app-builder-lib 27.0.0-alpha.2 → 27.0.0-alpha.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.
Files changed (175) hide show
  1. package/dist/Framework.d.ts +2 -0
  2. package/dist/Framework.d.ts.map +1 -1
  3. package/dist/Framework.js.map +1 -1
  4. package/dist/asar/asarFileChecker.d.ts +4 -2
  5. package/dist/asar/asarFileChecker.d.ts.map +1 -1
  6. package/dist/asar/asarFileChecker.js +2 -3
  7. package/dist/asar/asarFileChecker.js.map +1 -1
  8. package/dist/codeSign/certInfo.d.ts +14 -0
  9. package/dist/codeSign/certInfo.d.ts.map +1 -1
  10. package/dist/codeSign/certInfo.js +49 -0
  11. package/dist/codeSign/certInfo.js.map +1 -1
  12. package/dist/codeSign/mac/macCodeSign.d.ts +3 -3
  13. package/dist/codeSign/mac/macCodeSign.d.ts.map +1 -1
  14. package/dist/codeSign/mac/macCodeSign.js +40 -14
  15. package/dist/codeSign/mac/macCodeSign.js.map +1 -1
  16. package/dist/codeSign/win/hsmSignManager.d.ts +10 -0
  17. package/dist/codeSign/win/hsmSignManager.d.ts.map +1 -0
  18. package/dist/codeSign/win/hsmSignManager.js +50 -0
  19. package/dist/codeSign/win/hsmSignManager.js.map +1 -0
  20. package/dist/codeSign/win/pkcs11SignManager.d.ts +14 -0
  21. package/dist/codeSign/win/pkcs11SignManager.d.ts.map +1 -0
  22. package/dist/codeSign/win/pkcs11SignManager.js +82 -0
  23. package/dist/codeSign/win/pkcs11SignManager.js.map +1 -0
  24. package/dist/codeSign/{signManager.d.ts → win/signManager.d.ts} +8 -6
  25. package/dist/codeSign/win/signManager.d.ts.map +1 -0
  26. package/dist/codeSign/win/signManager.js +19 -0
  27. package/dist/codeSign/win/signManager.js.map +1 -0
  28. package/dist/codeSign/win/signtoolBaseSignManager.d.ts +71 -0
  29. package/dist/codeSign/win/signtoolBaseSignManager.d.ts.map +1 -0
  30. package/dist/codeSign/win/signtoolBaseSignManager.js +407 -0
  31. package/dist/codeSign/win/signtoolBaseSignManager.js.map +1 -0
  32. package/dist/codeSign/win/windowsCodeSign.d.ts.map +1 -1
  33. package/dist/codeSign/win/windowsCodeSign.js +9 -4
  34. package/dist/codeSign/win/windowsCodeSign.js.map +1 -1
  35. package/dist/codeSign/win/windowsSignAzureManager.d.ts +9 -3
  36. package/dist/codeSign/win/windowsSignAzureManager.d.ts.map +1 -1
  37. package/dist/codeSign/win/windowsSignAzureManager.js +130 -36
  38. package/dist/codeSign/win/windowsSignAzureManager.js.map +1 -1
  39. package/dist/codeSign/win/windowsSignToolManager.d.ts +1 -58
  40. package/dist/codeSign/win/windowsSignToolManager.d.ts.map +1 -1
  41. package/dist/codeSign/win/windowsSignToolManager.js +3 -363
  42. package/dist/codeSign/win/windowsSignToolManager.js.map +1 -1
  43. package/dist/configuration.d.ts +19 -120
  44. package/dist/configuration.d.ts.map +1 -1
  45. package/dist/configuration.js.map +1 -1
  46. package/dist/electron/ElectronFramework.d.ts +0 -2
  47. package/dist/electron/ElectronFramework.d.ts.map +1 -1
  48. package/dist/electron/ElectronFramework.js +15 -27
  49. package/dist/electron/ElectronFramework.js.map +1 -1
  50. package/dist/electron/injectFFMPEG.js +2 -2
  51. package/dist/electron/injectFFMPEG.js.map +1 -1
  52. package/dist/electron/mac/electronMac.js +10 -8
  53. package/dist/electron/mac/electronMac.js.map +1 -1
  54. package/dist/electron/win/electronWin.js +1 -2
  55. package/dist/electron/win/electronWin.js.map +1 -1
  56. package/dist/index.d.ts +8 -4
  57. package/dist/index.d.ts.map +1 -1
  58. package/dist/index.js +3 -0
  59. package/dist/index.js.map +1 -1
  60. package/dist/indexInternal.d.ts +2 -2
  61. package/dist/indexInternal.d.ts.map +1 -1
  62. package/dist/indexInternal.js +1 -1
  63. package/dist/indexInternal.js.map +1 -1
  64. package/dist/macPackager.d.ts +14 -10
  65. package/dist/macPackager.d.ts.map +1 -1
  66. package/dist/macPackager.js +114 -121
  67. package/dist/macPackager.js.map +1 -1
  68. package/dist/node-module-collector/moduleManager.d.ts +7 -1
  69. package/dist/node-module-collector/moduleManager.d.ts.map +1 -1
  70. package/dist/node-module-collector/moduleManager.js +2 -2
  71. package/dist/node-module-collector/moduleManager.js.map +1 -1
  72. package/dist/node-module-collector/nodeModulesCollector.js +1 -1
  73. package/dist/node-module-collector/nodeModulesCollector.js.map +1 -1
  74. package/dist/node-module-collector/pnpmNodeModulesCollector.d.ts +48 -1
  75. package/dist/node-module-collector/pnpmNodeModulesCollector.d.ts.map +1 -1
  76. package/dist/node-module-collector/pnpmNodeModulesCollector.js +216 -17
  77. package/dist/node-module-collector/pnpmNodeModulesCollector.js.map +1 -1
  78. package/dist/options/FuseOptionsV1.d.ts +137 -0
  79. package/dist/options/FuseOptionsV1.d.ts.map +1 -0
  80. package/dist/options/FuseOptionsV1.js +2 -0
  81. package/dist/options/FuseOptionsV1.js.map +1 -0
  82. package/dist/options/PlatformSpecificBuildOptions.d.ts +1 -1
  83. package/dist/options/PlatformSpecificBuildOptions.d.ts.map +1 -1
  84. package/dist/options/PlatformSpecificBuildOptions.js.map +1 -1
  85. package/dist/options/macOptions.d.ts +93 -126
  86. package/dist/options/macOptions.d.ts.map +1 -1
  87. package/dist/options/macOptions.js.map +1 -1
  88. package/dist/options/winOptions.d.ts +137 -63
  89. package/dist/options/winOptions.d.ts.map +1 -1
  90. package/dist/options/winOptions.js +12 -1
  91. package/dist/options/winOptions.js.map +1 -1
  92. package/dist/platformPackager.d.ts +4 -2
  93. package/dist/platformPackager.d.ts.map +1 -1
  94. package/dist/platformPackager.js +11 -7
  95. package/dist/platformPackager.js.map +1 -1
  96. package/dist/targets/ArchiveTarget.js +2 -2
  97. package/dist/targets/ArchiveTarget.js.map +1 -1
  98. package/dist/targets/archive.d.ts +10 -2
  99. package/dist/targets/archive.d.ts.map +1 -1
  100. package/dist/targets/archive.js +25 -6
  101. package/dist/targets/archive.js.map +1 -1
  102. package/dist/targets/linux/snap/core24.d.ts +2 -0
  103. package/dist/targets/linux/snap/core24.d.ts.map +1 -1
  104. package/dist/targets/linux/snap/core24.js +48 -8
  105. package/dist/targets/linux/snap/core24.js.map +1 -1
  106. package/dist/targets/linux/snap/coreLegacy.d.ts +2 -2
  107. package/dist/targets/linux/snap/coreLegacy.d.ts.map +1 -1
  108. package/dist/targets/linux/snap/coreLegacy.js +3 -4
  109. package/dist/targets/linux/snap/coreLegacy.js.map +1 -1
  110. package/dist/targets/linux/snap/snapCommand.d.ts +13 -0
  111. package/dist/targets/linux/snap/snapCommand.d.ts.map +1 -0
  112. package/dist/targets/linux/snap/snapCommand.js +27 -0
  113. package/dist/targets/linux/snap/snapCommand.js.map +1 -0
  114. package/dist/targets/mac/MacTargetHelper.d.ts +12 -12
  115. package/dist/targets/mac/MacTargetHelper.d.ts.map +1 -1
  116. package/dist/targets/mac/MacTargetHelper.js +72 -67
  117. package/dist/targets/mac/MacTargetHelper.js.map +1 -1
  118. package/dist/targets/mac/pkg.d.ts.map +1 -1
  119. package/dist/targets/mac/pkg.js +4 -4
  120. package/dist/targets/mac/pkg.js.map +1 -1
  121. package/dist/targets/win/AppxTarget.d.ts.map +1 -1
  122. package/dist/targets/win/AppxTarget.js +4 -4
  123. package/dist/targets/win/AppxTarget.js.map +1 -1
  124. package/dist/targets/win/nsis/NsisTarget.js +2 -2
  125. package/dist/targets/win/nsis/NsisTarget.js.map +1 -1
  126. package/dist/targets/win/nsis/nsisScriptGenerator.js +1 -1
  127. package/dist/targets/win/nsis/nsisScriptGenerator.js.map +1 -1
  128. package/dist/targets/win/nsis/nsisUtil.d.ts.map +1 -1
  129. package/dist/targets/win/nsis/nsisUtil.js +2 -2
  130. package/dist/targets/win/nsis/nsisUtil.js.map +1 -1
  131. package/dist/toolsets/custom.d.ts +1 -0
  132. package/dist/toolsets/custom.d.ts.map +1 -1
  133. package/dist/toolsets/custom.js +19 -8
  134. package/dist/toolsets/custom.js.map +1 -1
  135. package/dist/toolsets/icons.js +1 -1
  136. package/dist/toolsets/icons.js.map +1 -1
  137. package/dist/toolsets/winCodeSign.d.ts +36 -0
  138. package/dist/toolsets/winCodeSign.d.ts.map +1 -1
  139. package/dist/toolsets/winCodeSign.js +84 -30
  140. package/dist/toolsets/winCodeSign.js.map +1 -1
  141. package/dist/toolsets/wine.d.ts.map +1 -1
  142. package/dist/toolsets/wine.js +20 -12
  143. package/dist/toolsets/wine.js.map +1 -1
  144. package/dist/util/config/schemaValidator.d.ts.map +1 -1
  145. package/dist/util/config/schemaValidator.js +1 -1
  146. package/dist/util/config/schemaValidator.js.map +1 -1
  147. package/dist/util/electronGet.d.ts +8 -25
  148. package/dist/util/electronGet.d.ts.map +1 -1
  149. package/dist/util/electronGet.js +107 -87
  150. package/dist/util/electronGet.js.map +1 -1
  151. package/dist/util/flags.d.ts +0 -3
  152. package/dist/util/flags.d.ts.map +1 -1
  153. package/dist/util/flags.js +0 -9
  154. package/dist/util/flags.js.map +1 -1
  155. package/dist/util/license.d.ts.map +1 -1
  156. package/dist/util/license.js +4 -1
  157. package/dist/util/license.js.map +1 -1
  158. package/dist/version.d.ts +1 -1
  159. package/dist/version.js +1 -1
  160. package/dist/version.js.map +1 -1
  161. package/dist/vm/ParallelsVm.d.ts.map +1 -1
  162. package/dist/vm/ParallelsVm.js +13 -2
  163. package/dist/vm/ParallelsVm.js.map +1 -1
  164. package/dist/vm/vm.d.ts.map +1 -1
  165. package/dist/vm/vm.js +4 -1
  166. package/dist/vm/vm.js.map +1 -1
  167. package/dist/winPackager.d.ts +1 -2
  168. package/dist/winPackager.d.ts.map +1 -1
  169. package/dist/winPackager.js +17 -22
  170. package/dist/winPackager.js.map +1 -1
  171. package/package.json +15 -14
  172. package/scheme.json +484 -432
  173. package/dist/codeSign/signManager.d.ts.map +0 -1
  174. package/dist/codeSign/signManager.js +0 -2
  175. package/dist/codeSign/signManager.js.map +0 -1
@@ -1,18 +1,18 @@
1
1
  import * as get from "@electron/get";
2
2
  import { ElectronDownloadCacheMode, } from "@electron/get";
