@apollo-deploy/tesseract 1.9.0 → 2.1.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 (194) hide show
  1. package/README.md +218 -110
  2. package/dist/adapters/csharp/index.d.ts +5 -8
  3. package/dist/adapters/csharp/index.d.ts.map +1 -1
  4. package/dist/adapters/csharp/index.js +314 -74
  5. package/dist/adapters/csharp/index.js.map +1 -1
  6. package/dist/adapters/documentation.d.ts +17 -0
  7. package/dist/adapters/documentation.d.ts.map +1 -0
  8. package/dist/adapters/documentation.js +268 -0
  9. package/dist/adapters/documentation.js.map +1 -0
  10. package/dist/adapters/go/index.d.ts +5 -8
  11. package/dist/adapters/go/index.d.ts.map +1 -1
  12. package/dist/adapters/go/index.js +197 -101
  13. package/dist/adapters/go/index.js.map +1 -1
  14. package/dist/adapters/kotlin/index.d.ts +5 -9
  15. package/dist/adapters/kotlin/index.d.ts.map +1 -1
  16. package/dist/adapters/kotlin/index.js +280 -212
  17. package/dist/adapters/kotlin/index.js.map +1 -1
  18. package/dist/adapters/php/index.d.ts +5 -15
  19. package/dist/adapters/php/index.d.ts.map +1 -1
  20. package/dist/adapters/php/index.js +362 -90
  21. package/dist/adapters/php/index.js.map +1 -1
  22. package/dist/adapters/python/index.d.ts +5 -8
  23. package/dist/adapters/python/index.d.ts.map +1 -1
  24. package/dist/adapters/python/index.js +240 -109
  25. package/dist/adapters/python/index.js.map +1 -1
  26. package/dist/adapters/ruby/index.d.ts +3 -3
  27. package/dist/adapters/ruby/index.d.ts.map +1 -1
  28. package/dist/adapters/ruby/index.js +235 -46
  29. package/dist/adapters/ruby/index.js.map +1 -1
  30. package/dist/adapters/rust/index.d.ts +5 -9
  31. package/dist/adapters/rust/index.d.ts.map +1 -1
  32. package/dist/adapters/rust/index.js +237 -169
  33. package/dist/adapters/rust/index.js.map +1 -1
  34. package/dist/adapters/shared.d.ts +7 -0
  35. package/dist/adapters/shared.d.ts.map +1 -0
  36. package/dist/adapters/shared.js +68 -0
  37. package/dist/adapters/shared.js.map +1 -0
  38. package/dist/adapters/type-utils.d.ts +13 -0
  39. package/dist/adapters/type-utils.d.ts.map +1 -0
  40. package/dist/adapters/type-utils.js +105 -0
  41. package/dist/adapters/type-utils.js.map +1 -0
  42. package/dist/adapters/types.d.ts.map +1 -1
  43. package/dist/adapters/typescript/emitter/emitSchema.d.ts +2 -2
  44. package/dist/adapters/typescript/emitter/emitSchema.js +39 -27
  45. package/dist/adapters/typescript/emitter/emitSchema.js.map +1 -1
  46. package/dist/adapters/typescript/emitter/emitTypeScriptModels.d.ts +2 -2
  47. package/dist/adapters/typescript/emitter/emitTypeScriptModels.js +15 -15
  48. package/dist/adapters/typescript/emitter/importCollector.d.ts +2 -4
  49. package/dist/adapters/typescript/emitter/importCollector.d.ts.map +1 -1
  50. package/dist/adapters/typescript/emitter/importCollector.js +40 -50
  51. package/dist/adapters/typescript/emitter/importCollector.js.map +1 -1
  52. package/dist/adapters/typescript/emitter/parsers.d.ts +1 -1
  53. package/dist/adapters/typescript/emitter/parsers.js +13 -13
  54. package/dist/adapters/typescript/emitter/typeHoister.d.ts +1 -1
  55. package/dist/adapters/typescript/emitter/typeHoister.d.ts.map +1 -1
  56. package/dist/adapters/typescript/emitter/typeHoister.js +12 -20
  57. package/dist/adapters/typescript/emitter/typeHoister.js.map +1 -1
  58. package/dist/adapters/typescript/index.d.ts +3 -3
  59. package/dist/adapters/typescript/index.d.ts.map +1 -1
  60. package/dist/adapters/typescript/index.js +148 -166
  61. package/dist/adapters/typescript/index.js.map +1 -1
  62. package/dist/adapters/typescript/shared.d.ts +2 -2
  63. package/dist/adapters/typescript/shared.js +12 -12
  64. package/dist/cli.js +50 -37
  65. package/dist/cli.js.map +1 -1
  66. package/dist/collector.d.ts +32 -7
  67. package/dist/collector.d.ts.map +1 -1
  68. package/dist/collector.js +149 -49
  69. package/dist/collector.js.map +1 -1
  70. package/dist/elysia.js +2 -2
  71. package/dist/elysia.js.map +1 -1
  72. package/dist/express.d.ts.map +1 -1
  73. package/dist/express.js.map +1 -1
  74. package/dist/fastify.d.ts +9 -2
  75. package/dist/fastify.d.ts.map +1 -1
  76. package/dist/fastify.js +40 -21
  77. package/dist/fastify.js.map +1 -1
  78. package/dist/helpers/handlebars.d.ts +7 -16
  79. package/dist/helpers/handlebars.d.ts.map +1 -1
  80. package/dist/helpers/handlebars.js +127 -177
  81. package/dist/helpers/handlebars.js.map +1 -1
  82. package/dist/hono.d.ts.map +1 -1
  83. package/dist/hono.js.map +1 -1
  84. package/dist/index.d.ts +14 -12
  85. package/dist/index.d.ts.map +1 -1
  86. package/dist/index.js +32 -30
  87. package/dist/index.js.map +1 -1
  88. package/dist/koa.d.ts.map +1 -1
  89. package/dist/koa.js.map +1 -1
  90. package/dist/nestjs.d.ts.map +1 -1
  91. package/dist/nestjs.js +41 -14
  92. package/dist/nestjs.js.map +1 -1
  93. package/dist/pipeline/enrich.d.ts +2 -13
  94. package/dist/pipeline/enrich.d.ts.map +1 -1
  95. package/dist/pipeline/enrich.js +157 -212
  96. package/dist/pipeline/enrich.js.map +1 -1
  97. package/dist/pipeline/intake.d.ts +3 -3
  98. package/dist/pipeline/intake.d.ts.map +1 -1
  99. package/dist/pipeline/intake.js +342 -238
  100. package/dist/pipeline/intake.js.map +1 -1
  101. package/dist/pipeline/write.d.ts +1 -14
  102. package/dist/pipeline/write.d.ts.map +1 -1
  103. package/dist/pipeline/write.js +73 -113
  104. package/dist/pipeline/write.js.map +1 -1
  105. package/dist/types/config.d.ts +14 -26
  106. package/dist/types/config.d.ts.map +1 -1
  107. package/dist/types/config.js +16 -12
  108. package/dist/types/config.js.map +1 -1
  109. package/dist/types/ir.d.ts +12 -8
  110. package/dist/types/ir.d.ts.map +1 -1
  111. package/dist/types/manifest.d.ts +10 -11
  112. package/dist/types/manifest.d.ts.map +1 -1
  113. package/dist/types/manifest.js +54 -14
  114. package/dist/types/manifest.js.map +1 -1
  115. package/dist/types/sdk-module.d.ts +2 -2
  116. package/dist/types/sdk-module.js +1 -1
  117. package/dist/utils/format.d.ts +1 -3
  118. package/dist/utils/format.d.ts.map +1 -1
  119. package/dist/utils/format.js +3 -10
  120. package/dist/utils/format.js.map +1 -1
  121. package/dist/utils/naming.d.ts.map +1 -1
  122. package/dist/utils/naming.js +174 -184
  123. package/dist/utils/naming.js.map +1 -1
  124. package/dist/utils/npm-token.d.ts +1 -17
  125. package/dist/utils/npm-token.d.ts.map +1 -1
  126. package/dist/utils/npm-token.js +27 -76
  127. package/dist/utils/npm-token.js.map +1 -1
  128. package/dist/utils/version.d.ts +14 -0
  129. package/dist/utils/version.d.ts.map +1 -0
  130. package/dist/utils/version.js +60 -0
  131. package/dist/utils/version.js.map +1 -0
  132. package/package.json +4 -3
  133. package/templates/csharp/client.hbs +26 -49
  134. package/templates/csharp/csproj.hbs +7 -0
  135. package/templates/csharp/domain.hbs +48 -130
  136. package/templates/csharp/errors.hbs +17 -25
  137. package/templates/csharp/readme.hbs +31 -44
  138. package/templates/csharp/transport.hbs +238 -136
  139. package/templates/csharp/types.hbs +30 -76
  140. package/templates/go/client.hbs +44 -109
  141. package/templates/go/domain.hbs +83 -25
  142. package/templates/go/go-mod.hbs +1 -4
  143. package/templates/go/readme.hbs +32 -29
  144. package/templates/go/transport.hbs +174 -173
  145. package/templates/go/types.hbs +17 -53
  146. package/templates/go/utils.hbs +3 -2
  147. package/templates/kotlin/build-gradle.hbs +1 -1
  148. package/templates/kotlin/client.hbs +18 -15
  149. package/templates/kotlin/domain.hbs +54 -51
  150. package/templates/kotlin/errors.hbs +1 -1
  151. package/templates/kotlin/readme.hbs +35 -137
  152. package/templates/kotlin/transport.hbs +140 -123
  153. package/templates/kotlin/types.hbs +30 -81
  154. package/templates/php/client.hbs +8 -46
  155. package/templates/php/composer.hbs +2 -1
  156. package/templates/php/domain.hbs +86 -117
  157. package/templates/php/errors.hbs +1 -1
  158. package/templates/php/readme.hbs +42 -49
  159. package/templates/php/transport.hbs +192 -145
  160. package/templates/php/types.hbs +63 -60
  161. package/templates/python/client.hbs +15 -2
  162. package/templates/python/domain.hbs +50 -108
  163. package/templates/python/pyproject.hbs +5 -0
  164. package/templates/python/readme.hbs +47 -30
  165. package/templates/python/resources-init.hbs +1 -1
  166. package/templates/python/transport.hbs +167 -53
  167. package/templates/python/types.hbs +22 -58
  168. package/templates/ruby/client.hbs +10 -6
  169. package/templates/ruby/domain.hbs +48 -67
  170. package/templates/ruby/errors.hbs +3 -3
  171. package/templates/ruby/gemspec.hbs +3 -10
  172. package/templates/ruby/index.hbs +3 -3
  173. package/templates/ruby/readme.hbs +33 -70
  174. package/templates/ruby/transport.hbs +129 -103
  175. package/templates/ruby/types.hbs +11 -16
  176. package/templates/ruby/version.hbs +1 -1
  177. package/templates/rust/cargo.hbs +2 -0
  178. package/templates/rust/client.hbs +10 -1
  179. package/templates/rust/domain.hbs +69 -52
  180. package/templates/rust/error.hbs +3 -1
  181. package/templates/rust/lib.hbs +4 -5
  182. package/templates/rust/readme.hbs +33 -46
  183. package/templates/rust/transport.hbs +170 -159
  184. package/templates/rust/types.hbs +34 -111
  185. package/templates/typescript/domain-class.hbs +14 -6
  186. package/templates/typescript/domain.hbs +13 -5
  187. package/templates/typescript/package-json.hbs +3 -1
  188. package/templates/typescript/readme.hbs +42 -42
  189. package/templates/typescript/transport.hbs +46 -8
  190. package/templates/typescript/types-errors.hbs +1 -1
  191. package/dist/adapters/typescript/model-emitter.d.ts +0 -13
  192. package/dist/adapters/typescript/model-emitter.d.ts.map +0 -1
  193. package/dist/adapters/typescript/model-emitter.js +0 -415
  194. package/dist/adapters/typescript/model-emitter.js.map +0 -1
