rewrite typeysation

This commit is contained in:
Darius
2025-11-21 16:49:12 +01:00
parent 27582e342f
commit e8459a7a7b
6 changed files with 131 additions and 514 deletions

399
package-lock.json generated
View File

@@ -20,8 +20,8 @@
} }
}, },
"node_modules/@dpu/shared": { "node_modules/@dpu/shared": {
"version": "1.0.14", "version": "1.1.4",
"resolved": "git+https://git.dariusbag.dev/DarDarBinks/dpu-shared.git#9269eaaa881762c7045ba96b07a0beaf0384ed91", "resolved": "git+https://git.dariusbag.dev/DarDarBinks/dpu-shared.git#a35a3e7ecbc23444bcfbfc2e89770f490fd4123f",
"dependencies": { "dependencies": {
"axios": "^1.7.9", "axios": "^1.7.9",
"chalk": "^5.6.2", "chalk": "^5.6.2",
@@ -605,23 +605,6 @@
"node": "20 || >=22" "node": "20 || >=22"
} }
}, },
"node_modules/@isaacs/cliui": {
"version": "8.0.2",
"resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
"integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
"license": "ISC",
"dependencies": {
"string-width": "^5.1.2",
"string-width-cjs": "npm:string-width@^4.2.0",
"strip-ansi": "^7.0.1",
"strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
"wrap-ansi": "^8.1.0",
"wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
},
"engines": {
"node": ">=12"
}
},
"node_modules/@pinojs/redact": { "node_modules/@pinojs/redact": {
"version": "0.4.0", "version": "0.4.0",
"resolved": "https://registry.npmjs.org/@pinojs/redact/-/redact-0.4.0.tgz", "resolved": "https://registry.npmjs.org/@pinojs/redact/-/redact-0.4.0.tgz",
@@ -677,30 +660,6 @@
} }
} }
}, },
"node_modules/ansi-regex": {
"version": "6.2.2",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz",
"integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==",
"license": "MIT",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/chalk/ansi-regex?sponsor=1"
}
},
"node_modules/ansi-styles": {
"version": "6.2.3",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz",
"integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==",
"license": "MIT",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"node_modules/asynckit": { "node_modules/asynckit": {
"version": "0.4.0", "version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
@@ -762,24 +721,6 @@
"url": "https://github.com/chalk/chalk?sponsor=1" "url": "https://github.com/chalk/chalk?sponsor=1"
} }
}, },
"node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"license": "MIT",
"dependencies": {
"color-name": "~1.1.4"
},
"engines": {
"node": ">=7.0.0"
}
},
"node_modules/color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"license": "MIT"
},
"node_modules/combined-stream": { "node_modules/combined-stream": {
"version": "1.0.8", "version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
@@ -801,20 +742,6 @@
"node": ">=18" "node": ">=18"
} }
}, },
"node_modules/cross-spawn": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
"license": "MIT",
"dependencies": {
"path-key": "^3.1.0",
"shebang-command": "^2.0.0",
"which": "^2.0.1"
},
"engines": {
"node": ">= 8"
}
},
"node_modules/delayed-stream": { "node_modules/delayed-stream": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
@@ -859,18 +786,6 @@
"node": ">= 0.4" "node": ">= 0.4"
} }
}, },
"node_modules/eastasianwidth": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
"license": "MIT"
},
"node_modules/emoji-regex": {
"version": "9.2.2",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
"integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
"license": "MIT"
},
"node_modules/es-define-property": { "node_modules/es-define-property": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
@@ -1111,22 +1026,6 @@
} }
} }
}, },
"node_modules/foreground-child": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz",
"integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==",
"license": "ISC",
"dependencies": {
"cross-spawn": "^7.0.6",
"signal-exit": "^4.0.1"
},
"engines": {
"node": ">=14"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/form-data": { "node_modules/form-data": {
"version": "4.0.5", "version": "4.0.5",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz",
@@ -1218,21 +1117,15 @@
} }
}, },
"node_modules/glob": { "node_modules/glob": {
"version": "11.1.0", "version": "13.0.0",
"resolved": "https://registry.npmjs.org/glob/-/glob-11.1.0.tgz", "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.0.tgz",
"integrity": "sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==", "integrity": "sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA==",
"license": "BlueOak-1.0.0", "license": "BlueOak-1.0.0",
"dependencies": { "dependencies": {
"foreground-child": "^3.3.1",
"jackspeak": "^4.1.1",
"minimatch": "^10.1.1", "minimatch": "^10.1.1",
"minipass": "^7.1.2", "minipass": "^7.1.2",
"package-json-from-dist": "^1.0.0",
"path-scurry": "^2.0.0" "path-scurry": "^2.0.0"
}, },
"bin": {
"glob": "dist/esm/bin.mjs"
},
"engines": { "engines": {
"node": "20 || >=22" "node": "20 || >=22"
}, },
@@ -1300,36 +1193,6 @@
"node": ">= 10" "node": ">= 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/isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
"license": "ISC"
},
"node_modules/jackspeak": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.1.tgz",
"integrity": "sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==",
"license": "BlueOak-1.0.0",
"dependencies": {
"@isaacs/cliui": "^8.0.2"
},
"engines": {
"node": "20 || >=22"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/json-schema-ref-resolver": { "node_modules/json-schema-ref-resolver": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/json-schema-ref-resolver/-/json-schema-ref-resolver-3.0.0.tgz", "resolved": "https://registry.npmjs.org/json-schema-ref-resolver/-/json-schema-ref-resolver-3.0.0.tgz",
@@ -1470,15 +1333,6 @@
"integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
"license": "BlueOak-1.0.0" "license": "BlueOak-1.0.0"
}, },
"node_modules/path-key": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/path-scurry": { "node_modules/path-scurry": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz",
@@ -1614,12 +1468,12 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/rimraf": { "node_modules/rimraf": {
"version": "6.1.0", "version": "6.1.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.1.0.tgz", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.1.2.tgz",
"integrity": "sha512-DxdlA1bdNzkZK7JiNWH+BAx1x4tEJWoTofIopFo6qWUU94jYrFZ0ubY05TqH3nWPJ1nKa1JWVFDINZ3fnrle/A==", "integrity": "sha512-cFCkPslJv7BAXJsYlK1dZsbP8/ZNLkCAQ0bi1hf5EKX2QHegmDFEFA6QhuYJlk7UDdc+02JjO80YSOrWPpw06g==",
"license": "BlueOak-1.0.0", "license": "BlueOak-1.0.0",
"dependencies": { "dependencies": {
"glob": "^11.0.3", "glob": "^13.0.0",
"package-json-from-dist": "^1.0.1" "package-json-from-dist": "^1.0.1"
}, },
"bin": { "bin": {
@@ -1694,39 +1548,6 @@
"integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==", "integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
"license": "MIT",
"dependencies": {
"shebang-regex": "^3.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/shebang-regex": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/signal-exit": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
"integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
"license": "ISC",
"engines": {
"node": ">=14"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/sonic-boom": { "node_modules/sonic-boom": {
"version": "4.2.0", "version": "4.2.0",
"resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-4.2.0.tgz", "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-4.2.0.tgz",
@@ -1745,102 +1566,6 @@
"node": ">= 10.x" "node": ">= 10.x"
} }
}, },
"node_modules/string-width": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
"integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
"license": "MIT",
"dependencies": {
"eastasianwidth": "^0.2.0",
"emoji-regex": "^9.2.2",
"strip-ansi": "^7.0.1"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/string-width-cjs": {
"name": "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/string-width-cjs/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/string-width-cjs/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/string-width-cjs/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-ansi": {
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz",
"integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==",
"license": "MIT",
"dependencies": {
"ansi-regex": "^6.0.1"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/chalk/strip-ansi?sponsor=1"
}
},
"node_modules/strip-ansi-cjs": {
"name": "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-ansi-cjs/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/thread-stream": { "node_modules/thread-stream": {
"version": "3.1.0", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-3.1.0.tgz", "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-3.1.0.tgz",
@@ -1899,112 +1624,6 @@
"integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==",
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
},
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
"license": "ISC",
"dependencies": {
"isexe": "^2.0.0"
},
"bin": {
"node-which": "bin/node-which"
},
"engines": {
"node": ">= 8"
}
},
"node_modules/wrap-ansi": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
"integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
"license": "MIT",
"dependencies": {
"ansi-styles": "^6.1.0",
"string-width": "^5.0.1",
"strip-ansi": "^7.0.1"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
}
},
"node_modules/wrap-ansi-cjs": {
"name": "wrap-ansi",
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
"license": "MIT",
"dependencies": {
"ansi-styles": "^4.0.0",
"string-width": "^4.1.0",
"strip-ansi": "^6.0.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
}
},
"node_modules/wrap-ansi-cjs/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/wrap-ansi-cjs/node_modules/ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"license": "MIT",
"dependencies": {
"color-convert": "^2.0.1"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"node_modules/wrap-ansi-cjs/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/wrap-ansi-cjs/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/wrap-ansi-cjs/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"
}
} }
} }
} }

