@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.
- package/README.md +218 -110
- package/dist/adapters/csharp/index.d.ts +5 -8
- package/dist/adapters/csharp/index.d.ts.map +1 -1
- package/dist/adapters/csharp/index.js +314 -74
- package/dist/adapters/csharp/index.js.map +1 -1
- package/dist/adapters/documentation.d.ts +17 -0
- package/dist/adapters/documentation.d.ts.map +1 -0
- package/dist/adapters/documentation.js +268 -0
- package/dist/adapters/documentation.js.map +1 -0
- package/dist/adapters/go/index.d.ts +5 -8
- package/dist/adapters/go/index.d.ts.map +1 -1
- package/dist/adapters/go/index.js +197 -101
- package/dist/adapters/go/index.js.map +1 -1
- package/dist/adapters/kotlin/index.d.ts +5 -9
- package/dist/adapters/kotlin/index.d.ts.map +1 -1
- package/dist/adapters/kotlin/index.js +280 -212
- package/dist/adapters/kotlin/index.js.map +1 -1
- package/dist/adapters/php/index.d.ts +5 -15
- package/dist/adapters/php/index.d.ts.map +1 -1
- package/dist/adapters/php/index.js +362 -90
- package/dist/adapters/php/index.js.map +1 -1
- package/dist/adapters/python/index.d.ts +5 -8
- package/dist/adapters/python/index.d.ts.map +1 -1
- package/dist/adapters/python/index.js +240 -109
- package/dist/adapters/python/index.js.map +1 -1
- package/dist/adapters/ruby/index.d.ts +3 -3
- package/dist/adapters/ruby/index.d.ts.map +1 -1
- package/dist/adapters/ruby/index.js +235 -46
- package/dist/adapters/ruby/index.js.map +1 -1
- package/dist/adapters/rust/index.d.ts +5 -9
- package/dist/adapters/rust/index.d.ts.map +1 -1
- package/dist/adapters/rust/index.js +237 -169
- package/dist/adapters/rust/index.js.map +1 -1
- package/dist/adapters/shared.d.ts +7 -0
- package/dist/adapters/shared.d.ts.map +1 -0
- package/dist/adapters/shared.js +68 -0
- package/dist/adapters/shared.js.map +1 -0
- package/dist/adapters/type-utils.d.ts +13 -0
- package/dist/adapters/type-utils.d.ts.map +1 -0
- package/dist/adapters/type-utils.js +105 -0
- package/dist/adapters/type-utils.js.map +1 -0
- package/dist/adapters/types.d.ts.map +1 -1
- package/dist/adapters/typescript/emitter/emitSchema.d.ts +2 -2
- package/dist/adapters/typescript/emitter/emitSchema.js +39 -27
- package/dist/adapters/typescript/emitter/emitSchema.js.map +1 -1
- package/dist/adapters/typescript/emitter/emitTypeScriptModels.d.ts +2 -2
- package/dist/adapters/typescript/emitter/emitTypeScriptModels.js +15 -15
- package/dist/adapters/typescript/emitter/importCollector.d.ts +2 -4
- package/dist/adapters/typescript/emitter/importCollector.d.ts.map +1 -1
- package/dist/adapters/typescript/emitter/importCollector.js +40 -50
- package/dist/adapters/typescript/emitter/importCollector.js.map +1 -1
- package/dist/adapters/typescript/emitter/parsers.d.ts +1 -1
- package/dist/adapters/typescript/emitter/parsers.js +13 -13
- package/dist/adapters/typescript/emitter/typeHoister.d.ts +1 -1
- package/dist/adapters/typescript/emitter/typeHoister.d.ts.map +1 -1
- package/dist/adapters/typescript/emitter/typeHoister.js +12 -20
- package/dist/adapters/typescript/emitter/typeHoister.js.map +1 -1
- package/dist/adapters/typescript/index.d.ts +3 -3
- package/dist/adapters/typescript/index.d.ts.map +1 -1
- package/dist/adapters/typescript/index.js +148 -166
- package/dist/adapters/typescript/index.js.map +1 -1
- package/dist/adapters/typescript/shared.d.ts +2 -2
- package/dist/adapters/typescript/shared.js +12 -12
- package/dist/cli.js +50 -37
- package/dist/cli.js.map +1 -1
- package/dist/collector.d.ts +32 -7
- package/dist/collector.d.ts.map +1 -1
- package/dist/collector.js +149 -49
- package/dist/collector.js.map +1 -1
- package/dist/elysia.js +2 -2
- package/dist/elysia.js.map +1 -1
- package/dist/express.d.ts.map +1 -1
- package/dist/express.js.map +1 -1
- package/dist/fastify.d.ts +9 -2
- package/dist/fastify.d.ts.map +1 -1
- package/dist/fastify.js +40 -21
- package/dist/fastify.js.map +1 -1
- package/dist/helpers/handlebars.d.ts +7 -16
- package/dist/helpers/handlebars.d.ts.map +1 -1
- package/dist/helpers/handlebars.js +127 -177
- package/dist/helpers/handlebars.js.map +1 -1
- package/dist/hono.d.ts.map +1 -1
- package/dist/hono.js.map +1 -1
- package/dist/index.d.ts +14 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +32 -30
- package/dist/index.js.map +1 -1
- package/dist/koa.d.ts.map +1 -1
- package/dist/koa.js.map +1 -1
- package/dist/nestjs.d.ts.map +1 -1
- package/dist/nestjs.js +41 -14
- package/dist/nestjs.js.map +1 -1
- package/dist/pipeline/enrich.d.ts +2 -13
- package/dist/pipeline/enrich.d.ts.map +1 -1
- package/dist/pipeline/enrich.js +157 -212
- package/dist/pipeline/enrich.js.map +1 -1
- package/dist/pipeline/intake.d.ts +3 -3
- package/dist/pipeline/intake.d.ts.map +1 -1
- package/dist/pipeline/intake.js +342 -238
- package/dist/pipeline/intake.js.map +1 -1
- package/dist/pipeline/write.d.ts +1 -14
- package/dist/pipeline/write.d.ts.map +1 -1
- package/dist/pipeline/write.js +73 -113
- package/dist/pipeline/write.js.map +1 -1
- package/dist/types/config.d.ts +14 -26
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/config.js +16 -12
- package/dist/types/config.js.map +1 -1
- package/dist/types/ir.d.ts +12 -8
- package/dist/types/ir.d.ts.map +1 -1
- package/dist/types/manifest.d.ts +10 -11
- package/dist/types/manifest.d.ts.map +1 -1
- package/dist/types/manifest.js +54 -14
- package/dist/types/manifest.js.map +1 -1
- package/dist/types/sdk-module.d.ts +2 -2
- package/dist/types/sdk-module.js +1 -1
- package/dist/utils/format.d.ts +1 -3
- package/dist/utils/format.d.ts.map +1 -1
- package/dist/utils/format.js +3 -10
- package/dist/utils/format.js.map +1 -1
- package/dist/utils/naming.d.ts.map +1 -1
- package/dist/utils/naming.js +174 -184
- package/dist/utils/naming.js.map +1 -1
- package/dist/utils/npm-token.d.ts +1 -17
- package/dist/utils/npm-token.d.ts.map +1 -1
- package/dist/utils/npm-token.js +27 -76
- package/dist/utils/npm-token.js.map +1 -1
- package/dist/utils/version.d.ts +14 -0
- package/dist/utils/version.d.ts.map +1 -0
- package/dist/utils/version.js +60 -0
- package/dist/utils/version.js.map +1 -0
- package/package.json +4 -3
- package/templates/csharp/client.hbs +26 -49
- package/templates/csharp/csproj.hbs +7 -0
- package/templates/csharp/domain.hbs +48 -130
- package/templates/csharp/errors.hbs +17 -25
- package/templates/csharp/readme.hbs +31 -44
- package/templates/csharp/transport.hbs +238 -136
- package/templates/csharp/types.hbs +30 -76
- package/templates/go/client.hbs +44 -109
- package/templates/go/domain.hbs +83 -25
- package/templates/go/go-mod.hbs +1 -4
- package/templates/go/readme.hbs +32 -29
- package/templates/go/transport.hbs +174 -173
- package/templates/go/types.hbs +17 -53
- package/templates/go/utils.hbs +3 -2
- package/templates/kotlin/build-gradle.hbs +1 -1
- package/templates/kotlin/client.hbs +18 -15
- package/templates/kotlin/domain.hbs +54 -51
- package/templates/kotlin/errors.hbs +1 -1
- package/templates/kotlin/readme.hbs +35 -137
- package/templates/kotlin/transport.hbs +140 -123
- package/templates/kotlin/types.hbs +30 -81
- package/templates/php/client.hbs +8 -46
- package/templates/php/composer.hbs +2 -1
- package/templates/php/domain.hbs +86 -117
- package/templates/php/errors.hbs +1 -1
- package/templates/php/readme.hbs +42 -49
- package/templates/php/transport.hbs +192 -145
- package/templates/php/types.hbs +63 -60
- package/templates/python/client.hbs +15 -2
- package/templates/python/domain.hbs +50 -108
- package/templates/python/pyproject.hbs +5 -0
- package/templates/python/readme.hbs +47 -30
- package/templates/python/resources-init.hbs +1 -1
- package/templates/python/transport.hbs +167 -53
- package/templates/python/types.hbs +22 -58
- package/templates/ruby/client.hbs +10 -6
- package/templates/ruby/domain.hbs +48 -67
- package/templates/ruby/errors.hbs +3 -3
- package/templates/ruby/gemspec.hbs +3 -10
- package/templates/ruby/index.hbs +3 -3
- package/templates/ruby/readme.hbs +33 -70
- package/templates/ruby/transport.hbs +129 -103
- package/templates/ruby/types.hbs +11 -16
- package/templates/ruby/version.hbs +1 -1
- package/templates/rust/cargo.hbs +2 -0
- package/templates/rust/client.hbs +10 -1
- package/templates/rust/domain.hbs +69 -52
- package/templates/rust/error.hbs +3 -1
- package/templates/rust/lib.hbs +4 -5
- package/templates/rust/readme.hbs +33 -46
- package/templates/rust/transport.hbs +170 -159
- package/templates/rust/types.hbs +34 -111
- package/templates/typescript/domain-class.hbs +14 -6
- package/templates/typescript/domain.hbs +13 -5
- package/templates/typescript/package-json.hbs +3 -1
- package/templates/typescript/readme.hbs +42 -42
- package/templates/typescript/transport.hbs +46 -8
- package/templates/typescript/types-errors.hbs +1 -1
- package/dist/adapters/typescript/model-emitter.d.ts +0 -13
- package/dist/adapters/typescript/model-emitter.d.ts.map +0 -1
- package/dist/adapters/typescript/model-emitter.js +0 -415
- 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
|
|
6
|
-
import { readFileSync } from
|
|
7
|
-
import { resolve, join, dirname } from
|
|
8
|
-
import { fileURLToPath } from
|
|
9
|
-
import { spawnSync } from
|
|
10
|
-
import { generate } from
|
|
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,
|
|
17
|
-
const pkg = JSON.parse(readFileSync(pkgPath,
|
|
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 ??
|
|
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(
|
|
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
|
|
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
|
|
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(
|
|
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:
|
|
117
|
-
stdio:
|
|
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(
|
|
129
|
-
.description(
|
|
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(
|
|
133
|
-
.description(
|
|
134
|
-
.requiredOption(
|
|
135
|
-
.requiredOption(
|
|
136
|
-
.option(
|
|
137
|
-
.option(
|
|
138
|
-
.option(
|
|
139
|
-
.option(
|
|
140
|
-
.option(
|
|
141
|
-
.option(
|
|
142
|
-
.option(
|
|
143
|
-
.option(
|
|
144
|
-
.option(
|
|
145
|
-
.option(
|
|
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(
|
|
161
|
+
.command('run')
|
|
149
162
|
.description([
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
].join(
|
|
153
|
-
.argument(
|
|
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":";AACA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE/C,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/collector.d.ts
CHANGED
|
@@ -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?:
|
|
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
|
-
*
|
|
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',
|
|
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:
|
|
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:
|
|
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?:
|
|
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
|
package/dist/collector.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collector.d.ts","sourceRoot":"","sources":["../src/collector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,KAAK,
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
:
|
|
114
|
-
|
|
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 = [
|
|
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
|
-
|
|
209
|
-
|
|
210
|
-
if (
|
|
211
|
-
|
|
212
|
-
|
|
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
|
-
|
|
232
|
-
|
|
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([
|
|
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] =
|
|
342
|
+
serialized[status] = convert(responseSchema, `response ${status}`, 'output', true);
|
|
253
343
|
}
|
|
254
344
|
result[key] = serialized;
|
|
345
|
+
continue;
|
|
255
346
|
}
|
|
256
|
-
|
|
257
|
-
|
|
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
|
|
294
|
-
|
|
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 =
|
|
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 }) => ({
|
|
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
|
|
326
|
-
|
|
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 &&
|
|
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;
|