void 0.10.11 → 0.10.13

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.
Files changed (36) hide show
  1. package/dist/cli/cli.mjs +14 -14
  2. package/dist/cli/env-schema-probe.mjs +2 -2
  3. package/dist/{config-E03l1C_h.mjs → config-qHGgPuWT.mjs} +23 -0
  4. package/dist/{db-PZBsLSGb.mjs → db-C0i0sYMS.mjs} +3 -3
  5. package/dist/{deploy-DT8wsPZd.mjs → deploy-jBJT1fUT.mjs} +408 -66
  6. package/dist/{env-AAHU02L6.mjs → env-CZy5MorI.mjs} +1 -1
  7. package/dist/{env-validation-BdDlGhbN.mjs → env-validation-Dea3v3ej.mjs} +1 -1
  8. package/dist/{gen-oup1xBN0.mjs → gen-BzXf3Jh2.mjs} +1 -1
  9. package/dist/{git-metadata-CBKaL0v5.mjs → git-metadata-D-gurjzG.mjs} +6 -5
  10. package/dist/{github-cmd-BdNaOVNa.mjs → github-cmd-DKcGUNsj.mjs} +1 -1
  11. package/dist/{headers-BQknpzkn.mjs → headers-ChAADPQu.mjs} +1 -1
  12. package/dist/index.mjs +91 -43
  13. package/dist/{init-Dl2PKuQn.mjs → init-7JCAcKNQ.mjs} +2 -2
  14. package/dist/{node-BDx8pmhq.mjs → node-pRg81HqV.mjs} +3 -3
  15. package/dist/pages/index.mjs +3 -3
  16. package/dist/pages/islands-plugin.mjs +1 -1
  17. package/dist/{prepare-DOBTY0o4.mjs → prepare-BvvgAz-3.mjs} +3 -3
  18. package/dist/{preset-BGrvB4Bl.mjs → preset-BjyR3lzz.mjs} +55 -2
  19. package/dist/{provision-BLrCEBbI.mjs → provision-CPx2ZxsH.mjs} +2 -2
  20. package/dist/{route-types-COI2DsZv.mjs → route-types-z1jtHEi_.mjs} +8 -1
  21. package/dist/{scan-DYXkrasO.mjs → scan-ChWt4pX1.mjs} +12 -13
  22. package/dist/{scan-DEwlM_Xy.mjs → scan-NU4xKGci.mjs} +4 -1
  23. package/package.json +2 -2
  24. package/schema.json +18 -0
  25. package/skills/migrate-vite-cloudflare-to-void/SKILL.md +1 -1
  26. package/skills/void/docs/guide/app-types.md +43 -0
  27. package/skills/void/docs/guide/deployment.md +68 -1
  28. package/skills/void/docs/guide/edge/static-assets.md +37 -1
  29. package/skills/void/docs/guide/server-routing.md +21 -1
  30. package/skills/void/docs/guide/websockets.md +3 -0
  31. package/skills/void/docs/integrations/frameworks/overview.md +1 -0
  32. package/skills/void/docs/node_modules/void/CLAUDE.md +3 -1
  33. package/skills/void/docs/node_modules/void/skills/migrate-vite-cloudflare-to-void/SKILL.md +1 -1
  34. package/skills/void/docs/reference/cli.md +24 -0
  35. package/skills/void/docs/reference/config.md +42 -1
  36. package/skills/void/docs/reference/structure.md +1 -0
@@ -2,7 +2,7 @@ import { a as join } from "./dist-DaKKDf8D.mjs";
2
2
  import { D as outro, E as note, T as log, a as cliTitle, w as intro } from "./agents-CtgBYqld.mjs";
3
3
  import { b as readProjectConfig, f as getToken, n as PlatformClient } from "./client-Gb71-XkG.mjs";
4
4
  import { r as generateEnvTypes, t as findEnvFile } from "./env-types-QBj-ndax.mjs";
5
- import { h as loadUserEnvFile, l as fetchRemoteSecretNames, m as validateProdEnv, u as formatEnvReport } from "./env-validation-BdDlGhbN.mjs";
5
+ import { h as loadUserEnvFile, l as fetchRemoteSecretNames, m as validateProdEnv, u as formatEnvReport } from "./env-validation-Dea3v3ej.mjs";
6
6
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
7
7
  //#region src/cli/env-example.ts
