@doccov/sdk 0.12.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 +243 -208
- package/dist/index.js +262 -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
|
*/
|
|
@@ -225,7 +225,7 @@ declare function ensureSpecCoverage(spec: OpenPkgSpec): OpenPkgSpec & {
|
|
|
225
225
|
coverageScore: number;
|
|
226
226
|
};
|
|
227
227
|
};
|
|
228
|
-
import { OpenPkg as
|
|
228
|
+
import { OpenPkg as OpenPkg3, SpecDocDrift as SpecDocDrift2, SpecDocsMetadata, SpecExport as SpecExport3 } from "@openpkg-ts/spec";
|
|
229
229
|
import { SpecExport as SpecExport2, SpecExportKind } from "@openpkg-ts/spec";
|
|
230
230
|
import * as TS from "typescript";
|
|
231
231
|
/**
|
|
@@ -445,7 +445,7 @@ type EnrichedDocsMetadata = SpecDocsMetadata & {
|
|
|
445
445
|
* An enriched OpenPkg spec with computed documentation metadata.
|
|
446
446
|
* Extends OpenPkg with per-and aggregate coverage data.
|
|
447
447
|
*/
|
|
448
|
-
type EnrichedOpenPkg = Omit<
|
|
448
|
+
type EnrichedOpenPkg = Omit<OpenPkg3, "exports"> & {
|
|
449
449
|
exports: EnrichedExport[];
|
|
450
450
|
docs?: EnrichedDocsMetadata;
|
|
451
451
|
/** Drift summary with category breakdown (if drift exists) */
|
|
@@ -490,8 +490,8 @@ interface EnrichOptions {
|
|
|
490
490
|
* console.log(enriched.docs?.missing); // e.g., ['has-examples']
|
|
491
491
|
* ```
|
|
492
492
|
*/
|
|
493
|
-
declare function enrichSpec(spec:
|
|
494
|
-
import { OpenPkg as
|
|
493
|
+
declare function enrichSpec(spec: OpenPkg3, options?: EnrichOptions): EnrichedOpenPkg;
|
|
494
|
+
import { OpenPkg as OpenPkg4 } from "@openpkg-ts/spec";
|
|
495
495
|
import { DriftCategory as DriftCategory2, SpecDocDrift as SpecDocDrift3 } from "@openpkg-ts/spec";
|
|
496
496
|
/**
|
|
497
497
|
* DocCov report schema version.
|
|
@@ -686,7 +686,7 @@ interface DocCovReport {
|
|
|
686
686
|
* console.log(`Coverage: ${report.coverage.score}%`);
|
|
687
687
|
* ```
|
|
688
688
|
*/
|
|
689
|
-
declare function generateReport(spec:
|
|
689
|
+
declare function generateReport(spec: OpenPkg4): DocCovReport;
|
|
690
690
|
/**
|
|
691
691
|
* Generate a DocCov report from an already-enriched spec.
|
|
692
692
|
*
|
|
@@ -755,7 +755,7 @@ declare function hashFiles(filePaths: string[], cwd: string): Record<string, str
|
|
|
755
755
|
* @returns Array of file paths that changed, were added, or were removed
|
|
756
756
|
*/
|
|
757
757
|
declare function diffHashes(cached: Record<string, string>, current: Record<string, string>): string[];
|
|
758
|
-
import { OpenPkg as
|
|
758
|
+
import { OpenPkg as OpenPkg5 } from "@openpkg-ts/spec";
|
|
759
759
|
/** Current cache format version */
|
|
760
760
|
declare const CACHE_VERSION = "1.0.0";
|
|
761
761
|
/** Default cache file path */
|
|
@@ -790,7 +790,7 @@ interface SpecCache {
|
|
|
790
790
|
/** Analysis configuration that affects output */
|
|
791
791
|
config: SpecCacheConfig;
|
|
792
792
|
/** The cached OpenPkg spec */
|
|
793
|
-
spec:
|
|
793
|
+
spec: OpenPkg5;
|
|
794
794
|
}
|
|
795
795
|
/**
|
|
796
796
|
* Result of cache validation.
|
|
@@ -833,7 +833,7 @@ declare function loadSpecCache(cwd: string): SpecCache | null;
|
|
|
833
833
|
* @param spec - OpenPkg spec to cache
|
|
834
834
|
* @param context - Cache context with file paths and config
|
|
835
835
|
*/
|
|
836
|
-
declare function saveSpecCache(spec:
|
|
836
|
+
declare function saveSpecCache(spec: OpenPkg5, context: CacheContext): void;
|
|
837
837
|
/**
|
|
838
838
|
* Validate if cached spec is still valid.
|
|
839
839
|
*
|
|
@@ -1477,7 +1477,7 @@ declare function categorizeDrifts(drifts: SpecDocDrift4[]): {
|
|
|
1477
1477
|
fixable: SpecDocDrift4[];
|
|
1478
1478
|
nonFixable: SpecDocDrift4[];
|
|
1479
1479
|
};
|
|
1480
|
-
import { OpenPkg as
|
|
1480
|
+
import { OpenPkg as OpenPkg6 } from "@openpkg-ts/spec";
|
|
1481
1481
|
/**
|
|
1482
1482
|
* Parsed components of a GitHub URL.
|
|
1483
1483
|
*/
|
|
@@ -1570,7 +1570,7 @@ declare function buildRawUrl(parsed: ParsedGitHubUrl, filePath: string): string;
|
|
|
1570
1570
|
* }
|
|
1571
1571
|
* ```
|
|
1572
1572
|
*/
|
|
1573
|
-
declare function fetchSpecFromGitHub(parsed: ParsedGitHubUrl): Promise<
|
|
1573
|
+
declare function fetchSpecFromGitHub(parsed: ParsedGitHubUrl): Promise<OpenPkg6 | null>;
|
|
1574
1574
|
/**
|
|
1575
1575
|
* Fetch an OpenPkg spec from a GitHub repository by owner/repo/branch.
|
|
1576
1576
|
*
|
|
@@ -1581,84 +1581,22 @@ declare function fetchSpecFromGitHub(parsed: ParsedGitHubUrl): Promise<OpenPkg5
|
|
|
1581
1581
|
* @param branch - Branch name (default: 'main')
|
|
1582
1582
|
* @returns The OpenPkg spec, or null if not found
|
|
1583
1583
|
*/
|
|
1584
|
-
declare function fetchSpec(owner: string, repo: string, branch?: string): Promise<
|
|
1585
|
-
/**
|
|
1586
|
-
* Scan types for CLI, API, and SDK consumers.
|
|
1587
|
-
* Single source of truth for scan-related interfaces.
|
|
1588
|
-
*/
|
|
1589
|
-
/**
|
|
1590
|
-
* Result of scanning a repository for documentation coverage.
|
|
1591
|
-
* Used by CLI scan command, API endpoints, and SDK consumers.
|
|
1592
|
-
*/
|
|
1593
|
-
interface ScanResult {
|
|
1594
|
-
/** GitHub repository owner */
|
|
1595
|
-
owner: string;
|
|
1596
|
-
/** GitHub repository name */
|
|
1597
|
-
repo: string;
|
|
1598
|
-
/** Git ref (branch/tag) that was scanned */
|
|
1599
|
-
ref: string;
|
|
1600
|
-
/** Package name if scanning a monorepo package */
|
|
1601
|
-
packageName?: string;
|
|
1602
|
-
/** Overall documentation coverage percentage (0-100) */
|
|
1603
|
-
coverage: number;
|
|
1604
|
-
/** Number of public exports analyzed */
|
|
1605
|
-
exportCount: number;
|
|
1606
|
-
/** Number of types analyzed */
|
|
1607
|
-
typeCount: number;
|
|
1608
|
-
/** Number of documentation drift issues found */
|
|
1609
|
-
driftCount: number;
|
|
1610
|
-
/** Names of exports missing documentation */
|
|
1611
|
-
undocumented: string[];
|
|
1612
|
-
/** Drift issues found during analysis */
|
|
1613
|
-
drift: DriftIssue[];
|
|
1614
|
-
}
|
|
1584
|
+
declare function fetchSpec(owner: string, repo: string, branch?: string): Promise<OpenPkg6 | null>;
|
|
1615
1585
|
/**
|
|
1616
|
-
*
|
|
1586
|
+
* Progress event for installation status updates.
|
|
1617
1587
|
*/
|
|
1618
|
-
interface
|
|
1619
|
-
/**
|
|
1620
|
-
|
|
1621
|
-
/** Type of drift (e.g., 'param-mismatch', 'return-type') */
|
|
1622
|
-
type: string;
|
|
1623
|
-
/** Human-readable description of the issue */
|
|
1624
|
-
issue: string;
|
|
1625
|
-
/** Optional suggestion for fixing the issue */
|
|
1626
|
-
suggestion?: string;
|
|
1627
|
-
}
|
|
1628
|
-
/**
|
|
1629
|
-
* Options for running a scan.
|
|
1630
|
-
*/
|
|
1631
|
-
interface ScanOptions {
|
|
1632
|
-
/** GitHub URL or owner/repo shorthand */
|
|
1633
|
-
url: string;
|
|
1634
|
-
/** Git ref (branch/tag) to scan */
|
|
1635
|
-
ref?: string;
|
|
1636
|
-
/** Target package name for monorepos */
|
|
1637
|
-
package?: string;
|
|
1638
|
-
/** Skip dependency installation */
|
|
1639
|
-
skipInstall?: boolean;
|
|
1640
|
-
/** Skip external type resolution */
|
|
1641
|
-
skipResolve?: boolean;
|
|
1642
|
-
}
|
|
1643
|
-
/**
|
|
1644
|
-
* Stages of the scan pipeline.
|
|
1645
|
-
*/
|
|
1646
|
-
type ProgressStage = "cloning" | "detecting" | "installing" | "building" | "analyzing" | "complete";
|
|
1647
|
-
/**
|
|
1648
|
-
* Progress event emitted during scan operations.
|
|
1649
|
-
*/
|
|
1650
|
-
interface ProgressEvent {
|
|
1651
|
-
/** Current stage of the scan */
|
|
1652
|
-
stage: ProgressStage;
|
|
1588
|
+
interface InstallProgressEvent {
|
|
1589
|
+
/** Current stage */
|
|
1590
|
+
stage: "installing";
|
|
1653
1591
|
/** Human-readable message */
|
|
1654
1592
|
message: string;
|
|
1655
1593
|
/** Progress percentage (0-100), if known */
|
|
1656
1594
|
progress?: number;
|
|
1657
1595
|
}
|
|
1658
1596
|
/**
|
|
1659
|
-
* Callback for receiving progress events.
|
|
1597
|
+
* Callback for receiving installation progress events.
|
|
1660
1598
|
*/
|
|
1661
|
-
type
|
|
1599
|
+
type InstallProgressCallback = (event: InstallProgressEvent) => void;
|
|
1662
1600
|
/**
|
|
1663
1601
|
* Result of running a command.
|
|
1664
1602
|
*/
|
|
@@ -1702,7 +1640,7 @@ interface InstallOptions {
|
|
|
1702
1640
|
/** Order of fallback package managers to try */
|
|
1703
1641
|
fallbackOrder?: PackageManager[];
|
|
1704
1642
|
/** Progress callback for status updates */
|
|
1705
|
-
onProgress?:
|
|
1643
|
+
onProgress?: InstallProgressCallback;
|
|
1706
1644
|
}
|
|
1707
1645
|
/**
|
|
1708
1646
|
* Install dependencies for a project.
|
|
@@ -1902,7 +1840,7 @@ declare function getDocumentedExports(markdownFiles: MarkdownDocFile[], exportNa
|
|
|
1902
1840
|
* Get all exports that lack documentation
|
|
1903
1841
|
*/
|
|
1904
1842
|
declare function getUndocumentedExports(markdownFiles: MarkdownDocFile[], exportNames: string[]): string[];
|
|
1905
|
-
import { CategorizedBreaking, OpenPkg as
|
|
1843
|
+
import { CategorizedBreaking, OpenPkg as OpenPkg8, SpecDiff as SpecDiff2 } from "@openpkg-ts/spec";
|
|
1906
1844
|
/**
|
|
1907
1845
|
* Extended spec diff result with docs impact
|
|
1908
1846
|
*/
|
|
@@ -1948,7 +1886,7 @@ interface DiffWithDocsOptions {
|
|
|
1948
1886
|
* }
|
|
1949
1887
|
* ```
|
|
1950
1888
|
*/
|
|
1951
|
-
declare function diffSpecWithDocs(oldSpec:
|
|
1889
|
+
declare function diffSpecWithDocs(oldSpec: OpenPkg8, newSpec: OpenPkg8, options?: DiffWithDocsOptions): SpecDiffWithDocs;
|
|
1952
1890
|
/**
|
|
1953
1891
|
* Check if a diff has any docs impact
|
|
1954
1892
|
*/
|
|
@@ -2004,7 +1942,29 @@ declare function findExportReferences(files: MarkdownDocFile[], exportNames: str
|
|
|
2004
1942
|
* Check if a code block references any of the given names
|
|
2005
1943
|
*/
|
|
2006
1944
|
declare function blockReferencesExport(block: MarkdownCodeBlock, exportName: string): boolean;
|
|
2007
|
-
|
|
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 {
|
|
2008
1968
|
message: string;
|
|
2009
1969
|
severity: "error" | "warning" | "info";
|
|
2010
1970
|
suggestion?: string;
|
|
@@ -2016,7 +1976,7 @@ interface Diagnostic {
|
|
|
2016
1976
|
}
|
|
2017
1977
|
interface AnalysisResult {
|
|
2018
1978
|
spec: OpenPkgSpec;
|
|
2019
|
-
diagnostics:
|
|
1979
|
+
diagnostics: Diagnostic2[];
|
|
2020
1980
|
metadata: AnalysisMetadata;
|
|
2021
1981
|
/** True if result came from cache (no fresh analysis) */
|
|
2022
1982
|
fromCache?: boolean;
|
|
@@ -2034,6 +1994,8 @@ interface AnalysisMetadata {
|
|
|
2034
1994
|
}
|
|
2035
1995
|
interface AnalyzeOptions {
|
|
2036
1996
|
filters?: FilterOptions;
|
|
1997
|
+
/** Generation metadata input (entry point info, tool version, etc.) */
|
|
1998
|
+
generationInput?: GenerationInput;
|
|
2037
1999
|
}
|
|
2038
2000
|
declare class DocCov {
|
|
2039
2001
|
private readonly options;
|
|
@@ -2068,7 +2030,7 @@ declare class DocCov {
|
|
|
2068
2030
|
declare function analyze(code: string, options?: AnalyzeOptions): Promise<OpenPkgSpec>;
|
|
2069
2031
|
declare function analyzeFile(filePath: string, options?: AnalyzeOptions): Promise<OpenPkgSpec>;
|
|
2070
2032
|
/** @deprecated Use DocCov instead */
|
|
2071
|
-
declare const
|
|
2033
|
+
declare const OpenPkg9: typeof DocCov;
|
|
2072
2034
|
import { SpecExport as SpecExport6 } from "@openpkg-ts/spec";
|
|
2073
2035
|
import { SpecExportKind as SpecExportKind2 } from "@openpkg-ts/spec";
|
|
2074
2036
|
/**
|
|
@@ -2179,127 +2141,18 @@ interface ResolvedTarget {
|
|
|
2179
2141
|
* ```
|
|
2180
2142
|
*/
|
|
2181
2143
|
declare function resolveTarget(fs: FileSystem, options: ResolveTargetOptions): Promise<ResolvedTarget>;
|
|
2182
|
-
import { OpenPkg as OpenPkg9 } from "@openpkg-ts/spec";
|
|
2183
2144
|
/**
|
|
2184
|
-
*
|
|
2145
|
+
* A documentation drift issue in a spec summary.
|
|
2185
2146
|
*/
|
|
2186
|
-
interface
|
|
2187
|
-
/**
|
|
2188
|
-
|
|
2189
|
-
/**
|
|
2190
|
-
|
|
2191
|
-
/**
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
* Context for the current scan operation.
|
|
2196
|
-
*/
|
|
2197
|
-
interface ScanContext {
|
|
2198
|
-
/** Parsed GitHub URL info */
|
|
2199
|
-
parsed: ParsedGitHubUrl;
|
|
2200
|
-
/** Target package name for monorepos */
|
|
2201
|
-
packageName?: string;
|
|
2202
|
-
/** Working directory for the scan */
|
|
2203
|
-
workDir: string;
|
|
2204
|
-
/** Entry point file path */
|
|
2205
|
-
entryFile?: string;
|
|
2206
|
-
}
|
|
2207
|
-
/**
|
|
2208
|
-
* Orchestrates the scan workflow.
|
|
2209
|
-
*
|
|
2210
|
-
* The orchestrator coordinates:
|
|
2211
|
-
* 1. Repository cloning (for remote URLs)
|
|
2212
|
-
* 2. Monorepo detection and package resolution
|
|
2213
|
-
* 3. Entry point detection
|
|
2214
|
-
* 4. Dependency installation
|
|
2215
|
-
* 5. Build execution (if needed)
|
|
2216
|
-
* 6. Documentation analysis
|
|
2217
|
-
* 7. Summary extraction
|
|
2218
|
-
*
|
|
2219
|
-
* It's designed to be FileSystem-agnostic so it works with both:
|
|
2220
|
-
* - NodeFileSystem (CLI - local execution)
|
|
2221
|
-
* - SandboxFileSystem (API - isolated execution)
|
|
2222
|
-
*
|
|
2223
|
-
* @example
|
|
2224
|
-
* ```typescript
|
|
2225
|
-
* import { ScanOrchestrator, NodeFileSystem, createNodeCommandRunner } from '@doccov/sdk';
|
|
2226
|
-
*
|
|
2227
|
-
* const fs = new NodeFileSystem('/path/to/repo');
|
|
2228
|
-
* const orchestrator = new ScanOrchestrator(fs, {
|
|
2229
|
-
* commandRunner: createNodeCommandRunner(),
|
|
2230
|
-
* onProgress: (event) => console.log(event.message),
|
|
2231
|
-
* });
|
|
2232
|
-
*
|
|
2233
|
-
* const result = await orchestrator.scan({
|
|
2234
|
-
* url: 'https://github.com/owner/repo',
|
|
2235
|
-
* ref: 'main',
|
|
2236
|
-
* });
|
|
2237
|
-
*
|
|
2238
|
-
* console.log(`Coverage: ${result.coverage}%`);
|
|
2239
|
-
* ```
|
|
2240
|
-
*/
|
|
2241
|
-
declare class ScanOrchestrator {
|
|
2242
|
-
private readonly fs;
|
|
2243
|
-
private readonly options;
|
|
2244
|
-
constructor(fs: FileSystem, options?: ScanOrchestratorOptions);
|
|
2245
|
-
/**
|
|
2246
|
-
* Emit a progress event.
|
|
2247
|
-
*/
|
|
2248
|
-
private emit;
|
|
2249
|
-
/**
|
|
2250
|
-
* Detect monorepo and resolve target package.
|
|
2251
|
-
*
|
|
2252
|
-
* @param packageName - Target package name (required for monorepos)
|
|
2253
|
-
* @returns Target directory path (relative to workDir)
|
|
2254
|
-
* @throws Error if monorepo requires --package flag
|
|
2255
|
-
*/
|
|
2256
|
-
detectPackage(packageName?: string): Promise<{
|
|
2257
|
-
targetPath: string;
|
|
2258
|
-
resolvedPackage?: string;
|
|
2259
|
-
}>;
|
|
2260
|
-
/**
|
|
2261
|
-
* Detect entry point for the package.
|
|
2262
|
-
*
|
|
2263
|
-
* @param targetPath - Path to the package directory
|
|
2264
|
-
* @returns Entry point file path (relative to workDir)
|
|
2265
|
-
*/
|
|
2266
|
-
detectEntry(targetPath: string): Promise<string>;
|
|
2267
|
-
/**
|
|
2268
|
-
* Install dependencies for the project.
|
|
2269
|
-
*
|
|
2270
|
-
* @param workDir - Working directory (absolute path)
|
|
2271
|
-
* @returns Installation result
|
|
2272
|
-
*/
|
|
2273
|
-
install(workDir: string): Promise<InstallResult>;
|
|
2274
|
-
/**
|
|
2275
|
-
* Run build if needed.
|
|
2276
|
-
*
|
|
2277
|
-
* @param workDir - Working directory (absolute path)
|
|
2278
|
-
* @param targetPath - Target package path (relative)
|
|
2279
|
-
*/
|
|
2280
|
-
build(workDir: string, targetPath: string): Promise<void>;
|
|
2281
|
-
/**
|
|
2282
|
-
* Run documentation analysis.
|
|
2283
|
-
*
|
|
2284
|
-
* @param entryFile - Path to entry file (absolute)
|
|
2285
|
-
* @returns OpenPkg spec
|
|
2286
|
-
*/
|
|
2287
|
-
analyze(entryFile: string): Promise<OpenPkg9>;
|
|
2288
|
-
/**
|
|
2289
|
-
* Run a complete scan workflow.
|
|
2290
|
-
*
|
|
2291
|
-
* @param options - Scan options
|
|
2292
|
-
* @returns Scan result with coverage statistics
|
|
2293
|
-
*/
|
|
2294
|
-
scan(options: ScanOptions): Promise<ScanResult>;
|
|
2295
|
-
}
|
|
2296
|
-
/**
|
|
2297
|
-
* Error thrown when a monorepo is detected but no package is specified.
|
|
2298
|
-
*/
|
|
2299
|
-
declare class MonorepoRequiresPackageError extends Error {
|
|
2300
|
-
/** Available package names */
|
|
2301
|
-
readonly availablePackages: string[];
|
|
2302
|
-
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;
|
|
2303
2156
|
}
|
|
2304
2157
|
/**
|
|
2305
2158
|
* Summary of a spec's documentation coverage.
|
|
@@ -2317,7 +2170,7 @@ interface SpecSummary {
|
|
|
2317
2170
|
/** Names of undocumented or partially documented exports */
|
|
2318
2171
|
undocumented: string[];
|
|
2319
2172
|
/** Drift issues */
|
|
2320
|
-
drift:
|
|
2173
|
+
drift: SummaryDriftIssue[];
|
|
2321
2174
|
}
|
|
2322
2175
|
/**
|
|
2323
2176
|
* Extract a summary from an enriched OpenPkg spec.
|
|
@@ -2342,6 +2195,188 @@ interface SpecSummary {
|
|
|
2342
2195
|
*/
|
|
2343
2196
|
declare function extractSpecSummary(spec: EnrichedOpenPkg): SpecSummary;
|
|
2344
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
|
+
/**
|
|
2345
2380
|
* Type-check a single example
|
|
2346
2381
|
*/
|
|
2347
2382
|
declare function typecheckExample(example: string, packagePath: string, options?: TypecheckOptions): ExampleTypeError[];
|
|
@@ -2349,4 +2384,4 @@ declare function typecheckExample(example: string, packagePath: string, options?
|
|
|
2349
2384
|
* Type-check multiple examples
|
|
2350
2385
|
*/
|
|
2351
2386
|
declare function typecheckExamples(examples: string[], packagePath: string, options?: TypecheckOptions): TypecheckResult;
|
|
2352
|
-
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, getDiffReportPath, getDefaultConfig, getCoverageRules, generateReportFromEnriched, generateReport, generateFixesForExport, generateFix, formatPackageList, formatDriftSummaryLine, findRemovedReferences, findPackageByName, findJSDocLocation, findExportReferences, findDeprecatedReferences, fetchSpecFromGitHub, fetchSpec, 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, 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
|
@@ -6147,10 +6147,30 @@ class TypeRegistry {
|
|
|
6147
6147
|
}
|
|
6148
6148
|
|
|
6149
6149
|
// src/analysis/spec-builder.ts
|
|
6150
|
-
function
|
|
6151
|
-
|
|
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;
|
|
6152
6171
|
const packageJsonPath = path9.join(baseDir, "package.json");
|
|
6153
6172
|
const packageJson = fs8.existsSync(packageJsonPath) ? JSON.parse(fs8.readFileSync(packageJsonPath, "utf-8")) : {};
|
|
6173
|
+
const generationInfo = generation ?? createDefaultGenerationInfo(path9.relative(baseDir, entryFile));
|
|
6154
6174
|
const spec = {
|
|
6155
6175
|
$schema: SCHEMA_URL,
|
|
6156
6176
|
openpkg: SCHEMA_VERSION,
|
|
@@ -6163,7 +6183,8 @@ function buildOpenPkgSpec(context, resolveExternalTypes) {
|
|
|
6163
6183
|
ecosystem: "js/ts"
|
|
6164
6184
|
},
|
|
6165
6185
|
exports: [],
|
|
6166
|
-
types: []
|
|
6186
|
+
types: [],
|
|
6187
|
+
generation: generationInfo
|
|
6167
6188
|
};
|
|
6168
6189
|
const typeRegistry = new TypeRegistry;
|
|
6169
6190
|
const serializerContext = {
|
|
@@ -6480,7 +6501,7 @@ function hasExternalImports(sourceFile) {
|
|
|
6480
6501
|
});
|
|
6481
6502
|
return found;
|
|
6482
6503
|
}
|
|
6483
|
-
function runAnalysis(input) {
|
|
6504
|
+
function runAnalysis(input, generationInput) {
|
|
6484
6505
|
const context = createAnalysisContext(input);
|
|
6485
6506
|
const { baseDir, options, program } = context;
|
|
6486
6507
|
const packageJsonPath = findNearestPackageJson(baseDir);
|
|
@@ -6493,30 +6514,65 @@ function runAnalysis(input) {
|
|
|
6493
6514
|
`);
|
|
6494
6515
|
return !/allowJs/i.test(msg);
|
|
6495
6516
|
});
|
|
6496
|
-
const spec = buildOpenPkgSpec(context, resolveExternalTypes);
|
|
6497
6517
|
const specDiagnostics = [];
|
|
6518
|
+
const generationIssues = [];
|
|
6498
6519
|
if (!hasNodeModules && hasExternalImports(context.sourceFile)) {
|
|
6499
|
-
|
|
6520
|
+
const issue = {
|
|
6521
|
+
code: "NO_NODE_MODULES",
|
|
6500
6522
|
message: "External imports detected but node_modules not found.",
|
|
6501
6523
|
severity: "info",
|
|
6502
6524
|
suggestion: "Run npm install or bun install for complete type resolution."
|
|
6503
|
-
}
|
|
6504
|
-
|
|
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);
|
|
6505
6551
|
const danglingRefs = collectDanglingRefs(spec);
|
|
6506
6552
|
for (const ref of danglingRefs) {
|
|
6507
|
-
|
|
6553
|
+
const issue = {
|
|
6554
|
+
code: "DANGLING_REF",
|
|
6508
6555
|
message: `Type '${ref}' is referenced but not defined in types[].`,
|
|
6509
6556
|
severity: "warning",
|
|
6510
6557
|
suggestion: hasNodeModules ? "The type may be from an external package. Check import paths." : "Run npm/bun install to resolve external types."
|
|
6511
|
-
}
|
|
6558
|
+
};
|
|
6559
|
+
specDiagnostics.push(issue);
|
|
6560
|
+
if (generation) {
|
|
6561
|
+
generation.issues.push(issue);
|
|
6562
|
+
}
|
|
6512
6563
|
}
|
|
6513
6564
|
const externalTypes = collectExternalTypes(spec);
|
|
6514
6565
|
if (externalTypes.length > 0) {
|
|
6515
|
-
|
|
6566
|
+
const issue = {
|
|
6567
|
+
code: "EXTERNAL_TYPE_STUBS",
|
|
6516
6568
|
message: `${externalTypes.length} external type(s) could not be fully resolved: ${externalTypes.slice(0, 5).join(", ")}${externalTypes.length > 5 ? "..." : ""}`,
|
|
6517
6569
|
severity: "warning",
|
|
6518
6570
|
suggestion: hasNodeModules ? "Types are from external packages. Full resolution requires type declarations." : "Run npm/bun install to resolve external type definitions."
|
|
6519
|
-
}
|
|
6571
|
+
};
|
|
6572
|
+
specDiagnostics.push(issue);
|
|
6573
|
+
if (generation) {
|
|
6574
|
+
generation.issues.push(issue);
|
|
6575
|
+
}
|
|
6520
6576
|
}
|
|
6521
6577
|
const sourceFiles = program.getSourceFiles().filter((sf) => !sf.isDeclarationFile && sf.fileName.startsWith(baseDir)).map((sf) => sf.fileName);
|
|
6522
6578
|
return {
|
|
@@ -8176,7 +8232,7 @@ class DocCov {
|
|
|
8176
8232
|
packageDir,
|
|
8177
8233
|
content: code,
|
|
8178
8234
|
options: this.options
|
|
8179
|
-
});
|
|
8235
|
+
}, analyzeOptions.generationInput);
|
|
8180
8236
|
const filterOutcome = this.applySpecFilters(analysis.spec, analyzeOptions.filters);
|
|
8181
8237
|
return {
|
|
8182
8238
|
spec: filterOutcome.spec,
|
|
@@ -8211,7 +8267,7 @@ class DocCov {
|
|
|
8211
8267
|
packageDir,
|
|
8212
8268
|
content,
|
|
8213
8269
|
options: this.options
|
|
8214
|
-
});
|
|
8270
|
+
}, analyzeOptions.generationInput);
|
|
8215
8271
|
const filterOutcome = this.applySpecFilters(analysis.spec, analyzeOptions.filters);
|
|
8216
8272
|
const metadata = this.normalizeMetadata(analysis.metadata);
|
|
8217
8273
|
const result = {
|
|
@@ -8486,130 +8542,204 @@ function extractSpecSummary(spec) {
|
|
|
8486
8542
|
drift
|
|
8487
8543
|
};
|
|
8488
8544
|
}
|
|
8489
|
-
|
|
8490
|
-
|
|
8491
|
-
|
|
8492
|
-
|
|
8493
|
-
|
|
8494
|
-
|
|
8495
|
-
|
|
8496
|
-
|
|
8497
|
-
|
|
8498
|
-
|
|
8499
|
-
|
|
8500
|
-
}
|
|
8501
|
-
async detectPackage(packageName) {
|
|
8502
|
-
this.emit({ stage: "detecting", message: "Detecting project structure...", progress: 10 });
|
|
8503
|
-
const mono = await detectMonorepo(this.fs);
|
|
8504
|
-
if (mono.isMonorepo) {
|
|
8505
|
-
if (!packageName) {
|
|
8506
|
-
const publicPackages = mono.packages.filter((p) => !p.private);
|
|
8507
|
-
throw new MonorepoRequiresPackageError(publicPackages.map((p) => p.name));
|
|
8508
|
-
}
|
|
8509
|
-
const pkg = findPackageByName(mono.packages, packageName);
|
|
8510
|
-
if (!pkg) {
|
|
8511
|
-
throw new Error(`Package "${packageName}" not found. Available: ${mono.packages.map((p) => p.name).join(", ")}`);
|
|
8512
|
-
}
|
|
8513
|
-
this.emit({ stage: "detecting", message: `Found package: ${pkg.name}`, progress: 15 });
|
|
8514
|
-
return { targetPath: pkg.path, resolvedPackage: pkg.name };
|
|
8515
|
-
}
|
|
8516
|
-
return { targetPath: "." };
|
|
8517
|
-
}
|
|
8518
|
-
async detectEntry(targetPath) {
|
|
8519
|
-
this.emit({ stage: "detecting", message: "Detecting entry point...", progress: 18 });
|
|
8520
|
-
const entry = await detectEntryPoint(this.fs, targetPath);
|
|
8521
|
-
const entryFile = targetPath === "." ? entry.path : `${targetPath}/${entry.path}`;
|
|
8522
|
-
this.emit({
|
|
8523
|
-
stage: "detecting",
|
|
8524
|
-
message: `Entry point: ${entry.path} (from ${entry.source})`,
|
|
8525
|
-
progress: 20
|
|
8526
|
-
});
|
|
8527
|
-
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
|
+
}
|
|
8528
8556
|
}
|
|
8529
|
-
|
|
8530
|
-
|
|
8531
|
-
|
|
8532
|
-
|
|
8533
|
-
|
|
8534
|
-
|
|
8535
|
-
|
|
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();
|
|
8536
8565
|
}
|
|
8537
|
-
|
|
8538
|
-
|
|
8539
|
-
|
|
8540
|
-
|
|
8541
|
-
|
|
8542
|
-
|
|
8543
|
-
|
|
8544
|
-
|
|
8545
|
-
|
|
8546
|
-
|
|
8547
|
-
|
|
8548
|
-
});
|
|
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"
|
|
8549
8577
|
}
|
|
8550
|
-
|
|
8578
|
+
});
|
|
8579
|
+
if (!response.ok) {
|
|
8580
|
+
throw new Error(`Failed to fetch repository: ${response.status} ${response.statusText}`);
|
|
8551
8581
|
}
|
|
8552
|
-
|
|
8553
|
-
|
|
8554
|
-
|
|
8555
|
-
|
|
8556
|
-
|
|
8557
|
-
|
|
8558
|
-
|
|
8559
|
-
|
|
8560
|
-
|
|
8561
|
-
|
|
8562
|
-
|
|
8563
|
-
|
|
8564
|
-
|
|
8565
|
-
|
|
8566
|
-
|
|
8567
|
-
|
|
8568
|
-
|
|
8569
|
-
|
|
8570
|
-
|
|
8571
|
-
|
|
8572
|
-
|
|
8573
|
-
|
|
8574
|
-
|
|
8575
|
-
|
|
8576
|
-
|
|
8577
|
-
|
|
8578
|
-
|
|
8579
|
-
|
|
8580
|
-
|
|
8581
|
-
const
|
|
8582
|
-
const
|
|
8583
|
-
|
|
8584
|
-
await this.install(".");
|
|
8585
|
-
await this.build(".", targetPath);
|
|
8586
|
-
}
|
|
8587
|
-
const spec = await this.analyze(entryFile);
|
|
8588
|
-
this.emit({ stage: "complete", message: "Extracting results...", progress: 95 });
|
|
8589
|
-
const summary = extractSpecSummary(spec);
|
|
8590
|
-
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;
|
|
8591
8614
|
return {
|
|
8592
|
-
|
|
8593
|
-
|
|
8594
|
-
|
|
8595
|
-
packageName: resolvedPackage ?? options.package,
|
|
8596
|
-
coverage: summary.coverage,
|
|
8597
|
-
exportCount: summary.exportCount,
|
|
8598
|
-
typeCount: summary.typeCount,
|
|
8599
|
-
driftCount: summary.driftCount,
|
|
8600
|
-
undocumented: summary.undocumented,
|
|
8601
|
-
drift: summary.drift
|
|
8615
|
+
isMonorepo: true,
|
|
8616
|
+
tool: "pnpm",
|
|
8617
|
+
packages
|
|
8602
8618
|
};
|
|
8603
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 };
|
|
8604
8637
|
}
|
|
8605
|
-
|
|
8606
|
-
|
|
8607
|
-
|
|
8608
|
-
|
|
8609
|
-
|
|
8610
|
-
|
|
8611
|
-
|
|
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 {}
|
|
8612
8741
|
}
|
|
8742
|
+
return packages;
|
|
8613
8743
|
}
|
|
8614
8744
|
export {
|
|
8615
8745
|
validateSpecCache,
|
|
@@ -8626,6 +8756,7 @@ export {
|
|
|
8626
8756
|
runExample,
|
|
8627
8757
|
resolveTarget,
|
|
8628
8758
|
readPackageJson,
|
|
8759
|
+
parseGitHubUrl2 as parseScanGitHubUrl,
|
|
8629
8760
|
parseMarkdownFiles,
|
|
8630
8761
|
parseMarkdownFile,
|
|
8631
8762
|
parseListFlag,
|
|
@@ -8638,6 +8769,7 @@ export {
|
|
|
8638
8769
|
mergeConfig,
|
|
8639
8770
|
loadSpecCache,
|
|
8640
8771
|
loadCachedReport,
|
|
8772
|
+
listWorkspacePackages,
|
|
8641
8773
|
isFixableDrift,
|
|
8642
8774
|
isExecutableLang,
|
|
8643
8775
|
isCachedReportValid,
|
|
@@ -8676,6 +8808,7 @@ export {
|
|
|
8676
8808
|
findDeprecatedReferences,
|
|
8677
8809
|
fetchSpecFromGitHub,
|
|
8678
8810
|
fetchSpec,
|
|
8811
|
+
fetchGitHubContext,
|
|
8679
8812
|
extractSpecSummary,
|
|
8680
8813
|
extractPackageSpec,
|
|
8681
8814
|
extractImports,
|
|
@@ -8713,7 +8846,6 @@ export {
|
|
|
8713
8846
|
analyzeDocsImpact,
|
|
8714
8847
|
analyze,
|
|
8715
8848
|
VALIDATION_INFO,
|
|
8716
|
-
ScanOrchestrator,
|
|
8717
8849
|
SandboxFileSystem,
|
|
8718
8850
|
STYLE_RULES,
|
|
8719
8851
|
SPEC_CACHE_FILE,
|
|
@@ -8721,7 +8853,6 @@ export {
|
|
|
8721
8853
|
REPORT_EXTENSIONS,
|
|
8722
8854
|
OpenPkg,
|
|
8723
8855
|
NodeFileSystem,
|
|
8724
|
-
MonorepoRequiresPackageError,
|
|
8725
8856
|
DocCov,
|
|
8726
8857
|
DEFAULT_REPORT_PATH,
|
|
8727
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",
|