@netlify/config 18.2.4 → 18.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/bin.js +5 -0
  2. package/lib/api/build_settings.js +20 -33
  3. package/lib/api/client.js +10 -13
  4. package/lib/api/site_info.js +48 -56
  5. package/lib/base.js +10 -18
  6. package/lib/bin/flags.js +134 -142
  7. package/lib/bin/main.js +49 -63
  8. package/lib/build_dir.js +11 -15
  9. package/lib/cached_config.js +14 -17
  10. package/lib/case.js +16 -35
  11. package/lib/context.js +62 -84
  12. package/lib/default.js +18 -22
  13. package/lib/env/envelope.js +23 -23
  14. package/lib/env/git.js +18 -18
  15. package/lib/env/main.js +127 -179
  16. package/lib/error.js +19 -27
  17. package/lib/events.js +18 -19
  18. package/lib/files.js +63 -87
  19. package/lib/functions_config.js +36 -52
  20. package/lib/headers.js +17 -27
  21. package/lib/inline_config.js +6 -7
  22. package/lib/log/cleanup.js +54 -82
  23. package/lib/log/logger.js +25 -36
  24. package/lib/log/main.js +31 -40
  25. package/lib/log/messages.js +56 -95
  26. package/lib/log/options.js +24 -38
  27. package/lib/log/serialize.js +3 -4
  28. package/lib/log/theme.js +10 -11
  29. package/lib/main.js +188 -263
  30. package/lib/merge.js +25 -35
  31. package/lib/merge_normalize.js +17 -24
  32. package/lib/mutations/apply.js +53 -65
  33. package/lib/mutations/config_prop_name.js +6 -8
  34. package/lib/mutations/update.js +79 -98
  35. package/lib/normalize.js +24 -28
  36. package/lib/options/base.js +39 -51
  37. package/lib/options/branch.js +23 -26
  38. package/lib/options/feature_flags.js +7 -10
  39. package/lib/options/main.js +76 -96
  40. package/lib/options/repository_root.js +11 -16
  41. package/lib/origin.js +22 -29
  42. package/lib/parse.js +42 -55
  43. package/lib/path.js +29 -40
  44. package/lib/redirects.js +16 -26
  45. package/lib/simplify.js +66 -92
  46. package/lib/utils/group.js +5 -6
  47. package/lib/utils/remove_falsy.js +9 -13
  48. package/lib/utils/set.js +19 -25
  49. package/lib/utils/toml.js +13 -16
  50. package/lib/validate/context.js +24 -43
  51. package/lib/validate/example.js +20 -27
  52. package/lib/validate/helpers.js +17 -23
  53. package/lib/validate/identical.js +8 -12
  54. package/lib/validate/main.js +83 -127
  55. package/lib/validate/validations.js +243 -257
  56. package/package.json +13 -8
@@ -1,43 +1,29 @@
1
- import { DEFAULT_FEATURE_FLAGS } from '../options/feature_flags.js'
2
- import { removeEmptyArray } from '../simplify.js'
3
- import { removeFalsy } from '../utils/remove_falsy.js'
4
-
1
+ import { DEFAULT_FEATURE_FLAGS } from '../options/feature_flags.js';
2
+ import { removeEmptyArray } from '../simplify.js';
3
+ import { removeFalsy } from '../utils/remove_falsy.js';
5
4
  // Use an allowlist to prevent printing confidential values.
6
- export const cleanupConfigOpts = function ({
7
- config,
8
- cwd,
9
- context,
10
- branch,
11
- mode,
12
- repositoryRoot,
13
- siteId,
14
- baseRelDir,
15
- env = {},
16
- featureFlags = {},
17
- }) {
18
- const envA = Object.keys(env)
19
- return removeFalsy({
20
- config,
21
- cwd,
22
- context,
23
- branch,
24
- mode,
25
- repositoryRoot,
26
- siteId,
27
- baseRelDir,
28
- ...removeEmptyArray(envA, 'env'),
29
- featureFlags: cleanFeatureFlags(featureFlags),
30
- })
31
- }
32
-
5
+ export const cleanupConfigOpts = function ({ config, cwd, context, branch, mode, repositoryRoot, siteId, baseRelDir, env = {}, featureFlags = {}, }) {
6
+ const envA = Object.keys(env);
7
+ return removeFalsy({
8
+ config,
9
+ cwd,
10
+ context,
11
+ branch,
12
+ mode,
13
+ repositoryRoot,
14
+ siteId,
15
+ baseRelDir,
16
+ ...removeEmptyArray(envA, 'env'),
17
+ featureFlags: cleanFeatureFlags(featureFlags),
18
+ });
19
+ };
33
20
  // We only show feature flags related to `@netlify/config`.
