node-modules-tools 0.0.7 → 0.0.8
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/chunks/{pnpm.mjs → index.mjs} +4 -1
- package/dist/index.d.mts +50 -30
- package/dist/index.d.ts +50 -30
- package/dist/index.mjs +194 -86
- package/package.json +2 -1
|
@@ -36,7 +36,10 @@ async function getDependenciesTree(options) {
|
|
|
36
36
|
cwd: options.cwd
|
|
37
37
|
}
|
|
38
38
|
});
|
|
39
|
-
|
|
39
|
+
const json = await import('./json-parse-stream.mjs').then((r) => r.parseJsonStream(process.process.stdout));
|
|
40
|
+
if (!Array.isArray(json))
|
|
41
|
+
throw new Error(`Failed to parse \`pnpm ls\` output, expected an array but got: ${String(json)}`);
|
|
42
|
+
return json;
|
|
40
43
|
}
|
|
41
44
|
async function listPackageDependencies(options) {
|
|
42
45
|
const root = await resolveRoot(options) || options.cwd;
|
package/dist/index.d.mts
CHANGED
|
@@ -1,35 +1,23 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
interface
|
|
1
|
+
import { AgentName } from 'package-manager-detector';
|
|
2
|
+
|
|
3
|
+
interface BaseOptions {
|
|
4
4
|
/**
|
|
5
5
|
* Current working directory
|
|
6
6
|
*/
|
|
7
7
|
cwd: string;
|
|
8
|
-
/**
|
|
9
|
-
* Depeth of the dependency tree
|
|
10
|
-
*/
|
|
11
|
-
depth: number;
|
|
12
|
-
/**
|
|
13
|
-
* Should it list dependencies of all packages in the monorepo
|
|
14
|
-
*/
|
|
15
|
-
monorepo: boolean;
|
|
16
|
-
/**
|
|
17
|
-
* Filter if a package should be included and continue traversing
|
|
18
|
-
*/
|
|
19
|
-
traverseFilter?: (node: PackageNodeRaw) => boolean;
|
|
20
8
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
packages: Map<string, PackageNodeBase>;
|
|
29
|
-
}
|
|
30
|
-
interface ListPackageDependenciesResult extends ListPackageDependenciesBaseResult {
|
|
31
|
-
packages: Map<string, PackageNode>;
|
|
9
|
+
|
|
10
|
+
interface PackageInstallSizeInfo {
|
|
11
|
+
bytes: number;
|
|
12
|
+
categories: Partial<Record<FileCategory, {
|
|
13
|
+
bytes: number;
|
|
14
|
+
count: number;
|
|
15
|
+
}>>;
|
|
32
16
|
}
|
|
17
|
+
type FileCategory = 'comp' | 'css' | 'doc' | 'dts' | 'html' | 'image' | 'js' | 'json' | 'other' | 'test' | 'ts' | 'bin' | 'map' | 'wasm' | 'flow' | 'font';
|
|
18
|
+
|
|
19
|
+
type PackageModuleTypeSimple = 'cjs' | 'esm';
|
|
20
|
+
type PackageModuleType = 'cjs' | 'esm' | 'dual' | 'faux' | 'dts';
|
|
33
21
|
interface PackageNodeRaw {
|
|
34
22
|
/** Package Name */
|
|
35
23
|
name: string;
|
|
@@ -70,17 +58,48 @@ interface PackageNode extends PackageNodeBase {
|
|
|
70
58
|
repository?: string;
|
|
71
59
|
homepage?: string;
|
|
72
60
|
engines?: Record<string, string>;
|
|
61
|
+
installSize?: PackageInstallSizeInfo;
|
|
73
62
|
};
|
|
74
63
|
}
|
|
75
64
|
|
|
76
|
-
|
|
65
|
+
interface ListPackageDependenciesOptions extends BaseOptions {
|
|
66
|
+
/**
|
|
67
|
+
* Depeth of the dependency tree
|
|
68
|
+
*/
|
|
69
|
+
depth: number;
|
|
70
|
+
/**
|
|
71
|
+
* Should it list dependencies of all packages in the monorepo
|
|
72
|
+
*/
|
|
73
|
+
monorepo: boolean;
|
|
74
|
+
/**
|
|
75
|
+
* Filter if a package should be included and continue traversing
|
|
76
|
+
*/
|
|
77
|
+
traverseFilter?: (node: PackageNodeRaw) => boolean;
|
|
78
|
+
}
|
|
79
|
+
interface ListPackageDependenciesRawResult {
|
|
80
|
+
root: string;
|
|
81
|
+
packageManager: string;
|
|
82
|
+
packageManagerVersion?: string;
|
|
83
|
+
packages: Map<string, PackageNodeRaw>;
|
|
84
|
+
}
|
|
85
|
+
interface ListPackageDependenciesBaseResult extends ListPackageDependenciesRawResult {
|
|
86
|
+
packages: Map<string, PackageNodeBase>;
|
|
87
|
+
}
|
|
88
|
+
interface ListPackageDependenciesResult extends ListPackageDependenciesBaseResult {
|
|
89
|
+
packages: Map<string, PackageNode>;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
declare function getPackageManager(options: BaseOptions): Promise<AgentName>;
|
|
77
93
|
|
|
78
94
|
/**
|
|
79
95
|
* List dependencies of packages in the current project.
|
|
80
96
|
*
|
|
81
97
|
* This function will automatically detect the package manager in the current project, and list the dependencies of the packages.
|
|
82
98
|
*/
|
|
83
|
-
declare function listPackageDependenciesRaw(options: ListPackageDependenciesOptions): Promise<ListPackageDependenciesRawResult>;
|
|
99
|
+
declare function listPackageDependenciesRaw(manager: AgentName, options: ListPackageDependenciesOptions): Promise<ListPackageDependenciesRawResult>;
|
|
100
|
+
|
|
101
|
+
declare const PackageModuleTypes: readonly PackageModuleType[];
|
|
102
|
+
|
|
84
103
|
declare function listPackageDependencies(options: ListPackageDependenciesOptions): Promise<ListPackageDependenciesResult>;
|
|
85
104
|
|
|
86
105
|
/**
|
|
@@ -89,8 +108,9 @@ declare function listPackageDependencies(options: ListPackageDependenciesOptions
|
|
|
89
108
|
*
|
|
90
109
|
* - Set `module` to the resolved module type (cjs, esm, dual, faux, none).
|
|
91
110
|
*/
|
|
92
|
-
declare function resolvePackage(pkg: PackageNodeBase): Promise<PackageNode>;
|
|
111
|
+
declare function resolvePackage(_packageManager: AgentName, pkg: PackageNodeBase, _options: BaseOptions): Promise<PackageNode>;
|
|
93
112
|
|
|
94
113
|
declare function stripBomTag(content: string): string;
|
|
114
|
+
declare function warnOnce(message: string): void;
|
|
95
115
|
|
|
96
|
-
export { type ListPackageDependenciesBaseResult, type ListPackageDependenciesOptions, type ListPackageDependenciesRawResult, type ListPackageDependenciesResult, type PackageModuleType, type PackageModuleTypeSimple, PackageModuleTypes, type PackageNode, type PackageNodeBase, type PackageNodeRaw, listPackageDependencies, listPackageDependenciesRaw, resolvePackage, stripBomTag };
|
|
116
|
+
export { type BaseOptions, type FileCategory, type ListPackageDependenciesBaseResult, type ListPackageDependenciesOptions, type ListPackageDependenciesRawResult, type ListPackageDependenciesResult, type PackageInstallSizeInfo, type PackageModuleType, type PackageModuleTypeSimple, PackageModuleTypes, type PackageNode, type PackageNodeBase, type PackageNodeRaw, getPackageManager, listPackageDependencies, listPackageDependenciesRaw, resolvePackage, stripBomTag, warnOnce };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,35 +1,23 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
interface
|
|
1
|
+
import { AgentName } from 'package-manager-detector';
|
|
2
|
+
|
|
3
|
+
interface BaseOptions {
|
|
4
4
|
/**
|
|
5
5
|
* Current working directory
|
|
6
6
|
*/
|
|
7
7
|
cwd: string;
|
|
8
|
-
/**
|
|
9
|
-
* Depeth of the dependency tree
|
|
10
|
-
*/
|
|
11
|
-
depth: number;
|
|
12
|
-
/**
|
|
13
|
-
* Should it list dependencies of all packages in the monorepo
|
|
14
|
-
*/
|
|
15
|
-
monorepo: boolean;
|
|
16
|
-
/**
|
|
17
|
-
* Filter if a package should be included and continue traversing
|
|
18
|
-
*/
|
|
19
|
-
traverseFilter?: (node: PackageNodeRaw) => boolean;
|
|
20
8
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
packages: Map<string, PackageNodeBase>;
|
|
29
|
-
}
|
|
30
|
-
interface ListPackageDependenciesResult extends ListPackageDependenciesBaseResult {
|
|
31
|
-
packages: Map<string, PackageNode>;
|
|
9
|
+
|
|
10
|
+
interface PackageInstallSizeInfo {
|
|
11
|
+
bytes: number;
|
|
12
|
+
categories: Partial<Record<FileCategory, {
|
|
13
|
+
bytes: number;
|
|
14
|
+
count: number;
|
|
15
|
+
}>>;
|
|
32
16
|
}
|
|
17
|
+
type FileCategory = 'comp' | 'css' | 'doc' | 'dts' | 'html' | 'image' | 'js' | 'json' | 'other' | 'test' | 'ts' | 'bin' | 'map' | 'wasm' | 'flow' | 'font';
|
|
18
|
+
|
|
19
|
+
type PackageModuleTypeSimple = 'cjs' | 'esm';
|
|
20
|
+
type PackageModuleType = 'cjs' | 'esm' | 'dual' | 'faux' | 'dts';
|
|
33
21
|
interface PackageNodeRaw {
|
|
34
22
|
/** Package Name */
|
|
35
23
|
name: string;
|
|
@@ -70,17 +58,48 @@ interface PackageNode extends PackageNodeBase {
|
|
|
70
58
|
repository?: string;
|
|
71
59
|
homepage?: string;
|
|
72
60
|
engines?: Record<string, string>;
|
|
61
|
+
installSize?: PackageInstallSizeInfo;
|
|
73
62
|
};
|
|
74
63
|
}
|
|
75
64
|
|
|
76
|
-
|
|
65
|
+
interface ListPackageDependenciesOptions extends BaseOptions {
|
|
66
|
+
/**
|
|
67
|
+
* Depeth of the dependency tree
|
|
68
|
+
*/
|
|
69
|
+
depth: number;
|
|
70
|
+
/**
|
|
71
|
+
* Should it list dependencies of all packages in the monorepo
|
|
72
|
+
*/
|
|
73
|
+
monorepo: boolean;
|
|
74
|
+
/**
|
|
75
|
+
* Filter if a package should be included and continue traversing
|
|
76
|
+
*/
|
|
77
|
+
traverseFilter?: (node: PackageNodeRaw) => boolean;
|
|
78
|
+
}
|
|
79
|
+
interface ListPackageDependenciesRawResult {
|
|
80
|
+
root: string;
|
|
81
|
+
packageManager: string;
|
|
82
|
+
packageManagerVersion?: string;
|
|
83
|
+
packages: Map<string, PackageNodeRaw>;
|
|
84
|
+
}
|
|
85
|
+
interface ListPackageDependenciesBaseResult extends ListPackageDependenciesRawResult {
|
|
86
|
+
packages: Map<string, PackageNodeBase>;
|
|
87
|
+
}
|
|
88
|
+
interface ListPackageDependenciesResult extends ListPackageDependenciesBaseResult {
|
|
89
|
+
packages: Map<string, PackageNode>;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
declare function getPackageManager(options: BaseOptions): Promise<AgentName>;
|
|
77
93
|
|
|
78
94
|
/**
|
|
79
95
|
* List dependencies of packages in the current project.
|
|
80
96
|
*
|
|
81
97
|
* This function will automatically detect the package manager in the current project, and list the dependencies of the packages.
|
|
82
98
|
*/
|
|
83
|
-
declare function listPackageDependenciesRaw(options: ListPackageDependenciesOptions): Promise<ListPackageDependenciesRawResult>;
|
|
99
|
+
declare function listPackageDependenciesRaw(manager: AgentName, options: ListPackageDependenciesOptions): Promise<ListPackageDependenciesRawResult>;
|
|
100
|
+
|
|
101
|
+
declare const PackageModuleTypes: readonly PackageModuleType[];
|
|
102
|
+
|
|
84
103
|
declare function listPackageDependencies(options: ListPackageDependenciesOptions): Promise<ListPackageDependenciesResult>;
|
|
85
104
|
|
|
86
105
|
/**
|
|
@@ -89,8 +108,9 @@ declare function listPackageDependencies(options: ListPackageDependenciesOptions
|
|
|
89
108
|
*
|
|
90
109
|
* - Set `module` to the resolved module type (cjs, esm, dual, faux, none).
|
|
91
110
|
*/
|
|
92
|
-
declare function resolvePackage(pkg: PackageNodeBase): Promise<PackageNode>;
|
|
111
|
+
declare function resolvePackage(_packageManager: AgentName, pkg: PackageNodeBase, _options: BaseOptions): Promise<PackageNode>;
|
|
93
112
|
|
|
94
113
|
declare function stripBomTag(content: string): string;
|
|
114
|
+
declare function warnOnce(message: string): void;
|
|
95
115
|
|
|
96
|
-
export { type ListPackageDependenciesBaseResult, type ListPackageDependenciesOptions, type ListPackageDependenciesRawResult, type ListPackageDependenciesResult, type PackageModuleType, type PackageModuleTypeSimple, PackageModuleTypes, type PackageNode, type PackageNodeBase, type PackageNodeRaw, listPackageDependencies, listPackageDependenciesRaw, resolvePackage, stripBomTag };
|
|
116
|
+
export { type BaseOptions, type FileCategory, type ListPackageDependenciesBaseResult, type ListPackageDependenciesOptions, type ListPackageDependenciesRawResult, type ListPackageDependenciesResult, type PackageInstallSizeInfo, type PackageModuleType, type PackageModuleTypeSimple, PackageModuleTypes, type PackageNode, type PackageNodeBase, type PackageNodeRaw, getPackageManager, listPackageDependencies, listPackageDependenciesRaw, resolvePackage, stripBomTag, warnOnce };
|
package/dist/index.mjs
CHANGED
|
@@ -1,10 +1,98 @@
|
|
|
1
|
+
import pLimit from 'p-limit';
|
|
1
2
|
import { detect } from 'package-manager-detector';
|
|
2
3
|
import fs from 'node:fs/promises';
|
|
3
|
-
import { join } from 'pathe';
|
|
4
|
+
import { join as join$1 } from 'pathe';
|
|
5
|
+
import { relative, join } from 'node:path';
|
|
6
|
+
|
|
7
|
+
async function getPackageManager(options) {
|
|
8
|
+
const manager = await detect({
|
|
9
|
+
cwd: options.cwd
|
|
10
|
+
});
|
|
11
|
+
if (!manager)
|
|
12
|
+
throw new Error("Cannot detect package manager in the current path");
|
|
13
|
+
return manager.name;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async function listPackageDependenciesRaw(manager, options) {
|
|
17
|
+
let result;
|
|
18
|
+
if (manager === "pnpm")
|
|
19
|
+
result = await import('./chunks/index.mjs').then((r) => r.listPackageDependencies(options));
|
|
20
|
+
else
|
|
21
|
+
throw new Error(`Package manager ${manager} is not yet supported`);
|
|
22
|
+
return populateRawResult(result);
|
|
23
|
+
}
|
|
24
|
+
function populateRawResult(input) {
|
|
25
|
+
const result = {
|
|
26
|
+
...input,
|
|
27
|
+
packages: /* @__PURE__ */ new Map()
|
|
28
|
+
};
|
|
29
|
+
for (const [spec, pkg] of input.packages) {
|
|
30
|
+
const node = Object.assign(pkg, {
|
|
31
|
+
dependents: /* @__PURE__ */ new Set(),
|
|
32
|
+
flatDependencies: /* @__PURE__ */ new Set(),
|
|
33
|
+
flatDependents: /* @__PURE__ */ new Set(),
|
|
34
|
+
depth: pkg.workspace ? 0 : Infinity
|
|
35
|
+
});
|
|
36
|
+
result.packages.set(spec, node);
|
|
37
|
+
}
|
|
38
|
+
for (const pkg of result.packages.values()) {
|
|
39
|
+
for (const dep of pkg.dependencies) {
|
|
40
|
+
result.packages.get(dep)?.dependents.add(pkg.spec);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function resloveFlatDependencies(pkg) {
|
|
44
|
+
const postTasks = [];
|
|
45
|
+
function traverseDependencies(node, seen = /* @__PURE__ */ new Set()) {
|
|
46
|
+
for (const dep of node.dependencies) {
|
|
47
|
+
const level = node.depth + 1;
|
|
48
|
+
const depNode = result.packages.get(dep);
|
|
49
|
+
if (!node.workspace) {
|
|
50
|
+
if (node.dev)
|
|
51
|
+
depNode.dev = true;
|
|
52
|
+
if (node.prod)
|
|
53
|
+
depNode.prod = true;
|
|
54
|
+
if (node.optional)
|
|
55
|
+
depNode.optional = true;
|
|
56
|
+
}
|
|
57
|
+
if (depNode.depth > level)
|
|
58
|
+
depNode.depth = level;
|
|
59
|
+
if (seen.has(depNode))
|
|
60
|
+
continue;
|
|
61
|
+
pkg.flatDependencies.add(dep);
|
|
62
|
+
seen.add(depNode);
|
|
63
|
+
postTasks.push(() => {
|
|
64
|
+
depNode.flatDependents.add(pkg.spec);
|
|
65
|
+
});
|
|
66
|
+
traverseDependencies(depNode, seen);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function traverseDependents(node) {
|
|
70
|
+
for (const dep of node.dependents) {
|
|
71
|
+
if (pkg.flatDependents.has(dep))
|
|
72
|
+
continue;
|
|
73
|
+
pkg.flatDependents.add(dep);
|
|
74
|
+
const parentNode = result.packages.get(dep);
|
|
75
|
+
postTasks.push(() => {
|
|
76
|
+
parentNode.flatDependencies.add(pkg.spec);
|
|
77
|
+
});
|
|
78
|
+
traverseDependents(parentNode);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
traverseDependencies(pkg);
|
|
82
|
+
traverseDependents(pkg);
|
|
83
|
+
for (const task of postTasks)
|
|
84
|
+
task();
|
|
85
|
+
}
|
|
86
|
+
for (const pkg of result.packages.values())
|
|
87
|
+
resloveFlatDependencies(pkg);
|
|
88
|
+
return result;
|
|
89
|
+
}
|
|
4
90
|
|
|
5
91
|
const PackageModuleTypes = Object.freeze(["cjs", "esm", "dual", "faux", "dts"]);
|
|
6
92
|
|
|
7
93
|
function analyzePackageModuleType(pkgJson) {
|
|
94
|
+
if (pkgJson.name?.startsWith("@types/"))
|
|
95
|
+
return "dts";
|
|
8
96
|
const { exports, main, type } = pkgJson;
|
|
9
97
|
let cjs;
|
|
10
98
|
let esm;
|
|
@@ -102,18 +190,114 @@ function analyzePackageModuleType(pkgJson) {
|
|
|
102
190
|
}
|
|
103
191
|
}
|
|
104
192
|
|
|
193
|
+
async function getPackageInstallSize(pkg) {
|
|
194
|
+
if (pkg.workspace)
|
|
195
|
+
return;
|
|
196
|
+
if (pkg.name.startsWith("#"))
|
|
197
|
+
return;
|
|
198
|
+
if (pkg.version.match(/^(?:file|link|workspace):/))
|
|
199
|
+
return;
|
|
200
|
+
const root = pkg.filepath;
|
|
201
|
+
const files = [];
|
|
202
|
+
async function traverse(dir) {
|
|
203
|
+
for (const n of await fs.readdir(dir, { withFileTypes: true })) {
|
|
204
|
+
if (n.isFile()) {
|
|
205
|
+
files.push(join(dir, n.name));
|
|
206
|
+
} else if (n.isDirectory()) {
|
|
207
|
+
if (n.name.match(/^\.|^node_modules$/))
|
|
208
|
+
continue;
|
|
209
|
+
await traverse(join(dir, n.name));
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
await traverse(root);
|
|
214
|
+
const types = files.map((f) => guessFileCategory(relative(root, f)));
|
|
215
|
+
const categories = {};
|
|
216
|
+
const sizes = await Promise.all(files.map(getSingleFileSize));
|
|
217
|
+
let bytes = 0;
|
|
218
|
+
for (let i = 0; i < files.length; i++) {
|
|
219
|
+
bytes += sizes[i];
|
|
220
|
+
const type = types[i];
|
|
221
|
+
if (!categories[type])
|
|
222
|
+
categories[type] = { bytes: 0, count: 0 };
|
|
223
|
+
categories[type].bytes += sizes[i];
|
|
224
|
+
categories[type].count += 1;
|
|
225
|
+
}
|
|
226
|
+
return {
|
|
227
|
+
bytes,
|
|
228
|
+
categories
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
async function getSingleFileSize(file) {
|
|
232
|
+
try {
|
|
233
|
+
const stats = await fs.stat(file);
|
|
234
|
+
return stats.size;
|
|
235
|
+
} catch {
|
|
236
|
+
return 0;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
function guessFileCategory(file) {
|
|
240
|
+
const parts = file.split(/\/|\\/g);
|
|
241
|
+
const dirs = parts.slice(0, -1);
|
|
242
|
+
const base = parts.at(-1);
|
|
243
|
+
if (dirs.some((d) => d.match(/^(?:test|tests|__tests__)$/)))
|
|
244
|
+
return "test";
|
|
245
|
+
if (dirs.some((d) => d.match(/^\.\w/)) || base.startsWith("."))
|
|
246
|
+
return "other";
|
|
247
|
+
if (dirs.some((d) => d.match(/^(?:bin|binary)$/)))
|
|
248
|
+
return "bin";
|
|
249
|
+
if (base.match(/\.(?:test|tests|spec|specs)\.\w+$/i))
|
|
250
|
+
return "test";
|
|
251
|
+
if (base.match(/\.map$/i))
|
|
252
|
+
return "map";
|
|
253
|
+
if (base.match(/\.d(\.\w+)?\.[cm]?tsx?$/i))
|
|
254
|
+
return "dts";
|
|
255
|
+
if (base.match(/\.exe$/i))
|
|
256
|
+
return "bin";
|
|
257
|
+
if (base.match(/\.(?:css|scss|sass|less)$/i))
|
|
258
|
+
return "css";
|
|
259
|
+
if (base.match(/\.(?:json[c5]?|ya?ml)$/i))
|
|
260
|
+
return "json";
|
|
261
|
+
if (base.match(/\.html?$/i))
|
|
262
|
+
return "html";
|
|
263
|
+
if (base.match(/\.[cm]?jsx?$/i))
|
|
264
|
+
return "js";
|
|
265
|
+
if (base.match(/\.[cm]?tsx?$/i))
|
|
266
|
+
return "ts";
|
|
267
|
+
if (base.match(/\.(?:vue|svelte|astro)$/i))
|
|
268
|
+
return "comp";
|
|
269
|
+
if (base.match(/\.(?:png|jpe?g|gif|svg)$/i))
|
|
270
|
+
return "image";
|
|
271
|
+
if (base.match(/\.(?:md|txt|mdx|markdown|rst)$/i))
|
|
272
|
+
return "doc";
|
|
273
|
+
if (base.match(/\.(?:wasm|wat)$/i))
|
|
274
|
+
return "wasm";
|
|
275
|
+
if (base.match(/\.flow$/i))
|
|
276
|
+
return "flow";
|
|
277
|
+
if (base.match(/\.(?:ttf|otf|woff2?)$/i))
|
|
278
|
+
return "font";
|
|
279
|
+
return "other";
|
|
280
|
+
}
|
|
281
|
+
|
|
105
282
|
function stripBomTag(content) {
|
|
106
283
|
if (content.charCodeAt(0) === 65279) {
|
|
107
284
|
return content.slice(1);
|
|
108
285
|
}
|
|
109
286
|
return content;
|
|
110
287
|
}
|
|
288
|
+
const warned = /* @__PURE__ */ new Set();
|
|
289
|
+
function warnOnce(message) {
|
|
290
|
+
if (warned.has(message))
|
|
291
|
+
return;
|
|
292
|
+
warned.add(message);
|
|
293
|
+
console.warn(message);
|
|
294
|
+
}
|
|
111
295
|
|
|
112
|
-
async function resolvePackage(pkg) {
|
|
296
|
+
async function resolvePackage(_packageManager, pkg, _options) {
|
|
113
297
|
const _pkg = pkg;
|
|
114
298
|
if (_pkg.resolved)
|
|
115
299
|
return _pkg;
|
|
116
|
-
const content = await fs.readFile(join(pkg.filepath, "package.json"), "utf-8");
|
|
300
|
+
const content = await fs.readFile(join$1(pkg.filepath, "package.json"), "utf-8");
|
|
117
301
|
const json = JSON.parse(stripBomTag(content));
|
|
118
302
|
let repository = typeof json.repository === "string" ? json.repository : json.repository?.url;
|
|
119
303
|
if (repository?.startsWith("git+"))
|
|
@@ -130,94 +314,18 @@ async function resolvePackage(pkg) {
|
|
|
130
314
|
license: json.license,
|
|
131
315
|
author: typeof json.author === "string" ? json.author : json.author?.url,
|
|
132
316
|
repository,
|
|
133
|
-
homepage: json.homepage
|
|
317
|
+
homepage: json.homepage,
|
|
318
|
+
installSize: await getPackageInstallSize(_pkg)
|
|
134
319
|
};
|
|
135
320
|
return _pkg;
|
|
136
321
|
}
|
|
137
322
|
|
|
138
|
-
async function listPackageDependenciesRaw(options) {
|
|
139
|
-
const manager = await detect({
|
|
140
|
-
cwd: options.cwd
|
|
141
|
-
});
|
|
142
|
-
if (!manager)
|
|
143
|
-
throw new Error("Cannot detect package manager in the current patch");
|
|
144
|
-
let result;
|
|
145
|
-
if (manager.name === "pnpm")
|
|
146
|
-
result = await import('./chunks/pnpm.mjs').then((r) => r.listPackageDependencies(options));
|
|
147
|
-
else
|
|
148
|
-
throw new Error(`Package manager ${manager.name} is not yet supported`);
|
|
149
|
-
return populateRawResult(result);
|
|
150
|
-
}
|
|
151
|
-
function populateRawResult(input) {
|
|
152
|
-
const result = {
|
|
153
|
-
...input,
|
|
154
|
-
packages: /* @__PURE__ */ new Map()
|
|
155
|
-
};
|
|
156
|
-
for (const [spec, pkg] of input.packages) {
|
|
157
|
-
const node = Object.assign(pkg, {
|
|
158
|
-
dependents: /* @__PURE__ */ new Set(),
|
|
159
|
-
flatDependencies: /* @__PURE__ */ new Set(),
|
|
160
|
-
flatDependents: /* @__PURE__ */ new Set(),
|
|
161
|
-
depth: pkg.workspace ? 0 : Infinity
|
|
162
|
-
});
|
|
163
|
-
result.packages.set(spec, node);
|
|
164
|
-
}
|
|
165
|
-
for (const pkg of result.packages.values()) {
|
|
166
|
-
for (const dep of pkg.dependencies) {
|
|
167
|
-
result.packages.get(dep)?.dependents.add(pkg.spec);
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
function resloveFlatDependencies(pkg) {
|
|
171
|
-
const postTasks = [];
|
|
172
|
-
function traverseDependencies(node, seen = /* @__PURE__ */ new Set()) {
|
|
173
|
-
for (const dep of node.dependencies) {
|
|
174
|
-
const level = node.depth + 1;
|
|
175
|
-
const depNode = result.packages.get(dep);
|
|
176
|
-
if (!node.workspace) {
|
|
177
|
-
if (node.dev)
|
|
178
|
-
depNode.dev = true;
|
|
179
|
-
if (node.prod)
|
|
180
|
-
depNode.prod = true;
|
|
181
|
-
if (node.optional)
|
|
182
|
-
depNode.optional = true;
|
|
183
|
-
}
|
|
184
|
-
if (depNode.depth > level)
|
|
185
|
-
depNode.depth = level;
|
|
186
|
-
if (seen.has(depNode))
|
|
187
|
-
continue;
|
|
188
|
-
pkg.flatDependencies.add(dep);
|
|
189
|
-
seen.add(depNode);
|
|
190
|
-
postTasks.push(() => {
|
|
191
|
-
depNode.flatDependents.add(pkg.spec);
|
|
192
|
-
});
|
|
193
|
-
traverseDependencies(depNode, seen);
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
function traverseDependents(node) {
|
|
197
|
-
for (const dep of node.dependents) {
|
|
198
|
-
if (pkg.flatDependents.has(dep))
|
|
199
|
-
continue;
|
|
200
|
-
pkg.flatDependents.add(dep);
|
|
201
|
-
const parentNode = result.packages.get(dep);
|
|
202
|
-
postTasks.push(() => {
|
|
203
|
-
parentNode.flatDependencies.add(pkg.spec);
|
|
204
|
-
});
|
|
205
|
-
traverseDependents(parentNode);
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
traverseDependencies(pkg);
|
|
209
|
-
traverseDependents(pkg);
|
|
210
|
-
for (const task of postTasks)
|
|
211
|
-
task();
|
|
212
|
-
}
|
|
213
|
-
for (const pkg of result.packages.values())
|
|
214
|
-
resloveFlatDependencies(pkg);
|
|
215
|
-
return result;
|
|
216
|
-
}
|
|
217
323
|
async function listPackageDependencies(options) {
|
|
218
|
-
const
|
|
219
|
-
|
|
324
|
+
const packageManager = await getPackageManager(options);
|
|
325
|
+
const result = await listPackageDependenciesRaw(packageManager, options);
|
|
326
|
+
const limit = pLimit(10);
|
|
327
|
+
await Promise.all(Array.from(result.packages.values()).map((pkg) => limit(() => resolvePackage(packageManager, pkg))));
|
|
220
328
|
return result;
|
|
221
329
|
}
|
|
222
330
|
|
|
223
|
-
export { PackageModuleTypes, listPackageDependencies, listPackageDependenciesRaw, resolvePackage, stripBomTag };
|
|
331
|
+
export { PackageModuleTypes, getPackageManager, listPackageDependencies, listPackageDependenciesRaw, resolvePackage, stripBomTag, warnOnce };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-modules-tools",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.8",
|
|
5
5
|
"description": "Tools for inspecting node_modules",
|
|
6
6
|
"author": "Anthony Fu <anthonyfu117@hotmail.com>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
"dist"
|
|
34
34
|
],
|
|
35
35
|
"dependencies": {
|
|
36
|
+
"p-limit": "^6.2.0",
|
|
36
37
|
"package-manager-detector": "^0.2.9",
|
|
37
38
|
"pathe": "^2.0.2",
|
|
38
39
|
"tinyexec": "^0.3.2"
|