mirror of
https://github.com/LukeHagar/vercel.git
synced 2025-12-11 21:07:47 +00:00
Compare commits
5 Commits
@vercel/py
...
@vercel/py
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4bf6295d7a | ||
|
|
a4001ce10b | ||
|
|
2df3432d88 | ||
|
|
bcfc19de12 | ||
|
|
04381c669b |
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vercel/build-utils",
|
"name": "@vercel/build-utils",
|
||||||
"version": "4.1.0",
|
"version": "4.1.1-canary.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"types": "./dist/index.d.js",
|
"types": "./dist/index.d.js",
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ interface ErrorResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface Options {
|
interface Options {
|
||||||
tag?: 'canary' | 'latest' | string;
|
tag?: string;
|
||||||
functions?: BuilderFunctions;
|
functions?: BuilderFunctions;
|
||||||
ignoreBuildScript?: boolean;
|
ignoreBuildScript?: boolean;
|
||||||
projectSettings?: ProjectSettings;
|
projectSettings?: ProjectSettings;
|
||||||
@@ -278,7 +278,7 @@ export async function detectBuilders(
|
|||||||
// and package.json can be served as static files
|
// and package.json can be served as static files
|
||||||
frontendBuilder = {
|
frontendBuilder = {
|
||||||
use: '@vercel/static',
|
use: '@vercel/static',
|
||||||
src: '!{api/**,package.json}',
|
src: '!{api/**,package.json,middleware.[jt]s}',
|
||||||
config: {
|
config: {
|
||||||
zeroConfig: true,
|
zeroConfig: true,
|
||||||
},
|
},
|
||||||
@@ -355,7 +355,16 @@ function maybeGetApiBuilder(
|
|||||||
apiMatches: Builder[],
|
apiMatches: Builder[],
|
||||||
options: Options
|
options: Options
|
||||||
) {
|
) {
|
||||||
if (!fileName.startsWith('api/')) {
|
const middleware =
|
||||||
|
fileName === 'middleware.js' || fileName === 'middleware.ts';
|
||||||
|
|
||||||
|
// Root-level Middleware file is handled by `@vercel/next`, so don't
|
||||||
|
// schedule a separate Builder when "nextjs" framework is selected
|
||||||
|
if (middleware && options.projectSettings?.framework === 'nextjs') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(fileName.startsWith('api/') || middleware)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -381,7 +390,7 @@ function maybeGetApiBuilder(
|
|||||||
|
|
||||||
const { fnPattern, func } = getFunction(fileName, options);
|
const { fnPattern, func } = getFunction(fileName, options);
|
||||||
|
|
||||||
const use = (func && func.runtime) || (match && match.use);
|
const use = func?.runtime || match?.use;
|
||||||
|
|
||||||
if (!use) {
|
if (!use) {
|
||||||
return null;
|
return null;
|
||||||
@@ -389,6 +398,10 @@ function maybeGetApiBuilder(
|
|||||||
|
|
||||||
const config: Config = { zeroConfig: true };
|
const config: Config = { zeroConfig: true };
|
||||||
|
|
||||||
|
if (middleware) {
|
||||||
|
config.middleware = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (fnPattern && func) {
|
if (fnPattern && func) {
|
||||||
config.functions = { [fnPattern]: func };
|
config.functions = { [fnPattern]: func };
|
||||||
|
|
||||||
@@ -428,6 +441,7 @@ function getApiMatches() {
|
|||||||
const config = { zeroConfig: true };
|
const config = { zeroConfig: true };
|
||||||
|
|
||||||
return [
|
return [
|
||||||
|
{ src: 'middleware.[jt]s', use: `@vercel/node`, config },
|
||||||
{ src: 'api/**/*.js', use: `@vercel/node`, config },
|
{ src: 'api/**/*.js', use: `@vercel/node`, config },
|
||||||
{ src: 'api/**/*.mjs', use: `@vercel/node`, config },
|
{ src: 'api/**/*.mjs', use: `@vercel/node`, config },
|
||||||
{ src: 'api/**/*.ts', use: `@vercel/node`, config },
|
{ src: 'api/**/*.ts', use: `@vercel/node`, config },
|
||||||
|
|||||||
60
packages/build-utils/src/get-project-paths.ts
Normal file
60
packages/build-utils/src/get-project-paths.ts
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
import { detectFramework } from './detect-framework';
|
||||||
|
import { DetectorFilesystem } from './detectors/filesystem';
|
||||||
|
import frameworks from '@vercel/frameworks';
|
||||||
|
|
||||||
|
const MAX_DEPTH_TRAVERSE = 3;
|
||||||
|
|
||||||
|
export interface GetProjectPathsOptions {
|
||||||
|
fs: DetectorFilesystem;
|
||||||
|
path?: string;
|
||||||
|
skipPaths?: string[];
|
||||||
|
depth?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ProjectPath = string;
|
||||||
|
|
||||||
|
export const getProjectPaths = async ({
|
||||||
|
fs,
|
||||||
|
path,
|
||||||
|
skipPaths,
|
||||||
|
depth = MAX_DEPTH_TRAVERSE,
|
||||||
|
}: GetProjectPathsOptions): Promise<ProjectPath[]> => {
|
||||||
|
if (depth === 0) return [];
|
||||||
|
|
||||||
|
const allPaths: Array<ProjectPath> = [];
|
||||||
|
const topPath: string = path ?? './';
|
||||||
|
|
||||||
|
if (path && skipPaths?.includes(path)) {
|
||||||
|
return allPaths;
|
||||||
|
}
|
||||||
|
const framework = await detectFramework({
|
||||||
|
fs: fs.chdir(topPath),
|
||||||
|
frameworkList: frameworks,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (framework !== null) allPaths.push(topPath);
|
||||||
|
|
||||||
|
if (depth > 1) {
|
||||||
|
const directoryContents = await fs.readdir(topPath);
|
||||||
|
const childDirectories = directoryContents.filter(
|
||||||
|
stat => stat.type === 'dir' && !skipPaths?.includes(stat.path)
|
||||||
|
);
|
||||||
|
|
||||||
|
const paths = (
|
||||||
|
await Promise.all(
|
||||||
|
childDirectories.map(({ path }) => {
|
||||||
|
return getProjectPaths({
|
||||||
|
fs,
|
||||||
|
path,
|
||||||
|
depth: depth - 1,
|
||||||
|
skipPaths,
|
||||||
|
});
|
||||||
|
})
|
||||||
|
)
|
||||||
|
).flat();
|
||||||
|
|
||||||
|
return [...paths, ...allPaths];
|
||||||
|
}
|
||||||
|
|
||||||
|
return allPaths;
|
||||||
|
};
|
||||||
@@ -88,6 +88,7 @@ export {
|
|||||||
} from './detect-builders';
|
} from './detect-builders';
|
||||||
export { detectFileSystemAPI } from './detect-file-system-api';
|
export { detectFileSystemAPI } from './detect-file-system-api';
|
||||||
export { detectFramework } from './detect-framework';
|
export { detectFramework } from './detect-framework';
|
||||||
|
export { getProjectPaths } from './get-project-paths';
|
||||||
export { DetectorFilesystem } from './detectors/filesystem';
|
export { DetectorFilesystem } from './detectors/filesystem';
|
||||||
export { readConfigFile } from './fs/read-config-file';
|
export { readConfigFile } from './fs/read-config-file';
|
||||||
export { normalizePath } from './fs/normalize-path';
|
export { normalizePath } from './fs/normalize-path';
|
||||||
|
|||||||
@@ -428,6 +428,8 @@ export interface BuildResultV2Typical {
|
|||||||
export type BuildResultV2 = BuildResultV2Typical | BuildResultBuildOutput;
|
export type BuildResultV2 = BuildResultV2Typical | BuildResultBuildOutput;
|
||||||
|
|
||||||
export interface BuildResultV3 {
|
export interface BuildResultV3 {
|
||||||
|
// TODO: use proper `Route` type from `routing-utils` (perhaps move types to a common package)
|
||||||
|
routes?: any[];
|
||||||
output: Lambda | EdgeFunction;
|
output: Lambda | EdgeFunction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"name": "app-three",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"next": "^4.3.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"name": "backend",
|
||||||
|
"license": "MIT",
|
||||||
|
"version": "0.1.0"
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"name": "app-one",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"next": "^4.3.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"name": "app-one",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"next": "^4.3.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"name": "frontend",
|
||||||
|
"license": "MIT",
|
||||||
|
"version": "0.1.0"
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"name": "app-three",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"next": "^4.3.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"name": "backend",
|
||||||
|
"license": "MIT",
|
||||||
|
"version": "0.1.0"
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"name": "a",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"debug": "^4.3.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"name": "b",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"cowsay": "^1.5.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"name": "21-npm-workspaces",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"private": true,
|
||||||
|
"workspaces": [
|
||||||
|
"a",
|
||||||
|
"b"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"name": "app-three",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"next": "^4.3.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"name": "backend",
|
||||||
|
"license": "MIT",
|
||||||
|
"version": "0.1.0"
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"name": "app-one",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"next": "^4.3.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"name": "app-two",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"next": "^4.3.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"name": "frontend",
|
||||||
|
"license": "MIT",
|
||||||
|
"version": "0.1.0"
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"name": "app-one",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC"
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"name": "app-one",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"next": "^4.3.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"name": "app-two",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"next": "^4.3.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"name": "frontend",
|
||||||
|
"license": "MIT",
|
||||||
|
"version": "0.1.0"
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"name": "app-one",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"next": "^4.3.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -78,7 +78,7 @@ describe('Test `detectBuilders`', () => {
|
|||||||
expect(builders![0].use).toBe('@vercel/node');
|
expect(builders![0].use).toBe('@vercel/node');
|
||||||
expect(builders![0].src).toBe('api/users.js');
|
expect(builders![0].src).toBe('api/users.js');
|
||||||
expect(builders![1].use).toBe('@vercel/static');
|
expect(builders![1].use).toBe('@vercel/static');
|
||||||
expect(builders![1].src).toBe('!{api/**,package.json}');
|
expect(builders![1].src).toBe('!{api/**,package.json,middleware.[jt]s}');
|
||||||
expect(builders!.length).toBe(2);
|
expect(builders!.length).toBe(2);
|
||||||
expect(errors).toBe(null);
|
expect(errors).toBe(null);
|
||||||
});
|
});
|
||||||
@@ -89,7 +89,7 @@ describe('Test `detectBuilders`', () => {
|
|||||||
expect(builders![0].use).toBe('@vercel/node');
|
expect(builders![0].use).toBe('@vercel/node');
|
||||||
expect(builders![0].src).toBe('api/[endpoint].js');
|
expect(builders![0].src).toBe('api/[endpoint].js');
|
||||||
expect(builders![1].use).toBe('@vercel/static');
|
expect(builders![1].use).toBe('@vercel/static');
|
||||||
expect(builders![1].src).toBe('!{api/**,package.json}');
|
expect(builders![1].src).toBe('!{api/**,package.json,middleware.[jt]s}');
|
||||||
expect(builders!.length).toBe(2);
|
expect(builders!.length).toBe(2);
|
||||||
expect(errors).toBe(null);
|
expect(errors).toBe(null);
|
||||||
});
|
});
|
||||||
@@ -144,7 +144,7 @@ describe('Test `detectBuilders`', () => {
|
|||||||
expect(builders![0].use).toBe('@vercel/node');
|
expect(builders![0].use).toBe('@vercel/node');
|
||||||
expect(builders![0].src).toBe('api/endpoint.js');
|
expect(builders![0].src).toBe('api/endpoint.js');
|
||||||
expect(builders![1].use).toBe('@vercel/static');
|
expect(builders![1].use).toBe('@vercel/static');
|
||||||
expect(builders![1].src).toBe('!{api/**,package.json}');
|
expect(builders![1].src).toBe('!{api/**,package.json,middleware.[jt]s}');
|
||||||
expect(builders!.length).toBe(2);
|
expect(builders!.length).toBe(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -347,7 +347,7 @@ describe('Test `detectBuilders`', () => {
|
|||||||
expect(builders![0].use).toBe('@vercel/node');
|
expect(builders![0].use).toBe('@vercel/node');
|
||||||
expect(builders![0].src).toBe('api/index.ts');
|
expect(builders![0].src).toBe('api/index.ts');
|
||||||
expect(builders![1].use).toBe('@vercel/static');
|
expect(builders![1].use).toBe('@vercel/static');
|
||||||
expect(builders![1].src).toBe('!{api/**,package.json}');
|
expect(builders![1].src).toBe('!{api/**,package.json,middleware.[jt]s}');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('functions with nextjs', async () => {
|
it('functions with nextjs', async () => {
|
||||||
@@ -1010,7 +1010,7 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
|
|||||||
expect(builders![0].use).toBe('@vercel/node');
|
expect(builders![0].use).toBe('@vercel/node');
|
||||||
expect(builders![0].src).toBe('api/users.js');
|
expect(builders![0].src).toBe('api/users.js');
|
||||||
expect(builders![1].use).toBe('@vercel/static');
|
expect(builders![1].use).toBe('@vercel/static');
|
||||||
expect(builders![1].src).toBe('!{api/**,package.json}');
|
expect(builders![1].src).toBe('!{api/**,package.json,middleware.[jt]s}');
|
||||||
expect(builders!.length).toBe(2);
|
expect(builders!.length).toBe(2);
|
||||||
expect(errors).toBe(null);
|
expect(errors).toBe(null);
|
||||||
|
|
||||||
@@ -1032,7 +1032,7 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
|
|||||||
expect(builders![0].use).toBe('@vercel/node');
|
expect(builders![0].use).toBe('@vercel/node');
|
||||||
expect(builders![0].src).toBe('api/[endpoint].js');
|
expect(builders![0].src).toBe('api/[endpoint].js');
|
||||||
expect(builders![1].use).toBe('@vercel/static');
|
expect(builders![1].use).toBe('@vercel/static');
|
||||||
expect(builders![1].src).toBe('!{api/**,package.json}');
|
expect(builders![1].src).toBe('!{api/**,package.json,middleware.[jt]s}');
|
||||||
expect(builders!.length).toBe(2);
|
expect(builders!.length).toBe(2);
|
||||||
expect(errors).toBe(null);
|
expect(errors).toBe(null);
|
||||||
});
|
});
|
||||||
@@ -1258,7 +1258,7 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
|
|||||||
expect(builders![0].use).toBe('@vercel/node');
|
expect(builders![0].use).toBe('@vercel/node');
|
||||||
expect(builders![0].src).toBe('api/endpoint.js');
|
expect(builders![0].src).toBe('api/endpoint.js');
|
||||||
expect(builders![1].use).toBe('@vercel/static');
|
expect(builders![1].use).toBe('@vercel/static');
|
||||||
expect(builders![1].src).toBe('!{api/**,package.json}');
|
expect(builders![1].src).toBe('!{api/**,package.json,middleware.[jt]s}');
|
||||||
expect(builders!.length).toBe(2);
|
expect(builders!.length).toBe(2);
|
||||||
|
|
||||||
expect(defaultRoutes!.length).toBe(2);
|
expect(defaultRoutes!.length).toBe(2);
|
||||||
@@ -1288,7 +1288,7 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
|
|||||||
expect(builders![0].use).toBe('@vercel/node');
|
expect(builders![0].use).toBe('@vercel/node');
|
||||||
expect(builders![0].src).toBe('api/version.js');
|
expect(builders![0].src).toBe('api/version.js');
|
||||||
expect(builders![1].use).toBe('@vercel/static');
|
expect(builders![1].use).toBe('@vercel/static');
|
||||||
expect(builders![1].src).toBe('!{api/**,package.json}');
|
expect(builders![1].src).toBe('!{api/**,package.json,middleware.[jt]s}');
|
||||||
expect(builders!.length).toBe(2);
|
expect(builders!.length).toBe(2);
|
||||||
|
|
||||||
expect(defaultRoutes!.length).toBe(2);
|
expect(defaultRoutes!.length).toBe(2);
|
||||||
@@ -1567,7 +1567,7 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
|
|||||||
expect(builders![0].use).toBe('@vercel/node');
|
expect(builders![0].use).toBe('@vercel/node');
|
||||||
expect(builders![0].src).toBe('api/index.ts');
|
expect(builders![0].src).toBe('api/index.ts');
|
||||||
expect(builders![1].use).toBe('@vercel/static');
|
expect(builders![1].use).toBe('@vercel/static');
|
||||||
expect(builders![1].src).toBe('!{api/**,package.json}');
|
expect(builders![1].src).toBe('!{api/**,package.json,middleware.[jt]s}');
|
||||||
expect(errorRoutes!.length).toBe(1);
|
expect(errorRoutes!.length).toBe(1);
|
||||||
expect((errorRoutes![0] as Source).status).toBe(404);
|
expect((errorRoutes![0] as Source).status).toBe(404);
|
||||||
});
|
});
|
||||||
@@ -2228,6 +2228,55 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
|
|||||||
expect(builders).toBe(null);
|
expect(builders).toBe(null);
|
||||||
expect(errors).toBe(null);
|
expect(errors).toBe(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('no package.json + no build + root-level "middleware.js"', async () => {
|
||||||
|
const files = ['middleware.js', 'index.html', 'web/middleware.js'];
|
||||||
|
const { builders, errors } = await detectBuilders(files, null, {
|
||||||
|
featHandleMiss,
|
||||||
|
});
|
||||||
|
expect(builders![0].use).toBe('@vercel/node');
|
||||||
|
expect(builders![0].src).toBe('middleware.js');
|
||||||
|
expect(builders![0].config?.middleware).toEqual(true);
|
||||||
|
expect(builders![1].use).toBe('@vercel/static');
|
||||||
|
expect(builders![1].src).toBe('!{api/**,package.json,middleware.[jt]s}');
|
||||||
|
expect(builders!.length).toBe(2);
|
||||||
|
expect(errors).toBe(null);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('no package.json + no build + root-level "middleware.ts"', async () => {
|
||||||
|
const files = ['middleware.ts', 'index.html', 'web/middleware.js'];
|
||||||
|
const { builders, errors } = await detectBuilders(files, null, {
|
||||||
|
featHandleMiss,
|
||||||
|
});
|
||||||
|
expect(builders![0].use).toBe('@vercel/node');
|
||||||
|
expect(builders![0].src).toBe('middleware.ts');
|
||||||
|
expect(builders![0].config?.middleware).toEqual(true);
|
||||||
|
expect(builders![1].use).toBe('@vercel/static');
|
||||||
|
expect(builders![1].src).toBe('!{api/**,package.json,middleware.[jt]s}');
|
||||||
|
expect(builders!.length).toBe(2);
|
||||||
|
expect(errors).toBe(null);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not add middleware builder when "nextjs" framework is selected', async () => {
|
||||||
|
const files = ['package.json', 'pages/index.ts', 'middleware.ts'];
|
||||||
|
const projectSettings = {
|
||||||
|
framework: 'nextjs',
|
||||||
|
};
|
||||||
|
const { builders } = await detectBuilders(files, null, {
|
||||||
|
projectSettings,
|
||||||
|
featHandleMiss,
|
||||||
|
});
|
||||||
|
expect(builders).toEqual([
|
||||||
|
{
|
||||||
|
use: '@vercel/next',
|
||||||
|
src: 'package.json',
|
||||||
|
config: {
|
||||||
|
zeroConfig: true,
|
||||||
|
framework: projectSettings.framework,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Test `detectRoutes`', async () => {
|
it('Test `detectRoutes`', async () => {
|
||||||
|
|||||||
70
packages/build-utils/test/unit.get-project-paths.test.ts
vendored
Normal file
70
packages/build-utils/test/unit.get-project-paths.test.ts
vendored
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
import path from 'path';
|
||||||
|
import { normalizePath } from '../src';
|
||||||
|
import { getProjectPaths, ProjectPath } from '../src/get-project-paths';
|
||||||
|
import { FixtureFilesystem } from './utils/fixture-filesystem';
|
||||||
|
|
||||||
|
describe.each<{
|
||||||
|
fixturePath: string;
|
||||||
|
resultPaths: ProjectPath[];
|
||||||
|
skipPaths?: ProjectPath[];
|
||||||
|
readdirCalls: number;
|
||||||
|
}>([
|
||||||
|
{
|
||||||
|
fixturePath: '32-monorepo-highly-nested',
|
||||||
|
resultPaths: [],
|
||||||
|
readdirCalls: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fixturePath: '33-hybrid-monorepo',
|
||||||
|
resultPaths: ['backend/app-three'],
|
||||||
|
readdirCalls: 2,
|
||||||
|
skipPaths: ['frontend'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fixturePath: '34-monorepo-no-workspaces',
|
||||||
|
resultPaths: ['backend/app-three', 'frontend/app-one', 'frontend/app-two'],
|
||||||
|
readdirCalls: 3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fixturePath: '35-no-monorepo',
|
||||||
|
resultPaths: [],
|
||||||
|
readdirCalls: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fixturePath: '36-monorepo-some-nested',
|
||||||
|
resultPaths: ['frontend/app-two'],
|
||||||
|
readdirCalls: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fixturePath: '37-project-depth-one-level',
|
||||||
|
resultPaths: ['./'],
|
||||||
|
readdirCalls: 1,
|
||||||
|
},
|
||||||
|
])(
|
||||||
|
'`getProjectPaths()`',
|
||||||
|
({ resultPaths, readdirCalls, fixturePath, skipPaths }) => {
|
||||||
|
const testName =
|
||||||
|
resultPaths.length > 0
|
||||||
|
? `should detect ${resultPaths.join()} project${
|
||||||
|
resultPaths.length > 1 ? 's' : ''
|
||||||
|
} for ${fixturePath}`
|
||||||
|
: `should not detect any path for ${fixturePath}`;
|
||||||
|
|
||||||
|
it(testName, async () => {
|
||||||
|
const fixture = path.join(
|
||||||
|
__dirname,
|
||||||
|
'non-deployed-fixtures',
|
||||||
|
fixturePath
|
||||||
|
);
|
||||||
|
const fs = new FixtureFilesystem(fixture);
|
||||||
|
const mockReaddir = jest.fn().mockImplementation(fs.readdir);
|
||||||
|
const mockHasPath = jest.fn().mockImplementation(fs.hasPath);
|
||||||
|
fs.readdir = mockReaddir;
|
||||||
|
fs.hasPath = mockHasPath;
|
||||||
|
const actualPaths = await getProjectPaths({ fs, skipPaths });
|
||||||
|
const normalizedPaths = actualPaths.map(path => normalizePath(path));
|
||||||
|
expect(normalizedPaths).toEqual(resultPaths);
|
||||||
|
expect(fs.readdir).toHaveBeenCalledTimes(readdirCalls);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "vercel",
|
"name": "vercel",
|
||||||
"version": "25.1.0",
|
"version": "25.1.1-canary.0",
|
||||||
"preferGlobal": true,
|
"preferGlobal": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"description": "The command-line interface for Vercel",
|
"description": "The command-line interface for Vercel",
|
||||||
@@ -42,15 +42,15 @@
|
|||||||
"node": ">= 14"
|
"node": ">= 14"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vercel/build-utils": "4.1.0",
|
"@vercel/build-utils": "4.1.1-canary.0",
|
||||||
"@vercel/go": "2.0.1",
|
"@vercel/go": "2.0.2-canary.0",
|
||||||
"@vercel/next": "3.0.1",
|
"@vercel/next": "3.0.2-canary.0",
|
||||||
"@vercel/node": "2.1.0",
|
"@vercel/node": "2.1.1-canary.0",
|
||||||
"@vercel/python": "3.0.1",
|
"@vercel/python": "3.0.2-canary.0",
|
||||||
"@vercel/redwood": "1.0.1",
|
"@vercel/redwood": "1.0.2-canary.0",
|
||||||
"@vercel/remix": "1.0.1",
|
"@vercel/remix": "1.0.2-canary.0",
|
||||||
"@vercel/ruby": "1.3.9",
|
"@vercel/ruby": "1.3.10-canary.0",
|
||||||
"@vercel/static-build": "1.0.1",
|
"@vercel/static-build": "1.0.2-canary.0",
|
||||||
"update-notifier": "5.1.0"
|
"update-notifier": "5.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@@ -94,7 +94,7 @@
|
|||||||
"@types/which": "1.3.2",
|
"@types/which": "1.3.2",
|
||||||
"@types/write-json-file": "2.2.1",
|
"@types/write-json-file": "2.2.1",
|
||||||
"@types/yauzl-promise": "2.1.0",
|
"@types/yauzl-promise": "2.1.0",
|
||||||
"@vercel/client": "12.0.1",
|
"@vercel/client": "12.0.2-canary.0",
|
||||||
"@vercel/frameworks": "1.0.1",
|
"@vercel/frameworks": "1.0.1",
|
||||||
"@vercel/ncc": "0.24.0",
|
"@vercel/ncc": "0.24.0",
|
||||||
"@zeit/fun": "0.11.2",
|
"@zeit/fun": "0.11.2",
|
||||||
|
|||||||
@@ -101,6 +101,7 @@ export default async function main(client: Client): Promise<number> {
|
|||||||
const argv = getArgs(client.argv.slice(2), {
|
const argv = getArgs(client.argv.slice(2), {
|
||||||
'--cwd': String,
|
'--cwd': String,
|
||||||
'--prod': Boolean,
|
'--prod': Boolean,
|
||||||
|
'--yes': Boolean,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (argv['--help']) {
|
if (argv['--help']) {
|
||||||
@@ -114,12 +115,18 @@ export default async function main(client: Client): Promise<number> {
|
|||||||
}
|
}
|
||||||
const cwd = process.cwd();
|
const cwd = process.cwd();
|
||||||
|
|
||||||
|
// Build `target` influences which environment variables will be used
|
||||||
|
const target = argv['--prod'] ? 'production' : 'preview';
|
||||||
|
const yes = Boolean(argv['--yes']);
|
||||||
|
|
||||||
// TODO: read project settings from the API, fall back to local `project.json` if that fails
|
// TODO: read project settings from the API, fall back to local `project.json` if that fails
|
||||||
|
|
||||||
// Read project settings, and pull them from Vercel if necessary
|
// Read project settings, and pull them from Vercel if necessary
|
||||||
let project = await readProjectSettings(join(cwd, VERCEL_DIR));
|
let project = await readProjectSettings(join(cwd, VERCEL_DIR));
|
||||||
const isTTY = process.stdin.isTTY;
|
const isTTY = process.stdin.isTTY;
|
||||||
while (!project?.settings) {
|
while (!project?.settings) {
|
||||||
|
let confirmed = yes;
|
||||||
|
if (!confirmed) {
|
||||||
if (!isTTY) {
|
if (!isTTY) {
|
||||||
client.output.print(
|
client.output.print(
|
||||||
`No Project Settings found locally. Run ${cli.getCommandName(
|
`No Project Settings found locally. Run ${cli.getCommandName(
|
||||||
@@ -129,27 +136,32 @@ export default async function main(client: Client): Promise<number> {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const confirmed = await confirm(
|
confirmed = await confirm(
|
||||||
`No Project Settings found locally. Run ${cli.getCommandName(
|
`No Project Settings found locally. Run ${cli.getCommandName(
|
||||||
'pull'
|
'pull'
|
||||||
)} for retrieving them?`,
|
)} for retrieving them?`,
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
}
|
||||||
if (!confirmed) {
|
if (!confirmed) {
|
||||||
client.output.print(`Aborted. No Project Settings retrieved.\n`);
|
client.output.print(`Aborted. No Project Settings retrieved.\n`);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
client.argv = [];
|
const { argv: originalArgv } = client;
|
||||||
|
client.argv = [
|
||||||
|
...originalArgv.slice(0, 2),
|
||||||
|
'pull',
|
||||||
|
`--environment`,
|
||||||
|
target,
|
||||||
|
];
|
||||||
const result = await pull(client);
|
const result = await pull(client);
|
||||||
if (result !== 0) {
|
if (result !== 0) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
client.argv = originalArgv;
|
||||||
project = await readProjectSettings(join(cwd, VERCEL_DIR));
|
project = await readProjectSettings(join(cwd, VERCEL_DIR));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build `target` influences which environment variables will be used
|
|
||||||
const target = argv['--prod'] ? 'production' : 'preview';
|
|
||||||
|
|
||||||
// TODO: load env vars from the API, fall back to local files if that fails
|
// TODO: load env vars from the API, fall back to local files if that fails
|
||||||
|
|
||||||
const envPath = await checkExists([
|
const envPath = await checkExists([
|
||||||
|
|||||||
7
packages/cli/test/fixtures/unit/commands/build/middleware/.vercel/project.json
vendored
Normal file
7
packages/cli/test/fixtures/unit/commands/build/middleware/.vercel/project.json
vendored
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"orgId": ".",
|
||||||
|
"projectId": ".",
|
||||||
|
"settings": {
|
||||||
|
"framework": null
|
||||||
|
}
|
||||||
|
}
|
||||||
1
packages/cli/test/fixtures/unit/commands/build/middleware/index.html
vendored
Normal file
1
packages/cli/test/fixtures/unit/commands/build/middleware/index.html
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<h1>Vercel</h1>
|
||||||
1
packages/cli/test/fixtures/unit/commands/build/middleware/middleware.js
vendored
Normal file
1
packages/cli/test/fixtures/unit/commands/build/middleware/middleware.js
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export default req => new Response('middleware');
|
||||||
4
packages/cli/test/fixtures/unit/commands/build/static-pull/.vercel/project.json
vendored
Normal file
4
packages/cli/test/fixtures/unit/commands/build/static-pull/.vercel/project.json
vendored
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"projectId": "vercel-pull-next",
|
||||||
|
"orgId": "team_dummy"
|
||||||
|
}
|
||||||
1
packages/cli/test/fixtures/unit/commands/build/static-pull/index.html
vendored
Normal file
1
packages/cli/test/fixtures/unit/commands/build/static-pull/index.html
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<h1>Vercel</h1>
|
||||||
@@ -1,8 +1,11 @@
|
|||||||
import ms from 'ms';
|
import ms from 'ms';
|
||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
import { client } from '../../mocks/client';
|
|
||||||
import build from '../../../src/commands/build';
|
import build from '../../../src/commands/build';
|
||||||
|
import { client } from '../../mocks/client';
|
||||||
|
import { defaultProject, useProject } from '../../mocks/project';
|
||||||
|
import { useTeams } from '../../mocks/team';
|
||||||
|
import { useUser } from '../../mocks/user';
|
||||||
|
|
||||||
jest.setTimeout(ms('1 minute'));
|
jest.setTimeout(ms('1 minute'));
|
||||||
|
|
||||||
@@ -139,7 +142,7 @@ describe('build', () => {
|
|||||||
require: '@vercel/static',
|
require: '@vercel/static',
|
||||||
apiVersion: 2,
|
apiVersion: 2,
|
||||||
use: '@vercel/static',
|
use: '@vercel/static',
|
||||||
src: '!{api/**,package.json}',
|
src: '!{api/**,package.json,middleware.[jt]s}',
|
||||||
config: {
|
config: {
|
||||||
zeroConfig: true,
|
zeroConfig: true,
|
||||||
},
|
},
|
||||||
@@ -204,7 +207,7 @@ describe('build', () => {
|
|||||||
require: '@vercel/static',
|
require: '@vercel/static',
|
||||||
apiVersion: 2,
|
apiVersion: 2,
|
||||||
use: '@vercel/static',
|
use: '@vercel/static',
|
||||||
src: '!{api/**,package.json}',
|
src: '!{api/**,package.json,middleware.[jt]s}',
|
||||||
config: {
|
config: {
|
||||||
zeroConfig: true,
|
zeroConfig: true,
|
||||||
},
|
},
|
||||||
@@ -237,4 +240,135 @@ describe('build', () => {
|
|||||||
delete process.env.__VERCEL_BUILD_RUNNING;
|
delete process.env.__VERCEL_BUILD_RUNNING;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should pull "preview" env vars by default', async () => {
|
||||||
|
const cwd = fixture('static-pull');
|
||||||
|
useUser();
|
||||||
|
useTeams('team_dummy');
|
||||||
|
useProject({
|
||||||
|
...defaultProject,
|
||||||
|
id: 'vercel-pull-next',
|
||||||
|
name: 'vercel-pull-next',
|
||||||
|
});
|
||||||
|
const envFilePath = join(cwd, '.vercel', '.env.preview.local');
|
||||||
|
const projectJsonPath = join(cwd, '.vercel', 'project.json');
|
||||||
|
const originalProjectJson = await fs.readJSON(
|
||||||
|
join(cwd, '.vercel/project.json')
|
||||||
|
);
|
||||||
|
try {
|
||||||
|
process.chdir(cwd);
|
||||||
|
client.setArgv('build', '--yes');
|
||||||
|
const exitCode = await build(client);
|
||||||
|
expect(exitCode).toEqual(0);
|
||||||
|
|
||||||
|
const previewEnv = await fs.readFile(envFilePath, 'utf8');
|
||||||
|
const envFileHasPreviewEnv = previewEnv.includes(
|
||||||
|
'REDIS_CONNECTION_STRING'
|
||||||
|
);
|
||||||
|
expect(envFileHasPreviewEnv).toBeTruthy();
|
||||||
|
} finally {
|
||||||
|
await fs.remove(envFilePath);
|
||||||
|
await fs.writeJSON(projectJsonPath, originalProjectJson, { spaces: 2 });
|
||||||
|
process.chdir(originalCwd);
|
||||||
|
delete process.env.__VERCEL_BUILD_RUNNING;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should pull "production" env vars with `--prod`', async () => {
|
||||||
|
const cwd = fixture('static-pull');
|
||||||
|
useUser();
|
||||||
|
useTeams('team_dummy');
|
||||||
|
useProject({
|
||||||
|
...defaultProject,
|
||||||
|
id: 'vercel-pull-next',
|
||||||
|
name: 'vercel-pull-next',
|
||||||
|
});
|
||||||
|
const envFilePath = join(cwd, '.vercel', '.env.production.local');
|
||||||
|
const projectJsonPath = join(cwd, '.vercel', 'project.json');
|
||||||
|
const originalProjectJson = await fs.readJSON(
|
||||||
|
join(cwd, '.vercel/project.json')
|
||||||
|
);
|
||||||
|
try {
|
||||||
|
process.chdir(cwd);
|
||||||
|
client.setArgv('build', '--yes', '--prod');
|
||||||
|
const exitCode = await build(client);
|
||||||
|
expect(exitCode).toEqual(0);
|
||||||
|
|
||||||
|
const prodEnv = await fs.readFile(envFilePath, 'utf8');
|
||||||
|
const envFileHasProductionEnv1 = prodEnv.includes(
|
||||||
|
'REDIS_CONNECTION_STRING'
|
||||||
|
);
|
||||||
|
expect(envFileHasProductionEnv1).toBeTruthy();
|
||||||
|
const envFileHasProductionEnv2 = prodEnv.includes(
|
||||||
|
'SQL_CONNECTION_STRING'
|
||||||
|
);
|
||||||
|
expect(envFileHasProductionEnv2).toBeTruthy();
|
||||||
|
} finally {
|
||||||
|
await fs.remove(envFilePath);
|
||||||
|
await fs.writeJSON(projectJsonPath, originalProjectJson, { spaces: 2 });
|
||||||
|
process.chdir(originalCwd);
|
||||||
|
delete process.env.__VERCEL_BUILD_RUNNING;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should build root-level `middleware.js` and exclude from static files', async () => {
|
||||||
|
const cwd = fixture('middleware');
|
||||||
|
const output = join(cwd, '.vercel/output');
|
||||||
|
try {
|
||||||
|
process.chdir(cwd);
|
||||||
|
const exitCode = await build(client);
|
||||||
|
expect(exitCode).toEqual(0);
|
||||||
|
|
||||||
|
// `builds.json` says that "@vercel/static" was run
|
||||||
|
const builds = await fs.readJSON(join(output, 'builds.json'));
|
||||||
|
expect(builds).toMatchObject({
|
||||||
|
target: 'preview',
|
||||||
|
builds: [
|
||||||
|
{
|
||||||
|
require: '@vercel/node',
|
||||||
|
apiVersion: 3,
|
||||||
|
use: '@vercel/node',
|
||||||
|
src: 'middleware.js',
|
||||||
|
config: {
|
||||||
|
zeroConfig: true,
|
||||||
|
middleware: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
require: '@vercel/static',
|
||||||
|
apiVersion: 2,
|
||||||
|
use: '@vercel/static',
|
||||||
|
src: '!{api/**,package.json,middleware.[jt]s}',
|
||||||
|
config: {
|
||||||
|
zeroConfig: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
// `config.json` includes the "middlewarePath" route
|
||||||
|
const config = await fs.readJSON(join(output, 'config.json'));
|
||||||
|
expect(config).toMatchObject({
|
||||||
|
version: 3,
|
||||||
|
routes: [
|
||||||
|
{ src: '/.*', middlewarePath: 'middleware', continue: true },
|
||||||
|
{ handle: 'filesystem' },
|
||||||
|
{ src: '^/api(/.*)?$', status: 404 },
|
||||||
|
{ handle: 'error' },
|
||||||
|
{ status: 404, src: '^(?!/api).*$', dest: '/404.html' },
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
// "static" directory contains `index.html`, but *not* `middleware.js`
|
||||||
|
const staticFiles = await fs.readdir(join(output, 'static'));
|
||||||
|
expect(staticFiles.sort()).toEqual(['index.html']);
|
||||||
|
|
||||||
|
// "functions" directory contains `middleware.func`
|
||||||
|
const functions = await fs.readdir(join(output, 'functions'));
|
||||||
|
expect(functions.sort()).toEqual(['middleware.func']);
|
||||||
|
} finally {
|
||||||
|
process.chdir(originalCwd);
|
||||||
|
delete process.env.__VERCEL_BUILD_RUNNING;
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vercel/client",
|
"name": "@vercel/client",
|
||||||
"version": "12.0.1",
|
"version": "12.0.2-canary.0",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"typings": "dist/index.d.ts",
|
"typings": "dist/index.d.ts",
|
||||||
"homepage": "https://vercel.com",
|
"homepage": "https://vercel.com",
|
||||||
@@ -42,7 +42,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vercel/build-utils": "4.1.0",
|
"@vercel/build-utils": "4.1.1-canary.0",
|
||||||
"@zeit/fetch": "5.2.0",
|
"@zeit/fetch": "5.2.0",
|
||||||
"async-retry": "1.2.3",
|
"async-retry": "1.2.3",
|
||||||
"async-sema": "3.0.0",
|
"async-sema": "3.0.0",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vercel/go",
|
"name": "@vercel/go",
|
||||||
"version": "2.0.1",
|
"version": "2.0.2-canary.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"main": "./dist/index",
|
"main": "./dist/index",
|
||||||
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/go",
|
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/go",
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
"@types/fs-extra": "^5.0.5",
|
"@types/fs-extra": "^5.0.5",
|
||||||
"@types/node-fetch": "^2.3.0",
|
"@types/node-fetch": "^2.3.0",
|
||||||
"@types/tar": "^4.0.0",
|
"@types/tar": "^4.0.0",
|
||||||
"@vercel/build-utils": "4.1.0",
|
"@vercel/build-utils": "4.1.1-canary.0",
|
||||||
"@vercel/ncc": "0.24.0",
|
"@vercel/ncc": "0.24.0",
|
||||||
"async-retry": "1.3.1",
|
"async-retry": "1.3.1",
|
||||||
"execa": "^1.0.0",
|
"execa": "^1.0.0",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vercel/next",
|
"name": "@vercel/next",
|
||||||
"version": "3.0.1",
|
"version": "3.0.2-canary.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"main": "./dist/index",
|
"main": "./dist/index",
|
||||||
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/next-js",
|
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/next-js",
|
||||||
@@ -45,7 +45,7 @@
|
|||||||
"@types/semver": "6.0.0",
|
"@types/semver": "6.0.0",
|
||||||
"@types/text-table": "0.2.1",
|
"@types/text-table": "0.2.1",
|
||||||
"@types/webpack-sources": "3.2.0",
|
"@types/webpack-sources": "3.2.0",
|
||||||
"@vercel/build-utils": "4.1.0",
|
"@vercel/build-utils": "4.1.1-canary.0",
|
||||||
"@vercel/nft": "0.19.1",
|
"@vercel/nft": "0.19.1",
|
||||||
"@vercel/routing-utils": "1.13.4",
|
"@vercel/routing-utils": "1.13.4",
|
||||||
"async-sema": "3.0.1",
|
"async-sema": "3.0.1",
|
||||||
|
|||||||
@@ -1294,6 +1294,7 @@ export const build: BuildV2 = async ({
|
|||||||
entryPath,
|
entryPath,
|
||||||
baseDir,
|
baseDir,
|
||||||
dataRoutes,
|
dataRoutes,
|
||||||
|
buildId,
|
||||||
escapedBuildId,
|
escapedBuildId,
|
||||||
outputDirectory,
|
outputDirectory,
|
||||||
trailingSlashRedirects,
|
trailingSlashRedirects,
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ import prettyBytes from 'pretty-bytes';
|
|||||||
// related PR: https://github.com/vercel/next.js/pull/30046
|
// related PR: https://github.com/vercel/next.js/pull/30046
|
||||||
const CORRECT_NOT_FOUND_ROUTES_VERSION = 'v12.0.1';
|
const CORRECT_NOT_FOUND_ROUTES_VERSION = 'v12.0.1';
|
||||||
const CORRECT_MIDDLEWARE_ORDER_VERSION = 'v12.1.7-canary.29';
|
const CORRECT_MIDDLEWARE_ORDER_VERSION = 'v12.1.7-canary.29';
|
||||||
|
const NEXT_DATA_MIDDLEWARE_RESOLVING_VERSION = 'v12.1.7-canary.33';
|
||||||
|
|
||||||
export async function serverBuild({
|
export async function serverBuild({
|
||||||
dynamicPages,
|
dynamicPages,
|
||||||
@@ -65,6 +66,7 @@ export async function serverBuild({
|
|||||||
workPath,
|
workPath,
|
||||||
entryPath,
|
entryPath,
|
||||||
nodeVersion,
|
nodeVersion,
|
||||||
|
buildId,
|
||||||
escapedBuildId,
|
escapedBuildId,
|
||||||
dynamicPrefix,
|
dynamicPrefix,
|
||||||
entryDirectory,
|
entryDirectory,
|
||||||
@@ -101,6 +103,7 @@ export async function serverBuild({
|
|||||||
privateOutputs: { files: Files; routes: Route[] };
|
privateOutputs: { files: Files; routes: Route[] };
|
||||||
entryPath: string;
|
entryPath: string;
|
||||||
dynamicPrefix: string;
|
dynamicPrefix: string;
|
||||||
|
buildId: string;
|
||||||
escapedBuildId: string;
|
escapedBuildId: string;
|
||||||
wildcardConfig: BuildResult['wildcard'];
|
wildcardConfig: BuildResult['wildcard'];
|
||||||
nodeVersion: NodeVersion;
|
nodeVersion: NodeVersion;
|
||||||
@@ -796,6 +799,10 @@ export async function serverBuild({
|
|||||||
isCorrectMiddlewareOrder,
|
isCorrectMiddlewareOrder,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const isNextDataServerResolving =
|
||||||
|
middleware.staticRoutes.length > 0 &&
|
||||||
|
semver.gte(nextVersion, NEXT_DATA_MIDDLEWARE_RESOLVING_VERSION);
|
||||||
|
|
||||||
const dynamicRoutes = await getDynamicRoutes(
|
const dynamicRoutes = await getDynamicRoutes(
|
||||||
entryPath,
|
entryPath,
|
||||||
entryDirectory,
|
entryDirectory,
|
||||||
@@ -876,6 +883,53 @@ export async function serverBuild({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const normalizeNextDataRoute = isNextDataServerResolving
|
||||||
|
? [
|
||||||
|
// strip _next/data prefix for resolving
|
||||||
|
{
|
||||||
|
src: `^${path.join(
|
||||||
|
'/',
|
||||||
|
entryDirectory,
|
||||||
|
'/_next/data/',
|
||||||
|
escapedBuildId,
|
||||||
|
'/(.*).json'
|
||||||
|
)}`,
|
||||||
|
dest: `${path.join('/', entryDirectory, '/$1')}`,
|
||||||
|
continue: true,
|
||||||
|
override: true,
|
||||||
|
has: [
|
||||||
|
{
|
||||||
|
type: 'header',
|
||||||
|
key: 'x-nextjs-data',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: [];
|
||||||
|
|
||||||
|
const denormalizeNextDataRoute = isNextDataServerResolving
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
src: '/(.*)',
|
||||||
|
has: [
|
||||||
|
{
|
||||||
|
type: 'header',
|
||||||
|
key: 'x-nextjs-data',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
dest: `${path.join(
|
||||||
|
'/',
|
||||||
|
entryDirectory,
|
||||||
|
'/_next/data/',
|
||||||
|
buildId,
|
||||||
|
'/$1.json'
|
||||||
|
)}`,
|
||||||
|
continue: true,
|
||||||
|
override: true,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: [];
|
||||||
|
|
||||||
return {
|
return {
|
||||||
wildcard: wildcardConfig,
|
wildcard: wildcardConfig,
|
||||||
images:
|
images:
|
||||||
@@ -900,6 +954,15 @@ export async function serverBuild({
|
|||||||
...staticDirectoryFiles,
|
...staticDirectoryFiles,
|
||||||
...privateOutputs.files,
|
...privateOutputs.files,
|
||||||
...middleware.edgeFunctions,
|
...middleware.edgeFunctions,
|
||||||
|
...(isNextDataServerResolving
|
||||||
|
? {
|
||||||
|
__next_data_catchall: new FileBlob({
|
||||||
|
contentType: 'application/json',
|
||||||
|
mode: 0o644,
|
||||||
|
data: '{}',
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
: {}),
|
||||||
},
|
},
|
||||||
routes: [
|
routes: [
|
||||||
/*
|
/*
|
||||||
@@ -919,6 +982,9 @@ export async function serverBuild({
|
|||||||
|
|
||||||
...privateOutputs.routes,
|
...privateOutputs.routes,
|
||||||
|
|
||||||
|
// normalize _next/data URL before processing redirects
|
||||||
|
...normalizeNextDataRoute,
|
||||||
|
|
||||||
...(i18n
|
...(i18n
|
||||||
? [
|
? [
|
||||||
// Handle auto-adding current default locale to path based on
|
// Handle auto-adding current default locale to path based on
|
||||||
@@ -1077,6 +1143,9 @@ export async function serverBuild({
|
|||||||
},
|
},
|
||||||
]),
|
]),
|
||||||
|
|
||||||
|
// we need to undo _next/data normalize before checking filesystem
|
||||||
|
...denormalizeNextDataRoute,
|
||||||
|
|
||||||
// while middleware was in beta the order came right before
|
// while middleware was in beta the order came right before
|
||||||
// handle: 'filesystem' we maintain this for older versions
|
// handle: 'filesystem' we maintain this for older versions
|
||||||
// to prevent a local/deploy mismatch
|
// to prevent a local/deploy mismatch
|
||||||
@@ -1098,6 +1167,11 @@ export async function serverBuild({
|
|||||||
]
|
]
|
||||||
: []),
|
: []),
|
||||||
|
|
||||||
|
// normalize _next/data URL before processing rewrites
|
||||||
|
...normalizeNextDataRoute,
|
||||||
|
|
||||||
|
...(!isNextDataServerResolving
|
||||||
|
? [
|
||||||
// No-op _next/data rewrite to trigger handle: 'rewrites' and then 404
|
// No-op _next/data rewrite to trigger handle: 'rewrites' and then 404
|
||||||
// if no match to prevent rewriting _next/data unexpectedly
|
// if no match to prevent rewriting _next/data unexpectedly
|
||||||
{
|
{
|
||||||
@@ -1105,6 +1179,8 @@ export async function serverBuild({
|
|||||||
dest: path.join('/', entryDirectory, '_next/data/$1'),
|
dest: path.join('/', entryDirectory, '_next/data/$1'),
|
||||||
check: true,
|
check: true,
|
||||||
},
|
},
|
||||||
|
]
|
||||||
|
: []),
|
||||||
|
|
||||||
// These need to come before handle: miss or else they are grouped
|
// These need to come before handle: miss or else they are grouped
|
||||||
// with that routing section
|
// with that routing section
|
||||||
@@ -1163,9 +1239,14 @@ export async function serverBuild({
|
|||||||
// if there no rewrites
|
// if there no rewrites
|
||||||
{ handle: 'rewrite' },
|
{ handle: 'rewrite' },
|
||||||
|
|
||||||
|
// re-build /_next/data URL after resolving
|
||||||
|
...denormalizeNextDataRoute,
|
||||||
|
|
||||||
// /_next/data routes for getServerProps/getStaticProps pages
|
// /_next/data routes for getServerProps/getStaticProps pages
|
||||||
...dataRoutes,
|
...dataRoutes,
|
||||||
|
|
||||||
|
...(!isNextDataServerResolving
|
||||||
|
? [
|
||||||
// ensure we 404 for non-existent _next/data routes before
|
// ensure we 404 for non-existent _next/data routes before
|
||||||
// trying page dynamic routes
|
// trying page dynamic routes
|
||||||
{
|
{
|
||||||
@@ -1173,11 +1254,30 @@ export async function serverBuild({
|
|||||||
dest: path.join('/', entryDirectory, '404'),
|
dest: path.join('/', entryDirectory, '404'),
|
||||||
status: 404,
|
status: 404,
|
||||||
},
|
},
|
||||||
|
]
|
||||||
|
: []),
|
||||||
|
|
||||||
// Dynamic routes (must come after dataRoutes as dataRoutes are more
|
// Dynamic routes (must come after dataRoutes as dataRoutes are more
|
||||||
// specific)
|
// specific)
|
||||||
...dynamicRoutes,
|
...dynamicRoutes,
|
||||||
|
|
||||||
|
...(isNextDataServerResolving
|
||||||
|
? [
|
||||||
|
// add a catch-all data route so we don't 404 when getting
|
||||||
|
// middleware effects
|
||||||
|
{
|
||||||
|
src: `^${path.join(
|
||||||
|
'/',
|
||||||
|
entryDirectory,
|
||||||
|
'/_next/data/',
|
||||||
|
escapedBuildId,
|
||||||
|
'/(.*).json'
|
||||||
|
)}`,
|
||||||
|
dest: '__next_data_catchall',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: []),
|
||||||
|
|
||||||
// routes to call after a file has been matched
|
// routes to call after a file has been matched
|
||||||
{ handle: 'hit' },
|
{ handle: 'hit' },
|
||||||
// Before we handle static files we need to set proper caching headers
|
// Before we handle static files we need to set proper caching headers
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vercel/node",
|
"name": "@vercel/node",
|
||||||
"version": "2.1.0",
|
"version": "2.1.1-canary.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"main": "./dist/index",
|
"main": "./dist/index",
|
||||||
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/node-js",
|
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/node-js",
|
||||||
@@ -45,7 +45,7 @@
|
|||||||
"@types/etag": "1.8.0",
|
"@types/etag": "1.8.0",
|
||||||
"@types/jest": "27.4.1",
|
"@types/jest": "27.4.1",
|
||||||
"@types/test-listen": "1.1.0",
|
"@types/test-listen": "1.1.0",
|
||||||
"@vercel/build-utils": "4.1.0",
|
"@vercel/build-utils": "4.1.1-canary.0",
|
||||||
"@vercel/ncc": "0.24.0",
|
"@vercel/ncc": "0.24.0",
|
||||||
"@vercel/nft": "0.19.1",
|
"@vercel/nft": "0.19.1",
|
||||||
"@vercel/static-config": "2.0.1",
|
"@vercel/static-config": "2.0.1",
|
||||||
|
|||||||
@@ -373,12 +373,38 @@ export const build: BuildV3 = async ({
|
|||||||
);
|
);
|
||||||
debug(`Trace complete [${Date.now() - traceTime}ms]`);
|
debug(`Trace complete [${Date.now() - traceTime}ms]`);
|
||||||
|
|
||||||
|
let routes: BuildResultV3['routes'];
|
||||||
|
let output: BuildResultV3['output'] | undefined;
|
||||||
|
|
||||||
|
const handler = renameTStoJS(relative(baseDir, entrypointPath));
|
||||||
|
const outputName = config.zeroConfig
|
||||||
|
? handler.substring(0, handler.length - 3)
|
||||||
|
: handler;
|
||||||
|
|
||||||
|
// Will output an `EdgeFunction` for when `config.middleware = true`
|
||||||
|
// (i.e. for root-level "middleware" file) or if source code contains:
|
||||||
|
// `export const config = { runtime: 'experimental-edge' }`
|
||||||
|
let isEdgeFunction = false;
|
||||||
|
|
||||||
|
// Add a catch-all `route` for Middleware
|
||||||
|
if (config.middleware === true) {
|
||||||
|
routes = [
|
||||||
|
{
|
||||||
|
src: '/.*',
|
||||||
|
middlewarePath: config.zeroConfig
|
||||||
|
? outputName
|
||||||
|
: relative(baseDir, entrypointPath),
|
||||||
|
continue: true,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
// Middleware is implicitly an Edge Function
|
||||||
|
isEdgeFunction = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isEdgeFunction) {
|
||||||
const project = new Project();
|
const project = new Project();
|
||||||
const staticConfig = getConfig(project, entrypointPath);
|
const staticConfig = getConfig(project, entrypointPath);
|
||||||
|
|
||||||
let output: BuildResultV3['output'] | undefined;
|
|
||||||
const handler = renameTStoJS(relative(baseDir, entrypointPath));
|
|
||||||
|
|
||||||
if (staticConfig?.runtime) {
|
if (staticConfig?.runtime) {
|
||||||
if (!ALLOWED_RUNTIMES.includes(staticConfig.runtime)) {
|
if (!ALLOWED_RUNTIMES.includes(staticConfig.runtime)) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
@@ -387,22 +413,20 @@ export const build: BuildV3 = async ({
|
|||||||
)} (must be one of: ${JSON.stringify(ALLOWED_RUNTIMES)})`
|
)} (must be one of: ${JSON.stringify(ALLOWED_RUNTIMES)})`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (staticConfig.runtime === 'experimental-edge') {
|
isEdgeFunction = staticConfig.runtime === 'experimental-edge';
|
||||||
const name = config.zeroConfig
|
}
|
||||||
? handler.substring(0, handler.length - 3)
|
}
|
||||||
: handler;
|
|
||||||
|
if (isEdgeFunction) {
|
||||||
output = new EdgeFunction({
|
output = new EdgeFunction({
|
||||||
entrypoint: handler,
|
entrypoint: handler,
|
||||||
files: preparedFiles,
|
files: preparedFiles,
|
||||||
|
|
||||||
// TODO: remove - these two properties should not be required
|
// TODO: remove - these two properties should not be required
|
||||||
name,
|
name: outputName,
|
||||||
deploymentTarget: 'v8-worker',
|
deploymentTarget: 'v8-worker',
|
||||||
});
|
});
|
||||||
}
|
} else {
|
||||||
}
|
|
||||||
|
|
||||||
if (!output) {
|
|
||||||
// "nodejs" runtime is the default
|
// "nodejs" runtime is the default
|
||||||
const shouldAddHelpers = !(
|
const shouldAddHelpers = !(
|
||||||
config.helpers === false || process.env.NODEJS_HELPERS === '0'
|
config.helpers === false || process.env.NODEJS_HELPERS === '0'
|
||||||
@@ -418,7 +442,7 @@ export const build: BuildV3 = async ({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return { output };
|
return { routes, output };
|
||||||
};
|
};
|
||||||
|
|
||||||
export const prepareCache: PrepareCache = ({ repoRootPath, workPath }) => {
|
export const prepareCache: PrepareCache = ({ repoRootPath, workPath }) => {
|
||||||
|
|||||||
7
packages/node/test/fixtures/62-edge-middleware/api/edge.js
vendored
Normal file
7
packages/node/test/fixtures/62-edge-middleware/api/edge.js
vendored
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
export const config = {
|
||||||
|
runtime: 'experimental-edge',
|
||||||
|
};
|
||||||
|
|
||||||
|
export default req => {
|
||||||
|
return new Response(`RANDOMNESS_PLACEHOLDER:edge`);
|
||||||
|
};
|
||||||
14
packages/node/test/fixtures/62-edge-middleware/middleware.ts
vendored
Normal file
14
packages/node/test/fixtures/62-edge-middleware/middleware.ts
vendored
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
export default (req: Request) => {
|
||||||
|
const url = new URL(req.url);
|
||||||
|
const headers = new Headers({
|
||||||
|
'x-got-middleware': 'true',
|
||||||
|
});
|
||||||
|
if (url.pathname === '/' || url.pathname.startsWith('/api/')) {
|
||||||
|
// For `index.html` and `/api/edge.js`, pass through
|
||||||
|
headers.set('x-middleware-next', '1');
|
||||||
|
return new Response(null, { headers });
|
||||||
|
} else {
|
||||||
|
// For everything else, serve a custom response
|
||||||
|
return new Response(`RANDOMNESS_PLACEHOLDER:middleware`, { headers });
|
||||||
|
}
|
||||||
|
};
|
||||||
26
packages/node/test/fixtures/62-edge-middleware/vercel.json
vendored
Normal file
26
packages/node/test/fixtures/62-edge-middleware/vercel.json
vendored
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"builds": [
|
||||||
|
{ "src": "api/**/*.js", "use": "@vercel/node" },
|
||||||
|
{
|
||||||
|
"src": "middleware.ts",
|
||||||
|
"use": "@vercel/node",
|
||||||
|
"config": { "middleware": true }
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"probes": [
|
||||||
|
{
|
||||||
|
"path": "/api/edge.js",
|
||||||
|
"mustContain": "RANDOMNESS_PLACEHOLDER:edge",
|
||||||
|
"responseHeaders": {
|
||||||
|
"x-got-middleware": "true"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "/non-exist",
|
||||||
|
"mustContain": "RANDOMNESS_PLACEHOLDER:middleware",
|
||||||
|
"responseHeaders": {
|
||||||
|
"x-got-middleware": "true"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vercel/python",
|
"name": "@vercel/python",
|
||||||
"version": "3.0.1",
|
"version": "3.0.2-canary.0",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/python",
|
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/python",
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/execa": "^0.9.0",
|
"@types/execa": "^0.9.0",
|
||||||
"@types/jest": "27.4.1",
|
"@types/jest": "27.4.1",
|
||||||
"@vercel/build-utils": "4.1.0",
|
"@vercel/build-utils": "4.1.1-canary.0",
|
||||||
"@vercel/ncc": "0.24.0",
|
"@vercel/ncc": "0.24.0",
|
||||||
"execa": "^1.0.0",
|
"execa": "^1.0.0",
|
||||||
"typescript": "4.3.4"
|
"typescript": "4.3.4"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vercel/redwood",
|
"name": "@vercel/redwood",
|
||||||
"version": "1.0.1",
|
"version": "1.0.2-canary.0",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"homepage": "https://vercel.com/docs",
|
"homepage": "https://vercel.com/docs",
|
||||||
@@ -28,6 +28,6 @@
|
|||||||
"@types/aws-lambda": "8.10.19",
|
"@types/aws-lambda": "8.10.19",
|
||||||
"@types/node": "*",
|
"@types/node": "*",
|
||||||
"@types/semver": "6.0.0",
|
"@types/semver": "6.0.0",
|
||||||
"@vercel/build-utils": "4.1.0"
|
"@vercel/build-utils": "4.1.1-canary.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vercel/remix",
|
"name": "@vercel/remix",
|
||||||
"version": "1.0.1",
|
"version": "1.0.2-canary.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"homepage": "https://vercel.com/docs",
|
"homepage": "https://vercel.com/docs",
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/jest": "27.5.1",
|
"@types/jest": "27.5.1",
|
||||||
"@types/node": "*",
|
"@types/node": "*",
|
||||||
"@vercel/build-utils": "4.1.0",
|
"@vercel/build-utils": "4.1.1-canary.0",
|
||||||
"typescript": "4.6.4"
|
"typescript": "4.6.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@vercel/ruby",
|
"name": "@vercel/ruby",
|
||||||
"author": "Nathan Cahill <nathan@nathancahill.com>",
|
"author": "Nathan Cahill <nathan@nathancahill.com>",
|
||||||
"version": "1.3.9",
|
"version": "1.3.10-canary.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"main": "./dist/index",
|
"main": "./dist/index",
|
||||||
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/ruby",
|
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/ruby",
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/fs-extra": "8.0.0",
|
"@types/fs-extra": "8.0.0",
|
||||||
"@types/semver": "6.0.0",
|
"@types/semver": "6.0.0",
|
||||||
"@vercel/build-utils": "4.1.0",
|
"@vercel/build-utils": "4.1.1-canary.0",
|
||||||
"@vercel/ncc": "0.24.0",
|
"@vercel/ncc": "0.24.0",
|
||||||
"execa": "2.0.4",
|
"execa": "2.0.4",
|
||||||
"fs-extra": "^7.0.1",
|
"fs-extra": "^7.0.1",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vercel/static-build",
|
"name": "@vercel/static-build",
|
||||||
"version": "1.0.1",
|
"version": "1.0.2-canary.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"main": "./dist/index",
|
"main": "./dist/index",
|
||||||
"homepage": "https://vercel.com/docs/build-step",
|
"homepage": "https://vercel.com/docs/build-step",
|
||||||
@@ -37,7 +37,7 @@
|
|||||||
"@types/ms": "0.7.31",
|
"@types/ms": "0.7.31",
|
||||||
"@types/node-fetch": "2.5.4",
|
"@types/node-fetch": "2.5.4",
|
||||||
"@types/promise-timeout": "1.3.0",
|
"@types/promise-timeout": "1.3.0",
|
||||||
"@vercel/build-utils": "4.1.0",
|
"@vercel/build-utils": "4.1.1-canary.0",
|
||||||
"@vercel/frameworks": "1.0.1",
|
"@vercel/frameworks": "1.0.1",
|
||||||
"@vercel/ncc": "0.24.0",
|
"@vercel/ncc": "0.24.0",
|
||||||
"@vercel/routing-utils": "1.13.4",
|
"@vercel/routing-utils": "1.13.4",
|
||||||
|
|||||||
Reference in New Issue
Block a user