package/dist/cli.js CHANGED
@@ -2,19 +2,19 @@
2
2
  /**
3
3
  * Tesseract CLI — manifest-first SDK generator (refactored, scalable).
4
4
  */
5
- import { Command } from "commander";
6
- import { readFileSync } from "node:fs";
7
- import { resolve, join, dirname } from "node:path";
8
- import { fileURLToPath } from "node:url";
9
- import { spawnSync } from "node:child_process";
10
- import { generate } from "./index.js";
5
+ import { Command } from 'commander';
6
+ import { readFileSync } from 'node:fs';
7
+ import { resolve, join, dirname } from 'node:path';
8
+ import { fileURLToPath } from 'node:url';
9
+ import { spawnSync } from 'node:child_process';
10
+ import { generate } from './index.js';
11
11
  const __dirname = dirname(fileURLToPath(import.meta.url));
12
12
  /**
13
13
  * Package metadata loader (isolated for testability + reuse)
14
14
  */
15
15
  function loadPackageVersion() {
16
- const pkgPath = join(__dirname, "..", "package.json");
17
- const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
16
+ const pkgPath = join(__dirname, '..', 'package.json');
17
+ const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
18
18
  return pkg.version;
19
19
  }
20
20
  /**
@@ -24,9 +24,10 @@ function buildConfig(opts) {
24
24
  return {
25
25
  input: resolve(opts.input),
26
26
  output: resolve(opts.output),
27
- language: opts.language ?? "typescript",
27
+ language: opts.language ?? 'typescript',
28
28
  packageName: opts.name,
29
29
  packageVersion: opts.packageVersion,
30
+ versionBump: opts.versionBump,
30
31
  npmToken: opts.npmToken,
31
32
  clientName: opts.clientName,
32
33
  baseUrl: opts.baseUrl,
@@ -42,12 +43,12 @@ function buildConfig(opts) {
42
43
  function printWarnings(warnings) {
43
44
  if (!warnings.length)
44
45
  return;
45
- console.warn("\nWarnings:");
46
+ console.warn('\nWarnings:');
46
47
  for (const w of warnings) {
47
48
  console.warn(` ⚠ ${w}`);
48
49
  }
49
50
  }
50
- function printFileList(files, prefix = " - ") {
51
+ function printFileList(files, prefix = ' - ') {
51
52
  for (const file of files) {
52
53
  console.log(`${prefix}${file}`);
53
54
  }
@@ -58,7 +59,7 @@ function printFileList(files, prefix = " - ") {
58
59
  function handleResult(opts, result) {
59
60
  printWarnings(result.warnings);
60
61
  switch (result.mode) {
61
- case "check":
62
+ case 'check':
62
63
  if (result.hasChanges) {
63
64
  console.error(`\n✗ Generated output is out of date: ${result.filesWritten} files would change`);
64
65
  printFileList(result.changedFiles);
@@ -66,7 +67,7 @@ function handleResult(opts, result) {
66
67
  }
67
68
  console.log(`\n✓ Generated output is up to date → ${opts.output}`);
68
69
  return;
69
- case "dry-run":
70
+ case 'dry-run':
70
71
  console.log(`\n✓ Dry run complete: ${result.filesWritten} files would change → ${opts.output}`);
71
72
  if (result.changedFiles.length) {
72
73
  printFileList(result.changedFiles);
@@ -74,12 +75,18 @@ function handleResult(opts, result) {
74
75
  if (result.filesSkipped > 0) {
75
76
  console.log(` ${result.filesSkipped} files unchanged`);
76
77
  }
78
+ if (result.filesDeleted > 0) {
79
+ console.log(` ${result.filesDeleted} stale files would be removed`);
80
+ }
77
81
  return;
78
82
  default:
79
83
  console.log(`\n✓ Generated ${result.filesWritten} files → ${opts.output}`);
80
84
  if (result.filesSkipped > 0) {
81
85
  console.log(` ${result.filesSkipped} files unchanged (skipped)`);
82
86
  }
87
+ if (result.filesDeleted > 0) {
88
+ console.log(` ${result.filesDeleted} stale files removed`);
89
+ }
83
90
  }
84
91
  }
85
92
  /**
@@ -87,7 +94,12 @@ function handleResult(opts, result) {
87
94
  */
