theokit 0.1.0-alpha.8 → 0.2.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 (138) hide show
  1. package/dist/actions-virtual-module-E6PU47GV.js +175 -0
  2. package/dist/actions-virtual-module-E6PU47GV.js.map +1 -0
  3. package/dist/actions-virtual-module-E7IELVHL.js +174 -0
  4. package/dist/actions-virtual-module-E7IELVHL.js.map +1 -0
  5. package/dist/add-2ZFFGGE4.js +0 -0
  6. package/dist/app-typed-client-4L4L4BWD.js +289 -0
  7. package/dist/app-typed-client-4L4L4BWD.js.map +1 -0
  8. package/dist/app-typed-client-6PAT6VOL.js +289 -0
  9. package/dist/app-typed-client-6PAT6VOL.js.map +1 -0
  10. package/dist/aws-lambda-PONVF3UX.js +0 -0
  11. package/dist/broadcast-QOQGUNNK.js +0 -0
  12. package/dist/{build-IQQYCA3B.js → build-EWZDEDT3.js} +37 -11
  13. package/dist/build-EWZDEDT3.js.map +1 -0
  14. package/dist/build-request-body-preview-EOP2Y4F3.js +52 -0
  15. package/dist/build-request-body-preview-EOP2Y4F3.js.map +1 -0
  16. package/dist/build-request-body-preview-II2235E6.js +54 -0
  17. package/dist/build-request-body-preview-II2235E6.js.map +1 -0
  18. package/dist/bun-DITMZMKL.js +0 -0
  19. package/dist/check-PZR67OY5.js +0 -0
  20. package/dist/{chunk-GQSTRXXB.js → chunk-2BQYEBCK.js} +77 -68
  21. package/dist/chunk-2BQYEBCK.js.map +1 -0
  22. package/dist/{chunk-FRBYJANT.js → chunk-4W447H7M.js} +195 -41
  23. package/dist/chunk-4W447H7M.js.map +1 -0
  24. package/dist/chunk-5ODOE6EF.js +0 -0
  25. package/dist/chunk-7DHGV77J.js +140 -0
  26. package/dist/chunk-7DHGV77J.js.map +1 -0
  27. package/dist/{chunk-WQCPKA2L.js → chunk-C27AZN46.js} +570 -165
  28. package/dist/chunk-C27AZN46.js.map +1 -0
  29. package/dist/chunk-ERAZNHHR.js +73 -0
  30. package/dist/chunk-ERAZNHHR.js.map +1 -0
  31. package/dist/chunk-F3TG5FJV.js +97 -0
  32. package/dist/chunk-F3TG5FJV.js.map +1 -0
  33. package/dist/chunk-KJVEJILQ.js +109 -0
  34. package/dist/chunk-KJVEJILQ.js.map +1 -0
  35. package/dist/chunk-KT3MWNZG.js +0 -0
  36. package/dist/{chunk-MCP6Y5BA.js → chunk-M23FP2AS.js} +25 -1
  37. package/dist/chunk-M23FP2AS.js.map +1 -0
  38. package/dist/{chunk-S3JBIFKS.js → chunk-MG7H3LAW.js} +2 -2
  39. package/dist/chunk-MOT42NAH.js +165 -0
  40. package/dist/chunk-MOT42NAH.js.map +1 -0
  41. package/dist/chunk-O7335ZGH.js +0 -0
  42. package/dist/{chunk-OEB3OIYP.js → chunk-OJHO2X7C.js} +497 -168
  43. package/dist/chunk-OJHO2X7C.js.map +1 -0
  44. package/dist/chunk-QLGES2HC.js +189 -0
  45. package/dist/chunk-QLGES2HC.js.map +1 -0
  46. package/dist/{chunk-JZ5WEG3S.js → chunk-SEVYARIU.js} +9 -5
  47. package/dist/chunk-SEVYARIU.js.map +1 -0
  48. package/dist/{chunk-ZK5JCE5J.js → chunk-TFECHXR5.js} +201 -43
  49. package/dist/chunk-TFECHXR5.js.map +1 -0
  50. package/dist/chunk-WSJKACWB.js +17 -0
  51. package/dist/chunk-WSJKACWB.js.map +1 -0
  52. package/dist/chunk-WZ7CPVQB.js +0 -0
  53. package/dist/chunk-XMS5VRIK.js +0 -0
  54. package/dist/chunk-Y5KE6YFP.js +0 -0
  55. package/dist/{chunk-3Q36SEDK.js → chunk-ZBWROIIO.js} +43 -2
  56. package/dist/{chunk-3Q36SEDK.js.map → chunk-ZBWROIIO.js.map} +1 -1
  57. package/dist/chunk-ZOXNJV2O.js +358 -0
  58. package/dist/chunk-ZOXNJV2O.js.map +1 -0
  59. package/dist/cli/index.js +22 -7
  60. package/dist/cli/index.js.map +1 -1
  61. package/dist/client/index.d.ts +31 -1
  62. package/dist/client/index.js +100 -0
  63. package/dist/client/index.js.map +1 -1
  64. package/dist/cloudflare-RBANU3SE.js +0 -0
  65. package/dist/configure-agent-registry-6YGTJYBC.js +0 -0
  66. package/dist/deno-deploy-J7LI6HNL.js +0 -0
  67. package/dist/{dev-VN6WS3CM.js → dev-74KPI5C5.js} +15 -7
  68. package/dist/dev-74KPI5C5.js.map +1 -0
  69. package/dist/dev-emit-3CHM73TV.js +390 -0
  70. package/dist/dev-emit-3CHM73TV.js.map +1 -0
  71. package/dist/dev-emit-I3CKOHML.js +44 -0
  72. package/dist/dev-emit-I3CKOHML.js.map +1 -0
  73. package/dist/devtools/entry.js +653 -243
  74. package/dist/devtools/entry.js.map +1 -1
  75. package/dist/dispatcher-AQJGI3HU.js +8 -0
  76. package/dist/dispatcher-E6QV32BO.js +83 -0
  77. package/dist/dispatcher-E6QV32BO.js.map +1 -0
  78. package/dist/{dist-UZV7J3YI.js → dist-R2Q7GVDW.js} +10412 -11961
  79. package/dist/dist-R2Q7GVDW.js.map +1 -0
  80. package/dist/docker-EZDA5FT7.js +0 -0
  81. package/dist/{generate-SIO4JSKJ.js → generate-DT4IIAHF.js} +88 -22
  82. package/dist/generate-DT4IIAHF.js.map +1 -0
  83. package/dist/index.d.ts +108 -1
  84. package/dist/index.js +5 -2
  85. package/dist/index.js.map +1 -1
  86. package/dist/{info-B3UOXFUF.js → info-VM7EK4JC.js} +3 -3
  87. package/dist/lib-NST3PNZX.js +0 -0
  88. package/dist/netlify-IFY6ZGFV.js +0 -0
  89. package/dist/node-KWZI3CKV.js +0 -0
  90. package/dist/openapi-CBASKC7W.js +84 -0
  91. package/dist/openapi-CBASKC7W.js.map +1 -0
  92. package/dist/proper-lockfile-MVKMQGFK.js +0 -0
  93. package/dist/{registry-BB3UYAOG.js → registry-QGSNLJKJ.js} +2 -2
  94. package/dist/{routes-CAGFZKUK.js → routes-7O4NUDYS.js} +9 -7
  95. package/dist/{routes-CAGFZKUK.js.map → routes-7O4NUDYS.js.map} +1 -1
  96. package/dist/scan-C2BOKLSY.js +0 -0
  97. package/dist/{schema-Cxq2qqwh.d.ts → schema-CjVly9c_.d.ts} +43 -1
  98. package/dist/{schema-MVB2FVK6.js → schema-JAKF23GR.js} +2 -2
  99. package/dist/server/cost/index.d.ts +7 -0
  100. package/dist/server/cost/index.js +1 -1
  101. package/dist/server/index.d.ts +219 -47
  102. package/dist/server/index.js +101 -114
  103. package/dist/server/index.js.map +1 -1
  104. package/dist/services-typed-client-ZX5JUHH3.js +0 -0
  105. package/dist/sqlite-vec-54KB4RD3.js +0 -0
  106. package/dist/{start-CSLJQXV3.js → start-5JTFWF4T.js} +20 -14
  107. package/dist/start-5JTFWF4T.js.map +1 -0
  108. package/dist/{static-BH6JQNM2.js → static-6PZZBY7G.js} +4 -4
  109. package/dist/storage-manager-D5KBXXKB.js +0 -0
  110. package/dist/theo-cloud-3K4DGB3S.js +0 -0
  111. package/dist/{upgrade-readiness-OHL36FQL.js → upgrade-readiness-Q46KTG2J.js} +6 -1
  112. package/dist/upgrade-readiness-Q46KTG2J.js.map +1 -0
  113. package/dist/vercel-RHADE5IP.js +0 -0
  114. package/dist/vite-plugin/index.d.ts +25 -1
  115. package/dist/vite-plugin/index.js +5 -2
  116. package/dist/{vite-plugin-WA3G45YY.js → vite-plugin-3EQP2JYM.js} +7 -6
  117. package/dist/vite-plugin-3EQP2JYM.js.map +1 -0
  118. package/package.json +10 -8
  119. package/LICENSE +0 -201
  120. package/dist/build-IQQYCA3B.js.map +0 -1
  121. package/dist/chunk-FRBYJANT.js.map +0 -1
  122. package/dist/chunk-GQSTRXXB.js.map +0 -1
  123. package/dist/chunk-JZ5WEG3S.js.map +0 -1
  124. package/dist/chunk-MCP6Y5BA.js.map +0 -1
  125. package/dist/chunk-OEB3OIYP.js.map +0 -1
  126. package/dist/chunk-WQCPKA2L.js.map +0 -1
  127. package/dist/chunk-ZK5JCE5J.js.map +0 -1
  128. package/dist/dev-VN6WS3CM.js.map +0 -1
  129. package/dist/dist-UZV7J3YI.js.map +0 -1
  130. package/dist/generate-SIO4JSKJ.js.map +0 -1
  131. package/dist/start-CSLJQXV3.js.map +0 -1
  132. package/dist/upgrade-readiness-OHL36FQL.js.map +0 -1
  133. /package/dist/{chunk-S3JBIFKS.js.map → chunk-MG7H3LAW.js.map} +0 -0
  134. /package/dist/{schema-MVB2FVK6.js.map → dispatcher-AQJGI3HU.js.map} +0 -0
  135. /package/dist/{info-B3UOXFUF.js.map → info-VM7EK4JC.js.map} +0 -0
  136. /package/dist/{registry-BB3UYAOG.js.map → registry-QGSNLJKJ.js.map} +0 -0
  137. /package/dist/{vite-plugin-WA3G45YY.js.map → schema-JAKF23GR.js.map} +0 -0
  138. /package/dist/{static-BH6JQNM2.js.map → static-6PZZBY7G.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/server/scan/match.ts","../src/server/scan/scan.ts","../src/server/scan/detect-http-methods.ts","../src/server/scan/ws-scan.ts"],"sourcesContent":["export interface ServerRouteNode {\n filePath: string\n routePath: string\n paramNames: string[]\n pattern: RegExp\n /** HTTP methods (uppercase) the route file exports. Optional for backward\n * compatibility with manifests generated before G1. Empty array means the\n * file has no HTTP exports (util-only); undefined means \"not detected\". */\n methods?: string[]\n}\n\nexport function compilePattern(routePath: string): {\n pattern: RegExp\n paramNames: string[]\n} {\n const paramNames: string[] = []\n // Single pass: handle both catch-all (:...name) and regular (:name) params\n const regexStr = routePath.replace(/:(?:\\.\\.\\.)?([^/]+)/g, (match: string, name: string) => {\n paramNames.push(name)\n // Catch-all matches across slashes, regular matches single segment\n return match.startsWith(':...') ? '(.+)' : '([^/]+)'\n })\n // `regexStr` is derived from a developer-authored route path (build-time\n // input, not HTTP-controlled). The `security/detect-non-literal-regexp`\n // rule cannot see this constraint — disable narrowly.\n // eslint-disable-next-line security/detect-non-literal-regexp -- route pattern from build-time scan, never HTTP input\n return { pattern: new RegExp(`^${regexStr}$`), paramNames }\n}\n\nexport function matchRoute(\n url: string,\n routes: ServerRouteNode[],\n): { route: ServerRouteNode; params: Record<string, string> } | null {\n // Strip query string and trailing slash\n let path = url.split('?')[0]\n if (path.length > 1 && path.endsWith('/')) {\n path = path.slice(0, -1)\n }\n\n for (const route of routes) {\n const match = route.pattern.exec(path)\n if (match) {\n const params: Record<string, string> = {}\n route.paramNames.forEach((name, i) => {\n params[name] = match[i + 1]\n })\n return { route, params }\n }\n }\n return null\n}\n","/* eslint-disable security/detect-non-literal-fs-filename --\n * Build-time scanner: walks `serverDir/routes/` derived from cwd.\n * No HTTP input ever reaches these fs calls.\n */\nimport { existsSync, statSync } from 'node:fs'\nimport { extname, join, relative } from 'node:path'\n\nimport { walkSourceFiles } from '../_internal/scan-walker.js'\n\nimport { detectExportedHttpMethods } from './detect-http-methods.js'\nimport { compilePattern, type ServerRouteNode } from './match.js'\n\nconst ROUTE_EXTENSIONS = new Set(['.ts', '.tsx', '.js', '.jsx'])\n\nfunction fileToRoutePath(filePath: string, routesDir: string): string {\n let rel = relative(routesDir, filePath)\n // Strip extension\n const ext = extname(rel)\n rel = rel.slice(0, -ext.length)\n // Normalize separators\n rel = rel.replace(/\\\\/g, '/')\n // Strip index suffix\n if (rel.endsWith('/index')) {\n rel = rel.slice(0, -6)\n } else if (rel === 'index') {\n rel = ''\n }\n // Replace [...param] with :...param (catch-all, before regular params).\n // Replace [param] with :param. Inputs are file paths bounded by the\n // OS filename limit; the bracket capture is bounded by `]`.\n rel = rel.replace(/\\[\\.\\.\\.([^\\]]+)\\]/g, ':...$1')\n // eslint-disable-next-line sonarjs/slow-regex -- bounded by `]`; input is a single filename\n rel = rel.replace(/\\[([^\\]]+)\\]/g, ':$1')\n return `/api/${rel}`\n}\n\nexport function scanServerRoutes(serverDir: string): ServerRouteNode[] {\n const routesDir = join(serverDir, 'routes')\n if (!existsSync(routesDir) || !statSync(routesDir).isDirectory()) {\n return []\n }\n\n const results: ServerRouteNode[] = []\n walkSourceFiles(routesDir, { extensions: ROUTE_EXTENSIONS }, (absPath) => {\n const routePath = fileToRoutePath(absPath, routesDir)\n const { pattern, paramNames } = compilePattern(routePath)\n const methods = detectExportedHttpMethods(absPath)\n results.push({\n filePath: absPath,\n routePath,\n paramNames,\n pattern,\n methods,\n })\n })\n\n // T1.4 / EC-2 — refuse to scan if a user route collides with the reserved\n // batch endpoint path. User must rename or disable batching.\n const conflicting = results.find((r) => r.routePath === '/api/__theo_batch__')\n if (conflicting) {\n throw new Error(\n `Server route ${conflicting.filePath} resolves to '/api/__theo_batch__' which is reserved for the batch endpoint. Rename the route or disable batching in theo.config.ts.`,\n )\n }\n\n // Sort: static first, then dynamic, then catch-all last\n const isCatchAll = (route: ServerRouteNode) => route.routePath.includes(':...')\n results.sort((a, b) => {\n const aStatic = a.paramNames.length === 0\n const bStatic = b.paramNames.length === 0\n const aCatchAll = isCatchAll(a)\n const bCatchAll = isCatchAll(b)\n\n // Static routes first\n if (aStatic && !bStatic) return -1\n if (!aStatic && bStatic) return 1\n // Catch-all routes last\n if (aCatchAll && !bCatchAll) return 1\n if (!aCatchAll && bCatchAll) return -1\n return a.routePath.localeCompare(b.routePath)\n })\n\n return results\n}\n","/**\n * Detect which HTTP-method named exports a route file declares.\n *\n * Uses the TypeScript compiler API (not regex) per G1 edge-case review EC-4:\n * regex over file content emits false positives for `// export const GET = ...`\n * in comments and `` `export const GET = ...` `` in template literals. AST\n * walking avoids both classes of bug.\n *\n * `typescript` ships as CommonJS with internal dynamic `require('fs')`.\n * When loaded via ESM `import`, the dynamic requires fail at module-bootstrap.\n * We use `createRequire(import.meta.url)` to keep the package on its native\n * CJS path. The type-only namespace import gives us the AST helpers shape.\n *\n * Returns the set of HTTP methods (uppercase) the file exports. Empty array\n * means the file has no HTTP exports (the route file is util-only).\n */\n\nimport { readFileSync } from 'node:fs'\nimport { createRequire } from 'node:module'\n\nimport type * as TS from 'typescript'\n\nimport { HTTP_METHODS, type HttpMethod } from '../../core/contracts/http-methods.js'\n\nconst require_ = createRequire(import.meta.url)\n// eslint-disable-next-line @typescript-eslint/no-require-imports\nconst ts = require_('typescript') as typeof TS\n\nconst HTTP_METHOD_NAMES = new Set<string>(HTTP_METHODS)\n\nfunction hasExportModifier(modifiers: readonly TS.Modifier[] | undefined): boolean {\n if (!modifiers) return false\n for (const m of modifiers) {\n if (m.kind === ts.SyntaxKind.ExportKeyword) return true\n }\n return false\n}\n\nfunction collectFromStatement(stmt: TS.Statement, found: Set<HttpMethod>): void {\n // `export const GET = ...` / `export function GET ...` / `export async function GET ...`\n if (ts.isVariableStatement(stmt) && hasExportModifier(ts.getModifiers(stmt))) {\n for (const decl of stmt.declarationList.declarations) {\n if (ts.isIdentifier(decl.name) && HTTP_METHOD_NAMES.has(decl.name.text)) {\n found.add(decl.name.text as HttpMethod)\n }\n }\n return\n }\n\n if (\n (ts.isFunctionDeclaration(stmt) || ts.isClassDeclaration(stmt)) &&\n hasExportModifier(ts.getModifiers(stmt))\n ) {\n if (stmt.name && HTTP_METHOD_NAMES.has(stmt.name.text)) {\n found.add(stmt.name.text as HttpMethod)\n }\n return\n }\n\n // `export { GET }` / `export { handler as GET } from './shared'` (EC-5)\n if (ts.isExportDeclaration(stmt) && stmt.exportClause && ts.isNamedExports(stmt.exportClause)) {\n for (const spec of stmt.exportClause.elements) {\n // spec.name is the exported (re-)name; spec.propertyName is the original (when renamed)\n if (HTTP_METHOD_NAMES.has(spec.name.text)) {\n found.add(spec.name.text as HttpMethod)\n }\n }\n }\n}\n\nexport function detectExportedHttpMethods(filePath: string, content?: string): HttpMethod[] {\n const src = content ?? readFileSync(filePath, 'utf-8')\n const sourceFile = ts.createSourceFile(\n filePath,\n src,\n ts.ScriptTarget.Latest,\n /* setParentNodes */ false,\n ts.ScriptKind.TS,\n )\n const found = new Set<HttpMethod>()\n for (const stmt of sourceFile.statements) {\n collectFromStatement(stmt, found)\n }\n return [...found].sort()\n}\n","/* eslint-disable security/detect-non-literal-fs-filename --\n * Build-time scanner: walks `serverDir/ws/` derived from cwd.\n * No HTTP input ever reaches these fs calls.\n */\nimport { existsSync, statSync } from 'node:fs'\nimport { extname, join, relative } from 'node:path'\n\nimport { walkSourceFiles } from '../_internal/scan-walker.js'\n\nconst WS_EXTENSIONS = new Set(['.ts', '.tsx', '.js', '.jsx'])\n\nexport interface WebSocketRouteNode {\n filePath: string\n wsPath: string\n}\n\nexport function scanWebSocketRoutes(serverDir: string): WebSocketRouteNode[] {\n const wsDir = join(serverDir, 'ws')\n if (!existsSync(wsDir) || !statSync(wsDir).isDirectory()) {\n return []\n }\n\n const results: WebSocketRouteNode[] = []\n walkSourceFiles(wsDir, { extensions: WS_EXTENSIONS }, (absPath) => {\n let rel = relative(wsDir, absPath)\n rel = rel.replace(/\\\\/g, '/')\n rel = rel.slice(0, -extname(rel).length)\n if (rel.endsWith('/index')) rel = rel.slice(0, -6)\n else if (rel === 'index') rel = ''\n results.push({\n filePath: absPath,\n wsPath: `/ws/${rel}`,\n })\n })\n return results\n}\n"],"mappings":"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","names":["existsSync","statSync","extname","join","relative","join","existsSync","statSync","relative","extname"]}
@@ -8,6 +8,7 @@ import {
8
8
  import {
9
9
  BATCH_PATH,
10
10
  CSP_REPORT_PATH,
11
+ CsrfReadinessStore,
11
12
  TRACE_HEADER,
12
13
  applySecurityHeaders,
13
14
  createCorsHandler,
@@ -23,13 +24,17 @@ import {
23
24
  handleCsrfReadiness,
24
25
  loadEnv,
25
26
  logRequest,
26
- matchRoute,
27
27
  resolveTransformer,
28
- scanServerActions,
29
- scanServerRoutes,
30
- scanWebSocketRoutes,
31
28
  sendError
32
- } from "./chunk-OEB3OIYP.js";
29
+ } from "./chunk-OJHO2X7C.js";
30
+ import {
31
+ matchRoute,
32
+ scanServerRoutes,
33
+ scanWebSocketRoutes
34
+ } from "./chunk-2BQYEBCK.js";
35
+ import {
36
+ scanServerActions
37
+ } from "./chunk-7DHGV77J.js";
33
38
  import {
34
39
  generateNonce
35
40
  } from "./chunk-PB4GR7EP.js";
@@ -612,13 +617,17 @@ function createActionMiddleware(vite, serverDir, options) {
612
617
  csrfMode,
613
618
  disallowed
614
619
  );
615
- logRequest({
616
- method: req.method ?? "POST",
617
- url,
618
- status: res.statusCode,
619
- duration: Date.now() - start,
620
- requestId
621
- });
620
+ logRequest(
621
+ {
622
+ method: req.method ?? "POST",
623
+ url,
624
+ status: res.statusCode,
625
+ duration: Date.now() - start,
626
+ requestId
627
+ },
628
+ void 0,
629
+ req
630
+ );
622
631
  })();
623
632
  };
