@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,24 +1,21 @@
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
-
1
+ import CronParser from 'cron-parser';
2
+ import isPlainObj from 'is-plain-obj';
3
+ import validateNpmPackageName from 'validate-npm-package-name';
4
+ import { bundlers, WILDCARD_ALL as FUNCTIONS_CONFIG_WILDCARD_ALL } from '../functions_config.js';
5
+ import { functionsDirectoryCheck, isArrayOfObjects, isArrayOfStrings, isString, validProperties } from './helpers.js';
9
6
  /**
10
7
  * @param {string} cron
11
8
  * @returns {boolean}
12
9
  */
13
10
  const isValidCronExpression = (cron) => {
14
- try {
15
- CronParser.parseExpression(cron)
16
- return true
17
- } catch {
18
- return false
19
- }
20
- }
21
-
11
+ try {
12
+ CronParser.parseExpression(cron);
13
+ return true;
14
+ }
15
+ catch {
16
+ return false;
17
+ }
18
+ };
22
19
  // List of validations performed on the configuration file.
23
20
  // Validation are performed in order: parent should be before children.
24
21
  // Each validation is an object with the following properties:
@@ -33,257 +30,246 @@ const isValidCronExpression = (cron) => {
33
30
  // - `formatInvalid` {(object) => object}: formats the invalid value when
34
31
  // displaying an error message
35
32
  // We use this instead of JSON schema (or others) to get nicer error messages.
36
-
37
33
  // Validations done before case normalization
38
34
  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
-
35
+ {
36
+ property: 'build',
37
+ check: isPlainObj,
38
+ message: 'must be a plain object.',
39
+ example: () => ({ build: { command: 'npm run build' } }),
40
+ },
41
+ ];
47
42
  // Properties with an `origin` property need to be validated twice:
48
43
  // - Before the `origin` property is added
49
44
  // - After `context.*` is merged, since they might contain that property
50
45
  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
-
46
+ {
47
+ property: 'build.command',
48
+ check: isString,
49
+ message: 'must be a string',
50
+ example: () => ({ build: { command: 'npm run build' } }),
51
+ },
52
+ {
53
+ property: 'plugins',
54
+ check: isArrayOfObjects,
55
+ message: 'must be an array of objects.',
56
+ example: () => ({ plugins: [{ package: 'netlify-plugin-one' }, { package: 'netlify-plugin-two' }] }),
57
+ },
58
+ ];
65
59
  // Validations done before `defaultConfig` merge
66
- export const PRE_MERGE_VALIDATIONS = [...ORIGIN_VALIDATIONS]
67
-
60
+ export const PRE_MERGE_VALIDATIONS = [...ORIGIN_VALIDATIONS];
68
61
  // Validations done before context merge
69
62
  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
-
63
+ {
64
+ property: 'context',
65
+ check: isPlainObj,
66
+ message: 'must be a plain object.',
67
+ example: () => ({ context: { production: { publish: 'dist' } } }),
68
+ },
69
+ {
70
+ property: 'context.*',
71
+ check: isPlainObj,
72
+ message: 'must be a plain object.',
73
+ example: (contextProps, key) => ({ context: { [key]: { publish: 'dist' } } }),
74
+ },
75
+ ];
84
76
  // Validations done before normalization
85
77
  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
-
78
+ ...ORIGIN_VALIDATIONS,
79
+ {
80
+ property: 'functions',
81
+ check: isPlainObj,
82
+ message: 'must be an object.',
83
+ example: () => ({
84
+ functions: { external_node_modules: ['module-one', 'module-two'] },
85
+ }),
86
+ },
87
+ {
88
+ property: 'functions',
89
+ check: isPlainObj,
90
+ message: 'must be an object.',
91
+ example: () => ({
92
+ functions: { ignored_node_modules: ['module-one', 'module-two'] },
93
+ }),
94
+ },
95
+ {
96
+ property: 'edge_functions',
97
+ check: isArrayOfObjects,
98
+ message: 'must be an array of objects.',
99
+ example: () => ({
100
+ edge_functions: [
101
+ { path: '/hello', function: 'hello' },
102
+ { path: '/auth', function: 'auth' },
103
+ ],
104
+ }),
105
+ },
106
+ ];
107
+ const EXAMPLE_PORT = 80;
118
108
  // Validations done after normalization
119
109
  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
