@@ -177,6 +177,69 @@ class TreeFormatter {
177
177
0
178
178
) ;
179
179
}
180
+
181
+ getMarkdownList ( hierarchy , parentPath = "" ) {
182
+ let result = "" ;
183
+ const currentPath = parentPath
184
+ ? `${ parentPath } -> ${ hierarchy . name } `
185
+ : hierarchy . name ;
186
+
187
+ // If this is a leaf node (no further usages), add a list item
188
+ if ( ! hierarchy . usedIn || hierarchy . usedIn . length === 0 ) {
189
+ result += `- ${ currentPath } \n` ;
190
+ }
191
+
192
+ // Recursively process children
193
+ if ( hierarchy . usedIn && hierarchy . usedIn . length > 0 ) {
194
+ hierarchy . usedIn . forEach ( ( child ) => {
195
+ result += this . getMarkdownList ( child , currentPath ) ;
196
+ } ) ;
197
+ }
198
+
199
+ return result ;
200
+ }
201
+
202
+ getStatistics ( hierarchy ) {
203
+ const stats = {
204
+ totalComponents : new Set ( ) ,
205
+ maxDepth : 0 ,
206
+ leafNodes : 0 ,
207
+ uniqueFiles : new Set ( ) ,
208
+ } ;
209
+
210
+ this . calculateStats ( hierarchy , 1 , stats ) ;
211
+
212
+ return {
213
+ totalComponents : stats . totalComponents . size ,
214
+ maxDepth : stats . maxDepth ,
215
+ leafNodes : stats . leafNodes ,
216
+ uniqueFiles : stats . uniqueFiles . size ,
217
+ } ;
218
+ }
219
+
220
+ calculateStats ( node , depth , stats ) {
221
+ stats . totalComponents . add ( node . name ) ;
222
+ stats . maxDepth = Math . max ( stats . maxDepth , depth ) ;
223
+ if ( node . definedIn ) {
224
+ stats . uniqueFiles . add ( node . definedIn ) ;
225
+ }
226
+
227
+ if ( ! node . usedIn || node . usedIn . length === 0 ) {
228
+ stats . leafNodes ++ ;
229
+ } else {
230
+ node . usedIn . forEach ( ( child ) => {
231
+ this . calculateStats ( child , depth + 1 , stats ) ;
232
+ } ) ;
233
+ }
234
+ }
235
+
236
+ formatSummary ( stats ) {
237
+ return `Summary:
238
+ • Total unique components: ${ stats . totalComponents }
239
+ • Maximum depth: ${ stats . maxDepth }
240
+ • Leaf usages: ${ stats . leafNodes }
241
+ • Files involved: ${ stats . uniqueFiles } \n` ;
242
+ }
180
243
}
181
244
182
245
const argv = yargs ( hideBin ( process . argv ) )
@@ -193,33 +256,74 @@ const argv = yargs(hideBin(process.argv))
193
256
demandOption : true ,
194
257
type : "string" ,
195
258
} )
259
+ . option ( "m" , {
260
+ alias : "markdown" ,
261
+ describe : "Output as markdown list" ,
262
+ type : "boolean" ,
263
+ default : false ,
264
+ } )
196
265
. help ( "h" )
197
266
. alias ( "h" , "help" ) . argv ;
198
267
199
268
async function main ( ) {
200
269
try {
201
270
const analyzer = new ComponentAnalyzer ( argv . directory ) ;
202
271
const hierarchy = await analyzer . analyze ( argv . component ) ;
203
-
204
- console . log ( "\nComponent Usage Tree:" ) ;
205
272
const formatter = new TreeFormatter ( ) ;
206
- const treeOutput = formatter . formatHierarchy ( hierarchy ) ;
207
- console . log ( treeOutput ) ;
208
273
209
- const totalUsages = formatter . getLeafUsages ( hierarchy ) ;
210
- console . log ( `\nTotal leaf usages found: ${ totalUsages } ` ) ;
274
+ // Calculate and display statistics
275
+ const stats = formatter . getStatistics ( hierarchy ) ;
276
+ console . log ( "\n" + formatter . formatSummary ( stats ) ) ;
277
+
278
+ // Prompt for viewing the list
279
+ const viewResponse = await prompts ( [
280
+ {
281
+ type : "confirm" ,
282
+ name : "viewList" ,
283
+ message : "Would you like to see the detailed usage list?" ,
284
+ initial : true ,
285
+ } ,
286
+ {
287
+ type : ( prev ) => ( prev ? "select" : null ) ,
288
+ name : "format" ,
289
+ message : "Select output format:" ,
290
+ choices : [
291
+ { title : "Tree view" , value : "tree" } ,
292
+ { title : "Markdown list" , value : "markdown" } ,
293
+ ] ,
294
+ initial : 0 ,
295
+ } ,
296
+ ] ) ;
297
+
298
+ let output = "" ;
299
+ if ( viewResponse . viewList ) {
300
+ if ( viewResponse . format === "markdown" ) {
301
+ output = formatter . getMarkdownList ( hierarchy ) ;
302
+ console . log ( "\nComponent Usage List:" ) ;
303
+ } else {
304
+ output = formatter . formatHierarchy ( hierarchy ) ;
305
+ console . log ( "\nComponent Usage Tree:" ) ;
306
+ }
307
+ console . log ( output ) ;
308
+ }
211
309
212
- const response = await prompts ( {
310
+ const clipboardResponse = await prompts ( {
213
311
type : "confirm" ,
214
312
name : "copyToClipboard" ,
215
313
message : "Copy output to clipboard?" ,
216
314
initial : false ,
217
315
} ) ;
218
316
219
- if ( response . copyToClipboard ) {
220
- const markdownOutput = `\`\`\`text\n${ treeOutput } \`\`\`` ;
317
+ if ( clipboardResponse . copyToClipboard ) {
318
+ const markdownOutput =
319
+ viewResponse . format === "markdown"
320
+ ? `${ formatter . formatSummary ( stats ) } \n${ output } `
321
+ : `\`\`\`text\n${ formatter . formatSummary ( stats ) } \n${ output } \`\`\`` ;
221
322
await clipboardy . write ( markdownOutput ) ;
222
- console . log ( "\n✓ Copied to clipboard in markdown format" ) ;
323
+ console . log (
324
+ "\n✓ Copied to clipboard" +
325
+ ( viewResponse . format === "markdown" ? "" : " in markdown format" )
326
+ ) ;
223
327
}
224
328
} catch ( error ) {
225
329
console . error ( "Error:" , error ) ;
0 commit comments