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
}
}