34
21
  // Also, we only print enabled feature flags.
35
22
  const cleanFeatureFlags = function (featureFlags) {
36
- return Object.entries(featureFlags)
37
- .filter(shouldPrintFeatureFlag)
38
- .map(([featureFlagName]) => featureFlagName)
39
- }
40
-
23
+ return Object.entries(featureFlags)
24
+ .filter(shouldPrintFeatureFlag)
25
+ .map(([featureFlagName]) => featureFlagName);
26
+ };
41
27
  const shouldPrintFeatureFlag = function ([featureFlagName, enabled]) {
42
- return enabled && featureFlagName in DEFAULT_FEATURE_FLAGS
43
- }
28
+ return enabled && featureFlagName in DEFAULT_FEATURE_FLAGS;
29
+ };
@@ -1,5 +1,4 @@
1
- import { dump } from 'js-yaml'
2
-
1
+ import { dump } from 'js-yaml';
3
2
  export const serializeObject = function (object) {
4
- return dump(object, { noRefs: true, sortKeys: true, lineWidth: Number.POSITIVE_INFINITY }).trimEnd()
5
- }
3
+ return dump(object, { noRefs: true, sortKeys: true, lineWidth: Number.POSITIVE_INFINITY }).trimEnd();
4
+ };
package/lib/log/theme.js CHANGED
@@ -1,14 +1,13 @@
1
- import chalk from 'chalk'
2
-
1
+ import chalk from 'chalk';
3
2
  // Color theme. Please use this instead of requiring chalk directly, to ensure
4
3
  // consistent colors.
5
4
  export const THEME = {
6
- // Single lines used as subheaders
7
- subHeader: chalk.cyan.bold,
8
- // Single lines used as subheaders indicating an error
9
- errorSubHeader: chalk.red.bold,
10
- // Same for warnings
11
- warningLine: chalk.yellowBright,
12
- // One of several words that should be highlighted inside a line
13
- highlightWords: chalk.cyan,
14
- }
5
+ // Single lines used as subheaders
6
+ subHeader: chalk.cyan.bold,
7
+ // Single lines used as subheaders indicating an error
8
+ errorSubHeader: chalk.red.bold,
9
+ // Same for warnings
10
+ warningLine: chalk.yellowBright,
11
+ // One of several words that should be highlighted inside a line
12
+ highlightWords: chalk.cyan,
13
+ };
package/lib/main.js CHANGED
@@ -1,254 +1,183 @@
1
- import { getApiClient } from './api/client.js'
2
- import { getSiteInfo } from './api/site_info.js'
3
- import { getInitialBase, getBase, addBase } from './base.js'
4
- import { getBuildDir } from './build_dir.js'
5
- import { getCachedConfig } from './cached_config.js'
6
- import { normalizeContextProps, mergeContext } from './context.js'
7
- import { parseDefaultConfig } from './default.js'
8
- import { getEnv } from './env/main.js'
9
- import { resolveConfigPaths } from './files.js'
10
- import { getHeadersPath, addHeaders } from './headers.js'
11
- import { getInlineConfig } from './inline_config.js'
12
- import { logResult } from './log/main.js'
13
- import { mergeConfigs } from './merge.js'
14
- import { normalizeBeforeConfigMerge, normalizeAfterConfigMerge } from './merge_normalize.js'
15
- import { addDefaultOpts, normalizeOpts } from './options/main.js'
16
- import { UI_ORIGIN, CONFIG_ORIGIN, INLINE_ORIGIN } from './origin.js'
17
- import { parseConfig } from './parse.js'
18
- import { getConfigPath } from './path.js'
19
- import { getRedirectsPath, addRedirects } from './redirects.js'
20
-
21
- export { DEV_EVENTS, EVENTS } from './events.js'
22
- export { cleanupConfig } from './log/cleanup.js'
23
- // eslint-disable-next-line import/max-dependencies
24
- export { updateConfig, restoreConfig } from './mutations/update.js'
25
-
1
+ import { getApiClient } from './api/client.js';
2
+ import { getSiteInfo } from './api/site_info.js';
3
+ import { getInitialBase, getBase, addBase } from './base.js';
4
+ import { getBuildDir } from './build_dir.js';
5
+ import { getCachedConfig } from './cached_config.js';
6
+ import { normalizeContextProps, mergeContext } from './context.js';
7
+ import { parseDefaultConfig } from './default.js';
8
+ import { getEnv } from './env/main.js';
9
+ import { resolveConfigPaths } from './files.js';
10
+ import { getHeadersPath, addHeaders } from './headers.js';
11
+ import { getInlineConfig } from './inline_config.js';
12
+ import { logResult } from './log/main.js';
13
+ import { mergeConfigs } from './merge.js';
14
+ import { normalizeBeforeConfigMerge, normalizeAfterConfigMerge } from './merge_normalize.js';
15
+ import { addDefaultOpts, normalizeOpts } from './options/main.js';
16
+ import { UI_ORIGIN, CONFIG_ORIGIN, INLINE_ORIGIN } from './origin.js';
17
+ import { parseConfig } from './parse.js';
18
+ import { getConfigPath } from './path.js';
19
+ import { getRedirectsPath, addRedirects } from './redirects.js';
20
+ export { DEV_EVENTS, EVENTS } from './events.js';
21
+ export { cleanupConfig } from './log/cleanup.js';
22
+ export { updateConfig, restoreConfig } from './mutations/update.js';
26
23
  // Load the configuration file.
27
24
  // Takes an optional configuration file path as input and return the resolved
28
25
  // `config` together with related properties such as the `configPath`.
29
26
  export const resolveConfig = async function (opts) {
30
- const { cachedConfig, cachedConfigPath, host, scheme, pathPrefix, testOpts, token, offline, ...optsA } =
31
- addDefaultOpts(opts)
32
- // `api` is not JSON-serializable, so we cannot cache it inside `cachedConfig`
33
- const api = getApiClient({ token, offline, host, scheme, pathPrefix, testOpts })
34
-
35
- const parsedCachedConfig = await getCachedConfig({ cachedConfig, cachedConfigPath, token, api })
36
- if (parsedCachedConfig !== undefined) {
37
- return parsedCachedConfig
38
- }
39
-
40
- const {
41
- config: configOpt,
42
- defaultConfig,
43
- inlineConfig,
44
- configMutations,
45
- cwd,
46
- context,
47
- repositoryRoot,
48
- base,
49
- branch,
50
- siteId,
51
- deployId,
52
- buildId,
53
- baseRelDir,
54
- mode,
55
- debug,
56
- logs,
57
- featureFlags,
58
- } = await normalizeOpts(optsA)
59
-
60
- const { siteInfo, accounts, addons } = await getSiteInfo({ api, siteId, mode, testOpts })
61
-
62
- const { defaultConfig: defaultConfigA, baseRelDir: baseRelDirA } = parseDefaultConfig({
63
- defaultConfig,
64
- base,
65
- baseRelDir,
66
- siteInfo,
67
- logs,
68
- debug,
69
- })
70
- const inlineConfigA = getInlineConfig({ inlineConfig, configMutations, logs, debug })
71
-
72
- const { configPath, config, buildDir, redirectsPath, headersPath } = await loadConfig({
73
- configOpt,
74
- cwd,
75
- context,
76
- repositoryRoot,
77
- branch,
78
- defaultConfig: defaultConfigA,
79
- inlineConfig: inlineConfigA,
80
- baseRelDir: baseRelDirA,
81
- logs,
82
- featureFlags,
83
- })
84
-
85
- const env = await getEnv({
86
- api,
87
- mode,
88
- config,
89
- siteInfo,
90
- accounts,
91
- addons,
92
- buildDir,
93
- branch,
94
- deployId,
95
- buildId,
96
- context,
97
- })
98
-
99
- // @todo Remove in the next major version.
100
- const configA = addLegacyFunctionsDirectory(config)
101
-
102
- const result = {
103
- siteInfo,
104
- accounts,
105
- addons,
106
- env,
107
- configPath,
108
- redirectsPath,
109
- headersPath,
110
- buildDir,
111
- repositoryRoot,
112
- config: configA,
113
- context,
114
- branch,
115
- token,
116
- api,
117
- logs,
118
- }
119
- logResult(result, { logs, debug })
120
- return result
121
- }
122
-
27
+ const { cachedConfig, cachedConfigPath, host, scheme, pathPrefix, testOpts, token, offline, ...optsA } = addDefaultOpts(opts);
28
+ // `api` is not JSON-serializable, so we cannot cache it inside `cachedConfig`
29
+ const api = getApiClient({ token, offline, host, scheme, pathPrefix, testOpts });
30
+ const parsedCachedConfig = await getCachedConfig({ cachedConfig, cachedConfigPath, token, api });
31
+ if (parsedCachedConfig !== undefined) {
32
+ return parsedCachedConfig;
33
+ }
34
+ const { config: configOpt, defaultConfig, inlineConfig, configMutations, cwd, context, repositoryRoot, base, branch, siteId, deployId, buildId, baseRelDir, mode, debug, logs, featureFlags, } = await normalizeOpts(optsA);
35
+ const { siteInfo, accounts, addons } = await getSiteInfo({ api, siteId, mode, testOpts });
36
+ const { defaultConfig: defaultConfigA, baseRelDir: baseRelDirA } = parseDefaultConfig({
37
+ defaultConfig,
38
+ base,
39
+ baseRelDir,
40
+ siteInfo,
41
+ logs,
42
+ debug,
43
+ });
44
+ const inlineConfigA = getInlineConfig({ inlineConfig, configMutations, logs, debug });
45
+ const { configPath, config, buildDir, redirectsPath, headersPath } = await loadConfig({
46
+ configOpt,
47
+ cwd,
48
+ context,
49
+ repositoryRoot,
50
+ branch,
51
+ defaultConfig: defaultConfigA,
52
+ inlineConfig: inlineConfigA,
53
+ baseRelDir: baseRelDirA,
54
+ logs,
55
+ featureFlags,
56
+ });
57
+ const env = await getEnv({
58
+ api,
59
+ mode,
60
+ config,
61
+ siteInfo,
62
+ accounts,
63
+ addons,
64
+ buildDir,
65
+ branch,
66
+ deployId,
67
+ buildId,
68
+ context,
69
+ });
70
+ // @todo Remove in the next major version.
71
+ const configA = addLegacyFunctionsDirectory(config);
72
+ const result = {
73
+ siteInfo,
74
+ accounts,
75
+ addons,
76
+ env,
77
+ configPath,
78
+ redirectsPath,
79
+ headersPath,
80
+ buildDir,
81
+ repositoryRoot,
82
+ config: configA,
83
+ context,
84
+ branch,
85
+ token,
86
+ api,
87
+ logs,
88
+ };
89
+ logResult(result, { logs, debug });
90
+ return result;
91
+ };
123
92
  // Adds a `build.functions` property that mirrors `functionsDirectory`, for
