@kubb/plugin-ts 5.0.0-beta.81 → 5.0.0-beta.85
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 +243 -183
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +177 -146
- package/dist/index.js +191 -132
- package/dist/index.js.map +1 -1
- package/package.json +4 -6
package/dist/index.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { n as __name, t as __exportAll } from "./rolldown-runtime-CNktS9qV.js";
|
|
2
|
-
import { extractRefName, isStringType, jsStringEscape, mapSchemaItems, mapSchemaProperties, stringify, syncSchemaRef, trimQuotes } from "@kubb/ast/utils";
|
|
3
2
|
import { parserTs } from "@kubb/parser-ts";
|
|
4
|
-
import { File, jsxRenderer } from "
|
|
3
|
+
import { File, jsxRenderer } from "kubb/jsx";
|
|
4
|
+
import { Resolver, ast, createResolver, defineGenerator, definePlugin } from "kubb/kit";
|
|
5
5
|
import ts from "typescript";
|
|
6
|
-
import { Fragment, jsx, jsxs } from "
|
|
7
|
-
import { ast, defineGenerator, definePlugin, defineResolver } from "@kubb/core";
|
|
6
|
+
import { Fragment, jsx, jsxs } from "kubb/jsx/jsx-runtime";
|
|
8
7
|
//#region ../../internals/utils/src/casing.ts
|
|
9
8
|
/**
|
|
10
9
|
* Shared implementation for camelCase and PascalCase conversion.
|
|
@@ -216,6 +215,67 @@ function ensureValidVarName(name) {
|
|
|
216
215
|
return `_${name}`;
|
|
217
216
|
}
|
|
218
217
|
//#endregion
|
|
218
|
+
//#region ../../internals/utils/src/strings.ts
|
|
219
|
+
/**
|
|
220
|
+
* Strips a single matching pair of `"..."`, `'...'`, or `` `...` `` from both ends of `text`.
|
|
221
|
+
* Returns the string unchanged when no balanced quote pair is found.
|
|
222
|
+
*
|
|
223
|
+
* @example
|
|
224
|
+
* ```ts
|
|
225
|
+
* trimQuotes('"hello"') // 'hello'
|
|
226
|
+
* trimQuotes('hello') // 'hello'
|
|
227
|
+
* ```
|
|
228
|
+
*/
|
|
229
|
+
function trimQuotes(text) {
|
|
230
|
+
if (text.length >= 2) {
|
|
231
|
+
const first = text[0];
|
|
232
|
+
const last = text[text.length - 1];
|
|
233
|
+
if (first === "\"" && last === "\"" || first === "'" && last === "'" || first === "`" && last === "`") return text.slice(1, -1);
|
|
234
|
+
}
|
|
235
|
+
return text;
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Serializes a primitive to a single-quoted string literal, stripping any surrounding quotes first.
|
|
239
|
+
*
|
|
240
|
+
* Escaping runs through `JSON.stringify`, then the result switches to single quotes so the generated
|
|
241
|
+
* code matches the repo style without a formatter.
|
|
242
|
+
*
|
|
243
|
+
* @example
|
|
244
|
+
* ```ts
|
|
245
|
+
* stringify('hello') // "'hello'"
|
|
246
|
+
* stringify('"hello"') // "'hello'"
|
|
247
|
+
* ```
|
|
248
|
+
*/
|
|
249
|
+
function stringify(value) {
|
|
250
|
+
if (value === void 0 || value === null) return "''";
|
|
251
|
+
return `'${JSON.stringify(trimQuotes(value.toString())).slice(1, -1).replace(/\\"/g, "\"").replace(/'/g, "\\'")}'`;
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Escapes characters that are not allowed inside JS string literals, covering quotes, backslashes,
|
|
255
|
+
* and the Unicode line terminators U+2028 and U+2029.
|
|
256
|
+
*
|
|
257
|
+
* @see http://www.ecma-international.org/ecma-262/5.1/#sec-7.8.4
|
|
258
|
+
*
|
|
259
|
+
* @example
|
|
260
|
+
* ```ts
|
|
261
|
+
* jsStringEscape('say "hi"\nbye') // 'say \\"hi\\"\\nbye'
|
|
262
|
+
* ```
|
|
263
|
+
*/
|
|
264
|
+
function jsStringEscape(input) {
|
|
265
|
+
return `${input}`.replace(/["'\\\n\r\u2028\u2029]/g, (character) => {
|
|
266
|
+
switch (character) {
|
|
267
|
+
case "\"":
|
|
268
|
+
case "'":
|
|
269
|
+
case "\\": return `\\${character}`;
|
|
270
|
+
case "\n": return "\\n";
|
|
271
|
+
case "\r": return "\\r";
|
|
272
|
+
case "\u2028": return "\\u2028";
|
|
273
|
+
case "\u2029": return "\\u2029";
|
|
274
|
+
default: return "";
|
|
275
|
+
}
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
//#endregion
|
|
219
279
|
//#region src/constants.ts
|
|
220
280
|
/**
|
|
221
281
|
* `optionalType` values that cause a property's type to include `| undefined`.
|
|
@@ -756,7 +816,7 @@ function buildTupleNode(node, print) {
|
|
|
756
816
|
*/
|
|
757
817
|
function buildPropertyType(schema, baseType, optionalType, optional) {
|
|
758
818
|
const addsUndefined = OPTIONAL_ADDS_UNDEFINED.has(optionalType);
|
|
759
|
-
const meta = syncSchemaRef(schema);
|
|
819
|
+
const meta = ast.syncSchemaRef(schema);
|
|
760
820
|
let type = baseType;
|
|
761
821
|
if (meta.nullable) type = createUnionDeclaration({ nodes: [type, keywordTypeNodes.null] });
|
|
762
822
|
if ((optional || meta.nullish || meta.optional) && addsUndefined) type = createUnionDeclaration({ nodes: [type, keywordTypeNodes.undefined] });
|
|
@@ -800,10 +860,10 @@ function buildIndexSignatures(node, propertyCount, print) {
|
|
|
800
860
|
* resolve to the same name, which TypeScript merges into a single value+type declaration.
|
|
801
861
|
*/
|
|
802
862
|
function getEnumNames({ node, enum: enumOptions, resolver }) {
|
|
803
|
-
const resolved = resolver.
|
|
863
|
+
const resolved = resolver.name(node.name);
|
|
804
864
|
return {
|
|
805
865
|
enumName: enumOptions.constCasing === "pascalCase" ? resolved : camelCase(node.name),
|
|
806
|
-
typeName: ENUM_TYPES_WITH_KEY_SUFFIX.has(enumOptions.type) ? resolver.
|
|
866
|
+
typeName: ENUM_TYPES_WITH_KEY_SUFFIX.has(enumOptions.type) ? resolver.enum.keyName(node, enumOptions.typeSuffix) : resolved
|
|
807
867
|
};
|
|
808
868
|
}
|
|
809
869
|
/**
|
|
@@ -1002,7 +1062,7 @@ function isSchemaOptional(schema) {
|
|
|
1002
1062
|
return Boolean("optional" in schema && schema.optional || "nullish" in schema && schema.nullish);
|
|
1003
1063
|
}
|
|
1004
1064
|
function buildPropertyJSDocComments(schema, optional) {
|
|
1005
|
-
const meta = syncSchemaRef(schema);
|
|
1065
|
+
const meta = ast.syncSchemaRef(schema);
|
|
1006
1066
|
const isArray = meta?.primitive === "array";
|
|
1007
1067
|
const hasDescription = meta && "description" in meta && meta.description;
|
|
1008
1068
|
const formatComment = meta && "format" in meta && meta.format ? hasDescription ? [" ", `Format: \`${meta.format}\``] : ["@description", `Format: \`${meta.format}\``] : [];
|
|
@@ -1019,21 +1079,25 @@ function buildPropertyJSDocComments(schema, optional) {
|
|
|
1019
1079
|
meta && "primitive" in meta && meta.primitive ? [`@type ${meta.primitive}`, optional ?? isSchemaOptional(schema) ? " | undefined" : null].filter(Boolean).join("") : null
|
|
1020
1080
|
].filter(Boolean);
|
|
1021
1081
|
}
|
|
1022
|
-
|
|
1082
|
+
/**
|
|
1083
|
+
* Builds the object schema for a group of parameters sharing one `in` location (path, query, or
|
|
1084
|
+
* header), embedding each param's own schema (and JSDoc) directly rather than referencing a
|
|
1085
|
+
* separate per-param type — the group itself is the only type these params get exported as.
|
|
1086
|
+
*/
|
|
1087
|
+
function buildParams({ params }) {
|
|
1023
1088
|
return ast.factory.createSchema({
|
|
1024
1089
|
type: "object",
|
|
1025
1090
|
properties: params.map((param) => ast.factory.createProperty({
|
|
1026
1091
|
name: param.name,
|
|
1027
1092
|
required: param.required,
|
|
1028
1093
|
schema: ast.factory.createSchema({
|
|
1029
|
-
|
|
1030
|
-
name: resolver.resolveParamName(node, param),
|
|
1094
|
+
...param.schema,
|
|
1031
1095
|
optional: !param.required
|
|
1032
1096
|
})
|
|
1033
1097
|
}))
|
|
1034
1098
|
});
|
|
1035
1099
|
}
|
|
1036
|
-
function
|
|
1100
|
+
function buildOptions(node, { resolver }) {
|
|
1037
1101
|
const { path: pathParams, query: queryParams, header: headerParams } = getOperationParameters(node, { paramsCasing: "original" });
|
|
1038
1102
|
const hasBody = Boolean(node.requestBody?.content?.[0]?.schema);
|
|
1039
1103
|
const hasRequiredPath = pathParams.some((param) => param.required);
|
|
@@ -1048,7 +1112,7 @@ function buildData(node, { resolver }) {
|
|
|
1048
1112
|
required: hasBody,
|
|
1049
1113
|
schema: hasBody ? ast.factory.createSchema({
|
|
1050
1114
|
type: "ref",
|
|
1051
|
-
name: resolver.
|
|
1115
|
+
name: resolver.response.body(node)
|
|
1052
1116
|
}) : ast.factory.createSchema({
|
|
1053
1117
|
type: "never",
|
|
1054
1118
|
primitive: void 0,
|
|
@@ -1059,10 +1123,8 @@ function buildData(node, { resolver }) {
|
|
|
1059
1123
|
name: "path",
|
|
1060
1124
|
required: hasRequiredPath,
|
|
1061
1125
|
schema: pathParams.length > 0 ? ast.factory.createSchema({
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
resolver
|
|
1065
|
-
}),
|
|
1126
|
+
type: "ref",
|
|
1127
|
+
name: resolver.param.path(node, pathParams[0]),
|
|
1066
1128
|
optional: !hasRequiredPath
|
|
1067
1129
|
}) : ast.factory.createSchema({
|
|
1068
1130
|
type: "never",
|
|
@@ -1074,10 +1136,8 @@ function buildData(node, { resolver }) {
|
|
|
1074
1136
|
name: "query",
|
|
1075
1137
|
required: hasRequiredQuery,
|
|
1076
1138
|
schema: queryParams.length > 0 ? ast.factory.createSchema({
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
resolver
|
|
1080
|
-
}),
|
|
1139
|
+
type: "ref",
|
|
1140
|
+
name: resolver.param.query(node, queryParams[0]),
|
|
1081
1141
|
optional: !hasRequiredQuery
|
|
1082
1142
|
}) : ast.factory.createSchema({
|
|
1083
1143
|
type: "never",
|
|
@@ -1089,10 +1149,8 @@ function buildData(node, { resolver }) {
|
|
|
1089
1149
|
name: "headers",
|
|
1090
1150
|
required: hasRequiredHeader,
|
|
1091
1151
|
schema: headerParams.length > 0 ? ast.factory.createSchema({
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
resolver
|
|
1095
|
-
}),
|
|
1152
|
+
type: "ref",
|
|
1153
|
+
name: resolver.param.headers(node, headerParams[0]),
|
|
1096
1154
|
optional: !hasRequiredHeader
|
|
1097
1155
|
}) : ast.factory.createSchema({
|
|
1098
1156
|
type: "never",
|
|
@@ -1110,7 +1168,7 @@ function buildData(node, { resolver }) {
|
|
|
1110
1168
|
* query hooks and `result.data` use.
|
|
1111
1169
|
*/
|
|
1112
1170
|
function buildResponseRecordEntry(node, res, resolver) {
|
|
1113
|
-
const statusName = resolver.
|
|
1171
|
+
const statusName = resolver.response.status(node, res.statusCode);
|
|
1114
1172
|
const variants = (res.content ?? []).filter((entry) => entry.schema);
|
|
1115
1173
|
if (variants.length <= 1) return ast.factory.createSchema({
|
|
1116
1174
|
type: "ref",
|
|
@@ -1155,7 +1213,7 @@ function buildResponseUnion(node, { resolver }) {
|
|
|
1155
1213
|
type: "union",
|
|
1156
1214
|
members: responsesWithSchema.map((res) => ast.factory.createSchema({
|
|
1157
1215
|
type: "ref",
|
|
1158
|
-
name: resolver.
|
|
1216
|
+
name: resolver.response.status(node, res.statusCode)
|
|
1159
1217
|
}))
|
|
1160
1218
|
});
|
|
1161
1219
|
}
|
|
@@ -1248,8 +1306,8 @@ const printerTs = ast.createPrinter((options) => {
|
|
|
1248
1306
|
time: dateOrStringNode,
|
|
1249
1307
|
ref(node) {
|
|
1250
1308
|
if (!node.name) return null;
|
|
1251
|
-
const refName = node.ref ? this.options.nameMapping?.get(node.ref) ?? extractRefName(node.ref) ?? node.name : node.name;
|
|
1252
|
-
return createTypeReferenceNode(node.ref && ENUM_TYPES_WITH_KEY_SUFFIX.has(this.options.enum.type) && this.options.enum.typeSuffix && this.options.enumSchemaNames?.has(refName) ? this.options.resolver.
|
|
1309
|
+
const refName = node.ref ? this.options.nameMapping?.get(node.ref) ?? ast.extractRefName(node.ref) ?? node.name : node.name;
|
|
1310
|
+
return createTypeReferenceNode(node.ref && ENUM_TYPES_WITH_KEY_SUFFIX.has(this.options.enum.type) && this.options.enum.typeSuffix && this.options.enumSchemaNames?.has(refName) ? this.options.resolver.enum.keyName({ name: refName }, this.options.enum.typeSuffix) : node.ref ? this.options.resolver.name(refName) : refName, void 0);
|
|
1253
1311
|
},
|
|
1254
1312
|
enum(node) {
|
|
1255
1313
|
const values = node.namedEnumValues?.map((v) => v.value) ?? node.enumValues ?? [];
|
|
@@ -1257,18 +1315,18 @@ const printerTs = ast.createPrinter((options) => {
|
|
|
1257
1315
|
withParentheses: true,
|
|
1258
1316
|
nodes: values.filter((v) => v !== null && v !== void 0).map((value) => constToTypeNode(value, typeof value)).filter(isNonNullable)
|
|
1259
1317
|
}) ?? void 0;
|
|
1260
|
-
return createTypeReferenceNode(ENUM_TYPES_WITH_KEY_SUFFIX.has(this.options.enum.type) && this.options.enum.typeSuffix ? this.options.resolver.
|
|
1318
|
+
return createTypeReferenceNode(ENUM_TYPES_WITH_KEY_SUFFIX.has(this.options.enum.type) && this.options.enum.typeSuffix ? this.options.resolver.enum.keyName(node, this.options.enum.typeSuffix) : this.options.resolver.name(node.name), void 0);
|
|
1261
1319
|
},
|
|
1262
1320
|
union(node) {
|
|
1263
1321
|
const members = node.members ?? [];
|
|
1264
1322
|
const hasStringLiteral = members.some((m) => {
|
|
1265
1323
|
return ast.narrowSchema(m, ast.schemaTypes.enum)?.primitive === "string";
|
|
1266
1324
|
});
|
|
1267
|
-
const hasPlainString = members.some((m) => isStringType(m));
|
|
1325
|
+
const hasPlainString = members.some((m) => ast.isStringType(m));
|
|
1268
1326
|
if (hasStringLiteral && hasPlainString) return createUnionDeclaration({
|
|
1269
1327
|
withParentheses: true,
|
|
1270
1328
|
nodes: members.map((m) => {
|
|
1271
|
-
if (isStringType(m)) return createIntersectionDeclaration({
|
|
1329
|
+
if (ast.isStringType(m)) return createIntersectionDeclaration({
|
|
1272
1330
|
nodes: [keywordTypeNodes.string, createTypeLiteralNode([])],
|
|
1273
1331
|
withParentheses: true
|
|
1274
1332
|
});
|
|
@@ -1288,7 +1346,7 @@ const printerTs = ast.createPrinter((options) => {
|
|
|
1288
1346
|
},
|
|
1289
1347
|
array(node) {
|
|
1290
1348
|
return createArrayDeclaration({
|
|
1291
|
-
nodes: mapSchemaItems(node, (item) => this.transform(item)).map(({ output }) => output).filter(isNonNullable),
|
|
1349
|
+
nodes: ast.mapSchemaItems(node, (item) => this.transform(item)).map(({ output }) => output).filter(isNonNullable),
|
|
1292
1350
|
arrayType: this.options.arrayType
|
|
1293
1351
|
}) ?? null;
|
|
1294
1352
|
},
|
|
@@ -1298,11 +1356,11 @@ const printerTs = ast.createPrinter((options) => {
|
|
|
1298
1356
|
object(node) {
|
|
1299
1357
|
const { transform, options } = this;
|
|
1300
1358
|
const addsQuestionToken = OPTIONAL_ADDS_QUESTION_TOKEN.has(options.optionalType);
|
|
1301
|
-
const propertyNodes = mapSchemaProperties(node, (schema) => transform(schema)).map(({ name, property, output }) => {
|
|
1359
|
+
const propertyNodes = ast.mapSchemaProperties(node, (schema) => transform(schema)).map(({ name, property, output }) => {
|
|
1302
1360
|
const baseType = output ?? keywordTypeNodes.unknown;
|
|
1303
1361
|
const optional = !property.required || !!property.schema.optional || !!property.schema.nullish;
|
|
1304
1362
|
const type = buildPropertyType(property.schema, baseType, options.optionalType, optional);
|
|
1305
|
-
const propMeta = syncSchemaRef(property.schema);
|
|
1363
|
+
const propMeta = ast.syncSchemaRef(property.schema);
|
|
1306
1364
|
return appendJSDocToNode({
|
|
1307
1365
|
node: createPropertySignature({
|
|
1308
1366
|
questionToken: optional ? addsQuestionToken : false,
|
|
@@ -1323,7 +1381,7 @@ const printerTs = ast.createPrinter((options) => {
|
|
|
1323
1381
|
const { name, syntaxType = "type", description, keysToOmit } = this.options;
|
|
1324
1382
|
const transformed = this.transform(node);
|
|
1325
1383
|
if (!transformed) return null;
|
|
1326
|
-
const meta = syncSchemaRef(node);
|
|
1384
|
+
const meta = ast.syncSchemaRef(node);
|
|
1327
1385
|
if (!name) {
|
|
1328
1386
|
const withNullable = meta.nullable ? createUnionDeclaration({ nodes: [transformed, keywordTypeNodes.null] }) : transformed;
|
|
1329
1387
|
const result = (meta.nullish || meta.optional) && addsUndefined ? createUnionDeclaration({ nodes: [withNullable, keywordTypeNodes.undefined] }) : withNullable;
|
|
@@ -1369,15 +1427,14 @@ const typeGenerator = defineGenerator({
|
|
|
1369
1427
|
if (!node.name) return;
|
|
1370
1428
|
const enumSchemaNames = new Set(ctx.meta.enumNames);
|
|
1371
1429
|
function resolveImportName(schemaName) {
|
|
1372
|
-
if (ENUM_TYPES_WITH_KEY_SUFFIX.has(enumOptions.type) && enumOptions.typeSuffix && enumSchemaNames.has(schemaName)) return resolver.
|
|
1373
|
-
return resolver.
|
|
1430
|
+
if (ENUM_TYPES_WITH_KEY_SUFFIX.has(enumOptions.type) && enumOptions.typeSuffix && enumSchemaNames.has(schemaName)) return resolver.enum.keyName({ name: schemaName }, enumOptions.typeSuffix);
|
|
1431
|
+
return resolver.name(schemaName);
|
|
1374
1432
|
}
|
|
1375
1433
|
const imports = adapter.getImports(node, (schemaName) => ({
|
|
1376
1434
|
name: resolveImportName(schemaName),
|
|
1377
|
-
path: resolver.
|
|
1435
|
+
path: resolver.file({
|
|
1378
1436
|
name: schemaName,
|
|
1379
|
-
extname: ".ts"
|
|
1380
|
-
}, {
|
|
1437
|
+
extname: ".ts",
|
|
1381
1438
|
root,
|
|
1382
1439
|
output,
|
|
1383
1440
|
group: group ?? void 0
|
|
@@ -1386,11 +1443,10 @@ const typeGenerator = defineGenerator({
|
|
|
1386
1443
|
const enumNode = ast.narrowSchema(node, ast.schemaTypes.enum);
|
|
1387
1444
|
const isEnumSchema = !!enumNode && !isInlineConstEnum(enumNode, enumSchemaNames);
|
|
1388
1445
|
const meta = {
|
|
1389
|
-
name: ENUM_TYPES_WITH_KEY_SUFFIX.has(enumOptions.type) && isEnumSchema ? resolver.
|
|
1390
|
-
file: resolver.
|
|
1446
|
+
name: ENUM_TYPES_WITH_KEY_SUFFIX.has(enumOptions.type) && isEnumSchema ? resolver.enum.keyName(node, enumOptions.typeSuffix) : resolver.name(node.name),
|
|
1447
|
+
file: resolver.file({
|
|
1391
1448
|
name: node.name,
|
|
1392
|
-
extname: ".ts"
|
|
1393
|
-
}, {
|
|
1449
|
+
extname: ".ts",
|
|
1394
1450
|
root,
|
|
1395
1451
|
output,
|
|
1396
1452
|
group: group ?? void 0
|
|
@@ -1412,7 +1468,7 @@ const typeGenerator = defineGenerator({
|
|
|
1412
1468
|
baseName: meta.file.baseName,
|
|
1413
1469
|
path: meta.file.path,
|
|
1414
1470
|
meta: meta.file.meta,
|
|
1415
|
-
banner: resolver.
|
|
1471
|
+
banner: resolver.default.banner(ctx.meta, {
|
|
1416
1472
|
output,
|
|
1417
1473
|
config,
|
|
1418
1474
|
file: {
|
|
@@ -1420,7 +1476,7 @@ const typeGenerator = defineGenerator({
|
|
|
1420
1476
|
baseName: meta.file.baseName
|
|
1421
1477
|
}
|
|
1422
1478
|
}),
|
|
1423
|
-
footer: resolver.
|
|
1479
|
+
footer: resolver.default.footer(ctx.meta, {
|
|
1424
1480
|
output,
|
|
1425
1481
|
config,
|
|
1426
1482
|
file: {
|
|
@@ -1450,29 +1506,27 @@ const typeGenerator = defineGenerator({
|
|
|
1450
1506
|
const { enum: enumOptions, optionalType, arrayType, syntaxType, group, output, printer } = ctx.options;
|
|
1451
1507
|
const { adapter, config, resolver, root } = ctx;
|
|
1452
1508
|
const params = caseParams(node.parameters, "camelcase");
|
|
1453
|
-
const meta = { file: resolver.
|
|
1509
|
+
const meta = { file: resolver.file({
|
|
1454
1510
|
name: node.operationId,
|
|
1455
1511
|
extname: ".ts",
|
|
1456
1512
|
tag: node.tags[0] ?? "default",
|
|
1457
|
-
path: node.path
|
|
1458
|
-
}, {
|
|
1513
|
+
path: node.path,
|
|
1459
1514
|
root,
|
|
1460
1515
|
output,
|
|
1461
1516
|
group: group ?? void 0
|
|
1462
1517
|
}) };
|
|
1463
1518
|
const enumSchemaNames = new Set(ctx.meta.enumNames);
|
|
1464
1519
|
function resolveImportName(schemaName) {
|
|
1465
|
-
if (ENUM_TYPES_WITH_KEY_SUFFIX.has(enumOptions.type) && enumOptions.typeSuffix && enumSchemaNames.has(schemaName)) return resolver.
|
|
1466
|
-
return resolver.
|
|
1520
|
+
if (ENUM_TYPES_WITH_KEY_SUFFIX.has(enumOptions.type) && enumOptions.typeSuffix && enumSchemaNames.has(schemaName)) return resolver.enum.keyName({ name: schemaName }, enumOptions.typeSuffix);
|
|
1521
|
+
return resolver.name(schemaName);
|
|
1467
1522
|
}
|
|
1468
1523
|
function renderSchemaType({ schema, name, keysToOmit }) {
|
|
1469
1524
|
if (!schema) return null;
|
|
1470
1525
|
const imports = adapter.getImports(schema, (schemaName) => ({
|
|
1471
1526
|
name: resolveImportName(schemaName),
|
|
1472
|
-
path: resolver.
|
|
1527
|
+
path: resolver.file({
|
|
1473
1528
|
name: schemaName,
|
|
1474
|
-
extname: ".ts"
|
|
1475
|
-
}, {
|
|
1529
|
+
extname: ".ts",
|
|
1476
1530
|
root,
|
|
1477
1531
|
output,
|
|
1478
1532
|
group: group ?? void 0
|
|
@@ -1532,13 +1586,24 @@ const typeGenerator = defineGenerator({
|
|
|
1532
1586
|
name: baseName
|
|
1533
1587
|
})] });
|
|
1534
1588
|
}
|
|
1535
|
-
const
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1589
|
+
const { path: pathParams, query: queryParams, header: headerParams } = getOperationParameters({
|
|
1590
|
+
...node,
|
|
1591
|
+
parameters: params
|
|
1592
|
+
}, { paramsCasing: "original" });
|
|
1593
|
+
const paramGroupTypes = [
|
|
1594
|
+
pathParams.length > 0 && renderSchemaType({
|
|
1595
|
+
schema: buildParams({ params: pathParams }),
|
|
1596
|
+
name: resolver.param.path(node, pathParams[0])
|
|
1597
|
+
}),
|
|
1598
|
+
queryParams.length > 0 && renderSchemaType({
|
|
1599
|
+
schema: buildParams({ params: queryParams }),
|
|
1600
|
+
name: resolver.param.query(node, queryParams[0])
|
|
1601
|
+
}),
|
|
1602
|
+
headerParams.length > 0 && renderSchemaType({
|
|
1603
|
+
schema: buildParams({ params: headerParams }),
|
|
1604
|
+
name: resolver.param.headers(node, headerParams[0])
|
|
1605
|
+
})
|
|
1606
|
+
];
|
|
1542
1607
|
const requestBodyContent = node.requestBody?.content ?? [];
|
|
1543
1608
|
function buildRequestType() {
|
|
1544
1609
|
if (requestBodyContent.length === 0) return null;
|
|
@@ -1550,11 +1615,11 @@ const typeGenerator = defineGenerator({
|
|
|
1550
1615
|
...entry.schema,
|
|
1551
1616
|
description: node.requestBody.description ?? entry.schema.description
|
|
1552
1617
|
},
|
|
1553
|
-
name: resolver.
|
|
1618
|
+
name: resolver.response.body(node),
|
|
1554
1619
|
keysToOmit: entry.keysToOmit
|
|
1555
1620
|
});
|
|
1556
1621
|
}
|
|
1557
|
-
return buildContentTypeVariants(requestBodyContent, resolver.
|
|
1622
|
+
return buildContentTypeVariants(requestBodyContent, resolver.response.body(node), (schema) => ({
|
|
1558
1623
|
...schema,
|
|
1559
1624
|
description: node.requestBody.description ?? schema.description
|
|
1560
1625
|
}));
|
|
@@ -1562,29 +1627,29 @@ const typeGenerator = defineGenerator({
|
|
|
1562
1627
|
const requestType = buildRequestType();
|
|
1563
1628
|
const responseTypes = node.responses.map((res) => {
|
|
1564
1629
|
const variants = (res.content ?? []).filter((entry) => entry.schema);
|
|
1565
|
-
if (variants.length > 1) return buildContentTypeVariants(variants, resolver.
|
|
1630
|
+
if (variants.length > 1) return buildContentTypeVariants(variants, resolver.response.status(node, res.statusCode));
|
|
1566
1631
|
const primary = variants[0] ?? res.content?.[0];
|
|
1567
1632
|
return renderSchemaType({
|
|
1568
1633
|
schema: primary?.schema ?? null,
|
|
1569
|
-
name: resolver.
|
|
1634
|
+
name: resolver.response.status(node, res.statusCode),
|
|
1570
1635
|
keysToOmit: primary?.keysToOmit
|
|
1571
1636
|
});
|
|
1572
1637
|
});
|
|
1573
|
-
const
|
|
1574
|
-
schema:
|
|
1638
|
+
const optionsType = renderSchemaType({
|
|
1639
|
+
schema: buildOptions({
|
|
1575
1640
|
...node,
|
|
1576
1641
|
parameters: params
|
|
1577
1642
|
}, { resolver }),
|
|
1578
|
-
name: resolver.
|
|
1643
|
+
name: resolver.response.options(node)
|
|
1579
1644
|
});
|
|
1580
1645
|
const responsesType = renderSchemaType({
|
|
1581
1646
|
schema: buildResponses(node, { resolver }),
|
|
1582
|
-
name: resolver.
|
|
1647
|
+
name: resolver.response.responses(node)
|
|
1583
1648
|
});
|
|
1584
1649
|
function buildResponseType() {
|
|
1585
1650
|
const hasSchema = (res) => (res.content ?? []).some((entry) => entry.schema);
|
|
1586
1651
|
if (!node.responses.some(hasSchema)) return null;
|
|
1587
|
-
const responseName = resolver.
|
|
1652
|
+
const responseName = resolver.response.response(node);
|
|
1588
1653
|
const responsesWithSchema = node.responses.filter(hasSchema);
|
|
1589
1654
|
if (new Set(responsesWithSchema.flatMap((res) => (res.content ?? []).flatMap((entry) => entry.schema ? adapter.getImports(entry.schema, (schemaName) => ({
|
|
1590
1655
|
name: resolveImportName(schemaName),
|
|
@@ -1603,7 +1668,7 @@ const typeGenerator = defineGenerator({
|
|
|
1603
1668
|
baseName: meta.file.baseName,
|
|
1604
1669
|
path: meta.file.path,
|
|
1605
1670
|
meta: meta.file.meta,
|
|
1606
|
-
banner: resolver.
|
|
1671
|
+
banner: resolver.default.banner(ctx.meta, {
|
|
1607
1672
|
output,
|
|
1608
1673
|
config,
|
|
1609
1674
|
file: {
|
|
@@ -1611,7 +1676,7 @@ const typeGenerator = defineGenerator({
|
|
|
1611
1676
|
baseName: meta.file.baseName
|
|
1612
1677
|
}
|
|
1613
1678
|
}),
|
|
1614
|
-
footer: resolver.
|
|
1679
|
+
footer: resolver.default.footer(ctx.meta, {
|
|
1615
1680
|
output,
|
|
1616
1681
|
config,
|
|
1617
1682
|
file: {
|
|
@@ -1620,10 +1685,10 @@ const typeGenerator = defineGenerator({
|
|
|
1620
1685
|
}
|
|
1621
1686
|
}),
|
|
1622
1687
|
children: [
|
|
1623
|
-
|
|
1688
|
+
paramGroupTypes,
|
|
1624
1689
|
responseTypes,
|
|
1625
1690
|
requestType,
|
|
1626
|
-
|
|
1691
|
+
optionsType,
|
|
1627
1692
|
responsesType,
|
|
1628
1693
|
responseType
|
|
1629
1694
|
]
|
|
@@ -1638,64 +1703,61 @@ const typeGenerator = defineGenerator({
|
|
|
1638
1703
|
* to reference the exact names `plugin-ts` produces without duplicating the
|
|
1639
1704
|
* casing/file-layout rules.
|
|
1640
1705
|
*
|
|
1641
|
-
* The `default`
|
|
1642
|
-
* type names and PascalCase file paths (dotted names
|
|
1706
|
+
* The `default` helpers are supplied by `createResolver`. This plugin overrides the top-level `name`
|
|
1707
|
+
* to use PascalCase for value and type names and `file` to write PascalCase file paths (dotted names
|
|
1708
|
+
* become `/`-joined), and groups the operation-specific naming under the `param`, `response`, and
|
|
1709
|
+
* `enum` namespaces.
|
|
1643
1710
|
*
|
|
1644
1711
|
* @example Resolve a type and file name
|
|
1645
1712
|
* ```ts
|
|
1646
1713
|
* import { resolverTs } from '@kubb/plugin-ts'
|
|
1647
1714
|
*
|
|
1648
|
-
* resolverTs.
|
|
1649
|
-
* resolverTs.
|
|
1650
|
-
* resolverTs.resolveResponseStatusName(node, 200) // 'ListPetsStatus200'
|
|
1715
|
+
* resolverTs.name('list pets') // 'ListPets'
|
|
1716
|
+
* resolverTs.response.status(node, 200) // 'ListPetsStatus200'
|
|
1651
1717
|
* ```
|
|
1652
1718
|
*/
|
|
1653
|
-
const resolverTs =
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
resolvePathName(name, type) {
|
|
1665
|
-
if (type === "file") return toFilePath(name, pascalCase);
|
|
1666
|
-
return ensureValidVarName(pascalCase(name));
|
|
1667
|
-
},
|
|
1668
|
-
resolveParamName(node, param) {
|
|
1669
|
-
return this.resolveTypeName(`${node.operationId} ${param.in} ${param.name}`);
|
|
1670
|
-
},
|
|
1671
|
-
resolveResponseStatusName(node, statusCode) {
|
|
1672
|
-
return this.resolveTypeName(`${node.operationId} Status ${statusCode}`);
|
|
1673
|
-
},
|
|
1674
|
-
resolveDataName(node) {
|
|
1675
|
-
return this.resolveTypeName(`${node.operationId} Data`);
|
|
1719
|
+
const resolverTs = createResolver({
|
|
1720
|
+
pluginName: "plugin-ts",
|
|
1721
|
+
name(name) {
|
|
1722
|
+
return ensureValidVarName(pascalCase(name));
|
|
1723
|
+
},
|
|
1724
|
+
file: { baseName({ name, extname }) {
|
|
1725
|
+
return `${toFilePath(name, pascalCase)}${extname}`;
|
|
1726
|
+
} },
|
|
1727
|
+
param: {
|
|
1728
|
+
name(node, param) {
|
|
1729
|
+
return this.name(`${node.operationId} ${param.in} ${param.name}`);
|
|
1676
1730
|
},
|
|
1677
|
-
|
|
1678
|
-
return this.
|
|
1731
|
+
path(node) {
|
|
1732
|
+
return this.name(`${node.operationId} Path`);
|
|
1679
1733
|
},
|
|
1680
|
-
|
|
1681
|
-
return this.
|
|
1734
|
+
query(node) {
|
|
1735
|
+
return this.name(`${node.operationId} Query`);
|
|
1682
1736
|
},
|
|
1683
|
-
|
|
1684
|
-
return this.
|
|
1737
|
+
headers(node) {
|
|
1738
|
+
return this.name(`${node.operationId} Headers`);
|
|
1739
|
+
}
|
|
1740
|
+
},
|
|
1741
|
+
response: {
|
|
1742
|
+
status(node, statusCode) {
|
|
1743
|
+
return this.name(`${node.operationId} Status ${statusCode}`);
|
|
1685
1744
|
},
|
|
1686
|
-
|
|
1687
|
-
return
|
|
1745
|
+
options(node) {
|
|
1746
|
+
return this.name(`${node.operationId} Options`);
|
|
1688
1747
|
},
|
|
1689
|
-
|
|
1690
|
-
return this.
|
|
1748
|
+
responses(node) {
|
|
1749
|
+
return this.name(`${node.operationId} Responses`);
|
|
1691
1750
|
},
|
|
1692
|
-
|
|
1693
|
-
return this.
|
|
1751
|
+
response(node) {
|
|
1752
|
+
return this.name(`${node.operationId} Response`);
|
|
1694
1753
|
},
|
|
1695
|
-
|
|
1696
|
-
return this.
|
|
1754
|
+
body(node) {
|
|
1755
|
+
return this.name(`${node.operationId} Body`);
|
|
1697
1756
|
}
|
|
1698
|
-
}
|
|
1757
|
+
},
|
|
1758
|
+
enum: { keyName(node, enumTypeSuffix = "key") {
|
|
1759
|
+
return `${this.name(node.name ?? "")}${enumTypeSuffix}`;
|
|
1760
|
+
} }
|
|
1699
1761
|
});
|
|
1700
1762
|
//#endregion
|
|
1701
1763
|
//#region src/plugin.ts
|
|
@@ -1712,7 +1774,7 @@ const pluginTsName = "plugin-ts";
|
|
|
1712
1774
|
*
|
|
1713
1775
|
* @example
|
|
1714
1776
|
* ```ts
|
|
1715
|
-
* import { defineConfig } from 'kubb'
|
|
1777
|
+
* import { defineConfig } from 'kubb/config'
|
|
1716
1778
|
* import { pluginTs } from '@kubb/plugin-ts'
|
|
1717
1779
|
*
|
|
1718
1780
|
* export default defineConfig({
|
|
@@ -1756,10 +1818,7 @@ const pluginTs = definePlugin((options) => {
|
|
|
1756
1818
|
syntaxType,
|
|
1757
1819
|
printer
|
|
1758
1820
|
});
|
|
1759
|
-
ctx.setResolver(userResolver ?
|
|
1760
|
-
...resolverTs,
|
|
1761
|
-
...userResolver
|
|
1762
|
-
} : resolverTs);
|
|
1821
|
+
ctx.setResolver(userResolver ? Resolver.merge(resolverTs, userResolver) : resolverTs);
|
|
1763
1822
|
if (userMacros?.length) ctx.setMacros(userMacros);
|
|
1764
1823
|
ctx.addGenerator(typeGenerator);
|
|
1765
1824
|
} }
|
|
@@ -2020,12 +2079,12 @@ function functionPrinter(options) {
|
|
|
2020
2079
|
*/
|
|
2021
2080
|
function resolveParamType({ node, param, resolver }) {
|
|
2022
2081
|
if (!resolver) return param.schema.primitive ?? "unknown";
|
|
2023
|
-
const individualName = resolver.
|
|
2082
|
+
const individualName = resolver.param.name(node, param);
|
|
2024
2083
|
const groupLocation = param.in === "path" || param.in === "query" || param.in === "header" ? param.in : void 0;
|
|
2025
2084
|
const groupResolvers = {
|
|
2026
|
-
path: resolver.
|
|
2027
|
-
query: resolver.
|
|
2028
|
-
header: resolver.
|
|
2085
|
+
path: resolver.param.path,
|
|
2086
|
+
query: resolver.param.query,
|
|
2087
|
+
header: resolver.param.headers
|
|
2029
2088
|
};
|
|
2030
2089
|
const groupName = groupLocation ? groupResolvers[groupLocation].call(resolver, node, param) : void 0;
|
|
2031
2090
|
if (groupName && groupName !== individualName) return createIndexedAccessType({
|
|
@@ -2043,8 +2102,8 @@ function resolveParamType({ node, param, resolver }) {
|
|
|
2043
2102
|
function resolveGroupType({ node, params, group, resolver }) {
|
|
2044
2103
|
if (!resolver || !params.length) return null;
|
|
2045
2104
|
const firstParam = params[0];
|
|
2046
|
-
const groupName = (group === "query" ? resolver.
|
|
2047
|
-
if (groupName === resolver.
|
|
2105
|
+
const groupName = (group === "query" ? resolver.param.query : resolver.param.headers).call(resolver, node, firstParam);
|
|
2106
|
+
if (groupName === resolver.param.name(node, firstParam)) return null;
|
|
2048
2107
|
return {
|
|
2049
2108
|
type: groupName,
|
|
2050
2109
|
optional: params.every((p) => !p.required)
|
|
@@ -2080,7 +2139,7 @@ function createOperationParams(node, options) {
|
|
|
2080
2139
|
optional: !param.required
|
|
2081
2140
|
});
|
|
2082
2141
|
const emptyObjectDefault = (props) => props.every((p) => p.optional) ? "{}" : void 0;
|
|
2083
|
-
const bodyType = node.requestBody?.content?.[0]?.schema ? wrapType(resolver?.
|
|
2142
|
+
const bodyType = node.requestBody?.content?.[0]?.schema ? wrapType(resolver?.response.body(node) ?? "unknown") : void 0;
|
|
2084
2143
|
const bodyProperty = bodyType ? [{
|
|
2085
2144
|
name: dataName,
|
|
2086
2145
|
type: bodyType,
|
|
@@ -2124,7 +2183,7 @@ function createOperationParams(node, options) {
|
|
|
2124
2183
|
}));
|
|
2125
2184
|
} else {
|
|
2126
2185
|
if (pathParamsType === "inlineSpread" && pathParams.length) {
|
|
2127
|
-
const spreadType = resolver?.
|
|
2186
|
+
const spreadType = resolver?.param.path(node, pathParams[0]);
|
|
2128
2187
|
params.push(createFunctionParameter({
|
|
2129
2188
|
name: pathName,
|
|
2130
2189
|
type: spreadType ? wrapType(spreadType) : void 0,
|
|
@@ -2192,6 +2251,6 @@ function buildTypeLiteral({ node, params, resolver }) {
|
|
|
2192
2251
|
})) });
|
|
2193
2252
|
}
|
|
2194
2253
|
//#endregion
|
|
2195
|
-
export { Enum, Type, createFunctionParameter, createFunctionParameters, createIndexedAccessType, createObjectBindingPattern, createOperationParams, createTypeLiteral, pluginTs as default, pluginTs, functionPrinter, pluginTsName, printerTs, renderType, resolverTs, typeGenerator };
|
|
2254
|
+
export { Enum, Type, buildParams, createFunctionParameter, createFunctionParameters, createIndexedAccessType, createObjectBindingPattern, createOperationParams, createTypeLiteral, pluginTs as default, pluginTs, functionPrinter, pluginTsName, printerTs, renderType, resolverTs, typeGenerator };
|
|
2196
2255
|
|
|
2197
2256
|
//# sourceMappingURL=index.js.map
|