void 1.2.1 → 1.4.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/dist/{account-cmd-CdUll_35.mjs → account-cmd-HP8bixYo.mjs} +3 -3
- package/dist/{application-analysis-fEqoSeMp.mjs → application-analysis-DDOQwiXk.mjs} +18 -12
- package/dist/{application-routing-DAhNP4u3.mjs → application-routing-4719u_kf.mjs} +3 -1
- package/dist/auth-g2TQbDLD.d.mts +70 -0
- package/dist/{auth-link-C87vGXM-.mjs → auth-link-CedYpDCy.mjs} +3 -3
- package/dist/{auth-router-6I81r-ix.mjs → auth-router-vafo7x8w.mjs} +11 -6
- package/dist/{better-auth-shared-D-6z0q0f.mjs → better-auth-shared-7FM3Uk2N.mjs} +48 -2
- package/dist/{better-auth-shared-DVk2DkTW.d.mts → better-auth-shared-BHB8kiTE.d.mts} +1 -1
- package/dist/{build-cmd-ex1g-j_e.mjs → build-cmd-9vUAQ1_V.mjs} +1 -1
- package/dist/{cache-oHzrnY3z.mjs → cache-jvwLNb0h.mjs} +1 -1
- package/dist/{cancel-deploy-viAMD0Q_.mjs → cancel-deploy-Dw0UmWKO.mjs} +1 -1
- package/dist/{cf-build-output-BhVxldCw.mjs → cf-build-output-XpNR9zoh.mjs} +122 -5
- package/dist/cf-build-output-bd8Uwv1P.mjs +1 -0
- package/dist/{cf-worker-settings-BECvvTVd.mjs → cf-worker-settings-Dg27RzyT.mjs} +11 -5
- package/dist/cli/cli.mjs +41 -32
- package/dist/cli/cloudflare-operation-process.mjs +35 -8
- package/dist/cli/env-schema-probe.mjs +2 -2
- package/dist/{client-BEkdj1kx.mjs → client-B3LnB_bE.mjs} +8 -1
- package/dist/client-BZb9j66F.mjs +1 -0
- package/dist/{cloudflare-auth-Byo_0_N9.mjs → cloudflare-auth-DyD_kVFr.mjs} +1 -1
- package/dist/{cloudflare-cmd-DMzCv12s.mjs → cloudflare-cmd-D-b_u3T4.mjs} +2 -2
- package/dist/{cloudflare-config-DchHxPTo.mjs → cloudflare-config-CH1AylZT.mjs} +14 -3
- package/dist/{cloudflare-connect-CCRTVg-I.mjs → cloudflare-connect-zTJh8UnN.mjs} +2 -2
- package/dist/{cloudflare-operations-Dh9dEHJj.mjs → cloudflare-operations-Bc-7fN44.mjs} +4 -4
- package/dist/{cloudflare-operations-DsSaw2BT.mjs → cloudflare-operations-BtulCNOg.mjs} +1 -1
- package/dist/{config-BU6hMu1W.mjs → config-BV2ASlpn.mjs} +1 -1
- package/dist/{config-DQfHOKh9.d.mts → config-CAdZVTLN.d.mts} +4 -1
- package/dist/config-D-6q7EBH.mjs +87 -0
- package/dist/{config-DHgSEWT7.mjs → config-OFOAimzt.mjs} +5 -3
- package/dist/config-entry.d.mts +1 -1
- package/dist/{config-BIaXIkkv.mjs → config-tqMM6DwY.mjs} +1 -1
- package/dist/{connect-k7R2rPVA.mjs → connect-BOM6zvFX.mjs} +4 -4
- package/dist/{create-project-DV71ol5d.mjs → create-project-Bxd02EHN.mjs} +1 -1
- package/dist/{create-project-DTuy-l0z.mjs → create-project-C2K0DN2O.mjs} +1 -1
- package/dist/{db-DVOkLH5X.mjs → db-Cdvr3zwG.mjs} +18 -18
- package/dist/{db-types-NGxPwnlt.mjs → db-types-0eCiqYb1.mjs} +1 -1
- package/dist/{delete-BbP5eopu.mjs → delete-lETE6Tpt.mjs} +1 -1
- package/dist/deploy-CX94CmKa.mjs +2 -0
- package/dist/{deploy-7H32EnUs.mjs → deploy-CdM-LAxX.mjs} +473 -148
- package/dist/{deploy-managed-static-DlvcvnQT.mjs → deploy-managed-static-DjeBFG2c.mjs} +43 -20
- package/dist/{deploy-transport-BzGEj0Ge.mjs → deploy-transport-DIq_gFTP.mjs} +14 -13
- package/dist/deploy.d.mts +2 -0
- package/dist/deploy.mjs +8 -5
- package/dist/{dispatch-DoUnxTNo.mjs → dispatch-CLa2LThw.mjs} +76 -7
- package/dist/{domain-CA2wBgra.mjs → domain-DyhNtdYf.mjs} +2 -2
- package/dist/{email-DXpCc77w.mjs → email-DM2wDcBN.mjs} +59 -10
- package/dist/{email-cloudflare-D03g2TkS.mjs → email-cloudflare-PMbAev9Q.mjs} +124 -10
- package/dist/{env-DgOQ9_8S.mjs → env-78hbN-oI.mjs} +3 -3
- package/dist/{env-BJjULvL0.mjs → env-BaMz0j7H.mjs} +6 -1
- package/dist/{env-validation-Dwq3PJzK.mjs → env-validation-B3VobvXm.mjs} +2 -1
- package/dist/{env-validation-BmsdCZEk.mjs → env-validation-BUfFZ6bt.mjs} +1 -1
- package/dist/error-pages-CLIJ7aYq.mjs +37 -0
- package/dist/gen-BhWBT4iu.mjs +1 -0
- package/dist/{gen-BfmcIi2g.mjs → gen-CFmsUsW1.mjs} +3 -3
- package/dist/{github-cmd-CY9LUqLh.mjs → github-cmd-De-_IWbM.mjs} +1 -1
- package/dist/{handler-BbkSPzGF.d.mts → handler-BHktmuTL.d.mts} +4 -2
- package/dist/{headers-D522zd0A.mjs → headers--vaK_chu.mjs} +1 -1
- package/dist/{help-CxSlPpzJ.mjs → help-CKbrhZha.mjs} +16 -1
- package/dist/help-qOZr3wng.mjs +1 -0
- package/dist/index.d.mts +3 -5
- package/dist/index.mjs +370 -140
- package/dist/{info-7VDlhtyy.mjs → info-Yg0-V5Rs.mjs} +4 -4
- package/dist/{init-DxYyOs4-.mjs → init-CDiJQycf.mjs} +241 -206
- package/dist/{link-Ddmod1dZ.mjs → link-Dllip08S.mjs} +2 -2
- package/dist/{list-MogaugiO.mjs → list-BYRP6am0.mjs} +2 -2
- package/dist/{live-Bt8Y_0bg.d.mts → live-BllfDuzA.d.mts} +2 -2
- package/dist/{local-d1-BHBnKWRb.mjs → local-d1-CAwAs9GH.mjs} +1 -1
- package/dist/login-BAPmYnb7.mjs +1 -0
- package/dist/{login-Cttnagmm.mjs → login-PcFy5mlC.mjs} +2 -2
- package/dist/{logs-CAszUWZI.mjs → logs-DmJTBhed.mjs} +2 -2
- package/dist/{migrate-DyT2jJ8y.mjs → migrate-B8S2xTcb.mjs} +5 -66
- package/dist/migrate-BIYTPQE6.mjs +1 -0
- package/dist/nitro.mjs +4 -4
- package/dist/{node-WB7c2N4L.mjs → node-CDOPrGSl.mjs} +5 -5
- package/dist/{operator-args-UnE8Y2eK.mjs → operator-args-BsJIYXaT.mjs} +8 -1
- package/dist/operator-cmd-CjazwOyb.mjs +1 -0
- package/dist/{operator-cmd-skshjMGl.mjs → operator-cmd-DmkmS2wL.mjs} +4 -3
- package/dist/pages/client.d.mts +32 -4
- package/dist/pages/client.mjs +186 -29
- package/dist/pages/index.d.mts +34 -2
- package/dist/pages/index.mjs +96 -55
- package/dist/pages/islands-plugin.d.mts +1 -1
- package/dist/pages/islands-plugin.mjs +9 -3
- package/dist/pages/protocol.d.mts +2 -2
- package/dist/platform-args-BC8_hsDj.mjs +1 -0
- package/dist/{platform-args-DVbVClZl.mjs → platform-args-BMD2gjc_.mjs} +1 -1
- package/dist/{platform-auth-config-C-pm5Qzx.mjs → platform-auth-config-CImnfohz.mjs} +3 -3
- package/dist/{platform-auth-protection-SHhvim1L.mjs → platform-auth-protection-BogLhtHi.mjs} +2 -2
- package/dist/{platform-auth-recovery-DXVWs-wA.mjs → platform-auth-recovery-B-mEaWEi.mjs} +2 -2
- package/dist/{platform-cmd-PiNRkopU.mjs → platform-cmd-CV8NxIIn.mjs} +1 -1
- package/dist/{platform-cmd-D5I1beUX.mjs → platform-cmd-DZK2ixMl.mjs} +4 -4
- package/dist/{platform-domain-jpmBfZeb.mjs → platform-domain-CRvelPGE.mjs} +2 -2
- package/dist/{platform-lifecycle-DyKmuNY6.mjs → platform-lifecycle-CPYY7E9B.mjs} +103 -41
- package/dist/{platform-lifecycle-DH3Yr1qQ.mjs → platform-lifecycle-DwXq7kZt.mjs} +1 -1
- package/dist/{platform-management--vDwSn35.mjs → platform-management-BOnGbMSM.mjs} +1 -1
- package/dist/{platform-management-7m-PLaPJ.mjs → platform-management-lXdgGgAM.mjs} +1 -1
- package/dist/{platform-recovery-BiNpZZab.mjs → platform-recovery-noaALXnE.mjs} +2 -2
- package/dist/{plugin-inference-DUjCd55H.mjs → plugin-inference-CeiB6BG5.mjs} +53 -18
- package/dist/{prepare-BcAE5Sdj.mjs → prepare-BuOS18AM.mjs} +1 -1
- package/dist/{prepare-DA-17DhO.mjs → prepare-D604Yiyr.mjs} +12 -8
- package/dist/prepare-DU-tOpS5.mjs +1 -0
- package/dist/{prerender-render-Cijv7UFo.mjs → prerender-render-CaShbHJ3.mjs} +13 -1
- package/dist/prerender-render.d.mts +1 -0
- package/dist/prerender-render.mjs +1 -1
- package/dist/{project-cmd-DA4K5faU.mjs → project-cmd-DBYqAIbe.mjs} +15 -15
- package/dist/{project-team-CQBNveX3.mjs → project-team-BjCLgTRC.mjs} +1 -1
- package/dist/{project-token-CCalFyQf.mjs → project-token-BB6PwaA9.mjs} +1 -1
- package/dist/{project-tsconfig-Itv1f4WC.mjs → project-tsconfig-CVvk6Z_e.mjs} +24 -2
- package/dist/{project-zero-trust-DPnkiEuT.mjs → project-zero-trust-CWDh1P_t.mjs} +1 -1
- package/dist/{protocol-BBDpJz3G.d.mts → protocol-D5XDySYu.d.mts} +2 -2
- package/dist/{provision-BFLCrnUp.mjs → provision-DfxLCg-d.mjs} +1 -1
- package/dist/{provision-DtROpNNI.mjs → provision-DztLJ97X.mjs} +24 -8
- package/dist/{requests-BpH0kImL.mjs → requests-D_pbzDyz.mjs} +1 -1
- package/dist/{rollback-CXS1tAa-.mjs → rollback-CjfIYsJx.mjs} +2 -2
- package/dist/{route-types-BZi26DVS.mjs → route-types-DvEGmPif.mjs} +109 -30
- package/dist/routes-stub.d.mts +22 -13
- package/dist/runtime/auth.d.mts +2 -2
- package/dist/runtime/better-auth-mysql.d.mts +1 -1
- package/dist/runtime/better-auth-mysql.mjs +1 -1
- package/dist/runtime/better-auth-pg.d.mts +1 -1
- package/dist/runtime/better-auth-pg.mjs +1 -1
- package/dist/runtime/better-auth.d.mts +1 -1
- package/dist/runtime/better-auth.mjs +1 -1
- package/dist/runtime/client-react.d.mts +1 -1
- package/dist/runtime/client-solid.d.mts +1 -1
- package/dist/runtime/client-svelte.d.mts +1 -1
- package/dist/runtime/client-vue.d.mts +1 -1
- package/dist/runtime/client.d.mts +1 -1
- package/dist/runtime/handler.d.mts +1 -1
- package/dist/runtime/live-client.d.mts +1 -1
- package/dist/runtime/live.d.mts +1 -1
- package/dist/runtime/log.mjs +19 -1
- package/dist/runtime/routing.d.mts +5 -4
- package/dist/runtime/routing.mjs +14 -73
- package/dist/runtime/validator.d.mts +1 -1
- package/dist/runtime/ws-server.d.mts +3 -3
- package/dist/runtime/ws.d.mts +1 -1
- package/dist/runtime/ws.mjs +4 -2
- package/dist/{scan-8IzYXiU_.mjs → scan-N9WzdcAl.mjs} +302 -23
- package/dist/{secret-BbXHfLAt.mjs → secret-3X0PxmuX.mjs} +9 -12
- package/dist/static-asset-marker-Btf-6oCD.mjs +32 -0
- package/dist/{types-7AIz0OZu.d.mts → types-w72dljaA.d.mts} +6 -1
- package/dist/{version-metadata-tS39iW09.mjs → version-metadata-D2vfMQzv.mjs} +2 -1
- package/dist/worker-conditions-AWFRcFxR.mjs +11 -0
- package/dist/{wrangler-F96NnLyb.mjs → wrangler-I-scB_1t.mjs} +82 -13
- package/dist/wrangler-UnwdISay.mjs +1 -0
- package/dist/{wrapper-D3sZyh2C.mjs → wrapper-BBl1rC32.mjs} +8 -12
- package/dist/{ws-BH-im_tX.d.mts → ws-B3ClMVDh.d.mts} +3 -2
- package/docs/guide/auth.md +4 -2
- package/docs/guide/edge/redirects.md +22 -0
- package/docs/guide/edge/static-assets.md +10 -0
- package/docs/guide/email/domains.md +1 -1
- package/docs/guide/email/receiving.md +2 -0
- package/docs/guide/email/sending.md +1 -1
- package/docs/guide/pages-routing/actions-and-forms.md +43 -13
- package/docs/guide/pages-routing/markdown.md +2 -0
- package/docs/guide/pages-routing/overview.md +33 -2
- package/docs/guide/platform/administration/email.md +18 -0
- package/docs/guide/platform/installation/maintenance.md +3 -1
- package/docs/guide/platform/installation/prerequisites.md +9 -4
- package/docs/guide/platform/installation/uninstall.md +2 -0
- package/docs/guide/queues.md +13 -1
- package/docs/guide/server-routing.md +40 -2
- package/docs/guide/ssg.md +8 -0
- package/docs/guide/type-safety.md +7 -7
- package/docs/guide/websockets.md +4 -2
- package/docs/integrations/cloudflare.md +16 -7
- package/docs/reference/api/auth.md +6 -2
- package/docs/reference/api/deploy.md +9 -5
- package/docs/reference/api/pages.md +6 -4
- package/docs/reference/cli/deploy.md +10 -9
- package/docs/reference/cli/email.md +13 -0
- package/docs/reference/cli/platform-email.md +2 -2
- package/docs/reference/cli.md +1 -0
- package/docs/reference/config.md +11 -1
- package/docs/reference/structure.md +3 -1
- package/package.json +9 -7
- package/schema.json +4 -0
- package/skills/void/SKILL.md +1 -1
- package/templates/assets/icons.svg +49 -0
- package/templates/assets/react.svg +1 -0
- package/templates/assets/solid.svg +1 -0
- package/templates/assets/stack.svg +35 -0
- package/templates/assets/svelte.svg +1 -0
- package/templates/assets/void.svg +5 -0
- package/templates/assets/vue.svg +1 -0
- package/dist/auth-DkcFflXV.d.mts +0 -42
- package/dist/cf-build-output-BJHuSsVN.mjs +0 -1
- package/dist/client-BiRDZTSd.mjs +0 -1
- package/dist/config-CyUJzi3q.mjs +0 -32
- package/dist/deploy-CE0Ev0Ob.mjs +0 -2
- package/dist/gen-NrOlWZaG.mjs +0 -1
- package/dist/help-BeAFFE5C.mjs +0 -1
- package/dist/login-DgDwlKc_.mjs +0 -1
- package/dist/migrate-n49ZeS1X.mjs +0 -1
- package/dist/operator-cmd-d2MvJOrl.mjs +0 -1
- package/dist/parse-filename-DioPHiR9.mjs +0 -77
- package/dist/platform-args-kQrgxScY.mjs +0 -1
- package/dist/prepare-C4I0f--h.mjs +0 -1
- package/dist/wrangler-BLb3_luP.mjs +0 -1
|
@@ -1,49 +1,50 @@
|
|
|
1
1
|
import { n as __toESM, t as __commonJSMin } from "./rolldown-runtime-3h0WiCiA.mjs";
|
|
2
2
|
import { a as join, c as resolve, n as dirname, o as normalize, r as extname, s as relative, t as basename } from "./dist-ipQi0Q8y.mjs";
|
|
3
3
|
import { t as require_picocolors } from "./picocolors-BsDfhxIw.mjs";
|
|
4
|
-
import { r as detectFramework } from "./plugin-inference-
|
|
4
|
+
import { r as detectFramework } from "./plugin-inference-CeiB6BG5.mjs";
|
|
5
5
|
import { n as readProjectPaths, t as assertNoRootSourceConventionConflicts } from "./project-paths-DGu_QZ_Q.mjs";
|
|
6
|
-
import { m as resolveBindingNames, p as readConfig, u as isNodeTarget } from "./config-
|
|
7
|
-
import { a as hasSandboxSqliteMigration, c as sandboxContainerConfig, i as assertSandboxNamespaceConfig, o as requiresSandboxPlatformImage, r as SANDBOX_MIGRATION_TAG, s as resolveSandboxConfig, t as analyzeApplicationSync } from "./application-analysis-
|
|
6
|
+
import { m as resolveBindingNames, p as readConfig, u as isNodeTarget } from "./config-OFOAimzt.mjs";
|
|
7
|
+
import { a as hasSandboxSqliteMigration, c as sandboxContainerConfig, i as assertSandboxNamespaceConfig, o as requiresSandboxPlatformImage, r as SANDBOX_MIGRATION_TAG, s as resolveSandboxConfig, t as analyzeApplicationSync } from "./application-analysis-DDOQwiXk.mjs";
|
|
8
8
|
import { t as collectMigrations } from "./collect-Dew86qce.mjs";
|
|
9
9
|
import { o as validateSsrEntry } from "./entry-BEM8ZuGP.mjs";
|
|
10
10
|
import { r as hasEmailHandlers } from "./email-B9ayYQEG.mjs";
|
|
11
|
-
import { i as voidWarn } from "./log-BMwmN5Ae.mjs";
|
|
12
11
|
import { a as resolveDistDir, c as hasDocumentRoutes, l as resolveAssetConfig, n as collectRevalidate, o as resolveWorkerDirName, r as hasRevalidate, s as hasApiRoutes } from "./isr-config-fZaJJ8t7.mjs";
|
|
13
12
|
import { t as writeFileAtomic } from "./atomic-write-Dq6R0BPN.mjs";
|
|
14
13
|
import { s as listPlatformConnections } from "./platform-registry-B9mWX9LO.mjs";
|
|
15
14
|
import { c as writeDeploymentPlatform, n as readDeploymentPlatform, r as readProjectConfig } from "./project-rqDnVsJN.mjs";
|
|
16
15
|
import { n as readGeneratedWranglerConfigFile } from "./generated-wrangler-config-DeWj5F9Y.mjs";
|
|
17
|
-
import {
|
|
18
|
-
import { A as syncWranglerWebSockets, C as readWranglerManagedQueueCleanupCandidates, D as sameMigrationsDir, E as resolveLiveBindingConfig, M as writeProvisionedWranglerConfig, N as writeWranglerPublishedTrafficSnapshot, a as LIVE_MIGRATION_TAG, c as bindingEntriesForField, h as nextDurableObjectMigrationTag, k as syncWranglerDurableObjects, m as hasDurableObjectSqliteMigration, o as acknowledgeWranglerManagedQueueRemovals, r as FRIENDLY_BINDING_NAMES, v as readExistingLiveBindingConfig, w as readWranglerPublishedTrafficSnapshot } from "./wrangler-
|
|
16
|
+
import { a as persistCloudflareConfig, c as stashCloudflareDeployPointer, i as materializeCloudflareConfig } from "./cloudflare-config-CH1AylZT.mjs";
|
|
17
|
+
import { A as syncWranglerWebSockets, C as readWranglerManagedQueueCleanupCandidates, D as sameMigrationsDir, E as resolveLiveBindingConfig, L as writeVoidProjectConfig, M as writeProvisionedWranglerConfig, N as writeWranglerPublishedTrafficSnapshot, a as LIVE_MIGRATION_TAG, c as bindingEntriesForField, h as nextDurableObjectMigrationTag, k as syncWranglerDurableObjects, m as hasDurableObjectSqliteMigration, o as acknowledgeWranglerManagedQueueRemovals, r as FRIENDLY_BINDING_NAMES, v as readExistingLiveBindingConfig, w as readWranglerPublishedTrafficSnapshot } from "./wrangler-I-scB_1t.mjs";
|
|
19
18
|
import { r as trustedCloudflareWorkerAccessHeaders, t as cfAccessHeaders } from "./cf-access-BM9G0lhO.mjs";
|
|
20
19
|
import { t as ensurePlatformAccessToken } from "./cf-access-CWP4avfP.mjs";
|
|
21
20
|
import { a as getApiUrl, c as getToken, l as getTokenSource } from "./auth-B6iOCjKI.mjs";
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
25
|
-
import { n as
|
|
26
|
-
import { a as
|
|
21
|
+
import { i as otherQueueConsumers, n as chooseCloudflareQueueName, o as scopedCloudflareQueueName, r as cloudflareQueueName } from "./dispatch-CLa2LThw.mjs";
|
|
22
|
+
import { l as resolveRemoteMode, n as CLOUDFLARE_QUEUE_NAMES_BUILD_ENV, t as CLOUDFLARE_DEPLOY_BUILD_ENV } from "./env-BaMz0j7H.mjs";
|
|
23
|
+
import { t as assertNoPrerenderFailures } from "./prerender-render-CaShbHJ3.mjs";
|
|
24
|
+
import { a as buildEnv, n as readVersionMetadataBinding, r as selectNativeVersionMetadataBinding, t as CLOUDFLARE_PRESERVE_BINDINGS_BUILD_ENV } from "./version-metadata-D2vfMQzv.mjs";
|
|
25
|
+
import { a as emailConfigInputs, c as renderAddressMap, d as isGeneratedAssetHeaders, g as prerenderPagesNode, h as prerenderPages, i as createNodeEmailDns, l as renderEmailChecklist, m as collectPrerenderPathsNode, n as SEND_EMAIL_BINDING, o as preflightEmail, p as collectPrerenderPaths, r as applyEmailSetup, t as EMAIL_FROM_VAR } from "./email-cloudflare-PMbAev9Q.mjs";
|
|
26
|
+
import { n as completeApplicationAnalysis, t as analyzeApplication } from "./application-routing-4719u_kf.mjs";
|
|
27
|
+
import { a as record, i as migrateBuiltWranglerConfig, n as prepareCfFrameworkBuildOutput, r as prepareCfStaticBuildOutput, t as prepareCfBuildOutput } from "./cf-build-output-XpNR9zoh.mjs";
|
|
27
28
|
import { i as validateMigrations, t as assertJournalCoherence } from "./validate-CnZPMq4q.mjs";
|
|
28
29
|
import { A as confirm, K as select, L as log, tt as isCancel } from "./dist-Cor9XGoz.mjs";
|
|
29
30
|
import { r as getPackageDir } from "./agents-CuNtT0D_.mjs";
|
|
30
|
-
import { a as isExpiredTokenError, r as PlatformClient } from "./client-
|
|
31
|
+
import { a as isExpiredTokenError, r as PlatformClient } from "./client-B3LnB_bE.mjs";
|
|
31
32
|
import { o as formatCount, p as note, r as createSpinner, u as getErrorMessage } from "./output-BpgYODYx.mjs";
|
|
32
33
|
import { t as getRequestedProjectSlug } from "./resolve-project-Xoi6eTWY.mjs";
|
|
33
34
|
import { i as safePositional, r as readCfUploadOutput, t as CF_VERSION_SOURCE_MAX_OUTPUT_BYTES } from "./cf-command-values-ByHk0xg4.mjs";
|
|
34
35
|
import { a as FRAMEWORK_PRESETS, c as hasBackendFiles, i as isCleanCloudflareExit, l as resolveCloudflareOperationArgv, o as detectPreset, s as formatProjectCommand, t as createCloudflareProcessRunner, u as resolveProjectCommand } from "./cloudflare-process-8jEYIeim.mjs";
|
|
35
|
-
import { f as listSelfHostSecretNames, h as selfHostSchemaFailureMessage, i as SelfHostSecretListError, l as dischargeSelfHostEnvContext, n as SelfHostFirstDeployError, p as readEmittedWorkerVars, r as SelfHostSchemaError, s as deriveSelfHostEnvContextFromVars, t as SelfHostEnvValidationError } from "./env-validation-
|
|
36
|
-
import { a as needsWrapper, r as cleanupWrapper, t as bundleEntry } from "./wrapper-
|
|
37
|
-
import { A as
|
|
38
|
-
import { a as checkCloudflareProvisionDrift, d as isQueueConfirmedAbsent, f as isRealD1Id, g as provisionCloudflareResources, i as assertValidResourceName, m as isRealKvId, s as deleteEnvVarCaseAware } from "./provision-
|
|
39
|
-
import { c as scrubWranglerAuthCredentials, n as buildSchemaProbeEnv, o as resolveDeployTransport, r as deployChildEnv, s as scrubManagedDeployBuildMarkers, t as MANAGED_DEPLOY_BUILD_ENV } from "./deploy-transport-
|
|
40
|
-
import { n as getCfCliVersion, r as getVoidUserAgent, t as
|
|
36
|
+
import { f as listSelfHostSecretNames, h as selfHostSchemaFailureMessage, i as SelfHostSecretListError, l as dischargeSelfHostEnvContext, n as SelfHostFirstDeployError, p as readEmittedWorkerVars, r as SelfHostSchemaError, s as deriveSelfHostEnvContextFromVars, t as SelfHostEnvValidationError } from "./env-validation-B3VobvXm.mjs";
|
|
37
|
+
import { a as needsWrapper, r as cleanupWrapper, t as bundleEntry } from "./wrapper-BBl1rC32.mjs";
|
|
38
|
+
import { A as promptDeployProjectConfig, C as ensureManagedHyperdrive, D as hasNonPageBackend, E as getGitCommit, F as resolveStaticBuildCommand, I as resolveStaticDeployPreset, L as toManifestSchedulesAndQueues, M as resolveDeployWorkerMain, N as resolveDeployWranglerCompat, O as hasPrerenderSources, P as resolveFullDeployBuildCommand, R as validateDeployMigrations, S as createProjectFromSlug, T as getExitCode, _ as getDeploySchemaDriftMessage, a as collectAndHashAssets, b as assertProjectDeployAccess, c as readWranglerHtmlHandling, d as printDeploySuccess, f as mergeAndLintRoutingRules, g as assertDeploySchemaDriftFree, h as warnUnpublishedRouting, i as buildStaticManifest, j as resolveDeployLiveBindingConfig, k as log$1, l as formatDeploySummary, m as warnIgnoredNotFoundForFramework, n as runStaticDeploy, o as collectWorkerFiles, p as streamDirectR2Deploy, r as buildFrameworkManifest, s as detectNonSpaFallbackWarning, t as assembleVoidManifest, u as printDeployContext, v as hasDeploySchemaDrift, w as generateDeployWrapperIfNeeded, x as assertWorkerMainUploaded, y as assertEnvSchemaValid } from "./deploy-managed-static-DjeBFG2c.mjs";
|
|
39
|
+
import { a as checkCloudflareProvisionDrift, b as resolveWorkersDevComplianceRegion, d as isQueueConfirmedAbsent, f as isRealD1Id, g as provisionCloudflareResources, i as assertValidResourceName, m as isRealKvId, s as deleteEnvVarCaseAware } from "./provision-DztLJ97X.mjs";
|
|
40
|
+
import { c as scrubWranglerAuthCredentials, n as buildSchemaProbeEnv, o as resolveDeployTransport, r as deployChildEnv, s as scrubManagedDeployBuildMarkers, t as MANAGED_DEPLOY_BUILD_ENV } from "./deploy-transport-DIq_gFTP.mjs";
|
|
41
|
+
import { n as getCfCliVersion, r as getVoidUserAgent, t as publishCloudflareWorkerSettings } from "./cf-worker-settings-Dg27RzyT.mjs";
|
|
41
42
|
import { t as sanitizeTerminalLogText } from "./terminal-log-text-D9ACPOuG.mjs";
|
|
42
|
-
import { t as promptForLoginToken } from "./login-
|
|
43
|
-
import { a as parseCloudflareAuthSession, i as ensureCloudflareAuthentication, n as cloudflareCredentialOverrides, t as CloudflareAuthenticationError } from "./cloudflare-auth-
|
|
44
|
-
import { a as createCloudflareEmptyDomainPublisher, i as createCloudflareEmptyCronPublisher } from "./cloudflare-operations-
|
|
43
|
+
import { t as promptForLoginToken } from "./login-PcFy5mlC.mjs";
|
|
44
|
+
import { a as parseCloudflareAuthSession, i as ensureCloudflareAuthentication, n as cloudflareCredentialOverrides, t as CloudflareAuthenticationError } from "./cloudflare-auth-DyD_kVFr.mjs";
|
|
45
|
+
import { a as createCloudflareEmptyDomainPublisher, i as createCloudflareEmptyCronPublisher } from "./cloudflare-operations-Bc-7fN44.mjs";
|
|
45
46
|
import { n as openMigrationValidationDatabase, t as SqliteMigrationError } from "./sqlite-validation-BzKMWnO4.mjs";
|
|
46
|
-
import {
|
|
47
|
+
import { r as discoverFrameworkWranglerFiles, t as migrateLegacyVoidConfig } from "./migrate-B8S2xTcb.mjs";
|
|
47
48
|
import { a as runMySqlMigrations } from "./runner-mysql-BWmbk5IE.mjs";
|
|
48
49
|
import { i as runPgMigrations } from "./runner-pg-Cr3qrqi4.mjs";
|
|
49
50
|
import { t as collectGitDeployMetadata } from "./git-metadata-D-gurjzG.mjs";
|
|
@@ -59,9 +60,10 @@ import { execFile, execSync, spawn } from "node:child_process";
|
|
|
59
60
|
import { getWorkerAssetsDir, getWorkerBundleDir, getWorkerConfigPath, readBuildOutput } from "@cloudflare/build-output-utils";
|
|
60
61
|
import { convertToWranglerConfig } from "@cloudflare/config";
|
|
61
62
|
import ignore from "ignore";
|
|
62
|
-
import { CloudflareWorkerInspectionError, activateCloudflareVersion, assertCloudflareBindingsPreserved, assertCloudflareDurableObjectLifecycleSupported, assertExistingCloudflareConfig, cloudflareCommandDiagnostic, encodeCloudflareVersionMessage, extractWorkersDevSubdomain, normalizeWorkersDevSubdomain, parseRootWranglerConfig, parseRootWranglerConfig as parseRootWranglerConfig$1, readBindingFieldPresence, readCloudflareTriggerConfig, readConfigEntryString, readExistingCloudflareWorker, readStoredResourceName, readWranglerTopLevelString, renderCloudflareStaticEntry, resolveD1MigrateTarget, stageCloudflareStaticAssets, writeCloudflareFrameworkDeployConfig, writeCloudflareStaticDeployConfig } from "@void/deploy-cloudflare";
|
|
63
|
+
import { CloudflareWorkerInspectionError, activateCloudflareVersion, assertCloudflareBindingsPreserved, assertCloudflareDurableObjectLifecycleSupported, assertExistingCloudflareConfig, cloudflareCommandDiagnostic, encodeCloudflareVersionMessage, extractWorkersDevSubdomain, normalizeReadinessAccessOrigin, normalizeWorkersDevSubdomain, parseRootWranglerConfig, parseRootWranglerConfig as parseRootWranglerConfig$1, readBindingFieldPresence, readCloudflareTriggerConfig, readConfigEntryString, readExistingCloudflareWorker, readStoredResourceName, readWranglerTopLevelString, renderCloudflareStaticEntry, resolveD1MigrateTarget, stageCloudflareStaticAssets, writeCloudflareFrameworkDeployConfig, writeCloudflareStaticDeployConfig } from "@void/deploy-cloudflare";
|
|
63
64
|
import { setTimeout as setTimeout$1 } from "node:timers/promises";
|
|
64
65
|
import mime from "mime";
|
|
66
|
+
import { Buffer as Buffer$1 } from "node:buffer";
|
|
65
67
|
import { Minimatch } from "minimatch";
|
|
66
68
|
//#region src/cli/cloudflare-candidate.ts
|
|
67
69
|
const CANDIDATE_FILE = ".void/cloudflare-candidate.json";
|
|
@@ -217,6 +219,112 @@ async function maybeLinkCloudflareDeploy(root, options = {}, deps = {}) {
|
|
|
217
219
|
return isCancel(accepted) || accepted !== true ? "cancelled" : "existing";
|
|
218
220
|
}
|
|
219
221
|
//#endregion
|
|
222
|
+
//#region src/cli/cloudflare-readiness.ts
|
|
223
|
+
const STATE_FILE = join(".void", "cloudflare.json");
|
|
224
|
+
/** Resolve the account subdomain without exposing Cloudflare credentials to project code. */
|
|
225
|
+
function resolveCloudflareWorkersDevSubdomain(root, accountId, env = process.env) {
|
|
226
|
+
const configured = env.CLOUDFLARE_WORKERS_SUBDOMAIN;
|
|
227
|
+
if (configured !== void 0 && configured.trim().length > 0) {
|
|
228
|
+
const normalized = normalizeWorkersDevSubdomain(configured);
|
|
229
|
+
if (!normalized) throw new Error("deploy: CLOUDFLARE_WORKERS_SUBDOMAIN must be the account subdomain, for example \"my-team\" or \"my-team.workers.dev\".");
|
|
230
|
+
return normalized;
|
|
231
|
+
}
|
|
232
|
+
const cached = subdomainsByAccount(readCloudflareLocalState(root))[accountId];
|
|
233
|
+
return typeof cached === "string" ? normalizeWorkersDevSubdomain(cached) : void 0;
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Record `CF_ACCESS_READINESS_ORIGIN` before project code runs. `void.config.ts` is evaluated in
|
|
237
|
+
* this process, so a later read of `process.env` could see a value that the project assigned,
|
|
238
|
+
* for example through a dotenv import. `null` means unset. An already recorded value is kept.
|
|
239
|
+
*/
|
|
240
|
+
function withRecordedReadinessAccessOrigin(options, env = process.env) {
|
|
241
|
+
return options.readinessAccessOrigin !== void 0 ? options : {
|
|
242
|
+
...options,
|
|
243
|
+
readinessAccessOrigin: env.CF_ACCESS_READINESS_ORIGIN ?? null
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Validate the operator-selected origin that may receive readiness Access credentials when the
|
|
248
|
+
* probe uses a route or Custom Domain. Pass the value that `withRecordedReadinessAccessOrigin`
|
|
249
|
+
* recorded, not the current `process.env`.
|
|
250
|
+
*/
|
|
251
|
+
function resolveCloudflareReadinessAccessOrigin(env) {
|
|
252
|
+
const configured = env.CF_ACCESS_READINESS_ORIGIN?.trim();
|
|
253
|
+
if (!configured) return;
|
|
254
|
+
const origin = normalizeReadinessAccessOrigin(configured);
|
|
255
|
+
if (!origin) throw new Error("deploy: CF_ACCESS_READINESS_ORIGIN must be one exact https origin, without a wildcard, path, query, fragment, or credentials, for example \"https://app.example.com\".");
|
|
256
|
+
return origin;
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Read the account subdomain from the Cloudflare API when a first publish reports no URL and
|
|
260
|
+
* no subdomain is configured or cached. The API returns only the account label, so this adds
|
|
261
|
+
* `.fed` for FedRAMP High, as Wrangler does. A failed lookup resolves `unavailable`.
|
|
262
|
+
*/
|
|
263
|
+
async function readCloudflareWorkersDevSubdomain(options) {
|
|
264
|
+
if (!options.verifyUploader()) return {
|
|
265
|
+
ok: false,
|
|
266
|
+
reason: "uploader-changed"
|
|
267
|
+
};
|
|
268
|
+
let label;
|
|
269
|
+
try {
|
|
270
|
+
const result = await options.runWrangler({
|
|
271
|
+
type: "workers.subdomain.get",
|
|
272
|
+
configPath: options.configPath
|
|
273
|
+
}, { capture: true });
|
|
274
|
+
if (!isCleanCloudflareExit(result) || !result.data || typeof result.data !== "object" || !("subdomain" in result.data) || typeof result.data.subdomain !== "string") return {
|
|
275
|
+
ok: false,
|
|
276
|
+
reason: "unavailable"
|
|
277
|
+
};
|
|
278
|
+
label = result.data.subdomain;
|
|
279
|
+
} catch {
|
|
280
|
+
return {
|
|
281
|
+
ok: false,
|
|
282
|
+
reason: "unavailable"
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
const subdomain = normalizeWorkersDevSubdomain(options.complianceRegion === "fedramp_high" ? `${label}.fed` : label);
|
|
286
|
+
return subdomain ? {
|
|
287
|
+
ok: true,
|
|
288
|
+
subdomain
|
|
289
|
+
} : {
|
|
290
|
+
ok: false,
|
|
291
|
+
reason: "unavailable"
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
/** Cache a Wrangler-reported account subdomain for later no-preview version probes. */
|
|
295
|
+
function rememberCloudflareWorkersDevSubdomain(root, accountId, url) {
|
|
296
|
+
const workersDevSubdomain = extractWorkersDevSubdomain(url);
|
|
297
|
+
if (!workersDevSubdomain) return false;
|
|
298
|
+
const current = readCloudflareLocalState(root);
|
|
299
|
+
const currentByAccount = subdomainsByAccount(current);
|
|
300
|
+
if (currentByAccount[accountId] === workersDevSubdomain) return false;
|
|
301
|
+
const { workersDevSubdomain: _legacy, ...state } = current;
|
|
302
|
+
const filePath = join(root, STATE_FILE);
|
|
303
|
+
mkdirSync(dirname(filePath), { recursive: true });
|
|
304
|
+
writeFileSync(filePath, JSON.stringify({
|
|
305
|
+
...state,
|
|
306
|
+
workersDevSubdomains: {
|
|
307
|
+
...currentByAccount,
|
|
308
|
+
[accountId]: workersDevSubdomain
|
|
309
|
+
}
|
|
310
|
+
}, null, 2) + "\n");
|
|
311
|
+
return true;
|
|
312
|
+
}
|
|
313
|
+
function subdomainsByAccount(state) {
|
|
314
|
+
const value = state.workersDevSubdomains;
|
|
315
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
316
|
+
}
|
|
317
|
+
function readCloudflareLocalState(root) {
|
|
318
|
+
const filePath = join(root, STATE_FILE);
|
|
319
|
+
if (!existsSync(filePath)) return {};
|
|
320
|
+
try {
|
|
321
|
+
const parsed = JSON.parse(readFileSync(filePath, "utf-8"));
|
|
322
|
+
return typeof parsed === "object" && parsed !== null && !Array.isArray(parsed) ? parsed : {};
|
|
323
|
+
} catch {
|
|
324
|
+
return {};
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
//#endregion
|
|
220
328
|
//#region src/cli/deploy-binding-snapshot.ts
|
|
221
329
|
/** The id-bearing binding fields whose identity must survive the build unchanged. */
|
|
222
330
|
const DEPLOY_BINDING_IDENTITY_FIELDS = {
|
|
@@ -786,7 +894,10 @@ async function computeDesiredCloudflareResources(root, voidConfig, configPath, a
|
|
|
786
894
|
};
|
|
787
895
|
reasons.set(binding, analysis.reasons.r2[0]);
|
|
788
896
|
}
|
|
789
|
-
|
|
897
|
+
if (analysis.queues.length > 0) {
|
|
898
|
+
desired.queueNames = Object.fromEntries(analysis.queues.map((q) => [q.name, scopedCloudflareQueueName(toValidWorkerName(workerName), q.name)]));
|
|
899
|
+
desired.queues = Object.values(desired.queueNames);
|
|
900
|
+
}
|
|
790
901
|
if (needsDatabase && dialect !== "sqlite") {
|
|
791
902
|
const binding = "HYPERDRIVE";
|
|
792
903
|
desired.hyperdrive = {
|
|
@@ -1772,6 +1883,9 @@ async function ensureCloudflareAuthSecret(options) {
|
|
|
1772
1883
|
return { created: true };
|
|
1773
1884
|
}
|
|
1774
1885
|
//#endregion
|
|
1886
|
+
//#region src/cli/node-buffer.ts
|
|
1887
|
+
const Buffer$2 = Buffer$1;
|
|
1888
|
+
//#endregion
|
|
1775
1889
|
//#region src/cli/cf-version-api.ts
|
|
1776
1890
|
var CloudflareApiError = class extends Error {
|
|
1777
1891
|
status;
|
|
@@ -1797,6 +1911,31 @@ function textValue(value, label) {
|
|
|
1797
1911
|
if (typeof value !== "string") throw new Error(`The Cloudflare ${label} is missing from the verified Worker output.`);
|
|
1798
1912
|
return value;
|
|
1799
1913
|
}
|
|
1914
|
+
/** Match cf's package collection for uploads that preserve secrets through the JSON API. */
|
|
1915
|
+
async function readPackageDependencies(directory) {
|
|
1916
|
+
try {
|
|
1917
|
+
const pkg = record(JSON.parse(readFileSync(join(directory, "package.json"), "utf8")));
|
|
1918
|
+
const declared = {
|
|
1919
|
+
...record(pkg?.dependencies),
|
|
1920
|
+
...record(pkg?.devDependencies)
|
|
1921
|
+
};
|
|
1922
|
+
const { getInstalledPackageVersion } = await import("@cloudflare/workers-utils");
|
|
1923
|
+
const dependencies = [];
|
|
1924
|
+
for (const [name, packageJsonVersion] of Object.entries(declared)) {
|
|
1925
|
+
if (dependencies.length >= 200) break;
|
|
1926
|
+
if (typeof packageJsonVersion !== "string" || /^(workspace|catalog|file|link):/.test(packageJsonVersion)) continue;
|
|
1927
|
+
const installedVersion = getInstalledPackageVersion(name, directory);
|
|
1928
|
+
if (installedVersion) dependencies.push({
|
|
1929
|
+
name,
|
|
1930
|
+
packageJsonVersion,
|
|
1931
|
+
installedVersion
|
|
1932
|
+
});
|
|
1933
|
+
}
|
|
1934
|
+
return dependencies.length ? dependencies : void 0;
|
|
1935
|
+
} catch {
|
|
1936
|
+
return;
|
|
1937
|
+
}
|
|
1938
|
+
}
|
|
1800
1939
|
const moduleContentTypes = {
|
|
1801
1940
|
esm: "application/javascript+module",
|
|
1802
1941
|
cjs: "application/javascript",
|
|
@@ -2090,11 +2229,22 @@ function assetConfigFromOutput(value) {
|
|
|
2090
2229
|
...config.runWorkerFirst === void 0 ? {} : { run_worker_first: config.runWorkerFirst }
|
|
2091
2230
|
};
|
|
2092
2231
|
}
|
|
2093
|
-
/**
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2232
|
+
/** The region, host or hostname of a targeted placement. */
|
|
2233
|
+
function placementTarget(placement) {
|
|
2234
|
+
if (!placement) return;
|
|
2235
|
+
for (const kind of [
|
|
2236
|
+
"region",
|
|
2237
|
+
"host",
|
|
2238
|
+
"hostname"
|
|
2239
|
+
]) {
|
|
2240
|
+
const value = placement[kind];
|
|
2241
|
+
if (typeof value === "string" && value) return {
|
|
2242
|
+
kind,
|
|
2243
|
+
value
|
|
2244
|
+
};
|
|
2245
|
+
}
|
|
2246
|
+
}
|
|
2247
|
+
/** The version API placement, in the shape cf's own version uploads send. */
|
|
2098
2248
|
function placementFromOutput(placement) {
|
|
2099
2249
|
if (!placement) return;
|
|
2100
2250
|
const hint = "hint" in placement ? placement.hint : void 0;
|
|
@@ -2102,8 +2252,22 @@ function placementFromOutput(placement) {
|
|
|
2102
2252
|
mode: "smart",
|
|
2103
2253
|
...hint ? { hint } : {}
|
|
2104
2254
|
};
|
|
2105
|
-
const target =
|
|
2106
|
-
|
|
2255
|
+
const target = placementTarget(placement);
|
|
2256
|
+
return target ? {
|
|
2257
|
+
mode: "targeted",
|
|
2258
|
+
[target.kind]: target.value
|
|
2259
|
+
} : void 0;
|
|
2260
|
+
}
|
|
2261
|
+
/**
|
|
2262
|
+
* Whether the upload reply still names the requested target. The Workers beta version
|
|
2263
|
+
* endpoint has replied `placement: {}` after dropping one (terraform-provider-cloudflare#7273).
|
|
2264
|
+
* It now replies with the target alone, e.g. `{ region }`.
|
|
2265
|
+
*/
|
|
2266
|
+
function keepsPlacementTarget(placement, target) {
|
|
2267
|
+
const reply = record(placement);
|
|
2268
|
+
if (!reply) return false;
|
|
2269
|
+
const targets = reply.target === void 0 ? [reply] : reply.target;
|
|
2270
|
+
return Array.isArray(targets) && targets.length === 1 && record(targets[0])?.[target.kind] === target.value;
|
|
2107
2271
|
}
|
|
2108
2272
|
async function apiResult(url, token, method, body, verifyUploader, timeout = 12e4) {
|
|
2109
2273
|
assertUploaderUnchanged(verifyUploader);
|
|
@@ -2333,6 +2497,22 @@ async function ensureContainerApplications(options) {
|
|
|
2333
2497
|
assertContainerApplicationSettings(confirmed, plan);
|
|
2334
2498
|
}
|
|
2335
2499
|
}
|
|
2500
|
+
/**
|
|
2501
|
+
* The `_headers` file a native build generated for its fingerprinted files.
|
|
2502
|
+
* This API takes it as a `_headers` module, as cf does on its JSON version
|
|
2503
|
+
* uploads. A user-authored `_headers` is not sent on this path.
|
|
2504
|
+
*/
|
|
2505
|
+
function readGeneratedAssetHeaders(output) {
|
|
2506
|
+
if (!output.assetsDirectory) return;
|
|
2507
|
+
let text;
|
|
2508
|
+
try {
|
|
2509
|
+
text = readFileSync(join(getWorkerAssetsDir(output.directory), "_headers"), "utf8");
|
|
2510
|
+
} catch (cause) {
|
|
2511
|
+
if (cause instanceof Error && "code" in cause && cause.code === "ENOENT") return;
|
|
2512
|
+
throw cause;
|
|
2513
|
+
}
|
|
2514
|
+
return isGeneratedAssetHeaders(text) ? text : void 0;
|
|
2515
|
+
}
|
|
2336
2516
|
async function uploadAssets(options) {
|
|
2337
2517
|
if (!options.output.assetsDirectory) return;
|
|
2338
2518
|
const directory = getWorkerAssetsDir(options.output.directory);
|
|
@@ -2460,6 +2640,12 @@ async function uploadPinnedCloudflareVersion(options) {
|
|
|
2460
2640
|
content_base64: readFileSync(join(getWorkerBundleDir(options.output.directory), name)).toString("base64")
|
|
2461
2641
|
});
|
|
2462
2642
|
}
|
|
2643
|
+
const generatedHeaders = readGeneratedAssetHeaders(options.output);
|
|
2644
|
+
if (generatedHeaders !== void 0) modules.push({
|
|
2645
|
+
name: "_headers",
|
|
2646
|
+
content_type: "text/plain",
|
|
2647
|
+
content_base64: Buffer$2.from(generatedHeaders).toString("base64")
|
|
2648
|
+
});
|
|
2463
2649
|
await preflightWorkflowExports({
|
|
2464
2650
|
exports,
|
|
2465
2651
|
accountUrl,
|
|
@@ -2489,6 +2675,7 @@ async function uploadPinnedCloudflareVersion(options) {
|
|
|
2489
2675
|
modules,
|
|
2490
2676
|
compatibility_date: config.compatibilityDate,
|
|
2491
2677
|
compatibility_flags: config.compatibilityFlags,
|
|
2678
|
+
package_dependencies: await readPackageDependencies(options.output.directory),
|
|
2492
2679
|
bindings,
|
|
2493
2680
|
...config.limits ? { limits: {
|
|
2494
2681
|
cpu_ms: config.limits.cpuMs,
|
|
@@ -2522,6 +2709,8 @@ async function uploadPinnedCloudflareVersion(options) {
|
|
|
2522
2709
|
} catch {
|
|
2523
2710
|
throw new Error(`Cloudflare Worker version ${versionId} was uploaded${options.atomic ? " and may already be published" : ""}, but its Container applications could not be verified. Read back the Worker deployment and Container identities before retrying.`);
|
|
2524
2711
|
}
|
|
2712
|
+
const target = placementTarget(config.placement);
|
|
2713
|
+
if (target && !keepsPlacementTarget(uploaded.placement, target)) throw new Error(`Cloudflare did not keep placement.${target.kind} "${target.value}" on Worker version ${versionId}${options.atomic ? ", which is already live" : ", so it was not deployed"}. Deploy again, or set cloudflare.placement to { mode: 'smart' } in void.config.ts.`);
|
|
2525
2714
|
return {
|
|
2526
2715
|
id: versionId,
|
|
2527
2716
|
urls: Array.isArray(uploaded.urls) ? uploaded.urls.filter((url) => typeof url === "string") : []
|
|
@@ -2952,7 +3141,7 @@ function createCfVersionRunner(options) {
|
|
|
2952
3141
|
"versions",
|
|
2953
3142
|
"create",
|
|
2954
3143
|
"--prebuilt",
|
|
2955
|
-
...operation.message ? [
|
|
3144
|
+
...operation.message ? [`--message=${operation.message}`] : [],
|
|
2956
3145
|
...operation.secretsFilePath ? ["--secrets-file", operation.secretsFilePath] : [],
|
|
2957
3146
|
...operation.previewAlias ? ["--preview-alias", operation.previewAlias] : []
|
|
2958
3147
|
], command.capture));
|
|
@@ -2979,7 +3168,8 @@ function createCfVersionRunner(options) {
|
|
|
2979
3168
|
strategy: "percentage",
|
|
2980
3169
|
versions: parsed,
|
|
2981
3170
|
annotations: { "workers/message": operation.message }
|
|
2982
|
-
})] : []
|
|
3171
|
+
})] : [],
|
|
3172
|
+
...operation.bypassDeploymentChecks ? ["--bypass-deployment-checks"] : []
|
|
2983
3173
|
], command.capture);
|
|
2984
3174
|
}
|
|
2985
3175
|
if (operation.type === "worker.deploy") {
|
|
@@ -2989,7 +3179,7 @@ function createCfVersionRunner(options) {
|
|
|
2989
3179
|
return uploadedResult(await run([
|
|
2990
3180
|
"deploy",
|
|
2991
3181
|
"--prebuilt",
|
|
2992
|
-
...operation.message ? [
|
|
3182
|
+
...operation.message ? [`--message=${operation.message}`] : [],
|
|
2993
3183
|
...operation.secretsFilePath ? ["--secrets-file", operation.secretsFilePath] : []
|
|
2994
3184
|
], command.capture));
|
|
2995
3185
|
}
|
|
@@ -3038,17 +3228,18 @@ function createCfVersionRunner(options) {
|
|
|
3038
3228
|
"deploy",
|
|
3039
3229
|
"--prebuilt"
|
|
3040
3230
|
], command.capture, directory);
|
|
3041
|
-
if (isCleanCloudflareExit(deployed) && raw.observability !== void 0) {
|
|
3231
|
+
if (isCleanCloudflareExit(deployed) && (raw.observability !== void 0 || raw.logpush !== void 0)) {
|
|
3042
3232
|
const credentials = options.pinnedUpload;
|
|
3043
3233
|
if (!credentials || !credentials.verifyUploader()) return failed("The Cloudflare settings publisher is unavailable.");
|
|
3044
3234
|
try {
|
|
3045
3235
|
const token = await credentials.getToken();
|
|
3046
3236
|
if (!token || !credentials.verifyUploader()) return failed("Cloudflare session is unavailable for publishing Worker settings.");
|
|
3047
|
-
await
|
|
3237
|
+
await publishCloudflareWorkerSettings({
|
|
3048
3238
|
apiBaseUrl: credentials.apiBaseUrl,
|
|
3049
3239
|
accountId: credentials.accountId,
|
|
3050
3240
|
workerName,
|
|
3051
3241
|
observability: raw.observability,
|
|
3242
|
+
logpush: raw.logpush,
|
|
3052
3243
|
headers: { Authorization: `Bearer ${token}` }
|
|
3053
3244
|
});
|
|
3054
3245
|
} catch (cause) {
|
|
@@ -3109,53 +3300,6 @@ function createCfVersionRunner(options) {
|
|
|
3109
3300
|
};
|
|
3110
3301
|
}
|
|
3111
3302
|
//#endregion
|
|
3112
|
-
//#region src/cli/cloudflare-readiness.ts
|
|
3113
|
-
const STATE_FILE = join(".void", "cloudflare.json");
|
|
3114
|
-
/** Resolve the account subdomain without exposing Cloudflare credentials to project code. */
|
|
3115
|
-
function resolveCloudflareWorkersDevSubdomain(root, accountId, env = process.env) {
|
|
3116
|
-
const configured = env.CLOUDFLARE_WORKERS_SUBDOMAIN;
|
|
3117
|
-
if (configured !== void 0 && configured.trim().length > 0) {
|
|
3118
|
-
const normalized = normalizeWorkersDevSubdomain(configured);
|
|
3119
|
-
if (!normalized) throw new Error("deploy: CLOUDFLARE_WORKERS_SUBDOMAIN must be the account subdomain, for example \"my-team\" or \"my-team.workers.dev\".");
|
|
3120
|
-
return normalized;
|
|
3121
|
-
}
|
|
3122
|
-
const cached = subdomainsByAccount(readCloudflareLocalState(root))[accountId];
|
|
3123
|
-
return typeof cached === "string" ? normalizeWorkersDevSubdomain(cached) : void 0;
|
|
3124
|
-
}
|
|
3125
|
-
/** Cache a Wrangler-reported account subdomain for later no-preview version probes. */
|
|
3126
|
-
function rememberCloudflareWorkersDevSubdomain(root, accountId, url) {
|
|
3127
|
-
const workersDevSubdomain = extractWorkersDevSubdomain(url);
|
|
3128
|
-
if (!workersDevSubdomain) return false;
|
|
3129
|
-
const current = readCloudflareLocalState(root);
|
|
3130
|
-
const currentByAccount = subdomainsByAccount(current);
|
|
3131
|
-
if (currentByAccount[accountId] === workersDevSubdomain) return false;
|
|
3132
|
-
const { workersDevSubdomain: _legacy, ...state } = current;
|
|
3133
|
-
const filePath = join(root, STATE_FILE);
|
|
3134
|
-
mkdirSync(dirname(filePath), { recursive: true });
|
|
3135
|
-
writeFileSync(filePath, JSON.stringify({
|
|
3136
|
-
...state,
|
|
3137
|
-
workersDevSubdomains: {
|
|
3138
|
-
...currentByAccount,
|
|
3139
|
-
[accountId]: workersDevSubdomain
|
|
3140
|
-
}
|
|
3141
|
-
}, null, 2) + "\n");
|
|
3142
|
-
return true;
|
|
3143
|
-
}
|
|
3144
|
-
function subdomainsByAccount(state) {
|
|
3145
|
-
const value = state.workersDevSubdomains;
|
|
3146
|
-
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
3147
|
-
}
|
|
3148
|
-
function readCloudflareLocalState(root) {
|
|
3149
|
-
const filePath = join(root, STATE_FILE);
|
|
3150
|
-
if (!existsSync(filePath)) return {};
|
|
3151
|
-
try {
|
|
3152
|
-
const parsed = JSON.parse(readFileSync(filePath, "utf-8"));
|
|
3153
|
-
return typeof parsed === "object" && parsed !== null && !Array.isArray(parsed) ? parsed : {};
|
|
3154
|
-
} catch {
|
|
3155
|
-
return {};
|
|
3156
|
-
}
|
|
3157
|
-
}
|
|
3158
|
-
//#endregion
|
|
3159
3303
|
//#region src/cli/deploy-cloudflare-helpers.ts
|
|
3160
3304
|
/**
|
|
3161
3305
|
* Discover the root wrangler config path the same way the build / bindings
|
|
@@ -3208,6 +3352,7 @@ async function connectCloudflareDeployAccount(options) {
|
|
|
3208
3352
|
log$1.error(`deploy: ${getErrorMessage(error)}`);
|
|
3209
3353
|
return null;
|
|
3210
3354
|
}
|
|
3355
|
+
const complianceRegion = resolveWorkersDevComplianceRegion(process.env, readWranglerTopLevelString(rootConfig, "compliance_region"));
|
|
3211
3356
|
const pins = createCloudflareUploaderPins(root, deps);
|
|
3212
3357
|
let accountId = readWranglerTopLevelString(rootConfig, "account_id") ?? (process.env.CLOUDFLARE_ACCOUNT_ID?.trim() || void 0);
|
|
3213
3358
|
if (!accountId) {
|
|
@@ -3227,8 +3372,10 @@ async function connectCloudflareDeployAccount(options) {
|
|
|
3227
3372
|
}
|
|
3228
3373
|
}
|
|
3229
3374
|
let workersDevSubdomain;
|
|
3375
|
+
let readinessAccessOrigin;
|
|
3230
3376
|
try {
|
|
3231
3377
|
workersDevSubdomain = resolveCloudflareWorkersDevSubdomain(root, accountId);
|
|
3378
|
+
readinessAccessOrigin = resolveCloudflareReadinessAccessOrigin({ CF_ACCESS_READINESS_ORIGIN: options.readinessAccessOrigin ?? void 0 });
|
|
3232
3379
|
} catch (error) {
|
|
3233
3380
|
log$1.error(getErrorMessage(error));
|
|
3234
3381
|
return null;
|
|
@@ -3236,8 +3383,10 @@ async function connectCloudflareDeployAccount(options) {
|
|
|
3236
3383
|
return {
|
|
3237
3384
|
...pins,
|
|
3238
3385
|
apiBaseUrl,
|
|
3386
|
+
complianceRegion,
|
|
3239
3387
|
accountId,
|
|
3240
3388
|
workersDevSubdomain,
|
|
3389
|
+
readinessAccessOrigin,
|
|
3241
3390
|
runWrangler: deps.runWrangler ?? createDeployWranglerRunner(root, accountId, apiBaseUrl),
|
|
3242
3391
|
rootConfig
|
|
3243
3392
|
};
|
|
@@ -3323,7 +3472,21 @@ function cloudflareCandidateActivationOptions(options) {
|
|
|
3323
3472
|
},
|
|
3324
3473
|
readinessHeaders: cloudflareWorkerReadinessHeaders(),
|
|
3325
3474
|
workersDevSubdomain,
|
|
3475
|
+
resolveWorkersDevSubdomain: async () => {
|
|
3476
|
+
const { complianceRegion } = options;
|
|
3477
|
+
if (complianceRegion === void 0) return {
|
|
3478
|
+
ok: false,
|
|
3479
|
+
reason: "unavailable"
|
|
3480
|
+
};
|
|
3481
|
+
return readCloudflareWorkersDevSubdomain({
|
|
3482
|
+
configPath,
|
|
3483
|
+
complianceRegion,
|
|
3484
|
+
runWrangler,
|
|
3485
|
+
verifyUploader: options.assertUploaderStillPinned
|
|
3486
|
+
});
|
|
3487
|
+
},
|
|
3326
3488
|
readinessHeadersWorkersDevSubdomain: process.env.CLOUDFLARE_WORKERS_SUBDOMAIN?.trim() ? workersDevSubdomain : void 0,
|
|
3489
|
+
readinessHeadersOrigin: options.readinessAccessOrigin,
|
|
3327
3490
|
...createCloudflareEmptyTriggerPublishers({
|
|
3328
3491
|
accountId,
|
|
3329
3492
|
apiBaseUrl: options.apiBaseUrl,
|
|
@@ -3383,6 +3546,10 @@ async function activateCloudflareVersionWithProgress(activate, options) {
|
|
|
3383
3546
|
}
|
|
3384
3547
|
}
|
|
3385
3548
|
function formatCloudflareActivationError(result) {
|
|
3549
|
+
const message = formatCloudflareActivationFailure(result);
|
|
3550
|
+
return result.restoredOlderSecrets ? `${message}\nCloudflare refused to restore the previous version because this deploy changed a secret, so Void forced the restore. The previous version runs with its old secret values; deploy again to apply the new ones.` : message;
|
|
3551
|
+
}
|
|
3552
|
+
function formatCloudflareActivationFailure(result) {
|
|
3386
3553
|
const status = result.status === void 0 ? "" : ` (exit ${String(result.status)})`;
|
|
3387
3554
|
const cloudflareCode = result.cloudflareErrorCode === void 0 ? "" : ` Cloudflare error code: ${String(result.cloudflareErrorCode)}.`;
|
|
3388
3555
|
const diagnostic = result.diagnostic ? `\n\n${result.diagnostic}` : "";
|
|
@@ -3420,36 +3587,64 @@ function formatCloudflareActivationError(result) {
|
|
|
3420
3587
|
].join("\n");
|
|
3421
3588
|
case "readiness-staging-failed": return `deploy: Cloudflare could not stage the uploaded Worker Version at zero-percent traffic${status}; production traffic is unchanged.${cloudflareCode}${diagnostic}${result.cloudflareErrorCode === 10210 && (result.diagnostic ?? "").toLowerCase().includes("durable object migration") ? "\n\nReview the Durable Object migration, then run `void deploy --platform cloudflare --atomic`. For future deploys, set deploy.cloudflare.mode to \"atomic\" in void.config.ts." : result.cloudflareErrorCode === 100405 ? "\n\nThe new version declares different exports from the live version (for example a Durable Object or Workflow class), so Cloudflare cannot split traffic between them. Run `void deploy --platform cloudflare --atomic` once to publish it at 100% directly; it receives traffic before readiness is checked." : ""}`;
|
|
3422
3589
|
case "atomic-failed": return `deploy: Cloudflare could not publish the Worker atomically${status}; inspect production status before retrying.${cloudflareCode}${diagnostic}`;
|
|
3423
|
-
case "atomic-output-invalid":
|
|
3590
|
+
case "atomic-output-invalid":
|
|
3591
|
+
if (result.versionId) return formatCloudflarePublishWithoutUrl(`Cloudflare published Worker version ${result.versionId} atomically`, `If the app uses workers.dev, set CLOUDFLARE_WORKERS_SUBDOMAIN to your account subdomain ${WORKERS_SUBDOMAIN_EXAMPLE}.`);
|
|
3592
|
+
return "deploy: Cloudflare published atomically but did not report its version id. Inspect `void project status` immediately.";
|
|
3424
3593
|
case "atomic-readiness-failed":
|
|
3425
|
-
case "atomic-readiness-access-denied": return `deploy: the atomic Worker deployment is live, but /__void/ready could not be verified. Inspect \`void project status\` and Worker logs immediately.${diagnostic}`;
|
|
3594
|
+
case "atomic-readiness-access-denied": return `deploy: the atomic Worker deployment is live, but /__void/ready could not be verified. Inspect \`void project status\` and Worker logs immediately.${diagnostic}${result.customRouteReadinessOrigin ? `\n\n${customRouteAccessHint(result.customRouteReadinessOrigin).join("\n")}` : ""}`;
|
|
3426
3595
|
case "readiness-failed": return ["deploy: the uploaded Worker Version did not pass /__void/ready.", formatCloudflareReadinessRestoration(result)].join("\n");
|
|
3427
|
-
case "readiness-access-denied":
|
|
3428
|
-
|
|
3429
|
-
|
|
3430
|
-
|
|
3431
|
-
|
|
3432
|
-
|
|
3433
|
-
|
|
3596
|
+
case "readiness-access-denied":
|
|
3597
|
+
if (result.customRouteReadinessOrigin) return [
|
|
3598
|
+
"deploy: Cloudflare Access blocked the uploaded Worker Version readiness probe.",
|
|
3599
|
+
...customRouteAccessHint(result.customRouteReadinessOrigin),
|
|
3600
|
+
ATOMIC_ACCESS_ALTERNATIVE,
|
|
3601
|
+
formatCloudflareReadinessRestoration(result)
|
|
3602
|
+
].join("\n");
|
|
3603
|
+
return [
|
|
3604
|
+
"deploy: Cloudflare Access blocked the uploaded Worker Version readiness probe.",
|
|
3605
|
+
"For CI, set CF_ACCESS_CLIENT_ID and CF_ACCESS_CLIENT_SECRET to an admitted service token.",
|
|
3606
|
+
"For a local deploy, set CF_ACCESS_TOKEN to a short-lived user JWT from cloudflared.",
|
|
3607
|
+
"If the response is error 1050, create an Access application for this hostname; a token alone cannot bypass account default-deny.",
|
|
3608
|
+
`Then retry. ${formatCloudflareReadinessRestoration(result)}`
|
|
3609
|
+
].join("\n");
|
|
3434
3610
|
case "bootstrap-failed": return `deploy: Cloudflare could not bootstrap the first Worker deployment${status}.${cloudflareCode}${diagnostic}`;
|
|
3435
|
-
case "bootstrap-output-invalid":
|
|
3611
|
+
case "bootstrap-output-invalid":
|
|
3612
|
+
if (result.versionId) return formatCloudflarePublishWithoutUrl(`Cloudflare published the first Worker deployment as version ${result.versionId}`, `If the app uses workers.dev, enable workers.dev for this Worker in the Cloudflare dashboard. Then set CLOUDFLARE_WORKERS_SUBDOMAIN to your account subdomain ${WORKERS_SUBDOMAIN_EXAMPLE}.`);
|
|
3613
|
+
return ["deploy: Cloudflare bootstrapped the first Worker deployment, but Wrangler", "did not report its version id. Inspect `void project status` before retrying."].join("\n");
|
|
3436
3614
|
case "bootstrap-readiness-failed": return [
|
|
3437
3615
|
"deploy: the first Worker deployment did not pass /__void/ready.",
|
|
3438
3616
|
"Cloudflare requires this bootstrap to be non-versioned, so the new Worker is already active;",
|
|
3439
3617
|
"inspect its logs and `void project status` before retrying."
|
|
3440
3618
|
].join("\n") + diagnostic;
|
|
3441
|
-
case "bootstrap-readiness-access-denied":
|
|
3442
|
-
|
|
3443
|
-
|
|
3444
|
-
|
|
3445
|
-
|
|
3446
|
-
|
|
3447
|
-
|
|
3448
|
-
|
|
3619
|
+
case "bootstrap-readiness-access-denied":
|
|
3620
|
+
if (result.customRouteReadinessOrigin) return [
|
|
3621
|
+
"deploy: Cloudflare Access blocked the first Worker deployment readiness probe.",
|
|
3622
|
+
"Cloudflare requires the first deployment to be non-versioned, so the new Worker is already active behind Access.",
|
|
3623
|
+
...customRouteAccessHint(result.customRouteReadinessOrigin),
|
|
3624
|
+
"Later deploys check readiness before traffic moves, so they need the same setting.",
|
|
3625
|
+
ATOMIC_ACCESS_ALTERNATIVE
|
|
3626
|
+
].join("\n");
|
|
3627
|
+
return [
|
|
3628
|
+
"deploy: Cloudflare Access blocked the first Worker deployment readiness probe.",
|
|
3629
|
+
"For CI, set CF_ACCESS_CLIENT_ID and CF_ACCESS_CLIENT_SECRET to an admitted service token;",
|
|
3630
|
+
"for a local deploy, set CF_ACCESS_TOKEN to a short-lived user JWT from cloudflared.",
|
|
3631
|
+
"If the response is error 1050, create an Access application for this hostname; a token alone cannot bypass account default-deny.",
|
|
3632
|
+
"Then retry. Cloudflare requires the first deployment to be non-versioned, so the new",
|
|
3633
|
+
"Worker is already active behind Access."
|
|
3634
|
+
].join("\n");
|
|
3449
3635
|
case "activation-failed": return `deploy: the ready Worker Version could not be activated${status}; production traffic is unchanged.`;
|
|
3450
3636
|
case "triggers-failed": return `deploy: the Worker activated, but Cloudflare trigger synchronization failed${status}. ${result.rollback === "succeeded" ? "Traffic was restored to the previous version." : result.rollback === "unavailable" ? result.previousVersionId === null ? "This was the first deployment, so no previous version was available to restore." : "Traffic or trigger restoration could not be completed. Inspect its routes, schedules, queues, and workflows in Cloudflare before retrying." : "Automatic traffic restoration failed; inspect `void project status` immediately."}`;
|
|
3451
3637
|
}
|
|
3452
3638
|
}
|
|
3639
|
+
/** Explain why a custom-route readiness probe carried no Access credentials. */
|
|
3640
|
+
function customRouteAccessHint(origin) {
|
|
3641
|
+
return [
|
|
3642
|
+
`Void did not send Access credentials to ${origin}. A route or Custom Domain receives them only when CF_ACCESS_READINESS_ORIGIN names its origin.`,
|
|
3643
|
+
`If Access protects ${origin} and admits your credentials, set CF_ACCESS_READINESS_ORIGIN=${origin} with CF_ACCESS_CLIENT_ID and CF_ACCESS_CLIENT_SECRET, or CF_ACCESS_TOKEN. Then retry.`,
|
|
3644
|
+
"Set it only if you control this hostname and it serves this Worker, because Void sends your Access credentials to it."
|
|
3645
|
+
];
|
|
3646
|
+
}
|
|
3647
|
+
const ATOMIC_ACCESS_ALTERNATIVE = "For a Worker with Durable Object migration history, `void deploy --platform cloudflare --atomic` publishes without the zero-traffic check. The new version receives traffic first, and the command still exits with an error because Void cannot verify readiness through Access.";
|
|
3453
3648
|
function formatCloudflareReadinessRestoration(result) {
|
|
3454
3649
|
switch (result.rollback) {
|
|
3455
3650
|
case "succeeded": return "The failed version remains inactive, and traffic was restored to the previous version.";
|
|
@@ -3459,6 +3654,16 @@ function formatCloudflareReadinessRestoration(result) {
|
|
|
3459
3654
|
default: return "The failed version remains inactive for inspection; production traffic is unchanged.";
|
|
3460
3655
|
}
|
|
3461
3656
|
}
|
|
3657
|
+
const WORKERS_SUBDOMAIN_EXAMPLE = "(for example \"my-team\", or \"my-team.fed\" for FedRAMP High)";
|
|
3658
|
+
/** Explain a live version whose readiness URL Void could not determine. */
|
|
3659
|
+
function formatCloudflarePublishWithoutUrl(published, recovery) {
|
|
3660
|
+
return [
|
|
3661
|
+
`deploy: ${published}, but Void could not determine its URL.`,
|
|
3662
|
+
"Void did not update its routes, workers.dev setting, or other triggers, and did not check /__void/ready.",
|
|
3663
|
+
recovery,
|
|
3664
|
+
"Then inspect `void project status` before you deploy again."
|
|
3665
|
+
].join("\n");
|
|
3666
|
+
}
|
|
3462
3667
|
/** Capture the Access credential used only by the guarded Worker readiness probe. */
|
|
3463
3668
|
function cloudflareWorkerReadinessHeaders() {
|
|
3464
3669
|
return trustedCloudflareWorkerAccessHeaders({
|
|
@@ -3494,6 +3699,7 @@ async function prepareCloudflareFrameworkArtifact(options) {
|
|
|
3494
3699
|
await generateDeployWrapperIfNeeded(root, join(root, preset.workerDir), preset.workerMain, {
|
|
3495
3700
|
crons,
|
|
3496
3701
|
queues,
|
|
3702
|
+
cloudflareQueueNames: options.cloudflareQueueNames,
|
|
3497
3703
|
hasMigrations: false,
|
|
3498
3704
|
migrationDialect: analysis.dialect,
|
|
3499
3705
|
readiness: true,
|
|
@@ -3585,10 +3791,11 @@ async function runCloudflareStaticDeploy(root, options, voidConfig, preset, cliL
|
|
|
3585
3791
|
configPath,
|
|
3586
3792
|
rootConfig: parseRootWranglerConfig(configPath),
|
|
3587
3793
|
deps,
|
|
3588
|
-
persistAccount: !(options.reuseExistingWorker || initialCloudflareLink)
|
|
3794
|
+
persistAccount: !(options.reuseExistingWorker || initialCloudflareLink),
|
|
3795
|
+
readinessAccessOrigin: options.readinessAccessOrigin
|
|
3589
3796
|
});
|
|
3590
3797
|
if (!connection || !await confirmCloudflareDeployAuthentication(connection, configPath)) return exit(1);
|
|
3591
|
-
const { apiBaseUrl, usesCf, cfUploaderIsPinned, assertUploaderStillPinned, accountId, workersDevSubdomain, runWrangler } = connection;
|
|
3798
|
+
const { apiBaseUrl, complianceRegion, usesCf, cfUploaderIsPinned, assertUploaderStillPinned, accountId, workersDevSubdomain, readinessAccessOrigin, runWrangler } = connection;
|
|
3592
3799
|
const existingWorker = await prepareExistingCloudflareDeployWithAuth({
|
|
3593
3800
|
root,
|
|
3594
3801
|
configPath,
|
|
@@ -3636,11 +3843,13 @@ async function runCloudflareStaticDeploy(root, options, voidConfig, preset, cliL
|
|
|
3636
3843
|
const merged = mergeAndLintRoutingRules(preset.outputDir, voidConfig.routing);
|
|
3637
3844
|
const manifest = buildStaticManifest({
|
|
3638
3845
|
appType: preset.appType,
|
|
3846
|
+
alwaysUseHttps: voidConfig.routing?.alwaysUseHttps,
|
|
3639
3847
|
hashedAssetsPrefix: "assets",
|
|
3640
3848
|
headerRules: merged.headerRules,
|
|
3641
3849
|
redirectRules: merged.redirectRules,
|
|
3642
3850
|
fallbackRules: merged.fallbackRules,
|
|
3643
|
-
notFound: voidConfig.routing?.notFound
|
|
3851
|
+
notFound: voidConfig.routing?.notFound,
|
|
3852
|
+
html_handling: readWranglerHtmlHandling(rootConfig)
|
|
3644
3853
|
});
|
|
3645
3854
|
const entryPath = join(root, ".void", "deploy", "cloudflare", "static-edge.mjs");
|
|
3646
3855
|
mkdirSync(dirname(entryPath), { recursive: true });
|
|
@@ -3667,6 +3876,7 @@ async function runCloudflareStaticDeploy(root, options, voidConfig, preset, cliL
|
|
|
3667
3876
|
}, null, 2)}\n`, { mode: 384 });
|
|
3668
3877
|
writeFileSync(entryPath, renderCloudflareStaticEntry({
|
|
3669
3878
|
runtimeImport: "void/edge",
|
|
3879
|
+
alwaysUseHttps: manifest.alwaysUseHttps,
|
|
3670
3880
|
headerRules: manifest.headerRules,
|
|
3671
3881
|
redirectRules: manifest.redirectRules,
|
|
3672
3882
|
fallbackRules: manifest.fallbackRules,
|
|
@@ -3715,8 +3925,10 @@ async function runCloudflareStaticDeploy(root, options, voidConfig, preset, cliL
|
|
|
3715
3925
|
uploadConfigPath: staticConfigPath,
|
|
3716
3926
|
accountId,
|
|
3717
3927
|
apiBaseUrl,
|
|
3928
|
+
complianceRegion,
|
|
3718
3929
|
workerName,
|
|
3719
3930
|
workersDevSubdomain,
|
|
3931
|
+
readinessAccessOrigin,
|
|
3720
3932
|
runWrangler,
|
|
3721
3933
|
readExistingWorker: deps.readExistingWorker,
|
|
3722
3934
|
existingWorker,
|
|
@@ -4155,12 +4367,14 @@ async function buildCloudflareWorker(input) {
|
|
|
4155
4367
|
const buildChildEnv = scrubManagedDeployBuildMarkers(scrubWranglerAuthCredentials(deployChildEnv(accountId, apiBaseUrl)));
|
|
4156
4368
|
deleteEnvVarCaseAware(buildChildEnv, CLOUDFLARE_DEPLOY_BUILD_ENV);
|
|
4157
4369
|
buildChildEnv[CLOUDFLARE_DEPLOY_BUILD_ENV] = "1";
|
|
4370
|
+
deleteEnvVarCaseAware(buildChildEnv, CLOUDFLARE_QUEUE_NAMES_BUILD_ENV);
|
|
4371
|
+
if (desired.queueNames) buildChildEnv[CLOUDFLARE_QUEUE_NAMES_BUILD_ENV] = JSON.stringify(desired.queueNames);
|
|
4158
4372
|
deleteEnvVarCaseAware(buildChildEnv, CLOUDFLARE_PRESERVE_BINDINGS_BUILD_ENV);
|
|
4159
4373
|
if (existingWorker) buildChildEnv[CLOUDFLARE_PRESERVE_BINDINGS_BUILD_ENV] = "1";
|
|
4160
4374
|
deleteEnvVarCaseAware(buildChildEnv, "NODE_ENV");
|
|
4161
4375
|
buildChildEnv.NODE_ENV = "production";
|
|
4162
4376
|
const runBuild = deps.runBuild ?? ((env) => {
|
|
4163
|
-
const command =
|
|
4377
|
+
const command = resolveFullDeployBuildCommand(root, voidConfig.inference?.build, frameworkPreset?.buildCommand).command;
|
|
4164
4378
|
execSync(command, {
|
|
4165
4379
|
cwd: root,
|
|
4166
4380
|
stdio: "inherit",
|
|
@@ -4185,7 +4399,8 @@ async function buildCloudflareWorker(input) {
|
|
|
4185
4399
|
preset: frameworkPreset,
|
|
4186
4400
|
requiredSecretNames: schemaFacts.requiredKeys,
|
|
4187
4401
|
ai: needsAI ? { binding: aiBindingName } : void 0,
|
|
4188
|
-
preserveBindings: existingWorker !== null
|
|
4402
|
+
preserveBindings: existingWorker !== null,
|
|
4403
|
+
cloudflareQueueNames: desired.queueNames
|
|
4189
4404
|
});
|
|
4190
4405
|
} catch (error) {
|
|
4191
4406
|
log$1.error(`deploy: could not prepare ${detectedFramework.name} for Cloudflare — ${getErrorMessage(error)}`);
|
|
@@ -4301,7 +4516,7 @@ async function buildCloudflareWorker(input) {
|
|
|
4301
4516
|
projectRoot: root,
|
|
4302
4517
|
configPath: generatedConfigPath,
|
|
4303
4518
|
accountId
|
|
4304
|
-
}) : prepareCfBuildOutput(dirname(generatedConfigPath), accountId);
|
|
4519
|
+
}) : prepareCfBuildOutput(dirname(generatedConfigPath), accountId, void 0, root);
|
|
4305
4520
|
if (usesCf) {
|
|
4306
4521
|
const preflight = await prepareBuildOutput();
|
|
4307
4522
|
if (!preflight) {
|
|
@@ -4639,6 +4854,114 @@ function existingAddresses(rootConfig, pre) {
|
|
|
4639
4854
|
return Array.isArray(rootConfig.addresses) ? rootConfig.addresses.map((a) => typeof a === "string" ? a.toLowerCase() : "").filter((a) => pre.addresses.includes(a)) : [];
|
|
4640
4855
|
}
|
|
4641
4856
|
//#endregion
|
|
4857
|
+
//#region src/cli/deploy-cloudflare-queues.ts
|
|
4858
|
+
function isValidQueueName(name) {
|
|
4859
|
+
try {
|
|
4860
|
+
assertValidResourceName("queue", name);
|
|
4861
|
+
return true;
|
|
4862
|
+
} catch {
|
|
4863
|
+
return false;
|
|
4864
|
+
}
|
|
4865
|
+
}
|
|
4866
|
+
/**
|
|
4867
|
+
* Pick each queue's Cloudflare name from the account's queues and write it into `desired`.
|
|
4868
|
+
* Returns the chosen names that do not exist yet, or a message that blocks the deploy.
|
|
4869
|
+
*/
|
|
4870
|
+
async function chooseCloudflareQueueNames(input) {
|
|
4871
|
+
const { desired, workerName, configPath, runWrangler } = input;
|
|
4872
|
+
if (!desired.queueNames) return {
|
|
4873
|
+
ok: true,
|
|
4874
|
+
absent: []
|
|
4875
|
+
};
|
|
4876
|
+
const lookup = async (name) => {
|
|
4877
|
+
const info = await Promise.resolve(runWrangler({
|
|
4878
|
+
type: "queues.info",
|
|
4879
|
+
name,
|
|
4880
|
+
configPath
|
|
4881
|
+
}, { capture: true }));
|
|
4882
|
+
if (isQueueConfirmedAbsent(info)) return null;
|
|
4883
|
+
const data = info.data;
|
|
4884
|
+
if (!isCleanCloudflareExit(info) || !isRecord(data) || data.name !== name || !Array.isArray(data.consumers)) throw new Error(`deploy: could not read Cloudflare queue ${name} and its consumers. Retry \`void deploy --platform cloudflare\`.`);
|
|
4885
|
+
return { consumers: data.consumers };
|
|
4886
|
+
};
|
|
4887
|
+
const invalid = Object.keys(desired.queueNames).filter((queueName) => !isValidQueueName(queueName)).map((queueName) => ` • ${queueName} (queue)`);
|
|
4888
|
+
if (invalid.length > 0) return {
|
|
4889
|
+
ok: false,
|
|
4890
|
+
message: [
|
|
4891
|
+
"Deploy blocked — these queue names are not valid Cloudflare queue names:",
|
|
4892
|
+
...invalid,
|
|
4893
|
+
"",
|
|
4894
|
+
"A queue takes its name from its path in queues/; nested segments are joined with \"-\".",
|
|
4895
|
+
"A queue name must be 1–63 characters, contain only letters, digits and \"-\", and",
|
|
4896
|
+
"begin and end with a letter or digit.",
|
|
4897
|
+
"",
|
|
4898
|
+
"Rename the offending file(s) in queues/ and retry."
|
|
4899
|
+
].join("\n")
|
|
4900
|
+
};
|
|
4901
|
+
const queueNames = desired.queueNames;
|
|
4902
|
+
const clashes = Object.keys(queueNames).filter((queueName) => Object.hasOwn(queueNames, queueNames[queueName])).map((queueName) => ` • ${queueName} uses the Cloudflare queue ${queueNames[queueName]}, which is also a queue in queues/`);
|
|
4903
|
+
if (clashes.length > 0) return {
|
|
4904
|
+
ok: false,
|
|
4905
|
+
message: [
|
|
4906
|
+
"Deploy blocked — these queues would share a Cloudflare queue:",
|
|
4907
|
+
...clashes,
|
|
4908
|
+
"",
|
|
4909
|
+
`A queue's Cloudflare name is the Worker name, "-", then its name from queues/.`,
|
|
4910
|
+
"Rename one of the files in queues/, then retry."
|
|
4911
|
+
].join("\n")
|
|
4912
|
+
};
|
|
4913
|
+
const names = {};
|
|
4914
|
+
const absent = [];
|
|
4915
|
+
const tooLong = [];
|
|
4916
|
+
const taken = [];
|
|
4917
|
+
for (const queueName of Object.keys(desired.queueNames)) {
|
|
4918
|
+
const scopedName = desired.queueNames[queueName];
|
|
4919
|
+
const scoped = isValidQueueName(scopedName) ? await lookup(scopedName) : null;
|
|
4920
|
+
const plain = scoped?.consumers.includes(workerName) ? void 0 : await lookup(queueName);
|
|
4921
|
+
const choice = chooseCloudflareQueueName({
|
|
4922
|
+
workerName,
|
|
4923
|
+
queueName,
|
|
4924
|
+
scopedName,
|
|
4925
|
+
scoped,
|
|
4926
|
+
plain
|
|
4927
|
+
});
|
|
4928
|
+
names[queueName] = choice.name;
|
|
4929
|
+
if (!isValidQueueName(choice.name)) {
|
|
4930
|
+
tooLong.push(` • ${choice.name} (${choice.name.length} characters)`);
|
|
4931
|
+
continue;
|
|
4932
|
+
}
|
|
4933
|
+
const state = choice.kept ? plain : scoped;
|
|
4934
|
+
if (state === null) absent.push(choice.name);
|
|
4935
|
+
for (const consumer of otherQueueConsumers(state, workerName)) taken.push(` • ${choice.name} is consumed by ${consumer === null ? "a non-Worker (HTTP pull) consumer" : `Worker ${consumer}`}`);
|
|
4936
|
+
if (choice.kept) input.info(`Queue ${queueName} keeps its Cloudflare name ${choice.name}, because this Worker already consumes it.`);
|
|
4937
|
+
}
|
|
4938
|
+
if (tooLong.length > 0) return {
|
|
4939
|
+
ok: false,
|
|
4940
|
+
message: [
|
|
4941
|
+
"Deploy blocked — these Cloudflare queue names are longer than 63 characters:",
|
|
4942
|
+
...tooLong,
|
|
4943
|
+
"",
|
|
4944
|
+
`A queue's Cloudflare name is the Worker name, "-", then its name from queues/.`,
|
|
4945
|
+
"Shorten the Worker name or rename the file(s) in queues/, then retry."
|
|
4946
|
+
].join("\n")
|
|
4947
|
+
};
|
|
4948
|
+
if (taken.length > 0) return {
|
|
4949
|
+
ok: false,
|
|
4950
|
+
message: [
|
|
4951
|
+
`Deploy blocked — Worker ${workerName} cannot consume these queues:`,
|
|
4952
|
+
...taken,
|
|
4953
|
+
"",
|
|
4954
|
+
"A Cloudflare queue has one consumer. Rename the file in queues/ or the Worker, then retry."
|
|
4955
|
+
].join("\n")
|
|
4956
|
+
};
|
|
4957
|
+
desired.queueNames = names;
|
|
4958
|
+
desired.queues = Object.values(names);
|
|
4959
|
+
return {
|
|
4960
|
+
ok: true,
|
|
4961
|
+
absent
|
|
4962
|
+
};
|
|
4963
|
+
}
|
|
4964
|
+
//#endregion
|
|
4642
4965
|
//#region src/cli/deploy-cloudflare-preflight.ts
|
|
4643
4966
|
/** Validate source-level native deploy inputs before account operations or project code. */
|
|
4644
4967
|
async function prepareCloudflareDeploySource(root, options, voidConfig) {
|
|
@@ -4716,10 +5039,11 @@ async function preflightCloudflareWorker(input) {
|
|
|
4716
5039
|
configPath,
|
|
4717
5040
|
rootConfig,
|
|
4718
5041
|
deps,
|
|
4719
|
-
persistAccount: !(options.reuseExistingWorker || initialCloudflareLink)
|
|
5042
|
+
persistAccount: !(options.reuseExistingWorker || initialCloudflareLink),
|
|
5043
|
+
readinessAccessOrigin: options.readinessAccessOrigin
|
|
4720
5044
|
});
|
|
4721
5045
|
if (!connection) return exit(1);
|
|
4722
|
-
const { apiBaseUrl, usesCf, cfUploaderIsPinned, assertUploaderStillPinned, accountId, workersDevSubdomain, runWrangler } = connection;
|
|
5046
|
+
const { apiBaseUrl, complianceRegion, usesCf, cfUploaderIsPinned, assertUploaderStillPinned, accountId, workersDevSubdomain, readinessAccessOrigin, runWrangler } = connection;
|
|
4723
5047
|
rootConfig = connection.rootConfig;
|
|
4724
5048
|
const workerName = readWranglerTopLevelString(rootConfig, "name") ?? deriveWorkerName(root);
|
|
4725
5049
|
printDeployContext(workerName, "Cloudflare");
|
|
@@ -4895,53 +5219,38 @@ async function preflightCloudflareWorker(input) {
|
|
|
4895
5219
|
return exit(1);
|
|
4896
5220
|
}
|
|
4897
5221
|
};
|
|
4898
|
-
|
|
4899
|
-
|
|
4900
|
-
|
|
4901
|
-
|
|
4902
|
-
|
|
4903
|
-
|
|
4904
|
-
|
|
4905
|
-
|
|
4906
|
-
} catch {
|
|
4907
|
-
return true;
|
|
4908
|
-
}
|
|
5222
|
+
let queueNames;
|
|
5223
|
+
try {
|
|
5224
|
+
queueNames = await chooseCloudflareQueueNames({
|
|
5225
|
+
desired,
|
|
5226
|
+
workerName,
|
|
5227
|
+
configPath,
|
|
5228
|
+
runWrangler,
|
|
5229
|
+
info: (message) => log$1.info(message)
|
|
4909
5230
|
});
|
|
4910
|
-
|
|
4911
|
-
|
|
4912
|
-
|
|
4913
|
-
|
|
4914
|
-
|
|
4915
|
-
|
|
4916
|
-
|
|
4917
|
-
"begin and end with a letter or digit.",
|
|
4918
|
-
"",
|
|
4919
|
-
"Rename the offending file(s) in queues/ and retry."
|
|
4920
|
-
].join("\n"));
|
|
4921
|
-
return exit(1);
|
|
4922
|
-
}
|
|
4923
|
-
const absentQueues = [];
|
|
4924
|
-
for (const name of desired.queues) {
|
|
4925
|
-
const info = await Promise.resolve(runWrangler({
|
|
4926
|
-
type: "queues.info",
|
|
4927
|
-
name,
|
|
4928
|
-
configPath
|
|
4929
|
-
}, { capture: true }));
|
|
4930
|
-
if (isQueueConfirmedAbsent(info)) absentQueues.push(name);
|
|
4931
|
-
}
|
|
4932
|
-
if (absentQueues.length > 0) await provisionAndVerify();
|
|
5231
|
+
} catch (error) {
|
|
5232
|
+
log$1.error(getErrorMessage(error));
|
|
5233
|
+
return exit(1);
|
|
5234
|
+
}
|
|
5235
|
+
if (!queueNames.ok) {
|
|
5236
|
+
log$1.error(queueNames.message);
|
|
5237
|
+
return exit(1);
|
|
4933
5238
|
}
|
|
5239
|
+
const absentQueues = queueNames.absent;
|
|
5240
|
+
const { missing: initiallyMissing } = checkCloudflareProvisionDrift(configPath, desired);
|
|
5241
|
+
const d1NeedsConfigReconciliation = !existingWorker && d1MigrationsDirMissing();
|
|
5242
|
+
if (options.provision || initiallyMissing.length > 0 || d1NeedsConfigReconciliation || absentQueues.length > 0) await provisionAndVerify();
|
|
4934
5243
|
const frameworkQueues = detectedFramework ? source.analysis.queues : [];
|
|
4935
5244
|
writeProvisionedWranglerConfig(root, {
|
|
4936
5245
|
name: workerName,
|
|
4937
5246
|
accountId,
|
|
4938
5247
|
...detectedFramework ? { queues: {
|
|
4939
5248
|
producers: frameworkQueues.map((queue) => ({
|
|
4940
|
-
queue: queue.name,
|
|
5249
|
+
queue: cloudflareQueueName(queue.name, desired.queueNames),
|
|
4941
5250
|
binding: queue.bindingName
|
|
4942
5251
|
})),
|
|
4943
5252
|
consumers: frameworkQueues.map((queue) => ({
|
|
4944
|
-
queue: queue.name,
|
|
5253
|
+
queue: cloudflareQueueName(queue.name, desired.queueNames),
|
|
4945
5254
|
...queue.maxBatchSize != null && { max_batch_size: queue.maxBatchSize },
|
|
4946
5255
|
...queue.maxBatchTimeout != null && { max_batch_timeout: queue.maxBatchTimeout },
|
|
4947
5256
|
...queue.maxRetries != null && { max_retries: queue.maxRetries },
|
|
@@ -4962,11 +5271,13 @@ async function preflightCloudflareWorker(input) {
|
|
|
4962
5271
|
});
|
|
4963
5272
|
return {
|
|
4964
5273
|
apiBaseUrl,
|
|
5274
|
+
complianceRegion,
|
|
4965
5275
|
usesCf,
|
|
4966
5276
|
cfUploaderIsPinned,
|
|
4967
5277
|
assertUploaderStillPinned,
|
|
4968
5278
|
accountId,
|
|
4969
5279
|
workersDevSubdomain,
|
|
5280
|
+
readinessAccessOrigin,
|
|
4970
5281
|
runWrangler,
|
|
4971
5282
|
workerName,
|
|
4972
5283
|
emailMap,
|
|
@@ -4987,7 +5298,7 @@ async function preflightCloudflareWorker(input) {
|
|
|
4987
5298
|
async function publishCloudflareWorker(input) {
|
|
4988
5299
|
const { root, deps, exit, cliLog, atomic, detectedFramework, initialCloudflareCandidate } = input;
|
|
4989
5300
|
const { configPath, needsSandbox, desired, analysis } = input.source;
|
|
4990
|
-
const { usesCf, existingWorker, pinnedHandoffLink, accountId, workerName, cfUploaderIsPinned, apiBaseUrl, runWrangler, assertUploaderStillPinned, schemaFacts, approvedHandoffKv, workersDevSubdomain } = input.preflight;
|
|
5301
|
+
const { usesCf, existingWorker, pinnedHandoffLink, accountId, workerName, cfUploaderIsPinned, apiBaseUrl, complianceRegion, runWrangler, assertUploaderStillPinned, schemaFacts, approvedHandoffKv, workersDevSubdomain, readinessAccessOrigin } = input.preflight;
|
|
4991
5302
|
const { migrations, d1MigrateToken, generatedConfigPath, prepareBuildOutput } = input.build;
|
|
4992
5303
|
const { workerWasMissingBeforeSecretProvisioning, initialAuthSecret, appliedMigrations } = input.migration;
|
|
4993
5304
|
const queueConsumerCleanup = readWranglerManagedQueueCleanupCandidates(configPath);
|
|
@@ -5029,8 +5340,10 @@ async function publishCloudflareWorker(input) {
|
|
|
5029
5340
|
uploadConfigPath: generatedConfigPath,
|
|
5030
5341
|
accountId,
|
|
5031
5342
|
apiBaseUrl,
|
|
5343
|
+
complianceRegion,
|
|
5032
5344
|
workerName,
|
|
5033
5345
|
workersDevSubdomain,
|
|
5346
|
+
readinessAccessOrigin,
|
|
5034
5347
|
runWrangler,
|
|
5035
5348
|
readExistingWorker: deps.readExistingWorker,
|
|
5036
5349
|
existingWorker,
|
|
@@ -5081,6 +5394,7 @@ async function publishCloudflareWorker(input) {
|
|
|
5081
5394
|
//#region src/cli/deploy-cloudflare.ts
|
|
5082
5395
|
/** Deploy to the user's own Cloudflare account through the guarded native Worker flow. */
|
|
5083
5396
|
async function runCloudflareDeploy(root, options, cliLog, deps = {}) {
|
|
5397
|
+
options = withRecordedReadinessAccessOrigin(options);
|
|
5084
5398
|
const initialCloudflareLink = readCloudflareLink(root);
|
|
5085
5399
|
const initialCloudflareCandidate = readCloudflareCandidate(root);
|
|
5086
5400
|
const exit = deps.exit ?? ((code) => process.exit(code));
|
|
@@ -5117,6 +5431,14 @@ async function runCloudflareDeploy(root, options, cliLog, deps = {}) {
|
|
|
5117
5431
|
}
|
|
5118
5432
|
return runCloudflareStaticDeploy(root, options, voidConfig, staticPreset, cliLog, deps, initialCloudflareLink, initialCloudflareCandidate);
|
|
5119
5433
|
}
|
|
5434
|
+
if (detectedFramework && voidConfig.routing?.alwaysUseHttps === true) {
|
|
5435
|
+
log$1.error([
|
|
5436
|
+
`deploy: native Cloudflare deployment cannot apply Void routing.alwaysUseHttps to ${detectedFramework.name}.`,
|
|
5437
|
+
"This framework owns its Worker request handler, so the HTTPS redirect would otherwise be ignored.",
|
|
5438
|
+
"Redirect HTTP to HTTPS in the framework, or turn on Cloudflare's Always Use HTTPS setting for your zone, then remove routing.alwaysUseHttps and retry."
|
|
5439
|
+
].join("\n"));
|
|
5440
|
+
return exit(1);
|
|
5441
|
+
}
|
|
5120
5442
|
const source = await prepareCloudflareDeploySource(root, options, voidConfig);
|
|
5121
5443
|
if (!source) return exit(1);
|
|
5122
5444
|
const preflight = await preflightCloudflareWorker({
|
|
@@ -5286,6 +5608,7 @@ async function runFrameworkDeploy(root, config, client, detected, fwPreset, void
|
|
|
5286
5608
|
};
|
|
5287
5609
|
const manifest = buildFrameworkManifest({
|
|
5288
5610
|
frameworkName: detected.name,
|
|
5611
|
+
alwaysUseHttps: voidConfig.routing?.alwaysUseHttps,
|
|
5289
5612
|
workerMain: actualWorkerMain,
|
|
5290
5613
|
bindings,
|
|
5291
5614
|
migrations: validatedMigrations,
|
|
@@ -5392,7 +5715,7 @@ async function runFullDeploy(root, config, client, voidConfig, fwPreset, skipBui
|
|
|
5392
5715
|
voidToken: await client.createPrerenderToken(config.projectId)
|
|
5393
5716
|
});
|
|
5394
5717
|
if (result.paths.length === 0) log$1.info("No pages to prerender");
|
|
5395
|
-
else
|
|
5718
|
+
else assertNoPrerenderFailures(result.failed);
|
|
5396
5719
|
}
|
|
5397
5720
|
const analysis = await analyzeApplication(root, {
|
|
5398
5721
|
config: voidConfig,
|
|
@@ -5459,7 +5782,7 @@ async function runFullDeploy(root, config, client, voidConfig, fwPreset, skipBui
|
|
|
5459
5782
|
buildCommand: null,
|
|
5460
5783
|
outputDir: clientDir,
|
|
5461
5784
|
appType: "static"
|
|
5462
|
-
}, true, gitMetadata, assetsPrefix, headerRules, redirectRules, fallbackRules, void 0, cliLog, voidConfig.routing?.notFound);
|
|
5785
|
+
}, true, gitMetadata, assetsPrefix, headerRules, redirectRules, fallbackRules, void 0, cliLog, voidConfig.routing?.notFound, voidConfig.routing?.alwaysUseHttps);
|
|
5463
5786
|
}
|
|
5464
5787
|
}
|
|
5465
5788
|
const prerenderSourcesPresent = hasPrerenderSources({
|
|
@@ -5542,6 +5865,7 @@ async function runFullDeploy(root, config, client, voidConfig, fwPreset, skipBui
|
|
|
5542
5865
|
...bindings,
|
|
5543
5866
|
needsLive: true
|
|
5544
5867
|
} : bindings,
|
|
5868
|
+
alwaysUseHttps: voidConfig.routing?.alwaysUseHttps,
|
|
5545
5869
|
hasEmailHandlers: !isFrameworkMode && routeScan.email !== void 0 && hasEmailHandlers(routeScan.email),
|
|
5546
5870
|
migrations: validatedMigrations,
|
|
5547
5871
|
schedules,
|
|
@@ -6044,6 +6368,7 @@ function resolveDeploymentPlatform(root, options) {
|
|
|
6044
6368
|
}
|
|
6045
6369
|
/** Run `void deploy`; a failure carries a summary of the deploy log in its message. */
|
|
6046
6370
|
async function runDeploy(root, options) {
|
|
6371
|
+
options = withRecordedReadinessAccessOrigin(options ?? {});
|
|
6047
6372
|
console.log();
|
|
6048
6373
|
const cliLog = openDeployLog({ mirrorToStderr: options?.debug === true || process.env.VOID_DEPLOY_DEBUG === "1" });
|
|
6049
6374
|
cliLog.info("deploy_start", {
|