124
93
  // backward compatibility.
125
94
  const addLegacyFunctionsDirectory = (config) => {
126
- if (!config.functionsDirectory) {
127
- return config
128
- }
129
-
130
- return {
131
- ...config,
132
- build: {
133
- ...config.build,
134
- functions: config.functionsDirectory,
135
- },
136
- }
137
- }
138
-
95
+ if (!config.functionsDirectory) {
96
+ return config;
97
+ }
98
+ return {
99
+ ...config,
100
+ build: {
101
+ ...config.build,
102
+ functions: config.functionsDirectory,
103
+ },
104
+ };
105
+ };
139
106
  // Try to load the configuration file in two passes.
140
107
  // The first pass uses the `defaultConfig`'s `build.base` (if defined).
141
108
  // The second pass uses the `build.base` from the first pass (if defined).
142
- const loadConfig = async function ({
143
- configOpt,
144
- cwd,
145
- context,
146
- repositoryRoot,
147
- branch,
148
- defaultConfig,
149
- inlineConfig,
150
- baseRelDir,
151
- logs,
152
- featureFlags,
153
- }) {
154
- const initialBase = getInitialBase({ repositoryRoot, defaultConfig, inlineConfig })
155
- const { configPath, config, buildDir, base, redirectsPath, headersPath } = await getFullConfig({
156
- configOpt,
157
- cwd,
158
- context,
159
- repositoryRoot,
160
- branch,
161
- defaultConfig,
162
- inlineConfig,
163
- baseRelDir,
164
- configBase: initialBase,
165
- logs,
166
- featureFlags,
167
- })
168
-
169
- // No second pass needed if:
170
- // - there is no `build.base` (in which case both `base` and `initialBase`
171
- // are `undefined`)
172
- // - `build.base` is the same as the `Base directory` UI setting (already
173
- // used in the first round)
174
- // - `baseRelDir` feature flag is not used. This feature flag was introduced
175
- // to ensure backward compatibility.
176
- if (!baseRelDir || base === initialBase) {
177
- return { configPath, config, buildDir, redirectsPath, headersPath }
178
- }
179
-
180
- const {
181
- configPath: configPathA,
182
- config: configA,
183
- buildDir: buildDirA,
184
- redirectsPath: redirectsPathA,
185
- headersPath: headersPathA,
186
- } = await getFullConfig({
187
- cwd,
188
- context,
189
- repositoryRoot,
190
- branch,
191
- defaultConfig,
192
- inlineConfig,
193
- baseRelDir,
194
- configBase: base,
195
- base,
196
- logs,
197
- featureFlags,
198
- })
199
- return {
200
- configPath: configPathA,
201
- config: configA,
202
- buildDir: buildDirA,
203
- redirectsPath: redirectsPathA,
204
- headersPath: headersPathA,
205
- }
206
- }
207
-
109
+ const loadConfig = async function ({ configOpt, cwd, context, repositoryRoot, branch, defaultConfig, inlineConfig, baseRelDir, logs, featureFlags, }) {
110
+ const initialBase = getInitialBase({ repositoryRoot, defaultConfig, inlineConfig });
111
+ const { configPath, config, buildDir, base, redirectsPath, headersPath } = await getFullConfig({
112
+ configOpt,
113
+ cwd,
114
+ context,
115
+ repositoryRoot,
116
+ branch,
117
+ defaultConfig,
118
+ inlineConfig,
119
+ baseRelDir,
120
+ configBase: initialBase,
121
+ logs,
122
+ featureFlags,
123
+ });
124
+ // No second pass needed if:
125
+ // - there is no `build.base` (in which case both `base` and `initialBase`
126
+ // are `undefined`)
127
+ // - `build.base` is the same as the `Base directory` UI setting (already
128
+ // used in the first round)
129
+ // - `baseRelDir` feature flag is not used. This feature flag was introduced
130
+ // to ensure backward compatibility.
131
+ if (!baseRelDir || base === initialBase) {
132
+ return { configPath, config, buildDir, redirectsPath, headersPath };
133
+ }
134
+ const { configPath: configPathA, config: configA, buildDir: buildDirA, redirectsPath: redirectsPathA, headersPath: headersPathA, } = await getFullConfig({
135
+ cwd,
136
+ context,
137
+ repositoryRoot,
138
+ branch,
139
+ defaultConfig,
140
+ inlineConfig,
141
+ baseRelDir,
142
+ configBase: base,
143
+ base,
144
+ logs,
145
+ featureFlags,
146
+ });
147
+ return {
148
+ configPath: configPathA,
149
+ config: configA,
150
+ buildDir: buildDirA,
151
+ redirectsPath: redirectsPathA,
152
+ headersPath: headersPathA,
153
+ };
154
+ };
208
155
  // Load configuration file and normalize it, merge contexts, etc.
