theokit 0.5.4 → 0.6.0

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 (114) hide show
  1. package/dist/{aws-lambda-SCRGTGF5.js → aws-lambda-WT4HRBNL.js} +3 -3
  2. package/dist/{build-R74EU6BP.js → build-ZZAQV2ES.js} +7 -7
  3. package/dist/{bun-FURRCQMS.js → bun-UTDVN6R4.js} +3 -3
  4. package/dist/{check-NXYPLM6M.js → check-F3UDYSZ4.js} +2 -2
  5. package/dist/{chunk-KJLECZWQ.js → chunk-3FYJ7R7N.js} +57 -14
  6. package/dist/chunk-3FYJ7R7N.js.map +1 -0
  7. package/dist/{chunk-JD7AQNJS.js → chunk-4NLIESWK.js} +18 -12
  8. package/dist/{chunk-JD7AQNJS.js.map → chunk-4NLIESWK.js.map} +1 -1
  9. package/dist/{chunk-H4J2LECY.js → chunk-6BUUZ2PK.js} +9 -9
  10. package/dist/chunk-6BUUZ2PK.js.map +1 -0
  11. package/dist/{chunk-FGOX37NB.js → chunk-BNGBG2SQ.js} +21 -2
  12. package/dist/chunk-BNGBG2SQ.js.map +1 -0
  13. package/dist/{chunk-X32KQH5C.js → chunk-CCVC6P6B.js} +3 -3
  14. package/dist/chunk-CCVC6P6B.js.map +1 -0
  15. package/dist/{chunk-S74FECKW.js → chunk-D4SV7JOG.js} +24 -20
  16. package/dist/chunk-D4SV7JOG.js.map +1 -0
  17. package/dist/{chunk-DNMSV3R3.js → chunk-D7ZH7DTG.js} +3 -3
  18. package/dist/chunk-D7ZH7DTG.js.map +1 -0
  19. package/dist/{chunk-MWYSRZI4.js → chunk-EQV67HZL.js} +2 -2
  20. package/dist/{chunk-CG563V5M.js → chunk-IEES3CHD.js} +39 -5
  21. package/dist/chunk-IEES3CHD.js.map +1 -0
  22. package/dist/{chunk-DUKXQNM7.js → chunk-IHMJV2OK.js} +2 -2
  23. package/dist/{chunk-WGHJD6I7.js → chunk-JAIKGP3Q.js} +76 -21
  24. package/dist/chunk-JAIKGP3Q.js.map +1 -0
  25. package/dist/{chunk-NZXH2LQQ.js → chunk-SJIRP73B.js} +18 -1
  26. package/dist/chunk-SJIRP73B.js.map +1 -0
  27. package/dist/{chunk-X3VNROZ7.js → chunk-SVSUUK4H.js} +73 -14
  28. package/dist/chunk-SVSUUK4H.js.map +1 -0
  29. package/dist/cli/index.js +25 -10
  30. package/dist/cli/index.js.map +1 -1
  31. package/dist/{cloudflare-IZ6VJ2OU.js → cloudflare-U5GYYI47.js} +3 -3
  32. package/dist/db-ZPDW3UCU.js +78 -0
  33. package/dist/db-ZPDW3UCU.js.map +1 -0
  34. package/dist/{deno-deploy-O73NBXIW.js → deno-deploy-3QHJ3AJQ.js} +3 -3
  35. package/dist/{dev-ZU46C5AZ.js → dev-MHCQ5RD7.js} +16 -8
  36. package/dist/dev-MHCQ5RD7.js.map +1 -0
  37. package/dist/{dev-emit-66FCOS7V.js → dev-emit-4WG3B5BM.js} +2 -2
  38. package/dist/{dev-emit-JBVINGHU.js → dev-emit-6DJUK6DT.js} +76 -21
  39. package/dist/dev-emit-6DJUK6DT.js.map +1 -0
  40. package/dist/devtools/entry.js +1 -0
  41. package/dist/devtools/entry.js.map +1 -1
  42. package/dist/generate-ODDAYXNR.js +494 -0
  43. package/dist/generate-ODDAYXNR.js.map +1 -0
  44. package/dist/index.d.ts +32 -3
  45. package/dist/index.js +3 -4
  46. package/dist/index.js.map +1 -1
  47. package/dist/{info-CORLCPEJ.js → info-CSGWIAXA.js} +5 -5
  48. package/dist/{netlify-O7G3RLK4.js → netlify-DUB7BZ4E.js} +3 -3
  49. package/dist/{node-LXPQLMVB.js → node-ELE236WK.js} +3 -3
  50. package/dist/{openapi-TEOUOIJ2.js → openapi-KSY272CW.js} +5 -5
  51. package/dist/registry-B7FA6KMI.js +25 -0
  52. package/dist/{routes-GAXVWJUK.js → routes-NWJA5L5I.js} +4 -4
  53. package/dist/{scan-NQFI5S7P.js → scan-I5PT6TUX.js} +2 -2
  54. package/dist/{schema-D3v8VB7o.d.ts → schema-BpH6ivDY.d.ts} +2 -4
  55. package/dist/{schema-Z5VJ2I76.js → schema-NPI4NJEF.js} +3 -3
  56. package/dist/server/auth/index.js +3 -5
  57. package/dist/server/define/index.d.ts +7 -0
  58. package/dist/server/define/index.js +1 -1
  59. package/dist/server/http/index.js +1 -2
  60. package/dist/server/index.d.ts +34 -1
  61. package/dist/server/index.js +57 -48
  62. package/dist/server/index.js.map +1 -1
  63. package/dist/{services-typed-client-ASZL7FQV.js → services-typed-client-24VBMDOF.js} +2 -2
  64. package/dist/{services-typed-client-KK6RHRDG.js → services-typed-client-IETY2SAK.js} +2 -2
  65. package/dist/{start-HGUNNF5X.js → start-OAAAQ7Z4.js} +84 -69
  66. package/dist/start-OAAAQ7Z4.js.map +1 -0
  67. package/dist/{static-EO73I4C7.js → static-YWF2M6YT.js} +4 -4
  68. package/dist/{theo-cloud-HBCYEODQ.js → theo-cloud-EUK56I7O.js} +2 -2
  69. package/dist/{vercel-GSFDMF7K.js → vercel-LGDQWYZD.js} +3 -3
  70. package/dist/vite-plugin/index.d.ts +1 -1
  71. package/dist/vite-plugin/index.js +3 -4
  72. package/dist/{vite-plugin-TX5H4MB6.js → vite-plugin-IF2O6BJV.js} +7 -7
  73. package/package.json +4 -1
  74. package/dist/chunk-4HBI7DHP.js +0 -20
  75. package/dist/chunk-4HBI7DHP.js.map +0 -1
  76. package/dist/chunk-CG563V5M.js.map +0 -1
  77. package/dist/chunk-DNMSV3R3.js.map +0 -1
  78. package/dist/chunk-FGOX37NB.js.map +0 -1
  79. package/dist/chunk-H4J2LECY.js.map +0 -1
  80. package/dist/chunk-KJLECZWQ.js.map +0 -1
  81. package/dist/chunk-NZXH2LQQ.js.map +0 -1
  82. package/dist/chunk-S74FECKW.js.map +0 -1
  83. package/dist/chunk-WGHJD6I7.js.map +0 -1
  84. package/dist/chunk-X32KQH5C.js.map +0 -1
  85. package/dist/chunk-X3VNROZ7.js.map +0 -1
  86. package/dist/dev-ZU46C5AZ.js.map +0 -1
  87. package/dist/dev-emit-JBVINGHU.js.map +0 -1
  88. package/dist/generate-AZ2K6Z2Z.js +0 -281
  89. package/dist/generate-AZ2K6Z2Z.js.map +0 -1
  90. package/dist/registry-KW4F4D2L.js +0 -25
  91. package/dist/start-HGUNNF5X.js.map +0 -1
  92. /package/dist/{aws-lambda-SCRGTGF5.js.map → aws-lambda-WT4HRBNL.js.map} +0 -0
  93. /package/dist/{build-R74EU6BP.js.map → build-ZZAQV2ES.js.map} +0 -0
  94. /package/dist/{bun-FURRCQMS.js.map → bun-UTDVN6R4.js.map} +0 -0
  95. /package/dist/{check-NXYPLM6M.js.map → check-F3UDYSZ4.js.map} +0 -0
  96. /package/dist/{chunk-MWYSRZI4.js.map → chunk-EQV67HZL.js.map} +0 -0
  97. /package/dist/{chunk-DUKXQNM7.js.map → chunk-IHMJV2OK.js.map} +0 -0
  98. /package/dist/{cloudflare-IZ6VJ2OU.js.map → cloudflare-U5GYYI47.js.map} +0 -0
  99. /package/dist/{deno-deploy-O73NBXIW.js.map → deno-deploy-3QHJ3AJQ.js.map} +0 -0
  100. /package/dist/{dev-emit-66FCOS7V.js.map → dev-emit-4WG3B5BM.js.map} +0 -0
  101. /package/dist/{info-CORLCPEJ.js.map → info-CSGWIAXA.js.map} +0 -0
  102. /package/dist/{netlify-O7G3RLK4.js.map → netlify-DUB7BZ4E.js.map} +0 -0
  103. /package/dist/{node-LXPQLMVB.js.map → node-ELE236WK.js.map} +0 -0
  104. /package/dist/{openapi-TEOUOIJ2.js.map → openapi-KSY272CW.js.map} +0 -0
  105. /package/dist/{registry-KW4F4D2L.js.map → registry-B7FA6KMI.js.map} +0 -0
  106. /package/dist/{routes-GAXVWJUK.js.map → routes-NWJA5L5I.js.map} +0 -0
  107. /package/dist/{scan-NQFI5S7P.js.map → scan-I5PT6TUX.js.map} +0 -0
  108. /package/dist/{schema-Z5VJ2I76.js.map → schema-NPI4NJEF.js.map} +0 -0
  109. /package/dist/{services-typed-client-ASZL7FQV.js.map → services-typed-client-24VBMDOF.js.map} +0 -0
  110. /package/dist/{services-typed-client-KK6RHRDG.js.map → services-typed-client-IETY2SAK.js.map} +0 -0
  111. /package/dist/{static-EO73I4C7.js.map → static-YWF2M6YT.js.map} +0 -0
  112. /package/dist/{theo-cloud-HBCYEODQ.js.map → theo-cloud-EUK56I7O.js.map} +0 -0
  113. /package/dist/{vercel-GSFDMF7K.js.map → vercel-LGDQWYZD.js.map} +0 -0
  114. /package/dist/{vite-plugin-TX5H4MB6.js.map → vite-plugin-IF2O6BJV.js.map} +0 -0
