diff --git a/.eslintignore b/.eslintignore index ab2d091f8..17738bf89 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,2 +1,2 @@ -src/client/editor/recast/recast.js -src/client/vendor/TransformControls.js \ No newline at end of file +src/editor/recast/recast.js +src/vendor/TransformControls.js \ No newline at end of file diff --git a/.gitignore b/.gitignore index 8dcb81f2e..7f1f69dbc 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ public/ example/generated/ example/imported/ .certs/ +certs/ .env release/spoke-linux release/spoke-macos diff --git a/.prettierignore b/.prettierignore index 6f8ffdb24..634e30353 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,2 +1,2 @@ -src/client/vendor/TransformControls.js +src/vendor/TransformControls.js package.json \ No newline at end of file diff --git a/LICENSE b/LICENSE index e047ca518..35a1a7ab5 100644 --- a/LICENSE +++ b/LICENSE @@ -2,7 +2,7 @@ ==================================================================== -Portions of this project, particularly code under src/client/editor/, are +Portions of this project, particularly code under src/editor/, are derived from the "three.js / editor" project (https://github.com/mrdoob/three.js/), licensed under the MIT License. diff --git a/package-lock.json b/package-lock.json index cf137d4a8..e729cd324 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1753,6 +1753,12 @@ "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==", "dev": true }, + "ansi-html": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz", + "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=", + "dev": true + }, "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", @@ -1861,6 +1867,12 @@ "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", "dev": true }, + "array-flatten": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", + "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", + "dev": true + }, "array-includes": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz", @@ -1957,6 +1969,12 @@ "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", "dev": true }, + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "dev": true + }, "async-each": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", @@ -3067,6 +3085,12 @@ "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==", "dev": true }, + "batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", + "dev": true + }, "bcrypt-pbkdf": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", @@ -3109,6 +3133,55 @@ "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", "dev": true }, + "body-parser": { + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz", + "integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=", + "dev": true, + "requires": { + "bytes": "3.0.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "~1.6.3", + "iconv-lite": "0.4.23", + "on-finished": "~2.3.0", + "qs": "6.5.2", + "raw-body": "2.3.3", + "type-is": "~1.6.16" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true + } + } + }, + "bonjour": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz", + "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=", + "dev": true, + "requires": { + "array-flatten": "^2.1.0", + "deep-equal": "^1.0.1", + "dns-equal": "^1.0.0", + "dns-txt": "^2.0.2", + "multicast-dns": "^6.0.1", + "multicast-dns-service-types": "^1.1.0" + } + }, "boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", @@ -3306,6 +3379,12 @@ "integrity": "sha512-c5mRlguI/Pe2dSZmpER62rSCu0ryKmWddzRYsuXc50U2/g8jMOulc31VZMa4mYx31U5xsmSOpDCgH88Vl9cDGQ==", "dev": true }, + "buffer-indexof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz", + "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==", + "dev": true + }, "buffer-xor": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", @@ -4640,6 +4719,41 @@ "resolved": "https://registry.npmjs.org/component-indexof/-/component-indexof-0.0.3.tgz", "integrity": "sha1-EdCRMSI5648yyPJa6csAL/6NPCQ=" }, + "compressible": { + "version": "2.0.16", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.16.tgz", + "integrity": "sha512-JQfEOdnI7dASwCuSPWIeVYwc/zMsu/+tRhoUvEfXz2gxOA2DNjmG5vhtFdBlhWPPGo+RdT9S3tgc/uH5qgDiiA==", + "dev": true, + "requires": { + "mime-db": ">= 1.38.0 < 2" + } + }, + "compression": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.3.tgz", + "integrity": "sha512-HSjyBG5N1Nnz7tF2+O7A9XUhyjru71/fwgNb7oIsEVHR0WShfs2tIS/EySLgiTe98aOK18YDlMXpzjCXY/n9mg==", + "dev": true, + "requires": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.14", + "debug": "2.6.9", + "on-headers": "~1.0.1", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -4715,6 +4829,12 @@ } } }, + "connect-history-api-fallback": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", + "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==", + "dev": true + }, "console-browserify": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", @@ -4760,6 +4880,18 @@ "integrity": "sha1-fj5Iu+bZl7FBfdyihoIEtNPYVxU=", "dev": true }, + "cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=", + "dev": true + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", + "dev": true + }, "cookies": { "version": "0.7.3", "resolved": "https://registry.npmjs.org/cookies/-/cookies-0.7.3.tgz", @@ -4912,6 +5044,16 @@ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, + "cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dev": true, + "requires": { + "object-assign": "^4", + "vary": "^1" + } + }, "cosmiconfig": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.1.0.tgz", @@ -5325,6 +5467,52 @@ "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", "dev": true }, + "default-gateway": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz", + "integrity": "sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==", + "dev": true, + "requires": { + "execa": "^1.0.0", + "ip-regex": "^2.1.0" + }, + "dependencies": { + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + } + } + }, "define-properties": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", @@ -5450,6 +5638,12 @@ "repeating": "^2.0.0" } }, + "detect-node": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz", + "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==", + "dev": true + }, "diff": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", @@ -5487,6 +5681,31 @@ "redux": "^4.0.0" } }, + "dns-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", + "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=", + "dev": true + }, + "dns-packet": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.1.tgz", + "integrity": "sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==", + "dev": true, + "requires": { + "ip": "^1.1.0", + "safe-buffer": "^5.0.1" + } + }, + "dns-txt": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz", + "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=", + "dev": true, + "requires": { + "buffer-indexof": "^1.0.0" + } + }, "doctrine": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", @@ -5683,6 +5902,12 @@ "core-js": "^2.0.0" } }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "dev": true + }, "encoding": { "version": "0.1.12", "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", @@ -6101,6 +6326,12 @@ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=" }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "dev": true + }, "eventemitter3": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz", @@ -6112,6 +6343,15 @@ "integrity": "sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA==", "dev": true }, + "eventsource": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.0.7.tgz", + "integrity": "sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ==", + "dev": true, + "requires": { + "original": "^1.0.0" + } + }, "evp_bytestokey": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", @@ -6265,6 +6505,85 @@ "homedir-polyfill": "^1.0.1" } }, + "express": { + "version": "4.16.4", + "resolved": "https://registry.npmjs.org/express/-/express-4.16.4.tgz", + "integrity": "sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg==", + "dev": true, + "requires": { + "accepts": "~1.3.5", + "array-flatten": "1.1.1", + "body-parser": "1.18.3", + "content-disposition": "0.5.2", + "content-type": "~1.0.4", + "cookie": "0.3.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.1.1", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.4", + "qs": "6.5.2", + "range-parser": "~1.2.0", + "safe-buffer": "5.1.2", + "send": "0.16.2", + "serve-static": "1.13.2", + "setprototypeof": "1.1.0", + "statuses": "~1.4.0", + "type-is": "~1.6.16", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", + "dev": true + }, + "content-disposition": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", + "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=", + "dev": true + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", + "dev": true + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true + }, + "statuses": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", + "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==", + "dev": true + } + } + }, "extend-shallow": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", @@ -6413,6 +6732,15 @@ "integrity": "sha1-0eJkOzipTXWDtHkGDmxK/8lAcfg=", "dev": true }, + "faye-websocket": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", + "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", + "dev": true, + "requires": { + "websocket-driver": ">=0.5.1" + } + }, "fbjs": { "version": "0.8.17", "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.17.tgz", @@ -6507,6 +6835,38 @@ } } }, + "finalhandler": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", + "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", + "dev": true, + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", + "statuses": "~1.4.0", + "unpipe": "~1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "statuses": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", + "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==", + "dev": true + } + } + }, "find-cache-dir": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-1.0.0.tgz", @@ -6595,6 +6955,32 @@ "integrity": "sha1-UhTXU3pNBqSjAcDMJi/rhBiAAuc=", "dev": true }, + "follow-redirects": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.7.0.tgz", + "integrity": "sha512-m/pZQy4Gj287eNy94nivy5wchN3Kp+Q5WgUPNy5lJSZ3sgkVKSYV/ZChMAQVIgx1SqfZ2zBZtPA2YlXIWxxJOQ==", + "dev": true, + "requires": { + "debug": "^3.2.6" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + } + } + }, "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", @@ -6636,6 +7022,12 @@ "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.1.tgz", "integrity": "sha512-Fs9VRguL0gqGHkXS5GQiMCr1VhZBxz0JnJs4JmMp/2jL18Fmbzvv7vOFRU+U8TBkHEE/CX1qDXzJplVULgsLeg==" }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", + "dev": true + }, "fragment-cache": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", @@ -7610,6 +8002,12 @@ "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", "dev": true }, + "handle-thing": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.0.tgz", + "integrity": "sha512-d4sze1JNC454Wdo2fkuyzCr6aHcbL6PGGuFAz0Li/NcOm1tCHGnWDRmJP85dh9IhQErTc2svWFEX5xHIOo//kQ==", + "dev": true + }, "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -7783,6 +8181,18 @@ "integrity": "sha512-lIbgIIQA3lz5XaB6vxakj6sDHADJiZadYEJB+FgA+C4nubM1NwcuvUr9EJPmnH1skZqpqUzWborWo8EIUi0Sdw==", "dev": true }, + "hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, "html-comment-regex": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.1.tgz", @@ -7803,6 +8213,12 @@ "whatwg-encoding": "^1.0.1" } }, + "html-entities": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.2.1.tgz", + "integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=", + "dev": true + }, "html-minifier": { "version": "3.5.16", "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.16.tgz", @@ -7924,6 +8340,12 @@ } } }, + "http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=", + "dev": true + }, "http-errors": { "version": "1.6.3", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", @@ -7935,6 +8357,35 @@ "statuses": ">= 1.4.0 < 2" } }, + "http-parser-js": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.0.tgz", + "integrity": "sha512-cZdEF7r4gfRIq7ezX9J0T+kQmJNOub71dWbgAXVHDct80TKP4MCETtZQ31xyv38UwgzkWPYF/Xc0ge55dW9Z9w==", + "dev": true + }, + "http-proxy": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.17.0.tgz", + "integrity": "sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==", + "dev": true, + "requires": { + "eventemitter3": "^3.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + } + }, + "http-proxy-middleware": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz", + "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==", + "dev": true, + "requires": { + "http-proxy": "^1.17.0", + "is-glob": "^4.0.0", + "lodash": "^4.17.11", + "micromatch": "^3.1.10" + } + }, "https-browserify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", @@ -8272,10 +8723,28 @@ "through": "^2.3.6" } }, - "interpret": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz", - "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==", + "internal-ip": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.2.0.tgz", + "integrity": "sha512-ZY8Rk+hlvFeuMmG5uH1MXhhdeMntmIaxaInvAmzMq/SHV8rv4Kh+6GiQNNDQd0wZFrcO+FiTBo8lui/osKOyJw==", + "dev": true, + "requires": { + "default-gateway": "^4.0.1", + "ipaddr.js": "^1.9.0" + }, + "dependencies": { + "ipaddr.js": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz", + "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==", + "dev": true + } + } + }, + "interpret": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz", + "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==", "dev": true }, "invariant": { @@ -8292,6 +8761,24 @@ "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", "dev": true }, + "ip": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", + "dev": true + }, + "ip-regex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", + "dev": true + }, + "ipaddr.js": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.8.0.tgz", + "integrity": "sha1-6qM9bd16zo9/b+DJygRA5wZzix4=", + "dev": true + }, "irregular-plurals": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-1.4.0.tgz", @@ -8890,6 +9377,12 @@ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" }, + "json3": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz", + "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=", + "dev": true + }, "json5": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", @@ -8947,6 +9440,12 @@ "resolved": "https://registry.npmjs.org/keygrip/-/keygrip-1.0.3.tgz", "integrity": "sha512-/PpesirAIfaklxUzp4Yb7xBper9MwP6hNRA6BGGUFCgbJ+BM5CKBtsoxinNXkLHAr+GXS1/lSlF2rP7cv5Fl+g==" }, + "killable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz", + "integrity": "sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==", + "dev": true + }, "kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", @@ -9662,6 +10161,12 @@ "wrap-ansi": "^3.0.1" } }, + "loglevel": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.1.tgz", + "integrity": "sha1-4PyVEztu8nbNyIh82vJKpvFW+Po=", + "dev": true + }, "loglevelnext": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/loglevelnext/-/loglevelnext-1.0.5.tgz", @@ -9866,6 +10371,12 @@ } } }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", + "dev": true + }, "merge-options": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-options/-/merge-options-1.0.1.tgz", @@ -10104,6 +10615,22 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, + "multicast-dns": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz", + "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==", + "dev": true, + "requires": { + "dns-packet": "^1.3.1", + "thunky": "^1.0.2" + } + }, + "multicast-dns-service-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz", + "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=", + "dev": true + }, "multimatch": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz", @@ -10198,7 +10725,8 @@ "node-forge": { "version": "0.7.5", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.5.tgz", - "integrity": "sha512-MmbQJ2MTESTjt3Gi/3yG1wGpIMhUfcIypUCGtTizFR9IiccFwxSpfp0vtIZlkFclEqERemxfnSdZEMR9VqqEFQ==" + "integrity": "sha512-MmbQJ2MTESTjt3Gi/3yG1wGpIMhUfcIypUCGtTizFR9IiccFwxSpfp0vtIZlkFclEqERemxfnSdZEMR9VqqEFQ==", + "dev": true }, "node-gyp": { "version": "3.8.0", @@ -10610,6 +11138,12 @@ } } }, + "obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "dev": true + }, "on-finished": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", @@ -10618,6 +11152,12 @@ "ee-first": "1.1.1" } }, + "on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "dev": true + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -10641,6 +11181,15 @@ "resolved": "https://registry.npmjs.org/only/-/only-0.0.2.tgz", "integrity": "sha1-Kv3oTQPlC5qO3EROMGEKcCle37Q=" }, + "opn": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-5.4.0.tgz", + "integrity": "sha512-YF9MNdVy/0qvJvDtunAOzFw9iasOQHpVthTCvGzxt61Il64AYSGdK+rYwld7NAfk9qJ7dt+hymBNSc9LNYS+Sw==", + "dev": true, + "requires": { + "is-wsl": "^1.1.0" + } + }, "option-chain": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/option-chain/-/option-chain-1.0.0.tgz", @@ -10661,6 +11210,15 @@ "wordwrap": "~1.0.0" } }, + "original": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz", + "integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==", + "dev": true, + "requires": { + "url-parse": "^1.4.3" + } + }, "os-browserify": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", @@ -11074,6 +11632,28 @@ "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==", "dev": true }, + "portfinder": { + "version": "1.0.20", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.20.tgz", + "integrity": "sha512-Yxe4mTyDzTd59PZJY4ojZR8F+E5e97iq2ZOHPz3HDgSvYC5siNad2tLooQ5y5QHyQhc3xVqvyk/eNA3wuoa7Sw==", + "dev": true, + "requires": { + "async": "^1.5.2", + "debug": "^2.2.0", + "mkdirp": "0.5.x" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, "posix-character-classes": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", @@ -11685,6 +12265,16 @@ } } }, + "proxy-addr": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.4.tgz", + "integrity": "sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA==", + "dev": true, + "requires": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.8.0" + } + }, "prr": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", @@ -11830,6 +12420,12 @@ "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", "dev": true }, + "querystringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.0.tgz", + "integrity": "sha512-sluvZZ1YiTLD5jsqZcDmFyV2EwToyXZBfpoVOmktMmW+VEnhgakFHnasVph65fOjGPTWN0Nw3+XQaSeMayr0kg==", + "dev": true + }, "raf": { "version": "3.4.1", "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz", @@ -12819,6 +13415,12 @@ "resolve-from": "^1.0.0" } }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", + "dev": true + }, "resolve": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", @@ -13057,10 +13659,17 @@ } } }, + "select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=", + "dev": true + }, "selfsigned": { "version": "1.10.4", "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.4.tgz", "integrity": "sha512-9AukTiDmHXGXWtWjembZ5NDmVvP2695EtpgbCsxCa68w3c88B+alqbmZ4O3hZ4VWGXeGWzEVdvqgAJD8DQPCDw==", + "dev": true, "requires": { "node-forge": "0.7.5" } @@ -13086,6 +13695,50 @@ "semver": "^5.0.3" } }, + "send": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", + "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", + "dev": true, + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.6.2", + "mime": "1.4.1", + "ms": "2.0.0", + "on-finished": "~2.3.0", + "range-parser": "~1.2.0", + "statuses": "~1.4.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "mime": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", + "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==", + "dev": true + }, + "statuses": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", + "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==", + "dev": true + } + } + }, "serialize-error": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-2.1.0.tgz", @@ -13098,6 +13751,44 @@ "integrity": "sha512-A5MOagrPFga4YaKQSWHryl7AXvbQkEqpw4NNYMTNYUNV51bA8ABHgYFpqKx+YFFrw59xMV1qGH1R4AgoNIVgCw==", "dev": true }, + "serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", + "dev": true, + "requires": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "serve-static": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", + "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", + "dev": true, + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.2", + "send": "0.16.2" + } + }, "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", @@ -13339,6 +14030,56 @@ } } }, + "sockjs": { + "version": "0.3.19", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.19.tgz", + "integrity": "sha512-V48klKZl8T6MzatbLlzzRNhMepEys9Y4oGFpypBFFn1gLI/QQ9HtLLyWJNbPlwGLelOVOEijUbTTJeLLI59jLw==", + "dev": true, + "requires": { + "faye-websocket": "^0.10.0", + "uuid": "^3.0.1" + } + }, + "sockjs-client": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.3.0.tgz", + "integrity": "sha512-R9jxEzhnnrdxLCNln0xg5uGHqMnkhPSTzUZH2eXcR03S/On9Yvoq2wyUZILRUhZCNVu2PmwWVoyuiPz8th8zbg==", + "dev": true, + "requires": { + "debug": "^3.2.5", + "eventsource": "^1.0.7", + "faye-websocket": "~0.11.1", + "inherits": "^2.0.3", + "json3": "^3.3.2", + "url-parse": "^1.4.3" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "faye-websocket": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.1.tgz", + "integrity": "sha1-8O/hjE9W5PQK/H4Gxxn9XuYYjzg=", + "dev": true, + "requires": { + "websocket-driver": ">=0.5.1" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + } + } + }, "sort-keys": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", @@ -13428,6 +14169,78 @@ "integrity": "sha512-2+EPwgbnmOIl8HjGBXXMd9NAu02vLjOO1nWw4kmeRDFyHn+M/ETfHxQUK0oXg8ctgVnl9t3rosNVsZ1jG61nDA==", "dev": true }, + "spdy": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.0.tgz", + "integrity": "sha512-ot0oEGT/PGUpzf/6uk4AWLqkq+irlqHXkrdbk51oWONh3bxQmBuljxPNl66zlRRcIJStWq0QkLUCPOPjgjvU0Q==", + "dev": true, + "requires": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + } + } + }, + "spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "dev": true, + "requires": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, + "readable-stream": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.2.0.tgz", + "integrity": "sha512-RV20kLjdmpZuTF1INEb9IA3L68Nmi+Ri7ppZqo78wj//Pn62fCoJyV9zalccNzDD/OuJpMG4f+pfMl8+L6QdGw==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, "split-string": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", @@ -14075,6 +14888,12 @@ "xtend": "~4.0.1" } }, + "thunky": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.0.3.tgz", + "integrity": "sha512-YwT8pjmNcAXBZqrubu22P4FYsh2D4dxRmnWBOL8Jk8bUcRUtc5326kx32tuTmFDAZtLOGEVNl8POAR8j896Iow==", + "dev": true + }, "time-zone": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/time-zone/-/time-zone-1.0.0.tgz", @@ -14582,6 +15401,16 @@ } } }, + "url-parse": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.4.tgz", + "integrity": "sha512-/92DTTorg4JjktLNLe6GPS2/RvAd/RGr6LuktmWSMLEOa6rjnlrFXNgSbSmkNvCoL2T028A0a1JaJLzRMlFoHg==", + "dev": true, + "requires": { + "querystringify": "^2.0.0", + "requires-port": "^1.0.0" + } + }, "use": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", @@ -14618,6 +15447,12 @@ "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=", "dev": true }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "dev": true + }, "uuid": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", @@ -14720,6 +15555,15 @@ "neo-async": "^2.5.0" } }, + "wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "dev": true, + "requires": { + "minimalistic-assert": "^1.0.0" + } + }, "webidl-conversions": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", @@ -15021,29 +15865,367 @@ "webpack-log": "^2.0.0" } }, - "webpack-hot-client": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/webpack-hot-client/-/webpack-hot-client-4.1.1.tgz", - "integrity": "sha512-Gu3hEkFJIsvC+2Dg86FvAzIL8KSR88Ptk0QnV4wEucObB0c9aMIYbjSA9oPTV4X5OZRH6ftrk4FcSGsZmTLiWA==", - "dev": true, - "requires": { - "@webpack-contrib/schema-utils": "^1.0.0-beta.0", - "json-stringify-safe": "^5.0.1", - "loglevelnext": "^1.0.2", - "merge-options": "^1.0.1", - "strip-ansi": "^4.0.0", - "uuid": "^3.1.0", - "webpack-log": "^1.1.1", - "ws": "^4.0.0" + "webpack-dev-server": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.2.1.tgz", + "integrity": "sha512-sjuE4mnmx6JOh9kvSbPYw3u/6uxCLHNWfhWaIPwcXWsvWOPN+nc5baq4i9jui3oOBRXGonK9+OI0jVkaz6/rCw==", + "dev": true, + "requires": { + "ansi-html": "0.0.7", + "bonjour": "^3.5.0", + "chokidar": "^2.0.0", + "compression": "^1.5.2", + "connect-history-api-fallback": "^1.3.0", + "debug": "^4.1.1", + "del": "^3.0.0", + "express": "^4.16.2", + "html-entities": "^1.2.0", + "http-proxy-middleware": "^0.19.1", + "import-local": "^2.0.0", + "internal-ip": "^4.2.0", + "ip": "^1.1.5", + "killable": "^1.0.0", + "loglevel": "^1.4.1", + "opn": "^5.1.0", + "portfinder": "^1.0.9", + "schema-utils": "^1.0.0", + "selfsigned": "^1.9.1", + "semver": "^5.6.0", + "serve-index": "^1.7.2", + "sockjs": "0.3.19", + "sockjs-client": "1.3.0", + "spdy": "^4.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^6.1.0", + "url": "^0.11.0", + "webpack-dev-middleware": "^3.5.1", + "webpack-log": "^2.0.0", + "yargs": "12.0.2" }, "dependencies": { - "webpack-log": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-1.2.0.tgz", - "integrity": "sha512-U9AnICnu50HXtiqiDxuli5gLB5PGBo7VvcHx36jRZHwK4vzOYLbImqT4lwWwoMHdQWwEKw736fCHEekokTEKHA==", - "dev": true, - "requires": { - "chalk": "^2.1.0", + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, + "cliui": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", + "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "dev": true, + "requires": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "decamelize": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-2.0.0.tgz", + "integrity": "sha512-Ikpp5scV3MSYxY39ymh45ZLEecsTdv/Xj2CaQfI8RLMuwi7XvjX9H/fhraiSuU+C5w5NTDu4ZU72xNiZnurBPg==", + "dev": true, + "requires": { + "xregexp": "4.0.0" + } + }, + "del": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/del/-/del-3.0.0.tgz", + "integrity": "sha1-U+z2mf/LyzljdpGrE7rxYIGXZuU=", + "dev": true, + "requires": { + "globby": "^6.1.0", + "is-path-cwd": "^1.0.0", + "is-path-in-cwd": "^1.0.0", + "p-map": "^1.1.1", + "pify": "^3.0.0", + "rimraf": "^2.2.8" + } + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "dev": true, + "requires": { + "array-union": "^1.0.1", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, + "invert-kv": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", + "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "lcid": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", + "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", + "dev": true, + "requires": { + "invert-kv": "^2.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, + "os-locale": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", + "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", + "dev": true, + "requires": { + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + } + }, + "p-limit": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", + "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz", + "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==", + "dev": true + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + } + } + }, + "yargs": { + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.2.tgz", + "integrity": "sha512-e7SkEx6N6SIZ5c5H22RTZae61qtn3PYUE8JYbBFlK9sYmh3DMQ6E5ygtaG/2BW0JZi4WGgTR2IV5ChqlqrDGVQ==", + "dev": true, + "requires": { + "cliui": "^4.0.0", + "decamelize": "^2.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^1.0.1", + "os-locale": "^3.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1 || ^4.0.0", + "yargs-parser": "^10.1.0" + } + }, + "yargs-parser": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz", + "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==", + "dev": true, + "requires": { + "camelcase": "^4.1.0" + } + } + } + }, + "webpack-hot-client": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/webpack-hot-client/-/webpack-hot-client-4.1.1.tgz", + "integrity": "sha512-Gu3hEkFJIsvC+2Dg86FvAzIL8KSR88Ptk0QnV4wEucObB0c9aMIYbjSA9oPTV4X5OZRH6ftrk4FcSGsZmTLiWA==", + "dev": true, + "requires": { + "@webpack-contrib/schema-utils": "^1.0.0-beta.0", + "json-stringify-safe": "^5.0.1", + "loglevelnext": "^1.0.2", + "merge-options": "^1.0.1", + "strip-ansi": "^4.0.0", + "uuid": "^3.1.0", + "webpack-log": "^1.1.1", + "ws": "^4.0.0" + }, + "dependencies": { + "webpack-log": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-1.2.0.tgz", + "integrity": "sha512-U9AnICnu50HXtiqiDxuli5gLB5PGBo7VvcHx36jRZHwK4vzOYLbImqT4lwWwoMHdQWwEKw736fCHEekokTEKHA==", + "dev": true, + "requires": { + "chalk": "^2.1.0", "log-symbols": "^2.1.0", "loglevelnext": "^1.0.1", "uuid": "^3.1.0" @@ -15089,6 +16271,22 @@ } } }, + "websocket-driver": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.0.tgz", + "integrity": "sha1-DK+dLXVdk67gSdS90NP+LMoqJOs=", + "dev": true, + "requires": { + "http-parser-js": ">=0.4.0", + "websocket-extensions": ">=0.1.1" + } + }, + "websocket-extensions": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz", + "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==", + "dev": true + }, "well-known-symbols": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/well-known-symbols/-/well-known-symbols-1.0.0.tgz", @@ -15327,6 +16525,12 @@ "integrity": "sha512-tGkGJkN8XqCod7OT+EvGYK5Z4SfDQGD30zAa58OcnAa0RRWgzUEK72tkXhsX1FZd+rgnhRxFtmO+ihkp8LHSkw==", "dev": true }, + "xregexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-4.0.0.tgz", + "integrity": "sha512-PHyM+sQouu7xspQQwELlGwwd05mXUFqwFYfqPO0cC7x4fxyHnnuetmQr6CjJiafIDoH4MogHb9dOoJzR/Y4rFg==", + "dev": true + }, "xtend": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", diff --git a/package.json b/package.json index 0a9e1ea15..f410d89f2 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "url": "https://github.com/MozillaReality/spoke.git" }, "scripts": { - "start": "cross-env NODE_ENV=development node ./src/server", + "start": "cross-env NODE_ENV=development webpack-dev-server --mode development", "build": "cross-env NODE_ENV=production webpack --mode production", "precommit": "lint-staged", "lint": "eslint ./src", @@ -78,7 +78,6 @@ "react-router-dom": "^4.3.1", "react-select": "^2.4.1", "react-toggle": "^4.0.2", - "selfsigned": "^1.10.4", "signals": "^1.0.0", "three": "github:mozillareality/three.js#220c52eb20b5d8afce8aecc295283d7a7a1e0c62", "uuid": "^3.3.2" @@ -98,6 +97,7 @@ "browser-env": "^3.2.6", "chai": "^4.2.0", "copy-webpack-plugin": "^5.0.0", + "cors": "^2.8.5", "cross-env": "^5.2.0", "css-loader": "^0.28.11", "dotenv": "^6.2.0", @@ -118,10 +118,12 @@ "prettier": "^1.16.4", "puppeteer-core": "^1.13.0", "sass-loader": "^7.1.0", + "selfsigned": "^1.10.4", "source-map-support": "^0.5.10", "style-loader": "^0.21.0", "webpack": "^4.28.4", "webpack-cli": "^3.2.3", + "webpack-dev-server": "^3.2.1", "worker-loader": "^2.0.0" } } diff --git a/src/client/api/Api.js b/src/api/Api.js similarity index 85% rename from src/client/api/Api.js rename to src/api/Api.js index 601e40e08..3e810366a 100644 --- a/src/client/api/Api.js +++ b/src/api/Api.js @@ -156,12 +156,54 @@ export default class Project extends EventEmitter { return localStorage.getItem("spoke-credentials") !== null; } - getProjects() { - return this.fetchJSON(`https://${process.env.RETICULUM_SERVER}/api/v1/projects`); + async getProjects() { + const credentials = localStorage.getItem("spoke-credentials"); + + const headers = { + "content-type": "application/json", + authorization: `Bearer ${credentials}` + }; + + const response = await fetch(`https://${process.env.RETICULUM_SERVER}/api/v1/projects`, { headers }); + + const json = await response.json(); + + if (!Array.isArray(json.projects)) { + throw new Error(`Error fetching projects: ${json.error || "Unknown error."}`); + } + + return json.projects.map(project => ({ + id: project.project_id, + name: project.name, + thumbnailUrl: project.thumbnail_url + })); } - getProject(projectId) { - return this.fetchJSON(`https://${process.env.RETICULUM_SERVER}/api/v1/projects/${projectId}`); + async getProject(projectId) { + const credentials = localStorage.getItem("spoke-credentials"); + + const headers = { + "content-type": "application/json", + authorization: `Bearer ${credentials}` + }; + + const response = await fetch(`https://${process.env.RETICULUM_SERVER}/api/v1/projects/${projectId}`, { headers }); + + const json = await response.json(); + + let project = null; + + if (json.project_url) { + const projectFileResponse = await fetch(json.project_url, { headers }); + project = await projectFileResponse.json(); + } + + return { + id: json.project_id, + name: json.name, + thumbnailUrl: json.thumbnail_url, + project + }; } async getContentType(url) { @@ -259,11 +301,13 @@ export default class Project extends EventEmitter { }; const body = JSON.stringify({ - name: editor.scene.name, - thumbnail_file_id, - thumbnail_file_token, - project_file_id, - project_file_token + project: { + name: editor.scene.name, + thumbnail_file_id, + thumbnail_file_token, + project_file_id, + project_file_token + } }); const projectEndpoint = `https://${process.env.RETICULUM_SERVER}/api/v1/projects/${projectId}`; @@ -290,7 +334,7 @@ export default class Project extends EventEmitter { } } - async publishProject(projectId, editor, location, showDialog, hideDialog) { + async publishProject(projectId, editor, showDialog, hideDialog) { let screenshotURL; try { @@ -298,7 +342,7 @@ export default class Project extends EventEmitter { // Save the scene if it has been modified. if (editor.sceneModified) { - await this.saveProject(); + await this.saveProject(projectId, editor, showDialog, hideDialog); } // Ensure the user is authenticated before continuing. @@ -319,7 +363,11 @@ export default class Project extends EventEmitter { const userInfo = this.getUserInfo(); let initialCreatorAttribution = creatorAttribution; - if (!initialCreatorAttribution || initialCreatorAttribution.length === 0) { + if ( + (!initialCreatorAttribution || initialCreatorAttribution.length === 0) && + userInfo && + userInfo.creatorAttribution + ) { initialCreatorAttribution = userInfo.creatorAttribution; } @@ -327,7 +375,7 @@ export default class Project extends EventEmitter { // Display the publish dialog and wait for the user to submit / cancel const publishParams = await new Promise(resolve => { - this.showDialog(PublishDialog, { + showDialog(PublishDialog, { screenshotURL, contentAttributions, initialName: name || editor.scene.name, @@ -390,32 +438,25 @@ export default class Project extends EventEmitter { }); // Upload the screenshot file - const screenshotFormData = new FormData(); - screenshotFormData.set("media", screenshotBlob); const { file_id: screenshotId, meta: { access_token: screenshotToken } - } = await this.upload(screenshotFormData); + } = await this.upload(screenshotBlob); - const glbFormData = new FormData(); - glbFormData.set("media", glbBlob); const { file_id: glbId, meta: { access_token: glbToken } - } = await this.upload(glbFormData, uploadProgress => { + } = await this.upload(glbBlob, uploadProgress => { showDialog(ProgressDialog, { title: "Publishing Scene", message: `Uploading scene: ${Math.floor(uploadProgress * 100)}%` }); }); - const sceneFormData = new FormData(); - sceneFormData.set("media", sceneBlob); - const { file_id: sceneFileId, meta: { access_token: sceneFileToken } - } = await this.upload(sceneFormData); + } = await this.upload(sceneBlob); const sceneParams = { screenshot_file_id: screenshotId, @@ -424,13 +465,13 @@ export default class Project extends EventEmitter { model_file_token: glbToken, scene_file_id: sceneFileId, scene_file_token: sceneFileToken, - allow_remixing: allowRemixing, - allow_promotion: allowPromotion, - name, - description, + allow_remixing: publishParams.allowRemixing, + allow_promotion: publishParams.allowPromotion, + name: publishParams.name, + description: publishParams.description, attributions: { - creator: creatorAttribution, - content: contentAttributions + creator: publishParams.creatorAttribution, + content: publishParams.contentAttributions } }; @@ -456,7 +497,7 @@ export default class Project extends EventEmitter { showDialog(LoginDialog, { onSuccess: async () => { try { - await this.publish(editor, location, showDialog, hideDialog); + await this.publish(editor, showDialog, hideDialog); resolve(); } catch (e) { reject(e); @@ -475,12 +516,12 @@ export default class Project extends EventEmitter { let sceneUrl = json.scenes[0].url; if (process.env.HUBS_SERVER) { - sceneUrl = `https://${process.env.HUBS_SERVER}/scene.html?scene_id=${newSceneId}`; + sceneUrl = `https://${process.env.HUBS_SERVER}/scenes/${newSceneId}`; } - editor.setSceneMetadata({ sceneUrl, sceneId }); + scene.setMetadata({ sceneUrl, sceneId }); - await this.saveProject(editor, showDialog, hideDialog); + await this.saveProject(projectId, editor, showDialog, hideDialog); showDialog(PublishDialog, { screenshotURL, diff --git a/src/client/api/AuthContainer.js b/src/api/AuthContainer.js similarity index 85% rename from src/client/api/AuthContainer.js rename to src/api/AuthContainer.js index 06558b16d..ed1e920c3 100644 --- a/src/client/api/AuthContainer.js +++ b/src/api/AuthContainer.js @@ -22,10 +22,12 @@ export default class AuthContainer extends Component { .authenticate(email) .then(this.props.onSuccess) .catch(this.onError); + + this.setState({ mailSent: true }); }; onError = err => { - this.setState({ error: err.message || "Error signing in. Please try again." }); + this.setState({ mailSent: false, error: err.message || "Error signing in. Please try again." }); }; render() { diff --git a/src/client/api/AuthEmailSentMessage.js b/src/api/AuthEmailSentMessage.js similarity index 100% rename from src/client/api/AuthEmailSentMessage.js rename to src/api/AuthEmailSentMessage.js diff --git a/src/client/api/AuthForm.js b/src/api/AuthForm.js similarity index 90% rename from src/client/api/AuthForm.js rename to src/api/AuthForm.js index fe3a929a9..21923b8a2 100644 --- a/src/client/api/AuthForm.js +++ b/src/api/AuthForm.js @@ -13,6 +13,7 @@ export default class AuthForm extends Component { onSubmit = e => { e.preventDefault(); + console.log("onsubmit"); this.props.onSubmit(this.state.email); }; @@ -26,7 +27,7 @@ export default class AuthForm extends Component { {this.props.error &&

{this.props.error}

}