209
- const getFullConfig = async function ({
210
- configOpt,
211
- cwd,
212
- context,
213
- repositoryRoot,
214
- branch,
215
- defaultConfig,
216
- inlineConfig,
217
- baseRelDir,
218
- configBase,
219
- base,
220
- logs,
221
- featureFlags,
222
- }) {
223
- const configPath = await getConfigPath({ configOpt, cwd, repositoryRoot, configBase })
224
-
225
- try {
226
- const config = await parseConfig(configPath)
227
- const configA = mergeAndNormalizeConfig({
228
- config,
229
- defaultConfig,
230
- inlineConfig,
231
- context,
232
- branch,
233
- logs,
234
- })
235
- const {
236
- config: configB,
237
- buildDir,
238
- base: baseA,
239
- } = await resolveFiles({ config: configA, repositoryRoot, base, baseRelDir })
240
- const headersPath = getHeadersPath(configB)
241
- const configC = await addHeaders({ config: configB, headersPath, logs, featureFlags })
242
- const redirectsPath = getRedirectsPath(configC)
243
- const configD = await addRedirects({ config: configC, redirectsPath, logs, featureFlags })
244
- return { configPath, config: configD, buildDir, base: baseA, redirectsPath, headersPath }
245
- } catch (error) {
246
- const configName = configPath === undefined ? '' : ` file ${configPath}`
247
- error.message = `When resolving config${configName}:\n${error.message}`
248
- throw error
249
- }
250
- }
251
-
156
+ const getFullConfig = async function ({ configOpt, cwd, context, repositoryRoot, branch, defaultConfig, inlineConfig, baseRelDir, configBase, base, logs, featureFlags, }) {
157
+ const configPath = await getConfigPath({ configOpt, cwd, repositoryRoot, configBase });
158
+ try {
159
+ const config = await parseConfig(configPath);
160
+ const configA = mergeAndNormalizeConfig({
161
+ config,
162
+ defaultConfig,
163
+ inlineConfig,
164
+ context,
165
+ branch,
166
+ logs,
167
+ });
168
+ const { config: configB, buildDir, base: baseA, } = await resolveFiles({ config: configA, repositoryRoot, base, baseRelDir });
169
+ const headersPath = getHeadersPath(configB);
170
+ const configC = await addHeaders({ config: configB, headersPath, logs, featureFlags });
171
+ const redirectsPath = getRedirectsPath(configC);
172
+ const configD = await addRedirects({ config: configC, redirectsPath, logs, featureFlags });
173
+ return { configPath, config: configD, buildDir, base: baseA, redirectsPath, headersPath };
174
+ }
175
+ catch (error) {
176
+ const configName = configPath === undefined ? '' : ` file ${configPath}`;
177
+ error.message = `When resolving config${configName}:\n${error.message}`;
178
+ throw error;
179
+ }
180
+ };
252
181
  // Merge:
