@vercel/config 0.0.14 → 0.0.16
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/README.md +75 -298
- package/dist/cli.js +57 -28
- package/dist/index.d.ts +2 -1
- package/dist/index.js +7 -1
- package/dist/router.d.ts +35 -97
- package/dist/router.js +117 -301
- package/dist/types.d.ts +57 -3
- package/dist/utils/validation.d.ts +27 -0
- package/dist/utils/validation.js +96 -1
- package/dist/v1/index.d.ts +9 -0
- package/dist/v1/index.js +27 -0
- package/package.json +15 -1
package/dist/router.js
CHANGED
|
@@ -111,187 +111,35 @@ class Router {
|
|
|
111
111
|
});
|
|
112
112
|
return { proxy, accessedVars };
|
|
113
113
|
}
|
|
114
|
+
// Deprecated: extractEnvVars method no longer needed after refactor
|
|
114
115
|
/**
|
|
115
|
-
*
|
|
116
|
-
* Environment variables are identified by the pattern $VAR_NAME where VAR_NAME
|
|
117
|
-
* is typically uppercase with underscores (e.g., $API_KEY, $BEARER_TOKEN).
|
|
118
|
-
*/
|
|
119
|
-
extractEnvVars(args) {
|
|
120
|
-
const envVars = new Set();
|
|
121
|
-
const values = Array.isArray(args) ? args : [args];
|
|
122
|
-
for (const value of values) {
|
|
123
|
-
const matches = value.match(/\$([A-Z][A-Z0-9_]*)/g);
|
|
124
|
-
if (matches) {
|
|
125
|
-
for (const match of matches) {
|
|
126
|
-
envVars.add(match.substring(1));
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
return Array.from(envVars);
|
|
131
|
-
}
|
|
132
|
-
/**
|
|
116
|
+
* @deprecated No longer used after refactor to return schema objects directly
|
|
133
117
|
* Internal helper to convert TransformOptions to Transform array
|
|
134
118
|
* @param options Transform options to convert
|
|
135
119
|
* @param trackedEnvVars Optional set of environment variables that were accessed via the env proxy
|
|
136
120
|
*/
|
|
137
|
-
transformOptionsToTransforms
|
|
138
|
-
const transforms = [];
|
|
139
|
-
// Helper to get env vars for a value
|
|
140
|
-
const getEnvVars = (value) => {
|
|
141
|
-
if (trackedEnvVars) {
|
|
142
|
-
return Array.from(trackedEnvVars).filter(envVar => {
|
|
143
|
-
const valueStr = Array.isArray(value) ? value.join(' ') : value;
|
|
144
|
-
return valueStr.includes(`$${envVar}`);
|
|
145
|
-
});
|
|
146
|
-
}
|
|
147
|
-
return this.extractEnvVars(value);
|
|
148
|
-
};
|
|
149
|
-
// SET operations
|
|
150
|
-
// Convert requestHeaders (set)
|
|
151
|
-
if (options.requestHeaders) {
|
|
152
|
-
for (const [key, value] of Object.entries(options.requestHeaders)) {
|
|
153
|
-
const envVars = getEnvVars(value);
|
|
154
|
-
transforms.push({
|
|
155
|
-
type: 'request.headers',
|
|
156
|
-
op: 'set',
|
|
157
|
-
target: { key },
|
|
158
|
-
args: value,
|
|
159
|
-
...(envVars.length > 0 && { env: envVars }),
|
|
160
|
-
});
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
// Convert responseHeaders (set)
|
|
164
|
-
if (options.responseHeaders) {
|
|
165
|
-
for (const [key, value] of Object.entries(options.responseHeaders)) {
|
|
166
|
-
const envVars = getEnvVars(value);
|
|
167
|
-
transforms.push({
|
|
168
|
-
type: 'response.headers',
|
|
169
|
-
op: 'set',
|
|
170
|
-
target: { key },
|
|
171
|
-
args: value,
|
|
172
|
-
...(envVars.length > 0 && { env: envVars }),
|
|
173
|
-
});
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
// Convert requestQuery (set)
|
|
177
|
-
if (options.requestQuery) {
|
|
178
|
-
for (const [key, value] of Object.entries(options.requestQuery)) {
|
|
179
|
-
const envVars = getEnvVars(value);
|
|
180
|
-
transforms.push({
|
|
181
|
-
type: 'request.query',
|
|
182
|
-
op: 'set',
|
|
183
|
-
target: { key },
|
|
184
|
-
args: value,
|
|
185
|
-
...(envVars.length > 0 && { env: envVars }),
|
|
186
|
-
});
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
// APPEND operations
|
|
190
|
-
// Convert appendRequestHeaders
|
|
191
|
-
if (options.appendRequestHeaders) {
|
|
192
|
-
for (const [key, value] of Object.entries(options.appendRequestHeaders)) {
|
|
193
|
-
const envVars = getEnvVars(value);
|
|
194
|
-
transforms.push({
|
|
195
|
-
type: 'request.headers',
|
|
196
|
-
op: 'append',
|
|
197
|
-
target: { key },
|
|
198
|
-
args: value,
|
|
199
|
-
...(envVars.length > 0 && { env: envVars }),
|
|
200
|
-
});
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
// Convert appendResponseHeaders
|
|
204
|
-
if (options.appendResponseHeaders) {
|
|
205
|
-
for (const [key, value] of Object.entries(options.appendResponseHeaders)) {
|
|
206
|
-
const envVars = getEnvVars(value);
|
|
207
|
-
transforms.push({
|
|
208
|
-
type: 'response.headers',
|
|
209
|
-
op: 'append',
|
|
210
|
-
target: { key },
|
|
211
|
-
args: value,
|
|
212
|
-
...(envVars.length > 0 && { env: envVars }),
|
|
213
|
-
});
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
// Convert appendRequestQuery
|
|
217
|
-
if (options.appendRequestQuery) {
|
|
218
|
-
for (const [key, value] of Object.entries(options.appendRequestQuery)) {
|
|
219
|
-
const envVars = getEnvVars(value);
|
|
220
|
-
transforms.push({
|
|
221
|
-
type: 'request.query',
|
|
222
|
-
op: 'append',
|
|
223
|
-
target: { key },
|
|
224
|
-
args: value,
|
|
225
|
-
...(envVars.length > 0 && { env: envVars }),
|
|
226
|
-
});
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
// DELETE operations
|
|
230
|
-
// Convert deleteRequestHeaders
|
|
231
|
-
if (options.deleteRequestHeaders) {
|
|
232
|
-
for (const key of options.deleteRequestHeaders) {
|
|
233
|
-
transforms.push({
|
|
234
|
-
type: 'request.headers',
|
|
235
|
-
op: 'delete',
|
|
236
|
-
target: { key },
|
|
237
|
-
});
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
// Convert deleteResponseHeaders
|
|
241
|
-
if (options.deleteResponseHeaders) {
|
|
242
|
-
for (const key of options.deleteResponseHeaders) {
|
|
243
|
-
transforms.push({
|
|
244
|
-
type: 'response.headers',
|
|
245
|
-
op: 'delete',
|
|
246
|
-
target: { key },
|
|
247
|
-
});
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
// Convert deleteRequestQuery
|
|
251
|
-
if (options.deleteRequestQuery) {
|
|
252
|
-
for (const key of options.deleteRequestQuery) {
|
|
253
|
-
transforms.push({
|
|
254
|
-
type: 'request.query',
|
|
255
|
-
op: 'delete',
|
|
256
|
-
target: { key },
|
|
257
|
-
});
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
return transforms;
|
|
261
|
-
}
|
|
121
|
+
// Deprecated: transformOptionsToTransforms method removed after refactor
|
|
262
122
|
/**
|
|
263
|
-
*
|
|
264
|
-
* Automatically enables rewrite caching by adding the x-vercel-enable-rewrite-caching header.
|
|
123
|
+
* Creates a rewrite rule. Returns either a Rewrite object (simple case) or Route with transforms.
|
|
265
124
|
*
|
|
266
125
|
* @example
|
|
267
126
|
* // Simple rewrite
|
|
268
127
|
* router.rewrite('/api/(.*)', 'https://old-on-prem.com/$1')
|
|
269
128
|
*
|
|
270
|
-
* // With transforms
|
|
129
|
+
* // With transforms
|
|
271
130
|
* router.rewrite('/users/:userId', 'https://api.example.com/users/$1', ({userId, env}) => ({
|
|
272
|
-
* requestHeaders: {
|
|
273
|
-
*
|
|
274
|
-
*
|
|
275
|
-
* }
|
|
276
|
-
* }));
|
|
277
|
-
*
|
|
278
|
-
* // With transforms using object (legacy)
|
|
279
|
-
* router.rewrite('/users/:userId', 'https://api.example.com/users/$1', {
|
|
280
|
-
* requestHeaders: {
|
|
281
|
-
* 'x-user-id': param('userId')
|
|
282
|
-
* }
|
|
283
|
-
* });
|
|
131
|
+
* requestHeaders: { 'x-user-id': userId }
|
|
132
|
+
* }))
|
|
133
|
+
* @internal Can return Route with transforms internally
|
|
284
134
|
*/
|
|
285
135
|
rewrite(source, destination, optionsOrCallback) {
|
|
286
136
|
this.validateSourcePattern(source);
|
|
287
137
|
(0, validation_1.validateCaptureGroupReferences)(source, destination);
|
|
288
138
|
let options;
|
|
289
|
-
let trackedEnvVars;
|
|
290
139
|
// Handle callback syntax
|
|
291
140
|
if (typeof optionsOrCallback === 'function') {
|
|
292
141
|
const pathParams = this.extractPathParams(source);
|
|
293
|
-
const { proxy: envProxy
|
|
294
|
-
trackedEnvVars = accessedVars;
|
|
142
|
+
const { proxy: envProxy } = this.createEnvProxy();
|
|
295
143
|
// Create params object with path parameters as $paramName
|
|
296
144
|
const paramsObj = {};
|
|
297
145
|
for (const param of pathParams) {
|
|
@@ -304,101 +152,86 @@ class Router {
|
|
|
304
152
|
else {
|
|
305
153
|
options = optionsOrCallback;
|
|
306
154
|
}
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
const
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
155
|
+
const { has, missing, requestHeaders, responseHeaders, requestQuery } = options || {};
|
|
156
|
+
// Check if any transforms were provided
|
|
157
|
+
const hasTransforms = requestHeaders || responseHeaders || requestQuery;
|
|
158
|
+
if (hasTransforms) {
|
|
159
|
+
// Build a Route object with transforms
|
|
160
|
+
const transforms = [];
|
|
161
|
+
if (requestHeaders) {
|
|
162
|
+
for (const [key, value] of Object.entries(requestHeaders)) {
|
|
163
|
+
transforms.push({
|
|
164
|
+
type: 'request.headers',
|
|
165
|
+
op: 'set',
|
|
166
|
+
target: { key },
|
|
167
|
+
args: value,
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
if (responseHeaders) {
|
|
172
|
+
for (const [key, value] of Object.entries(responseHeaders)) {
|
|
173
|
+
transforms.push({
|
|
174
|
+
type: 'response.headers',
|
|
175
|
+
op: 'set',
|
|
176
|
+
target: { key },
|
|
177
|
+
args: value,
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
if (requestQuery) {
|
|
182
|
+
for (const [key, value] of Object.entries(requestQuery)) {
|
|
183
|
+
transforms.push({
|
|
184
|
+
type: 'request.query',
|
|
185
|
+
op: 'set',
|
|
186
|
+
target: { key },
|
|
187
|
+
args: value,
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
const route = {
|
|
192
|
+
src: source,
|
|
193
|
+
dest: destination,
|
|
194
|
+
transforms,
|
|
195
|
+
};
|
|
196
|
+
if (has)
|
|
197
|
+
route.has = has;
|
|
198
|
+
if (missing)
|
|
199
|
+
route.missing = missing;
|
|
200
|
+
return route;
|
|
201
|
+
}
|
|
202
|
+
// Simple rewrite without transforms
|
|
203
|
+
const rewrite = {
|
|
328
204
|
source,
|
|
329
205
|
destination,
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
has
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
// Only enable rewrite caching for rewrites without transforms
|
|
337
|
-
// (transforms convert to routes, which don't need the caching header)
|
|
338
|
-
if (!transforms) {
|
|
339
|
-
this.headerRules.push({
|
|
340
|
-
source,
|
|
341
|
-
headers: [{ key: 'x-vercel-enable-rewrite-caching', value: '1' }],
|
|
342
|
-
has,
|
|
343
|
-
missing,
|
|
344
|
-
});
|
|
345
|
-
}
|
|
346
|
-
return this;
|
|
206
|
+
};
|
|
207
|
+
if (has)
|
|
208
|
+
rewrite.has = has;
|
|
209
|
+
if (missing)
|
|
210
|
+
rewrite.missing = missing;
|
|
211
|
+
return rewrite;
|
|
347
212
|
}
|
|
348
213
|
/**
|
|
349
|
-
*
|
|
350
|
-
* Automatically enables rewrite caching for all loaded rules by adding the x-vercel-enable-rewrite-caching header.
|
|
214
|
+
* Creates a redirect rule. Returns either a Redirect object (simple case) or Route with transforms.
|
|
351
215
|
*
|
|
352
216
|
* @example
|
|
353
|
-
* // This will automatically enable caching for all rewrites
|
|
354
|
-
* await router.rewrites(() => fetchRewriteRulesFromDB());
|
|
355
|
-
*/
|
|
356
|
-
async rewrites(provider) {
|
|
357
|
-
const rules = await provider();
|
|
358
|
-
this.rewriteRules.push(...rules);
|
|
359
|
-
// Automatically enable rewrite caching for all rules
|
|
360
|
-
const headerRules = rules.map((rule) => ({
|
|
361
|
-
source: rule.source,
|
|
362
|
-
headers: [{ key: 'x-vercel-enable-rewrite-caching', value: '1' }],
|
|
363
|
-
has: rule.has,
|
|
364
|
-
missing: rule.missing,
|
|
365
|
-
}));
|
|
366
|
-
this.headerRules.push(...headerRules);
|
|
367
|
-
return this;
|
|
368
|
-
}
|
|
369
|
-
/**
|
|
370
|
-
* Adds a single redirect rule (synchronous).
|
|
371
|
-
* @example
|
|
372
217
|
* // Simple redirect
|
|
373
218
|
* router.redirect('/old-path', '/new-path', { permanent: true })
|
|
374
219
|
*
|
|
375
|
-
* // With transforms
|
|
220
|
+
* // With transforms
|
|
376
221
|
* router.redirect('/users/:userId', '/new-users/$1', ({userId, env}) => ({
|
|
377
222
|
* permanent: true,
|
|
378
|
-
* requestHeaders: {
|
|
379
|
-
* 'x-user-id': userId,
|
|
380
|
-
* 'x-api-key': env.API_KEY
|
|
381
|
-
* }
|
|
223
|
+
* requestHeaders: { 'x-user-id': userId }
|
|
382
224
|
* }))
|
|
383
|
-
*
|
|
384
|
-
* // With transforms using object (legacy)
|
|
385
|
-
* router.redirect('/users/:userId', '/new-users/$1', {
|
|
386
|
-
* permanent: true,
|
|
387
|
-
* requestHeaders: {
|
|
388
|
-
* 'x-user-id': param('userId')
|
|
389
|
-
* }
|
|
390
|
-
* })
|
|
225
|
+
* @internal Can return Route with transforms internally
|
|
391
226
|
*/
|
|
392
227
|
redirect(source, destination, optionsOrCallback) {
|
|
393
228
|
this.validateSourcePattern(source);
|
|
394
229
|
(0, validation_1.validateCaptureGroupReferences)(source, destination);
|
|
395
230
|
let options;
|
|
396
|
-
let trackedEnvVars;
|
|
397
231
|
// Handle callback syntax
|
|
398
232
|
if (typeof optionsOrCallback === 'function') {
|
|
399
233
|
const pathParams = this.extractPathParams(source);
|
|
400
|
-
const { proxy: envProxy
|
|
401
|
-
trackedEnvVars = accessedVars;
|
|
234
|
+
const { proxy: envProxy } = this.createEnvProxy();
|
|
402
235
|
// Create params object with path parameters as $paramName
|
|
403
236
|
const paramsObj = {};
|
|
404
237
|
for (const param of pathParams) {
|
|
@@ -411,92 +244,75 @@ class Router {
|
|
|
411
244
|
else {
|
|
412
245
|
options = optionsOrCallback;
|
|
413
246
|
}
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
deleteRequestHeaders,
|
|
429
|
-
deleteResponseHeaders,
|
|
430
|
-
deleteRequestQuery,
|
|
431
|
-
};
|
|
432
|
-
const transforms = this.transformOptionsToTransforms(transformOpts, trackedEnvVars);
|
|
433
|
-
this.routeRules.push({
|
|
247
|
+
const { permanent, statusCode, has, missing, requestHeaders } = options || {};
|
|
248
|
+
// Check if transforms were provided
|
|
249
|
+
if (requestHeaders) {
|
|
250
|
+
// Build a Route object with transforms
|
|
251
|
+
const transforms = [];
|
|
252
|
+
for (const [key, value] of Object.entries(requestHeaders)) {
|
|
253
|
+
transforms.push({
|
|
254
|
+
type: 'request.headers',
|
|
255
|
+
op: 'set',
|
|
256
|
+
target: { key },
|
|
257
|
+
args: value,
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
const route = {
|
|
434
261
|
src: source,
|
|
435
262
|
dest: destination,
|
|
436
|
-
...(methods && { methods }),
|
|
437
|
-
transforms,
|
|
438
263
|
redirect: true,
|
|
439
264
|
status: statusCode || (permanent ? 308 : 307),
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
destination,
|
|
448
|
-
permanent,
|
|
449
|
-
statusCode,
|
|
450
|
-
has,
|
|
451
|
-
missing,
|
|
452
|
-
});
|
|
265
|
+
transforms,
|
|
266
|
+
};
|
|
267
|
+
if (has)
|
|
268
|
+
route.has = has;
|
|
269
|
+
if (missing)
|
|
270
|
+
route.missing = missing;
|
|
271
|
+
return route;
|
|
453
272
|
}
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
273
|
+
// Simple redirect without transforms
|
|
274
|
+
const redirect = {
|
|
275
|
+
source,
|
|
276
|
+
destination,
|
|
277
|
+
};
|
|
278
|
+
if (permanent !== undefined)
|
|
279
|
+
redirect.permanent = permanent;
|
|
280
|
+
if (statusCode !== undefined)
|
|
281
|
+
redirect.statusCode = statusCode;
|
|
282
|
+
if (has)
|
|
283
|
+
redirect.has = has;
|
|
284
|
+
if (missing)
|
|
285
|
+
redirect.missing = missing;
|
|
286
|
+
return redirect;
|
|
463
287
|
}
|
|
464
288
|
/**
|
|
465
|
-
*
|
|
289
|
+
* Creates a header rule matching the vercel.json schema.
|
|
466
290
|
* @example
|
|
467
291
|
* router.header('/api/(.*)', [{ key: 'X-Custom', value: 'HelloWorld' }])
|
|
468
292
|
*/
|
|
469
293
|
header(source, headers, options) {
|
|
470
294
|
this.validateSourcePattern(source);
|
|
471
|
-
|
|
472
|
-
return this;
|
|
295
|
+
return { source, headers, ...options };
|
|
473
296
|
}
|
|
474
297
|
/**
|
|
475
|
-
*
|
|
476
|
-
|
|
477
|
-
async headers(provider) {
|
|
478
|
-
const rules = await provider();
|
|
479
|
-
this.headerRules.push(...rules);
|
|
480
|
-
return this;
|
|
481
|
-
}
|
|
482
|
-
/**
|
|
483
|
-
* Adds a typed "Cache-Control" header, leveraging `pretty-cache-header`.
|
|
484
|
-
* This method is purely for convenience, so you can do:
|
|
298
|
+
* Creates a Cache-Control header rule, leveraging `pretty-cache-header`.
|
|
299
|
+
* Returns a HeaderRule matching the vercel.json schema.
|
|
485
300
|
*
|
|
486
|
-
*
|
|
487
|
-
*
|
|
488
|
-
*
|
|
489
|
-
*
|
|
490
|
-
*
|
|
301
|
+
* @example
|
|
302
|
+
* router.cacheControl('/my-page', {
|
|
303
|
+
* public: true,
|
|
304
|
+
* maxAge: '1week',
|
|
305
|
+
* staleWhileRevalidate: '1year'
|
|
306
|
+
* })
|
|
491
307
|
*/
|
|
492
308
|
cacheControl(source, cacheOptions, options) {
|
|
309
|
+
this.validateSourcePattern(source);
|
|
493
310
|
const value = (0, pretty_cache_header_1.cacheHeader)(cacheOptions);
|
|
494
|
-
|
|
311
|
+
return {
|
|
495
312
|
source,
|
|
496
313
|
headers: [{ key: 'Cache-Control', value }],
|
|
497
314
|
...options,
|
|
498
|
-
}
|
|
499
|
-
return this;
|
|
315
|
+
};
|
|
500
316
|
}
|
|
501
317
|
/**
|
|
502
318
|
* Adds a route with transforms support.
|
package/dist/types.d.ts
CHANGED
|
@@ -34,19 +34,67 @@ export interface GithubConfig {
|
|
|
34
34
|
autoAlias?: boolean;
|
|
35
35
|
autoJobCancelation?: boolean;
|
|
36
36
|
}
|
|
37
|
+
/**
|
|
38
|
+
* HTTP header key/value pair
|
|
39
|
+
*/
|
|
37
40
|
export interface Header {
|
|
38
41
|
key: string;
|
|
39
42
|
value: string;
|
|
40
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* Condition for matching in redirects, rewrites, and headers
|
|
46
|
+
*/
|
|
47
|
+
export interface Condition {
|
|
48
|
+
type: 'header' | 'cookie' | 'host' | 'query' | 'path';
|
|
49
|
+
key?: string;
|
|
50
|
+
value?: string | number;
|
|
51
|
+
inc?: string[];
|
|
52
|
+
pre?: string;
|
|
53
|
+
eq?: string | number;
|
|
54
|
+
neq?: string;
|
|
55
|
+
gt?: number;
|
|
56
|
+
gte?: number;
|
|
57
|
+
lt?: number;
|
|
58
|
+
lte?: number;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Redirect matching vercel.json schema
|
|
62
|
+
* Returned by router.redirect()
|
|
63
|
+
*/
|
|
64
|
+
export interface Redirect {
|
|
65
|
+
source: string;
|
|
66
|
+
destination: string;
|
|
67
|
+
permanent?: boolean;
|
|
68
|
+
statusCode?: number;
|
|
69
|
+
has?: Condition[];
|
|
70
|
+
missing?: Condition[];
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Rewrite matching vercel.json schema
|
|
74
|
+
* Returned by router.rewrite()
|
|
75
|
+
*/
|
|
76
|
+
export interface Rewrite {
|
|
77
|
+
source: string;
|
|
78
|
+
destination: string;
|
|
79
|
+
has?: Condition[];
|
|
80
|
+
missing?: Condition[];
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Header rule matching vercel.json schema
|
|
84
|
+
* Returned by router.header() and router.cacheControl()
|
|
85
|
+
*/
|
|
41
86
|
export interface HeaderRule {
|
|
42
87
|
source: string;
|
|
43
88
|
headers: Header[];
|
|
89
|
+
has?: Condition[];
|
|
90
|
+
missing?: Condition[];
|
|
44
91
|
}
|
|
45
92
|
/**
|
|
46
|
-
*
|
|
47
|
-
*
|
|
93
|
+
* Union type for all router helper outputs
|
|
94
|
+
* Can be simple schema objects (Redirect, Rewrite, HeaderRule) or Routes with transforms
|
|
95
|
+
* Note: Route type is defined in router.ts (uses src/dest instead of source/destination)
|
|
48
96
|
*/
|
|
49
|
-
export type RouteType = any;
|
|
97
|
+
export type RouteType = Redirect | Rewrite | HeaderRule | any;
|
|
50
98
|
export interface WildcardDomain {
|
|
51
99
|
domain: string;
|
|
52
100
|
value: string;
|
|
@@ -103,6 +151,12 @@ export interface VercelConfig {
|
|
|
103
151
|
* Can use router.rewrite() helper.
|
|
104
152
|
*/
|
|
105
153
|
rewrites?: RouteType[];
|
|
154
|
+
/**
|
|
155
|
+
* Routes configuration using the lower-level routes primitive.
|
|
156
|
+
* Use this if you need transforms or want everything in one place.
|
|
157
|
+
* Cannot be mixed with headers, redirects, or rewrites.
|
|
158
|
+
*/
|
|
159
|
+
routes?: RouteType[];
|
|
106
160
|
/**
|
|
107
161
|
* Wildcard domain configuration.
|
|
108
162
|
*/
|
|
@@ -41,3 +41,30 @@ export declare function countCaptureGroups(pattern: string): number;
|
|
|
41
41
|
* that don't exist in the source pattern.
|
|
42
42
|
*/
|
|
43
43
|
export declare function validateCaptureGroupReferences(source: string, destination: string): void;
|
|
44
|
+
/**
|
|
45
|
+
* Validates that a value is a static string literal (not computed, not a function call, etc.)
|
|
46
|
+
* Used for static fields that must be extracted before build execution.
|
|
47
|
+
*/
|
|
48
|
+
export declare function validateStaticString(value: any, fieldName: string): void;
|
|
49
|
+
/**
|
|
50
|
+
* Validates that a value is a static boolean literal
|
|
51
|
+
*/
|
|
52
|
+
export declare function validateStaticBoolean(value: any, fieldName: string): void;
|
|
53
|
+
/**
|
|
54
|
+
* Validates that a value is a static object with primitive values
|
|
55
|
+
* Used for git.deploymentEnabled and similar objects that need to be static
|
|
56
|
+
*/
|
|
57
|
+
export declare function validateStaticObject(value: any, fieldName: string): void;
|
|
58
|
+
/**
|
|
59
|
+
* Validates that a value is a static array of strings
|
|
60
|
+
*/
|
|
61
|
+
export declare function validateStaticStringArray(value: any, fieldName: string): void;
|
|
62
|
+
/**
|
|
63
|
+
* Validates static fields in VercelConfig that must be extracted before build execution.
|
|
64
|
+
* These fields include:
|
|
65
|
+
* - buildCommand, devCommand, installCommand, framework, nodeVersion, outputDirectory
|
|
66
|
+
* - github.enabled, github.autoAlias, github.autoJobCancelation
|
|
67
|
+
* - git.deploymentEnabled
|
|
68
|
+
* - relatedProjects
|
|
69
|
+
*/
|
|
70
|
+
export declare function validateStaticFields(config: Record<string, any>): void;
|