View File

@@ -1,14 +1,8 @@
import type { HomeAssistantEntity } from "@dpu/shared"; import type { HomeAssistantEntity } from "@dpu/shared";
import { BaseClient } from "@dpu/shared/dist/fastify";
import { printNetworkError } from "@dpu/shared/dist/logger.js"; import { printNetworkError } from "@dpu/shared/dist/logger.js";
import type { AxiosInstance } from "axios";
export class HomeAssistantClient {
private axiosInstance: AxiosInstance;
constructor(axiosInstance: AxiosInstance) {
this.axiosInstance = axiosInstance;
}
export class HomeAssistantClient extends BaseClient {
async getEntityStates(entityIds: string[]): Promise<HomeAssistantEntity[]> { async getEntityStates(entityIds: string[]): Promise<HomeAssistantEntity[]> {
try { try {
const promises = entityIds.map((id) => this.getEntityState(id)); const promises = entityIds.map((id) => this.getEntityState(id));
@@ -21,7 +15,7 @@ export class HomeAssistantClient {
async getEntityState(entityId: string): Promise<HomeAssistantEntity> { async getEntityState(entityId: string): Promise<HomeAssistantEntity> {
try { try {
const response = await this.axiosInstance.get<HomeAssistantEntity>( const response = await this.getAxios().get<HomeAssistantEntity>(
`states/${entityId}`, `states/${entityId}`,
); );
return response.data; return response.data;
@@ -33,7 +27,7 @@ export class HomeAssistantClient {
async triggerWebhook(webhookId: string): Promise<unknown> { async triggerWebhook(webhookId: string): Promise<unknown> {
try { try {
const response = await this.axiosInstance.post<HomeAssistantEntity>( const response = await this.getAxios().post<HomeAssistantEntity>(
`webhook/${webhookId}`, `webhook/${webhookId}`,
); );
return response.data; return response.data;

View File

@@ -2,26 +2,23 @@ import type {
HomeAssistantDeskPositionResult, HomeAssistantDeskPositionResult,
HomeAssistantEntity, HomeAssistantEntity,
} from "@dpu/shared"; } from "@dpu/shared";
import { BaseService, type ServiceResult } from "@dpu/shared/dist/fastify.js";
import { logWarning } from "@dpu/shared/dist/logger.js"; import { logWarning } from "@dpu/shared/dist/logger.js";
import { calculateSecondsBetween } from "@dpu/shared/dist/timehelper.js"; import { calculateSecondsBetween } from "@dpu/shared/dist/timehelper.js";
import { Config } from "../config.js"; import { Config } from "../config.js";
import type { HomeAssistantClient } from "./client.js"; import type { HomeAssistantClient } from "./client.js";
export class HomeAssistantService { export class HomeAssistantService extends BaseService<HomeAssistantClient> {
private client: HomeAssistantClient; async startStandingAutomation(): Promise<ServiceResult<unknown | string>> {
constructor(client: HomeAssistantClient) {
this.client = client;
}
async startStandingAutomation(): Promise<unknown | null> {
try { try {
const position = await this.getDeskPosition(); const positionResult = await this.getDeskPosition();
if (position === null) { if (!positionResult.successful) {
throw Error("error accessing desk api"); throw Error(positionResult.result as string);
} }
const position = positionResult.result as HomeAssistantDeskPositionResult;
if (position.as_boolean) { if (position.as_boolean) {
throw Error("desk is already in standing position"); throw Error("desk is already in standing position");
} }
@@ -30,24 +27,29 @@ export class HomeAssistantService {
throw Error("desk has moved too recently"); throw Error("desk has moved too recently");
} }
return await this.client.triggerWebhook( const result = await this.getClient().triggerWebhook(
Config.homeassistant.id_webhook_stand, Config.homeassistant.id_webhook_stand,
); );
return this.getSuccessfulResult(result);
} catch (error) { } catch (error) {
logWarning("Error starting stand automation:", error); const error_message = "error starting stand automation";
return null; logWarning(error_message, error);
return this.getErrorResult(error_message);
} }
} }
async getDeskPosition(): Promise<HomeAssistantDeskPositionResult | null> { async getDeskPosition(): Promise<
ServiceResult<HomeAssistantDeskPositionResult | string>
> {
try { try {
const raw = await this.client.getEntityState( const raw = await this.getClient().getEntityState(
Config.homeassistant.id_desk_sensor_binary, Config.homeassistant.id_desk_sensor_binary,
); );
const position = Number(raw.state); const position = Number(raw.state);
return { const result = {
raw, raw,
as_boolean: position === 1, as_boolean: position === 1,
as_text: () => { as_text: () => {
@@ -60,13 +62,16 @@ export class HomeAssistantService {
Date.now(), Date.now(),
), ),
}; };
return this.getSuccessfulResult(result);
} catch (error) { } catch (error) {
logWarning("Error getting desk position:", error); const error_message = "error getting desk position";
return null; logWarning(error_message, error);
return this.getErrorResult(error_message);
} }
} }
async getTemperatureText(): Promise<string | null> { async getTemperatureText(): Promise<ServiceResult<string>> {
try { try {
const entities = await this.getTemperatures(); const entities = await this.getTemperatures();
const values = entities const values = entities
@@ -76,30 +81,23 @@ export class HomeAssistantService {
values.length > 0 values.length > 0
? values.reduce((sum, value) => sum + value, 0) / values.length ? values.reduce((sum, value) => sum + value, 0) / values.length
: 0; : 0;
return average.toFixed(2); const result = average.toFixed(2);
return this.getSuccessfulResult(result);
} catch (error) { } catch (error) {
logWarning(`Error getting temperature as text`, error); const error_message = "error getting temperature as text";
return null; logWarning(error_message, error);
return this.getErrorResult(error_message);
} }
} }
async getTemperatures(): Promise<HomeAssistantEntity[]> { private async getTemperatures(): Promise<HomeAssistantEntity[]> {
try { try {
return await this.client.getEntityStates( return await this.getClient().getEntityStates(
Config.homeassistant.id_room_sensors, Config.homeassistant.id_room_sensors,
); );
} catch (error) { } catch (error) {
logWarning("Error getting temperatures:", error); logWarning("error getting temperatures:", error);
return []; return [];
} }
} }
async getTemperature(entityId: string): Promise<HomeAssistantEntity | null> {
try {
return await this.client.getEntityState(entityId);
} catch (error) {
logWarning(`Error getting temperature for ${entityId}:`, error);
return null;
}
}
} }

View File

@@ -1,3 +1,4 @@
import type { HomeAssistantDeskPositionResult } from "@dpu/shared";
import { logInfo } from "@dpu/shared/dist/logger.js"; import { logInfo } from "@dpu/shared/dist/logger.js";
import type { FastifyReply, FastifyRequest } from "fastify"; import type { FastifyReply, FastifyRequest } from "fastify";
import fastify from "fastify"; import fastify from "fastify";
@@ -44,17 +45,20 @@ const tidalService = new TidalService(tidalClient);
// HOME ASSISTANT // HOME ASSISTANT
server.get("/homeassistant/desk/position", async (_request, reply) => { server.get("/homeassistant/desk/position", async (_request, reply) => {
const result = await haService.getDeskPosition(); const service_result = await haService.getDeskPosition();
if (!result) { if (!service_result.successful) {
reply.code(500); reply.code(418);
return { error: "Failed to get desk position" }; return { error: service_result.result };
} }
const position_result =
service_result.result as HomeAssistantDeskPositionResult;
return { return {
position: result.as_text(), position: position_result.as_text(),
is_standing: result.as_boolean, is_standing: position_result.as_boolean,
last_changed: result.last_changed.toReadable(true), last_changed: position_result.last_changed.toReadable(true),
}; };
}); });
@@ -62,60 +66,60 @@ server.post(
"/homeassistant/desk/stand", "/homeassistant/desk/stand",
{ preHandler: verifyAPIKey }, { preHandler: verifyAPIKey },
async (_request, reply) => { async (_request, reply) => {
const result = await haService.startStandingAutomation(); const service_result = await haService.startStandingAutomation();
if (!result) { if (!service_result.successful) {
reply.code(500); reply.code(418);
return { error: "Failed to start stand automation" }; return { error: service_result.result };
} }
return result; return service_result.result;
}, },
); );
server.get("/homeassistant/temperature", async (_request, reply) => { server.get("/homeassistant/temperature", async (_request, reply) => {
const result = await haService.getTemperatureText(); const service_result = await haService.getTemperatureText();
if (!result) { if (!service_result.successful) {
reply.code(500); reply.code(418);
return { error: "Failed to get temperature" }; return { error: service_result.result };
} }
return result; return service_result.result;
}); });
// TIDAL // TIDAL
server.get("/tidal/song", async (_request, reply) => { server.get("/tidal/song", async (_request, reply) => {
const result = await tidalService.getSong(); const service_result = await tidalService.getSong();
if (!result) { if (!service_result.successful) {
reply.code(500); reply.code(418);
return { error: "Failed to get song" }; return { error: service_result.result };
} }
return result; return service_result.result;
}); });
server.get("/tidal/songFormatted", async (_request, reply) => { server.get("/tidal/songFormatted", async (_request, reply) => {
const result = await tidalService.getSongFormatted(); const service_result = await tidalService.getSongFormatted();
if (!result) { if (!service_result.successful) {
reply.code(500); reply.code(418);
return { error: "Failed to get song" }; return { error: service_result.result };
} }
return result; return service_result.result;
}); });
server.get("/tidal/volume", async (_request, reply) => { server.get("/tidal/volume", async (_request, reply) => {
const result = await tidalService.getVolume(); const service_result = await tidalService.getVolume();
if (!result) { if (!service_result.successful) {
reply.code(500); reply.code(418);
return { error: "Failed to get volume" }; return { error: service_result.result };
} }
return result; return service_result.result;
}); });
server.post( server.post(
@@ -123,14 +127,14 @@ server.post(
{ preHandler: verifyAPIKey }, { preHandler: verifyAPIKey },
async (request, reply) => { async (request, reply) => {
const volume = request.body as string; const volume = request.body as string;
const result = await tidalService.setVolume(volume); const service_result = await tidalService.setVolume(volume);
if (!result) { if (!service_result.successful) {
reply.code(500); reply.code(418);
return { error: "Failed to set volume" }; return { error: service_result.result };
} }
return result; return service_result.result;
}, },
); );

View File

@@ -1,16 +1,10 @@
import { BaseClient } from "@dpu/shared/dist/fastify";
import { printNetworkError } from "@dpu/shared/dist/logger.js"; import { printNetworkError } from "@dpu/shared/dist/logger.js";
import type { AxiosInstance } from "axios";
export class TidalClient {
private axiosInstance: AxiosInstance;
constructor(axiosInstance: AxiosInstance) {
this.axiosInstance = axiosInstance;
}
export class TidalClient extends BaseClient {
async get<T>(endpoint: string): Promise<T> { async get<T>(endpoint: string): Promise<T> {
try { try {
const response = await this.axiosInstance.get<T>(`/${endpoint}`); const response = await this.getAxios().get<T>(`/${endpoint}`);
return response.data; return response.data;
} catch (error) { } catch (error) {
@@ -21,7 +15,7 @@ export class TidalClient {
async post<T>(endpoint: string, data: unknown): Promise<T> { async post<T>(endpoint: string, data: unknown): Promise<T> {
try { try {
const response = await this.axiosInstance.post<T>(`/${endpoint}`, data); const response = await this.getAxios().post<T>(`/${endpoint}`, data);
return response.data; return response.data;
} catch (error) { } catch (error) {
printNetworkError(error); printNetworkError(error);

View File

@@ -1,43 +1,43 @@
import type { TidalSong, TidalVolume } from "@dpu/shared"; import type { TidalSong, TidalVolume } from "@dpu/shared";
import { BaseService, type ServiceResult } from "@dpu/shared/dist/fastify.js";
import { logWarning } from "@dpu/shared/dist/logger.js"; import { logWarning } from "@dpu/shared/dist/logger.js";
import type { TidalClient } from "./client.js"; import type { TidalClient } from "./client";
export class TidalService { export class TidalService extends BaseService<TidalClient> {
private client: TidalClient; async getSongFormatted(): Promise<ServiceResult<string>> {
const req = await this.getSong();
constructor(client: TidalClient) { if (req.successful) {
this.client = client; const song = req.result as TidalSong;
}
async getSongFormatted(): Promise<string> {
const song = await this.getSong();
if (song) {
const status = song.status === "playing" ? "▶️" : "⏸️"; const status = song.status === "playing" ? "▶️" : "⏸️";
return `listening to ${song.title} by ${song.artists}. ${status} ${song.current}/${song.duration}. link: ${song.url}`; return this.getSuccessfulResult(
`listening to ${song.title} by ${song.artists}. ${status} ${song.current}/${song.duration}. link: ${song.url}`,
);
} else { } else {
return `no song found`; return this.getErrorResult(req.result as string);
} }
} }
async getSong(): Promise<TidalSong | null> { async getSong(): Promise<ServiceResult<TidalSong | string>> {
try { try {
const response = this.client.get<TidalSong>("current"); const response = await this.getClient().get<TidalSong>("current");
return response; return this.getSuccessfulResult(response);
} catch { } catch {
logWarning("error getting song from tidal"); const error_message = "error getting song from tidal";
return null; logWarning(error_message);
return this.getErrorResult(error_message);
} }
} }
async getVolume(): Promise<TidalVolume | null> { async getVolume(): Promise<ServiceResult<TidalVolume | string>> {
try { try {
const response = await this.client.get<TidalVolume>("volume"); const response = await this.getClient().get<TidalVolume>("volume");
return response; return this.getSuccessfulResult(response);
} catch { } catch {
logWarning("error getting volume from tidal"); const error_message = "error getting volume from tidal";
return null; logWarning(error_message);
return this.getErrorResult(error_message);
} }
} }
@@ -45,13 +45,16 @@ export class TidalService {
return Math.min(Math.max(value, 0), 100); return Math.min(Math.max(value, 0), 100);
} }
async setVolume(argument: string): Promise<TidalVolume | null> { async setVolume(
argument: string,
): Promise<ServiceResult<TidalVolume | string>> {
const value = parseInt(argument, 10); const value = parseInt(argument, 10);
// relative // relative
const adjustMatch = argument.match(/^([+-])(\d+)$/); const adjustMatch = argument.match(/^([+-])(\d+)$/);
if (adjustMatch) { if (adjustMatch) {
const volume = await this.getVolume(); const req = await this.getVolume();
if (volume) { if (req.successful) {
const volume = req.result as TidalVolume;
const wantedVolume = volume.volume + value; const wantedVolume = volume.volume + value;
const clampWantedVolume = this.clamp(wantedVolume); const clampWantedVolume = this.clamp(wantedVolume);
return await this.setVolumeToTidal(clampWantedVolume); return await this.setVolumeToTidal(clampWantedVolume);
@@ -65,19 +68,24 @@ export class TidalService {
return await this.setVolumeToTidal(clampValue); return await this.setVolumeToTidal(clampValue);
} }
return null; const error_message = "error parsing volume to set";
logWarning(error_message);
return this.getErrorResult(error_message);
} }
async setVolumeToTidal(volume: number): Promise<TidalVolume | null> { async setVolumeToTidal(
volume: number,
): Promise<ServiceResult<TidalVolume | string>> {
try { try {
const response = await this.client.post<TidalVolume>("volume", { const response = await this.getClient().post<TidalVolume>("volume", {
volume, volume,
}); });
return response; return this.getSuccessfulResult(response);
} catch { } catch {
logWarning("error setting volume from tidal"); const error_message = "error setting volume from tidal";
return null; logWarning(error_message);
return this.getErrorResult(error_message);
} }
} }
} }