253
182
  // - `--defaultConfig`: UI build settings and UI-installed plugins
254
183
  // - `inlineConfig`: Netlify CLI flags
@@ -257,29 +186,25 @@ const getFullConfig = async function ({
257
186
  // Those need to be done at different stages depending on whether they should
258
187
  // happen before/after the merges mentioned above.
259
188
  const mergeAndNormalizeConfig = function ({ config, defaultConfig, inlineConfig, context, branch, logs }) {
260
- const configA = normalizeConfigAndContext(config, CONFIG_ORIGIN)
261
- const defaultConfigA = normalizeConfigAndContext(defaultConfig, UI_ORIGIN)
262
- const inlineConfigA = normalizeConfigAndContext(inlineConfig, INLINE_ORIGIN)
263
-
264
- const configB = mergeConfigs([defaultConfigA, configA])
265
- const configC = mergeContext({ config: configB, context, branch, logs })
266
- const configD = mergeConfigs([configC, inlineConfigA])
267
-
268
- const configE = normalizeAfterConfigMerge(configD)
269
- return configE
270
- }
271
-
189
+ const configA = normalizeConfigAndContext(config, CONFIG_ORIGIN);
190
+ const defaultConfigA = normalizeConfigAndContext(defaultConfig, UI_ORIGIN);
191
+ const inlineConfigA = normalizeConfigAndContext(inlineConfig, INLINE_ORIGIN);
192
+ const configB = mergeConfigs([defaultConfigA, configA]);
193
+ const configC = mergeContext({ config: configB, context, branch, logs });
194
+ const configD = mergeConfigs([configC, inlineConfigA]);
195
+ const configE = normalizeAfterConfigMerge(configD);
196
+ return configE;
197
+ };
272
198
  const normalizeConfigAndContext = function (config, origin) {
273
- const configA = normalizeBeforeConfigMerge(config, origin)
274
- const configB = normalizeContextProps({ config: configA, origin })
275
- return configB
276
- }
277
-
199
+ const configA = normalizeBeforeConfigMerge(config, origin);
200
+ const configB = normalizeContextProps({ config: configA, origin });
201
+ return configB;
202
+ };
278
203
  // Find base directory, build directory and resolve all paths to absolute paths
