theokit 0.5.4 → 0.6.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 (170) hide show
  1. package/dist/{actions-virtual-module-DL74V6SR.js → actions-virtual-module-4WVKHQ2X.js} +5 -2
  2. package/dist/actions-virtual-module-4WVKHQ2X.js.map +1 -0
  3. package/dist/{actions-virtual-module-ZDD54ZZE.js → actions-virtual-module-LTOXBSCF.js} +16 -2
  4. package/dist/actions-virtual-module-LTOXBSCF.js.map +1 -0
  5. package/dist/{app-typed-client-4M4NVSK3.js → app-typed-client-4N5OGNOQ.js} +15 -4
  6. package/dist/app-typed-client-4N5OGNOQ.js.map +1 -0
  7. package/dist/{app-typed-client-4GIKUKRT.js → app-typed-client-SAETWZT5.js} +5 -4
  8. package/dist/app-typed-client-SAETWZT5.js.map +1 -0
  9. package/dist/{aws-lambda-SCRGTGF5.js → aws-lambda-WT4HRBNL.js} +3 -3
  10. package/dist/{build-R74EU6BP.js → build-KQD2EDU4.js} +10 -11
  11. package/dist/build-KQD2EDU4.js.map +1 -0
  12. package/dist/{bun-FURRCQMS.js → bun-UTDVN6R4.js} +3 -3
  13. package/dist/{check-NXYPLM6M.js → check-F3UDYSZ4.js} +2 -2
  14. package/dist/chunk-223EFY5X.js +469 -0
  15. package/dist/chunk-223EFY5X.js.map +1 -0
  16. package/dist/{chunk-KJLECZWQ.js → chunk-3FYJ7R7N.js} +57 -14
  17. package/dist/chunk-3FYJ7R7N.js.map +1 -0
  18. package/dist/{chunk-HDA6M7P4.js → chunk-3LVRAGAZ.js} +3 -5
  19. package/dist/{chunk-JD7AQNJS.js → chunk-4I47JW5O.js} +38 -425
  20. package/dist/chunk-4I47JW5O.js.map +1 -0
  21. package/dist/{chunk-H4J2LECY.js → chunk-6BUUZ2PK.js} +9 -9
  22. package/dist/chunk-6BUUZ2PK.js.map +1 -0
  23. package/dist/{chunk-P2RS3WWY.js → chunk-6FYD34NX.js} +194 -22
  24. package/dist/chunk-6FYD34NX.js.map +1 -0
  25. package/dist/{chunk-X3VNROZ7.js → chunk-6VSKLYT6.js} +78 -21
  26. package/dist/chunk-6VSKLYT6.js.map +1 -0
  27. package/dist/{chunk-FGOX37NB.js → chunk-BNGBG2SQ.js} +21 -2
  28. package/dist/chunk-BNGBG2SQ.js.map +1 -0
  29. package/dist/chunk-CBGRFVF5.js +421 -0
  30. package/dist/chunk-CBGRFVF5.js.map +1 -0
  31. package/dist/{chunk-X32KQH5C.js → chunk-CCVC6P6B.js} +3 -3
  32. package/dist/chunk-CCVC6P6B.js.map +1 -0
  33. package/dist/{chunk-DNMSV3R3.js → chunk-D7ZH7DTG.js} +3 -3
  34. package/dist/chunk-D7ZH7DTG.js.map +1 -0
  35. package/dist/{chunk-MWYSRZI4.js → chunk-EQV67HZL.js} +2 -2
  36. package/dist/{chunk-CG563V5M.js → chunk-IEES3CHD.js} +39 -5
  37. package/dist/chunk-IEES3CHD.js.map +1 -0
  38. package/dist/{chunk-DUKXQNM7.js → chunk-IHMJV2OK.js} +2 -2
  39. package/dist/{chunk-WGHJD6I7.js → chunk-JAIKGP3Q.js} +76 -21
  40. package/dist/chunk-JAIKGP3Q.js.map +1 -0
  41. package/dist/{chunk-B3L3TJVF.js → chunk-JBCHWRKF.js} +50 -50
  42. package/dist/chunk-JBCHWRKF.js.map +1 -0
  43. package/dist/{chunk-XMS5VRIK.js → chunk-JQSFBJR5.js} +3 -3
  44. package/dist/chunk-JQSFBJR5.js.map +1 -0
  45. package/dist/{chunk-S74FECKW.js → chunk-MV4LKTW6.js} +119 -153
  46. package/dist/chunk-MV4LKTW6.js.map +1 -0
  47. package/dist/chunk-PBEH6NXR.js +44 -0
  48. package/dist/chunk-PBEH6NXR.js.map +1 -0
  49. package/dist/chunk-PPPR5DGR.js +1 -0
  50. package/dist/{chunk-NZXH2LQQ.js → chunk-SJIRP73B.js} +18 -1
  51. package/dist/chunk-SJIRP73B.js.map +1 -0
  52. package/dist/cli/index.js +25 -10
  53. package/dist/cli/index.js.map +1 -1
  54. package/dist/client/index.d.ts +4 -4
  55. package/dist/{cloudflare-IZ6VJ2OU.js → cloudflare-U5GYYI47.js} +3 -3
  56. package/dist/db-ZPDW3UCU.js +78 -0
  57. package/dist/db-ZPDW3UCU.js.map +1 -0
  58. package/dist/{deno-deploy-O73NBXIW.js → deno-deploy-3QHJ3AJQ.js} +3 -3
  59. package/dist/{dev-ZU46C5AZ.js → dev-NDEZA2MP.js} +21 -11
  60. package/dist/dev-NDEZA2MP.js.map +1 -0
  61. package/dist/{dev-emit-JBVINGHU.js → dev-emit-O4EGOSNV.js} +77 -24
  62. package/dist/dev-emit-O4EGOSNV.js.map +1 -0
  63. package/dist/{dev-emit-66FCOS7V.js → dev-emit-OUPI7NAQ.js} +4 -5
  64. package/dist/{dev-emit-66FCOS7V.js.map → dev-emit-OUPI7NAQ.js.map} +1 -1
  65. package/dist/devtools/entry.js +1 -0
  66. package/dist/devtools/entry.js.map +1 -1
  67. package/dist/{dist-KRW6OVD4.js → dist-6GPD6WCU.js} +10231 -8164
  68. package/dist/dist-6GPD6WCU.js.map +1 -0
  69. package/dist/generate-ODDAYXNR.js +494 -0
  70. package/dist/generate-ODDAYXNR.js.map +1 -0
  71. package/dist/{index-CuHICqb9.d.ts → index-DWZF8uQD.d.ts} +132 -132
  72. package/dist/index.d.ts +32 -3
  73. package/dist/index.js +8 -9
  74. package/dist/index.js.map +1 -1
  75. package/dist/{info-CORLCPEJ.js → info-CSGWIAXA.js} +5 -5
  76. package/dist/{lib-NST3PNZX.js → lib-JBI3XXH3.js} +27 -27
  77. package/dist/{lib-NST3PNZX.js.map → lib-JBI3XXH3.js.map} +1 -1
  78. package/dist/{netlify-O7G3RLK4.js → netlify-DUB7BZ4E.js} +3 -3
  79. package/dist/{node-LXPQLMVB.js → node-ELE236WK.js} +3 -3
  80. package/dist/{openapi-TEOUOIJ2.js → openapi-NXGRXABL.js} +7 -8
  81. package/dist/{openapi-TEOUOIJ2.js.map → openapi-NXGRXABL.js.map} +1 -1
  82. package/dist/registry-B7FA6KMI.js +25 -0
  83. package/dist/{routes-GAXVWJUK.js → routes-6A5XFGF7.js} +7 -9
  84. package/dist/routes-6A5XFGF7.js.map +1 -0
  85. package/dist/{scan-NQFI5S7P.js → scan-I5PT6TUX.js} +2 -2
  86. package/dist/{schema-D3v8VB7o.d.ts → schema-BpH6ivDY.d.ts} +2 -4
  87. package/dist/{schema-Z5VJ2I76.js → schema-NPI4NJEF.js} +3 -3
  88. package/dist/server/auth/index.d.ts +20 -20
  89. package/dist/server/auth/index.js +3 -5
  90. package/dist/server/define/index.d.ts +7 -0
  91. package/dist/server/define/index.js +1 -1
  92. package/dist/server/http/index.d.ts +2 -2
  93. package/dist/server/http/index.js +1 -2
  94. package/dist/server/index.d.ts +36 -3
  95. package/dist/server/index.js +66 -61
  96. package/dist/server/index.js.map +1 -1
  97. package/dist/server/scan/index.d.ts +13 -13
  98. package/dist/server/scan/index.js +8 -12
  99. package/dist/server/security/index.d.ts +69 -69
  100. package/dist/server/security/index.js +1 -1
  101. package/dist/{services-typed-client-ASZL7FQV.js → services-typed-client-24VBMDOF.js} +2 -2
  102. package/dist/{services-typed-client-KK6RHRDG.js → services-typed-client-IETY2SAK.js} +2 -2
  103. package/dist/{start-HGUNNF5X.js → start-SPFWOGHL.js} +95 -80
  104. package/dist/start-SPFWOGHL.js.map +1 -0
  105. package/dist/{static-EO73I4C7.js → static-YWF2M6YT.js} +4 -4
  106. package/dist/{theo-cloud-HBCYEODQ.js → theo-cloud-EUK56I7O.js} +2 -2
  107. package/dist/{vercel-GSFDMF7K.js → vercel-LGDQWYZD.js} +3 -3
  108. package/dist/vite-plugin/index.d.ts +1 -1
  109. package/dist/vite-plugin/index.js +6 -7
  110. package/dist/{vite-plugin-TX5H4MB6.js → vite-plugin-43KQU5S7.js} +11 -9
  111. package/dist/vite-plugin-43KQU5S7.js.map +1 -0
  112. package/package.json +22 -19
  113. package/dist/actions-virtual-module-DL74V6SR.js.map +0 -1
  114. package/dist/actions-virtual-module-ZDD54ZZE.js.map +0 -1
  115. package/dist/app-typed-client-4GIKUKRT.js.map +0 -1
  116. package/dist/app-typed-client-4M4NVSK3.js.map +0 -1
  117. package/dist/build-R74EU6BP.js.map +0 -1
  118. package/dist/chunk-4HBI7DHP.js +0 -20
  119. package/dist/chunk-4HBI7DHP.js.map +0 -1
  120. package/dist/chunk-B3L3TJVF.js.map +0 -1
  121. package/dist/chunk-CG563V5M.js.map +0 -1
  122. package/dist/chunk-DNMSV3R3.js.map +0 -1
  123. package/dist/chunk-FGOX37NB.js.map +0 -1
  124. package/dist/chunk-GPF64ENM.js +0 -73
  125. package/dist/chunk-H4J2LECY.js.map +0 -1
  126. package/dist/chunk-HDA6M7P4.js.map +0 -1
  127. package/dist/chunk-JD7AQNJS.js.map +0 -1
  128. package/dist/chunk-KJLECZWQ.js.map +0 -1
  129. package/dist/chunk-NZXH2LQQ.js.map +0 -1
  130. package/dist/chunk-OLPB36O2.js +0 -259
  131. package/dist/chunk-OLPB36O2.js.map +0 -1
  132. package/dist/chunk-P2RS3WWY.js.map +0 -1
  133. package/dist/chunk-P3SGM4NR.js +0 -156
  134. package/dist/chunk-P3SGM4NR.js.map +0 -1
  135. package/dist/chunk-S74FECKW.js.map +0 -1
  136. package/dist/chunk-UVHRD33F.js +0 -181
  137. package/dist/chunk-UVHRD33F.js.map +0 -1
  138. package/dist/chunk-WGHJD6I7.js.map +0 -1
  139. package/dist/chunk-X32KQH5C.js.map +0 -1
  140. package/dist/chunk-X3VNROZ7.js.map +0 -1
  141. package/dist/chunk-XMS5VRIK.js.map +0 -1
  142. package/dist/dev-ZU46C5AZ.js.map +0 -1
  143. package/dist/dev-emit-JBVINGHU.js.map +0 -1
  144. package/dist/dist-KRW6OVD4.js.map +0 -1
  145. package/dist/generate-AZ2K6Z2Z.js +0 -281
  146. package/dist/generate-AZ2K6Z2Z.js.map +0 -1
  147. package/dist/registry-KW4F4D2L.js +0 -25
  148. package/dist/routes-GAXVWJUK.js.map +0 -1
  149. package/dist/start-HGUNNF5X.js.map +0 -1
  150. package/dist/{aws-lambda-SCRGTGF5.js.map → aws-lambda-WT4HRBNL.js.map} +0 -0
  151. package/dist/{bun-FURRCQMS.js.map → bun-UTDVN6R4.js.map} +0 -0
  152. package/dist/{check-NXYPLM6M.js.map → check-F3UDYSZ4.js.map} +0 -0
  153. package/dist/{chunk-GPF64ENM.js.map → chunk-3LVRAGAZ.js.map} +0 -0
  154. package/dist/{chunk-MWYSRZI4.js.map → chunk-EQV67HZL.js.map} +0 -0
  155. package/dist/{chunk-DUKXQNM7.js.map → chunk-IHMJV2OK.js.map} +0 -0
  156. package/dist/{node-LXPQLMVB.js.map → chunk-PPPR5DGR.js.map} +0 -0
  157. package/dist/{cloudflare-IZ6VJ2OU.js.map → cloudflare-U5GYYI47.js.map} +0 -0
  158. package/dist/{deno-deploy-O73NBXIW.js.map → deno-deploy-3QHJ3AJQ.js.map} +0 -0
  159. package/dist/{info-CORLCPEJ.js.map → info-CSGWIAXA.js.map} +0 -0
  160. package/dist/{module-loader-Cfz7dgCP.d.ts → match-CfbEFRG4.d.ts} +4 -4
  161. /package/dist/{netlify-O7G3RLK4.js.map → netlify-DUB7BZ4E.js.map} +0 -0
  162. /package/dist/{scan-NQFI5S7P.js.map → node-ELE236WK.js.map} +0 -0
  163. /package/dist/{registry-KW4F4D2L.js.map → registry-B7FA6KMI.js.map} +0 -0
  164. /package/dist/{schema-Z5VJ2I76.js.map → scan-I5PT6TUX.js.map} +0 -0
  165. /package/dist/{vite-plugin-TX5H4MB6.js.map → schema-NPI4NJEF.js.map} +0 -0
  166. /package/dist/{services-typed-client-ASZL7FQV.js.map → services-typed-client-24VBMDOF.js.map} +0 -0
  167. /package/dist/{services-typed-client-KK6RHRDG.js.map → services-typed-client-IETY2SAK.js.map} +0 -0
  168. /package/dist/{static-EO73I4C7.js.map → static-YWF2M6YT.js.map} +0 -0
  169. /package/dist/{theo-cloud-HBCYEODQ.js.map → theo-cloud-EUK56I7O.js.map} +0 -0
  170. /package/dist/{vercel-GSFDMF7K.js.map → vercel-LGDQWYZD.js.map} +0 -0