88
95
  function validateFlags(opts) {
89
96
  if (opts.dryRun && opts.check) {
90
- console.error("\n✗ --dry-run and --check are mutually exclusive");
97
+ console.error('\n✗ --dry-run and --check are mutually exclusive');
98
+ process.exit(1);
99
+ }
100
+ if (opts.versionBump &&
101
+ !['patch', 'minor', 'major'].includes(opts.versionBump)) {
102
+ console.error('\n✗ --version-bump must be patch, minor, or major');
91
103
  process.exit(1);
92
104
  }
93
105
  }
@@ -113,8 +125,8 @@ async function handleGenerate(opts) {
113
125
  function handleRun(appPath) {
114
126
  const resolved = resolve(appPath);
115
127
  const result = spawnSync(process.execPath, [resolved], {
116
- env: { ...process.env, TESSERACT_GENERATE: "1" },
117
- stdio: "inherit",
128
+ env: { ...process.env, TESSERACT_GENERATE: '1' },
129
+ stdio: 'inherit',
118
130
  });
119
131
  process.exit(result.status ?? 0);
120
132
  }
@@ -125,32 +137,33 @@ function createCLI() {
125
137
  const program = new Command();
126
138
  const version = loadPackageVersion();
127
139
  program
128
- .name("tesseract")
129
- .description("Manifest-first SDK generator — turns sdk-manifold/v1 manifests into production-ready TypeScript SDKs")
140
+ .name('tesseract')
141
+ .description('Manifest-first SDK generator — turns sdk-manifold/v1 manifests into production-ready TypeScript SDKs')
130
142
  .version(version);
131
143
  program
132
- .command("generate")
133
- .description("Generate an SDK from an sdk-manifold/v1 manifest file")
134
- .requiredOption("-i, --input <path>", "Path to the sdk-manifold/v1 manifest JSON file")
135
- .requiredOption("-o, --output <dir>", "Output directory for the generated SDK")
136
- .option("-l, --language <lang>", "Target language: typescript, python, ruby, php, go, rust, kotlin, csharp")
137
- .option("-n, --name <name>", "Override the SDK package name")
138
- .option("--package-version <version>", "Override the generated package version")
139
- .option("--client-name <name>", "Override the client class name")
140
- .option("--base-url <url>", "Override the base URL")
141
- .option("--dry-run", "Preview output without writing files")
142
- .option("--check", "Exit non-zero if generated output is out of date")
143
- .option("--sdk-style <style>", 'SDK style: functional (default) or class (Resend-style: new MySDK("key"))')
144
- .option("--client-type <type>", "Client type: internal (full options, default) or public (auth key only, baseUrl baked in)")
145
- .option("--npm-token <token>", "NPM auth token for resolving private package versions (defaults to NPM_TOKEN env var)")
144
+ .command('generate')
145
+ .description('Generate an SDK from an sdk-manifold/v1 manifest file')
146
+ .requiredOption('-i, --input <path>', 'Path to the sdk-manifold/v1 manifest JSON file')
147
+ .requiredOption('-o, --output <dir>', 'Output directory for the generated SDK')
148
+ .option('-l, --language <lang>', 'Target language: typescript, python, ruby, php, go, rust, kotlin, csharp')
149
+ .option('-n, --name <name>', 'Override the SDK package name')
150
+ .option('--package-version <version>', 'Override the generated package version')
151
+ .option('--version-bump <type>', 'Version bump when package version is resolved: patch, minor, or major')
152
+ .option('--client-name <name>', 'Override the client class name')
153
+ .option('--base-url <url>', 'Override the base URL')
154
+ .option('--dry-run', 'Preview output without writing files')
155
+ .option('--check', 'Exit non-zero if generated output is out of date')
156
+ .option('--sdk-style <style>', 'SDK style: functional (default) or class (Resend-style: new MySDK("key"))')
157
+ .option('--client-type <type>', 'Client type: internal (full options, default) or public (auth key only, baseUrl baked in)')
158
+ .option('--npm-token <token>', 'NPM auth token for resolving private package versions (defaults to NPM_TOKEN env var)')
146
159
  .action(handleGenerate);
147
160
  program
148
- .command("run")
161
+ .command('run')
149
162
  .description([
150
- "Boot an instrumented Fastify app with TESSERACT_GENERATE=1 to collect routes and generate an SDK.",
151
- "The app must register `tesseractPlugin` from `@apollo-deploy/tesseract/fastify`.",
152
- ].join("\n"))
153
- .argument("<app>", "Path to the compiled app entry-point (e.g. dist/app.js)")
163
+ 'Boot an instrumented Fastify app with TESSERACT_GENERATE=1 to collect routes and generate an SDK.',
164
+ 'The app must register `tesseractPlugin` from `@apollo-deploy/tesseract/fastify`.',
165
+ ].join('\n'))
166
+ .argument('<app>', 'Path to the compiled app entry-point (e.g. dist/app.js)')
154
167
  .action(handleRun);
