1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | exports.computeDefaultAppDirectory = exports.validateConfiguration = exports.doMergeConfigs = exports.getConfig = void 0;
|
4 | const builder_util_1 = require("builder-util");
|
5 | const fs_1 = require("builder-util/out/fs");
|
6 | const fs_extra_1 = require("fs-extra");
|
7 | const lazy_val_1 = require("lazy-val");
|
8 | const path = require("path");
|
9 | const read_config_file_1 = require("read-config-file");
|
10 | const rectCra_1 = require("../presets/rectCra");
|
11 | const version_1 = require("../version");
|
12 |
|
13 | const validateSchema = require("@develar/schema-utils");
|
14 |
|
15 | function mergePublish(config, configFromOptions) {
|
16 |
|
17 | const publish = Array.isArray(config.publish) ? configFromOptions.publish : null;
|
18 | if (publish != null) {
|
19 | delete configFromOptions.publish;
|
20 | }
|
21 | (0, builder_util_1.deepAssign)(config, configFromOptions);
|
22 | if (publish == null) {
|
23 | return;
|
24 | }
|
25 | const listOnDisk = config.publish;
|
26 | if (listOnDisk.length === 0) {
|
27 | config.publish = publish;
|
28 | }
|
29 | else {
|
30 |
|
31 | Object.assign(listOnDisk[0], publish);
|
32 | }
|
33 | }
|
34 | async function getConfig(projectDir, configPath, configFromOptions, packageMetadata = new lazy_val_1.Lazy(() => (0, read_config_file_1.orNullIfFileNotExist)((0, fs_extra_1.readJson)(path.join(projectDir, "package.json"))))) {
|
35 | const configRequest = { packageKey: "build", configFilename: "electron-builder", projectDir, packageMetadata };
|
36 | const configAndEffectiveFile = await (0, read_config_file_1.getConfig)(configRequest, configPath);
|
37 | const config = configAndEffectiveFile == null ? {} : configAndEffectiveFile.result;
|
38 | if (configFromOptions != null) {
|
39 | mergePublish(config, configFromOptions);
|
40 | }
|
41 | if (configAndEffectiveFile != null) {
|
42 | builder_util_1.log.info({ file: configAndEffectiveFile.configFile == null ? 'package.json ("build" field)' : configAndEffectiveFile.configFile }, "loaded configuration");
|
43 | }
|
44 | if (config.extends == null && config.extends !== null) {
|
45 | const metadata = (await packageMetadata.value) || {};
|
46 | const devDependencies = metadata.devDependencies;
|
47 | const dependencies = metadata.dependencies;
|
48 | if ((dependencies != null && "react-scripts" in dependencies) || (devDependencies != null && "react-scripts" in devDependencies)) {
|
49 | config.extends = "react-cra";
|
50 | }
|
51 | else if (devDependencies != null && "electron-webpack" in devDependencies) {
|
52 | let file = "electron-webpack/out/electron-builder.js";
|
53 | try {
|
54 | file = require.resolve(file);
|
55 | }
|
56 | catch (ignore) {
|
57 | file = require.resolve("electron-webpack/electron-builder.yml");
|
58 | }
|
59 | config.extends = `file:${file}`;
|
60 | }
|
61 | }
|
62 | const parentConfigs = await loadParentConfigsRecursively(config.extends, async (configExtend) => {
|
63 | if (configExtend === "react-cra") {
|
64 | const result = await (0, rectCra_1.reactCra)(projectDir);
|
65 | builder_util_1.log.info({ preset: configExtend }, "loaded parent configuration");
|
66 | return result;
|
67 | }
|
68 | else {
|
69 | const { configFile, result } = await (0, read_config_file_1.loadParentConfig)(configRequest, configExtend);
|
70 | builder_util_1.log.info({ file: configFile }, "loaded parent configuration");
|
71 | return result;
|
72 | }
|
73 | });
|
74 | return doMergeConfigs([...parentConfigs, config]);
|
75 | }
|
76 | exports.getConfig = getConfig;
|
77 | function asArray(value) {
|
78 | return Array.isArray(value) ? value : typeof value === "string" ? [value] : [];
|
79 | }
|
80 | async function loadParentConfigsRecursively(configExtends, loader) {
|
81 | const configs = [];
|
82 | for (const configExtend of asArray(configExtends)) {
|
83 | const result = await loader(configExtend);
|
84 | const parentConfigs = await loadParentConfigsRecursively(result.extends, loader);
|
85 | configs.push(...parentConfigs, result);
|
86 | }
|
87 | return configs;
|
88 | }
|
89 |
|
90 | function normalizeFiles(configuration, name) {
|
91 | let value = configuration[name];
|
92 | if (value == null) {
|
93 | return;
|
94 | }
|
95 | if (!Array.isArray(value)) {
|
96 | value = [value];
|
97 | }
|
98 | itemLoop: for (let i = 0; i < value.length; i++) {
|
99 | let item = value[i];
|
100 | if (typeof item === "string") {
|
101 |
|
102 | if (i !== 0) {
|
103 | let prevItemIndex = i - 1;
|
104 | let prevItem;
|
105 | do {
|
106 | prevItem = value[prevItemIndex--];
|
107 | } while (prevItem == null);
|
108 | if (prevItem.from == null && prevItem.to == null) {
|
109 | if (prevItem.filter == null) {
|
110 | prevItem.filter = [item];
|
111 | }
|
112 | else {
|
113 | ;
|
114 | prevItem.filter.push(item);
|
115 | }
|
116 | value[i] = null;
|
117 | continue itemLoop;
|
118 | }
|
119 | }
|
120 | item = {
|
121 | filter: [item],
|
122 | };
|
123 | value[i] = item;
|
124 | }
|
125 | else if (Array.isArray(item)) {
|
126 | throw new Error(`${name} configuration is invalid, nested array not expected for index ${i}: ${item}`);
|
127 | }
|
128 |
|
129 | if (item.from === ".") {
|
130 | item.from = undefined;
|
131 | }
|
132 | if (item.to === ".") {
|
133 | item.to = undefined;
|
134 | }
|
135 | if (item.filter != null && typeof item.filter === "string") {
|
136 | item.filter = [item.filter];
|
137 | }
|
138 | }
|
139 | configuration[name] = value.filter(it => it != null);
|
140 | }
|
141 | function isSimilarFileSet(value, other) {
|
142 | return value.from === other.from && value.to === other.to;
|
143 | }
|
144 | function mergeFilters(value, other) {
|
145 | return asArray(value).concat(asArray(other));
|
146 | }
|
147 | function mergeFileSets(lists) {
|
148 | const result = [];
|
149 | for (const list of lists) {
|
150 | for (const item of list) {
|
151 | const existingItem = result.find(i => isSimilarFileSet(i, item));
|
152 | if (existingItem) {
|
153 | existingItem.filter = mergeFilters(item.filter, existingItem.filter);
|
154 | }
|
155 | else {
|
156 | result.push(item);
|
157 | }
|
158 | }
|
159 | }
|
160 | return result;
|
161 | }
|
162 |
|
163 |
|
164 |
|
165 |
|
166 | function doMergeConfigs(configs) {
|
167 | for (const config of configs) {
|
168 | normalizeFiles(config, "files");
|
169 | normalizeFiles(config, "extraFiles");
|
170 | normalizeFiles(config, "extraResources");
|
171 | }
|
172 | const result = (0, builder_util_1.deepAssign)(getDefaultConfig(), ...configs);
|
173 |
|
174 |
|
175 |
|
176 | configs = configs.slice().reverse();
|
177 | result.files = mergeFileSets(configs.map(config => { var _a; return ((_a = config.files) !== null && _a !== void 0 ? _a : []); }));
|
178 | return result;
|
179 | }
|
180 | exports.doMergeConfigs = doMergeConfigs;
|
181 | function getDefaultConfig() {
|
182 | return {
|
183 | directories: {
|
184 | output: "dist",
|
185 | buildResources: "build",
|
186 | },
|
187 | };
|
188 | }
|
189 | const schemeDataPromise = new lazy_val_1.Lazy(() => (0, fs_extra_1.readJson)(path.join(__dirname, "..", "..", "scheme.json")));
|
190 | async function validateConfiguration(config, debugLogger) {
|
191 | const extraMetadata = config.extraMetadata;
|
192 | if (extraMetadata != null) {
|
193 | if (extraMetadata.build != null) {
|
194 | throw new builder_util_1.InvalidConfigurationError(`--em.build is deprecated, please specify as -c"`);
|
195 | }
|
196 | if (extraMetadata.directories != null) {
|
197 | throw new builder_util_1.InvalidConfigurationError(`--em.directories is deprecated, please specify as -c.directories"`);
|
198 | }
|
199 | }
|
200 | const oldConfig = config;
|
201 | if (oldConfig.npmSkipBuildFromSource === false) {
|
202 | throw new builder_util_1.InvalidConfigurationError(`npmSkipBuildFromSource is deprecated, please use buildDependenciesFromSource"`);
|
203 | }
|
204 | if (oldConfig.appImage != null && oldConfig.appImage.systemIntegration != null) {
|
205 | throw new builder_util_1.InvalidConfigurationError(`appImage.systemIntegration is deprecated, https://github.com/TheAssassin/AppImageLauncher is used for desktop integration"`);
|
206 | }
|
207 |
|
208 | validateSchema(await schemeDataPromise.value, config, {
|
209 | name: `electron-builder ${version_1.PACKAGE_VERSION}`,
|
210 | postFormatter: (formattedError, error) => {
|
211 | if (debugLogger.isEnabled) {
|
212 | debugLogger.add("invalidConfig", (0, builder_util_1.safeStringifyJson)(error));
|
213 | }
|
214 | const site = "https://www.electron.build";
|
215 | let url = `${site}/configuration/configuration`;
|
216 | const targets = new Set(["mac", "dmg", "pkg", "mas", "win", "nsis", "appx", "linux", "appimage", "snap"]);
|
217 | const dataPath = error.dataPath == null ? null : error.dataPath;
|
218 | const targetPath = dataPath.startsWith(".") ? dataPath.substr(1).toLowerCase() : null;
|
219 | if (targetPath != null && targets.has(targetPath)) {
|
220 | url = `${site}/configuration/${targetPath}`;
|
221 | }
|
222 | return `${formattedError}\n How to fix:
|
223 | 1. Open ${url}
|
224 | 2. Search the option name on the page (or type in into Search to find across the docs).
|
225 | * Not found? The option was deprecated or not exists (check spelling).
|
226 | * Found? Check that the option in the appropriate place. e.g. "title" only in the "dmg", not in the root.
|
227 | `;
|
228 | },
|
229 | });
|
230 | }
|
231 | exports.validateConfiguration = validateConfiguration;
|
232 | const DEFAULT_APP_DIR_NAMES = ["app", "www"];
|
233 | async function computeDefaultAppDirectory(projectDir, userAppDir) {
|
234 | if (userAppDir != null) {
|
235 | const absolutePath = path.resolve(projectDir, userAppDir);
|
236 | const stat = await (0, fs_1.statOrNull)(absolutePath);
|
237 | if (stat == null) {
|
238 | throw new builder_util_1.InvalidConfigurationError(`Application directory ${userAppDir} doesn't exist`);
|
239 | }
|
240 | else if (!stat.isDirectory()) {
|
241 | throw new builder_util_1.InvalidConfigurationError(`Application directory ${userAppDir} is not a directory`);
|
242 | }
|
243 | else if (projectDir === absolutePath) {
|
244 | builder_util_1.log.warn({ appDirectory: userAppDir }, `Specified application directory equals to project dir — superfluous or wrong configuration`);
|
245 | }
|
246 | return absolutePath;
|
247 | }
|
248 | for (const dir of DEFAULT_APP_DIR_NAMES) {
|
249 | const absolutePath = path.join(projectDir, dir);
|
250 | const packageJson = path.join(absolutePath, "package.json");
|
251 | const stat = await (0, fs_1.statOrNull)(packageJson);
|
252 | if (stat != null && stat.isFile()) {
|
253 | return absolutePath;
|
254 | }
|
255 | }
|
256 | return projectDir;
|
257 | }
|
258 | exports.computeDefaultAppDirectory = computeDefaultAppDirectory;
|
259 |
|
\ | No newline at end of file |