@kubb/plugin-ts 5.0.0-alpha.10 → 5.0.0-alpha.12
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-CRu8IKY3.js → Type-CX1HRooG.js} +377 -365
- package/dist/Type-CX1HRooG.js.map +1 -0
- package/dist/Type-Cat0_htq.cjs +808 -0
- package/dist/Type-Cat0_htq.cjs.map +1 -0
- package/dist/components.cjs +3 -2
- package/dist/components.d.ts +40 -9
- package/dist/components.js +2 -2
- package/dist/generators-CLuCmfUz.js +532 -0
- package/dist/generators-CLuCmfUz.js.map +1 -0
- package/dist/generators-DWBU-MuW.cjs +536 -0
- package/dist/generators-DWBU-MuW.cjs.map +1 -0
- package/dist/generators.cjs +2 -3
- package/dist/generators.d.ts +3 -503
- package/dist/generators.js +2 -2
- package/dist/index.cjs +308 -4
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +26 -21
- package/dist/index.js +305 -2
- package/dist/index.js.map +1 -0
- package/dist/{types-mSXmB8WU.d.ts → types-BA1ZCQ5p.d.ts} +73 -57
- package/package.json +5 -5
- package/src/components/{v2/Enum.tsx → Enum.tsx} +27 -11
- package/src/components/Type.tsx +23 -141
- package/src/components/index.ts +1 -0
- package/src/generators/index.ts +0 -1
- package/src/generators/typeGenerator.tsx +189 -413
- package/src/generators/utils.ts +298 -0
- package/src/index.ts +1 -1
- package/src/plugin.ts +81 -129
- package/src/printer.ts +15 -4
- package/src/resolverTs.ts +109 -1
- package/src/types.ts +68 -52
- package/dist/components-CRu8IKY3.js.map +0 -1
- package/dist/components-DeNDKlzf.cjs +0 -982
- package/dist/components-DeNDKlzf.cjs.map +0 -1
- package/dist/plugin-BZkBwnEA.js +0 -1269
- package/dist/plugin-BZkBwnEA.js.map +0 -1
- package/dist/plugin-Bunz1oGa.cjs +0 -1322
- package/dist/plugin-Bunz1oGa.cjs.map +0 -1
- package/src/components/v2/Type.tsx +0 -59
- package/src/generators/v2/typeGenerator.tsx +0 -167
- package/src/generators/v2/utils.ts +0 -140
- package/src/parser.ts +0 -389
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import "./chunk--u3MIqq1.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { collect, isPlainStringType } from "@kubb/ast";
|
|
3
|
+
import { definePrinter } from "@kubb/core";
|
|
4
4
|
import { File } from "@kubb/react-fabric";
|
|
5
|
-
import
|
|
5
|
+
import { safePrint } from "@kubb/fabric-core/parsers/typescript";
|
|
6
6
|
import { isNumber } from "remeda";
|
|
7
|
+
import ts from "typescript";
|
|
7
8
|
import { Fragment, jsx, jsxs } from "@kubb/react-fabric/jsx-runtime";
|
|
8
9
|
//#region ../../internals/utils/src/casing.ts
|
|
9
10
|
/**
|
|
@@ -24,9 +25,12 @@ function toCamelOrPascal(text, pascal) {
|
|
|
24
25
|
* Splits `text` on `.` and applies `transformPart` to each segment.
|
|
25
26
|
* The last segment receives `isLast = true`, all earlier segments receive `false`.
|
|
26
27
|
* Segments are joined with `/` to form a file path.
|
|
28
|
+
*
|
|
29
|
+
* Only splits on dots followed by a letter so that version numbers
|
|
30
|
+
* embedded in operationIds (e.g. `v2025.0`) are kept intact.
|
|
27
31
|
*/
|
|
28
32
|
function applyToFileParts(text, transformPart) {
|
|
29
|
-
const parts = text.split(
|
|
33
|
+
const parts = text.split(/\.(?=[a-zA-Z])/);
|
|
30
34
|
return parts.map((part, i) => transformPart(part, i === parts.length - 1)).join("/");
|
|
31
35
|
}
|
|
32
36
|
/**
|
|
@@ -120,6 +124,53 @@ function jsStringEscape(input) {
|
|
|
120
124
|
});
|
|
121
125
|
}
|
|
122
126
|
//#endregion
|
|
127
|
+
//#region ../../internals/utils/src/object.ts
|
|
128
|
+
/**
|
|
129
|
+
* Serializes a primitive value to a JSON string literal, stripping any surrounding quote characters first.
|
|
130
|
+
*
|
|
131
|
+
* @example
|
|
132
|
+
* stringify('hello') // '"hello"'
|
|
133
|
+
* stringify('"hello"') // '"hello"'
|
|
134
|
+
*/
|
|
135
|
+
function stringify(value) {
|
|
136
|
+
if (value === void 0 || value === null) return "\"\"";
|
|
137
|
+
return JSON.stringify(trimQuotes(value.toString()));
|
|
138
|
+
}
|
|
139
|
+
//#endregion
|
|
140
|
+
//#region src/constants.ts
|
|
141
|
+
/**
|
|
142
|
+
* `optionalType` values that cause a property's type to include `| undefined`.
|
|
143
|
+
*/
|
|
144
|
+
const OPTIONAL_ADDS_UNDEFINED = new Set(["undefined", "questionTokenAndUndefined"]);
|
|
145
|
+
/**
|
|
146
|
+
* `optionalType` values that render the property key with a `?` token.
|
|
147
|
+
*/
|
|
148
|
+
const OPTIONAL_ADDS_QUESTION_TOKEN = new Set(["questionToken", "questionTokenAndUndefined"]);
|
|
149
|
+
/**
|
|
150
|
+
* `enumType` values that append a `Key` suffix to the generated enum type alias.
|
|
151
|
+
*/
|
|
152
|
+
const ENUM_TYPES_WITH_KEY_SUFFIX = new Set(["asConst", "asPascalConst"]);
|
|
153
|
+
/**
|
|
154
|
+
* `enumType` values that require a runtime value declaration (object, enum, or literal).
|
|
155
|
+
*/
|
|
156
|
+
const ENUM_TYPES_WITH_RUNTIME_VALUE = new Set([
|
|
157
|
+
"enum",
|
|
158
|
+
"asConst",
|
|
159
|
+
"asPascalConst",
|
|
160
|
+
"constEnum",
|
|
161
|
+
"literal",
|
|
162
|
+
void 0
|
|
163
|
+
]);
|
|
164
|
+
/**
|
|
165
|
+
* `enumType` values whose type declaration is type-only (no runtime value emitted for the type alias).
|
|
166
|
+
*/
|
|
167
|
+
const ENUM_TYPES_WITH_TYPE_ONLY = new Set([
|
|
168
|
+
"asConst",
|
|
169
|
+
"asPascalConst",
|
|
170
|
+
"literal",
|
|
171
|
+
void 0
|
|
172
|
+
]);
|
|
173
|
+
//#endregion
|
|
123
174
|
//#region src/factory.ts
|
|
124
175
|
const { SyntaxKind, factory } = ts;
|
|
125
176
|
const modifiers = {
|
|
@@ -133,11 +184,6 @@ const syntaxKind = {
|
|
|
133
184
|
literalType: SyntaxKind.LiteralType,
|
|
134
185
|
stringLiteral: SyntaxKind.StringLiteral
|
|
135
186
|
};
|
|
136
|
-
function getUnknownType(unknownType) {
|
|
137
|
-
if (unknownType === "any") return keywordTypeNodes.any;
|
|
138
|
-
if (unknownType === "void") return keywordTypeNodes.void;
|
|
139
|
-
return keywordTypeNodes.unknown;
|
|
140
|
-
}
|
|
141
187
|
function isValidIdentifier(str) {
|
|
142
188
|
if (!str.length || str.trim() !== str) return false;
|
|
143
189
|
const node = ts.parseIsolatedEntityName(str, ts.ScriptTarget.Latest);
|
|
@@ -342,388 +388,354 @@ const createTupleTypeNode = factory.createTupleTypeNode;
|
|
|
342
388
|
const createRestTypeNode = factory.createRestTypeNode;
|
|
343
389
|
const createTrue = factory.createTrue;
|
|
344
390
|
const createFalse = factory.createFalse;
|
|
345
|
-
|
|
346
|
-
|
|
391
|
+
factory.createIndexedAccessTypeNode;
|
|
392
|
+
factory.createTypeOperatorNode;
|
|
347
393
|
const createPrefixUnaryExpression = factory.createPrefixUnaryExpression;
|
|
348
394
|
//#endregion
|
|
349
|
-
//#region src/
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
395
|
+
//#region src/printer.ts
|
|
396
|
+
/**
|
|
397
|
+
* Converts a primitive const value to a TypeScript literal type node.
|
|
398
|
+
* Handles negative numbers via a prefix unary expression.
|
|
399
|
+
*/
|
|
400
|
+
function constToTypeNode(value, format) {
|
|
401
|
+
if (format === "boolean") return createLiteralTypeNode(value === true ? createTrue() : createFalse());
|
|
402
|
+
if (format === "number" && typeof value === "number") {
|
|
403
|
+
if (value < 0) return createLiteralTypeNode(createPrefixUnaryExpression(SyntaxKind.MinusToken, createNumericLiteral(Math.abs(value))));
|
|
404
|
+
return createLiteralTypeNode(createNumericLiteral(value));
|
|
405
|
+
}
|
|
406
|
+
return createLiteralTypeNode(createStringLiteral(String(value)));
|
|
407
|
+
}
|
|
408
|
+
/**
|
|
409
|
+
* Returns a `Date` reference type node when `representation` is `'date'`, otherwise falls back to `string`.
|
|
410
|
+
*/
|
|
411
|
+
function dateOrStringNode(node) {
|
|
412
|
+
return node.representation === "date" ? createTypeReferenceNode(createIdentifier("Date")) : keywordTypeNodes.string;
|
|
413
|
+
}
|
|
414
|
+
/**
|
|
415
|
+
* Maps an array of `SchemaNode`s through the printer, filtering out `null` and `undefined` results.
|
|
416
|
+
*/
|
|
417
|
+
function buildMemberNodes(members, print) {
|
|
418
|
+
return (members ?? []).map(print).filter(Boolean);
|
|
419
|
+
}
|
|
420
|
+
/**
|
|
421
|
+
* Builds a TypeScript tuple type node from an array schema's `items`,
|
|
422
|
+
* applying min/max slice and optional/rest element rules.
|
|
423
|
+
*/
|
|
424
|
+
function buildTupleNode(node, print) {
|
|
425
|
+
let items = (node.items ?? []).map(print).filter(Boolean);
|
|
426
|
+
const restNode = node.rest ? print(node.rest) ?? void 0 : void 0;
|
|
427
|
+
const { min, max } = node;
|
|
428
|
+
if (max !== void 0) {
|
|
429
|
+
items = items.slice(0, max);
|
|
430
|
+
if (items.length < max && restNode) items = [...items, ...Array(max - items.length).fill(restNode)];
|
|
431
|
+
}
|
|
432
|
+
if (min !== void 0) items = items.map((item, i) => i >= min ? createOptionalTypeNode(item) : item);
|
|
433
|
+
if (max === void 0 && restNode) items.push(createRestTypeNode(createArrayTypeNode(restNode)));
|
|
434
|
+
return createTupleTypeNode(items);
|
|
435
|
+
}
|
|
436
|
+
/**
|
|
437
|
+
* Applies `nullable` and optional/nullish `| undefined` union modifiers to a property's resolved base type.
|
|
438
|
+
*/
|
|
439
|
+
function buildPropertyType(schema, baseType, optionalType) {
|
|
440
|
+
const addsUndefined = OPTIONAL_ADDS_UNDEFINED.has(optionalType);
|
|
441
|
+
let type = baseType;
|
|
442
|
+
if (schema.nullable) type = createUnionDeclaration({ nodes: [type, keywordTypeNodes.null] });
|
|
443
|
+
if ((schema.nullish || schema.optional) && addsUndefined) type = createUnionDeclaration({ nodes: [type, keywordTypeNodes.undefined] });
|
|
444
|
+
return type;
|
|
445
|
+
}
|
|
446
|
+
/**
|
|
447
|
+
* Collects JSDoc annotation strings (description, deprecated, min/max, pattern, default, example, type) for a schema node.
|
|
448
|
+
*/
|
|
449
|
+
function buildPropertyJSDocComments(schema) {
|
|
450
|
+
return [
|
|
451
|
+
"description" in schema && schema.description ? `@description ${jsStringEscape(schema.description)}` : void 0,
|
|
452
|
+
"deprecated" in schema && schema.deprecated ? "@deprecated" : void 0,
|
|
453
|
+
"min" in schema && schema.min !== void 0 ? `@minLength ${schema.min}` : void 0,
|
|
454
|
+
"max" in schema && schema.max !== void 0 ? `@maxLength ${schema.max}` : void 0,
|
|
455
|
+
"pattern" in schema && schema.pattern ? `@pattern ${schema.pattern}` : void 0,
|
|
456
|
+
"default" in schema && schema.default !== void 0 ? `@default ${"primitive" in schema && schema.primitive === "string" ? stringify(schema.default) : schema.default}` : void 0,
|
|
457
|
+
"example" in schema && schema.example !== void 0 ? `@example ${schema.example}` : void 0,
|
|
458
|
+
"primitive" in schema && schema.primitive ? [`@type ${schema.primitive || "unknown"}`, "optional" in schema && schema.optional ? " | undefined" : void 0].filter(Boolean).join("") : void 0
|
|
459
|
+
];
|
|
460
|
+
}
|
|
461
|
+
/**
|
|
462
|
+
* Creates TypeScript index signatures for `additionalProperties` and `patternProperties` on an object schema node.
|
|
463
|
+
*/
|
|
464
|
+
function buildIndexSignatures(node, propertyCount, print) {
|
|
465
|
+
const elements = [];
|
|
466
|
+
if (node.additionalProperties && node.additionalProperties !== true) {
|
|
467
|
+
const additionalType = print(node.additionalProperties) ?? keywordTypeNodes.unknown;
|
|
468
|
+
elements.push(createIndexSignature(propertyCount > 0 ? keywordTypeNodes.unknown : additionalType));
|
|
469
|
+
} else if (node.additionalProperties === true) elements.push(createIndexSignature(keywordTypeNodes.unknown));
|
|
470
|
+
if (node.patternProperties) {
|
|
471
|
+
const first = Object.values(node.patternProperties)[0];
|
|
472
|
+
if (first) {
|
|
473
|
+
let patternType = print(first) ?? keywordTypeNodes.unknown;
|
|
474
|
+
if (first.nullable) patternType = createUnionDeclaration({ nodes: [patternType, keywordTypeNodes.null] });
|
|
475
|
+
elements.push(createIndexSignature(patternType));
|
|
400
476
|
}
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
datetime: () => keywordTypeNodes.string,
|
|
405
|
-
date: (type = "string") => type === "string" ? keywordTypeNodes.string : createTypeReferenceNode(createIdentifier("Date")),
|
|
406
|
-
time: (type = "string") => type === "string" ? keywordTypeNodes.string : createTypeReferenceNode(createIdentifier("Date")),
|
|
407
|
-
uuid: () => keywordTypeNodes.string,
|
|
408
|
-
url: () => keywordTypeNodes.string,
|
|
409
|
-
default: void 0,
|
|
410
|
-
and: (nodes) => {
|
|
411
|
-
if (!nodes) return;
|
|
412
|
-
return createIntersectionDeclaration({
|
|
413
|
-
withParentheses: true,
|
|
414
|
-
nodes
|
|
415
|
-
});
|
|
416
|
-
},
|
|
417
|
-
describe: void 0,
|
|
418
|
-
min: void 0,
|
|
419
|
-
max: void 0,
|
|
420
|
-
optional: void 0,
|
|
421
|
-
matches: () => keywordTypeNodes.string,
|
|
422
|
-
email: () => keywordTypeNodes.string,
|
|
423
|
-
firstName: void 0,
|
|
424
|
-
lastName: void 0,
|
|
425
|
-
password: void 0,
|
|
426
|
-
phone: void 0,
|
|
427
|
-
readOnly: void 0,
|
|
428
|
-
writeOnly: void 0,
|
|
429
|
-
ref: (propertyName) => {
|
|
430
|
-
if (!propertyName) return;
|
|
431
|
-
return createTypeReferenceNode(propertyName, void 0);
|
|
432
|
-
},
|
|
433
|
-
blob: () => createTypeReferenceNode("Blob", []),
|
|
434
|
-
deprecated: void 0,
|
|
435
|
-
example: void 0,
|
|
436
|
-
schema: void 0,
|
|
437
|
-
catchall: void 0,
|
|
438
|
-
name: void 0,
|
|
439
|
-
interface: void 0,
|
|
440
|
-
exclusiveMaximum: void 0,
|
|
441
|
-
exclusiveMinimum: void 0
|
|
442
|
-
};
|
|
477
|
+
}
|
|
478
|
+
return elements;
|
|
479
|
+
}
|
|
443
480
|
/**
|
|
444
|
-
*
|
|
481
|
+
* TypeScript type printer built with `definePrinter`.
|
|
445
482
|
*
|
|
446
|
-
*
|
|
483
|
+
* Converts a `SchemaNode` AST node into a TypeScript AST node:
|
|
484
|
+
* - **`printer.print(node)`** — when `options.typeName` is set, returns a full
|
|
485
|
+
* `type Name = …` or `interface Name { … }` declaration (`ts.Node`).
|
|
486
|
+
* Without `typeName`, returns the raw `ts.TypeNode` for the schema.
|
|
447
487
|
*
|
|
448
|
-
*
|
|
449
|
-
*
|
|
450
|
-
*
|
|
451
|
-
* @
|
|
452
|
-
*
|
|
488
|
+
* Dispatches on `node.type` to the appropriate handler in `nodes`. Options are closed
|
|
489
|
+
* over per printer instance, so each call to `printerTs(options)` produces an independent printer.
|
|
490
|
+
*
|
|
491
|
+
* @example Raw type node (no `typeName`)
|
|
492
|
+
* ```ts
|
|
493
|
+
* const printer = printerTs({ optionalType: 'questionToken', arrayType: 'array', enumType: 'inlineLiteral' })
|
|
494
|
+
* const typeNode = printer.print(schemaNode) // ts.TypeNode
|
|
495
|
+
* ```
|
|
496
|
+
*
|
|
497
|
+
* @example Full declaration (with `typeName`)
|
|
498
|
+
* ```ts
|
|
499
|
+
* const printer = printerTs({ optionalType: 'questionToken', arrayType: 'array', enumType: 'inlineLiteral', typeName: 'MyType' })
|
|
500
|
+
* const declaration = printer.print(schemaNode) // ts.TypeAliasDeclaration | ts.InterfaceDeclaration
|
|
501
|
+
* ```
|
|
453
502
|
*/
|
|
454
|
-
const
|
|
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
|
-
name
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
const
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
const matchesSchema = schemas.find((schema) => schema.keyword === schemaKeywords.matches);
|
|
544
|
-
let type = schemas.map((it) => this.parse({
|
|
545
|
-
schema,
|
|
546
|
-
parent: current,
|
|
547
|
-
name,
|
|
548
|
-
current: it,
|
|
549
|
-
siblings: schemas
|
|
550
|
-
}, options)).filter(Boolean)[0];
|
|
551
|
-
if (isNullable) type = createUnionDeclaration({ nodes: [type, keywordTypeNodes.null] });
|
|
552
|
-
if (isNullish && ["undefined", "questionTokenAndUndefined"].includes(options.optionalType)) type = createUnionDeclaration({ nodes: [type, keywordTypeNodes.undefined] });
|
|
553
|
-
if (isOptional && ["undefined", "questionTokenAndUndefined"].includes(options.optionalType)) type = createUnionDeclaration({ nodes: [type, keywordTypeNodes.undefined] });
|
|
554
|
-
return appendJSDocToNode({
|
|
555
|
-
node: createPropertySignature({
|
|
556
|
-
questionToken: isOptional || isNullish ? ["questionToken", "questionTokenAndUndefined"].includes(options.optionalType) : false,
|
|
557
|
-
name: mappedName,
|
|
558
|
-
type,
|
|
559
|
-
readOnly: isReadonly
|
|
560
|
-
}),
|
|
561
|
-
comments: [
|
|
562
|
-
describeSchema ? `@description ${jsStringEscape(describeSchema.args)}` : void 0,
|
|
563
|
-
deprecatedSchema ? "@deprecated" : void 0,
|
|
564
|
-
minSchema ? `@minLength ${minSchema.args}` : void 0,
|
|
565
|
-
maxSchema ? `@maxLength ${maxSchema.args}` : void 0,
|
|
566
|
-
matchesSchema ? `@pattern ${matchesSchema.args}` : void 0,
|
|
567
|
-
defaultSchema ? `@default ${defaultSchema.args}` : void 0,
|
|
568
|
-
exampleSchema ? `@example ${exampleSchema.args}` : void 0,
|
|
569
|
-
schemaSchema?.args?.type || schemaSchema?.args?.format ? [`@type ${schemaSchema?.args?.type || "unknown"}${!isOptional ? "" : " | undefined"}`, schemaSchema?.args?.format].filter(Boolean).join(", ") : void 0
|
|
570
|
-
].filter(Boolean)
|
|
503
|
+
const printerTs = definePrinter((options) => {
|
|
504
|
+
const addsUndefined = OPTIONAL_ADDS_UNDEFINED.has(options.optionalType);
|
|
505
|
+
return {
|
|
506
|
+
name: "typescript",
|
|
507
|
+
options,
|
|
508
|
+
nodes: {
|
|
509
|
+
any: () => keywordTypeNodes.any,
|
|
510
|
+
unknown: () => keywordTypeNodes.unknown,
|
|
511
|
+
void: () => keywordTypeNodes.void,
|
|
512
|
+
never: () => keywordTypeNodes.never,
|
|
513
|
+
boolean: () => keywordTypeNodes.boolean,
|
|
514
|
+
null: () => keywordTypeNodes.null,
|
|
515
|
+
blob: () => createTypeReferenceNode("Blob", []),
|
|
516
|
+
string: () => keywordTypeNodes.string,
|
|
517
|
+
uuid: () => keywordTypeNodes.string,
|
|
518
|
+
email: () => keywordTypeNodes.string,
|
|
519
|
+
url: (node) => {
|
|
520
|
+
if (node.path) return createUrlTemplateType(node.path);
|
|
521
|
+
return keywordTypeNodes.string;
|
|
522
|
+
},
|
|
523
|
+
datetime: () => keywordTypeNodes.string,
|
|
524
|
+
number: () => keywordTypeNodes.number,
|
|
525
|
+
integer: () => keywordTypeNodes.number,
|
|
526
|
+
bigint: () => keywordTypeNodes.bigint,
|
|
527
|
+
date: dateOrStringNode,
|
|
528
|
+
time: dateOrStringNode,
|
|
529
|
+
ref(node) {
|
|
530
|
+
if (!node.name) return;
|
|
531
|
+
const refName = node.ref ? node.ref.split("/").at(-1) ?? node.name : node.name;
|
|
532
|
+
return createTypeReferenceNode(node.ref ? this.options.resolver.default(refName, "type") : refName, void 0);
|
|
533
|
+
},
|
|
534
|
+
enum(node) {
|
|
535
|
+
const values = node.namedEnumValues?.map((v) => v.value) ?? node.enumValues ?? [];
|
|
536
|
+
if (this.options.enumType === "inlineLiteral" || !node.name) return createUnionDeclaration({
|
|
537
|
+
withParentheses: true,
|
|
538
|
+
nodes: values.filter((v) => v !== null).map((value) => constToTypeNode(value, typeof value)).filter(Boolean)
|
|
539
|
+
}) ?? void 0;
|
|
540
|
+
const resolvedName = this.options.resolver.default(node.name, "type");
|
|
541
|
+
return createTypeReferenceNode(ENUM_TYPES_WITH_KEY_SUFFIX.has(this.options.enumType) ? `${resolvedName}Key` : resolvedName, void 0);
|
|
542
|
+
},
|
|
543
|
+
union(node) {
|
|
544
|
+
const members = node.members ?? [];
|
|
545
|
+
const hasStringLiteral = members.some((m) => m.type === "enum" && (m.enumType === "string" || m.primitive === "string"));
|
|
546
|
+
const hasPlainString = members.some((m) => isPlainStringType(m));
|
|
547
|
+
if (hasStringLiteral && hasPlainString) return createUnionDeclaration({
|
|
548
|
+
withParentheses: true,
|
|
549
|
+
nodes: members.map((m) => {
|
|
550
|
+
if (isPlainStringType(m)) return createIntersectionDeclaration({
|
|
551
|
+
nodes: [keywordTypeNodes.string, createTypeLiteralNode([])],
|
|
552
|
+
withParentheses: true
|
|
553
|
+
});
|
|
554
|
+
return this.print(m);
|
|
555
|
+
}).filter(Boolean)
|
|
556
|
+
}) ?? void 0;
|
|
557
|
+
return createUnionDeclaration({
|
|
558
|
+
withParentheses: true,
|
|
559
|
+
nodes: buildMemberNodes(members, this.print)
|
|
560
|
+
}) ?? void 0;
|
|
561
|
+
},
|
|
562
|
+
intersection(node) {
|
|
563
|
+
return createIntersectionDeclaration({
|
|
564
|
+
withParentheses: true,
|
|
565
|
+
nodes: buildMemberNodes(node.members, this.print)
|
|
566
|
+
}) ?? void 0;
|
|
567
|
+
},
|
|
568
|
+
array(node) {
|
|
569
|
+
return createArrayDeclaration({
|
|
570
|
+
nodes: (node.items ?? []).map((item) => this.print(item)).filter(Boolean),
|
|
571
|
+
arrayType: this.options.arrayType
|
|
572
|
+
}) ?? void 0;
|
|
573
|
+
},
|
|
574
|
+
tuple(node) {
|
|
575
|
+
return buildTupleNode(node, this.print);
|
|
576
|
+
},
|
|
577
|
+
object(node) {
|
|
578
|
+
const { print, options } = this;
|
|
579
|
+
const addsQuestionToken = OPTIONAL_ADDS_QUESTION_TOKEN.has(options.optionalType);
|
|
580
|
+
const propertyNodes = node.properties.map((prop) => {
|
|
581
|
+
const baseType = print(prop.schema) ?? keywordTypeNodes.unknown;
|
|
582
|
+
const type = buildPropertyType(prop.schema, baseType, options.optionalType);
|
|
583
|
+
return appendJSDocToNode({
|
|
584
|
+
node: createPropertySignature({
|
|
585
|
+
questionToken: prop.schema.optional || prop.schema.nullish ? addsQuestionToken : false,
|
|
586
|
+
name: prop.name,
|
|
587
|
+
type,
|
|
588
|
+
readOnly: prop.schema.readOnly
|
|
589
|
+
}),
|
|
590
|
+
comments: buildPropertyJSDocComments(prop.schema)
|
|
591
|
+
});
|
|
571
592
|
});
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
let additionalPropertiesType = current.args.additionalProperties.map((it) => this.parse({
|
|
576
|
-
schema,
|
|
577
|
-
parent: current,
|
|
578
|
-
name,
|
|
579
|
-
current: it,
|
|
580
|
-
siblings: []
|
|
581
|
-
}, options)).filter(Boolean).at(0);
|
|
582
|
-
if (current.args?.additionalProperties.some((schema) => isKeyword(schema, schemaKeywords.nullable))) additionalPropertiesType = createUnionDeclaration({ nodes: [additionalPropertiesType, keywordTypeNodes.null] });
|
|
583
|
-
additionalProperties = createIndexSignature(properties.length > 0 ? keywordTypeNodes.unknown : additionalPropertiesType);
|
|
593
|
+
const allElements = [...propertyNodes, ...buildIndexSignatures(node, propertyNodes.length, print)];
|
|
594
|
+
if (!allElements.length) return keywordTypeNodes.object;
|
|
595
|
+
return createTypeLiteralNode(allElements);
|
|
584
596
|
}
|
|
585
|
-
let patternProperties;
|
|
586
|
-
if (current.args?.patternProperties) {
|
|
587
|
-
const allPatternSchemas = Object.values(current.args.patternProperties).flat();
|
|
588
|
-
if (allPatternSchemas.length > 0) {
|
|
589
|
-
patternProperties = allPatternSchemas.map((it) => this.parse({
|
|
590
|
-
schema,
|
|
591
|
-
parent: current,
|
|
592
|
-
name,
|
|
593
|
-
current: it,
|
|
594
|
-
siblings: []
|
|
595
|
-
}, options)).filter(Boolean).at(0);
|
|
596
|
-
if (allPatternSchemas.some((schema) => isKeyword(schema, schemaKeywords.nullable))) patternProperties = createUnionDeclaration({ nodes: [patternProperties, keywordTypeNodes.null] });
|
|
597
|
-
patternProperties = createIndexSignature(patternProperties);
|
|
598
|
-
}
|
|
599
|
-
}
|
|
600
|
-
return typeKeywordMapper.object([
|
|
601
|
-
...properties,
|
|
602
|
-
additionalProperties,
|
|
603
|
-
patternProperties
|
|
604
|
-
].filter(Boolean));
|
|
605
|
-
},
|
|
606
|
-
datetime() {
|
|
607
|
-
return typeKeywordMapper.datetime();
|
|
608
|
-
},
|
|
609
|
-
date(tree) {
|
|
610
|
-
const { current } = tree;
|
|
611
|
-
return typeKeywordMapper.date(current.args.type);
|
|
612
597
|
},
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
598
|
+
print(node) {
|
|
599
|
+
let type = this.print(node);
|
|
600
|
+
if (!type) return;
|
|
601
|
+
if (node.nullable) type = createUnionDeclaration({ nodes: [type, keywordTypeNodes.null] });
|
|
602
|
+
if ((node.nullish || node.optional) && addsUndefined) type = createUnionDeclaration({ nodes: [type, keywordTypeNodes.undefined] });
|
|
603
|
+
const { typeName, syntaxType = "type", description, keysToOmit } = this.options;
|
|
604
|
+
if (!typeName) return type;
|
|
605
|
+
const useTypeGeneration = syntaxType === "type" || type.kind === syntaxKind.union || !!keysToOmit?.length;
|
|
606
|
+
return createTypeDeclaration({
|
|
607
|
+
name: typeName,
|
|
608
|
+
isExportable: true,
|
|
609
|
+
type: keysToOmit?.length ? createOmitDeclaration({
|
|
610
|
+
keys: keysToOmit,
|
|
611
|
+
type,
|
|
612
|
+
nonNullable: true
|
|
613
|
+
}) : type,
|
|
614
|
+
syntax: useTypeGeneration ? "type" : "interface",
|
|
615
|
+
comments: [
|
|
616
|
+
node?.title ? jsStringEscape(node.title) : void 0,
|
|
617
|
+
description ? `@description ${jsStringEscape(description)}` : void 0,
|
|
618
|
+
node?.deprecated ? "@deprecated" : void 0,
|
|
619
|
+
node && "min" in node && node.min !== void 0 ? `@minLength ${node.min}` : void 0,
|
|
620
|
+
node && "max" in node && node.max !== void 0 ? `@maxLength ${node.max}` : void 0,
|
|
621
|
+
node && "pattern" in node && node.pattern ? `@pattern ${node.pattern}` : void 0,
|
|
622
|
+
node?.default ? `@default ${node.default}` : void 0,
|
|
623
|
+
node?.example ? `@example ${node.example}` : void 0
|
|
624
|
+
]
|
|
625
|
+
});
|
|
616
626
|
}
|
|
617
|
-
}
|
|
627
|
+
};
|
|
618
628
|
});
|
|
619
629
|
//#endregion
|
|
630
|
+
//#region src/components/Enum.tsx
|
|
631
|
+
/**
|
|
632
|
+
* Resolves the runtime identifier name and the TypeScript type name for an enum schema node.
|
|
633
|
+
*
|
|
634
|
+
* The raw `node.name` may be a YAML key such as `"enumNames.Type"` which is not a
|
|
635
|
+
* valid TypeScript identifier. The resolver normalizes it; for inline enum
|
|
636
|
+
* properties the adapter already emits a PascalCase+suffix name so resolution is typically a no-op.
|
|
637
|
+
*/
|
|
638
|
+
function getEnumNames({ node, enumType, resolver }) {
|
|
639
|
+
const resolved = resolver.default(node.name, "type");
|
|
640
|
+
return {
|
|
641
|
+
enumName: enumType === "asPascalConst" ? resolved : camelCase(node.name),
|
|
642
|
+
typeName: ENUM_TYPES_WITH_KEY_SUFFIX.has(enumType) ? `${resolved}Key` : resolved,
|
|
643
|
+
refName: resolved
|
|
644
|
+
};
|
|
645
|
+
}
|
|
646
|
+
/**
|
|
647
|
+
* Renders the enum declaration(s) for a single named `EnumSchemaNode`.
|
|
648
|
+
*
|
|
649
|
+
* Depending on `enumType` this may emit:
|
|
650
|
+
* - A runtime object (`asConst` / `asPascalConst`) plus a `typeof` type alias
|
|
651
|
+
* - A `const enum` or plain `enum` declaration (`constEnum` / `enum`)
|
|
652
|
+
* - A union literal type alias (`literal`)
|
|
653
|
+
*
|
|
654
|
+
* The emitted `File.Source` nodes carry the resolved names so that the barrel
|
|
655
|
+
* index picks up the correct export identifiers.
|
|
656
|
+
*/
|
|
657
|
+
function Enum({ node, enumType, enumKeyCasing, resolver }) {
|
|
658
|
+
const { enumName, typeName, refName } = getEnumNames({
|
|
659
|
+
node,
|
|
660
|
+
enumType,
|
|
661
|
+
resolver
|
|
662
|
+
});
|
|
663
|
+
const [nameNode, typeNode] = createEnumDeclaration({
|
|
664
|
+
name: enumName,
|
|
665
|
+
typeName,
|
|
666
|
+
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]) ?? [],
|
|
667
|
+
type: enumType,
|
|
668
|
+
enumKeyCasing
|
|
669
|
+
});
|
|
670
|
+
const needsRefAlias = ENUM_TYPES_WITH_KEY_SUFFIX.has(enumType) && refName !== typeName;
|
|
671
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
672
|
+
nameNode && /* @__PURE__ */ jsx(File.Source, {
|
|
673
|
+
name: enumName,
|
|
674
|
+
isExportable: true,
|
|
675
|
+
isIndexable: true,
|
|
676
|
+
isTypeOnly: false,
|
|
677
|
+
children: safePrint(nameNode)
|
|
678
|
+
}),
|
|
679
|
+
/* @__PURE__ */ jsx(File.Source, {
|
|
680
|
+
name: typeName,
|
|
681
|
+
isIndexable: true,
|
|
682
|
+
isExportable: ENUM_TYPES_WITH_RUNTIME_VALUE.has(enumType),
|
|
683
|
+
isTypeOnly: ENUM_TYPES_WITH_TYPE_ONLY.has(enumType),
|
|
684
|
+
children: safePrint(typeNode)
|
|
685
|
+
}),
|
|
686
|
+
needsRefAlias && /* @__PURE__ */ jsx(File.Source, {
|
|
687
|
+
name: refName,
|
|
688
|
+
isExportable: true,
|
|
689
|
+
isIndexable: true,
|
|
690
|
+
isTypeOnly: true,
|
|
691
|
+
children: `export type ${refName} = ${typeName}`
|
|
692
|
+
})
|
|
693
|
+
] });
|
|
694
|
+
}
|
|
695
|
+
//#endregion
|
|
620
696
|
//#region src/components/Type.tsx
|
|
621
|
-
function Type({ name, typedName,
|
|
622
|
-
const
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
name,
|
|
628
|
-
schema,
|
|
629
|
-
parent: void 0,
|
|
630
|
-
current,
|
|
631
|
-
siblings
|
|
632
|
-
}, {
|
|
697
|
+
function Type({ name, typedName, node, keysToOmit, optionalType, arrayType, syntaxType, enumType, enumKeyCasing, description, resolver }) {
|
|
698
|
+
const resolvedDescription = description || node?.description;
|
|
699
|
+
const enumSchemaNodes = collect(node, { schema(n) {
|
|
700
|
+
if (n.type === "enum" && n.name) return n;
|
|
701
|
+
} });
|
|
702
|
+
const typeNode = printerTs({
|
|
633
703
|
optionalType,
|
|
634
704
|
arrayType,
|
|
635
|
-
enumType
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
}
|
|
645
|
-
}
|
|
646
|
-
if (schemaFromTree && isKeyword(schemaFromTree, schemaKeywords.schema)) {
|
|
647
|
-
const isNullish = tree.some((item) => item.keyword === schemaKeywords.nullish);
|
|
648
|
-
const isNullable = tree.some((item) => item.keyword === schemaKeywords.nullable);
|
|
649
|
-
const isOptional = tree.some((item) => item.keyword === schemaKeywords.optional);
|
|
650
|
-
if (isNullable) type = createUnionDeclaration({ nodes: [type, keywordTypeNodes.null] });
|
|
651
|
-
if (isNullish && ["undefined", "questionTokenAndUndefined"].includes(optionalType)) type = createUnionDeclaration({ nodes: [type, keywordTypeNodes.undefined] });
|
|
652
|
-
if (isOptional && ["undefined", "questionTokenAndUndefined"].includes(optionalType)) type = createUnionDeclaration({ nodes: [type, keywordTypeNodes.undefined] });
|
|
653
|
-
}
|
|
654
|
-
const useTypeGeneration = syntaxType === "type" || [syntaxKind.union].includes(type.kind) || !!keysToOmit?.length;
|
|
655
|
-
typeNodes.push(createTypeDeclaration({
|
|
656
|
-
name,
|
|
657
|
-
isExportable: true,
|
|
658
|
-
type: keysToOmit?.length ? createOmitDeclaration({
|
|
659
|
-
keys: keysToOmit,
|
|
660
|
-
type,
|
|
661
|
-
nonNullable: true
|
|
662
|
-
}) : type,
|
|
663
|
-
syntax: useTypeGeneration ? "type" : "interface",
|
|
664
|
-
comments: [
|
|
665
|
-
schema.title ? `${jsStringEscape(schema.title)}` : void 0,
|
|
666
|
-
description ? `@description ${jsStringEscape(description)}` : void 0,
|
|
667
|
-
schema.deprecated ? "@deprecated" : void 0,
|
|
668
|
-
schema.minLength ? `@minLength ${schema.minLength}` : void 0,
|
|
669
|
-
schema.maxLength ? `@maxLength ${schema.maxLength}` : void 0,
|
|
670
|
-
schema.pattern ? `@pattern ${schema.pattern}` : void 0,
|
|
671
|
-
schema.default ? `@default ${schema.default}` : void 0,
|
|
672
|
-
schema.example ? `@example ${schema.example}` : void 0
|
|
673
|
-
]
|
|
674
|
-
}));
|
|
675
|
-
const enums = [...new Set(enumSchemas)].map((enumSchema) => {
|
|
676
|
-
const name = enumType === "asPascalConst" ? pascalCase(enumSchema.args.name) : camelCase(enumSchema.args.name);
|
|
677
|
-
const typeName = ["asConst", "asPascalConst"].includes(enumType) ? `${enumSchema.args.typeName}Key` : enumSchema.args.typeName;
|
|
678
|
-
const [nameNode, typeNode] = createEnumDeclaration({
|
|
679
|
-
name,
|
|
680
|
-
typeName,
|
|
681
|
-
enums: enumSchema.args.items.map((item) => item.value === void 0 ? void 0 : [trimQuotes(item.name?.toString()), item.value]).filter(Boolean),
|
|
682
|
-
type: enumType,
|
|
683
|
-
enumKeyCasing
|
|
684
|
-
});
|
|
705
|
+
enumType,
|
|
706
|
+
typeName: name,
|
|
707
|
+
syntaxType,
|
|
708
|
+
description: resolvedDescription,
|
|
709
|
+
keysToOmit,
|
|
710
|
+
resolver
|
|
711
|
+
}).print(node);
|
|
712
|
+
if (!typeNode) return;
|
|
713
|
+
const enums = [...new Map(enumSchemaNodes.map((n) => [n.name, n])).values()].map((node) => {
|
|
685
714
|
return {
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
715
|
+
node,
|
|
716
|
+
...getEnumNames({
|
|
717
|
+
node,
|
|
718
|
+
enumType,
|
|
719
|
+
resolver
|
|
720
|
+
})
|
|
690
721
|
};
|
|
691
722
|
});
|
|
692
723
|
const shouldExportEnums = enumType !== "inlineLiteral";
|
|
693
724
|
const shouldExportType = enumType === "inlineLiteral" || enums.every((item) => item.typeName !== name);
|
|
694
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [shouldExportEnums && enums.map(({
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
}), /* @__PURE__ */ jsx(File.Source, {
|
|
701
|
-
name: typeName,
|
|
702
|
-
isIndexable: true,
|
|
703
|
-
isExportable: [
|
|
704
|
-
"enum",
|
|
705
|
-
"asConst",
|
|
706
|
-
"asPascalConst",
|
|
707
|
-
"constEnum",
|
|
708
|
-
"literal",
|
|
709
|
-
void 0
|
|
710
|
-
].includes(enumType),
|
|
711
|
-
isTypeOnly: [
|
|
712
|
-
"asConst",
|
|
713
|
-
"asPascalConst",
|
|
714
|
-
"literal",
|
|
715
|
-
void 0
|
|
716
|
-
].includes(enumType),
|
|
717
|
-
children: safePrint(typeNode)
|
|
718
|
-
})] })), shouldExportType && /* @__PURE__ */ jsx(File.Source, {
|
|
725
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [shouldExportEnums && enums.map(({ node }) => /* @__PURE__ */ jsx(Enum, {
|
|
726
|
+
node,
|
|
727
|
+
enumType,
|
|
728
|
+
enumKeyCasing,
|
|
729
|
+
resolver
|
|
730
|
+
})), shouldExportType && /* @__PURE__ */ jsx(File.Source, {
|
|
719
731
|
name: typedName,
|
|
720
732
|
isTypeOnly: true,
|
|
721
733
|
isExportable: true,
|
|
722
734
|
isIndexable: true,
|
|
723
|
-
children: safePrint(
|
|
735
|
+
children: safePrint(typeNode)
|
|
724
736
|
})] });
|
|
725
737
|
}
|
|
726
738
|
//#endregion
|
|
727
|
-
export {
|
|
739
|
+
export { pascalCase as a, camelCase as i, Enum as n, ENUM_TYPES_WITH_KEY_SUFFIX as r, Type as t };
|
|
728
740
|
|
|
729
|
-
//# sourceMappingURL=
|
|
741
|
+
//# sourceMappingURL=Type-CX1HRooG.js.map
|