279
204
  const resolveFiles = async function ({ config, repositoryRoot, base, baseRelDir }) {
280
- const baseA = getBase(base, repositoryRoot, config)
281
- const buildDir = await getBuildDir(repositoryRoot, baseA)
282
- const configA = await resolveConfigPaths({ config, repositoryRoot, buildDir, baseRelDir })
283
- const configB = addBase(configA, baseA)
284
- return { config: configB, buildDir, base: baseA }
285
- }
205
+ const baseA = getBase(base, repositoryRoot, config);
206
+ const buildDir = await getBuildDir(repositoryRoot, baseA);
207
+ const configA = await resolveConfigPaths({ config, repositoryRoot, buildDir, baseRelDir });
208
+ const configB = addBase(configA, baseA);
209
+ return { config: configB, buildDir, base: baseA };
210
+ };
package/lib/merge.js CHANGED
@@ -1,53 +1,43 @@
1
- import deepmerge from 'deepmerge'
2
- import isPlainObj from 'is-plain-obj'
3
-
4
- import { groupBy } from './utils/group.js'
5
- import { removeUndefined } from './utils/remove_falsy.js'
6
-
1
+ import deepmerge from 'deepmerge';
2
+ import isPlainObj from 'is-plain-obj';
3
+ import { groupBy } from './utils/group.js';
4
+ import { removeUndefined } from './utils/remove_falsy.js';
7
5
  // Merge an array of configuration objects.
8
6
  // Last items have higher priority.
9
7
  // Configuration objects are deeply merged.
10
8
  // - Arrays are overridden, not concatenated.
11
9
  export const mergeConfigs = function (configs) {
12
- const cleanedConfigs = configs.map(removeUndefinedProps)
13
- return deepmerge.all(cleanedConfigs, { arrayMerge })
14
- }
15
-
10
+ const cleanedConfigs = configs.map(removeUndefinedProps);
11
+ return deepmerge.all(cleanedConfigs, { arrayMerge });
12
+ };
16
13
  const removeUndefinedProps = function ({ build = {}, ...config }) {
17
- return removeUndefined({ ...config, build: removeUndefined(build) })
18
- }
19
-
14
+ return removeUndefined({ ...config, build: removeUndefined(build) });
15
+ };
20
16
  // By default `deepmerge` concatenates arrays. We use the `arrayMerge` option
21
17
  // to remove this behavior. Also, we merge some array properties differently,
22
18
  // such as `plugins`.
23
19
  const arrayMerge = function (arrayA, arrayB) {
24
- if (isPluginsProperty(arrayA) && isPluginsProperty(arrayB)) {
25
- return mergePlugins(arrayA, arrayB)
26
- }
27
-
28
- return arrayB
29
- }
30
-
20
+ if (isPluginsProperty(arrayA) && isPluginsProperty(arrayB)) {
21
+ return mergePlugins(arrayA, arrayB);
22
+ }
23
+ return arrayB;
24
+ };
31
25
  // `deepmerge` does not allow retrieving the name of the array property being
32
26
  // merged, so we need to do some heuristics.
33
27
  const isPluginsProperty = function (array) {
34
- return Array.isArray(array) && array.every(isPluginObject)
35
- }
36
-
28
+ return Array.isArray(array) && array.every(isPluginObject);
29
+ };
37
30
  const isPluginObject = function (object) {
38
- return isPlainObj(object) && typeof object.package === 'string'
39
- }
40
-
31
+ return isPlainObj(object) && typeof object.package === 'string';
32
+ };
41
33
  // Merge two `config.plugins`. Merge plugins with the same `plugin.package`.
42
34
  const mergePlugins = function (pluginsA, pluginsB) {
43
- const plugins = [...pluginsA, ...pluginsB]
44
- return groupBy(plugins, 'package').map(mergePluginConfigs)
45
- }
46
-
35
+ const plugins = [...pluginsA, ...pluginsB];
36
+ return groupBy(plugins, 'package').map(mergePluginConfigs);
37
+ };
47
38
  const mergePluginConfigs = function (plugins) {
48
- return plugins.reduce(mergePluginsPair, {})
49
- }
50
-
39
+ return plugins.reduce(mergePluginsPair, {});
40
+ };
51
41
  const mergePluginsPair = function (pluginA, pluginB) {
52
- return deepmerge(pluginA, pluginB, { arrayMerge })
53
- }
42
+ return deepmerge(pluginA, pluginB, { arrayMerge });
43
+ };