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/README.md +131 -131
- package/dist/cli.js +159 -239
- package/dist/cli.js.map +1 -1
- package/package.json +4 -1
package/dist/cli.js
CHANGED
|
@@ -1,26 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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 (
|
|
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:
|
|
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 =
|
|
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:
|
|
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 (
|
|
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:
|
|
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 (
|
|
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" &&
|
|
332
|
+
if (prop.type === "AssignmentPatternProperty" && prop.key?.type === "Identifier") {
|
|
355
333
|
const propName = prop.key.value;
|
|
356
|
-
if (
|
|
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:
|
|
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
|
-
|
|
384
|
-
const
|
|
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:
|
|
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
|
-
|
|
399
|
-
|
|
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:
|
|
408
|
-
line:
|
|
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
|
-
|
|
415
|
-
|
|
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 (
|
|
393
|
+
if (componentProps?.length > 0) {
|
|
423
394
|
state.usagePatterns.objectMappings.add({
|
|
424
|
-
mappings: componentProps.map((prop) => {
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
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
|
-
|
|
440
|
-
|
|
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 (
|
|
444
|
-
const source =
|
|
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:
|
|
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
|
-
|
|
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:
|
|
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:
|
|
472
|
-
component:
|
|
473
|
-
line:
|
|
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
|
-
|
|
479
|
-
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
-
|
|
504
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 (
|
|
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 (
|
|
598
|
-
if (
|
|
547
|
+
if (node.callee?.object?.value === "React") {
|
|
548
|
+
if (node.callee?.property?.value === "memo") {
|
|
599
549
|
analyzeMemoUsage(node, state);
|
|
600
|
-
} else if (
|
|
550
|
+
} else if (node.callee?.property?.value === "forwardRef") {
|
|
601
551
|
analyzeForwardRefUsage(node, state);
|
|
602
552
|
}
|
|
603
553
|
}
|
|
604
|
-
if (
|
|
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 =
|
|
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
|
-
|
|
704
|
-
|
|
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(
|
|
927
|
+
return `${seconds.toFixed(2)}s`;
|
|
984
928
|
}
|
|
985
929
|
|
|
986
930
|
// src/utils/print-summary.ts
|
|
987
931
|
function printHeader() {
|
|
988
|
-
console.log(
|
|
932
|
+
console.log(chalk5.green.bold("\n\u{1F4CA} Summary\n"));
|
|
989
933
|
}
|
|
990
|
-
function printSummary(aggregated
|
|
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
|
|
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(
|
|
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(
|
|
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 =
|
|
1063
|
-
const valueStr = showValues ? ` ${item.value
|
|
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
|
|
1071
|
-
console.log(
|
|
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
|
-
|
|
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(
|
|
1005
|
+
console.log(chalk5.gray(" No external components found"));
|
|
1088
1006
|
return;
|
|
1089
1007
|
}
|
|
1090
|
-
const table = new
|
|
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
|
-
|
|
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(
|
|
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
|
|
1118
|
-
console.log(
|
|
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
|
-
|
|
1047
|
+
printHeader3();
|
|
1130
1048
|
if (patterns.length === 0) {
|
|
1131
|
-
console.log(
|
|
1049
|
+
console.log(chalk5.gray(" No patterns found"));
|
|
1132
1050
|
return;
|
|
1133
1051
|
}
|
|
1134
|
-
const table = new
|
|
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(
|
|
1064
|
+
console.log(chalk5.gray(`
|
|
1147
1065
|
Total: ${totalPatterns} patterns detected`));
|
|
1148
1066
|
}
|
|
1149
1067
|
function printPatternsChart(patterns) {
|
|
1150
|
-
|
|
1068
|
+
printHeader3();
|
|
1151
1069
|
if (patterns.length === 0) {
|
|
1152
|
-
console.log(
|
|
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
|
|
1162
|
-
console.log(
|
|
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
|
-
|
|
1091
|
+
printHeader4();
|
|
1174
1092
|
if (packages.length === 0) {
|
|
1175
|
-
console.log(
|
|
1093
|
+
console.log(chalk5.gray(" No packages found"));
|
|
1176
1094
|
return;
|
|
1177
1095
|
}
|
|
1178
|
-
const table = new
|
|
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
|
-
|
|
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
|
-
|
|
1126
|
+
printHeader4();
|
|
1209
1127
|
if (packages.length === 0) {
|
|
1210
|
-
console.log(
|
|
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 =
|
|
1140
|
+
const bar = chalk5.green("\u2588".repeat(barLength)) + chalk5.gray("\u2591".repeat(emptyLength));
|
|
1223
1141
|
console.log(
|
|
1224
|
-
`${paddedLabel} ${bar} ${
|
|
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
|
|
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 =
|
|
1244
|
-
return
|
|
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 =
|
|
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 =
|
|
1291
|
-
return
|
|
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 =
|
|
1296
|
-
const lockData =
|
|
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 =
|
|
1356
|
-
return
|
|
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 =
|
|
1361
|
-
const parsed =
|
|
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
|
-
"
|
|
1347
|
+
"Pattern for what packages to ignore",
|
|
1433
1348
|
[]
|
|
1434
|
-
).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
|
|
1452
|
-
if (!
|
|
1366
|
+
function normalizeArray(value) {
|
|
1367
|
+
if (!value) {
|
|
1453
1368
|
return [];
|
|
1454
1369
|
}
|
|
1455
|
-
return Array.isArray(
|
|
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
|
-
|
|
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:
|
|
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 =
|
|
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
|
-
|
|
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(
|
|
1406
|
+
spinner.fail(`No files found matching pattern: ${pattern}`);
|
|
1482
1407
|
return;
|
|
1483
1408
|
}
|
|
1484
|
-
spinner.succeed(
|
|
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
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
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,
|
|
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.
|
|
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
|
|
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(
|
|
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.
|
|
1452
|
+
version: "1.1.1"};
|
|
1533
1453
|
|
|
1534
1454
|
// src/cli.ts
|
|
1535
|
-
var program = new
|
|
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
|
-
|
|
1460
|
+
export { program };
|
|
1541
1461
|
//# sourceMappingURL=cli.js.map
|
|
1542
1462
|
//# sourceMappingURL=cli.js.map
|