Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

@vercel/config

Package Overview
Dependencies
Maintainers
335
Versions
40
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@vercel/config - npm Package Compare versions

Comparing version
0.0.9
to
0.0.10
+85
-11
dist/router.d.ts

@@ -356,2 +356,6 @@ /**

/**
* Path to a JSON file containing bulk redirect rules.
*/
bulkRedirectsPath?: string;
/**
* Array of cron definitions for scheduled invocations.

@@ -382,5 +386,42 @@ */

private trailingSlashConfig;
private bulkRedirectsPathConfig;
private buildCommandConfig;
private installCommandConfig;
/**
* Property setter for cleanUrls configuration.
*/
set cleanUrls(value: boolean | undefined);
/**
* Property getter for cleanUrls configuration.
*/
get cleanUrls(): boolean | undefined;
/**
* Property setter for trailingSlash configuration.
*/
set trailingSlash(value: boolean | undefined);
/**
* Property getter for trailingSlash configuration.
*/
get trailingSlash(): boolean | undefined;
/**
* Property setter for bulkRedirectsPath configuration.
*/
set bulkRedirectsPath(value: string | undefined);
/**
* Property getter for bulkRedirectsPath configuration.
*/
get bulkRedirectsPath(): string | undefined;
/**
* Helper to extract path parameter names from a source pattern.
* Path parameters are identified by :paramName syntax.
* @example
* extractPathParams('/users/:userId/posts/:postId') // Returns ['userId', 'postId']
*/
private extractPathParams;
/**
* Creates a Proxy object that tracks environment variable accesses.
* Returns both the proxy and a set of accessed environment variable names.
*/
private createEnvProxy;
/**
* Helper to extract environment variable names from a string or string array.

@@ -400,16 +441,21 @@ * Environment variables are identified by the pattern $VAR_NAME where VAR_NAME

* @example
* // This will automatically enable caching for the rewrite
* import { createRouter, param, runtimeEnv } from '@vercel/router-sdk';
* const router = createRouter();
* // Simple rewrite
* router.rewrite('/api/(.*)', 'https://old-on-prem.com/$1')
*
* // With transforms
* // With transforms using callback
* router.rewrite('/users/:userId', 'https://api.example.com/users/$1', ({userId, env}) => ({
* requestHeaders: {
* 'x-user-id': userId,
* 'authorization': `Bearer ${env.API_TOKEN}`
* }
* }));
*
* // With transforms using object (legacy)
* router.rewrite('/users/:userId', 'https://api.example.com/users/$1', {
* requestHeaders: {
* 'x-user-id': param('userId'),
* 'authorization': `Bearer ${runtimeEnv('API_TOKEN')}`
* 'x-user-id': param('userId')
* }
* });
*/
rewrite(source: string, destination: string, options?: {
rewrite(source: string, destination: string, optionsOrCallback?: {
has?: Condition[];

@@ -420,3 +466,11 @@ missing?: Condition[];

requestQuery?: Record<string, string | string[]>;
}): this;
} | ((params: Record<string, string> & {
env: any;
}) => {
has?: Condition[];
missing?: Condition[];
requestHeaders?: Record<string, string | string[]>;
responseHeaders?: Record<string, string | string[]>;
requestQuery?: Record<string, string | string[]>;
})): this;
/**

@@ -434,5 +488,15 @@ * Loads rewrite rules asynchronously and appends them.

* @example
* // Simple redirect
* router.redirect('/old-path', '/new-path', { permanent: true })
*
* // With transforms
* // With transforms using callback
* router.redirect('/users/:userId', '/new-users/$1', ({userId, env}) => ({
* permanent: true,
* requestHeaders: {
* 'x-user-id': userId,
* 'x-api-key': env.API_KEY
* }
* }))
*
* // With transforms using object (legacy)
* router.redirect('/users/:userId', '/new-users/$1', {

@@ -445,3 +509,3 @@ * permanent: true,

*/
redirect(source: string, destination: string, options?: {
redirect(source: string, destination: string, optionsOrCallback?: {
permanent?: boolean;

@@ -454,3 +518,13 @@ statusCode?: number;

requestQuery?: Record<string, string | string[]>;
}): this;
} | ((params: Record<string, string> & {
env: any;
}) => {
permanent?: boolean;
statusCode?: number;
has?: Condition[];
missing?: Condition[];
requestHeaders?: Record<string, string | string[]>;
responseHeaders?: Record<string, string | string[]>;
requestQuery?: Record<string, string | string[]>;
})): this;
/**

@@ -457,0 +531,0 @@ * Loads redirect rules asynchronously and appends them.

@@ -43,2 +43,3 @@ "use strict";

this.trailingSlashConfig = undefined;
this.bulkRedirectsPathConfig = undefined;
this.buildCommandConfig = undefined;

@@ -48,2 +49,69 @@ this.installCommandConfig = undefined;

/**
* Property setter for cleanUrls configuration.
*/
set cleanUrls(value) {
this.cleanUrlsConfig = value;
}
/**
* Property getter for cleanUrls configuration.
*/
get cleanUrls() {
return this.cleanUrlsConfig;
}
/**
* Property setter for trailingSlash configuration.
*/
set trailingSlash(value) {
this.trailingSlashConfig = value;
}
/**
* Property getter for trailingSlash configuration.
*/
get trailingSlash() {
return this.trailingSlashConfig;
}
/**
* Property setter for bulkRedirectsPath configuration.
*/
set bulkRedirectsPath(value) {
this.bulkRedirectsPathConfig = value;
}
/**
* Property getter for bulkRedirectsPath configuration.
*/
get bulkRedirectsPath() {
return this.bulkRedirectsPathConfig;
}
/**
* Helper to extract path parameter names from a source pattern.
* Path parameters are identified by :paramName syntax.
* @example
* extractPathParams('/users/:userId/posts/:postId') // Returns ['userId', 'postId']
*/
extractPathParams(source) {
const params = [];
const matches = source.matchAll(/:([a-zA-Z_][a-zA-Z0-9_]*)/g);
for (const match of matches) {
params.push(match[1]);
}
return params;
}
/**
* Creates a Proxy object that tracks environment variable accesses.
* Returns both the proxy and a set of accessed environment variable names.
*/
createEnvProxy() {
const accessedVars = new Set();
const proxy = new Proxy({}, {
get(_target, prop) {
if (typeof prop === 'string') {
accessedVars.add(prop);
return `$${prop}`;
}
return undefined;
}
});
return { proxy, accessedVars };
}
/**
* Helper to extract environment variable names from a string or string array.

@@ -117,18 +185,40 @@ * Environment variables are identified by the pattern $VAR_NAME where VAR_NAME

* @example
* // This will automatically enable caching for the rewrite
* import { createRouter, param, runtimeEnv } from '@vercel/router-sdk';
* const router = createRouter();
* // Simple rewrite
* router.rewrite('/api/(.*)', 'https://old-on-prem.com/$1')
*
* // With transforms
* // With transforms using callback
* router.rewrite('/users/:userId', 'https://api.example.com/users/$1', ({userId, env}) => ({
* requestHeaders: {
* 'x-user-id': userId,
* 'authorization': `Bearer ${env.API_TOKEN}`
* }
* }));
*
* // With transforms using object (legacy)
* router.rewrite('/users/:userId', 'https://api.example.com/users/$1', {
* requestHeaders: {
* 'x-user-id': param('userId'),
* 'authorization': `Bearer ${runtimeEnv('API_TOKEN')}`
* 'x-user-id': param('userId')
* }
* });
*/
rewrite(source, destination, options) {
rewrite(source, destination, optionsOrCallback) {
this.validateSourcePattern(source);
(0, validation_1.validateCaptureGroupReferences)(source, destination);
let options;
// Handle callback syntax
if (typeof optionsOrCallback === 'function') {
const pathParams = this.extractPathParams(source);
const { proxy: envProxy } = this.createEnvProxy();
// Create params object with path parameters as $paramName
const paramsObj = {};
for (const param of pathParams) {
paramsObj[param] = `$${param}`;
}
paramsObj.env = envProxy;
// Call the callback to get options
options = optionsOrCallback(paramsObj);
}
else {
options = optionsOrCallback;
}
// Extract transform options

@@ -188,5 +278,15 @@ const { requestHeaders, responseHeaders, requestQuery, has, missing } = options || {};

* @example
* // Simple redirect
* router.redirect('/old-path', '/new-path', { permanent: true })
*
* // With transforms
* // With transforms using callback
* router.redirect('/users/:userId', '/new-users/$1', ({userId, env}) => ({
* permanent: true,
* requestHeaders: {
* 'x-user-id': userId,
* 'x-api-key': env.API_KEY
* }
* }))
*
* // With transforms using object (legacy)
* router.redirect('/users/:userId', '/new-users/$1', {

@@ -199,5 +299,22 @@ * permanent: true,

*/
redirect(source, destination, options) {
redirect(source, destination, optionsOrCallback) {
this.validateSourcePattern(source);
(0, validation_1.validateCaptureGroupReferences)(source, destination);
let options;
// Handle callback syntax
if (typeof optionsOrCallback === 'function') {
const pathParams = this.extractPathParams(source);
const { proxy: envProxy } = this.createEnvProxy();
// Create params object with path parameters as $paramName
const paramsObj = {};
for (const param of pathParams) {
paramsObj[param] = `$${param}`;
}
paramsObj.env = envProxy;
// Call the callback to get options
options = optionsOrCallback(paramsObj);
}
else {
options = optionsOrCallback;
}
// Extract transform options

@@ -388,3 +505,6 @@ const { requestHeaders, responseHeaders, requestQuery, permanent, statusCode, has, missing, } = options || {};

};
// Only include buildCommand/installCommand if they're explicitly set
// Only include optional fields if they're explicitly set
if (this.bulkRedirectsPathConfig !== undefined) {
config.bulkRedirectsPath = this.bulkRedirectsPathConfig;
}
if (this.buildCommandConfig !== undefined) {

@@ -407,3 +527,6 @@ config.buildCommand = this.buildCommandConfig;

};
// Only include buildCommand/installCommand if they're explicitly set
// Only include optional fields if they're explicitly set
if (this.bulkRedirectsPathConfig !== undefined) {
config.bulkRedirectsPath = this.bulkRedirectsPathConfig;
}
if (this.buildCommandConfig !== undefined) {

@@ -410,0 +533,0 @@ config.buildCommand = this.buildCommandConfig;

+1
-1
{
"name": "@vercel/config",
"version": "0.0.9",
"version": "0.0.10",
"description": "A TypeScript SDK for programmatically generating Vercel configuration files",

@@ -5,0 +5,0 @@ "bugs": {

+139
-26

@@ -1,46 +0,159 @@

# Vercel Router SDK
# @vercel/config
This is a prototype of what a Router SDK could look like.
TypeScript SDK for defining Vercel configuration programmatically.
## Installation
```bash
npm install @vercel/config
```
## Usage
1. Install the package:
`npm install @vercel/router`
Create a `vercel.ts` file in your project root:
2. Create a router configuration file (e.g., `router.config.ts`):
```typescript
import { createRouter } from "@vercel/router";
import { createRouter } from '@vercel/config';
const router = createRouter();
router
.rewrite("/api/(.*)", "/api/$1")
.redirect("/old-docs", "/docs", { permanent: true })
.cacheControl("/static/(.*)", {
public: true,
maxAge: "1week",
immutable: true
})
.setCleanUrls(true);
// Basic rewrite
router.rewrite('/api/(.*)', 'https://backend.com/$1');
// Rewrite with transforms
router.rewrite('/users/:userId', 'https://api.example.com/users/$1', ({userId, env}) => ({
requestHeaders: {
'x-user-id': userId,
'authorization': `Bearer ${env.API_TOKEN}`
}
}));
// Redirects
router.redirect('/old-docs', '/docs', { permanent: true });
// Cache control
router.cacheControl('/static/(.*)', {
public: true,
maxAge: '1week',
immutable: true
});
// Global settings
router.cleanUrls = true;
router.trailingSlash = true;
// Bulk redirects
router.bulkRedirectsPath = './bulkRedirectsDemo.json';
// Cron jobs
router.cron('/api/cleanup', '0 0 * * *');
export default router.getConfig();
```
3. Add the generate-config script to your package.json:
## Automatic Compilation
```json
{
"scripts": {
"generate-config": "@vercel/router"
Your `vercel.ts` file is automatically compiled when you run:
```bash
vercel build # For local builds
vercel dev # For local development
vercel deploy # For deployment
```
The Vercel CLI automatically compiles `vercel.ts` to `.vercel/vercel.json` before building or deploying.
## API Reference
### `createRouter()`
Creates a new router instance.
### `router.rewrite(source, destination, options?)`
Add a rewrite rule. Options can be an object or a callback function that receives path parameters and environment variables.
```typescript
// With callback for transforms
router.rewrite('/users/:userId', 'https://api.example.com/users/$1', ({userId, env}) => ({
requestHeaders: {
'x-user-id': userId,
'authorization': `Bearer ${env.API_TOKEN}`
},
responseHeaders: {
'x-powered-by': 'My API'
},
requestQuery: {
'version': '2.0'
}
}
}));
// Simple rewrite without transforms
router.rewrite('/api/(.*)', 'https://backend.com/$1');
```
4. Run the script to generate your `vercel.json`:
### `router.redirect(source, destination, options?)`
```bash
npm run generate-config
Add a redirect rule. Options include `permanent` and `statusCode`.
```typescript
router.redirect('/old-page', '/new-page', { permanent: true });
router.redirect('/temp', '/elsewhere', { statusCode: 302 });
```
This will generate a `vercel.json` file in your project root with all your routing configurations.
### `router.header(source, headers, options?)`
Add custom headers for a path pattern.
```typescript
router.header('/api/(.*)', [
{ key: 'X-Custom-Header', value: 'value' }
]);
```
### `router.cacheControl(source, options)`
Set cache control headers. Options include `public`, `private`, `maxAge`, `sMaxAge`, `immutable`, etc.
```typescript
router.cacheControl('/static/(.*)', {
public: true,
maxAge: '1week',
immutable: true
});
```
### `router.cleanUrls`
Set whether to enable clean URLs (removes file extensions).
```typescript
router.cleanUrls = true;
```
### `router.trailingSlash`
Set whether to normalize paths to include trailing slashes.
```typescript
router.trailingSlash = true;
```
### `router.bulkRedirectsPath`
Set the path to a bulk redirects JSON file.
```typescript
router.bulkRedirectsPath = './bulkRedirectsDemo.json';
```
## Important Notes
- **One config file only**: You cannot have both `vercel.ts` and `vercel.json`. The build will fail if both exist.
- **Automatic gitignore**: The generated `.vercel/vercel.json` file is automatically ignored by git (in the `.vercel/` directory).
- **No manual compilation needed**: The Vercel CLI handles compilation automatically - no need to run a separate command.
## Learn More
- [Vercel Configuration Documentation](https://vercel.com/docs/projects/project-configuration)
- [Routing Documentation](https://vercel.com/docs/edge-network/routing)