hermex 1.1.1-beta.1 → 1.1.2

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/cli.js CHANGED
@@ -1,26 +1,15 @@
1
1
  #!/usr/bin/env node
2
- 'use strict';
3
-
4
- var commander = require('commander');
5
- var ora = require('ora');
6
- var chalk6 = require('chalk');
7
- var core = require('@swc/core');
8
- var fs3 = require('fs');
9
- var Table = require('cli-table3');
10
- var glob = require('glob');
11
- var path = require('path');
12
- var yaml = require('js-yaml');
13
- var lockfile = require('@yarnpkg/lockfile');
14
-
15
- function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
16
-
17
- var ora__default = /*#__PURE__*/_interopDefault(ora);
18
- var chalk6__default = /*#__PURE__*/_interopDefault(chalk6);
19
- var fs3__default = /*#__PURE__*/_interopDefault(fs3);
20
- var Table__default = /*#__PURE__*/_interopDefault(Table);
21
- var path__default = /*#__PURE__*/_interopDefault(path);
22
- var yaml__default = /*#__PURE__*/_interopDefault(yaml);
23
- var lockfile__default = /*#__PURE__*/_interopDefault(lockfile);
2
+ import { Command } from 'commander';
3
+ import ora from 'ora';
4
+ import chalk5 from 'chalk';
5
+ import { minimatch } from 'minimatch';
6
+ import { parseSync } from '@swc/core';
7
+ import fs3 from 'fs';
8
+ import Table from 'cli-table3';
9
+ import { glob } from 'glob';
10
+ import path from 'path';
11
+ import yaml from 'js-yaml';
12
+ import lockfile from '@yarnpkg/lockfile';
24
13
 
25
14
  // src/swc-parser/core/state.ts