@@ -1,5 +1,22 @@
1
1
  #!/usr/bin/env node
2
2
  import "tsx/esm";
3
+ import {
4
+ resolveTransformer
5
+ } from "./chunk-PBEH6NXR.js";
6
+ import {
7
+ loadConfig
8
+ } from "./chunk-IHMJV2OK.js";
9
+ import {
10
+ BATCH_PATH,
11
+ CSP_REPORT_PATH,
12
+ CsrfReadinessStore,
13
+ TRACE_HEADER,
14
+ createCorsHandler,
15
+ extractTraceId,
16
+ handleBatchRequest,
17
+ handleCspReport,
18
+ handleCsrfReadiness
19
+ } from "./chunk-CBGRFVF5.js";
3
20
  import {
4
21
  applySecurityHeaders,
5
22
  createPluginRunnerFromConfig,
@@ -10,31 +27,24 @@ import {
10
27
  findSuggestion,
11
28
  generateNonce,
12
29
  logRequest,
13
- resolveTransformer,
14
- safeAudit,
15
30
  sendError
16
- } from "./chunk-S74FECKW.js";
17
- import {
18
- loadConfig
19
- } from "./chunk-DUKXQNM7.js";
31
+ } from "./chunk-MV4LKTW6.js";
20
32
  import {
21
33
  buildServicesProxyConfig
22
- } from "./chunk-X32KQH5C.js";
34
+ } from "./chunk-CCVC6P6B.js";
23
35
  import {
24
36
  broadcastToDevtools
25
37
  } from "./chunk-5ODOE6EF.js";