155
168
  return program;
156
169
  }
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -28,7 +28,19 @@
28
28
  */
29
29
  import type { BackendManifest, ManifestRouteSchema } from './types/manifest.js';
30
30
  import type { SDKModuleConfig, SDKRouteConfig } from './types/sdk-module.js';
31
- import type { TargetLanguage } from './types/ir.js';
31
+ import type { TargetLanguage, VersionBump } from './types/ir.js';
32
+ export type SchemaConversionMode = 'input' | 'output';
33
+ export interface SchemaOverrideContext {
34
+ zodSchema: unknown;
35
+ jsonSchema: Record<string, unknown>;
36
+ path: Array<string | number>;
37
+ }
38
+ export interface SchemaConversionOptions {
39
+ io?: SchemaConversionMode;
40
+ unrepresentable?: 'throw' | 'any';
41
+ override?: (context: SchemaOverrideContext) => void;
42
+ }
43
+ export type SchemaConverter = (schema: unknown, options?: SchemaConversionOptions) => unknown;
32
44
  /**
33
45
  * Minimal interface for Zod v4's global registry — only what Tesseract needs.
34
46
  * Declared here so adapters don't need a hard dependency on `zod`.
@@ -74,7 +86,7 @@ export interface CollectorOptions {
74
86
  * new SDKCollector({ ..., schemaConverter: toJSONSchema });
75
87
  * ```
76
88
  */
