void 0.28.0 → 1.1.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-Ci00cncT.mjs → account-cmd-BTcUzv9L.mjs} +4 -4
- package/dist/{application-analysis-D72ZQfMZ.mjs → application-analysis-AB_YYWgH.mjs} +1 -1
- package/dist/{application-routing-Dy589Vgn.mjs → application-routing-L7V-TFhZ.mjs} +1 -1
- package/dist/auth-Cbqi1iVX.mjs +1 -0
- package/dist/{auth-link-DWr6Afao.mjs → auth-link-DUJuvRx5.mjs} +4 -4
- package/dist/{auth-router-DP14wVkZ.mjs → auth-router-CIxiMG7i.mjs} +3 -3
- package/dist/{build-cmd-Cr3FJxv0.mjs → build-cmd-BkIv25PA.mjs} +3 -3
- package/dist/{cache-D0Tt28cn.mjs → cache-Ctzfig-W.mjs} +3 -3
- package/dist/{cancel-deploy-CJKvk7AN.mjs → cancel-deploy-CD9o-SsC.mjs} +2 -2
- package/dist/cf-build-output-BU3hqdHu.mjs +1 -0
- package/dist/cli/cli.mjs +31 -31
- package/dist/cli/cloudflare-operation-process.mjs +2 -2
- package/dist/cli/env-schema-probe.d.mts +2 -1
- package/dist/cli/env-schema-probe.mjs +2 -2
- package/dist/client-B60PwCC4.mjs +1 -0
- package/dist/{cloudflare-cmd-CTrn-lXJ.mjs → cloudflare-cmd-BIAF_BIY.mjs} +2 -2
- package/dist/{cloudflare-connect-BosmCNlq.mjs → cloudflare-connect-WjwnVOJA.mjs} +1 -1
- package/dist/{cloudflare-operations-BKdSfNBN.mjs → cloudflare-operations-B42EZeJy.mjs} +3 -3
- package/dist/cloudflare-operations-CrSUFRzJ.mjs +1 -0
- package/dist/collect-Cae8A7Zr.mjs +1 -0
- package/dist/config-QrJWu0IX.mjs +1 -0
- package/dist/{connect-nukQSoEO.mjs → connect-CKtk-EZe.mjs} +5 -5
- package/dist/create-project-B-ewF_Af.mjs +1 -0
- package/dist/{create-project-D4APeBwX.mjs → create-project-yInGo72M.mjs} +3 -3
- package/dist/database-provider.mjs +1 -2
- package/dist/{db-27RztQLy.mjs → db-7I_gfdVq.mjs} +37 -38
- package/dist/db-types-Bb4WBWIs.mjs +49 -0
- package/dist/{delete-BbsZFZIw.mjs → delete-Cy-M1u-r.mjs} +3 -3
- package/dist/deploy-9lgfhrXS.mjs +2 -0
- package/dist/{deploy-B06EQq4t.mjs → deploy-BYYlnsiy.mjs} +176 -21
- package/dist/{deploy-managed-static-CGswbcay.mjs → deploy-managed-static-Ca4TFdmx.mjs} +24 -706
- package/dist/{deploy-transport-BiicfoQW.mjs → deploy-transport-DWlWBe6M.mjs} +1 -1
- package/dist/deploy.mjs +4 -4
- package/dist/discover-ClzFSwns.mjs +1 -0
- package/dist/dispatch-DrTTk8Xg.mjs +431 -0
- package/dist/{dist-D3m88sjf.mjs → dist-BVdsO7Py.mjs} +5 -6
- package/dist/dist-CfgIkieS.mjs +1 -0
- package/dist/{domain-Bfq9n03H.mjs → domain-CZGxPv9u.mjs} +4 -4
- package/dist/edge.mjs +1 -2
- package/dist/{email-DIwaQU4P.mjs → email-DzyNVuoU.mjs} +6 -6
- package/dist/{email-cloudflare-CH053RxK.mjs → email-cloudflare-DfG6UEMm.mjs} +1 -1
- package/dist/{env-BhdWMrNy.mjs → env-0jrMQJI_.mjs} +5 -2
- package/dist/{env-C6ipBLp3.mjs → env-Nx3yf50r.mjs} +4 -4
- package/dist/{env-raw-Cklzcde3.mjs → env-raw-D74P4ebM.mjs} +12 -1
- package/dist/env-validation-BT7z-qpQ.mjs +1 -0
- package/dist/{env-validation-cE0zcmzO.mjs → env-validation-DYxjz_Wo.mjs} +2 -0
- package/dist/{gen-CnN1Xidx.mjs → gen-CufHEf42.mjs} +2 -2
- package/dist/gen-sXyp5DFO.mjs +1 -0
- package/dist/generate-ClI89brV.mjs +1 -0
- package/dist/{github-cmd-BdkU4Nhe.mjs → github-cmd-FU8EjFyU.mjs} +3 -3
- package/dist/{help-Bug7pyK_.mjs → help-BT2hovNI.mjs} +9 -5
- package/dist/help-i2YGGnTH.mjs +1 -0
- package/dist/{inbound-DmkTQeWp.mjs → inbound-BuTfm11U.mjs} +1 -1
- package/dist/index.mjs +551 -303
- package/dist/{info-CujPwtMe.mjs → info-l249eUdH.mjs} +1 -1
- package/dist/{init-ZWOJvc-Z.mjs → init-D0A6M64Q.mjs} +60 -14
- package/dist/{isr-config-DPjXM8J2.mjs → isr-config-fZaJJ8t7.mjs} +1 -30
- package/dist/{link-UEc7bnF4.mjs → link-WMoJFf4i.mjs} +4 -4
- package/dist/{list-CuWeOnzk.mjs → list-CQ2EQEHL.mjs} +4 -4
- package/dist/{live-BxLX-JqJ.mjs → live-BcHoTDFe.mjs} +1 -1
- package/dist/{local-d1-BM3p74mm.mjs → local-d1-BxvQYEFi.mjs} +1 -1
- package/dist/{login-CZ2Cqa-D.mjs → login-C2T1oVG-.mjs} +3 -3
- package/dist/login-XD844Xs-.mjs +1 -0
- package/dist/{logs-TihRcLTk.mjs → logs-DnC1d7xB.mjs} +3 -3
- package/dist/{migrate-uFwojusJ.mjs → migrate-BDIprOYd.mjs} +2 -2
- package/dist/migrate-BRwU-blY.mjs +1 -0
- package/dist/mysql-migration-sql-BIS5vbNk.mjs +241 -0
- package/dist/nitro.d.mts +30 -0
- package/dist/nitro.mjs +88 -0
- package/dist/{node-DoKbo1SZ.mjs → node-cPadMgUO.mjs} +3 -3
- package/dist/operator-cmd-D6gnZsnK.mjs +1 -0
- package/dist/{operator-cmd-C5lCctnc.mjs → operator-cmd-DHieWtFp.mjs} +5 -5
- package/dist/{output-FNHKw5Ac.mjs → output-Ba6ZbrzY.mjs} +1 -1
- package/dist/pages/head.mjs +1 -2
- package/dist/pages/prefetch.mjs +1 -2
- package/dist/pages/serialize.mjs +1 -2
- package/dist/plan-CKX_jWnD.mjs +1 -0
- package/dist/platform-args-B0HeTh0C.mjs +1 -0
- package/dist/{platform-args-C6Mb_I3a.mjs → platform-args-CaCL_1Ch.mjs} +9 -2
- package/dist/{platform-auth-config-CJmNkFT2.mjs → platform-auth-config-Z16-I8nT.mjs} +6 -6
- package/dist/{platform-auth-protection-D5wvsI-Y.mjs → platform-auth-protection-BXwZiJSF.mjs} +4 -4
- package/dist/{platform-auth-recovery-D_0I3n-1.mjs → platform-auth-recovery-CXjfqyOv.mjs} +4 -4
- package/dist/{platform-cmd-DxxZO6e5.mjs → platform-cmd-DaAOiWTl.mjs} +7 -7
- package/dist/platform-cmd-PT4YwMLM.mjs +1 -0
- package/dist/{platform-domain-zLXnW1G_.mjs → platform-domain-CxpvUeo0.mjs} +4 -4
- package/dist/{platform-lifecycle-DOW-wLfx.mjs → platform-lifecycle-DBiS0cJd.mjs} +317 -99
- package/dist/platform-lifecycle-u9pMOvxC.mjs +1 -0
- package/dist/{platform-management-t7HKy4-U.mjs → platform-management-DhEFdQAf.mjs} +67 -9
- package/dist/platform-management-DvBS83rC.mjs +1 -0
- package/dist/{platform-plans-config-CNH6zbPX.mjs → platform-plans-config-BWn1S2Rv.mjs} +2 -2
- package/dist/{platform-recovery-DeucI7A9.mjs → platform-recovery-BUGOB4RC.mjs} +2 -2
- package/dist/{platform-setup-CTf6MMT9.mjs → platform-setup-YvN9VQXV.mjs} +3 -3
- package/dist/prepare-CYT6tAzD.mjs +1 -0
- package/dist/{prepare-CSH9dKTI.mjs → prepare-DEB5SeVJ.mjs} +3 -2
- package/dist/{prepare-C4zfwks4.mjs → prepare-PQCgsny0.mjs} +3 -3
- package/dist/prerender-render.mjs +1 -2
- package/dist/{project-cmd-Dq75AXzy.mjs → project-cmd-DVatD8Ev.mjs} +16 -16
- package/dist/project-slug-6cyz8E7k.mjs +1 -0
- package/dist/{project-team-B3_QcStG.mjs → project-team-DJrWEAG1.mjs} +3 -3
- package/dist/{project-token-CvsRvv2I.mjs → project-token-CBgLBuL6.mjs} +3 -3
- package/dist/project-zdB3fs9G.mjs +1 -0
- package/dist/{project-zero-trust-D1ICiwN_.mjs → project-zero-trust-92gLtZ25.mjs} +3 -3
- package/dist/{provision-DDh7ITVS.mjs → provision-BnSSkiED.mjs} +1 -1
- package/dist/{requests-3CL3BuZh.mjs → requests-7W1Pygt2.mjs} +2 -2
- package/dist/resolve-project-PnhzMtY6.mjs +1 -0
- package/dist/{resolve-project-C_Cu7E8a.mjs → resolve-project-WpwkCB_c.mjs} +1 -1
- package/dist/{rollback-Ce1d_0J9.mjs → rollback-BcASVnwP.mjs} +3 -3
- package/dist/{route-types-IrBuwJ7u.mjs → route-types-BZi26DVS.mjs} +2 -49
- package/dist/{runner-DcVDrzuR.mjs → runner-CabsQ-iM.mjs} +15 -6
- package/dist/runner-So9mYfcm.mjs +1 -0
- package/dist/runner-mysql-BhRaONkO.mjs +146 -0
- package/dist/runner-mysql-DWwE8jKi.mjs +1 -0
- package/dist/{runner-pg-CPd-CB_F.mjs → runner-pg-BRemq_GX.mjs} +2 -2
- package/dist/runner-pg-_Xncr3H5.mjs +1 -0
- package/dist/runtime/ai.mjs +15 -4
- package/dist/runtime/auth-client-react.mjs +1 -2
- package/dist/runtime/auth-client-solid.mjs +1 -2
- package/dist/runtime/auth-client-svelte.mjs +1 -2
- package/dist/runtime/auth-client-vue.mjs +1 -2
- package/dist/runtime/auth-client.mjs +1 -2
- package/dist/runtime/auth.mjs +1 -2
- package/dist/runtime/better-auth-mysql.mjs +4 -1
- package/dist/runtime/db.mjs +6 -2
- package/dist/runtime/durable.d.mts +2 -1
- package/dist/runtime/durable.mjs +1 -1
- package/dist/runtime/email/testing.mjs +1 -1
- package/dist/runtime/email-protocol.mjs +1 -2
- package/dist/runtime/email.mjs +1 -1
- package/dist/runtime/env-public.mjs +2 -2
- package/dist/runtime/env.mjs +1 -2
- package/dist/runtime/isr.mjs +1 -1
- package/dist/runtime/kv.mjs +1 -1
- package/dist/runtime/limits.mjs +1 -2
- package/dist/runtime/live-client.d.mts +2 -1
- package/dist/runtime/live-server.d.mts +2 -1
- package/dist/runtime/live-server.mjs +1 -1
- package/dist/runtime/live.mjs +1 -2
- package/dist/runtime/log.d.mts +2 -1
- package/dist/runtime/migration-handler-mysql.mjs +38 -8
- package/dist/runtime/migration-handler.mjs +1 -2
- package/dist/runtime/queues.mjs +1 -1
- package/dist/runtime/response.mjs +1 -2
- package/dist/runtime/route-url.mjs +1 -2
- package/dist/runtime/routing.d.mts +2 -1
- package/dist/runtime/sandbox-container.mjs +1 -2
- package/dist/runtime/sandbox.mjs +3 -3
- package/dist/runtime/seed.d.mts +2 -1
- package/dist/runtime/sse.mjs +1 -2
- package/dist/runtime/storage.mjs +1 -1
- package/dist/runtime/validator.mjs +1 -2
- package/dist/runtime/ws-server.d.mts +2 -1
- package/dist/runtime/ws-server.mjs +1 -1
- package/dist/{secret-B5J8bBsI.mjs → secret-bg73f1Ge.mjs} +5 -5
- package/dist/{skills-BJsan98C.mjs → skills-C_yRTg0g.mjs} +1 -1
- package/dist/{subcommand-prompt-gQ-NDA-u.mjs → subcommand-prompt-Bm3ZlYgA.mjs} +2 -2
- package/dist/sveltekit.d.mts +2 -1
- package/dist/validate-BQFdf0Pi.mjs +1 -0
- package/dist/wrapper-CwhpNWtH.mjs +663 -0
- package/docs/guide/ai.md +8 -2
- package/docs/guide/database/mysql.md +14 -3
- package/docs/guide/database.md +1 -5
- package/docs/guide/durable-state.md +9 -5
- package/docs/guide/platform/installation/credentials.md +18 -2
- package/docs/guide/platform/installation/domains.md +1 -1
- package/docs/guide/platform/installation/maintenance.md +38 -1
- package/docs/guide/platform/installation/prerequisites.md +6 -2
- package/docs/guide/platform/installation/setup.md +23 -1
- package/docs/guide/platform/installation/uninstall.md +6 -1
- package/docs/guide/sandboxes.md +1 -1
- package/docs/guide/self-hosted-platform.md +1 -1
- package/docs/integrations/cloudflare.md +2 -2
- package/docs/integrations/frameworks/analog.md +3 -11
- package/docs/integrations/frameworks/nuxt.md +7 -10
- package/docs/integrations/nodejs-bun-deno.md +2 -0
- package/docs/reference/api.md +1 -0
- package/docs/reference/cli/platform-installation.md +18 -6
- package/docs/reference/config.md +2 -0
- package/package.json +34 -28
- package/sandbox.Dockerfile +1 -1
- package/skills/void/SKILL.md +1 -1
- package/dist/auth-wn6F8dB8.mjs +0 -2
- package/dist/cf-build-output-2u583yJK.mjs +0 -2
- package/dist/client-C1BjRn3g.mjs +0 -2
- package/dist/cloudflare-operations-Ds-lX3Ts.mjs +0 -2
- package/dist/collect-NUlJMpLY.mjs +0 -2
- package/dist/config-CNnrSMYm.mjs +0 -2
- package/dist/create-project-DL7YXpjj.mjs +0 -2
- package/dist/deploy-Db2ALnQP.mjs +0 -3
- package/dist/discover-CTUiSsfG.mjs +0 -2
- package/dist/dist-Bx1z6Eva.mjs +0 -2
- package/dist/env-validation-CTn-HhG1.mjs +0 -2
- package/dist/gen-F8pSZnhc.mjs +0 -2
- package/dist/generate-Rii9klHB.mjs +0 -2
- package/dist/help-s9q7LTcu.mjs +0 -2
- package/dist/login-DhK7o1oJ.mjs +0 -2
- package/dist/migrate-BgT-hmu8.mjs +0 -2
- package/dist/operator-cmd-Cjk5DiRx.mjs +0 -2
- package/dist/plan-CH2G51je.mjs +0 -2
- package/dist/platform-args-Cm7x-fot.mjs +0 -2
- package/dist/platform-cmd-Cuj4oUVo.mjs +0 -2
- package/dist/platform-lifecycle-_gfnjUBr.mjs +0 -2
- package/dist/platform-management-CYrLvTGH.mjs +0 -2
- package/dist/prepare-dr9uxQSV.mjs +0 -2
- package/dist/project-DiiOBZPF.mjs +0 -2
- package/dist/project-slug-DofjTFd-.mjs +0 -2
- package/dist/resolve-project-B9Hr0D3n.mjs +0 -2
- package/dist/runner-B5huK2eC.mjs +0 -2
- package/dist/runner-mysql-CCtyI0p6.mjs +0 -55
- package/dist/runner-mysql-CaJq-hd6.mjs +0 -2
- package/dist/runner-pg-BJhFZZG4.mjs +0 -2
- package/dist/validate-C9xtFOYR.mjs +0 -2
- package/dist/{sandbox-container-DBKIqDEK.mjs → sandbox-container-a9LRUtii.mjs} +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { a as join, s as relative } from "./dist-ipQi0Q8y.mjs";
|
|
2
2
|
import { a as deriveWebSocketClassNameFromName, o as inferWebSocketResourceName } from "./plugin-inference-DsARdQKE.mjs";
|
|
3
3
|
import { d as readConfig } from "./config-Bx_1SpnO.mjs";
|
|
4
|
-
import { d as deriveDurableResourceIdentity, f as inferDurableResourceName, t as analyzeApplicationSync } from "./application-analysis-
|
|
4
|
+
import { d as deriveDurableResourceIdentity, f as inferDurableResourceName, t as analyzeApplicationSync } from "./application-analysis-AB_YYWgH.mjs";
|
|
5
5
|
import { n as VOID_LOCK_FILE } from "./cloudflare-config-DV60XFFK.mjs";
|
|
6
6
|
import { existsSync, readFileSync } from "node:fs";
|
|
7
7
|
import { isRecord } from "@void/deploy-core";
|
|
@@ -8,21 +8,21 @@ import { r as materializeCloudflareConfig } from "./cloudflare-config-DV60XFFK.m
|
|
|
8
8
|
import { i as LATEST_KNOWN_COMPAT_DATE, j as writeProvisionedWranglerConfig } from "./wrangler-BYs07Rxy.mjs";
|
|
9
9
|
import { i as readPackageJson, n as hasPackageDependency } from "./package-json-BjYqR-So.mjs";
|
|
10
10
|
import { c as getToken } from "./auth-B6iOCjKI.mjs";
|
|
11
|
-
import { A as confirm, K as select, L as log, O as cancel, X as text, tt as isCancel } from "./dist-
|
|
12
|
-
import { l as formatUrl, m as printSuccess, p as note } from "./output-
|
|
11
|
+
import { A as confirm, K as select, L as log, O as cancel, X as text, tt as isCancel } from "./dist-BVdsO7Py.mjs";
|
|
12
|
+
import { l as formatUrl, m as printSuccess, p as note } from "./output-Ba6ZbrzY.mjs";
|
|
13
13
|
import { n as ensureProjectTsconfig, t as createProjectTsconfig } from "./project-tsconfig-bveqhlYA.mjs";
|
|
14
14
|
import { t as parseDotenvFile } from "./dotenv-CNazY3-w.mjs";
|
|
15
15
|
import { r as writeDrizzleConfig, t as PLACEHOLDER_DB_URL } from "./config-BEm9vRvS.mjs";
|
|
16
16
|
import { n as getOwnVersion, r as getPackageDir, t as detectAgents } from "./agents-CuNtT0D_.mjs";
|
|
17
17
|
import { r as PlatformClient } from "./client-DM9Kcf4e.mjs";
|
|
18
|
-
import { a as promptProjectSelection, r as promptAndCreateProject } from "./create-project-
|
|
18
|
+
import { a as promptProjectSelection, r as promptAndCreateProject } from "./create-project-yInGo72M.mjs";
|
|
19
19
|
import { s as formatProjectCommand } from "./cloudflare-process-CeDWJRhj.mjs";
|
|
20
20
|
import { i as hasLocalLockfile, n as drizzleKitBin, r as findInstalledYarnPnpRuntime, t as buildDrizzleKitSpawnEnv } from "./yarn-pnp-DLbEFMT0.mjs";
|
|
21
|
-
import { t as promptForLoginToken } from "./login-
|
|
22
|
-
import { i as saveDiscoveredPlatform, t as discoverPlatform } from "./platform-cmd-
|
|
23
|
-
import { t as connectCloudflare } from "./cloudflare-connect-
|
|
21
|
+
import { t as promptForLoginToken } from "./login-C2T1oVG-.mjs";
|
|
22
|
+
import { i as saveDiscoveredPlatform, t as discoverPlatform } from "./platform-cmd-DaAOiWTl.mjs";
|
|
23
|
+
import { t as connectCloudflare } from "./cloudflare-connect-WjwnVOJA.mjs";
|
|
24
24
|
import { n as snapshotDrizzleOutputs } from "./generate-Dat0UTry.mjs";
|
|
25
|
-
import { i as writeVoidProjectConfig, o as migrateFrameworkAdapterPaths, r as canRewriteVoidProjectConfig, t as migrateLegacyVoidConfig } from "./migrate-
|
|
25
|
+
import { i as writeVoidProjectConfig, o as migrateFrameworkAdapterPaths, r as canRewriteVoidProjectConfig, t as migrateLegacyVoidConfig } from "./migrate-BDIprOYd.mjs";
|
|
26
26
|
import { createRequire } from "node:module";
|
|
27
27
|
import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from "node:fs";
|
|
28
28
|
import { parseSync } from "vite";
|
|
@@ -30,6 +30,7 @@ import { isRecord } from "@void/deploy-core";
|
|
|
30
30
|
import { parseArgs } from "node:util";
|
|
31
31
|
import { parse } from "jsonc-parser";
|
|
32
32
|
import { spawnSync } from "node:child_process";
|
|
33
|
+
import { parseDocument } from "yaml";
|
|
33
34
|
//#region src/cli/deploy-setup.ts
|
|
34
35
|
async function maybeSetupDeployProject(root) {
|
|
35
36
|
const existing = readProjectConfig(root);
|
|
@@ -228,7 +229,10 @@ const SCAFFOLD_BASE_DEV_DEPENDENCIES = {
|
|
|
228
229
|
vite: "^8.0.10",
|
|
229
230
|
typescript: "^7.0.2"
|
|
230
231
|
};
|
|
231
|
-
const SCAFFOLD_VITE_PLUS_DEV_DEPENDENCIES = {
|
|
232
|
+
const SCAFFOLD_VITE_PLUS_DEV_DEPENDENCIES = {
|
|
233
|
+
vite: "npm:@voidzero-dev/vite-plus-core@^1.2.0",
|
|
234
|
+
"vite-plus": "^1.2.0"
|
|
235
|
+
};
|
|
232
236
|
const SCAFFOLD_TOOLCHAIN_OPTIONS = [{
|
|
233
237
|
value: "vite-plus",
|
|
234
238
|
label: "Vite+",
|
|
@@ -651,6 +655,41 @@ export default function HomePage(props: Props) {
|
|
|
651
655
|
}
|
|
652
656
|
}
|
|
653
657
|
//#endregion
|
|
658
|
+
//#region src/cli/init-vite-plus.ts
|
|
659
|
+
/** Keep every Vite consumer on the core used by the selected Vite+ toolchain. */
|
|
660
|
+
function configureVitePlusScaffold(root, packageManager, pkg) {
|
|
661
|
+
const core = SCAFFOLD_VITE_PLUS_DEV_DEPENDENCIES.vite;
|
|
662
|
+
if (packageManager === "pnpm") editYaml(root, "pnpm-workspace.yaml", (document) => {
|
|
663
|
+
if (document.hasIn(["overrides", "vite"])) document.deleteIn(["overrides", "vite"]);
|
|
664
|
+
document.setIn(["overrides", "vite@*"], core);
|
|
665
|
+
document.setIn([
|
|
666
|
+
"peerDependencyRules",
|
|
667
|
+
"allowedVersions",
|
|
668
|
+
"vite"
|
|
669
|
+
], "*");
|
|
670
|
+
});
|
|
671
|
+
else if (packageManager === "yarn") {
|
|
672
|
+
pkg.resolutions = {
|
|
673
|
+
...pkg.resolutions,
|
|
674
|
+
vite: core
|
|
675
|
+
};
|
|
676
|
+
editYaml(root, ".yarnrc.yml", (document) => {
|
|
677
|
+
document.set("nodeLinker", "node-modules");
|
|
678
|
+
});
|
|
679
|
+
} else pkg.overrides = {
|
|
680
|
+
...pkg.overrides,
|
|
681
|
+
vite: packageManager === "npm" ? "$vite" : core
|
|
682
|
+
};
|
|
683
|
+
}
|
|
684
|
+
function editYaml(root, name, edit) {
|
|
685
|
+
const path = join(root, name);
|
|
686
|
+
const before = existsSync(path) ? readFileSync(path, "utf8") : "";
|
|
687
|
+
const document = parseDocument(before);
|
|
688
|
+
if (document.errors.length) throw new Error(`Could not parse ${name}: ${document.errors[0].message}`);
|
|
689
|
+
edit(document);
|
|
690
|
+
writeFileSync(path, document.toString());
|
|
691
|
+
}
|
|
692
|
+
//#endregion
|
|
654
693
|
//#region src/cli/vite-config-patch.ts
|
|
655
694
|
function unwrap(node) {
|
|
656
695
|
while (node && [
|
|
@@ -764,6 +803,7 @@ const EMPTY_PROJECT_ALLOWED_ENTRIES = /* @__PURE__ */ new Set([
|
|
|
764
803
|
"CLAUDE.md",
|
|
765
804
|
".node-version",
|
|
766
805
|
".npmrc",
|
|
806
|
+
".yarnrc.yml",
|
|
767
807
|
".nvmrc",
|
|
768
808
|
".editorconfig",
|
|
769
809
|
".vscode",
|
|
@@ -1732,7 +1772,7 @@ async function ensureVoidPlatformConnection(root) {
|
|
|
1732
1772
|
let selectedApiUrl = null;
|
|
1733
1773
|
let promptedForPlatform = false;
|
|
1734
1774
|
try {
|
|
1735
|
-
const { getApiUrl, getSiteDomain } = await import("./auth-
|
|
1775
|
+
const { getApiUrl, getSiteDomain } = await import("./auth-Cbqi1iVX.mjs");
|
|
1736
1776
|
selectedApiUrl = getApiUrl(root);
|
|
1737
1777
|
getSiteDomain(root);
|
|
1738
1778
|
} catch (error) {
|
|
@@ -2128,8 +2168,9 @@ function scaffoldPagesApp(root, packageManager, framework, starterMode, toolchai
|
|
|
2128
2168
|
const targetGroup = group === "dependencies" ? dependencies : devDependencies;
|
|
2129
2169
|
const sourceGroup = otherGroup === "dependencies" ? dependencies : devDependencies;
|
|
2130
2170
|
const existing = targetGroup[name] ?? sourceGroup[name];
|
|
2131
|
-
|
|
2132
|
-
|
|
2171
|
+
const selectToolchainVersion = toolchain === "vite-plus" && (name === "vite" || name === "vite-plus");
|
|
2172
|
+
if (!targetGroup[name] || selectToolchainVersion && existing !== fallbackVersion) {
|
|
2173
|
+
targetGroup[name] = selectToolchainVersion ? fallbackVersion : existing ?? fallbackVersion;
|
|
2133
2174
|
dependencyAdded = true;
|
|
2134
2175
|
}
|
|
2135
2176
|
if (sourceGroup[name]) {
|
|
@@ -2140,6 +2181,7 @@ function scaffoldPagesApp(root, packageManager, framework, starterMode, toolchai
|
|
|
2140
2181
|
for (const [name, version] of Object.entries(template.dependencies)) ensureDependency("dependencies", name, version);
|
|
2141
2182
|
for (const [name, version] of Object.entries(template.devDependencies)) ensureDependency("devDependencies", name, version);
|
|
2142
2183
|
if (packageManager === "pnpm" || isPnpmProject(root, pkg)) ensurePnpmAllowBuilds(root, pkg);
|
|
2184
|
+
if (toolchain === "vite-plus") configureVitePlusScaffold(packageManager === "pnpm" ? resolvePnpmConfigRoot(root, pkg) : root, packageManager, pkg);
|
|
2143
2185
|
writeFileSync(packageJsonPath, JSON.stringify(pkg, null, 2) + "\n");
|
|
2144
2186
|
log.step("Updated package.json with starter scripts and dependencies");
|
|
2145
2187
|
for (const [filePath, content] of Object.entries(template.files)) writeFileIfMissing(root, filePath, content);
|
|
@@ -2236,7 +2278,11 @@ function noteManualFrameworkConfigSetup(framework) {
|
|
|
2236
2278
|
return;
|
|
2237
2279
|
}
|
|
2238
2280
|
if (framework.name === "nuxt") {
|
|
2239
|
-
note("Detected Nuxt. Void init does not patch nuxt.config.* automatically.\n\nAdd `voidPlugin()` to the Nuxt Vite plugins option:\n\nimport { voidPlugin } from \"void\";\n\nexport default defineNuxtConfig({\n vite: { plugins: [voidPlugin()] },\n});", "Manual Nuxt config step");
|
|
2281
|
+
note("Detected Nuxt. Void init does not patch nuxt.config.* automatically.\n\nAdd `voidPlugin()` to the Nuxt Vite plugins option, the `@schema` alias that `nuxi typecheck` reads, and the Cloudflare preset, `void/nitro` and the generated Cloudflare config to the Nitro options:\n\nimport { resolve } from \"node:path\";\nimport { voidPlugin } from \"void\";\n\nexport default defineNuxtConfig({\n alias: {\n \"@schema\": resolve(import.meta.dirname, \"db/schema.ts\"),\n },\n nitro: {\n preset: \"cloudflare-module\",\n modules: [\"void/nitro\"],\n cloudflare: { dev: { configPath: \"./.void-wrangler.jsonc\" } },\n },\n vite: { plugins: [voidPlugin()] },\n});", "Manual Nuxt config step");
|
|
2282
|
+
return;
|
|
2283
|
+
}
|
|
2284
|
+
if (framework.name === "analog") {
|
|
2285
|
+
note("Detected Analog. Void init does not patch vite.config.* automatically.\n\nInstall `nitro-cloudflare-dev` as a dev dependency. Add `voidPlugin()` to the Vite plugins, and the Cloudflare preset, `void/nitro` and the generated Cloudflare config to Analog's Nitro options:\n\nimport analog from \"@analogjs/platform\";\nimport { voidPlugin } from \"void\";\n\nexport default defineConfig({\n plugins: [\n analog({\n ssr: true,\n nitro: {\n preset: \"cloudflare-module\",\n modules: [\"nitro-cloudflare-dev\", \"void/nitro\"],\n cloudflareDev: { configPath: \"./.void-wrangler.jsonc\" },\n },\n }),\n voidPlugin(),\n ],\n});", "Manual Analog config step");
|
|
2240
2286
|
return;
|
|
2241
2287
|
}
|
|
2242
2288
|
noteManualViteConfigSetup();
|
|
@@ -2437,7 +2483,7 @@ async function runInitCommand(root, initArgs) {
|
|
|
2437
2483
|
await injectAgentBlock(root, newProject);
|
|
2438
2484
|
const agents = detectAgents(root);
|
|
2439
2485
|
if (agents.length > 0) {
|
|
2440
|
-
const { linkSkillsForSpecificAgents } = await import("./skills-
|
|
2486
|
+
const { linkSkillsForSpecificAgents } = await import("./skills-C_yRTg0g.mjs");
|
|
2441
2487
|
linkSkillsForSpecificAgents(root, agents);
|
|
2442
2488
|
} else log.info("Bundled Void docs: node_modules/void/docs/");
|
|
2443
2489
|
if (!targeted && !framework) {
|
|
@@ -2467,7 +2513,7 @@ async function runInitCommand(root, initArgs) {
|
|
|
2467
2513
|
let shouldSetupGithub = targeted ? initArgs?.github === true : deploymentPlatform !== "none";
|
|
2468
2514
|
if (shouldSetupGithub && !workspaceSubpackage && deploymentPlatform !== "cloudflare" && deploymentPlatform !== "none") {
|
|
2469
2515
|
if (!voidPlatformDiscovery) {
|
|
2470
|
-
const { getApiUrl } = await import("./auth-
|
|
2516
|
+
const { getApiUrl } = await import("./auth-Cbqi1iVX.mjs");
|
|
2471
2517
|
voidPlatformDiscovery = await discoverPlatform(getApiUrl(root));
|
|
2472
2518
|
}
|
|
2473
2519
|
if (!voidPlatformDiscovery.capabilities.githubActions) {
|
|
@@ -47,35 +47,6 @@ function resolveAssetRoutingPolicy(inputs) {
|
|
|
47
47
|
};
|
|
48
48
|
}
|
|
49
49
|
//#endregion
|
|
50
|
-
//#region src/queues/dispatch.ts
|
|
51
|
-
/**
|
|
52
|
-
* Emit the queue-name resolver used by generated native workers and framework
|
|
53
|
-
* wrappers. Hosted relays send the exact logical name. Native Queue events may
|
|
54
|
-
* expose a project-prefixed physical name, so fallback matching selects the
|
|
55
|
-
* unique longest known `-name` suffix. Unknown or ambiguous inputs fail closed.
|
|
56
|
-
*/
|
|
57
|
-
function generateQueueResolverSource(queueNames) {
|
|
58
|
-
return `const __queueNames = ${JSON.stringify(queueNames)};
|
|
59
|
-
function __resolveQueueIndex(queueName) {
|
|
60
|
-
if (typeof queueName !== "string") return -1;
|
|
61
|
-
const exact = __queueNames.indexOf(queueName);
|
|
62
|
-
if (exact !== -1) return exact;
|
|
63
|
-
let match = -1;
|
|
64
|
-
let matchLength = -1;
|
|
65
|
-
for (let i = 0; i < __queueNames.length; i++) {
|
|
66
|
-
const name = __queueNames[i];
|
|
67
|
-
if (!queueName.endsWith("-" + name)) continue;
|
|
68
|
-
if (name.length > matchLength) {
|
|
69
|
-
match = i;
|
|
70
|
-
matchLength = name.length;
|
|
71
|
-
} else if (name.length === matchLength) {
|
|
72
|
-
match = -1;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
return match;
|
|
76
|
-
}`;
|
|
77
|
-
}
|
|
78
|
-
//#endregion
|
|
79
50
|
//#region src/cli/build-output-dir.ts
|
|
80
51
|
/**
|
|
81
52
|
* Resolve the top-level build output directory: the first segment of a
|
|
@@ -191,4 +162,4 @@ function collectPages(pageScan, revalidateConfig, isrEnabled = true) {
|
|
|
191
162
|
});
|
|
192
163
|
}
|
|
193
164
|
//#endregion
|
|
194
|
-
export { resolveDistDir as a,
|
|
165
|
+
export { resolveDistDir as a, hasDocumentRoutes as c, collectFiles as i, resolveAssetConfig as l, collectRevalidate as n, resolveWorkerDirName as o, hasRevalidate as r, hasApiRoutes as s, collectPages as t, resolveAssetRoutingPolicy as u };
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { r as readProjectConfig, t as attachSelectedPlatform, u as writeProjectConfig } from "./project-rqDnVsJN.mjs";
|
|
2
2
|
import { c as getToken, s as getSiteDomain } from "./auth-B6iOCjKI.mjs";
|
|
3
|
-
import { H as outro, L as log, O as cancel } from "./dist-
|
|
4
|
-
import { f as import_picocolors, m as printSuccess } from "./output-
|
|
3
|
+
import { H as outro, L as log, O as cancel } from "./dist-BVdsO7Py.mjs";
|
|
4
|
+
import { f as import_picocolors, m as printSuccess } from "./output-Ba6ZbrzY.mjs";
|
|
5
5
|
import { r as PlatformClient } from "./client-DM9Kcf4e.mjs";
|
|
6
|
-
import { a as promptProjectSelection, r as promptAndCreateProject } from "./create-project-
|
|
7
|
-
import { a as resolveProjectBySlug } from "./resolve-project-
|
|
6
|
+
import { a as promptProjectSelection, r as promptAndCreateProject } from "./create-project-yInGo72M.mjs";
|
|
7
|
+
import { a as resolveProjectBySlug } from "./resolve-project-WpwkCB_c.mjs";
|
|
8
8
|
//#region src/cli/link.ts
|
|
9
9
|
function projectLabel(slug, root, url) {
|
|
10
10
|
if (url) return url;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { n as readDeploymentPlatform, r as readProjectConfig } from "./project-rqDnVsJN.mjs";
|
|
2
2
|
import { c as getToken } from "./auth-B6iOCjKI.mjs";
|
|
3
|
-
import { H as outro, L as log } from "./dist-
|
|
4
|
-
import { _ as tablePrefix, c as formatRelativeTime, f as import_picocolors, h as sanitizeTerminalText, i as dim, o as formatCount } from "./output-
|
|
3
|
+
import { H as outro, L as log } from "./dist-BVdsO7Py.mjs";
|
|
4
|
+
import { _ as tablePrefix, c as formatRelativeTime, f as import_picocolors, h as sanitizeTerminalText, i as dim, o as formatCount } from "./output-Ba6ZbrzY.mjs";
|
|
5
5
|
import { r as PlatformClient } from "./client-DM9Kcf4e.mjs";
|
|
6
|
-
import { a as resolveProjectBySlug } from "./resolve-project-
|
|
6
|
+
import { a as resolveProjectBySlug } from "./resolve-project-WpwkCB_c.mjs";
|
|
7
7
|
//#region src/cli/list.ts
|
|
8
8
|
async function runListCommand(root, slug) {
|
|
9
9
|
console.log();
|
|
@@ -42,7 +42,7 @@ async function runListCommand(root, slug) {
|
|
|
42
42
|
}
|
|
43
43
|
async function showCloudflareDeployments(root, slug) {
|
|
44
44
|
if (slug) throw new Error("project: A project name selects a Void platform project and is not used for direct Cloudflare apps.");
|
|
45
|
-
const { readCloudflareWorkerStatus, resolveCloudflareOperationContext } = await import("./cloudflare-operations-
|
|
45
|
+
const { readCloudflareWorkerStatus, resolveCloudflareOperationContext } = await import("./cloudflare-operations-CrSUFRzJ.mjs");
|
|
46
46
|
const status = await readCloudflareWorkerStatus(resolveCloudflareOperationContext(root));
|
|
47
47
|
if (status.versions.length === 0) {
|
|
48
48
|
outro(`No deployments for ${status.workerName}.`);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as bytesToBase64 } from "./base64-DVrOndmI.mjs";
|
|
2
|
-
import { a as getRawRuntimeEnv } from "./env-raw-
|
|
2
|
+
import { a as getRawRuntimeEnv } from "./env-raw-D74P4ebM.mjs";
|
|
3
3
|
import { i as getUser } from "./auth-3sGB0zJ1.mjs";
|
|
4
4
|
//#region src/runtime/live-names.ts
|
|
5
5
|
async function topicDigest(streamId, topic) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { a as join, c as resolve, i as isAbsolute } from "./dist-ipQi0Q8y.mjs";
|
|
2
2
|
import { b as readRootWranglerConfig } from "./wrangler-BYs07Rxy.mjs";
|
|
3
|
-
import { r as getMiniflareDatabasePath } from "./runner-
|
|
3
|
+
import { r as getMiniflareDatabasePath } from "./runner-CabsQ-iM.mjs";
|
|
4
4
|
import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
5
5
|
import { createHash } from "node:crypto";
|
|
6
6
|
//#region src/local-d1.ts
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { a as getApiUrl, c as getToken, f as removeToken, l as getTokenSource, m as savePlatformToken, p as runPlatformLogin } from "./auth-B6iOCjKI.mjs";
|
|
2
|
-
import { H as outro, K as select, L as log, O as cancel, tt as isCancel } from "./dist-
|
|
3
|
-
import { f as import_picocolors, l as formatUrl, m as printSuccess, r as createSpinner } from "./output-
|
|
2
|
+
import { H as outro, K as select, L as log, O as cancel, tt as isCancel } from "./dist-BVdsO7Py.mjs";
|
|
3
|
+
import { f as import_picocolors, l as formatUrl, m as printSuccess, r as createSpinner } from "./output-Ba6ZbrzY.mjs";
|
|
4
4
|
import { a as isExpiredTokenError, r as PlatformClient } from "./client-DM9Kcf4e.mjs";
|
|
5
5
|
//#region src/cli/login.ts
|
|
6
6
|
async function selectPlatformLoginMethod(platform, requestedId) {
|
|
@@ -30,7 +30,7 @@ async function selectPlatformLoginMethod(platform, requestedId) {
|
|
|
30
30
|
}
|
|
31
31
|
async function promptForLoginToken(root = process.cwd(), platform) {
|
|
32
32
|
const apiUrl = platform?.apiUrl ?? getApiUrl(root);
|
|
33
|
-
const { id: provider, label: providerName } = await selectPlatformLoginMethod(platform ?? await (await import("./platform-cmd-
|
|
33
|
+
const { id: provider, label: providerName } = await selectPlatformLoginMethod(platform ?? await (await import("./platform-cmd-PT4YwMLM.mjs")).discoverPlatform(apiUrl));
|
|
34
34
|
const s = createSpinner();
|
|
35
35
|
s.start(`Opening browser for ${providerName} login...`);
|
|
36
36
|
try {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { r as selectPlatformLoginMethod } from "./login-C2T1oVG-.mjs";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { n as readDeploymentPlatform, r as readProjectConfig } from "./project-rqDnVsJN.mjs";
|
|
2
2
|
import { c as getToken } from "./auth-B6iOCjKI.mjs";
|
|
3
|
-
import { $ as wrapTextWithPrefix, H as outro, L as log } from "./dist-
|
|
4
|
-
import { a as errorStackFrames, f as import_picocolors, i as dim, o as formatCount } from "./output-
|
|
3
|
+
import { $ as wrapTextWithPrefix, H as outro, L as log } from "./dist-BVdsO7Py.mjs";
|
|
4
|
+
import { a as errorStackFrames, f as import_picocolors, i as dim, o as formatCount } from "./output-Ba6ZbrzY.mjs";
|
|
5
5
|
import { r as PlatformClient } from "./client-DM9Kcf4e.mjs";
|
|
6
6
|
import { t as sanitizeTerminalLogText } from "./terminal-log-text-D9ACPOuG.mjs";
|
|
7
7
|
//#region src/cli/logs.ts
|
|
@@ -9,7 +9,7 @@ async function runLogsCommand(root, filter, range, deployment, level) {
|
|
|
9
9
|
console.log();
|
|
10
10
|
const platform = readDeploymentPlatform(root);
|
|
11
11
|
if (platform === "cloudflare") {
|
|
12
|
-
const { resolveCloudflareOperationContext, tailCloudflareWorker } = await import("./cloudflare-operations-
|
|
12
|
+
const { resolveCloudflareOperationContext, tailCloudflareWorker } = await import("./cloudflare-operations-CrSUFRzJ.mjs");
|
|
13
13
|
if (range !== "1h") log.warn("Cloudflare tail streams live logs; --range does not select historical entries.");
|
|
14
14
|
if (level && level !== "all" && level !== "error") log.warn("Cloudflare tail cannot filter individual console levels; showing all invocation logs.");
|
|
15
15
|
await tailCloudflareWorker(resolveCloudflareOperationContext(root), {
|
|
@@ -4,8 +4,8 @@ import { p as validateConfig } from "./config-Bx_1SpnO.mjs";
|
|
|
4
4
|
import { t as parseJsoncObject } from "./generated-wrangler-config-DeWj5F9Y.mjs";
|
|
5
5
|
import { n as VOID_LOCK_FILE, o as seedCloudflareConfig, s as stashCloudflareDeployPointer } from "./cloudflare-config-DV60XFFK.mjs";
|
|
6
6
|
import "./wrangler-BYs07Rxy.mjs";
|
|
7
|
-
import { L as log } from "./dist-
|
|
8
|
-
import { m as printSuccess } from "./output-
|
|
7
|
+
import { L as log } from "./dist-BVdsO7Py.mjs";
|
|
8
|
+
import { m as printSuccess } from "./output-Ba6ZbrzY.mjs";
|
|
9
9
|
import { existsSync, mkdirSync, readFileSync, renameSync, rmSync, unlinkSync, writeFileSync } from "node:fs";
|
|
10
10
|
import { parseSync } from "vite";
|
|
11
11
|
import { randomUUID } from "node:crypto";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { n as runMigrateCommand } from "./migrate-BDIprOYd.mjs";
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
import { n as splitMigrationSql } from "./migration-handler-Cg0Y4EPu.mjs";
|
|
2
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
3
|
+
//#region src/runtime/migration-lock-mysql.ts
|
|
4
|
+
/**
|
|
5
|
+
* Migration runs on one MySQL database exclude each other with two kinds of lock, and each run
|
|
6
|
+
* checks for the other kind after it takes its own:
|
|
7
|
+
*
|
|
8
|
+
* - The CLI runner holds a named lock (GET_LOCK) for its session, so it ends with the connection.
|
|
9
|
+
* - The hosted handler reaches MySQL through Hyperdrive, which pools connections per transaction,
|
|
10
|
+
* so a session lock could stay on a pooled connection or be reset away. It writes a lease row
|
|
11
|
+
* with an expiry instead, using one statement at a time. Lease times are UTC: NOW() follows
|
|
12
|
+
* each session's time zone and its DST changes, and DATETIME stores no zone.
|
|
13
|
+
*/
|
|
14
|
+
/** Hyperdrive ends a statement after 60 seconds, and the hosted handler renews before each one. */
|
|
15
|
+
const LEASE_SECONDS = 120;
|
|
16
|
+
/** A deploy waits long enough for the lease of a run that stopped early to expire. */
|
|
17
|
+
const DEPLOY_WAIT_MS = 13e4;
|
|
18
|
+
const POLL_MS = 1e3;
|
|
19
|
+
/** How often the lease is renewed while statements that cannot renew it themselves run. */
|
|
20
|
+
const KEEP_ALIVE_MS = 3e4;
|
|
21
|
+
/**
|
|
22
|
+
* The CLI runner's named lock. Lock names are server-wide and at most 64 characters, so the name
|
|
23
|
+
* carries a hash of the database name. Vitess reports a connection's target (`app@primary`,
|
|
24
|
+
* `app:-80@replica`) in DATABASE(), and the lock belongs to the keyspace.
|
|
25
|
+
*/
|
|
26
|
+
function mySqlMigrationLockName(database) {
|
|
27
|
+
return `void_migrations:${createHash("sha1").update(database.split(/[:@]/)[0]).digest("hex")}`;
|
|
28
|
+
}
|
|
29
|
+
function mySqlMigrationLockError(database, retry) {
|
|
30
|
+
return /* @__PURE__ */ new Error(`Another migration run is applying migrations to MySQL database "${database}". Wait for it to finish, then ${retry}.`);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Seconds left on a deploy's lease, or undefined when no deploy holds one. The CLI runner calls
|
|
34
|
+
* this while it holds the named lock.
|
|
35
|
+
*/
|
|
36
|
+
async function readMySqlMigrationLease(query) {
|
|
37
|
+
try {
|
|
38
|
+
const [row] = rowsOf(await query("SELECT TIMESTAMPDIFF(SECOND, UTC_TIMESTAMP(6), `expires_at`) AS remaining FROM `_void_migration_lock` WHERE `name` = 'app' AND `expires_at` > UTC_TIMESTAMP(6)"));
|
|
39
|
+
return row ? Number(row.remaining) : void 0;
|
|
40
|
+
} catch (error) {
|
|
41
|
+
if (isMissingTable(error)) return;
|
|
42
|
+
throw error;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Takes the lease for a hosted run. It waits while another deploy holds the lease or a CLI run
|
|
47
|
+
* holds the named lock, and throws when that takes too long.
|
|
48
|
+
*/
|
|
49
|
+
async function acquireMySqlMigrationLease(query) {
|
|
50
|
+
const [row] = rowsOf(await query("SELECT DATABASE() AS db"));
|
|
51
|
+
const database = String(row?.db ?? "");
|
|
52
|
+
const lockName = mySqlMigrationLockName(database);
|
|
53
|
+
const owner = randomUUID();
|
|
54
|
+
await query("CREATE TABLE IF NOT EXISTS `_void_migration_lock` (`name` VARCHAR(64) NOT NULL PRIMARY KEY, `owner` VARCHAR(64) NOT NULL, `expires_at` DATETIME(6) NOT NULL)");
|
|
55
|
+
const lease = {
|
|
56
|
+
async renew() {
|
|
57
|
+
if (affectedRows(await query("UPDATE `_void_migration_lock` SET `expires_at` = UTC_TIMESTAMP(6) + INTERVAL ? SECOND WHERE `name` = 'app' AND `owner` = ? AND `expires_at` > UTC_TIMESTAMP(6)", [LEASE_SECONDS, owner])) !== 1) throw new Error(`The migration lock on MySQL database "${database}" expired before this run finished. Deploy again.`);
|
|
58
|
+
},
|
|
59
|
+
async release() {
|
|
60
|
+
await query("UPDATE `_void_migration_lock` SET `expires_at` = UTC_TIMESTAMP(6) - INTERVAL 1 SECOND WHERE `name` = 'app' AND `owner` = ?", [owner]);
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
const deadline = Date.now() + DEPLOY_WAIT_MS;
|
|
64
|
+
for (;;) {
|
|
65
|
+
if (await take(query, owner)) {
|
|
66
|
+
const [lock] = rowsOf(await query("SELECT IS_USED_LOCK(?)", [lockName]));
|
|
67
|
+
if (Object.values(lock ?? {})[0] == null) return lease;
|
|
68
|
+
await lease.release();
|
|
69
|
+
}
|
|
70
|
+
if (Date.now() >= deadline) throw mySqlMigrationLockError(database, "deploy again");
|
|
71
|
+
await new Promise((resolve) => setTimeout(resolve, POLL_MS));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Runs `work`, whose statements cannot renew the lease before each one (Better Auth's migrations),
|
|
76
|
+
* and renews the lease in the background meanwhile. Throws after `work` when a renewal failed,
|
|
77
|
+
* because another run may have taken the lease.
|
|
78
|
+
*/
|
|
79
|
+
async function holdMySqlMigrationLease(lease, work) {
|
|
80
|
+
await lease.renew();
|
|
81
|
+
let failure;
|
|
82
|
+
let renewal = Promise.resolve();
|
|
83
|
+
const timer = setInterval(() => {
|
|
84
|
+
renewal = renewal.then(() => lease.renew()).catch((error) => {
|
|
85
|
+
failure ??= { error };
|
|
86
|
+
});
|
|
87
|
+
}, KEEP_ALIVE_MS);
|
|
88
|
+
let result;
|
|
89
|
+
try {
|
|
90
|
+
result = await work();
|
|
91
|
+
} finally {
|
|
92
|
+
clearInterval(timer);
|
|
93
|
+
await renewal;
|
|
94
|
+
}
|
|
95
|
+
if (failure) throw failure.error;
|
|
96
|
+
return result;
|
|
97
|
+
}
|
|
98
|
+
async function take(query, owner) {
|
|
99
|
+
try {
|
|
100
|
+
return await tryTake(query, owner);
|
|
101
|
+
} catch (error) {
|
|
102
|
+
if (errnoOf(error) === 1213) return false;
|
|
103
|
+
throw error;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
async function tryTake(query, owner) {
|
|
107
|
+
if (affectedRows(await query("INSERT IGNORE INTO `_void_migration_lock` (`name`, `owner`, `expires_at`) VALUES ('app', ?, UTC_TIMESTAMP(6) + INTERVAL ? SECOND)", [owner, LEASE_SECONDS])) === 1) return true;
|
|
108
|
+
return affectedRows(await query("UPDATE `_void_migration_lock` SET `owner` = ?, `expires_at` = UTC_TIMESTAMP(6) + INTERVAL ? SECOND WHERE `name` = 'app' AND `expires_at` < UTC_TIMESTAMP(6)", [owner, LEASE_SECONDS])) === 1;
|
|
109
|
+
}
|
|
110
|
+
function rowsOf(result) {
|
|
111
|
+
return Array.isArray(result) ? result : [];
|
|
112
|
+
}
|
|
113
|
+
function affectedRows(result) {
|
|
114
|
+
return Number(result?.affectedRows ?? 0);
|
|
115
|
+
}
|
|
116
|
+
function isMissingTable(error) {
|
|
117
|
+
const value = typeof error === "object" && error !== null ? error : void 0;
|
|
118
|
+
return value?.code === "ER_NO_SUCH_TABLE" || value?.errno === 1146;
|
|
119
|
+
}
|
|
120
|
+
function errnoOf(error) {
|
|
121
|
+
return typeof error === "object" && error !== null ? error.errno : void 0;
|
|
122
|
+
}
|
|
123
|
+
//#endregion
|
|
124
|
+
//#region src/runtime/mysql-migration-sql.ts
|
|
125
|
+
/**
|
|
126
|
+
* Splits a MySQL migration file into the statements Void runs one query at a time. Hyperdrive
|
|
127
|
+
* does not accept several statements in one query, and a file that runs statement by statement
|
|
128
|
+
* can tell whether a failure left earlier statements committed.
|
|
129
|
+
*
|
|
130
|
+
* The file first splits at drizzle-kit `--> statement-breakpoint` lines. Each part then splits at
|
|
131
|
+
* semicolons outside strings, quoted names and comments, and drops comments after its last
|
|
132
|
+
* statement. A statement that defines a trigger, routine or event keeps the rest of its part with
|
|
133
|
+
* it: the semicolons in its BEGIN ... END body cannot be told apart from the ones between
|
|
134
|
+
* statements without a parser.
|
|
135
|
+
*/
|
|
136
|
+
function splitMySqlMigrationSql(sql) {
|
|
137
|
+
return splitMySqlMigrationStatements(sql).map((statement) => statement.sql);
|
|
138
|
+
}
|
|
139
|
+
/** {@link splitMySqlMigrationSql}, with each statement marked. */
|
|
140
|
+
function splitMySqlMigrationStatements(sql) {
|
|
141
|
+
return splitMigrationSql(sql).flatMap((part) => {
|
|
142
|
+
const statements = splitMySqlStatements(part);
|
|
143
|
+
return statements.length > 0 ? statements : [{
|
|
144
|
+
sql: part,
|
|
145
|
+
program: false
|
|
146
|
+
}];
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* The start of a statement whose body can hold semicolons: a stored program, after options such
|
|
151
|
+
* as DEFINER, or a compound statement that MariaDB also runs outside one. It is matched against
|
|
152
|
+
* the statement with quoted text and comments blanked out, so a column named `event` or a plain
|
|
153
|
+
* `BEGIN` transaction does not match.
|
|
154
|
+
*/
|
|
155
|
+
const COMPOUND_START = new RegExp([
|
|
156
|
+
`^\\s*(?:CREATE|ALTER)\\s+(?:(?!(?:TABLE|INDEX|VIEW|DATABASE|SCHEMA|USER|ROLE|TABLESPACE|SERVER|UNIQUE|FULLTEXT|SPATIAL|TEMPORARY)\\b)\\S+\\s+){0,8}?(?:TRIGGER|PROCEDURE|FUNCTION|EVENT|PACKAGE)\\b`,
|
|
157
|
+
"^\\s*BEGIN\\s+NOT\\s+ATOMIC\\b",
|
|
158
|
+
"^\\s*(?:\\w+\\s*:\\s*)?(?:BEGIN|IF|CASE|LOOP|REPEAT|WHILE)\\b(?!\\s*(?:WORK\\s*)?$)"
|
|
159
|
+
].join("|"), "i");
|
|
160
|
+
/** The statements in `sql`, without the comments around them. */
|
|
161
|
+
function splitMySqlStatements(sql) {
|
|
162
|
+
const statements = [];
|
|
163
|
+
let bare = "";
|
|
164
|
+
let start = -1;
|
|
165
|
+
let end = -1;
|
|
166
|
+
let compound = false;
|
|
167
|
+
let index = 0;
|
|
168
|
+
const take = (from, to) => {
|
|
169
|
+
if (start === -1) start = from;
|
|
170
|
+
end = to;
|
|
171
|
+
};
|
|
172
|
+
while (index < sql.length) {
|
|
173
|
+
const character = sql[index];
|
|
174
|
+
const next = sql[index + 1];
|
|
175
|
+
if (character === "'" || character === "\"" || character === "`") {
|
|
176
|
+
const close = skipQuoted(sql, index, character);
|
|
177
|
+
take(index, close);
|
|
178
|
+
bare += " ";
|
|
179
|
+
index = close;
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
if (character === "#" || character === "-" && next === "-" && !/\S/.test(sql[index + 2] ?? " ")) {
|
|
183
|
+
const newline = sql.indexOf("\n", index);
|
|
184
|
+
index = newline === -1 ? sql.length : newline;
|
|
185
|
+
bare += " ";
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
if (character === "/" && next === "*") {
|
|
189
|
+
const close = sql.indexOf("*/", index + 2);
|
|
190
|
+
const commentEnd = close === -1 ? sql.length : close + 2;
|
|
191
|
+
if (sql[index + 2] === "!" || sql[index + 2] === "+") take(index, commentEnd);
|
|
192
|
+
bare += " ";
|
|
193
|
+
index = commentEnd;
|
|
194
|
+
continue;
|
|
195
|
+
}
|
|
196
|
+
if (character === ";" && !compound) {
|
|
197
|
+
if (start !== -1 && COMPOUND_START.test(bare)) compound = true;
|
|
198
|
+
else {
|
|
199
|
+
if (start !== -1) statements.push({
|
|
200
|
+
sql: sql.slice(start, index + 1),
|
|
201
|
+
program: false
|
|
202
|
+
});
|
|
203
|
+
start = -1;
|
|
204
|
+
end = -1;
|
|
205
|
+
bare = "";
|
|
206
|
+
index++;
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
bare += character;
|
|
211
|
+
if (!/\s/.test(character)) take(index, index + 1);
|
|
212
|
+
index++;
|
|
213
|
+
}
|
|
214
|
+
if (start !== -1) statements.push({
|
|
215
|
+
sql: sql.slice(start, end),
|
|
216
|
+
program: compound
|
|
217
|
+
});
|
|
218
|
+
return statements;
|
|
219
|
+
}
|
|
220
|
+
/** The index after the quoted string or name that opens at `open`. */
|
|
221
|
+
function skipQuoted(sql, open, quote) {
|
|
222
|
+
let index = open + 1;
|
|
223
|
+
while (index < sql.length) {
|
|
224
|
+
const character = sql[index];
|
|
225
|
+
if (character === "\\" && quote !== "`") {
|
|
226
|
+
index += 2;
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
if (character === quote) {
|
|
230
|
+
if (sql[index + 1] === quote) {
|
|
231
|
+
index += 2;
|
|
232
|
+
continue;
|
|
233
|
+
}
|
|
234
|
+
return index + 1;
|
|
235
|
+
}
|
|
236
|
+
index++;
|
|
237
|
+
}
|
|
238
|
+
return sql.length;
|
|
239
|
+
}
|
|
240
|
+
//#endregion
|
|
241
|
+
export { mySqlMigrationLockError as a, holdMySqlMigrationLease as i, splitMySqlMigrationStatements as n, mySqlMigrationLockName as o, acquireMySqlMigrationLease as r, readMySqlMigrationLease as s, splitMySqlMigrationSql as t };
|
package/dist/nitro.d.mts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
//#region src/nitro.d.ts
|
|
2
|
+
/** The parts of a Nitro instance that the module uses. */
|
|
3
|
+
type NitroInstance = {
|
|
4
|
+
options: {
|
|
5
|
+
dev: boolean;
|
|
6
|
+
rootDir: string;
|
|
7
|
+
buildDir: string;
|
|
8
|
+
exportConditions?: Array<string>;
|
|
9
|
+
plugins: Array<string>;
|
|
10
|
+
virtual: Record<string, string | (() => string | Promise<string>)>;
|
|
11
|
+
rollupConfig?: {
|
|
12
|
+
plugins?: unknown;
|
|
13
|
+
};
|
|
14
|
+
cloudflare?: {
|
|
15
|
+
nodeCompat?: boolean;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Nitro module for apps whose server routes Nitro bundles (Nuxt and Analog). Nitro's bundler
|
|
21
|
+
* does not run Vite plugins, so without this module `void/db` in a server route, page server
|
|
22
|
+
* load or cron job is the package's D1 client without the app's schema. Register it in the
|
|
23
|
+
* Nitro config: `modules: ['void/nitro']`.
|
|
24
|
+
*/
|
|
25
|
+
declare const voidNitroModule: {
|
|
26
|
+
name: string;
|
|
27
|
+
setup(nitro: NitroInstance): void;
|
|
28
|
+
};
|
|
29
|
+
//#endregion
|
|
30
|
+
export { voidNitroModule as default };
|