26
38
  import {
27
39
  isRouteFile,
28
40
  scanRoutes
29
- } from "./chunk-CG563V5M.js";
41
+ } from "./chunk-IEES3CHD.js";
30
42
  import {
31
43
  matchRoute,
44
+ scanServerActions,
32
45
  scanServerRoutes,
33
46
  scanWebSocketRoutes
34
- } from "./chunk-P2RS3WWY.js";
35
- import {
36
- scanServerActions
37
- } from "./chunk-UVHRD33F.js";
47
+ } from "./chunk-6FYD34NX.js";
38
48
 
39
49
  // src/vite-plugin/index.ts
40
50
  import { existsSync as existsSync7 } from "fs";
@@ -285,54 +295,6 @@ function broadcastRouteManifest(tree) {
285
295
  broadcastToDevtools("theo:devtools:manifest", manifest);
286
296
  }
287
297
 
288
- // src/server/security/csrf-readiness-store.ts
289
- var CsrfReadinessStore = class _CsrfReadinessStore {
290
- static MAX_ENTRIES = 1e3;
291
- entries = /* @__PURE__ */ new Map();
292
- keyFor(event) {
293
- return `${event.method}\0${event.path}\0${event.reason}`;
294
- }
295
- record(event) {
296
- const key = this.keyFor(event);
297
- const now = (/* @__PURE__ */ new Date()).toISOString();
298
- const existing = this.entries.get(key);
299
- if (existing) {
300
- existing.count++;
301
- existing.lastSeen = now;
302
- return;
303
- }
304
- if (this.entries.size >= _CsrfReadinessStore.MAX_ENTRIES) {
305
- const firstKey = this.entries.keys().next().value;
306
- if (firstKey !== void 0) this.entries.delete(firstKey);
307
- }
308
- this.entries.set(key, { count: 1, firstSeen: now, lastSeen: now });
309
- }
310
- summary() {
311
- let total = 0;
312
- const routes = [];
313
- for (const [key, entry] of this.entries) {
314
- const [method, path, reason] = key.split("\0");
315
- routes.push({
316
- method,
317
- path,
318
- reason,
319
- count: entry.count,
320
- firstSeen: entry.firstSeen,
321
- lastSeen: entry.lastSeen
322
- });
323
- total += entry.count;
324
- }
325
- return {
326
- generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
327
- totalEvents: total,
328
- routes
329
- };
330
- }
331
- reset() {
332
- this.entries.clear();
333
- }
334
- };
335
-
336
298
  // src/vite-plugin/action-middleware.ts
