app-builder-lib 26.10.0 → 26.11.1

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 (88) hide show
  1. package/out/ProtonFramework.d.ts +1 -1
  2. package/out/ProtonFramework.js +2 -2
  3. package/out/ProtonFramework.js.map +1 -1
  4. package/out/configuration.d.ts +95 -65
  5. package/out/configuration.js.map +1 -1
  6. package/out/core.d.ts +2 -2
  7. package/out/core.js.map +1 -1
  8. package/out/electron/ElectronFramework.js +6 -3
  9. package/out/electron/ElectronFramework.js.map +1 -1
  10. package/out/frameworks/LibUiFramework.d.ts +3 -2
  11. package/out/frameworks/LibUiFramework.js +5 -2
  12. package/out/frameworks/LibUiFramework.js.map +1 -1
  13. package/out/index.d.ts +1 -1
  14. package/out/index.js.map +1 -1
  15. package/out/node-module-collector/moduleManager.d.ts +7 -1
  16. package/out/node-module-collector/moduleManager.js +9 -2
  17. package/out/node-module-collector/moduleManager.js.map +1 -1
  18. package/out/node-module-collector/nodeModulesCollector.js +5 -4
  19. package/out/node-module-collector/nodeModulesCollector.js.map +1 -1
  20. package/out/node-module-collector/pnpmNodeModulesCollector.d.ts +13 -0
  21. package/out/node-module-collector/pnpmNodeModulesCollector.js +54 -12
  22. package/out/node-module-collector/pnpmNodeModulesCollector.js.map +1 -1
  23. package/out/options/AppXOptions.d.ts +1 -1
  24. package/out/options/AppXOptions.js.map +1 -1
  25. package/out/options/PlatformSpecificBuildOptions.d.ts +31 -11
  26. package/out/options/PlatformSpecificBuildOptions.js.map +1 -1
  27. package/out/options/SnapOptions.d.ts +1 -1
  28. package/out/options/SnapOptions.js.map +1 -1
  29. package/out/options/linuxOptions.d.ts +38 -12
  30. package/out/options/linuxOptions.js.map +1 -1
  31. package/out/options/macOptions.d.ts +10 -7
  32. package/out/options/macOptions.js.map +1 -1
  33. package/out/options/metadata.d.ts +1 -2
  34. package/out/options/metadata.js.map +1 -1
  35. package/out/options/pkgOptions.d.ts +1 -1
  36. package/out/options/pkgOptions.js.map +1 -1
  37. package/out/options/winOptions.d.ts +15 -5
  38. package/out/options/winOptions.js.map +1 -1
  39. package/out/packager.js +2 -3
  40. package/out/packager.js.map +1 -1
  41. package/out/platformPackager.js +1 -1
  42. package/out/platformPackager.js.map +1 -1
  43. package/out/targets/FpmTarget.js +3 -2
  44. package/out/targets/FpmTarget.js.map +1 -1
  45. package/out/targets/LinuxTargetHelper.d.ts +4 -4
  46. package/out/targets/LinuxTargetHelper.js.map +1 -1
  47. package/out/targets/appimage/AppImageTarget.d.ts +1 -0
  48. package/out/targets/appimage/AppImageTarget.js +30 -10
  49. package/out/targets/appimage/AppImageTarget.js.map +1 -1
  50. package/out/targets/appimage/appImageUtil.d.ts +10 -2
  51. package/out/targets/appimage/appImageUtil.js +2 -5
  52. package/out/targets/appimage/appImageUtil.js.map +1 -1
  53. package/out/targets/archive.js +20 -6
  54. package/out/targets/archive.js.map +1 -1
  55. package/out/targets/nsis/NsisTarget.js +11 -11
  56. package/out/targets/nsis/NsisTarget.js.map +1 -1
  57. package/out/targets/nsis/nsisOptions.d.ts +20 -16
  58. package/out/targets/nsis/nsisOptions.js.map +1 -1
  59. package/out/targets/nsis/nsisScriptGenerator.d.ts +1 -0
  60. package/out/targets/nsis/nsisScriptGenerator.js +14 -1
  61. package/out/targets/nsis/nsisScriptGenerator.js.map +1 -1
  62. package/out/targets/nsis/nsisUtil.js +2 -1
  63. package/out/targets/nsis/nsisUtil.js.map +1 -1
  64. package/out/util/appBuilder.js +1 -1
  65. package/out/util/appBuilder.js.map +1 -1
  66. package/out/util/cacheState.d.ts +28 -0
  67. package/out/util/cacheState.js +143 -0
  68. package/out/util/cacheState.js.map +1 -0
  69. package/out/util/electronGet.d.ts +1 -1
  70. package/out/util/electronGet.js +89 -33
  71. package/out/util/electronGet.js.map +1 -1
  72. package/out/util/macroExpander.js +3 -0
  73. package/out/util/macroExpander.js.map +1 -1
  74. package/out/util/resEdit.d.ts +10 -0
  75. package/out/util/resEdit.js +48 -0
  76. package/out/util/resEdit.js.map +1 -0
  77. package/out/util/resolve.js +11 -1
  78. package/out/util/resolve.js.map +1 -1
  79. package/out/version.d.ts +1 -1
  80. package/out/version.js +1 -1
  81. package/out/version.js.map +1 -1
  82. package/out/vm/ParallelsVm.d.ts +16 -0
  83. package/out/vm/ParallelsVm.js +0 -1
  84. package/out/vm/ParallelsVm.js.map +1 -1
  85. package/out/winPackager.js +44 -42
  86. package/out/winPackager.js.map +1 -1
  87. package/package.json +8 -8
  88. package/scheme.json +611 -133
@@ -18,6 +18,7 @@ const lockfile = require("proper-lockfile");
18
18
  const promises_1 = require("stream/promises");
19
19
  const tar = require("tar");
20
20
  const unzipper = require("unzipper");
