diff --git a/package.json b/package.json index d88ab4194c5df..1be6067933959 100644 --- a/package.json +++ b/package.json @@ -81,6 +81,7 @@ "execa": "2.0.3", "express": "4.17.0", "faunadb": "2.6.1", + "firebase": "6.3.4", "fs-extra": "7.0.1", "get-port": "5.0.0", "isomorphic-unfetch": "3.0.0", diff --git a/packages/next-server/server/config.ts b/packages/next-server/server/config.ts index 36e4a25456023..25d96b215135f 100644 --- a/packages/next-server/server/config.ts +++ b/packages/next-server/server/config.ts @@ -1,9 +1,10 @@ -import os from 'os' import findUp from 'find-up' +import os from 'os' + import { CONFIG_FILE } from '../lib/constants' import { execOnce } from '../lib/utils' -const targets = ['server', 'serverless'] +const targets = ['server', 'serverless', 'experimental-serverless-trace'] const defaultConfig: { [key: string]: any } = { env: [], @@ -120,10 +121,12 @@ export default function loadConfig( } if ( - userConfig.target === 'serverless' && + userConfig.target && + userConfig.target !== 'server' && userConfig.publicRuntimeConfig && Object.keys(userConfig.publicRuntimeConfig).length !== 0 ) { + // TODO: change error message tone to "Only compatible with [fat] server mode" throw new Error( 'Cannot use publicRuntimeConfig with target=serverless https://err.sh/zeit/next.js/serverless-publicRuntimeConfig' ) @@ -134,3 +137,9 @@ export default function loadConfig( return defaultConfig } + +export function isTargetLikeServerless(target: string) { + const isServerless = target === 'serverless' + const isServerlessTrace = target === 'experimental-serverless-trace' + return isServerless || isServerlessTrace +} diff --git a/packages/next-server/server/next-server.ts b/packages/next-server/server/next-server.ts index 84544b68ba866..d37b95d1fa186 100644 --- a/packages/next-server/server/next-server.ts +++ b/packages/next-server/server/next-server.ts @@ -1,13 +1,12 @@ +import compression from 'compression' import fs from 'fs' import { IncomingMessage, ServerResponse } from 'http' import { join, resolve, sep } from 'path' import { parse as parseQs, ParsedUrlQuery } from 'querystring' import { parse as parseUrl, UrlWithParsedQuery } from 'url' -import compression from 'compression' import { BUILD_ID_FILE, - BUILD_MANIFEST, CLIENT_PUBLIC_FILES_PATH, CLIENT_STATIC_FILES_PATH, CLIENT_STATIC_FILES_RUNTIME, @@ -25,12 +24,12 @@ import { import * as envConfig from '../lib/runtime-config' import { NextApiRequest, NextApiResponse } from '../lib/utils' import { apiResolver } from './api-utils' -import loadConfig from './config' +import loadConfig, { isTargetLikeServerless } from './config' import { recursiveReadDirSync } from './lib/recursive-readdir-sync' import { loadComponents, LoadComponentsReturnType } from './load-components' import { renderToHTML } from './render' import { getPagePath } from './require' -import Router, { route, Route, RouteMatch, Params } from './router' +import Router, { Params, route, Route, RouteMatch } from './router' import { sendHTML } from './send-html' import { serveStatic } from './serve-static' import { isBlockedPage, isInternalUrl } from './utils' @@ -98,7 +97,9 @@ export default class Server { this.publicDir = join(this.dir, CLIENT_PUBLIC_FILES_PATH) this.pagesManifest = join( this.distDir, - this.nextConfig.target || 'server', + this.nextConfig.target === 'server' + ? SERVER_DIRECTORY + : SERVERLESS_DIRECTORY, PAGES_MANIFEST ) @@ -131,7 +132,7 @@ export default class Server { this.renderOpts.runtimeConfig = publicRuntimeConfig } - if (compress && this.nextConfig.target !== 'serverless') { + if (compress && this.nextConfig.target === 'server') { this.compression = compression() as Middleware } @@ -319,7 +320,7 @@ export default class Server { return this.render404(req, res) } - if (!this.renderOpts.dev && this.nextConfig.target === 'serverless') { + if (!this.renderOpts.dev && this._isLikeServerless) { const mod = require(resolverFunction) if (typeof mod.default === 'function') { return mod.default(req, res) @@ -342,7 +343,7 @@ export default class Server { return getPagePath( pathname, this.distDir, - this.nextConfig.target === 'serverless', + this._isLikeServerless, this.renderOpts.dev ) } @@ -352,9 +353,7 @@ export default class Server { const publicFiles = recursiveReadDirSync(this.publicDir) const serverBuildPath = join( this.distDir, - this.nextConfig.target === 'serverless' - ? SERVERLESS_DIRECTORY - : SERVER_DIRECTORY + this._isLikeServerless ? SERVERLESS_DIRECTORY : SERVER_DIRECTORY ) const pagesManifest = require(join(serverBuildPath, PAGES_MANIFEST)) @@ -458,8 +457,7 @@ export default class Server { pathname: string, query: ParsedUrlQuery = {} ) { - const serverless = - !this.renderOpts.dev && this.nextConfig.target === 'serverless' + const serverless = !this.renderOpts.dev && this._isLikeServerless // try serving a static AMP version first if (query.amp) { try { @@ -708,4 +706,8 @@ export default class Server { throw err } } + + private get _isLikeServerless(): boolean { + return isTargetLikeServerless(this.nextConfig.target) + } } diff --git a/packages/next/build/entries.ts b/packages/next/build/entries.ts index d896332bfc07e..d9b13b8d7adfe 100644 --- a/packages/next/build/entries.ts +++ b/packages/next/build/entries.ts @@ -1,6 +1,8 @@ +import { isTargetLikeServerless } from 'next-server/dist/server/config' import { join } from 'path' import { stringify } from 'querystring' -import { PAGES_DIR_ALIAS, DOT_NEXT_ALIAS, API_ROUTE } from '../lib/constants' + +import { API_ROUTE, DOT_NEXT_ALIAS, PAGES_DIR_ALIAS } from '../lib/constants' import { ServerlessLoaderQuery } from './webpack/loaders/next-serverless-loader' type PagesMapping = { @@ -45,7 +47,7 @@ type Entrypoints = { export function createEntrypoints( pages: PagesMapping, - target: 'server' | 'serverless', + target: 'server' | 'serverless' | 'experimental-serverless-trace', buildId: string, dynamicBuildId: boolean, config: any @@ -72,7 +74,9 @@ export function createEntrypoints( const bundlePath = join('static', buildId, 'pages', bundleFile) - if (isApiRoute && target === 'serverless') { + const isLikeServerless = isTargetLikeServerless(target) + + if (isApiRoute && isLikeServerless) { const serverlessLoaderOptions: ServerlessLoaderQuery = { page, absolutePagePath, @@ -83,11 +87,7 @@ export function createEntrypoints( )}!` } else if (isApiRoute || target === 'server') { server[bundlePath] = [absolutePagePath] - } else if ( - target === 'serverless' && - page !== '/_app' && - page !== '/_document' - ) { + } else if (isLikeServerless && page !== '/_app' && page !== '/_document') { const serverlessLoaderOptions: ServerlessLoaderQuery = { page, absolutePagePath, diff --git a/packages/next/build/index.ts b/packages/next/build/index.ts index e33f992316784..a0d8187307386 100644 --- a/packages/next/build/index.ts +++ b/packages/next/build/index.ts @@ -1,18 +1,25 @@ +import { Sema } from 'async-sema' import chalk from 'chalk' +import fs from 'fs' +import mkdirpOrig from 'mkdirp' import { - SERVER_DIRECTORY, - SERVERLESS_DIRECTORY, - PAGES_MANIFEST, CHUNK_GRAPH_MANIFEST, + PAGES_MANIFEST, PHASE_PRODUCTION_BUILD, + SERVER_DIRECTORY, + SERVERLESS_DIRECTORY, } from 'next-server/constants' -import loadConfig from 'next-server/next-config' +import loadConfig, { + isTargetLikeServerless, +} from 'next-server/dist/server/config' import nanoid from 'next/dist/compiled/nanoid/index.js' import path from 'path' -import fs from 'fs' import { promisify } from 'util' +import workerFarm from 'worker-farm' + import formatWebpackMessages from '../client/dev/error-overlay/format-webpack-messages' import { recursiveDelete } from '../lib/recursive-delete' +import { recursiveReadDir } from '../lib/recursive-readdir' import { verifyTypeScriptSetup } from '../lib/verifyTypeScriptSetup' import { CompilerResult, runCompiler } from './compiler' import { createEntrypoints, createPagesMapping } from './entries' @@ -25,9 +32,9 @@ import { getFileForPage, getPageSizeInKb, getSpecifiedPages, - printTreeView, - PageInfo, hasCustomAppGetInitialProps, + PageInfo, + printTreeView, } from './utils' import getBaseWebpackConfig from './webpack-config' import { @@ -35,10 +42,6 @@ import { getPageChunks, } from './webpack/plugins/chunk-graph-plugin' import { writeBuildId } from './write-build-id' -import { recursiveReadDir } from '../lib/recursive-readdir' -import mkdirpOrig from 'mkdirp' -import workerFarm from 'worker-farm' -import { Sema } from 'async-sema' const fsUnlink = promisify(fs.unlink) const fsRmdir = promisify(fs.rmdir) @@ -75,11 +78,13 @@ export default async function build(dir: string, conf = null): Promise { isFlyingShuttle || process.env.__NEXT_BUILDER_EXPERIMENTAL_PAGE ) + const isLikeServerless = isTargetLikeServerless(target) + if (selectivePageBuilding && target !== 'serverless') { throw new Error( `Cannot use ${ isFlyingShuttle ? 'flying shuttle' : '`now dev`' - } without the serverless target.` + } without the \`serverless\` target.` ) } @@ -199,7 +204,8 @@ export default async function build(dir: string, conf = null): Promise { ]) let result: CompilerResult = { warnings: [], errors: [] } - if (target === 'serverless') { + // TODO: why do we need this?? https://github.com/zeit/next.js/issues/8253 + if (isLikeServerless) { const clientResult = await runCompiler(configs[0]) // Fail build if clientResult contains errors if (clientResult.errors.length > 0) { @@ -273,7 +279,7 @@ export default async function build(dir: string, conf = null): Promise { const pageKeys = Object.keys(mappedPages) const manifestPath = path.join( distDir, - target === 'serverless' ? SERVERLESS_DIRECTORY : SERVER_DIRECTORY, + isLikeServerless ? SERVERLESS_DIRECTORY : SERVER_DIRECTORY, PAGES_MANIFEST ) @@ -303,12 +309,12 @@ export default async function build(dir: string, conf = null): Promise { const actualPage = page === '/' ? '/index' : page const size = await getPageSizeInKb(actualPage, distPath, buildId) const bundleRelative = path.join( - target === 'serverless' ? 'pages' : `static/${buildId}/pages`, + isLikeServerless ? 'pages' : `static/${buildId}/pages`, actualPage + '.js' ) const serverBundle = path.join( distPath, - target === 'serverless' ? SERVERLESS_DIRECTORY : SERVER_DIRECTORY, + isLikeServerless ? SERVERLESS_DIRECTORY : SERVER_DIRECTORY, bundleRelative ) @@ -324,7 +330,7 @@ export default async function build(dir: string, conf = null): Promise { if (nonReservedPage && customAppGetInitialProps === undefined) { customAppGetInitialProps = hasCustomAppGetInitialProps( - target === 'serverless' + isLikeServerless ? serverBundle : path.join( distPath, @@ -437,7 +443,7 @@ export default async function build(dir: string, conf = null): Promise { for (const file of toMove) { const orig = path.join(exportOptions.outdir, file) const dest = path.join(serverDir, file) - const relativeDest = (target === 'serverless' + const relativeDest = (isLikeServerless ? path.join('pages', file) : path.join('static', buildId, 'pages', file) ).replace(/\\/g, '/') @@ -465,9 +471,5 @@ export default async function build(dir: string, conf = null): Promise { await flyingShuttle.save(allStaticPages, pageInfos) } - printTreeView( - Object.keys(allMappedPages), - allPageInfos, - target === 'serverless' - ) + printTreeView(Object.keys(allMappedPages), allPageInfos, isLikeServerless) } diff --git a/packages/next/build/webpack-config.ts b/packages/next/build/webpack-config.ts index 0cbb4cc8ef2da..4032efb73b5fe 100644 --- a/packages/next/build/webpack-config.ts +++ b/packages/next/build/webpack-config.ts @@ -1,10 +1,10 @@ import ForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin' -import fs from 'fs' import { CLIENT_STATIC_FILES_RUNTIME_MAIN, CLIENT_STATIC_FILES_RUNTIME_WEBPACK, REACT_LOADABLE_MANIFEST, SERVER_DIRECTORY, + SERVERLESS_DIRECTORY, } from 'next-server/constants' import resolve from 'next/dist/compiled/resolve/index.js' import path from 'path' @@ -25,6 +25,7 @@ import ChunkNamesPlugin from './webpack/plugins/chunk-names-plugin' import { importAutoDllPlugin } from './webpack/plugins/dll-import' import { HashedChunkIdsPlugin } from './webpack/plugins/hashed-chunk-ids-plugin' import { DropClientPage } from './webpack/plugins/next-drop-client-page-plugin' +import NextEsmPlugin from './webpack/plugins/next-esm-plugin' import NextJsSsrImportPlugin from './webpack/plugins/nextjs-ssr-import' import NextJsSSRModuleCachePlugin from './webpack/plugins/nextjs-ssr-module-cache' import PagesManifestPlugin from './webpack/plugins/pages-manifest-plugin' @@ -32,7 +33,6 @@ import { ReactLoadablePlugin } from './webpack/plugins/react-loadable-plugin' import { ServerlessPlugin } from './webpack/plugins/serverless-plugin' import { SharedRuntimePlugin } from './webpack/plugins/shared-runtime-plugin' import { TerserPlugin } from './webpack/plugins/terser-webpack-plugin/src/index' -import NextEsmPlugin from './webpack/plugins/next-esm-plugin' type ExcludesFalse = (x: T | false) => x is T @@ -79,7 +79,12 @@ export default async function getBaseWebpackConfig( .split(process.platform === 'win32' ? ';' : ':') .filter(p => !!p) - const outputDir = target === 'serverless' ? 'serverless' : SERVER_DIRECTORY + const isServerless = target === 'serverless' + const isServerlessTrace = target === 'experimental-serverless-trace' + // Intentionally not using isTargetLikeServerless helper + const isLikeServerless = isServerless || isServerlessTrace + + const outputDir = isLikeServerless ? SERVERLESS_DIRECTORY : SERVER_DIRECTORY const outputPath = path.join(distDir, isServer ? outputDir : '') const totalPages = Object.keys(entrypoints).length const clientEntries = !isServer @@ -238,7 +243,7 @@ export default async function getBaseWebpackConfig( target: isServer ? 'node' : 'web', externals: !isServer ? undefined - : target !== 'serverless' + : !isServerless ? [ (context, request, callback) => { const notExternalModules = [ @@ -293,8 +298,8 @@ export default async function getBaseWebpackConfig( }, ] : [ - // When the serverless target is used all node_modules will be compiled into the output bundles - // So that the serverless bundles have 0 runtime dependencies + // When the 'serverless' target is used all node_modules will be compiled into the output bundles + // So that the 'serverless' bundles have 0 runtime dependencies 'amp-toolbox-optimizer', // except this one (context, request, callback) => { if ( @@ -561,11 +566,14 @@ export default async function getBaseWebpackConfig( ) }, }), - target === 'serverless' && - (isServer || selectivePageBuilding) && - new ServerlessPlugin(buildId, { isServer }), - isServer && new PagesManifestPlugin(target === 'serverless'), - target !== 'serverless' && + isLikeServerless && + new ServerlessPlugin(buildId, { + isServer, + isFlyingShuttle: selectivePageBuilding, + isTrace: isServerlessTrace, + }), + isServer && new PagesManifestPlugin(isLikeServerless), + target === 'server' && isServer && new NextJsSSRModuleCachePlugin({ outputPath }), isServer && new NextJsSsrImportPlugin(), diff --git a/packages/next/build/webpack/plugins/serverless-plugin.ts b/packages/next/build/webpack/plugins/serverless-plugin.ts index 5eec0eaaacd07..4c0039333dfa5 100644 --- a/packages/next/build/webpack/plugins/serverless-plugin.ts +++ b/packages/next/build/webpack/plugins/serverless-plugin.ts @@ -54,18 +54,47 @@ function interceptFileWrites( export class ServerlessPlugin { private buildId: string private isServer: boolean + private isTrace: boolean + private isFlyingShuttle: boolean - constructor(buildId: string, { isServer = false } = {}) { + constructor( + buildId: string, + { + isServer, + isTrace, + isFlyingShuttle, + }: { isServer: boolean; isTrace: boolean; isFlyingShuttle: boolean } + ) { this.buildId = buildId this.isServer = isServer + this.isTrace = isTrace + this.isFlyingShuttle = isFlyingShuttle } apply(compiler: Compiler) { - if (this.isServer) { - interceptFileWrites(compiler, content => - replaceInBuffer(content, NEXT_REPLACE_BUILD_ID, this.buildId) - ) + if (!this.isServer) { + if (this.isFlyingShuttle) { + compiler.hooks.emit.tap('ServerlessPlugin', compilation => { + const assetNames = Object.keys(compilation.assets).filter(f => + f.includes(this.buildId) + ) + for (const name of assetNames) { + compilation.assets[ + name + .replace(new RegExp(`${this.buildId}[\\/\\\\]`), 'client/') + .replace(/[.]js$/, `.${this.buildId}.js`) + ] = compilation.assets[name] + } + }) + } + return + } + interceptFileWrites(compiler, content => + replaceInBuffer(content, NEXT_REPLACE_BUILD_ID, this.buildId) + ) + + if (!this.isTrace) { compiler.hooks.compilation.tap('ServerlessPlugin', compilation => { compilation.hooks.optimizeChunksBasic.tap( 'ServerlessPlugin', @@ -86,19 +115,6 @@ export class ServerlessPlugin { } ) }) - } else { - compiler.hooks.emit.tap('ServerlessPlugin', compilation => { - const assetNames = Object.keys(compilation.assets).filter(f => - f.includes(this.buildId) - ) - for (const name of assetNames) { - compilation.assets[ - name - .replace(new RegExp(`${this.buildId}[\\/\\\\]`), 'client/') - .replace(/[.]js$/, `.${this.buildId}.js`) - ] = compilation.assets[name] - } - }) } } } diff --git a/packages/next/export/index.js b/packages/next/export/index.js index 62d4c04058dd5..c9a469aaac43f 100644 --- a/packages/next/export/index.js +++ b/packages/next/export/index.js @@ -4,7 +4,9 @@ import { recursiveCopy } from '../lib/recursive-copy' import mkdirpModule from 'mkdirp' import { resolve, join } from 'path' import { existsSync, readFileSync } from 'fs' -import loadConfig from 'next-server/next-config' +import loadConfig, { + isTargetLikeServerless +} from 'next-server/dist/server/config' import { PHASE_EXPORT, SERVER_DIRECTORY, @@ -183,7 +185,7 @@ export default async function (dir, options, configuration) { serverRuntimeConfig, concurrency, subFolders, - serverless: nextConfig.target === 'serverless' + serverless: isTargetLikeServerless(nextConfig.target) }) worker.on('message', ({ type, payload }) => { if (type === 'progress' && progress) { diff --git a/test/integration/external-assets/next.config.js b/test/integration/external-assets/next.config.js new file mode 100644 index 0000000000000..1a3d6bd0f29ba --- /dev/null +++ b/test/integration/external-assets/next.config.js @@ -0,0 +1,6 @@ +module.exports = { + target: 'experimental-serverless-trace', + onDemandEntries: { + maxInactiveAge: 1000 * 60 * 60 + } +} diff --git a/test/integration/external-assets/pages/about/history.js b/test/integration/external-assets/pages/about/history.js new file mode 100644 index 0000000000000..17844f4af04a2 --- /dev/null +++ b/test/integration/external-assets/pages/about/history.js @@ -0,0 +1,19 @@ +import firebase from 'firebase/app' +import 'firebase/firestore' + +if (!firebase.apps.length) { + firebase.initializeApp({ projectId: 'noop' }) +} + +const store = firebase.firestore() + +const Comp = ({ results }) => { + return
Hello Firebase: {results}
+} + +Comp.getInitialProps = async () => { + const query = await store.collection('users').get() + return { results: query.size } +} + +export default Comp diff --git a/test/integration/external-assets/test/index.test.js b/test/integration/external-assets/test/index.test.js new file mode 100644 index 0000000000000..19bd653ee2c39 --- /dev/null +++ b/test/integration/external-assets/test/index.test.js @@ -0,0 +1,29 @@ +/* eslint-env jest */ +/* global jasmine */ +import { join } from 'path' +import { + killApp, + findPort, + nextBuild, + nextStart, + renderViaHTTP +} from 'next-test-utils' + +const appDir = join(__dirname, '../') +let appPort +let app +jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000 * 60 * 5 + +describe('External Assets', () => { + beforeAll(async () => { + await nextBuild(appDir, []) + appPort = await findPort() + app = await nextStart(appDir, appPort) + }) + afterAll(() => killApp(app)) + + it('should support Firebase', async () => { + const html = await renderViaHTTP(appPort, '/about/history') + expect(html).toMatch(/Hello Firebase: 0/) + }) +}) diff --git a/test/integration/serverless-trace/components/hello.js b/test/integration/serverless-trace/components/hello.js new file mode 100644 index 0000000000000..0a350ec10be59 --- /dev/null +++ b/test/integration/serverless-trace/components/hello.js @@ -0,0 +1 @@ +export default () =>

Hello!

diff --git a/test/integration/serverless-trace/next.config.js b/test/integration/serverless-trace/next.config.js new file mode 100644 index 0000000000000..77afbd15b0ab7 --- /dev/null +++ b/test/integration/serverless-trace/next.config.js @@ -0,0 +1,12 @@ +module.exports = { + target: 'experimental-serverless-trace', + onDemandEntries: { + // Make sure entries are not getting disposed. + maxInactiveAge: 1000 * 60 * 60 + }, + experimental: { + publicDirectory: true + }, + // make sure error isn't thrown from empty publicRuntimeConfig + publicRuntimeConfig: {} +} diff --git a/test/integration/serverless-trace/pages/abc.js b/test/integration/serverless-trace/pages/abc.js new file mode 100644 index 0000000000000..7d148e908f127 --- /dev/null +++ b/test/integration/serverless-trace/pages/abc.js @@ -0,0 +1 @@ +export default () =>
test
diff --git a/test/integration/serverless-trace/pages/api/hello.js b/test/integration/serverless-trace/pages/api/hello.js new file mode 100644 index 0000000000000..a9f26c92c2adc --- /dev/null +++ b/test/integration/serverless-trace/pages/api/hello.js @@ -0,0 +1,3 @@ +export default (req, res) => { + res.send('hello world') +} diff --git a/test/integration/serverless-trace/pages/api/posts/[id].js b/test/integration/serverless-trace/pages/api/posts/[id].js new file mode 100644 index 0000000000000..490c95a79f881 --- /dev/null +++ b/test/integration/serverless-trace/pages/api/posts/[id].js @@ -0,0 +1,3 @@ +export default (req, res) => { + res.json({ post: req.query.id }) +} diff --git a/test/integration/serverless-trace/pages/dynamic-two.js b/test/integration/serverless-trace/pages/dynamic-two.js new file mode 100644 index 0000000000000..88d9e7d63496c --- /dev/null +++ b/test/integration/serverless-trace/pages/dynamic-two.js @@ -0,0 +1,9 @@ +import dynamic from 'next/dynamic' + +const Hello = dynamic(() => import('../components/hello')) + +export default () => ( +
+ +
+) diff --git a/test/integration/serverless-trace/pages/dynamic.js b/test/integration/serverless-trace/pages/dynamic.js new file mode 100644 index 0000000000000..88d9e7d63496c --- /dev/null +++ b/test/integration/serverless-trace/pages/dynamic.js @@ -0,0 +1,9 @@ +import dynamic from 'next/dynamic' + +const Hello = dynamic(() => import('../components/hello')) + +export default () => ( +
+ +
+) diff --git a/test/integration/serverless-trace/pages/fetch.js b/test/integration/serverless-trace/pages/fetch.js new file mode 100644 index 0000000000000..b863dc3d6e85b --- /dev/null +++ b/test/integration/serverless-trace/pages/fetch.js @@ -0,0 +1,29 @@ +import fetch from 'isomorphic-unfetch' +import React from 'react' + +export default class extends React.Component { + static async getInitialProps () { + try { + const res = await fetch('') + const text = await res.text() + console.log(text) + return { text } + } catch (err) { + if (err.message.includes('is not a function')) { + return { failed: true, error: err.toString() } + } + + return { error: err.toString() } + } + } + render () { + const { failed, error, text } = this.props + return ( +
+ {failed ? 'failed' : ''} + {error} +
{text}
+
+ ) + } +} diff --git a/test/integration/serverless-trace/pages/index.js b/test/integration/serverless-trace/pages/index.js new file mode 100644 index 0000000000000..9abcbc9f8ee19 --- /dev/null +++ b/test/integration/serverless-trace/pages/index.js @@ -0,0 +1,11 @@ +import Link from 'next/link' +export default () => { + return ( +
+ Hello World + + fetch page + +
+ ) +} diff --git a/test/integration/serverless-trace/pages/some-amp.js b/test/integration/serverless-trace/pages/some-amp.js new file mode 100644 index 0000000000000..8b00afe0125b3 --- /dev/null +++ b/test/integration/serverless-trace/pages/some-amp.js @@ -0,0 +1,2 @@ +export default () => `Hi Im an AMP page!` +export const config = { amp: 'hybrid' } diff --git a/test/integration/serverless-trace/public/hello.txt b/test/integration/serverless-trace/public/hello.txt new file mode 100644 index 0000000000000..3b18e512dba79 --- /dev/null +++ b/test/integration/serverless-trace/public/hello.txt @@ -0,0 +1 @@ +hello world diff --git a/test/integration/serverless-trace/test/index.test.js b/test/integration/serverless-trace/test/index.test.js new file mode 100644 index 0000000000000..a07043f189177 --- /dev/null +++ b/test/integration/serverless-trace/test/index.test.js @@ -0,0 +1,149 @@ +/* eslint-env jest */ +/* global jasmine */ +import webdriver from 'next-webdriver' +import { join } from 'path' +import { existsSync } from 'fs' +import { + killApp, + findPort, + nextBuild, + nextStart, + fetchViaHTTP, + renderViaHTTP +} from 'next-test-utils' +import fetch from 'node-fetch' + +const appDir = join(__dirname, '../') +const serverlessDir = join(appDir, '.next/serverless/pages') +let appPort +let app +jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000 * 60 * 5 + +describe('Serverless', () => { + beforeAll(async () => { + await nextBuild(appDir) + appPort = await findPort() + app = await nextStart(appDir, appPort) + }) + afterAll(() => killApp(app)) + + it('should render the page', async () => { + const html = await renderViaHTTP(appPort, '/') + expect(html).toMatch(/Hello World/) + }) + + it('should serve file from public folder', async () => { + const content = await renderViaHTTP(appPort, '/hello.txt') + expect(content.trim()).toBe('hello world') + }) + + it('should render the page with dynamic import', async () => { + const html = await renderViaHTTP(appPort, '/dynamic') + expect(html).toMatch(/Hello!/) + }) + + it('should render the page with same dynamic import', async () => { + const html = await renderViaHTTP(appPort, '/dynamic-two') + expect(html).toMatch(/Hello!/) + }) + + it('should render 404', async () => { + const html = await renderViaHTTP(appPort, '/404') + expect(html).toMatch(/This page could not be found/) + }) + + it('should render an AMP page', async () => { + const html = await renderViaHTTP(appPort, '/some-amp?amp=1') + expect(html).toMatch(/Hi Im an AMP page/) + expect(html).toMatch(/ampproject\.org/) + }) + + it('should have correct amphtml rel link', async () => { + const html = await renderViaHTTP(appPort, '/some-amp') + expect(html).toMatch(/Hi Im an AMP page/) + expect(html).toMatch(/rel="amphtml" href="\/some-amp\?amp=1"/) + }) + + it('should have correct canonical link', async () => { + const html = await renderViaHTTP(appPort, '/some-amp?amp=1') + expect(html).toMatch(/rel="canonical" href="\/some-amp"/) + }) + + it('should render correctly when importing isomorphic-unfetch', async () => { + const url = `http://localhost:${appPort}/fetch` + const res = await fetch(url) + expect(res.status).toBe(200) + const text = await res.text() + expect(text.includes('failed')).toBe(false) + }) + + it('should render correctly when importing isomorphic-unfetch on the client side', async () => { + const browser = await webdriver(appPort, '/') + try { + const text = await browser + .elementByCss('a') + .click() + .waitForElementByCss('.fetch-page') + .elementByCss('#text') + .text() + + expect(text).toMatch(/fetch page/) + } finally { + await browser.close() + } + }) + + it('should not output _app.js and _document.js to serverless build', () => { + expect(existsSync(join(serverlessDir, '_app.js'))).toBeFalsy() + expect(existsSync(join(serverlessDir, '_document.js'))).toBeFalsy() + }) + + it('should replace static pages with HTML files', async () => { + const staticFiles = ['abc', 'dynamic', 'dynamic-two', 'some-amp'] + for (const file of staticFiles) { + expect(existsSync(join(serverlessDir, file + '.html'))).toBe(true) + expect(existsSync(join(serverlessDir, file + '.js'))).toBe(false) + } + }) + + it('should not replace non-static pages with HTML files', async () => { + const nonStaticFiles = ['fetch', '_error'] + for (const file of nonStaticFiles) { + expect(existsSync(join(serverlessDir, file + '.js'))).toBe(true) + expect(existsSync(join(serverlessDir, file + '.html'))).toBe(false) + } + }) + + it('should reply on API request successfully', async () => { + const content = await renderViaHTTP(appPort, '/api/hello') + expect(content).toMatch(/hello world/) + }) + + it('should reply on dynamic API request successfully', async () => { + const result = await renderViaHTTP(appPort, '/api/posts/post-1') + const { post } = JSON.parse(result) + expect(post).toBe('post-1') + }) + + it('should 404 on API request with trailing slash', async () => { + const res = await fetchViaHTTP(appPort, '/api/hello/') + expect(res.status).toBe(404) + }) + + describe('With basic usage', () => { + it('should allow etag header support', async () => { + const url = `http://localhost:${appPort}/` + const etag = (await fetch(url)).headers.get('ETag') + + const headers = { 'If-None-Match': etag } + const res2 = await fetch(url, { headers }) + expect(res2.status).toBe(304) + }) + + it('should set Content-Length header', async () => { + const url = `http://localhost:${appPort}` + const res = await fetch(url) + expect(res.headers.get('Content-Length')).toBeDefined() + }) + }) +}) diff --git a/yarn.lock b/yarn.lock index ae396d990b10c..bcec23bc52b7f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -782,6 +782,177 @@ exec-sh "^0.3.2" minimist "^1.2.0" +"@firebase/app-types@0.4.3": + version "0.4.3" + resolved "https://registry.yarnpkg.com/@firebase/app-types/-/app-types-0.4.3.tgz#80d2b6e5ee43ac99892329ab02301ee7ed82da45" + integrity sha512-VU5c+ZjejvefLVH4cjiX3Hy1w9HYMv7TtZ1tF9ZmOqT4DSIU1a3VISWoo8///cGGffr5IirMO+Q/WZLI4p8VcA== + +"@firebase/app@0.4.13": + version "0.4.13" + resolved "https://registry.yarnpkg.com/@firebase/app/-/app-0.4.13.tgz#5997214002f5a56b88154566e483dc3440e3d57e" + integrity sha512-LWiIKRoik1dFsY24k3pQ6NrQyWvSt+HzJKratUHfzqDBACdxcw7+9kwFMnS4MHGc/GGFVC42rHrI0PHeRe779w== + dependencies: + "@firebase/app-types" "0.4.3" + "@firebase/logger" "0.1.21" + "@firebase/util" "0.2.24" + dom-storage "2.1.0" + tslib "1.10.0" + xmlhttprequest "1.8.0" + +"@firebase/auth-types@0.7.2": + version "0.7.2" + resolved "https://registry.yarnpkg.com/@firebase/auth-types/-/auth-types-0.7.2.tgz#6343639d422ea84feddf619e22d8db7f63b0eb62" + integrity sha512-xm3evp6671LoI+6M8Om3OhikabLf88Ivz1e7aR8uZjVBYptEYbF3seDIyHn/3wWdVYbp20WK4aWixKlRnHl+6Q== + +"@firebase/auth@0.11.7": + version "0.11.7" + resolved "https://registry.yarnpkg.com/@firebase/auth/-/auth-0.11.7.tgz#febfcbb6281db73e47446394be3d6370416af26e" + integrity sha512-qloLTfUPja0ivRvyC0FnEMif6bYPZb9DsJsV83KiBWaYMSkCeNHuA34p73JvjmgHrT571t+zFpJ3OrBH+va4ow== + dependencies: + "@firebase/auth-types" "0.7.2" + +"@firebase/database-types@0.4.2": + version "0.4.2" + resolved "https://registry.yarnpkg.com/@firebase/database-types/-/database-types-0.4.2.tgz#7bb2e605b914ad5cca7b1f4f5d8e7940fa37a708" + integrity sha512-rBF/Sp4S4zzVg+a6h0iEiXR2GdNRrvx2BR6IcvGHnSPF7XVpj9UuUWtZMJyO+vWP3zlIGDvlNRJ4qF01Y6KxGg== + +"@firebase/database@0.4.11": + version "0.4.11" + resolved "https://registry.yarnpkg.com/@firebase/database/-/database-0.4.11.tgz#671a7da8195d02b8cbcd3e0c23adbd6226d8df38" + integrity sha512-g6VcEiw1HqBbV31p0j61CleLKZQ2XEOqpv1MSuiH9YYMsbHI7uUaebj3dxIdLSdLMoWNpGYmlXva/AWkirAV8Q== + dependencies: + "@firebase/database-types" "0.4.2" + "@firebase/logger" "0.1.21" + "@firebase/util" "0.2.24" + faye-websocket "0.11.3" + tslib "1.10.0" + +"@firebase/firestore-types@1.4.4": + version "1.4.4" + resolved "https://registry.yarnpkg.com/@firebase/firestore-types/-/firestore-types-1.4.4.tgz#3051a9c163b4b76ae04544629ff5e0777e452548" + integrity sha512-kFpmzkUKfzrXkcMad+TQlMs55dWNY0q1UxGICW82EneX3Yg6HN3Nx36kYfqH+SLBFUN1ZTikN07alMp0MA9p9g== + +"@firebase/firestore@1.4.8": + version "1.4.8" + resolved "https://registry.yarnpkg.com/@firebase/firestore/-/firestore-1.4.8.tgz#a17ee01463b546a2adfb2162a0613c74d0a25208" + integrity sha512-/Ult2LpbweinNnpqGrGiMw+EAaMEy6uA71DWN868oZoUmnn/+s/DCe2J0P+On2HATqvg5WggrQRa9I0in8fFag== + dependencies: + "@firebase/firestore-types" "1.4.4" + "@firebase/logger" "0.1.21" + "@firebase/util" "0.2.24" + "@firebase/webchannel-wrapper" "0.2.23" + "@grpc/proto-loader" "^0.5.0" + grpc "1.22.2" + tslib "1.10.0" + +"@firebase/functions-types@0.3.8": + version "0.3.8" + resolved "https://registry.yarnpkg.com/@firebase/functions-types/-/functions-types-0.3.8.tgz#c01f670bbca04365e680d048b0fe5770a946f643" + integrity sha512-9hajHxA4UWVCGFmoL8PBYHpamE3JTNjObieMmnvZw3cMRTP2EwipMpzZi+GPbMlA/9swF9yHCY/XFAEkwbvdgQ== + +"@firebase/functions@0.4.14": + version "0.4.14" + resolved "https://registry.yarnpkg.com/@firebase/functions/-/functions-0.4.14.tgz#c222086222ec072e0c9c6602500d6d2435b09355" + integrity sha512-rWYWIp2NIRfNGREkSEhu9fD7WsqkUARnonn7+g+DOCxlf23AkwwDwp6q9cnSia7iJ9kmkiz4hyQVI0vB1QlV5A== + dependencies: + "@firebase/functions-types" "0.3.8" + "@firebase/messaging-types" "0.3.2" + isomorphic-fetch "2.2.1" + tslib "1.10.0" + +"@firebase/installations-types@0.1.2": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@firebase/installations-types/-/installations-types-0.1.2.tgz#ac2a912e078282fd270b03b571b4639ed88d871a" + integrity sha512-fQaWIW8hyX1XUN7+FCSPjvM1agFjGidVuF4Sxi7aFwfyh5t+4fD2VpM4wCQbWmodnx4fZLvsuQd9mkxxU+lGYQ== + +"@firebase/installations@0.2.3": + version "0.2.3" + resolved "https://registry.yarnpkg.com/@firebase/installations/-/installations-0.2.3.tgz#d0203a7e3dac00a5d57f9b25a2ab4ba082bc8851" + integrity sha512-HhHMn1xvyqBCvw8HmjZ5w856BQ0+xX4tKe/48k+dyKUzzSjwrFjILWTDV2GIHZcVyMHuSS3/bX9ehIBULB5yAA== + dependencies: + "@firebase/installations-types" "0.1.2" + "@firebase/util" "0.2.24" + idb "3.0.2" + tslib "1.10.0" + +"@firebase/logger@0.1.21": + version "0.1.21" + resolved "https://registry.yarnpkg.com/@firebase/logger/-/logger-0.1.21.tgz#4918944ae01561afa8801f2bc4fc609351418007" + integrity sha512-O4aIK1wkMpczqnDSwzDaEcQ8a5puVU4Bpt+16PfenicsBSrIR+gKq44crPM3nv/LURWtDpUVSYGoqhKPeodPAg== + +"@firebase/messaging-types@0.3.2": + version "0.3.2" + resolved "https://registry.yarnpkg.com/@firebase/messaging-types/-/messaging-types-0.3.2.tgz#cf802617c161434a02fe029290a79f422821d12f" + integrity sha512-2qa2qNKqpalmtwaUV3+wQqfCm5myP/dViIBv+pXF8HinemIfO1IPQtr9pCNfsSYyus78qEhtfldnPWXxUH5v0w== + +"@firebase/messaging@0.4.7": + version "0.4.7" + resolved "https://registry.yarnpkg.com/@firebase/messaging/-/messaging-0.4.7.tgz#d55d63b9f48c04b6c380ff4fafd2461597961e9a" + integrity sha512-Kzx64ELqOhEniyKawyCmDiQo8tX+wiF7Jsk5kp7moh7090dOPb8p8snkq770UFwUZjhouVrl8tOKzD3SInVIFA== + dependencies: + "@firebase/messaging-types" "0.3.2" + "@firebase/util" "0.2.24" + tslib "1.10.0" + +"@firebase/performance-types@0.0.3": + version "0.0.3" + resolved "https://registry.yarnpkg.com/@firebase/performance-types/-/performance-types-0.0.3.tgz#bdd37975cd5f12a55d3951f4942c3fa2661b354f" + integrity sha512-RuC63nYJPJU65AsrNMc3fTRcRgHiyNcQLh9ufeKUT1mEsFgpxr167gMb+tpzNU4jsbvM6+c6nQAFdHpqcGkRlQ== + +"@firebase/performance@0.2.14": + version "0.2.14" + resolved "https://registry.yarnpkg.com/@firebase/performance/-/performance-0.2.14.tgz#a868dc9f50bcfe55a091ee30aea50f7674fa2357" + integrity sha512-WNhJkVEq9q6OazUldzeRcESmGl0W2kw82CfUII/uPATdMvF5wXvda60BN0zwquRVSdLTt7qVRQA/8wLQYnX/Kw== + dependencies: + "@firebase/installations" "0.2.3" + "@firebase/logger" "0.1.21" + "@firebase/performance-types" "0.0.3" + "@firebase/util" "0.2.24" + tslib "1.10.0" + +"@firebase/polyfill@0.3.18": + version "0.3.18" + resolved "https://registry.yarnpkg.com/@firebase/polyfill/-/polyfill-0.3.18.tgz#cb064aa19774c4d2b9bfc82450786957a65d60ae" + integrity sha512-Erp0vuFYMS8BlQzuAWR6zf10rxDT4GHRGJypxoW7arU4J61KIb6CPmrO9tVtf/rVEZuUXsDO65etDEFA8elCYA== + dependencies: + core-js "3.1.4" + promise-polyfill "8.1.3" + whatwg-fetch "2.0.4" + +"@firebase/storage-types@0.3.3": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@firebase/storage-types/-/storage-types-0.3.3.tgz#179ad38485d450023406cf9731560d690ef39d19" + integrity sha512-fUp4kpbxwDiWs/aIBJqBvXgFHZvgoND2JA0gJYSEsXtWtVwfgzY/710plErgZDeQKopX5eOR1sHskZkQUy0U6w== + +"@firebase/storage@0.3.8": + version "0.3.8" + resolved "https://registry.yarnpkg.com/@firebase/storage/-/storage-0.3.8.tgz#1422fe583c57a712d03a155d2ce6bef8526e7c33" + integrity sha512-u/JHEkoIPKkRigHhcHcmHq6Ymu27Iyei6SqDFPm17vfC85jDetdg6aO9K+UxbtdDICa60P86UguqDHTMLVwKIg== + dependencies: + "@firebase/storage-types" "0.3.3" + "@firebase/util" "0.2.24" + tslib "1.10.0" + +"@firebase/util@0.2.24": + version "0.2.24" + resolved "https://registry.yarnpkg.com/@firebase/util/-/util-0.2.24.tgz#5ccb7888f3dacf911c1c6ec51b68a17dea5c9b74" + integrity sha512-XFBNxfkMajl2zSUdcCQ3H32IN9JSM7Dacv8RK72DKoFV8Zn8dx4iZvtx8RB/VTFpXfcl435A0RzXqkLfSSEK/A== + dependencies: + tslib "1.10.0" + +"@firebase/webchannel-wrapper@0.2.23": + version "0.2.23" + resolved "https://registry.yarnpkg.com/@firebase/webchannel-wrapper/-/webchannel-wrapper-0.2.23.tgz#a0df05b210ff03c65ecb3589390095631b95e1f8" + integrity sha512-BJqOF51sPQjmRoX+WFMbZ5mhuy53JrFN0t1KY+HffcvDRb+82+vkFatKnwG3wTCKV183vJW5tGQIytb4T8pUBg== + +"@grpc/proto-loader@^0.5.0": + version "0.5.1" + resolved "https://registry.yarnpkg.com/@grpc/proto-loader/-/proto-loader-0.5.1.tgz#48492b53cdda353110b51a4b02f465974729c76f" + integrity sha512-3y0FhacYAwWvyXshH18eDkUI40wT/uGio7MAegzY8lO5+wVsc19+1A7T0pPptae4kl7bdITL+0cHpnAPmryBjQ== + dependencies: + lodash.camelcase "^4.3.0" + protobufjs "^6.8.6" + "@jest/console@^24.7.1": version "24.7.1" resolved "https://registry.yarnpkg.com/@jest/console/-/console-24.7.1.tgz#32a9e42535a97aedfe037e725bd67e954b459545" @@ -1708,6 +1879,59 @@ universal-user-agent "^2.0.0" url-template "^2.0.8" +"@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" + integrity sha1-m4sMxmPWaafY9vXQiToU00jzD78= + +"@protobufjs/base64@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735" + integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg== + +"@protobufjs/codegen@^2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb" + integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg== + +"@protobufjs/eventemitter@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70" + integrity sha1-NVy8mLr61ZePntCV85diHx0Ga3A= + +"@protobufjs/fetch@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45" + integrity sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU= + dependencies: + "@protobufjs/aspromise" "^1.1.1" + "@protobufjs/inquire" "^1.1.0" + +"@protobufjs/float@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1" + integrity sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E= + +"@protobufjs/inquire@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089" + integrity sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik= + +"@protobufjs/path@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d" + integrity sha1-bMKyDFya1q0NzP0hynZz2Nf79o0= + +"@protobufjs/pool@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54" + integrity sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q= + +"@protobufjs/utf8@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" + integrity sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA= + "@samverschueren/stream-to-observable@^0.3.0": version "0.3.0" resolved "https://registry.yarnpkg.com/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz#ecdf48d532c58ea477acfcab80348424f8d0662f" @@ -1936,6 +2160,11 @@ "@types/node" "*" "@types/webpack" "*" +"@types/long@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.0.tgz#719551d2352d301ac8b81db732acb6bdc28dbdef" + integrity sha512-1w52Nyx4Gq47uuu0EVcsHBxZFJgurQ+rTKS3qMHxR1GY2T8c2AJYd6vZoZ9q1rupaDjU0yT+Jc2XTyXkjeMA+Q== + "@types/mime@*": version "2.0.1" resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.1.tgz#dc488842312a7f075149312905b5e3c0b054c79d" @@ -1979,6 +2208,11 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-12.0.2.tgz#3452a24edf9fea138b48fad4a0a028a683da1e40" integrity sha512-5tabW/i+9mhrfEOUcLDu2xBPsHJ+X5Orqy9FKpale3SjDA17j5AEpYq5vfy3oAeAHGcvANRCO3NV3d2D6q3NiA== +"@types/node@^10.1.0": + version "10.14.14" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.14.tgz#a47955df2acf76ba7f0ac3b205d325da193dc9ad" + integrity sha512-xXD08vZsvpv4xptQXj1+ky22f7ZoKu5ZNI/4l+/BXG3X+XaeZsmaFbbTKuhSE3NjjvRuZFxFf9sQBMXIcZNFMQ== + "@types/node@^12.6.8": version "12.6.8" resolved "https://registry.yarnpkg.com/@types/node/-/node-12.6.8.tgz#e469b4bf9d1c9832aee4907ba8a051494357c12c" @@ -2769,6 +3003,14 @@ asap@^2.0.0, asap@~2.0.3: resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= +ascli@~1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ascli/-/ascli-1.0.1.tgz#bcfa5974a62f18e81cabaeb49732ab4a88f906bc" + integrity sha1-vPpZdKYvGOgcq660lzKrSoj5Brw= + dependencies: + colour "~0.7.1" + optjs "~3.2.2" + asn1.js@^4.0.0: version "4.10.1" resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" @@ -3330,6 +3572,13 @@ 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== +bytebuffer@~5: + version "5.0.1" + resolved "https://registry.yarnpkg.com/bytebuffer/-/bytebuffer-5.0.1.tgz#582eea4b1a873b6d020a48d58df85f0bba6cfddd" + integrity sha1-WC7qSxqHO20CCkjVjfhfC7ps/d0= + dependencies: + long "~3" + bytes@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" @@ -3480,7 +3729,7 @@ camelcase@5.0.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.0.0.tgz#03295527d58bd3cd4aa75363f35b2e8d97be2f42" integrity sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA== -camelcase@^2.0.0: +camelcase@^2.0.0, camelcase@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" integrity sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8= @@ -3771,7 +4020,7 @@ cli-width@^2.0.0: resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk= -cliui@^3.2.0: +cliui@^3.0.3, cliui@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" integrity sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0= @@ -3904,6 +4153,11 @@ colors@1.1.2: resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" integrity sha1-FopHAXVran9RoSzgyXv6KMCE7WM= +colour@~0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/colour/-/colour-0.7.1.tgz#9cb169917ec5d12c0736d3e8685746df1cadf778" + integrity sha1-nLFpkX7F0SwHNtPoaFdG3xyt93g= + columnify@^1.5.4: version "1.5.4" resolved "https://registry.yarnpkg.com/columnify/-/columnify-1.5.4.tgz#4737ddf1c7b69a8a7c340570782e947eec8e78bb" @@ -4207,6 +4461,11 @@ core-js-pure@3.1.2: resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.1.2.tgz#62fc435f35b7374b9b782013cdcb2f97e9f6dffa" integrity sha512-5ckIdBF26B3ldK9PM177y2ZcATP2oweam9RskHSoqfZCrJ2As6wVg8zJ1zTriFsZf6clj/N1ThDFRGaomMsh9w== +core-js@3.1.4: + version "3.1.4" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.1.4.tgz#3a2837fc48e582e1ae25907afcd6cf03b0cc7a07" + integrity sha512-YNZN8lt82XIMLnLirj9MhKDFZHalwzzrL9YLt6eb0T5D0EDl4IQ90IGkua8mHbnxNrkj1d8hbdizMc0Qmg1WnQ== + core-js@^2.4.0, core-js@^2.6.5: version "2.6.8" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.8.tgz#dc3a1e633a04267944e0cb850d3880f340248139" @@ -4951,6 +5210,11 @@ dom-serializer@0, dom-serializer@~0.1.0: domelementtype "^1.3.0" entities "^1.1.1" +dom-storage@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/dom-storage/-/dom-storage-2.1.0.tgz#00fb868bc9201357ea243c7bcfd3304c1e34ea39" + integrity sha512-g6RpyWXzl0RR6OTElHKBl7nwnK87GUyZMYC7JWsB/IA73vpqK2K6LT39x4VepLxlSsWBFrPVLnsSR5Jyty0+2Q== + domain-browser@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" @@ -5783,6 +6047,13 @@ faunadb@2.6.1: superagent "^3.8.1" util-deprecate "^1.0.2" +faye-websocket@0.11.3: + version "0.11.3" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.3.tgz#5c0e9a8968e8912c286639fde977a8b209f2508e" + integrity sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA== + dependencies: + websocket-driver ">=0.5.1" + fb-watchman@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.0.tgz#54e9abf7dfa2f26cd9b1636c588c1afc05de5d58" @@ -5953,6 +6224,24 @@ find-up@^3.0.0: dependencies: locate-path "^3.0.0" +firebase@6.3.4: + version "6.3.4" + resolved "https://registry.yarnpkg.com/firebase/-/firebase-6.3.4.tgz#a96301d5308871a9afe8b06195fac967e893778d" + integrity sha512-UvLCXApdrhYZkGl1N/4dPPFVa3zFd+K963guaP9ckQhagch66Hv1xLwL8urmlBAGk9UZECMAk8f7YcLD217HkA== + dependencies: + "@firebase/app" "0.4.13" + "@firebase/app-types" "0.4.3" + "@firebase/auth" "0.11.7" + "@firebase/database" "0.4.11" + "@firebase/firestore" "1.4.8" + "@firebase/functions" "0.4.14" + "@firebase/installations" "0.2.3" + "@firebase/messaging" "0.4.7" + "@firebase/performance" "0.2.14" + "@firebase/polyfill" "0.3.18" + "@firebase/storage" "0.3.8" + "@firebase/util" "0.2.24" + flat-cache@^1.2.1: version "1.3.4" resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.4.tgz#2c2ef77525cc2929007dfffa1dd314aa9c9dee6f" @@ -6580,6 +6869,17 @@ growly@^1.3.0: resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE= +grpc@1.22.2: + version "1.22.2" + resolved "https://registry.yarnpkg.com/grpc/-/grpc-1.22.2.tgz#1a60c728c692a93a85e855e35c2e0216654f0198" + integrity sha512-gaK59oAA5/mlOIn+hQO5JROPoAzsaGRpEMcrAayW5WGETS8QScpBoQ+XBxEWAAF0kbeGIELuGRCVEObKS1SLmw== + dependencies: + lodash.camelcase "^4.3.0" + lodash.clone "^4.5.0" + nan "^2.13.2" + node-pre-gyp "^0.13.0" + protobufjs "^5.0.3" + gulp-mocha@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/gulp-mocha/-/gulp-mocha-6.0.0.tgz#80f32bc705ce30747f355ddb8ccd96a1c73bef13" @@ -6850,6 +7150,11 @@ http-errors@~1.6.2: setprototypeof "1.1.0" statuses ">= 1.4.0 < 2" +"http-parser-js@>=0.4.0 <0.4.11": + version "0.4.10" + resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.4.10.tgz#92c9c1374c35085f75db359ec56cc257cbb93fa4" + integrity sha1-ksnBN0w1CF912zWexWzCV8u5P6Q= + 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" @@ -6906,6 +7211,11 @@ icss-utils@^2.1.0: dependencies: postcss "^6.0.1" +idb@3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/idb/-/idb-3.0.2.tgz#c8e9122d5ddd40f13b60ae665e4862f8b13fa384" + integrity sha512-+FLa/0sTXqyux0o6C+i2lOR0VoS60LU/jzUo5xjfY6+7sEEgy4Gz1O7yFBXvjd7N0NyIGWIRg8DcQSLEG+VSPw== + ieee754@^1.1.4: version "1.1.13" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" @@ -7503,7 +7813,7 @@ is-ssh@^1.3.0: dependencies: protocols "^1.1.0" -is-stream@^1.0.0, is-stream@^1.1.0: +is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= @@ -7622,6 +7932,14 @@ isobject@^4.0.0: resolved "https://registry.yarnpkg.com/isobject/-/isobject-4.0.0.tgz#3f1c9155e73b192022a80819bacd0343711697b0" integrity sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA== +isomorphic-fetch@2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9" + integrity sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk= + dependencies: + node-fetch "^1.0.1" + whatwg-fetch ">=0.10.0" + isomorphic-unfetch@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/isomorphic-unfetch/-/isomorphic-unfetch-3.0.0.tgz#de6d80abde487b17de2c400a7ef9e5ecc2efb362" @@ -8529,6 +8847,11 @@ lodash.camelcase@^4.3.0: resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY= +lodash.clone@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clone/-/lodash.clone-4.5.0.tgz#195870450f5a13192478df4bc3d23d2dea1907b6" + integrity sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y= + lodash.clonedeep@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" @@ -8697,6 +9020,16 @@ lolex@1.3.2: resolved "https://registry.yarnpkg.com/lolex/-/lolex-1.3.2.tgz#7c3da62ffcb30f0f5a80a2566ca24e45d8a01f31" integrity sha1-fD2mL/yzDw9agKJWbKJORdigHzE= +long@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" + integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== + +long@~3: + version "3.2.0" + resolved "https://registry.yarnpkg.com/long/-/long-3.2.0.tgz#d821b7138ca1cb581c172990ef14db200b5c474b" + integrity sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s= + loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" @@ -9339,6 +9672,14 @@ node-fetch@2.6.0, node-fetch@^2.1.1, node-fetch@^2.2.0, node-fetch@^2.3.0: resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd" integrity sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA== +node-fetch@^1.0.1: + version "1.7.3" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" + integrity sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ== + dependencies: + encoding "^0.1.11" + is-stream "^1.0.1" + node-gyp@^3.8.0: version "3.8.0" resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-3.8.0.tgz#540304261c330e80d0d5edce253a68cb3964218c" @@ -9440,6 +9781,22 @@ node-pre-gyp@^0.12.0: semver "^5.3.0" tar "^4" +node-pre-gyp@^0.13.0: + version "0.13.0" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.13.0.tgz#df9ab7b68dd6498137717838e4f92a33fc9daa42" + integrity sha512-Md1D3xnEne8b/HGVQkZZwV27WUi1ZRuZBij24TNaZwUPU3ZAFtvT6xxJGaUVillfmMKnn5oD1HoGsp2Ftik7SQ== + 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" + node-releases@^1.1.19: version "1.1.21" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.21.tgz#46c86f9adaceae4d63c75d3c2f2e6eee618e55f3" @@ -9819,6 +10176,11 @@ optionator@^0.8.1, optionator@^0.8.2: type-check "~0.3.2" wordwrap "~1.0.0" +optjs@~3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/optjs/-/optjs-3.2.2.tgz#69a6ce89c442a44403141ad2f9b370bd5bb6f4ee" + integrity sha1-aabOicRCpEQDFBrS+bNwvVu29O4= + ora@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ora/-/ora-2.0.0.tgz#8ec3a37fa7bffb54a3a0c188a1f6798e7e1827cd" @@ -10825,6 +11187,11 @@ promise-inflight@^1.0.1: resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= +promise-polyfill@8.1.3: + version "8.1.3" + resolved "https://registry.yarnpkg.com/promise-polyfill/-/promise-polyfill-8.1.3.tgz#8c99b3cf53f3a91c68226ffde7bde81d7f904116" + integrity sha512-MG5r82wBzh7pSKDRa9y+vllNHz3e3d4CNj1PQE4BQYxLme0gKYYBm9YENq+UkEikyZ0XbiGWxYlVw3Rl9O/U8g== + promise-polyfill@^6.0.1: version "6.1.0" resolved "https://registry.yarnpkg.com/promise-polyfill/-/promise-polyfill-6.1.0.tgz#dfa96943ea9c121fca4de9b5868cb39d3472e057" @@ -10893,6 +11260,35 @@ proto-list@~1.2.1: resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" integrity sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk= +protobufjs@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-5.0.3.tgz#e4dfe9fb67c90b2630d15868249bcc4961467a17" + integrity sha512-55Kcx1MhPZX0zTbVosMQEO5R6/rikNXd9b6RQK4KSPcrSIIwoXTtebIczUrXlwaSrbz4x8XUVThGPob1n8I4QA== + dependencies: + ascli "~1" + bytebuffer "~5" + glob "^7.0.5" + yargs "^3.10.0" + +protobufjs@^6.8.6: + version "6.8.8" + resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.8.8.tgz#c8b4f1282fd7a90e6f5b109ed11c84af82908e7c" + integrity sha512-AAmHtD5pXgZfi7GMpllpO3q1Xw1OYldr+dMUlAnffGTAhqkg72WdmSY71uKBF/JuyiKs8psYbtKrhi0ASCD8qw== + dependencies: + "@protobufjs/aspromise" "^1.1.2" + "@protobufjs/base64" "^1.1.2" + "@protobufjs/codegen" "^2.0.4" + "@protobufjs/eventemitter" "^1.1.0" + "@protobufjs/fetch" "^1.1.0" + "@protobufjs/float" "^1.0.2" + "@protobufjs/inquire" "^1.1.0" + "@protobufjs/path" "^1.1.2" + "@protobufjs/pool" "^1.1.0" + "@protobufjs/utf8" "^1.1.0" + "@types/long" "^4.0.0" + "@types/node" "^10.1.0" + long "^4.0.0" + protocols@^1.1.0, protocols@^1.4.0: version "1.4.7" resolved "https://registry.yarnpkg.com/protocols/-/protocols-1.4.7.tgz#95f788a4f0e979b291ffefcf5636ad113d037d32" @@ -11781,6 +12177,11 @@ safe-buffer@5.1.2, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, s resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== +safe-buffer@>=5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" + integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== + safe-regex@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" @@ -13142,6 +13543,11 @@ tryer@^1.0.0: resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8" integrity sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA== +tslib@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" + integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== + tslib@^1.9.0: version "1.9.3" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" @@ -13785,6 +14191,20 @@ webpack@4.39.0: watchpack "^1.6.0" webpack-sources "^1.4.1" +websocket-driver@>=0.5.1: + version "0.7.3" + resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.3.tgz#a2d4e0d4f4f116f1e6297eba58b05d430100e9f9" + integrity sha512-bpxWlvbbB459Mlipc5GBzzZwhoZgGEZLuqPaR0INBGnPAY1vdBX6hPnoFXiw+3yWxDuHyQjO2oXTMyS8A5haFg== + dependencies: + http-parser-js ">=0.4.0 <0.4.11" + safe-buffer ">=5.1.0" + websocket-extensions ">=0.1.1" + +websocket-extensions@>=0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.3.tgz#5d2ff22977003ec687a4b87073dfbbac146ccf29" + integrity sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg== + whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3: version "1.0.5" resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" @@ -13792,6 +14212,16 @@ whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3: dependencies: iconv-lite "0.4.24" +whatwg-fetch@2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz#dde6a5df315f9d39991aa17621853d720b85566f" + integrity sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng== + +whatwg-fetch@>=0.10.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz#fc804e458cc460009b1a2b966bc8817d2578aefb" + integrity sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q== + whatwg-mimetype@^2.1.0, whatwg-mimetype@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" @@ -13846,6 +14276,11 @@ wide-align@^1.1.0: dependencies: string-width "^1.0.2 || 2" +window-size@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.4.tgz#f8e1aa1ee5a53ec5bf151ffa09742a6ad7697876" + integrity sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY= + windows-release@^3.1.0: version "3.2.0" resolved "https://registry.yarnpkg.com/windows-release/-/windows-release-3.2.0.tgz#8122dad5afc303d833422380680a79cdfa91785f" @@ -13984,6 +14419,11 @@ xml@^1.0.1: resolved "https://registry.yarnpkg.com/xml/-/xml-1.0.1.tgz#78ba72020029c5bc87b8a81a3cfcd74b4a2fc1e5" integrity sha1-eLpyAgApxbyHuKgaPPzXS0ovweU= +xmlhttprequest@1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz#67fe075c5c24fef39f9d65f5f7b7fe75171968fc" + integrity sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw= + xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" @@ -13996,7 +14436,7 @@ xtend@~2.1.1: dependencies: object-keys "~0.4.0" -y18n@^3.2.1: +y18n@^3.2.0, y18n@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" integrity sha1-bRX7qITAhnnA136I53WegR4H+kE= @@ -14049,6 +14489,19 @@ yargs@^12.0.1, yargs@^12.0.2: y18n "^3.2.1 || ^4.0.0" yargs-parser "^11.1.1" +yargs@^3.10.0: + version "3.32.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.32.0.tgz#03088e9ebf9e756b69751611d2a5ef591482c995" + integrity sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU= + dependencies: + camelcase "^2.0.1" + cliui "^3.0.3" + decamelize "^1.1.1" + os-locale "^1.4.0" + string-width "^1.0.1" + window-size "^0.1.4" + y18n "^3.2.0" + yargs@^7.0.0: version "7.1.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-7.1.0.tgz#6ba318eb16961727f5d284f8ea003e8d6154d0c8"