Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@vercel/routing-utils

Package Overview
Dependencies
Maintainers
13
Versions
80
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@vercel/routing-utils - npm Package Compare versions

Comparing version 1.8.3-canary.1 to 1.8.3-canary.2

247

dist/index.js

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

Object.defineProperty(exports, "__esModule", { value: true });
const url_1 = require("url");
__export(require("./schemas"));

@@ -39,26 +40,18 @@ const superstatic_1 = require("./superstatic");

const errors = [];
// We don't want to treat the input routes as references
inputRoutes.forEach(r => routes.push(Object.assign({}, r)));
for (const route of routes) {
inputRoutes.forEach((r, i) => {
const route = { ...r };
routes.push(route);
const keys = Object.keys(route);
if (isHandler(route)) {
if (Object.keys(route).length !== 1) {
errors.push({
message: `Cannot have any other keys when handle is used (handle: ${route.handle})`,
handle: route.handle,
});
}
const { handle } = route;
if (!isValidHandleValue(handle)) {
errors.push({
message: `This is not a valid handler (handle: ${handle})`,
handle: handle,
});
continue;
if (keys.length !== 1) {
const unknownProp = keys.find(prop => prop !== 'handle');
errors.push(`Route at index ${i} has unknown property \`${unknownProp}\`.`);
}
if (handling.includes(handle)) {
errors.push({
message: `You can only handle something once (handle: ${handle})`,
handle: handle,
});
else if (!isValidHandleValue(handle)) {
errors.push(`Route at index ${i} has unknown handle value \`handle: ${handle}\`.`);
}
else if (handling.includes(handle)) {
errors.push(`Route at index ${i} is a duplicate. Please use one \`handle: ${handle}\` at most.`);
}
else {

@@ -79,3 +72,3 @@ handling.push(handle);

route.src = route.src.replace(/\\\//g, '/');
const regError = checkRegexSyntax(route.src);
const regError = checkRegexSyntax('Route', i, route.src);
if (regError) {

@@ -88,18 +81,9 @@ errors.push(regError);

if (route.dest) {
errors.push({
message: `You cannot assign "dest" after "handle: hit"`,
src: route.src,
});
errors.push(`Route at index ${i} cannot define \`dest\` after \`handle: hit\`.`);
}
if (route.status) {
errors.push({
message: `You cannot assign "status" after "handle: hit"`,
src: route.src,
});
errors.push(`Route at index ${i} cannot define \`status\` after \`handle: hit\`.`);
}
if (!route.continue) {
errors.push({
message: `You must assign "continue: true" after "handle: hit"`,
src: route.src,
});
errors.push(`Route at index ${i} must define \`continue: true\` after \`handle: hit\`.`);
}

@@ -109,12 +93,6 @@ }

if (route.dest && !route.check) {
errors.push({
message: `You must assign "check: true" after "handle: miss"`,
src: route.src,
});
errors.push(`Route at index ${i} must define \`check: true\` after \`handle: miss\`.`);
}
else if (!route.dest && !route.continue) {
errors.push({
message: `You must assign "continue: true" after "handle: miss"`,
src: route.src,
});
errors.push(`Route at index ${i} must define \`continue: true\` after \`handle: miss\`.`);
}

@@ -124,27 +102,24 @@ }

else {
errors.push({
message: 'A route must set either handle or src',
});
errors.push(`Route at index ${i} must define either \`handle\` or \`src\` property.`);
}
}
const error = createNowError('invalid_routes', 'One or more invalid routes were found', errors);
});
const error = errors.length > 0
? createError('invalid_route', errors, 'https://vercel.link/routes-json', 'Learn More')
: null;
return { routes, error };
}
exports.normalizeRoutes = normalizeRoutes;
function checkRegexSyntax(src) {
function checkRegexSyntax(type, index, src) {
try {
// This feels a bit dangerous if there would be a vulnerability in RegExp.
new RegExp(src);
}
catch (err) {
return {
message: `Invalid regular expression: "${src}"`,
src,
};
const prop = type === 'Route' ? 'src' : 'source';
return `${type} at index ${index} has invalid \`${prop}\` regular expression "${src}".`;
}
return null;
}
function checkPatternSyntax({ source, destination, }) {
function checkPatternSyntax(type, index, { source, destination, }) {
let sourceSegments = new Set();
let destinationSegments = new Set();
const destinationSegments = new Set();
try {

@@ -155,15 +130,15 @@ sourceSegments = new Set(superstatic_1.sourceToRegex(source).segments);

return {
message: `Invalid source pattern: "${source}"`,
src: source,
message: `${type} at index ${index} has invalid \`source\` pattern "${source}".`,
link: 'https://vercel.link/invalid-route-source-pattern',
};
}
if (destination) {
if (destination.startsWith('http://')) {
destination = destination.slice(7);
}
if (destination.startsWith('https://')) {
destination = destination.slice(8);
}
try {
destinationSegments = new Set(superstatic_1.sourceToRegex(destination).segments);
const { hostname, pathname, query } = url_1.parse(destination, true);
superstatic_1.sourceToRegex(hostname || '').segments.forEach(name => destinationSegments.add(name));
superstatic_1.sourceToRegex(pathname || '').segments.forEach(name => destinationSegments.add(name));
for (const strOrArray of Object.values(query)) {
const value = Array.isArray(strOrArray) ? strOrArray[0] : strOrArray;
superstatic_1.sourceToRegex(value || '').segments.forEach(name => destinationSegments.add(name));
}
}

@@ -178,4 +153,4 @@ catch (err) {

return {
message: `Found segment ":${segment}" in "destination" pattern but not in "source" pattern.`,
src: segment,
message: `${type} at index ${index} has segment ":${segment}" in \`destination\` property but not in \`source\` property.`,
link: 'https://vercel.link/invalid-route-destination-segment',
};

@@ -187,22 +162,25 @@ }

}
function checkRedirect(r) {
function checkRedirect(r, index) {
if (typeof r.permanent !== 'undefined' &&
typeof r.statusCode !== 'undefined') {
return {
message: `Redirect "${r.source}" cannot define both "permanent" and "statusCode".`,
src: r.source,
};
return `Redirect at index ${index} cannot define both \`permanent\` and \`statusCode\` properties.`;
}
return null;
}
function createNowError(code, msg, errors) {
const error = errors.length > 0
? {
code,
message: `${msg}:\n${errors
.map(item => `- ${item.message}`)
.join('\n')}`,
errors,
}
: null;
function createError(code, errors, link, action) {
let message;
let otherErrors = [];
if (Array.isArray(errors)) {
[message, ...otherErrors] = errors;
}
else {
message = errors;
}
const error = {
code,
message,
link,
action,
otherErrors,
};
return error;

@@ -216,31 +194,10 @@ }

let { routes = null } = nowConfig;
const errors = [];
if (routes) {
if (typeof cleanUrls !== 'undefined') {
errors.push({
message: 'Cannot define both `routes` and `cleanUrls`',
});
}
if (typeof trailingSlash !== 'undefined') {
errors.push({
message: 'Cannot define both `routes` and `trailingSlash`',
});
}
if (typeof redirects !== 'undefined') {
errors.push({
message: 'Cannot define both `routes` and `redirects`',
});
}
if (typeof headers !== 'undefined') {
errors.push({
message: 'Cannot define both `routes` and `headers`',
});
}
if (typeof rewrites !== 'undefined') {
errors.push({
message: 'Cannot define both `routes` and `rewrites`',
});
}
if (errors.length > 0) {
const error = createNowError('invalid_keys', 'Cannot mix legacy routes with new keys', errors);
const hasNewProperties = typeof cleanUrls !== 'undefined' ||
typeof trailingSlash !== 'undefined' ||
typeof redirects !== 'undefined' ||
typeof headers !== 'undefined' ||
typeof rewrites !== 'undefined';
if (hasNewProperties) {
const error = createError('invalid_mixed_routes', 'If `rewrites`, `redirects`, `headers`, `cleanUrls` or `trailingSlash` are used, then `routes` cannot be present.', 'https://vercel.link/mix-routing-props', 'Learn More');
return { routes, error };

@@ -269,26 +226,26 @@ }

if (typeof redirects !== 'undefined') {
const code = 'invalid_redirects';
const errorsRegex = redirects
.map(r => checkRegexSyntax(r.source))
.filter(notEmpty);
if (errorsRegex.length > 0) {
const code = 'invalid_redirect';
const regexErrorMessage = redirects
.map((r, i) => checkRegexSyntax('Redirect', i, r.source))
.find(notEmpty);
if (regexErrorMessage) {
return {
routes,
error: createNowError(code, 'Redirect `source` contains invalid regex. Read more: https://err.sh/now/invalid-route-source', errorsRegex),
error: createError('invalid_redirect', regexErrorMessage, 'https://vercel.link/invalid-route-source-pattern', 'Learn More'),
};
}
const errorsPattern = redirects
.map(r => checkPatternSyntax(r))
.filter(notEmpty);
if (errorsPattern.length > 0) {
const patternError = redirects
.map((r, i) => checkPatternSyntax('Redirect', i, r))
.find(notEmpty);
if (patternError) {
return {
routes,
error: createNowError(code, 'Redirect `source` contains invalid pattern. Read more: https://err.sh/now/invalid-route-source', errorsPattern),
error: createError(code, patternError.message, patternError.link, 'Learn More'),
};
}
const errorProps = redirects.map(r => checkRedirect(r)).filter(notEmpty);
if (errorProps.length > 0) {
const redirectErrorMessage = redirects.map(checkRedirect).find(notEmpty);
if (redirectErrorMessage) {
return {
routes,
error: createNowError(code, 'Invalid redirects', errorProps),
error: createError(code, redirectErrorMessage, 'https://vercel.link/redirects-json', 'Learn More'),
};

@@ -305,19 +262,19 @@ }

if (typeof headers !== 'undefined') {
const code = 'invalid_headers';
const errorsRegex = headers
.map(r => checkRegexSyntax(r.source))
.filter(notEmpty);
if (errorsRegex.length > 0) {
const code = 'invalid_header';
const regexErrorMessage = headers
.map((r, i) => checkRegexSyntax('Header', i, r.source))
.find(notEmpty);
if (regexErrorMessage) {
return {
routes,
error: createNowError(code, 'Headers `source` contains invalid regex. Read more: https://err.sh/now/invalid-route-source', errorsRegex),
error: createError(code, regexErrorMessage, 'https://vercel.link/invalid-route-source-pattern', 'Learn More'),
};
}
const errorsPattern = headers
.map(r => checkPatternSyntax(r))
.filter(notEmpty);
if (errorsPattern.length > 0) {
const patternError = headers
.map((r, i) => checkPatternSyntax('Header', i, r))
.find(notEmpty);
if (patternError) {
return {
routes,
error: createNowError(code, 'Headers `source` contains invalid pattern. Read more: https://err.sh/now/invalid-route-source', errorsPattern),
error: createError(code, patternError.message, patternError.link, 'Learn More'),
};

@@ -327,3 +284,3 @@ }

if (normalized.error) {
normalized.error.code = 'invalid_headers';
normalized.error.code = code;
return { routes, error: normalized.error };

@@ -335,19 +292,19 @@ }

if (typeof rewrites !== 'undefined') {
const code = 'invalid_rewrites';
const errorsRegex = rewrites
.map(r => checkRegexSyntax(r.source))
.filter(notEmpty);
if (errorsRegex.length > 0) {
const code = 'invalid_rewrite';
const regexErrorMessage = rewrites
.map((r, i) => checkRegexSyntax('Rewrite', i, r.source))
.find(notEmpty);
if (regexErrorMessage) {
return {
routes,
error: createNowError(code, 'Rewrites `source` contains invalid regex. Read more: https://err.sh/now/invalid-route-source', errorsRegex),
error: createError(code, regexErrorMessage, 'https://vercel.link/invalid-route-source-pattern', 'Learn More'),
};
}
const errorsPattern = rewrites
.map(r => checkPatternSyntax(r))
.filter(notEmpty);
if (errorsPattern.length > 0) {
const patternError = rewrites
.map((r, i) => checkPatternSyntax('Rewrite', i, r))
.find(notEmpty);
if (patternError) {
return {
routes,
error: createNowError(code, 'Rewrites `source` contains invalid pattern. Read more: https://err.sh/now/invalid-route-source', errorsPattern),
error: createError(code, patternError.message, patternError.link, 'Learn More'),
};

@@ -354,0 +311,0 @@ }

import { HandleValue } from './index';
export declare type NowError = {
export declare type RouteApiError = {
code: string;
message: string;
errors: NowErrorNested[];
sha?: string;
link?: string;
action?: string;
otherErrors?: string[];
};
export declare type NowErrorNested = {
message: string;
src?: string;
handle?: string;
};
export declare type Source = {

@@ -33,3 +29,3 @@ src: string;

routes: Route[] | null;
error: NowError | null;
error: RouteApiError | null;
};

@@ -36,0 +32,0 @@ export interface GetRoutesProps {

{
"name": "@vercel/routing-utils",
"version": "1.8.3-canary.1",
"version": "1.8.3-canary.2",
"description": "Vercel routing utilities",

@@ -33,3 +33,3 @@ "main": "./dist/index.js",

},
"gitHead": "081b3fd3db01ad2252036fb3a2503e14868103fe"
"gitHead": "b16f94098af561ab9ea12597fd019a1ac423cc38"
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc