@kubb/adapter-oas 5.0.0-beta.37 → 5.0.0-beta.39
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/dist/index.cjs +221 -199
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +221 -199
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/adapter.ts +71 -28
- package/src/factory.ts +5 -5
- package/src/refs.ts +7 -4
- package/src/resolvers.ts +3 -3
- package/src/schemaDiagnostics.ts +25 -8
package/dist/index.cjs
CHANGED
|
@@ -21,12 +21,12 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
21
21
|
enumerable: true
|
|
22
22
|
}) : target, mod));
|
|
23
23
|
//#endregion
|
|
24
|
-
let node_fs_promises = require("node:fs/promises");
|
|
25
|
-
let node_path = require("node:path");
|
|
26
|
-
node_path = __toESM(node_path, 1);
|
|
27
24
|
let _kubb_core = require("@kubb/core");
|
|
28
25
|
let oas = require("oas");
|
|
29
26
|
oas = __toESM(oas, 1);
|
|
27
|
+
let node_path = require("node:path");
|
|
28
|
+
node_path = __toESM(node_path, 1);
|
|
29
|
+
let node_fs_promises = require("node:fs/promises");
|
|
30
30
|
let _redocly_openapi_core = require("@redocly/openapi-core");
|
|
31
31
|
let oas_normalize = require("oas-normalize");
|
|
32
32
|
oas_normalize = __toESM(oas_normalize, 1);
|
|
@@ -34,6 +34,138 @@ let swagger2openapi = require("swagger2openapi");
|
|
|
34
34
|
swagger2openapi = __toESM(swagger2openapi, 1);
|
|
35
35
|
let oas_types = require("oas/types");
|
|
36
36
|
let oas_utils = require("oas/utils");
|
|
37
|
+
//#region src/constants.ts
|
|
38
|
+
/**
|
|
39
|
+
* Default parser options applied when no explicit options are provided.
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```ts
|
|
43
|
+
* import { DEFAULT_PARSER_OPTIONS } from '@kubb/adapter-oas'
|
|
44
|
+
*
|
|
45
|
+
* const parser = createOasParser(oas)
|
|
46
|
+
* const root = parser.parse({ ...DEFAULT_PARSER_OPTIONS, dateType: 'date' })
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
const DEFAULT_PARSER_OPTIONS = {
|
|
50
|
+
dateType: "string",
|
|
51
|
+
integerType: "bigint",
|
|
52
|
+
unknownType: "any",
|
|
53
|
+
emptySchemaType: "any",
|
|
54
|
+
enumSuffix: "enum"
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* JSON-Pointer prefix for schemas declared under `components.schemas` in an OpenAPI document.
|
|
58
|
+
*
|
|
59
|
+
* Used when building or parsing `$ref` strings.
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```ts
|
|
63
|
+
* `${SCHEMA_REF_PREFIX}Pet` // '#/components/schemas/Pet'
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
66
|
+
const SCHEMA_REF_PREFIX = "#/components/schemas/";
|
|
67
|
+
/**
|
|
68
|
+
* OpenAPI version string written into the stub document created during multi-spec merges.
|
|
69
|
+
*/
|
|
70
|
+
const MERGE_OPENAPI_VERSION = "3.0.0";
|
|
71
|
+
/**
|
|
72
|
+
* Fallback `info.title` placed in the stub document when merging multiple API files.
|
|
73
|
+
*/
|
|
74
|
+
const MERGE_DEFAULT_TITLE = "Merged API";
|
|
75
|
+
/**
|
|
76
|
+
* Fallback `info.version` placed in the stub document when merging multiple API files.
|
|
77
|
+
*/
|
|
78
|
+
const MERGE_DEFAULT_VERSION = "1.0.0";
|
|
79
|
+
/**
|
|
80
|
+
* Set of JSON Schema keywords that prevent a schema fragment from being inlined during `allOf` flattening.
|
|
81
|
+
*
|
|
82
|
+
* A fragment that contains any of these keys carries structural meaning of its own and must stay as a separate
|
|
83
|
+
* intersection member rather than being merged into the parent.
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* ```ts
|
|
87
|
+
* import { structuralKeys } from '@kubb/adapter-oas'
|
|
88
|
+
*
|
|
89
|
+
* const isStructural = Object.keys(fragment).some((key) => structuralKeys.has(key))
|
|
90
|
+
* // true when fragment has e.g. 'properties' or 'oneOf'
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
93
|
+
const structuralKeys = new Set([
|
|
94
|
+
"properties",
|
|
95
|
+
"items",
|
|
96
|
+
"additionalProperties",
|
|
97
|
+
"oneOf",
|
|
98
|
+
"anyOf",
|
|
99
|
+
"allOf",
|
|
100
|
+
"not"
|
|
101
|
+
]);
|
|
102
|
+
/**
|
|
103
|
+
* Static map from OAS `format` strings to Kubb `SchemaType` values.
|
|
104
|
+
*
|
|
105
|
+
* Only formats whose AST type differs from the OAS `type` field appear here.
|
|
106
|
+
* Formats that depend on runtime options (`int64`, `date-time`, `date`, `time`) are handled separately
|
|
107
|
+
* in the parser. `ipv4` and `ipv6` map to their own dedicated schema types; `hostname` and
|
|
108
|
+
* `idn-hostname` map to `'url'` as the closest generic string-format type.
|
|
109
|
+
*
|
|
110
|
+
* @example
|
|
111
|
+
* ```ts
|
|
112
|
+
* import { formatMap } from '@kubb/adapter-oas'
|
|
113
|
+
*
|
|
114
|
+
* formatMap['uuid'] // 'uuid'
|
|
115
|
+
* formatMap['binary'] // 'blob'
|
|
116
|
+
* formatMap['float'] // 'number'
|
|
117
|
+
* ```
|
|
118
|
+
*/
|
|
119
|
+
/**
|
|
120
|
+
* Formats `convertFormat` maps to a dedicated type without going through `formatMap`:
|
|
121
|
+
* `int64` and the date/time family. Keep this in sync with the `convertFormat`
|
|
122
|
+
* special-cases in `parser.ts`. `isHandledFormat` reads it so the
|
|
123
|
+
* `KUBB_UNSUPPORTED_FORMAT` diagnostic and the parser agree on what is handled.
|
|
124
|
+
*/
|
|
125
|
+
const specialCasedFormats = new Set([
|
|
126
|
+
"int64",
|
|
127
|
+
"date-time",
|
|
128
|
+
"date",
|
|
129
|
+
"time"
|
|
130
|
+
]);
|
|
131
|
+
const formatMap = {
|
|
132
|
+
uuid: "uuid",
|
|
133
|
+
email: "email",
|
|
134
|
+
"idn-email": "email",
|
|
135
|
+
uri: "url",
|
|
136
|
+
"uri-reference": "url",
|
|
137
|
+
url: "url",
|
|
138
|
+
ipv4: "ipv4",
|
|
139
|
+
ipv6: "ipv6",
|
|
140
|
+
hostname: "url",
|
|
141
|
+
"idn-hostname": "url",
|
|
142
|
+
binary: "blob",
|
|
143
|
+
byte: "blob",
|
|
144
|
+
int32: "integer",
|
|
145
|
+
float: "number",
|
|
146
|
+
double: "number"
|
|
147
|
+
};
|
|
148
|
+
/**
|
|
149
|
+
* Vendor extension keys that attach human-readable labels to enum values, checked in priority order.
|
|
150
|
+
*
|
|
151
|
+
* @example
|
|
152
|
+
* ```ts
|
|
153
|
+
* import { enumExtensionKeys } from '@kubb/adapter-oas'
|
|
154
|
+
*
|
|
155
|
+
* const key = enumExtensionKeys.find((k) => k in schema) // 'x-enumNames' | 'x-enum-varnames' | undefined
|
|
156
|
+
* ```
|
|
157
|
+
*/
|
|
158
|
+
const enumExtensionKeys = ["x-enumNames", "x-enum-varnames"];
|
|
159
|
+
/**
|
|
160
|
+
* Maps `'any' | 'unknown' | 'void'` option strings to their `ScalarSchemaType` constant.
|
|
161
|
+
* Replaces a plain object lookup with a `Map` for explicit key membership testing via `.has()`.
|
|
162
|
+
*/
|
|
163
|
+
const typeOptionMap = new Map([
|
|
164
|
+
["any", _kubb_core.ast.schemaTypes.any],
|
|
165
|
+
["unknown", _kubb_core.ast.schemaTypes.unknown],
|
|
166
|
+
["void", _kubb_core.ast.schemaTypes.void]
|
|
167
|
+
]);
|
|
168
|
+
//#endregion
|
|
37
169
|
//#region ../../internals/utils/src/casing.ts
|
|
38
170
|
/**
|
|
39
171
|
* Shared implementation for camelCase and PascalCase conversion.
|
|
@@ -149,30 +281,6 @@ function mergeDeep(target, source) {
|
|
|
149
281
|
return result;
|
|
150
282
|
}
|
|
151
283
|
//#endregion
|
|
152
|
-
//#region ../../internals/utils/src/promise.ts
|
|
153
|
-
/**
|
|
154
|
-
* Returns a wrapper that caches the result of the first invocation and replays
|
|
155
|
-
* it for every subsequent call, ignoring later arguments.
|
|
156
|
-
*
|
|
157
|
-
* Works for sync and async factories — for async, the cached value is the
|
|
158
|
-
* promise itself, so concurrent callers share one in-flight execution and
|
|
159
|
-
* cannot race each other.
|
|
160
|
-
*
|
|
161
|
-
* @example
|
|
162
|
-
* ```ts
|
|
163
|
-
* const loadDocument = once(async (path: string) => parse(await readFile(path)))
|
|
164
|
-
* const a = loadDocument('./a.yaml') // parses
|
|
165
|
-
* const b = loadDocument('./b.yaml') // returns the cached promise from the first call
|
|
166
|
-
* ```
|
|
167
|
-
*/
|
|
168
|
-
function once(factory) {
|
|
169
|
-
let cache;
|
|
170
|
-
return (...args) => {
|
|
171
|
-
if (!cache) cache = { value: factory(...args) };
|
|
172
|
-
return cache.value;
|
|
173
|
-
};
|
|
174
|
-
}
|
|
175
|
-
//#endregion
|
|
176
284
|
//#region ../../internals/utils/src/reserved.ts
|
|
177
285
|
/**
|
|
178
286
|
* JavaScript and Java reserved words.
|
|
@@ -423,138 +531,6 @@ var URLPath = class {
|
|
|
423
531
|
}
|
|
424
532
|
};
|
|
425
533
|
//#endregion
|
|
426
|
-
//#region src/constants.ts
|
|
427
|
-
/**
|
|
428
|
-
* Default parser options applied when no explicit options are provided.
|
|
429
|
-
*
|
|
430
|
-
* @example
|
|
431
|
-
* ```ts
|
|
432
|
-
* import { DEFAULT_PARSER_OPTIONS } from '@kubb/adapter-oas'
|
|
433
|
-
*
|
|
434
|
-
* const parser = createOasParser(oas)
|
|
435
|
-
* const root = parser.parse({ ...DEFAULT_PARSER_OPTIONS, dateType: 'date' })
|
|
436
|
-
* ```
|
|
437
|
-
*/
|
|
438
|
-
const DEFAULT_PARSER_OPTIONS = {
|
|
439
|
-
dateType: "string",
|
|
440
|
-
integerType: "bigint",
|
|
441
|
-
unknownType: "any",
|
|
442
|
-
emptySchemaType: "any",
|
|
443
|
-
enumSuffix: "enum"
|
|
444
|
-
};
|
|
445
|
-
/**
|
|
446
|
-
* JSON-Pointer prefix for schemas declared under `components.schemas` in an OpenAPI document.
|
|
447
|
-
*
|
|
448
|
-
* Used when building or parsing `$ref` strings.
|
|
449
|
-
*
|
|
450
|
-
* @example
|
|
451
|
-
* ```ts
|
|
452
|
-
* `${SCHEMA_REF_PREFIX}Pet` // '#/components/schemas/Pet'
|
|
453
|
-
* ```
|
|
454
|
-
*/
|
|
455
|
-
const SCHEMA_REF_PREFIX = "#/components/schemas/";
|
|
456
|
-
/**
|
|
457
|
-
* OpenAPI version string written into the stub document created during multi-spec merges.
|
|
458
|
-
*/
|
|
459
|
-
const MERGE_OPENAPI_VERSION = "3.0.0";
|
|
460
|
-
/**
|
|
461
|
-
* Fallback `info.title` placed in the stub document when merging multiple API files.
|
|
462
|
-
*/
|
|
463
|
-
const MERGE_DEFAULT_TITLE = "Merged API";
|
|
464
|
-
/**
|
|
465
|
-
* Fallback `info.version` placed in the stub document when merging multiple API files.
|
|
466
|
-
*/
|
|
467
|
-
const MERGE_DEFAULT_VERSION = "1.0.0";
|
|
468
|
-
/**
|
|
469
|
-
* Set of JSON Schema keywords that prevent a schema fragment from being inlined during `allOf` flattening.
|
|
470
|
-
*
|
|
471
|
-
* A fragment that contains any of these keys carries structural meaning of its own and must stay as a separate
|
|
472
|
-
* intersection member rather than being merged into the parent.
|
|
473
|
-
*
|
|
474
|
-
* @example
|
|
475
|
-
* ```ts
|
|
476
|
-
* import { structuralKeys } from '@kubb/adapter-oas'
|
|
477
|
-
*
|
|
478
|
-
* const isStructural = Object.keys(fragment).some((key) => structuralKeys.has(key))
|
|
479
|
-
* // true when fragment has e.g. 'properties' or 'oneOf'
|
|
480
|
-
* ```
|
|
481
|
-
*/
|
|
482
|
-
const structuralKeys = new Set([
|
|
483
|
-
"properties",
|
|
484
|
-
"items",
|
|
485
|
-
"additionalProperties",
|
|
486
|
-
"oneOf",
|
|
487
|
-
"anyOf",
|
|
488
|
-
"allOf",
|
|
489
|
-
"not"
|
|
490
|
-
]);
|
|
491
|
-
/**
|
|
492
|
-
* Static map from OAS `format` strings to Kubb `SchemaType` values.
|
|
493
|
-
*
|
|
494
|
-
* Only formats whose AST type differs from the OAS `type` field appear here.
|
|
495
|
-
* Formats that depend on runtime options (`int64`, `date-time`, `date`, `time`) are handled separately
|
|
496
|
-
* in the parser. `ipv4` and `ipv6` map to their own dedicated schema types; `hostname` and
|
|
497
|
-
* `idn-hostname` map to `'url'` as the closest generic string-format type.
|
|
498
|
-
*
|
|
499
|
-
* @example
|
|
500
|
-
* ```ts
|
|
501
|
-
* import { formatMap } from '@kubb/adapter-oas'
|
|
502
|
-
*
|
|
503
|
-
* formatMap['uuid'] // 'uuid'
|
|
504
|
-
* formatMap['binary'] // 'blob'
|
|
505
|
-
* formatMap['float'] // 'number'
|
|
506
|
-
* ```
|
|
507
|
-
*/
|
|
508
|
-
/**
|
|
509
|
-
* Formats `convertFormat` maps to a dedicated type without going through `formatMap`:
|
|
510
|
-
* `int64` and the date/time family. Keep this in sync with the `convertFormat`
|
|
511
|
-
* special-cases in `parser.ts`. `isHandledFormat` reads it so the
|
|
512
|
-
* `KUBB_UNSUPPORTED_FORMAT` diagnostic and the parser agree on what is handled.
|
|
513
|
-
*/
|
|
514
|
-
const specialCasedFormats = new Set([
|
|
515
|
-
"int64",
|
|
516
|
-
"date-time",
|
|
517
|
-
"date",
|
|
518
|
-
"time"
|
|
519
|
-
]);
|
|
520
|
-
const formatMap = {
|
|
521
|
-
uuid: "uuid",
|
|
522
|
-
email: "email",
|
|
523
|
-
"idn-email": "email",
|
|
524
|
-
uri: "url",
|
|
525
|
-
"uri-reference": "url",
|
|
526
|
-
url: "url",
|
|
527
|
-
ipv4: "ipv4",
|
|
528
|
-
ipv6: "ipv6",
|
|
529
|
-
hostname: "url",
|
|
530
|
-
"idn-hostname": "url",
|
|
531
|
-
binary: "blob",
|
|
532
|
-
byte: "blob",
|
|
533
|
-
int32: "integer",
|
|
534
|
-
float: "number",
|
|
535
|
-
double: "number"
|
|
536
|
-
};
|
|
537
|
-
/**
|
|
538
|
-
* Vendor extension keys that attach human-readable labels to enum values, checked in priority order.
|
|
539
|
-
*
|
|
540
|
-
* @example
|
|
541
|
-
* ```ts
|
|
542
|
-
* import { enumExtensionKeys } from '@kubb/adapter-oas'
|
|
543
|
-
*
|
|
544
|
-
* const key = enumExtensionKeys.find((k) => k in schema) // 'x-enumNames' | 'x-enum-varnames' | undefined
|
|
545
|
-
* ```
|
|
546
|
-
*/
|
|
547
|
-
const enumExtensionKeys = ["x-enumNames", "x-enum-varnames"];
|
|
548
|
-
/**
|
|
549
|
-
* Maps `'any' | 'unknown' | 'void'` option strings to their `ScalarSchemaType` constant.
|
|
550
|
-
* Replaces a plain object lookup with a `Map` for explicit key membership testing via `.has()`.
|
|
551
|
-
*/
|
|
552
|
-
const typeOptionMap = new Map([
|
|
553
|
-
["any", _kubb_core.ast.schemaTypes.any],
|
|
554
|
-
["unknown", _kubb_core.ast.schemaTypes.unknown],
|
|
555
|
-
["void", _kubb_core.ast.schemaTypes.void]
|
|
556
|
-
]);
|
|
557
|
-
//#endregion
|
|
558
534
|
//#region src/guards.ts
|
|
559
535
|
/**
|
|
560
536
|
* Returns `true` when `doc` is a Swagger 2.0 document (no `openapi` key).
|
|
@@ -664,8 +640,8 @@ async function mergeDocuments(pathOrApi) {
|
|
|
664
640
|
enablePaths: false,
|
|
665
641
|
canBundle: false
|
|
666
642
|
})));
|
|
667
|
-
if (documents.length === 0) throw new _kubb_core.
|
|
668
|
-
code: _kubb_core.
|
|
643
|
+
if (documents.length === 0) throw new _kubb_core.Diagnostics.Error({
|
|
644
|
+
code: _kubb_core.Diagnostics.code.inputRequired,
|
|
669
645
|
severity: "error",
|
|
670
646
|
message: "No OAS documents were provided for merging.",
|
|
671
647
|
help: "Pass at least one path or document to `input.path`.",
|
|
@@ -714,8 +690,8 @@ async function parseFromConfig(source) {
|
|
|
714
690
|
*/
|
|
715
691
|
async function assertInputExists(input) {
|
|
716
692
|
if (new URLPath(input).isURL) return;
|
|
717
|
-
if (!await exists(input)) throw new _kubb_core.
|
|
718
|
-
code: _kubb_core.
|
|
693
|
+
if (!await exists(input)) throw new _kubb_core.Diagnostics.Error({
|
|
694
|
+
code: _kubb_core.Diagnostics.code.inputNotFound,
|
|
719
695
|
severity: "error",
|
|
720
696
|
message: `Cannot read the file set in \`input.path\` (or via \`kubb generate PATH\`): ${input}`,
|
|
721
697
|
help: "Check that the path exists and is readable, then set it in `input.path` or pass it as `kubb generate PATH`.",
|
|
@@ -769,7 +745,7 @@ function resolveRef(document, $ref) {
|
|
|
769
745
|
const current = $ref.split("/").filter(Boolean).reduce((obj, key) => obj?.[key], document);
|
|
770
746
|
if (!current) {
|
|
771
747
|
const diagnostic = {
|
|
772
|
-
code: _kubb_core.
|
|
748
|
+
code: _kubb_core.Diagnostics.code.refNotFound,
|
|
773
749
|
severity: "error",
|
|
774
750
|
message: `Could not find a definition for ${origRef}.`,
|
|
775
751
|
help: "Add the schema under `components.schemas`, or fix the `$ref`. Run `kubb validate` to check the spec.",
|
|
@@ -779,7 +755,7 @@ function resolveRef(document, $ref) {
|
|
|
779
755
|
ref: origRef
|
|
780
756
|
}
|
|
781
757
|
};
|
|
782
|
-
_kubb_core.Diagnostics.report(diagnostic);
|
|
758
|
+
if (!_kubb_core.Diagnostics.report(diagnostic)) throw new _kubb_core.Diagnostics.Error(diagnostic);
|
|
783
759
|
return null;
|
|
784
760
|
}
|
|
785
761
|
docCache.set($ref, current);
|
|
@@ -856,8 +832,8 @@ function resolveServerUrl(server, overrides) {
|
|
|
856
832
|
for (const [key, variable] of Object.entries(server.variables)) {
|
|
857
833
|
const value = overrides?.[key] ?? (variable.default != null ? String(variable.default) : void 0);
|
|
858
834
|
if (value === void 0) continue;
|
|
859
|
-
if (variable.enum?.length && !variable.enum.some((e) => String(e) === value)) throw new _kubb_core.
|
|
860
|
-
code: _kubb_core.
|
|
835
|
+
if (variable.enum?.length && !variable.enum.some((e) => String(e) === value)) throw new _kubb_core.Diagnostics.Error({
|
|
836
|
+
code: _kubb_core.Diagnostics.code.invalidServerVariable,
|
|
861
837
|
severity: "error",
|
|
862
838
|
message: `Invalid server variable value '${value}' for '${key}' when resolving ${server.url}. Valid values are: ${variable.enum.join(", ")}.`,
|
|
863
839
|
help: `Use one of the allowed enum values, or drop the enum on the '${key}' server variable.`,
|
|
@@ -2188,11 +2164,18 @@ function patchDiscriminatorNode(node, entry) {
|
|
|
2188
2164
|
* no-op outside one, and repeats are deduped by the build.
|
|
2189
2165
|
*/
|
|
2190
2166
|
function reportSchemaDiagnostics({ node, name }) {
|
|
2191
|
-
visit(node, `#/components/schemas/${name}`);
|
|
2167
|
+
visit(node, `#/components/schemas/${escapePointerToken(name)}`);
|
|
2168
|
+
}
|
|
2169
|
+
/**
|
|
2170
|
+
* Escapes a single JSON pointer reference token per RFC 6901 (`~` → `~0`, `/` → `~1`), so a
|
|
2171
|
+
* property name with those characters maps to a distinct pointer instead of colliding in the dedupe.
|
|
2172
|
+
*/
|
|
2173
|
+
function escapePointerToken(token) {
|
|
2174
|
+
return token.replace(/~/g, "~0").replace(/\//g, "~1");
|
|
2192
2175
|
}
|
|
2193
2176
|
function visit(node, pointer) {
|
|
2194
2177
|
if (node.deprecated) _kubb_core.Diagnostics.report({
|
|
2195
|
-
code: _kubb_core.
|
|
2178
|
+
code: _kubb_core.Diagnostics.code.deprecated,
|
|
2196
2179
|
severity: "info",
|
|
2197
2180
|
message: "This schema is marked as deprecated.",
|
|
2198
2181
|
location: {
|
|
@@ -2201,7 +2184,7 @@ function visit(node, pointer) {
|
|
|
2201
2184
|
}
|
|
2202
2185
|
});
|
|
2203
2186
|
if (typeof node.format === "string" && !isHandledFormat(node.format)) _kubb_core.Diagnostics.report({
|
|
2204
|
-
code: _kubb_core.
|
|
2187
|
+
code: _kubb_core.Diagnostics.code.unsupportedFormat,
|
|
2205
2188
|
severity: "warning",
|
|
2206
2189
|
message: `Kubb does not map the format "${node.format}" to a specific type, so it falls back to the base type.`,
|
|
2207
2190
|
help: `Use a format Kubb supports, or handle "${node.format}" with a custom parser or plugin.`,
|
|
@@ -2211,15 +2194,19 @@ function visit(node, pointer) {
|
|
|
2211
2194
|
}
|
|
2212
2195
|
});
|
|
2213
2196
|
if (node.type === "object") {
|
|
2214
|
-
for (const property of node.properties) visit(property.schema, `${pointer}/properties/${property.name}`);
|
|
2197
|
+
for (const property of node.properties) visit(property.schema, `${pointer}/properties/${escapePointerToken(property.name)}`);
|
|
2215
2198
|
if (node.additionalProperties && typeof node.additionalProperties === "object") visit(node.additionalProperties, `${pointer}/additionalProperties`);
|
|
2216
2199
|
return;
|
|
2217
2200
|
}
|
|
2218
|
-
if (node.type === "array"
|
|
2201
|
+
if (node.type === "array") {
|
|
2219
2202
|
for (const item of node.items ?? []) visit(item, `${pointer}/items`);
|
|
2220
2203
|
return;
|
|
2221
2204
|
}
|
|
2222
|
-
if (node.type === "
|
|
2205
|
+
if (node.type === "tuple") {
|
|
2206
|
+
for (const [index, item] of (node.items ?? []).entries()) visit(item, `${pointer}/items/${index}`);
|
|
2207
|
+
return;
|
|
2208
|
+
}
|
|
2209
|
+
if (node.type === "union" || node.type === "intersection") for (const [index, member] of (node.members ?? []).entries()) visit(member, `${pointer}/members/${index}`);
|
|
2223
2210
|
}
|
|
2224
2211
|
//#endregion
|
|
2225
2212
|
//#region src/stream.ts
|
|
@@ -2449,37 +2436,72 @@ const adapterOas = (0, _kubb_core.createAdapter)((options) => {
|
|
|
2449
2436
|
};
|
|
2450
2437
|
let nameMapping = /* @__PURE__ */ new Map();
|
|
2451
2438
|
let parsedDocument = null;
|
|
2452
|
-
const
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2439
|
+
const documentCache = /* @__PURE__ */ new WeakMap();
|
|
2440
|
+
const schemasCache = /* @__PURE__ */ new WeakMap();
|
|
2441
|
+
const baseOasCache = /* @__PURE__ */ new WeakMap();
|
|
2442
|
+
const schemaParserCache = /* @__PURE__ */ new WeakMap();
|
|
2443
|
+
const preScanCache = /* @__PURE__ */ new WeakMap();
|
|
2444
|
+
function ensureDocument(source) {
|
|
2445
|
+
const cached = documentCache.get(source);
|
|
2446
|
+
if (cached) return cached;
|
|
2447
|
+
const promise = (async () => {
|
|
2448
|
+
const fresh = await parseFromConfig(source);
|
|
2449
|
+
if (validate) await validateDocument(fresh);
|
|
2450
|
+
parsedDocument = fresh;
|
|
2451
|
+
return fresh;
|
|
2452
|
+
})();
|
|
2453
|
+
documentCache.set(source, promise);
|
|
2454
|
+
return promise;
|
|
2455
|
+
}
|
|
2456
|
+
function ensureSchemas(document) {
|
|
2457
|
+
const cached = schemasCache.get(document);
|
|
2458
|
+
if (cached) return cached;
|
|
2459
|
+
const promise = Promise.resolve().then(() => {
|
|
2460
|
+
const result = getSchemas(document, { contentType });
|
|
2461
|
+
nameMapping = result.nameMapping;
|
|
2462
|
+
return result.schemas;
|
|
2463
|
+
});
|
|
2464
|
+
schemasCache.set(document, promise);
|
|
2465
|
+
return promise;
|
|
2466
|
+
}
|
|
2467
|
+
function ensureBaseOas(document) {
|
|
2468
|
+
const cached = baseOasCache.get(document);
|
|
2469
|
+
if (cached) return cached;
|
|
2470
|
+
const baseOas = new oas.default(document);
|
|
2471
|
+
baseOasCache.set(document, baseOas);
|
|
2472
|
+
return baseOas;
|
|
2473
|
+
}
|
|
2474
|
+
function ensureSchemaParser(document) {
|
|
2475
|
+
const cached = schemaParserCache.get(document);
|
|
2476
|
+
if (cached) return cached;
|
|
2477
|
+
const parser = createSchemaParser({
|
|
2478
|
+
document,
|
|
2479
|
+
contentType
|
|
2480
|
+
});
|
|
2481
|
+
schemaParserCache.set(document, parser);
|
|
2482
|
+
return parser;
|
|
2483
|
+
}
|
|
2484
|
+
function ensurePreScan(document, schemas, parseSchema, parseOperation, baseOas) {
|
|
2485
|
+
const cached = preScanCache.get(document);
|
|
2486
|
+
if (cached) return cached;
|
|
2487
|
+
const result = preScan({
|
|
2488
|
+
schemas,
|
|
2489
|
+
parseSchema,
|
|
2490
|
+
parseOperation,
|
|
2491
|
+
baseOas,
|
|
2492
|
+
parserOptions,
|
|
2493
|
+
discriminator,
|
|
2494
|
+
dedupe
|
|
2495
|
+
});
|
|
2496
|
+
preScanCache.set(document, result);
|
|
2497
|
+
return result;
|
|
2498
|
+
}
|
|
2477
2499
|
async function createStream(source) {
|
|
2478
2500
|
const document = await ensureDocument(source);
|
|
2479
2501
|
const schemas = await ensureSchemas(document);
|
|
2480
2502
|
const { parseSchema, parseOperation } = ensureSchemaParser(document);
|
|
2481
2503
|
const baseOas = ensureBaseOas(document);
|
|
2482
|
-
const { refAliasMap, enumNames, circularNames, discriminatorChildMap, dedupePlan } = ensurePreScan(schemas, parseSchema, parseOperation, baseOas);
|
|
2504
|
+
const { refAliasMap, enumNames, circularNames, discriminatorChildMap, dedupePlan } = ensurePreScan(document, schemas, parseSchema, parseOperation, baseOas);
|
|
2483
2505
|
return createInputStream({
|
|
2484
2506
|
schemas,
|
|
2485
2507
|
parseSchema,
|