node-modules-tools 0.4.3 → 0.5.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.
@@ -1,3 +1,3 @@
1
- export { d as CLUSTER_DEP_DEV, e as CLUSTER_DEP_OPTIONAL, C as CLUSTER_DEP_PROD, c as PackageModuleTypes } from './shared/node-modules-tools.CX5_YEVA.mjs';
1
+ export { d as CLUSTER_DEP_DEV, e as CLUSTER_DEP_OPTIONAL, C as CLUSTER_DEP_PROD, c as PackageModuleTypes } from './shared/node-modules-tools.Bnm4jx4C.mjs';
2
2
  import 'pkg-types';
3
3
  import 'publint';
@@ -1,3 +1,3 @@
1
- export { d as CLUSTER_DEP_DEV, e as CLUSTER_DEP_OPTIONAL, C as CLUSTER_DEP_PROD, c as PackageModuleTypes } from './shared/node-modules-tools.CX5_YEVA.js';
1
+ export { d as CLUSTER_DEP_DEV, e as CLUSTER_DEP_OPTIONAL, C as CLUSTER_DEP_PROD, c as PackageModuleTypes } from './shared/node-modules-tools.Bnm4jx4C.js';
2
2
  import 'pkg-types';
3
3
  import 'publint';
package/dist/index.d.mts CHANGED
@@ -1,9 +1,9 @@
1
1
  import { AgentName } from 'package-manager-detector';
2
- import { P as PackageNodeRaw, a as PackageNodeBase, b as PackageNode } from './shared/node-modules-tools.CX5_YEVA.mjs';
3
- export { d as CLUSTER_DEP_DEV, e as CLUSTER_DEP_OPTIONAL, C as CLUSTER_DEP_PROD, F as FileCategory, N as NpmMeta, h as NpmMetaLatest, i as PackageInstallSizeInfo, g as PackageModuleType, f as PackageModuleTypeSimple, c as PackageModuleTypes } from './shared/node-modules-tools.CX5_YEVA.mjs';
2
+ import { P as PackageNodeRaw, a as PackageNodeBase, b as PackageNode } from './shared/node-modules-tools.Bnm4jx4C.mjs';
3
+ export { d as CLUSTER_DEP_DEV, e as CLUSTER_DEP_OPTIONAL, C as CLUSTER_DEP_PROD, F as FileCategory, N as NpmMeta, h as NpmMetaLatest, i as PackageInstallSizeInfo, g as PackageModuleType, f as PackageModuleTypeSimple, c as PackageModuleTypes } from './shared/node-modules-tools.Bnm4jx4C.mjs';
4
+ export { PackageJson } from 'pkg-types';
4
5
  export { Message as PublintMessage } from 'publint';
5
- export { PackageNodeLike, constructPackageFilter, constructPackageFilters } from './utils.mjs';
6
- import 'pkg-types';
6
+ export { NormalizedFunding, PackageNodeLike, ParsedFunding, constructPackageFilter, constructPackageFilters, normalizePkgAuthor, normalizePkgFundings, normalizePkgRepository, parseAuthor, parseFunding } from './utils.mjs';
7
7
 