8
8
  /**
@@ -1,7 +1,7 @@
1
1
  import { n as __exportAll } from "./rolldown-runtime-DJK8HYOj.mjs";
2
2
  import { a as join, c as resolve, n as dirname } from "./dist-DaKKDf8D.mjs";
3
3
  import { i as voidWarn } from "./log-ChfPKsVd.mjs";
4
- import { c as mergeAndExpand, l as parseDotenvFile, o as resolveWranglerArgv } from "./preset-BGrvB4Bl.mjs";
4
+ import { c as mergeAndExpand, l as parseDotenvFile, o as resolveWranglerArgv } from "./preset-BjyR3lzz.mjs";
5
5
  import { t as findEnvFile } from "./env-types-QBj-ndax.mjs";
6
6
  import { getSecretOverride } from "./runtime/env-helpers.mjs";
7
7
  import { t as isLikelySecretKey } from "./env-mask-Dd47NbR6.mjs";
@@ -2,7 +2,7 @@ import { a as join, n as dirname, s as relative } from "./dist-DaKKDf8D.mjs";
2
2
  import { D as outro, T as log, a as cliTitle, j as isCancel, k as select, w as intro, x as cancel } from "./agents-CtgBYqld.mjs";
3
3
  import { n as readProjectPaths } from "./project-paths-BQd7OmIo.mjs";
4
4
  import { n as ensureProjectTsconfig } from "./project-tsconfig-B-QtXjLQ.mjs";
5
- import { c as getDatabaseDialect, f as readConfig } from "./config-E03l1C_h.mjs";
5
+ import { c as getDatabaseDialect, f as readConfig } from "./config-qHGgPuWT.mjs";
6
6
  import { n as writeDrizzleConfig } from "./config-CutEMNGJ.mjs";
7
7
  import { c as collectMigrations, n as listDrizzleArtifacts, t as assertJournalCoherence, u as readJournal } from "./validate-Cw_RLeTj.mjs";
8
8
  import { t as buildDrizzleKitSpawnEnv } from "./yarn-pnp-DJn3SAHF.mjs";
@@ -1,6 +1,6 @@
1
1
  import { execFileSync } from "node:child_process";
2
2
  //#region src/cli/git-metadata.ts
3
- function git(root, args) {
3
+ function git(root, args, env) {
4
4
  try {
5
5
  return execFileSync("git", args, {
6
6
  cwd: root,
@@ -9,7 +9,8 @@ function git(root, args) {
9
9
  "ignore",
10
10
  "pipe",
11
11
  "ignore"
12
- ]
12
+ ],
13
+ env
13
14
  }).trim();
14
15
  } catch {
15
16
  return null;
@@ -60,17 +61,17 @@ function getGitHubRepositoryUrl(env) {
60
61
  if (!env.GITHUB_REPOSITORY) return null;
61
62
  return normalizeGitRemoteUrl(`${env.GITHUB_SERVER_URL ?? "https://github.com"}/${env.GITHUB_REPOSITORY}`);
62
63
  }
63
- function collectGitDeployMetadata(root, commit, env = process.env) {
64
+ function collectGitDeployMetadata(root, commit, env = process.env, childEnv = process.env) {
64
65
  const repositoryUrl = getGitHubRepositoryUrl(env) ?? normalizeGitRemoteUrl(git(root, [
65
66
  "remote",
66
67
  "get-url",
67
68
  "origin"
68
- ]));
69
+ ], childEnv));
69
70
  const gitRef = getGitRefFromEnv(env) ?? git(root, [
70
71
  "rev-parse",
71
72
  "--abbrev-ref",
72
73
  "HEAD"
73
- ]);
74
+ ], childEnv);
74
75
  return {
75
76
  commit,
76
77
  commitUrl: buildCommitUrl(repositoryUrl, commit),
@@ -1,7 +1,7 @@
1
1
  import { A as text, S as confirm, T as log, j as isCancel, k as select, u as import_picocolors, x as cancel } from "./agents-CtgBYqld.mjs";
2
2
  import { b as readProjectConfig, c as createCodeChallenge, f as getToken, h as openBrowser, l as createCodeVerifier, n as PlatformClient, o as parsePlatformErrorBody, s as awaitBrowserCallback, t as PlatformApiError } from "./client-Gb71-XkG.mjs";
3
3
  import { r as resolveProjectBySlug, t as getRequestedProjectSlug } from "./resolve-project-BBMtLLV9.mjs";
4
- import { t as collectGitDeployMetadata } from "./git-metadata-CBKaL0v5.mjs";
4
+ import { t as collectGitDeployMetadata } from "./git-metadata-D-gurjzG.mjs";
5
5
  import { randomBytes } from "node:crypto";
6
6
  //#region src/cli/github-cmd.ts
7
7
  /**
@@ -1,5 +1,5 @@
1
1
  import { a as join } from "./dist-DaKKDf8D.mjs";
2
- import { a as convertRedirectsConfig, d as parseHostPrefixedSource, i as convertHeadersConfig, o as convertRewritesConfig, r as convertFallbacksConfig, s as countSplats, t as VALID_REDIRECT_STATUSES, u as isProtocolRelative } from "./config-E03l1C_h.mjs";
2
+ import { a as convertRedirectsConfig, d as parseHostPrefixedSource, i as convertHeadersConfig, o as convertRewritesConfig, r as convertFallbacksConfig, s as countSplats, t as VALID_REDIRECT_STATUSES, u as isProtocolRelative } from "./config-qHGgPuWT.mjs";
3
3
  import { i as voidWarn } from "./log-ChfPKsVd.mjs";
4
4
  import { existsSync, readFileSync } from "node:fs";
5
5
  //#region src/cli/headers.ts
package/dist/index.mjs CHANGED
@@ -1,24 +1,24 @@
1
1
  import { r as __toESM } from "./rolldown-runtime-DJK8HYOj.mjs";
2
2
  import { a as join, n as dirname, s as relative } from "./dist-DaKKDf8D.mjs";
3
3
  import { M as require_picocolors } from "./agents-CtgBYqld.mjs";
4
- import { A as resolveAssetRoutingPolicy, C as syncWranglerBindings, D as resolveSandboxConfig, E as isSandboxEnabled, O as hasApiRoutes, S as resolveLiveBindingConfig, T as SANDBOX_MIGRATION_TAG, _ as nextDurableObjectMigrationTag, a as prerenderPagesNode, c as filterLoadedEnv, d as LIVE_MIGRATION_TAG, g as hasDurableObjectSqliteMigration, h as ensureWranglerNodejsAlsFlag, i as prerenderPages, k as hasDocumentRoutes, l as resolveRemoteMode, m as ensureWranglerCompatibilityDate, n as resolveDistDir, o as collectRevalidate, p as ensureWranglerCompat, r as resolveWorkerDirName, s as hasRevalidate, u as stripInternalEnvKeys, v as normalizeWranglerCompatibilityFlags, x as readWranglerCompat, y as readExistingLiveBindingConfig } from "./deploy-DT8wsPZd.mjs";
4
+ import { A as resolveAssetRoutingPolicy, C as syncWranglerBindings, D as resolveSandboxConfig, E as isSandboxEnabled, O as hasApiRoutes, S as resolveLiveBindingConfig, T as SANDBOX_MIGRATION_TAG, _ as nextDurableObjectMigrationTag, a as prerenderPagesNode, c as filterLoadedEnv, d as LIVE_MIGRATION_TAG, g as hasDurableObjectSqliteMigration, h as ensureWranglerNodejsAlsFlag, i as prerenderPages, k as hasDocumentRoutes, l as resolveRemoteMode, m as ensureWranglerCompatibilityDate, n as resolveDistDir, o as collectRevalidate, p as ensureWranglerCompat, r as resolveWorkerDirName, s as hasRevalidate, u as stripInternalEnvKeys, v as normalizeWranglerCompatibilityFlags, x as readWranglerCompat, y as readExistingLiveBindingConfig } from "./deploy-jBJT1fUT.mjs";
5
5
  import { i as resolveProjectPaths, n as readProjectPaths, t as assertNoRootSourceConventionConflicts } from "./project-paths-BQd7OmIo.mjs";
6
- import { a as scanQueuesSync, c as loadVoidAuthConfig, i as scanWebSocketRoutesSync, n as scanRoutePatternsSync, o as scanJobsSync, r as scanRoutes, s as findVoidAuthConfig, t as scanMiddlewareSync } from "./scan-DYXkrasO.mjs";
6
+ import { a as scanQueuesSync, c as loadVoidAuthConfig, i as scanWebSocketRoutesSync, n as scanRoutePatternsSync, o as scanJobsSync, r as scanRoutes, s as findVoidAuthConfig, t as scanMiddlewareSync } from "./scan-ChWt4pX1.mjs";
7
7
  import { b as readProjectConfig, f as getToken, m as isStagingMode } from "./client-Gb71-XkG.mjs";
8
8
  import { n as ensureProjectTsconfig, r as writeFileIfChanged } from "./project-tsconfig-B-QtXjLQ.mjs";
9
- import { c as getDatabaseDialect, f as readConfig, l as isNodeTarget, p as resolveBindingNames } from "./config-E03l1C_h.mjs";
9
+ import { c as getDatabaseDialect, f as readConfig, l as isNodeTarget, p as resolveBindingNames } from "./config-qHGgPuWT.mjs";
10
10
  import { a as inferBindingsFromSource, i as inferProjectBindings, n as FRAMEWORK_SCAN_DIRS, o as walk, r as detectFramework, t as DEFAULT_SCAN_DIRS } from "./plugin-inference-DMeavIJ6.mjs";
11
11
  import { a as validateSsrEntries, c as isIdentifier, l as isLiteral, n as SSR_SERVER_ENTRY_RELATIVE_PATHS, o as validateSsrEntry, t as SSR_CLIENT_ENTRY_RELATIVE_PATHS, u as isMemberExpression } from "./entry-D7yy4xVH.mjs";
12
12
  import { i as voidWarn, n as voidError, r as voidLog, t as setShowTimestamp } from "./log-ChfPKsVd.mjs";
13
- import { l as parseDotenvFile } from "./preset-BGrvB4Bl.mjs";
14
- import { i as generateVoidAuthDrizzleSchema, n as generateQueueTypes, o as DRIZZLE_OPERATORS, r as generateVoidAuthDatabaseModule, s as generateDbDts, t as generateRouteTypes } from "./route-types-COI2DsZv.mjs";
13
+ import { l as parseDotenvFile } from "./preset-BjyR3lzz.mjs";
14
+ import { i as generateVoidAuthDrizzleSchema, n as generateQueueTypes, o as DRIZZLE_OPERATORS, r as generateVoidAuthDatabaseModule, s as generateDbDts, t as generateRouteTypes } from "./route-types-z1jtHEi_.mjs";
15
15
  import { t as discoverSchema } from "./discover-CJHyvYfR.mjs";
16
16
  import { t as MagicString } from "./magic-string.es-ZQjdJFFn.mjs";
17
17
  import { n as findEnvFileForPaths, r as generateEnvTypes, t as findEnvFile } from "./env-types-QBj-ndax.mjs";
18
- import { h as loadUserEnvFile } from "./env-validation-BdDlGhbN.mjs";
19
- import { i as resolveLayoutIds } from "./scan-DEwlM_Xy.mjs";
18
+ import { h as loadUserEnvFile } from "./env-validation-Dea3v3ej.mjs";
19
+ import { i as resolveLayoutIds, o as isRouteEnabledForEnvironment } from "./scan-NU4xKGci.mjs";
20
20
  import { n as STAGING_PROXY_URL, t as DEFAULT_PROXY_URL } from "./proxy-D-3_D-Gl.mjs";
21
- import { n as lintDuplicateSources, r as mergeRoutingRules, t as lintDestinationSplats } from "./headers-BQknpzkn.mjs";
21
+ import { n as lintDuplicateSources, r as mergeRoutingRules, t as lintDestinationSplats } from "./headers-ChAADPQu.mjs";
22
22
  import { n as INTERNAL_BINDING_PREFIXES, t as INTERNAL_BINDING_EXACT_NAMES } from "./env-raw-Cx8ElDdj.mjs";
23
23
  import { n as defer } from "./defer-YsYDUoii.mjs";
24
24
  import { VoidAssetRewriteError, basicAuth, defineHandler, defineHead, defineMiddleware, defineQueue, defineRender, defineScheduled } from "./runtime/handler.mjs";
@@ -1687,7 +1687,7 @@ function migrationPlugin(root, dialect, databaseId = "local", persistRoot = join
1687
1687
  if (applied.length > 0) voidLog(`Applied ${applied.length} migration(s): ${applied.join(", ")}`);
1688
1688
  }
1689
1689
  if (auth?.enabled) {
1690
- const { runLocalVoidAuthMigrations } = await import("./node-BDx8pmhq.mjs");
1690
+ const { runLocalVoidAuthMigrations } = await import("./node-pRg81HqV.mjs");
1691
1691
  await runLocalVoidAuthMigrations(root, dialect, persistRoot, databaseId, auth.configPath);
1692
1692
  voidLog("Applied Better Auth migrations");
1693
1693
  }
@@ -3562,9 +3562,19 @@ function compilePageRoutes(lines, scan, pages, options) {
3562
3562
  * Class A framework wrappers. If the app returns 404, check ASSETS binding
3563
3563
  * for static files and set cache headers. Edge caching of hashed assets
3564
3564
  * happens at the dispatch layer (see design doc 0042).
3565
+ *
3566
+ * `notFound` is the RESOLVED `assetConfig.not_found_handling` for this build
3567
+ * (`resolveAssetRoutingPolicy`), and it decides what happens once the asset
3568
+ * binding has also answered 404. It is a separate argument from
3569
+ * `serveSpaFallback` because the two are not derived from each other: the
3570
+ * common worker-first app runs with `not_found_handling: 'none'` and STILL
3571
+ * wants the worker-side shell fallback (that is the whole reason the flag
3572
+ * exists). They are mutually exclusive in practice — `resolveAssetRoutingPolicy`
3573
+ * clears `workerSpaFallback` whenever an explicit `routing.notFound` asks for
3574
+ * anything other than the SPA shell.
3565
3575
  */
