1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | exports.createMacApp = void 0;
|
4 | const bluebird_lst_1 = require("bluebird-lst");
|
5 | const builder_util_1 = require("builder-util");
|
6 | const fs_1 = require("builder-util/out/fs");
|
7 | const promises_1 = require("fs/promises");
|
8 | const path = require("path");
|
9 | const appInfo_1 = require("../appInfo");
|
10 | const platformPackager_1 = require("../platformPackager");
|
11 | const appBuilder_1 = require("../util/appBuilder");
|
12 | const ElectronFramework_1 = require("./ElectronFramework");
|
13 | function doRename(basePath, oldName, newName) {
|
14 | return (0, promises_1.rename)(path.join(basePath, oldName), path.join(basePath, newName));
|
15 | }
|
16 | function moveHelpers(helperSuffixes, frameworksPath, appName, prefix) {
|
17 | return bluebird_lst_1.default.map(helperSuffixes, suffix => {
|
18 | const executableBasePath = path.join(frameworksPath, `${prefix}${suffix}.app`, "Contents", "MacOS");
|
19 | return doRename(executableBasePath, `${prefix}${suffix}`, appName + suffix).then(() => doRename(frameworksPath, `${prefix}${suffix}.app`, `${appName}${suffix}.app`));
|
20 | });
|
21 | }
|
22 | function getAvailableHelperSuffixes(helperEHPlist, helperNPPlist, helperRendererPlist, helperPluginPlist, helperGPUPlist) {
|
23 | const result = [" Helper"];
|
24 | if (helperEHPlist != null) {
|
25 | result.push(" Helper EH");
|
26 | }
|
27 | if (helperNPPlist != null) {
|
28 | result.push(" Helper NP");
|
29 | }
|
30 | if (helperRendererPlist != null) {
|
31 | result.push(" Helper (Renderer)");
|
32 | }
|
33 | if (helperPluginPlist != null) {
|
34 | result.push(" Helper (Plugin)");
|
35 | }
|
36 | if (helperGPUPlist != null) {
|
37 | result.push(" Helper (GPU)");
|
38 | }
|
39 | return result;
|
40 | }
|
41 |
|
42 | async function createMacApp(packager, appOutDir, asarIntegrity, isMas) {
|
43 | var _a, _b;
|
44 | const appInfo = packager.appInfo;
|
45 |
|
46 |
|
47 |
|
48 | const appFilename = appInfo.sanitizedProductName;
|
49 | const electronBranding = (0, ElectronFramework_1.createBrandingOpts)(packager.config);
|
50 | const contentsPath = path.join(appOutDir, packager.info.framework.distMacOsAppName, "Contents");
|
51 | const frameworksPath = path.join(contentsPath, "Frameworks");
|
52 | const loginItemPath = path.join(contentsPath, "Library", "LoginItems");
|
53 | const appPlistFilename = path.join(contentsPath, "Info.plist");
|
54 | const helperPlistFilename = path.join(frameworksPath, `${electronBranding.productName} Helper.app`, "Contents", "Info.plist");
|
55 | const helperEHPlistFilename = path.join(frameworksPath, `${electronBranding.productName} Helper EH.app`, "Contents", "Info.plist");
|
56 | const helperNPPlistFilename = path.join(frameworksPath, `${electronBranding.productName} Helper NP.app`, "Contents", "Info.plist");
|
57 | const helperRendererPlistFilename = path.join(frameworksPath, `${electronBranding.productName} Helper (Renderer).app`, "Contents", "Info.plist");
|
58 | const helperPluginPlistFilename = path.join(frameworksPath, `${electronBranding.productName} Helper (Plugin).app`, "Contents", "Info.plist");
|
59 | const helperGPUPlistFilename = path.join(frameworksPath, `${electronBranding.productName} Helper (GPU).app`, "Contents", "Info.plist");
|
60 | const helperLoginPlistFilename = path.join(loginItemPath, `${electronBranding.productName} Login Helper.app`, "Contents", "Info.plist");
|
61 | const plistContent = await (0, appBuilder_1.executeAppBuilderAsJson)([
|
62 | "decode-plist",
|
63 | "-f",
|
64 | appPlistFilename,
|
65 | "-f",
|
66 | helperPlistFilename,
|
67 | "-f",
|
68 | helperEHPlistFilename,
|
69 | "-f",
|
70 | helperNPPlistFilename,
|
71 | "-f",
|
72 | helperRendererPlistFilename,
|
73 | "-f",
|
74 | helperPluginPlistFilename,
|
75 | "-f",
|
76 | helperGPUPlistFilename,
|
77 | "-f",
|
78 | helperLoginPlistFilename,
|
79 | ]);
|
80 | if (plistContent[0] == null) {
|
81 | throw new Error("corrupted Electron dist");
|
82 | }
|
83 | const appPlist = plistContent[0];
|
84 | const helperPlist = plistContent[1];
|
85 | const helperEHPlist = plistContent[2];
|
86 | const helperNPPlist = plistContent[3];
|
87 | const helperRendererPlist = plistContent[4];
|
88 | const helperPluginPlist = plistContent[5];
|
89 | const helperGPUPlist = plistContent[6];
|
90 | const helperLoginPlist = plistContent[7];
|
91 |
|
92 | if (plistContent[8] != null) {
|
93 | Object.assign(appPlist, plistContent[8]);
|
94 | }
|
95 | const buildMetadata = packager.config;
|
96 | |
97 |
|
98 |
|
99 |
|
100 |
|
101 |
|
102 | const oldHelperBundleId = buildMetadata["helper-bundle-id"];
|
103 | if (oldHelperBundleId != null) {
|
104 | builder_util_1.log.warn("build.helper-bundle-id is deprecated, please set as build.mac.helperBundleId");
|
105 | }
|
106 | const defaultAppId = packager.platformSpecificBuildOptions.appId;
|
107 | const cfBundleIdentifier = (0, appInfo_1.filterCFBundleIdentifier)((isMas ? (_a = packager.config.mas) === null || _a === void 0 ? void 0 : _a.appId : defaultAppId) || defaultAppId || appInfo.macBundleIdentifier);
|
108 | const defaultHelperId = packager.platformSpecificBuildOptions.helperBundleId;
|
109 | const helperBundleIdentifier = (0, appInfo_1.filterCFBundleIdentifier)((isMas ? (_b = packager.config.mas) === null || _b === void 0 ? void 0 : _b.helperBundleId : defaultHelperId) || defaultHelperId || oldHelperBundleId || `${cfBundleIdentifier}.helper`);
|
110 | appPlist.CFBundleIdentifier = cfBundleIdentifier;
|
111 | await packager.applyCommonInfo(appPlist, contentsPath);
|
112 |
|
113 | if (!isMas) {
|
114 | configureLocalhostAts(appPlist);
|
115 | }
|
116 | helperPlist.CFBundleExecutable = `${appFilename} Helper`;
|
117 | helperPlist.CFBundleDisplayName = `${appInfo.productName} Helper`;
|
118 | helperPlist.CFBundleIdentifier = helperBundleIdentifier;
|
119 | helperPlist.CFBundleVersion = appPlist.CFBundleVersion;
|
120 | |
121 |
|
122 |
|
123 |
|
124 |
|
125 |
|
126 |
|
127 |
|
128 | function configureHelper(helper, postfix, userProvidedBundleIdentifier) {
|
129 | helper.CFBundleExecutable = `${appFilename} Helper ${postfix}`;
|
130 | helper.CFBundleDisplayName = `${appInfo.productName} Helper ${postfix}`;
|
131 | helper.CFBundleIdentifier = userProvidedBundleIdentifier
|
132 | ? (0, appInfo_1.filterCFBundleIdentifier)(userProvidedBundleIdentifier)
|
133 | : (0, appInfo_1.filterCFBundleIdentifier)(`${helperBundleIdentifier}.${postfix}`);
|
134 | helper.CFBundleVersion = appPlist.CFBundleVersion;
|
135 | }
|
136 | if (helperRendererPlist != null) {
|
137 | configureHelper(helperRendererPlist, "(Renderer)", packager.platformSpecificBuildOptions.helperRendererBundleId);
|
138 | }
|
139 | if (helperPluginPlist != null) {
|
140 | configureHelper(helperPluginPlist, "(Plugin)", packager.platformSpecificBuildOptions.helperPluginBundleId);
|
141 | }
|
142 | if (helperGPUPlist != null) {
|
143 | configureHelper(helperGPUPlist, "(GPU)", packager.platformSpecificBuildOptions.helperGPUBundleId);
|
144 | }
|
145 | if (helperEHPlist != null) {
|
146 | configureHelper(helperEHPlist, "EH", packager.platformSpecificBuildOptions.helperEHBundleId);
|
147 | }
|
148 | if (helperNPPlist != null) {
|
149 | configureHelper(helperNPPlist, "NP", packager.platformSpecificBuildOptions.helperNPBundleId);
|
150 | }
|
151 | if (helperLoginPlist != null) {
|
152 | helperLoginPlist.CFBundleExecutable = `${appFilename} Login Helper`;
|
153 | helperLoginPlist.CFBundleDisplayName = `${appInfo.productName} Login Helper`;
|
154 |
|
155 | helperLoginPlist.CFBundleIdentifier = `${cfBundleIdentifier}.loginhelper`;
|
156 | helperLoginPlist.CFBundleVersion = appPlist.CFBundleVersion;
|
157 | }
|
158 | const protocols = (0, builder_util_1.asArray)(buildMetadata.protocols).concat((0, builder_util_1.asArray)(packager.platformSpecificBuildOptions.protocols));
|
159 | if (protocols.length > 0) {
|
160 | appPlist.CFBundleURLTypes = protocols.map(protocol => {
|
161 | const schemes = (0, builder_util_1.asArray)(protocol.schemes);
|
162 | if (schemes.length === 0) {
|
163 | throw new builder_util_1.InvalidConfigurationError(`Protocol "${protocol.name}": must be at least one scheme specified`);
|
164 | }
|
165 | return {
|
166 | CFBundleURLName: protocol.name,
|
167 | CFBundleTypeRole: protocol.role || "Editor",
|
168 | CFBundleURLSchemes: schemes.slice(),
|
169 | };
|
170 | });
|
171 | }
|
172 | const fileAssociations = packager.fileAssociations;
|
173 | if (fileAssociations.length > 0) {
|
174 | const documentTypes = await bluebird_lst_1.default.map(fileAssociations, async (fileAssociation) => {
|
175 | const extensions = (0, builder_util_1.asArray)(fileAssociation.ext).map(platformPackager_1.normalizeExt);
|
176 | const customIcon = await packager.getResource((0, builder_util_1.getPlatformIconFileName)(fileAssociation.icon, true), `${extensions[0]}.icns`);
|
177 | let iconFile = appPlist.CFBundleIconFile;
|
178 | if (customIcon != null) {
|
179 | iconFile = path.basename(customIcon);
|
180 | await (0, fs_1.copyOrLinkFile)(customIcon, path.join(path.join(contentsPath, "Resources"), iconFile));
|
181 | }
|
182 | const result = {
|
183 | CFBundleTypeExtensions: extensions,
|
184 | CFBundleTypeName: fileAssociation.name || extensions[0],
|
185 | CFBundleTypeRole: fileAssociation.role || "Editor",
|
186 | LSHandlerRank: fileAssociation.rank || "Default",
|
187 | CFBundleTypeIconFile: iconFile,
|
188 | };
|
189 | if (fileAssociation.isPackage) {
|
190 | result.LSTypeIsPackage = true;
|
191 | }
|
192 | return result;
|
193 | });
|
194 |
|
195 | appPlist.CFBundleDocumentTypes = [...(appPlist.CFBundleDocumentTypes || []), ...documentTypes];
|
196 | }
|
197 | if (asarIntegrity != null) {
|
198 | appPlist.ElectronAsarIntegrity = asarIntegrity;
|
199 | }
|
200 | const plistDataToWrite = {
|
201 | [appPlistFilename]: appPlist,
|
202 | [helperPlistFilename]: helperPlist,
|
203 | };
|
204 | if (helperEHPlist != null) {
|
205 | plistDataToWrite[helperEHPlistFilename] = helperEHPlist;
|
206 | }
|
207 | if (helperNPPlist != null) {
|
208 | plistDataToWrite[helperNPPlistFilename] = helperNPPlist;
|
209 | }
|
210 | if (helperRendererPlist != null) {
|
211 | plistDataToWrite[helperRendererPlistFilename] = helperRendererPlist;
|
212 | }
|
213 | if (helperPluginPlist != null) {
|
214 | plistDataToWrite[helperPluginPlistFilename] = helperPluginPlist;
|
215 | }
|
216 | if (helperGPUPlist != null) {
|
217 | plistDataToWrite[helperGPUPlistFilename] = helperGPUPlist;
|
218 | }
|
219 | if (helperLoginPlist != null) {
|
220 | plistDataToWrite[helperLoginPlistFilename] = helperLoginPlist;
|
221 | }
|
222 | await Promise.all([
|
223 | (0, appBuilder_1.executeAppBuilderAndWriteJson)(["encode-plist"], plistDataToWrite),
|
224 | doRename(path.join(contentsPath, "MacOS"), electronBranding.productName, appPlist.CFBundleExecutable),
|
225 | (0, fs_1.unlinkIfExists)(path.join(appOutDir, "LICENSE")),
|
226 | (0, fs_1.unlinkIfExists)(path.join(appOutDir, "LICENSES.chromium.html")),
|
227 | ]);
|
228 | await moveHelpers(getAvailableHelperSuffixes(helperEHPlist, helperNPPlist, helperRendererPlist, helperPluginPlist, helperGPUPlist), frameworksPath, appFilename, electronBranding.productName);
|
229 | if (helperLoginPlist != null) {
|
230 | const prefix = electronBranding.productName;
|
231 | const suffix = " Login Helper";
|
232 | const executableBasePath = path.join(loginItemPath, `${prefix}${suffix}.app`, "Contents", "MacOS");
|
233 | await doRename(executableBasePath, `${prefix}${suffix}`, appFilename + suffix).then(() => doRename(loginItemPath, `${prefix}${suffix}.app`, `${appFilename}${suffix}.app`));
|
234 | }
|
235 | const appPath = path.join(appOutDir, `${appInfo.productFilename}.app`);
|
236 | await (0, promises_1.rename)(path.dirname(contentsPath), appPath);
|
237 |
|
238 | const now = Date.now() / 1000;
|
239 | await (0, promises_1.utimes)(appPath, now, now);
|
240 | }
|
241 | exports.createMacApp = createMacApp;
|
242 | function configureLocalhostAts(appPlist) {
|
243 |
|
244 | let ats = appPlist.NSAppTransportSecurity;
|
245 | if (ats == null) {
|
246 | ats = {};
|
247 | appPlist.NSAppTransportSecurity = ats;
|
248 | }
|
249 | ats.NSAllowsLocalNetworking = true;
|
250 |
|
251 | ats.NSAllowsArbitraryLoads = true;
|
252 | let exceptionDomains = ats.NSExceptionDomains;
|
253 | if (exceptionDomains == null) {
|
254 | exceptionDomains = {};
|
255 | ats.NSExceptionDomains = exceptionDomains;
|
256 | }
|
257 | if (exceptionDomains.localhost == null) {
|
258 | const allowHttp = {
|
259 | NSTemporaryExceptionAllowsInsecureHTTPSLoads: false,
|
260 | NSIncludesSubdomains: false,
|
261 | NSTemporaryExceptionAllowsInsecureHTTPLoads: true,
|
262 | NSTemporaryExceptionMinimumTLSVersion: "1.0",
|
263 | NSTemporaryExceptionRequiresForwardSecrecy: false,
|
264 | };
|
265 | exceptionDomains.localhost = allowHttp;
|
266 | exceptionDomains["127.0.0.1"] = allowHttp;
|
267 | }
|
268 | }
|
269 |
|
\ | No newline at end of file |