@reliverse/dler 2.2.5 → 2.2.10
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 +14 -14
- package/dist/cli.js +1 -1
- package/dist/cmds/biome/cmd.js +58 -0
- package/dist/cmds/biome/impl.d.ts +26 -0
- package/dist/cmds/biome/impl.js +272 -0
- package/dist/cmds/build/cmd.js +18 -10
- package/dist/cmds/clean/cmd.js +6 -6
- package/dist/cmds/clean/impl.js +16 -12
- package/dist/cmds/clean/presets.js +2 -2
- package/dist/cmds/publish/cmd.js +7 -7
- package/dist/cmds/senv/cmd.js +13 -15
- package/dist/cmds/tsc/cache.js +1 -1
- package/dist/cmds/tsc/cmd.js +11 -8
- package/dist/cmds/tsc/impl.js +132 -17
- package/dist/cmds/update/cmd.js +11 -10
- package/dist/cmds/update/impl.d.ts +4 -4
- package/dist/cmds/update/impl.js +10 -11
- package/dist/cmds/update/utils.d.ts +23 -4
- package/dist/cmds/update/utils.js +22 -16
- package/package.json +16 -13
- package/dist/cmds/perf/analysis/bundle.d.ts +0 -20
- package/dist/cmds/perf/analysis/bundle.js +0 -225
- package/dist/cmds/perf/analysis/filesystem.d.ts +0 -27
- package/dist/cmds/perf/analysis/filesystem.js +0 -245
- package/dist/cmds/perf/analysis/monorepo.d.ts +0 -30
- package/dist/cmds/perf/analysis/monorepo.js +0 -345
- package/dist/cmds/perf/benchmarks/command.d.ts +0 -21
- package/dist/cmds/perf/benchmarks/command.js +0 -162
- package/dist/cmds/perf/benchmarks/memory.d.ts +0 -41
- package/dist/cmds/perf/benchmarks/memory.js +0 -169
- package/dist/cmds/perf/benchmarks/runner.d.ts +0 -22
- package/dist/cmds/perf/benchmarks/runner.js +0 -157
- package/dist/cmds/perf/cmd.js +0 -240
- package/dist/cmds/perf/impl.d.ts +0 -24
- package/dist/cmds/perf/impl.js +0 -297
- package/dist/cmds/perf/reporters/console.d.ts +0 -12
- package/dist/cmds/perf/reporters/console.js +0 -257
- package/dist/cmds/perf/reporters/html.d.ts +0 -27
- package/dist/cmds/perf/reporters/html.js +0 -881
- package/dist/cmds/perf/reporters/json.d.ts +0 -9
- package/dist/cmds/perf/reporters/json.js +0 -32
- package/dist/cmds/perf/types.d.ts +0 -184
- package/dist/cmds/perf/types.js +0 -0
- package/dist/cmds/perf/utils/cache.d.ts +0 -23
- package/dist/cmds/perf/utils/cache.js +0 -172
- package/dist/cmds/perf/utils/formatter.d.ts +0 -17
- package/dist/cmds/perf/utils/formatter.js +0 -134
- package/dist/cmds/perf/utils/stats.d.ts +0 -15
- package/dist/cmds/perf/utils/stats.js +0 -101
- package/dist/cmds/port/cmd.d.ts +0 -2
- package/dist/cmds/port/cmd.js +0 -58
- package/dist/cmds/port/impl.d.ts +0 -5
- package/dist/cmds/port/impl.js +0 -280
- package/dist/cmds/shell/cmd.d.ts +0 -2
- package/dist/cmds/shell/cmd.js +0 -46
- /package/dist/cmds/{perf → biome}/cmd.d.ts +0 -0
package/package.json
CHANGED
|
@@ -2,27 +2,30 @@
|
|
|
2
2
|
"name": "@reliverse/dler",
|
|
3
3
|
"description": "@reliverse/dler is a framework which helps TypeScript and JavaScript developers create their libraries and CLI tools. It provides ready-to-use primitives, so you don't have to write them from scratch.",
|
|
4
4
|
"author": "reliverse",
|
|
5
|
-
"version": "2.2.
|
|
5
|
+
"version": "2.2.10",
|
|
6
6
|
"private": false,
|
|
7
7
|
"type": "module",
|
|
8
8
|
"bin": {
|
|
9
9
|
"dler": "dist/cli.js"
|
|
10
10
|
},
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"c12": "^3.3.
|
|
12
|
+
"c12": "^3.3.3",
|
|
13
13
|
"semver": "^7.7.3",
|
|
14
14
|
"lookpath": "^1.2.3",
|
|
15
|
-
"clipboardy": "^5.0.
|
|
16
|
-
"@reliverse/
|
|
17
|
-
"@reliverse/
|
|
18
|
-
"@reliverse/
|
|
19
|
-
"@reliverse/
|
|
20
|
-
"@reliverse/
|
|
21
|
-
"@reliverse/
|
|
22
|
-
"@reliverse/
|
|
23
|
-
"@reliverse/
|
|
24
|
-
"@reliverse/
|
|
25
|
-
"@reliverse/
|
|
15
|
+
"clipboardy": "^5.0.2",
|
|
16
|
+
"@reliverse/datetime": "2.2.7",
|
|
17
|
+
"@reliverse/config": "2.2.7",
|
|
18
|
+
"@reliverse/publish": "2.2.7",
|
|
19
|
+
"@reliverse/bump": "2.2.7",
|
|
20
|
+
"@reliverse/build": "2.2.7",
|
|
21
|
+
"@reliverse/relinka": "2.2.7",
|
|
22
|
+
"@reliverse/matcha": "2.2.7",
|
|
23
|
+
"@reliverse/rempts": "2.2.7",
|
|
24
|
+
"@reliverse/helpers": "2.2.7",
|
|
25
|
+
"@reliverse/typerso": "2.2.7",
|
|
26
|
+
"@reliverse/relifso": "2.2.7",
|
|
27
|
+
"@reliverse/mapkit": "2.2.7",
|
|
28
|
+
"@reliverse/pathkit": "2.2.7"
|
|
26
29
|
},
|
|
27
30
|
"keywords": [
|
|
28
31
|
"dler",
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import type { BundleAnalysisResult } from "../types.js";
|
|
2
|
-
export interface BundleAnalysisOptions {
|
|
3
|
-
target: string;
|
|
4
|
-
verbose?: boolean;
|
|
5
|
-
includeSourceMaps?: boolean;
|
|
6
|
-
analyzeDependencies?: boolean;
|
|
7
|
-
}
|
|
8
|
-
export declare class BundleAnalyzer {
|
|
9
|
-
private options;
|
|
10
|
-
constructor(options: BundleAnalysisOptions);
|
|
11
|
-
analyze(): Promise<BundleAnalysisResult>;
|
|
12
|
-
private findBundleFiles;
|
|
13
|
-
private analyzeFile;
|
|
14
|
-
private getFileType;
|
|
15
|
-
private extractModules;
|
|
16
|
-
private findDuplicates;
|
|
17
|
-
private calculateCompressionPotential;
|
|
18
|
-
}
|
|
19
|
-
export declare const analyzeBundle: (options: BundleAnalysisOptions) => Promise<BundleAnalysisResult>;
|
|
20
|
-
export declare const createBundleAnalyzer: (options: BundleAnalysisOptions) => BundleAnalyzer;
|
|
@@ -1,225 +0,0 @@
|
|
|
1
|
-
import { existsSync, readFileSync, statSync } from "node:fs";
|
|
2
|
-
import { extname, join, resolve } from "node:path";
|
|
3
|
-
import { logger } from "@reliverse/dler-logger";
|
|
4
|
-
export class BundleAnalyzer {
|
|
5
|
-
options;
|
|
6
|
-
constructor(options) {
|
|
7
|
-
this.options = options;
|
|
8
|
-
}
|
|
9
|
-
async analyze() {
|
|
10
|
-
const startTime = Date.now();
|
|
11
|
-
const { target, verbose } = this.options;
|
|
12
|
-
if (verbose) {
|
|
13
|
-
logger.info(`\u{1F50D} Analyzing bundle: ${target}`);
|
|
14
|
-
}
|
|
15
|
-
const targetPath = resolve(target);
|
|
16
|
-
if (!existsSync(targetPath)) {
|
|
17
|
-
throw new Error(`Target not found: ${target}`);
|
|
18
|
-
}
|
|
19
|
-
const stat = statSync(targetPath);
|
|
20
|
-
let files = [];
|
|
21
|
-
if (stat.isDirectory()) {
|
|
22
|
-
files = await this.findBundleFiles(targetPath);
|
|
23
|
-
} else {
|
|
24
|
-
files = [targetPath];
|
|
25
|
-
}
|
|
26
|
-
if (files.length === 0) {
|
|
27
|
-
throw new Error(`No bundle files found in: ${target}`);
|
|
28
|
-
}
|
|
29
|
-
if (verbose) {
|
|
30
|
-
logger.info(` Found ${files.length} bundle files`);
|
|
31
|
-
}
|
|
32
|
-
const fileSizes = [];
|
|
33
|
-
const modules = [];
|
|
34
|
-
const duplicates = [];
|
|
35
|
-
for (const file of files) {
|
|
36
|
-
const fileSize = await this.analyzeFile(file);
|
|
37
|
-
fileSizes.push(fileSize);
|
|
38
|
-
if (this.options.analyzeDependencies) {
|
|
39
|
-
const fileModules = await this.extractModules(file);
|
|
40
|
-
modules.push(...fileModules);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
fileSizes.sort((a, b) => b.size - a.size);
|
|
44
|
-
if (this.options.analyzeDependencies) {
|
|
45
|
-
const duplicateMap = this.findDuplicates(modules);
|
|
46
|
-
duplicates.push(...duplicateMap);
|
|
47
|
-
}
|
|
48
|
-
const totalSize = fileSizes.reduce((sum, file) => sum + file.size, 0);
|
|
49
|
-
const fileCount = fileSizes.length;
|
|
50
|
-
const compressionPotential = this.calculateCompressionPotential(files);
|
|
51
|
-
fileSizes.forEach((file) => {
|
|
52
|
-
file.percentage = file.size / totalSize * 100;
|
|
53
|
-
});
|
|
54
|
-
const analysisTime = Date.now() - startTime;
|
|
55
|
-
if (verbose) {
|
|
56
|
-
logger.info(` Analysis completed in ${analysisTime}ms`);
|
|
57
|
-
}
|
|
58
|
-
return {
|
|
59
|
-
target,
|
|
60
|
-
totalSize,
|
|
61
|
-
fileCount,
|
|
62
|
-
largestFiles: fileSizes.slice(0, 10),
|
|
63
|
-
// Top 10
|
|
64
|
-
modules: modules.slice(0, 20),
|
|
65
|
-
// Top 20 modules
|
|
66
|
-
duplicates: duplicates.slice(0, 10),
|
|
67
|
-
// Top 10 duplicates
|
|
68
|
-
compressionPotential,
|
|
69
|
-
analysisTime
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
async findBundleFiles(dir) {
|
|
73
|
-
const bundleExtensions = [".js", ".mjs", ".cjs", ".ts", ".jsx", ".tsx"];
|
|
74
|
-
const files = [];
|
|
75
|
-
try {
|
|
76
|
-
const glob = new Bun.Glob("**/*");
|
|
77
|
-
const matches = glob.scanSync({ cwd: dir, onlyFiles: true });
|
|
78
|
-
for (const match of matches) {
|
|
79
|
-
const fullPath = join(dir, match);
|
|
80
|
-
const ext = extname(match);
|
|
81
|
-
if (bundleExtensions.includes(ext)) {
|
|
82
|
-
files.push(fullPath);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
} catch (error) {
|
|
86
|
-
logger.warn(`Error scanning directory ${dir}:`, error);
|
|
87
|
-
}
|
|
88
|
-
return files;
|
|
89
|
-
}
|
|
90
|
-
async analyzeFile(filePath) {
|
|
91
|
-
const stat = statSync(filePath);
|
|
92
|
-
const ext = extname(filePath);
|
|
93
|
-
return {
|
|
94
|
-
path: filePath,
|
|
95
|
-
size: stat.size,
|
|
96
|
-
percentage: 0,
|
|
97
|
-
// Will be calculated later
|
|
98
|
-
type: this.getFileType(ext)
|
|
99
|
-
};
|
|
100
|
-
}
|
|
101
|
-
getFileType(extension) {
|
|
102
|
-
const typeMap = {
|
|
103
|
-
".js": "JavaScript",
|
|
104
|
-
".mjs": "ES Module",
|
|
105
|
-
".cjs": "CommonJS",
|
|
106
|
-
".ts": "TypeScript",
|
|
107
|
-
".jsx": "React JSX",
|
|
108
|
-
".tsx": "React TSX",
|
|
109
|
-
".json": "JSON",
|
|
110
|
-
".css": "CSS",
|
|
111
|
-
".scss": "SCSS",
|
|
112
|
-
".sass": "Sass",
|
|
113
|
-
".less": "Less",
|
|
114
|
-
".html": "HTML",
|
|
115
|
-
".svg": "SVG",
|
|
116
|
-
".png": "PNG",
|
|
117
|
-
".jpg": "JPEG",
|
|
118
|
-
".jpeg": "JPEG",
|
|
119
|
-
".gif": "GIF",
|
|
120
|
-
".webp": "WebP",
|
|
121
|
-
".woff": "WOFF",
|
|
122
|
-
".woff2": "WOFF2",
|
|
123
|
-
".ttf": "TrueType",
|
|
124
|
-
".eot": "EOT",
|
|
125
|
-
".map": "Source Map"
|
|
126
|
-
};
|
|
127
|
-
return typeMap[extension] ?? "Unknown";
|
|
128
|
-
}
|
|
129
|
-
async extractModules(filePath) {
|
|
130
|
-
const modules = [];
|
|
131
|
-
try {
|
|
132
|
-
const content = readFileSync(filePath, "utf-8");
|
|
133
|
-
const importRegex = /import\s+.*?\s+from\s+['"]([^'"]+)['"]/g;
|
|
134
|
-
const requireRegex = /require\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
|
|
135
|
-
const dynamicImportRegex = /import\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
|
|
136
|
-
const dependencies = /* @__PURE__ */ new Set();
|
|
137
|
-
let match;
|
|
138
|
-
while ((match = importRegex.exec(content)) !== null) {
|
|
139
|
-
dependencies.add(match[1]);
|
|
140
|
-
}
|
|
141
|
-
while ((match = requireRegex.exec(content)) !== null) {
|
|
142
|
-
dependencies.add(match[1]);
|
|
143
|
-
}
|
|
144
|
-
while ((match = dynamicImportRegex.exec(content)) !== null) {
|
|
145
|
-
dependencies.add(match[1]);
|
|
146
|
-
}
|
|
147
|
-
for (const dep of dependencies) {
|
|
148
|
-
const isExternal = !dep.startsWith(".") && !dep.startsWith("/");
|
|
149
|
-
modules.push({
|
|
150
|
-
name: dep,
|
|
151
|
-
size: 0,
|
|
152
|
-
// Would need to resolve actual size
|
|
153
|
-
percentage: 0,
|
|
154
|
-
dependencies: [],
|
|
155
|
-
isExternal
|
|
156
|
-
});
|
|
157
|
-
}
|
|
158
|
-
} catch (error) {
|
|
159
|
-
logger.warn(`Error extracting modules from ${filePath}:`, error);
|
|
160
|
-
}
|
|
161
|
-
return modules;
|
|
162
|
-
}
|
|
163
|
-
findDuplicates(modules) {
|
|
164
|
-
const moduleMap = /* @__PURE__ */ new Map();
|
|
165
|
-
for (const module of modules) {
|
|
166
|
-
const key = module.name;
|
|
167
|
-
const existing = moduleMap.get(key);
|
|
168
|
-
if (existing) {
|
|
169
|
-
existing.count++;
|
|
170
|
-
existing.totalSize += module.size;
|
|
171
|
-
existing.locations.push(module.name);
|
|
172
|
-
} else {
|
|
173
|
-
moduleMap.set(key, {
|
|
174
|
-
count: 1,
|
|
175
|
-
totalSize: module.size,
|
|
176
|
-
locations: [module.name]
|
|
177
|
-
});
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
const duplicates = [];
|
|
181
|
-
for (const [name, info] of moduleMap) {
|
|
182
|
-
if (info.count > 1) {
|
|
183
|
-
duplicates.push({
|
|
184
|
-
name,
|
|
185
|
-
count: info.count,
|
|
186
|
-
totalSize: info.totalSize,
|
|
187
|
-
locations: info.locations
|
|
188
|
-
});
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
return duplicates.sort((a, b) => b.totalSize - a.totalSize);
|
|
192
|
-
}
|
|
193
|
-
calculateCompressionPotential(files) {
|
|
194
|
-
let totalSize = 0;
|
|
195
|
-
let compressibleSize = 0;
|
|
196
|
-
for (const file of files) {
|
|
197
|
-
const stat = statSync(file);
|
|
198
|
-
const ext = extname(file);
|
|
199
|
-
totalSize += stat.size;
|
|
200
|
-
const compressibleExtensions = [
|
|
201
|
-
".js",
|
|
202
|
-
".ts",
|
|
203
|
-
".jsx",
|
|
204
|
-
".tsx",
|
|
205
|
-
".json",
|
|
206
|
-
".css",
|
|
207
|
-
".html",
|
|
208
|
-
".svg"
|
|
209
|
-
];
|
|
210
|
-
if (compressibleExtensions.includes(ext)) {
|
|
211
|
-
compressibleSize += stat.size;
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
if (totalSize === 0) return 0;
|
|
215
|
-
const estimatedCompression = compressibleSize * 0.7;
|
|
216
|
-
return estimatedCompression / totalSize * 100;
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
export const analyzeBundle = async (options) => {
|
|
220
|
-
const analyzer = new BundleAnalyzer(options);
|
|
221
|
-
return analyzer.analyze();
|
|
222
|
-
};
|
|
223
|
-
export const createBundleAnalyzer = (options) => {
|
|
224
|
-
return new BundleAnalyzer(options);
|
|
225
|
-
};
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import type { FileSystemAnalysisResult } from "../types.js";
|
|
2
|
-
export interface FileSystemAnalysisOptions {
|
|
3
|
-
target: string;
|
|
4
|
-
verbose?: boolean;
|
|
5
|
-
maxDepth?: number;
|
|
6
|
-
includeHidden?: boolean;
|
|
7
|
-
excludePatterns?: string[];
|
|
8
|
-
}
|
|
9
|
-
export declare class FileSystemAnalyzer {
|
|
10
|
-
private options;
|
|
11
|
-
private fileCount;
|
|
12
|
-
private totalSize;
|
|
13
|
-
private directoryCount;
|
|
14
|
-
private maxDepth;
|
|
15
|
-
private files;
|
|
16
|
-
private directories;
|
|
17
|
-
private fileTypes;
|
|
18
|
-
constructor(options: FileSystemAnalysisOptions);
|
|
19
|
-
analyze(): Promise<FileSystemAnalysisResult>;
|
|
20
|
-
private analyzeFile;
|
|
21
|
-
private analyzeDirectory;
|
|
22
|
-
private shouldExclude;
|
|
23
|
-
private getFileType;
|
|
24
|
-
private calculateCompressionPotential;
|
|
25
|
-
}
|
|
26
|
-
export declare const analyzeFileSystem: (options: FileSystemAnalysisOptions) => Promise<FileSystemAnalysisResult>;
|
|
27
|
-
export declare const createFileSystemAnalyzer: (options: FileSystemAnalysisOptions) => FileSystemAnalyzer;
|
|
@@ -1,245 +0,0 @@
|
|
|
1
|
-
import { existsSync, statSync } from "node:fs";
|
|
2
|
-
import { extname, join, resolve } from "node:path";
|
|
3
|
-
import { logger } from "@reliverse/dler-logger";
|
|
4
|
-
import { formatBytes } from "../utils/formatter.js";
|
|
5
|
-
export class FileSystemAnalyzer {
|
|
6
|
-
options;
|
|
7
|
-
fileCount = 0;
|
|
8
|
-
totalSize = 0;
|
|
9
|
-
directoryCount = 0;
|
|
10
|
-
maxDepth = 0;
|
|
11
|
-
files = [];
|
|
12
|
-
directories = [];
|
|
13
|
-
fileTypes = /* @__PURE__ */ new Map();
|
|
14
|
-
constructor(options) {
|
|
15
|
-
this.options = options;
|
|
16
|
-
}
|
|
17
|
-
async analyze() {
|
|
18
|
-
const startTime = Date.now();
|
|
19
|
-
const { target, verbose } = this.options;
|
|
20
|
-
if (verbose) {
|
|
21
|
-
logger.info(`\u{1F50D} Analyzing filesystem: ${target}`);
|
|
22
|
-
}
|
|
23
|
-
const targetPath = resolve(target);
|
|
24
|
-
if (!existsSync(targetPath)) {
|
|
25
|
-
throw new Error(`Target not found: ${target}`);
|
|
26
|
-
}
|
|
27
|
-
const stat = statSync(targetPath);
|
|
28
|
-
if (stat.isFile()) {
|
|
29
|
-
await this.analyzeFile(targetPath, 0);
|
|
30
|
-
} else {
|
|
31
|
-
await this.analyzeDirectory(targetPath, 0);
|
|
32
|
-
}
|
|
33
|
-
this.files.sort((a, b) => b.size - a.size);
|
|
34
|
-
this.directories.sort((a, b) => b.size - a.size);
|
|
35
|
-
const fileTypeDistribution = Array.from(
|
|
36
|
-
this.fileTypes.entries()
|
|
37
|
-
).map(([extension, info]) => ({
|
|
38
|
-
extension,
|
|
39
|
-
count: info.count,
|
|
40
|
-
totalSize: info.totalSize,
|
|
41
|
-
percentage: info.totalSize / this.totalSize * 100
|
|
42
|
-
})).sort((a, b) => b.totalSize - a.totalSize);
|
|
43
|
-
const compressionPotential = this.calculateCompressionPotential();
|
|
44
|
-
const analysisTime = Date.now() - startTime;
|
|
45
|
-
if (verbose) {
|
|
46
|
-
logger.info(` Analysis completed in ${analysisTime}ms`);
|
|
47
|
-
logger.info(
|
|
48
|
-
` Files: ${this.fileCount}, Directories: ${this.directoryCount}, Size: ${formatBytes(this.totalSize)}`
|
|
49
|
-
);
|
|
50
|
-
}
|
|
51
|
-
return {
|
|
52
|
-
target,
|
|
53
|
-
totalFiles: this.fileCount,
|
|
54
|
-
totalSize: this.totalSize,
|
|
55
|
-
directoryCount: this.directoryCount,
|
|
56
|
-
maxDepth: this.maxDepth,
|
|
57
|
-
largestFiles: this.files.slice(0, 20),
|
|
58
|
-
// Top 20
|
|
59
|
-
largestDirectories: this.directories.slice(0, 20),
|
|
60
|
-
// Top 20
|
|
61
|
-
fileTypes: fileTypeDistribution,
|
|
62
|
-
compressionPotential,
|
|
63
|
-
analysisTime
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
async analyzeFile(filePath, depth) {
|
|
67
|
-
try {
|
|
68
|
-
const stat = statSync(filePath);
|
|
69
|
-
const ext = extname(filePath);
|
|
70
|
-
if (this.shouldExclude(filePath)) {
|
|
71
|
-
return;
|
|
72
|
-
}
|
|
73
|
-
this.fileCount++;
|
|
74
|
-
this.totalSize += stat.size;
|
|
75
|
-
this.maxDepth = Math.max(this.maxDepth, depth);
|
|
76
|
-
this.files.push({
|
|
77
|
-
path: filePath,
|
|
78
|
-
size: stat.size,
|
|
79
|
-
percentage: 0,
|
|
80
|
-
// Will be calculated later
|
|
81
|
-
type: this.getFileType(ext)
|
|
82
|
-
});
|
|
83
|
-
const extension = ext || "no-extension";
|
|
84
|
-
const existing = this.fileTypes.get(extension);
|
|
85
|
-
if (existing) {
|
|
86
|
-
existing.count++;
|
|
87
|
-
existing.totalSize += stat.size;
|
|
88
|
-
} else {
|
|
89
|
-
this.fileTypes.set(extension, {
|
|
90
|
-
count: 1,
|
|
91
|
-
totalSize: stat.size
|
|
92
|
-
});
|
|
93
|
-
}
|
|
94
|
-
} catch (error) {
|
|
95
|
-
if (this.options.verbose) {
|
|
96
|
-
logger.warn(`Cannot access file ${filePath}:`, error);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
async analyzeDirectory(dirPath, depth) {
|
|
101
|
-
try {
|
|
102
|
-
this.directoryCount++;
|
|
103
|
-
this.maxDepth = Math.max(this.maxDepth, depth);
|
|
104
|
-
if (this.shouldExclude(dirPath)) {
|
|
105
|
-
return;
|
|
106
|
-
}
|
|
107
|
-
let dirSize = 0;
|
|
108
|
-
let dirFileCount = 0;
|
|
109
|
-
const glob = new Bun.Glob("**/*");
|
|
110
|
-
const matches = glob.scanSync({
|
|
111
|
-
cwd: dirPath,
|
|
112
|
-
onlyFiles: false,
|
|
113
|
-
dot: this.options.includeHidden ?? false
|
|
114
|
-
});
|
|
115
|
-
for (const match of matches) {
|
|
116
|
-
const fullPath = join(dirPath, match);
|
|
117
|
-
try {
|
|
118
|
-
const stat = statSync(fullPath);
|
|
119
|
-
if (stat.isFile()) {
|
|
120
|
-
await this.analyzeFile(fullPath, depth + 1);
|
|
121
|
-
dirSize += stat.size;
|
|
122
|
-
dirFileCount++;
|
|
123
|
-
} else if (stat.isDirectory()) {
|
|
124
|
-
await this.analyzeDirectory(fullPath, depth + 1);
|
|
125
|
-
}
|
|
126
|
-
} catch (error) {
|
|
127
|
-
if (this.options.verbose) {
|
|
128
|
-
logger.warn(`Cannot access ${fullPath}:`, error);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
this.directories.push({
|
|
133
|
-
path: dirPath,
|
|
134
|
-
size: dirSize,
|
|
135
|
-
fileCount: dirFileCount,
|
|
136
|
-
depth
|
|
137
|
-
});
|
|
138
|
-
} catch (error) {
|
|
139
|
-
if (this.options.verbose) {
|
|
140
|
-
logger.warn(`Cannot access directory ${dirPath}:`, error);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
shouldExclude(path) {
|
|
145
|
-
const { excludePatterns = [] } = this.options;
|
|
146
|
-
for (const pattern of excludePatterns) {
|
|
147
|
-
if (path.includes(pattern)) {
|
|
148
|
-
return true;
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
const defaultExclusions = [
|
|
152
|
-
"node_modules",
|
|
153
|
-
".git",
|
|
154
|
-
".next",
|
|
155
|
-
".expo",
|
|
156
|
-
"dist",
|
|
157
|
-
"build",
|
|
158
|
-
"coverage",
|
|
159
|
-
".cache",
|
|
160
|
-
".turbo"
|
|
161
|
-
];
|
|
162
|
-
for (const exclusion of defaultExclusions) {
|
|
163
|
-
if (path.includes(exclusion)) {
|
|
164
|
-
return true;
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
return false;
|
|
168
|
-
}
|
|
169
|
-
getFileType(extension) {
|
|
170
|
-
const typeMap = {
|
|
171
|
-
".js": "JavaScript",
|
|
172
|
-
".mjs": "ES Module",
|
|
173
|
-
".cjs": "CommonJS",
|
|
174
|
-
".ts": "TypeScript",
|
|
175
|
-
".jsx": "React JSX",
|
|
176
|
-
".tsx": "React TSX",
|
|
177
|
-
".json": "JSON",
|
|
178
|
-
".css": "CSS",
|
|
179
|
-
".scss": "SCSS",
|
|
180
|
-
".sass": "Sass",
|
|
181
|
-
".less": "Less",
|
|
182
|
-
".html": "HTML",
|
|
183
|
-
".svg": "SVG",
|
|
184
|
-
".png": "PNG",
|
|
185
|
-
".jpg": "JPEG",
|
|
186
|
-
".jpeg": "JPEG",
|
|
187
|
-
".gif": "GIF",
|
|
188
|
-
".webp": "WebP",
|
|
189
|
-
".woff": "WOFF",
|
|
190
|
-
".woff2": "WOFF2",
|
|
191
|
-
".ttf": "TrueType",
|
|
192
|
-
".eot": "EOT",
|
|
193
|
-
".map": "Source Map",
|
|
194
|
-
".d.ts": "TypeScript Declarations",
|
|
195
|
-
".md": "Markdown",
|
|
196
|
-
".txt": "Text",
|
|
197
|
-
".yml": "YAML",
|
|
198
|
-
".yaml": "YAML",
|
|
199
|
-
".xml": "XML",
|
|
200
|
-
".pdf": "PDF",
|
|
201
|
-
".zip": "ZIP",
|
|
202
|
-
".tar": "TAR",
|
|
203
|
-
".gz": "GZIP"
|
|
204
|
-
};
|
|
205
|
-
return typeMap[extension] ?? "Unknown";
|
|
206
|
-
}
|
|
207
|
-
calculateCompressionPotential() {
|
|
208
|
-
if (this.totalSize === 0) return 0;
|
|
209
|
-
let compressibleSize = 0;
|
|
210
|
-
for (const [extension, info] of this.fileTypes) {
|
|
211
|
-
const compressibleExtensions = [
|
|
212
|
-
".js",
|
|
213
|
-
".mjs",
|
|
214
|
-
".cjs",
|
|
215
|
-
".ts",
|
|
216
|
-
".jsx",
|
|
217
|
-
".tsx",
|
|
218
|
-
".json",
|
|
219
|
-
".css",
|
|
220
|
-
".scss",
|
|
221
|
-
".sass",
|
|
222
|
-
".less",
|
|
223
|
-
".html",
|
|
224
|
-
".svg",
|
|
225
|
-
".md",
|
|
226
|
-
".txt",
|
|
227
|
-
".yml",
|
|
228
|
-
".yaml",
|
|
229
|
-
".xml"
|
|
230
|
-
];
|
|
231
|
-
if (compressibleExtensions.includes(extension)) {
|
|
232
|
-
compressibleSize += info.totalSize;
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
const estimatedCompression = compressibleSize * 0.7;
|
|
236
|
-
return estimatedCompression / this.totalSize * 100;
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
export const analyzeFileSystem = async (options) => {
|
|
240
|
-
const analyzer = new FileSystemAnalyzer(options);
|
|
241
|
-
return analyzer.analyze();
|
|
242
|
-
};
|
|
243
|
-
export const createFileSystemAnalyzer = (options) => {
|
|
244
|
-
return new FileSystemAnalyzer(options);
|
|
245
|
-
};
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import type { MonorepoAnalysisResult } from "../types.js";
|
|
2
|
-
export interface MonorepoAnalysisOptions {
|
|
3
|
-
cwd?: string;
|
|
4
|
-
ignore?: string | string[];
|
|
5
|
-
verbose?: boolean;
|
|
6
|
-
includeDevDependencies?: boolean;
|
|
7
|
-
analyzeBuildOrder?: boolean;
|
|
8
|
-
}
|
|
9
|
-
export declare class MonorepoAnalyzer {
|
|
10
|
-
private options;
|
|
11
|
-
private packages;
|
|
12
|
-
private dependencyGraph;
|
|
13
|
-
constructor(options: MonorepoAnalysisOptions);
|
|
14
|
-
analyze(): Promise<MonorepoAnalysisResult>;
|
|
15
|
-
private findMonorepoRoot;
|
|
16
|
-
private discoverPackages;
|
|
17
|
-
private discoverSinglePackage;
|
|
18
|
-
private resolvePackageInfo;
|
|
19
|
-
private buildDependencyGraph;
|
|
20
|
-
private calculateLevels;
|
|
21
|
-
private findCircularDependencies;
|
|
22
|
-
private detectCycle;
|
|
23
|
-
private calculateCycleSeverity;
|
|
24
|
-
private calculateBuildOrder;
|
|
25
|
-
private findCriticalPath;
|
|
26
|
-
private identifyBottlenecks;
|
|
27
|
-
private suggestOptimalConcurrency;
|
|
28
|
-
}
|
|
29
|
-
export declare const analyzeMonorepo: (options: MonorepoAnalysisOptions) => Promise<MonorepoAnalysisResult>;
|
|
30
|
-
export declare const createMonorepoAnalyzer: (options: MonorepoAnalysisOptions) => MonorepoAnalyzer;
|