node-modules-tools 0.0.0
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/LICENSE.md +21 -0
- package/README.md +32 -0
- package/dist/chunks/pnpm.mjs +81 -0
- package/dist/index.d.mts +69 -0
- package/dist/index.d.ts +69 -0
- package/dist/index.mjs +125 -0
- package/package.json +51 -0
package/LICENSE.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Anthony Fu <https://github.com/antfu>
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# node-modules-tools
|
|
2
|
+
|
|
3
|
+
[![npm version][npm-version-src]][npm-version-href]
|
|
4
|
+
[![npm downloads][npm-downloads-src]][npm-downloads-href]
|
|
5
|
+
[![bundle][bundle-src]][bundle-href]
|
|
6
|
+
[![JSDocs][jsdocs-src]][jsdocs-href]
|
|
7
|
+
[![License][license-src]][license-href]
|
|
8
|
+
|
|
9
|
+
## Sponsors
|
|
10
|
+
|
|
11
|
+
<p align="center">
|
|
12
|
+
<a href="https://cdn.jsdelivr.net/gh/antfu/static/sponsors.svg">
|
|
13
|
+
<img src='https://cdn.jsdelivr.net/gh/antfu/static/sponsors.svg'/>
|
|
14
|
+
</a>
|
|
15
|
+
</p>
|
|
16
|
+
|
|
17
|
+
## License
|
|
18
|
+
|
|
19
|
+
[MIT](./LICENSE) License © [Anthony Fu](https://github.com/antfu)
|
|
20
|
+
|
|
21
|
+
<!-- Badges -->
|
|
22
|
+
|
|
23
|
+
[npm-version-src]: https://img.shields.io/npm/v/node-modules-tools?style=flat&colorA=080f12&colorB=1fa669
|
|
24
|
+
[npm-version-href]: https://npmjs.com/package/node-modules-tools
|
|
25
|
+
[npm-downloads-src]: https://img.shields.io/npm/dm/node-modules-tools?style=flat&colorA=080f12&colorB=1fa669
|
|
26
|
+
[npm-downloads-href]: https://npmjs.com/package/node-modules-tools
|
|
27
|
+
[bundle-src]: https://img.shields.io/bundlephobia/minzip/node-modules-tools?style=flat&colorA=080f12&colorB=1fa669&label=minzip
|
|
28
|
+
[bundle-href]: https://bundlephobia.com/result?p=node-modules-tools
|
|
29
|
+
[license-src]: https://img.shields.io/github/license/antfu/node-modules-tools.svg?style=flat&colorA=080f12&colorB=1fa669
|
|
30
|
+
[license-href]: https://github.com/antfu/node-modules-tools/blob/main/LICENSE
|
|
31
|
+
[jsdocs-src]: https://img.shields.io/badge/jsdocs-reference-080f12?style=flat&colorA=080f12&colorB=1fa669
|
|
32
|
+
[jsdocs-href]: https://www.jsdocs.io/package/node-modules-tools
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { x } from 'tinyexec';
|
|
2
|
+
|
|
3
|
+
async function getDependenciesTree(options) {
|
|
4
|
+
const args = ["ls", "--json", "--no-optional", "--depth", String(options.depth)];
|
|
5
|
+
if (options.monorepo)
|
|
6
|
+
args.push("--recursive");
|
|
7
|
+
const raw = await x("pnpm", args, { throwOnError: true, nodeOptions: { cwd: options.cwd } });
|
|
8
|
+
const tree = JSON.parse(raw.stdout);
|
|
9
|
+
return tree;
|
|
10
|
+
}
|
|
11
|
+
async function listPackageDependencies(options) {
|
|
12
|
+
const tree = await getDependenciesTree(options);
|
|
13
|
+
const specs = /* @__PURE__ */ new Map();
|
|
14
|
+
const map = /* @__PURE__ */ new WeakMap();
|
|
15
|
+
function normalize(raw) {
|
|
16
|
+
let node = map.get(raw);
|
|
17
|
+
if (node)
|
|
18
|
+
return node;
|
|
19
|
+
node = {
|
|
20
|
+
spec: `${raw.from}@${raw.version}`,
|
|
21
|
+
name: raw.from,
|
|
22
|
+
version: raw.version,
|
|
23
|
+
path: raw.path,
|
|
24
|
+
dependencies: /* @__PURE__ */ new Set(),
|
|
25
|
+
dependents: /* @__PURE__ */ new Set(),
|
|
26
|
+
flatDependents: /* @__PURE__ */ new Set(),
|
|
27
|
+
flatDependencies: /* @__PURE__ */ new Set(),
|
|
28
|
+
nestedLevels: /* @__PURE__ */ new Set(),
|
|
29
|
+
dev: false,
|
|
30
|
+
prod: false,
|
|
31
|
+
optional: false
|
|
32
|
+
};
|
|
33
|
+
map.set(raw, node);
|
|
34
|
+
return node;
|
|
35
|
+
}
|
|
36
|
+
function traverse(_node, level, mode, directImporter, nestedImporter) {
|
|
37
|
+
if (_node.from.startsWith("@types"))
|
|
38
|
+
return;
|
|
39
|
+
const node = normalize(_node);
|
|
40
|
+
if (directImporter)
|
|
41
|
+
node.dependents.add(directImporter);
|
|
42
|
+
for (const im of nestedImporter)
|
|
43
|
+
node.flatDependents.add(im);
|
|
44
|
+
node.nestedLevels.add(level);
|
|
45
|
+
if (mode === "dev")
|
|
46
|
+
node.dev = true;
|
|
47
|
+
if (mode === "prod")
|
|
48
|
+
node.prod = true;
|
|
49
|
+
if (mode === "optional")
|
|
50
|
+
node.optional = true;
|
|
51
|
+
if (options.traverseFilter?.(node) === false)
|
|
52
|
+
return;
|
|
53
|
+
if (specs.has(node.spec))
|
|
54
|
+
return;
|
|
55
|
+
specs.set(node.spec, node);
|
|
56
|
+
for (const dep of Object.values(_node.dependencies || {})) {
|
|
57
|
+
traverse(dep, level + 1, mode, node.spec, [...nestedImporter, node.spec]);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
for (const pkg of tree) {
|
|
61
|
+
for (const dep of Object.values(pkg.dependencies || {})) {
|
|
62
|
+
traverse(dep, 1, "prod", undefined, []);
|
|
63
|
+
}
|
|
64
|
+
for (const dep of Object.values(pkg.devDependencies || {})) {
|
|
65
|
+
traverse(dep, 1, "dev", undefined, []);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
const packages = [...specs.values()].sort((a, b) => a.spec.localeCompare(b.spec));
|
|
69
|
+
for (const pkg of packages) {
|
|
70
|
+
for (const dep of pkg.flatDependents) {
|
|
71
|
+
const node = specs.get(dep);
|
|
72
|
+
if (node)
|
|
73
|
+
node.flatDependencies.add(pkg.spec);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return {
|
|
77
|
+
packages
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export { listPackageDependencies };
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
type PackageModuleTypeSimple = 'cjs' | 'esm';
|
|
2
|
+
type PackageModuleType = 'cjs' | 'esm' | 'dual' | 'faux';
|
|
3
|
+
interface ListPackageDependenciesOptions {
|
|
4
|
+
/**
|
|
5
|
+
* Current working directory
|
|
6
|
+
*/
|
|
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: PackageNode) => boolean;
|
|
20
|
+
}
|
|
21
|
+
interface ListPackageDependenciesResult {
|
|
22
|
+
packages: PackageNode[];
|
|
23
|
+
}
|
|
24
|
+
interface PackageNode {
|
|
25
|
+
/** Package Name */
|
|
26
|
+
name: string;
|
|
27
|
+
/** Version */
|
|
28
|
+
version: string;
|
|
29
|
+
/** Combined name and version using `@` */
|
|
30
|
+
spec: string;
|
|
31
|
+
/** Absolute file path of the package */
|
|
32
|
+
path: string;
|
|
33
|
+
/** Direct dependencies of this package */
|
|
34
|
+
dependencies: Set<string>;
|
|
35
|
+
/** Direct dependents of this package */
|
|
36
|
+
dependents: Set<string>;
|
|
37
|
+
/** All nested dependencies of this package */
|
|
38
|
+
flatDependencies: Set<string>;
|
|
39
|
+
/** All nested dependents of this package */
|
|
40
|
+
flatDependents: Set<string>;
|
|
41
|
+
/** Nested levels of this package */
|
|
42
|
+
nestedLevels: Set<number>;
|
|
43
|
+
/** Is this package part of devDependencies */
|
|
44
|
+
dev: boolean;
|
|
45
|
+
/** Is this package part of dependencies */
|
|
46
|
+
prod: boolean;
|
|
47
|
+
/** Is this package part of optionalDependencies */
|
|
48
|
+
optional: boolean;
|
|
49
|
+
}
|
|
50
|
+
interface ResolvedPackageNode extends PackageNode {
|
|
51
|
+
module: PackageModuleType;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Analyze a package node, and return a resolved package node.
|
|
56
|
+
* This function mutates the input package node.
|
|
57
|
+
*
|
|
58
|
+
* - Set `module` to the resolved module type (cjs, esm, dual, faux).
|
|
59
|
+
*/
|
|
60
|
+
declare function analyzePackage(pkg: PackageNode): Promise<ResolvedPackageNode>;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* List dependencies of packages in the current project.
|
|
64
|
+
*
|
|
65
|
+
* This function will automatically detect the package manager in the current project, and list the dependencies of the packages.
|
|
66
|
+
*/
|
|
67
|
+
declare function listPackageDependencies(options: ListPackageDependenciesOptions): Promise<ListPackageDependenciesResult>;
|
|
68
|
+
|
|
69
|
+
export { type ListPackageDependenciesOptions, type ListPackageDependenciesResult, type PackageModuleType, type PackageModuleTypeSimple, type PackageNode, type ResolvedPackageNode, analyzePackage, listPackageDependencies };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
type PackageModuleTypeSimple = 'cjs' | 'esm';
|
|
2
|
+
type PackageModuleType = 'cjs' | 'esm' | 'dual' | 'faux';
|
|
3
|
+
interface ListPackageDependenciesOptions {
|
|
4
|
+
/**
|
|
5
|
+
* Current working directory
|
|
6
|
+
*/
|
|
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: PackageNode) => boolean;
|
|
20
|
+
}
|
|
21
|
+
interface ListPackageDependenciesResult {
|
|
22
|
+
packages: PackageNode[];
|
|
23
|
+
}
|
|
24
|
+
interface PackageNode {
|
|
25
|
+
/** Package Name */
|
|
26
|
+
name: string;
|
|
27
|
+
/** Version */
|
|
28
|
+
version: string;
|
|
29
|
+
/** Combined name and version using `@` */
|
|
30
|
+
spec: string;
|
|
31
|
+
/** Absolute file path of the package */
|
|
32
|
+
path: string;
|
|
33
|
+
/** Direct dependencies of this package */
|
|
34
|
+
dependencies: Set<string>;
|
|
35
|
+
/** Direct dependents of this package */
|
|
36
|
+
dependents: Set<string>;
|
|
37
|
+
/** All nested dependencies of this package */
|
|
38
|
+
flatDependencies: Set<string>;
|
|
39
|
+
/** All nested dependents of this package */
|
|
40
|
+
flatDependents: Set<string>;
|
|
41
|
+
/** Nested levels of this package */
|
|
42
|
+
nestedLevels: Set<number>;
|
|
43
|
+
/** Is this package part of devDependencies */
|
|
44
|
+
dev: boolean;
|
|
45
|
+
/** Is this package part of dependencies */
|
|
46
|
+
prod: boolean;
|
|
47
|
+
/** Is this package part of optionalDependencies */
|
|
48
|
+
optional: boolean;
|
|
49
|
+
}
|
|
50
|
+
interface ResolvedPackageNode extends PackageNode {
|
|
51
|
+
module: PackageModuleType;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Analyze a package node, and return a resolved package node.
|
|
56
|
+
* This function mutates the input package node.
|
|
57
|
+
*
|
|
58
|
+
* - Set `module` to the resolved module type (cjs, esm, dual, faux).
|
|
59
|
+
*/
|
|
60
|
+
declare function analyzePackage(pkg: PackageNode): Promise<ResolvedPackageNode>;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* List dependencies of packages in the current project.
|
|
64
|
+
*
|
|
65
|
+
* This function will automatically detect the package manager in the current project, and list the dependencies of the packages.
|
|
66
|
+
*/
|
|
67
|
+
declare function listPackageDependencies(options: ListPackageDependenciesOptions): Promise<ListPackageDependenciesResult>;
|
|
68
|
+
|
|
69
|
+
export { type ListPackageDependenciesOptions, type ListPackageDependenciesResult, type PackageModuleType, type PackageModuleTypeSimple, type PackageNode, type ResolvedPackageNode, analyzePackage, listPackageDependencies };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { detect } from 'package-manager-detector';
|
|
4
|
+
|
|
5
|
+
function analyzePackageJson(pkgJson) {
|
|
6
|
+
const { exports, main, type } = pkgJson;
|
|
7
|
+
let cjs;
|
|
8
|
+
let esm;
|
|
9
|
+
let fauxEsm;
|
|
10
|
+
if (pkgJson.module) {
|
|
11
|
+
fauxEsm = true;
|
|
12
|
+
}
|
|
13
|
+
if (exports && typeof exports === "object") {
|
|
14
|
+
for (const exportId in exports) {
|
|
15
|
+
if (Object.hasOwn(exports, exportId) && typeof exportId === "string") {
|
|
16
|
+
const value = (
|
|
17
|
+
/** @type {unknown} */
|
|
18
|
+
exports[exportId]
|
|
19
|
+
);
|
|
20
|
+
analyzeThing(value, `${pkgJson.name}#exports`);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
if (esm && type === "commonjs") {
|
|
25
|
+
cjs = true;
|
|
26
|
+
}
|
|
27
|
+
if (cjs && type === "module") {
|
|
28
|
+
esm = true;
|
|
29
|
+
}
|
|
30
|
+
if (cjs === undefined && esm === undefined) {
|
|
31
|
+
if (type === "module" || main && /\.mjs$/.test(main)) {
|
|
32
|
+
esm = true;
|
|
33
|
+
} else {
|
|
34
|
+
cjs = true;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
const style = esm && cjs ? "dual" : esm ? "esm" : fauxEsm ? "faux" : "cjs";
|
|
38
|
+
return style;
|
|
39
|
+
function analyzeThing(value, path) {
|
|
40
|
+
if (value && typeof value === "object") {
|
|
41
|
+
if (Array.isArray(value)) {
|
|
42
|
+
const values = (
|
|
43
|
+
/** @type {Array<unknown>} */
|
|
44
|
+
value
|
|
45
|
+
);
|
|
46
|
+
let index = -1;
|
|
47
|
+
while (++index < values.length) {
|
|
48
|
+
analyzeThing(values[index], `${path}[${index}]`);
|
|
49
|
+
}
|
|
50
|
+
} else {
|
|
51
|
+
const record = (
|
|
52
|
+
/** @type {Record<string, unknown>} */
|
|
53
|
+
value
|
|
54
|
+
);
|
|
55
|
+
let dots = false;
|
|
56
|
+
for (const [key, subvalue] of Object.entries(record)) {
|
|
57
|
+
if (key.charAt(0) !== ".")
|
|
58
|
+
break;
|
|
59
|
+
analyzeThing(subvalue, `${path}["${key}"]`);
|
|
60
|
+
dots = true;
|
|
61
|
+
}
|
|
62
|
+
if (dots)
|
|
63
|
+
return;
|
|
64
|
+
let explicit = false;
|
|
65
|
+
const conditionImport = Boolean("import" in record && record.import);
|
|
66
|
+
const conditionRequire = Boolean("require" in record && record.require);
|
|
67
|
+
const conditionDefault = Boolean("default" in record && record.default);
|
|
68
|
+
if (conditionImport || conditionRequire) {
|
|
69
|
+
explicit = true;
|
|
70
|
+
}
|
|
71
|
+
if (conditionImport || conditionRequire && conditionDefault) {
|
|
72
|
+
esm = true;
|
|
73
|
+
}
|
|
74
|
+
if (conditionRequire || conditionImport && conditionDefault) {
|
|
75
|
+
cjs = true;
|
|
76
|
+
}
|
|
77
|
+
const defaults = record.node || record.default;
|
|
78
|
+
if (typeof defaults === "string" && !explicit) {
|
|
79
|
+
if (/\.mjs$/.test(defaults))
|
|
80
|
+
esm = true;
|
|
81
|
+
if (/\.cjs$/.test(defaults))
|
|
82
|
+
cjs = true;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
} else if (typeof value === "string") {
|
|
86
|
+
if (/\.mjs$/.test(value))
|
|
87
|
+
esm = true;
|
|
88
|
+
if (/\.cjs$/.test(value))
|
|
89
|
+
cjs = true;
|
|
90
|
+
} else if (value === null) ; else {
|
|
91
|
+
console.error("unknown:", [value], path);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function stripBomTag(content) {
|
|
97
|
+
if (content.charCodeAt(0) === 65279) {
|
|
98
|
+
return content.slice(1);
|
|
99
|
+
}
|
|
100
|
+
return content;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
async function analyzePackage(pkg) {
|
|
104
|
+
const _pkg = pkg;
|
|
105
|
+
if (_pkg.module)
|
|
106
|
+
return _pkg;
|
|
107
|
+
const content = await fs.readFile(join(pkg.path, "package.json"), "utf-8");
|
|
108
|
+
const json = JSON.parse(stripBomTag(content));
|
|
109
|
+
_pkg.module = analyzePackageJson(json);
|
|
110
|
+
return _pkg;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
async function listPackageDependencies(options) {
|
|
114
|
+
const manager = await detect({
|
|
115
|
+
cwd: options.cwd
|
|
116
|
+
});
|
|
117
|
+
if (!manager)
|
|
118
|
+
throw new Error("Cannot detect package manager in the current patch");
|
|
119
|
+
if (manager.name === "pnpm")
|
|
120
|
+
return await import('./chunks/pnpm.mjs').then((r) => r.listPackageDependencies(options));
|
|
121
|
+
else
|
|
122
|
+
throw new Error(`Package manager ${manager.name} is not yet supported`);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export { analyzePackage, listPackageDependencies };
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "node-modules-tools",
|
|
3
|
+
"type": "module",
|
|
4
|
+
"version": "0.0.0",
|
|
5
|
+
"description": "Tools for inspecting node_modules",
|
|
6
|
+
"author": "Anthony Fu <anthonyfu117@hotmail.com>",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"funding": "https://github.com/sponsors/antfu",
|
|
9
|
+
"homepage": "https://github.com/antfu/node-modules-inspector#readme",
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "git+https://github.com/antfu/node-modules-inspector.git",
|
|
13
|
+
"directory": "packages/node-modules-tools"
|
|
14
|
+
},
|
|
15
|
+
"bugs": "https://github.com/antfu/node-modules-inspector/issues",
|
|
16
|
+
"keywords": [],
|
|
17
|
+
"sideEffects": false,
|
|
18
|
+
"exports": {
|
|
19
|
+
".": "./dist/index.mjs"
|
|
20
|
+
},
|
|
21
|
+
"main": "./dist/index.mjs",
|
|
22
|
+
"module": "./dist/index.mjs",
|
|
23
|
+
"types": "./dist/index.d.mts",
|
|
24
|
+
"typesVersions": {
|
|
25
|
+
"*": {
|
|
26
|
+
"*": [
|
|
27
|
+
"./dist/*",
|
|
28
|
+
"./dist/index.d.ts"
|
|
29
|
+
]
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"files": [
|
|
33
|
+
"dist"
|
|
34
|
+
],
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"package-manager-detector": "^0.2.8",
|
|
37
|
+
"tinyexec": "^0.3.2"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@pnpm/list": "^1000.0.5",
|
|
41
|
+
"@pnpm/types": "^1000.1.0",
|
|
42
|
+
"pkg-types": "^1.3.1",
|
|
43
|
+
"unbuild": "^3.3.1"
|
|
44
|
+
},
|
|
45
|
+
"scripts": {
|
|
46
|
+
"build": "unbuild",
|
|
47
|
+
"dev": "unbuild --stub",
|
|
48
|
+
"start": "tsx src/index.ts",
|
|
49
|
+
"test": "vitest"
|
|
50
|
+
}
|
|
51
|
+
}
|