UNPKG

29.6 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.isSafeToUnpackElectronOnRemoteBuildServer = exports.chooseNotNull = exports.resolveFunction = exports.normalizeExt = exports.computeSafeArtifactNameIfNeeded = exports.isSafeGithubName = exports.PlatformPackager = void 0;
4const bluebird_lst_1 = require("bluebird-lst");
5const builder_util_1 = require("builder-util");
6const arch_1 = require("builder-util/out/arch");
7const fs_1 = require("builder-util/out/fs");
8const promise_1 = require("builder-util/out/promise");
9const promises_1 = require("fs/promises");
10const lazy_val_1 = require("lazy-val");
11const path = require("path");
12const appInfo_1 = require("./appInfo");
13const asarFileChecker_1 = require("./asar/asarFileChecker");
14const asarUtil_1 = require("./asar/asarUtil");
15const integrity_1 = require("./asar/integrity");
16const fileMatcher_1 = require("./fileMatcher");
17const fileTransformer_1 = require("./fileTransformer");
18const Framework_1 = require("./Framework");
19const index_1 = require("./index");
20const appBuilder_1 = require("./util/appBuilder");
21const appFileCopier_1 = require("./util/appFileCopier");
22const macroExpander_1 = require("./util/macroExpander");
23class PlatformPackager {
24 constructor(info, platform) {
25 this.info = info;
26 this.platform = platform;
27 this._resourceList = new lazy_val_1.Lazy(() => promise_1.orIfFileNotExist(promises_1.readdir(this.info.buildResourcesDir), []));
28 this.platformSpecificBuildOptions = PlatformPackager.normalizePlatformSpecificBuildOptions(this.config[platform.buildConfigurationKey]);
29 this.appInfo = this.prepareAppInfo(info.appInfo);
30 }
31 get packagerOptions() {
32 return this.info.options;
33 }
34 get buildResourcesDir() {
35 return this.info.buildResourcesDir;
36 }
37 get projectDir() {
38 return this.info.projectDir;
39 }
40 get config() {
41 return this.info.config;
42 }
43 get resourceList() {
44 return this._resourceList.value;
45 }
46 get compression() {
47 const compression = this.platformSpecificBuildOptions.compression;
48 // explicitly set to null - request to use default value instead of parent (in the config)
49 if (compression === null) {
50 return "normal";
51 }
52 return compression || this.config.compression || "normal";
53 }
54 get debugLogger() {
55 return this.info.debugLogger;
56 }
57 // eslint-disable-next-line
58 prepareAppInfo(appInfo) {
59 return new appInfo_1.AppInfo(this.info, null, this.platformSpecificBuildOptions);
60 }
61 static normalizePlatformSpecificBuildOptions(options) {
62 return options == null ? Object.create(null) : options;
63 }
64 getCscPassword() {
65 const password = this.doGetCscPassword();
66 if (builder_util_1.isEmptyOrSpaces(password)) {
67 builder_util_1.log.info({ reason: "CSC_KEY_PASSWORD is not defined" }, "empty password will be used for code signing");
68 return "";
69 }
70 else {
71 return password.trim();
72 }
73 }
74 getCscLink(extraEnvName) {
75 // allow to specify as empty string
76 const envValue = chooseNotNull(extraEnvName == null ? null : process.env[extraEnvName], process.env.CSC_LINK);
77 return chooseNotNull(chooseNotNull(this.info.config.cscLink, this.platformSpecificBuildOptions.cscLink), envValue);
78 }
79 doGetCscPassword() {
80 // allow to specify as empty string
81 return chooseNotNull(chooseNotNull(this.info.config.cscKeyPassword, this.platformSpecificBuildOptions.cscKeyPassword), process.env.CSC_KEY_PASSWORD);
82 }
83 computeAppOutDir(outDir, arch) {
84 return (this.packagerOptions.prepackaged ||
85 path.join(outDir, `${this.platform.buildConfigurationKey}${builder_util_1.getArchSuffix(arch, this.platformSpecificBuildOptions.defaultArch)}${this.platform === index_1.Platform.MAC ? "" : "-unpacked"}`));
86 }
87 dispatchArtifactCreated(file, target, arch, safeArtifactName) {
88 return this.info.callArtifactBuildCompleted({
89 file,
90 safeArtifactName,
91 target,
92 arch,
93 packager: this,
94 });
95 }
96 async pack(outDir, arch, targets, taskManager) {
97 const appOutDir = this.computeAppOutDir(outDir, arch);
98 await this.doPack(outDir, appOutDir, this.platform.nodeName, arch, this.platformSpecificBuildOptions, targets);
99 this.packageInDistributableFormat(appOutDir, arch, targets, taskManager);
100 }
101 packageInDistributableFormat(appOutDir, arch, targets, taskManager) {
102 if (targets.find(it => !it.isAsyncSupported) == null) {
103 PlatformPackager.buildAsyncTargets(targets, taskManager, appOutDir, arch);
104 return;
105 }
106 taskManager.add(async () => {
107 // BluebirdPromise.map doesn't invoke target.build immediately, but for RemoteTarget it is very critical to call build() before finishBuild()
108 const subTaskManager = new builder_util_1.AsyncTaskManager(this.info.cancellationToken);
109 PlatformPackager.buildAsyncTargets(targets, subTaskManager, appOutDir, arch);
110 await subTaskManager.awaitTasks();
111 for (const target of targets) {
112 if (!target.isAsyncSupported) {
113 await target.build(appOutDir, arch);
114 }
115 }
116 });
117 }
118 static buildAsyncTargets(targets, taskManager, appOutDir, arch) {
119 for (const target of targets) {
120 if (target.isAsyncSupported) {
121 taskManager.addTask(target.build(appOutDir, arch));
122 }
123 }
124 }
125 getExtraFileMatchers(isResources, appOutDir, options) {
126 const base = isResources
127 ? this.getResourcesDir(appOutDir)
128 : this.platform === index_1.Platform.MAC
129 ? path.join(appOutDir, `${this.appInfo.productFilename}.app`, "Contents")
130 : appOutDir;
131 return fileMatcher_1.getFileMatchers(this.config, isResources ? "extraResources" : "extraFiles", base, options);
132 }
133 createGetFileMatchersOptions(outDir, arch, customBuildOptions) {
134 return {
135 macroExpander: it => this.expandMacro(it, arch == null ? null : builder_util_1.Arch[arch], { "/*": "{,/**/*}" }),
136 customBuildOptions,
137 globalOutDir: outDir,
138 defaultSrc: this.projectDir,
139 };
140 }
141 async doPack(outDir, appOutDir, platformName, arch, platformSpecificBuildOptions, targets, sign = true, disableAsarIntegrity = false) {
142 if (this.packagerOptions.prepackaged != null) {
143 return;
144 }
145 if (this.info.cancellationToken.cancelled) {
146 return;
147 }
148 const beforePack = resolveFunction(this.config.beforePack, "beforePack");
149 if (beforePack != null) {
150 await beforePack({
151 appOutDir,
152 outDir,
153 arch,
154 targets,
155 packager: this,
156 electronPlatformName: platformName,
157 });
158 }
159 await this.info.installAppDependencies(this.platform, arch);
160 if (this.info.cancellationToken.cancelled) {
161 return;
162 }
163 const framework = this.info.framework;
164 builder_util_1.log.info({
165 platform: platformName,
166 arch: builder_util_1.Arch[arch],
167 [`${framework.name}`]: framework.version,
168 appOutDir: builder_util_1.log.filePath(appOutDir),
169 }, `packaging`);
170 await framework.prepareApplicationStageDirectory({
171 packager: this,
172 appOutDir,
173 platformName,
174 arch: builder_util_1.Arch[arch],
175 version: framework.version,
176 });
177 const excludePatterns = [];
178 const computeParsedPatterns = (patterns) => {
179 if (patterns != null) {
180 for (const pattern of patterns) {
181 pattern.computeParsedPatterns(excludePatterns, this.info.projectDir);
182 }
183 }
184 };
185 const getFileMatchersOptions = this.createGetFileMatchersOptions(outDir, arch, platformSpecificBuildOptions);
186 const macroExpander = getFileMatchersOptions.macroExpander;
187 const extraResourceMatchers = this.getExtraFileMatchers(true, appOutDir, getFileMatchersOptions);
188 computeParsedPatterns(extraResourceMatchers);
189 const extraFileMatchers = this.getExtraFileMatchers(false, appOutDir, getFileMatchersOptions);
190 computeParsedPatterns(extraFileMatchers);
191 const packContext = {
192 appOutDir,
193 outDir,
194 arch,
195 targets,
196 packager: this,
197 electronPlatformName: platformName,
198 };
199 const asarOptions = await this.computeAsarOptions(platformSpecificBuildOptions);
200 const resourcesPath = this.platform === index_1.Platform.MAC
201 ? path.join(appOutDir, framework.distMacOsAppName, "Contents", "Resources")
202 : Framework_1.isElectronBased(framework)
203 ? path.join(appOutDir, "resources")
204 : appOutDir;
205 const taskManager = new builder_util_1.AsyncTaskManager(this.info.cancellationToken);
206 this.copyAppFiles(taskManager, asarOptions, resourcesPath, path.join(resourcesPath, "app"), packContext, platformSpecificBuildOptions, excludePatterns, macroExpander);
207 await taskManager.awaitTasks();
208 if (this.info.cancellationToken.cancelled) {
209 return;
210 }
211 if (framework.beforeCopyExtraFiles != null) {
212 await framework.beforeCopyExtraFiles({
213 packager: this,
214 appOutDir,
215 asarIntegrity: asarOptions == null || disableAsarIntegrity ? null : await integrity_1.computeData(resourcesPath, asarOptions.externalAllowed ? { externalAllowed: true } : null),
216 platformName,
217 });
218 }
219 if (this.info.cancellationToken.cancelled) {
220 return;
221 }
222 const transformerForExtraFiles = this.createTransformerForExtraFiles(packContext);
223 await fileMatcher_1.copyFiles(extraResourceMatchers, transformerForExtraFiles);
224 await fileMatcher_1.copyFiles(extraFileMatchers, transformerForExtraFiles);
225 if (this.info.cancellationToken.cancelled) {
226 return;
227 }
228 await this.info.afterPack(packContext);
229 if (framework.afterPack != null) {
230 await framework.afterPack(packContext);
231 }
232 const isAsar = asarOptions != null;
233 await this.sanityCheckPackage(appOutDir, isAsar, framework);
234 if (sign) {
235 await this.doSignAfterPack(outDir, appOutDir, platformName, arch, platformSpecificBuildOptions, targets);
236 }
237 }
238 async doSignAfterPack(outDir, appOutDir, platformName, arch, platformSpecificBuildOptions, targets) {
239 const asarOptions = await this.computeAsarOptions(platformSpecificBuildOptions);
240 const isAsar = asarOptions != null;
241 const packContext = {
242 appOutDir,
243 outDir,
244 arch,
245 targets,
246 packager: this,
247 electronPlatformName: platformName,
248 };
249 await this.signApp(packContext, isAsar);
250 const afterSign = resolveFunction(this.config.afterSign, "afterSign");
251 if (afterSign != null) {
252 await Promise.resolve(afterSign(packContext));
253 }
254 }
255 // eslint-disable-next-line
256 createTransformerForExtraFiles(packContext) {
257 return null;
258 }
259 copyAppFiles(taskManager, asarOptions, resourcePath, defaultDestination, packContext, platformSpecificBuildOptions, excludePatterns, macroExpander) {
260 const appDir = this.info.appDir;
261 const config = this.config;
262 const isElectronCompile = asarOptions != null && fileTransformer_1.isElectronCompileUsed(this.info);
263 const mainMatchers = fileMatcher_1.getMainFileMatchers(appDir, defaultDestination, macroExpander, platformSpecificBuildOptions, this, packContext.outDir, isElectronCompile);
264 if (excludePatterns.length > 0) {
265 for (const matcher of mainMatchers) {
266 matcher.excludePatterns = excludePatterns;
267 }
268 }
269 const framework = this.info.framework;
270 const transformer = fileTransformer_1.createTransformer(appDir, config, isElectronCompile
271 ? {
272 originalMain: this.info.metadata.main,
273 main: appFileCopier_1.ELECTRON_COMPILE_SHIM_FILENAME,
274 ...config.extraMetadata,
275 }
276 : config.extraMetadata, framework.createTransformer == null ? null : framework.createTransformer());
277 const _computeFileSets = (matchers) => {
278 return appFileCopier_1.computeFileSets(matchers, this.info.isPrepackedAppAsar ? null : transformer, this, isElectronCompile).then(async (result) => {
279 if (!this.info.isPrepackedAppAsar && !this.info.areNodeModulesHandledExternally) {
280 const moduleFileMatcher = fileMatcher_1.getNodeModuleFileMatcher(appDir, defaultDestination, macroExpander, platformSpecificBuildOptions, this.info);
281 result = result.concat(await appFileCopier_1.computeNodeModuleFileSets(this, moduleFileMatcher));
282 }
283 return result.filter(it => it.files.length > 0);
284 });
285 };
286 if (this.info.isPrepackedAppAsar) {
287 taskManager.addTask(bluebird_lst_1.default.each(_computeFileSets([new fileMatcher_1.FileMatcher(appDir, resourcePath, macroExpander)]), it => appFileCopier_1.copyAppFiles(it, this.info, transformer)));
288 }
289 else if (asarOptions == null) {
290 // for ASAR all asar unpacked files will be extra transformed (e.g. sign of EXE and DLL) later,
291 // for prepackaged asar extra transformation not supported yet,
292 // so, extra transform if asar is disabled
293 const transformerForExtraFiles = this.createTransformerForExtraFiles(packContext);
294 const combinedTransformer = file => {
295 if (transformerForExtraFiles != null) {
296 const result = transformerForExtraFiles(file);
297 if (result != null) {
298 return result;
299 }
300 }
301 return transformer(file);
302 };
303 taskManager.addTask(bluebird_lst_1.default.each(_computeFileSets(mainMatchers), it => appFileCopier_1.copyAppFiles(it, this.info, combinedTransformer)));
304 }
305 else {
306 const unpackPattern = fileMatcher_1.getFileMatchers(config, "asarUnpack", defaultDestination, {
307 macroExpander,
308 customBuildOptions: platformSpecificBuildOptions,
309 globalOutDir: packContext.outDir,
310 defaultSrc: appDir,
311 });
312 const fileMatcher = unpackPattern == null ? null : unpackPattern[0];
313 taskManager.addTask(_computeFileSets(mainMatchers).then(async (fileSets) => {
314 for (const fileSet of fileSets) {
315 await appFileCopier_1.transformFiles(transformer, fileSet);
316 }
317 await new asarUtil_1.AsarPackager(appDir, resourcePath, asarOptions, fileMatcher == null ? null : fileMatcher.createFilter()).pack(fileSets, this);
318 }));
319 }
320 }
321 // eslint-disable-next-line @typescript-eslint/no-unused-vars
322 signApp(packContext, isAsar) {
323 return Promise.resolve();
324 }
325 getIconPath() {
326 return Promise.resolve(null);
327 }
328 async computeAsarOptions(customBuildOptions) {
329 if (!Framework_1.isElectronBased(this.info.framework)) {
330 return null;
331 }
332 function errorMessage(name) {
333 return `${name} is deprecated is deprecated and not supported — please use asarUnpack`;
334 }
335 const buildMetadata = this.config;
336 if (buildMetadata["asar-unpack"] != null) {
337 throw new Error(errorMessage("asar-unpack"));
338 }
339 if (buildMetadata["asar-unpack-dir"] != null) {
340 throw new Error(errorMessage("asar-unpack-dir"));
341 }
342 const platformSpecific = customBuildOptions.asar;
343 const result = platformSpecific == null ? this.config.asar : platformSpecific;
344 if (result === false) {
345 const appAsarStat = await fs_1.statOrNull(path.join(this.info.appDir, "app.asar"));
346 //noinspection ES6MissingAwait
347 if (appAsarStat == null || !appAsarStat.isFile()) {
348 builder_util_1.log.warn({
349 solution: "enable asar and use asarUnpack to unpack files that must be externally available",
350 }, "asar usage is disabled — this is strongly not recommended");
351 }
352 return null;
353 }
354 if (result == null || result === true) {
355 return {};
356 }
357 for (const name of ["unpackDir", "unpack"]) {
358 if (result[name] != null) {
359 throw new Error(errorMessage(`asar.${name}`));
360 }
361 }
362 return builder_util_1.deepAssign({}, result);
363 }
364 getElectronSrcDir(dist) {
365 return path.resolve(this.projectDir, dist);
366 }
367 getElectronDestinationDir(appOutDir) {
368 return appOutDir;
369 }
370 getResourcesDir(appOutDir) {
371 if (this.platform === index_1.Platform.MAC) {
372 return this.getMacOsResourcesDir(appOutDir);
373 }
374 else if (Framework_1.isElectronBased(this.info.framework)) {
375 return path.join(appOutDir, "resources");
376 }
377 else {
378 return appOutDir;
379 }
380 }
381 getMacOsResourcesDir(appOutDir) {
382 return path.join(appOutDir, `${this.appInfo.productFilename}.app`, "Contents", "Resources");
383 }
384 async checkFileInPackage(resourcesDir, file, messagePrefix, isAsar) {
385 const relativeFile = path.relative(this.info.appDir, path.resolve(this.info.appDir, file));
386 if (isAsar) {
387 await asarFileChecker_1.checkFileInArchive(path.join(resourcesDir, "app.asar"), relativeFile, messagePrefix);
388 return;
389 }
390 const pathParsed = path.parse(file);
391 // Even when packaging to asar is disabled, it does not imply that the main file can not be inside an .asar archive.
392 // This may occur when the packaging is done manually before processing with electron-builder.
393 if (pathParsed.dir.includes(".asar")) {
394 // The path needs to be split to the part with an asar archive which acts like a directory and the part with
395 // the path to main file itself. (e.g. path/arch.asar/dir/index.js -> path/arch.asar, dir/index.js)
396 // noinspection TypeScriptValidateJSTypes
397 const pathSplit = pathParsed.dir.split(path.sep);
398 let partWithAsarIndex = 0;
399 pathSplit.some((pathPart, index) => {
400 partWithAsarIndex = index;
401 return pathPart.endsWith(".asar");
402 });
403 const asarPath = path.join(...pathSplit.slice(0, partWithAsarIndex + 1));
404 let mainPath = pathSplit.length > partWithAsarIndex + 1 ? path.join.apply(pathSplit.slice(partWithAsarIndex + 1)) : "";
405 mainPath += path.join(mainPath, pathParsed.base);
406 await asarFileChecker_1.checkFileInArchive(path.join(resourcesDir, "app", asarPath), mainPath, messagePrefix);
407 }
408 else {
409 const fullPath = path.join(resourcesDir, "app", relativeFile);
410 const outStat = await fs_1.statOrNull(fullPath);
411 if (outStat == null) {
412 throw new Error(`${messagePrefix} "${fullPath}" does not exist. Seems like a wrong configuration.`);
413 }
414 else {
415 //noinspection ES6MissingAwait
416 if (!outStat.isFile()) {
417 throw new Error(`${messagePrefix} "${fullPath}" is not a file. Seems like a wrong configuration.`);
418 }
419 }
420 }
421 }
422 async sanityCheckPackage(appOutDir, isAsar, framework) {
423 const outStat = await fs_1.statOrNull(appOutDir);
424 if (outStat == null) {
425 throw new Error(`Output directory "${appOutDir}" does not exist. Seems like a wrong configuration.`);
426 }
427 else {
428 //noinspection ES6MissingAwait
429 if (!outStat.isDirectory()) {
430 throw new Error(`Output directory "${appOutDir}" is not a directory. Seems like a wrong configuration.`);
431 }
432 }
433 const resourcesDir = this.getResourcesDir(appOutDir);
434 const mainFile = (framework.getMainFile == null ? null : framework.getMainFile(this.platform)) || this.info.metadata.main || "index.js";
435 await this.checkFileInPackage(resourcesDir, mainFile, "Application entry file", isAsar);
436 await this.checkFileInPackage(resourcesDir, "package.json", "Application", isAsar);
437 }
438 // tslint:disable-next-line:no-invalid-template-strings
439 computeSafeArtifactName(suggestedName, ext, arch, skipDefaultArch = true, defaultArch, safePattern = "${name}-${version}-${arch}.${ext}") {
440 return computeSafeArtifactNameIfNeeded(suggestedName, () => this.computeArtifactName(safePattern, ext, skipDefaultArch && arch === arch_1.defaultArchFromString(defaultArch) ? null : arch));
441 }
442 expandArtifactNamePattern(targetSpecificOptions, ext, arch, defaultPattern, skipDefaultArch = true, defaultArch) {
443 const { pattern, isUserForced } = this.artifactPatternConfig(targetSpecificOptions, defaultPattern);
444 return this.computeArtifactName(pattern, ext, !isUserForced && skipDefaultArch && arch === arch_1.defaultArchFromString(defaultArch) ? null : arch);
445 }
446 artifactPatternConfig(targetSpecificOptions, defaultPattern) {
447 const userSpecifiedPattern = (targetSpecificOptions === null || targetSpecificOptions === void 0 ? void 0 : targetSpecificOptions.artifactName) || this.platformSpecificBuildOptions.artifactName || this.config.artifactName;
448 return {
449 isUserForced: !!userSpecifiedPattern,
450 pattern: userSpecifiedPattern || defaultPattern || "${productName}-${version}-${arch}.${ext}",
451 };
452 }
453 expandArtifactBeautyNamePattern(targetSpecificOptions, ext, arch) {
454 // tslint:disable-next-line:no-invalid-template-strings
455 return this.expandArtifactNamePattern(targetSpecificOptions, ext, arch, "${productName} ${version} ${arch}.${ext}", true);
456 }
457 computeArtifactName(pattern, ext, arch) {
458 const archName = arch == null ? null : arch_1.getArtifactArchName(arch, ext);
459 return this.expandMacro(pattern, archName, {
460 ext,
461 });
462 }
463 expandMacro(pattern, arch, extra = {}, isProductNameSanitized = true) {
464 return macroExpander_1.expandMacro(pattern, arch, this.appInfo, { os: this.platform.buildConfigurationKey, ...extra }, isProductNameSanitized);
465 }
466 generateName2(ext, classifier, deployment) {
467 const dotExt = ext == null ? "" : `.${ext}`;
468 const separator = ext === "deb" ? "_" : "-";
469 return `${deployment ? this.appInfo.name : this.appInfo.productFilename}${separator}${this.appInfo.version}${classifier == null ? "" : `${separator}${classifier}`}${dotExt}`;
470 }
471 getTempFile(suffix) {
472 return this.info.tempDirManager.getTempFile({ suffix });
473 }
474 get fileAssociations() {
475 return builder_util_1.asArray(this.config.fileAssociations).concat(builder_util_1.asArray(this.platformSpecificBuildOptions.fileAssociations));
476 }
477 async getResource(custom, ...names) {
478 const resourcesDir = this.info.buildResourcesDir;
479 if (custom === undefined) {
480 const resourceList = await this.resourceList;
481 for (const name of names) {
482 if (resourceList.includes(name)) {
483 return path.join(resourcesDir, name);
484 }
485 }
486 }
487 else if (custom != null && !builder_util_1.isEmptyOrSpaces(custom)) {
488 const resourceList = await this.resourceList;
489 if (resourceList.includes(custom)) {
490 return path.join(resourcesDir, custom);
491 }
492 let p = path.resolve(resourcesDir, custom);
493 if ((await fs_1.statOrNull(p)) == null) {
494 p = path.resolve(this.projectDir, custom);
495 if ((await fs_1.statOrNull(p)) == null) {
496 throw new builder_util_1.InvalidConfigurationError(`cannot find specified resource "${custom}", nor relative to "${resourcesDir}", neither relative to project dir ("${this.projectDir}")`);
497 }
498 }
499 return p;
500 }
501 return null;
502 }
503 get forceCodeSigning() {
504 const forceCodeSigningPlatform = this.platformSpecificBuildOptions.forceCodeSigning;
505 return (forceCodeSigningPlatform == null ? this.config.forceCodeSigning : forceCodeSigningPlatform) || false;
506 }
507 async getOrConvertIcon(format) {
508 const result = await this.resolveIcon(builder_util_1.asArray(this.platformSpecificBuildOptions.icon || this.config.icon), [], format);
509 if (result.length === 0) {
510 const framework = this.info.framework;
511 if (framework.getDefaultIcon != null) {
512 return framework.getDefaultIcon(this.platform);
513 }
514 builder_util_1.log.warn({ reason: "application icon is not set" }, `default ${capitalizeFirstLetter(framework.name)} icon is used`);
515 return this.getDefaultFrameworkIcon();
516 }
517 else {
518 return result[0].file;
519 }
520 }
521 getDefaultFrameworkIcon() {
522 const framework = this.info.framework;
523 return framework.getDefaultIcon == null ? null : framework.getDefaultIcon(this.platform);
524 }
525 // convert if need, validate size (it is a reason why tool is called even if file has target extension (already specified as foo.icns for example))
526 async resolveIcon(sources, fallbackSources, outputFormat) {
527 const args = [
528 "icon",
529 "--format",
530 outputFormat,
531 "--root",
532 this.buildResourcesDir,
533 "--root",
534 this.projectDir,
535 "--out",
536 path.resolve(this.projectDir, this.config.directories.output, `.icon-${outputFormat}`),
537 ];
538 for (const source of sources) {
539 args.push("--input", source);
540 }
541 for (const source of fallbackSources) {
542 args.push("--fallback-input", source);
543 }
544 const result = await appBuilder_1.executeAppBuilderAsJson(args);
545 const errorMessage = result.error;
546 if (errorMessage != null) {
547 throw new builder_util_1.InvalidConfigurationError(errorMessage, result.errorCode);
548 }
549 if (result.isFallback) {
550 builder_util_1.log.warn({ reason: "application icon is not set" }, `default ${capitalizeFirstLetter(this.info.framework.name)} icon is used`);
551 }
552 return result.icons || [];
553 }
554}
555exports.PlatformPackager = PlatformPackager;
556function isSafeGithubName(name) {
557 return /^[0-9A-Za-z._-]+$/.test(name);
558}
559exports.isSafeGithubName = isSafeGithubName;
560function computeSafeArtifactNameIfNeeded(suggestedName, safeNameProducer) {
561 // GitHub only allows the listed characters in file names.
562 if (suggestedName != null) {
563 if (isSafeGithubName(suggestedName)) {
564 return null;
565 }
566 // prefer to use suggested name - so, if space is the only problem, just replace only space to dash
567 suggestedName = suggestedName.replace(/ /g, "-");
568 if (isSafeGithubName(suggestedName)) {
569 return suggestedName;
570 }
571 }
572 return safeNameProducer();
573}
574exports.computeSafeArtifactNameIfNeeded = computeSafeArtifactNameIfNeeded;
575// remove leading dot
576function normalizeExt(ext) {
577 return ext.startsWith(".") ? ext.substring(1) : ext;
578}
579exports.normalizeExt = normalizeExt;
580function resolveFunction(executor, name) {
581 if (executor == null || typeof executor !== "string") {
582 return executor;
583 }
584 let p = executor;
585 if (p.startsWith(".")) {
586 p = path.resolve(p);
587 }
588 try {
589 p = require.resolve(p);
590 }
591 catch (e) {
592 builder_util_1.debug(e);
593 p = path.resolve(p);
594 }
595 // eslint-disable-next-line @typescript-eslint/no-var-requires
596 const m = require(p);
597 const namedExport = m[name];
598 if (namedExport == null) {
599 return m.default || m;
600 }
601 else {
602 return namedExport;
603 }
604}
605exports.resolveFunction = resolveFunction;
606function chooseNotNull(v1, v2) {
607 return v1 == null ? v2 : v1;
608}
609exports.chooseNotNull = chooseNotNull;
610function capitalizeFirstLetter(text) {
611 return text.charAt(0).toUpperCase() + text.slice(1);
612}
613function isSafeToUnpackElectronOnRemoteBuildServer(packager) {
614 if (packager.platform !== index_1.Platform.LINUX || packager.config.remoteBuild === false) {
615 return false;
616 }
617 if (process.platform === "win32" || builder_util_1.isEnvTrue(process.env._REMOTE_BUILD)) {
618 return packager.config.electronDist == null && packager.config.electronDownload == null;
619 }
620 return false;
621}
622exports.isSafeToUnpackElectronOnRemoteBuildServer = isSafeToUnpackElectronOnRemoteBuildServer;
623//# sourceMappingURL=platformPackager.js.map
\No newline at end of file