@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
@@ -1,143 +0,0 @@
1
- import { throwUserError } from '../error.js'
2
- import { THEME } from '../log/theme.js'
3
-
4
- import { getExample } from './example.js'
5
- import {
6
- PRE_CASE_NORMALIZE_VALIDATIONS,
7
- PRE_MERGE_VALIDATIONS,
8
- PRE_CONTEXT_VALIDATIONS,
9
- PRE_NORMALIZE_VALIDATIONS,
10
- POST_NORMALIZE_VALIDATIONS,
11
- } from './validations.js'
12
-
13
- // Validate the configuration file, before case normalization.
14
- export const validatePreCaseNormalize = function (config) {
15
- validateConfig(config, PRE_CASE_NORMALIZE_VALIDATIONS)
16
- }
17
-
18
- // Validate the configuration file, before `defaultConfig` merge.
19
- export const validatePreMergeConfig = function (config) {
20
- validateConfig(config, PRE_MERGE_VALIDATIONS)
21
- }
22
-
23
- // Validate the configuration file, before context merge.
24
- export const validatePreContextConfig = function (config) {
25
- validateConfig(config, PRE_CONTEXT_VALIDATIONS)
26
- }
27
-
28
- // Validate the configuration file, before normalization.
29
- export const validatePreNormalizeConfig = function (config) {
30
- validateConfig(config, PRE_NORMALIZE_VALIDATIONS)
31
- }
32
-
33
- // Validate the configuration file, after normalization.
34
- export const validatePostNormalizeConfig = function (config) {
35
- validateConfig(config, POST_NORMALIZE_VALIDATIONS)
36
- }
37
-
38
- const validateConfig = function (config, validations) {
39
- try {
40
- validations.forEach(({ property, ...validation }) => {
41
- validateProperty(config, { ...validation, nextPath: property.split('.') })
42
- })
43
- } catch (error) {
44
- throwUserError(error)
45
- }
46
- }
47
-
48
- // Validate a single property in the configuration file.
49
- const validateProperty = function (
50
- parent,
51
- {
52
- nextPath: [propName, nextPropName, ...nextPath],
53
- prevPath = [propName],
54
- propPath = propName,
55
- key = propName,
56
- check,
57
- message,
58
- example,
59
- formatInvalid,
60
- propertyName,
61
- },
62
- ) {
63
- const value = parent[propName]
64
-
65
- if (nextPropName !== undefined) {
66
- return validateChild({
67
- value,
68
- nextPropName,
69
- prevPath,
70
- nextPath,
71
- propPath,
72
- key,
73
- check,
74
- message,
75
- example,
76
- formatInvalid,
77
- propertyName,
78
- })
79
- }
80
-
81
- if (value === undefined || (check !== undefined && check(value, key, prevPath))) {
82
- return
83
- }
84
-
85
- reportError({ prevPath, propPath, message, example, value, key, formatInvalid, propertyName })
86
- }
87
-
88
- const reportError = function ({
89
- prevPath,
90
- propPath,
91
- message,
92
- example,
93
- value,
94
- key,
95
- formatInvalid,
96
- propertyName = propPath,
97
- }) {
98
- throwUserError(`${THEME.highlightWords('Configuration property')} ${propertyName} ${message}
99
- ${getExample({ value, key, prevPath, example, formatInvalid })}`)
100
- }
101
-
102
- // Recurse over children (each part of the `property` array).
103
- const validateChild = function ({ value, nextPropName, prevPath, nextPath, propPath, ...rest }) {
104
- if (value === undefined) {
105
- return
106
- }
107
-
108
- if (nextPropName !== '*') {
109
- return validateProperty(value, {
110
- ...rest,
111
- prevPath: [...prevPath, nextPropName],
112
- nextPath: [nextPropName, ...nextPath],
113
- propPath: `${propPath}.${nextPropName}`,
114
- key: nextPropName,
115
- })
116
- }
117
-
118
- return Object.keys(value).forEach((childProp) => {
119
- validateChildProp({ childProp, value, nextPath, propPath, prevPath, ...rest })
120
- })
121
- }
122
-
123
- // Can use * to recurse over array|object elements.
124
- const validateChildProp = function ({ childProp, value, nextPath, propPath, prevPath, ...rest }) {
125
- if (Array.isArray(value)) {
126
- const key = Number(childProp)
127
- return validateProperty(value, {
128
- ...rest,
129
- prevPath: [...prevPath, key],
130
- nextPath: [key, ...nextPath],
131
- propPath: `${propPath}[${childProp}]`,
132
- key,
133
- })
134
- }
135
-
136
- validateProperty(value, {
137
- ...rest,
138
- prevPath: [...prevPath, childProp],
139
- nextPath: [childProp, ...nextPath],
140
- propPath: `${propPath}.${childProp}`,
141
- key: childProp,
142
- })
143
- }
@@ -1,289 +0,0 @@
1
- import CronParser from 'cron-parser'
2
- import isPlainObj from 'is-plain-obj'
3
- import validateNpmPackageName from 'validate-npm-package-name'
4
-
5
- import { bundlers, WILDCARD_ALL as FUNCTIONS_CONFIG_WILDCARD_ALL } from '../functions_config.js'
6
-
7
- import { functionsDirectoryCheck, isArrayOfObjects, isArrayOfStrings, isString, validProperties } from './helpers.js'
8
-
9
- /**
10
- * @param {string} cron
11
- * @returns {boolean}
12
- */
13
- const isValidCronExpression = (cron) => {
14
- try {
15
- CronParser.parseExpression(cron)
16
- return true
17
- } catch {
18
- return false
19
- }
20
- }
21
-
22
- // List of validations performed on the configuration file.
23
- // Validation are performed in order: parent should be before children.
24
- // Each validation is an object with the following properties:
25
- // - `property` {string}: dot-delimited path to the property.
26
- // Can contain `*` providing a previous check validates the parent is an
27
- // object or an array.
28
- // - `propertyName` {string}: human-friendly property name; overrides the
29
- // value of `property` when displaying an error message
30
- // - `check` {(value, key, prevPath) => boolean}: validation check function
31
- // - `message` {string}: error message
32
- // - `example` {string}: example of correct code
33
- // - `formatInvalid` {(object) => object}: formats the invalid value when
34
- // displaying an error message
35
- // We use this instead of JSON schema (or others) to get nicer error messages.
36
-
37
- // Validations done before case normalization
38
- export const PRE_CASE_NORMALIZE_VALIDATIONS = [
39
- {
40
- property: 'build',
41
- check: isPlainObj,
42
- message: 'must be a plain object.',
43
- example: () => ({ build: { command: 'npm run build' } }),
44
- },
45
- ]
46
-
47
- // Properties with an `origin` property need to be validated twice:
48
- // - Before the `origin` property is added
49
- // - After `context.*` is merged, since they might contain that property
50
- const ORIGIN_VALIDATIONS = [
51
- {
52
- property: 'build.command',
53
- check: isString,
54
- message: 'must be a string',
55
- example: () => ({ build: { command: 'npm run build' } }),
56
- },
57
- {
58
- property: 'plugins',
59
- check: isArrayOfObjects,
60
- message: 'must be an array of objects.',
61
- example: () => ({ plugins: [{ package: 'netlify-plugin-one' }, { package: 'netlify-plugin-two' }] }),
62
- },
63
- ]
64
-
65
- // Validations done before `defaultConfig` merge
66
- export const PRE_MERGE_VALIDATIONS = [...ORIGIN_VALIDATIONS]
67
-
68
- // Validations done before context merge
69
- export const PRE_CONTEXT_VALIDATIONS = [
70
- {
71
- property: 'context',
72
- check: isPlainObj,
73
- message: 'must be a plain object.',
74
- example: () => ({ context: { production: { publish: 'dist' } } }),
75
- },
76
- {
77
- property: 'context.*',
78
- check: isPlainObj,
79
- message: 'must be a plain object.',
80
- example: (contextProps, key) => ({ context: { [key]: { publish: 'dist' } } }),
81
- },
82
- ]
83
-
84
- // Validations done before normalization
85
- export const PRE_NORMALIZE_VALIDATIONS = [
86
- ...ORIGIN_VALIDATIONS,
87
- {
88
- property: 'functions',
89
- check: isPlainObj,
90
- message: 'must be an object.',
91
- example: () => ({
92
- functions: { external_node_modules: ['module-one', 'module-two'] },
93
- }),
94
- },
95
- {
96
- property: 'functions',
97
- check: isPlainObj,
98
- message: 'must be an object.',
99
- example: () => ({
100
- functions: { ignored_node_modules: ['module-one', 'module-two'] },
101
- }),
102
- },
103
- {
104
- property: 'edge_functions',
105
- check: isArrayOfObjects,
106
- message: 'must be an array of objects.',
107
- example: () => ({
108
- edge_functions: [
109
- { path: '/hello', function: 'hello' },
110
- { path: '/auth', function: 'auth' },
111
- ],
112
- }),
113
- },
114
- ]
115
-
116
- const EXAMPLE_PORT = 80
117
-
118
- // Validations done after normalization
119
- export const POST_NORMALIZE_VALIDATIONS = [
120
- {
121
- property: 'plugins.*',
122
- ...validProperties(['package', 'pinned_version', 'inputs'], ['origin']),
123
- example: { plugins: [{ package: 'netlify-plugin-one', inputs: { port: EXAMPLE_PORT } }] },
124
- },
125
-
126
- {
127
- property: 'plugins.*',
128
- check: (plugin) => plugin.package !== undefined,
129
- message: '"package" property is required.',
130
- example: () => ({ plugins: [{ package: 'netlify-plugin-one' }] }),
131
- },
132
-
133
- {
134
- property: 'plugins.*.package',
135
- check: isString,
136
- message: 'must be a string.',
137
- example: () => ({ plugins: [{ package: 'netlify-plugin-one' }] }),
138
- },
139
- // We don't allow `package@tag|version` nor `git:...`, `github:...`,
140
- // `https://...`, etc.
141
- // We skip this validation for local plugins.
142
- // We ensure @scope/plugin still work.
143
- {
144
- property: 'plugins.*.package',
145
- check: (packageName) =>
146
- packageName.startsWith('.') ||
147
- packageName.startsWith('/') ||
148
- validateNpmPackageName(packageName).validForOldPackages,
149
- message: 'must be a npm package name only.',
150
- example: () => ({ plugins: [{ package: 'netlify-plugin-one' }] }),
151
- },
152
-
153
- {
154
- property: 'plugins.*.pinned_version',
155
- check: isString,
156
- message: 'must be a string.',
157
- example: () => ({ plugins: [{ package: 'netlify-plugin-one', pinned_version: '1' }] }),
158
- },
159
- {
160
- property: 'plugins.*.inputs',
161
- check: isPlainObj,
162
- message: 'must be a plain object.',
163
- example: () => ({ plugins: [{ package: 'netlify-plugin-one', inputs: { port: EXAMPLE_PORT } }] }),
164
- },
165
- {
166
- property: 'build.base',
167
- check: isString,
168
- message: 'must be a string.',
169
- example: () => ({ build: { base: 'packages/project' } }),
170
- },
171
- {
172
- property: 'build.publish',
173
- check: isString,
174
- message: 'must be a string.',
175
- example: () => ({ build: { publish: 'dist' } }),
176
- },
177
- {
178
- property: 'build.functions',
179
- check: isString,
180
- message: 'must be a string.',
181
- example: () => ({ build: { functions: 'functions' } }),
182
- },
183
- {
184
- property: 'build.edge_functions',
185
- check: isString,
186
- message: 'must be a string.',
187
- example: () => ({ build: { edge_functions: 'edge-functions' } }),
188
- },
189
- {
190
- property: 'functions.*',
191
- check: isPlainObj,
192
- message: 'must be an object.',
193
- example: (value, key, prevPath) => ({
194
- functions: { [prevPath[1]]: { external_node_modules: ['module-one', 'module-two'] } },
195
- }),
196
- },
197
- {
198
- property: 'functions.*.external_node_modules',
199
- check: isArrayOfStrings,
200
- message: 'must be an array of strings.',
201
- example: (value, key, prevPath) => ({
202
- functions: { [prevPath[1]]: { external_node_modules: ['module-one', 'module-two'] } },
203
- }),
204
- },
205
- {
206
- property: 'functions.*.ignored_node_modules',
207
- check: isArrayOfStrings,
208
- message: 'must be an array of strings.',
209
- example: (value, key, prevPath) => ({
210
- functions: { [prevPath[1]]: { ignored_node_modules: ['module-one', 'module-two'] } },
211
- }),
212
- },
213
- {
214
- property: 'functions.*.included_files',
215
- check: isArrayOfStrings,
216
- message: 'must be an array of strings.',
217
- example: (value, key, prevPath) => ({
218
- functions: { [prevPath[1]]: { included_files: ['directory-one/file1', 'directory-two/**/*.jpg'] } },
219
- }),
220
- },
221
- {
222
- property: 'functions.*.node_bundler',
223
- check: (value) => bundlers.includes(value),
224
- message: `must be one of: ${bundlers.join(', ')}`,
225
- example: (value, key, prevPath) => ({
226
- functions: { [prevPath[1]]: { node_bundler: bundlers[0] } },
227
- }),
228
- },
229
- {
230
- property: 'functions.*.directory',
231
- check: (value, key, prevPath) => prevPath[1] === FUNCTIONS_CONFIG_WILDCARD_ALL,
232
- message: 'must be defined on the main `functions` object.',
233
- example: () => ({
234
- functions: { directory: 'my-functions' },
235
- }),
236
- },
237
- {
238
- property: 'functions.*.schedule',
239
- check: isValidCronExpression,
240
- message: 'must be a valid cron expression (see https://ntl.fyi/cron-syntax).',
241
- example: (value, key, prevPath) => ({
242
- functions: { [prevPath[1]]: { schedule: '5 4 * * *' } },
243
- }),
244
- },
245
- {
246
- property: 'functionsDirectory',
247
- check: isString,
248
- message: 'must be a string.',
249
- ...functionsDirectoryCheck,
250
- example: () => ({
251
- functions: { directory: 'my-functions' },
252
- }),
253
- },
254
- {
255
- property: 'edge_functions.*',
256
- ...validProperties(['path', 'function'], []),
257
- example: () => ({ edge_functions: [{ path: '/hello', function: 'hello' }] }),
258
- },
259
- {
260
- property: 'edge_functions.*',
261
- check: (edgeFunction) => edgeFunction.path !== undefined,
262
- message: '"path" property is required.',
263
- example: () => ({ edge_functions: [{ path: '/hello', function: 'hello' }] }),
264
- },
265
- {
266
- property: 'edge_functions.*',
267
- check: (edgeFunction) => edgeFunction.function !== undefined,
268
- message: '"function" property is required.',
269
- example: () => ({ edge_functions: [{ path: '/hello', function: 'hello' }] }),
270
- },
271
- {
272
- property: 'edge_functions.*.path',
273
- check: isString,
274
- message: 'must be a string.',
275
- example: () => ({ edge_functions: [{ path: '/hello', function: 'hello' }] }),
276
- },
277
- {
278
- property: 'edge_functions.*.function',
279
- check: isString,
280
- message: 'must be a string.',
281
- example: () => ({ edge_functions: [{ path: '/hello', function: 'hello' }] }),
282
- },
283
- {
284
- property: 'edge_functions.*.path',
285
- check: (pathName) => pathName.startsWith('/'),
286
- message: 'must be a valid path.',
287
- example: () => ({ edge_functions: [{ path: '/hello', function: 'hello' }] }),
288
- },
289
- ]