@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 +23 -3
- package/dist/index.js +495 -97
- package/package.json +2 -2
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:
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
2964
|
-
if (
|
|
2965
|
-
|
|
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
|
-
|
|
3053
|
+
const included = properties.filter((prop) => {
|
|
3006
3054
|
const propName = prop.getName();
|
|
3007
|
-
if (propName.startsWith("
|
|
3008
|
-
|
|
3055
|
+
if (propName.startsWith("__@"))
|
|
3056
|
+
return false;
|
|
3009
3057
|
if (isArrayLike && ARRAY_PROTOTYPE_METHODS.has(propName))
|
|
3010
|
-
|
|
3058
|
+
return false;
|
|
3011
3059
|
if (isStringLike && STRING_PROTOTYPE_METHODS.has(propName))
|
|
3012
|
-
|
|
3060
|
+
return false;
|
|
3013
3061
|
if (isNumberLike && NUMBER_PROTOTYPE_METHODS.has(propName))
|
|
3014
|
-
|
|
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
|
-
|
|
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 ??
|
|
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
|
|
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-
|
|
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
|
-
|
|
4364
|
-
|
|
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
|
|
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
|
-
...
|
|
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
|
-
...
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
4862
|
-
import * as
|
|
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
|
|
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/
|
|
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 =
|
|
5825
|
-
const normalizedBase =
|
|
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: "
|
|
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 (
|
|
6455
|
+
if (ts17.isExportSpecifier(decl)) {
|
|
6064
6456
|
const exportDecl = decl.parent?.parent;
|
|
6065
|
-
if (exportDecl &&
|
|
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 =
|
|
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 ??
|
|
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 ||
|
|
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 (
|
|
6673
|
+
if (ts17.isFunctionDeclaration(declaration)) {
|
|
6277
6674
|
result = serializeFunctionExport(declaration, ctx);
|
|
6278
|
-
} else if (
|
|
6675
|
+
} else if (ts17.isClassDeclaration(declaration)) {
|
|
6279
6676
|
result = serializeClass(declaration, ctx);
|
|
6280
|
-
} else if (
|
|
6677
|
+
} else if (ts17.isInterfaceDeclaration(declaration)) {
|
|
6281
6678
|
result = serializeInterface(declaration, ctx);
|
|
6282
|
-
} else if (
|
|
6679
|
+
} else if (ts17.isTypeAliasDeclaration(declaration)) {
|
|
6283
6680
|
result = serializeTypeAlias(declaration, ctx);
|
|
6284
|
-
} else if (
|
|
6681
|
+
} else if (ts17.isEnumDeclaration(declaration)) {
|
|
6285
6682
|
result = serializeEnum(declaration, ctx);
|
|
6286
|
-
} else if (
|
|
6683
|
+
} else if (ts17.isVariableDeclaration(declaration)) {
|
|
6287
6684
|
const varStatement = declaration.parent?.parent;
|
|
6288
|
-
if (varStatement &&
|
|
6289
|
-
if (declaration.initializer && (
|
|
6290
|
-
const varName =
|
|
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 (
|
|
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 &
|
|
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 &
|
|
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 !==
|
|
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 (
|
|
6776
|
+
if (ts17.isFunctionDeclaration(declaration) || ts17.isFunctionExpression(declaration)) {
|
|
6380
6777
|
kind = "function";
|
|
6381
|
-
} else if (
|
|
6778
|
+
} else if (ts17.isClassDeclaration(declaration)) {
|
|
6382
6779
|
kind = "class";
|
|
6383
|
-
} else if (
|
|
6780
|
+
} else if (ts17.isInterfaceDeclaration(declaration)) {
|
|
6384
6781
|
kind = "interface";
|
|
6385
|
-
} else if (
|
|
6782
|
+
} else if (ts17.isTypeAliasDeclaration(declaration)) {
|
|
6386
6783
|
kind = "type";
|
|
6387
|
-
} else if (
|
|
6784
|
+
} else if (ts17.isEnumDeclaration(declaration)) {
|
|
6388
6785
|
kind = "enum";
|
|
6389
|
-
} else if (
|
|
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 =
|
|
6421
|
-
if (exportDecl &&
|
|
6422
|
-
const jsDocs =
|
|
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 (
|
|
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:
|
|
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 =
|
|
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 ??
|
|
6519
|
-
while (dir !==
|
|
6520
|
-
const pkgPath =
|
|
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 (
|
|
6523
|
-
const pkg = JSON.parse(
|
|
6919
|
+
if (fs7.existsSync(pkgPath)) {
|
|
6920
|
+
const pkg = JSON.parse(fs7.readFileSync(pkgPath, "utf-8"));
|
|
6524
6921
|
return {
|
|
6525
|
-
name: pkg.name ??
|
|
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 =
|
|
6928
|
+
dir = path9.dirname(dir);
|
|
6532
6929
|
}
|
|
6533
|
-
return { name:
|
|
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
|
|
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 ===
|
|
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.
|
|
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.
|
|
46
|
+
"@openpkg-ts/spec": "^0.43.0",
|
|
47
47
|
"picomatch": "4.0.3",
|
|
48
48
|
"typescript": "^5.0.0"
|
|
49
49
|
},
|