3566
- function compileAssetFallbackHelper(assetsDir = "assets", serveSpaFallback = false) {
3567
- const spaFallbackCode = serveSpaFallback ? ` // SPA fallback: when HTML-owning features make
3576
+ function compileAssetFallbackHelper(assetsDir = "assets", serveSpaFallback = false, notFound = "none") {
3577
+ const fallthroughCode = serveSpaFallback ? ` // SPA fallback: when HTML-owning features make
3568
3578
  // assetConfig.not_found_handling = 'none', the asset binding returns 404
3569
3579
  // instead of falling back to index.html itself. Do that fallback here, after
3570
3580
  // user routes/middleware have run, so auth gates and OAuth callbacks see the request first.
@@ -3583,6 +3593,13 @@ function compileAssetFallbackHelper(assetsDir = "assets", serveSpaFallback = fal
3583
3593
  return res;
3584
3594
  }
3585
3595
  }
3596
+ return response;` : notFound === "404-page" ? ` const accept = request.headers.get("accept") ?? "";
3597
+ const assetContentType = asset.headers.get("content-type") ?? "";
3598
+ if (accept.includes("text/html") && assetContentType.includes("text/html")) {
3599
+ const res = new Response(asset.body, asset);
3600
+ res.headers.set("Cache-Control", "no-store");
3601
+ return res;
3602
+ }
3586
3603
  return response;` : ` return response;`;
3587
3604
  return `
