@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 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 { createRouter } from '@vercel/config';
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
- router.rewrite('/api/(.*)', 'https://backend.api.example.com/$1'),
25
+ routes.rewrite('/api/(.*)', 'https://backend.api.example.com/$1'),
28
26
 
29
27
  // Rewrite with transforms
30
- router.rewrite('/users/:userId', 'https://api.example.com/users/$1',
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
- router.redirect('/old-docs', '/docs', { permanent: true })
39
+ routes.redirect('/old-docs', '/docs', { permanent: true })
42
40
  ],
43
41
 
44
42
  headers: [
45
- router.cacheControl('/static/(.*)', {
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 `router.redirect()`, `router.rewrite()`, `router.header()`
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
- * Helper function to reference a path parameter in transforms.
4
- * Path parameters are extracted from the route pattern (e.g., :userId).
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
- * param('userId') // Returns '$userId'
7
+ * ExtractPathParams<'/users/:userId/posts/:postId'> // 'userId' | 'postId'
8
+ * ExtractPathParams<'/api/(.*)'> // never
8
9
  */
9
- export declare function param(name: string): string;
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
- * Helper function to reference a runtime environment variable in transforms.
12
- * These are environment variables that get resolved at request time by Vercel's routing layer,
13
- * not at build time.
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
- * runtimeEnv('BEARER_TOKEN') // Returns '$BEARER_TOKEN'
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 runtimeEnv(name: string): string;
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('/users/:userId', 'https://api.example.com/users/$1', ({userId, env}) => ({
506
- * requestHeaders: { 'x-user-id': userId }
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: string, destination: string, optionsOrCallback?: {
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
- } | ((params: Record<string, string> & {
517
- env: any;
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('/users/:userId', '/new-users/$1', ({userId, env}) => ({
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: { 'x-user-id': userId }
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: string, destination: string, optionsOrCallback?: {
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
- } | ((params: Record<string, string> & {
546
- env: any;
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
- })): Redirect | Route;
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.runtimeEnv = exports.param = void 0;
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 path parameter in transforms.
8
- * Path parameters are extracted from the route pattern (e.g., :userId).
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
- * param('userId') // Returns '$userId'
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 param(name) {
20
+ function deploymentEnv(name) {
14
21
  return `$${name}`;
15
22
  }
16
- exports.param = param;
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 router.redirect()
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 router.rewrite()
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 router.header() and router.cacheControl()
174
+ * Returned by routes.header() and routes.cacheControl()
175
175
  */
176
176
  export interface HeaderRule {
177
177
  source: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vercel/config",
3
- "version": "0.0.21",
3
+ "version": "0.0.22",
4
4
  "description": "A TypeScript SDK for programmatically configuring Vercel projects",
5
5
  "bugs": {
6
6
  "url": "https://github.com/vercel/config/issues"