@doccov/sdk 0.27.0 → 0.27.3
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/analysis/index.js +1 -1
- package/dist/index.d.ts +15 -129
- package/dist/index.js +7 -184
- package/dist/shared/{chunk-v62zsv8j.js → chunk-v1vce2mg.js} +91 -209
- package/package.json +2 -2
package/dist/analysis/index.js
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -1498,10 +1498,18 @@ interface JSDocTag {
|
|
|
1498
1498
|
/**
|
|
1499
1499
|
* A patchable representation of a JSDoc comment
|
|
1500
1500
|
*/
|
|
1501
|
+
/**
|
|
1502
|
+
* Represents a @throws tag in a JSDoc patch
|
|
1503
|
+
*/
|
|
1504
|
+
interface JSDocThrows {
|
|
1505
|
+
type?: string;
|
|
1506
|
+
description?: string;
|
|
1507
|
+
}
|
|
1501
1508
|
interface JSDocPatch {
|
|
1502
1509
|
description?: string;
|
|
1503
1510
|
params?: JSDocParam[];
|
|
1504
1511
|
returns?: JSDocReturn;
|
|
1512
|
+
throws?: JSDocThrows[];
|
|
1505
1513
|
examples?: string[];
|
|
1506
1514
|
deprecated?: string | false;
|
|
1507
1515
|
async?: boolean;
|
|
@@ -2131,143 +2139,21 @@ interface SchemaDetectionResult {
|
|
|
2131
2139
|
}
|
|
2132
2140
|
declare function detectRuntimeSchemas(context: SchemaDetectionContext): Promise<SchemaDetectionResult>;
|
|
2133
2141
|
import * as TS2 from "typescript";
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
* schema validation library.
|
|
2137
|
-
*/
|
|
2138
|
-
interface SchemaAdapter {
|
|
2139
|
-
/** Unique identifier for this adapter */
|
|
2140
|
-
readonly id: string;
|
|
2141
|
-
/** npm package name(s) this adapter handles */
|
|
2142
|
-
readonly packages: readonly string[];
|
|
2143
|
-
/**
|
|
2144
|
-
* Check if a type matches this adapter's schema library.
|
|
2145
|
-
* Should be fast - called for every export.
|
|
2146
|
-
*/
|
|
2147
|
-
matches(type: TS2.Type, checker: TS2.TypeChecker): boolean;
|
|
2148
|
-
/**
|
|
2149
|
-
* Extract the output type from a schema type.
|
|
2150
|
-
* Returns null if extraction fails.
|
|
2151
|
-
*/
|
|
2152
|
-
extractOutputType(type: TS2.Type, checker: TS2.TypeChecker): TS2.Type | null;
|
|
2153
|
-
/**
|
|
2154
|
-
* Extract the input type from a schema type (optional).
|
|
2155
|
-
* Useful for transforms where input differs from output.
|
|
2156
|
-
*/
|
|
2157
|
-
extractInputType?(type: TS2.Type, checker: TS2.TypeChecker): TS2.Type | null;
|
|
2158
|
-
}
|
|
2159
|
-
/**
|
|
2160
|
-
* Result of schema type extraction
|
|
2161
|
-
*/
|
|
2162
|
-
interface SchemaExtractionResult {
|
|
2163
|
-
/** The adapter that matched */
|
|
2164
|
-
adapter: SchemaAdapter;
|
|
2165
|
-
/** The extracted output type */
|
|
2166
|
-
outputType: TS2.Type;
|
|
2167
|
-
/** The extracted input type (if different from output) */
|
|
2168
|
-
inputType?: TS2.Type;
|
|
2169
|
-
}
|
|
2170
|
-
import * as TS3 from "typescript";
|
|
2171
|
-
/**
|
|
2172
|
-
* Find an adapter that matches the given type.
|
|
2173
|
-
* Returns null if no adapter matches.
|
|
2174
|
-
*/
|
|
2175
|
-
declare function findAdapter(type: TS3.Type, checker: TS3.TypeChecker): SchemaAdapter | null;
|
|
2176
|
-
/**
|
|
2177
|
-
* Check if a type is from a recognized schema library.
|
|
2178
|
-
*/
|
|
2179
|
-
declare function isSchemaType(type: TS3.Type, checker: TS3.TypeChecker): boolean;
|
|
2142
|
+
import { extractSchemaType, findAdapter, isSchemaType, extractStandardSchemas, extractStandardSchemasFromProject, isStandardJSONSchema, resolveCompiledPath, ExtractStandardSchemasOptions, SchemaAdapter, SchemaExtractionResult, StandardJSONSchemaV1, StandardSchemaExtractionOutput, StandardSchemaExtractionResult } from "@openpkg-ts/extract";
|
|
2143
|
+
import { SchemaAdapter as SchemaAdapter2 } from "@openpkg-ts/extract";
|
|
2180
2144
|
/**
|
|
2181
2145
|
* Extract the output type from a schema type.
|
|
2182
|
-
*
|
|
2183
|
-
* - The type is not from a recognized schema library
|
|
2184
|
-
* - The adapter fails to extract the output type
|
|
2146
|
+
* Convenience wrapper that returns just the type.
|
|
2185
2147
|
*/
|
|
2186
|
-
declare function extractSchemaOutputType(type:
|
|
2187
|
-
/**
|
|
2188
|
-
* Full extraction with adapter info.
|
|
2189
|
-
* Useful when you need to know which library was detected.
|
|
2190
|
-
*/
|
|
2191
|
-
declare function extractSchemaType(type: TS3.Type, checker: TS3.TypeChecker): SchemaExtractionResult | null;
|
|
2148
|
+
declare function extractSchemaOutputType(type: TS2.Type, checker: TS2.TypeChecker): TS2.Type | null;
|
|
2192
2149
|
/**
|
|
2193
2150
|
* Get all registered adapters.
|
|
2194
|
-
* Useful for logging/debugging.
|
|
2195
2151
|
*/
|
|
2196
|
-
declare function getRegisteredAdapters(): readonly
|
|
2152
|
+
declare function getRegisteredAdapters(): readonly SchemaAdapter2[];
|
|
2197
2153
|
/**
|
|
2198
2154
|
* Get supported library names.
|
|
2199
|
-
* Useful for documentation/help output.
|
|
2200
2155
|
*/
|
|
2201
2156
|
declare function getSupportedLibraries(): readonly string[];
|
|
2202
|
-
/**
|
|
2203
|
-
* Standard JSON Schema v1 interface (minimal for detection).
|
|
2204
|
-
*/
|
|
2205
|
-
interface StandardJSONSchemaV1 {
|
|
2206
|
-
"~standard": {
|
|
2207
|
-
version: number;
|
|
2208
|
-
vendor: string;
|
|
2209
|
-
jsonSchema?: {
|
|
2210
|
-
output: (target?: string) => Record<string, unknown>;
|
|
2211
|
-
input?: (target?: string) => Record<string, unknown>;
|
|
2212
|
-
};
|
|
2213
|
-
};
|
|
2214
|
-
}
|
|
2215
|
-
/**
|
|
2216
|
-
* Result of extracting Standard Schema from an export.
|
|
2217
|
-
*/
|
|
2218
|
-
interface StandardSchemaExtractionResult {
|
|
2219
|
-
exportName: string;
|
|
2220
|
-
vendor: string;
|
|
2221
|
-
outputSchema: Record<string, unknown>;
|
|
2222
|
-
inputSchema?: Record<string, unknown>;
|
|
2223
|
-
}
|
|
2224
|
-
/**
|
|
2225
|
-
* Options for runtime Standard Schema extraction.
|
|
2226
|
-
*/
|
|
2227
|
-
interface ExtractStandardSchemasOptions {
|
|
2228
|
-
/** Timeout in milliseconds (default: 10000) */
|
|
2229
|
-
timeout?: number;
|
|
2230
|
-
/** JSON Schema target version (default: 'draft-2020-12') */
|
|
2231
|
-
target?: "draft-2020-12" | "draft-07" | "openapi-3.0";
|
|
2232
|
-
}
|
|
2233
|
-
/**
|
|
2234
|
-
* Result of Standard Schema extraction.
|
|
2235
|
-
*/
|
|
2236
|
-
interface StandardSchemaExtractionOutput {
|
|
2237
|
-
schemas: Map<string, StandardSchemaExtractionResult>;
|
|
2238
|
-
errors: string[];
|
|
2239
|
-
}
|
|
2240
|
-
/**
|
|
2241
|
-
* Check if an object implements StandardJSONSchemaV1.
|
|
2242
|
-
* This is a static type guard - doesn't require runtime.
|
|
2243
|
-
*/
|
|
2244
|
-
declare function isStandardJSONSchema(obj: unknown): obj is StandardJSONSchemaV1;
|
|
2245
|
-
/**
|
|
2246
|
-
* Resolve compiled JS path from TypeScript source.
|
|
2247
|
-
* Tries common output locations: dist/, build/, lib/, same dir.
|
|
2248
|
-
*/
|
|
2249
|
-
declare function resolveCompiledPath(tsPath: string, baseDir: string): string | null;
|
|
2250
|
-
/**
|
|
2251
|
-
* Extract Standard Schema JSON Schemas from a compiled JS module.
|
|
2252
|
-
*
|
|
2253
|
-
* **Security Note**: This executes the module in a subprocess.
|
|
2254
|
-
* Only use with trusted code (user's own packages).
|
|
2255
|
-
*
|
|
2256
|
-
* @param compiledJsPath - Path to compiled .js file
|
|
2257
|
-
* @param options - Extraction options
|
|
2258
|
-
* @returns Extraction results with schemas and any errors
|
|
2259
|
-
*/
|
|
2260
|
-
declare function extractStandardSchemas(compiledJsPath: string, options?: ExtractStandardSchemasOptions): Promise<StandardSchemaExtractionOutput>;
|
|
2261
|
-
/**
|
|
2262
|
-
* Extract Standard Schema from a TypeScript project.
|
|
2263
|
-
*
|
|
2264
|
-
* Convenience function that resolves compiled JS and extracts schemas.
|
|
2265
|
-
*
|
|
2266
|
-
* @param entryFile - TypeScript entry file path
|
|
2267
|
-
* @param baseDir - Project base directory
|
|
2268
|
-
* @param options - Extraction options
|
|
2269
|
-
*/
|
|
2270
|
-
declare function extractStandardSchemasFromProject(entryFile: string, baseDir: string, options?: ExtractStandardSchemasOptions): Promise<StandardSchemaExtractionOutput>;
|
|
2271
2157
|
declare function extractPackageSpec(entryFile: string, packageDir?: string, content?: string, options?: DocCovOptions): Promise<OpenPkgSpec>;
|
|
2272
2158
|
/**
|
|
2273
2159
|
* Source of filter options.
|
|
@@ -2679,7 +2565,7 @@ interface SpecSummary {
|
|
|
2679
2565
|
* ```
|
|
2680
2566
|
*/
|
|
2681
2567
|
declare function extractSpecSummary(openpkg: OpenPkg8, doccov: DocCovSpec4): SpecSummary;
|
|
2682
|
-
import { OpenPkg as
|
|
2568
|
+
import { OpenPkg as OpenPkg_jkmegcwtaf } from "@openpkg-ts/spec";
|
|
2683
2569
|
/**
|
|
2684
2570
|
* Build Plan types for AI-powered repository scanning.
|
|
2685
2571
|
*/
|
|
@@ -2776,7 +2662,7 @@ interface BuildPlanExecutionResult {
|
|
|
2776
2662
|
/** Whether all required steps succeeded */
|
|
2777
2663
|
success: boolean;
|
|
2778
2664
|
/** Generated OpenPkg spec (if successful) */
|
|
2779
|
-
spec?:
|
|
2665
|
+
spec?: OpenPkg_jkmegcwtaf;
|
|
2780
2666
|
/** Results for each step */
|
|
2781
2667
|
stepResults: BuildPlanStepResult[];
|
|
2782
2668
|
/** Total execution time in milliseconds */
|
package/dist/index.js
CHANGED
|
@@ -21,8 +21,11 @@ import {
|
|
|
21
21
|
detectExampleRuntimeErrors,
|
|
22
22
|
detectRuntimeSchemas,
|
|
23
23
|
ensureSpecCoverage,
|
|
24
|
+
extractSchemaOutputType,
|
|
25
|
+
extractSchemaType,
|
|
24
26
|
extractStandardSchemas,
|
|
25
27
|
extractStandardSchemasFromProject,
|
|
28
|
+
findAdapter,
|
|
26
29
|
findJSDocLocation,
|
|
27
30
|
formatDelta,
|
|
28
31
|
formatDriftSummaryLine,
|
|
@@ -37,6 +40,8 @@ import {
|
|
|
37
40
|
getExportMissing,
|
|
38
41
|
getExportScore,
|
|
39
42
|
getExtendedTrend,
|
|
43
|
+
getRegisteredAdapters,
|
|
44
|
+
getSupportedLibraries,
|
|
40
45
|
getTrend,
|
|
41
46
|
groupDriftsByCategory,
|
|
42
47
|
groupFixesByFile,
|
|
@@ -44,6 +49,7 @@ import {
|
|
|
44
49
|
isBuiltInIdentifier,
|
|
45
50
|
isExportFullyDocumented,
|
|
46
51
|
isFixableDrift,
|
|
52
|
+
isSchemaType,
|
|
47
53
|
isStandardJSONSchema,
|
|
48
54
|
loadCachedReport,
|
|
49
55
|
loadSnapshots,
|
|
@@ -60,7 +66,7 @@ import {
|
|
|
60
66
|
saveSnapshot,
|
|
61
67
|
serializeJSDoc,
|
|
62
68
|
ts
|
|
63
|
-
} from "./shared/chunk-
|
|
69
|
+
} from "./shared/chunk-v1vce2mg.js";
|
|
64
70
|
import {
|
|
65
71
|
mergeFilters,
|
|
66
72
|
parseListFlag
|
|
@@ -419,189 +425,6 @@ function getSpecCachePath(cwd) {
|
|
|
419
425
|
}
|
|
420
426
|
// src/extractor.ts
|
|
421
427
|
import * as path6 from "node:path";
|
|
422
|
-
|
|
423
|
-
// src/extract/schema/types.ts
|
|
424
|
-
function isTypeReference(type) {
|
|
425
|
-
return !!(type.flags & 524288 && type.objectFlags && type.objectFlags & 4);
|
|
426
|
-
}
|
|
427
|
-
function getNonNullableType(type) {
|
|
428
|
-
if (type.isUnion()) {
|
|
429
|
-
const nonNullable = type.types.filter((t) => !(t.flags & 32768) && !(t.flags & 65536));
|
|
430
|
-
if (nonNullable.length === 1) {
|
|
431
|
-
return nonNullable[0];
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
return type;
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
// src/extract/schema/adapters/arktype.ts
|
|
438
|
-
var ARKTYPE_TYPE_PATTERN = /^Type</;
|
|
439
|
-
var arktypeAdapter = {
|
|
440
|
-
id: "arktype",
|
|
441
|
-
packages: ["arktype"],
|
|
442
|
-
matches(type, checker) {
|
|
443
|
-
const typeName = checker.typeToString(type);
|
|
444
|
-
return ARKTYPE_TYPE_PATTERN.test(typeName);
|
|
445
|
-
},
|
|
446
|
-
extractOutputType(type, checker) {
|
|
447
|
-
if (!isTypeReference(type)) {
|
|
448
|
-
return null;
|
|
449
|
-
}
|
|
450
|
-
const args = checker.getTypeArguments(type);
|
|
451
|
-
if (args.length < 1) {
|
|
452
|
-
return null;
|
|
453
|
-
}
|
|
454
|
-
return args[0];
|
|
455
|
-
},
|
|
456
|
-
extractInputType(type, checker) {
|
|
457
|
-
if (!isTypeReference(type)) {
|
|
458
|
-
return null;
|
|
459
|
-
}
|
|
460
|
-
const args = checker.getTypeArguments(type);
|
|
461
|
-
if (args.length < 2) {
|
|
462
|
-
return null;
|
|
463
|
-
}
|
|
464
|
-
return args[1];
|
|
465
|
-
}
|
|
466
|
-
};
|
|
467
|
-
// src/extract/schema/adapters/typebox.ts
|
|
468
|
-
var TYPEBOX_TYPE_PATTERN = /^T[A-Z]/;
|
|
469
|
-
var typeboxAdapter = {
|
|
470
|
-
id: "typebox",
|
|
471
|
-
packages: ["@sinclair/typebox"],
|
|
472
|
-
matches(type, checker) {
|
|
473
|
-
const typeName = checker.typeToString(type);
|
|
474
|
-
if (!TYPEBOX_TYPE_PATTERN.test(typeName)) {
|
|
475
|
-
return false;
|
|
476
|
-
}
|
|
477
|
-
const typeProperty = type.getProperty("type");
|
|
478
|
-
return typeProperty !== undefined;
|
|
479
|
-
},
|
|
480
|
-
extractOutputType(type, checker) {
|
|
481
|
-
const staticSymbol = type.getProperty("static");
|
|
482
|
-
if (staticSymbol) {
|
|
483
|
-
return checker.getTypeOfSymbol(staticSymbol);
|
|
484
|
-
}
|
|
485
|
-
return null;
|
|
486
|
-
}
|
|
487
|
-
};
|
|
488
|
-
// src/extract/schema/adapters/valibot.ts
|
|
489
|
-
var VALIBOT_TYPE_PATTERN = /Schema(<|$)/;
|
|
490
|
-
var valibotAdapter = {
|
|
491
|
-
id: "valibot",
|
|
492
|
-
packages: ["valibot"],
|
|
493
|
-
matches(type, checker) {
|
|
494
|
-
const typeName = checker.typeToString(type);
|
|
495
|
-
return VALIBOT_TYPE_PATTERN.test(typeName) && !typeName.includes("Zod");
|
|
496
|
-
},
|
|
497
|
-
extractOutputType(type, checker) {
|
|
498
|
-
const typesSymbol = type.getProperty("~types");
|
|
499
|
-
if (!typesSymbol) {
|
|
500
|
-
return null;
|
|
501
|
-
}
|
|
502
|
-
let typesType = checker.getTypeOfSymbol(typesSymbol);
|
|
503
|
-
typesType = getNonNullableType(typesType);
|
|
504
|
-
const outputSymbol = typesType.getProperty("output");
|
|
505
|
-
if (!outputSymbol) {
|
|
506
|
-
return null;
|
|
507
|
-
}
|
|
508
|
-
return checker.getTypeOfSymbol(outputSymbol);
|
|
509
|
-
},
|
|
510
|
-
extractInputType(type, checker) {
|
|
511
|
-
const typesSymbol = type.getProperty("~types");
|
|
512
|
-
if (!typesSymbol) {
|
|
513
|
-
return null;
|
|
514
|
-
}
|
|
515
|
-
let typesType = checker.getTypeOfSymbol(typesSymbol);
|
|
516
|
-
typesType = getNonNullableType(typesType);
|
|
517
|
-
const inputSymbol = typesType.getProperty("input");
|
|
518
|
-
if (!inputSymbol) {
|
|
519
|
-
return null;
|
|
520
|
-
}
|
|
521
|
-
return checker.getTypeOfSymbol(inputSymbol);
|
|
522
|
-
}
|
|
523
|
-
};
|
|
524
|
-
// src/extract/schema/adapters/zod.ts
|
|
525
|
-
var ZOD_TYPE_PATTERN = /^Zod[A-Z]/;
|
|
526
|
-
var zodAdapter = {
|
|
527
|
-
id: "zod",
|
|
528
|
-
packages: ["zod"],
|
|
529
|
-
matches(type, checker) {
|
|
530
|
-
const typeName = checker.typeToString(type);
|
|
531
|
-
return ZOD_TYPE_PATTERN.test(typeName);
|
|
532
|
-
},
|
|
533
|
-
extractOutputType(type, checker) {
|
|
534
|
-
const outputSymbol = type.getProperty("_output");
|
|
535
|
-
if (outputSymbol) {
|
|
536
|
-
return checker.getTypeOfSymbol(outputSymbol);
|
|
537
|
-
}
|
|
538
|
-
const typeSymbol = type.getProperty("_type");
|
|
539
|
-
if (typeSymbol) {
|
|
540
|
-
return checker.getTypeOfSymbol(typeSymbol);
|
|
541
|
-
}
|
|
542
|
-
return null;
|
|
543
|
-
},
|
|
544
|
-
extractInputType(type, checker) {
|
|
545
|
-
const inputSymbol = type.getProperty("_input");
|
|
546
|
-
if (inputSymbol) {
|
|
547
|
-
return checker.getTypeOfSymbol(inputSymbol);
|
|
548
|
-
}
|
|
549
|
-
return null;
|
|
550
|
-
}
|
|
551
|
-
};
|
|
552
|
-
// src/extract/schema/registry.ts
|
|
553
|
-
var adapters = [
|
|
554
|
-
zodAdapter,
|
|
555
|
-
arktypeAdapter,
|
|
556
|
-
typeboxAdapter,
|
|
557
|
-
valibotAdapter
|
|
558
|
-
];
|
|
559
|
-
function findAdapter(type, checker) {
|
|
560
|
-
for (const adapter of adapters) {
|
|
561
|
-
if (adapter.matches(type, checker)) {
|
|
562
|
-
return adapter;
|
|
563
|
-
}
|
|
564
|
-
}
|
|
565
|
-
return null;
|
|
566
|
-
}
|
|
567
|
-
function isSchemaType(type, checker) {
|
|
568
|
-
return findAdapter(type, checker) !== null;
|
|
569
|
-
}
|
|
570
|
-
function extractSchemaOutputType(type, checker) {
|
|
571
|
-
const adapter = findAdapter(type, checker);
|
|
572
|
-
if (!adapter) {
|
|
573
|
-
return null;
|
|
574
|
-
}
|
|
575
|
-
return adapter.extractOutputType(type, checker);
|
|
576
|
-
}
|
|
577
|
-
function extractSchemaType(type, checker) {
|
|
578
|
-
const adapter = findAdapter(type, checker);
|
|
579
|
-
if (!adapter) {
|
|
580
|
-
return null;
|
|
581
|
-
}
|
|
582
|
-
const outputType = adapter.extractOutputType(type, checker);
|
|
583
|
-
if (!outputType) {
|
|
584
|
-
return null;
|
|
585
|
-
}
|
|
586
|
-
const result = {
|
|
587
|
-
adapter,
|
|
588
|
-
outputType
|
|
589
|
-
};
|
|
590
|
-
if (adapter.extractInputType) {
|
|
591
|
-
const inputType = adapter.extractInputType(type, checker);
|
|
592
|
-
if (inputType) {
|
|
593
|
-
result.inputType = inputType;
|
|
594
|
-
}
|
|
595
|
-
}
|
|
596
|
-
return result;
|
|
597
|
-
}
|
|
598
|
-
function getRegisteredAdapters() {
|
|
599
|
-
return adapters;
|
|
600
|
-
}
|
|
601
|
-
function getSupportedLibraries() {
|
|
602
|
-
return adapters.flatMap((a) => a.packages);
|
|
603
|
-
}
|
|
604
|
-
// src/extractor.ts
|
|
605
428
|
async function extractPackageSpec(entryFile, packageDir, content, options) {
|
|
606
429
|
const baseDir = packageDir ?? path6.dirname(entryFile);
|
|
607
430
|
const schemaMode = options?.schemaExtraction ?? "static";
|
|
@@ -546,6 +546,21 @@ function parseJSDocToPatch(jsDocText) {
|
|
|
546
546
|
patch.deprecated = content || "Deprecated";
|
|
547
547
|
break;
|
|
548
548
|
}
|
|
549
|
+
case "throws":
|
|
550
|
+
case "throw": {
|
|
551
|
+
if (!patch.throws)
|
|
552
|
+
patch.throws = [];
|
|
553
|
+
const throwsMatch = content.match(/^(?:\{@?link\s+([^}]+)\}|\{([^}]+)\})?\s*(.*)$/s);
|
|
554
|
+
if (throwsMatch) {
|
|
555
|
+
patch.throws.push({
|
|
556
|
+
type: (throwsMatch[1] || throwsMatch[2])?.trim(),
|
|
557
|
+
description: throwsMatch[3]?.trim()
|
|
558
|
+
});
|
|
559
|
+
} else {
|
|
560
|
+
patch.throws.push({ description: content.trim() });
|
|
561
|
+
}
|
|
562
|
+
break;
|
|
563
|
+
}
|
|
549
564
|
case "async": {
|
|
550
565
|
patch.async = true;
|
|
551
566
|
break;
|
|
@@ -620,6 +635,9 @@ function applyPatchToJSDoc(existing, updates) {
|
|
|
620
635
|
...updates.returns
|
|
621
636
|
};
|
|
622
637
|
}
|
|
638
|
+
if (updates.throws !== undefined) {
|
|
639
|
+
result.throws = updates.throws;
|
|
640
|
+
}
|
|
623
641
|
if (updates.examples !== undefined) {
|
|
624
642
|
result.examples = updates.examples;
|
|
625
643
|
}
|
|
@@ -643,7 +661,7 @@ function serializeJSDoc(patch, indent = "") {
|
|
|
643
661
|
lines.push(line);
|
|
644
662
|
}
|
|
645
663
|
}
|
|
646
|
-
const hasTags = patch.params?.length || patch.returns || patch.examples?.length || patch.deprecated || patch.async || patch.type || patch.typeParams?.length || patch.otherTags?.length;
|
|
664
|
+
const hasTags = patch.params?.length || patch.returns || patch.throws?.length || patch.examples?.length || patch.deprecated || patch.async || patch.type || patch.typeParams?.length || patch.otherTags?.length;
|
|
647
665
|
if (patch.description && hasTags) {
|
|
648
666
|
lines.push("");
|
|
649
667
|
}
|
|
@@ -689,6 +707,18 @@ function serializeJSDoc(patch, indent = "") {
|
|
|
689
707
|
}
|
|
690
708
|
lines.push(tagLine);
|
|
691
709
|
}
|
|
710
|
+
if (patch.throws) {
|
|
711
|
+
for (const t of patch.throws) {
|
|
712
|
+
let tagLine = "@throws";
|
|
713
|
+
if (t.type) {
|
|
714
|
+
tagLine += ` {${t.type}}`;
|
|
715
|
+
}
|
|
716
|
+
if (t.description) {
|
|
717
|
+
tagLine += ` ${t.description}`;
|
|
718
|
+
}
|
|
719
|
+
lines.push(tagLine);
|
|
720
|
+
}
|
|
721
|
+
}
|
|
692
722
|
if (patch.deprecated && typeof patch.deprecated === "string") {
|
|
693
723
|
lines.push(`@deprecated ${patch.deprecated}`);
|
|
694
724
|
}
|
|
@@ -2765,195 +2795,47 @@ function renderApiSurface(spec) {
|
|
|
2765
2795
|
`);
|
|
2766
2796
|
}
|
|
2767
2797
|
|
|
2768
|
-
// src/extract/schema/
|
|
2769
|
-
import {
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
return typeof obj.type === 'string' || 'anyOf' in obj || 'oneOf' in obj || 'allOf' in obj;
|
|
2802
|
-
}
|
|
2803
|
-
|
|
2804
|
-
function sanitizeTypeBoxSchema(schema) {
|
|
2805
|
-
// JSON.stringify removes symbol keys, keeping only JSON Schema props
|
|
2806
|
-
return JSON.parse(JSON.stringify(schema));
|
|
2807
|
-
}
|
|
2808
|
-
|
|
2809
|
-
async function extract() {
|
|
2810
|
-
// With node -e, argv is: [node, arg1, arg2, ...]
|
|
2811
|
-
// (the -e script is NOT in argv)
|
|
2812
|
-
const [modulePath, target] = process.argv.slice(1);
|
|
2813
|
-
|
|
2814
|
-
try {
|
|
2815
|
-
// Import the module using dynamic import (works with ESM and CJS)
|
|
2816
|
-
const absPath = path.resolve(modulePath);
|
|
2817
|
-
const mod = await import(pathToFileURL(absPath).href);
|
|
2818
|
-
const results = [];
|
|
2819
|
-
|
|
2820
|
-
// Build exports map - handle both ESM and CJS (where exports are in mod.default)
|
|
2821
|
-
const exports = {};
|
|
2822
|
-
for (const [name, value] of Object.entries(mod)) {
|
|
2823
|
-
if (name === 'default' && typeof value === 'object' && value !== null) {
|
|
2824
|
-
// CJS module: spread default exports
|
|
2825
|
-
Object.assign(exports, value);
|
|
2826
|
-
} else if (name !== 'default') {
|
|
2827
|
-
exports[name] = value;
|
|
2828
|
-
}
|
|
2829
|
-
}
|
|
2830
|
-
|
|
2831
|
-
// Check each export
|
|
2832
|
-
for (const [name, value] of Object.entries(exports)) {
|
|
2833
|
-
if (name.startsWith('_')) continue;
|
|
2834
|
-
if (typeof value !== 'object' || value === null) continue;
|
|
2835
|
-
|
|
2836
|
-
// Priority 1: Standard Schema (Zod 4.2+, ArkType, etc.)
|
|
2837
|
-
const std = value['~standard'];
|
|
2838
|
-
if (std && typeof std === 'object' && typeof std.version === 'number' && typeof std.vendor === 'string' && std.jsonSchema && typeof std.jsonSchema.output === 'function') {
|
|
2839
|
-
try {
|
|
2840
|
-
const outputSchema = std.jsonSchema.output(target);
|
|
2841
|
-
const inputSchema = std.jsonSchema.input ? std.jsonSchema.input(target) : undefined;
|
|
2842
|
-
results.push({
|
|
2843
|
-
exportName: name,
|
|
2844
|
-
vendor: std.vendor,
|
|
2845
|
-
outputSchema,
|
|
2846
|
-
inputSchema
|
|
2847
|
-
});
|
|
2848
|
-
} catch (e) {
|
|
2849
|
-
// Skip schemas that fail to extract
|
|
2850
|
-
}
|
|
2851
|
-
continue;
|
|
2852
|
-
}
|
|
2853
|
-
|
|
2854
|
-
// Priority 2: TypeBox (schema IS JSON Schema)
|
|
2855
|
-
if (isTypeBoxSchema(value)) {
|
|
2856
|
-
try {
|
|
2857
|
-
results.push({
|
|
2858
|
-
exportName: name,
|
|
2859
|
-
vendor: 'typebox',
|
|
2860
|
-
outputSchema: sanitizeTypeBoxSchema(value)
|
|
2861
|
-
});
|
|
2862
|
-
} catch (e) {
|
|
2863
|
-
// Skip schemas that fail to extract
|
|
2864
|
-
}
|
|
2865
|
-
continue;
|
|
2866
|
-
}
|
|
2867
|
-
}
|
|
2868
|
-
|
|
2869
|
-
console.log(JSON.stringify({ success: true, results }));
|
|
2870
|
-
} catch (e) {
|
|
2871
|
-
console.log(JSON.stringify({ success: false, error: e.message }));
|
|
2872
|
-
}
|
|
2873
|
-
}
|
|
2874
|
-
|
|
2875
|
-
extract();
|
|
2876
|
-
`;
|
|
2877
|
-
function resolveCompiledPath(tsPath, baseDir) {
|
|
2878
|
-
const relativePath = path4.relative(baseDir, tsPath);
|
|
2879
|
-
const withoutExt = relativePath.replace(/\.tsx?$/, "");
|
|
2880
|
-
const candidates = [
|
|
2881
|
-
path4.join(baseDir, `${withoutExt}.js`),
|
|
2882
|
-
path4.join(baseDir, "dist", `${withoutExt.replace(/^src\//, "")}.js`),
|
|
2883
|
-
path4.join(baseDir, "build", `${withoutExt.replace(/^src\//, "")}.js`),
|
|
2884
|
-
path4.join(baseDir, "lib", `${withoutExt.replace(/^src\//, "")}.js`)
|
|
2885
|
-
];
|
|
2886
|
-
for (const candidate of candidates) {
|
|
2887
|
-
if (fs4.existsSync(candidate)) {
|
|
2888
|
-
return candidate;
|
|
2889
|
-
}
|
|
2798
|
+
// src/extract/schema/index.ts
|
|
2799
|
+
import {
|
|
2800
|
+
arktypeAdapter,
|
|
2801
|
+
typeboxAdapter,
|
|
2802
|
+
valibotAdapter,
|
|
2803
|
+
zodAdapter,
|
|
2804
|
+
extractSchemaType,
|
|
2805
|
+
findAdapter,
|
|
2806
|
+
isSchemaType,
|
|
2807
|
+
extractStandardSchemas,
|
|
2808
|
+
extractStandardSchemasFromProject,
|
|
2809
|
+
isStandardJSONSchema,
|
|
2810
|
+
resolveCompiledPath,
|
|
2811
|
+
getNonNullableType,
|
|
2812
|
+
isTypeReference
|
|
2813
|
+
} from "@openpkg-ts/extract";
|
|
2814
|
+
import {
|
|
2815
|
+
arktypeAdapter as arktypeAdapter2,
|
|
2816
|
+
findAdapter as findAdapter2,
|
|
2817
|
+
typeboxAdapter as typeboxAdapter2,
|
|
2818
|
+
valibotAdapter as valibotAdapter2,
|
|
2819
|
+
zodAdapter as zodAdapter2
|
|
2820
|
+
} from "@openpkg-ts/extract";
|
|
2821
|
+
var adapters = [
|
|
2822
|
+
zodAdapter2,
|
|
2823
|
+
arktypeAdapter2,
|
|
2824
|
+
typeboxAdapter2,
|
|
2825
|
+
valibotAdapter2
|
|
2826
|
+
];
|
|
2827
|
+
function extractSchemaOutputType(type, checker) {
|
|
2828
|
+
const adapter = findAdapter2(type, checker);
|
|
2829
|
+
if (!adapter) {
|
|
2830
|
+
return null;
|
|
2890
2831
|
}
|
|
2891
|
-
return
|
|
2832
|
+
return adapter.extractOutputType(type, checker);
|
|
2892
2833
|
}
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
const result = {
|
|
2896
|
-
schemas: new Map,
|
|
2897
|
-
errors: []
|
|
2898
|
-
};
|
|
2899
|
-
if (!fs4.existsSync(compiledJsPath)) {
|
|
2900
|
-
result.errors.push(`Compiled JS not found: ${compiledJsPath}`);
|
|
2901
|
-
return result;
|
|
2902
|
-
}
|
|
2903
|
-
return new Promise((resolve3) => {
|
|
2904
|
-
const child = spawn("node", ["-e", WORKER_SCRIPT, compiledJsPath, target], {
|
|
2905
|
-
timeout,
|
|
2906
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
2907
|
-
});
|
|
2908
|
-
let stdout = "";
|
|
2909
|
-
let stderr = "";
|
|
2910
|
-
child.stdout.on("data", (data) => {
|
|
2911
|
-
stdout += data.toString();
|
|
2912
|
-
});
|
|
2913
|
-
child.stderr.on("data", (data) => {
|
|
2914
|
-
stderr += data.toString();
|
|
2915
|
-
});
|
|
2916
|
-
child.on("close", (code) => {
|
|
2917
|
-
if (code !== 0) {
|
|
2918
|
-
result.errors.push(`Extraction process failed: ${stderr || `exit code ${code}`}`);
|
|
2919
|
-
resolve3(result);
|
|
2920
|
-
return;
|
|
2921
|
-
}
|
|
2922
|
-
try {
|
|
2923
|
-
const parsed = JSON.parse(stdout);
|
|
2924
|
-
if (!parsed.success) {
|
|
2925
|
-
result.errors.push(`Extraction failed: ${parsed.error}`);
|
|
2926
|
-
resolve3(result);
|
|
2927
|
-
return;
|
|
2928
|
-
}
|
|
2929
|
-
for (const item of parsed.results) {
|
|
2930
|
-
result.schemas.set(item.exportName, {
|
|
2931
|
-
exportName: item.exportName,
|
|
2932
|
-
vendor: item.vendor,
|
|
2933
|
-
outputSchema: item.outputSchema,
|
|
2934
|
-
inputSchema: item.inputSchema
|
|
2935
|
-
});
|
|
2936
|
-
}
|
|
2937
|
-
} catch (e) {
|
|
2938
|
-
result.errors.push(`Failed to parse extraction output: ${e}`);
|
|
2939
|
-
}
|
|
2940
|
-
resolve3(result);
|
|
2941
|
-
});
|
|
2942
|
-
child.on("error", (err) => {
|
|
2943
|
-
result.errors.push(`Subprocess error: ${err.message}`);
|
|
2944
|
-
resolve3(result);
|
|
2945
|
-
});
|
|
2946
|
-
});
|
|
2834
|
+
function getRegisteredAdapters() {
|
|
2835
|
+
return adapters;
|
|
2947
2836
|
}
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
if (!compiledPath) {
|
|
2951
|
-
return {
|
|
2952
|
-
schemas: new Map,
|
|
2953
|
-
errors: [`Could not find compiled JS for ${entryFile}. Build the project first.`]
|
|
2954
|
-
};
|
|
2955
|
-
}
|
|
2956
|
-
return extractStandardSchemas(compiledPath, options);
|
|
2837
|
+
function getSupportedLibraries() {
|
|
2838
|
+
return adapters.flatMap((a) => a.packages);
|
|
2957
2839
|
}
|
|
2958
2840
|
|
|
2959
2841
|
// src/analysis/schema-detection.ts
|
|
@@ -2982,8 +2864,8 @@ async function detectRuntimeSchemas(context) {
|
|
|
2982
2864
|
}
|
|
2983
2865
|
|
|
2984
2866
|
// src/analysis/history.ts
|
|
2985
|
-
import * as
|
|
2986
|
-
import * as
|
|
2867
|
+
import * as fs4 from "node:fs";
|
|
2868
|
+
import * as path4 from "node:path";
|
|
2987
2869
|
var HISTORY_DIR = ".doccov/history";
|
|
2988
2870
|
var RETENTION_DAYS = {
|
|
2989
2871
|
free: 7,
|
|
@@ -3021,24 +2903,24 @@ function computeSnapshot(spec, options) {
|
|
|
3021
2903
|
};
|
|
3022
2904
|
}
|
|
3023
2905
|
function saveSnapshot(snapshot, cwd) {
|
|
3024
|
-
const historyDir =
|
|
3025
|
-
if (!
|
|
3026
|
-
|
|
2906
|
+
const historyDir = path4.resolve(cwd, HISTORY_DIR);
|
|
2907
|
+
if (!fs4.existsSync(historyDir)) {
|
|
2908
|
+
fs4.mkdirSync(historyDir, { recursive: true });
|
|
3027
2909
|
}
|
|
3028
2910
|
const filename = getSnapshotFilename(new Date(snapshot.timestamp));
|
|
3029
|
-
const filepath =
|
|
3030
|
-
|
|
2911
|
+
const filepath = path4.join(historyDir, filename);
|
|
2912
|
+
fs4.writeFileSync(filepath, JSON.stringify(snapshot, null, 2));
|
|
3031
2913
|
}
|
|
3032
2914
|
function loadSnapshots(cwd) {
|
|
3033
|
-
const historyDir =
|
|
3034
|
-
if (!
|
|
2915
|
+
const historyDir = path4.resolve(cwd, HISTORY_DIR);
|
|
2916
|
+
if (!fs4.existsSync(historyDir)) {
|
|
3035
2917
|
return [];
|
|
3036
2918
|
}
|
|
3037
|
-
const files =
|
|
2919
|
+
const files = fs4.readdirSync(historyDir).filter((f) => f.endsWith(".json")).sort().reverse();
|
|
3038
2920
|
const snapshots = [];
|
|
3039
2921
|
for (const file of files) {
|
|
3040
2922
|
try {
|
|
3041
|
-
const content =
|
|
2923
|
+
const content = fs4.readFileSync(path4.join(historyDir, file), "utf-8");
|
|
3042
2924
|
snapshots.push(JSON.parse(content));
|
|
3043
2925
|
} catch {}
|
|
3044
2926
|
}
|
|
@@ -3078,15 +2960,15 @@ function formatDelta(delta) {
|
|
|
3078
2960
|
return "→0%";
|
|
3079
2961
|
}
|
|
3080
2962
|
function pruneHistory(cwd, keepCount = 100) {
|
|
3081
|
-
const historyDir =
|
|
3082
|
-
if (!
|
|
2963
|
+
const historyDir = path4.resolve(cwd, HISTORY_DIR);
|
|
2964
|
+
if (!fs4.existsSync(historyDir)) {
|
|
3083
2965
|
return 0;
|
|
3084
2966
|
}
|
|
3085
|
-
const files =
|
|
2967
|
+
const files = fs4.readdirSync(historyDir).filter((f) => f.endsWith(".json")).sort().reverse();
|
|
3086
2968
|
const toDelete = files.slice(keepCount);
|
|
3087
2969
|
for (const file of toDelete) {
|
|
3088
2970
|
try {
|
|
3089
|
-
|
|
2971
|
+
fs4.unlinkSync(path4.join(historyDir, file));
|
|
3090
2972
|
} catch {}
|
|
3091
2973
|
}
|
|
3092
2974
|
return toDelete.length;
|
|
@@ -3095,20 +2977,20 @@ function pruneByTier(cwd, tier) {
|
|
|
3095
2977
|
const retentionDays = RETENTION_DAYS[tier];
|
|
3096
2978
|
const cutoffDate = new Date;
|
|
3097
2979
|
cutoffDate.setDate(cutoffDate.getDate() - retentionDays);
|
|
3098
|
-
const historyDir =
|
|
3099
|
-
if (!
|
|
2980
|
+
const historyDir = path4.resolve(cwd, HISTORY_DIR);
|
|
2981
|
+
if (!fs4.existsSync(historyDir)) {
|
|
3100
2982
|
return 0;
|
|
3101
2983
|
}
|
|
3102
|
-
const files =
|
|
2984
|
+
const files = fs4.readdirSync(historyDir).filter((f) => f.endsWith(".json"));
|
|
3103
2985
|
let deleted = 0;
|
|
3104
2986
|
for (const file of files) {
|
|
3105
2987
|
try {
|
|
3106
|
-
const filepath =
|
|
3107
|
-
const content =
|
|
2988
|
+
const filepath = path4.join(historyDir, file);
|
|
2989
|
+
const content = fs4.readFileSync(filepath, "utf-8");
|
|
3108
2990
|
const snapshot = JSON.parse(content);
|
|
3109
2991
|
const snapshotDate = new Date(snapshot.timestamp);
|
|
3110
2992
|
if (snapshotDate < cutoffDate) {
|
|
3111
|
-
|
|
2993
|
+
fs4.unlinkSync(filepath);
|
|
3112
2994
|
deleted++;
|
|
3113
2995
|
}
|
|
3114
2996
|
} catch {}
|
|
@@ -3208,4 +3090,4 @@ function getExtendedTrend(spec, cwd, options) {
|
|
|
3208
3090
|
};
|
|
3209
3091
|
}
|
|
3210
3092
|
|
|
3211
|
-
export { computeHealth, isFixableDrift, generateFix, generateFixesForExport, mergeFixes, categorizeDrifts, ts, parseJSDocToPatch, applyPatchToJSDoc, serializeJSDoc, findJSDocLocation, applyEdits, createSourceFile, generateForgottenExportFixes, groupFixesByFile, applyForgottenExportFixes, previewForgottenExportFixes, isBuiltInIdentifier, detectExampleRuntimeErrors, parseAssertions, hasNonAssertionComments, detectExampleAssertionFailures, buildExportRegistry, computeDrift, computeExportDrift, buildDocCovSpec, DRIFT_CATEGORIES2 as DRIFT_CATEGORIES, DRIFT_CATEGORY_LABELS, DRIFT_CATEGORY_DESCRIPTIONS, categorizeDrift, groupDriftsByCategory, getDriftSummary, formatDriftSummaryLine, calculateAggregateCoverage, ensureSpecCoverage, getExportAnalysis, getExportScore, getExportDrift, getExportMissing, isExportFullyDocumented, generateReport, generateReportFromDocCov, loadCachedReport, saveReport, isCachedReportValid, renderApiSurface,
|
|
3093
|
+
export { computeHealth, isFixableDrift, generateFix, generateFixesForExport, mergeFixes, categorizeDrifts, ts, parseJSDocToPatch, applyPatchToJSDoc, serializeJSDoc, findJSDocLocation, applyEdits, createSourceFile, generateForgottenExportFixes, groupFixesByFile, applyForgottenExportFixes, previewForgottenExportFixes, isBuiltInIdentifier, detectExampleRuntimeErrors, parseAssertions, hasNonAssertionComments, detectExampleAssertionFailures, buildExportRegistry, computeDrift, computeExportDrift, buildDocCovSpec, DRIFT_CATEGORIES2 as DRIFT_CATEGORIES, DRIFT_CATEGORY_LABELS, DRIFT_CATEGORY_DESCRIPTIONS, categorizeDrift, groupDriftsByCategory, getDriftSummary, formatDriftSummaryLine, calculateAggregateCoverage, ensureSpecCoverage, getExportAnalysis, getExportScore, getExportDrift, getExportMissing, isExportFullyDocumented, generateReport, generateReportFromDocCov, loadCachedReport, saveReport, isCachedReportValid, renderApiSurface, extractSchemaOutputType, getRegisteredAdapters, getSupportedLibraries, extractSchemaType, findAdapter, isSchemaType, extractStandardSchemas, extractStandardSchemasFromProject, isStandardJSONSchema, resolveCompiledPath, detectRuntimeSchemas, HISTORY_DIR, RETENTION_DAYS, computeSnapshot, saveSnapshot, loadSnapshots, getTrend, renderSparkline, formatDelta, pruneHistory, pruneByTier, loadSnapshotsForDays, generateWeeklySummaries, getExtendedTrend };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@doccov/sdk",
|
|
3
|
-
"version": "0.27.
|
|
3
|
+
"version": "0.27.3",
|
|
4
4
|
"description": "DocCov SDK - Documentation coverage and drift detection for TypeScript",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"typescript",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
],
|
|
49
49
|
"dependencies": {
|
|
50
50
|
"@doccov/spec": "^0.27.0",
|
|
51
|
-
"@openpkg-ts/extract": "^0.16.
|
|
51
|
+
"@openpkg-ts/extract": "^0.16.1",
|
|
52
52
|
"@openpkg-ts/spec": "^0.12.0",
|
|
53
53
|
"@vercel/sandbox": "^1.0.3",
|
|
54
54
|
"mdast": "^3.0.0",
|