devflare 1.0.0-next.5 → 1.0.0-next.50
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/LICENSE +21 -0
- package/LLM.md +17312 -2139
- package/README.md +394 -605
- package/bin/devflare.js +30 -14
- package/dist/_chunks/account-BI3WZMDy.js +462 -0
- package/dist/_chunks/account-resources-CsmVowJp.js +159 -0
- package/dist/_chunks/ai-CBEuLdoP.js +322 -0
- package/dist/_chunks/api-TzdliH-6.js +568 -0
- package/dist/_chunks/build-artifacts-DU5V0J0Z.js +483 -0
- package/dist/_chunks/build-e0KR38-4.js +24 -0
- package/dist/_chunks/cli-DuUz10Mn.js +1163 -0
- package/dist/_chunks/cloudflare-BaloqI3H.js +157 -0
- package/dist/_chunks/colors-DiK6wPJ5.js +13 -0
- package/dist/_chunks/command-utils-DA0Qx9_K.js +45 -0
- package/dist/_chunks/compiler-Zw16C9Pi.js +489 -0
- package/dist/_chunks/config-Brju62xy.js +78 -0
- package/dist/_chunks/config-path-DaL1ylZ_.js +42 -0
- package/dist/_chunks/context-CX50Y2Kb.js +2250 -0
- package/dist/_chunks/decorators-QmV57ixr.js +19 -0
- package/dist/_chunks/dependencies-C2oxFjU_.js +57 -0
- package/dist/_chunks/deploy-B-Kku1Vk.js +1032 -0
- package/dist/_chunks/dev-D4e_RRZn.js +3471 -0
- package/dist/_chunks/doctor-jm_K4dxL.js +219 -0
- package/dist/_chunks/durable-object-DMtH0XYX.js +234 -0
- package/dist/_chunks/env-S0_nMVz1.js +125 -0
- package/dist/_chunks/family-_9-mGSfO.js +143 -0
- package/dist/_chunks/generated-artifacts-dMJY4KAt.js +32 -0
- package/dist/_chunks/glob-CmQOvunB.js +56 -0
- package/dist/_chunks/init-DnkJOmpW.js +165 -0
- package/dist/_chunks/loader-Cr0_OWPy.js +1288 -0
- package/dist/_chunks/local-dev-vars-CTSa-wvF.js +81 -0
- package/dist/_chunks/local-hyperdrive-CJ90j46O.js +119 -0
- package/dist/_chunks/local-media-bindings-DsAW4AMF.js +335 -0
- package/dist/_chunks/local-secrets-DMPkmOn3.js +123 -0
- package/dist/_chunks/local-workflow-entrypoints-Cq_WJajd.js +90 -0
- package/dist/_chunks/login-FjTAAQbi.js +51 -0
- package/dist/_chunks/package-metadata-DjHBLB-z.js +39 -0
- package/dist/_chunks/preferences-BKp_7XJx.js +241 -0
- package/dist/_chunks/preview-C3Cdr8an.js +462 -0
- package/dist/_chunks/preview-registry-ClAbLTHH.js +1186 -0
- package/dist/_chunks/preview-resources-CGMBjsYB.js +359 -0
- package/dist/_chunks/previews-C7hs9-BT.js +1134 -0
- package/dist/_chunks/productions-T9Als4fE.js +411 -0
- package/dist/_chunks/ref-CYJNAAe_.js +178 -0
- package/dist/_chunks/remote-CZnP-HLJ.js +79 -0
- package/dist/_chunks/remote-config-D39BY9ji.js +132 -0
- package/dist/_chunks/resolve-package-qizBfCIm.js +152 -0
- package/dist/_chunks/rolldown-runtime-CvQ6eiug.js +14 -0
- package/dist/_chunks/routes-BFYCqHb-.js +833 -0
- package/dist/_chunks/runtime-DL-Nz3k8.js +550 -0
- package/dist/_chunks/schema-normalization-BCwTLTGp.js +660 -0
- package/dist/_chunks/secrets-DIpJGe6C.js +95 -0
- package/dist/_chunks/tail-IY-ijYmv.js +239 -0
- package/dist/_chunks/token-Dmi0KXyX.js +333 -0
- package/dist/_chunks/tokens-iVcgNXi-.js +221 -0
- package/dist/_chunks/types-DoKsMYfm.js +484 -0
- package/dist/_chunks/ui-BUoZApvE.js +103 -0
- package/dist/_chunks/usage-BBTGzjon.js +272 -0
- package/dist/_chunks/vite-CGtVNf5E.js +1267 -0
- package/dist/_chunks/vite-utils-OVLMV605.js +183 -0
- package/dist/_chunks/worker-BEZI4od1.js +410 -0
- package/dist/_chunks/worker-bundler-dTTnYU3n.js +458 -0
- package/dist/_chunks/worker-entrypoint-CQW77lG8.js +247 -0
- package/dist/_chunks/workerName-CFJsLZA-.js +23 -0
- package/dist/bridge/client.d.ts +49 -7
- package/dist/bridge/client.d.ts.map +1 -1
- package/dist/bridge/gateway-runtime.d.ts +8 -0
- package/dist/bridge/gateway-runtime.d.ts.map +1 -0
- package/dist/bridge/index.d.ts +6 -6
- package/dist/bridge/index.d.ts.map +1 -1
- package/dist/bridge/log.d.ts +5 -0
- package/dist/bridge/log.d.ts.map +1 -0
- package/dist/bridge/miniflare.d.ts +82 -2
- package/dist/bridge/miniflare.d.ts.map +1 -1
- package/dist/bridge/proxy.d.ts +12 -11
- package/dist/bridge/proxy.d.ts.map +1 -1
- package/dist/bridge/server.d.ts +2 -1
- package/dist/bridge/server.d.ts.map +1 -1
- package/dist/bridge/v2/body-streams.d.ts +53 -0
- package/dist/bridge/v2/body-streams.d.ts.map +1 -0
- package/dist/bridge/v2/codec.d.ts +106 -0
- package/dist/bridge/v2/codec.d.ts.map +1 -0
- package/dist/bridge/v2/control-messages.d.ts +46 -0
- package/dist/bridge/v2/control-messages.d.ts.map +1 -0
- package/dist/bridge/v2/frames.d.ts +109 -0
- package/dist/bridge/v2/frames.d.ts.map +1 -0
- package/dist/bridge/v2/index.d.ts +11 -0
- package/dist/bridge/v2/index.d.ts.map +1 -0
- package/dist/bridge/v2/serialization.d.ts +48 -0
- package/dist/bridge/v2/serialization.d.ts.map +1 -0
- package/dist/bridge/v2/transport.d.ts +31 -0
- package/dist/bridge/v2/transport.d.ts.map +1 -0
- package/dist/bridge/v2/value-codec.d.ts +61 -0
- package/dist/bridge/v2/value-codec.d.ts.map +1 -0
- package/dist/bridge/{serialization.d.ts → v2/value-serialization.d.ts} +40 -18
- package/dist/bridge/v2/value-serialization.d.ts.map +1 -0
- package/dist/bridge/{protocol.d.ts → v2/wire.d.ts} +32 -8
- package/dist/bridge/v2/wire.d.ts.map +1 -0
- package/dist/bridge/v2/ws-relay.d.ts +53 -0
- package/dist/bridge/v2/ws-relay.d.ts.map +1 -0
- package/dist/browser-shim/handler.d.ts +2 -2
- package/dist/browser-shim/handler.d.ts.map +1 -1
- package/dist/browser-shim/index.d.ts +2 -2
- package/dist/browser-shim/server.d.ts +63 -0
- package/dist/browser-shim/server.d.ts.map +1 -1
- package/dist/browser.d.ts +5411 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.js +80 -0
- package/dist/bundler/defaults.d.ts +23 -0
- package/dist/bundler/defaults.d.ts.map +1 -0
- package/dist/bundler/do-bundler.d.ts +7 -0
- package/dist/bundler/do-bundler.d.ts.map +1 -1
- package/dist/bundler/index.d.ts +3 -1
- package/dist/bundler/index.d.ts.map +1 -1
- package/dist/bundler/rolldown-shared.d.ts +53 -0
- package/dist/bundler/rolldown-shared.d.ts.map +1 -0
- package/dist/bundler/worker-bundler.d.ts +13 -0
- package/dist/bundler/worker-bundler.d.ts.map +1 -0
- package/dist/bundler/worker-compat.d.ts +4 -0
- package/dist/bundler/worker-compat.d.ts.map +1 -0
- package/dist/cli/build-manifest.d.ts +66 -0
- package/dist/cli/build-manifest.d.ts.map +1 -0
- package/dist/cli/command-utils.d.ts +18 -0
- package/dist/cli/command-utils.d.ts.map +1 -0
- package/dist/cli/commands/account.d.ts +2 -2
- package/dist/cli/commands/account.d.ts.map +1 -1
- package/dist/cli/commands/ai.d.ts +1 -1
- package/dist/cli/commands/ai.d.ts.map +1 -1
- package/dist/cli/commands/build-artifacts.d.ts +40 -0
- package/dist/cli/commands/build-artifacts.d.ts.map +1 -0
- package/dist/cli/commands/build.d.ts +2 -2
- package/dist/cli/commands/build.d.ts.map +1 -1
- package/dist/cli/commands/config.d.ts +4 -0
- package/dist/cli/commands/config.d.ts.map +1 -0
- package/dist/cli/commands/deploy/metadata.d.ts +18 -0
- package/dist/cli/commands/deploy/metadata.d.ts.map +1 -0
- package/dist/cli/commands/deploy/prepare.d.ts +23 -0
- package/dist/cli/commands/deploy/prepare.d.ts.map +1 -0
- package/dist/cli/commands/deploy/runtime.d.ts +4 -0
- package/dist/cli/commands/deploy/runtime.d.ts.map +1 -0
- package/dist/cli/commands/deploy/verification.d.ts +36 -0
- package/dist/cli/commands/deploy/verification.d.ts.map +1 -0
- package/dist/cli/commands/deploy.d.ts +2 -2
- package/dist/cli/commands/deploy.d.ts.map +1 -1
- package/dist/cli/commands/dev.d.ts +9 -1
- package/dist/cli/commands/dev.d.ts.map +1 -1
- package/dist/cli/commands/doctor.d.ts +2 -2
- package/dist/cli/commands/doctor.d.ts.map +1 -1
- package/dist/cli/commands/init.d.ts +2 -2
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/login.d.ts +4 -0
- package/dist/cli/commands/login.d.ts.map +1 -0
- package/dist/cli/commands/previews-support/cleanup.d.ts +9 -0
- package/dist/cli/commands/previews-support/cleanup.d.ts.map +1 -0
- package/dist/cli/commands/previews-support/family.d.ts +10 -0
- package/dist/cli/commands/previews-support/family.d.ts.map +1 -0
- package/dist/cli/commands/previews-support/render.d.ts +8 -0
- package/dist/cli/commands/previews-support/render.d.ts.map +1 -0
- package/dist/cli/commands/previews-support/theme.d.ts +10 -0
- package/dist/cli/commands/previews-support/theme.d.ts.map +1 -0
- package/dist/cli/commands/previews-support/types.d.ts +70 -0
- package/dist/cli/commands/previews-support/types.d.ts.map +1 -0
- package/dist/cli/commands/previews.d.ts +4 -0
- package/dist/cli/commands/previews.d.ts.map +1 -0
- package/dist/cli/commands/productions.d.ts +4 -0
- package/dist/cli/commands/productions.d.ts.map +1 -0
- package/dist/cli/commands/remote.d.ts +1 -1
- package/dist/cli/commands/remote.d.ts.map +1 -1
- package/dist/cli/commands/secrets.d.ts +4 -0
- package/dist/cli/commands/secrets.d.ts.map +1 -0
- package/dist/cli/commands/tail.d.ts +44 -0
- package/dist/cli/commands/tail.d.ts.map +1 -0
- package/dist/cli/commands/token.d.ts +4 -0
- package/dist/cli/commands/token.d.ts.map +1 -0
- package/dist/cli/commands/type-generation/discovery.d.ts +7 -0
- package/dist/cli/commands/type-generation/discovery.d.ts.map +1 -0
- package/dist/cli/commands/type-generation/generator.d.ts +121 -0
- package/dist/cli/commands/type-generation/generator.d.ts.map +1 -0
- package/dist/cli/commands/type-generation/models.d.ts +27 -0
- package/dist/cli/commands/type-generation/models.d.ts.map +1 -0
- package/dist/cli/commands/types.d.ts +2 -2
- package/dist/cli/commands/types.d.ts.map +1 -1
- package/dist/cli/commands/worker.d.ts +4 -0
- package/dist/cli/commands/worker.d.ts.map +1 -0
- package/dist/cli/config-path.d.ts +6 -0
- package/dist/cli/config-path.d.ts.map +1 -0
- package/dist/cli/dependencies.d.ts +2 -1
- package/dist/cli/dependencies.d.ts.map +1 -1
- package/dist/cli/deploy-strategy.d.ts +17 -0
- package/dist/cli/deploy-strategy.d.ts.map +1 -0
- package/dist/cli/deploy-target.d.ts +17 -0
- package/dist/cli/deploy-target.d.ts.map +1 -0
- package/dist/cli/generated-artifacts.d.ts +12 -0
- package/dist/cli/generated-artifacts.d.ts.map +1 -0
- package/dist/cli/gradual-deploy.d.ts +49 -0
- package/dist/cli/gradual-deploy.d.ts.map +1 -0
- package/dist/cli/help-pages/pages/account.d.ts +3 -0
- package/dist/cli/help-pages/pages/account.d.ts.map +1 -0
- package/dist/cli/help-pages/pages/core.d.ts +4 -0
- package/dist/cli/help-pages/pages/core.d.ts.map +1 -0
- package/dist/cli/help-pages/pages/index.d.ts +3 -0
- package/dist/cli/help-pages/pages/index.d.ts.map +1 -0
- package/dist/cli/help-pages/pages/misc.d.ts +3 -0
- package/dist/cli/help-pages/pages/misc.d.ts.map +1 -0
- package/dist/cli/help-pages/pages/previews.d.ts +3 -0
- package/dist/cli/help-pages/pages/previews.d.ts.map +1 -0
- package/dist/cli/help-pages/pages/productions.d.ts +3 -0
- package/dist/cli/help-pages/pages/productions.d.ts.map +1 -0
- package/dist/cli/help-pages/render.d.ts +12 -0
- package/dist/cli/help-pages/render.d.ts.map +1 -0
- package/dist/cli/help-pages/shared.d.ts +15 -0
- package/dist/cli/help-pages/shared.d.ts.map +1 -0
- package/dist/cli/help-pages/types.d.ts +23 -0
- package/dist/cli/help-pages/types.d.ts.map +1 -0
- package/dist/cli/help.d.ts +6 -0
- package/dist/cli/help.d.ts.map +1 -0
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +2 -0
- package/dist/cli/package-metadata.d.ts +16 -0
- package/dist/cli/package-metadata.d.ts.map +1 -0
- package/dist/cli/preview-bindings.d.ts +49 -0
- package/dist/cli/preview-bindings.d.ts.map +1 -0
- package/dist/cli/preview.d.ts +10 -0
- package/dist/cli/preview.d.ts.map +1 -0
- package/dist/cli/ui.d.ts +37 -0
- package/dist/cli/ui.d.ts.map +1 -0
- package/dist/cli/workspace-build-guard.d.ts +14 -0
- package/dist/cli/workspace-build-guard.d.ts.map +1 -0
- package/dist/cli/wrangler-auth.d.ts +1 -1
- package/dist/cloudflare/account-core.d.ts +6 -0
- package/dist/cloudflare/account-core.d.ts.map +1 -0
- package/dist/cloudflare/account-resources.d.ts +40 -0
- package/dist/cloudflare/account-resources.d.ts.map +1 -0
- package/dist/cloudflare/account-status.d.ts +11 -0
- package/dist/cloudflare/account-status.d.ts.map +1 -0
- package/dist/cloudflare/account-workers.d.ts +14 -0
- package/dist/cloudflare/account-workers.d.ts.map +1 -0
- package/dist/cloudflare/account.d.ts +7 -64
- package/dist/cloudflare/account.d.ts.map +1 -1
- package/dist/cloudflare/api.d.ts +71 -3
- package/dist/cloudflare/api.d.ts.map +1 -1
- package/dist/cloudflare/auth.d.ts +1 -1
- package/dist/cloudflare/auth.d.ts.map +1 -1
- package/dist/cloudflare/index.d.ts +61 -6
- package/dist/cloudflare/index.d.ts.map +1 -1
- package/dist/cloudflare/index.js +4 -13
- package/dist/cloudflare/known-permission-group-ids.generated.d.ts +10 -0
- package/dist/cloudflare/known-permission-group-ids.generated.d.ts.map +1 -0
- package/dist/cloudflare/kv-namespace.d.ts +4 -0
- package/dist/cloudflare/kv-namespace.d.ts.map +1 -0
- package/dist/cloudflare/preferences.d.ts +7 -0
- package/dist/cloudflare/preferences.d.ts.map +1 -1
- package/dist/cloudflare/preview-registry-cache.d.ts +6 -0
- package/dist/cloudflare/preview-registry-cache.d.ts.map +1 -0
- package/dist/cloudflare/preview-registry-inference.d.ts +14 -0
- package/dist/cloudflare/preview-registry-inference.d.ts.map +1 -0
- package/dist/cloudflare/preview-registry-records.d.ts +4 -0
- package/dist/cloudflare/preview-registry-records.d.ts.map +1 -0
- package/dist/cloudflare/preview-registry-shape.d.ts +47 -0
- package/dist/cloudflare/preview-registry-shape.d.ts.map +1 -0
- package/dist/cloudflare/preview-registry-store.d.ts +14 -0
- package/dist/cloudflare/preview-registry-store.d.ts.map +1 -0
- package/dist/cloudflare/preview-registry-transport.d.ts +4 -0
- package/dist/cloudflare/preview-registry-transport.d.ts.map +1 -0
- package/dist/cloudflare/preview-registry-types.d.ts +103 -0
- package/dist/cloudflare/preview-registry-types.d.ts.map +1 -0
- package/dist/cloudflare/preview-registry.d.ts +42 -0
- package/dist/cloudflare/preview-registry.d.ts.map +1 -0
- package/dist/cloudflare/preview-urls.d.ts +3 -0
- package/dist/cloudflare/preview-urls.d.ts.map +1 -0
- package/dist/cloudflare/registry-schema.d.ts +253 -0
- package/dist/cloudflare/registry-schema.d.ts.map +1 -0
- package/dist/cloudflare/remote-config.d.ts.map +1 -1
- package/dist/cloudflare/tokens.d.ts +44 -0
- package/dist/cloudflare/tokens.d.ts.map +1 -0
- package/dist/cloudflare/types.d.ts +124 -7
- package/dist/cloudflare/types.d.ts.map +1 -1
- package/dist/cloudflare/usage.d.ts +31 -3
- package/dist/cloudflare/usage.d.ts.map +1 -1
- package/dist/config/binding-resolution-helpers.d.ts +41 -0
- package/dist/config/binding-resolution-helpers.d.ts.map +1 -0
- package/dist/config/compatibility.d.ts +3 -0
- package/dist/config/compatibility.d.ts.map +1 -0
- package/dist/config/compiler/bindings.d.ts +14 -0
- package/dist/config/compiler/bindings.d.ts.map +1 -0
- package/dist/config/compiler/core-helpers.d.ts +6 -0
- package/dist/config/compiler/core-helpers.d.ts.map +1 -0
- package/dist/config/compiler/do-workers.d.ts +34 -0
- package/dist/config/compiler/do-workers.d.ts.map +1 -0
- package/dist/config/compiler/paths.d.ts +18 -0
- package/dist/config/compiler/paths.d.ts.map +1 -0
- package/dist/config/compiler/types.d.ts +298 -0
- package/dist/config/compiler/types.d.ts.map +1 -0
- package/dist/config/compiler.d.ts +22 -134
- package/dist/config/compiler.d.ts.map +1 -1
- package/dist/config/cron.d.ts +19 -0
- package/dist/config/cron.d.ts.map +1 -0
- package/dist/config/define.d.ts +8 -5
- package/dist/config/define.d.ts.map +1 -1
- package/dist/config/deploy-resources.d.ts +58 -0
- package/dist/config/deploy-resources.d.ts.map +1 -0
- package/dist/config/env-vars.d.ts +309 -0
- package/dist/config/env-vars.d.ts.map +1 -0
- package/dist/config/framework-providers.d.ts +9 -0
- package/dist/config/framework-providers.d.ts.map +1 -0
- package/dist/config/index.d.ts +12 -5
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/loader.d.ts +2 -1
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/local-dev-vars.d.ts +15 -0
- package/dist/config/local-dev-vars.d.ts.map +1 -0
- package/dist/config/preview-resources.d.ts +83 -0
- package/dist/config/preview-resources.d.ts.map +1 -0
- package/dist/config/preview.d.ts +29 -0
- package/dist/config/preview.d.ts.map +1 -0
- package/dist/config/ref.d.ts +16 -25
- package/dist/config/ref.d.ts.map +1 -1
- package/dist/config/resolve-phased.d.ts +72 -0
- package/dist/config/resolve-phased.d.ts.map +1 -0
- package/dist/config/resolve.d.ts +11 -0
- package/dist/config/resolve.d.ts.map +1 -0
- package/dist/config/resource-resolution.d.ts +80 -0
- package/dist/config/resource-resolution.d.ts.map +1 -0
- package/dist/config/schema-bindings.d.ts +2025 -0
- package/dist/config/schema-bindings.d.ts.map +1 -0
- package/dist/config/schema-build.d.ts +67 -0
- package/dist/config/schema-build.d.ts.map +1 -0
- package/dist/config/schema-env.d.ts +3579 -0
- package/dist/config/schema-env.d.ts.map +1 -0
- package/dist/config/schema-normalization.d.ts +265 -0
- package/dist/config/schema-normalization.d.ts.map +1 -0
- package/dist/config/schema-runtime.d.ts +508 -0
- package/dist/config/schema-runtime.d.ts.map +1 -0
- package/dist/config/schema-types-bindings-platform.d.ts +508 -0
- package/dist/config/schema-types-bindings-platform.d.ts.map +1 -0
- package/dist/config/schema-types-bindings-resources.d.ts +767 -0
- package/dist/config/schema-types-bindings-resources.d.ts.map +1 -0
- package/dist/config/schema-types-bindings.d.ts +293 -0
- package/dist/config/schema-types-bindings.d.ts.map +1 -0
- package/dist/config/schema-types-build.d.ts +86 -0
- package/dist/config/schema-types-build.d.ts.map +1 -0
- package/dist/config/schema-types-runtime.d.ts +917 -0
- package/dist/config/schema-types-runtime.d.ts.map +1 -0
- package/dist/config/schema-types.d.ts +424 -0
- package/dist/config/schema-types.d.ts.map +1 -0
- package/dist/config/schema.d.ts +5324 -2011
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/service-bindings-validation.d.ts +36 -0
- package/dist/config/service-bindings-validation.d.ts.map +1 -0
- package/dist/config-entry.d.ts +7 -0
- package/dist/config-entry.d.ts.map +1 -0
- package/dist/config-entry.js +3 -0
- package/dist/decorators/durable-object.d.ts.map +1 -1
- package/dist/decorators/index.d.ts +2 -2
- package/dist/decorators/index.js +2 -9
- package/dist/dev-server/d1-migrations.d.ts +36 -0
- package/dist/dev-server/d1-migrations.d.ts.map +1 -0
- package/dist/dev-server/dev-server-state.d.ts +59 -0
- package/dist/dev-server/dev-server-state.d.ts.map +1 -0
- package/dist/dev-server/gateway-script.d.ts +21 -0
- package/dist/dev-server/gateway-script.d.ts.map +1 -0
- package/dist/dev-server/index.d.ts +1 -1
- package/dist/dev-server/miniflare-bindings.d.ts +81 -0
- package/dist/dev-server/miniflare-bindings.d.ts.map +1 -0
- package/dist/dev-server/miniflare-dev-config.d.ts +36 -0
- package/dist/dev-server/miniflare-dev-config.d.ts.map +1 -0
- package/dist/dev-server/miniflare-log.d.ts +20 -0
- package/dist/dev-server/miniflare-log.d.ts.map +1 -0
- package/dist/dev-server/miniflare-worker-config.d.ts +82 -0
- package/dist/dev-server/miniflare-worker-config.d.ts.map +1 -0
- package/dist/dev-server/reload-queue.d.ts +13 -0
- package/dist/dev-server/reload-queue.d.ts.map +1 -0
- package/dist/dev-server/runtime-stdio.d.ts +8 -0
- package/dist/dev-server/runtime-stdio.d.ts.map +1 -0
- package/dist/dev-server/server-startup-helpers.d.ts +84 -0
- package/dist/dev-server/server-startup-helpers.d.ts.map +1 -0
- package/dist/dev-server/server.d.ts +2 -0
- package/dist/dev-server/server.d.ts.map +1 -1
- package/dist/dev-server/vite-process.d.ts +15 -0
- package/dist/dev-server/vite-process.d.ts.map +1 -0
- package/dist/dev-server/vite-utils.d.ts +19 -1
- package/dist/dev-server/vite-utils.d.ts.map +1 -1
- package/dist/dev-server/worker-source-watcher.d.ts +17 -0
- package/dist/dev-server/worker-source-watcher.d.ts.map +1 -0
- package/dist/dev-server/worker-surface-paths.d.ts +6 -0
- package/dist/dev-server/worker-surface-paths.d.ts.map +1 -0
- package/dist/env.d.ts +10 -0
- package/dist/env.d.ts.map +1 -1
- package/dist/index.d.ts +8 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -298
- package/dist/runtime/context-events.d.ts +13 -0
- package/dist/runtime/context-events.d.ts.map +1 -0
- package/dist/runtime/context-types.d.ts +82 -0
- package/dist/runtime/context-types.d.ts.map +1 -0
- package/dist/runtime/context.d.ts +20 -44
- package/dist/runtime/context.d.ts.map +1 -1
- package/dist/runtime/exports.d.ts +70 -55
- package/dist/runtime/exports.d.ts.map +1 -1
- package/dist/runtime/index.d.ts +10 -3
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/index.js +5 -111
- package/dist/runtime/middleware.d.ts +119 -67
- package/dist/runtime/middleware.d.ts.map +1 -1
- package/dist/runtime/router/index.d.ts +7 -0
- package/dist/runtime/router/index.d.ts.map +1 -0
- package/dist/runtime/router/types.d.ts +24 -0
- package/dist/runtime/router/types.d.ts.map +1 -0
- package/dist/runtime/validation.d.ts +18 -4
- package/dist/runtime/validation.d.ts.map +1 -1
- package/dist/secrets/local-secrets.d.ts +46 -0
- package/dist/secrets/local-secrets.d.ts.map +1 -0
- package/dist/shims/local-hyperdrive.d.ts +12 -0
- package/dist/shims/local-hyperdrive.d.ts.map +1 -0
- package/dist/shims/local-media-bindings.d.ts +19 -0
- package/dist/shims/local-media-bindings.d.ts.map +1 -0
- package/dist/shims/local-worker-loader.d.ts +3 -0
- package/dist/shims/local-worker-loader.d.ts.map +1 -0
- package/dist/sveltekit/index.d.ts +1 -1
- package/dist/sveltekit/index.d.ts.map +1 -1
- package/dist/sveltekit/index.js +313 -167
- package/dist/sveltekit/local-bindings.d.ts +4 -0
- package/dist/sveltekit/local-bindings.d.ts.map +1 -0
- package/dist/sveltekit/platform.d.ts +20 -2
- package/dist/sveltekit/platform.d.ts.map +1 -1
- package/dist/test/ai-search.d.ts +39 -0
- package/dist/test/ai-search.d.ts.map +1 -0
- package/dist/test/alarm.d.ts +55 -0
- package/dist/test/alarm.d.ts.map +1 -0
- package/dist/test/binding-hints.d.ts +10 -0
- package/dist/test/binding-hints.d.ts.map +1 -0
- package/dist/test/cf.d.ts +71 -35
- package/dist/test/cf.d.ts.map +1 -1
- package/dist/test/containers.d.ts +87 -0
- package/dist/test/containers.d.ts.map +1 -0
- package/dist/test/email.d.ts +16 -7
- package/dist/test/email.d.ts.map +1 -1
- package/dist/test/index.d.ts +20 -21
- package/dist/test/index.d.ts.map +1 -1
- package/dist/test/index.js +4971 -70
- package/dist/test/offline-bindings.d.ts +115 -0
- package/dist/test/offline-bindings.d.ts.map +1 -0
- package/dist/test/queue.d.ts.map +1 -1
- package/dist/test/remote-ai.d.ts.map +1 -1
- package/dist/test/remote-cloudflare.d.ts +13 -0
- package/dist/test/remote-cloudflare.d.ts.map +1 -0
- package/dist/test/remote-vectorize.d.ts.map +1 -1
- package/dist/test/resolve-service-bindings.d.ts +64 -4
- package/dist/test/resolve-service-bindings.d.ts.map +1 -1
- package/dist/test/scheduled.d.ts.map +1 -1
- package/dist/test/should-skip.d.ts +14 -18
- package/dist/test/should-skip.d.ts.map +1 -1
- package/dist/test/simple-context-bindings.d.ts +13 -0
- package/dist/test/simple-context-bindings.d.ts.map +1 -0
- package/dist/test/simple-context-durable-objects.d.ts +6 -0
- package/dist/test/simple-context-durable-objects.d.ts.map +1 -0
- package/dist/test/simple-context-env.d.ts +35 -0
- package/dist/test/simple-context-env.d.ts.map +1 -0
- package/dist/test/simple-context-gateway-script.d.ts +2 -0
- package/dist/test/simple-context-gateway-script.d.ts.map +1 -0
- package/dist/test/simple-context-handlers.d.ts +12 -0
- package/dist/test/simple-context-handlers.d.ts.map +1 -0
- package/dist/test/simple-context-lifecycle.d.ts +32 -0
- package/dist/test/simple-context-lifecycle.d.ts.map +1 -0
- package/dist/test/simple-context-mfconfig.d.ts +10 -0
- package/dist/test/simple-context-mfconfig.d.ts.map +1 -0
- package/dist/test/simple-context-multi-worker.d.ts +16 -0
- package/dist/test/simple-context-multi-worker.d.ts.map +1 -0
- package/dist/test/simple-context-paths.d.ts +40 -0
- package/dist/test/simple-context-paths.d.ts.map +1 -0
- package/dist/test/simple-context-runtime.d.ts +19 -0
- package/dist/test/simple-context-runtime.d.ts.map +1 -0
- package/dist/test/simple-context-startup.d.ts +11 -0
- package/dist/test/simple-context-startup.d.ts.map +1 -0
- package/dist/test/simple-context-transport.d.ts +14 -0
- package/dist/test/simple-context-transport.d.ts.map +1 -0
- package/dist/test/simple-context.d.ts +8 -27
- package/dist/test/simple-context.d.ts.map +1 -1
- package/dist/test/tail.d.ts +3 -2
- package/dist/test/tail.d.ts.map +1 -1
- package/dist/test/utilities/analytics-engine.d.ts +22 -0
- package/dist/test/utilities/analytics-engine.d.ts.map +1 -0
- package/dist/test/utilities/artifacts.d.ts +11 -0
- package/dist/test/utilities/artifacts.d.ts.map +1 -0
- package/dist/test/utilities/context.d.ts +39 -0
- package/dist/test/utilities/context.d.ts.map +1 -0
- package/dist/test/utilities/d1.d.ts +21 -0
- package/dist/test/utilities/d1.d.ts.map +1 -0
- package/dist/test/utilities/env.d.ts +43 -0
- package/dist/test/utilities/env.d.ts.map +1 -0
- package/dist/test/utilities/kv.d.ts +11 -0
- package/dist/test/utilities/kv.d.ts.map +1 -0
- package/dist/test/utilities/media.d.ts +16 -0
- package/dist/test/utilities/media.d.ts.map +1 -0
- package/dist/test/utilities/platform.d.ts +41 -0
- package/dist/test/utilities/platform.d.ts.map +1 -0
- package/dist/test/utilities/queue.d.ts +5 -0
- package/dist/test/utilities/queue.d.ts.map +1 -0
- package/dist/test/utilities/r2.d.ts +2 -0
- package/dist/test/utilities/r2.d.ts.map +1 -0
- package/dist/test/utilities/stream-flagship.d.ts +27 -0
- package/dist/test/utilities/stream-flagship.d.ts.map +1 -0
- package/dist/test/utilities/vectorize.d.ts +38 -0
- package/dist/test/utilities/vectorize.d.ts.map +1 -0
- package/dist/test/utilities/workflows.d.ts +26 -0
- package/dist/test/utilities/workflows.d.ts.map +1 -0
- package/dist/test/utilities.d.ts +13 -98
- package/dist/test/utilities.d.ts.map +1 -1
- package/dist/test/worker.d.ts +6 -0
- package/dist/test/worker.d.ts.map +1 -1
- package/dist/transform/durable-object.d.ts.map +1 -1
- package/dist/transform/index.d.ts +2 -2
- package/dist/transform/worker-entrypoint.d.ts +5 -0
- package/dist/transform/worker-entrypoint.d.ts.map +1 -1
- package/dist/utils/entrypoint-discovery.d.ts +6 -3
- package/dist/utils/entrypoint-discovery.d.ts.map +1 -1
- package/dist/utils/glob.d.ts.map +1 -1
- package/dist/utils/resolve-package.d.ts.map +1 -1
- package/dist/utils/send-email.d.ts +15 -0
- package/dist/utils/send-email.d.ts.map +1 -0
- package/dist/utils/send-email.js +163 -0
- package/dist/vite/config-file.d.ts +25 -0
- package/dist/vite/config-file.d.ts.map +1 -0
- package/dist/vite/index.d.ts +3 -2
- package/dist/vite/index.d.ts.map +1 -1
- package/dist/vite/index.js +2 -339
- package/dist/vite/plugin-config-hook.d.ts +28 -0
- package/dist/vite/plugin-config-hook.d.ts.map +1 -0
- package/dist/vite/plugin-context.d.ts +27 -0
- package/dist/vite/plugin-context.d.ts.map +1 -0
- package/dist/vite/plugin-durable-objects.d.ts +18 -0
- package/dist/vite/plugin-durable-objects.d.ts.map +1 -0
- package/dist/vite/plugin-programmatic.d.ts +44 -0
- package/dist/vite/plugin-programmatic.d.ts.map +1 -0
- package/dist/vite/plugin-service-bindings.d.ts +13 -0
- package/dist/vite/plugin-service-bindings.d.ts.map +1 -0
- package/dist/vite/plugin-transform.d.ts +41 -0
- package/dist/vite/plugin-transform.d.ts.map +1 -0
- package/dist/vite/plugin.d.ts +10 -41
- package/dist/vite/plugin.d.ts.map +1 -1
- package/dist/worker-entry/composed-worker.d.ts +7 -0
- package/dist/worker-entry/composed-worker.d.ts.map +1 -0
- package/dist/worker-entry/durable-object-discovery.d.ts +20 -0
- package/dist/worker-entry/durable-object-discovery.d.ts.map +1 -0
- package/dist/worker-entry/extensions.d.ts +5 -0
- package/dist/worker-entry/extensions.d.ts.map +1 -0
- package/dist/worker-entry/routes.d.ts +22 -0
- package/dist/worker-entry/routes.d.ts.map +1 -0
- package/dist/worker-entry/surface-paths.d.ts +26 -0
- package/dist/worker-entry/surface-paths.d.ts.map +1 -0
- package/dist/worker-entry/validate-fetch-style.d.ts +12 -0
- package/dist/worker-entry/validate-fetch-style.d.ts.map +1 -0
- package/dist/workflows/local-workflow-entrypoints.d.ts +7 -0
- package/dist/workflows/local-workflow-entrypoints.d.ts.map +1 -0
- package/package.json +159 -116
- package/R2.md +0 -170
- package/dist/account-rvrj687w.js +0 -397
- package/dist/ai-dx4fr9jh.js +0 -107
- package/dist/bridge/protocol.d.ts.map +0 -1
- package/dist/bridge/serialization.d.ts.map +0 -1
- package/dist/browser-shim/worker.d.ts +0 -14
- package/dist/browser-shim/worker.d.ts.map +0 -1
- package/dist/build-mnf6v8gd.js +0 -53
- package/dist/deploy-nhceck39.js +0 -70
- package/dist/dev-b9dmrj7b.js +0 -2417
- package/dist/doctor-fmgb3d28.js +0 -190
- package/dist/durable-object-t4kbb0yt.js +0 -13
- package/dist/index-07q6yxyc.js +0 -168
- package/dist/index-18hvb6gb.js +0 -194
- package/dist/index-1xpj0m4r.js +0 -57
- package/dist/index-37x76zdn.js +0 -4
- package/dist/index-3t6rypgc.js +0 -13
- package/dist/index-67qcae0f.js +0 -183
- package/dist/index-a855bdsx.js +0 -18
- package/dist/index-d8bdkx2h.js +0 -109
- package/dist/index-ep3445yc.js +0 -2225
- package/dist/index-gz1gndna.js +0 -307
- package/dist/index-hcex3rgh.js +0 -266
- package/dist/index-m2q41jwa.js +0 -462
- package/dist/index-n7rs26ft.js +0 -77
- package/dist/index-pf5s73n9.js +0 -1413
- package/dist/index-rbht7m9r.js +0 -36
- package/dist/index-tfyxa77h.js +0 -850
- package/dist/index-tk6ej9dj.js +0 -94
- package/dist/index-z14anrqp.js +0 -226
- package/dist/init-f9mgmew3.js +0 -186
- package/dist/remote-q59qk463.js +0 -97
- package/dist/test/bridge-context.d.ts +0 -76
- package/dist/test/bridge-context.d.ts.map +0 -1
- package/dist/test/multi-worker-context.d.ts +0 -114
- package/dist/test/multi-worker-context.d.ts.map +0 -1
- package/dist/types-5nyrz1sz.js +0 -454
- package/dist/worker-entrypoint-m9th0rg0.js +0 -13
|
@@ -0,0 +1,1032 @@
|
|
|
1
|
+
import { a as resolvePreviewIdentifier, d as resolveConfigEnvVars } from "./preview-C3Cdr8an.js";
|
|
2
|
+
import { c as prepareConfigResourcesForDeploy, r as loadConfig, u as resolveConfigForEnvironment } from "./loader-Cr0_OWPy.js";
|
|
3
|
+
import { a as readWranglerConfig, c as writeWranglerConfig, n as compileConfig, o as rebaseWranglerConfigPaths, s as stringifyConfig, t as compileBuildConfig } from "./compiler-Zw16C9Pi.js";
|
|
4
|
+
import { d as getPrimaryAccount, n as getEffectiveAccountId } from "./preferences-BKp_7XJx.js";
|
|
5
|
+
import { D as listWorkerVersions, E as listWorkerDeployments, O as listWorkers, T as getWorkersSubdomain, c as reconcilePreviewRegistry, w as getWorkerVersionDetail, x as formatWorkersDevUrl } from "./preview-registry-ClAbLTHH.js";
|
|
6
|
+
import { _ as yellowBold, d as green, f as logLine, g as yellow, o as dim, r as createCliTheme } from "./ui-BUoZApvE.js";
|
|
7
|
+
import { n as getPackageVersion } from "./package-metadata-DjHBLB-z.js";
|
|
8
|
+
import { t as resolvePackageSpecifier } from "./resolve-package-qizBfCIm.js";
|
|
9
|
+
import { t as asOptionalString } from "./command-utils-DA0Qx9_K.js";
|
|
10
|
+
import { a as createBuildManifest, i as compareManifests, n as applyDeploymentStrategy, o as formatDriftWarning, r as describeDeploymentStrategy, s as readBuildManifest, t as prepareBuildArtifacts } from "./build-artifacts-DU5V0J0Z.js";
|
|
11
|
+
import { t as getDependencies } from "./dependencies-C2oxFjU_.js";
|
|
12
|
+
import { n as preparePreviewScopedResourcesForDeploy } from "./preview-resources-CGMBjsYB.js";
|
|
13
|
+
import { mkdir, open, readFile, rm, writeFile } from "node:fs/promises";
|
|
14
|
+
import { basename, dirname, isAbsolute, join, resolve } from "pathe";
|
|
15
|
+
//#region src/config/service-bindings-validation.ts
|
|
16
|
+
var ServiceBindingValidationError = class extends Error {
|
|
17
|
+
code = "SERVICE_BINDING_VALIDATION_ERROR";
|
|
18
|
+
missing;
|
|
19
|
+
constructor(missing, accountId) {
|
|
20
|
+
super(`Service binding(s) reference worker(s) that do not exist in Cloudflare account ${accountId}: ` + missing.join(", ") + `. Check the 'services' map in devflare.config.ts for typos or deploy the target worker(s) first.`);
|
|
21
|
+
this.name = "ServiceBindingValidationError";
|
|
22
|
+
this.missing = missing;
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Collect every `service` target referenced by the config's `bindings.services`
|
|
27
|
+
* map, deduplicated. Returns `[]` when no service bindings are configured.
|
|
28
|
+
*/
|
|
29
|
+
function collectReferencedServiceNames(config) {
|
|
30
|
+
const services = config.bindings?.services;
|
|
31
|
+
if (!services) return [];
|
|
32
|
+
const names = /* @__PURE__ */ new Set();
|
|
33
|
+
for (const binding of Object.values(services)) if (binding && typeof binding === "object" && typeof binding.service === "string") {
|
|
34
|
+
const name = binding.service.trim();
|
|
35
|
+
if (name.length > 0) names.add(name);
|
|
36
|
+
}
|
|
37
|
+
return [...names];
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Validate that every service binding target exists in the Cloudflare account.
|
|
41
|
+
*
|
|
42
|
+
* Throws `ServiceBindingValidationError` with the full list of missing
|
|
43
|
+
* targets if any are unreachable. A missing self-reference is tolerated
|
|
44
|
+
* when `selfWorkerName` matches, so first deploys don't fail against
|
|
45
|
+
* themselves.
|
|
46
|
+
*/
|
|
47
|
+
async function validateServiceBindings(config, accountId, options) {
|
|
48
|
+
const referenced = collectReferencedServiceNames(config);
|
|
49
|
+
if (referenced.length === 0) return;
|
|
50
|
+
const selfName = options.selfWorkerName?.trim();
|
|
51
|
+
const toValidate = selfName ? referenced.filter((name) => name !== selfName) : referenced;
|
|
52
|
+
if (toValidate.length === 0) return;
|
|
53
|
+
const workers = await options.listWorkers(accountId);
|
|
54
|
+
const workerNames = new Set(workers.map((worker) => worker.name));
|
|
55
|
+
const missing = toValidate.filter((name) => !workerNames.has(name));
|
|
56
|
+
if (missing.length > 0) throw new ServiceBindingValidationError(missing, accountId);
|
|
57
|
+
}
|
|
58
|
+
//#endregion
|
|
59
|
+
//#region src/cli/deploy-target.ts
|
|
60
|
+
function resolveDeployTarget(parsed, options = {}) {
|
|
61
|
+
const wantsProduction = parsed.options.prod === true || parsed.options.production === true;
|
|
62
|
+
const previewOption = parsed.options.preview;
|
|
63
|
+
const previewScopeRaw = asOptionalString(previewOption);
|
|
64
|
+
const wantsPreview = previewOption === true || Boolean(previewScopeRaw);
|
|
65
|
+
if (!wantsProduction && !wantsPreview) {
|
|
66
|
+
if (options.requireExplicitTarget === true) throw new Error("Deploy needs an explicit target. Use --prod / --production for live traffic, or --preview <name> (or bare --preview) for preview deploys.");
|
|
67
|
+
return {
|
|
68
|
+
mode: "implicit",
|
|
69
|
+
envOverrides: {}
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
if (wantsProduction && wantsPreview) throw new Error("Choose either --prod / --production or --preview <name>, not both.");
|
|
73
|
+
const explicitEnvironment = asOptionalString(parsed.options.env);
|
|
74
|
+
if (wantsProduction) {
|
|
75
|
+
if (explicitEnvironment && explicitEnvironment !== "production") throw new Error("Production deploys always target the production environment. Remove --env or use --env production.");
|
|
76
|
+
if (parsed.options["branch-name"] !== void 0) throw new Error("Production deploys do not accept --branch-name.");
|
|
77
|
+
return {
|
|
78
|
+
mode: "production",
|
|
79
|
+
environment: "production",
|
|
80
|
+
targetFlag: parsed.options.production === true ? "--production" : "--prod",
|
|
81
|
+
envOverrides: {
|
|
82
|
+
DEVFLARE_PREVIEW_BRANCH: void 0,
|
|
83
|
+
DEVFLARE_PREVIEW_IDENTIFIER: void 0,
|
|
84
|
+
DEVFLARE_PREVIEW_PR: void 0
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
if (explicitEnvironment && explicitEnvironment !== "preview") throw new Error("Preview deploys always target the preview environment. Remove --env or use --env preview.");
|
|
89
|
+
if (previewScopeRaw) {
|
|
90
|
+
const branchName = asOptionalString(parsed.options["branch-name"]);
|
|
91
|
+
if (branchName && branchName !== previewScopeRaw) throw new Error("Named preview deploys use the --preview value as the preview scope. Omit --branch-name or pass the same value to both flags.");
|
|
92
|
+
const previewScope = resolvePreviewIdentifier({ identifier: previewScopeRaw }).identifier ?? "preview";
|
|
93
|
+
return {
|
|
94
|
+
mode: "preview-scope",
|
|
95
|
+
environment: "preview",
|
|
96
|
+
targetFlag: "--preview",
|
|
97
|
+
previewScope,
|
|
98
|
+
previewScopeRaw,
|
|
99
|
+
envOverrides: {
|
|
100
|
+
DEVFLARE_PREVIEW_BRANCH: previewScopeRaw,
|
|
101
|
+
DEVFLARE_PREVIEW_IDENTIFIER: previewScope,
|
|
102
|
+
DEVFLARE_PREVIEW_PR: void 0
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
return {
|
|
107
|
+
mode: "preview-upload",
|
|
108
|
+
environment: "preview",
|
|
109
|
+
targetFlag: "--preview",
|
|
110
|
+
envOverrides: {
|
|
111
|
+
DEVFLARE_PREVIEW_BRANCH: void 0,
|
|
112
|
+
DEVFLARE_PREVIEW_IDENTIFIER: void 0,
|
|
113
|
+
DEVFLARE_PREVIEW_PR: void 0
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
function applyResolvedDeployTarget(parsed, target) {
|
|
118
|
+
if (!target.environment) return parsed;
|
|
119
|
+
return {
|
|
120
|
+
...parsed,
|
|
121
|
+
options: {
|
|
122
|
+
...parsed.options,
|
|
123
|
+
env: target.environment
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
async function withTemporaryEnvironment(overrides, operation) {
|
|
128
|
+
const previousValues = /* @__PURE__ */ new Map();
|
|
129
|
+
for (const [key, value] of Object.entries(overrides)) {
|
|
130
|
+
previousValues.set(key, process.env[key]);
|
|
131
|
+
if (typeof value === "string") {
|
|
132
|
+
process.env[key] = value;
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
delete process.env[key];
|
|
136
|
+
}
|
|
137
|
+
try {
|
|
138
|
+
return await operation();
|
|
139
|
+
} finally {
|
|
140
|
+
for (const [key, value] of previousValues) {
|
|
141
|
+
if (typeof value === "string") {
|
|
142
|
+
process.env[key] = value;
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
delete process.env[key];
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
//#endregion
|
|
150
|
+
//#region src/cli/gradual-deploy.ts
|
|
151
|
+
/**
|
|
152
|
+
* Parse and validate the `--percentage` CLI option.
|
|
153
|
+
*
|
|
154
|
+
* Returns `undefined` when the flag is absent (a normal full deploy). Throws a
|
|
155
|
+
* clear error when the value is present but not an integer in `[0, 100]` — the
|
|
156
|
+
* same bounds Wrangler enforces — so a typo never silently becomes a full
|
|
157
|
+
* deploy.
|
|
158
|
+
*/
|
|
159
|
+
function parseDeployPercentage(value) {
|
|
160
|
+
if (value === void 0) return;
|
|
161
|
+
if (value === true || value === false) throw new Error("--percentage requires a value between 0 and 100, e.g. `--percentage 10`.");
|
|
162
|
+
const trimmed = value.trim();
|
|
163
|
+
if (!/^\d+$/.test(trimmed)) throw new Error(`--percentage must be a whole number between 0 and 100, received "${value}".`);
|
|
164
|
+
const parsed = Number.parseInt(trimmed, 10);
|
|
165
|
+
if (!Number.isInteger(parsed) || parsed < 0 || parsed > 100) throw new Error(`--percentage must be a whole number between 0 and 100, received "${value}".`);
|
|
166
|
+
return parsed;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Build the positional `<version-id>@<percentage>` version specs for a rollout.
|
|
170
|
+
*
|
|
171
|
+
* Wrangler's `versions deploy` consumes traffic splits as positional specs (see
|
|
172
|
+
* `wrangler versions deploy --help`: "Shorthand notation to deploy Worker
|
|
173
|
+
* Version(s) [<version-id>@<percentage>..]"). When a distinct previous version
|
|
174
|
+
* id is provided, the remaining percentage is routed to it so the split is
|
|
175
|
+
* fully specified and Wrangler never has to prompt; otherwise only the new
|
|
176
|
+
* version is named and Wrangler distributes the rest.
|
|
177
|
+
*/
|
|
178
|
+
function buildVersionSpecs(spec) {
|
|
179
|
+
const specs = [`${spec.versionId}@${spec.percentage}`];
|
|
180
|
+
const remaining = 100 - spec.percentage;
|
|
181
|
+
if (spec.previousVersionId && spec.previousVersionId !== spec.versionId && remaining > 0) specs.push(`${spec.previousVersionId}@${remaining}`);
|
|
182
|
+
return specs;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Build the full `wrangler versions deploy` invocation for a gradual rollout.
|
|
186
|
+
*
|
|
187
|
+
* `localWranglerExecutable` mirrors the deploy command's resolution: when a
|
|
188
|
+
* local `wrangler/bin/wrangler.js` exists it is run under `node`; otherwise the
|
|
189
|
+
* invocation falls back to `bunx wrangler …`.
|
|
190
|
+
*/
|
|
191
|
+
function buildGradualDeployInvocation(spec, localWranglerExecutable) {
|
|
192
|
+
const command = localWranglerExecutable ? "node" : "bunx";
|
|
193
|
+
const args = localWranglerExecutable ? [
|
|
194
|
+
localWranglerExecutable,
|
|
195
|
+
"versions",
|
|
196
|
+
"deploy"
|
|
197
|
+
] : [
|
|
198
|
+
"wrangler",
|
|
199
|
+
"versions",
|
|
200
|
+
"deploy"
|
|
201
|
+
];
|
|
202
|
+
args.push(...buildVersionSpecs(spec));
|
|
203
|
+
args.push("--name", spec.workerName);
|
|
204
|
+
if (spec.message?.trim()) args.push("--message", spec.message.trim());
|
|
205
|
+
args.push("--yes");
|
|
206
|
+
return {
|
|
207
|
+
command,
|
|
208
|
+
args
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
//#endregion
|
|
212
|
+
//#region src/cli/preview.ts
|
|
213
|
+
function matchNamedValue(output, patterns) {
|
|
214
|
+
for (const pattern of patterns) {
|
|
215
|
+
const match = output.match(pattern);
|
|
216
|
+
if (match?.[1]) return match[1];
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
function appendUniqueUrls(target, value) {
|
|
220
|
+
if (typeof value === "string") {
|
|
221
|
+
if (value.startsWith("http://") || value.startsWith("https://")) target.push(value);
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
if (!Array.isArray(value)) return;
|
|
225
|
+
for (const item of value) appendUniqueUrls(target, item);
|
|
226
|
+
}
|
|
227
|
+
function parseWranglerStructuredOutput(output) {
|
|
228
|
+
const records = output.replace(/\r/g, "").split("\n").map((line) => line.trim()).filter(Boolean).map((line) => {
|
|
229
|
+
try {
|
|
230
|
+
return JSON.parse(line);
|
|
231
|
+
} catch {
|
|
232
|
+
return null;
|
|
233
|
+
}
|
|
234
|
+
}).filter((record) => record !== null);
|
|
235
|
+
const urls = [];
|
|
236
|
+
let versionId;
|
|
237
|
+
let previewUrl;
|
|
238
|
+
for (const record of records) {
|
|
239
|
+
if (!versionId && typeof record.version_id === "string" && record.version_id.trim()) versionId = record.version_id.trim();
|
|
240
|
+
appendUniqueUrls(urls, record.targets);
|
|
241
|
+
appendUniqueUrls(urls, record.preview_urls);
|
|
242
|
+
appendUniqueUrls(urls, record.urls);
|
|
243
|
+
appendUniqueUrls(urls, record.url);
|
|
244
|
+
if (!previewUrl && typeof record.preview_url === "string" && record.preview_url.trim()) previewUrl = record.preview_url.trim();
|
|
245
|
+
}
|
|
246
|
+
const uniqueUrls = [...new Set(urls)];
|
|
247
|
+
if (!previewUrl) previewUrl = uniqueUrls.find((url) => url.includes("workers.dev"));
|
|
248
|
+
return {
|
|
249
|
+
versionId,
|
|
250
|
+
previewUrl,
|
|
251
|
+
urls: uniqueUrls
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
function mergeParsedWranglerDeployOutputs(...outputs) {
|
|
255
|
+
const urls = [...new Set(outputs.flatMap((output) => output.urls))];
|
|
256
|
+
return {
|
|
257
|
+
versionId: outputs.map((output) => output.versionId).find((value) => Boolean(value)),
|
|
258
|
+
previewUrl: outputs.map((output) => output.previewUrl).find((value) => Boolean(value)) ?? urls.find((url) => url.includes("workers.dev")),
|
|
259
|
+
urls
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
function parseWranglerDeployOutput(output) {
|
|
263
|
+
const normalizedOutput = output.replace(/\r/g, "");
|
|
264
|
+
const urls = [...new Set(normalizedOutput.match(/https?:\/\/[^\s'"`]+/g) ?? [])];
|
|
265
|
+
const previewUrl = matchNamedValue(normalizedOutput, [/Preview URL:\s*(https?:\/\/\S+)/i, /Version Preview URL:\s*(https?:\/\/\S+)/i]) ?? urls.find((url) => url.includes("workers.dev"));
|
|
266
|
+
return {
|
|
267
|
+
versionId: matchNamedValue(normalizedOutput, [
|
|
268
|
+
/Worker Version ID:\s*([A-Za-z0-9_-]+)/i,
|
|
269
|
+
/Version ID:\s*([A-Za-z0-9_-]+)/i,
|
|
270
|
+
/version(?:_id| id)?\s*[:=]\s*([A-Za-z0-9_-]+)/i,
|
|
271
|
+
/"id"\s*:\s*"([A-Za-z0-9_-]+)"/i
|
|
272
|
+
]),
|
|
273
|
+
previewUrl,
|
|
274
|
+
urls
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
//#endregion
|
|
278
|
+
//#region src/cli/commands/deploy/metadata.ts
|
|
279
|
+
function inferRecordSource() {
|
|
280
|
+
return process.env.GITHUB_ACTIONS === "true" ? "github-action" : "cli";
|
|
281
|
+
}
|
|
282
|
+
async function writeDeployResultMetadata(metadata) {
|
|
283
|
+
const metadataPath = process.env.DEVFLARE_DEPLOY_METADATA_PATH?.trim();
|
|
284
|
+
if (!metadataPath) return;
|
|
285
|
+
await mkdir(dirname(metadataPath), { recursive: true });
|
|
286
|
+
await writeFile(metadataPath, JSON.stringify(metadata, null, " "), "utf8");
|
|
287
|
+
}
|
|
288
|
+
//#endregion
|
|
289
|
+
//#region src/cli/commands/deploy/prepare.ts
|
|
290
|
+
function summarizeDeployResourceNames(resources) {
|
|
291
|
+
const segments = [
|
|
292
|
+
resources.kv.length > 0 ? `KV ${resources.kv.length}` : null,
|
|
293
|
+
resources.d1.length > 0 ? `D1 ${resources.d1.length}` : null,
|
|
294
|
+
resources.r2.length > 0 ? `R2 ${resources.r2.length}` : null,
|
|
295
|
+
resources.queues.length > 0 ? `Queues ${resources.queues.length}` : null,
|
|
296
|
+
resources.vectorize.length > 0 ? `Vectorize ${resources.vectorize.length}` : null,
|
|
297
|
+
resources.hyperdrive.length > 0 ? `Hyperdrive ${resources.hyperdrive.length}` : null
|
|
298
|
+
].filter((segment) => segment !== null);
|
|
299
|
+
return segments.length > 0 ? segments.join(" · ") : null;
|
|
300
|
+
}
|
|
301
|
+
async function readDeployRedirectPath(filePath) {
|
|
302
|
+
const fs = await import("node:fs/promises");
|
|
303
|
+
try {
|
|
304
|
+
const rawConfig = await fs.readFile(filePath, "utf-8");
|
|
305
|
+
const parsed = JSON.parse(rawConfig);
|
|
306
|
+
if (typeof parsed.configPath !== "string" || parsed.configPath.length === 0) return null;
|
|
307
|
+
return resolve(dirname(filePath), parsed.configPath);
|
|
308
|
+
} catch {
|
|
309
|
+
return null;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
async function resolveBuildArtifactConfigPath(buildPath, cwd) {
|
|
313
|
+
const fs = await import("node:fs/promises");
|
|
314
|
+
const absoluteBuildPath = isAbsolute(buildPath) ? buildPath : resolve(cwd, buildPath);
|
|
315
|
+
let stat;
|
|
316
|
+
try {
|
|
317
|
+
stat = await fs.stat(absoluteBuildPath);
|
|
318
|
+
} catch {
|
|
319
|
+
throw new Error(`Could not find build artifact path: ${absoluteBuildPath}`);
|
|
320
|
+
}
|
|
321
|
+
if (stat.isFile()) {
|
|
322
|
+
if (basename(absoluteBuildPath) === "config.json") {
|
|
323
|
+
const redirectedConfigPath = await readDeployRedirectPath(absoluteBuildPath);
|
|
324
|
+
if (!redirectedConfigPath) throw new Error(`Build redirect ${absoluteBuildPath} did not contain a valid configPath.`);
|
|
325
|
+
return redirectedConfigPath;
|
|
326
|
+
}
|
|
327
|
+
return absoluteBuildPath;
|
|
328
|
+
}
|
|
329
|
+
const candidates = [
|
|
330
|
+
resolve(absoluteBuildPath, "wrangler.jsonc"),
|
|
331
|
+
resolve(absoluteBuildPath, ".wrangler", "deploy", "config.json"),
|
|
332
|
+
resolve(absoluteBuildPath, "config.json"),
|
|
333
|
+
resolve(absoluteBuildPath, ".devflare", "build", "wrangler.jsonc")
|
|
334
|
+
];
|
|
335
|
+
for (const candidatePath of candidates) try {
|
|
336
|
+
if (!(await fs.stat(candidatePath)).isFile()) continue;
|
|
337
|
+
if (basename(candidatePath) === "config.json") {
|
|
338
|
+
const redirectedConfigPath = await readDeployRedirectPath(candidatePath);
|
|
339
|
+
if (redirectedConfigPath) return redirectedConfigPath;
|
|
340
|
+
continue;
|
|
341
|
+
}
|
|
342
|
+
return candidatePath;
|
|
343
|
+
} catch {}
|
|
344
|
+
throw new Error(`Could not resolve a Wrangler build config from ${absoluteBuildPath}. Pass a .devflare/build directory, a generated wrangler.jsonc, or a .wrangler/deploy/config.json redirect.`);
|
|
345
|
+
}
|
|
346
|
+
function withBuildArtifactPaths(compiledConfig, buildConfig) {
|
|
347
|
+
return {
|
|
348
|
+
...compiledConfig,
|
|
349
|
+
...buildConfig.main ? { main: buildConfig.main } : {},
|
|
350
|
+
...buildConfig.assets ? { assets: buildConfig.assets } : {}
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
async function prepareDeployConfig(options) {
|
|
354
|
+
const rawConfig = await resolveConfigEnvVars(await loadConfig({
|
|
355
|
+
cwd: options.cwd,
|
|
356
|
+
configFile: options.configPath
|
|
357
|
+
}), {
|
|
358
|
+
cwd: options.cwd,
|
|
359
|
+
configPath: options.configPath,
|
|
360
|
+
mode: "build"
|
|
361
|
+
});
|
|
362
|
+
const manifest = await readBuildManifest(dirname(options.buildConfigPath));
|
|
363
|
+
if (manifest) {
|
|
364
|
+
const warning = formatDriftWarning(compareManifests(manifest, createBuildManifest(rawConfig, {
|
|
365
|
+
devflareVersion: await getPackageVersion(),
|
|
366
|
+
intendedTarget: {
|
|
367
|
+
environment: options.environment,
|
|
368
|
+
preview: options.preview,
|
|
369
|
+
branchName: options.branchName
|
|
370
|
+
}
|
|
371
|
+
})));
|
|
372
|
+
if (warning && options.logger) if (options.force) {
|
|
373
|
+
logLine(options.logger, warning);
|
|
374
|
+
logLine(options.logger, "Continuing because --force was passed.");
|
|
375
|
+
} else logLine(options.logger, warning);
|
|
376
|
+
}
|
|
377
|
+
const previewScopedResources = options.environment === "preview" ? await preparePreviewScopedResourcesForDeploy(rawConfig, { environment: options.environment }) : null;
|
|
378
|
+
const deployResources = await prepareConfigResourcesForDeploy(previewScopedResources?.config ?? rawConfig, {
|
|
379
|
+
environment: options.environment,
|
|
380
|
+
accountId: previewScopedResources?.accountId,
|
|
381
|
+
cloudflare: previewScopedResources?.resourceResolutionCloudflare
|
|
382
|
+
});
|
|
383
|
+
const deploymentStrategy = applyDeploymentStrategy(deployResources.config, {
|
|
384
|
+
environment: options.environment,
|
|
385
|
+
preview: options.preview,
|
|
386
|
+
branchName: options.branchName,
|
|
387
|
+
previewBranch: process.env.DEVFLARE_PREVIEW_BRANCH
|
|
388
|
+
});
|
|
389
|
+
const validationAccountId = previewScopedResources?.accountId ?? deploymentStrategy.config.accountId ?? process.env.CLOUDFLARE_ACCOUNT_ID;
|
|
390
|
+
if (validationAccountId) try {
|
|
391
|
+
await validateServiceBindings(deploymentStrategy.config, validationAccountId, {
|
|
392
|
+
listWorkers: (accountId) => listWorkers(accountId),
|
|
393
|
+
selfWorkerName: deploymentStrategy.config.name
|
|
394
|
+
});
|
|
395
|
+
} catch (error) {
|
|
396
|
+
if (error instanceof ServiceBindingValidationError) throw error;
|
|
397
|
+
}
|
|
398
|
+
const buildWranglerConfig = await readWranglerConfig(options.buildConfigPath);
|
|
399
|
+
const compiledWranglerConfig = compileConfig(deploymentStrategy.config);
|
|
400
|
+
const buildDir = dirname(options.buildConfigPath);
|
|
401
|
+
const deployArtefactDir = resolve(buildDir, "..", "deploy");
|
|
402
|
+
await mkdir(deployArtefactDir, { recursive: true });
|
|
403
|
+
const deployArtefactPath = resolve(deployArtefactDir, "wrangler.jsonc");
|
|
404
|
+
const wranglerConfig = withBuildArtifactPaths(rebaseWranglerConfigPaths(options.cwd, deployArtefactDir, compiledWranglerConfig), rebaseWranglerConfigPaths(buildDir, deployArtefactDir, buildWranglerConfig));
|
|
405
|
+
const lockPath = resolve(deployArtefactDir, ".lock");
|
|
406
|
+
const lockHandle = await acquireDeployArtefactLock(lockPath);
|
|
407
|
+
try {
|
|
408
|
+
await writeWranglerConfig(deployArtefactDir, wranglerConfig, "wrangler.jsonc");
|
|
409
|
+
} finally {
|
|
410
|
+
await releaseDeployArtefactLock(lockHandle, lockPath);
|
|
411
|
+
}
|
|
412
|
+
return {
|
|
413
|
+
config: deploymentStrategy.config,
|
|
414
|
+
deployConfigPath: deployArtefactPath,
|
|
415
|
+
previewScopedResources,
|
|
416
|
+
deployResources,
|
|
417
|
+
wranglerConfig
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
/**
|
|
421
|
+
* C10 — bounded-wait exclusive lock around the deploy artefact directory.
|
|
422
|
+
*
|
|
423
|
+
* Uses `open(path, 'wx')` (O_EXCL) which atomically fails when the file
|
|
424
|
+
* already exists, so the only way to acquire the lock is to be the process
|
|
425
|
+
* that successfully created it. Stale locks (older than 60s) are forcibly
|
|
426
|
+
* cleared so a crashed deploy cannot wedge subsequent runs.
|
|
427
|
+
*/
|
|
428
|
+
async function acquireDeployArtefactLock(lockPath, options = {}) {
|
|
429
|
+
const maxWaitMs = options.maxWaitMs ?? 3e4;
|
|
430
|
+
const staleAfterMs = options.staleAfterMs ?? 6e4;
|
|
431
|
+
const pollMs = 100;
|
|
432
|
+
const start = Date.now();
|
|
433
|
+
while (true) try {
|
|
434
|
+
const handle = await open(lockPath, "wx");
|
|
435
|
+
await handle.writeFile(`${process.pid}\n${Date.now()}`);
|
|
436
|
+
return handle;
|
|
437
|
+
} catch (err) {
|
|
438
|
+
if (err.code !== "EEXIST") throw err;
|
|
439
|
+
try {
|
|
440
|
+
const existing = await readFile(lockPath, "utf-8");
|
|
441
|
+
const ts = Number.parseInt(existing.split("\n")[1] ?? "0", 10);
|
|
442
|
+
if (Number.isFinite(ts) && Date.now() - ts > staleAfterMs) {
|
|
443
|
+
await rm(lockPath, { force: true });
|
|
444
|
+
continue;
|
|
445
|
+
}
|
|
446
|
+
} catch {
|
|
447
|
+
continue;
|
|
448
|
+
}
|
|
449
|
+
if (Date.now() - start > maxWaitMs) throw new Error(`Timed out waiting for deploy artefact lock at ${lockPath}. Another \`devflare deploy\` may be running against the same artefact directory.`);
|
|
450
|
+
await new Promise((r) => setTimeout(r, pollMs));
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
async function releaseDeployArtefactLock(handle, lockPath) {
|
|
454
|
+
try {
|
|
455
|
+
await handle.close();
|
|
456
|
+
} catch {}
|
|
457
|
+
await rm(lockPath, { force: true });
|
|
458
|
+
}
|
|
459
|
+
//#endregion
|
|
460
|
+
//#region src/cli/commands/deploy/runtime.ts
|
|
461
|
+
async function resolveLocalWranglerExecutable(cwd, fs) {
|
|
462
|
+
const wranglerExecutablePath = resolvePackageSpecifier("wrangler/bin/wrangler.js", cwd);
|
|
463
|
+
try {
|
|
464
|
+
await fs.access(wranglerExecutablePath);
|
|
465
|
+
return wranglerExecutablePath;
|
|
466
|
+
} catch {
|
|
467
|
+
return null;
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
//#endregion
|
|
471
|
+
//#region src/cli/commands/deploy/verification.ts
|
|
472
|
+
function shouldVerifyDeployControlPlane() {
|
|
473
|
+
const configured = process.env.DEVFLARE_VERIFY_DEPLOYMENT?.trim().toLowerCase();
|
|
474
|
+
if (!configured) return false;
|
|
475
|
+
return ![
|
|
476
|
+
"0",
|
|
477
|
+
"false",
|
|
478
|
+
"no",
|
|
479
|
+
"off"
|
|
480
|
+
].includes(configured);
|
|
481
|
+
}
|
|
482
|
+
function shouldRequireFreshProductionDeployment() {
|
|
483
|
+
const configured = process.env.DEVFLARE_REQUIRE_FRESH_PRODUCTION_DEPLOYMENT?.trim().toLowerCase();
|
|
484
|
+
if (!configured) return false;
|
|
485
|
+
return ![
|
|
486
|
+
"0",
|
|
487
|
+
"false",
|
|
488
|
+
"no",
|
|
489
|
+
"off"
|
|
490
|
+
].includes(configured);
|
|
491
|
+
}
|
|
492
|
+
function getDeployVerificationSettings() {
|
|
493
|
+
const attempts = Number.parseInt(process.env.DEVFLARE_VERIFY_DEPLOYMENT_ATTEMPTS ?? "", 10);
|
|
494
|
+
const delayMs = Number.parseInt(process.env.DEVFLARE_VERIFY_DEPLOYMENT_DELAY_MS ?? "", 10);
|
|
495
|
+
return {
|
|
496
|
+
attempts: Number.isFinite(attempts) && attempts > 0 ? attempts : 5,
|
|
497
|
+
delayMs: Number.isFinite(delayMs) && delayMs >= 0 ? delayMs : 1500
|
|
498
|
+
};
|
|
499
|
+
}
|
|
500
|
+
const DEPLOYMENT_LOOKBACK_TOLERANCE_MS = 120 * 1e3;
|
|
501
|
+
function normalizeCloudflareAccountId(value) {
|
|
502
|
+
const trimmed = value?.trim();
|
|
503
|
+
if (!trimmed) return;
|
|
504
|
+
return /^[a-f0-9]{32}$/i.test(trimmed) ? trimmed : void 0;
|
|
505
|
+
}
|
|
506
|
+
async function waitForDeployVerification(delayMs) {
|
|
507
|
+
if (delayMs <= 0) return;
|
|
508
|
+
await new Promise((resolve) => setTimeout(resolve, delayMs));
|
|
509
|
+
}
|
|
510
|
+
async function retryDeployVerification(description, operation) {
|
|
511
|
+
const { attempts, delayMs } = getDeployVerificationSettings();
|
|
512
|
+
let lastError;
|
|
513
|
+
for (let attempt = 1; attempt <= attempts; attempt++) try {
|
|
514
|
+
return await operation();
|
|
515
|
+
} catch (error) {
|
|
516
|
+
lastError = error;
|
|
517
|
+
if (attempt < attempts) await waitForDeployVerification(delayMs);
|
|
518
|
+
}
|
|
519
|
+
const message = lastError instanceof Error ? lastError.message : String(lastError);
|
|
520
|
+
throw new Error(`Cloudflare could not verify ${description} after ${attempts} attempt${attempts === 1 ? "" : "s"}: ${message}`);
|
|
521
|
+
}
|
|
522
|
+
async function resolveDeployAccountId(preferredAccountId) {
|
|
523
|
+
if (preferredAccountId !== void 0) return normalizeCloudflareAccountId(preferredAccountId);
|
|
524
|
+
const apiToken = process.env.CLOUDFLARE_API_TOKEN?.trim();
|
|
525
|
+
const apiKey = process.env.CLOUDFLARE_API_KEY?.trim();
|
|
526
|
+
const apiEmail = process.env.CLOUDFLARE_EMAIL?.trim();
|
|
527
|
+
if (!apiToken && !(apiKey && apiEmail)) return;
|
|
528
|
+
try {
|
|
529
|
+
const primaryAccount = await getPrimaryAccount();
|
|
530
|
+
if (!primaryAccount) return;
|
|
531
|
+
return normalizeCloudflareAccountId((await getEffectiveAccountId(primaryAccount.id)).accountId);
|
|
532
|
+
} catch {
|
|
533
|
+
return;
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
function selectDeploymentVersionId(deployment) {
|
|
537
|
+
return deployment.versions.find((version) => version.percentage === 100)?.versionId ?? deployment.versions[0]?.versionId;
|
|
538
|
+
}
|
|
539
|
+
function getWorkerVersionTimestamp(version) {
|
|
540
|
+
return version.metadata.modifiedOn ?? version.metadata.createdOn;
|
|
541
|
+
}
|
|
542
|
+
async function resolveVersionIdFromLatestDeployment(options) {
|
|
543
|
+
return retryDeployVerification(options.verificationDescription, async () => {
|
|
544
|
+
const latestDeployment = [...await listWorkerDeployments(options.accountId, options.workerName)].sort((a, b) => b.createdOn.getTime() - a.createdOn.getTime())[0];
|
|
545
|
+
if (!latestDeployment) throw new Error(`No deployments were found for Worker "${options.workerName}".`);
|
|
546
|
+
if (options.deployedAfter && latestDeployment.createdOn.getTime() < options.deployedAfter.getTime() - DEPLOYMENT_LOOKBACK_TOLERANCE_MS) throw new Error(`${options.deploymentLabel} ${latestDeployment.id} was created before this deploy started.`);
|
|
547
|
+
const versionId = selectDeploymentVersionId(latestDeployment);
|
|
548
|
+
if (!versionId) throw new Error(`${options.deploymentLabel} ${latestDeployment.id} does not reference any version ids.`);
|
|
549
|
+
return {
|
|
550
|
+
deploymentId: latestDeployment.id,
|
|
551
|
+
versionId
|
|
552
|
+
};
|
|
553
|
+
});
|
|
554
|
+
}
|
|
555
|
+
async function resolveVersionIdFromLatestWorkerVersion(options) {
|
|
556
|
+
return retryDeployVerification(`the latest ${options.preview ? "preview " : ""}version for Worker "${options.workerName}"`, async () => {
|
|
557
|
+
const latestVersion = [...await listWorkerVersions(options.accountId, options.workerName)].filter((version) => version.id).filter((version) => version.metadata.hasPreview === options.preview).sort((a, b) => {
|
|
558
|
+
const left = getWorkerVersionTimestamp(a)?.getTime() ?? 0;
|
|
559
|
+
return (getWorkerVersionTimestamp(b)?.getTime() ?? 0) - left;
|
|
560
|
+
})[0];
|
|
561
|
+
if (!latestVersion) throw new Error(`No ${options.preview ? "preview " : ""}versions were found for Worker "${options.workerName}".`);
|
|
562
|
+
const latestVersionTimestamp = getWorkerVersionTimestamp(latestVersion);
|
|
563
|
+
if (!latestVersionTimestamp) throw new Error(`Latest version ${latestVersion.id} did not include a creation timestamp.`);
|
|
564
|
+
if (latestVersionTimestamp.getTime() < options.deployedAfter.getTime() - DEPLOYMENT_LOOKBACK_TOLERANCE_MS) throw new Error(`Latest version ${latestVersion.id} was created before this deploy started.`);
|
|
565
|
+
return latestVersion.id;
|
|
566
|
+
});
|
|
567
|
+
}
|
|
568
|
+
async function resolveVersionIdFromLatestProductionDeployment(options) {
|
|
569
|
+
return resolveVersionIdFromLatestDeployment({
|
|
570
|
+
accountId: options.accountId,
|
|
571
|
+
workerName: options.workerName,
|
|
572
|
+
verificationDescription: `the latest deployment for Worker "${options.workerName}"`,
|
|
573
|
+
deploymentLabel: "Latest deployment",
|
|
574
|
+
deployedAfter: options.deployedAfter
|
|
575
|
+
});
|
|
576
|
+
}
|
|
577
|
+
async function resolveVersionIdFromCurrentProductionDeployment(options) {
|
|
578
|
+
return resolveVersionIdFromLatestDeployment({
|
|
579
|
+
accountId: options.accountId,
|
|
580
|
+
workerName: options.workerName,
|
|
581
|
+
verificationDescription: `the current active deployment for Worker "${options.workerName}"`,
|
|
582
|
+
deploymentLabel: "Current deployment"
|
|
583
|
+
});
|
|
584
|
+
}
|
|
585
|
+
async function verifyDeployControlPlane(options) {
|
|
586
|
+
logLine(options.logger, dim("Verifying Cloudflare control-plane state…", options.theme));
|
|
587
|
+
await retryDeployVerification(`Worker version ${options.versionId}`, async () => {
|
|
588
|
+
const version = await getWorkerVersionDetail(options.accountId, options.workerName, options.versionId);
|
|
589
|
+
if (!version.id) throw new Error(`Cloudflare returned an empty version record for ${options.versionId}.`);
|
|
590
|
+
return version;
|
|
591
|
+
});
|
|
592
|
+
if (options.preview) {
|
|
593
|
+
options.logger.success(`Verified preview upload in Cloudflare control plane for version ${options.versionId}`);
|
|
594
|
+
return;
|
|
595
|
+
}
|
|
596
|
+
const deployment = await retryDeployVerification(`a deployment that references version ${options.versionId}`, async () => {
|
|
597
|
+
const match = (await listWorkerDeployments(options.accountId, options.workerName)).find((item) => item.versions.some((version) => version.versionId === options.versionId));
|
|
598
|
+
if (!match) throw new Error(`No deployment for Worker "${options.workerName}" references version ${options.versionId} yet.`);
|
|
599
|
+
return match;
|
|
600
|
+
});
|
|
601
|
+
options.logger.success(`Verified Cloudflare deployment ${deployment.id} for version ${options.versionId}`);
|
|
602
|
+
}
|
|
603
|
+
//#endregion
|
|
604
|
+
//#region src/cli/commands/deploy.ts
|
|
605
|
+
async function runDeployCommand(parsed, logger, options) {
|
|
606
|
+
let deployTarget = {
|
|
607
|
+
mode: "implicit",
|
|
608
|
+
envOverrides: {}
|
|
609
|
+
};
|
|
610
|
+
let resolvedParsed = parsed;
|
|
611
|
+
const cwd = options.cwd || process.cwd();
|
|
612
|
+
let configPath;
|
|
613
|
+
let environment;
|
|
614
|
+
let dryRun = false;
|
|
615
|
+
let preview = false;
|
|
616
|
+
let branchName;
|
|
617
|
+
let deployMessage;
|
|
618
|
+
let deployTag;
|
|
619
|
+
let previewScopeName;
|
|
620
|
+
let rolloutPercentage;
|
|
621
|
+
let rolloutPreviousVersionId;
|
|
622
|
+
let requireFreshProductionDeployment = false;
|
|
623
|
+
let resolvedPreviewScopeName = process.env.DEVFLARE_PREVIEW_BRANCH?.trim() || void 0;
|
|
624
|
+
const theme = createCliTheme(parsed.options);
|
|
625
|
+
logLine(logger);
|
|
626
|
+
logLine(logger, `${yellowBold("deploy", theme)} ${dim("Shipping to Cloudflare", theme)}`);
|
|
627
|
+
try {
|
|
628
|
+
deployTarget = resolveDeployTarget(parsed, { requireExplicitTarget: options.requireExplicitDeployTarget === true });
|
|
629
|
+
resolvedParsed = applyResolvedDeployTarget(parsed, deployTarget);
|
|
630
|
+
configPath = resolvedParsed.options.config;
|
|
631
|
+
environment = resolvedParsed.options.env;
|
|
632
|
+
dryRun = resolvedParsed.options["dry-run"] === true;
|
|
633
|
+
preview = deployTarget.mode === "preview-upload";
|
|
634
|
+
branchName = resolvedParsed.options["branch-name"];
|
|
635
|
+
deployMessage = resolvedParsed.options.message;
|
|
636
|
+
deployTag = resolvedParsed.options.tag;
|
|
637
|
+
rolloutPercentage = parseDeployPercentage(resolvedParsed.options.percentage);
|
|
638
|
+
rolloutPreviousVersionId = typeof resolvedParsed.options.version === "string" ? resolvedParsed.options.version.trim() || void 0 : void 0;
|
|
639
|
+
if (rolloutPercentage !== void 0 && deployTarget.mode !== "production") throw new Error("--percentage is a production gradual rollout and is only valid with an explicit production target. Run `devflare deploy --prod --percentage <n>` (it cannot be combined with --preview or a named/branch preview deploy).");
|
|
640
|
+
previewScopeName = branchName?.trim() || deployTarget.previewScopeRaw || void 0;
|
|
641
|
+
resolvedPreviewScopeName = previewScopeName || process.env.DEVFLARE_PREVIEW_BRANCH?.trim() || void 0;
|
|
642
|
+
requireFreshProductionDeployment = !preview && shouldRequireFreshProductionDeployment();
|
|
643
|
+
return await withTemporaryEnvironment(deployTarget.envOverrides, async () => {
|
|
644
|
+
resolvedPreviewScopeName = previewScopeName || process.env.DEVFLARE_PREVIEW_BRANCH?.trim() || void 0;
|
|
645
|
+
if (dryRun) {
|
|
646
|
+
const deploymentStrategy = applyDeploymentStrategy(await resolveConfigEnvVars(resolveConfigForEnvironment(await loadConfig({
|
|
647
|
+
cwd,
|
|
648
|
+
configFile: configPath
|
|
649
|
+
}), environment), {
|
|
650
|
+
cwd,
|
|
651
|
+
configPath,
|
|
652
|
+
mode: "build"
|
|
653
|
+
}), {
|
|
654
|
+
environment,
|
|
655
|
+
preview,
|
|
656
|
+
branchName,
|
|
657
|
+
previewBranch: process.env.DEVFLARE_PREVIEW_BRANCH
|
|
658
|
+
});
|
|
659
|
+
const wranglerConfig = compileBuildConfig(deploymentStrategy.config, void 0, { alreadyResolved: true });
|
|
660
|
+
logLine(logger, `${yellow("dry run", theme)} ${dim("Skipping actual deployment", theme)}`);
|
|
661
|
+
if (rolloutPercentage !== void 0) logLine(logger, dim(`Would upload a new Worker version and route ${rolloutPercentage}% of production traffic to it via \`wrangler versions deploy\`${rolloutPreviousVersionId ? `, keeping ${100 - rolloutPercentage}% on version ${rolloutPreviousVersionId}` : ""}.`, theme));
|
|
662
|
+
const deploymentStrategyMessage = describeDeploymentStrategy(deploymentStrategy);
|
|
663
|
+
if (deploymentStrategyMessage) logLine(logger, dim(deploymentStrategyMessage, theme));
|
|
664
|
+
logLine(logger, dim("Would deploy with wrangler config:", theme));
|
|
665
|
+
logLine(logger, stringifyConfig(wranglerConfig));
|
|
666
|
+
try {
|
|
667
|
+
const describeResult = await prepareConfigResourcesForDeploy(deploymentStrategy.config, {
|
|
668
|
+
environment,
|
|
669
|
+
describeOnly: true
|
|
670
|
+
});
|
|
671
|
+
const resolvedWranglerConfig = compileConfig(describeResult.config);
|
|
672
|
+
logLine(logger, dim("Resolved view (would-create placeholders for missing resources):", theme));
|
|
673
|
+
logLine(logger, stringifyConfig(resolvedWranglerConfig));
|
|
674
|
+
const wouldCreate = [
|
|
675
|
+
...describeResult.created.kv.map((n) => `KV: ${n}`),
|
|
676
|
+
...describeResult.created.d1.map((n) => `D1: ${n}`),
|
|
677
|
+
...describeResult.created.r2.map((n) => `R2: ${n}`),
|
|
678
|
+
...describeResult.created.queues.map((n) => `Queue: ${n}`)
|
|
679
|
+
];
|
|
680
|
+
if (wouldCreate.length > 0) logLine(logger, dim(`Would create:\n - ${wouldCreate.join("\n - ")}`, theme));
|
|
681
|
+
} catch (describeErr) {
|
|
682
|
+
logLine(logger, dim(`(resolved view unavailable: ${describeErr.message})`, theme));
|
|
683
|
+
}
|
|
684
|
+
return { exitCode: 0 };
|
|
685
|
+
}
|
|
686
|
+
const deps = await getDependencies();
|
|
687
|
+
const requestedBuildPath = resolvedParsed.options.build;
|
|
688
|
+
const buildConfigPath = requestedBuildPath ? await resolveBuildArtifactConfigPath(requestedBuildPath, cwd) : (await prepareBuildArtifacts(resolvedParsed, logger, options)).deployConfigPath;
|
|
689
|
+
const prepared = await prepareDeployConfig({
|
|
690
|
+
cwd,
|
|
691
|
+
configPath,
|
|
692
|
+
environment,
|
|
693
|
+
buildConfigPath,
|
|
694
|
+
preview,
|
|
695
|
+
branchName,
|
|
696
|
+
logger,
|
|
697
|
+
force: resolvedParsed.options.force === true
|
|
698
|
+
});
|
|
699
|
+
const createdPreviewResourcesSummary = prepared.previewScopedResources ? summarizeDeployResourceNames(prepared.previewScopedResources.created) : null;
|
|
700
|
+
if (createdPreviewResourcesSummary) logLine(logger, `Provisioned preview-scoped resources: ${createdPreviewResourcesSummary}`);
|
|
701
|
+
const existingPreviewResourcesSummary = prepared.previewScopedResources ? summarizeDeployResourceNames(prepared.previewScopedResources.existing) : null;
|
|
702
|
+
if (existingPreviewResourcesSummary) logLine(logger, `Reused preview-scoped resources: ${existingPreviewResourcesSummary}`);
|
|
703
|
+
const createdDeployResourcesSummary = summarizeDeployResourceNames(prepared.deployResources.created);
|
|
704
|
+
if (createdDeployResourcesSummary) logLine(logger, `Provisioned deploy resources: ${createdDeployResourcesSummary}`);
|
|
705
|
+
const existingDeployResourcesSummary = summarizeDeployResourceNames(prepared.deployResources.existing);
|
|
706
|
+
if (existingDeployResourcesSummary) logLine(logger, `Reused deploy resources: ${existingDeployResourcesSummary}`);
|
|
707
|
+
for (const warning of prepared.previewScopedResources?.warnings ?? []) logger.warn(warning);
|
|
708
|
+
for (const warning of prepared.deployResources.warnings) logger.warn(warning);
|
|
709
|
+
if (requestedBuildPath) logLine(logger, `${dim("build", theme)} ${green(buildConfigPath, theme)}`);
|
|
710
|
+
logLine(logger, `${dim("worker", theme)} ${green(prepared.config.name, theme)}`);
|
|
711
|
+
const localWranglerExecutable = await resolveLocalWranglerExecutable(cwd, deps.fs);
|
|
712
|
+
const isBranchScopedPreviewDeployment = !preview && environment === "preview" && typeof resolvedPreviewScopeName === "string" && resolvedPreviewScopeName.length > 0;
|
|
713
|
+
if (preview) {
|
|
714
|
+
logger.warn("Cloudflare preview uploads cannot be the first upload for a brand-new Worker.");
|
|
715
|
+
if (prepared.config.bindings?.durableObjects && Object.keys(prepared.config.bindings.durableObjects).length > 0) logger.warn("Cloudflare does not currently generate preview URLs for Workers that implement Durable Objects.");
|
|
716
|
+
if (prepared.config.migrations && prepared.config.migrations.length > 0) logger.warn("Cloudflare versions upload does not currently support Durable Object migrations.");
|
|
717
|
+
}
|
|
718
|
+
const usePercentageRollout = !preview && !isBranchScopedPreviewDeployment && rolloutPercentage !== void 0;
|
|
719
|
+
const uploadVersionOnly = preview || usePercentageRollout;
|
|
720
|
+
logLine(logger, dim(preview ? "Uploading preview version with Wrangler…" : usePercentageRollout ? "Uploading new Worker version with Wrangler…" : "Deploying with Wrangler…", theme));
|
|
721
|
+
const deployStartedAt = /* @__PURE__ */ new Date();
|
|
722
|
+
const wranglerOutputDirectory = join(cwd, ".devflare");
|
|
723
|
+
const wranglerOutputFilePath = join(wranglerOutputDirectory, `wrangler-output-${Date.now()}-${process.pid}.ndjson`);
|
|
724
|
+
await deps.fs.mkdir(wranglerOutputDirectory, { recursive: true });
|
|
725
|
+
const wranglerCommand = localWranglerExecutable ? "node" : "bunx";
|
|
726
|
+
const wranglerArgs = uploadVersionOnly ? localWranglerExecutable ? [
|
|
727
|
+
localWranglerExecutable,
|
|
728
|
+
"versions",
|
|
729
|
+
"upload"
|
|
730
|
+
] : [
|
|
731
|
+
"wrangler",
|
|
732
|
+
"versions",
|
|
733
|
+
"upload"
|
|
734
|
+
] : localWranglerExecutable ? [localWranglerExecutable, "deploy"] : ["wrangler", "deploy"];
|
|
735
|
+
wranglerArgs.push("--config", prepared.deployConfigPath);
|
|
736
|
+
if (deployMessage?.trim()) wranglerArgs.push("--message", deployMessage.trim());
|
|
737
|
+
if (deployTag?.trim()) wranglerArgs.push("--tag", deployTag.trim());
|
|
738
|
+
const deployProc = await deps.exec.exec(wranglerCommand, wranglerArgs, {
|
|
739
|
+
cwd,
|
|
740
|
+
stdio: "inherit",
|
|
741
|
+
env: {
|
|
742
|
+
...process.env,
|
|
743
|
+
WRANGLER_OUTPUT_FILE_PATH: wranglerOutputFilePath,
|
|
744
|
+
FORCE_COLOR: process.env.FORCE_COLOR ?? "0"
|
|
745
|
+
}
|
|
746
|
+
});
|
|
747
|
+
let structuredOutput = "";
|
|
748
|
+
try {
|
|
749
|
+
structuredOutput = await deps.fs.readFile(wranglerOutputFilePath, "utf8");
|
|
750
|
+
} catch {
|
|
751
|
+
structuredOutput = "";
|
|
752
|
+
} finally {
|
|
753
|
+
try {
|
|
754
|
+
await deps.fs.unlink(wranglerOutputFilePath);
|
|
755
|
+
} catch {}
|
|
756
|
+
}
|
|
757
|
+
const parsedOutput = mergeParsedWranglerDeployOutputs(parseWranglerDeployOutput([deployProc.stdout, deployProc.stderr].filter((value) => typeof value === "string" && value.length > 0).join("\n")), structuredOutput ? parseWranglerStructuredOutput(structuredOutput) : {
|
|
758
|
+
urls: [],
|
|
759
|
+
versionId: void 0,
|
|
760
|
+
previewUrl: void 0
|
|
761
|
+
});
|
|
762
|
+
const workersDevUrl = parsedOutput.urls.find((url) => url.includes("workers.dev"));
|
|
763
|
+
let resolvedAccountId = normalizeCloudflareAccountId(prepared.config.accountId) ?? normalizeCloudflareAccountId(process.env.CLOUDFLARE_ACCOUNT_ID);
|
|
764
|
+
let didAttemptAccountResolution = false;
|
|
765
|
+
const versionRecoveryDiagnostics = [];
|
|
766
|
+
const ensureResolvedAccountId = async () => {
|
|
767
|
+
if (resolvedAccountId || didAttemptAccountResolution) return resolvedAccountId;
|
|
768
|
+
didAttemptAccountResolution = true;
|
|
769
|
+
resolvedAccountId = await resolveDeployAccountId(void 0);
|
|
770
|
+
return resolvedAccountId;
|
|
771
|
+
};
|
|
772
|
+
let resolvedVersionId = parsedOutput.versionId;
|
|
773
|
+
let resolvedPreviewUrl = parsedOutput.previewUrl;
|
|
774
|
+
let loggedVersionId = false;
|
|
775
|
+
let verificationNote;
|
|
776
|
+
const persistDeployMetadata = async (input) => {
|
|
777
|
+
await writeDeployResultMetadata({
|
|
778
|
+
status: input.status,
|
|
779
|
+
exitCode: input.exitCode,
|
|
780
|
+
workerName: prepared.config.name,
|
|
781
|
+
preview,
|
|
782
|
+
branchScopedPreview: isBranchScopedPreviewDeployment,
|
|
783
|
+
previewScope: resolvedPreviewScopeName,
|
|
784
|
+
versionId: resolvedVersionId,
|
|
785
|
+
previewUrl: resolvedPreviewUrl,
|
|
786
|
+
workersDevUrl,
|
|
787
|
+
verificationNote,
|
|
788
|
+
outputUrls: parsedOutput.urls,
|
|
789
|
+
structuredOutput,
|
|
790
|
+
...input.error ? { error: input.error } : {}
|
|
791
|
+
});
|
|
792
|
+
};
|
|
793
|
+
if (deployProc.exitCode !== 0) {
|
|
794
|
+
await persistDeployMetadata({
|
|
795
|
+
status: "failure",
|
|
796
|
+
exitCode: 1,
|
|
797
|
+
error: deployProc.stderr || deployProc.stdout || "Wrangler deploy failed"
|
|
798
|
+
});
|
|
799
|
+
logger.error("Deployment failed");
|
|
800
|
+
return {
|
|
801
|
+
exitCode: 1,
|
|
802
|
+
output: structuredOutput
|
|
803
|
+
};
|
|
804
|
+
}
|
|
805
|
+
if (!preview && !resolvedVersionId && !isBranchScopedPreviewDeployment) resolvedAccountId = await ensureResolvedAccountId();
|
|
806
|
+
if (isBranchScopedPreviewDeployment && !resolvedPreviewUrl) resolvedAccountId = await ensureResolvedAccountId();
|
|
807
|
+
if (isBranchScopedPreviewDeployment && !resolvedPreviewUrl && resolvedAccountId) {
|
|
808
|
+
const workersSubdomain = await getWorkersSubdomain(resolvedAccountId);
|
|
809
|
+
if (workersSubdomain) resolvedPreviewUrl = formatWorkersDevUrl(prepared.config.name, workersSubdomain);
|
|
810
|
+
}
|
|
811
|
+
if (!resolvedVersionId && resolvedAccountId) try {
|
|
812
|
+
resolvedVersionId = await resolveVersionIdFromLatestWorkerVersion({
|
|
813
|
+
accountId: resolvedAccountId,
|
|
814
|
+
workerName: prepared.config.name,
|
|
815
|
+
preview: preview || isBranchScopedPreviewDeployment,
|
|
816
|
+
deployedAfter: deployStartedAt
|
|
817
|
+
});
|
|
818
|
+
logger.success(`Version ID: ${resolvedVersionId}`);
|
|
819
|
+
loggedVersionId = true;
|
|
820
|
+
logLine(logger, dim("Resolved version id from Cloudflare version metadata", theme));
|
|
821
|
+
} catch (error) {
|
|
822
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
823
|
+
versionRecoveryDiagnostics.push(`version lookup: ${message}`);
|
|
824
|
+
}
|
|
825
|
+
if (isBranchScopedPreviewDeployment && !resolvedVersionId && resolvedAccountId) try {
|
|
826
|
+
const fallbackDeployment = await resolveVersionIdFromLatestProductionDeployment({
|
|
827
|
+
accountId: resolvedAccountId,
|
|
828
|
+
workerName: prepared.config.name,
|
|
829
|
+
deployedAfter: deployStartedAt
|
|
830
|
+
});
|
|
831
|
+
resolvedVersionId = fallbackDeployment.versionId;
|
|
832
|
+
logger.success(`Version ID: ${resolvedVersionId}`);
|
|
833
|
+
loggedVersionId = true;
|
|
834
|
+
logLine(logger, dim(`Resolved version id from Cloudflare deployment ${fallbackDeployment.deploymentId}`, theme));
|
|
835
|
+
} catch (error) {
|
|
836
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
837
|
+
versionRecoveryDiagnostics.push(`deployment lookup: ${message}`);
|
|
838
|
+
}
|
|
839
|
+
if (!preview && !isBranchScopedPreviewDeployment && !usePercentageRollout && !resolvedVersionId && resolvedAccountId) try {
|
|
840
|
+
const fallbackDeployment = await resolveVersionIdFromLatestProductionDeployment({
|
|
841
|
+
accountId: resolvedAccountId,
|
|
842
|
+
workerName: prepared.config.name,
|
|
843
|
+
deployedAfter: deployStartedAt
|
|
844
|
+
});
|
|
845
|
+
resolvedVersionId = fallbackDeployment.versionId;
|
|
846
|
+
logger.success(`Version ID: ${resolvedVersionId}`);
|
|
847
|
+
loggedVersionId = true;
|
|
848
|
+
logLine(logger, dim(`Resolved version id from Cloudflare deployment ${fallbackDeployment.deploymentId}`, theme));
|
|
849
|
+
} catch (error) {
|
|
850
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
851
|
+
versionRecoveryDiagnostics.push(`deployment lookup: ${message}`);
|
|
852
|
+
}
|
|
853
|
+
if (!preview && !isBranchScopedPreviewDeployment && !usePercentageRollout && !resolvedVersionId && resolvedAccountId) try {
|
|
854
|
+
const currentDeployment = await resolveVersionIdFromCurrentProductionDeployment({
|
|
855
|
+
accountId: resolvedAccountId,
|
|
856
|
+
workerName: prepared.config.name
|
|
857
|
+
});
|
|
858
|
+
resolvedVersionId = currentDeployment.versionId;
|
|
859
|
+
logger.success(`Version ID: ${resolvedVersionId}`);
|
|
860
|
+
loggedVersionId = true;
|
|
861
|
+
const reuseMessage = `Cloudflare did not expose a fresh deployment or version after verification retries, and the current active deployment ${currentDeployment.deploymentId} still points at version ${resolvedVersionId}. This usually means the built Worker code and configuration were unchanged, so Cloudflare kept the existing live version.`;
|
|
862
|
+
verificationNote = reuseMessage;
|
|
863
|
+
if (requireFreshProductionDeployment) {
|
|
864
|
+
await persistDeployMetadata({
|
|
865
|
+
status: "failure",
|
|
866
|
+
exitCode: 1,
|
|
867
|
+
error: reuseMessage
|
|
868
|
+
});
|
|
869
|
+
logger.error(`Deployment verification failed: ${reuseMessage} This run requires a fresh production deployment, so Devflare is treating the reused live version as a failure.`);
|
|
870
|
+
return {
|
|
871
|
+
exitCode: 1,
|
|
872
|
+
output: structuredOutput
|
|
873
|
+
};
|
|
874
|
+
}
|
|
875
|
+
logger.warn(`Deployment verification note: ${reuseMessage}`);
|
|
876
|
+
} catch (error) {
|
|
877
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
878
|
+
versionRecoveryDiagnostics.push(`current production deployment: ${message}`);
|
|
879
|
+
}
|
|
880
|
+
if (resolvedVersionId && !loggedVersionId) logger.success(`Version ID: ${resolvedVersionId}`);
|
|
881
|
+
if (isBranchScopedPreviewDeployment && !resolvedPreviewUrl && resolvedAccountId) {
|
|
882
|
+
const workersSubdomain = await getWorkersSubdomain(resolvedAccountId);
|
|
883
|
+
if (workersSubdomain) resolvedPreviewUrl = formatWorkersDevUrl(prepared.config.name, workersSubdomain);
|
|
884
|
+
}
|
|
885
|
+
if ((preview || isBranchScopedPreviewDeployment) && resolvedPreviewUrl) logLine(logger, `Preview URL: ${resolvedPreviewUrl}`);
|
|
886
|
+
if (shouldVerifyDeployControlPlane()) {
|
|
887
|
+
if (!resolvedVersionId) {
|
|
888
|
+
const recoveryDetails = versionRecoveryDiagnostics.length > 0 ? ` Cloudflare fallback checks also failed: ${versionRecoveryDiagnostics.join(" | ")}` : "";
|
|
889
|
+
await persistDeployMetadata({
|
|
890
|
+
status: "failure",
|
|
891
|
+
exitCode: 1,
|
|
892
|
+
error: `Wrangler did not return a Worker version id, so Devflare could not prove which version Cloudflare accepted.${recoveryDetails}`
|
|
893
|
+
});
|
|
894
|
+
logger.error(`Deployment verification failed: Wrangler did not return a Worker version id, so Devflare could not prove which version Cloudflare accepted.${recoveryDetails}`);
|
|
895
|
+
return {
|
|
896
|
+
exitCode: 1,
|
|
897
|
+
output: structuredOutput
|
|
898
|
+
};
|
|
899
|
+
}
|
|
900
|
+
resolvedAccountId = await ensureResolvedAccountId();
|
|
901
|
+
if (!resolvedAccountId) {
|
|
902
|
+
await persistDeployMetadata({
|
|
903
|
+
status: "failure",
|
|
904
|
+
exitCode: 1,
|
|
905
|
+
error: "Devflare could not resolve a Cloudflare account id."
|
|
906
|
+
});
|
|
907
|
+
logger.error("Deployment verification failed: Devflare could not resolve a Cloudflare account id. Pass cloudflare-account-id to the action or set accountId in devflare.config.ts.");
|
|
908
|
+
return {
|
|
909
|
+
exitCode: 1,
|
|
910
|
+
output: structuredOutput
|
|
911
|
+
};
|
|
912
|
+
}
|
|
913
|
+
try {
|
|
914
|
+
await verifyDeployControlPlane({
|
|
915
|
+
accountId: resolvedAccountId,
|
|
916
|
+
workerName: prepared.config.name,
|
|
917
|
+
versionId: resolvedVersionId,
|
|
918
|
+
preview: preview || usePercentageRollout,
|
|
919
|
+
logger,
|
|
920
|
+
theme
|
|
921
|
+
});
|
|
922
|
+
} catch (error) {
|
|
923
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
924
|
+
await persistDeployMetadata({
|
|
925
|
+
status: "failure",
|
|
926
|
+
exitCode: 1,
|
|
927
|
+
error: message
|
|
928
|
+
});
|
|
929
|
+
logger.error(`Deployment verification failed: ${message}`);
|
|
930
|
+
return {
|
|
931
|
+
exitCode: 1,
|
|
932
|
+
output: structuredOutput
|
|
933
|
+
};
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
if (usePercentageRollout) {
|
|
937
|
+
if (!resolvedVersionId) {
|
|
938
|
+
const recoveryDetails = versionRecoveryDiagnostics.length > 0 ? ` Cloudflare fallback checks also failed: ${versionRecoveryDiagnostics.join(" | ")}` : "";
|
|
939
|
+
const rolloutError = `A new Worker version was uploaded, but Devflare could not resolve its version id, so it could not start the ${rolloutPercentage}% gradual rollout. Re-run \`devflare deploy --prod --percentage ${rolloutPercentage}\`, or split traffic manually with \`wrangler versions deploy\`.${recoveryDetails}`;
|
|
940
|
+
await persistDeployMetadata({
|
|
941
|
+
status: "failure",
|
|
942
|
+
exitCode: 1,
|
|
943
|
+
error: rolloutError
|
|
944
|
+
});
|
|
945
|
+
logger.error(rolloutError);
|
|
946
|
+
return {
|
|
947
|
+
exitCode: 1,
|
|
948
|
+
output: structuredOutput
|
|
949
|
+
};
|
|
950
|
+
}
|
|
951
|
+
const rolloutInvocation = buildGradualDeployInvocation({
|
|
952
|
+
versionId: resolvedVersionId,
|
|
953
|
+
percentage: rolloutPercentage,
|
|
954
|
+
previousVersionId: rolloutPreviousVersionId,
|
|
955
|
+
workerName: prepared.config.name,
|
|
956
|
+
message: deployMessage?.trim() || void 0
|
|
957
|
+
}, localWranglerExecutable);
|
|
958
|
+
logLine(logger, dim(`Routing ${rolloutPercentage}% of production traffic to the new version with Wrangler…`, theme));
|
|
959
|
+
const rolloutProc = await deps.exec.exec(rolloutInvocation.command, rolloutInvocation.args, {
|
|
960
|
+
cwd,
|
|
961
|
+
stdio: "inherit",
|
|
962
|
+
env: {
|
|
963
|
+
...process.env,
|
|
964
|
+
FORCE_COLOR: process.env.FORCE_COLOR ?? "0"
|
|
965
|
+
}
|
|
966
|
+
});
|
|
967
|
+
if (rolloutProc.exitCode !== 0) {
|
|
968
|
+
const rolloutError = `The new Worker version ${resolvedVersionId} was uploaded, but \`wrangler versions deploy\` failed to route ${rolloutPercentage}% of production traffic to it. Re-run the rollout, or split traffic manually with \`wrangler versions deploy\`.`;
|
|
969
|
+
await persistDeployMetadata({
|
|
970
|
+
status: "failure",
|
|
971
|
+
exitCode: 1,
|
|
972
|
+
error: rolloutProc.stderr || rolloutProc.stdout || rolloutError
|
|
973
|
+
});
|
|
974
|
+
logger.error(rolloutError);
|
|
975
|
+
return {
|
|
976
|
+
exitCode: 1,
|
|
977
|
+
output: structuredOutput
|
|
978
|
+
};
|
|
979
|
+
}
|
|
980
|
+
logger.success(`Routed ${rolloutPercentage}% of production traffic to version ${resolvedVersionId}`);
|
|
981
|
+
}
|
|
982
|
+
if (resolvedAccountId) {
|
|
983
|
+
const previewRegistryScope = isBranchScopedPreviewDeployment ? deployTarget.previewScope : void 0;
|
|
984
|
+
const previewRegistryUrl = preview || isBranchScopedPreviewDeployment ? resolvedPreviewUrl : void 0;
|
|
985
|
+
try {
|
|
986
|
+
await reconcilePreviewRegistry({
|
|
987
|
+
accountId: resolvedAccountId,
|
|
988
|
+
workerName: prepared.config.name,
|
|
989
|
+
versionId: resolvedVersionId,
|
|
990
|
+
previewScope: previewRegistryScope,
|
|
991
|
+
previewUrl: previewRegistryUrl,
|
|
992
|
+
branchName: resolvedPreviewScopeName,
|
|
993
|
+
commitSha: process.env.GITHUB_SHA,
|
|
994
|
+
source: inferRecordSource(),
|
|
995
|
+
deploymentMessage: process.env.GITHUB_EVENT_NAME,
|
|
996
|
+
logger
|
|
997
|
+
});
|
|
998
|
+
} catch (error) {
|
|
999
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1000
|
+
logger.warn(`Devflare preview registry sync failed: ${message}`);
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
await persistDeployMetadata({
|
|
1004
|
+
status: "success",
|
|
1005
|
+
exitCode: 0
|
|
1006
|
+
});
|
|
1007
|
+
logger.success("Deployed successfully!");
|
|
1008
|
+
if (!preview && !isBranchScopedPreviewDeployment) logLine(logger, dim("Runtime secrets: set production secret values with `wrangler secret put` or the Cloudflare dashboard. Devflare manages local secret values (`devflare secrets --local`) and emits Secrets Store references only — it never sends secret values to Cloudflare.", theme));
|
|
1009
|
+
return {
|
|
1010
|
+
exitCode: 0,
|
|
1011
|
+
output: structuredOutput
|
|
1012
|
+
};
|
|
1013
|
+
});
|
|
1014
|
+
} catch (error) {
|
|
1015
|
+
await writeDeployResultMetadata({
|
|
1016
|
+
status: "failure",
|
|
1017
|
+
exitCode: 1,
|
|
1018
|
+
preview,
|
|
1019
|
+
branchScopedPreview: !preview && environment === "preview" && Boolean(resolvedPreviewScopeName),
|
|
1020
|
+
previewScope: resolvedPreviewScopeName,
|
|
1021
|
+
outputUrls: [],
|
|
1022
|
+
...error instanceof Error ? { error: error.message } : { error: String(error) }
|
|
1023
|
+
});
|
|
1024
|
+
if (error instanceof Error) {
|
|
1025
|
+
logger.error("Deployment failed:", error.message);
|
|
1026
|
+
if (resolvedParsed.options.debug) logger.error(error.stack);
|
|
1027
|
+
}
|
|
1028
|
+
return { exitCode: 1 };
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1031
|
+
//#endregion
|
|
1032
|
+
export { runDeployCommand };
|