@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.js CHANGED
@@ -1781,7 +1781,7 @@ function filterSpec(spec, criteria) {
1781
1781
  };
1782
1782
  }
1783
1783
  // src/primitives/get.ts
1784
- import ts13 from "typescript";
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, checker) {
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
- let constraint;
2112
- if (tp.constraint) {
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, checker) {
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 ts8 from "typescript";
2546
+ import ts9 from "typescript";
2527
2547
 
2528
2548
  // src/types/parameters.ts
2529
- import ts5 from "typescript";
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 & ts4.TypeFlags.NumberLike)
2720
+ if (slot.flags & ts5.TypeFlags.NumberLike)
2570
2721
  return "-?\\d+(?:\\.\\d+)?";
2571
- if (slot.flags & ts4.TypeFlags.BigIntLike)
2722
+ if (slot.flags & ts5.TypeFlags.BigIntLike)
2572
2723
  return "-?\\d+";
2573
- if (slot.flags & ts4.TypeFlags.BooleanLike)
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, ts4.TypeFormatFlags.NoTruncation | extraFlags));
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 (!ts4.isTypeReferenceNode(typeNode) && !ts4.isUnionTypeNode(typeNode))
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 & ts4.TypeFlags.Undefined));
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) => (ts4.getCombinedModifierFlags(d) & ts4.ModifierFlags.Readonly) !== 0);
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 & ts4.SymbolFlags.Optional);
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 & ts4.SymbolFlags.Method && !("x-ts-method" in obj)) {
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 (ts4.isMappedTypeNode(typeNode))
2897
+ if (ts5.isMappedTypeNode(typeNode))
2660
2898
  return false;
2661
- if (ts4.isTypeLiteralNode(typeNode)) {
2662
- return typeNode.members.length > 0 && typeNode.members.every((m) => ts4.isIndexSignatureDeclaration(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 & ts4.TypeFlags.TypeParameter))
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) => ts4.isClassDeclaration(decl) || ts4.isClassExpression(decl) || ts4.isInterfaceDeclaration(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 & ts4.TypeFlags.TypeParameter && !isFluentThisType(type)) {
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 & ts4.TypeFlags.String)
3348
+ if (type.flags & ts5.TypeFlags.String)
2926
3349
  return { type: "string" };
2927
- if (type.flags & ts4.TypeFlags.Number)
3350
+ if (type.flags & ts5.TypeFlags.Number)
2928
3351
  return { type: "number" };
2929
- if (type.flags & ts4.TypeFlags.Boolean)
3352
+ if (type.flags & ts5.TypeFlags.Boolean)
2930
3353
  return { type: "boolean" };
2931
- if (type.flags & ts4.TypeFlags.Undefined)
3354
+ if (type.flags & ts5.TypeFlags.Undefined)
2932
3355
  return { type: "undefined" };
2933
- if (type.flags & ts4.TypeFlags.Null)
3356
+ if (type.flags & ts5.TypeFlags.Null)
2934
3357
  return { type: "null" };
2935
- if (type.flags & ts4.TypeFlags.Void)
3358
+ if (type.flags & ts5.TypeFlags.Void)
2936
3359
  return { type: "void" };
2937
- if (type.flags & ts4.TypeFlags.TemplateLiteral) {
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 & ts4.TypeFlags.Object);
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 & ts4.TypeFlags.String)
3413
+ if (type.flags & ts5.TypeFlags.String)
2979
3414
  return { type: "string" };
2980
- if (type.flags & ts4.TypeFlags.Number)
3415
+ if (type.flags & ts5.TypeFlags.Number)
2981
3416
  return { type: "number" };
2982
- if (type.flags & ts4.TypeFlags.Boolean)
3417
+ if (type.flags & ts5.TypeFlags.Boolean)
2983
3418
  return { type: "boolean" };
2984
- if (type.flags & ts4.TypeFlags.Undefined)
3419
+ if (type.flags & ts5.TypeFlags.Undefined)
2985
3420
  return { type: "undefined" };
2986
- if (type.flags & ts4.TypeFlags.Null)
3421
+ if (type.flags & ts5.TypeFlags.Null)
2987
3422
  return { type: "null" };