3588
3605
  async function serveWithAssets(request, env, response) {
@@ -3597,7 +3614,7 @@ async function serveWithAssets(request, env, response) {
3597
3614
  }
3598
3615
  return res;
3599
3616
  }
3600
- ${spaFallbackCode}
3617
+ ${fallthroughCode}
3601
3618
  }
3602
3619
  `;
3603
3620
  }
@@ -3616,7 +3633,7 @@ ${spaFallbackCode}
3616
3633
  * remote mode (`__VOID_REMOTE`) and replace local bindings with
3617
3634
  * proxy-backed versions.
3618
3635
  */
3619
- function compileWorkerEntry(hasQueues = false, remote, assetsDir = "assets", webSocketClasses = [], runtimeEnvPath = "void/_env", envSchemaModule, sandbox, serveSpaFallback = false, live, isr) {
3636
+ function compileWorkerEntry(hasQueues = false, remote, assetsDir = "assets", webSocketClasses = [], runtimeEnvPath = "void/_env", envSchemaModule, sandbox, serveSpaFallback = false, live, isr, notFound = "none") {
3620
3637
  const remotePath = remote?.remotePath;
3621
3638
  const remoteBindingNames = JSON.stringify(remote?.bindingNames);
3622
3639
  const createRemoteEnvCall = `createRemoteEnv(env${remote?.bindingNames ? `, ${remoteBindingNames}` : ""})`;
@@ -3661,7 +3678,7 @@ function __filterInternalBindings(env) {
3661
3678
  });
3662
3679
  }
3663
3680
  `;
3664
- const assetHelper = compileAssetFallbackHelper(assetsDir, serveSpaFallback);
3681
+ const assetHelper = compileAssetFallbackHelper(assetsDir, serveSpaFallback, notFound);
3665
3682
  const isrImport = isr ? `import { handleIsr } from ${JSON.stringify(isr.runtimePath)};\nimport { __VOID_ISR_REVALIDATE, __VOID_ISR_DEPLOYMENT_ID } from 'virtual:void-routes';\n` : "";
3666
3683
  const isrEnvCapture = isr ? ` env.__VOID_ISR_DEPLOYMENT_ID ??= __VOID_ISR_DEPLOYMENT_ID;\n env.__VOID_ISR_HOST = new URL(request.url).hostname;\n` : "";
3667
3684
  const isrDeploymentStamp = isr ? ` env.__VOID_ISR_DEPLOYMENT_ID ??= __VOID_ISR_DEPLOYMENT_ID;\n` : "";
