@nodesecure/scanner 5.2.1 → 6.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.
Files changed (90) hide show
  1. package/README.md +6 -116
  2. package/dist/class/logger.class.d.ts +27 -0
  3. package/dist/class/logger.class.d.ts.map +1 -0
  4. package/dist/class/logger.class.js +52 -0
  5. package/dist/class/logger.class.js.map +1 -0
  6. package/dist/comparePayloads.d.ts +66 -0
  7. package/dist/comparePayloads.d.ts.map +1 -0
  8. package/dist/comparePayloads.js +147 -0
  9. package/dist/comparePayloads.js.map +1 -0
  10. package/dist/depWalker.d.ts +10 -0
  11. package/dist/depWalker.d.ts.map +1 -0
  12. package/dist/depWalker.js +205 -0
  13. package/dist/depWalker.js.map +1 -0
  14. package/dist/i18n/english.d.ts +9 -0
  15. package/dist/i18n/english.d.ts.map +1 -0
  16. package/dist/i18n/english.js +6 -0
  17. package/dist/i18n/english.js.map +1 -0
  18. package/dist/i18n/french.d.ts +9 -0
  19. package/dist/i18n/french.d.ts.map +1 -0
  20. package/dist/i18n/french.js +6 -0
  21. package/dist/i18n/french.js.map +1 -0
  22. package/dist/index.d.ts +11 -0
  23. package/dist/index.d.ts.map +1 -0
  24. package/dist/index.js +68 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/npmRegistry.d.ts +9 -0
  27. package/dist/npmRegistry.d.ts.map +1 -0
  28. package/dist/npmRegistry.js +125 -0
  29. package/dist/npmRegistry.js.map +1 -0
  30. package/dist/types.d.ts +216 -0
  31. package/dist/types.d.ts.map +1 -0
  32. package/dist/types.js +4 -0
  33. package/dist/types.js.map +1 -0
  34. package/dist/utils/addMissingVersionFlags.d.ts +3 -0
  35. package/dist/utils/addMissingVersionFlags.d.ts.map +1 -0
  36. package/dist/utils/addMissingVersionFlags.js +21 -0
  37. package/dist/utils/addMissingVersionFlags.js.map +1 -0
  38. package/dist/utils/dirname.d.ts +2 -0
  39. package/dist/utils/dirname.d.ts.map +1 -0
  40. package/dist/utils/dirname.js +8 -0
  41. package/dist/utils/dirname.js.map +1 -0
  42. package/dist/utils/getLinks.d.ts +7 -0
  43. package/dist/utils/getLinks.d.ts.map +1 -0
  44. package/dist/utils/getLinks.js +32 -0
  45. package/dist/utils/getLinks.js.map +1 -0
  46. package/dist/utils/index.d.ts +11 -0
  47. package/dist/utils/index.d.ts.map +1 -0
  48. package/dist/utils/index.js +9 -0
  49. package/dist/utils/index.js.map +1 -0
  50. package/dist/utils/urlToString.d.ts +2 -0
  51. package/dist/utils/urlToString.d.ts.map +1 -0
  52. package/dist/utils/urlToString.js +6 -0
  53. package/dist/utils/urlToString.js.map +1 -0
  54. package/dist/utils/warnings.d.ts +9 -0
  55. package/dist/utils/warnings.d.ts.map +1 -0
  56. package/dist/utils/warnings.js +49 -0
  57. package/dist/utils/warnings.js.map +1 -0
  58. package/package.json +23 -42
  59. package/LICENSE +0 -21
  60. package/i18n/english.js +0 -6
  61. package/i18n/french.js +0 -7
  62. package/index.d.ts +0 -14
  63. package/index.js +0 -74
  64. package/src/class/dependency.class.js +0 -113
  65. package/src/class/logger.class.js +0 -54
  66. package/src/constants.js +0 -13
  67. package/src/depWalker.js +0 -388
  68. package/src/manifest.js +0 -94
  69. package/src/npmRegistry.js +0 -136
  70. package/src/tarball.js +0 -210
  71. package/src/utils/addMissingVersionFlags.js +0 -24
  72. package/src/utils/analyzeDependencies.js +0 -71
  73. package/src/utils/booleanToFlags.js +0 -12
  74. package/src/utils/dirname.js +0 -9
  75. package/src/utils/filterDependencyKind.js +0 -44
  76. package/src/utils/getLinks.js +0 -36
  77. package/src/utils/getPackageName.js +0 -21
  78. package/src/utils/getTarballComposition.js +0 -38
  79. package/src/utils/index.js +0 -18
  80. package/src/utils/isGitDependency.js +0 -11
  81. package/src/utils/isSensitiveFile.js +0 -17
  82. package/src/utils/mergeDependencies.js +0 -30
  83. package/src/utils/parseManifestAuthor.js +0 -45
  84. package/src/utils/semver.js +0 -62
  85. package/src/utils/warnings.js +0 -44
  86. package/types/api.d.ts +0 -15
  87. package/types/logger.d.ts +0 -38
  88. package/types/scanner.d.ts +0 -244
  89. package/types/tarball.d.ts +0 -63
  90. package/types/walker.d.ts +0 -8