624
633
  }
@@ -698,6 +707,35 @@ async function handleBatchInline(req, res, batching, requestId) {
698
707
  sendError(res, "BATCH_ERROR", message, 400, void 0, requestId);
699
708
  }
700
709
  }
710
+ async function runPluginsBeforeRouteMatch(pluginRunner, reqCtx) {
711
+ const { req, res, requestId, start, url } = reqCtx;
712
+ try {
713
+ const hookResult = await pluginRunner.runOnRequest({
714
+ request: req,
715
+ response: res,
716
+ ctx: {},
717
+ requestId
718
+ });
719
+ if (hookResult.shortCircuited) {
720
+ logRequest(
721
+ {
722
+ method: req.method ?? "GET",
723
+ url,
724
+ status: res.statusCode,
725
+ duration: Date.now() - start,
726
+ requestId
727
+ },
728
+ void 0,
729
+ req
730
+ );
731
+ return true;
732
+ }
733
+ } catch (err) {
734
+ sendError(res, "PLUGIN_ERROR", err.message, 500, void 0, requestId);
735
+ return true;
736
+ }
737
+ return false;
738
+ }
701
739
  function createApiMiddleware(vite, serverDir, rateLimitConfigOrOptions) {
702
740
  const opts = rateLimitConfigOrOptions && "windowMs" in rateLimitConfigOrOptions ? { rateLimitConfig: rateLimitConfigOrOptions } : rateLimitConfigOrOptions ?? {};
703
741
  const loadModule = createViteLoader(vite);
@@ -715,7 +753,7 @@ function createApiMiddleware(vite, serverDir, rateLimitConfigOrOptions) {
715
753
  const csrfReadinessStore = opts.csrfReadinessStore;
716
754
  const servicesProxyPrefixes = opts.servicesProxyPrefixes ?? [];
717
755
  return (req, res, next) => {
718
- void (async () => {
756
+ const handle = async () => {
719
757
  const url = req.url ?? "";
720
758
  if (await handleCspReportIfMatch(req, res, url, { auditLogger, onCspViolation })) {
721
759
  return;
@@ -739,6 +777,9 @@ function createApiMiddleware(vite, serverDir, rateLimitConfigOrOptions) {
739
777
  if (applyRateLimitOr429(req, res, { rateLimiter, requestId, url, start })) {
740
778
  return;
741
779
  }
780
+ if (pluginRunner && await runPluginsBeforeRouteMatch(pluginRunner, { req, res, requestId, start, url })) {
781
+ return;
782
+ }
742
783
  if (await handleBatchIfMatch(req, res, { url, batching, requestId, start })) {
743
784
  return;
744
785
  }
@@ -750,13 +791,17 @@ function createApiMiddleware(vite, serverDir, rateLimitConfigOrOptions) {
750
791
  const suggestion = findSuggestion(urlPath, routePaths);
751
792
  const msg = suggestion ? `API route not found: ${urlPath}. Did you mean: ${suggestion}?` : "API route not found";
752
793
  sendError(res, "NOT_FOUND", msg, 404, void 0, requestId);
753
- logRequest({
754
- method: req.method ?? "GET",
755
- url,
756
- status: 404,
757
- duration: Date.now() - start,
758
- requestId
759
- });
794
+ logRequest(
795
+ {
796
+ method: req.method ?? "GET",
797
+ url,
798
+ status: 404,
799
+ duration: Date.now() - start,
800
+ requestId
801
+ },
802
+ void 0,
803
+ req
804
+ );
760
805
  return;
761
806
  }
762
807
  const method = (req.method ?? "GET").toUpperCase();
@@ -774,8 +819,13 @@ function createApiMiddleware(vite, serverDir, rateLimitConfigOrOptions) {
774
819
  csrfMode,
775
820
  disallowed
776
821
  });
777
- logRequest({ method, url, status: res.statusCode, duration: Date.now() - start, requestId });
778
- })();
822
+ logRequest(
823
+ { method, url, status: res.statusCode, duration: Date.now() - start, requestId },
824
+ void 0,
825
+ req
826
+ );
827
+ };
828
+ void handle();
779
829
  };
780
830
  }
781
831
 
@@ -1039,6 +1089,21 @@ var theoConfigSchema = z.object({
1039
1089
  * matching `--target`, `theokit build` emits a cross-reference note.
1040
1090
  */
1041
1091
  adapters: z.array(z.string()).optional(),
1092
+ /**
1093
+ * Extra package names to pre-bundle via Vite's `optimizeDeps.include`.
1094
+ *
1095
+ * Framework auto-includes `@usetheo/ui` and `lucide-react` when present.
1096
+ * Apps adding plugin peer-deps that rely on a runtime `import('<pkg>')`
1097
+ * (dynamic specifier) — e.g. `@theokit/plugin-canvas` consumers
1098
+ * installing `mermaid` for Mermaid SVG rendering — must declare those
1099
+ * here so Vite can resolve the literal in dev mode without
1100
+ * "Failed to resolve module specifier" errors. Production builds use
1101
+ * tsup/esbuild bundling and are not affected.
1102
+ *
1103
+ * Example:
1104
+ * viteOptimizeDeps: ['mermaid']
1105
+ */
1106
+ viteOptimizeDeps: z.array(z.string()).optional(),
1042
1107
  /**
1043
1108
  * Jobs backend (ADR D3 + T2.1). When configured, every request gets
1044
1109
  * `ctx.queue.enqueue` auto-wired via the outbox lifecycle. Pass a
@@ -1065,7 +1130,33 @@ var theoConfigSchema = z.object({
1065
1130
  * that boot alongside the TheoKit TS app. Empty `services: {}` is the
1066
1131
  * default and preserves Wave 1 behavior.
1067
1132
  */
1068
- services: servicesConfigSchema
1133
+ services: servicesConfigSchema,
1134
+ /**
1135
+ * G2 — OpenAPI emit (build-time only).
1136
+ *
1137
+ * When present, `theokit build` writes a generated `openapi.json` from
1138
+ * every `defineRoute()` body/query/params Zod schema. `undefined` keeps
1139
+ * the framework backward-compatible (no emit). Pass `openapi: {}` to
1140
+ * opt in with defaults.
1141
+ *
1142
+ * Defaults: spec 3.1.0 · servers `http://localhost:3000` · title
1143
+ * "TheoKit App" · version "0.0.0" · outDir ".theo" (next to dist).
1144
+ *
1145
+ * The env var `THEOKIT_OPENAPI_SERVERS` (CSV of URLs) overrides
1146
+ * `servers[].url` at emit time without rebuilding the config.
1147
+ */
1148
+ openapi: z.object({
1149
+ servers: z.array(
1150
+ z.object({
1151
+ url: z.string().url(),
1152
+ description: z.string().optional()
1153
+ })
1154
+ ).default([{ url: "http://localhost:3000", description: "Local development" }]),
1155
+ specVersion: z.enum(["3.1.0", "3.0.3"]).default("3.1.0"),
1156
+ title: z.string().default("TheoKit App"),
1157
+ version: z.string().default("0.0.0"),
1158
+ outDir: z.string().default(".theo")
1159
+ }).optional()
1069
1160
  }).refine((cfg) => !Object.values(cfg.services).some((s) => s.port === cfg.port), {
1070
1161
  message: "service.port collides with TheoKit web port \u2014 change one of them",
1071
1162
  path: ["services"]
@@ -1164,7 +1255,7 @@ function resolveExportSubpath(pkgRoot, subpath) {
1164
1255
  }
1165
1256
  let target;
1166
1257
  if (typeof exp === "string") target = exp;
1167
- else if (exp && typeof exp === "object") {
1258
+ else if (typeof exp === "object") {
1168
1259
  const e = exp;
1169
1260
  target = e.import ?? e.default;
1170
1261
  }
@@ -1234,7 +1325,9 @@ var DEFAULT_RESOLVED = {
1234
1325
  disallowed: void 0,
1235
1326
  cors: void 0,
1236
1327
  auditLogger: void 0,
1237
- devtoolsEnabled: true
1328
+ devtoolsEnabled: true,
1329
+ openapi: void 0,
1330
+ distDir: ".theo"
1238
1331
  };
1239
1332
  async function resolvePluginConfig(projectRoot) {
1240
1333
  try {
@@ -1263,7 +1356,9 @@ async function resolvePluginConfig(projectRoot) {
1263
1356
  disallowed: userConfig.security?.disallowed,
1264
1357
  cors: userConfig.security?.cors,
1265
1358
  auditLogger,
1266
- devtoolsEnabled: userConfig.devtools !== false
1359
+ devtoolsEnabled: userConfig.devtools !== false,
1360
+ openapi: userConfig.openapi,
1361
+ distDir: userConfig.distDir
1267
1362
  };
1268
1363
  } catch {
1269
1364
  return DEFAULT_RESOLVED;
@@ -1600,9 +1695,7 @@ async function integrateUseTheoUI(cwd, opts) {
1600
1695
  }
1601
1696
  const tailwindPlugins = normalizePluginReturn(tailwindPlugin);
1602
1697
  if (tailwindPlugins === null) {
1603
- console.warn(
1604
- `[theokit] @tailwindcss/vite returned unexpected shape. Skipping auto-config.`
1605
- );
1698
+ console.warn(`[theokit] @tailwindcss/vite returned unexpected shape. Skipping auto-config.`);
1606
1699
  return [];
1607
1700
  }
1608
1701
  const uiPlugins = normalizePluginReturn(uiPlugin);
@@ -1876,7 +1969,42 @@ async function theoPluginAsync(rootOrOptions) {
1876
1969
  })
1877
1970
  );
1878
1971
  }
1879
- return [theoPlugin(rootOrOptions), ...uiPlugins, ...servicesPlugins];
1972
+ const { appTypedClientPlugin } = await import("./app-typed-client-6PAT6VOL.js");
1973
+ const appClientPlugin = appTypedClientPlugin({
1974
+ cwd: projectRoot,
1975
+ serverDir: resolve6(projectRoot, "server"),
1976
+ distDir: resolve6(projectRoot, ".theo")
1977
+ });
1978
+ const { actionsVirtualModule } = await import("./actions-virtual-module-E7IELVHL.js");
1979
+ const actionsPlugin = actionsVirtualModule({
1980
+ serverDir: resolve6(projectRoot, "server"),
1981
+ distDir: resolve6(projectRoot, ".theo")
1982
+ });
1983
+ return [
1984
+ theoPlugin(rootOrOptions),
1985
+ ...uiPlugins,
1986
+ ...servicesPlugins,
1987
+ appClientPlugin,
1988
+ actionsPlugin
1989
+ ];
1990
+ }
1991
+ function buildOptimizeDepsInclude(projectRoot, viteOptimizeDeps) {
1992
+ const include = [];
1993
+ if (existsSync7(resolve6(projectRoot, "node_modules", "@usetheo", "ui"))) {
1994
+ include.push("@usetheo/ui");
1995
+ }
1996
+ if (existsSync7(resolve6(projectRoot, "node_modules", "lucide-react"))) {
1997
+ include.push("lucide-react");
1998
+ }
1999
+ include.push("devalue");
2000
+ if (Array.isArray(viteOptimizeDeps)) {
2001
+ for (const pkg of viteOptimizeDeps) {
2002
+ if (typeof pkg === "string" && pkg.length > 0 && !include.includes(pkg)) {
2003
+ include.push(pkg);
2004
+ }
2005
+ }
2006
+ }
2007
+ return include;
1880
2008
  }
1881
2009
  function theoPlugin(rootOrOptions) {
1882
2010
  const options = typeof rootOrOptions === "string" ? { root: rootOrOptions } : rootOrOptions ?? {};
@@ -1895,6 +2023,8 @@ function theoPlugin(rootOrOptions) {
1895
2023
  let cors;
1896
2024
  let auditLogger;
1897
2025
  let devtoolsEnabled = true;
2026
+ let resolvedOpenApi;
2027
+ let resolvedDistDir = ".theo";
1898
2028
  let isDevMode = false;
1899
2029
  let configLoadedOnce = false;
1900
2030
  return {
@@ -1913,6 +2043,8 @@ function theoPlugin(rootOrOptions) {
1913
2043
  cors = resolved.cors;
1914
2044
  auditLogger = resolved.auditLogger;
1915
2045
  devtoolsEnabled = resolved.devtoolsEnabled;
2046
+ resolvedOpenApi = resolved.openapi;
2047
+ resolvedDistDir = resolved.distDir;
1916
2048
  },
1917
2049
  // Vite calls this hook (sync return is fine — no awaits left after
1918
2050
  // the auto-chain moved to theoPluginAsync). The @usetheo/ui +
@@ -1920,13 +2052,7 @@ function theoPlugin(rootOrOptions) {
1920
2052
  // Vite drops plugins returned from a child plugin's config() hook.
1921
2053
  config() {
1922
2054
  const ext = existsSync7(resolve6(theoSrcDir, "index.ts")) ? ".ts" : ".js";
1923
- const optimizeDepsInclude = [];
1924
- if (existsSync7(resolve6(projectRoot, "node_modules", "@usetheo", "ui"))) {
1925
- optimizeDepsInclude.push("@usetheo/ui");
1926
- }
1927
- if (existsSync7(resolve6(projectRoot, "node_modules", "lucide-react"))) {
1928
- optimizeDepsInclude.push("lucide-react");
1929
- }
2055
+ const optimizeDepsInclude = buildOptimizeDepsInclude(projectRoot, options.viteOptimizeDeps);
1930
2056
  const warmupClientFiles = [];
1931
2057
  for (const candidate of ["app/layout.tsx", "app/page.tsx", "app/page.jsx"]) {
1932
2058
  const full = resolve6(projectRoot, candidate);
@@ -1935,7 +2061,10 @@ function theoPlugin(rootOrOptions) {
1935
2061
  const servicesProxy = options.services && Object.keys(options.services).length > 0 ? buildServicesProxyConfig(options.services) : void 0;
1936
2062
  return {
1937
2063
  envPrefix: "THEO_PUBLIC_",
1938
- optimizeDeps: optimizeDepsInclude.length > 0 ? { include: optimizeDepsInclude } : void 0,
2064
+ optimizeDeps: {
2065
+ ...optimizeDepsInclude.length > 0 ? { include: optimizeDepsInclude } : {},
2066
+ force: true
2067
+ },
1939
2068
  server: {
1940
2069
  ...warmupClientFiles.length > 0 ? { warmup: { clientFiles: warmupClientFiles } } : {},
1941
2070
  ...servicesProxy !== void 0 ? { proxy: servicesProxy } : {},
@@ -2050,7 +2179,7 @@ function theoPlugin(rootOrOptions) {
2050
2179
  ].join("\n");
2051
2180
  }
2052
2181
  },
2053
- configureServer(server) {
2182
+ async configureServer(server) {
2054
2183
  isDevMode = true;
2055
2184
  globalThis.__theoViteHotServer = server;
2056
2185
  server.ws.on("theo:devtools:request-manifest", () => {
@@ -2065,6 +2194,7 @@ function theoPlugin(rootOrOptions) {
2065
2194
  createActionMiddleware(server, serverDir, { pluginRunner, csrfMode, disallowed })
2066
2195
  );
2067
2196
  const servicesProxyPrefixes = options.services && Object.keys(options.services).length > 0 ? Object.values(options.services).map((s) => s.proxy) : [];
2197
+ const csrfReadinessStore = options.csrfReadinessStore ?? new CsrfReadinessStore();
2068
2198
  server.middlewares.use(
2069
2199
  createApiMiddleware(server, serverDir, {
2070
2200
  rateLimitConfig: options.rateLimit,
@@ -2076,7 +2206,8 @@ function theoPlugin(rootOrOptions) {
2076
2206
  disallowed,
2077
2207
  cors,
2078
2208
  auditLogger,
2079
- servicesProxyPrefixes
2209
+ servicesProxyPrefixes,
2210
+ csrfReadinessStore
2080
2211
  })
2081
2212
  );
2082
2213
  const configPath = resolve6(projectRoot, "theo.config.ts");
@@ -2105,6 +2236,29 @@ function theoPlugin(rootOrOptions) {
2105
2236
  }
2106
2237
  server.watcher.on("add", handleRouteChange);
2107
2238
  server.watcher.on("unlink", handleRouteChange);
2239
+ if (resolvedOpenApi !== void 0) {
2240
+ const openApiCfg = resolvedOpenApi;
2241
+ const { reEmitOpenApi } = await import("./dev-emit-3CHM73TV.js");
2242
+ const openApiServerDir = resolve6(projectRoot, "server");
2243
+ const openApiDistDir = resolve6(projectRoot, resolvedDistDir);
2244
+ const isRouteFileForOpenApi = (file) => file.startsWith(openApiServerDir) && /\.(ts|tsx|js|mjs)$/.test(file);
2245
+ void reEmitOpenApi(openApiServerDir, openApiDistDir, openApiCfg);
2246
+ server.watcher.on("change", (file) => {
2247
+ if (isRouteFileForOpenApi(file)) {
2248
+ void reEmitOpenApi(openApiServerDir, openApiDistDir, openApiCfg);
2249
+ }
2250
+ });
2251
+ server.watcher.on("add", (file) => {
2252
+ if (isRouteFileForOpenApi(file)) {
2253
+ void reEmitOpenApi(openApiServerDir, openApiDistDir, openApiCfg);
2254
+ }
2255
+ });
2256
+ server.watcher.on("unlink", (file) => {
2257
+ if (isRouteFileForOpenApi(file)) {
2258
+ void reEmitOpenApi(openApiServerDir, openApiDistDir, openApiCfg);
2259
+ }
2260
+ });
2261
+ }
2108
2262
  setupWsUpgrade(server, projectRoot);
2109
2263
  server.httpServer?.once("close", () => {
2110
2264
  ;
@@ -2130,4 +2284,4 @@ export {
2130
2284
  theoPluginAsync,
2131
2285
  theoPlugin
2132
2286
  };
2133
- //# sourceMappingURL=chunk-FRBYJANT.js.map
2287
+ //# sourceMappingURL=chunk-4W447H7M.js.map