package/dist/cli/index.js CHANGED
@@ -6,12 +6,12 @@ import "../chunk-KT3MWNZG.js";
6
6
  import cac from "cac";
7
7
  var cli = cac("theokit");
8
8
  cli.command("dev", "Start development server").option("--port <port>", "Port number").action(async (options) => {
9
- const { devCommand } = await import("../dev-ZU46C5AZ.js");
9
+ const { devCommand } = await import("../dev-MHCQ5RD7.js");
10
10
  await devCommand({ port: options.port ? Number(options.port) : void 0 });
11
11
  });
12
12
  cli.command("build", "Build for production").option("--target <target>", "Deploy target (node, vercel, cloudflare)").action(async (options) => {
13
13
  try {
14
- const { buildCommand } = await import("../build-R74EU6BP.js");
14
+ const { buildCommand } = await import("../build-ZZAQV2ES.js");
15
15
  await buildCommand({ target: options.target });
16
16
  } catch (err) {
17
17
  const msg = err instanceof Error ? err.message : String(err);
@@ -23,7 +23,7 @@ cli.command("build", "Build for production").option("--target <target>", "Deploy
23
23
  });
24
24
  cli.command("start", "Start production server").option("--port <port>", "Port number").action(async (options) => {
25
25
  try {
26
- const { startCommand } = await import("../start-HGUNNF5X.js");
26
+ const { startCommand } = await import("../start-OAAAQ7Z4.js");
27
27
  await startCommand({ port: options.port ? Number(options.port) : void 0 });
28
28
  } catch (err) {
29
29
  const msg = err instanceof Error ? err.message : String(err);
@@ -33,10 +33,13 @@ cli.command("start", "Start production server").option("--port <port>", "Port nu
33
33
  process.exit(1);
34
34
  }
35
35
  });
36
- cli.command("generate <type> <name>", "Generate a route, action, page, ws, or controller endpoint").action(async (type, name) => {
36
+ cli.command(
37
+ "generate <type> <name> [...fields]",
38
+ "Generate a route, action, page, ws, controller, or resource (resource accepts field:type args)"
39
+ ).action(async (type, name, fields) => {
37
40
  try {
38
- const { generateCommand } = await import("../generate-AZ2K6Z2Z.js");
39
- await generateCommand(type, name);
41
+ const { generateCommand } = await import("../generate-ODDAYXNR.js");
42
+ await generateCommand(type, name, fields.length > 0 ? fields : void 0);
40
43
  } catch (err) {
41
44
  const msg = err instanceof Error ? err.message : String(err);
42
45
  console.error(`
@@ -47,7 +50,7 @@ cli.command("generate <type> <name>", "Generate a route, action, page, ws, or co
47
50
  });
48
51
  cli.command("routes", "List all routes, actions, and WebSocket endpoints").action(async () => {
49
52
  try {
50
- const { routesCommand } = await import("../routes-GAXVWJUK.js");
53
+ const { routesCommand } = await import("../routes-NWJA5L5I.js");
51
54
  await routesCommand();
52
55
  } catch (err) {
53
56
  const msg = err instanceof Error ? err.message : String(err);
@@ -80,7 +83,7 @@ cli.command("check", "Run typecheck + scan + (optional) eslint").option(
80
83
  });
81
84
  return;
82
85
  }
83
- const { checkCommand } = await import("../check-NXYPLM6M.js");
86
+ const { checkCommand } = await import("../check-F3UDYSZ4.js");
84
87
  await checkCommand();
85
88
  });
86
89
  cli.command("add <package>", "Install a known TheoKit adapter or plugin (whitelist-only)").action(async (pkg) => {
@@ -88,7 +91,7 @@ cli.command("add <package>", "Install a known TheoKit adapter or plugin (whiteli
88
91
  await addCommand(pkg);
89
92
  });
90
93
  cli.command("info", "Print environment info (runtime, config, routes)").action(async () => {
91
- const { infoCommand } = await import("../info-CORLCPEJ.js");
94
+ const { infoCommand } = await import("../info-CSGWIAXA.js");
92
95
  await infoCommand();
93
96
  });
94
97
  cli.command(
@@ -96,7 +99,7 @@ cli.command(
96
99
  "Generate <distDir>/openapi.json from route schemas (opt-in via config.openapi)"
97
100
  ).option("--dry-run", "Print the document to stdout without writing to disk (EC-3)").action(async (options) => {
98
101
  try {
99
- const { openapiCommand } = await import("../openapi-TEOUOIJ2.js");
102
+ const { openapiCommand } = await import("../openapi-KSY272CW.js");
100
103
  await openapiCommand({ dryRun: Boolean(options.dryRun) });
101
104
  } catch (err) {
102
105
  const msg = err instanceof Error ? err.message : String(err);
@@ -153,6 +156,18 @@ cli.command("docker", "Generate Dockerfile for production").option("--force", "O
153
156
  process.exit(1);
154
157
  }
155
158
  });
159
+ cli.command("db <action>", "Database commands: migrate (push schema), generate (SQL files), seed").action(async (action) => {
160
+ try {
161
+ const { dbCommandCli } = await import("../db-ZPDW3UCU.js");
162
+ dbCommandCli(action);
163
+ } catch (err) {
164
+ const msg = err instanceof Error ? err.message : String(err);
165
+ console.error(`
166
+ \u2717 ${msg}
167
+ `);
168
+ process.exit(1);
169
+ }
170
+ });
156
171
  cli.help();
157
172
  cli.version("0.1.0-alpha.0");
158
173
  function main() {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/cli/index.ts"],"sourcesContent":["import cac from 'cac'\n\ninterface CliOptions {\n port?: string | number\n target?: string\n upgradeReadiness?: string | number\n json?: boolean\n allowWarnings?: boolean\n force?: boolean\n dryRun?: boolean\n}\n\nconst cli = cac('theokit')\n\ncli\n .command('dev', 'Start development server')\n .option('--port <port>', 'Port number')\n .action(async (options: CliOptions) => {\n const { devCommand } = await import('./commands/dev.js')\n await devCommand({ port: options.port ? Number(options.port) : undefined })\n })\n\ncli\n .command('build', 'Build for production')\n .option('--target <target>', 'Deploy target (node, vercel, cloudflare)')\n .action(async (options: CliOptions) => {\n try {\n const { buildCommand } = await import('./commands/build.js')\n await buildCommand({ target: options.target })\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n console.error(`\\n ✗ ${msg}\\n`)\n process.exit(1)\n }\n })\n\ncli\n .command('start', 'Start production server')\n .option('--port <port>', 'Port number')\n .action(async (options: CliOptions) => {\n try {\n const { startCommand } = await import('./commands/start/index.js')\n await startCommand({ port: options.port ? Number(options.port) : undefined })\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n console.error(`\\n ✗ ${msg}\\n`)\n process.exit(1)\n }\n })\n\ncli\n .command('generate <type> <name>', 'Generate a route, action, page, ws, or controller endpoint')\n .action(async (type: string, name: string) => {\n try {\n const { generateCommand } = await import('./commands/generate.js')\n await generateCommand(type, name)\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n console.error(`\\n ✗ ${msg}\\n`)\n process.exit(1)\n }\n })\n\ncli.command('routes', 'List all routes, actions, and WebSocket endpoints').action(async () => {\n try {\n const { routesCommand } = await import('./commands/routes.js')\n await routesCommand()\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n console.error(`\\n ✗ ${msg}\\n`)\n process.exit(1)\n }\n})\n\ncli\n .command('check', 'Run typecheck + scan + (optional) eslint')\n .option(\n '--upgrade-readiness <version>',\n 'Scan source for anticipated breakage under a future TheoKit version (currently supports 0.3). See docs/migration/0.2-to-0.3.md',\n )\n .option('--json', 'Emit machine-readable JSON (only with --upgrade-readiness)')\n .option(\n '--allow-warnings',\n 'Do not fail the build when violations are present (only with --upgrade-readiness)',\n )\n .action(async (options: CliOptions) => {\n // cac may coerce `0.3` to a JS number — normalize before comparing.\n const targetRaw = options.upgradeReadiness\n if (targetRaw !== undefined) {\n const target = String(targetRaw)\n if (target !== '0.3') {\n console.error(`\\n ✗ --upgrade-readiness: only '0.3' is supported (got '${target}')\\n`)\n process.exit(1)\n }\n const { upgradeReadinessCommand } = await import('./commands/upgrade-readiness.js')\n await upgradeReadinessCommand({\n json: Boolean(options.json),\n allowWarnings: Boolean(options.allowWarnings),\n })\n return\n }\n const { checkCommand } = await import('./commands/check.js')\n await checkCommand()\n })\n\ncli\n .command('add <package>', 'Install a known TheoKit adapter or plugin (whitelist-only)')\n .action(async (pkg: string) => {\n const { addCommand } = await import('./commands/add.js')\n await addCommand(pkg)\n })\n\ncli.command('info', 'Print environment info (runtime, config, routes)').action(async () => {\n const { infoCommand } = await import('./commands/info.js')\n await infoCommand()\n})\n\ncli\n .command(\n 'openapi',\n 'Generate <distDir>/openapi.json from route schemas (opt-in via config.openapi)',\n )\n .option('--dry-run', 'Print the document to stdout without writing to disk (EC-3)')\n .action(async (options: CliOptions) => {\n try {\n const { openapiCommand } = await import('./commands/openapi.js')\n await openapiCommand({ dryRun: Boolean(options.dryRun) })\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n console.error(`\\n ✗ ${msg}\\n`)\n process.exit(1)\n }\n })\n\ncli\n .command(\n 'migrate <kind>',\n 'Run a one-shot convention migration. Supported: router (G6 dotted→nested), services-json-v1-to-v2 (Plan v1.2 T2.3)',\n )\n .option('--dry-run', 'Print the migration plan but do not touch the filesystem')\n .option('--force', 'Skip the dev-server port pre-flight check (CI / non-TTY)')\n .option('--name <slug>', 'Explicit project name (DNS-1123). Services-json migrate only.')\n .action(async (kind: string, options: CliOptions & { name?: string }) => {\n try {\n if (kind === 'router') {\n const { routerMigrateCommand } = await import('./commands/migrate/router.js')\n await routerMigrateCommand({\n dryRun: Boolean(options.dryRun),\n force: Boolean(options.force),\n })\n return\n }\n if (kind === 'services-json-v1-to-v2' || kind === 'services-json') {\n const { servicesJsonMigrateCommand } = await import('./commands/migrate/services-json.js')\n await servicesJsonMigrateCommand({\n dryRun: Boolean(options.dryRun),\n name: options.name,\n })\n return\n }\n console.error(\n `\\n ✗ Unknown migration kind: ${kind}. Supported: router, services-json-v1-to-v2\\n`,\n )\n process.exit(1)\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n console.error(`\\n ✗ ${msg}\\n`)\n process.exit(1)\n }\n })\n\ncli\n .command('docker', 'Generate Dockerfile for production')\n .option('--force', 'Overwrite existing Dockerfile')\n .action(async (options: CliOptions) => {\n try {\n const { dockerCommand } = await import('./commands/docker.js')\n await dockerCommand({ force: options.force })\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n console.error(`\\n ✗ ${msg}\\n`)\n process.exit(1)\n }\n })\n\ncli.help()\ncli.version('0.1.0-alpha.0')\n\nexport function main(): void {\n cli.parse()\n}\n\n// Auto-execute when run as script\nmain()\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/cli/index.ts"],"sourcesContent":["import cac from 'cac'\n\ninterface CliOptions {\n port?: string | number\n target?: string\n upgradeReadiness?: string | number\n json?: boolean\n allowWarnings?: boolean\n force?: boolean\n dryRun?: boolean\n}\n\nconst cli = cac('theokit')\n\ncli\n .command('dev', 'Start development server')\n .option('--port <port>', 'Port number')\n .action(async (options: CliOptions) => {\n const { devCommand } = await import('./commands/dev.js')\n await devCommand({ port: options.port ? Number(options.port) : undefined })\n })\n\ncli\n .command('build', 'Build for production')\n .option('--target <target>', 'Deploy target (node, vercel, cloudflare)')\n .action(async (options: CliOptions) => {\n try {\n const { buildCommand } = await import('./commands/build.js')\n await buildCommand({ target: options.target })\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n console.error(`\\n ✗ ${msg}\\n`)\n process.exit(1)\n }\n })\n\ncli\n .command('start', 'Start production server')\n .option('--port <port>', 'Port number')\n .action(async (options: CliOptions) => {\n try {\n const { startCommand } = await import('./commands/start/index.js')\n await startCommand({ port: options.port ? Number(options.port) : undefined })\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n console.error(`\\n ✗ ${msg}\\n`)\n process.exit(1)\n }\n })\n\ncli\n .command(\n 'generate <type> <name> [...fields]',\n 'Generate a route, action, page, ws, controller, or resource (resource accepts field:type args)',\n )\n .action(async (type: string, name: string, fields: string[]) => {\n try {\n const { generateCommand } = await import('./commands/generate.js')\n await generateCommand(type, name, fields.length > 0 ? fields : undefined)\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n console.error(`\\n ✗ ${msg}\\n`)\n process.exit(1)\n }\n })\n\ncli.command('routes', 'List all routes, actions, and WebSocket endpoints').action(async () => {\n try {\n const { routesCommand } = await import('./commands/routes.js')\n await routesCommand()\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n console.error(`\\n ✗ ${msg}\\n`)\n process.exit(1)\n }\n})\n\ncli\n .command('check', 'Run typecheck + scan + (optional) eslint')\n .option(\n '--upgrade-readiness <version>',\n 'Scan source for anticipated breakage under a future TheoKit version (currently supports 0.3). See docs/migration/0.2-to-0.3.md',\n )\n .option('--json', 'Emit machine-readable JSON (only with --upgrade-readiness)')\n .option(\n '--allow-warnings',\n 'Do not fail the build when violations are present (only with --upgrade-readiness)',\n )\n .action(async (options: CliOptions) => {\n // cac may coerce `0.3` to a JS number — normalize before comparing.\n const targetRaw = options.upgradeReadiness\n if (targetRaw !== undefined) {\n const target = String(targetRaw)\n if (target !== '0.3') {\n console.error(`\\n ✗ --upgrade-readiness: only '0.3' is supported (got '${target}')\\n`)\n process.exit(1)\n }\n const { upgradeReadinessCommand } = await import('./commands/upgrade-readiness.js')\n await upgradeReadinessCommand({\n json: Boolean(options.json),\n allowWarnings: Boolean(options.allowWarnings),\n })\n return\n }\n const { checkCommand } = await import('./commands/check.js')\n await checkCommand()\n })\n\ncli\n .command('add <package>', 'Install a known TheoKit adapter or plugin (whitelist-only)')\n .action(async (pkg: string) => {\n const { addCommand } = await import('./commands/add.js')\n await addCommand(pkg)\n })\n\ncli.command('info', 'Print environment info (runtime, config, routes)').action(async () => {\n const { infoCommand } = await import('./commands/info.js')\n await infoCommand()\n})\n\ncli\n .command(\n 'openapi',\n 'Generate <distDir>/openapi.json from route schemas (opt-in via config.openapi)',\n )\n .option('--dry-run', 'Print the document to stdout without writing to disk (EC-3)')\n .action(async (options: CliOptions) => {\n try {\n const { openapiCommand } = await import('./commands/openapi.js')\n await openapiCommand({ dryRun: Boolean(options.dryRun) })\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n console.error(`\\n ✗ ${msg}\\n`)\n process.exit(1)\n }\n })\n\ncli\n .command(\n 'migrate <kind>',\n 'Run a one-shot convention migration. Supported: router (G6 dotted→nested), services-json-v1-to-v2 (Plan v1.2 T2.3)',\n )\n .option('--dry-run', 'Print the migration plan but do not touch the filesystem')\n .option('--force', 'Skip the dev-server port pre-flight check (CI / non-TTY)')\n .option('--name <slug>', 'Explicit project name (DNS-1123). Services-json migrate only.')\n .action(async (kind: string, options: CliOptions & { name?: string }) => {\n try {\n if (kind === 'router') {\n const { routerMigrateCommand } = await import('./commands/migrate/router.js')\n await routerMigrateCommand({\n dryRun: Boolean(options.dryRun),\n force: Boolean(options.force),\n })\n return\n }\n if (kind === 'services-json-v1-to-v2' || kind === 'services-json') {\n const { servicesJsonMigrateCommand } = await import('./commands/migrate/services-json.js')\n await servicesJsonMigrateCommand({\n dryRun: Boolean(options.dryRun),\n name: options.name,\n })\n return\n }\n console.error(\n `\\n ✗ Unknown migration kind: ${kind}. Supported: router, services-json-v1-to-v2\\n`,\n )\n process.exit(1)\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n console.error(`\\n ✗ ${msg}\\n`)\n process.exit(1)\n }\n })\n\ncli\n .command('docker', 'Generate Dockerfile for production')\n .option('--force', 'Overwrite existing Dockerfile')\n .action(async (options: CliOptions) => {\n try {\n const { dockerCommand } = await import('./commands/docker.js')\n await dockerCommand({ force: options.force })\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n console.error(`\\n ✗ ${msg}\\n`)\n process.exit(1)\n }\n })\n\ncli\n .command('db <action>', 'Database commands: migrate (push schema), generate (SQL files), seed')\n .action(async (action: string) => {\n try {\n const { dbCommandCli } = await import('./commands/db.js')\n dbCommandCli(action)\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n console.error(`\\n ✗ ${msg}\\n`)\n process.exit(1)\n }\n })\n\ncli.help()\ncli.version('0.1.0-alpha.0')\n\nexport function main(): void {\n cli.parse()\n}\n\n// Auto-execute when run as script\nmain()\n"],"mappings":"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","names":[]}
@@ -2,11 +2,11 @@
2
2
  import "tsx/esm";
3
3
  import {
4
4
  nodeAdapter
5
- } from "./chunk-MWYSRZI4.js";
5
+ } from "./chunk-EQV67HZL.js";
6
6
  import {
7
7
  assertServicesUnsupported,
8
8
  readManifest
9
- } from "./chunk-X32KQH5C.js";
9
+ } from "./chunk-CCVC6P6B.js";
10
10
  import "./chunk-KT3MWNZG.js";
11
11
 
12
12
  // src/adapters/cloudflare.ts
@@ -120,4 +120,4 @@ export {
120
120
  renderCloudflareWorkerEntry,
121
121
  renderWranglerToml
122
122
  };
123
- //# sourceMappingURL=cloudflare-IZ6VJ2OU.js.map
123
+ //# sourceMappingURL=cloudflare-U5GYYI47.js.map
@@ -0,0 +1,78 @@
1
+ #!/usr/bin/env node
2
+ import "tsx/esm";
3
+ import "./chunk-KT3MWNZG.js";
4
+
5
+ // src/cli/commands/db.ts
6
+ import { execSync } from "child_process";
7
+ import { existsSync } from "fs";
8
+ import { resolve } from "path";
9
+ var VALID_ACTIONS = /* @__PURE__ */ new Set(["migrate", "generate", "seed"]);
10
+ function assertFileExists(cwd, relPath, hint) {
11
+ if (!existsSync(resolve(cwd, relPath))) {
12
+ throw new Error(`${relPath} not found. ${hint}`);
13
+ }
14
+ }
15
+ function assertBinExists(cwd, bin) {
16
+ const binPath = resolve(cwd, "node_modules", ".bin", bin);
17
+ if (!existsSync(binPath)) {
18
+ throw new Error(`${bin} not found. Run: npm install -D ${bin}`);
19
+ }
20
+ }
21
+ function dbCommand(action, cwd) {
22
+ if (!VALID_ACTIONS.has(action)) {
23
+ return {
24
+ status: "invalid_action",
25
+ message: `Unknown db action "${action}". Available: ${[...VALID_ACTIONS].join(", ")}`
26
+ };
27
+ }
28
+ const dbAction = action;
29
+ try {
30
+ switch (dbAction) {
31
+ case "migrate": {
32
+ assertFileExists(cwd, "drizzle.config.ts", "Create a drizzle.config.ts for your project.");
33
+ assertBinExists(cwd, "drizzle-kit");
34
+ console.log("\n \u25B8 Running drizzle-kit push...\n");
35
+ execSync("npx drizzle-kit push", { cwd, stdio: "inherit" });
36
+ return { status: "success", message: "Database migrated successfully", action: dbAction };
37
+ }
38
+ case "generate": {
39
+ assertFileExists(cwd, "drizzle.config.ts", "Create a drizzle.config.ts for your project.");
40
+ assertBinExists(cwd, "drizzle-kit");
41
+ console.log("\n \u25B8 Running drizzle-kit generate...\n");
42
+ execSync("npx drizzle-kit generate", { cwd, stdio: "inherit" });
43
+ return {
44
+ status: "success",
45
+ message: "Migration files generated in drizzle/",
46
+ action: dbAction
47
+ };
48
+ }
49
+ case "seed": {
50
+ assertFileExists(cwd, "server/db/seed.ts", "Create server/db/seed.ts with your seed data.");
51
+ console.log("\n \u25B8 Running seed...\n");
52
+ execSync("npx tsx server/db/seed.ts", { cwd, stdio: "inherit" });
53
+ return { status: "success", message: "Database seeded successfully", action: dbAction };
54
+ }
55
+ }
56
+ } catch (err) {
57
+ const msg = err instanceof Error ? err.message : String(err);
58
+ return { status: "error", message: msg, action: dbAction };
59
+ }
60
+ }
61
+ function dbCommandCli(action) {
62
+ const result = dbCommand(action, process.cwd());
63
+ if (result.status === "success") {
64
+ console.log(`
65
+ \u2713 ${result.message}
66
+ `);
67
+ } else {
68
+ console.error(`
69
+ \u2717 ${result.message}
70
+ `);
71
+ process.exit(1);
72
+ }
73
+ }
74
+ export {
75
+ dbCommand,
76
+ dbCommandCli
77
+ };
78
+ //# sourceMappingURL=db-ZPDW3UCU.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/commands/db.ts"],"sourcesContent":["import { execSync } from 'node:child_process'\nimport { existsSync } from 'node:fs'\nimport { resolve } from 'node:path'\n\nexport type DbAction = 'migrate' | 'generate' | 'seed'\n\nconst VALID_ACTIONS = new Set<DbAction>(['migrate', 'generate', 'seed'])\n\nexport interface DbCommandResult {\n status: 'success' | 'error' | 'invalid_action'\n message: string\n action?: DbAction\n}\n\nfunction assertFileExists(cwd: string, relPath: string, hint: string): void {\n if (!existsSync(resolve(cwd, relPath))) {\n throw new Error(`${relPath} not found. ${hint}`)\n }\n}\n\nfunction assertBinExists(cwd: string, bin: string): void {\n const binPath = resolve(cwd, 'node_modules', '.bin', bin)\n if (!existsSync(binPath)) {\n throw new Error(`${bin} not found. Run: npm install -D ${bin}`)\n }\n}\n\nexport function dbCommand(action: string, cwd: string): DbCommandResult {\n if (!VALID_ACTIONS.has(action as DbAction)) {\n return {\n status: 'invalid_action',\n message: `Unknown db action \"${action}\". Available: ${[...VALID_ACTIONS].join(', ')}`,\n }\n }\n\n const dbAction = action as DbAction\n\n try {\n switch (dbAction) {\n case 'migrate': {\n assertFileExists(cwd, 'drizzle.config.ts', 'Create a drizzle.config.ts for your project.')\n assertBinExists(cwd, 'drizzle-kit')\n console.log('\\n ▸ Running drizzle-kit push...\\n')\n execSync('npx drizzle-kit push', { cwd, stdio: 'inherit' })\n return { status: 'success', message: 'Database migrated successfully', action: dbAction }\n }\n case 'generate': {\n assertFileExists(cwd, 'drizzle.config.ts', 'Create a drizzle.config.ts for your project.')\n assertBinExists(cwd, 'drizzle-kit')\n console.log('\\n ▸ Running drizzle-kit generate...\\n')\n execSync('npx drizzle-kit generate', { cwd, stdio: 'inherit' })\n return {\n status: 'success',\n message: 'Migration files generated in drizzle/',\n action: dbAction,\n }\n }\n case 'seed': {\n assertFileExists(cwd, 'server/db/seed.ts', 'Create server/db/seed.ts with your seed data.')\n console.log('\\n ▸ Running seed...\\n')\n execSync('npx tsx server/db/seed.ts', { cwd, stdio: 'inherit' })\n return { status: 'success', message: 'Database seeded successfully', action: dbAction }\n }\n }\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n return { status: 'error', message: msg, action: dbAction }\n }\n}\n\nexport function dbCommandCli(action: string): void {\n const result = dbCommand(action, process.cwd())\n if (result.status === 'success') {\n console.log(`\\n ✓ ${result.message}\\n`)\n } else {\n console.error(`\\n ✗ ${result.message}\\n`)\n process.exit(1)\n }\n}\n"],"mappings":";;;;;AAAA,SAAS,gBAAgB;AACzB,SAAS,kBAAkB;AAC3B,SAAS,eAAe;AAIxB,IAAM,gBAAgB,oBAAI,IAAc,CAAC,WAAW,YAAY,MAAM,CAAC;AAQvE,SAAS,iBAAiB,KAAa,SAAiB,MAAoB;AAC1E,MAAI,CAAC,WAAW,QAAQ,KAAK,OAAO,CAAC,GAAG;AACtC,UAAM,IAAI,MAAM,GAAG,OAAO,eAAe,IAAI,EAAE;AAAA,EACjD;AACF;AAEA,SAAS,gBAAgB,KAAa,KAAmB;AACvD,QAAM,UAAU,QAAQ,KAAK,gBAAgB,QAAQ,GAAG;AACxD,MAAI,CAAC,WAAW,OAAO,GAAG;AACxB,UAAM,IAAI,MAAM,GAAG,GAAG,mCAAmC,GAAG,EAAE;AAAA,EAChE;AACF;AAEO,SAAS,UAAU,QAAgB,KAA8B;AACtE,MAAI,CAAC,cAAc,IAAI,MAAkB,GAAG;AAC1C,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,SAAS,sBAAsB,MAAM,iBAAiB,CAAC,GAAG,aAAa,EAAE,KAAK,IAAI,CAAC;AAAA,IACrF;AAAA,EACF;AAEA,QAAM,WAAW;AAEjB,MAAI;AACF,YAAQ,UAAU;AAAA,MAChB,KAAK,WAAW;AACd,yBAAiB,KAAK,qBAAqB,8CAA8C;AACzF,wBAAgB,KAAK,aAAa;AAClC,gBAAQ,IAAI,0CAAqC;AACjD,iBAAS,wBAAwB,EAAE,KAAK,OAAO,UAAU,CAAC;AAC1D,eAAO,EAAE,QAAQ,WAAW,SAAS,kCAAkC,QAAQ,SAAS;AAAA,MAC1F;AAAA,MACA,KAAK,YAAY;AACf,yBAAiB,KAAK,qBAAqB,8CAA8C;AACzF,wBAAgB,KAAK,aAAa;AAClC,gBAAQ,IAAI,8CAAyC;AACrD,iBAAS,4BAA4B,EAAE,KAAK,OAAO,UAAU,CAAC;AAC9D,eAAO;AAAA,UACL,QAAQ;AAAA,UACR,SAAS;AAAA,UACT,QAAQ;AAAA,QACV;AAAA,MACF;AAAA,MACA,KAAK,QAAQ;AACX,yBAAiB,KAAK,qBAAqB,+CAA+C;AAC1F,gBAAQ,IAAI,8BAAyB;AACrC,iBAAS,6BAA6B,EAAE,KAAK,OAAO,UAAU,CAAC;AAC/D,eAAO,EAAE,QAAQ,WAAW,SAAS,gCAAgC,QAAQ,SAAS;AAAA,MACxF;AAAA,IACF;AAAA,EACF,SAAS,KAAK;AACZ,UAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,WAAO,EAAE,QAAQ,SAAS,SAAS,KAAK,QAAQ,SAAS;AAAA,EAC3D;AACF;AAEO,SAAS,aAAa,QAAsB;AACjD,QAAM,SAAS,UAAU,QAAQ,QAAQ,IAAI,CAAC;AAC9C,MAAI,OAAO,WAAW,WAAW;AAC/B,YAAQ,IAAI;AAAA,WAAS,OAAO,OAAO;AAAA,CAAI;AAAA,EACzC,OAAO;AACL,YAAQ,MAAM;AAAA,WAAS,OAAO,OAAO;AAAA,CAAI;AACzC,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;","names":[]}
@@ -2,11 +2,11 @@
2
2
  import "tsx/esm";
3
3
  import {
4
4
  nodeAdapter
5
- } from "./chunk-MWYSRZI4.js";
5
+ } from "./chunk-EQV67HZL.js";
6
6
  import {
7
7
  assertServicesUnsupported,
8
8
  readManifest
9
- } from "./chunk-X32KQH5C.js";
9
+ } from "./chunk-CCVC6P6B.js";
10
10
  import "./chunk-KT3MWNZG.js";
11
11
 
12
12
  // src/adapters/deno-deploy.ts
@@ -105,4 +105,4 @@ export {
105
105
  denoDeployAdapter,
106
106
  renderDenoEntry
107
107
  };
108
- //# sourceMappingURL=deno-deploy-O73NBXIW.js.map
108
+ //# sourceMappingURL=deno-deploy-3QHJ3AJQ.js.map
@@ -8,18 +8,18 @@ import {
8
8
  } from "./chunk-HNBWZKIQ.js";
9
9
  import {
10
10
  theoPluginAsync
11
- } from "./chunk-JD7AQNJS.js";
12
- import "./chunk-S74FECKW.js";
11
+ } from "./chunk-4NLIESWK.js";
12
+ import "./chunk-D4SV7JOG.js";
13
13
  import {
14
14
  loadConfig,
15
15
  loadEnv
16
- } from "./chunk-DUKXQNM7.js";
17
- import "./chunk-FGOX37NB.js";
16
+ } from "./chunk-IHMJV2OK.js";
17
+ import "./chunk-BNGBG2SQ.js";
18
18
  import {
19
19
  orchestrateDev
20
- } from "./chunk-X32KQH5C.js";
20
+ } from "./chunk-CCVC6P6B.js";
21
21
  import "./chunk-5ODOE6EF.js";
22
- import "./chunk-CG563V5M.js";
22
+ import "./chunk-IEES3CHD.js";
23
23
  import "./chunk-P2RS3WWY.js";
24
24
  import "./chunk-UVHRD33F.js";
25
25
  import "./chunk-KT3MWNZG.js";
@@ -59,7 +59,15 @@ async function startDevServer(cwd, options) {
59
59
  server = await createServer({
60
60
  root: cwd,
61
61
  plugins: [react(), ...theoPlugins],
62
- server: { port },
62
+ server: {
63
+ port,
64
+ host: config.host,
65
+ open: config.open,
66
+ strictPort: config.strictPort,
67
+ warmup: config.warmup ?? {
68
+ clientFiles: ["./app/**/*.tsx", "./app/**/*.ts"]
69
+ }
70
+ },
63
71
  logLevel: options?.port === 0 ? "silent" : void 0
64
72
  });
65
73
  await server.listen();
@@ -89,4 +97,4 @@ export {
89
97
  devCommand,
90
98
  startDevServer
91
99
  };
92
- //# sourceMappingURL=dev-ZU46C5AZ.js.map
100
+ //# sourceMappingURL=dev-MHCQ5RD7.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/commands/dev.ts"],"sourcesContent":["import react from '@vitejs/plugin-react'\nimport { createServer, type Plugin, type ViteDevServer } from 'vite'\n\nimport { loadConfig } from '../../config/load-config.js'\nimport { loadEnv } from '../../config/load-env.js'\nimport { validateProjectStructure } from '../../core/validate-structure.js'\nimport { orchestrateDev } from '../../services/index.js'\nimport { theoPluginAsync } from '../../vite-plugin/index.js'\nimport { preflightNodeAndBindings } from '../preflight-node-version.js'\n\ninterface DevOptions {\n port?: number\n}\n\nexport async function startDevServer(cwd: string, options?: DevOptions): Promise<ViteDevServer> {\n // Preflight (FIRST — BEFORE anything that touches native bindings):\n // verifies Node version + native binding ABI match. Emits actionable\n // error referencing `nvm use` + `pnpm rebuild` when the dev server\n // was spawned under the wrong Node (common gotcha with `nohup env ...`\n // stripping the nvm PATH prefix).\n preflightNodeAndBindings(cwd)\n\n // Phase 1 (T1.2) — Load .env files into process.env BEFORE any module\n // reads them. Must run before loadConfig() so theo.config.ts functions\n // referencing process.env.* resolve correctly.\n loadEnv({ cwd, mode: 'development' })\n\n const config = await loadConfig(cwd)\n validateProjectStructure(cwd)\n\n // Wave 2 (T1.1) — spawn polyglot services BEFORE Vite. Healthcheck gates\n // readiness. Empty `services: {}` → early return (Wave 1 BC preserved).\n const orchestration = await orchestrateDev({\n cwd,\n services: config.services,\n })\n if (!orchestration.allHealthy) {\n await orchestration.stop()\n throw new Error(\n `[services] services failed healthcheck: ${orchestration.unhealthy.join(', ')}. ` +\n `Check that each declared service binds its port and responds 200 on its ` +\n `healthcheck path within 30s.`,\n )\n }\n\n // Phase 7 — legacy fs-mtime sweep removed: SDK's Agent.registry handles\n // LRU + idle eviction natively (configurable via theo.config.ts >\n // agents.registry; lazy-configured on first request).\n\n const port = options?.port ?? config.port\n // Narrow the rateLimit union: only the legacy flat shape (windowMs+max)\n // flows into the theoPlugin's RateLimitConfig parameter. The per-route\n // variant is consumed inside the api-middleware via the loaded user\n // config separately.\n const flatRateLimit =\n config.rateLimit && 'windowMs' in config.rateLimit && 'max' in config.rateLimit\n ? config.rateLimit\n : undefined\n // theoPluginAsync auto-chains @theokit/ui + @tailwindcss/vite via\n // top-level Plugin[] return (sync `theoPlugin()` factory's config()\n // hook returning {plugins:[...]} is silently dropped by Vite — see\n // commit history). Spread the result so Vite flattens them.\n let server: ViteDevServer\n try {\n const theoPlugins = await theoPluginAsync({\n root: cwd,\n rateLimit: flatRateLimit,\n ssr: config.ssr,\n // Wave 2 (T3.1) — wire typed-client plugin when services declared.\n services: config.services,\n // T4.1 (canvas-ecosystem-refactor / ADR D6) — passthrough peer-deps\n // that plugins import dynamically (e.g., mermaid via plugin-canvas).\n viteOptimizeDeps: config.viteOptimizeDeps,\n })\n server = await createServer({\n root: cwd,\n plugins: [react(), ...theoPlugins] as Plugin[],\n server: {\n port,\n host: config.host,\n open: config.open,\n strictPort: config.strictPort,\n warmup: config.warmup ?? {\n clientFiles: ['./app/**/*.tsx', './app/**/*.ts'],\n },\n },\n logLevel: options?.port === 0 ? 'silent' : undefined,\n })\n\n await server.listen()\n } catch (err) {\n // EC-1 / try-finally pattern: if Vite create/listen fails AFTER services\n // started, stop them so we don't leak child processes.\n await orchestration.stop()\n throw err\n }\n\n // EC-1 fix: attach orchestration.stop() to the underlying HTTP server's\n // close event via Node-native API. We do NOT mutate `server.close`\n // (fragile across Vite upgrades). httpServer is `http.Server | null`.\n server.httpServer?.on('close', () => {\n void orchestration.stop()\n })\n\n return server\n}\n\nexport async function devCommand(options: DevOptions): Promise<void> {\n try {\n const cwd = process.cwd()\n const server = await startDevServer(cwd, options)\n server.printUrls()\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n console.error(`\\n ✗ ${msg}\\n`)\n process.exit(1)\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,OAAO,WAAW;AAClB,SAAS,oBAAqD;AAa9D,eAAsB,eAAe,KAAa,SAA8C;AAM9F,2BAAyB,GAAG;AAK5B,UAAQ,EAAE,KAAK,MAAM,cAAc,CAAC;AAEpC,QAAM,SAAS,MAAM,WAAW,GAAG;AACnC,2BAAyB,GAAG;AAI5B,QAAM,gBAAgB,MAAM,eAAe;AAAA,IACzC;AAAA,IACA,UAAU,OAAO;AAAA,EACnB,CAAC;AACD,MAAI,CAAC,cAAc,YAAY;AAC7B,UAAM,cAAc,KAAK;AACzB,UAAM,IAAI;AAAA,MACR,2CAA2C,cAAc,UAAU,KAAK,IAAI,CAAC;AAAA,IAG/E;AAAA,EACF;AAMA,QAAM,OAAO,SAAS,QAAQ,OAAO;AAKrC,QAAM,gBACJ,OAAO,aAAa,cAAc,OAAO,aAAa,SAAS,OAAO,YAClE,OAAO,YACP;AAKN,MAAI;AACJ,MAAI;AACF,UAAM,cAAc,MAAM,gBAAgB;AAAA,MACxC,MAAM;AAAA,MACN,WAAW;AAAA,MACX,KAAK,OAAO;AAAA;AAAA,MAEZ,UAAU,OAAO;AAAA;AAAA;AAAA,MAGjB,kBAAkB,OAAO;AAAA,IAC3B,CAAC;AACD,aAAS,MAAM,aAAa;AAAA,MAC1B,MAAM;AAAA,MACN,SAAS,CAAC,MAAM,GAAG,GAAG,WAAW;AAAA,MACjC,QAAQ;AAAA,QACN;AAAA,QACA,MAAM,OAAO;AAAA,QACb,MAAM,OAAO;AAAA,QACb,YAAY,OAAO;AAAA,QACnB,QAAQ,OAAO,UAAU;AAAA,UACvB,aAAa,CAAC,kBAAkB,eAAe;AAAA,QACjD;AAAA,MACF;AAAA,MACA,UAAU,SAAS,SAAS,IAAI,WAAW;AAAA,IAC7C,CAAC;AAED,UAAM,OAAO,OAAO;AAAA,EACtB,SAAS,KAAK;AAGZ,UAAM,cAAc,KAAK;AACzB,UAAM;AAAA,EACR;AAKA,SAAO,YAAY,GAAG,SAAS,MAAM;AACnC,SAAK,cAAc,KAAK;AAAA,EAC1B,CAAC;AAED,SAAO;AACT;AAEA,eAAsB,WAAW,SAAoC;AACnE,MAAI;AACF,UAAM,MAAM,QAAQ,IAAI;AACxB,UAAM,SAAS,MAAM,eAAe,KAAK,OAAO;AAChD,WAAO,UAAU;AAAA,EACnB,SAAS,KAAK;AACZ,UAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,YAAQ,MAAM;AAAA,WAAS,GAAG;AAAA,CAAI;AAC9B,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;","names":[]}
@@ -3,7 +3,7 @@ import "tsx/esm";
3
3
  import {
4
4
  emitOpenApi,
5
5
  loadRoutesForOpenApi
6
- } from "./chunk-WGHJD6I7.js";
6
+ } from "./chunk-JAIKGP3Q.js";
7
7
  import {
8
8
  generateManifest
9
9
  } from "./chunk-HDA6M7P4.js";
@@ -41,4 +41,4 @@ export {
41
41
  _resetInFlightForTests,
42
42
  reEmitOpenApi
43
43
  };
44
- //# sourceMappingURL=dev-emit-66FCOS7V.js.map
44
+ //# sourceMappingURL=dev-emit-4WG3B5BM.js.map
@@ -13,6 +13,12 @@ import { join } from "path";
13
13
 
14
14
  // src/vite-plugin/openapi-emit/zod-to-openapi.ts
15
15
  import { z } from "zod";
16
+ var ZodToOpenApiError = class extends Error {
17
+ constructor(message) {
18
+ super(message);
19
+ this.name = "ZodToOpenApiError";
20
+ }
21
+ };
16
22
  function zodToOpenApiSchema(schema, options = {}) {
17
23
  const ctx = options.ctx ?? { seen: /* @__PURE__ */ new Map(), components: {} };
18
24
  const name = options.name;
@@ -28,42 +34,92 @@ function zodToOpenApiSchema(schema, options = {}) {
28
34
  }
29
35
  return convertSchema(schema, ctx);
30
36
  }
37
+ function zodDef(schema) {
38
+ return schema.def;
39
+ }
31
40
  function convertSchema(schema, ctx) {
32
41
  const existing = ctx.seen.get(schema);
33
42
  if (existing !== void 0) {
34
43
  return { $ref: `#/components/schemas/${existing}` };
35
44
  }
45
+ const def = zodDef(schema);
46
+ if (def?.type === "function") {
47
+ throw new ZodToOpenApiError(
48
+ "z.function() cannot be represented in an OpenAPI schema (functions are not serializable)."
49
+ );
50
+ }
51
+ if (def?.type === "pipe" && def.in !== void 0) {
52
+ return convertSchema(def.in, ctx);
53
+ }
36
54
  try {
37
55
  const jsonSchema = z.toJSONSchema(schema);
38
- return toOpenApi3(jsonSchema);
39
- } catch {
56
+ const out = toOpenApi3(jsonSchema);
57
+ if (def?.type === "union" && def.discriminator !== void 0 && out.oneOf !== void 0) {
58
+ out.discriminator = { propertyName: def.discriminator };
59
+ }
60
+ return out;
61
+ } catch (err) {
62
+ if (err instanceof ZodToOpenApiError) throw err;
40
63
  return {};
41
64
  }
42
65
  }
66
+ var SAFE_INT_MIN = Number.MIN_SAFE_INTEGER;
67
+ var SAFE_INT_MAX = Number.MAX_SAFE_INTEGER;
68
+ function isRecord(v) {
69
+ return v !== null && typeof v === "object" && !Array.isArray(v);
70
+ }
71
+ function isNoiseKey(key, value, isInteger, hasFormat) {
72
+ if (key === "pattern" && hasFormat) return true;
73
+ if (isInteger && key === "minimum" && value === SAFE_INT_MIN) return true;
74
+ if (isInteger && key === "maximum" && value === SAFE_INT_MAX) return true;
75
+ return false;
76
+ }
77
+ function normalizeValue(key, value) {
78
+ if (key === "properties" && isRecord(value)) {
79
+ const props = {};
80
+ for (const [pk, pv] of Object.entries(value)) props[pk] = isRecord(pv) ? toOpenApi3(pv) : pv;
81
+ return props;
82
+ }
83
+ if (key === "items" && isRecord(value)) return toOpenApi3(value);
84
+ if ((key === "anyOf" || key === "oneOf" || key === "allOf") && Array.isArray(value)) {
85
+ const arr = value;
86
+ return arr.map((v) => isRecord(v) ? toOpenApi3(v) : v);
87
+ }
88
+ if (key === "additionalProperties" && isRecord(value)) return toOpenApi3(value);
89
+ return value;
90
+ }
91
+ function convertAnyOf(branches, rest) {
92
+ const records = branches.filter(isRecord);
93
+ const hasNull = records.some((b) => b.type === "null");
94
+ const nonNull = records.filter((b) => b.type !== "null");
95
+ if (hasNull && nonNull.length === 1) {
96
+ return { ...toOpenApi3(nonNull[0]), nullable: true };
97
+ }
98
+ const result = { oneOf: nonNull.map((b) => toOpenApi3(b)) };
99
+ if (hasNull) result.nullable = true;
100
+ for (const [k, v] of Object.entries(rest))
101
+ if (k !== "anyOf") result[k] = v;
102
+ return result;
103
+ }
43
104
  function toOpenApi3(js) {
44
105
  const { $schema: _, $defs: _defs, ...rest } = js;
106
+ if (Array.isArray(rest.anyOf)) return convertAnyOf(rest.anyOf, rest);
107
+ const isInteger = rest.type === "integer";
108
+ const hasFormat = typeof rest.format === "string";
45
109
  const out = {};
46
110
  for (const [key, value] of Object.entries(rest)) {
111
+ if (isNoiseKey(key, value, isInteger, hasFormat)) continue;
112
+ if (key === "const") {
113
+ out.enum = [value];
114
+ continue;
115
+ }
47
116
  if (key === "type" && Array.isArray(value)) {
48
- const types = value;
49
- const hasNull = types.includes("null");
117
+ const types = value.filter((t) => typeof t === "string");
50
118
  const nonNull = types.filter((t) => t !== "null");
51
119
  out.type = nonNull.length === 1 ? nonNull[0] : nonNull;
52
- if (hasNull) out.nullable = true;
53
- } else if (key === "properties" && value && typeof value === "object") {
54
- const props = {};
55
- for (const [pk, pv] of Object.entries(value)) {
56
- props[pk] = pv && typeof pv === "object" ? toOpenApi3(pv) : pv;
57
- }
58
- out.properties = props;
59
- } else if (key === "items" && value && typeof value === "object") {
60
- out.items = toOpenApi3(value);
61
- } else if ((key === "anyOf" || key === "oneOf" || key === "allOf") && Array.isArray(value)) {
62
- out[key] = value.map((v) => toOpenApi3(v));
63
- } else if (key === "additionalProperties" && value && typeof value === "object") {
64
- out.additionalProperties = toOpenApi3(value);
120
+ if (types.includes("null")) out.nullable = true;
65
121
  } else {
66
- out[key] = value;
122
+ out[key] = normalizeValue(key, value);
67
123
  }
68
124
  }
69
125
  return out;
@@ -96,8 +152,7 @@ function appendObjectAsParameters(schema, location, out, ctx) {
96
152
  const shape = schema.shape;
97
153
  if (shape === void 0) return;
98
154
  for (const [name, child] of Object.entries(shape)) {
99
- const childDef = child._def;
100
- const optional = childDef.typeName === "ZodOptional" || childDef.typeName === "ZodDefault";
155
+ const optional = child.safeParse(void 0).success;
101
156
  out.push({
102
157
  name,
103
158
  in: location,
@@ -284,4 +339,4 @@ export {
284
339
  _resetInFlightForTests,
285
340
  reEmitOpenApi
286
341
  };
287
- //# sourceMappingURL=dev-emit-JBVINGHU.js.map
342
+ //# sourceMappingURL=dev-emit-6DJUK6DT.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/vite-plugin/openapi-emit/emit.ts","../src/vite-plugin/openapi-emit/zod-to-openapi.ts","../src/vite-plugin/openapi-emit/load-routes.ts","../src/vite-plugin/openapi-emit/dev-emit.ts"],"sourcesContent":["/**\n * In-house `emitOpenApi()` orchestrator (build-time only).\n *\n * Pure transformation: takes a route manifest (already hydrated with Zod\n * schemas extracted from `defineRoute()` config) + the openapi config\n * block, builds an OpenAPI 3.x document, writes `<outDir>/openapi.json`,\n * returns the document for downstream callers (CLI logs, tests).\n *\n * Per G2 plan v1.1 T2.1. Modelled on trpc-openapi's\n * `generateOpenApiDocument` + encore's `Generator.Generate()`.\n *\n * NEVER ship to runtime — devDep-shaped artifact.\n *\n * Path templating: TheoKit's `:param` syntax is converted to OpenAPI's\n * `{param}` per the spec. Env-var override: `THEOKIT_OPENAPI_SERVER_URL`\n * overrides `servers[0].url` without rebuilding the config.\n */\n/* eslint-disable security/detect-non-literal-fs-filename --\n * Build-time emit. outDir is a config-controlled relative path. The\n * caller already refused absolute paths via theoConfigSchema.distDir\n * pattern; the openapi.outDir field follows the same convention.\n */\nimport { mkdirSync, writeFileSync } from 'node:fs'\nimport { join } from 'node:path'\n\nimport type { z } from 'zod'\n\nimport { zodToOpenApiSchema, type ConvertCtx, type OpenApiSchema } from './zod-to-openapi.js'\n\nexport interface OpenApiManifestRoute {\n /** TheoKit-style path with `:param` placeholders (`/users/:id`). */\n routePath: string\n /** Uppercase HTTP methods the route exports (`['GET','POST']`). */\n methods: string[]\n /** Optional `defineRoute({body})` schema. */\n body?: z.ZodType\n /** Optional `defineRoute({query})` schema. */\n query?: z.ZodType\n /** Optional `defineRoute({params})` schema. */\n params?: z.ZodType\n /** Optional `defineRoute({response})` schema. */\n response?: z.ZodType\n}\n\nexport interface OpenApiEmitConfig {\n servers: { url: string; description?: string }[]\n specVersion: '3.1.0' | '3.0.3'\n title: string\n version: string\n outDir: string\n}\n\nexport interface OpenApiOperation {\n operationId?: string\n parameters?: OpenApiParameter[]\n requestBody?: {\n required?: boolean\n content: Record<string, { schema: OpenApiSchema }>\n }\n responses: Record<\n string,\n { description: string; content?: Record<string, { schema: OpenApiSchema }> }\n >\n}\n\nexport interface OpenApiParameter {\n name: string\n in: 'path' | 'query' | 'header' | 'cookie'\n required: boolean\n schema: OpenApiSchema\n description?: string\n}\n\nexport type OpenApiPathItem = Partial<\n Record<'get' | 'post' | 'put' | 'patch' | 'delete' | 'head' | 'options', OpenApiOperation>\n>\n\nexport interface OpenApiDocument {\n openapi: '3.1.0' | '3.0.3'\n info: { title: string; version: string }\n servers: { url: string; description?: string }[]\n paths: Record<string, OpenApiPathItem>\n components?: { schemas?: Record<string, OpenApiSchema> }\n}\n\nexport interface EmitOpenApiInput {\n manifest: OpenApiManifestRoute[]\n config: OpenApiEmitConfig\n}\n\nexport interface EmitOpenApiResult {\n document: OpenApiDocument\n path: string\n}\n\nconst METHOD_TO_KEY: Record<string, keyof OpenApiPathItem> = {\n GET: 'get',\n POST: 'post',\n PUT: 'put',\n PATCH: 'patch',\n DELETE: 'delete',\n HEAD: 'head',\n OPTIONS: 'options',\n}\n\n/** Convert `/users/:id/posts/:postId?` → `/users/{id}/posts/{postId}`. */\nexport function templatePath(routePath: string): string {\n // Bounded quantifier (\\w{0,64}) is OSS-safe — TheoKit route param names\n // never exceed 64 chars in practice; cap prevents super-linear backtracking.\n return routePath.replace(/:([A-Za-z_]\\w{0,64})\\??/g, '{$1}')\n}\n\nfunction buildParameters(\n paramsSchema: z.ZodType | undefined,\n querySchema: z.ZodType | undefined,\n ctx: ConvertCtx,\n): OpenApiParameter[] {\n const out: OpenApiParameter[] = []\n if (paramsSchema !== undefined) {\n appendObjectAsParameters(paramsSchema, 'path', out, ctx)\n }\n if (querySchema !== undefined) {\n appendObjectAsParameters(querySchema, 'query', out, ctx)\n }\n return out\n}\n\nfunction appendObjectAsParameters(\n schema: z.ZodType,\n location: 'path' | 'query',\n out: OpenApiParameter[],\n ctx: ConvertCtx,\n): void {\n // We expect an object schema; if it's not, skip silently (caller already\n // validated upstream when scanning defineRoute()).\n const shape = (schema as unknown as { shape?: Record<string, z.ZodType> }).shape\n if (shape === undefined) return\n for (const [name, child] of Object.entries(shape)) {\n // A field is optional iff the schema accepts `undefined` (covers\n // `.optional()` + `.default()`). Runtime check via safeParse — robust\n // across zod versions, unlike reading the changed `_def.typeName` internal\n // (zod 3) / `def.type` (zod 4).\n const optional = child.safeParse(undefined).success\n out.push({\n name,\n in: location,\n required: location === 'path' ? true : !optional,\n schema: zodToOpenApiSchema(child, { ctx }),\n })\n }\n}\n\nfunction buildOperation(\n route: OpenApiManifestRoute,\n ctx: ConvertCtx,\n method: string,\n): OpenApiOperation {\n // Bounded sanitizer: two single-pass replacements (no nested quantifiers).\n const sanitized = route.routePath.replace(/[/:\\-{}]/g, '_').replace(/_+/g, '_')\n const operationId = `${method.toLowerCase()}_${sanitized.replace(/^_|_$/g, '')}`\n const op: OpenApiOperation = {\n operationId,\n responses: {\n '200': { description: 'OK' },\n },\n }\n\n const parameters = buildParameters(route.params, route.query, ctx)\n if (parameters.length > 0) op.parameters = parameters\n\n // Body only meaningful for write methods; we still attach if defined so\n // the document is honest about the contract.\n if (route.body !== undefined) {\n op.requestBody = {\n required: true,\n content: {\n 'application/json': { schema: zodToOpenApiSchema(route.body, { ctx }) },\n },\n }\n }\n\n if (route.response !== undefined) {\n op.responses['200'] = {\n description: 'OK',\n content: {\n 'application/json': { schema: zodToOpenApiSchema(route.response, { ctx }) },\n },\n }\n }\n\n return op\n}\n\nexport function emitOpenApi(input: EmitOpenApiInput): EmitOpenApiResult {\n const { manifest, config } = input\n\n const ctx: ConvertCtx = { seen: new Map(), components: {} }\n\n const paths: Record<string, OpenApiPathItem> = {}\n for (const route of manifest) {\n const templatedPath = templatePath(route.routePath)\n const item: OpenApiPathItem = paths[templatedPath] ?? {}\n for (const method of route.methods) {\n // Defensive: manifest emitter normalizes to uppercase, but if a\n // future scanner produces a non-HTTP verb the key lookup yields\n // undefined and we skip silently. TS narrows the indexed type to\n // keyof OpenApiPathItem; the runtime undefined check is honest.\n const key = METHOD_TO_KEY[method.toUpperCase()] as keyof OpenApiPathItem | undefined\n if (key === undefined) continue\n item[key] = buildOperation(route, ctx, method)\n }\n paths[templatedPath] = item\n }\n\n const servers = applyServerOverride(config.servers)\n\n const document: OpenApiDocument = {\n openapi: config.specVersion,\n info: { title: config.title, version: config.version },\n servers,\n paths,\n }\n\n if (Object.keys(ctx.components).length > 0) {\n document.components = { schemas: ctx.components }\n }\n\n mkdirSync(config.outDir, { recursive: true })\n const outPath = join(config.outDir, 'openapi.json')\n writeFileSync(outPath, `${JSON.stringify(document, null, 2)}\\n`, 'utf8')\n\n return { document, path: outPath }\n}\n\nfunction applyServerOverride(\n servers: { url: string; description?: string }[],\n): { url: string; description?: string }[] {\n const override = process.env.THEOKIT_OPENAPI_SERVER_URL\n if (override === undefined || override === '') return servers\n if (servers.length === 0) return [{ url: override }]\n const [first, ...rest] = servers\n return [\n {\n url: override,\n ...(first.description !== undefined ? { description: first.description } : {}),\n },\n ...rest,\n ]\n}\n","/**\n * Zod → OpenAPI 3.0 Schema converter (build-time only).\n *\n * Uses Zod v4's native `z.toJSONSchema()` and post-processes\n * the JSON Schema output into OpenAPI 3.0 format:\n * - Removes `$schema` (invalid in OpenAPI 3.0)\n * - Converts `type: [\"string\", \"null\"]` → `{ type: \"string\", nullable: true }`\n * - Recursively normalizes nested schemas\n *\n * NEVER ship to runtime — devDep-shaped artifact.\n */\nimport { z } from 'zod'\n\nexport interface OpenApiSchema {\n type?: 'string' | 'number' | 'integer' | 'boolean' | 'array' | 'object' | 'null'\n format?: string\n items?: OpenApiSchema\n properties?: Record<string, OpenApiSchema>\n required?: string[]\n additionalProperties?: boolean | OpenApiSchema\n oneOf?: OpenApiSchema[]\n anyOf?: OpenApiSchema[]\n allOf?: OpenApiSchema[]\n discriminator?: { propertyName: string; mapping?: Record<string, string> }\n enum?: unknown[]\n nullable?: boolean\n description?: string\n default?: unknown\n $ref?: string\n}\n\nexport interface ConvertCtx {\n seen: Map<z.ZodType, string>\n components: Record<string, OpenApiSchema>\n}\n\nexport interface ConvertOptions {\n ctx?: ConvertCtx\n name?: string\n}\n\nexport class ZodToOpenApiError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'ZodToOpenApiError'\n }\n}\n\nexport function zodToOpenApiSchema(schema: z.ZodType, options: ConvertOptions = {}): OpenApiSchema {\n const ctx: ConvertCtx = options.ctx ?? { seen: new Map(), components: {} }\n\n const name = options.name\n if (name !== undefined) {\n if (Object.prototype.hasOwnProperty.call(ctx.components, name)) {\n return { $ref: `#/components/schemas/${name}` }\n }\n ctx.seen.set(schema, name)\n ctx.components[name] = {}\n const body = convertSchema(schema, ctx)\n ctx.components[name] = body\n return { $ref: `#/components/schemas/${name}` }\n }\n\n return convertSchema(schema, ctx)\n}\n\ninterface ZodInternalDef {\n type?: string\n discriminator?: string\n in?: z.ZodType\n}\n\n/** Read zod v4's internal schema def (the `.def` getter) without a hard `any`. */\nfunction zodDef(schema: z.ZodType): ZodInternalDef | undefined {\n return (schema as unknown as { def?: ZodInternalDef }).def\n}\n\nfunction convertSchema(schema: z.ZodType, ctx: ConvertCtx): OpenApiSchema {\n const existing = ctx.seen.get(schema)\n if (existing !== undefined) {\n return { $ref: `#/components/schemas/${existing}` }\n }\n\n const def = zodDef(schema)\n // Fail loud on schema kinds that have no OpenAPI representation (rather than\n // swallowing the zod throw into `{}`). z.function() is the canonical case.\n if (def?.type === 'function') {\n throw new ZodToOpenApiError(\n 'z.function() cannot be represented in an OpenAPI schema (functions are not serializable).',\n )\n }\n\n // A transform / pipe (`z.string().transform(...)`) has no JSON-Schema of its\n // own — zod throws. The wire shape is the INPUT (transforms run post-parse),\n // so emit the input schema. This avoids the global `io: 'input'` mode, which\n // would also flip object `additionalProperties` semantics.\n if (def?.type === 'pipe' && def.in !== undefined) {\n return convertSchema(def.in, ctx)\n }\n\n try {\n const jsonSchema = z.toJSONSchema(schema) as Record<string, unknown>\n const out = toOpenApi3(jsonSchema)\n // zod v4 emits a discriminated union as `oneOf` but drops the discriminator\n // key; re-attach it from the zod def so OpenAPI consumers can branch.\n if (def?.type === 'union' && def.discriminator !== undefined && out.oneOf !== undefined) {\n out.discriminator = { propertyName: def.discriminator }\n }\n return out\n } catch (err) {\n if (err instanceof ZodToOpenApiError) throw err\n return {}\n }\n}\n\n/** JS safe-integer bounds zod v4 attaches to `.int()` — noise for OpenAPI, stripped. */\nconst SAFE_INT_MIN = Number.MIN_SAFE_INTEGER\nconst SAFE_INT_MAX = Number.MAX_SAFE_INTEGER\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return v !== null && typeof v === 'object' && !Array.isArray(v)\n}\n\n/** Drop zod-v4 noise keys: redundant `pattern` when `format` is set; JS safe-integer sentinel bounds. */\nfunction isNoiseKey(key: string, value: unknown, isInteger: boolean, hasFormat: boolean): boolean {\n if (key === 'pattern' && hasFormat) return true\n if (isInteger && key === 'minimum' && value === SAFE_INT_MIN) return true\n if (isInteger && key === 'maximum' && value === SAFE_INT_MAX) return true\n return false\n}\n\n/** Recursively normalize one JSON-Schema value (properties/items/*Of/additionalProperties). */\nfunction normalizeValue(key: string, value: unknown): unknown {\n if (key === 'properties' && isRecord(value)) {\n const props: Record<string, unknown> = {}\n for (const [pk, pv] of Object.entries(value)) props[pk] = isRecord(pv) ? toOpenApi3(pv) : pv\n return props\n }\n if (key === 'items' && isRecord(value)) return toOpenApi3(value)\n if ((key === 'anyOf' || key === 'oneOf' || key === 'allOf') && Array.isArray(value)) {\n const arr: unknown[] = value\n return arr.map((v) => (isRecord(v) ? toOpenApi3(v) : v))\n }\n if (key === 'additionalProperties' && isRecord(value)) return toOpenApi3(value)\n return value\n}\n\n/** Convert zod v4's `anyOf` (used for `.nullable()` + `z.union()`) to OpenAPI 3.0 shape. */\nfunction convertAnyOf(branches: unknown[], rest: Record<string, unknown>): OpenApiSchema {\n const records = branches.filter(isRecord)\n const hasNull = records.some((b) => b.type === 'null')\n const nonNull = records.filter((b) => b.type !== 'null')\n if (hasNull && nonNull.length === 1) {\n return { ...toOpenApi3(nonNull[0]), nullable: true }\n }\n const result: OpenApiSchema = { oneOf: nonNull.map((b) => toOpenApi3(b)) }\n if (hasNull) result.nullable = true\n for (const [k, v] of Object.entries(rest))\n if (k !== 'anyOf') (result as Record<string, unknown>)[k] = v\n return result\n}\n\n/**\n * Post-process JSON Schema (draft-2020-12) → OpenAPI 3.0:\n * - strip `$schema`/`$defs`\n * - `.nullable()`/union `anyOf` → `nullable: true` / `oneOf`\n * - `type: [\"string\",\"null\"]` → `{ type: \"string\", nullable: true }`\n * - drop zod-v4 noise (redundant pattern, safe-integer bounds)\n * - recurse into nested schemas\n */\nfunction toOpenApi3(js: Record<string, unknown>): OpenApiSchema {\n const { $schema: _, $defs: _defs, ...rest } = js\n if (Array.isArray(rest.anyOf)) return convertAnyOf(rest.anyOf, rest)\n\n const isInteger = rest.type === 'integer'\n const hasFormat = typeof rest.format === 'string'\n const out: Record<string, unknown> = {}\n\n for (const [key, value] of Object.entries(rest)) {\n if (isNoiseKey(key, value, isInteger, hasFormat)) continue\n // `const` is JSON-Schema / OpenAPI-3.1 only; `enum: [x]` is the 3.0-and-3.1\n // compatible spelling. zod v4 emits `const` for literals (discriminator tags).\n if (key === 'const') {\n out.enum = [value]\n continue\n }\n if (key === 'type' && Array.isArray(value)) {\n const types = value.filter((t): t is string => typeof t === 'string')\n const nonNull = types.filter((t) => t !== 'null')\n out.type = nonNull.length === 1 ? nonNull[0] : nonNull\n if (types.includes('null')) out.nullable = true\n } else {\n out[key] = normalizeValue(key, value)\n }\n }\n\n return out\n}\n","/**\n * Build-time route loader for OpenAPI emit.\n *\n * Takes the G1 manifest (filePath + routePath + methods) and hydrates each\n * route's Zod schemas by dynamically importing the module. `defineRoute`\n * is an identity function, so the imported config exposes `body/query/\n * params/response` directly without any AST gymnastics.\n *\n * Supports both export shapes:\n * 1. `export const POST = defineRoute({...})` (per-method named exports)\n * 2. `export default defineRoute({...})` (single-export legacy shape)\n *\n * Per G2 plan v1.1 T2.2. Uses Vite's `ssrLoadModule` because route files\n * are TS at build time — Node's native loader doesn't transpile.\n */\nimport { resolve } from 'node:path'\n\nimport type { z } from 'zod'\n\nimport type { ManifestRoute } from '../../server/scan/manifest.js'\n\nimport type { OpenApiManifestRoute } from './emit.js'\n\ninterface RouteConfigShape {\n body?: z.ZodType\n query?: z.ZodType\n params?: z.ZodType\n response?: z.ZodType\n}\n\ninterface ViteLikeServer {\n ssrLoadModule: (id: string) => Promise<Record<string, unknown>>\n close: () => Promise<void>\n}\n\ninterface DefaultLoader {\n load: (absPath: string) => Promise<Record<string, unknown>>\n dispose: () => Promise<void>\n}\n\n/** Method names recognized as per-route named exports (UPPERCASE). */\nconst HTTP_METHOD_KEYS = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'] as const\n\nexport interface LoadRoutesOptions {\n serverDir: string\n routes: ManifestRoute[]\n /** Injectable for tests; defaults to a fresh Vite SSR dev server. */\n loadModule?: (absPath: string) => Promise<Record<string, unknown>>\n}\n\n/**\n * Hydrate manifest routes with Zod schemas extracted from their modules.\n *\n * Returns one `OpenApiManifestRoute` per (file × method) tuple. If a route\n * file declares multiple methods (`GET` + `POST`), each method gets its\n * own entry with the schemas from that method's `defineRoute()` call.\n *\n * Routes that fail to load are skipped with a console warning — the emit\n * should be best-effort, not a hard build failure.\n *\n * The default Vite loader is created once per call and disposed in the\n * `finally` block so the underlying server is released even when route\n * loading throws.\n */\nexport async function loadRoutesForOpenApi(\n options: LoadRoutesOptions,\n): Promise<OpenApiManifestRoute[]> {\n const { serverDir, routes } = options\n let loadModule = options.loadModule\n let dispose: (() => Promise<void>) | undefined\n if (loadModule === undefined) {\n const created = await createDefaultLoader(serverDir)\n loadModule = created.load\n dispose = created.dispose\n }\n\n const out: OpenApiManifestRoute[] = []\n try {\n for (const r of routes) {\n const abs = resolve(serverDir, r.filePath)\n let mod: Record<string, unknown>\n try {\n mod = await loadModule(abs)\n } catch (err) {\n console.warn(\n `[openapi-emit] Skipping ${r.filePath}: load failed (${(err as Error).message})`,\n )\n continue\n }\n\n const methods = r.methods ?? HTTP_METHOD_KEYS.filter((m) => mod[m] !== undefined)\n if (methods.length === 0) {\n // Fall back to default export when no method-named exports detected.\n const def = mod.default\n if (def !== undefined && def !== null) {\n out.push({ routePath: r.routePath, methods: ['GET'], ...extractSchemas(def) })\n }\n continue\n }\n\n for (const method of methods) {\n const handler = mod[method] ?? mod.default\n if (handler === undefined || handler === null) continue\n out.push({ routePath: r.routePath, methods: [method], ...extractSchemas(handler) })\n }\n }\n } finally {\n if (dispose !== undefined) {\n await dispose()\n }\n }\n return out\n}\n\nfunction extractSchemas(handlerExport: unknown): RouteConfigShape {\n if (typeof handlerExport !== 'object' || handlerExport === null) return {}\n const cfg = handlerExport as RouteConfigShape\n const out: RouteConfigShape = {}\n if (cfg.body !== undefined) out.body = cfg.body\n if (cfg.query !== undefined) out.query = cfg.query\n if (cfg.params !== undefined) out.params = cfg.params\n if (cfg.response !== undefined) out.response = cfg.response\n return out\n}\n\n/**\n * Default loader: spin up a minimal Vite SSR dev server (no HMR, no\n * middlewares) just to use its `ssrLoadModule`. Vite handles TS, ESM, and\n * import resolution for free.\n *\n * Returns `{load, dispose}` — the caller owns the lifecycle and MUST\n * call `dispose()` (typically in a `finally`) so the server is closed.\n */\nasync function createDefaultLoader(serverDir: string): Promise<DefaultLoader> {\n // Vite is a peerDep in build flows; import dynamically.\n const { createServer } = await import('vite')\n const server = (await createServer({\n root: serverDir,\n configFile: false,\n server: { middlewareMode: true },\n appType: 'custom',\n logLevel: 'silent',\n })) as unknown as ViteLikeServer\n\n const swallow = (): void => {\n /* eat close errors — best-effort cleanup */\n }\n return {\n load: async (absPath) => server.ssrLoadModule(absPath),\n dispose: async () => {\n await server.close().catch(swallow)\n },\n }\n}\n","/**\n * Dev-mode OpenAPI emit helper for `theokit dev`.\n *\n * Per P#3 plan v1.3 T1.1 (ADRs D3 + D4 + EC-8). Called once on `theokit dev`\n * boot AND on every chokidar 'change'/'add'/'unlink' watcher event for\n * route files when `config.openapi !== undefined`. Re-runs G2's\n * `emitOpenApi()` orchestrator to keep `<distDir>/openapi.json` always\n * fresh in dev.\n *\n * EC-8 absorbed (single-flight guard): if a previous invocation is still\n * awaiting `loadRoutesForOpenApi` (Vite SSR loader can hang on circular\n * imports or syntax errors), skip the new call and emit a `console.warn`\n * so watcher events don't pile up + dev server doesn't deadlock.\n *\n * Best-effort: ALL errors caught + warned. Never throws out of the\n * exported function (would crash Vite dev's chokidar handler).\n *\n * NEVER ship to runtime — dev-only artifact gated on `config.openapi`.\n */\nimport { generateManifest } from '../../server/scan/manifest.js'\n\nimport { emitOpenApi } from './emit.js'\nimport { loadRoutesForOpenApi } from './load-routes.js'\n\ninterface DevEmitConfig {\n servers: { url: string; description?: string }[]\n specVersion: '3.1.0' | '3.0.3'\n title: string\n version: string\n}\n\nlet inFlight = false\n\nexport async function reEmitOpenApi(\n serverDir: string,\n distDir: string,\n openApiConfig: DevEmitConfig,\n): Promise<void> {\n if (inFlight) {\n console.warn(\n '[openapi-emit] previous emit still running; skipping watcher event (EC-8 single-flight guard)',\n )\n return\n }\n inFlight = true\n try {\n const manifest = generateManifest(serverDir)\n const hydrated = await loadRoutesForOpenApi({ serverDir, routes: manifest.routes })\n emitOpenApi({\n manifest: hydrated,\n config: { ...openApiConfig, outDir: distDir },\n })\n } catch (err) {\n console.warn(`[openapi-emit] re-emit failed: ${(err as Error).message}`)\n } finally {\n inFlight = false\n }\n}\n\n/** Test seam — resets the inFlight flag between tests. NOT for production use. */\nexport function _resetInFlightForTests(): void {\n inFlight = false\n}\n"],"mappings":"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","names":[]}
@@ -84,6 +84,7 @@ function subscribeToServerEvents(dispatcher2) {
84
84
  hot.off?.(CHANNEL_CSRF_WARN, csrfHandler);
85
85
  hot.off?.(CHANNEL_MANIFEST, manifestHandler);
86
86
  hot.off?.(CHANNEL_ROUTE_MATCHED, routeMatchedHandler);
87
+ hot.off?.(CHANNEL_AGENT_STREAM, agentStreamHandler);
87
88
  }
88
89
  };
89
90
  }