void 0.7.13 → 0.8.1

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 (133) hide show
  1. package/dist/{agents-DqkFfc2c.mjs → agents-Dkgafwfr.mjs} +1 -1
  2. package/dist/{auth-cmd-bS88H4Lb.mjs → auth-cmd-B1-7r6ng.mjs} +3 -3
  3. package/dist/{better-auth-shared-D2JaoCs4.mjs → better-auth-shared-CbAF6sOM.mjs} +1 -1
  4. package/dist/{better-auth-shared-HXlHRw02.d.mts → better-auth-shared-Fzyk5yS1.d.mts} +2 -7
  5. package/dist/{cache-DUDCNty6.mjs → cache-CGYC-2LW.mjs} +5 -5
  6. package/dist/{cancel-deploy-DOuSbPwX.mjs → cancel-deploy-B4j31z7d.mjs} +4 -4
  7. package/dist/canonical-json-CEyQaVDa.mjs +13 -0
  8. package/dist/cli/cli.mjs +44 -31
  9. package/dist/{client-C_DYiXeu.mjs → client-C-nH6yz3.mjs} +5 -5
  10. package/dist/{collect-HqAuilH6.mjs → collect-9rO3JFNM.mjs} +1 -1
  11. package/dist/{config-DyUSwbeX.mjs → config--wXmVOoe.mjs} +10 -8
  12. package/dist/{config-CeRQg3Lz.mjs → config-BVEC0lti.mjs} +11 -2
  13. package/dist/{config-CvHtTM0q.mjs → config-hhMYPVRT.mjs} +3 -12
  14. package/dist/{create-project-hvFe6rbI.mjs → create-project-BGnQMy5N.mjs} +44 -18
  15. package/dist/{db-YEYSTfGw.mjs → db-CT5Xg6ds.mjs} +42 -37
  16. package/dist/{delete-XyM_VD9o.mjs → delete-eMGTHHB9.mjs} +5 -5
  17. package/dist/{deploy-CPAEgVQm.mjs → deploy-DbmbcKID.mjs} +209 -127
  18. package/dist/{discover-CKGQpis8.mjs → discover-C8N1I4tK.mjs} +9 -6
  19. package/dist/{domain-Dvj7u8tr.mjs → domain-UfLrp2vc.mjs} +64 -22
  20. package/dist/{drizzle-Cx7cVwrE.mjs → drizzle-DmaANP4-.mjs} +1 -1
  21. package/dist/{env-Bjl0rzuf.mjs → env-Cvdbbm_N.mjs} +7 -7
  22. package/dist/{env-helpers-Dw95CU8e.d.mts → env-helpers-Bt9yYg5I.d.mts} +1 -1
  23. package/dist/{env-types-BSQghXbx.mjs → env-types-D6qI1ThV.mjs} +8 -19
  24. package/dist/{env-validation-Buy5pe3u.mjs → env-validation-DBJsxZLz.mjs} +4 -4
  25. package/dist/{gen-DU8NIdrH.mjs → gen-Cn2hZ8RR.mjs} +37 -31
  26. package/dist/{handler-DJTuxB10.d.mts → handler-BPhL8AmU.d.mts} +3 -3
  27. package/dist/{headers-CuVHn6Kl.mjs → headers-wAPJigtE.mjs} +3 -3
  28. package/dist/index.d.mts +3 -3
  29. package/dist/index.mjs +273 -104
  30. package/dist/{init-Br5DTaG7.mjs → init-CbNCFFWx.mjs} +105 -35
  31. package/dist/{link-DdXqlUiJ.mjs → link-C5x1E-XZ.mjs} +5 -5
  32. package/dist/{list-9Bxa5Odn.mjs → list-ezL7hqDV.mjs} +5 -5
  33. package/dist/{login-C_MfDjhu.mjs → login-CkLr-AaI.mjs} +3 -3
  34. package/dist/{logs-DjqCpEER.mjs → logs-MnGILmLz.mjs} +4 -4
  35. package/dist/{mcp-vA0880_K.mjs → mcp-B84MmVAW.mjs} +3 -3
  36. package/dist/{node-gxRQXIRT.mjs → node-fpywdcbN.mjs} +6 -6
  37. package/dist/{output-D3g5otMC.mjs → output-DeiS4oEX.mjs} +1 -1
  38. package/dist/pages/client.d.mts +1 -1
  39. package/dist/pages/head-client.d.mts +1 -1
  40. package/dist/pages/head.d.mts +1 -1
  41. package/dist/pages/index.d.mts +28 -3
  42. package/dist/pages/index.mjs +6 -5
  43. package/dist/pages/islands-plugin.d.mts +1 -1
  44. package/dist/pages/islands-plugin.mjs +7 -5
  45. package/dist/pages/protocol.d.mts +2 -2
  46. package/dist/pages/protocol.mjs +1 -1
  47. package/dist/{pathe.M-eThtNZ-D-kmWkCS.mjs → pathe.M-eThtNZ-BrPhGF_K.mjs} +1 -1
  48. package/dist/plan-aD3wRDqF.mjs +271 -0
  49. package/dist/{plugin-inference-BexV6LL3.mjs → plugin-inference-Ba1uGdIy.mjs} +26 -20
  50. package/dist/{prepare-BEkH89oX.mjs → prepare-BrAISonG.mjs} +29 -19
  51. package/dist/{preset-CYQh93UF.mjs → preset-BRsCi8ZB.mjs} +10 -8
  52. package/dist/{project-DhB4A8_g.mjs → project-CH9pdo16.mjs} +1 -1
  53. package/dist/{project-cmd-CeXO06hG.mjs → project-cmd-JQUzv3qF.mjs} +10 -10
  54. package/dist/project-paths-CCMrHYQm.mjs +100 -0
  55. package/dist/{project-slug-KRvHQEQI.mjs → project-slug-De4UjtD9.mjs} +0 -1
  56. package/dist/{project-tsconfig-Bfy55qvs.mjs → project-tsconfig-HAGjfY6w.mjs} +10 -5
  57. package/dist/{protocol-D7r_deVZ.d.mts → protocol-mcSsdMij.d.mts} +3 -3
  58. package/dist/providers--_pvxpNN.d.mts +7 -0
  59. package/dist/{resolve-project-DdjLQ2tB.mjs → resolve-project-CNpUbUHd.mjs} +1 -1
  60. package/dist/{rollback-C8OSMxmq.mjs → rollback-CoAAvC18.mjs} +4 -4
  61. package/dist/{route-types-qVL-v-CB.mjs → route-types-jxRfWuCb.mjs} +1 -1
  62. package/dist/{runner-C0d3lJo1.mjs → runner-BkGBfr4e.mjs} +4 -2
  63. package/dist/{runner-pg-Bd_172vF.mjs → runner-pg-BXP0JpHW.mjs} +1 -1
  64. package/dist/runtime/ai.mjs +2 -2
  65. package/dist/runtime/auth.d.mts +1 -1
  66. package/dist/runtime/better-auth-pg.d.mts +1 -1
  67. package/dist/runtime/better-auth-pg.mjs +2 -2
  68. package/dist/runtime/better-auth.d.mts +1 -1
  69. package/dist/runtime/better-auth.mjs +2 -2
  70. package/dist/runtime/client.d.mts +2 -2
  71. package/dist/runtime/client.mjs +1 -1
  72. package/dist/runtime/env-helpers.d.mts +1 -1
  73. package/dist/runtime/env-public-client.d.mts +1 -1
  74. package/dist/runtime/env-public.d.mts +2 -2
  75. package/dist/runtime/env-public.mjs +1 -1
  76. package/dist/runtime/env.mjs +1 -1
  77. package/dist/runtime/fetch-stream.d.mts +1 -1
  78. package/dist/runtime/fetch-stream.mjs +1 -1
  79. package/dist/runtime/fetch.d.mts +1 -1
  80. package/dist/runtime/fetch.mjs +1 -1
  81. package/dist/runtime/handler.d.mts +1 -1
  82. package/dist/runtime/handler.mjs +1 -1
  83. package/dist/runtime/isr.mjs +1 -1
  84. package/dist/runtime/live.d.mts +2 -2
  85. package/dist/runtime/live.mjs +1 -1
  86. package/dist/runtime/migration-handler.d.mts +33 -1
  87. package/dist/runtime/migration-handler.mjs +332 -24
  88. package/dist/runtime/remote/index.mjs +1 -1
  89. package/dist/runtime/sandbox.d.mts +73 -3
  90. package/dist/runtime/sandbox.mjs +239 -3
  91. package/dist/runtime/validator.d.mts +1 -1
  92. package/dist/runtime/ws-server.d.mts +2 -2
  93. package/dist/runtime/ws.d.mts +3 -3
  94. package/dist/{scan-CKpylFj9.mjs → scan-2YmJkYAf.mjs} +4 -3
  95. package/dist/{scan-CkK1Hzpa.mjs → scan-DzzHqtiT.mjs} +82 -43
  96. package/dist/{secret-NDvlqAN2.mjs → secret-mz8t_CML.mjs} +5 -5
  97. package/dist/{skills-SAG0WyVn.mjs → skills-B_ynF4lA.mjs} +3 -3
  98. package/dist/{subcommand-prompt-q9T06dpg.mjs → subcommand-prompt-CPuV7tPW.mjs} +2 -2
  99. package/dist/sveltekit.mjs +1 -1
  100. package/dist/{validate-DW3ViKTA.mjs → validate-CNWm-PsL.mjs} +49 -9
  101. package/dist/{yarn-pnp-6LD6_3Ej.mjs → yarn-pnp-QgEYVC3V.mjs} +1 -1
  102. package/package.json +3 -2
  103. package/schema.json +5 -0
  104. package/skills/void/docs/guide/ai.md +1 -1
  105. package/skills/void/docs/guide/app-types.md +1 -1
  106. package/skills/void/docs/guide/database/postgresql.md +4 -3
  107. package/skills/void/docs/guide/edge/headers.md +1 -1
  108. package/skills/void/docs/guide/edge/static-assets.md +34 -0
  109. package/skills/void/docs/guide/sandboxes.md +3 -2
  110. package/skills/void/docs/guide/ssr.md +25 -2
  111. package/skills/void/docs/integrations/cloudflare.md +5 -3
  112. package/skills/void/docs/integrations/frameworks/overview.md +1 -1
  113. package/skills/void/docs/integrations/nodejs-bun-deno.md +10 -9
  114. package/skills/void/docs/reference/api.md +204 -13
  115. package/skills/void/docs/reference/cli.md +53 -7
  116. package/skills/void/docs/reference/config.md +27 -4
  117. package/skills/void/docs/reference/resource-inference.md +1 -1
  118. /package/dist/{auth-DmuALf16.d.mts → auth-SfRBhXan.d.mts} +0 -0
  119. /package/dist/{auth-migrations-BwLPwRgH.mjs → auth-migrations-BqJoGqGQ.mjs} +0 -0
  120. /package/dist/{cf-access-BW8K93Fm.mjs → cf-access-DKDsgwOU.mjs} +0 -0
  121. /package/dist/{defer-2ARBu8Et.mjs → defer-DkoEwda-.mjs} +0 -0
  122. /package/dist/{dist-q8b2Mjgb.mjs → dist-DR9sIMbM.mjs} +0 -0
  123. /package/dist/{dist-D2L3_KTK.mjs → dist-abzUneor.mjs} +0 -0
  124. /package/dist/{dotenv-HQNhRalS.mjs → dotenv-Bkoqyq9r.mjs} +0 -0
  125. /package/dist/{env-raw-DtfQ9E31.mjs → env-raw-zk5JQKZe.mjs} +0 -0
  126. /package/dist/{fetch-error-DZ868Xq4.d.mts → fetch-error-BbixZ9vW.d.mts} +0 -0
  127. /package/dist/{fetch-error-CEr0ACTl.mjs → fetch-error-rXermVU3.mjs} +0 -0
  128. /package/dist/{head-C7QW7UY1.d.mts → head-CZs8dMxG.d.mts} +0 -0
  129. /package/dist/{log-7ChR5Fbc.mjs → log-CWWZV4V1.mjs} +0 -0
  130. /package/dist/{magic-string.es-DS_lmuBe.mjs → magic-string.es-C1Fb0uxq.mjs} +0 -0
  131. /package/dist/{providers-BlFNPYen.mjs → providers-uC0PJg1c.mjs} +0 -0
  132. /package/dist/{standard-schema-D2qvCEYV.d.mts → standard-schema-WhHcCaqJ.d.mts} +0 -0
  133. /package/dist/{types-DG_Ynnyd.d.mts → types-C8wsi1hv.d.mts} +0 -0
