app-builder-lib 26.15.6 → 26.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/out/configuration.d.ts +32 -0
- package/out/configuration.js.map +1 -1
- package/out/electron/ElectronFramework.d.ts +2 -1
- package/out/electron/ElectronFramework.js +30 -25
- package/out/electron/ElectronFramework.js.map +1 -1
- package/out/macPackager.d.ts +7 -2
- package/out/macPackager.js +40 -11
- package/out/macPackager.js.map +1 -1
- package/out/node-module-collector/nodeModulesCollector.d.ts +11 -1
- package/out/node-module-collector/nodeModulesCollector.js +16 -2
- package/out/node-module-collector/nodeModulesCollector.js.map +1 -1
- package/out/node-module-collector/pnpmNodeModulesCollector.js +3 -1
- package/out/node-module-collector/pnpmNodeModulesCollector.js.map +1 -1
- package/out/targets/AppxTarget.js +5 -5
- package/out/targets/AppxTarget.js.map +1 -1
- package/out/targets/MsiTarget.js +8 -11
- package/out/targets/MsiTarget.js.map +1 -1
- package/out/targets/appimage/appImageUtil.d.ts +1 -1
- package/out/targets/appimage/appImageUtil.js +3 -3
- package/out/targets/appimage/appImageUtil.js.map +1 -1
- package/out/targets/appimage/appLauncher.js +3 -9
- package/out/targets/appimage/appLauncher.js.map +1 -1
- package/out/targets/blockmap/blockmap.js +2 -2
- package/out/targets/blockmap/blockmap.js.map +1 -1
- package/out/targets/nsis/nsisOptions.d.ts +2 -0
- package/out/targets/nsis/nsisOptions.js.map +1 -1
- package/out/toolsets/icons.js +2 -2
- package/out/toolsets/icons.js.map +1 -1
- package/out/toolsets/linux.js +3 -3
- package/out/toolsets/linux.js.map +1 -1
- package/out/util/appFileCopier.d.ts +21 -0
- package/out/util/appFileCopier.js +58 -0
- package/out/util/appFileCopier.js.map +1 -1
- package/out/util/electronGet.d.ts +46 -0
- package/out/util/electronGet.js +191 -35
- package/out/util/electronGet.js.map +1 -1
- package/out/version.d.ts +1 -1
- package/out/version.js +1 -1
- package/out/version.js.map +1 -1
- package/package.json +8 -8
- package/scheme.json +20 -1
- package/templates/appx/appxmanifest.xml +1 -2
- package/templates/nsis/include/allowOnlyOneInstallerInstance.nsh +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"appFileCopier.js","sourceRoot":"","sources":["../../src/util/appFileCopier.ts"],"names":[],"mappings":"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","sourcesContent":["import { AsyncTaskManager, FileCopier, FileTransformer, isEmptyOrSpaces, Link, log, MAX_FILE_REQUESTS, statOrNull, walk } from \"builder-util\"\nimport { Stats } from \"fs\"\nimport { ensureSymlink } from \"fs-extra\"\nimport { mkdir, readlink } from \"fs/promises\"\nimport * as path from \"path\"\nimport asyncPool from \"tiny-async-pool\"\nimport { isLibOrExe } from \"../asar/unpackDetector\"\nimport { Platform } from \"../core\"\nimport { excludedExts, FileMatcher } from \"../fileMatcher\"\nimport { createElectronCompilerHost, NODE_MODULES_PATTERN } from \"../fileTransformer\"\nimport { getCollectorByPackageManager, PM } from \"../node-module-collector\"\nimport { LogMessageByKey, logMessageLevelByKey, ModuleManager } from \"../node-module-collector/moduleManager\"\nimport { Packager } from \"../packager\"\nimport { PlatformPackager } from \"../platformPackager\"\nimport { AppFileWalker } from \"./AppFileWalker\"\nimport { NodeModuleCopyHelper } from \"./NodeModuleCopyHelper\"\nimport { NodeModuleInfo } from \"./packageDependencies\"\n\nconst BOWER_COMPONENTS_PATTERN = `${path.sep}bower_components${path.sep}`\n/** @internal */\nexport const ELECTRON_COMPILE_SHIM_FILENAME = \"__shim.js\"\n\nexport function getDestinationPath(file: string, fileSet: ResolvedFileSet) {\n if (file === fileSet.src) {\n return fileSet.destination\n }\n\n const src = fileSet.src\n const dest = fileSet.destination\n // get node_modules path relative to src and then append to dest\n if (file.startsWith(src)) {\n return path.join(dest, path.relative(src, file))\n }\n return dest\n}\n\nexport async function copyAppFiles(fileSet: ResolvedFileSet, packager: Packager, transformer: FileTransformer) {\n const metadata = fileSet.metadata\n // search auto unpacked dir\n const taskManager = new AsyncTaskManager(packager.cancellationToken)\n const createdParentDirs = new Set<string>()\n\n const fileCopier = new FileCopier(file => {\n return !isLibOrExe(file)\n }, transformer)\n const links: Array<Link> = []\n for (let i = 0, n = fileSet.files.length; i < n; i++) {\n const sourceFile = fileSet.files[i]\n const stat = metadata.get(sourceFile)\n if (stat == null) {\n // dir\n continue\n }\n\n const destinationFile = getDestinationPath(sourceFile, fileSet)\n if (stat.isSymbolicLink()) {\n links.push({ file: destinationFile, link: await readlink(sourceFile) })\n continue\n }\n\n const fileParent = path.dirname(destinationFile)\n if (!createdParentDirs.has(fileParent)) {\n createdParentDirs.add(fileParent)\n await mkdir(fileParent, { recursive: true })\n }\n\n taskManager.addTask(fileCopier.copy(sourceFile, destinationFile, stat))\n if (taskManager.tasks.length > MAX_FILE_REQUESTS) {\n await taskManager.awaitTasks()\n }\n }\n\n if (taskManager.tasks.length > 0) {\n await taskManager.awaitTasks()\n }\n\n await asyncPool(MAX_FILE_REQUESTS, links, it => ensureSymlink(it.link, it.file))\n}\n\n// os path separator is used\nexport interface ResolvedFileSet {\n src: string\n destination: string\n\n files: Array<string>\n metadata: Map<string, Stats>\n transformedFiles?: Map<number, string | Buffer> | null\n}\n\n// used only for ASAR, if no asar, file transformed on the fly\nexport async function transformFiles(transformer: FileTransformer, fileSet: ResolvedFileSet): Promise<void> {\n if (transformer == null) {\n return\n }\n\n let transformedFiles = fileSet.transformedFiles\n if (fileSet.transformedFiles == null) {\n transformedFiles = new Map()\n fileSet.transformedFiles = transformedFiles\n }\n\n const metadata = fileSet.metadata\n const filesPromise = fileSet.files.map(async (it, index) => {\n const fileStat = metadata.get(it)\n if (fileStat == null || !fileStat.isFile()) {\n return\n }\n\n const transformedValue = transformer(it)\n if (transformedValue == null) {\n return\n }\n\n if (typeof transformedValue === \"object\" && \"then\" in transformedValue) {\n return (transformedValue as Promise<any>).then(it => {\n if (it != null) {\n transformedFiles!.set(index, it)\n }\n return\n })\n }\n transformedFiles!.set(index, transformedValue as string | Buffer)\n return\n })\n // `asyncPool` doesn't provide `index` in it's handler, so we `map` first before using it\n await asyncPool(MAX_FILE_REQUESTS, filesPromise, promise => promise)\n}\n\nexport async function computeFileSets(\n matchers: Array<FileMatcher>,\n transformer: FileTransformer | null,\n platformPackager: PlatformPackager<any>,\n isElectronCompile: boolean\n): Promise<Array<ResolvedFileSet>> {\n const fileSets: Array<ResolvedFileSet> = []\n const packager = platformPackager.info\n\n for (const matcher of matchers) {\n const fileWalker = new AppFileWalker(matcher, packager)\n\n const fromStat = await statOrNull(matcher.from)\n if (fromStat == null) {\n log.debug({ directory: matcher.from, reason: \"doesn't exist\" }, `skipped copying`)\n continue\n }\n\n const files = await walk(matcher.from, fileWalker.filter, fileWalker)\n const metadata = fileWalker.metadata\n fileSets.push(validateFileSet({ src: matcher.from, files, metadata, destination: matcher.to }))\n }\n\n if (isElectronCompile) {\n // cache files should be first (better IO)\n fileSets.unshift(await compileUsingElectronCompile(fileSets[0], packager))\n }\n return fileSets\n}\n\nfunction getNodeModuleExcludedExts(platformPackager: PlatformPackager<any>) {\n // do not exclude *.h files (https://github.com/electron-userland/electron-builder/issues/2852)\n const result = [\".o\", \".obj\"].concat(excludedExts.split(\",\").map(it => `.${it}`))\n if (platformPackager.config.includePdb !== true) {\n result.push(\".pdb\")\n }\n if (platformPackager.platform !== Platform.WINDOWS) {\n // https://github.com/electron-userland/electron-builder/issues/1738\n result.push(\".dll\")\n result.push(\".exe\")\n }\n return result\n}\n\nfunction validateFileSet(fileSet: ResolvedFileSet): ResolvedFileSet {\n if (fileSet.src == null || fileSet.src.length === 0) {\n throw new Error(\"fileset src is empty\")\n }\n return fileSet\n}\n\n/** @internal */\nexport async function computeNodeModuleFileSets(platformPackager: PlatformPackager<any>, mainMatcher: FileMatcher): Promise<Array<ResolvedFileSet>> {\n const deps = await collectNodeModulesWithLogging(platformPackager)\n\n const nodeModuleExcludedExts = getNodeModuleExcludedExts(platformPackager)\n // serial execution because copyNodeModules is concurrent and so, no need to increase queue/pressure\n const result = new Array<ResolvedFileSet>()\n let index = 0\n const NODE_MODULES = \"node_modules\"\n\n const collectNodeModules = async (dep: NodeModuleInfo, destination: string) => {\n const source = dep.dir\n const matcher = new FileMatcher(source, destination, mainMatcher.macroExpander, mainMatcher.patterns)\n const copier = new NodeModuleCopyHelper(matcher, platformPackager.info)\n const files = await copier.collectNodeModules(dep, nodeModuleExcludedExts, path.relative(mainMatcher.to, destination))\n result[index++] = validateFileSet({ src: source, destination, files, metadata: copier.metadata })\n\n log.debug({ dep: dep.name, from: log.filePath(source), to: log.filePath(destination), filesCount: files.length }, \"identified module\")\n\n if (dep.dependencies) {\n for (const c of dep.dependencies) {\n await collectNodeModules(c, path.join(destination, NODE_MODULES, c.name))\n }\n }\n }\n\n for (const dep of deps) {\n const destination = path.join(mainMatcher.to, NODE_MODULES, dep.name)\n await collectNodeModules(dep, destination)\n }\n return result\n}\n\ntype CollectedNodeModules = { nodeModules: NodeModuleInfo[]; logSummary: ModuleManager[\"logSummary\"] }\n\n/** Runs a single package-manager collector against a single directory. */\ntype CollectorRunner = (pm: PM, dir: string) => Promise<CollectedNodeModules>\n\n// `workspace:`/`file:`/`link:`/`portal:` dependencies are symlinked into place rather than\n// installed as standalone, hoistable packages, so they may legitimately be absent from a\n// collected tree and cannot be used to validate it.\nconst LOCAL_DEPENDENCY_SPEC = /^(?:workspace|file|link|portal):/\n\n/**\n * Determines whether a collected module tree actually describes the package being built.\n *\n * A package-manager `list` invocation can resolve to the wrong project root — most notably when\n * electron-builder is run from a workspace sub-package whose dependencies are hoisted to the\n * workspace root. In that case the collector returns a non-empty but unrelated tree. Accepting it\n * would suppress the manual-traversal fallback that resolves the correct modules, so we need to\n * tell a matching collection from a mismatched one.\n *\n * A collection matches when at least one of the package's declared external (registry-installed,\n * non-`workspace:`/`file:`/`link:`/`portal:`) production dependencies is present at the top level —\n * those direct dependencies are always hoisted to the top level of a correct collection. When the\n * package declares no external production dependencies there is nothing to validate against, so any\n * non-empty collection is accepted.\n */\nexport function collectionMatchesAppDependencies(nodeModules: NodeModuleInfo[], dependencies: Record<string, string> | undefined): boolean {\n const requiredExternalDeps = Object.entries(dependencies ?? {})\n .filter(([, spec]) => !LOCAL_DEPENDENCY_SPEC.test(spec))\n .map(([name]) => name)\n if (requiredExternalDeps.length === 0) {\n return true\n }\n const collected = new Set(nodeModules.map(it => it.name))\n return requiredExternalDeps.some(name => collected.has(name))\n}\n\n/**\n * Walks the candidate (package-manager, directory) combinations and returns the first collection\n * that both contains modules and matches the package being built (see\n * {@link collectionMatchesAppDependencies}). A non-empty collection that does NOT match — e.g. a\n * workspace-root tree returned for a sub-package — is retained only as a last-resort fallback so a\n * later approach (notably {@link PM.TRAVERSAL}) can supply the correct modules.\n */\nexport async function resolveFirstMatchingCollection(options: {\n pmApproaches: PM[]\n searchDirectories: string[]\n dependencies: Record<string, string> | undefined\n run: CollectorRunner\n}): Promise<CollectedNodeModules | undefined> {\n const { pmApproaches, searchDirectories, dependencies, run } = options\n let fallback: CollectedNodeModules | undefined\n\n for (const pm of pmApproaches) {\n for (const dir of searchDirectories) {\n log.info({ pm, searchDir: dir }, \"searching for node modules\")\n const deps = await run(pm, dir)\n if (deps.nodeModules.length === 0) {\n log.info({ pm, searchDir: dir }, \"no node modules found in collection, trying next search directory\")\n continue\n }\n if (collectionMatchesAppDependencies(deps.nodeModules, dependencies)) {\n log.debug({ pm, searchDir: dir, depCount: deps.nodeModules.length }, \"collected node modules\")\n return deps\n }\n log.info({ pm, searchDir: dir }, \"collected node modules do not match the target package, trying next search directory/approach\")\n fallback ??= deps\n }\n }\n return fallback\n}\n\nasync function collectNodeModulesWithLogging(platformPackager: PlatformPackager<any>) {\n const packager = platformPackager.info\n const { tempDirManager, appDir, projectDir } = packager\n\n const searchDirectories = Array.from(new Set([appDir, projectDir, await packager.getWorkspaceRoot()])).filter((it): it is string => isEmptyOrSpaces(it) === false)\n const pmApproaches = [await packager.getPackageManager(), PM.TRAVERSAL]\n\n // Validate against the as-declared (pre-extraMetadata) production dependencies so a configured\n // `extraMetadata.dependencies` entry that isn't installed cannot reject a correct collection.\n const deps = await resolveFirstMatchingCollection({\n pmApproaches,\n searchDirectories,\n dependencies: packager.originalMetadata.dependencies,\n run: (pm, dir) => getCollectorByPackageManager(pm, dir, tempDirManager).getNodeModules({ packageName: packager.nodePackageName }),\n })\n\n if (!deps?.nodeModules?.length) {\n log.warn({ searchDirectories: searchDirectories.map(it => log.filePath(it)) }, \"no node modules returned while searching directories\")\n return []\n }\n\n const summary = Object.entries(deps.logSummary ?? {}).filter(([, dependencies]) => Array.isArray(dependencies) && dependencies.length > 0)\n for (const [errorMessage, dependencies] of summary) {\n const logLevel = logMessageLevelByKey[errorMessage as LogMessageByKey] || \"debug\"\n log[logLevel]({ dependencies }, errorMessage)\n }\n\n return deps.nodeModules\n}\n\nasync function compileUsingElectronCompile(mainFileSet: ResolvedFileSet, packager: Packager): Promise<ResolvedFileSet> {\n log.info(\"compiling using electron-compile\")\n\n const electronCompileCache = await packager.tempDirManager.getTempDir({ prefix: \"electron-compile-cache\" })\n const cacheDir = path.join(electronCompileCache, \".cache\")\n // clear and create cache dir\n await mkdir(cacheDir, { recursive: true })\n const compilerHost = await createElectronCompilerHost(mainFileSet.src, cacheDir)\n const nextSlashIndex = mainFileSet.src.length + 1\n // pre-compute electron-compile to cache dir - we need to process only subdirectories, not direct files of app dir\n const filesPromise: Promise<any>[] = mainFileSet.files.map(file => {\n if (\n file.includes(NODE_MODULES_PATTERN) ||\n file.includes(BOWER_COMPONENTS_PATTERN) ||\n !file.includes(path.sep, nextSlashIndex) || // ignore not root files\n !mainFileSet.metadata.get(file)!.isFile()\n ) {\n return\n }\n return compilerHost.compile(file)\n })\n await asyncPool(MAX_FILE_REQUESTS, filesPromise, promise => promise)\n await compilerHost.saveConfiguration()\n\n const metadata = new Map<string, Stats>()\n const cacheFiles = await walk(cacheDir, file => !file.startsWith(\".\"), {\n consume: (file, fileStat) => {\n if (fileStat.isFile()) {\n metadata.set(file, fileStat)\n }\n return null\n },\n })\n\n // add shim\n const shimPath = `${mainFileSet.src}${path.sep}${ELECTRON_COMPILE_SHIM_FILENAME}`\n mainFileSet.files.push(shimPath)\n mainFileSet.metadata.set(shimPath, { isFile: () => true, isDirectory: () => false, isSymbolicLink: () => false } as any)\n if (mainFileSet.transformedFiles == null) {\n mainFileSet.transformedFiles = new Map()\n }\n mainFileSet.transformedFiles.set(\n mainFileSet.files.length - 1,\n `\n'use strict';\nrequire('electron-compile').init(__dirname, require('path').resolve(__dirname, '${packager.metadata.main || \"index\"}'), true);\n`\n )\n return { src: electronCompileCache, files: cacheFiles, metadata, destination: mainFileSet.destination }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"appFileCopier.js","sourceRoot":"","sources":["../../src/util/appFileCopier.ts"],"names":[],"mappings":"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","sourcesContent":["import { AsyncTaskManager, FileCopier, FileTransformer, InvalidConfigurationError, isEmptyOrSpaces, Link, log, MAX_FILE_REQUESTS, statOrNull, walk } from \"builder-util\"\nimport { Stats } from \"fs\"\nimport { ensureSymlink } from \"fs-extra\"\nimport { mkdir, readlink } from \"fs/promises\"\nimport * as path from \"path\"\nimport asyncPool from \"tiny-async-pool\"\nimport { isLibOrExe } from \"../asar/unpackDetector\"\nimport { Platform } from \"../core\"\nimport { excludedExts, FileMatcher } from \"../fileMatcher\"\nimport { createElectronCompilerHost, NODE_MODULES_PATTERN } from \"../fileTransformer\"\nimport { getCollectorByPackageManager, PM } from \"../node-module-collector\"\nimport { LogMessageByKey, logMessageLevelByKey, ModuleManager } from \"../node-module-collector/moduleManager\"\nimport { Packager } from \"../packager\"\nimport { PlatformPackager } from \"../platformPackager\"\nimport { AppFileWalker } from \"./AppFileWalker\"\nimport { NodeModuleCopyHelper } from \"./NodeModuleCopyHelper\"\nimport { NodeModuleInfo } from \"./packageDependencies\"\n\nconst BOWER_COMPONENTS_PATTERN = `${path.sep}bower_components${path.sep}`\n/** @internal */\nexport const ELECTRON_COMPILE_SHIM_FILENAME = \"__shim.js\"\n\nexport function getDestinationPath(file: string, fileSet: ResolvedFileSet) {\n if (file === fileSet.src) {\n return fileSet.destination\n }\n\n const src = fileSet.src\n const dest = fileSet.destination\n // get node_modules path relative to src and then append to dest\n if (file.startsWith(src)) {\n return path.join(dest, path.relative(src, file))\n }\n return dest\n}\n\nexport async function copyAppFiles(fileSet: ResolvedFileSet, packager: Packager, transformer: FileTransformer) {\n const metadata = fileSet.metadata\n // search auto unpacked dir\n const taskManager = new AsyncTaskManager(packager.cancellationToken)\n const createdParentDirs = new Set<string>()\n\n const fileCopier = new FileCopier(file => {\n return !isLibOrExe(file)\n }, transformer)\n const links: Array<Link> = []\n for (let i = 0, n = fileSet.files.length; i < n; i++) {\n const sourceFile = fileSet.files[i]\n const stat = metadata.get(sourceFile)\n if (stat == null) {\n // dir\n continue\n }\n\n const destinationFile = getDestinationPath(sourceFile, fileSet)\n if (stat.isSymbolicLink()) {\n links.push({ file: destinationFile, link: await readlink(sourceFile) })\n continue\n }\n\n const fileParent = path.dirname(destinationFile)\n if (!createdParentDirs.has(fileParent)) {\n createdParentDirs.add(fileParent)\n await mkdir(fileParent, { recursive: true })\n }\n\n taskManager.addTask(fileCopier.copy(sourceFile, destinationFile, stat))\n if (taskManager.tasks.length > MAX_FILE_REQUESTS) {\n await taskManager.awaitTasks()\n }\n }\n\n if (taskManager.tasks.length > 0) {\n await taskManager.awaitTasks()\n }\n\n await asyncPool(MAX_FILE_REQUESTS, links, it => ensureSymlink(it.link, it.file))\n}\n\n// os path separator is used\nexport interface ResolvedFileSet {\n src: string\n destination: string\n\n files: Array<string>\n metadata: Map<string, Stats>\n transformedFiles?: Map<number, string | Buffer> | null\n}\n\n// used only for ASAR, if no asar, file transformed on the fly\nexport async function transformFiles(transformer: FileTransformer, fileSet: ResolvedFileSet): Promise<void> {\n if (transformer == null) {\n return\n }\n\n let transformedFiles = fileSet.transformedFiles\n if (fileSet.transformedFiles == null) {\n transformedFiles = new Map()\n fileSet.transformedFiles = transformedFiles\n }\n\n const metadata = fileSet.metadata\n const filesPromise = fileSet.files.map(async (it, index) => {\n const fileStat = metadata.get(it)\n if (fileStat == null || !fileStat.isFile()) {\n return\n }\n\n const transformedValue = transformer(it)\n if (transformedValue == null) {\n return\n }\n\n if (typeof transformedValue === \"object\" && \"then\" in transformedValue) {\n return (transformedValue as Promise<any>).then(it => {\n if (it != null) {\n transformedFiles!.set(index, it)\n }\n return\n })\n }\n transformedFiles!.set(index, transformedValue as string | Buffer)\n return\n })\n // `asyncPool` doesn't provide `index` in it's handler, so we `map` first before using it\n await asyncPool(MAX_FILE_REQUESTS, filesPromise, promise => promise)\n}\n\nexport async function computeFileSets(\n matchers: Array<FileMatcher>,\n transformer: FileTransformer | null,\n platformPackager: PlatformPackager<any>,\n isElectronCompile: boolean\n): Promise<Array<ResolvedFileSet>> {\n const fileSets: Array<ResolvedFileSet> = []\n const packager = platformPackager.info\n\n for (const matcher of matchers) {\n const fileWalker = new AppFileWalker(matcher, packager)\n\n const fromStat = await statOrNull(matcher.from)\n if (fromStat == null) {\n log.debug({ directory: matcher.from, reason: \"doesn't exist\" }, `skipped copying`)\n continue\n }\n\n const files = await walk(matcher.from, fileWalker.filter, fileWalker)\n const metadata = fileWalker.metadata\n fileSets.push(validateFileSet({ src: matcher.from, files, metadata, destination: matcher.to }))\n }\n\n if (isElectronCompile) {\n // cache files should be first (better IO)\n fileSets.unshift(await compileUsingElectronCompile(fileSets[0], packager))\n }\n return fileSets\n}\n\nfunction getNodeModuleExcludedExts(platformPackager: PlatformPackager<any>) {\n // do not exclude *.h files (https://github.com/electron-userland/electron-builder/issues/2852)\n const result = [\".o\", \".obj\"].concat(excludedExts.split(\",\").map(it => `.${it}`))\n if (platformPackager.config.includePdb !== true) {\n result.push(\".pdb\")\n }\n if (platformPackager.platform !== Platform.WINDOWS) {\n // https://github.com/electron-userland/electron-builder/issues/1738\n result.push(\".dll\")\n result.push(\".exe\")\n }\n return result\n}\n\nfunction validateFileSet(fileSet: ResolvedFileSet): ResolvedFileSet {\n if (fileSet.src == null || fileSet.src.length === 0) {\n throw new Error(\"fileset src is empty\")\n }\n return fileSet\n}\n\n/** @internal */\nexport async function computeNodeModuleFileSets(platformPackager: PlatformPackager<any>, mainMatcher: FileMatcher): Promise<Array<ResolvedFileSet>> {\n const deps = await collectNodeModulesWithLogging(platformPackager)\n\n const nodeModuleExcludedExts = getNodeModuleExcludedExts(platformPackager)\n // serial execution because copyNodeModules is concurrent and so, no need to increase queue/pressure\n const result = new Array<ResolvedFileSet>()\n let index = 0\n const NODE_MODULES = \"node_modules\"\n\n const collectNodeModules = async (dep: NodeModuleInfo, destination: string) => {\n const source = dep.dir\n const matcher = new FileMatcher(source, destination, mainMatcher.macroExpander, mainMatcher.patterns)\n const copier = new NodeModuleCopyHelper(matcher, platformPackager.info)\n const files = await copier.collectNodeModules(dep, nodeModuleExcludedExts, path.relative(mainMatcher.to, destination))\n result[index++] = validateFileSet({ src: source, destination, files, metadata: copier.metadata })\n\n log.debug({ dep: dep.name, from: log.filePath(source), to: log.filePath(destination), filesCount: files.length }, \"identified module\")\n\n if (dep.dependencies) {\n for (const c of dep.dependencies) {\n await collectNodeModules(c, path.join(destination, NODE_MODULES, c.name))\n }\n }\n }\n\n for (const dep of deps) {\n const destination = path.join(mainMatcher.to, NODE_MODULES, dep.name)\n await collectNodeModules(dep, destination)\n }\n return result\n}\n\ntype CollectedNodeModules = { nodeModules: NodeModuleInfo[]; logSummary: ModuleManager[\"logSummary\"] }\n\n/** Runs a single package-manager collector against a single directory. */\ntype CollectorRunner = (pm: PM, dir: string) => Promise<CollectedNodeModules>\n\n// `workspace:`/`file:`/`link:`/`portal:` dependencies are symlinked into place rather than\n// installed as standalone, hoistable packages, so they may legitimately be absent from a\n// collected tree and cannot be used to validate it.\nconst LOCAL_DEPENDENCY_SPEC = /^(?:workspace|file|link|portal):/\n\n/**\n * Determines whether a collected module tree actually describes the package being built.\n *\n * A package-manager `list` invocation can resolve to the wrong project root — most notably when\n * electron-builder is run from a workspace sub-package whose dependencies are hoisted to the\n * workspace root. In that case the collector returns a non-empty but unrelated tree. Accepting it\n * would suppress the manual-traversal fallback that resolves the correct modules, so we need to\n * tell a matching collection from a mismatched one.\n *\n * A collection matches when at least one of the package's declared external (registry-installed,\n * non-`workspace:`/`file:`/`link:`/`portal:`) production dependencies is present at the top level —\n * those direct dependencies are always hoisted to the top level of a correct collection. When the\n * package declares no external production dependencies there is nothing to validate against, so any\n * non-empty collection is accepted.\n */\nexport function collectionMatchesAppDependencies(nodeModules: NodeModuleInfo[], dependencies: Record<string, string> | undefined): boolean {\n const requiredExternalDeps = Object.entries(dependencies ?? {})\n .filter(([, spec]) => !LOCAL_DEPENDENCY_SPEC.test(spec))\n .map(([name]) => name)\n if (requiredExternalDeps.length === 0) {\n return true\n }\n const collected = new Set(nodeModules.map(it => it.name))\n return requiredExternalDeps.some(name => collected.has(name))\n}\n\n/**\n * Walks the candidate (package-manager, directory) combinations and returns the first collection\n * that both contains modules and matches the package being built (see\n * {@link collectionMatchesAppDependencies}). A non-empty collection that does NOT match — e.g. a\n * workspace-root tree returned for a sub-package — is retained only as a last-resort fallback so a\n * later approach (notably {@link PM.TRAVERSAL}) can supply the correct modules.\n */\nexport async function resolveFirstMatchingCollection(options: {\n pmApproaches: PM[]\n searchDirectories: string[]\n dependencies: Record<string, string> | undefined\n run: CollectorRunner\n}): Promise<CollectedNodeModules | undefined> {\n const { pmApproaches, searchDirectories, dependencies, run } = options\n let fallback: CollectedNodeModules | undefined\n\n for (const pm of pmApproaches) {\n for (const dir of searchDirectories) {\n log.info({ pm, searchDir: dir }, \"searching for node modules\")\n const deps = await run(pm, dir)\n if (deps.nodeModules.length === 0) {\n log.info({ pm, searchDir: dir }, \"no node modules found in collection, trying next search directory\")\n continue\n }\n if (collectionMatchesAppDependencies(deps.nodeModules, dependencies)) {\n log.debug({ pm, searchDir: dir, depCount: deps.nodeModules.length }, \"collected node modules\")\n return deps\n }\n log.info({ pm, searchDir: dir }, \"collected node modules do not match the target package, trying next search directory/approach\")\n fallback ??= deps\n }\n }\n return fallback\n}\n\n/** Extracts the package name from a `name@version` log-summary entry, handling `@scope/name@version`. */\nfunction dependencyNameFromSummaryId(id: string): string {\n let at: number\n if (id.startsWith(\"@\")) {\n // Scoped package: the version separator is the first `@` after the scope's `/`\n const slashIndex = id.indexOf(\"/\")\n if (slashIndex === -1) {\n return id\n }\n at = id.indexOf(\"@\", slashIndex + 1)\n } else {\n at = id.indexOf(\"@\")\n }\n return at > 0 ? id.slice(0, at) : id\n}\n\n/**\n * Enforces `allowMissingDependencies` against the finished collection summary (issue #10058).\n * Runs only after collection completes, so the error reports the COMPLETE set of missing\n * production dependencies at once instead of failing on the first one.\n *\n * v26 defaults to warn-only: `true` and omitted keep the historical warning behavior of the\n * stable 26.x line, while `false`/`null` fail the build on any missing production dependency\n * (the electron-builder 27+ default). When the option is a `string[]`, only the listed dependency\n * names are allowed to be missing — matched against the package name parsed from the summary's\n * `name@version` entries (scoped names included), with an exact-entry match accepted as well.\n *\n * Only genuinely missing production dependencies (`PKG_NOT_FOUND` / `PKG_NOT_ON_DISK`) are fatal;\n * missing optional dependencies (`PKG_OPTIONAL_NOT_INSTALLED` / `PKG_OPTIONAL_PLATFORM_NOT_INSTALLED`)\n * never fail the build.\n *\n * Exported for tests (an internal-tagged export would be stripped from the declarations the test\n * project consumes).\n */\nexport function enforceAllowMissingDependencies(allowMissingDependencies: boolean | Array<string> | null | undefined, logSummary: ModuleManager[\"logSummary\"] | undefined): void {\n // v26 default: omitted behaves like `true` (warn-only) so existing 26.x builds keep working.\n if (allowMissingDependencies === true || allowMissingDependencies === undefined) {\n return\n }\n const missing = new Set<string>([...(logSummary?.[LogMessageByKey.PKG_NOT_FOUND] ?? []), ...(logSummary?.[LogMessageByKey.PKG_NOT_ON_DISK] ?? [])])\n const allowed = new Set(Array.isArray(allowMissingDependencies) ? allowMissingDependencies : [])\n const fatal = Array.from(missing)\n .filter(id => !allowed.has(dependencyNameFromSummaryId(id)) && !allowed.has(id))\n .sort()\n if (fatal.length === 0) {\n return\n }\n throw new InvalidConfigurationError(\n `The following production dependencies could not be resolved during node-module collection:\\n` +\n fatal.map(id => ` - ${id}`).join(\"\\n\") +\n `\\nInstall the missing dependencies, list names in \\`allowMissingDependencies\\` to allow specific ones to be missing, or set \\`allowMissingDependencies\\` to true to only warn.`\n )\n}\n\n/** Exported for tests (an internal-tagged export would be stripped from the declarations the test project consumes). */\nexport async function collectNodeModulesWithLogging(platformPackager: PlatformPackager<any>) {\n const packager = platformPackager.info\n const { tempDirManager, appDir, projectDir } = packager\n\n const searchDirectories = Array.from(new Set([appDir, projectDir, await packager.getWorkspaceRoot()])).filter((it): it is string => isEmptyOrSpaces(it) === false)\n const pmApproaches = [await packager.getPackageManager(), PM.TRAVERSAL]\n\n // Validate against the as-declared (pre-extraMetadata) production dependencies so a configured\n // `extraMetadata.dependencies` entry that isn't installed cannot reject a correct collection.\n const deps = await resolveFirstMatchingCollection({\n pmApproaches,\n searchDirectories,\n dependencies: packager.originalMetadata.dependencies,\n run: (pm, dir) => getCollectorByPackageManager(pm, dir, tempDirManager).getNodeModules({ packageName: packager.nodePackageName }),\n })\n\n if (!deps?.nodeModules?.length) {\n log.warn({ searchDirectories: searchDirectories.map(it => log.filePath(it)) }, \"no node modules returned while searching directories\")\n return []\n }\n\n const summary = Object.entries(deps.logSummary ?? {}).filter(([, dependencies]) => Array.isArray(dependencies) && dependencies.length > 0)\n for (const [errorMessage, dependencies] of summary) {\n const logLevel = logMessageLevelByKey[errorMessage as LogMessageByKey] || \"debug\"\n log[logLevel]({ dependencies }, errorMessage)\n }\n\n // Enforcement (issue #10058): collection is complete and the summary above has reached the log,\n // so failing here reports every missing production dependency at once.\n enforceAllowMissingDependencies(packager.config.allowMissingDependencies, deps.logSummary)\n\n return deps.nodeModules\n}\n\nasync function compileUsingElectronCompile(mainFileSet: ResolvedFileSet, packager: Packager): Promise<ResolvedFileSet> {\n log.info(\"compiling using electron-compile\")\n\n const electronCompileCache = await packager.tempDirManager.getTempDir({ prefix: \"electron-compile-cache\" })\n const cacheDir = path.join(electronCompileCache, \".cache\")\n // clear and create cache dir\n await mkdir(cacheDir, { recursive: true })\n const compilerHost = await createElectronCompilerHost(mainFileSet.src, cacheDir)\n const nextSlashIndex = mainFileSet.src.length + 1\n // pre-compute electron-compile to cache dir - we need to process only subdirectories, not direct files of app dir\n const filesPromise: Promise<any>[] = mainFileSet.files.map(file => {\n if (\n file.includes(NODE_MODULES_PATTERN) ||\n file.includes(BOWER_COMPONENTS_PATTERN) ||\n !file.includes(path.sep, nextSlashIndex) || // ignore not root files\n !mainFileSet.metadata.get(file)!.isFile()\n ) {\n return\n }\n return compilerHost.compile(file)\n })\n await asyncPool(MAX_FILE_REQUESTS, filesPromise, promise => promise)\n await compilerHost.saveConfiguration()\n\n const metadata = new Map<string, Stats>()\n const cacheFiles = await walk(cacheDir, file => !file.startsWith(\".\"), {\n consume: (file, fileStat) => {\n if (fileStat.isFile()) {\n metadata.set(file, fileStat)\n }\n return null\n },\n })\n\n // add shim\n const shimPath = `${mainFileSet.src}${path.sep}${ELECTRON_COMPILE_SHIM_FILENAME}`\n mainFileSet.files.push(shimPath)\n mainFileSet.metadata.set(shimPath, { isFile: () => true, isDirectory: () => false, isSymbolicLink: () => false } as any)\n if (mainFileSet.transformedFiles == null) {\n mainFileSet.transformedFiles = new Map()\n }\n mainFileSet.transformedFiles.set(\n mainFileSet.files.length - 1,\n `\n'use strict';\nrequire('electron-compile').init(__dirname, require('path').resolve(__dirname, '${packager.metadata.main || \"index\"}'), true);\n`\n )\n return { src: electronCompileCache, files: cacheFiles, metadata, destination: mainFileSet.destination }\n}\n"]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ElectronPlatformArtifactDetails, MirrorOptions } from "@electron/get";
|
|
2
|
+
import * as crypto from "crypto";
|
|
2
3
|
import { ElectronPlatformName } from "../electron/ElectronFramework";
|
|
3
4
|
export type ElectronGetOptions = Omit<ElectronPlatformArtifactDetails, "platform" | "arch" | "version" | "artifactName" | "artifactSuffix" | "customFilename" | "tempDirectory" | "downloader" | "cacheMode" | "cacheRoot" | "downloadOptions" | "isGeneric" | "mirrorOptions"> & {
|
|
4
5
|
mirrorOptions?: Omit<MirrorOptions, "customDir" | "customFilename" | "customVersion">;
|
|
@@ -37,6 +38,11 @@ export declare function getCacheDirectory(options: {
|
|
|
37
38
|
allowEnvVarOverride: boolean;
|
|
38
39
|
}): string;
|
|
39
40
|
export declare function extractArchive(file: string, dir: string): Promise<void>;
|
|
41
|
+
export type ExpectedChecksum = {
|
|
42
|
+
algorithm: "sha256" | "sha512";
|
|
43
|
+
encoding: crypto.BinaryToTextEncoding;
|
|
44
|
+
value: string;
|
|
45
|
+
};
|
|
40
46
|
/**
|
|
41
47
|
* Downloads a generic artifact (.tar.gz or .zip) from a GitHub release.
|
|
42
48
|
* Used for electron-builder-binaries tools (appimage, etc.).
|
|
@@ -48,6 +54,46 @@ export declare function downloadBuilderToolset(options: {
|
|
|
48
54
|
githubOrgRepo?: string;
|
|
49
55
|
overrideUrl?: string;
|
|
50
56
|
}): Promise<string>;
|
|
57
|
+
/**
|
|
58
|
+
* Mirrors @electron/get's default cache root (`env-paths("electron", { suffix: "" }).cache`).
|
|
59
|
+
* @electron/get does not export it, so the (deliberately tiny) platform switch is replicated here.
|
|
60
|
+
* Must stay in sync with the `cacheRoot` default documented in @electron/get's
|
|
61
|
+
* `ElectronDownloadRequestOptions`.
|
|
62
|
+
* Exposed for unit testing; not part of the public API.
|
|
63
|
+
*/
|
|
64
|
+
export declare function defaultElectronGetCacheRoot(): string;
|
|
65
|
+
/**
|
|
66
|
+
* Parses the upstream `SHASUMS256.txt` format into the `Record<filename, sha256-hex>` shape that
|
|
67
|
+
* @electron/get accepts as inline `checksums`. Each line is `<sha256-hex> *<filename>` (binary
|
|
68
|
+
* mode) or `<sha256-hex> <filename>` (text mode); malformed lines are ignored.
|
|
69
|
+
* Exposed for unit testing; not part of the public API.
|
|
70
|
+
*/
|
|
71
|
+
export declare function parseChecksumFile(content: string): Record<string, string>;
|
|
72
|
+
/**
|
|
73
|
+
* Looks for a locally seeded SHASUMS256 file at the root of the @electron/get cache and returns
|
|
74
|
+
* its contents as inline `checksums`, or null when nothing usable is seeded.
|
|
75
|
+
*
|
|
76
|
+
* Why: without inline `checksums`, @electron/get re-downloads `SHASUMS256.txt` with a hardcoded
|
|
77
|
+
* `cacheMode: Bypass` on EVERY build — even when the artifact itself is a cache hit — so a fully
|
|
78
|
+
* seeded cache still requires network access and air-gapped builds fail (#10039). Cache-seeding
|
|
79
|
+
* tools (e.g. flatpak-node-generator) already place `SHASUMS256.txt-<version>` flat at the cache
|
|
80
|
+
* root; feeding it back as inline `checksums` keeps checksum validation enabled while making it
|
|
81
|
+
* fully offline. A plain `SHASUMS256.txt` at the cache root is accepted as a manual-seeding
|
|
82
|
+
* fallback. A candidate file is only used when it actually contains an entry for the requested
|
|
83
|
+
* artifact, so a stale file for another version can never break an online build.
|
|
84
|
+
* See https://www.electron.build/tutorials/offline-air-gapped-builds for the seeding contract.
|
|
85
|
+
* Exposed for unit testing; not part of the public API.
|
|
86
|
+
*/
|
|
87
|
+
export declare function resolveSeededChecksums(cacheRoot: string, version: string, artifactFileName: string): Promise<Record<string, string> | null>;
|
|
88
|
+
/**
|
|
89
|
+
* Assembles the `@electron/get` artifact config from `ArtifactDownloadOptions`, accepting both the
|
|
90
|
+
* legacy `ElectronDownloadOptions` and the modern `ElectronGetOptions` config shapes. When the
|
|
91
|
+
* resolved config has no `checksums` (user-provided `electronDownload.checksums` always wins) and
|
|
92
|
+
* checksum verification is not disabled, a locally seeded `SHASUMS256.txt-<version>` at the cache
|
|
93
|
+
* root is picked up as inline `checksums` so validation works offline (see resolveSeededChecksums).
|
|
94
|
+
* Exposed for unit testing; not part of the public API.
|
|
95
|
+
*/
|
|
96
|
+
export declare function buildElectronArtifactConfig(options: ArtifactDownloadOptions): Promise<ElectronPlatformArtifactDetails>;
|
|
51
97
|
/**
|
|
52
98
|
* Downloads the electron artifact zip via @electron/get (with caching) and returns the zip file path.
|
|
53
99
|
* Use when you need to extract the zip yourself (e.g. directly to appOutDir to preserve empty dirs and symlinks).
|
package/out/util/electronGet.js
CHANGED
|
@@ -4,7 +4,12 @@ exports.getCacheDirectory = getCacheDirectory;
|
|
|
4
4
|
exports.isSafeExtractPath = isSafeExtractPath;
|
|
5
5
|
exports.moveDirAtomic = moveDirAtomic;
|
|
6
6
|
exports.extractArchive = extractArchive;
|
|
7
|
+
exports.parseExpectedChecksum = parseExpectedChecksum;
|
|
7
8
|
exports.downloadBuilderToolset = downloadBuilderToolset;
|
|
9
|
+
exports.defaultElectronGetCacheRoot = defaultElectronGetCacheRoot;
|
|
10
|
+
exports.parseChecksumFile = parseChecksumFile;
|
|
11
|
+
exports.resolveSeededChecksums = resolveSeededChecksums;
|
|
12
|
+
exports.buildElectronArtifactConfig = buildElectronArtifactConfig;
|
|
8
13
|
exports.downloadElectronArtifactZip = downloadElectronArtifactZip;
|
|
9
14
|
exports.downloadElectronArtifact = downloadElectronArtifact;
|
|
10
15
|
exports.getBinariesMirrorUrl = getBinariesMirrorUrl;
|
|
@@ -211,22 +216,25 @@ async function extractArchive(file, dir) {
|
|
|
211
216
|
if (file.endsWith(".tar.gz") || file.endsWith(".tgz")) {
|
|
212
217
|
await tar.extract({ file, cwd: tmpDir, strip: 1 });
|
|
213
218
|
}
|
|
214
|
-
else if (file.endsWith(".tar.xz") || file.endsWith(".txz")) {
|
|
215
|
-
// node-tar cannot decompress xz,
|
|
219
|
+
else if (file.endsWith(".tar.xz") || file.endsWith(".txz") || file.endsWith(".tar.7z")) {
|
|
220
|
+
// Compressed tarballs node-tar cannot decompress itself (xz, 7z): use 7za to strip the outer
|
|
221
|
+
// compression layer into a .tar, then extract that tar.
|
|
222
|
+
// Note: the .tar.7z check MUST stay ahead of the plain .7z branch below, otherwise only the outer
|
|
223
|
+
// 7z layer is removed and the inner tar is left behind as-is (see https://github.com/electron-userland/electron-builder/issues/10002).
|
|
216
224
|
const cmd7za = await (0, _7zip_1.getPath7za)();
|
|
217
|
-
const
|
|
218
|
-
await fs.rm(
|
|
219
|
-
await fs.mkdir(
|
|
225
|
+
const decompressOutDir = `${tmpDir}.decompress`;
|
|
226
|
+
await fs.rm(decompressOutDir, { recursive: true, force: true });
|
|
227
|
+
await fs.mkdir(decompressOutDir, { recursive: true });
|
|
220
228
|
try {
|
|
221
|
-
await (0, builder_util_1.exec)(cmd7za, ["x", "-bd", file, (0, builder_util_1.to7zaOutputSwitch)((0, builder_util_1.sanitizeDirPath)(
|
|
222
|
-
const innerTar = (await fs.readdir(
|
|
229
|
+
await (0, builder_util_1.exec)(cmd7za, ["x", "-bd", file, (0, builder_util_1.to7zaOutputSwitch)((0, builder_util_1.sanitizeDirPath)(decompressOutDir)), "-y"]);
|
|
230
|
+
const innerTar = (await fs.readdir(decompressOutDir)).find(f => f.endsWith(".tar"));
|
|
223
231
|
if (innerTar == null) {
|
|
224
|
-
throw new Error(`
|
|
232
|
+
throw new Error(`decompression of ${path.basename(file)} produced no .tar archive`);
|
|
225
233
|
}
|
|
226
|
-
await tar.extract({ file: path.join(
|
|
234
|
+
await tar.extract({ file: path.join(decompressOutDir, innerTar), cwd: tmpDir, strip: 1 });
|
|
227
235
|
}
|
|
228
236
|
finally {
|
|
229
|
-
await fs.rm(
|
|
237
|
+
await fs.rm(decompressOutDir, { recursive: true, force: true });
|
|
230
238
|
}
|
|
231
239
|
}
|
|
232
240
|
else if (file.endsWith(".zip")) {
|
|
@@ -357,24 +365,64 @@ async function downloadArtifactToFile(config, label) {
|
|
|
357
365
|
await releaseArtifactLock().catch(err => builder_util_1.log.warn({ err }, "failed to release artifact download lock"));
|
|
358
366
|
}
|
|
359
367
|
}
|
|
368
|
+
// @electron/get delegates verification to sumchecker, which only understands SHA-256 hex.
|
|
369
|
+
// The historically documented customNsisBinary/customNsisResources checksums are base64-encoded
|
|
370
|
+
// SHA-512, so those must be verified by electron-builder itself after the download
|
|
371
|
+
// (https://github.com/electron-userland/electron-builder/issues/10040).
|
|
372
|
+
const SHA256_HEX_RE = /^[0-9a-fA-F]{64}$/;
|
|
373
|
+
// 64 raw bytes → 86 significant base64 chars + "==" padding
|
|
374
|
+
const SHA512_BASE64_RE = /^[A-Za-z0-9+/]{86}==$/;
|
|
375
|
+
/** @internal exported for unit testing */
|
|
376
|
+
function parseExpectedChecksum(filename, value) {
|
|
377
|
+
if (SHA256_HEX_RE.test(value)) {
|
|
378
|
+
return { algorithm: "sha256", encoding: "hex", value };
|
|
379
|
+
}
|
|
380
|
+
if (SHA512_BASE64_RE.test(value)) {
|
|
381
|
+
return { algorithm: "sha512", encoding: "base64", value };
|
|
382
|
+
}
|
|
383
|
+
throw new Error(`Unrecognized checksum format for "${filename}": "${value}". ` +
|
|
384
|
+
`Accepted formats: 64-character SHA-256 hex (e.g. "shasum -a 256 <file>") or ` +
|
|
385
|
+
`88-character base64-encoded SHA-512 (e.g. "openssl dgst -sha512 -binary <file> | openssl base64 -A")`);
|
|
386
|
+
}
|
|
387
|
+
function hashFile(file, algorithm, encoding) {
|
|
388
|
+
return new Promise((resolve, reject) => {
|
|
389
|
+
const h = crypto.createHash(algorithm);
|
|
390
|
+
const s = (0, fs_1.createReadStream)(file);
|
|
391
|
+
s.on("error", reject);
|
|
392
|
+
s.on("data", (chunk) => h.update(chunk));
|
|
393
|
+
s.on("end", () => resolve(h.digest(encoding)));
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* Verifies a downloaded archive against a checksum @electron/get could not validate itself
|
|
398
|
+
* (i.e. base64 SHA-512). Deletes the file and throws on mismatch.
|
|
399
|
+
*/
|
|
400
|
+
async function verifyDownloadedArchive(file, label, expected) {
|
|
401
|
+
const actual = await hashFile(file, expected.algorithm, expected.encoding);
|
|
402
|
+
if (actual !== expected.value) {
|
|
403
|
+
await fs.rm(file, { force: true }).catch(() => { });
|
|
404
|
+
throw new Error(`${expected.algorithm} checksum mismatch for ${label}: expected "${expected.value}" but downloaded file is "${actual}". The corrupted download has been removed.`);
|
|
405
|
+
}
|
|
406
|
+
builder_util_1.log.debug({ file: label, algorithm: expected.algorithm }, "checksum verified");
|
|
407
|
+
}
|
|
360
408
|
/**
|
|
361
409
|
* Checks electron-builder's own archive cache for a previously downloaded archive.
|
|
362
|
-
* Validates the SHA-256
|
|
363
|
-
* null on miss or checksum mismatch (mismatch also deletes the stale file).
|
|
410
|
+
* Validates the checksum (SHA-256 hex or base64 SHA-512) when one is known. Returns the
|
|
411
|
+
* cached path on hit, null on miss or checksum mismatch (mismatch also deletes the stale file).
|
|
412
|
+
*
|
|
413
|
+
* Air-gapped seeding contract: placing the archive at
|
|
414
|
+
* `<cacheDir>/<releaseName>/<archive>` (e.g. `$ELECTRON_BUILDER_CACHE/appimage@1.0.3/appimage-tools-runtime-20251108.tar.gz`)
|
|
415
|
+
* is sufficient for a fully offline toolset resolution — the checksum here is computed locally
|
|
416
|
+
* against the value hardcoded in the toolset module, and extraction happens locally too. No
|
|
417
|
+
* `.state` file needs to be seeded. See https://www.electron.build/tutorials/offline-air-gapped-builds.
|
|
364
418
|
*/
|
|
365
|
-
async function resolveFromArchiveCache(archiveCachePath, label,
|
|
419
|
+
async function resolveFromArchiveCache(archiveCachePath, label, expected) {
|
|
366
420
|
if (!(await (0, builder_util_1.exists)(archiveCachePath))) {
|
|
367
421
|
return null;
|
|
368
422
|
}
|
|
369
|
-
if (
|
|
370
|
-
const hash = await
|
|
371
|
-
|
|
372
|
-
const s = (0, fs_1.createReadStream)(archiveCachePath);
|
|
373
|
-
s.on("error", reject);
|
|
374
|
-
s.on("data", (chunk) => h.update(chunk));
|
|
375
|
-
s.on("end", () => resolve(h.digest("hex")));
|
|
376
|
-
});
|
|
377
|
-
if (hash !== expectedSha256) {
|
|
423
|
+
if (expected) {
|
|
424
|
+
const hash = await hashFile(archiveCachePath, expected.algorithm, expected.encoding);
|
|
425
|
+
if (hash !== expected.value) {
|
|
378
426
|
builder_util_1.log.warn({ file: label, archiveCachePath }, "cached archive checksum mismatch — removing and re-downloading");
|
|
379
427
|
await fs.rm(archiveCachePath).catch(() => { });
|
|
380
428
|
return null;
|
|
@@ -401,8 +449,7 @@ async function persistToArchiveCache(sourcePath, archiveCachePath) {
|
|
|
401
449
|
* progress bar, extraction (.zip or .tar.gz), and completion marker.
|
|
402
450
|
* Both public download functions delegate here after building their respective configs.
|
|
403
451
|
*/
|
|
404
|
-
async function downloadAndExtract(config, extractDir, label, archiveCachePath) {
|
|
405
|
-
var _a;
|
|
452
|
+
async function downloadAndExtract(config, extractDir, label, archiveCachePath, expectedChecksum) {
|
|
406
453
|
await fs.mkdir(extractDir, { recursive: true });
|
|
407
454
|
// Pre-lock fast path: only short-circuit for a definitively complete and valid cache.
|
|
408
455
|
// Do NOT clean up here — concurrent processes could race to delete under each other.
|
|
@@ -446,7 +493,7 @@ async function downloadAndExtract(config, extractDir, label, archiveCachePath) {
|
|
|
446
493
|
// This lets repeated builds (or offline environments) skip the download entirely once
|
|
447
494
|
// the archive has been fetched at least once.
|
|
448
495
|
if (archiveCachePath) {
|
|
449
|
-
downloadedFile = await resolveFromArchiveCache(archiveCachePath, label,
|
|
496
|
+
downloadedFile = await resolveFromArchiveCache(archiveCachePath, label, expectedChecksum);
|
|
450
497
|
}
|
|
451
498
|
if (!downloadedFile) {
|
|
452
499
|
builder_util_1.log.debug({ file: label }, "downloading");
|
|
@@ -454,6 +501,12 @@ async function downloadAndExtract(config, extractDir, label, archiveCachePath) {
|
|
|
454
501
|
if (!downloadedFile) {
|
|
455
502
|
throw new Error(`Failed to download artifact: ${label}`);
|
|
456
503
|
}
|
|
504
|
+
// sha256-hex checksums are verified by @electron/get during the download; any other
|
|
505
|
+
// format was passed with unsafelyDisableChecksums, so verify it here before the
|
|
506
|
+
// archive is cached or extracted.
|
|
507
|
+
if (expectedChecksum != null && expectedChecksum.algorithm !== "sha256") {
|
|
508
|
+
await verifyDownloadedArchive(downloadedFile, label, expectedChecksum);
|
|
509
|
+
}
|
|
457
510
|
// Persist the downloaded archive so future builds (and offline environments) can
|
|
458
511
|
// skip the network request entirely.
|
|
459
512
|
if (archiveCachePath) {
|
|
@@ -486,10 +539,23 @@ async function downloadBuilderToolset(options) {
|
|
|
486
539
|
if (/[/\\]|\.\./.test(filenameWithExt)) {
|
|
487
540
|
throw new Error(`downloadBuilderToolset: unsafe filenameWithExt "${filenameWithExt}" — must be a plain filename with no path separators or traversal sequences`);
|
|
488
541
|
}
|
|
542
|
+
// Classify every provided checksum up front so a malformed value fails fast with a clear
|
|
543
|
+
// config error instead of a sumchecker parse error mid-download (#10040).
|
|
544
|
+
const parsedChecksums = checksums == null ? undefined : new Map(Object.entries(checksums).map(([file, value]) => [file, parseExpectedChecksum(file, value)]));
|
|
545
|
+
if (parsedChecksums != null && new Set(Array.from(parsedChecksums.values(), c => c.algorithm)).size > 1) {
|
|
546
|
+
throw new Error(`checksums for ${releaseName} mix formats — use a single format for all entries: either SHA-256 hex or base64-encoded SHA-512`);
|
|
547
|
+
}
|
|
548
|
+
const expectedChecksum = parsedChecksums === null || parsedChecksums === void 0 ? void 0 : parsedChecksums.get(filenameWithExt);
|
|
549
|
+
// @electron/get can only verify sha256-hex itself; for any other format the download is
|
|
550
|
+
// verified manually in downloadAndExtract, so disable its sumchecker-based validation.
|
|
551
|
+
const electronGetVerifiableChecksums = parsedChecksums != null && Array.from(parsedChecksums.values()).every(c => c.algorithm === "sha256") ? checksums : undefined;
|
|
489
552
|
const baseUrl = getBinariesMirrorUrl(githubOrgRepo);
|
|
490
553
|
const fullUrl = overrideUrl ? `${overrideUrl}/${filenameWithExt}` : `${baseUrl}${releaseName}/${filenameWithExt}`;
|
|
491
554
|
const suffix = hashUrlSafe(fullUrl, 5);
|
|
492
|
-
|
|
555
|
+
// tar.7z is listed before 7z so the full extension is stripped. Deliberate side effect: this changes the
|
|
556
|
+
// extract-dir name for .tar.7z toolsets (e.g. the snap template) from "<name>.tar-<hash>" to "<name>-<hash>",
|
|
557
|
+
// which busts caches poisoned by the broken .tar.7z extraction in 26.15.0-26.15.6 (issue #10002).
|
|
558
|
+
const folderName = `${filenameWithExt.replace(/\.(tar\.gz|tgz|tar\.xz|txz|tar\.7z|zip|7z)$/, "")}-${suffix}`;
|
|
493
559
|
const extractDir = path.join(getCacheDirectory({ allowEnvVarOverride: true }), releaseName, folderName);
|
|
494
560
|
// Use resolveAssetURL so @electron/get's ELECTRON_MIRROR env var check cannot override
|
|
495
561
|
// the builder-binaries URL we've already resolved (see getArtifactRemoteURL in @electron/get).
|
|
@@ -505,23 +571,104 @@ async function downloadBuilderToolset(options) {
|
|
|
505
571
|
artifactName: filenameWithExt,
|
|
506
572
|
cacheRoot: path.resolve(getCacheDirectory({ allowEnvVarOverride: true }), "downloads"),
|
|
507
573
|
cacheMode: resolveCacheMode(),
|
|
508
|
-
...(
|
|
574
|
+
...(electronGetVerifiableChecksums != null ? { checksums: electronGetVerifiableChecksums } : { unsafelyDisableChecksums: true }),
|
|
509
575
|
mirrorOptions,
|
|
510
576
|
isGeneric: true,
|
|
511
577
|
};
|
|
512
|
-
return downloadAndExtract(config, extractDir, filenameWithExt, archiveCachePath);
|
|
578
|
+
return downloadAndExtract(config, extractDir, filenameWithExt, archiveCachePath, expectedChecksum);
|
|
513
579
|
}
|
|
514
580
|
// Keys present in ElectronGetOptions but absent from ElectronDownloadOptions.
|
|
515
581
|
// Used to discriminate between the two config shapes at runtime.
|
|
516
|
-
|
|
582
|
+
// "checksums" is included so that `electronDownload: { checksums: {...} }` alone is routed to the
|
|
583
|
+
// modern branch and actually forwarded to @electron/get instead of being silently dropped.
|
|
584
|
+
const ELECTRON_GET_EXCLUSIVE_KEYS = ["mirrorOptions", "force", "unsafelyDisableChecksums", "checksums"];
|
|
517
585
|
function isElectronGetOptions(dl) {
|
|
518
586
|
return ELECTRON_GET_EXCLUSIVE_KEYS.some(k => Object.hasOwnProperty.call(dl, k));
|
|
519
587
|
}
|
|
520
588
|
/**
|
|
521
|
-
*
|
|
522
|
-
*
|
|
589
|
+
* Mirrors @electron/get's default cache root (`env-paths("electron", { suffix: "" }).cache`).
|
|
590
|
+
* @electron/get does not export it, so the (deliberately tiny) platform switch is replicated here.
|
|
591
|
+
* Must stay in sync with the `cacheRoot` default documented in @electron/get's
|
|
592
|
+
* `ElectronDownloadRequestOptions`.
|
|
593
|
+
* Exposed for unit testing; not part of the public API.
|
|
594
|
+
*/
|
|
595
|
+
function defaultElectronGetCacheRoot() {
|
|
596
|
+
const name = "electron";
|
|
597
|
+
const homeDir = os.homedir();
|
|
598
|
+
switch (os.platform()) {
|
|
599
|
+
case "darwin":
|
|
600
|
+
return path.join(homeDir, "Library", "Caches", name);
|
|
601
|
+
case "win32":
|
|
602
|
+
return path.join(process.env.LOCALAPPDATA || path.join(homeDir, "AppData", "Local"), name, "Cache");
|
|
603
|
+
default:
|
|
604
|
+
return path.join(process.env.XDG_CACHE_HOME || path.join(homeDir, ".cache"), name);
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
/**
|
|
608
|
+
* Parses the upstream `SHASUMS256.txt` format into the `Record<filename, sha256-hex>` shape that
|
|
609
|
+
* @electron/get accepts as inline `checksums`. Each line is `<sha256-hex> *<filename>` (binary
|
|
610
|
+
* mode) or `<sha256-hex> <filename>` (text mode); malformed lines are ignored.
|
|
611
|
+
* Exposed for unit testing; not part of the public API.
|
|
523
612
|
*/
|
|
524
|
-
function
|
|
613
|
+
function parseChecksumFile(content) {
|
|
614
|
+
const checksums = {};
|
|
615
|
+
for (const rawLine of content.split("\n")) {
|
|
616
|
+
const match = /^([a-fA-F0-9]{64})\s+\*?(.+)$/.exec(rawLine.trim());
|
|
617
|
+
if (match != null) {
|
|
618
|
+
checksums[match[2]] = match[1].toLowerCase();
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
return checksums;
|
|
622
|
+
}
|
|
623
|
+
/**
|
|
624
|
+
* Looks for a locally seeded SHASUMS256 file at the root of the @electron/get cache and returns
|
|
625
|
+
* its contents as inline `checksums`, or null when nothing usable is seeded.
|
|
626
|
+
*
|
|
627
|
+
* Why: without inline `checksums`, @electron/get re-downloads `SHASUMS256.txt` with a hardcoded
|
|
628
|
+
* `cacheMode: Bypass` on EVERY build — even when the artifact itself is a cache hit — so a fully
|
|
629
|
+
* seeded cache still requires network access and air-gapped builds fail (#10039). Cache-seeding
|
|
630
|
+
* tools (e.g. flatpak-node-generator) already place `SHASUMS256.txt-<version>` flat at the cache
|
|
631
|
+
* root; feeding it back as inline `checksums` keeps checksum validation enabled while making it
|
|
632
|
+
* fully offline. A plain `SHASUMS256.txt` at the cache root is accepted as a manual-seeding
|
|
633
|
+
* fallback. A candidate file is only used when it actually contains an entry for the requested
|
|
634
|
+
* artifact, so a stale file for another version can never break an online build.
|
|
635
|
+
* See https://www.electron.build/tutorials/offline-air-gapped-builds for the seeding contract.
|
|
636
|
+
* Exposed for unit testing; not part of the public API.
|
|
637
|
+
*/
|
|
638
|
+
async function resolveSeededChecksums(cacheRoot, version, artifactFileName) {
|
|
639
|
+
const candidates = [path.join(cacheRoot, `SHASUMS256.txt-${version}`), path.join(cacheRoot, "SHASUMS256.txt")];
|
|
640
|
+
for (const candidate of candidates) {
|
|
641
|
+
if (!(await (0, builder_util_1.exists)(candidate))) {
|
|
642
|
+
continue;
|
|
643
|
+
}
|
|
644
|
+
let content;
|
|
645
|
+
try {
|
|
646
|
+
content = await fs.readFile(candidate, "utf-8");
|
|
647
|
+
}
|
|
648
|
+
catch (err) {
|
|
649
|
+
builder_util_1.log.warn({ file: builder_util_1.log.filePath(candidate), err: err.message }, "failed to read seeded SHASUMS file — ignoring it");
|
|
650
|
+
continue;
|
|
651
|
+
}
|
|
652
|
+
const checksums = parseChecksumFile(content);
|
|
653
|
+
if (checksums[artifactFileName] == null) {
|
|
654
|
+
builder_util_1.log.warn({ file: builder_util_1.log.filePath(candidate), artifactFileName }, "seeded SHASUMS file has no entry for the requested artifact — ignoring it");
|
|
655
|
+
continue;
|
|
656
|
+
}
|
|
657
|
+
builder_util_1.log.debug({ file: builder_util_1.log.filePath(candidate), artifactFileName }, "using locally seeded SHASUMS256 checksums — checksum validation can run offline");
|
|
658
|
+
return checksums;
|
|
659
|
+
}
|
|
660
|
+
return null;
|
|
661
|
+
}
|
|
662
|
+
/**
|
|
663
|
+
* Assembles the `@electron/get` artifact config from `ArtifactDownloadOptions`, accepting both the
|
|
664
|
+
* legacy `ElectronDownloadOptions` and the modern `ElectronGetOptions` config shapes. When the
|
|
665
|
+
* resolved config has no `checksums` (user-provided `electronDownload.checksums` always wins) and
|
|
666
|
+
* checksum verification is not disabled, a locally seeded `SHASUMS256.txt-<version>` at the cache
|
|
667
|
+
* root is picked up as inline `checksums` so validation works offline (see resolveSeededChecksums).
|
|
668
|
+
* Exposed for unit testing; not part of the public API.
|
|
669
|
+
*/
|
|
670
|
+
async function buildElectronArtifactConfig(options) {
|
|
671
|
+
var _a;
|
|
525
672
|
const { electronDownload, arch, version, platformName: platform, artifactName, cacheDir: cacheRoot } = options;
|
|
526
673
|
let artifactConfig = { cacheRoot, platform, arch, version, artifactName };
|
|
527
674
|
if (electronDownload != null) {
|
|
@@ -557,19 +704,28 @@ function buildElectronArtifactConfig(options) {
|
|
|
557
704
|
}
|
|
558
705
|
}
|
|
559
706
|
artifactConfig.cacheMode = resolveCacheMode();
|
|
707
|
+
if (artifactConfig.checksums == null && !artifactConfig.unsafelyDisableChecksums) {
|
|
708
|
+
// Matches @electron/get's getArtifactFileName for non-generic artifacts; `artifactSuffix` and
|
|
709
|
+
// `customFilename` cannot diverge here — both are excluded from ElectronGetOptions.
|
|
710
|
+
const artifactFileName = `${artifactConfig.artifactName}-v${artifactConfig.version}-${artifactConfig.platform}-${artifactConfig.arch}.zip`;
|
|
711
|
+
const seededChecksums = await resolveSeededChecksums((_a = artifactConfig.cacheRoot) !== null && _a !== void 0 ? _a : defaultElectronGetCacheRoot(), artifactConfig.version, artifactFileName);
|
|
712
|
+
if (seededChecksums != null) {
|
|
713
|
+
artifactConfig.checksums = seededChecksums;
|
|
714
|
+
}
|
|
715
|
+
}
|
|
560
716
|
return artifactConfig;
|
|
561
717
|
}
|
|
562
718
|
/**
|
|
563
719
|
* Downloads the electron artifact zip via @electron/get (with caching) and returns the zip file path.
|
|
564
720
|
* Use when you need to extract the zip yourself (e.g. directly to appOutDir to preserve empty dirs and symlinks).
|
|
565
721
|
*/
|
|
566
|
-
function downloadElectronArtifactZip(options) {
|
|
567
|
-
const config = buildElectronArtifactConfig(options);
|
|
722
|
+
async function downloadElectronArtifactZip(options) {
|
|
723
|
+
const config = await buildElectronArtifactConfig(options);
|
|
568
724
|
return downloadArtifactToFile(config, config.artifactName);
|
|
569
725
|
}
|
|
570
726
|
async function downloadElectronArtifact(options) {
|
|
571
727
|
const { arch, version, platformName: platform, artifactName } = options;
|
|
572
|
-
const artifactConfig = buildElectronArtifactConfig(options);
|
|
728
|
+
const artifactConfig = await buildElectronArtifactConfig(options);
|
|
573
729
|
const suffix = hashUrlSafe(JSON.stringify(artifactConfig), 5);
|
|
574
730
|
const folderName = `${artifactName}-v${version}-${platform}-${arch}-${suffix}`;
|
|
575
731
|
const extractDir = path.join(getCacheDirectory({ allowEnvVarOverride: true }), `${artifactName}-v${version}`, folderName);
|