register match working

This commit is contained in:
2023-08-09 23:32:36 +02:00
parent fecbb80975
commit 338a283a07
10 changed files with 758 additions and 406 deletions
+1 -1
View File
@@ -14,6 +14,6 @@ module.exports = {
"@typescript-eslint/strict-boolean-expressions": 0,
"@typescript-eslint/explicit-function-return-type": "off",
},
plugins: ["jest"],
plugins: ["jest", { transform: "typia/lib/transform" }],
"jest/globals": true,
};
+1
View File
@@ -103,3 +103,4 @@ dist
# TernJS port file
.tern-port
out/
src/generated
+447 -11
View File
@@ -16,6 +16,7 @@
"pg": "^8.9.0",
"redis": "^4.6.5",
"ts-node": "^10.9.1",
"typia": "^4.2.1",
"ws": "^8.13.0"
},
"devDependencies": {
@@ -3251,7 +3252,6 @@
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
"integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==",
"devOptional": true,
"dependencies": {
"type-fest": "^0.21.3"
},
@@ -3266,7 +3266,6 @@
"version": "0.21.3",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
"integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
"devOptional": true,
"engines": {
"node": ">=10"
},
@@ -3343,6 +3342,11 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/array-timsort": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/array-timsort/-/array-timsort-1.0.3.tgz",
"integrity": "sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ=="
},
"node_modules/array-union": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
@@ -3543,6 +3547,25 @@
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
},
"node_modules/base64-js": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
]
},
"node_modules/basic-auth": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz",
@@ -3559,6 +3582,16 @@
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
},
"node_modules/bl": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
"integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
"dependencies": {
"buffer": "^5.5.0",
"inherits": "^2.0.4",
"readable-stream": "^3.4.0"
}
},
"node_modules/body-parser": {
"version": "1.20.1",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
@@ -3639,6 +3672,29 @@
"node-int64": "^0.4.0"
}
},
"node_modules/buffer": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
"integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"dependencies": {
"base64-js": "^1.3.1",
"ieee754": "^1.1.13"
}
},
"node_modules/buffer-from": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
@@ -3739,6 +3795,11 @@
"node": ">=10"
}
},
"node_modules/chardet": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
"integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA=="
},
"node_modules/ci-info": {
"version": "3.8.0",
"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz",
@@ -3760,6 +3821,36 @@
"integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==",
"devOptional": true
},
"node_modules/cli-cursor": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
"integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
"dependencies": {
"restore-cursor": "^3.1.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/cli-spinners": {
"version": "2.9.0",
"resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.0.tgz",
"integrity": "sha512-4/aL9X3Wh0yiMQlE+eeRhWP6vclO3QRtw1JHKIT0FFUs5FjpFmESqtMvYZ0+lbzBw900b95mS0hohy+qn2VK/g==",
"engines": {
"node": ">=6"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/cli-width": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz",
"integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==",
"engines": {
"node": ">= 10"
}
},
"node_modules/cliui": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
@@ -3774,6 +3865,14 @@
"node": ">=12"
}
},
"node_modules/clone": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
"integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==",
"engines": {
"node": ">=0.8"
}
},
"node_modules/cluster-key-slot": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz",
@@ -3814,6 +3913,29 @@
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
"node_modules/commander": {
"version": "10.0.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",
"integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==",
"engines": {
"node": ">=14"
}
},
"node_modules/comment-json": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/comment-json/-/comment-json-4.2.3.tgz",
"integrity": "sha512-SsxdiOf064DWoZLH799Ata6u7iV658A11PlWtZATDlXPpKGJnbJZ5Z24ybixAi+LUUqJ/GKowAejtC5GFUG7Tw==",
"dependencies": {
"array-timsort": "^1.0.3",
"core-util-is": "^1.0.3",
"esprima": "^4.0.1",
"has-own-prop": "^2.0.0",
"repeat-string": "^1.6.1"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@@ -3870,6 +3992,11 @@
"url": "https://opencollective.com/core-js"
}
},
"node_modules/core-util-is": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
"integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="
},
"node_modules/cors": {
"version": "2.8.5",
"resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
@@ -3928,6 +4055,17 @@
"node": ">=0.10.0"
}
},
"node_modules/defaults": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz",
"integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==",
"dependencies": {
"clone": "^1.0.2"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/define-properties": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz",
@@ -4017,6 +4155,14 @@
"node": ">=12"
}
},
"node_modules/drange": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/drange/-/drange-1.1.1.tgz",
"integrity": "sha512-pYxfDYpued//QpnLIm4Avk7rsNtAtQkUES2cwAYSvD/wd2pKD71gN2Ebj3e7klzXwjocvE8c5vx/1fxwpqmSxA==",
"engines": {
"node": ">=4"
}
},
"node_modules/ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
@@ -4043,8 +4189,7 @@
"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==",
"devOptional": true
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
},
"node_modules/encodeurl": {
"version": "1.0.2",
@@ -4588,7 +4733,6 @@
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
"devOptional": true,
"bin": {
"esparse": "bin/esparse.js",
"esvalidate": "bin/esvalidate.js"
@@ -4752,6 +4896,19 @@
"node": ">= 8.0.0"
}
},
"node_modules/external-editor": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz",
"integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==",
"dependencies": {
"chardet": "^0.7.0",
"iconv-lite": "^0.4.24",
"tmp": "^0.0.33"
},
"engines": {
"node": ">=4"
}
},
"node_modules/fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
@@ -4810,6 +4967,28 @@
"bser": "2.1.1"
}
},
"node_modules/figures": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz",
"integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==",
"dependencies": {
"escape-string-regexp": "^1.0.5"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/figures/node_modules/escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
"engines": {
"node": ">=0.8.0"
}
},
"node_modules/file-entry-cache": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
@@ -5162,6 +5341,14 @@
"node": ">=8"
}
},
"node_modules/has-own-prop": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/has-own-prop/-/has-own-prop-2.0.0.tgz",
"integrity": "sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==",
"engines": {
"node": ">=8"
}
},
"node_modules/has-property-descriptors": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz",
@@ -5253,6 +5440,25 @@
"node": ">=0.10.0"
}
},
"node_modules/ieee754": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
]
},
"node_modules/ignore": {
"version": "5.2.4",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
@@ -5317,6 +5523,44 @@
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"node_modules/inquirer": {
"version": "8.2.6",
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.6.tgz",
"integrity": "sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg==",
"dependencies": {
"ansi-escapes": "^4.2.1",
"chalk": "^4.1.1",
"cli-cursor": "^3.1.0",
"cli-width": "^3.0.0",
"external-editor": "^3.0.3",
"figures": "^3.0.0",
"lodash": "^4.17.21",
"mute-stream": "0.0.8",
"ora": "^5.4.1",
"run-async": "^2.4.0",
"rxjs": "^7.5.5",
"string-width": "^4.1.0",
"strip-ansi": "^6.0.0",
"through": "^2.3.6",
"wrap-ansi": "^6.0.1"
},
"engines": {
"node": ">=12.0.0"
}
},
"node_modules/inquirer/node_modules/wrap-ansi": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
"integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
"dependencies": {
"ansi-styles": "^4.0.0",
"string-width": "^4.1.0",
"strip-ansi": "^6.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/internal-slot": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz",
@@ -5438,7 +5682,6 @@
"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==",
"devOptional": true,
"engines": {
"node": ">=8"
}
@@ -5463,6 +5706,14 @@
"node": ">=0.10.0"
}
},
"node_modules/is-interactive": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz",
"integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==",
"engines": {
"node": ">=8"
}
},
"node_modules/is-negative-zero": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz",
@@ -5595,6 +5846,17 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-unicode-supported": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
"integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/is-weakref": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz",
@@ -6417,6 +6679,21 @@
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="
},
"node_modules/log-symbols": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
"integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
"dependencies": {
"chalk": "^4.1.0",
"is-unicode-supported": "^0.1.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
@@ -6547,7 +6824,6 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
"devOptional": true,
"engines": {
"node": ">=6"
}
@@ -6577,6 +6853,11 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
},
"node_modules/mute-stream": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
"integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA=="
},
"node_modules/natural-compare": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
@@ -6712,7 +6993,6 @@
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
"integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
"devOptional": true,
"dependencies": {
"mimic-fn": "^2.1.0"
},
@@ -6739,6 +7019,36 @@
"node": ">= 0.8.0"
}
},
"node_modules/ora": {
"version": "5.4.1",
"resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz",
"integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==",
"dependencies": {
"bl": "^4.1.0",
"chalk": "^4.1.0",
"cli-cursor": "^3.1.0",
"cli-spinners": "^2.5.0",
"is-interactive": "^1.0.0",
"is-unicode-supported": "^0.1.0",
"log-symbols": "^4.1.0",
"strip-ansi": "^6.0.0",
"wcwidth": "^1.0.1"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/os-tmpdir": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
"integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/p-limit": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
@@ -7160,6 +7470,18 @@
}
]
},
"node_modules/randexp": {
"version": "0.5.3",
"resolved": "https://registry.npmjs.org/randexp/-/randexp-0.5.3.tgz",
"integrity": "sha512-U+5l2KrcMNOUPYvazA3h5ekF80FHTUG+87SEAmHZmolh1M+i/WyTCxVzmi+tidIa1tM4BSe8g2Y/D3loWDjj+w==",
"dependencies": {
"drange": "^1.0.2",
"ret": "^0.2.0"
},
"engines": {
"node": ">=4"
}
},
"node_modules/range-parser": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
@@ -7188,6 +7510,19 @@
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
"devOptional": true
},
"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==",
"dependencies": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/redis": {
"version": "4.6.5",
"resolved": "https://registry.npmjs.org/redis/-/redis-4.6.5.tgz",
@@ -7300,6 +7635,14 @@
"jsesc": "bin/jsesc"
}
},
"node_modules/repeat-string": {
"version": "1.6.1",
"resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
"integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==",
"engines": {
"node": ">=0.10"
}
},
"node_modules/require-directory": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
@@ -7364,6 +7707,26 @@
"node": ">=10"
}
},
"node_modules/restore-cursor": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
"integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
"dependencies": {
"onetime": "^5.1.0",
"signal-exit": "^3.0.2"
},
"engines": {
"node": ">=8"
}
},
"node_modules/ret": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/ret/-/ret-0.2.2.tgz",
"integrity": "sha512-M0b3YWQs7R3Z917WRQy1HHA7Ba7D8hvZg6UE5mLykJxQVE2ju0IXbGlaHPPlkY+WN7wFP+wUMXmBFA0aV6vYGQ==",
"engines": {
"node": ">=4"
}
},
"node_modules/reusify": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
@@ -7387,6 +7750,14 @@
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/run-async": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz",
"integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==",
"engines": {
"node": ">=0.12.0"
}
},
"node_modules/run-parallel": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
@@ -7409,6 +7780,19 @@
"queue-microtask": "^1.2.2"
}
},
"node_modules/rxjs": {
"version": "7.8.1",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz",
"integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==",
"dependencies": {
"tslib": "^2.1.0"
}
},
"node_modules/rxjs/node_modules/tslib": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.1.tgz",
"integrity": "sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig=="
},
"node_modules/safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
@@ -7543,8 +7927,7 @@
"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==",
"devOptional": true
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="
},
"node_modules/sisteransi": {
"version": "1.0.5",
@@ -7622,6 +8005,14 @@
"node": ">= 0.8"
}
},
"node_modules/string_decoder": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
"dependencies": {
"safe-buffer": "~5.2.0"
}
},
"node_modules/string-length": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz",
@@ -7639,7 +8030,6 @@
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"devOptional": true,
"dependencies": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
@@ -7759,6 +8149,22 @@
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
"integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw=="
},
"node_modules/through": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
"integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg=="
},
"node_modules/tmp": {
"version": "0.0.33",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
"integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
"dependencies": {
"os-tmpdir": "~1.0.2"
},
"engines": {
"node": ">=0.6.0"
}
},
"node_modules/tmpl": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz",
@@ -7935,6 +8341,23 @@
"node": ">=4.2.0"
}
},
"node_modules/typia": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/typia/-/typia-4.2.1.tgz",
"integrity": "sha512-X2cp2w+t59wcIO7n5qQRGb0T6N0rsCxF4Dgfy7hy2IqgKL2+GrVUWHG+KvCf5CgcKmDyql+A9CgVwoxJeiZkpg==",
"dependencies": {
"commander": "^10.0.0",
"comment-json": "^4.2.3",
"inquirer": "^8.2.5",
"randexp": "^0.5.3"
},
"bin": {
"typia": "lib/executable/typia.js"
},
"peerDependencies": {
"typescript": ">= 4.7.4"
}
},
"node_modules/unbox-primitive": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
@@ -8032,6 +8455,11 @@
"punycode": "^2.1.0"
}
},
"node_modules/util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
},
"node_modules/utils-merge": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
@@ -8100,6 +8528,14 @@
"makeerror": "1.0.12"
}
},
"node_modules/wcwidth": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",
"integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==",
"dependencies": {
"defaults": "^1.0.3"
}
},
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+4 -2
View File
@@ -11,6 +11,7 @@
"pg": "^8.9.0",
"redis": "^4.6.5",
"ts-node": "^10.9.1",
"typia": "^4.2.1",
"ws": "^8.13.0"
},
"devDependencies": {
@@ -33,11 +34,12 @@
},
"main": "out/index.js",
"scripts": {
"build": "npx tsc",
"build": "npm run generate && npx tsc",
"startServer": "node out/serverMain.js",
"startClient": "node out/clientMain.js",
"startWebsocket": "node out/websocket.js",
"documentation": "redocly build-docs .\\docs\\v2.yml --output=docs\\index.html",
"test": "jest --runInBand"
"test": "jest --runInBand",
"generate": "npx typia generate --input src/templates --output src/generated --project tsconfig.json"
}
}
+1 -1
Submodule src/db updated: 491213147e...c985feb726
-291
View File
@@ -1,291 +0,0 @@
/* eslint-disable @typescript-eslint/naming-convention */
import { Router } from 'express'
import { body, header } from 'express-validator'
import { /* CreateKillRecord, */ CheckServerToken } from '../db/db'
import { validateErrors } from '../common'
const router = Router()
// auth middleware
router.post(
'/*',
header('authorization')
.exists({ checkFalsy: true })
.withMessage('Missing Authorization Header')
.bail()
.custom((e) => e.split(' ')[0].toLowerCase() === 'bearer')
.withMessage('Authorization Token is not Bearer'),
validateErrors,
(req, res, next) => {
void (async () => {
if (!req) return res.sendStatus(500)
if (!req.headers.authorization) {
console.error('no authorization header')
return res.sendStatus(403)
}
const query = await CheckServerToken(
req.headers.authorization.split(' ')[1]
)
if (!query?.host_id) {
console.error(
`incorrect token : ${
req.headers.authorization.split(' ')[1]
} with IP ${
req.headers['x-forwarded-for']?.toString() ??
req.socket.remoteAddress?.toString() ??
''
}`
)
return res.sendStatus(403)
}
next()
})()
}
)
// Route to check auth
router.post('/', (req, res) => {
res.sendStatus(200)
})
// const serversCount: Record<string, number> = {}
// const serversTimeout: Record<string, NodeJS.Timeout> = {}
// same rate limiting code as register. max 10 kills per server every 1 sec. should be enough.
/* router.post('/kill', (req, res, next) => {
let host = Number(req.query.serverId)
if (serversCount[serverId] > 2) {
return res.status(429).json({
error: 'too many requests. Are players really making that much kills ?'
})
}
clearTimeout(serversTimeout[serverId])
serversCount[serverId] =
serversCount[serverId] ?? (serversCount[serverId] + 1) | 1
serversTimeout[serverId] = setTimeout(() => {
serversCount[serverId] = 0
}, 1000)
next()
}) */
router.post(
'/kill',
body([
'attacker_current_weapon_mods',
'attacker_weapon_1_mods',
'attacker_weapon_2_mods',
'attacker_weapon_3_mods',
'attacker_offhand_weapon_1_mods',
'attacker_offhand_weapon_2_mods',
'victim_current_weapon_mods',
'victim_weapon_1_mods',
'victim_weapon_2_mods',
'victim_weapon_3_mods',
'victim_offhand_weapon_1_mods',
'victim_offhand_weapon_2_mods'
]).customSanitizer((value) => {
if (isNaN(value) || !value) {
value = 0
}
return value
}),
body([
'attacker_current_weapon_mods',
'attacker_weapon_1_mods',
'attacker_weapon_2_mods',
'attacker_weapon_3_mods',
'attacker_offhand_weapon_1_mods',
'attacker_offhand_weapon_2_mods',
'victim_current_weapon_mods',
'victim_weapon_1_mods',
'victim_weapon_2_mods',
'victim_weapon_3_mods',
'victim_offhand_weapon_1_mods',
'victim_offhand_weapon_2_mods'
])
.toInt()
.isInt()
.withMessage('must be a valid int'),
body(['distance', 'player_count'])
.toInt()
.isInt()
.withMessage('must be a valid int'),
body(['distance', 'game_time'])
.toFloat()
.isFloat()
.withMessage('must be a valid float'),
body(
[
'attacker_id',
'victim_id',
'killstat_version',
'match_id',
'game_mode',
'map',
'attacker_name',
'attacker_current_weapon',
'attacker_weapon_1',
'attacker_weapon_2',
'attacker_weapon_3',
'attacker_offhand_weapon_1',
'attacker_offhand_weapon_2',
'victim_name',
'victim_current_weapon',
'victim_weapon_1',
'victim_weapon_2',
'victim_weapon_3',
'victim_offhand_weapon_1',
'victim_offhand_weapon_2',
'cause_of_death',
'victim_titan',
'attacker_titan'
],
'must be composed of a maximum of 50 valid ascii characters'
)
.isString()
.isLength({ max: 50 })
.isAscii(),
body('servername').isString().isLength({ max: 100 }).isAscii(),
body(['distance', 'game_time'], 'must be postitive floats').isFloat({
min: 0
}),
body(['cause_of_death', 'victim_id'], 'mandatory').exists().notEmpty(),
// do we need this ?
// body('servername').customSanitizer(e => e.replace(/[^a-z0-9]/gi, '')),
validateErrors,
(req, res) => {
void (async () => {
// Do we check the same thing twice ?????
if (!req.headers.authorization) return res.sendStatus(403)
const headers = req.headers.authorization.split(' ')
if (headers[0].toLowerCase() !== 'bearer') { return res.status(403).send('authorization must be token bearer') }
const query = await CheckServerToken(headers[1])
if (!query) return res.sendStatus(403)
// const host = query.id
// const {
// servername,
// match_id,
// game_mode,
// map,
// game_time,
// player_count,
// attacker_name,
// attacker_id,
// attacker_current_weapon,
// attacker_current_weapon_mods,
// attacker_weapon_1,
// attacker_weapon_1_mods,
// attacker_weapon_2,
// attacker_weapon_2_mods,
// attacker_weapon_3,
// attacker_weapon_3_mods,
// attacker_offhand_weapon_1,
// attacker_offhand_weapon_1_mods,
// attacker_offhand_weapon_2,
// attacker_offhand_weapon_2_mods,
// victim_name,
// victim_id,
// victim_current_weapon,
// victim_current_weapon_mods,
// victim_weapon_1,
// victim_weapon_1_mods,
// victim_weapon_2,
// victim_weapon_2_mods,
// victim_weapon_3,
// victim_weapon_3_mods,
// victim_offhand_weapon_1,
// victim_offhand_weapon_1_mods,
// victim_offhand_weapon_2,
// victim_offhand_weapon_2_mods,
// cause_of_death,
// distance
// } = req.body
// CreateKillRecord({
// servername,
// host,
// match_id,
// game_mode,
// map,
// game_time,
// player_count,
// attacker_name,
// attacker_id,
// attacker_current_weapon,
// attacker_current_weapon_mods,
// attacker_weapon_1,
// attacker_weapon_1_mods,
// attacker_weapon_2,
// attacker_weapon_2_mods,
// attacker_weapon_3,
// attacker_weapon_3_mods,
// attacker_offhand_weapon_1,
// attacker_offhand_weapon_1_mods,
// attacker_offhand_weapon_2,
// attacker_offhand_weapon_2_mods,
// victim_name,
// victim_id,
// victim_current_weapon,
// victim_current_weapon_mods,
// victim_weapon_1,
// victim_weapon_1_mods,
// victim_weapon_2,
// victim_weapon_2_mods,
// victim_weapon_3,
// victim_weapon_3_mods,
// victim_offhand_weapon_1,
// victim_offhand_weapon_1_mods,
// victim_offhand_weapon_2,
// victim_offhand_weapon_2_mods,
// cause_of_death,
// distance
// })
// .then((e) => {
// res.sendStatus(201)
// console.log(
// `[${new Date().toLocaleString()}] Kill submitted for server ${servername}, ${attacker_name} killed ${victim_name}`
// )
// })
// .catch((e) => {
// res.sendStatus(500)
// console.error({
// killstat_version,
// servername,
// host,
// match_id,
// game_mode,
// map,
// game_time,
// player_count,
// attacker_name,
// attacker_id,
// attacker_current_weapon,
// attacker_current_weapon_mods,
// attacker_weapon_1,
// attacker_weapon_1_mods,
// attacker_weapon_2,
// attacker_weapon_2_mods,
// attacker_weapon_3,
// attacker_weapon_3_mods,
// attacker_offhand_weapon_1,
// attacker_offhand_weapon_2,
// victim_name,
// victim_id,
// victim_current_weapon,
// victim_current_weapon_mods,
// victim_weapon_1,
// victim_weapon_1_mods,
// victim_weapon_2,
// victim_weapon_2_mods,
// victim_weapon_3,
// victim_weapon_3_mods,
// victim_offhand_weapon_1,
// victim_offhand_weapon_2,
// cause_of_death,
// distance
// })
// console.error(e)
// })
})()
}
)
export default router
+54
View File
@@ -0,0 +1,54 @@
import { RequestHandler, Request } from "express";
import typia from "typia";
type WeaponKillData = {
name: string;
mods: number;
};
type PlayerKillData = {
velocity: number;
name: string;
loadout: {
ordnance: WeaponKillData;
secondary: WeaponKillData;
primary: WeaponKillData;
tactical: WeaponKillData;
anti_titan: WeaponKillData;
};
current_weapon: WeaponKillData;
state: string;
titan: string | null;
id: number | bigint;
cloaked: boolean;
};
export type MatchData = {
server_name: string;
game_map: string;
gamemode: string;
air_accel: boolean;
};
export type KillData = {
game_time: number;
player_count: number;
match_id: number;
victim: PlayerKillData;
attacker: PlayerKillData;
distance: number;
cause_of_death: string;
};
type RequestBody<T> = Request<{}, {}, T>;
export const validateBody =
<T>(checker: (input: T) => typia.IValidation<T>): RequestHandler =>
(req, res, next) => {
const result: typia.IValidation<T> = checker(req.body);
if (!result.success) {
res.status(400).send({ errors: result.errors });
} else {
next();
}
};
+5 -1
View File
@@ -1,8 +1,12 @@
// Typed routes from https://urosstok.com/blog/typed-routes-in-express
import * as dotenv from 'dotenv'
import express from 'express'
import cors from 'cors'
import { dbReady } from './db/db'
import server from './server/server'
import server from './generated/server'
dotenv.config()
const app = express()
+142
View File
@@ -0,0 +1,142 @@
/* eslint-disable @typescript-eslint/naming-convention */
import { Router, Request, Response } from "express";
import { header } from "express-validator";
import db, { /* CreateKillRecord, */ CheckServerToken } from "../db/db";
import { validateErrors } from "../common";
import { KillData, MatchData, validateBody } from "../server/types";
import typia from "typia";
const router = Router();
// auth middleware
router.post(
"/*",
header("authorization")
.exists({ checkFalsy: true })
.withMessage("Missing Authorization Header")
.bail()
.custom((e) => e.split(" ")[0].toLowerCase() === "bearer")
.withMessage("Authorization Token is not Bearer"),
validateErrors,
(req, res, next) => {
void (async () => {
if (!req.headers.authorization) {
return res.sendStatus(401);
}
const query = await CheckServerToken(
req.headers.authorization.split(" ")[1]
);
if (!query?.host_id) {
console.error(
`incorrect token : ${
req.headers.authorization.split(" ")[1]
} with IP ${
req.headers["x-forwarded-for"]?.toString() ??
req.socket.remoteAddress?.toString() ??
""
}`
);
return res.status(401).send({
errors: [
{
msg: "Incorrect Token",
param: "authorization",
location: "headers",
},
],
});
}
res.locals.host_id = query.host_id;
next();
})();
}
);
// Route to check auth
router.post("/", (req, res) => {
res.sendStatus(200);
});
// const serversCount: Record<string, number> = {}
// const serversTimeout: Record<string, NodeJS.Timeout> = {}
// same rate limiting code as register. max 10 kills per server every 1 sec. should be enough.
/* router.post('/kill', (req, res, next) => {
let host = Number(req.query.serverId)
if (serversCount[serverId] > 2) {
return res.status(429).json({
error: 'too many requests. Are players really making that much kills ?'
})
}
clearTimeout(serversTimeout[serverId])
serversCount[serverId] =
serversCount[serverId] ?? (serversCount[serverId] + 1) | 1
serversTimeout[serverId] = setTimeout(() => {
serversCount[serverId] = 0
}, 1000)
next()
}) */
type RequestBody<T> = Request<{}, {}, T>;
router.post(
"/kill",
validateBody(typia.createValidate<KillData>()),
(req: RequestBody<KillData>, res: Response) => {
void (async () => {
const host_id = res.locals.host_id;
const { match_id } = req.body;
const match = await db
.selectFrom("ToneAPI_v3.match")
.select(["ToneAPI_v3.match.host_id", "ToneAPI_v3.match.match_id"])
.where("ToneAPI_v3.match.host_id", "=", host_id)
.where("ToneAPI_v3.match.match_id", "=", match_id)
.executeTakeFirst();
if (!match) {
res
.status(403)
.send({
errors: [
{
msg: "Match does not exists",
param: "match_id",
location: "body",
},
],
});
return;
}
req.body;
})();
}
);
router.post(
"/match",
validateBody(typia.createValidate<MatchData>()),
(req: RequestBody<MatchData>, res: Response) => {
void (async () => {
const host_id = res.locals.host_id;
const { air_accel, server_name, game_map, gamemode } = req.body;
const server = await db
.selectFrom("ToneAPI_v3.server")
.selectAll()
.where("ToneAPI_v3.server.host_id", "=", host_id)
.where("ToneAPI_v3.server.server_name", "=", server_name)
.executeTakeFirst();
if (!server) {
await db
.insertInto("ToneAPI_v3.server")
.values({ host_id, server_name })
.execute();
}
const match = await db
.insertInto("ToneAPI_v3.match")
.values({ air_accel, server_name, game_map, gamemode, host_id })
.executeTakeFirst();
res.status(201).send({ match: match.insertId });
})();
}
);
export default router;
+101 -97
View File
@@ -2,10 +2,93 @@ import { afterAll, beforeAll, describe, expect, test } from '@jest/globals'
import serverMain from '../src/serverMain'
import db from "../src/db/db"
import * as dotenv from 'dotenv'
import {type KillData} from '../src/server/types'
dotenv.config()
let listenServer
const headers = {
"Content-Type": "application/json",
'Authorization': `Bearer ${Buffer.from(process.env.SERVERAUTH_TOKEN + '').toString('base64')}`
}
const testMatch = { air_accel:false, server_name:Math.floor(Math.random()*100).toString(), game_map:"testMap", gamemode:"test" }
const testKill = {
"game_time": 22.616668701171876,
"player_count": 1,
"match_id": 1,
"victim": {
"velocity": 0.0,
"name": "Legonzaur",
"loadout": {
"ordnance": {
"name": "mp_weapon_satchel",
"mods": 0
},
"secondary": {
"name": "mp_weapon_wingman",
"mods": 140
},
"primary": {
"name": "mp_weapon_sniper",
"mods": 1168
},
"tactical": {
"name": "mp_ability_grapple",
"mods": 8
},
"anti_titan": {
"name": "mp_weapon_defender",
"mods": 134
}
},
"current_weapon": {
"name": "mp_weapon_sniper",
"mods": 1168
},
"state": "OnGround",
"titan": "null",
"id": 1005930844007n,
"cloaked": false
},
"attacker": {
"velocity": 0.0,
"name": "Legonzaur",
"loadout": {
"ordnance": {
"name": "mp_weapon_satchel",
"mods": 0
},
"secondary": {
"name": "mp_weapon_wingman",
"mods": 140
},
"primary": {
"name": "mp_weapon_sniper",
"mods": 1168
},
"tactical": {
"name": "mp_ability_grapple",
"mods": 8
},
"anti_titan": {
"name": "mp_weapon_defender",
"mods": 134
}
},
"current_weapon": {
"name": "mp_weapon_sniper",
"mods": 1168
},
"state": "OnGround",
"titan": "null",
"id": 1005930844007n,
"cloaked": false
},
"distance": 0.0,
"cause_of_death": "mp_weapon_satchel"
} as KillData
beforeAll(async () => {
listenServer = await serverMain;
})
@@ -46,69 +129,30 @@ describe('server', () => {
expect(response2.status).toBe(403)
})
test('good auth prefetch', async () => {
const response = await fetch(`http://127.0.0.1:3001/`, {
method: "POST", // *GET, POST, PUT, DELETE, etc.
credentials: "same-origin", // include, *same-origin, omit
headers: {
"Content-Type": "application/json",
'Authorization': `Bearer ${Buffer.from('' + process.env.SERVERAUTH_TOKEN).toString('base64')}`
}
headers
});
expect(response.status).toBe(200)
})
test('register a match', async () => {
const response = await fetch(`http://127.0.0.1:3001/match`, {
method: "POST",
headers,
body: JSON.stringify(testMatch),
});
expect(await response.json()).toHaveProperty("match")
expect(response.status).toBe(201)
})
test('register a kill', async () => {
const data = {
servername: 'testserver',
attacker_weapon_1_mods: 0,
victim_id: '0',
victim_name: 'TestVictim',
victim_offhand_weapon_2: 'offhand_weapon_test',
victim_offhand_weapon_2_mods: 0,
victim_weapon_3_mods: 0,
attacker_weapon_2_mods: 0,
attacker_offhand_weapon_1: 'offhand_weapon_test',
attacker_offhand_weapon_1_mods: 0,
attacker_weapon_3_mods: 0,
attacker_offhand_weapon_2: 'offhand_weapon_test',
attacker_offhand_weapon_2_mods: 0,
victim_offhand_weapon_1: 'offhand_weapon_test',
victim_offhand_weapon_1_mods: 0,
attacker_weapon_3: 'defender',
killstat_version: 'ks_3.0.0',
attacker_weapon_1: 'smr',
match_id: '31b1f34d',
distance: 0,
victim_current_weapon: 'smr',
cause_of_death: 'smr',
victim_weapon_2_mods: 0,
victim_current_weapon_mods: 0,
attacker_current_weapon_mods: 0,
game_time: 377.799,
player_count: 1,
attacker_current_weapon: 'smr',
attacker_id: '1',
game_mode: 'tdm',
map: 'thaw',
attacker_weapon_2: 'autopistol',
victim_weapon_1: 'smr',
victim_weapon_2: 'autopistol',
victim_weapon_1_mods: 0,
victim_weapon_3: 'defender',
attacker_name: 'TestAttacker',
victim_titan: 'null',
attacker_titan: 'null'
}
const response = await fetch(`http://127.0.0.1:3001/kill`, {
method: "POST", // *GET, POST, PUT, DELETE, etc.
credentials: "same-origin", // include, *same-origin, omit
headers: {
"Content-Type": "application/json",
'Authorization': `Bearer ${Buffer.from(process.env.SERVERAUTH_TOKEN + '').toString('base64')}`
},
body: JSON.stringify(data), // body data type must match "Content-Type" header
method: "POST",
headers,
body: JSON.stringify(testKill),
});
console.log(await response.text())
expect(response.status).toBe(201)
@@ -116,47 +160,7 @@ describe('server', () => {
test('register a kill with missing data', async () => {
const data = {
servername: 'testserver',
attacker_weapon_1_mods: 0,
victim_id: '0',
victim_name: 'TestVictim',
victim_offhand_weapon_2: 'null',
victim_offhand_weapon_2_mods: 0,
victim_weapon_3_mods: 0,
attacker_weapon_2_mods: NaN,
attacker_offhand_weapon_1: 'null',
attacker_offhand_weapon_1_mods: 0,
attacker_weapon_3_mods: NaN,
attacker_offhand_weapon_2: 'null',
attacker_offhand_weapon_2_mods: NaN,
victim_offhand_weapon_1: 'offhand_weapon_test',
victim_offhand_weapon_1_mods: 0,
attacker_weapon_3: 'defender',
killstat_version: 'ks_3.0.0',
attacker_weapon_1: 'smr',
match_id: '31b1f34d',
distance: 0,
victim_current_weapon: 'smr',
cause_of_death: 'smr',
victim_weapon_2_mods: 0,
victim_current_weapon_mods: 0,
attacker_current_weapon_mods: 0,
game_time: 377.799,
player_count: 1,
attacker_current_weapon: 'smr',
attacker_id: '1',
game_mode: 'tdm',
map: 'thaw',
attacker_weapon_2: 'autopistol',
victim_weapon_1: 'null',
victim_weapon_2: 'autopistol',
victim_weapon_1_mods: 0,
victim_weapon_3: 'defender',
attacker_name: 'TestAttacker',
victim_titan: 'null',
attacker_titan: 'null'
}
const data = testKill
const response = await fetch(`http://127.0.0.1:3001/kill`, {
method: "POST", // *GET, POST, PUT, DELETE, etc.
credentials: "same-origin", // include, *same-origin, omit
@@ -164,17 +168,17 @@ describe('server', () => {
"Content-Type": "application/json",
'Authorization': `Bearer ${Buffer.from(process.env.SERVERAUTH_TOKEN + '').toString('base64')}`
},
body: JSON.stringify(data), // body data type must match "Content-Type" header
body: JSON.stringify(data),
});
expect(response.status).toBe(201)
})
})
afterAll((done) => {
db.deleteFrom('kill').where('attacker_id', '=', '0').orWhere('attacker_id', '=', '1').execute().then(() => {
// db.deleteFrom('kill').where('attacker_id', '=', 0n).orWhere('attacker_id', '=', 1n).execute().then(() => {
listenServer.close(async () => {
await db.destroy()
done()
})
})
// })
})