@@ -0,0 +1,271 @@
1
+ import { n as __exportAll } from "./chunk-DJd-R1mw.mjs";
2
+ import { t as canonicalJson } from "./canonical-json-CEyQaVDa.mjs";
3
+ import { createHash } from "node:crypto";
4
+ //#region src/migrations/tokenize.ts
5
+ function* tokenizeSql(sql) {
6
+ const sqlLength = sql.length;
7
+ let index = 0;
8
+ let runStart = 0;
9
+ const flushRun = (upTo) => {
10
+ if (upTo > runStart) return {
11
+ kind: "sql",
12
+ start: runStart,
13
+ end: upTo
14
+ };
15
+ };
16
+ while (index < sqlLength) {
17
+ const character = sql[index];
18
+ const next = index + 1 < sqlLength ? sql[index + 1] : "";
19
+ if (character === "-" && next === "-") {
20
+ const run = flushRun(index);
21
+ if (run) yield run;
22
+ let scanIndex = index + 2;
23
+ while (scanIndex < sqlLength && sql[scanIndex] !== "\n") scanIndex++;
24
+ yield {
25
+ kind: "line-comment",
26
+ start: index,
27
+ end: scanIndex
28
+ };
29
+ index = scanIndex;
30
+ runStart = index;
31
+ continue;
32
+ }
33
+ if (character === "/" && next === "*") {
34
+ const run = flushRun(index);
35
+ if (run) yield run;
36
+ let scanIndex = index + 2;
37
+ while (scanIndex < sqlLength - 1 && !(sql[scanIndex] === "*" && sql[scanIndex + 1] === "/")) scanIndex++;
38
+ const end = Math.min(scanIndex + 2, sqlLength);
39
+ yield {
40
+ kind: "block-comment",
41
+ start: index,
42
+ end
43
+ };
44
+ index = end;
45
+ runStart = index;
46
+ continue;
47
+ }
48
+ if (character === "'") {
49
+ const run = flushRun(index);
50
+ if (run) yield run;
51
+ let scanIndex = index + 1;
52
+ while (scanIndex < sqlLength) {
53
+ if (sql[scanIndex] === "'" && sql[scanIndex + 1] === "'") {
54
+ scanIndex += 2;
55
+ continue;
56
+ }
57
+ if (sql[scanIndex] === "'") {
58
+ scanIndex++;
59
+ break;
60
+ }
61
+ scanIndex++;
62
+ }
63
+ yield {
64
+ kind: "string",
65
+ start: index,
66
+ end: scanIndex
67
+ };
68
+ index = scanIndex;
69
+ runStart = index;
70
+ continue;
71
+ }
72
+ if (character === "\"" || character === "`" || character === "[") {
73
+ const run = flushRun(index);
74
+ if (run) yield run;
75
+ const close = character === "[" ? "]" : character;
76
+ let scanIndex = index + 1;
77
+ while (scanIndex < sqlLength) {
78
+ if (close !== "]" && sql[scanIndex] === close && sql[scanIndex + 1] === close) {
79
+ scanIndex += 2;
80
+ continue;
81
+ }
82
+ if (sql[scanIndex] === close) {
83
+ scanIndex++;
84
+ break;
85
+ }
86
+ scanIndex++;
87
+ }
88
+ yield {
89
+ kind: "ident-quote",
90
+ open: character,
91
+ start: index,
92
+ end: scanIndex
93
+ };
94
+ index = scanIndex;
95
+ runStart = index;
96
+ continue;
97
+ }
98
+ index++;
99
+ }
100
+ const tail = flushRun(sqlLength);
101
+ if (tail) yield tail;
102
+ }
103
+ //#endregion
104
+ //#region src/migrations/plan.ts
105
+ var plan_exports = /* @__PURE__ */ __exportAll({
106
+ DESTRUCTIVE_PRAGMA: () => DESTRUCTIVE_PRAGMA,
107
+ MIGRATION_CLASSIFIER_VERSION: () => 1,
108
+ UNSPLIT_MULTI_STATEMENT_PRAGMA: () => UNSPLIT_MULTI_STATEMENT_PRAGMA,
109
+ buildMigrationPlanBundle: () => buildMigrationPlanBundle,
110
+ canonicalSql: () => canonicalSql,
111
+ classifyMigration: () => classifyMigration,
112
+ computeMigrationListHash: () => computeMigrationListHash,
113
+ hasStandalonePragma: () => hasStandalonePragma,
114
+ isSingleStatement: () => isSingleStatement,
115
+ sha256Hex: () => sha256Hex
116
+ });
117
+ const UNSPLIT_MULTI_STATEMENT_PRAGMA = "-- void:allow-unsplit-multi-statement";
118
+ const DESTRUCTIVE_PRAGMA = "-- void:allow-destructive";
119
+ function canonicalSql(sql) {
120
+ return (sql.charCodeAt(0) === 65279 ? sql.slice(1) : sql).replace(/\r\n?/g, "\n");
121
+ }
122
+ function sha256Hex(value) {
123
+ return `sha256:${createHash("sha256").update(value).digest("hex")}`;
124
+ }
125
+ function getPlanHashInput(plan) {
126
+ const base = {
127
+ classifierVersion: plan.classifierVersion,
128
+ dialect: plan.dialect,
129
+ kind: plan.kind,
130
+ name: plan.name,
131
+ sqlHash: plan.sqlHash,
132
+ stability: plan.stability
133
+ };
134
+ if (plan.kind === "breakpoint-framed") base.statements = plan.statements;
135
+ return base;
136
+ }
137
+ function hashPlan(plan) {
138
+ return sha256Hex(canonicalJson(getPlanHashInput(plan)));
139
+ }
140
+ function computeMigrationListHash(plans) {
141
+ return sha256Hex(canonicalJson(plans.map((plan) => [
142
+ plan.name,
143
+ plan.sqlHash,
144
+ plan.planHash
145
+ ])));
146
+ }
147
+ function isStandalonePragmaLine(line, pragma) {
148
+ return line.trim() === pragma;
149
+ }
150
+ function hasStandalonePragma(sql, pragma) {
151
+ return canonicalSql(sql).split("\n").some((line) => isStandalonePragmaLine(line, pragma));
152
+ }
153
+ function isBreakpointComment(text) {
154
+ return text.trim() === "--> statement-breakpoint";
155
+ }
156
+ function splitBreakpointFramedSql(sql) {
157
+ const normalized = canonicalSql(sql);
158
+ const statements = [];
159
+ let cursor = 0;
160
+ for (const segment of tokenizeSql(normalized)) {
161
+ if (segment.kind !== "line-comment") continue;
162
+ if (isBreakpointComment(normalized.slice(segment.start, segment.end))) {
163
+ const statement = normalized.slice(cursor, segment.start).trim();
164
+ if (statement) statements.push(statement);
165
+ cursor = segment.end;
166
+ }
167
+ }
168
+ const statement = normalized.slice(cursor).trim();
169
+ if (statement) statements.push(statement);
170
+ return statements;
171
+ }
172
+ function getExecutableSql(sql) {
173
+ let out = "";
174
+ for (const segment of tokenizeSql(sql)) if (segment.kind === "sql") out += sql.slice(segment.start, segment.end);
175
+ else out += " ".repeat(segment.end - segment.start);
176
+ return out;
177
+ }
178
+ function hasStatementBreakpointOutsideLiterals(sql) {
179
+ const normalized = canonicalSql(sql);
180
+ for (const segment of tokenizeSql(normalized)) {
181
+ if (segment.kind !== "line-comment") continue;
182
+ if (isBreakpointComment(normalized.slice(segment.start, segment.end))) return true;
183
+ }
184
+ return false;
185
+ }
186
+ function isSingleStatement(sql) {
187
+ const normalized = canonicalSql(sql);
188
+ let statements = 0;
189
+ let inStatement = false;
190
+ for (const segment of tokenizeSql(normalized)) {
191
+ if (segment.kind === "line-comment" || segment.kind === "block-comment") continue;
192
+ if (segment.kind === "string" || segment.kind === "ident-quote") {
193
+ inStatement = true;
194
+ continue;
195
+ }
196
+ for (let index = segment.start; index < segment.end; index++) {
197
+ const character = normalized[index];
198
+ if (character === ";") {
199
+ if (inStatement) {
200
+ statements++;
201
+ inStatement = false;
202
+ }
203
+ continue;
204
+ }
205
+ if (character !== " " && character !== " " && character !== "\n" && character !== "\r") inStatement = true;
206
+ }
207
+ }
208
+ if (inStatement) statements++;
209
+ return statements === 1;
210
+ }
211
+ function includesTransactionControl(sql) {
212
+ return getExecutableSql(sql).match(/(?:^|;)\s*(BEGIN(?:\s+(?:DEFERRED|IMMEDIATE|EXCLUSIVE|TRANSACTION))?|COMMIT|ROLLBACK|SAVEPOINT|RELEASE)\b/i)?.[1]?.toUpperCase() ?? null;
213
+ }
214
+ function classifyMigration(migration) {
215
+ const sql = canonicalSql(migration.sql);
216
+ const sqlHash = sha256Hex(sql);
217
+ const transactionControl = includesTransactionControl(sql);
218
+ if (transactionControl) throw new Error(`Migration ${migration.name} contains ${transactionControl}; Void owns the stable D1 transaction boundary.`);
219
+ let base;
220
+ const warnings = [];
221
+ if (hasStatementBreakpointOutsideLiterals(sql)) {
222
+ const statements = splitBreakpointFramedSql(sql);
223
+ if (statements.length === 0) throw new Error(`Migration ${migration.name} has statement breakpoints but no SQL statements.`);
224
+ base = {
225
+ classifierVersion: 1,
226
+ dialect: "sqlite",
227
+ kind: "breakpoint-framed",
228
+ name: migration.name,
229
+ sqlHash,
230
+ stability: "stable",
231
+ statements
232
+ };
233
+ } else if (isSingleStatement(sql)) base = {
234
+ classifierVersion: 1,
235
+ dialect: "sqlite",
236
+ kind: "single-statement",
237
+ name: migration.name,
238
+ sqlHash,
239
+ stability: "stable"
240
+ };
241
+ else {
242
+ const allowLegacy = hasStandalonePragma(sql, UNSPLIT_MULTI_STATEMENT_PRAGMA);
243
+ warnings.push(`Migration ${migration.name} contains multiple statements without Drizzle statement breakpoints; it will run through the legacy D1 path.`);
244
+ base = {
245
+ allowLegacy,
246
+ classifierVersion: 1,
247
+ dialect: "sqlite",
248
+ kind: "legacy-unsplit-multi-statement",
249
+ name: migration.name,
250
+ sqlHash,
251
+ stability: "legacy"
252
+ };
253
+ }
254
+ return {
255
+ ...base,
256
+ planHash: hashPlan(base),
257
+ ...warnings.length > 0 ? { warnings } : {}
258
+ };
259
+ }
260
+ function buildMigrationPlanBundle(migrations) {
261
+ const plans = migrations.map((migration) => classifyMigration(migration));
262
+ return {
263
+ classifierVersion: 1,
264
+ destructiveValidation: "passed",
265
+ migrationListHash: computeMigrationListHash(plans),
266
+ plans,
267
+ protocolVersion: 2
268
+ };
269
+ }
270
+ //#endregion
271
+ export { tokenizeSql as a, plan_exports as i, buildMigrationPlanBundle as n, classifyMigration as r, DESTRUCTIVE_PRAGMA as t };
@@ -1,5 +1,6 @@
1
- import { a as join } from "./pathe.M-eThtNZ-D-kmWkCS.mjs";
2
- import { n as globSync } from "./dist-q8b2Mjgb.mjs";
1
+ import { a as join, s as relative } from "./pathe.M-eThtNZ-BrPhGF_K.mjs";
2
+ import { n as readProjectPaths } from "./project-paths-CCMrHYQm.mjs";
3
+ import { n as globSync } from "./dist-DR9sIMbM.mjs";
3
4
  import { existsSync, readFileSync } from "node:fs";
