@viberails/scanner 0.1.0 → 0.2.1
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/index.cjs +250 -35
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +55 -6
- package/dist/index.d.ts +55 -6
- package/dist/index.js +247 -35
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -21,6 +21,10 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
23
|
VERSION: () => VERSION,
|
|
24
|
+
aggregateConventions: () => aggregateConventions,
|
|
25
|
+
aggregateStacks: () => aggregateStacks,
|
|
26
|
+
aggregateStatistics: () => aggregateStatistics,
|
|
27
|
+
aggregateStructures: () => aggregateStructures,
|
|
24
28
|
computeStatistics: () => computeStatistics,
|
|
25
29
|
detectConventions: () => detectConventions,
|
|
26
30
|
detectStack: () => detectStack,
|
|
@@ -29,10 +33,161 @@ __export(index_exports, {
|
|
|
29
33
|
extractMajorVersion: () => extractMajorVersion,
|
|
30
34
|
readPackageJson: () => readPackageJson,
|
|
31
35
|
scan: () => scan,
|
|
36
|
+
scanPackage: () => scanPackage,
|
|
32
37
|
walkDirectory: () => walkDirectory
|
|
33
38
|
});
|
|
34
39
|
module.exports = __toCommonJS(index_exports);
|
|
35
40
|
|
|
41
|
+
// src/aggregate.ts
|
|
42
|
+
var import_types = require("@viberails/types");
|
|
43
|
+
var FRAMEWORK_PRIORITY = [
|
|
44
|
+
"nextjs",
|
|
45
|
+
"sveltekit",
|
|
46
|
+
"astro",
|
|
47
|
+
"expo",
|
|
48
|
+
"react-native",
|
|
49
|
+
"svelte",
|
|
50
|
+
"vue",
|
|
51
|
+
"react"
|
|
52
|
+
];
|
|
53
|
+
function aggregateStacks(packages) {
|
|
54
|
+
if (packages.length === 1) return packages[0].stack;
|
|
55
|
+
const language = packages.some((p) => p.stack.language.name === "typescript") ? packages.find((p) => p.stack.language.name === "typescript").stack.language : packages[0].stack.language;
|
|
56
|
+
const packageManager = packages[0].stack.packageManager;
|
|
57
|
+
const frameworkPackages = packages.filter((p) => p.stack.framework);
|
|
58
|
+
let framework;
|
|
59
|
+
if (frameworkPackages.length > 0) {
|
|
60
|
+
frameworkPackages.sort((a, b) => {
|
|
61
|
+
const aIdx = FRAMEWORK_PRIORITY.indexOf(a.stack.framework.name);
|
|
62
|
+
const bIdx = FRAMEWORK_PRIORITY.indexOf(b.stack.framework.name);
|
|
63
|
+
return (aIdx === -1 ? Infinity : aIdx) - (bIdx === -1 ? Infinity : bIdx);
|
|
64
|
+
});
|
|
65
|
+
framework = frameworkPackages[0].stack.framework;
|
|
66
|
+
}
|
|
67
|
+
const libraryMap = /* @__PURE__ */ new Map();
|
|
68
|
+
for (const pkg of packages) {
|
|
69
|
+
if (pkg.stack.framework && pkg.stack.framework.name !== framework?.name) {
|
|
70
|
+
libraryMap.set(pkg.stack.framework.name, pkg.stack.framework);
|
|
71
|
+
}
|
|
72
|
+
for (const lib of pkg.stack.libraries) {
|
|
73
|
+
if (!libraryMap.has(lib.name)) {
|
|
74
|
+
libraryMap.set(lib.name, lib);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
const styling = packages.find((p) => p.stack.styling)?.stack.styling;
|
|
79
|
+
const backend = packages.find((p) => p.stack.backend)?.stack.backend;
|
|
80
|
+
const linter = packages.find((p) => p.stack.linter)?.stack.linter;
|
|
81
|
+
const formatter = packages.find((p) => p.stack.formatter)?.stack.formatter;
|
|
82
|
+
const testRunner = packages.find((p) => p.stack.testRunner)?.stack.testRunner;
|
|
83
|
+
return {
|
|
84
|
+
language,
|
|
85
|
+
packageManager,
|
|
86
|
+
framework,
|
|
87
|
+
libraries: [...libraryMap.values()],
|
|
88
|
+
styling,
|
|
89
|
+
backend,
|
|
90
|
+
linter,
|
|
91
|
+
formatter,
|
|
92
|
+
testRunner
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
function aggregateStructures(packages) {
|
|
96
|
+
if (packages.length === 1) return packages[0].structure;
|
|
97
|
+
const srcDir = packages.some((p) => p.structure.srcDir) ? "src" : void 0;
|
|
98
|
+
const directories = packages.flatMap(
|
|
99
|
+
(pkg) => pkg.structure.directories.map((dir) => ({
|
|
100
|
+
...dir,
|
|
101
|
+
path: pkg.relativePath ? `${pkg.relativePath}/${dir.path}` : dir.path
|
|
102
|
+
}))
|
|
103
|
+
);
|
|
104
|
+
const testPatterns = packages.map((p) => p.structure.testPattern).filter((t) => t !== void 0);
|
|
105
|
+
let testPattern;
|
|
106
|
+
if (testPatterns.length > 0) {
|
|
107
|
+
const counts = /* @__PURE__ */ new Map();
|
|
108
|
+
for (const tp of testPatterns) {
|
|
109
|
+
const existing = counts.get(tp.value);
|
|
110
|
+
if (existing) {
|
|
111
|
+
existing.count++;
|
|
112
|
+
} else {
|
|
113
|
+
counts.set(tp.value, { count: 1, pattern: tp });
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
let best = { count: 0, pattern: testPatterns[0] };
|
|
117
|
+
for (const entry of counts.values()) {
|
|
118
|
+
if (entry.count > best.count) best = entry;
|
|
119
|
+
}
|
|
120
|
+
testPattern = best.pattern;
|
|
121
|
+
}
|
|
122
|
+
return { srcDir, directories, testPattern };
|
|
123
|
+
}
|
|
124
|
+
function aggregateConventions(packages) {
|
|
125
|
+
if (packages.length === 1) return packages[0].conventions;
|
|
126
|
+
const allKeys = /* @__PURE__ */ new Set();
|
|
127
|
+
for (const pkg of packages) {
|
|
128
|
+
for (const key of Object.keys(pkg.conventions)) {
|
|
129
|
+
allKeys.add(key);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
const result = {};
|
|
133
|
+
for (const key of allKeys) {
|
|
134
|
+
const entries = packages.map((p) => p.conventions[key]).filter((c) => c !== void 0);
|
|
135
|
+
if (entries.length < packages.length / 2) continue;
|
|
136
|
+
const valueCounts = /* @__PURE__ */ new Map();
|
|
137
|
+
for (const entry of entries) {
|
|
138
|
+
const existing = valueCounts.get(entry.value);
|
|
139
|
+
if (existing) {
|
|
140
|
+
existing.count++;
|
|
141
|
+
existing.totalConsistency += entry.consistency;
|
|
142
|
+
existing.totalSamples += entry.sampleSize;
|
|
143
|
+
} else {
|
|
144
|
+
valueCounts.set(entry.value, {
|
|
145
|
+
count: 1,
|
|
146
|
+
totalConsistency: entry.consistency,
|
|
147
|
+
totalSamples: entry.sampleSize
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
let majorityValue = "";
|
|
152
|
+
let majorityData = { count: 0, totalConsistency: 0, totalSamples: 0 };
|
|
153
|
+
for (const [value, data] of valueCounts) {
|
|
154
|
+
if (data.count > majorityData.count) {
|
|
155
|
+
majorityValue = value;
|
|
156
|
+
majorityData = data;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
const agreement = majorityData.count / entries.length;
|
|
160
|
+
const avgConsistency = majorityData.totalConsistency / majorityData.count;
|
|
161
|
+
const consistency = Math.round(avgConsistency * agreement);
|
|
162
|
+
result[key] = {
|
|
163
|
+
value: majorityValue,
|
|
164
|
+
confidence: (0, import_types.confidenceFromConsistency)(consistency),
|
|
165
|
+
sampleSize: majorityData.totalSamples,
|
|
166
|
+
consistency
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
return result;
|
|
170
|
+
}
|
|
171
|
+
function aggregateStatistics(packages) {
|
|
172
|
+
if (packages.length === 1) return packages[0].statistics;
|
|
173
|
+
const totalFiles = packages.reduce((sum, p) => sum + p.statistics.totalFiles, 0);
|
|
174
|
+
const totalLines = packages.reduce((sum, p) => sum + p.statistics.totalLines, 0);
|
|
175
|
+
const averageFileLines = totalFiles > 0 ? Math.round(totalLines / totalFiles) : 0;
|
|
176
|
+
const largestFiles = packages.flatMap(
|
|
177
|
+
(pkg) => pkg.statistics.largestFiles.map((f) => ({
|
|
178
|
+
path: pkg.relativePath ? `${pkg.relativePath}/${f.path}` : f.path,
|
|
179
|
+
lines: f.lines
|
|
180
|
+
}))
|
|
181
|
+
).sort((a, b) => b.lines - a.lines).slice(0, 5);
|
|
182
|
+
const filesByExtension = {};
|
|
183
|
+
for (const pkg of packages) {
|
|
184
|
+
for (const [ext, count] of Object.entries(pkg.statistics.filesByExtension)) {
|
|
185
|
+
filesByExtension[ext] = (filesByExtension[ext] ?? 0) + count;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return { totalFiles, totalLines, averageFileLines, largestFiles, filesByExtension };
|
|
189
|
+
}
|
|
190
|
+
|
|
36
191
|
// src/compute-statistics.ts
|
|
37
192
|
var import_promises2 = require("fs/promises");
|
|
38
193
|
var import_node_path2 = require("path");
|
|
@@ -51,7 +206,12 @@ var IGNORED_DIRS = /* @__PURE__ */ new Set([
|
|
|
51
206
|
"coverage",
|
|
52
207
|
".turbo",
|
|
53
208
|
".cache",
|
|
54
|
-
".output"
|
|
209
|
+
".output",
|
|
210
|
+
".expo",
|
|
211
|
+
"android",
|
|
212
|
+
"ios",
|
|
213
|
+
"Pods",
|
|
214
|
+
".gradle"
|
|
55
215
|
]);
|
|
56
216
|
var SOURCE_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
57
217
|
".ts",
|
|
@@ -78,7 +238,9 @@ async function walkDirectory(projectPath, maxDepth = 4) {
|
|
|
78
238
|
return results;
|
|
79
239
|
}
|
|
80
240
|
while (queue.length > 0) {
|
|
81
|
-
const
|
|
241
|
+
const item = queue.shift();
|
|
242
|
+
if (!item) break;
|
|
243
|
+
const { absolutePath, depth } = item;
|
|
82
244
|
const sourceFileNames = [];
|
|
83
245
|
try {
|
|
84
246
|
const entries = await (0, import_promises.readdir)(absolutePath, { withFileTypes: true });
|
|
@@ -202,7 +364,7 @@ async function computeStatistics(projectPath, dirs) {
|
|
|
202
364
|
// src/detect-conventions.ts
|
|
203
365
|
var import_promises3 = require("fs/promises");
|
|
204
366
|
var import_node_path3 = require("path");
|
|
205
|
-
var
|
|
367
|
+
var import_types2 = require("@viberails/types");
|
|
206
368
|
|
|
207
369
|
// src/utils/classify-filename.ts
|
|
208
370
|
var PATTERNS = [
|
|
@@ -259,7 +421,7 @@ function detectFileNaming(dirs) {
|
|
|
259
421
|
if (sorted.length === 0) return void 0;
|
|
260
422
|
const [dominantConvention, dominantCount] = sorted[0];
|
|
261
423
|
const consistency = Math.round(dominantCount / total * 100);
|
|
262
|
-
const confidence = (0,
|
|
424
|
+
const confidence = (0, import_types2.confidenceFromConsistency)(consistency);
|
|
263
425
|
if (confidence === "low") return void 0;
|
|
264
426
|
return {
|
|
265
427
|
value: dominantConvention,
|
|
@@ -285,7 +447,7 @@ function detectComponentNaming(dirs, structure) {
|
|
|
285
447
|
const dominantValue = pascalCount >= tsxFiles.length / 2 ? "PascalCase" : "camelCase";
|
|
286
448
|
return {
|
|
287
449
|
value: dominantValue,
|
|
288
|
-
confidence: (0,
|
|
450
|
+
confidence: (0, import_types2.confidenceFromConsistency)(consistency),
|
|
289
451
|
sampleSize: tsxFiles.length,
|
|
290
452
|
consistency
|
|
291
453
|
};
|
|
@@ -321,7 +483,7 @@ function detectHookNaming(dirs, structure) {
|
|
|
321
483
|
const consistency = Math.round(dominantCount / total * 100);
|
|
322
484
|
return {
|
|
323
485
|
value: isDominantKebab ? "use-*" : "useXxx",
|
|
324
|
-
confidence: (0,
|
|
486
|
+
confidence: (0, import_types2.confidenceFromConsistency)(consistency),
|
|
325
487
|
sampleSize: total,
|
|
326
488
|
consistency
|
|
327
489
|
};
|
|
@@ -335,7 +497,7 @@ async function detectImportAlias(projectPath) {
|
|
|
335
497
|
const aliases = Object.keys(paths);
|
|
336
498
|
if (aliases.length === 0) return void 0;
|
|
337
499
|
return {
|
|
338
|
-
value: aliases
|
|
500
|
+
value: aliases.join(","),
|
|
339
501
|
confidence: "high",
|
|
340
502
|
sampleSize: aliases.length,
|
|
341
503
|
consistency: 100
|
|
@@ -376,6 +538,8 @@ async function fileExists(filePath) {
|
|
|
376
538
|
}
|
|
377
539
|
var FRAMEWORK_MAPPINGS = [
|
|
378
540
|
{ dep: "next", name: "nextjs" },
|
|
541
|
+
{ dep: "expo", name: "expo" },
|
|
542
|
+
{ dep: "react-native", name: "react-native", excludeDep: "expo" },
|
|
379
543
|
{ dep: "@sveltejs/kit", name: "sveltekit" },
|
|
380
544
|
{ dep: "svelte", name: "svelte" },
|
|
381
545
|
{ dep: "astro", name: "astro" },
|
|
@@ -409,9 +573,10 @@ var LOCK_FILE_MAP = [
|
|
|
409
573
|
{ file: "bun.lockb", name: "bun" },
|
|
410
574
|
{ file: "package-lock.json", name: "npm" }
|
|
411
575
|
];
|
|
412
|
-
async function detectStack(projectPath) {
|
|
576
|
+
async function detectStack(projectPath, additionalDeps) {
|
|
413
577
|
const pkg = await readPackageJson(projectPath);
|
|
414
578
|
const allDeps = {
|
|
579
|
+
...additionalDeps,
|
|
415
580
|
...pkg?.dependencies,
|
|
416
581
|
...pkg?.devDependencies
|
|
417
582
|
};
|
|
@@ -421,6 +586,7 @@ async function detectStack(projectPath) {
|
|
|
421
586
|
const backend = detectFirst(allDeps, BACKEND_MAPPINGS);
|
|
422
587
|
const packageManager = await detectPackageManager(projectPath);
|
|
423
588
|
const linter = detectLinter(allDeps);
|
|
589
|
+
const formatter = detectFormatter(allDeps);
|
|
424
590
|
const testRunner = detectTestRunner(allDeps);
|
|
425
591
|
const libraries = detectLibraries(allDeps);
|
|
426
592
|
return {
|
|
@@ -430,6 +596,7 @@ async function detectStack(projectPath) {
|
|
|
430
596
|
...backend && { backend },
|
|
431
597
|
packageManager,
|
|
432
598
|
...linter && { linter },
|
|
599
|
+
...formatter && { formatter },
|
|
433
600
|
...testRunner && { testRunner },
|
|
434
601
|
libraries
|
|
435
602
|
};
|
|
@@ -488,6 +655,18 @@ function detectLinter(allDeps) {
|
|
|
488
655
|
}
|
|
489
656
|
return void 0;
|
|
490
657
|
}
|
|
658
|
+
function detectFormatter(allDeps) {
|
|
659
|
+
if ("prettier" in allDeps) {
|
|
660
|
+
return { name: "prettier", version: extractMajorVersion(allDeps.prettier) };
|
|
661
|
+
}
|
|
662
|
+
if ("@biomejs/biome" in allDeps) {
|
|
663
|
+
return {
|
|
664
|
+
name: "biome",
|
|
665
|
+
version: extractMajorVersion(allDeps["@biomejs/biome"])
|
|
666
|
+
};
|
|
667
|
+
}
|
|
668
|
+
return void 0;
|
|
669
|
+
}
|
|
491
670
|
function detectTestRunner(allDeps) {
|
|
492
671
|
if ("vitest" in allDeps) {
|
|
493
672
|
return { name: "vitest", version: extractMajorVersion(allDeps.vitest) };
|
|
@@ -512,7 +691,7 @@ function detectLibraries(allDeps) {
|
|
|
512
691
|
}
|
|
513
692
|
|
|
514
693
|
// src/detect-structure.ts
|
|
515
|
-
var
|
|
694
|
+
var import_types3 = require("@viberails/types");
|
|
516
695
|
|
|
517
696
|
// src/utils/classify-directory.ts
|
|
518
697
|
var ROLE_PATTERNS = [
|
|
@@ -553,7 +732,9 @@ function classifyDirectory(dir) {
|
|
|
553
732
|
function matchByName(relativePath) {
|
|
554
733
|
for (const { role, pathPatterns } of ROLE_PATTERNS) {
|
|
555
734
|
for (const pattern of pathPatterns) {
|
|
556
|
-
if (relativePath === pattern)
|
|
735
|
+
if (relativePath === pattern || relativePath.endsWith(`/${pattern}`)) {
|
|
736
|
+
return role;
|
|
737
|
+
}
|
|
557
738
|
}
|
|
558
739
|
}
|
|
559
740
|
return null;
|
|
@@ -564,7 +745,7 @@ function inferFromContent(dir) {
|
|
|
564
745
|
const name = f.split(".")[0];
|
|
565
746
|
return name.startsWith("use-") || /^use[A-Z]/.test(name);
|
|
566
747
|
});
|
|
567
|
-
if (hookFiles.length
|
|
748
|
+
if (hookFiles.length >= 2 && hookFiles.length / sourceFileCount >= 0.5) {
|
|
568
749
|
return {
|
|
569
750
|
path: dir.relativePath,
|
|
570
751
|
role: "hooks",
|
|
@@ -573,7 +754,7 @@ function inferFromContent(dir) {
|
|
|
573
754
|
};
|
|
574
755
|
}
|
|
575
756
|
const testFiles = sourceFileNames.filter((f) => f.includes(".test.") || f.includes(".spec."));
|
|
576
|
-
if (testFiles.length
|
|
757
|
+
if (testFiles.length >= 2 && testFiles.length / sourceFileCount >= 0.5) {
|
|
577
758
|
return {
|
|
578
759
|
path: dir.relativePath,
|
|
579
760
|
role: "tests",
|
|
@@ -618,7 +799,7 @@ function detectTestPattern(dirs) {
|
|
|
618
799
|
const sep = isDotTest ? "test" : "spec";
|
|
619
800
|
return {
|
|
620
801
|
value: `*.${sep}${topExt}`,
|
|
621
|
-
confidence: (0,
|
|
802
|
+
confidence: (0, import_types3.confidenceFromConsistency)(consistency),
|
|
622
803
|
sampleSize: testFiles.length,
|
|
623
804
|
consistency
|
|
624
805
|
};
|
|
@@ -720,18 +901,33 @@ async function resolvePackages(projectRoot, dirs) {
|
|
|
720
901
|
|
|
721
902
|
// src/scan.ts
|
|
722
903
|
var import_promises7 = require("fs/promises");
|
|
904
|
+
var import_node_path8 = require("path");
|
|
905
|
+
|
|
906
|
+
// src/scan-package.ts
|
|
723
907
|
var import_node_path7 = require("path");
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
908
|
+
async function scanPackage(packagePath, name, relativePath, rootDeps) {
|
|
909
|
+
const root = (0, import_node_path7.resolve)(packagePath);
|
|
910
|
+
const dirs = await walkDirectory(root, 4);
|
|
911
|
+
const [stack, structure, statistics] = await Promise.all([
|
|
912
|
+
detectStack(root, rootDeps),
|
|
913
|
+
detectStructure(root, dirs),
|
|
914
|
+
computeStatistics(root, dirs)
|
|
915
|
+
]);
|
|
916
|
+
const conventions = await detectConventions(root, structure, dirs);
|
|
917
|
+
return {
|
|
918
|
+
name,
|
|
919
|
+
root,
|
|
920
|
+
relativePath,
|
|
921
|
+
stack,
|
|
922
|
+
structure,
|
|
923
|
+
conventions,
|
|
924
|
+
statistics
|
|
925
|
+
};
|
|
732
926
|
}
|
|
927
|
+
|
|
928
|
+
// src/scan.ts
|
|
733
929
|
async function scan(projectPath, _options) {
|
|
734
|
-
const root = (0,
|
|
930
|
+
const root = (0, import_node_path8.resolve)(projectPath);
|
|
735
931
|
try {
|
|
736
932
|
const st = await (0, import_promises7.stat)(root);
|
|
737
933
|
if (!st.isDirectory()) {
|
|
@@ -743,22 +939,36 @@ async function scan(projectPath, _options) {
|
|
|
743
939
|
}
|
|
744
940
|
throw new Error(`Project path does not exist: ${root}`);
|
|
745
941
|
}
|
|
746
|
-
const allDirs = await walkDirectory(root, 4);
|
|
747
|
-
const dirs = filterFixtureDirs(allDirs);
|
|
748
|
-
const [stack, structure, statistics] = await Promise.all([
|
|
749
|
-
detectStack(root),
|
|
750
|
-
detectStructure(root, dirs),
|
|
751
|
-
computeStatistics(root, dirs)
|
|
752
|
-
]);
|
|
753
|
-
const conventions = await detectConventions(root, structure, dirs);
|
|
754
942
|
const workspace = await detectWorkspace(root);
|
|
943
|
+
if (workspace && workspace.packages.length > 0) {
|
|
944
|
+
const rootPkg2 = await readPackageJson(root);
|
|
945
|
+
const rootDeps = {
|
|
946
|
+
...rootPkg2?.dependencies,
|
|
947
|
+
...rootPkg2?.devDependencies
|
|
948
|
+
};
|
|
949
|
+
const packages = await Promise.all(
|
|
950
|
+
workspace.packages.map((wp) => scanPackage(wp.path, wp.name, wp.relativePath, rootDeps))
|
|
951
|
+
);
|
|
952
|
+
return {
|
|
953
|
+
root,
|
|
954
|
+
stack: aggregateStacks(packages),
|
|
955
|
+
structure: aggregateStructures(packages),
|
|
956
|
+
conventions: aggregateConventions(packages),
|
|
957
|
+
statistics: aggregateStatistics(packages),
|
|
958
|
+
workspace,
|
|
959
|
+
packages
|
|
960
|
+
};
|
|
961
|
+
}
|
|
962
|
+
const rootPkg = await readPackageJson(root);
|
|
963
|
+
const name = rootPkg?.name ?? (0, import_node_path8.basename)(root);
|
|
964
|
+
const pkg = await scanPackage(root, name, "");
|
|
755
965
|
return {
|
|
756
966
|
root,
|
|
757
|
-
stack,
|
|
758
|
-
structure,
|
|
759
|
-
conventions,
|
|
760
|
-
statistics,
|
|
761
|
-
|
|
967
|
+
stack: pkg.stack,
|
|
968
|
+
structure: pkg.structure,
|
|
969
|
+
conventions: pkg.conventions,
|
|
970
|
+
statistics: pkg.statistics,
|
|
971
|
+
packages: [pkg]
|
|
762
972
|
};
|
|
763
973
|
}
|
|
764
974
|
|
|
@@ -767,6 +977,10 @@ var VERSION = "0.1.0";
|
|
|
767
977
|
// Annotate the CommonJS export names for ESM import in node:
|
|
768
978
|
0 && (module.exports = {
|
|
769
979
|
VERSION,
|
|
980
|
+
aggregateConventions,
|
|
981
|
+
aggregateStacks,
|
|
982
|
+
aggregateStatistics,
|
|
983
|
+
aggregateStructures,
|
|
770
984
|
computeStatistics,
|
|
771
985
|
detectConventions,
|
|
772
986
|
detectStack,
|
|
@@ -775,6 +989,7 @@ var VERSION = "0.1.0";
|
|
|
775
989
|
extractMajorVersion,
|
|
776
990
|
readPackageJson,
|
|
777
991
|
scan,
|
|
992
|
+
scanPackage,
|
|
778
993
|
walkDirectory
|
|
779
994
|
});
|
|
780
995
|
//# sourceMappingURL=index.cjs.map
|