337
299
  import { randomUUID } from "crypto";
338
300
  var PREFIX = "/api/__actions/";
@@ -416,361 +378,6 @@ function createActionMiddleware(vite, serverDir, options) {
416
378
  };
417
379
  }
418
380
 
419
- // src/server/http/batch-handler.ts
420
- import { z } from "zod";
421
- var STRIPPED_HEADERS = [
422
- "authorization",
423
- "cookie",
424
- "x-forwarded-for",
425
- "x-forwarded-host",
426
- "x-forwarded-proto",
427
- "x-real-ip",
428
- "host"
429
- ];
430
- var BATCH_PATH = "/api/__theo_batch__";
431
- var DEFAULT_MAX_BATCH = 32;
432
- var batchRequestSchema = z.object({
433
- path: z.string().min(1),
434
- method: z.string().min(1),
435
- query: z.record(z.string(), z.unknown()).optional(),
436
- body: z.unknown().optional(),
437
- headers: z.record(z.string(), z.string()).optional()
438
- });
439
- var batchPayloadSchema = z.object({
440
- requests: z.array(batchRequestSchema).min(1)
441
- });
442
- function sanitizeItemHeaders(itemHeaders, outerHeaders) {
443
- const out = {};
444
- if (itemHeaders) {
445
- for (const [k, v] of Object.entries(itemHeaders)) {
446
- const lower = k.toLowerCase();
447
- if (!STRIPPED_HEADERS.includes(lower)) {
448
- out[lower] = v;
449
- }
450
- }
451
- }
452
- if (outerHeaders) {
453
- for (const stripped of STRIPPED_HEADERS) {
454
- if (Object.hasOwn(outerHeaders, stripped)) {
455
- out[stripped] = outerHeaders[stripped];
456
- }
457
- }
458
- }
459
- return out;
460
- }
461
- async function handleBatchRequest(payload, options) {
462
- const parsed = batchPayloadSchema.parse(payload);
463
- const max = options.max ?? DEFAULT_MAX_BATCH;
464
- if (parsed.requests.length > max) {
465
- throw new Error(`Batch size ${parsed.requests.length} exceeds max ${max}`);
466
- }
467
- const results = [];
468
- for (const item of parsed.requests) {
469
- const sanitized = {
470
- ...item,
471
- headers: sanitizeItemHeaders(item.headers, options.outerHeaders)
472
- };
473
- try {
474
- const r = await options.execute(sanitized);
475
- results.push(r);
476
- } catch (err) {
477
- const message = err instanceof Error ? err.message : String(err);
478
- results.push({ error: { message } });
479
- }
480
- }
481
- return { results };
482
- }
483
-
484
- // src/server/http/cors.ts
485
- var DEFAULT_METHODS = ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS", "HEAD"];
486
- var DEFAULT_ALLOWED_HEADERS = ["Content-Type", "X-Theo-Action", "Authorization"];
487
- var DEFAULT_MAX_AGE = 600;
488
- function readOrigin(req) {
489
- const raw = req.headers.origin;
490
- if (raw === void 0) return void 0;
491
- if (Array.isArray(raw)) {
492
- return raw.find((v) => typeof v === "string" && v.length > 0);
493
- }
494
- return raw;
495
- }
496
- function matchesOrigin(origin, allowed) {
497
- if (allowed === "*") return true;
498
- if (typeof allowed === "string") return origin === allowed;
499
- if (allowed instanceof RegExp) {
500
- allowed.lastIndex = 0;
501
- return allowed.test(origin);
502
- }
503
- if (Array.isArray(allowed)) {
504
- for (const entry of allowed) {
505
- if (typeof entry === "string" && origin === entry) return true;
506
- if (entry instanceof RegExp) {
507
- entry.lastIndex = 0;
508
- if (entry.test(origin)) return true;
509
- }
510
- }
511
- return false;
512
- }
513
- if (typeof allowed === "function") {
514
- try {
515
- return allowed(origin);
516
- } catch {
517
- return false;
518
- }
519
- }
520
- return false;
521
- }
522
- function createCorsHandler(config) {
523
- const methods = (config.methods ?? DEFAULT_METHODS).slice();
524
- const allowedHeaders = (config.allowedHeaders ?? DEFAULT_ALLOWED_HEADERS).slice();
525
- const maxAge = String(config.maxAge ?? DEFAULT_MAX_AGE);
526
- const credentials = config.credentials === true;
527
- return {
528
- handlePreflight(req, res) {
529
- if (req.method !== "OPTIONS") return false;
530
- const acMethod = req.headers["access-control-request-method"];
531
- if (!acMethod) return false;
532
- const origin = readOrigin(req);
533
- if (!origin) return false;
534
- if (!matchesOrigin(origin, config.origins)) {
535
- res.statusCode = 403;
536
- res.end();
537
- return true;
538
- }
539
- res.setHeader("Access-Control-Allow-Origin", origin);
540
- res.setHeader("Access-Control-Allow-Methods", methods.join(", "));
541
- res.setHeader("Access-Control-Allow-Headers", allowedHeaders.join(", "));
542
- res.setHeader("Access-Control-Max-Age", maxAge);
543
- res.setHeader("Vary", "Origin");
544
- if (credentials) res.setHeader("Access-Control-Allow-Credentials", "true");
545
- res.statusCode = 204;
546
- res.end();
547
- return true;
548
- },
549
- applyHeaders(req, res) {
550
- const origin = readOrigin(req);
551
- if (!origin) return;
552
- if (!matchesOrigin(origin, config.origins)) return;
553
- res.setHeader("Access-Control-Allow-Origin", origin);
554
- res.setHeader("Vary", "Origin");
555
- if (credentials) res.setHeader("Access-Control-Allow-Credentials", "true");
556
- if (config.exposedHeaders && config.exposedHeaders.length > 0) {
557
- res.setHeader("Access-Control-Expose-Headers", config.exposedHeaders.join(", "));
558
- }
559
- }
560
- };
561
- }
562
-
563
- // src/server/http/trace-context.ts
564
- var TRACE_HEADER = "x-trace-id";
565
- var TRACE_PARENT_HEADER = "traceparent";
566
- var REQUEST_ID_HEADER = "x-request-id";
567
- var TRACEPARENT_RE = /^00-([0-9a-f]{32})-([0-9a-f]{16})-[0-9a-f]{2}$/;
568
- function parseTraceparent(value) {
569
- if (!value) return null;
570
- const m = TRACEPARENT_RE.exec(value);
571
- if (!m) return null;
572
- const traceId = m[1];
573
- if (/^0+$/.test(traceId)) return null;
574
- return traceId;
575
- }
576
- function pickHeader(value) {
577
- if (Array.isArray(value)) {
578
- for (const v of value) {
579
- if (typeof v === "string" && v.length > 0) return v;
580
- }
581
- return null;
582
- }
583
- if (typeof value === "string" && value.length > 0) return value;
584
- return null;
585
- }
586
- function resolveTraceIdFromHeaders(traceparent, requestId) {
587
- if (traceparent !== null) {
588
- const parsed = parseTraceparent(traceparent);
589
- if (parsed !== null) return parsed;
590
- }
591
- if (requestId !== null) return requestId;
592
- return globalThis.crypto.randomUUID();
593
- }
594
- function extractTraceId(req) {
595
- return resolveTraceIdFromHeaders(
596
- pickHeader(req.headers[TRACE_PARENT_HEADER]),
597
- pickHeader(req.headers[REQUEST_ID_HEADER])
598
- );
599
- }
600
-
601
- // src/server/security/csp-report.ts
602
- var CSP_REPORT_PATH = "/__theo/csp-report";
603
- var MAX_BODY = 16 * 1024;
604
- function pickHeader2(value) {
605
- if (typeof value === "string") return value;
606
- if (Array.isArray(value) && value.length > 0) return value[0];
607
- return "";
608
- }
609
- function toStringSafe(value, fallback = "(missing)") {
610
- if (typeof value === "string") return value;
611
- if (typeof value === "number" || typeof value === "boolean") return String(value);
612
- return fallback;
613
- }
614
- function normalizeLegacy(raw) {
615
- return {
616
- blockedUrl: toStringSafe(raw["blocked-uri"]),
617
- documentUrl: toStringSafe(raw["document-uri"]),
618
- violatedDirective: toStringSafe(raw["violated-directive"]),
619
- effectiveDirective: typeof raw["effective-directive"] === "string" ? raw["effective-directive"] : void 0,
620
- originalPolicy: typeof raw["original-policy"] === "string" ? raw["original-policy"] : void 0,
621
- disposition: raw.disposition === "enforce" || raw.disposition === "report" ? raw.disposition : void 0,
622
- statusCode: typeof raw["status-code"] === "number" ? raw["status-code"] : void 0,
623
- sourceFile: typeof raw["source-file"] === "string" ? raw["source-file"] : void 0,
624
- lineNumber: typeof raw["line-number"] === "number" ? raw["line-number"] : void 0,
625
- columnNumber: typeof raw["column-number"] === "number" ? raw["column-number"] : void 0
626
- };
627
- }
628
- function normalizeNew(entry) {
629
- if (!entry || typeof entry !== "object") return null;
630
- const body = entry.body;
631
- if (!body || typeof body !== "object") return null;
632
- const b = body;
633
- return {
634
- blockedUrl: toStringSafe(b.blockedURL),
635
- documentUrl: toStringSafe(b.documentURL),
636
- violatedDirective: toStringSafe(b.violatedDirective),
637
- effectiveDirective: typeof b.effectiveDirective === "string" ? b.effectiveDirective : void 0,
638
- originalPolicy: typeof b.originalPolicy === "string" ? b.originalPolicy : void 0,
639
- disposition: b.disposition === "enforce" || b.disposition === "report" ? b.disposition : void 0,
640
- statusCode: typeof b.statusCode === "number" ? b.statusCode : void 0,
641
- sourceFile: typeof b.sourceFile === "string" ? b.sourceFile : void 0,
642
- lineNumber: typeof b.lineNumber === "number" ? b.lineNumber : void 0,
643
- columnNumber: typeof b.columnNumber === "number" ? b.columnNumber : void 0
644
- };
645
- }
646
- async function readBody(req, maxBytes) {
647
- return await new Promise((resolve8, reject) => {
648
- const chunks = [];
649
- let total = 0;
650
- req.on("data", (chunk) => {
651
- total += chunk.length;
652
- if (total > maxBytes) {
653
- reject(new Error("body too large"));
654
- req.destroy();
655
- return;
656
- }
657
- chunks.push(chunk);
658
- });
659
- req.on("end", () => {
660
- resolve8(Buffer.concat(chunks).toString("utf8"));
661
- });
662
- req.on("error", reject);
663
- });
664
- }
665
- async function handleCspReport(req, res, opts) {
666
- const ctHeader = req.headers["content-type"];
667
- const ct = pickHeader2(ctHeader);
668
- let raw;
669
- try {
670
- raw = await readBody(req, MAX_BODY);
671
- } catch {
672
- res.statusCode = 413;
673
- res.end();
674
- return;
675
- }
676
- let violations;
677
- try {
678
- if (ct.startsWith("application/csp-report")) {
679
- const parsed = JSON.parse(raw);
680
- const inner = parsed["csp-report"];
681
- if (!inner || typeof inner !== "object") {
682
- res.statusCode = 204;
683
- res.end();
684
- return;
685
- }
686
- violations = [normalizeLegacy(inner)];
687
- } else if (ct.startsWith("application/reports+json")) {
688
- const parsed = JSON.parse(raw);
689
- const entries = Array.isArray(parsed) ? parsed : [];
690
- violations = entries.map((e) => normalizeNew(e)).filter((v) => v !== null);
691
- } else {
692
- res.statusCode = 415;
693
- res.end();
694
- return;
695
- }
696
- } catch {
697
- res.statusCode = 400;
698
- res.end();
699
- return;
700
- }
701
- for (const v of violations) {
702
- safeAudit(opts.auditLogger, {
703
- action: "csp.violation",
704
- metadata: v
705
- });
706
- try {
707
- opts.devtoolsDispatcher?.onCspViolation?.(v);
708
- } catch {
709
- }
710
- try {
711
- opts.onViolation?.(v);
712
- } catch {
713
- }
714
- }
715
- res.statusCode = 204;
716
- res.end();
717
- }
718
-
719
- // src/server/security/csrf-readiness-endpoint.ts
720
- var CSRF_READINESS_PATH = "/__theo/csrf-readiness";
721
- var CSRF_READINESS_RESET_PATH = "/__theo/csrf-readiness/reset";
722
- function originMatchesHost(req) {
723
- const origin = req.headers.origin;
724
- if (typeof origin !== "string") return false;
725
- const host = req.headers.host;
726
- if (typeof host !== "string") return false;
727
- try {
728
- const parsed = new URL(origin);
729
- return parsed.host === host;
730
- } catch {
731
- return false;
732
- }
733
- }
734
- function sendJson(res, status, body) {
735
- res.writeHead(status, { "content-type": "application/json" });
736
- res.end(JSON.stringify(body));
737
- }
738
- function sendNoContent(res) {
739
- res.writeHead(204);
740
- res.end();
741
- }
742
- function sendError2(res, status, code, message) {
743
- res.writeHead(status, { "content-type": "application/json" });
744
- res.end(JSON.stringify({ error: { code, message } }));
745
- }
746
- async function handleCsrfReadiness(req, res, store) {
747
- const url = (req.url ?? "").split("?")[0];
748
- const method = req.method ?? "GET";
749
- if (url === CSRF_READINESS_PATH) {
750
- if (method === "GET") {
751
- sendJson(res, 200, store.summary());
752
- return true;
753
- }
754
- sendError2(res, 405, "METHOD_NOT_ALLOWED", `Use GET on ${CSRF_READINESS_PATH}`);
755
- return true;
756
- }
757
- if (url === CSRF_READINESS_RESET_PATH) {
758
- if (method !== "POST") {
759
- sendError2(res, 405, "METHOD_NOT_ALLOWED", `Use POST on ${CSRF_READINESS_RESET_PATH}`);
760
- return true;
761
- }
762
- const hasHeader = req.headers["x-theo-action"] === "1";
763
- if (!hasHeader || !originMatchesHost(req)) {
764
- sendError2(res, 403, "CSRF_INVALID", "Reset requires X-Theo-Action: 1 + same-origin");
765
- return true;
766
- }
767
- store.reset();
768
- sendNoContent(res);
769
- return true;
770
- }
771
- return false;
772
- }
773
-
774
381
  // src/vite-plugin/api-middleware.ts