4
5
  import { parseSync } from "vite";
5
6
  import { parse } from "es-module-lexer/js";
@@ -242,7 +243,7 @@ function inferBindingsFromSource(code, filename) {
242
243
  case "void/auth":
243
244
  result.needsAuth = true;
244
245
  break;
245
- case "void/queue":
246
+ case "void/queues":
246
247
  result.needsQueues = true;
247
248
  break;
248
249
  case "void/ai":
@@ -352,10 +353,10 @@ function mergeBindings(bindings) {
352
353
  //#region src/ssr/entry.ts
353
354
  const SSR_SERVER_ENTRY_RELATIVE_PATHS = ["src/main.ssr.ts", "src/main.ssr.tsx"];
354
355
  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)
356
+ function resolveSingleEntry(root, entries, label, paths = readProjectPaths(root)) {
357
+ const matches = entries.map((entryName) => ({
358
+ relativePath: relative(root, join(paths.ssrDir, entryName)).replace(/\\/g, "/"),
359
+ absolutePath: join(paths.ssrDir, entryName)
359
360
  })).filter((entry) => existsSync(entry.absolutePath));
360
361
  if (matches.length === 0) return null;
361
362
  if (matches.length > 1) {
@@ -364,11 +365,13 @@ function resolveSingleEntry(root, entries, label) {
364
365
  }
365
366
  return matches[0];
366
367
  }
367
- function getSsrServerEntryPath(root) {
368
- return resolveSingleEntry(root, SSR_SERVER_ENTRY_RELATIVE_PATHS, "SSR")?.absolutePath ?? null;
368
+ const SSR_SERVER_ENTRY_NAMES = ["main.ssr.ts", "main.ssr.tsx"];
369
+ const SSR_CLIENT_ENTRY_NAMES = ["main.client.ts", "main.client.tsx"];
370
+ function getSsrServerEntryPath(root, paths = readProjectPaths(root)) {
371
+ return resolveSingleEntry(root, SSR_SERVER_ENTRY_NAMES, "SSR", paths)?.absolutePath ?? null;
369
372
  }
370
- function hasSsrEntry(root) {
371
- return getSsrServerEntryPath(root) !== null;
373
+ function hasSsrEntry(root, paths = readProjectPaths(root)) {
374
+ return getSsrServerEntryPath(root, paths) !== null;
372
375
  }
373
376
  function validateServerRenderExport(entry) {
374
377
  const { absolutePath, relativePath } = entry;
@@ -407,9 +410,9 @@ function validateServerRenderExport(entry) {
407
410
  * Validate SSR mode entry conventions.
408
411
  * Returns null when SSR mode is not used.
409
412
  */
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
+ function validateSsrEntries(root, paths = readProjectPaths(root)) {
414
+ const server = resolveSingleEntry(root, SSR_SERVER_ENTRY_NAMES, "SSR", paths);
415
+ const client = resolveSingleEntry(root, SSR_CLIENT_ENTRY_NAMES, "SSR client", paths);
413
416
  if (!server && !client) return null;
414
417
  if (server && !client) throw new Error(`ssr: Missing client entry. Add one of: ${SSR_CLIENT_ENTRY_RELATIVE_PATHS.join(", ")}.`);
415
418
  if (!server && client) throw new Error(`ssr: Missing server entry. Add one of: ${SSR_SERVER_ENTRY_RELATIVE_PATHS.join(", ")}.`);
@@ -419,8 +422,8 @@ function validateSsrEntries(root) {
419
422
  client
420
423
  };
421
424
  }
422
- function validateSsrEntry(root) {
423
- return validateSsrEntries(root)?.server.absolutePath ?? null;
425
+ function validateSsrEntry(root, paths = readProjectPaths(root)) {
426
+ return validateSsrEntries(root, paths)?.server.absolutePath ?? null;
424
427
  }
425
428
  //#endregion
426
429
  //#region src/plugin-inference.ts
@@ -531,7 +534,8 @@ function inferProjectBindings(root, options, scanDirs) {
531
534
  needsSandbox: false,
532
535
  needsLive: false
533
536
  };
534
- const dirs = scanDirs ?? DEFAULT_SCAN_DIRS;
537
+ const paths = options?.paths ?? readProjectPaths(root);
538
+ const dirs = scanDirs ?? (paths.sourceDir ? [paths.sourceDir] : DEFAULT_SCAN_DIRS);
535
539
  const allBindings = [];
536
540
  for (const dir of dirs) {
537
541
  const dirPath = join(root, dir);
@@ -549,14 +553,16 @@ function inferProjectBindings(root, options, scanDirs) {
549
553
  allBindings.push(inferBindingsFromFile(file, code));
550
554
  }
551
555
  }
552
- const ssrEntry = getSsrServerEntryPath(root);
556
+ const ssrEntry = getSsrServerEntryPath(root, paths);
553
557
  if (ssrEntry) {
554
558
  const code = readFileSync(ssrEntry, "utf-8");
555
559
  const filename = ssrEntry.split("/").pop() ?? "main.ssr.ts";
556
560
  allBindings.push(inferBindingsFromSource(code, filename));
557
561
  }
558
- if (!new Set(dirs).has("src")) {
559
- const srcPath = join(root, "src");
562
+ const dirsSet = new Set(dirs);
563
+ const srcRel = paths.sourceDir ? paths.sourceDir : "src";
564
+ if (!dirsSet.has(srcRel)) {
565
+ const srcPath = paths.sourceDir ? paths.sourceRoot : join(root, "src");
560
566
  let srcFiles;
561
567
  try {
562
568
  srcFiles = globSync(SOURCE_GLOB, {
@@ -1,15 +1,16 @@
1
- import { a as join } from "./pathe.M-eThtNZ-D-kmWkCS.mjs";
2
- import { n as cliTitle } from "./output-D3g5otMC.mjs";
3
- import { n as loadVoidAuthConfig, t as findVoidAuthConfig } from "./config-CvHtTM0q.mjs";
4
- import { c as R, g as ge, u as Se, y as ye } from "./dist-D2L3_KTK.mjs";
5
- import { c as getDatabaseDialect, f as readConfig } from "./config-CeRQg3Lz.mjs";
6
- import { t as scanRoutes } from "./scan-CkK1Hzpa.mjs";
7
- import { i as inferProjectBindings, n as FRAMEWORK_SCAN_DIRS, r as detectFramework } from "./plugin-inference-BexV6LL3.mjs";
8
- import { i as generateDbDts, n as generateQueueTypes, t as generateRouteTypes } from "./route-types-qVL-v-CB.mjs";
9
- import { n as ensureProjectTsconfig } from "./project-tsconfig-Bfy55qvs.mjs";
10
- import { t as discoverSchema } from "./discover-CKGQpis8.mjs";
11
- import { n as generateEnvTypes, t as findEnvFile } from "./env-types-BSQghXbx.mjs";
12
- import { n as generateVoidAuthDrizzleSchema, t as generateVoidAuthDatabaseModule } from "./drizzle-Cx7cVwrE.mjs";
1
+ import { a as join } from "./pathe.M-eThtNZ-BrPhGF_K.mjs";
2
+ import { n as cliTitle } from "./output-DeiS4oEX.mjs";
3
+ import { i as resolveProjectPaths } from "./project-paths-CCMrHYQm.mjs";
4
+ import { n as loadVoidAuthConfig, t as findVoidAuthConfig } from "./config-hhMYPVRT.mjs";
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-DzzHqtiT.mjs";
8
+ import { i as inferProjectBindings, n as FRAMEWORK_SCAN_DIRS, r as detectFramework } from "./plugin-inference-Ba1uGdIy.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";
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-DmaANP4-.mjs";
13
14
  import { existsSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
14
15
  import { fileURLToPath } from "node:url";
15
16
  import { loadEnv } from "vite";
@@ -27,13 +28,19 @@ function removeGeneratedFile(outDir, fileName, removed) {
27
28
  }
28
29
  async function prepareProject(root) {
29
30
  const config = readConfig(root);
31
+ const paths = resolveProjectPaths(root, config);
30
32
  const outDir = join(root, ".void");
31
33
  const written = [];
32
34
  const removed = [];
33
35
  mkdirSync(outDir, { recursive: true });
34
36
  const detectedFramework = detectFramework(root);
35
- const bindings = inferProjectBindings(root, config.inference?.bindings ? { bindings: config.inference.bindings } : void 0, config.inference?.scanDirs ?? (detectedFramework ? FRAMEWORK_SCAN_DIRS : void 0));
36
- const authConfigPath = findVoidAuthConfig(root);
37
+ const inferenceOptions = config.inference?.bindings ? { bindings: config.inference.bindings } : void 0;
38
+ const scanDirs = config.inference?.scanDirs ?? (detectedFramework ? FRAMEWORK_SCAN_DIRS : void 0);
39
+ const bindings = inferProjectBindings(root, {
40
+ ...inferenceOptions,
41
+ paths
42
+ }, scanDirs);
43
+ const authConfigPath = findVoidAuthConfig(root, paths);
37
44
  const authEnabled = bindings.needsAuth || authConfigPath !== null || config.auth !== void 0;
38
45
  const dialect = getDatabaseDialect(config);
39
46
  const envFile = findEnvFile(root);
@@ -41,15 +48,18 @@ async function prepareProject(root) {
41
48
  const { dts } = generateEnvTypes(envFile, outDir);
42
49
  writeGeneratedFile(outDir, "env.d.ts", dts, written);
43
50
  } else removeGeneratedFile(outDir, "env.d.ts", removed);
44
- const scan = await scanRoutes(root, { output: config.output });
51
+ const scan = await scanRoutes(root, {
52
+ output: config.output,
53
+ paths
54
+ });
45
55
  const hasRouteTypes = scan.routes.length > 0 || (scan.websockets?.length ?? 0) > 0 || scan.pages.pages.length > 0;
46
56
  if (hasRouteTypes) {
47
- const { dts } = generateRouteTypes(scan, join(root, "routes"), outDir, join(root, "pages"));
57
+ const { dts } = generateRouteTypes(scan, paths.routesDir, outDir, paths.pagesDir);
48
58
  writeGeneratedFile(outDir, "routes.d.ts", dts, written);
49
59
  } else removeGeneratedFile(outDir, "routes.d.ts", removed);
50
- if (scan.queues.length > 0) writeGeneratedFile(outDir, "queues.d.ts", generateQueueTypes(scan.queues, join(root, "queues"), outDir), written);
60
+ if (scan.queues.length > 0) writeGeneratedFile(outDir, "queues.d.ts", generateQueueTypes(scan.queues, paths.queuesDir, outDir), written);
51
61
  else removeGeneratedFile(outDir, "queues.d.ts", removed);
52
- const schema = discoverSchema(root);
62
+ const schema = discoverSchema(root, paths);
53
63
  const hasDbRuntime = schema != null || authEnabled;
54
64
  if (hasDbRuntime) {
55
65
  generateDbDts(outDir, schema, dialect);
@@ -77,7 +87,7 @@ async function prepareProject(root) {
77
87
  removeGeneratedFile(outDir, "better-auth-schema.ts", removed);
78
88
  removeGeneratedFile(outDir, "better-auth-db.ts", removed);
79
89
  }
80
- ensureProjectTsconfig(root, hasRouteTypes, hasDbRuntime, schema != null);
90
+ ensureProjectTsconfig(root, hasRouteTypes, hasDbRuntime, schema != null, { paths });
81
91
  written.push(join(".void", "tsconfig.json"));
82
92
  return {
83
93
  written,
@@ -1,5 +1,6 @@
1
- import { a as join, s as resolve } from "./pathe.M-eThtNZ-D-kmWkCS.mjs";
2
- import { s as hasSsrEntry } from "./plugin-inference-BexV6LL3.mjs";
1
+ import { a as join, c as resolve } from "./pathe.M-eThtNZ-BrPhGF_K.mjs";
2
+ import { n as readProjectPaths } from "./project-paths-CCMrHYQm.mjs";
3
+ import { s as hasSsrEntry } from "./plugin-inference-Ba1uGdIy.mjs";
3
4
  import { existsSync, readFileSync } from "node:fs";
4
5
  //#region src/cli/preset.ts
5
6
  /**
@@ -209,12 +210,13 @@ function detectViteBinary(root) {
209
210
  * Check whether the project has backend files that require a full worker deploy.
210
211
  */
211
212
  function hasBackendFiles(root) {
212
- if (existsSync(join(root, "routes"))) return true;
213
- if (existsSync(join(root, "pages"))) return true;
214
- if (existsSync(join(root, "middleware"))) return true;
215
- if (existsSync(join(root, "crons"))) return true;
216
- if (existsSync(join(root, "queues"))) return true;
217
- if (hasSsrEntry(root)) return true;
213
+ const paths = readProjectPaths(root);
214
+ if (existsSync(paths.routesDir)) return true;
215
+ if (existsSync(paths.pagesDir)) return true;
216
+ if (existsSync(paths.middlewareDir)) return true;
217
+ if (existsSync(paths.cronsDir)) return true;
218
+ if (existsSync(paths.queuesDir)) return true;
219
+ if (hasSsrEntry(root, paths)) return true;
218
220
  return false;
219
221
  }
220
222
  //#endregion
@@ -1,5 +1,5 @@
1
1
  import { n as __exportAll } from "./chunk-DJd-R1mw.mjs";
2
- import { a as join, n as dirname } from "./pathe.M-eThtNZ-D-kmWkCS.mjs";
2
+ import { a as join, n as dirname } from "./pathe.M-eThtNZ-BrPhGF_K.mjs";
3
3
  import { mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
4
4
  //#region src/cli/project.ts
5
5
  var project_exports = /* @__PURE__ */ __exportAll({
@@ -1,6 +1,6 @@
1
- import { i as dim, l as tablePrefix, n as cliTitle, s as import_picocolors } from "./output-D3g5otMC.mjs";
2
- import { c as getToken, n as PlatformClient, s as getSiteDomain } from "./client-C_DYiXeu.mjs";
3
- import { c as R, g as ge, y as ye } from "./dist-D2L3_KTK.mjs";
1
+ import { i as dim, l as tablePrefix, n as cliTitle, s as import_picocolors } from "./output-DeiS4oEX.mjs";
2
+ import { c as getToken, n as PlatformClient, s as getSiteDomain } from "./client-C-nH6yz3.mjs";
3
+ import { c as R, g as ge, y as ye } from "./dist-abzUneor.mjs";
4
4
  //#region src/cli/projects.ts
5
5
  async function runProjectsCommand(root) {
6
6
  console.log();
@@ -34,32 +34,32 @@ async function runProjectsCommand(root) {
34
34
  //#region src/cli/project-cmd.ts
35
35
  async function runProjectCommand(root, args) {
36
36
  if (args.subcommand === "status") {
37
- const { runListCommand } = await import("./list-9Bxa5Odn.mjs");
37
+ const { runListCommand } = await import("./list-ezL7hqDV.mjs");
38
38
  return runListCommand(root, args.name || void 0);
39
39
  }
40
40
  if (args.subcommand === "link") {
41
- const { runLink } = await import("./link-DdXqlUiJ.mjs");
41
+ const { runLink } = await import("./link-C5x1E-XZ.mjs");
42
42
  return runLink(root, args.name || void 0);
43
43
  }
44
44
  if (args.subcommand === "list") return runProjectsCommand(root);
45
45
  if (args.subcommand === "logs") {
46
- const { runLogsCommand } = await import("./logs-DjqCpEER.mjs");
46
+ const { runLogsCommand } = await import("./logs-MnGILmLz.mjs");
47
47
  return runLogsCommand(root, args.filter, args.range, args.deployment || void 0, args.level || void 0);
48
48
  }
49
49
  if (args.subcommand === "rollback") {
50
- const { runRollbackCommand } = await import("./rollback-C8OSMxmq.mjs");
50
+ const { runRollbackCommand } = await import("./rollback-CoAAvC18.mjs");
51
51
  return runRollbackCommand(root, args.deployId || void 0);
52
52
  }
53
53
  if (args.subcommand === "cancel") {
54
- const { runCancelDeployCommand } = await import("./cancel-deploy-DOuSbPwX.mjs");
54
+ const { runCancelDeployCommand } = await import("./cancel-deploy-B4j31z7d.mjs");
55
55
  return runCancelDeployCommand(root, args.deployId || void 0);
56
56
  }
57
57
  if (args.subcommand === "delete") {
58
- const { runDeleteCommand } = await import("./delete-XyM_VD9o.mjs");
58
+ const { runDeleteCommand } = await import("./delete-eMGTHHB9.mjs");
59
59
  return runDeleteCommand(root, args.name || void 0, { force: args.force });
60
60
  }
61
61
  if (args.subcommand === "purge-cache") {
62
- const { runPurgeCacheCommand } = await import("./cache-DUDCNty6.mjs");
62
+ const { runPurgeCacheCommand } = await import("./cache-CGYC-2LW.mjs");
63
63
  return runPurgeCacheCommand(root, args.projectSlug || void 0);
64
64
  }
65
65
  }
@@ -0,0 +1,100 @@
1
+ import { a as join, i as isAbsolute, o as normalize, s as relative } from "./pathe.M-eThtNZ-BrPhGF_K.mjs";
2
+ import { existsSync, readFileSync } from "node:fs";
3
+ //#region src/project-paths.ts
4
+ const SOURCE_CONVENTION_DIRECTORIES = [
5
+ "routes",
6
+ "pages",
7
+ "middleware",
8
+ "crons",
9
+ "queues",
10
+ "db"
11
+ ];
12
+ const AUTH_CONFIG_FILES = [
13
+ "auth.ts",
14
+ "auth.mts",
15
+ "auth.js",
16
+ "auth.mjs",
17
+ "auth.cts",
18
+ "auth.cjs"
19
+ ];
20
+ const ENV_CONFIG_FILES = [
21
+ "env.ts",
22
+ "env.mts",
23
+ "env.js",
24
+ "env.mjs"
25
+ ];
26
+ const SOURCE_CONVENTIONS = new Set([
27
+ ...SOURCE_CONVENTION_DIRECTORIES,
28
+ ...AUTH_CONFIG_FILES,
29
+ ...ENV_CONFIG_FILES
30
+ ]);
31
+ function validateSourceDir(value, label = "sourceDir") {
32
+ if (value.trim() !== value || value.length === 0) throw new Error(`config: "${label}" in void.json must be a non-empty relative directory.`);
33
+ if (value === "." || value === ".." || value.startsWith("../") || value.includes("/../") || value.endsWith("/..") || isAbsolute(value)) throw new Error(`config: "${label}" path '${value}' in void.json must be a relative directory.`);
34
+ const normalized = normalize(value).replace(/\/+$/, "");
35
+ if (normalized === "" || normalized === ".") throw new Error(`config: "${label}" path '${value}' in void.json must be a relative directory.`);
36
+ return normalized;
37
+ }
38
+ function getSourceDir(config) {
39
+ return config?.sourceDir ? validateSourceDir(config.sourceDir) : "";
40
+ }
41
+ function resolveCandidate(root, sourceDir, candidate) {
42
+ return sourceDir ? join(root, sourceDir, candidate) : join(root, candidate);
43
+ }
44
+ function resolveProjectPaths(root, config) {
45
+ const sourceDir = getSourceDir(config);
46
+ const sourceRoot = sourceDir ? join(root, sourceDir) : root;
47
+ const sourceRelative = (path) => sourceDir ? `${sourceDir}/${path}` : path;
48
+ const envFileCandidates = sourceDir ? ENV_CONFIG_FILES.map((file) => join(sourceRoot, file)) : [...ENV_CONFIG_FILES.map((file) => join(root, file)), ...ENV_CONFIG_FILES.map((file) => join(root, "src", file))];
49
+ return {
50
+ root,
51
+ sourceDir,
52
+ sourceRoot,
53
+ routesDir: join(sourceRoot, "routes"),
54
+ middlewareDir: join(sourceRoot, "middleware"),
55
+ cronsDir: join(sourceRoot, "crons"),
56
+ queuesDir: join(sourceRoot, "queues"),
57
+ pagesDir: join(sourceRoot, "pages"),
58
+ dbDir: join(sourceRoot, "db"),
59
+ migrationsDir: join(sourceRoot, "db", "migrations"),
60
+ schemaFile: join(sourceRoot, "db", "schema.ts"),
61
+ schemaDir: join(sourceRoot, "db", "schema"),
62
+ srcDir: join(sourceRoot, "src"),
63
+ ssrDir: sourceDir ? sourceRoot : join(root, "src"),
64
+ sourceRelative,
65
+ authConfigCandidates: AUTH_CONFIG_FILES.map((file) => resolveCandidate(root, sourceDir, file)),
66
+ envFileCandidates
67
+ };
68
+ }
69
+ function readProjectPaths(root) {
70
+ return resolveProjectPaths(root, readSourceDirConfig(root));
71
+ }
72
+ function readSourceDirConfig(root) {
73
+ let raw;
74
+ try {
75
+ raw = readFileSync(join(root, "void.json"), "utf-8");
76
+ } catch {
77
+ return {};
78
+ }
79
+ let config;
80
+ try {
81
+ config = JSON.parse(raw);
82
+ } catch {
83
+ return {};
84
+ }
85
+ if (typeof config !== "object" || config === null || Array.isArray(config)) return {};
86
+ const sourceDir = config.sourceDir;
87
+ return typeof sourceDir === "string" ? { sourceDir } : {};
88
+ }
89
+ function resolvePagesDir(root = process.cwd()) {
90
+ return readProjectPaths(root).pagesDir;
91
+ }
92
+ function assertNoRootSourceConventionConflicts(paths) {
93
+ if (!paths.sourceDir) return;
94
+ const conflicts = Array.from(SOURCE_CONVENTIONS).filter((convention) => existsSync(join(paths.root, convention)) && existsSync(join(paths.sourceRoot, convention)));
95
+ if (conflicts.length === 0) return;
96
+ const relSource = relative(paths.root, paths.sourceRoot);
97
+ throw new Error(`sourceDir: void.json sets "sourceDir": "${paths.sourceDir}", but convention path(s) also exist at the project root: ${conflicts.join(", ")}. Move them under "${relSource}" or remove the root copy.`);
98
+ }
99
+ //#endregion
100
+ export { validateSourceDir as a, resolveProjectPaths as i, readProjectPaths as n, resolvePagesDir as r, assertNoRootSourceConventionConflicts as t };
@@ -5,7 +5,6 @@ function validateProjectSlug(value) {
5
5
  const slug = (value ?? "").trim();
6
6
  if (slug.length === 0) return "Project slug is required.";
7
7
  if (!(slug.length === 1 ? /^[a-z0-9]$/.test(slug) : /^[a-z0-9][a-z0-9-]*[a-z0-9]$/.test(slug))) return "Slug must be lowercase alphanumeric with dashes.";
8
- if (slug.length <= 5) return "Slugs of 5 characters or fewer require a paid plan. Use at least 6 characters.";
9
8
  }
10
9
  //#endregion
11
10
  export { validateProjectSlug as n, project_slug_exports as t };