mirror of
https://github.com/LukeHagar/vercel.git
synced 2025-12-12 21:07:46 +00:00
Compare commits
9 Commits
vercel-plu
...
vercel-plu
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
792ab38760 | ||
|
|
0bba3e76c1 | ||
|
|
3d961ffbb9 | ||
|
|
a3039f57bb | ||
|
|
5499fa9a04 | ||
|
|
b9fd64faff | ||
|
|
1202ff7b2b | ||
|
|
abd9f019f1 | ||
|
|
edb5eead81 |
15787
examples/nextjs/package-lock.json
generated
Normal file
15787
examples/nextjs/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
2
examples/remix/.gitignore
vendored
2
examples/remix/.gitignore
vendored
@@ -5,4 +5,4 @@ node_modules
|
|||||||
.output
|
.output
|
||||||
|
|
||||||
public/build
|
public/build
|
||||||
api/build
|
api/_build
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
const { createRequestHandler } = require("@remix-run/vercel");
|
const { createRequestHandler } = require("@remix-run/vercel");
|
||||||
|
|
||||||
module.exports = createRequestHandler({
|
module.exports = createRequestHandler({
|
||||||
build: require("./build")
|
build: require("./_build")
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,120 +0,0 @@
|
|||||||
/*
|
|
||||||
* You probably want to just delete this file; it's just for the demo pages.
|
|
||||||
*/
|
|
||||||
.remix-app {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
min-height: 100vh;
|
|
||||||
min-height: calc(100vh - env(safe-area-inset-bottom));
|
|
||||||
}
|
|
||||||
|
|
||||||
.remix-app > * {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.remix-app__header {
|
|
||||||
padding-top: 1rem;
|
|
||||||
padding-bottom: 1rem;
|
|
||||||
border-bottom: 1px solid var(--color-border);
|
|
||||||
}
|
|
||||||
|
|
||||||
.remix-app__header-content {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.remix-app__header-home-link {
|
|
||||||
width: 106px;
|
|
||||||
height: 30px;
|
|
||||||
color: var(--color-foreground);
|
|
||||||
}
|
|
||||||
|
|
||||||
.remix-app__header-nav ul {
|
|
||||||
list-style: none;
|
|
||||||
margin: 0;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 1.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.remix-app__header-nav li {
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.remix-app__main {
|
|
||||||
flex: 1 1 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.remix-app__footer {
|
|
||||||
padding-top: 1rem;
|
|
||||||
padding-bottom: 1rem;
|
|
||||||
border-top: 1px solid var(--color-border);
|
|
||||||
}
|
|
||||||
|
|
||||||
.remix-app__footer-content {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.remix__page {
|
|
||||||
--gap: 1rem;
|
|
||||||
--space: 2rem;
|
|
||||||
display: grid;
|
|
||||||
grid-auto-rows: min-content;
|
|
||||||
gap: var(--gap);
|
|
||||||
padding-top: var(--space);
|
|
||||||
padding-bottom: var(--space);
|
|
||||||
}
|
|
||||||
|
|
||||||
@media print, screen and (min-width: 640px) {
|
|
||||||
.remix__page {
|
|
||||||
--gap: 2rem;
|
|
||||||
grid-auto-rows: unset;
|
|
||||||
grid-template-columns: repeat(2, 1fr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (min-width: 1024px) {
|
|
||||||
.remix__page {
|
|
||||||
--gap: 4rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.remix__page > main > :first-child {
|
|
||||||
margin-top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.remix__page > main > :last-child {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.remix__page > aside {
|
|
||||||
margin: 0;
|
|
||||||
padding: 1.5ch 2ch;
|
|
||||||
border: solid 1px var(--color-border);
|
|
||||||
border-radius: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.remix__page > aside > :first-child {
|
|
||||||
margin-top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.remix__page > aside > :last-child {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.remix__form {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 1rem;
|
|
||||||
padding: 1rem;
|
|
||||||
border: 1px solid var(--color-border);
|
|
||||||
border-radius: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.remix__form > * {
|
|
||||||
margin-top: 0;
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
8345
examples/remix/package-lock.json
generated
Normal file
8345
examples/remix/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -9,15 +9,15 @@
|
|||||||
"postinstall": "remix setup node"
|
"postinstall": "remix setup node"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@remix-run/react": "^1.0.5",
|
"@remix-run/react": "^1.0.6",
|
||||||
"react": "^17.0.2",
|
"react": "^17.0.2",
|
||||||
"react-dom": "^17.0.2",
|
"react-dom": "^17.0.2",
|
||||||
"remix": "^1.0.5",
|
"remix": "^1.0.6",
|
||||||
"@remix-run/serve": "^1.0.5",
|
"@remix-run/serve": "^1.0.6",
|
||||||
"@remix-run/vercel": "^1.0.5"
|
"@remix-run/vercel": "^1.0.6"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@remix-run/dev": "^1.0.5",
|
"@remix-run/dev": "^1.0.6",
|
||||||
"@types/react": "^17.0.24",
|
"@types/react": "^17.0.24",
|
||||||
"@types/react-dom": "^17.0.9",
|
"@types/react-dom": "^17.0.9",
|
||||||
"typescript": "^4.1.2"
|
"typescript": "^4.1.2"
|
||||||
|
|||||||
@@ -5,5 +5,5 @@ module.exports = {
|
|||||||
appDirectory: "app",
|
appDirectory: "app",
|
||||||
browserBuildDirectory: "public/build",
|
browserBuildDirectory: "public/build",
|
||||||
publicPath: "/build/",
|
publicPath: "/build/",
|
||||||
serverBuildDirectory: "api/build"
|
serverBuildDirectory: "api/_build"
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vercel/build-utils",
|
"name": "@vercel/build-utils",
|
||||||
"version": "2.12.3-canary.25",
|
"version": "2.12.3-canary.28",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"types": "./dist/index.d.js",
|
"types": "./dist/index.d.js",
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
"@types/node-fetch": "^2.1.6",
|
"@types/node-fetch": "^2.1.6",
|
||||||
"@types/semver": "6.0.0",
|
"@types/semver": "6.0.0",
|
||||||
"@types/yazl": "^2.4.1",
|
"@types/yazl": "^2.4.1",
|
||||||
"@vercel/frameworks": "0.5.1-canary.15",
|
"@vercel/frameworks": "0.5.1-canary.16",
|
||||||
"@vercel/ncc": "0.24.0",
|
"@vercel/ncc": "0.24.0",
|
||||||
"aggregate-error": "3.0.1",
|
"aggregate-error": "3.0.1",
|
||||||
"async-retry": "1.2.3",
|
"async-retry": "1.2.3",
|
||||||
|
|||||||
@@ -2,55 +2,78 @@ import fs from 'fs-extra';
|
|||||||
import { join, dirname, relative } from 'path';
|
import { join, dirname, relative } from 'path';
|
||||||
import glob from './fs/glob';
|
import glob from './fs/glob';
|
||||||
import { normalizePath } from './fs/normalize-path';
|
import { normalizePath } from './fs/normalize-path';
|
||||||
import { FILES_SYMBOL, getLambdaOptionsFromFunction, Lambda } from './lambda';
|
import { FILES_SYMBOL, Lambda } from './lambda';
|
||||||
import type FileBlob from './file-blob';
|
import type FileBlob from './file-blob';
|
||||||
import type { BuilderFunctions, BuildOptions, Files } from './types';
|
import type { BuildOptions, Files } from './types';
|
||||||
import minimatch from 'minimatch';
|
import { getIgnoreFilter } from '.';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert legacy Runtime to a Plugin.
|
* Convert legacy Runtime to a Plugin.
|
||||||
* @param buildRuntime - a legacy build() function from a Runtime
|
* @param buildRuntime - a legacy build() function from a Runtime
|
||||||
|
* @param packageName - the name of the package, for example `vercel-plugin-python`
|
||||||
* @param ext - the file extension, for example `.py`
|
* @param ext - the file extension, for example `.py`
|
||||||
*/
|
*/
|
||||||
export function convertRuntimeToPlugin(
|
export function convertRuntimeToPlugin(
|
||||||
buildRuntime: (options: BuildOptions) => Promise<{ output: Lambda }>,
|
buildRuntime: (options: BuildOptions) => Promise<{ output: Lambda }>,
|
||||||
|
packageName: string,
|
||||||
ext: string
|
ext: string
|
||||||
) {
|
) {
|
||||||
// This `build()` signature should match `plugin.build()` signature in `vercel build`.
|
// This `build()` signature should match `plugin.build()` signature in `vercel build`.
|
||||||
return async function build({
|
return async function build({ workPath }: { workPath: string }) {
|
||||||
vercelConfig,
|
|
||||||
workPath,
|
|
||||||
}: {
|
|
||||||
vercelConfig: {
|
|
||||||
functions?: BuilderFunctions;
|
|
||||||
regions?: string[];
|
|
||||||
};
|
|
||||||
workPath: string;
|
|
||||||
}) {
|
|
||||||
const opts = { cwd: workPath };
|
const opts = { cwd: workPath };
|
||||||
const files = await glob('**', opts);
|
const files = await glob('**', opts);
|
||||||
delete files['vercel.json']; // Builders/Runtimes didn't have vercel.json
|
|
||||||
const entrypoints = await glob(`api/**/*${ext}`, opts);
|
// `.output` was already created by the Build Command, so we have
|
||||||
|
// to ensure its contents don't get bundled into the Lambda. Similarily,
|
||||||
|
// we don't want to bundle anything from `.vercel` either. Lastly,
|
||||||
|
// Builders/Runtimes didn't have `vercel.json` or `now.json`.
|
||||||
|
const ignoredPaths = ['.output', '.vercel', 'vercel.json', 'now.json'];
|
||||||
|
|
||||||
|
// We also don't want to provide any files to Runtimes that were ignored
|
||||||
|
// through `.vercelignore` or `.nowignore`, because the Build Step does the same.
|
||||||
|
const ignoreFilter = await getIgnoreFilter(workPath);
|
||||||
|
|
||||||
|
// We're not passing this as an `ignore` filter to the `glob` function above,
|
||||||
|
// so that we can re-use exactly the same `getIgnoreFilter` method that the
|
||||||
|
// Build Step uses (literally the same code).
|
||||||
|
for (const file in files) {
|
||||||
|
const isNative = ignoredPaths.some(item => {
|
||||||
|
return file.startsWith(item);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (isNative || ignoreFilter(file)) {
|
||||||
|
delete files[file];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const entrypointPattern = `api/**/*${ext}`;
|
||||||
|
const entrypoints = await glob(entrypointPattern, opts);
|
||||||
const pages: { [key: string]: any } = {};
|
const pages: { [key: string]: any } = {};
|
||||||
const { functions = {} } = vercelConfig;
|
const pluginName = packageName.replace('vercel-plugin-', '');
|
||||||
const traceDir = join(workPath, '.output', 'runtime-traced-files');
|
|
||||||
|
const traceDir = join(
|
||||||
|
workPath,
|
||||||
|
`.output`,
|
||||||
|
`inputs`,
|
||||||
|
// Legacy Runtimes can only provide API Routes, so that's
|
||||||
|
// why we can use this prefix for all of them. Here, we have to
|
||||||
|
// make sure to not use a cryptic hash name, because people
|
||||||
|
// need to be able to easily inspect the output.
|
||||||
|
`api-routes-${pluginName}`
|
||||||
|
);
|
||||||
|
|
||||||
await fs.ensureDir(traceDir);
|
await fs.ensureDir(traceDir);
|
||||||
|
|
||||||
for (const entrypoint of Object.keys(entrypoints)) {
|
for (const entrypoint of Object.keys(entrypoints)) {
|
||||||
const key =
|
|
||||||
Object.keys(functions).find(
|
|
||||||
src => src === entrypoint || minimatch(entrypoint, src)
|
|
||||||
) || '';
|
|
||||||
const config = functions[key] || {};
|
|
||||||
|
|
||||||
const { output } = await buildRuntime({
|
const { output } = await buildRuntime({
|
||||||
files,
|
files,
|
||||||
entrypoint,
|
entrypoint,
|
||||||
workPath,
|
workPath,
|
||||||
config: {
|
config: {
|
||||||
zeroConfig: true,
|
zeroConfig: true,
|
||||||
includeFiles: config.includeFiles,
|
},
|
||||||
excludeFiles: config.excludeFiles,
|
meta: {
|
||||||
|
avoidTopLevelInstall: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -61,7 +84,6 @@ export function convertRuntimeToPlugin(
|
|||||||
maxDuration: output.maxDuration,
|
maxDuration: output.maxDuration,
|
||||||
environment: output.environment,
|
environment: output.environment,
|
||||||
allowQuery: output.allowQuery,
|
allowQuery: output.allowQuery,
|
||||||
//regions: output.regions,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// @ts-ignore This symbol is a private API
|
// @ts-ignore This symbol is a private API
|
||||||
@@ -108,7 +130,7 @@ export function convertRuntimeToPlugin(
|
|||||||
await fs.writeFile(nft, json);
|
await fs.writeFile(nft, json);
|
||||||
}
|
}
|
||||||
|
|
||||||
await updateFunctionsManifest({ vercelConfig, workPath, pages });
|
await updateFunctionsManifest({ workPath, pages });
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,15 +158,12 @@ async function readJson(filePath: string): Promise<{ [key: string]: any }> {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* If `.output/functions-manifest.json` exists, append to the pages
|
* If `.output/functions-manifest.json` exists, append to the pages
|
||||||
* property. Otherwise write a new file. This will also read `vercel.json`
|
* property. Otherwise write a new file.
|
||||||
* and apply relevant `functions` property config.
|
|
||||||
*/
|
*/
|
||||||
export async function updateFunctionsManifest({
|
export async function updateFunctionsManifest({
|
||||||
vercelConfig,
|
|
||||||
workPath,
|
workPath,
|
||||||
pages,
|
pages,
|
||||||
}: {
|
}: {
|
||||||
vercelConfig: { functions?: BuilderFunctions; regions?: string[] };
|
|
||||||
workPath: string;
|
workPath: string;
|
||||||
pages: { [key: string]: any };
|
pages: { [key: string]: any };
|
||||||
}) {
|
}) {
|
||||||
@@ -159,16 +178,7 @@ export async function updateFunctionsManifest({
|
|||||||
if (!functionsManifest.pages) functionsManifest.pages = {};
|
if (!functionsManifest.pages) functionsManifest.pages = {};
|
||||||
|
|
||||||
for (const [pageKey, pageConfig] of Object.entries(pages)) {
|
for (const [pageKey, pageConfig] of Object.entries(pages)) {
|
||||||
const fnConfig = await getLambdaOptionsFromFunction({
|
functionsManifest.pages[pageKey] = { ...pageConfig };
|
||||||
sourceFile: pageKey,
|
|
||||||
config: vercelConfig,
|
|
||||||
});
|
|
||||||
functionsManifest.pages[pageKey] = {
|
|
||||||
...pageConfig,
|
|
||||||
memory: fnConfig.memory || pageConfig.memory,
|
|
||||||
maxDuration: fnConfig.maxDuration || pageConfig.maxDuration,
|
|
||||||
regions: vercelConfig.regions || pageConfig.regions,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await fs.writeFile(functionsManifestPath, JSON.stringify(functionsManifest));
|
await fs.writeFile(functionsManifestPath, JSON.stringify(functionsManifest));
|
||||||
|
|||||||
84
packages/build-utils/src/get-ignore-filter.ts
Normal file
84
packages/build-utils/src/get-ignore-filter.ts
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
import path from 'path';
|
||||||
|
import fs from 'fs-extra';
|
||||||
|
import ignore from 'ignore';
|
||||||
|
|
||||||
|
interface CodedError extends Error {
|
||||||
|
code: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isCodedError(error: unknown): error is CodedError {
|
||||||
|
return (
|
||||||
|
error !== null &&
|
||||||
|
error !== undefined &&
|
||||||
|
(error as CodedError).code !== undefined
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearRelative(s: string) {
|
||||||
|
return s.replace(/(\n|^)\.\//g, '$1');
|
||||||
|
}
|
||||||
|
|
||||||
|
export default async function (
|
||||||
|
downloadPath: string,
|
||||||
|
rootDirectory?: string | undefined
|
||||||
|
) {
|
||||||
|
const readFile = async (p: string) => {
|
||||||
|
try {
|
||||||
|
return await fs.readFile(p, 'utf8');
|
||||||
|
} catch (error: any) {
|
||||||
|
if (
|
||||||
|
error.code === 'ENOENT' ||
|
||||||
|
(error instanceof Error && error.message.includes('ENOENT'))
|
||||||
|
) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const vercelIgnorePath = path.join(
|
||||||
|
downloadPath,
|
||||||
|
rootDirectory || '',
|
||||||
|
'.vercelignore'
|
||||||
|
);
|
||||||
|
const nowIgnorePath = path.join(
|
||||||
|
downloadPath,
|
||||||
|
rootDirectory || '',
|
||||||
|
'.nowignore'
|
||||||
|
);
|
||||||
|
const ignoreContents = [];
|
||||||
|
|
||||||
|
try {
|
||||||
|
ignoreContents.push(
|
||||||
|
...(
|
||||||
|
await Promise.all([readFile(vercelIgnorePath), readFile(nowIgnorePath)])
|
||||||
|
).filter(Boolean)
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
if (isCodedError(error) && error.code === 'ENOTDIR') {
|
||||||
|
console.log(`Warning: Cannot read ignore file from ${vercelIgnorePath}`);
|
||||||
|
} else {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ignoreContents.length === 2) {
|
||||||
|
throw new Error(
|
||||||
|
'Cannot use both a `.vercelignore` and `.nowignore` file. Please delete the `.nowignore` file.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ignoreContents.length === 0) {
|
||||||
|
return () => false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ignoreFilter: any = ignore().add(clearRelative(ignoreContents[0]!));
|
||||||
|
|
||||||
|
return function (p: string) {
|
||||||
|
// we should not ignore now.json and vercel.json if it asked to.
|
||||||
|
// we depend on these files for building the app with sourceless
|
||||||
|
if (p === 'now.json' || p === 'vercel.json') return false;
|
||||||
|
return ignoreFilter.test(p).ignored;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { createHash } from 'crypto';
|
||||||
import FileBlob from './file-blob';
|
import FileBlob from './file-blob';
|
||||||
import FileFsRef from './file-fs-ref';
|
import FileFsRef from './file-fs-ref';
|
||||||
import FileRef from './file-ref';
|
import FileRef from './file-ref';
|
||||||
@@ -33,6 +34,7 @@ import { NowBuildError } from './errors';
|
|||||||
import streamToBuffer from './fs/stream-to-buffer';
|
import streamToBuffer from './fs/stream-to-buffer';
|
||||||
import shouldServe from './should-serve';
|
import shouldServe from './should-serve';
|
||||||
import debug from './debug';
|
import debug from './debug';
|
||||||
|
import getIgnoreFilter from './get-ignore-filter';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
FileBlob,
|
FileBlob,
|
||||||
@@ -70,6 +72,7 @@ export {
|
|||||||
isSymbolicLink,
|
isSymbolicLink,
|
||||||
getLambdaOptionsFromFunction,
|
getLambdaOptionsFromFunction,
|
||||||
scanParentDirs,
|
scanParentDirs,
|
||||||
|
getIgnoreFilter,
|
||||||
};
|
};
|
||||||
|
|
||||||
export {
|
export {
|
||||||
@@ -132,3 +135,11 @@ export const getPlatformEnv = (name: string): string | undefined => {
|
|||||||
}
|
}
|
||||||
return n;
|
return n;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function for generating file or directories names in `.output/inputs`
|
||||||
|
* for dependencies of files provided to the File System API.
|
||||||
|
*/
|
||||||
|
export const getInputHash = (source: Buffer | string): string => {
|
||||||
|
return createHash('sha1').update(source).digest('hex');
|
||||||
|
};
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ export interface Meta {
|
|||||||
filesRemoved?: string[];
|
filesRemoved?: string[];
|
||||||
env?: Env;
|
env?: Env;
|
||||||
buildEnv?: Env;
|
buildEnv?: Env;
|
||||||
|
avoidTopLevelInstall?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AnalyzeOptions {
|
export interface AnalyzeOptions {
|
||||||
|
|||||||
@@ -50,16 +50,21 @@ describe('convert-runtime-to-plugin', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const lambdaFiles = await fsToJson(workPath);
|
const lambdaFiles = await fsToJson(workPath);
|
||||||
const vercelConfig = JSON.parse(lambdaFiles['vercel.json']);
|
|
||||||
delete lambdaFiles['vercel.json'];
|
delete lambdaFiles['vercel.json'];
|
||||||
const build = await convertRuntimeToPlugin(buildRuntime, '.py');
|
|
||||||
|
|
||||||
await build({ vercelConfig, workPath });
|
const ext = '.py';
|
||||||
|
const packageName = 'vercel-plugin-python';
|
||||||
|
const build = await convertRuntimeToPlugin(buildRuntime, packageName, ext);
|
||||||
|
|
||||||
|
await build({ workPath });
|
||||||
|
|
||||||
const output = await fsToJson(join(workPath, '.output'));
|
const output = await fsToJson(join(workPath, '.output'));
|
||||||
|
|
||||||
expect(output).toMatchObject({
|
expect(output).toMatchObject({
|
||||||
'functions-manifest.json': expect.stringContaining('{'),
|
'functions-manifest.json': expect.stringContaining('{'),
|
||||||
'runtime-traced-files': lambdaFiles,
|
inputs: {
|
||||||
|
'api-routes-python': lambdaFiles,
|
||||||
|
},
|
||||||
server: {
|
server: {
|
||||||
pages: {
|
pages: {
|
||||||
api: {
|
api: {
|
||||||
@@ -82,7 +87,7 @@ describe('convert-runtime-to-plugin', () => {
|
|||||||
pages: {
|
pages: {
|
||||||
'api/index.py': lambdaOptions,
|
'api/index.py': lambdaOptions,
|
||||||
'api/users/get.py': lambdaOptions,
|
'api/users/get.py': lambdaOptions,
|
||||||
'api/users/post.py': { ...lambdaOptions, memory: 3008 },
|
'api/users/post.py': { ...lambdaOptions, memory: 512 },
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -91,36 +96,35 @@ describe('convert-runtime-to-plugin', () => {
|
|||||||
version: 1,
|
version: 1,
|
||||||
files: [
|
files: [
|
||||||
{
|
{
|
||||||
input: '../../../../runtime-traced-files/api/db/[id].py',
|
input: `../../../../inputs/api-routes-python/api/db/[id].py`,
|
||||||
output: 'api/db/[id].py',
|
output: 'api/db/[id].py',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
input: '../../../../runtime-traced-files/api/index.py',
|
input: `../../../../inputs/api-routes-python/api/index.py`,
|
||||||
output: 'api/index.py',
|
output: 'api/index.py',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
input:
|
input: `../../../../inputs/api-routes-python/api/project/[aid]/[bid]/index.py`,
|
||||||
'../../../../runtime-traced-files/api/project/[aid]/[bid]/index.py',
|
|
||||||
output: 'api/project/[aid]/[bid]/index.py',
|
output: 'api/project/[aid]/[bid]/index.py',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
input: '../../../../runtime-traced-files/api/users/get.py',
|
input: `../../../../inputs/api-routes-python/api/users/get.py`,
|
||||||
output: 'api/users/get.py',
|
output: 'api/users/get.py',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
input: '../../../../runtime-traced-files/api/users/post.py',
|
input: `../../../../inputs/api-routes-python/api/users/post.py`,
|
||||||
output: 'api/users/post.py',
|
output: 'api/users/post.py',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
input: '../../../../runtime-traced-files/file.txt',
|
input: `../../../../inputs/api-routes-python/file.txt`,
|
||||||
output: 'file.txt',
|
output: 'file.txt',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
input: '../../../../runtime-traced-files/util/date.py',
|
input: `../../../../inputs/api-routes-python/util/date.py`,
|
||||||
output: 'util/date.py',
|
output: 'util/date.py',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
input: '../../../../runtime-traced-files/util/math.py',
|
input: `../../../../inputs/api-routes-python/util/math.py`,
|
||||||
output: 'util/math.py',
|
output: 'util/math.py',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@@ -133,36 +137,35 @@ describe('convert-runtime-to-plugin', () => {
|
|||||||
version: 1,
|
version: 1,
|
||||||
files: [
|
files: [
|
||||||
{
|
{
|
||||||
input: '../../../../../runtime-traced-files/api/db/[id].py',
|
input: `../../../../../inputs/api-routes-python/api/db/[id].py`,
|
||||||
output: 'api/db/[id].py',
|
output: 'api/db/[id].py',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
input: '../../../../../runtime-traced-files/api/index.py',
|
input: `../../../../../inputs/api-routes-python/api/index.py`,
|
||||||
output: 'api/index.py',
|
output: 'api/index.py',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
input:
|
input: `../../../../../inputs/api-routes-python/api/project/[aid]/[bid]/index.py`,
|
||||||
'../../../../../runtime-traced-files/api/project/[aid]/[bid]/index.py',
|
|
||||||
output: 'api/project/[aid]/[bid]/index.py',
|
output: 'api/project/[aid]/[bid]/index.py',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
input: '../../../../../runtime-traced-files/api/users/get.py',
|
input: `../../../../../inputs/api-routes-python/api/users/get.py`,
|
||||||
output: 'api/users/get.py',
|
output: 'api/users/get.py',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
input: '../../../../../runtime-traced-files/api/users/post.py',
|
input: `../../../../../inputs/api-routes-python/api/users/post.py`,
|
||||||
output: 'api/users/post.py',
|
output: 'api/users/post.py',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
input: '../../../../../runtime-traced-files/file.txt',
|
input: `../../../../../inputs/api-routes-python/file.txt`,
|
||||||
output: 'file.txt',
|
output: 'file.txt',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
input: '../../../../../runtime-traced-files/util/date.py',
|
input: `../../../../../inputs/api-routes-python/util/date.py`,
|
||||||
output: 'util/date.py',
|
output: 'util/date.py',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
input: '../../../../../runtime-traced-files/util/math.py',
|
input: `../../../../../inputs/api-routes-python/util/math.py`,
|
||||||
output: 'util/math.py',
|
output: 'util/math.py',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@@ -175,36 +178,35 @@ describe('convert-runtime-to-plugin', () => {
|
|||||||
version: 1,
|
version: 1,
|
||||||
files: [
|
files: [
|
||||||
{
|
{
|
||||||
input: '../../../../../runtime-traced-files/api/db/[id].py',
|
input: `../../../../../inputs/api-routes-python/api/db/[id].py`,
|
||||||
output: 'api/db/[id].py',
|
output: 'api/db/[id].py',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
input: '../../../../../runtime-traced-files/api/index.py',
|
input: `../../../../../inputs/api-routes-python/api/index.py`,
|
||||||
output: 'api/index.py',
|
output: 'api/index.py',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
input:
|
input: `../../../../../inputs/api-routes-python/api/project/[aid]/[bid]/index.py`,
|
||||||
'../../../../../runtime-traced-files/api/project/[aid]/[bid]/index.py',
|
|
||||||
output: 'api/project/[aid]/[bid]/index.py',
|
output: 'api/project/[aid]/[bid]/index.py',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
input: '../../../../../runtime-traced-files/api/users/get.py',
|
input: `../../../../../inputs/api-routes-python/api/users/get.py`,
|
||||||
output: 'api/users/get.py',
|
output: 'api/users/get.py',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
input: '../../../../../runtime-traced-files/api/users/post.py',
|
input: `../../../../../inputs/api-routes-python/api/users/post.py`,
|
||||||
output: 'api/users/post.py',
|
output: 'api/users/post.py',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
input: '../../../../../runtime-traced-files/file.txt',
|
input: `../../../../../inputs/api-routes-python/file.txt`,
|
||||||
output: 'file.txt',
|
output: 'file.txt',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
input: '../../../../../runtime-traced-files/util/date.py',
|
input: `../../../../../inputs/api-routes-python/util/date.py`,
|
||||||
output: 'util/date.py',
|
output: 'util/date.py',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
input: '../../../../../runtime-traced-files/util/math.py',
|
input: `../../../../../inputs/api-routes-python/util/math.py`,
|
||||||
output: 'util/math.py',
|
output: 'util/math.py',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "vercel",
|
"name": "vercel",
|
||||||
"version": "23.1.3-canary.43",
|
"version": "23.1.3-canary.47",
|
||||||
"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.25",
|
"@vercel/build-utils": "2.12.3-canary.28",
|
||||||
"@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.1",
|
||||||
"@vercel/ruby": "1.2.8-canary.4",
|
"@vercel/ruby": "1.2.8-canary.6",
|
||||||
"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.16"
|
"vercel-plugin-node": "1.12.2-canary.19"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@next/env": "11.1.2",
|
"@next/env": "11.1.2",
|
||||||
@@ -90,7 +90,7 @@
|
|||||||
"@types/update-notifier": "5.1.0",
|
"@types/update-notifier": "5.1.0",
|
||||||
"@types/which": "1.3.2",
|
"@types/which": "1.3.2",
|
||||||
"@types/write-json-file": "2.2.1",
|
"@types/write-json-file": "2.2.1",
|
||||||
"@vercel/frameworks": "0.5.1-canary.15",
|
"@vercel/frameworks": "0.5.1-canary.16",
|
||||||
"@vercel/ncc": "0.24.0",
|
"@vercel/ncc": "0.24.0",
|
||||||
"@vercel/nft": "0.17.0",
|
"@vercel/nft": "0.17.0",
|
||||||
"@zeit/fun": "0.11.2",
|
"@zeit/fun": "0.11.2",
|
||||||
|
|||||||
@@ -298,6 +298,9 @@ export default async function main(client: Client) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Required for Next.js to produce the correct `.nft.json` files.
|
||||||
|
spawnOpts.env.NEXT_PRIVATE_OUTPUT_TRACE_ROOT = baseDir;
|
||||||
|
|
||||||
// Yarn v2 PnP mode may be activated, so force
|
// Yarn v2 PnP mode may be activated, so force
|
||||||
// "node-modules" linker style
|
// "node-modules" linker style
|
||||||
const env = {
|
const env = {
|
||||||
@@ -621,16 +624,18 @@ export default async function main(client: Client) {
|
|||||||
...requiredServerFilesJson,
|
...requiredServerFilesJson,
|
||||||
appDir: '.',
|
appDir: '.',
|
||||||
files: requiredServerFilesJson.files.map((i: string) => {
|
files: requiredServerFilesJson.files.map((i: string) => {
|
||||||
const originalPath = join(dirname(distDir), i);
|
const originalPath = join(requiredServerFilesJson.appDir, i);
|
||||||
const relPath = join(OUTPUT_DIR, relative(distDir, originalPath));
|
const relPath = join(OUTPUT_DIR, relative(distDir, originalPath));
|
||||||
|
|
||||||
const absolutePath = join(cwd, relPath);
|
const absolutePath = join(cwd, relPath);
|
||||||
const output = relative(baseDir, absolutePath);
|
const output = relative(baseDir, absolutePath);
|
||||||
|
|
||||||
return {
|
return relPath === output
|
||||||
input: relPath,
|
? relPath
|
||||||
output,
|
: {
|
||||||
};
|
input: relPath,
|
||||||
|
output,
|
||||||
|
};
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vercel/client",
|
"name": "@vercel/client",
|
||||||
"version": "10.2.3-canary.26",
|
"version": "10.2.3-canary.29",
|
||||||
"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.25",
|
"@vercel/build-utils": "2.12.3-canary.28",
|
||||||
"@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",
|
||||||
|
|||||||
6
packages/frameworks/logos/remix.svg
Normal file
6
packages/frameworks/logos/remix.svg
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<svg viewBox="0 0 800 800" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M700 0H100C44.772 0 0 44.772 0 100v600c0 55.228 44.772 100 100 100h600c55.228 0 100-44.772 100-100V100C800 44.772 755.228 0 700 0Z" fill="#212121"/>
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M587.947 527.768c4.254 54.65 4.254 80.268 4.254 108.232H465.756c0-6.091.109-11.663.219-17.313.342-17.564.699-35.88-2.147-72.868-3.761-54.152-27.08-66.185-69.957-66.185H195v-98.525h204.889c54.16 0 81.241-16.476 81.241-60.098 0-38.357-27.081-61.601-81.241-61.601H195V163h227.456C545.069 163 606 220.912 606 313.42c0 69.193-42.877 114.319-100.799 121.84 48.895 9.777 77.48 37.605 82.746 92.508Z" fill="#fff"/>
|
||||||
|
<path d="M195 636v-73.447h133.697c22.332 0 27.181 16.563 27.181 26.441V636H195Z" fill="#fff"/>
|
||||||
|
<path d="M194.5 636v.5h161.878v-47.506c0-5.006-1.226-11.734-5.315-17.224-4.108-5.515-11.059-9.717-22.366-9.717H194.5V636Z" stroke="#fff" stroke-opacity=".8"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 958 B |
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vercel/frameworks",
|
"name": "@vercel/frameworks",
|
||||||
"version": "0.5.1-canary.15",
|
"version": "0.5.1-canary.16",
|
||||||
"main": "./dist/frameworks.js",
|
"main": "./dist/frameworks.js",
|
||||||
"types": "./dist/frameworks.d.ts",
|
"types": "./dist/frameworks.d.ts",
|
||||||
"files": [
|
"files": [
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"private": false,
|
"private": false,
|
||||||
"name": "vercel-plugin-go",
|
"name": "vercel-plugin-go",
|
||||||
"version": "1.0.0-canary.10",
|
"version": "1.0.0-canary.13",
|
||||||
"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.25",
|
"@vercel/build-utils": "2.12.3-canary.28",
|
||||||
"@vercel/go": "1.2.4-canary.4"
|
"@vercel/go": "1.2.4-canary.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { convertRuntimeToPlugin } from '@vercel/build-utils';
|
import { convertRuntimeToPlugin } from '@vercel/build-utils';
|
||||||
import * as go from '@vercel/go';
|
import * as go from '@vercel/go';
|
||||||
|
import { name } from '../package.json';
|
||||||
|
|
||||||
export const build = convertRuntimeToPlugin(go.build, '.go');
|
export const build = convertRuntimeToPlugin(go.build, name, '.go');
|
||||||
|
|
||||||
export const startDevServer = go.startDevServer;
|
export const startDevServer = go.startDevServer;
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
"noUnusedParameters": true,
|
"noUnusedParameters": true,
|
||||||
"outDir": "dist",
|
"outDir": "dist",
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"target": "esnext"
|
"target": "esnext",
|
||||||
|
"resolveJsonModule": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "vercel-plugin-node",
|
"name": "vercel-plugin-node",
|
||||||
"version": "1.12.2-canary.16",
|
"version": "1.12.2-canary.19",
|
||||||
"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.25",
|
"@vercel/build-utils": "2.12.3-canary.28",
|
||||||
"@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",
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ import {
|
|||||||
walkParentDirs,
|
walkParentDirs,
|
||||||
normalizePath,
|
normalizePath,
|
||||||
runPackageJsonScript,
|
runPackageJsonScript,
|
||||||
|
getInputHash,
|
||||||
} from '@vercel/build-utils';
|
} from '@vercel/build-utils';
|
||||||
import { FromSchema } from 'json-schema-to-ts';
|
import { FromSchema } from 'json-schema-to-ts';
|
||||||
import { getConfig, BaseFunctionConfigSchema } from '@vercel/static-config';
|
import { getConfig, BaseFunctionConfigSchema } from '@vercel/static-config';
|
||||||
@@ -47,8 +48,6 @@ import { AbortController } from 'abort-controller';
|
|||||||
import { Register, register } from './typescript';
|
import { Register, register } from './typescript';
|
||||||
import { pageToRoute } from './router/page-to-route';
|
import { pageToRoute } from './router/page-to-route';
|
||||||
import { isDynamicRoute } from './router/is-dynamic';
|
import { isDynamicRoute } from './router/is-dynamic';
|
||||||
import crypto from 'crypto';
|
|
||||||
import type { VercelConfig } from '@vercel/client';
|
|
||||||
|
|
||||||
export { shouldServe };
|
export { shouldServe };
|
||||||
export {
|
export {
|
||||||
@@ -380,13 +379,7 @@ function getAWSLambdaHandler(entrypoint: string, config: FunctionConfig) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO NATE: turn this into a `@vercel/plugin-utils` helper function?
|
// TODO NATE: turn this into a `@vercel/plugin-utils` helper function?
|
||||||
export async function build({
|
export async function build({ workPath }: { workPath: string }) {
|
||||||
vercelConfig,
|
|
||||||
workPath,
|
|
||||||
}: {
|
|
||||||
vercelConfig: VercelConfig;
|
|
||||||
workPath: string;
|
|
||||||
}) {
|
|
||||||
const project = new Project();
|
const project = new Project();
|
||||||
const entrypoints = await glob('api/**/*.[jt]s', workPath);
|
const entrypoints = await glob('api/**/*.[jt]s', workPath);
|
||||||
const installedPaths = new Set<string>();
|
const installedPaths = new Set<string>();
|
||||||
@@ -415,7 +408,6 @@ export async function build({
|
|||||||
}
|
}
|
||||||
|
|
||||||
await buildEntrypoint({
|
await buildEntrypoint({
|
||||||
vercelConfig,
|
|
||||||
workPath,
|
workPath,
|
||||||
entrypoint,
|
entrypoint,
|
||||||
config,
|
config,
|
||||||
@@ -425,23 +417,18 @@ export async function build({
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function buildEntrypoint({
|
export async function buildEntrypoint({
|
||||||
vercelConfig,
|
|
||||||
workPath,
|
workPath,
|
||||||
entrypoint,
|
entrypoint,
|
||||||
config,
|
config,
|
||||||
installedPaths,
|
installedPaths,
|
||||||
}: {
|
}: {
|
||||||
vercelConfig: VercelConfig;
|
|
||||||
workPath: string;
|
workPath: string;
|
||||||
entrypoint: string;
|
entrypoint: string;
|
||||||
config: FunctionConfig;
|
config: FunctionConfig;
|
||||||
installedPaths?: Set<string>;
|
installedPaths?: Set<string>;
|
||||||
}) {
|
}) {
|
||||||
// Unique hash that will be used as directory name for `.output`.
|
// Unique hash that will be used as directory name for `.output`.
|
||||||
const entrypointHash = crypto
|
const entrypointHash = 'api-routes-node-' + getInputHash(entrypoint);
|
||||||
.createHash('sha256')
|
|
||||||
.update(entrypoint)
|
|
||||||
.digest('hex');
|
|
||||||
const outputDirPath = join(workPath, '.output');
|
const outputDirPath = join(workPath, '.output');
|
||||||
|
|
||||||
const { dir, name } = parsePath(entrypoint);
|
const { dir, name } = parsePath(entrypoint);
|
||||||
@@ -561,7 +548,7 @@ export async function buildEntrypoint({
|
|||||||
runtime: nodeVersion.runtime,
|
runtime: nodeVersion.runtime,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
await updateFunctionsManifest({ vercelConfig, workPath, pages });
|
await updateFunctionsManifest({ workPath, pages });
|
||||||
|
|
||||||
// Update the `routes-mainifest.json` file with the wildcard route
|
// Update the `routes-mainifest.json` file with the wildcard route
|
||||||
// when the entrypoint is dynamic (i.e. `/api/[id].ts`).
|
// when the entrypoint is dynamic (i.e. `/api/[id].ts`).
|
||||||
|
|||||||
11
packages/plugin-node/test/build.test.ts
vendored
11
packages/plugin-node/test/build.test.ts
vendored
@@ -143,16 +143,7 @@ function withFixture<T>(
|
|||||||
await runNpmInstall(fixture);
|
await runNpmInstall(fixture);
|
||||||
}
|
}
|
||||||
|
|
||||||
let vercelConfig = {};
|
await build({ workPath: fixture });
|
||||||
try {
|
|
||||||
vercelConfig = JSON.parse(
|
|
||||||
await fsp.readFile(path.join(fixture, 'vercel.json'), 'utf8')
|
|
||||||
);
|
|
||||||
} catch (e) {
|
|
||||||
// Consume error
|
|
||||||
}
|
|
||||||
|
|
||||||
await build({ vercelConfig, workPath: fixture });
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return await t({ fixture, fetch });
|
return await t({ fixture, fetch });
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"private": false,
|
"private": false,
|
||||||
"name": "vercel-plugin-python",
|
"name": "vercel-plugin-python",
|
||||||
"version": "1.0.0-canary.11",
|
"version": "1.0.0-canary.14",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"files": [
|
"files": [
|
||||||
@@ -17,8 +17,8 @@
|
|||||||
"prepublishOnly": "tsc"
|
"prepublishOnly": "tsc"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vercel/build-utils": "2.12.3-canary.25",
|
"@vercel/build-utils": "2.12.3-canary.28",
|
||||||
"@vercel/python": "2.1.2-canary.0"
|
"@vercel/python": "2.1.2-canary.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "*",
|
"@types/node": "*",
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { convertRuntimeToPlugin } from '@vercel/build-utils';
|
import { convertRuntimeToPlugin } from '@vercel/build-utils';
|
||||||
import * as python from '@vercel/python';
|
import * as python from '@vercel/python';
|
||||||
|
import { name } from '../package.json';
|
||||||
|
|
||||||
export const build = convertRuntimeToPlugin(python.build, '.py');
|
export const build = convertRuntimeToPlugin(python.build, name, '.py');
|
||||||
|
|
||||||
//export const startDevServer = python.startDevServer;
|
//export const startDevServer = python.startDevServer;
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
"outDir": "dist",
|
"outDir": "dist",
|
||||||
"types": ["node"],
|
"types": ["node"],
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"target": "esnext"
|
"target": "esnext",
|
||||||
|
"resolveJsonModule": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"private": false,
|
"private": false,
|
||||||
"name": "vercel-plugin-ruby",
|
"name": "vercel-plugin-ruby",
|
||||||
"version": "1.0.0-canary.9",
|
"version": "1.0.0-canary.12",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"files": [
|
"files": [
|
||||||
@@ -17,8 +17,8 @@
|
|||||||
"prepublishOnly": "tsc"
|
"prepublishOnly": "tsc"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vercel/build-utils": "2.12.3-canary.25",
|
"@vercel/build-utils": "2.12.3-canary.28",
|
||||||
"@vercel/ruby": "1.2.8-canary.4"
|
"@vercel/ruby": "1.2.8-canary.6"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "*",
|
"@types/node": "*",
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { convertRuntimeToPlugin } from '@vercel/build-utils';
|
import { convertRuntimeToPlugin } from '@vercel/build-utils';
|
||||||
import * as ruby from '@vercel/ruby';
|
import * as ruby from '@vercel/ruby';
|
||||||
|
import { name } from '../package.json';
|
||||||
|
|
||||||
export const build = convertRuntimeToPlugin(ruby.build, '.rb');
|
export const build = convertRuntimeToPlugin(ruby.build, name, '.rb');
|
||||||
|
|
||||||
//export const startDevServer = ruby.startDevServer;
|
//export const startDevServer = ruby.startDevServer;
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
"outDir": "dist",
|
"outDir": "dist",
|
||||||
"types": ["node"],
|
"types": ["node"],
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"target": "esnext"
|
"target": "esnext",
|
||||||
|
"resolveJsonModule": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vercel/python",
|
"name": "@vercel/python",
|
||||||
"version": "2.1.2-canary.0",
|
"version": "2.1.2-canary.1",
|
||||||
"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",
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { relative, basename } from 'path';
|
||||||
import execa from 'execa';
|
import execa from 'execa';
|
||||||
import { Meta, debug } from '@vercel/build-utils';
|
import { Meta, debug } from '@vercel/build-utils';
|
||||||
|
|
||||||
@@ -135,6 +136,18 @@ export async function installRequirementsFile({
|
|||||||
meta,
|
meta,
|
||||||
args = [],
|
args = [],
|
||||||
}: InstallRequirementsFileArg) {
|
}: InstallRequirementsFileArg) {
|
||||||
|
const fileAtRoot = relative(workPath, filePath) === basename(filePath);
|
||||||
|
|
||||||
|
// If the `requirements.txt` file is located in the Root Directory of the project and
|
||||||
|
// the new File System API is used (`avoidTopLevelInstall`), the Install Command
|
||||||
|
// will have already installed its dependencies, so we don't need to do it again.
|
||||||
|
if (meta.avoidTopLevelInstall && fileAtRoot) {
|
||||||
|
debug(
|
||||||
|
`Skipping requirements file installation, already installed by Install Command`
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
meta.isDev &&
|
meta.isDev &&
|
||||||
(await areRequirementsInstalled(pythonPath, filePath, workPath))
|
(await areRequirementsInstalled(pythonPath, filePath, workPath))
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { join, dirname } from 'path';
|
import { join, dirname, relative } from 'path';
|
||||||
import execa from 'execa';
|
import execa from 'execa';
|
||||||
import {
|
import {
|
||||||
ensureDir,
|
ensureDir,
|
||||||
@@ -85,10 +85,12 @@ export async function build({
|
|||||||
}: BuildOptions) {
|
}: BuildOptions) {
|
||||||
await download(files, workPath, meta);
|
await download(files, workPath, meta);
|
||||||
const entrypointFsDirname = join(workPath, dirname(entrypoint));
|
const entrypointFsDirname = join(workPath, dirname(entrypoint));
|
||||||
|
const gemfileName = 'Gemfile';
|
||||||
|
|
||||||
const gemfilePath = await walkParentDirs({
|
const gemfilePath = await walkParentDirs({
|
||||||
base: workPath,
|
base: workPath,
|
||||||
start: entrypointFsDirname,
|
start: entrypointFsDirname,
|
||||||
filename: 'Gemfile',
|
filename: gemfileName,
|
||||||
});
|
});
|
||||||
const gemfileContents = gemfilePath
|
const gemfileContents = gemfilePath
|
||||||
? await readFile(gemfilePath, 'utf8')
|
? await readFile(gemfilePath, 'utf8')
|
||||||
@@ -130,15 +132,24 @@ export async function build({
|
|||||||
'did not find a vendor directory but found a Gemfile, bundling gems...'
|
'did not find a vendor directory but found a Gemfile, bundling gems...'
|
||||||
);
|
);
|
||||||
|
|
||||||
// try installing. this won't work if native extesions are required.
|
const fileAtRoot = relative(workPath, gemfilePath) === gemfileName;
|
||||||
// if that's the case, gems should be vendored locally before deploying.
|
|
||||||
try {
|
// If the `Gemfile` is located in the Root Directory of the project and
|
||||||
await bundleInstall(bundlerPath, bundleDir, gemfilePath);
|
// the new File System API is used (`avoidTopLevelInstall`), the Install Command
|
||||||
} catch (err) {
|
// will have already installed its dependencies, so we don't need to do it again.
|
||||||
debug(
|
if (meta.avoidTopLevelInstall && fileAtRoot) {
|
||||||
'unable to build gems from Gemfile. vendor the gems locally with "bundle install --deployment" and retry.'
|
debug('Skipping `bundle install` — already handled by Install Command');
|
||||||
);
|
} else {
|
||||||
throw err;
|
// try installing. this won't work if native extesions are required.
|
||||||
|
// if that's the case, gems should be vendored locally before deploying.
|
||||||
|
try {
|
||||||
|
await bundleInstall(bundlerPath, bundleDir, gemfilePath);
|
||||||
|
} catch (err) {
|
||||||
|
debug(
|
||||||
|
'unable to build gems from Gemfile. vendor the gems locally with "bundle install --deployment" and retry.'
|
||||||
|
);
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -66,6 +66,23 @@ export async function installBundler(meta: Meta, gemfileContents: string) {
|
|||||||
gemfileContents
|
gemfileContents
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// If the new File System API is used (`avoidTopLevelInstall`), the Install Command
|
||||||
|
// will have already installed the dependencies, so we don't need to do it again.
|
||||||
|
if (meta.avoidTopLevelInstall) {
|
||||||
|
debug(
|
||||||
|
`Skipping bundler installation, already installed by Install Command`
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
gemHome,
|
||||||
|
rubyPath,
|
||||||
|
gemPath,
|
||||||
|
vendorPath,
|
||||||
|
runtime,
|
||||||
|
bundlerPath: join(gemHome, 'bin', 'bundler'),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
debug('installing bundler...');
|
debug('installing bundler...');
|
||||||
await execa(gemPath, ['install', 'bundler', '--no-document'], {
|
await execa(gemPath, ['install', 'bundler', '--no-document'], {
|
||||||
stdio: 'pipe',
|
stdio: 'pipe',
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@vercel/ruby",
|
"name": "@vercel/ruby",
|
||||||
"author": "Nathan Cahill <nathan@nathancahill.com>",
|
"author": "Nathan Cahill <nathan@nathancahill.com>",
|
||||||
"version": "1.2.8-canary.4",
|
"version": "1.2.8-canary.6",
|
||||||
"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",
|
||||||
|
|||||||
2
packages/ruby/test/fixtures/02-cowsay-vendored/.bundle/config
vendored
Normal file
2
packages/ruby/test/fixtures/02-cowsay-vendored/.bundle/config
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
---
|
||||||
|
BUNDLE_PATH: "vendor/bundle"
|
||||||
@@ -2,6 +2,6 @@
|
|||||||
|
|
||||||
source "https://rubygems.org"
|
source "https://rubygems.org"
|
||||||
|
|
||||||
ruby "~> 2.5.0"
|
ruby "~> 2.7.0"
|
||||||
|
|
||||||
gem "cowsay", "~> 0.3.0"
|
gem "cowsay", "~> 0.3.0"
|
||||||
|
|||||||
16
packages/ruby/test/fixtures/02-cowsay-vendored/Gemfile.lock
vendored
Normal file
16
packages/ruby/test/fixtures/02-cowsay-vendored/Gemfile.lock
vendored
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
GEM
|
||||||
|
remote: https://rubygems.org/
|
||||||
|
specs:
|
||||||
|
cowsay (0.3.0)
|
||||||
|
|
||||||
|
PLATFORMS
|
||||||
|
x86_64-darwin-21
|
||||||
|
|
||||||
|
DEPENDENCIES
|
||||||
|
cowsay (~> 0.3.0)
|
||||||
|
|
||||||
|
RUBY VERSION
|
||||||
|
ruby 2.7.5p203
|
||||||
|
|
||||||
|
BUNDLED WITH
|
||||||
|
2.2.22
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"version": 2,
|
"version": 2,
|
||||||
"builds": [{ "src": "index.rb", "use": "@vercel/ruby" }],
|
"builds": [{ "src": "index.rb", "use": "@vercel/ruby" }],
|
||||||
"build": { "env": { "RUBY_VERSION": "2.5.x" } },
|
"build": { "env": { "RUBY_VERSION": "2.7.x" } },
|
||||||
"probes": [{ "path": "/", "mustContain": "gem:RANDOMNESS_PLACEHOLDER" }]
|
"probes": [{ "path": "/", "mustContain": "gem:RANDOMNESS_PLACEHOLDER" }]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,19 +14,17 @@ Gem::Specification.new do |s|
|
|||||||
s.executables = ["cowsay".freeze]
|
s.executables = ["cowsay".freeze]
|
||||||
s.files = ["bin/cowsay".freeze]
|
s.files = ["bin/cowsay".freeze]
|
||||||
s.homepage = "https://github.com/moneydesktop/cowsay".freeze
|
s.homepage = "https://github.com/moneydesktop/cowsay".freeze
|
||||||
s.rubygems_version = "3.0.3".freeze
|
s.rubygems_version = "3.2.22".freeze
|
||||||
s.summary = "ASCII art avatars emote your messages".freeze
|
s.summary = "ASCII art avatars emote your messages".freeze
|
||||||
|
|
||||||
s.installed_by_version = "3.0.3" if s.respond_to? :installed_by_version
|
s.installed_by_version = "3.2.22" if s.respond_to? :installed_by_version
|
||||||
|
|
||||||
if s.respond_to? :specification_version then
|
if s.respond_to? :specification_version then
|
||||||
s.specification_version = 4
|
s.specification_version = 4
|
||||||
|
end
|
||||||
|
|
||||||
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
if s.respond_to? :add_runtime_dependency then
|
||||||
s.add_development_dependency(%q<rake>.freeze, [">= 0"])
|
s.add_development_dependency(%q<rake>.freeze, [">= 0"])
|
||||||
else
|
|
||||||
s.add_dependency(%q<rake>.freeze, [">= 0"])
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
s.add_dependency(%q<rake>.freeze, [">= 0"])
|
s.add_dependency(%q<rake>.freeze, [">= 0"])
|
||||||
end
|
end
|
||||||
2
packages/ruby/test/fixtures/04-cowsay-vendored-nested/.bundle/config
vendored
Normal file
2
packages/ruby/test/fixtures/04-cowsay-vendored-nested/.bundle/config
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
---
|
||||||
|
BUNDLE_PATH: "vendor/bundle"
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"version": 2,
|
"version": 2,
|
||||||
"builds": [{ "src": "project/index.rb", "use": "@vercel/ruby" }],
|
"builds": [{ "src": "project/index.rb", "use": "@vercel/ruby" }],
|
||||||
"build": { "env": { "RUBY_VERSION": "2.5.x" } },
|
"build": { "env": { "RUBY_VERSION": "2.7.x" } },
|
||||||
"probes": [
|
"probes": [
|
||||||
{ "path": "/project/", "mustContain": "gem:RANDOMNESS_PLACEHOLDER" }
|
{ "path": "/project/", "mustContain": "gem:RANDOMNESS_PLACEHOLDER" }
|
||||||
]
|
]
|
||||||
|
|||||||
2
packages/ruby/test/fixtures/04-cowsay-vendored-nested/project/.bundle/config
vendored
Normal file
2
packages/ruby/test/fixtures/04-cowsay-vendored-nested/project/.bundle/config
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
---
|
||||||
|
BUNDLE_PATH: "vendor/bundle"
|
||||||
@@ -2,6 +2,6 @@
|
|||||||
|
|
||||||
source "https://rubygems.org"
|
source "https://rubygems.org"
|
||||||
|
|
||||||
ruby "~> 2.5.0"
|
ruby "~> 2.7.0"
|
||||||
|
|
||||||
gem "cowsay", "~> 0.3.0"
|
gem "cowsay", "~> 0.3.0"
|
||||||
|
|||||||
16
packages/ruby/test/fixtures/04-cowsay-vendored-nested/project/Gemfile.lock
vendored
Normal file
16
packages/ruby/test/fixtures/04-cowsay-vendored-nested/project/Gemfile.lock
vendored
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
GEM
|
||||||
|
remote: https://rubygems.org/
|
||||||
|
specs:
|
||||||
|
cowsay (0.3.0)
|
||||||
|
|
||||||
|
PLATFORMS
|
||||||
|
x86_64-darwin-21
|
||||||
|
|
||||||
|
DEPENDENCIES
|
||||||
|
cowsay (~> 0.3.0)
|
||||||
|
|
||||||
|
RUBY VERSION
|
||||||
|
ruby 2.7.5p203
|
||||||
|
|
||||||
|
BUNDLED WITH
|
||||||
|
2.2.22
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user