void 0.9.2 → 0.9.3

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 (53) hide show
  1. package/README.md +1 -0
  2. package/dist/{better-auth-shared-ChVbrq52.mjs → better-auth-shared-QAfk8CAS.mjs} +1 -1
  3. package/dist/cli/cli.mjs +12 -12
  4. package/dist/{config-BVEC0lti.mjs → config-8dLIngKW.mjs} +1 -1
  5. package/dist/{db-DiddQC2v.mjs → db-UW4IYQFw.mjs} +4 -4
  6. package/dist/{deploy-CRU9fGjE.mjs → deploy-RQXpVBL-.mjs} +27 -10
  7. package/dist/{drizzle-2fs1qTgy.mjs → drizzle-DYstYz0j.mjs} +1 -1
  8. package/dist/{env-Bvw0wMTI.mjs → env-C_ZcxxED.mjs} +2 -2
  9. package/dist/{env-types-D6qI1ThV.mjs → env-types-CaJaIRXU.mjs} +1 -1
  10. package/dist/{env-validation-DBJsxZLz.mjs → env-validation-LH6eoyW-.mjs} +3 -3
  11. package/dist/{gen-CZdNWIaA.mjs → gen-O5mXZ76K.mjs} +2 -2
  12. package/dist/{handler-xflsMwWM.d.mts → handler-hm9KldPP.d.mts} +21 -1
  13. package/dist/{headers-Y0jshugF.mjs → headers-VkAnACKX.mjs} +2 -2
  14. package/dist/index.d.mts +2 -2
  15. package/dist/index.mjs +48 -43
  16. package/dist/{init-BHupO7Fm.mjs → init-DGrLx2ls.mjs} +5 -5
  17. package/dist/{node-CHWVVjO6.mjs → node-Df8UjQ2H.mjs} +2 -2
  18. package/dist/pages/client.d.mts +1 -1
  19. package/dist/pages/index.d.mts +7 -5
  20. package/dist/pages/index.mjs +3 -3
  21. package/dist/pages/islands-plugin.d.mts +1 -1
  22. package/dist/pages/islands-plugin.mjs +1 -1
  23. package/dist/pages/protocol.d.mts +2 -2
  24. package/dist/pages/protocol.mjs +29 -11
  25. package/dist/{plugin-inference-BUBhHt_1.mjs → plugin-inference--7geW5Z2.mjs} +1 -1
  26. package/dist/{prepare-CrlAVbWS.mjs → prepare-DT-7QII_.mjs} +14 -19
  27. package/dist/{preset-CIJG2O7a.mjs → preset-2aBxMfY1.mjs} +1 -1
  28. package/dist/{project-tsconfig-HAGjfY6w.mjs → project-tsconfig-BTNuNoJ0.mjs} +18 -4
  29. package/dist/{protocol-DYca39yJ.d.mts → protocol-B9GZA4Bn.d.mts} +7 -4
  30. package/dist/{route-types-jxRfWuCb.mjs → route-types-D03ryMXz.mjs} +3 -2
  31. package/dist/runtime/better-auth-pg.mjs +1 -1
  32. package/dist/runtime/better-auth.mjs +1 -1
  33. package/dist/runtime/handler.d.mts +2 -2
  34. package/dist/runtime/handler.mjs +67 -1
  35. package/dist/runtime/live.d.mts +1 -1
  36. package/dist/runtime/validator.d.mts +1 -1
  37. package/dist/runtime/ws.d.mts +1 -1
  38. package/dist/{scan-BNC_1OsY.mjs → scan-B2H1Vo2C.mjs} +3 -3
  39. package/dist/{scan-2YmJkYAf.mjs → scan-VCAM1oh3.mjs} +55 -29
  40. package/dist/{types-Dm9kep2X.d.mts → types-DEWCqHtl.d.mts} +12 -3
  41. package/package.json +2 -2
  42. package/skills/void/docs/guide/pages-routing/layouts.md +8 -7
  43. package/skills/void/docs/guide/pages-routing/loaders.md +1 -1
  44. package/skills/void/docs/guide/pages-routing/overview.md +32 -5
  45. package/skills/void/docs/guide/server-routing.md +28 -0
  46. package/skills/void/docs/node_modules/void/AGENTS.md +15 -14
  47. package/skills/void/docs/node_modules/void/README.md +1 -0
  48. package/skills/void/docs/reference/api.md +44 -1
  49. package/skills/void/docs/reference/config.md +1 -1
  50. /package/dist/{dist-DR9sIMbM.mjs → dist-5cGIJHQQ.mjs} +0 -0
  51. /package/dist/{dotenv-Bkoqyq9r.mjs → dotenv-lS94ymhM.mjs} +0 -0
  52. /package/dist/{log-CWWZV4V1.mjs → log-BdD_Fpms.mjs} +0 -0
  53. /package/dist/{providers-uC0PJg1c.mjs → providers-BwPbdHdi.mjs} +0 -0
@@ -1,4 +1,4 @@
1
- import { t as PageObject } from "../protocol-DYca39yJ.mjs";
1
+ import { t as PageObject } from "../protocol-B9GZA4Bn.mjs";
2
2
  import { CacheForInput, CacheForResult } from "./prefetch.mjs";
3
3
 
4
4
  //#region src/pages/action-result.d.ts
