Compare commits

...

3 Commits

Author SHA1 Message Date
Steven
bef1aec766 Publish Stable
- @vercel/build-utils@5.0.3
 - vercel@27.1.5
 - @vercel/client@12.1.2
 - @vercel/frameworks@1.1.1
 - @vercel/fs-detectors@2.0.1
 - @vercel/go@2.0.7
 - @vercel/hydrogen@0.0.4
 - @vercel/next@3.1.7
 - @vercel/node@2.4.4
 - @vercel/python@3.0.7
 - @vercel/redwood@1.0.8
 - @vercel/remix@1.0.9
 - @vercel/routing-utils@2.0.0
 - @vercel/ruby@1.3.15
 - @vercel/static-build@1.0.8
2022-07-15 15:40:37 -04:00
Steven
4f4a42813f [build-utils][node][python][ruby] Update error message for EOL runtimes (#8167)
This PR updates the error message when the runtime version detected is EOL
2022-07-15 15:38:38 -04:00
Steven
181a492d91 [routing-utils] MAJOR refactor getTransformedRoutes and types (#8155)
This is a semver major change to the public API for `@vercel/routing-utils` which includes the following breaking changes.

1. `getTransformedRoutes({ nowConfig })` props changed to `getTransformedRoutes(nowConfig)`
2. `type Source` renamed `type RouteWithSrc`
3. `type Handler` renamed `type RouteWithHandle`
4. `interface VercelConfig` removed
5. `type NowConfig` removed
6. `type NowRewrite` removed
7. `type NowRedirect` removed
8. `type NowHeader` removed
9. `type NowHeaderKeyValue` removed
2022-07-15 14:05:08 -04:00
37 changed files with 187 additions and 211 deletions

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/build-utils",
"version": "5.0.2",
"version": "5.0.3",
"license": "MIT",
"main": "./dist/index.js",
"types": "./dist/index.d.js",

View File

@@ -33,9 +33,6 @@ function getHint(isAuto = false) {
: `Please set "engines": { "node": "${range}" } in your \`package.json\` file to use Node.js ${major}.`;
}
const upstreamProvider =
'This change is the result of a decision made by an upstream infrastructure provider (AWS).';
export function getLatestNodeVersion() {
return allOptions[0];
}
@@ -75,7 +72,7 @@ export async function getSupportedNodeVersion(
throw new NowBuildError({
code: 'BUILD_UTILS_NODE_VERSION_DISCONTINUED',
link: 'http://vercel.link/node-version',
message: `${intro} ${getHint(isAuto)} ${upstreamProvider}`,
message: `${intro} ${getHint(isAuto)}`,
});
}
@@ -86,9 +83,9 @@ export async function getSupportedNodeVersion(
console.warn(
`Error: Node.js version ${
selection.range
} is deprecated. Deployments created on or after ${d} will fail to build. ${getHint(
} has reached End-of-Life. Deployments created on or after ${d} will fail to build. ${getHint(
isAuto
)} ${upstreamProvider}`
)}`
);
}

View File

@@ -387,10 +387,10 @@ it('should warn for deprecated versions, soon to be discontinued', async () => {
12
);
expect(warningMessages).toStrictEqual([
'Error: Node.js version 10.x is deprecated. Deployments created on or after 2021-04-20 will fail to build. Please set "engines": { "node": "16.x" } in your `package.json` file to use Node.js 16. This change is the result of a decision made by an upstream infrastructure provider (AWS).',
'Error: Node.js version 10.x is deprecated. Deployments created on or after 2021-04-20 will fail to build. Please set Node.js Version to 16.x in your Project Settings to use Node.js 16. This change is the result of a decision made by an upstream infrastructure provider (AWS).',
'Error: Node.js version 12.x is deprecated. Deployments created on or after 2022-08-09 will fail to build. Please set "engines": { "node": "16.x" } in your `package.json` file to use Node.js 16. This change is the result of a decision made by an upstream infrastructure provider (AWS).',
'Error: Node.js version 12.x is deprecated. Deployments created on or after 2022-08-09 will fail to build. Please set Node.js Version to 16.x in your Project Settings to use Node.js 16. This change is the result of a decision made by an upstream infrastructure provider (AWS).',
'Error: Node.js version 10.x has reached End-of-Life. Deployments created on or after 2021-04-20 will fail to build. Please set "engines": { "node": "16.x" } in your `package.json` file to use Node.js 16.',
'Error: Node.js version 10.x has reached End-of-Life. Deployments created on or after 2021-04-20 will fail to build. Please set Node.js Version to 16.x in your Project Settings to use Node.js 16.',
'Error: Node.js version 12.x has reached End-of-Life. Deployments created on or after 2022-08-09 will fail to build. Please set "engines": { "node": "16.x" } in your `package.json` file to use Node.js 16.',
'Error: Node.js version 12.x has reached End-of-Life. Deployments created on or after 2022-08-09 will fail to build. Please set Node.js Version to 16.x in your Project Settings to use Node.js 16.',
]);
global.Date.now = realDateNow;

View File

@@ -1,6 +1,6 @@
{
"name": "vercel",
"version": "27.1.4",
"version": "27.1.5",
"preferGlobal": true,
"license": "Apache-2.0",
"description": "The command-line interface for Vercel",
@@ -42,16 +42,16 @@
"node": ">= 14"
},
"dependencies": {
"@vercel/build-utils": "5.0.2",
"@vercel/go": "2.0.6",
"@vercel/hydrogen": "0.0.3",
"@vercel/next": "3.1.6",
"@vercel/node": "2.4.3",
"@vercel/python": "3.0.6",
"@vercel/redwood": "1.0.7",
"@vercel/remix": "1.0.8",
"@vercel/ruby": "1.3.14",
"@vercel/static-build": "1.0.7",
"@vercel/build-utils": "5.0.3",
"@vercel/go": "2.0.7",
"@vercel/hydrogen": "0.0.4",
"@vercel/next": "3.1.7",
"@vercel/node": "2.4.4",
"@vercel/python": "3.0.7",
"@vercel/redwood": "1.0.8",
"@vercel/remix": "1.0.9",
"@vercel/ruby": "1.3.15",
"@vercel/static-build": "1.0.8",
"update-notifier": "5.1.0"
},
"devDependencies": {
@@ -96,9 +96,9 @@
"@types/which": "1.3.2",
"@types/write-json-file": "2.2.1",
"@types/yauzl-promise": "2.1.0",
"@vercel/client": "12.1.1",
"@vercel/frameworks": "1.1.0",
"@vercel/fs-detectors": "2.0.0",
"@vercel/client": "12.1.2",
"@vercel/frameworks": "1.1.1",
"@vercel/fs-detectors": "2.0.1",
"@vercel/ncc": "0.24.0",
"@zeit/fun": "0.11.2",
"@zeit/source-map-support": "0.6.2",

View File

@@ -206,7 +206,7 @@ export default async function main(client: Client): Promise<number> {
normalizePath(relative(workPath, f))
);
const routesResult = getTransformedRoutes({ nowConfig: vercelConfig || {} });
const routesResult = getTransformedRoutes(vercelConfig || {});
if (routesResult.error) {
output.prettyError(routesResult.error);
return 1;

View File

@@ -558,9 +558,8 @@ export default class DevServer {
]);
await this.validateVercelConfig(vercelConfig);
const { error: routeError, routes: maybeRoutes } = getTransformedRoutes({
nowConfig: vercelConfig,
});
const { error: routeError, routes: maybeRoutes } =
getTransformedRoutes(vercelConfig);
if (routeError) {
this.output.prettyError(routeError);
await this.exit();

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/client",
"version": "12.1.1",
"version": "12.1.2",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"homepage": "https://vercel.com",
@@ -42,8 +42,8 @@
]
},
"dependencies": {
"@vercel/build-utils": "5.0.2",
"@vercel/routing-utils": "1.13.5",
"@vercel/build-utils": "5.0.3",
"@vercel/routing-utils": "2.0.0",
"@zeit/fetch": "5.2.0",
"async-retry": "1.2.3",
"async-sema": "3.0.0",

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/frameworks",
"version": "1.1.0",
"version": "1.1.1",
"main": "./dist/frameworks.js",
"types": "./dist/frameworks.d.ts",
"files": [
@@ -21,7 +21,7 @@
"@types/js-yaml": "3.12.1",
"@types/node": "12.0.4",
"@types/node-fetch": "2.5.8",
"@vercel/routing-utils": "1.13.5",
"@vercel/routing-utils": "2.0.0",
"ajv": "6.12.2",
"typescript": "4.3.4"
}

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/fs-detectors",
"version": "2.0.0",
"version": "2.0.1",
"description": "Vercel filesystem detectors",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
@@ -20,8 +20,8 @@
"test-unit": "yarn test"
},
"dependencies": {
"@vercel/frameworks": "1.1.0",
"@vercel/routing-utils": "1.13.5",
"@vercel/frameworks": "1.1.1",
"@vercel/routing-utils": "2.0.0",
"glob": "8.0.3",
"js-yaml": "4.1.0",
"minimatch": "3.0.4",

View File

@@ -1,7 +1,7 @@
import minimatch from 'minimatch';
import { valid as validSemver } from 'semver';
import { parse as parsePath, extname } from 'path';
import type { Route, Source } from '@vercel/routing-utils';
import type { Route, RouteWithSrc } from '@vercel/routing-utils';
import frameworkList, { Framework } from '@vercel/frameworks';
import type {
PackageJson,
@@ -155,8 +155,8 @@ export async function detectBuilders(
let fallbackEntrypoint: string | null = null;
const apiRoutes: Source[] = [];
const dynamicRoutes: Source[] = [];
const apiRoutes: RouteWithSrc[] = [];
const dynamicRoutes: RouteWithSrc[] = [];
// API
for (const fileName of sortedFiles) {
@@ -692,7 +692,7 @@ function getApiRoute(
options: Options,
absolutePathCache: Map<string, string>
): {
apiRoute: Source | null;
apiRoute: RouteWithSrc | null;
isDynamic: boolean;
routeError: ErrorResponse | null;
} {
@@ -886,7 +886,7 @@ function createRouteFromPath(
filePath: string,
featHandleMiss: boolean,
cleanUrls: boolean
): { route: Source; isDynamic: boolean } {
): { route: RouteWithSrc; isDynamic: boolean } {
const parts = filePath.split('/');
let counter = 1;
@@ -932,7 +932,7 @@ function createRouteFromPath(
? `^/${srcParts.slice(0, -1).join('/')}${srcParts.slice(-1)[0]}$`
: `^/${srcParts.join('/')}$`;
let route: Source;
let route: RouteWithSrc;
if (featHandleMiss) {
const extensionless = ext ? filePath.slice(0, -ext.length) : filePath;
@@ -959,8 +959,8 @@ interface LimitedRoutes {
function getRouteResult(
pkg: PackageJson | undefined | null,
apiRoutes: Source[],
dynamicRoutes: Source[],
apiRoutes: RouteWithSrc[],
dynamicRoutes: RouteWithSrc[],
outputDirectory: string,
apiBuilders: Builder[],
frontendBuilder: Builder | null,

View File

@@ -1,4 +1,8 @@
import type { Source, Route, Handler } from '@vercel/routing-utils';
import type {
Route,
RouteWithHandle as Handler,
RouteWithSrc as Source,
} from '@vercel/routing-utils';
import {
detectBuilders,
detectOutputDirectory,

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/go",
"version": "2.0.6",
"version": "2.0.7",
"license": "MIT",
"main": "./dist/index",
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/go",
@@ -25,7 +25,7 @@
"@types/fs-extra": "^5.0.5",
"@types/node-fetch": "^2.3.0",
"@types/tar": "^4.0.0",
"@vercel/build-utils": "5.0.2",
"@vercel/build-utils": "5.0.3",
"@vercel/ncc": "0.24.0",
"async-retry": "1.3.1",
"execa": "^1.0.0",

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/hydrogen",
"version": "0.0.3",
"version": "0.0.4",
"license": "MIT",
"main": "./dist/index.js",
"homepage": "https://vercel.com/docs",
@@ -22,7 +22,7 @@
"devDependencies": {
"@types/jest": "27.5.1",
"@types/node": "*",
"@vercel/build-utils": "5.0.2",
"@vercel/build-utils": "5.0.3",
"typescript": "4.6.4"
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/next",
"version": "3.1.6",
"version": "3.1.7",
"license": "MIT",
"main": "./dist/index",
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/next-js",
@@ -45,9 +45,9 @@
"@types/semver": "6.0.0",
"@types/text-table": "0.2.1",
"@types/webpack-sources": "3.2.0",
"@vercel/build-utils": "5.0.2",
"@vercel/build-utils": "5.0.3",
"@vercel/nft": "0.20.1",
"@vercel/routing-utils": "1.13.5",
"@vercel/routing-utils": "2.0.0",
"async-sema": "3.0.1",
"buffer-crc32": "0.2.13",
"cheerio": "1.0.0-rc.10",

View File

@@ -24,7 +24,7 @@ import {
NodejsLambda,
BuildResultV2Typical as BuildResult,
} from '@vercel/build-utils';
import { Handler, Route, Source } from '@vercel/routing-utils';
import { Route, RouteWithHandle, RouteWithSrc } from '@vercel/routing-utils';
import {
convertHeaders,
convertRedirects,
@@ -896,7 +896,7 @@ export const build: BuildV2 = async ({
...(output[path.join('./', entryDirectory, '404')] ||
output[path.join('./', entryDirectory, '404/index')]
? [
{ handle: 'error' } as Handler,
{ handle: 'error' } as RouteWithHandle,
{
status: 404,
@@ -928,7 +928,7 @@ export const build: BuildV2 = async ({
let trailingSlash = false;
redirects = redirects.filter(_redir => {
const redir = _redir as Source;
const redir = _redir as RouteWithSrc;
// detect the trailing slash redirect and make sure it's
// kept above the wildcard mapping to prevent erroneous redirects
// since non-continue routes come after continue the $wildcard
@@ -1146,7 +1146,7 @@ export const build: BuildV2 = async ({
continue;
}
const route: Source & { dest: string } = {
const route: RouteWithSrc & { dest: string } = {
src: (
dataRoute.namedDataRouteRegex || dataRoute.dataRouteRegex
).replace(/^\^/, `^${appMountPrefixNoTrailingSlash}`),
@@ -1175,7 +1175,7 @@ export const build: BuildV2 = async ({
if (isOmittedRoute && isServerMode) {
// only match this route when in preview mode so
// preview works for non-prerender fallback: false pages
(route as Source).has = [
(route as RouteWithSrc).has = [
{
type: 'cookie',
key: '__prerender_bypass',
@@ -2454,7 +2454,7 @@ export const build: BuildV2 = async ({
? []
: [
// Custom Next.js 404 page
{ handle: 'error' } as Handler,
{ handle: 'error' } as RouteWithHandle,
...(i18n && (static404Page || hasIsr404Page)
? [

View File

@@ -14,7 +14,7 @@ import {
Files,
BuildResultV2Typical as BuildResult,
} from '@vercel/build-utils';
import { Handler, Route, Source } from '@vercel/routing-utils';
import { Route, RouteWithHandle, RouteWithSrc } from '@vercel/routing-utils';
import { MAX_AGE_ONE_YEAR } from '.';
import {
NextRequiredServerFilesManifest,
@@ -828,7 +828,7 @@ export async function serverBuild({
const { staticFiles, publicDirectoryFiles, staticDirectoryFiles } =
await getStaticFiles(entryPath, entryDirectory, outputDirectory);
const notFoundPreviewRoutes: Source[] = [];
const notFoundPreviewRoutes: RouteWithSrc[] = [];
if (prerenderManifest.notFoundRoutes?.length > 0 && canUsePreviewMode) {
// we combine routes into one src here to reduce the number of needed
@@ -1384,7 +1384,7 @@ export async function serverBuild({
},
// error handling
{ handle: 'error' } as Handler,
{ handle: 'error' } as RouteWithHandle,
// Custom Next.js 404 page
...(i18n && (static404Page || hasIsr404Page || lambdaPages['404.js'])

View File

@@ -16,7 +16,7 @@ import {
EdgeFunction,
} from '@vercel/build-utils';
import { NodeFileTraceReasons } from '@vercel/nft';
import { Header, Rewrite, Route, Source } from '@vercel/routing-utils';
import { Header, Rewrite, Route, RouteWithSrc } from '@vercel/routing-utils';
import { Sema } from 'async-sema';
import crc32 from 'buffer-crc32';
import fs, { lstat, stat } from 'fs-extra';
@@ -273,8 +273,8 @@ export async function getDynamicRoutes(
canUsePreviewMode?: boolean,
bypassToken?: string,
isServerMode?: boolean,
dynamicMiddlewareRouteMap?: Map<string, Source>
): Promise<Source[]> {
dynamicMiddlewareRouteMap?: Map<string, RouteWithSrc>
): Promise<RouteWithSrc[]> {
if (routesManifest) {
switch (routesManifest.version) {
case 1:
@@ -307,7 +307,7 @@ export async function getDynamicRoutes(
}
const { page, namedRegex, regex, routeKeys } = params;
const route: Source = {
const route: RouteWithSrc = {
src: namedRegex || regex,
dest: `${!isDev ? path.join('/', entryDirectory, page) : page}${
routeKeys
@@ -400,7 +400,7 @@ export async function getDynamicRoutes(
matcher: getRouteRegex && getRouteRegex(pageName).re,
}));
const routes: Source[] = [];
const routes: RouteWithSrc[] = [];
pageMatchers.forEach(pageMatcher => {
// in `vercel dev` we don't need to prefix the destination
const dest = !isDev
@@ -419,7 +419,7 @@ export async function getDynamicRoutes(
}
export function localizeDynamicRoutes(
dynamicRoutes: Source[],
dynamicRoutes: RouteWithSrc[],
dynamicPrefix: string,
entryDirectory: string,
staticPages: Files,
@@ -427,8 +427,8 @@ export function localizeDynamicRoutes(
routesManifest?: RoutesManifest,
isServerMode?: boolean,
isCorrectLocaleAPIRoutes?: boolean
): Source[] {
return dynamicRoutes.map((route: Source) => {
): RouteWithSrc[] {
return dynamicRoutes.map((route: RouteWithSrc) => {
// i18n is already handled for middleware
if (route.middleware !== undefined || route.middlewarePath !== undefined)
return route;
@@ -2312,7 +2312,7 @@ export async function getMiddlewareBundle({
const source: {
staticRoutes: Route[];
dynamicRouteMap: Map<string, Source>;
dynamicRouteMap: Map<string, RouteWithSrc>;
edgeFunctions: Record<string, EdgeFunction>;
} = {
staticRoutes: [],

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/node",
"version": "2.4.3",
"version": "2.4.4",
"license": "MIT",
"main": "./dist/index",
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/node-js",
@@ -31,7 +31,7 @@
},
"dependencies": {
"@types/node": "*",
"@vercel/build-utils": "5.0.2",
"@vercel/build-utils": "5.0.3",
"@vercel/node-bridge": "3.0.0",
"@vercel/static-config": "2.0.1",
"edge-runtime": "1.0.1",

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/python",
"version": "3.0.6",
"version": "3.0.7",
"main": "./dist/index.js",
"license": "MIT",
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/python",
@@ -23,7 +23,7 @@
"devDependencies": {
"@types/execa": "^0.9.0",
"@types/jest": "27.4.1",
"@vercel/build-utils": "5.0.2",
"@vercel/build-utils": "5.0.3",
"@vercel/ncc": "0.24.0",
"execa": "^1.0.0",
"typescript": "4.3.4"

View File

@@ -25,9 +25,6 @@ const allOptions: PythonVersion[] = [
},
];
const upstreamProvider =
'This change is the result of a decision made by an upstream infrastructure provider (AWS)';
function getDevPythonVersion(): PythonVersion {
// Use the system-installed version of `python3` when running `vercel dev`
return {
@@ -75,14 +72,14 @@ export function getSupportedPythonVersion({
throw new NowBuildError({
code: 'BUILD_UTILS_PYTHON_VERSION_DISCONTINUED',
link: 'http://vercel.link/python-version',
message: `Python version "${selection.version}" detected in Pipfile.lock is discontinued and must be upgraded. ${upstreamProvider}.`,
message: `Python version "${selection.version}" detected in Pipfile.lock is discontinued and must be upgraded.`,
});
}
if (selection.discontinueDate) {
const d = selection.discontinueDate.toISOString().split('T')[0];
console.warn(
`Error: Python version "${selection.version}" detected in Pipfile.lock is deprecated. Deployments created on or after ${d} will fail to build. ${upstreamProvider}. http://vercel.link/python-version`
`Error: Python version "${selection.version}" detected in Pipfile.lock has reached End-of-Life. Deployments created on or after ${d} will fail to build. http://vercel.link/python-version`
);
}

View File

@@ -5,7 +5,7 @@
{
"path": "/",
"mustContain": "wsgi:RANDOMNESS_PLACEHOLDER",
"logMustContain": "Python version \"3.6\" detected in Pipfile.lock is deprecated. Deployments created on or after 2022-07-18 will fail to build"
"logMustContain": "Python version \"3.6\" detected in Pipfile.lock has reached End-of-Life. Deployments created on or after 2022-07-18 will fail to build"
}
]
}

View File

@@ -8,7 +8,7 @@
{
"path": "/",
"mustContain": "RANDOMNESS_PLACEHOLDER:env",
"logMustContain": "Python version \"3.6\" detected in Pipfile.lock is deprecated. Deployments created on or after 2022-07-18 will fail to build"
"logMustContain": "Python version \"3.6\" detected in Pipfile.lock has reached End-of-Life. Deployments created on or after 2022-07-18 will fail to build"
}
]
}

View File

@@ -58,7 +58,7 @@ it('should throw for discontinued versions', async () => {
expect(() =>
getSupportedPythonVersion({ pipLockPythonVersion: '3.6' })
).toThrow(
'Python version "3.6" detected in Pipfile.lock is discontinued and must be upgraded. This change is the result of a decision made by an upstream infrastructure provider (AWS).'
'Python version "3.6" detected in Pipfile.lock is discontinued and must be upgraded.'
);
expect(warningMessages).toStrictEqual([]);
});
@@ -70,6 +70,6 @@ it('should warn for deprecated versions, soon to be discontinued', async () => {
getSupportedPythonVersion({ pipLockPythonVersion: '3.6' })
).toHaveProperty('runtime', 'python3.6');
expect(warningMessages).toStrictEqual([
'Error: Python version "3.6" detected in Pipfile.lock is deprecated. Deployments created on or after 2022-07-18 will fail to build. This change is the result of a decision made by an upstream infrastructure provider (AWS). http://vercel.link/python-version',
'Error: Python version "3.6" detected in Pipfile.lock has reached End-of-Life. Deployments created on or after 2022-07-18 will fail to build. http://vercel.link/python-version',
]);
});

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/redwood",
"version": "1.0.7",
"version": "1.0.8",
"main": "./dist/index.js",
"license": "MIT",
"homepage": "https://vercel.com/docs",
@@ -21,13 +21,13 @@
},
"dependencies": {
"@vercel/nft": "0.20.1",
"@vercel/routing-utils": "1.13.5",
"@vercel/routing-utils": "2.0.0",
"semver": "6.1.1"
},
"devDependencies": {
"@types/aws-lambda": "8.10.19",
"@types/node": "*",
"@types/semver": "6.0.0",
"@vercel/build-utils": "5.0.2"
"@vercel/build-utils": "5.0.3"
}
}

View File

@@ -283,12 +283,10 @@ export const build: BuildV2 = async ({
: '/index';
const defaultRoutesConfig = getTransformedRoutes({
nowConfig: {
// this makes sure we send back 200.html for unprerendered pages
rewrites: [{ source: '/(.*)', destination: fallbackHtmlPage }],
cleanUrls: true,
trailingSlash: false,
},
// this makes sure we send back 200.html for unprerendered pages
rewrites: [{ source: '/(.*)', destination: fallbackHtmlPage }],
cleanUrls: true,
trailingSlash: false,
});
if (defaultRoutesConfig.error) {

View File

@@ -1,6 +1,5 @@
const fs = require('fs');
const path = require('path');
const { version } = require('../package.json');
const {
packAndDeploy,
@@ -9,10 +8,15 @@ const {
jest.setTimeout(12 * 60 * 1000);
let buildUtilsUrl;
let builderUrl;
const buildUtilsUrl = version.includes('canary') ? '@canary' : undefined;
beforeAll(async () => {
if (!buildUtilsUrl) {
const buildUtilsPath = path.resolve(__dirname, '..', '..', 'build-utils');
buildUtilsUrl = await packAndDeploy(buildUtilsPath);
console.log('buildUtilsUrl', buildUtilsUrl);
}
const builderPath = path.resolve(__dirname, '..');
builderUrl = await packAndDeploy(builderPath);
console.log('builderUrl', builderUrl);

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/remix",
"version": "1.0.8",
"version": "1.0.9",
"license": "MIT",
"main": "./dist/index.js",
"homepage": "https://vercel.com/docs",
@@ -26,7 +26,7 @@
"devDependencies": {
"@types/jest": "27.5.1",
"@types/node": "*",
"@vercel/build-utils": "5.0.2",
"@vercel/build-utils": "5.0.3",
"typescript": "4.6.4"
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/routing-utils",
"version": "1.13.5",
"version": "2.0.0",
"description": "Vercel routing utilities",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",

View File

@@ -1,28 +1,27 @@
import { parse as parseUrl } from 'url';
export * from './schemas';
export * from './types';
import {
Route,
Handler,
NormalizedRoutes,
GetRoutesProps,
RouteApiError,
Redirect,
HasField,
} from './types';
import {
collectHasSegments,
convertCleanUrls,
convertRewrites,
convertRedirects,
convertHeaders,
convertRedirects,
convertRewrites,
convertTrailingSlash,
sourceToRegex,
collectHasSegments,
} from './superstatic';
export { getCleanUrls } from './superstatic';
export { mergeRoutes } from './merge';
import {
GetRoutesProps,
HasField,
NormalizedRoutes,
Redirect,
Route,
RouteApiError,
RouteWithHandle,
} from './types';
export { appendRoutesToPhase } from './append';
export { mergeRoutes } from './merge';
export * from './schemas';
export { getCleanUrls } from './superstatic';
export * from './types';
const VALID_HANDLE_VALUES = [
'filesystem',
@@ -35,8 +34,8 @@ const VALID_HANDLE_VALUES = [
const validHandleValues = new Set<string>(VALID_HANDLE_VALUES);
export type HandleValue = typeof VALID_HANDLE_VALUES[number];
export function isHandler(route: Route): route is Handler {
return typeof (route as Handler).handle !== 'undefined';
export function isHandler(route: Route): route is RouteWithHandle {
return typeof (route as RouteWithHandle).handle !== 'undefined';
}
export function isValidHandleValue(handle: string): handle is HandleValue {
@@ -249,11 +248,12 @@ function notEmpty<T>(value: T | null | undefined): value is T {
return value !== null && value !== undefined;
}
export function getTransformedRoutes({
nowConfig,
}: GetRoutesProps): NormalizedRoutes {
const { cleanUrls, rewrites, redirects, headers, trailingSlash } = nowConfig;
let { routes = null } = nowConfig;
export function getTransformedRoutes(
vercelConfig: GetRoutesProps
): NormalizedRoutes {
const { cleanUrls, rewrites, redirects, headers, trailingSlash } =
vercelConfig;
let { routes = null } = vercelConfig;
if (routes) {
const hasNewProperties =
typeof cleanUrls !== 'undefined' ||

View File

@@ -21,7 +21,7 @@ export type HasField = Array<
}
>;
export type Source = {
export type RouteWithSrc = {
src: string;
dest?: string;
headers?: { [name: string]: string };
@@ -49,14 +49,14 @@ export type Source = {
middleware?: number;
};
export type Handler = {
export type RouteWithHandle = {
handle: HandleValue;
src?: string;
dest?: string;
status?: number;
};
export type Route = Source | Handler;
export type Route = RouteWithSrc | RouteWithHandle;
export type NormalizedRoutes = {
routes: Route[] | null;
@@ -64,7 +64,12 @@ export type NormalizedRoutes = {
};
export interface GetRoutesProps {
nowConfig: VercelConfig;
routes?: Route[];
cleanUrls?: boolean;
rewrites?: Rewrite[];
redirects?: Redirect[];
headers?: Header[];
trailingSlash?: boolean;
}
export interface MergeRoutesProps {
@@ -78,17 +83,6 @@ export interface Build {
routes?: Route[];
}
export interface VercelConfig {
name?: string;
version?: number;
routes?: Route[];
cleanUrls?: boolean;
rewrites?: Rewrite[];
redirects?: Redirect[];
headers?: Header[];
trailingSlash?: boolean;
}
export interface Rewrite {
source: string;
destination: string;
@@ -131,18 +125,3 @@ export interface AppendRoutesToPhaseProps {
*/
phase: HandleValue;
}
/** @deprecated Use VercelConfig instead. */
export type NowConfig = VercelConfig;
/** @deprecated Use Rewrite instead. */
export type NowRewrite = Rewrite;
/** @deprecated Use Redirect instead. */
export type NowRedirect = Redirect;
/** @deprecated Use Header instead. */
export type NowHeader = Header;
/** @deprecated Use HeaderKeyValue instead. */
export type NowHeaderKeyValue = HeaderKeyValue;

View File

@@ -775,24 +775,24 @@ describe('normalizeRoutes', () => {
});
describe('getTransformedRoutes', () => {
test('should normalize nowConfig.routes', () => {
const nowConfig = { routes: [{ src: '/page', dest: '/page.html' }] };
const actual = getTransformedRoutes({ nowConfig });
const expected = normalizeRoutes(nowConfig.routes);
test('should normalize vercelConfig.routes', () => {
const vercelConfig = { routes: [{ src: '/page', dest: '/page.html' }] };
const actual = getTransformedRoutes(vercelConfig);
const expected = normalizeRoutes(vercelConfig.routes);
assert.deepEqual(actual, expected);
assertValid(actual.routes);
});
test('should not error when routes is null and cleanUrls is true', () => {
const nowConfig = { cleanUrls: true, routes: null };
const vercelConfig = { cleanUrls: true, routes: null };
// @ts-expect-error intentionally passing invalid `routes: null` here
const actual = getTransformedRoutes({ nowConfig });
const actual = getTransformedRoutes(vercelConfig);
assert.equal(actual.error, null);
assertValid(actual.routes);
});
test('should not error when has segment is used in destination', () => {
const nowConfig = {
const vercelConfig = {
redirects: [
{
source: '/redirect',
@@ -809,17 +809,17 @@ describe('getTransformedRoutes', () => {
};
// @ts-expect-error not sure if this one is an error or not…
const actual = getTransformedRoutes({ nowConfig });
const actual = getTransformedRoutes(vercelConfig);
assert.equal(actual.error, null);
assertValid(actual.routes);
});
test('should error when routes is defined and cleanUrls is true', () => {
const nowConfig = {
const vercelConfig = {
cleanUrls: true,
routes: [{ src: '/page', dest: '/file.html' }],
};
const { error } = getTransformedRoutes({ nowConfig });
const { error } = getTransformedRoutes(vercelConfig);
assert.notEqual(error, null);
assert.equal(error?.code, 'invalid_mixed_routes');
assert.equal(
@@ -831,10 +831,10 @@ describe('getTransformedRoutes', () => {
});
test('should error when redirects is invalid regex', () => {
const nowConfig = {
const vercelConfig = {
redirects: [{ source: '^/(*.)\\.html$', destination: '/file.html' }],
};
const { error } = getTransformedRoutes({ nowConfig });
const { error } = getTransformedRoutes(vercelConfig);
assert.notEqual(error, null);
assert.equal(error?.code, 'invalid_redirect');
assert.equal(
@@ -846,10 +846,10 @@ describe('getTransformedRoutes', () => {
});
test('should error when redirects is invalid pattern', () => {
const nowConfig = {
const vercelConfig = {
redirects: [{ source: '/:?', destination: '/file.html' }],
};
const { error } = getTransformedRoutes({ nowConfig });
const { error } = getTransformedRoutes(vercelConfig);
assert.notEqual(error, null);
assert.equal(error?.code, 'invalid_redirect');
assert.equal(
@@ -861,7 +861,7 @@ describe('getTransformedRoutes', () => {
});
test('should error when redirects defines both permanent and statusCode', () => {
const nowConfig = {
const vercelConfig = {
redirects: [
{
source: '^/both$',
@@ -871,7 +871,7 @@ describe('getTransformedRoutes', () => {
},
],
};
const { error } = getTransformedRoutes({ nowConfig });
const { error } = getTransformedRoutes(vercelConfig);
assert.notEqual(error, null);
assert.equal(error?.code, 'invalid_redirect');
assert.equal(
@@ -883,7 +883,7 @@ describe('getTransformedRoutes', () => {
});
test('should error when headers is invalid regex', () => {
const nowConfig = {
const vercelConfig = {
headers: [
{
source: '^/(*.)\\.html$',
@@ -896,7 +896,7 @@ describe('getTransformedRoutes', () => {
},
],
};
const { error } = getTransformedRoutes({ nowConfig });
const { error } = getTransformedRoutes(vercelConfig);
assert.notEqual(error, null);
assert.equal(error?.code, 'invalid_header');
assert.equal(
@@ -908,12 +908,12 @@ describe('getTransformedRoutes', () => {
});
test('should error when headers is invalid pattern', () => {
const nowConfig = {
const vercelConfig = {
headers: [
{ source: '/:?', headers: [{ key: 'x-hello', value: 'world' }] },
],
};
const { error } = getTransformedRoutes({ nowConfig });
const { error } = getTransformedRoutes(vercelConfig);
assert.notEqual(error, null);
assert.equal(error?.code, 'invalid_header');
assert.equal(
@@ -925,10 +925,10 @@ describe('getTransformedRoutes', () => {
});
test('should error when rewrites is invalid regex', () => {
const nowConfig = {
const vercelConfig = {
rewrites: [{ source: '^/(*.)\\.html$', destination: '/file.html' }],
};
const { error } = getTransformedRoutes({ nowConfig });
const { error } = getTransformedRoutes(vercelConfig);
assert.notEqual(error, null);
assert.equal(error?.code, 'invalid_rewrite');
assert.equal(
@@ -940,10 +940,10 @@ describe('getTransformedRoutes', () => {
});
test('should error when rewrites is invalid pattern', () => {
const nowConfig = {
const vercelConfig = {
rewrites: [{ source: '/:?', destination: '/file.html' }],
};
const { error } = getTransformedRoutes({ nowConfig });
const { error } = getTransformedRoutes(vercelConfig);
assert.notEqual(error, null);
assert.equal(error?.code, 'invalid_rewrite');
assert.equal(
@@ -955,7 +955,7 @@ describe('getTransformedRoutes', () => {
});
test('should normalize all redirects before rewrites', () => {
const nowConfig = {
const vercelConfig = {
cleanUrls: true,
rewrites: [{ source: '/v1', destination: '/v2/api.py' }],
redirects: [
@@ -967,7 +967,7 @@ describe('getTransformedRoutes', () => {
},
],
};
const { error, routes } = getTransformedRoutes({ nowConfig });
const { error, routes } = getTransformedRoutes(vercelConfig);
const expected = [
{
src: '^/(?:(.+)/)?index(?:\\.html)?/?$',
@@ -998,7 +998,7 @@ describe('getTransformedRoutes', () => {
});
test('should validate schemas', () => {
const nowConfig = {
const vercelConfig = {
cleanUrls: true,
rewrites: [
{ source: '/page', destination: '/page.html' },
@@ -1071,22 +1071,22 @@ describe('getTransformedRoutes', () => {
],
trailingSlashSchema: false,
};
assertValid(nowConfig.cleanUrls, cleanUrlsSchema);
assertValid(nowConfig.rewrites, rewritesSchema);
assertValid(nowConfig.redirects, redirectsSchema);
assertValid(nowConfig.headers, headersSchema);
assertValid(nowConfig.trailingSlashSchema, trailingSlashSchema);
assertValid(vercelConfig.cleanUrls, cleanUrlsSchema);
assertValid(vercelConfig.rewrites, rewritesSchema);
assertValid(vercelConfig.redirects, redirectsSchema);
assertValid(vercelConfig.headers, headersSchema);
assertValid(vercelConfig.trailingSlashSchema, trailingSlashSchema);
});
test('should return null routes if no transformations are performed', () => {
const nowConfig = { routes: null };
const vercelConfig = { routes: null };
// @ts-expect-error intentionally passing invalid `routes: null`
const { routes } = getTransformedRoutes({ nowConfig });
const { routes } = getTransformedRoutes(vercelConfig);
assert.equal(routes, null);
});
test('should error when segment is defined in `destination` but not `source`', () => {
const nowConfig = {
const vercelConfig = {
redirects: [
{
source: '/iforgot/:id',
@@ -1094,7 +1094,7 @@ describe('getTransformedRoutes', () => {
},
],
};
const { routes, error } = getTransformedRoutes({ nowConfig });
const { routes, error } = getTransformedRoutes(vercelConfig);
assert.deepEqual(routes, null);
assert.ok(
error?.message.includes(
@@ -1105,7 +1105,7 @@ describe('getTransformedRoutes', () => {
});
test('should error when segment is defined in HTTPS `destination` but not `source`', () => {
const nowConfig = {
const vercelConfig = {
redirects: [
{
source: '/iforgot/:id',
@@ -1113,7 +1113,7 @@ describe('getTransformedRoutes', () => {
},
],
};
const { routes, error } = getTransformedRoutes({ nowConfig });
const { routes, error } = getTransformedRoutes(vercelConfig);
assert.deepEqual(routes, null);
assert.ok(
error?.message.includes(
@@ -1124,7 +1124,7 @@ describe('getTransformedRoutes', () => {
});
test('should error when segment is defined in `destination` query string but not `source`', () => {
const nowConfig = {
const vercelConfig = {
redirects: [
{
source: '/iforgot/:id',
@@ -1132,7 +1132,7 @@ describe('getTransformedRoutes', () => {
},
],
};
const { routes, error } = getTransformedRoutes({ nowConfig });
const { routes, error } = getTransformedRoutes(vercelConfig);
assert.deepEqual(routes, null);
assert.ok(
error?.message.includes(
@@ -1143,7 +1143,7 @@ describe('getTransformedRoutes', () => {
});
test('should error when segment is defined in HTTPS `destination` query string but not `source`', () => {
const nowConfig = {
const vercelConfig = {
redirects: [
{
source: '/iforgot/:id',
@@ -1151,7 +1151,7 @@ describe('getTransformedRoutes', () => {
},
],
};
const { routes, error } = getTransformedRoutes({ nowConfig });
const { routes, error } = getTransformedRoutes(vercelConfig);
assert.deepEqual(routes, null);
assert.ok(
error?.message.includes(
@@ -1162,7 +1162,7 @@ describe('getTransformedRoutes', () => {
});
test('should work with content-security-policy header containing URL', () => {
const nowConfig = {
const vercelConfig = {
headers: [
{
source: '/(.*)',
@@ -1201,7 +1201,7 @@ describe('getTransformedRoutes', () => {
},
],
};
const actual = getTransformedRoutes({ nowConfig });
const actual = getTransformedRoutes(vercelConfig);
assert.deepEqual(actual.routes, [
{
continue: true,

View File

@@ -1,5 +1,5 @@
import { deepEqual } from 'assert';
import { Route, Source, normalizeRoutes } from '../src';
import { Route, RouteWithSrc, normalizeRoutes } from '../src';
import {
getCleanUrls,
convertCleanUrls,
@@ -15,7 +15,7 @@ function routesToRegExps(routeArray: Route[]) {
throw error;
}
return (routes || [])
.filter((r): r is Source => 'src' in r)
.filter((r): r is RouteWithSrc => 'src' in r)
.map(r => new RegExp(r.src));
}

View File

@@ -56,12 +56,10 @@ function getRubyPath(meta: Meta, gemfileContents: string) {
const latest = getLatestRubyVersion();
const intro = `Found \`Gemfile\` with discontinued Ruby version: \`${line}.\``;
const hint = `Please set \`ruby "~> ${latest.range}"\` in your \`Gemfile\` to use Ruby ${latest.range}.`;
const upstream =
'This change is the result of a decision made by an upstream infrastructure provider (AWS).';
throw new NowBuildError({
code: 'RUBY_DISCONTINUED_VERSION',
link: 'http://vercel.link/ruby-version',
message: `${intro} ${hint} ${upstream}`,
message: `${intro} ${hint}`,
});
}
}

View File

@@ -1,7 +1,7 @@
{
"name": "@vercel/ruby",
"author": "Nathan Cahill <nathan@nathancahill.com>",
"version": "1.3.14",
"version": "1.3.15",
"license": "MIT",
"main": "./dist/index",
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/ruby",
@@ -23,7 +23,7 @@
"devDependencies": {
"@types/fs-extra": "8.0.0",
"@types/semver": "6.0.0",
"@vercel/build-utils": "5.0.2",
"@vercel/build-utils": "5.0.3",
"@vercel/ncc": "0.24.0",
"execa": "2.0.4",
"fs-extra": "^7.0.1",

View File

@@ -26,7 +26,7 @@ const fixturesPath = path.resolve(__dirname, 'fixtures');
const testsThatFailToBuild = new Map([
[
'11-version-2-5-error',
'Found `Gemfile` with discontinued Ruby version: `ruby "~> 2.5.x".` Please set `ruby "~> 2.7.x"` in your `Gemfile` to use Ruby 2.7.x. This change is the result of a decision made by an upstream infrastructure provider (AWS).',
'Found `Gemfile` with discontinued Ruby version: `ruby "~> 2.5.x".` Please set `ruby "~> 2.7.x"` in your `Gemfile` to use Ruby 2.7.x.',
],
]);

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/static-build",
"version": "1.0.7",
"version": "1.0.8",
"license": "MIT",
"main": "./dist/index",
"homepage": "https://vercel.com/docs/build-step",
@@ -37,10 +37,10 @@
"@types/ms": "0.7.31",
"@types/node-fetch": "2.5.4",
"@types/promise-timeout": "1.3.0",
"@vercel/build-utils": "5.0.2",
"@vercel/frameworks": "1.1.0",
"@vercel/build-utils": "5.0.3",
"@vercel/frameworks": "1.1.1",
"@vercel/ncc": "0.24.0",
"@vercel/routing-utils": "1.13.5",
"@vercel/routing-utils": "2.0.0",
"fs-extra": "10.0.0",
"get-port": "5.0.0",
"is-port-reachable": "2.0.1",

View File

@@ -31,7 +31,7 @@ import {
NowBuildError,
scanParentDirs,
} from '@vercel/build-utils';
import type { Route, Source } from '@vercel/routing-utils';
import type { Route, RouteWithSrc } from '@vercel/routing-utils';
import * as BuildOutputV1 from './utils/build-output-v1';
import * as BuildOutputV2 from './utils/build-output-v2';
import * as BuildOutputV3 from './utils/build-output-v3';
@@ -173,8 +173,8 @@ const nowDevChildProcesses = new Set<ChildProcess>();
});
});
const getDevRoute = (srcBase: string, devPort: number, route: Source) => {
const basic: Source = {
const getDevRoute = (srcBase: string, devPort: number, route: RouteWithSrc) => {
const basic: RouteWithSrc = {
src: `${srcBase}${route.src}`,
dest: `http://localhost:${devPort}${route.dest}`,
};