@openpkg-ts/sdk 0.54.4 → 0.54.6
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.d.ts +34 -4
- package/dist/index.js +866 -324
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1781,7 +1781,7 @@ function filterSpec(spec, criteria) {
|
|
|
1781
1781
|
};
|
|
1782
1782
|
}
|
|
1783
1783
|
// src/primitives/get.ts
|
|
1784
|
-
import
|
|
1784
|
+
import ts14 from "typescript";
|
|
1785
1785
|
|
|
1786
1786
|
// src/ast/type-identity.ts
|
|
1787
1787
|
import * as path3 from "node:path";
|
|
@@ -2102,22 +2102,14 @@ function extractVarianceModifiers(modifiers) {
|
|
|
2102
2102
|
const variance = hasIn && hasOut ? "inout" : hasIn ? "in" : hasOut ? "out" : undefined;
|
|
2103
2103
|
return { variance, isConst };
|
|
2104
2104
|
}
|
|
2105
|
-
function extractTypeParameters(node,
|
|
2105
|
+
function extractTypeParameters(node, _checker) {
|
|
2106
2106
|
if (!node.typeParameters || node.typeParameters.length === 0) {
|
|
2107
2107
|
return;
|
|
2108
2108
|
}
|
|
2109
2109
|
return node.typeParameters.map((tp) => {
|
|
2110
2110
|
const name = tp.name.text;
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
const constraintType = checker.getTypeAtLocation(tp.constraint);
|
|
2114
|
-
constraint = checker.typeToString(constraintType);
|
|
2115
|
-
}
|
|
2116
|
-
let defaultType;
|
|
2117
|
-
if (tp.default) {
|
|
2118
|
-
const defType = checker.getTypeAtLocation(tp.default);
|
|
2119
|
-
defaultType = checker.typeToString(defType);
|
|
2120
|
-
}
|
|
2111
|
+
const constraint = tp.constraint ? tp.constraint.getText() : undefined;
|
|
2112
|
+
const defaultType = tp.default ? tp.default.getText() : undefined;
|
|
2121
2113
|
const { variance, isConst } = extractVarianceModifiers(ts2.getModifiers(tp));
|
|
2122
2114
|
return {
|
|
2123
2115
|
name,
|
|
@@ -2175,7 +2167,7 @@ function getJSDocForSignature(signature, checker) {
|
|
|
2175
2167
|
const symbol = checker?.getSymbolAtLocation(decl);
|
|
2176
2168
|
return getJSDocComment(decl, symbol, checker);
|
|
2177
2169
|
}
|
|
2178
|
-
function extractTypeParametersFromSignature(signature,
|
|
2170
|
+
function extractTypeParametersFromSignature(signature, _checker) {
|
|
2179
2171
|
const typeParams = signature.getTypeParameters();
|
|
2180
2172
|
if (!typeParams || typeParams.length === 0) {
|
|
2181
2173
|
return;
|
|
@@ -2183,15 +2175,7 @@ function extractTypeParametersFromSignature(signature, checker) {
|
|
|
2183
2175
|
return typeParams.map((tp) => {
|
|
2184
2176
|
const name = tp.getSymbol()?.getName() ?? "T";
|
|
2185
2177
|
let constraint;
|
|
2186
|
-
const constraintType = tp.getConstraint();
|
|
2187
|
-
if (constraintType) {
|
|
2188
|
-
constraint = checker.typeToString(constraintType);
|
|
2189
|
-
}
|
|
2190
2178
|
let defaultType;
|
|
2191
|
-
const defaultT = tp.getDefault();
|
|
2192
|
-
if (defaultT) {
|
|
2193
|
-
defaultType = checker.typeToString(defaultT);
|
|
2194
|
-
}
|
|
2195
2179
|
let variance;
|
|
2196
2180
|
let isConst;
|
|
2197
2181
|
const tpSymbol = tp.getSymbol();
|
|
@@ -2199,6 +2183,10 @@ function extractTypeParametersFromSignature(signature, checker) {
|
|
|
2199
2183
|
for (const decl of declarations) {
|
|
2200
2184
|
if (ts2.isTypeParameterDeclaration(decl)) {
|
|
2201
2185
|
({ variance, isConst } = extractVarianceModifiers(ts2.getModifiers(decl)));
|
|
2186
|
+
if (decl.constraint)
|
|
2187
|
+
constraint = decl.constraint.getText();
|
|
2188
|
+
if (decl.default)
|
|
2189
|
+
defaultType = decl.default.getText();
|
|
2202
2190
|
break;
|
|
2203
2191
|
}
|
|
2204
2192
|
}
|
|
@@ -2235,6 +2223,37 @@ function getExportKind(declaration, type) {
|
|
|
2235
2223
|
import * as fs4 from "node:fs";
|
|
2236
2224
|
import * as path5 from "node:path";
|
|
2237
2225
|
import ts3 from "typescript";
|
|
2226
|
+
function collectLocalModuleFiles(entryFile, host, options) {
|
|
2227
|
+
const seen = new Set;
|
|
2228
|
+
const queue = [entryFile];
|
|
2229
|
+
while (queue.length > 0) {
|
|
2230
|
+
const file = queue.pop();
|
|
2231
|
+
if (seen.has(file))
|
|
2232
|
+
continue;
|
|
2233
|
+
seen.add(file);
|
|
2234
|
+
const text = host.readFile(file);
|
|
2235
|
+
if (text === undefined)
|
|
2236
|
+
continue;
|
|
2237
|
+
const sf = ts3.createSourceFile(file, text, ts3.ScriptTarget.Latest, true, getScriptKind(file));
|
|
2238
|
+
for (const stmt of sf.statements) {
|
|
2239
|
+
let spec;
|
|
2240
|
+
if (ts3.isImportDeclaration(stmt))
|
|
2241
|
+
spec = stmt.moduleSpecifier;
|
|
2242
|
+
else if (ts3.isExportDeclaration(stmt))
|
|
2243
|
+
spec = stmt.moduleSpecifier;
|
|
2244
|
+
if (!spec || !ts3.isStringLiteral(spec))
|
|
2245
|
+
continue;
|
|
2246
|
+
if (!spec.text.startsWith("."))
|
|
2247
|
+
continue;
|
|
2248
|
+
const resolved = ts3.resolveModuleName(spec.text, file, options, host);
|
|
2249
|
+
const resolvedFile = resolved.resolvedModule?.resolvedFileName;
|
|
2250
|
+
if (resolvedFile && !resolvedFile.includes(`${path5.sep}node_modules${path5.sep}`)) {
|
|
2251
|
+
queue.push(resolvedFile);
|
|
2252
|
+
}
|
|
2253
|
+
}
|
|
2254
|
+
}
|
|
2255
|
+
return [...seen];
|
|
2256
|
+
}
|
|
2238
2257
|
function isJsFile(file) {
|
|
2239
2258
|
return /\.(js|mjs|cjs|jsx)$/.test(file);
|
|
2240
2259
|
}
|
|
@@ -2499,6 +2518,7 @@ function createProgram(options) {
|
|
|
2499
2518
|
return ts3.resolveModuleName(literal.text, containingFile, options2, compilerHost, undefined, redirectedReference, mode);
|
|
2500
2519
|
});
|
|
2501
2520
|
}
|
|
2521
|
+
const localRoots = collectLocalModuleFiles(entryFile, compilerHost, compilerOptions);
|
|
2502
2522
|
if (content !== undefined) {
|
|
2503
2523
|
inMemorySource = ts3.createSourceFile(entryFile, content, ts3.ScriptTarget.Latest, true, getScriptKind(entryFile));
|
|
2504
2524
|
const originalGetSourceFile = compilerHost.getSourceFile.bind(compilerHost);
|
|
@@ -2509,7 +2529,7 @@ function createProgram(options) {
|
|
|
2509
2529
|
return originalGetSourceFile(fileName, languageVersion, onError, shouldCreateNewSourceFile);
|
|
2510
2530
|
};
|
|
2511
2531
|
}
|
|
2512
|
-
const rootFiles = [entryFile, ...additionalRootFiles];
|
|
2532
|
+
const rootFiles = [...new Set([entryFile, ...localRoots, ...additionalRootFiles])];
|
|
2513
2533
|
const program = ts3.createProgram(rootFiles, compilerOptions, compilerHost);
|
|
2514
2534
|
const sourceFile = inMemorySource ?? program.getSourceFile(entryFile);
|
|
2515
2535
|
return {
|
|
@@ -2523,13 +2543,144 @@ function createProgram(options) {
|
|
|
2523
2543
|
}
|
|
2524
2544
|
|
|
2525
2545
|
// src/serializers/classes.ts
|
|
2526
|
-
import
|
|
2546
|
+
import ts9 from "typescript";
|
|
2527
2547
|
|
|
2528
2548
|
// src/types/parameters.ts
|
|
2529
|
-
import
|
|
2549
|
+
import ts6 from "typescript";
|
|
2530
2550
|
|
|
2531
2551
|
// src/types/schema-builder.ts
|
|
2552
|
+
import ts5 from "typescript";
|
|
2553
|
+
|
|
2554
|
+
// src/ast/resolve.ts
|
|
2532
2555
|
import ts4 from "typescript";
|
|
2556
|
+
function isTypeOnlyExport(symbol) {
|
|
2557
|
+
const declarations = symbol.declarations ?? [];
|
|
2558
|
+
for (const decl of declarations) {
|
|
2559
|
+
if (ts4.isExportSpecifier(decl)) {
|
|
2560
|
+
if (decl.isTypeOnly)
|
|
2561
|
+
return true;
|
|
2562
|
+
const exportDecl = decl.parent?.parent;
|
|
2563
|
+
if (exportDecl && ts4.isExportDeclaration(exportDecl) && exportDecl.isTypeOnly) {
|
|
2564
|
+
return true;
|
|
2565
|
+
}
|
|
2566
|
+
}
|
|
2567
|
+
}
|
|
2568
|
+
return false;
|
|
2569
|
+
}
|
|
2570
|
+
function resolveExportTarget(symbol, checker, program) {
|
|
2571
|
+
const isTypeOnly = isTypeOnlyExport(symbol);
|
|
2572
|
+
const targetSymbol = resolveAliasSymbol(symbol, checker, undefined, program);
|
|
2573
|
+
const declarations = targetSymbol.declarations ?? [];
|
|
2574
|
+
const declaration = targetSymbol.valueDeclaration || declarations.find((decl) => decl.kind !== ts4.SyntaxKind.ExportSpecifier && decl.kind !== ts4.SyntaxKind.ImportSpecifier && decl.kind !== ts4.SyntaxKind.ExportDeclaration && decl.kind !== ts4.SyntaxKind.ImportClause && decl.kind !== ts4.SyntaxKind.NamespaceExport);
|
|
2575
|
+
return { declaration, targetSymbol, isTypeOnly };
|
|
2576
|
+
}
|
|
2577
|
+
function resolveAliasSymbol(symbol, checker, seen = new Set, program) {
|
|
2578
|
+
if (seen.has(symbol))
|
|
2579
|
+
return symbol;
|
|
2580
|
+
seen.add(symbol);
|
|
2581
|
+
if (symbol.flags & ts4.SymbolFlags.Alias) {
|
|
2582
|
+
try {
|
|
2583
|
+
const aliased = checker.getAliasedSymbol(symbol);
|
|
2584
|
+
if (aliased && aliased !== symbol && hasConcreteDeclaration(aliased)) {
|
|
2585
|
+
return resolveAliasSymbol(aliased, checker, seen, program);
|
|
2586
|
+
}
|
|
2587
|
+
} catch {}
|
|
2588
|
+
}
|
|
2589
|
+
for (const decl of symbol.declarations ?? []) {
|
|
2590
|
+
const fromModule = resolveFromModuleSpecifier(decl, symbol, checker, program);
|
|
2591
|
+
if (fromModule && fromModule !== symbol) {
|
|
2592
|
+
return resolveAliasSymbol(fromModule, checker, seen, program);
|
|
2593
|
+
}
|
|
2594
|
+
}
|
|
2595
|
+
return symbol;
|
|
2596
|
+
}
|
|
2597
|
+
function hasConcreteDeclaration(symbol) {
|
|
2598
|
+
if (symbol.valueDeclaration)
|
|
2599
|
+
return true;
|
|
2600
|
+
return (symbol.declarations ?? []).some((d) => d.kind !== ts4.SyntaxKind.ExportSpecifier && d.kind !== ts4.SyntaxKind.ImportSpecifier && d.kind !== ts4.SyntaxKind.ExportDeclaration && d.kind !== ts4.SyntaxKind.NamespaceExport);
|
|
2601
|
+
}
|
|
2602
|
+
function resolveFromModuleSpecifier(decl, symbol, checker, program) {
|
|
2603
|
+
let moduleSpecifier;
|
|
2604
|
+
let importedName;
|
|
2605
|
+
if (ts4.isExportSpecifier(decl)) {
|
|
2606
|
+
const exportDecl = decl.parent?.parent;
|
|
2607
|
+
if (exportDecl && ts4.isExportDeclaration(exportDecl)) {
|
|
2608
|
+
moduleSpecifier = exportDecl.moduleSpecifier;
|
|
2609
|
+
importedName = (decl.propertyName ?? decl.name).text;
|
|
2610
|
+
}
|
|
2611
|
+
} else if (ts4.isImportSpecifier(decl)) {
|
|
2612
|
+
const importDecl = decl.parent?.parent?.parent;
|
|
2613
|
+
if (importDecl && ts4.isImportDeclaration(importDecl)) {
|
|
2614
|
+
moduleSpecifier = importDecl.moduleSpecifier;
|
|
2615
|
+
importedName = (decl.propertyName ?? decl.name).text;
|
|
2616
|
+
}
|
|
2617
|
+
} else if (ts4.isImportClause(decl) && decl.name) {
|
|
2618
|
+
const importDecl = decl.parent;
|
|
2619
|
+
if (ts4.isImportDeclaration(importDecl)) {
|
|
2620
|
+
moduleSpecifier = importDecl.moduleSpecifier;
|
|
2621
|
+
importedName = "default";
|
|
2622
|
+
}
|
|
2623
|
+
}
|
|
2624
|
+
if (!moduleSpecifier || importedName === undefined || !ts4.isStringLiteral(moduleSpecifier)) {
|
|
2625
|
+
return;
|
|
2626
|
+
}
|
|
2627
|
+
let modSym = checker.getSymbolAtLocation(moduleSpecifier);
|
|
2628
|
+
if (!modSym && program) {
|
|
2629
|
+
const containing = decl.getSourceFile().fileName;
|
|
2630
|
+
const resolved = ts4.resolveModuleName(moduleSpecifier.text, containing, program.getCompilerOptions(), ts4.sys);
|
|
2631
|
+
const file = resolved.resolvedModule?.resolvedFileName;
|
|
2632
|
+
const sf = file ? program.getSourceFile(file) : undefined;
|
|
2633
|
+
if (sf)
|
|
2634
|
+
modSym = checker.getSymbolAtLocation(sf);
|
|
2635
|
+
}
|
|
2636
|
+
if (!modSym)
|
|
2637
|
+
return;
|
|
2638
|
+
if (modSym.flags & ts4.SymbolFlags.Alias) {
|
|
2639
|
+
try {
|
|
2640
|
+
modSym = checker.getAliasedSymbol(modSym);
|
|
2641
|
+
} catch {
|
|
2642
|
+
return;
|
|
2643
|
+
}
|
|
2644
|
+
}
|
|
2645
|
+
if (!modSym)
|
|
2646
|
+
return;
|
|
2647
|
+
const exported = getModuleExportsFollowingStars(modSym, checker, program);
|
|
2648
|
+
const match = exported.find((e) => e.getName() === importedName);
|
|
2649
|
+
return match && match !== symbol ? match : undefined;
|
|
2650
|
+
}
|
|
2651
|
+
function getModuleExportsFollowingStars(modSym, checker, program, seen = new Set) {
|
|
2652
|
+
if (seen.has(modSym))
|
|
2653
|
+
return [];
|
|
2654
|
+
seen.add(modSym);
|
|
2655
|
+
const byName = new Map;
|
|
2656
|
+
for (const s of checker.getExportsOfModule(modSym)) {
|
|
2657
|
+
byName.set(s.getName(), s);
|
|
2658
|
+
}
|
|
2659
|
+
for (const decl of modSym.declarations ?? []) {
|
|
2660
|
+
const sf = ts4.isSourceFile(decl) ? decl : decl.getSourceFile();
|
|
2661
|
+
for (const stmt of sf.statements) {
|
|
2662
|
+
if (!ts4.isExportDeclaration(stmt) || stmt.exportClause || !stmt.moduleSpecifier || !ts4.isStringLiteral(stmt.moduleSpecifier)) {
|
|
2663
|
+
continue;
|
|
2664
|
+
}
|
|
2665
|
+
const nested = moduleSymbolFromPath(stmt.moduleSpecifier.text, sf.fileName, checker, program);
|
|
2666
|
+
if (!nested)
|
|
2667
|
+
continue;
|
|
2668
|
+
for (const s of getModuleExportsFollowingStars(nested, checker, program, seen)) {
|
|
2669
|
+
if (!byName.has(s.getName()))
|
|
2670
|
+
byName.set(s.getName(), s);
|
|
2671
|
+
}
|
|
2672
|
+
}
|
|
2673
|
+
}
|
|
2674
|
+
return [...byName.values()];
|
|
2675
|
+
}
|
|
2676
|
+
function moduleSymbolFromPath(spec, containingFile, checker, program) {
|
|
2677
|
+
if (!program)
|
|
2678
|
+
return;
|
|
2679
|
+
const resolved = ts4.resolveModuleName(spec, containingFile, program.getCompilerOptions(), ts4.sys);
|
|
2680
|
+
const file = resolved.resolvedModule?.resolvedFileName;
|
|
2681
|
+
const sf = file ? program.getSourceFile(file) : undefined;
|
|
2682
|
+
return sf ? checker.getSymbolAtLocation(sf) : undefined;
|
|
2683
|
+
}
|
|
2533
2684
|
|
|
2534
2685
|
// src/schema/builtins.ts
|
|
2535
2686
|
var BUILTIN_TYPE_SCHEMAS = {
|
|
@@ -2566,11 +2717,11 @@ function escapeRegex(text) {
|
|
|
2566
2717
|
}
|
|
2567
2718
|
function buildTemplatePattern(type) {
|
|
2568
2719
|
const slotPattern = (slot) => {
|
|
2569
|
-
if (slot.flags &
|
|
2720
|
+
if (slot.flags & ts5.TypeFlags.NumberLike)
|
|
2570
2721
|
return "-?\\d+(?:\\.\\d+)?";
|
|
2571
|
-
if (slot.flags &
|
|
2722
|
+
if (slot.flags & ts5.TypeFlags.BigIntLike)
|
|
2572
2723
|
return "-?\\d+";
|
|
2573
|
-
if (slot.flags &
|
|
2724
|
+
if (slot.flags & ts5.TypeFlags.BooleanLike)
|
|
2574
2725
|
return "(?:true|false)";
|
|
2575
2726
|
return ".*";
|
|
2576
2727
|
};
|
|
@@ -2597,12 +2748,12 @@ function scrubImportQualifiers(text) {
|
|
|
2597
2748
|
return text.replace(/import\((?:"[^"]*"|'[^']*')\)\./g, "");
|
|
2598
2749
|
}
|
|
2599
2750
|
function renderTypeText(type, checker, enclosing, extraFlags = 0) {
|
|
2600
|
-
return scrubImportQualifiers(checker.typeToString(type, enclosing,
|
|
2751
|
+
return scrubImportQualifiers(checker.typeToString(type, enclosing, ts5.TypeFormatFlags.NoTruncation | extraFlags));
|
|
2601
2752
|
}
|
|
2602
2753
|
function writtenTypeText(typeNode) {
|
|
2603
2754
|
if (!typeNode)
|
|
2604
2755
|
return;
|
|
2605
|
-
if (!
|
|
2756
|
+
if (!ts5.isTypeReferenceNode(typeNode) && !ts5.isUnionTypeNode(typeNode))
|
|
2606
2757
|
return;
|
|
2607
2758
|
try {
|
|
2608
2759
|
const text = scrubImportQualifiers(typeNode.getText().replace(/\s+/g, " ").replace(/^\|\s*/, "").trim());
|
|
@@ -2615,10 +2766,97 @@ function declaredTypeNode(decl) {
|
|
|
2615
2766
|
const withType = decl;
|
|
2616
2767
|
return withType?.type;
|
|
2617
2768
|
}
|
|
2769
|
+
function typeNodeOfSignature(sig) {
|
|
2770
|
+
const decl = sig.getDeclaration();
|
|
2771
|
+
if (!decl || !ts5.isFunctionLike(decl))
|
|
2772
|
+
return;
|
|
2773
|
+
return decl.type;
|
|
2774
|
+
}
|
|
2775
|
+
function resolvedSymbol(symbol, checker) {
|
|
2776
|
+
if (!symbol)
|
|
2777
|
+
return;
|
|
2778
|
+
if (symbol.flags & ts5.SymbolFlags.Alias) {
|
|
2779
|
+
try {
|
|
2780
|
+
return checker.getAliasedSymbol(symbol);
|
|
2781
|
+
} catch {
|
|
2782
|
+
return symbol;
|
|
2783
|
+
}
|
|
2784
|
+
}
|
|
2785
|
+
return symbol;
|
|
2786
|
+
}
|
|
2787
|
+
function buildSchemaFromTypeNode(node, checker, ctx) {
|
|
2788
|
+
if (ts5.isParenthesizedTypeNode(node)) {
|
|
2789
|
+
return buildSchemaFromTypeNode(node.type, checker, ctx);
|
|
2790
|
+
}
|
|
2791
|
+
if (ts5.isUnionTypeNode(node)) {
|
|
2792
|
+
return { anyOf: node.types.map((t2) => buildSchemaFromTypeNode(t2, checker, ctx)) };
|
|
2793
|
+
}
|
|
2794
|
+
if (ts5.isIntersectionTypeNode(node)) {
|
|
2795
|
+
return { allOf: node.types.map((t2) => buildSchemaFromTypeNode(t2, checker, ctx)) };
|
|
2796
|
+
}
|
|
2797
|
+
if (node.kind === ts5.SyntaxKind.NullKeyword) {
|
|
2798
|
+
return { type: "null" };
|
|
2799
|
+
}
|
|
2800
|
+
if (ts5.isLiteralTypeNode(node) && node.literal.kind === ts5.SyntaxKind.NullKeyword) {
|
|
2801
|
+
return { type: "null" };
|
|
2802
|
+
}
|
|
2803
|
+
if (node.kind === ts5.SyntaxKind.UndefinedKeyword) {
|
|
2804
|
+
return { type: "undefined" };
|
|
2805
|
+
}
|
|
2806
|
+
if (node.kind === ts5.SyntaxKind.VoidKeyword) {
|
|
2807
|
+
return { type: "void" };
|
|
2808
|
+
}
|
|
2809
|
+
if (node.kind === ts5.SyntaxKind.AnyKeyword) {
|
|
2810
|
+
return { "x-ts-type": "any" };
|
|
2811
|
+
}
|
|
2812
|
+
if (node.kind === ts5.SyntaxKind.UnknownKeyword) {
|
|
2813
|
+
return { type: "unknown" };
|
|
2814
|
+
}
|
|
2815
|
+
if (ts5.isTypeReferenceNode(node)) {
|
|
2816
|
+
const raw = checker.getSymbolAtLocation(ts5.isQualifiedName(node.typeName) ? node.typeName.right : node.typeName);
|
|
2817
|
+
const symbol = resolvedSymbol(raw, checker);
|
|
2818
|
+
const name = symbol?.getName() ?? node.typeName.getText();
|
|
2819
|
+
const args = node.typeArguments?.map((arg) => {
|
|
2820
|
+
if (typeNodeDefersExpansion(arg, checker, ctx?.program)) {
|
|
2821
|
+
return buildSchemaFromTypeNode(arg, checker, ctx);
|
|
2822
|
+
}
|
|
2823
|
+
const argType = checker.getTypeFromTypeNode(arg);
|
|
2824
|
+
return buildSchema(argType, checker, ctx, arg);
|
|
2825
|
+
});
|
|
2826
|
+
const withArgs = (schema) => {
|
|
2827
|
+
if (!args || args.length === 0)
|
|
2828
|
+
return schema;
|
|
2829
|
+
if (typeof schema !== "object" || schema === null || Array.isArray(schema)) {
|
|
2830
|
+
return schema;
|
|
2831
|
+
}
|
|
2832
|
+
return { ...schema, typeArguments: args };
|
|
2833
|
+
};
|
|
2834
|
+
if (name && isBuiltinGeneric(name) && (!symbol || isBuiltinSymbol(symbol))) {
|
|
2835
|
+
return withArgs({ ...builtinSchema(name) });
|
|
2836
|
+
}
|
|
2837
|
+
if (name && !name.startsWith("__")) {
|
|
2838
|
+
let refId = name;
|
|
2839
|
+
if (symbol && ctx) {
|
|
2840
|
+
try {
|
|
2841
|
+
refId = namedRefId(checker.getDeclaredTypeOfSymbol(symbol), name, ctx);
|
|
2842
|
+
} catch {
|
|
2843
|
+
refId = name;
|
|
2844
|
+
}
|
|
2845
|
+
}
|
|
2846
|
+
return withArgs({ $ref: `#/types/${refId}` });
|
|
2847
|
+
}
|
|
2848
|
+
return { "x-ts-type": scrubImportQualifiers(node.getText()) };
|
|
2849
|
+
}
|
|
2850
|
+
const t = checker.getTypeFromTypeNode(node);
|
|
2851
|
+
if (!(t.flags & ts5.TypeFlags.Any)) {
|
|
2852
|
+
return buildSchema(t, checker, ctx);
|
|
2853
|
+
}
|
|
2854
|
+
return { "x-ts-type": scrubImportQualifiers(node.getText()) };
|
|
2855
|
+
}
|
|
2618
2856
|
function stripUndefinedFromType(type, checker) {
|
|
2619
2857
|
if (!type.isUnion())
|
|
2620
2858
|
return type;
|
|
2621
|
-
const nonUndefinedTypes = type.types.filter((t) => !(t.flags &
|
|
2859
|
+
const nonUndefinedTypes = type.types.filter((t) => !(t.flags & ts5.TypeFlags.Undefined));
|
|
2622
2860
|
if (nonUndefinedTypes.length === 0)
|
|
2623
2861
|
return type;
|
|
2624
2862
|
if (nonUndefinedTypes.length === 1)
|
|
@@ -2627,13 +2865,13 @@ function stripUndefinedFromType(type, checker) {
|
|
|
2627
2865
|
}
|
|
2628
2866
|
function isReadonlyPropertySymbol(prop) {
|
|
2629
2867
|
const decls = prop.getDeclarations() ?? [];
|
|
2630
|
-
return decls.some((d) => (
|
|
2868
|
+
return decls.some((d) => (ts5.getCombinedModifierFlags(d) & ts5.ModifierFlags.Readonly) !== 0);
|
|
2631
2869
|
}
|
|
2632
2870
|
function decoratePropertySchema(schema, prop, propType, checker) {
|
|
2633
2871
|
if (typeof schema !== "object" || schema === null || Array.isArray(schema))
|
|
2634
2872
|
return schema;
|
|
2635
2873
|
const decl = prop.valueDeclaration ?? prop.getDeclarations()?.[0];
|
|
2636
|
-
const optional = !!(prop.flags &
|
|
2874
|
+
const optional = !!(prop.flags & ts5.SymbolFlags.Optional);
|
|
2637
2875
|
const textType = optional ? stripUndefinedFromType(propType, checker) : propType;
|
|
2638
2876
|
const text = renderTypeText(textType, checker, decl);
|
|
2639
2877
|
const obj = schema;
|
|
@@ -2650,16 +2888,16 @@ function decoratePropertySchema(schema, prop, propType, checker) {
|
|
|
2650
2888
|
if (isReadonlyPropertySymbol(prop) && !("readOnly" in obj)) {
|
|
2651
2889
|
result = { ...result, readOnly: true };
|
|
2652
2890
|
}
|
|
2653
|
-
if (prop.flags &
|
|
2891
|
+
if (prop.flags & ts5.SymbolFlags.Method && !("x-ts-method" in obj)) {
|
|
2654
2892
|
result = { ...result, "x-ts-method": true };
|
|
2655
2893
|
}
|
|
2656
2894
|
return result;
|
|
2657
2895
|
}
|
|
2658
2896
|
function shouldEmitAliasTypeText(typeNode) {
|
|
2659
|
-
if (
|
|
2897
|
+
if (ts5.isMappedTypeNode(typeNode))
|
|
2660
2898
|
return false;
|
|
2661
|
-
if (
|
|
2662
|
-
return typeNode.members.length > 0 && typeNode.members.every((m) =>
|
|
2899
|
+
if (ts5.isTypeLiteralNode(typeNode)) {
|
|
2900
|
+
return typeNode.members.length > 0 && typeNode.members.every((m) => ts5.isIndexSignatureDeclaration(m));
|
|
2663
2901
|
}
|
|
2664
2902
|
return true;
|
|
2665
2903
|
}
|
|
@@ -2721,6 +2959,104 @@ var RESOLVED_UTILITY_TYPES = new Set([
|
|
|
2721
2959
|
"NonNullable",
|
|
2722
2960
|
"Awaited"
|
|
2723
2961
|
]);
|
|
2962
|
+
function isDeferredMappedOrConditional(type) {
|
|
2963
|
+
if (shouldDeferAlias(type.aliasSymbol))
|
|
2964
|
+
return true;
|
|
2965
|
+
const target = type.target;
|
|
2966
|
+
if (target && target !== type) {
|
|
2967
|
+
if (shouldDeferAlias(target.aliasSymbol ?? target.getSymbol()))
|
|
2968
|
+
return true;
|
|
2969
|
+
const targetName = target.aliasSymbol?.getName() ?? target.getSymbol()?.getName();
|
|
2970
|
+
if (targetName && RESOLVED_UTILITY_TYPES.has(targetName))
|
|
2971
|
+
return false;
|
|
2972
|
+
}
|
|
2973
|
+
if (type.flags & ts5.TypeFlags.Conditional) {
|
|
2974
|
+
const name = type.aliasSymbol?.getName();
|
|
2975
|
+
if (name && RESOLVED_UTILITY_TYPES.has(name))
|
|
2976
|
+
return false;
|
|
2977
|
+
return true;
|
|
2978
|
+
}
|
|
2979
|
+
const objectFlags = type.objectFlags ?? 0;
|
|
2980
|
+
if (objectFlags & ts5.ObjectFlags.Mapped) {
|
|
2981
|
+
const name = type.aliasSymbol?.getName();
|
|
2982
|
+
if (name && RESOLVED_UTILITY_TYPES.has(name))
|
|
2983
|
+
return false;
|
|
2984
|
+
if (aliasRhsIsUtility(type.aliasSymbol))
|
|
2985
|
+
return false;
|
|
2986
|
+
return true;
|
|
2987
|
+
}
|
|
2988
|
+
return false;
|
|
2989
|
+
}
|
|
2990
|
+
function typeRefName(node) {
|
|
2991
|
+
return ts5.isQualifiedName(node.typeName) ? node.typeName.right.text : node.typeName.getText();
|
|
2992
|
+
}
|
|
2993
|
+
function aliasRhsIsUtility(symbol) {
|
|
2994
|
+
const alias = symbol?.declarations?.find(ts5.isTypeAliasDeclaration);
|
|
2995
|
+
if (!alias || !ts5.isTypeReferenceNode(alias.type))
|
|
2996
|
+
return false;
|
|
2997
|
+
return RESOLVED_UTILITY_TYPES.has(typeRefName(alias.type));
|
|
2998
|
+
}
|
|
2999
|
+
function isMappedOrConditionalBody(node) {
|
|
3000
|
+
if (ts5.isParenthesizedTypeNode(node))
|
|
3001
|
+
return isMappedOrConditionalBody(node.type);
|
|
3002
|
+
if (ts5.isMappedTypeNode(node) || ts5.isConditionalTypeNode(node))
|
|
3003
|
+
return true;
|
|
3004
|
+
if (ts5.isUnionTypeNode(node) || ts5.isIntersectionTypeNode(node)) {
|
|
3005
|
+
return node.types.some(isMappedOrConditionalBody);
|
|
3006
|
+
}
|
|
3007
|
+
return false;
|
|
3008
|
+
}
|
|
3009
|
+
function shouldDeferAlias(symbol) {
|
|
3010
|
+
if (!symbol)
|
|
3011
|
+
return false;
|
|
3012
|
+
const name = symbol.getName();
|
|
3013
|
+
if (!name || name.startsWith("__") || RESOLVED_UTILITY_TYPES.has(name))
|
|
3014
|
+
return false;
|
|
3015
|
+
if (aliasRhsIsUtility(symbol))
|
|
3016
|
+
return false;
|
|
3017
|
+
const alias = symbol.declarations?.find(ts5.isTypeAliasDeclaration);
|
|
3018
|
+
if (!alias)
|
|
3019
|
+
return false;
|
|
3020
|
+
return isMappedOrConditionalBody(alias.type);
|
|
3021
|
+
}
|
|
3022
|
+
function typeNodeDefersExpansion(node, checker, program) {
|
|
3023
|
+
if (!node)
|
|
3024
|
+
return false;
|
|
3025
|
+
if (ts5.isParenthesizedTypeNode(node))
|
|
3026
|
+
return typeNodeDefersExpansion(node.type, checker, program);
|
|
3027
|
+
if (ts5.isUnionTypeNode(node) || ts5.isIntersectionTypeNode(node)) {
|
|
3028
|
+
return node.types.some((t) => typeNodeDefersExpansion(t, checker, program));
|
|
3029
|
+
}
|
|
3030
|
+
if (!ts5.isTypeReferenceNode(node))
|
|
3031
|
+
return false;
|
|
3032
|
+
const raw = checker.getSymbolAtLocation(ts5.isQualifiedName(node.typeName) ? node.typeName.right : node.typeName);
|
|
3033
|
+
if (!raw)
|
|
3034
|
+
return false;
|
|
3035
|
+
const symbol = resolveAliasSymbol(raw, checker, undefined, program);
|
|
3036
|
+
return shouldDeferAlias(symbol);
|
|
3037
|
+
}
|
|
3038
|
+
function cheapTypeText(type, _checker, typeNode) {
|
|
3039
|
+
if (typeNode) {
|
|
3040
|
+
try {
|
|
3041
|
+
const text = scrubImportQualifiers(typeNode.getText().replace(/\s+/g, " ").trim());
|
|
3042
|
+
if (text)
|
|
3043
|
+
return text;
|
|
3044
|
+
} catch {}
|
|
3045
|
+
}
|
|
3046
|
+
const alias = type.aliasSymbol;
|
|
3047
|
+
const decl = alias?.declarations?.find(ts5.isTypeAliasDeclaration);
|
|
3048
|
+
if (decl?.type) {
|
|
3049
|
+
try {
|
|
3050
|
+
const text = scrubImportQualifiers(decl.type.getText().replace(/\s+/g, " ").trim());
|
|
3051
|
+
if (text)
|
|
3052
|
+
return text;
|
|
3053
|
+
} catch {}
|
|
3054
|
+
}
|
|
3055
|
+
const name = alias?.getName() ?? type.getSymbol()?.getName();
|
|
3056
|
+
if (name && !name.startsWith("__"))
|
|
3057
|
+
return name;
|
|
3058
|
+
return "unknown";
|
|
3059
|
+
}
|
|
2724
3060
|
var BUILTIN_TYPES = new Set([
|
|
2725
3061
|
"Date",
|
|
2726
3062
|
"RegExp",
|
|
@@ -2867,12 +3203,94 @@ function isAnonymous(type) {
|
|
|
2867
3203
|
return name.startsWith("__") || name === "";
|
|
2868
3204
|
}
|
|
2869
3205
|
function isFluentThisType(type) {
|
|
2870
|
-
if (!(type.flags &
|
|
3206
|
+
if (!(type.flags & ts5.TypeFlags.TypeParameter))
|
|
2871
3207
|
return false;
|
|
2872
3208
|
const declarations = type.getSymbol()?.declarations;
|
|
2873
3209
|
if (!declarations || declarations.length === 0)
|
|
2874
3210
|
return false;
|
|
2875
|
-
return declarations.some((decl) =>
|
|
3211
|
+
return declarations.some((decl) => ts5.isClassDeclaration(decl) || ts5.isClassExpression(decl) || ts5.isInterfaceDeclaration(decl));
|
|
3212
|
+
}
|
|
3213
|
+
function containsUnresolvedTypeParameter(type, seen = new Set) {
|
|
3214
|
+
if (seen.has(type))
|
|
3215
|
+
return false;
|
|
3216
|
+
seen.add(type);
|
|
3217
|
+
if (type.flags & ts5.TypeFlags.TypeParameter) {
|
|
3218
|
+
return !isFluentThisType(type);
|
|
3219
|
+
}
|
|
3220
|
+
if (type.isUnionOrIntersection()) {
|
|
3221
|
+
return type.types.some((t) => containsUnresolvedTypeParameter(t, seen));
|
|
3222
|
+
}
|
|
3223
|
+
if (type.aliasTypeArguments) {
|
|
3224
|
+
for (const arg of type.aliasTypeArguments) {
|
|
3225
|
+
if (containsUnresolvedTypeParameter(arg, seen))
|
|
3226
|
+
return true;
|
|
3227
|
+
}
|
|
3228
|
+
}
|
|
3229
|
+
const targs = type.typeArguments;
|
|
3230
|
+
if (targs) {
|
|
3231
|
+
for (const arg of targs) {
|
|
3232
|
+
if (containsUnresolvedTypeParameter(arg, seen))
|
|
3233
|
+
return true;
|
|
3234
|
+
}
|
|
3235
|
+
}
|
|
3236
|
+
if (type.flags & ts5.TypeFlags.IndexedAccess) {
|
|
3237
|
+
const ia = type;
|
|
3238
|
+
return containsUnresolvedTypeParameter(ia.objectType, seen) || containsUnresolvedTypeParameter(ia.indexType, seen);
|
|
3239
|
+
}
|
|
3240
|
+
return false;
|
|
3241
|
+
}
|
|
3242
|
+
function isUtilityOverTypeParameter(type) {
|
|
3243
|
+
const name = type.aliasSymbol?.getName();
|
|
3244
|
+
if (!name || !RESOLVED_UTILITY_TYPES.has(name))
|
|
3245
|
+
return false;
|
|
3246
|
+
const args = type.aliasTypeArguments;
|
|
3247
|
+
if (!args || args.length === 0)
|
|
3248
|
+
return false;
|
|
3249
|
+
return args.some((t) => containsUnresolvedTypeParameter(t));
|
|
3250
|
+
}
|
|
3251
|
+
function writtenUtilityText(type, checker, typeNode) {
|
|
3252
|
+
let node = typeNode;
|
|
3253
|
+
while (node && ts5.isParenthesizedTypeNode(node))
|
|
3254
|
+
node = node.type;
|
|
3255
|
+
const fromNode = writtenTypeText(node);
|
|
3256
|
+
if (fromNode)
|
|
3257
|
+
return fromNode;
|
|
3258
|
+
if (node) {
|
|
3259
|
+
try {
|
|
3260
|
+
const text = scrubImportQualifiers(node.getText().replace(/\s+/g, " ").trim());
|
|
3261
|
+
if (text)
|
|
3262
|
+
return text;
|
|
3263
|
+
} catch {}
|
|
3264
|
+
}
|
|
3265
|
+
const name = type.aliasSymbol?.getName();
|
|
3266
|
+
const args = type.aliasTypeArguments;
|
|
3267
|
+
if (name && args && args.length > 0) {
|
|
3268
|
+
const inner = args.map((t) => scrubImportQualifiers(checker.typeToString(t))).join(", ");
|
|
3269
|
+
return `${name}<${inner}>`;
|
|
3270
|
+
}
|
|
3271
|
+
return renderTypeText(type, checker);
|
|
3272
|
+
}
|
|
3273
|
+
function isReadonlyArrayType(type, typeNode) {
|
|
3274
|
+
let node = typeNode;
|
|
3275
|
+
while (node && ts5.isParenthesizedTypeNode(node))
|
|
3276
|
+
node = node.type;
|
|
3277
|
+
if (node && ts5.isTypeOperatorNode(node) && node.operator === ts5.SyntaxKind.ReadonlyKeyword) {
|
|
3278
|
+
return true;
|
|
3279
|
+
}
|
|
3280
|
+
if (node && ts5.isTypeReferenceNode(node) && typeRefName(node) === "ReadonlyArray") {
|
|
3281
|
+
return true;
|
|
3282
|
+
}
|
|
3283
|
+
const ref = type;
|
|
3284
|
+
const name = ref.target?.getSymbol()?.getName() ?? type.getSymbol()?.getName();
|
|
3285
|
+
return name === "ReadonlyArray";
|
|
3286
|
+
}
|
|
3287
|
+
function withReadonlyArrayHint(schema, type, typeNode) {
|
|
3288
|
+
if (!isReadonlyArrayType(type, typeNode))
|
|
3289
|
+
return schema;
|
|
3290
|
+
if (typeof schema !== "object" || schema === null || Array.isArray(schema))
|
|
3291
|
+
return schema;
|
|
3292
|
+
setSchemaExtension(schema, "x-ts-readonly", true);
|
|
3293
|
+
return schema;
|
|
2876
3294
|
}
|
|
2877
3295
|
function withDepth(ctx, fn) {
|
|
2878
3296
|
ctx.currentDepth++;
|
|
@@ -2904,12 +3322,17 @@ function ensureNonEmptySchema(schema, type, checker) {
|
|
|
2904
3322
|
}
|
|
2905
3323
|
return schema;
|
|
2906
3324
|
}
|
|
2907
|
-
function buildSchema(type, checker, ctx) {
|
|
2908
|
-
const schema = buildSchemaInternal(type, checker, ctx);
|
|
3325
|
+
function buildSchema(type, checker, ctx, typeNode) {
|
|
3326
|
+
const schema = buildSchemaInternal(type, checker, ctx, typeNode);
|
|
2909
3327
|
return ensureNonEmptySchema(schema, type, checker);
|
|
2910
3328
|
}
|
|
2911
|
-
function buildMaxDepthSchema(type, checker) {
|
|
2912
|
-
if (type.flags &
|
|
3329
|
+
function buildMaxDepthSchema(type, checker, typeNode) {
|
|
3330
|
+
if (type.flags & ts5.TypeFlags.Any) {
|
|
3331
|
+
if (typeNode)
|
|
3332
|
+
return buildSchemaFromTypeNode(typeNode, checker);
|
|
3333
|
+
return { "x-ts-type": checker.typeToString(type) };
|
|
3334
|
+
}
|
|
3335
|
+
if (type.flags & ts5.TypeFlags.TypeParameter && !isFluentThisType(type)) {
|
|
2913
3336
|
return { "x-ts-type": checker.typeToString(type) };
|
|
2914
3337
|
}
|
|
2915
3338
|
const symbol = type.getSymbol() || type.aliasSymbol;
|
|
@@ -2922,19 +3345,19 @@ function buildMaxDepthSchema(type, checker) {
|
|
|
2922
3345
|
return { $ref: `#/types/${name}` };
|
|
2923
3346
|
}
|
|
2924
3347
|
}
|
|
2925
|
-
if (type.flags &
|
|
3348
|
+
if (type.flags & ts5.TypeFlags.String)
|
|
2926
3349
|
return { type: "string" };
|
|
2927
|
-
if (type.flags &
|
|
3350
|
+
if (type.flags & ts5.TypeFlags.Number)
|
|
2928
3351
|
return { type: "number" };
|
|
2929
|
-
if (type.flags &
|
|
3352
|
+
if (type.flags & ts5.TypeFlags.Boolean)
|
|
2930
3353
|
return { type: "boolean" };
|
|
2931
|
-
if (type.flags &
|
|
3354
|
+
if (type.flags & ts5.TypeFlags.Undefined)
|
|
2932
3355
|
return { type: "undefined" };
|
|
2933
|
-
if (type.flags &
|
|
3356
|
+
if (type.flags & ts5.TypeFlags.Null)
|
|
2934
3357
|
return { type: "null" };
|
|
2935
|
-
if (type.flags &
|
|
3358
|
+
if (type.flags & ts5.TypeFlags.Void)
|
|
2936
3359
|
return { type: "void" };
|
|
2937
|
-
if (type.flags &
|
|
3360
|
+
if (type.flags & ts5.TypeFlags.TemplateLiteral) {
|
|
2938
3361
|
return {
|
|
2939
3362
|
type: "string",
|
|
2940
3363
|
pattern: buildTemplatePattern(type),
|
|
@@ -2951,9 +3374,21 @@ function buildMaxDepthSchema(type, checker) {
|
|
|
2951
3374
|
}
|
|
2952
3375
|
return { type: checker.typeToString(type) };
|
|
2953
3376
|
}
|
|
2954
|
-
function buildSchemaInternal(type, checker, ctx) {
|
|
3377
|
+
function buildSchemaInternal(type, checker, ctx, typeNode) {
|
|
2955
3378
|
if (isAtMaxDepth(ctx)) {
|
|
2956
|
-
return buildMaxDepthSchema(type, checker);
|
|
3379
|
+
return buildMaxDepthSchema(type, checker, typeNode);
|
|
3380
|
+
}
|
|
3381
|
+
if (ctx) {
|
|
3382
|
+
ctx.schemaOps += 1;
|
|
3383
|
+
if (ctx.schemaOps > ctx.maxSchemaOps) {
|
|
3384
|
+
ctx.budgetExceeded = true;
|
|
3385
|
+
return { "x-ts-type": cheapTypeText(type, checker, typeNode) };
|
|
3386
|
+
}
|
|
3387
|
+
}
|
|
3388
|
+
if (isDeferredMappedOrConditional(type)) {
|
|
3389
|
+
if (ctx)
|
|
3390
|
+
ctx.budgetExceeded = true;
|
|
3391
|
+
return { "x-ts-type": cheapTypeText(type, checker, typeNode) };
|
|
2957
3392
|
}
|
|
2958
3393
|
if (ctx?.visitedTypes.has(type)) {
|
|
2959
3394
|
const callSignatures = type.getCallSignatures();
|
|
@@ -2970,32 +3405,35 @@ function buildSchemaInternal(type, checker, ctx) {
|
|
|
2970
3405
|
}
|
|
2971
3406
|
return { type: checker.typeToString(type) };
|
|
2972
3407
|
}
|
|
2973
|
-
const addedToVisited = !!(ctx && type.flags &
|
|
3408
|
+
const addedToVisited = !!(ctx && type.flags & ts5.TypeFlags.Object);
|
|
2974
3409
|
if (addedToVisited) {
|
|
2975
3410
|
ctx.visitedTypes.add(type);
|
|
2976
3411
|
}
|
|
2977
3412
|
try {
|
|
2978
|
-
if (type.flags &
|
|
3413
|
+
if (type.flags & ts5.TypeFlags.String)
|
|
2979
3414
|
return { type: "string" };
|
|
2980
|
-
if (type.flags &
|
|
3415
|
+
if (type.flags & ts5.TypeFlags.Number)
|
|
2981
3416
|
return { type: "number" };
|
|
2982
|
-
if (type.flags &
|
|
3417
|
+
if (type.flags & ts5.TypeFlags.Boolean)
|
|
2983
3418
|
return { type: "boolean" };
|
|
2984
|
-
if (type.flags &
|
|
3419
|
+
if (type.flags & ts5.TypeFlags.Undefined)
|
|
2985
3420
|
return { type: "undefined" };
|
|
2986
|
-
if (type.flags &
|
|
3421
|
+
if (type.flags & ts5.TypeFlags.Null)
|
|
2987
3422
|
return { type: "null" };
|
|
2988
|
-
if (type.flags &
|
|
3423
|
+
if (type.flags & ts5.TypeFlags.Void)
|
|
2989
3424
|
return { type: "void" };
|
|
2990
|
-
if (type.flags &
|
|
2991
|
-
|
|
2992
|
-
|
|
3425
|
+
if (type.flags & ts5.TypeFlags.Any) {
|
|
3426
|
+
if (typeNode)
|
|
3427
|
+
return buildSchemaFromTypeNode(typeNode, checker, ctx);
|
|
3428
|
+
return { "x-ts-type": checker.typeToString(type) };
|
|
3429
|
+
}
|
|
3430
|
+
if (type.flags & ts5.TypeFlags.Unknown)
|
|
2993
3431
|
return { type: "unknown" };
|
|
2994
|
-
if (type.flags &
|
|
3432
|
+
if (type.flags & ts5.TypeFlags.Never)
|
|
2995
3433
|
return { type: "never" };
|
|
2996
|
-
if (type.flags &
|
|
3434
|
+
if (type.flags & ts5.TypeFlags.BigInt)
|
|
2997
3435
|
return { type: "bigint" };
|
|
2998
|
-
if (type.flags &
|
|
3436
|
+
if (type.flags & ts5.TypeFlags.ESSymbol)
|
|
2999
3437
|
return { type: "symbol" };
|
|
3000
3438
|
if (isFluentThisType(type)) {
|
|
3001
3439
|
const constraint = type.getConstraint?.();
|
|
@@ -3007,18 +3445,21 @@ function buildSchemaInternal(type, checker, ctx) {
|
|
|
3007
3445
|
};
|
|
3008
3446
|
}
|
|
3009
3447
|
}
|
|
3010
|
-
if (type.flags &
|
|
3448
|
+
if (type.flags & ts5.TypeFlags.TypeParameter) {
|
|
3011
3449
|
return { "x-ts-type": checker.typeToString(type) };
|
|
3012
3450
|
}
|
|
3013
|
-
if (type
|
|
3451
|
+
if (isUtilityOverTypeParameter(type)) {
|
|
3452
|
+
return { "x-ts-type": writtenUtilityText(type, checker, typeNode) };
|
|
3453
|
+
}
|
|
3454
|
+
if (type.flags & ts5.TypeFlags.StringLiteral) {
|
|
3014
3455
|
const literal = type.value;
|
|
3015
3456
|
return { type: "string", enum: [literal] };
|
|
3016
3457
|
}
|
|
3017
|
-
if (type.flags &
|
|
3458
|
+
if (type.flags & ts5.TypeFlags.NumberLiteral) {
|
|
3018
3459
|
const literal = type.value;
|
|
3019
3460
|
return { type: "number", enum: [literal] };
|
|
3020
3461
|
}
|
|
3021
|
-
if (type.flags &
|
|
3462
|
+
if (type.flags & ts5.TypeFlags.BooleanLiteral) {
|
|
3022
3463
|
const typeString2 = checker.typeToString(type);
|
|
3023
3464
|
return { type: "boolean", enum: [typeString2 === "true"] };
|
|
3024
3465
|
}
|
|
@@ -3033,33 +3474,33 @@ function buildSchemaInternal(type, checker, ctx) {
|
|
|
3033
3474
|
return schema;
|
|
3034
3475
|
}
|
|
3035
3476
|
}
|
|
3036
|
-
if (type.flags &
|
|
3477
|
+
if (type.flags & ts5.TypeFlags.TemplateLiteral) {
|
|
3037
3478
|
return {
|
|
3038
3479
|
type: "string",
|
|
3039
3480
|
pattern: buildTemplatePattern(type),
|
|
3040
3481
|
"x-ts-type": renderTypeText(type, checker)
|
|
3041
3482
|
};
|
|
3042
3483
|
}
|
|
3043
|
-
if (type.flags &
|
|
3484
|
+
if (type.flags & ts5.TypeFlags.StringMapping) {
|
|
3044
3485
|
return { type: "string", "x-ts-type": renderTypeText(type, checker) };
|
|
3045
3486
|
}
|
|
3046
3487
|
if (type.isUnion()) {
|
|
3047
3488
|
const types = type.types;
|
|
3048
|
-
const allStringLiterals = types.every((t) => t.flags &
|
|
3489
|
+
const allStringLiterals = types.every((t) => t.flags & ts5.TypeFlags.StringLiteral);
|
|
3049
3490
|
if (allStringLiterals) {
|
|
3050
3491
|
const enumValues = types.map((t) => t.value);
|
|
3051
3492
|
return { type: "string", enum: enumValues };
|
|
3052
3493
|
}
|
|
3053
|
-
const allNumberLiterals = types.every((t) => t.flags &
|
|
3494
|
+
const allNumberLiterals = types.every((t) => t.flags & ts5.TypeFlags.NumberLiteral);
|
|
3054
3495
|
if (allNumberLiterals) {
|
|
3055
3496
|
const enumValues = types.map((t) => t.value);
|
|
3056
3497
|
return { type: "number", enum: enumValues };
|
|
3057
3498
|
}
|
|
3058
|
-
const allBooleanLiterals = types.every((t) => t.flags &
|
|
3499
|
+
const allBooleanLiterals = types.every((t) => t.flags & ts5.TypeFlags.BooleanLiteral);
|
|
3059
3500
|
if (allBooleanLiterals) {
|
|
3060
3501
|
return { type: "boolean" };
|
|
3061
3502
|
}
|
|
3062
|
-
const isBoolLiteral = (t) => !!(t.flags &
|
|
3503
|
+
const isBoolLiteral = (t) => !!(t.flags & ts5.TypeFlags.BooleanLiteral);
|
|
3063
3504
|
let members = types;
|
|
3064
3505
|
if (types.filter(isBoolLiteral).length === 2) {
|
|
3065
3506
|
const firstBool = types.findIndex(isBoolLiteral);
|
|
@@ -3073,10 +3514,10 @@ function buildSchemaInternal(type, checker, ctx) {
|
|
|
3073
3514
|
}
|
|
3074
3515
|
return { anyOf: members.map(buildBranch) };
|
|
3075
3516
|
}
|
|
3076
|
-
const isIntersectionType = type.isIntersection() || !!(type.flags &
|
|
3517
|
+
const isIntersectionType = type.isIntersection() || !!(type.flags & ts5.TypeFlags.Intersection);
|
|
3077
3518
|
if (isIntersectionType && "types" in type) {
|
|
3078
3519
|
const intersectionType = type;
|
|
3079
|
-
const filteredTypes = intersectionType.types.filter((t) => !(t.flags &
|
|
3520
|
+
const filteredTypes = intersectionType.types.filter((t) => !(t.flags & ts5.TypeFlags.Never));
|
|
3080
3521
|
if (filteredTypes.length === 0) {
|
|
3081
3522
|
return { type: "never" };
|
|
3082
3523
|
}
|
|
@@ -3109,15 +3550,10 @@ function buildSchemaInternal(type, checker, ctx) {
|
|
|
3109
3550
|
const arrayTypeArgs = checker.getTypeArguments(arrayTypeRef);
|
|
3110
3551
|
const elementType = arrayTypeArgs?.[0];
|
|
3111
3552
|
if (elementType) {
|
|
3112
|
-
|
|
3113
|
-
|
|
3114
|
-
type: "array",
|
|
3115
|
-
items: buildSchema(elementType, checker, ctx)
|
|
3116
|
-
}));
|
|
3117
|
-
}
|
|
3118
|
-
return { type: "array", items: buildSchema(elementType, checker, ctx) };
|
|
3553
|
+
const build = () => withReadonlyArrayHint({ type: "array", items: buildSchema(elementType, checker, ctx) }, type, typeNode);
|
|
3554
|
+
return ctx ? withDepth(ctx, build) : build();
|
|
3119
3555
|
}
|
|
3120
|
-
return { type: "array" };
|
|
3556
|
+
return withReadonlyArrayHint({ type: "array" }, type, typeNode);
|
|
3121
3557
|
}
|
|
3122
3558
|
if (checker.isTupleType(type)) {
|
|
3123
3559
|
const tupleTypeRef = type;
|
|
@@ -3191,7 +3627,7 @@ function buildSchemaInternal(type, checker, ctx) {
|
|
|
3191
3627
|
if (BUILTIN_TYPES.has(name)) {
|
|
3192
3628
|
return builtinSchema(name);
|
|
3193
3629
|
}
|
|
3194
|
-
if (RESOLVED_UTILITY_TYPES.has(name) && type.flags &
|
|
3630
|
+
if (RESOLVED_UTILITY_TYPES.has(name) && type.flags & ts5.TypeFlags.Object) {
|
|
3195
3631
|
const props = type.getProperties();
|
|
3196
3632
|
const hasIndex = checker.getIndexInfosOfType(type).length > 0;
|
|
3197
3633
|
if (props.length > 0 || hasIndex) {
|
|
@@ -3229,7 +3665,7 @@ function buildSchemaInternal(type, checker, ctx) {
|
|
|
3229
3665
|
return schema;
|
|
3230
3666
|
}
|
|
3231
3667
|
}
|
|
3232
|
-
if (type.flags &
|
|
3668
|
+
if (type.flags & ts5.TypeFlags.Object) {
|
|
3233
3669
|
const callSignatures = type.getCallSignatures();
|
|
3234
3670
|
if (callSignatures.length > 0) {
|
|
3235
3671
|
return buildFunctionSchema(callSignatures, checker, ctx);
|
|
@@ -3255,10 +3691,10 @@ function buildSchemaInternal(type, checker, ctx) {
|
|
|
3255
3691
|
return schema;
|
|
3256
3692
|
}
|
|
3257
3693
|
}
|
|
3258
|
-
if (type.flags &
|
|
3694
|
+
if (type.flags & ts5.TypeFlags.Object) {
|
|
3259
3695
|
const objectType = type;
|
|
3260
3696
|
const properties = type.getProperties();
|
|
3261
|
-
if (properties.length > 0 || objectType.objectFlags &
|
|
3697
|
+
if (properties.length > 0 || objectType.objectFlags & ts5.ObjectFlags.Anonymous || checker.getIndexInfosOfType(type).length > 0) {
|
|
3262
3698
|
return buildObjectSchema(properties, checker, ctx, type);
|
|
3263
3699
|
}
|
|
3264
3700
|
}
|
|
@@ -3281,7 +3717,7 @@ function buildFunctionSchema(callSignatures, checker, ctx) {
|
|
|
3281
3717
|
const effectiveType = isOptional ? stripUndefinedFromType(paramType, checker) : paramType;
|
|
3282
3718
|
return {
|
|
3283
3719
|
name: param.getName(),
|
|
3284
|
-
schema: buildSchema(effectiveType, checker, ctx),
|
|
3720
|
+
schema: buildSchema(effectiveType, checker, ctx, decl.type),
|
|
3285
3721
|
required: !isOptional
|
|
3286
3722
|
};
|
|
3287
3723
|
});
|
|
@@ -3289,7 +3725,7 @@ function buildFunctionSchema(callSignatures, checker, ctx) {
|
|
|
3289
3725
|
return {
|
|
3290
3726
|
parameters: params,
|
|
3291
3727
|
returns: {
|
|
3292
|
-
schema: buildSchema(returnType, checker, ctx)
|
|
3728
|
+
schema: buildSchema(returnType, checker, ctx, typeNodeOfSignature(sig))
|
|
3293
3729
|
}
|
|
3294
3730
|
};
|
|
3295
3731
|
});
|
|
@@ -3302,8 +3738,8 @@ function buildFunctionSchema(callSignatures, checker, ctx) {
|
|
|
3302
3738
|
}
|
|
3303
3739
|
function buildObjectSchema(properties, checker, ctx, originalType) {
|
|
3304
3740
|
const isArrayLikeType = originalType ? checker.isArrayType(originalType) || checker.isTupleType(originalType) || originalType.symbol?.getName() === "Array" && isBuiltinSymbol(originalType.symbol) : false;
|
|
3305
|
-
const isStringLikeType = !!(originalType && originalType.flags &
|
|
3306
|
-
const isNumberLikeType = !!(originalType && originalType.flags &
|
|
3741
|
+
const isStringLikeType = !!(originalType && originalType.flags & ts5.TypeFlags.StringLike);
|
|
3742
|
+
const isNumberLikeType = !!(originalType && originalType.flags & ts5.TypeFlags.NumberLike);
|
|
3307
3743
|
const buildProps = () => {
|
|
3308
3744
|
const props = {};
|
|
3309
3745
|
const required = [];
|
|
@@ -3320,10 +3756,11 @@ function buildObjectSchema(properties, checker, ctx, originalType) {
|
|
|
3320
3756
|
if (isNumberLikeType && NUMBER_PROTOTYPE_METHODS.has(propName)) {
|
|
3321
3757
|
continue;
|
|
3322
3758
|
}
|
|
3323
|
-
const isOptionalProp = !!(prop.flags &
|
|
3759
|
+
const isOptionalProp = !!(prop.flags & ts5.SymbolFlags.Optional);
|
|
3324
3760
|
const rawPropType = checker.getTypeOfSymbol(prop);
|
|
3325
3761
|
const propType = isOptionalProp ? stripUndefinedFromType(rawPropType, checker) : rawPropType;
|
|
3326
|
-
|
|
3762
|
+
const decl = prop.valueDeclaration ?? prop.getDeclarations()?.[0];
|
|
3763
|
+
let propSchema = buildSchema(propType, checker, ctx, declaredTypeNode(decl));
|
|
3327
3764
|
const docComment = prop.getDocumentationComment(checker);
|
|
3328
3765
|
if (docComment.length > 0) {
|
|
3329
3766
|
const description = docComment.map((c) => c.text).join(`
|
|
@@ -3338,7 +3775,7 @@ function buildObjectSchema(properties, checker, ctx, originalType) {
|
|
|
3338
3775
|
}
|
|
3339
3776
|
propSchema = decoratePropertySchema(propSchema, prop, propType, checker);
|
|
3340
3777
|
props[propName] = propSchema;
|
|
3341
|
-
if (!(prop.flags &
|
|
3778
|
+
if (!(prop.flags & ts5.SymbolFlags.Optional)) {
|
|
3342
3779
|
required.push(propName);
|
|
3343
3780
|
}
|
|
3344
3781
|
}
|
|
@@ -3348,11 +3785,11 @@ function buildObjectSchema(properties, checker, ctx, originalType) {
|
|
|
3348
3785
|
...required.length > 0 ? { required } : {}
|
|
3349
3786
|
};
|
|
3350
3787
|
const indexInfos = originalType ? checker.getIndexInfosOfType(originalType) : [];
|
|
3351
|
-
const stringIndex = indexInfos.find((i) => i.keyType.flags &
|
|
3788
|
+
const stringIndex = indexInfos.find((i) => i.keyType.flags & ts5.TypeFlags.String);
|
|
3352
3789
|
if (stringIndex) {
|
|
3353
3790
|
schema.additionalProperties = buildSchema(stringIndex.type, checker, ctx);
|
|
3354
3791
|
}
|
|
3355
|
-
const numberIndex = indexInfos.find((i) => i.keyType.flags &
|
|
3792
|
+
const numberIndex = indexInfos.find((i) => i.keyType.flags & ts5.TypeFlags.Number);
|
|
3356
3793
|
if (numberIndex) {
|
|
3357
3794
|
schema.patternProperties = {
|
|
3358
3795
|
"^\\d+$": buildSchema(numberIndex.type, checker, ctx)
|
|
@@ -3441,7 +3878,7 @@ function deduplicateSchemas(schemas) {
|
|
|
3441
3878
|
function findDiscriminatorProperty(unionTypes, checker) {
|
|
3442
3879
|
const memberProps = [];
|
|
3443
3880
|
for (const t of unionTypes) {
|
|
3444
|
-
if (t.flags & (
|
|
3881
|
+
if (t.flags & (ts5.TypeFlags.Null | ts5.TypeFlags.Undefined)) {
|
|
3445
3882
|
continue;
|
|
3446
3883
|
}
|
|
3447
3884
|
const props = t.getProperties();
|
|
@@ -3495,24 +3932,27 @@ function extractParameters(signature, ctx) {
|
|
|
3495
3932
|
const { typeChecker: checker } = ctx;
|
|
3496
3933
|
const result = [];
|
|
3497
3934
|
const signatureDecl = signature.getDeclaration();
|
|
3498
|
-
const jsdocTags = signatureDecl ?
|
|
3935
|
+
const jsdocTags = signatureDecl ? ts6.getJSDocTags(signatureDecl) : [];
|
|
3499
3936
|
for (const param of signature.getParameters()) {
|
|
3500
3937
|
const decl = param.valueDeclaration;
|
|
3501
3938
|
if (!decl)
|
|
3502
3939
|
continue;
|
|
3503
|
-
const
|
|
3504
|
-
|
|
3505
|
-
|
|
3940
|
+
const defer = typeNodeDefersExpansion(decl.type, checker, ctx.program);
|
|
3941
|
+
const type = defer ? undefined : checker.getTypeOfSymbolAtLocation(param, decl);
|
|
3942
|
+
if (decl && ts6.isObjectBindingPattern(decl.name)) {
|
|
3943
|
+
const expandedParams = expandBindingPattern(decl, type ?? checker.getTypeOfSymbolAtLocation(param, decl), jsdocTags, ctx);
|
|
3506
3944
|
result.push(...expandedParams);
|
|
3507
3945
|
} else {
|
|
3508
3946
|
const isOptional = !!decl?.questionToken || !!decl?.initializer;
|
|
3509
|
-
const effectiveType = isOptional ? stripUndefinedFromType(type, checker) : type;
|
|
3510
|
-
registerReferencedTypes(effectiveType, ctx);
|
|
3511
3947
|
const paramName = param.getName();
|
|
3512
3948
|
const description = getParamDescription(paramName, jsdocTags);
|
|
3949
|
+
const schema = defer ? buildSchemaFromTypeNode(decl.type, checker, ctx) : buildSchema(isOptional ? stripUndefinedFromType(type, checker) : type, checker, ctx, decl.type);
|
|
3950
|
+
if (!defer && type) {
|
|
3951
|
+
registerReferencedTypes(isOptional ? stripUndefinedFromType(type, checker) : type, ctx);
|
|
3952
|
+
}
|
|
3513
3953
|
const paramResult = {
|
|
3514
3954
|
name: paramName,
|
|
3515
|
-
schema
|
|
3955
|
+
schema,
|
|
3516
3956
|
required: !isOptional
|
|
3517
3957
|
};
|
|
3518
3958
|
if (description) {
|
|
@@ -3536,20 +3976,20 @@ function expandBindingPattern(paramDecl, paramType, jsdocTags, ctx) {
|
|
|
3536
3976
|
const allProperties = getEffectiveProperties(paramType, checker);
|
|
3537
3977
|
const inferredAlias = inferParamAlias(jsdocTags);
|
|
3538
3978
|
for (const element of bindingPattern.elements) {
|
|
3539
|
-
if (!
|
|
3979
|
+
if (!ts6.isBindingElement(element))
|
|
3540
3980
|
continue;
|
|
3541
|
-
const propertyName = element.propertyName ?
|
|
3981
|
+
const propertyName = element.propertyName ? ts6.isIdentifier(element.propertyName) ? element.propertyName.text : element.propertyName.getText() : ts6.isIdentifier(element.name) ? element.name.text : element.name.getText();
|
|
3542
3982
|
const propSymbol = allProperties.get(propertyName);
|
|
3543
3983
|
if (!propSymbol)
|
|
3544
3984
|
continue;
|
|
3545
|
-
const isOptional = !!(propSymbol.flags &
|
|
3985
|
+
const isOptional = !!(propSymbol.flags & ts6.SymbolFlags.Optional) || element.initializer !== undefined;
|
|
3546
3986
|
const propType = checker.getTypeOfSymbol(propSymbol);
|
|
3547
3987
|
const effectiveType = isOptional ? stripUndefinedFromType(propType, checker) : propType;
|
|
3548
3988
|
registerReferencedTypes(effectiveType, ctx);
|
|
3549
3989
|
const description = getParamDescription(propertyName, jsdocTags, inferredAlias);
|
|
3550
3990
|
const param = {
|
|
3551
3991
|
name: propertyName,
|
|
3552
|
-
schema: buildSchema(effectiveType, checker, ctx),
|
|
3992
|
+
schema: buildSchema(effectiveType, checker, ctx, declaredTypeNode(propSymbol.valueDeclaration)),
|
|
3553
3993
|
required: !isOptional
|
|
3554
3994
|
};
|
|
3555
3995
|
if (description) {
|
|
@@ -3585,7 +4025,7 @@ function inferParamAlias(jsdocTags) {
|
|
|
3585
4025
|
for (const tag of jsdocTags) {
|
|
3586
4026
|
if (tag.tagName.text !== "param")
|
|
3587
4027
|
continue;
|
|
3588
|
-
const tagText = typeof tag.comment === "string" ? tag.comment :
|
|
4028
|
+
const tagText = typeof tag.comment === "string" ? tag.comment : ts6.getTextOfJSDocComment(tag.comment) ?? "";
|
|
3589
4029
|
const paramTag = tag;
|
|
3590
4030
|
const paramName = paramTag.name?.getText() ?? "";
|
|
3591
4031
|
if (paramName.includes(".")) {
|
|
@@ -3608,22 +4048,22 @@ function inferParamAlias(jsdocTags) {
|
|
|
3608
4048
|
return Array.from(counts.entries()).sort((a, b) => b[1] - a[1])[0]?.[0];
|
|
3609
4049
|
}
|
|
3610
4050
|
function extractLiteralDefault(initializer) {
|
|
3611
|
-
if (
|
|
4051
|
+
if (ts6.isStringLiteral(initializer)) {
|
|
3612
4052
|
return { literal: true, value: initializer.text };
|
|
3613
4053
|
}
|
|
3614
|
-
if (
|
|
4054
|
+
if (ts6.isNumericLiteral(initializer)) {
|
|
3615
4055
|
return { literal: true, value: Number(initializer.text) };
|
|
3616
4056
|
}
|
|
3617
|
-
if (
|
|
4057
|
+
if (ts6.isPrefixUnaryExpression(initializer) && initializer.operator === ts6.SyntaxKind.MinusToken && ts6.isNumericLiteral(initializer.operand)) {
|
|
3618
4058
|
return { literal: true, value: -Number(initializer.operand.text) };
|
|
3619
4059
|
}
|
|
3620
|
-
if (initializer.kind ===
|
|
4060
|
+
if (initializer.kind === ts6.SyntaxKind.TrueKeyword) {
|
|
3621
4061
|
return { literal: true, value: true };
|
|
3622
4062
|
}
|
|
3623
|
-
if (initializer.kind ===
|
|
4063
|
+
if (initializer.kind === ts6.SyntaxKind.FalseKeyword) {
|
|
3624
4064
|
return { literal: true, value: false };
|
|
3625
4065
|
}
|
|
3626
|
-
if (initializer.kind ===
|
|
4066
|
+
if (initializer.kind === ts6.SyntaxKind.NullKeyword) {
|
|
3627
4067
|
return { literal: true, value: null };
|
|
3628
4068
|
}
|
|
3629
4069
|
return { literal: false, text: initializer.getText() };
|
|
@@ -3635,8 +4075,11 @@ function applyDefault(param, initializer) {
|
|
|
3635
4075
|
if (param.schema && typeof param.schema === "object" && !Array.isArray(param.schema)) {
|
|
3636
4076
|
param.schema.default = extracted.value;
|
|
3637
4077
|
}
|
|
3638
|
-
} else
|
|
3639
|
-
param.
|
|
4078
|
+
} else {
|
|
4079
|
+
param.default = extracted.text;
|
|
4080
|
+
if (param.schema && typeof param.schema === "object" && !Array.isArray(param.schema)) {
|
|
4081
|
+
param.schema["x-ts-default"] = extracted.text;
|
|
4082
|
+
}
|
|
3640
4083
|
}
|
|
3641
4084
|
}
|
|
3642
4085
|
function registerReferencedTypes(type, ctx, depth = 0) {
|
|
@@ -3644,7 +4087,7 @@ function registerReferencedTypes(type, ctx, depth = 0) {
|
|
|
3644
4087
|
return;
|
|
3645
4088
|
if (ctx.registeredTypes.has(type))
|
|
3646
4089
|
return;
|
|
3647
|
-
const isPrimitive = type.flags & (
|
|
4090
|
+
const isPrimitive = type.flags & (ts6.TypeFlags.String | ts6.TypeFlags.Number | ts6.TypeFlags.Boolean | ts6.TypeFlags.Void | ts6.TypeFlags.Undefined | ts6.TypeFlags.Null | ts6.TypeFlags.Any | ts6.TypeFlags.Unknown | ts6.TypeFlags.Never | ts6.TypeFlags.StringLiteral | ts6.TypeFlags.NumberLiteral | ts6.TypeFlags.BooleanLiteral);
|
|
3648
4091
|
if (!isPrimitive) {
|
|
3649
4092
|
ctx.registeredTypes.add(type);
|
|
3650
4093
|
}
|
|
@@ -3673,7 +4116,10 @@ function registerReferencedTypes(type, ctx, depth = 0) {
|
|
|
3673
4116
|
if (isForeignPackage(typeSymbol, ctx.workspacePackages)) {
|
|
3674
4117
|
return;
|
|
3675
4118
|
}
|
|
3676
|
-
if (type
|
|
4119
|
+
if (isDeferredMappedOrConditional(type)) {
|
|
4120
|
+
return;
|
|
4121
|
+
}
|
|
4122
|
+
if (type.flags & ts6.TypeFlags.Object) {
|
|
3677
4123
|
const props = type.getProperties();
|
|
3678
4124
|
const limit = ctx.maxProperties;
|
|
3679
4125
|
if (props.length > limit && ctx.onTruncation) {
|
|
@@ -3688,10 +4134,10 @@ function registerReferencedTypes(type, ctx, depth = 0) {
|
|
|
3688
4134
|
}
|
|
3689
4135
|
|
|
3690
4136
|
// src/serializers/context.ts
|
|
3691
|
-
import
|
|
4137
|
+
import ts8 from "typescript";
|
|
3692
4138
|
|
|
3693
4139
|
// src/ast/registry.ts
|
|
3694
|
-
import
|
|
4140
|
+
import ts7 from "typescript";
|
|
3695
4141
|
var BUILTINS = new Set([
|
|
3696
4142
|
"Array",
|
|
3697
4143
|
"ArrayBuffer",
|
|
@@ -3788,9 +4234,10 @@ class TypeRegistry {
|
|
|
3788
4234
|
return this.types.size;
|
|
3789
4235
|
}
|
|
3790
4236
|
registerType(type, ctx) {
|
|
3791
|
-
const
|
|
3792
|
-
if (!
|
|
4237
|
+
const rawSymbol = type.aliasSymbol || type.getSymbol();
|
|
4238
|
+
if (!rawSymbol)
|
|
3793
4239
|
return;
|
|
4240
|
+
const symbol = resolveAliasSymbol(rawSymbol, ctx.typeChecker, undefined, ctx.program);
|
|
3794
4241
|
const name = symbol.getName();
|
|
3795
4242
|
if (PRIMITIVES.has(name))
|
|
3796
4243
|
return;
|
|
@@ -3800,13 +4247,13 @@ class TypeRegistry {
|
|
|
3800
4247
|
return;
|
|
3801
4248
|
if (name.startsWith('"'))
|
|
3802
4249
|
return;
|
|
3803
|
-
if (symbol.flags &
|
|
4250
|
+
if (symbol.flags & ts7.SymbolFlags.EnumMember)
|
|
3804
4251
|
return;
|
|
3805
|
-
if (symbol.flags &
|
|
4252
|
+
if (symbol.flags & ts7.SymbolFlags.TypeParameter)
|
|
3806
4253
|
return;
|
|
3807
|
-
if (symbol.flags &
|
|
4254
|
+
if (symbol.flags & ts7.SymbolFlags.Method)
|
|
3808
4255
|
return;
|
|
3809
|
-
if (symbol.flags &
|
|
4256
|
+
if (symbol.flags & ts7.SymbolFlags.Function)
|
|
3810
4257
|
return;
|
|
3811
4258
|
if (isGenericTypeParameter(name))
|
|
3812
4259
|
return;
|
|
@@ -3829,7 +4276,7 @@ class TypeRegistry {
|
|
|
3829
4276
|
});
|
|
3830
4277
|
return id;
|
|
3831
4278
|
};
|
|
3832
|
-
if (ctx.shouldExpandExternal && !ctx.shouldExpandExternal(symbol)) {
|
|
4279
|
+
if (symbol.declarations?.[0] && ctx.shouldExpandExternal && !ctx.shouldExpandExternal(symbol)) {
|
|
3833
4280
|
return stubExternal();
|
|
3834
4281
|
}
|
|
3835
4282
|
if (this.types.size >= MAX_REGISTERED_TYPES) {
|
|
@@ -3856,11 +4303,11 @@ class TypeRegistry {
|
|
|
3856
4303
|
let kind = "type";
|
|
3857
4304
|
const external = decl ? isExternalType(decl) : false;
|
|
3858
4305
|
if (decl) {
|
|
3859
|
-
if (
|
|
4306
|
+
if (ts7.isClassDeclaration(decl))
|
|
3860
4307
|
kind = "class";
|
|
3861
|
-
else if (
|
|
4308
|
+
else if (ts7.isInterfaceDeclaration(decl))
|
|
3862
4309
|
kind = "interface";
|
|
3863
|
-
else if (
|
|
4310
|
+
else if (ts7.isEnumDeclaration(decl))
|
|
3864
4311
|
kind = "enum";
|
|
3865
4312
|
}
|
|
3866
4313
|
if (external) {
|
|
@@ -3876,8 +4323,8 @@ class TypeRegistry {
|
|
|
3876
4323
|
schema = enumSchema;
|
|
3877
4324
|
}
|
|
3878
4325
|
}
|
|
3879
|
-
if (kind === "type" && decl &&
|
|
3880
|
-
const text = renderTypeText(type, checker, decl,
|
|
4326
|
+
if (kind === "type" && decl && ts7.isTypeAliasDeclaration(decl) && shouldEmitAliasTypeText(decl.type) && typeof schema === "object" && schema !== null && !("x-ts-type" in schema)) {
|
|
4327
|
+
const text = renderTypeText(type, checker, decl, ts7.TypeFormatFlags.InTypeAlias);
|
|
3881
4328
|
if (!PRIMITIVES.has(text) && text !== name) {
|
|
3882
4329
|
schema["x-ts-type"] = text;
|
|
3883
4330
|
const declared = writtenTypeText(declaredTypeNode(decl));
|
|
@@ -3887,7 +4334,7 @@ class TypeRegistry {
|
|
|
3887
4334
|
}
|
|
3888
4335
|
}
|
|
3889
4336
|
let typeParameters;
|
|
3890
|
-
if (decl && (
|
|
4337
|
+
if (decl && (ts7.isTypeAliasDeclaration(decl) || ts7.isInterfaceDeclaration(decl) || ts7.isClassDeclaration(decl))) {
|
|
3891
4338
|
typeParameters = extractTypeParameters(decl, checker);
|
|
3892
4339
|
}
|
|
3893
4340
|
return {
|
|
@@ -3908,14 +4355,14 @@ class TypeRegistry {
|
|
|
3908
4355
|
resolveSelRefSchema(type, checker, ctx) {
|
|
3909
4356
|
if (type.isUnion()) {
|
|
3910
4357
|
const types = type.types;
|
|
3911
|
-
const allStringLiterals = types.every((t) => t.flags &
|
|
4358
|
+
const allStringLiterals = types.every((t) => t.flags & ts7.TypeFlags.StringLiteral);
|
|
3912
4359
|
if (allStringLiterals) {
|
|
3913
4360
|
return {
|
|
3914
4361
|
type: "string",
|
|
3915
4362
|
enum: types.map((t) => t.value)
|
|
3916
4363
|
};
|
|
3917
4364
|
}
|
|
3918
|
-
const allNumberLiterals = types.every((t) => t.flags &
|
|
4365
|
+
const allNumberLiterals = types.every((t) => t.flags & ts7.TypeFlags.NumberLiteral);
|
|
3919
4366
|
if (allNumberLiterals) {
|
|
3920
4367
|
return {
|
|
3921
4368
|
type: "number",
|
|
@@ -3950,18 +4397,18 @@ class TypeRegistry {
|
|
|
3950
4397
|
const elementType = checker.getTypeArguments(type)?.[0];
|
|
3951
4398
|
return elementType ? { type: "array", items: buildSchema(elementType, checker, ctx) } : { type: "array" };
|
|
3952
4399
|
}
|
|
3953
|
-
if (type.flags &
|
|
4400
|
+
if (type.flags & ts7.TypeFlags.Conditional) {
|
|
3954
4401
|
return { "x-ts-type": renderTypeText(type, checker) };
|
|
3955
4402
|
}
|
|
3956
4403
|
const constraint = checker.getBaseConstraintOfType(type);
|
|
3957
|
-
const primitive = constraint && constraint.flags &
|
|
4404
|
+
const primitive = constraint && constraint.flags & ts7.TypeFlags.StringLike ? "string" : constraint && constraint.flags & ts7.TypeFlags.NumberLike ? "number" : constraint && constraint.flags & ts7.TypeFlags.BooleanLike ? "boolean" : undefined;
|
|
3958
4405
|
if (primitive) {
|
|
3959
4406
|
return { type: primitive, "x-ts-type": renderTypeText(type, checker) };
|
|
3960
4407
|
}
|
|
3961
4408
|
return this.buildObjectSchemaFromProperties(type, checker, ctx);
|
|
3962
4409
|
}
|
|
3963
4410
|
buildEnumSchema(symbol, checker) {
|
|
3964
|
-
const decl = symbol.declarations?.find(
|
|
4411
|
+
const decl = symbol.declarations?.find(ts7.isEnumDeclaration);
|
|
3965
4412
|
if (!decl)
|
|
3966
4413
|
return;
|
|
3967
4414
|
const members = [];
|
|
@@ -3988,8 +4435,8 @@ class TypeRegistry {
|
|
|
3988
4435
|
buildObjectSchemaFromProperties(type, checker, ctx) {
|
|
3989
4436
|
const properties = type.getProperties();
|
|
3990
4437
|
const indexInfos = checker.getIndexInfosOfType(type);
|
|
3991
|
-
const stringIndex = indexInfos.find((i) => i.keyType.flags &
|
|
3992
|
-
const numberIndex = indexInfos.find((i) => i.keyType.flags &
|
|
4438
|
+
const stringIndex = indexInfos.find((i) => i.keyType.flags & ts7.TypeFlags.String);
|
|
4439
|
+
const numberIndex = indexInfos.find((i) => i.keyType.flags & ts7.TypeFlags.Number);
|
|
3993
4440
|
if (properties.length === 0 && !stringIndex && !numberIndex) {
|
|
3994
4441
|
return { type: checker.typeToString(type) };
|
|
3995
4442
|
}
|
|
@@ -3997,8 +4444,8 @@ class TypeRegistry {
|
|
|
3997
4444
|
const required = [];
|
|
3998
4445
|
const limit = ctx.maxProperties;
|
|
3999
4446
|
const isArrayLike = checker.isArrayType(type) || checker.isTupleType(type) || type.symbol?.getName() === "Array" && isLibFile(type.symbol?.getDeclarations()?.[0]?.getSourceFile()?.fileName ?? "");
|
|
4000
|
-
const isStringLike = type.flags &
|
|
4001
|
-
const isNumberLike = type.flags &
|
|
4447
|
+
const isStringLike = type.flags & ts7.TypeFlags.StringLike;
|
|
4448
|
+
const isNumberLike = type.flags & ts7.TypeFlags.NumberLike;
|
|
4002
4449
|
const included = properties.filter((prop) => {
|
|
4003
4450
|
const propName = prop.getName();
|
|
4004
4451
|
if (propName.startsWith("__@"))
|
|
@@ -4018,9 +4465,9 @@ class TypeRegistry {
|
|
|
4018
4465
|
for (const prop of included.slice(0, limit)) {
|
|
4019
4466
|
const propName = prop.getName();
|
|
4020
4467
|
const rawPropType = checker.getTypeOfSymbol(prop);
|
|
4021
|
-
const propType = prop.flags &
|
|
4468
|
+
const propType = prop.flags & ts7.SymbolFlags.Optional ? stripUndefinedFromType(rawPropType, checker) : rawPropType;
|
|
4022
4469
|
this.registerType(propType, ctx);
|
|
4023
|
-
let propSchema = buildSchema(propType, checker, ctx);
|
|
4470
|
+
let propSchema = buildSchema(propType, checker, ctx, declaredTypeNode(prop.valueDeclaration ?? prop.getDeclarations()?.[0]));
|
|
4024
4471
|
const docComment = prop.getDocumentationComment(checker);
|
|
4025
4472
|
if (docComment.length > 0) {
|
|
4026
4473
|
const description = docComment.map((c) => c.text).join(`
|
|
@@ -4035,7 +4482,7 @@ class TypeRegistry {
|
|
|
4035
4482
|
}
|
|
4036
4483
|
propSchema = decoratePropertySchema(propSchema, prop, propType, checker);
|
|
4037
4484
|
props[propName] = propSchema;
|
|
4038
|
-
if (!(prop.flags &
|
|
4485
|
+
if (!(prop.flags & ts7.SymbolFlags.Optional)) {
|
|
4039
4486
|
required.push(propName);
|
|
4040
4487
|
}
|
|
4041
4488
|
}
|
|
@@ -4071,7 +4518,10 @@ function createContext(program, sourceFile, options = {}) {
|
|
|
4071
4518
|
typeIds: new Map,
|
|
4072
4519
|
declIds: new Map,
|
|
4073
4520
|
idOwner: new Map,
|
|
4074
|
-
workspacePackages: options.workspacePackages ?? new Map
|
|
4521
|
+
workspacePackages: options.workspacePackages ?? new Map,
|
|
4522
|
+
schemaOps: 0,
|
|
4523
|
+
maxSchemaOps: 20000,
|
|
4524
|
+
budgetExceeded: false
|
|
4075
4525
|
};
|
|
4076
4526
|
}
|
|
4077
4527
|
function getInheritedMembers(classType, ownMemberNames, ctx, isStatic = false) {
|
|
@@ -4140,15 +4590,15 @@ function serializeInheritedMember(symbol, inheritedFrom, ctx, isStatic) {
|
|
|
4140
4590
|
const type = checker.getTypeOfSymbol(symbol);
|
|
4141
4591
|
registerReferencedTypes(type, ctx);
|
|
4142
4592
|
let visibility;
|
|
4143
|
-
if (decl &&
|
|
4144
|
-
const modifiers =
|
|
4593
|
+
if (decl && ts8.canHaveModifiers(decl)) {
|
|
4594
|
+
const modifiers = ts8.getModifiers(decl);
|
|
4145
4595
|
if (modifiers) {
|
|
4146
4596
|
for (const mod of modifiers) {
|
|
4147
|
-
if (mod.kind ===
|
|
4597
|
+
if (mod.kind === ts8.SyntaxKind.PrivateKeyword)
|
|
4148
4598
|
visibility = "private";
|
|
4149
|
-
else if (mod.kind ===
|
|
4599
|
+
else if (mod.kind === ts8.SyntaxKind.ProtectedKeyword)
|
|
4150
4600
|
visibility = "protected";
|
|
4151
|
-
else if (mod.kind ===
|
|
4601
|
+
else if (mod.kind === ts8.SyntaxKind.PublicKeyword)
|
|
4152
4602
|
visibility = "public";
|
|
4153
4603
|
}
|
|
4154
4604
|
}
|
|
@@ -4160,17 +4610,17 @@ function serializeInheritedMember(symbol, inheritedFrom, ctx, isStatic) {
|
|
|
4160
4610
|
const callSigs = type.getCallSignatures();
|
|
4161
4611
|
if (callSigs.length > 0) {
|
|
4162
4612
|
kind = "method";
|
|
4163
|
-
} else if (
|
|
4613
|
+
} else if (ts8.isGetAccessorDeclaration(decl)) {
|
|
4164
4614
|
kind = "getter";
|
|
4165
|
-
} else if (
|
|
4615
|
+
} else if (ts8.isSetAccessorDeclaration(decl)) {
|
|
4166
4616
|
kind = "setter";
|
|
4167
4617
|
}
|
|
4168
4618
|
const flags = {};
|
|
4169
4619
|
if (isStatic)
|
|
4170
4620
|
flags.static = true;
|
|
4171
|
-
if (decl &&
|
|
4172
|
-
const modifiers =
|
|
4173
|
-
if (modifiers?.some((m) => m.kind ===
|
|
4621
|
+
if (decl && ts8.canHaveModifiers(decl)) {
|
|
4622
|
+
const modifiers = ts8.getModifiers(decl);
|
|
4623
|
+
if (modifiers?.some((m) => m.kind === ts8.SyntaxKind.ReadonlyKeyword)) {
|
|
4174
4624
|
flags.readonly = true;
|
|
4175
4625
|
}
|
|
4176
4626
|
}
|
|
@@ -4184,7 +4634,7 @@ function serializeInheritedMember(symbol, inheritedFrom, ctx, isStatic) {
|
|
|
4184
4634
|
return {
|
|
4185
4635
|
parameters: params.length > 0 ? params : undefined,
|
|
4186
4636
|
returns: {
|
|
4187
|
-
schema: buildSchema(returnType, checker, ctx)
|
|
4637
|
+
schema: buildSchema(returnType, checker, ctx, typeNodeOfSignature(sig))
|
|
4188
4638
|
},
|
|
4189
4639
|
...sigDoc.description ? { description: sigDoc.description } : {},
|
|
4190
4640
|
...sigDoc.tags.length > 0 ? { tags: sigDoc.tags } : {},
|
|
@@ -4200,7 +4650,7 @@ function serializeInheritedMember(symbol, inheritedFrom, ctx, isStatic) {
|
|
|
4200
4650
|
description,
|
|
4201
4651
|
tags: tags.length > 0 ? tags : undefined,
|
|
4202
4652
|
visibility,
|
|
4203
|
-
schema: kind !== "method" ? buildSchema(type, checker, ctx) : decoratePropertySchema({ "x-ts-function": true }, symbol, type, checker),
|
|
4653
|
+
schema: kind !== "method" ? buildSchema(type, checker, ctx, declaredTypeNode(decl)) : decoratePropertySchema({ "x-ts-function": true }, symbol, type, checker),
|
|
4204
4654
|
signatures,
|
|
4205
4655
|
flags: Object.keys(flags).length > 0 ? flags : undefined,
|
|
4206
4656
|
...inlineTags ? { inlineTags } : {}
|
|
@@ -4223,7 +4673,7 @@ function buildSignatures(callSignatures, checker, ctx) {
|
|
|
4223
4673
|
const sigTypeParams = extractTypeParametersFromSignature(sig, checker);
|
|
4224
4674
|
return {
|
|
4225
4675
|
parameters: params.length > 0 ? params : undefined,
|
|
4226
|
-
returns: { schema: buildSchema(returnType, checker, ctx) },
|
|
4676
|
+
returns: { schema: buildSchema(returnType, checker, ctx, typeNodeOfSignature(sig)) },
|
|
4227
4677
|
...sigDoc.description ? { description: sigDoc.description } : {},
|
|
4228
4678
|
...sigDoc.tags.length > 0 ? { tags: sigDoc.tags } : {},
|
|
4229
4679
|
...sigDoc.examples.length > 0 ? { examples: sigDoc.examples } : {},
|
|
@@ -4250,11 +4700,11 @@ function serializeClass(node, ctx) {
|
|
|
4250
4700
|
const memberName = getMemberName(member);
|
|
4251
4701
|
if (memberName?.startsWith("#"))
|
|
4252
4702
|
continue;
|
|
4253
|
-
if (
|
|
4703
|
+
if (ts9.isPropertyDeclaration(member)) {
|
|
4254
4704
|
const propMember = serializeProperty(member, ctx);
|
|
4255
4705
|
if (propMember)
|
|
4256
4706
|
members.push(propMember);
|
|
4257
|
-
} else if (
|
|
4707
|
+
} else if (ts9.isMethodDeclaration(member)) {
|
|
4258
4708
|
const methodMember = serializeMethod(member, ctx);
|
|
4259
4709
|
if (methodMember?.name) {
|
|
4260
4710
|
if (!methodsByName.has(methodMember.name)) {
|
|
@@ -4271,11 +4721,11 @@ function serializeClass(node, ctx) {
|
|
|
4271
4721
|
}
|
|
4272
4722
|
}
|
|
4273
4723
|
}
|
|
4274
|
-
} else if (
|
|
4724
|
+
} else if (ts9.isConstructorDeclaration(member)) {
|
|
4275
4725
|
const ctorSig = serializeConstructor(member, ctx);
|
|
4276
4726
|
if (ctorSig)
|
|
4277
4727
|
signatures.push(ctorSig);
|
|
4278
|
-
} else if (
|
|
4728
|
+
} else if (ts9.isGetAccessorDeclaration(member) || ts9.isSetAccessorDeclaration(member)) {
|
|
4279
4729
|
const accessorMember = serializeAccessor(member, ctx);
|
|
4280
4730
|
if (accessorMember)
|
|
4281
4731
|
members.push(accessorMember);
|
|
@@ -4299,8 +4749,8 @@ function serializeClass(node, ctx) {
|
|
|
4299
4749
|
const extendsClause = getExtendsClause(node, checker);
|
|
4300
4750
|
const implementsClause = getImplementsClause(node, checker);
|
|
4301
4751
|
const classFlags = {};
|
|
4302
|
-
const classModifiers =
|
|
4303
|
-
if (classModifiers?.some((m) => m.kind ===
|
|
4752
|
+
const classModifiers = ts9.getModifiers(node);
|
|
4753
|
+
if (classModifiers?.some((m) => m.kind === ts9.SyntaxKind.AbstractKeyword)) {
|
|
4304
4754
|
classFlags.abstract = true;
|
|
4305
4755
|
}
|
|
4306
4756
|
return {
|
|
@@ -4322,37 +4772,37 @@ function serializeClass(node, ctx) {
|
|
|
4322
4772
|
};
|
|
4323
4773
|
}
|
|
4324
4774
|
function getMemberName(member) {
|
|
4325
|
-
if (
|
|
4775
|
+
if (ts9.isConstructorDeclaration(member))
|
|
4326
4776
|
return "constructor";
|
|
4327
4777
|
if (!member.name)
|
|
4328
4778
|
return;
|
|
4329
|
-
if (
|
|
4779
|
+
if (ts9.isIdentifier(member.name))
|
|
4330
4780
|
return member.name.text;
|
|
4331
|
-
if (
|
|
4781
|
+
if (ts9.isPrivateIdentifier(member.name))
|
|
4332
4782
|
return member.name.text;
|
|
4333
4783
|
return member.name.getText();
|
|
4334
4784
|
}
|
|
4335
4785
|
function getVisibility(member) {
|
|
4336
|
-
const modifiers =
|
|
4786
|
+
const modifiers = ts9.canHaveModifiers(member) ? ts9.getModifiers(member) : undefined;
|
|
4337
4787
|
if (!modifiers)
|
|
4338
4788
|
return;
|
|
4339
4789
|
for (const mod of modifiers) {
|
|
4340
|
-
if (mod.kind ===
|
|
4790
|
+
if (mod.kind === ts9.SyntaxKind.PrivateKeyword)
|
|
4341
4791
|
return "private";
|
|
4342
|
-
if (mod.kind ===
|
|
4792
|
+
if (mod.kind === ts9.SyntaxKind.ProtectedKeyword)
|
|
4343
4793
|
return "protected";
|
|
4344
|
-
if (mod.kind ===
|
|
4794
|
+
if (mod.kind === ts9.SyntaxKind.PublicKeyword)
|
|
4345
4795
|
return "public";
|
|
4346
4796
|
}
|
|
4347
4797
|
return;
|
|
4348
4798
|
}
|
|
4349
4799
|
function isStatic(member) {
|
|
4350
|
-
const modifiers =
|
|
4351
|
-
return modifiers?.some((m) => m.kind ===
|
|
4800
|
+
const modifiers = ts9.canHaveModifiers(member) ? ts9.getModifiers(member) : undefined;
|
|
4801
|
+
return modifiers?.some((m) => m.kind === ts9.SyntaxKind.StaticKeyword) ?? false;
|
|
4352
4802
|
}
|
|
4353
4803
|
function isReadonly(member) {
|
|
4354
|
-
const modifiers =
|
|
4355
|
-
return modifiers?.some((m) => m.kind ===
|
|
4804
|
+
const modifiers = ts9.canHaveModifiers(member) ? ts9.getModifiers(member) : undefined;
|
|
4805
|
+
return modifiers?.some((m) => m.kind === ts9.SyntaxKind.ReadonlyKeyword) ?? false;
|
|
4356
4806
|
}
|
|
4357
4807
|
function serializeProperty(node, ctx) {
|
|
4358
4808
|
const { typeChecker: checker } = ctx;
|
|
@@ -4367,7 +4817,7 @@ function serializeProperty(node, ctx) {
|
|
|
4367
4817
|
const rawType = checker.getTypeAtLocation(node);
|
|
4368
4818
|
const type = node.questionToken ? stripUndefinedFromType(rawType, checker) : rawType;
|
|
4369
4819
|
registerReferencedTypes(type, ctx);
|
|
4370
|
-
let schema = buildSchema(type, checker, ctx);
|
|
4820
|
+
let schema = buildSchema(type, checker, ctx, node.type);
|
|
4371
4821
|
const flags = {};
|
|
4372
4822
|
if (isStatic(node))
|
|
4373
4823
|
flags.static = true;
|
|
@@ -4411,11 +4861,11 @@ function serializeMethod(node, ctx) {
|
|
|
4411
4861
|
if (node.asteriskToken)
|
|
4412
4862
|
flags.generator = true;
|
|
4413
4863
|
flags.methodSyntax = true;
|
|
4414
|
-
const modifiers =
|
|
4415
|
-
if (modifiers?.some((m) => m.kind ===
|
|
4864
|
+
const modifiers = ts9.getModifiers(node);
|
|
4865
|
+
if (modifiers?.some((m) => m.kind === ts9.SyntaxKind.AsyncKeyword)) {
|
|
4416
4866
|
flags.async = true;
|
|
4417
4867
|
}
|
|
4418
|
-
if (modifiers?.some((m) => m.kind ===
|
|
4868
|
+
if (modifiers?.some((m) => m.kind === ts9.SyntaxKind.AbstractKeyword)) {
|
|
4419
4869
|
flags.abstract = true;
|
|
4420
4870
|
}
|
|
4421
4871
|
const symbol = checker.getSymbolAtLocation(node.name ?? node);
|
|
@@ -4454,7 +4904,7 @@ function serializeConstructorSignature(node, sig, ctx) {
|
|
|
4454
4904
|
}
|
|
4455
4905
|
function serializeInheritedConstructors(node, ctx) {
|
|
4456
4906
|
const { typeChecker: checker } = ctx;
|
|
4457
|
-
const hasExtends = node.heritageClauses?.some((c) => c.token ===
|
|
4907
|
+
const hasExtends = node.heritageClauses?.some((c) => c.token === ts9.SyntaxKind.ExtendsKeyword);
|
|
4458
4908
|
if (!hasExtends)
|
|
4459
4909
|
return [];
|
|
4460
4910
|
const symbol = checker.getSymbolAtLocation(node.name ?? node);
|
|
@@ -4463,11 +4913,11 @@ function serializeInheritedConstructors(node, ctx) {
|
|
|
4463
4913
|
const staticType = checker.getTypeOfSymbolAtLocation(symbol, node);
|
|
4464
4914
|
const ctorSigs = staticType.getConstructSignatures().filter((sig) => {
|
|
4465
4915
|
const decl = sig.getDeclaration();
|
|
4466
|
-
return decl !== undefined &&
|
|
4916
|
+
return decl !== undefined && ts9.isConstructorDeclaration(decl);
|
|
4467
4917
|
});
|
|
4468
4918
|
return ctorSigs.map((sig, index) => {
|
|
4469
4919
|
const decl = sig.getDeclaration();
|
|
4470
|
-
const owner =
|
|
4920
|
+
const owner = ts9.isClassLike(decl.parent) ? decl.parent.name?.text : undefined;
|
|
4471
4921
|
return {
|
|
4472
4922
|
...serializeConstructorSignature(decl, sig, ctx),
|
|
4473
4923
|
...owner ? { inheritedFrom: owner } : {},
|
|
@@ -4486,14 +4936,14 @@ function serializeAccessor(node, ctx) {
|
|
|
4486
4936
|
return null;
|
|
4487
4937
|
}
|
|
4488
4938
|
const type = checker.getTypeAtLocation(node);
|
|
4489
|
-
const schema = buildSchema(type, checker, ctx);
|
|
4939
|
+
const schema = buildSchema(type, checker, ctx, ts9.isGetAccessorDeclaration(node) ? node.type : undefined);
|
|
4490
4940
|
registerReferencedTypes(type, ctx);
|
|
4491
|
-
const kind =
|
|
4941
|
+
const kind = ts9.isGetAccessorDeclaration(node) ? "getter" : "setter";
|
|
4492
4942
|
const flags = {};
|
|
4493
4943
|
if (isStatic(node))
|
|
4494
4944
|
flags.static = true;
|
|
4495
4945
|
let signatures;
|
|
4496
|
-
if (
|
|
4946
|
+
if (ts9.isSetAccessorDeclaration(node) && node.parameters.length > 0) {
|
|
4497
4947
|
const param = node.parameters[0];
|
|
4498
4948
|
const paramName = param.name.getText();
|
|
4499
4949
|
const paramType = checker.getTypeAtLocation(param);
|
|
@@ -4503,7 +4953,7 @@ function serializeAccessor(node, ctx) {
|
|
|
4503
4953
|
parameters: [
|
|
4504
4954
|
{
|
|
4505
4955
|
name: paramName,
|
|
4506
|
-
schema: buildSchema(paramType, checker, ctx),
|
|
4956
|
+
schema: buildSchema(paramType, checker, ctx, param.type),
|
|
4507
4957
|
required: true
|
|
4508
4958
|
}
|
|
4509
4959
|
]
|
|
@@ -4526,7 +4976,7 @@ function getExtendsClause(node, checker) {
|
|
|
4526
4976
|
if (!node.heritageClauses)
|
|
4527
4977
|
return;
|
|
4528
4978
|
for (const clause of node.heritageClauses) {
|
|
4529
|
-
if (clause.token ===
|
|
4979
|
+
if (clause.token === ts9.SyntaxKind.ExtendsKeyword) {
|
|
4530
4980
|
const expr = clause.types[0];
|
|
4531
4981
|
if (expr) {
|
|
4532
4982
|
const type = checker.getTypeAtLocation(expr);
|
|
@@ -4541,7 +4991,7 @@ function getImplementsClause(node, checker) {
|
|
|
4541
4991
|
if (!node.heritageClauses)
|
|
4542
4992
|
return;
|
|
4543
4993
|
for (const clause of node.heritageClauses) {
|
|
4544
|
-
if (clause.token ===
|
|
4994
|
+
if (clause.token === ts9.SyntaxKind.ImplementsKeyword) {
|
|
4545
4995
|
return clause.types.map((expr) => {
|
|
4546
4996
|
const type = checker.getTypeAtLocation(expr);
|
|
4547
4997
|
const symbol = type.getSymbol();
|
|
@@ -4604,16 +5054,16 @@ function serializeEnum(node, ctx) {
|
|
|
4604
5054
|
}
|
|
4605
5055
|
|
|
4606
5056
|
// src/serializers/functions.ts
|
|
4607
|
-
import
|
|
5057
|
+
import ts10 from "typescript";
|
|
4608
5058
|
function buildReturnSchema(sig, ctx) {
|
|
4609
5059
|
const returnType = ctx.typeChecker.getReturnTypeOfSignature(sig);
|
|
4610
5060
|
registerReferencedTypes(returnType, ctx);
|
|
4611
|
-
const schema = buildSchema(returnType, ctx.typeChecker, ctx);
|
|
5061
|
+
const schema = buildSchema(returnType, ctx.typeChecker, ctx, typeNodeOfSignature(sig));
|
|
4612
5062
|
const declaration = sig.getDeclaration();
|
|
4613
|
-
if (declaration &&
|
|
5063
|
+
if (declaration && ts10.isFunctionLike(declaration) && declaration.type) {
|
|
4614
5064
|
const returnTypeNode = declaration.type;
|
|
4615
|
-
if (
|
|
4616
|
-
const parameterName =
|
|
5065
|
+
if (ts10.isTypePredicateNode(returnTypeNode)) {
|
|
5066
|
+
const parameterName = ts10.isIdentifier(returnTypeNode.parameterName) ? returnTypeNode.parameterName.text : returnTypeNode.parameterName.getText();
|
|
4617
5067
|
let predicateTypeSchema = { type: "unknown" };
|
|
4618
5068
|
if (returnTypeNode.type) {
|
|
4619
5069
|
const predicateType = ctx.typeChecker.getTypeAtLocation(returnTypeNode.type);
|
|
@@ -4633,21 +5083,82 @@ function buildReturnSchema(sig, ctx) {
|
|
|
4633
5083
|
}
|
|
4634
5084
|
return { schema };
|
|
4635
5085
|
}
|
|
4636
|
-
function
|
|
4637
|
-
|
|
4638
|
-
|
|
4639
|
-
|
|
4640
|
-
|
|
4641
|
-
const
|
|
4642
|
-
|
|
5086
|
+
function functionSignatureDecls(node, ctx) {
|
|
5087
|
+
if (!ts10.isFunctionDeclaration(node) || !node.name)
|
|
5088
|
+
return [node];
|
|
5089
|
+
const symbol = ctx.typeChecker.getSymbolAtLocation(node.name);
|
|
5090
|
+
const fns = (symbol?.declarations ?? []).filter(ts10.isFunctionDeclaration);
|
|
5091
|
+
const overloads = fns.filter((d) => !d.body);
|
|
5092
|
+
return overloads.length > 0 ? overloads : [node];
|
|
5093
|
+
}
|
|
5094
|
+
function signatureDeclDefers(decl, ctx) {
|
|
5095
|
+
const checker = ctx.typeChecker;
|
|
5096
|
+
if (decl.typeParameters) {
|
|
5097
|
+
for (const tp of decl.typeParameters) {
|
|
5098
|
+
if (typeNodeDefersExpansion(tp.constraint, checker, ctx.program))
|
|
5099
|
+
return true;
|
|
5100
|
+
if (typeNodeDefersExpansion(tp.default, checker, ctx.program))
|
|
5101
|
+
return true;
|
|
5102
|
+
}
|
|
5103
|
+
}
|
|
5104
|
+
for (const p of decl.parameters) {
|
|
5105
|
+
if (typeNodeDefersExpansion(p.type, checker, ctx.program))
|
|
5106
|
+
return true;
|
|
5107
|
+
}
|
|
5108
|
+
return typeNodeDefersExpansion(decl.type, checker, ctx.program);
|
|
5109
|
+
}
|
|
5110
|
+
function anySignatureDefers(node, ctx) {
|
|
5111
|
+
return functionSignatureDecls(node, ctx).some((d) => signatureDeclDefers(d, ctx));
|
|
5112
|
+
}
|
|
5113
|
+
function schemaFromTypeNode(node, ctx) {
|
|
5114
|
+
if (!node)
|
|
5115
|
+
return { type: "unknown" };
|
|
5116
|
+
if (typeNodeDefersExpansion(node, ctx.typeChecker, ctx.program)) {
|
|
5117
|
+
return buildSchemaFromTypeNode(node, ctx.typeChecker, ctx);
|
|
5118
|
+
}
|
|
5119
|
+
return buildSchema(ctx.typeChecker.getTypeFromTypeNode(node), ctx.typeChecker, ctx, node);
|
|
5120
|
+
}
|
|
5121
|
+
function parametersFromAst(decl, ctx) {
|
|
5122
|
+
const jsdocTags = ts10.getJSDocTags(decl);
|
|
5123
|
+
return decl.parameters.map((p) => {
|
|
5124
|
+
const name = ts10.isIdentifier(p.name) ? p.name.text : p.name.getText();
|
|
5125
|
+
const isOptional = !!p.questionToken || !!p.initializer;
|
|
5126
|
+
const param = {
|
|
5127
|
+
name,
|
|
5128
|
+
schema: schemaFromTypeNode(p.type, ctx),
|
|
5129
|
+
required: !isOptional
|
|
5130
|
+
};
|
|
5131
|
+
const description = getParamDescription(name, jsdocTags);
|
|
5132
|
+
if (description)
|
|
5133
|
+
param.description = description;
|
|
5134
|
+
return param;
|
|
5135
|
+
});
|
|
5136
|
+
}
|
|
5137
|
+
function signaturesFromAst(node, ctx) {
|
|
5138
|
+
const decls = functionSignatureDecls(node, ctx);
|
|
5139
|
+
return decls.map((decl, index) => {
|
|
5140
|
+
const sigDoc = getJSDocComment(decl);
|
|
5141
|
+
const sigTypeParams = ts10.isFunctionDeclaration(decl) || ts10.isArrowFunction(decl) || ts10.isFunctionExpression(decl) ? extractTypeParameters(decl, ctx.typeChecker) : undefined;
|
|
5142
|
+
const returns = { schema: schemaFromTypeNode(decl.type, ctx) };
|
|
5143
|
+
return {
|
|
5144
|
+
parameters: parametersFromAst(decl, ctx),
|
|
5145
|
+
returns,
|
|
5146
|
+
...sigDoc.description ? { description: sigDoc.description } : {},
|
|
5147
|
+
...sigDoc.tags.length > 0 ? { tags: sigDoc.tags } : {},
|
|
5148
|
+
...sigDoc.examples.length > 0 ? { examples: sigDoc.examples } : {},
|
|
5149
|
+
...sigTypeParams ? { typeParameters: sigTypeParams } : {},
|
|
5150
|
+
...decls.length > 1 ? { overloadIndex: index } : {}
|
|
5151
|
+
};
|
|
5152
|
+
});
|
|
5153
|
+
}
|
|
5154
|
+
function signaturesFromChecker(node, ctx) {
|
|
4643
5155
|
const type = ctx.typeChecker.getTypeAtLocation(node);
|
|
4644
5156
|
const callSignatures = type.getCallSignatures();
|
|
4645
|
-
|
|
4646
|
-
const params = extractParameters(sig, ctx);
|
|
5157
|
+
return callSignatures.map((sig, index) => {
|
|
4647
5158
|
const sigDoc = getJSDocForSignature(sig, ctx.typeChecker);
|
|
4648
5159
|
const sigTypeParams = extractTypeParametersFromSignature(sig, ctx.typeChecker);
|
|
4649
5160
|
return {
|
|
4650
|
-
parameters:
|
|
5161
|
+
parameters: extractParameters(sig, ctx),
|
|
4651
5162
|
returns: buildReturnSchema(sig, ctx),
|
|
4652
5163
|
...sigDoc.description ? { description: sigDoc.description } : {},
|
|
4653
5164
|
...sigDoc.tags.length > 0 ? { tags: sigDoc.tags } : {},
|
|
@@ -4656,9 +5167,18 @@ function serializeFunctionExport(node, ctx, nameOverride) {
|
|
|
4656
5167
|
...callSignatures.length > 1 ? { overloadIndex: index } : {}
|
|
4657
5168
|
};
|
|
4658
5169
|
});
|
|
5170
|
+
}
|
|
5171
|
+
function serializeFunctionExport(node, ctx, nameOverride) {
|
|
5172
|
+
const symbol = ctx.typeChecker.getSymbolAtLocation(node.name ?? node);
|
|
5173
|
+
const name = nameOverride ?? symbol?.getName() ?? node.name?.getText();
|
|
5174
|
+
if (!name)
|
|
5175
|
+
return null;
|
|
5176
|
+
const { description, tags, examples, source, deprecated, deprecationReason, inlineTags } = extractExportMetadata(node, symbol, ctx.typeChecker);
|
|
5177
|
+
const typeParameters = extractTypeParameters(node, ctx.typeChecker);
|
|
5178
|
+
const signatures = anySignatureDefers(node, ctx) ? signaturesFromAst(node, ctx) : signaturesFromChecker(node, ctx);
|
|
4659
5179
|
const flags = {};
|
|
4660
|
-
const modifiers =
|
|
4661
|
-
if (modifiers?.some((m) => m.kind ===
|
|
5180
|
+
const modifiers = ts10.getModifiers(node);
|
|
5181
|
+
if (modifiers?.some((m) => m.kind === ts10.SyntaxKind.AsyncKeyword)) {
|
|
4662
5182
|
flags.async = true;
|
|
4663
5183
|
}
|
|
4664
5184
|
if (node.asteriskToken) {
|
|
@@ -4681,7 +5201,7 @@ function serializeFunctionExport(node, ctx, nameOverride) {
|
|
|
4681
5201
|
}
|
|
4682
5202
|
|
|
4683
5203
|
// src/serializers/interfaces.ts
|
|
4684
|
-
import
|
|
5204
|
+
import ts11 from "typescript";
|
|
4685
5205
|
function serializeInterface(node, ctx) {
|
|
4686
5206
|
const { typeChecker: checker } = ctx;
|
|
4687
5207
|
const symbol = checker.getSymbolAtLocation(node.name ?? node);
|
|
@@ -4694,11 +5214,11 @@ function serializeInterface(node, ctx) {
|
|
|
4694
5214
|
const methodsByName = new Map;
|
|
4695
5215
|
let callSignatureMember = null;
|
|
4696
5216
|
for (const member of node.members) {
|
|
4697
|
-
if (
|
|
5217
|
+
if (ts11.isPropertySignature(member)) {
|
|
4698
5218
|
const propMember = serializePropertySignature(member, ctx);
|
|
4699
5219
|
if (propMember)
|
|
4700
5220
|
members.push(propMember);
|
|
4701
|
-
} else if (
|
|
5221
|
+
} else if (ts11.isMethodSignature(member)) {
|
|
4702
5222
|
const methodMember = serializeMethodSignature(member, ctx);
|
|
4703
5223
|
if (methodMember?.name && methodMember.signatures) {
|
|
4704
5224
|
const existing = methodsByName.get(methodMember.name);
|
|
@@ -4719,7 +5239,7 @@ function serializeInterface(node, ctx) {
|
|
|
4719
5239
|
methodsByName.set(methodMember.name, methodMember);
|
|
4720
5240
|
}
|
|
4721
5241
|
}
|
|
4722
|
-
} else if (
|
|
5242
|
+
} else if (ts11.isCallSignatureDeclaration(member)) {
|
|
4723
5243
|
const callSig = serializeCallSignature(member, ctx);
|
|
4724
5244
|
if (callSig?.signatures) {
|
|
4725
5245
|
if (callSignatureMember?.signatures) {
|
|
@@ -4742,7 +5262,7 @@ function serializeInterface(node, ctx) {
|
|
|
4742
5262
|
callSignatureMember = callSig;
|
|
4743
5263
|
}
|
|
4744
5264
|
}
|
|
4745
|
-
} else if (
|
|
5265
|
+
} else if (ts11.isIndexSignatureDeclaration(member)) {
|
|
4746
5266
|
const indexMember = serializeIndexSignature(member, ctx);
|
|
4747
5267
|
if (indexMember)
|
|
4748
5268
|
members.push(indexMember);
|
|
@@ -4776,12 +5296,12 @@ function serializePropertySignature(node, ctx) {
|
|
|
4776
5296
|
const { description, tags, inlineTags } = getJSDocComment(node);
|
|
4777
5297
|
const rawType = checker.getTypeAtLocation(node);
|
|
4778
5298
|
const type = node.questionToken ? stripUndefinedFromType(rawType, checker) : rawType;
|
|
4779
|
-
let schema = buildSchema(type, checker, ctx);
|
|
5299
|
+
let schema = buildSchema(type, checker, ctx, node.type);
|
|
4780
5300
|
registerReferencedTypes(type, ctx);
|
|
4781
5301
|
const flags = {};
|
|
4782
5302
|
if (node.questionToken)
|
|
4783
5303
|
flags.optional = true;
|
|
4784
|
-
if (node.modifiers?.some((m) => m.kind ===
|
|
5304
|
+
if (node.modifiers?.some((m) => m.kind === ts11.SyntaxKind.ReadonlyKeyword)) {
|
|
4785
5305
|
flags.readonly = true;
|
|
4786
5306
|
}
|
|
4787
5307
|
const symbol = checker.getSymbolAtLocation(node.name);
|
|
@@ -4845,7 +5365,7 @@ function serializeCallSignature(node, ctx) {
|
|
|
4845
5365
|
{
|
|
4846
5366
|
parameters: params.length > 0 ? params : undefined,
|
|
4847
5367
|
returns: {
|
|
4848
|
-
schema: buildSchema(returnType, checker, ctx)
|
|
5368
|
+
schema: buildSchema(returnType, checker, ctx, node.type)
|
|
4849
5369
|
}
|
|
4850
5370
|
}
|
|
4851
5371
|
]
|
|
@@ -4855,7 +5375,7 @@ function serializeIndexSignature(node, ctx) {
|
|
|
4855
5375
|
const { typeChecker: checker } = ctx;
|
|
4856
5376
|
const { description, tags, inlineTags } = getJSDocComment(node);
|
|
4857
5377
|
const valueType = node.type ? checker.getTypeAtLocation(node.type) : checker.getAnyType();
|
|
4858
|
-
const valueSchema = buildSchema(valueType, checker, ctx);
|
|
5378
|
+
const valueSchema = buildSchema(valueType, checker, ctx, node.type);
|
|
4859
5379
|
registerReferencedTypes(valueType, ctx);
|
|
4860
5380
|
const keyParam = node.parameters[0];
|
|
4861
5381
|
const keyType = keyParam?.type ? checker.getTypeAtLocation(keyParam.type) : checker.getStringType();
|
|
@@ -4873,7 +5393,7 @@ function getInterfaceExtends(node, checker) {
|
|
|
4873
5393
|
if (!node.heritageClauses)
|
|
4874
5394
|
return;
|
|
4875
5395
|
for (const clause of node.heritageClauses) {
|
|
4876
|
-
if (clause.token ===
|
|
5396
|
+
if (clause.token === ts11.SyntaxKind.ExtendsKeyword && clause.types.length > 0) {
|
|
4877
5397
|
const names = clause.types.map((expr) => {
|
|
4878
5398
|
const type = checker.getTypeAtLocation(expr);
|
|
4879
5399
|
return type.getSymbol()?.getName() ?? expr.expression.getText();
|
|
@@ -4885,7 +5405,7 @@ function getInterfaceExtends(node, checker) {
|
|
|
4885
5405
|
}
|
|
4886
5406
|
|
|
4887
5407
|
// src/serializers/type-aliases.ts
|
|
4888
|
-
import
|
|
5408
|
+
import ts12 from "typescript";
|
|
4889
5409
|
function buildIntersectionSchemaFromNode(node, ctx) {
|
|
4890
5410
|
const types = node.types;
|
|
4891
5411
|
const schemas = [];
|
|
@@ -4913,7 +5433,7 @@ function serializeTypeAlias(node, ctx) {
|
|
|
4913
5433
|
registerReferencedTypes(type, ctx);
|
|
4914
5434
|
let schema;
|
|
4915
5435
|
let members;
|
|
4916
|
-
if (
|
|
5436
|
+
if (ts12.isIntersectionTypeNode(node.type)) {
|
|
4917
5437
|
schema = buildIntersectionSchemaFromNode(node.type, ctx);
|
|
4918
5438
|
if (type.getProperties().length > 0 && type.getCallSignatures().length === 0) {
|
|
4919
5439
|
members = serializeResolvedMembers(type, node, ctx);
|
|
@@ -4923,7 +5443,7 @@ function serializeTypeAlias(node, ctx) {
|
|
|
4923
5443
|
if (type.getProperties().length > 0) {
|
|
4924
5444
|
members = serializeResolvedMembers(type, node, ctx);
|
|
4925
5445
|
}
|
|
4926
|
-
} else if ((
|
|
5446
|
+
} else if ((ts12.isMappedTypeNode(node.type) || ts12.isConditionalTypeNode(node.type)) && type.getProperties().length > 0 && type.getCallSignatures().length === 0 && !(type.flags & ts12.TypeFlags.Conditional) && !(type.flags & (ts12.TypeFlags.StringLike | ts12.TypeFlags.NumberLike))) {
|
|
4927
5447
|
schema = buildObjectSchema(type.getProperties(), ctx.typeChecker, ctx, type);
|
|
4928
5448
|
members = serializeResolvedMembers(type, node, ctx);
|
|
4929
5449
|
} else {
|
|
@@ -4933,7 +5453,7 @@ function serializeTypeAlias(node, ctx) {
|
|
|
4933
5453
|
}
|
|
4934
5454
|
}
|
|
4935
5455
|
if (shouldEmitAliasTypeText(node.type) && typeof schema === "object" && schema !== null && !("x-ts-type" in schema)) {
|
|
4936
|
-
const text = renderTypeText(type, ctx.typeChecker, node,
|
|
5456
|
+
const text = renderTypeText(type, ctx.typeChecker, node, ts12.TypeFormatFlags.InTypeAlias);
|
|
4937
5457
|
if (!PRIMITIVES.has(text) && text !== name) {
|
|
4938
5458
|
schema["x-ts-type"] = text;
|
|
4939
5459
|
const declared = writtenTypeText(declaredTypeNode(node));
|
|
@@ -4959,12 +5479,12 @@ function serializeTypeAlias(node, ctx) {
|
|
|
4959
5479
|
}
|
|
4960
5480
|
function isObjectShapedAlias(type, ctx) {
|
|
4961
5481
|
const { typeChecker: checker } = ctx;
|
|
4962
|
-
if (!(type.flags &
|
|
5482
|
+
if (!(type.flags & ts12.TypeFlags.Object))
|
|
4963
5483
|
return false;
|
|
4964
5484
|
if (checker.isArrayType(type) || checker.isTupleType(type))
|
|
4965
5485
|
return false;
|
|
4966
5486
|
const objectFlags = type.objectFlags;
|
|
4967
|
-
if (!(objectFlags &
|
|
5487
|
+
if (!(objectFlags & ts12.ObjectFlags.Mapped)) {
|
|
4968
5488
|
const targetSymbol = type.target?.getSymbol?.() ?? type.getSymbol();
|
|
4969
5489
|
if (isBuiltinSymbol(targetSymbol))
|
|
4970
5490
|
return false;
|
|
@@ -4972,19 +5492,19 @@ function isObjectShapedAlias(type, ctx) {
|
|
|
4972
5492
|
return type.getProperties().length > 0 && type.getCallSignatures().length === 0;
|
|
4973
5493
|
}
|
|
4974
5494
|
function isInlineFunctionAlias(typeNode) {
|
|
4975
|
-
return
|
|
5495
|
+
return ts12.isFunctionTypeNode(typeNode) || ts12.isTypeLiteralNode(typeNode) && typeNode.members.some(ts12.isCallSignatureDeclaration);
|
|
4976
5496
|
}
|
|
4977
5497
|
function buildConditionalArmDocs(typeNode, checker) {
|
|
4978
5498
|
const docs = new Map;
|
|
4979
|
-
if (!
|
|
5499
|
+
if (!ts12.isMappedTypeNode(typeNode) || !typeNode.type)
|
|
4980
5500
|
return docs;
|
|
4981
5501
|
const literalKeys = (extendsType) => {
|
|
4982
5502
|
const keys = [];
|
|
4983
5503
|
const visit = (n) => {
|
|
4984
|
-
if (
|
|
5504
|
+
if (ts12.isUnionTypeNode(n)) {
|
|
4985
5505
|
for (const member of n.types)
|
|
4986
5506
|
visit(member);
|
|
4987
|
-
} else if (
|
|
5507
|
+
} else if (ts12.isLiteralTypeNode(n) && ts12.isStringLiteral(n.literal)) {
|
|
4988
5508
|
keys.push(n.literal.text);
|
|
4989
5509
|
}
|
|
4990
5510
|
};
|
|
@@ -4992,12 +5512,12 @@ function buildConditionalArmDocs(typeNode, checker) {
|
|
|
4992
5512
|
return keys;
|
|
4993
5513
|
};
|
|
4994
5514
|
const armDoc = (armType) => {
|
|
4995
|
-
if (!
|
|
5515
|
+
if (!ts12.isTypeReferenceNode(armType))
|
|
4996
5516
|
return;
|
|
4997
5517
|
const symbol = checker.getSymbolAtLocation(armType.typeName);
|
|
4998
5518
|
if (!symbol)
|
|
4999
5519
|
return;
|
|
5000
|
-
const target = symbol.flags &
|
|
5520
|
+
const target = symbol.flags & ts12.SymbolFlags.Alias ? checker.getAliasedSymbol(symbol) : symbol;
|
|
5001
5521
|
const { deprecated, reason } = isSymbolDeprecated(target);
|
|
5002
5522
|
const targetDecl = target.getDeclarations()?.[0];
|
|
5003
5523
|
const description = targetDecl ? getJSDocComment(targetDecl, target, checker).description : undefined;
|
|
@@ -5006,7 +5526,7 @@ function buildConditionalArmDocs(typeNode, checker) {
|
|
|
5006
5526
|
return { deprecated, deprecationReason: reason, description };
|
|
5007
5527
|
};
|
|
5008
5528
|
let current = typeNode.type;
|
|
5009
|
-
while (current &&
|
|
5529
|
+
while (current && ts12.isConditionalTypeNode(current)) {
|
|
5010
5530
|
const doc = armDoc(current.trueType);
|
|
5011
5531
|
if (doc) {
|
|
5012
5532
|
for (const key of literalKeys(current.extendsType)) {
|
|
@@ -5025,10 +5545,10 @@ function serializeResolvedMembers(type, node, ctx) {
|
|
|
5025
5545
|
for (const prop of type.getProperties()) {
|
|
5026
5546
|
const decl = prop.getDeclarations()?.[0] ?? node;
|
|
5027
5547
|
const rawPropType = checker.getTypeOfSymbolAtLocation(prop, decl);
|
|
5028
|
-
const propType = prop.flags &
|
|
5548
|
+
const propType = prop.flags & ts12.SymbolFlags.Optional ? stripUndefinedFromType(rawPropType, checker) : rawPropType;
|
|
5029
5549
|
registerReferencedTypes(propType, ctx);
|
|
5030
5550
|
const callSigs = propType.getCallSignatures();
|
|
5031
|
-
const isMethodDecl =
|
|
5551
|
+
const isMethodDecl = ts12.isMethodSignature(decl) || ts12.isMethodDeclaration(decl) || ts12.isFunctionDeclaration(decl);
|
|
5032
5552
|
const kind = callSigs.length > 0 && isMethodDecl ? "method" : "property";
|
|
5033
5553
|
let { description, tags } = getJSDocComment(decl, prop, checker);
|
|
5034
5554
|
let { deprecated, reason: deprecationReason } = isSymbolDeprecated(prop);
|
|
@@ -5046,13 +5566,13 @@ function serializeResolvedMembers(type, node, ctx) {
|
|
|
5046
5566
|
({ deprecated, reason: deprecationReason } = isSymbolDeprecated(armAlias));
|
|
5047
5567
|
}
|
|
5048
5568
|
const flags = {};
|
|
5049
|
-
if (prop.flags &
|
|
5569
|
+
if (prop.flags & ts12.SymbolFlags.Optional)
|
|
5050
5570
|
flags.optional = true;
|
|
5051
5571
|
if (isReadonlyPropertySymbol(prop))
|
|
5052
5572
|
flags.readonly = true;
|
|
5053
|
-
if (prop.flags &
|
|
5573
|
+
if (prop.flags & ts12.SymbolFlags.Method)
|
|
5054
5574
|
flags.methodSyntax = true;
|
|
5055
|
-
const schema = kind === "property" ? decoratePropertySchema(buildSchema(propType, checker, ctx), prop, propType, checker) : decoratePropertySchema({ "x-ts-function": true }, prop, propType, checker);
|
|
5575
|
+
const schema = kind === "property" ? decoratePropertySchema(buildSchema(propType, checker, ctx, declaredTypeNode(prop.valueDeclaration ?? prop.getDeclarations()?.[0])), prop, propType, checker) : decoratePropertySchema({ "x-ts-function": true }, prop, propType, checker);
|
|
5056
5576
|
const inlineTags = parseInlineTags(description);
|
|
5057
5577
|
members.push({
|
|
5058
5578
|
name: prop.getName(),
|
|
@@ -5070,13 +5590,13 @@ function serializeResolvedMembers(type, node, ctx) {
|
|
|
5070
5590
|
}
|
|
5071
5591
|
|
|
5072
5592
|
// src/schema/registry.ts
|
|
5073
|
-
import
|
|
5593
|
+
import ts13 from "typescript";
|
|
5074
5594
|
function isTypeReference(type) {
|
|
5075
|
-
return !!(type.flags &
|
|
5595
|
+
return !!(type.flags & ts13.TypeFlags.Object && type.objectFlags && type.objectFlags & ts13.ObjectFlags.Reference);
|
|
5076
5596
|
}
|
|
5077
5597
|
function getNonNullableType(type) {
|
|
5078
5598
|
if (type.isUnion()) {
|
|
5079
|
-
const nonNullable = type.types.filter((t) => !(t.flags &
|
|
5599
|
+
const nonNullable = type.types.filter((t) => !(t.flags & ts13.TypeFlags.Undefined) && !(t.flags & ts13.TypeFlags.Null));
|
|
5080
5600
|
if (nonNullable.length === 1) {
|
|
5081
5601
|
return nonNullable[0];
|
|
5082
5602
|
}
|
|
@@ -5244,7 +5764,7 @@ function serializeVariable(node, statement, ctx) {
|
|
|
5244
5764
|
const schemaExtraction = extractSchemaType(type, ctx.typeChecker);
|
|
5245
5765
|
const typeToSerialize = schemaExtraction?.outputType ?? type;
|
|
5246
5766
|
registerReferencedTypes(typeToSerialize, ctx);
|
|
5247
|
-
const schema = buildSchema(typeToSerialize, ctx.typeChecker, ctx);
|
|
5767
|
+
const schema = buildSchema(typeToSerialize, ctx.typeChecker, ctx, node.type);
|
|
5248
5768
|
const flags = schemaExtraction ? {
|
|
5249
5769
|
schemaLibrary: schemaExtraction.adapter.id,
|
|
5250
5770
|
...schemaExtraction.inputType && schemaExtraction.inputType !== schemaExtraction.outputType ? { hasTransform: true } : {}
|
|
@@ -5269,7 +5789,7 @@ import { JSON_SCHEMA_DRAFT } from "@openpkg-ts/spec";
|
|
|
5269
5789
|
var TS_PRIMITIVE_NORMALIZATIONS = {
|
|
5270
5790
|
void: () => ({ type: "null", "x-ts-type": "void" }),
|
|
5271
5791
|
never: () => ({ not: {} }),
|
|
5272
|
-
any: () => ({}),
|
|
5792
|
+
any: () => ({ "x-ts-type": "any" }),
|
|
5273
5793
|
unknown: () => ({ "x-ts-type": "unknown" }),
|
|
5274
5794
|
undefined: () => ({ type: "null", "x-ts-type": "undefined" }),
|
|
5275
5795
|
bigint: () => ({ type: "integer", "x-ts-type": "bigint" }),
|
|
@@ -5832,7 +6352,7 @@ async function getExport(options) {
|
|
|
5832
6352
|
ctx.exportedIds = exportedIds;
|
|
5833
6353
|
try {
|
|
5834
6354
|
const originalDecls = targetSymbol.declarations ?? [];
|
|
5835
|
-
const isNamespaceExportDecl = originalDecls.some((d) =>
|
|
6355
|
+
const isNamespaceExportDecl = originalDecls.some((d) => ts14.isNamespaceExport(d) || ts14.isNamespaceImport(d));
|
|
5836
6356
|
if (isNamespaceExportDecl) {
|
|
5837
6357
|
const spec2 = serializeNamespaceForGet(targetSymbol, exportName, ctx);
|
|
5838
6358
|
const types2 = ctx.typeRegistry.getAll().map((t) => normalizeType(t));
|
|
@@ -5842,7 +6362,7 @@ async function getExport(options) {
|
|
|
5842
6362
|
errors
|
|
5843
6363
|
};
|
|
5844
6364
|
}
|
|
5845
|
-
const { declaration, resolvedSymbol, isTypeOnly } =
|
|
6365
|
+
const { declaration, resolvedSymbol: resolvedSymbol2, isTypeOnly } = resolveExportTarget2(targetSymbol, checker);
|
|
5846
6366
|
if (!declaration) {
|
|
5847
6367
|
const externalPackage = detectExternalPackage(targetSymbol, checker);
|
|
5848
6368
|
if (externalPackage) {
|
|
@@ -5856,7 +6376,7 @@ async function getExport(options) {
|
|
|
5856
6376
|
}
|
|
5857
6377
|
return { export: null, types: [], errors: [`No declaration found for '${exportName}'`] };
|
|
5858
6378
|
}
|
|
5859
|
-
let spec = serializeDeclaration(declaration, targetSymbol,
|
|
6379
|
+
let spec = serializeDeclaration(declaration, targetSymbol, resolvedSymbol2, exportName, ctx, isTypeOnly);
|
|
5860
6380
|
if (!spec) {
|
|
5861
6381
|
const externalPackage = detectExternalPackage(targetSymbol, checker);
|
|
5862
6382
|
if (externalPackage) {
|
|
@@ -5878,47 +6398,47 @@ async function getExport(options) {
|
|
|
5878
6398
|
return { export: null, types: [], errors };
|
|
5879
6399
|
}
|
|
5880
6400
|
}
|
|
5881
|
-
function
|
|
5882
|
-
let
|
|
6401
|
+
function resolveExportTarget2(symbol, checker) {
|
|
6402
|
+
let resolvedSymbol2 = symbol;
|
|
5883
6403
|
let isTypeOnly = false;
|
|
5884
6404
|
const declarations = symbol.declarations ?? [];
|
|
5885
6405
|
for (const decl of declarations) {
|
|
5886
|
-
if (
|
|
6406
|
+
if (ts14.isExportSpecifier(decl)) {
|
|
5887
6407
|
if (decl.isTypeOnly)
|
|
5888
6408
|
isTypeOnly = true;
|
|
5889
6409
|
const exportDecl = decl.parent?.parent;
|
|
5890
|
-
if (exportDecl &&
|
|
6410
|
+
if (exportDecl && ts14.isExportDeclaration(exportDecl) && exportDecl.isTypeOnly) {
|
|
5891
6411
|
isTypeOnly = true;
|
|
5892
6412
|
}
|
|
5893
6413
|
}
|
|
5894
6414
|
}
|
|
5895
|
-
if (symbol.flags &
|
|
6415
|
+
if (symbol.flags & ts14.SymbolFlags.Alias) {
|
|
5896
6416
|
const aliased = checker.getAliasedSymbol(symbol);
|
|
5897
6417
|
if (aliased && aliased !== symbol) {
|
|
5898
|
-
|
|
6418
|
+
resolvedSymbol2 = aliased;
|
|
5899
6419
|
}
|
|
5900
6420
|
}
|
|
5901
|
-
const targetDeclarations =
|
|
5902
|
-
const declaration =
|
|
5903
|
-
return { declaration, resolvedSymbol, isTypeOnly };
|
|
6421
|
+
const targetDeclarations = resolvedSymbol2.declarations ?? [];
|
|
6422
|
+
const declaration = resolvedSymbol2.valueDeclaration || targetDeclarations.find((d) => d.kind !== ts14.SyntaxKind.ExportSpecifier) || targetDeclarations[0];
|
|
6423
|
+
return { declaration, resolvedSymbol: resolvedSymbol2, isTypeOnly };
|
|
5904
6424
|
}
|
|
5905
6425
|
function serializeDeclaration(declaration, _exportSymbol, _targetSymbol, exportName, ctx, isTypeOnly) {
|
|
5906
6426
|
let result = null;
|
|
5907
|
-
if (
|
|
6427
|
+
if (ts14.isFunctionDeclaration(declaration)) {
|
|
5908
6428
|
result = serializeFunctionExport(declaration, ctx);
|
|
5909
|
-
} else if (
|
|
6429
|
+
} else if (ts14.isClassDeclaration(declaration)) {
|
|
5910
6430
|
result = serializeClass(declaration, ctx);
|
|
5911
|
-
} else if (
|
|
6431
|
+
} else if (ts14.isInterfaceDeclaration(declaration)) {
|
|
5912
6432
|
result = serializeInterface(declaration, ctx);
|
|
5913
|
-
} else if (
|
|
6433
|
+
} else if (ts14.isTypeAliasDeclaration(declaration)) {
|
|
5914
6434
|
result = serializeTypeAlias(declaration, ctx);
|
|
5915
|
-
} else if (
|
|
6435
|
+
} else if (ts14.isEnumDeclaration(declaration)) {
|
|
5916
6436
|
result = serializeEnum(declaration, ctx);
|
|
5917
|
-
} else if (
|
|
6437
|
+
} else if (ts14.isVariableDeclaration(declaration)) {
|
|
5918
6438
|
const varStatement = declaration.parent?.parent;
|
|
5919
|
-
if (varStatement &&
|
|
5920
|
-
if (declaration.initializer && (
|
|
5921
|
-
const varName =
|
|
6439
|
+
if (varStatement && ts14.isVariableStatement(varStatement)) {
|
|
6440
|
+
if (declaration.initializer && (ts14.isArrowFunction(declaration.initializer) || ts14.isFunctionExpression(declaration.initializer))) {
|
|
6441
|
+
const varName = ts14.isIdentifier(declaration.name) ? declaration.name.text : declaration.name.getText();
|
|
5922
6442
|
result = serializeFunctionExport(declaration.initializer, ctx, varName);
|
|
5923
6443
|
} else {
|
|
5924
6444
|
const checker = ctx.program.getTypeChecker();
|
|
@@ -5932,7 +6452,7 @@ function serializeDeclaration(declaration, _exportSymbol, _targetSymbol, exportN
|
|
|
5932
6452
|
}
|
|
5933
6453
|
}
|
|
5934
6454
|
}
|
|
5935
|
-
} else if (
|
|
6455
|
+
} else if (ts14.isNamespaceExport(declaration) || ts14.isModuleDeclaration(declaration) || ts14.isNamespaceImport(declaration) || ts14.isSourceFile(declaration)) {
|
|
5936
6456
|
result = serializeNamespaceForGet(_exportSymbol, exportName, ctx);
|
|
5937
6457
|
}
|
|
5938
6458
|
if (result) {
|
|
@@ -5948,7 +6468,7 @@ function serializeDeclaration(declaration, _exportSymbol, _targetSymbol, exportN
|
|
|
5948
6468
|
function serializeNamespaceForGet(symbol, exportName, ctx) {
|
|
5949
6469
|
const checker = ctx.program.getTypeChecker();
|
|
5950
6470
|
let targetSymbol = symbol;
|
|
5951
|
-
if (symbol.flags &
|
|
6471
|
+
if (symbol.flags & ts14.SymbolFlags.Alias) {
|
|
5952
6472
|
const aliased = checker.getAliasedSymbol(symbol);
|
|
5953
6473
|
if (aliased && aliased !== symbol) {
|
|
5954
6474
|
targetSymbol = aliased;
|
|
@@ -5978,7 +6498,7 @@ function serializeNamespaceForGet(symbol, exportName, ctx) {
|
|
|
5978
6498
|
}
|
|
5979
6499
|
function detectExternalPackage(symbol, checker) {
|
|
5980
6500
|
let targetSymbol = symbol;
|
|
5981
|
-
if (symbol.flags &
|
|
6501
|
+
if (symbol.flags & ts14.SymbolFlags.Alias) {
|
|
5982
6502
|
const aliased = checker.getAliasedSymbol(symbol);
|
|
5983
6503
|
if (aliased && aliased !== symbol) {
|
|
5984
6504
|
targetSymbol = aliased;
|
|
@@ -5990,9 +6510,9 @@ function detectExternalPackage(symbol, checker) {
|
|
|
5990
6510
|
const pkg = sf && packageNameFromPath(sf.fileName);
|
|
5991
6511
|
if (pkg)
|
|
5992
6512
|
return pkg;
|
|
5993
|
-
if (
|
|
6513
|
+
if (ts14.isExportSpecifier(decl)) {
|
|
5994
6514
|
const exportDecl = decl.parent?.parent;
|
|
5995
|
-
if (exportDecl &&
|
|
6515
|
+
if (exportDecl && ts14.isExportDeclaration(exportDecl) && exportDecl.moduleSpecifier) {
|
|
5996
6516
|
const moduleText = exportDecl.moduleSpecifier.text;
|
|
5997
6517
|
if (!moduleText.startsWith(".") && !moduleText.startsWith("/")) {
|
|
5998
6518
|
return moduleText;
|
|
@@ -6004,7 +6524,7 @@ function detectExternalPackage(symbol, checker) {
|
|
|
6004
6524
|
}
|
|
6005
6525
|
// src/primitives/list.ts
|
|
6006
6526
|
import * as path6 from "node:path";
|
|
6007
|
-
import
|
|
6527
|
+
import ts15 from "typescript";
|
|
6008
6528
|
async function listExports(options) {
|
|
6009
6529
|
const { entryFile, baseDir, content } = options;
|
|
6010
6530
|
const errors = [];
|
|
@@ -6047,16 +6567,16 @@ async function listExports(options) {
|
|
|
6047
6567
|
}
|
|
6048
6568
|
function extractExportItem(symbol, checker, entryFile, entrySourceFile) {
|
|
6049
6569
|
const name = symbol.getName();
|
|
6050
|
-
const isReexport = !!(symbol.flags &
|
|
6570
|
+
const isReexport = !!(symbol.flags & ts15.SymbolFlags.Alias);
|
|
6051
6571
|
let targetSymbol = symbol;
|
|
6052
|
-
if (symbol.flags &
|
|
6572
|
+
if (symbol.flags & ts15.SymbolFlags.Alias) {
|
|
6053
6573
|
const aliased = checker.getAliasedSymbol(symbol);
|
|
6054
6574
|
if (aliased && aliased !== symbol) {
|
|
6055
6575
|
targetSymbol = aliased;
|
|
6056
6576
|
}
|
|
6057
6577
|
}
|
|
6058
6578
|
const declarations = targetSymbol.declarations ?? [];
|
|
6059
|
-
const declaration = targetSymbol.valueDeclaration || declarations.find((d) => d.kind !==
|
|
6579
|
+
const declaration = targetSymbol.valueDeclaration || declarations.find((d) => d.kind !== ts15.SyntaxKind.ExportSpecifier) || declarations[0];
|
|
6060
6580
|
if (!declaration) {
|
|
6061
6581
|
return {
|
|
6062
6582
|
name,
|
|
@@ -6066,7 +6586,7 @@ function extractExportItem(symbol, checker, entryFile, entrySourceFile) {
|
|
|
6066
6586
|
reexport: true
|
|
6067
6587
|
};
|
|
6068
6588
|
}
|
|
6069
|
-
if (
|
|
6589
|
+
if (ts15.isSourceFile(declaration)) {
|
|
6070
6590
|
return {
|
|
6071
6591
|
name,
|
|
6072
6592
|
kind: "namespace",
|
|
@@ -6110,36 +6630,6 @@ import * as path10 from "node:path";
|
|
|
6110
6630
|
import { SCHEMA_URL, SCHEMA_VERSION } from "@openpkg-ts/spec";
|
|
6111
6631
|
import ts19 from "typescript";
|
|
6112
6632
|
|
|
6113
|
-
// src/ast/resolve.ts
|
|
6114
|
-
import ts15 from "typescript";
|
|
6115
|
-
function isTypeOnlyExport(symbol) {
|
|
6116
|
-
const declarations = symbol.declarations ?? [];
|
|
6117
|
-
for (const decl of declarations) {
|
|
6118
|
-
if (ts15.isExportSpecifier(decl)) {
|
|
6119
|
-
if (decl.isTypeOnly)
|
|
6120
|
-
return true;
|
|
6121
|
-
const exportDecl = decl.parent?.parent;
|
|
6122
|
-
if (exportDecl && ts15.isExportDeclaration(exportDecl) && exportDecl.isTypeOnly) {
|
|
6123
|
-
return true;
|
|
6124
|
-
}
|
|
6125
|
-
}
|
|
6126
|
-
}
|
|
6127
|
-
return false;
|
|
6128
|
-
}
|
|
6129
|
-
function resolveExportTarget2(symbol, checker) {
|
|
6130
|
-
let targetSymbol = symbol;
|
|
6131
|
-
const isTypeOnly = isTypeOnlyExport(symbol);
|
|
6132
|
-
if (symbol.flags & ts15.SymbolFlags.Alias) {
|
|
6133
|
-
const aliasTarget = checker.getAliasedSymbol(symbol);
|
|
6134
|
-
if (aliasTarget && aliasTarget !== symbol) {
|
|
6135
|
-
targetSymbol = aliasTarget;
|
|
6136
|
-
}
|
|
6137
|
-
}
|
|
6138
|
-
const declarations = targetSymbol.declarations ?? [];
|
|
6139
|
-
const declaration = targetSymbol.valueDeclaration || declarations.find((decl) => decl.kind !== ts15.SyntaxKind.ExportSpecifier) || declarations[0];
|
|
6140
|
-
return { declaration, targetSymbol, isTypeOnly };
|
|
6141
|
-
}
|
|
6142
|
-
|
|
6143
6633
|
// src/schema/standard-schema.ts
|
|
6144
6634
|
import { spawn as spawn2, spawnSync as spawnSync2 } from "node:child_process";
|
|
6145
6635
|
import * as fs5 from "node:fs";
|
|
@@ -6770,16 +7260,16 @@ function extractExternalExport(exportName, resolvedModule, program, ctx, visited
|
|
|
6770
7260
|
if (!targetExport) {
|
|
6771
7261
|
return null;
|
|
6772
7262
|
}
|
|
6773
|
-
let
|
|
7263
|
+
let resolvedSymbol2 = targetExport;
|
|
6774
7264
|
if (targetExport.flags & ts16.SymbolFlags.Alias) {
|
|
6775
7265
|
const aliased = checker.getAliasedSymbol(targetExport);
|
|
6776
7266
|
if (aliased && aliased !== targetExport) {
|
|
6777
|
-
|
|
7267
|
+
resolvedSymbol2 = aliased;
|
|
6778
7268
|
}
|
|
6779
7269
|
}
|
|
6780
|
-
const decl = (
|
|
7270
|
+
const decl = (resolvedSymbol2.declarations ?? [])[0];
|
|
6781
7271
|
const kind = decl ? getExportKind(decl, checker.getTypeAtLocation(decl)) : "variable";
|
|
6782
|
-
const docComment =
|
|
7272
|
+
const docComment = resolvedSymbol2.getDocumentationComment(checker);
|
|
6783
7273
|
const description = docComment.length > 0 ? docComment.map((c) => c.text).join(`
|
|
6784
7274
|
`) : undefined;
|
|
6785
7275
|
const specExport = {
|
|
@@ -6794,18 +7284,18 @@ function extractExternalExport(exportName, resolvedModule, program, ctx, visited
|
|
|
6794
7284
|
}
|
|
6795
7285
|
};
|
|
6796
7286
|
if (kind === "function") {
|
|
6797
|
-
const type = checker.getTypeOfSymbol(
|
|
7287
|
+
const type = checker.getTypeOfSymbol(resolvedSymbol2);
|
|
6798
7288
|
const callSignatures = type.getCallSignatures();
|
|
6799
7289
|
if (callSignatures.length > 0) {
|
|
6800
7290
|
specExport.signatures = buildSignatures(callSignatures, checker, ctx);
|
|
6801
7291
|
}
|
|
6802
7292
|
} else if (kind === "interface" || kind === "type" || kind === "class") {
|
|
6803
|
-
const type = checker.getTypeOfSymbol(
|
|
7293
|
+
const type = checker.getTypeOfSymbol(resolvedSymbol2);
|
|
6804
7294
|
registerReferencedTypes(type, ctx);
|
|
6805
7295
|
const schema = buildSchema(type, checker, ctx);
|
|
6806
7296
|
specExport.schema = schema;
|
|
6807
7297
|
} else if (kind === "variable") {
|
|
6808
|
-
const type = checker.getTypeOfSymbol(
|
|
7298
|
+
const type = checker.getTypeOfSymbol(resolvedSymbol2);
|
|
6809
7299
|
registerReferencedTypes(type, ctx);
|
|
6810
7300
|
const schema = buildSchema(type, checker, ctx);
|
|
6811
7301
|
specExport.schema = schema;
|
|
@@ -6996,10 +7486,11 @@ function createExternalExpansionPredicate(opts) {
|
|
|
6996
7486
|
return opts.workspacePackages.has(pkg);
|
|
6997
7487
|
};
|
|
6998
7488
|
return (symbol) => {
|
|
6999
|
-
const
|
|
7489
|
+
const resolved = resolveAliasSymbol(symbol, opts.checker, undefined, opts.program);
|
|
7490
|
+
const decl = (resolved.declarations ?? symbol.declarations)?.[0];
|
|
7000
7491
|
if (!decl)
|
|
7001
7492
|
return false;
|
|
7002
|
-
if (isLibSymbol(symbol))
|
|
7493
|
+
if (isLibSymbol(resolved) || isLibSymbol(symbol))
|
|
7003
7494
|
return false;
|
|
7004
7495
|
const pkg = packageNameFromPath(decl.getSourceFile().fileName);
|
|
7005
7496
|
if (pkg)
|
|
@@ -7015,7 +7506,12 @@ function expandReachableTypes(exportedSymbols, ctx, opts) {
|
|
|
7015
7506
|
const MAX_DEPTH = 30;
|
|
7016
7507
|
let visits = 0;
|
|
7017
7508
|
const MAX_VISITS = 50000;
|
|
7018
|
-
const symbolAllowed = createExternalExpansionPredicate(
|
|
7509
|
+
const symbolAllowed = createExternalExpansionPredicate({
|
|
7510
|
+
followExternal: opts.followExternal,
|
|
7511
|
+
workspacePackages: opts.workspacePackages,
|
|
7512
|
+
checker: ctx.typeChecker,
|
|
7513
|
+
program: ctx.program
|
|
7514
|
+
});
|
|
7019
7515
|
const visit = (type, depth) => {
|
|
7020
7516
|
if (!type || depth > MAX_DEPTH || visited.has(type))
|
|
7021
7517
|
return;
|
|
@@ -7048,7 +7544,7 @@ function expandReachableTypes(exportedSymbols, ctx, opts) {
|
|
|
7048
7544
|
visit(t, depth + 1);
|
|
7049
7545
|
}
|
|
7050
7546
|
}
|
|
7051
|
-
if (!allowed || !(type.flags & ts18.TypeFlags.Object || type.isClassOrInterface())) {
|
|
7547
|
+
if (!allowed || isDeferredMappedOrConditional(type) || !(type.flags & ts18.TypeFlags.Object || type.isClassOrInterface())) {
|
|
7052
7548
|
return;
|
|
7053
7549
|
}
|
|
7054
7550
|
if (isForeignPackage(symbol, opts.workspacePackages)) {
|
|
@@ -7086,14 +7582,8 @@ function expandReachableTypes(exportedSymbols, ctx, opts) {
|
|
|
7086
7582
|
return "type";
|
|
7087
7583
|
};
|
|
7088
7584
|
const resolveAlias = (symbol) => {
|
|
7089
|
-
|
|
7090
|
-
|
|
7091
|
-
return checker.getAliasedSymbol(symbol);
|
|
7092
|
-
} catch {
|
|
7093
|
-
return;
|
|
7094
|
-
}
|
|
7095
|
-
}
|
|
7096
|
-
return symbol;
|
|
7585
|
+
const resolved = resolveAliasSymbol(symbol, checker, undefined, ctx.program);
|
|
7586
|
+
return resolved;
|
|
7097
7587
|
};
|
|
7098
7588
|
const symbolByName = new Map;
|
|
7099
7589
|
const registerTypeSymbol = (symbol) => {
|
|
@@ -7494,7 +7984,9 @@ async function extract(options) {
|
|
|
7494
7984
|
onTruncation,
|
|
7495
7985
|
shouldExpandExternal: createExternalExpansionPredicate({
|
|
7496
7986
|
followExternal,
|
|
7497
|
-
workspacePackages: result.workspacePackages ?? new Map
|
|
7987
|
+
workspacePackages: result.workspacePackages ?? new Map,
|
|
7988
|
+
checker: typeChecker,
|
|
7989
|
+
program
|
|
7498
7990
|
}),
|
|
7499
7991
|
workspacePackages: result.workspacePackages ?? new Map
|
|
7500
7992
|
});
|
|
@@ -7512,7 +8004,7 @@ async function extract(options) {
|
|
|
7512
8004
|
await new Promise((r) => setImmediate(r));
|
|
7513
8005
|
}
|
|
7514
8006
|
try {
|
|
7515
|
-
const { declaration, targetSymbol, isTypeOnly } =
|
|
8007
|
+
const { declaration, targetSymbol, isTypeOnly } = resolveExportTarget(symbol, typeChecker, program);
|
|
7516
8008
|
if (!declaration) {
|
|
7517
8009
|
let externalPackage;
|
|
7518
8010
|
const allDecls = [...targetSymbol.declarations ?? [], ...symbol.declarations ?? []];
|
|
@@ -7593,6 +8085,13 @@ async function extract(options) {
|
|
|
7593
8085
|
workspacePackages: result.workspacePackages ?? new Map,
|
|
7594
8086
|
entryFile
|
|
7595
8087
|
});
|
|
8088
|
+
if (ctx.budgetExceeded) {
|
|
8089
|
+
diagnostics.push({
|
|
8090
|
+
message: "Stopped expanding some types after hitting the schema expansion budget",
|
|
8091
|
+
severity: "warning",
|
|
8092
|
+
code: "TYPE_EXPANSION_LIMIT"
|
|
8093
|
+
});
|
|
8094
|
+
}
|
|
7596
8095
|
{
|
|
7597
8096
|
const symFlags = ts19.SymbolFlags.Type | ts19.SymbolFlags.Interface | ts19.SymbolFlags.Class;
|
|
7598
8097
|
const maxPasses = 5;
|
|
@@ -7762,6 +8261,15 @@ function serializeDeclaration2(declaration, exportSymbol, exportName, ctx, isTyp
|
|
|
7762
8261
|
const type = ctx.typeChecker.getTypeAtLocation(declaration);
|
|
7763
8262
|
if (type.getConstructSignatures().length > 0) {
|
|
7764
8263
|
result = { ...result, kind: "class" };
|
|
8264
|
+
} else {
|
|
8265
|
+
const callSigs = callSignaturesForVariable(declaration, ctx);
|
|
8266
|
+
if (callSigs.length > 0) {
|
|
8267
|
+
result = {
|
|
8268
|
+
...result,
|
|
8269
|
+
kind: "function",
|
|
8270
|
+
signatures: buildSignatures(callSigs, ctx.typeChecker, ctx)
|
|
8271
|
+
};
|
|
8272
|
+
}
|
|
7765
8273
|
}
|
|
7766
8274
|
}
|
|
7767
8275
|
}
|
|
@@ -7946,6 +8454,35 @@ function extractExamples(doc) {
|
|
|
7946
8454
|
}
|
|
7947
8455
|
return examples;
|
|
7948
8456
|
}
|
|
8457
|
+
function callSignaturesForVariable(declaration, ctx) {
|
|
8458
|
+
const checker = ctx.typeChecker;
|
|
8459
|
+
if (declaration.type && ts19.isTypeReferenceNode(declaration.type)) {
|
|
8460
|
+
const nameNode = ts19.isQualifiedName(declaration.type.typeName) ? declaration.type.typeName.right : declaration.type.typeName;
|
|
8461
|
+
const raw = checker.getSymbolAtLocation(nameNode);
|
|
8462
|
+
if (raw) {
|
|
8463
|
+
const symbol = resolveAliasSymbol(raw, checker, undefined, ctx.program);
|
|
8464
|
+
const iface = symbol.declarations?.find((d) => ts19.isInterfaceDeclaration(d));
|
|
8465
|
+
try {
|
|
8466
|
+
const declared = checker.getDeclaredTypeOfSymbol(symbol);
|
|
8467
|
+
const sigs = declared.getCallSignatures();
|
|
8468
|
+
if (sigs.length > 0)
|
|
8469
|
+
return sigs;
|
|
8470
|
+
if (iface) {
|
|
8471
|
+
const fromDecl = checker.getTypeAtLocation(iface).getCallSignatures();
|
|
8472
|
+
if (fromDecl.length > 0)
|
|
8473
|
+
return fromDecl;
|
|
8474
|
+
}
|
|
8475
|
+
} catch {
|
|
8476
|
+
if (iface) {
|
|
8477
|
+
try {
|
|
8478
|
+
return checker.getTypeAtLocation(iface).getCallSignatures();
|
|
8479
|
+
} catch {}
|
|
8480
|
+
}
|
|
8481
|
+
}
|
|
8482
|
+
}
|
|
8483
|
+
}
|
|
8484
|
+
return checker.getTypeAtLocation(declaration).getCallSignatures();
|
|
8485
|
+
}
|
|
7949
8486
|
function withExportName(entry, exportName) {
|
|
7950
8487
|
if (entry.name === exportName) {
|
|
7951
8488
|
return entry;
|
|
@@ -8522,6 +9059,8 @@ export {
|
|
|
8522
9059
|
validateSpec2 as validateSpec,
|
|
8523
9060
|
valibotAdapter,
|
|
8524
9061
|
typeboxAdapter,
|
|
9062
|
+
typeNodeOfSignature,
|
|
9063
|
+
typeNodeDefersExpansion,
|
|
8525
9064
|
toToolSchema,
|
|
8526
9065
|
toSearchIndexJSON,
|
|
8527
9066
|
toSearchIndex,
|
|
@@ -8550,8 +9089,9 @@ export {
|
|
|
8550
9089
|
schemaIsAny,
|
|
8551
9090
|
resolveTypeRef,
|
|
8552
9091
|
resolveTarget,
|
|
8553
|
-
|
|
9092
|
+
resolveExportTarget,
|
|
8554
9093
|
resolveCompiledPath,
|
|
9094
|
+
resolveAliasSymbol,
|
|
8555
9095
|
renderTypeText,
|
|
8556
9096
|
registerReferencedTypes,
|
|
8557
9097
|
registerAdapter,
|
|
@@ -8581,6 +9121,7 @@ export {
|
|
|
8581
9121
|
isMethod,
|
|
8582
9122
|
isExported,
|
|
8583
9123
|
isEntryFilePath,
|
|
9124
|
+
isDeferredMappedOrConditional,
|
|
8584
9125
|
isBuiltinSymbol,
|
|
8585
9126
|
isBuiltinGeneric,
|
|
8586
9127
|
isAnonymous,
|
|
@@ -8635,6 +9176,7 @@ export {
|
|
|
8635
9176
|
calculateNextVersion,
|
|
8636
9177
|
bundleRefs,
|
|
8637
9178
|
buildSignatureString,
|
|
9179
|
+
buildSchemaFromTypeNode,
|
|
8638
9180
|
buildSchema,
|
|
8639
9181
|
buildObjectSchema,
|
|
8640
9182
|
buildFunctionSchema,
|