@@ -1,5 +1,5 @@
1
1
  import { a as renderHtmlAttrs, i as renderHeadToString, n as HeadDescriptor, o as resolveHead, r as renderBodyAttrs, t as HeadConfig } from "../head-BsSTGnIe.mjs";
2
- import { a as PageScanResult, i as PageDefinition, n as LayoutDefinition, r as NamedLayoutDefinition } from "../types-Dm9kep2X.mjs";
2
+ import { i as PageDefinition, n as LayoutDefinition, o as PageScanResult, r as NamedLayoutDefinition } from "../types-DEWCqHtl.mjs";
3
3
  import { serializePageData } from "./serialize.mjs";
4
4
  import { RewriteDestination } from "void/routes";
5
5
 
@@ -27,21 +27,23 @@ declare function resolvePagesDir(root?: string): string;
27
27
  //#endregion
28
28
  //#region src/pages/layout-resolution.d.ts
29
29
  /** Resolve the layout chain for a component (innermost last) */
30
- declare function resolveLayoutChain(componentId: string, layouts: Array<LayoutDefinition>): Array<LayoutDefinition>;
30
+ declare function resolveLayoutChain(componentId: string, layouts: Array<LayoutDefinition>, componentPath?: string): Array<LayoutDefinition>;
31
31
  /** Walk up directory tree to find closest _layouts/<name> */
32
- declare function resolveNamedLayout(name: string, componentId: string, namedLayouts: Array<NamedLayoutDefinition>): NamedLayoutDefinition | null;
32
+ declare function resolveNamedLayout(name: string, componentId: string, namedLayouts: Array<NamedLayoutDefinition>, componentPath?: string): NamedLayoutDefinition | null;
33
33
  /** Resolve effective layout chain accounting for named layout selection */
34
34
  declare function resolveEffectiveLayoutChain(page: {
35
35
  componentId: string;
36
+ componentPath?: string;
36
37
  layout?: string | false;
37
38
  }, layouts: Array<LayoutDefinition>, namedLayouts: Array<NamedLayoutDefinition>): Array<LayoutDefinition | NamedLayoutDefinition>;
38
39
  //#endregion
39
40
  //#region src/pages/scan.d.ts
40
- declare function scanPages(root: string, options?: {
41
+ type PageScanOptions = {
41
42
  output?: "server" | "static";
42
43
  paths?: ProjectPaths;
43
44
  pagesDir?: string;
44
- }): Promise<PageScanResult>;
45
+ };
46
+ declare function scanPages(root: string, options?: PageScanOptions): Promise<PageScanResult>;
45
47
  //#endregion
46
48
  //#region src/pages/manifest.d.ts
47
49
  /**
@@ -1,8 +1,8 @@
1
1
  import { a as join } from "../pathe.M-eThtNZ-BrPhGF_K.mjs";
2
2
  import { r as resolvePagesDir } from "../project-paths-CCMrHYQm.mjs";
3
- import { f as readConfig } from "../config-BVEC0lti.mjs";
4
- import { a as resolveNamedLayout, i as resolveLayoutIds, n as resolveEffectiveLayoutChain, r as resolveLayoutChain, t as scanPages } from "../scan-2YmJkYAf.mjs";
5
- import { i as parseRedirectsFile } from "../headers-Y0jshugF.mjs";
3
+ import { f as readConfig } from "../config-8dLIngKW.mjs";
4
+ import { a as resolveNamedLayout, i as resolveLayoutIds, n as resolveEffectiveLayoutChain, r as resolveLayoutChain, t as scanPages } from "../scan-VCAM1oh3.mjs";
5
+ import { i as parseRedirectsFile } from "../headers-VkAnACKX.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,4 +1,4 @@
1
- import { a as PageScanResult } from "../types-Dm9kep2X.mjs";
1
+ import { o as PageScanResult } from "../types-DEWCqHtl.mjs";
2
2
  import { ResolvedConfig, ViteDevServer } from "vite";
3
3
 
4
4
  //#region src/pages/islands-plugin.d.ts
@@ -1,5 +1,5 @@
1
1
  import { c as resolve, n as dirname } from "../pathe.M-eThtNZ-BrPhGF_K.mjs";
2
- import { n as resolveEffectiveLayoutChain, t as scanPages } from "../scan-2YmJkYAf.mjs";
2
+ import { n as resolveEffectiveLayoutChain, t as scanPages } from "../scan-VCAM1oh3.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,3 +1,3 @@
1
- import { S as ValidationError } from "../handler-xflsMwWM.mjs";
2
- import { a as handlePageMutation, i as handlePageGet, n as PageRenderResult, o as safeJsonStringify, r as flattenValidationErrors, t as PageObject } from "../protocol-DYca39yJ.mjs";
1
+ import { w as ValidationError } from "../handler-hm9KldPP.mjs";
2
+ import { a as handlePageMutation, i as handlePageGet, n as PageRenderResult, o as safeJsonStringify, r as flattenValidationErrors, t as PageObject } from "../protocol-B9GZA4Bn.mjs";
3
3
  export { PageObject, PageRenderResult, ValidationError, flattenValidationErrors, handlePageGet, handlePageMutation, safeJsonStringify };
@@ -1,6 +1,7 @@
1
1
  import { isConvertedResponse } from "../runtime/response.mjs";
2
2
  import { i as ValidationError, r as separateDeferred, t as DEFERRED } from "../defer-CouVukrf.mjs";
3
- import { resolveHead } from "./head.mjs";
3
+ import { renderBodyAttrs, renderHeadToString, renderHtmlAttrs, resolveHead } from "./head.mjs";
4
+ import { serializePageData } from "./serialize.mjs";
4
5
  //#region src/pages/protocol.ts
5
6
  const POWERED_BY = { "X-Powered-By": "Void" };
6
7
  const RENDER_ERROR_ASSET_TAGS_KEY = "__voidPageAssetTags";
@@ -95,6 +96,21 @@ async function renderWithAssetTags(renderFn, pageObj, assetTags) {
95
96
  attachRenderErrorAssetTags(error, assetTags);
96
97
  }
97
98
  }
99
+ function renderClientOnlyPage(pageObj, assetTags, renderFn) {
100
+ const pageData = serializePageData(pageObj);
101
+ const headHtml = pageObj.head ? renderHeadToString(pageObj.head) : "";
102
+ const htmlAttrs = pageObj.head ? renderHtmlAttrs(pageObj.head) : "";
103
+ const bodyAttrs = pageObj.head ? renderBodyAttrs(pageObj.head) : "";
104
+ return `<!doctype html>
105
+ <html${htmlAttrs}>
106
+ <head>${headHtml}${typeof renderFn.preambleScript === "string" ? renderFn.preambleScript : ""}${assetTags.css}${assetTags.preloads}</head>
107
+ <body${bodyAttrs}>
108
+ <script id="__VOID_PAGE_DATA__" type="application/json">${pageData}<\/script>
109
+ <div id="app" data-void-ssr="false"></div>
110
+ ${assetTags.body}
111
+ </body>
112
+ </html>`;
113
+ }
98
114
  function pageJsonResponse(c, pageObj) {
99
115
  return Response.json(pageObj, { headers: pageResponseHeaders(c, {
100
116
  "X-VoidPages": "true",
@@ -170,7 +186,8 @@ function streamDeferredResponse(initialChunk, deferredMap, c, contentType, forma
170
186
  }), assetTags?.devCssNonce) });
171
187
  }
172
188
  /** Handle GET page request — run handler, return page object or SSR HTML */
