alchemy 0.12.21 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/ai/client.d.ts.map +1 -1
- package/lib/ai/client.js +3 -5
- package/lib/ai/client.js.map +1 -1
- package/lib/alchemy.d.ts +2 -1
- package/lib/alchemy.d.ts.map +1 -1
- package/lib/alchemy.js +87 -92
- package/lib/alchemy.js.map +1 -1
- package/lib/apply.d.ts.map +1 -1
- package/lib/apply.js +6 -0
- package/lib/apply.js.map +1 -1
- package/lib/aws/bucket.d.ts.map +1 -1
- package/lib/aws/bucket.js +55 -57
- package/lib/aws/bucket.js.map +1 -1
- package/lib/aws/function.d.ts.map +1 -1
- package/lib/aws/function.js +250 -252
- package/lib/aws/function.js.map +1 -1
- package/lib/aws/policy-attachment.d.ts.map +1 -1
- package/lib/aws/policy-attachment.js +4 -6
- package/lib/aws/policy-attachment.js.map +1 -1
- package/lib/aws/policy.d.ts.map +1 -1
- package/lib/aws/policy.js +63 -65
- package/lib/aws/policy.js.map +1 -1
- package/lib/aws/queue.js +88 -90
- package/lib/aws/queue.js.map +1 -1
- package/lib/aws/table.d.ts.map +1 -1
- package/lib/aws/table.js +95 -99
- package/lib/aws/table.js.map +1 -1
- package/lib/cloudflare/account-api-token.d.ts +1 -1
- package/lib/cloudflare/account-api-token.d.ts.map +1 -1
- package/lib/cloudflare/account-api-token.js +0 -1
- package/lib/cloudflare/account-api-token.js.map +1 -1
- package/lib/cloudflare/ai-gateway.js.map +1 -1
- package/lib/cloudflare/ai.d.ts +1 -1
- package/lib/cloudflare/ai.d.ts.map +1 -1
- package/lib/cloudflare/ai.js.map +1 -1
- package/lib/cloudflare/api.js +1 -5
- package/lib/cloudflare/api.js.map +1 -1
- package/lib/cloudflare/bucket.d.ts +2 -2
- package/lib/cloudflare/bucket.d.ts.map +1 -1
- package/lib/cloudflare/bucket.js +22 -24
- package/lib/cloudflare/bucket.js.map +1 -1
- package/lib/cloudflare/bundle/hybrid-nodejs-compat.d.ts +0 -3
- package/lib/cloudflare/bundle/hybrid-nodejs-compat.d.ts.map +1 -1
- package/lib/cloudflare/bundle/hybrid-nodejs-compat.js +3 -4
- package/lib/cloudflare/bundle/hybrid-nodejs-compat.js.map +1 -1
- package/lib/cloudflare/custom-domain.d.ts.map +1 -1
- package/lib/cloudflare/custom-domain.js +3 -5
- package/lib/cloudflare/custom-domain.js.map +1 -1
- package/lib/cloudflare/d1-database.d.ts +1 -1
- package/lib/cloudflare/d1-database.d.ts.map +1 -1
- package/lib/cloudflare/d1-database.js +70 -72
- package/lib/cloudflare/d1-database.js.map +1 -1
- package/lib/cloudflare/d1-migrations.d.ts +1 -1
- package/lib/cloudflare/d1-migrations.d.ts.map +1 -1
- package/lib/cloudflare/d1-migrations.js +2 -3
- package/lib/cloudflare/d1-migrations.js.map +1 -1
- package/lib/cloudflare/dns-records.d.ts.map +1 -1
- package/lib/cloudflare/dns-records.js +2 -4
- package/lib/cloudflare/dns-records.js.map +1 -1
- package/lib/cloudflare/kv-namespace.d.ts +1 -1
- package/lib/cloudflare/kv-namespace.d.ts.map +1 -1
- package/lib/cloudflare/kv-namespace.js +24 -27
- package/lib/cloudflare/kv-namespace.js.map +1 -1
- package/lib/cloudflare/pipeline.d.ts +1 -1
- package/lib/cloudflare/pipeline.d.ts.map +1 -1
- package/lib/cloudflare/pipeline.js +32 -34
- package/lib/cloudflare/pipeline.js.map +1 -1
- package/lib/cloudflare/queue-consumer.d.ts +1 -1
- package/lib/cloudflare/queue-consumer.d.ts.map +1 -1
- package/lib/cloudflare/queue-consumer.js +31 -33
- package/lib/cloudflare/queue-consumer.js.map +1 -1
- package/lib/cloudflare/queue.d.ts +1 -1
- package/lib/cloudflare/queue.d.ts.map +1 -1
- package/lib/cloudflare/queue.js +36 -38
- package/lib/cloudflare/queue.js.map +1 -1
- package/lib/cloudflare/r2-rest-state-store.js +4 -8
- package/lib/cloudflare/r2-rest-state-store.js.map +1 -1
- package/lib/cloudflare/types.d.ts.map +1 -1
- package/lib/cloudflare/types.js +1 -3
- package/lib/cloudflare/types.js.map +1 -1
- package/lib/cloudflare/vectorize-index.d.ts.map +1 -1
- package/lib/cloudflare/vectorize-index.js +37 -39
- package/lib/cloudflare/vectorize-index.js.map +1 -1
- package/lib/cloudflare/vectorize-metadata-index.d.ts +1 -1
- package/lib/cloudflare/vectorize-metadata-index.d.ts.map +1 -1
- package/lib/cloudflare/vectorize-metadata-index.js +10 -13
- package/lib/cloudflare/vectorize-metadata-index.js.map +1 -1
- package/lib/cloudflare/worker.js +6 -12
- package/lib/cloudflare/worker.js.map +1 -1
- package/lib/cloudflare/workflow.d.ts +1 -1
- package/lib/cloudflare/workflow.d.ts.map +1 -1
- package/lib/cloudflare/workflow.js.map +1 -1
- package/lib/cloudflare/zone.d.ts.map +1 -1
- package/lib/cloudflare/zone.js +48 -50
- package/lib/cloudflare/zone.js.map +1 -1
- package/lib/dns/godaddy.js +1 -1
- package/lib/dns/import-dns.js +1 -1
- package/lib/dns/import-dns.js.map +1 -1
- package/lib/env.js +7 -9
- package/lib/env.js.map +1 -1
- package/lib/esbuild/bundle.js +8 -10
- package/lib/esbuild/bundle.js.map +1 -1
- package/lib/fs/copy-file.d.ts.map +1 -1
- package/lib/fs/copy-file.js +27 -29
- package/lib/fs/copy-file.js.map +1 -1
- package/lib/fs/file.d.ts +1 -1
- package/lib/fs/file.d.ts.map +1 -1
- package/lib/fs/file.js +1 -1
- package/lib/fs/file.js.map +1 -1
- package/lib/fs/folder.d.ts.map +1 -1
- package/lib/fs/folder.js +1 -3
- package/lib/fs/folder.js.map +1 -1
- package/lib/github/client.d.ts.map +1 -1
- package/lib/github/client.js +3 -5
- package/lib/github/client.js.map +1 -1
- package/lib/github/repository-environment.d.ts.map +1 -1
- package/lib/github/repository-environment.js +173 -176
- package/lib/github/repository-environment.js.map +1 -1
- package/lib/github/secret.d.ts.map +1 -1
- package/lib/github/secret.js +97 -99
- package/lib/github/secret.js.map +1 -1
- package/lib/internal/docs/providers.d.ts.map +1 -1
- package/lib/internal/docs/providers.js +5 -7
- package/lib/internal/docs/providers.js.map +1 -1
- package/lib/neon/api.js +1 -2
- package/lib/neon/api.js.map +1 -1
- package/lib/neon/project.js +2 -2
- package/lib/neon/project.js.map +1 -1
- package/lib/os/exec.d.ts +5 -0
- package/lib/os/exec.d.ts.map +1 -1
- package/lib/os/exec.js +88 -56
- package/lib/os/exec.js.map +1 -1
- package/lib/scope.d.ts +3 -0
- package/lib/scope.d.ts.map +1 -1
- package/lib/scope.js +10 -3
- package/lib/scope.js.map +1 -1
- package/lib/secret.d.ts.map +1 -1
- package/lib/secret.js +1 -3
- package/lib/secret.js.map +1 -1
- package/lib/serde.d.ts.map +1 -1
- package/lib/serde.js +13 -15
- package/lib/serde.js.map +1 -1
- package/lib/stripe/price.d.ts.map +1 -1
- package/lib/stripe/price.js +69 -73
- package/lib/stripe/price.js.map +1 -1
- package/lib/stripe/product.d.ts.map +1 -1
- package/lib/stripe/product.js +50 -52
- package/lib/stripe/product.js.map +1 -1
- package/lib/stripe/webhook.d.ts.map +1 -1
- package/lib/stripe/webhook.js +51 -53
- package/lib/stripe/webhook.js.map +1 -1
- package/lib/test/bun.d.ts +1 -1
- package/lib/test/bun.d.ts.map +1 -1
- package/lib/test/bun.js +1 -0
- package/lib/test/bun.js.map +1 -1
- package/lib/test/prune.d.ts.map +1 -1
- package/lib/test/prune.js.map +1 -1
- package/lib/util/dedent.js +4 -4
- package/lib/util/dedent.js.map +1 -1
- package/lib/web/astro.js +1 -1
- package/lib/web/shadcn.js +4 -4
- package/lib/web/shadcn.js.map +1 -1
- package/lib/web/tailwind.d.ts.map +1 -1
- package/lib/web/tailwind.js +0 -1
- package/lib/web/tailwind.js.map +1 -1
- package/lib/web/vite.js +3 -3
- package/lib/web/vitepress/home-page.d.ts.map +1 -1
- package/lib/web/vitepress/home-page.js +6 -8
- package/lib/web/vitepress/home-page.js.map +1 -1
- package/lib/web/vitepress/process-front-matter-files.js +1 -1
- package/lib/web/vitepress/process-front-matter-files.js.map +1 -1
- package/lib/web/vitepress/vitepress.js +2 -2
- package/lib/web/vitepress/vitepress.js.map +1 -1
- package/package.json +1 -1
- package/src/ai/astro-file.ts +4 -4
- package/src/ai/client.ts +4 -5
- package/src/ai/css-file.ts +4 -4
- package/src/ai/document.ts +3 -3
- package/src/ai/html-file.ts +4 -4
- package/src/ai/json-file.ts +1 -1
- package/src/ai/typescript-file.ts +4 -4
- package/src/ai/vue-file.ts +4 -4
- package/src/ai/yaml-file.ts +1 -1
- package/src/alchemy.ts +111 -104
- package/src/apply.ts +13 -5
- package/src/aws/bucket.ts +72 -75
- package/src/aws/function.ts +296 -297
- package/src/aws/oidc/github-oidc-provider.ts +1 -1
- package/src/aws/oidc/oidc-provider.ts +15 -15
- package/src/aws/policy-attachment.ts +10 -11
- package/src/aws/policy.ts +91 -94
- package/src/aws/queue.ts +111 -111
- package/src/aws/role.ts +24 -24
- package/src/aws/ses.ts +17 -17
- package/src/aws/table.ts +114 -115
- package/src/cloudflare/account-api-token.ts +11 -11
- package/src/cloudflare/account-id.ts +1 -1
- package/src/cloudflare/ai-gateway.ts +4 -4
- package/src/cloudflare/ai.ts +1 -1
- package/src/cloudflare/api-error.ts +1 -1
- package/src/cloudflare/api.ts +7 -11
- package/src/cloudflare/assets.ts +4 -4
- package/src/cloudflare/auth.ts +13 -13
- package/src/cloudflare/bucket.ts +62 -63
- package/src/cloudflare/bundle/hybrid-nodejs-compat.ts +13 -14
- package/src/cloudflare/custom-domain.ts +27 -28
- package/src/cloudflare/d1-database.ts +101 -102
- package/src/cloudflare/d1-migrations.ts +10 -10
- package/src/cloudflare/dns-records.ts +23 -24
- package/src/cloudflare/durable-object-namespace.ts +1 -1
- package/src/cloudflare/event-source.ts +1 -1
- package/src/cloudflare/hyperdrive.ts +3 -3
- package/src/cloudflare/kv-namespace.ts +36 -37
- package/src/cloudflare/nuxt.ts +1 -1
- package/src/cloudflare/permission-groups.ts +7 -7
- package/src/cloudflare/pipeline.ts +55 -56
- package/src/cloudflare/queue-consumer.ts +53 -54
- package/src/cloudflare/queue.ts +56 -57
- package/src/cloudflare/r2-rest-state-store.ts +11 -11
- package/src/cloudflare/redwood.ts +1 -1
- package/src/cloudflare/tanstack-start.ts +1 -1
- package/src/cloudflare/types.ts +1 -2
- package/src/cloudflare/vectorize-index.ts +60 -61
- package/src/cloudflare/vectorize-metadata-index.ts +25 -25
- package/src/cloudflare/vite.ts +1 -1
- package/src/cloudflare/website.ts +3 -3
- package/src/cloudflare/worker.ts +61 -61
- package/src/cloudflare/workflow.ts +4 -4
- package/src/cloudflare/wrangler.json.ts +4 -4
- package/src/cloudflare/zone.ts +69 -70
- package/src/destroy.ts +4 -4
- package/src/dns/godaddy.ts +1 -1
- package/src/dns/import-dns.ts +5 -5
- package/src/encrypt.ts +6 -6
- package/src/env.ts +10 -10
- package/src/esbuild/bundle.ts +14 -14
- package/src/fs/copy-file.ts +35 -36
- package/src/fs/file-system-state-store.ts +4 -4
- package/src/fs/file.ts +9 -8
- package/src/fs/folder.ts +6 -7
- package/src/github/client.ts +15 -14
- package/src/github/repository-environment.ts +206 -210
- package/src/github/secret.ts +111 -116
- package/src/internal/docs/providers.ts +16 -17
- package/src/neon/api-error.ts +1 -1
- package/src/neon/api.ts +6 -6
- package/src/neon/project.ts +18 -17
- package/src/os/exec.ts +107 -66
- package/src/resource.ts +3 -3
- package/src/scope.ts +14 -4
- package/src/secret.ts +2 -3
- package/src/serde.ts +30 -22
- package/src/stripe/price.ts +74 -77
- package/src/stripe/product.ts +55 -56
- package/src/stripe/webhook.ts +56 -57
- package/src/test/bun.ts +7 -6
- package/src/test/prune.ts +4 -4
- package/src/util/dedent.ts +4 -4
- package/src/web/astro.ts +10 -10
- package/src/web/shadcn-component.ts +4 -4
- package/src/web/shadcn.ts +10 -10
- package/src/web/tailwind.ts +2 -3
- package/src/web/vite.ts +11 -11
- package/src/web/vitepress/config.ts +2 -2
- package/src/web/vitepress/custom-theme.ts +7 -7
- package/src/web/vitepress/dependencies.ts +4 -4
- package/src/web/vitepress/home-page.ts +8 -9
- package/src/web/vitepress/process-front-matter-files.ts +5 -5
- package/src/web/vitepress/vitepress.ts +7 -7
|
@@ -154,7 +154,7 @@ export const AiGateway = Resource(
|
|
|
154
154
|
async function (
|
|
155
155
|
this: Context<AiGateway>,
|
|
156
156
|
id: string,
|
|
157
|
-
props: AiGatewayProps = {}
|
|
157
|
+
props: AiGatewayProps = {},
|
|
158
158
|
): Promise<AiGateway> {
|
|
159
159
|
const api = await createCloudflareApi(props);
|
|
160
160
|
const gatewayPath = `/accounts/${api.accountId}/ai-gateway/gateways/${id}`;
|
|
@@ -199,7 +199,7 @@ export const AiGateway = Resource(
|
|
|
199
199
|
if (getResponse.status === 200) {
|
|
200
200
|
// Gateway exists, treat as update (PUT)
|
|
201
201
|
console.log(
|
|
202
|
-
`AI Gateway '${id}' already exists. Updating existing resource
|
|
202
|
+
`AI Gateway '${id}' already exists. Updating existing resource.`,
|
|
203
203
|
);
|
|
204
204
|
const requestBody = mapPropsToApi(id, mergedProps, false);
|
|
205
205
|
response = await api.put(gatewayPath, requestBody);
|
|
@@ -248,14 +248,14 @@ export const AiGateway = Resource(
|
|
|
248
248
|
logpushPublicKey: apiResource.logpush_public_key,
|
|
249
249
|
type: "ai_gateway",
|
|
250
250
|
});
|
|
251
|
-
}
|
|
251
|
+
},
|
|
252
252
|
);
|
|
253
253
|
|
|
254
254
|
// Helper function to map props to the API request body format
|
|
255
255
|
function mapPropsToApi(
|
|
256
256
|
id: string,
|
|
257
257
|
props: AiGatewayProps,
|
|
258
|
-
includeIdInBody
|
|
258
|
+
includeIdInBody = false,
|
|
259
259
|
): Record<string, any> {
|
|
260
260
|
const body: Record<string, any> = {};
|
|
261
261
|
if (includeIdInBody) {
|
package/src/cloudflare/ai.ts
CHANGED
package/src/cloudflare/api.ts
CHANGED
|
@@ -48,7 +48,7 @@ export interface CloudflareApiOptions {
|
|
|
48
48
|
* @returns Promise resolving to a CloudflareApi instance
|
|
49
49
|
*/
|
|
50
50
|
export async function createCloudflareApi(
|
|
51
|
-
options: Partial<CloudflareApiOptions> = {}
|
|
51
|
+
options: Partial<CloudflareApiOptions> = {},
|
|
52
52
|
): Promise<CloudflareApi> {
|
|
53
53
|
const userInfo = await getCloudflareUserInfo(options);
|
|
54
54
|
return new CloudflareApi({
|
|
@@ -77,7 +77,7 @@ export class CloudflareApi {
|
|
|
77
77
|
constructor(
|
|
78
78
|
private readonly options: CloudflareApiOptions & {
|
|
79
79
|
accountId: string;
|
|
80
|
-
}
|
|
80
|
+
},
|
|
81
81
|
) {
|
|
82
82
|
this.accountId = options.accountId;
|
|
83
83
|
this.baseUrl = options.baseUrl ?? "https://api.cloudflare.com/client/v4";
|
|
@@ -130,7 +130,7 @@ export class CloudflareApi {
|
|
|
130
130
|
// transient errors should be retried aggressively
|
|
131
131
|
(error) => error instanceof InternalError,
|
|
132
132
|
5, // Maximum 5 attempts (1 initial + 4 retries)
|
|
133
|
-
1000 // Start with 1s delay, will exponentially increase
|
|
133
|
+
1000, // Start with 1s delay, will exponentially increase
|
|
134
134
|
);
|
|
135
135
|
}
|
|
136
136
|
|
|
@@ -153,7 +153,7 @@ export class CloudflareApi {
|
|
|
153
153
|
async post(
|
|
154
154
|
path: string,
|
|
155
155
|
body: any,
|
|
156
|
-
init: RequestInit = {}
|
|
156
|
+
init: RequestInit = {},
|
|
157
157
|
): Promise<Response> {
|
|
158
158
|
const requestBody =
|
|
159
159
|
body instanceof FormData
|
|
@@ -170,7 +170,7 @@ export class CloudflareApi {
|
|
|
170
170
|
async put(
|
|
171
171
|
path: string,
|
|
172
172
|
body: any,
|
|
173
|
-
init: RequestInit = {}
|
|
173
|
+
init: RequestInit = {},
|
|
174
174
|
): Promise<Response> {
|
|
175
175
|
const requestBody = body instanceof FormData ? body : JSON.stringify(body);
|
|
176
176
|
return this.fetch(path, { ...init, method: "PUT", body: requestBody });
|
|
@@ -182,7 +182,7 @@ export class CloudflareApi {
|
|
|
182
182
|
async patch(
|
|
183
183
|
path: string,
|
|
184
184
|
body: any,
|
|
185
|
-
init: RequestInit = {}
|
|
185
|
+
init: RequestInit = {},
|
|
186
186
|
): Promise<Response> {
|
|
187
187
|
return this.fetch(path, {
|
|
188
188
|
...init,
|
|
@@ -199,8 +199,4 @@ export class CloudflareApi {
|
|
|
199
199
|
}
|
|
200
200
|
}
|
|
201
201
|
|
|
202
|
-
class InternalError extends Error {
|
|
203
|
-
constructor(message: string) {
|
|
204
|
-
super(message);
|
|
205
|
-
}
|
|
206
|
-
}
|
|
202
|
+
class InternalError extends Error {}
|
package/src/cloudflare/assets.ts
CHANGED
|
@@ -92,7 +92,7 @@ export const Assets = Resource(
|
|
|
92
92
|
async function (
|
|
93
93
|
this: Context<Assets>,
|
|
94
94
|
id: string,
|
|
95
|
-
props: AssetsProps
|
|
95
|
+
props: AssetsProps,
|
|
96
96
|
): Promise<Assets> {
|
|
97
97
|
if (this.phase === "delete") {
|
|
98
98
|
return this.destroy();
|
|
@@ -106,7 +106,7 @@ export const Assets = Resource(
|
|
|
106
106
|
}
|
|
107
107
|
} catch (error) {
|
|
108
108
|
throw new Error(
|
|
109
|
-
`Assets directory ${props.path} does not exist or is not accessible
|
|
109
|
+
`Assets directory ${props.path} does not exist or is not accessible`,
|
|
110
110
|
);
|
|
111
111
|
}
|
|
112
112
|
|
|
@@ -137,7 +137,7 @@ export const Assets = Resource(
|
|
|
137
137
|
createdAt: this.output?.createdAt || now,
|
|
138
138
|
updatedAt: now,
|
|
139
139
|
});
|
|
140
|
-
}
|
|
140
|
+
},
|
|
141
141
|
);
|
|
142
142
|
|
|
143
143
|
// Helper functions for file operations
|
|
@@ -151,7 +151,7 @@ async function getFilesRecursively(dir: string): Promise<string[]> {
|
|
|
151
151
|
return getFilesRecursively(path);
|
|
152
152
|
}
|
|
153
153
|
return path;
|
|
154
|
-
})
|
|
154
|
+
}),
|
|
155
155
|
);
|
|
156
156
|
|
|
157
157
|
return allFiles.flat();
|
package/src/cloudflare/auth.ts
CHANGED
|
@@ -77,7 +77,7 @@ export interface CloudflareOrganization {
|
|
|
77
77
|
const userInfoCache: Record<string, CloudflareUserInfo> = {};
|
|
78
78
|
|
|
79
79
|
export async function getCloudflareUserInfo(
|
|
80
|
-
options: CloudflareAuthOptions
|
|
80
|
+
options: CloudflareAuthOptions,
|
|
81
81
|
): Promise<CloudflareUserInfo> {
|
|
82
82
|
const cacheKey = JSON.stringify({
|
|
83
83
|
apiKey: options.apiKey?.unencrypted,
|
|
@@ -94,7 +94,7 @@ export async function getCloudflareUserInfo(
|
|
|
94
94
|
if (!user.ok) {
|
|
95
95
|
if (user.status === 403) {
|
|
96
96
|
throw new Error(
|
|
97
|
-
"Cloudflare authentication required. Did you forget to login with `wrangler login` or set CLOUDFLARE_API_TOKEN, CLOUDFLARE_API_KEY, or CLOUDFLARE_EMAIL, or CLOUDFLARE_API_KEY?"
|
|
97
|
+
"Cloudflare authentication required. Did you forget to login with `wrangler login` or set CLOUDFLARE_API_TOKEN, CLOUDFLARE_API_KEY, or CLOUDFLARE_EMAIL, or CLOUDFLARE_API_KEY?",
|
|
98
98
|
);
|
|
99
99
|
}
|
|
100
100
|
await handleApiError(user, "getting", "user", "user");
|
|
@@ -103,7 +103,7 @@ export async function getCloudflareUserInfo(
|
|
|
103
103
|
"https://api.cloudflare.com/client/v4/accounts",
|
|
104
104
|
{
|
|
105
105
|
headers,
|
|
106
|
-
}
|
|
106
|
+
},
|
|
107
107
|
);
|
|
108
108
|
const userInfo: CloudflareUserInfo = {
|
|
109
109
|
...((await user.json()) as any).result,
|
|
@@ -114,7 +114,7 @@ export async function getCloudflareUserInfo(
|
|
|
114
114
|
}
|
|
115
115
|
|
|
116
116
|
export async function getCloudflareAuthHeaders(
|
|
117
|
-
options: CloudflareAuthOptions = {}
|
|
117
|
+
options: CloudflareAuthOptions = {},
|
|
118
118
|
): Promise<Record<string, string>> {
|
|
119
119
|
// Check for API Token (preferred method)
|
|
120
120
|
const apiToken =
|
|
@@ -145,7 +145,7 @@ export async function getCloudflareAuthHeaders(
|
|
|
145
145
|
}
|
|
146
146
|
|
|
147
147
|
throw new Error(
|
|
148
|
-
"Cloudflare authentication required. Did you forget to login with `wrangler login` or set CLOUDFLARE_API_TOKEN, CLOUDFLARE_API_KEY, or CLOUDFLARE_EMAIL, or CLOUDFLARE_API_KEY?"
|
|
148
|
+
"Cloudflare authentication required. Did you forget to login with `wrangler login` or set CLOUDFLARE_API_TOKEN, CLOUDFLARE_API_KEY, or CLOUDFLARE_EMAIL, or CLOUDFLARE_API_KEY?",
|
|
149
149
|
);
|
|
150
150
|
}
|
|
151
151
|
|
|
@@ -169,7 +169,7 @@ async function getUserEmailFromApiKey(apiKey: string): Promise<string> {
|
|
|
169
169
|
|
|
170
170
|
if (!response.ok) {
|
|
171
171
|
throw new Error(
|
|
172
|
-
`Failed to get user information: ${response.status} ${response.statusText}
|
|
172
|
+
`Failed to get user information: ${response.status} ${response.statusText}`,
|
|
173
173
|
);
|
|
174
174
|
}
|
|
175
175
|
|
|
@@ -192,13 +192,13 @@ async function getUserEmailFromApiKey(apiKey: string): Promise<string> {
|
|
|
192
192
|
} catch (error) {
|
|
193
193
|
console.error("Error retrieving email from Cloudflare API:", error);
|
|
194
194
|
throw new Error(
|
|
195
|
-
"Failed to automatically discover email for API Key authentication"
|
|
195
|
+
"Failed to automatically discover email for API Key authentication",
|
|
196
196
|
);
|
|
197
197
|
}
|
|
198
198
|
}
|
|
199
199
|
|
|
200
200
|
async function refreshAuthToken(
|
|
201
|
-
options: WranglerConfig
|
|
201
|
+
options: WranglerConfig,
|
|
202
202
|
): Promise<WranglerConfig> {
|
|
203
203
|
const response = await fetch("https://dash.cloudflare.com/oauth2/token", {
|
|
204
204
|
method: "POST",
|
|
@@ -214,7 +214,7 @@ async function refreshAuthToken(
|
|
|
214
214
|
|
|
215
215
|
if (!response.ok) {
|
|
216
216
|
throw new Error(
|
|
217
|
-
`Failed to refresh auth token: ${response.status} ${response.statusText}
|
|
217
|
+
`Failed to refresh auth token: ${response.status} ${response.statusText}`,
|
|
218
218
|
);
|
|
219
219
|
}
|
|
220
220
|
|
|
@@ -226,7 +226,7 @@ async function refreshAuthToken(
|
|
|
226
226
|
options.oauth_token = data.access_token;
|
|
227
227
|
options.refresh_token = data.refresh_token;
|
|
228
228
|
options.expiration_time = new Date(
|
|
229
|
-
Date.now() + data.expires_in * 1000
|
|
229
|
+
Date.now() + data.expires_in * 1000,
|
|
230
230
|
).toISOString();
|
|
231
231
|
options.scopes = data.scope?.split(" ") || [];
|
|
232
232
|
|
|
@@ -280,7 +280,7 @@ async function readWranglerConfig(): Promise<WranglerConfig> {
|
|
|
280
280
|
const configPath = await findWranglerConfig();
|
|
281
281
|
try {
|
|
282
282
|
const config = (authConfigCache[configPath] ??= await parseTOML(
|
|
283
|
-
await fs.readFile(configPath, "utf-8")
|
|
283
|
+
await fs.readFile(configPath, "utf-8"),
|
|
284
284
|
));
|
|
285
285
|
config.path = configPath;
|
|
286
286
|
|
|
@@ -307,7 +307,7 @@ async function findWranglerConfig(): Promise<string> {
|
|
|
307
307
|
const environment = process.env.WRANGLER_API_ENVIRONMENT ?? "production";
|
|
308
308
|
const filePath = path.join(
|
|
309
309
|
"config",
|
|
310
|
-
`${environment === "production" ? "default.toml" : `${environment}.toml`}
|
|
310
|
+
`${environment === "production" ? "default.toml" : `${environment}.toml`}`,
|
|
311
311
|
);
|
|
312
312
|
|
|
313
313
|
const xdgAppPaths = (await import("xdg-app-paths")).default;
|
|
@@ -318,7 +318,7 @@ async function findWranglerConfig(): Promise<string> {
|
|
|
318
318
|
// Check for the .wrangler directory in root if it is not there then use the XDG compliant path.
|
|
319
319
|
wranglerConfigPath = path.join(
|
|
320
320
|
(await isDirectory(legacyConfigDir)) ? legacyConfigDir : configDir,
|
|
321
|
-
filePath
|
|
321
|
+
filePath,
|
|
322
322
|
);
|
|
323
323
|
return wranglerConfigPath;
|
|
324
324
|
}
|
package/src/cloudflare/bucket.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { Context } from "../context.js";
|
|
|
3
3
|
import { Resource } from "../resource.js";
|
|
4
4
|
import type { Secret } from "../secret.js";
|
|
5
5
|
import { CloudflareApiError, handleApiError } from "./api-error.js";
|
|
6
|
-
import { CloudflareApi, createCloudflareApi } from "./api.js";
|
|
6
|
+
import { type CloudflareApi, createCloudflareApi } from "./api.js";
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Properties for creating or updating an R2 Bucket
|
|
@@ -162,7 +162,7 @@ export const R2Bucket = Resource(
|
|
|
162
162
|
async function (
|
|
163
163
|
this: Context<R2Bucket>,
|
|
164
164
|
id: string,
|
|
165
|
-
props: BucketProps = {}
|
|
165
|
+
props: BucketProps = {},
|
|
166
166
|
): Promise<R2Bucket> {
|
|
167
167
|
const api = await createCloudflareApi(props);
|
|
168
168
|
const bucketName = props.name || this.id;
|
|
@@ -184,38 +184,37 @@ export const R2Bucket = Resource(
|
|
|
184
184
|
|
|
185
185
|
// Return void (a deleted bucket has no content)
|
|
186
186
|
return this.destroy();
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
throw err;
|
|
195
|
-
}
|
|
196
|
-
} else {
|
|
187
|
+
}
|
|
188
|
+
if (this.phase === "create") {
|
|
189
|
+
try {
|
|
190
|
+
await createBucket(api, bucketName, props);
|
|
191
|
+
} catch (err) {
|
|
192
|
+
if (err instanceof CloudflareApiError && err.status === 409) {
|
|
193
|
+
if (!props.adopt) {
|
|
197
194
|
throw err;
|
|
198
195
|
}
|
|
196
|
+
} else {
|
|
197
|
+
throw err;
|
|
199
198
|
}
|
|
200
199
|
}
|
|
200
|
+
}
|
|
201
201
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
202
|
+
await updatePublicAccess(
|
|
203
|
+
api,
|
|
204
|
+
bucketName,
|
|
205
|
+
props.allowPublicAccess === true,
|
|
206
|
+
props.jurisdiction,
|
|
207
|
+
);
|
|
208
208
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
}
|
|
209
|
+
return this({
|
|
210
|
+
name: bucketName,
|
|
211
|
+
location: props.locationHint || "default",
|
|
212
|
+
creationDate: new Date(),
|
|
213
|
+
jurisdiction: props.jurisdiction || "default",
|
|
214
|
+
type: "r2_bucket",
|
|
215
|
+
accountId: api.accountId,
|
|
216
|
+
});
|
|
217
|
+
},
|
|
219
218
|
);
|
|
220
219
|
|
|
221
220
|
/**
|
|
@@ -248,7 +247,7 @@ export function createR2Client(config?: R2ClientConfig): Promise<R2Client> {
|
|
|
248
247
|
|
|
249
248
|
if (!accessKeyId || !secretAccessKey) {
|
|
250
249
|
throw new Error(
|
|
251
|
-
"R2_ACCESS_KEY_ID and R2_SECRET_ACCESS_KEY environment variables are required"
|
|
250
|
+
"R2_ACCESS_KEY_ID and R2_SECRET_ACCESS_KEY environment variables are required",
|
|
252
251
|
);
|
|
253
252
|
}
|
|
254
253
|
|
|
@@ -287,8 +286,8 @@ interface CloudflareBucketResponse {
|
|
|
287
286
|
* @returns Modified headers object
|
|
288
287
|
*/
|
|
289
288
|
export function withJurisdiction(
|
|
290
|
-
headers: Record<string, string
|
|
291
|
-
props: BucketProps | { jurisdiction?: string } | string | undefined
|
|
289
|
+
headers: Record<string, string>,
|
|
290
|
+
props: BucketProps | { jurisdiction?: string } | string | undefined,
|
|
292
291
|
): Record<string, string> {
|
|
293
292
|
// Clone the headers object to avoid modifying the original
|
|
294
293
|
const result = { ...headers };
|
|
@@ -313,12 +312,12 @@ export function withJurisdiction(
|
|
|
313
312
|
export async function getBucket(
|
|
314
313
|
api: CloudflareApi,
|
|
315
314
|
bucketName: string,
|
|
316
|
-
props: BucketProps = {}
|
|
315
|
+
props: BucketProps = {},
|
|
317
316
|
): Promise<CloudflareBucketResponse> {
|
|
318
317
|
const headers = withJurisdiction({}, props);
|
|
319
318
|
const getResponse = await api.get(
|
|
320
319
|
`/accounts/${api.accountId}/r2/buckets/${bucketName}`,
|
|
321
|
-
{ headers }
|
|
320
|
+
{ headers },
|
|
322
321
|
);
|
|
323
322
|
|
|
324
323
|
if (!getResponse.ok) {
|
|
@@ -335,7 +334,7 @@ export async function getBucket(
|
|
|
335
334
|
|
|
336
335
|
throw new CloudflareApiError(
|
|
337
336
|
`Error getting R2 bucket '${bucketName}': ${errorData.errors?.[0]?.message || getResponse.statusText}`,
|
|
338
|
-
getResponse
|
|
337
|
+
getResponse,
|
|
339
338
|
);
|
|
340
339
|
}
|
|
341
340
|
|
|
@@ -345,7 +344,7 @@ export async function getBucket(
|
|
|
345
344
|
export async function createBucket(
|
|
346
345
|
api: CloudflareApi,
|
|
347
346
|
bucketName: string,
|
|
348
|
-
props: BucketProps = {}
|
|
347
|
+
props: BucketProps = {},
|
|
349
348
|
): Promise<CloudflareBucketResponse> {
|
|
350
349
|
// Create new R2 bucket
|
|
351
350
|
const createPayload: any = {
|
|
@@ -361,7 +360,7 @@ export async function createBucket(
|
|
|
361
360
|
const createResponse = await api.post(
|
|
362
361
|
`/accounts/${api.accountId}/r2/buckets`,
|
|
363
362
|
createPayload,
|
|
364
|
-
{ headers }
|
|
363
|
+
{ headers },
|
|
365
364
|
);
|
|
366
365
|
|
|
367
366
|
if (!createResponse.ok) {
|
|
@@ -369,7 +368,7 @@ export async function createBucket(
|
|
|
369
368
|
createResponse,
|
|
370
369
|
"creating",
|
|
371
370
|
"R2 bucket",
|
|
372
|
-
bucketName
|
|
371
|
+
bucketName,
|
|
373
372
|
);
|
|
374
373
|
}
|
|
375
374
|
|
|
@@ -382,14 +381,14 @@ export async function createBucket(
|
|
|
382
381
|
export async function deleteBucket(
|
|
383
382
|
api: CloudflareApi,
|
|
384
383
|
bucketName: string,
|
|
385
|
-
props: BucketProps
|
|
384
|
+
props: BucketProps,
|
|
386
385
|
): Promise<void> {
|
|
387
386
|
// Delete R2 bucket
|
|
388
387
|
const headers = withJurisdiction({}, props);
|
|
389
388
|
|
|
390
389
|
const deleteResponse = await api.delete(
|
|
391
390
|
`/accounts/${api.accountId}/r2/buckets/${bucketName}`,
|
|
392
|
-
{ headers }
|
|
391
|
+
{ headers },
|
|
393
392
|
);
|
|
394
393
|
|
|
395
394
|
if (!deleteResponse.ok && deleteResponse.status !== 404) {
|
|
@@ -398,7 +397,7 @@ export async function deleteBucket(
|
|
|
398
397
|
}));
|
|
399
398
|
throw new CloudflareApiError(
|
|
400
399
|
`Error deleting R2 bucket '${bucketName}': ${errorData.errors?.[0]?.message || deleteResponse.statusText}`,
|
|
401
|
-
deleteResponse
|
|
400
|
+
deleteResponse,
|
|
402
401
|
);
|
|
403
402
|
}
|
|
404
403
|
}
|
|
@@ -416,11 +415,11 @@ export async function listObjects(
|
|
|
416
415
|
r2: R2Client,
|
|
417
416
|
bucketName: string,
|
|
418
417
|
continuationToken?: string,
|
|
419
|
-
jurisdiction?: string
|
|
418
|
+
jurisdiction?: string,
|
|
420
419
|
): Promise<{ objects: { Key: string }[]; continuationToken?: string }> {
|
|
421
420
|
// List objects in the bucket
|
|
422
421
|
const url = new URL(
|
|
423
|
-
`https://${r2.accountId}.r2.cloudflarestorage.com/${bucketName}
|
|
422
|
+
`https://${r2.accountId}.r2.cloudflarestorage.com/${bucketName}`,
|
|
424
423
|
);
|
|
425
424
|
if (continuationToken) {
|
|
426
425
|
url.searchParams.set("continuation-token", continuationToken);
|
|
@@ -433,7 +432,7 @@ export async function listObjects(
|
|
|
433
432
|
if (!listResponse.ok) {
|
|
434
433
|
throw new CloudflareApiError(
|
|
435
434
|
`Failed to list objects: ${listResponse.statusText}`,
|
|
436
|
-
listResponse
|
|
435
|
+
listResponse,
|
|
437
436
|
);
|
|
438
437
|
}
|
|
439
438
|
|
|
@@ -450,7 +449,7 @@ export async function listObjects(
|
|
|
450
449
|
// Get continuation token if present using regex
|
|
451
450
|
const tokenMatch =
|
|
452
451
|
/<NextContinuationToken>([^<]+)<\/NextContinuationToken>/.exec(
|
|
453
|
-
responseText
|
|
452
|
+
responseText,
|
|
454
453
|
);
|
|
455
454
|
const nextContinuationToken = tokenMatch ? tokenMatch[1] : undefined;
|
|
456
455
|
|
|
@@ -463,7 +462,7 @@ export async function listObjects(
|
|
|
463
462
|
export async function emptyBucket(
|
|
464
463
|
r2: R2Client,
|
|
465
464
|
bucketName: string,
|
|
466
|
-
jurisdiction?: string
|
|
465
|
+
jurisdiction?: string,
|
|
467
466
|
): Promise<void> {
|
|
468
467
|
let continuationToken: string | undefined;
|
|
469
468
|
let totalDeleted = 0;
|
|
@@ -476,7 +475,7 @@ export async function emptyBucket(
|
|
|
476
475
|
r2,
|
|
477
476
|
bucketName,
|
|
478
477
|
continuationToken,
|
|
479
|
-
jurisdiction
|
|
478
|
+
jurisdiction,
|
|
480
479
|
);
|
|
481
480
|
|
|
482
481
|
continuationToken = nextToken;
|
|
@@ -497,16 +496,16 @@ export async function emptyBucket(
|
|
|
497
496
|
`;
|
|
498
497
|
|
|
499
498
|
const deleteUrl = new URL(
|
|
500
|
-
`https://${r2.accountId}.r2.cloudflarestorage.com/${bucketName}?delete
|
|
499
|
+
`https://${r2.accountId}.r2.cloudflarestorage.com/${bucketName}?delete`,
|
|
501
500
|
);
|
|
502
501
|
|
|
503
502
|
console.log(
|
|
504
|
-
`Deleting ${batch.length} objects from bucket ${bucketName}
|
|
503
|
+
`Deleting ${batch.length} objects from bucket ${bucketName}`,
|
|
505
504
|
);
|
|
506
505
|
|
|
507
506
|
const headers = withJurisdiction(
|
|
508
507
|
{ "Content-Type": "application/xml" },
|
|
509
|
-
jurisdiction
|
|
508
|
+
jurisdiction,
|
|
510
509
|
);
|
|
511
510
|
|
|
512
511
|
const deleteResponse = await r2.fetch(deleteUrl.toString(), {
|
|
@@ -518,7 +517,7 @@ export async function emptyBucket(
|
|
|
518
517
|
if (!deleteResponse.ok) {
|
|
519
518
|
throw new CloudflareApiError(
|
|
520
519
|
`Failed to delete objects: ${deleteResponse.statusText}`,
|
|
521
|
-
deleteResponse
|
|
520
|
+
deleteResponse,
|
|
522
521
|
);
|
|
523
522
|
}
|
|
524
523
|
|
|
@@ -528,7 +527,7 @@ export async function emptyBucket(
|
|
|
528
527
|
} while (continuationToken);
|
|
529
528
|
|
|
530
529
|
console.log(
|
|
531
|
-
`Successfully emptied bucket ${bucketName}, deleted ${totalDeleted} objects total
|
|
530
|
+
`Successfully emptied bucket ${bucketName}, deleted ${totalDeleted} objects total`,
|
|
532
531
|
);
|
|
533
532
|
} catch (error) {
|
|
534
533
|
if (error instanceof CloudflareApiError && error.status === 404) {
|
|
@@ -550,7 +549,7 @@ export async function updatePublicAccess(
|
|
|
550
549
|
api: CloudflareApi,
|
|
551
550
|
bucketName: string,
|
|
552
551
|
allowPublicAccess: boolean,
|
|
553
|
-
jurisdiction?: string
|
|
552
|
+
jurisdiction?: string,
|
|
554
553
|
): Promise<void> {
|
|
555
554
|
const headers = withJurisdiction({}, jurisdiction);
|
|
556
555
|
|
|
@@ -559,7 +558,7 @@ export async function updatePublicAccess(
|
|
|
559
558
|
{
|
|
560
559
|
enabled: allowPublicAccess,
|
|
561
560
|
},
|
|
562
|
-
{ headers }
|
|
561
|
+
{ headers },
|
|
563
562
|
);
|
|
564
563
|
|
|
565
564
|
if (!response.ok) {
|
|
@@ -567,7 +566,7 @@ export async function updatePublicAccess(
|
|
|
567
566
|
response,
|
|
568
567
|
"updating public access for",
|
|
569
568
|
"R2 bucket",
|
|
570
|
-
bucketName
|
|
569
|
+
bucketName,
|
|
571
570
|
);
|
|
572
571
|
}
|
|
573
572
|
}
|
|
@@ -581,8 +580,8 @@ export async function setCorsConfiguration(
|
|
|
581
580
|
allowedOrigins: string[] = ["*"],
|
|
582
581
|
allowedMethods: string[] = ["GET", "HEAD", "PUT", "POST", "DELETE"],
|
|
583
582
|
allowedHeaders: string[] = ["*"],
|
|
584
|
-
maxAgeSeconds
|
|
585
|
-
jurisdiction?: string
|
|
583
|
+
maxAgeSeconds = 3600,
|
|
584
|
+
jurisdiction?: string,
|
|
586
585
|
): Promise<void> {
|
|
587
586
|
try {
|
|
588
587
|
// Construct CORS XML configuration
|
|
@@ -599,12 +598,12 @@ export async function setCorsConfiguration(
|
|
|
599
598
|
`;
|
|
600
599
|
|
|
601
600
|
const url = new URL(
|
|
602
|
-
`https://${r2.accountId}.r2.cloudflarestorage.com/${bucketName}?cors
|
|
601
|
+
`https://${r2.accountId}.r2.cloudflarestorage.com/${bucketName}?cors`,
|
|
603
602
|
);
|
|
604
603
|
|
|
605
604
|
const headers = withJurisdiction(
|
|
606
605
|
{ "Content-Type": "application/xml" },
|
|
607
|
-
jurisdiction
|
|
606
|
+
jurisdiction,
|
|
608
607
|
);
|
|
609
608
|
|
|
610
609
|
const response = await r2.fetch(url.toString(), {
|
|
@@ -616,7 +615,7 @@ export async function setCorsConfiguration(
|
|
|
616
615
|
if (!response.ok) {
|
|
617
616
|
throw new CloudflareApiError(
|
|
618
617
|
`Failed to set CORS configuration: ${response.statusText}`,
|
|
619
|
-
response
|
|
618
|
+
response,
|
|
620
619
|
);
|
|
621
620
|
}
|
|
622
621
|
|
|
@@ -624,7 +623,7 @@ export async function setCorsConfiguration(
|
|
|
624
623
|
} catch (error) {
|
|
625
624
|
console.error(
|
|
626
625
|
`Failed to set CORS configuration for bucket ${bucketName}:`,
|
|
627
|
-
error
|
|
626
|
+
error,
|
|
628
627
|
);
|
|
629
628
|
throw error;
|
|
630
629
|
}
|
|
@@ -660,7 +659,7 @@ export async function listBuckets(
|
|
|
660
659
|
cursor?: string;
|
|
661
660
|
direction?: "asc" | "desc";
|
|
662
661
|
jurisdiction?: string;
|
|
663
|
-
} = {}
|
|
662
|
+
} = {},
|
|
664
663
|
): Promise<R2BucketInfo[]> {
|
|
665
664
|
// Build query parameters
|
|
666
665
|
const params = new URLSearchParams();
|
|
@@ -682,7 +681,7 @@ export async function listBuckets(
|
|
|
682
681
|
}
|
|
683
682
|
|
|
684
683
|
// Build URL with query parameters
|
|
685
|
-
const path = `/accounts/${api.accountId}/r2/buckets${params.toString() ?
|
|
684
|
+
const path = `/accounts/${api.accountId}/r2/buckets${params.toString() ? `?${params.toString()}` : ""}`;
|
|
686
685
|
|
|
687
686
|
// Set jurisdiction header if provided
|
|
688
687
|
const headers = withJurisdiction({}, options.jurisdiction);
|
|
@@ -693,7 +692,7 @@ export async function listBuckets(
|
|
|
693
692
|
if (!response.ok) {
|
|
694
693
|
throw new CloudflareApiError(
|
|
695
694
|
`Failed to list buckets: ${response.statusText}`,
|
|
696
|
-
response
|
|
695
|
+
response,
|
|
697
696
|
);
|
|
698
697
|
}
|
|
699
698
|
|