@netlify/config 19.0.0-rc → 19.0.1

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 (100) hide show
  1. package/bin.js +5 -0
  2. package/lib/api/build_settings.js +28 -0
  3. package/lib/api/client.js +12 -0
  4. package/lib/api/site_info.js +59 -0
  5. package/{src → lib}/base.js +10 -18
  6. package/lib/bin/flags.js +173 -0
  7. package/lib/bin/main.js +59 -0
  8. package/{src → lib}/build_dir.js +11 -15
  9. package/{src → lib}/cached_config.js +14 -17
  10. package/lib/case.js +18 -0
  11. package/lib/context.js +86 -0
  12. package/lib/default.js +27 -0
  13. package/lib/env/envelope.js +24 -0
  14. package/lib/env/git.js +23 -0
  15. package/lib/env/main.js +150 -0
  16. package/lib/error.js +28 -0
  17. package/lib/events.js +21 -0
  18. package/lib/files.js +83 -0
  19. package/{src → lib}/functions_config.js +36 -52
  20. package/lib/headers.js +20 -0
  21. package/lib/inline_config.js +8 -0
  22. package/lib/log/cleanup.js +64 -0
  23. package/lib/log/logger.js +36 -0
  24. package/lib/log/main.js +39 -0
  25. package/{src → lib}/log/messages.js +56 -95
  26. package/lib/log/options.js +29 -0
  27. package/lib/log/serialize.js +4 -0
  28. package/lib/log/theme.js +13 -0
  29. package/lib/main.js +210 -0
  30. package/{src → lib}/merge.js +25 -35
  31. package/lib/merge_normalize.js +24 -0
  32. package/lib/mutations/apply.js +66 -0
  33. package/{src → lib}/mutations/config_prop_name.js +6 -8
  34. package/lib/mutations/update.js +98 -0
  35. package/lib/normalize.js +32 -0
  36. package/lib/options/base.js +54 -0
  37. package/lib/options/branch.js +31 -0
  38. package/{src → lib}/options/feature_flags.js +7 -10
  39. package/lib/options/main.js +91 -0
  40. package/lib/options/repository_root.js +16 -0
  41. package/lib/origin.js +31 -0
  42. package/lib/parse.js +56 -0
  43. package/lib/path.js +41 -0
  44. package/lib/redirects.js +19 -0
  45. package/lib/simplify.js +77 -0
  46. package/{src → lib}/utils/group.js +5 -6
  47. package/lib/utils/remove_falsy.js +14 -0
  48. package/lib/utils/set.js +27 -0
  49. package/lib/utils/toml.js +20 -0
  50. package/lib/validate/context.js +38 -0
  51. package/lib/validate/example.js +30 -0
  52. package/lib/validate/helpers.js +25 -0
  53. package/{src → lib}/validate/identical.js +8 -12
  54. package/lib/validate/main.js +99 -0
  55. package/lib/validate/validations.js +275 -0
  56. package/package.json +22 -12
  57. package/src/api/build_settings.js +0 -41
  58. package/src/api/client.js +0 -15
  59. package/src/api/site_info.js +0 -67
  60. package/src/bin/flags.js +0 -181
  61. package/src/bin/main.js +0 -73
  62. package/src/case.js +0 -37
  63. package/src/context.js +0 -99
  64. package/src/default.js +0 -31
  65. package/src/env/envelope.js +0 -24
  66. package/src/env/git.js +0 -23
  67. package/src/env/main.js +0 -198
  68. package/src/error.js +0 -36
  69. package/src/events.js +0 -22
  70. package/src/files.js +0 -107
  71. package/src/headers.js +0 -30
  72. package/src/inline_config.js +0 -9
  73. package/src/log/cleanup.js +0 -92
  74. package/src/log/logger.js +0 -47
  75. package/src/log/main.js +0 -48
  76. package/src/log/options.js +0 -43
  77. package/src/log/serialize.js +0 -5
  78. package/src/log/theme.js +0 -14
  79. package/src/main.js +0 -285
  80. package/src/merge_normalize.js +0 -31
  81. package/src/mutations/apply.js +0 -78
  82. package/src/mutations/update.js +0 -117
  83. package/src/normalize.js +0 -36
  84. package/src/options/base.js +0 -66
  85. package/src/options/branch.js +0 -34
  86. package/src/options/main.js +0 -111
  87. package/src/options/repository_root.js +0 -21
  88. package/src/origin.js +0 -38
  89. package/src/parse.js +0 -69
  90. package/src/path.js +0 -52
  91. package/src/redirects.js +0 -29
  92. package/src/simplify.js +0 -103
  93. package/src/utils/remove_falsy.js +0 -18
  94. package/src/utils/set.js +0 -33
  95. package/src/utils/toml.js +0 -23
  96. package/src/validate/context.js +0 -57
  97. package/src/validate/example.js +0 -37
  98. package/src/validate/helpers.js +0 -31
  99. package/src/validate/main.js +0 -143
  100. package/src/validate/validations.js +0 -289
