@openpkg-ts/sdk 0.42.0 → 0.44.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -35,6 +35,13 @@ interface ExtractOptions {
35
35
  externals?: ExternalsConfig;
36
36
  /** Max properties to serialize per object type (default: 500) */
37
37
  maxProperties?: number;
38
+ /**
39
+ * Register referenced-but-not-exported types from dependencies as named
40
+ * types[] entries. true → all packages; string[] → listed packages (plus
41
+ * workspace siblings); false → disable the expansion pass; default →
42
+ * workspace sibling packages only.
43
+ */
44
+ followExternal?: boolean | string[];
38
45
  /** Callback when properties are truncated */
39
46
  onTruncation?: (typeName: string, actual: number, limit: number) => void;
40
47
  }
@@ -1202,6 +1209,12 @@ declare class TypeRegistry {
1202
1209
  */
1203
1210
  private resolveSelRefSchema;
1204
1211
  /**
1212
+ * Build an enum schema with member names from the enum declaration.
1213
+ * Returns undefined when the symbol has no enum declaration or no
1214
+ * constant-valued members.
1215
+ */
1216
+ private buildEnumSchema;
1217
+ /**
1205
1218
  * Build object schema from type properties (for interfaces/classes)
1206
1219
  */
1207
1220
  private buildObjectSchemaFromProperties;
@@ -1550,6 +1563,8 @@ interface ProgramResult {
1550
1563
  configPath?: string;
1551
1564
  /** Resolved project references (workspace packages) */
1552
1565
  projectReferences?: ts7.ResolvedProjectReference[];
1566
+ /** Workspace sibling packages discovered from the workspace map (name → dir) */
1567
+ workspacePackages?: Map<string, string>;
1553
1568
  }
1554
1569
  declare function createProgram(options: ProgramOptions): ProgramResult;
1555
1570
  import * as TS from "typescript";
@@ -1694,6 +1709,11 @@ declare function isPureRefSchema(schema: SpecSchema2): schema is {
1694
1709
  */
1695
1710
  declare function withDescription2(schema: SpecSchema2, description: string): SpecSchema2;
1696
1711
  /**
1712
+ * Mark a schema as deprecated, handling $ref properly.
1713
+ * For pure $ref schemas, wraps in allOf to preserve the reference.
1714
+ */
1715
+ declare function withDeprecated(schema: SpecSchema2, reason?: string): SpecSchema2;
1716
+ /**
1697
1717
  * Check if a schema represents the 'any' type
1698
1718
  */
1699
1719
  declare function schemaIsAny(schema: SpecSchema2): boolean;
@@ -1775,4 +1795,4 @@ declare function normalizeMembers(members: SpecMember3[], options?: NormalizeOpt
1775
1795
  import ts16 from "typescript";
1776
1796
  declare function isExported(node: ts16.Node): boolean;
1777
1797
  declare function getNodeName(node: ts16.Node): string | undefined;
1778
- export { zodAdapter, withDescription2 as withDescription, valibotAdapter, typeboxAdapter, toSearchIndexJSON, toSearchIndex2 as toSearchIndex, toPagefindRecords2 as toPagefindRecords, toNavigation2 as toNavigation, toMarkdown2 as toMarkdown, toJSONString, toJSON2 as toJSON, toHTML2 as toHTML, toFumadocsMetaJSON, toDocusaurusSidebarJS, toAlgoliaRecords2 as toAlgoliaRecords, sortByName, serializeVariable, serializeTypeAlias, serializeInterface, serializeFunctionExport, serializeEnum, serializeClass, schemasAreEqual, schemaIsAny, resolveTypeRef, resolveExportTarget, resolveCompiledPath, registerReferencedTypes, registerAdapter, recommendSemverBump, query, normalizeType, normalizeSchema, normalizeMembers, normalizeExport, mergeConfig, loadSpec, loadConfig, listExports, isTypeReference, isTypeOnlyExport, isSymbolDeprecated, isStandardJSONSchema, isSchemaType, isPureRefSchema, isProperty, isPrimitiveName, isMethod, isExported, isBuiltinGeneric, isAnonymous, hasDeprecatedTag, groupByVisibility, getTypeOrigin, getSourceLocation, getProperties, getParamDescription, getNonNullableType, getNodeName, getMethods, getMemberBadges, getJSDocComment, getExportKind, getExport2 as getExport, getDeprecationMessage, toMarkdown2 as generateDocs, formatTypeParameters, formatSchema, formatReturnType, formatParameters, formatMappedType, formatConditionalType, formatBadges, findMissingParamDocs, findDiscriminatorProperty, findAdapter, filterSpec, extractTypeParameters, extractStandardSchemasFromTs, extractStandardSchemasFromProject, extractStandardSchemas, extractSpec, extractSchemaType, extractParameters, extract, exportToMarkdown, ensureNonEmptySchema, diffSpec2 as diffSpecs, diffSpec, detectTsRuntime, deduplicateSchemas, createProgram, createDocs, categorizeBreakingChanges, calculateNextVersion, buildSignatureString, buildSchema, buildObjectSchema, buildFunctionSchema, arktypeAdapter, analyzeSpec, TypeRegistry, TypeReference2 as TypeReference, TsRuntime, StandardSchemaExtractionResult, StandardSchemaExtractionOutput, StandardJSONSchemaV1, StandardJSONSchemaTarget, StandardJSONSchemaOptions, SpecMappedType, SpecDiff, SpecDiagnostics, SpecConditionalType, SkippedExportDetail, SimplifiedSpec, SimplifiedSignature, SimplifiedReturn, SimplifiedParameter, SimplifiedMember, SimplifiedExport, SimplifiedExample, SerializerContext, SemverRecommendation, SemverBump, SearchRecord, SearchOptions, SearchIndex, SchemaExtractionResult, SchemaAdapter, STRING_PROTOTYPE_METHODS, QueryBuilder, ProjectExtractionOutput, ProjectExtractionInfo, ProgramResult, ProgramOptions, PagefindRecord, PRIMITIVES, OpenpkgConfig, NormalizeOptions, NavOptions, NavItem, NavGroup, NavFormat, NUMBER_PROTOTYPE_METHODS, MemberChangeInfo, MarkdownOptions, LoadOptions, ListExportsResult, ListExportsOptions, JSONSchema, JSONOptions, HTMLOptions, GroupBy, GetExportResult, GetExportOptions, GenericNav, FumadocsMetaItem, FumadocsMeta, FormatSchemaOptions, ForgottenExport, FilterResult, FilterCriteria, ExtractionWarningCode, ExtractionWarning, ExtractStandardSchemasOptions, ExtractResult, ExtractOptions, ExtractFromProjectOptions, ExternalsConfig, ExportVerification, ExportTracker, ExportMarkdownOptions, ExportItem, DocusaurusSidebarItem, DocusaurusSidebar, DocsInstance, DiagnosticItem, Diagnostic, CategorizedBreaking, CacheManagerOptions, CacheManager, CONFIG_FILENAME, BreakingSeverity, BUILTIN_TYPE_SCHEMAS, AlgoliaRecord, ARRAY_PROTOTYPE_METHODS };
1798
+ export { zodAdapter, withDescription2 as withDescription, withDeprecated, valibotAdapter, typeboxAdapter, toSearchIndexJSON, toSearchIndex2 as toSearchIndex, toPagefindRecords2 as toPagefindRecords, toNavigation2 as toNavigation, toMarkdown2 as toMarkdown, toJSONString, toJSON2 as toJSON, toHTML2 as toHTML, toFumadocsMetaJSON, toDocusaurusSidebarJS, toAlgoliaRecords2 as toAlgoliaRecords, sortByName, serializeVariable, serializeTypeAlias, serializeInterface, serializeFunctionExport, serializeEnum, serializeClass, schemasAreEqual, schemaIsAny, resolveTypeRef, resolveExportTarget, resolveCompiledPath, registerReferencedTypes, registerAdapter, recommendSemverBump, query, normalizeType, normalizeSchema, normalizeMembers, normalizeExport, mergeConfig, loadSpec, loadConfig, listExports, isTypeReference, isTypeOnlyExport, isSymbolDeprecated, isStandardJSONSchema, isSchemaType, isPureRefSchema, isProperty, isPrimitiveName, isMethod, isExported, isBuiltinGeneric, isAnonymous, hasDeprecatedTag, groupByVisibility, getTypeOrigin, getSourceLocation, getProperties, getParamDescription, getNonNullableType, getNodeName, getMethods, getMemberBadges, getJSDocComment, getExportKind, getExport2 as getExport, getDeprecationMessage, toMarkdown2 as generateDocs, formatTypeParameters, formatSchema, formatReturnType, formatParameters, formatMappedType, formatConditionalType, formatBadges, findMissingParamDocs, findDiscriminatorProperty, findAdapter, filterSpec, extractTypeParameters, extractStandardSchemasFromTs, extractStandardSchemasFromProject, extractStandardSchemas, extractSpec, extractSchemaType, extractParameters, extract, exportToMarkdown, ensureNonEmptySchema, diffSpec2 as diffSpecs, diffSpec, detectTsRuntime, deduplicateSchemas, createProgram, createDocs, categorizeBreakingChanges, calculateNextVersion, buildSignatureString, buildSchema, buildObjectSchema, buildFunctionSchema, arktypeAdapter, analyzeSpec, TypeRegistry, TypeReference2 as TypeReference, TsRuntime, StandardSchemaExtractionResult, StandardSchemaExtractionOutput, StandardJSONSchemaV1, StandardJSONSchemaTarget, StandardJSONSchemaOptions, SpecMappedType, SpecDiff, SpecDiagnostics, SpecConditionalType, SkippedExportDetail, SimplifiedSpec, SimplifiedSignature, SimplifiedReturn, SimplifiedParameter, SimplifiedMember, SimplifiedExport, SimplifiedExample, SerializerContext, SemverRecommendation, SemverBump, SearchRecord, SearchOptions, SearchIndex, SchemaExtractionResult, SchemaAdapter, STRING_PROTOTYPE_METHODS, QueryBuilder, ProjectExtractionOutput, ProjectExtractionInfo, ProgramResult, ProgramOptions, PagefindRecord, PRIMITIVES, OpenpkgConfig, NormalizeOptions, NavOptions, NavItem, NavGroup, NavFormat, NUMBER_PROTOTYPE_METHODS, MemberChangeInfo, MarkdownOptions, LoadOptions, ListExportsResult, ListExportsOptions, JSONSchema, JSONOptions, HTMLOptions, GroupBy, GetExportResult, GetExportOptions, GenericNav, FumadocsMetaItem, FumadocsMeta, FormatSchemaOptions, ForgottenExport, FilterResult, FilterCriteria, ExtractionWarningCode, ExtractionWarning, ExtractStandardSchemasOptions, ExtractResult, ExtractOptions, ExtractFromProjectOptions, ExternalsConfig, ExportVerification, ExportTracker, ExportMarkdownOptions, ExportItem, DocusaurusSidebarItem, DocusaurusSidebar, DocsInstance, DiagnosticItem, Diagnostic, CategorizedBreaking, CacheManagerOptions, CacheManager, CONFIG_FILENAME, BreakingSeverity, BUILTIN_TYPE_SCHEMAS, AlgoliaRecord, ARRAY_PROTOTYPE_METHODS };
package/dist/index.js CHANGED
@@ -1769,7 +1769,16 @@ function createProgram(options) {
1769
1769
  const parsedConfig = ts2.parseJsonConfigFileContent(configFile.config, ts2.sys, path3.dirname(configPath));
1770
1770
  compilerOptions = { ...compilerOptions, ...parsedConfig.options };
1771
1771
  additionalRootFiles = resolveProjectReferences(configPath, parsedConfig);
1772
- const sourceFiles = parsedConfig.fileNames.filter((f) => !f.includes(".test.") && !f.includes(".spec.") && !f.includes("/dist/") && !f.includes("/node_modules/"));
1772
+ let sourceFiles = parsedConfig.fileNames.filter((f) => !f.includes(".test.") && !f.includes(".spec.") && !f.includes("/dist/") && !f.includes("/node_modules/"));
1773
+ if (/\.d\.[cm]?ts$/.test(entryFile)) {
1774
+ sourceFiles = sourceFiles.filter((f) => {
1775
+ try {
1776
+ return !ts2.getOutputFileNames(parsedConfig, f, !ts2.sys.useCaseSensitiveFileNames).some((out) => path3.resolve(out) === entryFile);
1777
+ } catch {
1778
+ return true;
1779
+ }
1780
+ });
1781
+ }
1773
1782
  additionalRootFiles.push(...sourceFiles);
1774
1783
  }
1775
1784
  if (isJsFile(entryFile)) {
@@ -1826,7 +1835,8 @@ function createProgram(options) {
1826
1835
  compilerHost,
1827
1836
  compilerOptions,
1828
1837
  sourceFile,
1829
- configPath
1838
+ configPath,
1839
+ workspacePackages: new Map(workspaceMap?.packages ?? [])
1830
1840
  };
1831
1841
  }
1832
1842
 
@@ -2459,7 +2469,20 @@ function buildObjectSchema(properties, checker, ctx, originalType) {
2459
2469
  continue;
2460
2470
  }
2461
2471
  const propType = checker.getTypeOfSymbol(prop);
2462
- props[propName] = buildSchema(propType, checker, ctx);
2472
+ let propSchema = buildSchema(propType, checker, ctx);
2473
+ const docComment = prop.getDocumentationComment(checker);
2474
+ if (docComment.length > 0) {
2475
+ const description = docComment.map((c) => c.text).join(`
2476
+ `);
2477
+ if (description.trim()) {
2478
+ propSchema = withDescription(propSchema, description);
2479
+ }
2480
+ }
2481
+ const { deprecated, reason } = isSymbolDeprecated(prop);
2482
+ if (deprecated) {
2483
+ propSchema = withDeprecated(propSchema, reason);
2484
+ }
2485
+ props[propName] = propSchema;
2463
2486
  if (!(prop.flags & ts3.SymbolFlags.Optional)) {
2464
2487
  required.push(propName);
2465
2488
  }
@@ -2498,6 +2521,19 @@ function withDescription(schema, description) {
2498
2521
  }
2499
2522
  return { ...schema, description };
2500
2523
  }
2524
+ function withDeprecated(schema, reason) {
2525
+ const extra = { deprecated: true };
2526
+ if (reason?.trim()) {
2527
+ extra["x-deprecated-reason"] = reason;
2528
+ }
2529
+ if (typeof schema === "string") {
2530
+ return { type: schema, ...extra };
2531
+ }
2532
+ if (isPureRefSchema(schema)) {
2533
+ return { allOf: [schema], ...extra };
2534
+ }
2535
+ return { ...schema, ...extra };
2536
+ }
2501
2537
  function schemaIsAny(schema) {
2502
2538
  if (typeof schema === "string") {
2503
2539
  return schema === "any";
@@ -2923,6 +2959,12 @@ class TypeRegistry {
2923
2959
  if (this.isSelfRef(schema, name)) {
2924
2960
  schema = this.resolveSelRefSchema(type, checker, ctx);
2925
2961
  }
2962
+ if (kind === "enum") {
2963
+ const enumSchema = this.buildEnumSchema(symbol, checker);
2964
+ if (enumSchema) {
2965
+ schema = enumSchema;
2966
+ }
2967
+ }
2926
2968
  return {
2927
2969
  id: name,
2928
2970
  name,
@@ -2960,32 +3002,42 @@ class TypeRegistry {
2960
3002
  }
2961
3003
  const symbol = type.getSymbol() ?? type.aliasSymbol;
2962
3004
  if (symbol) {
2963
- const decl = symbol.declarations?.find(ts5.isEnumDeclaration);
2964
- if (decl) {
2965
- const members = [];
2966
- for (const member of decl.members) {
2967
- const memberSymbol = checker.getSymbolAtLocation(member.name);
2968
- if (memberSymbol) {
2969
- const constantValue = checker.getConstantValue(member);
2970
- if (constantValue !== undefined) {
2971
- members.push({
2972
- name: memberSymbol.getName(),
2973
- value: constantValue
2974
- });
2975
- }
2976
- }
2977
- }
2978
- if (members.length > 0) {
2979
- return {
2980
- type: typeof members[0].value === "string" ? "string" : "number",
2981
- enum: members.map((m) => m.value),
2982
- "x-enum-members": members
2983
- };
2984
- }
3005
+ const enumSchema = this.buildEnumSchema(symbol, checker);
3006
+ if (enumSchema) {
3007
+ return enumSchema;
2985
3008
  }
2986
3009
  }
3010
+ const callSignatures = type.getCallSignatures();
3011
+ if (callSignatures.length > 0 && type.getProperties().length === 0) {
3012
+ return buildFunctionSchema(callSignatures, checker, ctx);
3013
+ }
2987
3014
  return this.buildObjectSchemaFromProperties(type, checker, ctx);
2988
3015
  }
3016
+ buildEnumSchema(symbol, checker) {
3017
+ const decl = symbol.declarations?.find(ts5.isEnumDeclaration);
3018
+ if (!decl)
3019
+ return;
3020
+ const members = [];
3021
+ for (const member of decl.members) {
3022
+ const memberSymbol = checker.getSymbolAtLocation(member.name);
3023
+ if (memberSymbol) {
3024
+ const constantValue = checker.getConstantValue(member);
3025
+ if (constantValue !== undefined) {
3026
+ members.push({
3027
+ name: memberSymbol.getName(),
3028
+ value: constantValue
3029
+ });
3030
+ }
3031
+ }
3032
+ }
3033
+ if (members.length === 0)
3034
+ return;
3035
+ return {
3036
+ type: typeof members[0].value === "string" ? "string" : "number",
3037
+ enum: members.map((m) => m.value),
3038
+ "x-enum-members": members
3039
+ };
3040
+ }
2989
3041
  buildObjectSchemaFromProperties(type, checker, ctx) {
2990
3042
  const properties = type.getProperties();
2991
3043
  const stringIndex = checker.getIndexInfosOfType(type).find((i) => i.keyType.flags & ts5.TypeFlags.String);
@@ -3018,7 +3070,20 @@ class TypeRegistry {
3018
3070
  const propName = prop.getName();
3019
3071
  const propType = checker.getTypeOfSymbol(prop);
3020
3072
  this.registerType(propType, ctx);
3021
- props[propName] = buildSchema(propType, checker, ctx);
3073
+ let propSchema = buildSchema(propType, checker, ctx);
3074
+ const docComment = prop.getDocumentationComment(checker);
3075
+ if (docComment.length > 0) {
3076
+ const description = docComment.map((c) => c.text).join(`
3077
+ `);
3078
+ if (description.trim()) {
3079
+ propSchema = withDescription(propSchema, description);
3080
+ }
3081
+ }
3082
+ const { deprecated, reason } = isSymbolDeprecated(prop);
3083
+ if (deprecated) {
3084
+ propSchema = withDeprecated(propSchema, reason);
3085
+ }
3086
+ props[propName] = propSchema;
3022
3087
  if (!(prop.flags & ts5.SymbolFlags.Optional)) {
3023
3088
  required.push(propName);
3024
3089
  }
@@ -3256,6 +3321,9 @@ function serializeClass(node, ctx) {
3256
3321
  }
3257
3322
  }
3258
3323
  members.push(...methodsByName.values());
3324
+ if (signatures.length === 0) {
3325
+ signatures.push(...serializeInheritedConstructors(node, ctx));
3326
+ }
3259
3327
  const ownMemberNames = new Set;
3260
3328
  for (const member of node.members) {
3261
3329
  const memberName = getMemberName(member);
@@ -3397,16 +3465,44 @@ function serializeMethod(node, ctx) {
3397
3465
  }
3398
3466
  function serializeConstructor(node, ctx) {
3399
3467
  const { typeChecker: checker } = ctx;
3400
- const { description } = getJSDocComment(node);
3401
3468
  const sig = checker.getSignatureFromDeclaration(node);
3402
3469
  if (!sig)
3403
3470
  return null;
3471
+ return serializeConstructorSignature(node, sig, ctx);
3472
+ }
3473
+ function serializeConstructorSignature(node, sig, ctx) {
3474
+ const { description, tags, examples } = getJSDocComment(node);
3404
3475
  const params = extractParameters(sig, ctx);
3405
3476
  return {
3406
3477
  description,
3407
- parameters: params.length > 0 ? params : undefined
3478
+ parameters: params.length > 0 ? params : undefined,
3479
+ ...tags.length > 0 ? { tags } : {},
3480
+ ...examples.length > 0 ? { examples } : {}
3408
3481
  };
3409
3482
  }
3483
+ function serializeInheritedConstructors(node, ctx) {
3484
+ const { typeChecker: checker } = ctx;
3485
+ const hasExtends = node.heritageClauses?.some((c) => c.token === ts7.SyntaxKind.ExtendsKeyword);
3486
+ if (!hasExtends)
3487
+ return [];
3488
+ const symbol = checker.getSymbolAtLocation(node.name ?? node);
3489
+ if (!symbol)
3490
+ return [];
3491
+ const staticType = checker.getTypeOfSymbolAtLocation(symbol, node);
3492
+ const ctorSigs = staticType.getConstructSignatures().filter((sig) => {
3493
+ const decl = sig.getDeclaration();
3494
+ return decl !== undefined && ts7.isConstructorDeclaration(decl);
3495
+ });
3496
+ return ctorSigs.map((sig, index) => {
3497
+ const decl = sig.getDeclaration();
3498
+ const owner = ts7.isClassLike(decl.parent) ? decl.parent.name?.text : undefined;
3499
+ return {
3500
+ ...serializeConstructorSignature(decl, sig, ctx),
3501
+ ...owner ? { inheritedFrom: owner } : {},
3502
+ ...ctorSigs.length > 1 ? { overloadIndex: index } : {}
3503
+ };
3504
+ });
3505
+ }
3410
3506
  function serializeAccessor(node, ctx) {
3411
3507
  const { typeChecker: checker } = ctx;
3412
3508
  const name = getMemberName(node);
@@ -3824,6 +3920,9 @@ function serializeTypeAlias(node, ctx) {
3824
3920
  let members;
3825
3921
  if (ts10.isIntersectionTypeNode(node.type)) {
3826
3922
  schema = buildIntersectionSchemaFromNode(node.type, ctx);
3923
+ if (type.getProperties().length > 0 && type.getCallSignatures().length === 0) {
3924
+ members = serializeResolvedMembers(type, node, ctx);
3925
+ }
3827
3926
  } else if (isInlineFunctionAlias(node.type) && type.getCallSignatures().length > 0) {
3828
3927
  schema = buildFunctionSchema(type.getCallSignatures(), ctx.typeChecker, ctx);
3829
3928
  } else if ((ts10.isMappedTypeNode(node.type) || ts10.isConditionalTypeNode(node.type)) && type.getProperties().length > 0 && type.getCallSignatures().length === 0) {
@@ -3902,7 +4001,8 @@ function serializeResolvedMembers(type, node, ctx) {
3902
4001
  const propType = checker.getTypeOfSymbolAtLocation(prop, decl);
3903
4002
  registerReferencedTypes(propType, ctx);
3904
4003
  const callSigs = propType.getCallSignatures();
3905
- const kind = callSigs.length > 0 ? "method" : "property";
4004
+ const isMethodDecl = ts10.isMethodSignature(decl) || ts10.isMethodDeclaration(decl) || ts10.isFunctionDeclaration(decl);
4005
+ const kind = callSigs.length > 0 && isMethodDecl ? "method" : "property";
3906
4006
  let { description, tags } = getJSDocComment(decl, prop, checker);
3907
4007
  let { deprecated, reason: deprecationReason } = isSymbolDeprecated(prop);
3908
4008
  const arm = armDocs.get(prop.getName());
@@ -4150,6 +4250,19 @@ function normalizeSchema(schema, options = {}) {
4150
4250
  return normalized;
4151
4251
  }
4152
4252
  function normalizeSchemaInternal(schema, options) {
4253
+ const result = normalizeSchemaDispatch(schema, options);
4254
+ if (schema && typeof schema === "object") {
4255
+ const s = schema;
4256
+ if (s.deprecated === true && result.deprecated === undefined) {
4257
+ result.deprecated = true;
4258
+ }
4259
+ if (typeof s["x-deprecated-reason"] === "string" && result["x-deprecated-reason"] === undefined) {
4260
+ result["x-deprecated-reason"] = s["x-deprecated-reason"];
4261
+ }
4262
+ }
4263
+ return result;
4264
+ }
4265
+ function normalizeSchemaDispatch(schema, options) {
4153
4266
  if (typeof schema === "string") {
4154
4267
  return normalizeStringType(schema);
4155
4268
  }
@@ -4338,7 +4451,7 @@ function normalizeStandardType(schema, options) {
4338
4451
  }
4339
4452
  }
4340
4453
  for (const key of Object.keys(schema)) {
4341
- if (key.startsWith("x-ts-") && schema[key] !== undefined) {
4454
+ if (key.startsWith("x-") && schema[key] !== undefined) {
4342
4455
  const value = schema[key];
4343
4456
  if (isSchemaLike(value)) {
4344
4457
  result[key] = normalizeSchemaInternal(value, options);
@@ -4364,9 +4477,25 @@ function normalizeRef(schema, options) {
4364
4477
  return result;
4365
4478
  }
4366
4479
  function normalizeCombinator(keyword, schemas, originalSchema, options) {
4367
- const result = {
4368
- [keyword]: schemas.map((s) => normalizeSchemaInternal(s, options))
4369
- };
4480
+ let branches = schemas.map((s) => normalizeSchemaInternal(s, options));
4481
+ if (keyword !== "allOf") {
4482
+ const seen = new Set;
4483
+ branches = branches.filter((b) => {
4484
+ const key = JSON.stringify(b);
4485
+ if (seen.has(key))
4486
+ return false;
4487
+ seen.add(key);
4488
+ return true;
4489
+ });
4490
+ if (branches.length === 1) {
4491
+ const single = { ...branches[0] };
4492
+ if ("description" in originalSchema && originalSchema.description && !single.description) {
4493
+ single.description = originalSchema.description;
4494
+ }
4495
+ return single;
4496
+ }
4497
+ }
4498
+ const result = { [keyword]: branches };
4370
4499
  if ((keyword === "anyOf" || keyword === "oneOf") && "discriminator" in originalSchema && originalSchema.discriminator) {
4371
4500
  result.discriminator = originalSchema.discriminator;
4372
4501
  }
@@ -4503,8 +4632,22 @@ function normalizeMembers(members, options = {}) {
4503
4632
  }
4504
4633
  return result;
4505
4634
  }
4635
+ function memberDocExtras(member) {
4636
+ const extras = {};
4637
+ if (member.description) {
4638
+ extras.description = member.description;
4639
+ }
4640
+ if (member.deprecated) {
4641
+ extras.deprecated = true;
4642
+ const reason = member.deprecationReason ?? member.tags?.find((t) => t.name === "deprecated")?.text;
4643
+ if (reason?.trim()) {
4644
+ extras["x-deprecated-reason"] = reason;
4645
+ }
4646
+ }
4647
+ return extras;
4648
+ }
4506
4649
  function normalizeMemberToSchema(member, options) {
4507
- const { kind, schema, signatures, description } = member;
4650
+ const { kind, schema, signatures } = member;
4508
4651
  if (kind === "method" || kind === "call-signature") {
4509
4652
  return normalizeMethodMember(member, options);
4510
4653
  }
@@ -4513,7 +4656,7 @@ function normalizeMemberToSchema(member, options) {
4513
4656
  return {
4514
4657
  ...baseSchema2,
4515
4658
  "x-ts-accessor": "getter",
4516
- ...description ? { description } : {}
4659
+ ...memberDocExtras(member)
4517
4660
  };
4518
4661
  }
4519
4662
  if (kind === "setter") {
@@ -4521,7 +4664,7 @@ function normalizeMemberToSchema(member, options) {
4521
4664
  return {
4522
4665
  ...baseSchema2,
4523
4666
  "x-ts-accessor": "setter",
4524
- ...description ? { description } : {}
4667
+ ...memberDocExtras(member)
4525
4668
  };
4526
4669
  }
4527
4670
  if (kind === "index" || kind === "index-signature") {
@@ -4534,7 +4677,8 @@ function normalizeMemberToSchema(member, options) {
4534
4677
  return normalizeMethodMember(member, options);
4535
4678
  }
4536
4679
  const baseSchema = schema ? normalizeSchemaInternal(schema, options) : {};
4537
- return description ? { ...baseSchema, description } : baseSchema;
4680
+ const extras = memberDocExtras(member);
4681
+ return Object.keys(extras).length > 0 ? { ...baseSchema, ...extras } : baseSchema;
4538
4682
  }
4539
4683
  function normalizeMethodMember(member, options) {
4540
4684
  const result = {
@@ -4543,9 +4687,7 @@ function normalizeMethodMember(member, options) {
4543
4687
  if (member.signatures && member.signatures.length > 0) {
4544
4688
  result["x-ts-signatures"] = member.signatures.map((sig) => normalizeSignature(sig, options));
4545
4689
  }
4546
- if (member.description) {
4547
- result.description = member.description;
4548
- }
4690
+ Object.assign(result, memberDocExtras(member));
4549
4691
  return result;
4550
4692
  }
4551
4693
  function isOptionalMember(member) {
@@ -4789,6 +4931,12 @@ async function listExports(options) {
4789
4931
  };
4790
4932
  }
4791
4933
  const exportedSymbols = checker.getExportsOfModule(moduleSymbol);
4934
+ if (exportedSymbols.length === 0) {
4935
+ return {
4936
+ exports: [],
4937
+ errors: [`No exports found in ${entryFile}. Is this the right entry point?`]
4938
+ };
4939
+ }
4792
4940
  for (const symbol of exportedSymbols) {
4793
4941
  try {
4794
4942
  const exportItem = extractExportItem(symbol, checker, entryFile, sourceFile);
@@ -4862,10 +5010,10 @@ function getDescriptionPreview(symbol, checker) {
4862
5010
  return `${firstLine.slice(0, 77)}...`;
4863
5011
  }
4864
5012
  // src/builder/spec-builder.ts
4865
- import * as fs6 from "node:fs";
4866
- import * as path8 from "node:path";
5013
+ import * as fs7 from "node:fs";
5014
+ import * as path9 from "node:path";
4867
5015
  import { SCHEMA_URL, SCHEMA_VERSION } from "@openpkg-ts/spec";
4868
- import ts16 from "typescript";
5016
+ import ts17 from "typescript";
4869
5017
 
4870
5018
  // src/ast/resolve.ts
4871
5019
  import ts13 from "typescript";
@@ -5735,8 +5883,268 @@ function hasInternalTag(typeName, program, sourceFile) {
5735
5883
  });
5736
5884
  }
5737
5885
 
5738
- // src/builder/verification.ts
5886
+ // src/builder/type-expansion.ts
5887
+ import * as fs6 from "node:fs";
5739
5888
  import * as path7 from "node:path";
5889
+ import ts16 from "typescript";
5890
+ function findPackageDir(fromFile) {
5891
+ let dir = path7.dirname(path7.resolve(fromFile));
5892
+ while (true) {
5893
+ if (fs6.existsSync(path7.join(dir, "package.json")))
5894
+ return dir;
5895
+ const parent = path7.dirname(dir);
5896
+ if (parent === dir)
5897
+ return;
5898
+ dir = parent;
5899
+ }
5900
+ }
5901
+ var NODE_MODULES_PKG = /node_modules\/(@[^/]+\/[^/]+|[^/]+)/;
5902
+ function isLibFile(fileName) {
5903
+ return fileName.includes("/typescript/lib/lib.") || fileName.includes("\\typescript\\lib\\lib.");
5904
+ }
5905
+ function expandReachableTypes(exportedSymbols, ctx, opts) {
5906
+ if (opts.followExternal === false)
5907
+ return;
5908
+ const checker = ctx.typeChecker;
5909
+ const visited = new Set;
5910
+ const MAX_DEPTH = 30;
5911
+ const packageAllowed = (pkg) => {
5912
+ if (pkg === "typescript")
5913
+ return false;
5914
+ if (opts.followExternal === true)
5915
+ return true;
5916
+ if (Array.isArray(opts.followExternal) && opts.followExternal.includes(pkg))
5917
+ return true;
5918
+ return opts.workspacePackages.has(pkg);
5919
+ };
5920
+ const entryPackageDir = findPackageDir(opts.entryFile);
5921
+ const packageLabel = (fileName) => {
5922
+ const match = fileName.match(NODE_MODULES_PKG);
5923
+ let pkg = match?.[1];
5924
+ if (!pkg) {
5925
+ for (const [name, dir] of opts.workspacePackages) {
5926
+ if (fileName.startsWith(`${path7.resolve(dir)}${path7.sep}`)) {
5927
+ pkg = name;
5928
+ break;
5929
+ }
5930
+ }
5931
+ }
5932
+ return (pkg ?? "local").replace(/^@/, "").replace(/\//g, "-");
5933
+ };
5934
+ const symbolAllowed = (symbol) => {
5935
+ const decl = symbol.declarations?.[0];
5936
+ if (!decl)
5937
+ return false;
5938
+ const fileName = decl.getSourceFile().fileName;
5939
+ if (isLibFile(fileName))
5940
+ return false;
5941
+ const match = fileName.match(NODE_MODULES_PKG);
5942
+ if (match)
5943
+ return packageAllowed(match[1]);
5944
+ return true;
5945
+ };
5946
+ const visit = (type, depth) => {
5947
+ if (!type || depth > MAX_DEPTH || visited.has(type))
5948
+ return;
5949
+ visited.add(type);
5950
+ const symbol = type.aliasSymbol ?? type.getSymbol();
5951
+ const named = !!symbol && !symbol.getName().startsWith("__");
5952
+ const allowed = !named || !symbol || symbolAllowed(symbol);
5953
+ if (named && allowed && symbol && !ctx.exportedIds.has(symbol.getName())) {
5954
+ ctx.typeRegistry.registerType(type, ctx);
5955
+ const name = symbol.getName();
5956
+ if (!symbolByName.has(name)) {
5957
+ symbolByName.set(name, symbol);
5958
+ }
5959
+ }
5960
+ for (const arg of type.aliasTypeArguments ?? []) {
5961
+ visit(arg, depth + 1);
5962
+ }
5963
+ const typeRef = type;
5964
+ if (typeRef.target) {
5965
+ for (const arg of checker.getTypeArguments(typeRef) ?? []) {
5966
+ visit(arg, depth + 1);
5967
+ }
5968
+ }
5969
+ if (type.isUnion() || type.isIntersection()) {
5970
+ for (const t of type.types) {
5971
+ visit(t, depth + 1);
5972
+ }
5973
+ }
5974
+ if (!allowed || !(type.flags & ts16.TypeFlags.Object || type.isClassOrInterface())) {
5975
+ return;
5976
+ }
5977
+ if (type.isClassOrInterface()) {
5978
+ for (const base of checker.getBaseTypes(type) ?? []) {
5979
+ visit(base, depth + 1);
5980
+ }
5981
+ }
5982
+ for (const prop of type.getProperties().slice(0, ctx.maxProperties)) {
5983
+ if (prop.getName().startsWith("__@"))
5984
+ continue;
5985
+ visit(checker.getTypeOfSymbol(prop), depth + 1);
5986
+ }
5987
+ for (const sig of [...type.getCallSignatures(), ...type.getConstructSignatures()]) {
5988
+ for (const param of sig.getParameters()) {
5989
+ visit(checker.getTypeOfSymbol(param), depth + 1);
5990
+ }
5991
+ visit(sig.getReturnType(), depth + 1);
5992
+ }
5993
+ for (const info of checker.getIndexInfosOfType(type)) {
5994
+ visit(info.type, depth + 1);
5995
+ }
5996
+ };
5997
+ const TYPE_SYMBOL_FLAGS = ts16.SymbolFlags.Interface | ts16.SymbolFlags.TypeAlias | ts16.SymbolFlags.Class | ts16.SymbolFlags.RegularEnum | ts16.SymbolFlags.ConstEnum;
5998
+ const visitedSymbols = new Set;
5999
+ const symbolKind = (symbol) => {
6000
+ if (symbol.flags & ts16.SymbolFlags.Interface)
6001
+ return "interface";
6002
+ if (symbol.flags & ts16.SymbolFlags.Class)
6003
+ return "class";
6004
+ if (symbol.flags & (ts16.SymbolFlags.RegularEnum | ts16.SymbolFlags.ConstEnum))
6005
+ return "enum";
6006
+ return "type";
6007
+ };
6008
+ const resolveAlias = (symbol) => {
6009
+ if (symbol.flags & ts16.SymbolFlags.Alias) {
6010
+ try {
6011
+ return checker.getAliasedSymbol(symbol);
6012
+ } catch {
6013
+ return;
6014
+ }
6015
+ }
6016
+ return symbol;
6017
+ };
6018
+ const symbolByName = new Map;
6019
+ const registerTypeSymbol = (symbol) => {
6020
+ const name = symbol.getName();
6021
+ if (name.startsWith("__"))
6022
+ return;
6023
+ if (!(symbol.flags & TYPE_SYMBOL_FLAGS))
6024
+ return;
6025
+ if (!symbolAllowed(symbol))
6026
+ return;
6027
+ if (ctx.exportedIds.has(name)) {
6028
+ walkDeclarations(symbol);
6029
+ return;
6030
+ }
6031
+ if (ctx.typeRegistry.has(name)) {
6032
+ const prior = symbolByName.get(name);
6033
+ if (prior !== symbol) {
6034
+ const declFile = symbol.declarations?.[0]?.getSourceFile().fileName ?? "";
6035
+ const foreign = !!entryPackageDir && !declFile.startsWith(`${entryPackageDir}${path7.sep}`);
6036
+ if (prior !== undefined || foreign) {
6037
+ const scopedId = `${packageLabel(declFile)}.${name}`;
6038
+ if (!ctx.typeRegistry.has(scopedId)) {
6039
+ const declared2 = checker.getDeclaredTypeOfSymbol(symbol);
6040
+ const schema = ensureNonEmptySchema(buildSchema(declared2, checker, ctx), declared2, checker);
6041
+ const selfRef = JSON.stringify(schema) === JSON.stringify({ $ref: `#/types/${name}` });
6042
+ if (!selfRef && JSON.stringify(ctx.typeRegistry.get(name)?.schema) !== JSON.stringify(schema)) {
6043
+ ctx.typeRegistry.add({
6044
+ id: scopedId,
6045
+ name,
6046
+ kind: symbolKind(symbol),
6047
+ schema
6048
+ });
6049
+ visit(declared2, 0);
6050
+ }
6051
+ }
6052
+ }
6053
+ }
6054
+ walkDeclarations(symbol);
6055
+ return;
6056
+ }
6057
+ const declared = checker.getDeclaredTypeOfSymbol(symbol);
6058
+ ctx.typeRegistry.registerType(declared, ctx);
6059
+ if (!ctx.typeRegistry.has(name)) {
6060
+ ctx.typeRegistry.add({
6061
+ id: name,
6062
+ name,
6063
+ kind: symbolKind(symbol),
6064
+ schema: ensureNonEmptySchema(buildSchema(declared, checker, ctx), declared, checker)
6065
+ });
6066
+ }
6067
+ symbolByName.set(name, symbol);
6068
+ visit(declared, 0);
6069
+ walkDeclarations(symbol);
6070
+ };
6071
+ const handleRef = (nameNode) => {
6072
+ const symbol = checker.getSymbolAtLocation(nameNode);
6073
+ const target = symbol && resolveAlias(symbol);
6074
+ if (target)
6075
+ registerTypeSymbol(target);
6076
+ };
6077
+ const handleNamespaceRef = (nameNode) => {
6078
+ const symbol = checker.getSymbolAtLocation(nameNode);
6079
+ const target = symbol && resolveAlias(symbol);
6080
+ if (!target || visitedSymbols.has(target))
6081
+ return;
6082
+ if (!(target.flags & (ts16.SymbolFlags.ValueModule | ts16.SymbolFlags.NamespaceModule)))
6083
+ return;
6084
+ if (!symbolAllowed(target))
6085
+ return;
6086
+ visitedSymbols.add(target);
6087
+ for (const exp of checker.getExportsOfModule(target)) {
6088
+ const expTarget = resolveAlias(exp);
6089
+ if (!expTarget)
6090
+ continue;
6091
+ if (expTarget.flags & TYPE_SYMBOL_FLAGS) {
6092
+ registerTypeSymbol(expTarget);
6093
+ }
6094
+ }
6095
+ };
6096
+ const walkNode = (node) => {
6097
+ if (ts16.isTypeReferenceNode(node)) {
6098
+ handleRef(node.typeName);
6099
+ if (ts16.isQualifiedName(node.typeName)) {
6100
+ handleNamespaceRef(node.typeName.left);
6101
+ }
6102
+ } else if (ts16.isExpressionWithTypeArguments(node)) {
6103
+ handleRef(node.expression);
6104
+ } else if (ts16.isTypeQueryNode(node)) {
6105
+ handleRef(node.exprName);
6106
+ if (ts16.isQualifiedName(node.exprName)) {
6107
+ handleRef(node.exprName.left);
6108
+ handleNamespaceRef(node.exprName.left);
6109
+ }
6110
+ } else if (ts16.isImportTypeNode(node) && node.qualifier) {
6111
+ handleRef(node.qualifier);
6112
+ if (ts16.isQualifiedName(node.qualifier)) {
6113
+ handleNamespaceRef(node.qualifier.left);
6114
+ }
6115
+ }
6116
+ node.forEachChild(walkNode);
6117
+ };
6118
+ const walkDeclarations = (symbol) => {
6119
+ if (visitedSymbols.has(symbol))
6120
+ return;
6121
+ visitedSymbols.add(symbol);
6122
+ for (const decl of symbol.declarations ?? []) {
6123
+ walkNode(decl);
6124
+ }
6125
+ };
6126
+ for (const exportSymbol of exportedSymbols) {
6127
+ let target = exportSymbol;
6128
+ if (exportSymbol.flags & ts16.SymbolFlags.Alias) {
6129
+ try {
6130
+ target = checker.getAliasedSymbol(exportSymbol);
6131
+ } catch {
6132
+ continue;
6133
+ }
6134
+ }
6135
+ const decl = target.valueDeclaration ?? target.declarations?.[0];
6136
+ if (decl) {
6137
+ visit(checker.getTypeOfSymbolAtLocation(target, decl), 0);
6138
+ }
6139
+ if (target.flags & TYPE_SYMBOL_FLAGS) {
6140
+ visit(checker.getDeclaredTypeOfSymbol(target), 0);
6141
+ }
6142
+ walkDeclarations(target);
6143
+ }
6144
+ }
6145
+
6146
+ // src/builder/verification.ts
6147
+ import * as path8 from "node:path";
5740
6148
  var BUILTIN_TYPES2 = new Set([
5741
6149
  "Array",
5742
6150
  "ArrayBuffer",
@@ -5825,8 +6233,8 @@ function isExternalType2(definedIn, baseDir) {
5825
6233
  return true;
5826
6234
  if (definedIn.includes("node_modules"))
5827
6235
  return true;
5828
- const normalizedDefined = path7.resolve(definedIn);
5829
- const normalizedBase = path7.resolve(baseDir);
6236
+ const normalizedDefined = path8.resolve(definedIn);
6237
+ const normalizedBase = path8.resolve(baseDir);
5830
6238
  return !normalizedDefined.startsWith(normalizedBase);
5831
6239
  }
5832
6240
  function shouldSkipDanglingRef(name) {
@@ -6008,12 +6416,23 @@ async function extract(options) {
6008
6416
  diagnostics: [
6009
6417
  {
6010
6418
  message: `No exports found in ${entryFile}. Is this the right entry point?`,
6011
- severity: "warning"
6419
+ severity: "error"
6012
6420
  }
6013
6421
  ]
6014
6422
  };
6015
6423
  }
6016
6424
  const exportedSymbols = typeChecker.getExportsOfModule(moduleSymbol);
6425
+ if (exportedSymbols.length === 0) {
6426
+ return {
6427
+ spec: createEmptySpec(entryFile, includeSchema, isDtsSource),
6428
+ diagnostics: [
6429
+ {
6430
+ message: `No exports found in ${entryFile}. Is this the right entry point?`,
6431
+ severity: "error"
6432
+ }
6433
+ ]
6434
+ };
6435
+ }
6017
6436
  const exportedIds = new Set;
6018
6437
  for (const symbol of exportedSymbols) {
6019
6438
  exportedIds.add(symbol.getName());
@@ -6064,9 +6483,9 @@ async function extract(options) {
6064
6483
  break;
6065
6484
  }
6066
6485
  }
6067
- if (ts16.isExportSpecifier(decl)) {
6486
+ if (ts17.isExportSpecifier(decl)) {
6068
6487
  const exportDecl = decl.parent?.parent;
6069
- if (exportDecl && ts16.isExportDeclaration(exportDecl) && exportDecl.moduleSpecifier) {
6488
+ if (exportDecl && ts17.isExportDeclaration(exportDecl) && exportDecl.moduleSpecifier) {
6070
6489
  const moduleText = exportDecl.moduleSpecifier.getText().slice(1, -1);
6071
6490
  if (!moduleText.startsWith(".") && !moduleText.startsWith("/")) {
6072
6491
  externalPackage = moduleText;
@@ -6129,8 +6548,13 @@ async function extract(options) {
6129
6548
  }
6130
6549
  const verification = buildVerificationSummary(exportedSymbols.length, exports.length, exportTracker);
6131
6550
  const meta = await getPackageMeta(entryFile, baseDir);
6551
+ expandReachableTypes(filteredSymbols, ctx, {
6552
+ followExternal: options.followExternal,
6553
+ workspacePackages: result.workspacePackages ?? new Map,
6554
+ entryFile
6555
+ });
6132
6556
  {
6133
- const symFlags = ts16.SymbolFlags.Type | ts16.SymbolFlags.Interface | ts16.SymbolFlags.Class;
6557
+ const symFlags = ts17.SymbolFlags.Type | ts17.SymbolFlags.Interface | ts17.SymbolFlags.Class;
6134
6558
  const maxPasses = 5;
6135
6559
  for (let pass = 0;pass < maxPasses; pass++) {
6136
6560
  const allRefs = new Map;
@@ -6165,7 +6589,7 @@ async function extract(options) {
6165
6589
  }
6166
6590
  }
6167
6591
  const types = ctx.typeRegistry.getAll();
6168
- const projectBaseDir = baseDir ?? path8.dirname(entryFile);
6592
+ const projectBaseDir = baseDir ?? path9.dirname(entryFile);
6169
6593
  const definedTypes = new Set(types.map((t) => t.id));
6170
6594
  const forgottenExports = collectForgottenExports(exports, types, program, sourceFile, exportedIds, projectBaseDir, definedTypes);
6171
6595
  for (const forgotten of forgottenExports) {
@@ -6198,7 +6622,7 @@ async function extract(options) {
6198
6622
  }
6199
6623
  let runtimeMetadata;
6200
6624
  if (options.schemaExtraction === "hybrid") {
6201
- const projectBaseDir2 = baseDir || path8.dirname(entryFile);
6625
+ const projectBaseDir2 = baseDir || path9.dirname(entryFile);
6202
6626
  const runtimeResult = await extractStandardSchemasFromProject(entryFile, projectBaseDir2, {
6203
6627
  target: options.schemaTarget || "draft-2020-12",
6204
6628
  timeout: 15000
@@ -6277,21 +6701,21 @@ async function extract(options) {
6277
6701
  }
6278
6702
  function serializeDeclaration2(declaration, exportSymbol, exportName, ctx, isTypeOnly = false) {
6279
6703
  let result = null;
6280
- if (ts16.isFunctionDeclaration(declaration)) {
6704
+ if (ts17.isFunctionDeclaration(declaration)) {
6281
6705
  result = serializeFunctionExport(declaration, ctx);
6282
- } else if (ts16.isClassDeclaration(declaration)) {
6706
+ } else if (ts17.isClassDeclaration(declaration)) {
6283
6707
  result = serializeClass(declaration, ctx);
6284
- } else if (ts16.isInterfaceDeclaration(declaration)) {
6708
+ } else if (ts17.isInterfaceDeclaration(declaration)) {
6285
6709
  result = serializeInterface(declaration, ctx);
6286
- } else if (ts16.isTypeAliasDeclaration(declaration)) {
6710
+ } else if (ts17.isTypeAliasDeclaration(declaration)) {
6287
6711
  result = serializeTypeAlias(declaration, ctx);
6288
- } else if (ts16.isEnumDeclaration(declaration)) {
6712
+ } else if (ts17.isEnumDeclaration(declaration)) {
6289
6713
  result = serializeEnum(declaration, ctx);
6290
- } else if (ts16.isVariableDeclaration(declaration)) {
6714
+ } else if (ts17.isVariableDeclaration(declaration)) {
6291
6715
  const varStatement = declaration.parent?.parent;
6292
- if (varStatement && ts16.isVariableStatement(varStatement)) {
6293
- if (declaration.initializer && (ts16.isArrowFunction(declaration.initializer) || ts16.isFunctionExpression(declaration.initializer))) {
6294
- const varName = ts16.isIdentifier(declaration.name) ? declaration.name.text : declaration.name.getText();
6716
+ if (varStatement && ts17.isVariableStatement(varStatement)) {
6717
+ if (declaration.initializer && (ts17.isArrowFunction(declaration.initializer) || ts17.isFunctionExpression(declaration.initializer))) {
6718
+ const varName = ts17.isIdentifier(declaration.name) ? declaration.name.text : declaration.name.getText();
6295
6719
  result = serializeFunctionExport(declaration.initializer, ctx, varName);
6296
6720
  } else {
6297
6721
  result = serializeVariable(declaration, varStatement, ctx);
@@ -6303,7 +6727,7 @@ function serializeDeclaration2(declaration, exportSymbol, exportName, ctx, isTyp
6303
6727
  }
6304
6728
  }
6305
6729
  }
6306
- } else if (ts16.isNamespaceExport(declaration) || ts16.isModuleDeclaration(declaration) || ts16.isNamespaceImport(declaration) || ts16.isSourceFile(declaration)) {
6730
+ } else if (ts17.isNamespaceExport(declaration) || ts17.isModuleDeclaration(declaration) || ts17.isNamespaceImport(declaration) || ts17.isSourceFile(declaration)) {
6307
6731
  try {
6308
6732
  result = serializeNamespaceExport(exportSymbol, exportName, ctx);
6309
6733
  } catch {
@@ -6339,7 +6763,7 @@ function serializeNamespaceExport(symbol, exportName, ctx) {
6339
6763
  const members = [];
6340
6764
  const checker = ctx.program.getTypeChecker();
6341
6765
  let targetSymbol = symbol;
6342
- if (symbol.flags & ts16.SymbolFlags.Alias) {
6766
+ if (symbol.flags & ts17.SymbolFlags.Alias) {
6343
6767
  const aliased = checker.getAliasedSymbol(symbol);
6344
6768
  if (aliased && aliased !== symbol) {
6345
6769
  targetSymbol = aliased;
@@ -6366,31 +6790,31 @@ function serializeNamespaceExport(symbol, exportName, ctx) {
6366
6790
  function serializeNamespaceMember(symbol, memberName, ctx) {
6367
6791
  const checker = ctx.program.getTypeChecker();
6368
6792
  let targetSymbol = symbol;
6369
- if (symbol.flags & ts16.SymbolFlags.Alias) {
6793
+ if (symbol.flags & ts17.SymbolFlags.Alias) {
6370
6794
  const aliased = checker.getAliasedSymbol(symbol);
6371
6795
  if (aliased && aliased !== symbol) {
6372
6796
  targetSymbol = aliased;
6373
6797
  }
6374
6798
  }
6375
6799
  const declarations = targetSymbol.declarations ?? [];
6376
- const declaration = targetSymbol.valueDeclaration || declarations.find((d) => d.kind !== ts16.SyntaxKind.ExportSpecifier) || declarations[0];
6800
+ const declaration = targetSymbol.valueDeclaration || declarations.find((d) => d.kind !== ts17.SyntaxKind.ExportSpecifier) || declarations[0];
6377
6801
  if (!declaration)
6378
6802
  return null;
6379
6803
  const type = checker.getTypeAtLocation(declaration);
6380
6804
  const callSignatures = type.getCallSignatures();
6381
6805
  const { deprecated } = isSymbolDeprecated(targetSymbol);
6382
6806
  let kind = "variable";
6383
- if (ts16.isFunctionDeclaration(declaration) || ts16.isFunctionExpression(declaration)) {
6807
+ if (ts17.isFunctionDeclaration(declaration) || ts17.isFunctionExpression(declaration)) {
6384
6808
  kind = "function";
6385
- } else if (ts16.isClassDeclaration(declaration)) {
6809
+ } else if (ts17.isClassDeclaration(declaration)) {
6386
6810
  kind = "class";
6387
- } else if (ts16.isInterfaceDeclaration(declaration)) {
6811
+ } else if (ts17.isInterfaceDeclaration(declaration)) {
6388
6812
  kind = "interface";
6389
- } else if (ts16.isTypeAliasDeclaration(declaration)) {
6813
+ } else if (ts17.isTypeAliasDeclaration(declaration)) {
6390
6814
  kind = "type";
6391
- } else if (ts16.isEnumDeclaration(declaration)) {
6815
+ } else if (ts17.isEnumDeclaration(declaration)) {
6392
6816
  kind = "enum";
6393
- } else if (ts16.isVariableDeclaration(declaration)) {
6817
+ } else if (ts17.isVariableDeclaration(declaration)) {
6394
6818
  if (callSignatures.length > 0) {
6395
6819
  kind = "function";
6396
6820
  }
@@ -6421,11 +6845,11 @@ function getJSDocFromExportSymbol(symbol) {
6421
6845
  const examples = [];
6422
6846
  const decl = symbol.declarations?.[0];
6423
6847
  if (decl) {
6424
- const exportDecl = ts16.isNamespaceExport(decl) ? decl.parent : decl;
6425
- if (exportDecl && ts16.isExportDeclaration(exportDecl)) {
6426
- const jsDocs = ts16.getJSDocCommentsAndTags(exportDecl);
6848
+ const exportDecl = ts17.isNamespaceExport(decl) ? decl.parent : decl;
6849
+ if (exportDecl && ts17.isExportDeclaration(exportDecl)) {
6850
+ const jsDocs = ts17.getJSDocCommentsAndTags(exportDecl);
6427
6851
  for (const doc of jsDocs) {
6428
- if (ts16.isJSDoc(doc) && doc.comment) {
6852
+ if (ts17.isJSDoc(doc) && doc.comment) {
6429
6853
  const commentText = typeof doc.comment === "string" ? doc.comment : doc.comment.map((c) => ("text" in c) ? c.text : "").join("");
6430
6854
  if (commentText) {
6431
6855
  return {
@@ -6487,7 +6911,7 @@ function createEmptySpec(entryFile, includeSchema, isDtsSource) {
6487
6911
  return {
6488
6912
  ...includeSchema ? { $schema: SCHEMA_URL } : {},
6489
6913
  openpkg: SCHEMA_VERSION,
6490
- meta: { name: path8.basename(entryFile, path8.extname(entryFile)) },
6914
+ meta: { name: path9.basename(entryFile, path9.extname(entryFile)) },
6491
6915
  exports: [],
6492
6916
  generation: {
6493
6917
  generator: "@openpkg-ts/sdk",
@@ -6503,7 +6927,7 @@ function findTypeInProgram(name, checker, program, sourceFile, symFlags) {
6503
6927
  const localSym = checker.resolveName(name, sourceFile, symFlags, false);
6504
6928
  if (localSym)
6505
6929
  return checker.getDeclaredTypeOfSymbol(localSym);
6506
- const entryDir = path8.dirname(sourceFile.fileName);
6930
+ const entryDir = path9.dirname(sourceFile.fileName);
6507
6931
  for (const sf of program.getSourceFiles()) {
6508
6932
  const fn = sf.fileName;
6509
6933
  if (fn.includes("/typescript/lib/lib.") || fn.includes("\\typescript\\lib\\lib."))
@@ -6519,33 +6943,33 @@ function findTypeInProgram(name, checker, program, sourceFile, symFlags) {
6519
6943
  return;
6520
6944
  }
6521
6945
  async function getPackageMeta(entryFile, baseDir) {
6522
- let dir = baseDir ?? path8.dirname(entryFile);
6523
- while (dir !== path8.dirname(dir)) {
6524
- const pkgPath = path8.join(dir, "package.json");
6946
+ let dir = baseDir ?? path9.dirname(entryFile);
6947
+ while (dir !== path9.dirname(dir)) {
6948
+ const pkgPath = path9.join(dir, "package.json");
6525
6949
  try {
6526
- if (fs6.existsSync(pkgPath)) {
6527
- const pkg = JSON.parse(fs6.readFileSync(pkgPath, "utf-8"));
6950
+ if (fs7.existsSync(pkgPath)) {
6951
+ const pkg = JSON.parse(fs7.readFileSync(pkgPath, "utf-8"));
6528
6952
  return {
6529
- name: pkg.name ?? path8.basename(dir),
6953
+ name: pkg.name ?? path9.basename(dir),
6530
6954
  version: pkg.version,
6531
6955
  description: pkg.description
6532
6956
  };
6533
6957
  }
6534
6958
  } catch {}
6535
- dir = path8.dirname(dir);
6959
+ dir = path9.dirname(dir);
6536
6960
  }
6537
- return { name: path8.basename(baseDir ?? path8.dirname(entryFile)) };
6961
+ return { name: path9.basename(baseDir ?? path9.dirname(entryFile)) };
6538
6962
  }
6539
6963
 
6540
6964
  // src/primitives/spec.ts
6541
6965
  var extractSpec = extract;
6542
6966
  // src/types/utils.ts
6543
- import ts17 from "typescript";
6967
+ import ts18 from "typescript";
6544
6968
  function isExported(node) {
6545
6969
  const modifiers = node.modifiers;
6546
6970
  if (!modifiers)
6547
6971
  return false;
6548
- return modifiers.some((m) => m.kind === ts17.SyntaxKind.ExportKeyword);
6972
+ return modifiers.some((m) => m.kind === ts18.SyntaxKind.ExportKeyword);
6549
6973
  }
6550
6974
  function getNodeName(node) {
6551
6975
  if ("name" in node && node.name) {
@@ -6557,6 +6981,7 @@ function getNodeName(node) {
6557
6981
  export {
6558
6982
  zodAdapter,
6559
6983
  withDescription,
6984
+ withDeprecated,
6560
6985
  valibotAdapter,
6561
6986
  typeboxAdapter,
6562
6987
  toSearchIndexJSON,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openpkg-ts/sdk",
3
- "version": "0.42.0",
3
+ "version": "0.44.0",
4
4
  "description": "TypeScript API extraction SDK - programmatic primitives for OpenPkg specs",
5
5
  "keywords": [
6
6
  "openpkg",
@@ -43,7 +43,7 @@
43
43
  "test": "bun test"
44
44
  },
45
45
  "dependencies": {
46
- "@openpkg-ts/spec": "^0.41.0",
46
+ "@openpkg-ts/spec": "^0.44.0",
47
47
  "picomatch": "4.0.3",
48
48
  "typescript": "^5.0.0"
49
49
  },