@openpkg-ts/extract 0.11.3 → 0.11.4

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-9x67bae3.js";
4
+ } from "../shared/chunk-twaykyxs.js";
5
5
 
6
6
  // src/cli/spec.ts
7
7
  import * as fs from "node:fs";
@@ -1,6 +1,95 @@
1
1
  // src/ast/registry.ts
2
+ import ts from "typescript";
3
+ var PRIMITIVES = new Set([
4
+ "string",
5
+ "number",
6
+ "boolean",
7
+ "void",
8
+ "any",
9
+ "undefined",
10
+ "null",
11
+ "never",
12
+ "unknown",
13
+ "object",
14
+ "symbol",
15
+ "bigint"
16
+ ]);
17
+ var BUILTINS = new Set([
18
+ "Array",
19
+ "ArrayBuffer",
20
+ "ArrayBufferLike",
21
+ "ArrayLike",
22
+ "Promise",
23
+ "Map",
24
+ "Set",
25
+ "WeakMap",
26
+ "WeakSet",
27
+ "Date",
28
+ "RegExp",
29
+ "Error",
30
+ "Function",
31
+ "Object",
32
+ "String",
33
+ "Number",
34
+ "Boolean",
35
+ "Symbol",
36
+ "BigInt",
37
+ "Uint8Array",
38
+ "Int8Array",
39
+ "Uint16Array",
40
+ "Int16Array",
41
+ "Uint32Array",
42
+ "Int32Array",
43
+ "Float32Array",
44
+ "Float64Array",
45
+ "BigInt64Array",
46
+ "BigUint64Array",
47
+ "DataView",
48
+ "ReadonlyArray",
49
+ "Readonly",
50
+ "Partial",
51
+ "Required",
52
+ "Pick",
53
+ "Omit",
54
+ "Record",
55
+ "Exclude",
56
+ "Extract",
57
+ "NonNullable",
58
+ "Parameters",
59
+ "ReturnType",
60
+ "ConstructorParameters",
61
+ "InstanceType",
62
+ "ThisType",
63
+ "Awaited",
64
+ "PromiseLike",
65
+ "Iterable",
66
+ "Iterator",
67
+ "IterableIterator",
68
+ "Generator",
69
+ "AsyncGenerator",
70
+ "AsyncIterable",
71
+ "AsyncIterator",
72
+ "AsyncIterableIterator",
73
+ "SharedArrayBuffer",
74
+ "Atomics",
75
+ "JSON",
76
+ "Math",
77
+ "console",
78
+ "globalThis"
79
+ ]);
80
+ function isGenericTypeParameter(name) {
81
+ if (/^[A-Z]$/.test(name))
82
+ return true;
83
+ if (/^T[A-Z]/.test(name))
84
+ return true;
85
+ if (["Key", "Value", "Item", "Element"].includes(name))
86
+ return true;
87
+ return false;
88
+ }
89
+
2
90
  class TypeRegistry {
3
91
  types = new Map;
92
+ processing = new Set;
4
93
  add(type) {
5
94
  this.types.set(type.id, type);
6
95
  }
@@ -13,22 +102,77 @@ class TypeRegistry {
13
102
  getAll() {
14
103
  return Array.from(this.types.values());
15
104
  }
16
- registerFromSymbol(symbol, checker) {
105
+ registerType(type, checker, exportedIds) {
106
+ const symbol = type.getSymbol() || type.aliasSymbol;
107
+ if (!symbol)
108
+ return;
17
109
  const name = symbol.getName();
110
+ if (PRIMITIVES.has(name))
111
+ return;
112
+ if (BUILTINS.has(name))
113
+ return;
114
+ if (name.startsWith("__"))
115
+ return;
116
+ if (symbol.flags & ts.SymbolFlags.EnumMember)
117
+ return;
118
+ if (symbol.flags & ts.SymbolFlags.TypeParameter)
119
+ return;
120
+ if (isGenericTypeParameter(name))
121
+ return;
18
122
  if (this.has(name))
19
- return this.get(name);
20
- const type = {
123
+ return name;
124
+ if (exportedIds.has(name))
125
+ return name;
126
+ if (this.processing.has(name))
127
+ return name;
128
+ this.processing.add(name);
129
+ try {
130
+ const specType = this.buildSpecType(symbol, type, checker);
131
+ if (specType) {
132
+ this.add(specType);
133
+ return specType.id;
134
+ }
135
+ } finally {
136
+ this.processing.delete(name);
137
+ }
138
+ return;
139
+ }
140
+ buildSpecType(symbol, type, checker) {
141
+ const name = symbol.getName();
142
+ const decl = symbol.declarations?.[0];
143
+ let kind = "type";
144
+ if (decl) {
145
+ if (ts.isClassDeclaration(decl))
146
+ kind = "class";
147
+ else if (ts.isInterfaceDeclaration(decl))
148
+ kind = "interface";
149
+ else if (ts.isEnumDeclaration(decl))
150
+ kind = "enum";
151
+ }
152
+ const typeString = checker.typeToString(type);
153
+ return {
21
154
  id: name,
22
155
  name,
23
- kind: "type"
156
+ kind,
157
+ type: typeString !== name ? typeString : undefined
24
158
  };
25
- this.add(type);
26
- return type;
159
+ }
160
+ registerFromSymbol(symbol, checker) {
161
+ const name = symbol.getName();
162
+ if (this.has(name))
163
+ return this.get(name);
164
+ const type = checker.getDeclaredTypeOfSymbol(symbol);
165
+ const specType = this.buildSpecType(symbol, type, checker);
166
+ if (specType) {
167
+ this.add(specType);
168
+ return specType;
169
+ }
170
+ return;
27
171
  }
28
172
  }
29
173
 
30
174
  // src/ast/utils.ts
31
- import ts from "typescript";
175
+ import ts2 from "typescript";
32
176
  function parseExamplesFromTags(tags) {
33
177
  const examples = [];
34
178
  for (const tag of tags) {
@@ -51,17 +195,17 @@ function parseExamplesFromTags(tags) {
51
195
  return examples;
52
196
  }
53
197
  function getJSDocComment(node) {
54
- const jsDocTags = ts.getJSDocTags(node);
198
+ const jsDocTags = ts2.getJSDocTags(node);
55
199
  const tags = jsDocTags.map((tag) => ({
56
200
  name: tag.tagName.text,
57
- text: typeof tag.comment === "string" ? tag.comment : ts.getTextOfJSDocComment(tag.comment) ?? ""
201
+ text: typeof tag.comment === "string" ? tag.comment : ts2.getTextOfJSDocComment(tag.comment) ?? ""
58
202
  }));
59
203
  const jsDocComments = node.jsDoc;
60
204
  let description;
61
205
  if (jsDocComments && jsDocComments.length > 0) {
62
206
  const firstDoc = jsDocComments[0];
63
207
  if (firstDoc.comment) {
64
- description = typeof firstDoc.comment === "string" ? firstDoc.comment : ts.getTextOfJSDocComment(firstDoc.comment);
208
+ description = typeof firstDoc.comment === "string" ? firstDoc.comment : ts2.getTextOfJSDocComment(firstDoc.comment);
65
209
  }
66
210
  }
67
211
  const examples = parseExamplesFromTags(tags);
@@ -77,34 +221,34 @@ function getSourceLocation(node, sourceFile) {
77
221
 
78
222
  // src/compiler/program.ts
79
223
  import * as path from "node:path";
80
- import ts2 from "typescript";
224
+ import ts3 from "typescript";
81
225
  var DEFAULT_COMPILER_OPTIONS = {
82
- target: ts2.ScriptTarget.Latest,
83
- module: ts2.ModuleKind.CommonJS,
226
+ target: ts3.ScriptTarget.Latest,
227
+ module: ts3.ModuleKind.CommonJS,
84
228
  lib: ["lib.es2021.d.ts"],
85
229
  declaration: true,
86
- moduleResolution: ts2.ModuleResolutionKind.NodeJs
230
+ moduleResolution: ts3.ModuleResolutionKind.NodeJs
87
231
  };
88
232
  function createProgram({
89
233
  entryFile,
90
234
  baseDir = path.dirname(entryFile),
91
235
  content
92
236
  }) {
93
- const configPath = ts2.findConfigFile(baseDir, ts2.sys.fileExists, "tsconfig.json");
237
+ const configPath = ts3.findConfigFile(baseDir, ts3.sys.fileExists, "tsconfig.json");
94
238
  let compilerOptions = { ...DEFAULT_COMPILER_OPTIONS };
95
239
  if (configPath) {
96
- const configFile = ts2.readConfigFile(configPath, ts2.sys.readFile);
97
- const parsedConfig = ts2.parseJsonConfigFileContent(configFile.config, ts2.sys, path.dirname(configPath));
240
+ const configFile = ts3.readConfigFile(configPath, ts3.sys.readFile);
241
+ const parsedConfig = ts3.parseJsonConfigFileContent(configFile.config, ts3.sys, path.dirname(configPath));
98
242
  compilerOptions = { ...compilerOptions, ...parsedConfig.options };
99
243
  }
100
244
  const allowJsVal = compilerOptions.allowJs;
101
245
  if (typeof allowJsVal === "boolean" && allowJsVal) {
102
246
  compilerOptions = { ...compilerOptions, allowJs: false, checkJs: false };
103
247
  }
104
- const compilerHost = ts2.createCompilerHost(compilerOptions, true);
248
+ const compilerHost = ts3.createCompilerHost(compilerOptions, true);
105
249
  let inMemorySource;
106
250
  if (content !== undefined) {
107
- inMemorySource = ts2.createSourceFile(entryFile, content, ts2.ScriptTarget.Latest, true, ts2.ScriptKind.TS);
251
+ inMemorySource = ts3.createSourceFile(entryFile, content, ts3.ScriptTarget.Latest, true, ts3.ScriptKind.TS);
108
252
  const originalGetSourceFile = compilerHost.getSourceFile.bind(compilerHost);
109
253
  compilerHost.getSourceFile = (fileName, languageVersion, onError, shouldCreateNewSourceFile) => {
110
254
  if (fileName === entryFile) {
@@ -113,7 +257,7 @@ function createProgram({
113
257
  return originalGetSourceFile(fileName, languageVersion, onError, shouldCreateNewSourceFile);
114
258
  };
115
259
  }
116
- const program = ts2.createProgram([entryFile], compilerOptions, compilerHost);
260
+ const program = ts3.createProgram([entryFile], compilerOptions, compilerHost);
117
261
  const sourceFile = inMemorySource ?? program.getSourceFile(entryFile);
118
262
  return {
119
263
  program,
@@ -176,9 +320,11 @@ function serializeEnum(node, ctx) {
176
320
  }
177
321
 
178
322
  // src/types/parameters.ts
179
- function extractParameters(signature, checker) {
323
+ function extractParameters(signature, ctx) {
324
+ const { typeChecker: checker, typeRegistry, exportedIds } = ctx;
180
325
  return signature.getParameters().map((param) => {
181
326
  const type = checker.getTypeOfSymbolAtLocation(param, param.valueDeclaration);
327
+ registerReferencedTypes(type, ctx);
182
328
  return {
183
329
  name: param.getName(),
184
330
  schema: { type: checker.typeToString(type) },
@@ -186,6 +332,29 @@ function extractParameters(signature, checker) {
186
332
  };
187
333
  });
188
334
  }
335
+ function registerReferencedTypes(type, ctx) {
336
+ if (ctx.visitedTypes.has(type))
337
+ return;
338
+ ctx.visitedTypes.add(type);
339
+ const { typeChecker: checker, typeRegistry, exportedIds } = ctx;
340
+ typeRegistry.registerType(type, checker, exportedIds);
341
+ const typeArgs = type.typeArguments;
342
+ if (typeArgs) {
343
+ for (const arg of typeArgs) {
344
+ registerReferencedTypes(arg, ctx);
345
+ }
346
+ }
347
+ if (type.isUnion()) {
348
+ for (const t of type.types) {
349
+ registerReferencedTypes(t, ctx);
350
+ }
351
+ }
352
+ if (type.isIntersection()) {
353
+ for (const t of type.types) {
354
+ registerReferencedTypes(t, ctx);
355
+ }
356
+ }
357
+ }
189
358
 
190
359
  // src/serializers/functions.ts
191
360
  function serializeFunctionExport(node, ctx) {
@@ -199,8 +368,9 @@ function serializeFunctionExport(node, ctx) {
199
368
  const type = ctx.typeChecker.getTypeAtLocation(node);
200
369
  const callSignatures = type.getCallSignatures();
201
370
  const signatures = callSignatures.map((sig) => {
202
- const params = extractParameters(sig, ctx.typeChecker);
371
+ const params = extractParameters(sig, ctx);
203
372
  const returnType = ctx.typeChecker.getReturnTypeOfSignature(sig);
373
+ registerReferencedTypes(returnType, ctx);
204
374
  return {
205
375
  parameters: params,
206
376
  returns: {
@@ -275,6 +445,7 @@ function serializeVariable(node, statement, ctx) {
275
445
  const source = getSourceLocation(node, declSourceFile);
276
446
  const type = ctx.typeChecker.getTypeAtLocation(node);
277
447
  const typeString = ctx.typeChecker.typeToString(type);
448
+ registerReferencedTypes(type, ctx);
278
449
  return {
279
450
  id: name,
280
451
  name,
@@ -291,7 +462,7 @@ function serializeVariable(node, statement, ctx) {
291
462
  import * as fs from "node:fs";
292
463
  import * as path2 from "node:path";
293
464
  import { SCHEMA_VERSION } from "@openpkg-ts/spec";
294
- import ts3 from "typescript";
465
+ import ts4 from "typescript";
295
466
 
296
467
  // src/serializers/context.ts
297
468
  function createContext(program, sourceFile, options = {}) {
@@ -301,7 +472,9 @@ function createContext(program, sourceFile, options = {}) {
301
472
  sourceFile,
302
473
  maxTypeDepth: options.maxTypeDepth ?? 20,
303
474
  resolveExternalTypes: options.resolveExternalTypes ?? true,
304
- typeRegistry: new TypeRegistry
475
+ typeRegistry: new TypeRegistry,
476
+ exportedIds: new Set,
477
+ visitedTypes: new Set
305
478
  };
306
479
  }
307
480
 
@@ -318,7 +491,6 @@ async function extract(options) {
318
491
  diagnostics: [{ message: `Could not load source file: ${entryFile}`, severity: "error" }]
319
492
  };
320
493
  }
321
- const ctx = createContext(program, sourceFile, { maxTypeDepth, resolveExternalTypes });
322
494
  const typeChecker = program.getTypeChecker();
323
495
  const moduleSymbol = typeChecker.getSymbolAtLocation(sourceFile);
324
496
  if (!moduleSymbol) {
@@ -328,13 +500,19 @@ async function extract(options) {
328
500
  };
329
501
  }
330
502
  const exportedSymbols = typeChecker.getExportsOfModule(moduleSymbol);
503
+ const exportedIds = new Set;
504
+ for (const symbol of exportedSymbols) {
505
+ exportedIds.add(symbol.getName());
506
+ }
507
+ const ctx = createContext(program, sourceFile, { maxTypeDepth, resolveExternalTypes });
508
+ ctx.exportedIds = exportedIds;
331
509
  for (const symbol of exportedSymbols) {
332
510
  try {
333
511
  const { declaration, targetSymbol } = resolveExportTarget(symbol, typeChecker);
334
512
  if (!declaration)
335
513
  continue;
336
514
  const exportName = symbol.getName();
337
- const exp = serializeDeclaration(declaration, targetSymbol, exportName, ctx);
515
+ const exp = serializeDeclaration(declaration, symbol, targetSymbol, exportName, ctx);
338
516
  if (exp)
339
517
  exports.push(exp);
340
518
  } catch (err) {
@@ -359,39 +537,111 @@ async function extract(options) {
359
537
  }
360
538
  function resolveExportTarget(symbol, checker) {
361
539
  let targetSymbol = symbol;
362
- if (symbol.flags & ts3.SymbolFlags.Alias) {
540
+ if (symbol.flags & ts4.SymbolFlags.Alias) {
363
541
  const aliasTarget = checker.getAliasedSymbol(symbol);
364
542
  if (aliasTarget && aliasTarget !== symbol) {
365
543
  targetSymbol = aliasTarget;
366
544
  }
367
545
  }
368
546
  const declarations = targetSymbol.declarations ?? [];
369
- const declaration = targetSymbol.valueDeclaration || declarations.find((decl) => decl.kind !== ts3.SyntaxKind.ExportSpecifier) || declarations[0];
547
+ const declaration = targetSymbol.valueDeclaration || declarations.find((decl) => decl.kind !== ts4.SyntaxKind.ExportSpecifier) || declarations[0];
370
548
  return { declaration, targetSymbol };
371
549
  }
372
- function serializeDeclaration(declaration, symbol, exportName, ctx) {
550
+ function serializeDeclaration(declaration, exportSymbol, targetSymbol, exportName, ctx) {
373
551
  let result = null;
374
- if (ts3.isFunctionDeclaration(declaration)) {
552
+ if (ts4.isFunctionDeclaration(declaration)) {
375
553
  result = serializeFunctionExport(declaration, ctx);
376
- } else if (ts3.isClassDeclaration(declaration)) {
554
+ } else if (ts4.isClassDeclaration(declaration)) {
377
555
  result = serializeClass(declaration, ctx);
378
- } else if (ts3.isInterfaceDeclaration(declaration)) {
556
+ } else if (ts4.isInterfaceDeclaration(declaration)) {
379
557
  result = serializeInterface(declaration, ctx);
380
- } else if (ts3.isTypeAliasDeclaration(declaration)) {
558
+ } else if (ts4.isTypeAliasDeclaration(declaration)) {
381
559
  result = serializeTypeAlias(declaration, ctx);
382
- } else if (ts3.isEnumDeclaration(declaration)) {
560
+ } else if (ts4.isEnumDeclaration(declaration)) {
383
561
  result = serializeEnum(declaration, ctx);
384
- } else if (ts3.isVariableDeclaration(declaration)) {
562
+ } else if (ts4.isVariableDeclaration(declaration)) {
385
563
  const varStatement = declaration.parent?.parent;
386
- if (varStatement && ts3.isVariableStatement(varStatement)) {
564
+ if (varStatement && ts4.isVariableStatement(varStatement)) {
387
565
  result = serializeVariable(declaration, varStatement, ctx);
388
566
  }
567
+ } else if (ts4.isNamespaceExport(declaration) || ts4.isModuleDeclaration(declaration)) {
568
+ result = serializeNamespaceExport(exportSymbol, exportName, ctx);
569
+ } else if (ts4.isSourceFile(declaration)) {
570
+ result = serializeNamespaceExport(exportSymbol, exportName, ctx);
389
571
  }
390
572
  if (result) {
391
573
  result = withExportName(result, exportName);
392
574
  }
393
575
  return result;
394
576
  }
577
+ function serializeNamespaceExport(symbol, exportName, ctx) {
578
+ const { description, tags, examples } = getJSDocFromExportSymbol(symbol);
579
+ return {
580
+ id: exportName,
581
+ name: exportName,
582
+ kind: "namespace",
583
+ description,
584
+ tags,
585
+ ...examples.length > 0 ? { examples } : {}
586
+ };
587
+ }
588
+ function getJSDocFromExportSymbol(symbol) {
589
+ const tags = [];
590
+ const examples = [];
591
+ const decl = symbol.declarations?.[0];
592
+ if (decl) {
593
+ const exportDecl = ts4.isNamespaceExport(decl) ? decl.parent : decl;
594
+ if (exportDecl && ts4.isExportDeclaration(exportDecl)) {
595
+ const jsDocs = ts4.getJSDocCommentsAndTags(exportDecl);
596
+ for (const doc of jsDocs) {
597
+ if (ts4.isJSDoc(doc) && doc.comment) {
598
+ const commentText = typeof doc.comment === "string" ? doc.comment : doc.comment.map((c) => ("text" in c) ? c.text : "").join("");
599
+ if (commentText) {
600
+ return {
601
+ description: commentText,
602
+ tags: extractJSDocTags(doc),
603
+ examples: extractExamples(doc)
604
+ };
605
+ }
606
+ }
607
+ }
608
+ }
609
+ }
610
+ const docComment = symbol.getDocumentationComment(undefined);
611
+ const description = docComment.map((c) => c.text).join(`
612
+ `) || undefined;
613
+ const jsTags = symbol.getJsDocTags();
614
+ for (const tag of jsTags) {
615
+ const text = tag.text?.map((t) => t.text).join("") ?? "";
616
+ if (tag.name === "example") {
617
+ examples.push(text);
618
+ } else {
619
+ tags.push({ name: tag.name, text });
620
+ }
621
+ }
622
+ return { description, tags, examples };
623
+ }
624
+ function extractJSDocTags(doc) {
625
+ const tags = [];
626
+ for (const tag of doc.tags ?? []) {
627
+ if (tag.tagName.text !== "example") {
628
+ const text = typeof tag.comment === "string" ? tag.comment : tag.comment?.map((c) => ("text" in c) ? c.text : "").join("") ?? "";
629
+ tags.push({ name: tag.tagName.text, text });
630
+ }
631
+ }
632
+ return tags;
633
+ }
634
+ function extractExamples(doc) {
635
+ const examples = [];
636
+ for (const tag of doc.tags ?? []) {
637
+ if (tag.tagName.text === "example") {
638
+ const text = typeof tag.comment === "string" ? tag.comment : tag.comment?.map((c) => ("text" in c) ? c.text : "").join("") ?? "";
639
+ if (text)
640
+ examples.push(text);
641
+ }
642
+ }
643
+ return examples;
644
+ }
395
645
  function withExportName(entry, exportName) {
396
646
  if (entry.name === exportName) {
397
647
  return entry;
@@ -428,4 +678,4 @@ async function getPackageMeta(entryFile, baseDir) {
428
678
  } catch {}
429
679
  return { name: path2.basename(searchDir) };
430
680
  }
431
- export { TypeRegistry, getJSDocComment, getSourceLocation, createProgram, serializeClass, serializeEnum, extractParameters, serializeFunctionExport, serializeInterface, serializeTypeAlias, serializeVariable, extract };
681
+ export { TypeRegistry, getJSDocComment, getSourceLocation, createProgram, serializeClass, serializeEnum, extractParameters, registerReferencedTypes, serializeFunctionExport, serializeInterface, serializeTypeAlias, serializeVariable, extract };
@@ -2,10 +2,17 @@ import { SpecType } from "@openpkg-ts/spec";
2
2
  import ts from "typescript";
3
3
  declare class TypeRegistry {
4
4
  private types;
5
+ private processing;
5
6
  add(type: SpecType): void;
6
7
  get(id: string): SpecType | undefined;
7
8
  has(id: string): boolean;
8
9
  getAll(): SpecType[];
10
+ /**
11
+ * Register a type from a ts.Type, extracting its structure.
12
+ * Returns the type ID if registered, undefined if skipped.
13
+ */
14
+ registerType(type: ts.Type, checker: ts.TypeChecker, exportedIds: Set<string>): string | undefined;
15
+ private buildSpecType;
9
16
  registerFromSymbol(symbol: ts.Symbol, checker: ts.TypeChecker): SpecType | undefined;
10
17
  }
11
18
  import { SpecExample, SpecSource, SpecTag } from "@openpkg-ts/spec";
@@ -17,9 +24,9 @@ declare function getJSDocComment(node: ts2.Node): {
17
24
  };
18
25
  declare function getSourceLocation(node: ts2.Node, sourceFile: ts2.SourceFile): SpecSource;
19
26
  import { OpenPkg } from "@openpkg-ts/spec";
20
- import { TypeChecker as TypeChecker_vexmldwuwp } from "typescript";
21
- import { Program as Program_lhgjafqgga } from "typescript";
22
- import { SourceFile as SourceFile_sameteuoys } from "typescript";
27
+ import { TypeChecker as TypeChecker_lrgbhchnsl } from "typescript";
28
+ import { Program as Program_jbfzpxflck } from "typescript";
29
+ import { SourceFile as SourceFile_eubaywigwb } from "typescript";
23
30
  interface ExtractOptions {
24
31
  entryFile: string;
25
32
  baseDir?: string;
@@ -42,9 +49,9 @@ interface Diagnostic {
42
49
  };
43
50
  }
44
51
  interface SerializerContext {
45
- typeChecker: TypeChecker_vexmldwuwp;
46
- program: Program_lhgjafqgga;
47
- sourceFile: SourceFile_sameteuoys;
52
+ typeChecker: TypeChecker_lrgbhchnsl;
53
+ program: Program_jbfzpxflck;
54
+ sourceFile: SourceFile_eubaywigwb;
48
55
  maxTypeDepth: number;
49
56
  resolveExternalTypes: boolean;
50
57
  }
@@ -95,6 +102,9 @@ interface SerializerContext2 {
95
102
  maxTypeDepth: number;
96
103
  resolveExternalTypes: boolean;
97
104
  typeRegistry: TypeRegistry;
105
+ exportedIds: Set<string>;
106
+ /** Track visited types to prevent infinite recursion */
107
+ visitedTypes: Set<ts6.Type>;
98
108
  }
99
109
  declare function serializeClass(node: ts7.ClassDeclaration, ctx: SerializerContext2): SpecExport | null;
100
110
  import { SpecExport as SpecExport2 } from "@openpkg-ts/spec";
@@ -117,11 +127,16 @@ declare function formatTypeReference(type: ts13.Type, checker: ts13.TypeChecker)
117
127
  declare function collectReferencedTypes(type: ts13.Type, checker: ts13.TypeChecker, visited?: Set<string>): string[];
118
128
  import { SpecSignatureParameter } from "@openpkg-ts/spec";
119
129
  import ts14 from "typescript";
120
- declare function extractParameters(signature: ts14.Signature, checker: ts14.TypeChecker): SpecSignatureParameter[];
130
+ declare function extractParameters(signature: ts14.Signature, ctx: SerializerContext2): SpecSignatureParameter[];
131
+ /**
132
+ * Recursively register types referenced by a ts.Type.
133
+ * Uses ctx.visitedTypes to prevent infinite recursion on circular types.
134
+ */
135
+ declare function registerReferencedTypes(type: ts14.Type, ctx: SerializerContext2): void;
121
136
  import { SpecSchema as SpecSchema3 } from "@openpkg-ts/spec";
122
137
  import ts15 from "typescript";
123
138
  declare function buildSchema(type: ts15.Type, checker: ts15.TypeChecker, depth?: number): SpecSchema3;
124
139
  import ts16 from "typescript";
125
140
  declare function isExported(node: ts16.Node): boolean;
126
141
  declare function getNodeName(node: ts16.Node): string | undefined;
127
- export { zodAdapter, valibotAdapter, typeboxAdapter, serializeVariable, serializeTypeAlias, serializeInterface, serializeFunctionExport, serializeEnum, serializeClass, registerAdapter, isSchemaType, isExported, getSourceLocation, getNodeName, getJSDocComment, formatTypeReference, findAdapter, extractStandardSchemas, extractSchemaType, extractParameters, extract, createProgram, collectReferencedTypes, buildSchema, arktypeAdapter, TypeRegistry, StandardSchemaResult, SerializerContext, SchemaAdapter, ProgramResult, ProgramOptions, ExtractResult, ExtractOptions, Diagnostic };
142
+ export { zodAdapter, valibotAdapter, typeboxAdapter, serializeVariable, serializeTypeAlias, serializeInterface, serializeFunctionExport, serializeEnum, serializeClass, registerReferencedTypes, registerAdapter, isSchemaType, isExported, getSourceLocation, getNodeName, getJSDocComment, formatTypeReference, findAdapter, extractStandardSchemas, extractSchemaType, extractParameters, extract, createProgram, collectReferencedTypes, buildSchema, arktypeAdapter, TypeRegistry, StandardSchemaResult, SerializerContext, SchemaAdapter, ProgramResult, ProgramOptions, ExtractResult, ExtractOptions, Diagnostic };
package/dist/src/index.js CHANGED
@@ -5,13 +5,14 @@ import {
5
5
  extractParameters,
6
6
  getJSDocComment,
7
7
  getSourceLocation,
8
+ registerReferencedTypes,
8
9
  serializeClass,
9
10
  serializeEnum,
10
11
  serializeFunctionExport,
11
12
  serializeInterface,
12
13
  serializeTypeAlias,
13
14
  serializeVariable
14
- } from "../shared/chunk-9x67bae3.js";
15
+ } from "../shared/chunk-twaykyxs.js";
15
16
  // src/schema/adapters/arktype.ts
16
17
  var arktypeAdapter = {
17
18
  name: "arktype",
@@ -119,6 +120,7 @@ export {
119
120
  serializeFunctionExport,
120
121
  serializeEnum,
121
122
  serializeClass,
123
+ registerReferencedTypes,
122
124
  registerAdapter,
123
125
  isSchemaType,
124
126
  isExported,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openpkg-ts/extract",
3
- "version": "0.11.3",
3
+ "version": "0.11.4",
4
4
  "description": "TypeScript export extraction to OpenPkg spec",
5
5
  "keywords": [
6
6
  "openpkg",