void 0.7.5 → 0.7.7

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 (66) hide show
  1. package/dist/{auth-DrfOTMmr.d.mts → auth-DmuALf16.d.mts} +4 -4
  2. package/dist/{better-auth-shared-CZsIpjey.d.mts → better-auth-shared-HXlHRw02.d.mts} +15 -15
  3. package/dist/cli/cli.mjs +14 -14
  4. package/dist/{config-BIa9HwVX.mjs → config-DqkeX_Fa.mjs} +5 -5
  5. package/dist/{db-RqxhOT2E.mjs → db-BnKZW1J7.mjs} +26 -22
  6. package/dist/{deploy-CRIz77mw.mjs → deploy-D3t53kng.mjs} +46 -16
  7. package/dist/{domain-CDQhvYNZ.mjs → domain-ClDdX9I1.mjs} +24 -1
  8. package/dist/{dotenv-DwO4ti0Z.mjs → dotenv-zdFCCgFU.mjs} +26 -26
  9. package/dist/{env-CnrQY2b6.mjs → env-CU97_4YK.mjs} +1 -1
  10. package/dist/{env-helpers-CbeM_7-k.d.mts → env-helpers-Dw95CU8e.d.mts} +4 -4
  11. package/dist/{env-validation-DJKjR_8q.mjs → env-validation-Bc_aiBUm.mjs} +1 -1
  12. package/dist/{fetch-error-DflegrF3.d.mts → fetch-error-DZ868Xq4.d.mts} +4 -4
  13. package/dist/{gen-C0EY2k27.mjs → gen-CpeKIqlM.mjs} +2 -2
  14. package/dist/{handler-dKQWyF-G.d.mts → handler-DJTuxB10.d.mts} +24 -27
  15. package/dist/{head-CZGAunBV.d.mts → head-C7QW7UY1.d.mts} +5 -6
  16. package/dist/{headers-YVkHjOyq.mjs → headers-C7Yf6_CN.mjs} +1 -1
  17. package/dist/index.d.mts +3 -3
  18. package/dist/index.mjs +501 -63
  19. package/dist/{init-FMZ29UZW.mjs → init-CTtDfVVo.mjs} +4 -4
  20. package/dist/{node-DFqMcZR1.mjs → node-DHVCtkgt.mjs} +1 -1
  21. package/dist/pages/client.d.mts +35 -41
  22. package/dist/pages/head-client.d.mts +1 -1
  23. package/dist/pages/head.d.mts +1 -1
  24. package/dist/pages/head.mjs +4 -4
  25. package/dist/pages/index.d.mts +6 -6
  26. package/dist/pages/index.mjs +6 -6
  27. package/dist/pages/islands-plugin.d.mts +4 -13
  28. package/dist/pages/islands-plugin.mjs +2 -64
  29. package/dist/pages/prefetch.d.mts +5 -5
  30. package/dist/pages/protocol.d.mts +2 -2
  31. package/dist/pages/protocol.mjs +98 -14
  32. package/dist/plugin-inference-CXUuq0aC.mjs +577 -0
  33. package/dist/{prepare-PqAbhLte.mjs → prepare-CKzO06-Z.mjs} +4 -4
  34. package/dist/{preset-jKn1hQwP.mjs → preset-BhnZpb7t.mjs} +1 -1
  35. package/dist/{protocol-DxGzKEz2.d.mts → protocol-D7r_deVZ.d.mts} +7 -4
  36. package/dist/{route-types-DReF1gUY.mjs → route-types-Cnqj_8a7.mjs} +2 -2
  37. package/dist/runtime/ai.d.mts +33 -40
  38. package/dist/runtime/auth.d.mts +1 -1
  39. package/dist/runtime/better-auth-pg.d.mts +1 -1
  40. package/dist/runtime/better-auth.d.mts +1 -1
  41. package/dist/runtime/client.d.mts +2 -2
  42. package/dist/runtime/env-helpers.d.mts +1 -1
  43. package/dist/runtime/env-helpers.mjs +3 -3
  44. package/dist/runtime/env-public-client.d.mts +3 -3
  45. package/dist/runtime/env-public.d.mts +7 -7
  46. package/dist/runtime/fetch-stream.d.mts +1 -1
  47. package/dist/runtime/fetch.d.mts +1 -1
  48. package/dist/runtime/handler.d.mts +1 -1
  49. package/dist/runtime/handler.mjs +3 -3
  50. package/dist/runtime/isr.d.mts +2 -2
  51. package/dist/runtime/kv.d.mts +12 -12
  52. package/dist/runtime/live-server.d.mts +4 -4
  53. package/dist/runtime/live.d.mts +2 -2
  54. package/dist/runtime/migration-handler.d.mts +6 -6
  55. package/dist/runtime/seed.d.mts +4 -4
  56. package/dist/runtime/validator.d.mts +1 -1
  57. package/dist/runtime/ws-server.d.mts +8 -8
  58. package/dist/runtime/ws.d.mts +21 -21
  59. package/dist/{scan-QtRTdh94.mjs → scan-B8iEm8xn.mjs} +6 -6
  60. package/dist/{scan-Ba4hFwlH.mjs → scan-CWfLxtOe.mjs} +8 -8
  61. package/dist/{standard-schema-BfGDWXff.d.mts → standard-schema-D2qvCEYV.d.mts} +14 -14
  62. package/dist/sveltekit.d.mts +3 -5
  63. package/dist/types-DG_Ynnyd.d.mts +42 -0
  64. package/package.json +3 -3
  65. package/dist/plugin-inference-CCtRkt9O.mjs +0 -2476
  66. package/dist/types-AdKzPp2C.d.mts +0 -57
