@@ -199,21 +199,16 @@ function formatHierarchy(hierarchy, prefix = "", isLast = true) {
199
199
200
200
const connector = isLast ? treeChars . corner : treeChars . tee ;
201
201
const componentName = hierarchy . name ;
202
- const definedIn = hierarchy . definedIn
203
- ? ` (${ path . relative ( process . cwd ( ) , hierarchy . definedIn ) } )`
204
- : "" ;
205
-
206
- result += `${ prefix } ${ connector } ${ componentName } ${ definedIn } \n` ;
207
-
208
- if ( hierarchy . locations && hierarchy . locations . length > 0 ) {
209
- const locationPrefix = prefix + ( isLast ? treeChars . blank : treeChars . pipe ) ;
210
- hierarchy . locations . forEach ( ( loc ) => {
211
- result += `${ locationPrefix } ${ treeChars . pipe } Used at: ${ path . relative (
212
- process . cwd ( ) ,
213
- loc . file
214
- ) } :${ loc . line } \n`;
215
- } ) ;
216
- }
202
+
203
+ // Show the location where this component is used
204
+ const usageLocation =
205
+ hierarchy . locations && hierarchy . locations [ 0 ]
206
+ ? ` (${ path . relative ( process . cwd ( ) , hierarchy . locations [ 0 ] . file ) } :${
207
+ hierarchy . locations [ 0 ] . line
208
+ } )`
209
+ : "" ;
210
+
211
+ result += `${ prefix } ${ connector } ${ componentName } ${ usageLocation } \n` ;
217
212
218
213
const childPrefix = prefix + ( isLast ? treeChars . blank : treeChars . pipe ) ;
219
214
@@ -228,37 +223,42 @@ function formatHierarchy(hierarchy, prefix = "", isLast = true) {
228
223
}
229
224
230
225
/**
231
- * Formats a component hierarchy as a markdown list
226
+ * Formats a component hierarchy as a markdown list, showing only complete paths
232
227
* @param {Object } hierarchy - Component hierarchy object
233
228
* @param {string } parentPath - Current path in the component tree
229
+ * @param {Object|null } firstUsageLocation - Location where the first child component uses the target
234
230
* @returns {string } Formatted markdown list
235
231
*/
236
- function getMarkdownList ( hierarchy , parentPath = "" ) {
232
+ function getMarkdownList (
233
+ hierarchy ,
234
+ parentPath = "" ,
235
+ firstUsageLocation = null
236
+ ) {
237
237
let result = "" ;
238
238
const currentPath = parentPath
239
239
? `${ parentPath } -> ${ hierarchy . name } `
240
240
: hierarchy . name ;
241
241
242
- const definedIn = hierarchy . definedIn
243
- ? ` (defined in ${ path . relative ( process . cwd ( ) , hierarchy . definedIn ) } )`
244
- : "" ;
245
-
242
+ // Only output leaf nodes (components that aren't used by other components)
246
243
if ( ! hierarchy . usedIn || hierarchy . usedIn . length === 0 ) {
247
- result += `- ${ currentPath } ${ definedIn } \n` ;
248
- if ( hierarchy . locations ) {
249
- hierarchy . locations . forEach ( ( loc ) => {
250
- result += ` - Used at: ${ path . relative ( process . cwd ( ) , loc . file ) } :${
251
- loc . line
252
- } \n`;
253
- } ) ;
254
- }
244
+ const usageLocation = firstUsageLocation
245
+ ? ` (${ path . relative ( process . cwd ( ) , firstUsageLocation . file ) } :${
246
+ firstUsageLocation . line
247
+ } )`
248
+ : "" ;
249
+ result += `- ${ currentPath } ${ usageLocation } \n` ;
255
250
} else {
256
- result += `- ${ currentPath } ${ definedIn } \n` ;
257
- }
258
-
259
- if ( hierarchy . usedIn && hierarchy . usedIn . length > 0 ) {
251
+ // Continue traversing the tree
260
252
hierarchy . usedIn . forEach ( ( child ) => {
261
- result += getMarkdownList ( child , currentPath ) ;
253
+ // If this is the root component (Link), look for where it's used in its child
254
+ const nextLocation =
255
+ ! parentPath &&
256
+ hierarchy . locations ?. find ( ( loc ) => loc . file === child . definedIn ) ;
257
+ result += getMarkdownList (
258
+ child ,
259
+ currentPath ,
260
+ nextLocation || firstUsageLocation
261
+ ) ;
262
262
} ) ;
263
263
}
264
264
@@ -270,19 +270,26 @@ function getMarkdownList(hierarchy, parentPath = "") {
270
270
* @param {Object } node - Current node in the hierarchy
271
271
* @param {number } depth - Current depth in the tree
272
272
* @param {Object } stats - Statistics object to update
273
+ * @param {Array } currentPath - Array of components in current path
273
274
*/
274
- function calculateStats ( node , depth , stats ) {
275
- stats . totalComponents . add ( node . name ) ;
276
- stats . maxDepth = Math . max ( stats . maxDepth , depth ) ;
277
- if ( node . definedIn ) {
278
- stats . uniqueFiles . add ( node . definedIn ) ;
279
- }
275
+ function calculateStats ( node , depth , stats , currentPath = [ ] ) {
276
+ currentPath . push ( node . name ) ;
280
277
281
278
if ( ! node . usedIn || node . usedIn . length === 0 ) {
279
+ // Store the complete path as a string, excluding the target component itself
280
+ const pathString = currentPath . slice ( 1 ) . join ( " -> " ) ;
281
+ if ( pathString ) {
282
+ stats . uniquePaths . add ( pathString ) ;
283
+ }
284
+
285
+ stats . maxDepth = Math . max ( stats . maxDepth , depth ) ;
286
+ if ( node . definedIn ) {
287
+ stats . uniqueFiles . add ( node . definedIn ) ;
288
+ }
282
289
stats . leafNodes ++ ;
283
290
} else {
284
291
node . usedIn . forEach ( ( child ) => {
285
- calculateStats ( child , depth + 1 , stats ) ;
292
+ calculateStats ( child , depth + 1 , stats , [ ... currentPath ] ) ;
286
293
} ) ;
287
294
}
288
295
}
@@ -294,7 +301,7 @@ function calculateStats(node, depth, stats) {
294
301
*/
295
302
function getStatistics ( hierarchy ) {
296
303
const stats = {
297
- totalComponents : new Set ( ) ,
304
+ uniquePaths : new Set ( ) ,
298
305
maxDepth : 0 ,
299
306
leafNodes : 0 ,
300
307
uniqueFiles : new Set ( ) ,
@@ -303,7 +310,7 @@ function getStatistics(hierarchy) {
303
310
calculateStats ( hierarchy , 1 , stats ) ;
304
311
305
312
return {
306
- totalComponents : stats . totalComponents . size ,
313
+ uniquePaths : stats . uniquePaths . size ,
307
314
maxDepth : stats . maxDepth ,
308
315
leafNodes : stats . leafNodes ,
309
316
uniqueFiles : stats . uniqueFiles . size ,
@@ -317,9 +324,8 @@ function getStatistics(hierarchy) {
317
324
*/
318
325
function formatSummary ( stats ) {
319
326
return `Summary:
320
- • Total unique components : ${ stats . totalComponents }
327
+ • Unique usage paths : ${ stats . uniquePaths }
321
328
• Maximum depth: ${ stats . maxDepth }
322
- • Leaf usages: ${ stats . leafNodes }
323
329
• Files involved: ${ stats . uniqueFiles } \n` ;
324
330
}
325
331
0 commit comments