775
382
  function shouldBypassApiMiddleware(url, prefixes) {
776
383
  if (!url.startsWith("/api/")) return true;
@@ -1145,7 +752,7 @@ async function runConfigureServer(server, ctx) {
1145
752
  server.watcher.on("unlink", handleRouteChange);
1146
753
  if (ctx.resolvedOpenApi !== void 0) {
1147
754
  const openApiCfg = ctx.resolvedOpenApi;
1148
- const { reEmitOpenApi } = await import("./dev-emit-66FCOS7V.js");
755
+ const { reEmitOpenApi } = await import("./dev-emit-OUPI7NAQ.js");
1149
756
  const openApiServerDir = resolve4(ctx.projectRoot, "server");
1150
757
  const openApiDistDir = resolve4(ctx.projectRoot, ctx.resolvedDistDir);
1151
758
  const isRouteFileForOpenApi = (file) => file.startsWith(openApiServerDir) && /\.(ts|tsx|js|mjs)$/.test(file);
@@ -1838,6 +1445,11 @@ function safeVarName(segment, prefix) {
1838
1445
  const safe = segment.replace(/[^a-zA-Z0-9]/g, "_") || "root";
1839
1446
  return `${prefix}_${safe}`;
1840
1447
  }
1448
+ function segmentPath(node) {
1449
+ if (node.dynamic?.catchAll) return "*";
1450
+ if (node.dynamic) return `:${node.dynamic.paramName}`;
1451
+ return node.segment;
1452
+ }
1841
1453
  function buildRoutePath(parents, segment) {
1842
1454
  const joined = [...parents, segment].filter(Boolean).join("/");
1843
1455
  return "/" + joined;
@@ -1849,7 +1461,7 @@ function pushIf(staticImports, filePath, varName) {
1849
1461
  }
1850
1462
  function walkRouteTree(node, parents, acc) {
1851
1463
  const seg = node.segment || "root";
1852
- const routePath = buildRoutePath(parents, node.segment);
1464
+ const routePath = buildRoutePath(parents, segmentPath(node));
1853
1465
  if (node.page !== void 0) {
1854
1466
  acc.lazyPages.push({
1855
1467
  varName: safeVarName(seg, "Page"),
@@ -1863,7 +1475,8 @@ function walkRouteTree(node, parents, acc) {
1863
1475
  pushIf(acc.staticImports, node.loading, safeVarName(seg, "Loading"));
1864
1476
  pushIf(acc.staticImports, node.notFound, safeVarName(seg, "NotFound"));
1865
1477
  for (const child of node.children) {
1866
- const nextParents = node.segment ? [...parents, node.segment] : parents;
1478
+ const childSegPath = segmentPath(node);
1479
+ const nextParents = childSegPath ? [...parents, childSegPath] : parents;
1867
1480
  walkRouteTree(child, nextParents, acc);
1868
1481
  }
1869
1482
  }
@@ -1922,7 +1535,7 @@ function generateRouteManifest(tree) {
1922
1535
  const childrenArray = buildChildrenArray(node, seg);
1923
1536
  if (node.layout) {
1924
1537
  const layoutVar = safeVarName(seg, "Layout");
1925
- const pathPart = isRoot ? `path: '/'` : `path: '${node.segment}'`;
1538
+ const pathPart = isRoot ? `path: '/'` : `path: '${segmentPath(node)}'`;
1926
1539
  return `{ ${pathPart}, element: React.createElement(${layoutVar}, { children: React.createElement(Outlet) }), children: ${childrenArray} }`;
1927
1540
  }
1928
1541
  if (isRoot) {
@@ -1935,9 +1548,9 @@ function generateRouteManifest(tree) {
1935
1548
  const pageVar = safeVarName(seg, "Page");
1936
1549
  const fallbackEl = node.loading ? `React.createElement(${safeVarName(seg, "Loading")})` : "null";
1937
1550
  const pageElement = `React.createElement(Suspense, { fallback: ${fallbackEl} }, React.createElement(${pageVar}))`;
1938
- return `{ path: '${node.segment}', element: ${pageElement} }`;
1551
+ return `{ path: '${segmentPath(node)}', element: ${pageElement} }`;
1939
1552
  }
1940
- return `{ path: '${node.segment}', children: ${childrenArray} }`;
1553
+ return `{ path: '${segmentPath(node)}', children: ${childrenArray} }`;
1941
1554
  }
1942
1555
  const routeConfig = genRouteConfig(tree, true);
1943
1556
  lines.push(`export const routes = [${routeConfig}]`);
@@ -2117,7 +1730,7 @@ async function theoPluginAsync(rootOrOptions) {
2117
1730
  });
2118
1731
  const servicesPlugins = [];
2119
1732
  if (options.services && Object.keys(options.services).length > 0) {
2120
- const { servicesTypedClientPlugin } = await import("./services-typed-client-ASZL7FQV.js");
1733
+ const { servicesTypedClientPlugin } = await import("./services-typed-client-24VBMDOF.js");
2121
1734
  servicesPlugins.push(
2122
1735
  servicesTypedClientPlugin({
2123
1736
  cwd: projectRoot,
@@ -2125,13 +1738,13 @@ async function theoPluginAsync(rootOrOptions) {
2125
1738
  })
2126
1739
  );
2127
1740
  }
2128
- const { appTypedClientPlugin } = await import("./app-typed-client-4GIKUKRT.js");
1741
+ const { appTypedClientPlugin } = await import("./app-typed-client-SAETWZT5.js");
2129
1742
  const appClientPlugin = appTypedClientPlugin({
2130
1743
  cwd: projectRoot,
2131
1744
  serverDir: resolve7(projectRoot, "server"),
2132
1745
  distDir: resolve7(projectRoot, ".theokit")
2133
1746
  });
2134
- const { actionsVirtualModule } = await import("./actions-virtual-module-DL74V6SR.js");
1747
+ const { actionsVirtualModule } = await import("./actions-virtual-module-4WVKHQ2X.js");
2135
1748
  const actionsPlugin = actionsVirtualModule({
2136
1749
  serverDir: resolve7(projectRoot, "server"),
2137
1750
  distDir: resolve7(projectRoot, ".theokit")
@@ -2297,4 +1910,4 @@ export {
2297
1910
  theoPluginAsync,
2298
1911
  theoPlugin
2299
1912
  };
2300
- //# sourceMappingURL=chunk-JD7AQNJS.js.map
1913
+ //# sourceMappingURL=chunk-4I47JW5O.js.map