@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.js
CHANGED
|
@@ -1,3 +1,155 @@
|
|
|
1
|
+
// src/aggregate.ts
|
|
2
|
+
import {
|
|
3
|
+
confidenceFromConsistency
|
|
4
|
+
} from "@viberails/types";
|
|
5
|
+
var FRAMEWORK_PRIORITY = [
|
|
6
|
+
"nextjs",
|
|
7
|
+
"sveltekit",
|
|
8
|
+
"astro",
|
|
9
|
+
"expo",
|
|
10
|
+
"react-native",
|
|
11
|
+
"svelte",
|
|
12
|
+
"vue",
|
|
13
|
+
"react"
|
|
14
|
+
];
|
|
15
|
+
function aggregateStacks(packages) {
|
|
16
|
+
if (packages.length === 1) return packages[0].stack;
|
|
17
|
+
const language = packages.some((p) => p.stack.language.name === "typescript") ? packages.find((p) => p.stack.language.name === "typescript").stack.language : packages[0].stack.language;
|
|
18
|
+
const packageManager = packages[0].stack.packageManager;
|
|
19
|
+
const frameworkPackages = packages.filter((p) => p.stack.framework);
|
|
20
|
+
let framework;
|
|
21
|
+
if (frameworkPackages.length > 0) {
|
|
22
|
+
frameworkPackages.sort((a, b) => {
|
|
23
|
+
const aIdx = FRAMEWORK_PRIORITY.indexOf(a.stack.framework.name);
|
|
24
|
+
const bIdx = FRAMEWORK_PRIORITY.indexOf(b.stack.framework.name);
|
|
25
|
+
return (aIdx === -1 ? Infinity : aIdx) - (bIdx === -1 ? Infinity : bIdx);
|
|
26
|
+
});
|
|
27
|
+
framework = frameworkPackages[0].stack.framework;
|
|
28
|
+
}
|
|
29
|
+
const libraryMap = /* @__PURE__ */ new Map();
|
|
30
|
+
for (const pkg of packages) {
|
|
31
|
+
if (pkg.stack.framework && pkg.stack.framework.name !== framework?.name) {
|
|
32
|
+
libraryMap.set(pkg.stack.framework.name, pkg.stack.framework);
|
|
33
|
+
}
|
|
34
|
+
for (const lib of pkg.stack.libraries) {
|
|
35
|
+
if (!libraryMap.has(lib.name)) {
|
|
36
|
+
libraryMap.set(lib.name, lib);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
const styling = packages.find((p) => p.stack.styling)?.stack.styling;
|
|
41
|
+
const backend = packages.find((p) => p.stack.backend)?.stack.backend;
|
|
42
|
+
const linter = packages.find((p) => p.stack.linter)?.stack.linter;
|
|
43
|
+
const formatter = packages.find((p) => p.stack.formatter)?.stack.formatter;
|
|
44
|
+
const testRunner = packages.find((p) => p.stack.testRunner)?.stack.testRunner;
|
|
45
|
+
return {
|
|
46
|
+
language,
|
|
47
|
+
packageManager,
|
|
48
|
+
framework,
|
|
49
|
+
libraries: [...libraryMap.values()],
|
|
50
|
+
styling,
|
|
51
|
+
backend,
|
|
52
|
+
linter,
|
|
53
|
+
formatter,
|
|
54
|
+
testRunner
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
function aggregateStructures(packages) {
|
|
58
|
+
if (packages.length === 1) return packages[0].structure;
|
|
59
|
+
const srcDir = packages.some((p) => p.structure.srcDir) ? "src" : void 0;
|
|
60
|
+
const directories = packages.flatMap(
|
|
61
|
+
(pkg) => pkg.structure.directories.map((dir) => ({
|
|
62
|
+
...dir,
|
|
63
|
+
path: pkg.relativePath ? `${pkg.relativePath}/${dir.path}` : dir.path
|
|
64
|
+
}))
|
|
65
|
+
);
|
|
66
|
+
const testPatterns = packages.map((p) => p.structure.testPattern).filter((t) => t !== void 0);
|
|
67
|
+
let testPattern;
|
|
68
|
+
if (testPatterns.length > 0) {
|
|
69
|
+
const counts = /* @__PURE__ */ new Map();
|
|
70
|
+
for (const tp of testPatterns) {
|
|
71
|
+
const existing = counts.get(tp.value);
|
|
72
|
+
if (existing) {
|
|
73
|
+
existing.count++;
|
|
74
|
+
} else {
|
|
75
|
+
counts.set(tp.value, { count: 1, pattern: tp });
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
let best = { count: 0, pattern: testPatterns[0] };
|
|
79
|
+
for (const entry of counts.values()) {
|
|
80
|
+
if (entry.count > best.count) best = entry;
|
|
81
|
+
}
|
|
82
|
+
testPattern = best.pattern;
|
|
83
|
+
}
|
|
84
|
+
return { srcDir, directories, testPattern };
|
|
85
|
+
}
|
|
86
|
+
function aggregateConventions(packages) {
|
|
87
|
+
if (packages.length === 1) return packages[0].conventions;
|
|
88
|
+
const allKeys = /* @__PURE__ */ new Set();
|
|
89
|
+
for (const pkg of packages) {
|
|
90
|
+
for (const key of Object.keys(pkg.conventions)) {
|
|
91
|
+
allKeys.add(key);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
const result = {};
|
|
95
|
+
for (const key of allKeys) {
|
|
96
|
+
const entries = packages.map((p) => p.conventions[key]).filter((c) => c !== void 0);
|
|
97
|
+
if (entries.length < packages.length / 2) continue;
|
|
98
|
+
const valueCounts = /* @__PURE__ */ new Map();
|
|
99
|
+
for (const entry of entries) {
|
|
100
|
+
const existing = valueCounts.get(entry.value);
|
|
101
|
+
if (existing) {
|
|
102
|
+
existing.count++;
|
|
103
|
+
existing.totalConsistency += entry.consistency;
|
|
104
|
+
existing.totalSamples += entry.sampleSize;
|
|
105
|
+
} else {
|
|
106
|
+
valueCounts.set(entry.value, {
|
|
107
|
+
count: 1,
|
|
108
|
+
totalConsistency: entry.consistency,
|
|
109
|
+
totalSamples: entry.sampleSize
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
let majorityValue = "";
|
|
114
|
+
let majorityData = { count: 0, totalConsistency: 0, totalSamples: 0 };
|
|
115
|
+
for (const [value, data] of valueCounts) {
|
|
116
|
+
if (data.count > majorityData.count) {
|
|
117
|
+
majorityValue = value;
|
|
118
|
+
majorityData = data;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
const agreement = majorityData.count / entries.length;
|
|
122
|
+
const avgConsistency = majorityData.totalConsistency / majorityData.count;
|
|
123
|
+
const consistency = Math.round(avgConsistency * agreement);
|
|
124
|
+
result[key] = {
|
|
125
|
+
value: majorityValue,
|
|
126
|
+
confidence: confidenceFromConsistency(consistency),
|
|
127
|
+
sampleSize: majorityData.totalSamples,
|
|
128
|
+
consistency
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
return result;
|
|
132
|
+
}
|
|
133
|
+
function aggregateStatistics(packages) {
|
|
134
|
+
if (packages.length === 1) return packages[0].statistics;
|
|
135
|
+
const totalFiles = packages.reduce((sum, p) => sum + p.statistics.totalFiles, 0);
|
|
136
|
+
const totalLines = packages.reduce((sum, p) => sum + p.statistics.totalLines, 0);
|
|
137
|
+
const averageFileLines = totalFiles > 0 ? Math.round(totalLines / totalFiles) : 0;
|
|
138
|
+
const largestFiles = packages.flatMap(
|
|
139
|
+
(pkg) => pkg.statistics.largestFiles.map((f) => ({
|
|
140
|
+
path: pkg.relativePath ? `${pkg.relativePath}/${f.path}` : f.path,
|
|
141
|
+
lines: f.lines
|
|
142
|
+
}))
|
|
143
|
+
).sort((a, b) => b.lines - a.lines).slice(0, 5);
|
|
144
|
+
const filesByExtension = {};
|
|
145
|
+
for (const pkg of packages) {
|
|
146
|
+
for (const [ext, count] of Object.entries(pkg.statistics.filesByExtension)) {
|
|
147
|
+
filesByExtension[ext] = (filesByExtension[ext] ?? 0) + count;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return { totalFiles, totalLines, averageFileLines, largestFiles, filesByExtension };
|
|
151
|
+
}
|
|
152
|
+
|
|
1
153
|
// src/compute-statistics.ts
|
|
2
154
|
import { readdir as readdir2, readFile } from "fs/promises";
|
|
3
155
|
import { extname, join as join2 } from "path";
|
|
@@ -16,7 +168,12 @@ var IGNORED_DIRS = /* @__PURE__ */ new Set([
|
|
|
16
168
|
"coverage",
|
|
17
169
|
".turbo",
|
|
18
170
|
".cache",
|
|
19
|
-
".output"
|
|
171
|
+
".output",
|
|
172
|
+
".expo",
|
|
173
|
+
"android",
|
|
174
|
+
"ios",
|
|
175
|
+
"Pods",
|
|
176
|
+
".gradle"
|
|
20
177
|
]);
|
|
21
178
|
var SOURCE_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
22
179
|
".ts",
|
|
@@ -43,7 +200,9 @@ async function walkDirectory(projectPath, maxDepth = 4) {
|
|
|
43
200
|
return results;
|
|
44
201
|
}
|
|
45
202
|
while (queue.length > 0) {
|
|
46
|
-
const
|
|
203
|
+
const item = queue.shift();
|
|
204
|
+
if (!item) break;
|
|
205
|
+
const { absolutePath, depth } = item;
|
|
47
206
|
const sourceFileNames = [];
|
|
48
207
|
try {
|
|
49
208
|
const entries = await readdir(absolutePath, { withFileTypes: true });
|
|
@@ -167,7 +326,7 @@ async function computeStatistics(projectPath, dirs) {
|
|
|
167
326
|
// src/detect-conventions.ts
|
|
168
327
|
import { readFile as readFile2 } from "fs/promises";
|
|
169
328
|
import { join as join3 } from "path";
|
|
170
|
-
import { confidenceFromConsistency } from "@viberails/types";
|
|
329
|
+
import { confidenceFromConsistency as confidenceFromConsistency2 } from "@viberails/types";
|
|
171
330
|
|
|
172
331
|
// src/utils/classify-filename.ts
|
|
173
332
|
var PATTERNS = [
|
|
@@ -224,7 +383,7 @@ function detectFileNaming(dirs) {
|
|
|
224
383
|
if (sorted.length === 0) return void 0;
|
|
225
384
|
const [dominantConvention, dominantCount] = sorted[0];
|
|
226
385
|
const consistency = Math.round(dominantCount / total * 100);
|
|
227
|
-
const confidence =
|
|
386
|
+
const confidence = confidenceFromConsistency2(consistency);
|
|
228
387
|
if (confidence === "low") return void 0;
|
|
229
388
|
return {
|
|
230
389
|
value: dominantConvention,
|
|
@@ -250,7 +409,7 @@ function detectComponentNaming(dirs, structure) {
|
|
|
250
409
|
const dominantValue = pascalCount >= tsxFiles.length / 2 ? "PascalCase" : "camelCase";
|
|
251
410
|
return {
|
|
252
411
|
value: dominantValue,
|
|
253
|
-
confidence:
|
|
412
|
+
confidence: confidenceFromConsistency2(consistency),
|
|
254
413
|
sampleSize: tsxFiles.length,
|
|
255
414
|
consistency
|
|
256
415
|
};
|
|
@@ -286,7 +445,7 @@ function detectHookNaming(dirs, structure) {
|
|
|
286
445
|
const consistency = Math.round(dominantCount / total * 100);
|
|
287
446
|
return {
|
|
288
447
|
value: isDominantKebab ? "use-*" : "useXxx",
|
|
289
|
-
confidence:
|
|
448
|
+
confidence: confidenceFromConsistency2(consistency),
|
|
290
449
|
sampleSize: total,
|
|
291
450
|
consistency
|
|
292
451
|
};
|
|
@@ -300,7 +459,7 @@ async function detectImportAlias(projectPath) {
|
|
|
300
459
|
const aliases = Object.keys(paths);
|
|
301
460
|
if (aliases.length === 0) return void 0;
|
|
302
461
|
return {
|
|
303
|
-
value: aliases
|
|
462
|
+
value: aliases.join(","),
|
|
304
463
|
confidence: "high",
|
|
305
464
|
sampleSize: aliases.length,
|
|
306
465
|
consistency: 100
|
|
@@ -341,6 +500,8 @@ async function fileExists(filePath) {
|
|
|
341
500
|
}
|
|
342
501
|
var FRAMEWORK_MAPPINGS = [
|
|
343
502
|
{ dep: "next", name: "nextjs" },
|
|
503
|
+
{ dep: "expo", name: "expo" },
|
|
504
|
+
{ dep: "react-native", name: "react-native", excludeDep: "expo" },
|
|
344
505
|
{ dep: "@sveltejs/kit", name: "sveltekit" },
|
|
345
506
|
{ dep: "svelte", name: "svelte" },
|
|
346
507
|
{ dep: "astro", name: "astro" },
|
|
@@ -374,9 +535,10 @@ var LOCK_FILE_MAP = [
|
|
|
374
535
|
{ file: "bun.lockb", name: "bun" },
|
|
375
536
|
{ file: "package-lock.json", name: "npm" }
|
|
376
537
|
];
|
|
377
|
-
async function detectStack(projectPath) {
|
|
538
|
+
async function detectStack(projectPath, additionalDeps) {
|
|
378
539
|
const pkg = await readPackageJson(projectPath);
|
|
379
540
|
const allDeps = {
|
|
541
|
+
...additionalDeps,
|
|
380
542
|
...pkg?.dependencies,
|
|
381
543
|
...pkg?.devDependencies
|
|
382
544
|
};
|
|
@@ -386,6 +548,7 @@ async function detectStack(projectPath) {
|
|
|
386
548
|
const backend = detectFirst(allDeps, BACKEND_MAPPINGS);
|
|
387
549
|
const packageManager = await detectPackageManager(projectPath);
|
|
388
550
|
const linter = detectLinter(allDeps);
|
|
551
|
+
const formatter = detectFormatter(allDeps);
|
|
389
552
|
const testRunner = detectTestRunner(allDeps);
|
|
390
553
|
const libraries = detectLibraries(allDeps);
|
|
391
554
|
return {
|
|
@@ -395,6 +558,7 @@ async function detectStack(projectPath) {
|
|
|
395
558
|
...backend && { backend },
|
|
396
559
|
packageManager,
|
|
397
560
|
...linter && { linter },
|
|
561
|
+
...formatter && { formatter },
|
|
398
562
|
...testRunner && { testRunner },
|
|
399
563
|
libraries
|
|
400
564
|
};
|
|
@@ -453,6 +617,18 @@ function detectLinter(allDeps) {
|
|
|
453
617
|
}
|
|
454
618
|
return void 0;
|
|
455
619
|
}
|
|
620
|
+
function detectFormatter(allDeps) {
|
|
621
|
+
if ("prettier" in allDeps) {
|
|
622
|
+
return { name: "prettier", version: extractMajorVersion(allDeps.prettier) };
|
|
623
|
+
}
|
|
624
|
+
if ("@biomejs/biome" in allDeps) {
|
|
625
|
+
return {
|
|
626
|
+
name: "biome",
|
|
627
|
+
version: extractMajorVersion(allDeps["@biomejs/biome"])
|
|
628
|
+
};
|
|
629
|
+
}
|
|
630
|
+
return void 0;
|
|
631
|
+
}
|
|
456
632
|
function detectTestRunner(allDeps) {
|
|
457
633
|
if ("vitest" in allDeps) {
|
|
458
634
|
return { name: "vitest", version: extractMajorVersion(allDeps.vitest) };
|
|
@@ -477,7 +653,7 @@ function detectLibraries(allDeps) {
|
|
|
477
653
|
}
|
|
478
654
|
|
|
479
655
|
// src/detect-structure.ts
|
|
480
|
-
import { confidenceFromConsistency as
|
|
656
|
+
import { confidenceFromConsistency as confidenceFromConsistency3 } from "@viberails/types";
|
|
481
657
|
|
|
482
658
|
// src/utils/classify-directory.ts
|
|
483
659
|
var ROLE_PATTERNS = [
|
|
@@ -518,7 +694,9 @@ function classifyDirectory(dir) {
|
|
|
518
694
|
function matchByName(relativePath) {
|
|
519
695
|
for (const { role, pathPatterns } of ROLE_PATTERNS) {
|
|
520
696
|
for (const pattern of pathPatterns) {
|
|
521
|
-
if (relativePath === pattern)
|
|
697
|
+
if (relativePath === pattern || relativePath.endsWith(`/${pattern}`)) {
|
|
698
|
+
return role;
|
|
699
|
+
}
|
|
522
700
|
}
|
|
523
701
|
}
|
|
524
702
|
return null;
|
|
@@ -529,7 +707,7 @@ function inferFromContent(dir) {
|
|
|
529
707
|
const name = f.split(".")[0];
|
|
530
708
|
return name.startsWith("use-") || /^use[A-Z]/.test(name);
|
|
531
709
|
});
|
|
532
|
-
if (hookFiles.length
|
|
710
|
+
if (hookFiles.length >= 2 && hookFiles.length / sourceFileCount >= 0.5) {
|
|
533
711
|
return {
|
|
534
712
|
path: dir.relativePath,
|
|
535
713
|
role: "hooks",
|
|
@@ -538,7 +716,7 @@ function inferFromContent(dir) {
|
|
|
538
716
|
};
|
|
539
717
|
}
|
|
540
718
|
const testFiles = sourceFileNames.filter((f) => f.includes(".test.") || f.includes(".spec."));
|
|
541
|
-
if (testFiles.length
|
|
719
|
+
if (testFiles.length >= 2 && testFiles.length / sourceFileCount >= 0.5) {
|
|
542
720
|
return {
|
|
543
721
|
path: dir.relativePath,
|
|
544
722
|
role: "tests",
|
|
@@ -583,7 +761,7 @@ function detectTestPattern(dirs) {
|
|
|
583
761
|
const sep = isDotTest ? "test" : "spec";
|
|
584
762
|
return {
|
|
585
763
|
value: `*.${sep}${topExt}`,
|
|
586
|
-
confidence:
|
|
764
|
+
confidence: confidenceFromConsistency3(consistency),
|
|
587
765
|
sampleSize: testFiles.length,
|
|
588
766
|
consistency
|
|
589
767
|
};
|
|
@@ -685,18 +863,33 @@ async function resolvePackages(projectRoot, dirs) {
|
|
|
685
863
|
|
|
686
864
|
// src/scan.ts
|
|
687
865
|
import { stat } from "fs/promises";
|
|
866
|
+
import { basename, resolve as resolve2 } from "path";
|
|
867
|
+
|
|
868
|
+
// src/scan-package.ts
|
|
688
869
|
import { resolve } from "path";
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
870
|
+
async function scanPackage(packagePath, name, relativePath, rootDeps) {
|
|
871
|
+
const root = resolve(packagePath);
|
|
872
|
+
const dirs = await walkDirectory(root, 4);
|
|
873
|
+
const [stack, structure, statistics] = await Promise.all([
|
|
874
|
+
detectStack(root, rootDeps),
|
|
875
|
+
detectStructure(root, dirs),
|
|
876
|
+
computeStatistics(root, dirs)
|
|
877
|
+
]);
|
|
878
|
+
const conventions = await detectConventions(root, structure, dirs);
|
|
879
|
+
return {
|
|
880
|
+
name,
|
|
881
|
+
root,
|
|
882
|
+
relativePath,
|
|
883
|
+
stack,
|
|
884
|
+
structure,
|
|
885
|
+
conventions,
|
|
886
|
+
statistics
|
|
887
|
+
};
|
|
697
888
|
}
|
|
889
|
+
|
|
890
|
+
// src/scan.ts
|
|
698
891
|
async function scan(projectPath, _options) {
|
|
699
|
-
const root =
|
|
892
|
+
const root = resolve2(projectPath);
|
|
700
893
|
try {
|
|
701
894
|
const st = await stat(root);
|
|
702
895
|
if (!st.isDirectory()) {
|
|
@@ -708,22 +901,36 @@ async function scan(projectPath, _options) {
|
|
|
708
901
|
}
|
|
709
902
|
throw new Error(`Project path does not exist: ${root}`);
|
|
710
903
|
}
|
|
711
|
-
const allDirs = await walkDirectory(root, 4);
|
|
712
|
-
const dirs = filterFixtureDirs(allDirs);
|
|
713
|
-
const [stack, structure, statistics] = await Promise.all([
|
|
714
|
-
detectStack(root),
|
|
715
|
-
detectStructure(root, dirs),
|
|
716
|
-
computeStatistics(root, dirs)
|
|
717
|
-
]);
|
|
718
|
-
const conventions = await detectConventions(root, structure, dirs);
|
|
719
904
|
const workspace = await detectWorkspace(root);
|
|
905
|
+
if (workspace && workspace.packages.length > 0) {
|
|
906
|
+
const rootPkg2 = await readPackageJson(root);
|
|
907
|
+
const rootDeps = {
|
|
908
|
+
...rootPkg2?.dependencies,
|
|
909
|
+
...rootPkg2?.devDependencies
|
|
910
|
+
};
|
|
911
|
+
const packages = await Promise.all(
|
|
912
|
+
workspace.packages.map((wp) => scanPackage(wp.path, wp.name, wp.relativePath, rootDeps))
|
|
913
|
+
);
|
|
914
|
+
return {
|
|
915
|
+
root,
|
|
916
|
+
stack: aggregateStacks(packages),
|
|
917
|
+
structure: aggregateStructures(packages),
|
|
918
|
+
conventions: aggregateConventions(packages),
|
|
919
|
+
statistics: aggregateStatistics(packages),
|
|
920
|
+
workspace,
|
|
921
|
+
packages
|
|
922
|
+
};
|
|
923
|
+
}
|
|
924
|
+
const rootPkg = await readPackageJson(root);
|
|
925
|
+
const name = rootPkg?.name ?? basename(root);
|
|
926
|
+
const pkg = await scanPackage(root, name, "");
|
|
720
927
|
return {
|
|
721
928
|
root,
|
|
722
|
-
stack,
|
|
723
|
-
structure,
|
|
724
|
-
conventions,
|
|
725
|
-
statistics,
|
|
726
|
-
|
|
929
|
+
stack: pkg.stack,
|
|
930
|
+
structure: pkg.structure,
|
|
931
|
+
conventions: pkg.conventions,
|
|
932
|
+
statistics: pkg.statistics,
|
|
933
|
+
packages: [pkg]
|
|
727
934
|
};
|
|
728
935
|
}
|
|
729
936
|
|
|
@@ -731,6 +938,10 @@ async function scan(projectPath, _options) {
|
|
|
731
938
|
var VERSION = "0.1.0";
|
|
732
939
|
export {
|
|
733
940
|
VERSION,
|
|
941
|
+
aggregateConventions,
|
|
942
|
+
aggregateStacks,
|
|
943
|
+
aggregateStatistics,
|
|
944
|
+
aggregateStructures,
|
|
734
945
|
computeStatistics,
|
|
735
946
|
detectConventions,
|
|
736
947
|
detectStack,
|
|
@@ -739,6 +950,7 @@ export {
|
|
|
739
950
|
extractMajorVersion,
|
|
740
951
|
readPackageJson,
|
|
741
952
|
scan,
|
|
953
|
+
scanPackage,
|
|
742
954
|
walkDirectory
|
|
743
955
|
};
|
|
744
956
|
//# sourceMappingURL=index.js.map
|