app-builder-lib 26.3.1 → 26.3.3
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/out/asar/asar.js +9 -0
- package/out/asar/asar.js.map +1 -1
- package/out/asar/asarUtil.js +56 -63
- package/out/asar/asarUtil.js.map +1 -1
- package/out/node-module-collector/moduleCache.d.ts +4 -1
- package/out/node-module-collector/moduleCache.js.map +1 -1
- package/out/node-module-collector/nodeModulesCollector.d.ts +15 -14
- package/out/node-module-collector/nodeModulesCollector.js +51 -67
- package/out/node-module-collector/nodeModulesCollector.js.map +1 -1
- package/out/node-module-collector/npmNodeModulesCollector.js +7 -8
- package/out/node-module-collector/npmNodeModulesCollector.js.map +1 -1
- package/out/node-module-collector/packageManager.js +3 -3
- package/out/node-module-collector/packageManager.js.map +1 -1
- package/out/node-module-collector/pnpmNodeModulesCollector.d.ts +2 -0
- package/out/node-module-collector/pnpmNodeModulesCollector.js +55 -34
- package/out/node-module-collector/pnpmNodeModulesCollector.js.map +1 -1
- package/out/node-module-collector/yarnNodeModulesCollector.d.ts +0 -1
- package/out/node-module-collector/yarnNodeModulesCollector.js +40 -36
- package/out/node-module-collector/yarnNodeModulesCollector.js.map +1 -1
- package/out/util/appFileCopier.js +1 -1
- package/out/util/appFileCopier.js.map +1 -1
- package/out/version.d.ts +1 -1
- package/out/version.js +1 -1
- package/out/version.js.map +1 -1
- package/package.json +7 -7
package/out/asar/asar.js
CHANGED
|
@@ -24,6 +24,9 @@ class AsarFilesystem {
|
|
|
24
24
|
let node = this.header;
|
|
25
25
|
for (const dir of p.split(path.sep)) {
|
|
26
26
|
if (dir !== ".") {
|
|
27
|
+
if (node == null) {
|
|
28
|
+
throw new Error(`Cannot find node for path: ${p} (node is null at ${dir})`);
|
|
29
|
+
}
|
|
27
30
|
let child = node.files[dir];
|
|
28
31
|
if (child == null) {
|
|
29
32
|
if (!isCreate) {
|
|
@@ -44,6 +47,9 @@ class AsarFilesystem {
|
|
|
44
47
|
}
|
|
45
48
|
const name = path.basename(p);
|
|
46
49
|
const dirNode = this.searchNodeFromDirectory(path.dirname(p), true);
|
|
50
|
+
if (dirNode == null) {
|
|
51
|
+
throw new Error(`Cannot find node for path: ${p} (node is null at ${path.dirname(p)})`);
|
|
52
|
+
}
|
|
47
53
|
if (dirNode.files == null) {
|
|
48
54
|
dirNode.files = this.newNode();
|
|
49
55
|
}
|
|
@@ -84,6 +90,9 @@ class AsarFilesystem {
|
|
|
84
90
|
}
|
|
85
91
|
getNode(p) {
|
|
86
92
|
const node = this.searchNodeFromDirectory(path.dirname(p), false);
|
|
93
|
+
if (node == null) {
|
|
94
|
+
throw new Error(`Cannot find node for path: ${p} (node is null at ${path.dirname(p)})`);
|
|
95
|
+
}
|
|
87
96
|
return node.files[path.basename(p)];
|
|
88
97
|
}
|
|
89
98
|
getFile(p, followLinks = true) {
|
package/out/asar/asar.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"asar.js","sourceRoot":"","sources":["../../src/asar/asar.ts"],"names":[],"mappings":"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","sourcesContent":["import { createFromBuffer } from \"chromium-pickle-js\"\nimport { close, open, read, readFile, Stats } from \"fs-extra\"\nimport * as path from \"path\"\n\nexport interface ReadAsarHeader {\n readonly header: string\n readonly size: number\n}\n\nexport interface NodeIntegrity {\n algorithm: \"SHA256\"\n hash: string\n blockSize: number\n blocks: Array<string>\n}\n\nexport class Node {\n // we don't use Map because later it will be stringified\n files?: Record<string, Node>\n\n unpacked?: boolean\n\n size?: number\n // electron expects string\n offset?: string\n\n executable?: boolean\n\n link?: string\n\n integrity?: NodeIntegrity\n}\n\nexport class AsarFilesystem {\n private offset = 0\n\n constructor(\n readonly src: string,\n readonly header = new Node(),\n readonly headerSize: number = -1\n ) {\n if (this.header.files == null) {\n this.header.files = this.newNode()\n }\n }\n\n searchNodeFromDirectory(p: string, isCreate: boolean): Node | null {\n let node = this.header\n for (const dir of p.split(path.sep)) {\n if (dir !== \".\") {\n let child = node.files![dir]\n if (child == null) {\n if (!isCreate) {\n return null\n }\n child = new Node()\n child.files = this.newNode()\n node.files![dir] = child\n }\n node = child\n }\n }\n return node\n }\n\n getOrCreateNode(p: string): Node {\n if (p == null || p.length === 0) {\n return this.header\n }\n\n const name = path.basename(p)\n const dirNode = this.searchNodeFromDirectory(path.dirname(p), true)!\n if (dirNode.files == null) {\n dirNode.files = this.newNode()\n }\n\n let result = dirNode.files[name]\n if (result == null) {\n result = new Node()\n dirNode.files[name] = result\n }\n return result\n }\n\n addFileNode(file: string, dirNode: Node, size: number, unpacked: boolean, stat: Stats, integrity?: NodeIntegrity): Node {\n if (size > 4294967295) {\n throw new Error(`${file}: file size cannot be larger than 4.2GB`)\n }\n\n const node = new Node()\n node.size = size\n if (integrity) {\n node.integrity = integrity\n }\n if (unpacked) {\n node.unpacked = true\n } else {\n // electron expects string\n node.offset = this.offset.toString()\n if (process.platform !== \"win32\" && stat.mode & 0o100) {\n node.executable = true\n }\n this.offset += node.size\n }\n\n let children = dirNode.files\n if (children == null) {\n children = this.newNode()\n dirNode.files = children\n }\n children[path.basename(file)] = node\n\n return node\n }\n\n getNode(p: string): Node | null {\n const node = this.searchNodeFromDirectory(path.dirname(p), false)!\n return node.files![path.basename(p)]\n }\n\n getFile(p: string, followLinks = true): Node {\n const info = this.getNode(p)!\n // if followLinks is false we don't resolve symlinks\n return followLinks && info.link != null ? this.getFile(info.link) : info\n }\n\n async readJson(file: string): Promise<any> {\n return JSON.parse((await this.readFile(file)).toString())\n }\n\n readFile(file: string): Promise<Buffer> {\n return readFileFromAsar(this, file, this.getFile(file))\n }\n\n private newNode() {\n return Object.create(null) as Record<string, Node>\n }\n}\n\nexport async function readAsarHeader(archive: string): Promise<ReadAsarHeader> {\n const fd = await open(archive, \"r\")\n let size: number\n let headerBuf\n try {\n const sizeBuf = Buffer.allocUnsafe(8)\n if ((await read(fd, sizeBuf, 0, 8, null as any)).bytesRead !== 8) {\n throw new Error(\"Unable to read header size\")\n }\n\n const sizePickle = createFromBuffer(sizeBuf)\n size = sizePickle.createIterator().readUInt32()\n headerBuf = Buffer.allocUnsafe(size)\n if ((await read(fd, headerBuf, 0, size, null as any)).bytesRead !== size) {\n throw new Error(\"Unable to read header\")\n }\n } finally {\n await close(fd)\n }\n\n const headerPickle = createFromBuffer(headerBuf)\n return { header: headerPickle.createIterator().readString(), size }\n}\n\nexport async function readAsar(archive: string): Promise<AsarFilesystem> {\n const { header, size } = await readAsarHeader(archive)\n return new AsarFilesystem(archive, JSON.parse(header), size)\n}\n\nexport async function readAsarJson(archive: string, file: string): Promise<any> {\n const fs = await readAsar(archive)\n return await fs.readJson(file)\n}\n\nasync function readFileFromAsar(filesystem: AsarFilesystem, filename: string, info: Node): Promise<Buffer> {\n const size = info.size!\n const buffer = Buffer.allocUnsafe(size)\n if (size <= 0) {\n return buffer\n }\n\n if (info.unpacked) {\n return await readFile(path.join(`${filesystem.src}.unpacked`, filename))\n }\n\n const fd = await open(filesystem.src, \"r\")\n try {\n const offset = 8 + filesystem.headerSize + parseInt(info.offset!, 10)\n await read(fd, buffer, 0, size, offset)\n } finally {\n await close(fd)\n }\n return buffer\n}\n"]}
|
|
1
|
+
{"version":3,"file":"asar.js","sourceRoot":"","sources":["../../src/asar/asar.ts"],"names":[],"mappings":"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","sourcesContent":["import { createFromBuffer } from \"chromium-pickle-js\"\nimport { close, open, read, readFile, Stats } from \"fs-extra\"\nimport * as path from \"path\"\n\nexport interface ReadAsarHeader {\n readonly header: string\n readonly size: number\n}\n\nexport interface NodeIntegrity {\n algorithm: \"SHA256\"\n hash: string\n blockSize: number\n blocks: Array<string>\n}\n\nexport class Node {\n // we don't use Map because later it will be stringified\n files?: Record<string, Node>\n\n unpacked?: boolean\n\n size?: number\n // electron expects string\n offset?: string\n\n executable?: boolean\n\n link?: string\n\n integrity?: NodeIntegrity\n}\n\nexport class AsarFilesystem {\n private offset = 0\n\n constructor(\n readonly src: string,\n readonly header = new Node(),\n readonly headerSize: number = -1\n ) {\n if (this.header.files == null) {\n this.header.files = this.newNode()\n }\n }\n\n searchNodeFromDirectory(p: string, isCreate: boolean): Node | null {\n let node = this.header\n for (const dir of p.split(path.sep)) {\n if (dir !== \".\") {\n if (node == null) {\n throw new Error(`Cannot find node for path: ${p} (node is null at ${dir})`)\n }\n let child = node.files![dir]\n if (child == null) {\n if (!isCreate) {\n return null\n }\n child = new Node()\n child.files = this.newNode()\n node.files![dir] = child\n }\n node = child\n }\n }\n return node\n }\n\n getOrCreateNode(p: string): Node {\n if (p == null || p.length === 0) {\n return this.header\n }\n\n const name = path.basename(p)\n const dirNode = this.searchNodeFromDirectory(path.dirname(p), true)!\n if (dirNode == null) {\n throw new Error(`Cannot find node for path: ${p} (node is null at ${path.dirname(p)})`)\n }\n if (dirNode.files == null) {\n dirNode.files = this.newNode()\n }\n\n let result = dirNode.files[name]\n if (result == null) {\n result = new Node()\n dirNode.files[name] = result\n }\n return result\n }\n\n addFileNode(file: string, dirNode: Node, size: number, unpacked: boolean, stat: Stats, integrity?: NodeIntegrity): Node {\n if (size > 4294967295) {\n throw new Error(`${file}: file size cannot be larger than 4.2GB`)\n }\n\n const node = new Node()\n node.size = size\n if (integrity) {\n node.integrity = integrity\n }\n if (unpacked) {\n node.unpacked = true\n } else {\n // electron expects string\n node.offset = this.offset.toString()\n if (process.platform !== \"win32\" && stat.mode & 0o100) {\n node.executable = true\n }\n this.offset += node.size\n }\n\n let children = dirNode.files\n if (children == null) {\n children = this.newNode()\n dirNode.files = children\n }\n children[path.basename(file)] = node\n\n return node\n }\n\n getNode(p: string): Node | null {\n const node = this.searchNodeFromDirectory(path.dirname(p), false)!\n if (node == null) {\n throw new Error(`Cannot find node for path: ${p} (node is null at ${path.dirname(p)})`)\n }\n return node.files![path.basename(p)]\n }\n\n getFile(p: string, followLinks = true): Node {\n const info = this.getNode(p)!\n // if followLinks is false we don't resolve symlinks\n return followLinks && info.link != null ? this.getFile(info.link) : info\n }\n\n async readJson(file: string): Promise<any> {\n return JSON.parse((await this.readFile(file)).toString())\n }\n\n readFile(file: string): Promise<Buffer> {\n return readFileFromAsar(this, file, this.getFile(file))\n }\n\n private newNode() {\n return Object.create(null) as Record<string, Node>\n }\n}\n\nexport async function readAsarHeader(archive: string): Promise<ReadAsarHeader> {\n const fd = await open(archive, \"r\")\n let size: number\n let headerBuf\n try {\n const sizeBuf = Buffer.allocUnsafe(8)\n if ((await read(fd, sizeBuf, 0, 8, null as any)).bytesRead !== 8) {\n throw new Error(\"Unable to read header size\")\n }\n\n const sizePickle = createFromBuffer(sizeBuf)\n size = sizePickle.createIterator().readUInt32()\n headerBuf = Buffer.allocUnsafe(size)\n if ((await read(fd, headerBuf, 0, size, null as any)).bytesRead !== size) {\n throw new Error(\"Unable to read header\")\n }\n } finally {\n await close(fd)\n }\n\n const headerPickle = createFromBuffer(headerBuf)\n return { header: headerPickle.createIterator().readString(), size }\n}\n\nexport async function readAsar(archive: string): Promise<AsarFilesystem> {\n const { header, size } = await readAsarHeader(archive)\n return new AsarFilesystem(archive, JSON.parse(header), size)\n}\n\nexport async function readAsarJson(archive: string, file: string): Promise<any> {\n const fs = await readAsar(archive)\n return await fs.readJson(file)\n}\n\nasync function readFileFromAsar(filesystem: AsarFilesystem, filename: string, info: Node): Promise<Buffer> {\n const size = info.size!\n const buffer = Buffer.allocUnsafe(size)\n if (size <= 0) {\n return buffer\n }\n\n if (info.unpacked) {\n return await readFile(path.join(`${filesystem.src}.unpacked`, filename))\n }\n\n const fd = await open(filesystem.src, \"r\")\n try {\n const offset = 8 + filesystem.headerSize + parseInt(info.offset!, 10)\n await read(fd, buffer, 0, size, offset)\n } finally {\n await close(fd)\n }\n return buffer\n}\n"]}
|
package/out/asar/asarUtil.js
CHANGED
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.AsarPackager = void 0;
|
|
4
4
|
const asar_1 = require("@electron/asar");
|
|
5
5
|
const builder_util_1 = require("builder-util");
|
|
6
|
+
const fs_1 = require("builder-util/out/fs");
|
|
6
7
|
const fs = require("fs-extra");
|
|
7
8
|
const fs_extra_1 = require("fs-extra");
|
|
8
9
|
const path = require("path");
|
|
@@ -10,6 +11,30 @@ const appFileCopier_1 = require("../util/appFileCopier");
|
|
|
10
11
|
const unpackDetector_1 = require("./unpackDetector");
|
|
11
12
|
const stream_1 = require("stream");
|
|
12
13
|
const os = require("os");
|
|
14
|
+
const resolvePath = async (file) => (file && (await (0, fs_1.exists)(file)) ? fs.realpath(file).catch(() => path.resolve(file)) : undefined);
|
|
15
|
+
const resolvePaths = async (filepaths) => {
|
|
16
|
+
return Promise.all(filepaths.map(resolvePath)).then(paths => paths.filter((it) => it != null));
|
|
17
|
+
};
|
|
18
|
+
const DENYLIST = resolvePaths([
|
|
19
|
+
"/usr",
|
|
20
|
+
"/lib",
|
|
21
|
+
"/bin",
|
|
22
|
+
"/sbin",
|
|
23
|
+
"/etc",
|
|
24
|
+
"/tmp",
|
|
25
|
+
"/var", // block whole /var by default. If $HOME is under /var, it's explicitly in ALLOWLIST - https://github.com/electron-userland/electron-builder/issues/9025#issuecomment-3575380041
|
|
26
|
+
// macOS system directories
|
|
27
|
+
"/System",
|
|
28
|
+
"/Library",
|
|
29
|
+
"/private",
|
|
30
|
+
// Windows system directories
|
|
31
|
+
process.env.SystemRoot,
|
|
32
|
+
process.env.WINDIR,
|
|
33
|
+
]);
|
|
34
|
+
const ALLOWLIST = resolvePaths([
|
|
35
|
+
os.tmpdir(), // always allow temp dir
|
|
36
|
+
os.homedir(), // always allow home dir
|
|
37
|
+
]);
|
|
13
38
|
/** @internal */
|
|
14
39
|
class AsarPackager {
|
|
15
40
|
constructor(packager, config) {
|
|
@@ -48,6 +73,7 @@ class AsarPackager {
|
|
|
48
73
|
}
|
|
49
74
|
}
|
|
50
75
|
const results = [];
|
|
76
|
+
const resultsPaths = new Set();
|
|
51
77
|
for (const fileSet of fileSets) {
|
|
52
78
|
// Don't use Promise.all, we need to retain order of execution/iteration through the already-ordered fileset
|
|
53
79
|
for (const [index, file] of fileSet.files.entries()) {
|
|
@@ -62,7 +88,7 @@ class AsarPackager {
|
|
|
62
88
|
const isFileUnpacked = (_c = (_b = (_a = this.config).unpackPattern) === null || _b === void 0 ? void 0 : _b.call(_a, file, stat)) !== null && _c !== void 0 ? _c : false;
|
|
63
89
|
return isChild || isFileUnpacked;
|
|
64
90
|
};
|
|
65
|
-
this.processParentDirectories(isUnpacked, destination, results);
|
|
91
|
+
this.processParentDirectories(isUnpacked, destination, results, resultsPaths);
|
|
66
92
|
const result = await this.processFileOrSymlink({
|
|
67
93
|
file,
|
|
68
94
|
destination,
|
|
@@ -73,12 +99,13 @@ class AsarPackager {
|
|
|
73
99
|
});
|
|
74
100
|
if (result != null) {
|
|
75
101
|
results.push(result);
|
|
102
|
+
resultsPaths.add(result.path);
|
|
76
103
|
}
|
|
77
104
|
}
|
|
78
105
|
}
|
|
79
106
|
return results;
|
|
80
107
|
}
|
|
81
|
-
processParentDirectories(isUnpacked, destination, results) {
|
|
108
|
+
processParentDirectories(isUnpacked, destination, results, resultsPaths) {
|
|
82
109
|
// process parent directories
|
|
83
110
|
let superDir = path.dirname(path.normalize(destination));
|
|
84
111
|
while (superDir !== ".") {
|
|
@@ -88,8 +115,9 @@ class AsarPackager {
|
|
|
88
115
|
unpacked: isUnpacked(superDir),
|
|
89
116
|
};
|
|
90
117
|
// add to results if not already present
|
|
91
|
-
if (!
|
|
118
|
+
if (!resultsPaths.has(dir.path)) {
|
|
92
119
|
results.push(dir);
|
|
120
|
+
resultsPaths.add(dir.path);
|
|
93
121
|
}
|
|
94
122
|
superDir = path.dirname(superDir);
|
|
95
123
|
}
|
|
@@ -114,7 +142,7 @@ class AsarPackager {
|
|
|
114
142
|
return { path: destination, streamGenerator, unpacked, type: "file", stat: { mode: stat.mode, size } };
|
|
115
143
|
}
|
|
116
144
|
// verify that the file is not a direct link or symlinked to access/copy a system file
|
|
117
|
-
await this.protectSystemAndUnsafePaths(file);
|
|
145
|
+
await this.protectSystemAndUnsafePaths(file, await this.packager.info.getWorkspaceRoot());
|
|
118
146
|
const config = {
|
|
119
147
|
path: destination,
|
|
120
148
|
streamGenerator: () => fs.createReadStream(file),
|
|
@@ -128,8 +156,6 @@ class AsarPackager {
|
|
|
128
156
|
type: "file",
|
|
129
157
|
};
|
|
130
158
|
}
|
|
131
|
-
// guard against symlink pointing to outside workspace root
|
|
132
|
-
await this.protectSystemAndUnsafePaths(file, await this.packager.info.getWorkspaceRoot());
|
|
133
159
|
// okay, it must be a symlink. evaluate link to be relative to source file in asar
|
|
134
160
|
let link = await (0, fs_extra_1.readlink)(file);
|
|
135
161
|
if (path.isAbsolute(link)) {
|
|
@@ -184,75 +210,42 @@ class AsarPackager {
|
|
|
184
210
|
transformedFiles,
|
|
185
211
|
};
|
|
186
212
|
}
|
|
187
|
-
async
|
|
188
|
-
const
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
"/sbin",
|
|
194
|
-
"/System",
|
|
195
|
-
"/Library",
|
|
196
|
-
"/private/etc",
|
|
197
|
-
"/private/var/db",
|
|
198
|
-
"/private/var/root",
|
|
199
|
-
"/private/var/log",
|
|
200
|
-
"/private/tmp",
|
|
201
|
-
// macOS legacy symlinks
|
|
202
|
-
"/etc",
|
|
203
|
-
"/var",
|
|
204
|
-
"/tmp",
|
|
205
|
-
// Windows
|
|
206
|
-
process.env.SystemRoot,
|
|
207
|
-
process.env.WINDIR,
|
|
208
|
-
// process.env.ProgramFiles,
|
|
209
|
-
// process.env["ProgramFiles(x86)"],
|
|
210
|
-
// process.env.ProgramData,
|
|
211
|
-
// process.env.CommonProgramFiles,
|
|
212
|
-
// process.env["CommonProgramFiles(x86)"],
|
|
213
|
-
]
|
|
214
|
-
.filter(Boolean)
|
|
215
|
-
.map(p => path.resolve(p));
|
|
216
|
-
// Normalize to real paths to prevent symlink bypasses
|
|
217
|
-
const resolvedPaths = [];
|
|
218
|
-
for (const p of systemPaths) {
|
|
219
|
-
try {
|
|
220
|
-
resolvedPaths.push(await fs.realpath(p));
|
|
221
|
-
}
|
|
222
|
-
catch {
|
|
223
|
-
resolvedPaths.push(path.resolve(p));
|
|
213
|
+
async checkAgainstRoots(target, allowRoots) {
|
|
214
|
+
const resolved = await resolvePath(target);
|
|
215
|
+
for (const root of allowRoots) {
|
|
216
|
+
const resolvedRoot = root;
|
|
217
|
+
if (resolved === resolvedRoot || (resolved === null || resolved === void 0 ? void 0 : resolved.startsWith(resolvedRoot + path.sep))) {
|
|
218
|
+
return true;
|
|
224
219
|
}
|
|
225
220
|
}
|
|
226
|
-
return
|
|
221
|
+
return false;
|
|
227
222
|
}
|
|
228
223
|
async protectSystemAndUnsafePaths(file, workspaceRoot) {
|
|
229
|
-
const resolved = await
|
|
230
|
-
const
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
// Allow temp & cache folders
|
|
238
|
-
const tmpdir = await fs.realpath(os.tmpdir());
|
|
239
|
-
if (resolved.startsWith(tmpdir)) {
|
|
224
|
+
const resolved = await resolvePath(file);
|
|
225
|
+
const logFields = { source: file, realPath: resolved };
|
|
226
|
+
const isUnsafe = async () => {
|
|
227
|
+
const workspace = await resolvePath(workspaceRoot);
|
|
228
|
+
if (workspace && (resolved === null || resolved === void 0 ? void 0 : resolved.startsWith(workspace))) {
|
|
229
|
+
// if in workspace, always safe
|
|
240
230
|
return false;
|
|
241
231
|
}
|
|
242
|
-
const
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
232
|
+
const allowed = await this.checkAgainstRoots(file, await ALLOWLIST);
|
|
233
|
+
if (allowed) {
|
|
234
|
+
return false; // allowlist is priority
|
|
235
|
+
}
|
|
236
|
+
const denied = await this.checkAgainstRoots(file, await DENYLIST);
|
|
237
|
+
if (denied) {
|
|
238
|
+
builder_util_1.log.error(logFields, `denied access to system or unsafe path`);
|
|
239
|
+
return true;
|
|
247
240
|
}
|
|
241
|
+
// default
|
|
242
|
+
builder_util_1.log.debug(logFields, `path is outside of explicit safe paths, defaulting to safe`);
|
|
248
243
|
return false;
|
|
249
244
|
};
|
|
250
|
-
const unsafe = await
|
|
245
|
+
const unsafe = await isUnsafe();
|
|
251
246
|
if (unsafe) {
|
|
252
|
-
builder_util_1.log.error({ source: file, realPath: resolved }, `unable to copy, file is from outside the package to a system or unsafe path`);
|
|
253
247
|
throw new Error(`Cannot copy file [${file}] symlinked to file [${resolved}] outside the package to a system or unsafe path`);
|
|
254
248
|
}
|
|
255
|
-
return unsafe;
|
|
256
249
|
}
|
|
257
250
|
}
|
|
258
251
|
exports.AsarPackager = AsarPackager;
|
package/out/asar/asarUtil.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"asarUtil.js","sourceRoot":"","sources":["../../src/asar/asarUtil.ts"],"names":[],"mappings":"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","sourcesContent":["import { createPackageFromStreams, AsarStreamType, AsarDirectory } from \"@electron/asar\"\nimport { log } from \"builder-util\"\nimport { Filter } from \"builder-util/out/fs\"\nimport * as fs from \"fs-extra\"\nimport { readlink } from \"fs-extra\"\nimport * as path from \"path\"\nimport { AsarOptions } from \"../options/PlatformSpecificBuildOptions\"\nimport { PlatformPackager } from \"../platformPackager\"\nimport { ResolvedFileSet, getDestinationPath } from \"../util/appFileCopier\"\nimport { detectUnpackedDirs } from \"./unpackDetector\"\nimport { Readable } from \"stream\"\nimport * as os from \"os\"\n\n/** @internal */\nexport class AsarPackager {\n private readonly outFile: string\n\n constructor(\n readonly packager: PlatformPackager<any>,\n private readonly config: {\n defaultDestination: string\n resourcePath: string\n options: AsarOptions\n unpackPattern: Filter | undefined\n }\n ) {\n this.outFile = path.join(config.resourcePath, `app.asar`)\n }\n\n async pack(fileSets: Array<ResolvedFileSet>) {\n const orderedFileSets = [\n // Write dependencies first to minimize offset changes to asar header\n ...fileSets.slice(1),\n\n // Finish with the app files that change most often\n fileSets[0],\n ].map(set => this.orderFileSet(set))\n\n const streams = await this.processFileSets(orderedFileSets)\n await this.executeElectronAsar(streams)\n }\n\n private async executeElectronAsar(streams: AsarStreamType[]) {\n // override logger temporarily to clean up console (electron/asar does some internal logging that blogs up the default electron-builder logs)\n const consoleLogger = console.log\n console.log = (...args) => {\n if (args[0] === \"Ordering file has 100% coverage.\") {\n return // no need to log, this means our ordering logic is working correctly\n }\n log.info({ args }, \"logging @electron/asar\")\n }\n await createPackageFromStreams(this.outFile, streams)\n console.log = consoleLogger\n }\n\n private async processFileSets(fileSets: ResolvedFileSet[]): Promise<AsarStreamType[]> {\n const unpackedPaths = new Set<string>()\n if (this.config.options.smartUnpack !== false) {\n for (const fileSet of fileSets) {\n detectUnpackedDirs(fileSet, unpackedPaths)\n }\n }\n\n const results: AsarStreamType[] = []\n for (const fileSet of fileSets) {\n // Don't use Promise.all, we need to retain order of execution/iteration through the already-ordered fileset\n for (const [index, file] of fileSet.files.entries()) {\n const transformedData = fileSet.transformedFiles?.get(index)\n const stat = fileSet.metadata.get(file)!\n const destination = path.relative(this.config.defaultDestination, getDestinationPath(file, fileSet))\n\n const paths = Array.from(unpackedPaths).map(p => path.normalize(p))\n\n const isChildDirectory = (fileOrDirPath: string) =>\n paths.includes(path.normalize(fileOrDirPath)) || paths.some(unpackedPath => path.normalize(fileOrDirPath).startsWith(unpackedPath + path.sep))\n const isUnpacked = (dir: string) => {\n const isChild = isChildDirectory(dir)\n const isFileUnpacked = this.config.unpackPattern?.(file, stat) ?? false\n return isChild || isFileUnpacked\n }\n\n this.processParentDirectories(isUnpacked, destination, results)\n\n const result = await this.processFileOrSymlink({\n file,\n destination,\n fileSet,\n transformedData,\n stat,\n isUnpacked,\n })\n if (result != null) {\n results.push(result)\n }\n }\n }\n return results\n }\n\n private processParentDirectories(isUnpacked: (path: string) => boolean, destination: string, results: AsarStreamType[]) {\n // process parent directories\n let superDir = path.dirname(path.normalize(destination))\n while (superDir !== \".\") {\n const dir: AsarDirectory = {\n type: \"directory\",\n path: superDir,\n unpacked: isUnpacked(superDir),\n }\n // add to results if not already present\n if (!results.some(r => r.path === dir.path)) {\n results.push(dir)\n }\n\n superDir = path.dirname(superDir)\n }\n }\n\n private async processFileOrSymlink(options: {\n file: string\n destination: string\n stat: fs.Stats\n fileSet: ResolvedFileSet\n transformedData: string | Buffer | undefined\n isUnpacked: (path: string) => boolean\n }): Promise<AsarStreamType> {\n const { isUnpacked, transformedData, file, destination, stat } = options\n const unpacked = isUnpacked(destination)\n\n if (!stat.isFile() && !stat.isSymbolicLink()) {\n return { path: destination, unpacked, type: \"directory\" }\n }\n\n // write any data if provided, skip symlink check\n if (transformedData != null) {\n const streamGenerator = () => {\n return new Readable({\n read() {\n this.push(transformedData)\n this.push(null)\n },\n })\n }\n const size = Buffer.byteLength(transformedData)\n return { path: destination, streamGenerator, unpacked, type: \"file\", stat: { mode: stat.mode, size } }\n }\n\n // verify that the file is not a direct link or symlinked to access/copy a system file\n await this.protectSystemAndUnsafePaths(file)\n\n const config = {\n path: destination,\n streamGenerator: () => fs.createReadStream(file),\n unpacked,\n stat,\n }\n\n // file, stream directly\n if (!stat.isSymbolicLink()) {\n return {\n ...config,\n type: \"file\",\n }\n }\n\n // guard against symlink pointing to outside workspace root\n await this.protectSystemAndUnsafePaths(file, await this.packager.info.getWorkspaceRoot())\n\n // okay, it must be a symlink. evaluate link to be relative to source file in asar\n let link = await readlink(file)\n if (path.isAbsolute(link)) {\n link = path.relative(path.dirname(file), link)\n }\n return {\n ...config,\n type: \"link\",\n symlink: link,\n }\n }\n\n private orderFileSet(fileSet: ResolvedFileSet): ResolvedFileSet {\n const sortedFileEntries = Array.from(fileSet.files.entries())\n\n sortedFileEntries.sort(([, a], [, b]) => {\n if (a === b) {\n return 0\n }\n\n // Place addons last because their signature changes per build\n const isAAddon = a.endsWith(\".node\")\n const isBAddon = b.endsWith(\".node\")\n if (isAAddon && !isBAddon) {\n return 1\n }\n if (isBAddon && !isAAddon) {\n return -1\n }\n\n // Otherwise order by name\n return a < b ? -1 : 1\n })\n\n let transformedFiles: Map<number, string | Buffer> | undefined\n if (fileSet.transformedFiles) {\n transformedFiles = new Map()\n\n const indexMap = new Map<number, number>()\n for (const [newIndex, [oldIndex]] of sortedFileEntries.entries()) {\n indexMap.set(oldIndex, newIndex)\n }\n\n for (const [oldIndex, value] of fileSet.transformedFiles) {\n const newIndex = indexMap.get(oldIndex)\n if (newIndex === undefined) {\n const file = fileSet.files[oldIndex]\n throw new Error(`Internal error: ${file} was lost while ordering asar`)\n }\n\n transformedFiles.set(newIndex, value)\n }\n }\n\n const { src, destination, metadata } = fileSet\n\n return {\n src,\n destination,\n metadata,\n files: sortedFileEntries.map(([, file]) => file),\n transformedFiles,\n }\n }\n\n private async getProtectedPaths(): Promise<string[]> {\n const systemPaths = [\n // Generic *nix\n \"/usr\",\n \"/lib\",\n \"/bin\",\n \"/sbin\",\n \"/System\",\n \"/Library\",\n \"/private/etc\",\n \"/private/var/db\",\n \"/private/var/root\",\n \"/private/var/log\",\n \"/private/tmp\",\n\n // macOS legacy symlinks\n \"/etc\",\n \"/var\",\n \"/tmp\",\n\n // Windows\n process.env.SystemRoot,\n process.env.WINDIR,\n // process.env.ProgramFiles,\n // process.env[\"ProgramFiles(x86)\"],\n // process.env.ProgramData,\n // process.env.CommonProgramFiles,\n // process.env[\"CommonProgramFiles(x86)\"],\n ]\n .filter(Boolean)\n .map(p => path.resolve(p as string))\n\n // Normalize to real paths to prevent symlink bypasses\n const resolvedPaths: string[] = []\n for (const p of systemPaths) {\n try {\n resolvedPaths.push(await fs.realpath(p))\n } catch {\n resolvedPaths.push(path.resolve(p))\n }\n }\n\n return resolvedPaths\n }\n\n private async protectSystemAndUnsafePaths(file: string, workspaceRoot?: string): Promise<boolean> {\n const resolved = await fs.realpath(file).catch(() => path.resolve(file))\n\n const scan = async () => {\n if (workspaceRoot) {\n const workspace = path.resolve(workspaceRoot)\n\n if (!resolved.startsWith(workspace)) {\n return true\n }\n }\n\n // Allow temp & cache folders\n const tmpdir = await fs.realpath(os.tmpdir())\n if (resolved.startsWith(tmpdir)) {\n return false\n }\n\n const blockedSystemPaths = await this.getProtectedPaths()\n for (const sys of blockedSystemPaths) {\n if (resolved.startsWith(sys)) {\n return true\n }\n }\n\n return false\n }\n\n const unsafe = await scan()\n\n if (unsafe) {\n log.error({ source: file, realPath: resolved }, `unable to copy, file is from outside the package to a system or unsafe path`)\n throw new Error(`Cannot copy file [${file}] symlinked to file [${resolved}] outside the package to a system or unsafe path`)\n }\n return unsafe\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"asarUtil.js","sourceRoot":"","sources":["../../src/asar/asarUtil.ts"],"names":[],"mappings":"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","sourcesContent":["import { createPackageFromStreams, AsarStreamType, AsarDirectory } from \"@electron/asar\"\nimport { log } from \"builder-util\"\nimport { exists, Filter } from \"builder-util/out/fs\"\nimport * as fs from \"fs-extra\"\nimport { readlink } from \"fs-extra\"\nimport * as path from \"path\"\nimport { AsarOptions } from \"../options/PlatformSpecificBuildOptions\"\nimport { PlatformPackager } from \"../platformPackager\"\nimport { ResolvedFileSet, getDestinationPath } from \"../util/appFileCopier\"\nimport { detectUnpackedDirs } from \"./unpackDetector\"\nimport { Readable } from \"stream\"\nimport * as os from \"os\"\n\nconst resolvePath = async (file: string | undefined): Promise<string | undefined> => (file && (await exists(file)) ? fs.realpath(file).catch(() => path.resolve(file)) : undefined)\nconst resolvePaths = async (filepaths: (string | undefined)[]) => {\n return Promise.all(filepaths.map(resolvePath)).then(paths => paths.filter((it): it is string => it != null))\n}\n\nconst DENYLIST = resolvePaths([\n \"/usr\",\n \"/lib\",\n \"/bin\",\n \"/sbin\",\n \"/etc\",\n\n \"/tmp\",\n \"/var\", // block whole /var by default. If $HOME is under /var, it's explicitly in ALLOWLIST - https://github.com/electron-userland/electron-builder/issues/9025#issuecomment-3575380041\n\n // macOS system directories\n \"/System\",\n \"/Library\",\n \"/private\",\n\n // Windows system directories\n process.env.SystemRoot,\n process.env.WINDIR,\n])\n\nconst ALLOWLIST = resolvePaths([\n os.tmpdir(), // always allow temp dir\n os.homedir(), // always allow home dir\n])\n\n/** @internal */\nexport class AsarPackager {\n private readonly outFile: string\n\n constructor(\n readonly packager: PlatformPackager<any>,\n private readonly config: {\n defaultDestination: string\n resourcePath: string\n options: AsarOptions\n unpackPattern: Filter | undefined\n }\n ) {\n this.outFile = path.join(config.resourcePath, `app.asar`)\n }\n\n async pack(fileSets: Array<ResolvedFileSet>) {\n const orderedFileSets = [\n // Write dependencies first to minimize offset changes to asar header\n ...fileSets.slice(1),\n\n // Finish with the app files that change most often\n fileSets[0],\n ].map(set => this.orderFileSet(set))\n\n const streams = await this.processFileSets(orderedFileSets)\n await this.executeElectronAsar(streams)\n }\n\n private async executeElectronAsar(streams: AsarStreamType[]) {\n // override logger temporarily to clean up console (electron/asar does some internal logging that blogs up the default electron-builder logs)\n const consoleLogger = console.log\n console.log = (...args) => {\n if (args[0] === \"Ordering file has 100% coverage.\") {\n return // no need to log, this means our ordering logic is working correctly\n }\n log.info({ args }, \"logging @electron/asar\")\n }\n await createPackageFromStreams(this.outFile, streams)\n console.log = consoleLogger\n }\n\n private async processFileSets(fileSets: ResolvedFileSet[]): Promise<AsarStreamType[]> {\n const unpackedPaths = new Set<string>()\n if (this.config.options.smartUnpack !== false) {\n for (const fileSet of fileSets) {\n detectUnpackedDirs(fileSet, unpackedPaths)\n }\n }\n\n const results: AsarStreamType[] = []\n const resultsPaths = new Set<string>()\n for (const fileSet of fileSets) {\n // Don't use Promise.all, we need to retain order of execution/iteration through the already-ordered fileset\n for (const [index, file] of fileSet.files.entries()) {\n const transformedData = fileSet.transformedFiles?.get(index)\n const stat = fileSet.metadata.get(file)!\n const destination = path.relative(this.config.defaultDestination, getDestinationPath(file, fileSet))\n\n const paths = Array.from(unpackedPaths).map(p => path.normalize(p))\n\n const isChildDirectory = (fileOrDirPath: string) =>\n paths.includes(path.normalize(fileOrDirPath)) || paths.some(unpackedPath => path.normalize(fileOrDirPath).startsWith(unpackedPath + path.sep))\n const isUnpacked = (dir: string) => {\n const isChild = isChildDirectory(dir)\n const isFileUnpacked = this.config.unpackPattern?.(file, stat) ?? false\n return isChild || isFileUnpacked\n }\n\n this.processParentDirectories(isUnpacked, destination, results, resultsPaths)\n\n const result = await this.processFileOrSymlink({\n file,\n destination,\n fileSet,\n transformedData,\n stat,\n isUnpacked,\n })\n if (result != null) {\n results.push(result)\n resultsPaths.add(result.path)\n }\n }\n }\n return results\n }\n\n private processParentDirectories(isUnpacked: (path: string) => boolean, destination: string, results: AsarStreamType[], resultsPaths: Set<string>) {\n // process parent directories\n let superDir = path.dirname(path.normalize(destination))\n while (superDir !== \".\") {\n const dir: AsarDirectory = {\n type: \"directory\",\n path: superDir,\n unpacked: isUnpacked(superDir),\n }\n // add to results if not already present\n if (!resultsPaths.has(dir.path)) {\n results.push(dir)\n resultsPaths.add(dir.path)\n }\n\n superDir = path.dirname(superDir)\n }\n }\n\n private async processFileOrSymlink(options: {\n file: string\n destination: string\n stat: fs.Stats\n fileSet: ResolvedFileSet\n transformedData: string | Buffer | undefined\n isUnpacked: (path: string) => boolean\n }): Promise<AsarStreamType> {\n const { isUnpacked, transformedData, file, destination, stat } = options\n const unpacked = isUnpacked(destination)\n\n if (!stat.isFile() && !stat.isSymbolicLink()) {\n return { path: destination, unpacked, type: \"directory\" }\n }\n\n // write any data if provided, skip symlink check\n if (transformedData != null) {\n const streamGenerator = () => {\n return new Readable({\n read() {\n this.push(transformedData)\n this.push(null)\n },\n })\n }\n const size = Buffer.byteLength(transformedData)\n return { path: destination, streamGenerator, unpacked, type: \"file\", stat: { mode: stat.mode, size } }\n }\n\n // verify that the file is not a direct link or symlinked to access/copy a system file\n await this.protectSystemAndUnsafePaths(file, await this.packager.info.getWorkspaceRoot())\n\n const config = {\n path: destination,\n streamGenerator: () => fs.createReadStream(file),\n unpacked,\n stat,\n }\n\n // file, stream directly\n if (!stat.isSymbolicLink()) {\n return {\n ...config,\n type: \"file\",\n }\n }\n\n // okay, it must be a symlink. evaluate link to be relative to source file in asar\n let link = await readlink(file)\n if (path.isAbsolute(link)) {\n link = path.relative(path.dirname(file), link)\n }\n return {\n ...config,\n type: \"link\",\n symlink: link,\n }\n }\n\n private orderFileSet(fileSet: ResolvedFileSet): ResolvedFileSet {\n const sortedFileEntries = Array.from(fileSet.files.entries())\n\n sortedFileEntries.sort(([, a], [, b]) => {\n if (a === b) {\n return 0\n }\n\n // Place addons last because their signature changes per build\n const isAAddon = a.endsWith(\".node\")\n const isBAddon = b.endsWith(\".node\")\n if (isAAddon && !isBAddon) {\n return 1\n }\n if (isBAddon && !isAAddon) {\n return -1\n }\n\n // Otherwise order by name\n return a < b ? -1 : 1\n })\n\n let transformedFiles: Map<number, string | Buffer> | undefined\n if (fileSet.transformedFiles) {\n transformedFiles = new Map()\n\n const indexMap = new Map<number, number>()\n for (const [newIndex, [oldIndex]] of sortedFileEntries.entries()) {\n indexMap.set(oldIndex, newIndex)\n }\n\n for (const [oldIndex, value] of fileSet.transformedFiles) {\n const newIndex = indexMap.get(oldIndex)\n if (newIndex === undefined) {\n const file = fileSet.files[oldIndex]\n throw new Error(`Internal error: ${file} was lost while ordering asar`)\n }\n\n transformedFiles.set(newIndex, value)\n }\n }\n\n const { src, destination, metadata } = fileSet\n\n return {\n src,\n destination,\n metadata,\n files: sortedFileEntries.map(([, file]) => file),\n transformedFiles,\n }\n }\n\n private async checkAgainstRoots(target: string, allowRoots: string[]): Promise<boolean> {\n const resolved = await resolvePath(target)\n\n for (const root of allowRoots) {\n const resolvedRoot = root\n if (resolved === resolvedRoot || resolved?.startsWith(resolvedRoot + path.sep)) {\n return true\n }\n }\n return false\n }\n\n private async protectSystemAndUnsafePaths(file: string, workspaceRoot: string): Promise<void> {\n const resolved = await resolvePath(file)\n const logFields = { source: file, realPath: resolved }\n\n const isUnsafe = async () => {\n const workspace = await resolvePath(workspaceRoot)\n\n if (workspace && resolved?.startsWith(workspace)) {\n // if in workspace, always safe\n return false\n }\n\n const allowed = await this.checkAgainstRoots(file, await ALLOWLIST)\n if (allowed) {\n return false // allowlist is priority\n }\n\n const denied = await this.checkAgainstRoots(file, await DENYLIST)\n if (denied) {\n log.error(logFields, `denied access to system or unsafe path`)\n return true\n }\n // default\n log.debug(logFields, `path is outside of explicit safe paths, defaulting to safe`)\n return false\n }\n\n const unsafe = await isUnsafe()\n\n if (unsafe) {\n throw new Error(`Cannot copy file [${file}] symlinked to file [${resolved}] outside the package to a system or unsafe path`)\n }\n }\n}\n"]}
|
|
@@ -13,7 +13,10 @@ export type ModuleCache = {
|
|
|
13
13
|
/** Cache for lstat results */
|
|
14
14
|
lstat: Map<string, fs.Stats>;
|
|
15
15
|
/** Cache for require.resolve results (key: "packageName::fromDir") */
|
|
16
|
-
requireResolve: Map<string,
|
|
16
|
+
requireResolve: Map<string, {
|
|
17
|
+
entry: string;
|
|
18
|
+
packageDir: string;
|
|
19
|
+
} | null>;
|
|
17
20
|
};
|
|
18
21
|
/**
|
|
19
22
|
* Creates a new empty ModuleCache instance
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"moduleCache.js","sourceRoot":"","sources":["../../src/node-module-collector/moduleCache.ts"],"names":[],"mappings":";;AAsBA,8CAQC;AAXD;;GAEG;AACH,SAAgB,iBAAiB;IAC/B,OAAO;QACL,WAAW,EAAE,IAAI,GAAG,EAAE;QACtB,QAAQ,EAAE,IAAI,GAAG,EAAE;QACnB,MAAM,EAAE,IAAI,GAAG,EAAE;QACjB,KAAK,EAAE,IAAI,GAAG,EAAE;QAChB,cAAc,EAAE,IAAI,GAAG,EAAE;KAC1B,CAAA;AACH,CAAC","sourcesContent":["import * as fs from \"fs\"\nimport { PackageJson } from \"./types\"\n\n/**\n * Unified cache for all file system and module resolution operations\n */\nexport type ModuleCache = {\n /** Cache for package.json contents (readJson/require) */\n packageJson: Map<string, PackageJson>\n /** Cache for resolved real paths (realpath) */\n realPath: Map<string, string>\n /** Cache for file/directory existence checks */\n exists: Map<string, boolean>\n /** Cache for lstat results */\n lstat: Map<string, fs.Stats>\n /** Cache for require.resolve results (key: \"packageName::fromDir\") */\n requireResolve: Map<string, string | null>\n}\n\n/**\n * Creates a new empty ModuleCache instance\n */\nexport function createModuleCache(): ModuleCache {\n return {\n packageJson: new Map(),\n realPath: new Map(),\n exists: new Map(),\n lstat: new Map(),\n requireResolve: new Map(),\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"moduleCache.js","sourceRoot":"","sources":["../../src/node-module-collector/moduleCache.ts"],"names":[],"mappings":";;AAsBA,8CAQC;AAXD;;GAEG;AACH,SAAgB,iBAAiB;IAC/B,OAAO;QACL,WAAW,EAAE,IAAI,GAAG,EAAE;QACtB,QAAQ,EAAE,IAAI,GAAG,EAAE;QACnB,MAAM,EAAE,IAAI,GAAG,EAAE;QACjB,KAAK,EAAE,IAAI,GAAG,EAAE;QAChB,cAAc,EAAE,IAAI,GAAG,EAAE;KAC1B,CAAA;AACH,CAAC","sourcesContent":["import * as fs from \"fs\"\nimport { PackageJson } from \"./types\"\n\n/**\n * Unified cache for all file system and module resolution operations\n */\nexport type ModuleCache = {\n /** Cache for package.json contents (readJson/require) */\n packageJson: Map<string, PackageJson>\n /** Cache for resolved real paths (realpath) */\n realPath: Map<string, string>\n /** Cache for file/directory existence checks */\n exists: Map<string, boolean>\n /** Cache for lstat results */\n lstat: Map<string, fs.Stats>\n /** Cache for require.resolve results (key: \"packageName::fromDir\") */\n requireResolve: Map<string, { entry: string; packageDir: string } | null>\n}\n\n/**\n * Creates a new empty ModuleCache instance\n */\nexport function createModuleCache(): ModuleCache {\n return {\n packageJson: new Map(),\n realPath: new Map(),\n exists: new Map(),\n lstat: new Map(),\n requireResolve: new Map(),\n }\n}\n"]}
|
|
@@ -2,20 +2,16 @@ import { TmpDir } from "builder-util";
|
|
|
2
2
|
import { CancellationToken } from "builder-util-runtime";
|
|
3
3
|
import * as fs from "fs-extra";
|
|
4
4
|
import { Lazy } from "lazy-val";
|
|
5
|
-
import { type ModuleCache } from "./moduleCache";
|
|
6
5
|
import { PM } from "./packageManager";
|
|
7
6
|
import type { Dependency, DependencyGraph, NodeModuleInfo, PackageJson } from "./types";
|
|
8
7
|
export declare abstract class NodeModulesCollector<ProdDepType extends Dependency<ProdDepType, OptionalDepType>, OptionalDepType> {
|
|
9
8
|
protected readonly rootDir: string;
|
|
10
9
|
private readonly tempDirManager;
|
|
11
|
-
private nodeModules;
|
|
12
|
-
protected allDependencies: Map<string, ProdDepType>;
|
|
13
|
-
protected productionGraph: DependencyGraph;
|
|
14
|
-
|
|
15
|
-
protected
|
|
16
|
-
private importMetaResolve;
|
|
17
|
-
protected cache: ModuleCache;
|
|
18
|
-
protected isHoisted: Lazy<boolean>;
|
|
10
|
+
private readonly nodeModules;
|
|
11
|
+
protected readonly allDependencies: Map<string, ProdDepType>;
|
|
12
|
+
protected readonly productionGraph: DependencyGraph;
|
|
13
|
+
private readonly cache;
|
|
14
|
+
protected readonly isHoisted: Lazy<boolean>;
|
|
19
15
|
protected appPkgJson: Lazy<PackageJson>;
|
|
20
16
|
constructor(rootDir: string, tempDirManager: TmpDir);
|
|
21
17
|
getNodeModules({ cancellationToken, packageName }: {
|
|
@@ -35,14 +31,19 @@ export declare abstract class NodeModulesCollector<ProdDepType extends Dependenc
|
|
|
35
31
|
protected readJsonMemoized(filePath: string): Promise<PackageJson>;
|
|
36
32
|
protected lstatMemoized(filePath: string): Promise<fs.Stats>;
|
|
37
33
|
protected realpathMemoized(filePath: string): Promise<string>;
|
|
34
|
+
protected requireMemoized(pkgPath: string): PackageJson;
|
|
35
|
+
protected existsSyncMemoized(filePath: string): boolean;
|
|
38
36
|
protected resolvePath(filePath: string): Promise<string>;
|
|
39
37
|
/**
|
|
40
|
-
*
|
|
41
|
-
*
|
|
38
|
+
* Resolve a package directory purely from the filesystem.
|
|
39
|
+
* Does NOT attempt to load the module or resolve an "exports" entrypoint.
|
|
40
|
+
* Good for Yarn 4 because a package may not be resolvable as a module,
|
|
41
|
+
* but still exists on disk.
|
|
42
42
|
*/
|
|
43
|
-
protected
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
protected resolvePackage(packageName: string, fromDir: string): Promise<{
|
|
44
|
+
entry: string;
|
|
45
|
+
packageDir: string;
|
|
46
|
+
} | null>;
|
|
46
47
|
protected cacheKey(pkg: ProdDepType): string;
|
|
47
48
|
protected packageVersionString(pkg: ProdDepType): string;
|
|
48
49
|
/**
|
|
@@ -10,7 +10,6 @@ const path = require("path");
|
|
|
10
10
|
const hoist_1 = require("./hoist");
|
|
11
11
|
const moduleCache_1 = require("./moduleCache");
|
|
12
12
|
const packageManager_1 = require("./packageManager");
|
|
13
|
-
const node_url_1 = require("node:url");
|
|
14
13
|
class NodeModulesCollector {
|
|
15
14
|
constructor(rootDir, tempDirManager) {
|
|
16
15
|
this.rootDir = rootDir;
|
|
@@ -18,26 +17,14 @@ class NodeModulesCollector {
|
|
|
18
17
|
this.nodeModules = [];
|
|
19
18
|
this.allDependencies = new Map();
|
|
20
19
|
this.productionGraph = {};
|
|
21
|
-
this.pkgJsonCache = new Map();
|
|
22
|
-
this.memoResolvedModules = new Map();
|
|
23
|
-
this.importMetaResolve = new lazy_val_1.Lazy(async () => {
|
|
24
|
-
try {
|
|
25
|
-
// Node >= 16 builtin ESM-aware resolver
|
|
26
|
-
const packageName = "import-meta-resolve";
|
|
27
|
-
const imported = await Promise.resolve(`${packageName}`).then(s => require(s));
|
|
28
|
-
return imported.resolve;
|
|
29
|
-
}
|
|
30
|
-
catch {
|
|
31
|
-
return null;
|
|
32
|
-
}
|
|
33
|
-
});
|
|
34
20
|
// Unified cache for all file system and module operations
|
|
35
21
|
this.cache = (0, moduleCache_1.createModuleCache)();
|
|
36
22
|
this.isHoisted = new lazy_val_1.Lazy(async () => {
|
|
23
|
+
var _a;
|
|
37
24
|
const { manager } = this.installOptions;
|
|
38
25
|
const command = (0, packageManager_1.getPackageManagerCommand)(manager);
|
|
39
|
-
const config = (await this.asyncExec(command, ["config", "list"])).stdout;
|
|
40
|
-
if (
|
|
26
|
+
const config = (_a = (await this.asyncExec(command, ["config", "list"])).stdout) === null || _a === void 0 ? void 0 : _a.trim();
|
|
27
|
+
if ((0, builder_util_1.isEmptyOrSpaces)(config)) {
|
|
41
28
|
builder_util_1.log.debug({ manager }, "unable to determine if node_modules are hoisted: no config output. falling back to hoisted mode");
|
|
42
29
|
return false;
|
|
43
30
|
}
|
|
@@ -64,7 +51,9 @@ class NodeModulesCollector {
|
|
|
64
51
|
if (cancellationToken.cancelled) {
|
|
65
52
|
throw new Error("getNodeModules cancelled after building production graph");
|
|
66
53
|
}
|
|
67
|
-
const hoisterResult = (0, hoist_1.hoist)(this.transformToHoisterTree(this.productionGraph, packageName), {
|
|
54
|
+
const hoisterResult = (0, hoist_1.hoist)(this.transformToHoisterTree(this.productionGraph, packageName), {
|
|
55
|
+
check: builder_util_1.log.isDebugEnabled,
|
|
56
|
+
});
|
|
68
57
|
await this._getNodeModules(hoisterResult.dependencies, this.nodeModules);
|
|
69
58
|
builder_util_1.log.debug({ packageName, depCount: this.nodeModules.length }, "node modules collection complete");
|
|
70
59
|
return this.nodeModules;
|
|
@@ -130,6 +119,18 @@ class NodeModulesCollector {
|
|
|
130
119
|
}
|
|
131
120
|
return this.cache.realPath.get(filePath);
|
|
132
121
|
}
|
|
122
|
+
requireMemoized(pkgPath) {
|
|
123
|
+
if (!this.cache.packageJson.has(pkgPath)) {
|
|
124
|
+
this.cache.packageJson.set(pkgPath, require(pkgPath));
|
|
125
|
+
}
|
|
126
|
+
return this.cache.packageJson.get(pkgPath);
|
|
127
|
+
}
|
|
128
|
+
existsSyncMemoized(filePath) {
|
|
129
|
+
if (!this.cache.exists.has(filePath)) {
|
|
130
|
+
this.cache.exists.set(filePath, fs.existsSync(filePath));
|
|
131
|
+
}
|
|
132
|
+
return this.cache.exists.get(filePath);
|
|
133
|
+
}
|
|
133
134
|
async resolvePath(filePath) {
|
|
134
135
|
// Check if we've already resolved this path
|
|
135
136
|
if (this.cache.realPath.has(filePath)) {
|
|
@@ -154,68 +155,49 @@ class NodeModulesCollector {
|
|
|
154
155
|
}
|
|
155
156
|
}
|
|
156
157
|
/**
|
|
157
|
-
*
|
|
158
|
-
*
|
|
158
|
+
* Resolve a package directory purely from the filesystem.
|
|
159
|
+
* Does NOT attempt to load the module or resolve an "exports" entrypoint.
|
|
160
|
+
* Good for Yarn 4 because a package may not be resolvable as a module,
|
|
161
|
+
* but still exists on disk.
|
|
159
162
|
*/
|
|
160
|
-
async
|
|
163
|
+
async resolvePackage(packageName, fromDir) {
|
|
161
164
|
const cacheKey = `${packageName}::${fromDir}`;
|
|
162
165
|
if (this.cache.requireResolve.has(cacheKey)) {
|
|
163
166
|
return this.cache.requireResolve.get(cacheKey);
|
|
164
167
|
}
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
return require.resolve(packageName, { paths: [fromDir, this.rootDir] });
|
|
179
|
-
}
|
|
180
|
-
catch {
|
|
181
|
-
// ignore
|
|
182
|
-
}
|
|
183
|
-
return null;
|
|
184
|
-
};
|
|
185
|
-
const entry = await resolveEntry();
|
|
186
|
-
if (!entry) {
|
|
187
|
-
this.cache.requireResolve.set(cacheKey, null);
|
|
188
|
-
return null;
|
|
168
|
+
// 1. NESTED under fromDir/node_modules/<name>
|
|
169
|
+
let candidate = path.join(fromDir, "node_modules", packageName);
|
|
170
|
+
let pkgJson = path.join(candidate, "package.json");
|
|
171
|
+
if (await this.existsMemoized(pkgJson)) {
|
|
172
|
+
this.cache.requireResolve.set(cacheKey, { entry: pkgJson, packageDir: candidate });
|
|
173
|
+
return { entry: pkgJson, packageDir: candidate };
|
|
174
|
+
}
|
|
175
|
+
// 2. HOISTED under rootDir/node_modules/<name>
|
|
176
|
+
candidate = path.join(this.rootDir, "node_modules", packageName);
|
|
177
|
+
pkgJson = path.join(candidate, "package.json");
|
|
178
|
+
if (await this.existsMemoized(pkgJson)) {
|
|
179
|
+
this.cache.requireResolve.set(cacheKey, { entry: pkgJson, packageDir: candidate });
|
|
180
|
+
return { entry: pkgJson, packageDir: candidate };
|
|
189
181
|
}
|
|
190
|
-
// 3
|
|
191
|
-
let
|
|
182
|
+
// 3. FALLBACK: try parent directories BFS (classic Node-style search)
|
|
183
|
+
let current = fromDir;
|
|
192
184
|
while (true) {
|
|
193
|
-
const
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
185
|
+
const nm = path.join(current, "node_modules", packageName);
|
|
186
|
+
const pkg = path.join(nm, "package.json");
|
|
187
|
+
if (await this.existsMemoized(pkg)) {
|
|
188
|
+
this.cache.requireResolve.set(cacheKey, { entry: pkg, packageDir: nm });
|
|
189
|
+
return { entry: pkg, packageDir: nm };
|
|
197
190
|
}
|
|
198
|
-
const parent = path.dirname(
|
|
199
|
-
if (parent ===
|
|
200
|
-
break;
|
|
191
|
+
const parent = path.dirname(current);
|
|
192
|
+
if (parent === current) {
|
|
193
|
+
break;
|
|
201
194
|
}
|
|
202
|
-
|
|
195
|
+
current = parent;
|
|
203
196
|
}
|
|
197
|
+
// 4. LAST RESORT: DO NOT throw — just return null
|
|
204
198
|
this.cache.requireResolve.set(cacheKey, null);
|
|
205
199
|
return null;
|
|
206
200
|
}
|
|
207
|
-
requireMemoized(pkgPath) {
|
|
208
|
-
if (!this.cache.packageJson.has(pkgPath)) {
|
|
209
|
-
this.cache.packageJson.set(pkgPath, require(pkgPath));
|
|
210
|
-
}
|
|
211
|
-
return this.cache.packageJson.get(pkgPath);
|
|
212
|
-
}
|
|
213
|
-
existsSyncMemoized(filePath) {
|
|
214
|
-
if (!this.cache.exists.has(filePath)) {
|
|
215
|
-
this.cache.exists.set(filePath, fs.existsSync(filePath));
|
|
216
|
-
}
|
|
217
|
-
return this.cache.exists.get(filePath);
|
|
218
|
-
}
|
|
219
201
|
cacheKey(pkg) {
|
|
220
202
|
const rel = path.relative(this.rootDir, pkg.path);
|
|
221
203
|
return `${pkg.name}::${pkg.version}::${rel !== null && rel !== void 0 ? rel : "."}`;
|
|
@@ -243,9 +225,10 @@ class NodeModulesCollector {
|
|
|
243
225
|
}
|
|
244
226
|
if ((_a = tree.dependencies) === null || _a === void 0 ? void 0 : _a[packageName]) {
|
|
245
227
|
const { name, path, dependencies } = tree.dependencies[packageName];
|
|
246
|
-
builder_util_1.log.debug({ name, path, dependencies: JSON.stringify(dependencies) }, "pruning root app/self
|
|
228
|
+
builder_util_1.log.debug({ name, path, dependencies: JSON.stringify(dependencies) }, "pruning root app/self reference from workspace tree, merging dependencies uptree");
|
|
247
229
|
for (const [name, pkg] of Object.entries(dependencies !== null && dependencies !== void 0 ? dependencies : {})) {
|
|
248
230
|
tree.dependencies[name] = pkg;
|
|
231
|
+
this.allDependencies.set(this.packageVersionString(pkg), pkg);
|
|
249
232
|
}
|
|
250
233
|
delete tree.dependencies[packageName];
|
|
251
234
|
}
|
|
@@ -331,6 +314,7 @@ class NodeModulesCollector {
|
|
|
331
314
|
command = "cmd.exe";
|
|
332
315
|
args = ["/c", tempBatFile, ...args];
|
|
333
316
|
}
|
|
317
|
+
builder_util_1.log.debug({ command, args, cwd, tempOutputFile }, "spawning node module collector process");
|
|
334
318
|
await new Promise((resolve, reject) => {
|
|
335
319
|
const outStream = (0, fs_extra_1.createWriteStream)(tempOutputFile);
|
|
336
320
|
const child = childProcess.spawn(command, args, {
|