@vercel/config 0.0.21 → 0.0.22
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 +7 -9
- package/dist/router.d.ts +71 -30
- package/dist/router.js +13 -72
- package/dist/types.d.ts +3 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -13,10 +13,8 @@ npm install @vercel/config
|
|
|
13
13
|
Create a `vercel.ts` file in your project root:
|
|
14
14
|
|
|
15
15
|
```typescript
|
|
16
|
-
import {
|
|
17
|
-
import type { VercelConfig } from '@vercel/config';
|
|
18
|
-
|
|
19
|
-
const router = createRouter();
|
|
16
|
+
import { routes } from '@vercel/config/v1';
|
|
17
|
+
import type { VercelConfig } from '@vercel/config/v1';
|
|
20
18
|
|
|
21
19
|
export const config: VercelConfig = {
|
|
22
20
|
buildCommand: 'npm run build',
|
|
@@ -24,10 +22,10 @@ export const config: VercelConfig = {
|
|
|
24
22
|
|
|
25
23
|
rewrites: [
|
|
26
24
|
// Simple rewrite
|
|
27
|
-
|
|
25
|
+
routes.rewrite('/api/(.*)', 'https://backend.api.example.com/$1'),
|
|
28
26
|
|
|
29
27
|
// Rewrite with transforms
|
|
30
|
-
|
|
28
|
+
routes.rewrite('/users/:userId', 'https://api.example.com/users/$1',
|
|
31
29
|
({ userId, env }) => ({
|
|
32
30
|
requestHeaders: {
|
|
33
31
|
'x-user-id': userId,
|
|
@@ -38,11 +36,11 @@ export const config: VercelConfig = {
|
|
|
38
36
|
],
|
|
39
37
|
|
|
40
38
|
redirects: [
|
|
41
|
-
|
|
39
|
+
routes.redirect('/old-docs', '/docs', { permanent: true })
|
|
42
40
|
],
|
|
43
41
|
|
|
44
42
|
headers: [
|
|
45
|
-
|
|
43
|
+
routes.cacheControl('/static/(.*)', {
|
|
46
44
|
public: true,
|
|
47
45
|
maxAge: '1 week',
|
|
48
46
|
immutable: true
|
|
@@ -58,7 +56,7 @@ export const config: VercelConfig = {
|
|
|
58
56
|
## Features
|
|
59
57
|
|
|
60
58
|
- **Type-safe configuration** - Full TypeScript support with IDE autocomplete
|
|
61
|
-
- **Readable syntax** - Helper methods like `
|
|
59
|
+
- **Readable syntax** - Helper methods like `routes.redirect()`, `routes.rewrite()`, `routes.header()`
|
|
62
60
|
- **Transforms** - Modify request/response headers and query parameters on the fly
|
|
63
61
|
- **Conditions** - Advanced routing with `has` and `missing` conditions
|
|
64
62
|
- **CLI tools** - `compile` and `validate` commands for development
|
package/dist/router.d.ts
CHANGED
|
@@ -1,21 +1,35 @@
|
|
|
1
1
|
import type { Redirect, Rewrite } from './types';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
3
|
+
* Type utility to extract path parameter names from a route pattern string.
|
|
4
|
+
* Supports :paramName syntax used in path-to-regexp patterns.
|
|
5
5
|
*
|
|
6
6
|
* @example
|
|
7
|
-
*
|
|
7
|
+
* ExtractPathParams<'/users/:userId/posts/:postId'> // 'userId' | 'postId'
|
|
8
|
+
* ExtractPathParams<'/api/(.*)'> // never
|
|
8
9
|
*/
|
|
9
|
-
|
|
10
|
+
type ExtractPathParams<T extends string> = T extends `${string}:${infer Param}/${infer Rest}` ? (Param extends `${infer P}(${string}` ? P : Param) | ExtractPathParams<`/${Rest}`> : T extends `${string}:${infer Param}` ? Param extends `${infer P}(${string}` ? P : Param : never;
|
|
10
11
|
/**
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
|
|
12
|
+
* Creates an object type where keys are the extracted path parameter names
|
|
13
|
+
* and values are strings (the resolved $paramName values).
|
|
14
|
+
*/
|
|
15
|
+
type PathParams<T extends string> = {
|
|
16
|
+
[K in ExtractPathParams<T>]: string;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Helper function to reference a Vercel project environment variable.
|
|
20
|
+
* These are placeholders that get resolved at request time by Vercel's routing layer.
|
|
21
|
+
* They are set per-deployment and don't change until you redeploy.
|
|
14
22
|
*
|
|
15
23
|
* @example
|
|
16
|
-
*
|
|
24
|
+
* // Usage in rewrites with type-safe path params:
|
|
25
|
+
* routes.rewrite('/users/:userId', 'https://api.example.com/$1', ({ userId }) => ({
|
|
26
|
+
* requestHeaders: {
|
|
27
|
+
* 'x-user-id': userId,
|
|
28
|
+
* 'authorization': `Bearer ${deploymentEnv('API_KEY')}`
|
|
29
|
+
* }
|
|
30
|
+
* }))
|
|
17
31
|
*/
|
|
18
|
-
export declare function
|
|
32
|
+
export declare function deploymentEnv(name: string): string;
|
|
19
33
|
/**
|
|
20
34
|
* Template literal type for durations recognized by pretty-cache-header.
|
|
21
35
|
*
|
|
@@ -489,11 +503,6 @@ export declare class Router {
|
|
|
489
503
|
* extractPathParams('/users/:userId/posts/:postId') // Returns ['userId', 'postId']
|
|
490
504
|
*/
|
|
491
505
|
private extractPathParams;
|
|
492
|
-
/**
|
|
493
|
-
* Creates a Proxy object that tracks environment variable accesses.
|
|
494
|
-
* Returns both the proxy and a set of accessed environment variable names.
|
|
495
|
-
*/
|
|
496
|
-
private createEnvProxy;
|
|
497
506
|
/**
|
|
498
507
|
* Creates a rewrite rule. Returns either a Rewrite object (simple case) or Route with transforms.
|
|
499
508
|
*
|
|
@@ -501,27 +510,42 @@ export declare class Router {
|
|
|
501
510
|
* // Simple rewrite
|
|
502
511
|
* router.rewrite('/api/(.*)', 'https://old-on-prem.com/$1')
|
|
503
512
|
*
|
|
504
|
-
* // With transforms
|
|
505
|
-
* router.rewrite('/
|
|
506
|
-
* requestHeaders: {
|
|
513
|
+
* // With transforms but no path params
|
|
514
|
+
* router.rewrite('/(.*)', 'https://api.example.com/$1', {
|
|
515
|
+
* requestHeaders: {
|
|
516
|
+
* 'authorization': `Bearer ${deploymentEnv('API_KEY')}`
|
|
517
|
+
* }
|
|
518
|
+
* })
|
|
519
|
+
*
|
|
520
|
+
* // With type-safe path params
|
|
521
|
+
* router.rewrite('/users/:userId', 'https://api.example.com/users/$1', ({ userId }) => ({
|
|
522
|
+
* requestHeaders: {
|
|
523
|
+
* 'x-user-id': userId,
|
|
524
|
+
* 'authorization': `Bearer ${deploymentEnv('API_KEY')}`
|
|
525
|
+
* }
|
|
507
526
|
* }))
|
|
527
|
+
*
|
|
528
|
+
* // With conditions only
|
|
529
|
+
* router.rewrite('/admin/(.*)', 'https://admin.example.com/$1', {
|
|
530
|
+
* has: [{ type: 'header', key: 'x-admin-token' }]
|
|
531
|
+
* })
|
|
508
532
|
* @internal Can return Route with transforms internally
|
|
509
533
|
*/
|
|
510
|
-
rewrite(source:
|
|
534
|
+
rewrite<T extends string>(source: T, destination: string): Rewrite | Route;
|
|
535
|
+
rewrite<T extends string>(source: T, destination: string, callback: (params: PathParams<T>) => {
|
|
511
536
|
has?: Condition[];
|
|
512
537
|
missing?: Condition[];
|
|
513
538
|
requestHeaders?: Record<string, string | string[]>;
|
|
514
539
|
responseHeaders?: Record<string, string | string[]>;
|
|
515
540
|
requestQuery?: Record<string, string | string[]>;
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
}) => {
|
|
541
|
+
}): Rewrite | Route;
|
|
542
|
+
rewrite<T extends string>(source: T, destination: string, options: ({
|
|
519
543
|
has?: Condition[];
|
|
520
544
|
missing?: Condition[];
|
|
521
545
|
requestHeaders?: Record<string, string | string[]>;
|
|
522
546
|
responseHeaders?: Record<string, string | string[]>;
|
|
523
547
|
requestQuery?: Record<string, string | string[]>;
|
|
524
|
-
})): Rewrite | Route;
|
|
548
|
+
}) & Record<never, never>): Rewrite | Route;
|
|
525
549
|
/**
|
|
526
550
|
* Creates a redirect rule. Returns either a Redirect object (simple case) or Route with transforms.
|
|
527
551
|
*
|
|
@@ -529,28 +553,44 @@ export declare class Router {
|
|
|
529
553
|
* // Simple redirect
|
|
530
554
|
* router.redirect('/old-path', '/new-path', { permanent: true })
|
|
531
555
|
*
|
|
532
|
-
* // With transforms
|
|
533
|
-
* router.redirect('/
|
|
556
|
+
* // With transforms but no path params
|
|
557
|
+
* router.redirect('/old', '/new', {
|
|
558
|
+
* permanent: true,
|
|
559
|
+
* requestHeaders: {
|
|
560
|
+
* 'x-api-key': deploymentEnv('API_KEY')
|
|
561
|
+
* }
|
|
562
|
+
* })
|
|
563
|
+
*
|
|
564
|
+
* // With type-safe path params
|
|
565
|
+
* router.redirect('/users/:userId', '/new-users/$1', ({ userId }) => ({
|
|
534
566
|
* permanent: true,
|
|
535
|
-
* requestHeaders: {
|
|
567
|
+
* requestHeaders: {
|
|
568
|
+
* 'x-user-id': userId,
|
|
569
|
+
* 'x-api-key': deploymentEnv('API_KEY')
|
|
570
|
+
* }
|
|
536
571
|
* }))
|
|
572
|
+
*
|
|
573
|
+
* // With conditions only
|
|
574
|
+
* router.redirect('/dashboard/(.*)', '/login', {
|
|
575
|
+
* missing: [{ type: 'cookie', key: 'auth-token' }]
|
|
576
|
+
* })
|
|
537
577
|
* @internal Can return Route with transforms internally
|
|
538
578
|
*/
|
|
539
|
-
redirect(source:
|
|
579
|
+
redirect<T extends string>(source: T, destination: string): Redirect | Route;
|
|
580
|
+
redirect<T extends string>(source: T, destination: string, callback: (params: PathParams<T>) => {
|
|
540
581
|
permanent?: boolean;
|
|
541
582
|
statusCode?: number;
|
|
542
583
|
has?: Condition[];
|
|
543
584
|
missing?: Condition[];
|
|
544
585
|
requestHeaders?: Record<string, string | string[]>;
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
}) => {
|
|
586
|
+
}): Redirect | Route;
|
|
587
|
+
redirect<T extends string>(source: T, destination: string, options: {
|
|
548
588
|
permanent?: boolean;
|
|
549
589
|
statusCode?: number;
|
|
550
590
|
has?: Condition[];
|
|
551
591
|
missing?: Condition[];
|
|
552
592
|
requestHeaders?: Record<string, string | string[]>;
|
|
553
|
-
})
|
|
593
|
+
}): Redirect | Route;
|
|
554
594
|
/**
|
|
555
595
|
* Creates a header rule matching the vercel.json schema.
|
|
556
596
|
* @example
|
|
@@ -647,3 +687,4 @@ export declare function createRoutes(): Router;
|
|
|
647
687
|
* routes.redirect('/old', '/new');
|
|
648
688
|
*/
|
|
649
689
|
export declare const routes: Router;
|
|
690
|
+
export {};
|
package/dist/router.js
CHANGED
|
@@ -1,31 +1,26 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.routes = exports.createRoutes = exports.Router = exports.
|
|
3
|
+
exports.routes = exports.createRoutes = exports.Router = exports.deploymentEnv = void 0;
|
|
4
4
|
const pretty_cache_header_1 = require("pretty-cache-header");
|
|
5
5
|
const validation_1 = require("./utils/validation");
|
|
6
6
|
/**
|
|
7
|
-
* Helper function to reference a
|
|
8
|
-
*
|
|
7
|
+
* Helper function to reference a Vercel project environment variable.
|
|
8
|
+
* These are placeholders that get resolved at request time by Vercel's routing layer.
|
|
9
|
+
* They are set per-deployment and don't change until you redeploy.
|
|
9
10
|
*
|
|
10
11
|
* @example
|
|
11
|
-
*
|
|
12
|
+
* // Usage in rewrites with type-safe path params:
|
|
13
|
+
* routes.rewrite('/users/:userId', 'https://api.example.com/$1', ({ userId }) => ({
|
|
14
|
+
* requestHeaders: {
|
|
15
|
+
* 'x-user-id': userId,
|
|
16
|
+
* 'authorization': `Bearer ${deploymentEnv('API_KEY')}`
|
|
17
|
+
* }
|
|
18
|
+
* }))
|
|
12
19
|
*/
|
|
13
|
-
function
|
|
20
|
+
function deploymentEnv(name) {
|
|
14
21
|
return `$${name}`;
|
|
15
22
|
}
|
|
16
|
-
exports.
|
|
17
|
-
/**
|
|
18
|
-
* Helper function to reference a runtime environment variable in transforms.
|
|
19
|
-
* These are environment variables that get resolved at request time by Vercel's routing layer,
|
|
20
|
-
* not at build time.
|
|
21
|
-
*
|
|
22
|
-
* @example
|
|
23
|
-
* runtimeEnv('BEARER_TOKEN') // Returns '$BEARER_TOKEN'
|
|
24
|
-
*/
|
|
25
|
-
function runtimeEnv(name) {
|
|
26
|
-
return `$${name}`;
|
|
27
|
-
}
|
|
28
|
-
exports.runtimeEnv = runtimeEnv;
|
|
23
|
+
exports.deploymentEnv = deploymentEnv;
|
|
29
24
|
/**
|
|
30
25
|
* Extract environment variable names from a string or array of strings
|
|
31
26
|
* Returns env var names without the $ prefix, excluding path parameters
|
|
@@ -77,50 +72,15 @@ class Router {
|
|
|
77
72
|
}
|
|
78
73
|
return params;
|
|
79
74
|
}
|
|
80
|
-
/**
|
|
81
|
-
* Creates a Proxy object that tracks environment variable accesses.
|
|
82
|
-
* Returns both the proxy and a set of accessed environment variable names.
|
|
83
|
-
*/
|
|
84
|
-
createEnvProxy() {
|
|
85
|
-
const accessedVars = new Set();
|
|
86
|
-
const proxy = new Proxy({}, {
|
|
87
|
-
get(_target, prop) {
|
|
88
|
-
if (typeof prop === 'string') {
|
|
89
|
-
accessedVars.add(prop);
|
|
90
|
-
return `$${prop}`;
|
|
91
|
-
}
|
|
92
|
-
return undefined;
|
|
93
|
-
}
|
|
94
|
-
});
|
|
95
|
-
return { proxy, accessedVars };
|
|
96
|
-
}
|
|
97
|
-
/**
|
|
98
|
-
* Creates a rewrite rule. Returns either a Rewrite object (simple case) or Route with transforms.
|
|
99
|
-
*
|
|
100
|
-
* @example
|
|
101
|
-
* // Simple rewrite
|
|
102
|
-
* router.rewrite('/api/(.*)', 'https://old-on-prem.com/$1')
|
|
103
|
-
*
|
|
104
|
-
* // With transforms
|
|
105
|
-
* router.rewrite('/users/:userId', 'https://api.example.com/users/$1', ({userId, env}) => ({
|
|
106
|
-
* requestHeaders: { 'x-user-id': userId }
|
|
107
|
-
* }))
|
|
108
|
-
* @internal Can return Route with transforms internally
|
|
109
|
-
*/
|
|
110
75
|
rewrite(source, destination, optionsOrCallback) {
|
|
111
76
|
this.validateSourcePattern(source);
|
|
112
77
|
let options;
|
|
113
|
-
// Handle callback syntax
|
|
114
78
|
if (typeof optionsOrCallback === 'function') {
|
|
115
79
|
const pathParams = this.extractPathParams(source);
|
|
116
|
-
const { proxy: envProxy } = this.createEnvProxy();
|
|
117
|
-
// Create params object with path parameters as $paramName
|
|
118
80
|
const paramsObj = {};
|
|
119
81
|
for (const param of pathParams) {
|
|
120
82
|
paramsObj[param] = `$${param}`;
|
|
121
83
|
}
|
|
122
|
-
paramsObj.env = envProxy;
|
|
123
|
-
// Call the callback to get options
|
|
124
84
|
options = optionsOrCallback(paramsObj);
|
|
125
85
|
}
|
|
126
86
|
else {
|
|
@@ -200,34 +160,15 @@ class Router {
|
|
|
200
160
|
rewrite.missing = missing;
|
|
201
161
|
return rewrite;
|
|
202
162
|
}
|
|
203
|
-
/**
|
|
204
|
-
* Creates a redirect rule. Returns either a Redirect object (simple case) or Route with transforms.
|
|
205
|
-
*
|
|
206
|
-
* @example
|
|
207
|
-
* // Simple redirect
|
|
208
|
-
* router.redirect('/old-path', '/new-path', { permanent: true })
|
|
209
|
-
*
|
|
210
|
-
* // With transforms
|
|
211
|
-
* router.redirect('/users/:userId', '/new-users/$1', ({userId, env}) => ({
|
|
212
|
-
* permanent: true,
|
|
213
|
-
* requestHeaders: { 'x-user-id': userId }
|
|
214
|
-
* }))
|
|
215
|
-
* @internal Can return Route with transforms internally
|
|
216
|
-
*/
|
|
217
163
|
redirect(source, destination, optionsOrCallback) {
|
|
218
164
|
this.validateSourcePattern(source);
|
|
219
165
|
let options;
|
|
220
|
-
// Handle callback syntax
|
|
221
166
|
if (typeof optionsOrCallback === 'function') {
|
|
222
167
|
const pathParams = this.extractPathParams(source);
|
|
223
|
-
const { proxy: envProxy } = this.createEnvProxy();
|
|
224
|
-
// Create params object with path parameters as $paramName
|
|
225
168
|
const paramsObj = {};
|
|
226
169
|
for (const param of pathParams) {
|
|
227
170
|
paramsObj[param] = `$${param}`;
|
|
228
171
|
}
|
|
229
|
-
paramsObj.env = envProxy;
|
|
230
|
-
// Call the callback to get options
|
|
231
172
|
options = optionsOrCallback(paramsObj);
|
|
232
173
|
}
|
|
233
174
|
else {
|
package/dist/types.d.ts
CHANGED
|
@@ -149,7 +149,7 @@ export interface Condition {
|
|
|
149
149
|
}
|
|
150
150
|
/**
|
|
151
151
|
* Redirect matching vercel.json schema
|
|
152
|
-
* Returned by
|
|
152
|
+
* Returned by routes.redirect()
|
|
153
153
|
*/
|
|
154
154
|
export interface Redirect {
|
|
155
155
|
source: string;
|
|
@@ -161,7 +161,7 @@ export interface Redirect {
|
|
|
161
161
|
}
|
|
162
162
|
/**
|
|
163
163
|
* Rewrite matching vercel.json schema
|
|
164
|
-
* Returned by
|
|
164
|
+
* Returned by routes.rewrite()
|
|
165
165
|
*/
|
|
166
166
|
export interface Rewrite {
|
|
167
167
|
source: string;
|
|
@@ -171,7 +171,7 @@ export interface Rewrite {
|
|
|
171
171
|
}
|
|
172
172
|
/**
|
|
173
173
|
* Header rule matching vercel.json schema
|
|
174
|
-
* Returned by
|
|
174
|
+
* Returned by routes.header() and routes.cacheControl()
|
|
175
175
|
*/
|
|
176
176
|
export interface HeaderRule {
|
|
177
177
|
source: string;
|