update packages, add back eventstream testing

This commit is contained in:
proddy
2024-03-30 18:57:20 +01:00
parent d8ff9da733
commit 9822aa6e13
11 changed files with 229 additions and 313 deletions

View File

@@ -1,7 +1,7 @@
{
"name": "EMS-ESP",
"version": "3.7",
"description": "build EMS-ESP WebUI",
"description": "Build the EMS-ESP WebUI",
"homepage": "https://emsesp.github.io/docs",
"author": "proddy",
"license": "MIT",
@@ -12,9 +12,10 @@
"preview": "vite preview",
"build-hosted": "typesafe-i18n --no-watch && vite build --mode hosted",
"preview-standalone": "typesafe-i18n --no-watch && vite build && concurrently -c \"auto\" \"npm:mock-api\" \"vite preview\"",
"mock-api": "bun --watch ../mock-api/server.ts",
"mock-api": "bun --watch ../mock-api/rest_server.ts",
"mock-es": "bun --watch ../mock-api/es_server.ts",
"old_mock-api": "bun --watch ../mock-api/server.js",
"standalone": "concurrently -c \"auto\" \"typesafe-i18n\" \"npm:mock-api\" \"vite\"",
"standalone": "concurrently -c \"auto\" \"typesafe-i18n\" \"npm:mock-api\" \"npm:mock-es\" \"vite\"",
"old_standalone": "concurrently -c \"auto\" \"typesafe-i18n\" \"npm:old_mock-api\" \"vite\"",
"typesafe-i18n": "typesafe-i18n --no-watch",
"webUI": "node progmem-generator.js",
@@ -25,18 +26,19 @@
"@alova/adapter-xhr": "^1.0.3",
"@babel/core": "^7.24.3",
"@emotion/react": "^11.11.4",
"@emotion/styled": "^11.11.0",
"@emotion/styled": "^11.11.5",
"@mui/icons-material": "^5.15.14",
"@mui/material": "^5.15.14",
"@table-library/react-table-library": "4.1.7",
"@types/imagemin": "^8.0.5",
"@types/lodash-es": "^4.17.12",
"@types/node": "^20.11.30",
"@types/react": "^18.2.72",
"@types/react-dom": "^18.2.22",
"@types/node": "^20.12.2",
"@types/react": "^18.2.73",
"@types/react-dom": "^18.2.23",
"@types/react-router-dom": "^5.3.3",
"alova": "^2.18.0",
"alova": "^2.18.2",
"async-validator": "^4.2.5",
"eslint-plugin-prettier": "^5.1.3",
"history": "^5.3.0",
"jwt-decode": "^4.0.0",
"lodash-es": "^4.17.21",
@@ -47,7 +49,6 @@
"react-icons": "^5.0.1",
"react-router-dom": "^6.22.3",
"react-toastify": "^10.0.5",
"sockette": "^2.0.6",
"typesafe-i18n": "^5.26.2",
"typescript": "^5.4.3"
},
@@ -62,15 +63,13 @@
"eslint-import-resolver-typescript": "^3.6.1",
"eslint-plugin-autofix": "^1.1.0",
"eslint-plugin-import": "^2.29.1",
"eslint-plugin-jsx-a11y": "^6.8.0",
"eslint-plugin-prettier": "alpha",
"eslint-plugin-react": "^7.34.1",
"eslint-plugin-react-hooks": "^4.6.0",
"preact": "^10.20.1",
"prettier": "^3.2.5",
"rollup-plugin-visualizer": "^5.12.0",
"terser": "^5.30.0",
"vite": "^5.2.6",
"vite": "^5.2.7",
"vite-plugin-imagemin": "^0.6.1",
"vite-tsconfig-paths": "^4.3.2"
},

View File

