diff --git a/web/jspm-node.js b/web/jspm-node.js index b0808072..d1c2d196 100644 --- a/web/jspm-node.js +++ b/web/jspm-node.js @@ -19,6 +19,7 @@ const generator = new Generator({ 'koa-bodyparser', 'http-errors', 'pg', + 'mime' ], }) diff --git a/web/package-lock.json b/web/package-lock.json index fdef79e5..e99adbdd 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -10,7 +10,7 @@ "dependencies": { "@apollo/client": "^3.6.9", "@arcgis/core": "^4.24.7", - "@emotion/cache": "^11.10.1", + "@emotion/cache": "^11.10.2", "@emotion/react": "^11.10.0", "@emotion/server": "^11.10.0", "@emotion/styled": "^11.10.0", @@ -24,7 +24,8 @@ "@node-loader/import-maps": "^1.1.0", "@rollup/plugin-replace": "^4.0.0", "@swc/cli": "^0.1.57", - "@swc/core": "^1.2.241", + "@swc/core": "^1.2.242", + "@types/react": "^18.0.17", "apollo-server-core": "^3.10.1", "apollo-server-koa": "^3.10.1", "browserslist": "^4.21.3", @@ -41,6 +42,7 @@ "koa-static": "^5.0.0", "make-fetch-happen": "^10.2.1", "maplibre-gl": "2.3.0", + "mime": "^3.0.0", "mkdirp": "^1.0.4", "mongodb": "^4.9.0", "pg": "^8.7.3", @@ -733,9 +735,9 @@ } }, "node_modules/@emotion/cache": { - "version": "11.10.1", - "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.10.1.tgz", - "integrity": "sha512-uZTj3Yz5D69GE25iFZcIQtibnVCFsc/6+XIozyL3ycgWvEdif2uEw9wlUt6umjLr4Keg9K6xRPHmD8LGi+6p1A==", + "version": "11.10.2", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.10.2.tgz", + "integrity": "sha512-GPR4PovENRvYDbCEnDRecPZYJzWdNMsM+Jn+13MC5uImVNbMyKwzv95DUHy5PDcgfPtKoDtfLU6emF1grrbQDg==", "dependencies": { "@emotion/memoize": "^0.8.0", "@emotion/sheet": "^1.2.0", @@ -1795,9 +1797,9 @@ } }, "node_modules/@swc/core": { - "version": "1.2.241", - "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.2.241.tgz", - "integrity": "sha512-zDUpW3ffFllBi2c5ui9JXl7zUjzMOOZGwy9JCAsodWo7DXWjw5pJF4GsTCzaYHDf62XQzQWuL7zGyRnJyMiyAA==", + "version": "1.2.242", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.2.242.tgz", + "integrity": "sha512-JQqSYVoLtHtztCNBgeCKyxmqw6AksHsC4WvVSSErLXJx6JXKaog1HFVuzd6rwx2lLCV+zBnbqJFug5OX0g2knw==", "hasInstallScript": true, "bin": { "swcx": "run_swcx.js" @@ -1810,25 +1812,25 @@ "url": "https://opencollective.com/swc" }, "optionalDependencies": { - "@swc/core-android-arm-eabi": "1.2.241", - "@swc/core-android-arm64": "1.2.241", - "@swc/core-darwin-arm64": "1.2.241", - "@swc/core-darwin-x64": "1.2.241", - "@swc/core-freebsd-x64": "1.2.241", - "@swc/core-linux-arm-gnueabihf": "1.2.241", - "@swc/core-linux-arm64-gnu": "1.2.241", - "@swc/core-linux-arm64-musl": "1.2.241", - "@swc/core-linux-x64-gnu": "1.2.241", - "@swc/core-linux-x64-musl": "1.2.241", - "@swc/core-win32-arm64-msvc": "1.2.241", - "@swc/core-win32-ia32-msvc": "1.2.241", - "@swc/core-win32-x64-msvc": "1.2.241" + "@swc/core-android-arm-eabi": "1.2.242", + "@swc/core-android-arm64": "1.2.242", + "@swc/core-darwin-arm64": "1.2.242", + "@swc/core-darwin-x64": "1.2.242", + "@swc/core-freebsd-x64": "1.2.242", + "@swc/core-linux-arm-gnueabihf": "1.2.242", + "@swc/core-linux-arm64-gnu": "1.2.242", + "@swc/core-linux-arm64-musl": "1.2.242", + "@swc/core-linux-x64-gnu": "1.2.242", + "@swc/core-linux-x64-musl": "1.2.242", + "@swc/core-win32-arm64-msvc": "1.2.242", + "@swc/core-win32-ia32-msvc": "1.2.242", + "@swc/core-win32-x64-msvc": "1.2.242" } }, "node_modules/@swc/core-android-arm-eabi": { - "version": "1.2.241", - "resolved": "https://registry.npmjs.org/@swc/core-android-arm-eabi/-/core-android-arm-eabi-1.2.241.tgz", - "integrity": "sha512-VfbyFAQ+JT4kl4a7kPFM4pUSLHXnJ/bKIW0gAsVngBIcu73cz59HlylKiOtmx3UtXPsYu0Ort/qfC/UJfeEgrQ==", + "version": "1.2.242", + "resolved": "https://registry.npmjs.org/@swc/core-android-arm-eabi/-/core-android-arm-eabi-1.2.242.tgz", + "integrity": "sha512-Ukx1LQAUbPRJdREF9FMgeUwIuRtWJNpPyPF7BWl4hIkw024q75mohMbp3S2wgrF1TsSsEGW37q0DkFxPJ2uJbQ==", "cpu": [ "arm" ], @@ -1844,9 +1846,9 @@ } }, "node_modules/@swc/core-android-arm64": { - "version": "1.2.241", - "resolved": "https://registry.npmjs.org/@swc/core-android-arm64/-/core-android-arm64-1.2.241.tgz", - "integrity": "sha512-WAJW542fxtO5iTP/vrBrf64dWfBq6rmWgL0HpM+ENFbqO4ME0xO49ky+5rMRAQdtwnJ5ZNkCvb49J+iIIY6yaw==", + "version": "1.2.242", + "resolved": "https://registry.npmjs.org/@swc/core-android-arm64/-/core-android-arm64-1.2.242.tgz", + "integrity": "sha512-4E/y+reQWHVCV/0Sn174gsLQyqIKlBWKnwUfPa7MA53VBacp8HTYoPY+iwKPrngsH16gEOC7iByiTJHR/4kirg==", "cpu": [ "arm64" ], @@ -1868,9 +1870,9 @@ "optional": true }, "node_modules/@swc/core-darwin-arm64": { - "version": "1.2.241", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.2.241.tgz", - "integrity": "sha512-5lQaguosciAN6kOfmNY1UeitrwMyPUt4d/Z70A1ac5e1ZFuYlhOxGHuhkz6abEewLkS/b1CGruSAtphEEVGLmw==", + "version": "1.2.242", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.2.242.tgz", + "integrity": "sha512-nIqtjxdbz0Fe0gFZwCygBwUrGEXj3c4mjHjNeveidVX/6U0HE/EAj+0iXuw8zjJLof8HCMnxq8CzzvhA6gd3ZA==", "cpu": [ "arm64" ], @@ -1883,9 +1885,9 @@ } }, "node_modules/@swc/core-darwin-x64": { - "version": "1.2.241", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.2.241.tgz", - "integrity": "sha512-VtcCBdhOktYPDnEEL0f+pfGmvjIlmXWMZKIb48WTYunxwsehxQk79ZkLXc+TwZ3ur9GEoZHh31RaKqOj4QDHpQ==", + "version": "1.2.242", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.2.242.tgz", + "integrity": "sha512-iZKzI76vYYHD/t8wkQ/uIVuIyxN1eift2nLvUU7/jtmoa6b8DH/45ykB/C3vkuvYVNMiGA8HIjJIzw7RJz5XIQ==", "cpu": [ "x64" ], @@ -1898,9 +1900,9 @@ } }, "node_modules/@swc/core-freebsd-x64": { - "version": "1.2.241", - "resolved": "https://registry.npmjs.org/@swc/core-freebsd-x64/-/core-freebsd-x64-1.2.241.tgz", - "integrity": "sha512-i12GxWnm1LuvZ9T0HVB8+CFIhcFzTxu3u2U97LZNb7vbHGHehUwIb6GmTwUbF+wEdFkwsIKWTf3RpvnEejWUsA==", + "version": "1.2.242", + "resolved": "https://registry.npmjs.org/@swc/core-freebsd-x64/-/core-freebsd-x64-1.2.242.tgz", + "integrity": "sha512-6JNi5/6JDvcTQzBkndELiIlJufWowoI2ZEmXlGIJpiGoj28PEDPwy5LO7KkXa4DnY5L4CSh15idFO/DxV0rGAQ==", "cpu": [ "x64" ], @@ -1922,9 +1924,9 @@ "optional": true }, "node_modules/@swc/core-linux-arm-gnueabihf": { - "version": "1.2.241", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.2.241.tgz", - "integrity": "sha512-lTSiPkfEscfYEZxsKLbVqISRvCcatB+h7eENy0+Qdqqyio0yTOMfG7837jZhfy1hCjAwT8x2sh77fbvfQD4dRA==", + "version": "1.2.242", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.2.242.tgz", + "integrity": "sha512-NGL9A3cv8PCbeQ1SvPfApNlHvFbf7Jn305sCAy3iZYsmwm+EU4JNlOWXGgRioP7ABhz2kwLhfYs8UMYCDIVq8Q==", "cpu": [ "arm" ], @@ -1946,9 +1948,9 @@ "optional": true }, "node_modules/@swc/core-linux-arm64-gnu": { - "version": "1.2.241", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.2.241.tgz", - "integrity": "sha512-H6lTvd6nm4eaOi4Ledo5z1a6LXzJ2WpHTRsf3FssM9qqwFmbvNIz9vCTI4jCR5Y3Ed3jlmQli+znzmWJ/qzLLQ==", + "version": "1.2.242", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.2.242.tgz", + "integrity": "sha512-OJ0kAjgeoRDJlo6Rvd2GnJ92tiIndmC/8krD9gfnQEyAgpR+jajOxbKhyBN/QZPyD2q/TG2LPqxhGYZ79q5mWQ==", "cpu": [ "arm64" ], @@ -1961,9 +1963,9 @@ } }, "node_modules/@swc/core-linux-arm64-musl": { - "version": "1.2.241", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.2.241.tgz", - "integrity": "sha512-K8bXA+JtoD0g+w9wDyI3R0VkFaxFokF9KI0ioDVRfwDDNoFWq3slQWyN9fkj0dI9XagK15OcSuMGTH+h9B7veQ==", + "version": "1.2.242", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.2.242.tgz", + "integrity": "sha512-VqnHSYb1a6xW5ARUx9kq88s1S3XvCw9TvQXsPcN4e5qsugrLzxWLnqIM6VnWW06prxN7pYlWo9QtrtdPfbppmA==", "cpu": [ "arm64" ], @@ -1976,9 +1978,9 @@ } }, "node_modules/@swc/core-linux-x64-gnu": { - "version": "1.2.241", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.2.241.tgz", - "integrity": "sha512-jLr+mtNhHMcSRz0xZ9/R9g59kVmgekcz9RyXIFkO7RzJOGVzXxGxfO3pSsQ+u2tCpYbK9M6rMiaNoRYnQj3yNQ==", + "version": "1.2.242", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.2.242.tgz", + "integrity": "sha512-DDqVJh0KpgHb+E0563+6PqAYDzYTSwgZXF/fOULwlHC7Yt50a9+ecisTFSHkWc74zPMtq27kMTuZyyLeD3gu7A==", "cpu": [ "x64" ], @@ -1991,9 +1993,9 @@ } }, "node_modules/@swc/core-linux-x64-musl": { - "version": "1.2.241", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.2.241.tgz", - "integrity": "sha512-yXkhlxTSH6ddcBCxwRHTnpj5TA0GXbWADjPIhhXG8KlM4KGjnEvfSBa1xtSNbJcYT8kBYM1n+jYf0dIX2je5eg==", + "version": "1.2.242", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.2.242.tgz", + "integrity": "sha512-P+9sWgd5eZ6kS1WxOJbCeSgWY7mLP742PhwAzpFrJqCq5nx8Q4FYo4L5mOVNAheYDWldsxR1nKXR1RIMK3S2Lw==", "cpu": [ "x64" ], @@ -2006,9 +2008,9 @@ } }, "node_modules/@swc/core-win32-arm64-msvc": { - "version": "1.2.241", - "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.2.241.tgz", - "integrity": "sha512-/f3ylWLHfUtRgHFER3FdH5QwDhO7siQ6h5ug0yVKXIDfNJhJVt9Hd+ZjMGJhNGTkzrl+uZmwXWBiklMcaMCtbQ==", + "version": "1.2.242", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.2.242.tgz", + "integrity": "sha512-W5cevrf5aDJzdE++XeQi1BJKuigC3dlG2NaBUyt3inmep7nli6eoBJdj9Vyg5EPfFOdeI6wQiwOpFvQRoAle8Q==", "cpu": [ "arm64" ], @@ -2030,9 +2032,9 @@ "optional": true }, "node_modules/@swc/core-win32-ia32-msvc": { - "version": "1.2.241", - "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.2.241.tgz", - "integrity": "sha512-HC1T9sWC9zuZ6C/WWTFMHdgKYv+qaOfWduIvNVqhECa+FXRcBTPtDgNBhMTc2lpt4biKf5iPHhAVZkP6Za3OOw==", + "version": "1.2.242", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.2.242.tgz", + "integrity": "sha512-XRQcgChvY9333hBre9F53EbiVfVu5MkSH4+XIiNMK14Jg8EqQ1nOcd+jvv2sEdEVbufCmBbWNjofUrCoQey60w==", "cpu": [ "ia32" ], @@ -2054,9 +2056,9 @@ "optional": true }, "node_modules/@swc/core-win32-x64-msvc": { - "version": "1.2.241", - "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.2.241.tgz", - "integrity": "sha512-BW1MHKdmi+DDBH+Z/XlhluIjZj9SMkMheeN95G71Z2Pim5LrvzIHf31UD0kYh6ZWWphP06Jlpzl0oi4stxeETw==", + "version": "1.2.242", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.2.242.tgz", + "integrity": "sha512-Cz1hZOxcfEVgzEr2sYIW9MxT+wEEbYz7aB87ZDmTUpr7vuvBiLMwsYItm8qG847wZeJfa+J7CC+tty5GJOBOOQ==", "cpu": [ "x64" ], @@ -5809,6 +5811,17 @@ "node": ">=8.6" } }, + "node_modules/mime": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", + "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", @@ -8555,9 +8568,9 @@ } }, "@emotion/cache": { - "version": "11.10.1", - "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.10.1.tgz", - "integrity": "sha512-uZTj3Yz5D69GE25iFZcIQtibnVCFsc/6+XIozyL3ycgWvEdif2uEw9wlUt6umjLr4Keg9K6xRPHmD8LGi+6p1A==", + "version": "11.10.2", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.10.2.tgz", + "integrity": "sha512-GPR4PovENRvYDbCEnDRecPZYJzWdNMsM+Jn+13MC5uImVNbMyKwzv95DUHy5PDcgfPtKoDtfLU6emF1grrbQDg==", "requires": { "@emotion/memoize": "^0.8.0", "@emotion/sheet": "^1.2.0", @@ -9319,38 +9332,38 @@ } }, "@swc/core": { - "version": "1.2.241", - "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.2.241.tgz", - "integrity": "sha512-zDUpW3ffFllBi2c5ui9JXl7zUjzMOOZGwy9JCAsodWo7DXWjw5pJF4GsTCzaYHDf62XQzQWuL7zGyRnJyMiyAA==", - "requires": { - "@swc/core-android-arm-eabi": "1.2.241", - "@swc/core-android-arm64": "1.2.241", - "@swc/core-darwin-arm64": "1.2.241", - "@swc/core-darwin-x64": "1.2.241", - "@swc/core-freebsd-x64": "1.2.241", - "@swc/core-linux-arm-gnueabihf": "1.2.241", - "@swc/core-linux-arm64-gnu": "1.2.241", - "@swc/core-linux-arm64-musl": "1.2.241", - "@swc/core-linux-x64-gnu": "1.2.241", - "@swc/core-linux-x64-musl": "1.2.241", - "@swc/core-win32-arm64-msvc": "1.2.241", - "@swc/core-win32-ia32-msvc": "1.2.241", - "@swc/core-win32-x64-msvc": "1.2.241" + "version": "1.2.242", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.2.242.tgz", + "integrity": "sha512-JQqSYVoLtHtztCNBgeCKyxmqw6AksHsC4WvVSSErLXJx6JXKaog1HFVuzd6rwx2lLCV+zBnbqJFug5OX0g2knw==", + "requires": { + "@swc/core-android-arm-eabi": "1.2.242", + "@swc/core-android-arm64": "1.2.242", + "@swc/core-darwin-arm64": "1.2.242", + "@swc/core-darwin-x64": "1.2.242", + "@swc/core-freebsd-x64": "1.2.242", + "@swc/core-linux-arm-gnueabihf": "1.2.242", + "@swc/core-linux-arm64-gnu": "1.2.242", + "@swc/core-linux-arm64-musl": "1.2.242", + "@swc/core-linux-x64-gnu": "1.2.242", + "@swc/core-linux-x64-musl": "1.2.242", + "@swc/core-win32-arm64-msvc": "1.2.242", + "@swc/core-win32-ia32-msvc": "1.2.242", + "@swc/core-win32-x64-msvc": "1.2.242" } }, "@swc/core-android-arm-eabi": { - "version": "1.2.241", - "resolved": "https://registry.npmjs.org/@swc/core-android-arm-eabi/-/core-android-arm-eabi-1.2.241.tgz", - "integrity": "sha512-VfbyFAQ+JT4kl4a7kPFM4pUSLHXnJ/bKIW0gAsVngBIcu73cz59HlylKiOtmx3UtXPsYu0Ort/qfC/UJfeEgrQ==", + "version": "1.2.242", + "resolved": "https://registry.npmjs.org/@swc/core-android-arm-eabi/-/core-android-arm-eabi-1.2.242.tgz", + "integrity": "sha512-Ukx1LQAUbPRJdREF9FMgeUwIuRtWJNpPyPF7BWl4hIkw024q75mohMbp3S2wgrF1TsSsEGW37q0DkFxPJ2uJbQ==", "optional": true, "requires": { "@swc/wasm": "1.2.122" } }, "@swc/core-android-arm64": { - "version": "1.2.241", - "resolved": "https://registry.npmjs.org/@swc/core-android-arm64/-/core-android-arm64-1.2.241.tgz", - "integrity": "sha512-WAJW542fxtO5iTP/vrBrf64dWfBq6rmWgL0HpM+ENFbqO4ME0xO49ky+5rMRAQdtwnJ5ZNkCvb49J+iIIY6yaw==", + "version": "1.2.242", + "resolved": "https://registry.npmjs.org/@swc/core-android-arm64/-/core-android-arm64-1.2.242.tgz", + "integrity": "sha512-4E/y+reQWHVCV/0Sn174gsLQyqIKlBWKnwUfPa7MA53VBacp8HTYoPY+iwKPrngsH16gEOC7iByiTJHR/4kirg==", "optional": true, "requires": { "@swc/wasm": "1.2.130" @@ -9365,21 +9378,21 @@ } }, "@swc/core-darwin-arm64": { - "version": "1.2.241", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.2.241.tgz", - "integrity": "sha512-5lQaguosciAN6kOfmNY1UeitrwMyPUt4d/Z70A1ac5e1ZFuYlhOxGHuhkz6abEewLkS/b1CGruSAtphEEVGLmw==", + "version": "1.2.242", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.2.242.tgz", + "integrity": "sha512-nIqtjxdbz0Fe0gFZwCygBwUrGEXj3c4mjHjNeveidVX/6U0HE/EAj+0iXuw8zjJLof8HCMnxq8CzzvhA6gd3ZA==", "optional": true }, "@swc/core-darwin-x64": { - "version": "1.2.241", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.2.241.tgz", - "integrity": "sha512-VtcCBdhOktYPDnEEL0f+pfGmvjIlmXWMZKIb48WTYunxwsehxQk79ZkLXc+TwZ3ur9GEoZHh31RaKqOj4QDHpQ==", + "version": "1.2.242", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.2.242.tgz", + "integrity": "sha512-iZKzI76vYYHD/t8wkQ/uIVuIyxN1eift2nLvUU7/jtmoa6b8DH/45ykB/C3vkuvYVNMiGA8HIjJIzw7RJz5XIQ==", "optional": true }, "@swc/core-freebsd-x64": { - "version": "1.2.241", - "resolved": "https://registry.npmjs.org/@swc/core-freebsd-x64/-/core-freebsd-x64-1.2.241.tgz", - "integrity": "sha512-i12GxWnm1LuvZ9T0HVB8+CFIhcFzTxu3u2U97LZNb7vbHGHehUwIb6GmTwUbF+wEdFkwsIKWTf3RpvnEejWUsA==", + "version": "1.2.242", + "resolved": "https://registry.npmjs.org/@swc/core-freebsd-x64/-/core-freebsd-x64-1.2.242.tgz", + "integrity": "sha512-6JNi5/6JDvcTQzBkndELiIlJufWowoI2ZEmXlGIJpiGoj28PEDPwy5LO7KkXa4DnY5L4CSh15idFO/DxV0rGAQ==", "optional": true, "requires": { "@swc/wasm": "1.2.130" @@ -9394,9 +9407,9 @@ } }, "@swc/core-linux-arm-gnueabihf": { - "version": "1.2.241", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.2.241.tgz", - "integrity": "sha512-lTSiPkfEscfYEZxsKLbVqISRvCcatB+h7eENy0+Qdqqyio0yTOMfG7837jZhfy1hCjAwT8x2sh77fbvfQD4dRA==", + "version": "1.2.242", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.2.242.tgz", + "integrity": "sha512-NGL9A3cv8PCbeQ1SvPfApNlHvFbf7Jn305sCAy3iZYsmwm+EU4JNlOWXGgRioP7ABhz2kwLhfYs8UMYCDIVq8Q==", "optional": true, "requires": { "@swc/wasm": "1.2.130" @@ -9411,33 +9424,33 @@ } }, "@swc/core-linux-arm64-gnu": { - "version": "1.2.241", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.2.241.tgz", - "integrity": "sha512-H6lTvd6nm4eaOi4Ledo5z1a6LXzJ2WpHTRsf3FssM9qqwFmbvNIz9vCTI4jCR5Y3Ed3jlmQli+znzmWJ/qzLLQ==", + "version": "1.2.242", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.2.242.tgz", + "integrity": "sha512-OJ0kAjgeoRDJlo6Rvd2GnJ92tiIndmC/8krD9gfnQEyAgpR+jajOxbKhyBN/QZPyD2q/TG2LPqxhGYZ79q5mWQ==", "optional": true }, "@swc/core-linux-arm64-musl": { - "version": "1.2.241", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.2.241.tgz", - "integrity": "sha512-K8bXA+JtoD0g+w9wDyI3R0VkFaxFokF9KI0ioDVRfwDDNoFWq3slQWyN9fkj0dI9XagK15OcSuMGTH+h9B7veQ==", + "version": "1.2.242", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.2.242.tgz", + "integrity": "sha512-VqnHSYb1a6xW5ARUx9kq88s1S3XvCw9TvQXsPcN4e5qsugrLzxWLnqIM6VnWW06prxN7pYlWo9QtrtdPfbppmA==", "optional": true }, "@swc/core-linux-x64-gnu": { - "version": "1.2.241", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.2.241.tgz", - "integrity": "sha512-jLr+mtNhHMcSRz0xZ9/R9g59kVmgekcz9RyXIFkO7RzJOGVzXxGxfO3pSsQ+u2tCpYbK9M6rMiaNoRYnQj3yNQ==", + "version": "1.2.242", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.2.242.tgz", + "integrity": "sha512-DDqVJh0KpgHb+E0563+6PqAYDzYTSwgZXF/fOULwlHC7Yt50a9+ecisTFSHkWc74zPMtq27kMTuZyyLeD3gu7A==", "optional": true }, "@swc/core-linux-x64-musl": { - "version": "1.2.241", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.2.241.tgz", - "integrity": "sha512-yXkhlxTSH6ddcBCxwRHTnpj5TA0GXbWADjPIhhXG8KlM4KGjnEvfSBa1xtSNbJcYT8kBYM1n+jYf0dIX2je5eg==", + "version": "1.2.242", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.2.242.tgz", + "integrity": "sha512-P+9sWgd5eZ6kS1WxOJbCeSgWY7mLP742PhwAzpFrJqCq5nx8Q4FYo4L5mOVNAheYDWldsxR1nKXR1RIMK3S2Lw==", "optional": true }, "@swc/core-win32-arm64-msvc": { - "version": "1.2.241", - "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.2.241.tgz", - "integrity": "sha512-/f3ylWLHfUtRgHFER3FdH5QwDhO7siQ6h5ug0yVKXIDfNJhJVt9Hd+ZjMGJhNGTkzrl+uZmwXWBiklMcaMCtbQ==", + "version": "1.2.242", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.2.242.tgz", + "integrity": "sha512-W5cevrf5aDJzdE++XeQi1BJKuigC3dlG2NaBUyt3inmep7nli6eoBJdj9Vyg5EPfFOdeI6wQiwOpFvQRoAle8Q==", "optional": true, "requires": { "@swc/wasm": "1.2.130" @@ -9452,9 +9465,9 @@ } }, "@swc/core-win32-ia32-msvc": { - "version": "1.2.241", - "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.2.241.tgz", - "integrity": "sha512-HC1T9sWC9zuZ6C/WWTFMHdgKYv+qaOfWduIvNVqhECa+FXRcBTPtDgNBhMTc2lpt4biKf5iPHhAVZkP6Za3OOw==", + "version": "1.2.242", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.2.242.tgz", + "integrity": "sha512-XRQcgChvY9333hBre9F53EbiVfVu5MkSH4+XIiNMK14Jg8EqQ1nOcd+jvv2sEdEVbufCmBbWNjofUrCoQey60w==", "optional": true, "requires": { "@swc/wasm": "1.2.130" @@ -9469,9 +9482,9 @@ } }, "@swc/core-win32-x64-msvc": { - "version": "1.2.241", - "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.2.241.tgz", - "integrity": "sha512-BW1MHKdmi+DDBH+Z/XlhluIjZj9SMkMheeN95G71Z2Pim5LrvzIHf31UD0kYh6ZWWphP06Jlpzl0oi4stxeETw==", + "version": "1.2.242", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.2.242.tgz", + "integrity": "sha512-Cz1hZOxcfEVgzEr2sYIW9MxT+wEEbYz7aB87ZDmTUpr7vuvBiLMwsYItm8qG847wZeJfa+J7CC+tty5GJOBOOQ==", "optional": true }, "@swc/wasm": { @@ -12370,6 +12383,11 @@ "picomatch": "^2.3.1" } }, + "mime": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", + "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==" + }, "mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", diff --git a/web/package.json b/web/package.json index d3fb9d53..e6bc41a6 100644 --- a/web/package.json +++ b/web/package.json @@ -7,7 +7,7 @@ "dependencies": { "@apollo/client": "^3.6.9", "@arcgis/core": "^4.24.7", - "@emotion/cache": "^11.10.1", + "@emotion/cache": "^11.10.2", "@emotion/react": "^11.10.0", "@emotion/server": "^11.10.0", "@emotion/styled": "^11.10.0", @@ -21,7 +21,8 @@ "@node-loader/import-maps": "^1.1.0", "@rollup/plugin-replace": "^4.0.0", "@swc/cli": "^0.1.57", - "@swc/core": "^1.2.241", + "@swc/core": "^1.2.242", + "@types/react": "^18.0.17", "apollo-server-core": "^3.10.1", "apollo-server-koa": "^3.10.1", "browserslist": "^4.21.3", @@ -38,6 +39,7 @@ "koa-static": "^5.0.0", "make-fetch-happen": "^10.2.1", "maplibre-gl": "2.3.0", + "mime": "^3.0.0", "mkdirp": "^1.0.4", "mongodb": "^4.9.0", "pg": "^8.7.3", diff --git a/web/somisana.web.d.ts b/web/somisana.web.d.ts index ea74a463..75d3f5b8 100644 --- a/web/somisana.web.d.ts +++ b/web/somisana.web.d.ts @@ -1 +1,2 @@ declare module 'cookie' +declare module 'make-fetch-happen' \ No newline at end of file diff --git a/web/ssr/_layout.tsx b/web/ssr/_layout.tsx index 6e23d9b6..c5b2c8ce 100644 --- a/web/ssr/_layout.tsx +++ b/web/ssr/_layout.tsx @@ -25,7 +25,9 @@ export default ({ children, ctx, emotionCache }) => { cookie={cookie} acceptLanguage={language} emotionCache={emotionCache} - Router={props => } + Router={(props: React.FC) => ( + + )} apolloClient={apolloClient} > {children} diff --git a/web/ssr/_register-assets.ts b/web/ssr/_register-assets.ts new file mode 100644 index 00000000..329893af --- /dev/null +++ b/web/ssr/_register-assets.ts @@ -0,0 +1,11 @@ +import { readdir } from 'fs/promises' +import dirname from '../server/lib/dirname' +import { join, normalize } from 'path' + +const __dirname = dirname(import.meta) + +export const assetsPath = normalize(join(__dirname, '../.client')) + +export const htmlFiles = await readdir(normalize(join(__dirname, '../client/html'))) + .then((files: Array) => files.filter((f: string) => f.includes('.html'))) + .then((files: Array) => files.map((f: string) => f.replace('.html', ''))) diff --git a/web/ssr/_render-html.tsx b/web/ssr/_render-html.tsx new file mode 100644 index 00000000..0a8bcfa5 --- /dev/null +++ b/web/ssr/_render-html.tsx @@ -0,0 +1,41 @@ +import { createEmotionCache } from '../common/app' +import createEmotionServer from '@emotion/server/create-instance' +import Layout from './_layout' +import { renderToString } from 'react-dom/server' +import { join, normalize } from 'path' +import fs from 'fs/promises' + +const INDEX_NAME = 'somisana' + +export default async (ctx, htmlFiles, assetsPath) => { + ctx.set('Content-type', 'text/html') + const entry = ctx.request.url.replace('.html', '').replace('/', '') + const page = entry ? (htmlFiles.includes(entry) ? entry : INDEX_NAME) : INDEX_NAME + + const htmlUtf8 = await fs.readFile(normalize(join(assetsPath, `${page}.html`)), { + encoding: 'utf-8', + }) + + const SsrEntry = await import(normalize(join(assetsPath, `ssr.${page}.js`))).then( + ({ default: C }) => C + ) + + const emotionCache = createEmotionCache() + const { extractCriticalToChunks, constructStyleTagsFromChunks } = + createEmotionServer(emotionCache) + + const html = renderToString( + + + + ) + + const emotionChunks = extractCriticalToChunks(html) + const emotionCss = constructStyleTagsFromChunks(emotionChunks) + + const result = htmlUtf8 + .replace('', `${emotionCss}`) + .replace('
', `
${html}
`) + + ctx.body = result +} diff --git a/web/ssr/_serve.ts b/web/ssr/_serve.ts deleted file mode 100644 index 458327ac..00000000 --- a/web/ssr/_serve.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { createReadStream } from 'fs' -import { join, normalize } from 'path' - -export default (ctx, { files, url }) => createReadStream(normalize(join(files, url))) diff --git a/web/ssr/_stream-file.ts b/web/ssr/_stream-file.ts new file mode 100644 index 00000000..c52a6c62 --- /dev/null +++ b/web/ssr/_stream-file.ts @@ -0,0 +1,14 @@ +import { open } from 'fs/promises' + +export default async (ctx: any, contentType: string, filePath: string) => { + let fd: any + try { + fd = await open(filePath) + } catch (error) { + ctx.status = 404 + return + } + + ctx.set('Content-type', contentType) + ctx.body = fd.createReadStream() +} diff --git a/web/ssr/_url-rewrite.ts b/web/ssr/_url-rewrite.ts new file mode 100644 index 00000000..7ea0fe89 --- /dev/null +++ b/web/ssr/_url-rewrite.ts @@ -0,0 +1,7 @@ +export default (path: string) => + path.replace(/(explore)\/(.*)/, (match, g1, g2) => { + if (path.endsWith('.js')) { + return path.replace(`${g1}/`, '') + } + return match.replace(`${g1}/`, 'esri-atlas').replace(g2, '') + }) diff --git a/web/ssr/index.tsx b/web/ssr/index.tsx index b6a41e98..acb0ea32 100644 --- a/web/ssr/index.tsx +++ b/web/ssr/index.tsx @@ -1,84 +1,23 @@ import { join, normalize } from 'path' -import fs from 'fs/promises' -import dirname from '../server/lib/dirname' -import { createEmotionCache } from '../common/app' -import createEmotionServer from '@emotion/server/create-instance' -import Layout from './_layout' -import serve from './_serve' +import streamFile from './_stream-file' +import renderHTML from './_render-html' +import mime from 'mime' +import rewrite from './_url-rewrite' +import { assetsPath, htmlFiles } from './_register-assets' -/** - * Emotion doesn't support stream-rendering yet - * Once it does, please update - */ -import { renderToString } from 'react-dom/server' - -const INDEX_NAME = 'somisana' -const __dirname = dirname(import.meta) -const files = normalize(join(__dirname, '../.client')) -const APP_ENTRIES = await fs - .readdir(normalize(join(__dirname, '../client/html'))) - .then(files => files.filter(f => f.includes('.html'))) - .then(files => files.map(f => f.replace('.html', ''))) - -const rewrite = str => - str.replace(/(explore)\/(.*)/, (match, g1, g2) => { - if (str.endsWith('.js')) { - return str.replace(`${g1}/`, '') - } - return match.replace(`${g1}/`, 'esri-atlas').replace(g2, '') - }) - -export default async ctx => { +export default async (ctx: any) => { const url = rewrite(ctx.request.url) - - if (url.endsWith('.txt')) { - ctx.set('Content-type', 'text/plain') - ctx.body = serve(ctx, { files, url }) - } else if (url.endsWith('.ico')) { - ctx.set('Content-type', 'image/x-icon') - ctx.body = serve(ctx, { files, url }) - } else if (url.endsWith('.js')) { - ctx.set('Content-type', 'application/javascript; charset=utf-8') - ctx.body = serve(ctx, { files, url }) - } else if (url.endsWith('.png')) { - ctx.set('Content-type', 'image/png') - ctx.body = serve(ctx, { files, url }) - } else if (url.endsWith('.css')) { - ctx.set('Content-type', 'text/css') - ctx.body = serve(ctx, { files, url }) - } else if (url.endsWith('site.webmanifest')) { - ctx.set('Content-type', 'application/json; charset=utf-8') - ctx.body = serve(ctx, { files, url }) - } else { - ctx.set('Content-type', 'text/html') - const entry = ctx.request.url.replace('.html', '').replace('/', '') - const page = entry ? (APP_ENTRIES.includes(entry) ? entry : INDEX_NAME) : INDEX_NAME - - const htmlUtf8 = await fs.readFile(normalize(join(files, `${page}.html`)), { - encoding: 'utf-8', - }) - - const SsrEntry = await import(normalize(join(files, `ssr.${page}.js`))).then( - ({ default: C }) => C - ) - - const emotionCache = createEmotionCache() - const { extractCriticalToChunks, constructStyleTagsFromChunks } = - createEmotionServer(emotionCache) - - const html = renderToString( - - - - ) - - const emotionChunks = extractCriticalToChunks(html) - const emotionCss = constructStyleTagsFromChunks(emotionChunks) - - const result = htmlUtf8 - .replace('', `${emotionCss}`) - .replace('
', `
${html}
`) - - ctx.body = result + const contentType = mime.getType(url) + const assetPath = normalize(join(assetsPath, url)) + + switch (contentType) { + case 'text/html': + case null: + await renderHTML(ctx, htmlFiles, assetsPath) + break + + default: + await streamFile(ctx, contentType, assetPath) + break } }