alchemy 0.1.18 → 0.2.1
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/README.md +506 -0
- package/lib/alchemy.d.ts +67 -0
- package/lib/alchemy.js +48 -0
- package/lib/apply.d.ts +3 -20
- package/lib/apply.js +95 -82
- package/lib/aws/account-id.d.ts +0 -1
- package/lib/aws/account-id.js +0 -1
- package/lib/aws/bucket.d.ts +4 -7
- package/lib/aws/bucket.js +8 -12
- package/lib/aws/function.d.ts +4 -7
- package/lib/aws/function.js +9 -30
- package/lib/aws/index.d.ts +1 -1
- package/lib/aws/index.js +1 -1
- package/lib/aws/oidc/github-oidc-provider.d.ts +2 -6
- package/lib/aws/oidc/github-oidc-provider.js +10 -15
- package/lib/aws/oidc/index.d.ts +0 -1
- package/lib/aws/oidc/index.js +0 -1
- package/lib/aws/oidc/oidc-provider.d.ts +4 -6
- package/lib/aws/oidc/oidc-provider.js +9 -11
- package/lib/aws/policy-attachment.d.ts +9 -0
- package/lib/aws/policy-attachment.js +20 -0
- package/lib/aws/policy.d.ts +4 -16
- package/lib/aws/policy.js +9 -40
- package/lib/aws/queue.d.ts +4 -34
- package/lib/aws/queue.js +10 -20
- package/lib/aws/role.d.ts +4 -7
- package/lib/aws/role.js +17 -26
- package/lib/aws/ses.d.ts +4 -10
- package/lib/aws/ses.js +118 -131
- package/lib/aws/table.d.ts +4 -7
- package/lib/aws/table.js +8 -11
- package/lib/cloudflare/api.d.ts +0 -1
- package/lib/cloudflare/api.js +0 -1
- package/lib/cloudflare/asset-manifest.d.ts +0 -1
- package/lib/cloudflare/asset-manifest.js +0 -1
- package/lib/cloudflare/auth.d.ts +0 -1
- package/lib/cloudflare/auth.js +0 -1
- package/lib/cloudflare/bindings.d.ts +1 -1
- package/lib/cloudflare/bindings.js +3 -2
- package/lib/cloudflare/bound.d.ts +0 -1
- package/lib/cloudflare/bound.js +0 -1
- package/lib/cloudflare/bucket.d.ts +7 -15
- package/lib/cloudflare/bucket.js +12 -19
- package/lib/cloudflare/durable-object-namespace.d.ts +0 -3
- package/lib/cloudflare/durable-object-namespace.js +0 -4
- package/lib/cloudflare/generate-asset-manifest.d.ts +0 -1
- package/lib/cloudflare/generate-asset-manifest.js +1 -2
- package/lib/cloudflare/index.d.ts +2 -1
- package/lib/cloudflare/index.js +2 -1
- package/lib/cloudflare/kv-namespace.d.ts +6 -9
- package/lib/cloudflare/kv-namespace.js +16 -20
- package/lib/cloudflare/state.d.ts +0 -1
- package/lib/cloudflare/state.js +0 -1
- package/lib/cloudflare/static-site-router.d.ts +0 -1
- package/lib/cloudflare/static-site-router.js +0 -4
- package/lib/cloudflare/static-site.d.ts +5 -11
- package/lib/cloudflare/static-site.js +25 -37
- package/lib/cloudflare/types.d.ts +0 -1
- package/lib/cloudflare/types.js +0 -1
- package/lib/cloudflare/upload-asset-manifest.d.ts +0 -1
- package/lib/cloudflare/upload-asset-manifest.js +0 -1
- package/lib/cloudflare/worker-metadata.d.ts +0 -1
- package/lib/cloudflare/worker-metadata.js +0 -1
- package/lib/cloudflare/worker-migration.d.ts +0 -1
- package/lib/cloudflare/worker-migration.js +0 -1
- package/lib/cloudflare/worker.d.ts +8 -14
- package/lib/cloudflare/worker.js +38 -50
- package/lib/cloudflare/wrangler.json.d.ts +243 -0
- package/lib/cloudflare/wrangler.json.js +35 -0
- package/lib/cloudflare/zone-settings.d.ts +301 -0
- package/lib/cloudflare/zone-settings.js +1 -0
- package/lib/cloudflare/zone.d.ts +196 -0
- package/lib/cloudflare/zone.js +175 -0
- package/lib/context.d.ts +58 -0
- package/lib/context.js +36 -0
- package/lib/destroy.d.ts +10 -13
- package/lib/destroy.js +104 -43
- package/lib/{esbuild.d.ts → esbuild/bundle.d.ts} +4 -18
- package/lib/{esbuild.js → esbuild/bundle.js} +10 -24
- package/lib/esbuild/index.d.ts +1 -0
- package/lib/esbuild/index.js +1 -0
- package/lib/fs/file.d.ts +13 -0
- package/lib/fs/file.js +20 -0
- package/lib/fs/folder.d.ts +10 -0
- package/lib/fs/folder.js +16 -0
- package/lib/fs/index.d.ts +2 -0
- package/lib/fs/index.js +2 -0
- package/lib/github/client.d.ts +0 -1
- package/lib/github/client.js +0 -1
- package/lib/github/index.d.ts +0 -1
- package/lib/github/index.js +0 -1
- package/lib/github/secret.d.ts +4 -6
- package/lib/github/secret.js +10 -12
- package/lib/index.d.ts +6 -10
- package/lib/index.js +5 -9
- package/lib/project/index.d.ts +1 -0
- package/lib/project/index.js +1 -0
- package/lib/project/vite.d.ts +39 -0
- package/lib/project/vite.js +68 -0
- package/lib/resource.d.ts +34 -62
- package/lib/resource.js +29 -270
- package/lib/scope.d.ts +37 -14
- package/lib/scope.js +97 -23
- package/lib/secret.d.ts +2 -7
- package/lib/secret.js +7 -20
- package/lib/state.d.ts +14 -10
- package/lib/state.js +20 -14
- package/lib/stripe/index.d.ts +0 -1
- package/lib/stripe/index.js +0 -1
- package/lib/stripe/price.d.ts +4 -5
- package/lib/stripe/price.js +10 -20
- package/lib/stripe/product.d.ts +4 -5
- package/lib/stripe/product.js +10 -20
- package/lib/stripe/webhook.d.ts +4 -6
- package/lib/stripe/webhook.js +12 -25
- package/lib/test/bun.d.ts +19 -0
- package/lib/test/bun.js +55 -0
- package/lib/{utils → util}/content-type.d.ts +0 -1
- package/lib/{utils → util}/content-type.js +0 -1
- package/lib/{encrypt.d.ts → util/encrypt.d.ts} +0 -1
- package/lib/{encrypt.js → util/encrypt.js} +0 -1
- package/lib/{error.d.ts → util/ignore.d.ts} +0 -1
- package/lib/{error.js → util/ignore.js} +0 -1
- package/lib/{utils → util}/retry.d.ts +0 -1
- package/lib/{utils → util}/retry.js +0 -1
- package/lib/util/rm.d.ts +1 -0
- package/lib/util/rm.js +11 -0
- package/lib/util/serde.d.ts +3 -0
- package/lib/{serde.js → util/serde.js} +19 -10
- package/lib/util/slugify.d.ts +1 -0
- package/lib/util/slugify.js +3 -0
- package/package.json +7 -5
- package/src/alchemy.ts +127 -0
- package/src/apply.ts +116 -115
- package/src/aws/bucket.ts +11 -14
- package/src/aws/function.ts +13 -33
- package/src/aws/index.ts +1 -0
- package/src/aws/oidc/github-oidc-provider.ts +14 -19
- package/src/aws/oidc/oidc-provider.ts +19 -12
- package/src/aws/policy-attachment.ts +51 -0
- package/src/aws/policy.ts +15 -60
- package/src/aws/queue.ts +17 -21
- package/src/aws/role.ts +25 -28
- package/src/aws/ses.ts +150 -164
- package/src/aws/table.ts +15 -15
- package/src/cloudflare/bindings.ts +8 -0
- package/src/cloudflare/bucket.ts +39 -47
- package/src/cloudflare/durable-object-namespace.ts +0 -10
- package/src/cloudflare/generate-asset-manifest.ts +1 -1
- package/src/cloudflare/index.ts +2 -0
- package/src/cloudflare/kv-namespace.ts +35 -33
- package/src/cloudflare/static-site-router.ts +0 -3
- package/src/cloudflare/static-site.ts +55 -71
- package/src/cloudflare/worker.ts +106 -112
- package/src/cloudflare/wrangler.json.ts +309 -0
- package/src/cloudflare/zone-settings.ts +368 -0
- package/src/cloudflare/zone.ts +491 -0
- package/src/context.ts +122 -0
- package/src/destroy.ts +124 -73
- package/src/{esbuild.ts → esbuild/bundle.ts} +16 -28
- package/src/esbuild/index.ts +1 -0
- package/src/fs/file.ts +39 -0
- package/src/fs/folder.ts +32 -0
- package/src/fs/index.ts +2 -0
- package/src/github/secret.ts +19 -16
- package/src/index.ts +7 -15
- package/src/project/index.ts +1 -0
- package/src/project/vite.ts +152 -0
- package/src/resource.ts +101 -462
- package/src/scope.ts +125 -36
- package/src/secret.ts +9 -32
- package/src/state.ts +38 -21
- package/src/stripe/price.ts +17 -22
- package/src/stripe/product.ts +17 -22
- package/src/stripe/webhook.ts +21 -27
- package/src/test/bun.ts +105 -0
- package/src/util/rm.ts +11 -0
- package/src/util/serde.ts +53 -0
- package/src/util/slugify.ts +3 -0
- package/lib/$.d.ts +0 -12
- package/lib/$.d.ts.map +0 -1
- package/lib/$.js +0 -42
- package/lib/$.js.map +0 -1
- package/lib/alchemize.d.ts +0 -47
- package/lib/alchemize.d.ts.map +0 -1
- package/lib/alchemize.js +0 -116
- package/lib/alchemize.js.map +0 -1
- package/lib/apply.d.ts.map +0 -1
- package/lib/apply.js.map +0 -1
- package/lib/aws/account-id.d.ts.map +0 -1
- package/lib/aws/account-id.js.map +0 -1
- package/lib/aws/bucket.d.ts.map +0 -1
- package/lib/aws/bucket.js.map +0 -1
- package/lib/aws/function.d.ts.map +0 -1
- package/lib/aws/function.js.map +0 -1
- package/lib/aws/index.d.ts.map +0 -1
- package/lib/aws/index.js.map +0 -1
- package/lib/aws/oidc/github-oidc-provider.d.ts.map +0 -1
- package/lib/aws/oidc/github-oidc-provider.js.map +0 -1
- package/lib/aws/oidc/index.d.ts.map +0 -1
- package/lib/aws/oidc/index.js.map +0 -1
- package/lib/aws/oidc/oidc-provider.d.ts.map +0 -1
- package/lib/aws/oidc/oidc-provider.js.map +0 -1
- package/lib/aws/policy.d.ts.map +0 -1
- package/lib/aws/policy.js.map +0 -1
- package/lib/aws/queue.d.ts.map +0 -1
- package/lib/aws/queue.js.map +0 -1
- package/lib/aws/role.d.ts.map +0 -1
- package/lib/aws/role.js.map +0 -1
- package/lib/aws/ses.d.ts.map +0 -1
- package/lib/aws/ses.js.map +0 -1
- package/lib/aws/table.d.ts.map +0 -1
- package/lib/aws/table.js.map +0 -1
- package/lib/cloudflare/api.d.ts.map +0 -1
- package/lib/cloudflare/api.js.map +0 -1
- package/lib/cloudflare/asset-manifest.d.ts.map +0 -1
- package/lib/cloudflare/asset-manifest.js.map +0 -1
- package/lib/cloudflare/auth.d.ts.map +0 -1
- package/lib/cloudflare/auth.js.map +0 -1
- package/lib/cloudflare/bindings.d.ts.map +0 -1
- package/lib/cloudflare/bindings.js.map +0 -1
- package/lib/cloudflare/bound.d.ts.map +0 -1
- package/lib/cloudflare/bound.js.map +0 -1
- package/lib/cloudflare/bucket.d.ts.map +0 -1
- package/lib/cloudflare/bucket.js.map +0 -1
- package/lib/cloudflare/durable-object-namespace.d.ts.map +0 -1
- package/lib/cloudflare/durable-object-namespace.js.map +0 -1
- package/lib/cloudflare/generate-asset-manifest.d.ts.map +0 -1
- package/lib/cloudflare/generate-asset-manifest.js.map +0 -1
- package/lib/cloudflare/index.d.ts.map +0 -1
- package/lib/cloudflare/index.js.map +0 -1
- package/lib/cloudflare/kv-namespace.d.ts.map +0 -1
- package/lib/cloudflare/kv-namespace.js.map +0 -1
- package/lib/cloudflare/state.d.ts.map +0 -1
- package/lib/cloudflare/state.js.map +0 -1
- package/lib/cloudflare/static-site-router.d.ts.map +0 -1
- package/lib/cloudflare/static-site-router.js.map +0 -1
- package/lib/cloudflare/static-site.d.ts.map +0 -1
- package/lib/cloudflare/static-site.js.map +0 -1
- package/lib/cloudflare/types.d.ts.map +0 -1
- package/lib/cloudflare/types.js.map +0 -1
- package/lib/cloudflare/upload-asset-manifest.d.ts.map +0 -1
- package/lib/cloudflare/upload-asset-manifest.js.map +0 -1
- package/lib/cloudflare/worker-metadata.d.ts.map +0 -1
- package/lib/cloudflare/worker-metadata.js.map +0 -1
- package/lib/cloudflare/worker-migration.d.ts.map +0 -1
- package/lib/cloudflare/worker-migration.js.map +0 -1
- package/lib/cloudflare/worker.d.ts.map +0 -1
- package/lib/cloudflare/worker.js.map +0 -1
- package/lib/destroy.d.ts.map +0 -1
- package/lib/destroy.js.map +0 -1
- package/lib/encrypt.d.ts.map +0 -1
- package/lib/encrypt.js.map +0 -1
- package/lib/error.d.ts.map +0 -1
- package/lib/error.js.map +0 -1
- package/lib/esbuild.d.ts.map +0 -1
- package/lib/esbuild.js.map +0 -1
- package/lib/fs.d.ts +0 -12
- package/lib/fs.d.ts.map +0 -1
- package/lib/fs.js +0 -41
- package/lib/fs.js.map +0 -1
- package/lib/github/client.d.ts.map +0 -1
- package/lib/github/client.js.map +0 -1
- package/lib/github/index.d.ts.map +0 -1
- package/lib/github/index.js.map +0 -1
- package/lib/github/secret.d.ts.map +0 -1
- package/lib/github/secret.js.map +0 -1
- package/lib/global.d.ts +0 -16
- package/lib/global.d.ts.map +0 -1
- package/lib/global.js +0 -42
- package/lib/global.js.map +0 -1
- package/lib/index.d.ts.map +0 -1
- package/lib/index.js.map +0 -1
- package/lib/input.d.ts +0 -7
- package/lib/input.d.ts.map +0 -1
- package/lib/input.js +0 -2
- package/lib/input.js.map +0 -1
- package/lib/main.d.ts +0 -3
- package/lib/main.d.ts.map +0 -1
- package/lib/main.js +0 -32
- package/lib/main.js.map +0 -1
- package/lib/output.d.ts +0 -25
- package/lib/output.d.ts.map +0 -1
- package/lib/output.js +0 -23
- package/lib/output.js.map +0 -1
- package/lib/print.d.ts +0 -7
- package/lib/print.d.ts.map +0 -1
- package/lib/print.js +0 -10
- package/lib/print.js.map +0 -1
- package/lib/resource.d.ts.map +0 -1
- package/lib/resource.js.map +0 -1
- package/lib/scope.d.ts.map +0 -1
- package/lib/scope.js.map +0 -1
- package/lib/secret.d.ts.map +0 -1
- package/lib/secret.js.map +0 -1
- package/lib/serde.d.ts +0 -3
- package/lib/serde.d.ts.map +0 -1
- package/lib/serde.js.map +0 -1
- package/lib/slug.d.ts +0 -2
- package/lib/slug.d.ts.map +0 -1
- package/lib/slug.js +0 -4
- package/lib/slug.js.map +0 -1
- package/lib/state.d.ts.map +0 -1
- package/lib/state.js.map +0 -1
- package/lib/stripe/index.d.ts.map +0 -1
- package/lib/stripe/index.js.map +0 -1
- package/lib/stripe/price.d.ts.map +0 -1
- package/lib/stripe/price.js.map +0 -1
- package/lib/stripe/product.d.ts.map +0 -1
- package/lib/stripe/product.js.map +0 -1
- package/lib/stripe/webhook.d.ts.map +0 -1
- package/lib/stripe/webhook.js.map +0 -1
- package/lib/utils/content-type.d.ts.map +0 -1
- package/lib/utils/content-type.js.map +0 -1
- package/lib/utils/retry.d.ts.map +0 -1
- package/lib/utils/retry.js.map +0 -1
- package/src/$.ts +0 -69
- package/src/alchemize.ts +0 -195
- package/src/fs.ts +0 -47
- package/src/global.ts +0 -63
- package/src/input.ts +0 -19
- package/src/main.ts +0 -34
- package/src/output.ts +0 -75
- package/src/print.ts +0 -18
- package/src/serde.ts +0 -46
- package/src/slug.ts +0 -3
- /package/src/{utils → util}/content-type.ts +0 -0
- /package/src/{encrypt.ts → util/encrypt.ts} +0 -0
- /package/src/{error.ts → util/ignore.ts} +0 -0
- /package/src/{utils → util}/retry.ts +0 -0
package/src/cloudflare/worker.ts
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import * as fs from "fs/promises";
|
|
2
|
-
import {
|
|
3
|
-
import { Bundle, type BundleProps } from "../esbuild";
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import { withExponentialBackoff } from "../utils/retry";
|
|
2
|
+
import type { Context } from "../context";
|
|
3
|
+
import { Bundle, type BundleProps } from "../esbuild/bundle";
|
|
4
|
+
import { Resource } from "../resource";
|
|
5
|
+
import { isSecret } from "../secret";
|
|
6
|
+
import { withExponentialBackoff } from "../util/retry";
|
|
7
|
+
import { slugify } from "../util/slugify";
|
|
9
8
|
import { type CloudflareApi, createCloudflareApi } from "./api";
|
|
10
|
-
import
|
|
9
|
+
import {
|
|
10
|
+
type Bindings,
|
|
11
|
+
type WorkerBindingSpec,
|
|
12
|
+
isDurableObjectNamespace,
|
|
13
|
+
} from "./bindings";
|
|
11
14
|
import type { Bound } from "./bound";
|
|
12
|
-
import { isBucket } from "./bucket";
|
|
13
15
|
import type { DurableObjectNamespace } from "./durable-object-namespace";
|
|
14
|
-
import { isDurableObjectNamespace } from "./durable-object-namespace";
|
|
15
16
|
import { isKVNamespace } from "./kv-namespace";
|
|
16
17
|
import type { WorkerScriptMetadata } from "./worker-metadata";
|
|
17
18
|
import type { SingleStepMigration } from "./worker-migration";
|
|
@@ -100,8 +101,9 @@ export interface WorkerProps<B extends Bindings = Bindings> {
|
|
|
100
101
|
/**
|
|
101
102
|
* Output returned after Worker creation/update
|
|
102
103
|
*/
|
|
103
|
-
export interface
|
|
104
|
-
extends
|
|
104
|
+
export interface Worker<B extends Bindings = Bindings>
|
|
105
|
+
extends Resource<"cloudflare::Worker">,
|
|
106
|
+
Omit<WorkerProps<B>, "url"> {
|
|
105
107
|
type: "service";
|
|
106
108
|
|
|
107
109
|
/**
|
|
@@ -128,94 +130,95 @@ export interface WorkerOutput<B extends Bindings = Bindings>
|
|
|
128
130
|
/**
|
|
129
131
|
* The bindings that were created
|
|
130
132
|
*/
|
|
131
|
-
bindings: B;
|
|
132
|
-
}
|
|
133
|
+
bindings: B | undefined;
|
|
133
134
|
|
|
134
|
-
|
|
135
|
-
|
|
135
|
+
// phantom property (for typeof myWorker.Env)
|
|
136
|
+
Env: {
|
|
137
|
+
[bindingName in keyof B]: Bound<B[bindingName]>;
|
|
138
|
+
};
|
|
136
139
|
}
|
|
137
140
|
|
|
138
|
-
export
|
|
141
|
+
export const Worker = Resource(
|
|
139
142
|
"cloudflare::Worker",
|
|
140
143
|
{
|
|
141
144
|
alwaysUpdate: true,
|
|
142
145
|
},
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
const workerName = props.name;
|
|
159
|
-
|
|
160
|
-
// Validate input - we need either script, entryPoint, or bundle
|
|
161
|
-
if (!props.script && !props.entrypoint) {
|
|
162
|
-
throw new Error("One of script or entryPoint must be provided");
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
if (ctx.event === "delete") {
|
|
166
|
-
return deleteWorker(ctx, api, workerName);
|
|
167
|
-
} else if (ctx.event === "create") {
|
|
168
|
-
await assertWorkerDoesNotExist(ctx, api, workerName);
|
|
169
|
-
}
|
|
146
|
+
async function <const B extends Bindings>(
|
|
147
|
+
this: Context<Worker<NoInfer<B>>>,
|
|
148
|
+
id: string,
|
|
149
|
+
props: WorkerProps<B>,
|
|
150
|
+
): Promise<Worker<B>> {
|
|
151
|
+
// Create Cloudflare API client with automatic account discovery
|
|
152
|
+
const api = await createCloudflareApi();
|
|
153
|
+
|
|
154
|
+
// Use the provided name
|
|
155
|
+
const workerName = props.name;
|
|
156
|
+
|
|
157
|
+
// Validate input - we need either script, entryPoint, or bundle
|
|
158
|
+
if (!props.script && !props.entrypoint) {
|
|
159
|
+
throw new Error("One of script or entryPoint must be provided");
|
|
160
|
+
}
|
|
170
161
|
|
|
171
|
-
|
|
162
|
+
if (this.phase === "delete") {
|
|
163
|
+
await deleteWorker(this, api, workerName);
|
|
164
|
+
return this.destroy();
|
|
165
|
+
} else if (this.phase === "create") {
|
|
166
|
+
await assertWorkerDoesNotExist(this, api, workerName);
|
|
167
|
+
}
|
|
172
168
|
|
|
173
|
-
|
|
169
|
+
const oldBindings = await this.get<Bindings>("bindings");
|
|
174
170
|
|
|
175
|
-
|
|
176
|
-
|
|
171
|
+
const scriptMetadata = await prepareWorkerMetadata(
|
|
172
|
+
this,
|
|
173
|
+
oldBindings,
|
|
174
|
+
props,
|
|
175
|
+
);
|
|
177
176
|
|
|
178
|
-
|
|
179
|
-
|
|
177
|
+
// Get the script content - either from props.script, or by bundling
|
|
178
|
+
const scriptContent = props.script ?? (await bundleWorkerScript(props));
|
|
180
179
|
|
|
181
|
-
|
|
182
|
-
|
|
180
|
+
// Upload the worker script
|
|
181
|
+
await putWorker(api, workerName, scriptContent, scriptMetadata);
|
|
183
182
|
|
|
184
|
-
|
|
185
|
-
|
|
183
|
+
// TODO: it is less than ideal that this can fail, resulting in state problem
|
|
184
|
+
await this.set("bindings", props.bindings);
|
|
186
185
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
ctx,
|
|
190
|
-
api,
|
|
191
|
-
workerName,
|
|
192
|
-
props.url ?? false,
|
|
193
|
-
);
|
|
186
|
+
// Handle routes if requested
|
|
187
|
+
await setupRoutes(api, workerName, props.routes || []);
|
|
194
188
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
name: workerName,
|
|
203
|
-
script: scriptContent,
|
|
204
|
-
format: props.format || "esm", // Include format in the output
|
|
205
|
-
routes: props.routes || [],
|
|
206
|
-
bindings: props.bindings ?? {},
|
|
207
|
-
env: props.env,
|
|
208
|
-
observability: scriptMetadata.observability,
|
|
209
|
-
createdAt: now,
|
|
210
|
-
updatedAt: now,
|
|
211
|
-
url: workerUrl,
|
|
212
|
-
};
|
|
189
|
+
// Handle worker URL if requested
|
|
190
|
+
const workerUrl = await configureURL(
|
|
191
|
+
this,
|
|
192
|
+
api,
|
|
193
|
+
workerName,
|
|
194
|
+
props.url ?? false,
|
|
195
|
+
);
|
|
213
196
|
|
|
214
|
-
|
|
215
|
-
|
|
197
|
+
// Get current timestamp
|
|
198
|
+
const now = Date.now();
|
|
199
|
+
|
|
200
|
+
// Construct the output
|
|
201
|
+
return this({
|
|
202
|
+
type: "service",
|
|
203
|
+
id,
|
|
204
|
+
name: workerName,
|
|
205
|
+
script: scriptContent,
|
|
206
|
+
format: props.format || "esm", // Include format in the output
|
|
207
|
+
routes: props.routes || [],
|
|
208
|
+
bindings: props.bindings ?? ({} as B),
|
|
209
|
+
env: props.env,
|
|
210
|
+
observability: scriptMetadata.observability,
|
|
211
|
+
createdAt: now,
|
|
212
|
+
updatedAt: now,
|
|
213
|
+
url: workerUrl,
|
|
214
|
+
// phantom property
|
|
215
|
+
Env: undefined!,
|
|
216
|
+
});
|
|
217
|
+
},
|
|
218
|
+
);
|
|
216
219
|
|
|
217
|
-
async function deleteWorker(
|
|
218
|
-
ctx: Context<
|
|
220
|
+
async function deleteWorker<B extends Bindings>(
|
|
221
|
+
ctx: Context<Worker<B>>,
|
|
219
222
|
api: CloudflareApi,
|
|
220
223
|
workerName: string,
|
|
221
224
|
) {
|
|
@@ -284,7 +287,6 @@ async function deleteWorker(
|
|
|
284
287
|
}
|
|
285
288
|
|
|
286
289
|
async function putWorker(
|
|
287
|
-
ctx: Context<WorkerOutput>,
|
|
288
290
|
api: CloudflareApi,
|
|
289
291
|
workerName: string,
|
|
290
292
|
scriptContent: string,
|
|
@@ -309,8 +311,6 @@ async function putWorker(
|
|
|
309
311
|
scriptName,
|
|
310
312
|
);
|
|
311
313
|
|
|
312
|
-
// console.log("Script Metadata:", JSON.stringify(scriptMetadata, null, 2));
|
|
313
|
-
|
|
314
314
|
// Add metadata as JSON
|
|
315
315
|
formData.append(
|
|
316
316
|
"metadata",
|
|
@@ -375,8 +375,8 @@ interface WorkerMetadata {
|
|
|
375
375
|
tags?: string[];
|
|
376
376
|
}
|
|
377
377
|
|
|
378
|
-
async function prepareWorkerMetadata(
|
|
379
|
-
ctx: Context<
|
|
378
|
+
async function prepareWorkerMetadata<B extends Bindings>(
|
|
379
|
+
ctx: Context<Worker<B>>,
|
|
380
380
|
oldBindings: Bindings | undefined,
|
|
381
381
|
props: WorkerProps,
|
|
382
382
|
): Promise<WorkerMetadata> {
|
|
@@ -386,7 +386,8 @@ async function prepareWorkerMetadata(
|
|
|
386
386
|
observability: {
|
|
387
387
|
enabled: props.observability?.enabled !== false,
|
|
388
388
|
},
|
|
389
|
-
|
|
389
|
+
// TODO(sam): base64 encode instead? 0 collision risk vs readability.
|
|
390
|
+
tags: [`alchemy:id:${slugify(ctx.fqn)}`],
|
|
390
391
|
migrations: {
|
|
391
392
|
new_classes: props.migrations?.new_classes ?? [],
|
|
392
393
|
deleted_classes: props.migrations?.deleted_classes ?? [],
|
|
@@ -396,7 +397,7 @@ async function prepareWorkerMetadata(
|
|
|
396
397
|
},
|
|
397
398
|
};
|
|
398
399
|
|
|
399
|
-
const bindings = (props.bindings ?? {}) as
|
|
400
|
+
const bindings = (props.bindings ?? {}) as Bindings;
|
|
400
401
|
|
|
401
402
|
// Convert bindings to the format expected by the API
|
|
402
403
|
for (const [bindingName, binding] of Object.entries(bindings)) {
|
|
@@ -406,7 +407,7 @@ async function prepareWorkerMetadata(
|
|
|
406
407
|
meta.bindings.push({
|
|
407
408
|
type: "kv_namespace",
|
|
408
409
|
name: bindingName,
|
|
409
|
-
namespace_id: binding.
|
|
410
|
+
namespace_id: binding.namespaceId,
|
|
410
411
|
});
|
|
411
412
|
} else if (typeof binding === "string") {
|
|
412
413
|
meta.bindings.push({
|
|
@@ -420,7 +421,7 @@ async function prepareWorkerMetadata(
|
|
|
420
421
|
name: bindingName,
|
|
421
422
|
service: binding.id,
|
|
422
423
|
});
|
|
423
|
-
} else if (
|
|
424
|
+
} else if (binding.type === "durable_object_namespace") {
|
|
424
425
|
const stableId = binding.id;
|
|
425
426
|
const className = binding.className;
|
|
426
427
|
|
|
@@ -451,13 +452,13 @@ async function prepareWorkerMetadata(
|
|
|
451
452
|
to: className,
|
|
452
453
|
});
|
|
453
454
|
}
|
|
454
|
-
} else if (
|
|
455
|
+
} else if (binding.type === "r2_bucket") {
|
|
455
456
|
meta.bindings.push({
|
|
456
457
|
type: "r2_bucket",
|
|
457
458
|
name: bindingName,
|
|
458
|
-
bucket_name: binding.name
|
|
459
|
+
bucket_name: binding.name,
|
|
459
460
|
});
|
|
460
|
-
} else if (binding
|
|
461
|
+
} else if (isSecret(binding)) {
|
|
461
462
|
meta.bindings.push({
|
|
462
463
|
type: "secret_text",
|
|
463
464
|
name: bindingName,
|
|
@@ -494,8 +495,8 @@ async function prepareWorkerMetadata(
|
|
|
494
495
|
return meta;
|
|
495
496
|
}
|
|
496
497
|
|
|
497
|
-
async function assertWorkerDoesNotExist(
|
|
498
|
-
ctx: Context<
|
|
498
|
+
async function assertWorkerDoesNotExist<B extends Bindings>(
|
|
499
|
+
ctx: Context<Worker<B>>,
|
|
499
500
|
api: CloudflareApi,
|
|
500
501
|
workerName: string,
|
|
501
502
|
) {
|
|
@@ -516,7 +517,7 @@ async function assertWorkerDoesNotExist(
|
|
|
516
517
|
|
|
517
518
|
if (
|
|
518
519
|
metadata.default_environment?.script.tags.includes(
|
|
519
|
-
`alchemy:id:${ctx.
|
|
520
|
+
`alchemy:id:${slugify(ctx.fqn)}`,
|
|
520
521
|
)
|
|
521
522
|
) {
|
|
522
523
|
return true;
|
|
@@ -527,15 +528,12 @@ async function assertWorkerDoesNotExist(
|
|
|
527
528
|
);
|
|
528
529
|
} else {
|
|
529
530
|
throw new Error(
|
|
530
|
-
`Error checking if worker exists: ${response.status} ${response.statusText}`,
|
|
531
|
+
`Error checking if worker exists: ${response.status} ${response.statusText} ${await response.text()}`,
|
|
531
532
|
);
|
|
532
533
|
}
|
|
533
534
|
}
|
|
534
535
|
|
|
535
|
-
async function bundleWorkerScript(
|
|
536
|
-
ctx: Context<WorkerOutput>,
|
|
537
|
-
props: WorkerProps,
|
|
538
|
-
) {
|
|
536
|
+
async function bundleWorkerScript<B extends Bindings>(props: WorkerProps) {
|
|
539
537
|
// Get the script content - either from props.script, or by bundling
|
|
540
538
|
|
|
541
539
|
// Create and use a Bundle resource with worker-optimized configuration
|
|
@@ -556,18 +554,14 @@ async function bundleWorkerScript(
|
|
|
556
554
|
};
|
|
557
555
|
|
|
558
556
|
// Create the bundle
|
|
559
|
-
const bundle =
|
|
557
|
+
const bundle = await Bundle("bundle", {
|
|
560
558
|
entryPoint: props.entrypoint!,
|
|
561
559
|
...bundleOptions,
|
|
562
560
|
external: [...(bundleOptions.external ?? []), "cloudflare:workers"],
|
|
563
561
|
});
|
|
564
562
|
|
|
565
|
-
// Get the bundled content
|
|
566
|
-
const bundleOutput = await apply(bundle, {
|
|
567
|
-
quiet: ctx.quiet,
|
|
568
|
-
});
|
|
569
563
|
try {
|
|
570
|
-
return await fs.readFile(
|
|
564
|
+
return await fs.readFile(bundle.path, "utf-8");
|
|
571
565
|
} catch (error) {
|
|
572
566
|
console.error("Error reading bundle:", error);
|
|
573
567
|
throw new Error("Error reading bundle");
|
|
@@ -635,8 +629,8 @@ async function setupRoutes(
|
|
|
635
629
|
}
|
|
636
630
|
}
|
|
637
631
|
|
|
638
|
-
async function configureURL(
|
|
639
|
-
ctx: Context<
|
|
632
|
+
async function configureURL<B extends Bindings>(
|
|
633
|
+
ctx: Context<Worker<B>>,
|
|
640
634
|
api: CloudflareApi,
|
|
641
635
|
workerName: string,
|
|
642
636
|
url: boolean,
|
|
@@ -675,7 +669,7 @@ async function configureURL(
|
|
|
675
669
|
// Add a delay when the subdomain is first created.
|
|
676
670
|
// This is to prevent an issue where a negative cache-hit
|
|
677
671
|
// causes the subdomain to be unavailable for 30 seconds.
|
|
678
|
-
if (ctx.
|
|
672
|
+
if (ctx.phase === "create" || !ctx.output?.url) {
|
|
679
673
|
await new Promise((resolve) => setTimeout(resolve, 3000));
|
|
680
674
|
}
|
|
681
675
|
}
|
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
import * as fs from "fs/promises";
|
|
2
|
+
import type { Context } from "../context";
|
|
3
|
+
import { Resource } from "../resource";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Properties for wrangler.json configuration file
|
|
7
|
+
*/
|
|
8
|
+
export interface WranglerJsonProps {
|
|
9
|
+
/**
|
|
10
|
+
* The name of your worker
|
|
11
|
+
*/
|
|
12
|
+
name: string;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* The directory containing your worker entry point
|
|
16
|
+
* @default "src"
|
|
17
|
+
*/
|
|
18
|
+
main?: string;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* The entry point for your worker
|
|
22
|
+
* @default "index.ts" or "index.js"
|
|
23
|
+
*/
|
|
24
|
+
entrypoint?: string;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* The directory to store build artifacts
|
|
28
|
+
* @default "dist"
|
|
29
|
+
*/
|
|
30
|
+
outdir?: string;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* The directory to serve static assets from
|
|
34
|
+
*/
|
|
35
|
+
assets?: string;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Minify the worker script
|
|
39
|
+
* @default true
|
|
40
|
+
*/
|
|
41
|
+
minify?: boolean;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Node.js compatibility mode
|
|
45
|
+
* @default false
|
|
46
|
+
*/
|
|
47
|
+
node_compat?: boolean;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* First-party worker service bindings
|
|
51
|
+
*/
|
|
52
|
+
services?: Array<{
|
|
53
|
+
/**
|
|
54
|
+
* Binding name
|
|
55
|
+
*/
|
|
56
|
+
name: string;
|
|
57
|
+
/**
|
|
58
|
+
* Service environment
|
|
59
|
+
*/
|
|
60
|
+
environment?: string;
|
|
61
|
+
}>;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Worker environment variables
|
|
65
|
+
*/
|
|
66
|
+
vars?: Record<string, string>;
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* KV Namespace bindings
|
|
70
|
+
*/
|
|
71
|
+
kv_namespaces?: Array<{
|
|
72
|
+
/**
|
|
73
|
+
* Binding name
|
|
74
|
+
*/
|
|
75
|
+
binding: string;
|
|
76
|
+
/**
|
|
77
|
+
* KV namespace ID
|
|
78
|
+
*/
|
|
79
|
+
id: string;
|
|
80
|
+
/**
|
|
81
|
+
* Preview KV namespace ID
|
|
82
|
+
*/
|
|
83
|
+
preview_id?: string;
|
|
84
|
+
}>;
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* R2 bucket bindings
|
|
88
|
+
*/
|
|
89
|
+
r2_buckets?: Array<{
|
|
90
|
+
/**
|
|
91
|
+
* Binding name
|
|
92
|
+
*/
|
|
93
|
+
binding: string;
|
|
94
|
+
/**
|
|
95
|
+
* Bucket name
|
|
96
|
+
*/
|
|
97
|
+
bucket_name: string;
|
|
98
|
+
/**
|
|
99
|
+
* Preview bucket name
|
|
100
|
+
*/
|
|
101
|
+
preview_bucket_name?: string;
|
|
102
|
+
}>;
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* D1 database bindings
|
|
106
|
+
*/
|
|
107
|
+
d1_databases?: Array<{
|
|
108
|
+
/**
|
|
109
|
+
* Binding name
|
|
110
|
+
*/
|
|
111
|
+
binding: string;
|
|
112
|
+
/**
|
|
113
|
+
* Database name
|
|
114
|
+
*/
|
|
115
|
+
database_name: string;
|
|
116
|
+
/**
|
|
117
|
+
* Database ID
|
|
118
|
+
*/
|
|
119
|
+
database_id: string;
|
|
120
|
+
/**
|
|
121
|
+
* Preview database ID
|
|
122
|
+
*/
|
|
123
|
+
preview_database_id?: string;
|
|
124
|
+
}>;
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Durable Object bindings
|
|
128
|
+
*/
|
|
129
|
+
durable_objects?: {
|
|
130
|
+
/**
|
|
131
|
+
* Durable Object bindings
|
|
132
|
+
*/
|
|
133
|
+
bindings: Array<{
|
|
134
|
+
/**
|
|
135
|
+
* Binding name
|
|
136
|
+
*/
|
|
137
|
+
name: string;
|
|
138
|
+
/**
|
|
139
|
+
* Class name
|
|
140
|
+
*/
|
|
141
|
+
class_name: string;
|
|
142
|
+
/**
|
|
143
|
+
* Script name
|
|
144
|
+
*/
|
|
145
|
+
script_name?: string;
|
|
146
|
+
/**
|
|
147
|
+
* Environment name
|
|
148
|
+
*/
|
|
149
|
+
environment?: string;
|
|
150
|
+
}>;
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Queue bindings
|
|
155
|
+
*/
|
|
156
|
+
queues?: {
|
|
157
|
+
/**
|
|
158
|
+
* Producer bindings
|
|
159
|
+
*/
|
|
160
|
+
producers?: Array<{
|
|
161
|
+
/**
|
|
162
|
+
* Binding name
|
|
163
|
+
*/
|
|
164
|
+
binding: string;
|
|
165
|
+
/**
|
|
166
|
+
* Queue name
|
|
167
|
+
*/
|
|
168
|
+
queue: string;
|
|
169
|
+
}>;
|
|
170
|
+
/**
|
|
171
|
+
* Consumer configuration
|
|
172
|
+
*/
|
|
173
|
+
consumers?: Array<{
|
|
174
|
+
/**
|
|
175
|
+
* Queue name
|
|
176
|
+
*/
|
|
177
|
+
queue: string;
|
|
178
|
+
/**
|
|
179
|
+
* Maximum batch size
|
|
180
|
+
*/
|
|
181
|
+
max_batch_size?: number;
|
|
182
|
+
/**
|
|
183
|
+
* Maximum batch timeout
|
|
184
|
+
*/
|
|
185
|
+
max_batch_timeout?: number;
|
|
186
|
+
/**
|
|
187
|
+
* Maximum retries
|
|
188
|
+
*/
|
|
189
|
+
max_retries?: number;
|
|
190
|
+
/**
|
|
191
|
+
* Dead letter queue
|
|
192
|
+
*/
|
|
193
|
+
dead_letter_queue?: string;
|
|
194
|
+
}>;
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Analytics Engine bindings
|
|
199
|
+
*/
|
|
200
|
+
analytics_engine_datasets?: Array<{
|
|
201
|
+
/**
|
|
202
|
+
* Binding name
|
|
203
|
+
*/
|
|
204
|
+
binding: string;
|
|
205
|
+
/**
|
|
206
|
+
* Dataset name
|
|
207
|
+
*/
|
|
208
|
+
dataset?: string;
|
|
209
|
+
}>;
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Route configuration
|
|
213
|
+
*/
|
|
214
|
+
routes?: Array<string>;
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Triggers configuration
|
|
218
|
+
*/
|
|
219
|
+
triggers?: {
|
|
220
|
+
/**
|
|
221
|
+
* Cron triggers
|
|
222
|
+
*/
|
|
223
|
+
crons: Array<string>;
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Worker compatibility date
|
|
228
|
+
*/
|
|
229
|
+
compatibility_date?: string;
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Worker compatibility flags
|
|
233
|
+
*/
|
|
234
|
+
compatibility_flags?: Array<string>;
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Worker usage model
|
|
238
|
+
* "bundled" - Includes resources like CPU and memory. Better for consistent workloads.
|
|
239
|
+
* "unbound" - Pay only for what you use. Better for sporadic workloads.
|
|
240
|
+
*/
|
|
241
|
+
usage_model?: "bundled" | "unbound";
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Path to the wrangler.json file
|
|
245
|
+
* @internal
|
|
246
|
+
*/
|
|
247
|
+
path?: string;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Output returned after WranglerJson creation/update
|
|
252
|
+
*/
|
|
253
|
+
export interface WranglerJson
|
|
254
|
+
extends Resource<"cloudflare::WranglerJson">,
|
|
255
|
+
WranglerJsonProps {
|
|
256
|
+
/**
|
|
257
|
+
* Time at which the file was created
|
|
258
|
+
*/
|
|
259
|
+
createdAt: number;
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Time at which the file was last updated
|
|
263
|
+
*/
|
|
264
|
+
updatedAt: number;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Resource for managing wrangler.json configuration files
|
|
269
|
+
*/
|
|
270
|
+
export const WranglerJson = Resource(
|
|
271
|
+
"cloudflare::WranglerJson",
|
|
272
|
+
async function (
|
|
273
|
+
this: Context<WranglerJson>,
|
|
274
|
+
id: string,
|
|
275
|
+
props: WranglerJsonProps,
|
|
276
|
+
): Promise<WranglerJson> {
|
|
277
|
+
// Default path is wrangler.json in current directory
|
|
278
|
+
const filePath = props.path || "wrangler.json";
|
|
279
|
+
|
|
280
|
+
if (this.phase === "delete") {
|
|
281
|
+
try {
|
|
282
|
+
await fs.unlink(filePath);
|
|
283
|
+
} catch (error) {
|
|
284
|
+
// Ignore errors if file doesn't exist
|
|
285
|
+
if ((error as NodeJS.ErrnoException).code !== "ENOENT") {
|
|
286
|
+
throw error;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
return this.destroy();
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// Create or update the file
|
|
293
|
+
const config = {
|
|
294
|
+
...props,
|
|
295
|
+
// Remove internal path property
|
|
296
|
+
path: undefined,
|
|
297
|
+
};
|
|
298
|
+
|
|
299
|
+
// Write the file
|
|
300
|
+
await fs.writeFile(filePath, JSON.stringify(config, null, 2));
|
|
301
|
+
|
|
302
|
+
// Return the resource
|
|
303
|
+
return this({
|
|
304
|
+
...props,
|
|
305
|
+
createdAt: Date.now(),
|
|
306
|
+
updatedAt: Date.now(),
|
|
307
|
+
});
|
|
308
|
+
},
|
|
309
|
+
);
|