@@ -18,7 +18,7 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url));
1818const CLIS_DIR = path . resolve ( __dirname , 'clis' ) ;
1919const OUTPUT = path . resolve ( __dirname , '..' , 'dist' , 'cli-manifest.json' ) ;
2020
21- interface ManifestEntry {
21+ export interface ManifestEntry {
2222 site: string ;
2323 name: string ;
2424 description: string ;
@@ -28,14 +28,14 @@ interface ManifestEntry {
2828 args: Array < {
2929 name : string ;
3030 type ? : string ;
31- default ? : any ;
31+ default ? : unknown ;
3232 required ? : boolean ;
3333 positional ? : boolean ;
3434 help ? : string ;
3535 choices ?: string [ ] ;
3636 } > ;
3737 columns ?: string [ ] ;
38- pipeline ?: any [ ] ;
38+ pipeline ? : Record < string , unknown > [ ] ;
3939 timeout ?: number ;
4040 /** 'yaml' or 'ts' — determines how executeCommand loads the handler */
4141 type : 'yaml' | 'ts' ;
@@ -45,6 +45,38 @@ interface ManifestEntry {
4545 navigateBefore ?: boolean | string ;
4646}
4747
48+ interface YamlArgDefinition {
49+ type ?: string ;
50+ default ?: unknown ;
51+ required ?: boolean ;
52+ positional ?: boolean ;
53+ description ?: string ;
54+ help ?: string ;
55+ choices ?: string [ ] ;
56+ }
57+
58+ interface YamlCliDefinition {
59+ site ?: string ;
60+ name ?: string ;
61+ description ?: string ;
62+ domain ?: string ;
63+ strategy ?: string ;
64+ browser ?: boolean ;
65+ args ? : Record < string , YamlArgDefinition > ;
66+ columns ?: string [ ] ;
67+ pipeline ? : Record < string , unknown > [ ] ;
68+ timeout ?: number ;
69+ navigateBefore ?: boolean | string ;
70+ }
71+
72+ function isRecord ( value : unknown ) : value is Record < string , unknown > {
73+ return typeof value === 'object' && value !== null && ! Array . isArray ( value ) ;
74+ }
75+
76+ function getErrorMessage(error: unknown): string {
77+ return error instanceof Error ? error . message : String ( error ) ;
78+ }
79+
4880function extractBalancedBlock(
4981 source: string,
5082 startIndex: number,
@@ -129,7 +161,7 @@ export function parseTsArgsBlock(argsBlock: string): ManifestEntry['args'] {
129161 const helpMatch = body . match ( / h e l p \s * : \s * [ ' " ` ] ( [ ^ ' " ` ] * ) [ ' " ` ] / ) ;
130162 const positionalMatch = body . match ( / p o s i t i o n a l \s * : \s * ( t r u e | f a l s e ) / ) ;
131163
132- let defaultVal : any = undefined ;
164+ let defaultVal : unknown = undefined ;
133165 if ( defaultMatch ) {
134166 const raw = defaultMatch [ 1 ] . trim ( ) ;
135167 if ( raw === 'true' ) defaultVal = true ;
@@ -158,16 +190,17 @@ export function parseTsArgsBlock(argsBlock: string): ManifestEntry['args'] {
158190function scanYaml ( filePath : string , site : string ) : ManifestEntry | null {
159191 try {
160192 const raw = fs . readFileSync ( filePath , 'utf-8' ) ;
161- const def = yaml . load ( raw ) as any ;
162- if ( ! def || typeof def !== 'object' ) return null ;
193+ const def = yaml . load ( raw ) as YamlCliDefinition | null ;
194+ if ( ! isRecord ( def ) ) return null ;
195+ const cliDef = def as YamlCliDefinition ;
163196
164- const strategyStr = def . strategy ?? ( def . browser === false ? 'public' : 'cookie' ) ;
197+ const strategyStr = cliDef . strategy ?? ( cliDef . browser === false ? 'public' : 'cookie' ) ;
165198 const strategy = strategyStr . toUpperCase ( ) ;
166- const browser = def . browser ?? ( strategy !== 'PUBLIC' ) ;
199+ const browser = cliDef . browser ?? ( strategy !== 'PUBLIC' ) ;
167200
168201 const args : ManifestEntry [ 'args' ] = [ ] ;
169- if ( def . args && typeof def . args === 'object' ) {
170- for ( const [ argName , argDef ] of Object . entries ( def . args as Record < string , any > ) ) {
202+ if ( cliDef . args && typeof cliDef . args === 'object' ) {
203+ for ( const [ argName , argDef ] of Object . entries ( cliDef . args ) ) {
171204 args . push ( {
172205 name : argName ,
173206 type : argDef ?. type ?? 'str' ,
@@ -180,21 +213,21 @@ function scanYaml(filePath: string, site: string): ManifestEntry | null {
180213 }
181214
182215 return {
183- site : def . site ?? site ,
184- name : def . name ?? path . basename ( filePath , path . extname ( filePath ) ) ,
185- description : def . description ?? '' ,
186- domain : def . domain ,
216+ site : cliDef . site ?? site ,
217+ name : cliDef . name ?? path . basename ( filePath , path . extname ( filePath ) ) ,
218+ description : cliDef . description ?? '' ,
219+ domain : cliDef . domain ,
187220 strategy : strategy . toLowerCase ( ) ,
188221 browser ,
189222 args ,
190- columns : def . columns ,
191- pipeline : def . pipeline ,
192- timeout : def . timeout ,
223+ columns : cliDef . columns ,
224+ pipeline : cliDef . pipeline ,
225+ timeout : cliDef . timeout ,
193226 type : 'yaml' ,
194- navigateBefore : def . navigateBefore ,
227+ navigateBefore : cliDef . navigateBefore ,
195228 } ;
196- } catch ( err : any ) {
197- process . stderr . write ( `Warning: failed to parse ${ filePath } : ${ err . message } \n` ) ;
229+ } catch ( err ) {
230+ process . stderr . write ( `Warning: failed to parse ${ filePath } : ${ getErrorMessage ( err ) } \n` ) ;
198231 return null ;
199232 }
200233}
@@ -256,9 +289,9 @@ export function scanTs(filePath: string, site: string): ManifestEntry | null {
256289 if (navMatch) entry.navigateBefore = navMatch[1] === 'true' ? true : false;
257290
258291 return entry;
259- } catch ( err : any ) {
292+ } catch ( err ) {
260293 // If parsing fails, log a warning (matching scanYaml behaviour) and skip the entry.
261- process . stderr . write ( `Warning: failed to scan ${ filePath } : ${ err . message } \n` ) ;
294+ process . stderr . write ( `Warning: failed to scan ${ filePath } : ${ getErrorMessage ( err ) } \n` ) ;
262295 return null ;
263296 }
264297}
0 commit comments