- ]
110
+ {
111
+ property: 'plugins.*',
112
+ ...validProperties(['package', 'pinned_version', 'inputs'], ['origin']),
113
+ example: { plugins: [{ package: 'netlify-plugin-one', inputs: { port: EXAMPLE_PORT } }] },
114
+ },
115
+ {
116
+ property: 'plugins.*',
117
+ check: (plugin) => plugin.package !== undefined,
118
+ message: '"package" property is required.',
119
+ example: () => ({ plugins: [{ package: 'netlify-plugin-one' }] }),
120
+ },
121
+ {
122
+ property: 'plugins.*.package',
123
+ check: isString,
124
+ message: 'must be a string.',
125
+ example: () => ({ plugins: [{ package: 'netlify-plugin-one' }] }),
126
+ },
127
+ // We don't allow `package@tag|version` nor `git:...`, `github:...`,
128
+ // `https://...`, etc.
129
+ // We skip this validation for local plugins.
130
+ // We ensure @scope/plugin still work.
131
+ {
132
+ property: 'plugins.*.package',
133
+ check: (packageName) => packageName.startsWith('.') ||
134
+ packageName.startsWith('/') ||
135
+ validateNpmPackageName(packageName).validForOldPackages,
136
+ message: 'must be a npm package name only.',
137
+ example: () => ({ plugins: [{ package: 'netlify-plugin-one' }] }),
138
+ },
139
+ {
140
+ property: 'plugins.*.pinned_version',
141
+ check: isString,
142
+ message: 'must be a string.',
143
+ example: () => ({ plugins: [{ package: 'netlify-plugin-one', pinned_version: '1' }] }),
144
+ },
145
+ {
146
+ property: 'plugins.*.inputs',
147
+ check: isPlainObj,
148
+ message: 'must be a plain object.',
149
+ example: () => ({ plugins: [{ package: 'netlify-plugin-one', inputs: { port: EXAMPLE_PORT } }] }),
150
+ },
151
+ {
152
+ property: 'build.base',
153
+ check: isString,
154
+ message: 'must be a string.',
155
+ example: () => ({ build: { base: 'packages/project' } }),
156
+ },
157
+ {
158
+ property: 'build.publish',
159
+ check: isString,
160
+ message: 'must be a string.',
161
+ example: () => ({ build: { publish: 'dist' } }),
162
+ },
163
+ {
164
+ property: 'build.functions',
165
+ check: isString,
166
+ message: 'must be a string.',
167
+ example: () => ({ build: { functions: 'functions' } }),
168
+ },
169
+ {
170
+ property: 'build.edge_functions',
171
+ check: isString,
172
+ message: 'must be a string.',
173
+ example: () => ({ build: { edge_functions: 'edge-functions' } }),
174
+ },
175
+ {
176
+ property: 'functions.*',
177
+ check: isPlainObj,
178
+ message: 'must be an object.',
179
+ example: (value, key, prevPath) => ({
180
+ functions: { [prevPath[1]]: { external_node_modules: ['module-one', 'module-two'] } },
181
+ }),
182
+ },
183
+ {
184
+ property: 'functions.*.external_node_modules',
185
+ check: isArrayOfStrings,
186
+ message: 'must be an array of strings.',
187
+ example: (value, key, prevPath) => ({
188
+ functions: { [prevPath[1]]: { external_node_modules: ['module-one', 'module-two'] } },
189
+ }),
190
+ },
191
+ {
192
+ property: 'functions.*.ignored_node_modules',
193
+ check: isArrayOfStrings,
194
+ message: 'must be an array of strings.',
195
+ example: (value, key, prevPath) => ({
196
+ functions: { [prevPath[1]]: { ignored_node_modules: ['module-one', 'module-two'] } },
197
+ }),
198
+ },
199
+ {
200
+ property: 'functions.*.included_files',
201
+ check: isArrayOfStrings,
202
+ message: 'must be an array of strings.',
203
+ example: (value, key, prevPath) => ({
204
+ functions: { [prevPath[1]]: { included_files: ['directory-one/file1', 'directory-two/**/*.jpg'] } },
205
+ }),
206
+ },
207
+ {
208
+ property: 'functions.*.node_bundler',
209
+ check: (value) => bundlers.includes(value),
210
+ message: `must be one of: ${bundlers.join(', ')}`,
211
+ example: (value, key, prevPath) => ({
212
+ functions: { [prevPath[1]]: { node_bundler: bundlers[0] } },
213
+ }),
214
+ },
215
+ {
216
+ property: 'functions.*.directory',
217
+ check: (value, key, prevPath) => prevPath[1] === FUNCTIONS_CONFIG_WILDCARD_ALL,
218
+ message: 'must be defined on the main `functions` object.',
219
+ example: () => ({
220
+ functions: { directory: 'my-functions' },
221
+ }),
222
+ },
223
+ {
224
+ property: 'functions.*.schedule',
225
+ check: isValidCronExpression,
226
+ message: 'must be a valid cron expression (see https://ntl.fyi/cron-syntax).',
227
+ example: (value, key, prevPath) => ({
228
+ functions: { [prevPath[1]]: { schedule: '5 4 * * *' } },
229
+ }),
230
+ },
231
+ {
232
+ property: 'functionsDirectory',
233
+ check: isString,
234
+ message: 'must be a string.',
235
+ ...functionsDirectoryCheck,
236
+ example: () => ({
237
+ functions: { directory: 'my-functions' },
238
+ }),
239
+ },
240
+ {
241
+ property: 'edge_functions.*',
242
+ ...validProperties(['path', 'function'], []),
243
+ example: () => ({ edge_functions: [{ path: '/hello', function: 'hello' }] }),
244
+ },
245
+ {
246
+ property: 'edge_functions.*',
247
+ check: (edgeFunction) => edgeFunction.path !== undefined,
248
+ message: '"path" property is required.',
249
+ example: () => ({ edge_functions: [{ path: '/hello', function: 'hello' }] }),
250
+ },
251
+ {
252
+ property: 'edge_functions.*',
253
+ check: (edgeFunction) => edgeFunction.function !== undefined,
254
+ message: '"function" property is required.',
255
+ example: () => ({ edge_functions: [{ path: '/hello', function: 'hello' }] }),
256
+ },
257
+ {
258
+ property: 'edge_functions.*.path',
259
+ check: isString,
260
+ message: 'must be a string.',
261
+ example: () => ({ edge_functions: [{ path: '/hello', function: 'hello' }] }),
262
+ },
263
+ {
264
+ property: 'edge_functions.*.function',
265
+ check: isString,
266
+ message: 'must be a string.',
267
+ example: () => ({ edge_functions: [{ path: '/hello', function: 'hello' }] }),
268
+ },
269
+ {
270
+ property: 'edge_functions.*.path',
271
+ check: (pathName) => pathName.startsWith('/'),
272
+ message: 'must be a valid path.',
273
+ example: () => ({ edge_functions: [{ path: '/hello', function: 'hello' }] }),
274
+ },
275
+ ];
package/package.json CHANGED
@@ -1,14 +1,16 @@
1
1
  {
2
2
  "name": "@netlify/config",
3
- "version": "18.2.4",
3
+ "version": "18.2.5",
4
4
  "description": "Netlify config module",
5
5
  "type": "module",
6
6
  "exports": "./lib/main.js",
7
7
  "main": "./lib/main.js",
8
+ "types": "./lib/main.d.ts",
8
9
  "bin": {
9
- "netlify-config": "lib/bin/main.js"
10
+ "netlify-config": "./bin.js"
10
11
  },
11
12
  "files": [
13
+ "bin.js",
12
14
  "lib/**/*.js"
13
15
  ],
14
16
  "author": "Netlify Inc.",
@@ -16,9 +18,10 @@
16
18
  "David Wells <hello@davidwells.io> (https://davidwells.io/)"
17
19
  ],