77
- schemaConverter?: (schema: unknown) => unknown;
89
+ schemaConverter?: SchemaConverter;
78
90
  /**
79
91
  * Zod v4 global registry — controls how registered schemas are resolved
80
92
  * when `schemaConverter` is set.
@@ -96,6 +108,8 @@ export interface CollectorOptions {
96
108
  packageName?: string;
97
109
  /** Override the generated package version. */
98
110
  packageVersion?: string;
111
+ /** Version increment used when packageVersion is omitted. */
112
+ versionBump?: VersionBump;
99
113
  /**
100
114
  * Target SDK language for the primary output. Defaults to `'typescript'`.
101
115
  * Use `additionalTargets` to emit multiple languages simultaneously.
@@ -124,6 +138,7 @@ export interface CollectorOptions {
124
138
  output: string;
125
139
  packageName?: string;
126
140
  packageVersion?: string;
141
+ versionBump?: VersionBump;
127
142
  clientType?: 'internal' | 'public';
128
143
  sdkStyle?: 'functional' | 'class';
129
144
  /**
@@ -134,12 +149,17 @@ export interface CollectorOptions {
134
149
  * from a shared TypeScript package but an additional target (e.g. Kotlin)
135
150
  * needs self-contained inline types.
136
151
  *
137
- * Omit to inherit the primary `schemaPackage`.
152
+ * Non-TypeScript targets default to expanding types inline (as if
153
+ * `schemaPackage: null`) when this field is omitted, since they cannot
154
+ * import a TypeScript schema package.
155
+ *
156
+ * Omit on a TypeScript additional target to inherit the primary `schemaPackage`.
138
157
  *
139
158
  * @example
140
159
  * ```ts
141
160
  * additionalTargets: [
142
- * { language: 'kotlin', output: './sdk/java', schemaPackage: null },
161
+ * { language: 'kotlin', output: './sdk/java' }, // auto-expands types
162
+ * { language: 'kotlin', output: './sdk/java', schemaPackage: null }, // explicit
143
163
  * ]
144
164
  * ```
145
165
  */
