11import { execSync } from 'node:child_process' ;
22import { readFileSync } from 'node:fs' ;
33import * as path from 'node:path' ;
4- import { computeDrift } from '@driftdev/sdk' ;
4+ import type { OpenPkgSpec } from '@openpkg-ts/spec' ;
5+ import { computeDrift , isFixableDrift } from '@driftdev/sdk' ;
56import type { Command } from 'commander' ;
67import { cachedExtract } from '../cache/cached-extract' ;
78import { loadConfig } from '../config/loader' ;
89import { renderContext } from '../formatters/context' ;
910import {
1011 type ContextData ,
1112 type PackageContext ,
13+ type PackageIssue ,
14+ type UndocumentedExport ,
1215 renderContextMarkdown ,
1316 writeContext ,
1417} from '../utils/context-writer' ;
@@ -26,6 +29,59 @@ function getCommitSha(): string | null {
2629 }
2730}
2831
32+ function buildPackageContext ( name : string , spec : OpenPkgSpec ) : PackageContext {
33+ const exports = spec . exports ?? [ ] ;
34+ let documented = 0 ;
35+ const undocumented : string [ ] = [ ] ;
36+ const undocumentedExports : UndocumentedExport [ ] = [ ] ;
37+
38+ for ( const exp of exports ) {
39+ if ( exp . description ?. trim ( ) ) {
40+ documented ++ ;
41+ } else {
42+ undocumented . push ( exp . name ) ;
43+ undocumentedExports . push ( {
44+ name : exp . name ,
45+ kind : exp . kind ,
46+ filePath : exp . source ?. file ,
47+ line : exp . source ?. line ,
48+ } ) ;
49+ }
50+ }
51+
52+ const coverage = exports . length > 0 ? Math . round ( ( documented / exports . length ) * 100 ) : 100 ;
53+
54+ const driftResult = computeDrift ( spec ) ;
55+ const issues : PackageIssue [ ] = [ ] ;
56+ let lintIssues = 0 ;
57+
58+ for ( const [ exportName , drifts ] of driftResult . exports ) {
59+ lintIssues += drifts . length ;
60+ const exp = exports . find ( ( e ) => e . name === exportName ) ;
61+ for ( const drift of drifts ) {
62+ issues . push ( {
63+ export : exportName ,
64+ type : drift . type ,
65+ issue : drift . issue ,
66+ filePath : drift . filePath ?? exp ?. source ?. file ,
67+ line : drift . line ?? exp ?. source ?. line ,
68+ fixable : isFixableDrift ( drift ) ,
69+ } ) ;
70+ }
71+ }
72+
73+ return {
74+ name,
75+ coverage,
76+ lintIssues,
77+ exports : exports . length ,
78+ documented,
79+ undocumented,
80+ issues : issues . length > 0 ? issues : undefined ,
81+ undocumentedExports : undocumentedExports . length > 0 ? undocumentedExports : undefined ,
82+ } ;
83+ }
84+
2985export function registerContextCommand ( program : Command ) : void {
3086 program
3187 . command ( 'context [entry]' )
@@ -49,7 +105,6 @@ export function registerContextCommand(program: Command): void {
49105 const packages : PackageContext [ ] = [ ] ;
50106
51107 if ( options . all || ! entry ) {
52- // Multi-package: discover workspace packages
53108 const allPackages = discoverPackages ( cwd ) ;
54109 const pkgs =
55110 allPackages && allPackages . length > 0
@@ -62,26 +117,7 @@ export function registerContextCommand(program: Command): void {
62117 for ( const pkg of pkgs ) {
63118 try {
64119 const { spec } = await cachedExtract ( pkg . entry ) ;
65- const exports = spec . exports ?? [ ] ;
66- let documented = 0 ;
67- const undocumented : string [ ] = [ ] ;
68- for ( const exp of exports ) {
69- if ( exp . description ?. trim ( ) ) documented ++ ;
70- else undocumented . push ( exp . name ) ;
71- }
72- const coverage =
73- exports . length > 0 ? Math . round ( ( documented / exports . length ) * 100 ) : 100 ;
74- const driftResult = computeDrift ( spec ) ;
75- let lintIssues = 0 ;
76- for ( const [ , drifts ] of driftResult . exports ) lintIssues += drifts . length ;
77- packages . push ( {
78- name : pkg . name ,
79- coverage,
80- lintIssues,
81- exports : exports . length ,
82- documented,
83- undocumented,
84- } ) ;
120+ packages . push ( buildPackageContext ( pkg . name , spec ) ) ;
85121 } catch {
86122 packages . push ( {
87123 name : pkg . name ,
@@ -94,66 +130,24 @@ export function registerContextCommand(program: Command): void {
94130 }
95131 }
96132 } else {
97- // Single package fallback
98133 const entryFile = config . entry ? path . resolve ( cwd , config . entry ) : detectEntry ( ) ;
99134 const { spec } = await cachedExtract ( entryFile ) ;
100- const exports = spec . exports ?? [ ] ;
101- let documented = 0 ;
102- const undocumented : string [ ] = [ ] ;
103- for ( const exp of exports ) {
104- if ( exp . description ?. trim ( ) ) documented ++ ;
105- else undocumented . push ( exp . name ) ;
106- }
107- const coverage =
108- exports . length > 0 ? Math . round ( ( documented / exports . length ) * 100 ) : 100 ;
109- const driftResult = computeDrift ( spec ) ;
110- let lintIssues = 0 ;
111- for ( const [ , drifts ] of driftResult . exports ) lintIssues += drifts . length ;
112-
113135 const pkgJsonPath = path . resolve ( cwd , 'package.json' ) ;
114136 let name = path . basename ( cwd ) ;
115137 try {
116138 name = JSON . parse ( readFileSync ( pkgJsonPath , 'utf-8' ) ) . name ?? name ;
117139 } catch { }
118- packages . push ( {
119- name,
120- coverage,
121- lintIssues,
122- exports : exports . length ,
123- documented,
124- undocumented,
125- } ) ;
140+ packages . push ( buildPackageContext ( name , spec ) ) ;
126141 }
127142 } else {
128- // Single entry
129143 const entryFile = path . resolve ( cwd , entry ) ;
130144 const { spec } = await cachedExtract ( entryFile ) ;
131- const exports = spec . exports ?? [ ] ;
132- let documented = 0 ;
133- const undocumented : string [ ] = [ ] ;
134- for ( const exp of exports ) {
135- if ( exp . description ?. trim ( ) ) documented ++ ;
136- else undocumented . push ( exp . name ) ;
137- }
138- const coverage =
139- exports . length > 0 ? Math . round ( ( documented / exports . length ) * 100 ) : 100 ;
140- const driftResult = computeDrift ( spec ) ;
141- let lintIssues = 0 ;
142- for ( const [ , drifts ] of driftResult . exports ) lintIssues += drifts . length ;
143-
144145 const pkgJsonPath = path . resolve ( cwd , 'package.json' ) ;
145146 let name = path . basename ( cwd ) ;
146147 try {
147148 name = JSON . parse ( readFileSync ( pkgJsonPath , 'utf-8' ) ) . name ?? name ;
148149 } catch { }
149- packages . push ( {
150- name,
151- coverage,
152- lintIssues,
153- exports : exports . length ,
154- documented,
155- undocumented,
156- } ) ;
150+ packages . push ( buildPackageContext ( name , spec ) ) ;
157151 }
158152
159153 const contextData : ContextData = { packages, history, config, commit : commit ?? null } ;
0 commit comments