18
20
  "scripts": {
19
- "prepublishOnly": "cd ../../ && npm run prepublishOnly",
20
21
  "prebuild": "rm -rf lib",
21
- "build": "cp -a src lib/"
22
+ "build": "tsc",
23
+ "test": "ava",
24
+ "test:ci": "c8 -r lcovonly -r text -r json ava"
22
25
  },
23
26
  "keywords": [
24
27
  "javascript",
@@ -66,9 +69,9 @@
66
69
  "is-plain-obj": "^4.0.0",
67
70
  "js-yaml": "^4.0.0",
68
71
  "map-obj": "^5.0.0",
69
- "netlify": "^12.0.1",
70
- "netlify-headers-parser": "^6.0.2",
71
- "netlify-redirect-parser": "13.0.5",
72
+ "netlify": "^12.0.2",
73
+ "netlify-headers-parser": "^6.0.3",
74
+ "netlify-redirect-parser": "^13.0.6",
72
75
  "omit.js": "^2.0.2",
73
76
  "p-locate": "^6.0.0",
74
77
  "path-exists": "^5.0.0",
@@ -80,6 +83,7 @@
80
83
  },
81
84
  "devDependencies": {
82
85
  "ava": "^4.0.0",
86
+ "c8": "^7.12.0",
83
87
  "del": "^6.0.0",
84
88
  "has-ansi": "^5.0.0",
85
89
  "is-ci": "^3.0.0",
@@ -87,5 +91,6 @@
87
91
  },
88
92
  "engines": {
89
93
  "node": "^12.20.0 || ^14.14.0 || >=16.0.0"
90
- }
94
+ },
95
+ "gitHead": "5555ff52d82f1c26f2074ee52d5e7c5c6c8d02d2"
91
96
  }