@doccov/sdk 0.11.0 → 0.13.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 +309 -208
- package/dist/index.js +299 -131
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -45,8 +45,8 @@ declare function runExamples(examples: string[], options?: RunExampleOptions): P
|
|
|
45
45
|
* runs all examples, then cleans up.
|
|
46
46
|
*/
|
|
47
47
|
declare function runExamplesWithPackage(examples: string[], options: RunExamplesWithPackageOptions): Promise<RunExamplesWithPackageResult>;
|
|
48
|
-
import { OpenPkg } from "@openpkg-ts/spec";
|
|
49
|
-
type OpenPkgSpec =
|
|
48
|
+
import { OpenPkg as OpenPkg2 } from "@openpkg-ts/spec";
|
|
49
|
+
type OpenPkgSpec = OpenPkg2;
|
|
50
50
|
/**
|
|
51
51
|
* Result of computing drift for a single export.
|
|
52
52
|
*/
|
|
@@ -177,7 +177,55 @@ declare function getDriftSummary(drifts: SpecDocDrift[]): DriftSummary;
|
|
|
177
177
|
* ```
|
|
178
178
|
*/
|
|
179
179
|
declare function formatDriftSummaryLine(summary: DriftSummary): string;
|
|
180
|
-
|
|
180
|
+
/**
|
|
181
|
+
* Calculate aggregate coverage score from a spec's exports.
|
|
182
|
+
*
|
|
183
|
+
* This is a lightweight function that calculates coverage without
|
|
184
|
+
* requiring full quality evaluation. It handles three cases:
|
|
185
|
+
* 1. Exports with `docs.coverageScore` - uses that value
|
|
186
|
+
* 2. Exports without score but with description - counts as 100%
|
|
187
|
+
* 3. Exports without score and no description - counts as 0%
|
|
188
|
+
*
|
|
189
|
+
* @param spec - The OpenPkg spec to calculate coverage for
|
|
190
|
+
* @returns The aggregate coverage score (0-100)
|
|
191
|
+
*
|
|
192
|
+
* @example
|
|
193
|
+
* ```ts
|
|
194
|
+
* import { calculateAggregateCoverage } from '@doccov/sdk';
|
|
195
|
+
*
|
|
196
|
+
* const coverage = calculateAggregateCoverage(spec);
|
|
197
|
+
* console.log(`Coverage: ${coverage}%`);
|
|
198
|
+
* ```
|
|
199
|
+
*/
|
|
200
|
+
declare function calculateAggregateCoverage(spec: OpenPkgSpec): number;
|
|
201
|
+
/**
|
|
202
|
+
* Ensure a spec has a top-level docs.coverageScore.
|
|
203
|
+
*
|
|
204
|
+
* If the spec already has `docs.coverageScore`, returns the spec unchanged.
|
|
205
|
+
* Otherwise, calculates aggregate coverage from exports and returns a
|
|
206
|
+
* new spec with the coverage score added.
|
|
207
|
+
*
|
|
208
|
+
* This is useful for commands like `diff` that need coverage scores
|
|
209
|
+
* but may receive raw specs that haven't been enriched.
|
|
210
|
+
*
|
|
211
|
+
* @param spec - The OpenPkg spec to ensure coverage for
|
|
212
|
+
* @returns The spec with guaranteed top-level coverage score
|
|
213
|
+
*
|
|
214
|
+
* @example
|
|
215
|
+
* ```ts
|
|
216
|
+
* import { ensureSpecCoverage } from '@doccov/sdk';
|
|
217
|
+
*
|
|
218
|
+
* // Works with raw or enriched specs
|
|
219
|
+
* const specWithCoverage = ensureSpecCoverage(rawSpec);
|
|
220
|
+
* console.log(specWithCoverage.docs?.coverageScore); // e.g., 85
|
|
221
|
+
* ```
|
|
222
|
+
*/
|
|
223
|
+
declare function ensureSpecCoverage(spec: OpenPkgSpec): OpenPkgSpec & {
|
|
224
|
+
docs: {
|
|
225
|
+
coverageScore: number;
|
|
226
|
+
};
|
|
227
|
+
};
|
|
228
|
+
import { OpenPkg as OpenPkg3, SpecDocDrift as SpecDocDrift2, SpecDocsMetadata, SpecExport as SpecExport3 } from "@openpkg-ts/spec";
|
|
181
229
|
import { SpecExport as SpecExport2, SpecExportKind } from "@openpkg-ts/spec";
|
|
182
230
|
import * as TS from "typescript";
|
|
183
231
|
/**
|
|
@@ -397,7 +445,7 @@ type EnrichedDocsMetadata = SpecDocsMetadata & {
|
|
|
397
445
|
* An enriched OpenPkg spec with computed documentation metadata.
|
|
398
446
|
* Extends OpenPkg with per-and aggregate coverage data.
|
|
399
447
|
*/
|
|
400
|
-
type EnrichedOpenPkg = Omit<
|
|
448
|
+
type EnrichedOpenPkg = Omit<OpenPkg3, "exports"> & {
|
|
401
449
|
exports: EnrichedExport[];
|
|
402
450
|
docs?: EnrichedDocsMetadata;
|
|
403
451
|
/** Drift summary with category breakdown (if drift exists) */
|
|
@@ -442,8 +490,8 @@ interface EnrichOptions {
|
|
|
442
490
|
* console.log(enriched.docs?.missing); // e.g., ['has-examples']
|
|
443
491
|
* ```
|
|
444
492
|
*/
|
|
445
|
-
declare function enrichSpec(spec:
|
|
446
|
-
import { OpenPkg as
|
|
493
|
+
declare function enrichSpec(spec: OpenPkg3, options?: EnrichOptions): EnrichedOpenPkg;
|
|
494
|
+
import { OpenPkg as OpenPkg4 } from "@openpkg-ts/spec";
|
|
447
495
|
import { DriftCategory as DriftCategory2, SpecDocDrift as SpecDocDrift3 } from "@openpkg-ts/spec";
|
|
448
496
|
/**
|
|
449
497
|
* DocCov report schema version.
|
|
@@ -476,6 +524,24 @@ declare const REPORT_EXTENSIONS: Record<string, string>;
|
|
|
476
524
|
*/
|
|
477
525
|
declare function getReportPath(format: string, dir?: string): string;
|
|
478
526
|
/**
|
|
527
|
+
* Get the report path for a diff comparison.
|
|
528
|
+
*
|
|
529
|
+
* Uses truncated hashes from both specs to create a unique, deterministic filename.
|
|
530
|
+
*
|
|
531
|
+
* @param baseHash - Hash of the base (before) spec
|
|
532
|
+
* @param headHash - Hash of the head (after) spec
|
|
533
|
+
* @param format - The report format (json, markdown, html, github)
|
|
534
|
+
* @param dir - The output directory (defaults to .doccov)
|
|
535
|
+
* @returns The full path to the diff report file
|
|
536
|
+
*
|
|
537
|
+
* @example
|
|
538
|
+
* ```ts
|
|
539
|
+
* getDiffReportPath('abc123def456', 'xyz789uvw012', 'markdown');
|
|
540
|
+
* // '.doccov/diff-abc123de-xyz789uv.md'
|
|
541
|
+
* ```
|
|
542
|
+
*/
|
|
543
|
+
declare function getDiffReportPath(baseHash: string, headHash: string, format: string, dir?: string): string;
|
|
544
|
+
/**
|
|
479
545
|
* Drift summary with category breakdown.
|
|
480
546
|
*/
|
|
481
547
|
interface DriftReportSummary {
|
|
@@ -620,7 +686,7 @@ interface DocCovReport {
|
|
|
620
686
|
* console.log(`Coverage: ${report.coverage.score}%`);
|
|
621
687
|
* ```
|
|
622
688
|
*/
|
|
623
|
-
declare function generateReport(spec:
|
|
689
|
+
declare function generateReport(spec: OpenPkg4): DocCovReport;
|
|
624
690
|
/**
|
|
625
691
|
* Generate a DocCov report from an already-enriched spec.
|
|
626
692
|
*
|
|
@@ -689,7 +755,7 @@ declare function hashFiles(filePaths: string[], cwd: string): Record<string, str
|
|
|
689
755
|
* @returns Array of file paths that changed, were added, or were removed
|
|
690
756
|
*/
|
|
691
757
|
declare function diffHashes(cached: Record<string, string>, current: Record<string, string>): string[];
|
|
692
|
-
import { OpenPkg as
|
|
758
|
+
import { OpenPkg as OpenPkg5 } from "@openpkg-ts/spec";
|
|
693
759
|
/** Current cache format version */
|
|
694
760
|
declare const CACHE_VERSION = "1.0.0";
|
|
695
761
|
/** Default cache file path */
|
|
@@ -724,7 +790,7 @@ interface SpecCache {
|
|
|
724
790
|
/** Analysis configuration that affects output */
|
|
725
791
|
config: SpecCacheConfig;
|
|
726
792
|
/** The cached OpenPkg spec */
|
|
727
|
-
spec:
|
|
793
|
+
spec: OpenPkg5;
|
|
728
794
|
}
|
|
729
795
|
/**
|
|
730
796
|
* Result of cache validation.
|
|
@@ -767,7 +833,7 @@ declare function loadSpecCache(cwd: string): SpecCache | null;
|
|
|
767
833
|
* @param spec - OpenPkg spec to cache
|
|
768
834
|
* @param context - Cache context with file paths and config
|
|
769
835
|
*/
|
|
770
|
-
declare function saveSpecCache(spec:
|
|
836
|
+
declare function saveSpecCache(spec: OpenPkg5, context: CacheContext): void;
|
|
771
837
|
/**
|
|
772
838
|
* Validate if cached spec is still valid.
|
|
773
839
|
*
|
|
@@ -1411,7 +1477,7 @@ declare function categorizeDrifts(drifts: SpecDocDrift4[]): {
|
|
|
1411
1477
|
fixable: SpecDocDrift4[];
|
|
1412
1478
|
nonFixable: SpecDocDrift4[];
|
|
1413
1479
|
};
|
|
1414
|
-
import { OpenPkg as
|
|
1480
|
+
import { OpenPkg as OpenPkg6 } from "@openpkg-ts/spec";
|
|
1415
1481
|
/**
|
|
1416
1482
|
* Parsed components of a GitHub URL.
|
|
1417
1483
|
*/
|
|
@@ -1504,7 +1570,7 @@ declare function buildRawUrl(parsed: ParsedGitHubUrl, filePath: string): string;
|
|
|
1504
1570
|
* }
|
|
1505
1571
|
* ```
|
|
1506
1572
|
*/
|
|
1507
|
-
declare function fetchSpecFromGitHub(parsed: ParsedGitHubUrl): Promise<
|
|
1573
|
+
declare function fetchSpecFromGitHub(parsed: ParsedGitHubUrl): Promise<OpenPkg6 | null>;
|
|
1508
1574
|
/**
|
|
1509
1575
|
* Fetch an OpenPkg spec from a GitHub repository by owner/repo/branch.
|
|
1510
1576
|
*
|
|
@@ -1515,84 +1581,22 @@ declare function fetchSpecFromGitHub(parsed: ParsedGitHubUrl): Promise<OpenPkg5
|
|
|
1515
1581
|
* @param branch - Branch name (default: 'main')
|
|
1516
1582
|
* @returns The OpenPkg spec, or null if not found
|
|
1517
1583
|
*/
|
|
1518
|
-
declare function fetchSpec(owner: string, repo: string, branch?: string): Promise<
|
|
1584
|
+
declare function fetchSpec(owner: string, repo: string, branch?: string): Promise<OpenPkg6 | null>;
|
|
1519
1585
|
/**
|
|
1520
|
-
*
|
|
1521
|
-
* Single source of truth for scan-related interfaces.
|
|
1586
|
+
* Progress event for installation status updates.
|
|
1522
1587
|
*/
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
*/
|
|
1527
|
-
interface ScanResult {
|
|
1528
|
-
/** GitHub repository owner */
|
|
1529
|
-
owner: string;
|
|
1530
|
-
/** GitHub repository name */
|
|
1531
|
-
repo: string;
|
|
1532
|
-
/** Git ref (branch/tag) that was scanned */
|
|
1533
|
-
ref: string;
|
|
1534
|
-
/** Package name if scanning a monorepo package */
|
|
1535
|
-
packageName?: string;
|
|
1536
|
-
/** Overall documentation coverage percentage (0-100) */
|
|
1537
|
-
coverage: number;
|
|
1538
|
-
/** Number of public exports analyzed */
|
|
1539
|
-
exportCount: number;
|
|
1540
|
-
/** Number of types analyzed */
|
|
1541
|
-
typeCount: number;
|
|
1542
|
-
/** Number of documentation drift issues found */
|
|
1543
|
-
driftCount: number;
|
|
1544
|
-
/** Names of exports missing documentation */
|
|
1545
|
-
undocumented: string[];
|
|
1546
|
-
/** Drift issues found during analysis */
|
|
1547
|
-
drift: DriftIssue[];
|
|
1548
|
-
}
|
|
1549
|
-
/**
|
|
1550
|
-
* A documentation drift issue.
|
|
1551
|
-
*/
|
|
1552
|
-
interface DriftIssue {
|
|
1553
|
-
/** Name of the with drift */
|
|
1554
|
-
export: string;
|
|
1555
|
-
/** Type of drift (e.g., 'param-mismatch', 'return-type') */
|
|
1556
|
-
type: string;
|
|
1557
|
-
/** Human-readable description of the issue */
|
|
1558
|
-
issue: string;
|
|
1559
|
-
/** Optional suggestion for fixing the issue */
|
|
1560
|
-
suggestion?: string;
|
|
1561
|
-
}
|
|
1562
|
-
/**
|
|
1563
|
-
* Options for running a scan.
|
|
1564
|
-
*/
|
|
1565
|
-
interface ScanOptions {
|
|
1566
|
-
/** GitHub URL or owner/repo shorthand */
|
|
1567
|
-
url: string;
|
|
1568
|
-
/** Git ref (branch/tag) to scan */
|
|
1569
|
-
ref?: string;
|
|
1570
|
-
/** Target package name for monorepos */
|
|
1571
|
-
package?: string;
|
|
1572
|
-
/** Skip dependency installation */
|
|
1573
|
-
skipInstall?: boolean;
|
|
1574
|
-
/** Skip external type resolution */
|
|
1575
|
-
skipResolve?: boolean;
|
|
1576
|
-
}
|
|
1577
|
-
/**
|
|
1578
|
-
* Stages of the scan pipeline.
|
|
1579
|
-
*/
|
|
1580
|
-
type ProgressStage = "cloning" | "detecting" | "installing" | "building" | "analyzing" | "complete";
|
|
1581
|
-
/**
|
|
1582
|
-
* Progress event emitted during scan operations.
|
|
1583
|
-
*/
|
|
1584
|
-
interface ProgressEvent {
|
|
1585
|
-
/** Current stage of the scan */
|
|
1586
|
-
stage: ProgressStage;
|
|
1588
|
+
interface InstallProgressEvent {
|
|
1589
|
+
/** Current stage */
|
|
1590
|
+
stage: "installing";
|
|
1587
1591
|
/** Human-readable message */
|
|
1588
1592
|
message: string;
|
|
1589
1593
|
/** Progress percentage (0-100), if known */
|
|
1590
1594
|
progress?: number;
|
|
1591
1595
|
}
|
|
1592
1596
|
/**
|
|
1593
|
-
* Callback for receiving progress events.
|
|
1597
|
+
* Callback for receiving installation progress events.
|
|
1594
1598
|
*/
|
|
1595
|
-
type
|
|
1599
|
+
type InstallProgressCallback = (event: InstallProgressEvent) => void;
|
|
1596
1600
|
/**
|
|
1597
1601
|
* Result of running a command.
|
|
1598
1602
|
*/
|
|
@@ -1636,7 +1640,7 @@ interface InstallOptions {
|
|
|
1636
1640
|
/** Order of fallback package managers to try */
|
|
1637
1641
|
fallbackOrder?: PackageManager[];
|
|
1638
1642
|
/** Progress callback for status updates */
|
|
1639
|
-
onProgress?:
|
|
1643
|
+
onProgress?: InstallProgressCallback;
|
|
1640
1644
|
}
|
|
1641
1645
|
/**
|
|
1642
1646
|
* Install dependencies for a project.
|
|
@@ -1836,7 +1840,7 @@ declare function getDocumentedExports(markdownFiles: MarkdownDocFile[], exportNa
|
|
|
1836
1840
|
* Get all exports that lack documentation
|
|
1837
1841
|
*/
|
|
1838
1842
|
declare function getUndocumentedExports(markdownFiles: MarkdownDocFile[], exportNames: string[]): string[];
|
|
1839
|
-
import { CategorizedBreaking, OpenPkg as
|
|
1843
|
+
import { CategorizedBreaking, OpenPkg as OpenPkg8, SpecDiff as SpecDiff2 } from "@openpkg-ts/spec";
|
|
1840
1844
|
/**
|
|
1841
1845
|
* Extended spec diff result with docs impact
|
|
1842
1846
|
*/
|
|
@@ -1882,7 +1886,7 @@ interface DiffWithDocsOptions {
|
|
|
1882
1886
|
* }
|
|
1883
1887
|
* ```
|
|
1884
1888
|
*/
|
|
1885
|
-
declare function diffSpecWithDocs(oldSpec:
|
|
1889
|
+
declare function diffSpecWithDocs(oldSpec: OpenPkg8, newSpec: OpenPkg8, options?: DiffWithDocsOptions): SpecDiffWithDocs;
|
|
1886
1890
|
/**
|
|
1887
1891
|
* Check if a diff has any docs impact
|
|
1888
1892
|
*/
|
|
@@ -1938,7 +1942,29 @@ declare function findExportReferences(files: MarkdownDocFile[], exportNames: str
|
|
|
1938
1942
|
* Check if a code block references any of the given names
|
|
1939
1943
|
*/
|
|
1940
1944
|
declare function blockReferencesExport(block: MarkdownCodeBlock, exportName: string): boolean;
|
|
1941
|
-
|
|
1945
|
+
import { EntryPointDetectionMethod } from "@openpkg-ts/spec";
|
|
1946
|
+
/**
|
|
1947
|
+
* Input for generation metadata that comes from the caller (CLI, API, etc.)
|
|
1948
|
+
*/
|
|
1949
|
+
interface GenerationInput {
|
|
1950
|
+
/** Entry point file path (relative to package root) */
|
|
1951
|
+
entryPoint: string;
|
|
1952
|
+
/** How the entry point was detected */
|
|
1953
|
+
entryPointSource: EntryPointDetectionMethod;
|
|
1954
|
+
/** Whether this is a declaration-only analysis (.d.ts file) */
|
|
1955
|
+
isDeclarationOnly?: boolean;
|
|
1956
|
+
/** Generator tool name */
|
|
1957
|
+
generatorName: string;
|
|
1958
|
+
/** Generator tool version */
|
|
1959
|
+
generatorVersion: string;
|
|
1960
|
+
/** Detected package manager */
|
|
1961
|
+
packageManager?: string;
|
|
1962
|
+
/** Whether this is a monorepo */
|
|
1963
|
+
isMonorepo?: boolean;
|
|
1964
|
+
/** Target package name (for monorepos) */
|
|
1965
|
+
targetPackage?: string;
|
|
1966
|
+
}
|
|
1967
|
+
interface Diagnostic2 {
|
|
1942
1968
|
message: string;
|
|
1943
1969
|
severity: "error" | "warning" | "info";
|
|
1944
1970
|
suggestion?: string;
|
|
@@ -1950,7 +1976,7 @@ interface Diagnostic {
|
|
|
1950
1976
|
}
|
|
1951
1977
|
interface AnalysisResult {
|
|
1952
1978
|
spec: OpenPkgSpec;
|
|
1953
|
-
diagnostics:
|
|
1979
|
+
diagnostics: Diagnostic2[];
|
|
1954
1980
|
metadata: AnalysisMetadata;
|
|
1955
1981
|
/** True if result came from cache (no fresh analysis) */
|
|
1956
1982
|
fromCache?: boolean;
|
|
@@ -1968,6 +1994,8 @@ interface AnalysisMetadata {
|
|
|
1968
1994
|
}
|
|
1969
1995
|
interface AnalyzeOptions {
|
|
1970
1996
|
filters?: FilterOptions;
|
|
1997
|
+
/** Generation metadata input (entry point info, tool version, etc.) */
|
|
1998
|
+
generationInput?: GenerationInput;
|
|
1971
1999
|
}
|
|
1972
2000
|
declare class DocCov {
|
|
1973
2001
|
private readonly options;
|
|
@@ -2002,7 +2030,7 @@ declare class DocCov {
|
|
|
2002
2030
|
declare function analyze(code: string, options?: AnalyzeOptions): Promise<OpenPkgSpec>;
|
|
2003
2031
|
declare function analyzeFile(filePath: string, options?: AnalyzeOptions): Promise<OpenPkgSpec>;
|
|
2004
2032
|
/** @deprecated Use DocCov instead */
|
|
2005
|
-
declare const
|
|
2033
|
+
declare const OpenPkg9: typeof DocCov;
|
|
2006
2034
|
import { SpecExport as SpecExport6 } from "@openpkg-ts/spec";
|
|
2007
2035
|
import { SpecExportKind as SpecExportKind2 } from "@openpkg-ts/spec";
|
|
2008
2036
|
/**
|
|
@@ -2113,127 +2141,18 @@ interface ResolvedTarget {
|
|
|
2113
2141
|
* ```
|
|
2114
2142
|
*/
|
|
2115
2143
|
declare function resolveTarget(fs: FileSystem, options: ResolveTargetOptions): Promise<ResolvedTarget>;
|
|
2116
|
-
import { OpenPkg as OpenPkg9 } from "@openpkg-ts/spec";
|
|
2117
|
-
/**
|
|
2118
|
-
* Options for creating a ScanOrchestrator.
|
|
2119
|
-
*/
|
|
2120
|
-
interface ScanOrchestratorOptions {
|
|
2121
|
-
/** Progress callback for status updates */
|
|
2122
|
-
onProgress?: ProgressCallback;
|
|
2123
|
-
/** Command runner for executing shell commands */
|
|
2124
|
-
commandRunner?: CommandRunner;
|
|
2125
|
-
/** Skip external type resolution */
|
|
2126
|
-
skipResolve?: boolean;
|
|
2127
|
-
}
|
|
2128
2144
|
/**
|
|
2129
|
-
*
|
|
2145
|
+
* A documentation drift issue in a spec summary.
|
|
2130
2146
|
*/
|
|
2131
|
-
interface
|
|
2132
|
-
/**
|
|
2133
|
-
|
|
2134
|
-
/**
|
|
2135
|
-
|
|
2136
|
-
/**
|
|
2137
|
-
|
|
2138
|
-
/**
|
|
2139
|
-
|
|
2140
|
-
}
|
|
2141
|
-
/**
|
|
2142
|
-
* Orchestrates the scan workflow.
|
|
2143
|
-
*
|
|
2144
|
-
* The orchestrator coordinates:
|
|
2145
|
-
* 1. Repository cloning (for remote URLs)
|
|
2146
|
-
* 2. Monorepo detection and package resolution
|
|
2147
|
-
* 3. Entry point detection
|
|
2148
|
-
* 4. Dependency installation
|
|
2149
|
-
* 5. Build execution (if needed)
|
|
2150
|
-
* 6. Documentation analysis
|
|
2151
|
-
* 7. Summary extraction
|
|
2152
|
-
*
|
|
2153
|
-
* It's designed to be FileSystem-agnostic so it works with both:
|
|
2154
|
-
* - NodeFileSystem (CLI - local execution)
|
|
2155
|
-
* - SandboxFileSystem (API - isolated execution)
|
|
2156
|
-
*
|
|
2157
|
-
* @example
|
|
2158
|
-
* ```typescript
|
|
2159
|
-
* import { ScanOrchestrator, NodeFileSystem, createNodeCommandRunner } from '@doccov/sdk';
|
|
2160
|
-
*
|
|
2161
|
-
* const fs = new NodeFileSystem('/path/to/repo');
|
|
2162
|
-
* const orchestrator = new ScanOrchestrator(fs, {
|
|
2163
|
-
* commandRunner: createNodeCommandRunner(),
|
|
2164
|
-
* onProgress: (event) => console.log(event.message),
|
|
2165
|
-
* });
|
|
2166
|
-
*
|
|
2167
|
-
* const result = await orchestrator.scan({
|
|
2168
|
-
* url: 'https://github.com/owner/repo',
|
|
2169
|
-
* ref: 'main',
|
|
2170
|
-
* });
|
|
2171
|
-
*
|
|
2172
|
-
* console.log(`Coverage: ${result.coverage}%`);
|
|
2173
|
-
* ```
|
|
2174
|
-
*/
|
|
2175
|
-
declare class ScanOrchestrator {
|
|
2176
|
-
private readonly fs;
|
|
2177
|
-
private readonly options;
|
|
2178
|
-
constructor(fs: FileSystem, options?: ScanOrchestratorOptions);
|
|
2179
|
-
/**
|
|
2180
|
-
* Emit a progress event.
|
|
2181
|
-
*/
|
|
2182
|
-
private emit;
|
|
2183
|
-
/**
|
|
2184
|
-
* Detect monorepo and resolve target package.
|
|
2185
|
-
*
|
|
2186
|
-
* @param packageName - Target package name (required for monorepos)
|
|
2187
|
-
* @returns Target directory path (relative to workDir)
|
|
2188
|
-
* @throws Error if monorepo requires --package flag
|
|
2189
|
-
*/
|
|
2190
|
-
detectPackage(packageName?: string): Promise<{
|
|
2191
|
-
targetPath: string;
|
|
2192
|
-
resolvedPackage?: string;
|
|
2193
|
-
}>;
|
|
2194
|
-
/**
|
|
2195
|
-
* Detect entry point for the package.
|
|
2196
|
-
*
|
|
2197
|
-
* @param targetPath - Path to the package directory
|
|
2198
|
-
* @returns Entry point file path (relative to workDir)
|
|
2199
|
-
*/
|
|
2200
|
-
detectEntry(targetPath: string): Promise<string>;
|
|
2201
|
-
/**
|
|
2202
|
-
* Install dependencies for the project.
|
|
2203
|
-
*
|
|
2204
|
-
* @param workDir - Working directory (absolute path)
|
|
2205
|
-
* @returns Installation result
|
|
2206
|
-
*/
|
|
2207
|
-
install(workDir: string): Promise<InstallResult>;
|
|
2208
|
-
/**
|
|
2209
|
-
* Run build if needed.
|
|
2210
|
-
*
|
|
2211
|
-
* @param workDir - Working directory (absolute path)
|
|
2212
|
-
* @param targetPath - Target package path (relative)
|
|
2213
|
-
*/
|
|
2214
|
-
build(workDir: string, targetPath: string): Promise<void>;
|
|
2215
|
-
/**
|
|
2216
|
-
* Run documentation analysis.
|
|
2217
|
-
*
|
|
2218
|
-
* @param entryFile - Path to entry file (absolute)
|
|
2219
|
-
* @returns OpenPkg spec
|
|
2220
|
-
*/
|
|
2221
|
-
analyze(entryFile: string): Promise<OpenPkg9>;
|
|
2222
|
-
/**
|
|
2223
|
-
* Run a complete scan workflow.
|
|
2224
|
-
*
|
|
2225
|
-
* @param options - Scan options
|
|
2226
|
-
* @returns Scan result with coverage statistics
|
|
2227
|
-
*/
|
|
2228
|
-
scan(options: ScanOptions): Promise<ScanResult>;
|
|
2229
|
-
}
|
|
2230
|
-
/**
|
|
2231
|
-
* Error thrown when a monorepo is detected but no package is specified.
|
|
2232
|
-
*/
|
|
2233
|
-
declare class MonorepoRequiresPackageError extends Error {
|
|
2234
|
-
/** Available package names */
|
|
2235
|
-
readonly availablePackages: string[];
|
|
2236
|
-
constructor(availablePackages: string[]);
|
|
2147
|
+
interface SummaryDriftIssue {
|
|
2148
|
+
/** Name of the with drift */
|
|
2149
|
+
export: string;
|
|
2150
|
+
/** Type of drift (e.g., 'param-mismatch', 'return-type') */
|
|
2151
|
+
type: string;
|
|
2152
|
+
/** Human-readable description of the issue */
|
|
2153
|
+
issue: string;
|
|
2154
|
+
/** Optional suggestion for fixing the issue */
|
|
2155
|
+
suggestion?: string;
|
|
2237
2156
|
}
|
|
2238
2157
|
/**
|
|
2239
2158
|
* Summary of a spec's documentation coverage.
|
|
@@ -2251,7 +2170,7 @@ interface SpecSummary {
|
|
|
2251
2170
|
/** Names of undocumented or partially documented exports */
|
|
2252
2171
|
undocumented: string[];
|
|
2253
2172
|
/** Drift issues */
|
|
2254
|
-
drift:
|
|
2173
|
+
drift: SummaryDriftIssue[];
|
|
2255
2174
|
}
|
|
2256
2175
|
/**
|
|
2257
2176
|
* Extract a summary from an enriched OpenPkg spec.
|
|
@@ -2276,6 +2195,188 @@ interface SpecSummary {
|
|
|
2276
2195
|
*/
|
|
2277
2196
|
declare function extractSpecSummary(spec: EnrichedOpenPkg): SpecSummary;
|
|
2278
2197
|
/**
|
|
2198
|
+
* Build Plan types for AI-powered repository scanning.
|
|
2199
|
+
*/
|
|
2200
|
+
/**
|
|
2201
|
+
* Target repository information for a build plan.
|
|
2202
|
+
*/
|
|
2203
|
+
interface BuildPlanTarget {
|
|
2204
|
+
/** Target type (currently only GitHub is supported) */
|
|
2205
|
+
type: "github";
|
|
2206
|
+
/** Full GitHub repository URL */
|
|
2207
|
+
repoUrl: string;
|
|
2208
|
+
/** Git ref (branch, tag, or commit) */
|
|
2209
|
+
ref: string;
|
|
2210
|
+
/** Root path within the repository (for monorepos) */
|
|
2211
|
+
rootPath?: string;
|
|
2212
|
+
/** Entry point files to analyze */
|
|
2213
|
+
entryPoints: string[];
|
|
2214
|
+
}
|
|
2215
|
+
/**
|
|
2216
|
+
* Runtime environment configuration for executing a build plan.
|
|
2217
|
+
*/
|
|
2218
|
+
interface BuildPlanEnvironment {
|
|
2219
|
+
/** Node.js or Bun runtime */
|
|
2220
|
+
runtime: "node20" | "node22" | "bun";
|
|
2221
|
+
/** Package manager to use */
|
|
2222
|
+
packageManager: "npm" | "yarn" | "pnpm" | "bun";
|
|
2223
|
+
/** Additional tools required (e.g., 'wasm-pack', 'cargo') */
|
|
2224
|
+
requiredTools?: string[];
|
|
2225
|
+
}
|
|
2226
|
+
/**
|
|
2227
|
+
* A single step in the build plan.
|
|
2228
|
+
*/
|
|
2229
|
+
interface BuildPlanStep {
|
|
2230
|
+
/** Unique identifier for this step */
|
|
2231
|
+
id: string;
|
|
2232
|
+
/** Human-readable step name */
|
|
2233
|
+
name: string;
|
|
2234
|
+
/** Command to execute */
|
|
2235
|
+
command: string;
|
|
2236
|
+
/** Command arguments */
|
|
2237
|
+
args: string[];
|
|
2238
|
+
/** Working directory (relative to repo root) */
|
|
2239
|
+
cwd?: string;
|
|
2240
|
+
/** Timeout in milliseconds */
|
|
2241
|
+
timeout?: number;
|
|
2242
|
+
/** If true, failure won't stop the plan execution */
|
|
2243
|
+
optional?: boolean;
|
|
2244
|
+
}
|
|
2245
|
+
/**
|
|
2246
|
+
* AI-generated build plan for analyzing a repository.
|
|
2247
|
+
*/
|
|
2248
|
+
interface BuildPlan {
|
|
2249
|
+
/** Build plan schema version */
|
|
2250
|
+
version: "1.0.0";
|
|
2251
|
+
/** When the plan was generated */
|
|
2252
|
+
generatedAt: string;
|
|
2253
|
+
/** Target repository information */
|
|
2254
|
+
target: BuildPlanTarget;
|
|
2255
|
+
/** Environment configuration */
|
|
2256
|
+
environment: BuildPlanEnvironment;
|
|
2257
|
+
/** Ordered list of steps to execute */
|
|
2258
|
+
steps: BuildPlanStep[];
|
|
2259
|
+
/** AI reasoning about the plan */
|
|
2260
|
+
reasoning: {
|
|
2261
|
+
/** Brief summary of the approach */
|
|
2262
|
+
summary: string;
|
|
2263
|
+
/** Why this approach was chosen */
|
|
2264
|
+
rationale: string;
|
|
2265
|
+
/** Potential issues or concerns */
|
|
2266
|
+
concerns: string[];
|
|
2267
|
+
};
|
|
2268
|
+
/** AI confidence in the plan */
|
|
2269
|
+
confidence: "high" | "medium" | "low";
|
|
2270
|
+
}
|
|
2271
|
+
/**
|
|
2272
|
+
* Result of executing a single build plan step.
|
|
2273
|
+
*/
|
|
2274
|
+
interface BuildPlanStepResult {
|
|
2275
|
+
/** Step ID that was executed */
|
|
2276
|
+
stepId: string;
|
|
2277
|
+
/** Whether the step succeeded */
|
|
2278
|
+
success: boolean;
|
|
2279
|
+
/** Duration in milliseconds */
|
|
2280
|
+
duration: number;
|
|
2281
|
+
/** Command output (stdout) */
|
|
2282
|
+
output?: string;
|
|
2283
|
+
/** Error message if failed */
|
|
2284
|
+
error?: string;
|
|
2285
|
+
}
|
|
2286
|
+
/**
|
|
2287
|
+
* Result of executing a complete build plan.
|
|
2288
|
+
*/
|
|
2289
|
+
interface BuildPlanExecutionResult {
|
|
2290
|
+
/** Whether all required steps succeeded */
|
|
2291
|
+
success: boolean;
|
|
2292
|
+
/** Generated OpenPkg spec (if successful) */
|
|
2293
|
+
spec?: import("@openpkg-ts/spec").OpenPkg;
|
|
2294
|
+
/** Results for each step */
|
|
2295
|
+
stepResults: BuildPlanStepResult[];
|
|
2296
|
+
/** Total execution time in milliseconds */
|
|
2297
|
+
totalDuration: number;
|
|
2298
|
+
/** Overall error message if failed */
|
|
2299
|
+
error?: string;
|
|
2300
|
+
}
|
|
2301
|
+
/**
|
|
2302
|
+
* GitHub context fetcher for AI-powered build plan generation.
|
|
2303
|
+
* Fetches project context via GitHub API without cloning the repository.
|
|
2304
|
+
*/
|
|
2305
|
+
/**
|
|
2306
|
+
* Repository metadata from GitHub API.
|
|
2307
|
+
*/
|
|
2308
|
+
interface GitHubRepoMetadata {
|
|
2309
|
+
owner: string;
|
|
2310
|
+
repo: string;
|
|
2311
|
+
defaultBranch: string;
|
|
2312
|
+
description: string | null;
|
|
2313
|
+
language: string | null;
|
|
2314
|
+
topics: string[];
|
|
2315
|
+
isPrivate: boolean;
|
|
2316
|
+
}
|
|
2317
|
+
/**
|
|
2318
|
+
* Detected package manager from lockfile.
|
|
2319
|
+
*/
|
|
2320
|
+
type DetectedPackageManager = "npm" | "yarn" | "pnpm" | "bun" | "unknown";
|
|
2321
|
+
/**
|
|
2322
|
+
* Workspace/monorepo configuration.
|
|
2323
|
+
*/
|
|
2324
|
+
interface WorkspaceConfig {
|
|
2325
|
+
isMonorepo: boolean;
|
|
2326
|
+
tool?: "npm" | "yarn" | "pnpm" | "lerna" | "turborepo" | "nx";
|
|
2327
|
+
packages?: string[];
|
|
2328
|
+
}
|
|
2329
|
+
/**
|
|
2330
|
+
* Build hints detected from project files.
|
|
2331
|
+
*/
|
|
2332
|
+
interface BuildHints {
|
|
2333
|
+
hasTypeScript: boolean;
|
|
2334
|
+
hasWasm: boolean;
|
|
2335
|
+
hasNativeModules: boolean;
|
|
2336
|
+
hasBuildScript: boolean;
|
|
2337
|
+
buildScript?: string;
|
|
2338
|
+
frameworks: string[];
|
|
2339
|
+
}
|
|
2340
|
+
/**
|
|
2341
|
+
* Complete project context for build plan generation.
|
|
2342
|
+
*/
|
|
2343
|
+
interface GitHubProjectContext {
|
|
2344
|
+
/** Repository metadata */
|
|
2345
|
+
metadata: GitHubRepoMetadata;
|
|
2346
|
+
/** Git ref being analyzed */
|
|
2347
|
+
ref: string;
|
|
2348
|
+
/** Detected package manager */
|
|
2349
|
+
packageManager: DetectedPackageManager;
|
|
2350
|
+
/** Workspace/monorepo configuration */
|
|
2351
|
+
workspace: WorkspaceConfig;
|
|
2352
|
+
/** Build hints from project files */
|
|
2353
|
+
buildHints: BuildHints;
|
|
2354
|
+
/** Raw file contents for AI analysis */
|
|
2355
|
+
files: {
|
|
2356
|
+
packageJson?: string;
|
|
2357
|
+
tsconfigJson?: string;
|
|
2358
|
+
lockfile?: {
|
|
2359
|
+
name: string;
|
|
2360
|
+
content: string;
|
|
2361
|
+
};
|
|
2362
|
+
};
|
|
2363
|
+
}
|
|
2364
|
+
/**
|
|
2365
|
+
* Parse GitHub URL into owner and repo.
|
|
2366
|
+
*/
|
|
2367
|
+
declare function parseGitHubUrl2(url: string): {
|
|
2368
|
+
owner: string;
|
|
2369
|
+
repo: string;
|
|
2370
|
+
} | null;
|
|
2371
|
+
/**
|
|
2372
|
+
* Fetch complete project context from GitHub.
|
|
2373
|
+
*/
|
|
2374
|
+
declare function fetchGitHubContext(repoUrl: string, ref?: string): Promise<GitHubProjectContext>;
|
|
2375
|
+
/**
|
|
2376
|
+
* List packages in a monorepo workspace.
|
|
2377
|
+
*/
|
|
2378
|
+
declare function listWorkspacePackages(owner: string, repo: string, ref: string, patterns: string[]): Promise<string[]>;
|
|
2379
|
+
/**
|
|
2279
2380
|
* Type-check a single example
|
|
2280
2381
|
*/
|
|
2281
2382
|
declare function typecheckExample(example: string, packagePath: string, options?: TypecheckOptions): ExampleTypeError[];
|
|
@@ -2283,4 +2384,4 @@ declare function typecheckExample(example: string, packagePath: string, options?
|
|
|
2283
2384
|
* Type-check multiple examples
|
|
2284
2385
|
*/
|
|
2285
2386
|
declare function typecheckExamples(examples: string[], packagePath: string, options?: TypecheckOptions): TypecheckResult;
|
|
2286
|
-
export { validateSpecCache, validateExamples, typecheckExamples, typecheckExample, shouldValidate, serializeJSDoc, saveSpecCache, saveReport, safeParseJson, runExamplesWithPackage, runExamples, runExample, resolveTarget, readPackageJson, parseMarkdownFiles, parseMarkdownFile, parseListFlag, parseJSDocToPatch, parseGitHubUrl, parseExamplesFlag, parseAssertions, mergeFixes, mergeFilters, mergeConfig, loadSpecCache, loadCachedReport, isFixableDrift, isExecutableLang, isCachedReportValid, installDependencies, hashString, hashFiles, hashFile, hasNonAssertionComments, hasDocsImpact, hasDocsForExport, groupDriftsByCategory, getUndocumentedExports, getSpecCachePath, getRunCommand, getRulesForKind, getRule, getReportPath, getPrimaryBuildScript, getInstallCommand, getDriftSummary, getDocumentedExports, getDocsImpactSummary, getDefaultConfig, getCoverageRules, generateReportFromEnriched, generateReport, generateFixesForExport, generateFix, formatPackageList, formatDriftSummaryLine, findRemovedReferences, findPackageByName, findJSDocLocation, findExportReferences, findDeprecatedReferences, fetchSpecFromGitHub, fetchSpec, extractSpecSummary, extractPackageSpec, extractImports, extractFunctionCalls, evaluateQuality, evaluateExportQuality, enrichSpec, diffSpecWithDocs, diffHashes, detectPackageManager, detectMonorepo, detectExampleRuntimeErrors, detectExampleAssertionFailures, detectEntryPoint, detectBuildInfo, defineConfig, createSourceFile, createNodeCommandRunner, computeExportDrift, computeDrift, clearSpecCache, categorizeDrifts, categorizeDrift, buildRawUrl, buildExportRegistry, buildDisplayUrl, buildCloneUrl, blockReferencesExport, applyPatchToJSDoc, applyEdits, analyzeProject2 as analyzeProject, analyzeFile, analyzeDocsImpact, analyze, WorkspacePackage, VALIDATION_INFO, TypecheckValidationResult, TypecheckResult, TypecheckOptions, SpecSummary, SpecDiffWithDocs, SpecCacheConfig, SpecCache,
|
|
2387
|
+
export { validateSpecCache, validateExamples, typecheckExamples, typecheckExample, shouldValidate, serializeJSDoc, saveSpecCache, saveReport, safeParseJson, runExamplesWithPackage, runExamples, runExample, resolveTarget, readPackageJson, parseGitHubUrl2 as parseScanGitHubUrl, parseMarkdownFiles, parseMarkdownFile, parseListFlag, parseJSDocToPatch, parseGitHubUrl, parseExamplesFlag, parseAssertions, mergeFixes, mergeFilters, mergeConfig, loadSpecCache, loadCachedReport, listWorkspacePackages, isFixableDrift, isExecutableLang, isCachedReportValid, installDependencies, hashString, hashFiles, hashFile, hasNonAssertionComments, hasDocsImpact, hasDocsForExport, groupDriftsByCategory, getUndocumentedExports, getSpecCachePath, getRunCommand, getRulesForKind, getRule, getReportPath, getPrimaryBuildScript, getInstallCommand, getDriftSummary, getDocumentedExports, getDocsImpactSummary, getDiffReportPath, getDefaultConfig, getCoverageRules, generateReportFromEnriched, generateReport, generateFixesForExport, generateFix, formatPackageList, formatDriftSummaryLine, findRemovedReferences, findPackageByName, findJSDocLocation, findExportReferences, findDeprecatedReferences, fetchSpecFromGitHub, fetchSpec, fetchGitHubContext, extractSpecSummary, extractPackageSpec, extractImports, extractFunctionCalls, evaluateQuality, evaluateExportQuality, ensureSpecCoverage, enrichSpec, diffSpecWithDocs, diffHashes, detectPackageManager, detectMonorepo, detectExampleRuntimeErrors, detectExampleAssertionFailures, detectEntryPoint, detectBuildInfo, defineConfig, createSourceFile, createNodeCommandRunner, computeExportDrift, computeDrift, clearSpecCache, categorizeDrifts, categorizeDrift, calculateAggregateCoverage, buildRawUrl, buildExportRegistry, buildDisplayUrl, buildCloneUrl, blockReferencesExport, applyPatchToJSDoc, applyEdits, analyzeProject2 as analyzeProject, analyzeFile, analyzeDocsImpact, analyze, WorkspacePackage, WorkspaceConfig, VALIDATION_INFO, TypecheckValidationResult, TypecheckResult, TypecheckOptions, SummaryDriftIssue, SpecSummary, SpecDiffWithDocs, SpecCacheConfig, SpecCache, SandboxFileSystem, STYLE_RULES, SPEC_CACHE_FILE, RuntimeDrift, RunValidationResult, RunExamplesWithPackageResult, RunExamplesWithPackageOptions, RunExampleOptions, RuleContext, ResolvedTarget, ResolvedFilters, ResolveTargetOptions, REPORT_VERSION, REPORT_EXTENSIONS, QualityViolation, QualitySeverity2 as QualitySeverity, QualityRulesConfig, QualityRule, QualityResult, QualityConfig, ProjectInfo, PresenceResult, ParsedGitHubUrl, PackageManagerInfo, PackageManager, PackageJson, PackageExports, OpenPkgSpec, OpenPkgOptions, OpenPkg9 as OpenPkg, NodeFileSystem, MonorepoType, MonorepoInfo, MemberChange, MarkdownDocFile, MarkdownCodeBlock, LLMAssertion, JSDocTag, JSDocReturn, JSDocPatch, JSDocParam, JSDocEdit, InstallResult, InstallOptions, GitHubRepoMetadata, GitHubProjectContext, FixType, FixSuggestion, FilterSource, FilterOptions, FileSystem, ExportReference, ExportDriftResult, ExportCoverageData, ExampleValidationTypeError, ExampleValidationResult, ExampleValidationOptions, ExampleValidationMode, ExampleValidation, ExampleTypeError, ExampleRunResult, EntryPointSource, EntryPointInfo, EnrichedOpenPkg, EnrichedExport, EnrichedDocsMetadata, EnrichOptions, DriftSummary, DriftResult, DriftReportSummary, DriftReport, DocsImpactResult, DocsImpactReference, DocsImpact, DocsConfig, DocsChangeType, DocCovReport, DocCovOptions, DocCovConfig, DocCov, DiffWithDocsOptions, Diagnostic2 as Diagnostic, DetectedPackageManager, DEFAULT_REPORT_PATH, DEFAULT_REPORT_DIR, CoverageSummary, CommandRunner, CommandResult, CheckConfig, CategorizedDrift, CacheValidationResult, CacheContext, CORE_RULES, CACHE_VERSION, BuildPlanTarget, BuildPlanStepResult, BuildPlanStep, BuildPlanExecutionResult, BuildPlanEnvironment, BuildPlan, BuildInfo, BuildHints, BUILTIN_RULES, ApplyEditsResult, AnalyzeProjectOptions, AnalyzeOptions, AnalysisResult, AggregateQualityResult, ALL_VALIDATIONS };
|
package/dist/index.js
CHANGED
|
@@ -1201,6 +1201,35 @@ function formatDriftSummaryLine(summary) {
|
|
|
1201
1201
|
const fixableNote = summary.fixable > 0 ? ` (${summary.fixable} auto-fixable)` : "";
|
|
1202
1202
|
return `${summary.total} issues (${parts.join(", ")})${fixableNote}`;
|
|
1203
1203
|
}
|
|
1204
|
+
function calculateAggregateCoverage(spec) {
|
|
1205
|
+
const exports = spec.exports ?? [];
|
|
1206
|
+
if (exports.length === 0)
|
|
1207
|
+
return 100;
|
|
1208
|
+
let totalScore = 0;
|
|
1209
|
+
for (const exp of exports) {
|
|
1210
|
+
const score = exp.docs?.coverageScore;
|
|
1211
|
+
if (score !== undefined) {
|
|
1212
|
+
totalScore += score;
|
|
1213
|
+
} else {
|
|
1214
|
+
totalScore += exp.description ? 100 : 0;
|
|
1215
|
+
}
|
|
1216
|
+
}
|
|
1217
|
+
return Math.round(totalScore / exports.length);
|
|
1218
|
+
}
|
|
1219
|
+
function ensureSpecCoverage(spec) {
|
|
1220
|
+
const specWithDocs = spec;
|
|
1221
|
+
if (specWithDocs.docs?.coverageScore !== undefined) {
|
|
1222
|
+
return spec;
|
|
1223
|
+
}
|
|
1224
|
+
const coverage = calculateAggregateCoverage(spec);
|
|
1225
|
+
return {
|
|
1226
|
+
...spec,
|
|
1227
|
+
docs: {
|
|
1228
|
+
...specWithDocs.docs ?? {},
|
|
1229
|
+
coverageScore: coverage
|
|
1230
|
+
}
|
|
1231
|
+
};
|
|
1232
|
+
}
|
|
1204
1233
|
// src/fix/jsdoc-writer.ts
|
|
1205
1234
|
import * as fs from "node:fs";
|
|
1206
1235
|
import * as path from "node:path";
|
|
@@ -1938,6 +1967,11 @@ function getReportPath(format, dir = DEFAULT_REPORT_DIR) {
|
|
|
1938
1967
|
const ext = REPORT_EXTENSIONS[format] ?? format;
|
|
1939
1968
|
return `${dir}/report.${ext}`;
|
|
1940
1969
|
}
|
|
1970
|
+
function getDiffReportPath(baseHash, headHash, format, dir = DEFAULT_REPORT_DIR) {
|
|
1971
|
+
const ext = REPORT_EXTENSIONS[format] ?? format;
|
|
1972
|
+
const hash = `${baseHash.slice(0, 8)}-${headHash.slice(0, 8)}`;
|
|
1973
|
+
return `${dir}/diff-${hash}.${ext}`;
|
|
1974
|
+
}
|
|
1941
1975
|
|
|
1942
1976
|
// src/analysis/report.ts
|
|
1943
1977
|
function generateReport(spec) {
|
|
@@ -6113,10 +6147,30 @@ class TypeRegistry {
|
|
|
6113
6147
|
}
|
|
6114
6148
|
|
|
6115
6149
|
// src/analysis/spec-builder.ts
|
|
6116
|
-
function
|
|
6117
|
-
|
|
6150
|
+
function createDefaultGenerationInfo(entryFile) {
|
|
6151
|
+
return {
|
|
6152
|
+
timestamp: new Date().toISOString(),
|
|
6153
|
+
generator: {
|
|
6154
|
+
name: "@doccov/sdk",
|
|
6155
|
+
version: "0.0.0"
|
|
6156
|
+
},
|
|
6157
|
+
analysis: {
|
|
6158
|
+
entryPoint: entryFile,
|
|
6159
|
+
entryPointSource: "explicit",
|
|
6160
|
+
isDeclarationOnly: entryFile.endsWith(".d.ts"),
|
|
6161
|
+
resolvedExternalTypes: false
|
|
6162
|
+
},
|
|
6163
|
+
environment: {
|
|
6164
|
+
hasNodeModules: false
|
|
6165
|
+
},
|
|
6166
|
+
issues: []
|
|
6167
|
+
};
|
|
6168
|
+
}
|
|
6169
|
+
function buildOpenPkgSpec(context, resolveExternalTypes, generation) {
|
|
6170
|
+
const { baseDir, checker: typeChecker, sourceFile, program, entryFile } = context;
|
|
6118
6171
|
const packageJsonPath = path9.join(baseDir, "package.json");
|
|
6119
6172
|
const packageJson = fs8.existsSync(packageJsonPath) ? JSON.parse(fs8.readFileSync(packageJsonPath, "utf-8")) : {};
|
|
6173
|
+
const generationInfo = generation ?? createDefaultGenerationInfo(path9.relative(baseDir, entryFile));
|
|
6120
6174
|
const spec = {
|
|
6121
6175
|
$schema: SCHEMA_URL,
|
|
6122
6176
|
openpkg: SCHEMA_VERSION,
|
|
@@ -6129,7 +6183,8 @@ function buildOpenPkgSpec(context, resolveExternalTypes) {
|
|
|
6129
6183
|
ecosystem: "js/ts"
|
|
6130
6184
|
},
|
|
6131
6185
|
exports: [],
|
|
6132
|
-
types: []
|
|
6186
|
+
types: [],
|
|
6187
|
+
generation: generationInfo
|
|
6133
6188
|
};
|
|
6134
6189
|
const typeRegistry = new TypeRegistry;
|
|
6135
6190
|
const serializerContext = {
|
|
@@ -6446,7 +6501,7 @@ function hasExternalImports(sourceFile) {
|
|
|
6446
6501
|
});
|
|
6447
6502
|
return found;
|
|
6448
6503
|
}
|
|
6449
|
-
function runAnalysis(input) {
|
|
6504
|
+
function runAnalysis(input, generationInput) {
|
|
6450
6505
|
const context = createAnalysisContext(input);
|
|
6451
6506
|
const { baseDir, options, program } = context;
|
|
6452
6507
|
const packageJsonPath = findNearestPackageJson(baseDir);
|
|
@@ -6459,30 +6514,65 @@ function runAnalysis(input) {
|
|
|
6459
6514
|
`);
|
|
6460
6515
|
return !/allowJs/i.test(msg);
|
|
6461
6516
|
});
|
|
6462
|
-
const spec = buildOpenPkgSpec(context, resolveExternalTypes);
|
|
6463
6517
|
const specDiagnostics = [];
|
|
6518
|
+
const generationIssues = [];
|
|
6464
6519
|
if (!hasNodeModules && hasExternalImports(context.sourceFile)) {
|
|
6465
|
-
|
|
6520
|
+
const issue = {
|
|
6521
|
+
code: "NO_NODE_MODULES",
|
|
6466
6522
|
message: "External imports detected but node_modules not found.",
|
|
6467
6523
|
severity: "info",
|
|
6468
6524
|
suggestion: "Run npm install or bun install for complete type resolution."
|
|
6469
|
-
}
|
|
6470
|
-
|
|
6525
|
+
};
|
|
6526
|
+
specDiagnostics.push(issue);
|
|
6527
|
+
generationIssues.push(issue);
|
|
6528
|
+
}
|
|
6529
|
+
const generation = generationInput ? {
|
|
6530
|
+
timestamp: new Date().toISOString(),
|
|
6531
|
+
generator: {
|
|
6532
|
+
name: generationInput.generatorName,
|
|
6533
|
+
version: generationInput.generatorVersion
|
|
6534
|
+
},
|
|
6535
|
+
analysis: {
|
|
6536
|
+
entryPoint: generationInput.entryPoint,
|
|
6537
|
+
entryPointSource: generationInput.entryPointSource,
|
|
6538
|
+
isDeclarationOnly: generationInput.isDeclarationOnly ?? false,
|
|
6539
|
+
resolvedExternalTypes: resolveExternalTypes,
|
|
6540
|
+
maxTypeDepth: options.maxDepth
|
|
6541
|
+
},
|
|
6542
|
+
environment: {
|
|
6543
|
+
packageManager: generationInput.packageManager,
|
|
6544
|
+
hasNodeModules,
|
|
6545
|
+
isMonorepo: generationInput.isMonorepo,
|
|
6546
|
+
targetPackage: generationInput.targetPackage
|
|
6547
|
+
},
|
|
6548
|
+
issues: generationIssues
|
|
6549
|
+
} : undefined;
|
|
6550
|
+
const spec = buildOpenPkgSpec(context, resolveExternalTypes, generation);
|
|
6471
6551
|
const danglingRefs = collectDanglingRefs(spec);
|
|
6472
6552
|
for (const ref of danglingRefs) {
|
|
6473
|
-
|
|
6553
|
+
const issue = {
|
|
6554
|
+
code: "DANGLING_REF",
|
|
6474
6555
|
message: `Type '${ref}' is referenced but not defined in types[].`,
|
|
6475
6556
|
severity: "warning",
|
|
6476
6557
|
suggestion: hasNodeModules ? "The type may be from an external package. Check import paths." : "Run npm/bun install to resolve external types."
|
|
6477
|
-
}
|
|
6558
|
+
};
|
|
6559
|
+
specDiagnostics.push(issue);
|
|
6560
|
+
if (generation) {
|
|
6561
|
+
generation.issues.push(issue);
|
|
6562
|
+
}
|
|
6478
6563
|
}
|
|
6479
6564
|
const externalTypes = collectExternalTypes(spec);
|
|
6480
6565
|
if (externalTypes.length > 0) {
|
|
6481
|
-
|
|
6566
|
+
const issue = {
|
|
6567
|
+
code: "EXTERNAL_TYPE_STUBS",
|
|
6482
6568
|
message: `${externalTypes.length} external type(s) could not be fully resolved: ${externalTypes.slice(0, 5).join(", ")}${externalTypes.length > 5 ? "..." : ""}`,
|
|
6483
6569
|
severity: "warning",
|
|
6484
6570
|
suggestion: hasNodeModules ? "Types are from external packages. Full resolution requires type declarations." : "Run npm/bun install to resolve external type definitions."
|
|
6485
|
-
}
|
|
6571
|
+
};
|
|
6572
|
+
specDiagnostics.push(issue);
|
|
6573
|
+
if (generation) {
|
|
6574
|
+
generation.issues.push(issue);
|
|
6575
|
+
}
|
|
6486
6576
|
}
|
|
6487
6577
|
const sourceFiles = program.getSourceFiles().filter((sf) => !sf.isDeclarationFile && sf.fileName.startsWith(baseDir)).map((sf) => sf.fileName);
|
|
6488
6578
|
return {
|
|
@@ -8142,7 +8232,7 @@ class DocCov {
|
|
|
8142
8232
|
packageDir,
|
|
8143
8233
|
content: code,
|
|
8144
8234
|
options: this.options
|
|
8145
|
-
});
|
|
8235
|
+
}, analyzeOptions.generationInput);
|
|
8146
8236
|
const filterOutcome = this.applySpecFilters(analysis.spec, analyzeOptions.filters);
|
|
8147
8237
|
return {
|
|
8148
8238
|
spec: filterOutcome.spec,
|
|
@@ -8177,7 +8267,7 @@ class DocCov {
|
|
|
8177
8267
|
packageDir,
|
|
8178
8268
|
content,
|
|
8179
8269
|
options: this.options
|
|
8180
|
-
});
|
|
8270
|
+
}, analyzeOptions.generationInput);
|
|
8181
8271
|
const filterOutcome = this.applySpecFilters(analysis.spec, analyzeOptions.filters);
|
|
8182
8272
|
const metadata = this.normalizeMetadata(analysis.metadata);
|
|
8183
8273
|
const result = {
|
|
@@ -8452,130 +8542,204 @@ function extractSpecSummary(spec) {
|
|
|
8452
8542
|
drift
|
|
8453
8543
|
};
|
|
8454
8544
|
}
|
|
8455
|
-
|
|
8456
|
-
|
|
8457
|
-
|
|
8458
|
-
|
|
8459
|
-
|
|
8460
|
-
|
|
8461
|
-
|
|
8462
|
-
|
|
8463
|
-
|
|
8464
|
-
|
|
8465
|
-
|
|
8466
|
-
}
|
|
8467
|
-
async detectPackage(packageName) {
|
|
8468
|
-
this.emit({ stage: "detecting", message: "Detecting project structure...", progress: 10 });
|
|
8469
|
-
const mono = await detectMonorepo(this.fs);
|
|
8470
|
-
if (mono.isMonorepo) {
|
|
8471
|
-
if (!packageName) {
|
|
8472
|
-
const publicPackages = mono.packages.filter((p) => !p.private);
|
|
8473
|
-
throw new MonorepoRequiresPackageError(publicPackages.map((p) => p.name));
|
|
8474
|
-
}
|
|
8475
|
-
const pkg = findPackageByName(mono.packages, packageName);
|
|
8476
|
-
if (!pkg) {
|
|
8477
|
-
throw new Error(`Package "${packageName}" not found. Available: ${mono.packages.map((p) => p.name).join(", ")}`);
|
|
8478
|
-
}
|
|
8479
|
-
this.emit({ stage: "detecting", message: `Found package: ${pkg.name}`, progress: 15 });
|
|
8480
|
-
return { targetPath: pkg.path, resolvedPackage: pkg.name };
|
|
8481
|
-
}
|
|
8482
|
-
return { targetPath: "." };
|
|
8483
|
-
}
|
|
8484
|
-
async detectEntry(targetPath) {
|
|
8485
|
-
this.emit({ stage: "detecting", message: "Detecting entry point...", progress: 18 });
|
|
8486
|
-
const entry = await detectEntryPoint(this.fs, targetPath);
|
|
8487
|
-
const entryFile = targetPath === "." ? entry.path : `${targetPath}/${entry.path}`;
|
|
8488
|
-
this.emit({
|
|
8489
|
-
stage: "detecting",
|
|
8490
|
-
message: `Entry point: ${entry.path} (from ${entry.source})`,
|
|
8491
|
-
progress: 20
|
|
8492
|
-
});
|
|
8493
|
-
return entryFile;
|
|
8545
|
+
// src/scan/github-context.ts
|
|
8546
|
+
function parseGitHubUrl2(url) {
|
|
8547
|
+
const patterns = [
|
|
8548
|
+
/github\.com\/([^/]+)\/([^/]+?)(?:\.git)?(?:\/|$)/,
|
|
8549
|
+
/^([^/]+)\/([^/]+)$/
|
|
8550
|
+
];
|
|
8551
|
+
for (const pattern of patterns) {
|
|
8552
|
+
const match = url.match(pattern);
|
|
8553
|
+
if (match) {
|
|
8554
|
+
return { owner: match[1], repo: match[2].replace(/\.git$/, "") };
|
|
8555
|
+
}
|
|
8494
8556
|
}
|
|
8495
|
-
|
|
8496
|
-
|
|
8497
|
-
|
|
8498
|
-
|
|
8499
|
-
|
|
8500
|
-
|
|
8501
|
-
|
|
8557
|
+
return null;
|
|
8558
|
+
}
|
|
8559
|
+
async function fetchRawFile(owner, repo, ref, path13) {
|
|
8560
|
+
const url = `https://raw.githubusercontent.com/${owner}/${repo}/${ref}/${path13}`;
|
|
8561
|
+
try {
|
|
8562
|
+
const response = await fetch(url);
|
|
8563
|
+
if (response.ok) {
|
|
8564
|
+
return await response.text();
|
|
8502
8565
|
}
|
|
8503
|
-
|
|
8504
|
-
|
|
8505
|
-
|
|
8506
|
-
|
|
8507
|
-
|
|
8508
|
-
|
|
8509
|
-
|
|
8510
|
-
|
|
8511
|
-
|
|
8512
|
-
|
|
8513
|
-
|
|
8514
|
-
});
|
|
8566
|
+
return null;
|
|
8567
|
+
} catch {
|
|
8568
|
+
return null;
|
|
8569
|
+
}
|
|
8570
|
+
}
|
|
8571
|
+
async function fetchRepoMetadata(owner, repo) {
|
|
8572
|
+
const url = `https://api.github.com/repos/${owner}/${repo}`;
|
|
8573
|
+
const response = await fetch(url, {
|
|
8574
|
+
headers: {
|
|
8575
|
+
Accept: "application/vnd.github.v3+json",
|
|
8576
|
+
"User-Agent": "DocCov-Scanner"
|
|
8515
8577
|
}
|
|
8516
|
-
|
|
8578
|
+
});
|
|
8579
|
+
if (!response.ok) {
|
|
8580
|
+
throw new Error(`Failed to fetch repository: ${response.status} ${response.statusText}`);
|
|
8517
8581
|
}
|
|
8518
|
-
|
|
8519
|
-
|
|
8520
|
-
|
|
8521
|
-
|
|
8522
|
-
|
|
8523
|
-
|
|
8524
|
-
|
|
8525
|
-
|
|
8526
|
-
|
|
8527
|
-
|
|
8528
|
-
|
|
8529
|
-
|
|
8530
|
-
|
|
8531
|
-
|
|
8532
|
-
|
|
8533
|
-
|
|
8534
|
-
|
|
8535
|
-
|
|
8536
|
-
|
|
8537
|
-
|
|
8538
|
-
|
|
8539
|
-
|
|
8540
|
-
|
|
8541
|
-
|
|
8542
|
-
|
|
8543
|
-
|
|
8544
|
-
|
|
8545
|
-
|
|
8546
|
-
|
|
8547
|
-
const
|
|
8548
|
-
const
|
|
8549
|
-
|
|
8550
|
-
await this.install(".");
|
|
8551
|
-
await this.build(".", targetPath);
|
|
8552
|
-
}
|
|
8553
|
-
const spec = await this.analyze(entryFile);
|
|
8554
|
-
this.emit({ stage: "complete", message: "Extracting results...", progress: 95 });
|
|
8555
|
-
const summary = extractSpecSummary(spec);
|
|
8556
|
-
this.emit({ stage: "complete", message: "Scan complete", progress: 100 });
|
|
8582
|
+
const data = await response.json();
|
|
8583
|
+
return {
|
|
8584
|
+
owner,
|
|
8585
|
+
repo,
|
|
8586
|
+
defaultBranch: data.default_branch,
|
|
8587
|
+
description: data.description,
|
|
8588
|
+
language: data.language,
|
|
8589
|
+
topics: data.topics ?? [],
|
|
8590
|
+
isPrivate: data.private
|
|
8591
|
+
};
|
|
8592
|
+
}
|
|
8593
|
+
async function detectPackageManager3(owner, repo, ref) {
|
|
8594
|
+
const lockfiles = [
|
|
8595
|
+
{ name: "bun.lockb", manager: "bun" },
|
|
8596
|
+
{ name: "pnpm-lock.yaml", manager: "pnpm" },
|
|
8597
|
+
{ name: "yarn.lock", manager: "yarn" },
|
|
8598
|
+
{ name: "package-lock.json", manager: "npm" }
|
|
8599
|
+
];
|
|
8600
|
+
for (const { name, manager } of lockfiles) {
|
|
8601
|
+
const content = await fetchRawFile(owner, repo, ref, name);
|
|
8602
|
+
if (content !== null) {
|
|
8603
|
+
return { manager, lockfile: { name, content: content.slice(0, 1e4) } };
|
|
8604
|
+
}
|
|
8605
|
+
}
|
|
8606
|
+
return { manager: "unknown" };
|
|
8607
|
+
}
|
|
8608
|
+
async function detectWorkspace(packageJson, owner, repo, ref) {
|
|
8609
|
+
const pnpmWorkspace = await fetchRawFile(owner, repo, ref, "pnpm-workspace.yaml");
|
|
8610
|
+
if (pnpmWorkspace) {
|
|
8611
|
+
const packagesMatch = pnpmWorkspace.match(/packages:\s*\n((?:\s+-\s+['"]?[^\n]+['"]?\n?)+)/);
|
|
8612
|
+
const packages = packagesMatch ? packagesMatch[1].split(`
|
|
8613
|
+
`).map((line) => line.replace(/^\s+-\s+['"]?/, "").replace(/['"]?\s*$/, "")).filter(Boolean) : undefined;
|
|
8557
8614
|
return {
|
|
8558
|
-
|
|
8559
|
-
|
|
8560
|
-
|
|
8561
|
-
packageName: resolvedPackage ?? options.package,
|
|
8562
|
-
coverage: summary.coverage,
|
|
8563
|
-
exportCount: summary.exportCount,
|
|
8564
|
-
typeCount: summary.typeCount,
|
|
8565
|
-
driftCount: summary.driftCount,
|
|
8566
|
-
undocumented: summary.undocumented,
|
|
8567
|
-
drift: summary.drift
|
|
8615
|
+
isMonorepo: true,
|
|
8616
|
+
tool: "pnpm",
|
|
8617
|
+
packages
|
|
8568
8618
|
};
|
|
8569
8619
|
}
|
|
8620
|
+
const lernaJson = await fetchRawFile(owner, repo, ref, "lerna.json");
|
|
8621
|
+
if (lernaJson) {
|
|
8622
|
+
return { isMonorepo: true, tool: "lerna" };
|
|
8623
|
+
}
|
|
8624
|
+
if (packageJson && typeof packageJson === "object") {
|
|
8625
|
+
const pkg = packageJson;
|
|
8626
|
+
if (pkg.workspaces) {
|
|
8627
|
+
const workspaces = pkg.workspaces;
|
|
8628
|
+
const packages = Array.isArray(workspaces) ? workspaces : workspaces.packages;
|
|
8629
|
+
return {
|
|
8630
|
+
isMonorepo: true,
|
|
8631
|
+
tool: "npm",
|
|
8632
|
+
packages: packages?.filter((p) => typeof p === "string")
|
|
8633
|
+
};
|
|
8634
|
+
}
|
|
8635
|
+
}
|
|
8636
|
+
return { isMonorepo: false };
|
|
8570
8637
|
}
|
|
8571
|
-
|
|
8572
|
-
|
|
8573
|
-
|
|
8574
|
-
|
|
8575
|
-
|
|
8576
|
-
|
|
8577
|
-
|
|
8638
|
+
function detectBuildHints(packageJson, tsconfigJson) {
|
|
8639
|
+
const hints = {
|
|
8640
|
+
hasTypeScript: false,
|
|
8641
|
+
hasWasm: false,
|
|
8642
|
+
hasNativeModules: false,
|
|
8643
|
+
hasBuildScript: false,
|
|
8644
|
+
frameworks: []
|
|
8645
|
+
};
|
|
8646
|
+
if (!packageJson || typeof packageJson !== "object") {
|
|
8647
|
+
return hints;
|
|
8648
|
+
}
|
|
8649
|
+
const pkg = packageJson;
|
|
8650
|
+
const deps = {
|
|
8651
|
+
...typeof pkg.dependencies === "object" ? pkg.dependencies : {},
|
|
8652
|
+
...typeof pkg.devDependencies === "object" ? pkg.devDependencies : {}
|
|
8653
|
+
};
|
|
8654
|
+
hints.hasTypeScript = "typescript" in deps || tsconfigJson !== null;
|
|
8655
|
+
hints.hasWasm = "wasm-pack" in deps || "@aspect-build/rules_esbuild" in deps;
|
|
8656
|
+
hints.hasNativeModules = "node-gyp" in deps || "prebuild" in deps || "napi-rs" in deps;
|
|
8657
|
+
const scripts = typeof pkg.scripts === "object" ? pkg.scripts : {};
|
|
8658
|
+
if (scripts.build) {
|
|
8659
|
+
hints.hasBuildScript = true;
|
|
8660
|
+
hints.buildScript = scripts.build;
|
|
8661
|
+
}
|
|
8662
|
+
const frameworkDeps = [
|
|
8663
|
+
{ dep: "react", name: "React" },
|
|
8664
|
+
{ dep: "vue", name: "Vue" },
|
|
8665
|
+
{ dep: "svelte", name: "Svelte" },
|
|
8666
|
+
{ dep: "next", name: "Next.js" },
|
|
8667
|
+
{ dep: "nuxt", name: "Nuxt" },
|
|
8668
|
+
{ dep: "astro", name: "Astro" },
|
|
8669
|
+
{ dep: "express", name: "Express" },
|
|
8670
|
+
{ dep: "fastify", name: "Fastify" },
|
|
8671
|
+
{ dep: "hono", name: "Hono" }
|
|
8672
|
+
];
|
|
8673
|
+
for (const { dep, name } of frameworkDeps) {
|
|
8674
|
+
if (dep in deps) {
|
|
8675
|
+
hints.frameworks.push(name);
|
|
8676
|
+
}
|
|
8677
|
+
}
|
|
8678
|
+
return hints;
|
|
8679
|
+
}
|
|
8680
|
+
async function fetchGitHubContext(repoUrl, ref) {
|
|
8681
|
+
const parsed = parseGitHubUrl2(repoUrl);
|
|
8682
|
+
if (!parsed) {
|
|
8683
|
+
throw new Error(`Invalid GitHub URL: ${repoUrl}`);
|
|
8684
|
+
}
|
|
8685
|
+
const { owner, repo } = parsed;
|
|
8686
|
+
const metadata = await fetchRepoMetadata(owner, repo);
|
|
8687
|
+
const targetRef = ref ?? metadata.defaultBranch;
|
|
8688
|
+
const [packageJsonRaw, tsconfigJsonRaw, pmResult] = await Promise.all([
|
|
8689
|
+
fetchRawFile(owner, repo, targetRef, "package.json"),
|
|
8690
|
+
fetchRawFile(owner, repo, targetRef, "tsconfig.json"),
|
|
8691
|
+
detectPackageManager3(owner, repo, targetRef)
|
|
8692
|
+
]);
|
|
8693
|
+
let packageJson = null;
|
|
8694
|
+
let tsconfigJson = null;
|
|
8695
|
+
if (packageJsonRaw) {
|
|
8696
|
+
try {
|
|
8697
|
+
packageJson = JSON.parse(packageJsonRaw);
|
|
8698
|
+
} catch {}
|
|
8699
|
+
}
|
|
8700
|
+
if (tsconfigJsonRaw) {
|
|
8701
|
+
try {
|
|
8702
|
+
tsconfigJson = JSON.parse(tsconfigJsonRaw);
|
|
8703
|
+
} catch {}
|
|
8704
|
+
}
|
|
8705
|
+
const workspace = await detectWorkspace(packageJson, owner, repo, targetRef);
|
|
8706
|
+
const buildHints = detectBuildHints(packageJson, tsconfigJson);
|
|
8707
|
+
return {
|
|
8708
|
+
metadata,
|
|
8709
|
+
ref: targetRef,
|
|
8710
|
+
packageManager: pmResult.manager,
|
|
8711
|
+
workspace,
|
|
8712
|
+
buildHints,
|
|
8713
|
+
files: {
|
|
8714
|
+
packageJson: packageJsonRaw ?? undefined,
|
|
8715
|
+
tsconfigJson: tsconfigJsonRaw ?? undefined,
|
|
8716
|
+
lockfile: pmResult.lockfile
|
|
8717
|
+
}
|
|
8718
|
+
};
|
|
8719
|
+
}
|
|
8720
|
+
async function listWorkspacePackages(owner, repo, ref, patterns) {
|
|
8721
|
+
const packages = [];
|
|
8722
|
+
for (const pattern of patterns) {
|
|
8723
|
+
const baseDir = pattern.replace(/\/\*.*$/, "");
|
|
8724
|
+
try {
|
|
8725
|
+
const url = `https://api.github.com/repos/${owner}/${repo}/contents/${baseDir}?ref=${ref}`;
|
|
8726
|
+
const response = await fetch(url, {
|
|
8727
|
+
headers: {
|
|
8728
|
+
Accept: "application/vnd.github.v3+json",
|
|
8729
|
+
"User-Agent": "DocCov-Scanner"
|
|
8730
|
+
}
|
|
8731
|
+
});
|
|
8732
|
+
if (response.ok) {
|
|
8733
|
+
const contents = await response.json();
|
|
8734
|
+
for (const item of contents) {
|
|
8735
|
+
if (item.type === "dir") {
|
|
8736
|
+
packages.push(`${baseDir}/${item.name}`);
|
|
8737
|
+
}
|
|
8738
|
+
}
|
|
8739
|
+
}
|
|
8740
|
+
} catch {}
|
|
8578
8741
|
}
|
|
8742
|
+
return packages;
|
|
8579
8743
|
}
|
|
8580
8744
|
export {
|
|
8581
8745
|
validateSpecCache,
|
|
@@ -8592,6 +8756,7 @@ export {
|
|
|
8592
8756
|
runExample,
|
|
8593
8757
|
resolveTarget,
|
|
8594
8758
|
readPackageJson,
|
|
8759
|
+
parseGitHubUrl2 as parseScanGitHubUrl,
|
|
8595
8760
|
parseMarkdownFiles,
|
|
8596
8761
|
parseMarkdownFile,
|
|
8597
8762
|
parseListFlag,
|
|
@@ -8604,6 +8769,7 @@ export {
|
|
|
8604
8769
|
mergeConfig,
|
|
8605
8770
|
loadSpecCache,
|
|
8606
8771
|
loadCachedReport,
|
|
8772
|
+
listWorkspacePackages,
|
|
8607
8773
|
isFixableDrift,
|
|
8608
8774
|
isExecutableLang,
|
|
8609
8775
|
isCachedReportValid,
|
|
@@ -8626,6 +8792,7 @@ export {
|
|
|
8626
8792
|
getDriftSummary,
|
|
8627
8793
|
getDocumentedExports,
|
|
8628
8794
|
getDocsImpactSummary,
|
|
8795
|
+
getDiffReportPath,
|
|
8629
8796
|
getDefaultConfig,
|
|
8630
8797
|
getCoverageRules,
|
|
8631
8798
|
generateReportFromEnriched,
|
|
@@ -8641,12 +8808,14 @@ export {
|
|
|
8641
8808
|
findDeprecatedReferences,
|
|
8642
8809
|
fetchSpecFromGitHub,
|
|
8643
8810
|
fetchSpec,
|
|
8811
|
+
fetchGitHubContext,
|
|
8644
8812
|
extractSpecSummary,
|
|
8645
8813
|
extractPackageSpec,
|
|
8646
8814
|
extractImports,
|
|
8647
8815
|
extractFunctionCalls,
|
|
8648
8816
|
evaluateQuality,
|
|
8649
8817
|
evaluateExportQuality,
|
|
8818
|
+
ensureSpecCoverage,
|
|
8650
8819
|
enrichSpec,
|
|
8651
8820
|
diffSpecWithDocs,
|
|
8652
8821
|
diffHashes,
|
|
@@ -8664,6 +8833,7 @@ export {
|
|
|
8664
8833
|
clearSpecCache,
|
|
8665
8834
|
categorizeDrifts,
|
|
8666
8835
|
categorizeDrift,
|
|
8836
|
+
calculateAggregateCoverage,
|
|
8667
8837
|
buildRawUrl,
|
|
8668
8838
|
buildExportRegistry,
|
|
8669
8839
|
buildDisplayUrl,
|
|
@@ -8676,7 +8846,6 @@ export {
|
|
|
8676
8846
|
analyzeDocsImpact,
|
|
8677
8847
|
analyze,
|
|
8678
8848
|
VALIDATION_INFO,
|
|
8679
|
-
ScanOrchestrator,
|
|
8680
8849
|
SandboxFileSystem,
|
|
8681
8850
|
STYLE_RULES,
|
|
8682
8851
|
SPEC_CACHE_FILE,
|
|
@@ -8684,7 +8853,6 @@ export {
|
|
|
8684
8853
|
REPORT_EXTENSIONS,
|
|
8685
8854
|
OpenPkg,
|
|
8686
8855
|
NodeFileSystem,
|
|
8687
|
-
MonorepoRequiresPackageError,
|
|
8688
8856
|
DocCov,
|
|
8689
8857
|
DEFAULT_REPORT_PATH,
|
|
8690
8858
|
DEFAULT_REPORT_DIR,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@doccov/sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"description": "DocCov SDK - Documentation coverage and drift detection for TypeScript",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"typescript",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"dist"
|
|
40
40
|
],
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@openpkg-ts/spec": "^0.
|
|
42
|
+
"@openpkg-ts/spec": "^0.9.0",
|
|
43
43
|
"@vercel/sandbox": "^1.0.3",
|
|
44
44
|
"mdast": "^3.0.0",
|
|
45
45
|
"remark-mdx": "^3.1.0",
|