21
+ const cacheState_1 = require("./cacheState");
21
22
  function hashUrlSafe(input, length = 6) {
22
23
  let hash = 5381;
23
24
  for (let i = 0; i < input.length; i++) {
@@ -27,10 +28,10 @@ function hashUrlSafe(input, length = 6) {
27
28
  const out = hash.toString(36);
28
29
  return out.length >= length ? out.slice(0, length) : out.padStart(length, "0");
29
30
  }
30
- function getCacheDirectory(isAvoidSystemOnWindows = false) {
31
+ function getCacheDirectory(isAvoidSystemOnWindows = false, allowEnvVarOverride = true) {
31
32
  var _a, _b, _c, _d, _e;
32
33
  const env = (_a = process.env.ELECTRON_BUILDER_CACHE) === null || _a === void 0 ? void 0 : _a.trim();
33
- if (env && path.parse(env).root) {
34
+ if (allowEnvVarOverride && env && path.parse(env).root) {
34
35
  return env;
35
36
  }
36
37
  const appName = "electron-builder";
@@ -112,7 +113,7 @@ async function extractArchive(file, dir) {
112
113
  await fs.mkdir(tmpDir, { recursive: true });
113
114
  const release = await lockfile.lock(tmpDir, {
114
115
  retries: { retries: 5, minTimeout: 1000, maxTimeout: 5000 },
115
- stale: 60000,
116
+ stale: 120000, // Increased from 60s to allow long-running extractions
116
117
  });
117
118
  try {
118
119
  // rm + mkdir happen AFTER acquiring the lock so no concurrent caller can clear our tmpDir mid-extraction
@@ -125,11 +126,29 @@ async function extractArchive(file, dir) {
125
126
  await extractZipStreaming(file, tmpDir);
126
127
  }
127
128
  else if (file.endsWith(".7z")) {
128
- await (0, builder_util_1.exec)(await (0, builder_util_1.getPath7za)(), ["x", "-bd", file, `-o${tmpDir}`, "-y"]);
129
+ const cmd7za = await (0, builder_util_1.getPath7za)();
130
+ try {
131
+ await (0, builder_util_1.exec)(cmd7za, ["x", "-bd", file, `-o${tmpDir}`, "-y"]);
132
+ }
133
+ catch (e) {
134
+ // Check if extraction actually failed or just had benign warnings
135
+ const files = await fs.readdir(tmpDir);
136
+ if (files.length === 0) {
137
+ builder_util_1.log.warn({ file, tmpDir, error: e.message }, "7z extraction produced no output");
138
+ throw new Error(`7z extraction failed for ${file}: ${e.message}`);
139
+ }
140
+ // If files were extracted despite the error, log and continue
141
+ builder_util_1.log.warn({ error: e.message, filesExtracted: files.length }, "7z reported error but extracted files");
142
+ }
129
143
  }
130
144
  else {
131
145
  throw new Error(`Unsupported archive format: ${path.basename(file)}`);
132
146
  }
147
+ // Verify extraction produced files
148
+ const extractedFiles = await fs.readdir(tmpDir);
149
+ if (extractedFiles.length === 0) {
150
+ throw new Error(`Extraction of ${path.basename(file)} produced no files`);
151
+ }
133
152
  await fs.rm(dir, { recursive: true, force: true });
134
153
  await fs.rename(tmpDir, dir);
135
154
  }
@@ -138,17 +157,28 @@ async function extractArchive(file, dir) {
138
157
  }
139
158
  }
140
159
  async function downloadArtifactToFile(config, label) {
141
- const progress = process.stdout.isTTY ? new multiProgress_1.MultiProgress() : null;
142
- const progressBar = progress === null || progress === void 0 ? void 0 : progress.createBar(`${" ".repeat(builder_util_1.PADDING + 2)}[:bar] :percent | ${label}`, { total: 100 });
143
- progressBar === null || progressBar === void 0 ? void 0 : progressBar.render();
160
+ var _a, _b, _c, _d;
144
161
  let lastLoggedMilestone = -1;
162
+ const state = { bar: undefined };
145
163
  const downloadOptions = {
146
164
  timeout: { request: 10 * 60 * 1000 }, // prevent indefinite hang on stalled connections
147
165
  ...config.downloadOptions,
166
+ agent: (_b = (_a = config.downloadOptions) === null || _a === void 0 ? void 0 : _a.agent) !== null && _b !== void 0 ? _b : (0, builder_util_1.buildGotProxyAgent)(),
148
167
  getProgressCallback: info => {
168
+ // @electron/get passes downloadOptions (including this callback) to its internal
169
+ // SHASUMS256.txt validation download. That file is tiny (<1 MB) and fires at 100%
170
+ // immediately, producing a spurious bar even when the artifact itself is cached.
171
+ // Skip progress display for any download whose total size is known and small.
172
+ if (info.total && info.total < 1000000) {
173
+ return Promise.resolve();
174
+ }
175
+ if (!state.bar && process.stdout.isTTY) {
176
+ builder_util_1.log.info({ label }, "downloading");
177
+ state.bar = new multiProgress_1.MultiProgress().createBar(`${" ".repeat(builder_util_1.PADDING + 2)}[:bar] :percent | ${label}`, { total: 100 });
178
+ }
149
179
  const pct = info.percent != null ? Math.floor(info.percent * 100) : 0;
150
- if (progressBar) {
151
- progressBar.update(pct);
180
+ if (state.bar) {
181
+ state.bar.update(pct);
152
182
  }
153
183
  else {
154
184
  // 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
@@ -161,7 +191,6 @@ async function downloadArtifactToFile(config, label) {
161
191
  return Promise.resolve();
162
192
  },
163
193
  };
164
- builder_util_1.log.info({ label }, "downloading");
165
194
  const configWithProgress = { ...config, downloadOptions };
166
195
  try {
167
196
  let filePath;
@@ -180,11 +209,14 @@ async function downloadArtifactToFile(config, label) {
180
209
  builder_util_1.log.warn({ filePath, label }, "cached artifact missing from disk; retrying with cache write");
181
210
  filePath = await get.downloadArtifact({ ...configWithProgress, cacheMode: get_1.ElectronDownloadCacheMode.WriteOnly });
182
211
  }
212
+ if (!state.bar && lastLoggedMilestone === -1) {
213
+ builder_util_1.log.info({ label }, "using cached artifact");
214
+ }
183
215
  return filePath;
184
216
  }
185
217
  finally {
186
- progressBar === null || progressBar === void 0 ? void 0 : progressBar.update(100);
187
- progressBar === null || progressBar === void 0 ? void 0 : progressBar.terminate();
218
+ (_c = state.bar) === null || _c === void 0 ? void 0 : _c.update(100);
219
+ (_d = state.bar) === null || _d === void 0 ? void 0 : _d.terminate();
188
220
  }
189
221
  }
190
222
  /**
@@ -193,31 +225,58 @@ async function downloadArtifactToFile(config, label) {
193
225
  * Both public download functions delegate here after building their respective configs.
194
226
  */
195
227
  async function downloadAndExtract(config, extractDir, label) {
196
- const completeMarker = `${extractDir}.complete`;
197
- const isCached = async () => (0, builder_util_1.exists)(completeMarker);
198
228
  await fs.mkdir(extractDir, { recursive: true });
199
- if (await isCached()) {
200
- builder_util_1.log.debug({ file: label, path: extractDir }, "using cached artifact - skipping download/extract");
201
- return extractDir;
229
+ // Pre-lock fast path: only short-circuit for a definitively complete and valid cache.
230
+ // Do NOT clean up here — concurrent processes could race to delete under each other.
231
+ const stateData = await (0, cacheState_1.readCacheStateFile)(extractDir);
232
+ if ((stateData === null || stateData === void 0 ? void 0 : stateData.state) === cacheState_1.CacheState.complete) {
233
+ const isValid = await (0, cacheState_1.validateCacheDirectory)(extractDir, stateData.fileCount);
234
+ if (isValid) {
235
+ builder_util_1.log.debug({ file: label, path: extractDir }, "using cached artifact - cache valid");
236
+ return extractDir;
237
+ }
202
238
  }
203
239
  const release = await lockfile.lock(extractDir, {
204
240
  retries: { retries: 5, minTimeout: 1000, maxTimeout: 5000 },
205
- stale: 60000,
241
+ stale: 120000,
206
242
  });
207
243
  let downloadedFile = null;
208
244
  try {
209
245
  // Re-check after acquiring lock: another worker may have completed while we waited.
210
- if (await isCached()) {
211
- builder_util_1.log.debug({ file: label, path: extractDir }, "using cached artifact - skipping download/extract");
212
- return extractDir;
246
+ const stateDataAfterLock = await (0, cacheState_1.readCacheStateFile)(extractDir);
247
+ if ((stateDataAfterLock === null || stateDataAfterLock === void 0 ? void 0 : stateDataAfterLock.state) === cacheState_1.CacheState.complete) {
248
+ const isValid = await (0, cacheState_1.validateCacheDirectory)(extractDir, stateDataAfterLock.fileCount);
249
+ if (isValid) {
250
+ builder_util_1.log.debug({ file: label, path: extractDir }, "using cached artifact - skipping download/extract");
251
+ return extractDir;
252
+ }
253
+ builder_util_1.log.warn({ extractDir }, "Cache marked complete but files invalid, clearing");
213
254
  }
255
+ else if ((stateDataAfterLock === null || stateDataAfterLock === void 0 ? void 0 : stateDataAfterLock.state) === cacheState_1.CacheState.corrupted) {
256
+ builder_util_1.log.warn({ extractDir }, "Corrupted cache detected, cleaning up and re-extracting");
257
+ }
258
+ // Cleanup inside the lock — skip lock files since we currently hold them
259
+ await (0, cacheState_1.cleanupCacheDirectory)(extractDir, { skipLockFiles: true });
260
+ await fs.mkdir(extractDir, { recursive: true });
261
+ builder_util_1.log.debug({ file: label }, "downloading");
214
262
  downloadedFile = await downloadArtifactToFile(config, label);
263
+ if (!downloadedFile) {
264
+ throw new Error(`Failed to download artifact: ${label}`);
265
+ }
266
+ await (0, cacheState_1.writeCacheState)(extractDir, cacheState_1.CacheState.downloaded);
267
+ // Mark extracting so stale-lock detection can recover a crashed mid-extraction process
268
+ await (0, cacheState_1.writeCacheState)(extractDir, cacheState_1.CacheState.extracting);
269
+ // Extract while holding the lock to prevent concurrent interference
270
+ await extractArchive(downloadedFile, extractDir);
271
+ // Compute metadata with a full recursive walk now that tmpDir has been renamed to extractDir
272
+ const { fileCount, extractedSize } = await (0, cacheState_1.computeCacheMetadata)(extractDir);
273
+ // Write complete state with metadata BEFORE releasing the lock; throwOnError=true so a
274
+ // failed write (disk full, permissions) propagates instead of silently producing a no-op cache
275
+ await (0, cacheState_1.writeCacheState)(extractDir, cacheState_1.CacheState.complete, { fileCount, extractedSize }, true);
215
276
  }
216
277
  finally {
217
278
  await release().catch(err => builder_util_1.log.warn({ err }, "failed to release lockfile"));
218
279
  }
219
- await extractArchive(downloadedFile, extractDir);
220
- await fs.writeFile(completeMarker, "");
221
280
  return extractDir;
222
281
  }
223
282
  // ─── Public API ───────────────────────────────────────────────────────────────
@@ -228,18 +287,15 @@ async function downloadAndExtract(config, extractDir, label) {
228
287
  async function downloadBuilderToolset(options) {
229
288
  const { releaseName, filenameWithExt, checksums, githubOrgRepo = "electron-userland/electron-builder-binaries", overrideUrl } = options;
230
289
  const baseUrl = getBinariesMirrorUrl(githubOrgRepo);
231
- const hashInput = overrideUrl ? `${overrideUrl}/${filenameWithExt}` : `${baseUrl}${releaseName}/${filenameWithExt}`;
232
- const suffix = hashUrlSafe(hashInput, 5);
290
+ const fullUrl = overrideUrl ? `${overrideUrl}/${filenameWithExt}` : `${baseUrl}${releaseName}/${filenameWithExt}`;
291
+ const suffix = hashUrlSafe(fullUrl, 5);
233
292
  const folderName = `${filenameWithExt.replace(/\.(tar\.gz|tgz|zip|7z)$/, "")}-${suffix}`;
234
293
  const extractDir = path.join(getCacheDirectory(), releaseName, folderName);
235
- const mirrorOptions = overrideUrl
236
- ? { resolveAssetURL: async () => Promise.resolve(`${overrideUrl}/${filenameWithExt}`) }
237
- : {
238
- // `${mirror}${customDir}/${customFilename}`
239
- mirror: baseUrl,
240
- customDir: releaseName,
241
- customFilename: filenameWithExt,
242
- };
294
+ // Use resolveAssetURL so @electron/get's ELECTRON_MIRROR env var check cannot override
295
+ // the builder-binaries URL we've already resolved (see getArtifactRemoteURL in @electron/get).
296
+ const mirrorOptions = {
297
+ resolveAssetURL: async () => Promise.resolve(fullUrl),
298
+ };
243
299
  const config = {
244
300
  version: "9.9.9", // must be >1.3.2 to bypass @electron/get validation shortcut
245
301
  artifactName: filenameWithExt,
@@ -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 { exec, exists, getPath7za, log, PADDING, parseValidEnvVarUrl } from \"builder-util\"\nimport { MultiProgress } from \"electron-publish/out/multiProgress\"\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 { ElectronPlatformName } from \"../electron/ElectronFramework\"\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 strictSSL?: boolean\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(isAvoidSystemOnWindows = false): string {\n const env = process.env.ELECTRON_BUILDER_CACHE?.trim()\n if (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 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 retries: { retries: 5, minTimeout: 1000, maxTimeout: 5000 },\n stale: 60000,\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 if (file.endsWith(\".tar.gz\") || file.endsWith(\".tgz\")) {\n await tar.extract({ file, cwd: tmpDir, strip: 1 })\n } else if (file.endsWith(\".zip\")) {\n await extractZipStreaming(file, tmpDir)\n } else if (file.endsWith(\".7z\")) {\n await exec(await getPath7za(), [\"x\", \"-bd\", file, `-o${tmpDir}`, \"-y\"])\n } else {\n throw new Error(`Unsupported archive format: ${path.basename(file)}`)\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 const progress = process.stdout.isTTY ? new MultiProgress() : null\n const progressBar = progress?.createBar(`${\" \".repeat(PADDING + 2)}[:bar] :percent | ${label}`, { total: 100 })\n progressBar?.render()\n\n let lastLoggedMilestone = -1\n const downloadOptions: GotDownloaderOptions = {\n timeout: { request: 10 * 60 * 1000 }, // prevent indefinite hang on stalled connections\n ...config.downloadOptions,\n getProgressCallback: info => {\n const pct = info.percent != null ? Math.floor(info.percent * 100) : 0\n if (progressBar) {\n progressBar.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 log.info({ label }, \"downloading\")\n const configWithProgress = { ...config, downloadOptions }\n try {\n let filePath: string\n try {\n filePath = await get.downloadArtifact(configWithProgress)\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 return filePath\n } finally {\n progressBar?.update(100)\n progressBar?.terminate()\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): Promise<string> {\n const completeMarker = `${extractDir}.complete`\n const isCached = async () => exists(completeMarker)\n\n await fs.mkdir(extractDir, { recursive: true })\n\n if (await isCached()) {\n log.debug({ file: label, path: extractDir }, \"using cached artifact - skipping download/extract\")\n return extractDir\n }\n\n const release = await lockfile.lock(extractDir, {\n retries: { retries: 5, minTimeout: 1000, maxTimeout: 5000 },\n stale: 60000,\n })\n let downloadedFile: string | null = null\n try {\n // Re-check after acquiring lock: another worker may have completed while we waited.\n if (await isCached()) {\n log.debug({ file: label, path: extractDir }, \"using cached artifact - skipping download/extract\")\n return extractDir\n }\n\n downloadedFile = await downloadArtifactToFile(config, label)\n } finally {\n await release().catch(err => log.warn({ err }, \"failed to release lockfile\"))\n }\n await extractArchive(downloadedFile, extractDir)\n await fs.writeFile(completeMarker, \"\")\n return extractDir\n}\n\n// ─── Public API ───────────────────────────────────────────────────────────────\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 const baseUrl = getBinariesMirrorUrl(githubOrgRepo)\n const hashInput = overrideUrl ? `${overrideUrl}/${filenameWithExt}` : `${baseUrl}${releaseName}/${filenameWithExt}`\n const suffix = hashUrlSafe(hashInput, 5)\n const folderName = `${filenameWithExt.replace(/\\.(tar\\.gz|tgz|zip|7z)$/, \"\")}-${suffix}`\n const extractDir = path.join(getCacheDirectory(), releaseName, folderName)\n\n const mirrorOptions: MirrorOptions = overrideUrl\n ? { resolveAssetURL: async () => Promise.resolve(`${overrideUrl}/${filenameWithExt}`) }\n : {\n // `${mirror}${customDir}/${customFilename}`\n mirror: baseUrl,\n customDir: releaseName,\n customFilename: filenameWithExt,\n }\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(), \"downloads\"),\n cacheMode: resolveCacheMode(),\n ...(checksums != null ? { checksums } : { unsafelyDisableChecksums: true }),\n mirrorOptions,\n isGeneric: true,\n }\n return downloadAndExtract(config, extractDir, filenameWithExt)\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 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(), `${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 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)\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":";;AAwFA,8CAyBC;AAyDD,wCA+CC;AAyID,wDA+BC;AAqDD,kEAGC;AAED,4DASC;AAMD,oDAaC;AAvdD,qCAAoC;AACpC,uCAOsB;AACtB,+CAA8G;AAC9G,sEAAkE;AAClE,2BAAwD;AACxD,kCAAiC;AACjC,yBAAwB;AACxB,6BAA4B;AAC5B,4CAA2C;AAC3C,8CAA0C;AAC1C,2BAA0B;AAC1B,qCAAoC;AAEpC,6CAAmJ;AA0DnJ,SAAS,WAAW,CAAC,KAAa,EAAE,MAAM,GAAG,CAAC;IAC5C,IAAI,IAAI,GAAG,IAAI,CAAA;IACf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,IAAI,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAA;IACnD,CAAC;IACD,IAAI,MAAM,CAAC,CAAA;IACX,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAA;IAC7B,OAAO,GAAG,CAAC,MAAM,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;AAChF,CAAC;AAED,SAAgB,iBAAiB,CAAC,sBAAsB,GAAG,KAAK,EAAE,mBAAmB,GAAG,IAAI;;IAC1F,MAAM,GAAG,GAAG,MAAA,OAAO,CAAC,GAAG,CAAC,sBAAsB,0CAAE,IAAI,EAAE,CAAA;IACtD,IAAI,mBAAmB,IAAI,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;QACvD,OAAO,GAAG,CAAA;IACZ,CAAC;IAED,MAAM,OAAO,GAAG,kBAAkB,CAAA;IAClC,MAAM,QAAQ,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAA;IAC9B,MAAM,OAAO,GAAG,EAAE,CAAC,OAAO,EAAE,CAAA;IAE5B,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAA;IACzD,CAAC;IACD,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QACzB,MAAM,YAAY,GAAG,MAAA,OAAO,CAAC,GAAG,CAAC,YAAY,0CAAE,IAAI,EAAE,CAAA;QACrD,MAAM,QAAQ,GAAG,MAAA,MAAA,OAAO,CAAC,GAAG,CAAC,QAAQ,0CAAE,IAAI,EAAE,0CAAE,WAAW,EAAE,CAAA;QAC5D,MAAM,YAAY,GAAG,sBAAsB,IAAI,CAAC,CAAA,MAAA,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,WAAW,EAAE,0CAAE,QAAQ,CAAC,uBAAuB,CAAC,KAAI,QAAQ,KAAK,QAAQ,CAAC,CAAA;QACxI,IAAI,CAAC,YAAY,IAAI,YAAY,EAAE,CAAC;YAClC,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,GAAG,OAAO,QAAQ,CAAC,CAAA;QACnD,CAAC;QACD,OAAO,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;IAClD,CAAC;IAED,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAA;IAC3C,OAAO,QAAQ,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAA;AACrH,CAAC;AAED,SAAS,gBAAgB;;IACvB,MAAM,OAAO,GAAG,8BAA8B,CAAA;IAC9C,MAAM,aAAa,GAAG,MAAA,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,0CAAE,IAAI,EAAE,CAAA;IAClD,IAAI,aAAa,IAAI,MAAM,CAAC,aAAa,CAAC,IAAI,+BAAyB,EAAE,CAAC;QACxE,MAAM,IAAI,GAAG,MAAM,CAAC,aAAa,CAA8B,CAAA;QAC/D,kBAAG,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,EAAE,qCAAqC,OAAO,EAAE,CAAC,CAAA;QACnE,OAAO,IAAI,CAAA;IACb,CAAC;IACD,OAAO,+BAAyB,CAAC,SAAS,CAAA;AAC5C,CAAC;AAED,KAAK,UAAU,mBAAmB,CAAC,IAAY,EAAE,GAAW;;IAC1D,8EAA8E;IAC9E,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC7C,MAAM,UAAU,GAAG,IAAI,GAAG,EAAkB,CAAA;IAC5C,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACjC,MAAM,IAAI,GAAG,CAAC,KAAK,CAAC,sBAAsB,IAAI,EAAE,CAAC,GAAG,MAAM,CAAA;QAC1D,IAAI,IAAI,GAAG,CAAC,EAAE,CAAC;YACb,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;QAClC,CAAC;IACH,CAAC;IACD,MAAM,SAAS,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,CAAC,IAAI,GAAG,QAAQ,CAAC,KAAK,QAAQ,CAAA;IAElE,kEAAkE;IAClE,MAAM,OAAO,GAAG,IAAA,qBAAgB,EAAC,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;IAClF,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,OAAwC,EAAE,CAAC;QACnE,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAA;QAC9C,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,QAAQ,KAAK,GAAG,EAAE,CAAC;YAC7D,MAAM,IAAI,KAAK,CAAC,2BAA2B,KAAK,CAAC,IAAI,EAAE,CAAC,CAAA;QAC1D,CAAC;QACD,MAAM,IAAI,GAAG,MAAA,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,mCAAI,CAAC,CAAA;QAC5C,IAAI,IAAI,GAAG,CAAC,IAAI,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;YAChC,MAAM,MAAM,GAAG,CAAC,MAAM,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAA;YAChD,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC5B,MAAM,IAAI,KAAK,CAAC,oCAAoC,MAAM,EAAE,CAAC,CAAA;YAC/D,CAAC;YACD,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,CAAA;YACnE,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,cAAc,KAAK,GAAG,EAAE,CAAC;gBACzE,MAAM,IAAI,KAAK,CAAC,0CAA0C,MAAM,EAAE,CAAC,CAAA;YACrE,CAAC;YACD,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;YAC3D,MAAM,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;QACpC,CAAC;aAAM,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YACtC,MAAM,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;YAC7C,KAAK,CAAC,SAAS,EAAE,CAAA;QACnB,CAAC;aAAM,CAAC;YACN,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;YAC3D,MAAM,IAAA,mBAAQ,EAAC,KAAK,EAAE,IAAA,sBAAiB,EAAC,QAAQ,CAAC,CAAC,CAAA;YAClD,IAAI,IAAI,GAAG,CAAC,EAAE,CAAC;gBACb,MAAM,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,IAAI,GAAG,MAAM,CAAC,CAAA;YACzC,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAEM,KAAK,UAAU,cAAc,CAAC,IAAY,EAAE,GAAW;IAC5D,MAAM,MAAM,GAAG,GAAG,GAAG,MAAM,CAAA;IAC3B,MAAM,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAE3C,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE;QAC1C,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE;QAC3D,KAAK,EAAE,MAAM,EAAE,uDAAuD;KACvE,CAAC,CAAA;IAEF,IAAI,CAAC;QACH,yGAAyG;QACzG,MAAM,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;QACrD,MAAM,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;QAE3C,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YACtD,MAAM,GAAG,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAA;QACpD,CAAC;aAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YACjC,MAAM,mBAAmB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;QACzC,CAAC;aAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAChC,MAAM,MAAM,GAAG,MAAM,IAAA,yBAAU,GAAE,CAAA;YACjC,IAAI,CAAC;gBACH,MAAM,IAAA,mBAAI,EAAC,MAAM,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,MAAM,EAAE,EAAE,IAAI,CAAC,CAAC,CAAA;YAC7D,CAAC;YAAC,OAAO,CAAM,EAAE,CAAC;gBAChB,kEAAkE;gBAClE,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;gBACtC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBACvB,kBAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE,EAAE,kCAAkC,CAAC,CAAA;oBAChF,MAAM,IAAI,KAAK,CAAC,4BAA4B,IAAI,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAA;gBACnE,CAAC;gBACD,8DAA8D;gBAC9D,kBAAG,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,CAAC,MAAM,EAAE,EAAE,uCAAuC,CAAC,CAAA;YACvG,CAAC;QACH,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,KAAK,CAAC,+BAA+B,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QACvE,CAAC;QAED,mCAAmC;QACnC,MAAM,cAAc,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;QAC/C,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CAAC,iBAAiB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAA;QAC3E,CAAC;QAED,MAAM,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;QAClD,MAAM,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC9B,CAAC;YAAS,CAAC;QACT,MAAM,OAAO,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,kBAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,EAAE,4BAA4B,CAAC,CAAC,CAAA;IAC/E,CAAC;AACH,CAAC;AAED,KAAK,UAAU,sBAAsB,CAAC,MAAkD,EAAE,KAAa;;IACrG,IAAI,mBAAmB,GAAG,CAAC,CAAC,CAAA;IAC5B,MAAM,KAAK,GAAqC,EAAE,GAAG,EAAE,SAAS,EAAE,CAAA;IAElE,MAAM,eAAe,GAAyB;QAC5C,OAAO,EAAE,EAAE,OAAO,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,EAAE,iDAAiD;QACvF,GAAG,MAAM,CAAC,eAAe;QACzB,KAAK,EAAE,MAAA,MAAA,MAAM,CAAC,eAAe,0CAAE,KAAK,mCAAI,IAAA,iCAAkB,GAAE;QAC5D,mBAAmB,EAAE,IAAI,CAAC,EAAE;YAC1B,iFAAiF;YACjF,kFAAkF;YAClF,iFAAiF;YACjF,8EAA8E;YAC9E,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,GAAG,OAAS,EAAE,CAAC;gBACzC,OAAO,OAAO,CAAC,OAAO,EAAE,CAAA;YAC1B,CAAC;YACD,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;gBACvC,kBAAG,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,aAAa,CAAC,CAAA;gBAClC,KAAK,CAAC,GAAG,GAAG,IAAI,6BAAa,EAAE,CAAC,SAAS,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,sBAAO,GAAG,CAAC,CAAC,qBAAqB,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAA;YACnH,CAAC;YACD,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;YACrE,IAAI,KAAK,CAAC,GAAG,EAAE,CAAC;gBACd,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;YACvB,CAAC;iBAAM,CAAC;gBACN,oKAAoK;gBACpK,MAAM,gBAAgB,GAAG,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,EAAE,CAAA;gBACvI,IAAI,gBAAgB,GAAG,mBAAmB,IAAI,gBAAgB,GAAG,CAAC,EAAE,CAAC;oBACnE,mBAAmB,GAAG,gBAAgB,CAAA;oBACtC,kBAAG,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,gBAAgB,GAAG,EAAE,EAAE,gBAAgB,KAAK,GAAG,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,YAAY,CAAC,CAAA;gBAChH,CAAC;YACH,CAAC;YACD,OAAO,OAAO,CAAC,OAAO,EAAE,CAAA;QAC1B,CAAC;KACF,CAAA;IAED,MAAM,kBAAkB,GAAG,EAAE,GAAG,MAAM,EAAE,eAAe,EAAE,CAAA;IACzD,IAAI,CAAC;QACH,IAAI,QAAgB,CAAA;QACpB,IAAI,CAAC;YACH,QAAQ,GAAG,MAAM,GAAG,CAAC,gBAAgB,CAAC,kBAAkB,CAAC,CAAA;QAC3D,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,OAAO,CAAC,GAAW,aAAX,GAAG,uBAAH,GAAG,CAAU,OAAO,CAAA,KAAK,QAAQ,IAAK,GAAW,CAAC,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAC,EAAE,CAAC;gBACtG,QAAQ,GAAG,MAAM,GAAG,CAAC,gBAAgB,CAAC,kBAAkB,CAAC,CAAA;YAC3D,CAAC;iBAAM,CAAC;gBACN,MAAM,GAAG,CAAA;YACX,CAAC;QACH,CAAC;QACD,IAAI,CAAC,CAAC,MAAM,IAAA,qBAAM,EAAC,QAAQ,CAAC,CAAC,EAAE,CAAC;YAC9B,kBAAG,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,8DAA8D,CAAC,CAAA;YAC7F,QAAQ,GAAG,MAAM,GAAG,CAAC,gBAAgB,CAAC,EAAE,GAAG,kBAAkB,EAAE,SAAS,EAAE,+BAAyB,CAAC,SAAS,EAAE,CAAC,CAAA;QAClH,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,mBAAmB,KAAK,CAAC,CAAC,EAAE,CAAC;YAC7C,kBAAG,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,uBAAuB,CAAC,CAAA;QAC9C,CAAC;QACD,OAAO,QAAQ,CAAA;IACjB,CAAC;YAAS,CAAC;QACT,MAAA,KAAK,CAAC,GAAG,0CAAE,MAAM,CAAC,GAAG,CAAC,CAAA;QACtB,MAAA,KAAK,CAAC,GAAG,0CAAE,SAAS,EAAE,CAAA;IACxB,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,KAAK,UAAU,kBAAkB,CAAC,MAAkD,EAAE,UAAkB,EAAE,KAAa;IACrH,MAAM,EAAE,CAAC,KAAK,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAE/C,sFAAsF;IACtF,qFAAqF;IACrF,MAAM,SAAS,GAAG,MAAM,IAAA,+BAAkB,EAAC,UAAU,CAAC,CAAA;IACtD,IAAI,CAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,KAAK,MAAK,uBAAU,CAAC,QAAQ,EAAE,CAAC;QAC7C,MAAM,OAAO,GAAG,MAAM,IAAA,mCAAsB,EAAC,UAAU,EAAE,SAAS,CAAC,SAAS,CAAC,CAAA;QAC7E,IAAI,OAAO,EAAE,CAAC;YACZ,kBAAG,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,qCAAqC,CAAC,CAAA;YACnF,OAAO,UAAU,CAAA;QACnB,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,UAAU,EAAE;QAC9C,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE;QAC3D,KAAK,EAAE,MAAM;KACd,CAAC,CAAA;IACF,IAAI,cAAc,GAAkB,IAAI,CAAA;IACxC,IAAI,CAAC;QACH,oFAAoF;QACpF,MAAM,kBAAkB,GAAG,MAAM,IAAA,+BAAkB,EAAC,UAAU,CAAC,CAAA;QAC/D,IAAI,CAAA,kBAAkB,aAAlB,kBAAkB,uBAAlB,kBAAkB,CAAE,KAAK,MAAK,uBAAU,CAAC,QAAQ,EAAE,CAAC;YACtD,MAAM,OAAO,GAAG,MAAM,IAAA,mCAAsB,EAAC,UAAU,EAAE,kBAAkB,CAAC,SAAS,CAAC,CAAA;YACtF,IAAI,OAAO,EAAE,CAAC;gBACZ,kBAAG,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,mDAAmD,CAAC,CAAA;gBACjG,OAAO,UAAU,CAAA;YACnB,CAAC;YACD,kBAAG,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,EAAE,mDAAmD,CAAC,CAAA;QAC/E,CAAC;aAAM,IAAI,CAAA,kBAAkB,aAAlB,kBAAkB,uBAAlB,kBAAkB,CAAE,KAAK,MAAK,uBAAU,CAAC,SAAS,EAAE,CAAC;YAC9D,kBAAG,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,EAAE,yDAAyD,CAAC,CAAA;QACrF,CAAC;QAED,yEAAyE;QACzE,MAAM,IAAA,kCAAqB,EAAC,UAAU,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAA;QAChE,MAAM,EAAE,CAAC,KAAK,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;QAE/C,kBAAG,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,aAAa,CAAC,CAAA;QACzC,cAAc,GAAG,MAAM,sBAAsB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;QAC5D,IAAI,CAAC,cAAc,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CAAC,gCAAgC,KAAK,EAAE,CAAC,CAAA;QAC1D,CAAC;QAED,MAAM,IAAA,4BAAe,EAAC,UAAU,EAAE,uBAAU,CAAC,UAAU,CAAC,CAAA;QAExD,uFAAuF;QACvF,MAAM,IAAA,4BAAe,EAAC,UAAU,EAAE,uBAAU,CAAC,UAAU,CAAC,CAAA;QAExD,oEAAoE;QACpE,MAAM,cAAc,CAAC,cAAc,EAAE,UAAU,CAAC,CAAA;QAEhD,6FAA6F;QAC7F,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,GAAG,MAAM,IAAA,iCAAoB,EAAC,UAAU,CAAC,CAAA;QAE3E,uFAAuF;QACvF,+FAA+F;QAC/F,MAAM,IAAA,4BAAe,EAAC,UAAU,EAAE,uBAAU,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,aAAa,EAAE,EAAE,IAAI,CAAC,CAAA;IAC5F,CAAC;YAAS,CAAC;QACT,MAAM,OAAO,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,kBAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,EAAE,4BAA4B,CAAC,CAAC,CAAA;IAC/E,CAAC;IACD,OAAO,UAAU,CAAA;AACnB,CAAC;AAED,iFAAiF;AAEjF;;;GAGG;AACI,KAAK,UAAU,sBAAsB,CAAC,OAM5C;IACC,MAAM,EAAE,WAAW,EAAE,eAAe,EAAE,SAAS,EAAE,aAAa,GAAG,6CAA6C,EAAE,WAAW,EAAE,GAAG,OAAO,CAAA;IAEvI,MAAM,OAAO,GAAG,oBAAoB,CAAC,aAAa,CAAC,CAAA;IACnD,MAAM,OAAO,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,WAAW,IAAI,eAAe,EAAE,CAAC,CAAC,CAAC,GAAG,OAAO,GAAG,WAAW,IAAI,eAAe,EAAE,CAAA;IACjH,MAAM,MAAM,GAAG,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC,CAAA;IACtC,MAAM,UAAU,GAAG,GAAG,eAAe,CAAC,OAAO,CAAC,yBAAyB,EAAE,EAAE,CAAC,IAAI,MAAM,EAAE,CAAA;IACxF,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,EAAE,WAAW,EAAE,UAAU,CAAC,CAAA;IAE1E,uFAAuF;IACvF,+FAA+F;IAC/F,MAAM,aAAa,GAAkB;QACnC,eAAe,EAAE,KAAK,IAAI,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC;KACtD,CAAA;IAED,MAAM,MAAM,GAAmF;QAC7F,OAAO,EAAE,OAAO,EAAE,6DAA6D;QAC/E,YAAY,EAAE,eAAe;QAC7B,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,iBAAiB,EAAE,EAAE,WAAW,CAAC;QACzD,SAAS,EAAE,gBAAgB,EAAE;QAC7B,GAAG,CAAC,SAAS,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,wBAAwB,EAAE,IAAI,EAAE,CAAC;QAC3E,aAAa;QACb,SAAS,EAAE,IAAI;KAChB,CAAA;IACD,OAAO,kBAAkB,CAAC,MAAM,EAAE,UAAU,EAAE,eAAe,CAAC,CAAA;AAChE,CAAC;AAED,8EAA8E;AAC9E,iEAAiE;AACjE,MAAM,2BAA2B,GAAsB,CAAC,eAAe,EAAE,OAAO,EAAE,0BAA0B,CAAC,CAAA;AAE7G,SAAS,oBAAoB,CAAC,EAAgD;IAC5E,OAAO,2BAA2B,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAA;AACjF,CAAC;AAED;;;GAGG;AACH,SAAS,2BAA2B,CAAC,OAAgC;IACnE,MAAM,EAAE,gBAAgB,EAAE,IAAI,EAAE,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,OAAO,CAAA;IAE9G,IAAI,cAAc,GAAoC,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,YAAY,EAAE,CAAA;IAE1G,IAAI,gBAAgB,IAAI,IAAI,EAAE,CAAC;QAC7B,IAAI,oBAAoB,CAAC,gBAAgB,CAAC,EAAE,CAAC;YAC3C,MAAM,EAAE,aAAa,EAAE,GAAG,IAAI,EAAE,GAAG,gBAAgB,CAAA;YACnD,cAAc,GAAG,EAAE,GAAG,cAAc,EAAE,GAAG,IAAI,EAAE,SAAS,EAAE,aAAa,EAAE,CAAA;QAC3E,CAAC;aAAM,CAAC;YACN,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,SAAS,EAAE,QAAQ,EAAE,gBAAgB,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,gBAAgB,CAAA;YAClJ,cAAc,GAAG;gBACf,GAAG,cAAc;gBACjB,wBAAwB,EAAE,gBAAgB,KAAK,KAAK;gBACpD,SAAS,EAAE,KAAK,aAAL,KAAK,cAAL,KAAK,GAAI,SAAS;gBAC7B,aAAa,EAAE;oBACb,MAAM,EAAE,MAAM,IAAI,SAAS;oBAC3B,SAAS,EAAE,SAAS,IAAI,SAAS;oBACjC,cAAc,EAAE,cAAc,IAAI,SAAS;iBAC5C;gBACD,GAAG,CAAC,SAAS,KAAK,KAAK,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,EAAE,KAAK,EAAE,EAAE,kBAAkB,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC9F,CAAA;YACD,IAAI,gBAAgB,IAAI,IAAI,EAAE,CAAC;gBAC7B,cAAc,CAAC,QAAQ,GAAG,gBAAgB,CAAA;YAC5C,CAAC;YACD,IAAI,YAAY,IAAI,IAAI,EAAE,CAAC;gBACzB,cAAc,CAAC,IAAI,GAAG,YAAY,CAAA;YACpC,CAAC;QACH,CAAC;IACH,CAAC;IAED,cAAc,CAAC,SAAS,GAAG,gBAAgB,EAAE,CAAA;IAC7C,OAAO,cAAc,CAAA;AACvB,CAAC;AAED;;;GAGG;AACH,SAAgB,2BAA2B,CAAC,OAAgC;IAC1E,MAAM,MAAM,GAAG,2BAA2B,CAAC,OAAO,CAAC,CAAA;IACnD,OAAO,sBAAsB,CAAC,MAAM,EAAE,MAAM,CAAC,YAAY,CAAC,CAAA;AAC5D,CAAC;AAEM,KAAK,UAAU,wBAAwB,CAAC,OAAgC;IAC7E,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,OAAO,CAAA;IACvE,MAAM,cAAc,GAAG,2BAA2B,CAAC,OAAO,CAAC,CAAA;IAE3D,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC,CAAA;IAC7D,MAAM,UAAU,GAAG,GAAG,YAAY,KAAK,OAAO,IAAI,QAAQ,IAAI,IAAI,IAAI,MAAM,EAAE,CAAA;IAC9E,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,EAAE,GAAG,YAAY,KAAK,OAAO,EAAE,EAAE,UAAU,CAAC,CAAA;IAE5F,OAAO,kBAAkB,CAAC,cAAc,EAAE,UAAU,EAAE,YAAY,CAAC,CAAA;AACrE,CAAC;AAED;;;GAGG;AACH,SAAgB,oBAAoB,CAAC,aAAqB;IACxD,KAAK,MAAM,MAAM,IAAI;QACnB,6CAA6C;QAC7C,6CAA6C;QAC7C,qDAAqD;QACrD,kCAAkC;KACnC,EAAE,CAAC;QACF,MAAM,GAAG,GAAG,IAAA,kCAAmB,EAAC,MAAM,CAAC,CAAA;QACvC,IAAI,GAAG,EAAE,CAAC;YACR,OAAO,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,CAAA;QAC5C,CAAC;IACH,CAAC;IACD,OAAO,sBAAsB,aAAa,qBAAqB,CAAA;AACjE,CAAC","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, getPath7za, log, PADDING, parseValidEnvVarUrl } from \"builder-util\"\nimport { MultiProgress } from \"electron-publish/out/multiProgress\"\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 { ElectronPlatformName } from \"../electron/ElectronFramework\"\nimport { CacheState, cleanupCacheDirectory, computeCacheMetadata, readCacheStateFile, validateCacheDirectory, writeCacheState } from \"./cacheState\"\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 strictSSL?: boolean\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(isAvoidSystemOnWindows = false, allowEnvVarOverride = true): string {\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 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 retries: { retries: 5, 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 if (file.endsWith(\".tar.gz\") || file.endsWith(\".tgz\")) {\n await tar.extract({ file, cwd: tmpDir, strip: 1 })\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, `-o${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 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 get.downloadArtifact(configWithProgress)\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 }\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): 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 const release = await lockfile.lock(extractDir, {\n retries: { retries: 5, 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 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\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 * 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 const baseUrl = getBinariesMirrorUrl(githubOrgRepo)\n const fullUrl = overrideUrl ? `${overrideUrl}/${filenameWithExt}` : `${baseUrl}${releaseName}/${filenameWithExt}`\n const suffix = hashUrlSafe(fullUrl, 5)\n const folderName = `${filenameWithExt.replace(/\\.(tar\\.gz|tgz|zip|7z)$/, \"\")}-${suffix}`\n const extractDir = path.join(getCacheDirectory(), 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 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(), \"downloads\"),\n cacheMode: resolveCacheMode(),\n ...(checksums != null ? { checksums } : { unsafelyDisableChecksums: true }),\n mirrorOptions,\n isGeneric: true,\n }\n return downloadAndExtract(config, extractDir, filenameWithExt)\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 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(), `${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 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)\n if (url) {\n return url.endsWith(\"/\") ? url : `${url}/`\n }\n }\n return `https://github.com/${githubOrgRepo}/releases/download/`\n}\n"]}
@@ -45,6 +45,9 @@ function expandMacro(pattern, arch, appInfo, extra = {}, isProductNameSanitized
45
45
  if (envValue == null) {
46
46
  throw new builder_util_1.InvalidConfigurationError(`cannot expand pattern "${pattern}": env ${envName} is not defined`, "ERR_ELECTRON_BUILDER_ENV_NOT_DEFINED");
47
47
  }
48
+ if (/TOKEN|SECRET|KEY|PASSWORD|CREDENTIAL/i.test(envName)) {
49
+ builder_util_1.log.warn({ envName, pattern }, "macro expansion includes an env var that may contain a secret — verify this is intentional");
50
+ }
48
51
  return envValue;
49
52
  }
50
53
  const value = extra[p1];
@@ -1 +1 @@
1
- {"version":3,"file":"macroExpander.js","sourceRoot":"","sources":["../../src/util/macroExpander.ts"],"names":[],"mappings":";;AAIA,kCA8DC;AAlED,+CAAwD;AAIxD,SAAgB,WAAW,CAAC,OAAe,EAAE,IAAsB,EAAE,OAAgB,EAAE,QAAa,EAAE,EAAE,sBAAsB,GAAG,IAAI;IACnI,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;QACjB,OAAO,GAAG,OAAO;YACf,uDAAuD;aACtD,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;YACxB,uDAAuD;aACtD,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;YACxB,uDAAuD;aACtD,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;YACxB,uDAAuD;aACtD,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAA;IAC5B,CAAC;IAED,OAAO,OAAO,CAAC,OAAO,CAAC,uBAAuB,EAAE,CAAC,KAAK,EAAE,EAAE,EAAU,EAAE;QACpE,QAAQ,EAAE,EAAE,CAAC;YACX,KAAK,aAAa;gBAChB,OAAO,sBAAsB,CAAC,CAAC,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,CAAA;YAEpF,KAAK,MAAM;gBACT,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;oBACjB,wCAAwC;oBACxC,OAAO,EAAE,CAAA;gBACX,CAAC;gBACD,OAAO,IAAI,CAAA;YAEb,KAAK,QAAQ,CAAC,CAAC,CAAC;gBACd,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,CAAA;gBACvC,IAAI,WAAW,IAAI,IAAI,EAAE,CAAC;oBACxB,MAAM,IAAI,wCAAyB,CAAC,0BAA0B,OAAO,4BAA4B,EAAE,yCAAyC,CAAC,CAAA;gBAC/I,CAAC;gBACD,OAAO,WAAW,CAAA;YACpB,CAAC;YAED,KAAK,UAAU;gBACb,OAAO,OAAO,CAAC,QAAQ,CAAA;YAEzB,KAAK,SAAS;gBACZ,OAAO,OAAO,CAAC,OAAO,IAAI,QAAQ,CAAA;YAEpC,OAAO,CAAC,CAAC,CAAC;gBACR,IAAI,EAAE,IAAI,OAAO,EAAE,CAAC;oBAClB,OAAQ,OAAe,CAAC,EAAE,CAAC,CAAA;gBAC7B,CAAC;gBAED,IAAI,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;oBAC1B,MAAM,OAAO,GAAG,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;oBAC3C,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;oBACrC,IAAI,QAAQ,IAAI,IAAI,EAAE,CAAC;wBACrB,MAAM,IAAI,wCAAyB,CAAC,0BAA0B,OAAO,UAAU,OAAO,iBAAiB,EAAE,sCAAsC,CAAC,CAAA;oBAClJ,CAAC;oBACD,OAAO,QAAQ,CAAA;gBACjB,CAAC;gBAED,MAAM,KAAK,GAAG,KAAK,CAAC,EAAE,CAAC,CAAA;gBACvB,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;oBAClB,MAAM,IAAI,wCAAyB,CAAC,0BAA0B,OAAO,YAAY,EAAE,iBAAiB,EAAE,wCAAwC,CAAC,CAAA;gBACjJ,CAAC;qBAAM,CAAC;oBACN,OAAO,KAAK,CAAA;gBACd,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAA;AACJ,CAAC","sourcesContent":["import { InvalidConfigurationError } from \"builder-util\"\nimport { Nullish } from \"builder-util-runtime\"\nimport { AppInfo } from \"../appInfo\"\n\nexport function expandMacro(pattern: string, arch: string | Nullish, appInfo: AppInfo, extra: any = {}, isProductNameSanitized = true): string {\n if (arch == null) {\n pattern = pattern\n // tslint:disable-next-line:no-invalid-template-strings\n .replace(\"-${arch}\", \"\")\n // tslint:disable-next-line:no-invalid-template-strings\n .replace(\" ${arch}\", \"\")\n // tslint:disable-next-line:no-invalid-template-strings\n .replace(\"_${arch}\", \"\")\n // tslint:disable-next-line:no-invalid-template-strings\n .replace(\"/${arch}\", \"\")\n }\n\n return pattern.replace(/\\${([_a-zA-Z./*+]+)}/g, (match, p1): string => {\n switch (p1) {\n case \"productName\":\n return isProductNameSanitized ? appInfo.sanitizedProductName : appInfo.productName\n\n case \"arch\":\n if (arch == null) {\n // see above, we remove macro if no arch\n return \"\"\n }\n return arch\n\n case \"author\": {\n const companyName = appInfo.companyName\n if (companyName == null) {\n throw new InvalidConfigurationError(`cannot expand pattern \"${pattern}\": author is not specified`, \"ERR_ELECTRON_BUILDER_AUTHOR_UNSPECIFIED\")\n }\n return companyName\n }\n\n case \"platform\":\n return process.platform\n\n case \"channel\":\n return appInfo.channel || \"latest\"\n\n default: {\n if (p1 in appInfo) {\n return (appInfo as any)[p1]\n }\n\n if (p1.startsWith(\"env.\")) {\n const envName = p1.substring(\"env.\".length)\n const envValue = process.env[envName]\n if (envValue == null) {\n throw new InvalidConfigurationError(`cannot expand pattern \"${pattern}\": env ${envName} is not defined`, \"ERR_ELECTRON_BUILDER_ENV_NOT_DEFINED\")\n }\n return envValue\n }\n\n const value = extra[p1]\n if (value == null) {\n throw new InvalidConfigurationError(`cannot expand pattern \"${pattern}\": macro ${p1} is not defined`, \"ERR_ELECTRON_BUILDER_MACRO_NOT_DEFINED\")\n } else {\n return value\n }\n }\n }\n })\n}\n"]}
1
+ {"version":3,"file":"macroExpander.js","sourceRoot":"","sources":["../../src/util/macroExpander.ts"],"names":[],"mappings":";;AAIA,kCAiEC;AArED,+CAA6D;AAI7D,SAAgB,WAAW,CAAC,OAAe,EAAE,IAAsB,EAAE,OAAgB,EAAE,QAAa,EAAE,EAAE,sBAAsB,GAAG,IAAI;IACnI,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;QACjB,OAAO,GAAG,OAAO;YACf,uDAAuD;aACtD,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;YACxB,uDAAuD;aACtD,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;YACxB,uDAAuD;aACtD,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;YACxB,uDAAuD;aACtD,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAA;IAC5B,CAAC;IAED,OAAO,OAAO,CAAC,OAAO,CAAC,uBAAuB,EAAE,CAAC,KAAK,EAAE,EAAE,EAAU,EAAE;QACpE,QAAQ,EAAE,EAAE,CAAC;YACX,KAAK,aAAa;gBAChB,OAAO,sBAAsB,CAAC,CAAC,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,CAAA;YAEpF,KAAK,MAAM;gBACT,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;oBACjB,wCAAwC;oBACxC,OAAO,EAAE,CAAA;gBACX,CAAC;gBACD,OAAO,IAAI,CAAA;YAEb,KAAK,QAAQ,CAAC,CAAC,CAAC;gBACd,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,CAAA;gBACvC,IAAI,WAAW,IAAI,IAAI,EAAE,CAAC;oBACxB,MAAM,IAAI,wCAAyB,CAAC,0BAA0B,OAAO,4BAA4B,EAAE,yCAAyC,CAAC,CAAA;gBAC/I,CAAC;gBACD,OAAO,WAAW,CAAA;YACpB,CAAC;YAED,KAAK,UAAU;gBACb,OAAO,OAAO,CAAC,QAAQ,CAAA;YAEzB,KAAK,SAAS;gBACZ,OAAO,OAAO,CAAC,OAAO,IAAI,QAAQ,CAAA;YAEpC,OAAO,CAAC,CAAC,CAAC;gBACR,IAAI,EAAE,IAAI,OAAO,EAAE,CAAC;oBAClB,OAAQ,OAAe,CAAC,EAAE,CAAC,CAAA;gBAC7B,CAAC;gBAED,IAAI,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;oBAC1B,MAAM,OAAO,GAAG,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;oBAC3C,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;oBACrC,IAAI,QAAQ,IAAI,IAAI,EAAE,CAAC;wBACrB,MAAM,IAAI,wCAAyB,CAAC,0BAA0B,OAAO,UAAU,OAAO,iBAAiB,EAAE,sCAAsC,CAAC,CAAA;oBAClJ,CAAC;oBACD,IAAI,uCAAuC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;wBAC1D,kBAAG,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,4FAA4F,CAAC,CAAA;oBAC9H,CAAC;oBACD,OAAO,QAAQ,CAAA;gBACjB,CAAC;gBAED,MAAM,KAAK,GAAG,KAAK,CAAC,EAAE,CAAC,CAAA;gBACvB,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;oBAClB,MAAM,IAAI,wCAAyB,CAAC,0BAA0B,OAAO,YAAY,EAAE,iBAAiB,EAAE,wCAAwC,CAAC,CAAA;gBACjJ,CAAC;qBAAM,CAAC;oBACN,OAAO,KAAK,CAAA;gBACd,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAA;AACJ,CAAC","sourcesContent":["import { InvalidConfigurationError, log } from \"builder-util\"\nimport { Nullish } from \"builder-util-runtime\"\nimport { AppInfo } from \"../appInfo\"\n\nexport function expandMacro(pattern: string, arch: string | Nullish, appInfo: AppInfo, extra: any = {}, isProductNameSanitized = true): string {\n if (arch == null) {\n pattern = pattern\n // tslint:disable-next-line:no-invalid-template-strings\n .replace(\"-${arch}\", \"\")\n // tslint:disable-next-line:no-invalid-template-strings\n .replace(\" ${arch}\", \"\")\n // tslint:disable-next-line:no-invalid-template-strings\n .replace(\"_${arch}\", \"\")\n // tslint:disable-next-line:no-invalid-template-strings\n .replace(\"/${arch}\", \"\")\n }\n\n return pattern.replace(/\\${([_a-zA-Z./*+]+)}/g, (match, p1): string => {\n switch (p1) {\n case \"productName\":\n return isProductNameSanitized ? appInfo.sanitizedProductName : appInfo.productName\n\n case \"arch\":\n if (arch == null) {\n // see above, we remove macro if no arch\n return \"\"\n }\n return arch\n\n case \"author\": {\n const companyName = appInfo.companyName\n if (companyName == null) {\n throw new InvalidConfigurationError(`cannot expand pattern \"${pattern}\": author is not specified`, \"ERR_ELECTRON_BUILDER_AUTHOR_UNSPECIFIED\")\n }\n return companyName\n }\n\n case \"platform\":\n return process.platform\n\n case \"channel\":\n return appInfo.channel || \"latest\"\n\n default: {\n if (p1 in appInfo) {\n return (appInfo as any)[p1]\n }\n\n if (p1.startsWith(\"env.\")) {\n const envName = p1.substring(\"env.\".length)\n const envValue = process.env[envName]\n if (envValue == null) {\n throw new InvalidConfigurationError(`cannot expand pattern \"${pattern}\": env ${envName} is not defined`, \"ERR_ELECTRON_BUILDER_ENV_NOT_DEFINED\")\n }\n if (/TOKEN|SECRET|KEY|PASSWORD|CREDENTIAL/i.test(envName)) {\n log.warn({ envName, pattern }, \"macro expansion includes an env var that may contain a secret — verify this is intentional\")\n }\n return envValue\n }\n\n const value = extra[p1]\n if (value == null) {\n throw new InvalidConfigurationError(`cannot expand pattern \"${pattern}\": macro ${p1} is not defined`, \"ERR_ELECTRON_BUILDER_MACRO_NOT_DEFINED\")\n } else {\n return value\n }\n }\n }\n })\n}\n"]}
@@ -0,0 +1,10 @@
1
+ import { RequestedExecutionLevel } from "../options/winOptions";
2
+ export interface ResourceEditOptions {
3
+ file: string;
4
+ versionStrings: Record<string, string>;
5
+ fileVersion: string;
6
+ productVersion: string;
7
+ requestedExecutionLevel?: RequestedExecutionLevel | null;
8
+ iconPath?: string | null;
9
+ }
10
+ export declare function editWindowsResources(opts: ResourceEditOptions): Promise<void>;
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.editWindowsResources = editWindowsResources;
4
+ const builder_util_1 = require("builder-util");
5
+ const promises_1 = require("fs/promises");
6
+ const resedit_1 = require("resedit");
7
+ async function editWindowsResources(opts) {
8
+ const buffer = await (0, promises_1.readFile)(opts.file);
9
+ const executable = resedit_1.NtExecutable.from(buffer);
10
+ const res = resedit_1.NtExecutableResource.from(executable);
11
+ const viList = resedit_1.Resource.VersionInfo.fromEntries(res.entries);
12
+ // Mirror rcedit: create version info from scratch if none exists; use first if multiple
13
+ const vi = viList.length > 0 ? viList[0] : resedit_1.Resource.VersionInfo.createEmpty();
14
+ // Mirror rcedit: default to en-US (1033) if no languages present; use first if multiple
15
+ const languages = vi.getAllLanguagesForStringValues();
16
+ const lang = languages.length > 0 ? languages[0] : { lang: 0x0409, codepage: 1200 };
17
+ vi.setStringValues(lang, opts.versionStrings);
18
+ vi.setFileVersion(opts.fileVersion);
19
+ vi.setProductVersion(opts.productVersion);
20
+ // resedit normalizes the string to 4-part numeric; restore the original (e.g. "1.1.0" or "3.0.0-beta.2")
21
+ vi.setStringValues(lang, { FileVersion: opts.fileVersion });
22
+ vi.outputToResourceEntries(res.entries);
23
+ if (opts.iconPath) {
24
+ const iconBuf = await (0, promises_1.readFile)(opts.iconPath);
25
+ const iconFile = resedit_1.Data.IconFile.from(iconBuf);
26
+ resedit_1.Resource.IconGroupEntry.replaceIconsForResource(res.entries, 1, lang.lang, iconFile.icons.map(i => i.data));
27
+ }
28
+ if (opts.requestedExecutionLevel && opts.requestedExecutionLevel !== "asInvoker") {
29
+ const manifestEntry = res.entries.find(e => e.type === 24 && e.id === 1);
30
+ if (!manifestEntry) {
31
+ builder_util_1.log.warn({ file: opts.file }, "no RT_MANIFEST resource found; requestedExecutionLevel will not be applied");
32
+ }
33
+ else {
34
+ const originalXml = Buffer.from(manifestEntry.bin).toString("utf-8");
35
+ const updatedXml = originalXml.replace(/(<requestedExecutionLevel[^>]*\blevel=")[^"]*(")/i, `$1${opts.requestedExecutionLevel}$2`);
36
+ if (updatedXml === originalXml) {
37
+ builder_util_1.log.warn({ file: opts.file, requestedExecutionLevel: opts.requestedExecutionLevel }, "requestedExecutionLevel node not found in manifest; execution level not updated");
38
+ }
39
+ else {
40
+ const newBuf = Buffer.from(updatedXml, "utf-8");
41
+ manifestEntry.bin = newBuf.buffer.slice(newBuf.byteOffset, newBuf.byteOffset + newBuf.byteLength);
42
+ }
43
+ }
44
+ }
45
+ res.outputResource(executable);
46
+ await (0, promises_1.writeFile)(opts.file, Buffer.from(executable.generate()));
47
+ }
48
+ //# sourceMappingURL=resEdit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resEdit.js","sourceRoot":"","sources":["../../src/util/resEdit.ts"],"names":[],"mappings":"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","sourcesContent":["import { log } from \"builder-util\"\nimport { readFile, writeFile } from \"fs/promises\"\nimport { Data, NtExecutable, NtExecutableResource, Resource } from \"resedit\"\nimport { RequestedExecutionLevel } from \"../options/winOptions\"\n\nexport interface ResourceEditOptions {\n file: string\n versionStrings: Record<string, string>\n fileVersion: string\n productVersion: string\n requestedExecutionLevel?: RequestedExecutionLevel | null\n iconPath?: string | null\n}\n\nexport async function editWindowsResources(opts: ResourceEditOptions): Promise<void> {\n const buffer = await readFile(opts.file)\n const executable = NtExecutable.from(buffer)\n const res = NtExecutableResource.from(executable)\n\n const viList = Resource.VersionInfo.fromEntries(res.entries)\n // Mirror rcedit: create version info from scratch if none exists; use first if multiple\n const vi = viList.length > 0 ? viList[0] : Resource.VersionInfo.createEmpty()\n // Mirror rcedit: default to en-US (1033) if no languages present; use first if multiple\n const languages = vi.getAllLanguagesForStringValues()\n const lang = languages.length > 0 ? languages[0] : { lang: 0x0409, codepage: 1200 }\n\n vi.setStringValues(lang, opts.versionStrings)\n vi.setFileVersion(opts.fileVersion)\n vi.setProductVersion(opts.productVersion)\n // resedit normalizes the string to 4-part numeric; restore the original (e.g. \"1.1.0\" or \"3.0.0-beta.2\")\n vi.setStringValues(lang, { FileVersion: opts.fileVersion })\n vi.outputToResourceEntries(res.entries)\n\n if (opts.iconPath) {\n const iconBuf = await readFile(opts.iconPath)\n const iconFile = Data.IconFile.from(iconBuf)\n Resource.IconGroupEntry.replaceIconsForResource(\n res.entries,\n 1,\n lang.lang,\n iconFile.icons.map(i => i.data)\n )\n }\n\n if (opts.requestedExecutionLevel && opts.requestedExecutionLevel !== \"asInvoker\") {\n const manifestEntry = res.entries.find(e => e.type === 24 && e.id === 1)\n if (!manifestEntry) {\n log.warn({ file: opts.file }, \"no RT_MANIFEST resource found; requestedExecutionLevel will not be applied\")\n } else {\n const originalXml = Buffer.from(manifestEntry.bin).toString(\"utf-8\")\n const updatedXml = originalXml.replace(/(<requestedExecutionLevel[^>]*\\blevel=\")[^\"]*(\")/i, `$1${opts.requestedExecutionLevel}$2`)\n if (updatedXml === originalXml) {\n log.warn({ file: opts.file, requestedExecutionLevel: opts.requestedExecutionLevel }, \"requestedExecutionLevel node not found in manifest; execution level not updated\")\n } else {\n const newBuf = Buffer.from(updatedXml, \"utf-8\")\n manifestEntry.bin = newBuf.buffer.slice(newBuf.byteOffset, newBuf.byteOffset + newBuf.byteLength)\n }\n }\n }\n\n res.outputResource(executable)\n await writeFile(opts.file, Buffer.from(executable.generate()))\n}\n"]}
@@ -5,6 +5,7 @@ exports.resolveFunction = resolveFunction;
5
5
  const builder_util_1 = require("builder-util");
6
6
  const log_1 = require("builder-util/out/log");
7
7
  const debug_1 = require("debug");
8
+ const promises_1 = require("fs/promises");
8
9
  const path = require("path");
9
10
  const requireMaybe = require("../../helpers/dynamic-import");
10
11
  async function resolveModule(type, name) {
@@ -25,7 +26,16 @@ async function resolveFunction(type, executor, name, rootSearchDir) {
25
26
  let p = executor;
26
27
  if (p.startsWith(".")) {
27
28
  p = path.resolve(p);
28
- const relative = path.relative(rootSearchDir, p);
29
+ let realP = p;
30
+ let realRoot = rootSearchDir;
31
+ try {
32
+ realP = await (0, promises_1.realpath)(p);
33
+ realRoot = await (0, promises_1.realpath)(rootSearchDir);
34
+ }
35
+ catch {
36
+ // path may not exist yet; fall back to lexical check
37
+ }
38
+ const relative = path.relative(realRoot, realP);
29
39
  if (relative.startsWith("..") || path.isAbsolute(relative)) {
30
40
  throw new builder_util_1.InvalidConfigurationError(`Hook module path "${executor}" resolves outside the workspace root ("${rootSearchDir}")`);
31
41
  }
@@ -1 +1 @@
1
- {"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/util/resolve.ts"],"names":[],"mappings":";;AAMA,sCAOC;AAED,0CA6BC;AA5CD,+CAAwD;AACxD,8CAA0C;AAC1C,iCAAyB;AACzB,6BAA4B;AAC5B,6DAA4D;AAErD,KAAK,UAAU,aAAa,CAAI,IAAwB,EAAE,IAAY;;IAC3E,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAA;IAC9C,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,SAAG,CAAC,KAAK,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,MAAA,KAAK,CAAC,OAAO,mCAAI,KAAK,CAAC,KAAK,EAAE,EAAE,6CAA6C,CAAC,CAAA;QACrH,MAAM,KAAK,CAAA;IACb,CAAC;AACH,CAAC;AAEM,KAAK,UAAU,eAAe,CAAI,IAAwB,EAAE,QAAoB,EAAE,IAAY,EAAE,aAAqB;IAC1H,IAAI,QAAQ,IAAI,IAAI,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACrD,oDAAoD;QACpD,OAAO,QAAQ,CAAA;IACjB,CAAC;IAED,IAAI,CAAC,GAAG,QAAkB,CAAA;IAC1B,IAAI,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACtB,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;QACnB,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,aAAa,EAAE,CAAC,CAAC,CAAA;QAChD,IAAI,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC3D,MAAM,IAAI,wCAAyB,CAAC,qBAAqB,QAAQ,2CAA2C,aAAa,IAAI,CAAC,CAAA;QAChI,CAAC;IACH,CAAC;IAED,IAAI,CAAC;QACH,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;IACxB,CAAC;IAAC,OAAO,CAAM,EAAE,CAAC;QAChB,IAAA,eAAK,EAAC,CAAC,CAAC,CAAA;QACR,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;IACrB,CAAC;IAED,MAAM,CAAC,GAAQ,MAAM,aAAa,CAAC,IAAI,EAAE,CAAC,CAAC,CAAA;IAC3C,MAAM,WAAW,GAAG,CAAC,CAAC,IAAI,CAAC,CAAA;IAC3B,IAAI,WAAW,IAAI,IAAI,EAAE,CAAC;QACxB,OAAO,CAAC,CAAC,OAAO,IAAI,CAAC,CAAA;IACvB,CAAC;SAAM,CAAC;QACN,OAAO,WAAW,CAAA;IACpB,CAAC;AACH,CAAC","sourcesContent":["import { InvalidConfigurationError } from \"builder-util\"\nimport { log } from \"builder-util/out/log\"\nimport debug from \"debug\"\nimport * as path from \"path\"\nimport * as requireMaybe from \"../../helpers/dynamic-import\"\n\nexport async function resolveModule<T>(type: string | undefined, name: string): Promise<T> {\n try {\n return requireMaybe.dynamicImportMaybe(name)\n } catch (error: any) {\n log.error({ moduleName: name, message: error.message ?? error.stack }, \"Unable to dynamically `import` or `require`\")\n throw error\n }\n}\n\nexport async function resolveFunction<T>(type: string | undefined, executor: T | string, name: string, rootSearchDir: string): Promise<T> {\n if (executor == null || typeof executor !== \"string\") {\n // is already function or explicitly ignored by user\n return executor\n }\n\n let p = executor as string\n if (p.startsWith(\".\")) {\n p = path.resolve(p)\n const relative = path.relative(rootSearchDir, p)\n if (relative.startsWith(\"..\") || path.isAbsolute(relative)) {\n throw new InvalidConfigurationError(`Hook module path \"${executor}\" resolves outside the workspace root (\"${rootSearchDir}\")`)\n }\n }\n\n try {\n p = require.resolve(p)\n } catch (e: any) {\n debug(e)\n p = path.resolve(p)\n }\n\n const m: any = await resolveModule(type, p)\n const namedExport = m[name]\n if (namedExport == null) {\n return m.default || m\n } else {\n return namedExport\n }\n}\n"]}
1
+ {"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/util/resolve.ts"],"names":[],"mappings":";;AAOA,sCAOC;AAED,0CAqCC;AArDD,+CAAwD;AACxD,8CAA0C;AAC1C,iCAAyB;AACzB,0CAAsC;AACtC,6BAA4B;AAC5B,6DAA4D;AAErD,KAAK,UAAU,aAAa,CAAI,IAAwB,EAAE,IAAY;;IAC3E,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAA;IAC9C,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,SAAG,CAAC,KAAK,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,MAAA,KAAK,CAAC,OAAO,mCAAI,KAAK,CAAC,KAAK,EAAE,EAAE,6CAA6C,CAAC,CAAA;QACrH,MAAM,KAAK,CAAA;IACb,CAAC;AACH,CAAC;AAEM,KAAK,UAAU,eAAe,CAAI,IAAwB,EAAE,QAAoB,EAAE,IAAY,EAAE,aAAqB;IAC1H,IAAI,QAAQ,IAAI,IAAI,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACrD,oDAAoD;QACpD,OAAO,QAAQ,CAAA;IACjB,CAAC;IAED,IAAI,CAAC,GAAG,QAAkB,CAAA;IAC1B,IAAI,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACtB,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;QACnB,IAAI,KAAK,GAAG,CAAC,CAAA;QACb,IAAI,QAAQ,GAAG,aAAa,CAAA;QAC5B,IAAI,CAAC;YACH,KAAK,GAAG,MAAM,IAAA,mBAAQ,EAAC,CAAC,CAAC,CAAA;YACzB,QAAQ,GAAG,MAAM,IAAA,mBAAQ,EAAC,aAAa,CAAC,CAAA;QAC1C,CAAC;QAAC,MAAM,CAAC;YACP,qDAAqD;QACvD,CAAC;QACD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAA;QAC/C,IAAI,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC3D,MAAM,IAAI,wCAAyB,CAAC,qBAAqB,QAAQ,2CAA2C,aAAa,IAAI,CAAC,CAAA;QAChI,CAAC;IACH,CAAC;IAED,IAAI,CAAC;QACH,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;IACxB,CAAC;IAAC,OAAO,CAAM,EAAE,CAAC;QAChB,IAAA,eAAK,EAAC,CAAC,CAAC,CAAA;QACR,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;IACrB,CAAC;IAED,MAAM,CAAC,GAAQ,MAAM,aAAa,CAAC,IAAI,EAAE,CAAC,CAAC,CAAA;IAC3C,MAAM,WAAW,GAAG,CAAC,CAAC,IAAI,CAAC,CAAA;IAC3B,IAAI,WAAW,IAAI,IAAI,EAAE,CAAC;QACxB,OAAO,CAAC,CAAC,OAAO,IAAI,CAAC,CAAA;IACvB,CAAC;SAAM,CAAC;QACN,OAAO,WAAW,CAAA;IACpB,CAAC;AACH,CAAC","sourcesContent":["import { InvalidConfigurationError } from \"builder-util\"\nimport { log } from \"builder-util/out/log\"\nimport debug from \"debug\"\nimport { realpath } from \"fs/promises\"\nimport * as path from \"path\"\nimport * as requireMaybe from \"../../helpers/dynamic-import\"\n\nexport async function resolveModule<T>(type: string | undefined, name: string): Promise<T> {\n try {\n return requireMaybe.dynamicImportMaybe(name)\n } catch (error: any) {\n log.error({ moduleName: name, message: error.message ?? error.stack }, \"Unable to dynamically `import` or `require`\")\n throw error\n }\n}\n\nexport async function resolveFunction<T>(type: string | undefined, executor: T | string, name: string, rootSearchDir: string): Promise<T> {\n if (executor == null || typeof executor !== \"string\") {\n // is already function or explicitly ignored by user\n return executor\n }\n\n let p = executor as string\n if (p.startsWith(\".\")) {\n p = path.resolve(p)\n let realP = p\n let realRoot = rootSearchDir\n try {\n realP = await realpath(p)\n realRoot = await realpath(rootSearchDir)\n } catch {\n // path may not exist yet; fall back to lexical check\n }\n const relative = path.relative(realRoot, realP)\n if (relative.startsWith(\"..\") || path.isAbsolute(relative)) {\n throw new InvalidConfigurationError(`Hook module path \"${executor}\" resolves outside the workspace root (\"${rootSearchDir}\")`)\n }\n }\n\n try {\n p = require.resolve(p)\n } catch (e: any) {\n debug(e)\n p = path.resolve(p)\n }\n\n const m: any = await resolveModule(type, p)\n const namedExport = m[name]\n if (namedExport == null) {\n return m.default || m\n } else {\n return namedExport\n }\n}\n"]}
package/out/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const PACKAGE_VERSION = "26.10.0";
1
+ export declare const PACKAGE_VERSION = "26.11.1";
package/out/version.js CHANGED
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.PACKAGE_VERSION = void 0;
4
- exports.PACKAGE_VERSION = "26.10.0";
4
+ exports.PACKAGE_VERSION = "26.11.1";
5
5
  //# sourceMappingURL=version.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":";;;AAAa,QAAA,eAAe,GAAG,SAAS,CAAA","sourcesContent":["export const PACKAGE_VERSION = \"26.10.0\"\n"]}
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":";;;AAAa,QAAA,eAAe,GAAG,SAAS,CAAA","sourcesContent":["export const PACKAGE_VERSION = \"26.11.1\"\n"]}
@@ -1,3 +1,19 @@
1
+ import { ExtraSpawnOptions } from "builder-util";
2
+ import { ExecFileOptions, SpawnOptions } from "child_process";
3
+ import { VmManager } from "./vm";
4
+ export declare class ParallelsVmManager extends VmManager {
5
+ private readonly vm;
6
+ private startPromise;
7
+ private isExitHookAdded;
8
+ constructor(vm: ParallelsVm);
9
+ get pathSep(): string;
10
+ private handleExecuteError;
11
+ exec(file: string, args: Array<string>, options?: ExecFileOptions): Promise<string>;
12
+ spawn(file: string, args: Array<string>, options?: SpawnOptions, extraOptions?: ExtraSpawnOptions): Promise<any>;
13
+ private doStartVm;
14
+ private ensureThatVmStarted;
15
+ toVmFile(file: string): string;
16
+ }
1
17
  export declare function macPathToParallelsWindows(file: string): string;
2
18
  export interface ParallelsVm {
3
19
  id: string;
@@ -33,7 +33,6 @@ async function parseVmList(debugLogger) {
33
33
  }
34
34
  return result;
35
35
  }
36
- /** @internal */
37
36
  class ParallelsVmManager extends vm_1.VmManager {
38
37
  constructor(vm) {
39
38
  super();