diff --git a/display/middleware/package-lock.json b/display/middleware/package-lock.json index d0c789f..f93a4e6 100644 --- a/display/middleware/package-lock.json +++ b/display/middleware/package-lock.json @@ -8,8 +8,6 @@ "name": "display-middleware", "version": "1.0.0", "dependencies": { - "@types/bcryptjs": "^2.4.6", - "bcrypt": "^5.1.1", "bcryptjs": "^3.0.3", "better-sqlite3": "^9.6.0", "cors": "^2.8.6", @@ -20,7 +18,7 @@ "pg": "^8.20.0" }, "devDependencies": { - "@types/bcrypt": "^5.0.2", + "@types/bcryptjs": "^2.4.6", "@types/better-sqlite3": "^7.6.13", "@types/cors": "^2.8.19", "@types/express": "^4.17.25", @@ -505,26 +503,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@mapbox/node-pre-gyp": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz", - "integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==", - "license": "BSD-3-Clause", - "dependencies": { - "detect-libc": "^2.0.0", - "https-proxy-agent": "^5.0.0", - "make-dir": "^3.1.0", - "node-fetch": "^2.6.7", - "nopt": "^5.0.0", - "npmlog": "^5.0.1", - "rimraf": "^3.0.2", - "semver": "^7.3.5", - "tar": "^6.1.11" - }, - "bin": { - "node-pre-gyp": "bin/node-pre-gyp" - } - }, "node_modules/@noble/hashes": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", @@ -944,20 +922,11 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/bcrypt": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@types/bcrypt/-/bcrypt-5.0.2.tgz", - "integrity": "sha512-6atioO8Y75fNcbmj0G7UjI9lXN2pQ/IGJ2FWT4a/btd0Lk9lQalHLKhkgKVZ3r+spnmWUKfbMi1GEe9wyHQfNQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/bcryptjs": { "version": "2.4.6", "resolved": "https://registry.npmjs.org/@types/bcryptjs/-/bcryptjs-2.4.6.tgz", "integrity": "sha512-9xlo6R2qDs5uixm0bcIqCeMCE6HiQsIyel9KQySStiyqNl2tnj2mP3DX1Nf56MD6KMenNNlBBsy3LJ7gUEQPXQ==", + "dev": true, "license": "MIT" }, "node_modules/@types/better-sqlite3": { @@ -1264,12 +1233,6 @@ "url": "https://opencollective.com/vitest" } }, - "node_modules/abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "license": "ISC" - }, "node_modules/abort-controller": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", @@ -1321,50 +1284,6 @@ "node": ">=0.4.0" } }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "license": "MIT", - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/agent-base/node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/agent-base/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/ansi-styles": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", @@ -1378,40 +1297,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/aproba": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.1.0.tgz", - "integrity": "sha512-tLIEcj5GuR2RSTnxNKdkK0dJ/GrC7P38sUkiDmDuHfsHmbagTFAxDVIBltoklXEVIQ/f14IL8IMJ5pn9Hez1Ew==", - "license": "ISC" - }, - "node_modules/are-we-there-yet": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", - "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", - "deprecated": "This package is no longer supported.", - "license": "ISC", - "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^3.6.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/are-we-there-yet/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", @@ -1442,12 +1327,6 @@ "dev": true, "license": "MIT" }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "license": "MIT" - }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -1468,20 +1347,6 @@ ], "license": "MIT" }, - "node_modules/bcrypt": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.1.1.tgz", - "integrity": "sha512-AGBHOG5hPYZ5Xl9KXzU5iKq9516yEmvCKDg3ecP5kX2aB6UqTeXZxk2ELnDgDm6BQSMlLt9rDB4LoSMx0rYwww==", - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "@mapbox/node-pre-gyp": "^1.0.11", - "node-addon-api": "^5.0.0" - }, - "engines": { - "node": ">= 10.0.0" - } - }, "node_modules/bcryptjs": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-3.0.3.tgz", @@ -1547,16 +1412,6 @@ "npm": "1.2.8000 || >= 1.4.16" } }, - "node_modules/brace-expansion": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", - "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, "node_modules/broker-factory": { "version": "3.1.14", "resolved": "https://registry.npmjs.org/broker-factory/-/broker-factory-3.1.14.tgz", @@ -1685,24 +1540,6 @@ "node": "*" } }, - "node_modules/chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/color-support": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "license": "ISC", - "bin": { - "color-support": "bin.js" - } - }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -1732,12 +1569,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "license": "MIT" - }, "node_modules/concat-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", @@ -1774,12 +1605,6 @@ "dev": true, "license": "MIT" }, - "node_modules/console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", - "license": "ISC" - }, "node_modules/content-disposition": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", @@ -1911,12 +1736,6 @@ "node": ">=0.4.0" } }, - "node_modules/delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", - "license": "MIT" - }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -1995,12 +1814,6 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", "license": "MIT" }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT" - }, "node_modules/encodeurl": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", @@ -2343,36 +2156,6 @@ "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", "license": "MIT" }, - "node_modules/fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/fs-minipass/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "license": "ISC" - }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -2397,27 +2180,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/gauge": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", - "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", - "deprecated": "This package is no longer supported.", - "license": "ISC", - "dependencies": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.2", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.1", - "object-assign": "^4.1.1", - "signal-exit": "^3.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.2" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/get-func-name": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", @@ -2497,27 +2259,6 @@ "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", "license": "MIT" }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/gopd": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", @@ -2558,12 +2299,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", - "license": "ISC" - }, "node_modules/hasown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", @@ -2602,42 +2337,6 @@ "url": "https://opencollective.com/express" } }, - "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "license": "MIT", - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/https-proxy-agent/node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/https-proxy-agent/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, "node_modules/human-signals": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", @@ -2680,17 +2379,6 @@ ], "license": "BSD-3-Clause" }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "license": "ISC", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", @@ -2721,15 +2409,6 @@ "node": ">= 0.10" } }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/is-stream": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", @@ -2901,30 +2580,6 @@ "@jridgewell/sourcemap-codec": "^1.5.5" } }, - "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "license": "MIT", - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/make-dir/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -3026,18 +2681,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/minimatch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", - "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/minimist": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", @@ -3047,52 +2690,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/minipass": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", - "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", - "license": "ISC", - "engines": { - "node": ">=8" - } - }, - "node_modules/minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "license": "MIT", - "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minizlib/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "license": "MIT", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/mkdirp-classic": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", @@ -3260,53 +2857,12 @@ "node": ">=10" } }, - "node_modules/node-addon-api": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", - "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==", - "license": "MIT" - }, - "node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "license": "MIT", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, "node_modules/node-sqlite3-wasm": { "version": "0.8.55", "resolved": "https://registry.npmjs.org/node-sqlite3-wasm/-/node-sqlite3-wasm-0.8.55.tgz", "integrity": "sha512-C2m7JzZgKiv9XVZ1ts9oPmS56PCvyHeQffTOF2KNO2TVZzq5IW2s+NFeEZn+eP6bnAuD2We/O9cOJSjQVf7Xxw==", "license": "MIT" }, - "node_modules/nopt": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", - "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", - "license": "ISC", - "dependencies": { - "abbrev": "1" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/npm-run-path": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", @@ -3336,19 +2892,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/npmlog": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", - "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", - "deprecated": "This package is no longer supported.", - "license": "ISC", - "dependencies": { - "are-we-there-yet": "^2.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^3.0.0", - "set-blocking": "^2.0.0" - } - }, "node_modules/number-allocator": { "version": "1.0.14", "resolved": "https://registry.npmjs.org/number-allocator/-/number-allocator-1.0.14.tgz", @@ -3465,15 +3008,6 @@ "node": ">= 0.8" } }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -3863,22 +3397,6 @@ "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", "license": "MIT" }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/rollup": { "version": "4.60.1", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.1.tgz", @@ -4007,12 +3525,6 @@ "node": ">= 0.8.0" } }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "license": "ISC" - }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -4121,12 +3633,6 @@ "dev": true, "license": "ISC" }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "license": "ISC" - }, "node_modules/simple-concat": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", @@ -4247,32 +3753,6 @@ "safe-buffer": "~5.2.0" } }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/strip-final-newline": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", @@ -4384,24 +3864,6 @@ "node": ">=6.4.0" } }, - "node_modules/tar": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", - "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", - "deprecated": "Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", - "license": "ISC", - "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^5.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/tar-fs": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.4.tgz", @@ -4521,12 +3983,6 @@ "node": ">=0.6" } }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "license": "MIT" - }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", @@ -5283,22 +4739,6 @@ "dev": true, "license": "MIT" }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "license": "BSD-2-Clause" - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "license": "MIT", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -5332,15 +4772,6 @@ "node": ">=8" } }, - "node_modules/wide-align": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", - "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", - "license": "ISC", - "dependencies": { - "string-width": "^1.0.2 || 2 || 3 || 4" - } - }, "node_modules/worker-factory": { "version": "7.0.49", "resolved": "https://registry.npmjs.org/worker-factory/-/worker-factory-7.0.49.tgz", @@ -5424,12 +4855,6 @@ "node": ">=0.4" } }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "license": "ISC" - }, "node_modules/yocto-queue": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.2.tgz", diff --git a/display/middleware/src/api/routes/display-api.ts b/display/middleware/src/api/routes/display-api.ts index 83487cd..a74a0fe 100644 --- a/display/middleware/src/api/routes/display-api.ts +++ b/display/middleware/src/api/routes/display-api.ts @@ -44,10 +44,9 @@ router.get('/:id', (req: Request, res: Response): void => { } // Update last_seen - db.run( - `UPDATE displays SET last_seen = datetime('now') WHERE id = ?`, - [displayId] - ); + db.prepare( + `UPDATE displays SET last_seen = datetime('now') WHERE id = ?` + ).run(displayId); const json = buildDisplayJson(displayId); if (!json) { diff --git a/display/middleware/src/api/routes/displays.ts b/display/middleware/src/api/routes/displays.ts index d74cebc..9e6d980 100644 --- a/display/middleware/src/api/routes/displays.ts +++ b/display/middleware/src/api/routes/displays.ts @@ -43,11 +43,10 @@ router.post('/', (req, res): void => { const { name, description, layout_id, api_token, refresh_sec } = req.body; if (!name) { res.status(400).json({ error: 'name is required' }); return; } - const result = db.run( + const result = db.prepare( `INSERT INTO displays (name, description, layout_id, api_token, refresh_sec) - VALUES (?, ?, ?, ?, ?)`, - [name, description ?? null, layout_id ?? null, api_token ?? null, refresh_sec ?? 300] - ); + VALUES (?, ?, ?, ?, ?)` + ).run(name, description ?? null, layout_id ?? null, api_token ?? null, refresh_sec ?? 300); const id = result.lastInsertRowid as number; res.status(201).json(db.prepare('SELECT * FROM displays WHERE id = ?').get(id)); } catch (err) { @@ -78,7 +77,7 @@ router.put('/:id', (req, res): void => { } values.push(id); - db.run(`UPDATE displays SET ${fields.join(', ')} WHERE id = ?`, values); + db.prepare(`UPDATE displays SET ${fields.join(', ')} WHERE id = ?`).run(...values); const display = db.prepare('SELECT * FROM displays WHERE id = ?').get(id); if (!display) { res.status(404).json({ error: 'Display not found' }); return; } res.json(display); @@ -91,7 +90,7 @@ router.put('/:id', (req, res): void => { router.delete('/:id', (req, res): void => { try { const db = getDb(); - const result = db.run('DELETE FROM displays WHERE id = ?', [parseInt(req.params.id)]); + const result = db.prepare('DELETE FROM displays WHERE id = ?').run(parseInt(req.params.id)); if ((result.changes as number) === 0) { res.status(404).json({ error: 'Display not found' }); return; } res.status(204).send(); } catch (err) { diff --git a/display/middleware/src/db/index.ts b/display/middleware/src/db/index.ts index 68a0c9b..1c202a1 100644 --- a/display/middleware/src/db/index.ts +++ b/display/middleware/src/db/index.ts @@ -1,16 +1,13 @@ -import { Database } from 'node-sqlite3-wasm'; +import Database from 'better-sqlite3'; import { migrate001 } from './migrations/001-initial'; -let dbInstance: Database | null = null; +let dbInstance: Database.Database | null = null; -export function initDb(path: string): Database { - // node-sqlite3-wasm: pass undefined for in-memory DB - const db = new Database(path === ':memory:' ? undefined : path); +export function initDb(path: string): Database.Database { + const db = new Database(path === ':memory:' ? ':memory:' : path); - // Enable WAL mode (file-based databases only, :memory: uses 'memory' mode) - db.exec('PRAGMA journal_mode = WAL'); - // Enable foreign key constraints - db.exec('PRAGMA foreign_keys = ON'); + db.pragma('journal_mode = WAL'); + db.pragma('foreign_keys = ON'); // Run migrations migrate001(db); @@ -19,7 +16,7 @@ export function initDb(path: string): Database { return db; } -export function getDb(): Database { +export function getDb(): Database.Database { if (!dbInstance) { throw new Error('Database not initialized. Call initDb() first.'); } diff --git a/display/middleware/src/db/migrations/001-initial.ts b/display/middleware/src/db/migrations/001-initial.ts index 287a40e..990627d 100644 --- a/display/middleware/src/db/migrations/001-initial.ts +++ b/display/middleware/src/db/migrations/001-initial.ts @@ -1,4 +1,4 @@ -import { Database } from 'node-sqlite3-wasm'; +import Database from 'better-sqlite3'; export function migrate001(db: Database): void { db.exec(` diff --git a/display/middleware/src/index.ts b/display/middleware/src/index.ts index b4b0d49..b9273f4 100644 --- a/display/middleware/src/index.ts +++ b/display/middleware/src/index.ts @@ -19,10 +19,9 @@ async function main(): Promise { if (userCount.count === 0) { const hash = bcrypt.hashSync('admin', 10); - db.run( - `INSERT INTO users (username, password_hash) VALUES (?, ?)`, - ['admin', hash] - ); + db.prepare( + `INSERT INTO users (username, password_hash) VALUES (?, ?)` + ).run('admin', hash); console.log('Created default admin user (admin/admin)'); } diff --git a/display/middleware/src/modules/datapoints/datapoint-manager.ts b/display/middleware/src/modules/datapoints/datapoint-manager.ts index 9061983..6e64e5c 100644 --- a/display/middleware/src/modules/datapoints/datapoint-manager.ts +++ b/display/middleware/src/modules/datapoints/datapoint-manager.ts @@ -54,10 +54,9 @@ export function updateDatapointValue(id: number, rawValue: string): Datapoint | const transformed = applyTransform(rawValue, config); - db.run( - `UPDATE datapoints SET value = ?, status = 'ok', updated_at = datetime('now') WHERE id = ?`, - [transformed, id] - ); + db.prepare( + `UPDATE datapoints SET value = ?, status = 'ok', updated_at = datetime('now') WHERE id = ?` + ).run(transformed, id); return db.prepare('SELECT * FROM datapoints WHERE id = ?').get(id) as Datapoint | undefined; } @@ -87,7 +86,7 @@ export function updateDatapoint(id: number, data: DatapointUpdate): Datapoint | if (fields.length === 0) return getDatapointById(id); values.push(id); - db.run(`UPDATE datapoints SET ${fields.join(', ')} WHERE id = ?`, values); + db.prepare(`UPDATE datapoints SET ${fields.join(', ')} WHERE id = ?`).run(...values); return getDatapointById(id); } @@ -97,11 +96,10 @@ export function createDatapointFromMqtt( topicPath: string ): Datapoint { const db = getDb(); - const result = db.run( + const result = db.prepare( `INSERT INTO datapoints (name, label, source_type, source_id, topic_id, enabled) - VALUES (?, ?, 'mqtt', ?, ?, 1)`, - [topicPath, topicPath, brokerId, topicId] - ); + VALUES (?, ?, 'mqtt', ?, ?, 1)` + ).run(topicPath, topicPath, brokerId, topicId); const id = result.lastInsertRowid as number; return db.prepare('SELECT * FROM datapoints WHERE id = ?').get(id) as Datapoint; } @@ -112,11 +110,10 @@ export function createDatapointFromPg( queryName: string ): Datapoint { const db = getDb(); - const result = db.run( + const result = db.prepare( `INSERT INTO datapoints (name, label, source_type, source_id, query_id, enabled) - VALUES (?, ?, 'postgresql', ?, ?, 1)`, - [queryName, queryName, sourceId, queryId] - ); + VALUES (?, ?, 'postgresql', ?, ?, 1)` + ).run(queryName, queryName, sourceId, queryId); const id = result.lastInsertRowid as number; return db.prepare('SELECT * FROM datapoints WHERE id = ?').get(id) as Datapoint; } diff --git a/display/middleware/src/modules/display/layout-manager.ts b/display/middleware/src/modules/display/layout-manager.ts index 64d8e72..445a4e0 100644 --- a/display/middleware/src/modules/display/layout-manager.ts +++ b/display/middleware/src/modules/display/layout-manager.ts @@ -92,17 +92,16 @@ export function getLayoutById(id: number): LayoutWithElements | undefined { export function createLayout(data: CreateLayoutData): Layout { const db = getDb(); - const result = db.run( + const result = db.prepare( `INSERT INTO layouts (name, type, width, height, grid_cols, grid_rows) - VALUES (?, ?, ?, ?, ?, ?)`, - [ - data.name, - data.type ?? 'free', - data.width ?? 800, - data.height ?? 480, - data.grid_cols ?? null, - data.grid_rows ?? null, - ] + VALUES (?, ?, ?, ?, ?, ?)` + ).run( + data.name, + data.type ?? 'free', + data.width ?? 800, + data.height ?? 480, + data.grid_cols ?? null, + data.grid_rows ?? null, ); const id = result.lastInsertRowid as number; return db.prepare('SELECT * FROM layouts WHERE id = ?').get(id) as Layout; @@ -125,41 +124,40 @@ export function updateLayout(id: number, data: UpdateLayoutData): Layout | undef } values.push(id); - db.run(`UPDATE layouts SET ${fields.join(', ')} WHERE id = ?`, values); + db.prepare(`UPDATE layouts SET ${fields.join(', ')} WHERE id = ?`).run(...values); return db.prepare('SELECT * FROM layouts WHERE id = ?').get(id) as Layout | undefined; } export function deleteLayout(id: number): boolean { const db = getDb(); - const result = db.run('DELETE FROM layouts WHERE id = ?', [id]); + const result = db.prepare('DELETE FROM layouts WHERE id = ?').run(id); return (result.changes as number) > 0; } export function addElement(layoutId: number, data: CreateElementData): LayoutElement { const db = getDb(); - const result = db.run( + const result = db.prepare( `INSERT INTO layout_elements (layout_id, datapoint_id, type, x, y, width, height, font_size, font_weight, text_align, icon, style, static_text, grid_col, grid_row, sort_order) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, - [ - layoutId, - data.datapoint_id ?? null, - data.type, - data.x ?? 0, - data.y ?? 0, - data.width ?? null, - data.height ?? null, - data.font_size ?? 24, - data.font_weight ?? 'normal', - data.text_align ?? 'left', - data.icon ?? null, - data.style ?? 'plain', - data.static_text ?? null, - data.grid_col ?? null, - data.grid_row ?? null, - data.sort_order ?? 0, - ] + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)` + ).run( + layoutId, + data.datapoint_id ?? null, + data.type, + data.x ?? 0, + data.y ?? 0, + data.width ?? null, + data.height ?? null, + data.font_size ?? 24, + data.font_weight ?? 'normal', + data.text_align ?? 'left', + data.icon ?? null, + data.style ?? 'plain', + data.static_text ?? null, + data.grid_col ?? null, + data.grid_row ?? null, + data.sort_order ?? 0, ); const id = result.lastInsertRowid as number; return db.prepare('SELECT * FROM layout_elements WHERE id = ?').get(id) as LayoutElement; @@ -200,12 +198,12 @@ export function updateElement(id: number, data: UpdateElementData): LayoutElemen } values.push(id); - db.run(`UPDATE layout_elements SET ${fields.join(', ')} WHERE id = ?`, values); + db.prepare(`UPDATE layout_elements SET ${fields.join(', ')} WHERE id = ?`).run(...values); return db.prepare('SELECT * FROM layout_elements WHERE id = ?').get(id) as LayoutElement | undefined; } export function deleteElement(id: number): boolean { const db = getDb(); - const result = db.run('DELETE FROM layout_elements WHERE id = ?', [id]); + const result = db.prepare('DELETE FROM layout_elements WHERE id = ?').run(id); return (result.changes as number) > 0; } diff --git a/display/middleware/src/modules/mqtt/broker-manager.ts b/display/middleware/src/modules/mqtt/broker-manager.ts index cd73aa8..32d0ece 100644 --- a/display/middleware/src/modules/mqtt/broker-manager.ts +++ b/display/middleware/src/modules/mqtt/broker-manager.ts @@ -55,18 +55,17 @@ export function getBrokerById(id: number): MqttBroker | undefined { export function createBroker(data: CreateBrokerData): MqttBroker { const db = getDb(); - const result = db.run( + const result = db.prepare( `INSERT INTO mqtt_brokers (name, host, port, username, password, use_tls, enabled) - VALUES (?, ?, ?, ?, ?, ?, ?)`, - [ - data.name, - data.host, - data.port ?? 1883, - data.username ?? null, - data.password ?? null, - data.use_tls ?? 0, - data.enabled ?? 1, - ] + VALUES (?, ?, ?, ?, ?, ?, ?)` + ).run( + data.name, + data.host, + data.port ?? 1883, + data.username ?? null, + data.password ?? null, + data.use_tls ?? 0, + data.enabled ?? 1, ); const id = result.lastInsertRowid as number; return db.prepare('SELECT * FROM mqtt_brokers WHERE id = ?').get(id) as MqttBroker; @@ -89,14 +88,14 @@ export function updateBroker(id: number, data: UpdateBrokerData): MqttBroker | u fields.push("updated_at = datetime('now')"); values.push(id); - db.run(`UPDATE mqtt_brokers SET ${fields.join(', ')} WHERE id = ?`, values); + db.prepare(`UPDATE mqtt_brokers SET ${fields.join(', ')} WHERE id = ?`).run(...values); return getBrokerById(id); } export function deleteBroker(id: number): boolean { const db = getDb(); disconnectBroker(id); - const result = db.run('DELETE FROM mqtt_brokers WHERE id = ?', [id]); + const result = db.prepare('DELETE FROM mqtt_brokers WHERE id = ?').run(id); return (result.changes as number) > 0; } @@ -107,10 +106,9 @@ function buildConnectUrl(broker: MqttBroker): string { function setStatus(id: number, status: string): void { const db = getDb(); - db.run( - `UPDATE mqtt_brokers SET status = ?, updated_at = datetime('now') WHERE id = ?`, - [status, id] - ); + db.prepare( + `UPDATE mqtt_brokers SET status = ?, updated_at = datetime('now') WHERE id = ?` + ).run(status, id); } export function connectBroker(id: number): Promise { @@ -172,7 +170,7 @@ export function connectBroker(id: number): Promise { .get(id, t) as MqttTopic | undefined; if (!topicRecord) continue; - db.run('UPDATE mqtt_topics SET last_payload = ? WHERE id = ?', [p, topicRecord.id]); + db.prepare('UPDATE mqtt_topics SET last_payload = ? WHERE id = ?').run(p, topicRecord.id); const extracted = extractValue(p, topicRecord.json_path); if (extracted === null) continue; diff --git a/display/middleware/src/modules/mqtt/topic-discovery.ts b/display/middleware/src/modules/mqtt/topic-discovery.ts index eaff9f2..9ab937a 100644 --- a/display/middleware/src/modules/mqtt/topic-discovery.ts +++ b/display/middleware/src/modules/mqtt/topic-discovery.ts @@ -40,7 +40,7 @@ export function updateTopic(id: number, data: UpdateTopicData): MqttTopic | unde } values.push(id); - db.run(`UPDATE mqtt_topics SET ${fields.join(', ')} WHERE id = ?`, values); + db.prepare(`UPDATE mqtt_topics SET ${fields.join(', ')} WHERE id = ?`).run(...values); return db.prepare('SELECT * FROM mqtt_topics WHERE id = ?').get(id) as MqttTopic | undefined; } @@ -51,11 +51,10 @@ function ensureTopicExists(brokerId: number, topic: string): void { .get(brokerId, topic); if (!existing) { - db.run( + db.prepare( `INSERT INTO mqtt_topics (broker_id, topic, selected, ignored) - VALUES (?, ?, 0, 0)`, - [brokerId, topic] - ); + VALUES (?, ?, 0, 0)` + ).run(brokerId, topic); } } @@ -105,10 +104,9 @@ export function startDiscovery(brokerId: number, prefix?: string): Promise 0; } @@ -99,10 +98,9 @@ async function executeQuery(queryId: number): Promise { const valueStr = String(rawValue); const db = getDb(); - db.run( - `UPDATE pg_queries SET last_result = ?, last_run_at = datetime('now') WHERE id = ?`, - [valueStr, queryId] - ); + db.prepare( + `UPDATE pg_queries SET last_result = ?, last_run_at = datetime('now') WHERE id = ?` + ).run(valueStr, queryId); const dp = getDatapointByQueryId(queryId); if (dp) { diff --git a/display/middleware/src/modules/postgres/source-manager.ts b/display/middleware/src/modules/postgres/source-manager.ts index 0bb8d61..af71a96 100644 --- a/display/middleware/src/modules/postgres/source-manager.ts +++ b/display/middleware/src/modules/postgres/source-manager.ts @@ -42,19 +42,18 @@ export function getSourceById(id: number): PgSource | undefined { export function createSource(data: CreateSourceData): PgSource { const db = getDb(); - const result = db.run( + const result = db.prepare( `INSERT INTO pg_sources (name, host, port, database_name, username, password, use_tls, enabled) - VALUES (?, ?, ?, ?, ?, ?, ?, ?)`, - [ - data.name, - data.host, - data.port ?? 5432, - data.database_name, - data.username, - data.password, - data.use_tls ?? 0, - data.enabled ?? 1, - ] + VALUES (?, ?, ?, ?, ?, ?, ?, ?)` + ).run( + data.name, + data.host, + data.port ?? 5432, + data.database_name, + data.username, + data.password, + data.use_tls ?? 0, + data.enabled ?? 1, ); const id = result.lastInsertRowid as number; return db.prepare('SELECT * FROM pg_sources WHERE id = ?').get(id) as PgSource; @@ -77,20 +76,20 @@ export function updateSource(id: number, data: UpdateSourceData): PgSource | und if (fields.length === 0) return getSourceById(id); values.push(id); - db.run(`UPDATE pg_sources SET ${fields.join(', ')} WHERE id = ?`, values); + db.prepare(`UPDATE pg_sources SET ${fields.join(', ')} WHERE id = ?`).run(...values); return getSourceById(id); } export function deleteSource(id: number): boolean { const db = getDb(); disconnectSource(id); - const result = db.run('DELETE FROM pg_sources WHERE id = ?', [id]); + const result = db.prepare('DELETE FROM pg_sources WHERE id = ?').run(id); return (result.changes as number) > 0; } function setStatus(id: number, status: string): void { const db = getDb(); - db.run('UPDATE pg_sources SET status = ? WHERE id = ?', [status, id]); + db.prepare('UPDATE pg_sources SET status = ? WHERE id = ?').run(status, id); } export async function connectSource(id: number): Promise { diff --git a/display/middleware/tests/api/auth.test.ts b/display/middleware/tests/api/auth.test.ts index 01d4bef..ceed5f7 100644 --- a/display/middleware/tests/api/auth.test.ts +++ b/display/middleware/tests/api/auth.test.ts @@ -8,10 +8,9 @@ beforeAll(() => { const db = initDb(':memory:'); // Create a test user const hash = bcrypt.hashSync('correctpassword', 10); - db.run( - `INSERT INTO users (username, password_hash) VALUES (?, ?)`, - ['testuser', hash] - ); + db.prepare( + `INSERT INTO users (username, password_hash) VALUES (?, ?)` + ).run('testuser', hash); }); afterAll(() => { diff --git a/display/middleware/tests/api/display-api.test.ts b/display/middleware/tests/api/display-api.test.ts index 6c85f8e..27e2ed4 100644 --- a/display/middleware/tests/api/display-api.test.ts +++ b/display/middleware/tests/api/display-api.test.ts @@ -9,22 +9,22 @@ beforeAll(() => { const db = initDb(':memory:'); // Create a layout - db.run( + db.prepare( `INSERT INTO layouts (id, name, type, width, height) VALUES (1, 'Test Layout', 'free', 800, 480)` - ); + ).run(); // Display without token - db.run( + db.prepare( `INSERT INTO displays (id, name, layout_id, refresh_sec) VALUES (1, 'Open Display', 1, 60)` - ); + ).run(); // Display with token auth - db.run( + db.prepare( `INSERT INTO displays (id, name, layout_id, api_token, refresh_sec) VALUES (2, 'Secure Display', 1, 'secret-token-123', 300)` - ); + ).run(); }); afterAll(() => { diff --git a/display/middleware/tests/db.test.ts b/display/middleware/tests/db.test.ts index c5fc393..91617c5 100644 --- a/display/middleware/tests/db.test.ts +++ b/display/middleware/tests/db.test.ts @@ -1,8 +1,8 @@ import { describe, it, expect, beforeAll, afterAll } from 'vitest'; -import { Database } from 'node-sqlite3-wasm'; +import type Database from 'better-sqlite3'; import { initDb, closeDb } from '../src/db/index'; -let db: Database; +let db: InstanceType; beforeAll(() => { db = initDb(':memory:'); @@ -96,10 +96,9 @@ describe('Table creation', () => { describe('Broker insert and retrieve', () => { it('should insert and retrieve a broker', () => { - const result = db.run( - `INSERT INTO mqtt_brokers (name, host, port) VALUES (?, ?, ?)`, - ['Test Broker', 'mqtt.example.com', 1883] - ); + const result = db.prepare( + `INSERT INTO mqtt_brokers (name, host, port) VALUES (?, ?, ?)` + ).run('Test Broker', 'mqtt.example.com', 1883); expect(result.lastInsertRowid).toBeGreaterThan(0); const broker = db @@ -119,22 +118,22 @@ describe('Broker insert and retrieve', () => { }); it('should cascade delete topics when broker is deleted', () => { - const broker = db.run(`INSERT INTO mqtt_brokers (name, host) VALUES (?, ?)`, [ + const broker = db.prepare(`INSERT INTO mqtt_brokers (name, host) VALUES (?, ?)`).run( 'Cascade Broker', 'cascade.example.com', - ]); + ); - db.run(`INSERT INTO mqtt_topics (broker_id, topic) VALUES (?, ?)`, [ + db.prepare(`INSERT INTO mqtt_topics (broker_id, topic) VALUES (?, ?)`).run( broker.lastInsertRowid, 'sensors/temp', - ]); + ); const topicsBefore = db .prepare(`SELECT * FROM mqtt_topics WHERE broker_id = ?`) .all(broker.lastInsertRowid); expect(topicsBefore.length).toBe(1); - db.run(`DELETE FROM mqtt_brokers WHERE id = ?`, [broker.lastInsertRowid]); + db.prepare(`DELETE FROM mqtt_brokers WHERE id = ?`).run(broker.lastInsertRowid); const topicsAfter = db .prepare(`SELECT * FROM mqtt_topics WHERE broker_id = ?`) @@ -144,10 +143,9 @@ describe('Broker insert and retrieve', () => { it('should reject invalid source_type values', () => { expect(() => { - db.run( - `INSERT INTO datapoints (name, label, source_type, source_id) VALUES (?, ?, ?, ?)`, - ['dp1', 'Datapoint 1', 'invalid_source', 1] - ); + db.prepare( + `INSERT INTO datapoints (name, label, source_type, source_id) VALUES (?, ?, ?, ?)` + ).run('dp1', 'Datapoint 1', 'invalid_source', 1); }).toThrow(); }); }); diff --git a/display/middleware/tests/display-builder.test.ts b/display/middleware/tests/display-builder.test.ts index 5ddddc7..2400b29 100644 --- a/display/middleware/tests/display-builder.test.ts +++ b/display/middleware/tests/display-builder.test.ts @@ -6,48 +6,48 @@ beforeAll(() => { const db = initDb(':memory:'); // Create a layout - db.run( + db.prepare( `INSERT INTO layouts (id, name, type, width, height, grid_cols, grid_rows) VALUES (1, 'Test Layout', 'grid', 800, 480, 2, 3)` - ); + ).run(); // Create a display with the layout - db.run( + db.prepare( `INSERT INTO displays (id, name, layout_id, refresh_sec) VALUES (1, 'Test Display', 1, 60)` - ); + ).run(); // Create a display without layout - db.run( + db.prepare( `INSERT INTO displays (id, name, layout_id, refresh_sec) VALUES (2, 'Empty Display', NULL, 300)` - ); + ).run(); // Create a broker and topic for datapoint - db.run( + db.prepare( `INSERT INTO mqtt_brokers (id, name, host) VALUES (1, 'Test Broker', 'localhost')` - ); - db.run( + ).run(); + db.prepare( `INSERT INTO mqtt_topics (id, broker_id, topic) VALUES (1, 1, 'sensors/temp')` - ); + ).run(); // Create a datapoint - db.run( + db.prepare( `INSERT INTO datapoints (id, name, label, unit, value, source_type, source_id, topic_id, enabled) VALUES (1, 'temperature', 'Temperature', '°C', '22.5', 'mqtt', 1, 1, 1)` - ); + ).run(); // Create layout elements // Label element - db.run( + db.prepare( `INSERT INTO layout_elements (id, layout_id, type, x, y, static_text, sort_order) VALUES (1, 1, 'label', 0, 0, 'Hello World', 0)` - ); + ).run(); // Value element linked to datapoint - db.run( + db.prepare( `INSERT INTO layout_elements (id, layout_id, datapoint_id, type, x, y, font_size, sort_order) VALUES (2, 1, 1, 'value', 100, 0, 32, 1)` - ); + ).run(); }); afterAll(() => {