@@ -20,7 +20,7 @@ export default defineConfig(({ command, mode }) => {
secure: false
},
'/es': {
target: 'http://localhost:3080',
target: 'http://localhost:3081',
changeOrigin: true,
secure: false
}

View File

@@ -268,7 +268,7 @@ __metadata:
languageName: node
linkType: hard
"@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.21.0, @babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.23.9, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.7.6, @babel/runtime@npm:^7.8.7":
"@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.21.0, @babel/runtime@npm:^7.23.9, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.7.6, @babel/runtime@npm:^7.8.7":
version: 7.24.1
resolution: "@babel/runtime@npm:7.24.1"
dependencies:
@@ -356,7 +356,7 @@ __metadata:
languageName: node
linkType: hard
"@emotion/is-prop-valid@npm:^1.2.1":
"@emotion/is-prop-valid@npm:^1.2.2":
version: 1.2.2
resolution: "@emotion/is-prop-valid@npm:1.2.2"
dependencies:
@@ -406,6 +406,19 @@ __metadata:
languageName: node
linkType: hard
"@emotion/serialize@npm:^1.1.4":
version: 1.1.4
resolution: "@emotion/serialize@npm:1.1.4"
dependencies:
"@emotion/hash": "npm:^0.9.1"
"@emotion/memoize": "npm:^0.8.1"
"@emotion/unitless": "npm:^0.8.1"
"@emotion/utils": "npm:^1.2.1"
csstype: "npm:^3.0.2"
checksum: 10/11fc4f960226778e9a5f86310b739703986d13b2de3e89a16d788126ce312b2c8c174a2947c9bfc80cb124b331c36feeac44193f81150616d94b1ba19a92d70a
languageName: node
linkType: hard
"@emotion/sheet@npm:^1.2.2":
version: 1.2.2
resolution: "@emotion/sheet@npm:1.2.2"
@@ -413,14 +426,14 @@ __metadata:
languageName: node
linkType: hard
"@emotion/styled@npm:^11.11.0":
version: 11.11.0
resolution: "@emotion/styled@npm:11.11.0"
"@emotion/styled@npm:^11.11.5":
version: 11.11.5
resolution: "@emotion/styled@npm:11.11.5"
dependencies:
"@babel/runtime": "npm:^7.18.3"
"@emotion/babel-plugin": "npm:^11.11.0"
"@emotion/is-prop-valid": "npm:^1.2.1"
"@emotion/serialize": "npm:^1.1.2"
"@emotion/is-prop-valid": "npm:^1.2.2"
"@emotion/serialize": "npm:^1.1.4"
"@emotion/use-insertion-effect-with-fallbacks": "npm:^1.0.1"
"@emotion/utils": "npm:^1.2.1"
peerDependencies:
@@ -429,7 +442,7 @@ __metadata:
peerDependenciesMeta:
"@types/react":
optional: true
checksum: 10/ac471a40645ee7bc950378ff9453028078bc2e45a6317f77636e4ed27f7ea61eb549b1efefdc5433640f73246ae5ee212e6c864085dc042b6541b2ffa0e21a49
checksum: 10/a936787ef80d73066840391522d88280424de0abb56bec83d17e14bdc5a515e77e343dd171f7caae1405462e3f71815b5480dcc4e1eff5e8ff4a020f5c39341e
languageName: node
linkType: hard
@@ -1397,7 +1410,7 @@ __metadata:
languageName: node
linkType: hard
"@types/node@npm:*, @types/node@npm:^20.11.30":
"@types/node@npm:*":
version: 20.11.30
resolution: "@types/node@npm:20.11.30"
dependencies:
@@ -1406,6 +1419,15 @@ __metadata:
languageName: node
linkType: hard
"@types/node@npm:^20.12.2":
version: 20.12.2
resolution: "@types/node@npm:20.12.2"
dependencies:
undici-types: "npm:~5.26.4"
checksum: 10/f1f0ebfe475aefa183763b856e0023b81b76554196e8676a45b9fcfd1012cdd20d32adefb3c0330001c0011e074676603c34c24821a4924228250ea13a75da43
languageName: node
linkType: hard
"@types/parse-json@npm:^4.0.0":
version: 4.0.2
resolution: "@types/parse-json@npm:4.0.2"
@@ -1420,12 +1442,12 @@ __metadata:
languageName: node
linkType: hard
"@types/react-dom@npm:^18.2.22":
version: 18.2.22
resolution: "@types/react-dom@npm:18.2.22"
"@types/react-dom@npm:^18.2.23":
version: 18.2.23
resolution: "@types/react-dom@npm:18.2.23"
dependencies:
"@types/react": "npm:*"
checksum: 10/310da22244c1bb65a7f213f8727bda821dd211cfb2dd62d1f9b28dd50ef1c196d59e908494bd5f25c13a3844343f3a6135f39fb830aca6f79646fa56c1b56c08
checksum: 10/8311c67767b0aafb5cd94176a90f801f0f5f6930731d57caaa04bb0d87fdef6bc6f723a116d9777d2082ec022682acaad7a62d04dc27e330e818cf34f2ef2703
languageName: node
linkType: hard
@@ -1470,13 +1492,13 @@ __metadata:
languageName: node
linkType: hard
"@types/react@npm:^18.2.72":
version: 18.2.72
resolution: "@types/react@npm:18.2.72"
"@types/react@npm:^18.2.73":
version: 18.2.73
resolution: "@types/react@npm:18.2.73"
dependencies:
"@types/prop-types": "npm:*"
csstype: "npm:^3.0.2"
checksum: 10/0c15461eeb8cd5153b48446d4aae681ae1d4f45fa5828fc53c12aaac9dfe426a64259a284737f6abfc3bea36df9507c129d7065ebb390b21349ad30128385ac1
checksum: 10/799e30e73464dff40e04f4eb7499ebc31f99b1711a69263b9af340af738e35c9cdf53084e3dacc3b21c031aaa0cba1b51f4ba60490204b7abb75f115b841583f
languageName: node
linkType: hard
@@ -1649,7 +1671,7 @@ __metadata:
"@alova/adapter-xhr": "npm:^1.0.3"
"@babel/core": "npm:^7.24.3"
"@emotion/react": "npm:^11.11.4"
"@emotion/styled": "npm:^11.11.0"
"@emotion/styled": "npm:^11.11.5"
"@mui/icons-material": "npm:^5.15.14"
"@mui/material": "npm:^5.15.14"
"@preact/compat": "npm:^17.1.2"
@@ -1657,13 +1679,13 @@ __metadata:
"@table-library/react-table-library": "npm:4.1.7"
"@types/imagemin": "npm:^8.0.5"
"@types/lodash-es": "npm:^4.17.12"
"@types/node": "npm:^20.11.30"
"@types/react": "npm:^18.2.72"
"@types/react-dom": "npm:^18.2.22"
"@types/node": "npm:^20.12.2"
"@types/react": "npm:^18.2.73"
"@types/react-dom": "npm:^18.2.23"
"@types/react-router-dom": "npm:^5.3.3"
"@typescript-eslint/eslint-plugin": "npm:^7.4.0"
"@typescript-eslint/parser": "npm:^7.4.0"
alova: "npm:^2.18.0"
alova: "npm:^2.18.2"
async-validator: "npm:^4.2.5"
concurrently: "npm:^8.2.2"
eslint: "npm:^8.57.0"
@@ -1671,8 +1693,7 @@ __metadata:
eslint-import-resolver-typescript: "npm:^3.6.1"
eslint-plugin-autofix: "npm:^1.1.0"
eslint-plugin-import: "npm:^2.29.1"
eslint-plugin-jsx-a11y: "npm:^6.8.0"
eslint-plugin-prettier: "npm:alpha"
eslint-plugin-prettier: "npm:^5.1.3"
eslint-plugin-react: "npm:^7.34.1"
eslint-plugin-react-hooks: "npm:^4.6.0"
history: "npm:^5.3.0"
@@ -1688,11 +1709,10 @@ __metadata:
react-router-dom: "npm:^6.22.3"
react-toastify: "npm:^10.0.5"
rollup-plugin-visualizer: "npm:^5.12.0"
sockette: "npm:^2.0.6"
terser: "npm:^5.30.0"
typesafe-i18n: "npm:^5.26.2"
typescript: "npm:^5.4.3"
vite: "npm:^5.2.6"
vite: "npm:^5.2.7"
vite-plugin-imagemin: "npm:^0.6.1"
vite-tsconfig-paths: "npm:^4.3.2"
languageName: unknown
@@ -1754,10 +1774,10 @@ __metadata:
languageName: node
linkType: hard
"alova@npm:^2.18.0":
version: 2.18.0
resolution: "alova@npm:2.18.0"
checksum: 10/6edf15157f4bce4239ba3461bf71a653fd4e904c80e5e7d4574328bb30d5704d5e4fc9c024b60f886bb010ee3e29e56cfb6ab7fc235a6a2aa4ee879cae35e387
"alova@npm:^2.18.2":
version: 2.18.2
resolution: "alova@npm:2.18.2"
checksum: 10/715d97c5b80c2b3541b7b5dd203bb7496d7308a49682df31ed007c12a7d716ee910f3da852accc2398c2283db3808748678074cb87324b5d77bb991018431bf3
languageName: node
linkType: hard
@@ -1837,15 +1857,6 @@ __metadata:
languageName: node
linkType: hard
"aria-query@npm:^5.3.0":
version: 5.3.0
resolution: "aria-query@npm:5.3.0"
dependencies:
dequal: "npm:^2.0.3"
checksum: 10/c3e1ed127cc6886fea4732e97dd6d3c3938e64180803acfb9df8955517c4943760746ffaf4020ce8f7ffaa7556a3b5f85c3769a1f5ca74a1288e02d042f9ae4e
languageName: node
linkType: hard
"array-buffer-byte-length@npm:^1.0.1":
version: 1.0.1
resolution: "array-buffer-byte-length@npm:1.0.1"
@@ -1977,13 +1988,6 @@ __metadata:
languageName: node
linkType: hard
"ast-types-flow@npm:^0.0.8":
version: 0.0.8
resolution: "ast-types-flow@npm:0.0.8"
checksum: 10/85a1c24af4707871c27cfe456bd2ff7fcbe678f3d1c878ac968c9557735a171a17bdcc8c8f903ceab3fc3c49d5b3da2194e6ab0a6be7fec0e133fa028f21ba1b
languageName: node
linkType: hard
"async-validator@npm:^4.2.5":
version: 4.2.5
resolution: "async-validator@npm:4.2.5"
@@ -2007,22 +2011,6 @@ __metadata:
languageName: node
linkType: hard
"axe-core@npm:=4.7.0":
version: 4.7.0
resolution: "axe-core@npm:4.7.0"
checksum: 10/615c0f7722c3c9fcf353dbd70b00e2ceae234d4c17cbc839dd85c01d16797c4e4da45f8d27c6118e9e6b033fb06efd196106e13651a1b2f3a10e0f11c7b2f660
languageName: node
linkType: hard
"axobject-query@npm:^3.2.1":
version: 3.2.1
resolution: "axobject-query@npm:3.2.1"
dependencies:
dequal: "npm:^2.0.3"
checksum: 10/675af2548ed4ece75ad6d50cc0473cfdec7579eac77ec9861e7088d03ffb171aa697b70d2877423bee2ce16460ef62c698c6442a105612cc015719e8ea06b0bd
languageName: node
linkType: hard
"babel-plugin-macros@npm:^3.1.0":
version: 3.1.0
resolution: "babel-plugin-macros@npm:3.1.0"
@@ -2643,13 +2631,6 @@ __metadata:
languageName: node
linkType: hard
"damerau-levenshtein@npm:^1.0.8":
version: 1.0.8
resolution: "damerau-levenshtein@npm:1.0.8"
checksum: 10/f4eba1c90170f96be25d95fa3857141b5f81e254f7e4d530da929217b19990ea9a0390fc53d3c1cafac9152fda78e722ea4894f765cf6216be413b5af1fbf821
languageName: node
linkType: hard
"data-view-buffer@npm:^1.0.1":
version: 1.0.1
resolution: "data-view-buffer@npm:1.0.1"
@@ -2835,13 +2816,6 @@ __metadata:
languageName: node
linkType: hard
"dequal@npm:^2.0.3":
version: 2.0.3
resolution: "dequal@npm:2.0.3"
checksum: 10/6ff05a7561f33603df87c45e389c9ac0a95e3c056be3da1a0c4702149e3a7f6fe5ffbb294478687ba51a9e95f3a60e8b6b9005993acd79c292c7d15f71964b6b
languageName: node
linkType: hard
"dir-glob@npm:^3.0.1":
version: 3.0.1
resolution: "dir-glob@npm:3.0.1"
@@ -3157,7 +3131,7 @@ __metadata:
languageName: node
linkType: hard
"es-iterator-helpers@npm:^1.0.15, es-iterator-helpers@npm:^1.0.17":
"es-iterator-helpers@npm:^1.0.17":
version: 1.0.18
resolution: "es-iterator-helpers@npm:1.0.18"
dependencies:
@@ -3628,48 +3602,23 @@ __metadata:
languageName: node
linkType: hard
"eslint-plugin-jsx-a11y@npm:^6.8.0":
version: 6.8.0
resolution: "eslint-plugin-jsx-a11y@npm:6.8.0"
dependencies:
"@babel/runtime": "npm:^7.23.2"
aria-query: "npm:^5.3.0"
array-includes: "npm:^3.1.7"
array.prototype.flatmap: "npm:^1.3.2"
ast-types-flow: "npm:^0.0.8"
axe-core: "npm:=4.7.0"
axobject-query: "npm:^3.2.1"
damerau-levenshtein: "npm:^1.0.8"
emoji-regex: "npm:^9.2.2"
es-iterator-helpers: "npm:^1.0.15"
hasown: "npm:^2.0.0"
jsx-ast-utils: "npm:^3.3.5"
language-tags: "npm:^1.0.9"
minimatch: "npm:^3.1.2"
object.entries: "npm:^1.1.7"
object.fromentries: "npm:^2.0.7"
peerDependencies:
eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8
checksum: 10/7a8e4498531a43d988ce2f12502a3f5ce96eacfec13f956cf927f24bb041b724fb7fc0f0306ea19d143bfc79e138bf25e25acca0822847206ac6bf5ce095e846
languageName: node
linkType: hard
"eslint-plugin-prettier@npm:alpha":
version: 5.0.0-alpha.2
resolution: "eslint-plugin-prettier@npm:5.0.0-alpha.2"
"eslint-plugin-prettier@npm:^5.1.3":
version: 5.1.3
resolution: "eslint-plugin-prettier@npm:5.1.3"
dependencies:
prettier-linter-helpers: "npm:^1.0.0"
synckit: "npm:^0.8.5"
synckit: "npm:^0.8.6"
peerDependencies:
"@types/eslint": ">=8.0.0"
eslint: ">=8.0.0"
eslint-config-prettier: "*"
prettier: ">=3.0.0"
peerDependenciesMeta:
"@types/eslint":
optional: true
eslint-config-prettier:
optional: true
checksum: 10/dc67d0ea0e0dfc0dcda176ddb3297c5616752ab8ba3369b2ff67336cfd5343bbce78c55295f0db07b07a9c8c72ceed41dca8834a4bcaab88dc8b45cf43ce7bc7
checksum: 10/4f26a30444adc61ed692cdb5a9f7e8d9f5794f0917151051e66755ce032a08c3cc72c8b5d56101412e90f6d77035bd8194ea8731e9c16aacdd5ae345a8dae188
languageName: node
linkType: hard
@@ -5529,7 +5478,7 @@ __metadata:
languageName: node
linkType: hard
"jsx-ast-utils@npm:^2.4.1 || ^3.0.0, jsx-ast-utils@npm:^3.3.5":
"jsx-ast-utils@npm:^2.4.1 || ^3.0.0":
version: 3.3.5
resolution: "jsx-ast-utils@npm:3.3.5"
dependencies:
@@ -5580,22 +5529,6 @@ __metadata:
languageName: node
linkType: hard
"language-subtag-registry@npm:^0.3.20":
version: 0.3.22
resolution: "language-subtag-registry@npm:0.3.22"
checksum: 10/5591f4abd775d1ab5945355a5ba894327d2d94c900607bdb69aac1bc5bb921dbeeeb5f616df95e8c0ae875501d19c1cfa0e852ece822121e95048deb34f2b4d2
languageName: node
linkType: hard
"language-tags@npm:^1.0.9":
version: 1.0.9
resolution: "language-tags@npm:1.0.9"
dependencies:
language-subtag-registry: "npm:^0.3.20"
checksum: 10/d3a7c14b694e67f519153d6df6cb200681648d38d623c3bfa9d6a66a5ec5493628acb88e9df5aceef3cf1902ab263a205e7d59ee4cf1d6bb67e707b83538bd6d
languageName: node
linkType: hard
"levn@npm:^0.4.1":
version: 0.4.1
resolution: "levn@npm:0.4.1"
@@ -6641,7 +6574,7 @@ __metadata:
languageName: node
linkType: hard
"postcss@npm:^8.4.36":
"postcss@npm:^8.4.38":
version: 8.4.38
resolution: "postcss@npm:8.4.38"
dependencies:
@@ -7433,13 +7366,6 @@ __metadata:
languageName: node
linkType: hard
"sockette@npm:^2.0.6":
version: 2.0.6
resolution: "sockette@npm:2.0.6"
checksum: 10/38a59afc6a61572e25066b8ac0345c3c91a5aac0447392f5d281927c7365b6d1c67de95b667fa7f9ea21cd0928ec854baaa055c264fed1e9223f37996bfd598b
languageName: node
linkType: hard
"socks-proxy-agent@npm:^8.0.1":
version: 8.0.2
resolution: "socks-proxy-agent@npm:8.0.2"
@@ -7872,7 +7798,7 @@ __metadata:
languageName: node
linkType: hard
"synckit@npm:^0.8.5":
"synckit@npm:^0.8.6":
version: 0.8.8
resolution: "synckit@npm:0.8.8"
dependencies:
@@ -8352,13 +8278,13 @@ __metadata:
languageName: node
linkType: hard
"vite@npm:^5.2.6":
version: 5.2.6
resolution: "vite@npm:5.2.6"
"vite@npm:^5.2.7":
version: 5.2.7
resolution: "vite@npm:5.2.7"
dependencies:
esbuild: "npm:^0.20.1"
fsevents: "npm:~2.3.3"
postcss: "npm:^8.4.36"
postcss: "npm:^8.4.38"
rollup: "npm:^4.13.0"
peerDependencies:
"@types/node": ^18.0.0 || >=20.0.0
@@ -8388,7 +8314,7 @@ __metadata:
optional: true
bin:
vite: bin/vite.js
checksum: 10/0409acd4bbad1bca42b2015ac5d0f710bbc84b86f6b518add9a9c13adf1aab02fd40fcca854dc08ff2a2226c1df77d5d5b4a958c6c4c04ca27a6bfb0b4f60615
checksum: 10/a00173446c8392069a70a92be78b060f7e5895f28c229eb25198953daa55c16ffbddcd4e8f015f220b2b1113e12d30e7a892221de34be336b222a12cddbb78a4
languageName: node
linkType: hard

67
mock-api/es_server.ts Normal file
View File

@@ -0,0 +1,67 @@
import express from 'express';
const rest_server = express();
const port = 3081;
const ES_ENDPOINT_ROOT = '/es/';
const ES_LOG_ENDPOINT = ES_ENDPOINT_ROOT + 'log';
const INTERVAL = 2000;
function pad(number) {
var r = String(number);
if (r.length === 1) {
r = '0' + r;
}
return r;
}
// e.g. 2024-03-29 07:02:37.856
Date.prototype.toISOString = function () {
return (
this.getUTCFullYear() +
'-' +
pad(this.getUTCMonth() + 1) +
'-' +
pad(this.getUTCDate()) +
' ' +
pad(this.getUTCHours()) +
':' +
pad(this.getUTCMinutes()) +
':' +
pad(this.getUTCSeconds()) +
'.' +
String((this.getUTCMilliseconds() / 1000).toFixed(3)).slice(2, 5)
);
};
rest_server.get(ES_LOG_ENDPOINT, (_req, res) => {
res.writeHead(200, {
Connection: 'keep-alive',
'Cache-Control': 'no-cache',
'Content-Type': 'text/event-stream'
});
let count = 0;
const interval = setInterval(() => {
const data = {
t: new Date().toISOString(),
l: 3, // error
i: count,
n: 'system',
m: 'message #' + count++
};
res.write(`data: ${JSON.stringify(data)}\n\n`);
}, INTERVAL);
// if client closes connection
res.on('close', () => {
console.log('Closing ES connection');
clearInterval(interval);
res.end();
});
});
// start eventsource server
rest_server.listen(port, () => console.log(`EMS-ESP EventSource server running on http://localhost:${port}/`));

View File

@@ -3,17 +3,16 @@
"version": "3.7.0",
"description": "mock api for EMS-ESP",
"author": "proddy",
"main": "server.ts",
"license": "MIT",
"scripts": {
"standalone": "bun --watch server.ts",
"old_standalone": "node server.js"
"mock-api": "bun --watch rest_server.ts",
"mock-es": "bun --watch es_server.ts"
},
"dependencies": {
"@msgpack/msgpack": "^2.8.0",
"compression": "^1.7.4",
"express": "^4.19.2",
"itty-router": "^4.2.2",
"itty-router": "^5.0.4",
"multer": "^1.4.5-lts.1"
},
"packageManager": "yarn@4.1.1",

View File

@@ -1,19 +1,19 @@
import { Router } from 'itty-router';
import { AutoRouter, error, status } from 'itty-router';
import { Encoder } from '@msgpack/msgpack';
// import busboy from 'busboy';
// import multer from 'multer';
// const upload = multer({ dest: '../mock-api/uploads' });
const encoder = new Encoder();
const router = Router();
// const upload = multer({ dest: '../mock-api/uploads' }); // TODO remove muter
const router = AutoRouter({
port: 3080,
missing: () => error(404, 'Error, not found')
});
const REST_ENDPOINT_ROOT = '/rest/';
const API_ENDPOINT_ROOT = '/api/';
const ES_ENDPOINT_ROOT = '/es/';
const restRouter = Router({ base: REST_ENDPOINT_ROOT });
const apiRouter = Router({ base: API_ENDPOINT_ROOT });
const esRouter = Router({ base: ES_ENDPOINT_ROOT });
// HTTP HEADERS
const headers = {
@@ -125,7 +125,7 @@ const LOG_SETTINGS_ENDPOINT = REST_ENDPOINT_ROOT + 'logSettings';
let log_settings = {
level: 6,
max_messages: 50,
compact: false
compact: true
};
const FETCH_LOG_ENDPOINT = REST_ENDPOINT_ROOT + 'fetchLog';
@@ -454,7 +454,6 @@ const EMSESP_SCANDEVICES_ENDPOINT = REST_ENDPOINT_ROOT + 'scanDevices';
// const EMSESP_DEVICEENTITIES_ENDPOINT = REST_ENDPOINT_ROOT + 'deviceEntities/:id';
const EMSESP_DEVICEDATA_ENDPOINT = REST_ENDPOINT_ROOT + 'deviceData';
const EMSESP_DEVICEENTITIES_ENDPOINT = REST_ENDPOINT_ROOT + 'deviceEntities';
const EMSESP_STATUS_ENDPOINT = REST_ENDPOINT_ROOT + 'status';
const EMSESP_BOARDPROFILE_ENDPOINT = REST_ENDPOINT_ROOT + 'boardProfile';
const EMSESP_WRITE_DEVICEVALUE_ENDPOINT = REST_ENDPOINT_ROOT + 'writeDeviceValue';
const EMSESP_WRITE_TEMPSENSOR_ENDPOINT = REST_ENDPOINT_ROOT + 'writeTemperatureSensor';
@@ -2321,91 +2320,89 @@ const emsesp_deviceentities_4 = [
// LOG
router
.post(FETCH_LOG_ENDPOINT, () => {
const encoded = encoder.encode(fetch_log);
// TODO check if still need this or just send a 200 since ES will catch up?
return new Response(encoded, { headers });
return status(200);
})
.get(LOG_SETTINGS_ENDPOINT, () => new Response(JSON.stringify(log_settings), { headers }))
.get(LOG_SETTINGS_ENDPOINT, () => log_settings)
.post(LOG_SETTINGS_ENDPOINT, async (request: any) => {
log_settings = await request.json();
return new Response('OK', { status: 200 });
return status(200);
});
// NETWORK
router
.get(NETWORK_STATUS_ENDPOINT, () => new Response(JSON.stringify(network_status), { headers }))
.get(NETWORK_SETTINGS_ENDPOINT, () => new Response(JSON.stringify(network_settings), { headers }))
.get(NETWORK_STATUS_ENDPOINT, () => network_status)
.get(NETWORK_SETTINGS_ENDPOINT, () => network_settings)
.get(LIST_NETWORKS_ENDPOINT, () => {
if (countWifiScanPoll++ === 3) {
console.log('done, sending list');
return new Response(JSON.stringify(list_networks), { headers }); // send list
return list_networks; // send list
} else {
console.log('...waiting #' + countWifiScanPoll);
return new Response('OK', { status: 200 });
return status(200);
}
})
.get(SCAN_NETWORKS_ENDPOINT, () => {
console.log('start scan networks');
countWifiScanPoll = 0; // stop the poll
return new Response('OK', { status: 202 }); // always 202, poll for list
return status(202);
})
.post(NETWORK_SETTINGS_ENDPOINT, async (request: any) => {
network_settings = await request.json();
return new Response('OK', { status: 200 });
return status(200);
});
// AP
router
.get(AP_SETTINGS_ENDPOINT, () => new Response(JSON.stringify(ap_settings), { headers }))
.get(AP_STATUS_ENDPOINT, () => new Response(JSON.stringify(ap_status), { headers }))
.get(AP_SETTINGS_ENDPOINT, () => ap_settings)
.get(AP_STATUS_ENDPOINT, () => ap_status)
.post(AP_SETTINGS_ENDPOINT, async (request: any) => {
ap_settings = await request.json();
return new Response('OK', { status: 200 });
return status(200);
});
// OTA
router
.get(OTA_SETTINGS_ENDPOINT, () => new Response(JSON.stringify(ota_settings), { headers }))
.get(OTA_SETTINGS_ENDPOINT, () => ota_settings)
.post(OTA_SETTINGS_ENDPOINT, async (request: any) => {
ota_settings = await request.json();
return new Response('OK', { status: 200 });
return status(200);
});
// MQTT
router
.get(MQTT_SETTINGS_ENDPOINT, () => new Response(JSON.stringify(mqtt_settings), { headers }))
.get(MQTT_STATUS_ENDPOINT, () => new Response(JSON.stringify(mqtt_status), { headers }))
.get(MQTT_SETTINGS_ENDPOINT, () => mqtt_settings)
.get(MQTT_STATUS_ENDPOINT, () => mqtt_status)
.post(MQTT_SETTINGS_ENDPOINT, async (request: any) => {
mqtt_settings = await request.json();
return new Response('OK', { status: 200 });
return status(200);
});
// NTP
router
.get(NTP_SETTINGS_ENDPOINT, () => new Response(JSON.stringify(ntp_settings), { headers }))
.get(NTP_STATUS_ENDPOINT, () => new Response(JSON.stringify(ntp_status), { headers }))
.post(TIME_ENDPOINT, () => new Response('OK', { status: 200 }))
.get(NTP_SETTINGS_ENDPOINT, () => ntp_settings)
.get(NTP_STATUS_ENDPOINT, () => ntp_status)
.post(TIME_ENDPOINT, () => status(200))
.post(NTP_SETTINGS_ENDPOINT, async (request: any) => {
ntp_settings = await request.json();
return new Response('OK', { status: 200 });
return status(200);
});
// SYSTEM and SETTINGS
router
.get(SYSTEM_STATUS_ENDPOINT, () => new Response(JSON.stringify(system_status), { headers }))
.get(ACTIVITY_ENDPOINT, () => new Response(JSON.stringify(activity), { headers }))
.get(ESPSYSTEM_STATUS_ENDPOINT, () => new Response(JSON.stringify(ESPsystem_status), { headers }))
.get(SECURITY_SETTINGS_ENDPOINT, () => new Response(JSON.stringify(security_settings), { headers }))
.get(SYSTEM_STATUS_ENDPOINT, () => system_status)
.get(ACTIVITY_ENDPOINT, () => activity)
.get(ESPSYSTEM_STATUS_ENDPOINT, () => ESPsystem_status)
.get(SECURITY_SETTINGS_ENDPOINT, () => security_settings)
.post(SECURITY_SETTINGS_ENDPOINT, async (request: any) => {
security_settings = await request.json();
return new Response('OK', { status: 200 });
return status(200);
})
.get(VERIFY_AUTHORIZATION_ENDPOINT, () => new Response(JSON.stringify(verify_authentication), { headers }))
.post(RESTART_ENDPOINT, () => new Response('OK', { status: 200 }))
.post(FACTORY_RESET_ENDPOINT, () => new Response('OK', { status: 200 }))
.post(UPLOAD_FILE_ENDPOINT, () => new Response('OK', { status: 404 })) // TODO remove upload when fixed
.post(SIGN_IN_ENDPOINT, () => new Response(JSON.stringify(signin), { headers }))
.get(GENERATE_TOKEN_ENDPOINT, () => new Response(JSON.stringify(generate_token), { headers }));
.get(VERIFY_AUTHORIZATION_ENDPOINT, () => verify_authentication)
.post(RESTART_ENDPOINT, () => status(200))
.post(FACTORY_RESET_ENDPOINT, () => status(200))
.post(UPLOAD_FILE_ENDPOINT, () => status(404)) // TODO remove upload when fixed
.post(SIGN_IN_ENDPOINT, () => signin)
.get(GENERATE_TOKEN_ENDPOINT, () => generate_token);
// uploads // TODO fix uploading later
@@ -2510,19 +2507,18 @@ router
router
// EMS-ESP Settings
.get(EMSESP_SETTINGS_ENDPOINT, () => new Response(JSON.stringify(settings), { headers }))
.get(EMSESP_SETTINGS_ENDPOINT, () => settings)
.post(EMSESP_SETTINGS_ENDPOINT, async (request: any) => {
settings = await request.json();
return new Response('OK', { status: 200 }); // no restart needed
// return new Response('OK', { status: 205 }); // restart needed
status(200); // no restart needed
status(205); // restart needed
})
// Device Dashboard Data
.get(EMSESP_CORE_DATA_ENDPOINT, () => new Response(JSON.stringify(emsesp_coredata), { headers }))
.get(EMSESP_SENSOR_DATA_ENDPOINT, () => new Response(JSON.stringify(emsesp_sensordata), { headers }))
.get(EMSESP_DEVICES_ENDPOINT, () => new Response(JSON.stringify(emsesp_devices), { headers }))
.post(EMSESP_SCANDEVICES_ENDPOINT, () => new Response('OK', { status: 200 }))
.get(EMSESP_STATUS_ENDPOINT, () => new Response(JSON.stringify(status), { headers }))
.get(EMSESP_CORE_DATA_ENDPOINT, () => emsesp_coredata)
.get(EMSESP_SENSOR_DATA_ENDPOINT, () => emsesp_sensordata)
.get(EMSESP_DEVICES_ENDPOINT, () => emsesp_devices)
.post(EMSESP_SCANDEVICES_ENDPOINT, () => status(200))
.get(EMSESP_DEVICEDATA_ENDPOINT, (request) => {
// const id = Number(request.params.id); // TODO when using :id
const id = Number(request.query.id);
@@ -2600,27 +2596,27 @@ router
updateMask(entity, emsesp_deviceentities_6, emsesp_devicedata_6);
}
}
return new Response('OK', { status: 200 });
return status(200);
})
.post(EMSESP_RESET_CUSTOMIZATIONS_ENDPOINT, async (request: any) => {
return new Response('OK', { status: 200 });
return status(200);
})
// Scheduler
.post(EMSESP_SCHEDULE_ENDPOINT, async (request: any) => {
const content = await request.json();
emsesp_schedule = content;
return new Response('OK', { status: 200 });
return status(200);
})
.get(EMSESP_SCHEDULE_ENDPOINT, () => new Response(JSON.stringify(emsesp_schedule), { headers }))
.get(EMSESP_SCHEDULE_ENDPOINT, () => emsesp_schedule)
// Custom Entities
.post(EMSESP_CUSTOMENTITIES_ENDPOINT, async (request: any) => {
const content = await request.json();
emsesp_customentities = content;
return new Response('OK', { status: 200 });
return status(200);
})
.get(EMSESP_CUSTOMENTITIES_ENDPOINT, () => new Response(JSON.stringify(emsesp_customentities), { headers }))
.get(EMSESP_CUSTOMENTITIES_ENDPOINT, () => emsesp_customentities)
// Device Dashboard
.post(EMSESP_WRITE_DEVICEVALUE_ENDPOINT, async (request: any) => {
@@ -2665,7 +2661,7 @@ router
}
await delay(1000); // wait to show spinner
return new Response('OK', { status: 200 }); // or 400 for bad request
return status(200);
})
// Temperature & Analog Sensors
@@ -2676,7 +2672,7 @@ router
emsesp_sensordata.ts[objIndex].n = ts.name;
emsesp_sensordata.ts[objIndex].o = ts.offset;
}
return new Response('OK', { status: 200 });
return status(200);
})
.post(EMSESP_WRITE_ANALOGSENSOR_ENDPOINT, async (request: any) => {
const as = await request.json();
@@ -2709,7 +2705,7 @@ router
}
}
return new Response('OK', { status: 200 });
return status(200);
})
// Settings - board profile
@@ -2841,103 +2837,30 @@ router
data.eth_clock_mode = 0;
}
return new Response(JSON.stringify(data), { headers });
return data;
})
// Download Settings
.get(EMSESP_GET_SETTINGS_ENDPOINT, () => new Response(JSON.stringify(emsesp_info), { headers }))
.get(EMSESP_GET_CUSTOMIZATIONS_ENDPOINT, () => new Response(JSON.stringify(emsesp_deviceentities_1), { headers }))
.get(EMSESP_GET_ENTITIES_ENDPOINT, () => new Response(JSON.stringify(emsesp_customentities), { headers }))
.get(EMSESP_GET_SCHEDULE_ENDPOINT, () => new Response(JSON.stringify(emsesp_schedule), { headers }));
.get(EMSESP_GET_SETTINGS_ENDPOINT, () => emsesp_info)
.get(EMSESP_GET_CUSTOMIZATIONS_ENDPOINT, () => emsesp_deviceentities_1)
.get(EMSESP_GET_ENTITIES_ENDPOINT, () => emsesp_customentities)
.get(EMSESP_GET_SCHEDULE_ENDPOINT, () => emsesp_schedule);
// API which are usually POST for security
router
.post(EMSESP_SYSTEM_INFO_ENDPOINT, () => new Response(JSON.stringify(emsesp_info), { headers }))
.get(EMSESP_SYSTEM_INFO_ENDPOINT, () => new Response(JSON.stringify(emsesp_info), { headers }))
.post(EMSESP_SYSTEM_INFO_ENDPOINT, () => emsesp_info)
.get(EMSESP_SYSTEM_INFO_ENDPOINT, () => emsesp_info)
.post(API_ENDPOINT_ROOT, async (request: any) => {
const data = await request.json();
if (data.device === 'system') {
if (data.entity === 'info') {
return new Response(JSON.stringify(emsesp_info), { headers });
return emsesp_info;
}
if (data.entity === 'allvalues') {
return new Response(JSON.stringify(emsesp_allvalues), { headers });
return emsesp_allvalues;
}
}
return new Response('Not Found', { status: 404 });
return status(404); // not found
});
//
// Event Source // TODO fix event source later
//
// const data = {
// t: '000+00:00:00.000',
// l: 3, // error
// i: 1,
// n: 'system',
// m: 'incoming message #1'
// };
// const sseFormattedResponse = `data: ${JSON.stringify(data)}\n\n`;
// router.get('/es/log', () => new Response(sseFormattedResponse, { headers: ESheaders }));
var count = 8;
var log_index = 0;
const ES_LOG_ENDPOINT = ES_ENDPOINT_ROOT + 'log';
// new Response({
// headers: {
// 'content-type': 'application/json',
// 'Content-Type': 'text/event-stream',
// 'Cache-Control': 'no-cache',
// 'Access-Control-Allow-Origin': '*',
// 'Connection': 'keep-alive'
// },
// body: '{"foo":"bar"}'
// })
// rest_server.get(ES_LOG_ENDPOINT, function (req, res) {
// res.setHeader('Content-Type', 'text/event-stream');
// res.setHeader('Cache-Control', 'no-cache');
// res.setHeader('Access-Control-Allow-Origin', '*');
// res.setHeader('Connection', 'keep-alive');
// res.flushHeaders();
let sseFormattedResponse = '';
// var timer = setInterval(function () {
// count += 1;
// log_index += 1;
// const data = {
// t: '000+00:00:00.000',
// l: 3, // error
// i: count,
// n: 'system',
// m: 'incoming message #' + count + '/' + log_index
// };
// sseFormattedResponse = `data: ${JSON.stringify(data)}\n\n`;
// console.log('done');
// // res.write(sseFormattedResponse);
// // res.flush(); // this is important
// // if buffer is full, start over
// if (log_index > 50) {
// fetch_log.events = [];
// log_index = 0;
// }
// fetch_log.events.push(data); // append to buffer
// }, 300);
router.get(ES_LOG_ENDPOINT, () => new Response(sseFormattedResponse, { headers: ESheaders }));
// Tie it all together
const missingHandler = () => new Response('Not found.', { status: 404 });
router
.all('/api/*', apiRouter.handle)
.all('/rest/*', restRouter.handle)
.all('/es/*', esRouter.handle)
.all('*', missingHandler);
const errorHandler = (error: any) => new Response(error.message || 'Server Error', { status: error.status || 500 });
export const handleRequest = (request: any) => router.handle(request).catch(errorHandler);
export default router;

