@kubb/plugin-ts 5.0.0-beta.85 → 5.0.0-beta.87
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 +78 -28
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -2
- package/dist/index.js +78 -28
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.cjs
CHANGED
|
@@ -231,7 +231,7 @@ const reservedWords = /* @__PURE__ */ new Set([
|
|
|
231
231
|
*/
|
|
232
232
|
function isValidVarName(name) {
|
|
233
233
|
if (!name || reservedWords.has(name)) return false;
|
|
234
|
-
return
|
|
234
|
+
return isIdentifier(name);
|
|
235
235
|
}
|
|
236
236
|
/**
|
|
237
237
|
* Returns `name` when it's a syntactically valid JavaScript variable name,
|
|
@@ -253,6 +253,22 @@ function ensureValidVarName(name) {
|
|
|
253
253
|
if (!name || isValidVarName(name)) return name;
|
|
254
254
|
return `_${name}`;
|
|
255
255
|
}
|
|
256
|
+
/**
|
|
257
|
+
* Returns `true` when `name` is syntactically a valid identifier, ignoring reserved words.
|
|
258
|
+
*
|
|
259
|
+
* Reserved words and globals (`class`, `name`, `Date`, …) are valid as bare object-literal keys
|
|
260
|
+
* even though they are not valid variable names, so use this (not {@link isValidVarName}) when
|
|
261
|
+
* deciding whether an object key needs quoting.
|
|
262
|
+
*
|
|
263
|
+
* @example
|
|
264
|
+
* ```ts
|
|
265
|
+
* isIdentifier('name') // true
|
|
266
|
+
* isIdentifier('x-total')// false
|
|
267
|
+
* ```
|
|
268
|
+
*/
|
|
269
|
+
function isIdentifier(name) {
|
|
270
|
+
return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
|
|
271
|
+
}
|
|
256
272
|
//#endregion
|
|
257
273
|
//#region ../../internals/utils/src/strings.ts
|
|
258
274
|
/**
|
|
@@ -565,7 +581,7 @@ function createInterfaceDeclaration({ modifiers, name, typeParameters, members }
|
|
|
565
581
|
* Intelligently selects the syntax based on the type structure and attaches JSDoc comments.
|
|
566
582
|
*/
|
|
567
583
|
function createTypeDeclaration({ syntax, isExportable, comments, name, type }) {
|
|
568
|
-
if (syntax === "interface" &&
|
|
584
|
+
if (syntax === "interface" && typescript.default.isTypeLiteralNode(type)) return appendJSDocToNode({
|
|
569
585
|
node: createInterfaceDeclaration({
|
|
570
586
|
members: [...type.members],
|
|
571
587
|
modifiers: isExportable ? [modifiers.export] : [],
|
|
@@ -664,7 +680,7 @@ function createEnumDeclaration({ type = "enum", name, typeName, enums, enumKeyCa
|
|
|
664
680
|
}).filter((node) => node !== void 0)))];
|
|
665
681
|
if (type === "enum" || type === "constEnum") return [void 0, factory.createEnumDeclaration([factory.createToken(typescript.default.SyntaxKind.ExportKeyword), type === "constEnum" ? factory.createToken(typescript.default.SyntaxKind.ConstKeyword) : void 0].filter((modifier) => modifier !== void 0), factory.createIdentifier(typeName), enums.map(([key, value, description]) => {
|
|
666
682
|
let initializer = factory.createStringLiteral(value?.toString());
|
|
667
|
-
if (Number.parseInt(value.toString(), 10) === value && isNumber(
|
|
683
|
+
if (Number.parseInt(value.toString(), 10) === value && isNumber(value)) if (value < 0) initializer = factory.createPrefixUnaryExpression(typescript.default.SyntaxKind.MinusToken, factory.createNumericLiteral(Math.abs(value)));
|
|
668
684
|
else initializer = factory.createNumericLiteral(value);
|
|
669
685
|
if (typeof value === "boolean") initializer = value ? factory.createTrue() : factory.createFalse();
|
|
670
686
|
if (isNumber(Number.parseInt(key.toString(), 10))) {
|
|
@@ -939,13 +955,13 @@ function Enum({ node, enum: enumOptions, resolver }) {
|
|
|
939
955
|
isExportable: true,
|
|
940
956
|
isIndexable: true,
|
|
941
957
|
isTypeOnly: false,
|
|
942
|
-
children: _kubb_parser_ts.parserTs.print(nameNode)
|
|
958
|
+
children: (0, _kubb_parser_ts.parserTs)().print(nameNode)
|
|
943
959
|
}), /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Source, {
|
|
944
960
|
name: typeName,
|
|
945
961
|
isIndexable: !namesMerge,
|
|
946
962
|
isExportable: !namesMerge && ENUM_TYPES_WITH_RUNTIME_VALUE.has(enumOptions.type),
|
|
947
963
|
isTypeOnly: ENUM_TYPES_WITH_TYPE_ONLY.has(enumOptions.type),
|
|
948
|
-
children: _kubb_parser_ts.parserTs.print(typeNode)
|
|
964
|
+
children: (0, _kubb_parser_ts.parserTs)().print(typeNode)
|
|
949
965
|
})] });
|
|
950
966
|
}
|
|
951
967
|
//#endregion
|
|
@@ -1046,6 +1062,24 @@ function getOperationParameters(node, options = {}) {
|
|
|
1046
1062
|
};
|
|
1047
1063
|
}
|
|
1048
1064
|
//#endregion
|
|
1065
|
+
//#region ../../internals/shared/src/adapter.ts
|
|
1066
|
+
/**
|
|
1067
|
+
* Narrows the generic `Adapter` from a generator context to the OpenAPI adapter,
|
|
1068
|
+
* so OAS-only options (`dateType`, `nameMapping`) and the parsed `document` are typed.
|
|
1069
|
+
*
|
|
1070
|
+
* Throws when a non-OAS adapter is configured, turning a silently wrong cast into a
|
|
1071
|
+
* clear, actionable error at the point of use.
|
|
1072
|
+
*
|
|
1073
|
+
* @example
|
|
1074
|
+
* ```ts
|
|
1075
|
+
* const { dateType } = getOasAdapter(ctx.adapter).options
|
|
1076
|
+
* ```
|
|
1077
|
+
*/
|
|
1078
|
+
function getOasAdapter(adapter) {
|
|
1079
|
+
if (adapter.name !== "oas") throw new Error(`Expected the OpenAPI adapter (adapterOas), but received "${adapter.name}". Configure \`adapter: adapterOas()\` in your Kubb config.`);
|
|
1080
|
+
return adapter;
|
|
1081
|
+
}
|
|
1082
|
+
//#endregion
|
|
1049
1083
|
//#region ../../internals/shared/src/group.ts
|
|
1050
1084
|
/**
|
|
1051
1085
|
* Builds the `group` config a Kubb plugin passes to `ctx.setOptions`, applying the
|
|
@@ -1113,7 +1147,7 @@ function buildPropertyJSDocComments(schema, optional) {
|
|
|
1113
1147
|
!isArray && meta && "min" in meta && meta.min !== void 0 ? `@minLength ${meta.min}` : null,
|
|
1114
1148
|
!isArray && meta && "max" in meta && meta.max !== void 0 ? `@maxLength ${meta.max}` : null,
|
|
1115
1149
|
meta && "pattern" in meta && meta.pattern ? `@pattern ${meta.pattern}` : null,
|
|
1116
|
-
meta && "default" in meta && meta.default !== void 0 ? `@default ${"primitive" in meta && meta.primitive === "string" ? stringify(meta.default) : meta.default}` : null,
|
|
1150
|
+
meta && "default" in meta && meta.default !== void 0 ? `@default ${"primitive" in meta && meta.primitive === "string" && typeof meta.default === "string" ? stringify(meta.default) : meta.default}` : null,
|
|
1117
1151
|
...exampleValues.map((example) => `@example ${example}`),
|
|
1118
1152
|
meta && "primitive" in meta && meta.primitive ? [`@type ${meta.primitive}`, optional ?? isSchemaOptional(schema) ? " | undefined" : null].filter(Boolean).join("") : null
|
|
1119
1153
|
].filter(Boolean);
|
|
@@ -1424,7 +1458,7 @@ const printerTs = kubb_kit.ast.createPrinter((options) => {
|
|
|
1424
1458
|
if (!name) {
|
|
1425
1459
|
const withNullable = meta.nullable ? createUnionDeclaration({ nodes: [transformed, keywordTypeNodes.null] }) : transformed;
|
|
1426
1460
|
const result = (meta.nullish || meta.optional) && addsUndefined ? createUnionDeclaration({ nodes: [withNullable, keywordTypeNodes.undefined] }) : withNullable;
|
|
1427
|
-
return _kubb_parser_ts.parserTs.print(result);
|
|
1461
|
+
return (0, _kubb_parser_ts.parserTs)().print(result);
|
|
1428
1462
|
}
|
|
1429
1463
|
const inner = (() => {
|
|
1430
1464
|
const omitted = keysToOmit?.length ? createOmitDeclaration({
|
|
@@ -1445,13 +1479,22 @@ const printerTs = kubb_kit.ast.createPrinter((options) => {
|
|
|
1445
1479
|
description
|
|
1446
1480
|
})
|
|
1447
1481
|
});
|
|
1448
|
-
return _kubb_parser_ts.parserTs.print(typeNode);
|
|
1482
|
+
return (0, _kubb_parser_ts.parserTs)().print(typeNode);
|
|
1449
1483
|
}
|
|
1450
1484
|
};
|
|
1451
1485
|
});
|
|
1452
1486
|
//#endregion
|
|
1453
1487
|
//#region src/generators/typeGenerator.tsx
|
|
1454
1488
|
/**
|
|
1489
|
+
* Resolves the imported type name for a referenced schema. An enum schema emitted
|
|
1490
|
+
* as a `const` object imports its suffixed key alias (e.g. `StatusKey`); every other
|
|
1491
|
+
* schema imports its plain resolved name.
|
|
1492
|
+
*/
|
|
1493
|
+
function resolveImportName({ schemaName, enumOptions, enumSchemaNames, resolver }) {
|
|
1494
|
+
if (ENUM_TYPES_WITH_KEY_SUFFIX.has(enumOptions.type) && enumOptions.typeSuffix && enumSchemaNames.has(schemaName)) return resolver.enum.keyName({ name: schemaName }, enumOptions.typeSuffix);
|
|
1495
|
+
return resolver.name(schemaName);
|
|
1496
|
+
}
|
|
1497
|
+
/**
|
|
1455
1498
|
* Built-in generator for `@kubb/plugin-ts`. Emits one TypeScript file per
|
|
1456
1499
|
* schema in the spec plus per-operation request, response, and parameter
|
|
1457
1500
|
* types. Drop-replace with a custom `Generator<PluginTs>` to change how
|
|
@@ -1465,12 +1508,13 @@ const typeGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1465
1508
|
const { adapter, config, resolver, root } = ctx;
|
|
1466
1509
|
if (!node.name) return;
|
|
1467
1510
|
const enumSchemaNames = new Set(ctx.meta.enumNames);
|
|
1468
|
-
function resolveImportName(schemaName) {
|
|
1469
|
-
if (ENUM_TYPES_WITH_KEY_SUFFIX.has(enumOptions.type) && enumOptions.typeSuffix && enumSchemaNames.has(schemaName)) return resolver.enum.keyName({ name: schemaName }, enumOptions.typeSuffix);
|
|
1470
|
-
return resolver.name(schemaName);
|
|
1471
|
-
}
|
|
1472
1511
|
const imports = adapter.getImports(node, (schemaName) => ({
|
|
1473
|
-
name: resolveImportName(
|
|
1512
|
+
name: resolveImportName({
|
|
1513
|
+
schemaName,
|
|
1514
|
+
enumOptions,
|
|
1515
|
+
enumSchemaNames,
|
|
1516
|
+
resolver
|
|
1517
|
+
}),
|
|
1474
1518
|
path: resolver.file({
|
|
1475
1519
|
name: schemaName,
|
|
1476
1520
|
extname: ".ts",
|
|
@@ -1500,7 +1544,7 @@ const typeGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1500
1544
|
description: node.description,
|
|
1501
1545
|
resolver,
|
|
1502
1546
|
enumSchemaNames,
|
|
1503
|
-
nameMapping: adapter.options.nameMapping,
|
|
1547
|
+
nameMapping: getOasAdapter(adapter).options.nameMapping,
|
|
1504
1548
|
nodes: printer?.nodes
|
|
1505
1549
|
});
|
|
1506
1550
|
return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx.File, {
|
|
@@ -1555,14 +1599,15 @@ const typeGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1555
1599
|
group: group ?? void 0
|
|
1556
1600
|
}) };
|
|
1557
1601
|
const enumSchemaNames = new Set(ctx.meta.enumNames);
|
|
1558
|
-
function resolveImportName(schemaName) {
|
|
1559
|
-
if (ENUM_TYPES_WITH_KEY_SUFFIX.has(enumOptions.type) && enumOptions.typeSuffix && enumSchemaNames.has(schemaName)) return resolver.enum.keyName({ name: schemaName }, enumOptions.typeSuffix);
|
|
1560
|
-
return resolver.name(schemaName);
|
|
1561
|
-
}
|
|
1562
1602
|
function renderSchemaType({ schema, name, keysToOmit }) {
|
|
1563
1603
|
if (!schema) return null;
|
|
1564
1604
|
const imports = adapter.getImports(schema, (schemaName) => ({
|
|
1565
|
-
name: resolveImportName(
|
|
1605
|
+
name: resolveImportName({
|
|
1606
|
+
schemaName,
|
|
1607
|
+
enumOptions,
|
|
1608
|
+
enumSchemaNames,
|
|
1609
|
+
resolver
|
|
1610
|
+
}),
|
|
1566
1611
|
path: resolver.file({
|
|
1567
1612
|
name: schemaName,
|
|
1568
1613
|
extname: ".ts",
|
|
@@ -1581,7 +1626,7 @@ const typeGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1581
1626
|
keysToOmit,
|
|
1582
1627
|
resolver,
|
|
1583
1628
|
enumSchemaNames,
|
|
1584
|
-
nameMapping: adapter.options.nameMapping,
|
|
1629
|
+
nameMapping: getOasAdapter(adapter).options.nameMapping,
|
|
1585
1630
|
nodes: printer?.nodes
|
|
1586
1631
|
});
|
|
1587
1632
|
return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx_jsx_runtime.Fragment, { children: [imports.map((imp) => /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
|
|
@@ -1691,7 +1736,12 @@ const typeGenerator = (0, kubb_kit.defineGenerator)({
|
|
|
1691
1736
|
const responseName = resolver.response.response(node);
|
|
1692
1737
|
const responsesWithSchema = node.responses.filter(hasSchema);
|
|
1693
1738
|
if (new Set(responsesWithSchema.flatMap((res) => (res.content ?? []).flatMap((entry) => entry.schema ? adapter.getImports(entry.schema, (schemaName) => ({
|
|
1694
|
-
name: resolveImportName(
|
|
1739
|
+
name: resolveImportName({
|
|
1740
|
+
schemaName,
|
|
1741
|
+
enumOptions,
|
|
1742
|
+
enumSchemaNames,
|
|
1743
|
+
resolver
|
|
1744
|
+
}),
|
|
1695
1745
|
path: ""
|
|
1696
1746
|
})).flatMap((imp) => Array.isArray(imp.name) ? imp.name : [imp.name]) : []))).has(responseName)) return null;
|
|
1697
1747
|
return renderSchemaType({
|
|
@@ -1817,7 +1867,7 @@ const pluginTsName = "plugin-ts";
|
|
|
1817
1867
|
* import { pluginTs } from '@kubb/plugin-ts'
|
|
1818
1868
|
*
|
|
1819
1869
|
* export default defineConfig({
|
|
1820
|
-
* input:
|
|
1870
|
+
* input: './petStore.yaml',
|
|
1821
1871
|
* output: { path: './src/gen' },
|
|
1822
1872
|
* plugins: [
|
|
1823
1873
|
* pluginTs({
|
|
@@ -2054,14 +2104,14 @@ function renderGroupType(type, sorted, transformType) {
|
|
|
2054
2104
|
}
|
|
2055
2105
|
function printParameter(node, options) {
|
|
2056
2106
|
const { mode, transformName, transformType } = options;
|
|
2057
|
-
const
|
|
2107
|
+
const bindingName = node.name;
|
|
2058
2108
|
if (mode === "call") {
|
|
2059
|
-
if (
|
|
2060
|
-
const name = transformName ? transformName(
|
|
2109
|
+
if (typeof bindingName !== "string") return `{ ${sortedGroupMembers(bindingName, node.type).map((member) => renderBindingMember(member)).join(", ")} }`;
|
|
2110
|
+
const name = transformName ? transformName(bindingName) : bindingName;
|
|
2061
2111
|
return node.rest ? `...${name}` : name;
|
|
2062
2112
|
}
|
|
2063
|
-
if (
|
|
2064
|
-
const sorted = sortedGroupMembers(
|
|
2113
|
+
if (typeof bindingName !== "string") {
|
|
2114
|
+
const sorted = sortedGroupMembers(bindingName, node.type);
|
|
2065
2115
|
const binding = `{ ${sorted.map((member) => renderBindingMember(member, transformName)).join(", ")} }`;
|
|
2066
2116
|
const allOptional = sorted.every((member) => member.optional);
|
|
2067
2117
|
const type = renderGroupType(node.type, sorted, transformType);
|
|
@@ -2071,7 +2121,7 @@ function printParameter(node, options) {
|
|
|
2071
2121
|
}
|
|
2072
2122
|
return node.default ? `${binding} = ${node.default}` : binding;
|
|
2073
2123
|
}
|
|
2074
|
-
const name = transformName ? transformName(
|
|
2124
|
+
const name = transformName ? transformName(bindingName) : bindingName;
|
|
2075
2125
|
const type = node.type ? renderType(node.type, transformType) : void 0;
|
|
2076
2126
|
if (node.rest) return type ? `...${name}: ${type}` : `...${name}`;
|
|
2077
2127
|
if (type) {
|