From 57012a7da8d05da5db7dabae8620baba1c038aea Mon Sep 17 00:00:00 2001 From: Evan Wallace Date: Mon, 7 Dec 2020 18:23:29 -0800 Subject: [PATCH] fix #527: enable the build API in the browser --- CHANGELOG.md | 4 + Makefile | 18 +- lib/browser.ts | 17 +- lib/common.ts | 9 +- lib/node.ts | 2 + scripts/browser/browser-tests.js | 236 ++++++++++++++++++ scripts/browser/package-lock.json | 400 ++++++++++++++++++++++++++++++ scripts/browser/package.json | 5 + 8 files changed, 678 insertions(+), 13 deletions(-) create mode 100644 scripts/browser/browser-tests.js create mode 100644 scripts/browser/package-lock.json create mode 100644 scripts/browser/package.json diff --git a/CHANGELOG.md b/CHANGELOG.md index c13b6b4a40f..9f8dd5cded2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ To avoid making this a breaking change, there is now special behavior for entry point path resolution. If the entry point path exists relative to the current working directory and the path does not start with `./` or `../`, esbuild will now automatically insert a leading `./` at the start of the path to prevent the path from being interpreted as a `node_modules` package path. This is only done if the file actually exists to avoid introducing `./` for paths with special plugin-specific syntax. +* Enable the build API in the browser ([#527](https://github.com/evanw/esbuild/issues/527)) + + Previously you could only use the transform API in the browser, not the build API. You can now use the build API in the browser too. There is currently no in-browser file system so the build API will not do anything by default. Using this API requires you to use plugins to provide your own file system. Instructions for running esbuild in the browser can be found here: https://esbuild.github.io/api/#running-in-the-browser. + ## 0.8.20 * Fix an edge case with class body initialization diff --git a/Makefile b/Makefile index 1361461ee3e..c8c43463a2e 100644 --- a/Makefile +++ b/Makefile @@ -7,13 +7,15 @@ npm/esbuild-wasm/esbuild.wasm: cmd/esbuild/version.go cmd/esbuild/*.go pkg/*/*.g cp "$(shell go env GOROOT)/misc/wasm/wasm_exec.js" npm/esbuild-wasm/wasm_exec.js GOOS=js GOARCH=wasm go build -o npm/esbuild-wasm/esbuild.wasm ./cmd/esbuild -# These tests are for development test: - make -j6 test-go vet-go verify-source-map end-to-end-tests js-api-tests plugin-tests ts-type-tests + make -j6 test-common + +# These tests are for development +test-common: test-go vet-go verify-source-map end-to-end-tests js-api-tests plugin-tests -# These tests are for release ("test-wasm" is not included in "test" because it's pretty slow) +# These tests are for release (the extra tests are not included in "test" because they are pretty slow) test-all: - make -j7 test-go vet-go verify-source-map end-to-end-tests js-api-tests plugin-tests ts-type-tests test-wasm + make -j6 test-common ts-type-tests test-wasm-node test-wasm-browser # This includes tests of some 3rd-party libraries, which can be very slow test-prepublish: check-go-version test-all test-preact-splitting test-sucrase bench-rome-esbuild test-esprima test-rollup @@ -30,10 +32,13 @@ vet-go: fmt-go: go fmt ./cmd/... ./internal/... ./pkg/... -test-wasm: platform-wasm +test-wasm-node: platform-wasm PATH="$(shell go env GOROOT)/misc/wasm:$$PATH" GOOS=js GOARCH=wasm go test ./internal/... npm/esbuild-wasm/bin/esbuild --version +test-wasm-browser: platform-wasm | scripts/browser/node_modules + cd scripts/browser && node browser-tests.js + verify-source-map: cmd/esbuild/version.go | scripts/node_modules cd npm/esbuild && npm version "$(ESBUILD_VERSION)" --allow-same-version node scripts/verify-source-map.js @@ -252,6 +257,9 @@ lib/node_modules: scripts/node_modules: cd scripts && npm ci +scripts/browser/node_modules: + cd scripts/browser && npm ci + ################################################################################ # This downloads the kangax compat-table and generates browser support mappings diff --git a/lib/browser.ts b/lib/browser.ts index ec23e4ee095..3f66fb7a3ff 100644 --- a/lib/browser.ts +++ b/lib/browser.ts @@ -28,8 +28,13 @@ export const transformSync: typeof types.transformSync = () => { export const startService: typeof types.startService = options => { if (!options) throw new Error('Must provide an options object to "startService"'); - if (!options.wasmURL) throw new Error('Must provide the "wasmURL" option'); - return fetch(options.wasmURL).then(r => r.arrayBuffer()).then(wasm => { + let wasmURL = options.wasmURL; + if (!wasmURL) throw new Error('Must provide the "wasmURL" option'); + wasmURL += ''; + return fetch(wasmURL).then(res => { + if (!res.ok) throw new Error(`Failed to download ${JSON.stringify(wasmURL)}`); + return res.arrayBuffer(); + }).then(wasm => { let code = `{` + `let global={};` + `for(let o=self;o;o=Object.getPrototypeOf(o))` + @@ -67,12 +72,14 @@ export const startService: typeof types.startService = options => { worker.postMessage(bytes) }, isSync: false, + isBrowser: true, }) return { - build() { - throw new Error(`The "build" API only works in node`) - }, + build: (options: types.BuildOptions): Promise => + new Promise((resolve, reject) => + service.buildOrServe(null, options, false, (err, res) => + err ? reject(err) : resolve(res as types.BuildResult))), transform: (input, options) => new Promise((resolve, reject) => service.transform(input, options || {}, false, { diff --git a/lib/common.ts b/lib/common.ts index 2fc1ed4f1d7..680ef8c7987 100644 --- a/lib/common.ts +++ b/lib/common.ts @@ -126,7 +126,7 @@ function pushCommonFlags(flags: string[], options: CommonOptions, keys: OptionKe if (footer) flags.push(`--footer=${footer}`); } -function flagsForBuildOptions(options: types.BuildOptions, isTTY: boolean, logLevelDefault: types.LogLevel): +function flagsForBuildOptions(options: types.BuildOptions, isTTY: boolean, logLevelDefault: types.LogLevel, writeDefault: boolean): [string[], boolean, types.Plugin[] | undefined, string | null, string | null, boolean] { let flags: string[] = []; let keys: OptionKeys = Object.create(null); @@ -153,7 +153,7 @@ function flagsForBuildOptions(options: types.BuildOptions, isTTY: boolean, logLe let inject = getFlag(options, keys, 'inject', mustBeArray); let entryPoints = getFlag(options, keys, 'entryPoints', mustBeArray); let stdin = getFlag(options, keys, 'stdin', mustBeObject); - let write = getFlag(options, keys, 'write', mustBeBoolean) !== false; // Default to true if not specified + let write = getFlag(options, keys, 'write', mustBeBoolean) ?? writeDefault; // Default to true if not specified let incremental = getFlag(options, keys, 'incremental', mustBeBoolean) === true; let plugins = getFlag(options, keys, 'plugins', mustBeArray); checkForInvalidFlags(options, keys); @@ -250,6 +250,7 @@ export interface StreamIn { writeToStdin: (data: Uint8Array) => void; readFileSync?: (path: string, encoding: 'utf8') => string; isSync: boolean; + isBrowser: boolean; } export interface StreamOut { @@ -619,7 +620,8 @@ export function createChannel(streamIn: StreamIn): StreamOut { const logLevelDefault = 'info'; try { let key = nextBuildKey++; - let [flags, write, plugins, stdin, resolveDir, incremental] = flagsForBuildOptions(options, isTTY, logLevelDefault); + let writeDefault = !streamIn.isBrowser; + let [flags, write, plugins, stdin, resolveDir, incremental] = flagsForBuildOptions(options, isTTY, logLevelDefault, writeDefault); let request: protocol.BuildRequest = { command: 'build', key, flags, write, stdin, resolveDir, incremental }; let serve = serveOptions && buildServeData(serveOptions, request); let pluginCleanup = plugins && plugins.length > 0 && handlePlugins(plugins, request, key); @@ -664,6 +666,7 @@ export function createChannel(streamIn: StreamIn): StreamOut { return callback(null, result); }; + if (write && streamIn.isBrowser) throw new Error(`Cannot enable "write" in the browser`); if (incremental && streamIn.isSync) throw new Error(`Cannot use "incremental" with a synchronous build`); sendRequest(request, (error, response) => { if (error) return callback(new Error(error), null); diff --git a/lib/node.ts b/lib/node.ts index af3b688d3ab..f48ab91f9e1 100644 --- a/lib/node.ts +++ b/lib/node.ts @@ -149,6 +149,7 @@ export let startService: typeof types.startService = options => { }, readFileSync: fs.readFileSync, isSync: false, + isBrowser: false, }); child.stdout.on('data', readFromStdout); child.stdout.on('end', afterClose); @@ -205,6 +206,7 @@ let runServiceSync = (callback: (service: common.StreamService) => void): void = stdin = bytes; }, isSync: true, + isBrowser: false, }); callback(service); let stdout = child_process.execFileSync(command, args.concat(`--service=${ESBUILD_VERSION}`), { diff --git a/scripts/browser/browser-tests.js b/scripts/browser/browser-tests.js new file mode 100644 index 00000000000..a34228a19b3 --- /dev/null +++ b/scripts/browser/browser-tests.js @@ -0,0 +1,236 @@ +const puppeteer = require('puppeteer') +const http = require('http') +const path = require('path') +const url = require('url') +const fs = require('fs') + +const js = fs.readFileSync(path.join(__dirname, '..', '..', 'npm', 'esbuild-wasm', 'lib', 'browser.js')) +const esm = fs.readFileSync(path.join(__dirname, '..', '..', 'npm', 'esbuild-wasm', 'esm', 'browser.js')) +const wasm = fs.readFileSync(path.join(__dirname, '..', '..', 'npm', 'esbuild-wasm', 'esbuild.wasm')) + +// This is converted to a string and run inside the browser +async function runAllTests({ esbuild, service }) { + const tests = { + async transformJS() { + const { code } = await service.transform('1+2') + assertStrictEqual(code, '1 + 2;\n') + }, + + async transformTS() { + const { code } = await service.transform('1 as any + 2', { loader: 'ts' }) + assertStrictEqual(code, '1 + 2;\n') + }, + + async transformCSS() { + const { code } = await service.transform('div { color: red }', { loader: 'css' }) + assertStrictEqual(code, 'div {\n color: red;\n}\n') + }, + + async buildFib() { + const fibonacciPlugin = { + name: 'fib', + setup(build) { + build.onResolve({ filter: /^fib\((\d+)\)/ }, args => { + return { path: args.path, namespace: 'fib' } + }) + build.onLoad({ filter: /^fib\((\d+)\)/, namespace: 'fib' }, args => { + let match = /^fib\((\d+)\)/.exec(args.path), n = +match[1] + let contents = n < 2 ? `export default ${n}` : ` + import n1 from 'fib(${n - 1}) ${args.path}' + import n2 from 'fib(${n - 2}) ${args.path}' + export default n1 + n2` + return { contents } + }) + }, + } + const result = await service.build({ + stdin: { + contents: ` + import x from 'fib(10)' + return x + `, + }, + format: 'cjs', + bundle: true, + plugins: [fibonacciPlugin], + }) + assertStrictEqual(result.outputFiles.length, 1) + assertStrictEqual(result.outputFiles[0].path, '') + const code = result.outputFiles[0].text + const fib10 = new Function(code)() + assertStrictEqual(fib10, 55) + }, + + async serve() { + expectThrownError(service.serve, 'The "serve" API only works in node') + }, + + async esbuildBuild() { + expectThrownError(esbuild.build, 'The "build" API only works in node') + }, + + async esbuildTransform() { + expectThrownError(esbuild.transform, 'The "transform" API only works in node') + }, + + async esbuildBuildSync() { + expectThrownError(esbuild.buildSync, 'The "buildSync" API only works in node') + }, + + async esbuildTransformSync() { + expectThrownError(esbuild.transformSync, 'The "transformSync" API only works in node') + }, + } + + function expectThrownError(fn, err) { + try { + fn() + throw new Error('Expected an error to be thrown') + } catch (e) { + assertStrictEqual(e.message, err) + } + } + + function assertStrictEqual(a, b) { + if (a !== b) { + throw new Error(`Assertion failed: + Expected: ${JSON.stringify(a)} + Observed: ${JSON.stringify(b)}`); + } + } + + async function runTest(test) { + try { + await tests[test]() + } catch (e) { + testFail(`[${test}] ` + (e && e.message || e)) + } + } + + const promises = [] + for (const test in tests) { + promises.push(runTest(test)) + } + await Promise.all(promises) +} + +let pages = { + iife: ` + + + `, + esm: ` + + `, +} + +const server = http.createServer((req, res) => { + if (req.method === 'GET' && req.url) { + if (req.url === '/lib/esbuild.js') { + res.writeHead(200, { 'Content-Type': 'application/javascript' }) + res.end(js) + return + } + + if (req.url === '/esm/esbuild.js') { + res.writeHead(200, { 'Content-Type': 'application/javascript' }) + res.end(esm) + return + } + + if (req.url === '/esbuild.wasm') { + res.writeHead(200, { 'Content-Type': 'application/wasm' }) + res.end(wasm) + return + } + + if (req.url.startsWith('/page/')) { + let key = req.url.slice('/page/'.length) + if (Object.prototype.hasOwnProperty.call(pages, key)) { + res.writeHead(200, { 'Content-Type': 'text/html' }) + res.end(` + + + ${pages[key]} + `) + return + } + } + } + + console.log(`[http] ${req.method} ${req.url}`) + res.writeHead(404) + res.end() +}) + +server.listen() +const { address, port } = server.address() +const serverURL = url.format({ protocol: 'http', hostname: address, port }) +console.log(`[http] listening on ${serverURL}`) + +async function main() { + const browser = await puppeteer.launch() + const promises = [] + let allTestsPassed = true + + async function runPage(key) { + try { + const page = await browser.newPage() + page.on('console', obj => console.log(`[console.${obj.type()}] ${obj.text()}`)) + page.exposeFunction('testFail', error => { + console.log(`❌ ${error}`) + allTestsPassed = false + }) + let testDone = new Promise(resolve => { + page.exposeFunction('testDone', resolve) + }) + await page.goto(`${serverURL}/page/${key}`, { waitUntil: 'domcontentloaded' }) + await page.evaluate('testStart()') + await testDone + await page.close() + } catch (e) { + allTestsPassed = false + console.log(`❌ ${key}: ${e && e.message || e}`) + } + } + + for (let key in pages) { + promises.push(runPage(key)) + } + + await Promise.all(promises) + await browser.close() + server.close() + + if (!allTestsPassed) { + console.error(`❌ browser test failed`) + process.exit(1) + } else { + console.log(`✅ browser test passed`) + } +} + +main().catch(error => setTimeout(() => { throw error })) diff --git a/scripts/browser/package-lock.json b/scripts/browser/package-lock.json new file mode 100644 index 00000000000..2bc06aa4dd7 --- /dev/null +++ b/scripts/browser/package-lock.json @@ -0,0 +1,400 @@ +{ + "requires": true, + "lockfileVersion": 1, + "dependencies": { + "@types/node": { + "version": "14.14.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.10.tgz", + "integrity": "sha512-J32dgx2hw8vXrSbu4ZlVhn1Nm3GbeCFNw2FWL8S5QKucHGY0cyNwjdQdO+KMBZ4wpmC7KhLCiNsdk1RFRIYUQQ==", + "optional": true + }, + "@types/yauzl": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.1.tgz", + "integrity": "sha512-A1b8SU4D10uoPjwb0lnHmmu8wZhR9d+9o2PKBQT2jU5YPTKsxac6M2qGAdY7VcL+dHHhARVUDmeg0rOrcd9EjA==", + "optional": true, + "requires": { + "@types/node": "*" + } + }, + "agent-base": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-5.1.1.tgz", + "integrity": "sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g==" + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "bl": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz", + "integrity": "sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg==", + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=" + }, + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "requires": { + "ms": "2.1.2" + } + }, + "devtools-protocol": { + "version": "0.0.818844", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.818844.tgz", + "integrity": "sha512-AD1hi7iVJ8OD0aMLQU5VK0XH9LDlA1+BcPIgrAxPfaibx2DbWucuyOhc4oyQCbnvDDO68nN6/LcKfqTP343Jjg==" + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "requires": { + "once": "^1.4.0" + } + }, + "extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "requires": { + "@types/yauzl": "^2.9.1", + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + } + }, + "fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "requires": { + "pend": "~1.2.0" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "requires": { + "pump": "^3.0.0" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "https-proxy-agent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz", + "integrity": "sha512-zoDhWrkR3of1l9QAL8/scJZyLu8j/gBkcwcaQOZh7Gyh/+uJQzGVETdgT30akuwkpL8HTRfssqI3BZuV18teDg==", + "requires": { + "agent-base": "5", + "debug": "4" + } + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=" + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "requires": { + "find-up": "^4.0.0" + } + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" + }, + "proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "puppeteer": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-5.5.0.tgz", + "integrity": "sha512-OM8ZvTXAhfgFA7wBIIGlPQzvyEETzDjeRa4mZRCRHxYL+GNH5WAuYUQdja3rpWZvkX/JKqmuVgbsxDNsDFjMEg==", + "requires": { + "debug": "^4.1.0", + "devtools-protocol": "0.0.818844", + "extract-zip": "^2.0.0", + "https-proxy-agent": "^4.0.0", + "node-fetch": "^2.6.1", + "pkg-dir": "^4.2.0", + "progress": "^2.0.1", + "proxy-from-env": "^1.0.0", + "rimraf": "^3.0.2", + "tar-fs": "^2.0.0", + "unbzip2-stream": "^1.3.3", + "ws": "^7.2.3" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "requires": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "tar-stream": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.4.tgz", + "integrity": "sha512-o3pS2zlG4gxr67GmFYBLlq+dM8gyRGUOvsrHclSkvtVtQbjV0s/+ZE8OpICbaj8clrX3tjeHngYGP7rweaBnuw==", + "requires": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + } + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + }, + "unbzip2-stream": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", + "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", + "requires": { + "buffer": "^5.2.1", + "through": "^2.3.8" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "ws": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.1.tgz", + "integrity": "sha512-pTsP8UAfhy3sk1lSk/O/s4tjD0CRwvMnzvwr4OKGX7ZvqZtUyx4KIJB5JWbkykPoc55tixMGgTNoh3k4FkNGFQ==" + }, + "yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "requires": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + } + } +} diff --git a/scripts/browser/package.json b/scripts/browser/package.json new file mode 100644 index 00000000000..7c00483d786 --- /dev/null +++ b/scripts/browser/package.json @@ -0,0 +1,5 @@ +{ + "dependencies": { + "puppeteer": "5.5.0" + } +}