View File

@@ -1,6 +0,0 @@
import { handleRequest } from './handler';
export default {
port: 3080,
fetch: (request) => handleRequest(request)
};

View File

@@ -140,7 +140,7 @@ __metadata:
"@types/multer": "npm:^1.4.11"
compression: "npm:^1.7.4"
express: "npm:^4.19.2"
itty-router: "npm:^4.2.2"
itty-router: "npm:^5.0.4"
multer: "npm:^1.4.5-lts.1"
languageName: unknown
linkType: soft
@@ -526,10 +526,10 @@ __metadata:
languageName: node
linkType: hard
"itty-router@npm:^4.2.2":
version: 4.2.2
resolution: "itty-router@npm:4.2.2"
checksum: 10/ead44fd46ea358776dc2bb120970eff5ab0acb10ad82c384eba9b361c6eba7f5971408f80cbc3655004cb12ae53dd77a85de236bdb215cef896c2589f5096854
"itty-router@npm:^5.0.4":
version: 5.0.4
resolution: "itty-router@npm:5.0.4"
checksum: 10/61c5c12b57e592ae9689782ca59d7b77154909eb52fc019c38f34e03fdce3d7fb50aad930bde0b31ef8d9131d2101141517823416886b36b81ba3ec6a0ff819e
languageName: node
linkType: hard

View File

@@ -39,7 +39,7 @@ unbuild_flags =
${common.core_unbuild_flags}
[espressi32_base]
platform = espressif32@6.5.0
platform = espressif32@6.6.0
framework = arduino
board_build.filesystem = littlefs
build_flags = ${common.build_flags}

View File

@@ -5,6 +5,7 @@
@host = http://ems-esp.local
@host_dev = http://10.10.10.20
@host_standalone = http://localhost:3080
@token = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiYWRtaW4iOnRydWV9.2bHpWya2C7Q12WjNUBD6_7N3RCD7CMl-EGhyQVzFdDg
@@ -106,3 +107,10 @@ Authorization: Bearer {{token}}
###
GET {{host_dev}}/api/thermostat/seltemp
#### STANDALONE ####
GET {{host_standalone}}/api/system/info
###