@openpkg-ts/sdk 0.41.0 → 0.43.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
@@ -33,8 +33,15 @@ interface ExtractOptions {
33
33
  includePrivate?: boolean;
34
34
  /** Configuration for resolving external package re-exports */
35
35
  externals?: ExternalsConfig;
36
- /** Max properties to serialize per object type (default: 20) */
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
  }
@@ -1171,7 +1178,7 @@ interface SerializerContext {
1171
1178
  inTupleElement?: boolean;
1172
1179
  /** Include private/protected class members (default: false) */
1173
1180
  includePrivate?: boolean;
1174
- /** Max properties to serialize per object type (default: 20) */
1181
+ /** Max properties to serialize per object type (default: 500) */
1175
1182
  maxProperties: number;
1176
1183
  /** Callback when properties are truncated */
1177
1184
  onTruncation?: (typeName: string, actual: number, limit: number) => void;
@@ -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
 
@@ -2453,13 +2463,26 @@ function buildObjectSchema(properties, checker, ctx, originalType) {
2453
2463
  const required = [];
2454
2464
  for (const prop of properties) {
2455
2465
  const propName = prop.getName();
2456
- if (propName.startsWith("_"))
2466
+ if (propName.startsWith("__@"))
2457
2467
  continue;
2458
2468
  if (isArrayLikeType && ARRAY_PROTOTYPE_METHODS.has(propName)) {
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);
@@ -2995,26 +3047,43 @@ class TypeRegistry {
2995
3047
  const props = {};
2996
3048
  const required = [];
2997
3049
  const limit = ctx.maxProperties;
2998
- if (properties.length > limit && ctx.onTruncation) {
2999
- const typeName = type.getSymbol()?.getName() ?? "anonymous";
3000
- ctx.onTruncation(typeName, properties.length, limit);
3001
- }
3002
3050
  const isArrayLike = checker.isArrayType(type) || checker.isTupleType(type) || type.symbol?.getName() === "Array" && type.symbol?.getDeclarations()?.[0]?.getSourceFile()?.fileName?.includes("/typescript/lib/lib.");
3003
3051
  const isStringLike = type.flags & ts5.TypeFlags.StringLike;
3004
3052
  const isNumberLike = type.flags & ts5.TypeFlags.NumberLike;
3005
- for (const prop of properties.slice(0, limit)) {
3053
+ const included = properties.filter((prop) => {
3006
3054
  const propName = prop.getName();
3007
- if (propName.startsWith("_"))
3008
- continue;
3055
+ if (propName.startsWith("__@"))
3056
+ return false;
3009
3057
  if (isArrayLike && ARRAY_PROTOTYPE_METHODS.has(propName))
3010
- continue;
3058
+ return false;
3011
3059
  if (isStringLike && STRING_PROTOTYPE_METHODS.has(propName))
3012
- continue;
3060
+ return false;
3013
3061
  if (isNumberLike && NUMBER_PROTOTYPE_METHODS.has(propName))
3014
- continue;
3062
+ return false;
3063
+ return true;
3064
+ });
3065
+ if (included.length > limit && ctx.onTruncation) {
3066
+ const typeName = type.getSymbol()?.getName() ?? "anonymous";
3067
+ ctx.onTruncation(typeName, included.length, limit);
3068
+ }
3069
+ for (const prop of included.slice(0, limit)) {
3070
+ const propName = prop.getName();
3015
3071
  const propType = checker.getTypeOfSymbol(prop);
3016
3072
  this.registerType(propType, ctx);
3017
- 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;
3018
3087
  if (!(prop.flags & ts5.SymbolFlags.Optional)) {
3019
3088
  required.push(propName);
3020
3089
  }
@@ -3043,7 +3112,7 @@ function createContext(program, sourceFile, options = {}) {
3043
3112
  visitedTypes: new Set,
3044
3113
  registeredTypes: new Set,
3045
3114
  includePrivate: options.includePrivate ?? false,
3046
- maxProperties: options.maxProperties ?? 100,
3115
+ maxProperties: options.maxProperties ?? 500,
3047
3116
  onTruncation: options.onTruncation
3048
3117
  };
3049
3118
  }
@@ -3820,6 +3889,9 @@ function serializeTypeAlias(node, ctx) {
3820
3889
  let members;
3821
3890
  if (ts10.isIntersectionTypeNode(node.type)) {
3822
3891
  schema = buildIntersectionSchemaFromNode(node.type, ctx);
3892
+ if (type.getProperties().length > 0 && type.getCallSignatures().length === 0) {
3893
+ members = serializeResolvedMembers(type, node, ctx);
3894
+ }
3823
3895
  } else if (isInlineFunctionAlias(node.type) && type.getCallSignatures().length > 0) {
3824
3896
  schema = buildFunctionSchema(type.getCallSignatures(), ctx.typeChecker, ctx);
3825
3897
  } else if ((ts10.isMappedTypeNode(node.type) || ts10.isConditionalTypeNode(node.type)) && type.getProperties().length > 0 && type.getCallSignatures().length === 0) {
@@ -3898,7 +3970,8 @@ function serializeResolvedMembers(type, node, ctx) {
3898
3970
  const propType = checker.getTypeOfSymbolAtLocation(prop, decl);
3899
3971
  registerReferencedTypes(propType, ctx);
3900
3972
  const callSigs = propType.getCallSignatures();
3901
- const kind = callSigs.length > 0 ? "method" : "property";
3973
+ const isMethodDecl = ts10.isMethodSignature(decl) || ts10.isMethodDeclaration(decl) || ts10.isFunctionDeclaration(decl);
3974
+ const kind = callSigs.length > 0 && isMethodDecl ? "method" : "property";
3902
3975
  let { description, tags } = getJSDocComment(decl, prop, checker);
3903
3976
  let { deprecated, reason: deprecationReason } = isSymbolDeprecated(prop);
3904
3977
  const arm = armDocs.get(prop.getName());
@@ -4146,6 +4219,19 @@ function normalizeSchema(schema, options = {}) {
4146
4219
  return normalized;
4147
4220
  }
4148
4221
  function normalizeSchemaInternal(schema, options) {
4222
+ const result = normalizeSchemaDispatch(schema, options);
4223
+ if (schema && typeof schema === "object") {
4224
+ const s = schema;
4225
+ if (s.deprecated === true && result.deprecated === undefined) {
4226
+ result.deprecated = true;
4227
+ }
4228
+ if (typeof s["x-deprecated-reason"] === "string" && result["x-deprecated-reason"] === undefined) {
4229
+ result["x-deprecated-reason"] = s["x-deprecated-reason"];
4230
+ }
4231
+ }
4232
+ return result;
4233
+ }
4234
+ function normalizeSchemaDispatch(schema, options) {
4149
4235
  if (typeof schema === "string") {
4150
4236
  return normalizeStringType(schema);
4151
4237
  }
@@ -4334,7 +4420,7 @@ function normalizeStandardType(schema, options) {
4334
4420
  }
4335
4421
  }
4336
4422
  for (const key of Object.keys(schema)) {
4337
- if (key.startsWith("x-ts-") && schema[key] !== undefined) {
4423
+ if (key.startsWith("x-") && schema[key] !== undefined) {
4338
4424
  const value = schema[key];
4339
4425
  if (isSchemaLike(value)) {
4340
4426
  result[key] = normalizeSchemaInternal(value, options);
@@ -4360,9 +4446,25 @@ function normalizeRef(schema, options) {
4360
4446
  return result;
4361
4447
  }
4362
4448
  function normalizeCombinator(keyword, schemas, originalSchema, options) {
4363
- const result = {
4364
- [keyword]: schemas.map((s) => normalizeSchemaInternal(s, options))
4365
- };
4449
+ let branches = schemas.map((s) => normalizeSchemaInternal(s, options));
4450
+ if (keyword !== "allOf") {
4451
+ const seen = new Set;
4452
+ branches = branches.filter((b) => {
4453
+ const key = JSON.stringify(b);
4454
+ if (seen.has(key))
4455
+ return false;
4456
+ seen.add(key);
4457
+ return true;
4458
+ });
4459
+ if (branches.length === 1) {
4460
+ const single = { ...branches[0] };
4461
+ if ("description" in originalSchema && originalSchema.description && !single.description) {
4462
+ single.description = originalSchema.description;
4463
+ }
4464
+ return single;
4465
+ }
4466
+ }
4467
+ const result = { [keyword]: branches };
4366
4468
  if ((keyword === "anyOf" || keyword === "oneOf") && "discriminator" in originalSchema && originalSchema.discriminator) {
4367
4469
  result.discriminator = originalSchema.discriminator;
4368
4470
  }
@@ -4499,8 +4601,22 @@ function normalizeMembers(members, options = {}) {
4499
4601
  }
4500
4602
  return result;
4501
4603
  }
4604
+ function memberDocExtras(member) {
4605
+ const extras = {};
4606
+ if (member.description) {
4607
+ extras.description = member.description;
4608
+ }
4609
+ if (member.deprecated) {
4610
+ extras.deprecated = true;
4611
+ const reason = member.deprecationReason ?? member.tags?.find((t) => t.name === "deprecated")?.text;
4612
+ if (reason?.trim()) {
4613
+ extras["x-deprecated-reason"] = reason;
4614
+ }
4615
+ }
4616
+ return extras;
4617
+ }
4502
4618
  function normalizeMemberToSchema(member, options) {
4503
- const { kind, schema, signatures, description } = member;
4619
+ const { kind, schema, signatures } = member;
4504
4620
  if (kind === "method" || kind === "call-signature") {
4505
4621
  return normalizeMethodMember(member, options);
4506
4622
  }
@@ -4509,7 +4625,7 @@ function normalizeMemberToSchema(member, options) {
4509
4625
  return {
4510
4626
  ...baseSchema2,
4511
4627
  "x-ts-accessor": "getter",
4512
- ...description ? { description } : {}
4628
+ ...memberDocExtras(member)
4513
4629
  };
4514
4630
  }
4515
4631
  if (kind === "setter") {
@@ -4517,7 +4633,7 @@ function normalizeMemberToSchema(member, options) {
4517
4633
  return {
4518
4634
  ...baseSchema2,
4519
4635
  "x-ts-accessor": "setter",
4520
- ...description ? { description } : {}
4636
+ ...memberDocExtras(member)
4521
4637
  };
4522
4638
  }
4523
4639
  if (kind === "index" || kind === "index-signature") {
@@ -4530,7 +4646,8 @@ function normalizeMemberToSchema(member, options) {
4530
4646
  return normalizeMethodMember(member, options);
4531
4647
  }
4532
4648
  const baseSchema = schema ? normalizeSchemaInternal(schema, options) : {};
4533
- return description ? { ...baseSchema, description } : baseSchema;
4649
+ const extras = memberDocExtras(member);
4650
+ return Object.keys(extras).length > 0 ? { ...baseSchema, ...extras } : baseSchema;
4534
4651
  }
4535
4652
  function normalizeMethodMember(member, options) {
4536
4653
  const result = {
@@ -4539,9 +4656,7 @@ function normalizeMethodMember(member, options) {
4539
4656
  if (member.signatures && member.signatures.length > 0) {
4540
4657
  result["x-ts-signatures"] = member.signatures.map((sig) => normalizeSignature(sig, options));
4541
4658
  }
4542
- if (member.description) {
4543
- result.description = member.description;
4544
- }
4659
+ Object.assign(result, memberDocExtras(member));
4545
4660
  return result;
4546
4661
  }
4547
4662
  function isOptionalMember(member) {
@@ -4785,6 +4900,12 @@ async function listExports(options) {
4785
4900
  };
4786
4901
  }
4787
4902
  const exportedSymbols = checker.getExportsOfModule(moduleSymbol);
4903
+ if (exportedSymbols.length === 0) {
4904
+ return {
4905
+ exports: [],
4906
+ errors: [`No exports found in ${entryFile}. Is this the right entry point?`]
4907
+ };
4908
+ }
4788
4909
  for (const symbol of exportedSymbols) {
4789
4910
  try {
4790
4911
  const exportItem = extractExportItem(symbol, checker, entryFile, sourceFile);
@@ -4858,10 +4979,10 @@ function getDescriptionPreview(symbol, checker) {
4858
4979
  return `${firstLine.slice(0, 77)}...`;
4859
4980
  }
4860
4981
  // src/builder/spec-builder.ts
4861
- import * as fs6 from "node:fs";
4862
- import * as path8 from "node:path";
4982
+ import * as fs7 from "node:fs";
4983
+ import * as path9 from "node:path";
4863
4984
  import { SCHEMA_URL, SCHEMA_VERSION } from "@openpkg-ts/spec";
4864
- import ts16 from "typescript";
4985
+ import ts17 from "typescript";
4865
4986
 
4866
4987
  // src/ast/resolve.ts
4867
4988
  import ts13 from "typescript";
@@ -5731,8 +5852,268 @@ function hasInternalTag(typeName, program, sourceFile) {
5731
5852
  });
5732
5853
  }
5733
5854
 
5734
- // src/builder/verification.ts
5855
+ // src/builder/type-expansion.ts
5856
+ import * as fs6 from "node:fs";
5735
5857
  import * as path7 from "node:path";
5858
+ import ts16 from "typescript";
5859
+ function findPackageDir(fromFile) {
5860
+ let dir = path7.dirname(path7.resolve(fromFile));
5861
+ while (true) {
5862
+ if (fs6.existsSync(path7.join(dir, "package.json")))
5863
+ return dir;
5864
+ const parent = path7.dirname(dir);
5865
+ if (parent === dir)
5866
+ return;
5867
+ dir = parent;
5868
+ }
5869
+ }
5870
+ var NODE_MODULES_PKG = /node_modules\/(@[^/]+\/[^/]+|[^/]+)/;
5871
+ function isLibFile(fileName) {
5872
+ return fileName.includes("/typescript/lib/lib.") || fileName.includes("\\typescript\\lib\\lib.");
5873
+ }
5874
+ function expandReachableTypes(exportedSymbols, ctx, opts) {
5875
+ if (opts.followExternal === false)
5876
+ return;
5877
+ const checker = ctx.typeChecker;
5878
+ const visited = new Set;
5879
+ const MAX_DEPTH = 30;
5880
+ const packageAllowed = (pkg) => {
5881
+ if (pkg === "typescript")
5882
+ return false;
5883
+ if (opts.followExternal === true)
5884
+ return true;
5885
+ if (Array.isArray(opts.followExternal) && opts.followExternal.includes(pkg))
5886
+ return true;
5887
+ return opts.workspacePackages.has(pkg);
5888
+ };
5889
+ const entryPackageDir = findPackageDir(opts.entryFile);
5890
+ const packageLabel = (fileName) => {
5891
+ const match = fileName.match(NODE_MODULES_PKG);
5892
+ let pkg = match?.[1];
5893
+ if (!pkg) {
5894
+ for (const [name, dir] of opts.workspacePackages) {
5895
+ if (fileName.startsWith(`${path7.resolve(dir)}${path7.sep}`)) {
5896
+ pkg = name;
5897
+ break;
5898
+ }
5899
+ }
5900
+ }
5901
+ return (pkg ?? "local").replace(/^@/, "").replace(/\//g, "-");
5902
+ };
5903
+ const symbolAllowed = (symbol) => {
5904
+ const decl = symbol.declarations?.[0];
5905
+ if (!decl)
5906
+ return false;
5907
+ const fileName = decl.getSourceFile().fileName;
5908
+ if (isLibFile(fileName))
5909
+ return false;
5910
+ const match = fileName.match(NODE_MODULES_PKG);
5911
+ if (match)
5912
+ return packageAllowed(match[1]);
5913
+ return true;
5914
+ };
5915
+ const visit = (type, depth) => {
5916
+ if (!type || depth > MAX_DEPTH || visited.has(type))
5917
+ return;
5918
+ visited.add(type);
5919
+ const symbol = type.aliasSymbol ?? type.getSymbol();
5920
+ const named = !!symbol && !symbol.getName().startsWith("__");
5921
+ const allowed = !named || !symbol || symbolAllowed(symbol);
5922
+ if (named && allowed && symbol && !ctx.exportedIds.has(symbol.getName())) {
5923
+ ctx.typeRegistry.registerType(type, ctx);
5924
+ const name = symbol.getName();
5925
+ if (!symbolByName.has(name)) {
5926
+ symbolByName.set(name, symbol);
5927
+ }
5928
+ }
5929
+ for (const arg of type.aliasTypeArguments ?? []) {
5930
+ visit(arg, depth + 1);
5931
+ }
5932
+ const typeRef = type;
5933
+ if (typeRef.target) {
5934
+ for (const arg of checker.getTypeArguments(typeRef) ?? []) {
5935
+ visit(arg, depth + 1);
5936
+ }
5937
+ }
5938
+ if (type.isUnion() || type.isIntersection()) {
5939
+ for (const t of type.types) {
5940
+ visit(t, depth + 1);
5941
+ }
5942
+ }
5943
+ if (!allowed || !(type.flags & ts16.TypeFlags.Object || type.isClassOrInterface())) {
5944
+ return;
5945
+ }
5946
+ if (type.isClassOrInterface()) {
5947
+ for (const base of checker.getBaseTypes(type) ?? []) {
5948
+ visit(base, depth + 1);
5949
+ }
5950
+ }
5951
+ for (const prop of type.getProperties().slice(0, ctx.maxProperties)) {
5952
+ if (prop.getName().startsWith("__@"))
5953
+ continue;
5954
+ visit(checker.getTypeOfSymbol(prop), depth + 1);
5955
+ }
5956
+ for (const sig of [...type.getCallSignatures(), ...type.getConstructSignatures()]) {
5957
+ for (const param of sig.getParameters()) {
5958
+ visit(checker.getTypeOfSymbol(param), depth + 1);
5959
+ }
5960
+ visit(sig.getReturnType(), depth + 1);
5961
+ }
5962
+ for (const info of checker.getIndexInfosOfType(type)) {
5963
+ visit(info.type, depth + 1);
5964
+ }
5965
+ };
5966
+ const TYPE_SYMBOL_FLAGS = ts16.SymbolFlags.Interface | ts16.SymbolFlags.TypeAlias | ts16.SymbolFlags.Class | ts16.SymbolFlags.RegularEnum | ts16.SymbolFlags.ConstEnum;
5967
+ const visitedSymbols = new Set;
5968
+ const symbolKind = (symbol) => {
5969
+ if (symbol.flags & ts16.SymbolFlags.Interface)
5970
+ return "interface";
5971
+ if (symbol.flags & ts16.SymbolFlags.Class)
5972
+ return "class";
5973
+ if (symbol.flags & (ts16.SymbolFlags.RegularEnum | ts16.SymbolFlags.ConstEnum))
5974
+ return "enum";
5975
+ return "type";
5976
+ };
5977
+ const resolveAlias = (symbol) => {
5978
+ if (symbol.flags & ts16.SymbolFlags.Alias) {
5979
+ try {
5980
+ return checker.getAliasedSymbol(symbol);
5981
+ } catch {
5982
+ return;
5983
+ }
5984
+ }
5985
+ return symbol;
5986
+ };
5987
+ const symbolByName = new Map;
5988
+ const registerTypeSymbol = (symbol) => {
5989
+ const name = symbol.getName();
5990
+ if (name.startsWith("__"))
5991
+ return;
5992
+ if (!(symbol.flags & TYPE_SYMBOL_FLAGS))
5993
+ return;
5994
+ if (!symbolAllowed(symbol))
5995
+ return;
5996
+ if (ctx.exportedIds.has(name)) {
5997
+ walkDeclarations(symbol);
5998
+ return;
5999
+ }
6000
+ if (ctx.typeRegistry.has(name)) {
6001
+ const prior = symbolByName.get(name);
6002
+ if (prior !== symbol) {
6003
+ const declFile = symbol.declarations?.[0]?.getSourceFile().fileName ?? "";
6004
+ const foreign = !!entryPackageDir && !declFile.startsWith(`${entryPackageDir}${path7.sep}`);
6005
+ if (prior !== undefined || foreign) {
6006
+ const scopedId = `${packageLabel(declFile)}.${name}`;
6007
+ if (!ctx.typeRegistry.has(scopedId)) {
6008
+ const declared2 = checker.getDeclaredTypeOfSymbol(symbol);
6009
+ const schema = ensureNonEmptySchema(buildSchema(declared2, checker, ctx), declared2, checker);
6010
+ const selfRef = JSON.stringify(schema) === JSON.stringify({ $ref: `#/types/${name}` });
6011
+ if (!selfRef && JSON.stringify(ctx.typeRegistry.get(name)?.schema) !== JSON.stringify(schema)) {
6012
+ ctx.typeRegistry.add({
6013
+ id: scopedId,
6014
+ name,
6015
+ kind: symbolKind(symbol),
6016
+ schema
6017
+ });
6018
+ visit(declared2, 0);
6019
+ }
6020
+ }
6021
+ }
6022
+ }
6023
+ walkDeclarations(symbol);
6024
+ return;
6025
+ }
6026
+ const declared = checker.getDeclaredTypeOfSymbol(symbol);
6027
+ ctx.typeRegistry.registerType(declared, ctx);
6028
+ if (!ctx.typeRegistry.has(name)) {
6029
+ ctx.typeRegistry.add({
6030
+ id: name,
6031
+ name,
6032
+ kind: symbolKind(symbol),
6033
+ schema: ensureNonEmptySchema(buildSchema(declared, checker, ctx), declared, checker)
6034
+ });
6035
+ }
6036
+ symbolByName.set(name, symbol);
6037
+ visit(declared, 0);
6038
+ walkDeclarations(symbol);
6039
+ };
6040
+ const handleRef = (nameNode) => {
6041
+ const symbol = checker.getSymbolAtLocation(nameNode);
6042
+ const target = symbol && resolveAlias(symbol);
6043
+ if (target)
6044
+ registerTypeSymbol(target);
6045
+ };
6046
+ const handleNamespaceRef = (nameNode) => {
6047
+ const symbol = checker.getSymbolAtLocation(nameNode);
6048
+ const target = symbol && resolveAlias(symbol);
6049
+ if (!target || visitedSymbols.has(target))
6050
+ return;
6051
+ if (!(target.flags & (ts16.SymbolFlags.ValueModule | ts16.SymbolFlags.NamespaceModule)))
6052
+ return;
6053
+ if (!symbolAllowed(target))
6054
+ return;
6055
+ visitedSymbols.add(target);
6056
+ for (const exp of checker.getExportsOfModule(target)) {
6057
+ const expTarget = resolveAlias(exp);
6058
+ if (!expTarget)
6059
+ continue;
6060
+ if (expTarget.flags & TYPE_SYMBOL_FLAGS) {
6061
+ registerTypeSymbol(expTarget);
6062
+ }
6063
+ }
6064
+ };
6065
+ const walkNode = (node) => {
6066
+ if (ts16.isTypeReferenceNode(node)) {
6067
+ handleRef(node.typeName);
6068
+ if (ts16.isQualifiedName(node.typeName)) {
6069
+ handleNamespaceRef(node.typeName.left);
6070
+ }
6071
+ } else if (ts16.isExpressionWithTypeArguments(node)) {
6072
+ handleRef(node.expression);
6073
+ } else if (ts16.isTypeQueryNode(node)) {
6074
+ handleRef(node.exprName);
6075
+ if (ts16.isQualifiedName(node.exprName)) {
6076
+ handleRef(node.exprName.left);
6077
+ handleNamespaceRef(node.exprName.left);
6078
+ }
6079
+ } else if (ts16.isImportTypeNode(node) && node.qualifier) {
6080
+ handleRef(node.qualifier);
6081
+ if (ts16.isQualifiedName(node.qualifier)) {
6082
+ handleNamespaceRef(node.qualifier.left);
6083
+ }
6084
+ }
6085
+ node.forEachChild(walkNode);
6086
+ };
6087
+ const walkDeclarations = (symbol) => {
6088
+ if (visitedSymbols.has(symbol))
6089
+ return;
6090
+ visitedSymbols.add(symbol);
6091
+ for (const decl of symbol.declarations ?? []) {
6092
+ walkNode(decl);
6093
+ }
6094
+ };
6095
+ for (const exportSymbol of exportedSymbols) {
6096
+ let target = exportSymbol;
6097
+ if (exportSymbol.flags & ts16.SymbolFlags.Alias) {
6098
+ try {
6099
+ target = checker.getAliasedSymbol(exportSymbol);
6100
+ } catch {
6101
+ continue;
6102
+ }
6103
+ }
6104
+ const decl = target.valueDeclaration ?? target.declarations?.[0];
6105
+ if (decl) {
6106
+ visit(checker.getTypeOfSymbolAtLocation(target, decl), 0);
6107
+ }
6108
+ if (target.flags & TYPE_SYMBOL_FLAGS) {
6109
+ visit(checker.getDeclaredTypeOfSymbol(target), 0);
6110
+ }
6111
+ walkDeclarations(target);
6112
+ }
6113
+ }
6114
+
6115
+ // src/builder/verification.ts
6116
+ import * as path8 from "node:path";
5736
6117
  var BUILTIN_TYPES2 = new Set([
5737
6118
  "Array",
5738
6119
  "ArrayBuffer",
@@ -5821,8 +6202,8 @@ function isExternalType2(definedIn, baseDir) {
5821
6202
  return true;
5822
6203
  if (definedIn.includes("node_modules"))
5823
6204
  return true;
5824
- const normalizedDefined = path7.resolve(definedIn);
5825
- const normalizedBase = path7.resolve(baseDir);
6205
+ const normalizedDefined = path8.resolve(definedIn);
6206
+ const normalizedBase = path8.resolve(baseDir);
5826
6207
  return !normalizedDefined.startsWith(normalizedBase);
5827
6208
  }
5828
6209
  function shouldSkipDanglingRef(name) {
@@ -6004,12 +6385,23 @@ async function extract(options) {
6004
6385
  diagnostics: [
6005
6386
  {
6006
6387
  message: `No exports found in ${entryFile}. Is this the right entry point?`,
6007
- severity: "warning"
6388
+ severity: "error"
6008
6389
  }
6009
6390
  ]
6010
6391
  };
6011
6392
  }
6012
6393
  const exportedSymbols = typeChecker.getExportsOfModule(moduleSymbol);
6394
+ if (exportedSymbols.length === 0) {
6395
+ return {
6396
+ spec: createEmptySpec(entryFile, includeSchema, isDtsSource),
6397
+ diagnostics: [
6398
+ {
6399
+ message: `No exports found in ${entryFile}. Is this the right entry point?`,
6400
+ severity: "error"
6401
+ }
6402
+ ]
6403
+ };
6404
+ }
6013
6405
  const exportedIds = new Set;
6014
6406
  for (const symbol of exportedSymbols) {
6015
6407
  exportedIds.add(symbol.getName());
@@ -6060,9 +6452,9 @@ async function extract(options) {
6060
6452
  break;
6061
6453
  }
6062
6454
  }
6063
- if (ts16.isExportSpecifier(decl)) {
6455
+ if (ts17.isExportSpecifier(decl)) {
6064
6456
  const exportDecl = decl.parent?.parent;
6065
- if (exportDecl && ts16.isExportDeclaration(exportDecl) && exportDecl.moduleSpecifier) {
6457
+ if (exportDecl && ts17.isExportDeclaration(exportDecl) && exportDecl.moduleSpecifier) {
6066
6458
  const moduleText = exportDecl.moduleSpecifier.getText().slice(1, -1);
6067
6459
  if (!moduleText.startsWith(".") && !moduleText.startsWith("/")) {
6068
6460
  externalPackage = moduleText;
@@ -6125,8 +6517,13 @@ async function extract(options) {
6125
6517
  }
6126
6518
  const verification = buildVerificationSummary(exportedSymbols.length, exports.length, exportTracker);
6127
6519
  const meta = await getPackageMeta(entryFile, baseDir);
6520
+ expandReachableTypes(filteredSymbols, ctx, {
6521
+ followExternal: options.followExternal,
6522
+ workspacePackages: result.workspacePackages ?? new Map,
6523
+ entryFile
6524
+ });
6128
6525
  {
6129
- const symFlags = ts16.SymbolFlags.Type | ts16.SymbolFlags.Interface | ts16.SymbolFlags.Class;
6526
+ const symFlags = ts17.SymbolFlags.Type | ts17.SymbolFlags.Interface | ts17.SymbolFlags.Class;
6130
6527
  const maxPasses = 5;
6131
6528
  for (let pass = 0;pass < maxPasses; pass++) {
6132
6529
  const allRefs = new Map;
@@ -6161,7 +6558,7 @@ async function extract(options) {
6161
6558
  }
6162
6559
  }
6163
6560
  const types = ctx.typeRegistry.getAll();
6164
- const projectBaseDir = baseDir ?? path8.dirname(entryFile);
6561
+ const projectBaseDir = baseDir ?? path9.dirname(entryFile);
6165
6562
  const definedTypes = new Set(types.map((t) => t.id));
6166
6563
  const forgottenExports = collectForgottenExports(exports, types, program, sourceFile, exportedIds, projectBaseDir, definedTypes);
6167
6564
  for (const forgotten of forgottenExports) {
@@ -6194,7 +6591,7 @@ async function extract(options) {
6194
6591
  }
6195
6592
  let runtimeMetadata;
6196
6593
  if (options.schemaExtraction === "hybrid") {
6197
- const projectBaseDir2 = baseDir || path8.dirname(entryFile);
6594
+ const projectBaseDir2 = baseDir || path9.dirname(entryFile);
6198
6595
  const runtimeResult = await extractStandardSchemasFromProject(entryFile, projectBaseDir2, {
6199
6596
  target: options.schemaTarget || "draft-2020-12",
6200
6597
  timeout: 15000
@@ -6273,21 +6670,21 @@ async function extract(options) {
6273
6670
  }
6274
6671
  function serializeDeclaration2(declaration, exportSymbol, exportName, ctx, isTypeOnly = false) {
6275
6672
  let result = null;
6276
- if (ts16.isFunctionDeclaration(declaration)) {
6673
+ if (ts17.isFunctionDeclaration(declaration)) {
6277
6674
  result = serializeFunctionExport(declaration, ctx);
6278
- } else if (ts16.isClassDeclaration(declaration)) {
6675
+ } else if (ts17.isClassDeclaration(declaration)) {
6279
6676
  result = serializeClass(declaration, ctx);
6280
- } else if (ts16.isInterfaceDeclaration(declaration)) {
6677
+ } else if (ts17.isInterfaceDeclaration(declaration)) {
6281
6678
  result = serializeInterface(declaration, ctx);
6282
- } else if (ts16.isTypeAliasDeclaration(declaration)) {
6679
+ } else if (ts17.isTypeAliasDeclaration(declaration)) {
6283
6680
  result = serializeTypeAlias(declaration, ctx);
6284
- } else if (ts16.isEnumDeclaration(declaration)) {
6681
+ } else if (ts17.isEnumDeclaration(declaration)) {
6285
6682
  result = serializeEnum(declaration, ctx);
6286
- } else if (ts16.isVariableDeclaration(declaration)) {
6683
+ } else if (ts17.isVariableDeclaration(declaration)) {
6287
6684
  const varStatement = declaration.parent?.parent;
6288
- if (varStatement && ts16.isVariableStatement(varStatement)) {
6289
- if (declaration.initializer && (ts16.isArrowFunction(declaration.initializer) || ts16.isFunctionExpression(declaration.initializer))) {
6290
- const varName = ts16.isIdentifier(declaration.name) ? declaration.name.text : declaration.name.getText();
6685
+ if (varStatement && ts17.isVariableStatement(varStatement)) {
6686
+ if (declaration.initializer && (ts17.isArrowFunction(declaration.initializer) || ts17.isFunctionExpression(declaration.initializer))) {
6687
+ const varName = ts17.isIdentifier(declaration.name) ? declaration.name.text : declaration.name.getText();
6291
6688
  result = serializeFunctionExport(declaration.initializer, ctx, varName);
6292
6689
  } else {
6293
6690
  result = serializeVariable(declaration, varStatement, ctx);
@@ -6299,7 +6696,7 @@ function serializeDeclaration2(declaration, exportSymbol, exportName, ctx, isTyp
6299
6696
  }
6300
6697
  }
6301
6698
  }
6302
- } else if (ts16.isNamespaceExport(declaration) || ts16.isModuleDeclaration(declaration) || ts16.isNamespaceImport(declaration) || ts16.isSourceFile(declaration)) {
6699
+ } else if (ts17.isNamespaceExport(declaration) || ts17.isModuleDeclaration(declaration) || ts17.isNamespaceImport(declaration) || ts17.isSourceFile(declaration)) {
6303
6700
  try {
6304
6701
  result = serializeNamespaceExport(exportSymbol, exportName, ctx);
6305
6702
  } catch {
@@ -6335,7 +6732,7 @@ function serializeNamespaceExport(symbol, exportName, ctx) {
6335
6732
  const members = [];
6336
6733
  const checker = ctx.program.getTypeChecker();
6337
6734
  let targetSymbol = symbol;
6338
- if (symbol.flags & ts16.SymbolFlags.Alias) {
6735
+ if (symbol.flags & ts17.SymbolFlags.Alias) {
6339
6736
  const aliased = checker.getAliasedSymbol(symbol);
6340
6737
  if (aliased && aliased !== symbol) {
6341
6738
  targetSymbol = aliased;
@@ -6362,31 +6759,31 @@ function serializeNamespaceExport(symbol, exportName, ctx) {
6362
6759
  function serializeNamespaceMember(symbol, memberName, ctx) {
6363
6760
  const checker = ctx.program.getTypeChecker();
6364
6761
  let targetSymbol = symbol;
6365
- if (symbol.flags & ts16.SymbolFlags.Alias) {
6762
+ if (symbol.flags & ts17.SymbolFlags.Alias) {
6366
6763
  const aliased = checker.getAliasedSymbol(symbol);
6367
6764
  if (aliased && aliased !== symbol) {
6368
6765
  targetSymbol = aliased;
6369
6766
  }
6370
6767
  }
6371
6768
  const declarations = targetSymbol.declarations ?? [];
6372
- const declaration = targetSymbol.valueDeclaration || declarations.find((d) => d.kind !== ts16.SyntaxKind.ExportSpecifier) || declarations[0];
6769
+ const declaration = targetSymbol.valueDeclaration || declarations.find((d) => d.kind !== ts17.SyntaxKind.ExportSpecifier) || declarations[0];
6373
6770
  if (!declaration)
6374
6771
  return null;
6375
6772
  const type = checker.getTypeAtLocation(declaration);
6376
6773
  const callSignatures = type.getCallSignatures();
6377
6774
  const { deprecated } = isSymbolDeprecated(targetSymbol);
6378
6775
  let kind = "variable";
6379
- if (ts16.isFunctionDeclaration(declaration) || ts16.isFunctionExpression(declaration)) {
6776
+ if (ts17.isFunctionDeclaration(declaration) || ts17.isFunctionExpression(declaration)) {
6380
6777
  kind = "function";
6381
- } else if (ts16.isClassDeclaration(declaration)) {
6778
+ } else if (ts17.isClassDeclaration(declaration)) {
6382
6779
  kind = "class";
6383
- } else if (ts16.isInterfaceDeclaration(declaration)) {
6780
+ } else if (ts17.isInterfaceDeclaration(declaration)) {
6384
6781
  kind = "interface";
6385
- } else if (ts16.isTypeAliasDeclaration(declaration)) {
6782
+ } else if (ts17.isTypeAliasDeclaration(declaration)) {
6386
6783
  kind = "type";
6387
- } else if (ts16.isEnumDeclaration(declaration)) {
6784
+ } else if (ts17.isEnumDeclaration(declaration)) {
6388
6785
  kind = "enum";
6389
- } else if (ts16.isVariableDeclaration(declaration)) {
6786
+ } else if (ts17.isVariableDeclaration(declaration)) {
6390
6787
  if (callSignatures.length > 0) {
6391
6788
  kind = "function";
6392
6789
  }
@@ -6417,11 +6814,11 @@ function getJSDocFromExportSymbol(symbol) {
6417
6814
  const examples = [];
6418
6815
  const decl = symbol.declarations?.[0];
6419
6816
  if (decl) {
6420
- const exportDecl = ts16.isNamespaceExport(decl) ? decl.parent : decl;
6421
- if (exportDecl && ts16.isExportDeclaration(exportDecl)) {
6422
- const jsDocs = ts16.getJSDocCommentsAndTags(exportDecl);
6817
+ const exportDecl = ts17.isNamespaceExport(decl) ? decl.parent : decl;
6818
+ if (exportDecl && ts17.isExportDeclaration(exportDecl)) {
6819
+ const jsDocs = ts17.getJSDocCommentsAndTags(exportDecl);
6423
6820
  for (const doc of jsDocs) {
6424
- if (ts16.isJSDoc(doc) && doc.comment) {
6821
+ if (ts17.isJSDoc(doc) && doc.comment) {
6425
6822
  const commentText = typeof doc.comment === "string" ? doc.comment : doc.comment.map((c) => ("text" in c) ? c.text : "").join("");
6426
6823
  if (commentText) {
6427
6824
  return {
@@ -6483,7 +6880,7 @@ function createEmptySpec(entryFile, includeSchema, isDtsSource) {
6483
6880
  return {
6484
6881
  ...includeSchema ? { $schema: SCHEMA_URL } : {},
6485
6882
  openpkg: SCHEMA_VERSION,
6486
- meta: { name: path8.basename(entryFile, path8.extname(entryFile)) },
6883
+ meta: { name: path9.basename(entryFile, path9.extname(entryFile)) },
6487
6884
  exports: [],
6488
6885
  generation: {
6489
6886
  generator: "@openpkg-ts/sdk",
@@ -6499,7 +6896,7 @@ function findTypeInProgram(name, checker, program, sourceFile, symFlags) {
6499
6896
  const localSym = checker.resolveName(name, sourceFile, symFlags, false);
6500
6897
  if (localSym)
6501
6898
  return checker.getDeclaredTypeOfSymbol(localSym);
6502
- const entryDir = path8.dirname(sourceFile.fileName);
6899
+ const entryDir = path9.dirname(sourceFile.fileName);
6503
6900
  for (const sf of program.getSourceFiles()) {
6504
6901
  const fn = sf.fileName;
6505
6902
  if (fn.includes("/typescript/lib/lib.") || fn.includes("\\typescript\\lib\\lib."))
@@ -6515,33 +6912,33 @@ function findTypeInProgram(name, checker, program, sourceFile, symFlags) {
6515
6912
  return;
6516
6913
  }
6517
6914
  async function getPackageMeta(entryFile, baseDir) {
6518
- let dir = baseDir ?? path8.dirname(entryFile);
6519
- while (dir !== path8.dirname(dir)) {
6520
- const pkgPath = path8.join(dir, "package.json");
6915
+ let dir = baseDir ?? path9.dirname(entryFile);
6916
+ while (dir !== path9.dirname(dir)) {
6917
+ const pkgPath = path9.join(dir, "package.json");
6521
6918
  try {
6522
- if (fs6.existsSync(pkgPath)) {
6523
- const pkg = JSON.parse(fs6.readFileSync(pkgPath, "utf-8"));
6919
+ if (fs7.existsSync(pkgPath)) {
6920
+ const pkg = JSON.parse(fs7.readFileSync(pkgPath, "utf-8"));
6524
6921
  return {
6525
- name: pkg.name ?? path8.basename(dir),
6922
+ name: pkg.name ?? path9.basename(dir),
6526
6923
  version: pkg.version,
6527
6924
  description: pkg.description
6528
6925
  };
6529
6926
  }
6530
6927
  } catch {}
6531
- dir = path8.dirname(dir);
6928
+ dir = path9.dirname(dir);
6532
6929
  }
6533
- return { name: path8.basename(baseDir ?? path8.dirname(entryFile)) };
6930
+ return { name: path9.basename(baseDir ?? path9.dirname(entryFile)) };
6534
6931
  }
6535
6932
 
6536
6933
  // src/primitives/spec.ts
6537
6934
  var extractSpec = extract;
6538
6935
  // src/types/utils.ts
6539
- import ts17 from "typescript";
6936
+ import ts18 from "typescript";
6540
6937
  function isExported(node) {
6541
6938
  const modifiers = node.modifiers;
6542
6939
  if (!modifiers)
6543
6940
  return false;
6544
- return modifiers.some((m) => m.kind === ts17.SyntaxKind.ExportKeyword);
6941
+ return modifiers.some((m) => m.kind === ts18.SyntaxKind.ExportKeyword);
6545
6942
  }
6546
6943
  function getNodeName(node) {
6547
6944
  if ("name" in node && node.name) {
@@ -6553,6 +6950,7 @@ function getNodeName(node) {
6553
6950
  export {
6554
6951
  zodAdapter,
6555
6952
  withDescription,
6953
+ withDeprecated,
6556
6954
  valibotAdapter,
6557
6955
  typeboxAdapter,
6558
6956
  toSearchIndexJSON,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openpkg-ts/sdk",
3
- "version": "0.41.0",
3
+ "version": "0.43.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.43.0",
47
47
  "picomatch": "4.0.3",
48
48
  "typescript": "^5.0.0"
49
49
  },