mirror of
https://github.com/sst/opencode.git
synced 2025-12-23 10:11:41 +00:00
core(enterprise): use aws4fetch for smaller bundle size on edge runtimes
This commit is contained in:
parent
673dbeee09
commit
4000705701
3 changed files with 40 additions and 57 deletions
1
bun.lock
1
bun.lock
|
|
@ -171,6 +171,7 @@
|
|||
"@solidjs/meta": "catalog:",
|
||||
"@solidjs/router": "catalog:",
|
||||
"@solidjs/start": "catalog:",
|
||||
"aws4fetch": "^1.0.20",
|
||||
"hono": "catalog:",
|
||||
"hono-openapi": "catalog:",
|
||||
"luxon": "catalog:",
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
"dependencies": {
|
||||
"@opencode-ai/util": "workspace:*",
|
||||
"@opencode-ai/ui": "workspace:*",
|
||||
"aws4fetch": "^1.0.20",
|
||||
"@pierre/precision-diffs": "catalog:",
|
||||
"@solidjs/router": "catalog:",
|
||||
"@solidjs/start": "catalog:",
|
||||
|
|
|
|||
|
|
@ -1,10 +1,4 @@
|
|||
import {
|
||||
S3Client,
|
||||
PutObjectCommand,
|
||||
GetObjectCommand,
|
||||
DeleteObjectCommand,
|
||||
ListObjectsV2Command,
|
||||
} from "@aws-sdk/client-s3"
|
||||
import { AwsClient } from "aws4fetch"
|
||||
import { lazy } from "@opencode-ai/util/lazy"
|
||||
|
||||
export namespace Storage {
|
||||
|
|
@ -15,81 +9,68 @@ export namespace Storage {
|
|||
list(prefix: string): Promise<string[]>
|
||||
}
|
||||
|
||||
function createAdapter(client: S3Client, bucket: string): Adapter {
|
||||
function createAdapter(client: AwsClient, endpoint: string, bucket: string): Adapter {
|
||||
const base = `${endpoint}/${bucket}`
|
||||
return {
|
||||
async read(path: string): Promise<string | undefined> {
|
||||
try {
|
||||
const command = new GetObjectCommand({
|
||||
Bucket: bucket,
|
||||
Key: path,
|
||||
})
|
||||
const response = await client.send(command)
|
||||
if (!response.Body) return undefined
|
||||
return response.Body.transformToString()
|
||||
} catch (e: any) {
|
||||
if (e.name === "NoSuchKey") return undefined
|
||||
throw e
|
||||
}
|
||||
const response = await client.fetch(`${base}/${path}`)
|
||||
if (response.status === 404) return undefined
|
||||
if (!response.ok) throw new Error(`Failed to read ${path}: ${response.status}`)
|
||||
return response.text()
|
||||
},
|
||||
|
||||
async write(path: string, value: string): Promise<void> {
|
||||
const command = new PutObjectCommand({
|
||||
Bucket: bucket,
|
||||
Key: path,
|
||||
Body: value,
|
||||
ContentType: "application/json",
|
||||
const response = await client.fetch(`${base}/${path}`, {
|
||||
method: "PUT",
|
||||
body: value,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
})
|
||||
await client.send(command)
|
||||
if (!response.ok) throw new Error(`Failed to write ${path}: ${response.status}`)
|
||||
},
|
||||
|
||||
async remove(path: string): Promise<void> {
|
||||
const command = new DeleteObjectCommand({
|
||||
Bucket: bucket,
|
||||
Key: path,
|
||||
const response = await client.fetch(`${base}/${path}`, {
|
||||
method: "DELETE",
|
||||
})
|
||||
await client.send(command)
|
||||
if (!response.ok) throw new Error(`Failed to remove ${path}: ${response.status}`)
|
||||
},
|
||||
|
||||
async list(prefix: string): Promise<string[]> {
|
||||
const command = new ListObjectsV2Command({
|
||||
Bucket: bucket,
|
||||
Prefix: prefix,
|
||||
})
|
||||
const response = await client.send(command)
|
||||
return response.Contents?.map((c) => c.Key!) || []
|
||||
const params = new URLSearchParams({ "list-type": "2", prefix })
|
||||
const response = await client.fetch(`${base}?${params}`)
|
||||
if (!response.ok) throw new Error(`Failed to list ${prefix}: ${response.status}`)
|
||||
const xml = await response.text()
|
||||
const keys: string[] = []
|
||||
const regex = /<Key>([^<]+)<\/Key>/g
|
||||
let match
|
||||
while ((match = regex.exec(xml)) !== null) {
|
||||
keys.push(match[1])
|
||||
}
|
||||
return keys
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
function s3(): Adapter {
|
||||
const bucket = process.env.OPENCODE_STORAGE_BUCKET!
|
||||
const client = new S3Client({
|
||||
region: process.env.OPENCODE_STORAGE_REGION,
|
||||
credentials: process.env.OPENCODE_STORAGE_ACCESS_KEY_ID
|
||||
? {
|
||||
accessKeyId: process.env.OPENCODE_STORAGE_ACCESS_KEY_ID!,
|
||||
secretAccessKey: process.env.OPENCODE_STORAGE_SECRET_ACCESS_KEY!,
|
||||
}
|
||||
: undefined,
|
||||
const region = process.env.OPENCODE_STORAGE_REGION || "us-east-1"
|
||||
const client = new AwsClient({
|
||||
region,
|
||||
accessKeyId: process.env.OPENCODE_STORAGE_ACCESS_KEY_ID!,
|
||||
secretAccessKey: process.env.OPENCODE_STORAGE_SECRET_ACCESS_KEY!,
|
||||
})
|
||||
return createAdapter(client, bucket)
|
||||
return createAdapter(client, `https://s3.${region}.amazonaws.com`, bucket)
|
||||
}
|
||||
|
||||
function r2() {
|
||||
const accountId = process.env.OPENCODE_STORAGE_ACCOUNT_ID!
|
||||
const accessKeyId = process.env.OPENCODE_STORAGE_ACCESS_KEY_ID!
|
||||
const secretAccessKey = process.env.OPENCODE_STORAGE_SECRET_ACCESS_KEY!
|
||||
const bucket = process.env.OPENCODE_STORAGE_BUCKET!
|
||||
|
||||
const client = new S3Client({
|
||||
region: "auto",
|
||||
endpoint: `https://${accountId}.r2.cloudflarestorage.com`,
|
||||
credentials: {
|
||||
accessKeyId,
|
||||
secretAccessKey,
|
||||
},
|
||||
const client = new AwsClient({
|
||||
accessKeyId: process.env.OPENCODE_STORAGE_ACCESS_KEY_ID!,
|
||||
secretAccessKey: process.env.OPENCODE_STORAGE_SECRET_ACCESS_KEY!,
|
||||
})
|
||||
return createAdapter(client, bucket)
|
||||
return createAdapter(client, `https://${accountId}.r2.cloudflarestorage.com`, process.env.OPENCODE_STORAGE_BUCKET!)
|
||||
}
|
||||
|
||||
const adapter = lazy(() => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue