Compare commits

...

4 Commits

Author SHA1 Message Date
Steven
7bd338618c Publish Canary
- @vercel/build-utils@2.12.3-canary.23
 - vercel@23.1.3-canary.41
 - @vercel/client@10.2.3-canary.24
 - vercel-plugin-go@1.0.0-canary.8
 - vercel-plugin-node@1.12.2-canary.14
 - vercel-plugin-python@1.0.0-canary.9
 - vercel-plugin-ruby@1.0.0-canary.7
2021-11-24 22:03:54 -05:00
Steven
9048a6f584 [build-utils] Fix zero config routes for vercel build (#7063) 2021-11-24 22:00:49 -05:00
Steven
0cacb1bdac Publish Canary
- @vercel/build-utils@2.12.3-canary.22
 - vercel@23.1.3-canary.40
 - @vercel/client@10.2.3-canary.23
 - vercel-plugin-go@1.0.0-canary.7
 - vercel-plugin-node@1.12.2-canary.13
 - vercel-plugin-python@1.0.0-canary.8
 - vercel-plugin-ruby@1.0.0-canary.6
2021-11-24 18:12:26 -05:00
Steven
318bf35f82 [build-utils] Add support for writing routes-manifest.json (#7062)
* [build-utils] Add support for writing routes-manifest.json

* Add support for dynamicRoutes

* Add another test with multiple named params
2021-11-24 18:00:12 -05:00
22 changed files with 267 additions and 37 deletions

View File

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

View File

@@ -21,7 +21,10 @@ export function convertRuntimeToPlugin(
vercelConfig, vercelConfig,
workPath, workPath,
}: { }: {
vercelConfig: { functions?: BuilderFunctions; regions?: string[] }; vercelConfig: {
functions?: BuilderFunctions;
regions?: string[];
};
workPath: string; workPath: string;
}) { }) {
const opts = { cwd: workPath }; const opts = { cwd: workPath };
@@ -58,7 +61,7 @@ export function convertRuntimeToPlugin(
maxDuration: output.maxDuration, maxDuration: output.maxDuration,
environment: output.environment, environment: output.environment,
allowQuery: output.allowQuery, allowQuery: output.allowQuery,
regions: output.regions, //regions: output.regions,
}; };
// @ts-ignore This symbol is a private API // @ts-ignore This symbol is a private API
@@ -172,32 +175,81 @@ export async function updateFunctionsManifest({
} }
/** /**
* Will append routes to the `routes-manifest.json` file. * Append routes to the `routes-manifest.json` file.
* If the file does not exist, it'll be created. * If the file does not exist, it will be created.
*/ */
export async function updateRoutesManifest({ export async function updateRoutesManifest({
workPath, workPath,
redirects,
rewrites,
headers,
dynamicRoutes, dynamicRoutes,
staticRoutes,
}: { }: {
workPath: string; workPath: string;
redirects?: {
source: string;
destination: string;
statusCode: number;
regex: string;
}[];
rewrites?: {
source: string;
destination: string;
regex: string;
}[];
headers?: {
source: string;
headers: {
key: string;
value: string;
}[];
regex: string;
}[];
dynamicRoutes?: { dynamicRoutes?: {
page: string; page: string;
regex: string; regex: string;
namedRegex?: string; namedRegex?: string;
routeKeys?: { [named: string]: string }; routeKeys?: { [named: string]: string };
}[]; }[];
staticRoutes?: {
page: string;
regex: string;
namedRegex?: string;
routeKeys?: { [named: string]: string };
}[];
}) { }) {
const routesManifestPath = join(workPath, '.output', 'routes-manifest.json'); const routesManifestPath = join(workPath, '.output', 'routes-manifest.json');
const routesManifest = await readJson(routesManifestPath); const routesManifest = await readJson(routesManifestPath);
if (!routesManifest.version) routesManifest.version = 1; if (!routesManifest.version) routesManifest.version = 3;
if (routesManifest.pages404 === undefined) routesManifest.pages404 = true; if (routesManifest.pages404 === undefined) routesManifest.pages404 = true;
if (redirects) {
if (!routesManifest.redirects) routesManifest.redirects = [];
routesManifest.redirects.push(...redirects);
}
if (rewrites) {
if (!routesManifest.rewrites) routesManifest.rewrites = [];
routesManifest.rewrites.push(...rewrites);
}
if (headers) {
if (!routesManifest.headers) routesManifest.headers = [];
routesManifest.headers.push(...headers);
}
if (dynamicRoutes) { if (dynamicRoutes) {
if (!routesManifest.dynamicRoutes) routesManifest.dynamicRoutes = []; if (!routesManifest.dynamicRoutes) routesManifest.dynamicRoutes = [];
routesManifest.dynamicRoutes.push(...dynamicRoutes); routesManifest.dynamicRoutes.push(...dynamicRoutes);
} }
if (staticRoutes) {
if (!routesManifest.staticRoutes) routesManifest.staticRoutes = [];
routesManifest.staticRoutes.push(...staticRoutes);
}
await fs.writeFile(routesManifestPath, JSON.stringify(routesManifest)); await fs.writeFile(routesManifestPath, JSON.stringify(routesManifest));
} }

View File

@@ -96,6 +96,7 @@ export async function detectBuilders(
redirectRoutes: Route[] | null; redirectRoutes: Route[] | null;
rewriteRoutes: Route[] | null; rewriteRoutes: Route[] | null;
errorRoutes: Route[] | null; errorRoutes: Route[] | null;
limitedRoutes: LimitedRoutes | null;
}> { }> {
const errors: ErrorResponse[] = []; const errors: ErrorResponse[] = [];
const warnings: ErrorResponse[] = []; const warnings: ErrorResponse[] = [];
@@ -114,6 +115,7 @@ export async function detectBuilders(
redirectRoutes: null, redirectRoutes: null,
rewriteRoutes: null, rewriteRoutes: null,
errorRoutes: null, errorRoutes: null,
limitedRoutes: null,
}; };
} }
@@ -179,6 +181,7 @@ export async function detectBuilders(
redirectRoutes: null, redirectRoutes: null,
rewriteRoutes: null, rewriteRoutes: null,
errorRoutes: null, errorRoutes: null,
limitedRoutes: null,
}; };
} }
@@ -257,6 +260,7 @@ export async function detectBuilders(
defaultRoutes: null, defaultRoutes: null,
rewriteRoutes: null, rewriteRoutes: null,
errorRoutes: null, errorRoutes: null,
limitedRoutes: null,
}; };
} }
@@ -299,6 +303,7 @@ export async function detectBuilders(
defaultRoutes: null, defaultRoutes: null,
rewriteRoutes: null, rewriteRoutes: null,
errorRoutes: null, errorRoutes: null,
limitedRoutes: null,
}; };
} }
@@ -326,6 +331,7 @@ export async function detectBuilders(
} }
const routesResult = getRouteResult( const routesResult = getRouteResult(
pkg,
apiRoutes, apiRoutes,
dynamicRoutes, dynamicRoutes,
usedOutputDirectory, usedOutputDirectory,
@@ -342,6 +348,7 @@ export async function detectBuilders(
defaultRoutes: routesResult.defaultRoutes, defaultRoutes: routesResult.defaultRoutes,
rewriteRoutes: routesResult.rewriteRoutes, rewriteRoutes: routesResult.rewriteRoutes,
errorRoutes: routesResult.errorRoutes, errorRoutes: routesResult.errorRoutes,
limitedRoutes: routesResult.limitedRoutes,
}; };
} }
@@ -932,7 +939,14 @@ function createRouteFromPath(
return { route, isDynamic }; return { route, isDynamic };
} }
interface LimitedRoutes {
defaultRoutes: Route[];
redirectRoutes: Route[];
rewriteRoutes: Route[];
}
function getRouteResult( function getRouteResult(
pkg: PackageJson | undefined | null,
apiRoutes: Source[], apiRoutes: Source[],
dynamicRoutes: Source[], dynamicRoutes: Source[],
outputDirectory: string, outputDirectory: string,
@@ -944,11 +958,18 @@ function getRouteResult(
redirectRoutes: Route[]; redirectRoutes: Route[];
rewriteRoutes: Route[]; rewriteRoutes: Route[];
errorRoutes: Route[]; errorRoutes: Route[];
limitedRoutes: LimitedRoutes;
} { } {
const deps = Object.assign({}, pkg?.dependencies, pkg?.devDependencies);
const defaultRoutes: Route[] = []; const defaultRoutes: Route[] = [];
const redirectRoutes: Route[] = []; const redirectRoutes: Route[] = [];
const rewriteRoutes: Route[] = []; const rewriteRoutes: Route[] = [];
const errorRoutes: Route[] = []; const errorRoutes: Route[] = [];
const limitedRoutes: LimitedRoutes = {
defaultRoutes: [],
redirectRoutes: [],
rewriteRoutes: [],
};
const framework = frontendBuilder?.config?.framework || ''; const framework = frontendBuilder?.config?.framework || '';
const isNextjs = const isNextjs =
framework === 'nextjs' || isOfficialRuntime('next', frontendBuilder?.use); framework === 'nextjs' || isOfficialRuntime('next', frontendBuilder?.use);
@@ -956,14 +977,43 @@ function getRouteResult(
if (apiRoutes && apiRoutes.length > 0) { if (apiRoutes && apiRoutes.length > 0) {
if (options.featHandleMiss) { if (options.featHandleMiss) {
// Exclude extension names if the corresponding plugin is not found in package.json
// detectBuilders({ignoreRoutesForBuilders: ['@vercel/python']})
// return a copy of routes.
// We should exclud errorRoutes and
const extSet = detectApiExtensions(apiBuilders); const extSet = detectApiExtensions(apiBuilders);
const withTag = options.tag ? `@${options.tag}` : '';
const extSetLimited = detectApiExtensions(
apiBuilders.filter(b => {
if (
b.use === `@vercel/python${withTag}` &&
!('vercel-plugin-python' in deps)
) {
return false;
}
if (
b.use === `@vercel/go${withTag}` &&
!('vercel-plugin-go' in deps)
) {
return false;
}
if (
b.use === `@vercel/ruby${withTag}` &&
!('vercel-plugin-ruby' in deps)
) {
return false;
}
return true;
})
);
if (extSet.size > 0) { if (extSet.size > 0) {
const exts = Array.from(extSet) const extGroup = `(?:\\.(?:${Array.from(extSet)
.map(ext => ext.slice(1)) .map(ext => ext.slice(1))
.join('|'); .join('|')}))`;
const extGroupLimited = `(?:\\.(?:${Array.from(extSetLimited)
const extGroup = `(?:\\.(?:${exts}))`; .map(ext => ext.slice(1))
.join('|')}))`;
if (options.cleanUrls) { if (options.cleanUrls) {
redirectRoutes.push({ redirectRoutes.push({
@@ -979,6 +1029,20 @@ function getRouteResult(
}, },
status: 308, status: 308,
}); });
limitedRoutes.redirectRoutes.push({
src: `^/(api(?:.+)?)/index${extGroupLimited}?/?$`,
headers: { Location: options.trailingSlash ? '/$1/' : '/$1' },
status: 308,
});
limitedRoutes.redirectRoutes.push({
src: `^/api/(.+)${extGroupLimited}/?$`,
headers: {
Location: options.trailingSlash ? '/api/$1/' : '/api/$1',
},
status: 308,
});
} else { } else {
defaultRoutes.push({ handle: 'miss' }); defaultRoutes.push({ handle: 'miss' });
defaultRoutes.push({ defaultRoutes.push({
@@ -986,10 +1050,18 @@ function getRouteResult(
dest: '/api/$1', dest: '/api/$1',
check: true, check: true,
}); });
limitedRoutes.defaultRoutes.push({ handle: 'miss' });
limitedRoutes.defaultRoutes.push({
src: `^/api/(.+)${extGroupLimited}$`,
dest: '/api/$1',
check: true,
});
} }
} }
rewriteRoutes.push(...dynamicRoutes); rewriteRoutes.push(...dynamicRoutes);
limitedRoutes.rewriteRoutes.push(...dynamicRoutes);
if (typeof ignoreRuntimes === 'undefined') { if (typeof ignoreRuntimes === 'undefined') {
// This route is only necessary to hide the directory listing // This route is only necessary to hide the directory listing
@@ -1040,6 +1112,7 @@ function getRouteResult(
redirectRoutes, redirectRoutes,
rewriteRoutes, rewriteRoutes,
errorRoutes, errorRoutes,
limitedRoutes,
}; };
} }

View File

@@ -0,0 +1 @@
# users.rb

View File

@@ -1,9 +1,9 @@
{ {
"functions": { "functions": {
"api/users/post.py": { "api/users.rb": {
"memory": 3008 "memory": 3008
}, },
"api/not-matching-anything.py": { "api/doesnt-exist.rb": {
"memory": 768 "memory": 768
} }
} }

View File

@@ -0,0 +1 @@
# [id].py

View File

@@ -0,0 +1 @@
# project/[aid]/[bid]/index.py

View File

@@ -0,0 +1,7 @@
{
"functions": {
"api/users/post.py": {
"memory": 3008
}
}
}

View File

@@ -2385,13 +2385,10 @@ it('Test `detectRoutes` with `featHandleMiss=true`', async () => {
{ {
const files = ['api/user.go', 'api/team.js', 'api/package.json']; const files = ['api/user.go', 'api/team.js', 'api/package.json'];
const { defaultRoutes, rewriteRoutes, errorRoutes } = await detectBuilders( const { defaultRoutes, rewriteRoutes, errorRoutes, limitedRoutes } =
files, await detectBuilders(files, null, {
null,
{
featHandleMiss, featHandleMiss,
} });
);
expect(defaultRoutes).toStrictEqual([ expect(defaultRoutes).toStrictEqual([
{ handle: 'miss' }, { handle: 'miss' },
{ {
@@ -2414,6 +2411,22 @@ it('Test `detectRoutes` with `featHandleMiss=true`', async () => {
}, },
]); ]);
// Limited routes should have js but not go since the go plugin is not installed
expect(limitedRoutes).toStrictEqual({
redirectRoutes: [],
rewriteRoutes: [],
defaultRoutes: [
{
handle: 'miss',
},
{
src: '^/api/(.+)(?:\\.(?:js))$',
dest: '/api/$1',
check: true,
},
],
});
const pattern = new RegExp(errorRoutes![0].src!); const pattern = new RegExp(errorRoutes![0].src!);
[ [
@@ -2816,8 +2829,13 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`', async ()
{ {
const files = ['api/user.go', 'api/team.js', 'api/package.json']; const files = ['api/user.go', 'api/team.js', 'api/package.json'];
const { defaultRoutes, redirectRoutes, rewriteRoutes, errorRoutes } = const {
await detectBuilders(files, null, options); defaultRoutes,
redirectRoutes,
rewriteRoutes,
errorRoutes,
limitedRoutes,
} = await detectBuilders(files, null, options);
testHeaders(redirectRoutes); testHeaders(redirectRoutes);
expect(defaultRoutes).toStrictEqual([]); expect(defaultRoutes).toStrictEqual([]);
expect(rewriteRoutes).toStrictEqual([ expect(rewriteRoutes).toStrictEqual([
@@ -2834,6 +2852,28 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`', async ()
}, },
]); ]);
// Limited routes should have js but not go since the go plugin is not installed
expect(limitedRoutes).toStrictEqual({
redirectRoutes: [
{
src: '^/(api(?:.+)?)/index(?:\\.(?:js))?/?$',
headers: {
Location: '/$1',
},
status: 308,
},
{
src: '^/api/(.+)(?:\\.(?:js))/?$',
headers: {
Location: '/api/$1',
},
status: 308,
},
],
rewriteRoutes: [],
defaultRoutes: [],
});
// expected redirect should match inputs // expected redirect should match inputs
const getLocation = createReplaceLocation(redirectRoutes); const getLocation = createReplaceLocation(redirectRoutes);
@@ -3077,7 +3117,7 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`, `trailingS
{ {
const files = ['api/user.go', 'api/team.js', 'api/package.json']; const files = ['api/user.go', 'api/team.js', 'api/package.json'];
const { defaultRoutes, redirectRoutes, rewriteRoutes } = const { defaultRoutes, redirectRoutes, rewriteRoutes, limitedRoutes } =
await detectBuilders(files, null, options); await detectBuilders(files, null, options);
testHeaders(redirectRoutes); testHeaders(redirectRoutes);
expect(defaultRoutes).toStrictEqual([]); expect(defaultRoutes).toStrictEqual([]);
@@ -3088,6 +3128,28 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`, `trailingS
}, },
]); ]);
// Limited routes should have js but not go since the go plugin is not installed
expect(limitedRoutes).toStrictEqual({
redirectRoutes: [
{
src: '^/(api(?:.+)?)/index(?:\\.(?:js))?/?$',
headers: {
Location: '/$1/',
},
status: 308,
},
{
src: '^/api/(.+)(?:\\.(?:js))/?$',
headers: {
Location: '/api/$1/',
},
status: 308,
},
],
rewriteRoutes: [],
defaultRoutes: [],
});
// expected redirect should match inputs // expected redirect should match inputs
const getLocation = createReplaceLocation(redirectRoutes); const getLocation = createReplaceLocation(redirectRoutes);

View File

@@ -18,21 +18,27 @@ async function fsToJson(dir: string, output: Record<string, any> = {}) {
return output; return output;
} }
const workPath = join(__dirname, 'walk', 'python-api'); const invalidFuncWorkpath = join(
__dirname,
'convert-runtime',
'invalid-functions'
);
const pythonApiWorkpath = join(__dirname, 'convert-runtime', 'python-api');
describe('convert-runtime-to-plugin', () => { describe('convert-runtime-to-plugin', () => {
afterEach(async () => { afterEach(async () => {
await fs.remove(join(workPath, '.output')); await fs.remove(join(invalidFuncWorkpath, '.output'));
await fs.remove(join(pythonApiWorkpath, '.output'));
}); });
it('should create correct fileystem for python', async () => { it('should create correct fileystem for python', async () => {
const workPath = pythonApiWorkpath;
const lambdaOptions = { const lambdaOptions = {
handler: 'index.handler', handler: 'index.handler',
runtime: 'python3.9', runtime: 'python3.9',
memory: 512, memory: 512,
maxDuration: 5, maxDuration: 5,
environment: {}, environment: {},
regions: ['sfo1'],
}; };
const buildRuntime = async (opts: BuildOptions) => { const buildRuntime = async (opts: BuildOptions) => {
@@ -84,10 +90,19 @@ describe('convert-runtime-to-plugin', () => {
expect(indexJson).toMatchObject({ expect(indexJson).toMatchObject({
version: 1, version: 1,
files: [ files: [
{
input: '../../../../runtime-traced-files/api/db/[id].py',
output: 'api/db/[id].py',
},
{ {
input: '../../../../runtime-traced-files/api/index.py', input: '../../../../runtime-traced-files/api/index.py',
output: 'api/index.py', output: 'api/index.py',
}, },
{
input:
'../../../../runtime-traced-files/api/project/[aid]/[bid]/index.py',
output: 'api/project/[aid]/[bid]/index.py',
},
{ {
input: '../../../../runtime-traced-files/api/users/get.py', input: '../../../../runtime-traced-files/api/users/get.py',
output: 'api/users/get.py', output: 'api/users/get.py',
@@ -117,10 +132,19 @@ describe('convert-runtime-to-plugin', () => {
expect(getJson).toMatchObject({ expect(getJson).toMatchObject({
version: 1, version: 1,
files: [ files: [
{
input: '../../../../../runtime-traced-files/api/db/[id].py',
output: 'api/db/[id].py',
},
{ {
input: '../../../../../runtime-traced-files/api/index.py', input: '../../../../../runtime-traced-files/api/index.py',
output: 'api/index.py', output: 'api/index.py',
}, },
{
input:
'../../../../../runtime-traced-files/api/project/[aid]/[bid]/index.py',
output: 'api/project/[aid]/[bid]/index.py',
},
{ {
input: '../../../../../runtime-traced-files/api/users/get.py', input: '../../../../../runtime-traced-files/api/users/get.py',
output: 'api/users/get.py', output: 'api/users/get.py',
@@ -150,10 +174,19 @@ describe('convert-runtime-to-plugin', () => {
expect(postJson).toMatchObject({ expect(postJson).toMatchObject({
version: 1, version: 1,
files: [ files: [
{
input: '../../../../../runtime-traced-files/api/db/[id].py',
output: 'api/db/[id].py',
},
{ {
input: '../../../../../runtime-traced-files/api/index.py', input: '../../../../../runtime-traced-files/api/index.py',
output: 'api/index.py', output: 'api/index.py',
}, },
{
input:
'../../../../../runtime-traced-files/api/project/[aid]/[bid]/index.py',
output: 'api/project/[aid]/[bid]/index.py',
},
{ {
input: '../../../../../runtime-traced-files/api/users/get.py', input: '../../../../../runtime-traced-files/api/users/get.py',
output: 'api/users/get.py', output: 'api/users/get.py',

View File

@@ -1,6 +1,6 @@
{ {
"name": "vercel", "name": "vercel",
"version": "23.1.3-canary.39", "version": "23.1.3-canary.41",
"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",
@@ -43,14 +43,14 @@
"node": ">= 12" "node": ">= 12"
}, },
"dependencies": { "dependencies": {
"@vercel/build-utils": "2.12.3-canary.21", "@vercel/build-utils": "2.12.3-canary.23",
"@vercel/go": "1.2.4-canary.4", "@vercel/go": "1.2.4-canary.4",
"@vercel/node": "1.12.2-canary.7", "@vercel/node": "1.12.2-canary.7",
"@vercel/python": "2.1.2-canary.0", "@vercel/python": "2.1.2-canary.0",
"@vercel/ruby": "1.2.8-canary.4", "@vercel/ruby": "1.2.8-canary.4",
"update-notifier": "4.1.0", "update-notifier": "4.1.0",
"vercel-plugin-middleware": "0.0.0-canary.7", "vercel-plugin-middleware": "0.0.0-canary.7",
"vercel-plugin-node": "1.12.2-canary.12" "vercel-plugin-node": "1.12.2-canary.14"
}, },
"devDependencies": { "devDependencies": {
"@next/env": "11.1.2", "@next/env": "11.1.2",

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vercel/client", "name": "@vercel/client",
"version": "10.2.3-canary.22", "version": "10.2.3-canary.24",
"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",
@@ -40,7 +40,7 @@
] ]
}, },
"dependencies": { "dependencies": {
"@vercel/build-utils": "2.12.3-canary.21", "@vercel/build-utils": "2.12.3-canary.23",
"@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",

View File

@@ -1,7 +1,7 @@
{ {
"private": false, "private": false,
"name": "vercel-plugin-go", "name": "vercel-plugin-go",
"version": "1.0.0-canary.6", "version": "1.0.0-canary.8",
"main": "dist/index.js", "main": "dist/index.js",
"license": "MIT", "license": "MIT",
"files": [ "files": [
@@ -17,7 +17,7 @@
"prepublishOnly": "tsc" "prepublishOnly": "tsc"
}, },
"dependencies": { "dependencies": {
"@vercel/build-utils": "2.12.3-canary.21", "@vercel/build-utils": "2.12.3-canary.23",
"@vercel/go": "1.2.4-canary.4" "@vercel/go": "1.2.4-canary.4"
}, },
"devDependencies": { "devDependencies": {

View File

@@ -1,6 +1,6 @@
{ {
"name": "vercel-plugin-node", "name": "vercel-plugin-node",
"version": "1.12.2-canary.12", "version": "1.12.2-canary.14",
"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",
@@ -34,7 +34,7 @@
"@types/node-fetch": "2", "@types/node-fetch": "2",
"@types/test-listen": "1.1.0", "@types/test-listen": "1.1.0",
"@types/yazl": "2.4.2", "@types/yazl": "2.4.2",
"@vercel/build-utils": "2.12.3-canary.21", "@vercel/build-utils": "2.12.3-canary.23",
"@vercel/fun": "1.0.3", "@vercel/fun": "1.0.3",
"@vercel/ncc": "0.24.0", "@vercel/ncc": "0.24.0",
"@vercel/nft": "0.14.0", "@vercel/nft": "0.14.0",

View File

@@ -1,7 +1,7 @@
{ {
"private": false, "private": false,
"name": "vercel-plugin-python", "name": "vercel-plugin-python",
"version": "1.0.0-canary.7", "version": "1.0.0-canary.9",
"main": "dist/index.js", "main": "dist/index.js",
"license": "MIT", "license": "MIT",
"files": [ "files": [
@@ -17,7 +17,7 @@
"prepublishOnly": "tsc" "prepublishOnly": "tsc"
}, },
"dependencies": { "dependencies": {
"@vercel/build-utils": "2.12.3-canary.21", "@vercel/build-utils": "2.12.3-canary.23",
"@vercel/python": "2.1.2-canary.0" "@vercel/python": "2.1.2-canary.0"
}, },
"devDependencies": { "devDependencies": {

View File

@@ -1,7 +1,7 @@
{ {
"private": false, "private": false,
"name": "vercel-plugin-ruby", "name": "vercel-plugin-ruby",
"version": "1.0.0-canary.5", "version": "1.0.0-canary.7",
"main": "dist/index.js", "main": "dist/index.js",
"license": "MIT", "license": "MIT",
"files": [ "files": [
@@ -17,7 +17,7 @@
"prepublishOnly": "tsc" "prepublishOnly": "tsc"
}, },
"dependencies": { "dependencies": {
"@vercel/build-utils": "2.12.3-canary.21", "@vercel/build-utils": "2.12.3-canary.23",
"@vercel/ruby": "1.2.8-canary.4" "@vercel/ruby": "1.2.8-canary.4"
}, },
"devDependencies": { "devDependencies": {