8
8
  interface BaseOptions {
9
9
  /**
package/dist/index.d.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import { AgentName } from 'package-manager-detector';
2
- import { P as PackageNodeRaw, a as PackageNodeBase, b as PackageNode } from './shared/node-modules-tools.CX5_YEVA.js';
3
- export { d as CLUSTER_DEP_DEV, e as CLUSTER_DEP_OPTIONAL, C as CLUSTER_DEP_PROD, F as FileCategory, N as NpmMeta, h as NpmMetaLatest, i as PackageInstallSizeInfo, g as PackageModuleType, f as PackageModuleTypeSimple, c as PackageModuleTypes } from './shared/node-modules-tools.CX5_YEVA.js';
2
+ import { P as PackageNodeRaw, a as PackageNodeBase, b as PackageNode } from './shared/node-modules-tools.Bnm4jx4C.js';
3
+ export { d as CLUSTER_DEP_DEV, e as CLUSTER_DEP_OPTIONAL, C as CLUSTER_DEP_PROD, F as FileCategory, N as NpmMeta, h as NpmMetaLatest, i as PackageInstallSizeInfo, g as PackageModuleType, f as PackageModuleTypeSimple, c as PackageModuleTypes } from './shared/node-modules-tools.Bnm4jx4C.js';
4
+ export { PackageJson } from 'pkg-types';
4
5
  export { Message as PublintMessage } from 'publint';
5
- export { PackageNodeLike, constructPackageFilter, constructPackageFilters } from './utils.js';
6
- import 'pkg-types';
6
+ export { NormalizedFunding, PackageNodeLike, ParsedFunding, constructPackageFilter, constructPackageFilters, normalizePkgAuthor, normalizePkgFundings, normalizePkgRepository, parseAuthor, parseFunding } from './utils.js';
7
7
 
8
8
  interface BaseOptions {
9
9
  /**
package/dist/index.mjs CHANGED
@@ -4,7 +4,7 @@ import { detect } from 'package-manager-detector';
4
4
  import fs from 'node:fs/promises';
5
5
  import { join as join$1 } from 'pathe';
6
6
  import { relative, join } from 'node:path';
7
- export { c as constructPackageFilter, a as constructPackageFilters } from './shared/node-modules-tools.DT_mm7wI.mjs';
7
+ export { c as constructPackageFilter, a as constructPackageFilters, d as normalizePkgAuthor, n as normalizePkgFundings, e as normalizePkgRepository, b as parseAuthor, p as parseFunding } from './shared/node-modules-tools.D5TyCC_Y.mjs';
8
8
  import 'semver';
9
9
 
10
10
  async function getPackageManager(options) {
@@ -96,6 +96,16 @@ function populateRawResult(input) {
96
96
  return result;
97
97
  }
98
98
 
99
+ function objectPick(obj, keys, omitUndefined = false) {
100
+ return keys.reduce((n, k) => {
101
+ if (k in obj) {
102
+ if (!omitUndefined || obj[k] !== void 0)
103
+ n[k] = obj[k];
104
+ }
105
+ return n;
106
+ }, {});
107
+ }
108
+
99
109
  function analyzePackageModuleType(pkgJson) {
100
110
  if (pkgJson.name?.startsWith("@types/"))
101
111
  return "dts";
@@ -285,39 +295,37 @@ function guessFileCategory(file) {
285
295
  return "other";
286
296
  }
287
297
 
298
+ const PACKAGE_JSON_KEYS = [
299
+ "author",
300
+ "bin",
301
+ "bugs",
302
+ "dependencies",
303
+ "description",
304
+ "devDependencies",
305
+ "engines",
306
+ "exports",
307
+ "funding",
308
+ "homepage",
309
+ "imports",
310
+ "keywords",
311
+ "license",
312
+ "main",
313
+ "module",
314
+ "name",
315
+ "optionalDependencies",
316
+ "repository",
317
+ "types",
318
+ "version"
319
+ ];
288
320
  async function resolvePackage(_packageManager, pkg, _options) {
289
321
  const _pkg = pkg;
290
322
  if (_pkg.resolved)
291
323
  return _pkg;
292
324
  const content = await fs.readFile(join$1(pkg.filepath, "package.json"), "utf-8");
293
325
  const json = JSON.parse(stripBomTag(content));
294
- let repository = typeof json.repository === "string" ? json.repository : json.repository?.url;
295
- if (repository?.startsWith("git+"))
296
- repository = repository.slice(4);
297
- if (repository?.endsWith(".git"))
298
- repository = repository.slice(0, -4);
299
- if (repository?.startsWith("git://"))
300
- repository = `https://${repository.slice(6)}`;
301
- if (json.repository && typeof json.repository !== "string" && json.repository.directory)
302
- repository += `/tree/HEAD/${json.repository.directory}`;
303
- const rawFunding = json.funding;
304
- let fundings;
305
- if (typeof rawFunding === "string") {
306
- fundings = [{ url: rawFunding }];
307
- } else if (Array.isArray(rawFunding)) {
308
- fundings = rawFunding.map((f) => typeof f === "string" ? { url: f } : f);
309
- } else {
310
- fundings = rawFunding ? [rawFunding] : [];
311
- }
312
326
  _pkg.resolved = {
313
327
  module: analyzePackageModuleType(json),
314
- engines: json.engines,
315
- license: json.license,
316
- author: typeof json.author === "string" ? json.author : json.author?.url,
317
- fundings,
318
- exports: json.exports,
319
- repository,
320
- homepage: json.homepage,
328
+ packageJson: objectPick(json, PACKAGE_JSON_KEYS),
321
329
  installSize: await getPackageInstallSize(_pkg)
322
330
  };
323
331
  return _pkg;
@@ -1,4 +1,4 @@
1
- import { PackageJsonExports } from 'pkg-types';
1
+ import { PackageJson } from 'pkg-types';
2
2
  import { Message } from 'publint';
3
3
 
4
4
  interface PackageInstallSizeInfo {
@@ -51,16 +51,7 @@ interface PackageNodeBase extends PackageNodeRaw {
51
51
  interface PackageNode extends PackageNodeBase {
52
52
  resolved: {
53
53
  module: PackageModuleType;
54
- license?: string;
55
- author?: string;
56
- repository?: string;
57
- fundings?: {
58
- url: string;
59
- type?: string;
60
- }[];
61
- exports?: PackageJsonExports;
62
- homepage?: string;
63
- engines?: Record<string, string>;
54
+ packageJson: PackageJson;
64
55
  installSize?: PackageInstallSizeInfo;
65
56
  npmMeta?: NpmMeta;
66
57
  npmMetaLatest?: NpmMetaLatest;
@@ -1,4 +1,4 @@
1
- import { PackageJsonExports } from 'pkg-types';
1
+ import { PackageJson } from 'pkg-types';
2
2
  import { Message } from 'publint';
3
3
 
4
4
  interface PackageInstallSizeInfo {
@@ -51,16 +51,7 @@ interface PackageNodeBase extends PackageNodeRaw {
51
51
  interface PackageNode extends PackageNodeBase {
52
52
  resolved: {
53
53
  module: PackageModuleType;
54
- license?: string;
55
- author?: string;
56
- repository?: string;
57
- fundings?: {
58
- url: string;
59
- type?: string;
60
- }[];
61
- exports?: PackageJsonExports;
62
- homepage?: string;
63
- engines?: Record<string, string>;
54
+ packageJson: PackageJson;
64
55
  installSize?: PackageInstallSizeInfo;
65
56
  npmMeta?: NpmMeta;
66
57
  npmMetaLatest?: NpmMetaLatest;
@@ -0,0 +1,111 @@
1
+ import { satisfies } from 'semver';
2
+
3
+ function constructPackageFilter(range) {
4
+ const [name, version = "*"] = range.split(/\b@/);
5
+ const hasWildcard = name?.includes("*");
6
+ const nameMatch = hasWildcard ? new RegExp(`^${Array.from(name).map((char) => char === "*" ? ".*" : char === "." ? "\\." : char).join("")}$`) : name;
7
+ return (pkg) => {
8
+ const isNameMatch = nameMatch instanceof RegExp ? nameMatch.test(pkg.name) : pkg.name === name;
9
+ const isVersionMatch = version === "*" || pkg.version === version || satisfies(pkg.version, version);
10
+ return isNameMatch && isVersionMatch;
11
+ };
12
+ }
13
+ function constructPackageFilters(ranges, mode) {
14
+ const filters = ranges.map((x) => typeof x === "string" ? constructPackageFilter(x) : x);
15
+ return (pkg) => mode === "some" ? filters.some((filter) => filter(pkg)) : filters.every((filter) => filter(pkg));
16
+ }
17
+
18
+ function parseFunding(funding) {
19
+ const url = funding.url;
20
+ let name = "";
21
+ let type = funding.type || "link";
22
+ let avatar;
23
+ let match = url.match(/^(?:https?:\/\/)?(?:www\.)?github\.com\/sponsors\/([\w.-]+)/i);
24
+ if (match) {
25
+ name = match[1];
26
+ type = "github";
27
+ }
28
+ if (!name) {
29
+ match = url.match(/^(?:https?:\/\/)?(?:www\.)?github\.com\/([\w.-]+)/i);
30
+ if (match) {
31
+ name = match[1];
32
+ type = "github";
33
+ }
34
+ }
35
+ if (!name) {
36
+ match = url.match(/^(?:https?:\/\/)?(?:www\.)?opencollective\.com\/([\w.-]+)/i);
37
+ if (match) {
38
+ name = match[1];
39
+ type = "opencollective";
40
+ }
41
+ }
42
+ if (!name)
43
+ name = url.replace(/^(?:https?:\/\/)?(?:www\.)?/, "").replace(/\/$/, "");
44
+ if (type === "github" && name)
45
+ avatar = `https://avatars.antfu.dev/gh/${name}`;
46
+ if (type === "opencollective" && name)
47
+ avatar = `https://opencollective.com/${name}/avatar.png`;
48
+ const entry = `${type}@${name}`;
49
+ return {
50
+ url,
51
+ type,
52
+ entry,
53
+ name,
54
+ avatar
55
+ };
56
+ }
57
+ function normalizePkgFundings(json) {
58
+ const rawFunding = json.funding;
59
+ let fundings;
60
+ if (typeof rawFunding === "string") {
61
+ fundings = [{ url: rawFunding }];
62
+ } else if (Array.isArray(rawFunding)) {
63
+ fundings = rawFunding.map((f) => typeof f === "string" ? { url: f } : f);
64
+ } else {
65
+ fundings = rawFunding ? [rawFunding] : [];
66
+ }
67
+ if (fundings.length === 0)
68
+ return void 0;
69
+ return fundings.map((f) => parseFunding(f)).filter(Boolean);
70
+ }
71
+ function parseAuthor(author) {
72
+ if (!author)
73
+ return void 0;
74
+ }
75
+ function normalizePkgAuthor(json) {
76
+ const author = json.author;
77
+ if (!author)
78
+ return void 0;
79
+ if (typeof author === "string") {
80
+ let url;
81
+ const name = author.replace(/<.*>/, "").replace(/\(.*\)/, "").replace(/^https?:\/\//, "");
82
+ return {
83
+ name,
84
+ url
85
+ };
86
+ }
87
+ return {
88
+ name: author.name,
89
+ url: author.url
90
+ };
91
+ }
92
+ function normalizePkgRepository(json) {
93
+ if (!json.repository)
94
+ return void 0;
95
+ let url = typeof json.repository === "string" ? json.repository : json.repository?.url;
96
+ if (url?.startsWith("git+"))
97
+ url = url.slice(4);
98
+ if (url?.endsWith(".git"))
99
+ url = url.slice(0, -4);
100
+ if (url?.startsWith("git://"))
101
+ url = `https://${url.slice(6)}`;
102
+ if (json.repository && typeof json.repository !== "string" && json.repository.directory)
103
+ url += `/tree/HEAD/${json.repository.directory}`;
104
+ if (/^[a-z0-9]+(?:[-_.][a-z0-9]+)*\/[a-z0-9]+(?:[-_.][a-z0-9]+)*$/i.test(url))
105
+ url = `https://github.com/${url}`;
106
+ return {
107
+ url
108
+ };
109
+ }
110
+
111
+ export { constructPackageFilters as a, parseAuthor as b, constructPackageFilter as c, normalizePkgAuthor as d, normalizePkgRepository as e, normalizePkgFundings as n, parseFunding as p };
package/dist/utils.d.mts CHANGED
@@ -1,3 +1,5 @@
1
+ import { PackageJson } from 'pkg-types';
2
+
1
3
  interface PackageNodeLike {
2
4
  name: string;
3
5
  version: string;
@@ -14,4 +16,26 @@ interface PackageNodeLike {
14
16
  declare function constructPackageFilter(range: string): (pkg: PackageNodeLike) => boolean;
15
17
  declare function constructPackageFilters<Node extends PackageNodeLike = PackageNodeLike>(ranges: (string | ((pkg: Node) => boolean))[], mode: 'some' | 'every'): (pkg: Node) => boolean;
16
18
 
17
- export { type PackageNodeLike, constructPackageFilter, constructPackageFilters };
19
+ interface NormalizedFunding {
20
+ url: string;
21
+ type?: string;
22
+ }
23
+ interface ParsedFunding {
24
+ url: string;
25
+ type: string;
26
+ name: string;
27
+ entry: string;
28
+ avatar?: string;
29
+ }
30
+ declare function parseFunding(funding: NormalizedFunding): ParsedFunding;
31
+ declare function normalizePkgFundings(json: PackageJson): ParsedFunding[] | undefined;
32
+ declare function parseAuthor(author?: string): undefined;
33
+ declare function normalizePkgAuthor(json: PackageJson): {
34
+ name: string;
35
+ url: string | undefined;
36
+ } | undefined;
37
+ declare function normalizePkgRepository(json: PackageJson): {
38
+ url: string;
39
+ } | undefined;
40
+
41
+ export { type NormalizedFunding, type PackageNodeLike, type ParsedFunding, constructPackageFilter, constructPackageFilters, normalizePkgAuthor, normalizePkgFundings, normalizePkgRepository, parseAuthor, parseFunding };
package/dist/utils.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import { PackageJson } from 'pkg-types';
2
+
1
3
  interface PackageNodeLike {
2
4
  name: string;
3
5
  version: string;
@@ -14,4 +16,26 @@ interface PackageNodeLike {
14
16
  declare function constructPackageFilter(range: string): (pkg: PackageNodeLike) => boolean;
15
17
  declare function constructPackageFilters<Node extends PackageNodeLike = PackageNodeLike>(ranges: (string | ((pkg: Node) => boolean))[], mode: 'some' | 'every'): (pkg: Node) => boolean;
16
18
 
17
- export { type PackageNodeLike, constructPackageFilter, constructPackageFilters };
19
+ interface NormalizedFunding {
20
+ url: string;
21
+ type?: string;
22
+ }
23
+ interface ParsedFunding {
24
+ url: string;
25
+ type: string;
26
+ name: string;
27
+ entry: string;
28
+ avatar?: string;
29
+ }
30
+ declare function parseFunding(funding: NormalizedFunding): ParsedFunding;
31
+ declare function normalizePkgFundings(json: PackageJson): ParsedFunding[] | undefined;
32
+ declare function parseAuthor(author?: string): undefined;
33
+ declare function normalizePkgAuthor(json: PackageJson): {
34
+ name: string;
35
+ url: string | undefined;
36
+ } | undefined;
37
+ declare function normalizePkgRepository(json: PackageJson): {
38
+ url: string;
39
+ } | undefined;
40
+
41
+ export { type NormalizedFunding, type PackageNodeLike, type ParsedFunding, constructPackageFilter, constructPackageFilters, normalizePkgAuthor, normalizePkgFundings, normalizePkgRepository, parseAuthor, parseFunding };
package/dist/utils.mjs CHANGED
@@ -1,2 +1,2 @@
1
- export { c as constructPackageFilter, a as constructPackageFilters } from './shared/node-modules-tools.DT_mm7wI.mjs';
1
+ export { c as constructPackageFilter, a as constructPackageFilters, d as normalizePkgAuthor, n as normalizePkgFundings, e as normalizePkgRepository, b as parseAuthor, p as parseFunding } from './shared/node-modules-tools.D5TyCC_Y.mjs';
2
2
  import 'semver';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "node-modules-tools",
3
3
  "type": "module",
4
- "version": "0.4.3",
4
+ "version": "0.5.0",
5
5
  "description": "Tools for inspecting node_modules",
6
6
  "author": "Anthony Fu <anthonyfu117@hotmail.com>",
7
7
  "license": "MIT",
@@ -1,18 +0,0 @@
1
- import { satisfies } from 'semver';
2
-
3
- function constructPackageFilter(range) {
4
- const [name, version = "*"] = range.split(/\b@/);
5
- const hasWildcard = name?.includes("*");
6
- const nameMatch = hasWildcard ? new RegExp(`^${Array.from(name).map((char) => char === "*" ? ".*" : char === "." ? "\\." : char).join("")}$`) : name;
7
- return (pkg) => {
8
- const isNameMatch = nameMatch instanceof RegExp ? nameMatch.test(pkg.name) : pkg.name === name;
9
- const isVersionMatch = version === "*" || pkg.version === version || satisfies(pkg.version, version);
10
- return isNameMatch && isVersionMatch;
11
- };
12
- }
13
- function constructPackageFilters(ranges, mode) {
14
- const filters = ranges.map((x) => typeof x === "string" ? constructPackageFilter(x) : x);
15
- return (pkg) => mode === "some" ? filters.some((filter) => filter(pkg)) : filters.every((filter) => filter(pkg));
16
- }
17
-
18
- export { constructPackageFilters as a, constructPackageFilter as c };