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