package/src/manifest.js DELETED
@@ -1,94 +0,0 @@
1
- // Import Node.js Dependencies
2
- import fs from "node:fs/promises";
3
- import path from "node:path";
4
- import crypto from "node:crypto";
5
-
6
- // Import Internal Dependencies
7
- import { parseAuthor } from "./utils/index.js";
8
-
9
- // CONSTANTS
10
- // PR welcome to contribute to this list!
11
- const kNativeNpmPackages = new Set([
12
- "node-gyp", "node-pre-gyp", "node-gyp-build", "node-addon-api"
13
- ]);
14
- const kNodemodulesBinPrefix = "node_modules/.bin/";
15
-
16
- /**
17
- * @see https://www.nerdycode.com/prevent-npm-executing-scripts-security/
18
- */
19
- const kUnsafeNpmScripts = new Set([
20
- "install",
21
- "preinstall",
22
- "postinstall",
23
- "preuninstall",
24
- "postuninstall"
25
- ]);
26
-
27
- /**
28
- * @param {!string} location
29
- * @returns {Promise<import("@npm/types").PackageJson>}
30
- */
31
- export async function read(location) {
32
- const packageStr = await fs.readFile(
33
- path.join(location, "package.json"),
34
- "utf-8"
35
- );
36
-
37
- return JSON.parse(packageStr);
38
- }
39
-
40
- export async function readAnalyze(location) {
41
- const {
42
- name,
43
- version,
44
- description = "",
45
- author = {},
46
- scripts = {},
47
- dependencies = {},
48
- devDependencies = {},
49
- gypfile = false,
50
- engines = {},
51
- repository = {},
52
- imports = {},
53
- license = ""
54
- } = await read(location);
55
-
56
- for (const [scriptName, scriptValue] of Object.entries(scripts)) {
57
- if (scriptValue.startsWith(kNodemodulesBinPrefix)) {
58
- scripts[scriptName] = scriptValue.replaceAll(kNodemodulesBinPrefix, "");
59
- }
60
- }
61
-
62
- const integrityObj = {
63
- name,
64
- version,
65
- dependencies,
66
- license,
67
- scripts
68
- };
69
-
70
- const integrity = crypto
71
- .createHash("sha256")
72
- .update(JSON.stringify(integrityObj))
73
- .digest("hex");
74
-
75
- const packageDeps = Object.keys(dependencies);
76
- const packageDevDeps = Object.keys(devDependencies);
77
- const hasNativePackage = [...packageDevDeps, ...packageDeps]
78
- .some((pkg) => kNativeNpmPackages.has(pkg));
79
-
80
- return {
81
- author: parseAuthor(author),
82
- description,
83
- engines,
84
- repository,
85
- scripts,
86
- hasScript: Object.keys(scripts)
87
- .some((value) => kUnsafeNpmScripts.has(value.toLowerCase())),
88
- packageDeps,
89
- packageDevDeps,
90
- nodejs: { imports },
91
- hasNativeElements: hasNativePackage || gypfile,
92
- integrity
93
- };
94
- }
@@ -1,136 +0,0 @@
1
- // Import Node.js Dependencies
2
- import crypto from "node:crypto";
3
-
4
- // Import Third-party Dependencies
5
- import semver from "semver";
6
- import { packument, packumentVersion } from "@nodesecure/npm-registry-sdk";
7
-
8
- // Import Internal Dependencies
9
- import { parseAuthor, getLinks } from "./utils/index.js";
10
-
11
- export async function manifestMetadata(
12
- name,
13
- version,
14
- dependency
15
- ) {
16
- try {
17
- const pkgVersion = await packumentVersion(name, version);
18
-
19
- const integrity = getPackumentVersionIntegrity(pkgVersion);
20
- Object.assign(
21
- dependency.versions[version],
22
- {
23
- links: getLinks(pkgVersion)
24
- }
25
- );
26
-
27
- dependency.metadata.integrity[version] = integrity;
28
- }
29
- catch {
30
- // Ignore
31
- }
32
- }
33
-
34
- export async function packageMetadata(name, version, options) {
35
- const { ref, logger } = options;
36
- const packageSpec = `${name}:${version}`;
37
-
38
- try {
39
- const pkg = await packument(name);
40
-
41
- const oneYearFromToday = new Date();
42
- oneYearFromToday.setFullYear(oneYearFromToday.getFullYear() - 1);
43
-
44
- const lastVersion = pkg["dist-tags"].latest;
45
- const lastUpdateAt = new Date(pkg.time[lastVersion]);
46
- const metadata = {
47
- author: parseAuthor(pkg.author),
48
- homepage: pkg.homepage || null,
49
- publishedCount: Object.values(pkg.versions).length,
50
- lastVersion,
51
- lastUpdateAt,
52
- hasReceivedUpdateInOneYear: !(oneYearFromToday > lastUpdateAt),
53
- maintainers: pkg.maintainers ?? [],
54
- publishers: [],
55
- integrity: {}
56
- };
57
-
58
- const isOutdated = semver.neq(version, lastVersion);
59
- const flags = ref.versions[version].flags;
60
- if (isOutdated) {
61
- flags.push("isOutdated");
62
- }
63
-
64
- const publishers = new Set();
65
- let searchForMaintainersInVersions = metadata.maintainers.length === 0;
66
- for (const ver of Object.values(pkg.versions).reverse()) {
67
- const versionSpec = `${ver.name}:${ver.version}`;
68
- if (packageSpec === versionSpec) {
69
- if (ver.deprecated && !flags.includes("isDeprecated")) {
70
- flags.push("isDeprecated");
71
- }
72
-
73
- metadata.integrity[ver.version] = getPackumentVersionIntegrity(
74
- ver
75
- );
76
- }
77
-
78
- const { _npmUser: npmUser, version, maintainers = [] } = ver;
79
-
80
- const isNullOrUndefined = typeof npmUser === "undefined" || npmUser === null;
81
- if (isNullOrUndefined || !("name" in npmUser) || typeof npmUser.name !== "string") {
82
- continue;
83
- }
84
-
85
- const authorName = metadata.author?.name ?? null;
86
- if (authorName === null) {
87
- metadata.author = npmUser;
88
- }
89
- else if (npmUser.name !== metadata.author.name) {
90
- metadata.hasManyPublishers = true;
91
- }
92
-
93
- // TODO: add npmUser.email
94
- if (!publishers.has(npmUser.name)) {
95
- publishers.add(npmUser.name);
96
- metadata.publishers.push({ ...npmUser, version, at: new Date(pkg.time[version]) });
97
- }
98
-
99
- if (searchForMaintainersInVersions) {
100
- metadata.maintainers.push(...maintainers);
101
- searchForMaintainersInVersions = false;
102
- }
103
- }
104
-
105
- Object.assign(ref.versions[version], { links: getLinks(pkg.versions[version]) });
106
- Object.assign(ref.metadata, metadata);
107
- }
108
- catch {
109
- // ignore
110
- }
111
- finally {
112
- logger.tick("registry");
113
- }
114
- }
115
-
116
- function getPackumentVersionIntegrity(packumentVersion) {
117
- const { name, version, dependencies = {}, license = "", scripts = {} } = packumentVersion;
118
-
119
- // See https://github.com/npm/cli/issues/5234
120
- if ("install" in dependencies && dependencies.install === "node-gyp rebuild") {
121
- delete dependencies.install;
122
- }
123
-
124
- const integrityObj = {
125
- name,
126
- version,
127
- dependencies,
128
- license,
129
- scripts
130
- };
131
-
132
- return crypto
133
- .createHash("sha256")
134
- .update(JSON.stringify(integrityObj))
135
- .digest("hex");
136
- }
package/src/tarball.js DELETED
@@ -1,210 +0,0 @@
1
- // Import Node.js Dependencies
2
- import path from "path";
3
- import os from "os";
4
- import timers from "timers/promises";
5
-
6
- // Import Third-party Dependencies
7
- import { runASTAnalysisOnFile } from "@nodesecure/js-x-ray";
8
- import pacote from "pacote";
9
- import ntlp from "@nodesecure/ntlp";
10
-
11
- // Import Internal Dependencies
12
- import {
13
- getTarballComposition,
14
- isSensitiveFile,
15
- filterDependencyKind,
16
- analyzeDependencies,
17
- booleanToFlags,
18
- NPM_TOKEN,
19
- getSemVerWarning
20
- } from "./utils/index.js";
21
- import * as manifest from "./manifest.js";
22
-
23
- // CONSTANTS
24
- const kNativeCodeExtensions = new Set([".gyp", ".c", ".cpp", ".node", ".so", ".h"]);
25
- const kJsExtname = new Set([".js", ".mjs", ".cjs"]);
26
-
27
- export async function scanJavascriptFile(dest, file, packageName) {
28
- const result = await runASTAnalysisOnFile(path.join(dest, file), { packageName });
29
-
30
- const warnings = result.warnings.map((curr) => Object.assign({}, curr, { file }));
31
- if (!result.ok) {
32
- return {
33
- file,
34
- warnings,
35
- isMinified: false,
36
- tryDependencies: [],
37
- dependencies: [],
38
- filesDependencies: []
39
- };
40
- }
41
- const { packages, files } = filterDependencyKind(result.dependencies, path.dirname(file));
42
-
43
- return {
44
- file,
45
- warnings,
46
- isMinified: result.isMinified,
47
- tryDependencies: [...result.dependencies.getDependenciesInTryStatement()],
48
- dependencies: packages,
49
- filesDependencies: files
50
- };
51
- }
52
-
53
- export async function scanDirOrArchive(name, version, options) {
54
- const { ref, location = process.cwd(), tmpLocation, locker, registry } = options;
55
-
56
- const isNpmTarball = !(tmpLocation === null);
57
- const dest = isNpmTarball ? path.join(tmpLocation, `${name}@${version}`) : location;
58
- const free = await locker.acquireOne();
59
-
60
- try {
61
- // If this is an NPM tarball then we extract it on the disk with pacote.
62
- if (isNpmTarball) {
63
- await pacote.extract(ref.flags.includes("isGit") ? ref.gitUrl : `${name}@${version}`, dest, {
64
- ...NPM_TOKEN,
65
- registry,
66
- cache: `${os.homedir()}/.npm`
67
- });
68
- await timers.setImmediate();
69
- }
70
- else {
71
- // Set links to an empty object because theses are generated only for NPM tarballs
72
- Object.assign(ref, { links: {} });
73
- }
74
-
75
- // Read the package.json at the root of the directory or archive.
76
- const {
77
- packageDeps,
78
- packageDevDeps,
79
- author,
80
- description,
81
- hasScript,
82
- hasNativeElements,
83
- nodejs,
84
- engines,
85
- repository,
86
- scripts,
87
- integrity
88
- } = await manifest.readAnalyze(dest);
89
- Object.assign(ref, {
90
- author, description, engines, repository, scripts, integrity
91
- });
92
-
93
- // Get the composition of the (extracted) directory
94
- const { ext, files, size } = await getTarballComposition(dest);
95
- if (files.length === 1 && files.includes("package.json")) {
96
- ref.warnings.push({
97
- kind: "empty-package",
98
- location: null,
99
- i18n: "sast_warnings.emptyPackage",
100
- severity: "Critical",
101
- source: "Scanner",
102
- experimental: false
103
- });
104
- }
105
-
106
- ref.size = size;
107
- ref.composition.extensions.push(...ext);
108
- ref.composition.files.push(...files);
109
- const hasBannedFile = files.some((path) => isSensitiveFile(path));
110
- const hasNativeCode = hasNativeElements || files.some((file) => kNativeCodeExtensions.has(path.extname(file)));
111
-
112
- // Search for minified and runtime dependencies
113
- // Run a JS-X-Ray analysis on each JavaScript files of the project!
114
- const fileAnalysisRaw = await Promise.allSettled(
115
- files
116
- .filter((name) => kJsExtname.has(path.extname(name)))
117
- .map((file) => scanJavascriptFile(dest, file, name))
118
- );
119
-
120
- const fileAnalysisResults = fileAnalysisRaw
121
- .filter((promiseSettledResult) => promiseSettledResult.status === "fulfilled")
122
- .map((promiseSettledResult) => promiseSettledResult.value);
123
-
124
- ref.warnings.push(...fileAnalysisResults.flatMap((row) => row.warnings));
125
-
126
- if (/^0(\.\d+)*$/.test(version)) {
127
- ref.warnings.push(getSemVerWarning(version));
128
- }
129
-
130
- const dependencies = [...new Set(fileAnalysisResults.flatMap((row) => row.dependencies))];
131
- const filesDependencies = [...new Set(fileAnalysisResults.flatMap((row) => row.filesDependencies))];
132
- const tryDependencies = new Set(fileAnalysisResults.flatMap((row) => row.tryDependencies));
133
- const minifiedFiles = fileAnalysisResults.filter((row) => row.isMinified).flatMap((row) => row.file);
134
-
135
- const {
136
- nodeDependencies, thirdPartyDependencies, subpathImportsDependencies, missingDependencies, unusedDependencies, flags
137
- } = analyzeDependencies(dependencies, { packageDeps, packageDevDeps, tryDependencies, nodeImports: nodejs.imports });
138
-
139
- ref.composition.required_thirdparty = thirdPartyDependencies;
140
- ref.composition.required_subpath = Object.fromEntries(subpathImportsDependencies);
141
- ref.composition.unused.push(...unusedDependencies);
142
- ref.composition.missing.push(...missingDependencies);
143
- ref.composition.required_files = filesDependencies;
144
- ref.composition.required_nodejs = nodeDependencies;
145
- ref.composition.minified = minifiedFiles;
146
-
147
- // License
148
- await timers.setImmediate();
149
- const licenses = await ntlp(dest);
150
- const uniqueLicenseIds = Array.isArray(licenses.uniqueLicenseIds) ? licenses.uniqueLicenseIds : [];
151
- ref.license = licenses;
152
- ref.license.uniqueLicenseIds = uniqueLicenseIds;
153
-
154
- ref.flags.push(...booleanToFlags({
155
- ...flags,
156
- hasNoLicense: uniqueLicenseIds.length === 0,
157
- hasMultipleLicenses: licenses.hasMultipleLicenses,
158
- hasMinifiedCode: minifiedFiles.length > 0,
159
- hasWarnings: ref.warnings.length > 0 && !ref.flags.includes("hasWarnings"),
160
- hasBannedFile,
161
- hasNativeCode,
162
- hasScript
163
- }));
164
- }
165
- catch {
166
- // Ignore
167
- }
168
- finally {
169
- free();
170
- }
171
- }
172
-
173
- export async function scanPackage(dest, packageName) {
174
- const { type = "script", name } = await manifest.read(dest);
175
-
176
- await timers.setImmediate();
177
- const { ext, files, size } = await getTarballComposition(dest);
178
- ext.delete("");
179
-
180
- // Search for runtime dependencies
181
- const dependencies = Object.create(null);
182
- const [minified, warnings] = [[], []];
183
-
184
- const JSFiles = files.filter((name) => kJsExtname.has(path.extname(name)));
185
- for (const file of JSFiles) {
186
- const result = await runASTAnalysisOnFile(path.join(dest, file), {
187
- packageName: packageName ?? name,
188
- module: type === "module"
189
- });
190
-
191
- warnings.push(...result.warnings.map((curr) => Object.assign({}, curr, { file })));
192
- if (!result.ok) {
193
- continue;
194
- }
195
-
196
- dependencies[file] = result.dependencies.dependencies;
197
- result.isMinified && minified.push(file);
198
- }
199
-
200
- await timers.setImmediate();
201
- const { uniqueLicenseIds, licenses } = await ntlp(dest);
202
-
203
- return {
204
- files: { list: files, extensions: [...ext], minified },
205
- directorySize: size,
206
- uniqueLicenseIds,
207
- licenses,
208
- ast: { dependencies, warnings }
209
- };
210
- }
@@ -1,24 +0,0 @@
1
- /**
2
- * @param {Set<string>} flags
3
- * @param {import("../../types/scanner").Dependency} descriptor
4
- */
5
- export function* addMissingVersionFlags(flags, descriptor) {
6
- const { metadata, vulnerabilities = [], versions } = descriptor;
7
- const semverVersions = Object.keys(versions);
8
-
9
- if (!metadata.hasReceivedUpdateInOneYear && flags.has("hasOutdatedDependency") && !flags.has("isDead")) {
10
- yield "isDead";
11
- }
12
- if (metadata.hasManyPublishers && !flags.has("hasManyPublishers")) {
13
- yield "hasManyPublishers";
14
- }
15
- if (metadata.hasChangedAuthor && !flags.has("hasChangedAuthor")) {
16
- yield "hasChangedAuthor";
17
- }
18
- if (vulnerabilities.length > 0 && !flags.has("hasVulnerabilities")) {
19
- yield "hasVulnerabilities";
20
- }
21
- if (semverVersions.length > 1 && !flags.has("hasDuplicate")) {
22
- yield "hasDuplicate";
23
- }
24
- }
@@ -1,71 +0,0 @@
1
- // Import Third-party Dependencies
2
- import difference from "lodash.difference";
3
- import builtins from "builtins";
4
-
5
- // Import Internal Dependencies
6
- import { getPackageName } from "./getPackageName.js";
7
-
8
- // CONSTANTS
9
- const kNodeModules = new Set(builtins({ experimental: true }));
10
- const kExternalModules = new Set(["http", "https", "net", "http2", "dgram", "child_process"]);
11
-
12
- export function analyzeDependencies(dependencies, deps = {}) {
13
- const { packageDeps, packageDevDeps, tryDependencies, nodeImports = {} } = deps;
14
-
15
- // See: https://nodejs.org/api/packages.html#subpath-imports
16
- const subpathImportsDependencies = dependencies
17
- .filter((name) => isAliasDependency(name) && name in nodeImports)
18
- .map((name) => buildSubpathDependency(name, nodeImports));
19
- const thirdPartyDependenciesAliased = new Set(
20
- subpathImportsDependencies.flat().filter((name) => !isAliasDependency(name))
21
- );
22
-
23
- const thirdPartyDependencies = dependencies
24
- .map((name) => (packageDeps.includes(name) ? name : getPackageName(name)))
25
- .filter((name) => !name.startsWith("."))
26
- .filter((name) => !isNodeCoreModule(name))
27
- .filter((name) => !packageDevDeps.includes(name))
28
- .filter((name) => !tryDependencies.has(name));
29
-
30
- const unusedDependencies = difference(
31
- packageDeps.filter((name) => !name.startsWith("@types")),
32
- [...thirdPartyDependencies, ...thirdPartyDependenciesAliased]
33
- );
34
- const missingDependencies = [...new Set(difference(thirdPartyDependencies, packageDeps))]
35
- .filter((name) => !(name in nodeImports));
36
- const nodeDependencies = dependencies.filter((name) => isNodeCoreModule(name));
37
-
38
- return {
39
- nodeDependencies,
40
- thirdPartyDependencies: [...new Set(thirdPartyDependencies)],
41
- subpathImportsDependencies,
42
- unusedDependencies,
43
- missingDependencies,
44
-
45
- flags: {
46
- hasExternalCapacity: nodeDependencies.some((depName) => kExternalModules.has(depName)),
47
- hasMissingOrUnusedDependency: unusedDependencies.length > 0 || missingDependencies.length > 0
48
- }
49
- };
50
- }
51
-
52
- /**
53
- * @param {!string} moduleName
54
- * @returns {boolean}
55
- */
56
- function isNodeCoreModule(moduleName) {
57
- const cleanModuleName = moduleName.startsWith("node:") ? moduleName.slice(5) : moduleName;
58
-
59
- // Note: We need to also check moduleName because builtins package only return true for 'node:test'.
60
- return kNodeModules.has(cleanModuleName) || kNodeModules.has(moduleName);
61
- }
62
-
63
- function isAliasDependency(moduleName) {
64
- return moduleName.charAt(0) === "#";
65
- }
66
-
67
- function buildSubpathDependency(alias, nodeImports) {
68
- const importedDependency = nodeImports[alias].node ?? nodeImports[alias].default;
69
-
70
- return [alias, importedDependency];
71
- }
@@ -1,12 +0,0 @@
1
- /**
2
- * @param {Record<string, boolean>} flagsRecord
3
- * @example
4
- * console.log(...booleanToFlags({ hasScript: true })); // "hasScript"
5
- */
6
- export function* booleanToFlags(flagsRecord) {
7
- for (const [flagName, boolValue] of Object.entries(flagsRecord)) {
8
- if (boolValue) {
9
- yield flagName;
10
- }
11
- }
12
- }
@@ -1,9 +0,0 @@
1
- // Import Node.js Dependencies
2
- import { fileURLToPath } from "url";
3
- import { dirname } from "path";
4
-
5
- export function getDirNameFromUrl(url) {
6
- const __filename = fileURLToPath(url);
7
-
8
- return dirname(__filename);
9
- }
@@ -1,44 +0,0 @@
1
- // Import Node.js Dependencies
2
- import path from "path";
3
-
4
- // CONSTANTS
5
- const kRelativeImportPath = new Set([".", "..", "./", "../"]);
6
-
7
- /**
8
- * @see https://nodejs.org/docs/latest/api/modules.html#file-modules
9
- *
10
- * @param {IterableIterator<string>} dependencies
11
- * @param {!string} relativeFileLocation
12
- */
13
- export function filterDependencyKind(dependencies, relativeFileLocation) {
14
- const packages = [];
15
- const files = [];
16
-
17
- for (const moduleNameOrPath of dependencies) {
18
- const firstChar = moduleNameOrPath.charAt(0);
19
-
20
- /**
21
- * @example
22
- * require("..");
23
- * require("/home/marco/foo.js");
24
- */
25
- if (firstChar === "." || firstChar === "/") {
26
- // Note: condition only possible for CJS
27
- if (kRelativeImportPath.has(moduleNameOrPath)) {
28
- files.push(path.join(moduleNameOrPath, "index.js"));
29
- }
30
- else {
31
- // Note: we are speculating that the extension is .js (but it could be .json or .node)
32
- const fixedFileName = path.extname(moduleNameOrPath) === "" ?
33
- `${moduleNameOrPath}.js` : moduleNameOrPath;
34
-
35
- files.push(path.join(relativeFileLocation, fixedFileName));
36
- }
37
- }
38
- else {
39
- packages.push(moduleNameOrPath);
40
- }
41
- }
42
-
43
- return { packages, files };
44
- }
@@ -1,36 +0,0 @@
1
- // CONSTANTS
2
- const kVCSHosts = new Set(["github.com", "gitlab.com"]);
3
-
4
- function getVCSRepositoryURL(link) {
5
- try {
6
- const url = new URL(link);
7
- const { hostname, pathname } = url;
8
-
9
- if (kVCSHosts.has(hostname) === false) {
10
- return null;
11
- }
12
-
13
- const [owner, repo] = pathname.split("/").filter(Boolean).map((curr) => curr.replace(".git", ""));
14
-
15
- return `https://${hostname}/${owner}/${repo}`;
16
- }
17
- catch {
18
- return null;
19
- }
20
- }
21
-
22
- /**
23
- * @param {import("@nodesecure/npm-registry-sdk").PackumentVersion} packumentVersion
24
- */
25
- export function getLinks(
26
- packumentVersion
27
- ) {
28
- const homepage = packumentVersion.homepage || null;
29
- const repositoryUrl = packumentVersion.repository?.url || null;
30
-
31
- return {
32
- npm: `https://www.npmjs.com/package/${packumentVersion.name}/v/${packumentVersion.version}`,
33
- homepage,
34
- repository: getVCSRepositoryURL(homepage) ?? getVCSRepositoryURL(repositoryUrl)
35
- };
36
- }
@@ -1,21 +0,0 @@
1
- // CONSTANTS
2
- const kPackageSeparator = "/";
3
- const kPackageOrgSymbol = "@";
4
-
5
- /**
6
- * @see https://github.com/npm/validate-npm-package-name#naming-rules
7
- *
8
- * @param {!string} name full package name
9
- * @returns {string}
10
- *
11
- * @example
12
- * getPackageName("foo"); // foo
13
- * getPackageName("foo/bar"); // foo
14
- * getPackageName("@org/bar"); // @org/bar
15
- */
16
- export function getPackageName(name) {
17
- const parts = name.split(kPackageSeparator);
18
-
19
- // Note: only scoped package are allowed to start with @
20
- return name.startsWith(kPackageOrgSymbol) ? `${parts[0]}/${parts[1]}` : parts[0];
21
- }