173
- async function handlePageGet(handler, headFn, c, componentId, renderFn, getAssetTags, configHead, island) {
189
+ async function handlePageGet(handler, headFn, c, componentId, renderFn, getAssetTags, configHead, options) {
190
+ const renderMode = options?.renderMode ?? "server";
174
191
  const shared = c.get("shared") ?? {};
175
192
  let props = {};
176
193
  if (handler) {
@@ -200,7 +217,7 @@ async function handlePageGet(handler, headFn, c, componentId, renderFn, getAsset
200
217
  deferredKeys
201
218
  }
202
219
  };
203
- if (!island && isPagesRequest(c)) {
220
+ if (renderMode !== "island" && isPagesRequest(c)) {
204
221
  if (c.req.header("purpose") === "prefetch" && hasDeferred) {
205
222
  const resolvedProps = { ...immediateProps };
206
223
  await Promise.all(Object.entries(deferredMap).map(async ([, { resolver, keys }]) => {
@@ -231,12 +248,13 @@ async function handlePageGet(handler, headFn, c, componentId, renderFn, getAsset
231
248
  }) + "\n");
232
249
  }
233
250
  const assetTags = prepareAssetTags(await getAssetTags(c.req.raw, c.env, componentId));
234
- const html = await renderWithAssetTags(renderFn, pageObj, assetTags);
251
+ const html = renderMode === "client" ? renderClientOnlyPage(pageObj, assetTags, renderFn) : await renderWithAssetTags(renderFn, pageObj, assetTags);
235
252
  if (!hasDeferred) return renderedResponse(c, html, "text/html; charset=utf-8", assetTags);
236
253
  return streamDeferredResponse(html, deferredMap, c, "text/html; charset=utf-8", (group, data) => `\n<script>window.__resolveDeferred?window.__resolveDeferred(${safeJsonStringify(group)},${safeJsonStringify(data)}):(window.__deferredQueue??=[]).push([${safeJsonStringify(group)},${safeJsonStringify(data)}])<\/script>`, (group, error) => `\n<script>window.__rejectDeferred?window.__rejectDeferred(${safeJsonStringify(group)},${safeJsonStringify(error)}):(window.__deferredQueue??=[]).push([${safeJsonStringify(group)},0,${safeJsonStringify(error)}])<\/script>`, assetTags);
237
254
  }
238
255
  /** Handle POST/PUT/DELETE page request — run mutation, then re-run GET or redirect */
239
- async function handlePageMutation(mutationHandler, getHandler, headFn, c, componentId, renderFn, getAssetTags, configHead, island) {
256
+ async function handlePageMutation(mutationHandler, getHandler, headFn, c, componentId, renderFn, getAssetTags, configHead, options) {
257
+ const renderMode = options?.renderMode ?? "server";
240
258
  const shared = c.get("shared") ?? {};
241
259
  const middlewareHead = c.get("headDefaults");
242
260
  function buildMutationPageObj(props, errors) {
@@ -256,11 +274,11 @@ async function handlePageMutation(mutationHandler, getHandler, headFn, c, compon
256
274
  result = mutationHandler ? await mutationHandler(c) : void 0;
257
275
  } catch (e) {
258
276
  if (e instanceof ValidationError) {
259
- if (island) return Response.json({ errors: e.errors }, { status: 422 });
277
+ if (renderMode === "island") return Response.json({ errors: e.errors }, { status: 422 });
260
278
  const pageObj = buildMutationPageObj(stripDeferred(getHandler ? await extractProps(await getHandler(c)) : {}), e.errors);
261
279
  if (isPagesRequest(c)) return pageJsonResponse(c, pageObj);
262
280
  const assetTags = prepareAssetTags(await getAssetTags(c.req.raw, c.env, componentId));
263
- return renderedResponse(c, await renderWithAssetTags(renderFn, pageObj, assetTags), "text/html; charset=utf-8", assetTags);
281
+ return renderedResponse(c, renderMode === "client" ? renderClientOnlyPage(pageObj, assetTags, renderFn) : await renderWithAssetTags(renderFn, pageObj, assetTags), "text/html; charset=utf-8", assetTags);
264
282
  }
265
283
  throw e;
266
284
  }
@@ -269,19 +287,19 @@ async function handlePageMutation(mutationHandler, getHandler, headFn, c, compon
269
287
  if (status >= 300 && status < 400) return result;
270
288
  if (status === 400) {
271
289
  const errors = flattenValidationErrors(await result.json());
272
- if (island) return Response.json({ errors }, { status: 422 });
290
+ if (renderMode === "island") return Response.json({ errors }, { status: 422 });
273
291
  const pageObj = buildMutationPageObj(stripDeferred(getHandler ? await extractProps(await getHandler(c)) : {}), errors);
274
292
  if (isPagesRequest(c)) return pageJsonResponse(c, pageObj);
275
293
  const assetTags = prepareAssetTags(await getAssetTags(c.req.raw, c.env, componentId));
276
- return renderedResponse(c, await renderWithAssetTags(renderFn, pageObj, assetTags), "text/html; charset=utf-8", assetTags);
294
+ return renderedResponse(c, renderMode === "client" ? renderClientOnlyPage(pageObj, assetTags, renderFn) : await renderWithAssetTags(renderFn, pageObj, assetTags), "text/html; charset=utf-8", assetTags);
277
295
  }
278
296
  if (status !== 204) return result;
279
297
  }
280
- if (island) return Response.json({ success: true });
298
+ if (renderMode === "island") return Response.json({ success: true });
281
299
  const pageObj = buildMutationPageObj(stripDeferred(getHandler ? await extractProps(await getHandler(c)) : {}), null);
282
300
  if (isPagesRequest(c)) return pageJsonResponse(c, pageObj);
283
301
  const assetTags = prepareAssetTags(await getAssetTags(c.req.raw, c.env, componentId));
284
- return renderedResponse(c, await renderWithAssetTags(renderFn, pageObj, assetTags), "text/html; charset=utf-8", assetTags);
302
+ return renderedResponse(c, renderMode === "client" ? renderClientOnlyPage(pageObj, assetTags, renderFn) : await renderWithAssetTags(renderFn, pageObj, assetTags), "text/html; charset=utf-8", assetTags);
285
303
  }
286
304
  //#endregion
287
305
  export { ValidationError, flattenValidationErrors, handlePageGet, handlePageMutation, safeJsonStringify };
@@ -1,6 +1,6 @@
1
1
  import { a as join, s as relative } from "./pathe.M-eThtNZ-BrPhGF_K.mjs";
2
2
  import { n as readProjectPaths } from "./project-paths-CCMrHYQm.mjs";
3
- import { n as globSync } from "./dist-DR9sIMbM.mjs";
3
+ import { n as globSync } from "./dist-5cGIJHQQ.mjs";
4
4
  import { existsSync, readFileSync } from "node:fs";
5
5
  import { parseSync } from "vite";
6
6
  import { parse } from "es-module-lexer/js";
@@ -3,22 +3,21 @@ import { n as cliTitle } from "./output-DeiS4oEX.mjs";
3
3
  import { i as resolveProjectPaths } from "./project-paths-CCMrHYQm.mjs";
4
4
  import { n as loadVoidAuthConfig, t as findVoidAuthConfig } from "./config-hhMYPVRT.mjs";
5
5
  import { c as R, g as ge, u as Se, y as ye } from "./dist-abzUneor.mjs";
6
- import { c as getDatabaseDialect, f as readConfig } from "./config-BVEC0lti.mjs";
7
- import { r as scanRoutes } from "./scan-BNC_1OsY.mjs";
8
- import { i as inferProjectBindings, n as FRAMEWORK_SCAN_DIRS, r as detectFramework } from "./plugin-inference-BUBhHt_1.mjs";
9
- import { i as generateDbDts, n as generateQueueTypes, t as generateRouteTypes } from "./route-types-jxRfWuCb.mjs";
10
- import { n as ensureProjectTsconfig } from "./project-tsconfig-HAGjfY6w.mjs";
6
+ import { n as ensureProjectTsconfig, r as writeFileIfChanged } from "./project-tsconfig-BTNuNoJ0.mjs";
7
+ import { c as getDatabaseDialect, f as readConfig } from "./config-8dLIngKW.mjs";
8
+ import { r as scanRoutes } from "./scan-B2H1Vo2C.mjs";
9
+ import { i as inferProjectBindings, n as FRAMEWORK_SCAN_DIRS, r as detectFramework } from "./plugin-inference--7geW5Z2.mjs";
10
+ import { i as generateDbDts, n as generateQueueTypes, t as generateRouteTypes } from "./route-types-D03ryMXz.mjs";
11
11
  import { t as discoverSchema } from "./discover-C8N1I4tK.mjs";
12
- import { r as generateEnvTypes, t as findEnvFile } from "./env-types-D6qI1ThV.mjs";
13
- import { n as generateVoidAuthDrizzleSchema, t as generateVoidAuthDatabaseModule } from "./drizzle-2fs1qTgy.mjs";
14
- import { existsSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
12
+ import { r as generateEnvTypes, t as findEnvFile } from "./env-types-CaJaIRXU.mjs";
13
+ import { n as generateVoidAuthDrizzleSchema, t as generateVoidAuthDatabaseModule } from "./drizzle-DYstYz0j.mjs";
14
+ import { existsSync, mkdirSync, rmSync } from "node:fs";
15
15
  import { fileURLToPath } from "node:url";
16
16
  import { loadEnv } from "vite";
17
17
  //#region src/codegen/prepare.ts
18
18
  function writeGeneratedFile(outDir, fileName, content, written) {
19
19
  mkdirSync(outDir, { recursive: true });
20
- writeFileSync(join(outDir, fileName), content);
21
- written.push(join(".void", fileName));
20
+ if (writeFileIfChanged(join(outDir, fileName), content)) written.push(join(".void", fileName));
22
21
  }
23
22
  function removeGeneratedFile(outDir, fileName, removed) {
24
23
  const filePath = join(outDir, fileName);
@@ -62,8 +61,7 @@ async function prepareProject(root) {
62
61
  const schema = discoverSchema(root, paths);
63
62
  const hasDbRuntime = schema != null || authEnabled;
64
63
  if (hasDbRuntime) {
65
- generateDbDts(outDir, schema, dialect);
66
- written.push(join(".void", "db.d.ts"));
64
+ if (generateDbDts(outDir, schema, dialect)) written.push(join(".void", "db.d.ts"));
67
65
  } else removeGeneratedFile(outDir, "db.d.ts", removed);
68
66
  if (authEnabled) {
69
67
  const authRuntime = {
@@ -75,20 +73,17 @@ async function prepareProject(root) {
75
73
  const schemaPath = join(outDir, "better-auth-schema.ts");
76
74
  const databasePath = join(outDir, "better-auth-db.ts");
77
75
  const drizzleAdapterPath = fileURLToPath(import.meta.resolve("better-auth/adapters/drizzle"));
78
- writeFileSync(schemaPath, generateVoidAuthDrizzleSchema(authRuntime, env));
79
- writeFileSync(databasePath, generateVoidAuthDatabaseModule({
76
+ if (writeFileIfChanged(schemaPath, generateVoidAuthDrizzleSchema(authRuntime, env))) written.push(join(".void", "better-auth-schema.ts"));
77
+ if (writeFileIfChanged(databasePath, generateVoidAuthDatabaseModule({
80
78
  dialect,
81
79
  schemaImportPath: schemaPath,
82
80
  drizzleAdapterPath
83
- }));
84
- written.push(join(".void", "better-auth-schema.ts"));
85
- written.push(join(".void", "better-auth-db.ts"));
81
+ }))) written.push(join(".void", "better-auth-db.ts"));
86
82
  } else {
87
83
  removeGeneratedFile(outDir, "better-auth-schema.ts", removed);
88
84
  removeGeneratedFile(outDir, "better-auth-db.ts", removed);
89
85
  }
90
- ensureProjectTsconfig(root, hasRouteTypes, hasDbRuntime, schema != null, { paths });
91
- written.push(join(".void", "tsconfig.json"));
86
+ if (ensureProjectTsconfig(root, hasRouteTypes, hasDbRuntime, schema != null, { paths })) written.push(join(".void", "tsconfig.json"));
92
87
  return {
93
88
  written,
94
89
  removed
@@ -1,6 +1,6 @@
1
1
  import { a as join, c as resolve } from "./pathe.M-eThtNZ-BrPhGF_K.mjs";
2
2
  import { n as readProjectPaths } from "./project-paths-CCMrHYQm.mjs";
3
- import { s as hasSsrEntry } from "./plugin-inference-BUBhHt_1.mjs";
3
+ import { s as hasSsrEntry } from "./plugin-inference--7geW5Z2.mjs";
4
4
  import { i as readPackageJson, n as hasPackageDependency, t as getPackageDependencies } from "./package-json-B2TD0JLu.mjs";
5
5
  import { existsSync } from "node:fs";
6
6
  //#region src/cli/preset.ts
@@ -1,6 +1,20 @@
1
- import { a as join, s as relative } from "./pathe.M-eThtNZ-BrPhGF_K.mjs";
1
+ import { a as join, n as dirname, s as relative } from "./pathe.M-eThtNZ-BrPhGF_K.mjs";
2
2
  import { n as readProjectPaths } from "./project-paths-CCMrHYQm.mjs";
3
- import { existsSync, mkdirSync, writeFileSync } from "node:fs";
3
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
4
+ //#region src/codegen/write-if-changed.ts
5
+ function writeFileIfChanged(path, content) {
6
+ let existing = null;
7
+ try {
8
+ existing = readFileSync(path, "utf8");
9
+ } catch (err) {
10
+ if (err.code !== "ENOENT") throw err;
11
+ }
12
+ if (existing === content) return false;
13
+ mkdirSync(dirname(path), { recursive: true });
14
+ writeFileSync(path, content);
15
+ return true;
16
+ }
17
+ //#endregion
4
18
  //#region src/codegen/project-tsconfig.ts
5
19
  /**
6
20
  * Build the generated .void/tsconfig.json contents. Lists the generated
@@ -62,7 +76,7 @@ function ensureProjectTsconfig(root, hasRouteTypes, hasDb, hasSchema, options =
62
76
  const outDir = join(root, ".void");
63
77
  mkdirSync(outDir, { recursive: true });
64
78
  const tsconfig = createProjectTsconfig(root, hasRouteTypes, hasDb, hasSchema, options);
65
- writeFileSync(join(outDir, "tsconfig.json"), JSON.stringify(tsconfig, null, 2) + "\n");
79
+ return writeFileIfChanged(join(outDir, "tsconfig.json"), JSON.stringify(tsconfig, null, 2) + "\n");
66
80
  }
67
81
  //#endregion
68
- export { ensureProjectTsconfig as n, createProjectTsconfig as t };
82
+ export { ensureProjectTsconfig as n, writeFileIfChanged as r, createProjectTsconfig as t };
@@ -1,6 +1,6 @@
1
1
  import { n as HeadDescriptor, t as HeadConfig } from "./head-BsSTGnIe.mjs";
2
- import { n as CloudContext, t as CloudBindings } from "./handler-xflsMwWM.mjs";
3
- import { t as DevCssAsset } from "./types-Dm9kep2X.mjs";
2
+ import { n as CloudBindings, r as CloudContext } from "./handler-hm9KldPP.mjs";
3
+ import { a as PageRenderMode, t as DevCssAsset } from "./types-DEWCqHtl.mjs";
4
4
 
5
5
  //#region src/pages/protocol.d.ts
6
6
  /** Escape characters that are unsafe inside inline <script> tags to prevent XSS. */
@@ -19,6 +19,9 @@ type PageObject = {
19
19
  type PageRenderResult = string | ReadableStream<Uint8Array>;
20
20
  type PageHandler = ((c: CloudContext) => unknown | Promise<unknown>) | undefined;
21
21
  type PageHeadHandler = ((c: CloudContext, props: Record<string, unknown>) => HeadDescriptor | undefined) | undefined;
22
+ type PageRenderOptions = {
23
+ renderMode?: PageRenderMode;
24
+ };
22
25
  type AssetTags = {
23
26
  css: string;
24
27
  preloads: string;
@@ -31,8 +34,8 @@ type GetAssetTags = (req: Request, env: CloudBindings, componentId: string) => P
31
34
  /** Flatten withValidator's { issues: [{ slot, issues: [{ message, path }] }] } into { field: message } */
32
35
  declare function flattenValidationErrors(body: unknown): Record<string, string>;
33
36
  /** Handle GET page request — run handler, return page object or SSR HTML */
34
- declare function handlePageGet(handler: PageHandler, headFn: PageHeadHandler, c: CloudContext, componentId: string, renderFn: RenderPage, getAssetTags: GetAssetTags, configHead?: HeadConfig, island?: boolean): Promise<Response>;
37
+ declare function handlePageGet(handler: PageHandler, headFn: PageHeadHandler, c: CloudContext, componentId: string, renderFn: RenderPage, getAssetTags: GetAssetTags, configHead?: HeadConfig, options?: PageRenderOptions): Promise<Response>;
35
38
  /** Handle POST/PUT/DELETE page request — run mutation, then re-run GET or redirect */
36
- declare function handlePageMutation(mutationHandler: PageHandler, getHandler: PageHandler, headFn: PageHeadHandler, c: CloudContext, componentId: string, renderFn: RenderPage, getAssetTags: GetAssetTags, configHead?: HeadConfig, island?: boolean): Promise<Response>;
39
+ declare function handlePageMutation(mutationHandler: PageHandler, getHandler: PageHandler, headFn: PageHeadHandler, c: CloudContext, componentId: string, renderFn: RenderPage, getAssetTags: GetAssetTags, configHead?: HeadConfig, options?: PageRenderOptions): Promise<Response>;
37
40
  //#endregion
38
41
  export { handlePageMutation as a, handlePageGet as i, PageRenderResult as n, safeJsonStringify as o, flattenValidationErrors as r, PageObject as t };
@@ -1,5 +1,6 @@
1
1
  import { a as join, s as relative } from "./pathe.M-eThtNZ-BrPhGF_K.mjs";
2
- import { mkdirSync, writeFileSync } from "node:fs";
2
+ import { r as writeFileIfChanged } from "./project-tsconfig-BTNuNoJ0.mjs";
3
+ import { mkdirSync } from "node:fs";
3
4
  //#region src/codegen/db-types.ts
4
5
  const DRIZZLE_OPERATORS = "sql, eq, ne, gt, gte, lt, lte, and, or, not, desc, asc, like, ilike, notLike, inArray, notInArray, isNull, isNotNull, between, notBetween, exists, notExists, count, sum, avg, min, max";
5
6
  /**
@@ -53,7 +54,7 @@ function generateDbDts(outDir, schema, dialect) {
53
54
  "export type { DrizzleD1Database } from \"void/_db\";",
54
55
  ""
55
56
  ];
56
- writeFileSync(join(outDir, "db.d.ts"), lines.join("\n"));
57
+ return writeFileIfChanged(join(outDir, "db.d.ts"), lines.join("\n"));
57
58
  }
58
59
  //#endregion
59
60
  //#region src/codegen/queue-types.ts
@@ -1,5 +1,5 @@
1
1
  import { t as applyPgAuthMigrations } from "../auth-migrations-CuQkjjWE.mjs";
2
- import { t as createVoidAuthRuntime } from "../better-auth-shared-ChVbrq52.mjs";
2
+ import { t as createVoidAuthRuntime } from "../better-auth-shared-QAfk8CAS.mjs";
3
3
  import { t as disablePgPassFallback } from "../pg-CMZ_5wsC.mjs";
4
4
  //#region src/runtime/better-auth-pg.ts
5
5
  function resolveConnectionString(env) {
@@ -1,5 +1,5 @@
1
1
  import { n as applySqliteAuthMigrations } from "../auth-migrations-CuQkjjWE.mjs";
2
- import { t as createVoidAuthRuntime } from "../better-auth-shared-ChVbrq52.mjs";
2
+ import { t as createVoidAuthRuntime } from "../better-auth-shared-QAfk8CAS.mjs";
3
3
  //#region src/runtime/better-auth.ts
4
4
  async function resolveDatabase(env) {
5
5
  if (!env.DB) throw new Error("auth: Better Auth requires the \"DB\" D1 binding for sqlite apps.");
@@ -1,3 +1,3 @@
1
1
  /// <reference types="@cloudflare/workers-types" />
2
- import { C as HandlerInput, S as ValidationError, _ as defineScheduled, a as QueueBatch, b as InferProps, c as RenderAssetTags, d as VoidAssetRewriteError, f as defineHandler, g as defineRender, h as defineQueue, i as CloudEnv, l as TypedHandler, m as defineMiddleware, n as CloudContext, o as QueueMessage, p as defineHead, r as CloudContextVariables, s as QueueRetryOptions, t as CloudBindings, u as TypedQueueHandler, v as Deferred, w as ValidatorSlots, x as defer } from "../handler-xflsMwWM.mjs";
3
- export { CloudBindings, CloudContext, CloudContextVariables, CloudEnv, Deferred, HandlerInput, InferProps, QueueBatch, QueueMessage, QueueRetryOptions, RenderAssetTags, TypedHandler, TypedQueueHandler, ValidationError, ValidatorSlots, VoidAssetRewriteError, defer, defineHandler, defineHead, defineMiddleware, defineQueue, defineRender, defineScheduled };
2
+ import { C as defer, E as ValidatorSlots, S as InferProps, T as HandlerInput, _ as defineQueue, a as CloudEnv, b as Deferred, c as QueueRetryOptions, d as TypedQueueHandler, f as VoidAssetRewriteError, g as defineMiddleware, h as defineHead, i as CloudContextVariables, l as RenderAssetTags, m as defineHandler, n as CloudBindings, o as QueueBatch, p as basicAuth, r as CloudContext, s as QueueMessage, t as BasicAuthOptions, u as TypedHandler, v as defineRender, w as ValidationError, y as defineScheduled } from "../handler-hm9KldPP.mjs";
3
+ export { BasicAuthOptions, CloudBindings, CloudContext, CloudContextVariables, CloudEnv, Deferred, HandlerInput, InferProps, QueueBatch, QueueMessage, QueueRetryOptions, RenderAssetTags, TypedHandler, TypedQueueHandler, ValidationError, ValidatorSlots, VoidAssetRewriteError, basicAuth, defer, defineHandler, defineHead, defineMiddleware, defineQueue, defineRender, defineScheduled };
@@ -53,6 +53,72 @@ function defineHandler(...args) {
53
53
  function defineMiddleware(handler) {
54
54
  return handler;
55
55
  }
56
+ const basicAuthEncoder = new TextEncoder();
57
+ const basicAuthDecoder = new TextDecoder("utf-8", { fatal: true });
58
+ function parseBasicAuthHeader(authorization) {
59
+ if (!authorization?.toLowerCase().startsWith("basic ")) return null;
60
+ try {
61
+ const encoded = authorization.slice(6).trim();
62
+ const binary = atob(encoded);
63
+ const bytes = Uint8Array.from(binary, (char) => char.charCodeAt(0));
64
+ const decoded = basicAuthDecoder.decode(bytes);
65
+ const separator = decoded.indexOf(":");
66
+ if (separator === -1) return null;
67
+ return {
68
+ username: decoded.slice(0, separator),
69
+ password: decoded.slice(separator + 1)
70
+ };
71
+ } catch {
72
+ return null;
73
+ }
74
+ }
75
+ function timingSafeStringEqual(actual, expected) {
76
+ const actualBytes = basicAuthEncoder.encode(actual);
77
+ const expectedBytes = basicAuthEncoder.encode(expected);
78
+ let difference = actualBytes.length ^ expectedBytes.length;
79
+ for (let i = 0; i < expectedBytes.length; i++) difference |= (actualBytes[i] ?? 0) ^ expectedBytes[i];
80
+ return difference === 0;
81
+ }
82
+ function isVoidInternalPath(pathname) {
83
+ return pathname === "/__void" || pathname.startsWith("/__void/");
84
+ }
85
+ function basicAuthChallenge(realm, message) {
86
+ const escapedRealm = realm.replace(/["\\]/g, "\\$&");
87
+ return new Response(message, {
88
+ status: 401,
89
+ headers: {
90
+ "Cache-Control": "no-store",
91
+ "WWW-Authenticate": `Basic realm="${escapedRealm}", charset="UTF-8"`
92
+ }
93
+ });
94
+ }
95
+ function resolveBasicAuthOption(value, fallback) {
96
+ if (value === void 0) return fallback;
97
+ return typeof value === "function" ? value() : value;
98
+ }
99
+ /**
100
+ * Create Basic authentication middleware for temporary site gates and
101
+ * pre-launch protection.
102
+ *
103
+ * Void internal endpoints under `/__void` are always excluded so deploy-time
104
+ * migrations, prerendering, cron/queue dispatch, and remote binding helpers
105
+ * continue to reach Void's own internal-token checks.
106
+ */
107
+ function basicAuth(options) {
108
+ return defineMiddleware(async (c, next) => {
109
+ if (isVoidInternalPath(c.req.path)) {
110
+ await next();
111
+ return;
112
+ }
113
+ const username = resolveBasicAuthOption(options.username, "");
114
+ const password = resolveBasicAuthOption(options.password, "");
115
+ const credentials = parseBasicAuthHeader(c.req.raw.headers.get("Authorization"));
116
+ const usernameMatches = credentials && timingSafeStringEqual(credentials.username, username);
117
+ const passwordMatches = credentials && timingSafeStringEqual(credentials.password, password);
118
+ if (!usernameMatches || !passwordMatches) return basicAuthChallenge(resolveBasicAuthOption(options.realm, "Restricted"), resolveBasicAuthOption(options.message, "Authentication required"));
119
+ await next();
120
+ });
121
+ }
56
122
  /**
57
123
  * Identity function that provides type inference for scheduled jobs.
58
124
  * At runtime it simply returns the function passed to it.
@@ -82,4 +148,4 @@ function defineQueue(handler) {
82
148
  return handler;
83
149
  }
84
150
  //#endregion
85
- export { ValidationError, VoidAssetRewriteError, defer, defineHandler, defineHead, defineMiddleware, defineQueue, defineRender, defineScheduled };
151
+ export { ValidationError, VoidAssetRewriteError, basicAuth, defer, defineHandler, defineHead, defineMiddleware, defineQueue, defineRender, defineScheduled };
@@ -1,6 +1,6 @@
1
1
  /// <reference types="@cloudflare/workers-types" />
2
2
  import { r as AuthUser } from "../auth-CDeb2XAl.mjs";
3
- import { i as CloudEnv, n as CloudContext } from "../handler-xflsMwWM.mjs";
3
+ import { a as CloudEnv, r as CloudContext } from "../handler-hm9KldPP.mjs";
4
4
 
5
5
  //#region src/runtime/live.d.ts
6
6
  type MaybePromise<T> = T | Promise<T>;
@@ -1,2 +1,2 @@
1
- import { C as HandlerInput, T as runValidation, w as ValidatorSlots } from "../handler-xflsMwWM.mjs";
1
+ import { D as runValidation, E as ValidatorSlots, T as HandlerInput } from "../handler-hm9KldPP.mjs";
2
2
  export { HandlerInput, ValidatorSlots, runValidation };
@@ -1,6 +1,6 @@
1
1
  import { r as AuthUser } from "../auth-CDeb2XAl.mjs";
2
2
  import { t as StandardSchemaV1 } from "../standard-schema-Dnsh2vnl.mjs";
3
- import { i as CloudEnv } from "../handler-xflsMwWM.mjs";
3
+ import { a as CloudEnv } from "../handler-hm9KldPP.mjs";
4
4
  import { WebSocketRouteMap } from "void/routes";
5
5
 
6
6
  //#region src/runtime/ws.d.ts
@@ -1,8 +1,8 @@
1
1
  import { a as join, i as isAbsolute, t as basename } from "./pathe.M-eThtNZ-BrPhGF_K.mjs";
2
2
  import { n as readProjectPaths } from "./project-paths-CCMrHYQm.mjs";
3
- import { n as globSync, t as glob } from "./dist-DR9sIMbM.mjs";
4
- import { d as isCallExpression, f as isIdentifier, h as isObjectExpression, p as isLiteral } from "./plugin-inference-BUBhHt_1.mjs";
5
- import { o as parseRouteFilename, s as parseWebSocketFilename, t as scanPages } from "./scan-2YmJkYAf.mjs";
3
+ import { n as globSync, t as glob } from "./dist-5cGIJHQQ.mjs";
4
+ import { d as isCallExpression, f as isIdentifier, h as isObjectExpression, p as isLiteral } from "./plugin-inference--7geW5Z2.mjs";
5
+ import { o as parseRouteFilename, s as parseWebSocketFilename, t as scanPages } from "./scan-VCAM1oh3.mjs";
6
6
  import { readFileSync } from "node:fs";
7
7
  import { parseSync } from "vite";
8
8
  //#region src/crons/scan.ts