2988
- if (type.flags & ts4.TypeFlags.Void)
3423
+ if (type.flags & ts5.TypeFlags.Void)
2989
3424
  return { type: "void" };
2990
- if (type.flags & ts4.TypeFlags.Any)
2991
- return { type: "any" };
2992
- if (type.flags & ts4.TypeFlags.Unknown)
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 & ts4.TypeFlags.Never)
3432
+ if (type.flags & ts5.TypeFlags.Never)
2995
3433
  return { type: "never" };
2996
- if (type.flags & ts4.TypeFlags.BigInt)
3434
+ if (type.flags & ts5.TypeFlags.BigInt)
2997
3435
  return { type: "bigint" };
2998
- if (type.flags & ts4.TypeFlags.ESSymbol)
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 & ts4.TypeFlags.TypeParameter) {
3448
+ if (type.flags & ts5.TypeFlags.TypeParameter) {
3011
3449
  return { "x-ts-type": checker.typeToString(type) };
3012
3450
  }
3013
- if (type.flags & ts4.TypeFlags.StringLiteral) {
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 & ts4.TypeFlags.NumberLiteral) {
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 & ts4.TypeFlags.BooleanLiteral) {
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 & ts4.TypeFlags.TemplateLiteral) {
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 & ts4.TypeFlags.StringMapping) {
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 & ts4.TypeFlags.StringLiteral);
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 & ts4.TypeFlags.NumberLiteral);
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 & ts4.TypeFlags.BooleanLiteral);
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 & ts4.TypeFlags.BooleanLiteral);
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 & ts4.TypeFlags.Intersection);
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 & ts4.TypeFlags.Never));
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
- if (ctx) {
3113
- return withDepth(ctx, () => ({
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 & ts4.TypeFlags.Object) {
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 & ts4.TypeFlags.Object) {
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 & ts4.TypeFlags.Object) {
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 & ts4.ObjectFlags.Anonymous || checker.getIndexInfosOfType(type).length > 0) {
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 & ts4.TypeFlags.StringLike);
3306
- const isNumberLikeType = !!(originalType && originalType.flags & ts4.TypeFlags.NumberLike);
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 & ts4.SymbolFlags.Optional);
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
- let propSchema = buildSchema(propType, checker, ctx);
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 & ts4.SymbolFlags.Optional)) {
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 & ts4.TypeFlags.String);
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 & ts4.TypeFlags.Number);
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 & (ts4.TypeFlags.Null | ts4.TypeFlags.Undefined)) {
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 ? ts5.getJSDocTags(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 type = checker.getTypeOfSymbolAtLocation(param, decl);
3504
- if (decl && ts5.isObjectBindingPattern(decl.name)) {
3505
- const expandedParams = expandBindingPattern(decl, type, jsdocTags, ctx);
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: buildSchema(effectiveType, checker, ctx),
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 (!ts5.isBindingElement(element))
3979
+ if (!ts6.isBindingElement(element))
3540
3980
  continue;
3541
- const propertyName = element.propertyName ? ts5.isIdentifier(element.propertyName) ? element.propertyName.text : element.propertyName.getText() : ts5.isIdentifier(element.name) ? element.name.text : element.name.getText();
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 & ts5.SymbolFlags.Optional) || element.initializer !== undefined;
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 : ts5.getTextOfJSDocComment(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 (ts5.isStringLiteral(initializer)) {
4051
+ if (ts6.isStringLiteral(initializer)) {
3612
4052
  return { literal: true, value: initializer.text };
3613
4053
  }
3614
- if (ts5.isNumericLiteral(initializer)) {
4054
+ if (ts6.isNumericLiteral(initializer)) {
3615
4055
  return { literal: true, value: Number(initializer.text) };
3616
4056
  }
3617
- if (ts5.isPrefixUnaryExpression(initializer) && initializer.operator === ts5.SyntaxKind.MinusToken && ts5.isNumericLiteral(initializer.operand)) {
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 === ts5.SyntaxKind.TrueKeyword) {
4060
+ if (initializer.kind === ts6.SyntaxKind.TrueKeyword) {
3621
4061
  return { literal: true, value: true };
3622
4062
  }
3623
- if (initializer.kind === ts5.SyntaxKind.FalseKeyword) {
4063
+ if (initializer.kind === ts6.SyntaxKind.FalseKeyword) {
3624
4064
  return { literal: true, value: false };
3625
4065
  }
3626
- if (initializer.kind === ts5.SyntaxKind.NullKeyword) {
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 if (param.schema && typeof param.schema === "object" && !Array.isArray(param.schema)) {
3639
- param.schema["x-ts-default"] = extracted.text;
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 & (ts5.TypeFlags.String | ts5.TypeFlags.Number | ts5.TypeFlags.Boolean | ts5.TypeFlags.Void | ts5.TypeFlags.Undefined | ts5.TypeFlags.Null | ts5.TypeFlags.Any | ts5.TypeFlags.Unknown | ts5.TypeFlags.Never | ts5.TypeFlags.StringLiteral | ts5.TypeFlags.NumberLiteral | ts5.TypeFlags.BooleanLiteral);
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.flags & ts5.TypeFlags.Object) {
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 ts7 from "typescript";
4137
+ import ts8 from "typescript";
3692
4138
 
3693
4139
  // src/ast/registry.ts
3694
- import ts6 from "typescript";
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 symbol = type.aliasSymbol || type.getSymbol();
3792
- if (!symbol)
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 & ts6.SymbolFlags.EnumMember)
4250
+ if (symbol.flags & ts7.SymbolFlags.EnumMember)
3804
4251
  return;
3805
- if (symbol.flags & ts6.SymbolFlags.TypeParameter)
4252
+ if (symbol.flags & ts7.SymbolFlags.TypeParameter)
3806
4253
  return;
3807
- if (symbol.flags & ts6.SymbolFlags.Method)
4254
+ if (symbol.flags & ts7.SymbolFlags.Method)
3808
4255
  return;
3809
- if (symbol.flags & ts6.SymbolFlags.Function)
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 (ts6.isClassDeclaration(decl))
4306
+ if (ts7.isClassDeclaration(decl))
3860
4307
  kind = "class";
3861
- else if (ts6.isInterfaceDeclaration(decl))
4308
+ else if (ts7.isInterfaceDeclaration(decl))
3862
4309
  kind = "interface";
3863
- else if (ts6.isEnumDeclaration(decl))
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 && ts6.isTypeAliasDeclaration(decl) && shouldEmitAliasTypeText(decl.type) && typeof schema === "object" && schema !== null && !("x-ts-type" in schema)) {
3880
- const text = renderTypeText(type, checker, decl, ts6.TypeFormatFlags.InTypeAlias);
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 && (ts6.isTypeAliasDeclaration(decl) || ts6.isInterfaceDeclaration(decl) || ts6.isClassDeclaration(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 & ts6.TypeFlags.StringLiteral);
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 & ts6.TypeFlags.NumberLiteral);
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 & ts6.TypeFlags.Conditional) {
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 & ts6.TypeFlags.StringLike ? "string" : constraint && constraint.flags & ts6.TypeFlags.NumberLike ? "number" : constraint && constraint.flags & ts6.TypeFlags.BooleanLike ? "boolean" : undefined;
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(ts6.isEnumDeclaration);
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 & ts6.TypeFlags.String);
3992
- const numberIndex = indexInfos.find((i) => i.keyType.flags & ts6.TypeFlags.Number);
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 & ts6.TypeFlags.StringLike;
4001
- const isNumberLike = type.flags & ts6.TypeFlags.NumberLike;
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 & ts6.SymbolFlags.Optional ? stripUndefinedFromType(rawPropType, checker) : rawPropType;
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 & ts6.SymbolFlags.Optional)) {
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 && ts7.canHaveModifiers(decl)) {
4144
- const modifiers = ts7.getModifiers(decl);
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 === ts7.SyntaxKind.PrivateKeyword)
4597
+ if (mod.kind === ts8.SyntaxKind.PrivateKeyword)
4148
4598
  visibility = "private";
4149
- else if (mod.kind === ts7.SyntaxKind.ProtectedKeyword)
4599
+ else if (mod.kind === ts8.SyntaxKind.ProtectedKeyword)
4150
4600
  visibility = "protected";
4151
- else if (mod.kind === ts7.SyntaxKind.PublicKeyword)
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 (ts7.isGetAccessorDeclaration(decl)) {
4613
+ } else if (ts8.isGetAccessorDeclaration(decl)) {
4164
4614
  kind = "getter";
4165
- } else if (ts7.isSetAccessorDeclaration(decl)) {
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 && ts7.canHaveModifiers(decl)) {
4172
- const modifiers = ts7.getModifiers(decl);
4173
- if (modifiers?.some((m) => m.kind === ts7.SyntaxKind.ReadonlyKeyword)) {
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 (ts8.isPropertyDeclaration(member)) {
4703
+ if (ts9.isPropertyDeclaration(member)) {
4254
4704
  const propMember = serializeProperty(member, ctx);
4255
4705
  if (propMember)
4256
4706
  members.push(propMember);
4257
- } else if (ts8.isMethodDeclaration(member)) {
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 (ts8.isConstructorDeclaration(member)) {
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 (ts8.isGetAccessorDeclaration(member) || ts8.isSetAccessorDeclaration(member)) {
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 = ts8.getModifiers(node);
4303
- if (classModifiers?.some((m) => m.kind === ts8.SyntaxKind.AbstractKeyword)) {
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 (ts8.isConstructorDeclaration(member))
4775
+ if (ts9.isConstructorDeclaration(member))
4326
4776
  return "constructor";
4327
4777
  if (!member.name)
4328
4778
  return;
4329
- if (ts8.isIdentifier(member.name))
4779
+ if (ts9.isIdentifier(member.name))
4330
4780
  return member.name.text;
4331
- if (ts8.isPrivateIdentifier(member.name))
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 = ts8.canHaveModifiers(member) ? ts8.getModifiers(member) : undefined;
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 === ts8.SyntaxKind.PrivateKeyword)
4790
+ if (mod.kind === ts9.SyntaxKind.PrivateKeyword)
4341
4791
  return "private";
4342
- if (mod.kind === ts8.SyntaxKind.ProtectedKeyword)
4792
+ if (mod.kind === ts9.SyntaxKind.ProtectedKeyword)
4343
4793
  return "protected";
4344
- if (mod.kind === ts8.SyntaxKind.PublicKeyword)
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 = ts8.canHaveModifiers(member) ? ts8.getModifiers(member) : undefined;
4351
- return modifiers?.some((m) => m.kind === ts8.SyntaxKind.StaticKeyword) ?? false;
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 = ts8.canHaveModifiers(member) ? ts8.getModifiers(member) : undefined;
4355
- return modifiers?.some((m) => m.kind === ts8.SyntaxKind.ReadonlyKeyword) ?? false;
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 = ts8.getModifiers(node);
4415
- if (modifiers?.some((m) => m.kind === ts8.SyntaxKind.AsyncKeyword)) {
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 === ts8.SyntaxKind.AbstractKeyword)) {
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 === ts8.SyntaxKind.ExtendsKeyword);
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 && ts8.isConstructorDeclaration(decl);
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 = ts8.isClassLike(decl.parent) ? decl.parent.name?.text : undefined;
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 = ts8.isGetAccessorDeclaration(node) ? "getter" : "setter";
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 (ts8.isSetAccessorDeclaration(node) && node.parameters.length > 0) {
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 === ts8.SyntaxKind.ExtendsKeyword) {
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 === ts8.SyntaxKind.ImplementsKeyword) {
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 ts9 from "typescript";
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 && ts9.isFunctionLike(declaration) && declaration.type) {
5063
+ if (declaration && ts10.isFunctionLike(declaration) && declaration.type) {
4614
5064
  const returnTypeNode = declaration.type;
4615
- if (ts9.isTypePredicateNode(returnTypeNode)) {
4616
- const parameterName = ts9.isIdentifier(returnTypeNode.parameterName) ? returnTypeNode.parameterName.text : returnTypeNode.parameterName.getText();
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 serializeFunctionExport(node, ctx, nameOverride) {
4637
- const symbol = ctx.typeChecker.getSymbolAtLocation(node.name ?? node);
4638
- const name = nameOverride ?? symbol?.getName() ?? node.name?.getText();
4639
- if (!name)
4640
- return null;
4641
- const { description, tags, examples, source, deprecated, deprecationReason, inlineTags } = extractExportMetadata(node, symbol, ctx.typeChecker);
4642
- const typeParameters = extractTypeParameters(node, ctx.typeChecker);
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
- const signatures = callSignatures.map((sig, index) => {
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: params,
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 = ts9.getModifiers(node);
4661
- if (modifiers?.some((m) => m.kind === ts9.SyntaxKind.AsyncKeyword)) {
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 ts10 from "typescript";
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 (ts10.isPropertySignature(member)) {
5217
+ if (ts11.isPropertySignature(member)) {
4698
5218
  const propMember = serializePropertySignature(member, ctx);
4699
5219
  if (propMember)
4700
5220
  members.push(propMember);
4701
- } else if (ts10.isMethodSignature(member)) {
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 (ts10.isCallSignatureDeclaration(member)) {
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 (ts10.isIndexSignatureDeclaration(member)) {
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 === ts10.SyntaxKind.ReadonlyKeyword)) {
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 === ts10.SyntaxKind.ExtendsKeyword && clause.types.length > 0) {
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 ts11 from "typescript";
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 (ts11.isIntersectionTypeNode(node.type)) {
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 ((ts11.isMappedTypeNode(node.type) || ts11.isConditionalTypeNode(node.type)) && type.getProperties().length > 0 && type.getCallSignatures().length === 0 && !(type.flags & ts11.TypeFlags.Conditional) && !(type.flags & (ts11.TypeFlags.StringLike | ts11.TypeFlags.NumberLike))) {
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, ts11.TypeFormatFlags.InTypeAlias);
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 & ts11.TypeFlags.Object))
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 & ts11.ObjectFlags.Mapped)) {
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 ts11.isFunctionTypeNode(typeNode) || ts11.isTypeLiteralNode(typeNode) && typeNode.members.some(ts11.isCallSignatureDeclaration);
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 (!ts11.isMappedTypeNode(typeNode) || !typeNode.type)
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 (ts11.isUnionTypeNode(n)) {
5504
+ if (ts12.isUnionTypeNode(n)) {
4985
5505
  for (const member of n.types)
4986
5506
  visit(member);
4987
- } else if (ts11.isLiteralTypeNode(n) && ts11.isStringLiteral(n.literal)) {
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 (!ts11.isTypeReferenceNode(armType))
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 & ts11.SymbolFlags.Alias ? checker.getAliasedSymbol(symbol) : symbol;
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 && ts11.isConditionalTypeNode(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 & ts11.SymbolFlags.Optional ? stripUndefinedFromType(rawPropType, checker) : rawPropType;
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 = ts11.isMethodSignature(decl) || ts11.isMethodDeclaration(decl) || ts11.isFunctionDeclaration(decl);
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 & ts11.SymbolFlags.Optional)
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 & ts11.SymbolFlags.Method)
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 ts12 from "typescript";
5593
+ import ts13 from "typescript";
5074
5594
  function isTypeReference(type) {
5075
- return !!(type.flags & ts12.TypeFlags.Object && type.objectFlags && type.objectFlags & ts12.ObjectFlags.Reference);
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 & ts12.TypeFlags.Undefined) && !(t.flags & ts12.TypeFlags.Null));
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) => ts13.isNamespaceExport(d) || ts13.isNamespaceImport(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 } = resolveExportTarget(targetSymbol, checker);
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, resolvedSymbol, exportName, ctx, isTypeOnly);
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 resolveExportTarget(symbol, checker) {
5882
- let resolvedSymbol = symbol;
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 (ts13.isExportSpecifier(decl)) {
6406
+ if (ts14.isExportSpecifier(decl)) {
5887
6407
  if (decl.isTypeOnly)
5888
6408
  isTypeOnly = true;
5889
6409
  const exportDecl = decl.parent?.parent;
5890
- if (exportDecl && ts13.isExportDeclaration(exportDecl) && exportDecl.isTypeOnly) {
6410
+ if (exportDecl && ts14.isExportDeclaration(exportDecl) && exportDecl.isTypeOnly) {
5891
6411
  isTypeOnly = true;
5892
6412
  }
5893
6413
  }
5894
6414
  }
5895
- if (symbol.flags & ts13.SymbolFlags.Alias) {
6415
+ if (symbol.flags & ts14.SymbolFlags.Alias) {
5896
6416
  const aliased = checker.getAliasedSymbol(symbol);
5897
6417
  if (aliased && aliased !== symbol) {
5898
- resolvedSymbol = aliased;
6418
+ resolvedSymbol2 = aliased;
5899
6419
  }
5900
6420
  }
5901
- const targetDeclarations = resolvedSymbol.declarations ?? [];
5902
- const declaration = resolvedSymbol.valueDeclaration || targetDeclarations.find((d) => d.kind !== ts13.SyntaxKind.ExportSpecifier) || targetDeclarations[0];
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 (ts13.isFunctionDeclaration(declaration)) {
6427
+ if (ts14.isFunctionDeclaration(declaration)) {
5908
6428
  result = serializeFunctionExport(declaration, ctx);
5909
- } else if (ts13.isClassDeclaration(declaration)) {
6429
+ } else if (ts14.isClassDeclaration(declaration)) {
5910
6430
  result = serializeClass(declaration, ctx);
5911
- } else if (ts13.isInterfaceDeclaration(declaration)) {
6431
+ } else if (ts14.isInterfaceDeclaration(declaration)) {
5912
6432
  result = serializeInterface(declaration, ctx);
5913
- } else if (ts13.isTypeAliasDeclaration(declaration)) {
6433
+ } else if (ts14.isTypeAliasDeclaration(declaration)) {
5914
6434
  result = serializeTypeAlias(declaration, ctx);
5915
- } else if (ts13.isEnumDeclaration(declaration)) {
6435
+ } else if (ts14.isEnumDeclaration(declaration)) {
5916
6436
  result = serializeEnum(declaration, ctx);
5917
- } else if (ts13.isVariableDeclaration(declaration)) {
6437
+ } else if (ts14.isVariableDeclaration(declaration)) {
5918
6438
  const varStatement = declaration.parent?.parent;
5919
- if (varStatement && ts13.isVariableStatement(varStatement)) {
5920
- if (declaration.initializer && (ts13.isArrowFunction(declaration.initializer) || ts13.isFunctionExpression(declaration.initializer))) {
5921
- const varName = ts13.isIdentifier(declaration.name) ? declaration.name.text : declaration.name.getText();
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 (ts13.isNamespaceExport(declaration) || ts13.isModuleDeclaration(declaration) || ts13.isNamespaceImport(declaration) || ts13.isSourceFile(declaration)) {
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 & ts13.SymbolFlags.Alias) {
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 & ts13.SymbolFlags.Alias) {
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 (ts13.isExportSpecifier(decl)) {
6513
+ if (ts14.isExportSpecifier(decl)) {
5994
6514
  const exportDecl = decl.parent?.parent;
5995
- if (exportDecl && ts13.isExportDeclaration(exportDecl) && exportDecl.moduleSpecifier) {
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 ts14 from "typescript";
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 & ts14.SymbolFlags.Alias);
6570
+ const isReexport = !!(symbol.flags & ts15.SymbolFlags.Alias);
6051
6571
  let targetSymbol = symbol;
6052
- if (symbol.flags & ts14.SymbolFlags.Alias) {
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 !== ts14.SyntaxKind.ExportSpecifier) || declarations[0];
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 (ts14.isSourceFile(declaration)) {
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 resolvedSymbol = targetExport;
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
- resolvedSymbol = aliased;
7267
+ resolvedSymbol2 = aliased;
6778
7268
  }
6779
7269
  }
6780
- const decl = (resolvedSymbol.declarations ?? [])[0];
7270
+ const decl = (resolvedSymbol2.declarations ?? [])[0];
6781
7271
  const kind = decl ? getExportKind(decl, checker.getTypeAtLocation(decl)) : "variable";
6782
- const docComment = resolvedSymbol.getDocumentationComment(checker);
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(resolvedSymbol);
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(resolvedSymbol);
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(resolvedSymbol);
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 decl = symbol.declarations?.[0];
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(opts);
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
- if (symbol.flags & ts18.SymbolFlags.Alias) {
7090
- try {
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 } = resolveExportTarget2(symbol, typeChecker);
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
- resolveExportTarget2 as resolveExportTarget,
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,