@openpkg-ts/extract 0.14.0 → 0.14.1

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/bin/tspec.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  extract
4
- } from "../shared/chunk-v4cnenxs.js";
4
+ } from "../shared/chunk-khwn5myc.js";
5
5
 
6
6
  // src/cli/spec.ts
7
7
  import * as fs from "node:fs";
@@ -9,7 +9,7 @@ import * as path from "node:path";
9
9
  import { normalize, validateSpec } from "@openpkg-ts/spec";
10
10
  import { Command } from "commander";
11
11
  function createProgram() {
12
- const program = new Command("tspec").description("Extract TypeScript package API to OpenPkg spec").argument("[entry]", "Entry point file").option("-o, --output <file>", "Output file", "openpkg.json").option("--max-depth <n>", "Max type depth", "20").option("--skip-resolve", "Skip external type resolution").option("--runtime", "Enable Standard Schema runtime extraction").action(async (entry, options) => {
12
+ const program = new Command("tspec").description("Extract TypeScript package API to OpenPkg spec").argument("[entry]", "Entry point file").option("-o, --output <file>", "Output file", "openpkg.json").option("--max-depth <n>", "Max type depth (default: 4)").option("--skip-resolve", "Skip external type resolution").option("--runtime", "Enable Standard Schema runtime extraction").action(async (entry, options) => {
13
13
  const entryFile = entry || findEntryPoint(process.cwd());
14
14
  if (!entryFile) {
15
15
  console.error("No entry point found. Please specify an entry file.");
@@ -18,7 +18,7 @@ function createProgram() {
18
18
  console.log(`Extracting from: ${entryFile}`);
19
19
  const result = await extract({
20
20
  entryFile: path.resolve(entryFile),
21
- maxTypeDepth: parseInt(options.maxDepth),
21
+ ...options.maxDepth ? { maxTypeDepth: parseInt(options.maxDepth) } : {},
22
22
  resolveExternalTypes: !options.skipResolve,
23
23
  schemaExtraction: options.runtime ? "hybrid" : "static"
24
24
  });
@@ -1,6 +1,4 @@
1
1
  // src/ast/registry.ts
2
- import * as fs from "node:fs";
3
- import * as path from "node:path";
4
2
  import ts from "typescript";
5
3
  var PRIMITIVES = new Set([
6
4
  "string",
@@ -94,48 +92,6 @@ function isExternalType(decl) {
94
92
  return false;
95
93
  return sourceFile.fileName.includes("node_modules");
96
94
  }
97
- function extractPackageName(filePath) {
98
- const nmIndex = filePath.lastIndexOf("node_modules");
99
- if (nmIndex === -1)
100
- return;
101
- const afterNm = filePath.slice(nmIndex + "node_modules/".length);
102
- const parts = afterNm.split("/");
103
- if (parts[0].startsWith("@") && parts.length >= 2) {
104
- return `${parts[0]}/${parts[1]}`;
105
- }
106
- return parts[0];
107
- }
108
- function getPackageVersion(filePath, packageName) {
109
- const nmIndex = filePath.lastIndexOf("node_modules");
110
- if (nmIndex === -1)
111
- return;
112
- const nmDir = filePath.slice(0, nmIndex + "node_modules".length);
113
- const pkgJsonPath = path.join(nmDir, packageName, "package.json");
114
- try {
115
- if (fs.existsSync(pkgJsonPath)) {
116
- const pkg = JSON.parse(fs.readFileSync(pkgJsonPath, "utf-8"));
117
- return pkg.version;
118
- }
119
- } catch {}
120
- return;
121
- }
122
- function buildExternalSource(decl) {
123
- const sourceFile = decl.getSourceFile();
124
- if (!sourceFile)
125
- return;
126
- const filePath = sourceFile.fileName;
127
- if (!filePath.includes("node_modules"))
128
- return;
129
- const packageName = extractPackageName(filePath);
130
- if (!packageName)
131
- return;
132
- const version = getPackageVersion(filePath, packageName);
133
- return {
134
- file: filePath,
135
- package: packageName,
136
- version
137
- };
138
- }
139
95
 
140
96
  class TypeRegistry {
141
97
  types = new Map;
@@ -167,17 +123,19 @@ class TypeRegistry {
167
123
  return;
168
124
  if (symbol.flags & ts.SymbolFlags.TypeParameter)
169
125
  return;
126
+ if (symbol.flags & ts.SymbolFlags.Method)
127
+ return;
128
+ if (symbol.flags & ts.SymbolFlags.Function)
129
+ return;
170
130
  if (isGenericTypeParameter(name))
171
131
  return;
172
132
  if (this.has(name))
173
133
  return name;
174
- if (exportedIds.has(name))
175
- return name;
176
134
  if (this.processing.has(name))
177
135
  return name;
178
136
  this.processing.add(name);
179
137
  try {
180
- const specType = this.buildSpecType(symbol, type, checker);
138
+ const specType = this.buildStubType(symbol, checker);
181
139
  if (specType) {
182
140
  this.add(specType);
183
141
  return specType.id;
@@ -187,7 +145,7 @@ class TypeRegistry {
187
145
  }
188
146
  return;
189
147
  }
190
- buildSpecType(symbol, type, checker) {
148
+ buildStubType(symbol, checker) {
191
149
  const name = symbol.getName();
192
150
  const decl = symbol.declarations?.[0];
193
151
  let kind = "type";
@@ -203,139 +161,21 @@ class TypeRegistry {
203
161
  if (external) {
204
162
  kind = "external";
205
163
  }
206
- const source = decl ? buildExternalSource(decl) : undefined;
207
- const schema = this.buildShallowSchema(type, checker);
208
- let members;
209
- if (decl && (ts.isClassDeclaration(decl) || ts.isInterfaceDeclaration(decl))) {
210
- members = this.extractShallowMembers(decl, checker);
211
- }
164
+ const type = checker.getDeclaredTypeOfSymbol(symbol);
165
+ const typeString = checker.typeToString(type);
212
166
  return {
213
167
  id: name,
214
168
  name,
215
169
  kind,
216
- schema,
217
- members: members?.length ? members : undefined,
218
- ...external ? { external: true } : {},
219
- ...source ? { source } : {}
170
+ schema: { type: typeString },
171
+ ...external ? { external: true } : {}
220
172
  };
221
173
  }
222
- buildShallowSchema(type, checker) {
223
- if (type.isUnion()) {
224
- const allEnumLiterals = type.types.every((t) => t.flags & (ts.TypeFlags.EnumLiteral | ts.TypeFlags.NumberLiteral));
225
- if (allEnumLiterals) {
226
- const values = type.types.map((t) => {
227
- if (t.flags & ts.TypeFlags.NumberLiteral) {
228
- return t.value;
229
- }
230
- return checker.typeToString(t);
231
- }).filter((v) => v !== undefined);
232
- if (values.every((v) => typeof v === "number")) {
233
- return { type: "number", enum: values };
234
- }
235
- return { type: "string", enum: values };
236
- }
237
- return {
238
- anyOf: type.types.map((t) => {
239
- if (t.flags & ts.TypeFlags.EnumLiteral) {
240
- const value = t.value;
241
- if (typeof value === "number") {
242
- return { type: "number", enum: [value] };
243
- }
244
- return { type: checker.typeToString(t) };
245
- }
246
- const sym = t.getSymbol() || t.aliasSymbol;
247
- if (sym && sym.flags & ts.SymbolFlags.EnumMember) {
248
- return { type: checker.typeToString(t) };
249
- }
250
- if (sym && !sym.getName().startsWith("__")) {
251
- return { $ref: `#/types/${sym.getName()}` };
252
- }
253
- if (t.flags & ts.TypeFlags.StringLiteral) {
254
- return { type: "string", enum: [t.value] };
255
- }
256
- if (t.flags & ts.TypeFlags.NumberLiteral) {
257
- return { type: "number", enum: [t.value] };
258
- }
259
- return { type: checker.typeToString(t) };
260
- })
261
- };
262
- }
263
- if (type.isIntersection()) {
264
- return {
265
- allOf: type.types.map((t) => {
266
- const sym = t.getSymbol() || t.aliasSymbol;
267
- if (sym && !sym.getName().startsWith("__")) {
268
- return { $ref: `#/types/${sym.getName()}` };
269
- }
270
- return { type: checker.typeToString(t) };
271
- })
272
- };
273
- }
274
- const props = type.getProperties();
275
- if (props.length > 0) {
276
- const properties = {};
277
- const required = [];
278
- for (const prop of props.slice(0, 30)) {
279
- const propName = prop.getName();
280
- if (propName.startsWith("_"))
281
- continue;
282
- const propType = checker.getTypeOfSymbol(prop);
283
- const callSigs = propType.getCallSignatures();
284
- if (callSigs.length > 0) {
285
- properties[propName] = { type: "function" };
286
- } else {
287
- const propSym = propType.getSymbol() || propType.aliasSymbol;
288
- const symName = propSym?.getName();
289
- if (propSym && symName && !symName.startsWith("__") && symName !== propName) {
290
- properties[propName] = { $ref: `#/types/${symName}` };
291
- } else {
292
- properties[propName] = { type: checker.typeToString(propType) };
293
- }
294
- }
295
- if (!(prop.flags & ts.SymbolFlags.Optional)) {
296
- required.push(propName);
297
- }
298
- }
299
- return {
300
- type: "object",
301
- properties,
302
- ...required.length ? { required } : {}
303
- };
304
- }
305
- return { type: checker.typeToString(type) };
306
- }
307
- extractShallowMembers(decl, checker) {
308
- const members = [];
309
- for (const member of decl.members) {
310
- if (ts.isPropertyDeclaration(member) || ts.isPropertySignature(member)) {
311
- const name = member.name?.getText();
312
- if (!name || name.startsWith("#") || name.startsWith("_"))
313
- continue;
314
- const type = checker.getTypeAtLocation(member);
315
- const sym = type.getSymbol() || type.aliasSymbol;
316
- members.push({
317
- name,
318
- kind: "property",
319
- schema: sym && !sym.getName().startsWith("__") ? { $ref: `#/types/${sym.getName()}` } : { type: checker.typeToString(type) }
320
- });
321
- } else if (ts.isMethodDeclaration(member) || ts.isMethodSignature(member)) {
322
- const name = member.name?.getText();
323
- if (!name || name.startsWith("#") || name.startsWith("_"))
324
- continue;
325
- members.push({
326
- name,
327
- kind: "method"
328
- });
329
- }
330
- }
331
- return members;
332
- }
333
174
  registerFromSymbol(symbol, checker) {
334
175
  const name = symbol.getName();
335
176
  if (this.has(name))
336
177
  return this.get(name);
337
- const type = checker.getDeclaredTypeOfSymbol(symbol);
338
- const specType = this.buildSpecType(symbol, type, checker);
178
+ const specType = this.buildStubType(symbol, checker);
339
179
  if (specType) {
340
180
  this.add(specType);
341
181
  return specType;
@@ -445,7 +285,7 @@ function isSymbolDeprecated(symbol) {
445
285
  }
446
286
 
447
287
  // src/compiler/program.ts
448
- import * as path2 from "node:path";
288
+ import * as path from "node:path";
449
289
  import ts3 from "typescript";
450
290
  var DEFAULT_COMPILER_OPTIONS = {
451
291
  target: ts3.ScriptTarget.Latest,
@@ -456,14 +296,14 @@ var DEFAULT_COMPILER_OPTIONS = {
456
296
  };
457
297
  function createProgram({
458
298
  entryFile,
459
- baseDir = path2.dirname(entryFile),
299
+ baseDir = path.dirname(entryFile),
460
300
  content
461
301
  }) {
462
302
  const configPath = ts3.findConfigFile(baseDir, ts3.sys.fileExists, "tsconfig.json");
463
303
  let compilerOptions = { ...DEFAULT_COMPILER_OPTIONS };
464
304
  if (configPath) {
465
305
  const configFile = ts3.readConfigFile(configPath, ts3.sys.readFile);
466
- const parsedConfig = ts3.parseJsonConfigFileContent(configFile.config, ts3.sys, path2.dirname(configPath));
306
+ const parsedConfig = ts3.parseJsonConfigFileContent(configFile.config, ts3.sys, path.dirname(configPath));
467
307
  compilerOptions = { ...compilerOptions, ...parsedConfig.options };
468
308
  }
469
309
  const allowJsVal = compilerOptions.allowJs;
@@ -615,12 +455,19 @@ function buildSchema(type, checker, ctx, _depth = 0) {
615
455
  return { type: checker.typeToString(type) };
616
456
  }
617
457
  if (ctx?.visitedTypes.has(type)) {
458
+ const callSignatures = type.getCallSignatures();
459
+ if (callSignatures.length > 0) {
460
+ return buildFunctionSchema(callSignatures, checker, ctx);
461
+ }
618
462
  const symbol2 = type.getSymbol() || type.aliasSymbol;
619
463
  if (symbol2) {
620
464
  return { $ref: `#/types/${symbol2.getName()}` };
621
465
  }
622
466
  return { type: checker.typeToString(type) };
623
467
  }
468
+ if (ctx && type.flags & ts4.TypeFlags.Object) {
469
+ ctx.visitedTypes.add(type);
470
+ }
624
471
  if (type.flags & ts4.TypeFlags.String)
625
472
  return { type: "string" };
626
473
  if (type.flags & ts4.TypeFlags.Number)
@@ -734,6 +581,12 @@ function buildSchema(type, checker, ctx, _depth = 0) {
734
581
  };
735
582
  }
736
583
  }
584
+ if (type.flags & ts4.TypeFlags.Object) {
585
+ const callSignatures = type.getCallSignatures();
586
+ if (callSignatures.length > 0) {
587
+ return buildFunctionSchema(callSignatures, checker, ctx);
588
+ }
589
+ }
737
590
  const symbol = type.getSymbol() || type.aliasSymbol;
738
591
  if (symbol && !isAnonymous(type)) {
739
592
  const name = symbol.getName();
@@ -749,10 +602,6 @@ function buildSchema(type, checker, ctx, _depth = 0) {
749
602
  }
750
603
  if (type.flags & ts4.TypeFlags.Object) {
751
604
  const objectType = type;
752
- const callSignatures = type.getCallSignatures();
753
- if (callSignatures.length > 0) {
754
- return buildFunctionSchema(callSignatures, checker, ctx);
755
- }
756
605
  const properties = type.getProperties();
757
606
  if (properties.length > 0 || objectType.objectFlags & ts4.ObjectFlags.Anonymous) {
758
607
  return buildObjectSchema(properties, checker, ctx);
@@ -1032,7 +881,9 @@ function extractDefaultValue(initializer) {
1032
881
  }
1033
882
  return initializer.getText();
1034
883
  }
1035
- function registerReferencedTypes(type, ctx) {
884
+ function registerReferencedTypes(type, ctx, depth = 0) {
885
+ if (depth > ctx.maxTypeDepth)
886
+ return;
1036
887
  if (ctx.visitedTypes.has(type))
1037
888
  return;
1038
889
  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);
@@ -1044,17 +895,24 @@ function registerReferencedTypes(type, ctx) {
1044
895
  const typeArgs = type.typeArguments;
1045
896
  if (typeArgs) {
1046
897
  for (const arg of typeArgs) {
1047
- registerReferencedTypes(arg, ctx);
898
+ registerReferencedTypes(arg, ctx, depth + 1);
1048
899
  }
1049
900
  }
1050
901
  if (type.isUnion()) {
1051
902
  for (const t of type.types) {
1052
- registerReferencedTypes(t, ctx);
903
+ registerReferencedTypes(t, ctx, depth + 1);
1053
904
  }
1054
905
  }
1055
906
  if (type.isIntersection()) {
1056
907
  for (const t of type.types) {
1057
- registerReferencedTypes(t, ctx);
908
+ registerReferencedTypes(t, ctx, depth + 1);
909
+ }
910
+ }
911
+ if (type.flags & ts5.TypeFlags.Object) {
912
+ const props = type.getProperties();
913
+ for (const prop of props.slice(0, 20)) {
914
+ const propType = checker.getTypeOfSymbol(prop);
915
+ registerReferencedTypes(propType, ctx, depth + 1);
1058
916
  }
1059
917
  }
1060
918
  }
@@ -1166,8 +1024,8 @@ function serializeProperty(node, ctx) {
1166
1024
  const { description, tags } = getJSDocComment(node);
1167
1025
  const visibility = getVisibility(node);
1168
1026
  const type = checker.getTypeAtLocation(node);
1169
- const schema = buildSchema(type, checker, ctx);
1170
1027
  registerReferencedTypes(type, ctx);
1028
+ const schema = buildSchema(type, checker, ctx);
1171
1029
  const flags = {};
1172
1030
  if (isStatic(node))
1173
1031
  flags.static = true;
@@ -1541,8 +1399,8 @@ function serializeTypeAlias(node, ctx) {
1541
1399
  const source = getSourceLocation(node, declSourceFile);
1542
1400
  const typeParameters = extractTypeParameters(node, ctx.typeChecker);
1543
1401
  const type = ctx.typeChecker.getTypeAtLocation(node);
1544
- const schema = buildSchema(type, ctx.typeChecker, ctx);
1545
1402
  registerReferencedTypes(type, ctx);
1403
+ const schema = buildSchema(type, ctx.typeChecker, ctx);
1546
1404
  return {
1547
1405
  id: name,
1548
1406
  name,
@@ -1566,8 +1424,8 @@ function serializeVariable(node, statement, ctx) {
1566
1424
  const { description, tags, examples } = getJSDocComment(statement);
1567
1425
  const source = getSourceLocation(node, declSourceFile);
1568
1426
  const type = ctx.typeChecker.getTypeAtLocation(node);
1569
- const schema = buildSchema(type, ctx.typeChecker, ctx);
1570
1427
  registerReferencedTypes(type, ctx);
1428
+ const schema = buildSchema(type, ctx.typeChecker, ctx);
1571
1429
  return {
1572
1430
  id: name,
1573
1431
  name,
@@ -1581,8 +1439,8 @@ function serializeVariable(node, statement, ctx) {
1581
1439
  }
1582
1440
 
1583
1441
  // src/builder/spec-builder.ts
1584
- import * as fs2 from "node:fs";
1585
- import * as path3 from "node:path";
1442
+ import * as fs from "node:fs";
1443
+ import * as path2 from "node:path";
1586
1444
  import { SCHEMA_URL, SCHEMA_VERSION } from "@openpkg-ts/spec";
1587
1445
  import ts8 from "typescript";
1588
1446
 
@@ -1605,9 +1463,14 @@ function createContext(program, sourceFile, options = {}) {
1605
1463
  // src/builder/spec-builder.ts
1606
1464
  var BUILTIN_TYPES2 = new Set([
1607
1465
  "Array",
1466
+ "ArrayBuffer",
1467
+ "ArrayBufferLike",
1468
+ "ArrayLike",
1608
1469
  "Promise",
1609
1470
  "Map",
1610
1471
  "Set",
1472
+ "WeakMap",
1473
+ "WeakSet",
1611
1474
  "Record",
1612
1475
  "Partial",
1613
1476
  "Required",
@@ -1621,6 +1484,15 @@ var BUILTIN_TYPES2 = new Set([
1621
1484
  "Readonly",
1622
1485
  "ReadonlyArray",
1623
1486
  "Awaited",
1487
+ "PromiseLike",
1488
+ "Iterable",
1489
+ "Iterator",
1490
+ "IterableIterator",
1491
+ "Generator",
1492
+ "AsyncGenerator",
1493
+ "AsyncIterable",
1494
+ "AsyncIterator",
1495
+ "AsyncIterableIterator",
1624
1496
  "Date",
1625
1497
  "RegExp",
1626
1498
  "Error",
@@ -1630,8 +1502,34 @@ var BUILTIN_TYPES2 = new Set([
1630
1502
  "Number",
1631
1503
  "Boolean",
1632
1504
  "Symbol",
1633
- "BigInt"
1505
+ "BigInt",
1506
+ "Uint8Array",
1507
+ "Int8Array",
1508
+ "Uint16Array",
1509
+ "Int16Array",
1510
+ "Uint32Array",
1511
+ "Int32Array",
1512
+ "Float32Array",
1513
+ "Float64Array",
1514
+ "BigInt64Array",
1515
+ "BigUint64Array",
1516
+ "DataView",
1517
+ "SharedArrayBuffer",
1518
+ "ConstructorParameters",
1519
+ "InstanceType",
1520
+ "ThisType"
1634
1521
  ]);
1522
+ function shouldSkipDanglingRef(name) {
1523
+ if (name.startsWith("__"))
1524
+ return true;
1525
+ if (/^[A-Z]$/.test(name))
1526
+ return true;
1527
+ if (/^T[A-Z]/.test(name))
1528
+ return true;
1529
+ if (["Key", "Value", "Item", "Element"].includes(name))
1530
+ return true;
1531
+ return false;
1532
+ }
1635
1533
  async function extract(options) {
1636
1534
  const {
1637
1535
  entryFile,
@@ -1701,10 +1599,9 @@ async function extract(options) {
1701
1599
  const externalTypes = types.filter((t) => t.kind === "external");
1702
1600
  if (externalTypes.length > 0) {
1703
1601
  diagnostics.push({
1704
- message: `${externalTypes.length} external type(s) could not be fully resolved: ${externalTypes.slice(0, 5).map((t) => t.id).join(", ")}${externalTypes.length > 5 ? "..." : ""}`,
1705
- severity: "warning",
1706
- code: "EXTERNAL_TYPE_STUBS",
1707
- suggestion: "Types are from external packages. Full resolution requires type declarations."
1602
+ message: `${externalTypes.length} external type(s) from dependencies: ${externalTypes.slice(0, 5).map((t) => t.id).join(", ")}${externalTypes.length > 5 ? "..." : ""}`,
1603
+ severity: "info",
1604
+ code: "EXTERNAL_TYPES"
1708
1605
  });
1709
1606
  }
1710
1607
  const spec = {
@@ -1744,7 +1641,7 @@ function collectDanglingRefs(exports, types) {
1744
1641
  const referencedTypes = new Set;
1745
1642
  collectAllRefs(exports, referencedTypes);
1746
1643
  collectAllRefs(types, referencedTypes);
1747
- return Array.from(referencedTypes).filter((ref) => !definedTypes.has(ref) && !BUILTIN_TYPES2.has(ref));
1644
+ return Array.from(referencedTypes).filter((ref) => !definedTypes.has(ref) && !BUILTIN_TYPES2.has(ref) && !shouldSkipDanglingRef(ref));
1748
1645
  }
1749
1646
  function resolveExportTarget(symbol, checker) {
1750
1647
  let targetSymbol = symbol;
@@ -1867,7 +1764,7 @@ function createEmptySpec(entryFile, includeSchema) {
1867
1764
  return {
1868
1765
  ...includeSchema ? { $schema: SCHEMA_URL } : {},
1869
1766
  openpkg: SCHEMA_VERSION,
1870
- meta: { name: path3.basename(entryFile, path3.extname(entryFile)) },
1767
+ meta: { name: path2.basename(entryFile, path2.extname(entryFile)) },
1871
1768
  exports: [],
1872
1769
  generation: {
1873
1770
  generator: "@openpkg-ts/extract",
@@ -1876,18 +1773,18 @@ function createEmptySpec(entryFile, includeSchema) {
1876
1773
  };
1877
1774
  }
1878
1775
  async function getPackageMeta(entryFile, baseDir) {
1879
- const searchDir = baseDir ?? path3.dirname(entryFile);
1880
- const pkgPath = path3.join(searchDir, "package.json");
1776
+ const searchDir = baseDir ?? path2.dirname(entryFile);
1777
+ const pkgPath = path2.join(searchDir, "package.json");
1881
1778
  try {
1882
- if (fs2.existsSync(pkgPath)) {
1883
- const pkg = JSON.parse(fs2.readFileSync(pkgPath, "utf-8"));
1779
+ if (fs.existsSync(pkgPath)) {
1780
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
1884
1781
  return {
1885
- name: pkg.name ?? path3.basename(searchDir),
1782
+ name: pkg.name ?? path2.basename(searchDir),
1886
1783
  version: pkg.version,
1887
1784
  description: pkg.description
1888
1785
  };
1889
1786
  }
1890
1787
  } catch {}
1891
- return { name: path3.basename(searchDir) };
1788
+ return { name: path2.basename(searchDir) };
1892
1789
  }
1893
1790
  export { TypeRegistry, getJSDocComment, getSourceLocation, getParamDescription, extractTypeParameters, isSymbolDeprecated, createProgram, BUILTIN_TYPE_SCHEMAS, isPrimitiveName, isBuiltinGeneric, isAnonymous, buildSchema, isPureRefSchema, withDescription, schemaIsAny, schemasAreEqual, deduplicateSchemas, findDiscriminatorProperty, extractParameters, registerReferencedTypes, serializeClass, serializeEnum, serializeFunctionExport, serializeInterface, serializeTypeAlias, serializeVariable, extract };
@@ -8,21 +8,14 @@ declare class TypeRegistry {
8
8
  has(id: string): boolean;
9
9
  getAll(): SpecType[];
10
10
  /**
11
- * Register a type from a ts.Type, extracting its structure.
11
+ * Register a type from a ts.Type (lightweight stub).
12
12
  * Returns the type ID if registered, undefined if skipped.
13
13
  */
14
14
  registerType(type: ts.Type, checker: ts.TypeChecker, exportedIds: Set<string>): string | undefined;
15
- private buildSpecType;
16
15
  /**
17
- * Build a shallow schema for registry types (no deep recursion).
18
- * Only captures top-level structure with $refs.
16
+ * Build a lightweight stub type (no deep schema extraction).
19
17
  */
20
- private buildShallowSchema;
21
- /**
22
- * Extract shallow members for classes/interfaces.
23
- * Only captures property names and simple type info.
24
- */
25
- private extractShallowMembers;
18
+ private buildStubType;
26
19
  registerFromSymbol(symbol: ts.Symbol, checker: ts.TypeChecker): SpecType | undefined;
27
20
  }
28
21
  import { SpecExample, SpecSource, SpecTag, SpecTypeParameter } from "@openpkg-ts/spec";
@@ -253,7 +246,7 @@ declare function extractParameters(signature: ts11.Signature, ctx: SerializerCon
253
246
  * Recursively register types referenced by a ts.Type.
254
247
  * Uses ctx.visitedTypes to prevent infinite recursion on circular types.
255
248
  */
256
- declare function registerReferencedTypes(type: ts11.Type, ctx: SerializerContext): void;
249
+ declare function registerReferencedTypes(type: ts11.Type, ctx: SerializerContext, depth?: number): void;
257
250
  import { SpecSchema } from "@openpkg-ts/spec";
258
251
  import ts12 from "typescript";
259
252
  /**
package/dist/src/index.js CHANGED
@@ -26,7 +26,7 @@ import {
26
26
  serializeTypeAlias,
27
27
  serializeVariable,
28
28
  withDescription
29
- } from "../shared/chunk-v4cnenxs.js";
29
+ } from "../shared/chunk-khwn5myc.js";
30
30
  // src/schema/registry.ts
31
31
  function isTypeReference(type) {
32
32
  return !!(type.flags & 524288 && type.objectFlags && type.objectFlags & 4);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openpkg-ts/extract",
3
- "version": "0.14.0",
3
+ "version": "0.14.1",
4
4
  "description": "TypeScript export extraction to OpenPkg spec",
5
5
  "keywords": [
6
6
  "openpkg",