3
- import { buildGotProxyAgent, exec, exists, log, PADDING, parseValidEnvVarUrl, sanitizeDirPath, to7zaOutputSwitch } from "builder-util";
4
- import { getPath7za } from "../toolsets/7zip.js";
3
+ import { exec, exists, log, PADDING, parseValidEnvVarUrl, sanitizeDirPath, to7zaOutputSwitch, ensureDir, moveDirAtomic } from "builder-util";
4
+ import { HttpError, retry, sleep } from "builder-util-runtime";
5
+ import * as crypto from "crypto";
5
6
  import { MultiProgress } from "electron-publish";
6
7
  import { createReadStream, createWriteStream } from "fs";
7
8
  import * as fs from "fs/promises";
8
- import * as crypto from "crypto";
9
9
  import * as os from "os";
10
10
  import * as path from "path";
11
11
  import * as lockfile from "proper-lockfile";
12
12
  import { pipeline } from "stream/promises";
13
13
  import * as tar from "tar";
14
14
  import * as unzipper from "unzipper";
15
- import { HttpError, retry, sleep } from "builder-util-runtime";
15
+ import { getPath7za } from "../toolsets/7zip.js";
16
16
  import { CacheState, cleanupCacheDirectory, computeCacheMetadata, readCacheStateFile, validateCacheDirectory, writeCacheState } from "./cacheState.js";
17
17
  function hashUrlSafe(input, length = 6) {
18
18
  let hash = 5381;
@@ -58,6 +58,21 @@ function resolveCacheMode() {
58
58
  }
59
59
  return ElectronDownloadCacheMode.ReadWrite;
60
60
  }
61
+ /**
62
+ * Returns true when `destPath` is safely contained within `dir` (direct child or deeper).
63
+ * On Windows the filesystem is case-insensitive so the comparison is normalised to lowercase.
64
+ * @internal exported for unit testing
65
+ */
66
+ export function isSafeExtractPath(destPath, dir) {
67
+ const normalizedDest = path.resolve(destPath);
68
+ const normalizedDir = path.resolve(dir);
69
+ if (process.platform === "win32") {
70
+ const d = normalizedDest.toLowerCase();
71
+ const b = normalizedDir.toLowerCase();
72
+ return d.startsWith(b + path.sep) || d === b;
73
+ }
74
+ return normalizedDest.startsWith(normalizedDir + path.sep) || normalizedDest === normalizedDir;
75
+ }
61
76
  async function extractZipStreaming(file, dir) {
62
77
  // Pass 1: read central directory once to collect Unix modes (one seek to EOF)
63
78
  const zipDir = await unzipper.Open.file(file);
@@ -69,38 +84,46 @@ async function extractZipStreaming(file, dir) {
69
84
  }
70
85
  }
71
86
  const isSymlink = (mode) => (mode & 0o170000) === 0o120000;
