@openpkg-ts/extract 0.24.1 → 0.26.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/bin/tspec.js
CHANGED
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
detectTsRuntime,
|
|
4
4
|
extract,
|
|
5
5
|
resolveCompiledPath
|
|
6
|
-
} from "../shared/chunk-
|
|
6
|
+
} from "../shared/chunk-xamjhe27.js";
|
|
7
7
|
|
|
8
8
|
// src/cli/spec.ts
|
|
9
9
|
import * as fs from "node:fs";
|
|
@@ -428,8 +428,9 @@ function createProgram() {
|
|
|
428
428
|
fromDts = found.fromDts;
|
|
429
429
|
}
|
|
430
430
|
if (fromDts) {
|
|
431
|
-
console.
|
|
432
|
-
console.
|
|
431
|
+
console.log("Mode: Declaration-only (.d.ts)");
|
|
432
|
+
console.log(" Types and signatures will be extracted");
|
|
433
|
+
console.log(` JSDoc comments unavailable (stripped during compilation)
|
|
433
434
|
`);
|
|
434
435
|
}
|
|
435
436
|
if (options.runtime) {
|
|
@@ -459,7 +460,8 @@ function createProgram() {
|
|
|
459
460
|
resolveExternalTypes: !options.skipResolve,
|
|
460
461
|
schemaExtraction: options.runtime ? "hybrid" : "static",
|
|
461
462
|
...options.only ? { only: options.only.split(",").map((s) => s.trim()) } : {},
|
|
462
|
-
...options.ignore ? { ignore: options.ignore.split(",").map((s) => s.trim()) } : {}
|
|
463
|
+
...options.ignore ? { ignore: options.ignore.split(",").map((s) => s.trim()) } : {},
|
|
464
|
+
isDtsSource: fromDts
|
|
463
465
|
});
|
|
464
466
|
const normalized = normalize(result.spec);
|
|
465
467
|
const validation = validateSpec(normalized);
|
|
@@ -473,6 +475,15 @@ function createProgram() {
|
|
|
473
475
|
}
|
|
474
476
|
fs.writeFileSync(options.output, JSON.stringify(normalized, null, 2));
|
|
475
477
|
spin.success(`Extracted to ${options.output}`);
|
|
478
|
+
if (result.degradedMode) {
|
|
479
|
+
const { stats } = result.degradedMode;
|
|
480
|
+
const total = normalized.exports.length;
|
|
481
|
+
console.log(`
|
|
482
|
+
Extraction completed in declaration-only mode:`);
|
|
483
|
+
console.log(` ${stats.exportsWithoutDescription}/${total} exports missing descriptions`);
|
|
484
|
+
console.log(` ${stats.paramsWithoutDocs} parameters without documentation`);
|
|
485
|
+
console.log(` ${stats.missingExamples} exports without examples`);
|
|
486
|
+
}
|
|
476
487
|
if (result.runtimeSchemas) {
|
|
477
488
|
const { extracted, merged, vendors, method } = result.runtimeSchemas;
|
|
478
489
|
const via = method ? ` via ${method}` : "";
|
|
@@ -831,7 +831,7 @@ function extractSeeTagText(tag) {
|
|
|
831
831
|
}
|
|
832
832
|
return typeof tag.comment === "string" ? tag.comment : ts3.getTextOfJSDocComment(tag.comment) ?? "";
|
|
833
833
|
}
|
|
834
|
-
function getJSDocComment(node) {
|
|
834
|
+
function getJSDocComment(node, symbol, checker) {
|
|
835
835
|
const jsDocTags = ts3.getJSDocTags(node);
|
|
836
836
|
const tags = jsDocTags.map((tag) => {
|
|
837
837
|
const rawText = typeof tag.comment === "string" ? tag.comment : ts3.getTextOfJSDocComment(tag.comment) ?? "";
|
|
@@ -869,6 +869,13 @@ function getJSDocComment(node) {
|
|
|
869
869
|
description = typeof firstDoc.comment === "string" ? firstDoc.comment : ts3.getTextOfJSDocComment(firstDoc.comment);
|
|
870
870
|
}
|
|
871
871
|
}
|
|
872
|
+
if (!description && symbol && checker) {
|
|
873
|
+
const docComment = symbol.getDocumentationComment(checker);
|
|
874
|
+
if (docComment.length > 0) {
|
|
875
|
+
description = docComment.map((c) => c.text).join(`
|
|
876
|
+
`);
|
|
877
|
+
}
|
|
878
|
+
}
|
|
872
879
|
const examples = parseExamplesFromTags(tags);
|
|
873
880
|
return { description, tags, examples };
|
|
874
881
|
}
|
|
@@ -954,12 +961,13 @@ function isSymbolDeprecated(symbol) {
|
|
|
954
961
|
}
|
|
955
962
|
return false;
|
|
956
963
|
}
|
|
957
|
-
function getJSDocForSignature(signature) {
|
|
964
|
+
function getJSDocForSignature(signature, checker) {
|
|
958
965
|
const decl = signature.getDeclaration();
|
|
959
966
|
if (!decl) {
|
|
960
967
|
return { tags: [], examples: [] };
|
|
961
968
|
}
|
|
962
|
-
|
|
969
|
+
const symbol = checker?.getSymbolAtLocation(decl);
|
|
970
|
+
return getJSDocComment(decl, symbol, checker);
|
|
963
971
|
}
|
|
964
972
|
function extractTypeParametersFromSignature(signature, checker) {
|
|
965
973
|
const typeParams = signature.getTypeParameters();
|
|
@@ -1819,7 +1827,7 @@ function serializeInheritedMember(symbol, inheritedFrom, ctx, isStatic) {
|
|
|
1819
1827
|
const params = extractParameters(sig, ctx);
|
|
1820
1828
|
const returnType = checker.getReturnTypeOfSignature(sig);
|
|
1821
1829
|
registerReferencedTypes(returnType, ctx);
|
|
1822
|
-
const sigDoc = getJSDocForSignature(sig);
|
|
1830
|
+
const sigDoc = getJSDocForSignature(sig, checker);
|
|
1823
1831
|
return {
|
|
1824
1832
|
parameters: params.length > 0 ? params : undefined,
|
|
1825
1833
|
returns: {
|
|
@@ -1853,7 +1861,7 @@ function serializeClass(node, ctx) {
|
|
|
1853
1861
|
return null;
|
|
1854
1862
|
const deprecated = isSymbolDeprecated(symbol);
|
|
1855
1863
|
const declSourceFile = node.getSourceFile();
|
|
1856
|
-
const { description, tags, examples } = getJSDocComment(node);
|
|
1864
|
+
const { description, tags, examples } = getJSDocComment(node, symbol, checker);
|
|
1857
1865
|
const source = getSourceLocation(node, declSourceFile);
|
|
1858
1866
|
const typeParameters = extractTypeParameters(node, checker);
|
|
1859
1867
|
const members = [];
|
|
@@ -1995,7 +2003,7 @@ function serializeMethod(node, ctx) {
|
|
|
1995
2003
|
const params = extractParameters(sig, ctx);
|
|
1996
2004
|
const returnType = checker.getReturnTypeOfSignature(sig);
|
|
1997
2005
|
registerReferencedTypes(returnType, ctx);
|
|
1998
|
-
const sigDoc = getJSDocForSignature(sig);
|
|
2006
|
+
const sigDoc = getJSDocForSignature(sig, checker);
|
|
1999
2007
|
const sigTypeParams = extractTypeParametersFromSignature(sig, checker);
|
|
2000
2008
|
return {
|
|
2001
2009
|
parameters: params.length > 0 ? params : undefined,
|
|
@@ -2103,7 +2111,7 @@ function serializeEnum(node, ctx) {
|
|
|
2103
2111
|
return null;
|
|
2104
2112
|
const deprecated = isSymbolDeprecated(symbol);
|
|
2105
2113
|
const declSourceFile = node.getSourceFile();
|
|
2106
|
-
const { description, tags, examples } = getJSDocComment(node);
|
|
2114
|
+
const { description, tags, examples } = getJSDocComment(node, symbol, checker);
|
|
2107
2115
|
const source = getSourceLocation(node, declSourceFile);
|
|
2108
2116
|
const members = node.members.map((member) => {
|
|
2109
2117
|
const memberSymbol = checker.getSymbolAtLocation(member.name);
|
|
@@ -2176,14 +2184,14 @@ function serializeFunctionExport(node, ctx) {
|
|
|
2176
2184
|
return null;
|
|
2177
2185
|
const deprecated = isSymbolDeprecated(symbol);
|
|
2178
2186
|
const declSourceFile = node.getSourceFile();
|
|
2179
|
-
const { description, tags, examples } = getJSDocComment(node);
|
|
2187
|
+
const { description, tags, examples } = getJSDocComment(node, symbol, ctx.typeChecker);
|
|
2180
2188
|
const source = getSourceLocation(node, declSourceFile);
|
|
2181
2189
|
const typeParameters = extractTypeParameters(node, ctx.typeChecker);
|
|
2182
2190
|
const type = ctx.typeChecker.getTypeAtLocation(node);
|
|
2183
2191
|
const callSignatures = type.getCallSignatures();
|
|
2184
2192
|
const signatures = callSignatures.map((sig, index) => {
|
|
2185
2193
|
const params = extractParameters(sig, ctx);
|
|
2186
|
-
const sigDoc = getJSDocForSignature(sig);
|
|
2194
|
+
const sigDoc = getJSDocForSignature(sig, ctx.typeChecker);
|
|
2187
2195
|
const sigTypeParams = extractTypeParametersFromSignature(sig, ctx.typeChecker);
|
|
2188
2196
|
return {
|
|
2189
2197
|
parameters: params,
|
|
@@ -2219,7 +2227,7 @@ function serializeInterface(node, ctx) {
|
|
|
2219
2227
|
return null;
|
|
2220
2228
|
const deprecated = isSymbolDeprecated(symbol);
|
|
2221
2229
|
const declSourceFile = node.getSourceFile();
|
|
2222
|
-
const { description, tags, examples } = getJSDocComment(node);
|
|
2230
|
+
const { description, tags, examples } = getJSDocComment(node, symbol, checker);
|
|
2223
2231
|
const source = getSourceLocation(node, declSourceFile);
|
|
2224
2232
|
const typeParameters = extractTypeParameters(node, checker);
|
|
2225
2233
|
const members = [];
|
|
@@ -2294,7 +2302,7 @@ function serializeMethodSignature(node, ctx) {
|
|
|
2294
2302
|
const params = extractParameters(sig, ctx);
|
|
2295
2303
|
const returnType = checker.getReturnTypeOfSignature(sig);
|
|
2296
2304
|
registerReferencedTypes(returnType, ctx);
|
|
2297
|
-
const sigDoc = getJSDocForSignature(sig);
|
|
2305
|
+
const sigDoc = getJSDocForSignature(sig, checker);
|
|
2298
2306
|
const sigTypeParams = extractTypeParametersFromSignature(sig, checker);
|
|
2299
2307
|
return {
|
|
2300
2308
|
parameters: params.length > 0 ? params : undefined,
|
|
@@ -2404,7 +2412,7 @@ function serializeTypeAlias(node, ctx) {
|
|
|
2404
2412
|
return null;
|
|
2405
2413
|
const deprecated = isSymbolDeprecated(symbol);
|
|
2406
2414
|
const declSourceFile = node.getSourceFile();
|
|
2407
|
-
const { description, tags, examples } = getJSDocComment(node);
|
|
2415
|
+
const { description, tags, examples } = getJSDocComment(node, symbol, ctx.typeChecker);
|
|
2408
2416
|
const source = getSourceLocation(node, declSourceFile);
|
|
2409
2417
|
const typeParameters = extractTypeParameters(node, ctx.typeChecker);
|
|
2410
2418
|
const type = ctx.typeChecker.getTypeAtLocation(node);
|
|
@@ -2600,7 +2608,7 @@ function serializeVariable(node, statement, ctx) {
|
|
|
2600
2608
|
return null;
|
|
2601
2609
|
const deprecated = isSymbolDeprecated(symbol);
|
|
2602
2610
|
const declSourceFile = node.getSourceFile();
|
|
2603
|
-
const { description, tags, examples } = getJSDocComment(statement);
|
|
2611
|
+
const { description, tags, examples } = getJSDocComment(statement, symbol, ctx.typeChecker);
|
|
2604
2612
|
const source = getSourceLocation(node, declSourceFile);
|
|
2605
2613
|
const type = ctx.typeChecker.getTypeAtLocation(node);
|
|
2606
2614
|
const schemaExtraction = extractSchemaType(type, ctx.typeChecker);
|
|
@@ -3112,6 +3120,28 @@ function clearTypeDefinitionCache() {
|
|
|
3112
3120
|
typeDefinitionCache = null;
|
|
3113
3121
|
internalTagCache = null;
|
|
3114
3122
|
}
|
|
3123
|
+
var YIELD_BATCH_SIZE = 5;
|
|
3124
|
+
function computeDegradedStats(exports) {
|
|
3125
|
+
let exportsWithoutDescription = 0;
|
|
3126
|
+
let paramsWithoutDocs = 0;
|
|
3127
|
+
let missingExamples = 0;
|
|
3128
|
+
for (const exp of exports) {
|
|
3129
|
+
if (!exp.description)
|
|
3130
|
+
exportsWithoutDescription++;
|
|
3131
|
+
if (!exp.examples || exp.examples.length === 0)
|
|
3132
|
+
missingExamples++;
|
|
3133
|
+
const signatures = exp.signatures;
|
|
3134
|
+
if (signatures) {
|
|
3135
|
+
for (const sig of signatures) {
|
|
3136
|
+
for (const param of sig.parameters ?? []) {
|
|
3137
|
+
if (!param.description)
|
|
3138
|
+
paramsWithoutDocs++;
|
|
3139
|
+
}
|
|
3140
|
+
}
|
|
3141
|
+
}
|
|
3142
|
+
}
|
|
3143
|
+
return { exportsWithoutDescription, paramsWithoutDocs, missingExamples };
|
|
3144
|
+
}
|
|
3115
3145
|
var BUILTIN_TYPES2 = new Set([
|
|
3116
3146
|
"Array",
|
|
3117
3147
|
"ArrayBuffer",
|
|
@@ -3206,7 +3236,9 @@ async function extract(options) {
|
|
|
3206
3236
|
resolveExternalTypes,
|
|
3207
3237
|
includeSchema,
|
|
3208
3238
|
only,
|
|
3209
|
-
ignore
|
|
3239
|
+
ignore,
|
|
3240
|
+
onProgress,
|
|
3241
|
+
isDtsSource
|
|
3210
3242
|
} = options;
|
|
3211
3243
|
const diagnostics = [];
|
|
3212
3244
|
let exports = [];
|
|
@@ -3214,7 +3246,7 @@ async function extract(options) {
|
|
|
3214
3246
|
const { program, sourceFile } = result;
|
|
3215
3247
|
if (!sourceFile) {
|
|
3216
3248
|
return {
|
|
3217
|
-
spec: createEmptySpec(entryFile, includeSchema),
|
|
3249
|
+
spec: createEmptySpec(entryFile, includeSchema, isDtsSource),
|
|
3218
3250
|
diagnostics: [{ message: `Could not load source file: ${entryFile}`, severity: "error" }]
|
|
3219
3251
|
};
|
|
3220
3252
|
}
|
|
@@ -3222,7 +3254,7 @@ async function extract(options) {
|
|
|
3222
3254
|
const moduleSymbol = typeChecker.getSymbolAtLocation(sourceFile);
|
|
3223
3255
|
if (!moduleSymbol) {
|
|
3224
3256
|
return {
|
|
3225
|
-
spec: createEmptySpec(entryFile, includeSchema),
|
|
3257
|
+
spec: createEmptySpec(entryFile, includeSchema, isDtsSource),
|
|
3226
3258
|
diagnostics: [{ message: "Could not get module symbol", severity: "warning" }]
|
|
3227
3259
|
};
|
|
3228
3260
|
}
|
|
@@ -3237,10 +3269,15 @@ async function extract(options) {
|
|
|
3237
3269
|
resolveExternalTypes
|
|
3238
3270
|
});
|
|
3239
3271
|
ctx.exportedIds = exportedIds;
|
|
3240
|
-
|
|
3272
|
+
const filteredSymbols = exportedSymbols.filter((s) => shouldIncludeExport(s.getName(), only, ignore));
|
|
3273
|
+
const total = filteredSymbols.length;
|
|
3274
|
+
for (let i = 0;i < filteredSymbols.length; i++) {
|
|
3275
|
+
const symbol = filteredSymbols[i];
|
|
3241
3276
|
const exportName = symbol.getName();
|
|
3242
|
-
|
|
3243
|
-
|
|
3277
|
+
onProgress?.(i + 1, total, exportName);
|
|
3278
|
+
if (i > 0 && i % YIELD_BATCH_SIZE === 0) {
|
|
3279
|
+
await new Promise((r) => setImmediate(r));
|
|
3280
|
+
}
|
|
3244
3281
|
try {
|
|
3245
3282
|
const { declaration, targetSymbol } = resolveExportTarget(symbol, typeChecker);
|
|
3246
3283
|
if (!declaration)
|
|
@@ -3326,15 +3363,21 @@ async function extract(options) {
|
|
|
3326
3363
|
generation: {
|
|
3327
3364
|
generator: "@openpkg-ts/extract",
|
|
3328
3365
|
timestamp: new Date().toISOString(),
|
|
3329
|
-
|
|
3366
|
+
mode: isDtsSource ? "declaration-only" : "source",
|
|
3367
|
+
...options.schemaExtraction === "hybrid" ? { schemaExtraction: "hybrid" } : {},
|
|
3368
|
+
...isDtsSource && {
|
|
3369
|
+
limitations: ["No JSDoc descriptions", "No @example tags", "No @param descriptions"]
|
|
3370
|
+
}
|
|
3330
3371
|
}
|
|
3331
3372
|
};
|
|
3332
3373
|
const internalForgotten = forgottenExports.filter((f) => !f.isExternal);
|
|
3374
|
+
const degradedMode = isDtsSource ? { reason: "dts-source", stats: computeDegradedStats(normalizedExports) } : undefined;
|
|
3333
3375
|
return {
|
|
3334
3376
|
spec,
|
|
3335
3377
|
diagnostics,
|
|
3336
3378
|
...internalForgotten.length > 0 ? { forgottenExports: internalForgotten } : {},
|
|
3337
|
-
...runtimeMetadata ? { runtimeSchemas: runtimeMetadata } : {}
|
|
3379
|
+
...runtimeMetadata ? { runtimeSchemas: runtimeMetadata } : {},
|
|
3380
|
+
...degradedMode ? { degradedMode } : {}
|
|
3338
3381
|
};
|
|
3339
3382
|
}
|
|
3340
3383
|
function collectAllRefsWithContext(obj, refs, state) {
|
|
@@ -3592,7 +3635,7 @@ function serializeNamespaceMember(symbol, memberName, ctx) {
|
|
|
3592
3635
|
const returnType = checker.getReturnTypeOfSignature(sig);
|
|
3593
3636
|
registerReferencedTypes(returnType, ctx);
|
|
3594
3637
|
const returnSchema = buildSchema(returnType, ctx.typeChecker, ctx);
|
|
3595
|
-
const sigDoc = getJSDocForSignature(sig);
|
|
3638
|
+
const sigDoc = getJSDocForSignature(sig, checker);
|
|
3596
3639
|
const sigTypeParams = extractTypeParametersFromSignature(sig, ctx.typeChecker);
|
|
3597
3640
|
return {
|
|
3598
3641
|
parameters: params,
|
|
@@ -3686,7 +3729,7 @@ function withExportName(entry, exportName) {
|
|
|
3686
3729
|
name: entry.name
|
|
3687
3730
|
};
|
|
3688
3731
|
}
|
|
3689
|
-
function createEmptySpec(entryFile, includeSchema) {
|
|
3732
|
+
function createEmptySpec(entryFile, includeSchema, isDtsSource) {
|
|
3690
3733
|
return {
|
|
3691
3734
|
...includeSchema ? { $schema: SCHEMA_URL } : {},
|
|
3692
3735
|
openpkg: SCHEMA_VERSION,
|
|
@@ -3694,7 +3737,11 @@ function createEmptySpec(entryFile, includeSchema) {
|
|
|
3694
3737
|
exports: [],
|
|
3695
3738
|
generation: {
|
|
3696
3739
|
generator: "@openpkg-ts/extract",
|
|
3697
|
-
timestamp: new Date().toISOString()
|
|
3740
|
+
timestamp: new Date().toISOString(),
|
|
3741
|
+
mode: isDtsSource ? "declaration-only" : "source",
|
|
3742
|
+
...isDtsSource && {
|
|
3743
|
+
limitations: ["No JSDoc descriptions", "No @example tags", "No @param descriptions"]
|
|
3744
|
+
}
|
|
3698
3745
|
}
|
|
3699
3746
|
};
|
|
3700
3747
|
}
|
package/dist/src/index.d.ts
CHANGED
|
@@ -43,7 +43,7 @@ declare class TypeRegistry {
|
|
|
43
43
|
}
|
|
44
44
|
import { SpecExample, SpecSource, SpecTag, SpecTypeParameter } from "@openpkg-ts/spec";
|
|
45
45
|
import ts3 from "typescript";
|
|
46
|
-
declare function getJSDocComment(node: ts3.Node): {
|
|
46
|
+
declare function getJSDocComment(node: ts3.Node, symbol?: ts3.Symbol, checker?: ts3.TypeChecker): {
|
|
47
47
|
description?: string;
|
|
48
48
|
tags: SpecTag[];
|
|
49
49
|
examples: SpecExample[];
|
|
@@ -237,6 +237,10 @@ interface ExtractOptions {
|
|
|
237
237
|
only?: string[];
|
|
238
238
|
/** Ignore these exports (supports * wildcards) */
|
|
239
239
|
ignore?: string[];
|
|
240
|
+
/** Progress callback for tracking extraction progress */
|
|
241
|
+
onProgress?: (current: number, total: number, item: string) => void;
|
|
242
|
+
/** Whether source is a .d.ts file (degraded mode - TSDoc may be missing) */
|
|
243
|
+
isDtsSource?: boolean;
|
|
240
244
|
}
|
|
241
245
|
interface ExtractResult {
|
|
242
246
|
spec: OpenPkg;
|
|
@@ -255,6 +259,15 @@ interface ExtractResult {
|
|
|
255
259
|
/** Extraction method used: 'compiled' or 'direct-ts (runtime)' */
|
|
256
260
|
method?: string;
|
|
257
261
|
};
|
|
262
|
+
/** Degraded mode info when extracting from .d.ts files */
|
|
263
|
+
degradedMode?: {
|
|
264
|
+
reason: "dts-source";
|
|
265
|
+
stats: {
|
|
266
|
+
exportsWithoutDescription: number;
|
|
267
|
+
paramsWithoutDocs: number;
|
|
268
|
+
missingExamples: number;
|
|
269
|
+
};
|
|
270
|
+
};
|
|
258
271
|
}
|
|
259
272
|
interface Diagnostic {
|
|
260
273
|
message: string;
|
package/dist/src/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openpkg-ts/extract",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.26.0",
|
|
4
4
|
"description": "TypeScript export extraction to OpenPkg spec",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"openpkg",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"format": "biome format --write src/"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@openpkg-ts/spec": "^0.
|
|
43
|
+
"@openpkg-ts/spec": "^0.26.0",
|
|
44
44
|
"chalk": "^5.4.1",
|
|
45
45
|
"commander": "^12.0.0",
|
|
46
46
|
"tree-sitter-wasms": "^0.1.13",
|