alchemy 0.16.9 → 0.17.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/astro-file.d.ts +1 -1
- package/lib/ai/astro-file.d.ts.map +1 -1
- package/lib/ai/astro-file.js +1 -1
- package/lib/ai/astro-file.js.map +1 -1
- package/lib/ai/client.js +2 -2
- package/lib/ai/client.js.map +1 -1
- package/lib/ai/css-file.d.ts +1 -1
- package/lib/ai/css-file.d.ts.map +1 -1
- package/lib/ai/css-file.js +1 -1
- package/lib/ai/css-file.js.map +1 -1
- package/lib/ai/data.d.ts +1 -1
- package/lib/ai/data.d.ts.map +1 -1
- package/lib/ai/data.js +1 -1
- package/lib/ai/data.js.map +1 -1
- package/lib/ai/html-file.d.ts +1 -1
- package/lib/ai/html-file.d.ts.map +1 -1
- package/lib/ai/html-file.js +1 -1
- package/lib/ai/html-file.js.map +1 -1
- package/lib/ai/json-file.d.ts +1 -1
- package/lib/ai/json-file.d.ts.map +1 -1
- package/lib/ai/json-file.js +1 -1
- package/lib/ai/json-file.js.map +1 -1
- package/lib/ai/typescript-file.d.ts +1 -1
- package/lib/ai/typescript-file.d.ts.map +1 -1
- package/lib/ai/typescript-file.js +1 -1
- package/lib/ai/typescript-file.js.map +1 -1
- package/lib/ai/vue-file.d.ts +1 -1
- package/lib/ai/vue-file.d.ts.map +1 -1
- package/lib/ai/vue-file.js +1 -1
- package/lib/ai/vue-file.js.map +1 -1
- package/lib/ai/yaml-file.d.ts +1 -1
- package/lib/ai/yaml-file.d.ts.map +1 -1
- package/lib/ai/yaml-file.js +2 -2
- package/lib/ai/yaml-file.js.map +1 -1
- package/lib/alchemy.d.ts +4 -0
- package/lib/alchemy.d.ts.map +1 -1
- package/lib/alchemy.js +14 -4
- package/lib/alchemy.js.map +1 -1
- package/lib/apply.d.ts +2 -0
- package/lib/apply.d.ts.map +1 -1
- package/lib/apply.js +17 -2
- package/lib/apply.js.map +1 -1
- package/lib/aws/bucket.d.ts +1 -1
- package/lib/aws/bucket.d.ts.map +1 -1
- package/lib/aws/bucket.js +1 -1
- package/lib/aws/bucket.js.map +1 -1
- package/lib/aws/function.d.ts +1 -1
- package/lib/aws/function.d.ts.map +1 -1
- package/lib/aws/function.js +2 -2
- package/lib/aws/function.js.map +1 -1
- package/lib/aws/oidc/oidc-provider.d.ts +1 -1
- package/lib/aws/oidc/oidc-provider.d.ts.map +1 -1
- package/lib/aws/oidc/oidc-provider.js +1 -1
- package/lib/aws/oidc/oidc-provider.js.map +1 -1
- package/lib/aws/policy-attachment.d.ts +1 -1
- package/lib/aws/policy-attachment.d.ts.map +1 -1
- package/lib/aws/policy-attachment.js +1 -1
- package/lib/aws/policy-attachment.js.map +1 -1
- package/lib/aws/policy.d.ts +1 -1
- package/lib/aws/policy.d.ts.map +1 -1
- package/lib/aws/policy.js +1 -1
- package/lib/aws/policy.js.map +1 -1
- package/lib/aws/queue.d.ts +1 -1
- package/lib/aws/queue.d.ts.map +1 -1
- package/lib/aws/queue.js +20 -25
- package/lib/aws/queue.js.map +1 -1
- package/lib/aws/role.d.ts +1 -1
- package/lib/aws/role.d.ts.map +1 -1
- package/lib/aws/role.js +1 -1
- package/lib/aws/role.js.map +1 -1
- package/lib/aws/ses.d.ts +1 -1
- package/lib/aws/ses.d.ts.map +1 -1
- package/lib/aws/ses.js +1 -1
- package/lib/aws/ses.js.map +1 -1
- package/lib/aws/table.d.ts +1 -1
- package/lib/aws/table.d.ts.map +1 -1
- package/lib/aws/table.js +1 -1
- 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 +1 -1
- package/lib/cloudflare/account-api-token.js.map +1 -1
- package/lib/cloudflare/ai-gateway.d.ts +4 -3
- package/lib/cloudflare/ai-gateway.d.ts.map +1 -1
- package/lib/cloudflare/ai-gateway.js +13 -1
- package/lib/cloudflare/ai-gateway.js.map +1 -1
- package/lib/cloudflare/analytics-engine.d.ts +21 -0
- package/lib/cloudflare/analytics-engine.d.ts.map +1 -0
- package/lib/cloudflare/analytics-engine.js +17 -0
- package/lib/cloudflare/analytics-engine.js.map +1 -0
- package/lib/cloudflare/api-error.js +1 -1
- package/lib/cloudflare/api-error.js.map +1 -1
- package/lib/cloudflare/assets.js +2 -2
- package/lib/cloudflare/assets.js.map +1 -1
- package/lib/cloudflare/auth.js +1 -1
- package/lib/cloudflare/auth.js.map +1 -1
- package/lib/cloudflare/bindings.d.ts +18 -11
- package/lib/cloudflare/bindings.d.ts.map +1 -1
- package/lib/cloudflare/bindings.js +6 -0
- package/lib/cloudflare/bindings.js.map +1 -1
- package/lib/cloudflare/bound.d.ts +12 -10
- package/lib/cloudflare/bound.d.ts.map +1 -1
- package/lib/cloudflare/bucket.d.ts +6 -4
- package/lib/cloudflare/bucket.d.ts.map +1 -1
- package/lib/cloudflare/bucket.js +22 -2
- package/lib/cloudflare/bucket.js.map +1 -1
- package/lib/cloudflare/bundle/bundle-worker.d.ts +1 -0
- package/lib/cloudflare/bundle/bundle-worker.d.ts.map +1 -1
- package/lib/cloudflare/bundle/bundle-worker.js +4 -2
- package/lib/cloudflare/bundle/bundle-worker.js.map +1 -1
- package/lib/cloudflare/bundle/nodejs-compat-mode.d.ts +1 -1
- package/lib/cloudflare/bundle/nodejs-compat-mode.d.ts.map +1 -1
- package/lib/cloudflare/bundle/nodejs-compat-mode.js +2 -2
- package/lib/cloudflare/bundle/nodejs-compat-mode.js.map +1 -1
- package/lib/cloudflare/bundle/nodejs-compat.js +1 -1
- package/lib/cloudflare/bundle/nodejs-compat.js.map +1 -1
- package/lib/cloudflare/custom-domain.js +1 -1
- package/lib/cloudflare/custom-domain.js.map +1 -1
- package/lib/cloudflare/d1-database.d.ts +4 -62
- package/lib/cloudflare/d1-database.d.ts.map +1 -1
- package/lib/cloudflare/d1-database.js +27 -11
- package/lib/cloudflare/d1-database.js.map +1 -1
- package/lib/cloudflare/dns-records.d.ts +1 -1
- package/lib/cloudflare/dns-records.d.ts.map +1 -1
- package/lib/cloudflare/dns-records.js +2 -2
- package/lib/cloudflare/dns-records.js.map +1 -1
- package/lib/cloudflare/event-source.d.ts +3 -3
- package/lib/cloudflare/event-source.d.ts.map +1 -1
- package/lib/cloudflare/hyperdrive.d.ts +4 -3
- package/lib/cloudflare/hyperdrive.d.ts.map +1 -1
- package/lib/cloudflare/hyperdrive.js +9 -1
- package/lib/cloudflare/hyperdrive.js.map +1 -1
- package/lib/cloudflare/kv-namespace.d.ts +9 -5
- package/lib/cloudflare/kv-namespace.d.ts.map +1 -1
- package/lib/cloudflare/kv-namespace.js +26 -6
- package/lib/cloudflare/kv-namespace.js.map +1 -1
- package/lib/cloudflare/permission-groups.d.ts +1 -1
- package/lib/cloudflare/permission-groups.d.ts.map +1 -1
- package/lib/cloudflare/permission-groups.js +1 -1
- package/lib/cloudflare/permission-groups.js.map +1 -1
- package/lib/cloudflare/pipeline.d.ts +5 -3
- package/lib/cloudflare/pipeline.d.ts.map +1 -1
- package/lib/cloudflare/pipeline.js +16 -2
- package/lib/cloudflare/pipeline.js.map +1 -1
- package/lib/cloudflare/queue-consumer.d.ts +3 -3
- package/lib/cloudflare/queue-consumer.d.ts.map +1 -1
- package/lib/cloudflare/queue-consumer.js +1 -1
- package/lib/cloudflare/queue-consumer.js.map +1 -1
- package/lib/cloudflare/queue.d.ts +34 -22
- package/lib/cloudflare/queue.d.ts.map +1 -1
- package/lib/cloudflare/queue.js +66 -4
- package/lib/cloudflare/queue.js.map +1 -1
- package/lib/cloudflare/route.d.ts +1 -1
- package/lib/cloudflare/route.d.ts.map +1 -1
- package/lib/cloudflare/route.js +1 -1
- package/lib/cloudflare/route.js.map +1 -1
- package/lib/cloudflare/types.js +1 -1
- package/lib/cloudflare/types.js.map +1 -1
- package/lib/cloudflare/vectorize-index.d.ts +6 -4
- package/lib/cloudflare/vectorize-index.d.ts.map +1 -1
- package/lib/cloudflare/vectorize-index.js +20 -3
- package/lib/cloudflare/vectorize-index.js.map +1 -1
- package/lib/cloudflare/vectorize-metadata-index.d.ts +4 -3
- package/lib/cloudflare/vectorize-metadata-index.d.ts.map +1 -1
- package/lib/cloudflare/vectorize-metadata-index.js +5 -2
- package/lib/cloudflare/vectorize-metadata-index.js.map +1 -1
- package/lib/cloudflare/website.d.ts.map +1 -1
- package/lib/cloudflare/website.js +3 -0
- package/lib/cloudflare/website.js.map +1 -1
- package/lib/cloudflare/worker-assets.d.ts +32 -0
- package/lib/cloudflare/worker-assets.d.ts.map +1 -0
- package/lib/cloudflare/worker-assets.js +143 -0
- package/lib/cloudflare/worker-assets.js.map +1 -0
- package/lib/cloudflare/worker-metadata.d.ts +31 -0
- package/lib/cloudflare/worker-metadata.d.ts.map +1 -1
- package/lib/cloudflare/worker-metadata.js +248 -0
- package/lib/cloudflare/worker-metadata.js.map +1 -1
- package/lib/cloudflare/worker-stub.d.ts +40 -0
- package/lib/cloudflare/worker-stub.d.ts.map +1 -0
- package/lib/cloudflare/worker-stub.js +86 -0
- package/lib/cloudflare/worker-stub.js.map +1 -0
- package/lib/cloudflare/worker.d.ts +57 -28
- package/lib/cloudflare/worker.d.ts.map +1 -1
- package/lib/cloudflare/worker.js +203 -472
- package/lib/cloudflare/worker.js.map +1 -1
- package/lib/cloudflare/wrangler.json.d.ts +29 -1
- package/lib/cloudflare/wrangler.json.d.ts.map +1 -1
- package/lib/cloudflare/wrangler.json.js +50 -2
- package/lib/cloudflare/wrangler.json.js.map +1 -1
- package/lib/cloudflare/zone.d.ts +1 -1
- package/lib/cloudflare/zone.d.ts.map +1 -1
- package/lib/cloudflare/zone.js +1 -1
- package/lib/cloudflare/zone.js.map +1 -1
- package/lib/destroy.d.ts +1 -4
- package/lib/destroy.d.ts.map +1 -1
- package/lib/destroy.js +10 -21
- package/lib/destroy.js.map +1 -1
- package/lib/dns/import-dns.d.ts +1 -1
- package/lib/dns/import-dns.d.ts.map +1 -1
- package/lib/dns/import-dns.js +1 -1
- package/lib/dns/import-dns.js.map +1 -1
- package/lib/encrypt.d.ts.map +1 -1
- package/lib/encrypt.js +2 -1
- package/lib/encrypt.js.map +1 -1
- package/lib/env.js +14 -8
- package/lib/env.js.map +1 -1
- package/lib/esbuild/bundle.d.ts +2 -2
- package/lib/esbuild/bundle.d.ts.map +1 -1
- package/lib/esbuild/bundle.js +3 -3
- package/lib/esbuild/bundle.js.map +1 -1
- package/lib/fs/copy-file.d.ts +1 -1
- package/lib/fs/copy-file.d.ts.map +1 -1
- package/lib/fs/copy-file.js +1 -1
- package/lib/fs/copy-file.js.map +1 -1
- package/lib/github/client.js +1 -1
- package/lib/github/client.js.map +1 -1
- package/lib/github/repository-environment.d.ts +1 -1
- package/lib/github/repository-environment.d.ts.map +1 -1
- package/lib/github/repository-environment.js +2 -2
- package/lib/github/repository-environment.js.map +1 -1
- package/lib/github/secret.d.ts +1 -1
- package/lib/github/secret.d.ts.map +1 -1
- package/lib/github/secret.js +1 -1
- package/lib/github/secret.js.map +1 -1
- package/lib/internal/docs/providers.d.ts +1 -1
- package/lib/internal/docs/providers.d.ts.map +1 -1
- package/lib/internal/docs/providers.js +3 -1
- package/lib/internal/docs/providers.js.map +1 -1
- package/lib/neon/api-error.js +2 -2
- package/lib/neon/api-error.js.map +1 -1
- package/lib/os/exec.js +1 -1
- package/lib/os/exec.js.map +1 -1
- package/lib/resource.d.ts +13 -11
- package/lib/resource.d.ts.map +1 -1
- package/lib/resource.js +10 -5
- package/lib/resource.js.map +1 -1
- package/lib/runtime/bind.d.ts +25 -0
- package/lib/runtime/bind.d.ts.map +1 -0
- package/lib/runtime/bind.js +76 -0
- package/lib/runtime/bind.js.map +1 -0
- package/lib/runtime/global.d.ts +8 -0
- package/lib/runtime/global.d.ts.map +1 -0
- package/lib/runtime/global.js +3 -0
- package/lib/runtime/global.js.map +1 -0
- package/lib/runtime/plugin.d.ts +35 -0
- package/lib/runtime/plugin.d.ts.map +1 -0
- package/lib/runtime/plugin.js +133 -0
- package/lib/runtime/plugin.js.map +1 -0
- package/lib/runtime/shims.d.ts +6 -0
- package/lib/runtime/shims.d.ts.map +1 -0
- package/lib/runtime/shims.js +27 -0
- package/lib/runtime/shims.js.map +1 -0
- package/lib/runtime/state.d.ts +5 -0
- package/lib/runtime/state.d.ts.map +1 -0
- package/lib/runtime/state.js +4 -0
- package/lib/runtime/state.js.map +1 -0
- package/lib/scope.d.ts +16 -2
- package/lib/scope.d.ts.map +1 -1
- package/lib/scope.js +56 -9
- package/lib/scope.js.map +1 -1
- package/lib/secret.d.ts +7 -2
- package/lib/secret.d.ts.map +1 -1
- package/lib/secret.js +19 -4
- package/lib/secret.js.map +1 -1
- package/lib/sentry/client-key.d.ts +1 -1
- package/lib/sentry/client-key.d.ts.map +1 -1
- package/lib/sentry/client-key.js +1 -1
- package/lib/sentry/client-key.js.map +1 -1
- package/lib/sentry/project.d.ts +1 -1
- package/lib/sentry/project.d.ts.map +1 -1
- package/lib/sentry/project.js +1 -1
- package/lib/sentry/project.js.map +1 -1
- package/lib/sentry/team.d.ts +1 -1
- package/lib/sentry/team.d.ts.map +1 -1
- package/lib/sentry/team.js +1 -1
- package/lib/sentry/team.js.map +1 -1
- package/lib/serde.d.ts +26 -1
- package/lib/serde.d.ts.map +1 -1
- package/lib/serde.js +53 -8
- package/lib/serde.js.map +1 -1
- package/lib/stripe/meter.d.ts +1 -1
- package/lib/stripe/meter.d.ts.map +1 -1
- package/lib/stripe/meter.js +1 -1
- package/lib/stripe/meter.js.map +1 -1
- package/lib/stripe/price.d.ts +1 -1
- package/lib/stripe/price.d.ts.map +1 -1
- package/lib/stripe/price.js +1 -1
- package/lib/stripe/price.js.map +1 -1
- package/lib/stripe/product.d.ts +1 -1
- package/lib/stripe/product.d.ts.map +1 -1
- package/lib/stripe/product.js +1 -1
- package/lib/stripe/product.js.map +1 -1
- package/lib/stripe/webhook.d.ts +1 -1
- package/lib/stripe/webhook.d.ts.map +1 -1
- package/lib/stripe/webhook.js +1 -1
- package/lib/stripe/webhook.js.map +1 -1
- package/lib/test/bun.js +1 -1
- package/lib/test/bun.js.map +1 -1
- package/lib/test/prune.js +1 -1
- package/lib/test/prune.js.map +1 -1
- package/lib/upstash/redis.d.ts +1 -1
- package/lib/upstash/redis.d.ts.map +1 -1
- package/lib/upstash/redis.js +1 -1
- package/lib/upstash/redis.js.map +1 -1
- package/lib/util/assert-never.d.ts +2 -0
- package/lib/util/assert-never.d.ts.map +1 -0
- package/lib/util/assert-never.js +4 -0
- package/lib/util/assert-never.js.map +1 -0
- package/lib/util/content-type.d.ts +1 -1
- package/lib/util/content-type.d.ts.map +1 -1
- package/lib/util/content-type.js +1 -2
- package/lib/util/content-type.js.map +1 -1
- package/lib/util/retry.d.ts.map +1 -1
- package/lib/util/retry.js +1 -0
- package/lib/util/retry.js.map +1 -1
- package/lib/vercel/project-domain.d.ts +1 -1
- package/lib/vercel/project-domain.d.ts.map +1 -1
- package/lib/vercel/project-domain.js +1 -1
- package/lib/vercel/project-domain.js.map +1 -1
- package/lib/vercel/project.js +1 -1
- package/lib/vercel/project.js.map +1 -1
- package/lib/web/shadcn-component.d.ts +1 -1
- package/lib/web/shadcn-component.d.ts.map +1 -1
- package/lib/web/shadcn-component.js +1 -1
- package/lib/web/shadcn-component.js.map +1 -1
- package/lib/web/shadcn.d.ts +1 -1
- package/lib/web/shadcn.d.ts.map +1 -1
- package/lib/web/shadcn.js +1 -1
- package/lib/web/shadcn.js.map +1 -1
- package/lib/web/vitepress/dependencies.d.ts +1 -1
- package/lib/web/vitepress/dependencies.d.ts.map +1 -1
- package/lib/web/vitepress/dependencies.js +1 -1
- package/lib/web/vitepress/dependencies.js.map +1 -1
- package/lib/web/vitepress/vitepress.js +1 -1
- package/lib/web/vitepress/vitepress.js.map +1 -1
- package/package.json +2 -1
- package/src/ai/astro-file.ts +1 -1
- package/src/ai/client.ts +2 -2
- package/src/ai/css-file.ts +1 -1
- package/src/ai/data.ts +1 -1
- package/src/ai/html-file.ts +1 -1
- package/src/ai/json-file.ts +1 -1
- package/src/ai/typescript-file.ts +1 -1
- package/src/ai/vue-file.ts +1 -1
- package/src/ai/yaml-file.ts +2 -2
- package/src/alchemy.ts +18 -4
- package/src/apply.ts +27 -2
- package/src/aws/bucket.ts +1 -1
- package/src/aws/function.ts +2 -2
- package/src/aws/oidc/oidc-provider.ts +1 -1
- package/src/aws/policy-attachment.ts +1 -1
- package/src/aws/policy.ts +1 -1
- package/src/aws/queue.ts +28 -29
- package/src/aws/role.ts +1 -1
- package/src/aws/ses.ts +1 -1
- package/src/aws/table.ts +1 -1
- package/src/cloudflare/account-api-token.ts +1 -1
- package/src/cloudflare/ai-gateway.ts +23 -4
- package/src/cloudflare/analytics-engine.ts +26 -0
- package/src/cloudflare/api-error.ts +1 -1
- package/src/cloudflare/assets.ts +2 -2
- package/src/cloudflare/auth.ts +1 -1
- package/src/cloudflare/bindings.ts +35 -18
- package/src/cloudflare/bound.ts +27 -23
- package/src/cloudflare/bucket.ts +52 -24
- package/src/cloudflare/bundle/bundle-worker.ts +5 -2
- package/src/cloudflare/bundle/nodejs-compat-mode.ts +3 -3
- package/src/cloudflare/bundle/nodejs-compat.ts +1 -1
- package/src/cloudflare/custom-domain.ts +1 -1
- package/src/cloudflare/d1-database.ts +40 -19
- package/src/cloudflare/dns-records.ts +2 -2
- package/src/cloudflare/event-source.ts +3 -3
- package/src/cloudflare/hyperdrive.ts +19 -4
- package/src/cloudflare/kv-namespace.ts +46 -15
- package/src/cloudflare/permission-groups.ts +1 -1
- package/src/cloudflare/pipeline.ts +29 -6
- package/src/cloudflare/queue-consumer.ts +3 -3
- package/src/cloudflare/queue.ts +124 -23
- package/src/cloudflare/route.ts +1 -1
- package/src/cloudflare/types.ts +1 -1
- package/src/cloudflare/vectorize-index.ts +36 -8
- package/src/cloudflare/vectorize-metadata-index.ts +10 -4
- package/src/cloudflare/website.ts +3 -0
- package/src/cloudflare/worker-assets.ts +237 -0
- package/src/cloudflare/worker-metadata.ts +287 -0
- package/src/cloudflare/worker-stub.ts +153 -0
- package/src/cloudflare/worker.ts +386 -586
- package/src/cloudflare/wrangler.json.ts +75 -2
- package/src/cloudflare/zone.ts +1 -1
- package/src/destroy.ts +12 -23
- package/src/dns/import-dns.ts +1 -1
- package/src/encrypt.ts +2 -2
- package/src/env.ts +15 -8
- package/src/esbuild/bundle.ts +4 -3
- package/src/fs/copy-file.ts +1 -1
- package/src/github/client.ts +1 -1
- package/src/github/repository-environment.ts +2 -2
- package/src/github/secret.ts +1 -1
- package/src/internal/docs/providers.ts +1 -1
- package/src/neon/api-error.ts +2 -2
- package/src/os/exec.ts +1 -1
- package/src/resource.ts +22 -31
- package/src/runtime/bind.ts +95 -0
- package/src/runtime/global.ts +10 -0
- package/src/runtime/plugin.ts +162 -0
- package/src/runtime/shims.js +34 -0
- package/src/runtime/state.ts +9 -0
- package/src/scope.ts +72 -11
- package/src/secret.ts +29 -4
- package/src/sentry/client-key.ts +1 -1
- package/src/sentry/project.ts +1 -1
- package/src/sentry/team.ts +1 -1
- package/src/serde.ts +126 -10
- package/src/stripe/meter.ts +1 -1
- package/src/stripe/price.ts +1 -1
- package/src/stripe/product.ts +1 -1
- package/src/stripe/webhook.ts +1 -1
- package/src/test/bun.ts +1 -1
- package/src/test/prune.ts +1 -1
- package/src/upstash/redis.ts +1 -1
- package/src/util/assert-never.ts +3 -0
- package/src/util/content-type.ts +2 -3
- package/src/util/retry.ts +1 -0
- package/src/vercel/project-domain.ts +1 -1
- package/src/vercel/project.ts +1 -1
- package/src/web/shadcn-component.ts +1 -1
- package/src/web/shadcn.ts +1 -1
- package/src/web/vitepress/dependencies.ts +1 -1
- package/src/web/vitepress/vitepress.ts +1 -1
package/lib/cloudflare/worker.js
CHANGED
|
@@ -1,124 +1,200 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { InnerResourceScope, Resource, ResourceKind } from "../resource.js";
|
|
3
|
+
import { getBindKey, tryGetBinding } from "../runtime/bind.js";
|
|
4
|
+
import { isRuntime } from "../runtime/global.js";
|
|
5
|
+
import { bootstrapPlugin } from "../runtime/plugin.js";
|
|
6
|
+
import { Scope } from "../scope.js";
|
|
7
|
+
import { Secret, secret } from "../secret.js";
|
|
8
|
+
import { serializeScope } from "../serde.js";
|
|
5
9
|
import { withExponentialBackoff } from "../util/retry.js";
|
|
6
10
|
import { slugify } from "../util/slugify.js";
|
|
7
11
|
import { CloudflareApiError, handleApiError } from "./api-error.js";
|
|
8
12
|
import { createCloudflareApi, } from "./api.js";
|
|
9
|
-
import {
|
|
13
|
+
import { Json } from "./bindings.js";
|
|
14
|
+
import { isBucket } from "./bucket.js";
|
|
10
15
|
import { bundleWorkerScript } from "./bundle/bundle-worker.js";
|
|
11
|
-
import {
|
|
16
|
+
import { isD1Database } from "./d1-database.js";
|
|
17
|
+
import { isQueueEventSource, } from "./event-source.js";
|
|
18
|
+
import { isKVNamespace } from "./kv-namespace.js";
|
|
19
|
+
import { isPipeline } from "./pipeline.js";
|
|
12
20
|
import { QueueConsumer, deleteQueueConsumer, listQueueConsumers, } from "./queue-consumer.js";
|
|
13
21
|
import { isQueue } from "./queue.js";
|
|
22
|
+
import { isVectorizeIndex } from "./vectorize-index.js";
|
|
23
|
+
import { uploadAssets } from "./worker-assets.js";
|
|
24
|
+
import { prepareWorkerMetadata, } from "./worker-metadata.js";
|
|
25
|
+
import { WorkerStub, isWorkerStub } from "./worker-stub.js";
|
|
14
26
|
import { upsertWorkflow } from "./workflow.js";
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
27
|
+
export function isWorker(resource) {
|
|
28
|
+
return resource[ResourceKind] === "cloudflare::Worker";
|
|
29
|
+
}
|
|
30
|
+
export function Worker(...args) {
|
|
31
|
+
const [id, meta, props] = args.length === 2 ? [args[0], undefined, args[1]] : args;
|
|
32
|
+
if (("fetch" in props && props.fetch) || ("queue" in props && props.queue)) {
|
|
33
|
+
const scope = Scope.current;
|
|
34
|
+
const workerName = props.name ?? id;
|
|
35
|
+
// we need to make sure the worker exists
|
|
36
|
+
const stub = WorkerStub(`${id}/stub`, {
|
|
37
|
+
name: workerName,
|
|
38
|
+
accountId: props.accountId,
|
|
39
|
+
apiKey: props.apiKey,
|
|
40
|
+
apiToken: props.apiToken,
|
|
41
|
+
baseUrl: props.baseUrl,
|
|
42
|
+
email: props.email,
|
|
43
|
+
});
|
|
44
|
+
async function collectResources(scope) {
|
|
45
|
+
if (!scope) {
|
|
46
|
+
return [];
|
|
47
|
+
}
|
|
48
|
+
return (await Promise.all(Array.from(scope.resources.values()).map(async (resource) => [
|
|
49
|
+
(await resource),
|
|
50
|
+
...(await collectResources(await resource[InnerResourceScope])),
|
|
51
|
+
]))).flat();
|
|
52
|
+
}
|
|
53
|
+
const deferred = scope.defer(async () => {
|
|
54
|
+
const autoBindings = {};
|
|
55
|
+
for (const resource of await collectResources(Scope.root)) {
|
|
56
|
+
if (isQueue(resource) ||
|
|
57
|
+
isWorkerStub(resource) ||
|
|
58
|
+
isWorker(resource) ||
|
|
59
|
+
isD1Database(resource) ||
|
|
60
|
+
isBucket(resource) ||
|
|
61
|
+
isPipeline(resource) ||
|
|
62
|
+
isVectorizeIndex(resource) ||
|
|
63
|
+
isKVNamespace(resource)) {
|
|
64
|
+
// TODO(sam): make this generic/pluggable
|
|
65
|
+
autoBindings[getBindKey(resource)] = resource;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
// TODO(sam): prune to only needed secrets
|
|
69
|
+
for (const secret of Secret.all()) {
|
|
70
|
+
autoBindings[secret.name] = secret;
|
|
71
|
+
}
|
|
72
|
+
const bindings = {
|
|
73
|
+
...props.bindings,
|
|
74
|
+
__ALCHEMY_WORKER_NAME__: workerName,
|
|
75
|
+
__ALCHEMY_SERIALIZED_SCOPE__: Json(await serializeScope(scope)),
|
|
76
|
+
ALCHEMY_STAGE: scope.stage,
|
|
77
|
+
ALCHEMY_PASSWORD: secret(scope.password),
|
|
78
|
+
// TODO(sam): prune un-needed bindings
|
|
79
|
+
...autoBindings,
|
|
80
|
+
};
|
|
81
|
+
return _Worker(id, {
|
|
82
|
+
...props,
|
|
83
|
+
url: true,
|
|
84
|
+
compatibilityFlags: [
|
|
85
|
+
"nodejs_compat",
|
|
86
|
+
...(props.compatibilityFlags ?? []),
|
|
87
|
+
],
|
|
88
|
+
entrypoint: meta.filename,
|
|
89
|
+
name: workerName,
|
|
90
|
+
// adopt because the stub guarnatees that the worker exists
|
|
91
|
+
adopt: true,
|
|
92
|
+
bindings,
|
|
93
|
+
bundle: {
|
|
94
|
+
...props.bundle,
|
|
95
|
+
plugins: [bootstrapPlugin],
|
|
96
|
+
external: [
|
|
97
|
+
// for alchemy
|
|
98
|
+
"libsodium*",
|
|
99
|
+
"@swc/*",
|
|
100
|
+
"esbuild",
|
|
101
|
+
// TODO(sam): this is for fetch, why is it a package?
|
|
102
|
+
"undici",
|
|
103
|
+
// TODO(sam): no idea where this came from, feels dangerous to externalize it
|
|
104
|
+
"ws",
|
|
105
|
+
"miniflare",
|
|
106
|
+
],
|
|
107
|
+
banner: {
|
|
108
|
+
js: "var __ALCHEMY_RUNTIME__ = true;",
|
|
109
|
+
},
|
|
110
|
+
inject: [
|
|
111
|
+
...(props.bundle?.inject ?? []),
|
|
112
|
+
path.resolve(import.meta.dirname, "..", "runtime", "shims.js"),
|
|
113
|
+
],
|
|
114
|
+
},
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
// defer construction of this worker until the app is about to finaloze
|
|
118
|
+
// this ensures that the Worker's dependencies are instantiated before we bundle
|
|
119
|
+
// it is then safe to bundle and import the Worker to detect which resources need to be auto-bound
|
|
120
|
+
const promise = Promise.all([deferred, stub]).then(([worker]) => worker);
|
|
121
|
+
if (isRuntime) {
|
|
122
|
+
if (props.fetch) {
|
|
123
|
+
promise.fetch = async (request, env, ctx) => {
|
|
124
|
+
try {
|
|
125
|
+
return await props.fetch(request, env, ctx);
|
|
126
|
+
}
|
|
127
|
+
catch (err) {
|
|
128
|
+
return new Response(err.message + err.stack, {
|
|
129
|
+
status: 500,
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
if (props.queue) {
|
|
135
|
+
promise.queue = async (batch, env, ctx) => {
|
|
136
|
+
return await props.queue(batch, env, ctx);
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
promise.fetch = async (request, init) => {
|
|
142
|
+
const worker = await promise;
|
|
143
|
+
if (!worker.url) {
|
|
144
|
+
throw new Error("Worker URL is not available in runtime");
|
|
145
|
+
}
|
|
146
|
+
if (request instanceof Request) {
|
|
147
|
+
const origin = new URL(worker.url);
|
|
148
|
+
const incoming = request.url.startsWith("/")
|
|
149
|
+
? new URL(`${worker.url}${request.url}`)
|
|
150
|
+
: new URL(request.url);
|
|
151
|
+
console.log(incoming);
|
|
152
|
+
const proxyURL = new URL(`${incoming.pathname}${incoming.search}${incoming.hash}`, origin);
|
|
153
|
+
const headers = new Headers(request.headers);
|
|
154
|
+
headers.set("host", origin.host);
|
|
155
|
+
try {
|
|
156
|
+
return await fetch(new Request(proxyURL, {
|
|
157
|
+
method: request.method,
|
|
158
|
+
body: request.body,
|
|
159
|
+
headers,
|
|
160
|
+
// TODO(sam): do we need this? GPT added it ...
|
|
161
|
+
// redirect: "manual",
|
|
162
|
+
}));
|
|
163
|
+
}
|
|
164
|
+
catch (err) {
|
|
165
|
+
return new Response(err.message ?? "proxy error", { status: 500 });
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
if (typeof request === "string" && request.startsWith("/")) {
|
|
170
|
+
request = new URL(`${worker.url}${request}`);
|
|
171
|
+
}
|
|
172
|
+
return await fetch(request, init);
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
return promise;
|
|
177
|
+
}
|
|
178
|
+
return _Worker(id, props).then(async (worker) => {
|
|
179
|
+
const binding = await tryGetBinding(worker);
|
|
180
|
+
if (binding) {
|
|
181
|
+
worker.fetch = (request) => binding.fetch(request);
|
|
182
|
+
worker.connect = (address, options) => binding.connect(address, options);
|
|
183
|
+
}
|
|
184
|
+
return worker;
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
export const _Worker = Resource("cloudflare::Worker", {
|
|
108
188
|
alwaysUpdate: true,
|
|
109
189
|
}, async function (id, props) {
|
|
110
|
-
// Validate input - we need either script, entryPoint, or bundle
|
|
111
|
-
if (!props.script && !props.entrypoint) {
|
|
112
|
-
throw new Error("One of script or entryPoint must be provided");
|
|
113
|
-
}
|
|
114
190
|
// Create Cloudflare API client with automatic account discovery
|
|
115
191
|
const api = await createCloudflareApi(props);
|
|
116
192
|
// Use the provided name
|
|
117
193
|
const workerName = props.name ?? id;
|
|
118
|
-
const oldBindings = await this.get("bindings");
|
|
119
194
|
const compatibilityDate = props.compatibilityDate ?? "2025-04-20";
|
|
120
195
|
const compatibilityFlags = props.compatibilityFlags ?? [];
|
|
121
196
|
const uploadWorkerScript = async (props) => {
|
|
197
|
+
const oldBindings = await this.get("bindings");
|
|
122
198
|
// Get the script content - either from props.script, or by bundling
|
|
123
199
|
const scriptContent = props.script ??
|
|
124
200
|
(await bundleWorkerScript({
|
|
@@ -158,6 +234,8 @@ export const Worker = Resource("cloudflare::Worker", {
|
|
|
158
234
|
workerName,
|
|
159
235
|
}, assetUploadResult);
|
|
160
236
|
await putWorker(api, workerName, scriptContent, scriptMetadata);
|
|
237
|
+
// TODO: it is less than ideal that this can fail, resulting in state problem
|
|
238
|
+
await this.set("bindings", props.bindings);
|
|
161
239
|
for (const workflow of workflowsBindings) {
|
|
162
240
|
await upsertWorkflow(api, {
|
|
163
241
|
workflowName: workflow.workflowName,
|
|
@@ -181,8 +259,6 @@ export const Worker = Resource("cloudflare::Worker", {
|
|
|
181
259
|
}
|
|
182
260
|
throw new Error(`Unsupported event source type: ${eventSource}`);
|
|
183
261
|
}) ?? []);
|
|
184
|
-
// TODO: it is less than ideal that this can fail, resulting in state problem
|
|
185
|
-
await this.set("bindings", props.bindings);
|
|
186
262
|
// Handle worker URL if requested
|
|
187
263
|
const workerUrl = await configureURL(this, api, workerName, props.url ?? false);
|
|
188
264
|
// Get current timestamp
|
|
@@ -194,16 +270,19 @@ export const Worker = Resource("cloudflare::Worker", {
|
|
|
194
270
|
await handleApiError(res, "updating cron triggers", "worker", workerName);
|
|
195
271
|
}
|
|
196
272
|
}
|
|
197
|
-
return { scriptMetadata, workerUrl, now };
|
|
273
|
+
return { scriptContent, scriptMetadata, workerUrl, now };
|
|
198
274
|
};
|
|
199
275
|
if (this.phase === "delete") {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
276
|
+
// Delete any queue consumers attached to this worker first
|
|
277
|
+
await deleteQueueConsumers(this, api, workerName);
|
|
278
|
+
await uploadWorkerScript({
|
|
279
|
+
...props,
|
|
280
|
+
entrypoint: undefined,
|
|
281
|
+
script: props.format === "cjs"
|
|
282
|
+
? "addEventListener('fetch', event => { event.respondWith(new Response('hello world')); });"
|
|
283
|
+
: "export default { fetch(request) { return new Response('hello world'); } }",
|
|
284
|
+
bindings: {},
|
|
285
|
+
});
|
|
207
286
|
await withExponentialBackoff(() => deleteWorker(this, api, {
|
|
208
287
|
...props,
|
|
209
288
|
workerName,
|
|
@@ -213,6 +292,10 @@ export const Worker = Resource("cloudflare::Worker", {
|
|
|
213
292
|
err.status === 503, 10, 100);
|
|
214
293
|
return this.destroy();
|
|
215
294
|
}
|
|
295
|
+
// Validate input - we need either script, entryPoint, or bundle
|
|
296
|
+
if (!props.script && !props.entrypoint) {
|
|
297
|
+
throw new Error("One of script or entrypoint must be provided");
|
|
298
|
+
}
|
|
216
299
|
if (this.phase === "create") {
|
|
217
300
|
if (!props.adopt) {
|
|
218
301
|
await assertWorkerDoesNotExist(this, api, workerName);
|
|
@@ -244,10 +327,8 @@ export const Worker = Resource("cloudflare::Worker", {
|
|
|
244
327
|
Env: undefined,
|
|
245
328
|
});
|
|
246
329
|
});
|
|
247
|
-
async function deleteWorker(ctx, api, props) {
|
|
330
|
+
export async function deleteWorker(ctx, api, props) {
|
|
248
331
|
const workerName = props.workerName;
|
|
249
|
-
// Delete any queue consumers attached to this worker first
|
|
250
|
-
await deleteQueueConsumers(ctx, api, workerName);
|
|
251
332
|
// Delete worker
|
|
252
333
|
const deleteResponse = await api.delete(`/accounts/${api.accountId}/workers/scripts/${workerName}`);
|
|
253
334
|
// Check for success (2xx status code)
|
|
@@ -268,7 +349,7 @@ async function deleteWorker(ctx, api, props) {
|
|
|
268
349
|
// Return minimal output for deleted state
|
|
269
350
|
return;
|
|
270
351
|
}
|
|
271
|
-
async function putWorker(api, workerName, scriptContent, scriptMetadata) {
|
|
352
|
+
export async function putWorker(api, workerName, scriptContent, scriptMetadata) {
|
|
272
353
|
return withExponentialBackoff(async () => {
|
|
273
354
|
const scriptName = scriptMetadata.main_module ?? scriptMetadata.body_part;
|
|
274
355
|
// Create FormData for the upload
|
|
@@ -296,254 +377,7 @@ async function putWorker(api, workerName, scriptContent, scriptMetadata) {
|
|
|
296
377
|
return formData;
|
|
297
378
|
}, (err) => err.status === 404 || err.status === 500 || err.status === 503, 10, 100);
|
|
298
379
|
}
|
|
299
|
-
|
|
300
|
-
* Creates asset configuration object from provided config or defaults
|
|
301
|
-
*/
|
|
302
|
-
function createAssetConfig(config) {
|
|
303
|
-
const assetConfig = {
|
|
304
|
-
html_handling: "auto-trailing-slash",
|
|
305
|
-
};
|
|
306
|
-
if (config) {
|
|
307
|
-
if (config._headers !== undefined) {
|
|
308
|
-
assetConfig._headers = config._headers;
|
|
309
|
-
}
|
|
310
|
-
if (config._redirects !== undefined) {
|
|
311
|
-
assetConfig._redirects = config._redirects;
|
|
312
|
-
}
|
|
313
|
-
if (config.html_handling !== undefined) {
|
|
314
|
-
assetConfig.html_handling = config.html_handling;
|
|
315
|
-
}
|
|
316
|
-
if (config.not_found_handling !== undefined) {
|
|
317
|
-
assetConfig.not_found_handling = config.not_found_handling;
|
|
318
|
-
}
|
|
319
|
-
if (config.run_worker_first !== undefined) {
|
|
320
|
-
assetConfig.run_worker_first = config.run_worker_first;
|
|
321
|
-
}
|
|
322
|
-
if (config.serve_directly !== undefined) {
|
|
323
|
-
assetConfig.serve_directly = config.serve_directly;
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
return assetConfig;
|
|
327
|
-
}
|
|
328
|
-
async function prepareWorkerMetadata(ctx, oldBindings, props, assetUploadResult) {
|
|
329
|
-
// Prepare metadata with bindings
|
|
330
|
-
const meta = {
|
|
331
|
-
compatibility_date: props.compatibilityDate,
|
|
332
|
-
compatibility_flags: props.compatibilityFlags,
|
|
333
|
-
bindings: [],
|
|
334
|
-
observability: {
|
|
335
|
-
enabled: props.observability?.enabled !== false,
|
|
336
|
-
},
|
|
337
|
-
// TODO(sam): base64 encode instead? 0 collision risk vs readability.
|
|
338
|
-
tags: [`alchemy:id:${slugify(ctx.fqn)}`],
|
|
339
|
-
migrations: {
|
|
340
|
-
new_classes: props.migrations?.new_classes ?? [],
|
|
341
|
-
deleted_classes: props.migrations?.deleted_classes ?? [],
|
|
342
|
-
renamed_classes: props.migrations?.renamed_classes ?? [],
|
|
343
|
-
transferred_classes: props.migrations?.transferred_classes ?? [],
|
|
344
|
-
new_sqlite_classes: props.migrations?.new_sqlite_classes ?? [],
|
|
345
|
-
},
|
|
346
|
-
};
|
|
347
|
-
// If we have asset upload results, add them to the metadata
|
|
348
|
-
if (assetUploadResult) {
|
|
349
|
-
meta.assets = {
|
|
350
|
-
jwt: assetUploadResult.completionToken,
|
|
351
|
-
};
|
|
352
|
-
// Initialize config from assetUploadResult if it exists
|
|
353
|
-
if (assetUploadResult.assetConfig) {
|
|
354
|
-
meta.assets.config = {
|
|
355
|
-
...assetUploadResult.assetConfig,
|
|
356
|
-
};
|
|
357
|
-
}
|
|
358
|
-
// If there's no config from assetUploadResult but we have props.assets,
|
|
359
|
-
// we need to create the config ourselves (this handles the case when no assets were uploaded)
|
|
360
|
-
if (!meta.assets.config && props.assets) {
|
|
361
|
-
meta.assets.config = createAssetConfig(props.assets);
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
const bindings = (props.bindings ?? {});
|
|
365
|
-
// Convert bindings to the format expected by the API
|
|
366
|
-
for (const [bindingName, binding] of Object.entries(bindings)) {
|
|
367
|
-
// Create a copy of the binding to avoid modifying the original
|
|
368
|
-
if (typeof binding === "string") {
|
|
369
|
-
meta.bindings.push({
|
|
370
|
-
type: "plain_text",
|
|
371
|
-
name: bindingName,
|
|
372
|
-
text: binding,
|
|
373
|
-
});
|
|
374
|
-
}
|
|
375
|
-
else if (binding === Self) {
|
|
376
|
-
meta.bindings.push({
|
|
377
|
-
type: "service",
|
|
378
|
-
name: bindingName,
|
|
379
|
-
service: props.workerName,
|
|
380
|
-
});
|
|
381
|
-
}
|
|
382
|
-
else if (binding.type === "d1") {
|
|
383
|
-
meta.bindings.push({
|
|
384
|
-
type: "d1",
|
|
385
|
-
name: bindingName,
|
|
386
|
-
id: binding.id,
|
|
387
|
-
});
|
|
388
|
-
}
|
|
389
|
-
else if (binding.type === "kv_namespace") {
|
|
390
|
-
meta.bindings.push({
|
|
391
|
-
type: "kv_namespace",
|
|
392
|
-
name: bindingName,
|
|
393
|
-
namespace_id: "namespaceId" in binding ? binding.namespaceId : binding.id,
|
|
394
|
-
});
|
|
395
|
-
}
|
|
396
|
-
else if (binding.type === "service") {
|
|
397
|
-
meta.bindings.push({
|
|
398
|
-
type: "service",
|
|
399
|
-
name: bindingName,
|
|
400
|
-
service: binding.name,
|
|
401
|
-
});
|
|
402
|
-
}
|
|
403
|
-
else if (binding.type === "durable_object_namespace") {
|
|
404
|
-
meta.bindings.push({
|
|
405
|
-
type: "durable_object_namespace",
|
|
406
|
-
name: bindingName,
|
|
407
|
-
class_name: binding.className,
|
|
408
|
-
script_name: binding.scriptName,
|
|
409
|
-
environment: binding.environment,
|
|
410
|
-
namespace_id: binding.namespaceId,
|
|
411
|
-
});
|
|
412
|
-
configureClassMigration(binding, binding.id, binding.className);
|
|
413
|
-
}
|
|
414
|
-
else if (binding.type === "r2_bucket") {
|
|
415
|
-
meta.bindings.push({
|
|
416
|
-
type: "r2_bucket",
|
|
417
|
-
name: bindingName,
|
|
418
|
-
bucket_name: binding.name,
|
|
419
|
-
});
|
|
420
|
-
}
|
|
421
|
-
else if (binding.type === "assets") {
|
|
422
|
-
meta.bindings.push({
|
|
423
|
-
type: "assets",
|
|
424
|
-
name: bindingName,
|
|
425
|
-
});
|
|
426
|
-
}
|
|
427
|
-
else if (binding.type === "secret") {
|
|
428
|
-
meta.bindings.push({
|
|
429
|
-
type: "secret_text",
|
|
430
|
-
name: bindingName,
|
|
431
|
-
text: binding.unencrypted,
|
|
432
|
-
});
|
|
433
|
-
}
|
|
434
|
-
else if (binding.type === "workflow") {
|
|
435
|
-
meta.bindings.push({
|
|
436
|
-
type: "workflow",
|
|
437
|
-
name: bindingName,
|
|
438
|
-
workflow_name: binding.workflowName,
|
|
439
|
-
class_name: binding.className,
|
|
440
|
-
// this should be set if the Workflow is in another script ...
|
|
441
|
-
// script_name: ??,
|
|
442
|
-
});
|
|
443
|
-
// it's unclear whether this is needed, but it works both ways
|
|
444
|
-
// configureClassMigration(binding, binding.id, binding.className);
|
|
445
|
-
}
|
|
446
|
-
else if (binding.type === "queue") {
|
|
447
|
-
meta.bindings.push({
|
|
448
|
-
type: "queue",
|
|
449
|
-
name: bindingName,
|
|
450
|
-
queue_name: binding.name,
|
|
451
|
-
});
|
|
452
|
-
}
|
|
453
|
-
else if (binding.type === "pipeline") {
|
|
454
|
-
meta.bindings.push({
|
|
455
|
-
type: "pipelines",
|
|
456
|
-
name: bindingName,
|
|
457
|
-
pipeline: binding.name,
|
|
458
|
-
});
|
|
459
|
-
}
|
|
460
|
-
else if (binding.type === "vectorize") {
|
|
461
|
-
meta.bindings.push({
|
|
462
|
-
type: "vectorize",
|
|
463
|
-
name: bindingName,
|
|
464
|
-
index_name: binding.name,
|
|
465
|
-
});
|
|
466
|
-
}
|
|
467
|
-
else if (binding.type === "ai_gateway") {
|
|
468
|
-
// AI Gateway binding - just needs the name property
|
|
469
|
-
meta.bindings.push({
|
|
470
|
-
type: "ai",
|
|
471
|
-
name: bindingName,
|
|
472
|
-
});
|
|
473
|
-
}
|
|
474
|
-
else if (binding.type === "hyperdrive") {
|
|
475
|
-
// Hyperdrive binding
|
|
476
|
-
meta.bindings.push({
|
|
477
|
-
type: "hyperdrive",
|
|
478
|
-
name: bindingName,
|
|
479
|
-
id: binding.hyperdriveId,
|
|
480
|
-
});
|
|
481
|
-
}
|
|
482
|
-
else if (binding.type === "browser") {
|
|
483
|
-
meta.bindings.push({
|
|
484
|
-
type: "browser",
|
|
485
|
-
name: bindingName,
|
|
486
|
-
});
|
|
487
|
-
}
|
|
488
|
-
else if (binding.type === "ai") {
|
|
489
|
-
meta.bindings.push({
|
|
490
|
-
type: "ai",
|
|
491
|
-
name: bindingName,
|
|
492
|
-
});
|
|
493
|
-
}
|
|
494
|
-
else {
|
|
495
|
-
// @ts-expect-error - we should never reach here
|
|
496
|
-
throw new Error(`Unsupported binding type: ${binding.type}`);
|
|
497
|
-
}
|
|
498
|
-
}
|
|
499
|
-
function configureClassMigration(binding, stableId, className) {
|
|
500
|
-
const oldBinding = Object.values(oldBindings ?? {})
|
|
501
|
-
?.filter((b) => typeof b === "object" &&
|
|
502
|
-
(b.type === "durable_object_namespace" || b.type === "workflow"))
|
|
503
|
-
?.find((b) => b.id === stableId);
|
|
504
|
-
if (!oldBinding) {
|
|
505
|
-
if (binding.type === "durable_object_namespace" && binding.sqlite) {
|
|
506
|
-
meta.migrations.new_sqlite_classes.push(className);
|
|
507
|
-
}
|
|
508
|
-
else {
|
|
509
|
-
meta.migrations.new_classes.push(className);
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
|
-
else if (oldBinding.className !== className) {
|
|
513
|
-
meta.migrations.renamed_classes.push({
|
|
514
|
-
from: oldBinding.className,
|
|
515
|
-
to: className,
|
|
516
|
-
});
|
|
517
|
-
}
|
|
518
|
-
}
|
|
519
|
-
// Convert env variables to plain_text bindings
|
|
520
|
-
// TODO(sam): remove Worker.env in favor of always bindings
|
|
521
|
-
if (props.env) {
|
|
522
|
-
for (const [key, value] of Object.entries(props.env)) {
|
|
523
|
-
meta.bindings.push({
|
|
524
|
-
name: key,
|
|
525
|
-
type: "plain_text",
|
|
526
|
-
text: value,
|
|
527
|
-
});
|
|
528
|
-
}
|
|
529
|
-
}
|
|
530
|
-
// Determine if we're using ESM or service worker format
|
|
531
|
-
const isEsModule = props.format !== "cjs"; // Default to ESM unless CJS is specified
|
|
532
|
-
const scriptName = isEsModule ? "worker.js" : "script";
|
|
533
|
-
if (isEsModule) {
|
|
534
|
-
// For ES modules format
|
|
535
|
-
meta.main_module = scriptName;
|
|
536
|
-
}
|
|
537
|
-
else {
|
|
538
|
-
// For service worker format (CJS)
|
|
539
|
-
meta.body_part = scriptName;
|
|
540
|
-
}
|
|
541
|
-
if (process.env.DEBUG) {
|
|
542
|
-
console.log(meta);
|
|
543
|
-
}
|
|
544
|
-
return meta;
|
|
545
|
-
}
|
|
546
|
-
async function assertWorkerDoesNotExist(ctx, api, workerName) {
|
|
380
|
+
export async function assertWorkerDoesNotExist(ctx, api, workerName) {
|
|
547
381
|
const response = await api.get(`/accounts/${api.accountId}/workers/scripts/${workerName}`);
|
|
548
382
|
if (response.status === 404) {
|
|
549
383
|
return true;
|
|
@@ -560,7 +394,7 @@ async function assertWorkerDoesNotExist(ctx, api, workerName) {
|
|
|
560
394
|
}
|
|
561
395
|
throw new Error(`Error checking if worker exists: ${response.status} ${response.statusText} ${await response.text()}`);
|
|
562
396
|
}
|
|
563
|
-
async function configureURL(ctx, api, workerName, url) {
|
|
397
|
+
export async function configureURL(ctx, api, workerName, url) {
|
|
564
398
|
let workerUrl;
|
|
565
399
|
if (url) {
|
|
566
400
|
// Enable the workers.dev subdomain for this worker
|
|
@@ -595,7 +429,7 @@ async function configureURL(ctx, api, workerName, url) {
|
|
|
595
429
|
}
|
|
596
430
|
return workerUrl;
|
|
597
431
|
}
|
|
598
|
-
async function getWorkerScriptMetadata(api, workerName) {
|
|
432
|
+
export async function getWorkerScriptMetadata(api, workerName) {
|
|
599
433
|
const response = await api.get(`/accounts/${api.accountId}/workers/services/${workerName}`);
|
|
600
434
|
if (response.status === 404) {
|
|
601
435
|
return undefined;
|
|
@@ -605,7 +439,7 @@ async function getWorkerScriptMetadata(api, workerName) {
|
|
|
605
439
|
}
|
|
606
440
|
return (await response.json()).result;
|
|
607
441
|
}
|
|
608
|
-
async function
|
|
442
|
+
export async function _getWorkerBindings(api, workerName, environment = "production") {
|
|
609
443
|
const response = await api.get(`/accounts/${api.accountId}/workers/services/${workerName}/environments/${environment}/bindings`, {
|
|
610
444
|
headers: {
|
|
611
445
|
Authorization: `Bearer ${process.env.CLOUDFLARE_API_TOKEN}`,
|
|
@@ -621,109 +455,6 @@ async function getWorkerBindings(api, workerName, environment = "production") {
|
|
|
621
455
|
const data = await response.json();
|
|
622
456
|
return data.result;
|
|
623
457
|
}
|
|
624
|
-
/**
|
|
625
|
-
* Uploads assets to Cloudflare and returns a completion token
|
|
626
|
-
*
|
|
627
|
-
* @param api CloudflareApi instance
|
|
628
|
-
* @param workerName Name of the worker
|
|
629
|
-
* @param assets Assets resource containing files to upload
|
|
630
|
-
* @param assetConfig Configuration for the assets
|
|
631
|
-
* @returns Completion token for the assets upload
|
|
632
|
-
*/
|
|
633
|
-
async function uploadAssets(api, workerName, assets, assetConfig) {
|
|
634
|
-
// Process the assets configuration once at the beginning
|
|
635
|
-
const processedConfig = createAssetConfig(assetConfig);
|
|
636
|
-
// Generate the file manifest
|
|
637
|
-
const fileMetadata = {};
|
|
638
|
-
// Process each file in the assets
|
|
639
|
-
for (const file of assets.files) {
|
|
640
|
-
const { hash, size } = await calculateFileMetadata(file.filePath);
|
|
641
|
-
// Use the relative path as the key, ensuring it starts with a slash
|
|
642
|
-
const key = file.path.startsWith("/") ? file.path : `/${file.path}`;
|
|
643
|
-
fileMetadata[key] = { hash, size };
|
|
644
|
-
}
|
|
645
|
-
// Start the upload session
|
|
646
|
-
const uploadSessionUrl = `/accounts/${api.accountId}/workers/scripts/${workerName}/assets-upload-session`;
|
|
647
|
-
const uploadSessionResponse = await api.post(uploadSessionUrl, JSON.stringify({ manifest: fileMetadata }), {
|
|
648
|
-
headers: { "Content-Type": "application/json" },
|
|
649
|
-
});
|
|
650
|
-
if (!uploadSessionResponse.ok) {
|
|
651
|
-
throw new Error(`Failed to start assets upload session: ${uploadSessionResponse.status} ${uploadSessionResponse.statusText}`);
|
|
652
|
-
}
|
|
653
|
-
const sessionData = (await uploadSessionResponse.json());
|
|
654
|
-
// If there are no buckets, assets are already uploaded or empty
|
|
655
|
-
if (!sessionData.result.buckets || sessionData.result.buckets.length === 0) {
|
|
656
|
-
return {
|
|
657
|
-
completionToken: sessionData.result.jwt,
|
|
658
|
-
assetConfig: processedConfig,
|
|
659
|
-
};
|
|
660
|
-
}
|
|
661
|
-
// Upload the files in batches as specified by the API
|
|
662
|
-
let completionToken = sessionData.result.jwt;
|
|
663
|
-
const buckets = sessionData.result.buckets;
|
|
664
|
-
// Process each bucket of files
|
|
665
|
-
for (const bucket of buckets) {
|
|
666
|
-
const formData = new FormData();
|
|
667
|
-
let totalBytes = 0;
|
|
668
|
-
// Add each file in the bucket to the form
|
|
669
|
-
for (const fileHash of bucket) {
|
|
670
|
-
// Find the file with this hash
|
|
671
|
-
const file = assets.files.find((f) => {
|
|
672
|
-
const filePath = f.path.startsWith("/") ? f.path : `/${f.path}`;
|
|
673
|
-
return fileMetadata[filePath]?.hash === fileHash;
|
|
674
|
-
});
|
|
675
|
-
if (!file) {
|
|
676
|
-
throw new Error(`Could not find file with hash ${fileHash}`);
|
|
677
|
-
}
|
|
678
|
-
// Read the file content
|
|
679
|
-
const fileContent = await fs.readFile(file.filePath);
|
|
680
|
-
// Convert to base64 as required by the API when using base64=true
|
|
681
|
-
const base64Content = fileContent.toString("base64");
|
|
682
|
-
// Add the file to the form with the hash as the key and set the correct content type
|
|
683
|
-
const blob = new Blob([base64Content], {
|
|
684
|
-
type: getContentType(file.filePath),
|
|
685
|
-
});
|
|
686
|
-
totalBytes += blob.size;
|
|
687
|
-
formData.append(fileHash, blob, fileHash);
|
|
688
|
-
}
|
|
689
|
-
// Upload this batch of files
|
|
690
|
-
const uploadResponse = await api.post(`/accounts/${api.accountId}/workers/assets/upload?base64=true`, formData, {
|
|
691
|
-
headers: {
|
|
692
|
-
Authorization: `Bearer ${completionToken}`,
|
|
693
|
-
"Content-Type": "multipart/form-data",
|
|
694
|
-
},
|
|
695
|
-
});
|
|
696
|
-
if (!uploadResponse.ok) {
|
|
697
|
-
throw new Error(`Failed to upload asset files: ${uploadResponse.status} ${uploadResponse.statusText}`);
|
|
698
|
-
}
|
|
699
|
-
const uploadData = (await uploadResponse.json());
|
|
700
|
-
// Update the completion token for the next batch
|
|
701
|
-
if (uploadData.result.jwt) {
|
|
702
|
-
completionToken = uploadData.result.jwt;
|
|
703
|
-
}
|
|
704
|
-
}
|
|
705
|
-
// Return the final completion token with asset configuration
|
|
706
|
-
return {
|
|
707
|
-
completionToken,
|
|
708
|
-
assetConfig: processedConfig,
|
|
709
|
-
};
|
|
710
|
-
}
|
|
711
|
-
/**
|
|
712
|
-
* Calculate the SHA-256 hash and size of a file
|
|
713
|
-
*
|
|
714
|
-
* @param filePath Path to the file
|
|
715
|
-
* @returns Hash (first 32 chars of SHA-256) and size of the file
|
|
716
|
-
*/
|
|
717
|
-
async function calculateFileMetadata(filePath) {
|
|
718
|
-
const hash = crypto.createHash("sha256");
|
|
719
|
-
const fileContent = await fs.readFile(filePath);
|
|
720
|
-
hash.update(fileContent);
|
|
721
|
-
const fileHash = hash.digest("hex").substring(0, 32); // First 32 chars of hash
|
|
722
|
-
return {
|
|
723
|
-
hash: fileHash,
|
|
724
|
-
size: fileContent.length,
|
|
725
|
-
};
|
|
726
|
-
}
|
|
727
458
|
/**
|
|
728
459
|
* Lists and deletes all queue consumers for a specific worker
|
|
729
460
|
* @param ctx Worker context containing eventSources
|