UNPKG

13.9 kBJavaScriptView Raw
1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.default = void 0;
7
8function _bluebirdLst() {
9 const data = _interopRequireWildcard(require("bluebird-lst"));
10
11 _bluebirdLst = function () {
12 return data;
13 };
14
15 return data;
16}
17
18function _builderUtil() {
19 const data = require("builder-util");
20
21 _builderUtil = function () {
22 return data;
23 };
24
25 return data;
26}
27
28function _fs() {
29 const data = require("builder-util/out/fs");
30
31 _fs = function () {
32 return data;
33 };
34
35 return data;
36}
37
38function _fsExtraP() {
39 const data = require("fs-extra-p");
40
41 _fsExtraP = function () {
42 return data;
43 };
44
45 return data;
46}
47
48var path = _interopRequireWildcard(require("path"));
49
50function _core() {
51 const data = require("../core");
52
53 _core = function () {
54 return data;
55 };
56
57 return data;
58}
59
60function _pathManager() {
61 const data = require("../util/pathManager");
62
63 _pathManager = function () {
64 return data;
65 };
66
67 return data;
68}
69
70function _windowsCodeSign() {
71 const data = require("../windowsCodeSign");
72
73 _windowsCodeSign = function () {
74 return data;
75 };
76
77 return data;
78}
79
80function _targetUtil() {
81 const data = require("./targetUtil");
82
83 _targetUtil = function () {
84 return data;
85 };
86
87 return data;
88}
89
90function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } }
91
92const APPX_ASSETS_DIR_NAME = "appx";
93const vendorAssetsForDefaultAssets = {
94 "StoreLogo.png": "SampleAppx.50x50.png",
95 "Square150x150Logo.png": "SampleAppx.150x150.png",
96 "Square44x44Logo.png": "SampleAppx.44x44.png",
97 "Wide310x150Logo.png": "SampleAppx.310x150.png"
98};
99const DEFAULT_RESOURCE_LANG = "en-US";
100
101class AppXTarget extends _core().Target {
102 constructor(packager, outDir) {
103 super("appx");
104 this.packager = packager;
105 this.outDir = outDir;
106 this.options = (0, _builderUtil().deepAssign)({}, this.packager.platformSpecificBuildOptions, this.packager.config.appx);
107
108 if (process.platform !== "darwin" && (process.platform !== "win32" || (0, _windowsCodeSign().isOldWin6)())) {
109 throw new Error("AppX is supported only on Windows 10 or Windows Server 2012 R2 (version number 6.3+)");
110 }
111 } // https://docs.microsoft.com/en-us/windows/uwp/packaging/create-app-package-with-makeappx-tool#mapping-files
112
113
114 build(appOutDir, arch) {
115 var _this = this;
116
117 return (0, _bluebirdLst().coroutine)(function* () {
118 const packager = _this.packager;
119 const artifactName = packager.expandArtifactNamePattern(_this.options, "appx", arch);
120 const artifactPath = path.join(_this.outDir, artifactName);
121
122 _this.logBuilding("AppX", artifactPath, arch);
123
124 const vendorPath = yield (0, _windowsCodeSign().getSignVendorPath)();
125 const vm = yield packager.vm.value;
126 const stageDir = yield (0, _targetUtil().createStageDir)(_this, packager, arch);
127 const mappingFile = stageDir.getTempFile("mapping.txt");
128 const makeAppXArgs = ["pack", "/o"
129 /* overwrite the output file if it exists */
130 , "/f", vm.toVmFile(mappingFile), "/p", vm.toVmFile(artifactPath)];
131
132 if (packager.compression === "store") {
133 makeAppXArgs.push("/nc");
134 }
135
136 const mappingList = [];
137 mappingList.push((yield _bluebirdLst().default.map((0, _fs().walk)(appOutDir), file => {
138 let appxPath = file.substring(appOutDir.length + 1);
139
140 if (path.sep !== "\\") {
141 appxPath = appxPath.replace(/\//g, "\\");
142 }
143
144 return `"${vm.toVmFile(file)}" "app\\${appxPath}"`;
145 })));
146 const userAssetDir = yield _this.packager.getResource(undefined, APPX_ASSETS_DIR_NAME);
147 const assetInfo = yield AppXTarget.computeUserAssets(vm, vendorPath, userAssetDir);
148 const userAssets = assetInfo.userAssets;
149 const manifestFile = stageDir.getTempFile("AppxManifest.xml");
150 yield _this.writeManifest(manifestFile, arch, (yield _this.computePublisherName()), userAssets);
151 mappingList.push(assetInfo.mappings);
152 mappingList.push([`"${vm.toVmFile(manifestFile)}" "AppxManifest.xml"`]);
153
154 if (isScaledAssetsProvided(userAssets)) {
155 const outFile = vm.toVmFile(stageDir.getTempFile("resources.pri"));
156 const makePriPath = vm.toVmFile(path.join(vendorPath, "windows-10", _builderUtil().Arch[arch], "makepri.exe"));
157 const assetRoot = stageDir.getTempFile("appx/assets");
158 yield (0, _fsExtraP().emptyDir)(assetRoot);
159 yield _bluebirdLst().default.map(assetInfo.allAssets, it => (0, _fs().copyOrLinkFile)(it, path.join(assetRoot, path.basename(it))));
160 yield vm.exec(makePriPath, ["new", "/Overwrite", "/Manifest", vm.toVmFile(manifestFile), "/ProjectRoot", vm.toVmFile(path.dirname(assetRoot)), "/ConfigXml", vm.toVmFile(path.join((0, _pathManager().getTemplatePath)("appx"), "priconfig.xml")), "/OutputFile", outFile]); // in addition to resources.pri, resources.scale-140.pri and other such files will be generated
161
162 for (const resourceFile of (yield (0, _fsExtraP().readdir)(stageDir.dir)).filter(it => it.startsWith("resources.")).sort()) {
163 mappingList.push([`"${vm.toVmFile(stageDir.getTempFile(resourceFile))}" "${resourceFile}"`]);
164 }
165
166 makeAppXArgs.push("/l");
167 }
168
169 let mapping = "[Files]";
170
171 for (const list of mappingList) {
172 mapping += "\r\n" + list.join("\r\n");
173 }
174
175 yield (0, _fsExtraP().writeFile)(mappingFile, mapping);
176 packager.debugLogger.add("appx.mapping", mapping);
177
178 if (_this.options.makeappxArgs != null) {
179 makeAppXArgs.push(..._this.options.makeappxArgs);
180 }
181
182 yield vm.exec(vm.toVmFile(path.join(vendorPath, "windows-10", _builderUtil().Arch[arch], "makeappx.exe")), makeAppXArgs);
183 yield packager.sign(artifactPath);
184 yield stageDir.cleanup();
185 packager.info.dispatchArtifactCreated({
186 file: artifactPath,
187 packager,
188 arch,
189 safeArtifactName: packager.computeSafeArtifactName(artifactName, "appx"),
190 target: _this,
191 isWriteUpdateInfo: _this.options.electronUpdaterAware
192 });
193 })();
194 }
195
196 static computeUserAssets(vm, vendorPath, userAssetDir) {
197 return (0, _bluebirdLst().coroutine)(function* () {
198 const mappings = [];
199 let userAssets;
200 const allAssets = [];
201
202 if (userAssetDir == null) {
203 userAssets = [];
204 } else {
205 userAssets = (yield (0, _fsExtraP().readdir)(userAssetDir)).filter(it => !it.startsWith(".") && !it.endsWith(".db") && it.includes("."));
206
207 for (const name of userAssets) {
208 mappings.push(`"${vm.toVmFile(userAssetDir)}${vm.pathSep}${name}" "assets\\${name}"`);
209 allAssets.push(path.join(userAssetDir, name));
210 }
211 }
212
213 for (const defaultAsset of Object.keys(vendorAssetsForDefaultAssets)) {
214 if (userAssets.length === 0 || !isDefaultAssetIncluded(userAssets, defaultAsset)) {
215 const file = path.join(vendorPath, "appxAssets", vendorAssetsForDefaultAssets[defaultAsset]);
216 mappings.push(`"${vm.toVmFile(file)}" "assets\\${defaultAsset}"`);
217 allAssets.push(file);
218 }
219 } // we do not use process.arch to build path to tools, because even if you are on x64, ia32 appx tool must be used if you build appx for ia32
220
221
222 return {
223 userAssets,
224 mappings,
225 allAssets
226 };
227 })();
228 } // https://github.com/electron-userland/electron-builder/issues/2108#issuecomment-333200711
229
230
231 computePublisherName() {
232 var _this2 = this;
233
234 return (0, _bluebirdLst().coroutine)(function* () {
235 if ((yield _this2.packager.cscInfo.value) == null) {
236 _builderUtil().log.info({
237 reason: "Windows Store only build"
238 }, "AppX is not signed");
239
240 return _this2.options.publisher || "CN=ms";
241 }
242
243 const publisher = yield _this2.packager.computedPublisherSubjectOnWindowsOnly.value;
244
245 if (!publisher) {
246 throw new Error("Internal error: cannot compute subject using certificate info");
247 }
248
249 return publisher;
250 })();
251 }
252
253 writeManifest(outFile, arch, publisher, userAssets) {
254 var _this3 = this;
255
256 return (0, _bluebirdLst().coroutine)(function* () {
257 const appInfo = _this3.packager.appInfo;
258 const options = _this3.options;
259 const executable = `app\\${appInfo.productFilename}.exe`;
260 const displayName = options.displayName || appInfo.productName;
261 const manifest = (yield (0, _fsExtraP().readFile)(path.join((0, _pathManager().getTemplatePath)("appx"), "appxmanifest.xml"), "utf8")).replace(/\${([a-zA-Z0-9]+)}/g, (match, p1) => {
262 switch (p1) {
263 case "publisher":
264 return publisher;
265
266 case "publisherDisplayName":
267 const name = options.publisherDisplayName || appInfo.companyName;
268
269 if (name == null) {
270 throw new (_builderUtil().InvalidConfigurationError)(`Please specify "author" in the application package.json — it is required because "appx.publisherDisplayName" is not set.`);
271 }
272
273 return name;
274
275 case "version":
276 return appInfo.versionInWeirdWindowsForm;
277
278 case "applicationId":
279 const result = options.applicationId || options.identityName || appInfo.name;
280
281 if (!isNaN(parseInt(result[0], 10))) {
282 let message = `AppX Application.Id can’t start with numbers: "${result}"`;
283
284 if (options.applicationId == null) {
285 message += `\nPlease set appx.applicationId (or correct appx.identityName or name)`;
286 }
287
288 throw new (_builderUtil().InvalidConfigurationError)(message);
289 }
290
291 return result;
292
293 case "identityName":
294 return options.identityName || appInfo.name;
295
296 case "executable":
297 return executable;
298
299 case "displayName":
300 return displayName;
301
302 case "description":
303 return appInfo.description || appInfo.productName;
304
305 case "backgroundColor":
306 return options.backgroundColor || "#464646";
307
308 case "logo":
309 return "assets\\StoreLogo.png";
310
311 case "square150x150Logo":
312 return "assets\\Square150x150Logo.png";
313
314 case "square44x44Logo":
315 return "assets\\Square44x44Logo.png";
316
317 case "lockScreen":
318 return lockScreenTag(userAssets);
319
320 case "defaultTile":
321 return defaultTileTag(userAssets);
322
323 case "splashScreen":
324 return splashScreenTag(userAssets);
325
326 case "arch":
327 return arch === _builderUtil().Arch.ia32 ? "x86" : "x64";
328
329 case "resourceLanguages":
330 return resourceLanguageTag((0, _builderUtil().asArray)(options.languages));
331
332 case "extensions":
333 return _this3.getExtensions(executable, displayName);
334
335 default:
336 throw new Error(`Macro ${p1} is not defined`);
337 }
338 });
339 yield (0, _fsExtraP().writeFile)(outFile, manifest);
340 })();
341 }
342
343 getExtensions(executable, displayName) {
344 let isAddAutoLaunchExtension = this.options.addAutoLaunchExtension;
345
346 if (isAddAutoLaunchExtension === undefined) {
347 const deps = this.packager.info.metadata.dependencies;
348 isAddAutoLaunchExtension = deps != null && deps["electron-winstore-auto-launch"] != null;
349 }
350
351 if (!isAddAutoLaunchExtension) {
352 return "";
353 }
354
355 return `<Extensions>
356 <desktop:Extension Category="windows.startupTask" Executable="${executable}" EntryPoint="Windows.FullTrustApplication">
357 <desktop:StartupTask TaskId="SlackStartup" Enabled="true" DisplayName="${displayName}" />
358 </desktop:Extension>
359 </Extensions>`;
360 }
361
362} // get the resource - language tag, see https://docs.microsoft.com/en-us/windows/uwp/globalizing/manage-language-and-region#specify-the-supported-languages-in-the-apps-manifest
363
364
365exports.default = AppXTarget;
366
367function resourceLanguageTag(userLanguages) {
368 if (userLanguages == null || userLanguages.length === 0) {
369 userLanguages = [DEFAULT_RESOURCE_LANG];
370 }
371
372 return userLanguages.map(it => `<Resource Language="${it.replace(/_/g, "-")}" />`).join("\n");
373}
374
375function lockScreenTag(userAssets) {
376 if (isDefaultAssetIncluded(userAssets, "BadgeLogo.png")) {
377 return '<uap:LockScreen Notification="badgeAndTileText" BadgeLogo="assets\\BadgeLogo.png" />';
378 } else {
379 return "";
380 }
381}
382
383function defaultTileTag(userAssets) {
384 const defaultTiles = ["<uap:DefaultTile", 'Wide310x150Logo="assets\\Wide310x150Logo.png"'];
385
386 if (isDefaultAssetIncluded(userAssets, "LargeTile.png")) {
387 defaultTiles.push('Square310x310Logo="assets\\LargeTile.png"');
388 }
389
390 if (isDefaultAssetIncluded(userAssets, "SmallTile.png")) {
391 defaultTiles.push('Square71x71Logo="assets\\SmallTile.png"');
392 }
393
394 defaultTiles.push("/>");
395 return defaultTiles.join(" ");
396}
397
398function splashScreenTag(userAssets) {
399 if (isDefaultAssetIncluded(userAssets, "SplashScreen.png")) {
400 return '<uap:SplashScreen Image="assets\\SplashScreen.png" />';
401 } else {
402 return "";
403 }
404}
405
406function isDefaultAssetIncluded(userAssets, defaultAsset) {
407 const defaultAssetName = defaultAsset.substring(0, defaultAsset.indexOf("."));
408 return userAssets.some(it => it.includes(defaultAssetName));
409}
410
411function isScaledAssetsProvided(userAssets) {
412 return userAssets.some(it => it.includes(".scale-") || it.includes(".targetsize-"));
413}
414//# sourceMappingURL=AppxTarget.js.map
\No newline at end of file