1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | exports.LinuxTargetHelper = exports.installPrefix = void 0;
|
4 | const builder_util_1 = require("builder-util");
|
5 | const fs_extra_1 = require("fs-extra");
|
6 | const lazy_val_1 = require("lazy-val");
|
7 | const path_1 = require("path");
|
8 | exports.installPrefix = "/opt";
|
9 | class LinuxTargetHelper {
|
10 | constructor(packager) {
|
11 | this.packager = packager;
|
12 | this.iconPromise = new lazy_val_1.Lazy(() => this.computeDesktopIcons());
|
13 | this.mimeTypeFilesPromise = new lazy_val_1.Lazy(() => this.computeMimeTypeFiles());
|
14 | this.maxIconPath = null;
|
15 | }
|
16 | get icons() {
|
17 | return this.iconPromise.value;
|
18 | }
|
19 | get mimeTypeFiles() {
|
20 | return this.mimeTypeFilesPromise.value;
|
21 | }
|
22 | async computeMimeTypeFiles() {
|
23 | const items = [];
|
24 | for (const fileAssociation of this.packager.fileAssociations) {
|
25 | if (!fileAssociation.mimeType) {
|
26 | continue;
|
27 | }
|
28 | const data = `<mime-type type="${fileAssociation.mimeType}">
|
29 | <glob pattern="*.${fileAssociation.ext}"/>
|
30 | ${fileAssociation.description ? `<comment>${fileAssociation.description}</comment>` : ""}
|
31 | <icon name="x-office-document" />
|
32 | </mime-type>`;
|
33 | items.push(data);
|
34 | }
|
35 | if (items.length === 0) {
|
36 | return null;
|
37 | }
|
38 | const file = await this.packager.getTempFile(".xml");
|
39 | await (0, fs_extra_1.outputFile)(file, '<?xml version="1.0" encoding="utf-8"?>\n<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">\n' + items.join("\n") + "\n</mime-info>");
|
40 | return file;
|
41 | }
|
42 |
|
43 | async computeDesktopIcons() {
|
44 | var _a, _b, _c;
|
45 | const packager = this.packager;
|
46 | const { platformSpecificBuildOptions, config } = packager;
|
47 | const sources = [platformSpecificBuildOptions.icon, (_b = (_a = config.mac) === null || _a === void 0 ? void 0 : _a.icon) !== null && _b !== void 0 ? _b : config.icon].filter(str => !!str);
|
48 |
|
49 | let fallbackSources = [...(0, builder_util_1.asArray)(packager.getDefaultFrameworkIcon())];
|
50 | const buildResources = (_c = config.directories) === null || _c === void 0 ? void 0 : _c.buildResources;
|
51 | if (buildResources && (await (0, builder_util_1.exists)((0, path_1.join)(buildResources, "icons")))) {
|
52 | fallbackSources = [buildResources, ...fallbackSources];
|
53 | }
|
54 |
|
55 | const result = await packager.resolveIcon(sources, fallbackSources, "set");
|
56 | this.maxIconPath = result[result.length - 1].file;
|
57 | return result;
|
58 | }
|
59 | getDescription(options) {
|
60 | return options.description || this.packager.appInfo.description;
|
61 | }
|
62 | getSanitizedVersion(target) {
|
63 | const { appInfo: { version }, } = this.packager;
|
64 | switch (target) {
|
65 | case "pacman":
|
66 | return version.replace(/-/g, "_");
|
67 | case "rpm":
|
68 | case "deb":
|
69 | return version.replace(/-/g, "~");
|
70 | default:
|
71 | return version;
|
72 | }
|
73 | }
|
74 | async writeDesktopEntry(targetSpecificOptions, exec, destination, extra) {
|
75 | const data = await this.computeDesktopEntry(targetSpecificOptions, exec, extra);
|
76 | const file = destination || (await this.packager.getTempFile(`${this.packager.appInfo.productFilename}.desktop`));
|
77 | await (0, fs_extra_1.outputFile)(file, data);
|
78 | return file;
|
79 | }
|
80 | computeDesktopEntry(targetSpecificOptions, exec, extra) {
|
81 | if (exec != null && exec.length === 0) {
|
82 | throw new Error("Specified exec is empty");
|
83 | }
|
84 |
|
85 | if (targetSpecificOptions.desktop != null && targetSpecificOptions.desktop.Exec != null) {
|
86 | throw new Error("Please specify executable name as linux.executableName instead of linux.desktop.Exec");
|
87 | }
|
88 | const packager = this.packager;
|
89 | const appInfo = packager.appInfo;
|
90 | const executableArgs = targetSpecificOptions.executableArgs;
|
91 | if (exec == null) {
|
92 | exec = `${exports.installPrefix}/${appInfo.sanitizedProductName}/${packager.executableName}`;
|
93 | if (!/^[/0-9A-Za-z._-]+$/.test(exec)) {
|
94 | exec = `"${exec}"`;
|
95 | }
|
96 | if (executableArgs) {
|
97 | exec += " ";
|
98 | exec += executableArgs.join(" ");
|
99 | }
|
100 |
|
101 | const execCodes = ["%f", "%u", "%F", "%U"];
|
102 | if (executableArgs == null || executableArgs.findIndex(arg => execCodes.includes(arg)) === -1) {
|
103 | exec += " %U";
|
104 | }
|
105 | }
|
106 | const desktopMeta = {
|
107 | Name: appInfo.productName,
|
108 | Exec: exec,
|
109 | Terminal: "false",
|
110 | Type: "Application",
|
111 | Icon: packager.executableName,
|
112 |
|
113 |
|
114 |
|
115 |
|
116 |
|
117 | StartupWMClass: appInfo.productName,
|
118 | ...extra,
|
119 | ...targetSpecificOptions.desktop,
|
120 | };
|
121 | const description = this.getDescription(targetSpecificOptions);
|
122 | if (!(0, builder_util_1.isEmptyOrSpaces)(description)) {
|
123 | desktopMeta.Comment = description;
|
124 | }
|
125 | const mimeTypes = (0, builder_util_1.asArray)(targetSpecificOptions.mimeTypes);
|
126 | for (const fileAssociation of packager.fileAssociations) {
|
127 | if (fileAssociation.mimeType != null) {
|
128 | mimeTypes.push(fileAssociation.mimeType);
|
129 | }
|
130 | }
|
131 | for (const protocol of (0, builder_util_1.asArray)(packager.config.protocols).concat((0, builder_util_1.asArray)(packager.platformSpecificBuildOptions.protocols))) {
|
132 | for (const scheme of (0, builder_util_1.asArray)(protocol.schemes)) {
|
133 | mimeTypes.push(`x-scheme-handler/${scheme}`);
|
134 | }
|
135 | }
|
136 | if (mimeTypes.length !== 0) {
|
137 | desktopMeta.MimeType = mimeTypes.join(";") + ";";
|
138 | }
|
139 | let category = targetSpecificOptions.category;
|
140 | if ((0, builder_util_1.isEmptyOrSpaces)(category)) {
|
141 | const macCategory = (packager.config.mac || {}).category;
|
142 | if (macCategory != null) {
|
143 | category = macToLinuxCategory[macCategory];
|
144 | }
|
145 | if (category == null) {
|
146 |
|
147 | if (macCategory != null) {
|
148 | builder_util_1.log.warn({ macCategory }, "cannot map macOS category to Linux. If possible mapping is known for you, please file issue to add it.");
|
149 | }
|
150 | builder_util_1.log.warn({
|
151 | reason: "linux.category is not set and cannot map from macOS",
|
152 | docs: "https://www.electron.build/configuration/linux",
|
153 | }, 'application Linux category is set to default "Utility"');
|
154 | category = "Utility";
|
155 | }
|
156 | }
|
157 | desktopMeta.Categories = `${category}${category.endsWith(";") ? "" : ";"}`;
|
158 | let data = `[Desktop Entry]`;
|
159 | for (const name of Object.keys(desktopMeta)) {
|
160 | data += `\n${name}=${desktopMeta[name]}`;
|
161 | }
|
162 | data += "\n";
|
163 | return Promise.resolve(data);
|
164 | }
|
165 | }
|
166 | exports.LinuxTargetHelper = LinuxTargetHelper;
|
167 | const macToLinuxCategory = {
|
168 | "public.app-category.graphics-design": "Graphics",
|
169 | "public.app-category.developer-tools": "Development",
|
170 | "public.app-category.education": "Education",
|
171 | "public.app-category.games": "Game",
|
172 | "public.app-category.video": "Video;AudioVideo",
|
173 | "public.app-category.utilities": "Utility",
|
174 | "public.app-category.social-networking": "Network;Chat",
|
175 | "public.app-category.finance": "Office;Finance",
|
176 | };
|
177 |
|
\ | No newline at end of file |