1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | exports.prepareProductBuildArgs = exports.PkgTarget = void 0;
|
4 | const builder_util_1 = require("builder-util");
|
5 | const fs_1 = require("builder-util/out/fs");
|
6 | const appBuilder_1 = require("../util/appBuilder");
|
7 | const license_1 = require("../util/license");
|
8 | const promises_1 = require("fs/promises");
|
9 | const path = require("path");
|
10 | const appInfo_1 = require("../appInfo");
|
11 | const macCodeSign_1 = require("../codeSign/macCodeSign");
|
12 | const core_1 = require("../core");
|
13 | const fs_2 = require("fs");
|
14 | const certType = "Developer ID Installer";
|
15 |
|
16 |
|
17 |
|
18 |
|
19 | class PkgTarget extends core_1.Target {
|
20 | constructor(packager, outDir) {
|
21 | super("pkg");
|
22 | this.packager = packager;
|
23 | this.outDir = outDir;
|
24 | this.options = {
|
25 | allowAnywhere: true,
|
26 | allowCurrentUserHome: true,
|
27 | allowRootDirectory: true,
|
28 | ...this.packager.config.pkg,
|
29 | };
|
30 | }
|
31 | async build(appPath, arch) {
|
32 | const packager = this.packager;
|
33 | const options = this.options;
|
34 | const appInfo = packager.appInfo;
|
35 |
|
36 | const artifactName = packager.expandArtifactNamePattern(options, "pkg", arch);
|
37 | const artifactPath = path.join(this.outDir, artifactName);
|
38 | await packager.info.callArtifactBuildStarted({
|
39 | targetPresentableName: "pkg",
|
40 | file: artifactPath,
|
41 | arch,
|
42 | });
|
43 | const keychainFile = (await packager.codeSigningInfo.value).keychainFile;
|
44 | const appOutDir = this.outDir;
|
45 |
|
46 | const distInfoFile = path.join(appOutDir, "distribution.xml");
|
47 | const innerPackageFile = path.join(appOutDir, `${(0, appInfo_1.filterCFBundleIdentifier)(appInfo.id)}.pkg`);
|
48 | const componentPropertyListFile = path.join(appOutDir, `${(0, appInfo_1.filterCFBundleIdentifier)(appInfo.id)}.plist`);
|
49 | const identity = (await Promise.all([
|
50 | (0, macCodeSign_1.findIdentity)(certType, options.identity || packager.platformSpecificBuildOptions.identity, keychainFile),
|
51 | this.customizeDistributionConfiguration(distInfoFile, appPath),
|
52 | this.buildComponentPackage(appPath, componentPropertyListFile, innerPackageFile),
|
53 | ]))[0];
|
54 | if (identity == null && packager.forceCodeSigning) {
|
55 | throw new Error(`Cannot find valid "${certType}" to sign standalone installer, please see https://electron.build/code-signing`);
|
56 | }
|
57 | const args = prepareProductBuildArgs(identity, keychainFile);
|
58 | args.push("--distribution", distInfoFile);
|
59 | args.push(artifactPath);
|
60 | (0, builder_util_1.use)(options.productbuild, it => args.push(...it));
|
61 | await (0, builder_util_1.exec)("productbuild", args, {
|
62 | cwd: appOutDir,
|
63 | });
|
64 | await Promise.all([(0, promises_1.unlink)(innerPackageFile), (0, promises_1.unlink)(distInfoFile)]);
|
65 | await packager.dispatchArtifactCreated(artifactPath, this, arch, packager.computeSafeArtifactName(artifactName, "pkg", arch));
|
66 | }
|
67 | async customizeDistributionConfiguration(distInfoFile, appPath) {
|
68 | await (0, builder_util_1.exec)("productbuild", ["--synthesize", "--component", appPath, distInfoFile], {
|
69 | cwd: this.outDir,
|
70 | });
|
71 | const options = this.options;
|
72 | let distInfo = await (0, promises_1.readFile)(distInfoFile, "utf-8");
|
73 | if (options.mustClose != null && options.mustClose.length !== 0) {
|
74 | const startContent = ` <pkg-ref id="${this.packager.appInfo.id}">\n <must-close>\n`;
|
75 | const endContent = " </must-close>\n </pkg-ref>\n</installer-gui-script>";
|
76 | let mustCloseContent = "";
|
77 | options.mustClose.forEach(appId => {
|
78 | mustCloseContent += ` <app id="${appId}"/>\n`;
|
79 | });
|
80 | distInfo = distInfo.replace("</installer-gui-script>", `${startContent}${mustCloseContent}${endContent}`);
|
81 | }
|
82 | const insertIndex = distInfo.lastIndexOf("</installer-gui-script>");
|
83 | distInfo =
|
84 | distInfo.substring(0, insertIndex) +
|
85 | ` <domains enable_anywhere="${options.allowAnywhere}" enable_currentUserHome="${options.allowCurrentUserHome}" enable_localSystem="${options.allowRootDirectory}" />\n` +
|
86 | distInfo.substring(insertIndex);
|
87 | if (options.background != null) {
|
88 | const background = await this.packager.getResource(options.background.file);
|
89 | if (background != null) {
|
90 | const alignment = options.background.alignment || "center";
|
91 |
|
92 | const scaling = options.background.scaling || "tofit";
|
93 | distInfo = distInfo.substring(0, insertIndex) + ` <background file="${background}" alignment="${alignment}" scaling="${scaling}"/>\n` + distInfo.substring(insertIndex);
|
94 | distInfo =
|
95 | distInfo.substring(0, insertIndex) + ` <background-darkAqua file="${background}" alignment="${alignment}" scaling="${scaling}"/>\n` + distInfo.substring(insertIndex);
|
96 | }
|
97 | }
|
98 | const welcome = await this.packager.getResource(options.welcome);
|
99 | if (welcome != null) {
|
100 | distInfo = distInfo.substring(0, insertIndex) + ` <welcome file="${welcome}"/>\n` + distInfo.substring(insertIndex);
|
101 | }
|
102 | const license = await (0, license_1.getNotLocalizedLicenseFile)(options.license, this.packager);
|
103 | if (license != null) {
|
104 | distInfo = distInfo.substring(0, insertIndex) + ` <license file="${license}"/>\n` + distInfo.substring(insertIndex);
|
105 | }
|
106 | const conclusion = await this.packager.getResource(options.conclusion);
|
107 | if (conclusion != null) {
|
108 | distInfo = distInfo.substring(0, insertIndex) + ` <conclusion file="${conclusion}"/>\n` + distInfo.substring(insertIndex);
|
109 | }
|
110 | (0, builder_util_1.debug)(distInfo);
|
111 | await (0, promises_1.writeFile)(distInfoFile, distInfo);
|
112 | }
|
113 | async buildComponentPackage(appPath, propertyListOutputFile, packageOutputFile) {
|
114 | var _a;
|
115 | const options = this.options;
|
116 | const rootPath = path.dirname(appPath);
|
117 |
|
118 | await (0, builder_util_1.exec)("pkgbuild", ["--analyze", "--root", rootPath, propertyListOutputFile]);
|
119 |
|
120 | const plistInfo = (await (0, appBuilder_1.executeAppBuilderAsJson)(["decode-plist", "-f", propertyListOutputFile]))[0].filter((it) => it.RootRelativeBundlePath !== "Electron.dSYM");
|
121 | let packageInfo = {};
|
122 | if (plistInfo.length > 0) {
|
123 | packageInfo = plistInfo[0];
|
124 |
|
125 |
|
126 |
|
127 | delete packageInfo.ChildBundles;
|
128 | if (options.isRelocatable != null) {
|
129 | packageInfo.BundleIsRelocatable = options.isRelocatable;
|
130 | }
|
131 | if (options.isVersionChecked != null) {
|
132 | packageInfo.BundleIsVersionChecked = options.isVersionChecked;
|
133 | }
|
134 | if (options.hasStrictIdentifier != null) {
|
135 | packageInfo.BundleHasStrictIdentifier = options.hasStrictIdentifier;
|
136 | }
|
137 | if (options.overwriteAction != null) {
|
138 | packageInfo.BundleOverwriteAction = options.overwriteAction;
|
139 | }
|
140 | }
|
141 |
|
142 | const args = ["--root", rootPath, "--identifier", this.packager.appInfo.id, "--component-plist", propertyListOutputFile];
|
143 | (0, builder_util_1.use)(this.options.installLocation || "/Applications", it => args.push("--install-location", it));
|
144 |
|
145 | const scriptsDir =
|
146 |
|
147 | options.scripts != null
|
148 | ? path.resolve(this.packager.info.buildResourcesDir, options.scripts)
|
149 | :
|
150 | options.scripts !== null
|
151 | ? path.join(this.packager.info.buildResourcesDir, "pkg-scripts")
|
152 | : null;
|
153 | if (scriptsDir && ((_a = (await (0, fs_1.statOrNull)(scriptsDir))) === null || _a === void 0 ? void 0 : _a.isDirectory())) {
|
154 | const dirContents = (0, fs_2.readdirSync)(scriptsDir);
|
155 | dirContents.forEach(name => {
|
156 | if (name.includes("preinstall")) {
|
157 | packageInfo.BundlePreInstallScriptPath = name;
|
158 | }
|
159 | else if (name.includes("postinstall")) {
|
160 | packageInfo.BundlePostInstallScriptPath = name;
|
161 | }
|
162 | });
|
163 | args.push("--scripts", scriptsDir);
|
164 | }
|
165 | if (plistInfo.length > 0) {
|
166 | await (0, appBuilder_1.executeAppBuilderAndWriteJson)(["encode-plist"], { [propertyListOutputFile]: plistInfo });
|
167 | }
|
168 | args.push(packageOutputFile);
|
169 | await (0, builder_util_1.exec)("pkgbuild", args);
|
170 | }
|
171 | }
|
172 | exports.PkgTarget = PkgTarget;
|
173 | function prepareProductBuildArgs(identity, keychain) {
|
174 | const args = [];
|
175 | if (identity != null) {
|
176 | args.push("--sign", identity.hash);
|
177 | if (keychain != null) {
|
178 | args.push("--keychain", keychain);
|
179 | }
|
180 | }
|
181 | return args;
|
182 | }
|
183 | exports.prepareProductBuildArgs = prepareProductBuildArgs;
|
184 |
|
\ | No newline at end of file |