@@ -4235,6 +4252,7 @@ const RESOLVE_ID_FILTER = /^(virtual:void-(routes|client-worker(?::(react|vue|sv
4235
4252
  const LOAD_ID_FILTER = /^virtual:void-(routes|client-worker(?::(react|vue|svelte|solid))?|client-browser(?::(react|vue|svelte|solid))?)$/;
4236
4253
  function routingPlugin(root, options) {
4237
4254
  let scan = null;
4255
+ let routeEnvironment = "prod";
4238
4256
  let ssr = null;
4239
4257
  let authConfigPath = null;
4240
4258
  const paths = readProjectPaths(root);
@@ -4269,7 +4287,8 @@ function routingPlugin(root, options) {
4269
4287
  async function rescan() {
4270
4288
  scan = await scanRoutes(root, {
4271
4289
  output: options.output,
4272
- paths
4290
+ paths,
4291
+ environment: routeEnvironment
4273
4292
  });
4274
4293
  authConfigPath = findVoidAuthConfig(root, paths);
4275
4294
  const entries = validateSsrEntries(root, paths);
@@ -4418,6 +4437,15 @@ function routingPlugin(root, options) {
4418
4437
  if (!scan) return false;
4419
4438
  return resolveCurrentAssetRoutingPolicy().workerSpaFallback;
4420
4439
  }
4440
+ /**
4441
+ * The `not_found_handling` the generated worker entry must agree with. Read
4442
+ * off the SAME resolved policy that produces the wrangler asset config, so
4443
+ * the emitted `serveWithAssets` can never disagree with the platform switch
4444
+ * it is standing in for.
4445
+ */
4446
+ function currentNotFoundHandling() {
4447
+ return resolveCurrentAssetRoutingPolicy().assetConfig.not_found_handling ?? "none";
4448
+ }
4421
4449
  function resolveCurrentAssetRoutingPolicy() {
4422
4450
  if (!scan) return resolveAssetRoutingPolicy({
4423
4451
  isSsr: Boolean(ssr),
@@ -4427,7 +4455,8 @@ function routingPlugin(root, options) {
4427
4455
  hasMiddleware: false,
4428
4456
  hasWebSockets: false,
4429
4457
  authEnabled: compileOptions.auth !== null,
4430
- liveEnabled: options.live !== void 0
4458
+ liveEnabled: options.live !== void 0,
4459
+ notFound: options.routing?.notFound
4431
4460
  });
4432
4461
  return resolveAssetRoutingPolicy({
4433
4462
  isSsr: Boolean(ssr),
@@ -4437,7 +4466,8 @@ function routingPlugin(root, options) {
4437
4466
  hasMiddleware: scan.middleware.length > 0,
4438
4467
  hasWebSockets: hasDocumentRoutes(scan.websockets ?? []),
4439
4468
  authEnabled: compileOptions.auth !== null,
4440
- liveEnabled: options.live !== void 0
4469
+ liveEnabled: options.live !== void 0,
4470
+ notFound: options.routing?.notFound
4441
4471
  });
4442
4472
  }
4443
4473
  const outDir = join(root, ".void");
@@ -4465,6 +4495,7 @@ function routingPlugin(root, options) {
4465
4495
  }
4466
4496
  },
4467
4497
  config(_, env) {
4498
+ routeEnvironment = env.command === "serve" && !env.isPreview ? "dev" : "prod";
4468
4499
  if (env.command === "serve" && options.isAuthEnabled()) return { resolve: { alias: [
4469
4500
  "client",
4470
4501
  "react",
@@ -4520,7 +4551,7 @@ function routingPlugin(root, options) {
4520
4551
  bindingName: options.sandboxBindingName,
4521
4552
  className: options.sandboxClassName,
4522
4553
  runtimePath: sandboxRuntimePath
4523
- } : false, shouldServeSpaFallback(), options.live, isr));
4554
+ } : false, shouldServeSpaFallback(), options.live, isr, currentNotFoundHandling()));
4524
4555
  }
4525
4556
  },
4526
4557
  resolveId: {
@@ -4571,7 +4602,7 @@ function routingPlugin(root, options) {
4571
4602
  bindingName: options.sandboxBindingName,
4572
4603
  className: options.sandboxClassName,
4573
4604
  runtimePath: sandboxRuntimePath
4574
- } : false, shouldServeSpaFallback(), options.live));
4605
+ } : false, shouldServeSpaFallback(), options.live, void 0, currentNotFoundHandling()));
4575
4606
  const structural = event !== "change";
4576
4607
  const pageManifestChanged = isInDirectory(normalizedPath, normalizedPagesDir) && (structural || normalizedPath.endsWith(".md"));
4577
4608
  for (const env of Object.values(devServer.environments)) {
@@ -4706,10 +4737,10 @@ function warnIfPackageJsonIsNotEsm(root) {
4706
4737
  * dead-code-eliminated in `vite build`. Production deploys go through
4707
4738
  * `cli/wrapper.ts` instead.
4708
4739
  */
4709
- function getFrameworkEntry(framework, root, devTriggerToken) {
4740
+ function getFrameworkEntry(framework, root, devTriggerToken, notFound) {
4710
4741
  const isBuild = isViteBuildOrPreview();
4711
4742
  if (!isBuild) writeFrameworkTriggersDispatch(root, devTriggerToken);
4712
- return generateClassATriggerWrapper(root, framework, getOriginalFrameworkEntry(framework, root), isBuild);
4743
+ return generateClassATriggerWrapper(root, framework, getOriginalFrameworkEntry(framework, root), isBuild, void 0, notFound);
4713
4744
  }
4714
4745
  /** The framework's own server entry, before our trigger wrapper. */
4715
4746
  function getOriginalFrameworkEntry(framework, root) {
@@ -4738,7 +4769,7 @@ function getOriginalFrameworkEntry(framework, root) {
4738
4769
  * dispatch file (and its transitive user-cron/queue imports + dev token)
4739
4770
  * would still ship in the production bundle.
4740
4771
  */
4741
- function generateClassATriggerWrapper(root, framework, original, isBuild, assetsDir = "assets") {
4772
+ function generateClassATriggerWrapper(root, framework, original, isBuild, assetsDir = "assets", notFound) {
4742
4773
  const outDir = join(root, ".void");
4743
4774
  mkdirSync(outDir, { recursive: true });
4744
4775
  const wrapperPath = join(outDir, `${framework}-trigger-wrapper.ts`);
@@ -4751,7 +4782,7 @@ export default {
4751
4782
  return serveWithAssets(request, env, await original.fetch(request, env, ctx));
4752
4783
  },
4753
4784
  };
4754
- ${compileAssetFallbackHelper(assetsDir)}
4785
+ ${compileAssetFallbackHelper(assetsDir, false, notFound)}
4755
4786
  ` : `// @ts-nocheck — Auto-generated by Void in dev. Do NOT edit.
4756
4787
  import original from ${JSON.stringify(original)};
4757
4788
 
@@ -5035,6 +5066,7 @@ function voidPlugin(options) {
5035
5066
  const devTriggerToken = isViteBuildOrPreview() ? crypto.randomUUID() : getOrCreateDevTriggerToken(root);
5036
5067
  const config = readConfig(root);
5037
5068
  const paths = resolveProjectPaths(root, config);
5069
+ let routeEnvironment = "prod";
5038
5070
  assertNoRootSourceConventionConflicts(paths);
5039
5071
  const dialect = getDatabaseDialect(config);
5040
5072
  const detected = detectFramework(root);
@@ -5196,6 +5228,7 @@ function voidPlugin(options) {
5196
5228
  }
5197
5229
  const remoteMode = resolveRemoteMode(config.remote);
5198
5230
  const workerConfig = {};
5231
+ let assetRouting;
5199
5232
  if (config.worker?.vars) workerConfig.vars = { ...config.worker.vars };
5200
5233
  let viteCommand = "build";
5201
5234
  const wranglerCompat = isNodeTarget(config.target) ? void 0 : readWranglerCompat(root, config);
@@ -5203,12 +5236,14 @@ function voidPlugin(options) {
5203
5236
  workerConfig.compatibility_date = wranglerCompat.compatibilityDate;
5204
5237
  if (wranglerCompat.compatibilityFlags) workerConfig.compatibility_flags = wranglerCompat.compatibilityFlags;
5205
5238
  }
5239
+ if (config.worker?.limits?.cpu_ms) workerConfig.limits = { cpu_ms: config.worker.limits.cpu_ms };
5206
5240
  const inspectorPortEnv = process.env.VOID_INSPECTOR_PORT;
5207
5241
  const inspectorPort = inspectorPortEnv === "false" ? false : typeof inspectorPortEnv === "string" && inspectorPortEnv.length > 0 ? Number.parseInt(inspectorPortEnv, 10) : void 0;
5208
5242
  const inspectorPortOption = inspectorPort === false ? { inspectorPort: false } : typeof inspectorPort === "number" ? { inspectorPort } : {};
5209
5243
  const outDir = join(root, ".void");
5210
5244
  mkdirSync(outDir, { recursive: true });
5211
5245
  function mergeBindings(resolved) {
5246
+ const environmentWebsocketRoutes = websocketRoutes.filter((route) => isRouteEnabledForEnvironment(route, routeEnvironment));
5212
5247
  const result = { ...workerConfig };
5213
5248
  if (workerConfig.assets && resolved.assets) {
5214
5249
  delete resolved.assets.not_found_handling;
@@ -5253,16 +5288,16 @@ function voidPlugin(options) {
5253
5288
  ...q.retryDelay != null && { retry_delay: q.retryDelay }
5254
5289
  }))
5255
5290
  };
5256
- if (websocketRoutes.length > 0) {
5291
+ if (environmentWebsocketRoutes.length > 0) {
5257
5292
  const existingDurableObjectBindings = resolved.durable_objects?.bindings ?? [];
5258
- const missingDurableObjectBindings = websocketRoutes.filter((route) => !existingDurableObjectBindings.some((binding) => binding.name === route.bindingName)).map((route) => ({
5293
+ const missingDurableObjectBindings = environmentWebsocketRoutes.filter((route) => !existingDurableObjectBindings.some((binding) => binding.name === route.bindingName)).map((route) => ({
5259
5294
  name: route.bindingName,
5260
5295
  class_name: route.className
5261
5296
  }));
5262
5297
  if (missingDurableObjectBindings.length > 0) result.durable_objects = { bindings: [...existingDurableObjectBindings, ...missingDurableObjectBindings] };
5263
5298
  if (!Array.isArray(resolved.migrations)) result.migrations = [{
5264
5299
  tag: "void-ws-v1",
5265
- new_classes: websocketRoutes.map((route) => route.className)
5300
+ new_classes: environmentWebsocketRoutes.map((route) => route.className)
5266
5301
  }];
5267
5302
  }
5268
5303
  if (bindings.needsSandbox && sandboxConfig) {
@@ -5332,8 +5367,13 @@ function voidPlugin(options) {
5332
5367
  const envPlugin = {
5333
5368
  name: "void:env",
5334
5369
  api: { getVoidDeployBuildConfig: () => voidDeployBuildConfig },
5335
- config(userConfig, { mode, command }) {
5370
+ config(userConfig, { mode, command, isPreview }) {
5336
5371
  viteCommand = command;
5372
+ routeEnvironment = command === "serve" && !isPreview ? "dev" : "prod";
5373
+ if (!framework && !isNodeTarget(config.target)) {
5374
+ assetRouting = resolveConfiguredAssetRoutingPolicy();
5375
+ applyAssetRoutingPolicy(assetRouting);
5376
+ }
5337
5377
  const ignored = ["**/.void/**"];
5338
5378
  const rawEnvDir = typeof userConfig.envDir === "string" && userConfig.envDir.length > 0 ? userConfig.envDir : void 0;
5339
5379
  voidDeployBuildConfig = {
@@ -5347,7 +5387,7 @@ function voidPlugin(options) {
5347
5387
  ...env
5348
5388
  };
5349
5389
  const assets = workerConfig.assets;
5350
- if (command === "serve" && assets?.run_worker_first?.includes("/**")) assets.run_worker_first = [...DEV_ASSET_ROUTING_EXCLUSIONS, "/**"];
5390
+ if (command === "serve" && !isPreview && assets?.run_worker_first?.includes("/**")) assets.run_worker_first = [...DEV_ASSET_ROUTING_EXCLUSIONS, "/**"];
5351
5391
  const watchConfig = { server: { watch: { ignored } } };
5352
5392
  if (!isNodeTarget(config.target) && config.output !== "static") {
5353
5393
  const envNames = framework === "vinext-app" ? ["rsc", "ssr"] : ["ssr"];
@@ -5448,12 +5488,17 @@ function voidPlugin(options) {
5448
5488
  }
5449
5489
  };
5450
5490
  if (framework) {
5451
- workerConfig.main = getFrameworkEntry(framework, root, devTriggerToken);
5491
+ workerConfig.main = getFrameworkEntry(framework, root, devTriggerToken, config.routing?.notFound);
5492
+ let notFoundIgnoredWarned = false;
5452
5493
  const frameworkBuildWrapperPlugin = {
5453
5494
  name: "void:framework-build-wrapper",
5454
5495
  configResolved(resolved) {
5455
5496
  if (resolved.command !== "build") return;
5456
- generateClassATriggerWrapper(root, framework, getOriginalFrameworkEntry(framework, root), true, resolved.build.assetsDir);
5497
+ if (config.routing?.notFound !== void 0 && !process.env.VOID_DEPLOY_BUILD && !notFoundIgnoredWarned) {
5498
+ notFoundIgnoredWarned = true;
5499
+ voidWarn(`Void generates no asset routing policy for a ${framework} build, so "routing.notFound" in void.json is not written to the built worker config. On a self-hosted \`vite build && wrangler deploy\` it takes effect only if your own wrangler config declares a complete \`assets\` policy (\`binding\`, \`directory\`, \`not_found_handling\`, \`run_worker_first\`); otherwise Cloudflare's default applies. Managed \`void deploy\` supplies the policy for you.`);
5500
+ }
5501
+ generateClassATriggerWrapper(root, framework, getOriginalFrameworkEntry(framework, root), true, resolved.build.assetsDir, config.routing?.notFound);
5457
5502
  }
5458
5503
  };
5459
5504
  const existingFlags = workerConfig.compatibility_flags ?? [];
@@ -5543,19 +5588,22 @@ function voidPlugin(options) {
5543
5588
  const ssrEntry = validateSsrEntry(root, paths);
5544
5589
  const hasPages = existsSync(paths.pagesDir);
5545
5590
  const hasMiddleware = scanMiddlewareSync(root, paths).length > 0;
5546
- const routePatterns = scanRoutePatternsSync(root, paths);
5547
- const hasDocumentRoutes$1 = hasDocumentRoutes(routePatterns);
5548
- const hasApiRoutes$1 = hasApiRoutes(routePatterns) || hasApiRoutes(websocketRoutes) || authEnabled;
5549
- let assetRouting = resolveAssetRoutingPolicy({
5550
- isSsr: Boolean(ssrEntry),
5551
- hasPages,
5552
- hasApiRoutes: hasApiRoutes$1,
5553
- hasDocumentRoutes: hasDocumentRoutes$1,
5554
- hasMiddleware,
5555
- hasWebSockets: hasDocumentRoutes(websocketRoutes),
5556
- authEnabled,
5557
- liveEnabled: liveConfig !== void 0
5558
- });
5591
+ function resolveConfiguredAssetRoutingPolicy() {
5592
+ const routePatterns = scanRoutePatternsSync(root, paths, routeEnvironment);
5593
+ const environmentWebsocketRoutes = websocketRoutes.filter((route) => isRouteEnabledForEnvironment(route, routeEnvironment));
5594
+ return resolveAssetRoutingPolicy({
5595
+ isSsr: Boolean(ssrEntry),
5596
+ hasPages,
5597
+ hasApiRoutes: hasApiRoutes(routePatterns) || hasApiRoutes(environmentWebsocketRoutes) || authEnabled,
5598
+ hasDocumentRoutes: hasDocumentRoutes(routePatterns),
5599
+ hasMiddleware,
5600
+ hasWebSockets: hasDocumentRoutes(environmentWebsocketRoutes),
5601
+ authEnabled,
5602
+ liveEnabled: liveConfig !== void 0,
5603
+ notFound: config.routing?.notFound
5604
+ });
5605
+ }
5606
+ assetRouting = resolveConfiguredAssetRoutingPolicy();
5559
5607
  workerConfig.main = join(root, ".void", "entry.ts");
5560
5608
  if (jobs.length > 0) workerConfig.triggers = { crons: jobs.flatMap((job) => job.crons) };
5561
5609
  function applyAssetRoutingPolicy(policy) {
@@ -3,9 +3,9 @@ import { A as text, D as outro, E as note, S as confirm, T as log, a as cliTitle
3
3
  import { n as readProjectPaths } from "./project-paths-BQd7OmIo.mjs";
4
4
  import { S as writeProjectConfig, b as readProjectConfig, f as getToken, m as isStagingMode, n as PlatformClient } from "./client-Gb71-XkG.mjs";
5
5
  import { n as ensureProjectTsconfig, t as createProjectTsconfig } from "./project-tsconfig-B-QtXjLQ.mjs";
6
- import { c as getDatabaseDialect, f as readConfig } from "./config-E03l1C_h.mjs";
6
+ import { c as getDatabaseDialect, f as readConfig } from "./config-qHGgPuWT.mjs";
7
7
  import { r as detectFramework } from "./plugin-inference-DMeavIJ6.mjs";
8
- import { l as parseDotenvFile, r as formatProjectCommand, s as expandDotenv } from "./preset-BGrvB4Bl.mjs";
8
+ import { l as parseDotenvFile, r as formatProjectCommand, s as expandDotenv } from "./preset-BjyR3lzz.mjs";
9
9
  import { t as MagicString } from "./magic-string.es-ZQjdJFFn.mjs";
10
10
  import { n as writeDrizzleConfig } from "./config-CutEMNGJ.mjs";
11
11
  import { n as promptAndCreateProject, r as promptProjectSelection } from "./create-project-DsYvl3TB.mjs";
@@ -1,7 +1,7 @@
1
1
  import { a as join } from "./dist-DaKKDf8D.mjs";
2
- import { c as loadVoidAuthConfig, s as findVoidAuthConfig } from "./scan-DYXkrasO.mjs";
3
- import { f as readConfig } from "./config-E03l1C_h.mjs";
4
- import { a as resolveVoidAuthMigrationSchema } from "./route-types-COI2DsZv.mjs";
2
+ import { c as loadVoidAuthConfig, s as findVoidAuthConfig } from "./scan-ChWt4pX1.mjs";
3
+ import { f as readConfig } from "./config-qHGgPuWT.mjs";
4
+ import { a as resolveVoidAuthMigrationSchema } from "./route-types-z1jtHEi_.mjs";
5
5
  import { n as applySqliteAuthMigrations, t as applyPgAuthMigrations } from "./auth-migrations-BTZ-ATvQ.mjs";
6
6
  import { getMiniflareDatabasePath } from "./runner-kapo9aPs.mjs";
7
7
  import { loadEnv } from "vite";
@@ -1,8 +1,8 @@
1
1
  import { a as join } from "../dist-DaKKDf8D.mjs";
2
2
  import { r as resolvePagesDir } from "../project-paths-BQd7OmIo.mjs";
3
- import { f as readConfig } from "../config-E03l1C_h.mjs";
4
- import { a as resolveNamedLayout, i as resolveLayoutIds, n as resolveEffectiveLayoutChain, r as resolveLayoutChain, t as scanPages } from "../scan-DEwlM_Xy.mjs";
5
- import { i as parseRedirectsFile } from "../headers-BQknpzkn.mjs";
3
+ import { f as readConfig } from "../config-qHGgPuWT.mjs";
4
+ import { a as resolveNamedLayout, i as resolveLayoutIds, n as resolveEffectiveLayoutChain, r as resolveLayoutChain, t as scanPages } from "../scan-NU4xKGci.mjs";
5
+ import { i as parseRedirectsFile } from "../headers-ChAADPQu.mjs";
6
6
  import { renderBodyAttrs, renderHeadToString, renderHtmlAttrs, resolveHead } from "./head.mjs";
7
7
  import { serializePageData } from "./serialize.mjs";
8
8
  //#region src/pages/manifest.ts
@@ -1,5 +1,5 @@
1
1
  import { c as resolve, n as dirname } from "../dist-DaKKDf8D.mjs";
2
- import { n as resolveEffectiveLayoutChain, t as scanPages } from "../scan-DEwlM_Xy.mjs";
2
+ import { n as resolveEffectiveLayoutChain, t as scanPages } from "../scan-NU4xKGci.mjs";
3
3
  import { existsSync, readFileSync, readdirSync } from "node:fs";
4
4
  import { normalizePath } from "vite";
5
5
  //#region src/pages/islands-plugin.ts
@@ -1,11 +1,11 @@
1
1
  import { a as join } from "./dist-DaKKDf8D.mjs";
2
2
  import { D as outro, E as note, T as log, a as cliTitle, w as intro } from "./agents-CtgBYqld.mjs";
3
3
  import { i as resolveProjectPaths } from "./project-paths-BQd7OmIo.mjs";
4
- import { c as loadVoidAuthConfig, r as scanRoutes, s as findVoidAuthConfig } from "./scan-DYXkrasO.mjs";
4
+ import { c as loadVoidAuthConfig, r as scanRoutes, s as findVoidAuthConfig } from "./scan-ChWt4pX1.mjs";
5
5
  import { n as ensureProjectTsconfig, r as writeFileIfChanged } from "./project-tsconfig-B-QtXjLQ.mjs";
6
- import { c as getDatabaseDialect, f as readConfig } from "./config-E03l1C_h.mjs";
6
+ import { c as getDatabaseDialect, f as readConfig } from "./config-qHGgPuWT.mjs";
7
7
  import { i as inferProjectBindings, n as FRAMEWORK_SCAN_DIRS, r as detectFramework } from "./plugin-inference-DMeavIJ6.mjs";
8
- import { i as generateVoidAuthDrizzleSchema, n as generateQueueTypes, r as generateVoidAuthDatabaseModule, s as generateDbDts, t as generateRouteTypes } from "./route-types-COI2DsZv.mjs";
8
+ import { i as generateVoidAuthDrizzleSchema, n as generateQueueTypes, r as generateVoidAuthDatabaseModule, s as generateDbDts, t as generateRouteTypes } from "./route-types-z1jtHEi_.mjs";
9
9
  import { t as discoverSchema } from "./discover-CJHyvYfR.mjs";
10
10
  import { r as generateEnvTypes, t as findEnvFile } from "./env-types-QBj-ndax.mjs";
11
11
  import { existsSync, mkdirSync, rmSync } from "node:fs";
@@ -1,6 +1,6 @@
1
- import { a as join, c as resolve, n as dirname } from "./dist-DaKKDf8D.mjs";
1
+ import { a as join, c as resolve, n as dirname, s as relative } from "./dist-DaKKDf8D.mjs";
2
2
  import { n as readProjectPaths } from "./project-paths-BQd7OmIo.mjs";
3
- import { i as hasSsrEntry } from "./entry-D7yy4xVH.mjs";
3
+ import { i as hasSsrEntry, r as getSsrServerEntryPath } from "./entry-D7yy4xVH.mjs";
4
4
  import { i as readPackageJson, n as hasPackageDependency, t as getPackageDependencies } from "./package-json-Cx1osYo6.mjs";
5
5
  import { createRequire } from "node:module";
6
6
  import { existsSync, readFileSync } from "node:fs";
@@ -446,6 +446,15 @@ function formatProjectCommand(root, command) {
446
446
  /**
447
447
  * Detect a static deploy preset based on the project root.
448
448
  * Returns null when the project requires a full worker deploy.
449
+ *
450
+ * `strictBackend` refuses (throws) instead of returning an SSG preset when the
451
+ * project ALSO has backend sources. SSG detection (step 2) deliberately runs
452
+ * before the backend check (step 3), so without this an SSG repo that grew a
453
+ * single `routes/api/*.ts` would deploy as a pure static site with the backend
454
+ * silently dropped and no diagnostic. Opt-in because only the UNCONFIGURED
455
+ * auto-detect path is ambiguous: `--dir` and a configured
456
+ * `inference.appType: "static" | "spa"` are the user stating what they want, and
457
+ * must keep working silently.
449
458
  */
450
459
  function detectPreset(root, options) {
451
460
  if (options?.dir) return {
@@ -457,6 +466,10 @@ function detectPreset(root, options) {
457
466
  if (pkg) {
458
467
  const allDeps = getPackageDependencies(pkg);
459
468
  for (const preset of Object.values(SSG_PRESETS)) if (preset.dep in allDeps) {
469
+ if (options?.strictBackend) {
470
+ const backendSources = findBackendSources(root);
471
+ if (backendSources.length > 0) throw new Error(ssgWithBackendMessage(preset.dep, backendSources));
472
+ }
460
473
  const overrides = preset.resolve?.(root);
461
474
  const cmd = overrides?.buildCommand ?? preset.buildCommand;
462
475
  const out = overrides?.outputDir ?? preset.outputDir;
@@ -486,6 +499,25 @@ function detectPreset(root, options) {
486
499
  return null;
487
500
  }
488
501
  /**
502
+ * The refusal shown when an SSG project also carries backend sources and no
503
+ * `inference.appType` says which one to deploy. Names the exact directories
504
+ * found and both ways out.
505
+ */
506
+ function ssgWithBackendMessage(ssgDep, backendSources) {
507
+ return [
508
+ `deploy: "${ssgDep}" was detected, but this project also has backend code: ${backendSources.join(", ")}.`,
509
+ "A static deploy would silently drop it, so Void will not guess. Pick one in void.json:",
510
+ "",
511
+ " Deploy the static output only (the backend is NOT deployed):",
512
+ " { \"inference\": { \"appType\": \"static\" } }",
513
+ "",
514
+ " Deploy both — the SSG emits the site, then Void packages it with the worker:",
515
+ " { \"inference\": { \"appType\": \"void\", \"build\": \"<ssg> build && vite build\" } }",
516
+ " ...and in vite.config.ts add voidPlugin() plus `publicDir: \"<ssg output dir>\"`,",
517
+ " so the generated site is copied into the client build alongside the worker."
518
+ ].join("\n");
519
+ }
520
+ /**
489
521
  * Resolve a local node_modules/.bin executable path.
490
522
  * Falls back to bare command name if the bin doesn't exist locally.
491
523
  */
@@ -523,6 +555,27 @@ function detectViteBinary(root) {
523
555
  return "vite";
524
556
  }
525
557
  /**
558
+ * Every backend source in the project that requires a full worker deploy, named
559
+ * relative to the root (e.g. `routes/`, `src/main.ssr.tsx`).
560
+ *
561
+ * Returned as a list rather than a boolean so a caller that has to REJECT a
562
+ * static deploy can tell the user exactly what would have been dropped.
563
+ */
564
+ function findBackendSources(root) {
565
+ const paths = readProjectPaths(root);
566
+ const found = [];
567
+ for (const dir of [
568
+ paths.routesDir,
569
+ paths.pagesDir,
570
+ paths.middlewareDir,
571
+ paths.cronsDir,
572
+ paths.queuesDir
573
+ ]) if (existsSync(dir)) found.push(`${relative(root, dir)}/`);
574
+ const ssrEntry = getSsrServerEntryPath(root, paths);
575
+ if (ssrEntry) found.push(relative(root, ssrEntry));
576
+ return found;
577
+ }
578
+ /**
526
579
  * Check whether the project has backend files that require a full worker deploy.
527
580
  */
528
581
  function hasBackendFiles(root) {
@@ -1,7 +1,7 @@
1
1
  import { a as join, c as resolve, n as dirname, o as normalize, t as basename } from "./dist-DaKKDf8D.mjs";
2
- import { b as readProvisionedBindingEntry, f as assertNoDuplicateMembers, w as writeProvisionedWranglerConfig } from "./deploy-DT8wsPZd.mjs";
2
+ import { b as readProvisionedBindingEntry, f as assertNoDuplicateMembers, w as writeProvisionedWranglerConfig } from "./deploy-jBJT1fUT.mjs";
3
3
  import { i as voidWarn, r as voidLog } from "./log-ChfPKsVd.mjs";
4
- import { o as resolveWranglerArgv, u as scanWranglerDotenvKeys } from "./preset-BGrvB4Bl.mjs";
4
+ import { o as resolveWranglerArgv, u as scanWranglerDotenvKeys } from "./preset-BjyR3lzz.mjs";
5
5
  import { createRequire } from "node:module";
6
6
  import { closeSync, existsSync, fsyncSync, lstatSync, openSync, readFileSync, readlinkSync, realpathSync, renameSync, unlinkSync, writeFileSync, writeSync } from "node:fs";
7
7
  import { randomUUID } from "node:crypto";
@@ -283,7 +283,14 @@ function generateVoidAuthDatabaseModule(options) {
283
283
  `import { db as __voidDb } from "void/db";`,
284
284
  `import { schema as __voidAuthSchema } from ${schemaImport};`,
285
285
  "",
286
- `export const __voidAuthDatabase = drizzleAdapter(__voidDb, { provider: ${JSON.stringify(provider)}, schema: __voidAuthSchema });`,
286
+ "// Better Auth reads Drizzle metadata while creating the adapter.",
287
+ "// Defer that work until request handling, when runtime bindings are available.",
288
+ "let __voidAuthDatabaseInstance: ReturnType<typeof drizzleAdapter> | undefined;",
289
+ "",
290
+ "export const __voidAuthDatabase: ReturnType<typeof drizzleAdapter> = (options) => {",
291
+ ` __voidAuthDatabaseInstance ??= drizzleAdapter(__voidDb, { provider: ${JSON.stringify(provider)}, schema: __voidAuthSchema });`,
292
+ " return __voidAuthDatabaseInstance(options);",
293
+ "};",
287
294
  ""
288
295
  ].join("\n");
289
296
  }