@kubb/plugin-ts 5.0.0-alpha.5 → 5.0.0-alpha.7
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/{components-Cwn1rflQ.js → components-CRu8IKY3.js} +4 -6
- package/dist/{components-Cwn1rflQ.js.map → components-CRu8IKY3.js.map} +1 -1
- package/dist/{components-CxTvawXI.cjs → components-DeNDKlzf.cjs} +4 -6
- package/dist/components-DeNDKlzf.cjs.map +1 -0
- package/dist/components.cjs +1 -1
- package/dist/components.d.ts +1 -3
- package/dist/components.js +1 -1
- package/dist/generators.cjs +1 -1
- package/dist/generators.d.ts +4 -4
- package/dist/generators.js +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/{plugin-meWNDVe7.cjs → plugin-Cn85VLXR.cjs} +329 -248
- package/dist/plugin-Cn85VLXR.cjs.map +1 -0
- package/dist/{plugin-kdQ5D2cW.js → plugin-DVhVzwDg.js} +327 -245
- package/dist/plugin-DVhVzwDg.js.map +1 -0
- package/dist/{types-eWhVEVgF.d.ts → types-CsvB6X5Y.d.ts} +1 -14
- package/package.json +5 -5
- package/src/components/Type.tsx +0 -3
- package/src/components/v2/Enum.tsx +67 -0
- package/src/components/v2/Type.tsx +11 -130
- package/src/constants.ts +29 -0
- package/src/generators/typeGenerator.tsx +30 -32
- package/src/generators/v2/typeGenerator.tsx +22 -14
- package/src/generators/v2/utils.ts +10 -15
- package/src/parser.ts +1 -8
- package/src/plugin.ts +5 -7
- package/src/printer.ts +229 -119
- package/src/types.ts +0 -13
- package/dist/components-CxTvawXI.cjs.map +0 -1
- package/dist/plugin-kdQ5D2cW.js.map +0 -1
- package/dist/plugin-meWNDVe7.cjs.map +0 -1
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import "./chunk--u3MIqq1.js";
|
|
2
|
-
import { A as keywordTypeNodes, C as createTypeDeclaration, D as createUnionDeclaration, E as createTypeReferenceNode, F as camelCase, I as pascalCase, M as syntaxKind, N as jsStringEscape, O as createUrlTemplateType, P as trimQuotes, S as createTypeAliasDeclaration, T as createTypeOperatorNode, _ as createPropertySignature, a as createArrayTypeNode, b as createTrue, c as createIdentifier, d as createIntersectionDeclaration, f as createLiteralTypeNode, g as createPrefixUnaryExpression, h as createOptionalTypeNode, i as createArrayDeclaration, j as modifiers, k as getUnknownType, l as createIndexSignature, m as createOmitDeclaration, n as SyntaxKind, o as createEnumDeclaration, p as createNumericLiteral, r as appendJSDocToNode, s as createFalse, t as Type$1, u as createIndexedAccessTypeNode, v as createRestTypeNode, w as createTypeLiteralNode, x as createTupleTypeNode, y as createStringLiteral } from "./components-
|
|
2
|
+
import { A as keywordTypeNodes, C as createTypeDeclaration, D as createUnionDeclaration, E as createTypeReferenceNode, F as camelCase, I as pascalCase, M as syntaxKind, N as jsStringEscape, O as createUrlTemplateType, P as trimQuotes, S as createTypeAliasDeclaration, T as createTypeOperatorNode, _ as createPropertySignature, a as createArrayTypeNode, b as createTrue, c as createIdentifier, d as createIntersectionDeclaration, f as createLiteralTypeNode, g as createPrefixUnaryExpression, h as createOptionalTypeNode, i as createArrayDeclaration, j as modifiers, k as getUnknownType, l as createIndexSignature, m as createOmitDeclaration, n as SyntaxKind, o as createEnumDeclaration, p as createNumericLiteral, r as appendJSDocToNode, s as createFalse, t as Type$1, u as createIndexedAccessTypeNode, v as createRestTypeNode, w as createTypeLiteralNode, x as createTupleTypeNode, y as createStringLiteral } from "./components-CRu8IKY3.js";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { applyParamsCasing, collect, createProperty, createSchema, isPlainStringType, walk } from "@kubb/ast";
|
|
5
5
|
import { defineGenerator, definePlugin, definePrinter, getBarrelFiles, getMode, resolveOptions } from "@kubb/core";
|
|
6
6
|
import { OperationGenerator, SchemaGenerator, buildOperation, buildSchema, isKeyword, pluginOasName, schemaKeywords } from "@kubb/plugin-oas";
|
|
7
|
-
import { useKubb, useMode,
|
|
7
|
+
import { useKubb, useMode, usePluginDriver } from "@kubb/core/hooks";
|
|
8
8
|
import { safePrint } from "@kubb/fabric-core/parsers/typescript";
|
|
9
9
|
import { createReactGenerator } from "@kubb/plugin-oas/generators";
|
|
10
10
|
import { useOas, useOperationManager, useSchemaManager } from "@kubb/plugin-oas/hooks";
|
|
@@ -26,37 +26,37 @@ function stringify(value) {
|
|
|
26
26
|
}
|
|
27
27
|
//#endregion
|
|
28
28
|
//#region src/generators/typeGenerator.tsx
|
|
29
|
-
function printCombinedSchema({ name, schemas,
|
|
29
|
+
function printCombinedSchema({ name, schemas, driver }) {
|
|
30
30
|
const properties = {};
|
|
31
31
|
if (schemas.response) properties["response"] = createUnionDeclaration({ nodes: schemas.responses.map((res) => {
|
|
32
|
-
return createTypeReferenceNode(createIdentifier(
|
|
32
|
+
return createTypeReferenceNode(createIdentifier(driver.resolveName({
|
|
33
33
|
name: res.name,
|
|
34
34
|
pluginName: pluginTsName,
|
|
35
35
|
type: "function"
|
|
36
36
|
})), void 0);
|
|
37
37
|
}) });
|
|
38
|
-
if (schemas.request) properties["request"] = createTypeReferenceNode(createIdentifier(
|
|
38
|
+
if (schemas.request) properties["request"] = createTypeReferenceNode(createIdentifier(driver.resolveName({
|
|
39
39
|
name: schemas.request.name,
|
|
40
40
|
pluginName: pluginTsName,
|
|
41
41
|
type: "function"
|
|
42
42
|
})), void 0);
|
|
43
|
-
if (schemas.pathParams) properties["pathParams"] = createTypeReferenceNode(createIdentifier(
|
|
43
|
+
if (schemas.pathParams) properties["pathParams"] = createTypeReferenceNode(createIdentifier(driver.resolveName({
|
|
44
44
|
name: schemas.pathParams.name,
|
|
45
45
|
pluginName: pluginTsName,
|
|
46
46
|
type: "function"
|
|
47
47
|
})), void 0);
|
|
48
|
-
if (schemas.queryParams) properties["queryParams"] = createTypeReferenceNode(createIdentifier(
|
|
48
|
+
if (schemas.queryParams) properties["queryParams"] = createTypeReferenceNode(createIdentifier(driver.resolveName({
|
|
49
49
|
name: schemas.queryParams.name,
|
|
50
50
|
pluginName: pluginTsName,
|
|
51
51
|
type: "function"
|
|
52
52
|
})), void 0);
|
|
53
|
-
if (schemas.headerParams) properties["headerParams"] = createTypeReferenceNode(createIdentifier(
|
|
53
|
+
if (schemas.headerParams) properties["headerParams"] = createTypeReferenceNode(createIdentifier(driver.resolveName({
|
|
54
54
|
name: schemas.headerParams.name,
|
|
55
55
|
pluginName: pluginTsName,
|
|
56
56
|
type: "function"
|
|
57
57
|
})), void 0);
|
|
58
58
|
if (schemas.errors) properties["errors"] = createUnionDeclaration({ nodes: schemas.errors.map((error) => {
|
|
59
|
-
return createTypeReferenceNode(createIdentifier(
|
|
59
|
+
return createTypeReferenceNode(createIdentifier(driver.resolveName({
|
|
60
60
|
name: error.name,
|
|
61
61
|
pluginName: pluginTsName,
|
|
62
62
|
type: "function"
|
|
@@ -75,8 +75,8 @@ function printCombinedSchema({ name, schemas, pluginManager }) {
|
|
|
75
75
|
modifiers: [modifiers.export]
|
|
76
76
|
}));
|
|
77
77
|
}
|
|
78
|
-
function printRequestSchema({ baseName, operation, schemas,
|
|
79
|
-
const name =
|
|
78
|
+
function printRequestSchema({ baseName, operation, schemas, driver }) {
|
|
79
|
+
const name = driver.resolveName({
|
|
80
80
|
name: `${baseName} Request`,
|
|
81
81
|
pluginName: pluginTsName,
|
|
82
82
|
type: "type"
|
|
@@ -84,7 +84,7 @@ function printRequestSchema({ baseName, operation, schemas, pluginManager }) {
|
|
|
84
84
|
const results = [];
|
|
85
85
|
const dataRequestProperties = [];
|
|
86
86
|
if (schemas.request) {
|
|
87
|
-
const identifier =
|
|
87
|
+
const identifier = driver.resolveName({
|
|
88
88
|
name: schemas.request.name,
|
|
89
89
|
pluginName: pluginTsName,
|
|
90
90
|
type: "type"
|
|
@@ -100,7 +100,7 @@ function printRequestSchema({ baseName, operation, schemas, pluginManager }) {
|
|
|
100
100
|
type: keywordTypeNodes.never
|
|
101
101
|
}));
|
|
102
102
|
if (schemas.pathParams) {
|
|
103
|
-
const identifier =
|
|
103
|
+
const identifier = driver.resolveName({
|
|
104
104
|
name: schemas.pathParams.name,
|
|
105
105
|
pluginName: pluginTsName,
|
|
106
106
|
type: "type"
|
|
@@ -115,7 +115,7 @@ function printRequestSchema({ baseName, operation, schemas, pluginManager }) {
|
|
|
115
115
|
type: keywordTypeNodes.never
|
|
116
116
|
}));
|
|
117
117
|
if (schemas.queryParams) {
|
|
118
|
-
const identifier =
|
|
118
|
+
const identifier = driver.resolveName({
|
|
119
119
|
name: schemas.queryParams.name,
|
|
120
120
|
pluginName: pluginTsName,
|
|
121
121
|
type: "type"
|
|
@@ -131,7 +131,7 @@ function printRequestSchema({ baseName, operation, schemas, pluginManager }) {
|
|
|
131
131
|
type: keywordTypeNodes.never
|
|
132
132
|
}));
|
|
133
133
|
if (schemas.headerParams) {
|
|
134
|
-
const identifier =
|
|
134
|
+
const identifier = driver.resolveName({
|
|
135
135
|
name: schemas.headerParams.name,
|
|
136
136
|
pluginName: pluginTsName,
|
|
137
137
|
type: "type"
|
|
@@ -158,16 +158,16 @@ function printRequestSchema({ baseName, operation, schemas, pluginManager }) {
|
|
|
158
158
|
results.push(safePrint(dataRequestNode));
|
|
159
159
|
return results.join("\n\n");
|
|
160
160
|
}
|
|
161
|
-
function printResponseSchema({ baseName, schemas,
|
|
161
|
+
function printResponseSchema({ baseName, schemas, driver, unknownType }) {
|
|
162
162
|
const results = [];
|
|
163
|
-
const name =
|
|
163
|
+
const name = driver.resolveName({
|
|
164
164
|
name: `${baseName} ResponseData`,
|
|
165
165
|
pluginName: pluginTsName,
|
|
166
166
|
type: "type"
|
|
167
167
|
});
|
|
168
168
|
if (schemas.responses && schemas.responses.length > 0) {
|
|
169
169
|
const responsesProperties = schemas.responses.map((res) => {
|
|
170
|
-
const identifier =
|
|
170
|
+
const identifier = driver.resolveName({
|
|
171
171
|
name: res.name,
|
|
172
172
|
pluginName: pluginTsName,
|
|
173
173
|
type: "type"
|
|
@@ -202,9 +202,9 @@ function printResponseSchema({ baseName, schemas, pluginManager, unknownType })
|
|
|
202
202
|
const typeGenerator$1 = createReactGenerator({
|
|
203
203
|
name: "typescript",
|
|
204
204
|
Operation({ operation, generator, plugin }) {
|
|
205
|
-
const { options, options: {
|
|
205
|
+
const { options, options: { enumType, enumKeyCasing, syntaxType, optionalType, arrayType, unknownType, paramsCasing } } = plugin;
|
|
206
206
|
const mode = useMode();
|
|
207
|
-
const
|
|
207
|
+
const driver = usePluginDriver();
|
|
208
208
|
const oas = useOas();
|
|
209
209
|
const { getSchemas, getFile, getName, getGroup } = useOperationManager(generator);
|
|
210
210
|
const schemaManager = useSchemaManager();
|
|
@@ -219,7 +219,7 @@ const typeGenerator$1 = createReactGenerator({
|
|
|
219
219
|
oas,
|
|
220
220
|
events: generator.context.events,
|
|
221
221
|
plugin,
|
|
222
|
-
|
|
222
|
+
driver,
|
|
223
223
|
mode,
|
|
224
224
|
override: options.override
|
|
225
225
|
});
|
|
@@ -261,7 +261,6 @@ const typeGenerator$1 = createReactGenerator({
|
|
|
261
261
|
description,
|
|
262
262
|
tree,
|
|
263
263
|
schema: transformedSchema,
|
|
264
|
-
mapper,
|
|
265
264
|
enumType,
|
|
266
265
|
enumKeyCasing,
|
|
267
266
|
optionalType,
|
|
@@ -279,7 +278,7 @@ const typeGenerator$1 = createReactGenerator({
|
|
|
279
278
|
banner: getBanner({
|
|
280
279
|
oas,
|
|
281
280
|
output: plugin.options.output,
|
|
282
|
-
config:
|
|
281
|
+
config: driver.config
|
|
283
282
|
}),
|
|
284
283
|
footer: getFooter({
|
|
285
284
|
oas,
|
|
@@ -294,7 +293,7 @@ const typeGenerator$1 = createReactGenerator({
|
|
|
294
293
|
baseName: name,
|
|
295
294
|
operation,
|
|
296
295
|
schemas,
|
|
297
|
-
|
|
296
|
+
driver
|
|
298
297
|
})
|
|
299
298
|
}), /* @__PURE__ */ jsx(File.Source, {
|
|
300
299
|
name: responseName,
|
|
@@ -304,7 +303,7 @@ const typeGenerator$1 = createReactGenerator({
|
|
|
304
303
|
children: printResponseSchema({
|
|
305
304
|
baseName: name,
|
|
306
305
|
schemas,
|
|
307
|
-
|
|
306
|
+
driver,
|
|
308
307
|
unknownType
|
|
309
308
|
})
|
|
310
309
|
})] }) : /* @__PURE__ */ jsx(File.Source, {
|
|
@@ -315,16 +314,16 @@ const typeGenerator$1 = createReactGenerator({
|
|
|
315
314
|
children: printCombinedSchema({
|
|
316
315
|
name: combinedSchemaName,
|
|
317
316
|
schemas,
|
|
318
|
-
|
|
317
|
+
driver
|
|
319
318
|
})
|
|
320
319
|
})]
|
|
321
320
|
});
|
|
322
321
|
},
|
|
323
322
|
Schema({ schema, plugin }) {
|
|
324
|
-
const { options: {
|
|
323
|
+
const { options: { enumType, enumKeyCasing, syntaxType, optionalType, arrayType, output } } = plugin;
|
|
325
324
|
const mode = useMode();
|
|
326
325
|
const oas = useOas();
|
|
327
|
-
const
|
|
326
|
+
const driver = usePluginDriver();
|
|
328
327
|
const { getName, getFile } = useSchemaManager();
|
|
329
328
|
const imports = getImports(schema.tree);
|
|
330
329
|
const schemaFromTree = schema.tree.find((item) => item.keyword === schemaKeywords.schema);
|
|
@@ -342,7 +341,7 @@ const typeGenerator$1 = createReactGenerator({
|
|
|
342
341
|
banner: getBanner({
|
|
343
342
|
oas,
|
|
344
343
|
output,
|
|
345
|
-
config:
|
|
344
|
+
config: driver.config
|
|
346
345
|
}),
|
|
347
346
|
footer: getFooter({
|
|
348
347
|
oas,
|
|
@@ -363,7 +362,6 @@ const typeGenerator$1 = createReactGenerator({
|
|
|
363
362
|
description: schema.value.description,
|
|
364
363
|
tree: schema.tree,
|
|
365
364
|
schema: schema.value,
|
|
366
|
-
mapper,
|
|
367
365
|
enumType,
|
|
368
366
|
enumKeyCasing,
|
|
369
367
|
optionalType,
|
|
@@ -374,7 +372,45 @@ const typeGenerator$1 = createReactGenerator({
|
|
|
374
372
|
}
|
|
375
373
|
});
|
|
376
374
|
//#endregion
|
|
375
|
+
//#region src/constants.ts
|
|
376
|
+
/**
|
|
377
|
+
* `optionalType` values that cause a property's type to include `| undefined`.
|
|
378
|
+
*/
|
|
379
|
+
const OPTIONAL_ADDS_UNDEFINED = new Set(["undefined", "questionTokenAndUndefined"]);
|
|
380
|
+
/**
|
|
381
|
+
* `optionalType` values that render the property key with a `?` token.
|
|
382
|
+
*/
|
|
383
|
+
const OPTIONAL_ADDS_QUESTION_TOKEN = new Set(["questionToken", "questionTokenAndUndefined"]);
|
|
384
|
+
/**
|
|
385
|
+
* `enumType` values that append a `Key` suffix to the generated enum type alias.
|
|
386
|
+
*/
|
|
387
|
+
const ENUM_TYPES_WITH_KEY_SUFFIX = new Set(["asConst", "asPascalConst"]);
|
|
388
|
+
/**
|
|
389
|
+
* `enumType` values that require a runtime value declaration (object, enum, or literal).
|
|
390
|
+
*/
|
|
391
|
+
const ENUM_TYPES_WITH_RUNTIME_VALUE = new Set([
|
|
392
|
+
"enum",
|
|
393
|
+
"asConst",
|
|
394
|
+
"asPascalConst",
|
|
395
|
+
"constEnum",
|
|
396
|
+
"literal",
|
|
397
|
+
void 0
|
|
398
|
+
]);
|
|
399
|
+
/**
|
|
400
|
+
* `enumType` values whose type declaration is type-only (no runtime value emitted for the type alias).
|
|
401
|
+
*/
|
|
402
|
+
const ENUM_TYPES_WITH_TYPE_ONLY = new Set([
|
|
403
|
+
"asConst",
|
|
404
|
+
"asPascalConst",
|
|
405
|
+
"literal",
|
|
406
|
+
void 0
|
|
407
|
+
]);
|
|
408
|
+
//#endregion
|
|
377
409
|
//#region src/printer.ts
|
|
410
|
+
/**
|
|
411
|
+
* Converts a primitive const value to a TypeScript literal type node.
|
|
412
|
+
* Handles negative numbers via a prefix unary expression.
|
|
413
|
+
*/
|
|
378
414
|
function constToTypeNode(value, format) {
|
|
379
415
|
if (format === "boolean") return createLiteralTypeNode(value === true ? createTrue() : createFalse());
|
|
380
416
|
if (format === "number" && typeof value === "number") {
|
|
@@ -383,12 +419,22 @@ function constToTypeNode(value, format) {
|
|
|
383
419
|
}
|
|
384
420
|
return createLiteralTypeNode(createStringLiteral(String(value)));
|
|
385
421
|
}
|
|
422
|
+
/**
|
|
423
|
+
* Returns a `Date` reference type node when `representation` is `'date'`, otherwise falls back to `string`.
|
|
424
|
+
*/
|
|
386
425
|
function dateOrStringNode(node) {
|
|
387
426
|
return node.representation === "date" ? createTypeReferenceNode(createIdentifier("Date")) : keywordTypeNodes.string;
|
|
388
427
|
}
|
|
428
|
+
/**
|
|
429
|
+
* Maps an array of `SchemaNode`s through the printer, filtering out `null` and `undefined` results.
|
|
430
|
+
*/
|
|
389
431
|
function buildMemberNodes(members, print) {
|
|
390
432
|
return (members ?? []).map(print).filter(Boolean);
|
|
391
433
|
}
|
|
434
|
+
/**
|
|
435
|
+
* Builds a TypeScript tuple type node from an array schema's `items`,
|
|
436
|
+
* applying min/max slice and optional/rest element rules.
|
|
437
|
+
*/
|
|
392
438
|
function buildTupleNode(node, print) {
|
|
393
439
|
let items = (node.items ?? []).map(print).filter(Boolean);
|
|
394
440
|
const restNode = node.rest ? print(node.rest) ?? void 0 : void 0;
|
|
@@ -401,13 +447,19 @@ function buildTupleNode(node, print) {
|
|
|
401
447
|
if (max === void 0 && restNode) items.push(createRestTypeNode(createArrayTypeNode(restNode)));
|
|
402
448
|
return createTupleTypeNode(items);
|
|
403
449
|
}
|
|
450
|
+
/**
|
|
451
|
+
* Applies `nullable` and optional/nullish `| undefined` union modifiers to a property's resolved base type.
|
|
452
|
+
*/
|
|
404
453
|
function buildPropertyType(schema, baseType, optionalType) {
|
|
405
|
-
const addsUndefined =
|
|
454
|
+
const addsUndefined = OPTIONAL_ADDS_UNDEFINED.has(optionalType);
|
|
406
455
|
let type = baseType;
|
|
407
456
|
if (schema.nullable) type = createUnionDeclaration({ nodes: [type, keywordTypeNodes.null] });
|
|
408
457
|
if ((schema.nullish || schema.optional) && addsUndefined) type = createUnionDeclaration({ nodes: [type, keywordTypeNodes.undefined] });
|
|
409
458
|
return type;
|
|
410
459
|
}
|
|
460
|
+
/**
|
|
461
|
+
* Collects JSDoc annotation strings (description, deprecated, min/max, pattern, default, example, type) for a schema node.
|
|
462
|
+
*/
|
|
411
463
|
function buildPropertyJSDocComments(schema) {
|
|
412
464
|
return [
|
|
413
465
|
"description" in schema && schema.description ? `@description ${jsStringEscape(schema.description)}` : void 0,
|
|
@@ -420,6 +472,9 @@ function buildPropertyJSDocComments(schema) {
|
|
|
420
472
|
"primitive" in schema && schema.primitive ? [`@type ${schema.primitive || "unknown"}`, "optional" in schema && schema.optional ? " | undefined" : void 0].filter(Boolean).join("") : void 0
|
|
421
473
|
];
|
|
422
474
|
}
|
|
475
|
+
/**
|
|
476
|
+
* Creates TypeScript index signatures for `additionalProperties` and `patternProperties` on an object schema node.
|
|
477
|
+
*/
|
|
423
478
|
function buildIndexSignatures(node, propertyCount, print) {
|
|
424
479
|
const elements = [];
|
|
425
480
|
if (node.additionalProperties && node.additionalProperties !== true) {
|
|
@@ -437,204 +492,238 @@ function buildIndexSignatures(node, propertyCount, print) {
|
|
|
437
492
|
return elements;
|
|
438
493
|
}
|
|
439
494
|
/**
|
|
440
|
-
*
|
|
495
|
+
* TypeScript type printer built with `definePrinter`.
|
|
496
|
+
*
|
|
497
|
+
* Converts a `SchemaNode` AST node into a TypeScript AST node:
|
|
498
|
+
* - **`printer.print(node)`** — when `options.typeName` is set, returns a full
|
|
499
|
+
* `type Name = …` or `interface Name { … }` declaration (`ts.Node`).
|
|
500
|
+
* Without `typeName`, returns the raw `ts.TypeNode` for the schema.
|
|
501
|
+
*
|
|
502
|
+
* Dispatches on `node.type` to the appropriate handler in `nodes`. Options are closed
|
|
503
|
+
* over per printer instance, so each call to `printerTs(options)` produces an independent printer.
|
|
441
504
|
*
|
|
442
|
-
*
|
|
443
|
-
*
|
|
444
|
-
*
|
|
505
|
+
* @example Raw type node (no `typeName`)
|
|
506
|
+
* ```ts
|
|
507
|
+
* const printer = printerTs({ optionalType: 'questionToken', arrayType: 'array', enumType: 'inlineLiteral' })
|
|
508
|
+
* const typeNode = printer.print(schemaNode) // ts.TypeNode
|
|
509
|
+
* ```
|
|
510
|
+
*
|
|
511
|
+
* @example Full declaration (with `typeName`)
|
|
512
|
+
* ```ts
|
|
513
|
+
* const printer = printerTs({ optionalType: 'questionToken', arrayType: 'array', enumType: 'inlineLiteral', typeName: 'MyType' })
|
|
514
|
+
* const declaration = printer.print(schemaNode) // ts.TypeAliasDeclaration | ts.InterfaceDeclaration
|
|
515
|
+
* ```
|
|
445
516
|
*/
|
|
446
|
-
const printerTs = definePrinter((options) =>
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
517
|
+
const printerTs = definePrinter((options) => {
|
|
518
|
+
const addsUndefined = OPTIONAL_ADDS_UNDEFINED.has(options.optionalType);
|
|
519
|
+
return {
|
|
520
|
+
name: "typescript",
|
|
521
|
+
options,
|
|
522
|
+
nodes: {
|
|
523
|
+
any: () => keywordTypeNodes.any,
|
|
524
|
+
unknown: () => keywordTypeNodes.unknown,
|
|
525
|
+
void: () => keywordTypeNodes.void,
|
|
526
|
+
never: () => keywordTypeNodes.never,
|
|
527
|
+
boolean: () => keywordTypeNodes.boolean,
|
|
528
|
+
null: () => keywordTypeNodes.null,
|
|
529
|
+
blob: () => createTypeReferenceNode("Blob", []),
|
|
530
|
+
string: () => keywordTypeNodes.string,
|
|
531
|
+
uuid: () => keywordTypeNodes.string,
|
|
532
|
+
email: () => keywordTypeNodes.string,
|
|
533
|
+
url: (node) => {
|
|
534
|
+
if (node.path) return createUrlTemplateType(node.path);
|
|
535
|
+
return keywordTypeNodes.string;
|
|
536
|
+
},
|
|
537
|
+
datetime: () => keywordTypeNodes.string,
|
|
538
|
+
number: () => keywordTypeNodes.number,
|
|
539
|
+
integer: () => keywordTypeNodes.number,
|
|
540
|
+
bigint: () => keywordTypeNodes.bigint,
|
|
541
|
+
date: dateOrStringNode,
|
|
542
|
+
time: dateOrStringNode,
|
|
543
|
+
ref(node) {
|
|
544
|
+
if (!node.name) return;
|
|
545
|
+
return createTypeReferenceNode(node.name, void 0);
|
|
546
|
+
},
|
|
547
|
+
enum(node) {
|
|
548
|
+
const values = node.namedEnumValues?.map((v) => v.value) ?? node.enumValues ?? [];
|
|
549
|
+
if (this.options.enumType === "inlineLiteral" || !node.name) return createUnionDeclaration({
|
|
550
|
+
withParentheses: true,
|
|
551
|
+
nodes: values.filter((v) => v !== null).map((value) => constToTypeNode(value, typeof value)).filter(Boolean)
|
|
552
|
+
}) ?? void 0;
|
|
553
|
+
const resolvedName = pascalCase(node.name);
|
|
554
|
+
return createTypeReferenceNode(ENUM_TYPES_WITH_KEY_SUFFIX.has(this.options.enumType) ? `${resolvedName}Key` : resolvedName, void 0);
|
|
555
|
+
},
|
|
556
|
+
union(node) {
|
|
557
|
+
const members = node.members ?? [];
|
|
558
|
+
const hasStringLiteral = members.some((m) => m.type === "enum" && m.enumType === "string");
|
|
559
|
+
const hasPlainString = members.some((m) => isPlainStringType(m));
|
|
560
|
+
if (hasStringLiteral && hasPlainString) return createUnionDeclaration({
|
|
561
|
+
withParentheses: true,
|
|
562
|
+
nodes: members.map((m) => {
|
|
563
|
+
if (isPlainStringType(m)) return createIntersectionDeclaration({
|
|
564
|
+
nodes: [keywordTypeNodes.string, createTypeLiteralNode([])],
|
|
565
|
+
withParentheses: true
|
|
566
|
+
});
|
|
567
|
+
return this.print(m);
|
|
568
|
+
}).filter(Boolean)
|
|
569
|
+
}) ?? void 0;
|
|
570
|
+
return createUnionDeclaration({
|
|
571
|
+
withParentheses: true,
|
|
572
|
+
nodes: buildMemberNodes(members, this.print)
|
|
573
|
+
}) ?? void 0;
|
|
574
|
+
},
|
|
575
|
+
intersection(node) {
|
|
576
|
+
return createIntersectionDeclaration({
|
|
577
|
+
withParentheses: true,
|
|
578
|
+
nodes: buildMemberNodes(node.members, this.print)
|
|
579
|
+
}) ?? void 0;
|
|
580
|
+
},
|
|
581
|
+
array(node) {
|
|
582
|
+
return createArrayDeclaration({
|
|
583
|
+
nodes: (node.items ?? []).map((item) => this.print(item)).filter(Boolean),
|
|
584
|
+
arrayType: this.options.arrayType
|
|
585
|
+
}) ?? void 0;
|
|
586
|
+
},
|
|
587
|
+
tuple(node) {
|
|
588
|
+
return buildTupleNode(node, this.print);
|
|
589
|
+
},
|
|
590
|
+
object(node) {
|
|
591
|
+
const { print, options } = this;
|
|
592
|
+
const addsQuestionToken = OPTIONAL_ADDS_QUESTION_TOKEN.has(options.optionalType);
|
|
593
|
+
const propertyNodes = node.properties.map((prop) => {
|
|
594
|
+
const baseType = print(prop.schema) ?? keywordTypeNodes.unknown;
|
|
595
|
+
const type = buildPropertyType(prop.schema, baseType, options.optionalType);
|
|
596
|
+
return appendJSDocToNode({
|
|
597
|
+
node: createPropertySignature({
|
|
598
|
+
questionToken: prop.schema.optional || prop.schema.nullish ? addsQuestionToken : false,
|
|
599
|
+
name: prop.name,
|
|
600
|
+
type,
|
|
601
|
+
readOnly: prop.schema.readOnly
|
|
602
|
+
}),
|
|
603
|
+
comments: buildPropertyJSDocComments(prop.schema)
|
|
492
604
|
});
|
|
493
|
-
return this.print(m);
|
|
494
|
-
}).filter(Boolean)
|
|
495
|
-
}) ?? void 0;
|
|
496
|
-
return createUnionDeclaration({
|
|
497
|
-
withParentheses: true,
|
|
498
|
-
nodes: buildMemberNodes(members, this.print)
|
|
499
|
-
}) ?? void 0;
|
|
500
|
-
},
|
|
501
|
-
intersection(node) {
|
|
502
|
-
return createIntersectionDeclaration({
|
|
503
|
-
withParentheses: true,
|
|
504
|
-
nodes: buildMemberNodes(node.members, this.print)
|
|
505
|
-
}) ?? void 0;
|
|
506
|
-
},
|
|
507
|
-
array(node) {
|
|
508
|
-
return createArrayDeclaration({
|
|
509
|
-
nodes: (node.items ?? []).map((item) => this.print(item)).filter(Boolean),
|
|
510
|
-
arrayType: this.options.arrayType
|
|
511
|
-
}) ?? void 0;
|
|
512
|
-
},
|
|
513
|
-
tuple(node) {
|
|
514
|
-
return buildTupleNode(node, this.print);
|
|
515
|
-
},
|
|
516
|
-
object(node) {
|
|
517
|
-
const addsQuestionToken = ["questionToken", "questionTokenAndUndefined"].includes(this.options.optionalType);
|
|
518
|
-
const { print } = this;
|
|
519
|
-
const propertyNodes = node.properties.map((prop) => {
|
|
520
|
-
if (this.options.mapper && Object.hasOwn(this.options.mapper, prop.name)) return this.options.mapper[prop.name];
|
|
521
|
-
const baseType = print(prop.schema) ?? keywordTypeNodes.unknown;
|
|
522
|
-
const type = buildPropertyType(prop.schema, baseType, this.options.optionalType);
|
|
523
|
-
return appendJSDocToNode({
|
|
524
|
-
node: createPropertySignature({
|
|
525
|
-
questionToken: prop.schema.optional || prop.schema.nullish ? addsQuestionToken : false,
|
|
526
|
-
name: prop.name,
|
|
527
|
-
type,
|
|
528
|
-
readOnly: prop.schema.readOnly
|
|
529
|
-
}),
|
|
530
|
-
comments: buildPropertyJSDocComments(prop.schema)
|
|
531
605
|
});
|
|
606
|
+
const allElements = [...propertyNodes, ...buildIndexSignatures(node, propertyNodes.length, print)];
|
|
607
|
+
if (!allElements.length) return keywordTypeNodes.object;
|
|
608
|
+
return createTypeLiteralNode(allElements);
|
|
609
|
+
}
|
|
610
|
+
},
|
|
611
|
+
print(node) {
|
|
612
|
+
let type = this.print(node);
|
|
613
|
+
if (!type) return;
|
|
614
|
+
if (node.nullable) type = createUnionDeclaration({ nodes: [type, keywordTypeNodes.null] });
|
|
615
|
+
if ((node.nullish || node.optional) && addsUndefined) type = createUnionDeclaration({ nodes: [type, keywordTypeNodes.undefined] });
|
|
616
|
+
const { typeName, syntaxType = "type", description, keysToOmit } = this.options;
|
|
617
|
+
if (!typeName) return type;
|
|
618
|
+
const useTypeGeneration = syntaxType === "type" || type.kind === syntaxKind.union || !!keysToOmit?.length;
|
|
619
|
+
return createTypeDeclaration({
|
|
620
|
+
name: typeName,
|
|
621
|
+
isExportable: true,
|
|
622
|
+
type: keysToOmit?.length ? createOmitDeclaration({
|
|
623
|
+
keys: keysToOmit,
|
|
624
|
+
type,
|
|
625
|
+
nonNullable: true
|
|
626
|
+
}) : type,
|
|
627
|
+
syntax: useTypeGeneration ? "type" : "interface",
|
|
628
|
+
comments: [
|
|
629
|
+
node?.title ? jsStringEscape(node.title) : void 0,
|
|
630
|
+
description ? `@description ${jsStringEscape(description)}` : void 0,
|
|
631
|
+
node?.deprecated ? "@deprecated" : void 0,
|
|
632
|
+
node && "min" in node && node.min !== void 0 ? `@minLength ${node.min}` : void 0,
|
|
633
|
+
node && "max" in node && node.max !== void 0 ? `@maxLength ${node.max}` : void 0,
|
|
634
|
+
node && "pattern" in node && node.pattern ? `@pattern ${node.pattern}` : void 0,
|
|
635
|
+
node?.default ? `@default ${node.default}` : void 0,
|
|
636
|
+
node?.example ? `@example ${node.example}` : void 0
|
|
637
|
+
]
|
|
532
638
|
});
|
|
533
|
-
const allElements = [...propertyNodes, ...buildIndexSignatures(node, propertyNodes.length, print)];
|
|
534
|
-
if (!allElements.length) return keywordTypeNodes.object;
|
|
535
|
-
return createTypeLiteralNode(allElements);
|
|
536
639
|
}
|
|
537
|
-
}
|
|
538
|
-
})
|
|
640
|
+
};
|
|
641
|
+
});
|
|
642
|
+
//#endregion
|
|
643
|
+
//#region src/components/v2/Enum.tsx
|
|
644
|
+
/**
|
|
645
|
+
* Resolves the runtime identifier name and the TypeScript type name for an enum schema node.
|
|
646
|
+
*
|
|
647
|
+
* The raw `node.name` may be a YAML key such as `"enumNames.Type"` which is not a
|
|
648
|
+
* valid TypeScript identifier. `pascalCase` normalizes it unconditionally; for inline enum
|
|
649
|
+
* properties the adapter already emits a PascalCase+suffix name so `pascalCase` is a no-op.
|
|
650
|
+
*/
|
|
651
|
+
function getEnumNames(node, enumType) {
|
|
652
|
+
const resolved = pascalCase(node.name);
|
|
653
|
+
return {
|
|
654
|
+
enumName: enumType === "asPascalConst" ? resolved : camelCase(node.name),
|
|
655
|
+
typeName: ENUM_TYPES_WITH_KEY_SUFFIX.has(enumType) ? `${resolved}Key` : resolved
|
|
656
|
+
};
|
|
657
|
+
}
|
|
658
|
+
/**
|
|
659
|
+
* Renders the enum declaration(s) for a single named `EnumSchemaNode`.
|
|
660
|
+
*
|
|
661
|
+
* Depending on `enumType` this may emit:
|
|
662
|
+
* - A runtime object (`asConst` / `asPascalConst`) plus a `typeof` type alias
|
|
663
|
+
* - A `const enum` or plain `enum` declaration (`constEnum` / `enum`)
|
|
664
|
+
* - A union literal type alias (`literal`)
|
|
665
|
+
*
|
|
666
|
+
* The emitted `File.Source` nodes carry the resolved names so that the barrel
|
|
667
|
+
* index picks up the correct export identifiers.
|
|
668
|
+
*/
|
|
669
|
+
function Enum({ node, enumType, enumKeyCasing }) {
|
|
670
|
+
const { enumName, typeName } = getEnumNames(node, enumType);
|
|
671
|
+
const [nameNode, typeNode] = createEnumDeclaration({
|
|
672
|
+
name: enumName,
|
|
673
|
+
typeName,
|
|
674
|
+
enums: node.namedEnumValues?.map((v) => [trimQuotes(v.name.toString()), v.value]) ?? node.enumValues?.filter((v) => v !== null && v !== void 0).map((v) => [trimQuotes(v.toString()), v]) ?? [],
|
|
675
|
+
type: enumType,
|
|
676
|
+
enumKeyCasing
|
|
677
|
+
});
|
|
678
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [nameNode && /* @__PURE__ */ jsx(File.Source, {
|
|
679
|
+
name: enumName,
|
|
680
|
+
isExportable: true,
|
|
681
|
+
isIndexable: true,
|
|
682
|
+
isTypeOnly: false,
|
|
683
|
+
children: safePrint(nameNode)
|
|
684
|
+
}), /* @__PURE__ */ jsx(File.Source, {
|
|
685
|
+
name: typeName,
|
|
686
|
+
isIndexable: true,
|
|
687
|
+
isExportable: ENUM_TYPES_WITH_RUNTIME_VALUE.has(enumType),
|
|
688
|
+
isTypeOnly: ENUM_TYPES_WITH_TYPE_ONLY.has(enumType),
|
|
689
|
+
children: safePrint(typeNode)
|
|
690
|
+
})] });
|
|
691
|
+
}
|
|
539
692
|
//#endregion
|
|
540
693
|
//#region src/components/v2/Type.tsx
|
|
541
|
-
function Type({ name, typedName, node, keysToOmit, optionalType, arrayType, syntaxType, enumType, enumKeyCasing,
|
|
542
|
-
const
|
|
543
|
-
const description = rest.description || node?.description;
|
|
694
|
+
function Type({ name, typedName, node, keysToOmit, optionalType, arrayType, syntaxType, enumType, enumKeyCasing, description }) {
|
|
695
|
+
const resolvedDescription = description || node?.description;
|
|
544
696
|
const enumSchemaNodes = collect(node, { schema(n) {
|
|
545
697
|
if (n.type === "enum" && n.name) return n;
|
|
546
698
|
} });
|
|
547
|
-
|
|
699
|
+
const typeNode = printerTs({
|
|
548
700
|
optionalType,
|
|
549
701
|
arrayType,
|
|
550
702
|
enumType,
|
|
551
|
-
|
|
703
|
+
typeName: name,
|
|
704
|
+
syntaxType,
|
|
705
|
+
description: resolvedDescription,
|
|
706
|
+
keysToOmit
|
|
552
707
|
}).print(node);
|
|
553
|
-
if (!
|
|
554
|
-
|
|
555
|
-
const isDirectEnum = node.type === "array" && node.items !== void 0;
|
|
556
|
-
const isEnumOnly = "enum" in node && node.enum;
|
|
557
|
-
if (isDirectEnum || isEnumOnly) {
|
|
558
|
-
type = createTypeReferenceNode(`${enumSchemaNodes[0].name}Key`);
|
|
559
|
-
if (isDirectEnum) if (arrayType === "generic") type = createTypeReferenceNode(createIdentifier("Array"), [type]);
|
|
560
|
-
else type = createArrayTypeNode(type);
|
|
561
|
-
}
|
|
562
|
-
}
|
|
563
|
-
if (node) {
|
|
564
|
-
if (node.nullable) type = createUnionDeclaration({ nodes: [type, keywordTypeNodes.null] });
|
|
565
|
-
if (node.nullish && ["undefined", "questionTokenAndUndefined"].includes(optionalType)) type = createUnionDeclaration({ nodes: [type, keywordTypeNodes.undefined] });
|
|
566
|
-
if (node.optional && ["undefined", "questionTokenAndUndefined"].includes(optionalType)) type = createUnionDeclaration({ nodes: [type, keywordTypeNodes.undefined] });
|
|
567
|
-
}
|
|
568
|
-
const useTypeGeneration = syntaxType === "type" || [syntaxKind.union].includes(type.kind) || !!keysToOmit?.length;
|
|
569
|
-
typeNodes.push(createTypeDeclaration({
|
|
570
|
-
name,
|
|
571
|
-
isExportable: true,
|
|
572
|
-
type: keysToOmit?.length ? createOmitDeclaration({
|
|
573
|
-
keys: keysToOmit,
|
|
574
|
-
type,
|
|
575
|
-
nonNullable: true
|
|
576
|
-
}) : type,
|
|
577
|
-
syntax: useTypeGeneration ? "type" : "interface",
|
|
578
|
-
comments: [
|
|
579
|
-
node?.title ? `${jsStringEscape(node.title)}` : void 0,
|
|
580
|
-
description ? `@description ${jsStringEscape(description)}` : void 0,
|
|
581
|
-
node?.deprecated ? "@deprecated" : void 0,
|
|
582
|
-
node && "min" in node && node.min !== void 0 ? `@minLength ${node.min}` : void 0,
|
|
583
|
-
node && "max" in node && node.max !== void 0 ? `@maxLength ${node.max}` : void 0,
|
|
584
|
-
node && "pattern" in node && node.pattern ? `@pattern ${node.pattern}` : void 0,
|
|
585
|
-
node?.default ? `@default ${node.default}` : void 0,
|
|
586
|
-
node?.example ? `@example ${node.example}` : void 0
|
|
587
|
-
]
|
|
588
|
-
}));
|
|
589
|
-
const enums = [...new Map(enumSchemaNodes.map((n) => [n.name, n])).values()].map((enumSchemaNode) => {
|
|
590
|
-
const enumName = enumType === "asPascalConst" ? pascalCase(enumSchemaNode.name) : camelCase(enumSchemaNode.name);
|
|
591
|
-
const typeName = ["asConst", "asPascalConst"].includes(enumType) ? `${enumSchemaNode.name}Key` : enumSchemaNode.name;
|
|
592
|
-
const [nameNode, typeNode] = createEnumDeclaration({
|
|
593
|
-
name: enumName,
|
|
594
|
-
typeName,
|
|
595
|
-
enums: enumSchemaNode.namedEnumValues?.map((v) => [trimQuotes(v.name.toString()), v.value]) ?? enumSchemaNode.enumValues?.filter((v) => v !== null && v !== void 0).map((v) => [trimQuotes(v.toString()), v]) ?? [],
|
|
596
|
-
type: enumType,
|
|
597
|
-
enumKeyCasing
|
|
598
|
-
});
|
|
708
|
+
if (!typeNode) return;
|
|
709
|
+
const enums = [...new Map(enumSchemaNodes.map((n) => [n.name, n])).values()].map((node) => {
|
|
599
710
|
return {
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
name: enumName,
|
|
603
|
-
typeName
|
|
711
|
+
node,
|
|
712
|
+
...getEnumNames(node, enumType)
|
|
604
713
|
};
|
|
605
714
|
});
|
|
606
715
|
const shouldExportEnums = enumType !== "inlineLiteral";
|
|
607
716
|
const shouldExportType = enumType === "inlineLiteral" || enums.every((item) => item.typeName !== name);
|
|
608
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [shouldExportEnums && enums.map(({
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
children: safePrint(nameNode)
|
|
614
|
-
}), /* @__PURE__ */ jsx(File.Source, {
|
|
615
|
-
name: typeName,
|
|
616
|
-
isIndexable: true,
|
|
617
|
-
isExportable: [
|
|
618
|
-
"enum",
|
|
619
|
-
"asConst",
|
|
620
|
-
"asPascalConst",
|
|
621
|
-
"constEnum",
|
|
622
|
-
"literal",
|
|
623
|
-
void 0
|
|
624
|
-
].includes(enumType),
|
|
625
|
-
isTypeOnly: [
|
|
626
|
-
"asConst",
|
|
627
|
-
"asPascalConst",
|
|
628
|
-
"literal",
|
|
629
|
-
void 0
|
|
630
|
-
].includes(enumType),
|
|
631
|
-
children: safePrint(typeNode)
|
|
632
|
-
})] })), shouldExportType && /* @__PURE__ */ jsx(File.Source, {
|
|
717
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [shouldExportEnums && enums.map(({ node }) => /* @__PURE__ */ jsx(Enum, {
|
|
718
|
+
node,
|
|
719
|
+
enumType,
|
|
720
|
+
enumKeyCasing
|
|
721
|
+
})), shouldExportType && /* @__PURE__ */ jsx(File.Source, {
|
|
633
722
|
name: typedName,
|
|
634
723
|
isTypeOnly: true,
|
|
635
724
|
isExportable: true,
|
|
636
725
|
isIndexable: true,
|
|
637
|
-
children: safePrint(
|
|
726
|
+
children: safePrint(typeNode)
|
|
638
727
|
})] });
|
|
639
728
|
}
|
|
640
729
|
//#endregion
|
|
@@ -642,6 +731,8 @@ function Type({ name, typedName, node, keysToOmit, optionalType, arrayType, synt
|
|
|
642
731
|
/**
|
|
643
732
|
* Builds an `ObjectSchemaNode` for a group of parameters (path/query/header).
|
|
644
733
|
* Each property is a `ref` schema pointing to the individually-resolved parameter type.
|
|
734
|
+
* The ref name includes the parameter location so generated type names follow
|
|
735
|
+
* the `<OperationId><Location><ParamName>` convention.
|
|
645
736
|
*/
|
|
646
737
|
function buildParamsSchema({ params, operationId, resolveName }) {
|
|
647
738
|
return createSchema({
|
|
@@ -651,7 +742,7 @@ function buildParamsSchema({ params, operationId, resolveName }) {
|
|
|
651
742
|
schema: createSchema({
|
|
652
743
|
type: "ref",
|
|
653
744
|
name: resolveName({
|
|
654
|
-
name: `${operationId} ${param.name}`,
|
|
745
|
+
name: `${operationId} ${pascalCase(param.in)} ${param.name}`,
|
|
655
746
|
type: "function"
|
|
656
747
|
}),
|
|
657
748
|
optional: !param.required
|
|
@@ -660,7 +751,7 @@ function buildParamsSchema({ params, operationId, resolveName }) {
|
|
|
660
751
|
});
|
|
661
752
|
}
|
|
662
753
|
/**
|
|
663
|
-
* Builds an `ObjectSchemaNode` representing the `<OperationId>
|
|
754
|
+
* Builds an `ObjectSchemaNode` representing the `<OperationId>RequestConfig` type:
|
|
664
755
|
* - `data` → request body ref (optional) or `never`
|
|
665
756
|
* - `pathParams` → inline object of path param refs, or `never`
|
|
666
757
|
* - `queryParams` → inline object of query param refs (optional), or `never`
|
|
@@ -679,7 +770,7 @@ function buildDataSchemaNode({ node, resolveName }) {
|
|
|
679
770
|
schema: node.requestBody ? createSchema({
|
|
680
771
|
type: "ref",
|
|
681
772
|
name: resolveName({
|
|
682
|
-
name: `${node.operationId}
|
|
773
|
+
name: `${node.operationId} Data`,
|
|
683
774
|
type: "function"
|
|
684
775
|
}),
|
|
685
776
|
optional: true
|
|
@@ -739,11 +830,7 @@ function buildDataSchemaNode({ node, resolveName }) {
|
|
|
739
830
|
}
|
|
740
831
|
/**
|
|
741
832
|
* Builds an `ObjectSchemaNode` representing `<OperationId>Responses` — keyed by HTTP status code.
|
|
742
|
-
*
|
|
743
|
-
* Example output:
|
|
744
|
-
* ```ts
|
|
745
|
-
* export type PlaceOrderPatchResponses = { 200: PlaceOrderPatch200; 405: PlaceOrderPatch405 }
|
|
746
|
-
* ```
|
|
833
|
+
* Numeric status codes produce unquoted numeric keys (e.g. `200:`).
|
|
747
834
|
*/
|
|
748
835
|
function buildResponsesSchemaNode({ node, resolveName }) {
|
|
749
836
|
const responsesWithSchema = node.responses.filter((res) => res.schema);
|
|
@@ -755,7 +842,7 @@ function buildResponsesSchemaNode({ node, resolveName }) {
|
|
|
755
842
|
schema: createSchema({
|
|
756
843
|
type: "ref",
|
|
757
844
|
name: resolveName({
|
|
758
|
-
name: `${node.operationId} ${res.statusCode}`,
|
|
845
|
+
name: `${node.operationId} Status ${res.statusCode}`,
|
|
759
846
|
type: "function"
|
|
760
847
|
})
|
|
761
848
|
})
|
|
@@ -764,11 +851,7 @@ function buildResponsesSchemaNode({ node, resolveName }) {
|
|
|
764
851
|
}
|
|
765
852
|
/**
|
|
766
853
|
* Builds a `UnionSchemaNode` representing `<OperationId>Response` — all response types in union format.
|
|
767
|
-
*
|
|
768
|
-
* Example output:
|
|
769
|
-
* ```ts
|
|
770
|
-
* export type PlaceOrderPatchResponse = PlaceOrderPatch200 | PlaceOrderPatch405
|
|
771
|
-
* ```
|
|
854
|
+
* Returns `null` when the operation has no responses with schemas.
|
|
772
855
|
*/
|
|
773
856
|
function buildResponseUnionSchemaNode({ node, resolveName }) {
|
|
774
857
|
const responsesWithSchema = node.responses.filter((res) => res.schema);
|
|
@@ -778,7 +861,7 @@ function buildResponseUnionSchemaNode({ node, resolveName }) {
|
|
|
778
861
|
members: responsesWithSchema.map((res) => createSchema({
|
|
779
862
|
type: "ref",
|
|
780
863
|
name: resolveName({
|
|
781
|
-
name: `${node.operationId} ${res.statusCode}`,
|
|
864
|
+
name: `${node.operationId} Status ${res.statusCode}`,
|
|
782
865
|
type: "function"
|
|
783
866
|
})
|
|
784
867
|
}))
|
|
@@ -790,12 +873,13 @@ const typeGenerator = defineGenerator({
|
|
|
790
873
|
name: "typescript",
|
|
791
874
|
type: "react",
|
|
792
875
|
Operation({ node, adapter, options }) {
|
|
793
|
-
const { enumType, enumKeyCasing, optionalType, arrayType, syntaxType, paramsCasing,
|
|
876
|
+
const { enumType, enumKeyCasing, optionalType, arrayType, syntaxType, paramsCasing, group } = options;
|
|
794
877
|
const { mode, getFile, resolveName } = useKubb();
|
|
795
878
|
const file = getFile({
|
|
796
879
|
name: node.operationId,
|
|
797
880
|
extname: ".ts",
|
|
798
|
-
mode
|
|
881
|
+
mode,
|
|
882
|
+
options: { group: group ? group.type === "tag" ? { tag: node.tags[0] } : { path: node.path } : void 0 }
|
|
799
883
|
});
|
|
800
884
|
const params = applyParamsCasing(node.parameters, paramsCasing);
|
|
801
885
|
function renderSchemaType({ node: schemaNode, name, typedName, description }) {
|
|
@@ -829,29 +913,28 @@ const typeGenerator = defineGenerator({
|
|
|
829
913
|
enumKeyCasing,
|
|
830
914
|
optionalType,
|
|
831
915
|
arrayType,
|
|
832
|
-
syntaxType
|
|
833
|
-
mapper
|
|
916
|
+
syntaxType
|
|
834
917
|
})] });
|
|
835
918
|
}
|
|
836
919
|
const paramTypes = params.map((param) => renderSchemaType({
|
|
837
920
|
node: param.schema,
|
|
838
921
|
name: resolveName({
|
|
839
|
-
name: `${node.operationId} ${param.name}`,
|
|
922
|
+
name: `${node.operationId} ${pascalCase(param.in)} ${param.name}`,
|
|
840
923
|
type: "function"
|
|
841
924
|
}),
|
|
842
925
|
typedName: resolveName({
|
|
843
|
-
name: `${node.operationId} ${param.name}`,
|
|
926
|
+
name: `${node.operationId} ${pascalCase(param.in)} ${param.name}`,
|
|
844
927
|
type: "type"
|
|
845
928
|
})
|
|
846
929
|
}));
|
|
847
930
|
const responseTypes = node.responses.filter((res) => res.schema).map((res) => renderSchemaType({
|
|
848
931
|
node: res.schema,
|
|
849
932
|
name: resolveName({
|
|
850
|
-
name: `${node.operationId} ${res.statusCode}`,
|
|
933
|
+
name: `${node.operationId} Status ${res.statusCode}`,
|
|
851
934
|
type: "function"
|
|
852
935
|
}),
|
|
853
936
|
typedName: resolveName({
|
|
854
|
-
name: `${node.operationId} ${res.statusCode}`,
|
|
937
|
+
name: `${node.operationId} Status ${res.statusCode}`,
|
|
855
938
|
type: "type"
|
|
856
939
|
}),
|
|
857
940
|
description: res.description
|
|
@@ -859,11 +942,11 @@ const typeGenerator = defineGenerator({
|
|
|
859
942
|
const requestType = node.requestBody ? renderSchemaType({
|
|
860
943
|
node: node.requestBody,
|
|
861
944
|
name: resolveName({
|
|
862
|
-
name: `${node.operationId}
|
|
945
|
+
name: `${node.operationId} Data`,
|
|
863
946
|
type: "function"
|
|
864
947
|
}),
|
|
865
948
|
typedName: resolveName({
|
|
866
|
-
name: `${node.operationId}
|
|
949
|
+
name: `${node.operationId} Data`,
|
|
867
950
|
type: "type"
|
|
868
951
|
}),
|
|
869
952
|
description: node.requestBody.description
|
|
@@ -877,11 +960,11 @@ const typeGenerator = defineGenerator({
|
|
|
877
960
|
resolveName
|
|
878
961
|
}),
|
|
879
962
|
name: resolveName({
|
|
880
|
-
name: `${node.operationId}
|
|
963
|
+
name: `${node.operationId} RequestConfig`,
|
|
881
964
|
type: "function"
|
|
882
965
|
}),
|
|
883
966
|
typedName: resolveName({
|
|
884
|
-
name: `${node.operationId}
|
|
967
|
+
name: `${node.operationId} RequestConfig`,
|
|
885
968
|
type: "type"
|
|
886
969
|
})
|
|
887
970
|
});
|
|
@@ -911,7 +994,8 @@ const typeGenerator = defineGenerator({
|
|
|
911
994
|
typedName: resolveName({
|
|
912
995
|
name: `${node.operationId} Response`,
|
|
913
996
|
type: "type"
|
|
914
|
-
})
|
|
997
|
+
}),
|
|
998
|
+
description: "Union of all possible responses"
|
|
915
999
|
});
|
|
916
1000
|
return /* @__PURE__ */ jsxs(File, {
|
|
917
1001
|
baseName: file.baseName,
|
|
@@ -928,7 +1012,7 @@ const typeGenerator = defineGenerator({
|
|
|
928
1012
|
});
|
|
929
1013
|
},
|
|
930
1014
|
Schema({ node, adapter, options }) {
|
|
931
|
-
const { enumType, enumKeyCasing, syntaxType, optionalType, arrayType
|
|
1015
|
+
const { enumType, enumKeyCasing, syntaxType, optionalType, arrayType } = options;
|
|
932
1016
|
const { mode, resolveName, getFile } = useKubb();
|
|
933
1017
|
if (!node.name) return;
|
|
934
1018
|
const imports = adapter.getImports(node, (schemaName) => ({
|
|
@@ -947,7 +1031,7 @@ const typeGenerator = defineGenerator({
|
|
|
947
1031
|
name: node.name,
|
|
948
1032
|
type: "type"
|
|
949
1033
|
});
|
|
950
|
-
if (
|
|
1034
|
+
if (ENUM_TYPES_WITH_KEY_SUFFIX.has(enumType) && isEnumSchema) typedName += "Key";
|
|
951
1035
|
const type = {
|
|
952
1036
|
name: resolveName({
|
|
953
1037
|
name: node.name,
|
|
@@ -981,8 +1065,7 @@ const typeGenerator = defineGenerator({
|
|
|
981
1065
|
enumKeyCasing,
|
|
982
1066
|
optionalType,
|
|
983
1067
|
arrayType,
|
|
984
|
-
syntaxType
|
|
985
|
-
mapper
|
|
1068
|
+
syntaxType
|
|
986
1069
|
})]
|
|
987
1070
|
});
|
|
988
1071
|
}
|
|
@@ -994,7 +1077,7 @@ const pluginTs = definePlugin((options) => {
|
|
|
994
1077
|
const { output = {
|
|
995
1078
|
path: "types",
|
|
996
1079
|
barrelType: "named"
|
|
997
|
-
}, group, exclude = [], include, override = [], enumType = "asConst", enumKeyCasing = "none", enumSuffix = "enum", dateType = "string", integerType = "number", unknownType = "any", optionalType = "questionToken", arrayType = "array", emptySchemaType = unknownType, syntaxType = "type", transformers = {},
|
|
1080
|
+
}, group, exclude = [], include, override = [], enumType = "asConst", enumKeyCasing = "none", enumSuffix = "enum", dateType = "string", integerType = "number", unknownType = "any", optionalType = "questionToken", arrayType = "array", emptySchemaType = unknownType, syntaxType = "type", transformers = {}, paramsCasing, generators = [typeGenerator$1, typeGenerator].filter(Boolean), contentType, UNSTABLE_NAMING } = options;
|
|
998
1081
|
return {
|
|
999
1082
|
name: pluginTsName,
|
|
1000
1083
|
options: {
|
|
@@ -1012,7 +1095,6 @@ const pluginTs = definePlugin((options) => {
|
|
|
1012
1095
|
syntaxType,
|
|
1013
1096
|
group,
|
|
1014
1097
|
override,
|
|
1015
|
-
mapper,
|
|
1016
1098
|
paramsCasing,
|
|
1017
1099
|
usedEnumNames: {}
|
|
1018
1100
|
},
|
|
@@ -1040,7 +1122,7 @@ const pluginTs = definePlugin((options) => {
|
|
|
1040
1122
|
return resolvedName;
|
|
1041
1123
|
},
|
|
1042
1124
|
async install() {
|
|
1043
|
-
const { config, fabric, plugin, adapter, rootNode,
|
|
1125
|
+
const { config, fabric, plugin, adapter, rootNode, driver, openInStudio } = this;
|
|
1044
1126
|
const root = path.resolve(config.root, config.output.path);
|
|
1045
1127
|
const mode = getMode(path.resolve(root, output.path));
|
|
1046
1128
|
if (adapter) {
|
|
@@ -1063,7 +1145,7 @@ const pluginTs = definePlugin((options) => {
|
|
|
1063
1145
|
fabric,
|
|
1064
1146
|
Component: generator.Schema,
|
|
1065
1147
|
plugin,
|
|
1066
|
-
|
|
1148
|
+
driver,
|
|
1067
1149
|
mode,
|
|
1068
1150
|
version: generator.version
|
|
1069
1151
|
});
|
|
@@ -1088,7 +1170,7 @@ const pluginTs = definePlugin((options) => {
|
|
|
1088
1170
|
fabric,
|
|
1089
1171
|
Component: generator.Operation,
|
|
1090
1172
|
plugin,
|
|
1091
|
-
|
|
1173
|
+
driver,
|
|
1092
1174
|
mode,
|
|
1093
1175
|
version: generator.version
|
|
1094
1176
|
});
|
|
@@ -1110,7 +1192,7 @@ const pluginTs = definePlugin((options) => {
|
|
|
1110
1192
|
const schemaFiles = await new SchemaGenerator(this.plugin.options, {
|
|
1111
1193
|
fabric: this.fabric,
|
|
1112
1194
|
oas,
|
|
1113
|
-
|
|
1195
|
+
driver: this.driver,
|
|
1114
1196
|
events: this.events,
|
|
1115
1197
|
plugin: this.plugin,
|
|
1116
1198
|
contentType,
|
|
@@ -1123,7 +1205,7 @@ const pluginTs = definePlugin((options) => {
|
|
|
1123
1205
|
const operationFiles = await new OperationGenerator(this.plugin.options, {
|
|
1124
1206
|
fabric: this.fabric,
|
|
1125
1207
|
oas,
|
|
1126
|
-
|
|
1208
|
+
driver: this.driver,
|
|
1127
1209
|
events: this.events,
|
|
1128
1210
|
plugin: this.plugin,
|
|
1129
1211
|
contentType,
|
|
@@ -1147,4 +1229,4 @@ const pluginTs = definePlugin((options) => {
|
|
|
1147
1229
|
//#endregion
|
|
1148
1230
|
export { typeGenerator$1 as i, pluginTsName as n, typeGenerator as r, pluginTs as t };
|
|
1149
1231
|
|
|
1150
|
-
//# sourceMappingURL=plugin-
|
|
1232
|
+
//# sourceMappingURL=plugin-DVhVzwDg.js.map
|