package/src/main.js DELETED
@@ -1,285 +0,0 @@
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
-
26
- // Load the configuration file.
27
- // Takes an optional configuration file path as input and return the resolved
28
- // `config` together with related properties such as the `configPath`.
29
- 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
-
123
- // Adds a `build.functions` property that mirrors `functionsDirectory`, for
124
- // backward compatibility.
125
- 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
-
139
- // Try to load the configuration file in two passes.
140
- // The first pass uses the `defaultConfig`'s `build.base` (if defined).
141
- // 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
-
208
- // 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
-
252
- // Merge:
253
- // - `--defaultConfig`: UI build settings and UI-installed plugins
254
- // - `inlineConfig`: Netlify CLI flags
255
- // Then merge context-specific configuration.
256
- // Before and after those steps, also performs validation and normalization.
257
- // Those need to be done at different stages depending on whether they should
258
- // happen before/after the merges mentioned above.
259
- 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
-
272
- const normalizeConfigAndContext = function (config, origin) {
273
- const configA = normalizeBeforeConfigMerge(config, origin)
274
- const configB = normalizeContextProps({ config: configA, origin })
275
- return configB
276
- }
277
-
278
- // Find base directory, build directory and resolve all paths to absolute paths
279
- 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
- }
@@ -1,31 +0,0 @@
1
- import { normalizeConfigCase } from './case.js'
2
- import { normalizeConfig } from './normalize.js'
3
- import { addOrigins } from './origin.js'
4
- import { validateIdenticalPlugins } from './validate/identical.js'
5
- import {
6
- validatePreCaseNormalize,
7
- validatePreMergeConfig,
8
- validatePreNormalizeConfig,
9
- validatePostNormalizeConfig,
10
- } from './validate/main.js'
11
-
12
- // Perform validation and normalization logic to apply to all of:
13
- // - config, defaultConfig, inlineConfig
14
- // - context-specific configs
15
- // Therefore, this is performing before merging those together.
16
- export const normalizeBeforeConfigMerge = function (config, origin) {
17
- validatePreCaseNormalize(config)
18
- const configA = normalizeConfigCase(config)
19
- validatePreMergeConfig(configA)
20
- const configB = addOrigins(configA, origin)
21
- validateIdenticalPlugins(configB)
22
- return configB
23
- }
24
-
25
- // Validation and normalization logic performed after merging
26
- export const normalizeAfterConfigMerge = function (config) {
27
- validatePreNormalizeConfig(config)
28
- const configA = normalizeConfig(config)
29
- validatePostNormalizeConfig(configA)
30
- return configA
31
- }
@@ -1,78 +0,0 @@
1
- import { throwUserError } from '../error.js'
2
- import { EVENTS } from '../events.js'
3
- import { WILDCARD_ALL, FUNCTION_CONFIG_PROPERTIES } from '../functions_config.js'
4
- import { setProp } from '../utils/set.js'
5
-
6
- import { getPropName } from './config_prop_name.js'
7
-
8
- // Apply a series of mutations to `inlineConfig`.
9
- // Meant to be used to apply configuration changes at build time.
10
- // Those are applied on the `inlineConfig` object after `@netlify/config`
11
- // normalization. Therefore, this function also denormalizes (reverts that
12
- // normalization) so that the final `config` object can be serialized back to
13
- // a `netlify.toml`.
14
- export const applyMutations = function (inlineConfig, configMutations) {
15
- return configMutations.reduce(applyMutation, inlineConfig)
16
- }
17
-
18
- const applyMutation = function (inlineConfig, { keys, value, event }) {
19
- const propName = getPropName(keys)
20
- if (!(propName in MUTABLE_PROPS)) {
21
- throwUserError(`"netlifyConfig.${propName}" is read-only.`)
22
- }
23
-
24
- const { lastEvent, denormalize } = MUTABLE_PROPS[propName]
25
- validateEvent(lastEvent, event, propName)
26
-
27
- return denormalize === undefined ? setProp(inlineConfig, keys, value) : denormalize(inlineConfig, value, keys)
28
- }
29
-
30
- const validateEvent = function (lastEvent, event, propName) {
31
- if (EVENTS.indexOf(lastEvent) < EVENTS.indexOf(event)) {
32
- throwUserError(`"netlifyConfig.${propName}" cannot be modified after "${lastEvent}".`)
33
- }
34
- }
35
-
36
- // `functions['*'].*` has higher priority than `functions.*` so we convert the
37
- // latter to the former.
38
- const denormalizeFunctionsTopProps = function (
39
- { functions, functions: { [WILDCARD_ALL]: wildcardProps } = {}, ...inlineConfig },
40
- value,
41
- [, key],
42
- ) {
43
- return FUNCTION_CONFIG_PROPERTIES.has(key)
44
- ? {
45
- ...inlineConfig,
46
- functions: { ...functions, [WILDCARD_ALL]: { ...wildcardProps, [key]: value } },
47
- }
48
- : { ...inlineConfig, functions: { ...functions, [key]: value } }
49
- }
50
-
51
- // List of properties that are not read-only.
52
- const MUTABLE_PROPS = {
53
- 'build.command': { lastEvent: 'onPreBuild' },
54
- 'build.edge_functions': { lastEvent: 'onPostBuild' },
55
- 'build.environment': { lastEvent: 'onPostBuild' },
56
- 'build.environment.*': { lastEvent: 'onPostBuild' },
57
- 'build.functions': { lastEvent: 'onBuild' },
58
- 'build.processing': { lastEvent: 'onPostBuild' },
59
- 'build.processing.css': { lastEvent: 'onPostBuild' },
60
- 'build.processing.css.bundle': { lastEvent: 'onPostBuild' },
61
- 'build.processing.css.minify': { lastEvent: 'onPostBuild' },
62
- 'build.processing.html': { lastEvent: 'onPostBuild' },
63
- 'build.processing.html.pretty_urls': { lastEvent: 'onPostBuild' },
64
- 'build.processing.images': { lastEvent: 'onPostBuild' },
65
- 'build.processing.images.compress': { lastEvent: 'onPostBuild' },
66
- 'build.processing.js': { lastEvent: 'onPostBuild' },
67
- 'build.processing.js.bundle': { lastEvent: 'onPostBuild' },
68
- 'build.processing.js.minify': { lastEvent: 'onPostBuild' },
69
- 'build.processing.skip_processing': { lastEvent: 'onPostBuild' },
70
- 'build.publish': { lastEvent: 'onPostBuild' },
71
- 'build.services': { lastEvent: 'onPostBuild' },
72
- 'build.services.*': { lastEvent: 'onPostBuild' },
73
- edge_functions: { lastEvent: 'onPostBuild' },
74
- 'functions.*': { lastEvent: 'onBuild', denormalize: denormalizeFunctionsTopProps },
75
- 'functions.*.*': { lastEvent: 'onBuild' },
76
- headers: { lastEvent: 'onPostBuild' },
77
- redirects: { lastEvent: 'onPostBuild' },
78
- }
@@ -1,117 +0,0 @@
1
- import { promises as fs } from 'fs'
2
-
3
- import { pathExists } from 'path-exists'
4
-
5
- import { ensureConfigPriority } from '../context.js'
6
- import { addHeaders } from '../headers.js'
7
- import { mergeConfigs } from '../merge.js'
8
- import { parseOptionalConfig } from '../parse.js'
9
- import { addRedirects } from '../redirects.js'
10
- import { simplifyConfig } from '../simplify.js'
11
- import { serializeToml } from '../utils/toml.js'
12
-
13
- import { applyMutations } from './apply.js'
14
-
15
- // Persist configuration changes to `netlify.toml`.
16
- // If `netlify.toml` does not exist, creates it. Otherwise, merges the changes.
17
- export const updateConfig = async function (
18
- configMutations,
19
- { buildDir, configPath, headersPath, redirectsPath, context, branch, logs, featureFlags },
20
- ) {
21
- if (configMutations.length === 0) {
22
- return
23
- }
24
-
25
- const inlineConfig = applyMutations({}, configMutations)
26
- const normalizedInlineConfig = ensureConfigPriority(inlineConfig, context, branch)
27
- const updatedConfig = await mergeWithConfig(normalizedInlineConfig, configPath)
28
- const configWithHeaders = await addHeaders({ config: updatedConfig, headersPath, logs, featureFlags })
29
- const finalConfig = await addRedirects({ config: configWithHeaders, redirectsPath, logs, featureFlags })
30
- const simplifiedConfig = simplifyConfig(finalConfig)
31
- await backupConfig({ buildDir, configPath, headersPath, redirectsPath })
32
- await Promise.all([
33
- saveConfig(configPath, simplifiedConfig),
34
- deleteSideFile(headersPath),
35
- deleteSideFile(redirectsPath),
36
- ])
37
- }
38
-
39
- // If `netlify.toml` exists, deeply merges the configuration changes.
40
- const mergeWithConfig = async function (normalizedInlineConfig, configPath) {
41
- const config = await parseOptionalConfig(configPath)
42
- const updatedConfig = mergeConfigs([config, normalizedInlineConfig])
43
- return updatedConfig
44
- }
45
-
46
- // Serialize the changes to `netlify.toml`
47
- const saveConfig = async function (configPath, simplifiedConfig) {
48
- const serializedConfig = serializeToml(simplifiedConfig)
49
- await fs.writeFile(configPath, serializedConfig)
50
- }
51
-
52
- // Deletes `_headers/_redirects` since they are merged to `netlify.toml`,
53
- // to fix any priority problem.
54
- const deleteSideFile = async function (filePath) {
55
- if (filePath === undefined || !(await pathExists(filePath))) {
56
- return
57
- }
58
-
59
- await fs.unlink(filePath)
60
- }
61
-
62
- // Modifications to `netlify.toml` and `_headers/_redirects` are only meant for
63
- // the deploy API call. After it's been performed, we restore their former
64
- // state.
65
- // We do this by backing them up inside some sibling directory.
66
- const backupConfig = async function ({ buildDir, configPath, headersPath, redirectsPath }) {
67
- const tempDir = getTempDir(buildDir)
68
- await fs.mkdir(tempDir, { recursive: true })
69
- await Promise.all([
70
- backupFile(configPath, `${tempDir}/netlify.toml`),
71
- backupFile(headersPath, `${tempDir}/_headers`),
72
- backupFile(redirectsPath, `${tempDir}/_redirects`),
73
- ])
74
- }
75
-
76
- export const restoreConfig = async function (configMutations, { buildDir, configPath, headersPath, redirectsPath }) {
77
- if (configMutations.length === 0) {
78
- return
79
- }
80
-
81
- const tempDir = getTempDir(buildDir)
82
- await Promise.all([
83
- copyOrDelete(`${tempDir}/netlify.toml`, configPath),
84
- copyOrDelete(`${tempDir}/_headers`, headersPath),
85
- copyOrDelete(`${tempDir}/_redirects`, redirectsPath),
86
- ])
87
- }
88
-
89
- const getTempDir = function (buildDir) {
90
- return `${buildDir}/.netlify/deploy`
91
- }
92
-
93
- const backupFile = async function (original, backup) {
94
- // this makes sure we don't restore stale files
95
- await deleteNoError(backup)
96
-
97
- if (!(await pathExists(original))) {
98
- return
99
- }
100
-
101
- await fs.copyFile(original, backup)
102
- }
103
-
104
- const deleteNoError = async (path) => {
105
- try {
106
- await fs.unlink(path)
107
- } catch {}
108
- }
109
-
110
- const copyOrDelete = async function (src, dest) {
111
- if (await pathExists(src)) {
112
- await fs.copyFile(src, dest)
113
- return
114
- }
115
-
116
- await deleteNoError(dest)
117
- }
package/src/normalize.js DELETED
@@ -1,36 +0,0 @@
1
- import { normalizeFunctionsProps, WILDCARD_ALL } from './functions_config.js'
2
- import { mergeConfigs } from './merge.js'
3
- import { DEFAULT_ORIGIN } from './origin.js'
4
- import { removeFalsy } from './utils/remove_falsy.js'
5
-
6
- // Normalize configuration object
7
- export const normalizeConfig = function (config) {
8
- const configA = removeEmpty(config)
9
- const { build, functions, plugins, ...configB } = mergeConfigs([DEFAULT_CONFIG, configA])
10
- const { build: buildA, functions: functionsA, functionsDirectoryProps } = normalizeFunctionsProps(build, functions)
11
- const pluginsA = plugins.map(normalizePlugin)
12
- return { ...configB, build: buildA, functions: functionsA, plugins: pluginsA, ...functionsDirectoryProps }
13
- }
14
-
15
- // Remove empty strings.
16
- // This notably ensures that empty strings in the build command are removed.
17
- // Otherwise those would be run during builds, making the build fail.
18
- const removeEmpty = function ({ build, ...config }) {
19
- return removeFalsy({ ...config, build: removeFalsy(build) })
20
- }
21
-
22
- const DEFAULT_CONFIG = {
23
- build: {
24
- environment: {},
25
- publish: '.',
26
- publishOrigin: DEFAULT_ORIGIN,
27
- processing: { css: {}, html: {}, images: {}, js: {} },
28
- services: {},
29
- },
30
- functions: { [WILDCARD_ALL]: {} },
31
- plugins: [],
32
- }
33
-
34
- const normalizePlugin = function ({ inputs = {}, ...plugin }) {
35
- return removeFalsy({ ...plugin, inputs })
36
- }
@@ -1,66 +0,0 @@
1
- import { promises as fs } from 'fs'
2
- import { dirname, relative, sep } from 'path'
3
-
4
- import { pathExists } from 'path-exists'
5
-
6
- // Retrieve `base` override.
7
- // This uses any directory below `repositoryRoot` and above (or equal to)
8
- // `cwd` that has a `.netlify` or `netlify.toml`. This allows Netlify CLI users
9
- // to `cd` into monorepo directories to change their base and build directories.
10
- // Do all checks in parallel for speed
11
- export const getBaseOverride = async function ({ repositoryRoot, cwd }) {
12
- // Performance optimization
13
- if (repositoryRoot === cwd) {
14
- return {}
15
- }
16
-
17
- const [repositoryRootA, cwdA] = await Promise.all([fs.realpath(repositoryRoot), fs.realpath(cwd)])
18
- const basePaths = getBasePaths(repositoryRootA, cwdA)
19
- const basePath = await locatePath(basePaths)
20
-
21
- if (basePath === undefined) {
22
- return {}
23
- }
24
-
25
- // `base` starting with a `/` are relative to `repositoryRoot`, so we cannot
26
- // return an absolute path
27
- const base = relative(repositoryRoot, dirname(basePath))
28
- // When `base` is explicitely overridden, `baseRelDir: true` makes more sense
29
- // since we want `publish`, `functions` and `edge_functions` to be relative to it.
30
- return { base, baseRelDir: true }
31
- }
32
-
33
- // Returns list of files to check for the existence of a `base`
34
- const getBasePaths = function (repositoryRoot, cwd) {
35
- const subdirs = getSubdirs(repositoryRoot, cwd)
36
- const basePaths = subdirs.flatMap((subdir) => BASE_FILENAMES.map((filename) => `${subdir}/${filename}`))
37
- return basePaths
38
- }
39
-
40
- // Retrieves list of directories between `repositoryRoot` and `cwd`, including
41
- // `cwd` but excluding `repositoryRoot`
42
- const getSubdirs = function (repositoryRoot, dir, subdirs = []) {
43
- if (!dir.startsWith(`${repositoryRoot}${sep}`)) {
44
- return subdirs
45
- }
46
-
47
- return getSubdirs(repositoryRoot, dirname(dir), [...subdirs, dir])
48
- }
49
-
50
- const BASE_FILENAMES = ['.netlify', 'netlify.toml', 'package.json']
51
-
52
- // Returns the first path that exists.
53
- // Like `locate-path` library but works with mixed files/directories
54
- const locatePath = async function (paths) {
55
- const results = await Promise.all(paths.map(returnIfExists))
56
- const path = results.find(Boolean)
57
- return path
58
- }
59
-
60
- const returnIfExists = async function (path) {
61
- if (!(await pathExists(path))) {
62
- return
63
- }
64
-
65
- return path
66
- }
@@ -1,34 +0,0 @@
1
- import { execaCommand } from 'execa'
2
-
3
- // Find out git branch among (in priority order):
4
- // - `branch` option
5
- // - `BRANCH` environment variable
6
- // - `HEAD` branch (using `git`)
7
- // - `main` (using `git`)
8
- // - 'master' (fallback)
9
- export const getBranch = async function ({ branch, repositoryRoot }) {
10
- if (branch) {
11
- return branch
12
- }
13
-
14
- const headBranch = await getGitBranch(repositoryRoot, 'HEAD')
15
- if (headBranch !== undefined) {
16
- return headBranch
17
- }
18
-
19
- const mainBranch = await getGitBranch(repositoryRoot, 'main')
20
- if (mainBranch !== undefined) {
21
- return mainBranch
22
- }
23
-
24
- return FALLBACK_BRANCH
25
- }
26
-
27
- const getGitBranch = async function (repositoryRoot, gitRef) {
28
- try {
29
- const { stdout } = await execaCommand(`git rev-parse --abbrev-ref ${gitRef}`, { cwd: repositoryRoot })
30
- return stdout
31
- } catch {}
32
- }
33
-
34
- const FALLBACK_BRANCH = 'master'