@apollo-deploy/tesseract 1.8.0 → 2.0.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 +77 -3
- package/dist/collector.d.ts.map +1 -1
- package/dist/collector.js +198 -20
- 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 +8 -9
- package/dist/fastify.d.ts.map +1 -1
- package/dist/fastify.js +105 -164
- 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,18 @@
|
|
|
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
|
+
/**
|
|
33
|
+
* Minimal interface for Zod v4's global registry — only what Tesseract needs.
|
|
34
|
+
* Declared here so adapters don't need a hard dependency on `zod`.
|
|
35
|
+
*/
|
|
36
|
+
export interface ZodGlobalRegistry {
|
|
37
|
+
get(schema: unknown): {
|
|
38
|
+
id?: string;
|
|
39
|
+
} | undefined;
|
|
40
|
+
/** Internal id→schema map present in Zod v4 registries. */
|
|
41
|
+
_idmap?: Map<string, unknown>;
|
|
42
|
+
}
|
|
32
43
|
export interface CollectorOptions {
|
|
33
44
|
/** API metadata written into the generated package.json and README. */
|
|
34
45
|
info: {
|
|
@@ -50,6 +61,33 @@ export interface CollectorOptions {
|
|
|
50
61
|
version?: string;
|
|
51
62
|
importPath?: string;
|
|
52
63
|
};
|
|
64
|
+
/**
|
|
65
|
+
* Function to convert framework-specific schema objects (e.g. raw Zod schemas)
|
|
66
|
+
* to JSON Schema at generation time.
|
|
67
|
+
*
|
|
68
|
+
* Required when using `fastify-type-provider-zod` or passing raw Zod schemas
|
|
69
|
+
* directly to route/collector configs. Pass `toJSONSchema` from `zod` v4.
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* ```ts
|
|
73
|
+
* import { toJSONSchema } from 'zod';
|
|
74
|
+
* new SDKCollector({ ..., schemaConverter: toJSONSchema });
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
schemaConverter?: (schema: unknown) => unknown;
|
|
78
|
+
/**
|
|
79
|
+
* Zod v4 global registry — controls how registered schemas are resolved
|
|
80
|
+
* when `schemaConverter` is set.
|
|
81
|
+
*
|
|
82
|
+
* - With `schemaPackage`: registered schemas emit a bare `$ref: 'Id'` so
|
|
83
|
+
* intake creates external import stubs.
|
|
84
|
+
* - Without `schemaPackage` (or when a target sets `schemaPackage: null`):
|
|
85
|
+
* registered schemas are expanded and wrapped in `$defs` so intake
|
|
86
|
+
* generates named data classes (e.g. Kotlin `data class`).
|
|
87
|
+
*
|
|
88
|
+
* Pass `z.globalRegistry` from your app.
|
|
89
|
+
*/
|
|
90
|
+
zodGlobalRegistry?: ZodGlobalRegistry;
|
|
53
91
|
/** `'functional'` (default) or `'class'` (Resend-style `new MySDK('key')`). */
|
|
54
92
|
sdkStyle?: 'functional' | 'class';
|
|
55
93
|
/** `'internal'` (default) or `'public'` (auth key only, baseUrl baked in). */
|
|
@@ -58,6 +96,8 @@ export interface CollectorOptions {
|
|
|
58
96
|
packageName?: string;
|
|
59
97
|
/** Override the generated package version. */
|
|
60
98
|
packageVersion?: string;
|
|
99
|
+
/** Version increment used when packageVersion is omitted. */
|
|
100
|
+
versionBump?: VersionBump;
|
|
61
101
|
/**
|
|
62
102
|
* Target SDK language for the primary output. Defaults to `'typescript'`.
|
|
63
103
|
* Use `additionalTargets` to emit multiple languages simultaneously.
|
|
@@ -86,6 +126,7 @@ export interface CollectorOptions {
|
|
|
86
126
|
output: string;
|
|
87
127
|
packageName?: string;
|
|
88
128
|
packageVersion?: string;
|
|
129
|
+
versionBump?: VersionBump;
|
|
89
130
|
clientType?: 'internal' | 'public';
|
|
90
131
|
sdkStyle?: 'functional' | 'class';
|
|
91
132
|
/**
|
|
@@ -96,12 +137,17 @@ export interface CollectorOptions {
|
|
|
96
137
|
* from a shared TypeScript package but an additional target (e.g. Kotlin)
|
|
97
138
|
* needs self-contained inline types.
|
|
98
139
|
*
|
|
99
|
-
*
|
|
140
|
+
* Non-TypeScript targets default to expanding types inline (as if
|
|
141
|
+
* `schemaPackage: null`) when this field is omitted, since they cannot
|
|
142
|
+
* import a TypeScript schema package.
|
|
143
|
+
*
|
|
144
|
+
* Omit on a TypeScript additional target to inherit the primary `schemaPackage`.
|
|
100
145
|
*
|
|
101
146
|
* @example
|
|
102
147
|
* ```ts
|
|
103
148
|
* additionalTargets: [
|
|
104
|
-
* { language: 'kotlin', output: './sdk/java',
|
|
149
|
+
* { language: 'kotlin', output: './sdk/java' }, // auto-expands types
|
|
150
|
+
* { language: 'kotlin', output: './sdk/java', schemaPackage: null }, // explicit
|
|
105
151
|
* ]
|
|
106
152
|
* ```
|
|
107
153
|
*/
|
|
@@ -152,6 +198,8 @@ export declare class SDKCollector {
|
|
|
152
198
|
* @param config - Schema and SDK options for this route.
|
|
153
199
|
*/
|
|
154
200
|
route(url: string, method: string, config: CollectorRouteConfig): this;
|
|
201
|
+
/** Number of routes currently registered. */
|
|
202
|
+
get routeCount(): number;
|
|
155
203
|
/** Build and return the `BackendManifest` from all accumulated routes and domains. */
|
|
156
204
|
buildManifest(): BackendManifest;
|
|
157
205
|
/** Generate the SDK from accumulated routes and domains. */
|
|
@@ -169,6 +217,32 @@ export declare class SDKCollector {
|
|
|
169
217
|
*/
|
|
170
218
|
tryGenerate(): Promise<boolean>;
|
|
171
219
|
}
|
|
220
|
+
/**
|
|
221
|
+
* Post-process a JSON Schema produced by `toJSONSchema` so that any `$defs`
|
|
222
|
+
* entry whose key matches a registered global id is lifted to a bare `$ref`.
|
|
223
|
+
* Used in the external-target path so intake treats them as import stubs.
|
|
224
|
+
*/
|
|
225
|
+
export declare function liftRegisteredRefs(schema: unknown, registeredIds: Set<string>): unknown;
|
|
226
|
+
/**
|
|
227
|
+
* Convert a single raw schema value to JSON Schema.
|
|
228
|
+
*
|
|
229
|
+
* - `isExternalTarget: true` — registered schema → bare `$ref: 'Id'` (external import stub)
|
|
230
|
+
* - `isExternalTarget: false` — registered schema → `{ $defs: { Id: <expanded> }, $ref: '#/$defs/Id' }`
|
|
231
|
+
* so `buildManifestFromRoutes` can extract it as a named local definition.
|
|
232
|
+
* - No registry — calls `toJSONSchema` directly; nested `$defs` are extracted by
|
|
233
|
+
* `buildManifestFromRoutes`.
|
|
234
|
+
*/
|
|
235
|
+
export declare function convertSchemaValue(value: unknown, toJSONSchema: (s: unknown) => unknown, zodRegistry?: ZodGlobalRegistry, isExternalTarget?: boolean): unknown;
|
|
236
|
+
/**
|
|
237
|
+
* Convert all schema fields on a single route schema, applying the correct
|
|
238
|
+
* Zod→JSON Schema conversion strategy for the target.
|
|
239
|
+
*/
|
|
240
|
+
export declare function convertRouteSchema(schema: ManifestRouteSchema | undefined, toJSONSchema: (s: unknown) => unknown, zodRegistry?: ZodGlobalRegistry, isExternalTarget?: boolean): ManifestRouteSchema | undefined;
|
|
241
|
+
/**
|
|
242
|
+
* Resolve the `toJSONSchema` converter: use the explicit one if provided,
|
|
243
|
+
* otherwise attempt auto-detection from the host app's `zod` package.
|
|
244
|
+
*/
|
|
245
|
+
export declare function resolveSchemaConverter(explicit?: (s: unknown) => unknown): Promise<((s: unknown) => unknown) | undefined>;
|
|
172
246
|
/**
|
|
173
247
|
* Builds a `BackendManifest` from a flat list of collected routes and a domain
|
|
174
248
|
* 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);
|
|
@@ -78,24 +86,52 @@ export class SDKCollector {
|
|
|
78
86
|
/** Generate the SDK from accumulated routes and domains. */
|
|
79
87
|
async generate() {
|
|
80
88
|
const { generate } = await import('./index.js');
|
|
81
|
-
const
|
|
89
|
+
const toJSONSchema = await resolveSchemaConverter(this.opts.schemaConverter);
|
|
90
|
+
/**
|
|
91
|
+
* Build a manifest for a specific schemaPackage context.
|
|
92
|
+
* When `toJSONSchema` is available, routes are re-converted with the
|
|
93
|
+
* correct `isExternalTarget` flag before the manifest is built.
|
|
94
|
+
*/
|
|
95
|
+
const buildManifestFor = (schemaPackage) => {
|
|
96
|
+
if (!toJSONSchema) {
|
|
97
|
+
return buildManifestFromRoutes(this._routes, this._registry, this.opts.info, schemaPackage);
|
|
98
|
+
}
|
|
99
|
+
const isExternal = !!schemaPackage;
|
|
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;
|
|
104
|
+
const converted = this._routes.map((r) => ({
|
|
105
|
+
...r,
|
|
106
|
+
schema: convertRouteSchema(r.schema, toJSONSchema, registry, isExternal),
|
|
107
|
+
}));
|
|
108
|
+
return buildManifestFromRoutes(converted, this._registry, this.opts.info, schemaPackage);
|
|
109
|
+
};
|
|
110
|
+
const primaryManifest = buildManifestFor(this.opts.schemaPackage);
|
|
82
111
|
const primary = await generate({
|
|
83
|
-
manifest,
|
|
112
|
+
manifest: primaryManifest,
|
|
84
113
|
output: this.opts.output,
|
|
85
114
|
language: this.opts.language,
|
|
86
115
|
clientType: this.opts.clientType,
|
|
87
116
|
packageName: this.opts.packageName,
|
|
88
117
|
packageVersion: this.opts.packageVersion,
|
|
118
|
+
versionBump: this.opts.versionBump,
|
|
89
119
|
sdkStyle: this.opts.sdkStyle,
|
|
90
120
|
});
|
|
91
121
|
for (const target of this.opts.additionalTargets ?? []) {
|
|
92
|
-
// If the target overrides schemaPackage (including null to disable it),
|
|
93
|
-
// rebuild the manifest with the target-specific schemaPackage so that
|
|
94
|
-
// intake resolves types correctly for this language.
|
|
95
122
|
const hasSchemaPackageOverride = Object.prototype.hasOwnProperty.call(target, 'schemaPackage');
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
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';
|
|
126
|
+
const targetSchemaPackage = hasSchemaPackageOverride
|
|
127
|
+
? (target.schemaPackage ?? undefined)
|
|
128
|
+
: inheritsSchemaPackage
|
|
129
|
+
? undefined
|
|
130
|
+
: this.opts.schemaPackage;
|
|
131
|
+
const targetManifest = hasSchemaPackageOverride ||
|
|
132
|
+
targetSchemaPackage !== this.opts.schemaPackage
|
|
133
|
+
? buildManifestFor(targetSchemaPackage)
|
|
134
|
+
: primaryManifest;
|
|
99
135
|
const extra = await generate({
|
|
100
136
|
manifest: targetManifest,
|
|
101
137
|
output: target.output,
|
|
@@ -103,12 +139,13 @@ export class SDKCollector {
|
|
|
103
139
|
clientType: target.clientType ?? this.opts.clientType,
|
|
104
140
|
packageName: target.packageName ?? this.opts.packageName,
|
|
105
141
|
packageVersion: target.packageVersion ?? this.opts.packageVersion,
|
|
142
|
+
versionBump: target.versionBump ?? this.opts.versionBump,
|
|
106
143
|
sdkStyle: target.sdkStyle ?? this.opts.sdkStyle,
|
|
107
144
|
});
|
|
108
|
-
// Merge warnings and counts back into the primary result so callers
|
|
109
|
-
// get a single aggregated result regardless of target count.
|
|
110
145
|
primary.filesWritten += extra.filesWritten;
|
|
111
146
|
primary.filesSkipped += extra.filesSkipped;
|
|
147
|
+
primary.filesDeleted += extra.filesDeleted;
|
|
148
|
+
primary.hasChanges ||= extra.hasChanges;
|
|
112
149
|
primary.warnings.push(...extra.warnings);
|
|
113
150
|
primary.changedFiles.push(...extra.changedFiles);
|
|
114
151
|
}
|
|
@@ -133,11 +170,139 @@ export class SDKCollector {
|
|
|
133
170
|
for (const w of result.warnings)
|
|
134
171
|
console.warn(` ⚠ ${w}`);
|
|
135
172
|
}
|
|
136
|
-
const targets = [
|
|
173
|
+
const targets = [
|
|
174
|
+
this.opts.output,
|
|
175
|
+
...(this.opts.additionalTargets ?? []).map((t) => t.output),
|
|
176
|
+
];
|
|
137
177
|
console.log(`[tesseract] ✓ ${result.filesWritten} files written → ${targets.join(', ')}`);
|
|
138
178
|
return true;
|
|
139
179
|
}
|
|
140
180
|
}
|
|
181
|
+
// ── Zod schema conversion ─────────────────────────────────────────────────────
|
|
182
|
+
/** Returns true when `value` is a Zod v4 schema instance. */
|
|
183
|
+
function isZodSchema(value) {
|
|
184
|
+
return !!value && typeof value === 'object' && '_zod' in value;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Post-process a JSON Schema produced by `toJSONSchema` so that any `$defs`
|
|
188
|
+
* entry whose key matches a registered global id is lifted to a bare `$ref`.
|
|
189
|
+
* Used in the external-target path so intake treats them as import stubs.
|
|
190
|
+
*/
|
|
191
|
+
export function liftRegisteredRefs(schema, registeredIds) {
|
|
192
|
+
if (!schema || typeof schema !== 'object')
|
|
193
|
+
return schema;
|
|
194
|
+
if (Array.isArray(schema)) {
|
|
195
|
+
return schema.map((item) => liftRegisteredRefs(item, registeredIds));
|
|
196
|
+
}
|
|
197
|
+
const s = schema;
|
|
198
|
+
if (typeof s.$ref === 'string' && s.$ref.startsWith('#/$defs/')) {
|
|
199
|
+
const id = s.$ref.slice('#/$defs/'.length);
|
|
200
|
+
if (registeredIds.has(id))
|
|
201
|
+
return { $ref: id };
|
|
202
|
+
}
|
|
203
|
+
const result = {};
|
|
204
|
+
for (const [key, val] of Object.entries(s)) {
|
|
205
|
+
if (key === '$defs')
|
|
206
|
+
continue;
|
|
207
|
+
result[key] = liftRegisteredRefs(val, registeredIds);
|
|
208
|
+
}
|
|
209
|
+
if (s.$defs && typeof s.$defs === 'object' && !Array.isArray(s.$defs)) {
|
|
210
|
+
const remainingDefs = {};
|
|
211
|
+
for (const [defKey, defVal] of Object.entries(s.$defs)) {
|
|
212
|
+
if (!registeredIds.has(defKey)) {
|
|
213
|
+
remainingDefs[defKey] = liftRegisteredRefs(defVal, registeredIds);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
if (Object.keys(remainingDefs).length > 0)
|
|
217
|
+
result.$defs = remainingDefs;
|
|
218
|
+
}
|
|
219
|
+
return result;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Convert a single raw schema value to JSON Schema.
|
|
223
|
+
*
|
|
224
|
+
* - `isExternalTarget: true` — registered schema → bare `$ref: 'Id'` (external import stub)
|
|
225
|
+
* - `isExternalTarget: false` — registered schema → `{ $defs: { Id: <expanded> }, $ref: '#/$defs/Id' }`
|
|
226
|
+
* so `buildManifestFromRoutes` can extract it as a named local definition.
|
|
227
|
+
* - No registry — calls `toJSONSchema` directly; nested `$defs` are extracted by
|
|
228
|
+
* `buildManifestFromRoutes`.
|
|
229
|
+
*/
|
|
230
|
+
export function convertSchemaValue(value, toJSONSchema, zodRegistry, isExternalTarget) {
|
|
231
|
+
if (isZodSchema(value)) {
|
|
232
|
+
if (zodRegistry) {
|
|
233
|
+
const entry = zodRegistry.get(value);
|
|
234
|
+
if (entry?.id) {
|
|
235
|
+
if (isExternalTarget) {
|
|
236
|
+
return { $ref: entry.id };
|
|
237
|
+
}
|
|
238
|
+
const expanded = toJSONSchema(value);
|
|
239
|
+
return { $defs: { [entry.id]: expanded }, $ref: `#/$defs/${entry.id}` };
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
const jsonSchema = toJSONSchema(value);
|
|
243
|
+
// Only lift registered `$defs` → bare `$ref` for external (schemaPackage)
|
|
244
|
+
// targets. Inline targets must keep `$defs` so they become local models.
|
|
245
|
+
if (isExternalTarget &&
|
|
246
|
+
zodRegistry?._idmap &&
|
|
247
|
+
jsonSchema &&
|
|
248
|
+
typeof jsonSchema === 'object') {
|
|
249
|
+
const registeredIds = new Set(zodRegistry._idmap.keys());
|
|
250
|
+
return liftRegisteredRefs(jsonSchema, registeredIds);
|
|
251
|
+
}
|
|
252
|
+
return jsonSchema;
|
|
253
|
+
}
|
|
254
|
+
return value;
|
|
255
|
+
}
|
|
256
|
+
// Schema fields eligible for registry-based $ref replacement.
|
|
257
|
+
// headers are always expanded inline since they're rarely top-level registered schemas.
|
|
258
|
+
const REGISTRY_ELIGIBLE_FIELDS = new Set([
|
|
259
|
+
'body',
|
|
260
|
+
'querystring',
|
|
261
|
+
'query',
|
|
262
|
+
'params',
|
|
263
|
+
]);
|
|
264
|
+
/**
|
|
265
|
+
* Convert all schema fields on a single route schema, applying the correct
|
|
266
|
+
* Zod→JSON Schema conversion strategy for the target.
|
|
267
|
+
*/
|
|
268
|
+
export function convertRouteSchema(schema, toJSONSchema, zodRegistry, isExternalTarget) {
|
|
269
|
+
if (!schema)
|
|
270
|
+
return schema;
|
|
271
|
+
const result = {};
|
|
272
|
+
for (const [key, val] of Object.entries(schema)) {
|
|
273
|
+
if (key === 'response' && val && typeof val === 'object') {
|
|
274
|
+
const serialized = {};
|
|
275
|
+
for (const [status, responseSchema] of Object.entries(val)) {
|
|
276
|
+
serialized[status] = convertSchemaValue(responseSchema, toJSONSchema, zodRegistry, isExternalTarget);
|
|
277
|
+
}
|
|
278
|
+
result[key] = serialized;
|
|
279
|
+
}
|
|
280
|
+
else if (REGISTRY_ELIGIBLE_FIELDS.has(key)) {
|
|
281
|
+
result[key] = convertSchemaValue(val, toJSONSchema, zodRegistry, isExternalTarget);
|
|
282
|
+
}
|
|
283
|
+
else {
|
|
284
|
+
result[key] = convertSchemaValue(val, toJSONSchema);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
return result;
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Resolve the `toJSONSchema` converter: use the explicit one if provided,
|
|
291
|
+
* otherwise attempt auto-detection from the host app's `zod` package.
|
|
292
|
+
*/
|
|
293
|
+
export async function resolveSchemaConverter(explicit) {
|
|
294
|
+
if (typeof explicit === 'function')
|
|
295
|
+
return explicit;
|
|
296
|
+
try {
|
|
297
|
+
const zodPkg = 'zod';
|
|
298
|
+
const zodModule = (await import(zodPkg));
|
|
299
|
+
const converter = zodModule.toJSONSchema;
|
|
300
|
+
return typeof converter === 'function' ? converter : undefined;
|
|
301
|
+
}
|
|
302
|
+
catch {
|
|
303
|
+
return undefined;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
141
306
|
// ── Shared manifest builder ───────────────────────────────────────────────────
|
|
142
307
|
/**
|
|
143
308
|
* Builds a `BackendManifest` from a flat list of collected routes and a domain
|
|
@@ -149,15 +314,15 @@ export function buildManifestFromRoutes(routes, registry, info, schemaPackage) {
|
|
|
149
314
|
const sortedPrefixes = [...registry.keys()].sort((a, b) => b.length - a.length);
|
|
150
315
|
const domainMap = new Map();
|
|
151
316
|
for (const route of routes) {
|
|
152
|
-
const
|
|
153
|
-
|
|
317
|
+
const url = normalizePath(route.url);
|
|
318
|
+
const matchedPrefix = sortedPrefixes.find((prefix) => prefix === '/' || url === prefix || url.startsWith(`${prefix}/`)) ?? derivePrefix(url);
|
|
154
319
|
if (!domainMap.has(matchedPrefix)) {
|
|
155
320
|
domainMap.set(matchedPrefix, {
|
|
156
321
|
config: registry.get(matchedPrefix) ?? { prefix: matchedPrefix },
|
|
157
322
|
routes: [],
|
|
158
323
|
});
|
|
159
324
|
}
|
|
160
|
-
const tail =
|
|
325
|
+
const tail = url.substring(matchedPrefix === '/' ? 0 : matchedPrefix.length) || '/';
|
|
161
326
|
domainMap.get(matchedPrefix).routes.push({
|
|
162
327
|
method: route.method,
|
|
163
328
|
url: tail.startsWith('/') ? tail : '/' + tail,
|
|
@@ -175,14 +340,25 @@ export function buildManifestFromRoutes(routes, registry, info, schemaPackage) {
|
|
|
175
340
|
baseUrl: info.baseUrl,
|
|
176
341
|
},
|
|
177
342
|
...(schemaPackage && { schemaPackage }),
|
|
178
|
-
domains: [...domainMap.values()].map(({ config, routes }) => ({
|
|
343
|
+
domains: [...domainMap.values()].map(({ config, routes }) => ({
|
|
344
|
+
...config,
|
|
345
|
+
routes,
|
|
346
|
+
})),
|
|
179
347
|
...buildDefinitionsFromDefs(routes),
|
|
180
348
|
};
|
|
181
349
|
}
|
|
182
350
|
/** Derives a domain prefix from the first non-parameter URL segment. */
|
|
183
351
|
function derivePrefix(url) {
|
|
184
|
-
const first = url
|
|
185
|
-
|
|
352
|
+
const first = url
|
|
353
|
+
.split('/')
|
|
354
|
+
.find((segment) => segment && !segment.startsWith(':'));
|
|
355
|
+
return first ? `/${first}` : '/';
|
|
356
|
+
}
|
|
357
|
+
function normalizePath(value) {
|
|
358
|
+
const path = value.trim();
|
|
359
|
+
if (!path || path === '/')
|
|
360
|
+
return '/';
|
|
361
|
+
return `/${path.replace(/^\/+|\/+$/g, '')}`;
|
|
186
362
|
}
|
|
187
363
|
// ── $defs extraction ──────────────────────────────────────────────────────────
|
|
188
364
|
/**
|
|
@@ -224,7 +400,9 @@ function buildDefinitionsFromDefs(routes) {
|
|
|
224
400
|
function collectDefs(schema, out) {
|
|
225
401
|
if (!schema || typeof schema !== 'object')
|
|
226
402
|
return;
|
|
227
|
-
if (schema.$defs &&
|
|
403
|
+
if (schema.$defs &&
|
|
404
|
+
typeof schema.$defs === 'object' &&
|
|
405
|
+
!Array.isArray(schema.$defs)) {
|
|
228
406
|
for (const [key, val] of Object.entries(schema.$defs)) {
|
|
229
407
|
if (!(key in out))
|
|
230
408
|
out[key] = val;
|