@kubb/ast 5.0.0-alpha.16 → 5.0.0-alpha.18
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 +651 -494
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +229 -68
- package/dist/index.js +638 -489
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +2 -2
- package/dist/visitor-DCQyoFvH.d.ts +1976 -0
- package/package.json +1 -1
- package/src/constants.ts +88 -4
- package/src/factory.ts +174 -37
- package/src/guards.ts +37 -10
- package/src/index.ts +6 -5
- package/src/infer.ts +130 -0
- package/src/mocks.ts +4 -3
- package/src/nodes/base.ts +21 -3
- package/src/nodes/function.ts +34 -22
- package/src/nodes/http.ts +17 -5
- package/src/nodes/index.ts +14 -4
- package/src/nodes/operation.ts +47 -9
- package/src/nodes/parameter.ts +27 -1
- package/src/nodes/property.ts +23 -1
- package/src/nodes/response.ts +24 -4
- package/src/nodes/root.ts +29 -8
- package/src/nodes/schema.ts +301 -37
- package/src/{functionPrinter.ts → printers/functionPrinter.ts} +20 -19
- package/src/printers/index.ts +3 -0
- package/src/{printer.ts → printers/printer.ts} +60 -44
- package/src/refs.ts +30 -6
- package/src/resolvers.ts +45 -0
- package/src/transformers.ts +196 -0
- package/src/types.ts +2 -1
- package/src/utils.ts +37 -8
- package/src/visitor.ts +204 -18
- package/dist/visitor-YMltBj6w.d.ts +0 -970
- package/src/transforms.ts +0 -114
package/dist/index.cjs
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
Object.defineProperty;
|
|
3
3
|
//#endregion
|
|
4
|
-
let node_util = require("node:util");
|
|
5
4
|
//#region src/constants.ts
|
|
6
5
|
const visitorDepths = {
|
|
7
6
|
shallow: "shallow",
|
|
@@ -18,6 +17,17 @@ const nodeKinds = {
|
|
|
18
17
|
objectBindingParameter: "ObjectBindingParameter",
|
|
19
18
|
functionParameters: "FunctionParameters"
|
|
20
19
|
};
|
|
20
|
+
/**
|
|
21
|
+
* Canonical schema type strings used by AST schema nodes.
|
|
22
|
+
*
|
|
23
|
+
* These values are used across the AST as stable discriminators
|
|
24
|
+
* (for example `schema.type === schemaTypes.object`).
|
|
25
|
+
*
|
|
26
|
+
* The map is grouped by intent:
|
|
27
|
+
* - primitives (`string`, `number`, `boolean`, ...)
|
|
28
|
+
* - structural/composite (`object`, `array`, `union`, ...)
|
|
29
|
+
* - special OpenAPI-oriented types (`ref`, `datetime`, `uuid`, ...)
|
|
30
|
+
*/
|
|
21
31
|
const schemaTypes = {
|
|
22
32
|
string: "string",
|
|
23
33
|
number: "number",
|
|
@@ -45,7 +55,7 @@ const schemaTypes = {
|
|
|
45
55
|
never: "never"
|
|
46
56
|
};
|
|
47
57
|
/**
|
|
48
|
-
*
|
|
58
|
+
* Primitive scalar schema types used when simplifying union members.
|
|
49
59
|
*/
|
|
50
60
|
const SCALAR_PRIMITIVE_TYPES = new Set([
|
|
51
61
|
"string",
|
|
@@ -86,9 +96,241 @@ const mediaTypes = {
|
|
|
86
96
|
videoMp4: "video/mp4"
|
|
87
97
|
};
|
|
88
98
|
//#endregion
|
|
99
|
+
//#region ../../internals/utils/src/casing.ts
|
|
100
|
+
/**
|
|
101
|
+
* Shared implementation for camelCase and PascalCase conversion.
|
|
102
|
+
* Splits on common word boundaries (spaces, hyphens, underscores, dots, slashes, colons)
|
|
103
|
+
* and capitalizes each word according to `pascal`.
|
|
104
|
+
*
|
|
105
|
+
* When `pascal` is `true` the first word is also capitalized (PascalCase), otherwise only subsequent words are.
|
|
106
|
+
*/
|
|
107
|
+
function toCamelOrPascal(text, pascal) {
|
|
108
|
+
return text.trim().replace(/([a-z\d])([A-Z])/g, "$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2").replace(/(\d)([a-z])/g, "$1 $2").split(/[\s\-_./\\:]+/).filter(Boolean).map((word, i) => {
|
|
109
|
+
if (word.length > 1 && word === word.toUpperCase()) return word;
|
|
110
|
+
if (i === 0 && !pascal) return word.charAt(0).toLowerCase() + word.slice(1);
|
|
111
|
+
return word.charAt(0).toUpperCase() + word.slice(1);
|
|
112
|
+
}).join("").replace(/[^a-zA-Z0-9]/g, "");
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Splits `text` on `.` and applies `transformPart` to each segment.
|
|
116
|
+
* The last segment receives `isLast = true`, all earlier segments receive `false`.
|
|
117
|
+
* Segments are joined with `/` to form a file path.
|
|
118
|
+
*
|
|
119
|
+
* Only splits on dots followed by a letter so that version numbers
|
|
120
|
+
* embedded in operationIds (e.g. `v2025.0`) are kept intact.
|
|
121
|
+
*/
|
|
122
|
+
function applyToFileParts(text, transformPart) {
|
|
123
|
+
const parts = text.split(/\.(?=[a-zA-Z])/);
|
|
124
|
+
return parts.map((part, i) => transformPart(part, i === parts.length - 1)).join("/");
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Converts `text` to camelCase.
|
|
128
|
+
* When `isFile` is `true`, dot-separated segments are each cased independently and joined with `/`.
|
|
129
|
+
*
|
|
130
|
+
* @example
|
|
131
|
+
* camelCase('hello-world') // 'helloWorld'
|
|
132
|
+
* camelCase('pet.petId', { isFile: true }) // 'pet/petId'
|
|
133
|
+
*/
|
|
134
|
+
function camelCase(text, { isFile, prefix = "", suffix = "" } = {}) {
|
|
135
|
+
if (isFile) return applyToFileParts(text, (part, isLast) => camelCase(part, isLast ? {
|
|
136
|
+
prefix,
|
|
137
|
+
suffix
|
|
138
|
+
} : {}));
|
|
139
|
+
return toCamelOrPascal(`${prefix} ${text} ${suffix}`, false);
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Converts `text` to PascalCase.
|
|
143
|
+
* When `isFile` is `true`, the last dot-separated segment is PascalCased and earlier segments are camelCased.
|
|
144
|
+
*
|
|
145
|
+
* @example
|
|
146
|
+
* pascalCase('hello-world') // 'HelloWorld'
|
|
147
|
+
* pascalCase('pet.petId', { isFile: true }) // 'pet/PetId'
|
|
148
|
+
*/
|
|
149
|
+
function pascalCase(text, { isFile, prefix = "", suffix = "" } = {}) {
|
|
150
|
+
if (isFile) return applyToFileParts(text, (part, isLast) => isLast ? pascalCase(part, {
|
|
151
|
+
prefix,
|
|
152
|
+
suffix
|
|
153
|
+
}) : camelCase(part));
|
|
154
|
+
return toCamelOrPascal(`${prefix} ${text} ${suffix}`, true);
|
|
155
|
+
}
|
|
156
|
+
//#endregion
|
|
157
|
+
//#region ../../internals/utils/src/reserved.ts
|
|
158
|
+
/**
|
|
159
|
+
* Returns `true` when `name` is a syntactically valid JavaScript variable name.
|
|
160
|
+
*
|
|
161
|
+
* @example
|
|
162
|
+
* ```ts
|
|
163
|
+
* isValidVarName('status') // true
|
|
164
|
+
* isValidVarName('class') // false (reserved word)
|
|
165
|
+
* isValidVarName('42foo') // false (starts with digit)
|
|
166
|
+
* ```
|
|
167
|
+
*/
|
|
168
|
+
function isValidVarName(name) {
|
|
169
|
+
try {
|
|
170
|
+
new Function(`var ${name}`);
|
|
171
|
+
} catch {
|
|
172
|
+
return false;
|
|
173
|
+
}
|
|
174
|
+
return true;
|
|
175
|
+
}
|
|
176
|
+
//#endregion
|
|
177
|
+
//#region src/guards.ts
|
|
178
|
+
/**
|
|
179
|
+
* Narrows a `SchemaNode` to the variant that matches `type`.
|
|
180
|
+
*
|
|
181
|
+
* @example
|
|
182
|
+
* ```ts
|
|
183
|
+
* const schema = createSchema({ type: 'string' })
|
|
184
|
+
* const stringNode = narrowSchema(schema, 'string') // StringSchemaNode | undefined
|
|
185
|
+
* ```
|
|
186
|
+
*/
|
|
187
|
+
function narrowSchema(node, type) {
|
|
188
|
+
return node?.type === type ? node : void 0;
|
|
189
|
+
}
|
|
190
|
+
function isKind(kind) {
|
|
191
|
+
return (node) => node.kind === kind;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Returns `true` when the input is a `RootNode`.
|
|
195
|
+
*
|
|
196
|
+
* @example
|
|
197
|
+
* ```ts
|
|
198
|
+
* if (isRootNode(node)) {
|
|
199
|
+
* console.log(node.schemas.length)
|
|
200
|
+
* }
|
|
201
|
+
* ```
|
|
202
|
+
*/
|
|
203
|
+
const isRootNode = isKind("Root");
|
|
204
|
+
/**
|
|
205
|
+
* Returns `true` when the input is an `OperationNode`.
|
|
206
|
+
*
|
|
207
|
+
* @example
|
|
208
|
+
* ```ts
|
|
209
|
+
* if (isOperationNode(node)) {
|
|
210
|
+
* console.log(node.operationId)
|
|
211
|
+
* }
|
|
212
|
+
* ```
|
|
213
|
+
*/
|
|
214
|
+
const isOperationNode = isKind("Operation");
|
|
215
|
+
/**
|
|
216
|
+
* Returns `true` when the input is a `SchemaNode`.
|
|
217
|
+
*
|
|
218
|
+
* @example
|
|
219
|
+
* ```ts
|
|
220
|
+
* if (isSchemaNode(node)) {
|
|
221
|
+
* console.log(node.type)
|
|
222
|
+
* }
|
|
223
|
+
* ```
|
|
224
|
+
*/
|
|
225
|
+
const isSchemaNode = isKind("Schema");
|
|
226
|
+
/**
|
|
227
|
+
* Returns `true` when the input is a `PropertyNode`.
|
|
228
|
+
*/
|
|
229
|
+
const isPropertyNode = isKind("Property");
|
|
230
|
+
/**
|
|
231
|
+
* Returns `true` when the input is a `ParameterNode`.
|
|
232
|
+
*/
|
|
233
|
+
const isParameterNode = isKind("Parameter");
|
|
234
|
+
/**
|
|
235
|
+
* Returns `true` when the input is a `ResponseNode`.
|
|
236
|
+
*/
|
|
237
|
+
const isResponseNode = isKind("Response");
|
|
238
|
+
/**
|
|
239
|
+
* Returns `true` when the input is a `FunctionParameterNode`.
|
|
240
|
+
*/
|
|
241
|
+
const isFunctionParameterNode = isKind("FunctionParameter");
|
|
242
|
+
/**
|
|
243
|
+
* Returns `true` when the input is an `ObjectBindingParameterNode`.
|
|
244
|
+
*/
|
|
245
|
+
const isObjectBindingParameterNode = isKind("ObjectBindingParameter");
|
|
246
|
+
/**
|
|
247
|
+
* Returns `true` when the input is a `FunctionParametersNode`.
|
|
248
|
+
*/
|
|
249
|
+
const isFunctionParametersNode = isKind("FunctionParameters");
|
|
250
|
+
//#endregion
|
|
251
|
+
//#region src/utils.ts
|
|
252
|
+
const plainStringTypes = new Set([
|
|
253
|
+
"string",
|
|
254
|
+
"uuid",
|
|
255
|
+
"email",
|
|
256
|
+
"url",
|
|
257
|
+
"datetime"
|
|
258
|
+
]);
|
|
259
|
+
/**
|
|
260
|
+
* Returns `true` when a schema is emitted as a plain TypeScript `string`.
|
|
261
|
+
*
|
|
262
|
+
* - `string`, `uuid`, `email`, `url`, `datetime` are always plain strings.
|
|
263
|
+
* - `date` and `time` are plain strings when their `representation` is `'string'` rather than `'date'`.
|
|
264
|
+
*
|
|
265
|
+
* @example
|
|
266
|
+
* ```ts
|
|
267
|
+
* isStringType(createSchema({ type: 'uuid' })) // true
|
|
268
|
+
* isStringType(createSchema({ type: 'date', representation: 'date' })) // false
|
|
269
|
+
* ```
|
|
270
|
+
*/
|
|
271
|
+
function isStringType(node) {
|
|
272
|
+
if (plainStringTypes.has(node.type)) return true;
|
|
273
|
+
const temporal = narrowSchema(node, "date") ?? narrowSchema(node, "time");
|
|
274
|
+
if (temporal) return temporal.representation !== "date";
|
|
275
|
+
return false;
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Applies casing rules to parameter names and returns a new parameter array.
|
|
279
|
+
*
|
|
280
|
+
* The input array is not mutated.
|
|
281
|
+
* If `casing` is not set, the original array is returned unchanged.
|
|
282
|
+
*
|
|
283
|
+
* Use this before passing parameters to schema builders so that property keys
|
|
284
|
+
* in generated output match the desired casing while preserving
|
|
285
|
+
* `OperationNode.parameters` for other consumers.
|
|
286
|
+
*
|
|
287
|
+
* @example
|
|
288
|
+
* ```ts
|
|
289
|
+
* const params = [createParameter({ name: 'pet_id', in: 'query', schema: createSchema({ type: 'string' }) })]
|
|
290
|
+
* const cased = caseParams(params, 'camelcase')
|
|
291
|
+
* // cased[0].name === 'petId'
|
|
292
|
+
* ```
|
|
293
|
+
*/
|
|
294
|
+
function caseParams(params, casing) {
|
|
295
|
+
if (!casing) return params;
|
|
296
|
+
return params.map((param) => {
|
|
297
|
+
const transformed = casing === "camelcase" || !isValidVarName(param.name) ? camelCase(param.name) : param.name;
|
|
298
|
+
return {
|
|
299
|
+
...param,
|
|
300
|
+
name: transformed
|
|
301
|
+
};
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Syncs property/parameter schema optionality flags from `required` and `schema.nullable`.
|
|
306
|
+
*
|
|
307
|
+
* - `optional` is set for non-required, non-nullable schemas.
|
|
308
|
+
* - `nullish` is set for non-required, nullable schemas.
|
|
309
|
+
*/
|
|
310
|
+
function syncOptionality(required, schema) {
|
|
311
|
+
const nullable = schema.nullable ?? false;
|
|
312
|
+
return {
|
|
313
|
+
...schema,
|
|
314
|
+
optional: !required && !nullable ? true : void 0,
|
|
315
|
+
nullish: !required && nullable ? true : void 0
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
//#endregion
|
|
89
319
|
//#region src/factory.ts
|
|
90
320
|
/**
|
|
91
|
-
* Creates a `RootNode`.
|
|
321
|
+
* Creates a `RootNode` with stable defaults for `schemas` and `operations`.
|
|
322
|
+
*
|
|
323
|
+
* @example
|
|
324
|
+
* ```ts
|
|
325
|
+
* const root = createRoot()
|
|
326
|
+
* // { kind: 'Root', schemas: [], operations: [] }
|
|
327
|
+
* ```
|
|
328
|
+
*
|
|
329
|
+
* @example
|
|
330
|
+
* ```ts
|
|
331
|
+
* const root = createRoot({ schemas: [petSchema] })
|
|
332
|
+
* // keeps default operations: []
|
|
333
|
+
* ```
|
|
92
334
|
*/
|
|
93
335
|
function createRoot(overrides = {}) {
|
|
94
336
|
return {
|
|
@@ -99,7 +341,27 @@ function createRoot(overrides = {}) {
|
|
|
99
341
|
};
|
|
100
342
|
}
|
|
101
343
|
/**
|
|
102
|
-
* Creates an `OperationNode`.
|
|
344
|
+
* Creates an `OperationNode` with default empty arrays for `tags`, `parameters`, and `responses`.
|
|
345
|
+
*
|
|
346
|
+
* @example
|
|
347
|
+
* ```ts
|
|
348
|
+
* const operation = createOperation({
|
|
349
|
+
* operationId: 'getPetById',
|
|
350
|
+
* method: 'GET',
|
|
351
|
+
* path: '/pet/{petId}',
|
|
352
|
+
* })
|
|
353
|
+
* // tags, parameters, and responses are []
|
|
354
|
+
* ```
|
|
355
|
+
*
|
|
356
|
+
* @example
|
|
357
|
+
* ```ts
|
|
358
|
+
* const operation = createOperation({
|
|
359
|
+
* operationId: 'findPets',
|
|
360
|
+
* method: 'GET',
|
|
361
|
+
* path: '/pet/findByStatus',
|
|
362
|
+
* tags: ['pet'],
|
|
363
|
+
* })
|
|
364
|
+
* ```
|
|
103
365
|
*/
|
|
104
366
|
function createOperation(props) {
|
|
105
367
|
return {
|
|
@@ -122,20 +384,29 @@ function createSchema(props) {
|
|
|
122
384
|
};
|
|
123
385
|
}
|
|
124
386
|
/**
|
|
125
|
-
*
|
|
126
|
-
*
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
*
|
|
138
|
-
*
|
|
387
|
+
* Creates a `PropertyNode`.
|
|
388
|
+
*
|
|
389
|
+
* `required` defaults to `false`.
|
|
390
|
+
* `schema.optional` and `schema.nullish` are derived from `required` and `schema.nullable`.
|
|
391
|
+
*
|
|
392
|
+
* @example
|
|
393
|
+
* ```ts
|
|
394
|
+
* const property = createProperty({
|
|
395
|
+
* name: 'status',
|
|
396
|
+
* schema: createSchema({ type: 'string' }),
|
|
397
|
+
* })
|
|
398
|
+
* // required=false, schema.optional=true
|
|
399
|
+
* ```
|
|
400
|
+
*
|
|
401
|
+
* @example
|
|
402
|
+
* ```ts
|
|
403
|
+
* const property = createProperty({
|
|
404
|
+
* name: 'status',
|
|
405
|
+
* required: true,
|
|
406
|
+
* schema: createSchema({ type: 'string', nullable: true }),
|
|
407
|
+
* })
|
|
408
|
+
* // required=true, no optional/nullish
|
|
409
|
+
* ```
|
|
139
410
|
*/
|
|
140
411
|
function createProperty(props) {
|
|
141
412
|
const required = props.required ?? false;
|
|
@@ -143,12 +414,34 @@ function createProperty(props) {
|
|
|
143
414
|
...props,
|
|
144
415
|
kind: "Property",
|
|
145
416
|
required,
|
|
146
|
-
schema:
|
|
417
|
+
schema: syncOptionality(required, props.schema)
|
|
147
418
|
};
|
|
148
419
|
}
|
|
149
420
|
/**
|
|
150
|
-
* Creates a `ParameterNode`.
|
|
151
|
-
*
|
|
421
|
+
* Creates a `ParameterNode`.
|
|
422
|
+
*
|
|
423
|
+
* `required` defaults to `false`.
|
|
424
|
+
* Nested schema flags are set from `required` and `schema.nullable`.
|
|
425
|
+
*
|
|
426
|
+
* @example
|
|
427
|
+
* ```ts
|
|
428
|
+
* const param = createParameter({
|
|
429
|
+
* name: 'petId',
|
|
430
|
+
* in: 'path',
|
|
431
|
+
* required: true,
|
|
432
|
+
* schema: createSchema({ type: 'string' }),
|
|
433
|
+
* })
|
|
434
|
+
* ```
|
|
435
|
+
*
|
|
436
|
+
* @example
|
|
437
|
+
* ```ts
|
|
438
|
+
* const param = createParameter({
|
|
439
|
+
* name: 'status',
|
|
440
|
+
* in: 'query',
|
|
441
|
+
* schema: createSchema({ type: 'string', nullable: true }),
|
|
442
|
+
* })
|
|
443
|
+
* // required=false, schema.nullish=true
|
|
444
|
+
* ```
|
|
152
445
|
*/
|
|
153
446
|
function createParameter(props) {
|
|
154
447
|
const required = props.required ?? false;
|
|
@@ -156,11 +449,20 @@ function createParameter(props) {
|
|
|
156
449
|
...props,
|
|
157
450
|
kind: "Parameter",
|
|
158
451
|
required,
|
|
159
|
-
schema:
|
|
452
|
+
schema: syncOptionality(required, props.schema)
|
|
160
453
|
};
|
|
161
454
|
}
|
|
162
455
|
/**
|
|
163
456
|
* Creates a `ResponseNode`.
|
|
457
|
+
*
|
|
458
|
+
* @example
|
|
459
|
+
* ```ts
|
|
460
|
+
* const response = createResponse({
|
|
461
|
+
* statusCode: '200',
|
|
462
|
+
* description: 'Success',
|
|
463
|
+
* schema: createSchema({ type: 'object', properties: [] }),
|
|
464
|
+
* })
|
|
465
|
+
* ```
|
|
164
466
|
*/
|
|
165
467
|
function createResponse(props) {
|
|
166
468
|
return {
|
|
@@ -169,7 +471,33 @@ function createResponse(props) {
|
|
|
169
471
|
};
|
|
170
472
|
}
|
|
171
473
|
/**
|
|
172
|
-
* Creates a
|
|
474
|
+
* Creates a single-property object schema used as a discriminator literal.
|
|
475
|
+
*
|
|
476
|
+
* @example
|
|
477
|
+
* ```ts
|
|
478
|
+
* createDiscriminantNode({ propertyName: 'type', value: 'dog' })
|
|
479
|
+
* // -> { type: 'object', properties: [{ name: 'type', required: true, schema: enum('dog') }] }
|
|
480
|
+
* ```
|
|
481
|
+
*/
|
|
482
|
+
function createDiscriminantNode({ propertyName, value }) {
|
|
483
|
+
return createSchema({
|
|
484
|
+
type: "object",
|
|
485
|
+
primitive: "object",
|
|
486
|
+
properties: [createProperty({
|
|
487
|
+
name: propertyName,
|
|
488
|
+
schema: createSchema({
|
|
489
|
+
type: "enum",
|
|
490
|
+
primitive: "string",
|
|
491
|
+
enumValues: [value]
|
|
492
|
+
}),
|
|
493
|
+
required: true
|
|
494
|
+
})]
|
|
495
|
+
});
|
|
496
|
+
}
|
|
497
|
+
/**
|
|
498
|
+
* Creates a `FunctionParameterNode`.
|
|
499
|
+
*
|
|
500
|
+
* `optional` defaults to `false`.
|
|
173
501
|
*
|
|
174
502
|
* @example Required typed param
|
|
175
503
|
* ```ts
|
|
@@ -183,7 +511,7 @@ function createResponse(props) {
|
|
|
183
511
|
* // → params?: QueryParams
|
|
184
512
|
* ```
|
|
185
513
|
*
|
|
186
|
-
* @example Param with default (implicitly optional
|
|
514
|
+
* @example Param with default (implicitly optional; cannot combine with `optional: true`)
|
|
187
515
|
* ```ts
|
|
188
516
|
* createFunctionParameter({ name: 'config', type: 'RequestConfig', default: '{}' })
|
|
189
517
|
* // → config: RequestConfig = {}
|
|
@@ -197,7 +525,7 @@ function createFunctionParameter(props) {
|
|
|
197
525
|
};
|
|
198
526
|
}
|
|
199
527
|
/**
|
|
200
|
-
* Creates an `ObjectBindingParameterNode`
|
|
528
|
+
* Creates an `ObjectBindingParameterNode` for object-destructured parameter groups.
|
|
201
529
|
*
|
|
202
530
|
* @example Destructured object param
|
|
203
531
|
* ```ts
|
|
@@ -212,7 +540,7 @@ function createFunctionParameter(props) {
|
|
|
212
540
|
* // call → { id, name }
|
|
213
541
|
* ```
|
|
214
542
|
*
|
|
215
|
-
* @example Inline — children emitted as individual top-level
|
|
543
|
+
* @example Inline mode — children emitted as individual top-level parameters
|
|
216
544
|
* ```ts
|
|
217
545
|
* createObjectBindingParameter({
|
|
218
546
|
* properties: [createFunctionParameter({ name: 'petId', type: 'string', optional: false })],
|
|
@@ -229,7 +557,7 @@ function createObjectBindingParameter(props) {
|
|
|
229
557
|
};
|
|
230
558
|
}
|
|
231
559
|
/**
|
|
232
|
-
* Creates a `FunctionParametersNode` from an ordered list of
|
|
560
|
+
* Creates a `FunctionParametersNode` from an ordered list of parameters.
|
|
233
561
|
*
|
|
234
562
|
* @example
|
|
235
563
|
* ```ts
|
|
@@ -240,6 +568,12 @@ function createObjectBindingParameter(props) {
|
|
|
240
568
|
* ],
|
|
241
569
|
* })
|
|
242
570
|
* ```
|
|
571
|
+
*
|
|
572
|
+
* @example
|
|
573
|
+
* ```ts
|
|
574
|
+
* const empty = createFunctionParameters()
|
|
575
|
+
* // { kind: 'FunctionParameters', params: [] }
|
|
576
|
+
* ```
|
|
243
577
|
*/
|
|
244
578
|
function createFunctionParameters(props = {}) {
|
|
245
579
|
return {
|
|
@@ -249,18 +583,19 @@ function createFunctionParameters(props = {}) {
|
|
|
249
583
|
};
|
|
250
584
|
}
|
|
251
585
|
//#endregion
|
|
252
|
-
//#region src/printer.ts
|
|
586
|
+
//#region src/printers/printer.ts
|
|
253
587
|
/**
|
|
254
|
-
* Creates a
|
|
255
|
-
*
|
|
256
|
-
*
|
|
588
|
+
* Creates a schema printer factory.
|
|
589
|
+
*
|
|
590
|
+
* This function wraps a builder and makes options optional at call sites.
|
|
257
591
|
*
|
|
258
592
|
* The builder receives resolved options and returns:
|
|
259
593
|
* - `name` — a unique identifier for the printer
|
|
260
594
|
* - `options` — options stored on the returned printer instance
|
|
261
595
|
* - `nodes` — a map of `SchemaType` → handler functions that convert a `SchemaNode` to `TOutput`
|
|
262
|
-
* - `print` _(optional)_ —
|
|
263
|
-
* Inside
|
|
596
|
+
* - `print` _(optional)_ — top-level override exposed as `printer.print`
|
|
597
|
+
* - Inside this function, `this.print(node)` still dispatches to the `nodes` map
|
|
598
|
+
* - This keeps recursion safe and avoids self-calls
|
|
264
599
|
*
|
|
265
600
|
* When no `print` override is provided, `printer.print` is the node-level dispatcher directly.
|
|
266
601
|
*
|
|
@@ -280,32 +615,13 @@ function createFunctionParameters(props = {}) {
|
|
|
280
615
|
* },
|
|
281
616
|
* }))
|
|
282
617
|
* ```
|
|
283
|
-
*
|
|
284
|
-
* @example With a root-level `print` override to wrap output in a full declaration
|
|
285
|
-
* ```ts
|
|
286
|
-
* type TsPrinter = PrinterFactoryOptions<'ts', { typeName?: string }, ts.TypeNode, ts.Node>
|
|
287
|
-
*
|
|
288
|
-
* export const printerTs = definePrinter<TsPrinter>((options) => ({
|
|
289
|
-
* name: 'ts',
|
|
290
|
-
* options,
|
|
291
|
-
* nodes: { string: () => factory.keywordTypeNodes.string },
|
|
292
|
-
* print(node) {
|
|
293
|
-
* const type = this.print(node) // calls the node-level dispatcher
|
|
294
|
-
* if (!type || !this.options.typeName) return type
|
|
295
|
-
* return factory.createTypeAliasDeclaration(this.options.typeName, type)
|
|
296
|
-
* },
|
|
297
|
-
* }))
|
|
298
|
-
* ```
|
|
299
618
|
*/
|
|
300
619
|
function definePrinter(build) {
|
|
301
620
|
return createPrinterFactory((node) => node.type)(build);
|
|
302
621
|
}
|
|
303
622
|
/**
|
|
304
|
-
* Generic printer
|
|
305
|
-
|
|
306
|
-
*
|
|
307
|
-
* @param getKey — derives the handler-map key from a node. Return `undefined` to skip.
|
|
308
|
-
*
|
|
623
|
+
* Generic printer-factory function used by `definePrinter` and `defineFunctionPrinter`.
|
|
624
|
+
**
|
|
309
625
|
* @example
|
|
310
626
|
* ```ts
|
|
311
627
|
* export const defineFunctionPrinter = createPrinterFactory<FunctionNode, FunctionNodeType, FunctionNodeByType>(
|
|
@@ -321,9 +637,9 @@ function createPrinterFactory(getKey) {
|
|
|
321
637
|
options: resolvedOptions,
|
|
322
638
|
print: (node) => {
|
|
323
639
|
const key = getKey(node);
|
|
324
|
-
if (key === void 0) return
|
|
640
|
+
if (key === void 0) return null;
|
|
325
641
|
const handler = nodes[key];
|
|
326
|
-
if (!handler) return
|
|
642
|
+
if (!handler) return null;
|
|
327
643
|
return handler.call(context, node);
|
|
328
644
|
}
|
|
329
645
|
};
|
|
@@ -336,15 +652,17 @@ function createPrinterFactory(getKey) {
|
|
|
336
652
|
};
|
|
337
653
|
}
|
|
338
654
|
//#endregion
|
|
339
|
-
//#region src/functionPrinter.ts
|
|
655
|
+
//#region src/printers/functionPrinter.ts
|
|
340
656
|
const kindToHandlerKey = {
|
|
341
657
|
FunctionParameter: "functionParameter",
|
|
342
658
|
ObjectBindingParameter: "objectBindingParameter",
|
|
343
659
|
FunctionParameters: "functionParameters"
|
|
344
660
|
};
|
|
345
661
|
/**
|
|
346
|
-
* Creates a
|
|
347
|
-
*
|
|
662
|
+
* Creates a function-parameter printer factory.
|
|
663
|
+
*
|
|
664
|
+
* This wrapper uses `createPrinterFactory` and dispatches handlers by `node.kind`
|
|
665
|
+
* (for function nodes) rather than by `node.type` (for schema nodes).
|
|
348
666
|
*
|
|
349
667
|
* @example
|
|
350
668
|
* ```ts
|
|
@@ -385,12 +703,12 @@ function sortChildParams(params) {
|
|
|
385
703
|
return [...params].sort((a, b) => rank(a) - rank(b));
|
|
386
704
|
}
|
|
387
705
|
/**
|
|
388
|
-
* Default function-signature printer.
|
|
389
|
-
* used
|
|
706
|
+
* Default function-signature printer.
|
|
707
|
+
* Covers the four standard output modes used across Kubb plugins.
|
|
390
708
|
*
|
|
391
709
|
* @example
|
|
392
710
|
* ```ts
|
|
393
|
-
* const printer =
|
|
711
|
+
* const printer = functionPrinter({ mode: 'declaration' })
|
|
394
712
|
*
|
|
395
713
|
* const sig = createFunctionParameters({
|
|
396
714
|
* params: [
|
|
@@ -451,63 +769,30 @@ const functionPrinter = defineFunctionPrinter((options) => ({
|
|
|
451
769
|
}
|
|
452
770
|
}));
|
|
453
771
|
//#endregion
|
|
454
|
-
//#region src/
|
|
772
|
+
//#region src/refs.ts
|
|
455
773
|
/**
|
|
456
|
-
*
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
/**
|
|
465
|
-
* Type guard for `RootNode`.
|
|
466
|
-
*/
|
|
467
|
-
const isRootNode = isKind("Root");
|
|
468
|
-
/**
|
|
469
|
-
* Type guard for `OperationNode`.
|
|
470
|
-
*/
|
|
471
|
-
const isOperationNode = isKind("Operation");
|
|
472
|
-
/**
|
|
473
|
-
* Type guard for `SchemaNode`.
|
|
474
|
-
*/
|
|
475
|
-
const isSchemaNode = isKind("Schema");
|
|
476
|
-
/**
|
|
477
|
-
* Type guard for `PropertyNode`.
|
|
478
|
-
*/
|
|
479
|
-
const isPropertyNode = isKind("Property");
|
|
480
|
-
/**
|
|
481
|
-
* Type guard for `ParameterNode`.
|
|
482
|
-
*/
|
|
483
|
-
const isParameterNode = isKind("Parameter");
|
|
484
|
-
/**
|
|
485
|
-
* Type guard for `ResponseNode`.
|
|
486
|
-
*/
|
|
487
|
-
const isResponseNode = isKind("Response");
|
|
488
|
-
/**
|
|
489
|
-
* Type guard for `FunctionParameterNode`.
|
|
490
|
-
*/
|
|
491
|
-
const isFunctionParameterNode = isKind("FunctionParameter");
|
|
492
|
-
/**
|
|
493
|
-
* Type guard for `ObjectBindingParameterNode`.
|
|
494
|
-
*/
|
|
495
|
-
const isObjectBindingParameterNode = isKind("ObjectBindingParameter");
|
|
496
|
-
/**
|
|
497
|
-
* Type guard for `FunctionParametersNode`.
|
|
498
|
-
*/
|
|
499
|
-
const isFunctionParametersNode = isKind("FunctionParameters");
|
|
500
|
-
//#endregion
|
|
501
|
-
//#region src/refs.ts
|
|
502
|
-
/**
|
|
503
|
-
* Extracts the final segment from a reference string.
|
|
504
|
-
* Falls back to the original string when no slash exists.
|
|
774
|
+
* Returns the last path segment of a reference string.
|
|
775
|
+
*
|
|
776
|
+
* Example: `#/components/schemas/Pet` becomes `Pet`.
|
|
777
|
+
*
|
|
778
|
+
* @example
|
|
779
|
+
* ```ts
|
|
780
|
+
* extractRefName('#/components/schemas/Pet') // 'Pet'
|
|
781
|
+
* ```
|
|
505
782
|
*/
|
|
506
783
|
function extractRefName(ref) {
|
|
507
784
|
return ref.split("/").at(-1) ?? ref;
|
|
508
785
|
}
|
|
509
786
|
/**
|
|
510
|
-
*
|
|
787
|
+
* Builds a `RefMap` from `root.schemas` using each schema's `name`.
|
|
788
|
+
*
|
|
789
|
+
* Unnamed schemas are skipped.
|
|
790
|
+
*
|
|
791
|
+
* @example
|
|
792
|
+
* ```ts
|
|
793
|
+
* const refMap = buildRefMap(root)
|
|
794
|
+
* const pet = refMap.get('Pet')
|
|
795
|
+
* ```
|
|
511
796
|
*/
|
|
512
797
|
function buildRefMap(root) {
|
|
513
798
|
const map = /* @__PURE__ */ new Map();
|
|
@@ -515,389 +800,44 @@ function buildRefMap(root) {
|
|
|
515
800
|
return map;
|
|
516
801
|
}
|
|
517
802
|
/**
|
|
518
|
-
*
|
|
803
|
+
* Resolves a schema by name from a `RefMap`.
|
|
804
|
+
*
|
|
805
|
+
* @example
|
|
806
|
+
* ```ts
|
|
807
|
+
* const petSchema = resolveRef(refMap, 'Pet')
|
|
808
|
+
* ```
|
|
519
809
|
*/
|
|
520
810
|
function resolveRef(refMap, ref) {
|
|
521
811
|
return refMap.get(ref);
|
|
522
812
|
}
|
|
523
813
|
/**
|
|
524
|
-
* Converts a `RefMap`
|
|
814
|
+
* Converts a `RefMap` into a plain object.
|
|
815
|
+
*
|
|
816
|
+
* @example
|
|
817
|
+
* ```ts
|
|
818
|
+
* const refsObject = refMapToObject(refMap)
|
|
819
|
+
* ```
|
|
525
820
|
*/
|
|
526
821
|
function refMapToObject(refMap) {
|
|
527
822
|
return Object.fromEntries(refMap);
|
|
528
823
|
}
|
|
529
824
|
//#endregion
|
|
530
|
-
//#region src/
|
|
531
|
-
/**
|
|
532
|
-
* Replaces the discriminator property's schema inside an object node with
|
|
533
|
-
* an enum of the provided values.
|
|
534
|
-
*/
|
|
535
|
-
function applyDiscriminatorEnum({ node, propertyName, values, enumName }) {
|
|
536
|
-
const objectNode = narrowSchema(node, "object");
|
|
537
|
-
if (!objectNode?.properties?.length) return node;
|
|
538
|
-
if (!objectNode.properties.some((prop) => prop.name === propertyName)) return node;
|
|
539
|
-
return createSchema({
|
|
540
|
-
...objectNode,
|
|
541
|
-
properties: objectNode.properties.map((prop) => {
|
|
542
|
-
if (prop.name !== propertyName) return prop;
|
|
543
|
-
return createProperty({
|
|
544
|
-
...prop,
|
|
545
|
-
schema: createSchema({
|
|
546
|
-
type: "enum",
|
|
547
|
-
primitive: "string",
|
|
548
|
-
enumValues: values,
|
|
549
|
-
name: enumName,
|
|
550
|
-
readOnly: prop.schema.readOnly,
|
|
551
|
-
writeOnly: prop.schema.writeOnly
|
|
552
|
-
})
|
|
553
|
-
});
|
|
554
|
-
})
|
|
555
|
-
});
|
|
556
|
-
}
|
|
557
|
-
/**
|
|
558
|
-
* Merges adjacent anonymous object members into a single anonymous object.
|
|
559
|
-
*/
|
|
560
|
-
function mergeAdjacentAnonymousObjects(members) {
|
|
561
|
-
return members.reduce((acc, member) => {
|
|
562
|
-
const objectMember = narrowSchema(member, "object");
|
|
563
|
-
if (objectMember && !objectMember.name) {
|
|
564
|
-
const previous = acc.at(-1);
|
|
565
|
-
const previousObject = previous ? narrowSchema(previous, "object") : void 0;
|
|
566
|
-
if (previousObject && !previousObject.name) {
|
|
567
|
-
acc[acc.length - 1] = createSchema({
|
|
568
|
-
...previousObject,
|
|
569
|
-
properties: [...previousObject.properties ?? [], ...objectMember.properties ?? []]
|
|
570
|
-
});
|
|
571
|
-
return acc;
|
|
572
|
-
}
|
|
573
|
-
}
|
|
574
|
-
acc.push(member);
|
|
575
|
-
return acc;
|
|
576
|
-
}, []);
|
|
577
|
-
}
|
|
578
|
-
/**
|
|
579
|
-
* Removes enum members subsumed by broader scalar members in the same union.
|
|
580
|
-
*/
|
|
581
|
-
function simplifyUnionMembers(members) {
|
|
582
|
-
const scalarPrimitives = new Set(members.filter((member) => SCALAR_PRIMITIVE_TYPES.has(member.type)).map((m) => m.type));
|
|
583
|
-
if (!scalarPrimitives.size) return members;
|
|
584
|
-
return members.filter((member) => {
|
|
585
|
-
const enumNode = narrowSchema(member, "enum");
|
|
586
|
-
if (!enumNode) return true;
|
|
587
|
-
const primitive = enumNode.primitive;
|
|
588
|
-
if (!primitive) return true;
|
|
589
|
-
if (!enumNode.enumType) return true;
|
|
590
|
-
if (scalarPrimitives.has(primitive)) return false;
|
|
591
|
-
if ((primitive === "integer" || primitive === "number") && (scalarPrimitives.has("integer") || scalarPrimitives.has("number"))) return false;
|
|
592
|
-
return true;
|
|
593
|
-
});
|
|
594
|
-
}
|
|
595
|
-
//#endregion
|
|
596
|
-
//#region ../../internals/utils/dist/index.js
|
|
597
|
-
/**
|
|
598
|
-
* Shared implementation for camelCase and PascalCase conversion.
|
|
599
|
-
* Splits on common word boundaries (spaces, hyphens, underscores, dots, slashes, colons)
|
|
600
|
-
* and capitalizes each word according to `pascal`.
|
|
601
|
-
*
|
|
602
|
-
* When `pascal` is `true` the first word is also capitalized (PascalCase), otherwise only subsequent words are.
|
|
603
|
-
*/
|
|
604
|
-
function toCamelOrPascal(text, pascal) {
|
|
605
|
-
return text.trim().replace(/([a-z\d])([A-Z])/g, "$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2").replace(/(\d)([a-z])/g, "$1 $2").split(/[\s\-_./\\:]+/).filter(Boolean).map((word, i) => {
|
|
606
|
-
if (word.length > 1 && word === word.toUpperCase()) return word;
|
|
607
|
-
if (i === 0 && !pascal) return word.charAt(0).toLowerCase() + word.slice(1);
|
|
608
|
-
return word.charAt(0).toUpperCase() + word.slice(1);
|
|
609
|
-
}).join("").replace(/[^a-zA-Z0-9]/g, "");
|
|
610
|
-
}
|
|
825
|
+
//#region src/visitor.ts
|
|
611
826
|
/**
|
|
612
|
-
*
|
|
613
|
-
* The last segment receives `isLast = true`, all earlier segments receive `false`.
|
|
614
|
-
* Segments are joined with `/` to form a file path.
|
|
827
|
+
* Creates a small async concurrency limiter.
|
|
615
828
|
*
|
|
616
|
-
*
|
|
617
|
-
* embedded in operationIds (e.g. `v2025.0`) are kept intact.
|
|
618
|
-
*/
|
|
619
|
-
function applyToFileParts(text, transformPart) {
|
|
620
|
-
const parts = text.split(/\.(?=[a-zA-Z])/);
|
|
621
|
-
return parts.map((part, i) => transformPart(part, i === parts.length - 1)).join("/");
|
|
622
|
-
}
|
|
623
|
-
/**
|
|
624
|
-
* Converts `text` to camelCase.
|
|
625
|
-
* When `isFile` is `true`, dot-separated segments are each cased independently and joined with `/`.
|
|
829
|
+
* At most `concurrency` tasks are in flight at once. Extra tasks are queued.
|
|
626
830
|
*
|
|
627
831
|
* @example
|
|
628
|
-
*
|
|
629
|
-
*
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
}
|
|
638
|
-
/** Returns a `CLIAdapter` with type inference. Pass a different adapter to `createCLI` to swap the CLI engine. */
|
|
639
|
-
function defineCLIAdapter(adapter) {
|
|
640
|
-
return adapter;
|
|
641
|
-
}
|
|
642
|
-
/**
|
|
643
|
-
* Serializes `CommandDefinition[]` to a plain, JSON-serializable structure.
|
|
644
|
-
* Use to expose CLI capabilities to AI agents or MCP tools.
|
|
645
|
-
*/
|
|
646
|
-
function getCommandSchema(defs) {
|
|
647
|
-
return defs.map(serializeCommand);
|
|
648
|
-
}
|
|
649
|
-
function serializeCommand(def) {
|
|
650
|
-
return {
|
|
651
|
-
name: def.name,
|
|
652
|
-
description: def.description,
|
|
653
|
-
arguments: def.arguments,
|
|
654
|
-
options: serializeOptions(def.options ?? {}),
|
|
655
|
-
subCommands: def.subCommands ? def.subCommands.map(serializeCommand) : []
|
|
656
|
-
};
|
|
657
|
-
}
|
|
658
|
-
function serializeOptions(options) {
|
|
659
|
-
return Object.entries(options).map(([name, opt]) => {
|
|
660
|
-
return {
|
|
661
|
-
name,
|
|
662
|
-
flags: `${opt.short ? `-${opt.short}, ` : ""}--${name}${opt.type === "string" ? ` <${opt.hint ?? name}>` : ""}`,
|
|
663
|
-
type: opt.type,
|
|
664
|
-
description: opt.description,
|
|
665
|
-
...opt.default !== void 0 ? { default: opt.default } : {},
|
|
666
|
-
...opt.hint ? { hint: opt.hint } : {},
|
|
667
|
-
...opt.enum ? { enum: opt.enum } : {},
|
|
668
|
-
...opt.required ? { required: opt.required } : {}
|
|
669
|
-
};
|
|
670
|
-
});
|
|
671
|
-
}
|
|
672
|
-
/** Prints formatted help output for a command using its `CommandDefinition`. */
|
|
673
|
-
function renderHelp(def, parentName) {
|
|
674
|
-
const schema = getCommandSchema([def])[0];
|
|
675
|
-
const programName = parentName ? `${parentName} ${schema.name}` : schema.name;
|
|
676
|
-
const argsPart = schema.arguments?.length ? ` ${schema.arguments.join(" ")}` : "";
|
|
677
|
-
const subCmdPart = schema.subCommands.length ? " <command>" : "";
|
|
678
|
-
console.log(`\n${(0, node_util.styleText)("bold", "Usage:")} ${programName}${argsPart}${subCmdPart} [options]\n`);
|
|
679
|
-
if (schema.description) console.log(` ${schema.description}\n`);
|
|
680
|
-
if (schema.subCommands.length) {
|
|
681
|
-
console.log((0, node_util.styleText)("bold", "Commands:"));
|
|
682
|
-
for (const sub of schema.subCommands) console.log(` ${(0, node_util.styleText)("cyan", sub.name.padEnd(16))}${sub.description}`);
|
|
683
|
-
console.log();
|
|
684
|
-
}
|
|
685
|
-
const options = [...schema.options, {
|
|
686
|
-
name: "help",
|
|
687
|
-
flags: "-h, --help",
|
|
688
|
-
type: "boolean",
|
|
689
|
-
description: "Show help"
|
|
690
|
-
}];
|
|
691
|
-
console.log((0, node_util.styleText)("bold", "Options:"));
|
|
692
|
-
for (const opt of options) {
|
|
693
|
-
const flags = (0, node_util.styleText)("cyan", opt.flags.padEnd(30));
|
|
694
|
-
const defaultPart = opt.default !== void 0 ? (0, node_util.styleText)("dim", ` (default: ${opt.default})`) : "";
|
|
695
|
-
console.log(` ${flags}${opt.description}${defaultPart}`);
|
|
696
|
-
}
|
|
697
|
-
console.log();
|
|
698
|
-
}
|
|
699
|
-
function buildParseOptions(def) {
|
|
700
|
-
const result = { help: {
|
|
701
|
-
type: "boolean",
|
|
702
|
-
short: "h"
|
|
703
|
-
} };
|
|
704
|
-
for (const [name, opt] of Object.entries(def.options ?? {})) result[name] = {
|
|
705
|
-
type: opt.type,
|
|
706
|
-
...opt.short ? { short: opt.short } : {},
|
|
707
|
-
...opt.default !== void 0 ? { default: opt.default } : {}
|
|
708
|
-
};
|
|
709
|
-
return result;
|
|
710
|
-
}
|
|
711
|
-
async function runCommand(def, argv, parentName) {
|
|
712
|
-
const parseOptions = buildParseOptions(def);
|
|
713
|
-
let parsed;
|
|
714
|
-
try {
|
|
715
|
-
const result = (0, node_util.parseArgs)({
|
|
716
|
-
args: argv,
|
|
717
|
-
options: parseOptions,
|
|
718
|
-
allowPositionals: true,
|
|
719
|
-
strict: false
|
|
720
|
-
});
|
|
721
|
-
parsed = {
|
|
722
|
-
values: result.values,
|
|
723
|
-
positionals: result.positionals
|
|
724
|
-
};
|
|
725
|
-
} catch {
|
|
726
|
-
renderHelp(def, parentName);
|
|
727
|
-
process.exit(1);
|
|
728
|
-
}
|
|
729
|
-
if (parsed.values["help"]) {
|
|
730
|
-
renderHelp(def, parentName);
|
|
731
|
-
process.exit(0);
|
|
732
|
-
}
|
|
733
|
-
for (const [name, opt] of Object.entries(def.options ?? {})) if (opt.required && parsed.values[name] === void 0) {
|
|
734
|
-
console.error((0, node_util.styleText)("red", `Error: --${name} is required`));
|
|
735
|
-
renderHelp(def, parentName);
|
|
736
|
-
process.exit(1);
|
|
737
|
-
}
|
|
738
|
-
if (!def.run) {
|
|
739
|
-
renderHelp(def, parentName);
|
|
740
|
-
process.exit(0);
|
|
741
|
-
}
|
|
742
|
-
try {
|
|
743
|
-
await def.run(parsed);
|
|
744
|
-
} catch (err) {
|
|
745
|
-
console.error((0, node_util.styleText)("red", `Error: ${err instanceof Error ? err.message : String(err)}`));
|
|
746
|
-
renderHelp(def, parentName);
|
|
747
|
-
process.exit(1);
|
|
748
|
-
}
|
|
749
|
-
}
|
|
750
|
-
function printRootHelp(programName, version, defs) {
|
|
751
|
-
console.log(`\n${(0, node_util.styleText)("bold", "Usage:")} ${programName} <command> [options]\n`);
|
|
752
|
-
console.log(` Kubb generation — v${version}\n`);
|
|
753
|
-
console.log((0, node_util.styleText)("bold", "Commands:"));
|
|
754
|
-
for (const def of defs) console.log(` ${(0, node_util.styleText)("cyan", def.name.padEnd(16))}${def.description}`);
|
|
755
|
-
console.log();
|
|
756
|
-
console.log((0, node_util.styleText)("bold", "Options:"));
|
|
757
|
-
console.log(` ${(0, node_util.styleText)("cyan", "-v, --version".padEnd(30))}Show version number`);
|
|
758
|
-
console.log(` ${(0, node_util.styleText)("cyan", "-h, --help".padEnd(30))}Show help`);
|
|
759
|
-
console.log();
|
|
760
|
-
console.log(`Run ${(0, node_util.styleText)("cyan", `${programName} <command> --help`)} for command-specific help.\n`);
|
|
761
|
-
}
|
|
762
|
-
defineCLIAdapter({
|
|
763
|
-
renderHelp(def, parentName) {
|
|
764
|
-
renderHelp(def, parentName);
|
|
765
|
-
},
|
|
766
|
-
async run(defs, argv, opts) {
|
|
767
|
-
const { programName, defaultCommandName, version } = opts;
|
|
768
|
-
const args = argv.length >= 2 && argv[0]?.includes("node") ? argv.slice(2) : argv;
|
|
769
|
-
if (args[0] === "--version" || args[0] === "-v") {
|
|
770
|
-
console.log(version);
|
|
771
|
-
process.exit(0);
|
|
772
|
-
}
|
|
773
|
-
if (args[0] === "--help" || args[0] === "-h") {
|
|
774
|
-
printRootHelp(programName, version, defs);
|
|
775
|
-
process.exit(0);
|
|
776
|
-
}
|
|
777
|
-
if (args.length === 0) {
|
|
778
|
-
const defaultDef = defs.find((d) => d.name === defaultCommandName);
|
|
779
|
-
if (defaultDef?.run) await runCommand(defaultDef, [], programName);
|
|
780
|
-
else printRootHelp(programName, version, defs);
|
|
781
|
-
return;
|
|
782
|
-
}
|
|
783
|
-
const [first, ...rest] = args;
|
|
784
|
-
const isKnownSubcommand = defs.some((d) => d.name === first);
|
|
785
|
-
let def;
|
|
786
|
-
let commandArgv;
|
|
787
|
-
let parentName;
|
|
788
|
-
if (isKnownSubcommand) {
|
|
789
|
-
def = defs.find((d) => d.name === first);
|
|
790
|
-
commandArgv = rest;
|
|
791
|
-
parentName = programName;
|
|
792
|
-
} else {
|
|
793
|
-
def = defs.find((d) => d.name === defaultCommandName);
|
|
794
|
-
commandArgv = args;
|
|
795
|
-
parentName = programName;
|
|
796
|
-
}
|
|
797
|
-
if (!def) {
|
|
798
|
-
console.error(`Unknown command: ${first}`);
|
|
799
|
-
printRootHelp(programName, version, defs);
|
|
800
|
-
process.exit(1);
|
|
801
|
-
}
|
|
802
|
-
if (def.subCommands?.length) {
|
|
803
|
-
const [subName, ...subRest] = commandArgv;
|
|
804
|
-
const subDef = def.subCommands.find((s) => s.name === subName);
|
|
805
|
-
if (subName === "--help" || subName === "-h") {
|
|
806
|
-
renderHelp(def, parentName);
|
|
807
|
-
process.exit(0);
|
|
808
|
-
}
|
|
809
|
-
if (!subDef) {
|
|
810
|
-
renderHelp(def, parentName);
|
|
811
|
-
process.exit(subName ? 1 : 0);
|
|
812
|
-
}
|
|
813
|
-
await runCommand(subDef, subRest, `${parentName} ${def.name}`);
|
|
814
|
-
return;
|
|
815
|
-
}
|
|
816
|
-
await runCommand(def, commandArgv, parentName);
|
|
817
|
-
}
|
|
818
|
-
});
|
|
819
|
-
/**
|
|
820
|
-
* Parses a CSS hex color string (`#RGB`) into its RGB channels.
|
|
821
|
-
* Falls back to `255` for any channel that cannot be parsed.
|
|
822
|
-
*/
|
|
823
|
-
function parseHex(color) {
|
|
824
|
-
const int = Number.parseInt(color.replace("#", ""), 16);
|
|
825
|
-
return Number.isNaN(int) ? {
|
|
826
|
-
r: 255,
|
|
827
|
-
g: 255,
|
|
828
|
-
b: 255
|
|
829
|
-
} : {
|
|
830
|
-
r: int >> 16 & 255,
|
|
831
|
-
g: int >> 8 & 255,
|
|
832
|
-
b: int & 255
|
|
833
|
-
};
|
|
834
|
-
}
|
|
835
|
-
/**
|
|
836
|
-
* Returns a function that wraps a string in a 24-bit ANSI true-color escape sequence
|
|
837
|
-
* for the given hex color.
|
|
838
|
-
*/
|
|
839
|
-
function hex(color) {
|
|
840
|
-
const { r, g, b } = parseHex(color);
|
|
841
|
-
return (text) => `\x1b[38;2;${r};${g};${b}m${text}\x1b[0m`;
|
|
842
|
-
}
|
|
843
|
-
hex("#F55A17"), hex("#F5A217"), hex("#F58517"), hex("#B45309"), hex("#FFFFFF"), hex("#adadc6"), hex("#FDA4AF");
|
|
844
|
-
/**
|
|
845
|
-
* Returns `true` when `name` is a syntactically valid JavaScript variable name.
|
|
846
|
-
*/
|
|
847
|
-
function isValidVarName(name) {
|
|
848
|
-
try {
|
|
849
|
-
new Function(`var ${name}`);
|
|
850
|
-
} catch {
|
|
851
|
-
return false;
|
|
852
|
-
}
|
|
853
|
-
return true;
|
|
854
|
-
}
|
|
855
|
-
//#endregion
|
|
856
|
-
//#region src/utils.ts
|
|
857
|
-
const plainStringTypes = new Set([
|
|
858
|
-
"string",
|
|
859
|
-
"uuid",
|
|
860
|
-
"email",
|
|
861
|
-
"url",
|
|
862
|
-
"datetime"
|
|
863
|
-
]);
|
|
864
|
-
/**
|
|
865
|
-
* Returns `true` when a schema node will be represented as a plain string in generated code.
|
|
866
|
-
*
|
|
867
|
-
* - `string`, `uuid`, `email`, `url`, `datetime` are always plain strings.
|
|
868
|
-
* - `date` and `time` are plain strings when their `representation` is `'string'` rather than `'date'`.
|
|
869
|
-
*/
|
|
870
|
-
function isPlainStringType(node) {
|
|
871
|
-
if (plainStringTypes.has(node.type)) return true;
|
|
872
|
-
const temporal = narrowSchema(node, "date") ?? narrowSchema(node, "time");
|
|
873
|
-
if (temporal) return temporal.representation !== "date";
|
|
874
|
-
return false;
|
|
875
|
-
}
|
|
876
|
-
/**
|
|
877
|
-
* Transforms the `name` field of each parameter node according to the given casing strategy.
|
|
878
|
-
*
|
|
879
|
-
* The original `params` array is never mutated — a new array of cloned nodes is returned.
|
|
880
|
-
* When no `casing` is provided the original array is returned as-is.
|
|
881
|
-
*
|
|
882
|
-
* Use this before passing parameters to schema builders so that property keys
|
|
883
|
-
* in the generated output match the desired casing while the original
|
|
884
|
-
* `OperationNode.parameters` array remains untouched for other consumers.
|
|
885
|
-
*/
|
|
886
|
-
function applyParamsCasing(params, casing) {
|
|
887
|
-
if (!casing) return params;
|
|
888
|
-
return params.map((param) => {
|
|
889
|
-
const transformed = casing === "camelcase" || !isValidVarName(param.name) ? camelCase(param.name) : param.name;
|
|
890
|
-
return {
|
|
891
|
-
...param,
|
|
892
|
-
name: transformed
|
|
893
|
-
};
|
|
894
|
-
});
|
|
895
|
-
}
|
|
896
|
-
//#endregion
|
|
897
|
-
//#region src/visitor.ts
|
|
898
|
-
/**
|
|
899
|
-
* Creates a concurrency-limiting wrapper. At most `concurrency` promises may be
|
|
900
|
-
* in-flight simultaneously; additional calls are queued and dispatched as slots free.
|
|
832
|
+
* ```ts
|
|
833
|
+
* const limit = createLimit(2)
|
|
834
|
+
* await Promise.all([
|
|
835
|
+
* limit(() => taskA()),
|
|
836
|
+
* limit(() => taskB()),
|
|
837
|
+
* limit(() => taskC()),
|
|
838
|
+
* ])
|
|
839
|
+
* // only 2 tasks run at the same time
|
|
840
|
+
* ```
|
|
901
841
|
*/
|
|
902
842
|
function createLimit(concurrency) {
|
|
903
843
|
let active = 0;
|
|
@@ -923,8 +863,15 @@ function createLimit(concurrency) {
|
|
|
923
863
|
/**
|
|
924
864
|
* Returns the immediate traversable children of `node`.
|
|
925
865
|
*
|
|
926
|
-
* For `Schema` nodes, children (properties
|
|
927
|
-
*
|
|
866
|
+
* For `Schema` nodes, children (`properties`, `items`, `members`, and non-boolean
|
|
867
|
+
* `additionalProperties`) are only included
|
|
868
|
+
* when `recurse` is `true`; shallow mode skips them.
|
|
869
|
+
*
|
|
870
|
+
* @example
|
|
871
|
+
* ```ts
|
|
872
|
+
* const children = getChildren(operationNode, true)
|
|
873
|
+
* // returns parameters, requestBody schema (if present), and responses
|
|
874
|
+
* ```
|
|
928
875
|
*/
|
|
929
876
|
function getChildren(node, recurse) {
|
|
930
877
|
switch (node.kind) {
|
|
@@ -953,7 +900,23 @@ function getChildren(node, recurse) {
|
|
|
953
900
|
}
|
|
954
901
|
/**
|
|
955
902
|
* Depth-first traversal for side effects. Visitor return values are ignored.
|
|
956
|
-
* Sibling nodes at each level are visited concurrently up to `options.concurrency`
|
|
903
|
+
* Sibling nodes at each level are visited concurrently up to `options.concurrency`
|
|
904
|
+
* (default: `WALK_CONCURRENCY`).
|
|
905
|
+
*
|
|
906
|
+
* @example
|
|
907
|
+
* ```ts
|
|
908
|
+
* await walk(root, {
|
|
909
|
+
* operation(node) {
|
|
910
|
+
* console.log(node.operationId)
|
|
911
|
+
* },
|
|
912
|
+
* })
|
|
913
|
+
* ```
|
|
914
|
+
*
|
|
915
|
+
* @example
|
|
916
|
+
* ```ts
|
|
917
|
+
* // Visit only the current node
|
|
918
|
+
* await walk(root, { depth: 'shallow', root: () => {} })
|
|
919
|
+
* ```
|
|
957
920
|
*/
|
|
958
921
|
async function walk(node, options) {
|
|
959
922
|
return _walk(node, options, (options.depth ?? visitorDepths.deep) === visitorDepths.deep, createLimit(options.concurrency ?? 30), void 0);
|
|
@@ -1086,8 +1049,18 @@ function transform(node, options) {
|
|
|
1086
1049
|
}
|
|
1087
1050
|
}
|
|
1088
1051
|
/**
|
|
1089
|
-
*
|
|
1090
|
-
*
|
|
1052
|
+
* Composes multiple visitors into one visitor, applied left to right.
|
|
1053
|
+
*
|
|
1054
|
+
* For each node kind, output from one visitor is input to the next.
|
|
1055
|
+
* If a visitor returns `undefined`, the previous node value is kept.
|
|
1056
|
+
*
|
|
1057
|
+
* @example
|
|
1058
|
+
* ```ts
|
|
1059
|
+
* const visitor = composeTransformers(
|
|
1060
|
+
* { operation: (node) => ({ ...node, operationId: `a_${node.operationId}` }) },
|
|
1061
|
+
* { operation: (node) => ({ ...node, operationId: `b_${node.operationId}` }) },
|
|
1062
|
+
* )
|
|
1063
|
+
* ```
|
|
1091
1064
|
*/
|
|
1092
1065
|
function composeTransformers(...visitors) {
|
|
1093
1066
|
return {
|
|
@@ -1112,7 +1085,24 @@ function composeTransformers(...visitors) {
|
|
|
1112
1085
|
};
|
|
1113
1086
|
}
|
|
1114
1087
|
/**
|
|
1115
|
-
*
|
|
1088
|
+
* Runs a depth-first synchronous collection pass.
|
|
1089
|
+
*
|
|
1090
|
+
* Non-`undefined` values returned by visitor callbacks are appended to the result.
|
|
1091
|
+
*
|
|
1092
|
+
* @example
|
|
1093
|
+
* ```ts
|
|
1094
|
+
* const ids = collect(root, {
|
|
1095
|
+
* operation(node) {
|
|
1096
|
+
* return node.operationId
|
|
1097
|
+
* },
|
|
1098
|
+
* })
|
|
1099
|
+
* ```
|
|
1100
|
+
*
|
|
1101
|
+
* @example
|
|
1102
|
+
* ```ts
|
|
1103
|
+
* // Collect from only the current node
|
|
1104
|
+
* const values = collect(root, { depth: 'shallow', root: () => 'root' })
|
|
1105
|
+
* ```
|
|
1116
1106
|
*/
|
|
1117
1107
|
function collect(node, options) {
|
|
1118
1108
|
const { depth, parent, ...visitor } = options;
|
|
@@ -1150,12 +1140,173 @@ function collect(node, options) {
|
|
|
1150
1140
|
return results;
|
|
1151
1141
|
}
|
|
1152
1142
|
//#endregion
|
|
1143
|
+
//#region src/resolvers.ts
|
|
1144
|
+
function findDiscriminator(mapping, ref) {
|
|
1145
|
+
if (!mapping || !ref) return null;
|
|
1146
|
+
return Object.entries(mapping).find(([, value]) => value === ref)?.[0] ?? null;
|
|
1147
|
+
}
|
|
1148
|
+
function childName(parentName, propName) {
|
|
1149
|
+
return parentName ? pascalCase([parentName, propName].join(" ")) : null;
|
|
1150
|
+
}
|
|
1151
|
+
function enumPropName(parentName, propName, enumSuffix) {
|
|
1152
|
+
return pascalCase([
|
|
1153
|
+
parentName,
|
|
1154
|
+
propName,
|
|
1155
|
+
enumSuffix
|
|
1156
|
+
].filter(Boolean).join(" "));
|
|
1157
|
+
}
|
|
1158
|
+
/**
|
|
1159
|
+
* Collects import entries for all `ref` schema nodes in `node`.
|
|
1160
|
+
*/
|
|
1161
|
+
function collectImports({ node, nameMapping, resolve }) {
|
|
1162
|
+
return collect(node, { schema(schemaNode) {
|
|
1163
|
+
const schemaRef = narrowSchema(schemaNode, "ref");
|
|
1164
|
+
if (!schemaRef?.ref) return;
|
|
1165
|
+
const rawName = extractRefName(schemaRef.ref);
|
|
1166
|
+
const result = resolve(nameMapping.get(rawName) ?? rawName);
|
|
1167
|
+
if (!result) return;
|
|
1168
|
+
return result;
|
|
1169
|
+
} });
|
|
1170
|
+
}
|
|
1171
|
+
//#endregion
|
|
1172
|
+
//#region src/transformers.ts
|
|
1173
|
+
/**
|
|
1174
|
+
* Replaces a discriminator property's schema with a string enum of allowed values.
|
|
1175
|
+
*
|
|
1176
|
+
* If `node` is not an object schema, or if the property does not exist, the input
|
|
1177
|
+
* node is returned as-is.
|
|
1178
|
+
*
|
|
1179
|
+
* @example
|
|
1180
|
+
* ```ts
|
|
1181
|
+
* const schema = createSchema({
|
|
1182
|
+
* type: 'object',
|
|
1183
|
+
* properties: [createProperty({ name: 'type', required: true, schema: createSchema({ type: 'string' }) })],
|
|
1184
|
+
* })
|
|
1185
|
+
* const result = setDiscriminatorEnum({ node: schema, propertyName: 'type', values: ['dog', 'cat'] })
|
|
1186
|
+
* ```
|
|
1187
|
+
*/
|
|
1188
|
+
function setDiscriminatorEnum({ node, propertyName, values, enumName }) {
|
|
1189
|
+
const objectNode = narrowSchema(node, "object");
|
|
1190
|
+
if (!objectNode?.properties?.length) return node;
|
|
1191
|
+
if (!objectNode.properties.some((prop) => prop.name === propertyName)) return node;
|
|
1192
|
+
return createSchema({
|
|
1193
|
+
...objectNode,
|
|
1194
|
+
properties: objectNode.properties.map((prop) => {
|
|
1195
|
+
if (prop.name !== propertyName) return prop;
|
|
1196
|
+
return createProperty({
|
|
1197
|
+
...prop,
|
|
1198
|
+
schema: createSchema({
|
|
1199
|
+
type: "enum",
|
|
1200
|
+
primitive: "string",
|
|
1201
|
+
enumValues: values,
|
|
1202
|
+
name: enumName,
|
|
1203
|
+
readOnly: prop.schema.readOnly,
|
|
1204
|
+
writeOnly: prop.schema.writeOnly
|
|
1205
|
+
})
|
|
1206
|
+
});
|
|
1207
|
+
})
|
|
1208
|
+
});
|
|
1209
|
+
}
|
|
1210
|
+
/**
|
|
1211
|
+
* Merges adjacent anonymous object members into a single anonymous object member.
|
|
1212
|
+
*
|
|
1213
|
+
* @example
|
|
1214
|
+
* ```ts
|
|
1215
|
+
* const merged = mergeAdjacentObjects([
|
|
1216
|
+
* createSchema({ type: 'object', properties: [createProperty({ name: 'a', schema: createSchema({ type: 'string' }) })] }),
|
|
1217
|
+
* createSchema({ type: 'object', properties: [createProperty({ name: 'b', schema: createSchema({ type: 'number' }) })] }),
|
|
1218
|
+
* ])
|
|
1219
|
+
* ```
|
|
1220
|
+
*/
|
|
1221
|
+
function mergeAdjacentObjects(members) {
|
|
1222
|
+
return members.reduce((acc, member) => {
|
|
1223
|
+
const objectMember = narrowSchema(member, "object");
|
|
1224
|
+
if (objectMember && !objectMember.name) {
|
|
1225
|
+
const previous = acc.at(-1);
|
|
1226
|
+
const previousObject = previous ? narrowSchema(previous, "object") : void 0;
|
|
1227
|
+
if (previousObject && !previousObject.name) {
|
|
1228
|
+
acc[acc.length - 1] = createSchema({
|
|
1229
|
+
...previousObject,
|
|
1230
|
+
properties: [...previousObject.properties ?? [], ...objectMember.properties ?? []]
|
|
1231
|
+
});
|
|
1232
|
+
return acc;
|
|
1233
|
+
}
|
|
1234
|
+
}
|
|
1235
|
+
acc.push(member);
|
|
1236
|
+
return acc;
|
|
1237
|
+
}, []);
|
|
1238
|
+
}
|
|
1239
|
+
/**
|
|
1240
|
+
* Removes enum members that are covered by broader scalar primitives in the same union.
|
|
1241
|
+
*
|
|
1242
|
+
* @example
|
|
1243
|
+
* ```ts
|
|
1244
|
+
* const simplified = simplifyUnion([
|
|
1245
|
+
* createSchema({ type: 'enum', primitive: 'string', enumValues: ['active'] }),
|
|
1246
|
+
* createSchema({ type: 'string' }),
|
|
1247
|
+
* ])
|
|
1248
|
+
* // keeps only string member
|
|
1249
|
+
* ```
|
|
1250
|
+
*/
|
|
1251
|
+
function simplifyUnion(members) {
|
|
1252
|
+
const scalarPrimitives = new Set(members.filter((member) => SCALAR_PRIMITIVE_TYPES.has(member.type)).map((m) => m.type));
|
|
1253
|
+
if (!scalarPrimitives.size) return members;
|
|
1254
|
+
return members.filter((member) => {
|
|
1255
|
+
const enumNode = narrowSchema(member, "enum");
|
|
1256
|
+
if (!enumNode) return true;
|
|
1257
|
+
const primitive = enumNode.primitive;
|
|
1258
|
+
if (!primitive) return true;
|
|
1259
|
+
if ((enumNode.namedEnumValues?.length ?? enumNode.enumValues?.length ?? 0) <= 1) return true;
|
|
1260
|
+
if (scalarPrimitives.has(primitive)) return false;
|
|
1261
|
+
if ((primitive === "integer" || primitive === "number") && (scalarPrimitives.has("integer") || scalarPrimitives.has("number"))) return false;
|
|
1262
|
+
return true;
|
|
1263
|
+
});
|
|
1264
|
+
}
|
|
1265
|
+
function setEnumName(propNode, parentName, propName, enumSuffix) {
|
|
1266
|
+
const enumNode = narrowSchema(propNode, "enum");
|
|
1267
|
+
if (enumNode?.primitive === "boolean") return {
|
|
1268
|
+
...propNode,
|
|
1269
|
+
name: void 0
|
|
1270
|
+
};
|
|
1271
|
+
if (enumNode) return {
|
|
1272
|
+
...propNode,
|
|
1273
|
+
name: enumPropName(parentName, propName, enumSuffix)
|
|
1274
|
+
};
|
|
1275
|
+
return propNode;
|
|
1276
|
+
}
|
|
1277
|
+
/**
|
|
1278
|
+
* Walks a schema tree and resolves `ref`/`enum` names through callbacks.
|
|
1279
|
+
*/
|
|
1280
|
+
function resolveNames({ node, nameMapping, resolveName, resolveEnumName }) {
|
|
1281
|
+
return transform(node, { schema(schemaNode) {
|
|
1282
|
+
const schemaRef = narrowSchema(schemaNode, "ref");
|
|
1283
|
+
if (schemaRef && (schemaRef.ref || schemaRef.name)) {
|
|
1284
|
+
const rawRef = schemaRef.ref ?? schemaRef.name;
|
|
1285
|
+
const resolved = resolveName(nameMapping.get(rawRef) ?? rawRef);
|
|
1286
|
+
if (resolved) return {
|
|
1287
|
+
...schemaNode,
|
|
1288
|
+
name: resolved
|
|
1289
|
+
};
|
|
1290
|
+
}
|
|
1291
|
+
const schemaEnum = narrowSchema(schemaNode, "enum");
|
|
1292
|
+
if (schemaEnum?.name) {
|
|
1293
|
+
const resolved = (resolveEnumName ?? resolveName)(schemaEnum.name);
|
|
1294
|
+
if (resolved) return {
|
|
1295
|
+
...schemaNode,
|
|
1296
|
+
name: resolved
|
|
1297
|
+
};
|
|
1298
|
+
}
|
|
1299
|
+
} });
|
|
1300
|
+
}
|
|
1301
|
+
//#endregion
|
|
1153
1302
|
exports.SCALAR_PRIMITIVE_TYPES = SCALAR_PRIMITIVE_TYPES;
|
|
1154
|
-
exports.applyDiscriminatorEnum = applyDiscriminatorEnum;
|
|
1155
|
-
exports.applyParamsCasing = applyParamsCasing;
|
|
1156
1303
|
exports.buildRefMap = buildRefMap;
|
|
1304
|
+
exports.caseParams = caseParams;
|
|
1305
|
+
exports.childName = childName;
|
|
1157
1306
|
exports.collect = collect;
|
|
1307
|
+
exports.collectImports = collectImports;
|
|
1158
1308
|
exports.composeTransformers = composeTransformers;
|
|
1309
|
+
exports.createDiscriminantNode = createDiscriminantNode;
|
|
1159
1310
|
exports.createFunctionParameter = createFunctionParameter;
|
|
1160
1311
|
exports.createFunctionParameters = createFunctionParameters;
|
|
1161
1312
|
exports.createObjectBindingParameter = createObjectBindingParameter;
|
|
@@ -1165,8 +1316,11 @@ exports.createProperty = createProperty;
|
|
|
1165
1316
|
exports.createResponse = createResponse;
|
|
1166
1317
|
exports.createRoot = createRoot;
|
|
1167
1318
|
exports.createSchema = createSchema;
|
|
1319
|
+
exports.defineFunctionPrinter = defineFunctionPrinter;
|
|
1168
1320
|
exports.definePrinter = definePrinter;
|
|
1321
|
+
exports.enumPropName = enumPropName;
|
|
1169
1322
|
exports.extractRefName = extractRefName;
|
|
1323
|
+
exports.findDiscriminator = findDiscriminator;
|
|
1170
1324
|
exports.functionPrinter = functionPrinter;
|
|
1171
1325
|
exports.httpMethods = httpMethods;
|
|
1172
1326
|
exports.isFunctionParameterNode = isFunctionParameterNode;
|
|
@@ -1174,20 +1328,23 @@ exports.isFunctionParametersNode = isFunctionParametersNode;
|
|
|
1174
1328
|
exports.isObjectBindingParameterNode = isObjectBindingParameterNode;
|
|
1175
1329
|
exports.isOperationNode = isOperationNode;
|
|
1176
1330
|
exports.isParameterNode = isParameterNode;
|
|
1177
|
-
exports.isPlainStringType = isPlainStringType;
|
|
1178
1331
|
exports.isPropertyNode = isPropertyNode;
|
|
1179
1332
|
exports.isResponseNode = isResponseNode;
|
|
1180
1333
|
exports.isRootNode = isRootNode;
|
|
1181
1334
|
exports.isSchemaNode = isSchemaNode;
|
|
1335
|
+
exports.isStringType = isStringType;
|
|
1182
1336
|
exports.mediaTypes = mediaTypes;
|
|
1183
|
-
exports.
|
|
1337
|
+
exports.mergeAdjacentObjects = mergeAdjacentObjects;
|
|
1184
1338
|
exports.narrowSchema = narrowSchema;
|
|
1185
1339
|
exports.nodeKinds = nodeKinds;
|
|
1186
1340
|
exports.refMapToObject = refMapToObject;
|
|
1341
|
+
exports.resolveNames = resolveNames;
|
|
1187
1342
|
exports.resolveRef = resolveRef;
|
|
1188
1343
|
exports.schemaTypes = schemaTypes;
|
|
1189
|
-
exports.
|
|
1190
|
-
exports.
|
|
1344
|
+
exports.setDiscriminatorEnum = setDiscriminatorEnum;
|
|
1345
|
+
exports.setEnumName = setEnumName;
|
|
1346
|
+
exports.simplifyUnion = simplifyUnion;
|
|
1347
|
+
exports.syncOptionality = syncOptionality;
|
|
1191
1348
|
exports.transform = transform;
|
|
1192
1349
|
exports.walk = walk;
|
|
1193
1350
|
|