From 8886e1b55f3495b3b798825274a910e5f231a74b Mon Sep 17 00:00:00 2001 From: Ryan Dahl Date: Fri, 18 May 2018 20:39:20 -0400 Subject: [PATCH] Initial support for remote imports --- Makefile | 1 + main.go | 31 +- package.json | 6 +- runtime.ts | 59 +-- test.js | 19 +- testdata/006_url_imports.ts | 3 + testdata/006_url_imports.ts.out | 2 + tsconfig.json | 2 +- url.js | 671 ++++++++++++++++++++++++++++++++ util.ts | 2 + yarn.lock | 127 +++++- 11 files changed, 874 insertions(+), 49 deletions(-) create mode 100644 testdata/006_url_imports.ts create mode 100644 testdata/006_url_imports.ts.out create mode 100644 url.js diff --git a/Makefile b/Makefile index 27ce567d23..89c32846ea 100644 --- a/Makefile +++ b/Makefile @@ -5,6 +5,7 @@ TS_FILES = \ os.ts \ runtime.ts \ timers.ts \ + url.js \ util.ts deno: assets.go msg.pb.go main.go diff --git a/main.go b/main.go index 39ba9cb87e..c54ce9c382 100644 --- a/main.go +++ b/main.go @@ -6,9 +6,11 @@ import ( "github.com/golang/protobuf/proto" "github.com/ry/v8worker2" "io/ioutil" + "net/http" "os" "path" "runtime" + "strings" "sync" "time" ) @@ -28,11 +30,34 @@ func CacheFileName(filename string, sourceCodeBuf []byte) string { return path.Join(CompileDir, cacheKey+".js") } +func IsRemotePath(filename string) bool { + return strings.HasPrefix(filename, "/$remote$/") +} + +func FetchRemoteSource(remotePath string) (buf []byte, err error) { + url := strings.Replace(remotePath, "/$remote$/", "http://", 1) + // println("FetchRemoteSource", url) + res, err := http.Get(url) + if err != nil { + return + } + buf, err = ioutil.ReadAll(res.Body) + //println("FetchRemoteSource", err.Error()) + res.Body.Close() + return +} + func HandleSourceCodeFetch(filename string) []byte { res := &Msg{} - sourceCodeBuf, err := Asset("dist/" + filename) - if err != nil { - sourceCodeBuf, err = ioutil.ReadFile(filename) + var sourceCodeBuf []byte + var err error + if IsRemotePath(filename) { + sourceCodeBuf, err = FetchRemoteSource(filename) + } else { + sourceCodeBuf, err = Asset("dist/" + filename) + if err != nil { + sourceCodeBuf, err = ioutil.ReadFile(filename) + } } if err != nil { res.Error = err.Error() diff --git a/package.json b/package.json index 48593c59fb..60bdc8a053 100644 --- a/package.json +++ b/package.json @@ -5,11 +5,11 @@ "fmt": "prettier --write *.ts* *.js *.json" }, "devDependencies": { - "@types/text-encoding": "^0.0.32", + "http-server": "^0.11.1", "parcel-bundler": "^1.8.1", "protobufjs": "^6.8.6", - "text-encoding": "^0.6.4", "tslint": "^5.10.0", "typescript": "^2.8.3" - } + }, + "dependencies": {} } diff --git a/runtime.ts b/runtime.ts index b805259ca0..f3fb6765b5 100644 --- a/runtime.ts +++ b/runtime.ts @@ -9,6 +9,7 @@ import * as path from "path"; import * as util from "./util"; import { log } from "./util"; import * as os from "./os"; +import "./url"; const EOL = "\n"; @@ -26,8 +27,6 @@ export class FileModule { private constructor(readonly fileName: string) { FileModule.map.set(fileName, this); - assertValidFileName(this.fileName); - // Load typescript code (sourceCode) and maybe load compiled javascript // (outputCode) from cache. If cache is empty, outputCode will be null. const { sourceCode, outputCode } = os.sourceCodeFetch(this.fileName); @@ -49,7 +48,6 @@ export class FileModule { } static load(fileName: string): FileModule { - assertValidFileName(fileName); let m = this.map.get(fileName); if (m == null) { m = new this(fileName); @@ -70,12 +68,6 @@ export class FileModule { } } -function assertValidFileName(fileName: string): void { - if (fileName !== "lib.d.ts") { - util.assert(fileName[0] === "/", `fileName must be absolute: ${fileName}`); - } -} - // tslint:disable-next-line:no-any type AmdFactory = (...args: any[]) => undefined | object; type AmdDefine = (deps: string[], factory: AmdFactory) => void; @@ -94,8 +86,8 @@ export function makeDefine(fileName: string): AmdDefine { } else if (dep === "exports") { return localExports; } else { - dep = resolveModuleName(dep, fileName); - const depModule = FileModule.load(dep); + const resolved = resolveModuleName(dep, fileName); + const depModule = FileModule.load(resolved); depModule.compileAndRun(); return depModule.exports; } @@ -105,8 +97,26 @@ export function makeDefine(fileName: string): AmdDefine { return localDefine; } -function resolveModuleName(fileName: string, contextFileName: string): string { - return path.resolve(path.dirname(contextFileName), fileName); +function resolveModuleName(moduleName: string, containingFile: string): string { + if (isUrl(moduleName)) { + // Remove the "http://" from the start of the string. + const u = new URL(moduleName); + const withoutProtocol = u.toString().replace(u.protocol + "//", ""); + const name2 = "/$remote$/" + withoutProtocol; + return name2; + } else if (moduleName.startsWith("/")) { + throw Error("Absolute paths not supported"); + } else { + // Relative import. + const containingDir = path.dirname(containingFile); + const resolvedFileName = path.join(containingDir, moduleName); + util.log("relative import", { + containingFile, + moduleName, + resolvedFileName + }); + return resolvedFileName; + } } function execute(fileName: string, outputCode: string): void { @@ -231,24 +241,19 @@ class TypeScriptHost implements ts.LanguageServiceHost { ): Array { util.log("resolveModuleNames", { moduleNames, reusedNames }); return moduleNames.map((name: string) => { - if ( - name.startsWith("/") || - name.startsWith("http://") || - name.startsWith("https://") - ) { - throw Error("Non-relative imports not yet supported."); - } else { - // Relative import. - const containingDir = path.dirname(containingFile); - const resolvedFileName = path.join(containingDir, name); - util.log("relative import", { containingFile, name, resolvedFileName }); - const isExternalLibraryImport = false; - return { resolvedFileName, isExternalLibraryImport }; - } + const resolvedFileName = resolveModuleName(name, containingFile); + const isExternalLibraryImport = false; + return { resolvedFileName, isExternalLibraryImport }; }); } } +function isUrl(p: string): boolean { + return ( + p.startsWith("//") || p.startsWith("http://") || p.startsWith("https://") + ); +} + const formatDiagnosticsHost: ts.FormatDiagnosticsHost = { getCurrentDirectory(): string { return "."; diff --git a/test.js b/test.js index e9ae777556..36c0b58d37 100755 --- a/test.js +++ b/test.js @@ -4,7 +4,22 @@ const fs = require("fs"); const path = require("path"); -const { execFileSync } = require("child_process"); +const { spawn, execFileSync } = require("child_process"); + +// Some tests require an HTTP server. We start one here. +// Because we process tests synchronously in this program we must run +// the server as a subprocess. +// Note that "localhost:4545" is hardcoded into the tests at the moment, +// so if the server runs on a different port, it will fail. +const httpServerArgs = ["node_modules/.bin/http-server", __dirname, "-p 4545"]; +const server = spawn(process.execPath, httpServerArgs, { + cwd: __dirname, + stdio: "inherit" +}); +// TODO: For some reason the http-server doesn't exit properly +// when this program dies. So we force it with the exit handler here. +server.unref(); +process.on("exit", () => server.kill("SIGINT")); const testdataDir = path.join(__dirname, "testdata"); const denoFn = path.join(__dirname, "deno"); @@ -33,3 +48,5 @@ ${outFileBuffer.toString()} `); } } + +console.log("Tests done"); diff --git a/testdata/006_url_imports.ts b/testdata/006_url_imports.ts new file mode 100644 index 0000000000..57af683cf0 --- /dev/null +++ b/testdata/006_url_imports.ts @@ -0,0 +1,3 @@ +import { printHello } from "http://localhost:4545/testdata/subdir/print_hello.ts"; +printHello(); +console.log("success"); diff --git a/testdata/006_url_imports.ts.out b/testdata/006_url_imports.ts.out new file mode 100644 index 0000000000..989ce33e93 --- /dev/null +++ b/testdata/006_url_imports.ts.out @@ -0,0 +1,2 @@ +Hello +success diff --git a/tsconfig.json b/tsconfig.json index 71fb930b73..d598b8ce04 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -8,7 +8,7 @@ "preserveConstEnums": true, "declaration": true, "target": "es2017", - "lib": ["es2017"], + "lib": ["es2017", "DOM"], "noEmit": true, "noUnusedLocals": true, "noImplicitReturns": true, diff --git a/url.js b/url.js new file mode 100644 index 0000000000..76e32cc86f --- /dev/null +++ b/url.js @@ -0,0 +1,671 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + * Forked from https://github.com/github/url-polyfill + * Version 16c1aa Feb 9 2018. + */ + +(function(scope) { + "use strict"; + + // feature detect for URL constructor + var hasWorkingUrl = false; + if (!scope.forceJURL) { + try { + var u = new URL("b", "http://a"); + u.pathname = "c%20d"; + hasWorkingUrl = u.href === "http://a/c%20d"; + } catch (e) {} + } + + if (hasWorkingUrl) return; + + var relative = Object.create(null); + relative["ftp"] = 21; + relative["file"] = 0; + relative["gopher"] = 70; + relative["http"] = 80; + relative["https"] = 443; + relative["ws"] = 80; + relative["wss"] = 443; + + var relativePathDotMapping = Object.create(null); + relativePathDotMapping["%2e"] = "."; + relativePathDotMapping[".%2e"] = ".."; + relativePathDotMapping["%2e."] = ".."; + relativePathDotMapping["%2e%2e"] = ".."; + + function isRelativeScheme(scheme) { + return relative[scheme] !== undefined; + } + + function invalid() { + clear.call(this); + this._isInvalid = true; + } + + function IDNAToASCII(h) { + if ("" == h) { + invalid.call(this); + } + // XXX + return h.toLowerCase(); + } + + function percentEscape(c) { + var unicode = c.charCodeAt(0); + if ( + unicode > 0x20 && + unicode < 0x7f && + // " # < > ? ` + [0x22, 0x23, 0x3c, 0x3e, 0x3f, 0x60].indexOf(unicode) == -1 + ) { + return c; + } + return encodeURIComponent(c); + } + + function percentEscapeQuery(c) { + // XXX This actually needs to encode c using encoding and then + // convert the bytes one-by-one. + + var unicode = c.charCodeAt(0); + if ( + unicode > 0x20 && + unicode < 0x7f && + // " # < > ` (do not escape '?') + [0x22, 0x23, 0x3c, 0x3e, 0x60].indexOf(unicode) == -1 + ) { + return c; + } + return encodeURIComponent(c); + } + + var EOF = undefined, + ALPHA = /[a-zA-Z]/, + ALPHANUMERIC = /[a-zA-Z0-9\+\-\.]/; + + function parse(input, stateOverride, base) { + function err(message) { + errors.push(message); + } + + var state = stateOverride || "scheme start", + cursor = 0, + buffer = "", + seenAt = false, + seenBracket = false, + errors = []; + + loop: while ( + (input[cursor - 1] != EOF || cursor == 0) && + !this._isInvalid + ) { + var c = input[cursor]; + switch (state) { + case "scheme start": + if (c && ALPHA.test(c)) { + buffer += c.toLowerCase(); // ASCII-safe + state = "scheme"; + } else if (!stateOverride) { + buffer = ""; + state = "no scheme"; + continue; + } else { + err("Invalid scheme."); + break loop; + } + break; + + case "scheme": + if (c && ALPHANUMERIC.test(c)) { + buffer += c.toLowerCase(); // ASCII-safe + } else if (":" == c) { + this._scheme = buffer; + buffer = ""; + if (stateOverride) { + break loop; + } + if (isRelativeScheme(this._scheme)) { + this._isRelative = true; + } + if ("file" == this._scheme) { + state = "relative"; + } else if ( + this._isRelative && + base && + base._scheme == this._scheme + ) { + state = "relative or authority"; + } else if (this._isRelative) { + state = "authority first slash"; + } else { + state = "scheme data"; + } + } else if (!stateOverride) { + buffer = ""; + cursor = 0; + state = "no scheme"; + continue; + } else if (EOF == c) { + break loop; + } else { + err("Code point not allowed in scheme: " + c); + break loop; + } + break; + + case "scheme data": + if ("?" == c) { + query = "?"; + state = "query"; + } else if ("#" == c) { + this._fragment = "#"; + state = "fragment"; + } else { + // XXX error handling + if (EOF != c && "\t" != c && "\n" != c && "\r" != c) { + this._schemeData += percentEscape(c); + } + } + break; + + case "no scheme": + if (!base || !isRelativeScheme(base._scheme)) { + err("Missing scheme."); + invalid.call(this); + } else { + state = "relative"; + continue; + } + break; + + case "relative or authority": + if ("/" == c && "/" == input[cursor + 1]) { + state = "authority ignore slashes"; + } else { + err("Expected /, got: " + c); + state = "relative"; + continue; + } + break; + + case "relative": + this._isRelative = true; + if ("file" != this._scheme) this._scheme = base._scheme; + if (EOF == c) { + this._host = base._host; + this._port = base._port; + this._path = base._path.slice(); + this._query = base._query; + this._username = base._username; + this._password = base._password; + break loop; + } else if ("/" == c || "\\" == c) { + if ("\\" == c) err("\\ is an invalid code point."); + state = "relative slash"; + } else if ("?" == c) { + this._host = base._host; + this._port = base._port; + this._path = base._path.slice(); + this._query = "?"; + this._username = base._username; + this._password = base._password; + state = "query"; + } else if ("#" == c) { + this._host = base._host; + this._port = base._port; + this._path = base._path.slice(); + this._query = base._query; + this._fragment = "#"; + this._username = base._username; + this._password = base._password; + state = "fragment"; + } else { + var nextC = input[cursor + 1]; + var nextNextC = input[cursor + 2]; + if ( + "file" != this._scheme || + !ALPHA.test(c) || + (nextC != ":" && nextC != "|") || + (EOF != nextNextC && + "/" != nextNextC && + "\\" != nextNextC && + "?" != nextNextC && + "#" != nextNextC) + ) { + this._host = base._host; + this._port = base._port; + this._username = base._username; + this._password = base._password; + this._path = base._path.slice(); + this._path.pop(); + } + state = "relative path"; + continue; + } + break; + + case "relative slash": + if ("/" == c || "\\" == c) { + if ("\\" == c) { + err("\\ is an invalid code point."); + } + if ("file" == this._scheme) { + state = "file host"; + } else { + state = "authority ignore slashes"; + } + } else { + if ("file" != this._scheme) { + this._host = base._host; + this._port = base._port; + this._username = base._username; + this._password = base._password; + } + state = "relative path"; + continue; + } + break; + + case "authority first slash": + if ("/" == c) { + state = "authority second slash"; + } else { + err("Expected '/', got: " + c); + state = "authority ignore slashes"; + continue; + } + break; + + case "authority second slash": + state = "authority ignore slashes"; + if ("/" != c) { + err("Expected '/', got: " + c); + continue; + } + break; + + case "authority ignore slashes": + if ("/" != c && "\\" != c) { + state = "authority"; + continue; + } else { + err("Expected authority, got: " + c); + } + break; + + case "authority": + if ("@" == c) { + if (seenAt) { + err("@ already seen."); + buffer += "%40"; + } + seenAt = true; + for (var i = 0; i < buffer.length; i++) { + var cp = buffer[i]; + if ("\t" == cp || "\n" == cp || "\r" == cp) { + err("Invalid whitespace in authority."); + continue; + } + // XXX check URL code points + if (":" == cp && null === this._password) { + this._password = ""; + continue; + } + var tempC = percentEscape(cp); + null !== this._password + ? (this._password += tempC) + : (this._username += tempC); + } + buffer = ""; + } else if ( + EOF == c || + "/" == c || + "\\" == c || + "?" == c || + "#" == c + ) { + cursor -= buffer.length; + buffer = ""; + state = "host"; + continue; + } else { + buffer += c; + } + break; + + case "file host": + if (EOF == c || "/" == c || "\\" == c || "?" == c || "#" == c) { + if ( + buffer.length == 2 && + ALPHA.test(buffer[0]) && + (buffer[1] == ":" || buffer[1] == "|") + ) { + state = "relative path"; + } else if (buffer.length == 0) { + state = "relative path start"; + } else { + this._host = IDNAToASCII.call(this, buffer); + buffer = ""; + state = "relative path start"; + } + continue; + } else if ("\t" == c || "\n" == c || "\r" == c) { + err("Invalid whitespace in file host."); + } else { + buffer += c; + } + break; + + case "host": + case "hostname": + if (":" == c && !seenBracket) { + // XXX host parsing + this._host = IDNAToASCII.call(this, buffer); + buffer = ""; + state = "port"; + if ("hostname" == stateOverride) { + break loop; + } + } else if ( + EOF == c || + "/" == c || + "\\" == c || + "?" == c || + "#" == c + ) { + this._host = IDNAToASCII.call(this, buffer); + buffer = ""; + state = "relative path start"; + if (stateOverride) { + break loop; + } + continue; + } else if ("\t" != c && "\n" != c && "\r" != c) { + if ("[" == c) { + seenBracket = true; + } else if ("]" == c) { + seenBracket = false; + } + buffer += c; + } else { + err("Invalid code point in host/hostname: " + c); + } + break; + + case "port": + if (/[0-9]/.test(c)) { + buffer += c; + } else if ( + EOF == c || + "/" == c || + "\\" == c || + "?" == c || + "#" == c || + stateOverride + ) { + if ("" != buffer) { + var temp = parseInt(buffer, 10); + if (temp != relative[this._scheme]) { + this._port = temp + ""; + } + buffer = ""; + } + if (stateOverride) { + break loop; + } + state = "relative path start"; + continue; + } else if ("\t" == c || "\n" == c || "\r" == c) { + err("Invalid code point in port: " + c); + } else { + invalid.call(this); + } + break; + + case "relative path start": + if ("\\" == c) err("'\\' not allowed in path."); + state = "relative path"; + if ("/" != c && "\\" != c) { + continue; + } + break; + + case "relative path": + if ( + EOF == c || + "/" == c || + "\\" == c || + (!stateOverride && ("?" == c || "#" == c)) + ) { + if ("\\" == c) { + err("\\ not allowed in relative path."); + } + var tmp; + if ((tmp = relativePathDotMapping[buffer.toLowerCase()])) { + buffer = tmp; + } + if (".." == buffer) { + this._path.pop(); + if ("/" != c && "\\" != c) { + this._path.push(""); + } + } else if ("." == buffer && "/" != c && "\\" != c) { + this._path.push(""); + } else if ("." != buffer) { + if ( + "file" == this._scheme && + this._path.length == 0 && + buffer.length == 2 && + ALPHA.test(buffer[0]) && + buffer[1] == "|" + ) { + buffer = buffer[0] + ":"; + } + this._path.push(buffer); + } + buffer = ""; + if ("?" == c) { + this._query = "?"; + state = "query"; + } else if ("#" == c) { + this._fragment = "#"; + state = "fragment"; + } + } else if ("\t" != c && "\n" != c && "\r" != c) { + buffer += percentEscape(c); + } + break; + + case "query": + if (!stateOverride && "#" == c) { + this._fragment = "#"; + state = "fragment"; + } else if (EOF != c && "\t" != c && "\n" != c && "\r" != c) { + this._query += percentEscapeQuery(c); + } + break; + + case "fragment": + if (EOF != c && "\t" != c && "\n" != c && "\r" != c) { + this._fragment += c; + } + break; + } + + cursor++; + } + } + + function clear() { + this._scheme = ""; + this._schemeData = ""; + this._username = ""; + this._password = null; + this._host = ""; + this._port = ""; + this._path = []; + this._query = ""; + this._fragment = ""; + this._isInvalid = false; + this._isRelative = false; + } + + // Does not process domain names or IP addresses. + // Does not handle encoding for the query parameter. + function jURL(url, base /* , encoding */) { + if (base !== undefined && !(base instanceof jURL)) + base = new jURL(String(base)); + + url = String(url); + + this._url = url; + clear.call(this); + + var input = url.replace(/^[ \t\r\n\f]+|[ \t\r\n\f]+$/g, ""); + // encoding = encoding || 'utf-8' + + parse.call(this, input, null, base); + } + + jURL.prototype = { + toString: function() { + return this.href; + }, + get href() { + if (this._isInvalid) return this._url; + + var authority = ""; + if ("" != this._username || null != this._password) { + authority = + this._username + + (null != this._password ? ":" + this._password : "") + + "@"; + } + + return ( + this.protocol + + (this._isRelative ? "//" + authority + this.host : "") + + this.pathname + + this._query + + this._fragment + ); + }, + set href(href) { + clear.call(this); + parse.call(this, href); + }, + + get protocol() { + return this._scheme + ":"; + }, + set protocol(protocol) { + if (this._isInvalid) return; + parse.call(this, protocol + ":", "scheme start"); + }, + + get host() { + return this._isInvalid + ? "" + : this._port + ? this._host + ":" + this._port + : this._host; + }, + set host(host) { + if (this._isInvalid || !this._isRelative) return; + parse.call(this, host, "host"); + }, + + get hostname() { + return this._host; + }, + set hostname(hostname) { + if (this._isInvalid || !this._isRelative) return; + parse.call(this, hostname, "hostname"); + }, + + get port() { + return this._port; + }, + set port(port) { + if (this._isInvalid || !this._isRelative) return; + parse.call(this, port, "port"); + }, + + get pathname() { + return this._isInvalid + ? "" + : this._isRelative + ? "/" + this._path.join("/") + : this._schemeData; + }, + set pathname(pathname) { + if (this._isInvalid || !this._isRelative) return; + this._path = []; + parse.call(this, pathname, "relative path start"); + }, + + get search() { + return this._isInvalid || !this._query || "?" == this._query + ? "" + : this._query; + }, + set search(search) { + if (this._isInvalid || !this._isRelative) return; + this._query = "?"; + if ("?" == search[0]) search = search.slice(1); + parse.call(this, search, "query"); + }, + + get hash() { + return this._isInvalid || !this._fragment || "#" == this._fragment + ? "" + : this._fragment; + }, + set hash(hash) { + if (this._isInvalid) return; + this._fragment = "#"; + if ("#" == hash[0]) hash = hash.slice(1); + parse.call(this, hash, "fragment"); + }, + + get origin() { + var host; + if (this._isInvalid || !this._scheme) { + return ""; + } + // javascript: Gecko returns String(""), WebKit/Blink String("null") + // Gecko throws error for "data://" + // data: Gecko returns "", Blink returns "data://", WebKit returns "null" + // Gecko returns String("") for file: mailto: + // WebKit/Blink returns String("SCHEME://") for file: mailto: + switch (this._scheme) { + case "data": + case "file": + case "javascript": + case "mailto": + return "null"; + } + host = this.host; + if (!host) { + return ""; + } + return this._scheme + "://" + host; + } + }; + + // Copy over the static methods + var OriginalURL = scope.URL; + if (OriginalURL) { + jURL.createObjectURL = function(blob) { + // IE extension allows a second optional options argument. + // http://msdn.microsoft.com/en-us/library/ie/hh772302(v=vs.85).aspx + return OriginalURL.createObjectURL.apply(OriginalURL, arguments); + }; + jURL.revokeObjectURL = function(url) { + OriginalURL.revokeObjectURL(url); + }; + } + + scope.URL = jURL; +})(window); diff --git a/util.ts b/util.ts index b32e05edb3..42163fb417 100644 --- a/util.ts +++ b/util.ts @@ -9,6 +9,8 @@ export const globalEval = eval; // TODO The underscore is because it's conflicting with @types/node. export const _global = globalEval("this"); +_global["window"] = _global; // Create a window object. + const print = V8Worker2.print; // To control internal logging output diff --git a/yarn.lock b/yarn.lock index 782e7ceaa6..52e93859b5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -53,10 +53,6 @@ version "8.10.14" resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.14.tgz#a24767cfa22023f1bf7e751c0ead56a14c07ed45" -"@types/text-encoding@^0.0.32": - version "0.0.32" - resolved "https://registry.yarnpkg.com/@types/text-encoding/-/text-encoding-0.0.32.tgz#52289b320a406850b14f08f48b475ca021218048" - abbrev@1: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" @@ -153,6 +149,10 @@ async-limiter@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" +async@^1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" + atob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.1.tgz#ae2d5a729477f289d60dd7f96a6314a22dd6c22a" @@ -983,6 +983,10 @@ colormin@^1.0.5: css-color-names "0.0.4" has "^1.0.1" +colors@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b" + colors@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" @@ -1053,6 +1057,10 @@ core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" +corser@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/corser/-/corser-2.0.1.tgz#8eda252ecaab5840dcd975ceb90d9370c819ff87" + create-ecdh@^4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff" @@ -1213,6 +1221,12 @@ debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6. dependencies: ms "2.0.0" +debug@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + dependencies: + ms "2.0.0" + decamelize@^1.1.2: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" @@ -1349,6 +1363,15 @@ duplexer2@~0.1.4: dependencies: readable-stream "^2.0.2" +ecstatic@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/ecstatic/-/ecstatic-3.2.0.tgz#1b1aee1ca7c6b99cfb5cf6c9b26b481b90c4409f" + dependencies: + he "^1.1.1" + mime "^1.4.1" + minimist "^1.1.0" + url-join "^2.0.2" + editorconfig@^0.13.2: version "0.13.3" resolved "https://registry.yarnpkg.com/editorconfig/-/editorconfig-0.13.3.tgz#e5219e587951d60958fd94ea9a9a008cdeff1b34" @@ -1448,6 +1471,10 @@ etag@~1.8.1: version "1.8.1" resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" +eventemitter3@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.0.tgz#090b4d6cdbd645ed10bf750d4b5407942d7ba163" + events@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" @@ -1527,6 +1554,12 @@ flatten@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782" +follow-redirects@^1.0.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.4.1.tgz#d8120f4518190f55aac65bb6fc7b85fcd666d6aa" + dependencies: + debug "^3.1.0" + for-in@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" @@ -1685,6 +1718,10 @@ hash.js@^1.0.0, hash.js@^1.0.3: inherits "^2.0.3" minimalistic-assert "^1.0.0" +he@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" + hmac-drbg@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" @@ -1735,6 +1772,27 @@ http-errors@~1.6.2: setprototypeof "1.1.0" statuses ">= 1.4.0 < 2" +http-proxy@^1.8.1: + version "1.17.0" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.17.0.tgz#7ad38494658f84605e2f6db4436df410f4e5be9a" + dependencies: + eventemitter3 "^3.0.0" + follow-redirects "^1.0.0" + requires-port "^1.0.0" + +http-server@^0.11.1: + version "0.11.1" + resolved "https://registry.yarnpkg.com/http-server/-/http-server-0.11.1.tgz#2302a56a6ffef7f9abea0147d838a5e9b6b6a79b" + dependencies: + colors "1.0.3" + corser "~2.0.0" + ecstatic "^3.0.0" + http-proxy "^1.8.1" + opener "~1.4.0" + optimist "0.6.x" + portfinder "^1.0.13" + union "~0.4.3" + https-browserify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" @@ -2149,6 +2207,10 @@ mime@1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" +mime@^1.4.1: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + minimalistic-assert@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" @@ -2167,10 +2229,14 @@ minimist@0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" -minimist@^1.1.3, minimist@^1.2.0: +minimist@^1.1.0, minimist@^1.1.3, minimist@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" +minimist@~0.0.1: + version "0.0.10" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" + minipass@^2.2.1, minipass@^2.2.4: version "2.3.0" resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.0.tgz#2e11b1c46df7fe7f1afbe9a490280add21ffe384" @@ -2191,7 +2257,7 @@ mixin-deep@^1.2.0: for-in "^1.0.2" is-extendable "^1.0.1" -mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1: +mkdirp@0.5.x, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" dependencies: @@ -2407,12 +2473,23 @@ once@^1.3.0: dependencies: wrappy "1" +opener@~1.4.0: + version "1.4.3" + resolved "https://registry.yarnpkg.com/opener/-/opener-1.4.3.tgz#5c6da2c5d7e5831e8ffa3964950f8d6674ac90b8" + opn@^5.1.0: version "5.3.0" resolved "https://registry.yarnpkg.com/opn/-/opn-5.3.0.tgz#64871565c863875f052cfdf53d3e3cb5adb53b1c" dependencies: is-wsl "^1.1.0" +optimist@0.6.x: + version "0.6.1" + resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" + dependencies: + minimist "~0.0.1" + wordwrap "~0.0.2" + optionator@^0.8.1: version "0.8.2" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" @@ -2558,6 +2635,14 @@ physical-cpu-count@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/physical-cpu-count/-/physical-cpu-count-2.0.0.tgz#18de2f97e4bf7a9551ad7511942b5496f7aba660" +portfinder@^1.0.13: + version "1.0.13" + resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.13.tgz#bb32ecd87c27104ae6ee44b5a3ccbf0ebb1aede9" + dependencies: + async "^1.5.2" + debug "^2.2.0" + mkdirp "0.5.x" + posix-character-classes@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" @@ -2816,10 +2901,6 @@ prepend-http@^1.0.0: version "1.0.4" resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" -prettier@^1.12.1: - version "1.12.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.12.1.tgz#c1ad20e803e7749faf905a409d2367e06bbe7325" - private@^0.1.6, private@^0.1.8: version "0.1.8" resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" @@ -2880,6 +2961,10 @@ q@^1.1.2: version "1.5.1" resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" +qs@~2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/qs/-/qs-2.3.3.tgz#e9e85adbe75da0bbe4c8e0476a086290f863b404" + query-string@^4.1.0: version "4.3.4" resolved "https://registry.yarnpkg.com/query-string/-/query-string-4.3.4.tgz#bbb693b9ca915c232515b228b1a02b609043dbeb" @@ -3023,6 +3108,10 @@ repeating@^2.0.0: dependencies: is-finite "^1.0.0" +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + resolve-url@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" @@ -3404,10 +3493,6 @@ tar@^4: safe-buffer "^5.1.2" yallist "^3.0.2" -text-encoding@^0.6.4: - version "0.6.4" - resolved "https://registry.yarnpkg.com/text-encoding/-/text-encoding-0.6.4.tgz#e399a982257a276dae428bb92845cb71bdc26d19" - through2@^2.0.0, through2@~2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" @@ -3535,6 +3620,12 @@ union-value@^1.0.0: is-extendable "^0.1.1" set-value "^0.4.3" +union@~0.4.3: + version "0.4.6" + resolved "https://registry.yarnpkg.com/union/-/union-0.4.6.tgz#198fbdaeba254e788b0efcb630bc11f24a2959e0" + dependencies: + qs "~2.3.3" + uniq@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" @@ -3568,6 +3659,10 @@ urix@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" +url-join@^2.0.2: + version "2.0.5" + resolved "https://registry.yarnpkg.com/url-join/-/url-join-2.0.5.tgz#5af22f18c052a000a48d7b82c5e9c2e2feeda728" + url@^0.11.0: version "0.11.0" resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" @@ -3632,6 +3727,10 @@ wide-align@^1.1.0: dependencies: string-width "^1.0.2" +wordwrap@~0.0.2: + version "0.0.3" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" + wordwrap@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"