72
- // Pass 2: stream from byte 0 — no per-entry seeks, no Docker hang
73
- const entries = createReadStream(file).pipe(unzipper.Parse({ forceStream: true }));
74
- for await (const entry of entries) {
75
- const destPath = path.resolve(dir, entry.path);
76
- if (!destPath.startsWith(dir + path.sep) && destPath !== dir) {
77
- throw new Error(`Path traversal blocked: ${entry.path}`);
78
- }
79
- const mode = entryModes.get(entry.path) ?? 0;
80
- if (mode > 0 && isSymlink(mode)) {
81
- const target = (await entry.buffer()).toString();
82
- if (path.isAbsolute(target)) {
83
- throw new Error(`Absolute symlink target blocked: ${target}`);
87
+ // Pass 2: stream from byte 0 — no per-entry seeks, no Docker hang.
88
+ // Destroy the read stream in a finally block so the file handle is always released,
89
+ // including when the loop exits early due to a thrown error.
90
+ const readStream = createReadStream(file);
91
+ try {
92
+ const entries = readStream.pipe(unzipper.Parse({ forceStream: true }));
93
+ for await (const entry of entries) {
94
+ const destPath = path.resolve(dir, entry.path);
95
+ if (!isSafeExtractPath(destPath, dir)) {
96
+ throw new Error(`Path traversal blocked: ${entry.path}`);
84
97
  }
85
- const resolvedTarget = path.resolve(path.dirname(destPath), target);
86
- if (!resolvedTarget.startsWith(dir + path.sep) && resolvedTarget !== dir) {
87
- throw new Error(`Symlink target escapes extraction dir: ${target}`);
98
+ const mode = entryModes.get(entry.path) ?? 0;
99
+ if (mode > 0 && isSymlink(mode)) {
100
+ const target = (await entry.buffer()).toString();
101
+ if (path.isAbsolute(target)) {
102
+ throw new Error(`Absolute symlink target blocked: ${target}`);
103
+ }
104
+ const resolvedTarget = path.resolve(path.dirname(destPath), target);
105
+ if (!isSafeExtractPath(resolvedTarget, dir)) {
106
+ throw new Error(`Symlink target escapes extraction dir: ${target}`);
107
+ }
108
+ await fs.mkdir(path.dirname(destPath), { recursive: true });
109
+ await fs.symlink(target, destPath);
88
110
  }
89
- await fs.mkdir(path.dirname(destPath), { recursive: true });
90
- await fs.symlink(target, destPath);
91
- }
92
- else if (entry.type === "Directory") {
93
- await fs.mkdir(destPath, { recursive: true });
94
- entry.autodrain();
95
- }
96
- else {
97
- await fs.mkdir(path.dirname(destPath), { recursive: true });
98
- await pipeline(entry, createWriteStream(destPath));
99
- if (mode > 0) {
100
- await fs.chmod(destPath, mode & 0o7777);
111
+ else if (entry.type === "Directory") {
112
+ await fs.mkdir(destPath, { recursive: true });
113
+ entry.autodrain();
114
+ }
115
+ else {
116
+ await fs.mkdir(path.dirname(destPath), { recursive: true });
117
+ await pipeline(entry, createWriteStream(destPath));
118
+ if (mode > 0) {
119
+ await fs.chmod(destPath, mode & 0o7777);
120
+ }
101
121
  }
102
122
  }
103
123
  }
124
+ finally {
125
+ readStream.destroy();
126
+ }
104
127
  }
105
128
  export async function extractArchive(file, dir) {
106
129
  const tmpDir = `${dir}.tmp`;
@@ -157,7 +180,7 @@ export async function extractArchive(file, dir) {
157
180
  // Check if extraction actually failed or just had benign warnings
158
181
  const files = await fs.readdir(tmpDir);
159
182
  if (files.length === 0) {
160
- log.warn({ file, tmpDir, error: e.message }, "7z extraction produced no output");
183
+ log.warn({ file: log.filePath(file), tmpDir: log.filePath(tmpDir), error: e.message }, "7z extraction produced no output");
161
184
  throw new Error(`7z extraction failed for ${file}: ${e.message}`);
162
185
  }
163
186
  // If files were extracted despite the error, log and continue
@@ -173,20 +196,37 @@ export async function extractArchive(file, dir) {
173
196
  throw new Error(`Extraction of ${path.basename(file)} produced no files`);
174
197
  }
175
198
  await fs.rm(dir, { recursive: true, force: true });
176
- await fs.rename(tmpDir, dir);
199
+ await moveDirAtomic(tmpDir, dir);
177
200
  }
178
201
  finally {
179
202
  await release().catch(err => log.warn({ err }, "failed to release lockfile"));
180
203
  }
181
204
  }
205
+ let proxyInitialized = false;
206
+ function initializeProxyOnce() {
207
+ if (!proxyInitialized) {
208
+ reinitializeProxy();
209
+ proxyInitialized = true;
210
+ }
211
+ }
212
+ /**
213
+ * Forces undici's global proxy dispatcher to re-read the current HTTP(S)_PROXY / NO_PROXY env vars,
214
+ * bypassing the once-guard in initializeProxyOnce(). Exported for integration testing only.
215
+ */
216
+ export function reinitializeProxy() {
217
+ get.initializeProxy();
218
+ }
182
219
  async function downloadArtifactToFile(config, label) {
183
220
  // Serialize concurrent downloads of the same artifact across vitest workers to prevent @electron/get's
184
221
  // non-atomic putFileInCache (remove + move) from racing with a concurrent reader.
185
- const artifactLockKey = crypto
186
- .createHash("sha256")
187
- .update(JSON.stringify({ v: config.version, p: config.platform, a: config.arch, n: config.artifactName }))
188
- .digest("hex")
189
- .slice(0, 20);
222
+ const key = {
223
+ p: config.platform,
224
+ a: config.arch,
225
+ v: config.version,
226
+ n: config.artifactName,
227
+ g: config.isGeneric,
228
+ };
229
+ const artifactLockKey = crypto.createHash("sha256").update(JSON.stringify(key)).digest("hex").slice(0, 20);
190
230
  const artifactLockPath = path.join(os.tmpdir(), `eb-dl-${artifactLockKey}.lock`);
191
231
  // This lock is taken even for cache hits (the cache-hit check lives inside @electron/get), so under
192
232
  // heavy concurrency many builds serialize here. 30 retries (~137s of backoff) is too few — waiters
@@ -200,10 +240,12 @@ async function downloadArtifactToFile(config, label) {
200
240
  });
201
241
  let lastLoggedMilestone = -1;
202
242
  const state = { bar: undefined };
243
+ // @electron/get v5 downloads via fetch, whose proxy support comes from undici's global dispatcher.
244
+ // initializeProxy() wires that up from HTTP(S)_PROXY/NO_PROXY env vars (replaces the got proxy agent).
245
+ initializeProxyOnce();
203
246
  const downloadOptions = {
204
- timeout: { request: 10 * 60 * 1000 }, // prevent indefinite hang on stalled connections
247
+ signal: AbortSignal.timeout(10 * 60 * 1000), // prevent indefinite hang on stalled connections
205
248
  ...config.downloadOptions,
206
- agent: config.downloadOptions?.agent ?? buildGotProxyAgent(),
207
249
  getProgressCallback: info => {
208
250
  // @electron/get passes downloadOptions (including this callback) to its internal
209
251
  // SHASUMS256.txt validation download. That file is tiny (<1 MB) and fires at 100%
@@ -310,9 +352,14 @@ async function persistToArchiveCache(sourcePath, archiveCachePath) {
310
352
  * Both public download functions delegate here after building their respective configs.
311
353
  */
312
354
  async function downloadAndExtract(config, extractDir, label, archiveCachePath) {
313
- await fs.mkdir(extractDir, { recursive: true });
314
- // Pre-lock fast path: only short-circuit for a definitively complete and valid cache.
315
- // Do NOT clean up here — concurrent processes could race to delete under each other.
355
+ // Create only the PARENT dir (e.g. <cache>/fpm@2.2.1), never extractDir itself, before locking.
356
+ // The parent is stable — cleanup only ever removes extractDir and its .state/.tmp/.lock siblings —
357
+ // so extractDir's whole lifecycle (mkdir, rm, re-mkdir) stays inside the lock. ensureDir absorbs
358
+ // the concurrent-recursive-mkdir ENOENT/EEXIST race while peers populate the cold cache tree.
359
+ await ensureDir(path.dirname(extractDir));
360
+ // Pre-lock fast path: read-only short-circuit for a definitively complete and valid cache.
361
+ // Safe unlocked — the cache-state helpers return null/false for a missing or half-written dir,
362
+ // so a racing read only ever falls through to take the lock. Do NOT mutate the dir here.
316
363
  const stateData = await readCacheStateFile(extractDir);
317
364
  if (stateData?.state === CacheState.complete) {
318
365
  const isValid = await validateCacheDirectory(extractDir, stateData.fileCount);
@@ -327,6 +374,13 @@ async function downloadAndExtract(config, extractDir, label, archiveCachePath) {
327
374
  // patience of withToolsetLock. proper-lockfile's update heartbeat keeps a live holder's lock fresh,
328
375
  // so increasing waiter retries never falsely steals an in-progress extraction.
329
376
  const release = await lockfile.lock(extractDir, {
377
+ // realpath:false so proper-lockfile creates <extractDir>.lock in the (already-created) parent
378
+ // WITHOUT calling fs.realpath(extractDir) first — which would throw ENOENT now that extractDir
379
+ // is created lazily inside the lock. This filesystem lock serializes peers both across worker
380
+ // processes AND within a single process (a second lock() for the same path retries until the
381
+ // first releases), so no in-process promise cache is needed — and one wouldn't help across the
382
+ // separate test worker processes anyway.
383
+ realpath: false,
330
384
  retries: { retries: 100, minTimeout: 1000, maxTimeout: 5000 },
331
385
  stale: 120000,
332
386
  });
@@ -347,7 +401,7 @@ async function downloadAndExtract(config, extractDir, label, archiveCachePath) {
347
401
  }
348
402
  // Cleanup inside the lock — skip lock files since we currently hold them
349
403
  await cleanupCacheDirectory(extractDir, { skipLockFiles: true });
350
- await fs.mkdir(extractDir, { recursive: true });
404
+ await ensureDir(extractDir);
351
405
  // Check electron-builder's own archive cache before touching @electron/get.
352
406
  // The cache lives alongside the extract dir: <cacheDir>/<releaseName>/<filename>.
353
407
  // This lets repeated builds (or offline environments) skip the download entirely once
@@ -453,7 +507,9 @@ export async function downloadBuilderToolset(options) {
453
507
  const fullUrl = resolveBuilderBinaryUrl(releaseName, filenameWithExt, baseUrl, overrideUrl);
454
508
  const suffix = hashUrlSafe(fullUrl, 5);
455
509
  const folderName = `${filenameWithExt.replace(/\.(tar\.gz|tgz|tar\.xz|txz|zip|7z)$/, "")}-${suffix}`;
456
- const extractDir = path.join(getCacheDirectory({ allowEnvVarOverride: true }), releaseName, folderName);
510
+ // releaseName is library input; enforce cache-dir containment (rejects traversal, clears taint into shell extraction)
511
+ const cacheDir = getCacheDirectory({ allowEnvVarOverride: true });
512
+ const extractDir = sanitizeDirPath(path.join(cacheDir, releaseName, folderName), cacheDir);
457
513
  // Use resolveAssetURL so @electron/get's ELECTRON_MIRROR env var check cannot override
458
514
  // the builder-binaries URL we've already resolved (see getArtifactRemoteURL in @electron/get).
459
515
  const mirrorOptions = {
@@ -462,7 +518,7 @@ export async function downloadBuilderToolset(options) {
462
518
  // Predictable archive cache: <cacheDir>/<releaseName>/<filename>, next to the extract dir.
463
519
  // downloadAndExtract checks here before touching @electron/get and persists the archive here
464
520
  // after every successful download, so subsequent builds never need a network round-trip.
465
- const archiveCachePath = path.join(getCacheDirectory({ allowEnvVarOverride: true }), releaseName, filenameWithExt);
521
+ const archiveCachePath = sanitizeDirPath(path.join(cacheDir, releaseName, filenameWithExt), cacheDir);
466
522
  const config = {
467
523
  version: "9.9.9", // must be >1.3.2 to bypass @electron/get validation shortcut
468
524
  artifactName: filenameWithExt,
@@ -474,52 +530,16 @@ export async function downloadBuilderToolset(options) {
474
530
  };
475
531
  return downloadAndExtract(config, extractDir, filenameWithExt, archiveCachePath);
476
532
  }
477
- // Keys present in ElectronGetOptions but absent from ElectronDownloadOptions.
478
- // Used to discriminate between the two config shapes at runtime.
479
- const ELECTRON_GET_EXCLUSIVE_KEYS = ["mirrorOptions", "force", "unsafelyDisableChecksums"];
480
- function isElectronGetOptions(dl) {
481
- return ELECTRON_GET_EXCLUSIVE_KEYS.some(k => Object.hasOwnProperty.call(dl, k));
482
- }
483
533
  /**
484
534
  * Downloads and extracts an electron platform artifact (e.g. ffmpeg) using @electron/get.
485
535
  * Deduplicates concurrent calls for the same artifact within the same process.
486
536
  */
487
- function buildElectronArtifactConfig(options) {
488
- const { electronDownload, arch, version, platformName: platform, artifactName, cacheDir: cacheRoot } = options;
489
- let artifactConfig = { cacheRoot, platform, arch, version, artifactName };
490
- if (electronDownload != null) {
491
- if (isElectronGetOptions(electronDownload)) {
492
- const { mirrorOptions, ...rest } = electronDownload;
493
- artifactConfig = { ...artifactConfig, ...rest, cacheRoot, mirrorOptions };
494
- }
495
- else {
496
- const { mirror, customDir, cache, customFilename, isVerifyChecksum, strictSSL, platform: overridePlatform, arch: overrideArch } = electronDownload;
497
- // strictSSL: false disables TLS certificate validation for all
498
- // electron/tool downloads. This option exists only for air-gapped or
499
- // self-signed-cert environments; ensure your build network is fully trusted.
500
- if (strictSSL === false) {
501
- log.warn({ option: "electronDownload.strictSSL" }, "strictSSL is false — TLS certificate validation is DISABLED for Electron downloads. Only use this option in a trusted, isolated build environment.");
502
- }
503
- artifactConfig = {
504
- ...artifactConfig,
505
- unsafelyDisableChecksums: isVerifyChecksum === false,
506
- cacheRoot: cache ?? cacheRoot,
507
- mirrorOptions: {
508
- mirror: mirror || undefined,
509
- customDir: customDir || undefined,
510
- customFilename: customFilename || undefined,
511
- },
512
- ...(strictSSL === false ? { downloadOptions: { https: { rejectUnauthorized: false } } } : {}),
513
- };
514
- if (overridePlatform != null) {
515
- artifactConfig.platform = overridePlatform;
516
- }
517
- if (overrideArch != null) {
518
- artifactConfig.arch = overrideArch;
519
- }
520
- }
537
+ function buildElectronArtifactConfig(artifactOptions) {
538
+ const { options, arch, version, platformName: platform, artifactName, cacheDir: cacheRoot } = artifactOptions;
539
+ if (options?.unsafelyDisableChecksums) {
540
+ log.warn({ artifactName }, "electronGet.unsafelyDisableChecksums is enabled — downloaded artifacts will NOT be verified.txt; a compromised mirror can serve malicious binaries undetected");
521
541
  }
522
- artifactConfig.cacheMode = resolveCacheMode();
542
+ const artifactConfig = { ...options, cacheRoot, platform, arch, version, artifactName, cacheMode: resolveCacheMode() };
523
543
  return artifactConfig;
524
544
  }
525
545
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"electronGet.js","sourceRoot":"","sources":["../../src/util/electronGet.ts"],"names":[],"mappings":"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","sourcesContent":["import * as get from \"@electron/get\"\nimport {\n ElectronDownloadCacheMode,\n ElectronDownloadRequest,\n ElectronDownloadRequestOptions,\n ElectronPlatformArtifactDetails,\n GotDownloaderOptions,\n MirrorOptions,\n} from \"@electron/get\"\nimport { buildGotProxyAgent, exec, exists, log, PADDING, parseValidEnvVarUrl, sanitizeDirPath, to7zaOutputSwitch } from \"builder-util\"\nimport { getPath7za } from \"../toolsets/7zip.js\"\nimport { MultiProgress } from \"electron-publish\"\nimport { createReadStream, createWriteStream } from \"fs\"\nimport * as fs from \"fs/promises\"\nimport * as crypto from \"crypto\"\nimport * as os from \"os\"\nimport * as path from \"path\"\nimport * as lockfile from \"proper-lockfile\"\nimport { pipeline } from \"stream/promises\"\nimport * as tar from \"tar\"\nimport * as unzipper from \"unzipper\"\nimport { HttpError, retry, sleep } from \"builder-util-runtime\"\nimport { ElectronPlatformName } from \"../electron/ElectronFramework.js\"\nimport { CacheState, cleanupCacheDirectory, computeCacheMetadata, readCacheStateFile, validateCacheDirectory, writeCacheState } from \"./cacheState.js\"\nimport type { ProgressBar } from \"electron-publish\"\n\nexport type ElectronGetOptions = Omit<\n ElectronPlatformArtifactDetails,\n | \"platform\"\n | \"arch\"\n | \"version\"\n | \"artifactName\"\n | \"artifactSuffix\"\n | \"customFilename\"\n | \"tempDirectory\"\n | \"downloader\"\n | \"cacheMode\"\n | \"cacheRoot\"\n | \"downloadOptions\"\n | \"isGeneric\"\n | \"mirrorOptions\" // to be added below\n> & {\n mirrorOptions?: Omit<MirrorOptions, \"customDir\" | \"customFilename\" | \"customVersion\">\n}\n\nexport type ArtifactDownloadOptions = {\n electronDownload?: ElectronGetOptions | ElectronDownloadOptions | null\n artifactName: string\n platformName: string\n arch: string\n version: string\n cacheDir?: string\n}\n\nexport interface ElectronDownloadOptions {\n // https://github.com/electron-userland/electron-builder/issues/3077\n // must be optional\n version?: string\n\n /**\n * The [cache location](https://github.com/electron-userland/electron-download#cache-location).\n */\n cache?: string | null\n\n /**\n * The mirror.\n */\n mirror?: string | null\n\n /** @private */\n customDir?: string | null\n /** @private */\n customFilename?: string | null\n\n /** @private */\n strictSSL?: boolean\n /** @private */\n isVerifyChecksum?: boolean\n\n platform?: ElectronPlatformName\n arch?: string\n}\n\nfunction hashUrlSafe(input: string, length = 6): string {\n let hash = 5381\n for (let i = 0; i < input.length; i++) {\n hash = ((hash << 5) + hash) ^ input.charCodeAt(i)\n }\n hash >>>= 0\n const out = hash.toString(36)\n return out.length >= length ? out.slice(0, length) : out.padStart(length, \"0\")\n}\n\nexport function getCacheDirectory(options: { isAvoidSystemOnWindows?: boolean; allowEnvVarOverride: boolean }): string {\n const { isAvoidSystemOnWindows = true, allowEnvVarOverride } = options\n const env = process.env.ELECTRON_BUILDER_CACHE?.trim()\n if (allowEnvVarOverride && env && path.parse(env).root) {\n return env\n }\n\n const appName = \"electron-builder\"\n const platform = os.platform()\n const homeDir = os.homedir()\n\n if (platform === \"darwin\") {\n return path.join(homeDir, \"Library\", \"Caches\", appName)\n }\n if (platform === \"win32\") {\n const localAppData = process.env.LOCALAPPDATA?.trim()\n const username = process.env.USERNAME?.trim()?.toLowerCase()\n // https://github.com/electron-userland/electron-builder/issues/1164\n const isSystemUser = isAvoidSystemOnWindows && (localAppData?.toLowerCase()?.includes(\"\\\\windows\\\\system32\\\\\") || username === \"system\")\n if (!localAppData || isSystemUser) {\n return path.join(os.tmpdir(), `${appName}-cache`)\n }\n return path.join(localAppData, appName, \"Cache\")\n }\n\n const xdgCache = process.env.XDG_CACHE_HOME\n return xdgCache && path.parse(xdgCache).root ? path.join(xdgCache, appName) : path.join(homeDir, \".cache\", appName)\n}\n\nfunction resolveCacheMode(): ElectronDownloadCacheMode {\n const varName = \"ELECTRON_DOWNLOAD_CACHE_MODE\"\n const cacheOverride = process.env[varName]?.trim()\n if (cacheOverride && Number(cacheOverride) in ElectronDownloadCacheMode) {\n const mode = Number(cacheOverride) as ElectronDownloadCacheMode\n log.debug({ mode }, `cache mode overridden via env var ${varName}`)\n return mode\n }\n return ElectronDownloadCacheMode.ReadWrite\n}\n\nasync function extractZipStreaming(file: string, dir: string): Promise<void> {\n // Pass 1: read central directory once to collect Unix modes (one seek to EOF)\n const zipDir = await unzipper.Open.file(file)\n const entryModes = new Map<string, number>()\n for (const entry of zipDir.files) {\n const mode = (entry.externalFileAttributes >> 16) & 0xffff\n if (mode > 0) {\n entryModes.set(entry.path, mode)\n }\n }\n const isSymlink = (mode: number) => (mode & 0o170000) === 0o120000\n\n // Pass 2: stream from byte 0 — no per-entry seeks, no Docker hang\n const entries = createReadStream(file).pipe(unzipper.Parse({ forceStream: true }))\n for await (const entry of entries as AsyncIterable<unzipper.Entry>) {\n const destPath = path.resolve(dir, entry.path)\n if (!destPath.startsWith(dir + path.sep) && destPath !== dir) {\n throw new Error(`Path traversal blocked: ${entry.path}`)\n }\n const mode = entryModes.get(entry.path) ?? 0\n if (mode > 0 && isSymlink(mode)) {\n const target = (await entry.buffer()).toString()\n if (path.isAbsolute(target)) {\n throw new Error(`Absolute symlink target blocked: ${target}`)\n }\n const resolvedTarget = path.resolve(path.dirname(destPath), target)\n if (!resolvedTarget.startsWith(dir + path.sep) && resolvedTarget !== dir) {\n throw new Error(`Symlink target escapes extraction dir: ${target}`)\n }\n await fs.mkdir(path.dirname(destPath), { recursive: true })\n await fs.symlink(target, destPath)\n } else if (entry.type === \"Directory\") {\n await fs.mkdir(destPath, { recursive: true })\n entry.autodrain()\n } else {\n await fs.mkdir(path.dirname(destPath), { recursive: true })\n await pipeline(entry, createWriteStream(destPath))\n if (mode > 0) {\n await fs.chmod(destPath, mode & 0o7777)\n }\n }\n }\n}\n\nexport async function extractArchive(file: string, dir: string) {\n const tmpDir = `${dir}.tmp`\n await fs.mkdir(tmpDir, { recursive: true })\n\n const release = await lockfile.lock(tmpDir, {\n // 100 retries (not 15) so concurrent callers wait out a slow first extraction instead of failing\n // with ELOCKED; the update heartbeat keeps an in-progress holder's lock fresh against `stale`.\n retries: { retries: 100, minTimeout: 1000, maxTimeout: 5000 },\n stale: 120000, // Increased from 60s to allow long-running extractions\n })\n\n try {\n // rm + mkdir happen AFTER acquiring the lock so no concurrent caller can clear our tmpDir mid-extraction\n await fs.rm(tmpDir, { recursive: true, force: true })\n await fs.mkdir(tmpDir, { recursive: true })\n\n // Guard against the transient window in @electron/get's non-atomic putFileInCache (remove → move).\n // A concurrent worker may have deleted and not yet replaced the source archive; wait briefly for it.\n for (let i = 0; !(await exists(file)); i++) {\n if (i >= 4) {\n throw Object.assign(new Error(`Source archive not found after retries: ${file}`), { code: \"ENOENT\", path: file })\n }\n log.warn({ file, attempt: i + 1 }, \"source archive transiently missing, retrying\")\n await sleep(300 * (i + 1))\n }\n\n if (file.endsWith(\".tar.gz\") || file.endsWith(\".tgz\")) {\n await tar.extract({ file, cwd: tmpDir, strip: 1 })\n } else if (file.endsWith(\".tar.xz\") || file.endsWith(\".txz\")) {\n // node-tar cannot decompress xz, so use 7za to turn the .tar.xz into a .tar, then extract that tar.\n const cmd7za = await getPath7za()\n const xzOutDir = `${tmpDir}.xz`\n await fs.rm(xzOutDir, { recursive: true, force: true })\n await fs.mkdir(xzOutDir, { recursive: true })\n try {\n await exec(cmd7za, [\"x\", \"-bd\", file, to7zaOutputSwitch(sanitizeDirPath(xzOutDir)), \"-y\"])\n const innerTar = (await fs.readdir(xzOutDir)).find(f => f.endsWith(\".tar\"))\n if (innerTar == null) {\n throw new Error(`xz decompression of ${path.basename(file)} produced no .tar archive`)\n }\n await tar.extract({ file: path.join(xzOutDir, innerTar), cwd: tmpDir, strip: 1 })\n } finally {\n await fs.rm(xzOutDir, { recursive: true, force: true })\n }\n } else if (file.endsWith(\".zip\")) {\n await extractZipStreaming(file, tmpDir)\n } else if (file.endsWith(\".7z\")) {\n const cmd7za = await getPath7za()\n try {\n await exec(cmd7za, [\"x\", \"-bd\", file, to7zaOutputSwitch(sanitizeDirPath(tmpDir)), \"-y\"])\n } catch (e: any) {\n // Check if extraction actually failed or just had benign warnings\n const files = await fs.readdir(tmpDir)\n if (files.length === 0) {\n log.warn({ file, tmpDir, error: e.message }, \"7z extraction produced no output\")\n throw new Error(`7z extraction failed for ${file}: ${e.message}`)\n }\n // If files were extracted despite the error, log and continue\n log.warn({ error: e.message, filesExtracted: files.length }, \"7z reported error but extracted files\")\n }\n } else {\n throw new Error(`Unsupported archive format: ${path.basename(file)}`)\n }\n\n // Verify extraction produced files\n const extractedFiles = await fs.readdir(tmpDir)\n if (extractedFiles.length === 0) {\n throw new Error(`Extraction of ${path.basename(file)} produced no files`)\n }\n\n await fs.rm(dir, { recursive: true, force: true })\n await fs.rename(tmpDir, dir)\n } finally {\n await release().catch(err => log.warn({ err }, \"failed to release lockfile\"))\n }\n}\n\nasync function downloadArtifactToFile(config: Parameters<typeof get.downloadArtifact>[0], label: string): Promise<string> {\n // Serialize concurrent downloads of the same artifact across vitest workers to prevent @electron/get's\n // non-atomic putFileInCache (remove + move) from racing with a concurrent reader.\n const artifactLockKey = crypto\n .createHash(\"sha256\")\n .update(JSON.stringify({ v: config.version, p: (config as any).platform, a: (config as any).arch, n: (config as any).artifactName }))\n .digest(\"hex\")\n .slice(0, 20)\n const artifactLockPath = path.join(os.tmpdir(), `eb-dl-${artifactLockKey}.lock`)\n // This lock is taken even for cache hits (the cache-hit check lives inside @electron/get), so under\n // heavy concurrency many builds serialize here. 30 retries (~137s of backoff) is too few — waiters\n // were exhausting it and failing with ELOCKED while the holder fetched a large artifact. 100 retries\n // matches the other toolset locks; stale (10min) + proper-lockfile's update heartbeat keep a live\n // downloader's lock fresh so the longer wait never falsely steals an in-progress download.\n const releaseArtifactLock = await lockfile.lock(artifactLockPath, {\n retries: { retries: 100, minTimeout: 500, maxTimeout: 5000 },\n stale: 600_000,\n realpath: false,\n })\n let lastLoggedMilestone = -1\n const state: { bar: ProgressBar | undefined } = { bar: undefined }\n\n const downloadOptions: GotDownloaderOptions = {\n timeout: { request: 10 * 60 * 1000 }, // prevent indefinite hang on stalled connections\n ...config.downloadOptions,\n agent: config.downloadOptions?.agent ?? buildGotProxyAgent(),\n getProgressCallback: info => {\n // @electron/get passes downloadOptions (including this callback) to its internal\n // SHASUMS256.txt validation download. That file is tiny (<1 MB) and fires at 100%\n // immediately, producing a spurious bar even when the artifact itself is cached.\n // Skip progress display for any download whose total size is known and small.\n if (info.total && info.total < 1_000_000) {\n return Promise.resolve()\n }\n if (!state.bar && process.stdout.isTTY) {\n log.info({ label }, \"downloading\")\n state.bar = new MultiProgress().createBar(`${\" \".repeat(PADDING + 2)}[:bar] :percent | ${label}`, { total: 100 })\n }\n const pct = info.percent != null ? Math.floor(info.percent * 100) : 0\n if (state.bar) {\n state.bar.update(pct)\n } else {\n // log every 25% milestone for non-TTY environments (e.g. CI logs) to provide some visibility into download progress without overwhelming logs with too many updates\n const percentCompleted = info.transferred && info.total ? Math.floor((info.transferred / info.total) * 100) : Math.floor(pct / 25) * 25\n if (percentCompleted > lastLoggedMilestone && percentCompleted > 0) {\n lastLoggedMilestone = percentCompleted\n log.info({ label, progress: `${percentCompleted}%` }, percentCompleted !== 100 ? \"downloading\" : \"downloaded\")\n }\n }\n return Promise.resolve()\n },\n }\n\n const configWithProgress = { ...config, downloadOptions }\n try {\n let filePath: string\n try {\n filePath = await retry(() => get.downloadArtifact(configWithProgress), {\n retries: 3,\n interval: 2000,\n backoff: 2000,\n shouldRetry: (e: any) =>\n e instanceof HttpError ? e.isServerError() : typeof e?.code === \"string\" && [\"ENOTFOUND\", \"ETIMEDOUT\", \"ECONNRESET\", \"EPIPE\", \"ENOENT\"].includes(e.code),\n })\n } catch (err) {\n if (typeof (err as any)?.message === \"string\" && (err as any).message.includes(\"dest already exists\")) {\n filePath = await get.downloadArtifact(configWithProgress)\n } else {\n throw err\n }\n }\n if (!(await exists(filePath))) {\n log.warn({ filePath, label }, \"cached artifact missing from disk; retrying with cache write\")\n filePath = await get.downloadArtifact({ ...configWithProgress, cacheMode: ElectronDownloadCacheMode.WriteOnly })\n }\n if (!state.bar && lastLoggedMilestone === -1) {\n log.info({ label }, \"using cached artifact\")\n }\n return filePath\n } finally {\n state.bar?.update(100)\n state.bar?.terminate()\n await releaseArtifactLock().catch(err => log.warn({ err }, \"failed to release artifact download lock\"))\n }\n}\n\n/**\n * Checks electron-builder's own archive cache for a previously downloaded archive.\n * Validates the SHA-256 checksum when one is known. Returns the cached path on hit,\n * null on miss or checksum mismatch (mismatch also deletes the stale file).\n */\nasync function resolveFromArchiveCache(archiveCachePath: string, label: string, expectedSha256: string | undefined): Promise<string | null> {\n if (!(await exists(archiveCachePath))) {\n return null\n }\n if (expectedSha256) {\n const hash = await new Promise<string>((resolve, reject) => {\n const h = crypto.createHash(\"sha256\")\n const s = createReadStream(archiveCachePath)\n s.on(\"error\", reject)\n s.on(\"data\", (chunk: Buffer | string) => h.update(chunk))\n s.on(\"end\", () => resolve(h.digest(\"hex\")))\n })\n if (hash !== expectedSha256) {\n log.warn({ file: label, archiveCachePath }, \"cached archive checksum mismatch — removing and re-downloading\")\n await fs.rm(archiveCachePath).catch(() => {})\n return null\n }\n }\n log.debug({ file: label, archiveCachePath }, \"using cached archive — skipping download\")\n return archiveCachePath\n}\n\n/**\n * Copies a freshly downloaded archive into electron-builder's own archive cache so that\n * future builds (including offline environments) can skip the network request entirely.\n */\nasync function persistToArchiveCache(sourcePath: string, archiveCachePath: string): Promise<void> {\n try {\n await fs.mkdir(path.dirname(archiveCachePath), { recursive: true })\n await fs.copyFile(sourcePath, archiveCachePath)\n } catch (err) {\n log.warn({ err, archiveCachePath }, \"failed to persist archive to cache — will re-download next time\")\n }\n}\n\n/**\n * Core download + extract engine. Handles lockfile, cache-hit short-circuit,\n * progress bar, extraction (.zip or .tar.gz), and completion marker.\n * Both public download functions delegate here after building their respective configs.\n */\nasync function downloadAndExtract(config: Parameters<typeof get.downloadArtifact>[0], extractDir: string, label: string, archiveCachePath?: string): Promise<string> {\n await fs.mkdir(extractDir, { recursive: true })\n\n // Pre-lock fast path: only short-circuit for a definitively complete and valid cache.\n // Do NOT clean up here — concurrent processes could race to delete under each other.\n const stateData = await readCacheStateFile(extractDir)\n if (stateData?.state === CacheState.complete) {\n const isValid = await validateCacheDirectory(extractDir, stateData.fileCount)\n if (isValid) {\n log.debug({ file: label, path: extractDir }, \"using cached artifact - cache valid\")\n return extractDir\n }\n }\n\n // Be patient: when many targets/builds contend on the same toolset cache concurrently, all but the\n // first wait here while the winner downloads+extracts (a large bundle can take >1min). 15 retries\n // (~67s) is too few and waiters fail with ELOCKED before the winner finishes; 100 matches the\n // patience of withToolsetLock. proper-lockfile's update heartbeat keeps a live holder's lock fresh,\n // so increasing waiter retries never falsely steals an in-progress extraction.\n const release = await lockfile.lock(extractDir, {\n retries: { retries: 100, minTimeout: 1000, maxTimeout: 5000 },\n stale: 120000,\n })\n let downloadedFile: string | null = null\n try {\n // Re-check after acquiring lock: another worker may have completed while we waited.\n const stateDataAfterLock = await readCacheStateFile(extractDir)\n if (stateDataAfterLock?.state === CacheState.complete) {\n const isValid = await validateCacheDirectory(extractDir, stateDataAfterLock.fileCount)\n if (isValid) {\n log.debug({ file: label, path: extractDir }, \"using cached artifact - skipping download/extract\")\n return extractDir\n }\n log.warn({ extractDir }, \"Cache marked complete but files invalid, clearing\")\n } else if (stateDataAfterLock?.state === CacheState.corrupted) {\n log.warn({ extractDir }, \"Corrupted cache detected, cleaning up and re-extracting\")\n }\n\n // Cleanup inside the lock — skip lock files since we currently hold them\n await cleanupCacheDirectory(extractDir, { skipLockFiles: true })\n await fs.mkdir(extractDir, { recursive: true })\n\n // Check electron-builder's own archive cache before touching @electron/get.\n // The cache lives alongside the extract dir: <cacheDir>/<releaseName>/<filename>.\n // This lets repeated builds (or offline environments) skip the download entirely once\n // the archive has been fetched at least once.\n if (archiveCachePath) {\n downloadedFile = await resolveFromArchiveCache(archiveCachePath, label, (config as any).checksums?.[label])\n }\n\n if (!downloadedFile) {\n log.debug({ file: label }, \"downloading\")\n downloadedFile = await downloadArtifactToFile(config, label)\n if (!downloadedFile) {\n throw new Error(`Failed to download artifact: ${label}`)\n }\n // Persist the downloaded archive so future builds (and offline environments) can\n // skip the network request entirely.\n if (archiveCachePath) {\n await persistToArchiveCache(downloadedFile, archiveCachePath)\n }\n }\n\n await writeCacheState(extractDir, CacheState.downloaded)\n\n // Mark extracting so stale-lock detection can recover a crashed mid-extraction process\n await writeCacheState(extractDir, CacheState.extracting)\n\n // Extract while holding the lock to prevent concurrent interference\n await extractArchive(downloadedFile, extractDir)\n\n // Compute metadata with a full recursive walk now that tmpDir has been renamed to extractDir\n const { fileCount, extractedSize } = await computeCacheMetadata(extractDir)\n\n // Write complete state with metadata BEFORE releasing the lock; throwOnError=true so a\n // failed write (disk full, permissions) propagates instead of silently producing a no-op cache\n await writeCacheState(extractDir, CacheState.complete, { fileCount, extractedSize }, true)\n } finally {\n await release().catch(err => log.warn({ err }, \"failed to release lockfile\"))\n }\n return extractDir\n}\n\n// ─── Public API ───────────────────────────────────────────────────────────────\n\n/**\n * Copies a remote artifact to a specific output path on disk.\n * Unlike downloadBuilderToolset, this does not extract archives — it copies the raw file.\n * Used for certificate imports where the caller needs the file at a known path.\n */\nexport async function download(url: string, output: string, checksum?: string | null): Promise<void> {\n const filenameWithExt = path.basename(new URL(url).pathname)\n if (checksum == null) {\n log.warn({ url }, \"downloading without an integrity checksum — the download is not verified against a known-good hash\")\n }\n const downloadedFile = await downloadArtifactToFile(\n {\n version: \"9.9.9\",\n artifactName: filenameWithExt,\n cacheRoot: path.resolve(getCacheDirectory({ allowEnvVarOverride: true }), \"downloads\"),\n cacheMode: resolveCacheMode(),\n ...(checksum != null ? { checksums: { [filenameWithExt]: checksum } } : { unsafelyDisableChecksums: true }),\n mirrorOptions: { resolveAssetURL: async () => Promise.resolve(url) },\n isGeneric: true,\n },\n filenameWithExt\n )\n await fs.copyFile(downloadedFile, output)\n}\n\nfunction validateBinaryCustomDir(envVarName: string, value: string): string {\n if (value.includes(\"://\") || value.includes(\"..\") || value.startsWith(\"/\")) {\n throw new Error(\n `${envVarName} must be a safe relative path component (e.g. \"v1.0.0-custom\"). ` + `Values containing \"://\", \"..\", or a leading \"/\" are not allowed. Got: \"${value}\"`\n )\n }\n return value\n}\n\nconst CUSTOM_DIR_ENV_VARS = [\n \"NPM_CONFIG_ELECTRON_BUILDER_BINARIES_CUSTOM_DIR\",\n \"npm_config_electron_builder_binaries_custom_dir\",\n \"npm_package_config_electron_builder_binaries_custom_dir\",\n \"ELECTRON_BUILDER_BINARIES_CUSTOM_DIR\",\n] as const\n\n/**\n * Resolves the final download URL for a builder binary, honouring:\n * ELECTRON_BUILDER_BINARIES_DOWNLOAD_OVERRIDE_URL – fully replaces the URL directory\n * ELECTRON_BUILDER_BINARIES_CUSTOM_DIR (and npm_ variants) – replaces releaseName in the path\n * overrideUrl (caller-supplied) – used as-is when no env var is set\n *\n * Exported for unit testing; not part of the public API.\n * @internal\n */\nexport function resolveBuilderBinaryUrl(releaseName: string, filenameWithExt: string, baseUrl: string, overrideUrl?: string): string {\n const envOverrideUrl = parseValidEnvVarUrl(\"ELECTRON_BUILDER_BINARIES_DOWNLOAD_OVERRIDE_URL\")\n if (envOverrideUrl != null) {\n return `${envOverrideUrl}/${filenameWithExt}`\n }\n if (overrideUrl != null) {\n return `${overrideUrl}/${filenameWithExt}`\n }\n const customDirEntry = CUSTOM_DIR_ENV_VARS.map(name => ({ name, value: process.env[name] })).find(e => e.value != null)\n if (customDirEntry != null) {\n return `${baseUrl}${validateBinaryCustomDir(customDirEntry.name, customDirEntry.value!)}/${filenameWithExt}`\n }\n return `${baseUrl}${releaseName}/${filenameWithExt}`\n}\n\n/**\n * Downloads a generic artifact (.tar.gz or .zip) from a GitHub release.\n * Used for electron-builder-binaries tools (appimage, etc.).\n */\nexport async function downloadBuilderToolset(options: {\n releaseName: string\n filenameWithExt: string\n checksums?: Record<string, string>\n githubOrgRepo?: string\n overrideUrl?: string\n}): Promise<string> {\n const { releaseName, filenameWithExt, checksums, githubOrgRepo = \"electron-userland/electron-builder-binaries\", overrideUrl } = options\n\n if (/[/\\\\]|^\\.\\./.test(filenameWithExt) || filenameWithExt.includes(\"..\")) {\n throw new Error(`downloadBuilderToolset: unsafe filenameWithExt \"${filenameWithExt}\" — must be a plain filename with no path separators or traversal sequences`)\n }\n\n const baseUrl = getBinariesMirrorUrl(githubOrgRepo)\n const fullUrl = resolveBuilderBinaryUrl(releaseName, filenameWithExt, baseUrl, overrideUrl)\n const suffix = hashUrlSafe(fullUrl, 5)\n const folderName = `${filenameWithExt.replace(/\\.(tar\\.gz|tgz|tar\\.xz|txz|zip|7z)$/, \"\")}-${suffix}`\n const extractDir = path.join(getCacheDirectory({ allowEnvVarOverride: true }), releaseName, folderName)\n\n // Use resolveAssetURL so @electron/get's ELECTRON_MIRROR env var check cannot override\n // the builder-binaries URL we've already resolved (see getArtifactRemoteURL in @electron/get).\n const mirrorOptions: MirrorOptions = {\n resolveAssetURL: async () => Promise.resolve(fullUrl),\n }\n\n // Predictable archive cache: <cacheDir>/<releaseName>/<filename>, next to the extract dir.\n // downloadAndExtract checks here before touching @electron/get and persists the archive here\n // after every successful download, so subsequent builds never need a network round-trip.\n const archiveCachePath = path.join(getCacheDirectory({ allowEnvVarOverride: true }), releaseName, filenameWithExt)\n\n const config: ElectronDownloadRequest & ElectronDownloadRequestOptions & { isGeneric: true } = {\n version: \"9.9.9\", // must be >1.3.2 to bypass @electron/get validation shortcut\n artifactName: filenameWithExt,\n cacheRoot: path.resolve(getCacheDirectory({ allowEnvVarOverride: true }), \"downloads\"),\n cacheMode: resolveCacheMode(),\n ...(checksums != null ? { checksums } : { unsafelyDisableChecksums: true }),\n mirrorOptions,\n isGeneric: true,\n }\n return downloadAndExtract(config, extractDir, filenameWithExt, archiveCachePath)\n}\n\n// Keys present in ElectronGetOptions but absent from ElectronDownloadOptions.\n// Used to discriminate between the two config shapes at runtime.\nconst ELECTRON_GET_EXCLUSIVE_KEYS: readonly string[] = [\"mirrorOptions\", \"force\", \"unsafelyDisableChecksums\"]\n\nfunction isElectronGetOptions(dl: ElectronGetOptions | ElectronDownloadOptions): dl is ElectronGetOptions {\n return ELECTRON_GET_EXCLUSIVE_KEYS.some(k => Object.hasOwnProperty.call(dl, k))\n}\n\n/**\n * Downloads and extracts an electron platform artifact (e.g. ffmpeg) using @electron/get.\n * Deduplicates concurrent calls for the same artifact within the same process.\n */\nfunction buildElectronArtifactConfig(options: ArtifactDownloadOptions): ElectronPlatformArtifactDetails {\n const { electronDownload, arch, version, platformName: platform, artifactName, cacheDir: cacheRoot } = options\n\n let artifactConfig: ElectronPlatformArtifactDetails = { cacheRoot, platform, arch, version, artifactName }\n\n if (electronDownload != null) {\n if (isElectronGetOptions(electronDownload)) {\n const { mirrorOptions, ...rest } = electronDownload\n artifactConfig = { ...artifactConfig, ...rest, cacheRoot, mirrorOptions }\n } else {\n const { mirror, customDir, cache, customFilename, isVerifyChecksum, strictSSL, platform: overridePlatform, arch: overrideArch } = electronDownload\n // strictSSL: false disables TLS certificate validation for all\n // electron/tool downloads. This option exists only for air-gapped or\n // self-signed-cert environments; ensure your build network is fully trusted.\n if (strictSSL === false) {\n log.warn(\n { option: \"electronDownload.strictSSL\" },\n \"strictSSL is false — TLS certificate validation is DISABLED for Electron downloads. Only use this option in a trusted, isolated build environment.\"\n )\n }\n artifactConfig = {\n ...artifactConfig,\n unsafelyDisableChecksums: isVerifyChecksum === false,\n cacheRoot: cache ?? cacheRoot,\n mirrorOptions: {\n mirror: mirror || undefined,\n customDir: customDir || undefined,\n customFilename: customFilename || undefined,\n },\n ...(strictSSL === false ? { downloadOptions: { https: { rejectUnauthorized: false } } } : {}),\n }\n if (overridePlatform != null) {\n artifactConfig.platform = overridePlatform\n }\n if (overrideArch != null) {\n artifactConfig.arch = overrideArch\n }\n }\n }\n\n artifactConfig.cacheMode = resolveCacheMode()\n return artifactConfig\n}\n\n/**\n * Downloads the electron artifact zip via @electron/get (with caching) and returns the zip file path.\n * Use when you need to extract the zip yourself (e.g. directly to appOutDir to preserve empty dirs and symlinks).\n */\nexport function downloadElectronArtifactZip(options: ArtifactDownloadOptions): Promise<string> {\n const config = buildElectronArtifactConfig(options)\n return downloadArtifactToFile(config, config.artifactName)\n}\n\nexport async function downloadElectronArtifact(options: ArtifactDownloadOptions): Promise<string> {\n const { arch, version, platformName: platform, artifactName } = options\n const artifactConfig = buildElectronArtifactConfig(options)\n\n const suffix = hashUrlSafe(JSON.stringify(artifactConfig), 5)\n const folderName = `${artifactName}-v${version}-${platform}-${arch}-${suffix}`\n const extractDir = path.join(getCacheDirectory({ allowEnvVarOverride: true }), `${artifactName}-v${version}`, folderName)\n\n return downloadAndExtract(artifactConfig, extractDir, artifactName)\n}\n\n/**\n * Get the binaries mirror URL from environment variables.\n * Supports various npm config formats and falls back to GitHub.\n */\nexport function getBinariesMirrorUrl(githubOrgRepo: string): string {\n const allowHttp = process.env[\"ELECTRON_BUILDER_DANGEROUSLY_ALLOW_HTTP\"] === \"true\"\n for (const envVar of [\n \"NPM_CONFIG_ELECTRON_BUILDER_BINARIES_MIRROR\",\n \"npm_config_electron_builder_binaries_mirror\",\n \"npm_package_config_electron_builder_binaries_mirror\",\n \"ELECTRON_BUILDER_BINARIES_MIRROR\",\n ]) {\n const url = parseValidEnvVarUrl(envVar, allowHttp)\n if (url) {\n return url.endsWith(\"/\") ? url : `${url}/`\n }\n }\n return `https://github.com/${githubOrgRepo}/releases/download/`\n}\n"]}
1
+ {"version":3,"file":"electronGet.js","sourceRoot":"","sources":["../../src/util/electronGet.ts"],"names":[],"mappings":"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","sourcesContent":["import * as get from \"@electron/get\"\nimport {\n ElectronArtifactDetails,\n ElectronDownloadCacheMode,\n ElectronDownloadRequest,\n ElectronDownloadRequestOptions,\n ElectronPlatformArtifactDetails,\n FetchDownloaderOptions,\n MirrorOptions,\n} from \"@electron/get\"\nimport { exec, exists, log, PADDING, parseValidEnvVarUrl, sanitizeDirPath, to7zaOutputSwitch, ensureDir, moveDirAtomic } from \"builder-util\"\nimport { HttpError, retry, sleep } from \"builder-util-runtime\"\nimport * as crypto from \"crypto\"\nimport type { ProgressBar } from \"electron-publish\"\nimport { MultiProgress } from \"electron-publish\"\nimport { createReadStream, createWriteStream } from \"fs\"\nimport * as fs from \"fs/promises\"\nimport * as os from \"os\"\nimport * as path from \"path\"\nimport * as lockfile from \"proper-lockfile\"\nimport { pipeline } from \"stream/promises\"\nimport * as tar from \"tar\"\nimport * as unzipper from \"unzipper\"\nimport { getPath7za } from \"../toolsets/7zip.js\"\nimport { CacheState, cleanupCacheDirectory, computeCacheMetadata, readCacheStateFile, validateCacheDirectory, writeCacheState } from \"./cacheState.js\"\n\nexport interface ElectronGetOptions extends Omit<\n ElectronPlatformArtifactDetails,\n | \"platform\"\n | \"arch\"\n | \"version\"\n | \"artifactName\"\n | \"artifactSuffix\"\n | \"customFilename\"\n | \"tempDirectory\"\n | \"downloader\"\n | \"cacheMode\"\n | \"cacheRoot\"\n | \"downloadOptions\"\n | \"isGeneric\"\n | \"mirrorOptions\"\n> {\n mirrorOptions?: Omit<MirrorOptions, \"customDir\" | \"customFilename\" | \"customVersion\">\n}\n\nexport type ArtifactDownloadOptions = {\n options?: ElectronGetOptions | null\n artifactName: string\n platformName: string\n arch: string\n version: string\n cacheDir?: string\n}\n\nfunction hashUrlSafe(input: string, length = 6): string {\n let hash = 5381\n for (let i = 0; i < input.length; i++) {\n hash = ((hash << 5) + hash) ^ input.charCodeAt(i)\n }\n hash >>>= 0\n const out = hash.toString(36)\n return out.length >= length ? out.slice(0, length) : out.padStart(length, \"0\")\n}\n\nexport function getCacheDirectory(options: { isAvoidSystemOnWindows?: boolean; allowEnvVarOverride: boolean }): string {\n const { isAvoidSystemOnWindows = true, allowEnvVarOverride } = options\n const env = process.env.ELECTRON_BUILDER_CACHE?.trim()\n if (allowEnvVarOverride && env && path.parse(env).root) {\n return env\n }\n\n const appName = \"electron-builder\"\n const platform = os.platform()\n const homeDir = os.homedir()\n\n if (platform === \"darwin\") {\n return path.join(homeDir, \"Library\", \"Caches\", appName)\n }\n if (platform === \"win32\") {\n const localAppData = process.env.LOCALAPPDATA?.trim()\n const username = process.env.USERNAME?.trim()?.toLowerCase()\n // https://github.com/electron-userland/electron-builder/issues/1164\n const isSystemUser = isAvoidSystemOnWindows && (localAppData?.toLowerCase()?.includes(\"\\\\windows\\\\system32\\\\\") || username === \"system\")\n if (!localAppData || isSystemUser) {\n return path.join(os.tmpdir(), `${appName}-cache`)\n }\n return path.join(localAppData, appName, \"Cache\")\n }\n\n const xdgCache = process.env.XDG_CACHE_HOME\n return xdgCache && path.parse(xdgCache).root ? path.join(xdgCache, appName) : path.join(homeDir, \".cache\", appName)\n}\n\nfunction resolveCacheMode(): ElectronDownloadCacheMode {\n const varName = \"ELECTRON_DOWNLOAD_CACHE_MODE\"\n const cacheOverride = process.env[varName]?.trim()\n if (cacheOverride && Number(cacheOverride) in ElectronDownloadCacheMode) {\n const mode = Number(cacheOverride) as ElectronDownloadCacheMode\n log.debug({ mode }, `cache mode overridden via env var ${varName}`)\n return mode\n }\n return ElectronDownloadCacheMode.ReadWrite\n}\n\n/**\n * Returns true when `destPath` is safely contained within `dir` (direct child or deeper).\n * On Windows the filesystem is case-insensitive so the comparison is normalised to lowercase.\n * @internal exported for unit testing\n */\nexport function isSafeExtractPath(destPath: string, dir: string): boolean {\n const normalizedDest = path.resolve(destPath)\n const normalizedDir = path.resolve(dir)\n if (process.platform === \"win32\") {\n const d = normalizedDest.toLowerCase()\n const b = normalizedDir.toLowerCase()\n return d.startsWith(b + path.sep) || d === b\n }\n return normalizedDest.startsWith(normalizedDir + path.sep) || normalizedDest === normalizedDir\n}\n\nasync function extractZipStreaming(file: string, dir: string): Promise<void> {\n // Pass 1: read central directory once to collect Unix modes (one seek to EOF)\n const zipDir = await unzipper.Open.file(file)\n const entryModes = new Map<string, number>()\n for (const entry of zipDir.files) {\n const mode = (entry.externalFileAttributes >> 16) & 0xffff\n if (mode > 0) {\n entryModes.set(entry.path, mode)\n }\n }\n const isSymlink = (mode: number) => (mode & 0o170000) === 0o120000\n\n // Pass 2: stream from byte 0 — no per-entry seeks, no Docker hang.\n // Destroy the read stream in a finally block so the file handle is always released,\n // including when the loop exits early due to a thrown error.\n const readStream = createReadStream(file)\n try {\n const entries = readStream.pipe(unzipper.Parse({ forceStream: true }))\n for await (const entry of entries as AsyncIterable<unzipper.Entry>) {\n const destPath = path.resolve(dir, entry.path)\n if (!isSafeExtractPath(destPath, dir)) {\n throw new Error(`Path traversal blocked: ${entry.path}`)\n }\n const mode = entryModes.get(entry.path) ?? 0\n if (mode > 0 && isSymlink(mode)) {\n const target = (await entry.buffer()).toString()\n if (path.isAbsolute(target)) {\n throw new Error(`Absolute symlink target blocked: ${target}`)\n }\n const resolvedTarget = path.resolve(path.dirname(destPath), target)\n if (!isSafeExtractPath(resolvedTarget, dir)) {\n throw new Error(`Symlink target escapes extraction dir: ${target}`)\n }\n await fs.mkdir(path.dirname(destPath), { recursive: true })\n await fs.symlink(target, destPath)\n } else if (entry.type === \"Directory\") {\n await fs.mkdir(destPath, { recursive: true })\n entry.autodrain()\n } else {\n await fs.mkdir(path.dirname(destPath), { recursive: true })\n await pipeline(entry, createWriteStream(destPath))\n if (mode > 0) {\n await fs.chmod(destPath, mode & 0o7777)\n }\n }\n }\n } finally {\n readStream.destroy()\n }\n}\n\nexport async function extractArchive(file: string, dir: string) {\n const tmpDir = `${dir}.tmp`\n await fs.mkdir(tmpDir, { recursive: true })\n\n const release = await lockfile.lock(tmpDir, {\n // 100 retries (not 15) so concurrent callers wait out a slow first extraction instead of failing\n // with ELOCKED; the update heartbeat keeps an in-progress holder's lock fresh against `stale`.\n retries: { retries: 100, minTimeout: 1000, maxTimeout: 5000 },\n stale: 120000, // Increased from 60s to allow long-running extractions\n })\n\n try {\n // rm + mkdir happen AFTER acquiring the lock so no concurrent caller can clear our tmpDir mid-extraction\n await fs.rm(tmpDir, { recursive: true, force: true })\n await fs.mkdir(tmpDir, { recursive: true })\n\n // Guard against the transient window in @electron/get's non-atomic putFileInCache (remove → move).\n // A concurrent worker may have deleted and not yet replaced the source archive; wait briefly for it.\n for (let i = 0; !(await exists(file)); i++) {\n if (i >= 4) {\n throw Object.assign(new Error(`Source archive not found after retries: ${file}`), { code: \"ENOENT\", path: file })\n }\n log.warn({ file, attempt: i + 1 }, \"source archive transiently missing, retrying\")\n await sleep(300 * (i + 1))\n }\n\n if (file.endsWith(\".tar.gz\") || file.endsWith(\".tgz\")) {\n await tar.extract({ file, cwd: tmpDir, strip: 1 })\n } else if (file.endsWith(\".tar.xz\") || file.endsWith(\".txz\")) {\n // node-tar cannot decompress xz, so use 7za to turn the .tar.xz into a .tar, then extract that tar.\n const cmd7za = await getPath7za()\n const xzOutDir = `${tmpDir}.xz`\n await fs.rm(xzOutDir, { recursive: true, force: true })\n await fs.mkdir(xzOutDir, { recursive: true })\n try {\n await exec(cmd7za, [\"x\", \"-bd\", file, to7zaOutputSwitch(sanitizeDirPath(xzOutDir)), \"-y\"])\n const innerTar = (await fs.readdir(xzOutDir)).find(f => f.endsWith(\".tar\"))\n if (innerTar == null) {\n throw new Error(`xz decompression of ${path.basename(file)} produced no .tar archive`)\n }\n await tar.extract({ file: path.join(xzOutDir, innerTar), cwd: tmpDir, strip: 1 })\n } finally {\n await fs.rm(xzOutDir, { recursive: true, force: true })\n }\n } else if (file.endsWith(\".zip\")) {\n await extractZipStreaming(file, tmpDir)\n } else if (file.endsWith(\".7z\")) {\n const cmd7za = await getPath7za()\n try {\n await exec(cmd7za, [\"x\", \"-bd\", file, to7zaOutputSwitch(sanitizeDirPath(tmpDir)), \"-y\"])\n } catch (e: any) {\n // Check if extraction actually failed or just had benign warnings\n const files = await fs.readdir(tmpDir)\n if (files.length === 0) {\n log.warn({ file: log.filePath(file), tmpDir: log.filePath(tmpDir), error: e.message }, \"7z extraction produced no output\")\n throw new Error(`7z extraction failed for ${file}: ${e.message}`)\n }\n // If files were extracted despite the error, log and continue\n log.warn({ error: e.message, filesExtracted: files.length }, \"7z reported error but extracted files\")\n }\n } else {\n throw new Error(`Unsupported archive format: ${path.basename(file)}`)\n }\n\n // Verify extraction produced files\n const extractedFiles = await fs.readdir(tmpDir)\n if (extractedFiles.length === 0) {\n throw new Error(`Extraction of ${path.basename(file)} produced no files`)\n }\n\n await fs.rm(dir, { recursive: true, force: true })\n await moveDirAtomic(tmpDir, dir)\n } finally {\n await release().catch(err => log.warn({ err }, \"failed to release lockfile\"))\n }\n}\n\nlet proxyInitialized = false\nfunction initializeProxyOnce(): void {\n if (!proxyInitialized) {\n reinitializeProxy()\n proxyInitialized = true\n }\n}\n\n/**\n * Forces undici's global proxy dispatcher to re-read the current HTTP(S)_PROXY / NO_PROXY env vars,\n * bypassing the once-guard in initializeProxyOnce(). Exported for integration testing only.\n */\nexport function reinitializeProxy(): void {\n get.initializeProxy()\n}\n\nasync function downloadArtifactToFile(config: ElectronArtifactDetails, label: string): Promise<string> {\n // Serialize concurrent downloads of the same artifact across vitest workers to prevent @electron/get's\n // non-atomic putFileInCache (remove + move) from racing with a concurrent reader.\n const key = {\n p: (config as ElectronPlatformArtifactDetails).platform,\n a: (config as ElectronPlatformArtifactDetails).arch,\n v: config.version,\n n: config.artifactName,\n g: config.isGeneric,\n }\n\n const artifactLockKey = crypto.createHash(\"sha256\").update(JSON.stringify(key)).digest(\"hex\").slice(0, 20)\n const artifactLockPath = path.join(os.tmpdir(), `eb-dl-${artifactLockKey}.lock`)\n // This lock is taken even for cache hits (the cache-hit check lives inside @electron/get), so under\n // heavy concurrency many builds serialize here. 30 retries (~137s of backoff) is too few — waiters\n // were exhausting it and failing with ELOCKED while the holder fetched a large artifact. 100 retries\n // matches the other toolset locks; stale (10min) + proper-lockfile's update heartbeat keep a live\n // downloader's lock fresh so the longer wait never falsely steals an in-progress download.\n const releaseArtifactLock = await lockfile.lock(artifactLockPath, {\n retries: { retries: 100, minTimeout: 500, maxTimeout: 5000 },\n stale: 600_000,\n realpath: false,\n })\n let lastLoggedMilestone = -1\n const state: { bar: ProgressBar | undefined } = { bar: undefined }\n\n // @electron/get v5 downloads via fetch, whose proxy support comes from undici's global dispatcher.\n // initializeProxy() wires that up from HTTP(S)_PROXY/NO_PROXY env vars (replaces the got proxy agent).\n initializeProxyOnce()\n\n const downloadOptions: FetchDownloaderOptions = {\n signal: AbortSignal.timeout(10 * 60 * 1000), // prevent indefinite hang on stalled connections\n ...config.downloadOptions,\n getProgressCallback: info => {\n // @electron/get passes downloadOptions (including this callback) to its internal\n // SHASUMS256.txt validation download. That file is tiny (<1 MB) and fires at 100%\n // immediately, producing a spurious bar even when the artifact itself is cached.\n // Skip progress display for any download whose total size is known and small.\n if (info.total && info.total < 1_000_000) {\n return Promise.resolve()\n }\n if (!state.bar && process.stdout.isTTY) {\n log.info({ label }, \"downloading\")\n state.bar = new MultiProgress().createBar(`${\" \".repeat(PADDING + 2)}[:bar] :percent | ${label}`, { total: 100 })\n }\n const pct = info.percent != null ? Math.floor(info.percent * 100) : 0\n if (state.bar) {\n state.bar.update(pct)\n } else {\n // log every 25% milestone for non-TTY environments (e.g. CI logs) to provide some visibility into download progress without overwhelming logs with too many updates\n const percentCompleted = info.transferred && info.total ? Math.floor((info.transferred / info.total) * 100) : Math.floor(pct / 25) * 25\n if (percentCompleted > lastLoggedMilestone && percentCompleted > 0) {\n lastLoggedMilestone = percentCompleted\n log.info({ label, progress: `${percentCompleted}%` }, percentCompleted !== 100 ? \"downloading\" : \"downloaded\")\n }\n }\n return Promise.resolve()\n },\n }\n\n const configWithProgress = { ...config, downloadOptions }\n try {\n let filePath: string\n try {\n filePath = await retry(() => get.downloadArtifact(configWithProgress), {\n retries: 3,\n interval: 2000,\n backoff: 2000,\n shouldRetry: (e: any) =>\n e instanceof HttpError ? e.isServerError() : typeof e?.code === \"string\" && [\"ENOTFOUND\", \"ETIMEDOUT\", \"ECONNRESET\", \"EPIPE\", \"ENOENT\"].includes(e.code),\n })\n } catch (err) {\n if (typeof (err as any)?.message === \"string\" && (err as any).message.includes(\"dest already exists\")) {\n filePath = await get.downloadArtifact(configWithProgress)\n } else {\n throw err\n }\n }\n if (!(await exists(filePath))) {\n log.warn({ filePath, label }, \"cached artifact missing from disk; retrying with cache write\")\n filePath = await get.downloadArtifact({ ...configWithProgress, cacheMode: ElectronDownloadCacheMode.WriteOnly })\n }\n if (!state.bar && lastLoggedMilestone === -1) {\n log.info({ label }, \"using cached artifact\")\n }\n return filePath\n } finally {\n state.bar?.update(100)\n state.bar?.terminate()\n await releaseArtifactLock().catch(err => log.warn({ err }, \"failed to release artifact download lock\"))\n }\n}\n\n/**\n * Checks electron-builder's own archive cache for a previously downloaded archive.\n * Validates the SHA-256 checksum when one is known. Returns the cached path on hit,\n * null on miss or checksum mismatch (mismatch also deletes the stale file).\n */\nasync function resolveFromArchiveCache(archiveCachePath: string, label: string, expectedSha256: string | undefined): Promise<string | null> {\n if (!(await exists(archiveCachePath))) {\n return null\n }\n if (expectedSha256) {\n const hash = await new Promise<string>((resolve, reject) => {\n const h = crypto.createHash(\"sha256\")\n const s = createReadStream(archiveCachePath)\n s.on(\"error\", reject)\n s.on(\"data\", (chunk: Buffer | string) => h.update(chunk))\n s.on(\"end\", () => resolve(h.digest(\"hex\")))\n })\n if (hash !== expectedSha256) {\n log.warn({ file: label, archiveCachePath }, \"cached archive checksum mismatch — removing and re-downloading\")\n await fs.rm(archiveCachePath).catch(() => {})\n return null\n }\n }\n log.debug({ file: label, archiveCachePath }, \"using cached archive — skipping download\")\n return archiveCachePath\n}\n\n/**\n * Copies a freshly downloaded archive into electron-builder's own archive cache so that\n * future builds (including offline environments) can skip the network request entirely.\n */\nasync function persistToArchiveCache(sourcePath: string, archiveCachePath: string): Promise<void> {\n try {\n await fs.mkdir(path.dirname(archiveCachePath), { recursive: true })\n await fs.copyFile(sourcePath, archiveCachePath)\n } catch (err) {\n log.warn({ err, archiveCachePath }, \"failed to persist archive to cache — will re-download next time\")\n }\n}\n\n/**\n * Core download + extract engine. Handles lockfile, cache-hit short-circuit,\n * progress bar, extraction (.zip or .tar.gz), and completion marker.\n * Both public download functions delegate here after building their respective configs.\n */\nasync function downloadAndExtract(config: ElectronArtifactDetails, extractDir: string, label: string, archiveCachePath?: string): Promise<string> {\n // Create only the PARENT dir (e.g. <cache>/fpm@2.2.1), never extractDir itself, before locking.\n // The parent is stable — cleanup only ever removes extractDir and its .state/.tmp/.lock siblings —\n // so extractDir's whole lifecycle (mkdir, rm, re-mkdir) stays inside the lock. ensureDir absorbs\n // the concurrent-recursive-mkdir ENOENT/EEXIST race while peers populate the cold cache tree.\n await ensureDir(path.dirname(extractDir))\n\n // Pre-lock fast path: read-only short-circuit for a definitively complete and valid cache.\n // Safe unlocked — the cache-state helpers return null/false for a missing or half-written dir,\n // so a racing read only ever falls through to take the lock. Do NOT mutate the dir here.\n const stateData = await readCacheStateFile(extractDir)\n if (stateData?.state === CacheState.complete) {\n const isValid = await validateCacheDirectory(extractDir, stateData.fileCount)\n if (isValid) {\n log.debug({ file: label, path: extractDir }, \"using cached artifact - cache valid\")\n return extractDir\n }\n }\n\n // Be patient: when many targets/builds contend on the same toolset cache concurrently, all but the\n // first wait here while the winner downloads+extracts (a large bundle can take >1min). 15 retries\n // (~67s) is too few and waiters fail with ELOCKED before the winner finishes; 100 matches the\n // patience of withToolsetLock. proper-lockfile's update heartbeat keeps a live holder's lock fresh,\n // so increasing waiter retries never falsely steals an in-progress extraction.\n const release = await lockfile.lock(extractDir, {\n // realpath:false so proper-lockfile creates <extractDir>.lock in the (already-created) parent\n // WITHOUT calling fs.realpath(extractDir) first — which would throw ENOENT now that extractDir\n // is created lazily inside the lock. This filesystem lock serializes peers both across worker\n // processes AND within a single process (a second lock() for the same path retries until the\n // first releases), so no in-process promise cache is needed — and one wouldn't help across the\n // separate test worker processes anyway.\n realpath: false,\n retries: { retries: 100, minTimeout: 1000, maxTimeout: 5000 },\n stale: 120000,\n })\n let downloadedFile: string | null = null\n try {\n // Re-check after acquiring lock: another worker may have completed while we waited.\n const stateDataAfterLock = await readCacheStateFile(extractDir)\n if (stateDataAfterLock?.state === CacheState.complete) {\n const isValid = await validateCacheDirectory(extractDir, stateDataAfterLock.fileCount)\n if (isValid) {\n log.debug({ file: label, path: extractDir }, \"using cached artifact - skipping download/extract\")\n return extractDir\n }\n log.warn({ extractDir }, \"Cache marked complete but files invalid, clearing\")\n } else if (stateDataAfterLock?.state === CacheState.corrupted) {\n log.warn({ extractDir }, \"Corrupted cache detected, cleaning up and re-extracting\")\n }\n\n // Cleanup inside the lock — skip lock files since we currently hold them\n await cleanupCacheDirectory(extractDir, { skipLockFiles: true })\n await ensureDir(extractDir)\n\n // Check electron-builder's own archive cache before touching @electron/get.\n // The cache lives alongside the extract dir: <cacheDir>/<releaseName>/<filename>.\n // This lets repeated builds (or offline environments) skip the download entirely once\n // the archive has been fetched at least once.\n if (archiveCachePath) {\n downloadedFile = await resolveFromArchiveCache(archiveCachePath, label, (config as any).checksums?.[label])\n }\n\n if (!downloadedFile) {\n log.debug({ file: label }, \"downloading\")\n downloadedFile = await downloadArtifactToFile(config, label)\n if (!downloadedFile) {\n throw new Error(`Failed to download artifact: ${label}`)\n }\n // Persist the downloaded archive so future builds (and offline environments) can\n // skip the network request entirely.\n if (archiveCachePath) {\n await persistToArchiveCache(downloadedFile, archiveCachePath)\n }\n }\n\n await writeCacheState(extractDir, CacheState.downloaded)\n\n // Mark extracting so stale-lock detection can recover a crashed mid-extraction process\n await writeCacheState(extractDir, CacheState.extracting)\n\n // Extract while holding the lock to prevent concurrent interference\n await extractArchive(downloadedFile, extractDir)\n\n // Compute metadata with a full recursive walk now that tmpDir has been renamed to extractDir\n const { fileCount, extractedSize } = await computeCacheMetadata(extractDir)\n\n // Write complete state with metadata BEFORE releasing the lock; throwOnError=true so a\n // failed write (disk full, permissions) propagates instead of silently producing a no-op cache\n await writeCacheState(extractDir, CacheState.complete, { fileCount, extractedSize }, true)\n } finally {\n await release().catch(err => log.warn({ err }, \"failed to release lockfile\"))\n }\n return extractDir\n}\n\n// ─── Public API ───────────────────────────────────────────────────────────────\n\n/**\n * Copies a remote artifact to a specific output path on disk.\n * Unlike downloadBuilderToolset, this does not extract archives — it copies the raw file.\n * Used for certificate imports where the caller needs the file at a known path.\n */\nexport async function download(url: string, output: string, checksum?: string | null): Promise<void> {\n const filenameWithExt = path.basename(new URL(url).pathname)\n if (checksum == null) {\n log.warn({ url }, \"downloading without an integrity checksum — the download is not verified against a known-good hash\")\n }\n const downloadedFile = await downloadArtifactToFile(\n {\n version: \"9.9.9\",\n artifactName: filenameWithExt,\n cacheRoot: path.resolve(getCacheDirectory({ allowEnvVarOverride: true }), \"downloads\"),\n cacheMode: resolveCacheMode(),\n ...(checksum != null ? { checksums: { [filenameWithExt]: checksum } } : { unsafelyDisableChecksums: true }),\n mirrorOptions: { resolveAssetURL: async () => Promise.resolve(url) },\n isGeneric: true,\n },\n filenameWithExt\n )\n await fs.copyFile(downloadedFile, output)\n}\n\nfunction validateBinaryCustomDir(envVarName: string, value: string): string {\n if (value.includes(\"://\") || value.includes(\"..\") || value.startsWith(\"/\")) {\n throw new Error(\n `${envVarName} must be a safe relative path component (e.g. \"v1.0.0-custom\"). ` + `Values containing \"://\", \"..\", or a leading \"/\" are not allowed. Got: \"${value}\"`\n )\n }\n return value\n}\n\nconst CUSTOM_DIR_ENV_VARS = [\n \"NPM_CONFIG_ELECTRON_BUILDER_BINARIES_CUSTOM_DIR\",\n \"npm_config_electron_builder_binaries_custom_dir\",\n \"npm_package_config_electron_builder_binaries_custom_dir\",\n \"ELECTRON_BUILDER_BINARIES_CUSTOM_DIR\",\n] as const\n\n/**\n * Resolves the final download URL for a builder binary, honouring:\n * ELECTRON_BUILDER_BINARIES_DOWNLOAD_OVERRIDE_URL – fully replaces the URL directory\n * ELECTRON_BUILDER_BINARIES_CUSTOM_DIR (and npm_ variants) – replaces releaseName in the path\n * overrideUrl (caller-supplied) – used as-is when no env var is set\n *\n * Exported for unit testing; not part of the public API.\n * @internal\n */\nexport function resolveBuilderBinaryUrl(releaseName: string, filenameWithExt: string, baseUrl: string, overrideUrl?: string): string {\n const envOverrideUrl = parseValidEnvVarUrl(\"ELECTRON_BUILDER_BINARIES_DOWNLOAD_OVERRIDE_URL\")\n if (envOverrideUrl != null) {\n return `${envOverrideUrl}/${filenameWithExt}`\n }\n if (overrideUrl != null) {\n return `${overrideUrl}/${filenameWithExt}`\n }\n const customDirEntry = CUSTOM_DIR_ENV_VARS.map(name => ({ name, value: process.env[name] })).find(e => e.value != null)\n if (customDirEntry != null) {\n return `${baseUrl}${validateBinaryCustomDir(customDirEntry.name, customDirEntry.value!)}/${filenameWithExt}`\n }\n return `${baseUrl}${releaseName}/${filenameWithExt}`\n}\n\n/**\n * Downloads a generic artifact (.tar.gz or .zip) from a GitHub release.\n * Used for electron-builder-binaries tools (appimage, etc.).\n */\nexport async function downloadBuilderToolset(options: {\n releaseName: string\n filenameWithExt: string\n checksums?: Record<string, string>\n githubOrgRepo?: string\n overrideUrl?: string\n}): Promise<string> {\n const { releaseName, filenameWithExt, checksums, githubOrgRepo = \"electron-userland/electron-builder-binaries\", overrideUrl } = options\n\n if (/[/\\\\]|^\\.\\./.test(filenameWithExt) || filenameWithExt.includes(\"..\")) {\n throw new Error(`downloadBuilderToolset: unsafe filenameWithExt \"${filenameWithExt}\" — must be a plain filename with no path separators or traversal sequences`)\n }\n\n const baseUrl = getBinariesMirrorUrl(githubOrgRepo)\n const fullUrl = resolveBuilderBinaryUrl(releaseName, filenameWithExt, baseUrl, overrideUrl)\n const suffix = hashUrlSafe(fullUrl, 5)\n const folderName = `${filenameWithExt.replace(/\\.(tar\\.gz|tgz|tar\\.xz|txz|zip|7z)$/, \"\")}-${suffix}`\n // releaseName is library input; enforce cache-dir containment (rejects traversal, clears taint into shell extraction)\n const cacheDir = getCacheDirectory({ allowEnvVarOverride: true })\n const extractDir = sanitizeDirPath(path.join(cacheDir, releaseName, folderName), cacheDir)\n\n // Use resolveAssetURL so @electron/get's ELECTRON_MIRROR env var check cannot override\n // the builder-binaries URL we've already resolved (see getArtifactRemoteURL in @electron/get).\n const mirrorOptions: MirrorOptions = {\n resolveAssetURL: async () => Promise.resolve(fullUrl),\n }\n\n // Predictable archive cache: <cacheDir>/<releaseName>/<filename>, next to the extract dir.\n // downloadAndExtract checks here before touching @electron/get and persists the archive here\n // after every successful download, so subsequent builds never need a network round-trip.\n const archiveCachePath = sanitizeDirPath(path.join(cacheDir, releaseName, filenameWithExt), cacheDir)\n\n const config: ElectronDownloadRequest & ElectronDownloadRequestOptions & { isGeneric: true } = {\n version: \"9.9.9\", // must be >1.3.2 to bypass @electron/get validation shortcut\n artifactName: filenameWithExt,\n cacheRoot: path.resolve(getCacheDirectory({ allowEnvVarOverride: true }), \"downloads\"),\n cacheMode: resolveCacheMode(),\n ...(checksums != null ? { checksums } : { unsafelyDisableChecksums: true }),\n mirrorOptions,\n isGeneric: true,\n }\n return downloadAndExtract(config, extractDir, filenameWithExt, archiveCachePath)\n}\n\n/**\n * Downloads and extracts an electron platform artifact (e.g. ffmpeg) using @electron/get.\n * Deduplicates concurrent calls for the same artifact within the same process.\n */\nfunction buildElectronArtifactConfig(artifactOptions: ArtifactDownloadOptions): ElectronPlatformArtifactDetails {\n const { options, arch, version, platformName: platform, artifactName, cacheDir: cacheRoot } = artifactOptions\n\n if (options?.unsafelyDisableChecksums) {\n log.warn(\n { artifactName },\n \"electronGet.unsafelyDisableChecksums is enabled — downloaded artifacts will NOT be verified.txt; a compromised mirror can serve malicious binaries undetected\"\n )\n }\n\n const artifactConfig: ElectronPlatformArtifactDetails = { ...options, cacheRoot, platform, arch, version, artifactName, cacheMode: resolveCacheMode() }\n return artifactConfig\n}\n\n/**\n * Downloads the electron artifact zip via @electron/get (with caching) and returns the zip file path.\n * Use when you need to extract the zip yourself (e.g. directly to appOutDir to preserve empty dirs and symlinks).\n */\nexport function downloadElectronArtifactZip(options: ArtifactDownloadOptions): Promise<string> {\n const config = buildElectronArtifactConfig(options)\n return downloadArtifactToFile(config, config.artifactName)\n}\n\nexport async function downloadElectronArtifact(options: ArtifactDownloadOptions): Promise<string> {\n const { arch, version, platformName: platform, artifactName } = options\n const artifactConfig = buildElectronArtifactConfig(options)\n\n const suffix = hashUrlSafe(JSON.stringify(artifactConfig), 5)\n const folderName = `${artifactName}-v${version}-${platform}-${arch}-${suffix}`\n const extractDir = path.join(getCacheDirectory({ allowEnvVarOverride: true }), `${artifactName}-v${version}`, folderName)\n\n return downloadAndExtract(artifactConfig, extractDir, artifactName)\n}\n\n/**\n * Get the binaries mirror URL from environment variables.\n * Supports various npm config formats and falls back to GitHub.\n */\nexport function getBinariesMirrorUrl(githubOrgRepo: string): string {\n const allowHttp = process.env[\"ELECTRON_BUILDER_DANGEROUSLY_ALLOW_HTTP\"] === \"true\"\n for (const envVar of [\n \"NPM_CONFIG_ELECTRON_BUILDER_BINARIES_MIRROR\",\n \"npm_config_electron_builder_binaries_mirror\",\n \"npm_package_config_electron_builder_binaries_mirror\",\n \"ELECTRON_BUILDER_BINARIES_MIRROR\",\n ]) {\n const url = parseValidEnvVarUrl(envVar, allowHttp)\n if (url) {\n return url.endsWith(\"/\") ? url : `${url}/`\n }\n }\n return `https://github.com/${githubOrgRepo}/releases/download/`\n}\n"]}
@@ -1,7 +1,5 @@
1
- export declare function isUseSystemSigncode(): boolean;
2
1
  export declare function isAutoDiscoveryCodeSignIdentity(): boolean;
3
2
  export declare function isCscForPullRequest(): boolean;
4
- export declare function isUseSystemOsslSigncode(): boolean;
5
3
  export declare function isBuildCacheEnabled(): boolean;
6
4
  export declare function isRemoveStageDirEvenIfDebug(): boolean;
7
5
  export declare function isOfflineModeEnabled(): boolean;
@@ -10,7 +8,6 @@ export declare function isElectronBuilderAllowedAsProductionDependency(): boolea
10
8
  export declare function isNpmNoBinLinks(): boolean;
11
9
  export declare function isTravis(): boolean;
12
10
  export declare function isUseSystemFpm(): boolean;
13
- export declare function isUseSystemWine(): boolean;
14
11
  export declare function isFpmDebug(): boolean;
15
12
  export declare function isSnapDestructiveMode(): boolean;
16
13
  //# sourceMappingURL=flags.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"flags.d.ts","sourceRoot":"","sources":["../../src/util/flags.ts"],"names":[],"mappings":"AAIA,wBAAgB,mBAAmB,YAElC;AAED,wBAAgB,+BAA+B,YAE9C;AAED,wBAAgB,mBAAmB,YAElC;AAED,wBAAgB,uBAAuB,YAEtC;AAID,wBAAgB,mBAAmB,YAElC;AAED,wBAAgB,2BAA2B,YAE1C;AAED,wBAAgB,oBAAoB,YAEnC;AAID,wBAAgB,uBAAuB,YAEtC;AAID,wBAAgB,8CAA8C,YAE7D;AAED,wBAAgB,eAAe,YAE9B;AAID,wBAAgB,QAAQ,YAEvB;AAID,wBAAgB,cAAc,YAE7B;AAED,wBAAgB,eAAe,YAE9B;AAED,wBAAgB,UAAU,YAEzB;AAED,wBAAgB,qBAAqB,YAEpC"}
1
+ {"version":3,"file":"flags.d.ts","sourceRoot":"","sources":["../../src/util/flags.ts"],"names":[],"mappings":"AAIA,wBAAgB,+BAA+B,YAE9C;AAED,wBAAgB,mBAAmB,YAElC;AAID,wBAAgB,mBAAmB,YAElC;AAED,wBAAgB,2BAA2B,YAE1C;AAED,wBAAgB,oBAAoB,YAEnC;AAID,wBAAgB,uBAAuB,YAEtC;AAID,wBAAgB,8CAA8C,YAE7D;AAED,wBAAgB,eAAe,YAE9B;AAID,wBAAgB,QAAQ,YAEvB;AAID,wBAAgB,cAAc,YAE7B;AAED,wBAAgB,UAAU,YAEzB;AAED,wBAAgB,qBAAqB,YAEpC"}
@@ -1,17 +1,11 @@
1
1
  import { isEnvTrue } from "builder-util";
2
2
  // ─── Code signing ─────────────────────────────────────────────────────────────
3
- export function isUseSystemSigncode() {
4
- return isEnvTrue(process.env.USE_SYSTEM_SIGNCODE);
5
- }
6
3
  export function isAutoDiscoveryCodeSignIdentity() {
7
4
  return process.env.CSC_IDENTITY_AUTO_DISCOVERY !== "false";
8
5
  }
9
6
  export function isCscForPullRequest() {
10
7
  return isEnvTrue(process.env.CSC_FOR_PULL_REQUEST);
11
8
  }
12
- export function isUseSystemOsslSigncode() {
13
- return isEnvTrue(process.env.USE_SYSTEM_OSSLSIGNCODE);
14
- }
15
9
  // ─── Build behaviour ──────────────────────────────────────────────────────────
16
10
  export function isBuildCacheEnabled() {
17
11
  return !isEnvTrue(process.env.ELECTRON_BUILDER_DISABLE_BUILD_CACHE);
@@ -41,9 +35,6 @@ export function isTravis() {
41
35
  export function isUseSystemFpm() {
42
36
  return isEnvTrue(process.env.USE_SYSTEM_FPM);
43
37
  }
44
- export function isUseSystemWine() {
45
- return isEnvTrue(process.env.USE_SYSTEM_WINE);
46
- }
47
38
  export function isFpmDebug() {
48
39
  return isEnvTrue(process.env.FPM_DEBUG);
49
40
  }