26
15
  function createState() {
@@ -57,7 +46,6 @@ function createState() {
57
46
  // src/swc-parser/patterns/imports.ts
58
47
  function analyzeImportDeclaration(node, state) {
59
48
  const source = node.source.value;
60
- console.log(`\u{1F4E6} Found import: ${source}`);
61
49
  for (const spec of node.specifiers) {
62
50
  switch (spec.type) {
63
51
  case "ImportDefaultSpecifier":
@@ -73,40 +61,37 @@ function analyzeImportDeclaration(node, state) {
73
61
  }
74
62
  }
75
63
  function analyzeDefaultImport(spec, source, node, state) {
76
- var _a;
77
64
  const name = spec.local.value;
78
65
  state.usagePatterns.defaultImports.add({
79
66
  name,
80
67
  source,
81
- line: ((_a = node.span) == null ? void 0 : _a.start) || 0
68
+ line: node.span?.start || 0
82
69
  });
83
70
  state.componentNames.add(name);
84
71
  }
85
72
  function analyzeNamespaceImport(spec, source, node, state) {
86
- var _a;
87
73
  const name = spec.local.value;
88
74
  state.usagePatterns.namespaceImports.add({
89
75
  name,
90
76
  source,
91
- line: ((_a = node.span) == null ? void 0 : _a.start) || 0
77
+ line: node.span?.start || 0
92
78
  });
93
79
  state.allIdentifiers.add(name);
94
80
  }
95
81
  function analyzeNamedImport(spec, source, node, state) {
96
- var _a, _b;
97
82
  const importedName = spec.imported ? spec.imported.value : spec.local.value;
98
83
  const localName = spec.local.value;
99
84
  state.usagePatterns.namedImports.add({
100
85
  name: importedName,
101
86
  source,
102
- line: ((_a = node.span) == null ? void 0 : _a.start) || 0
87
+ line: node.span?.start || 0
103
88
  });
104
89
  if (importedName !== localName) {
105
90
  state.usagePatterns.aliasedImports.set(localName, {
106
91
  imported: importedName,
107
92
  local: localName,
108
93
  source,
109
- line: ((_b = node.span) == null ? void 0 : _b.start) || 0
94
+ line: node.span?.start || 0
110
95
  });
111
96
  }
112
97
  state.componentNames.add(localName);
@@ -125,7 +110,7 @@ function getJSXElementName(nameNode) {
125
110
  }
126
111
  }
127
112
  function isMemberExpressionComponent(nameNode, state) {
128
- if ((nameNode == null ? void 0 : nameNode.type) === "JSXMemberExpression") {
113
+ if (nameNode?.type === "JSXMemberExpression") {
129
114
  const objectName = getJSXElementName(nameNode.object);
130
115
  return state.allIdentifiers.has(objectName);
131
116
  }
@@ -134,10 +119,9 @@ function isMemberExpressionComponent(nameNode, state) {
134
119
  function extractJSXProps(attributes) {
135
120
  if (!attributes) return [];
136
121
  return attributes.map((attr) => {
137
- var _a, _b, _c;
138
122
  if (attr.type === "JSXAttribute") {
139
123
  return {
140
- name: ((_a = attr.name) == null ? void 0 : _a.value) || ((_c = (_b = attr.name) == null ? void 0 : _b.name) == null ? void 0 : _c.value),
124
+ name: attr.name?.value || attr.name?.name?.value,
141
125
  value: extractJSXAttributeValue(attr.value)
142
126
  };
143
127
  }
@@ -202,7 +186,6 @@ function getUsageContext(parent) {
202
186
 
203
187
  // src/swc-parser/patterns/props.ts
204
188
  function analyzePropsInDetail(attributes, componentName, state) {
205
- var _a, _b, _c;
206
189
  const analysis = {
207
190
  namedProps: [],
208
191
  hasSpread: false,
@@ -213,7 +196,7 @@ function analyzePropsInDetail(attributes, componentName, state) {
213
196
  if (!attributes) return analysis;
214
197
  for (const attr of attributes) {
215
198
  if (attr.type === "JSXAttribute") {
216
- const propName = ((_a = attr.name) == null ? void 0 : _a.value) || ((_c = (_b = attr.name) == null ? void 0 : _b.name) == null ? void 0 : _c.value);
199
+ const propName = attr.name?.value || attr.name?.name?.value;
217
200
  if (propName) {
218
201
  analysis.namedProps.push(propName);
219
202
  const propDetail = {
@@ -295,7 +278,6 @@ function analyzeJSXElement(node, state) {
295
278
  }
296
279
  }
297
280
  function analyzeJSXOpeningElement(node, state, parent) {
298
- var _a;
299
281
  const elementName = getJSXElementName(node.name);
300
282
  if (!state.componentNames.has(elementName) && !isMemberExpressionComponent(node.name, state)) {
301
283
  return;
@@ -309,13 +291,12 @@ function analyzeJSXOpeningElement(node, state, parent) {
309
291
  component: elementName,
310
292
  props: extractJSXProps(node.attributes).map((p) => p.name),
311
293
  propsAnalysis,
312
- line: ((_a = node.span) == null ? void 0 : _a.start) || 0,
294
+ line: node.span?.start || 0,
313
295
  context: getUsageContext(parent)
314
296
  };
315
297
  if (!state.usagePatterns.jsxUsage.has(elementName)) {
316
298
  state.usagePatterns.jsxUsage.set(elementName, usage);
317
299
  }
318
- console.log(`\u{1F3A8} JSX Usage: <${elementName}>`);
319
300
  }
320
301
 
321
302
  // src/swc-parser/utils/matchers.ts
@@ -325,42 +306,38 @@ function isKnownComponent(name, state) {
325
306
 
326
307
  // src/swc-parser/patterns/variables.ts
327
308
  function analyzeVariableDeclaration(node, state) {
328
- var _a, _b, _c;
329
309
  if (!node.declarations) return;
330
310
  for (const decl of node.declarations) {
331
- if (((_a = decl.id) == null ? void 0 : _a.type) === "Identifier") {
311
+ if (decl.id?.type === "Identifier") {
332
312
  const varName = decl.id.value;
333
313
  if (decl.init) {
334
314
  const assignment = extractAssignmentInfo(decl.init);
335
315
  if (assignment && isKnownComponent(assignment, state)) {
336
316
  state.usagePatterns.variableAssignments.set(varName, {
337
317
  assignment,
338
- line: ((_b = node.span) == null ? void 0 : _b.start) || 0
318
+ line: node.span?.start || 0
339
319
  });
340
320
  state.componentNames.add(varName);
341
- console.log(`\u{1F4DD} Variable assignment: ${varName} = ${assignment}`);
342
321
  }
343
322
  }
344
323
  }
345
- if (((_c = decl.id) == null ? void 0 : _c.type) === "ObjectPattern") {
324
+ if (decl.id?.type === "ObjectPattern") {
346
325
  analyzeDestructuringPattern(decl.id, decl.init, state);
347
326
  }
348
327
  }
349
328
  }
350
329
  function analyzeDestructuringPattern(pattern, init, state) {
351
- var _a, _b;
352
330
  if (!pattern.properties) return;
353
331
  for (const prop of pattern.properties) {
354
- if (prop.type === "AssignmentPatternProperty" && ((_a = prop.key) == null ? void 0 : _a.type) === "Identifier") {
332
+ if (prop.type === "AssignmentPatternProperty" && prop.key?.type === "Identifier") {
355
333
  const propName = prop.key.value;
356
- if ((init == null ? void 0 : init.type) === "Identifier" && state.allIdentifiers.has(init.value)) {
334
+ if (init?.type === "Identifier" && state.allIdentifiers.has(init.value)) {
357
335
  state.usagePatterns.destructuredUsage.add({
358
336
  property: propName,
359
337
  source: init.value,
360
- line: ((_b = pattern.span) == null ? void 0 : _b.start) || 0
338
+ line: pattern.span?.start || 0
361
339
  });
362
340
  state.componentNames.add(propName);
363
- console.log(`\u{1F527} Destructuring: ${propName} from ${init.value}`);
364
341
  }
365
342
  }
366
343
  }
@@ -380,141 +357,115 @@ function extractAssignmentInfo(node) {
380
357
 
381
358
  // src/swc-parser/patterns/conditionals.ts
382
359
  function analyzeConditionalExpression(node, state) {
383
- var _a, _b, _c;
384
- const consequent = ((_a = node.consequent) == null ? void 0 : _a.type) === "Identifier" ? node.consequent.value : null;
385
- const alternate = ((_b = node.alternate) == null ? void 0 : _b.type) === "Identifier" ? node.alternate.value : null;
360
+ const consequent = node.consequent?.type === "Identifier" ? node.consequent.value : null;
361
+ const alternate = node.alternate?.type === "Identifier" ? node.alternate.value : null;
386
362
  if (consequent && state.componentNames.has(consequent) || alternate && state.componentNames.has(alternate)) {
387
363
  state.usagePatterns.conditionalUsage.add({
388
364
  consequent: consequent || "",
389
365
  alternate: alternate || "",
390
- line: ((_c = node.span) == null ? void 0 : _c.start) || 0
366
+ line: node.span?.start || 0
391
367
  });
392
- console.log("\u{1F500} Conditional component usage found");
393
368
  }
394
369
  }
395
370
 
396
371
  // src/swc-parser/patterns/collections.ts
397
372
  function analyzeArrayExpression(node, state) {
398
- var _a, _b, _c;
399
- const hasComponents = (_a = node.elements) == null ? void 0 : _a.some((elem) => {
400
- if ((elem == null ? void 0 : elem.type) === "Identifier") {
373
+ const hasComponents = node.elements?.some((elem) => {
374
+ if (elem?.type === "Identifier") {
401
375
  return state.componentNames.has(elem.value);
402
376
  }
403
377
  return false;
404
378
  });
405
379
  if (hasComponents) {
406
380
  state.usagePatterns.arrayMappings.add({
407
- components: (_b = node.elements) == null ? void 0 : _b.map((elem) => elem == null ? void 0 : elem.value).filter(Boolean),
408
- line: ((_c = node.span) == null ? void 0 : _c.start) || 0
381
+ components: node.elements?.map((elem) => elem?.value).filter(Boolean),
382
+ line: node.span?.start || 0
409
383
  });
410
- console.log("\u{1F4CB} Array with components found");
411
384
  }
412
385
  }
413
386
  function analyzeObjectExpression(node, state) {
414
- var _a, _b;
415
- const componentProps = (_a = node.properties) == null ? void 0 : _a.filter((prop) => {
416
- var _a2;
417
- if (prop.type === "KeyValueProperty" && ((_a2 = prop.value) == null ? void 0 : _a2.type) === "Identifier") {
387
+ const componentProps = node.properties?.filter((prop) => {
388
+ if (prop.type === "KeyValueProperty" && prop.value?.type === "Identifier") {
418
389
  return state.componentNames.has(prop.value.value);
419
390
  }
420
391
  return false;
421
392
  });
422
- if ((componentProps == null ? void 0 : componentProps.length) > 0) {
393
+ if (componentProps?.length > 0) {
423
394
  state.usagePatterns.objectMappings.add({
424
- mappings: componentProps.map((prop) => {
425
- var _a2, _b2;
426
- return {
427
- key: ((_a2 = prop.key) == null ? void 0 : _a2.value) || "[computed]",
428
- component: (_b2 = prop.value) == null ? void 0 : _b2.value
429
- };
430
- }),
431
- line: ((_b = node.span) == null ? void 0 : _b.start) || 0
395
+ mappings: componentProps.map((prop) => ({
396
+ key: prop.key?.value || "[computed]",
397
+ component: prop.value?.value
398
+ })),
399
+ line: node.span?.start || 0
432
400
  });
433
- console.log("\u{1F5FA}\uFE0F Object mapping with components found");
434
401
  }
435
402
  }
436
403
 
437
404
  // src/swc-parser/patterns/lazy-dynamic.ts
438
405
  function analyzeLazyImport(node, state) {
439
- var _a, _b, _c, _d, _e, _f;
440
- const arg = (_a = node.arguments) == null ? void 0 : _a[0];
441
- if ((arg == null ? void 0 : arg.type) === "ArrowFunctionExpression" && ((_b = arg.body) == null ? void 0 : _b.type) === "CallExpression") {
406
+ const arg = node.arguments?.[0];
407
+ if (arg?.type === "ArrowFunctionExpression" && arg.body?.type === "CallExpression") {
442
408
  const importCall = arg.body;
443
- if (((_c = importCall.callee) == null ? void 0 : _c.type) === "Import") {
444
- const source = (_e = (_d = importCall.arguments) == null ? void 0 : _d[0]) == null ? void 0 : _e.value;
409
+ if (importCall.callee?.type === "Import") {
410
+ const source = importCall.arguments?.[0]?.value;
445
411
  if (source) {
446
412
  state.usagePatterns.lazyImports.add({
447
413
  source,
448
- line: ((_f = node.span) == null ? void 0 : _f.start) || 0
414
+ line: node.span?.start || 0
449
415
  });
450
- console.log(`\u{1F504} Found lazy import: ${source}`);
451
416
  }
452
417
  }
453
418
  }
454
419
  }
455
420
  function analyzeDynamicImport(node, state) {
456
- var _a, _b, _c;
457
- const source = (_b = (_a = node.arguments) == null ? void 0 : _a[0]) == null ? void 0 : _b.value;
421
+ const source = node.arguments?.[0]?.value;
458
422
  if (source) {
459
423
  state.usagePatterns.dynamicImports.add({
460
424
  source,
461
- line: ((_c = node.span) == null ? void 0 : _c.start) || 0
425
+ line: node.span?.start || 0
462
426
  });
463
- console.log(`\u26A1 Found dynamic import: ${source}`);
464
427
  }
465
428
  }
466
429
 
467
430
  // src/swc-parser/patterns/advanced.ts
468
431
  function analyzeHOCUsage(node, state) {
469
- var _a, _b, _c, _d;
470
432
  state.usagePatterns.hocUsage.add({
471
- function: ((_a = node.callee) == null ? void 0 : _a.value) || "[unknown]",
472
- component: ((_c = (_b = node.arguments) == null ? void 0 : _b[0]) == null ? void 0 : _c.value) || "[unknown]",
473
- line: ((_d = node.span) == null ? void 0 : _d.start) || 0
433
+ function: node.callee?.value || "[unknown]",
434
+ component: node.arguments?.[0]?.value || "[unknown]",
435
+ line: node.span?.start || 0
474
436
  });
475
- console.log(`\u{1F381} HOC usage found`);
476
437
  }
477
438
  function analyzeMemoUsage(node, state) {
478
- var _a, _b;
479
- const component = (_a = node.arguments) == null ? void 0 : _a[0];
480
- if ((component == null ? void 0 : component.type) === "Identifier" && state.componentNames.has(component.value)) {
439
+ const component = node.arguments?.[0];
440
+ if (component?.type === "Identifier" && state.componentNames.has(component.value)) {
481
441
  state.usagePatterns.memoizedComponents.add({
482
442
  component: component.value,
483
- line: ((_b = node.span) == null ? void 0 : _b.start) || 0
443
+ line: node.span?.start || 0
484
444
  });
485
- console.log(`\u{1F9E0} Memoized component: ${component.value}`);
486
445
  }
487
446
  }
488
447
  function analyzeForwardRefUsage(node, state) {
489
- var _a;
490
448
  state.usagePatterns.forwardedRefs.add({
491
- line: ((_a = node.span) == null ? void 0 : _a.start) || 0
449
+ line: node.span?.start || 0
492
450
  });
493
- console.log("\u2197\uFE0F ForwardRef usage found");
494
451
  }
495
452
  function analyzePortalUsage(node, state) {
496
- var _a;
497
453
  state.usagePatterns.portalUsage.add({
498
- line: ((_a = node.span) == null ? void 0 : _a.start) || 0
454
+ line: node.span?.start || 0
499
455
  });
500
- console.log("\u{1F300} Portal usage found");
501
456
  }
502
457
  function analyzeMemberExpression(node, state) {
503
- var _a, _b;
504
- if (((_a = node.object) == null ? void 0 : _a.type) === "Identifier" && state.allIdentifiers.has(node.object.value)) {
505
- const namespaceName = node.object.value;
506
- const propertyName = (_b = node.property) == null ? void 0 : _b.value;
458
+ if (node.object?.type === "Identifier" && state.allIdentifiers.has(node.object.value)) {
459
+ const propertyName = node.property?.value;
507
460
  if (propertyName) {
508
461
  state.componentNames.add(propertyName);
509
- console.log(`\u{1F517} Namespace access: ${namespaceName}.${propertyName}`);
510
462
  }
511
463
  }
512
464
  }
513
465
  function isHOCPattern(node, state) {
514
- var _a, _b;
515
- return ((_a = node.callee) == null ? void 0 : _a.type) === "Identifier" && ((_b = node.arguments) == null ? void 0 : _b.some(
466
+ return node.callee?.type === "Identifier" && node.arguments?.some(
516
467
  (arg) => arg.type === "Identifier" && state.componentNames.has(arg.value)
517
- ));
468
+ );
518
469
  }
519
470
 
520
471
  // src/swc-parser/core/visitor.ts
@@ -584,24 +535,23 @@ function visitNode(node, state, context = {}) {
584
535
  }
585
536
  }
586
537
  function analyzeCallExpression(node, state, context) {
587
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o;
588
- if (((_a = node.callee) == null ? void 0 : _a.value) === "lazy" || ((_c = (_b = node.callee) == null ? void 0 : _b.object) == null ? void 0 : _c.value) === "React" && ((_e = (_d = node.callee) == null ? void 0 : _d.property) == null ? void 0 : _e.value) === "lazy") {
538
+ if (node.callee?.value === "lazy" || node.callee?.object?.value === "React" && node.callee?.property?.value === "lazy") {
589
539
  analyzeLazyImport(node, state);
590
540
  }
591
- if (((_f = node.callee) == null ? void 0 : _f.type) === "Import") {
541
+ if (node.callee?.type === "Import") {
592
542
  analyzeDynamicImport(node, state);
593
543
  }
594
544
  if (isHOCPattern(node, state)) {
595
545
  analyzeHOCUsage(node, state);
596
546
  }
597
- if (((_h = (_g = node.callee) == null ? void 0 : _g.object) == null ? void 0 : _h.value) === "React") {
598
- if (((_j = (_i = node.callee) == null ? void 0 : _i.property) == null ? void 0 : _j.value) === "memo") {
547
+ if (node.callee?.object?.value === "React") {
548
+ if (node.callee?.property?.value === "memo") {
599
549
  analyzeMemoUsage(node, state);
600
- } else if (((_l = (_k = node.callee) == null ? void 0 : _k.property) == null ? void 0 : _l.value) === "forwardRef") {
550
+ } else if (node.callee?.property?.value === "forwardRef") {
601
551
  analyzeForwardRefUsage(node, state);
602
552
  }
603
553
  }
604
- if (((_n = (_m = node.callee) == null ? void 0 : _m.property) == null ? void 0 : _n.value) === "createPortal" || ((_o = node.callee) == null ? void 0 : _o.value) === "createPortal") {
554
+ if (node.callee?.property?.value === "createPortal" || node.callee?.value === "createPortal") {
605
555
  analyzePortalUsage(node, state);
606
556
  }
607
557
  visitChildren(node, state, context);
@@ -686,7 +636,7 @@ function calculateTotalPatterns(state) {
686
636
  // src/swc-parser/index.ts
687
637
  function parseCode(code, options = {}) {
688
638
  const state = createState();
689
- const ast = core.parseSync(code, {
639
+ const ast = parseSync(code, {
690
640
  syntax: "typescript",
691
641
  tsx: true,
692
642
  decorators: true,
@@ -700,15 +650,8 @@ function parseCode(code, options = {}) {
700
650
  return report;
701
651
  }
702
652
  function parseFile(filePath, options = {}) {
703
- console.log(`
704
- \u{1F4C1} Analyzing: ${filePath}`);
705
- try {
706
- const code = fs3__default.default.readFileSync(filePath, "utf8");
707
- return parseCode(code, options);
708
- } catch (error) {
709
- console.error(`\u274C Error parsing ${filePath}:`, error.message);
710
- return null;
711
- }
653
+ const code = fs3.readFileSync(filePath, "utf8");
654
+ return parseCode(code, options);
712
655
  }
713
656
  function filterReportByLibrary(report, libraryName) {
714
657
  const isFromLibrary = (source) => source.startsWith(libraryName) || source.includes(libraryName);
@@ -806,6 +749,7 @@ function aggregateReports(reports, versions = {}) {
806
749
  }
807
750
  function resolvePackageFromImportPath(importPath, availablePackages) {
808
751
  if (importPath.startsWith(".") || importPath.startsWith("/")) {
752
+ console.log("importPath", importPath);
809
753
  return "local";
810
754
  }
811
755
  const sortedPackages = [...availablePackages].sort(
@@ -980,22 +924,16 @@ function formatCount(num) {
980
924
  return num.toLocaleString();
981
925
  }
982
926
  function formatDuration(seconds) {
983
- return `${seconds.toFixed(1)}s`;
927
+ return `${seconds.toFixed(2)}s`;
984
928
  }
985
929
 
986
930
  // src/utils/print-summary.ts
987
931
  function printHeader() {
988
- console.log(chalk6__default.default.green.bold("\n\u{1F4CA} Summary\n"));
932
+ console.log(chalk5.green.bold("\n\u{1F4CA} Summary\n"));
989
933
  }
990
- function printSummary(aggregated, elapsedTimeSeconds) {
991
- console.log(
992
- chalk6__default.default.green(
993
- `Analysis completed successfully in ${formatDuration(elapsedTimeSeconds)}
994
- `
995
- )
996
- );
934
+ function printSummary(aggregated) {
997
935
  printHeader();
998
- const table = new Table__default.default({
936
+ const table = new Table({
999
937
  head: ["Metric", "Count"],
1000
938
  style: {
1001
939
  head: ["cyan"],
@@ -1017,26 +955,6 @@ function printSummary(aggregated, elapsedTimeSeconds) {
1017
955
  );
1018
956
  console.log(table.toString());
1019
957
  }
1020
- function printHeader2() {
1021
- console.log(chalk6__default.default.cyan.bold("\n\u{1F4CB} Details\n"));
1022
- }
1023
- function printDetails(aggregated) {
1024
- printHeader2();
1025
- console.log(
1026
- chalk6__default.default.cyan(
1027
- ` Total usage patterns: ${aggregated.totalUsagePatterns.toLocaleString()}`
1028
- )
1029
- );
1030
- for (const pattern of aggregated.patternCounts) {
1031
- if (pattern.count > 0) {
1032
- console.log(
1033
- chalk6__default.default.cyan(
1034
- ` ${pattern.displayName}: ${pattern.count.toLocaleString()}`
1035
- )
1036
- );
1037
- }
1038
- }
1039
- }
1040
958
  function renderBarChart(data, options = {}) {
1041
959
  const {
1042
960
  maxWidth = 50,
@@ -1045,12 +963,12 @@ function renderBarChart(data, options = {}) {
1045
963
  emptyChar = "\u2591"
1046
964
  } = options;
1047
965
  if (data.length === 0) {
1048
- console.log(chalk6__default.default.gray(" No data to display"));
966
+ console.log(chalk5.gray(" No data to display"));
1049
967
  return;
1050
968
  }
1051
969
  const maxValue = Math.max(...data.map((d) => d.value));
1052
970
  if (maxValue === 0) {
1053
- console.log(chalk6__default.default.gray(" All values are zero"));
971
+ console.log(chalk5.gray(" All values are zero"));
1054
972
  return;
1055
973
  }
1056
974
  const maxLabelLength = Math.max(...data.map((d) => d.label.length));
@@ -1059,16 +977,16 @@ function renderBarChart(data, options = {}) {
1059
977
  const barLength = Math.round(percentage * maxWidth);
1060
978
  const emptyLength = maxWidth - barLength;
1061
979
  const paddedLabel = item.label.padEnd(maxLabelLength, " ");
1062
- const bar = chalk6__default.default.green(barChar.repeat(barLength)) + chalk6__default.default.gray(emptyChar.repeat(emptyLength));
1063
- const valueStr = showValues ? ` ${item.value.toLocaleString()}` : "";
980
+ const bar = chalk5.green(barChar.repeat(barLength)) + chalk5.gray(emptyChar.repeat(emptyLength));
981
+ const valueStr = showValues ? ` ${formatCount(item.value)}` : "";
1064
982
  console.log(`${paddedLabel} ${bar}${valueStr}
1065
983
  `);
1066
984
  }
1067
985
  }
1068
986
 
1069
987
  // src/utils/print-components.ts
1070
- function printHeader3() {
1071
- console.log(chalk6__default.default.magenta.bold("\n\u269B\uFE0F Components\n"));
988
+ function printHeader2() {
989
+ console.log(chalk5.magenta.bold("\n\u269B\uFE0F Components\n"));
1072
990
  }
1073
991
  function printComponents(aggregated, mode) {
1074
992
  const components = aggregated.topComponents;
@@ -1079,15 +997,15 @@ function printComponents(aggregated, mode) {
1079
997
  }
1080
998
  }
1081
999
  function printComponentsTable(components) {
1082
- printHeader3();
1000
+ printHeader2();
1083
1001
  const externalComponents = components.filter(
1084
1002
  (comp) => comp.source !== "unknown" && comp.source !== "local"
1085
1003
  );
1086
1004
  if (externalComponents.length === 0) {
1087
- console.log(chalk6__default.default.gray(" No external components found"));
1005
+ console.log(chalk5.gray(" No external components found"));
1088
1006
  return;
1089
1007
  }
1090
- const table = new Table__default.default({
1008
+ const table = new Table({
1091
1009
  head: ["Component", "Package", "Count"],
1092
1010
  style: {
1093
1011
  head: ["cyan"],
@@ -1100,12 +1018,12 @@ function printComponentsTable(components) {
1100
1018
  console.log(table.toString());
1101
1019
  }
1102
1020
  function printComponentsChart(components) {
1103
- printHeader3();
1021
+ printHeader2();
1104
1022
  const externalComponents = components.filter(
1105
1023
  (comp) => comp.source !== "unknown" && comp.source !== "local"
1106
1024
  );
1107
1025
  if (externalComponents.length === 0) {
1108
- console.log(chalk6__default.default.gray(" No external components found"));
1026
+ console.log(chalk5.gray(" No external components found"));
1109
1027
  return;
1110
1028
  }
1111
1029
  const data = externalComponents.map((comp) => ({
@@ -1114,8 +1032,8 @@ function printComponentsChart(components) {
1114
1032
  }));
1115
1033
  renderBarChart(data, { maxWidth: 50 });
1116
1034
  }
1117
- function printHeader4() {
1118
- console.log(chalk6__default.default.blue.bold("\n\u{1F50D} Code Patterns\n"));
1035
+ function printHeader3() {
1036
+ console.log(chalk5.blue.bold("\n\u{1F50D} Code Patterns\n"));
1119
1037
  }
1120
1038
  function printPatterns(aggregated, mode) {
1121
1039
  const patterns = aggregated.patternCounts.filter((p) => p.count > 0);
@@ -1126,12 +1044,12 @@ function printPatterns(aggregated, mode) {
1126
1044
  }
1127
1045
  }
1128
1046
  function printPatternsTable(patterns) {
1129
- printHeader4();
1047
+ printHeader3();
1130
1048
  if (patterns.length === 0) {
1131
- console.log(chalk6__default.default.gray(" No patterns found"));
1049
+ console.log(chalk5.gray(" No patterns found"));
1132
1050
  return;
1133
1051
  }
1134
- const table = new Table__default.default({
1052
+ const table = new Table({
1135
1053
  head: ["Pattern", "Count"],
1136
1054
  style: {
1137
1055
  head: ["cyan"],
@@ -1143,13 +1061,13 @@ function printPatternsTable(patterns) {
1143
1061
  });
1144
1062
  console.log(table.toString());
1145
1063
  const totalPatterns = patterns.reduce((sum, p) => sum + p.count, 0);
1146
- console.log(chalk6__default.default.gray(`
1064
+ console.log(chalk5.gray(`
1147
1065
  Total: ${totalPatterns} patterns detected`));
1148
1066
  }
1149
1067
  function printPatternsChart(patterns) {
1150
- printHeader4();
1068
+ printHeader3();
1151
1069
  if (patterns.length === 0) {
1152
- console.log(chalk6__default.default.gray(" No patterns found"));
1070
+ console.log(chalk5.gray(" No patterns found"));
1153
1071
  return;
1154
1072
  }
1155
1073
  const data = patterns.map((pattern) => ({
@@ -1158,8 +1076,8 @@ function printPatternsChart(patterns) {
1158
1076
  }));
1159
1077
  renderBarChart(data, { maxWidth: 50 });
1160
1078
  }
1161
- function printHeader5() {
1162
- console.log(chalk6__default.default.blueBright.bold("\n\u{1F4E6} Packages\n"));
1079
+ function printHeader4() {
1080
+ console.log(chalk5.blueBright.bold("\n\u{1F4E6} Packages\n"));
1163
1081
  }
1164
1082
  function printPackages(aggregated, mode) {
1165
1083
  const packages = aggregated.packageDistribution;
@@ -1170,12 +1088,12 @@ function printPackages(aggregated, mode) {
1170
1088
  }
1171
1089
  }
1172
1090
  function printPackagesTable(packages) {
1173
- printHeader5();
1091
+ printHeader4();
1174
1092
  if (packages.length === 0) {
1175
- console.log(chalk6__default.default.gray(" No packages found"));
1093
+ console.log(chalk5.gray(" No packages found"));
1176
1094
  return;
1177
1095
  }
1178
- const table = new Table__default.default({
1096
+ const table = new Table({
1179
1097
  head: ["Package", "Version", "Components", "Usage", "Percentage"],
1180
1098
  style: {
1181
1099
  head: ["cyan"],
@@ -1198,16 +1116,16 @@ function printPackagesTable(packages) {
1198
1116
  );
1199
1117
  const totalExternalUsage = packages.reduce((sum, p) => sum + p.usageCount, 0);
1200
1118
  console.log(
1201
- chalk6__default.default.gray(
1119
+ chalk5.gray(
1202
1120
  `
1203
1121
  Total: ${formatCount(packages.length)} packages | ${formatCount(totalComponents)} unique components | ${formatCount(totalExternalUsage)} total usages`
1204
1122
  )
1205
1123
  );
1206
1124
  }
1207
1125
  function printPackagesChart(packages) {
1208
- printHeader5();
1126
+ printHeader4();
1209
1127
  if (packages.length === 0) {
1210
- console.log(chalk6__default.default.gray(" No packages found"));
1128
+ console.log(chalk5.gray(" No packages found"));
1211
1129
  return;
1212
1130
  }
1213
1131
  const maxBarWidth = 40;
@@ -1219,14 +1137,14 @@ function printPackagesChart(packages) {
1219
1137
  );
1220
1138
  const emptyLength = maxBarWidth - barLength;
1221
1139
  const paddedLabel = pkg.packageName.padEnd(maxLabelLength, " ");
1222
- const bar = chalk6__default.default.green("\u2588".repeat(barLength)) + chalk6__default.default.gray("\u2591".repeat(emptyLength));
1140
+ const bar = chalk5.green("\u2588".repeat(barLength)) + chalk5.gray("\u2591".repeat(emptyLength));
1223
1141
  console.log(
1224
- `${paddedLabel} ${bar} ${chalk6__default.default.bold(pkg.percentage.toFixed(1) + "%")} (${pkg.usageCount})`
1142
+ `${paddedLabel} ${bar} ${chalk5.bold(pkg.percentage.toFixed(1) + "%")} (${pkg.usageCount})`
1225
1143
  );
1226
1144
  });
1227
1145
  }
1228
1146
  async function findFiles(pattern, ignorePatterns) {
1229
- const files = await glob.glob(pattern, {
1147
+ const files = await glob(pattern, {
1230
1148
  ignore: ignorePatterns,
1231
1149
  nodir: true,
1232
1150
  absolute: true,
@@ -1240,12 +1158,12 @@ var NpmLockfileAdapter = class {
1240
1158
  this.supportedVersions = ["v2", "v3"];
1241
1159
  }
1242
1160
  detect(projectPath) {
1243
- const lockfilePath = path__default.default.join(projectPath, "package-lock.json");
1244
- return fs3__default.default.existsSync(lockfilePath) ? lockfilePath : null;
1161
+ const lockfilePath = path.join(projectPath, "package-lock.json");
1162
+ return fs3.existsSync(lockfilePath) ? lockfilePath : null;
1245
1163
  }
1246
1164
  parse(lockFilePath) {
1247
1165
  try {
1248
- const content = fs3__default.default.readFileSync(lockFilePath, "utf8");
1166
+ const content = fs3.readFileSync(lockFilePath, "utf8");
1249
1167
  const lockData = JSON.parse(content);
1250
1168
  const versions = {};
1251
1169
  if (lockData.packages) {
@@ -1287,13 +1205,13 @@ var PnpmLockfileAdapter = class {
1287
1205
  this.supportedVersions = ["v5", "v6", "v9"];
1288
1206
  }
1289
1207
  detect(projectPath) {
1290
- const lockfilePath = path__default.default.join(projectPath, "pnpm-lock.yaml");
1291
- return fs3__default.default.existsSync(lockfilePath) ? lockfilePath : null;
1208
+ const lockfilePath = path.join(projectPath, "pnpm-lock.yaml");
1209
+ return fs3.existsSync(lockfilePath) ? lockfilePath : null;
1292
1210
  }
1293
1211
  parse(lockFilePath) {
1294
1212
  try {
1295
- const content = fs3__default.default.readFileSync(lockFilePath, "utf8");
1296
- const lockData = yaml__default.default.load(content);
1213
+ const content = fs3.readFileSync(lockFilePath, "utf8");
1214
+ const lockData = yaml.load(content);
1297
1215
  const versions = {};
1298
1216
  if (lockData.importers) {
1299
1217
  const rootImporter = lockData.importers["."];
@@ -1352,13 +1270,13 @@ var YarnLockfileAdapter = class {
1352
1270
  this.supportedVersions = ["v1", "v2+"];
1353
1271
  }
1354
1272
  detect(projectPath) {
1355
- const lockfilePath = path__default.default.join(projectPath, "yarn.lock");
1356
- return fs3__default.default.existsSync(lockfilePath) ? lockfilePath : null;
1273
+ const lockfilePath = path.join(projectPath, "yarn.lock");
1274
+ return fs3.existsSync(lockfilePath) ? lockfilePath : null;
1357
1275
  }
1358
1276
  parse(lockFilePath) {
1359
1277
  try {
1360
- const content = fs3__default.default.readFileSync(lockFilePath, "utf8");
1361
- const parsed = lockfile__default.default.parse(content);
1278
+ const content = fs3.readFileSync(lockFilePath, "utf8");
1279
+ const parsed = lockfile.parse(content);
1362
1280
  if (parsed.type !== "success") {
1363
1281
  console.warn("Warning: Failed to parse yarn.lock");
1364
1282
  return {};
@@ -1422,16 +1340,13 @@ function registerScanCommand(program2) {
1422
1340
  "**/node_modules/**",
1423
1341
  "**/dist/**",
1424
1342
  "**/build/**"
1343
+ ]).option("--allow-packages <pattern>", "Pattern for what packages to scan", [
1344
+ "**"
1425
1345
  ]).option(
1426
- "--allow-packages <pattern>",
1427
- "Glob pattern for what packages to scan",
1428
- "ALL"
1429
- // TO FIX
1430
- ).option(
1431
1346
  "--ignore-packages <pattern>",
1432
- "Glob pattern for what packages to ignore",
1347
+ "Pattern for what packages to ignore",
1433
1348
  []
1434
- ).option("--summary [mode]", "Show summary stats (log, false)", "log").option("--no-summary", "Do not show summary stats").option("--details", "Show detailed pattern counts").option(
1349
+ ).option("--no-summary", "Hide summary", "table").option(
1435
1350
  "--components [mode]",
1436
1351
  "Show components table/chart (table, chart)",
1437
1352
  "table"
@@ -1448,40 +1363,50 @@ function registerScanCommand(program2) {
1448
1363
  await executeScan(pattern, normalizedOptions);
1449
1364
  });
1450
1365
  }
1451
- function normalizeIgnorePatterns(ignore) {
1452
- if (!ignore) {
1366
+ function normalizeArray(value) {
1367
+ if (!value) {
1453
1368
  return [];
1454
1369
  }
1455
- return Array.isArray(ignore) ? ignore : [ignore];
1370
+ return Array.isArray(value) ? value : [value];
1456
1371
  }
1457
1372
  function normalizeOptions(options) {
1458
1373
  return {
1459
1374
  verbose: options.verbose || false,
1460
1375
  summary: options.summary === false || options.summary === "false" ? false : "log",
1461
- details: options.details || false,
1376
+ noSummary: options.noSummary || false,
1462
1377
  components: options.components || "table",
1463
1378
  packages: options.packages || "table",
1464
1379
  patterns: options.patterns || "table",
1465
- ignore: normalizeIgnorePatterns(options.ignore)
1380
+ ignore: normalizeArray(options.ignore),
1381
+ allowPackages: normalizeArray(options.allowPackages),
1382
+ ignorePackages: normalizeArray(options.ignorePackages)
1466
1383
  };
1467
1384
  }
1468
1385
  async function executeScan(pattern, options) {
1469
1386
  const startTime = Date.now();
1470
- const spinner = ora__default.default("Parsing lockfile...").start();
1387
+ const spinner = ora("Parsing lockfile...").start();
1471
1388
  try {
1472
1389
  const lockfileResult = findAndParseLockfile(process.cwd());
1390
+ const allPackages = Object.keys(lockfileResult.versions);
1391
+ const filteredPackages = allPackages.filter((pkg) => {
1392
+ const allowed = options.allowPackages.some((p) => minimatch(pkg, p));
1393
+ const ignored = options.ignorePackages.some((p) => minimatch(pkg, p));
1394
+ return allowed && !ignored;
1395
+ });
1396
+ const filteredVersions = {};
1397
+ for (const pkg of filteredPackages) {
1398
+ filteredVersions[pkg] = lockfileResult.versions[pkg];
1399
+ }
1473
1400
  spinner.succeed(
1474
- chalk6__default.default.blue(
1475
- `\u{1F4E6} Found ${lockfileResult.lockfileType} lockfile (supports: ${lockfileResult.supportedVersions.join(", ")}) - ${Object.keys(lockfileResult.versions).length} packages`
1476
- )
1401
+ `Found ${lockfileResult.lockfileType} lockfile (supports: ${lockfileResult.supportedVersions.join(", ")}) - ${filteredPackages.length}/${allPackages.length} packages`
1477
1402
  );
1478
1403
  spinner.start("Finding files...");
1479
1404
  const files = await findFiles(pattern, options.ignore);
1480
1405
  if (files.length === 0) {
1481
- spinner.fail("TEST");
1406
+ spinner.fail(`No files found matching pattern: ${pattern}`);
1482
1407
  return;
1483
1408
  }
1484
- spinner.succeed(chalk6__default.default.green(` Found ${files.length} files`));
1409
+ spinner.succeed(chalk5.green(` Found ${files.length} files`));
1485
1410
  spinner.start("Analyzing files...");
1486
1411
  const reports = [];
1487
1412
  for (let i = 0; i < files.length; i++) {
@@ -1489,39 +1414,34 @@ async function executeScan(pattern, options) {
1489
1414
  if (!options.verbose) {
1490
1415
  spinner.text = `Analyzing files... (${i + 1}/${files.length})`;
1491
1416
  }
1492
- try {
1493
- const report = parseFile(file);
1494
- if (report) {
1495
- reports.push(report);
1496
- }
1497
- } catch (error) {
1498
- spinner.stop();
1499
- console.error(chalk6__default.default.red(`Error analyzing ${file}: ${error.message}`));
1500
- spinner.start();
1417
+ const report = parseFile(file);
1418
+ if (report) {
1419
+ reports.push(report);
1501
1420
  }
1502
1421
  }
1503
- spinner.succeed(
1504
- chalk6__default.default.green(`Analysis complete! Analyzed ${reports.length} files`)
1505
- );
1506
1422
  const elapsedTime = (Date.now() - startTime) / 1e3;
1507
- const aggregated = aggregateReports(reports, lockfileResult.versions);
1508
- if (options.packages) {
1423
+ const aggregated = aggregateReports(reports, filteredVersions);
1424
+ if (options.packages && !options.noPackages) {
1509
1425
  printPackages(aggregated, options.packages);
1510
1426
  }
1511
- if (options.details) {
1512
- printDetails(aggregated);
1513
- }
1514
- if (options.components) {
1427
+ if (options.components && !options.noComponents) {
1515
1428
  printComponents(aggregated, options.components);
1516
1429
  }
1517
- if (options.patterns) {
1430
+ if (options.patterns && !options.noPatterns) {
1518
1431
  printPatterns(aggregated, options.patterns);
1519
1432
  }
1520
- if (options.summary) {
1521
- printSummary(aggregated, elapsedTime);
1433
+ if (options.summary && !options.noSummary) {
1434
+ printSummary(aggregated);
1522
1435
  }
1436
+ console.log("");
1437
+ spinner.succeed(
1438
+ chalk5.green.bold(
1439
+ ` Analysis complete! Analyzed ${reports.length} files in ${formatDuration(elapsedTime)}
1440
+ `
1441
+ )
1442
+ );
1523
1443
  } catch (error) {
1524
- spinner.fail(chalk6__default.default.red("Analysis failed: " + error.message));
1444
+ spinner.fail(chalk5.red("Analysis failed: " + error.message));
1525
1445
  console.error(error);
1526
1446
  process.exit(1);
1527
1447
  }
@@ -1529,14 +1449,14 @@ async function executeScan(pattern, options) {
1529
1449
 
1530
1450
  // package.json
1531
1451
  var package_default = {
1532
- version: "1.1.0"};
1452
+ version: "1.1.1"};
1533
1453
 
1534
1454
  // src/cli.ts
1535
- var program = new commander.Command();
1455
+ var program = new Command();
1536
1456
  program.name("hermex").description("Analyze React component usage patterns in your codebase").version(package_default.version);
1537
1457
  registerScanCommand(program);
1538
1458
  program.parse(process.argv);
1539
1459
 
1540
- exports.program = program;
1460
+ export { program };
1541
1461
  //# sourceMappingURL=cli.js.map
1542
1462
  //# sourceMappingURL=cli.js.map