By proceeding, you agree to the{" "} @@ -36,7 +37,8 @@ export default class AuthForm extends Component { and{" "} privacy notice - . + + .

diff --git a/src/client/api/LoginDialog.js b/src/api/LoginDialog.js similarity index 100% rename from src/client/api/LoginDialog.js rename to src/api/LoginDialog.js diff --git a/src/client/api/PublishDialog.js b/src/api/PublishDialog.js similarity index 94% rename from src/client/api/PublishDialog.js rename to src/api/PublishDialog.js index d3aab490c..d5f7d4636 100644 --- a/src/client/api/PublishDialog.js +++ b/src/api/PublishDialog.js @@ -116,7 +116,8 @@ export default class PublishDialog extends Component { rel="noopener noreferrer" > Remixing -  with + +  with
Creative Commons  )} - {!published && - contentAttributions && ( -
- -

- {contentAttributions.map(a => `${a.name} by ${a.author}\n`)} -

-
- )} + {!published && contentAttributions && ( +
+ +

{contentAttributions.map(a => `${a.name} by ${a.author}\n`)}

+
+ )} diff --git a/src/client/api/sketchfab-zip.worker.js b/src/api/sketchfab-zip.worker.js similarity index 100% rename from src/client/api/sketchfab-zip.worker.js rename to src/api/sketchfab-zip.worker.js diff --git a/src/client/assets/LoginBot.png b/src/assets/LoginBot.png similarity index 100% rename from src/client/assets/LoginBot.png rename to src/assets/LoginBot.png diff --git a/src/client/assets/cubemap/negx.jpg b/src/assets/cubemap/negx.jpg similarity index 100% rename from src/client/assets/cubemap/negx.jpg rename to src/assets/cubemap/negx.jpg diff --git a/src/client/assets/cubemap/negy.jpg b/src/assets/cubemap/negy.jpg similarity index 100% rename from src/client/assets/cubemap/negy.jpg rename to src/assets/cubemap/negy.jpg diff --git a/src/client/assets/cubemap/negz.jpg b/src/assets/cubemap/negz.jpg similarity index 100% rename from src/client/assets/cubemap/negz.jpg rename to src/assets/cubemap/negz.jpg diff --git a/src/client/assets/cubemap/posx.jpg b/src/assets/cubemap/posx.jpg similarity index 100% rename from src/client/assets/cubemap/posx.jpg rename to src/assets/cubemap/posx.jpg diff --git a/src/client/assets/cubemap/posy.jpg b/src/assets/cubemap/posy.jpg similarity index 100% rename from src/client/assets/cubemap/posy.jpg rename to src/assets/cubemap/posy.jpg diff --git a/src/client/assets/cubemap/posz.jpg b/src/assets/cubemap/posz.jpg similarity index 100% rename from src/client/assets/cubemap/posz.jpg rename to src/assets/cubemap/posz.jpg diff --git a/src/client/assets/default-thumbnail.png b/src/assets/default-thumbnail.png similarity index 100% rename from src/client/assets/default-thumbnail.png rename to src/assets/default-thumbnail.png diff --git a/src/client/assets/error-icon.svg b/src/assets/error-icon.svg similarity index 100% rename from src/client/assets/error-icon.svg rename to src/assets/error-icon.svg diff --git a/src/client/assets/favicon.ico b/src/assets/favicon.ico similarity index 100% rename from src/client/assets/favicon.ico rename to src/assets/favicon.ico diff --git a/src/client/assets/file-icon.svg b/src/assets/file-icon.svg similarity index 100% rename from src/client/assets/file-icon.svg rename to src/assets/file-icon.svg diff --git a/src/client/assets/folder-icon.svg b/src/assets/folder-icon.svg similarity index 100% rename from src/client/assets/folder-icon.svg rename to src/assets/folder-icon.svg diff --git a/src/client/assets/info-icon.svg b/src/assets/info-icon.svg similarity index 100% rename from src/client/assets/info-icon.svg rename to src/assets/info-icon.svg diff --git a/src/client/assets/spawn-point.glb b/src/assets/spawn-point.glb similarity index 100% rename from src/client/assets/spawn-point.glb rename to src/assets/spawn-point.glb diff --git a/src/client/assets/spawn-point.png b/src/assets/spawn-point.png similarity index 100% rename from src/client/assets/spawn-point.png rename to src/assets/spawn-point.png diff --git a/src/client/assets/spoke-icon.png b/src/assets/spoke-icon.png similarity index 100% rename from src/client/assets/spoke-icon.png rename to src/assets/spoke-icon.png diff --git a/src/client/assets/warning-icon.svg b/src/assets/warning-icon.svg similarity index 100% rename from src/client/assets/warning-icon.svg rename to src/assets/warning-icon.svg diff --git a/src/client/ui/ProjectsPage.js b/src/client/ui/ProjectsPage.js deleted file mode 100644 index 2dcff9c48..000000000 --- a/src/client/ui/ProjectsPage.js +++ /dev/null @@ -1,41 +0,0 @@ -import React, { Component } from "react"; -import { Link } from "react-router-dom"; -import PropTypes from "prop-types"; -import { withApi } from "./contexts/ApiContext"; - -class ProjectsPage extends Component { - static propTypes = { - api: PropTypes.object.isRequired - }; - - constructor(props) { - super(props); - - this.state = { - projects: [] - }; - } - - componentDidMount() { - this.props.api.getProjects().then(projects => this.setState({ projects })); - } - - render() { - return ( -
-

Projects

- New Project -
- {this.state.projects.map(project => ( - - -
{project.name}
-
- ))} -
-
- ); - } -} - -export default withApi(ProjectsPage); diff --git a/src/client/ui/viewport/Viewport.js b/src/client/ui/viewport/Viewport.js deleted file mode 100644 index 56e4fe9a0..000000000 --- a/src/client/ui/viewport/Viewport.js +++ /dev/null @@ -1,4 +0,0 @@ -import React from "react"; -import styles from "./Viewport.scss"; - -export default React.forwardRef((props, ref) => ); diff --git a/src/client/config.js b/src/config.js similarity index 100% rename from src/client/config.js rename to src/config.js diff --git a/src/client/editor/Editor.js b/src/editor/Editor.js similarity index 100% rename from src/client/editor/Editor.js rename to src/editor/Editor.js diff --git a/src/client/editor/History.js b/src/editor/History.js similarity index 100% rename from src/client/editor/History.js rename to src/editor/History.js diff --git a/src/client/editor/MeshCombinationGroup.js b/src/editor/MeshCombinationGroup.js similarity index 100% rename from src/client/editor/MeshCombinationGroup.js rename to src/editor/MeshCombinationGroup.js diff --git a/src/client/editor/StaticMode.js b/src/editor/StaticMode.js similarity index 100% rename from src/client/editor/StaticMode.js rename to src/editor/StaticMode.js diff --git a/src/client/editor/Viewport.js b/src/editor/Viewport.js similarity index 100% rename from src/client/editor/Viewport.js rename to src/editor/Viewport.js diff --git a/src/client/editor/caches/Cache.js b/src/editor/caches/Cache.js similarity index 100% rename from src/client/editor/caches/Cache.js rename to src/editor/caches/Cache.js diff --git a/src/client/editor/caches/GLTFCache.js b/src/editor/caches/GLTFCache.js similarity index 100% rename from src/client/editor/caches/GLTFCache.js rename to src/editor/caches/GLTFCache.js diff --git a/src/client/editor/caches/TextureCache.js b/src/editor/caches/TextureCache.js similarity index 100% rename from src/client/editor/caches/TextureCache.js rename to src/editor/caches/TextureCache.js diff --git a/src/client/editor/commands/AddObjectCommand.js b/src/editor/commands/AddObjectCommand.js similarity index 100% rename from src/client/editor/commands/AddObjectCommand.js rename to src/editor/commands/AddObjectCommand.js diff --git a/src/client/editor/commands/Command.js b/src/editor/commands/Command.js similarity index 100% rename from src/client/editor/commands/Command.js rename to src/editor/commands/Command.js diff --git a/src/client/editor/commands/MoveObjectCommand.js b/src/editor/commands/MoveObjectCommand.js similarity index 100% rename from src/client/editor/commands/MoveObjectCommand.js rename to src/editor/commands/MoveObjectCommand.js diff --git a/src/client/editor/commands/MultiCmdsCommand.js b/src/editor/commands/MultiCmdsCommand.js similarity index 100% rename from src/client/editor/commands/MultiCmdsCommand.js rename to src/editor/commands/MultiCmdsCommand.js diff --git a/src/client/editor/commands/RemoveObjectCommand.js b/src/editor/commands/RemoveObjectCommand.js similarity index 100% rename from src/client/editor/commands/RemoveObjectCommand.js rename to src/editor/commands/RemoveObjectCommand.js diff --git a/src/client/editor/commands/SetObjectPropertyCommand.js b/src/editor/commands/SetObjectPropertyCommand.js similarity index 100% rename from src/client/editor/commands/SetObjectPropertyCommand.js rename to src/editor/commands/SetObjectPropertyCommand.js diff --git a/src/client/editor/commands/SetPositionCommand.js b/src/editor/commands/SetPositionCommand.js similarity index 100% rename from src/client/editor/commands/SetPositionCommand.js rename to src/editor/commands/SetPositionCommand.js diff --git a/src/client/editor/commands/SetRotationCommand.js b/src/editor/commands/SetRotationCommand.js similarity index 100% rename from src/client/editor/commands/SetRotationCommand.js rename to src/editor/commands/SetRotationCommand.js diff --git a/src/client/editor/commands/SetScaleCommand.js b/src/editor/commands/SetScaleCommand.js similarity index 100% rename from src/client/editor/commands/SetScaleCommand.js rename to src/editor/commands/SetScaleCommand.js diff --git a/src/client/editor/controls/SpokeTransformControls.js b/src/editor/controls/SpokeTransformControls.js similarity index 100% rename from src/client/editor/controls/SpokeTransformControls.js rename to src/editor/controls/SpokeTransformControls.js diff --git a/src/client/editor/helpers/GridHelper.js b/src/editor/helpers/GridHelper.js similarity index 100% rename from src/client/editor/helpers/GridHelper.js rename to src/editor/helpers/GridHelper.js diff --git a/src/client/editor/helpers/SpokeDirectionalLightHelper.js b/src/editor/helpers/SpokeDirectionalLightHelper.js similarity index 100% rename from src/client/editor/helpers/SpokeDirectionalLightHelper.js rename to src/editor/helpers/SpokeDirectionalLightHelper.js diff --git a/src/client/editor/helpers/SpokePointLightHelper.js b/src/editor/helpers/SpokePointLightHelper.js similarity index 100% rename from src/client/editor/helpers/SpokePointLightHelper.js rename to src/editor/helpers/SpokePointLightHelper.js diff --git a/src/client/editor/helpers/SpokeSpotLightHelper.js b/src/editor/helpers/SpokeSpotLightHelper.js similarity index 100% rename from src/client/editor/helpers/SpokeSpotLightHelper.js rename to src/editor/helpers/SpokeSpotLightHelper.js diff --git a/src/client/editor/helpers/utils.js b/src/editor/helpers/utils.js similarity index 100% rename from src/client/editor/helpers/utils.js rename to src/editor/helpers/utils.js diff --git a/src/client/editor/nodes/AmbientLightNode.js b/src/editor/nodes/AmbientLightNode.js similarity index 100% rename from src/client/editor/nodes/AmbientLightNode.js rename to src/editor/nodes/AmbientLightNode.js diff --git a/src/client/editor/nodes/BoxColliderNode.js b/src/editor/nodes/BoxColliderNode.js similarity index 100% rename from src/client/editor/nodes/BoxColliderNode.js rename to src/editor/nodes/BoxColliderNode.js diff --git a/src/client/editor/nodes/DirectionalLightNode.js b/src/editor/nodes/DirectionalLightNode.js similarity index 100% rename from src/client/editor/nodes/DirectionalLightNode.js rename to src/editor/nodes/DirectionalLightNode.js diff --git a/src/client/editor/nodes/EditorNodeMixin.js b/src/editor/nodes/EditorNodeMixin.js similarity index 100% rename from src/client/editor/nodes/EditorNodeMixin.js rename to src/editor/nodes/EditorNodeMixin.js diff --git a/src/client/editor/nodes/FloorPlanNode.js b/src/editor/nodes/FloorPlanNode.js similarity index 100% rename from src/client/editor/nodes/FloorPlanNode.js rename to src/editor/nodes/FloorPlanNode.js diff --git a/src/client/editor/nodes/GroundPlaneNode.js b/src/editor/nodes/GroundPlaneNode.js similarity index 100% rename from src/client/editor/nodes/GroundPlaneNode.js rename to src/editor/nodes/GroundPlaneNode.js diff --git a/src/client/editor/nodes/GroupNode.js b/src/editor/nodes/GroupNode.js similarity index 100% rename from src/client/editor/nodes/GroupNode.js rename to src/editor/nodes/GroupNode.js diff --git a/src/client/editor/nodes/HemisphereLightNode.js b/src/editor/nodes/HemisphereLightNode.js similarity index 100% rename from src/client/editor/nodes/HemisphereLightNode.js rename to src/editor/nodes/HemisphereLightNode.js diff --git a/src/client/editor/nodes/ImageNode.js b/src/editor/nodes/ImageNode.js similarity index 100% rename from src/client/editor/nodes/ImageNode.js rename to src/editor/nodes/ImageNode.js diff --git a/src/client/editor/nodes/ModelNode.js b/src/editor/nodes/ModelNode.js similarity index 100% rename from src/client/editor/nodes/ModelNode.js rename to src/editor/nodes/ModelNode.js diff --git a/src/client/editor/nodes/PointLightNode.js b/src/editor/nodes/PointLightNode.js similarity index 100% rename from src/client/editor/nodes/PointLightNode.js rename to src/editor/nodes/PointLightNode.js diff --git a/src/client/editor/nodes/SceneNode.js b/src/editor/nodes/SceneNode.js similarity index 100% rename from src/client/editor/nodes/SceneNode.js rename to src/editor/nodes/SceneNode.js diff --git a/src/client/editor/nodes/SkyboxNode.js b/src/editor/nodes/SkyboxNode.js similarity index 100% rename from src/client/editor/nodes/SkyboxNode.js rename to src/editor/nodes/SkyboxNode.js diff --git a/src/client/editor/nodes/SpawnPointNode.js b/src/editor/nodes/SpawnPointNode.js similarity index 100% rename from src/client/editor/nodes/SpawnPointNode.js rename to src/editor/nodes/SpawnPointNode.js diff --git a/src/client/editor/nodes/SpawnerNode.js b/src/editor/nodes/SpawnerNode.js similarity index 100% rename from src/client/editor/nodes/SpawnerNode.js rename to src/editor/nodes/SpawnerNode.js diff --git a/src/client/editor/nodes/SpotLightNode.js b/src/editor/nodes/SpotLightNode.js similarity index 100% rename from src/client/editor/nodes/SpotLightNode.js rename to src/editor/nodes/SpotLightNode.js diff --git a/src/client/editor/nodes/TriggerVolumeNode.js b/src/editor/nodes/TriggerVolumeNode.js similarity index 100% rename from src/client/editor/nodes/TriggerVolumeNode.js rename to src/editor/nodes/TriggerVolumeNode.js diff --git a/src/client/editor/nodes/VideoNode.js b/src/editor/nodes/VideoNode.js similarity index 100% rename from src/client/editor/nodes/VideoNode.js rename to src/editor/nodes/VideoNode.js diff --git a/src/client/editor/objects/FloorPlan.js b/src/editor/objects/FloorPlan.js similarity index 100% rename from src/client/editor/objects/FloorPlan.js rename to src/editor/objects/FloorPlan.js diff --git a/src/client/editor/objects/GroundPlane.js b/src/editor/objects/GroundPlane.js similarity index 100% rename from src/client/editor/objects/GroundPlane.js rename to src/editor/objects/GroundPlane.js diff --git a/src/client/editor/objects/Image.js b/src/editor/objects/Image.js similarity index 100% rename from src/client/editor/objects/Image.js rename to src/editor/objects/Image.js diff --git a/src/client/editor/objects/Model.js b/src/editor/objects/Model.js similarity index 100% rename from src/client/editor/objects/Model.js rename to src/editor/objects/Model.js diff --git a/src/client/editor/objects/PhysicalDirectionalLight.js b/src/editor/objects/PhysicalDirectionalLight.js similarity index 100% rename from src/client/editor/objects/PhysicalDirectionalLight.js rename to src/editor/objects/PhysicalDirectionalLight.js diff --git a/src/client/editor/objects/PhysicalHemisphereLight.js b/src/editor/objects/PhysicalHemisphereLight.js similarity index 100% rename from src/client/editor/objects/PhysicalHemisphereLight.js rename to src/editor/objects/PhysicalHemisphereLight.js diff --git a/src/client/editor/objects/PhysicalPointLight.js b/src/editor/objects/PhysicalPointLight.js similarity index 100% rename from src/client/editor/objects/PhysicalPointLight.js rename to src/editor/objects/PhysicalPointLight.js diff --git a/src/client/editor/objects/PhysicalSpotLight.js b/src/editor/objects/PhysicalSpotLight.js similarity index 100% rename from src/client/editor/objects/PhysicalSpotLight.js rename to src/editor/objects/PhysicalSpotLight.js diff --git a/src/client/editor/objects/Sky.js b/src/editor/objects/Sky.js similarity index 100% rename from src/client/editor/objects/Sky.js rename to src/editor/objects/Sky.js diff --git a/src/client/editor/objects/Video.js b/src/editor/objects/Video.js similarity index 100% rename from src/client/editor/objects/Video.js rename to src/editor/objects/Video.js diff --git a/src/client/editor/recast/recast.js b/src/editor/recast/recast.js similarity index 100% rename from src/client/editor/recast/recast.js rename to src/editor/recast/recast.js diff --git a/src/client/editor/recast/recast.wasm b/src/editor/recast/recast.wasm similarity index 100% rename from src/client/editor/recast/recast.wasm rename to src/editor/recast/recast.wasm diff --git a/src/client/editor/renderer/OutlinePass.js b/src/editor/renderer/OutlinePass.js similarity index 100% rename from src/client/editor/renderer/OutlinePass.js rename to src/editor/renderer/OutlinePass.js diff --git a/src/client/editor/utils/asyncTraverse.js b/src/editor/utils/asyncTraverse.js similarity index 100% rename from src/client/editor/utils/asyncTraverse.js rename to src/editor/utils/asyncTraverse.js diff --git a/src/client/editor/utils/cloneObject3D.js b/src/editor/utils/cloneObject3D.js similarity index 100% rename from src/client/editor/utils/cloneObject3D.js rename to src/editor/utils/cloneObject3D.js diff --git a/src/client/editor/utils/createShadowMapResolutionProxy.js b/src/editor/utils/createShadowMapResolutionProxy.js similarity index 100% rename from src/client/editor/utils/createShadowMapResolutionProxy.js rename to src/editor/utils/createShadowMapResolutionProxy.js diff --git a/src/client/editor/utils/eventToMessage.js b/src/editor/utils/eventToMessage.js similarity index 100% rename from src/client/editor/utils/eventToMessage.js rename to src/editor/utils/eventToMessage.js diff --git a/src/client/editor/utils/getNodeWithUUID.js b/src/editor/utils/getNodeWithUUID.js similarity index 100% rename from src/client/editor/utils/getNodeWithUUID.js rename to src/editor/utils/getNodeWithUUID.js diff --git a/src/client/editor/utils/hashImage.js b/src/editor/utils/hashImage.js similarity index 100% rename from src/client/editor/utils/hashImage.js rename to src/editor/utils/hashImage.js diff --git a/src/client/editor/utils/isEmptyObject.js b/src/editor/utils/isEmptyObject.js similarity index 100% rename from src/client/editor/utils/isEmptyObject.js rename to src/editor/utils/isEmptyObject.js diff --git a/src/client/editor/utils/keysEqual.js b/src/editor/utils/keysEqual.js similarity index 100% rename from src/client/editor/utils/keysEqual.js rename to src/editor/utils/keysEqual.js diff --git a/src/client/editor/utils/makeUniqueName.js b/src/editor/utils/makeUniqueName.js similarity index 100% rename from src/client/editor/utils/makeUniqueName.js rename to src/editor/utils/makeUniqueName.js diff --git a/src/client/editor/utils/resizeShadowCameraFrustum.js b/src/editor/utils/resizeShadowCameraFrustum.js similarity index 100% rename from src/client/editor/utils/resizeShadowCameraFrustum.js rename to src/editor/utils/resizeShadowCameraFrustum.js diff --git a/src/client/editor/utils/serializeColor.js b/src/editor/utils/serializeColor.js similarity index 100% rename from src/client/editor/utils/serializeColor.js rename to src/editor/utils/serializeColor.js diff --git a/src/client/editor/utils/sortEntities.js b/src/editor/utils/sortEntities.js similarity index 100% rename from src/client/editor/utils/sortEntities.js rename to src/editor/utils/sortEntities.js diff --git a/src/client/index.js b/src/index.js similarity index 100% rename from src/client/index.js rename to src/index.js diff --git a/src/server/Server.js b/src/server/Server.js deleted file mode 100644 index 1bce65e73..000000000 --- a/src/server/Server.js +++ /dev/null @@ -1,222 +0,0 @@ -const fs = require("fs-extra"); -const http = require("http"); -const https = require("https"); -const Koa = require("koa"); -const koaBody = require("koa-body"); -const mount = require("koa-mount"); -const path = require("path"); -const Router = require("koa-router"); -const selfsigned = require("selfsigned"); -const serve = require("koa-static"); -const rewrite = require("koa-rewrite"); -const glob = require("glob-promise"); -const os = require("os"); - -function getProjectFile(projectPath) { - return path.join(projectPath, "spoke-project.json"); -} - -function isExistingProjectPath(path) { - return fs.existsSync(getProjectFile(path)); -} - -async function startServer(projectPath, options = {}) { - if (!projectPath) { - for (const potentialProjectPathName of ["Spoke", "Spoke Scenes"]) { - const potentialProjectPath = path.join(os.homedir(), potentialProjectPathName); - if (!fs.existsSync(potentialProjectPath) || isExistingProjectPath(potentialProjectPath)) { - projectPath = potentialProjectPath; - break; - } - } - if (projectPath === null) { - throw new Error("Default directory is unavailable. Please specify a directory."); - } - } - - const opts = Object.assign( - { - host: "localhost", - port: 9090, - https: false - }, - options - ); - - let port = opts.port; - - await fs.ensureDir(projectPath); - - const projectFilePath = path.join(projectPath, "spoke-project.json"); - - if (!fs.existsSync(projectFilePath)) { - await fs.writeJSON(projectFilePath, {}); - } - - const app = new Koa(); - - let server; - - const requestHandler = app.callback(); - - if (opts.https) { - if (!fs.existsSync(".certs/key.pem")) { - console.log("Creating selfsigned certs"); - const cert = selfsigned.generate(); - await fs.ensureDir(".certs"); - fs.writeFileSync(path.join(".certs", "key.pem"), cert.private); - fs.writeFileSync(path.join(".certs", "cert.pem"), cert.cert); - } - server = https.createServer( - { - key: fs.readFileSync(path.join(".certs", "key.pem")), - cert: fs.readFileSync(path.join(".certs", "cert.pem")) - }, - requestHandler - ); - } else { - server = http.createServer(requestHandler); - } - - app.use(rewrite(/^\/projects/, "/")); - - if (opts.publicPath || process.env.NODE_ENV !== "development") { - app.use(serve(opts.publicPath || path.join(__dirname, "..", "..", "public"))); - } else { - console.log("Running in development environment"); - - const logger = require("koa-logger"); - app.use(logger()); - - app.use(async (ctx, next) => { - try { - await next(); - } catch (err) { - ctx.status = err.status || 500; - ctx.body = err.message; - ctx.app.emit("error", err, ctx); - } - }); - - const koaWebpack = require("koa-webpack"); - const webpack = require("webpack"); - const config = require("../../webpack.config.js"); - const compiler = webpack(config); - - try { - const devMiddleware = await koaWebpack({ - compiler, - // devMiddleware: { - // mimeTypes: { "application/wasm": ["wasm"] } - // }, - hotClient: false - }); - app.use(devMiddleware); - } catch (e) { - throw e; - } - } - - const router = new Router(); - - app.use( - mount( - "/api/files/", - serve(projectPath, { - hidden: true, - setHeaders: res => { - res.setHeader("Access-Control-Allow-Origin", "*"); - } - }) - ) - ); - - router.post("/api/files/:filePath*", koaBody({ multipart: true, text: false }), async ctx => { - const filePath = ctx.params.filePath ? path.resolve(projectPath, ctx.params.filePath) : projectPath; - - // If uploading as text body, write it to filePath using the stream API. - const writeStream = fs.createWriteStream(filePath, { flags: "w" }); - - ctx.req.pipe(writeStream); - - await new Promise((resolve, reject) => { - function cleanUp() { - writeStream.removeListener("finish", onFinish); - writeStream.removeListener("error", onError); - } - - function onFinish() { - cleanUp(); - resolve(); - } - - function onError(err) { - cleanUp(); - reject(err); - } - - writeStream.on("finish", onFinish); - writeStream.on("error", onError); - }); - - ctx.body = { - success: true - }; - }); - - router.get("/api/projects", async ctx => { - const paths = await glob(path.join(projectPath, "**/*.spoke")); - - ctx.body = paths.map(absolutePath => { - const url = absolutePath - .replace(projectPath, "/projects") - .replace(/\\/g, "/") - .replace(".spoke", ""); - - const name = url.split("/").pop(); - - return { - name, - thumbnail: null, - url - }; - }); - }); - - app.use(router.routes()); - app.use(router.allowedMethods()); - - const maxPortTries = 20; - let portTryCount = 0; - server.on("error", e => { - console.log("Server Error", e.toString()); - if (e.code === "EADDRINUSE") { - server.close(); - if (portTryCount > maxPortTries) { - console.log("Could not find a free port. Exiting."); - process.exit(1); - } - port++; - portTryCount++; - server.listen(port, opts.host); - } - }); - - server.on("close", e => { - console.log("Server Closed", e ? e : ""); - }); - - server.on("listening", () => { - const protocol = opts.https ? "https" : "http"; - const url = `${protocol}://localhost:${port}`; - console.log(`Server running at ${url}\n`); - }); - - server.listen(opts.port, opts.host); - - return server; -} - -module.exports = { - startServer -}; diff --git a/src/server/index.js b/src/server/index.js deleted file mode 100644 index 99a2ad1fa..000000000 --- a/src/server/index.js +++ /dev/null @@ -1,5 +0,0 @@ -const { startServer } = require("./Server"); - -startServer().catch(error => { - console.error(error); -}); diff --git a/src/client/ui/App.js b/src/ui/App.js similarity index 100% rename from src/client/ui/App.js rename to src/ui/App.js diff --git a/src/client/ui/AuthPage.js b/src/ui/AuthPage.js similarity index 87% rename from src/client/ui/AuthPage.js rename to src/ui/AuthPage.js index 2632efb44..266b8d2d0 100644 --- a/src/client/ui/AuthPage.js +++ b/src/ui/AuthPage.js @@ -19,7 +19,8 @@ class AuthPage extends Component { render() { if (this.state.redirectToReferrer) { - const from = this.props.location.state.from || "/projects"; + const location = this.props.location; + const from = location.state ? location.state.from : "/projects"; return ; } diff --git a/src/client/ui/EditorPage.js b/src/ui/EditorPage.js similarity index 98% rename from src/client/ui/EditorPage.js rename to src/ui/EditorPage.js index e82b5683c..61cddf93f 100644 --- a/src/client/ui/EditorPage.js +++ b/src/ui/EditorPage.js @@ -413,7 +413,13 @@ class EditorPage extends Component { try { const { project } = await this.props.api.getProject(projectId); - await this.state.editor.loadProject(project); + + if (!project) { + this.state.editor.loadNewScene(); + } else { + await this.state.editor.loadProject(project); + } + this.hideDialog(); } catch (e) { console.error(e); diff --git a/src/client/ui/LandingPage.js b/src/ui/LandingPage.js similarity index 100% rename from src/client/ui/LandingPage.js rename to src/ui/LandingPage.js diff --git a/src/ui/ProjectsPage.js b/src/ui/ProjectsPage.js new file mode 100644 index 000000000..179c9c681 --- /dev/null +++ b/src/ui/ProjectsPage.js @@ -0,0 +1,52 @@ +import React, { Component } from "react"; +import { Link } from "react-router-dom"; +import PropTypes from "prop-types"; +import { withApi } from "./contexts/ApiContext"; + +class ProjectsPage extends Component { + static propTypes = { + api: PropTypes.object.isRequired + }; + + constructor(props) { + super(props); + + this.state = { + projects: [], + error: null + }; + } + + componentDidMount() { + this.props.api + .getProjects() + .then(projects => this.setState({ projects })) + .catch(error => { + console.error(error); + this.setState({ error }); + }); + } + + render() { + const { error, projects } = this.state; + + return ( +
+

Projects

+ New Project +
+ {error + ? error.message || "There was an unknown error." + : projects.map(project => ( + + +
{project.name}
+ + ))} +
+
+ ); + } +} + +export default withApi(ProjectsPage); diff --git a/src/client/ui/contexts/ApiContext.js b/src/ui/contexts/ApiContext.js similarity index 67% rename from src/client/ui/contexts/ApiContext.js rename to src/ui/contexts/ApiContext.js index 92fee97a9..fe559cd5b 100644 --- a/src/client/ui/contexts/ApiContext.js +++ b/src/ui/contexts/ApiContext.js @@ -6,6 +6,6 @@ export const ApiContextProvider = ApiContext.Provider; export function withApi(Component) { return function ApiContextComponent(props) { - return {context => }; + return {api => }; }; } diff --git a/src/client/ui/contexts/DialogContext.js b/src/ui/contexts/DialogContext.js similarity index 100% rename from src/client/ui/contexts/DialogContext.js rename to src/ui/contexts/DialogContext.js diff --git a/src/client/ui/contexts/EditorContext.js b/src/ui/contexts/EditorContext.js similarity index 100% rename from src/client/ui/contexts/EditorContext.js rename to src/ui/contexts/EditorContext.js diff --git a/src/client/ui/contexts/SettingsContext.js b/src/ui/contexts/SettingsContext.js similarity index 100% rename from src/client/ui/contexts/SettingsContext.js rename to src/ui/contexts/SettingsContext.js diff --git a/src/client/ui/dialogs/AddMediaDialog.js b/src/ui/dialogs/AddMediaDialog.js similarity index 100% rename from src/client/ui/dialogs/AddMediaDialog.js rename to src/ui/dialogs/AddMediaDialog.js diff --git a/src/client/ui/dialogs/AddModelDialog.js b/src/ui/dialogs/AddModelDialog.js similarity index 100% rename from src/client/ui/dialogs/AddModelDialog.js rename to src/ui/dialogs/AddModelDialog.js diff --git a/src/client/ui/dialogs/ButtonSelectDialog.js b/src/ui/dialogs/ButtonSelectDialog.js similarity index 100% rename from src/client/ui/dialogs/ButtonSelectDialog.js rename to src/ui/dialogs/ButtonSelectDialog.js diff --git a/src/client/ui/dialogs/ConfirmDialog.js b/src/ui/dialogs/ConfirmDialog.js similarity index 100% rename from src/client/ui/dialogs/ConfirmDialog.js rename to src/ui/dialogs/ConfirmDialog.js diff --git a/src/client/ui/dialogs/DialogHeader.js b/src/ui/dialogs/DialogHeader.js similarity index 100% rename from src/client/ui/dialogs/DialogHeader.js rename to src/ui/dialogs/DialogHeader.js diff --git a/src/client/ui/dialogs/DialogHeader.scss b/src/ui/dialogs/DialogHeader.scss similarity index 100% rename from src/client/ui/dialogs/DialogHeader.scss rename to src/ui/dialogs/DialogHeader.scss diff --git a/src/client/ui/dialogs/ErrorDialog.js b/src/ui/dialogs/ErrorDialog.js similarity index 100% rename from src/client/ui/dialogs/ErrorDialog.js rename to src/ui/dialogs/ErrorDialog.js diff --git a/src/client/ui/dialogs/OptionDialog.js b/src/ui/dialogs/OptionDialog.js similarity index 100% rename from src/client/ui/dialogs/OptionDialog.js rename to src/ui/dialogs/OptionDialog.js diff --git a/src/client/ui/dialogs/ProgressDialog.js b/src/ui/dialogs/ProgressDialog.js similarity index 100% rename from src/client/ui/dialogs/ProgressDialog.js rename to src/ui/dialogs/ProgressDialog.js diff --git a/src/client/ui/dialogs/dialog.scss b/src/ui/dialogs/dialog.scss similarity index 100% rename from src/client/ui/dialogs/dialog.scss rename to src/ui/dialogs/dialog.scss diff --git a/src/client/ui/hierarchy/HierarchyPanelContainer.js b/src/ui/hierarchy/HierarchyPanelContainer.js similarity index 100% rename from src/client/ui/hierarchy/HierarchyPanelContainer.js rename to src/ui/hierarchy/HierarchyPanelContainer.js diff --git a/src/client/ui/hierarchy/HierarchyPanelContainer.scss b/src/ui/hierarchy/HierarchyPanelContainer.scss similarity index 100% rename from src/client/ui/hierarchy/HierarchyPanelContainer.scss rename to src/ui/hierarchy/HierarchyPanelContainer.scss diff --git a/src/client/ui/inputs/BooleanInput.js b/src/ui/inputs/BooleanInput.js similarity index 100% rename from src/client/ui/inputs/BooleanInput.js rename to src/ui/inputs/BooleanInput.js diff --git a/src/client/ui/inputs/BooleanInput.scss b/src/ui/inputs/BooleanInput.scss similarity index 100% rename from src/client/ui/inputs/BooleanInput.scss rename to src/ui/inputs/BooleanInput.scss diff --git a/src/client/ui/inputs/Button.js b/src/ui/inputs/Button.js similarity index 100% rename from src/client/ui/inputs/Button.js rename to src/ui/inputs/Button.js diff --git a/src/client/ui/inputs/Button.scss b/src/ui/inputs/Button.scss similarity index 100% rename from src/client/ui/inputs/Button.scss rename to src/ui/inputs/Button.scss diff --git a/src/client/ui/inputs/ColorInput.js b/src/ui/inputs/ColorInput.js similarity index 100% rename from src/client/ui/inputs/ColorInput.js rename to src/ui/inputs/ColorInput.js diff --git a/src/client/ui/inputs/ColorInput.scss b/src/ui/inputs/ColorInput.scss similarity index 100% rename from src/client/ui/inputs/ColorInput.scss rename to src/ui/inputs/ColorInput.scss diff --git a/src/client/ui/inputs/CompoundNumericInput.js b/src/ui/inputs/CompoundNumericInput.js similarity index 100% rename from src/client/ui/inputs/CompoundNumericInput.js rename to src/ui/inputs/CompoundNumericInput.js diff --git a/src/client/ui/inputs/CompoundNumericInput.scss b/src/ui/inputs/CompoundNumericInput.scss similarity index 100% rename from src/client/ui/inputs/CompoundNumericInput.scss rename to src/ui/inputs/CompoundNumericInput.scss diff --git a/src/client/ui/inputs/EulerInput.js b/src/ui/inputs/EulerInput.js similarity index 100% rename from src/client/ui/inputs/EulerInput.js rename to src/ui/inputs/EulerInput.js diff --git a/src/client/ui/inputs/InputGroup.js b/src/ui/inputs/InputGroup.js similarity index 100% rename from src/client/ui/inputs/InputGroup.js rename to src/ui/inputs/InputGroup.js diff --git a/src/client/ui/inputs/InputGroup.scss b/src/ui/inputs/InputGroup.scss similarity index 100% rename from src/client/ui/inputs/InputGroup.scss rename to src/ui/inputs/InputGroup.scss diff --git a/src/client/ui/inputs/NumericInput.js b/src/ui/inputs/NumericInput.js similarity index 100% rename from src/client/ui/inputs/NumericInput.js rename to src/ui/inputs/NumericInput.js diff --git a/src/client/ui/inputs/NumericInput.scss b/src/ui/inputs/NumericInput.scss similarity index 100% rename from src/client/ui/inputs/NumericInput.scss rename to src/ui/inputs/NumericInput.scss diff --git a/src/client/ui/inputs/SelectInput.js b/src/ui/inputs/SelectInput.js similarity index 100% rename from src/client/ui/inputs/SelectInput.js rename to src/ui/inputs/SelectInput.js diff --git a/src/client/ui/inputs/SelectInput.scss b/src/ui/inputs/SelectInput.scss similarity index 100% rename from src/client/ui/inputs/SelectInput.scss rename to src/ui/inputs/SelectInput.scss diff --git a/src/client/ui/inputs/StringInput.js b/src/ui/inputs/StringInput.js similarity index 94% rename from src/client/ui/inputs/StringInput.js rename to src/ui/inputs/StringInput.js index fda7297a2..ddd9525b9 100644 --- a/src/client/ui/inputs/StringInput.js +++ b/src/ui/inputs/StringInput.js @@ -8,6 +8,8 @@ const StringInput = React.forwardRef(({ className, onChange, ...rest }, ref) => return onChange(e.target.value, e)} className={fullClassName} />; }); +StringInput.displayName = "StringInput"; + StringInput.defaultProps = { value: "", onChange: () => {}, diff --git a/src/client/ui/inputs/StringInput.scss b/src/ui/inputs/StringInput.scss similarity index 100% rename from src/client/ui/inputs/StringInput.scss rename to src/ui/inputs/StringInput.scss diff --git a/src/client/ui/inputs/Vector3Input.js b/src/ui/inputs/Vector3Input.js similarity index 100% rename from src/client/ui/inputs/Vector3Input.js rename to src/ui/inputs/Vector3Input.js diff --git a/src/client/ui/inputs/Vector3Input.scss b/src/ui/inputs/Vector3Input.scss similarity index 100% rename from src/client/ui/inputs/Vector3Input.scss rename to src/ui/inputs/Vector3Input.scss diff --git a/src/client/ui/properties/AmbientLightNodeEditor.js b/src/ui/properties/AmbientLightNodeEditor.js similarity index 100% rename from src/client/ui/properties/AmbientLightNodeEditor.js rename to src/ui/properties/AmbientLightNodeEditor.js diff --git a/src/client/ui/properties/BoxColliderNodeEditor.js b/src/ui/properties/BoxColliderNodeEditor.js similarity index 100% rename from src/client/ui/properties/BoxColliderNodeEditor.js rename to src/ui/properties/BoxColliderNodeEditor.js diff --git a/src/client/ui/properties/DefaultNodeEditor.js b/src/ui/properties/DefaultNodeEditor.js similarity index 100% rename from src/client/ui/properties/DefaultNodeEditor.js rename to src/ui/properties/DefaultNodeEditor.js diff --git a/src/client/ui/properties/DirectionalLightNodeEditor.js b/src/ui/properties/DirectionalLightNodeEditor.js similarity index 100% rename from src/client/ui/properties/DirectionalLightNodeEditor.js rename to src/ui/properties/DirectionalLightNodeEditor.js diff --git a/src/client/ui/properties/FloorPlanNodeEditor.js b/src/ui/properties/FloorPlanNodeEditor.js similarity index 100% rename from src/client/ui/properties/FloorPlanNodeEditor.js rename to src/ui/properties/FloorPlanNodeEditor.js diff --git a/src/client/ui/properties/FloorPlanNodeEditor.scss b/src/ui/properties/FloorPlanNodeEditor.scss similarity index 100% rename from src/client/ui/properties/FloorPlanNodeEditor.scss rename to src/ui/properties/FloorPlanNodeEditor.scss diff --git a/src/client/ui/properties/GroundPlaneNodeEditor.js b/src/ui/properties/GroundPlaneNodeEditor.js similarity index 100% rename from src/client/ui/properties/GroundPlaneNodeEditor.js rename to src/ui/properties/GroundPlaneNodeEditor.js diff --git a/src/client/ui/properties/GroupNodeEditor.js b/src/ui/properties/GroupNodeEditor.js similarity index 100% rename from src/client/ui/properties/GroupNodeEditor.js rename to src/ui/properties/GroupNodeEditor.js diff --git a/src/client/ui/properties/HemisphereLightNodeEditor.js b/src/ui/properties/HemisphereLightNodeEditor.js similarity index 100% rename from src/client/ui/properties/HemisphereLightNodeEditor.js rename to src/ui/properties/HemisphereLightNodeEditor.js diff --git a/src/client/ui/properties/ImageNodeEditor.js b/src/ui/properties/ImageNodeEditor.js similarity index 100% rename from src/client/ui/properties/ImageNodeEditor.js rename to src/ui/properties/ImageNodeEditor.js diff --git a/src/client/ui/properties/LightShadowProperties.js b/src/ui/properties/LightShadowProperties.js similarity index 100% rename from src/client/ui/properties/LightShadowProperties.js rename to src/ui/properties/LightShadowProperties.js diff --git a/src/client/ui/properties/ModelNodeEditor.js b/src/ui/properties/ModelNodeEditor.js similarity index 100% rename from src/client/ui/properties/ModelNodeEditor.js rename to src/ui/properties/ModelNodeEditor.js diff --git a/src/client/ui/properties/NameInputGroup.js b/src/ui/properties/NameInputGroup.js similarity index 100% rename from src/client/ui/properties/NameInputGroup.js rename to src/ui/properties/NameInputGroup.js diff --git a/src/client/ui/properties/NodeEditor.js b/src/ui/properties/NodeEditor.js similarity index 100% rename from src/client/ui/properties/NodeEditor.js rename to src/ui/properties/NodeEditor.js diff --git a/src/client/ui/properties/PointLightNodeEditor.js b/src/ui/properties/PointLightNodeEditor.js similarity index 100% rename from src/client/ui/properties/PointLightNodeEditor.js rename to src/ui/properties/PointLightNodeEditor.js diff --git a/src/client/ui/properties/PropertiesPanelContainer.js b/src/ui/properties/PropertiesPanelContainer.js similarity index 100% rename from src/client/ui/properties/PropertiesPanelContainer.js rename to src/ui/properties/PropertiesPanelContainer.js diff --git a/src/client/ui/properties/PropertiesPanelContainer.scss b/src/ui/properties/PropertiesPanelContainer.scss similarity index 100% rename from src/client/ui/properties/PropertiesPanelContainer.scss rename to src/ui/properties/PropertiesPanelContainer.scss diff --git a/src/client/ui/properties/PropertyGroup.js b/src/ui/properties/PropertyGroup.js similarity index 100% rename from src/client/ui/properties/PropertyGroup.js rename to src/ui/properties/PropertyGroup.js diff --git a/src/client/ui/properties/PropertyGroup.scss b/src/ui/properties/PropertyGroup.scss similarity index 100% rename from src/client/ui/properties/PropertyGroup.scss rename to src/ui/properties/PropertyGroup.scss diff --git a/src/client/ui/properties/SceneNodeEditor.js b/src/ui/properties/SceneNodeEditor.js similarity index 100% rename from src/client/ui/properties/SceneNodeEditor.js rename to src/ui/properties/SceneNodeEditor.js diff --git a/src/client/ui/properties/SkyboxNodeEditor.js b/src/ui/properties/SkyboxNodeEditor.js similarity index 100% rename from src/client/ui/properties/SkyboxNodeEditor.js rename to src/ui/properties/SkyboxNodeEditor.js diff --git a/src/client/ui/properties/SpawnPointNodeEditor.js b/src/ui/properties/SpawnPointNodeEditor.js similarity index 100% rename from src/client/ui/properties/SpawnPointNodeEditor.js rename to src/ui/properties/SpawnPointNodeEditor.js diff --git a/src/client/ui/properties/SpawnerNodeEditor.js b/src/ui/properties/SpawnerNodeEditor.js similarity index 100% rename from src/client/ui/properties/SpawnerNodeEditor.js rename to src/ui/properties/SpawnerNodeEditor.js diff --git a/src/client/ui/properties/SpotLightNodeEditor.js b/src/ui/properties/SpotLightNodeEditor.js similarity index 100% rename from src/client/ui/properties/SpotLightNodeEditor.js rename to src/ui/properties/SpotLightNodeEditor.js diff --git a/src/client/ui/properties/TransformPropertyGroup.js b/src/ui/properties/TransformPropertyGroup.js similarity index 100% rename from src/client/ui/properties/TransformPropertyGroup.js rename to src/ui/properties/TransformPropertyGroup.js diff --git a/src/client/ui/properties/TriggerVolumeNodeEditor.js b/src/ui/properties/TriggerVolumeNodeEditor.js similarity index 100% rename from src/client/ui/properties/TriggerVolumeNodeEditor.js rename to src/ui/properties/TriggerVolumeNodeEditor.js diff --git a/src/client/ui/properties/VideoNodeEditor.js b/src/ui/properties/VideoNodeEditor.js similarity index 100% rename from src/client/ui/properties/VideoNodeEditor.js rename to src/ui/properties/VideoNodeEditor.js diff --git a/src/client/ui/routes/AuthenticatedRoute.js b/src/ui/routes/AuthenticatedRoute.js similarity index 100% rename from src/client/ui/routes/AuthenticatedRoute.js rename to src/ui/routes/AuthenticatedRoute.js diff --git a/src/client/ui/styles/common.scss b/src/ui/styles/common.scss similarity index 100% rename from src/client/ui/styles/common.scss rename to src/ui/styles/common.scss diff --git a/src/client/ui/styles/global.scss b/src/ui/styles/global.scss similarity index 100% rename from src/client/ui/styles/global.scss rename to src/ui/styles/global.scss diff --git a/src/client/ui/styles/icons.scss b/src/ui/styles/icons.scss similarity index 100% rename from src/client/ui/styles/icons.scss rename to src/ui/styles/icons.scss diff --git a/src/client/ui/styles/theme.scss b/src/ui/styles/theme.scss similarity index 100% rename from src/client/ui/styles/theme.scss rename to src/ui/styles/theme.scss diff --git a/src/client/ui/styles/vendor/react-contextmenu/index.scss b/src/ui/styles/vendor/react-contextmenu/index.scss similarity index 100% rename from src/client/ui/styles/vendor/react-contextmenu/index.scss rename to src/ui/styles/vendor/react-contextmenu/index.scss diff --git a/src/client/ui/styles/vendor/react-mosaic-component/mixins.scss b/src/ui/styles/vendor/react-mosaic-component/mixins.scss similarity index 100% rename from src/client/ui/styles/vendor/react-mosaic-component/mixins.scss rename to src/ui/styles/vendor/react-mosaic-component/mixins.scss diff --git a/src/client/ui/styles/vendor/react-mosaic-component/mosaic-window.scss b/src/ui/styles/vendor/react-mosaic-component/mosaic-window.scss similarity index 100% rename from src/client/ui/styles/vendor/react-mosaic-component/mosaic-window.scss rename to src/ui/styles/vendor/react-mosaic-component/mosaic-window.scss diff --git a/src/client/ui/styles/vendor/react-mosaic-component/mosaic.scss b/src/ui/styles/vendor/react-mosaic-component/mosaic.scss similarity index 100% rename from src/client/ui/styles/vendor/react-mosaic-component/mosaic.scss rename to src/ui/styles/vendor/react-mosaic-component/mosaic.scss diff --git a/src/client/ui/styles/vendor/react-select/index.scss b/src/ui/styles/vendor/react-select/index.scss similarity index 100% rename from src/client/ui/styles/vendor/react-select/index.scss rename to src/ui/styles/vendor/react-select/index.scss diff --git a/src/client/ui/styles/vendor/react-ui-tree/index.scss b/src/ui/styles/vendor/react-ui-tree/index.scss similarity index 100% rename from src/client/ui/styles/vendor/react-ui-tree/index.scss rename to src/ui/styles/vendor/react-ui-tree/index.scss diff --git a/src/client/ui/toolbar/SnappingDropdown.js b/src/ui/toolbar/SnappingDropdown.js similarity index 100% rename from src/client/ui/toolbar/SnappingDropdown.js rename to src/ui/toolbar/SnappingDropdown.js diff --git a/src/client/ui/toolbar/SnappingDropdown.scss b/src/ui/toolbar/SnappingDropdown.scss similarity index 100% rename from src/client/ui/toolbar/SnappingDropdown.scss rename to src/ui/toolbar/SnappingDropdown.scss diff --git a/src/client/ui/toolbar/ToolBar.js b/src/ui/toolbar/ToolBar.js similarity index 100% rename from src/client/ui/toolbar/ToolBar.js rename to src/ui/toolbar/ToolBar.js diff --git a/src/client/ui/toolbar/ToolBar.scss b/src/ui/toolbar/ToolBar.scss similarity index 100% rename from src/client/ui/toolbar/ToolBar.scss rename to src/ui/toolbar/ToolBar.scss diff --git a/src/client/ui/toolbar/ToolButton.js b/src/ui/toolbar/ToolButton.js similarity index 100% rename from src/client/ui/toolbar/ToolButton.js rename to src/ui/toolbar/ToolButton.js diff --git a/src/client/ui/toolbar/ToolButton.scss b/src/ui/toolbar/ToolButton.scss similarity index 100% rename from src/client/ui/toolbar/ToolButton.scss rename to src/ui/toolbar/ToolButton.scss diff --git a/src/client/ui/toolbar/ToolToggle.js b/src/ui/toolbar/ToolToggle.js similarity index 100% rename from src/client/ui/toolbar/ToolToggle.js rename to src/ui/toolbar/ToolToggle.js diff --git a/src/client/ui/toolbar/ToolToggle.scss b/src/ui/toolbar/ToolToggle.scss similarity index 100% rename from src/client/ui/toolbar/ToolToggle.scss rename to src/ui/toolbar/ToolToggle.scss diff --git a/src/client/ui/viewport/AddNodeActionButtons.js b/src/ui/viewport/AddNodeActionButtons.js similarity index 100% rename from src/client/ui/viewport/AddNodeActionButtons.js rename to src/ui/viewport/AddNodeActionButtons.js diff --git a/src/client/ui/viewport/AddNodeActionButtons.scss b/src/ui/viewport/AddNodeActionButtons.scss similarity index 100% rename from src/client/ui/viewport/AddNodeActionButtons.scss rename to src/ui/viewport/AddNodeActionButtons.scss diff --git a/src/client/ui/viewport/RendererStats.js b/src/ui/viewport/RendererStats.js similarity index 100% rename from src/client/ui/viewport/RendererStats.js rename to src/ui/viewport/RendererStats.js diff --git a/src/client/ui/viewport/RendererStats.scss b/src/ui/viewport/RendererStats.scss similarity index 100% rename from src/client/ui/viewport/RendererStats.scss rename to src/ui/viewport/RendererStats.scss diff --git a/src/ui/viewport/Viewport.js b/src/ui/viewport/Viewport.js new file mode 100644 index 000000000..7a4d32da6 --- /dev/null +++ b/src/ui/viewport/Viewport.js @@ -0,0 +1,8 @@ +import React from "react"; +import styles from "./Viewport.scss"; + +const Viewport = React.forwardRef((props, ref) => ); + +Viewport.displayName = "Viewport"; + +export default Viewport; diff --git a/src/client/ui/viewport/Viewport.scss b/src/ui/viewport/Viewport.scss similarity index 100% rename from src/client/ui/viewport/Viewport.scss rename to src/ui/viewport/Viewport.scss diff --git a/src/client/ui/viewport/ViewportPanelContainer.js b/src/ui/viewport/ViewportPanelContainer.js similarity index 100% rename from src/client/ui/viewport/ViewportPanelContainer.js rename to src/ui/viewport/ViewportPanelContainer.js diff --git a/src/client/ui/viewport/ViewportPanelContainer.scss b/src/ui/viewport/ViewportPanelContainer.scss similarity index 100% rename from src/client/ui/viewport/ViewportPanelContainer.scss rename to src/ui/viewport/ViewportPanelContainer.scss diff --git a/src/client/vendor/TransformControls.js b/src/vendor/TransformControls.js similarity index 100% rename from src/client/vendor/TransformControls.js rename to src/vendor/TransformControls.js diff --git a/src/client/vendor/three.js b/src/vendor/three.js similarity index 100% rename from src/client/vendor/three.js rename to src/vendor/three.js diff --git a/test/integration/tests/Editor.test.js b/test/integration/tests/Editor.test.js index 95fdc4572..d19179381 100644 --- a/test/integration/tests/Editor.test.js +++ b/test/integration/tests/Editor.test.js @@ -1,39 +1,39 @@ -import THREE from "../../../src/client/vendor/three"; -import Project from "../../../src/client/api/Project"; -import Editor from "../../../src/client/editor/Editor"; +import THREE from "../../../src/vendor/three"; +import Api from "../../../src/api/Api"; +import Editor from "../../../src/editor/Editor"; -import SceneNode from "../../../src/client/editor/nodes/SceneNode"; -import SceneNodeEditor from "../../../src/client/ui/properties/SceneNodeEditor"; -import GroupNode from "../../../src/client/editor/nodes/GroupNode"; -import GroupNodeEditor from "../../../src/client/ui/properties/GroupNodeEditor"; -import ModelNode from "../../../src/client/editor/nodes/ModelNode"; -import ModelNodeEditor from "../../../src/client/ui/properties/ModelNodeEditor"; -import GroundPlaneNode from "../../../src/client/editor/nodes/GroundPlaneNode"; -import GroundPlaneNodeEditor from "../../../src/client/ui/properties/GroundPlaneNodeEditor"; -import BoxColliderNode from "../../../src/client/editor/nodes/BoxColliderNode"; -import BoxColliderNodeEditor from "../../../src/client/ui/properties/BoxColliderNodeEditor"; -import AmbientLightNode from "../../../src/client/editor/nodes/AmbientLightNode"; -import AmbientLightNodeEditor from "../../../src/client/ui/properties/AmbientLightNodeEditor"; -import DirectionalLightNode from "../../../src/client/editor/nodes/DirectionalLightNode"; -import DirectionalLightNodeEditor from "../../../src/client/ui/properties/DirectionalLightNodeEditor"; -import SpotLightNode from "../../../src/client/editor/nodes/SpotLightNode"; -import SpotLightNodeEditor from "../../../src/client/ui/properties/SpotLightNodeEditor"; -import PointLightNode from "../../../src/client/editor/nodes/PointLightNode"; -import PointLightNodeEditor from "../../../src/client/ui/properties/PointLightNodeEditor"; -import HemisphereLightNode from "../../../src/client/editor/nodes/HemisphereLightNode"; -import HemisphereLightNodeEditor from "../../../src/client/ui/properties/HemisphereLightNodeEditor"; -import SpawnPointNode from "../../../src/client/editor/nodes/SpawnPointNode"; -import SpawnPointNodeEditor from "../../../src/client/ui/properties/SpawnPointNodeEditor"; -import SkyboxNode from "../../../src/client/editor/nodes/SkyboxNode"; -import SkyboxNodeEditor from "../../../src/client/ui/properties/SkyboxNodeEditor"; -import FloorPlanNode from "../../../src/client/editor/nodes/FloorPlanNode"; -import FloorPlanNodeEditor from "../../../src/client/ui/properties/FloorPlanNodeEditor"; -import ImageNode from "../../../src/client/editor/nodes/ImageNode"; -import ImageNodeEditor from "../../../src/client/ui/properties/ImageNodeEditor"; -import VideoNode from "../../../src/client/editor/nodes/VideoNode"; -import VideoNodeEditor from "../../../src/client/ui/properties/VideoNodeEditor"; -import SpawnerNode from "../../../src/client/editor/nodes/SpawnerNode"; -import SpawnerNodeEditor from "../../../src/client/ui/properties/SpawnerNodeEditor"; +import SceneNode from "../../../src/editor/nodes/SceneNode"; +import SceneNodeEditor from "../../../src/ui/properties/SceneNodeEditor"; +import GroupNode from "../../../src/editor/nodes/GroupNode"; +import GroupNodeEditor from "../../../src/ui/properties/GroupNodeEditor"; +import ModelNode from "../../../src/editor/nodes/ModelNode"; +import ModelNodeEditor from "../../../src/ui/properties/ModelNodeEditor"; +import GroundPlaneNode from "../../../src/editor/nodes/GroundPlaneNode"; +import GroundPlaneNodeEditor from "../../../src/ui/properties/GroundPlaneNodeEditor"; +import BoxColliderNode from "../../../src/editor/nodes/BoxColliderNode"; +import BoxColliderNodeEditor from "../../../src/ui/properties/BoxColliderNodeEditor"; +import AmbientLightNode from "../../../src/editor/nodes/AmbientLightNode"; +import AmbientLightNodeEditor from "../../../src/ui/properties/AmbientLightNodeEditor"; +import DirectionalLightNode from "../../../src/editor/nodes/DirectionalLightNode"; +import DirectionalLightNodeEditor from "../../../src/ui/properties/DirectionalLightNodeEditor"; +import SpotLightNode from "../../../src/editor/nodes/SpotLightNode"; +import SpotLightNodeEditor from "../../../src/ui/properties/SpotLightNodeEditor"; +import PointLightNode from "../../../src/editor/nodes/PointLightNode"; +import PointLightNodeEditor from "../../../src/ui/properties/PointLightNodeEditor"; +import HemisphereLightNode from "../../../src/editor/nodes/HemisphereLightNode"; +import HemisphereLightNodeEditor from "../../../src/ui/properties/HemisphereLightNodeEditor"; +import SpawnPointNode from "../../../src/editor/nodes/SpawnPointNode"; +import SpawnPointNodeEditor from "../../../src/ui/properties/SpawnPointNodeEditor"; +import SkyboxNode from "../../../src/editor/nodes/SkyboxNode"; +import SkyboxNodeEditor from "../../../src/ui/properties/SkyboxNodeEditor"; +import FloorPlanNode from "../../../src/editor/nodes/FloorPlanNode"; +import FloorPlanNodeEditor from "../../../src/ui/properties/FloorPlanNodeEditor"; +import ImageNode from "../../../src/editor/nodes/ImageNode"; +import ImageNodeEditor from "../../../src/ui/properties/ImageNodeEditor"; +import VideoNode from "../../../src/editor/nodes/VideoNode"; +import VideoNodeEditor from "../../../src/ui/properties/VideoNodeEditor"; +import SpawnerNode from "../../../src/editor/nodes/SpawnerNode"; +import SpawnerNodeEditor from "../../../src/ui/properties/SpawnerNodeEditor"; import { expect } from "chai"; @@ -45,10 +45,8 @@ describe("Editor", () => { before(async function() { this.timeout(30000); - const project = new Project(); - const editor = new Editor(project); - // Don't save the scene when regenerating the floorplan so that the .spoke file is not overwritten. - editor.saveOnGenerateFloorPlan = false; + const api = new Api(); + const editor = new Editor(api); editor.registerNode(SceneNode, SceneNodeEditor); editor.registerNode(GroupNode, GroupNodeEditor); @@ -75,7 +73,7 @@ describe("Editor", () => { editor.initializeViewport(canvas); - scene = await editor.openScene("./api/files/V1TestScene.spoke"); + scene = await editor.loadProject("./api/files/V1TestScene.spoke"); }); it("should load the SceneNode", async function() { diff --git a/test/unit/client/api/Project.test.js b/test/unit/client/api/Project.test.js deleted file mode 100644 index ec474358b..000000000 --- a/test/unit/client/api/Project.test.js +++ /dev/null @@ -1,33 +0,0 @@ -import test from "ava"; -import Project from "../../../../src/client/api/Project"; - -const fileUrl = "https://hubs.local:9090/api/files/directory/file.png"; -const fileUrlWithQS = "https://hubs.local:9090/api/files/directory/file.png?size=large"; -const directoryUrl = "https://hubs.local:9090/api/files/directory/"; -const directoryWithoutSlash = "https://hubs.local:9090/api/files/directory"; -const directoryUrlWithQS = "https://hubs.local:9090/api/files/directory?hello=world"; - -test("project.getUrlFilename on url with file extension", t => { - const project = new Project(); - t.is(project.getUrlFilename(fileUrl), "file"); -}); - -test("project.getUrlFilename on url with file extension and query string", t => { - const project = new Project(); - t.is(project.getUrlFilename(fileUrlWithQS), "file"); -}); - -test("project.getUrlFilename on url with trailing slash", t => { - const project = new Project(); - t.is(project.getUrlFilename(directoryUrl), "directory"); -}); - -test("project.getUrlFilename on url without trailing slash", t => { - const project = new Project(); - t.is(project.getUrlFilename(directoryWithoutSlash), "directory"); -}); - -test("project.getUrlFilename on url with query string", t => { - const project = new Project(); - t.is(project.getUrlFilename(directoryUrlWithQS), "directory"); -}); diff --git a/webpack.config.js b/webpack.config.js index 31cc1808f..2bd8bef0c 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -7,20 +7,90 @@ if (process.env.NODE_ENV === "production") { dotenv.config({ path: ".env.defaults" }); } +const fs = require("fs"); +const selfsigned = require("selfsigned"); +const cors = require("cors"); const HTMLWebpackPlugin = require("html-webpack-plugin"); const path = require("path"); const packageJSON = require("./package.json"); const webpack = require("webpack"); +function createHTTPSConfig() { + // Generate certs for the local webpack-dev-server. + if (fs.existsSync(path.join(__dirname, "certs"))) { + const key = fs.readFileSync(path.join(__dirname, "certs", "key.pem")); + const cert = fs.readFileSync(path.join(__dirname, "certs", "cert.pem")); + + return { key, cert }; + } else { + const pems = selfsigned.generate( + [ + { + name: "commonName", + value: "localhost" + } + ], + { + days: 365, + algorithm: "sha256", + extensions: [ + { + name: "subjectAltName", + altNames: [ + { + type: 2, + value: "localhost" + }, + { + type: 2, + value: "hubs.local" + } + ] + } + ] + } + ); + + fs.mkdirSync(path.join(__dirname, "certs")); + fs.writeFileSync(path.join(__dirname, "certs", "cert.pem"), pems.cert); + fs.writeFileSync(path.join(__dirname, "certs", "key.pem"), pems.private); + + return { + key: pems.private, + cert: pems.cert + }; + } +} + +const defaultHostName = "hubs.local"; +const host = process.env.HOST_IP || defaultHostName; + module.exports = { mode: process.env.NODE_ENV ? "development" : "production", entry: { - app: ["./src/client/index.js"] + app: ["./src/index.js"] }, devtool: process.env.NODE_ENV === "production" ? "source-map" : "inline-source-map", + devServer: { + https: createHTTPSConfig(), + historyApiFallback: true, + port: 9090, + host: process.env.HOST_IP || "0.0.0.0", + public: `${host}:9090`, + useLocalIp: true, + allowedHosts: [host], + headers: { + "Access-Control-Allow-Origin": "*" + }, + before: function(app) { + // be flexible with people accessing via a local reticulum on another port + app.use(cors({ origin: /hubs\.local(:\d*)?$/ })); + } + }, + output: { path: path.join(__dirname, "public"), filename: `[name].js`, @@ -39,7 +109,7 @@ module.exports = { }, { test: /\.scss$/, - include: path.join(__dirname, "src", "client"), + include: path.join(__dirname, "src"), use: [ "style-loader", { loader: "css-loader", options: { localIdentName: "[name]__[local]__[hash:base64:5]" } }, @@ -48,18 +118,18 @@ module.exports = { }, { test: /\.js$/, - include: path.join(__dirname, "src", "client"), + include: path.join(__dirname, "src"), use: "babel-loader" }, { test: /\.worker\.js$/, - include: path.join(__dirname, "src", "client"), + include: path.join(__dirname, "src"), loader: "worker-loader" }, { test: /\.wasm$/, type: "javascript/auto", - include: path.join(__dirname, "src", "client"), + include: path.join(__dirname, "src"), loader: "file-loader" } ] @@ -74,7 +144,7 @@ module.exports = { plugins: [ new HTMLWebpackPlugin({ title: packageJSON.productName, - favicon: "src/client/assets/favicon.ico" + favicon: "src/assets/favicon.ico" }), new webpack.DefinePlugin({ SPOKE_VERSION: JSON.stringify(packageJSON.version),