@@ -190,6 +210,8 @@ export declare class SDKCollector {
190
210
  * @param config - Schema and SDK options for this route.
191
211
  */
192
212
  route(url: string, method: string, config: CollectorRouteConfig): this;
213
+ /** Number of routes currently registered. */
214
+ get routeCount(): number;
193
215
  /** Build and return the `BackendManifest` from all accumulated routes and domains. */
194
216
  buildManifest(): BackendManifest;
195
217
  /** Generate the SDK from accumulated routes and domains. */
@@ -222,17 +244,20 @@ export declare function liftRegisteredRefs(schema: unknown, registeredIds: Set<s
222
244
  * - No registry — calls `toJSONSchema` directly; nested `$defs` are extracted by
223
245
  * `buildManifestFromRoutes`.
224
246
  */
225
- export declare function convertSchemaValue(value: unknown, toJSONSchema: (s: unknown) => unknown, zodRegistry?: ZodGlobalRegistry, isExternalTarget?: boolean): unknown;
247
+ export declare function convertSchemaValue(value: unknown, toJSONSchema: SchemaConverter, zodRegistry?: ZodGlobalRegistry, isExternalTarget?: boolean, mode?: SchemaConversionMode): unknown;
226
248
  /**
227
249
  * Convert all schema fields on a single route schema, applying the correct
228
250
  * Zod→JSON Schema conversion strategy for the target.
229
251
  */
230
- export declare function convertRouteSchema(schema: ManifestRouteSchema | undefined, toJSONSchema: (s: unknown) => unknown, zodRegistry?: ZodGlobalRegistry, isExternalTarget?: boolean): ManifestRouteSchema | undefined;
252
+ export declare function convertRouteSchema(schema: ManifestRouteSchema | undefined, toJSONSchema: SchemaConverter, zodRegistry?: ZodGlobalRegistry, isExternalTarget?: boolean, route?: {
253
+ method?: string;
254
+ url?: string;
255
+ }): ManifestRouteSchema | undefined;
231
256
  /**
232
257
  * Resolve the `toJSONSchema` converter: use the explicit one if provided,
233
258
  * otherwise attempt auto-detection from the host app's `zod` package.
234
259
  */
235
- export declare function resolveSchemaConverter(explicit?: (s: unknown) => unknown): Promise<((s: unknown) => unknown) | undefined>;
260
+ export declare function resolveSchemaConverter(explicit?: SchemaConverter): Promise<SchemaConverter | undefined>;
236
261
  /**
237
262
  * Builds a `BackendManifest` from a flat list of collected routes and a domain
238
263
  * registry. Exported so framework adapters (including the Fastify plugin) can
@@ -1 +1 @@
1
- {"version":3,"file":"collector.d.ts","sourceRoot":"","sources":["../src/collector.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"collector.d.ts","sourceRoot":"","sources":["../src/collector.ts"],"names":[],"mappings":"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"}
package/dist/collector.js CHANGED
@@ -47,7 +47,11 @@ export class SDKCollector {
47
47
  * @param config - Optional domain metadata — name override, description, stability.
48
48
  */
49
49
  domain(prefix, config) {
50
- this._registry.set(prefix, { prefix, ...config });
50
+ const normalizedPrefix = normalizePath(prefix);
51
+ this._registry.set(normalizedPrefix, {
52
+ prefix: normalizedPrefix,
53
+ ...config,
54
+ });
51
55
  return this;
52
56
  }
53
57
  /**
@@ -63,7 +67,7 @@ export class SDKCollector {
63
67
  if (config.sdk?.exclude)
64
68
  return this;
65
69
  this._routes.push({
66
- url,
70
+ url: normalizePath(url),
67
71
  method: method.toUpperCase(),
68
72
  schema: config.schema,
69
73
  sdk: config.sdk,
@@ -71,6 +75,10 @@ export class SDKCollector {
71
75
  });
72
76
  return this;
73
77
  }
78
+ /** Number of routes currently registered. */
79
+ get routeCount() {
80
+ return this._routes.length;
81
+ }
74
82
  /** Build and return the `BackendManifest` from all accumulated routes and domains. */
75
83
  buildManifest() {
76
84
  return buildManifestFromRoutes(this._routes, this._registry, this.opts.info, this.opts.schemaPackage);
@@ -89,10 +97,13 @@ export class SDKCollector {
89
97
  return buildManifestFromRoutes(this._routes, this._registry, this.opts.info, schemaPackage);
90
98
  }
91
99
  const isExternal = !!schemaPackage;
92
- const registry = schemaPackage ? this.opts.zodGlobalRegistry : undefined;
100
+ // Always pass the registry when available so non-external targets can
101
+ // expand registered schemas into `$defs` (named local models). External
102
+ // targets use the same registry to emit bare `$ref` import stubs.
103
+ const registry = this.opts.zodGlobalRegistry;
93
104
  const converted = this._routes.map((r) => ({
94
105
  ...r,
95
- schema: convertRouteSchema(r.schema, toJSONSchema, registry, isExternal),
106
+ schema: convertRouteSchema(r.schema, toJSONSchema, registry, isExternal, { method: r.method, url: r.url }),
96
107
  }));
97
108
  return buildManifestFromRoutes(converted, this._registry, this.opts.info, schemaPackage);
98
109
  };
@@ -104,14 +115,21 @@ export class SDKCollector {
104
115
  clientType: this.opts.clientType,
105
116
  packageName: this.opts.packageName,
106
117
  packageVersion: this.opts.packageVersion,
118
+ versionBump: this.opts.versionBump,
107
119
  sdkStyle: this.opts.sdkStyle,
108
120
  });
109
121
  for (const target of this.opts.additionalTargets ?? []) {
110
122
  const hasSchemaPackageOverride = Object.prototype.hasOwnProperty.call(target, 'schemaPackage');
123
+ // Non-TypeScript targets cannot import a TS schema package — expand
124
+ // registered types into local definitions unless explicitly overridden.
125
+ const inheritsSchemaPackage = !hasSchemaPackageOverride && target.language !== 'typescript';
111
126
  const targetSchemaPackage = hasSchemaPackageOverride
112
127
  ? (target.schemaPackage ?? undefined)
113
- : this.opts.schemaPackage;
114
- const targetManifest = hasSchemaPackageOverride || targetSchemaPackage !== this.opts.schemaPackage
128
+ : inheritsSchemaPackage
129
+ ? undefined
130
+ : this.opts.schemaPackage;
131
+ const targetManifest = hasSchemaPackageOverride ||
132
+ targetSchemaPackage !== this.opts.schemaPackage
115
133
  ? buildManifestFor(targetSchemaPackage)
116
134
  : primaryManifest;
117
135
  const extra = await generate({
@@ -121,10 +139,13 @@ export class SDKCollector {
121
139
  clientType: target.clientType ?? this.opts.clientType,
122
140
  packageName: target.packageName ?? this.opts.packageName,
123
141
  packageVersion: target.packageVersion ?? this.opts.packageVersion,
142
+ versionBump: target.versionBump ?? this.opts.versionBump,
124
143
  sdkStyle: target.sdkStyle ?? this.opts.sdkStyle,
125
144
  });
126
145
  primary.filesWritten += extra.filesWritten;
127
146
  primary.filesSkipped += extra.filesSkipped;
147
+ primary.filesDeleted += extra.filesDeleted;
148
+ primary.hasChanges ||= extra.hasChanges;
128
149
  primary.warnings.push(...extra.warnings);
129
150
  primary.changedFiles.push(...extra.changedFiles);
130
151
  }
@@ -149,7 +170,10 @@ export class SDKCollector {
149
170
  for (const w of result.warnings)
150
171
  console.warn(` ⚠ ${w}`);
151
172
  }
152
- const targets = [this.opts.output, ...(this.opts.additionalTargets ?? []).map((t) => t.output)];
173
+ const targets = [
174
+ this.opts.output,
175
+ ...(this.opts.additionalTargets ?? []).map((t) => t.output),
176
+ ];
153
177
  console.log(`[tesseract] ✓ ${result.filesWritten} files written → ${targets.join(', ')}`);
154
178
  return true;
155
179
  }
@@ -159,6 +183,61 @@ export class SDKCollector {
159
183
  function isZodSchema(value) {
160
184
  return !!value && typeof value === 'object' && '_zod' in value;
161
185
  }
186
+ function getSchemaId(schema, registry) {
187
+ const registeredId = registry?.get(schema)?.id;
188
+ if (registeredId)
189
+ return registeredId;
190
+ if (!schema || typeof schema !== 'object')
191
+ return undefined;
192
+ const meta = schema.meta;
193
+ if (typeof meta !== 'function')
194
+ return undefined;
195
+ const id = meta.call(schema)?.id;
196
+ return typeof id === 'string' && id.length > 0 ? id : undefined;
197
+ }
198
+ const NON_JSON_ZOD_TYPES = new Set([
199
+ 'bigint',
200
+ 'symbol',
201
+ 'undefined',
202
+ 'void',
203
+ 'nan',
204
+ 'custom',
205
+ 'function',
206
+ 'map',
207
+ 'set',
208
+ ]);
209
+ function getZodType(schema) {
210
+ if (!schema || typeof schema !== 'object')
211
+ return undefined;
212
+ const def = schema._zod?.def;
213
+ return typeof def?.type === 'string' ? def.type : undefined;
214
+ }
215
+ /**
216
+ * Convert a Zod schema while preserving JSON transport semantics.
217
+ *
218
+ * JavaScript `Date` values are serialized over HTTP as ISO-8601 strings, so
219
+ * they are represented as JSON Schema `string` / `date-time`. Other values
220
+ * that JSON cannot carry (BigInt, Function, Map, Set, etc.) still fail.
221
+ */
222
+ function convertZodSchema(schema, converter, mode) {
223
+ return converter(schema, {
224
+ io: mode,
225
+ unrepresentable: 'any',
226
+ override: ({ zodSchema, jsonSchema }) => {
227
+ const type = getZodType(zodSchema);
228
+ if (type === 'date') {
229
+ for (const key of Object.keys(jsonSchema))
230
+ delete jsonSchema[key];
231
+ jsonSchema.type = 'string';
232
+ jsonSchema.format = 'date-time';
233
+ return;
234
+ }
235
+ if (type && NON_JSON_ZOD_TYPES.has(type)) {
236
+ throw new Error(`${type[0].toUpperCase()}${type.slice(1)} cannot be represented in JSON Schema`);
237
+ }
238
+ },
239
+ });
240
+ }
162
241
  /**
163
242
  * Post-process a JSON Schema produced by `toJSONSchema` so that any `$defs`
164
243
  * entry whose key matches a registered global id is lifted to a bare `$ref`.
@@ -203,62 +282,70 @@ export function liftRegisteredRefs(schema, registeredIds) {
203
282
  * - No registry — calls `toJSONSchema` directly; nested `$defs` are extracted by
204
283
  * `buildManifestFromRoutes`.
205
284
  */
206
- export function convertSchemaValue(value, toJSONSchema, zodRegistry, isExternalTarget) {
285
+ export function convertSchemaValue(value, toJSONSchema, zodRegistry, isExternalTarget, mode = 'output') {
207
286
  if (isZodSchema(value)) {
208
- if (zodRegistry) {
209
- const entry = zodRegistry.get(value);
210
- if (entry?.id) {
211
- if (isExternalTarget) {
212
- return { $ref: entry.id };
213
- }
214
- try {
215
- const expanded = toJSONSchema(value);
216
- return { $defs: { [entry.id]: expanded }, $ref: `#/$defs/${entry.id}` };
217
- }
218
- catch {
219
- return { $ref: entry.id };
220
- }
221
- }
222
- }
223
- try {
224
- const jsonSchema = toJSONSchema(value);
225
- if (zodRegistry?._idmap && jsonSchema && typeof jsonSchema === 'object') {
226
- const registeredIds = new Set(zodRegistry._idmap.keys());
227
- return liftRegisteredRefs(jsonSchema, registeredIds);
228
- }
229
- return jsonSchema;
287
+ const schemaId = getSchemaId(value, zodRegistry);
288
+ if (schemaId) {
289
+ if (isExternalTarget)
290
+ return { $ref: schemaId };
291
+ const expanded = convertZodSchema(value, toJSONSchema, mode);
292
+ return { $defs: { [schemaId]: expanded }, $ref: `#/$defs/${schemaId}` };
230
293
  }
231
- catch {
232
- return value;
294
+ const jsonSchema = convertZodSchema(value, toJSONSchema, mode);
295
+ // Only lift registered `$defs` → bare `$ref` for external (schemaPackage)
296
+ // targets. Inline targets must keep `$defs` so they become local models.
297
+ if (isExternalTarget &&
298
+ zodRegistry?._idmap &&
299
+ jsonSchema &&
300
+ typeof jsonSchema === 'object') {
301
+ const registeredIds = new Set(zodRegistry._idmap.keys());
302
+ return liftRegisteredRefs(jsonSchema, registeredIds);
233
303
  }
304
+ return jsonSchema;
234
305
  }
235
306
  return value;
236
307
  }
237
308
  // Schema fields eligible for registry-based $ref replacement.
238
309
  // headers are always expanded inline since they're rarely top-level registered schemas.
239
- const REGISTRY_ELIGIBLE_FIELDS = new Set(['body', 'querystring', 'query', 'params']);
310
+ const REGISTRY_ELIGIBLE_FIELDS = new Set([
311
+ 'body',
312
+ 'querystring',
313
+ 'query',
314
+ 'params',
315
+ ]);
240
316
  /**
241
317
  * Convert all schema fields on a single route schema, applying the correct
242
318
  * Zod→JSON Schema conversion strategy for the target.
243
319
  */
244
- export function convertRouteSchema(schema, toJSONSchema, zodRegistry, isExternalTarget) {
320
+ export function convertRouteSchema(schema, toJSONSchema, zodRegistry, isExternalTarget, route) {
245
321
  if (!schema)
246
322
  return schema;
247
323
  const result = {};
324
+ const routeLabel = [route?.method, route?.url].filter(Boolean).join(' ');
325
+ const convert = (value, field, mode, useRegistry = false) => {
326
+ try {
327
+ return convertSchemaValue(value, toJSONSchema, useRegistry ? zodRegistry : undefined, useRegistry ? isExternalTarget : false, mode);
328
+ }
329
+ catch (error) {
330
+ const location = routeLabel ? ` for ${routeLabel}` : '';
331
+ const message = error instanceof Error ? error.message : String(error);
332
+ const hint = mode === 'output'
333
+ ? ' Response transforms must end in a JSON-schema-representable output schema.'
334
+ : '';
335
+ throw new Error(`Failed to convert ${field} schema${location}: ${message}.${hint}`, { cause: error });
336
+ }
337
+ };
248
338
  for (const [key, val] of Object.entries(schema)) {
249
339
  if (key === 'response' && val && typeof val === 'object') {
250
340
  const serialized = {};
251
341
  for (const [status, responseSchema] of Object.entries(val)) {
252
- serialized[status] = convertSchemaValue(responseSchema, toJSONSchema, zodRegistry, isExternalTarget);
342
+ serialized[status] = convert(responseSchema, `response ${status}`, 'output', true);
253
343
  }
254
344
  result[key] = serialized;
345
+ continue;
255
346
  }
256
- else if (REGISTRY_ELIGIBLE_FIELDS.has(key)) {
257
- result[key] = convertSchemaValue(val, toJSONSchema, zodRegistry, isExternalTarget);
258
- }
259
- else {
260
- result[key] = convertSchemaValue(val, toJSONSchema);
261
- }
347
+ const isRequestSchema = REGISTRY_ELIGIBLE_FIELDS.has(key) || key === 'headers';
348
+ result[key] = convert(val, key, isRequestSchema ? 'input' : 'output', REGISTRY_ELIGIBLE_FIELDS.has(key));
262
349
  }
263
350
  return result;
264
351
  }
@@ -271,7 +358,7 @@ export async function resolveSchemaConverter(explicit) {
271
358
  return explicit;
272
359
  try {
273
360
  const zodPkg = 'zod';
274
- const zodModule = await import(zodPkg);
361
+ const zodModule = (await import(zodPkg));
275
362
  const converter = zodModule.toJSONSchema;
276
363
  return typeof converter === 'function' ? converter : undefined;
277
364
  }
@@ -290,15 +377,15 @@ export function buildManifestFromRoutes(routes, registry, info, schemaPackage) {
290
377
  const sortedPrefixes = [...registry.keys()].sort((a, b) => b.length - a.length);
291
378
  const domainMap = new Map();
292
379
  for (const route of routes) {
293
- const matchedPrefix = sortedPrefixes.find((p) => route.url === p || route.url.startsWith(p + '/')) ??
294
- derivePrefix(route.url);
380
+ const url = normalizePath(route.url);
381
+ const matchedPrefix = sortedPrefixes.find((prefix) => prefix === '/' || url === prefix || url.startsWith(`${prefix}/`)) ?? derivePrefix(url);
295
382
  if (!domainMap.has(matchedPrefix)) {
296
383
  domainMap.set(matchedPrefix, {
297
384
  config: registry.get(matchedPrefix) ?? { prefix: matchedPrefix },
298
385
  routes: [],
299
386
  });
300
387
  }
301
- const tail = route.url.substring(matchedPrefix.length) || '/';
388
+ const tail = url.substring(matchedPrefix === '/' ? 0 : matchedPrefix.length) || '/';
302
389
  domainMap.get(matchedPrefix).routes.push({
303
390
  method: route.method,
304
391
  url: tail.startsWith('/') ? tail : '/' + tail,
@@ -316,14 +403,25 @@ export function buildManifestFromRoutes(routes, registry, info, schemaPackage) {
316
403
  baseUrl: info.baseUrl,
317
404
  },
318
405
  ...(schemaPackage && { schemaPackage }),
319
- domains: [...domainMap.values()].map(({ config, routes }) => ({ ...config, routes })),
406
+ domains: [...domainMap.values()].map(({ config, routes }) => ({
407
+ ...config,
408
+ routes,
409
+ })),
320
410
  ...buildDefinitionsFromDefs(routes),
321
411
  };
322
412
  }
323
413
  /** Derives a domain prefix from the first non-parameter URL segment. */
324
414
  function derivePrefix(url) {
325
- const first = url.split('/').find((s) => s.length > 0 && !s.startsWith(':'));
326
- return first ? '/' + first : '/';
415
+ const first = url
416
+ .split('/')
417
+ .find((segment) => segment && !segment.startsWith(':'));
418
+ return first ? `/${first}` : '/';
419
+ }
420
+ function normalizePath(value) {
421
+ const path = value.trim();
422
+ if (!path || path === '/')
423
+ return '/';
424
+ return `/${path.replace(/^\/+|\/+$/g, '')}`;
327
425
  }
328
426
  // ── $defs extraction ──────────────────────────────────────────────────────────
329
427
  /**
@@ -365,7 +463,9 @@ function buildDefinitionsFromDefs(routes) {
365
463
  function collectDefs(schema, out) {
366
464
  if (!schema || typeof schema !== 'object')
367
465
  return;
368
- if (schema.$defs && typeof schema.$defs === 'object' && !Array.isArray(schema.$defs)) {
466
+ if (schema.$defs &&
467
+ typeof schema.$defs === 'object' &&
468
+ !Array.isArray(schema.$defs)) {
369
469
  for (const [key, val] of Object.entries(schema.$defs)) {
370
470
  if (!(key in out))
371
471
  out[key] = val;