@@ -0,0 +1,577 @@
1
+ import { a as join } from "./pathe.M-eThtNZ-D-kmWkCS.mjs";
2
+ import { n as globSync } from "./dist-DUyXJLkq.mjs";
3
+ import { existsSync, readFileSync } from "node:fs";
4
+ import { parseSync } from "vite";
5
+ import { parse } from "es-module-lexer/js";
6
+ //#region ../../node_modules/.pnpm/estree-walker@3.0.3/node_modules/estree-walker/src/walker.js
7
+ /**
8
+ * @typedef { import('estree').Node} Node
9
+ * @typedef {{
10
+ * skip: () => void;
11
+ * remove: () => void;
12
+ * replace: (node: Node) => void;
13
+ * }} WalkerContext
14
+ */
15
+ var WalkerBase = class {
16
+ constructor() {
17
+ /** @type {boolean} */
18
+ this.should_skip = false;
19
+ /** @type {boolean} */
20
+ this.should_remove = false;
21
+ /** @type {Node | null} */
22
+ this.replacement = null;
23
+ /** @type {WalkerContext} */
24
+ this.context = {
25
+ skip: () => this.should_skip = true,
26
+ remove: () => this.should_remove = true,
27
+ replace: (node) => this.replacement = node
28
+ };
29
+ }
30
+ /**
31
+ * @template {Node} Parent
32
+ * @param {Parent | null | undefined} parent
33
+ * @param {keyof Parent | null | undefined} prop
34
+ * @param {number | null | undefined} index
35
+ * @param {Node} node
36
+ */
37
+ replace(parent, prop, index, node) {
38
+ if (parent && prop) if (index != null)
39
+ /** @type {Array<Node>} */ parent[prop][index] = node;
40
+ else
41
+ /** @type {Node} */ parent[prop] = node;
42
+ }
43
+ /**
44
+ * @template {Node} Parent
45
+ * @param {Parent | null | undefined} parent
46
+ * @param {keyof Parent | null | undefined} prop
47
+ * @param {number | null | undefined} index
48
+ */
49
+ remove(parent, prop, index) {
50
+ if (parent && prop) if (index !== null && index !== void 0)
51
+ /** @type {Array<Node>} */ parent[prop].splice(index, 1);
52
+ else delete parent[prop];
53
+ }
54
+ };
55
+ //#endregion
56
+ //#region ../../node_modules/.pnpm/estree-walker@3.0.3/node_modules/estree-walker/src/sync.js
57
+ /**
58
+ * @typedef { import('estree').Node} Node
59
+ * @typedef { import('./walker.js').WalkerContext} WalkerContext
60
+ * @typedef {(
61
+ * this: WalkerContext,
62
+ * node: Node,
63
+ * parent: Node | null,
64
+ * key: string | number | symbol | null | undefined,
65
+ * index: number | null | undefined
66
+ * ) => void} SyncHandler
67
+ */
68
+ var SyncWalker = class extends WalkerBase {
69
+ /**
70
+ *
71
+ * @param {SyncHandler} [enter]
72
+ * @param {SyncHandler} [leave]
73
+ */
74
+ constructor(enter, leave) {
75
+ super();
76
+ /** @type {boolean} */
77
+ this.should_skip = false;
78
+ /** @type {boolean} */
79
+ this.should_remove = false;
80
+ /** @type {Node | null} */
81
+ this.replacement = null;
82
+ /** @type {WalkerContext} */
83
+ this.context = {
84
+ skip: () => this.should_skip = true,
85
+ remove: () => this.should_remove = true,
86
+ replace: (node) => this.replacement = node
87
+ };
88
+ /** @type {SyncHandler | undefined} */
89
+ this.enter = enter;
90
+ /** @type {SyncHandler | undefined} */
91
+ this.leave = leave;
92
+ }
93
+ /**
94
+ * @template {Node} Parent
95
+ * @param {Node} node
96
+ * @param {Parent | null} parent
97
+ * @param {keyof Parent} [prop]
98
+ * @param {number | null} [index]
99
+ * @returns {Node | null}
100
+ */
101
+ visit(node, parent, prop, index) {
102
+ if (node) {
103
+ if (this.enter) {
104
+ const _should_skip = this.should_skip;
105
+ const _should_remove = this.should_remove;
106
+ const _replacement = this.replacement;
107
+ this.should_skip = false;
108
+ this.should_remove = false;
109
+ this.replacement = null;
110
+ this.enter.call(this.context, node, parent, prop, index);
111
+ if (this.replacement) {
112
+ node = this.replacement;
113
+ this.replace(parent, prop, index, node);
114
+ }
115
+ if (this.should_remove) this.remove(parent, prop, index);
116
+ const skipped = this.should_skip;
117
+ const removed = this.should_remove;
118
+ this.should_skip = _should_skip;
119
+ this.should_remove = _should_remove;
120
+ this.replacement = _replacement;
121
+ if (skipped) return node;
122
+ if (removed) return null;
123
+ }
124
+ /** @type {keyof Node} */
125
+ let key;
126
+ for (key in node) {
127
+ /** @type {unknown} */
128
+ const value = node[key];
129
+ if (value && typeof value === "object") {
130
+ if (Array.isArray(value)) {
131
+ const nodes = value;
132
+ for (let i = 0; i < nodes.length; i += 1) {
133
+ const item = nodes[i];
134
+ if (isNode(item)) {
135
+ if (!this.visit(item, node, key, i)) i--;
136
+ }
137
+ }
138
+ } else if (isNode(value)) this.visit(value, node, key, null);
139
+ }
140
+ }
141
+ if (this.leave) {
142
+ const _replacement = this.replacement;
143
+ const _should_remove = this.should_remove;
144
+ this.replacement = null;
145
+ this.should_remove = false;
146
+ this.leave.call(this.context, node, parent, prop, index);
147
+ if (this.replacement) {
148
+ node = this.replacement;
149
+ this.replace(parent, prop, index, node);
150
+ }
151
+ if (this.should_remove) this.remove(parent, prop, index);
152
+ const removed = this.should_remove;
153
+ this.replacement = _replacement;
154
+ this.should_remove = _should_remove;
155
+ if (removed) return null;
156
+ }
157
+ }
158
+ return node;
159
+ }
160
+ };
161
+ /**
162
+ * Ducktype a node.
163
+ *
164
+ * @param {unknown} value
165
+ * @returns {value is Node}
166
+ */
167
+ function isNode(value) {
168
+ return value !== null && typeof value === "object" && "type" in value && typeof value.type === "string";
169
+ }
170
+ //#endregion
171
+ //#region ../../node_modules/.pnpm/estree-walker@3.0.3/node_modules/estree-walker/src/index.js
172
+ /**
173
+ * @typedef {import('estree').Node} Node
174
+ * @typedef {import('./sync.js').SyncHandler} SyncHandler
175
+ * @typedef {import('./async.js').AsyncHandler} AsyncHandler
176
+ */
177
+ /**
178
+ * @param {Node} ast
179
+ * @param {{
180
+ * enter?: SyncHandler
181
+ * leave?: SyncHandler
182
+ * }} walker
183
+ * @returns {Node | null}
184
+ */
185
+ function walk(ast, { enter, leave }) {
186
+ return new SyncWalker(enter, leave).visit(ast, null);
187
+ }
188
+ //#endregion
189
+ //#region src/shared/ast.ts
190
+ function isIdentifier(node) {
191
+ return node?.type === "Identifier" && typeof node.name === "string";
192
+ }
193
+ function isLiteral(node) {
194
+ return node?.type === "Literal";
195
+ }
196
+ function isMemberExpression(node) {
197
+ return node?.type === "MemberExpression";
198
+ }
199
+ function isCallExpression(node) {
200
+ return node?.type === "CallExpression";
201
+ }
202
+ function isObjectExpression(node) {
203
+ return node?.type === "ObjectExpression";
204
+ }
205
+ //#endregion
206
+ //#region src/inference/walk.ts
207
+ const ENV_BINDING_RE = /\benv\s*\.\s*(DB|KV|STORAGE|QUEUE_\w+|AI|SANDBOX)\b/;
208
+ /**
209
+ * Infer which Cloudflare bindings a source file uses.
210
+ *
211
+ * Uses a tiered approach for performance:
212
+ * Tier 1: es-module-lexer to extract import sources (fast, asm.js, no init)
213
+ * Tier 2: Regex check for env.DB/KV/STORAGE patterns
214
+ * Tier 3: Full AST walk only when regex matches (to confirm member expressions)
215
+ */
216
+ function inferBindingsFromSource(code, filename) {
217
+ const result = {
218
+ needsD1: false,
219
+ needsKV: false,
220
+ needsR2: false,
221
+ needsAuth: false,
222
+ needsQueues: false,
223
+ needsAI: false,
224
+ needsSandbox: false,
225
+ needsLive: false
226
+ };
227
+ try {
228
+ const [imports] = parse(code);
229
+ for (const imp of imports) {
230
+ const source = imp.n;
231
+ if (!source) continue;
232
+ switch (source) {
233
+ case "void/db":
234
+ result.needsD1 = true;
235
+ break;
236
+ case "void/kv":
237
+ result.needsKV = true;
238
+ break;
239
+ case "void/storage":
240
+ result.needsR2 = true;
241
+ break;
242
+ case "void/auth":
243
+ result.needsAuth = true;
244
+ break;
245
+ case "void/queue":
246
+ result.needsQueues = true;
247
+ break;
248
+ case "void/ai":
249
+ result.needsAI = true;
250
+ break;
251
+ case "void/sandbox":
252
+ result.needsSandbox = true;
253
+ break;
254
+ case "void/live":
255
+ if (!isTypeOnlyImportStatement(code.slice(imp.ss, imp.se + 1))) result.needsLive = true;
256
+ break;
257
+ case "void/client": {
258
+ const stmt = code.slice(imp.ss, imp.se + 1);
259
+ if (/\bauth\b/.test(stmt)) result.needsAuth = true;
260
+ break;
261
+ }
262
+ }
263
+ }
264
+ } catch {
265
+ if (/\bfrom\s+["']void\/db["']/.test(code)) result.needsD1 = true;
266
+ if (/\bfrom\s+["']void\/kv["']/.test(code)) result.needsKV = true;
267
+ if (/\bfrom\s+["']void\/storage["']/.test(code)) result.needsR2 = true;
268
+ if (/\bfrom\s+["']void\/auth["']/.test(code)) result.needsAuth = true;
269
+ if (/\bfrom\s+["']void\/queue["']/.test(code)) result.needsQueues = true;
270
+ if (/\bfrom\s+["']void\/ai["']/.test(code)) result.needsAI = true;
271
+ if (/\bfrom\s+["']void\/sandbox["']/.test(code)) result.needsSandbox = true;
272
+ if (hasRuntimeImportFrom(code, "void/live")) result.needsLive = true;
273
+ if (/\bfrom\s+["']void\/client["']/.test(code) && /\bauth\b/.test(code)) result.needsAuth = true;
274
+ }
275
+ if (result.needsD1 && result.needsKV && result.needsR2 && result.needsAI && result.needsSandbox && result.needsLive) return result;
276
+ if (!ENV_BINDING_RE.test(code)) return result;
277
+ let parsed;
278
+ try {
279
+ parsed = parseSync(filename, code);
280
+ } catch {
281
+ return result;
282
+ }
283
+ const program = parsed.program;
284
+ walk(program, { enter(node) {
285
+ const current = node;
286
+ if (!isMemberExpression(current)) return;
287
+ if (current.computed) return;
288
+ const property = current.property;
289
+ if (!isIdentifier(property)) return;
290
+ const obj = current.object;
291
+ const isViaContextEnv = isMemberExpression(obj) && isIdentifier(obj.property) && obj.property.name === "env";
292
+ const isDirectEnv = isIdentifier(obj) && obj.name === "env";
293
+ if (!isViaContextEnv && !isDirectEnv) return;
294
+ switch (property.name) {
295
+ case "DB":
296
+ result.needsD1 = true;
297
+ break;
298
+ case "KV":
299
+ result.needsKV = true;
300
+ break;
301
+ case "STORAGE":
302
+ result.needsR2 = true;
303
+ break;
304
+ case "AI":
305
+ result.needsAI = true;
306
+ break;
307
+ case "SANDBOX":
308
+ result.needsSandbox = true;
309
+ break;
310
+ default:
311
+ if (property.name.startsWith("QUEUE_")) result.needsQueues = true;
312
+ break;
313
+ }
314
+ } });
315
+ return result;
316
+ }
317
+ function isTypeOnlyImportStatement(statement) {
318
+ if (/^\s*import\s+type\b/.test(statement)) return true;
319
+ const specifierStart = statement.indexOf("{");
320
+ const specifierEnd = statement.lastIndexOf("}");
321
+ if (specifierStart === -1 || specifierEnd === -1 || specifierEnd < specifierStart) return false;
322
+ const beforeSpecifiers = statement.slice(0, specifierStart);
323
+ if (!/^\s*import\s*$/.test(beforeSpecifiers)) return false;
324
+ const specifiers = statement.slice(specifierStart + 1, specifierEnd).split(",").map((specifier) => specifier.trim()).filter(Boolean);
325
+ return specifiers.length > 0 && specifiers.every((specifier) => specifier.startsWith("type "));
326
+ }
327
+ function hasRuntimeImportFrom(code, source) {
328
+ const escapedSource = source.replaceAll("/", "\\/");
329
+ const importRe = new RegExp(`\\bimport\\s+(?:[\\s\\S]*?\\bfrom\\s+)?["']${escapedSource}["']\\s*;?`, "g");
330
+ for (const match of code.matchAll(importRe)) {
331
+ const statement = match[0];
332
+ if (!isTypeOnlyImportStatement(statement)) return true;
333
+ }
334
+ return false;
335
+ }
336
+ /**
337
+ * Merge multiple InferredBindings into a single result (union).
338
+ */
339
+ function mergeBindings(bindings) {
340
+ return {
341
+ needsD1: bindings.some((b) => b.needsD1),
342
+ needsKV: bindings.some((b) => b.needsKV),
343
+ needsR2: bindings.some((b) => b.needsR2),
344
+ needsAuth: bindings.some((b) => b.needsAuth),
345
+ needsQueues: bindings.some((b) => b.needsQueues),
346
+ needsAI: bindings.some((b) => b.needsAI),
347
+ needsSandbox: bindings.some((b) => b.needsSandbox),
348
+ needsLive: bindings.some((b) => b.needsLive)
349
+ };
350
+ }
351
+ //#endregion
352
+ //#region src/ssr/entry.ts
353
+ const SSR_SERVER_ENTRY_RELATIVE_PATHS = ["src/main.ssr.ts", "src/main.ssr.tsx"];
354
+ const SSR_CLIENT_ENTRY_RELATIVE_PATHS = ["src/main.client.ts", "src/main.client.tsx"];
355
+ function resolveSingleEntry(root, entries, label) {
356
+ const matches = entries.map((relativePath) => ({
357
+ relativePath,
358
+ absolutePath: join(root, relativePath)
359
+ })).filter((entry) => existsSync(entry.absolutePath));
360
+ if (matches.length === 0) return null;
361
+ if (matches.length > 1) {
362
+ const names = matches.map((entry) => entry.relativePath).join(", ");
363
+ throw new Error(`ssr: Multiple ${label} entry files found: ${names}. Keep only one.`);
364
+ }
365
+ return matches[0];
366
+ }
367
+ function getSsrServerEntryPath(root) {
368
+ return resolveSingleEntry(root, SSR_SERVER_ENTRY_RELATIVE_PATHS, "SSR")?.absolutePath ?? null;
369
+ }
370
+ function hasSsrEntry(root) {
371
+ return getSsrServerEntryPath(root) !== null;
372
+ }
373
+ function validateServerRenderExport(entry) {
374
+ const { absolutePath, relativePath } = entry;
375
+ const source = readFileSync(absolutePath, "utf-8");
376
+ if (/\bexport\s+(?:async\s+)?function\s+render\b/.test(source) || /\bexport\s+const\s+render\b/.test(source) || /\bexport\s+default\s+(?:defineRender\b|(?:async\s+)?function\b)/.test(source)) return;
377
+ let parsed;
378
+ try {
379
+ parsed = parseSync(relativePath, source);
380
+ } catch (err) {
381
+ throw new Error(`ssr: Invalid entry '${relativePath}'. Could not parse source: '${err instanceof Error ? err.message : String(err)}'.`);
382
+ }
383
+ if (!(parsed.program.body ?? []).some((node) => {
384
+ if (node.type === "ExportDefaultDeclaration") {
385
+ const declaration = node.declaration;
386
+ if (declaration?.type === "FunctionDeclaration" || declaration?.type === "FunctionExpression" || declaration?.type === "ArrowFunctionExpression") return true;
387
+ if (declaration?.type === "CallExpression") {
388
+ const call = declaration;
389
+ return isIdentifier(call.callee) && call.callee.name === "defineRender";
390
+ }
391
+ return false;
392
+ }
393
+ if (node.type !== "ExportNamedDeclaration") return false;
394
+ const declaration = node.declaration;
395
+ if (declaration?.type === "FunctionDeclaration") {
396
+ const fn = declaration;
397
+ return isIdentifier(fn.id) && fn.id.name === "render";
398
+ }
399
+ if (declaration?.type === "VariableDeclaration") return (declaration.declarations ?? []).some((decl) => isIdentifier(decl.id) && decl.id.name === "render");
400
+ return (node.specifiers ?? []).some((specifier) => {
401
+ const exported = specifier.exported;
402
+ return isIdentifier(exported) && exported.name === "render";
403
+ });
404
+ })) throw new Error(`ssr: Invalid entry '${relativePath}'. Export \`render(c, assetTags)\` or \`export default defineRender(...)\`.`);
405
+ }
406
+ /**
407
+ * Validate SSR mode entry conventions.
408
+ * Returns null when SSR mode is not used.
409
+ */
410
+ function validateSsrEntries(root) {
411
+ const server = resolveSingleEntry(root, SSR_SERVER_ENTRY_RELATIVE_PATHS, "SSR");
412
+ const client = resolveSingleEntry(root, SSR_CLIENT_ENTRY_RELATIVE_PATHS, "SSR client");
413
+ if (!server && !client) return null;
414
+ if (server && !client) throw new Error(`ssr: Missing client entry. Add one of: ${SSR_CLIENT_ENTRY_RELATIVE_PATHS.join(", ")}.`);
415
+ if (!server && client) throw new Error(`ssr: Missing server entry. Add one of: ${SSR_SERVER_ENTRY_RELATIVE_PATHS.join(", ")}.`);
416
+ validateServerRenderExport(server);
417
+ return {
418
+ server,
419
+ client
420
+ };
421
+ }
422
+ function validateSsrEntry(root) {
423
+ return validateSsrEntries(root)?.server.absolutePath ?? null;
424
+ }
425
+ //#endregion
426
+ //#region src/plugin-inference.ts
427
+ const SOURCE_GLOB = "**/*.{ts,tsx,mts,js,jsx,mjs,astro}";
428
+ /** Directories to scan for binding inference in framework mode. */
429
+ const FRAMEWORK_SCAN_DIRS = [
430
+ "src",
431
+ "app",
432
+ "pages",
433
+ "routes",
434
+ "server",
435
+ "crons",
436
+ "queues"
437
+ ];
438
+ /** Directories to scan for binding inference in Void app mode. */
439
+ const DEFAULT_SCAN_DIRS = [
440
+ "routes",
441
+ "middleware",
442
+ "queues",
443
+ "pages",
444
+ "crons",
445
+ "src"
446
+ ];
447
+ /**
448
+ * Map from npm package name to framework identifier.
449
+ * Only packages that unambiguously indicate framework mode are listed.
450
+ * For example, `react-router` alone is a client-side router — only
451
+ * `@react-router/dev` signals the framework (Vite plugin) mode.
452
+ */
453
+ const FRAMEWORK_PACKAGES = {
454
+ "@tanstack/react-start": {
455
+ name: "tanstack-start",
456
+ class: "a"
457
+ },
458
+ "@react-router/dev": {
459
+ name: "react-router",
460
+ class: "a"
461
+ },
462
+ vinext: {
463
+ name: "vinext-pages",
464
+ class: "a"
465
+ },
466
+ "@sveltejs/kit": {
467
+ name: "sveltekit",
468
+ class: "b"
469
+ },
470
+ nuxt: {
471
+ name: "nuxt",
472
+ class: "c"
473
+ },
474
+ "@analogjs/platform": {
475
+ name: "analog",
476
+ class: "c"
477
+ },
478
+ astro: {
479
+ name: "astro",
480
+ class: "c"
481
+ }
482
+ };
483
+ /**
484
+ * Detect a meta-framework by checking package.json dependencies.
485
+ * Returns the detected framework with class info, or `undefined`.
486
+ */
487
+ function detectFramework(root) {
488
+ let pkg;
489
+ try {
490
+ pkg = JSON.parse(readFileSync(join(root, "package.json"), "utf-8"));
491
+ } catch {
492
+ return;
493
+ }
494
+ const deps = {
495
+ ...pkg.dependencies,
496
+ ...pkg.devDependencies
497
+ };
498
+ for (const [pkgName, framework] of Object.entries(FRAMEWORK_PACKAGES)) if (pkgName in deps) {
499
+ if (framework.name === "vinext-pages" && existsSync(join(root, "app"))) return {
500
+ name: "vinext-app",
501
+ class: "a"
502
+ };
503
+ return framework;
504
+ }
505
+ }
506
+ function extractAstroFrontmatter(code) {
507
+ return code.match(/^\uFEFF?---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/)?.[1] ?? "";
508
+ }
509
+ function inferBindingsFromFile(file, code) {
510
+ const filename = file.split("/").pop() ?? "unknown.ts";
511
+ if (!filename.endsWith(".astro")) return inferBindingsFromSource(code, filename);
512
+ return inferBindingsFromSource(extractAstroFrontmatter(code), filename.replace(/\.astro$/, ".ts"));
513
+ }
514
+ /**
515
+ * Synchronously infer which Cloudflare bindings the project needs
516
+ * by scanning route/middleware files and optional src/main.ssr.ts with oxc-parser.
517
+ *
518
+ * This runs once when voidPlugin() is called (before plugins initialize),
519
+ * so results are available to configure the Cloudflare plugin.
520
+ *
521
+ * @param scanDirs - Override the default scan directories (e.g., for framework mode)
522
+ */
523
+ function inferProjectBindings(root, options, scanDirs) {
524
+ if (options?.bindings) return {
525
+ needsD1: Boolean(options.bindings.db),
526
+ needsKV: Boolean(options.bindings.kv),
527
+ needsR2: Boolean(options.bindings.storage),
528
+ needsAuth: false,
529
+ needsQueues: false,
530
+ needsAI: Boolean(options.bindings.ai),
531
+ needsSandbox: false,
532
+ needsLive: false
533
+ };
534
+ const dirs = scanDirs ?? DEFAULT_SCAN_DIRS;
535
+ const allBindings = [];
536
+ for (const dir of dirs) {
537
+ const dirPath = join(root, dir);
538
+ let files;
539
+ try {
540
+ files = globSync(SOURCE_GLOB, {
541
+ cwd: dirPath,
542
+ absolute: true
543
+ });
544
+ } catch {
545
+ continue;
546
+ }
547
+ for (const file of files) {
548
+ const code = readFileSync(file, "utf-8");
549
+ allBindings.push(inferBindingsFromFile(file, code));
550
+ }
551
+ }
552
+ const ssrEntry = getSsrServerEntryPath(root);
553
+ if (ssrEntry) {
554
+ const code = readFileSync(ssrEntry, "utf-8");
555
+ const filename = ssrEntry.split("/").pop() ?? "main.ssr.ts";
556
+ allBindings.push(inferBindingsFromSource(code, filename));
557
+ }
558
+ if (!new Set(dirs).has("src")) {
559
+ const srcPath = join(root, "src");
560
+ let srcFiles;
561
+ try {
562
+ srcFiles = globSync(SOURCE_GLOB, {
563
+ cwd: srcPath,
564
+ absolute: true
565
+ });
566
+ } catch {
567
+ srcFiles = [];
568
+ }
569
+ for (const file of srcFiles) {
570
+ const code = readFileSync(file, "utf-8");
571
+ allBindings.push(inferBindingsFromFile(file, code));
572
+ }
573
+ }
574
+ return mergeBindings(allBindings);
575
+ }
576
+ //#endregion
577
+ export { SSR_CLIENT_ENTRY_RELATIVE_PATHS as a, validateSsrEntries as c, isCallExpression as d, isIdentifier as f, walk as g, isObjectExpression as h, inferProjectBindings as i, validateSsrEntry as l, isMemberExpression as m, FRAMEWORK_SCAN_DIRS as n, SSR_SERVER_ENTRY_RELATIVE_PATHS as o, isLiteral as p, detectFramework as r, hasSsrEntry as s, DEFAULT_SCAN_DIRS as t, inferBindingsFromSource as u };
@@ -2,10 +2,10 @@ import { a as join } from "./pathe.M-eThtNZ-D-kmWkCS.mjs";
2
2
  import { n as cliTitle } from "./output-BwlcIYSR.mjs";
3
3
  import { n as loadVoidAuthConfig, t as findVoidAuthConfig } from "./config-CvHtTM0q.mjs";
4
4
  import { c as R, g as ge, u as Se, y as ye } from "./dist-Dayj3gCK.mjs";
5
- import { c as getDatabaseDialect, f as readConfig } from "./config-BIa9HwVX.mjs";
6
- import { t as scanRoutes } from "./scan-QtRTdh94.mjs";
7
- import { i as inferProjectBindings, n as FRAMEWORK_SCAN_DIRS, r as detectFramework } from "./plugin-inference-CCtRkt9O.mjs";
8
- import { i as generateDbDts, n as generateQueueTypes, t as generateRouteTypes } from "./route-types-DReF1gUY.mjs";
5
+ import { c as getDatabaseDialect, f as readConfig } from "./config-DqkeX_Fa.mjs";
6
+ import { t as scanRoutes } from "./scan-B8iEm8xn.mjs";
7
+ import { i as inferProjectBindings, n as FRAMEWORK_SCAN_DIRS, r as detectFramework } from "./plugin-inference-CXUuq0aC.mjs";
8
+ import { i as generateDbDts, n as generateQueueTypes, t as generateRouteTypes } from "./route-types-Cnqj_8a7.mjs";
9
9
  import { n as ensureProjectTsconfig } from "./project-tsconfig-DfkESbDL.mjs";
10
10
  import { t as discoverSchema } from "./discover-B7FkXBLB.mjs";
11
11
  import { n as generateEnvTypes, t as findEnvFile } from "./env-types-DknSA4SO.mjs";
@@ -1,5 +1,5 @@
1
1
  import { a as join, s as resolve } from "./pathe.M-eThtNZ-D-kmWkCS.mjs";
2
- import { s as hasSsrEntry } from "./plugin-inference-CCtRkt9O.mjs";
2
+ import { s as hasSsrEntry } from "./plugin-inference-CXUuq0aC.mjs";
3
3
  import { existsSync, readFileSync } from "node:fs";
4
4
  //#region src/cli/preset.ts
5
5
  /**
@@ -1,10 +1,11 @@
1
- import { n as HeadDescriptor, t as HeadConfig } from "./head-CZGAunBV.mjs";
2
- import { n as CloudContext, t as CloudBindings } from "./handler-dKQWyF-G.mjs";
1
+ import { n as HeadDescriptor, t as HeadConfig } from "./head-C7QW7UY1.mjs";
2
+ import { n as CloudContext, t as CloudBindings } from "./handler-DJTuxB10.mjs";
3
+ import { t as DevCssAsset } from "./types-DG_Ynnyd.mjs";
3
4
 
4
5
  //#region src/pages/protocol.d.ts
5
6
  /** Escape characters that are unsafe inside inline <script> tags to prevent XSS. */
6
7
  declare function safeJsonStringify(value: unknown): string;
7
- interface PageObject {
8
+ type PageObject = {
8
9
  component: string;
9
10
  props: Record<string, unknown>;
10
11
  params: Record<string, string>;
@@ -14,7 +15,7 @@ interface PageObject {
14
15
  head?: HeadDescriptor;
15
16
  deferred?: Array<string>;
16
17
  deferredKeys?: Record<string, string>;
17
- }
18
+ };
18
19
  type PageRenderResult = string | ReadableStream<Uint8Array>;
19
20
  type PageHandler = ((c: CloudContext) => unknown | Promise<unknown>) | undefined;
20
21
  type PageHeadHandler = ((c: CloudContext, props: Record<string, unknown>) => HeadDescriptor | undefined) | undefined;
@@ -22,6 +23,8 @@ type AssetTags = {
22
23
  css: string;
23
24
  preloads: string;
24
25
  body: string;
26
+ devCss?: Array<DevCssAsset>;
27
+ devCssNonce?: string;
25
28
  };
26
29
  type RenderPage = (pageObj: PageObject, assetTags: AssetTags) => Promise<PageRenderResult>;
27
30
  type GetAssetTags = (req: Request, env: CloudBindings, componentId: string) => Promise<AssetTags>;
@@ -90,14 +90,14 @@ function generateRouteTypes(scan, routesDir, outDir, pagesDir) {
90
90
  const lines = [];
91
91
  lines.push("// Auto-generated by void — do not edit");
92
92
  lines.push("export {}");
93
- lines.push("interface StandardSchemaV1<Input = unknown, Output = Input> {");
93
+ lines.push("type StandardSchemaV1<Input = unknown, Output = Input> = {");
94
94
  lines.push(" readonly \"~standard\": {");
95
95
  lines.push(" readonly version: 1;");
96
96
  lines.push(" readonly vendor: string;");
97
97
  lines.push(" readonly validate: (value: unknown) => unknown;");
98
98
  lines.push(" readonly types?: { readonly input: Input; readonly output: Output } | undefined;");
99
99
  lines.push(" };");
100
- lines.push("}");
100
+ lines.push("};");
101
101
  lines.push("declare namespace StandardSchemaV1 {");
102
102
  lines.push(" type InferInput<Schema extends StandardSchemaV1> = NonNullable<");
103
103
  lines.push(" Schema[\"~standard\"][\"types\"]");