app-builder-lib 26.2.0 → 26.3.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.
- package/out/asar/asarUtil.js +78 -10
- package/out/asar/asarUtil.js.map +1 -1
- package/out/asar/unpackDetector.js +1 -3
- package/out/asar/unpackDetector.js.map +1 -1
- package/out/codeSign/macCodeSign.js +2 -1
- package/out/codeSign/macCodeSign.js.map +1 -1
- package/out/electron/search-module.js +1 -1
- package/out/electron/search-module.js.map +1 -1
- package/out/fileMatcher.js +1 -1
- package/out/fileMatcher.js.map +1 -1
- package/out/node-module-collector/bunNodeModulesCollector.d.ts +11 -0
- package/out/node-module-collector/bunNodeModulesCollector.js +22 -0
- package/out/node-module-collector/bunNodeModulesCollector.js.map +1 -0
- package/out/node-module-collector/index.d.ts +21 -6
- package/out/node-module-collector/index.js +93 -32
- package/out/node-module-collector/index.js.map +1 -1
- package/out/node-module-collector/moduleCache.d.ts +21 -0
- package/out/node-module-collector/moduleCache.js +16 -0
- package/out/node-module-collector/moduleCache.js.map +1 -0
- package/out/node-module-collector/nodeModulesCollector.d.ts +50 -14
- package/out/node-module-collector/nodeModulesCollector.js +239 -70
- package/out/node-module-collector/nodeModulesCollector.js.map +1 -1
- package/out/node-module-collector/npmNodeModulesCollector.d.ts +10 -3
- package/out/node-module-collector/npmNodeModulesCollector.js +100 -13
- package/out/node-module-collector/npmNodeModulesCollector.js.map +1 -1
- package/out/node-module-collector/packageManager.d.ts +8 -6
- package/out/node-module-collector/packageManager.js +73 -29
- package/out/node-module-collector/packageManager.js.map +1 -1
- package/out/node-module-collector/pnpmNodeModulesCollector.d.ts +4 -4
- package/out/node-module-collector/pnpmNodeModulesCollector.js +49 -23
- package/out/node-module-collector/pnpmNodeModulesCollector.js.map +1 -1
- package/out/node-module-collector/types.d.ts +25 -1
- package/out/node-module-collector/types.js.map +1 -1
- package/out/node-module-collector/yarnBerryNodeModulesCollector.d.ts +15 -0
- package/out/node-module-collector/yarnBerryNodeModulesCollector.js +93 -0
- package/out/node-module-collector/yarnBerryNodeModulesCollector.js.map +1 -0
- package/out/node-module-collector/yarnNodeModulesCollector.d.ts +12 -2
- package/out/node-module-collector/yarnNodeModulesCollector.js +234 -5
- package/out/node-module-collector/yarnNodeModulesCollector.js.map +1 -1
- package/out/options/winOptions.d.ts +2 -1
- package/out/options/winOptions.js.map +1 -1
- package/out/packager.d.ts +6 -1
- package/out/packager.js +12 -5
- package/out/packager.js.map +1 -1
- package/out/publish/PublishManager.js +2 -2
- package/out/publish/PublishManager.js.map +1 -1
- package/out/targets/AppxTarget.js +1 -1
- package/out/targets/AppxTarget.js.map +1 -1
- package/out/targets/MsiTarget.js +1 -1
- package/out/targets/MsiTarget.js.map +1 -1
- package/out/targets/nsis/NsisTarget.js +2 -2
- package/out/targets/nsis/NsisTarget.js.map +1 -1
- package/out/targets/nsis/nsisUtil.js +1 -1
- package/out/targets/nsis/nsisUtil.js.map +1 -1
- package/out/targets/tools.js +12 -12
- package/out/targets/tools.js.map +1 -1
- package/out/util/appFileCopier.js +18 -10
- package/out/util/appFileCopier.js.map +1 -1
- package/out/util/macosIconComposer.js +11 -4
- package/out/util/macosIconComposer.js.map +1 -1
- package/out/util/yarn.d.ts +4 -2
- package/out/util/yarn.js +34 -24
- package/out/util/yarn.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/out/winPackager.d.ts +1 -1
- package/out/winPackager.js +26 -9
- package/out/winPackager.js.map +1 -1
- package/package.json +9 -9
- package/scheme.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/node-module-collector/types.ts"],"names":[],"mappings":"","sourcesContent":["export interface NodeModuleInfo {\n name: string\n version: string\n dir: string\n dependencies?: Array<NodeModuleInfo>\n}\n\nexport type ParsedDependencyTree = {\n readonly name: string\n readonly version: string\n readonly path: string\n readonly workspaces?: string[] // we only use this at root level\n}\n\n// Note: `PnpmDependency` and `NpmDependency` include the output of `JSON.parse(...)` of `pnpm list` and `npm list` respectively\n// This object has a TON of info - a majority, if not all, of each dependency's package.json\n// We extract only what we need when constructing DependencyTree in `extractProductionDependencyTree`\nexport interface PnpmDependency extends Dependency<PnpmDependency, PnpmDependency> {\n readonly from: string\n}\n\nexport interface NpmDependency extends Dependency<NpmDependency, string> {\n // implicit dependencies\n readonly _dependencies?: {\n [packageName: string]: string\n }\n}\n\nexport type Dependency<T, V> = Dependencies<T, V> & ParsedDependencyTree\n\nexport type Dependencies<T, V> = {\n readonly dependencies?: {\n [packageName: string]: T\n }\n readonly optionalDependencies?: {\n [packageName: string]: V\n }\n}\n\nexport interface DependencyGraph {\n [packageNameAndVersion: string]: PackageDependencies\n}\n\ninterface PackageDependencies {\n readonly dependencies: string[]\n}\n"]}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/node-module-collector/types.ts"],"names":[],"mappings":"","sourcesContent":["export type PackageJson = {\n name: string\n version: string\n dependencies?: Record<string, string>\n devDependencies?: Record<string, string>\n peerDependencies?: Record<string, string>\n optionalDependencies?: Record<string, string>\n workspaces?: string[] | { packages: string[] }\n}\n\nexport type ResolveModuleOptions<T> = {\n dependency: T\n virtualPath?: string // e.g. for file: dependencies or symlinked dependencies\n isOptionalDependency?: boolean\n}\n\nexport interface NodeModuleInfo {\n name: string\n version: string\n dir: string\n dependencies?: Array<NodeModuleInfo>\n}\n\nexport type ParsedDependencyTree = {\n readonly name: string\n readonly version: string\n readonly path: string\n readonly workspaces?: string[] | { packages: string[] } // we only use this at root level\n}\n\n// Note: `PnpmDependency` and `NpmDependency` include the output of `JSON.parse(...)` of `pnpm list` and `npm list` respectively\n// This object has a TON of info - a majority, if not all, of each dependency's package.json\n// We extract only what we need when constructing DependencyTree in `extractProductionDependencyTree`\nexport interface PnpmDependency extends Dependency<PnpmDependency, PnpmDependency> {\n readonly from: string\n readonly resolved: string\n}\n\nexport interface NpmDependency extends Dependency<NpmDependency, string> {\n readonly resolved?: string\n // implicit dependencies\n readonly _dependencies?: {\n [packageName: string]: string\n }\n}\n\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport interface YarnBerryDependency extends Dependency<YarnBerryDependency, string> {}\n\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport interface YarnDependency extends Dependency<YarnDependency, YarnDependency> {}\n\nexport type Dependency<T, V> = Dependencies<T, V> & ParsedDependencyTree\n\nexport type Dependencies<T, V> = {\n readonly dependencies?: {\n [packageName: string]: T\n }\n readonly optionalDependencies?: {\n [packageName: string]: V\n }\n}\n\nexport interface DependencyGraph {\n [packageNameAndVersion: string]: PackageDependencies\n}\n\ninterface PackageDependencies {\n readonly dependencies: string[]\n}\n"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Lazy } from "lazy-val";
|
|
2
|
+
import { NpmNodeModulesCollector } from "./npmNodeModulesCollector";
|
|
3
|
+
import { PM } from "./packageManager";
|
|
4
|
+
import { NpmDependency } from "./types";
|
|
5
|
+
export declare class YarnBerryNodeModulesCollector extends NpmNodeModulesCollector {
|
|
6
|
+
readonly installOptions: {
|
|
7
|
+
manager: PM;
|
|
8
|
+
lockfile: string;
|
|
9
|
+
};
|
|
10
|
+
private yarnSetupInfo;
|
|
11
|
+
protected isHoisted: Lazy<boolean>;
|
|
12
|
+
protected getDependenciesTree(_pm: PM): Promise<NpmDependency>;
|
|
13
|
+
protected isProdDependency(packageName: string, tree: NpmDependency): boolean;
|
|
14
|
+
private detectYarnSetup;
|
|
15
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.YarnBerryNodeModulesCollector = void 0;
|
|
4
|
+
const builder_util_1 = require("builder-util");
|
|
5
|
+
const lazy_val_1 = require("lazy-val");
|
|
6
|
+
const npmNodeModulesCollector_1 = require("./npmNodeModulesCollector");
|
|
7
|
+
const packageManager_1 = require("./packageManager");
|
|
8
|
+
// Only Yarn v1 uses CLI. We should use pnp.cjs for PnP, but we can't access the files due to virtual file paths within zipped modules.
|
|
9
|
+
// We fallback to npm node module collection (since Yarn Berry could have npm-like structure OR pnpm-like structure, depending on `nmHoistingLimits` configuration).
|
|
10
|
+
// In the latter case, we still can't assume `pnpm` is installed, so we still try to use npm collection as a best-effort attempt.
|
|
11
|
+
// If those fail, such as if using corepack, we attempt to manually build the tree.
|
|
12
|
+
class YarnBerryNodeModulesCollector extends npmNodeModulesCollector_1.NpmNodeModulesCollector {
|
|
13
|
+
constructor() {
|
|
14
|
+
super(...arguments);
|
|
15
|
+
this.installOptions = {
|
|
16
|
+
manager: packageManager_1.PM.YARN_BERRY,
|
|
17
|
+
lockfile: "yarn.lock",
|
|
18
|
+
};
|
|
19
|
+
this.yarnSetupInfo = new lazy_val_1.Lazy(async () => this.detectYarnSetup(this.rootDir));
|
|
20
|
+
this.isHoisted = new lazy_val_1.Lazy(async () => this.yarnSetupInfo.value.then(info => info.isHoisted));
|
|
21
|
+
}
|
|
22
|
+
async getDependenciesTree(_pm) {
|
|
23
|
+
const isPnp = await this.yarnSetupInfo.value.then(info => !!info.isPnP);
|
|
24
|
+
if (isPnp) {
|
|
25
|
+
builder_util_1.log.warn(null, "Yarn PnP extraction not supported directly due to virtual file paths (<package_name>.zip/<file_path>), falling back to NPM node module collector");
|
|
26
|
+
}
|
|
27
|
+
return super.getDependenciesTree(packageManager_1.PM.NPM);
|
|
28
|
+
}
|
|
29
|
+
isProdDependency(packageName, tree) {
|
|
30
|
+
var _a, _b;
|
|
31
|
+
return ((_a = tree.dependencies) === null || _a === void 0 ? void 0 : _a[packageName]) != null || ((_b = tree.optionalDependencies) === null || _b === void 0 ? void 0 : _b[packageName]) != null;
|
|
32
|
+
}
|
|
33
|
+
async detectYarnSetup(rootDir) {
|
|
34
|
+
var _a, _b, _c, _d;
|
|
35
|
+
let yarnVersion = null;
|
|
36
|
+
let nodeLinker = null;
|
|
37
|
+
let nmHoistingLimits = null;
|
|
38
|
+
const output = await this.asyncExec("yarn", ["config", "--json"], rootDir);
|
|
39
|
+
if (!output.stdout) {
|
|
40
|
+
builder_util_1.log.debug(null, "Yarn config returned no output, assuming default Yarn v1 behavior (hoisted, non-PnP)");
|
|
41
|
+
return {
|
|
42
|
+
yarnVersion,
|
|
43
|
+
nodeLinker,
|
|
44
|
+
nmHoistingLimits,
|
|
45
|
+
isPnP: false,
|
|
46
|
+
isHoisted: true,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
// Yarn 1: multi-line stream with type:"inspect" (not used in this file anyways)
|
|
50
|
+
// Yarn 2–3: multi-line stream with type:"inspect"
|
|
51
|
+
// Yarn 4: single JSON object, no "type"
|
|
52
|
+
const lines = output.stdout
|
|
53
|
+
.split("\n")
|
|
54
|
+
.map(l => l.trim())
|
|
55
|
+
.filter(Boolean);
|
|
56
|
+
let data = null;
|
|
57
|
+
for (const line of lines) {
|
|
58
|
+
try {
|
|
59
|
+
const parsed = JSON.parse(line);
|
|
60
|
+
// Yarn 4: direct object
|
|
61
|
+
if (parsed.rc || parsed.manifest) {
|
|
62
|
+
data = parsed;
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
// Yarn 1–3: inspect event
|
|
66
|
+
if (parsed.type === "inspect") {
|
|
67
|
+
data = parsed.data;
|
|
68
|
+
break;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
// ignore non-JSON lines
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
if (data) {
|
|
76
|
+
const rc = data.rc || data; // Yarn 4: rc in root; Yarn 2–3: rc inside data
|
|
77
|
+
yarnVersion = (_b = (_a = data.manifest) === null || _a === void 0 ? void 0 : _a.version) !== null && _b !== void 0 ? _b : null;
|
|
78
|
+
nodeLinker = (_c = rc.nodeLinker) !== null && _c !== void 0 ? _c : null;
|
|
79
|
+
nmHoistingLimits = (_d = rc.nmHoistingLimits) !== null && _d !== void 0 ? _d : null;
|
|
80
|
+
}
|
|
81
|
+
const isPnP = nodeLinker === "pnp";
|
|
82
|
+
const isHoisted = !isPnP && (nmHoistingLimits === "dependencies" || nmHoistingLimits === "workspaces");
|
|
83
|
+
return {
|
|
84
|
+
yarnVersion,
|
|
85
|
+
nodeLinker,
|
|
86
|
+
nmHoistingLimits,
|
|
87
|
+
isPnP,
|
|
88
|
+
isHoisted,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
exports.YarnBerryNodeModulesCollector = YarnBerryNodeModulesCollector;
|
|
93
|
+
//# sourceMappingURL=yarnBerryNodeModulesCollector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yarnBerryNodeModulesCollector.js","sourceRoot":"","sources":["../../src/node-module-collector/yarnBerryNodeModulesCollector.ts"],"names":[],"mappings":"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","sourcesContent":["import { log } from \"builder-util\"\nimport { Lazy } from \"lazy-val\"\nimport { NpmNodeModulesCollector } from \"./npmNodeModulesCollector\"\nimport { PM } from \"./packageManager\"\nimport { NpmDependency } from \"./types\"\n\ntype YarnSetupInfo = {\n yarnVersion: string | null\n nodeLinker: \"pnp\" | \"node-modules\" | null\n nmHoistingLimits: \"workspaces\" | \"dependencies\" | \"none\" | null\n isPnP: boolean\n isHoisted: boolean\n}\n\n// Only Yarn v1 uses CLI. We should use pnp.cjs for PnP, but we can't access the files due to virtual file paths within zipped modules.\n// We fallback to npm node module collection (since Yarn Berry could have npm-like structure OR pnpm-like structure, depending on `nmHoistingLimits` configuration).\n// In the latter case, we still can't assume `pnpm` is installed, so we still try to use npm collection as a best-effort attempt.\n// If those fail, such as if using corepack, we attempt to manually build the tree.\nexport class YarnBerryNodeModulesCollector extends NpmNodeModulesCollector {\n public readonly installOptions = {\n manager: PM.YARN_BERRY,\n lockfile: \"yarn.lock\",\n }\n\n private yarnSetupInfo: Lazy<YarnSetupInfo> = new Lazy<YarnSetupInfo>(async () => this.detectYarnSetup(this.rootDir))\n\n protected isHoisted: Lazy<boolean> = new Lazy<boolean>(async () => this.yarnSetupInfo.value.then(info => info.isHoisted))\n\n protected async getDependenciesTree(_pm: PM): Promise<NpmDependency> {\n const isPnp = await this.yarnSetupInfo.value.then(info => !!info.isPnP)\n if (isPnp) {\n log.warn(null, \"Yarn PnP extraction not supported directly due to virtual file paths (<package_name>.zip/<file_path>), falling back to NPM node module collector\")\n }\n\n return super.getDependenciesTree(PM.NPM)\n }\n\n protected isProdDependency(packageName: string, tree: NpmDependency): boolean {\n return tree.dependencies?.[packageName] != null || tree.optionalDependencies?.[packageName] != null\n }\n\n private async detectYarnSetup(rootDir: string): Promise<YarnSetupInfo> {\n let yarnVersion: YarnSetupInfo[\"yarnVersion\"] = null\n let nodeLinker: YarnSetupInfo[\"nodeLinker\"] = null\n let nmHoistingLimits: YarnSetupInfo[\"nmHoistingLimits\"] = null\n\n const output = await this.asyncExec(\"yarn\", [\"config\", \"--json\"], rootDir)\n\n if (!output.stdout) {\n log.debug(null, \"Yarn config returned no output, assuming default Yarn v1 behavior (hoisted, non-PnP)\")\n return {\n yarnVersion,\n nodeLinker,\n nmHoistingLimits,\n isPnP: false,\n isHoisted: true,\n }\n }\n\n // Yarn 1: multi-line stream with type:\"inspect\" (not used in this file anyways)\n // Yarn 2–3: multi-line stream with type:\"inspect\"\n // Yarn 4: single JSON object, no \"type\"\n const lines = output.stdout\n .split(\"\\n\")\n .map(l => l.trim())\n .filter(Boolean)\n\n let data: any = null\n\n for (const line of lines) {\n try {\n const parsed = JSON.parse(line)\n\n // Yarn 4: direct object\n if (parsed.rc || parsed.manifest) {\n data = parsed\n break\n }\n\n // Yarn 1–3: inspect event\n if (parsed.type === \"inspect\") {\n data = parsed.data\n break\n }\n } catch {\n // ignore non-JSON lines\n }\n }\n\n if (data) {\n const rc = data.rc || data // Yarn 4: rc in root; Yarn 2–3: rc inside data\n yarnVersion = data.manifest?.version ?? null\n nodeLinker = rc.nodeLinker ?? null\n nmHoistingLimits = rc.nmHoistingLimits ?? null\n }\n\n const isPnP = nodeLinker === \"pnp\"\n const isHoisted = !isPnP && (nmHoistingLimits === \"dependencies\" || nmHoistingLimits === \"workspaces\")\n\n return {\n yarnVersion,\n nodeLinker,\n nmHoistingLimits,\n isPnP,\n isHoisted,\n }\n }\n}\n"]}
|
|
@@ -1,8 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Lazy } from "lazy-val";
|
|
2
|
+
import { NodeModulesCollector } from "./nodeModulesCollector";
|
|
2
3
|
import { PM } from "./packageManager";
|
|
3
|
-
|
|
4
|
+
import { PackageJson, YarnDependency } from "./types";
|
|
5
|
+
export declare class YarnNodeModulesCollector extends NodeModulesCollector<YarnDependency, YarnDependency> {
|
|
4
6
|
readonly installOptions: {
|
|
5
7
|
manager: PM;
|
|
6
8
|
lockfile: string;
|
|
7
9
|
};
|
|
10
|
+
protected isHoisted: Lazy<boolean>;
|
|
11
|
+
protected getArgs(): string[];
|
|
12
|
+
protected getTreeFromWorkspaces(tree: YarnDependency): Promise<YarnDependency>;
|
|
13
|
+
protected extractProductionDependencyGraph(tree: YarnDependency, dependencyId: string): Promise<void>;
|
|
14
|
+
protected getDependencyType(pkgName: string, parentPkgJson: PackageJson): "prod" | "dev" | "optional";
|
|
15
|
+
protected parseDependenciesTree(jsonBlob: string): Promise<YarnDependency>;
|
|
16
|
+
private normalizeTree;
|
|
17
|
+
protected collectAllDependencies(tree: YarnDependency, packageToExclude: string): Promise<void>;
|
|
8
18
|
}
|
|
@@ -1,14 +1,243 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.YarnNodeModulesCollector = void 0;
|
|
4
|
-
const
|
|
4
|
+
const builder_util_1 = require("builder-util");
|
|
5
|
+
const lazy_val_1 = require("lazy-val");
|
|
6
|
+
const path = require("path");
|
|
7
|
+
const nodeModulesCollector_1 = require("./nodeModulesCollector");
|
|
5
8
|
const packageManager_1 = require("./packageManager");
|
|
6
|
-
class YarnNodeModulesCollector extends
|
|
9
|
+
class YarnNodeModulesCollector extends nodeModulesCollector_1.NodeModulesCollector {
|
|
7
10
|
constructor() {
|
|
8
11
|
super(...arguments);
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
+
this.installOptions = {
|
|
13
|
+
manager: packageManager_1.PM.YARN,
|
|
14
|
+
lockfile: "yarn.lock",
|
|
15
|
+
};
|
|
16
|
+
this.isHoisted = new lazy_val_1.Lazy(async () => {
|
|
17
|
+
return Promise.resolve(true); // Yarn Classic always hoists
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
getArgs() {
|
|
21
|
+
return ["list", "--production", "--json", "--depth=Infinity", "--no-progress"];
|
|
22
|
+
}
|
|
23
|
+
async getTreeFromWorkspaces(tree) {
|
|
24
|
+
var _a;
|
|
25
|
+
if (!tree.workspaces || !tree.dependencies) {
|
|
26
|
+
return tree;
|
|
27
|
+
}
|
|
28
|
+
const appName = this.packageVersionString(tree);
|
|
29
|
+
if ((_a = tree.dependencies) === null || _a === void 0 ? void 0 : _a[appName]) {
|
|
30
|
+
const { name, path } = tree.dependencies[appName];
|
|
31
|
+
builder_util_1.log.debug({ name, path }, "pruning root app/self package from workspace tree");
|
|
32
|
+
delete tree.dependencies[appName];
|
|
33
|
+
}
|
|
34
|
+
return Promise.resolve(tree);
|
|
35
|
+
}
|
|
36
|
+
async extractProductionDependencyGraph(tree, dependencyId) {
|
|
37
|
+
if (this.productionGraph[dependencyId]) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
const productionDeps = Object.entries(tree.dependencies || {}).map(async ([, dependency]) => {
|
|
41
|
+
const dep = {
|
|
42
|
+
...dependency,
|
|
43
|
+
path: await this.resolvePath(dependency.path),
|
|
44
|
+
};
|
|
45
|
+
const childDependencyId = this.packageVersionString(dep);
|
|
46
|
+
await this.extractProductionDependencyGraph(dep, childDependencyId);
|
|
47
|
+
return childDependencyId;
|
|
48
|
+
});
|
|
49
|
+
this.productionGraph[dependencyId] = { dependencies: await Promise.all(productionDeps) };
|
|
50
|
+
}
|
|
51
|
+
getDependencyType(pkgName, parentPkgJson) {
|
|
52
|
+
var _a, _b, _c;
|
|
53
|
+
if ((_a = parentPkgJson.optionalDependencies) === null || _a === void 0 ? void 0 : _a[pkgName]) {
|
|
54
|
+
return "optional";
|
|
55
|
+
}
|
|
56
|
+
if ((_b = parentPkgJson.devDependencies) === null || _b === void 0 ? void 0 : _b[pkgName]) {
|
|
57
|
+
return "dev";
|
|
58
|
+
}
|
|
59
|
+
if ((_c = parentPkgJson.dependencies) === null || _c === void 0 ? void 0 : _c[pkgName]) {
|
|
60
|
+
return "prod";
|
|
61
|
+
}
|
|
62
|
+
return "prod";
|
|
63
|
+
}
|
|
64
|
+
async parseDependenciesTree(jsonBlob) {
|
|
65
|
+
const lines = jsonBlob
|
|
66
|
+
.split("\n")
|
|
67
|
+
.map(l => l.trim())
|
|
68
|
+
.filter(Boolean)
|
|
69
|
+
.map(l => {
|
|
70
|
+
try {
|
|
71
|
+
return JSON.parse(l);
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
return undefined;
|
|
75
|
+
}
|
|
76
|
+
})
|
|
77
|
+
.filter(Boolean);
|
|
78
|
+
const parsedTree = lines
|
|
79
|
+
.filter(l => l.type === "tree")
|
|
80
|
+
.map(l => l.data.trees)
|
|
81
|
+
.shift();
|
|
82
|
+
if (!parsedTree) {
|
|
83
|
+
throw new Error('Failed to extract Yarn tree: no "type":"tree" line found in console output');
|
|
84
|
+
}
|
|
85
|
+
const normalizedTree = await this.normalizeTree(parsedTree, new Set(), undefined);
|
|
86
|
+
const dependencies = {};
|
|
87
|
+
for (const [name, dep] of Object.entries(normalizedTree)) {
|
|
88
|
+
dependencies[name] = dep;
|
|
89
|
+
}
|
|
90
|
+
const rootPkgJson = await this.appPkgJson.value;
|
|
91
|
+
return Promise.resolve({
|
|
92
|
+
name: (rootPkgJson === null || rootPkgJson === void 0 ? void 0 : rootPkgJson.name) || ".",
|
|
93
|
+
version: (rootPkgJson === null || rootPkgJson === void 0 ? void 0 : rootPkgJson.version) || "unknown",
|
|
94
|
+
path: this.rootDir,
|
|
95
|
+
dependencies,
|
|
96
|
+
workspaces: rootPkgJson === null || rootPkgJson === void 0 ? void 0 : rootPkgJson.workspaces,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
async normalizeTree(tree, seen = new Set(), appName) {
|
|
100
|
+
const normalized = {};
|
|
101
|
+
for (const node of tree) {
|
|
102
|
+
const match = node.name.match(/^(.*)@([^@]+)$/);
|
|
103
|
+
if (!match) {
|
|
104
|
+
builder_util_1.log.debug({ name: node.name }, "invalid node name format");
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
const [, pkgName, version] = match;
|
|
108
|
+
const id = `${pkgName}@${version}`;
|
|
109
|
+
const isShadow = node.shadow && node.color === "dim";
|
|
110
|
+
if (isShadow) {
|
|
111
|
+
builder_util_1.log.debug({ pkgName, version }, "skipping shadow node");
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
if (seen.has(id)) {
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
seen.add(id);
|
|
118
|
+
// Build the expected path - yarn classic hoists to root node_modules
|
|
119
|
+
const pkgPath = path.join(this.rootDir, "node_modules", pkgName);
|
|
120
|
+
const normalizedDep = {
|
|
121
|
+
name: pkgName,
|
|
122
|
+
version,
|
|
123
|
+
path: pkgPath, // Will be resolved later in collectAllDependencies
|
|
124
|
+
dependencies: {},
|
|
125
|
+
optionalDependencies: {},
|
|
126
|
+
};
|
|
127
|
+
builder_util_1.log.debug({ name: pkgName, version }, "+ normalize");
|
|
128
|
+
if (node.children && node.children.length > 0) {
|
|
129
|
+
for (const child of node.children) {
|
|
130
|
+
const childMatch = child.name.match(/^(.*)@([^@]+)$/);
|
|
131
|
+
if (!childMatch) {
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
const [, childName, childVersion] = childMatch;
|
|
135
|
+
if (child.shadow && child.color === "dim") {
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
builder_util_1.log.debug({ parent: pkgName, childName, childVersion }, " + normalize child");
|
|
139
|
+
const childDeps = await this.normalizeTree([child], seen, appName);
|
|
140
|
+
for (const [childDepName, childDep] of Object.entries(childDeps)) {
|
|
141
|
+
normalizedDep.dependencies[childDepName] = childDep;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
normalized[pkgName] = normalizedDep;
|
|
146
|
+
}
|
|
147
|
+
return normalized;
|
|
148
|
+
}
|
|
149
|
+
async collectAllDependencies(tree, packageToExclude) {
|
|
150
|
+
const rootPkgJson = await this.appPkgJson.value;
|
|
151
|
+
const failedPackages = new Set();
|
|
152
|
+
builder_util_1.log.debug({ packageToExclude, hasWorkspaces: !!tree.workspaces }, "collectAllDependencies starting");
|
|
153
|
+
const collect = async (deps = {}, isOptionalDependency, parentIsOptional = false) => {
|
|
154
|
+
var _a, _b, _c, _d;
|
|
155
|
+
for (const [, value] of Object.entries(deps)) {
|
|
156
|
+
// Skip the app package if provided
|
|
157
|
+
if (packageToExclude && value.name === packageToExclude) {
|
|
158
|
+
builder_util_1.log.debug({ name: value.name }, "skipping app package in collectAllDependencies");
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
const isRootOptional = !!((_a = rootPkgJson.optionalDependencies) === null || _a === void 0 ? void 0 : _a[value.name]);
|
|
162
|
+
const isDirectRootDep = ((_b = rootPkgJson.dependencies) === null || _b === void 0 ? void 0 : _b[value.name]) || ((_c = rootPkgJson.optionalDependencies) === null || _c === void 0 ? void 0 : _c[value.name]) || ((_d = rootPkgJson.devDependencies) === null || _d === void 0 ? void 0 : _d[value.name]);
|
|
163
|
+
const treatAsOptional = isOptionalDependency || parentIsOptional || isRootOptional;
|
|
164
|
+
let p;
|
|
165
|
+
try {
|
|
166
|
+
p = await this.resolvePath(value.path);
|
|
167
|
+
}
|
|
168
|
+
catch (e) {
|
|
169
|
+
if (treatAsOptional) {
|
|
170
|
+
builder_util_1.log.debug({ pkg: this.cacheKey(value), name: value.name }, "failed to resolve optional dependency, skipping");
|
|
171
|
+
failedPackages.add(value.name);
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
if (!isDirectRootDep) {
|
|
175
|
+
builder_util_1.log.debug({ pkg: this.cacheKey(value), name: value.name }, "failed to resolve transitive dependency, treating as optional");
|
|
176
|
+
failedPackages.add(value.name);
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
179
|
+
builder_util_1.log.error({ pkg: this.cacheKey(value) }, "failed to resolve module directory");
|
|
180
|
+
throw e;
|
|
181
|
+
}
|
|
182
|
+
if (!p) {
|
|
183
|
+
builder_util_1.log.debug({ pkg: this.cacheKey(value), name: value.name }, "optional dependency not found, skipping");
|
|
184
|
+
failedPackages.add(value.name);
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
187
|
+
let resolvedVersion = value.version;
|
|
188
|
+
const versionMatch = p.match(/[/\\]node_modules[/\\][^@]+@([^/\\]+)[/\\]/);
|
|
189
|
+
if (versionMatch) {
|
|
190
|
+
resolvedVersion = versionMatch[1];
|
|
191
|
+
if (resolvedVersion !== value.version) {
|
|
192
|
+
builder_util_1.log.debug({ name: value.name, declared: value.version, resolved: resolvedVersion }, "resolved actual version from path");
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
const m = {
|
|
196
|
+
...value,
|
|
197
|
+
version: resolvedVersion,
|
|
198
|
+
path: p,
|
|
199
|
+
};
|
|
200
|
+
const moduleKey = this.packageVersionString(m);
|
|
201
|
+
if (this.allDependencies.has(moduleKey)) {
|
|
202
|
+
continue;
|
|
203
|
+
}
|
|
204
|
+
this.allDependencies.set(moduleKey, m);
|
|
205
|
+
const childIsOptional = treatAsOptional;
|
|
206
|
+
await collect(m.dependencies, false, childIsOptional);
|
|
207
|
+
await collect(m.optionalDependencies, true, true);
|
|
208
|
+
}
|
|
209
|
+
};
|
|
210
|
+
await collect(tree.dependencies, false, false);
|
|
211
|
+
await collect(tree.optionalDependencies, true, true);
|
|
212
|
+
// Final cleanup: remove the app package from allDependencies
|
|
213
|
+
if (packageToExclude) {
|
|
214
|
+
for (const [key, dep] of this.allDependencies.entries()) {
|
|
215
|
+
if (dep.name === packageToExclude) {
|
|
216
|
+
builder_util_1.log.debug({ key, name: dep.name }, "removing app package from allDependencies");
|
|
217
|
+
this.allDependencies.delete(key);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
if (failedPackages.size > 0) {
|
|
222
|
+
const cleanDependencies = (deps = {}) => {
|
|
223
|
+
for (const [key, dep] of Object.entries(deps)) {
|
|
224
|
+
if (failedPackages.has(dep.name)) {
|
|
225
|
+
builder_util_1.log.debug({ name: dep.name }, "removing failed package from tree");
|
|
226
|
+
delete deps[key];
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
if (dep.dependencies) {
|
|
230
|
+
cleanDependencies(dep.dependencies);
|
|
231
|
+
}
|
|
232
|
+
if (dep.optionalDependencies) {
|
|
233
|
+
cleanDependencies(dep.optionalDependencies);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
};
|
|
238
|
+
cleanDependencies(tree.dependencies);
|
|
239
|
+
cleanDependencies(tree.optionalDependencies);
|
|
240
|
+
}
|
|
12
241
|
}
|
|
13
242
|
}
|
|
14
243
|
exports.YarnNodeModulesCollector = YarnNodeModulesCollector;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"yarnNodeModulesCollector.js","sourceRoot":"","sources":["../../src/node-module-collector/yarnNodeModulesCollector.ts"],"names":[],"mappings":";;;AAAA,uEAAmE;AACnE,qDAAqC;AAErC,MAAa,wBAAyB,SAAQ,iDAAuB;IAArE;;QACE,6FAA6F;QAC7F,iHAAiH;QACjG,mBAAc,GAAG,EAAE,OAAO,EAAE,mBAAE,CAAC,GAAG,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAA;IAC7E,CAAC;CAAA;AAJD,4DAIC","sourcesContent":["import { NpmNodeModulesCollector } from \"./npmNodeModulesCollector\"\nimport { PM } from \"./packageManager\"\n\nexport class YarnNodeModulesCollector extends NpmNodeModulesCollector {\n // note: do not override instance-var `pmCommand`. We explicitly use npm for the json payload\n // yarn list cannot get the detailed dependencies path info, But we can use npm to get all dependencies path info\n public readonly installOptions = { manager: PM.NPM, lockfile: \"yarn.lock\" }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"yarnNodeModulesCollector.js","sourceRoot":"","sources":["../../src/node-module-collector/yarnNodeModulesCollector.ts"],"names":[],"mappings":"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","sourcesContent":["import { log } from \"builder-util\"\nimport { Lazy } from \"lazy-val\"\nimport * as path from \"path\"\nimport { NodeModulesCollector } from \"./nodeModulesCollector\"\nimport { PM } from \"./packageManager\"\nimport { PackageJson, YarnDependency } from \"./types\"\n\ntype YarnListJsonLine =\n | {\n type: \"tree\"\n data: {\n type: \"list\"\n trees: YarnListTree[]\n }\n }\n | {\n type: \"info\" | \"warning\" | \"error\"\n data: string\n }\n\ninterface YarnListTree {\n name: string // e.g. \"lodash@4.17.21\"\n children: YarnListTree[]\n shadow?: boolean\n color?: string\n hint?: any\n depth?: number\n}\n\nexport class YarnNodeModulesCollector extends NodeModulesCollector<YarnDependency, YarnDependency> {\n public readonly installOptions = {\n manager: PM.YARN,\n lockfile: \"yarn.lock\",\n }\n\n protected isHoisted: Lazy<boolean> = new Lazy<boolean>(async () => {\n return Promise.resolve(true) // Yarn Classic always hoists\n })\n\n protected getArgs(): string[] {\n return [\"list\", \"--production\", \"--json\", \"--depth=Infinity\", \"--no-progress\"]\n }\n\n protected async getTreeFromWorkspaces(tree: YarnDependency): Promise<YarnDependency> {\n if (!tree.workspaces || !tree.dependencies) {\n return tree\n }\n\n const appName = this.packageVersionString(tree)\n\n if (tree.dependencies?.[appName]) {\n const { name, path } = tree.dependencies[appName]\n log.debug({ name, path }, \"pruning root app/self package from workspace tree\")\n delete tree.dependencies[appName]\n }\n return Promise.resolve(tree)\n }\n\n protected async extractProductionDependencyGraph(tree: YarnDependency, dependencyId: string): Promise<void> {\n if (this.productionGraph[dependencyId]) {\n return\n }\n\n const productionDeps = Object.entries(tree.dependencies || {}).map(async ([, dependency]) => {\n const dep = {\n ...dependency,\n path: await this.resolvePath(dependency.path),\n }\n\n const childDependencyId = this.packageVersionString(dep)\n await this.extractProductionDependencyGraph(dep, childDependencyId)\n return childDependencyId\n })\n\n this.productionGraph[dependencyId] = { dependencies: await Promise.all(productionDeps) }\n }\n\n protected getDependencyType(pkgName: string, parentPkgJson: PackageJson): \"prod\" | \"dev\" | \"optional\" {\n if (parentPkgJson.optionalDependencies?.[pkgName]) {\n return \"optional\"\n }\n\n if (parentPkgJson.devDependencies?.[pkgName]) {\n return \"dev\"\n }\n\n if (parentPkgJson.dependencies?.[pkgName]) {\n return \"prod\"\n }\n\n return \"prod\"\n }\n\n protected async parseDependenciesTree(jsonBlob: string): Promise<YarnDependency> {\n const lines = jsonBlob\n .split(\"\\n\")\n .map(l => l.trim())\n .filter(Boolean)\n .map(l => {\n try {\n return JSON.parse(l)\n } catch {\n return undefined\n }\n })\n .filter(Boolean) as YarnListJsonLine[]\n\n const parsedTree: YarnListTree[] | undefined = lines\n .filter(l => l.type === \"tree\")\n .map(l => (l.data as any).trees)\n .shift()\n\n if (!parsedTree) {\n throw new Error('Failed to extract Yarn tree: no \"type\":\"tree\" line found in console output')\n }\n\n const normalizedTree = await this.normalizeTree(parsedTree, new Set<string>(), undefined)\n\n const dependencies: Record<string, YarnDependency> = {}\n for (const [name, dep] of Object.entries(normalizedTree)) {\n dependencies[name] = dep\n }\n\n const rootPkgJson = await this.appPkgJson.value\n return Promise.resolve({\n name: rootPkgJson?.name || \".\",\n version: rootPkgJson?.version || \"unknown\",\n path: this.rootDir,\n dependencies,\n workspaces: rootPkgJson?.workspaces,\n })\n }\n\n private async normalizeTree(tree: YarnListTree[], seen = new Set<string>(), appName?: string): Promise<Record<string, YarnDependency>> {\n const normalized: Record<string, YarnDependency> = {}\n\n for (const node of tree) {\n const match = node.name.match(/^(.*)@([^@]+)$/)\n if (!match) {\n log.debug({ name: node.name }, \"invalid node name format\")\n continue\n }\n\n const [, pkgName, version] = match\n const id = `${pkgName}@${version}`\n\n const isShadow = node.shadow && node.color === \"dim\"\n if (isShadow) {\n log.debug({ pkgName, version }, \"skipping shadow node\")\n continue\n }\n\n if (seen.has(id)) {\n continue\n }\n\n seen.add(id)\n\n // Build the expected path - yarn classic hoists to root node_modules\n const pkgPath = path.join(this.rootDir, \"node_modules\", pkgName)\n\n const normalizedDep: YarnDependency = {\n name: pkgName,\n version,\n path: pkgPath, // Will be resolved later in collectAllDependencies\n dependencies: {},\n optionalDependencies: {},\n }\n\n log.debug({ name: pkgName, version }, \"+ normalize\")\n\n if (node.children && node.children.length > 0) {\n for (const child of node.children) {\n const childMatch = child.name.match(/^(.*)@([^@]+)$/)\n if (!childMatch) {\n continue\n }\n\n const [, childName, childVersion] = childMatch\n if (child.shadow && child.color === \"dim\") {\n continue\n }\n\n log.debug({ parent: pkgName, childName, childVersion }, \" + normalize child\")\n const childDeps = await this.normalizeTree([child], seen, appName)\n\n for (const [childDepName, childDep] of Object.entries(childDeps)) {\n normalizedDep.dependencies![childDepName] = childDep\n }\n }\n }\n\n normalized[pkgName] = normalizedDep\n }\n\n return normalized\n }\n\n protected async collectAllDependencies(tree: YarnDependency, packageToExclude: string) {\n const rootPkgJson = await this.appPkgJson.value\n const failedPackages = new Set<string>()\n\n log.debug({ packageToExclude, hasWorkspaces: !!tree.workspaces }, \"collectAllDependencies starting\")\n\n const collect = async (\n deps: YarnDependency[\"dependencies\"] | YarnDependency[\"optionalDependencies\"] = {},\n isOptionalDependency: boolean,\n parentIsOptional: boolean = false\n ) => {\n for (const [, value] of Object.entries(deps)) {\n // Skip the app package if provided\n if (packageToExclude && value.name === packageToExclude) {\n log.debug({ name: value.name }, \"skipping app package in collectAllDependencies\")\n continue\n }\n\n const isRootOptional = !!rootPkgJson.optionalDependencies?.[value.name]\n const isDirectRootDep = rootPkgJson.dependencies?.[value.name] || rootPkgJson.optionalDependencies?.[value.name] || rootPkgJson.devDependencies?.[value.name]\n const treatAsOptional = isOptionalDependency || parentIsOptional || isRootOptional\n\n let p: string | null\n\n try {\n p = await this.resolvePath(value.path)\n } catch (e) {\n if (treatAsOptional) {\n log.debug({ pkg: this.cacheKey(value), name: value.name }, \"failed to resolve optional dependency, skipping\")\n failedPackages.add(value.name)\n continue\n }\n\n if (!isDirectRootDep) {\n log.debug({ pkg: this.cacheKey(value), name: value.name }, \"failed to resolve transitive dependency, treating as optional\")\n failedPackages.add(value.name)\n continue\n }\n\n log.error({ pkg: this.cacheKey(value) }, \"failed to resolve module directory\")\n throw e\n }\n\n if (!p) {\n log.debug({ pkg: this.cacheKey(value), name: value.name }, \"optional dependency not found, skipping\")\n failedPackages.add(value.name)\n continue\n }\n\n let resolvedVersion = value.version\n const versionMatch = p.match(/[/\\\\]node_modules[/\\\\][^@]+@([^/\\\\]+)[/\\\\]/)\n if (versionMatch) {\n resolvedVersion = versionMatch[1]\n if (resolvedVersion !== value.version) {\n log.debug({ name: value.name, declared: value.version, resolved: resolvedVersion }, \"resolved actual version from path\")\n }\n }\n\n const m: YarnDependency = {\n ...value,\n version: resolvedVersion,\n path: p,\n }\n\n const moduleKey = this.packageVersionString(m)\n if (this.allDependencies.has(moduleKey)) {\n continue\n }\n\n this.allDependencies.set(moduleKey, m)\n\n const childIsOptional = treatAsOptional\n await collect(m.dependencies, false, childIsOptional)\n await collect(m.optionalDependencies, true, true)\n }\n }\n\n await collect(tree.dependencies, false, false)\n await collect(tree.optionalDependencies, true, true)\n\n // Final cleanup: remove the app package from allDependencies\n if (packageToExclude) {\n for (const [key, dep] of this.allDependencies.entries()) {\n if (dep.name === packageToExclude) {\n log.debug({ key, name: dep.name }, \"removing app package from allDependencies\")\n this.allDependencies.delete(key)\n }\n }\n }\n\n if (failedPackages.size > 0) {\n const cleanDependencies = (deps: Record<string, YarnDependency> = {}) => {\n for (const [key, dep] of Object.entries(deps)) {\n if (failedPackages.has(dep.name)) {\n log.debug({ name: dep.name }, \"removing failed package from tree\")\n delete deps[key]\n } else {\n if (dep.dependencies) {\n cleanDependencies(dep.dependencies)\n }\n if (dep.optionalDependencies) {\n cleanDependencies(dep.optionalDependencies)\n }\n }\n }\n }\n\n cleanDependencies(tree.dependencies)\n cleanDependencies(tree.optionalDependencies)\n }\n }\n}\n"]}
|
|
@@ -52,7 +52,8 @@ export interface WindowsConfiguration extends PlatformSpecificBuildOptions {
|
|
|
52
52
|
*/
|
|
53
53
|
readonly signAndEditExecutable?: boolean;
|
|
54
54
|
/**
|
|
55
|
-
* Explicit file extensions to also sign. Advanced option.
|
|
55
|
+
* Explicit file name/extensions (`str.endsWith`) to also sign. Advanced option.
|
|
56
|
+
* Supports negative patterns, e.g. example that excludes `.appx` files: `["somefilename", ".dll", "!.appx"]`.
|
|
56
57
|
* @see https://github.com/electron-userland/electron-builder/issues/7329
|
|
57
58
|
* @default null
|
|
58
59
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"winOptions.js","sourceRoot":"","sources":["../../src/options/winOptions.ts"],"names":[],"mappings":"","sourcesContent":["import { Nullish } from \"builder-util-runtime\"\nimport { CustomWindowsSign } from \"../codeSign/windowsSignToolManager\"\nimport { PlatformSpecificBuildOptions, TargetConfigType } from \"../index\"\n\nexport interface WindowsConfiguration extends PlatformSpecificBuildOptions {\n /**\n * The target package type: list of `nsis`, `nsis-web` (Web installer), `portable` ([portable]./nsis.md#portable) app without installation), `appx`, `msi`, `msi-wrapped`, `squirrel`, `7z`, `zip`, `tar.xz`, `tar.lz`, `tar.gz`, `tar.bz2`, `dir`.\n * AppX package can be built only on Windows 10.\n *\n * To use Squirrel.Windows please install `electron-builder-squirrel-windows` dependency.\n *\n * @default nsis\n */\n readonly target?: TargetConfigType\n\n /**\n * The path to application icon.\n * @default build/icon.ico\n */\n readonly icon?: string | null\n\n /**\n * The trademarks and registered trademarks.\n */\n readonly legalTrademarks?: string | null\n\n /**\n * Options for usage with signtool.exe\n * Cannot be used in conjunction with `azureSignOptions`, signing will default to Azure Trusted Signing\n */\n readonly signtoolOptions?: WindowsSigntoolConfiguration | null\n\n /**\n * Options for usage of Azure Trusted Signing service\n * Cannot be used in conjunction with `signtoolOptions`, signing will default to Azure Trusted Signing\n */\n readonly azureSignOptions?: WindowsAzureSigningConfiguration | null\n\n /**\n * Whether to verify the signature of an available update before installation.\n * The [publisher name](#publisherName) will be used for the signature verification.\n *\n * @default true\n */\n readonly verifyUpdateCodeSignature?: boolean\n\n /**\n * The [security level](https://msdn.microsoft.com/en-us/library/6ad1fshk.aspx#Anchor_9) at which the application requests to be executed.\n * Cannot be specified per target, allowed only in the `win`.\n * @default asInvoker\n */\n readonly requestedExecutionLevel?: RequestedExecutionLevel | null\n\n /**\n * Whether to sign and add metadata to executable.\n * Metadata includes information about the app name/description/version, publisher, copyright, etc.\n * This property also is responsible for adding the app icon and setting execution level.\n * (Advanced option leveraging `rcedit`)\n * @default true\n */\n readonly signAndEditExecutable?: boolean\n\n /**\n * Explicit file extensions to also sign. Advanced option.\n * @see https://github.com/electron-userland/electron-builder/issues/7329\n * @default null\n */\n readonly signExts?: string[] | null\n}\n\nexport type RequestedExecutionLevel = \"asInvoker\" | \"highestAvailable\" | \"requireAdministrator\"\n\nexport interface WindowsSigntoolConfiguration {\n /**\n * The custom function (or path to file or module id) to sign Windows executables\n */\n readonly sign?: CustomWindowsSign | string | null\n\n /**\n * Array of signing algorithms used. For AppX `sha256` is always used.\n * @default ['sha1', 'sha256']\n */\n readonly signingHashAlgorithms?: Array<\"sha1\" | \"sha256\"> | null\n\n /**\n * The path to the *.pfx certificate you want to sign with. Please use it only if you cannot use env variable `CSC_LINK` (`WIN_CSC_LINK`) for some reason.\n * Please see [Code Signing](./code-signing.md).\n */\n readonly certificateFile?: string | null\n\n /**\n * The password to the certificate provided in `certificateFile`. Please use it only if you cannot use env variable `CSC_KEY_PASSWORD` (`WIN_CSC_KEY_PASSWORD`) for some reason.\n * Please see [Code Signing](./code-signing.md).\n */\n readonly certificatePassword?: string | null\n\n /**\n * The name of the subject of the signing certificate, which is often labeled with the field name `issued to`. Required only for EV Code Signing and works only on Windows (or on macOS if [Parallels Desktop](https://www.parallels.com/products/desktop/) Windows 10 virtual machines exits).\n */\n readonly certificateSubjectName?: string | null\n\n /**\n * The SHA1 hash of the signing certificate. The SHA1 hash is commonly specified when multiple certificates satisfy the criteria specified by the remaining switches. Works only on Windows (or on macOS if [Parallels Desktop](https://www.parallels.com/products/desktop/) Windows 10 virtual machines exits).\n */\n readonly certificateSha1?: string | null\n\n /**\n * The path to an additional certificate file you want to add to the signature block.\n */\n readonly additionalCertificateFile?: string | null\n\n /**\n * The URL of the RFC 3161 time stamp server.\n * @default http://timestamp.digicert.com\n */\n readonly rfc3161TimeStampServer?: string | null\n\n /**\n * The URL of the time stamp server.\n * @default http://timestamp.digicert.com\n */\n readonly timeStampServer?: string | null\n\n /**\n * [The publisher name](https://github.com/electron-userland/electron-builder/issues/1187#issuecomment-278972073), exactly as in your code signed certificate. Several names can be provided.\n * Defaults to common name from your code signing certificate.\n */\n readonly publisherName?: string | Array<string> | null\n}\n\n// https://learn.microsoft.com/en-us/azure/trusted-signing/how-to-signing-integrations\nexport interface WindowsAzureSigningConfiguration {\n /**\n * [The publisher name](https://github.com/electron-userland/electron-builder/issues/1187#issuecomment-278972073), exactly as in your code signed certificate. Several names can be provided.\n */\n readonly publisherName: string\n /**\n * The Trusted Signing Account endpoint. The URI value must have a URI that aligns to the\n * region your Trusted Signing Account and Certificate Profile you are specifying were created\n * in during the setup of these resources.\n *\n * Translates to field: Endpoint\n *\n * Requires one of environment variable configurations for authenticating to Microsoft Entra ID per [Microsoft's documentation](https://learn.microsoft.com/en-us/dotnet/api/azure.identity.environmentcredential?view=azure-dotnet#definition)\n */\n readonly endpoint: string\n /**\n * The Certificate Profile name. Translates to field: CertificateProfileName\n */\n readonly certificateProfileName: string\n /**\n * The Code Signing Signing Account name. Translates to field: CodeSigningAccountName\n */\n readonly codeSigningAccountName: string\n /**\n * The File Digest for signing each file. Translates to field: FileDigest\n * @default SHA256\n */\n readonly fileDigest?: string\n /**\n * The Timestamp rfc3161 server. Translates to field: TimestampRfc3161\n * @default http://timestamp.acs.microsoft.com\n */\n readonly timestampRfc3161?: string\n /**\n * The Timestamp Digest. Translates to field: TimestampDigest\n * @default SHA256\n */\n readonly timestampDigest?: string\n /**\n * Allow other CLI parameters (verbatim case-sensitive) to `Invoke-TrustedSigning`\n * Note: Key-Value pairs with `undefined`/`null` value are filtered out of the command.\n */\n [k: string]: string | Nullish\n}\n"]}
|
|
1
|
+
{"version":3,"file":"winOptions.js","sourceRoot":"","sources":["../../src/options/winOptions.ts"],"names":[],"mappings":"","sourcesContent":["import { Nullish } from \"builder-util-runtime\"\nimport { CustomWindowsSign } from \"../codeSign/windowsSignToolManager\"\nimport { PlatformSpecificBuildOptions, TargetConfigType } from \"../index\"\n\nexport interface WindowsConfiguration extends PlatformSpecificBuildOptions {\n /**\n * The target package type: list of `nsis`, `nsis-web` (Web installer), `portable` ([portable]./nsis.md#portable) app without installation), `appx`, `msi`, `msi-wrapped`, `squirrel`, `7z`, `zip`, `tar.xz`, `tar.lz`, `tar.gz`, `tar.bz2`, `dir`.\n * AppX package can be built only on Windows 10.\n *\n * To use Squirrel.Windows please install `electron-builder-squirrel-windows` dependency.\n *\n * @default nsis\n */\n readonly target?: TargetConfigType\n\n /**\n * The path to application icon.\n * @default build/icon.ico\n */\n readonly icon?: string | null\n\n /**\n * The trademarks and registered trademarks.\n */\n readonly legalTrademarks?: string | null\n\n /**\n * Options for usage with signtool.exe\n * Cannot be used in conjunction with `azureSignOptions`, signing will default to Azure Trusted Signing\n */\n readonly signtoolOptions?: WindowsSigntoolConfiguration | null\n\n /**\n * Options for usage of Azure Trusted Signing service\n * Cannot be used in conjunction with `signtoolOptions`, signing will default to Azure Trusted Signing\n */\n readonly azureSignOptions?: WindowsAzureSigningConfiguration | null\n\n /**\n * Whether to verify the signature of an available update before installation.\n * The [publisher name](#publisherName) will be used for the signature verification.\n *\n * @default true\n */\n readonly verifyUpdateCodeSignature?: boolean\n\n /**\n * The [security level](https://msdn.microsoft.com/en-us/library/6ad1fshk.aspx#Anchor_9) at which the application requests to be executed.\n * Cannot be specified per target, allowed only in the `win`.\n * @default asInvoker\n */\n readonly requestedExecutionLevel?: RequestedExecutionLevel | null\n\n /**\n * Whether to sign and add metadata to executable.\n * Metadata includes information about the app name/description/version, publisher, copyright, etc.\n * This property also is responsible for adding the app icon and setting execution level.\n * (Advanced option leveraging `rcedit`)\n * @default true\n */\n readonly signAndEditExecutable?: boolean\n\n /**\n * Explicit file name/extensions (`str.endsWith`) to also sign. Advanced option.\n * Supports negative patterns, e.g. example that excludes `.appx` files: `[\"somefilename\", \".dll\", \"!.appx\"]`.\n * @see https://github.com/electron-userland/electron-builder/issues/7329\n * @default null\n */\n readonly signExts?: string[] | null\n}\n\nexport type RequestedExecutionLevel = \"asInvoker\" | \"highestAvailable\" | \"requireAdministrator\"\n\nexport interface WindowsSigntoolConfiguration {\n /**\n * The custom function (or path to file or module id) to sign Windows executables\n */\n readonly sign?: CustomWindowsSign | string | null\n\n /**\n * Array of signing algorithms used. For AppX `sha256` is always used.\n * @default ['sha1', 'sha256']\n */\n readonly signingHashAlgorithms?: Array<\"sha1\" | \"sha256\"> | null\n\n /**\n * The path to the *.pfx certificate you want to sign with. Please use it only if you cannot use env variable `CSC_LINK` (`WIN_CSC_LINK`) for some reason.\n * Please see [Code Signing](./code-signing.md).\n */\n readonly certificateFile?: string | null\n\n /**\n * The password to the certificate provided in `certificateFile`. Please use it only if you cannot use env variable `CSC_KEY_PASSWORD` (`WIN_CSC_KEY_PASSWORD`) for some reason.\n * Please see [Code Signing](./code-signing.md).\n */\n readonly certificatePassword?: string | null\n\n /**\n * The name of the subject of the signing certificate, which is often labeled with the field name `issued to`. Required only for EV Code Signing and works only on Windows (or on macOS if [Parallels Desktop](https://www.parallels.com/products/desktop/) Windows 10 virtual machines exits).\n */\n readonly certificateSubjectName?: string | null\n\n /**\n * The SHA1 hash of the signing certificate. The SHA1 hash is commonly specified when multiple certificates satisfy the criteria specified by the remaining switches. Works only on Windows (or on macOS if [Parallels Desktop](https://www.parallels.com/products/desktop/) Windows 10 virtual machines exits).\n */\n readonly certificateSha1?: string | null\n\n /**\n * The path to an additional certificate file you want to add to the signature block.\n */\n readonly additionalCertificateFile?: string | null\n\n /**\n * The URL of the RFC 3161 time stamp server.\n * @default http://timestamp.digicert.com\n */\n readonly rfc3161TimeStampServer?: string | null\n\n /**\n * The URL of the time stamp server.\n * @default http://timestamp.digicert.com\n */\n readonly timeStampServer?: string | null\n\n /**\n * [The publisher name](https://github.com/electron-userland/electron-builder/issues/1187#issuecomment-278972073), exactly as in your code signed certificate. Several names can be provided.\n * Defaults to common name from your code signing certificate.\n */\n readonly publisherName?: string | Array<string> | null\n}\n\n// https://learn.microsoft.com/en-us/azure/trusted-signing/how-to-signing-integrations\nexport interface WindowsAzureSigningConfiguration {\n /**\n * [The publisher name](https://github.com/electron-userland/electron-builder/issues/1187#issuecomment-278972073), exactly as in your code signed certificate. Several names can be provided.\n */\n readonly publisherName: string\n /**\n * The Trusted Signing Account endpoint. The URI value must have a URI that aligns to the\n * region your Trusted Signing Account and Certificate Profile you are specifying were created\n * in during the setup of these resources.\n *\n * Translates to field: Endpoint\n *\n * Requires one of environment variable configurations for authenticating to Microsoft Entra ID per [Microsoft's documentation](https://learn.microsoft.com/en-us/dotnet/api/azure.identity.environmentcredential?view=azure-dotnet#definition)\n */\n readonly endpoint: string\n /**\n * The Certificate Profile name. Translates to field: CertificateProfileName\n */\n readonly certificateProfileName: string\n /**\n * The Code Signing Signing Account name. Translates to field: CodeSigningAccountName\n */\n readonly codeSigningAccountName: string\n /**\n * The File Digest for signing each file. Translates to field: FileDigest\n * @default SHA256\n */\n readonly fileDigest?: string\n /**\n * The Timestamp rfc3161 server. Translates to field: TimestampRfc3161\n * @default http://timestamp.acs.microsoft.com\n */\n readonly timestampRfc3161?: string\n /**\n * The Timestamp Digest. Translates to field: TimestampDigest\n * @default SHA256\n */\n readonly timestampDigest?: string\n /**\n * Allow other CLI parameters (verbatim case-sensitive) to `Invoke-TrustedSigning`\n * Note: Key-Value pairs with `undefined`/`null` value are filtered out of the command.\n */\n [k: string]: string | Nullish\n}\n"]}
|
package/out/packager.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ import { ArtifactBuildStarted, ArtifactCreated, PackagerOptions } from "./packag
|
|
|
10
10
|
import { PlatformPackager } from "./platformPackager";
|
|
11
11
|
import { NodeModuleDirInfo, NodeModuleInfo } from "./util/packageDependencies";
|
|
12
12
|
import { HandlerType } from "./util/asyncEventEmitter";
|
|
13
|
+
import { PM } from "./node-module-collector";
|
|
13
14
|
type PackagerEvents = {
|
|
14
15
|
artifactBuildStarted: Hook<ArtifactBuildStarted, void>;
|
|
15
16
|
beforePack: Hook<BeforePackContext, void>;
|
|
@@ -26,6 +27,9 @@ export declare class Packager {
|
|
|
26
27
|
readonly projectDir: string;
|
|
27
28
|
private _appDir;
|
|
28
29
|
get appDir(): string;
|
|
30
|
+
private readonly _packageManager;
|
|
31
|
+
getPackageManager(): Promise<PM>;
|
|
32
|
+
getWorkspaceRoot(): Promise<string>;
|
|
29
33
|
private _metadata;
|
|
30
34
|
get metadata(): Metadata;
|
|
31
35
|
private _nodeModulesHandledExternally;
|
|
@@ -46,6 +50,7 @@ export declare class Packager {
|
|
|
46
50
|
readonly debugLogger: DebugLogger;
|
|
47
51
|
get repositoryInfo(): Promise<SourceRepositoryInfo | null>;
|
|
48
52
|
private nodeDependencyInfo;
|
|
53
|
+
private runtimeEnvironmentVariables;
|
|
49
54
|
getNodeDependencyInfo(platform: Platform | null, flatten?: boolean): Lazy<Array<NodeModuleInfo | NodeModuleDirInfo>>;
|
|
50
55
|
stageDirPathCustomizer: (target: Target, packager: PlatformPackager<any>, arch: Arch) => string;
|
|
51
56
|
private _buildResourcesDir;
|
|
@@ -56,7 +61,7 @@ export declare class Packager {
|
|
|
56
61
|
private readonly toDispose;
|
|
57
62
|
disposeOnBuildFinish(disposer: () => Promise<void>): void;
|
|
58
63
|
constructor(options: PackagerOptions, cancellationToken?: CancellationToken);
|
|
59
|
-
addPackagerEventHandlers
|
|
64
|
+
private addPackagerEventHandlers;
|
|
60
65
|
onAfterPack(handler: PackagerEvents["afterPack"]): Packager;
|
|
61
66
|
onArtifactCreated(handler: PackagerEvents["artifactCreated"]): Packager;
|
|
62
67
|
filterPackagerEventListeners(event: keyof PackagerEvents, type: HandlerType | undefined): {
|
package/out/packager.js
CHANGED
|
@@ -25,6 +25,7 @@ const yarn_1 = require("./util/yarn");
|
|
|
25
25
|
const version_1 = require("./version");
|
|
26
26
|
const asyncEventEmitter_1 = require("./util/asyncEventEmitter");
|
|
27
27
|
const tiny_async_pool_1 = require("tiny-async-pool");
|
|
28
|
+
const node_module_collector_1 = require("./node-module-collector");
|
|
28
29
|
async function createFrameworkInfo(configuration, packager) {
|
|
29
30
|
let framework = configuration.framework;
|
|
30
31
|
if (framework != null) {
|
|
@@ -53,6 +54,12 @@ class Packager {
|
|
|
53
54
|
get appDir() {
|
|
54
55
|
return this._appDir;
|
|
55
56
|
}
|
|
57
|
+
async getPackageManager() {
|
|
58
|
+
return (await this._packageManager.value).pm;
|
|
59
|
+
}
|
|
60
|
+
async getWorkspaceRoot() {
|
|
61
|
+
return (await (await this._packageManager.value).workspaceRoot) || this.projectDir;
|
|
62
|
+
}
|
|
56
63
|
get metadata() {
|
|
57
64
|
return this._metadata;
|
|
58
65
|
}
|
|
@@ -122,6 +129,7 @@ class Packager {
|
|
|
122
129
|
this._repositoryInfo = new lazy_val_1.Lazy(() => (0, repositoryInfo_1.getRepositoryInfo)(this.projectDir, this.metadata, this.devMetadata));
|
|
123
130
|
this.debugLogger = new builder_util_1.DebugLogger(builder_util_1.log.isDebugEnabled);
|
|
124
131
|
this.nodeDependencyInfo = new Map();
|
|
132
|
+
this.runtimeEnvironmentVariables = {};
|
|
125
133
|
this.stageDirPathCustomizer = (target, packager, arch) => {
|
|
126
134
|
return path.join(target.outDir, `__${target.name}-${(0, builder_util_1.getArtifactArchName)(arch, target.name)}`);
|
|
127
135
|
};
|
|
@@ -177,6 +185,7 @@ class Packager {
|
|
|
177
185
|
}
|
|
178
186
|
this.projectDir = options.projectDir == null ? process.cwd() : path.resolve(options.projectDir);
|
|
179
187
|
this._appDir = this.projectDir;
|
|
188
|
+
this._packageManager = (0, node_module_collector_1.determinePackageManagerEnv)({ projectDir: this.projectDir, appDir: this.appDir, workspaceRoot: undefined });
|
|
180
189
|
this.options = {
|
|
181
190
|
...options,
|
|
182
191
|
prepackaged: options.prepackaged == null ? null : path.resolve(this.projectDir, options.prepackaged),
|
|
@@ -261,9 +270,7 @@ class Packager {
|
|
|
261
270
|
this._devMetadata = await (0, builder_util_1.orNullIfFileNotExist)((0, packageMetadata_1.readPackageJson)(devPackageFile));
|
|
262
271
|
const devMetadata = this.devMetadata;
|
|
263
272
|
const configuration = await (0, config_1.getConfig)(projectDir, configPath, configFromOptions, new lazy_val_1.Lazy(() => Promise.resolve(devMetadata)));
|
|
264
|
-
|
|
265
|
-
builder_util_1.log.debug({ config: getSafeEffectiveConfig(configuration) }, "effective config");
|
|
266
|
-
}
|
|
273
|
+
builder_util_1.log.debug({ config: getSafeEffectiveConfig(configuration) }, "effective config");
|
|
267
274
|
this._appDir = await (0, config_1.computeDefaultAppDirectory)(projectDir, configuration.directories.app);
|
|
268
275
|
this.isTwoPackageJsonProjectLayoutUsed = this._appDir !== projectDir;
|
|
269
276
|
const appPackageFile = this.isTwoPackageJsonProjectLayoutUsed ? path.join(this.appDir, "package.json") : devPackageFile;
|
|
@@ -457,12 +464,12 @@ class Packager {
|
|
|
457
464
|
builder_util_1.log.info({ reason: "platform is different and buildDependenciesFromSource is set to true" }, "skipped dependencies rebuild");
|
|
458
465
|
}
|
|
459
466
|
else {
|
|
460
|
-
await (0, yarn_1.installOrRebuild)(config, { appDir: this.appDir, projectDir: this.projectDir }, {
|
|
467
|
+
await (0, yarn_1.installOrRebuild)(config, { appDir: this.appDir, projectDir: this.projectDir, workspaceRoot: await this.getWorkspaceRoot() }, {
|
|
461
468
|
frameworkInfo,
|
|
462
469
|
platform: platform.nodeName,
|
|
463
470
|
arch: builder_util_1.Arch[arch],
|
|
464
471
|
productionDeps: this.getNodeDependencyInfo(null, false),
|
|
465
|
-
});
|
|
472
|
+
}, false, this.runtimeEnvironmentVariables);
|
|
466
473
|
}
|
|
467
474
|
}
|
|
468
475
|
}
|