mirror of
https://github.com/LukeHagar/vercel.git
synced 2025-12-08 21:07:46 +00:00
[cli][node] Re-apply @TooTallNate's vc dev updates (#4254)
This reverts commit 099bc6dbf6 (#4231).
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -10,8 +10,6 @@ coverage.lcov
|
|||||||
*.swp
|
*.swp
|
||||||
*.bak
|
*.bak
|
||||||
*.tgz
|
*.tgz
|
||||||
packages/now-cli/.builders
|
|
||||||
packages/now-cli/assets
|
|
||||||
packages/now-cli/src/util/dev/templates/*.ts
|
packages/now-cli/src/util/dev/templates/*.ts
|
||||||
packages/now-cli/src/util/constants.ts
|
packages/now-cli/src/util/constants.ts
|
||||||
packages/now-cli/test/**/yarn.lock
|
packages/now-cli/test/**/yarn.lock
|
||||||
|
|||||||
@@ -21,6 +21,9 @@ export default withApiHandler(async function(
|
|||||||
) {
|
) {
|
||||||
res.setHeader('Access-Control-Allow-Origin', '*');
|
res.setHeader('Access-Control-Allow-Origin', '*');
|
||||||
res.setHeader('Access-Control-Allow-Methods', 'GET');
|
res.setHeader('Access-Control-Allow-Methods', 'GET');
|
||||||
res.setHeader('Access-Control-Allow-Headers', 'Authorization, Accept, Content-Type');
|
res.setHeader(
|
||||||
|
'Access-Control-Allow-Headers',
|
||||||
|
'Authorization, Accept, Content-Type'
|
||||||
|
);
|
||||||
return res.status(200).json(frameworks);
|
return res.status(200).json(frameworks);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -188,6 +188,34 @@ export interface ShouldServeOptions {
|
|||||||
config: Config;
|
config: Config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface StartDevServerOptions {
|
||||||
|
/**
|
||||||
|
* Name of entrypoint file for this particular build job. Value
|
||||||
|
* `files[entrypoint]` is guaranteed to exist and be a valid File reference.
|
||||||
|
* `entrypoint` is always a discrete file and never a glob, since globs are
|
||||||
|
* expanded into separate builds at deployment time.
|
||||||
|
*/
|
||||||
|
entrypoint: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A writable temporary directory where you are encouraged to perform your
|
||||||
|
* build process. This directory will be populated with the restored cache.
|
||||||
|
*/
|
||||||
|
workPath: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An arbitrary object passed by the user in the build definition defined
|
||||||
|
* in `now.json`.
|
||||||
|
*/
|
||||||
|
config: Config;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runtime environment variables configuration from the project's `now.json`
|
||||||
|
* and local `.env` file.
|
||||||
|
*/
|
||||||
|
env: Env;
|
||||||
|
}
|
||||||
|
|
||||||
export interface StartDevServerSuccess {
|
export interface StartDevServerSuccess {
|
||||||
/**
|
/**
|
||||||
* Port number where the dev server can be connected to, assumed to be running
|
* Port number where the dev server can be connected to, assumed to be running
|
||||||
@@ -213,7 +241,7 @@ export type StartDevServerResult = StartDevServerSuccess | null;
|
|||||||
* Source: https://gist.github.com/iainreid820/5c1cc527fe6b5b7dba41fec7fe54bf6e
|
* Source: https://gist.github.com/iainreid820/5c1cc527fe6b5b7dba41fec7fe54bf6e
|
||||||
*/
|
*/
|
||||||
// eslint-disable-next-line @typescript-eslint/no-namespace
|
// eslint-disable-next-line @typescript-eslint/no-namespace
|
||||||
namespace PackageJson {
|
export namespace PackageJson {
|
||||||
/**
|
/**
|
||||||
* An author or contributor
|
* An author or contributor
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -61,9 +61,19 @@
|
|||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 10"
|
"node": ">= 10"
|
||||||
},
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@vercel/build-utils": "2.3.1",
|
||||||
|
"@vercel/go": "1.1.1",
|
||||||
|
"@vercel/next": "2.6.1",
|
||||||
|
"@vercel/node": "1.6.1",
|
||||||
|
"@vercel/python": "1.2.1",
|
||||||
|
"@vercel/ruby": "1.2.1",
|
||||||
|
"@vercel/static-build": "0.17.1"
|
||||||
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@sentry/node": "5.5.0",
|
"@sentry/node": "5.5.0",
|
||||||
"@sindresorhus/slugify": "0.11.0",
|
"@sindresorhus/slugify": "0.11.0",
|
||||||
|
"@tootallnate/once": "1.1.2",
|
||||||
"@types/ansi-escapes": "3.0.0",
|
"@types/ansi-escapes": "3.0.0",
|
||||||
"@types/ansi-regex": "4.0.0",
|
"@types/ansi-regex": "4.0.0",
|
||||||
"@types/async-retry": "1.2.1",
|
"@types/async-retry": "1.2.1",
|
||||||
@@ -179,7 +189,6 @@
|
|||||||
"which": "2.0.2",
|
"which": "2.0.2",
|
||||||
"which-promise": "1.0.0",
|
"which-promise": "1.0.0",
|
||||||
"write-json-file": "2.2.0",
|
"write-json-file": "2.2.0",
|
||||||
"xdg-app-paths": "5.1.0",
|
"xdg-app-paths": "5.1.0"
|
||||||
"yarn": "1.22.0"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,58 +1,10 @@
|
|||||||
import cpy from 'cpy';
|
import cpy from 'cpy';
|
||||||
import tar from 'tar-fs';
|
|
||||||
import execa from 'execa';
|
import execa from 'execa';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
import pipe from 'promisepipe';
|
import { remove, writeFile } from 'fs-extra';
|
||||||
import { createGzip } from 'zlib';
|
|
||||||
import {
|
|
||||||
createWriteStream,
|
|
||||||
mkdirp,
|
|
||||||
remove,
|
|
||||||
writeJSON,
|
|
||||||
writeFile,
|
|
||||||
} from 'fs-extra';
|
|
||||||
|
|
||||||
import { getDistTag } from '../src/util/get-dist-tag';
|
|
||||||
import pkg from '../package.json';
|
|
||||||
import { getBundledBuilders } from '../src/util/dev/get-bundled-builders';
|
|
||||||
|
|
||||||
const dirRoot = join(__dirname, '..');
|
const dirRoot = join(__dirname, '..');
|
||||||
|
|
||||||
async function createBuildersTarball() {
|
|
||||||
const distTag = getDistTag(pkg.version);
|
|
||||||
const builders = Array.from(getBundledBuilders()).map(b => `${b}@${distTag}`);
|
|
||||||
console.log(`Creating builders tarball with: ${builders.join(', ')}`);
|
|
||||||
|
|
||||||
const buildersDir = join(dirRoot, '.builders');
|
|
||||||
const assetsDir = join(dirRoot, 'assets');
|
|
||||||
await mkdirp(buildersDir);
|
|
||||||
await mkdirp(assetsDir);
|
|
||||||
|
|
||||||
const buildersTarballPath = join(assetsDir, 'builders.tar.gz');
|
|
||||||
|
|
||||||
try {
|
|
||||||
const buildersPkg = join(buildersDir, 'package.json');
|
|
||||||
await writeJSON(buildersPkg, { private: true }, { flag: 'wx' });
|
|
||||||
} catch (err) {
|
|
||||||
if (err.code !== 'EEXIST') {
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const yarn = join(dirRoot, '../../node_modules/yarn/bin/yarn.js');
|
|
||||||
await execa(process.execPath, [yarn, 'add', '--no-lockfile', ...builders], {
|
|
||||||
cwd: buildersDir,
|
|
||||||
stdio: 'inherit',
|
|
||||||
});
|
|
||||||
|
|
||||||
const packer = tar.pack(buildersDir);
|
|
||||||
await pipe(
|
|
||||||
packer,
|
|
||||||
createGzip(),
|
|
||||||
createWriteStream(buildersTarballPath)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function createConstants() {
|
async function createConstants() {
|
||||||
console.log('Creating constants.ts');
|
console.log('Creating constants.ts');
|
||||||
const filename = join(dirRoot, 'src/util/constants.ts');
|
const filename = join(dirRoot, 'src/util/constants.ts');
|
||||||
@@ -81,10 +33,6 @@ async function main() {
|
|||||||
// During local development, these secrets will be empty.
|
// During local development, these secrets will be empty.
|
||||||
await createConstants();
|
await createConstants();
|
||||||
|
|
||||||
// Create a tarball from all the `@now` scoped builders which will be bundled
|
|
||||||
// with Now CLI
|
|
||||||
await createBuildersTarball();
|
|
||||||
|
|
||||||
// `now dev` uses chokidar to watch the filesystem, but opts-out of the
|
// `now dev` uses chokidar to watch the filesystem, but opts-out of the
|
||||||
// `fsevents` feature using `useFsEvents: false`, so delete the module here so
|
// `fsevents` feature using `useFsEvents: false`, so delete the module here so
|
||||||
// that it is not compiled by ncc, which makes the npm package size larger
|
// that it is not compiled by ncc, which makes the npm package size larger
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ export default async function dev(
|
|||||||
});
|
});
|
||||||
|
|
||||||
process.once('SIGINT', () => devServer.stop());
|
process.once('SIGINT', () => devServer.stop());
|
||||||
|
process.once('SIGTERM', () => devServer.stop());
|
||||||
|
|
||||||
await devServer.start(...listen);
|
await devServer.start(...listen);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,23 +1,13 @@
|
|||||||
import execa from 'execa';
|
import execa from 'execa';
|
||||||
import semver from 'semver';
|
import semver from 'semver';
|
||||||
import pipe from 'promisepipe';
|
|
||||||
import retry from 'async-retry';
|
import retry from 'async-retry';
|
||||||
import npa from 'npm-package-arg';
|
import npa from 'npm-package-arg';
|
||||||
import pluralize from 'pluralize';
|
import pluralize from 'pluralize';
|
||||||
import { extract } from 'tar-fs';
|
import { basename, join } from 'path';
|
||||||
import { createHash } from 'crypto';
|
import { PackageJson } from '@vercel/build-utils';
|
||||||
import { createGunzip } from 'zlib';
|
|
||||||
import { join } from 'path';
|
|
||||||
import XDGAppPaths from 'xdg-app-paths';
|
import XDGAppPaths from 'xdg-app-paths';
|
||||||
import { PackageJson, isStaticRuntime } from '@vercel/build-utils';
|
import { mkdirp, readJSON, writeJSON } from 'fs-extra';
|
||||||
import {
|
import nowCliPkg from '../pkg';
|
||||||
createReadStream,
|
|
||||||
mkdirp,
|
|
||||||
readFile,
|
|
||||||
readJSON,
|
|
||||||
writeFile,
|
|
||||||
} from 'fs-extra';
|
|
||||||
import pkg from '../../../package.json';
|
|
||||||
|
|
||||||
import { NoBuilderCacheError } from '../errors-ts';
|
import { NoBuilderCacheError } from '../errors-ts';
|
||||||
import { Output } from '../output';
|
import { Output } from '../output';
|
||||||
@@ -34,6 +24,7 @@ const registryTypes = new Set(['version', 'tag', 'range']);
|
|||||||
const createStaticBuilder = (scope: string): BuilderWithPackage => {
|
const createStaticBuilder = (scope: string): BuilderWithPackage => {
|
||||||
return {
|
return {
|
||||||
runInProcess: true,
|
runInProcess: true,
|
||||||
|
requirePath: `${scope}/static`,
|
||||||
builder: Object.freeze(staticBuilder),
|
builder: Object.freeze(staticBuilder),
|
||||||
package: Object.freeze({ name: `@${scope}/static`, version: '' }),
|
package: Object.freeze({ name: `@${scope}/static`, version: '' }),
|
||||||
};
|
};
|
||||||
@@ -44,36 +35,10 @@ const localBuilders: { [key: string]: BuilderWithPackage } = {
|
|||||||
'@vercel/static': createStaticBuilder('vercel'),
|
'@vercel/static': createStaticBuilder('vercel'),
|
||||||
};
|
};
|
||||||
|
|
||||||
const distTag = getDistTag(pkg.version);
|
const distTag = nowCliPkg.version ? getDistTag(nowCliPkg.version) : 'canary';
|
||||||
|
|
||||||
export const cacheDirPromise = prepareCacheDir();
|
export const cacheDirPromise = prepareCacheDir();
|
||||||
export const builderDirPromise = prepareBuilderDir();
|
export const builderDirPromise = prepareBuilderDir();
|
||||||
export const builderModulePathPromise = prepareBuilderModulePath();
|
|
||||||
|
|
||||||
function readFileOrNull(
|
|
||||||
filePath: string,
|
|
||||||
encoding?: null
|
|
||||||
): Promise<Buffer | null>;
|
|
||||||
function readFileOrNull(
|
|
||||||
filePath: string,
|
|
||||||
encoding: string
|
|
||||||
): Promise<string | null>;
|
|
||||||
async function readFileOrNull(
|
|
||||||
filePath: string,
|
|
||||||
encoding?: string | null
|
|
||||||
): Promise<Buffer | string | null> {
|
|
||||||
try {
|
|
||||||
if (encoding) {
|
|
||||||
return await readFile(filePath, encoding);
|
|
||||||
}
|
|
||||||
return await readFile(filePath);
|
|
||||||
} catch (err) {
|
|
||||||
if (err.code === 'ENOENT') {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepare cache directory for installing now-builders
|
* Prepare cache directory for installing now-builders
|
||||||
@@ -94,51 +59,19 @@ export async function prepareBuilderDir() {
|
|||||||
const builderDir = join(await cacheDirPromise, 'builders');
|
const builderDir = join(await cacheDirPromise, 'builders');
|
||||||
await mkdirp(builderDir);
|
await mkdirp(builderDir);
|
||||||
|
|
||||||
// Extract the bundled `builders.tar.gz` file, if necessary
|
// Create an empty `package.json` file, only if one does not already exist
|
||||||
const bundledTarballPath = join(__dirname, '../../../assets/builders.tar.gz');
|
try {
|
||||||
|
const buildersPkg = join(builderDir, 'package.json');
|
||||||
const existingPackageJson =
|
await writeJSON(buildersPkg, { private: true }, { flag: 'wx' });
|
||||||
(await readFileOrNull(join(builderDir, 'package.json'), 'utf8')) || '{}';
|
} catch (err) {
|
||||||
const { dependencies = {} } = JSON.parse(existingPackageJson);
|
if (err.code !== 'EEXIST') {
|
||||||
|
throw err;
|
||||||
if (!hasBundledBuilders(dependencies)) {
|
}
|
||||||
const extractor = extract(builderDir);
|
|
||||||
await pipe(
|
|
||||||
createReadStream(bundledTarballPath),
|
|
||||||
createGunzip(),
|
|
||||||
extractor
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return builderDir;
|
return builderDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function prepareBuilderModulePath() {
|
|
||||||
const [builderDir, builderContents] = await Promise.all([
|
|
||||||
builderDirPromise,
|
|
||||||
readFile(join(__dirname, 'builder-worker.js')),
|
|
||||||
]);
|
|
||||||
let needsWrite = false;
|
|
||||||
const builderSha = getSha(builderContents);
|
|
||||||
const cachedBuilderPath = join(builderDir, 'builder.js');
|
|
||||||
|
|
||||||
const cachedBuilderContents = await readFileOrNull(cachedBuilderPath);
|
|
||||||
if (cachedBuilderContents) {
|
|
||||||
const cachedBuilderSha = getSha(cachedBuilderContents);
|
|
||||||
if (builderSha !== cachedBuilderSha) {
|
|
||||||
needsWrite = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
needsWrite = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (needsWrite) {
|
|
||||||
await writeFile(cachedBuilderPath, builderContents);
|
|
||||||
}
|
|
||||||
|
|
||||||
return cachedBuilderPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getNpmVersion(use = ''): string {
|
function getNpmVersion(use = ''): string {
|
||||||
const parsed = npa(use);
|
const parsed = npa(use);
|
||||||
if (registryTypes.has(parsed.type)) {
|
if (registryTypes.has(parsed.type)) {
|
||||||
@@ -168,12 +101,20 @@ function parseVersionSafe(rawSpec: string) {
|
|||||||
export function filterPackage(
|
export function filterPackage(
|
||||||
builderSpec: string,
|
builderSpec: string,
|
||||||
distTag: string,
|
distTag: string,
|
||||||
buildersPkg: PackageJson
|
buildersPkg: PackageJson,
|
||||||
|
nowCliPkg: PackageJson
|
||||||
) {
|
) {
|
||||||
if (builderSpec in localBuilders) return false;
|
if (builderSpec in localBuilders) return false;
|
||||||
const parsed = npa(builderSpec);
|
const parsed = npa(builderSpec);
|
||||||
const parsedVersion = parseVersionSafe(parsed.rawSpec);
|
const parsedVersion = parseVersionSafe(parsed.rawSpec);
|
||||||
// skip install of already installed Runtime
|
|
||||||
|
// If it's a builder that is part of Now CLI's `dependencies` then
|
||||||
|
// the builder is already installed into `node_modules`
|
||||||
|
if (isBundledBuilder(parsed, nowCliPkg)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip install of already installed Runtime
|
||||||
if (
|
if (
|
||||||
parsed.name &&
|
parsed.name &&
|
||||||
parsed.type === 'version' &&
|
parsed.type === 'version' &&
|
||||||
@@ -215,7 +156,6 @@ export function filterPackage(
|
|||||||
*/
|
*/
|
||||||
export async function installBuilders(
|
export async function installBuilders(
|
||||||
packagesSet: Set<string>,
|
packagesSet: Set<string>,
|
||||||
yarnDir: string,
|
|
||||||
output: Output,
|
output: Output,
|
||||||
builderDir?: string
|
builderDir?: string
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
@@ -231,9 +171,12 @@ export async function installBuilders(
|
|||||||
if (!builderDir) {
|
if (!builderDir) {
|
||||||
builderDir = await builderDirPromise;
|
builderDir = await builderDirPromise;
|
||||||
}
|
}
|
||||||
const yarnPath = join(yarnDir, 'yarn');
|
|
||||||
const buildersPkgPath = join(builderDir, 'package.json');
|
const buildersPkgPath = join(builderDir, 'package.json');
|
||||||
const buildersPkgBefore = await readJSON(buildersPkgPath);
|
const buildersPkgBefore = await readJSON(buildersPkgPath);
|
||||||
|
const depsBefore = {
|
||||||
|
...buildersPkgBefore.devDependencies,
|
||||||
|
...buildersPkgBefore.dependencies,
|
||||||
|
};
|
||||||
|
|
||||||
packages.push(
|
packages.push(
|
||||||
getBuildUtils(packages, 'vercel'),
|
getBuildUtils(packages, 'vercel'),
|
||||||
@@ -242,7 +185,7 @@ export async function installBuilders(
|
|||||||
|
|
||||||
// Filter out any packages that come packaged with `now-cli`
|
// Filter out any packages that come packaged with `now-cli`
|
||||||
const packagesToInstall = packages.filter(p =>
|
const packagesToInstall = packages.filter(p =>
|
||||||
filterPackage(p, distTag, buildersPkgBefore)
|
filterPackage(p, distTag, buildersPkgBefore, nowCliPkg)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (packagesToInstall.length === 0) {
|
if (packagesToInstall.length === 0) {
|
||||||
@@ -261,14 +204,11 @@ export async function installBuilders(
|
|||||||
await retry(
|
await retry(
|
||||||
() =>
|
() =>
|
||||||
execa(
|
execa(
|
||||||
process.execPath,
|
'npm',
|
||||||
[
|
[
|
||||||
yarnPath,
|
'install',
|
||||||
'add',
|
'--save-exact',
|
||||||
'--exact',
|
'--no-package-lock',
|
||||||
'--no-lockfile',
|
|
||||||
'--non-interactive',
|
|
||||||
'--ignore-workspace-root-check',
|
|
||||||
...packagesToInstall,
|
...packagesToInstall,
|
||||||
],
|
],
|
||||||
{
|
{
|
||||||
@@ -283,8 +223,12 @@ export async function installBuilders(
|
|||||||
|
|
||||||
const updatedPackages: string[] = [];
|
const updatedPackages: string[] = [];
|
||||||
const buildersPkgAfter = await readJSON(buildersPkgPath);
|
const buildersPkgAfter = await readJSON(buildersPkgPath);
|
||||||
for (const [name, version] of Object.entries(buildersPkgAfter.dependencies)) {
|
const depsAfter = {
|
||||||
if (version !== buildersPkgBefore.dependencies[name]) {
|
...buildersPkgAfter.devDependencies,
|
||||||
|
...buildersPkgAfter.dependencies,
|
||||||
|
};
|
||||||
|
for (const [name, version] of Object.entries(depsAfter)) {
|
||||||
|
if (version !== depsBefore[name]) {
|
||||||
output.debug(`Runtime "${name}" updated to version \`${version}\``);
|
output.debug(`Runtime "${name}" updated to version \`${version}\``);
|
||||||
updatedPackages.push(name);
|
updatedPackages.push(name);
|
||||||
}
|
}
|
||||||
@@ -295,7 +239,6 @@ export async function installBuilders(
|
|||||||
|
|
||||||
export async function updateBuilders(
|
export async function updateBuilders(
|
||||||
packagesSet: Set<string>,
|
packagesSet: Set<string>,
|
||||||
yarnDir: string,
|
|
||||||
output: Output,
|
output: Output,
|
||||||
builderDir?: string
|
builderDir?: string
|
||||||
): Promise<string[]> {
|
): Promise<string[]> {
|
||||||
@@ -303,46 +246,59 @@ export async function updateBuilders(
|
|||||||
builderDir = await builderDirPromise;
|
builderDir = await builderDirPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const updatedPackages: string[] = [];
|
||||||
const packages = Array.from(packagesSet);
|
const packages = Array.from(packagesSet);
|
||||||
const yarnPath = join(yarnDir, 'yarn');
|
|
||||||
const buildersPkgPath = join(builderDir, 'package.json');
|
const buildersPkgPath = join(builderDir, 'package.json');
|
||||||
const buildersPkgBefore = await readJSON(buildersPkgPath);
|
const buildersPkgBefore = await readJSON(buildersPkgPath);
|
||||||
|
const depsBefore = {
|
||||||
|
...buildersPkgBefore.devDependencies,
|
||||||
|
...buildersPkgBefore.dependencies,
|
||||||
|
};
|
||||||
|
|
||||||
packages.push(
|
const packagesToUpdate = packages.filter(p => {
|
||||||
getBuildUtils(packages, 'vercel'),
|
if (p in localBuilders) return false;
|
||||||
getBuildUtils(packages, 'now')
|
|
||||||
);
|
|
||||||
|
|
||||||
await retry(
|
// If it's a builder that is part of Now CLI's `dependencies` then
|
||||||
() =>
|
// don't update it
|
||||||
execa(
|
if (isBundledBuilder(npa(p), nowCliPkg)) {
|
||||||
process.execPath,
|
return false;
|
||||||
[
|
|
||||||
yarnPath,
|
|
||||||
'add',
|
|
||||||
'--exact',
|
|
||||||
'--no-lockfile',
|
|
||||||
'--non-interactive',
|
|
||||||
'--ignore-workspace-root-check',
|
|
||||||
...packages.filter(p => !isStaticRuntime(p)),
|
|
||||||
],
|
|
||||||
{
|
|
||||||
cwd: builderDir,
|
|
||||||
}
|
|
||||||
),
|
|
||||||
{ retries: 2 }
|
|
||||||
);
|
|
||||||
|
|
||||||
const updatedPackages: string[] = [];
|
|
||||||
const buildersPkgAfter = await readJSON(buildersPkgPath);
|
|
||||||
for (const [name, version] of Object.entries(buildersPkgAfter.dependencies)) {
|
|
||||||
if (version !== buildersPkgBefore.dependencies[name]) {
|
|
||||||
output.debug(`Runtime "${name}" updated to version \`${version}\``);
|
|
||||||
updatedPackages.push(name);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
purgeRequireCache(updatedPackages, builderDir, output);
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (packagesToUpdate.length > 0) {
|
||||||
|
packages.push(
|
||||||
|
getBuildUtils(packages, 'vercel'),
|
||||||
|
getBuildUtils(packages, 'now')
|
||||||
|
);
|
||||||
|
|
||||||
|
await retry(
|
||||||
|
() =>
|
||||||
|
execa(
|
||||||
|
'npm',
|
||||||
|
['install', '--save-exact', '--no-package-lock', ...packagesToUpdate],
|
||||||
|
{
|
||||||
|
cwd: builderDir,
|
||||||
|
}
|
||||||
|
),
|
||||||
|
{ retries: 2 }
|
||||||
|
);
|
||||||
|
|
||||||
|
const buildersPkgAfter = await readJSON(buildersPkgPath);
|
||||||
|
const depsAfter = {
|
||||||
|
...buildersPkgAfter.devDependencies,
|
||||||
|
...buildersPkgAfter.dependencies,
|
||||||
|
};
|
||||||
|
for (const [name, version] of Object.entries(depsAfter)) {
|
||||||
|
if (version !== depsBefore[name]) {
|
||||||
|
output.debug(`Runtime "${name}" updated to version \`${version}\``);
|
||||||
|
updatedPackages.push(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
purgeRequireCache(updatedPackages, builderDir, output);
|
||||||
|
}
|
||||||
|
|
||||||
return updatedPackages;
|
return updatedPackages;
|
||||||
}
|
}
|
||||||
@@ -352,7 +308,6 @@ export async function updateBuilders(
|
|||||||
*/
|
*/
|
||||||
export async function getBuilder(
|
export async function getBuilder(
|
||||||
builderPkg: string,
|
builderPkg: string,
|
||||||
yarnDir: string,
|
|
||||||
output: Output,
|
output: Output,
|
||||||
builderDir?: string,
|
builderDir?: string,
|
||||||
isRetry = false
|
isRetry = false
|
||||||
@@ -362,34 +317,74 @@ export async function getBuilder(
|
|||||||
if (!builderDir) {
|
if (!builderDir) {
|
||||||
builderDir = await builderDirPromise;
|
builderDir = await builderDirPromise;
|
||||||
}
|
}
|
||||||
|
let requirePath: string;
|
||||||
const parsed = npa(builderPkg);
|
const parsed = npa(builderPkg);
|
||||||
const buildersPkg = await readJSON(join(builderDir, 'package.json'));
|
|
||||||
const pkgName = getPackageName(parsed, buildersPkg) || builderPkg;
|
// First check if it's a bundled Runtime in Now CLI's `node_modules`
|
||||||
const dest = join(builderDir, 'node_modules', pkgName);
|
const bundledBuilder = isBundledBuilder(parsed, nowCliPkg);
|
||||||
|
if (bundledBuilder && parsed.name) {
|
||||||
|
requirePath = parsed.name;
|
||||||
|
} else {
|
||||||
|
const buildersPkg = await readJSON(join(builderDir, 'package.json'));
|
||||||
|
const pkgName = getPackageName(parsed, buildersPkg) || builderPkg;
|
||||||
|
requirePath = join(builderDir, 'node_modules', pkgName);
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const mod = require(dest);
|
output.debug(`Requiring runtime: "${requirePath}"`);
|
||||||
const pkg = require(join(dest, 'package.json'));
|
const mod = require(requirePath);
|
||||||
|
const pkg = require(join(requirePath, 'package.json'));
|
||||||
builderWithPkg = {
|
builderWithPkg = {
|
||||||
|
requirePath,
|
||||||
builder: Object.freeze(mod),
|
builder: Object.freeze(mod),
|
||||||
package: Object.freeze(pkg),
|
package: Object.freeze(pkg),
|
||||||
};
|
};
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err.code === 'MODULE_NOT_FOUND' && !isRetry) {
|
if (err.code === 'MODULE_NOT_FOUND' && !isRetry) {
|
||||||
output.debug(
|
output.debug(
|
||||||
`Attempted to require ${builderPkg}, but it is not installed`
|
`Attempted to require ${requirePath}, but it is not installed`
|
||||||
);
|
);
|
||||||
const pkgSet = new Set([builderPkg]);
|
const pkgSet = new Set([builderPkg]);
|
||||||
await installBuilders(pkgSet, yarnDir, output, builderDir);
|
await installBuilders(pkgSet, output, builderDir);
|
||||||
|
|
||||||
// Run `getBuilder()` again now that the builder has been installed
|
// Run `getBuilder()` again now that the builder has been installed
|
||||||
return getBuilder(builderPkg, yarnDir, output, builderDir, true);
|
return getBuilder(builderPkg, output, builderDir, true);
|
||||||
}
|
}
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If it's a bundled builder, then cache the require call
|
||||||
|
if (bundledBuilder) {
|
||||||
|
localBuilders[builderPkg] = builderWithPkg;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return builderWithPkg;
|
return builderWithPkg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isBundledBuilder(
|
||||||
|
parsed: npa.Result,
|
||||||
|
pkg: PackageJson
|
||||||
|
): boolean {
|
||||||
|
if (!parsed.name || !pkg.dependencies) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bundledVersion = pkg.dependencies[parsed.name];
|
||||||
|
if (bundledVersion) {
|
||||||
|
if (parsed.type === 'tag') {
|
||||||
|
if (parsed.fetchSpec === 'canary') {
|
||||||
|
return bundledVersion.includes('canary');
|
||||||
|
} else if (parsed.fetchSpec === 'latest') {
|
||||||
|
return !bundledVersion.includes('canary');
|
||||||
|
}
|
||||||
|
} else if (parsed.type === 'version') {
|
||||||
|
return parsed.fetchSpec === bundledVersion;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
function getPackageName(
|
function getPackageName(
|
||||||
parsed: npa.Result,
|
parsed: npa.Result,
|
||||||
buildersPkg: PackageJson
|
buildersPkg: PackageJson
|
||||||
@@ -397,30 +392,18 @@ function getPackageName(
|
|||||||
if (registryTypes.has(parsed.type)) {
|
if (registryTypes.has(parsed.type)) {
|
||||||
return parsed.name;
|
return parsed.name;
|
||||||
}
|
}
|
||||||
const deps = { ...buildersPkg.devDependencies, ...buildersPkg.dependencies };
|
const deps: { [name: string]: string } = {
|
||||||
|
...buildersPkg.devDependencies,
|
||||||
|
...buildersPkg.dependencies,
|
||||||
|
};
|
||||||
for (const [name, dep] of Object.entries(deps)) {
|
for (const [name, dep] of Object.entries(deps)) {
|
||||||
if (dep === parsed.raw) {
|
if (dep === parsed.raw || basename(dep) === basename(parsed.raw)) {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSha(buffer: Buffer): string {
|
|
||||||
const hash = createHash('sha256');
|
|
||||||
hash.update(buffer);
|
|
||||||
return hash.digest('hex');
|
|
||||||
}
|
|
||||||
|
|
||||||
function hasBundledBuilders(dependencies: { [name: string]: string }): boolean {
|
|
||||||
for (const name of getBundledBuilders()) {
|
|
||||||
if (!(name in dependencies)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function purgeRequireCache(
|
function purgeRequireCache(
|
||||||
packages: string[],
|
packages: string[],
|
||||||
builderDir: string,
|
builderDir: string,
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
/**
|
/**
|
||||||
* This file gets copied out of the `pkg` snapshot filesystem into the `now dev`
|
* This file gets copied out of the `pkg` snapshot filesystem into the `vc dev`
|
||||||
* builder cache directory, so it's very important that it does not rely on any
|
* builder cache directory, so it's very important that it does not rely on any
|
||||||
* modules from npm that would not be available in that directory (so basically,
|
* modules from npm that would not be available in that directory (so basically,
|
||||||
* only Now builders and `@now/build-utils`.
|
* only Vercel Runtimes and `@vercel/build-utils`.
|
||||||
*/
|
*/
|
||||||
const { FileFsRef } = require('@now/build-utils');
|
const { FileFsRef } = require('@vercel/build-utils');
|
||||||
|
|
||||||
process.on('unhandledRejection', err => {
|
process.on('unhandledRejection', err => {
|
||||||
console.error('Exiting builder due to build error:');
|
console.error('Exiting builder due to build error:');
|
||||||
@@ -24,21 +24,21 @@ function onMessage(message) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function processMessage(message) {
|
async function processMessage(message) {
|
||||||
const { builderName, buildParams } = message;
|
const { requirePath, buildOptions } = message;
|
||||||
const builder = require(builderName);
|
const builder = require(requirePath);
|
||||||
|
|
||||||
// Convert the `files` to back into `FileFsRef` instances
|
// Convert the `files` to back into `FileFsRef` instances
|
||||||
for (const name of Object.keys(buildParams.files)) {
|
for (const name of Object.keys(buildOptions.files)) {
|
||||||
const ref = Object.assign(
|
const ref = Object.assign(
|
||||||
Object.create(FileFsRef.prototype),
|
Object.create(FileFsRef.prototype),
|
||||||
buildParams.files[name]
|
buildOptions.files[name]
|
||||||
);
|
);
|
||||||
buildParams.files[name] = ref;
|
buildOptions.files[name] = ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await builder.build(buildParams);
|
const result = await builder.build(buildOptions);
|
||||||
|
|
||||||
// `@now/next` sets this, but it causes "Converting circular
|
// `@vercel/next` sets this, but it causes "Converting circular
|
||||||
// structure to JSON" errors, so delete the property...
|
// structure to JSON" errors, so delete the property...
|
||||||
delete result.childProcesses;
|
delete result.childProcesses;
|
||||||
|
|
||||||
|
|||||||
@@ -2,12 +2,13 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
||||||
import ms from 'ms';
|
import ms from 'ms';
|
||||||
import bytes from 'bytes';
|
import bytes from 'bytes';
|
||||||
import { promisify } from 'util';
|
|
||||||
import { delimiter, dirname, join } from 'path';
|
import { delimiter, dirname, join } from 'path';
|
||||||
import { fork, ChildProcess } from 'child_process';
|
import { fork, ChildProcess } from 'child_process';
|
||||||
import { createFunction } from '@zeit/fun';
|
import { createFunction } from '@zeit/fun';
|
||||||
import {
|
import {
|
||||||
Builder,
|
Builder,
|
||||||
|
BuildOptions,
|
||||||
|
Env,
|
||||||
File,
|
File,
|
||||||
Lambda,
|
Lambda,
|
||||||
FileBlob,
|
FileBlob,
|
||||||
@@ -16,17 +17,16 @@ import {
|
|||||||
} from '@vercel/build-utils';
|
} from '@vercel/build-utils';
|
||||||
import plural from 'pluralize';
|
import plural from 'pluralize';
|
||||||
import minimatch from 'minimatch';
|
import minimatch from 'minimatch';
|
||||||
import _treeKill from 'tree-kill';
|
|
||||||
|
|
||||||
import { Output } from '../output';
|
import { Output } from '../output';
|
||||||
import highlight from '../output/highlight';
|
import highlight from '../output/highlight';
|
||||||
|
import { treeKill } from '../tree-kill';
|
||||||
import { relative } from '../path-helpers';
|
import { relative } from '../path-helpers';
|
||||||
import { LambdaSizeExceededError } from '../errors-ts';
|
import { LambdaSizeExceededError } from '../errors-ts';
|
||||||
|
|
||||||
import DevServer from './server';
|
import DevServer from './server';
|
||||||
import { builderModulePathPromise, getBuilder } from './builder-cache';
|
import { getBuilder } from './builder-cache';
|
||||||
import {
|
import {
|
||||||
EnvConfig,
|
|
||||||
NowConfig,
|
NowConfig,
|
||||||
BuildMatch,
|
BuildMatch,
|
||||||
BuildResult,
|
BuildResult,
|
||||||
@@ -34,7 +34,6 @@ import {
|
|||||||
BuilderOutput,
|
BuilderOutput,
|
||||||
BuildResultV3,
|
BuildResultV3,
|
||||||
BuilderOutputs,
|
BuilderOutputs,
|
||||||
BuilderParams,
|
|
||||||
EnvConfigs,
|
EnvConfigs,
|
||||||
} from './types';
|
} from './types';
|
||||||
import { normalizeRoutes } from '@vercel/routing-utils';
|
import { normalizeRoutes } from '@vercel/routing-utils';
|
||||||
@@ -51,27 +50,18 @@ interface BuildMessageResult extends BuildMessage {
|
|||||||
error?: object;
|
error?: object;
|
||||||
}
|
}
|
||||||
|
|
||||||
const treeKill = promisify(_treeKill);
|
|
||||||
|
|
||||||
async function createBuildProcess(
|
async function createBuildProcess(
|
||||||
match: BuildMatch,
|
match: BuildMatch,
|
||||||
envConfigs: EnvConfigs,
|
envConfigs: EnvConfigs,
|
||||||
workPath: string,
|
workPath: string,
|
||||||
output: Output,
|
output: Output
|
||||||
yarnPath?: string
|
|
||||||
): Promise<ChildProcess> {
|
): Promise<ChildProcess> {
|
||||||
const { execPath } = process;
|
const builderWorkerPath = join(__dirname, 'builder-worker.js');
|
||||||
const modulePath = await builderModulePathPromise;
|
|
||||||
|
|
||||||
// Ensure that `node` is in the builder's `PATH`
|
// Ensure that `node` is in the builder's `PATH`
|
||||||
let PATH = `${dirname(execPath)}${delimiter}${process.env.PATH}`;
|
let PATH = `${dirname(process.execPath)}${delimiter}${process.env.PATH}`;
|
||||||
|
|
||||||
// Ensure that `yarn` is in the builder's `PATH`
|
const env: Env = {
|
||||||
if (yarnPath) {
|
|
||||||
PATH = `${yarnPath}${delimiter}${PATH}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
const env: EnvConfig = {
|
|
||||||
...process.env,
|
...process.env,
|
||||||
PATH,
|
PATH,
|
||||||
...envConfigs.allEnv,
|
...envConfigs.allEnv,
|
||||||
@@ -79,11 +69,9 @@ async function createBuildProcess(
|
|||||||
VERCEL_REGION: 'dev1',
|
VERCEL_REGION: 'dev1',
|
||||||
};
|
};
|
||||||
|
|
||||||
const buildProcess = fork(modulePath, [], {
|
const buildProcess = fork(builderWorkerPath, [], {
|
||||||
cwd: workPath,
|
cwd: workPath,
|
||||||
env,
|
env,
|
||||||
execPath,
|
|
||||||
execArgv: [],
|
|
||||||
});
|
});
|
||||||
match.buildProcess = buildProcess;
|
match.buildProcess = buildProcess;
|
||||||
|
|
||||||
@@ -117,10 +105,10 @@ export async function executeBuild(
|
|||||||
filesRemoved?: string[]
|
filesRemoved?: string[]
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const {
|
const {
|
||||||
builderWithPkg: { runInProcess, builder, package: pkg },
|
builderWithPkg: { runInProcess, requirePath, builder, package: pkg },
|
||||||
} = match;
|
} = match;
|
||||||
const { entrypoint } = match;
|
const { entrypoint } = match;
|
||||||
const { debug, envConfigs, yarnPath, cwd: workPath } = devServer;
|
const { debug, envConfigs, cwd: workPath } = devServer;
|
||||||
|
|
||||||
const startTime = Date.now();
|
const startTime = Date.now();
|
||||||
const showBuildTimestamp =
|
const showBuildTimestamp =
|
||||||
@@ -144,15 +132,14 @@ export async function executeBuild(
|
|||||||
match,
|
match,
|
||||||
envConfigs,
|
envConfigs,
|
||||||
workPath,
|
workPath,
|
||||||
devServer.output,
|
devServer.output
|
||||||
yarnPath
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const vercelDir = getVercelDirectory(workPath);
|
const vercelDir = getVercelDirectory(workPath);
|
||||||
const devCacheDir = join(vercelDir, 'cache');
|
const devCacheDir = join(vercelDir, 'cache');
|
||||||
|
|
||||||
const buildParams: BuilderParams = {
|
const buildOptions: BuildOptions = {
|
||||||
files,
|
files,
|
||||||
entrypoint,
|
entrypoint,
|
||||||
workPath,
|
workPath,
|
||||||
@@ -174,8 +161,8 @@ export async function executeBuild(
|
|||||||
if (buildProcess) {
|
if (buildProcess) {
|
||||||
buildProcess.send({
|
buildProcess.send({
|
||||||
type: 'build',
|
type: 'build',
|
||||||
builderName: pkg.name,
|
requirePath,
|
||||||
buildParams,
|
buildOptions,
|
||||||
});
|
});
|
||||||
|
|
||||||
buildResultOrOutputs = await new Promise((resolve, reject) => {
|
buildResultOrOutputs = await new Promise((resolve, reject) => {
|
||||||
@@ -206,7 +193,7 @@ export async function executeBuild(
|
|||||||
buildProcess!.on('message', onMessage);
|
buildProcess!.on('message', onMessage);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
buildResultOrOutputs = await builder.build(buildParams);
|
buildResultOrOutputs = await builder.build(buildOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort out build result to builder v2 shape
|
// Sort out build result to builder v2 shape
|
||||||
@@ -404,7 +391,6 @@ export async function executeBuild(
|
|||||||
export async function getBuildMatches(
|
export async function getBuildMatches(
|
||||||
nowConfig: NowConfig,
|
nowConfig: NowConfig,
|
||||||
cwd: string,
|
cwd: string,
|
||||||
yarnDir: string,
|
|
||||||
output: Output,
|
output: Output,
|
||||||
devServer: DevServer,
|
devServer: DevServer,
|
||||||
fileList: string[]
|
fileList: string[]
|
||||||
@@ -456,7 +442,7 @@ export async function getBuildMatches(
|
|||||||
|
|
||||||
for (const file of files) {
|
for (const file of files) {
|
||||||
src = relative(cwd, file);
|
src = relative(cwd, file);
|
||||||
const builderWithPkg = await getBuilder(use, yarnDir, output);
|
const builderWithPkg = await getBuilder(use, output);
|
||||||
matches.push({
|
matches.push({
|
||||||
...buildConfig,
|
...buildConfig,
|
||||||
src,
|
src,
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import PCRE from 'pcre-to-regexp';
|
|||||||
import isURL from './is-url';
|
import isURL from './is-url';
|
||||||
import DevServer from './server';
|
import DevServer from './server';
|
||||||
|
|
||||||
import { HttpHeadersConfig, RouteConfig, RouteResult } from './types';
|
import { HttpHeadersConfig, RouteResult } from './types';
|
||||||
import { isHandler, Route, HandleValue } from '@vercel/routing-utils';
|
import { isHandler, Route, HandleValue } from '@vercel/routing-utils';
|
||||||
|
|
||||||
export function resolveRouteParameters(
|
export function resolveRouteParameters(
|
||||||
@@ -48,10 +48,10 @@ export function getRoutesTypes(routes: Route[] = []) {
|
|||||||
export async function devRouter(
|
export async function devRouter(
|
||||||
reqUrl: string = '/',
|
reqUrl: string = '/',
|
||||||
reqMethod?: string,
|
reqMethod?: string,
|
||||||
routes?: RouteConfig[],
|
routes?: Route[],
|
||||||
devServer?: DevServer,
|
devServer?: DevServer,
|
||||||
previousHeaders?: HttpHeadersConfig,
|
previousHeaders?: HttpHeadersConfig,
|
||||||
missRoutes?: RouteConfig[],
|
missRoutes?: Route[],
|
||||||
phase?: HandleValue | null
|
phase?: HandleValue | null
|
||||||
): Promise<RouteResult> {
|
): Promise<RouteResult> {
|
||||||
let result: RouteResult | undefined;
|
let result: RouteResult | undefined;
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import serveHandler from 'serve-handler';
|
|||||||
import { watch, FSWatcher } from 'chokidar';
|
import { watch, FSWatcher } from 'chokidar';
|
||||||
import { parse as parseDotenv } from 'dotenv';
|
import { parse as parseDotenv } from 'dotenv';
|
||||||
import { basename, dirname, extname, join } from 'path';
|
import { basename, dirname, extname, join } from 'path';
|
||||||
|
import once from '@tootallnate/once';
|
||||||
import directoryTemplate from 'serve-handler/src/directory';
|
import directoryTemplate from 'serve-handler/src/directory';
|
||||||
import getPort from 'get-port';
|
import getPort from 'get-port';
|
||||||
import { ChildProcess } from 'child_process';
|
import { ChildProcess } from 'child_process';
|
||||||
@@ -23,9 +24,12 @@ import {
|
|||||||
getTransformedRoutes,
|
getTransformedRoutes,
|
||||||
appendRoutesToPhase,
|
appendRoutesToPhase,
|
||||||
HandleValue,
|
HandleValue,
|
||||||
|
Route,
|
||||||
} from '@vercel/routing-utils';
|
} from '@vercel/routing-utils';
|
||||||
import {
|
import {
|
||||||
Builder,
|
Builder,
|
||||||
|
Env,
|
||||||
|
StartDevServerResult,
|
||||||
FileFsRef,
|
FileFsRef,
|
||||||
PackageJson,
|
PackageJson,
|
||||||
detectBuilders,
|
detectBuilders,
|
||||||
@@ -35,7 +39,6 @@ import {
|
|||||||
isOfficialRuntime,
|
isOfficialRuntime,
|
||||||
} from '@vercel/build-utils';
|
} from '@vercel/build-utils';
|
||||||
|
|
||||||
import { once } from '../once';
|
|
||||||
import link from '../output/link';
|
import link from '../output/link';
|
||||||
import { Output } from '../output';
|
import { Output } from '../output';
|
||||||
import { relative } from '../path-helpers';
|
import { relative } from '../path-helpers';
|
||||||
@@ -57,10 +60,13 @@ import {
|
|||||||
|
|
||||||
import { devRouter, getRoutesTypes } from './router';
|
import { devRouter, getRoutesTypes } from './router';
|
||||||
import getMimeType from './mime-type';
|
import getMimeType from './mime-type';
|
||||||
import { getYarnPath } from './yarn-installer';
|
|
||||||
import { executeBuild, getBuildMatches, shutdownBuilder } from './builder';
|
import { executeBuild, getBuildMatches, shutdownBuilder } from './builder';
|
||||||
import { generateErrorMessage, generateHttpStatusDescription } from './errors';
|
import { generateErrorMessage, generateHttpStatusDescription } from './errors';
|
||||||
import { installBuilders, updateBuilders } from './builder-cache';
|
import {
|
||||||
|
installBuilders,
|
||||||
|
updateBuilders,
|
||||||
|
builderDirPromise,
|
||||||
|
} from './builder-cache';
|
||||||
|
|
||||||
// HTML templates
|
// HTML templates
|
||||||
import errorTemplate from './templates/error';
|
import errorTemplate from './templates/error';
|
||||||
@@ -70,7 +76,6 @@ import errorTemplate502 from './templates/error_502';
|
|||||||
import redirectTemplate from './templates/redirect';
|
import redirectTemplate from './templates/redirect';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
EnvConfig,
|
|
||||||
NowConfig,
|
NowConfig,
|
||||||
DevServerOptions,
|
DevServerOptions,
|
||||||
BuildMatch,
|
BuildMatch,
|
||||||
@@ -81,7 +86,6 @@ import {
|
|||||||
InvokePayload,
|
InvokePayload,
|
||||||
InvokeResult,
|
InvokeResult,
|
||||||
ListenSpec,
|
ListenSpec,
|
||||||
RouteConfig,
|
|
||||||
RouteResult,
|
RouteResult,
|
||||||
HttpHeadersConfig,
|
HttpHeadersConfig,
|
||||||
EnvConfigs,
|
EnvConfigs,
|
||||||
@@ -111,7 +115,6 @@ export default class DevServer {
|
|||||||
public envConfigs: EnvConfigs;
|
public envConfigs: EnvConfigs;
|
||||||
public frameworkSlug: string | null;
|
public frameworkSlug: string | null;
|
||||||
public files: BuilderInputs;
|
public files: BuilderInputs;
|
||||||
public yarnPath: string;
|
|
||||||
public address: string;
|
public address: string;
|
||||||
|
|
||||||
private cachedNowConfig: NowConfig | null;
|
private cachedNowConfig: NowConfig | null;
|
||||||
@@ -131,6 +134,7 @@ export default class DevServer {
|
|||||||
private devCommand?: string;
|
private devCommand?: string;
|
||||||
private devProcess?: ChildProcess;
|
private devProcess?: ChildProcess;
|
||||||
private devProcessPort?: number;
|
private devProcessPort?: number;
|
||||||
|
private devServerPids: Set<number>;
|
||||||
|
|
||||||
private getNowConfigPromise: Promise<NowConfig> | null;
|
private getNowConfigPromise: Promise<NowConfig> | null;
|
||||||
private blockingBuildsPromise: Promise<void> | null;
|
private blockingBuildsPromise: Promise<void> | null;
|
||||||
@@ -145,14 +149,10 @@ export default class DevServer {
|
|||||||
this.address = '';
|
this.address = '';
|
||||||
this.devCommand = options.devCommand;
|
this.devCommand = options.devCommand;
|
||||||
this.frameworkSlug = options.frameworkSlug;
|
this.frameworkSlug = options.frameworkSlug;
|
||||||
|
|
||||||
// This gets updated when `start()` is invoked
|
|
||||||
this.yarnPath = '/';
|
|
||||||
|
|
||||||
this.cachedNowConfig = null;
|
this.cachedNowConfig = null;
|
||||||
this.caseSensitive = false;
|
this.caseSensitive = false;
|
||||||
this.apiDir = null;
|
this.apiDir = null;
|
||||||
this.apiExtensions = new Set<string>();
|
this.apiExtensions = new Set();
|
||||||
this.server = http.createServer(this.devServerHandler);
|
this.server = http.createServer(this.devServerHandler);
|
||||||
this.server.timeout = 0; // Disable timeout
|
this.server.timeout = 0; // Disable timeout
|
||||||
this.stopping = false;
|
this.stopping = false;
|
||||||
@@ -171,6 +171,8 @@ export default class DevServer {
|
|||||||
this.podId = Math.random()
|
this.podId = Math.random()
|
||||||
.toString(32)
|
.toString(32)
|
||||||
.slice(-5);
|
.slice(-5);
|
||||||
|
|
||||||
|
this.devServerPids = new Set();
|
||||||
}
|
}
|
||||||
|
|
||||||
async exit(code = 1) {
|
async exit(code = 1) {
|
||||||
@@ -357,7 +359,6 @@ export default class DevServer {
|
|||||||
const matches = await getBuildMatches(
|
const matches = await getBuildMatches(
|
||||||
nowConfig,
|
nowConfig,
|
||||||
this.cwd,
|
this.cwd,
|
||||||
this.yarnPath,
|
|
||||||
this.output,
|
this.output,
|
||||||
this,
|
this,
|
||||||
fileList
|
fileList
|
||||||
@@ -449,11 +450,11 @@ export default class DevServer {
|
|||||||
await this.updateBuildMatches(nowConfig);
|
await this.updateBuildMatches(nowConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
async getLocalEnv(fileName: string, base?: EnvConfig): Promise<EnvConfig> {
|
async getLocalEnv(fileName: string, base?: Env): Promise<Env> {
|
||||||
// TODO: use the file watcher to only invalidate the env `dotfile`
|
// TODO: use the file watcher to only invalidate the env `dotfile`
|
||||||
// once a change to the `fileName` occurs
|
// once a change to the `fileName` occurs
|
||||||
const filePath = join(this.cwd, fileName);
|
const filePath = join(this.cwd, fileName);
|
||||||
let env: EnvConfig = {};
|
let env: Env = {};
|
||||||
try {
|
try {
|
||||||
const dotenv = await fs.readFile(filePath, 'utf8');
|
const dotenv = await fs.readFile(filePath, 'utf8');
|
||||||
this.output.debug(`Using local env: ${filePath}`);
|
this.output.debug(`Using local env: ${filePath}`);
|
||||||
@@ -583,7 +584,7 @@ export default class DevServer {
|
|||||||
config.builds = config.builds || [];
|
config.builds = config.builds || [];
|
||||||
config.builds.push(...builders);
|
config.builds.push(...builders);
|
||||||
|
|
||||||
const routes: RouteConfig[] = [];
|
const routes: Route[] = [];
|
||||||
const { routes: nowConfigRoutes } = config;
|
const { routes: nowConfigRoutes } = config;
|
||||||
routes.push(...(redirectRoutes || []));
|
routes.push(...(redirectRoutes || []));
|
||||||
routes.push(
|
routes.push(
|
||||||
@@ -656,6 +657,7 @@ export default class DevServer {
|
|||||||
if (config.version === 1) {
|
if (config.version === 1) {
|
||||||
this.output.error('Only `version: 2` is supported by `now dev`');
|
this.output.error('Only `version: 2` is supported by `now dev`');
|
||||||
await this.exit(1);
|
await this.exit(1);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.tryValidateOrExit(config, validateNowConfigBuilds);
|
await this.tryValidateOrExit(config, validateNowConfigBuilds);
|
||||||
@@ -668,13 +670,8 @@ export default class DevServer {
|
|||||||
await this.tryValidateOrExit(config, validateNowConfigFunctions);
|
await this.tryValidateOrExit(config, validateNowConfigFunctions);
|
||||||
}
|
}
|
||||||
|
|
||||||
validateEnvConfig(
|
validateEnvConfig(type: string, env: Env = {}, localEnv: Env = {}): Env {
|
||||||
type: string,
|
|
||||||
env: EnvConfig = {},
|
|
||||||
localEnv: EnvConfig = {}
|
|
||||||
): EnvConfig {
|
|
||||||
// Validate if there are any missing env vars defined in `vercel.json`,
|
// Validate if there are any missing env vars defined in `vercel.json`,
|
||||||
|
|
||||||
// but not in the `.env` / `.build.env` file
|
// but not in the `.env` / `.build.env` file
|
||||||
const missing: string[] = Object.entries(env)
|
const missing: string[] = Object.entries(env)
|
||||||
.filter(
|
.filter(
|
||||||
@@ -689,7 +686,7 @@ export default class DevServer {
|
|||||||
throw new MissingDotenvVarsError(type, missing);
|
throw new MissingDotenvVarsError(type, missing);
|
||||||
}
|
}
|
||||||
|
|
||||||
const merged: EnvConfig = { ...env, ...localEnv };
|
const merged: Env = { ...env, ...localEnv };
|
||||||
|
|
||||||
// Validate that the env var name matches what AWS Lambda allows:
|
// Validate that the env var name matches what AWS Lambda allows:
|
||||||
// - https://docs.aws.amazon.com/lambda/latest/dg/env_variables.html
|
// - https://docs.aws.amazon.com/lambda/latest/dg/env_variables.html
|
||||||
@@ -737,7 +734,6 @@ export default class DevServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const { ig } = await getVercelIgnore(this.cwd);
|
const { ig } = await getVercelIgnore(this.cwd);
|
||||||
this.yarnPath = await getYarnPath(this.output);
|
|
||||||
this.filter = ig.createFilter();
|
this.filter = ig.createFilter();
|
||||||
|
|
||||||
// Retrieve the path of the native module
|
// Retrieve the path of the native module
|
||||||
@@ -770,16 +766,12 @@ export default class DevServer {
|
|||||||
.map((b: Builder) => b.use)
|
.map((b: Builder) => b.use)
|
||||||
);
|
);
|
||||||
|
|
||||||
await installBuilders(builders, this.yarnPath, this.output);
|
await installBuilders(builders, this.output);
|
||||||
await this.updateBuildMatches(nowConfig, true);
|
await this.updateBuildMatches(nowConfig, true);
|
||||||
|
|
||||||
// Updating builders happens lazily, and any builders that were updated
|
// Updating builders happens lazily, and any builders that were updated
|
||||||
// get their "build matches" invalidated so that the new version is used.
|
// get their "build matches" invalidated so that the new version is used.
|
||||||
this.updateBuildersPromise = updateBuilders(
|
this.updateBuildersPromise = updateBuilders(builders, this.output)
|
||||||
builders,
|
|
||||||
this.yarnPath,
|
|
||||||
this.output
|
|
||||||
)
|
|
||||||
.then(updatedBuilders => {
|
.then(updatedBuilders => {
|
||||||
this.updateBuildersPromise = null;
|
this.updateBuildersPromise = null;
|
||||||
this.invalidateBuildMatches(nowConfig, updatedBuilders);
|
this.invalidateBuildMatches(nowConfig, updatedBuilders);
|
||||||
@@ -875,6 +867,7 @@ export default class DevServer {
|
|||||||
*/
|
*/
|
||||||
async stop(exitCode?: number): Promise<void> {
|
async stop(exitCode?: number): Promise<void> {
|
||||||
const { devProcess } = this;
|
const { devProcess } = this;
|
||||||
|
const { debug } = this.output;
|
||||||
if (this.stopping) return;
|
if (this.stopping) return;
|
||||||
|
|
||||||
this.stopping = true;
|
this.stopping = true;
|
||||||
@@ -905,15 +898,22 @@ export default class DevServer {
|
|||||||
ops.push(close(this.server));
|
ops.push(close(this.server));
|
||||||
|
|
||||||
if (this.watcher) {
|
if (this.watcher) {
|
||||||
this.output.debug(`Closing file watcher`);
|
debug(`Closing file watcher`);
|
||||||
this.watcher.close();
|
this.watcher.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.updateBuildersPromise) {
|
if (this.updateBuildersPromise) {
|
||||||
this.output.debug(`Waiting for builders update to complete`);
|
debug(`Waiting for builders update to complete`);
|
||||||
ops.push(this.updateBuildersPromise);
|
ops.push(this.updateBuildersPromise);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (const pid of this.devServerPids) {
|
||||||
|
ops.push(this.killBuilderDevServer(pid));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure that the builders module cache is created
|
||||||
|
ops.push(builderDirPromise);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await Promise.all(ops);
|
await Promise.all(ops);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -929,6 +929,18 @@ export default class DevServer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async killBuilderDevServer(pid: number) {
|
||||||
|
const { debug } = this.output;
|
||||||
|
debug(`Killing builder dev server with PID ${pid}`);
|
||||||
|
this.devServerPids.delete(pid);
|
||||||
|
try {
|
||||||
|
process.kill(pid, 'SIGTERM');
|
||||||
|
debug(`Killed builder dev server with PID ${pid}`);
|
||||||
|
} catch (err) {
|
||||||
|
debug(`Failed to kill builder dev server with PID ${pid}: ${err}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async send404(
|
async send404(
|
||||||
req: http.IncomingMessage,
|
req: http.IncomingMessage,
|
||||||
res: http.ServerResponse,
|
res: http.ServerResponse,
|
||||||
@@ -1222,9 +1234,11 @@ export default class DevServer {
|
|||||||
res: http.ServerResponse,
|
res: http.ServerResponse,
|
||||||
nowRequestId: string,
|
nowRequestId: string,
|
||||||
nowConfig: NowConfig,
|
nowConfig: NowConfig,
|
||||||
routes: RouteConfig[] | undefined = nowConfig.routes,
|
routes: Route[] | undefined = nowConfig.routes,
|
||||||
callLevel: number = 0
|
callLevel: number = 0
|
||||||
) => {
|
) => {
|
||||||
|
const { debug } = this.output;
|
||||||
|
|
||||||
// If there is a double-slash present in the URL,
|
// If there is a double-slash present in the URL,
|
||||||
// then perform a redirect to make it "clean".
|
// then perform a redirect to make it "clean".
|
||||||
const parsed = url.parse(req.url || '/');
|
const parsed = url.parse(req.url || '/');
|
||||||
@@ -1241,16 +1255,16 @@ export default class DevServer {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.output.debug(`Rewriting URL from "${req.url}" to "${location}"`);
|
debug(`Rewriting URL from "${req.url}" to "${location}"`);
|
||||||
req.url = location;
|
req.url = location;
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.updateBuildMatches(nowConfig);
|
if (callLevel === 0) {
|
||||||
|
await this.updateBuildMatches(nowConfig);
|
||||||
|
}
|
||||||
|
|
||||||
if (this.blockingBuildsPromise) {
|
if (this.blockingBuildsPromise) {
|
||||||
this.output.debug(
|
debug('Waiting for builds to complete before handling request');
|
||||||
'Waiting for builds to complete before handling request'
|
|
||||||
);
|
|
||||||
await this.blockingBuildsPromise;
|
await this.blockingBuildsPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1291,7 +1305,7 @@ export default class DevServer {
|
|||||||
Object.assign(destParsed.query, routeResult.uri_args);
|
Object.assign(destParsed.query, routeResult.uri_args);
|
||||||
const destUrl = url.format(destParsed);
|
const destUrl = url.format(destParsed);
|
||||||
|
|
||||||
this.output.debug(`ProxyPass: ${destUrl}`);
|
debug(`ProxyPass: ${destUrl}`);
|
||||||
this.setResponseHeaders(res, nowRequestId);
|
this.setResponseHeaders(res, nowRequestId);
|
||||||
return proxyPass(req, res, destUrl, this.output);
|
return proxyPass(req, res, destUrl, this.output);
|
||||||
}
|
}
|
||||||
@@ -1382,15 +1396,25 @@ export default class DevServer {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (statusCode) {
|
if (statusCode) {
|
||||||
res.statusCode = statusCode;
|
// Set the `statusCode` as read-only so that `http-proxy`
|
||||||
|
// is not able to modify the value in the future
|
||||||
|
Object.defineProperty(res, 'statusCode', {
|
||||||
|
get() {
|
||||||
|
return statusCode;
|
||||||
|
},
|
||||||
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||||
|
set(_: number) {
|
||||||
|
/* ignore */
|
||||||
|
},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const requestPath = dest.replace(/^\//, '');
|
const requestPath = dest.replace(/^\//, '');
|
||||||
|
|
||||||
if (!match) {
|
if (!match) {
|
||||||
// if the dev command is started, proxy to it
|
// If the dev command is started, then proxy to it
|
||||||
if (this.devProcessPort) {
|
if (this.devProcessPort) {
|
||||||
this.output.debug('Proxy to dev command server');
|
debug('Proxying to frontend dev server');
|
||||||
this.setResponseHeaders(res, nowRequestId);
|
this.setResponseHeaders(res, nowRequestId);
|
||||||
return proxyPass(
|
return proxyPass(
|
||||||
req,
|
req,
|
||||||
@@ -1423,7 +1447,7 @@ export default class DevServer {
|
|||||||
origUrl.pathname = dest;
|
origUrl.pathname = dest;
|
||||||
Object.assign(origUrl.query, uri_args);
|
Object.assign(origUrl.query, uri_args);
|
||||||
const newUrl = url.format(origUrl);
|
const newUrl = url.format(origUrl);
|
||||||
this.output.debug(
|
debug(
|
||||||
`Checking build result's ${buildResult.routes.length} \`routes\` to match ${newUrl}`
|
`Checking build result's ${buildResult.routes.length} \`routes\` to match ${newUrl}`
|
||||||
);
|
);
|
||||||
const matchedRoute = await devRouter(
|
const matchedRoute = await devRouter(
|
||||||
@@ -1433,9 +1457,7 @@ export default class DevServer {
|
|||||||
this
|
this
|
||||||
);
|
);
|
||||||
if (matchedRoute.found && callLevel === 0) {
|
if (matchedRoute.found && callLevel === 0) {
|
||||||
this.output.debug(
|
debug(`Found matching route ${matchedRoute.dest} for ${newUrl}`);
|
||||||
`Found matching route ${matchedRoute.dest} for ${newUrl}`
|
|
||||||
);
|
|
||||||
req.url = newUrl;
|
req.url = newUrl;
|
||||||
await this.serveProjectAsNowV2(
|
await this.serveProjectAsNowV2(
|
||||||
req,
|
req,
|
||||||
@@ -1449,7 +1471,76 @@ export default class DevServer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Before doing any asset matching, check if this builder supports the
|
||||||
|
// `startDevServer()` "optimization". In this case, the now dev server invokes
|
||||||
|
// `startDevServer()` on the builder for every HTTP request so that it boots
|
||||||
|
// up a single-serve dev HTTP server that now dev will proxy this HTTP request
|
||||||
|
// to. Once the proxied request is finished, now dev shuts down the dev
|
||||||
|
// server child process.
|
||||||
|
const { builder, package: builderPkg } = match.builderWithPkg;
|
||||||
|
if (typeof builder.startDevServer === 'function') {
|
||||||
|
let devServerResult: StartDevServerResult = null;
|
||||||
|
try {
|
||||||
|
devServerResult = await builder.startDevServer({
|
||||||
|
entrypoint: match.entrypoint,
|
||||||
|
workPath: this.cwd,
|
||||||
|
config: match.config || {},
|
||||||
|
env: this.envConfigs.runEnv || {},
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
// `startDevServer()` threw an error. Most likely this means the dev
|
||||||
|
// server process exited before sending the port information message
|
||||||
|
// (missing dependency at runtime, for example).
|
||||||
|
debug(`Error starting "${builderPkg.name}" dev server: ${err}`);
|
||||||
|
await this.sendError(
|
||||||
|
req,
|
||||||
|
res,
|
||||||
|
nowRequestId,
|
||||||
|
'NO_STATUS_CODE_FROM_DEV_SERVER',
|
||||||
|
502
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (devServerResult) {
|
||||||
|
// When invoking lambda functions, the region where the lambda was invoked
|
||||||
|
// is also included in the request ID. So use the same `dev1` fake region.
|
||||||
|
nowRequestId = generateRequestId(this.podId, true);
|
||||||
|
|
||||||
|
const { port, pid } = devServerResult;
|
||||||
|
this.devServerPids.add(pid);
|
||||||
|
|
||||||
|
res.once('close', () => {
|
||||||
|
this.killBuilderDevServer(pid);
|
||||||
|
});
|
||||||
|
|
||||||
|
debug(
|
||||||
|
`Proxying to "${builderPkg.name}" dev server (port=${port}, pid=${pid})`
|
||||||
|
);
|
||||||
|
|
||||||
|
// Mix in the routing based query parameters
|
||||||
|
const parsed = url.parse(req.url || '/', true);
|
||||||
|
Object.assign(parsed.query, uri_args);
|
||||||
|
req.url = url.format({
|
||||||
|
pathname: parsed.pathname,
|
||||||
|
query: parsed.query,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.setResponseHeaders(res, nowRequestId);
|
||||||
|
return proxyPass(
|
||||||
|
req,
|
||||||
|
res,
|
||||||
|
`http://localhost:${port}`,
|
||||||
|
this.output,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
debug(`Skipping \`startDevServer()\` for ${match.entrypoint}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let foundAsset = findAsset(match, requestPath, nowConfig);
|
let foundAsset = findAsset(match, requestPath, nowConfig);
|
||||||
|
|
||||||
if (!foundAsset && callLevel === 0) {
|
if (!foundAsset && callLevel === 0) {
|
||||||
await this.triggerBuild(match, buildRequestPath, req);
|
await this.triggerBuild(match, buildRequestPath, req);
|
||||||
|
|
||||||
@@ -1464,7 +1555,7 @@ export default class DevServer {
|
|||||||
this.devProcessPort &&
|
this.devProcessPort &&
|
||||||
(!foundAsset || (foundAsset && foundAsset.asset.type !== 'Lambda'))
|
(!foundAsset || (foundAsset && foundAsset.asset.type !== 'Lambda'))
|
||||||
) {
|
) {
|
||||||
this.output.debug('Proxy to dev command server');
|
debug('Proxying to frontend dev server');
|
||||||
this.setResponseHeaders(res, nowRequestId);
|
this.setResponseHeaders(res, nowRequestId);
|
||||||
return proxyPass(
|
return proxyPass(
|
||||||
req,
|
req,
|
||||||
@@ -1481,7 +1572,7 @@ export default class DevServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const { asset, assetKey } = foundAsset;
|
const { asset, assetKey } = foundAsset;
|
||||||
this.output.debug(
|
debug(
|
||||||
`Serving asset: [${asset.type}] ${assetKey} ${(asset as any)
|
`Serving asset: [${asset.type}] ${assetKey} ${(asset as any)
|
||||||
.contentType || ''}`
|
.contentType || ''}`
|
||||||
);
|
);
|
||||||
@@ -1550,7 +1641,7 @@ export default class DevServer {
|
|||||||
body: body.toString('base64'),
|
body: body.toString('base64'),
|
||||||
};
|
};
|
||||||
|
|
||||||
this.output.debug(`Invoking lambda: "${assetKey}" with ${path}`);
|
debug(`Invoking lambda: "${assetKey}" with ${path}`);
|
||||||
|
|
||||||
let result: InvokeResult;
|
let result: InvokeResult;
|
||||||
try {
|
try {
|
||||||
@@ -1699,7 +1790,7 @@ export default class DevServer {
|
|||||||
|
|
||||||
const port = await getPort();
|
const port = await getPort();
|
||||||
|
|
||||||
const env: EnvConfig = {
|
const env: Env = {
|
||||||
// Because of child process 'pipe' below, isTTY will be false.
|
// Because of child process 'pipe' below, isTTY will be false.
|
||||||
// Most frameworks use `chalk`/`supports-color` so we enable it anyway.
|
// Most frameworks use `chalk`/`supports-color` so we enable it anyway.
|
||||||
FORCE_COLOR: process.stdout.isTTY ? '1' : '0',
|
FORCE_COLOR: process.stdout.isTTY ? '1' : '0',
|
||||||
@@ -1912,7 +2003,7 @@ async function shouldServe(
|
|||||||
const shouldServe = await builder.shouldServe({
|
const shouldServe = await builder.shouldServe({
|
||||||
entrypoint: src,
|
entrypoint: src,
|
||||||
files,
|
files,
|
||||||
config,
|
config: config || {},
|
||||||
requestPath,
|
requestPath,
|
||||||
workPath: devServer.cwd,
|
workPath: devServer.cwd,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
import { basename, extname, join } from 'path';
|
import { basename, extname, join } from 'path';
|
||||||
import { BuilderParams, BuildResult, ShouldServeParams } from './types';
|
import {
|
||||||
|
FileFsRef,
|
||||||
|
BuildOptions,
|
||||||
|
ShouldServeOptions,
|
||||||
|
} from '@vercel/build-utils';
|
||||||
|
import { BuildResult } from './types';
|
||||||
|
|
||||||
export const version = 2;
|
export const version = 2;
|
||||||
|
|
||||||
@@ -7,7 +12,7 @@ export function build({
|
|||||||
files,
|
files,
|
||||||
entrypoint,
|
entrypoint,
|
||||||
config,
|
config,
|
||||||
}: BuilderParams): BuildResult {
|
}: BuildOptions): BuildResult {
|
||||||
let path = entrypoint;
|
let path = entrypoint;
|
||||||
const outputDir = config.zeroConfig ? config.outputDirectory : '';
|
const outputDir = config.zeroConfig ? config.outputDirectory : '';
|
||||||
const outputMatch = outputDir + '/';
|
const outputMatch = outputDir + '/';
|
||||||
@@ -16,7 +21,7 @@ export function build({
|
|||||||
path = path.slice(outputMatch.length);
|
path = path.slice(outputMatch.length);
|
||||||
}
|
}
|
||||||
const output = {
|
const output = {
|
||||||
[path]: files[entrypoint],
|
[path]: files[entrypoint] as FileFsRef,
|
||||||
};
|
};
|
||||||
const watch = [path];
|
const watch = [path];
|
||||||
|
|
||||||
@@ -28,7 +33,7 @@ export function shouldServe({
|
|||||||
files,
|
files,
|
||||||
requestPath,
|
requestPath,
|
||||||
config = {},
|
config = {},
|
||||||
}: ShouldServeParams) {
|
}: ShouldServeOptions) {
|
||||||
let outputPrefix = '';
|
let outputPrefix = '';
|
||||||
const outputDir = config.zeroConfig ? config.outputDirectory : '';
|
const outputDir = config.zeroConfig ? config.outputDirectory : '';
|
||||||
const outputMatch = outputDir + '/';
|
const outputMatch = outputDir + '/';
|
||||||
|
|||||||
@@ -3,12 +3,16 @@ import { ChildProcess } from 'child_process';
|
|||||||
import { Lambda as FunLambda } from '@zeit/fun';
|
import { Lambda as FunLambda } from '@zeit/fun';
|
||||||
import {
|
import {
|
||||||
Builder as BuildConfig,
|
Builder as BuildConfig,
|
||||||
|
BuildOptions,
|
||||||
|
PrepareCacheOptions,
|
||||||
|
ShouldServeOptions,
|
||||||
|
StartDevServerOptions,
|
||||||
|
StartDevServerResult,
|
||||||
|
Env,
|
||||||
FileBlob,
|
FileBlob,
|
||||||
FileFsRef,
|
FileFsRef,
|
||||||
Lambda,
|
Lambda,
|
||||||
PackageJson,
|
PackageJson,
|
||||||
Config,
|
|
||||||
Meta,
|
|
||||||
} from '@vercel/build-utils';
|
} from '@vercel/build-utils';
|
||||||
import { NowConfig } from '@vercel/client';
|
import { NowConfig } from '@vercel/client';
|
||||||
import { HandleValue, Route } from '@vercel/routing-utils';
|
import { HandleValue, Route } from '@vercel/routing-utils';
|
||||||
@@ -23,25 +27,21 @@ export interface DevServerOptions {
|
|||||||
frameworkSlug: string | null;
|
frameworkSlug: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface EnvConfig {
|
|
||||||
[name: string]: string | undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface EnvConfigs {
|
export interface EnvConfigs {
|
||||||
/**
|
/**
|
||||||
* environment variables from `.env.build` file (deprecated)
|
* environment variables from `.env.build` file (deprecated)
|
||||||
*/
|
*/
|
||||||
buildEnv: EnvConfig;
|
buildEnv: Env;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* environment variables from `.env` file
|
* environment variables from `.env` file
|
||||||
*/
|
*/
|
||||||
runEnv: EnvConfig;
|
runEnv: Env;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* environment variables from `.env` and `.env.build`
|
* environment variables from `.env` and `.env.build`
|
||||||
*/
|
*/
|
||||||
allEnv: EnvConfig;
|
allEnv: Env;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface BuildMatch extends BuildConfig {
|
export interface BuildMatch extends BuildConfig {
|
||||||
@@ -53,8 +53,6 @@ export interface BuildMatch extends BuildConfig {
|
|||||||
buildProcess?: ChildProcess;
|
buildProcess?: ChildProcess;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type RouteConfig = Route;
|
|
||||||
|
|
||||||
export interface HttpHandler {
|
export interface HttpHandler {
|
||||||
(req: http.IncomingMessage, res: http.ServerResponse): void;
|
(req: http.IncomingMessage, res: http.ServerResponse): void;
|
||||||
}
|
}
|
||||||
@@ -63,9 +61,9 @@ export interface BuilderInputs {
|
|||||||
[path: string]: FileFsRef;
|
[path: string]: FileFsRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type BuiltLambda = Lambda & {
|
export interface BuiltLambda extends Lambda {
|
||||||
fn?: FunLambda;
|
fn?: FunLambda;
|
||||||
};
|
}
|
||||||
|
|
||||||
export type BuilderOutput = BuiltLambda | FileFsRef | FileBlob;
|
export type BuilderOutput = BuiltLambda | FileFsRef | FileBlob;
|
||||||
|
|
||||||
@@ -79,21 +77,6 @@ export interface CacheOutputs {
|
|||||||
[path: string]: CacheOutput;
|
[path: string]: CacheOutput;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface BuilderParamsBase {
|
|
||||||
files: BuilderInputs;
|
|
||||||
entrypoint: string;
|
|
||||||
config: Config;
|
|
||||||
meta?: Meta;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface BuilderParams extends BuilderParamsBase {
|
|
||||||
workPath: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface PrepareCacheParams extends BuilderParams {
|
|
||||||
cachePath: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface BuilderConfigAttr {
|
export interface BuilderConfigAttr {
|
||||||
maxLambdaSize?: string | number;
|
maxLambdaSize?: string | number;
|
||||||
}
|
}
|
||||||
@@ -102,49 +85,43 @@ export interface Builder {
|
|||||||
version?: 1 | 2 | 3 | 4;
|
version?: 1 | 2 | 3 | 4;
|
||||||
config?: BuilderConfigAttr;
|
config?: BuilderConfigAttr;
|
||||||
build(
|
build(
|
||||||
params: BuilderParams
|
opts: BuildOptions
|
||||||
):
|
):
|
||||||
| BuilderOutputs
|
| BuilderOutputs
|
||||||
| BuildResult
|
| BuildResult
|
||||||
| Promise<BuilderOutputs>
|
| Promise<BuilderOutputs>
|
||||||
| Promise<BuildResult>;
|
| Promise<BuildResult>;
|
||||||
shouldServe?(params: ShouldServeParams): boolean | Promise<boolean>;
|
|
||||||
prepareCache?(
|
prepareCache?(
|
||||||
params: PrepareCacheParams
|
opts: PrepareCacheOptions
|
||||||
): CacheOutputs | Promise<CacheOutputs>;
|
): CacheOutputs | Promise<CacheOutputs>;
|
||||||
|
shouldServe?(params: ShouldServeOptions): boolean | Promise<boolean>;
|
||||||
|
startDevServer?(opts: StartDevServerOptions): Promise<StartDevServerResult>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface BuildResult {
|
export interface BuildResult {
|
||||||
output: BuilderOutputs;
|
output: BuilderOutputs;
|
||||||
routes: RouteConfig[];
|
routes: Route[];
|
||||||
watch: string[];
|
watch: string[];
|
||||||
distPath?: string;
|
distPath?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface BuildResultV3 {
|
export interface BuildResultV3 {
|
||||||
output: Lambda;
|
output: Lambda;
|
||||||
routes: RouteConfig[];
|
routes: Route[];
|
||||||
watch: string[];
|
watch: string[];
|
||||||
distPath?: string;
|
distPath?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface BuildResultV4 {
|
export interface BuildResultV4 {
|
||||||
output: { [filePath: string]: Lambda };
|
output: { [filePath: string]: Lambda };
|
||||||
routes: RouteConfig[];
|
routes: Route[];
|
||||||
watch: string[];
|
watch: string[];
|
||||||
distPath?: string;
|
distPath?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ShouldServeParams {
|
|
||||||
files: BuilderInputs;
|
|
||||||
entrypoint: string;
|
|
||||||
config?: Config;
|
|
||||||
requestPath: string;
|
|
||||||
workPath: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface BuilderWithPackage {
|
export interface BuilderWithPackage {
|
||||||
runInProcess?: boolean;
|
runInProcess?: boolean;
|
||||||
|
requirePath: string;
|
||||||
builder: Readonly<Builder>;
|
builder: Readonly<Builder>;
|
||||||
package: Readonly<PackageJson>;
|
package: Readonly<PackageJson>;
|
||||||
}
|
}
|
||||||
@@ -167,7 +144,7 @@ export interface RouteResult {
|
|||||||
// "uri_args": <object (key=value) list of new uri args to be passed along to dest >
|
// "uri_args": <object (key=value) list of new uri args to be passed along to dest >
|
||||||
uri_args?: { [key: string]: any };
|
uri_args?: { [key: string]: any };
|
||||||
// "matched_route": <object of the route spec that matched>
|
// "matched_route": <object of the route spec that matched>
|
||||||
matched_route?: RouteConfig;
|
matched_route?: Route;
|
||||||
// "matched_route_idx": <integer of the index of the route matched>
|
// "matched_route_idx": <integer of the index of the route matched>
|
||||||
matched_route_idx?: number;
|
matched_route_idx?: number;
|
||||||
// "userDest": <boolean in case the destination was user defined>
|
// "userDest": <boolean in case the destination was user defined>
|
||||||
|
|||||||
@@ -1,103 +0,0 @@
|
|||||||
import { createHash } from 'crypto';
|
|
||||||
import {
|
|
||||||
mkdirp,
|
|
||||||
createWriteStream,
|
|
||||||
writeFile,
|
|
||||||
statSync,
|
|
||||||
chmodSync,
|
|
||||||
createReadStream,
|
|
||||||
} from 'fs-extra';
|
|
||||||
import pipe from 'promisepipe';
|
|
||||||
import { join } from 'path';
|
|
||||||
import fetch from 'node-fetch';
|
|
||||||
import { Output } from '../output/create-output';
|
|
||||||
import { builderDirPromise } from './builder-cache';
|
|
||||||
|
|
||||||
const YARN_VERSION = '1.17.3';
|
|
||||||
const YARN_SHA = '77f28b2793ca7d0ab5bd5da072afc423f7fdf733';
|
|
||||||
const YARN_URL = `https://github.com/yarnpkg/yarn/releases/download/v${YARN_VERSION}/yarn-${YARN_VERSION}.js`;
|
|
||||||
|
|
||||||
function plusxSync(file: string): void {
|
|
||||||
const s = statSync(file);
|
|
||||||
const newMode = s.mode | 64 | 8 | 1;
|
|
||||||
|
|
||||||
if (s.mode === newMode) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const base8 = newMode.toString(8).slice(-3);
|
|
||||||
chmodSync(file, base8);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getSha1(filePath: string): Promise<string | null> {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const hash = createHash('sha1');
|
|
||||||
const stream = createReadStream(filePath);
|
|
||||||
stream.on('error', err => {
|
|
||||||
if (err.code === 'ENOENT') {
|
|
||||||
resolve(null);
|
|
||||||
} else {
|
|
||||||
reject(err);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
stream.on('data', chunk => hash.update(chunk));
|
|
||||||
stream.on('end', () => resolve(hash.digest('hex')));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async function installYarn(output: Output): Promise<string> {
|
|
||||||
// Loosely based on https://yarnpkg.com/install.sh
|
|
||||||
const dirName = await builderDirPromise;
|
|
||||||
const yarnBin = join(dirName, 'yarn');
|
|
||||||
const sha1 = await getSha1(yarnBin);
|
|
||||||
|
|
||||||
if (sha1 === YARN_SHA) {
|
|
||||||
output.debug('The yarn executable is already cached, not re-downloading');
|
|
||||||
return dirName;
|
|
||||||
}
|
|
||||||
|
|
||||||
output.debug(`Creating directory ${dirName}`);
|
|
||||||
await mkdirp(dirName);
|
|
||||||
output.debug(`Finished creating ${dirName}`);
|
|
||||||
|
|
||||||
output.debug(`Downloading ${YARN_URL}`);
|
|
||||||
const response = await fetch(YARN_URL, {
|
|
||||||
compress: false,
|
|
||||||
redirect: 'follow',
|
|
||||||
});
|
|
||||||
|
|
||||||
if (response.status !== 200) {
|
|
||||||
throw new Error(`Received invalid response: ${await response.text()}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const target = createWriteStream(yarnBin);
|
|
||||||
await pipe(
|
|
||||||
response.body,
|
|
||||||
target
|
|
||||||
);
|
|
||||||
output.debug(`Finished downloading yarn ${yarnBin}`);
|
|
||||||
|
|
||||||
output.debug(`Making the yarn binary executable`);
|
|
||||||
plusxSync(yarnBin);
|
|
||||||
output.debug(`Finished making the yarn binary executable`);
|
|
||||||
|
|
||||||
if (process.platform === 'win32') {
|
|
||||||
// The `yarn.cmd` file is necessary for `yarn` to be executable
|
|
||||||
// when running `now dev` through cmd.exe
|
|
||||||
await writeFile(
|
|
||||||
`${yarnBin}.cmd`,
|
|
||||||
[
|
|
||||||
'@echo off',
|
|
||||||
'@SETLOCAL',
|
|
||||||
'@SET PATHEXT=%PATHEXT:;.JS;=;%',
|
|
||||||
'node "%~dp0\\yarn" %*',
|
|
||||||
].join('\r\n')
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return dirName;
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getYarnPath(output: Output): Promise<string> {
|
|
||||||
return installYarn(output);
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
import { EventEmitter } from 'events';
|
|
||||||
|
|
||||||
export function once<T>(emitter: EventEmitter, name: string): Promise<T> {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
function cleanup() {
|
|
||||||
emitter.removeListener(name, onEvent);
|
|
||||||
emitter.removeListener('error', onError);
|
|
||||||
}
|
|
||||||
function onEvent(arg: T) {
|
|
||||||
cleanup();
|
|
||||||
resolve(arg);
|
|
||||||
}
|
|
||||||
function onError(err: Error) {
|
|
||||||
cleanup();
|
|
||||||
reject(err);
|
|
||||||
}
|
|
||||||
emitter.on(name, onEvent);
|
|
||||||
emitter.on('error', onError);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -1,13 +1,6 @@
|
|||||||
import path from 'path';
|
import _pkg from '../../package.json';
|
||||||
import pkg from '../../package.json';
|
import { PackageJson } from '@vercel/build-utils';
|
||||||
|
|
||||||
try {
|
const pkg: PackageJson = _pkg;
|
||||||
const distDir = path.dirname(process.execPath);
|
|
||||||
// @ts-ignore
|
|
||||||
pkg._npmPkg = require(`${path.join(distDir, '../../package.json')}`);
|
|
||||||
} catch (err) {
|
|
||||||
// @ts-ignore
|
|
||||||
pkg._npmPkg = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default pkg;
|
export default pkg;
|
||||||
|
|||||||
4
packages/now-cli/src/util/tree-kill.ts
Normal file
4
packages/now-cli/src/util/tree-kill.ts
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
import _treeKill from 'tree-kill';
|
||||||
|
import { promisify } from 'util';
|
||||||
|
|
||||||
|
export const treeKill = promisify(_treeKill);
|
||||||
184
packages/now-cli/test/dev-builder.unit.js
vendored
184
packages/now-cli/test/dev-builder.unit.js
vendored
@@ -1,17 +1,23 @@
|
|||||||
import test from 'ava';
|
import test from 'ava';
|
||||||
import { filterPackage } from '../src/util/dev/builder-cache';
|
import npa from 'npm-package-arg';
|
||||||
|
import { filterPackage, isBundledBuilder } from '../src/util/dev/builder-cache';
|
||||||
|
|
||||||
test('[dev-builder] filter install "latest", cached canary', async t => {
|
test('[dev-builder] filter install "latest", cached canary', t => {
|
||||||
const buildersPkg = {
|
const buildersPkg = {
|
||||||
dependencies: {
|
dependencies: {
|
||||||
'@vercel/build-utils': '0.0.1-canary.0',
|
'@vercel/build-utils': '0.0.1-canary.0',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const result = filterPackage('@vercel/build-utils', 'canary', buildersPkg);
|
const result = filterPackage(
|
||||||
|
'@vercel/build-utils',
|
||||||
|
'canary',
|
||||||
|
buildersPkg,
|
||||||
|
{}
|
||||||
|
);
|
||||||
t.is(result, true);
|
t.is(result, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('[dev-builder] filter install "canary", cached stable', async t => {
|
test('[dev-builder] filter install "canary", cached stable', t => {
|
||||||
const buildersPkg = {
|
const buildersPkg = {
|
||||||
dependencies: {
|
dependencies: {
|
||||||
'@vercel/build-utils': '0.0.1',
|
'@vercel/build-utils': '0.0.1',
|
||||||
@@ -20,22 +26,28 @@ test('[dev-builder] filter install "canary", cached stable', async t => {
|
|||||||
const result = filterPackage(
|
const result = filterPackage(
|
||||||
'@vercel/build-utils@canary',
|
'@vercel/build-utils@canary',
|
||||||
'latest',
|
'latest',
|
||||||
buildersPkg
|
buildersPkg,
|
||||||
|
{}
|
||||||
);
|
);
|
||||||
t.is(result, true);
|
t.is(result, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('[dev-builder] filter install "latest", cached stable', async t => {
|
test('[dev-builder] filter install "latest", cached stable', t => {
|
||||||
const buildersPkg = {
|
const buildersPkg = {
|
||||||
dependencies: {
|
dependencies: {
|
||||||
'@vercel/build-utils': '0.0.1',
|
'@vercel/build-utils': '0.0.1',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const result = filterPackage('@vercel/build-utils', 'latest', buildersPkg);
|
const result = filterPackage(
|
||||||
|
'@vercel/build-utils',
|
||||||
|
'latest',
|
||||||
|
buildersPkg,
|
||||||
|
{}
|
||||||
|
);
|
||||||
t.is(result, false);
|
t.is(result, false);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('[dev-builder] filter install "canary", cached canary', async t => {
|
test('[dev-builder] filter install "canary", cached canary', t => {
|
||||||
const buildersPkg = {
|
const buildersPkg = {
|
||||||
dependencies: {
|
dependencies: {
|
||||||
'@vercel/build-utils': '0.0.1-canary.0',
|
'@vercel/build-utils': '0.0.1-canary.0',
|
||||||
@@ -44,87 +56,209 @@ test('[dev-builder] filter install "canary", cached canary', async t => {
|
|||||||
const result = filterPackage(
|
const result = filterPackage(
|
||||||
'@vercel/build-utils@canary',
|
'@vercel/build-utils@canary',
|
||||||
'canary',
|
'canary',
|
||||||
buildersPkg
|
buildersPkg,
|
||||||
|
{}
|
||||||
);
|
);
|
||||||
t.is(result, false);
|
t.is(result, false);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('[dev-builder] filter install URL, cached stable', async t => {
|
test('[dev-builder] filter install URL, cached stable', t => {
|
||||||
const buildersPkg = {
|
const buildersPkg = {
|
||||||
dependencies: {
|
dependencies: {
|
||||||
'@vercel/build-utils': '0.0.1',
|
'@vercel/build-utils': '0.0.1',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const result = filterPackage('https://tarball.now.sh', 'latest', buildersPkg);
|
const result = filterPackage(
|
||||||
|
'https://tarball.now.sh',
|
||||||
|
'latest',
|
||||||
|
buildersPkg,
|
||||||
|
{}
|
||||||
|
);
|
||||||
t.is(result, true);
|
t.is(result, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('[dev-builder] filter install URL, cached canary', async t => {
|
test('[dev-builder] filter install URL, cached canary', t => {
|
||||||
const buildersPkg = {
|
const buildersPkg = {
|
||||||
dependencies: {
|
dependencies: {
|
||||||
'@vercel/build-utils': '0.0.1-canary.0',
|
'@vercel/build-utils': '0.0.1-canary.0',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const result = filterPackage('https://tarball.now.sh', 'canary', buildersPkg);
|
const result = filterPackage(
|
||||||
|
'https://tarball.now.sh',
|
||||||
|
'canary',
|
||||||
|
buildersPkg,
|
||||||
|
{}
|
||||||
|
);
|
||||||
t.is(result, true);
|
t.is(result, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('[dev-builder] filter install "latest", cached URL - stable', async t => {
|
test('[dev-builder] filter install "latest", cached URL - stable', t => {
|
||||||
const buildersPkg = {
|
const buildersPkg = {
|
||||||
dependencies: {
|
dependencies: {
|
||||||
'@vercel/build-utils': 'https://tarball.now.sh',
|
'@vercel/build-utils': 'https://tarball.now.sh',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const result = filterPackage('@vercel/build-utils', 'latest', buildersPkg);
|
const result = filterPackage(
|
||||||
|
'@vercel/build-utils',
|
||||||
|
'latest',
|
||||||
|
buildersPkg,
|
||||||
|
{}
|
||||||
|
);
|
||||||
t.is(result, true);
|
t.is(result, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('[dev-builder] filter install "latest", cached URL - canary', async t => {
|
test('[dev-builder] filter install "latest", cached URL - canary', t => {
|
||||||
const buildersPkg = {
|
const buildersPkg = {
|
||||||
dependencies: {
|
dependencies: {
|
||||||
'@vercel/build-utils': 'https://tarball.now.sh',
|
'@vercel/build-utils': 'https://tarball.now.sh',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const result = filterPackage('@vercel/build-utils', 'canary', buildersPkg);
|
const result = filterPackage(
|
||||||
|
'@vercel/build-utils',
|
||||||
|
'canary',
|
||||||
|
buildersPkg,
|
||||||
|
{}
|
||||||
|
);
|
||||||
t.is(result, true);
|
t.is(result, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('[dev-builder] filter install not bundled version, cached same version', async t => {
|
test('[dev-builder] filter install not bundled version, cached same version', t => {
|
||||||
const buildersPkg = {
|
const buildersPkg = {
|
||||||
dependencies: {
|
dependencies: {
|
||||||
'not-bundled-package': '0.0.1',
|
'not-bundled-package': '0.0.1',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const result = filterPackage('not-bundled-package@0.0.1', '_', buildersPkg);
|
const result = filterPackage(
|
||||||
|
'not-bundled-package@0.0.1',
|
||||||
|
'_',
|
||||||
|
buildersPkg,
|
||||||
|
{}
|
||||||
|
);
|
||||||
t.is(result, false);
|
t.is(result, false);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('[dev-builder] filter install not bundled version, cached different version', async t => {
|
test('[dev-builder] filter install not bundled version, cached different version', t => {
|
||||||
const buildersPkg = {
|
const buildersPkg = {
|
||||||
dependencies: {
|
dependencies: {
|
||||||
'not-bundled-package': '0.0.9',
|
'not-bundled-package': '0.0.9',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const result = filterPackage('not-bundled-package@0.0.1', '_', buildersPkg);
|
const result = filterPackage(
|
||||||
|
'not-bundled-package@0.0.1',
|
||||||
|
'_',
|
||||||
|
buildersPkg,
|
||||||
|
{}
|
||||||
|
);
|
||||||
t.is(result, true);
|
t.is(result, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('[dev-builder] filter install not bundled stable, cached version', async t => {
|
test('[dev-builder] filter install not bundled stable, cached version', t => {
|
||||||
const buildersPkg = {
|
const buildersPkg = {
|
||||||
dependencies: {
|
dependencies: {
|
||||||
'not-bundled-package': '0.0.1',
|
'not-bundled-package': '0.0.1',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const result = filterPackage('not-bundled-package', '_', buildersPkg);
|
const result = filterPackage('not-bundled-package', '_', buildersPkg, {});
|
||||||
t.is(result, true);
|
t.is(result, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('[dev-builder] filter install not bundled tagged, cached tagged', async t => {
|
test('[dev-builder] filter install not bundled tagged, cached tagged', t => {
|
||||||
const buildersPkg = {
|
const buildersPkg = {
|
||||||
dependencies: {
|
dependencies: {
|
||||||
'not-bundled-package': '16.9.0-alpha.0',
|
'not-bundled-package': '16.9.0-alpha.0',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const result = filterPackage('not-bundled-package@alpha', '_', buildersPkg);
|
const result = filterPackage(
|
||||||
|
'not-bundled-package@alpha',
|
||||||
|
'_',
|
||||||
|
buildersPkg,
|
||||||
|
{}
|
||||||
|
);
|
||||||
t.is(result, true);
|
t.is(result, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('[dev-builder] isBundledBuilder() - stable', t => {
|
||||||
|
const nowCliPkg = {
|
||||||
|
dependencies: {
|
||||||
|
'@now/node': '1.5.2',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// "canary" tag
|
||||||
|
{
|
||||||
|
const parsed = npa('@now/node@canary');
|
||||||
|
const result = isBundledBuilder(parsed, nowCliPkg);
|
||||||
|
t.is(result, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// "latest" tag
|
||||||
|
{
|
||||||
|
const parsed = npa('@now/node');
|
||||||
|
const result = isBundledBuilder(parsed, nowCliPkg);
|
||||||
|
t.is(result, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// specific matching version
|
||||||
|
{
|
||||||
|
const parsed = npa('@now/node@1.5.2');
|
||||||
|
const result = isBundledBuilder(parsed, nowCliPkg);
|
||||||
|
t.is(result, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// specific non-matching version
|
||||||
|
{
|
||||||
|
const parsed = npa('@now/node@1.5.1');
|
||||||
|
const result = isBundledBuilder(parsed, nowCliPkg);
|
||||||
|
t.is(result, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// URL
|
||||||
|
{
|
||||||
|
const parsed = npa('https://example.com');
|
||||||
|
const result = isBundledBuilder(parsed, nowCliPkg);
|
||||||
|
t.is(result, false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test('[dev-builder] isBundledBuilder() - canary', t => {
|
||||||
|
const nowCliPkg = {
|
||||||
|
dependencies: {
|
||||||
|
'@now/node': '1.5.2-canary.3',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// "canary" tag
|
||||||
|
{
|
||||||
|
const parsed = npa('@now/node@canary');
|
||||||
|
const result = isBundledBuilder(parsed, nowCliPkg);
|
||||||
|
t.is(result, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// "latest" tag
|
||||||
|
{
|
||||||
|
const parsed = npa('@now/node');
|
||||||
|
const result = isBundledBuilder(parsed, nowCliPkg);
|
||||||
|
t.is(result, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// specific matching version
|
||||||
|
{
|
||||||
|
const parsed = npa('@now/node@1.5.2-canary.3');
|
||||||
|
const result = isBundledBuilder(parsed, nowCliPkg);
|
||||||
|
t.is(result, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// specific non-matching version
|
||||||
|
{
|
||||||
|
const parsed = npa('@now/node@1.5.2-canary.2');
|
||||||
|
const result = isBundledBuilder(parsed, nowCliPkg);
|
||||||
|
t.is(result, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// URL
|
||||||
|
{
|
||||||
|
const parsed = npa('https://example.com');
|
||||||
|
const result = isBundledBuilder(parsed, nowCliPkg);
|
||||||
|
t.is(result, false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|||||||
2
packages/now-cli/test/dev-server.unit.js
vendored
2
packages/now-cli/test/dev-server.unit.js
vendored
@@ -289,6 +289,7 @@ test(
|
|||||||
testFixture('now-dev-static-routes', async (t, server) => {
|
testFixture('now-dev-static-routes', async (t, server) => {
|
||||||
{
|
{
|
||||||
const res = await fetch(`${server.address}/`);
|
const res = await fetch(`${server.address}/`);
|
||||||
|
t.is(res.status, 200);
|
||||||
const body = await res.text();
|
const body = await res.text();
|
||||||
t.is(body, '<body>Hello!</body>\n');
|
t.is(body, '<body>Hello!</body>\n');
|
||||||
}
|
}
|
||||||
@@ -300,6 +301,7 @@ test(
|
|||||||
testFixture('now-dev-static-build-routing', async (t, server) => {
|
testFixture('now-dev-static-build-routing', async (t, server) => {
|
||||||
{
|
{
|
||||||
const res = await fetch(`${server.address}/api/date`);
|
const res = await fetch(`${server.address}/api/date`);
|
||||||
|
t.is(res.status, 200);
|
||||||
const body = await res.text();
|
const body = await res.text();
|
||||||
t.is(body.startsWith('The current date:'), true);
|
t.is(body.startsWith('The current date:'), true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1074,11 +1074,6 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d"
|
resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d"
|
||||||
integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==
|
integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==
|
||||||
|
|
||||||
abbrev@1:
|
|
||||||
version "1.1.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8"
|
|
||||||
integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==
|
|
||||||
|
|
||||||
accepts@~1.3.5:
|
accepts@~1.3.5:
|
||||||
version "1.3.7"
|
version "1.3.7"
|
||||||
resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd"
|
resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd"
|
||||||
@@ -1147,11 +1142,6 @@ ansi-regex@^2.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
|
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
|
||||||
integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8=
|
integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8=
|
||||||
|
|
||||||
ansi-regex@^3.0.0:
|
|
||||||
version "3.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998"
|
|
||||||
integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=
|
|
||||||
|
|
||||||
ansi-regex@^4.1.0:
|
ansi-regex@^4.1.0:
|
||||||
version "4.1.0"
|
version "4.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997"
|
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997"
|
||||||
@@ -1185,19 +1175,11 @@ anymatch@~3.1.1:
|
|||||||
normalize-path "^3.0.0"
|
normalize-path "^3.0.0"
|
||||||
picomatch "^2.0.4"
|
picomatch "^2.0.4"
|
||||||
|
|
||||||
aproba@^1.0.3, aproba@^1.1.1:
|
aproba@^1.1.1:
|
||||||
version "1.2.0"
|
version "1.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a"
|
resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a"
|
||||||
integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==
|
integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==
|
||||||
|
|
||||||
are-we-there-yet@~1.1.2:
|
|
||||||
version "1.1.5"
|
|
||||||
resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21"
|
|
||||||
integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==
|
|
||||||
dependencies:
|
|
||||||
delegates "^1.0.0"
|
|
||||||
readable-stream "^2.0.6"
|
|
||||||
|
|
||||||
argparse@^1.0.7:
|
argparse@^1.0.7:
|
||||||
version "1.0.10"
|
version "1.0.10"
|
||||||
resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911"
|
resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911"
|
||||||
@@ -1809,11 +1791,6 @@ clone@^1.0.2:
|
|||||||
resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e"
|
resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e"
|
||||||
integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4=
|
integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4=
|
||||||
|
|
||||||
code-point-at@^1.0.0:
|
|
||||||
version "1.1.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
|
|
||||||
integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=
|
|
||||||
|
|
||||||
collection-visit@^1.0.0:
|
collection-visit@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0"
|
resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0"
|
||||||
@@ -1921,11 +1898,6 @@ console-browserify@^1.1.0:
|
|||||||
resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336"
|
resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336"
|
||||||
integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==
|
integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==
|
||||||
|
|
||||||
console-control-strings@^1.0.0, console-control-strings@~1.1.0:
|
|
||||||
version "1.1.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e"
|
|
||||||
integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=
|
|
||||||
|
|
||||||
constants-browserify@^1.0.0:
|
constants-browserify@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75"
|
resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75"
|
||||||
@@ -2154,7 +2126,7 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3:
|
|||||||
dependencies:
|
dependencies:
|
||||||
ms "2.0.0"
|
ms "2.0.0"
|
||||||
|
|
||||||
debug@^3.0.0, debug@^3.2.6:
|
debug@^3.0.0:
|
||||||
version "3.2.6"
|
version "3.2.6"
|
||||||
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b"
|
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b"
|
||||||
integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==
|
integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==
|
||||||
@@ -2173,11 +2145,6 @@ decode-uri-component@^0.2.0:
|
|||||||
resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545"
|
resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545"
|
||||||
integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=
|
integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=
|
||||||
|
|
||||||
deep-extend@^0.6.0:
|
|
||||||
version "0.6.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac"
|
|
||||||
integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==
|
|
||||||
|
|
||||||
defaults@^1.0.3:
|
defaults@^1.0.3:
|
||||||
version "1.0.3"
|
version "1.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d"
|
resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d"
|
||||||
@@ -2226,11 +2193,6 @@ del@^3.0.0:
|
|||||||
pify "^3.0.0"
|
pify "^3.0.0"
|
||||||
rimraf "^2.2.8"
|
rimraf "^2.2.8"
|
||||||
|
|
||||||
delegates@^1.0.0:
|
|
||||||
version "1.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
|
|
||||||
integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=
|
|
||||||
|
|
||||||
depd@~1.1.2:
|
depd@~1.1.2:
|
||||||
version "1.1.2"
|
version "1.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
|
resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
|
||||||
@@ -2249,11 +2211,6 @@ destroy@~1.0.4:
|
|||||||
resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80"
|
resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80"
|
||||||
integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=
|
integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=
|
||||||
|
|
||||||
detect-libc@^1.0.2:
|
|
||||||
version "1.0.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b"
|
|
||||||
integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=
|
|
||||||
|
|
||||||
devalue@2.0.1:
|
devalue@2.0.1:
|
||||||
version "2.0.1"
|
version "2.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/devalue/-/devalue-2.0.1.tgz#5d368f9adc0928e47b77eea53ca60d2f346f9762"
|
resolved "https://registry.yarnpkg.com/devalue/-/devalue-2.0.1.tgz#5d368f9adc0928e47b77eea53ca60d2f346f9762"
|
||||||
@@ -2717,13 +2674,6 @@ from2@^2.1.0:
|
|||||||
inherits "^2.0.1"
|
inherits "^2.0.1"
|
||||||
readable-stream "^2.0.0"
|
readable-stream "^2.0.0"
|
||||||
|
|
||||||
fs-minipass@^1.2.5:
|
|
||||||
version "1.2.7"
|
|
||||||
resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7"
|
|
||||||
integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==
|
|
||||||
dependencies:
|
|
||||||
minipass "^2.6.0"
|
|
||||||
|
|
||||||
fs-write-stream-atomic@^1.0.8:
|
fs-write-stream-atomic@^1.0.8:
|
||||||
version "1.0.10"
|
version "1.0.10"
|
||||||
resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9"
|
resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9"
|
||||||
@@ -2757,20 +2707,6 @@ function-bind@^1.1.1:
|
|||||||
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
|
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
|
||||||
integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
|
integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
|
||||||
|
|
||||||
gauge@~2.7.3:
|
|
||||||
version "2.7.4"
|
|
||||||
resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7"
|
|
||||||
integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=
|
|
||||||
dependencies:
|
|
||||||
aproba "^1.0.3"
|
|
||||||
console-control-strings "^1.0.0"
|
|
||||||
has-unicode "^2.0.0"
|
|
||||||
object-assign "^4.1.0"
|
|
||||||
signal-exit "^3.0.0"
|
|
||||||
string-width "^1.0.1"
|
|
||||||
strip-ansi "^3.0.1"
|
|
||||||
wide-align "^1.1.0"
|
|
||||||
|
|
||||||
get-value@^2.0.3, get-value@^2.0.6:
|
get-value@^2.0.3, get-value@^2.0.6:
|
||||||
version "2.0.6"
|
version "2.0.6"
|
||||||
resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28"
|
resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28"
|
||||||
@@ -2859,11 +2795,6 @@ has-symbols@^1.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8"
|
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8"
|
||||||
integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==
|
integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==
|
||||||
|
|
||||||
has-unicode@^2.0.0:
|
|
||||||
version "2.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
|
|
||||||
integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=
|
|
||||||
|
|
||||||
has-value@^0.3.1:
|
has-value@^0.3.1:
|
||||||
version "0.3.1"
|
version "0.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f"
|
resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f"
|
||||||
@@ -2984,7 +2915,7 @@ https-browserify@^1.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73"
|
resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73"
|
||||||
integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=
|
integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=
|
||||||
|
|
||||||
iconv-lite@0.4.24, iconv-lite@^0.4.4:
|
iconv-lite@0.4.24:
|
||||||
version "0.4.24"
|
version "0.4.24"
|
||||||
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
|
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
|
||||||
integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
|
integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
|
||||||
@@ -3013,13 +2944,6 @@ ignore-loader@0.1.2:
|
|||||||
resolved "https://registry.yarnpkg.com/ignore-loader/-/ignore-loader-0.1.2.tgz#d81f240376d0ba4f0d778972c3ad25874117a463"
|
resolved "https://registry.yarnpkg.com/ignore-loader/-/ignore-loader-0.1.2.tgz#d81f240376d0ba4f0d778972c3ad25874117a463"
|
||||||
integrity sha1-2B8kA3bQuk8Nd4lyw60lh0EXpGM=
|
integrity sha1-2B8kA3bQuk8Nd4lyw60lh0EXpGM=
|
||||||
|
|
||||||
ignore-walk@^3.0.1:
|
|
||||||
version "3.0.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.3.tgz#017e2447184bfeade7c238e4aefdd1e8f95b1e37"
|
|
||||||
integrity sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==
|
|
||||||
dependencies:
|
|
||||||
minimatch "^3.0.4"
|
|
||||||
|
|
||||||
import-cwd@^2.0.0:
|
import-cwd@^2.0.0:
|
||||||
version "2.1.0"
|
version "2.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/import-cwd/-/import-cwd-2.1.0.tgz#aa6cf36e722761285cb371ec6519f53e2435b0a9"
|
resolved "https://registry.yarnpkg.com/import-cwd/-/import-cwd-2.1.0.tgz#aa6cf36e722761285cb371ec6519f53e2435b0a9"
|
||||||
@@ -3080,11 +3004,6 @@ inherits@2.0.3:
|
|||||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
|
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
|
||||||
integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
|
integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
|
||||||
|
|
||||||
ini@~1.3.0:
|
|
||||||
version "1.3.5"
|
|
||||||
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927"
|
|
||||||
integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==
|
|
||||||
|
|
||||||
invariant@^2.2.2:
|
invariant@^2.2.2:
|
||||||
version "2.2.4"
|
version "2.2.4"
|
||||||
resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6"
|
resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6"
|
||||||
@@ -3189,18 +3108,6 @@ is-extglob@^2.1.0, is-extglob@^2.1.1:
|
|||||||
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
|
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
|
||||||
integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=
|
integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=
|
||||||
|
|
||||||
is-fullwidth-code-point@^1.0.0:
|
|
||||||
version "1.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb"
|
|
||||||
integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs=
|
|
||||||
dependencies:
|
|
||||||
number-is-nan "^1.0.0"
|
|
||||||
|
|
||||||
is-fullwidth-code-point@^2.0.0:
|
|
||||||
version "2.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f"
|
|
||||||
integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=
|
|
||||||
|
|
||||||
is-glob@^3.1.0:
|
is-glob@^3.1.0:
|
||||||
version "3.1.0"
|
version "3.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a"
|
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a"
|
||||||
@@ -3749,21 +3656,6 @@ minimist@^1.2.0, minimist@^1.2.5:
|
|||||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
|
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
|
||||||
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
|
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
|
||||||
|
|
||||||
minipass@^2.6.0, minipass@^2.8.6, minipass@^2.9.0:
|
|
||||||
version "2.9.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6"
|
|
||||||
integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==
|
|
||||||
dependencies:
|
|
||||||
safe-buffer "^5.1.2"
|
|
||||||
yallist "^3.0.0"
|
|
||||||
|
|
||||||
minizlib@^1.2.1:
|
|
||||||
version "1.3.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d"
|
|
||||||
integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==
|
|
||||||
dependencies:
|
|
||||||
minipass "^2.9.0"
|
|
||||||
|
|
||||||
mississippi@^3.0.0:
|
mississippi@^3.0.0:
|
||||||
version "3.0.0"
|
version "3.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022"
|
resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022"
|
||||||
@@ -3795,7 +3687,7 @@ mkdirp@0.5.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
minimist "0.0.8"
|
minimist "0.0.8"
|
||||||
|
|
||||||
mkdirp@^0.5.0, mkdirp@^0.5.1:
|
mkdirp@^0.5.1:
|
||||||
version "0.5.5"
|
version "0.5.5"
|
||||||
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def"
|
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def"
|
||||||
integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==
|
integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==
|
||||||
@@ -3851,15 +3743,6 @@ nanomatch@^1.2.9:
|
|||||||
snapdragon "^0.8.1"
|
snapdragon "^0.8.1"
|
||||||
to-regex "^3.0.1"
|
to-regex "^3.0.1"
|
||||||
|
|
||||||
needle@^2.2.1:
|
|
||||||
version "2.4.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/needle/-/needle-2.4.1.tgz#14af48732463d7475696f937626b1b993247a56a"
|
|
||||||
integrity sha512-x/gi6ijr4B7fwl6WYL9FwlCvRQKGlUNvnceho8wxkwXqN8jvVmmmATTmZPRRG7b/yC1eode26C2HO9jl78Du9g==
|
|
||||||
dependencies:
|
|
||||||
debug "^3.2.6"
|
|
||||||
iconv-lite "^0.4.4"
|
|
||||||
sax "^1.2.4"
|
|
||||||
|
|
||||||
negotiator@0.6.2:
|
negotiator@0.6.2:
|
||||||
version "0.6.2"
|
version "0.6.2"
|
||||||
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb"
|
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb"
|
||||||
@@ -4007,35 +3890,11 @@ node-libs-browser@^2.2.1:
|
|||||||
util "^0.11.0"
|
util "^0.11.0"
|
||||||
vm-browserify "^1.0.1"
|
vm-browserify "^1.0.1"
|
||||||
|
|
||||||
node-pre-gyp@*:
|
|
||||||
version "0.14.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.14.0.tgz#9a0596533b877289bcad4e143982ca3d904ddc83"
|
|
||||||
integrity sha512-+CvDC7ZttU/sSt9rFjix/P05iS43qHCOOGzcr3Ry99bXG7VX953+vFyEuph/tfqoYu8dttBkE86JSKBO2OzcxA==
|
|
||||||
dependencies:
|
|
||||||
detect-libc "^1.0.2"
|
|
||||||
mkdirp "^0.5.1"
|
|
||||||
needle "^2.2.1"
|
|
||||||
nopt "^4.0.1"
|
|
||||||
npm-packlist "^1.1.6"
|
|
||||||
npmlog "^4.0.2"
|
|
||||||
rc "^1.2.7"
|
|
||||||
rimraf "^2.6.1"
|
|
||||||
semver "^5.3.0"
|
|
||||||
tar "^4.4.2"
|
|
||||||
|
|
||||||
node-releases@^1.1.44, node-releases@^1.1.53:
|
node-releases@^1.1.44, node-releases@^1.1.53:
|
||||||
version "1.1.53"
|
version "1.1.53"
|
||||||
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.53.tgz#2d821bfa499ed7c5dffc5e2f28c88e78a08ee3f4"
|
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.53.tgz#2d821bfa499ed7c5dffc5e2f28c88e78a08ee3f4"
|
||||||
integrity sha512-wp8zyQVwef2hpZ/dJH7SfSrIPD6YoJz6BDQDpGEkcA0s3LpAQoxBIYmfIq6QAhC1DhwsyCgTaTTcONwX8qzCuQ==
|
integrity sha512-wp8zyQVwef2hpZ/dJH7SfSrIPD6YoJz6BDQDpGEkcA0s3LpAQoxBIYmfIq6QAhC1DhwsyCgTaTTcONwX8qzCuQ==
|
||||||
|
|
||||||
nopt@^4.0.1:
|
|
||||||
version "4.0.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.3.tgz#a375cad9d02fd921278d954c2254d5aa57e15e48"
|
|
||||||
integrity sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==
|
|
||||||
dependencies:
|
|
||||||
abbrev "1"
|
|
||||||
osenv "^0.1.4"
|
|
||||||
|
|
||||||
normalize-html-whitespace@1.0.0:
|
normalize-html-whitespace@1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/normalize-html-whitespace/-/normalize-html-whitespace-1.0.0.tgz#5e3c8e192f1b06c3b9eee4b7e7f28854c7601e34"
|
resolved "https://registry.yarnpkg.com/normalize-html-whitespace/-/normalize-html-whitespace-1.0.0.tgz#5e3c8e192f1b06c3b9eee4b7e7f28854c7601e34"
|
||||||
@@ -4078,47 +3937,11 @@ normalize-url@1.9.1:
|
|||||||
query-string "^4.1.0"
|
query-string "^4.1.0"
|
||||||
sort-keys "^1.0.0"
|
sort-keys "^1.0.0"
|
||||||
|
|
||||||
npm-bundled@^1.0.1:
|
|
||||||
version "1.1.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.1.1.tgz#1edd570865a94cdb1bc8220775e29466c9fb234b"
|
|
||||||
integrity sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA==
|
|
||||||
dependencies:
|
|
||||||
npm-normalize-package-bin "^1.0.1"
|
|
||||||
|
|
||||||
npm-normalize-package-bin@^1.0.1:
|
|
||||||
version "1.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz#6e79a41f23fd235c0623218228da7d9c23b8f6e2"
|
|
||||||
integrity sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==
|
|
||||||
|
|
||||||
npm-packlist@^1.1.6:
|
|
||||||
version "1.4.8"
|
|
||||||
resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.8.tgz#56ee6cc135b9f98ad3d51c1c95da22bbb9b2ef3e"
|
|
||||||
integrity sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==
|
|
||||||
dependencies:
|
|
||||||
ignore-walk "^3.0.1"
|
|
||||||
npm-bundled "^1.0.1"
|
|
||||||
npm-normalize-package-bin "^1.0.1"
|
|
||||||
|
|
||||||
npmlog@^4.0.2:
|
|
||||||
version "4.1.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b"
|
|
||||||
integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==
|
|
||||||
dependencies:
|
|
||||||
are-we-there-yet "~1.1.2"
|
|
||||||
console-control-strings "~1.1.0"
|
|
||||||
gauge "~2.7.3"
|
|
||||||
set-blocking "~2.0.0"
|
|
||||||
|
|
||||||
num2fraction@^1.2.2:
|
num2fraction@^1.2.2:
|
||||||
version "1.2.2"
|
version "1.2.2"
|
||||||
resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede"
|
resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede"
|
||||||
integrity sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=
|
integrity sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=
|
||||||
|
|
||||||
number-is-nan@^1.0.0:
|
|
||||||
version "1.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
|
|
||||||
integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=
|
|
||||||
|
|
||||||
object-assign@4.1.1, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1:
|
object-assign@4.1.1, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1:
|
||||||
version "4.1.1"
|
version "4.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
||||||
@@ -4210,24 +4033,6 @@ os-browserify@^0.3.0:
|
|||||||
resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27"
|
resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27"
|
||||||
integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=
|
integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=
|
||||||
|
|
||||||
os-homedir@^1.0.0:
|
|
||||||
version "1.0.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3"
|
|
||||||
integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M=
|
|
||||||
|
|
||||||
os-tmpdir@^1.0.0:
|
|
||||||
version "1.0.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
|
|
||||||
integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=
|
|
||||||
|
|
||||||
osenv@^0.1.4:
|
|
||||||
version "0.1.5"
|
|
||||||
resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410"
|
|
||||||
integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==
|
|
||||||
dependencies:
|
|
||||||
os-homedir "^1.0.0"
|
|
||||||
os-tmpdir "^1.0.0"
|
|
||||||
|
|
||||||
p-limit@^1.1.0:
|
p-limit@^1.1.0:
|
||||||
version "1.3.0"
|
version "1.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8"
|
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8"
|
||||||
@@ -4991,16 +4796,6 @@ raw-body@2.4.0:
|
|||||||
iconv-lite "0.4.24"
|
iconv-lite "0.4.24"
|
||||||
unpipe "1.0.0"
|
unpipe "1.0.0"
|
||||||
|
|
||||||
rc@^1.2.7:
|
|
||||||
version "1.2.8"
|
|
||||||
resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed"
|
|
||||||
integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==
|
|
||||||
dependencies:
|
|
||||||
deep-extend "^0.6.0"
|
|
||||||
ini "~1.3.0"
|
|
||||||
minimist "^1.2.0"
|
|
||||||
strip-json-comments "~2.0.1"
|
|
||||||
|
|
||||||
react-dom@16.13.0:
|
react-dom@16.13.0:
|
||||||
version "16.13.0"
|
version "16.13.0"
|
||||||
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.13.0.tgz#cdde54b48eb9e8a0ca1b3dc9943d9bb409b81866"
|
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.13.0.tgz#cdde54b48eb9e8a0ca1b3dc9943d9bb409b81866"
|
||||||
@@ -5044,7 +4839,7 @@ read-pkg@^2.0.0:
|
|||||||
normalize-package-data "^2.3.2"
|
normalize-package-data "^2.3.2"
|
||||||
path-type "^2.0.0"
|
path-type "^2.0.0"
|
||||||
|
|
||||||
"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6:
|
"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6:
|
||||||
version "2.3.7"
|
version "2.3.7"
|
||||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57"
|
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57"
|
||||||
integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==
|
integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==
|
||||||
@@ -5248,7 +5043,7 @@ rework@1.0.1:
|
|||||||
convert-source-map "^0.3.3"
|
convert-source-map "^0.3.3"
|
||||||
css "^2.0.0"
|
css "^2.0.0"
|
||||||
|
|
||||||
rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.3:
|
rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.3:
|
||||||
version "2.7.1"
|
version "2.7.1"
|
||||||
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec"
|
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec"
|
||||||
integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==
|
integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==
|
||||||
@@ -5303,11 +5098,6 @@ sass-loader@8.0.2:
|
|||||||
schema-utils "^2.6.1"
|
schema-utils "^2.6.1"
|
||||||
semver "^6.3.0"
|
semver "^6.3.0"
|
||||||
|
|
||||||
sax@^1.2.4:
|
|
||||||
version "1.2.4"
|
|
||||||
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
|
|
||||||
integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
|
|
||||||
|
|
||||||
scheduler@^0.19.0:
|
scheduler@^0.19.0:
|
||||||
version "0.19.1"
|
version "0.19.1"
|
||||||
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.19.1.tgz#4f3e2ed2c1a7d65681f4c854fa8c5a1ccb40f196"
|
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.19.1.tgz#4f3e2ed2c1a7d65681f4c854fa8c5a1ccb40f196"
|
||||||
@@ -5333,7 +5123,7 @@ schema-utils@^2.0.0, schema-utils@^2.0.1, schema-utils@^2.6.0, schema-utils@^2.6
|
|||||||
ajv "^6.12.0"
|
ajv "^6.12.0"
|
||||||
ajv-keywords "^3.4.1"
|
ajv-keywords "^3.4.1"
|
||||||
|
|
||||||
"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0:
|
"semver@2 || 3 || 4 || 5", semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0:
|
||||||
version "5.7.1"
|
version "5.7.1"
|
||||||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
|
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
|
||||||
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
|
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
|
||||||
@@ -5372,11 +5162,6 @@ serialize-javascript@^2.1.2:
|
|||||||
resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-2.1.2.tgz#ecec53b0e0317bdc95ef76ab7074b7384785fa61"
|
resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-2.1.2.tgz#ecec53b0e0317bdc95ef76ab7074b7384785fa61"
|
||||||
integrity sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==
|
integrity sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==
|
||||||
|
|
||||||
set-blocking@~2.0.0:
|
|
||||||
version "2.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
|
|
||||||
integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc=
|
|
||||||
|
|
||||||
set-value@^2.0.0, set-value@^2.0.1:
|
set-value@^2.0.0, set-value@^2.0.1:
|
||||||
version "2.0.1"
|
version "2.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b"
|
resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b"
|
||||||
@@ -5417,7 +5202,7 @@ shell-quote@^1.6.1:
|
|||||||
resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.2.tgz#67a7d02c76c9da24f99d20808fcaded0e0e04be2"
|
resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.2.tgz#67a7d02c76c9da24f99d20808fcaded0e0e04be2"
|
||||||
integrity sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==
|
integrity sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==
|
||||||
|
|
||||||
signal-exit@^3.0.0, signal-exit@^3.0.2:
|
signal-exit@^3.0.2:
|
||||||
version "3.0.3"
|
version "3.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c"
|
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c"
|
||||||
integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==
|
integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==
|
||||||
@@ -5603,23 +5388,6 @@ string-hash@1.1.3:
|
|||||||
resolved "https://registry.yarnpkg.com/string-hash/-/string-hash-1.1.3.tgz#e8aafc0ac1855b4666929ed7dd1275df5d6c811b"
|
resolved "https://registry.yarnpkg.com/string-hash/-/string-hash-1.1.3.tgz#e8aafc0ac1855b4666929ed7dd1275df5d6c811b"
|
||||||
integrity sha1-6Kr8CsGFW0Zmkp7X3RJ1311sgRs=
|
integrity sha1-6Kr8CsGFW0Zmkp7X3RJ1311sgRs=
|
||||||
|
|
||||||
string-width@^1.0.1:
|
|
||||||
version "1.0.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3"
|
|
||||||
integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=
|
|
||||||
dependencies:
|
|
||||||
code-point-at "^1.0.0"
|
|
||||||
is-fullwidth-code-point "^1.0.0"
|
|
||||||
strip-ansi "^3.0.0"
|
|
||||||
|
|
||||||
"string-width@^1.0.2 || 2":
|
|
||||||
version "2.1.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e"
|
|
||||||
integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==
|
|
||||||
dependencies:
|
|
||||||
is-fullwidth-code-point "^2.0.0"
|
|
||||||
strip-ansi "^4.0.0"
|
|
||||||
|
|
||||||
string_decoder@^1.0.0, string_decoder@^1.1.1:
|
string_decoder@^1.0.0, string_decoder@^1.1.1:
|
||||||
version "1.3.0"
|
version "1.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e"
|
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e"
|
||||||
@@ -5641,30 +5409,18 @@ strip-ansi@5.2.0, strip-ansi@^5.2.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
ansi-regex "^4.1.0"
|
ansi-regex "^4.1.0"
|
||||||
|
|
||||||
strip-ansi@^3.0.0, strip-ansi@^3.0.1:
|
strip-ansi@^3.0.0:
|
||||||
version "3.0.1"
|
version "3.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
|
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
|
||||||
integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=
|
integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=
|
||||||
dependencies:
|
dependencies:
|
||||||
ansi-regex "^2.0.0"
|
ansi-regex "^2.0.0"
|
||||||
|
|
||||||
strip-ansi@^4.0.0:
|
|
||||||
version "4.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f"
|
|
||||||
integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8=
|
|
||||||
dependencies:
|
|
||||||
ansi-regex "^3.0.0"
|
|
||||||
|
|
||||||
strip-bom@^3.0.0:
|
strip-bom@^3.0.0:
|
||||||
version "3.0.0"
|
version "3.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"
|
resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"
|
||||||
integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=
|
integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=
|
||||||
|
|
||||||
strip-json-comments@~2.0.1:
|
|
||||||
version "2.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
|
|
||||||
integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo=
|
|
||||||
|
|
||||||
style-loader@1.0.0:
|
style-loader@1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-1.0.0.tgz#1d5296f9165e8e2c85d24eee0b7caf9ec8ca1f82"
|
resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-1.0.0.tgz#1d5296f9165e8e2c85d24eee0b7caf9ec8ca1f82"
|
||||||
@@ -5721,19 +5477,6 @@ tapable@^1.0.0, tapable@^1.1.3:
|
|||||||
resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2"
|
resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2"
|
||||||
integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==
|
integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==
|
||||||
|
|
||||||
tar@^4.4.2:
|
|
||||||
version "4.4.13"
|
|
||||||
resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525"
|
|
||||||
integrity sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==
|
|
||||||
dependencies:
|
|
||||||
chownr "^1.1.1"
|
|
||||||
fs-minipass "^1.2.5"
|
|
||||||
minipass "^2.8.6"
|
|
||||||
minizlib "^1.2.1"
|
|
||||||
mkdirp "^0.5.0"
|
|
||||||
safe-buffer "^5.1.2"
|
|
||||||
yallist "^3.0.3"
|
|
||||||
|
|
||||||
terser-webpack-plugin@^1.4.1:
|
terser-webpack-plugin@^1.4.1:
|
||||||
version "1.4.3"
|
version "1.4.3"
|
||||||
resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz#5ecaf2dbdc5fb99745fd06791f46fc9ddb1c9a7c"
|
resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz#5ecaf2dbdc5fb99745fd06791f46fc9ddb1c9a7c"
|
||||||
@@ -6148,13 +5891,6 @@ whatwg-fetch@3.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz#fc804e458cc460009b1a2b966bc8817d2578aefb"
|
resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz#fc804e458cc460009b1a2b966bc8817d2578aefb"
|
||||||
integrity sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q==
|
integrity sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q==
|
||||||
|
|
||||||
wide-align@^1.1.0:
|
|
||||||
version "1.1.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457"
|
|
||||||
integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==
|
|
||||||
dependencies:
|
|
||||||
string-width "^1.0.2 || 2"
|
|
||||||
|
|
||||||
worker-farm@^1.7.0:
|
worker-farm@^1.7.0:
|
||||||
version "1.7.0"
|
version "1.7.0"
|
||||||
resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8"
|
resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8"
|
||||||
@@ -6194,7 +5930,7 @@ y18n@^4.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b"
|
resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b"
|
||||||
integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==
|
integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==
|
||||||
|
|
||||||
yallist@^3.0.0, yallist@^3.0.2, yallist@^3.0.3:
|
yallist@^3.0.2:
|
||||||
version "3.1.1"
|
version "3.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd"
|
resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd"
|
||||||
integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==
|
integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "mkdir public && echo $FOO > public/index.html"
|
"build": "mkdir -p public && echo $FOO > public/index.html"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
export default (_req, res) => {
|
module.exports = (_req, res) => {
|
||||||
res.end('current date: ' + new Date().toISOString());
|
res.end('current date: ' + new Date().toISOString());
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
export default (_req, res) => {
|
module.exports = (_req, res) => {
|
||||||
res.end('random number: ' + Math.random());
|
res.end('random number: ' + Math.random());
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -110,7 +110,10 @@ async function exec(directory, args = []) {
|
|||||||
|
|
||||||
async function runNpmInstall(fixturePath) {
|
async function runNpmInstall(fixturePath) {
|
||||||
if (await fs.exists(join(fixturePath, 'package.json'))) {
|
if (await fs.exists(join(fixturePath, 'package.json'))) {
|
||||||
return execa('yarn', ['install'], { cwd: fixturePath, shell: true });
|
await execa('yarn', ['install'], {
|
||||||
|
cwd: fixturePath,
|
||||||
|
shell: true,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,6 +285,9 @@ function testFixtureStdio(
|
|||||||
env,
|
env,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
dev.stdout.pipe(process.stdout);
|
||||||
|
dev.stderr.pipe(process.stderr);
|
||||||
|
|
||||||
dev.stdout.on('data', data => {
|
dev.stdout.on('data', data => {
|
||||||
stdoutList.push(data);
|
stdoutList.push(data);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -30,14 +30,6 @@ ncc build ../../node_modules/source-map-support/register -e @vercel/build-utils
|
|||||||
mv dist/source-map-support/index.js dist/source-map-support.js
|
mv dist/source-map-support/index.js dist/source-map-support.js
|
||||||
rm -rf dist/source-map-support
|
rm -rf dist/source-map-support
|
||||||
|
|
||||||
# build typescript
|
ncc build src/index.ts -e @vercel/build-utils -e @now/build-utils -e typescript -o dist/main
|
||||||
ncc build ../../node_modules/typescript/lib/typescript -e @vercel/build-utils -e @now/build-utils -o dist/typescript
|
|
||||||
mv dist/typescript/index.js dist/typescript.js
|
|
||||||
mkdir -p dist/typescript/lib
|
|
||||||
mv dist/typescript/typescript/lib/*.js dist/typescript/lib/
|
|
||||||
mv dist/typescript/typescript/lib/*.d.ts dist/typescript/lib/
|
|
||||||
rm -r dist/typescript/typescript
|
|
||||||
|
|
||||||
ncc build src/index.ts -e @vercel/build-utils -e @now/build-utils -o dist/main
|
|
||||||
mv dist/main/index.js dist/index.js
|
mv dist/main/index.js dist/index.js
|
||||||
rm -rf dist/main
|
rm -rf dist/main
|
||||||
|
|||||||
@@ -19,11 +19,14 @@
|
|||||||
"dist"
|
"dist"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/node": "*"
|
"@types/node": "*",
|
||||||
|
"ts-node": "8.9.1",
|
||||||
|
"typescript": "3.8.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "7.5.0",
|
"@babel/core": "7.5.0",
|
||||||
"@babel/plugin-transform-modules-commonjs": "7.5.0",
|
"@babel/plugin-transform-modules-commonjs": "7.5.0",
|
||||||
|
"@tootallnate/once": "1.1.2",
|
||||||
"@types/aws-lambda": "8.10.19",
|
"@types/aws-lambda": "8.10.19",
|
||||||
"@types/content-type": "1.1.3",
|
"@types/content-type": "1.1.3",
|
||||||
"@types/cookie": "0.3.3",
|
"@types/cookie": "0.3.3",
|
||||||
@@ -36,7 +39,6 @@
|
|||||||
"etag": "1.8.1",
|
"etag": "1.8.1",
|
||||||
"node-fetch": "2.6.0",
|
"node-fetch": "2.6.0",
|
||||||
"source-map-support": "0.5.12",
|
"source-map-support": "0.5.12",
|
||||||
"test-listen": "1.1.0",
|
"test-listen": "1.1.0"
|
||||||
"typescript": "3.5.2"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
75
packages/now-node/src/dev-server.ts
Normal file
75
packages/now-node/src/dev-server.ts
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
import { register } from 'ts-node';
|
||||||
|
|
||||||
|
// Use the project's version of TypeScript if available,
|
||||||
|
// otherwise fall back to using the copy that `@now/node` uses.
|
||||||
|
let compiler: string;
|
||||||
|
try {
|
||||||
|
compiler = require.resolve('typescript', {
|
||||||
|
paths: [process.cwd(), __dirname],
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
compiler = 'typescript';
|
||||||
|
}
|
||||||
|
|
||||||
|
register({
|
||||||
|
compiler,
|
||||||
|
compilerOptions: {
|
||||||
|
allowJs: true,
|
||||||
|
esModuleInterop: true,
|
||||||
|
jsx: 'react',
|
||||||
|
},
|
||||||
|
transpileOnly: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
import http from 'http';
|
||||||
|
import path from 'path';
|
||||||
|
import { createServerWithHelpers } from './helpers';
|
||||||
|
|
||||||
|
function listen(
|
||||||
|
server: http.Server,
|
||||||
|
port: number,
|
||||||
|
host: string
|
||||||
|
): Promise<void> {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
server.listen(port, host, () => {
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
const entrypoint = process.env.NOW_DEV_ENTRYPOINT;
|
||||||
|
delete process.env.NOW_DEV_ENTRYPOINT;
|
||||||
|
|
||||||
|
if (!entrypoint) {
|
||||||
|
throw new Error('`NOW_DEV_ENTRYPOINT` must be defined');
|
||||||
|
}
|
||||||
|
|
||||||
|
const config = JSON.parse(process.env.NOW_DEV_CONFIG || '{}');
|
||||||
|
delete process.env.NOW_DEV_CONFIG;
|
||||||
|
|
||||||
|
const shouldAddHelpers = !(
|
||||||
|
config.helpers === false || process.env.NODEJS_HELPERS === '0'
|
||||||
|
);
|
||||||
|
|
||||||
|
const entrypointPath = path.join(process.cwd(), entrypoint);
|
||||||
|
const handler = await import(entrypointPath);
|
||||||
|
|
||||||
|
const server = shouldAddHelpers
|
||||||
|
? createServerWithHelpers(handler.default)
|
||||||
|
: http.createServer(handler.default);
|
||||||
|
|
||||||
|
await listen(server, 0, '127.0.0.1');
|
||||||
|
|
||||||
|
const address = server.address();
|
||||||
|
if (typeof process.send === 'function') {
|
||||||
|
process.send(address);
|
||||||
|
} else {
|
||||||
|
console.log('Dev server listening:', address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
main().catch(err => {
|
||||||
|
console.error(err);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
@@ -6,6 +6,7 @@ import {
|
|||||||
NowRequestBody,
|
NowRequestBody,
|
||||||
} from './types';
|
} from './types';
|
||||||
import { Server } from 'http';
|
import { Server } from 'http';
|
||||||
|
import { Readable } from 'stream';
|
||||||
import { Bridge } from './bridge';
|
import { Bridge } from './bridge';
|
||||||
|
|
||||||
function getBodyParser(req: NowRequest, body: Buffer) {
|
function getBodyParser(req: NowRequest, body: Buffer) {
|
||||||
@@ -81,6 +82,7 @@ function setCharset(type: string, charset: string) {
|
|||||||
return format(parsed);
|
return format(parsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
function createETag(body: any, encoding: 'utf8' | undefined) {
|
function createETag(body: any, encoding: 'utf8' | undefined) {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||||
const etag = require('etag');
|
const etag = require('etag');
|
||||||
@@ -88,6 +90,7 @@ function createETag(body: any, encoding: 'utf8' | undefined) {
|
|||||||
return etag(buf, { weak: true });
|
return etag(buf, { weak: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
function send(req: NowRequest, res: NowResponse, body: any): NowResponse {
|
function send(req: NowRequest, res: NowResponse, body: any): NowResponse {
|
||||||
let chunk: unknown = body;
|
let chunk: unknown = body;
|
||||||
let encoding: 'utf8' | undefined;
|
let encoding: 'utf8' | undefined;
|
||||||
@@ -185,6 +188,7 @@ function send(req: NowRequest, res: NowResponse, body: any): NowResponse {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
function json(req: NowRequest, res: NowResponse, jsonBody: any): NowResponse {
|
function json(req: NowRequest, res: NowResponse, jsonBody: any): NowResponse {
|
||||||
const body = JSON.stringify(jsonBody);
|
const body = JSON.stringify(jsonBody);
|
||||||
|
|
||||||
@@ -233,9 +237,24 @@ function setLazyProp<T>(req: NowRequest, prop: string, getter: () => T) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function rawBody(readable: Readable): Promise<Buffer> {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
let bytes = 0;
|
||||||
|
const chunks: Buffer[] = [];
|
||||||
|
readable.on('error', reject);
|
||||||
|
readable.on('data', chunk => {
|
||||||
|
chunks.push(chunk);
|
||||||
|
bytes += chunk.length;
|
||||||
|
});
|
||||||
|
readable.on('end', () => {
|
||||||
|
resolve(Buffer.concat(chunks, bytes));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export function createServerWithHelpers(
|
export function createServerWithHelpers(
|
||||||
listener: (req: NowRequest, res: NowResponse) => void | Promise<void>,
|
handler: (req: NowRequest, res: NowResponse) => void | Promise<void>,
|
||||||
bridge: Bridge
|
bridge?: Bridge
|
||||||
) {
|
) {
|
||||||
const server = new Server(async (_req, _res) => {
|
const server = new Server(async (_req, _res) => {
|
||||||
const req = _req as NowRequest;
|
const req = _req as NowRequest;
|
||||||
@@ -247,21 +266,23 @@ export function createServerWithHelpers(
|
|||||||
// don't expose this header to the client
|
// don't expose this header to the client
|
||||||
delete req.headers['x-now-bridge-request-id'];
|
delete req.headers['x-now-bridge-request-id'];
|
||||||
|
|
||||||
if (typeof reqId !== 'string') {
|
let body: Buffer;
|
||||||
throw new ApiError(500, 'Internal Server Error');
|
if (typeof reqId === 'string' && bridge) {
|
||||||
|
const event = bridge.consumeEvent(reqId);
|
||||||
|
body = event.body;
|
||||||
|
} else {
|
||||||
|
body = await rawBody(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
const event = bridge.consumeEvent(reqId);
|
|
||||||
|
|
||||||
setLazyProp<NowRequestCookies>(req, 'cookies', getCookieParser(req));
|
setLazyProp<NowRequestCookies>(req, 'cookies', getCookieParser(req));
|
||||||
setLazyProp<NowRequestQuery>(req, 'query', getQueryParser(req));
|
setLazyProp<NowRequestQuery>(req, 'query', getQueryParser(req));
|
||||||
setLazyProp<NowRequestBody>(req, 'body', getBodyParser(req, event.body));
|
setLazyProp<NowRequestBody>(req, 'body', getBodyParser(req, body));
|
||||||
|
|
||||||
res.status = statusCode => status(res, statusCode);
|
res.status = statusCode => status(res, statusCode);
|
||||||
res.send = body => send(req, res, body);
|
res.send = body => send(req, res, body);
|
||||||
res.json = jsonBody => json(req, res, jsonBody);
|
res.json = jsonBody => json(req, res, jsonBody);
|
||||||
|
|
||||||
await listener(req, res);
|
await handler(req, res);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err instanceof ApiError) {
|
if (err instanceof ApiError) {
|
||||||
sendError(res, err.statusCode, err.message);
|
sendError(res, err.statusCode, err.message);
|
||||||
|
|||||||
@@ -1,12 +1,22 @@
|
|||||||
|
import { fork, spawn } from 'child_process';
|
||||||
|
import {
|
||||||
|
readFileSync,
|
||||||
|
lstatSync,
|
||||||
|
readlinkSync,
|
||||||
|
statSync,
|
||||||
|
promises as fsp,
|
||||||
|
} from 'fs';
|
||||||
import {
|
import {
|
||||||
basename,
|
basename,
|
||||||
dirname,
|
dirname,
|
||||||
|
extname,
|
||||||
join,
|
join,
|
||||||
relative,
|
relative,
|
||||||
resolve,
|
resolve,
|
||||||
sep,
|
sep,
|
||||||
parse as parsePath,
|
parse as parsePath,
|
||||||
} from 'path';
|
} from 'path';
|
||||||
|
import once from '@tootallnate/once';
|
||||||
import nodeFileTrace from '@zeit/node-file-trace';
|
import nodeFileTrace from '@zeit/node-file-trace';
|
||||||
import buildUtils from './build-utils';
|
import buildUtils from './build-utils';
|
||||||
import {
|
import {
|
||||||
@@ -16,6 +26,8 @@ import {
|
|||||||
PrepareCacheOptions,
|
PrepareCacheOptions,
|
||||||
BuildOptions,
|
BuildOptions,
|
||||||
Config,
|
Config,
|
||||||
|
StartDevServerOptions,
|
||||||
|
StartDevServerResult,
|
||||||
} from '@vercel/build-utils';
|
} from '@vercel/build-utils';
|
||||||
const {
|
const {
|
||||||
glob,
|
glob,
|
||||||
@@ -30,12 +42,13 @@ const {
|
|||||||
shouldServe,
|
shouldServe,
|
||||||
debug,
|
debug,
|
||||||
isSymbolicLink,
|
isSymbolicLink,
|
||||||
|
walkParentDirs,
|
||||||
} = buildUtils;
|
} = buildUtils;
|
||||||
|
import { makeNowLauncher, makeAwsLauncher } from './launcher';
|
||||||
|
import { Register, register } from './typescript';
|
||||||
|
|
||||||
export { shouldServe };
|
export { shouldServe };
|
||||||
export { NowRequest, NowResponse } from './types';
|
export { NowRequest, NowResponse } from './types';
|
||||||
import { makeNowLauncher, makeAwsLauncher } from './launcher';
|
|
||||||
import { readFileSync, lstatSync, readlinkSync, statSync } from 'fs';
|
|
||||||
import { Register, register } from './typescript';
|
|
||||||
|
|
||||||
interface CompilerConfig {
|
interface CompilerConfig {
|
||||||
debug?: boolean;
|
debug?: boolean;
|
||||||
@@ -51,6 +64,19 @@ interface DownloadOptions {
|
|||||||
meta: Meta;
|
meta: Meta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface PortInfo {
|
||||||
|
port: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isPortInfo(v: any): v is PortInfo {
|
||||||
|
return v && typeof v.port === 'number';
|
||||||
|
}
|
||||||
|
|
||||||
|
const tscPath = resolve(
|
||||||
|
dirname(require.resolve(eval('"typescript"'))),
|
||||||
|
'../bin/tsc'
|
||||||
|
);
|
||||||
|
|
||||||
// eslint-disable-next-line no-useless-escape
|
// eslint-disable-next-line no-useless-escape
|
||||||
const libPathRegEx = /^node_modules|[\/\\]node_modules[\/\\]/;
|
const libPathRegEx = /^node_modules|[\/\\]node_modules[\/\\]/;
|
||||||
|
|
||||||
@@ -317,6 +343,7 @@ export async function build({
|
|||||||
const shouldAddHelpers = !(
|
const shouldAddHelpers = !(
|
||||||
config.helpers === false || process.env.NODEJS_HELPERS === '0'
|
config.helpers === false || process.env.NODEJS_HELPERS === '0'
|
||||||
);
|
);
|
||||||
|
|
||||||
const awsLambdaHandler = getAWSLambdaHandler(entrypoint, config);
|
const awsLambdaHandler = getAWSLambdaHandler(entrypoint, config);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@@ -396,3 +423,89 @@ export async function prepareCache({
|
|||||||
const cache = await glob('node_modules/**', workPath);
|
const cache = await glob('node_modules/**', workPath);
|
||||||
return cache;
|
return cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function startDevServer(
|
||||||
|
opts: StartDevServerOptions
|
||||||
|
): Promise<StartDevServerResult> {
|
||||||
|
const { entrypoint, workPath, config, env } = opts;
|
||||||
|
const devServerPath = join(__dirname, 'dev-server.js');
|
||||||
|
const child = fork(devServerPath, [], {
|
||||||
|
cwd: workPath,
|
||||||
|
env: {
|
||||||
|
...process.env,
|
||||||
|
...env,
|
||||||
|
NOW_DEV_ENTRYPOINT: entrypoint,
|
||||||
|
NOW_DEV_CONFIG: JSON.stringify(config),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const { pid } = child;
|
||||||
|
const onMessage = once<{ port: number }>(child, 'message');
|
||||||
|
const onExit = once.spread<[number, string | null]>(child, 'exit');
|
||||||
|
const result = await Promise.race([onMessage, onExit]);
|
||||||
|
onExit.cancel();
|
||||||
|
onMessage.cancel();
|
||||||
|
|
||||||
|
if (isPortInfo(result)) {
|
||||||
|
// "message" event
|
||||||
|
|
||||||
|
const ext = extname(entrypoint);
|
||||||
|
if (ext === '.ts' || ext === '.tsx') {
|
||||||
|
// Invoke `tsc --noEmit` asynchronously in the background, so
|
||||||
|
// that the HTTP request is not blocked by the type checking.
|
||||||
|
doTypeCheck(opts).catch((err: Error) => {
|
||||||
|
console.error('Type check for %j failed:', entrypoint, err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return { port: result.port, pid };
|
||||||
|
} else {
|
||||||
|
// "exit" event
|
||||||
|
throw new Error(
|
||||||
|
`Failed to start dev server for "${entrypoint}" (code=${result[0]}, signal=${result[1]})`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function doTypeCheck({
|
||||||
|
entrypoint,
|
||||||
|
workPath,
|
||||||
|
}: StartDevServerOptions): Promise<void> {
|
||||||
|
// In order to type-check a single file, a temporary tsconfig
|
||||||
|
// file needs to be created that inherits from the base one :(
|
||||||
|
// See: https://stackoverflow.com/a/44748041/376773
|
||||||
|
const id = Math.random()
|
||||||
|
.toString(32)
|
||||||
|
.substring(2);
|
||||||
|
const tempConfigName = `.tsconfig-${id}.json`;
|
||||||
|
const projectTsConfig = await walkParentDirs({
|
||||||
|
base: workPath,
|
||||||
|
start: join(workPath, dirname(entrypoint)),
|
||||||
|
filename: 'tsconfig.json',
|
||||||
|
});
|
||||||
|
const tsconfig = {
|
||||||
|
extends: projectTsConfig || undefined,
|
||||||
|
include: [entrypoint],
|
||||||
|
};
|
||||||
|
await fsp.writeFile(tempConfigName, JSON.stringify(tsconfig));
|
||||||
|
|
||||||
|
const child = spawn(
|
||||||
|
process.execPath,
|
||||||
|
[
|
||||||
|
tscPath,
|
||||||
|
'--project',
|
||||||
|
tempConfigName,
|
||||||
|
'--noEmit',
|
||||||
|
'--allowJs',
|
||||||
|
'--esModuleInterop',
|
||||||
|
'--jsx',
|
||||||
|
'react',
|
||||||
|
],
|
||||||
|
{
|
||||||
|
cwd: workPath,
|
||||||
|
stdio: 'inherit',
|
||||||
|
}
|
||||||
|
);
|
||||||
|
await once.spread<[number, string | null]>(child, 'exit');
|
||||||
|
await fsp.unlink(tempConfigName);
|
||||||
|
}
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ export function register(opts: Options = {}): Register {
|
|||||||
paths: [options.project || cwd, nowNodeBase],
|
paths: [options.project || cwd, nowNodeBase],
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
compiler = require.resolve(eval('"./typescript"'));
|
compiler = require.resolve(eval('"typescript"'));
|
||||||
}
|
}
|
||||||
//eslint-disable-next-line @typescript-eslint/no-var-requires
|
//eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||||
const ts: typeof _ts = require(compiler);
|
const ts: typeof _ts = require(compiler);
|
||||||
|
|||||||
39
yarn.lock
39
yarn.lock
@@ -1422,10 +1422,10 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
defer-to-connect "^1.0.1"
|
defer-to-connect "^1.0.1"
|
||||||
|
|
||||||
"@tootallnate/once@1":
|
"@tootallnate/once@1", "@tootallnate/once@1.1.2":
|
||||||
version "1.0.0"
|
version "1.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.0.0.tgz#9c13c2574c92d4503b005feca8f2e16cc1611506"
|
resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82"
|
||||||
integrity sha512-KYyTT/T6ALPkIRd2Ge080X/BsXvy9O0hcWTtMWkPvwAwF99+vn6Dv4GzrFT/Nn1LePr+FFDbRXXlqmsy9lw2zA==
|
integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==
|
||||||
|
|
||||||
"@types/ansi-escapes@3.0.0":
|
"@types/ansi-escapes@3.0.0":
|
||||||
version "3.0.0"
|
version "3.0.0"
|
||||||
@@ -9963,6 +9963,14 @@ source-map-support@^0.5.12, source-map-support@^0.5.6:
|
|||||||
buffer-from "^1.0.0"
|
buffer-from "^1.0.0"
|
||||||
source-map "^0.6.0"
|
source-map "^0.6.0"
|
||||||
|
|
||||||
|
source-map-support@^0.5.17:
|
||||||
|
version "0.5.19"
|
||||||
|
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61"
|
||||||
|
integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==
|
||||||
|
dependencies:
|
||||||
|
buffer-from "^1.0.0"
|
||||||
|
source-map "^0.6.0"
|
||||||
|
|
||||||
source-map-url@^0.4.0:
|
source-map-url@^0.4.0:
|
||||||
version "0.4.0"
|
version "0.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3"
|
resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3"
|
||||||
@@ -10775,6 +10783,17 @@ ts-node@8.3.0:
|
|||||||
source-map-support "^0.5.6"
|
source-map-support "^0.5.6"
|
||||||
yn "^3.0.0"
|
yn "^3.0.0"
|
||||||
|
|
||||||
|
ts-node@8.9.1:
|
||||||
|
version "8.9.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-8.9.1.tgz#2f857f46c47e91dcd28a14e052482eb14cfd65a5"
|
||||||
|
integrity sha512-yrq6ODsxEFTLz0R3BX2myf0WBCSQh9A+py8PBo1dCzWIOcvisbyH6akNKqDHMgXePF2kir5mm5JXJTH3OUJYOQ==
|
||||||
|
dependencies:
|
||||||
|
arg "^4.1.0"
|
||||||
|
diff "^4.0.1"
|
||||||
|
make-error "^1.1.1"
|
||||||
|
source-map-support "^0.5.17"
|
||||||
|
yn "3.1.1"
|
||||||
|
|
||||||
tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3:
|
tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3:
|
||||||
version "1.10.0"
|
version "1.10.0"
|
||||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a"
|
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a"
|
||||||
@@ -10858,6 +10877,11 @@ typescript@3.6.4:
|
|||||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.6.4.tgz#b18752bb3792bc1a0281335f7f6ebf1bbfc5b91d"
|
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.6.4.tgz#b18752bb3792bc1a0281335f7f6ebf1bbfc5b91d"
|
||||||
integrity sha512-unoCll1+l+YK4i4F8f22TaNVPRHcD9PA3yCuZ8g5e0qGqlVlJ/8FSateOLLSagn+Yg5+ZwuPkL8LFUc0Jcvksg==
|
integrity sha512-unoCll1+l+YK4i4F8f22TaNVPRHcD9PA3yCuZ8g5e0qGqlVlJ/8FSateOLLSagn+Yg5+ZwuPkL8LFUc0Jcvksg==
|
||||||
|
|
||||||
|
typescript@3.8.3:
|
||||||
|
version "3.8.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.8.3.tgz#409eb8544ea0335711205869ec458ab109ee1061"
|
||||||
|
integrity sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w==
|
||||||
|
|
||||||
uglify-js@^3.1.4:
|
uglify-js@^3.1.4:
|
||||||
version "3.7.3"
|
version "3.7.3"
|
||||||
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.7.3.tgz#f918fce9182f466d5140f24bb0ff35c2d32dcc6a"
|
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.7.3.tgz#f918fce9182f466d5140f24bb0ff35c2d32dcc6a"
|
||||||
@@ -11486,11 +11510,6 @@ yargs@^13.3.0:
|
|||||||
y18n "^4.0.0"
|
y18n "^4.0.0"
|
||||||
yargs-parser "^13.1.1"
|
yargs-parser "^13.1.1"
|
||||||
|
|
||||||
yarn@1.22.0:
|
|
||||||
version "1.22.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/yarn/-/yarn-1.22.0.tgz#acf82906e36bcccd1ccab1cfb73b87509667c881"
|
|
||||||
integrity sha512-KMHP/Jq53jZKTY9iTUt3dIVl/be6UPs2INo96+BnZHLKxYNTfwMmlgHTaMWyGZoO74RI4AIFvnWhYrXq2USJkg==
|
|
||||||
|
|
||||||
yauzl-clone@^1.0.4:
|
yauzl-clone@^1.0.4:
|
||||||
version "1.0.4"
|
version "1.0.4"
|
||||||
resolved "https://registry.yarnpkg.com/yauzl-clone/-/yauzl-clone-1.0.4.tgz#8bc6d293b17cc98802bbbed2e289d18e7697c96c"
|
resolved "https://registry.yarnpkg.com/yauzl-clone/-/yauzl-clone-1.0.4.tgz#8bc6d293b17cc98802bbbed2e289d18e7697c96c"
|
||||||
@@ -11527,7 +11546,7 @@ yazl@2.4.3:
|
|||||||
dependencies:
|
dependencies:
|
||||||
buffer-crc32 "~0.2.3"
|
buffer-crc32 "~0.2.3"
|
||||||
|
|
||||||
yn@^3.0.0:
|
yn@3.1.1, yn@^3.0.0:
|
||||||
version "3.1.1"
|
version "3.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"
|
resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"
|
||||||
integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==
|
integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==
|
||||||
|
|||||||
Reference in New Issue
Block a user