@netlify/config 25.1.0 → 25.2.0
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.
- package/lib/edge_functions.d.ts +2 -0
- package/lib/edge_functions.js +33 -1
- package/lib/merge_normalize.js +7 -2
- package/lib/mutations/apply.js +1 -0
- package/lib/validate/helpers.d.ts +1 -0
- package/lib/validate/helpers.js +3 -0
- package/lib/validate/main.d.ts +1 -0
- package/lib/validate/main.js +8 -1
- package/lib/validate/validations.d.ts +18 -0
- package/lib/validate/validations.js +26 -2
- package/package.json +2 -2
package/lib/edge_functions.d.ts
CHANGED
package/lib/edge_functions.js
CHANGED
|
@@ -4,10 +4,30 @@ const methodValues = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'];
|
|
|
4
4
|
const isMethod = (value) => typeof value === 'string' && methodValues.includes(value.toUpperCase());
|
|
5
5
|
const isValidHeaderValue = (value) => typeof value === 'boolean' || typeof value === 'string';
|
|
6
6
|
const isValidHeaders = (value) => typeof value === 'object' && value !== null && !Array.isArray(value) && Object.values(value).every(isValidHeaderValue);
|
|
7
|
+
// Properties that can be set on an edge function declaration from any origin,
|
|
8
|
+
// including the user's `netlify.toml`.
|
|
9
|
+
export const EDGE_FUNCTIONS_PROPERTIES = [
|
|
10
|
+
'path',
|
|
11
|
+
'excludedPath',
|
|
12
|
+
'pattern',
|
|
13
|
+
'excludedPattern',
|
|
14
|
+
'function',
|
|
15
|
+
'cache',
|
|
16
|
+
'method',
|
|
17
|
+
'header',
|
|
18
|
+
'name',
|
|
19
|
+
];
|
|
20
|
+
// Properties that can only be set by platform-generated configuration, i.e. by
|
|
21
|
+
// frameworks and integrations through the Frameworks API — never from the
|
|
22
|
+
// user's `netlify.toml`.
|
|
23
|
+
export const EDGE_FUNCTIONS_INTERNAL_PROPERTIES = ['generator'];
|
|
7
24
|
export const validations = [
|
|
8
25
|
{
|
|
9
26
|
property: 'edge_functions.*',
|
|
10
|
-
|
|
27
|
+
// This runs on the fully-merged configuration, which may include properties
|
|
28
|
+
// contributed by the Frameworks API, so it validates against the full set.
|
|
29
|
+
// User-facing restrictions are enforced separately (see `CONFIG_FILE_VALIDATIONS`).
|
|
30
|
+
...validProperties([...EDGE_FUNCTIONS_PROPERTIES, ...EDGE_FUNCTIONS_INTERNAL_PROPERTIES], []),
|
|
11
31
|
example: () => ({ edge_functions: [{ path: '/hello', function: 'hello' }] }),
|
|
12
32
|
},
|
|
13
33
|
{
|
|
@@ -68,6 +88,18 @@ export const validations = [
|
|
|
68
88
|
message: 'must be a string.',
|
|
69
89
|
example: () => ({ edge_functions: [{ path: '/hello', function: 'hello' }] }),
|
|
70
90
|
},
|
|
91
|
+
{
|
|
92
|
+
property: 'edge_functions.*.name',
|
|
93
|
+
check: isString,
|
|
94
|
+
message: 'must be a string.',
|
|
95
|
+
example: () => ({ edge_functions: [{ path: '/hello', function: 'hello', name: 'Hello' }] }),
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
property: 'edge_functions.*.generator',
|
|
99
|
+
check: isString,
|
|
100
|
+
message: 'must be a string.',
|
|
101
|
+
example: () => ({ edge_functions: [{ path: '/hello', function: 'hello', generator: 'package-name@1.2.3' }] }),
|
|
102
|
+
},
|
|
71
103
|
{
|
|
72
104
|
property: 'edge_functions.*.path',
|
|
73
105
|
check: (pathName) => pathName.startsWith('/'),
|
package/lib/merge_normalize.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { normalizeConfigCase } from './case.js';
|
|
2
2
|
import { normalizeConfig } from './normalize.js';
|
|
3
|
-
import { addOrigins } from './origin.js';
|
|
3
|
+
import { addOrigins, CONFIG_ORIGIN } from './origin.js';
|
|
4
4
|
import { validateIdenticalPlugins } from './validate/identical.js';
|
|
5
|
-
import { validatePreCaseNormalize, validatePreMergeConfig, validatePreNormalizeConfig, validatePostNormalizeConfig, } from './validate/main.js';
|
|
5
|
+
import { validatePreCaseNormalize, validatePreMergeConfig, validateConfigFile, validatePreNormalizeConfig, validatePostNormalizeConfig, } from './validate/main.js';
|
|
6
6
|
/**
|
|
7
7
|
* Perform validation and normalization logic to apply to all of:
|
|
8
8
|
* - config, defaultConfig, inlineConfig
|
|
@@ -13,6 +13,11 @@ export const normalizeBeforeConfigMerge = function (config, origin) {
|
|
|
13
13
|
validatePreCaseNormalize(config);
|
|
14
14
|
const configA = normalizeConfigCase(config);
|
|
15
15
|
validatePreMergeConfig(configA);
|
|
16
|
+
// Some properties are only allowed to be set from the user's `netlify.toml`
|
|
17
|
+
// file, so they are validated exclusively against that origin.
|
|
18
|
+
if (origin === CONFIG_ORIGIN) {
|
|
19
|
+
validateConfigFile(configA);
|
|
20
|
+
}
|
|
16
21
|
const configB = addOrigins(configA, origin);
|
|
17
22
|
validateIdenticalPlugins(configB);
|
|
18
23
|
return configB;
|
package/lib/mutations/apply.js
CHANGED
|
@@ -65,6 +65,7 @@ const MUTABLE_PROPS = {
|
|
|
65
65
|
images: { lastEvent: 'onPostBuild' },
|
|
66
66
|
'images.remote_images': { lastEvent: 'onPostBuild' },
|
|
67
67
|
redirects: { lastEvent: 'onPostBuild' },
|
|
68
|
+
spa_fallback: { lastEvent: 'onPostBuild' },
|
|
68
69
|
dev: { lastEvent: 'onPreDev' },
|
|
69
70
|
'dev.processing': { lastEvent: 'onPreDev' },
|
|
70
71
|
'dev.processing.html': { lastEvent: 'onPreDev' },
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export function isArrayOfObjects(value: any): value is Record<PropertyKey, unknown>[];
|
|
2
2
|
export function isArrayOfStrings(value: any): value is string[];
|
|
3
3
|
export function isString(value: any): value is string;
|
|
4
|
+
export function isBoolean(value: any): value is boolean;
|
|
4
5
|
export function validProperties(propNames: any, legacyPropNames: any): {
|
|
5
6
|
check: (value: any) => boolean;
|
|
6
7
|
message: string;
|
package/lib/validate/helpers.js
CHANGED
|
@@ -8,6 +8,9 @@ export const isArrayOfStrings = function (value) {
|
|
|
8
8
|
export const isString = function (value) {
|
|
9
9
|
return typeof value === 'string';
|
|
10
10
|
};
|
|
11
|
+
export const isBoolean = function (value) {
|
|
12
|
+
return typeof value === 'boolean';
|
|
13
|
+
};
|
|
11
14
|
// Check an object valid properties, including legacy ones
|
|
12
15
|
export const validProperties = function (propNames, legacyPropNames) {
|
|
13
16
|
return {
|
package/lib/validate/main.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export function validatePreCaseNormalize(config: any): void;
|
|
2
2
|
export function validatePreMergeConfig(config: any): void;
|
|
3
|
+
export function validateConfigFile(config: any): void;
|
|
3
4
|
export function validatePreContextConfig(config: any): void;
|
|
4
5
|
export function validatePreNormalizeConfig(config: any): void;
|
|
5
6
|
export function validatePostNormalizeConfig(config: any): void;
|
package/lib/validate/main.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { throwUserError } from '../error.js';
|
|
2
2
|
import { THEME } from '../log/theme.js';
|
|
3
3
|
import { getExample } from './example.js';
|
|
4
|
-
import { PRE_CASE_NORMALIZE_VALIDATIONS, PRE_MERGE_VALIDATIONS, PRE_CONTEXT_VALIDATIONS, PRE_NORMALIZE_VALIDATIONS, POST_NORMALIZE_VALIDATIONS, } from './validations.js';
|
|
4
|
+
import { PRE_CASE_NORMALIZE_VALIDATIONS, PRE_MERGE_VALIDATIONS, PRE_CONTEXT_VALIDATIONS, PRE_NORMALIZE_VALIDATIONS, POST_NORMALIZE_VALIDATIONS, CONFIG_FILE_VALIDATIONS, } from './validations.js';
|
|
5
5
|
// Validate the configuration file, before case normalization.
|
|
6
6
|
export const validatePreCaseNormalize = function (config) {
|
|
7
7
|
validateConfig(config, PRE_CASE_NORMALIZE_VALIDATIONS);
|
|
@@ -10,6 +10,13 @@ export const validatePreCaseNormalize = function (config) {
|
|
|
10
10
|
export const validatePreMergeConfig = function (config) {
|
|
11
11
|
validateConfig(config, PRE_MERGE_VALIDATIONS);
|
|
12
12
|
};
|
|
13
|
+
// Validate properties that are only allowed to be set from the user's
|
|
14
|
+
// configuration file (`netlify.toml`). This runs exclusively on the config
|
|
15
|
+
// coming from that file, so properties reserved for other origins (e.g. the
|
|
16
|
+
// Frameworks API) can still set them.
|
|
17
|
+
export const validateConfigFile = function (config) {
|
|
18
|
+
validateConfig(config, CONFIG_FILE_VALIDATIONS);
|
|
19
|
+
};
|
|
13
20
|
// Validate the configuration file, before context merge.
|
|
14
21
|
export const validatePreContextConfig = function (config) {
|
|
15
22
|
validateConfig(config, PRE_CONTEXT_VALIDATIONS);
|
|
@@ -8,6 +8,17 @@ export const PRE_CASE_NORMALIZE_VALIDATIONS: {
|
|
|
8
8
|
};
|
|
9
9
|
};
|
|
10
10
|
}[];
|
|
11
|
+
export const CONFIG_FILE_VALIDATIONS: {
|
|
12
|
+
check: (edgeFunction: any) => boolean;
|
|
13
|
+
example: () => {
|
|
14
|
+
edge_functions: {
|
|
15
|
+
path: string;
|
|
16
|
+
function: string;
|
|
17
|
+
}[];
|
|
18
|
+
};
|
|
19
|
+
message: string;
|
|
20
|
+
property: string;
|
|
21
|
+
}[];
|
|
11
22
|
export const PRE_MERGE_VALIDATIONS: ({
|
|
12
23
|
property: string;
|
|
13
24
|
check: (value: any) => value is string;
|
|
@@ -204,6 +215,13 @@ export const POST_NORMALIZE_VALIDATIONS: ({
|
|
|
204
215
|
edge_functions: string;
|
|
205
216
|
};
|
|
206
217
|
};
|
|
218
|
+
} | {
|
|
219
|
+
property: string;
|
|
220
|
+
check: (value: any) => value is boolean;
|
|
221
|
+
message: string;
|
|
222
|
+
example: () => {
|
|
223
|
+
spa_fallback: boolean;
|
|
224
|
+
};
|
|
207
225
|
} | {
|
|
208
226
|
property: string;
|
|
209
227
|
check: typeof isPlainObj;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import CronParser from 'cron-parser';
|
|
2
2
|
import isPlainObj from 'is-plain-obj';
|
|
3
3
|
import validateNpmPackageName from 'validate-npm-package-name';
|
|
4
|
-
import { validations as edgeFunctionValidations } from '../edge_functions.js';
|
|
4
|
+
import { validations as edgeFunctionValidations, EDGE_FUNCTIONS_PROPERTIES } from '../edge_functions.js';
|
|
5
5
|
import { bundlers, WILDCARD_ALL as FUNCTIONS_CONFIG_WILDCARD_ALL } from '../functions_config.js';
|
|
6
|
-
import { functionsDirectoryCheck, isArrayOfObjects, isArrayOfStrings, isString, validProperties } from './helpers.js';
|
|
6
|
+
import { functionsDirectoryCheck, isArrayOfObjects, isArrayOfStrings, isBoolean, isString, validProperties, } from './helpers.js';
|
|
7
7
|
/**
|
|
8
8
|
* @param {string} cron
|
|
9
9
|
* @returns {boolean}
|
|
@@ -40,6 +40,24 @@ export const PRE_CASE_NORMALIZE_VALIDATIONS = [
|
|
|
40
40
|
example: () => ({ build: { command: 'npm run build' } }),
|
|
41
41
|
},
|
|
42
42
|
];
|
|
43
|
+
const edgeFunctionsUserProperties = validProperties(EDGE_FUNCTIONS_PROPERTIES, []);
|
|
44
|
+
// Validations performed only on the user's configuration file (`netlify.toml`),
|
|
45
|
+
// i.e. not on configuration coming from other origins such as the UI, the CLI,
|
|
46
|
+
// or the Frameworks API. This is where the schema is restricted to the subset
|
|
47
|
+
// of properties that users are allowed to set, excluding those reserved for
|
|
48
|
+
// platform-generated configuration (e.g. `generator`).
|
|
49
|
+
export const CONFIG_FILE_VALIDATIONS = [
|
|
50
|
+
{
|
|
51
|
+
property: 'edge_functions.*',
|
|
52
|
+
...edgeFunctionsUserProperties,
|
|
53
|
+
// Structural problems, such as an entry that is not an object, are reported
|
|
54
|
+
// by the shared `edge_functions` validations, which run later. We only check
|
|
55
|
+
// the properties of actual objects here, so that those validations remain
|
|
56
|
+
// the ones surfacing a meaningful error.
|
|
57
|
+
check: (edgeFunction) => !isPlainObj(edgeFunction) || edgeFunctionsUserProperties.check(edgeFunction),
|
|
58
|
+
example: () => ({ edge_functions: [{ path: '/hello', function: 'hello' }] }),
|
|
59
|
+
},
|
|
60
|
+
];
|
|
43
61
|
// Properties with an `origin` property need to be validated twice:
|
|
44
62
|
// - Before the `origin` property is added
|
|
45
63
|
// - After `context.*` is merged, since they might contain that property
|
|
@@ -191,6 +209,12 @@ export const POST_NORMALIZE_VALIDATIONS = [
|
|
|
191
209
|
message: 'must be a string.',
|
|
192
210
|
example: () => ({ build: { edge_functions: 'edge-functions' } }),
|
|
193
211
|
},
|
|
212
|
+
{
|
|
213
|
+
property: 'spa_fallback',
|
|
214
|
+
check: isBoolean,
|
|
215
|
+
message: 'must be a boolean.',
|
|
216
|
+
example: () => ({ spa_fallback: true }),
|
|
217
|
+
},
|
|
194
218
|
{
|
|
195
219
|
property: 'functions.*',
|
|
196
220
|
check: isPlainObj,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@netlify/config",
|
|
3
|
-
"version": "25.
|
|
3
|
+
"version": "25.2.0",
|
|
4
4
|
"description": "Netlify config module",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": "./lib/index.js",
|
|
@@ -96,5 +96,5 @@
|
|
|
96
96
|
"engines": {
|
|
97
97
|
"node": ">=22.12.0"
|
|
98
98
|
},
|
|
99
|
-
"gitHead": "
|
|
99
|
+
"gitHead": "f34dd81fc3bc8925aabe5cf9c1cdce4e8eebc4e0"
|
|
100
100
|
}
|