alchemy 0.1.16 → 0.1.17
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/$.d.ts +12 -0
- package/lib/$.d.ts.map +1 -0
- package/lib/$.js +42 -0
- package/lib/$.js.map +1 -0
- package/lib/alchemize.d.ts +43 -0
- package/lib/alchemize.d.ts.map +1 -0
- package/lib/alchemize.js +112 -0
- package/lib/alchemize.js.map +1 -0
- package/lib/apply.d.ts +23 -0
- package/lib/aws/account-id.d.ts +5 -0
- package/lib/aws/account-id.d.ts.map +1 -0
- package/lib/aws/account-id.js +10 -0
- package/lib/aws/account-id.js.map +1 -0
- package/lib/aws/bucket.d.ts +21 -0
- package/lib/aws/bucket.d.ts.map +1 -0
- package/lib/aws/bucket.js +114 -0
- package/lib/aws/bucket.js.map +1 -0
- package/lib/aws/function.d.ts +53 -0
- package/lib/aws/function.d.ts.map +1 -0
- package/lib/aws/function.js +195 -0
- package/lib/aws/function.js.map +1 -0
- package/lib/aws/index.d.ts +9 -0
- package/lib/aws/index.d.ts.map +1 -0
- package/lib/aws/index.js +9 -0
- package/lib/aws/index.js.map +1 -0
- package/lib/aws/oidc/github-oidc-provider.d.ts +11 -0
- package/lib/aws/oidc/github-oidc-provider.d.ts.map +1 -0
- package/lib/aws/oidc/github-oidc-provider.js +22 -0
- package/lib/aws/oidc/github-oidc-provider.js.map +1 -0
- package/lib/aws/oidc/index.d.ts +3 -0
- package/lib/aws/oidc/index.d.ts.map +1 -0
- package/lib/aws/oidc/index.js +3 -0
- package/lib/aws/oidc/index.js.map +1 -0
- package/lib/aws/oidc/oidc-provider.d.ts +60 -0
- package/lib/aws/oidc/oidc-provider.d.ts.map +1 -0
- package/lib/aws/oidc/oidc-provider.js +140 -0
- package/lib/aws/oidc/oidc-provider.js.map +1 -0
- package/lib/aws/policy.d.ts +46 -0
- package/lib/aws/policy.d.ts.map +1 -0
- package/lib/aws/policy.js +139 -0
- package/lib/aws/policy.js.map +1 -0
- package/lib/aws/queue.d.ts +62 -0
- package/lib/aws/queue.d.ts.map +1 -0
- package/lib/aws/queue.js +167 -0
- package/lib/aws/queue.js.map +1 -0
- package/lib/aws/role.d.ts +27 -0
- package/lib/aws/role.d.ts.map +1 -0
- package/lib/aws/role.js +197 -0
- package/lib/aws/role.js.map +1 -0
- package/lib/aws/ses.d.ts +75 -0
- package/lib/aws/ses.d.ts.map +1 -0
- package/lib/aws/ses.js +189 -0
- package/lib/aws/ses.js.map +1 -0
- package/lib/aws/table.d.ts +26 -0
- package/lib/aws/table.d.ts.map +1 -0
- package/lib/aws/table.js +154 -0
- package/lib/aws/table.js.map +1 -0
- package/lib/cloudflare/api.d.ts +88 -0
- package/lib/cloudflare/api.d.ts.map +1 -0
- package/lib/cloudflare/api.js +184 -0
- package/lib/cloudflare/api.js.map +1 -0
- package/lib/cloudflare/asset-manifest.d.ts +15 -0
- package/lib/cloudflare/asset-manifest.d.ts.map +1 -0
- package/lib/cloudflare/asset-manifest.js +2 -0
- package/lib/cloudflare/asset-manifest.js.map +1 -0
- package/lib/cloudflare/auth.d.ts +52 -0
- package/lib/cloudflare/auth.d.ts.map +1 -0
- package/lib/cloudflare/auth.js +114 -0
- package/lib/cloudflare/auth.js.map +1 -0
- package/lib/cloudflare/bindings.d.ts +260 -0
- package/lib/cloudflare/bindings.d.ts.map +1 -0
- package/lib/cloudflare/bindings.js +2 -0
- package/lib/cloudflare/bindings.js.map +1 -0
- package/lib/cloudflare/bucket.d.ts +54 -0
- package/lib/cloudflare/bucket.d.ts.map +1 -0
- package/lib/cloudflare/bucket.js +120 -0
- package/lib/cloudflare/bucket.js.map +1 -0
- package/lib/cloudflare/durable-object-namespace.d.ts +20 -0
- package/lib/cloudflare/durable-object-namespace.d.ts.map +1 -0
- package/lib/cloudflare/durable-object-namespace.js +21 -0
- package/lib/cloudflare/durable-object-namespace.js.map +1 -0
- package/lib/cloudflare/generate-asset-manifest.d.ts +3 -0
- package/lib/cloudflare/generate-asset-manifest.d.ts.map +1 -0
- package/lib/cloudflare/generate-asset-manifest.js +69 -0
- package/lib/cloudflare/generate-asset-manifest.js.map +1 -0
- package/lib/cloudflare/index.d.ts +8 -0
- package/lib/cloudflare/index.d.ts.map +1 -0
- package/lib/cloudflare/index.js +8 -0
- package/lib/cloudflare/index.js.map +1 -0
- package/lib/cloudflare/kv-namespace.d.ts +64 -0
- package/lib/cloudflare/kv-namespace.d.ts.map +1 -0
- package/lib/cloudflare/kv-namespace.js +114 -0
- package/lib/cloudflare/kv-namespace.js.map +1 -0
- package/lib/cloudflare/state.d.ts +83 -0
- package/lib/cloudflare/state.d.ts.map +1 -0
- package/lib/cloudflare/state.js +109 -0
- package/lib/cloudflare/state.js.map +1 -0
- package/lib/cloudflare/static-site-router.d.ts +19 -0
- package/lib/cloudflare/static-site-router.d.ts.map +1 -0
- package/lib/cloudflare/static-site-router.js +110 -0
- package/lib/cloudflare/static-site-router.js.map +1 -0
- package/lib/cloudflare/static-site.d.ts +166 -0
- package/lib/cloudflare/static-site.d.ts.map +1 -0
- package/lib/cloudflare/static-site.js +161 -0
- package/lib/cloudflare/static-site.js.map +1 -0
- package/lib/cloudflare/types.d.ts +52 -0
- package/lib/cloudflare/types.d.ts.map +1 -0
- package/lib/cloudflare/types.js +21 -0
- package/lib/cloudflare/types.js.map +1 -0
- package/lib/cloudflare/upload-asset-manifest.d.ts +12 -0
- package/lib/cloudflare/upload-asset-manifest.d.ts.map +1 -0
- package/lib/cloudflare/upload-asset-manifest.js +55 -0
- package/lib/cloudflare/upload-asset-manifest.js.map +1 -0
- package/lib/cloudflare/worker-metadata.d.ts +130 -0
- package/lib/cloudflare/worker-metadata.d.ts.map +1 -0
- package/lib/cloudflare/worker-metadata.js +2 -0
- package/lib/cloudflare/worker-metadata.js.map +1 -0
- package/lib/cloudflare/worker-migration.d.ts +110 -0
- package/lib/cloudflare/worker-migration.d.ts.map +1 -0
- package/lib/cloudflare/worker-migration.js +11 -0
- package/lib/cloudflare/worker-migration.js.map +1 -0
- package/lib/cloudflare/worker.d.ts +108 -0
- package/lib/cloudflare/worker.d.ts.map +1 -0
- package/lib/cloudflare/worker.js +407 -0
- package/lib/cloudflare/worker.js.map +1 -0
- package/lib/destroy.d.ts +19 -0
- package/lib/error.d.ts +2 -0
- package/lib/error.d.ts.map +1 -0
- package/lib/error.js +13 -0
- package/lib/error.js.map +1 -0
- package/lib/esbuild.d.ts +152 -0
- package/lib/esbuild.d.ts.map +1 -0
- package/lib/esbuild.js +67 -0
- package/lib/esbuild.js.map +1 -0
- package/lib/fs.d.ts +12 -0
- package/lib/fs.d.ts.map +1 -0
- package/lib/fs.js +41 -0
- package/lib/fs.js.map +1 -0
- package/lib/github/client.d.ts +34 -0
- package/lib/github/client.d.ts.map +1 -0
- package/lib/github/client.js +91 -0
- package/lib/github/client.js.map +1 -0
- package/lib/github/index.d.ts +2 -0
- package/lib/github/index.d.ts.map +1 -0
- package/lib/github/index.js +2 -0
- package/lib/github/index.js.map +1 -0
- package/lib/github/secret.d.ts +46 -0
- package/lib/github/secret.d.ts.map +1 -0
- package/lib/github/secret.js +103 -0
- package/lib/github/secret.js.map +1 -0
- package/lib/global.d.ts +16 -0
- package/lib/global.d.ts.map +1 -0
- package/lib/global.js +42 -0
- package/lib/global.js.map +1 -0
- package/lib/index.d.ts +10 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +9 -0
- package/lib/index.js.map +1 -0
- package/lib/input.d.ts +6 -0
- package/lib/input.d.ts.map +1 -0
- package/lib/input.js +2 -0
- package/lib/input.js.map +1 -0
- package/lib/main.d.ts +3 -0
- package/lib/main.d.ts.map +1 -0
- package/lib/main.js +32 -0
- package/lib/main.js.map +1 -0
- package/lib/output.d.ts +24 -0
- package/lib/output.d.ts.map +1 -0
- package/lib/output.js +23 -0
- package/lib/output.js.map +1 -0
- package/lib/print.d.ts +7 -0
- package/lib/print.d.ts.map +1 -0
- package/lib/print.js +10 -0
- package/lib/print.js.map +1 -0
- package/lib/resource.d.ts +71 -0
- package/lib/resource.d.ts.map +1 -0
- package/lib/resource.js +276 -0
- package/lib/resource.js.map +1 -0
- package/lib/scope.d.ts +18 -0
- package/lib/scope.d.ts.map +1 -0
- package/lib/scope.js +30 -0
- package/lib/scope.js.map +1 -0
- package/lib/slug.d.ts +2 -0
- package/lib/slug.d.ts.map +1 -0
- package/lib/slug.js +4 -0
- package/lib/slug.js.map +1 -0
- package/lib/state.d.ts +40 -0
- package/lib/state.d.ts.map +1 -0
- package/lib/state.js +73 -0
- package/lib/state.js.map +1 -0
- package/lib/stripe/index.d.ts +4 -0
- package/lib/stripe/index.d.ts.map +1 -0
- package/lib/stripe/index.js +4 -0
- package/lib/stripe/index.js.map +1 -0
- package/lib/stripe/price.d.ts +109 -0
- package/lib/stripe/price.d.ts.map +1 -0
- package/lib/stripe/price.js +112 -0
- package/lib/stripe/price.js.map +1 -0
- package/lib/stripe/product.d.ts +86 -0
- package/lib/stripe/product.d.ts.map +1 -0
- package/lib/stripe/product.js +90 -0
- package/lib/stripe/product.js.map +1 -0
- package/lib/stripe/webhook.d.ts +73 -0
- package/lib/stripe/webhook.d.ts.map +1 -0
- package/lib/stripe/webhook.js +94 -0
- package/lib/stripe/webhook.js.map +1 -0
- package/lib/utils/content-type.d.ts +8 -0
- package/lib/utils/content-type.d.ts.map +1 -0
- package/lib/utils/content-type.js +41 -0
- package/lib/utils/content-type.js.map +1 -0
- package/lib/utils/retry.d.ts +13 -0
- package/lib/utils/retry.d.ts.map +1 -0
- package/lib/utils/retry.js +32 -0
- package/lib/utils/retry.js.map +1 -0
- package/package.json +1 -1
- package/src/cloudflare/bindings.ts +7 -1
- package/src/cloudflare/bucket.ts +240 -0
- package/src/cloudflare/index.ts +1 -0
- package/src/cloudflare/static-site.ts +13 -1
- package/src/cloudflare/worker.ts +7 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"content-type.js","sourceRoot":"","sources":["../../src/utils/content-type.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,oBAAoB;AACpB,MAAM,SAAS,GAA2B;IACxC,OAAO,EAAE,WAAW;IACpB,MAAM,EAAE,WAAW;IACnB,MAAM,EAAE,UAAU;IAClB,KAAK,EAAE,wBAAwB;IAC/B,OAAO,EAAE,kBAAkB;IAC3B,MAAM,EAAE,iBAAiB;IACzB,MAAM,EAAE,YAAY;IACpB,KAAK,EAAE,eAAe;IACtB,MAAM,EAAE,WAAW;IACnB,MAAM,EAAE,YAAY;IACpB,OAAO,EAAE,YAAY;IACrB,MAAM,EAAE,WAAW;IACnB,OAAO,EAAE,YAAY;IACrB,MAAM,EAAE,eAAe;IACvB,MAAM,EAAE,cAAc;IACtB,MAAM,EAAE,iBAAiB;IACzB,MAAM,EAAE,iBAAiB;IACzB,OAAO,EAAE,WAAW;IACpB,QAAQ,EAAE,YAAY;IACtB,MAAM,EAAE,UAAU;IAClB,MAAM,EAAE,UAAU;IAClB,MAAM,EAAE,+BAA+B;IACvC,MAAM,EAAE,WAAW;IACnB,OAAO,EAAE,YAAY;IACrB,MAAM,EAAE,YAAY;IACpB,MAAM,EAAE,WAAW;CACpB,CAAC;AAEF;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,QAAgB;IAC7C,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;IACvD,OAAO,SAAS,CAAC,SAAS,CAAC,IAAI,0BAA0B,CAAC;AAC5D,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility function for exponential backoff retry
|
|
3
|
+
* Retries an operation with exponential backoff when a retryable error occurs
|
|
4
|
+
*
|
|
5
|
+
* @param operation The async operation to execute and potentially retry
|
|
6
|
+
* @param isRetryable Function to determine if an error should trigger a retry
|
|
7
|
+
* @param maxAttempts Maximum number of attempts before giving up
|
|
8
|
+
* @param initialDelayMs Initial delay in milliseconds before first retry
|
|
9
|
+
* @returns Result of the operation
|
|
10
|
+
* @throws The last error encountered if all retries fail
|
|
11
|
+
*/
|
|
12
|
+
export declare function withExponentialBackoff<T>(operation: () => Promise<T>, isRetryable: (error: any) => boolean, maxAttempts?: number, initialDelayMs?: number): Promise<T>;
|
|
13
|
+
//# sourceMappingURL=retry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../src/utils/retry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,wBAAsB,sBAAsB,CAAC,CAAC,EAC5C,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAC3B,WAAW,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,OAAO,EACpC,WAAW,SAAI,EACf,cAAc,SAAM,GACnB,OAAO,CAAC,CAAC,CAAC,CAoBZ"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility function for exponential backoff retry
|
|
3
|
+
* Retries an operation with exponential backoff when a retryable error occurs
|
|
4
|
+
*
|
|
5
|
+
* @param operation The async operation to execute and potentially retry
|
|
6
|
+
* @param isRetryable Function to determine if an error should trigger a retry
|
|
7
|
+
* @param maxAttempts Maximum number of attempts before giving up
|
|
8
|
+
* @param initialDelayMs Initial delay in milliseconds before first retry
|
|
9
|
+
* @returns Result of the operation
|
|
10
|
+
* @throws The last error encountered if all retries fail
|
|
11
|
+
*/
|
|
12
|
+
export async function withExponentialBackoff(operation, isRetryable, maxAttempts = 5, initialDelayMs = 100) {
|
|
13
|
+
let attempt = 0;
|
|
14
|
+
let delay = initialDelayMs;
|
|
15
|
+
while (true) {
|
|
16
|
+
try {
|
|
17
|
+
return await operation();
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
attempt++;
|
|
21
|
+
if (attempt >= maxAttempts || !isRetryable(error)) {
|
|
22
|
+
console.warn("Failed after ", attempt, " attempts");
|
|
23
|
+
throw error;
|
|
24
|
+
}
|
|
25
|
+
// Exponential backoff with jitter
|
|
26
|
+
const jitter = Math.random() * 0.1 * delay;
|
|
27
|
+
await new Promise((resolve) => setTimeout(resolve, delay + jitter));
|
|
28
|
+
delay *= 2; // Double the delay for next attempt
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=retry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/utils/retry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,SAA2B,EAC3B,WAAoC,EACpC,WAAW,GAAG,CAAC,EACf,cAAc,GAAG,GAAG;IAEpB,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,KAAK,GAAG,cAAc,CAAC;IAE3B,OAAO,IAAI,EAAE,CAAC;QACZ,IAAI,CAAC;YACH,OAAO,MAAM,SAAS,EAAE,CAAC;QAC3B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,EAAE,CAAC;YACV,IAAI,OAAO,IAAI,WAAW,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC;gBAClD,OAAO,CAAC,IAAI,CAAC,eAAe,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;gBACpD,MAAM,KAAK,CAAC;YACd,CAAC;YAED,kCAAkC;YAClC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,GAAG,KAAK,CAAC;YAC3C,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC;YACpE,KAAK,IAAI,CAAC,CAAC,CAAC,oCAAoC;QAClD,CAAC;IACH,CAAC;AACH,CAAC"}
|
package/package.json
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* Based on Cloudflare API documentation:
|
|
4
4
|
* https://developers.cloudflare.com/api/resources/workers/subresources/scripts/methods/update/
|
|
5
5
|
*/
|
|
6
|
+
import type { Bucket } from "./bucket";
|
|
6
7
|
import type { DurableObjectNamespace } from "./durable-object-namespace";
|
|
7
8
|
import type { KVNamespace } from "./kv-namespace";
|
|
8
9
|
import type { Worker } from "./worker";
|
|
@@ -14,7 +15,12 @@ export type Bindings = {
|
|
|
14
15
|
/**
|
|
15
16
|
* L2 Binding Resources.
|
|
16
17
|
*/
|
|
17
|
-
export type Binding =
|
|
18
|
+
export type Binding =
|
|
19
|
+
| DurableObjectNamespace
|
|
20
|
+
| KVNamespace
|
|
21
|
+
| Worker
|
|
22
|
+
| Bucket
|
|
23
|
+
| string;
|
|
18
24
|
|
|
19
25
|
/**
|
|
20
26
|
* Union type for all Worker binding types (API spec)
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import type { Resolved } from "../output";
|
|
2
|
+
import { type Context, Resource } from "../resource";
|
|
3
|
+
import { createCloudflareApi } from "./api";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Properties for creating or updating an R2 Bucket
|
|
7
|
+
*/
|
|
8
|
+
export interface BucketProps {
|
|
9
|
+
/**
|
|
10
|
+
* Name of the bucket
|
|
11
|
+
* Names can only contain lowercase letters (a-z), numbers (0-9), and hyphens (-)
|
|
12
|
+
* Cannot begin or end with a hyphen
|
|
13
|
+
*/
|
|
14
|
+
name?: string;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Optional location hint for the bucket
|
|
18
|
+
* Indicates the primary geographical location data will be accessed from
|
|
19
|
+
*/
|
|
20
|
+
locationHint?: string;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Optional jurisdiction for the bucket
|
|
24
|
+
* Determines the regulatory jurisdiction the bucket data falls under
|
|
25
|
+
*/
|
|
26
|
+
jurisdiction?: "default" | "eu" | "fedramp";
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Whether to allow public access through the r2.dev subdomain
|
|
30
|
+
* Only for development purposes - use custom domains for production
|
|
31
|
+
*/
|
|
32
|
+
allowPublicAccess?: boolean;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Output returned after R2 Bucket creation/update
|
|
37
|
+
*/
|
|
38
|
+
export interface BucketOutput extends BucketProps {
|
|
39
|
+
/**
|
|
40
|
+
* The ID of the bucket (same as name)
|
|
41
|
+
*/
|
|
42
|
+
id: string;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Location of the bucket
|
|
46
|
+
*/
|
|
47
|
+
location: string;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Time at which the bucket was created (Unix timestamp in seconds)
|
|
51
|
+
*/
|
|
52
|
+
creationDate: number;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Resource type identifier
|
|
56
|
+
*/
|
|
57
|
+
type: "r2_bucket";
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Cloudflare R2 bucket API response
|
|
62
|
+
*/
|
|
63
|
+
interface CloudflareBucketResponse {
|
|
64
|
+
result: {
|
|
65
|
+
name: string;
|
|
66
|
+
location?: string;
|
|
67
|
+
creation_date: string;
|
|
68
|
+
};
|
|
69
|
+
success: boolean;
|
|
70
|
+
errors: Array<{ code: number; message: string }>;
|
|
71
|
+
messages: string[];
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export function isBucket(resource: any): resource is Resolved<Bucket> {
|
|
75
|
+
return (
|
|
76
|
+
resource && typeof resource === "object" && resource.id && resource.location
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export class Bucket extends Resource(
|
|
81
|
+
"cloudflare::Bucket",
|
|
82
|
+
async (ctx: Context<BucketOutput>, props: BucketProps) => {
|
|
83
|
+
// Create Cloudflare API client with automatic account discovery
|
|
84
|
+
const api = await createCloudflareApi();
|
|
85
|
+
|
|
86
|
+
// Resource ID defaults to bucket name if provided
|
|
87
|
+
const bucketName = props.name || ctx.resourceID;
|
|
88
|
+
|
|
89
|
+
if (ctx.event === "delete") {
|
|
90
|
+
if (ctx.output?.id) {
|
|
91
|
+
// Delete R2 bucket
|
|
92
|
+
const headers: Record<string, string> = {};
|
|
93
|
+
if (props.jurisdiction && props.jurisdiction !== "default") {
|
|
94
|
+
headers["cf-r2-jurisdiction"] = props.jurisdiction;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const deleteResponse = await api.delete(
|
|
98
|
+
`/accounts/${api.accountId}/r2/buckets/${ctx.output.id}`,
|
|
99
|
+
{ headers },
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
if (!deleteResponse.ok && deleteResponse.status !== 404) {
|
|
103
|
+
const errorData: any = await deleteResponse.json().catch(() => ({
|
|
104
|
+
errors: [{ message: deleteResponse.statusText }],
|
|
105
|
+
}));
|
|
106
|
+
throw new Error(
|
|
107
|
+
`Error deleting R2 bucket '${bucketName}': ${errorData.errors?.[0]?.message || deleteResponse.statusText}`,
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Return void (a deleted bucket has no content)
|
|
113
|
+
return;
|
|
114
|
+
} else {
|
|
115
|
+
try {
|
|
116
|
+
let bucketOutput: BucketOutput;
|
|
117
|
+
|
|
118
|
+
if (ctx.event === "update" && ctx.output?.id) {
|
|
119
|
+
// Get bucket details to verify it exists
|
|
120
|
+
const headers: Record<string, string> = {};
|
|
121
|
+
if (props.jurisdiction && props.jurisdiction !== "default") {
|
|
122
|
+
headers["cf-r2-jurisdiction"] = props.jurisdiction;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const getResponse = await api.get(
|
|
126
|
+
`/accounts/${api.accountId}/r2/buckets/${bucketName}`,
|
|
127
|
+
{ headers },
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
if (!getResponse.ok) {
|
|
131
|
+
const errorData: any = await getResponse.json().catch(() => ({
|
|
132
|
+
errors: [{ message: getResponse.statusText }],
|
|
133
|
+
}));
|
|
134
|
+
throw new Error(
|
|
135
|
+
`Error getting R2 bucket '${bucketName}': ${errorData.errors?.[0]?.message || getResponse.statusText}`,
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const result = (await getResponse.json()) as CloudflareBucketResponse;
|
|
140
|
+
bucketOutput = {
|
|
141
|
+
id: result.result.name,
|
|
142
|
+
name: result.result.name,
|
|
143
|
+
location: result.result.location || "default",
|
|
144
|
+
creationDate: Math.floor(
|
|
145
|
+
new Date(result.result.creation_date).getTime() / 1000,
|
|
146
|
+
),
|
|
147
|
+
jurisdiction: props.jurisdiction || "default",
|
|
148
|
+
type: "r2_bucket",
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
// Update public access setting if it has changed
|
|
152
|
+
if (props.allowPublicAccess !== undefined) {
|
|
153
|
+
await updatePublicAccess(api, bucketName, props.allowPublicAccess);
|
|
154
|
+
}
|
|
155
|
+
} else {
|
|
156
|
+
// Create new R2 bucket
|
|
157
|
+
const createPayload: any = {
|
|
158
|
+
name: bucketName,
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
if (props.locationHint) {
|
|
162
|
+
createPayload.location_hint = props.locationHint;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const headers: Record<string, string> = {};
|
|
166
|
+
if (props.jurisdiction && props.jurisdiction !== "default") {
|
|
167
|
+
headers["cf-r2-jurisdiction"] = props.jurisdiction;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const createResponse = await api.post(
|
|
171
|
+
`/accounts/${api.accountId}/r2/buckets`,
|
|
172
|
+
createPayload,
|
|
173
|
+
{ headers },
|
|
174
|
+
);
|
|
175
|
+
|
|
176
|
+
if (!createResponse.ok) {
|
|
177
|
+
const errorData: any = await createResponse.json().catch(() => ({
|
|
178
|
+
errors: [{ message: createResponse.statusText }],
|
|
179
|
+
}));
|
|
180
|
+
throw new Error(
|
|
181
|
+
`Error creating R2 bucket '${bucketName}': ${errorData.errors?.[0]?.message || createResponse.statusText}`,
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
const result =
|
|
186
|
+
(await createResponse.json()) as CloudflareBucketResponse;
|
|
187
|
+
bucketOutput = {
|
|
188
|
+
id: result.result.name,
|
|
189
|
+
name: result.result.name,
|
|
190
|
+
location: result.result.location || "default",
|
|
191
|
+
creationDate: Math.floor(
|
|
192
|
+
new Date(result.result.creation_date).getTime() / 1000,
|
|
193
|
+
),
|
|
194
|
+
jurisdiction: props.jurisdiction || "default",
|
|
195
|
+
type: "r2_bucket",
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
// Set public access if requested
|
|
199
|
+
if (props.allowPublicAccess) {
|
|
200
|
+
await updatePublicAccess(api, bucketName, true);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
return bucketOutput;
|
|
205
|
+
} catch (error) {
|
|
206
|
+
console.error("Error creating/updating R2 bucket:", error);
|
|
207
|
+
throw error;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
},
|
|
211
|
+
) {}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Helper function to update the public access setting for a bucket
|
|
215
|
+
*/
|
|
216
|
+
async function updatePublicAccess(
|
|
217
|
+
api: any,
|
|
218
|
+
bucketName: string,
|
|
219
|
+
allowPublicAccess: boolean,
|
|
220
|
+
): Promise<void> {
|
|
221
|
+
try {
|
|
222
|
+
const response = await api.put(
|
|
223
|
+
`/accounts/${api.accountId}/r2/buckets/${bucketName}/domains/managed`,
|
|
224
|
+
{
|
|
225
|
+
enabled: allowPublicAccess,
|
|
226
|
+
},
|
|
227
|
+
);
|
|
228
|
+
|
|
229
|
+
if (!response.ok) {
|
|
230
|
+
const errorData: any = await response.json().catch(() => ({
|
|
231
|
+
errors: [{ message: response.statusText }],
|
|
232
|
+
}));
|
|
233
|
+
throw new Error(
|
|
234
|
+
`Error updating R2 bucket public access: ${errorData.errors?.[0]?.message || response.statusText}`,
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
} catch (error) {
|
|
238
|
+
console.warn("Could not set public access:", error);
|
|
239
|
+
}
|
|
240
|
+
}
|
package/src/cloudflare/index.ts
CHANGED
|
@@ -323,6 +323,18 @@ export class StaticSite extends Resource(
|
|
|
323
323
|
},
|
|
324
324
|
},
|
|
325
325
|
};
|
|
326
|
+
|
|
327
|
+
// Determine the entrypoint file - check for .ts first, fallback to .js
|
|
328
|
+
let entrypointFile = "static-site-router.js";
|
|
329
|
+
try {
|
|
330
|
+
const tsFile = path.resolve(__dirname, "static-site-router.ts");
|
|
331
|
+
await fs.access(tsFile);
|
|
332
|
+
// If we reach here, the TypeScript file exists
|
|
333
|
+
entrypointFile = "static-site-router.ts";
|
|
334
|
+
} catch (error) {
|
|
335
|
+
// TypeScript file doesn't exist, use JavaScript (default)
|
|
336
|
+
}
|
|
337
|
+
|
|
326
338
|
const worker = new Worker(
|
|
327
339
|
"worker",
|
|
328
340
|
{
|
|
@@ -333,7 +345,7 @@ export class StaticSite extends Resource(
|
|
|
333
345
|
...(props.workerScript
|
|
334
346
|
? { script: props.workerScript }
|
|
335
347
|
: {
|
|
336
|
-
entrypoint: path.resolve(__dirname,
|
|
348
|
+
entrypoint: path.resolve(__dirname, entrypointFile),
|
|
337
349
|
bundle: bundleOptions,
|
|
338
350
|
}),
|
|
339
351
|
bindings,
|
package/src/cloudflare/worker.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { type Context, Resource } from "../resource";
|
|
|
6
6
|
import { withExponentialBackoff } from "../utils/retry";
|
|
7
7
|
import { type CloudflareApi, createCloudflareApi } from "./api";
|
|
8
8
|
import type { Bindings, WorkerBindingSpec } from "./bindings";
|
|
9
|
+
import { isBucket } from "./bucket";
|
|
9
10
|
import type { DurableObjectNamespace } from "./durable-object-namespace";
|
|
10
11
|
import { isDurableObjectNamespace } from "./durable-object-namespace";
|
|
11
12
|
import { isKVNamespace } from "./kv-namespace";
|
|
@@ -438,6 +439,12 @@ async function prepareWorkerMetadata(
|
|
|
438
439
|
to: className,
|
|
439
440
|
});
|
|
440
441
|
}
|
|
442
|
+
} else if (isBucket(binding)) {
|
|
443
|
+
meta.bindings.push({
|
|
444
|
+
type: "r2_bucket",
|
|
445
|
+
name: bindingName,
|
|
446
|
+
bucket_name: binding.name || binding.id,
|
|
447
|
+
});
|
|
441
448
|
} else {
|
|
442
449
|
// @ts-expect-error - we should never reach here
|
|
443
450
|
throw new Error(`Unsupported binding type: ${binding.type}`);
|