mirror of
https://github.com/LukeHagar/vercel.git
synced 2025-12-24 11:49:13 +00:00
Compare commits
14 Commits
@now/node-
...
@now/node@
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e083aa3750 | ||
|
|
941f675657 | ||
|
|
6fad726abb | ||
|
|
dd22051d6b | ||
|
|
7e86cb403f | ||
|
|
d19d557738 | ||
|
|
e4281f698c | ||
|
|
86ff681c6d | ||
|
|
ba97a7cf19 | ||
|
|
0a94397700 | ||
|
|
5c8e2f2ccc | ||
|
|
35d56a34cb | ||
|
|
9dfd37e135 | ||
|
|
6f815f2645 |
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"eslint.enable": false
|
||||
}
|
||||
39
README.md
39
README.md
@@ -2,28 +2,41 @@
|
||||
|
||||
This is a monorepo containing the [Official Builders](https://zeit.co/docs/v2/deployments/builders/overview) provided by the ZEIT team.
|
||||
|
||||
There are two branches:
|
||||
## Channels
|
||||
|
||||
- canary - published to npm as `canary` dist-tag, eg `@now/node@canary`
|
||||
- master - published to npm as `latest` dist-tag, eg `@now/node@latest`
|
||||
There are two Channels:
|
||||
|
||||
| Channel | Git Branch | npm dist-tag | use example |
|
||||
| ------- | ---------- | ------------ | ------------------ |
|
||||
| Canary | `canary` | `@canary` | `@now/node@canary` |
|
||||
| Stable | `master` | `@latest` | `@now/node@latest` |
|
||||
|
||||
All PRs should be submitted to the `canary` branch.
|
||||
|
||||
Once a PR is merged into the `canary` branch, it should be published to npm immediately using the Canary Channel.
|
||||
|
||||
### Publishing to npm
|
||||
|
||||
Run the following command to publish modified builders to npm:
|
||||
|
||||
For the stable channel use:
|
||||
|
||||
```
|
||||
yarn publish-stable
|
||||
```
|
||||
|
||||
For the canary channel use:
|
||||
For the Canary Channel, publish the modified Builders to npm with the following:
|
||||
|
||||
```
|
||||
yarn publish-canary
|
||||
```
|
||||
|
||||
GitHub Actions will take care of publishing the updated packages to npm from there.
|
||||
For the Stable Channel, you must cherry pick each commit from canary to master and then deploy the modified Builders:
|
||||
|
||||
```
|
||||
git checkout master
|
||||
git pull # make sure you're up to date
|
||||
git cherry-pick <PR501_COMMIT_SHA>
|
||||
git cherry-pick <PR502_COMMIT_SHA>
|
||||
git cherry-pick <PR503_COMMIT_SHA>
|
||||
git cherry-pick <PR504_COMMIT_SHA>
|
||||
# ... etc ...
|
||||
yarn publish-stable
|
||||
```
|
||||
|
||||
After running this publish step, GitHub Actions will take care of publishing the modified Builder packages to npm.
|
||||
|
||||
If for some reason GitHub Actions fails to publish the npm package, you may do so
|
||||
manually by running `npm publish` from the package directory. Make sure to
|
||||
|
||||
@@ -32,6 +32,14 @@
|
||||
"*.ts": [
|
||||
"prettier --write",
|
||||
"git add"
|
||||
],
|
||||
"*.json": [
|
||||
"prettier --write",
|
||||
"git add"
|
||||
],
|
||||
"*.md": [
|
||||
"prettier --write",
|
||||
"git add"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@now/build-utils",
|
||||
"version": "0.5.6",
|
||||
"version": "0.5.7",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.js",
|
||||
|
||||
@@ -16,7 +16,14 @@ export interface Files {
|
||||
}
|
||||
|
||||
export interface Config {
|
||||
[key: string]: string;
|
||||
[key: string]: string | string[] | boolean | number | undefined;
|
||||
maxLambdaSize?: string;
|
||||
includeFiles?: string | string[];
|
||||
bundle?: boolean;
|
||||
ldsflags?: string;
|
||||
helpers?: boolean;
|
||||
rust?: string;
|
||||
debug?: boolean;
|
||||
}
|
||||
|
||||
export interface Meta {
|
||||
|
||||
1
packages/now-node/.gitignore
vendored
1
packages/now-node/.gitignore
vendored
@@ -1,2 +1,3 @@
|
||||
/dist
|
||||
/src/bridge.d.ts
|
||||
/test/fixtures/**/types.d.ts
|
||||
|
||||
45
packages/now-node/@types/zeit__ncc/index.d.ts
vendored
Normal file
45
packages/now-node/@types/zeit__ncc/index.d.ts
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
declare function ncc(
|
||||
entrypoint: string,
|
||||
options?: ncc.NccOptions
|
||||
): ncc.NccResult;
|
||||
|
||||
declare namespace ncc {
|
||||
export interface NccOptions {
|
||||
watch?: any;
|
||||
sourceMap?: boolean;
|
||||
sourceMapRegister?: boolean;
|
||||
}
|
||||
|
||||
export interface Asset {
|
||||
source: Buffer;
|
||||
permissions: number;
|
||||
}
|
||||
|
||||
export interface Assets {
|
||||
[name: string]: Asset;
|
||||
}
|
||||
|
||||
export interface BuildResult {
|
||||
err: Error | null | undefined;
|
||||
code: string;
|
||||
map: string | undefined;
|
||||
assets: Assets | undefined;
|
||||
permissions: number | undefined;
|
||||
}
|
||||
|
||||
export type HandlerFn = (params: BuildResult) => void;
|
||||
export type HandlerCallback = (fn: HandlerFn) => void;
|
||||
export type RebuildFn = () => void;
|
||||
export type RebuildCallback = (fn: RebuildFn) => void;
|
||||
export type CloseCallback = () => void;
|
||||
|
||||
export interface NccResult {
|
||||
handler: HandlerCallback;
|
||||
rebuild: RebuildCallback;
|
||||
close: CloseCallback;
|
||||
}
|
||||
}
|
||||
|
||||
declare module '@zeit/ncc' {
|
||||
export = ncc;
|
||||
}
|
||||
@@ -10,3 +10,13 @@ fi
|
||||
|
||||
cp -v "$bridge_defs" src
|
||||
tsc
|
||||
|
||||
# bundle helpers.ts with ncc
|
||||
rm dist/helpers.js
|
||||
ncc build src/helpers.ts -o dist/helpers
|
||||
mv dist/helpers/index.js dist/helpers.js
|
||||
rm -rf dist/helpers
|
||||
|
||||
# todo: improve
|
||||
# copy type file for ts test
|
||||
cp dist/types.d.ts test/fixtures/15-helpers/ts/types.d.ts
|
||||
|
||||
4
packages/now-node/jest.config.js
Normal file
4
packages/now-node/jest.config.js
Normal file
@@ -0,0 +1,4 @@
|
||||
module.exports = {
|
||||
preset: 'ts-jest',
|
||||
testEnvironment: 'node',
|
||||
};
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@now/node",
|
||||
"version": "0.7.4",
|
||||
"version": "0.8.1",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index",
|
||||
"repository": {
|
||||
@@ -11,6 +11,7 @@
|
||||
"dependencies": {
|
||||
"@now/node-bridge": "^1.1.4",
|
||||
"@zeit/ncc": "0.18.5",
|
||||
"@zeit/ncc-watcher": "1.0.3",
|
||||
"fs-extra": "7.0.1"
|
||||
},
|
||||
"scripts": {
|
||||
@@ -22,8 +23,18 @@
|
||||
"dist"
|
||||
],
|
||||
"devDependencies": {
|
||||
"@types/content-type": "1.1.3",
|
||||
"@types/cookie": "0.3.3",
|
||||
"@types/jest": "24.0.13",
|
||||
"@types/node": "11.9.4",
|
||||
"@types/test-listen": "1.1.0",
|
||||
"content-type": "1.0.4",
|
||||
"cookie": "0.4.0",
|
||||
"jest": "24.1.0",
|
||||
"node-fetch": "2.6.0",
|
||||
"raw-body": "2.4.0",
|
||||
"test-listen": "1.1.0",
|
||||
"ts-jest": "24.0.2",
|
||||
"typescript": "3.3.3"
|
||||
}
|
||||
}
|
||||
|
||||
152
packages/now-node/src/helpers.ts
Normal file
152
packages/now-node/src/helpers.ts
Normal file
@@ -0,0 +1,152 @@
|
||||
import { parse as parseCookies } from 'cookie';
|
||||
import { Stream } from 'stream';
|
||||
import getRawBody from 'raw-body';
|
||||
import { URL } from 'url';
|
||||
import { parse as parseCT } from 'content-type';
|
||||
import { RequestListener } from 'http';
|
||||
import { NowRequest, NowResponse } from './types';
|
||||
|
||||
type NowListener = (req: NowRequest, res: NowResponse) => void | Promise<void>;
|
||||
|
||||
async function parseBody(req: NowRequest, limit: string = '1mb') {
|
||||
const contentType = parseCT(req.headers['content-type'] || 'text/plain');
|
||||
const { type, parameters } = contentType;
|
||||
const encoding = parameters.charset || 'utf-8';
|
||||
|
||||
let buffer;
|
||||
|
||||
try {
|
||||
buffer = await getRawBody(req, { encoding, limit });
|
||||
} catch (e) {
|
||||
if (e.type === 'entity.too.large') {
|
||||
throw new ApiError(413, `Body exceeded ${limit} limit`);
|
||||
} else {
|
||||
throw new ApiError(400, 'Invalid body');
|
||||
}
|
||||
}
|
||||
|
||||
const body = buffer.toString();
|
||||
|
||||
if (type === 'application/json' || type === 'application/ld+json') {
|
||||
return parseJson(body);
|
||||
} else if (type === 'application/x-www-form-urlencoded') {
|
||||
const qs = require('querystring');
|
||||
return qs.decode(body);
|
||||
} else {
|
||||
return body;
|
||||
}
|
||||
}
|
||||
|
||||
// Parse `JSON` and handles invalid `JSON` strings
|
||||
function parseJson(str: string) {
|
||||
try {
|
||||
return JSON.parse(str);
|
||||
} catch (e) {
|
||||
throw new ApiError(400, 'Invalid JSON');
|
||||
}
|
||||
}
|
||||
|
||||
function parseQuery({ url = '/' }: NowRequest) {
|
||||
// we provide a placeholder base url because we only want searchParams
|
||||
const params = new URL(url, 'https://n').searchParams;
|
||||
|
||||
const obj: { [key: string]: string | string[] } = {};
|
||||
for (const [key, value] of params) {
|
||||
obj[key] = value;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
function sendStatusCode(res: NowResponse, statusCode: number) {
|
||||
res.statusCode = statusCode;
|
||||
return res;
|
||||
}
|
||||
|
||||
function sendData(res: NowResponse, body: any) {
|
||||
if (body === null) {
|
||||
res.end();
|
||||
return;
|
||||
}
|
||||
|
||||
const contentType = res.getHeader('Content-Type');
|
||||
|
||||
if (Buffer.isBuffer(body)) {
|
||||
if (!contentType) {
|
||||
res.setHeader('Content-Type', 'application/octet-stream');
|
||||
}
|
||||
res.setHeader('Content-Length', body.length);
|
||||
res.end(body);
|
||||
return;
|
||||
}
|
||||
|
||||
if (body instanceof Stream) {
|
||||
if (!contentType) {
|
||||
res.setHeader('Content-Type', 'application/octet-stream');
|
||||
}
|
||||
body.pipe(res);
|
||||
return;
|
||||
}
|
||||
|
||||
let str = body;
|
||||
|
||||
// Stringify JSON body
|
||||
if (typeof body === 'object' || typeof body === 'number') {
|
||||
str = JSON.stringify(body);
|
||||
res.setHeader('Content-Type', 'application/json; charset=utf-8');
|
||||
}
|
||||
|
||||
res.setHeader('Content-Length', Buffer.byteLength(str));
|
||||
res.end(str);
|
||||
}
|
||||
|
||||
function sendJson(res: NowResponse, jsonBody: any): void {
|
||||
// Set header to application/json
|
||||
res.setHeader('Content-Type', 'application/json; charset=utf-8');
|
||||
|
||||
// Use send to handle request
|
||||
res.send(jsonBody);
|
||||
}
|
||||
|
||||
export class ApiError extends Error {
|
||||
readonly statusCode: number;
|
||||
|
||||
constructor(statusCode: number, message: string) {
|
||||
super(message);
|
||||
this.statusCode = statusCode;
|
||||
}
|
||||
}
|
||||
|
||||
export function sendError(
|
||||
res: NowResponse,
|
||||
statusCode: number,
|
||||
message: string
|
||||
) {
|
||||
res.statusCode = statusCode;
|
||||
res.statusMessage = message;
|
||||
res.end();
|
||||
}
|
||||
|
||||
export function addHelpers(listener: NowListener): RequestListener {
|
||||
return async function(_req, _res) {
|
||||
const req = _req as NowRequest;
|
||||
const res = _res as NowResponse;
|
||||
|
||||
try {
|
||||
req.cookies = parseCookies(req.headers.cookie || '');
|
||||
req.query = parseQuery(req);
|
||||
req.body = await parseBody(req);
|
||||
|
||||
res.status = statusCode => sendStatusCode(res, statusCode);
|
||||
res.send = data => sendData(res, data);
|
||||
res.json = data => sendJson(res, data);
|
||||
|
||||
listener(req, res);
|
||||
} catch (err) {
|
||||
if (err instanceof ApiError) {
|
||||
sendError(res, err.statusCode, err.message);
|
||||
} else {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
import { join, dirname, sep } from 'path';
|
||||
import { readFile } from 'fs-extra';
|
||||
import { Assets, NccOptions } from '@zeit/ncc';
|
||||
import { join, dirname, relative, sep } from 'path';
|
||||
import { NccWatcher, WatcherResult } from '@zeit/ncc-watcher';
|
||||
import {
|
||||
glob,
|
||||
download,
|
||||
@@ -14,6 +16,7 @@ import {
|
||||
BuildOptions,
|
||||
shouldServe,
|
||||
} from '@now/build-utils';
|
||||
export { NowRequest, NowResponse } from './types';
|
||||
|
||||
interface CompilerConfig {
|
||||
includeFiles?: string | string[];
|
||||
@@ -23,10 +26,28 @@ interface DownloadOptions {
|
||||
files: Files;
|
||||
entrypoint: string;
|
||||
workPath: string;
|
||||
meta?: Meta;
|
||||
meta: Meta;
|
||||
npmArguments?: string[];
|
||||
}
|
||||
|
||||
const watchers: Map<string, NccWatcher> = new Map();
|
||||
|
||||
function getWatcher(entrypoint: string, options: NccOptions): NccWatcher {
|
||||
let watcher = watchers.get(entrypoint);
|
||||
if (!watcher) {
|
||||
watcher = new NccWatcher(entrypoint, options);
|
||||
watchers.set(entrypoint, watcher);
|
||||
}
|
||||
return watcher;
|
||||
}
|
||||
|
||||
function toBuffer(data: string | Buffer): Buffer {
|
||||
if (typeof data === 'string') {
|
||||
return Buffer.from(data, 'utf8');
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
async function downloadInstallAndBundle({
|
||||
files,
|
||||
entrypoint,
|
||||
@@ -46,18 +67,51 @@ async function downloadInstallAndBundle({
|
||||
}
|
||||
|
||||
async function compile(
|
||||
workPath: string,
|
||||
entrypointPath: string,
|
||||
entrypoint: string,
|
||||
config: CompilerConfig
|
||||
): Promise<Files> {
|
||||
config: CompilerConfig,
|
||||
{ isDev, filesChanged, filesRemoved }: Meta
|
||||
): Promise<{ preparedFiles: Files; watch: string[] }> {
|
||||
const input = entrypointPath;
|
||||
const inputDir = dirname(input);
|
||||
const rootIncludeFiles = inputDir.split(sep).pop() || '';
|
||||
const ncc = require('@zeit/ncc');
|
||||
const { code, map, assets } = await ncc(input, {
|
||||
const options: NccOptions = {
|
||||
sourceMap: true,
|
||||
sourceMapRegister: true,
|
||||
});
|
||||
};
|
||||
let code: string;
|
||||
let map: string | undefined;
|
||||
let assets: Assets | undefined;
|
||||
let watch: string[] = [];
|
||||
if (isDev) {
|
||||
const watcher = getWatcher(entrypointPath, options);
|
||||
const result = await watcher.build(
|
||||
Array.isArray(filesChanged)
|
||||
? filesChanged.map(f => join(workPath, f))
|
||||
: undefined,
|
||||
Array.isArray(filesRemoved)
|
||||
? filesRemoved.map(f => join(workPath, f))
|
||||
: undefined
|
||||
);
|
||||
code = result.code;
|
||||
map = result.map;
|
||||
assets = result.assets;
|
||||
watch = [...result.files, ...result.dirs, ...result.missing]
|
||||
.filter(f => f.startsWith(workPath))
|
||||
.map(f => relative(workPath, f));
|
||||
} else {
|
||||
const ncc = require('@zeit/ncc');
|
||||
const result = await ncc(input, {
|
||||
sourceMap: true,
|
||||
sourceMapRegister: true,
|
||||
});
|
||||
code = result.code;
|
||||
map = result.map;
|
||||
assets = result.assets;
|
||||
}
|
||||
|
||||
if (!assets) assets = {};
|
||||
|
||||
if (config && config.includeFiles) {
|
||||
const includeFiles =
|
||||
@@ -81,7 +135,7 @@ async function compile(
|
||||
}
|
||||
|
||||
assets[fullPath] = {
|
||||
source: data,
|
||||
source: toBuffer(data),
|
||||
permissions: mode,
|
||||
};
|
||||
}
|
||||
@@ -89,11 +143,15 @@ async function compile(
|
||||
}
|
||||
|
||||
const preparedFiles: Files = {};
|
||||
// move all user code to 'user' subdirectory
|
||||
preparedFiles[entrypoint] = new FileBlob({ data: code });
|
||||
preparedFiles[`${entrypoint.replace('.ts', '.js')}.map`] = new FileBlob({
|
||||
data: map,
|
||||
});
|
||||
|
||||
if (map) {
|
||||
preparedFiles[`${entrypoint.replace('.ts', '.js')}.map`] = new FileBlob({
|
||||
data: toBuffer(map),
|
||||
});
|
||||
}
|
||||
|
||||
// move all user code to 'user' subdirectory
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
for (const assetName of Object.keys(assets)) {
|
||||
const { source: data, permissions: mode } = assets[assetName];
|
||||
@@ -101,9 +159,11 @@ async function compile(
|
||||
preparedFiles[join(dirname(entrypoint), assetName)] = blob2;
|
||||
}
|
||||
|
||||
return preparedFiles;
|
||||
return { preparedFiles, watch };
|
||||
}
|
||||
|
||||
export const version = 2;
|
||||
|
||||
export const config = {
|
||||
maxLambdaSize: '5mb',
|
||||
};
|
||||
@@ -113,8 +173,10 @@ export async function build({
|
||||
entrypoint,
|
||||
workPath,
|
||||
config,
|
||||
meta,
|
||||
meta = {},
|
||||
}: BuildOptions) {
|
||||
const shouldAddHelpers = config && config.helpers;
|
||||
|
||||
const {
|
||||
entrypointPath,
|
||||
entrypointFsDirname,
|
||||
@@ -130,7 +192,13 @@ export async function build({
|
||||
await runPackageJsonScript(entrypointFsDirname, 'now-build');
|
||||
|
||||
console.log('compiling entrypoint with ncc...');
|
||||
const preparedFiles = await compile(entrypointPath, entrypoint, config);
|
||||
const { preparedFiles, watch } = await compile(
|
||||
workPath,
|
||||
entrypointPath,
|
||||
entrypoint,
|
||||
config,
|
||||
meta
|
||||
);
|
||||
const launcherPath = join(__dirname, 'launcher.js');
|
||||
let launcherData = await readFile(launcherPath, 'utf8');
|
||||
|
||||
@@ -139,21 +207,32 @@ export async function build({
|
||||
[
|
||||
`listener = require("./${entrypoint}");`,
|
||||
'if (listener.default) listener = listener.default;',
|
||||
shouldAddHelpers
|
||||
? 'listener = require("./helpers").addHelpers(listener)'
|
||||
: '',
|
||||
].join(' ')
|
||||
);
|
||||
|
||||
const launcherFiles = {
|
||||
const launcherFiles: Files = {
|
||||
'launcher.js': new FileBlob({ data: launcherData }),
|
||||
'bridge.js': new FileFsRef({ fsPath: require('@now/node-bridge') }),
|
||||
};
|
||||
|
||||
if (shouldAddHelpers) {
|
||||
launcherFiles['helpers.js'] = new FileFsRef({
|
||||
fsPath: join(__dirname, 'helpers.js'),
|
||||
});
|
||||
}
|
||||
|
||||
const lambda = await createLambda({
|
||||
files: { ...preparedFiles, ...launcherFiles },
|
||||
handler: 'launcher.launcher',
|
||||
runtime: 'nodejs8.10',
|
||||
});
|
||||
|
||||
return { [entrypoint]: lambda };
|
||||
const output = { [entrypoint]: lambda };
|
||||
const result = { output, watch };
|
||||
return result;
|
||||
}
|
||||
|
||||
export async function prepareCache({ workPath }: PrepareCacheOptions) {
|
||||
|
||||
13
packages/now-node/src/types.ts
Normal file
13
packages/now-node/src/types.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { ServerResponse, IncomingMessage } from 'http';
|
||||
|
||||
export type NowRequest = IncomingMessage & {
|
||||
query: { [key: string]: string | string[] };
|
||||
cookies: { [key: string]: string };
|
||||
body: any;
|
||||
};
|
||||
|
||||
export type NowResponse = ServerResponse & {
|
||||
send: (body: any) => void;
|
||||
json: (body: any) => void;
|
||||
status: (statusCode: number) => void;
|
||||
};
|
||||
17
packages/now-node/test/fixtures/15-helpers/index.js
vendored
Normal file
17
packages/now-node/test/fixtures/15-helpers/index.js
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
/* eslint-disable prefer-destructuring */
|
||||
|
||||
module.exports = (req, res) => {
|
||||
res.status(200);
|
||||
|
||||
let who = 'anonymous';
|
||||
|
||||
if (req.body && req.body.who) {
|
||||
who = req.body.who;
|
||||
} else if (req.query.who) {
|
||||
who = req.query.who;
|
||||
} else if (req.cookies.who) {
|
||||
who = req.cookies.who;
|
||||
}
|
||||
|
||||
res.send(`hello ${who}:RANDOMNESS_PLACEHOLDER`);
|
||||
};
|
||||
5
packages/now-node/test/fixtures/15-helpers/no-helpers/index.js
vendored
Normal file
5
packages/now-node/test/fixtures/15-helpers/no-helpers/index.js
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
module.exports = (req, res) => {
|
||||
const areHelpersAvailable = typeof req.query !== 'undefined';
|
||||
|
||||
res.end(`${areHelpersAvailable ? 'yes' : 'no'}:RANDOMNESS_PLACEHOLDER`);
|
||||
};
|
||||
37
packages/now-node/test/fixtures/15-helpers/now.json
vendored
Normal file
37
packages/now-node/test/fixtures/15-helpers/now.json
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"version": 2,
|
||||
"builds": [
|
||||
{ "src": "index.js", "use": "@now/node", "config": { "helpers": true } },
|
||||
{ "src": "ts/index.ts", "use": "@now/node", "config": { "helpers": true } },
|
||||
{ "src": "no-helpers/index.js", "use": "@now/node" }
|
||||
],
|
||||
"probes": [
|
||||
{
|
||||
"path": "/",
|
||||
"mustContain": "hello anonymous:RANDOMNESS_PLACEHOLDER"
|
||||
},
|
||||
{
|
||||
"path": "/ts",
|
||||
"mustContain": "hello:RANDOMNESS_PLACEHOLDER"
|
||||
},
|
||||
{
|
||||
"path": "/?who=bill",
|
||||
"mustContain": "hello bill:RANDOMNESS_PLACEHOLDER"
|
||||
},
|
||||
{
|
||||
"path": "/",
|
||||
"method": "POST",
|
||||
"body": { "who": "john" },
|
||||
"mustContain": "hello john:RANDOMNESS_PLACEHOLDER"
|
||||
},
|
||||
{
|
||||
"path": "/",
|
||||
"headers": { "cookie": "who=chris" },
|
||||
"mustContain": "hello chris:RANDOMNESS_PLACEHOLDER"
|
||||
},
|
||||
{
|
||||
"path": "/no-helpers/",
|
||||
"mustContain": "no:RANDOMNESS_PLACEHOLDER"
|
||||
}
|
||||
]
|
||||
}
|
||||
6
packages/now-node/test/fixtures/15-helpers/ts/index.ts
vendored
Normal file
6
packages/now-node/test/fixtures/15-helpers/ts/index.ts
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
import { NowRequest, NowResponse } from './types';
|
||||
|
||||
export default function listener(req: NowRequest, res: NowResponse) {
|
||||
res.status(200);
|
||||
res.send('hello:RANDOMNESS_PLACEHOLDER');
|
||||
}
|
||||
11
packages/now-node/test/fixtures/15-helpers/ts/tsconfig.json
vendored
Normal file
11
packages/now-node/test/fixtures/15-helpers/ts/tsconfig.json
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"sourceMap": true,
|
||||
"lib": ["esnext"],
|
||||
"target": "esnext",
|
||||
"module": "commonjs"
|
||||
},
|
||||
"include": ["index.ts"]
|
||||
}
|
||||
127
packages/now-node/test/helpers.test.ts
Normal file
127
packages/now-node/test/helpers.test.ts
Normal file
@@ -0,0 +1,127 @@
|
||||
/* global beforeAll, beforeEach, afterAll, expect, it, jest */
|
||||
import fetch from 'node-fetch';
|
||||
import { createServer, Server } from 'http';
|
||||
import listen from 'test-listen';
|
||||
import { mocked } from 'ts-jest/utils';
|
||||
|
||||
// we intentionally import these types from src/index
|
||||
// to test that they are exported
|
||||
import { NowRequest, NowResponse } from '../src/index';
|
||||
|
||||
import { addHelpers } from '../src/helpers';
|
||||
|
||||
const mockListener = mocked(
|
||||
jest.fn((req: NowRequest, res: NowResponse): void => {})
|
||||
);
|
||||
const listener = addHelpers(mockListener);
|
||||
|
||||
let server: Server;
|
||||
let url: string;
|
||||
|
||||
beforeAll(async () => {
|
||||
server = createServer(listener);
|
||||
url = await listen(server);
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
mockListener.mockReset();
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await server.close();
|
||||
});
|
||||
|
||||
it('req.query should reflect querystring in the url', async () => {
|
||||
mockListener.mockImplementation((req, res) => {
|
||||
res.send('hello');
|
||||
});
|
||||
|
||||
await fetch(`${url}/?who=bill&where=us`);
|
||||
|
||||
expect(mockListener.mock.calls[0][0].query).toMatchObject({
|
||||
who: 'bill',
|
||||
where: 'us',
|
||||
});
|
||||
});
|
||||
|
||||
it('req.cookies should reflect req.cookie header', async () => {
|
||||
mockListener.mockImplementation((req, res) => {
|
||||
res.send('hello');
|
||||
});
|
||||
|
||||
await fetch(url, {
|
||||
headers: {
|
||||
cookie: 'who=bill; where=us',
|
||||
},
|
||||
});
|
||||
|
||||
expect(mockListener.mock.calls[0][0].cookies).toMatchObject({
|
||||
who: 'bill',
|
||||
where: 'us',
|
||||
});
|
||||
});
|
||||
|
||||
it('req.body should contained the parsed body', async () => {
|
||||
mockListener.mockImplementation((req, res) => {
|
||||
res.send('hello');
|
||||
});
|
||||
|
||||
await fetch(url, {
|
||||
method: 'POST',
|
||||
body: 'hello',
|
||||
});
|
||||
|
||||
expect(mockListener.mock.calls[0][0].body).toBe('hello');
|
||||
});
|
||||
|
||||
it('req.body should contained the parsed json when content-type is application/json', async () => {
|
||||
mockListener.mockImplementation((req, res) => {
|
||||
res.send('hello');
|
||||
});
|
||||
|
||||
const json = {
|
||||
who: 'bill',
|
||||
where: 'us',
|
||||
};
|
||||
|
||||
await fetch(url, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(json),
|
||||
headers: { 'content-type': 'application/json' },
|
||||
});
|
||||
|
||||
expect(mockListener.mock.calls[0][0].body).toMatchObject(json);
|
||||
});
|
||||
|
||||
it('res.send() should send text', async () => {
|
||||
mockListener.mockImplementation((req, res) => {
|
||||
res.send('hello');
|
||||
});
|
||||
|
||||
const res = await fetch(url);
|
||||
|
||||
expect(await res.text()).toBe('hello');
|
||||
});
|
||||
|
||||
it('res.json() should send json', async () => {
|
||||
mockListener.mockImplementation((req, res) => {
|
||||
res.json({ who: 'bill' });
|
||||
});
|
||||
|
||||
const res = await fetch(url);
|
||||
const contentType = res.headers.get('content-type') || '';
|
||||
|
||||
expect(contentType.includes('application/json')).toBe(true);
|
||||
expect(await res.json()).toMatchObject({ who: 'bill' });
|
||||
});
|
||||
|
||||
it('res.status() should set the status code', async () => {
|
||||
mockListener.mockImplementation((req, res) => {
|
||||
res.status(404);
|
||||
res.end();
|
||||
});
|
||||
|
||||
const res = await fetch(url);
|
||||
|
||||
expect(res.status).toBe(404);
|
||||
});
|
||||
@@ -7,7 +7,8 @@
|
||||
"module": "commonjs",
|
||||
"outDir": "dist",
|
||||
"sourceMap": false,
|
||||
"declaration": false
|
||||
"declaration": true,
|
||||
"typeRoots": ["./@types", "./node_modules/@types"]
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules"]
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@now/python",
|
||||
"version": "0.2.5",
|
||||
"main": "index.js",
|
||||
"version": "0.2.6",
|
||||
"main": "./dist/index.js",
|
||||
"license": "MIT",
|
||||
"files": [
|
||||
"dist",
|
||||
@@ -15,7 +15,7 @@
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"test": "tsc && jest",
|
||||
"prepublish": "tsc"
|
||||
"prepublishOnly": "tsc"
|
||||
},
|
||||
"dependencies": {
|
||||
"execa": "^1.0.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@now/rust",
|
||||
"version": "0.2.5",
|
||||
"version": "0.2.6",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index",
|
||||
"repository": {
|
||||
|
||||
@@ -119,7 +119,10 @@ async function buildWholeProject(
|
||||
return lambdas;
|
||||
}
|
||||
|
||||
async function gatherExtraFiles(globMatcher: string, entrypoint: string) {
|
||||
async function gatherExtraFiles(
|
||||
globMatcher: string | string[] | undefined,
|
||||
entrypoint: string
|
||||
) {
|
||||
if (!globMatcher) return {};
|
||||
|
||||
console.log('gathering extra files for the fs...');
|
||||
@@ -176,7 +179,7 @@ async function buildSingleFile(
|
||||
rustEnv: Record<string, string>
|
||||
) {
|
||||
console.log('building single file');
|
||||
const launcherPath = path.join(__dirname, 'launcher.rs');
|
||||
const launcherPath = path.join(__dirname, '..', 'launcher.rs');
|
||||
let launcherData = await fs.readFile(launcherPath, 'utf8');
|
||||
|
||||
const entrypointPath = downloadedFiles[entrypoint].fsPath;
|
||||
@@ -12,7 +12,7 @@ it(
|
||||
'Should build the airtable folder',
|
||||
async () => {
|
||||
const { buildResult } = await runBuildForFolder('airtable');
|
||||
expect(buildResult['index.js']).toBeDefined();
|
||||
expect(buildResult.output['index.js']).toBeDefined();
|
||||
},
|
||||
TWO_MINUTES,
|
||||
);
|
||||
@@ -21,7 +21,7 @@ it(
|
||||
'Should build the aws-sdk folder',
|
||||
async () => {
|
||||
const { buildResult } = await runBuildForFolder('aws-sdk');
|
||||
expect(buildResult['index.js']).toBeDefined();
|
||||
expect(buildResult.output['index.js']).toBeDefined();
|
||||
},
|
||||
TWO_MINUTES,
|
||||
);
|
||||
@@ -30,7 +30,7 @@ it(
|
||||
'Should build the axios folder',
|
||||
async () => {
|
||||
const { buildResult } = await runBuildForFolder('axios');
|
||||
expect(buildResult['index.js']).toBeDefined();
|
||||
expect(buildResult.output['index.js']).toBeDefined();
|
||||
},
|
||||
TWO_MINUTES,
|
||||
);
|
||||
@@ -39,7 +39,7 @@ it(
|
||||
'Should build the mongoose folder',
|
||||
async () => {
|
||||
const { buildResult } = await runBuildForFolder('mongoose');
|
||||
expect(buildResult['index.js']).toBeDefined();
|
||||
expect(buildResult.output['index.js']).toBeDefined();
|
||||
},
|
||||
TWO_MINUTES,
|
||||
);
|
||||
|
||||
@@ -82,13 +82,13 @@ async function testDeployment (
|
||||
for (const probe of nowJson.probes || []) {
|
||||
console.log('testing', JSON.stringify(probe));
|
||||
const probeUrl = `https://${deploymentUrl}${probe.path}`;
|
||||
const { text, resp } = await fetchDeploymentUrl(probeUrl, {
|
||||
method: probe.method,
|
||||
body: probe.body ? JSON.stringify(probe.body) : undefined,
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
},
|
||||
});
|
||||
const fetchOpts = { method: probe.method, headers: { ...probe.headers } };
|
||||
if (probe.body) {
|
||||
fetchOpts.headers['content-type'] = 'application/json';
|
||||
fetchOpts.body = JSON.stringify(probe.body);
|
||||
}
|
||||
const { text, resp } = await fetchDeploymentUrl(probeUrl, fetchOpts);
|
||||
|
||||
if (probe.mustContain) {
|
||||
if (!text.includes(probe.mustContain)) {
|
||||
await fs.writeFile(path.join(__dirname, 'failed-page.txt'), text);
|
||||
|
||||
170
yarn.lock
170
yarn.lock
@@ -940,6 +940,16 @@
|
||||
dependencies:
|
||||
"@babel/types" "^7.3.0"
|
||||
|
||||
"@types/content-type@1.1.3":
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/content-type/-/content-type-1.1.3.tgz#3688bd77fc12f935548eef102a4e34c512b03a07"
|
||||
integrity sha512-pv8VcFrZ3fN93L4rTNIbbUzdkzjEyVMp5mPVjsFfOYTDOZMZiZ8P1dhu+kEv3faYyKzZgLlSvnyQNFg+p/v5ug==
|
||||
|
||||
"@types/cookie@0.3.3":
|
||||
version "0.3.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.3.3.tgz#85bc74ba782fb7aa3a514d11767832b0e3bc6803"
|
||||
integrity sha512-LKVP3cgXBT9RYj+t+9FDKwS5tdI+rPBXaNSkma7hvqy35lc7mAokC2zsqWJH0LaqIt3B962nuYI77hsJoT1gow==
|
||||
|
||||
"@types/cross-spawn@6.0.0":
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/cross-spawn/-/cross-spawn-6.0.0.tgz#320aaf1d1a12979f1b84fe7a5590a7e860bf3a80"
|
||||
@@ -1006,6 +1016,18 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.0.tgz#1eb8c033e98cf4e1a4cedcaf8bcafe8cb7591e85"
|
||||
integrity sha512-eAtOAFZefEnfJiRFQBGw1eYqa5GTLCZ1y86N0XSI/D6EB+E8z6VPV/UL7Gi5UEclFqoQk+6NRqEDsfmDLXn8sg==
|
||||
|
||||
"@types/jest-diff@*":
|
||||
version "20.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/jest-diff/-/jest-diff-20.0.1.tgz#35cc15b9c4f30a18ef21852e255fdb02f6d59b89"
|
||||
integrity sha512-yALhelO3i0hqZwhjtcr6dYyaLoCHbAMshwtj6cGxTvHZAKXHsYGdff6E8EPw3xLKY0ELUTQ69Q1rQiJENnccMA==
|
||||
|
||||
"@types/jest@24.0.13":
|
||||
version "24.0.13"
|
||||
resolved "https://registry.yarnpkg.com/@types/jest/-/jest-24.0.13.tgz#10f50b64cb05fb02411fbba49e9042a3a11da3f9"
|
||||
integrity sha512-3m6RPnO35r7Dg+uMLj1+xfZaOgIHHHut61djNjzwExXN4/Pm9has9C6I1KMYSfz7mahDhWUOVg4HW/nZdv5Pww==
|
||||
dependencies:
|
||||
"@types/jest-diff" "*"
|
||||
|
||||
"@types/minimatch@*":
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
|
||||
@@ -1101,6 +1123,13 @@
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/test-listen@1.1.0":
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/test-listen/-/test-listen-1.1.0.tgz#db7e5b0e277b4a3ee7b90770dae1a41b186458af"
|
||||
integrity sha512-y6ZfbSzYHniCeY6ZAzsQjSAdJInNVoEz4Uhsb81W+RCoNYA59yoG/+XbqPqCPj2KCU3Wa6RFWSozutkGIHIsNQ==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/uglify-js@*":
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-3.0.4.tgz#96beae23df6f561862a830b4288a49e86baac082"
|
||||
@@ -1158,7 +1187,14 @@
|
||||
globby "8.0.0"
|
||||
signal-exit "3.0.2"
|
||||
|
||||
"@zeit/ncc@0.18.5":
|
||||
"@zeit/ncc-watcher@1.0.3":
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@zeit/ncc-watcher/-/ncc-watcher-1.0.3.tgz#c4569d13db7b80a96a7672047c069400e69913ae"
|
||||
integrity sha512-367wm9bGMBCwT8kHQckw8UY/iYhC9rdzj357FBoM0SjVvWv53yziEmd12RkeF1EsBs0F2a1uBYdUaUvGo6LfkA==
|
||||
dependencies:
|
||||
"@zeit/ncc" "^0.18.5"
|
||||
|
||||
"@zeit/ncc@0.18.5", "@zeit/ncc@^0.18.5":
|
||||
version "0.18.5"
|
||||
resolved "https://registry.yarnpkg.com/@zeit/ncc/-/ncc-0.18.5.tgz#5687df6c32f1a2e2486aa110b3454ccebda4fb9c"
|
||||
integrity sha512-F+SbvEAh8rchiRXqQbmD1UmbePY7dCOKTbvfFtbVbK2xMH/tyri5YKfNxXKK7eL9EWkkbqB3NTVQO6nokApeBA==
|
||||
@@ -1891,6 +1927,13 @@ browser-resolve@^1.11.3:
|
||||
dependencies:
|
||||
resolve "1.1.7"
|
||||
|
||||
bs-logger@0.x:
|
||||
version "0.2.6"
|
||||
resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8"
|
||||
integrity sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==
|
||||
dependencies:
|
||||
fast-json-stable-stringify "2.x"
|
||||
|
||||
bser@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/bser/-/bser-2.0.0.tgz#9ac78d3ed5d915804fd87acb158bc797147a1719"
|
||||
@@ -1921,7 +1964,7 @@ buffer-fill@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c"
|
||||
integrity sha1-+PeLdniYiO858gXNY39o5wISKyw=
|
||||
|
||||
buffer-from@^1.0.0:
|
||||
buffer-from@1.x, buffer-from@^1.0.0:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
|
||||
integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==
|
||||
@@ -1961,6 +2004,11 @@ byte-size@^4.0.3:
|
||||
resolved "https://registry.yarnpkg.com/byte-size/-/byte-size-4.0.4.tgz#29d381709f41aae0d89c631f1c81aec88cd40b23"
|
||||
integrity sha512-82RPeneC6nqCdSwCX2hZUz3JPOvN5at/nTEw/CMf05Smu3Hrpo9Psb7LjN+k+XndNArG1EY8L4+BM3aTM4BCvw==
|
||||
|
||||
bytes@3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6"
|
||||
integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==
|
||||
|
||||
cacache@^11.0.1, cacache@^11.2.0:
|
||||
version "11.3.1"
|
||||
resolved "https://registry.yarnpkg.com/cacache/-/cacache-11.3.1.tgz#d09d25f6c4aca7a6d305d141ae332613aa1d515f"
|
||||
@@ -2424,6 +2472,11 @@ contains-path@^0.1.0:
|
||||
resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a"
|
||||
integrity sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=
|
||||
|
||||
content-type@1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b"
|
||||
integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==
|
||||
|
||||
conventional-changelog-angular@^5.0.2:
|
||||
version "5.0.2"
|
||||
resolved "https://registry.yarnpkg.com/conventional-changelog-angular/-/conventional-changelog-angular-5.0.2.tgz#39d945635e03b6d0c9d4078b1df74e06163dc66a"
|
||||
@@ -2514,6 +2567,11 @@ convert-source-map@^1.1.0, convert-source-map@^1.1.1, convert-source-map@^1.4.0,
|
||||
dependencies:
|
||||
safe-buffer "~5.1.1"
|
||||
|
||||
cookie@0.4.0:
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba"
|
||||
integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==
|
||||
|
||||
copy-concurrently@^1.0.0:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0"
|
||||
@@ -2864,6 +2922,11 @@ delegates@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
|
||||
integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=
|
||||
|
||||
depd@~1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
|
||||
integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=
|
||||
|
||||
detab@^2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/detab/-/detab-2.0.1.tgz#531f5e326620e2fd4f03264a905fb3bcc8af4df4"
|
||||
@@ -3512,7 +3575,7 @@ fast-glob@^2.0.2:
|
||||
merge2 "^1.2.3"
|
||||
micromatch "^3.1.10"
|
||||
|
||||
fast-json-stable-stringify@^2.0.0:
|
||||
fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2"
|
||||
integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I=
|
||||
@@ -4387,6 +4450,17 @@ http-cache-semantics@^3.8.1:
|
||||
resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2"
|
||||
integrity sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==
|
||||
|
||||
http-errors@1.7.2:
|
||||
version "1.7.2"
|
||||
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f"
|
||||
integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==
|
||||
dependencies:
|
||||
depd "~1.1.2"
|
||||
inherits "2.0.3"
|
||||
setprototypeof "1.1.1"
|
||||
statuses ">= 1.5.0 < 2"
|
||||
toidentifier "1.0.0"
|
||||
|
||||
http-proxy-agent@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz#e4821beef5b2142a2026bd73926fe537631c5405"
|
||||
@@ -4504,7 +4578,7 @@ inflight@^1.0.4:
|
||||
once "^1.3.0"
|
||||
wrappy "1"
|
||||
|
||||
inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3:
|
||||
inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
|
||||
integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
|
||||
@@ -6261,18 +6335,18 @@ json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1:
|
||||
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
|
||||
integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
|
||||
|
||||
json5@^0.5.1:
|
||||
version "0.5.1"
|
||||
resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821"
|
||||
integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=
|
||||
|
||||
json5@^2.1.0:
|
||||
json5@2.x, json5@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.0.tgz#e7a0c62c48285c628d20a10b85c89bb807c32850"
|
||||
integrity sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ==
|
||||
dependencies:
|
||||
minimist "^1.2.0"
|
||||
|
||||
json5@^0.5.1:
|
||||
version "0.5.1"
|
||||
resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821"
|
||||
integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=
|
||||
|
||||
jsonfile@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb"
|
||||
@@ -6753,6 +6827,11 @@ make-dir@^1.0.0, make-dir@^1.3.0:
|
||||
dependencies:
|
||||
pify "^3.0.0"
|
||||
|
||||
make-error@1.x:
|
||||
version "1.3.5"
|
||||
resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.5.tgz#efe4e81f6db28cadd605c70f29c831b58ef776c8"
|
||||
integrity sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==
|
||||
|
||||
make-fetch-happen@^4.0.1:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-4.0.1.tgz#141497cb878f243ba93136c83d8aba12c216c083"
|
||||
@@ -7056,7 +7135,7 @@ mixin-deep@^1.2.0:
|
||||
for-in "^1.0.2"
|
||||
is-extendable "^1.0.1"
|
||||
|
||||
"mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0:
|
||||
mkdirp@0.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0:
|
||||
version "0.5.1"
|
||||
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
|
||||
integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=
|
||||
@@ -8156,6 +8235,16 @@ randomatic@^3.0.0:
|
||||
kind-of "^6.0.0"
|
||||
math-random "^1.0.1"
|
||||
|
||||
raw-body@2.4.0:
|
||||
version "2.4.0"
|
||||
resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332"
|
||||
integrity sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==
|
||||
dependencies:
|
||||
bytes "3.1.0"
|
||||
http-errors "1.7.2"
|
||||
iconv-lite "0.4.24"
|
||||
unpipe "1.0.0"
|
||||
|
||||
rc@^1.1.2, rc@^1.2.7:
|
||||
version "1.2.8"
|
||||
resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed"
|
||||
@@ -8578,6 +8667,13 @@ resolve@1.1.7:
|
||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b"
|
||||
integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=
|
||||
|
||||
resolve@1.x:
|
||||
version "1.11.1"
|
||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.11.1.tgz#ea10d8110376982fef578df8fc30b9ac30a07a3e"
|
||||
integrity sha512-vIpgF6wfuJOZI7KKKSP+HmiKggadPQAdsp5HiC1mvqnfp0gF1vdwgBWZIdrVft9pgqoMFQN+R7BSWZiBxx+BBw==
|
||||
dependencies:
|
||||
path-parse "^1.0.6"
|
||||
|
||||
resolve@^1.3.2:
|
||||
version "1.10.0"
|
||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.10.0.tgz#3bdaaeaf45cc07f375656dfd2e54ed0810b101ba"
|
||||
@@ -8768,6 +8864,11 @@ semver@^4.0.3:
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.6.tgz#300bc6e0e86374f7ba61068b5b1ecd57fc6532da"
|
||||
integrity sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto=
|
||||
|
||||
semver@^5.5:
|
||||
version "5.7.0"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.0.tgz#790a7cf6fea5459bac96110b29b60412dc8ff96b"
|
||||
integrity sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==
|
||||
|
||||
semver@~5.3.0:
|
||||
version "5.3.0"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f"
|
||||
@@ -8803,6 +8904,11 @@ set-value@^2.0.0:
|
||||
is-plain-object "^2.0.3"
|
||||
split-string "^3.0.1"
|
||||
|
||||
setprototypeof@1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683"
|
||||
integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==
|
||||
|
||||
shebang-command@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"
|
||||
@@ -9106,6 +9212,11 @@ static-extend@^0.1.1:
|
||||
define-property "^0.2.5"
|
||||
object-copy "^0.1.0"
|
||||
|
||||
"statuses@>= 1.5.0 < 2":
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c"
|
||||
integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=
|
||||
|
||||
stealthy-require@^1.1.0:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b"
|
||||
@@ -9457,6 +9568,11 @@ test-exclude@^5.0.0:
|
||||
read-pkg-up "^4.0.0"
|
||||
require-main-filename "^1.0.1"
|
||||
|
||||
test-listen@1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/test-listen/-/test-listen-1.1.0.tgz#2ba614d96c3bc9157469003027b42a495dd83b6a"
|
||||
integrity sha512-OyEVi981C1sb9NX1xayfgZls3p8QTDRwp06EcgxSgd1kktaENBW8dO15i8v/7Fi15j0IYQctJzk5J+hyEBId2w==
|
||||
|
||||
text-extensions@^1.0.0:
|
||||
version "1.9.0"
|
||||
resolved "https://registry.yarnpkg.com/text-extensions/-/text-extensions-1.9.0.tgz#1853e45fee39c945ce6f6c36b2d659b5aabc2a26"
|
||||
@@ -9570,6 +9686,11 @@ to-regex@^3.0.1, to-regex@^3.0.2:
|
||||
regex-not "^1.0.2"
|
||||
safe-regex "^1.1.0"
|
||||
|
||||
toidentifier@1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553"
|
||||
integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==
|
||||
|
||||
tough-cookie@>=2.3.3, tough-cookie@^2.3.4:
|
||||
version "2.5.0"
|
||||
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2"
|
||||
@@ -9640,6 +9761,21 @@ trough@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/trough/-/trough-1.0.3.tgz#e29bd1614c6458d44869fc28b255ab7857ef7c24"
|
||||
integrity sha512-fwkLWH+DimvA4YCy+/nvJd61nWQQ2liO/nF/RjkTpiOGi+zxZzVkhb1mvbHIIW4b/8nDsYI8uTmAlc0nNkRMOw==
|
||||
|
||||
ts-jest@24.0.2:
|
||||
version "24.0.2"
|
||||
resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-24.0.2.tgz#8dde6cece97c31c03e80e474c749753ffd27194d"
|
||||
integrity sha512-h6ZCZiA1EQgjczxq+uGLXQlNgeg02WWJBbeT8j6nyIBRQdglqbvzDoHahTEIiS6Eor6x8mK6PfZ7brQ9Q6tzHw==
|
||||
dependencies:
|
||||
bs-logger "0.x"
|
||||
buffer-from "1.x"
|
||||
fast-json-stable-stringify "2.x"
|
||||
json5 "2.x"
|
||||
make-error "1.x"
|
||||
mkdirp "0.x"
|
||||
resolve "1.x"
|
||||
semver "^5.5"
|
||||
yargs-parser "10.x"
|
||||
|
||||
tslib@^1.9.0:
|
||||
version "1.9.3"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286"
|
||||
@@ -9849,6 +9985,11 @@ universalify@^0.1.0:
|
||||
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
|
||||
integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==
|
||||
|
||||
unpipe@1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
|
||||
integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=
|
||||
|
||||
unset-value@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559"
|
||||
@@ -10261,6 +10402,13 @@ yallist@^3.0.0, yallist@^3.0.2:
|
||||
resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.3.tgz#b4b049e314be545e3ce802236d6cd22cd91c3de9"
|
||||
integrity sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==
|
||||
|
||||
yargs-parser@10.x:
|
||||
version "10.1.0"
|
||||
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-10.1.0.tgz#7202265b89f7e9e9f2e5765e0fe735a905edbaa8"
|
||||
integrity sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==
|
||||
dependencies:
|
||||
camelcase "^4.1.0"
|
||||
|
||||
yargs-parser@^11.1.1:
|
||||
version "11.1.1"
|
||||
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-11.1.1.tgz#879a0865973bca9f6bab5cbdf3b1c67ec7d3bcf4"
|
||||
|
||||
Reference in New Issue
Block a user