Commit 8426d009 authored by nanahira's avatar nanahira

add tournament cache

parent 64cd40bb
Pipeline #39681 passed with stages
in 4 minutes and 26 seconds
......@@ -16,12 +16,14 @@
"@nestjs/platform-express": "^11.0.1",
"@nestjs/swagger": "^11.1.5",
"@nestjs/typeorm": "^11.0.0",
"aragami": "^1.2.5",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.1",
"crypto-random-string": "3.3.1",
"iconv-lite": "^0.6.3",
"lodash": "^4.17.21",
"nesties": "^1.1.1",
"nestjs-aragami": "^1.2.0",
"nestjs-mycard": "^4.0.2",
"nicot": "^1.1.21",
"pg": "^8.14.1",
......@@ -1309,6 +1311,12 @@
}
}
},
"node_modules/@ioredis/commands": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.3.0.tgz",
"integrity": "sha512-M/T6Zewn7sDaBQEqIZ8Rb+i9y8qfGmq+5SDFSf9sA2lUZTmdDLVdOiQaeDp+Q4wElZ9HG1GAX5KhDaidp6LQsQ==",
"license": "MIT"
},
"node_modules/@isaacs/cliui": {
"version": "8.0.2",
"resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
......@@ -2812,6 +2820,18 @@
"dev": true,
"license": "MIT"
},
"node_modules/@sesamecare-oss/redlock": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/@sesamecare-oss/redlock/-/redlock-1.4.0.tgz",
"integrity": "sha512-2z589R+yxKLN4CgKxP1oN4dsg6Y548SE4bVYam/R0kHk7Q9VrQ9l66q+k1ehhSLLY4or9hcchuF9/MhuuZdjJg==",
"license": "UNLICENSED",
"engines": {
"node": ">=16"
},
"peerDependencies": {
"ioredis": ">=5"
}
},
"node_modules/@sinclair/typebox": {
"version": "0.27.8",
"resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz",
......@@ -4702,6 +4722,32 @@
"integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==",
"license": "MIT"
},
"node_modules/aragami": {
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/aragami/-/aragami-1.2.5.tgz",
"integrity": "sha512-w+jSXxXYAk3X/TSMoVfc12lY1c40MYqf6W6R2yGE1q7pY4ZC+xpzGBT+Bqa4hO6hlWsM5sFRnKvAE+72HCkT2w==",
"license": "MIT",
"dependencies": {
"@sesamecare-oss/redlock": "^1.4.0",
"better-lock": "^2.0.3",
"class-transformer": "^0.5.1",
"encoded-buffer": "^0.2.6",
"generic-pool": "^3.9.0",
"ioredis": "^5.2.3",
"lodash": "^4.17.21",
"lru-cache": "^7.13.1",
"typed-reflector": "^1.0.11"
}
},
"node_modules/aragami/node_modules/lru-cache": {
"version": "7.18.3",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz",
"integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==",
"license": "ISC",
"engines": {
"node": ">=12"
}
},
"node_modules/arch": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/arch/-/arch-3.0.0.tgz",
......@@ -4763,6 +4809,21 @@
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
"license": "MIT"
},
"node_modules/available-typed-arrays": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
"integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==",
"license": "MIT",
"dependencies": {
"possible-typed-array-names": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/axios": {
"version": "1.8.4",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.8.4.tgz",
......@@ -4942,6 +5003,12 @@
],
"license": "MIT"
},
"node_modules/better-lock": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/better-lock/-/better-lock-2.0.3.tgz",
"integrity": "sha512-3bCaToLrmEXZcIOOVWgi1STvp3/6EpoZAmlWBeuX2MvDB0Ql2ctl/vQ0CbhQIJYQiptdGypllP3ez+TeEmdnKQ==",
"license": "MIT"
},
"node_modules/bin-version": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/bin-version/-/bin-version-6.0.0.tgz",
......@@ -5224,6 +5291,24 @@
"node": ">=14.16"
}
},
"node_modules/call-bind": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz",
"integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.0",
"es-define-property": "^1.0.0",
"get-intrinsic": "^1.2.4",
"set-function-length": "^1.2.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/call-bind-apply-helpers": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
......@@ -5520,6 +5605,15 @@
"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",
"integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==",
"license": "Apache-2.0",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/co": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
......@@ -5922,6 +6016,23 @@
"node": ">=10"
}
},
"node_modules/define-data-property": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
"integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
"license": "MIT",
"dependencies": {
"es-define-property": "^1.0.0",
"es-errors": "^1.3.0",
"gopd": "^1.0.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
......@@ -5931,6 +6042,15 @@
"node": ">=0.4.0"
}
},
"node_modules/denque": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz",
"integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==",
"license": "Apache-2.0",
"engines": {
"node": ">=0.10"
}
},
"node_modules/depd": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
......@@ -6076,6 +6196,24 @@
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"license": "MIT"
},
"node_modules/encoded-buffer": {
"version": "0.2.6",
"resolved": "https://registry.npmjs.org/encoded-buffer/-/encoded-buffer-0.2.6.tgz",
"integrity": "sha512-zEskqXs0FbF9HcwZkumyAoiB3NN23yAoJvPmLP0NuWQLXTeCDMeVRYK1kjIsZPkoXE2cIBS0iht95pqf8UKyog==",
"deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.",
"license": "MIT",
"dependencies": {
"lodash": "^4.17.10",
"to-buffer": "^1.1.1",
"tslib": "^1.9.3"
}
},
"node_modules/encoded-buffer/node_modules/tslib": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
"license": "0BSD"
},
"node_modules/encodeurl": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
......@@ -6911,6 +7049,21 @@
}
}
},
"node_modules/for-each": {
"version": "0.3.5",
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz",
"integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==",
"license": "MIT",
"dependencies": {
"is-callable": "^1.2.7"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/foreground-child": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz",
......@@ -7087,6 +7240,15 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/generic-pool": {
"version": "3.9.0",
"resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-3.9.0.tgz",
"integrity": "sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g==",
"license": "MIT",
"engines": {
"node": ">= 4"
}
},
"node_modules/gensync": {
"version": "1.0.0-beta.2",
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
......@@ -7321,6 +7483,18 @@
"node": ">=8"
}
},
"node_modules/has-property-descriptors": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
"integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
"license": "MIT",
"dependencies": {
"es-define-property": "^1.0.0"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-symbols": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
......@@ -7531,6 +7705,30 @@
"kind-of": "^6.0.2"
}
},
"node_modules/ioredis": {
"version": "5.6.1",
"resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.6.1.tgz",
"integrity": "sha512-UxC0Yv1Y4WRJiGQxQkP0hfdL0/5/6YvdfOOClRgJ0qppSarkhneSa6UvkMkms0AkdGimSH3Ikqm+6mkMmX7vGA==",
"license": "MIT",
"dependencies": {
"@ioredis/commands": "^1.1.1",
"cluster-key-slot": "^1.1.0",
"debug": "^4.3.4",
"denque": "^2.1.0",
"lodash.defaults": "^4.2.0",
"lodash.isarguments": "^3.1.0",
"redis-errors": "^1.2.0",
"redis-parser": "^3.0.0",
"standard-as-callback": "^2.1.0"
},
"engines": {
"node": ">=12.22.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/ioredis"
}
},
"node_modules/ipaddr.js": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
......@@ -7547,6 +7745,18 @@
"dev": true,
"license": "MIT"
},
"node_modules/is-callable": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
"integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-core-module": {
"version": "2.16.1",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
......@@ -7654,6 +7864,21 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/is-typed-array": {
"version": "1.1.15",
"resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz",
"integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==",
"license": "MIT",
"dependencies": {
"which-typed-array": "^1.1.16"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"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",
......@@ -8699,6 +8924,18 @@
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"license": "MIT"
},
"node_modules/lodash.defaults": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz",
"integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==",
"license": "MIT"
},
"node_modules/lodash.isarguments": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz",
"integrity": "sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==",
"license": "MIT"
},
"node_modules/lodash.memoize": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
......@@ -9110,6 +9347,18 @@
"@nestjs/swagger": "^11.0.0 || ^7.1.8 || ^6.3.0"
}
},
"node_modules/nestjs-aragami": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/nestjs-aragami/-/nestjs-aragami-1.2.0.tgz",
"integrity": "sha512-En25/anbQFLJf4+8lHSM9pxqjh/YRoQqvabyG8RQpRbCS4GxrQVJYNaSI9dGpcELippkskBnMWFxEqrX8M7A+g==",
"license": "MIT",
"peerDependencies": {
"@nestjs/common": "^9.1.2 || ^10.0.0 || ^11.0.0",
"@nestjs/core": "^9.4.2 || ^10.0.0 || ^11.0.0",
"aragami": "^1.2.0",
"rxjs": "^7.8.1"
}
},
"node_modules/nestjs-mycard": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/nestjs-mycard/-/nestjs-mycard-4.0.2.tgz",
......@@ -9802,6 +10051,15 @@
"node": ">=4"
}
},
"node_modules/possible-typed-array-names": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz",
"integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/postgres-array": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz",
......@@ -10100,6 +10358,27 @@
"url": "https://paulmillr.com/funding/"
}
},
"node_modules/redis-errors": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz",
"integrity": "sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==",
"license": "MIT",
"engines": {
"node": ">=4"
}
},
"node_modules/redis-parser": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz",
"integrity": "sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==",
"license": "MIT",
"dependencies": {
"redis-errors": "^1.0.0"
},
"engines": {
"node": ">=4"
}
},
"node_modules/reflect-metadata": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz",
......@@ -10461,6 +10740,23 @@
"node": ">= 18"
}
},
"node_modules/set-function-length": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
"integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
"license": "MIT",
"dependencies": {
"define-data-property": "^1.1.4",
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"get-intrinsic": "^1.2.4",
"gopd": "^1.0.1",
"has-property-descriptors": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/setprototypeof": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
......@@ -10714,6 +11010,12 @@
"node": ">=8"
}
},
"node_modules/standard-as-callback": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.1.0.tgz",
"integrity": "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==",
"license": "MIT"
},
"node_modules/statuses": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
......@@ -11338,6 +11640,26 @@
"dev": true,
"license": "BSD-3-Clause"
},
"node_modules/to-buffer": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.2.1.tgz",
"integrity": "sha512-tB82LpAIWjhLYbqjx3X4zEeHN6M8CiuOEy2JY8SEQVdYRe3CCHOFaqrBW1doLDrfpWhplcW7BL+bO3/6S3pcDQ==",
"license": "MIT",
"dependencies": {
"isarray": "^2.0.5",
"safe-buffer": "^5.2.1",
"typed-array-buffer": "^1.0.3"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/to-buffer/node_modules/isarray": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
"integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
"license": "MIT"
},
"node_modules/to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
......@@ -11634,6 +11956,20 @@
"node": ">= 0.6"
}
},
"node_modules/typed-array-buffer": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz",
"integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==",
"license": "MIT",
"dependencies": {
"call-bound": "^1.0.3",
"es-errors": "^1.3.0",
"is-typed-array": "^1.1.14"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/typed-reflector": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/typed-reflector/-/typed-reflector-1.0.11.tgz",
......@@ -12437,6 +12773,27 @@
"node": ">= 8"
}
},
"node_modules/which-typed-array": {
"version": "1.1.19",
"resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz",
"integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==",
"license": "MIT",
"dependencies": {
"available-typed-arrays": "^1.0.7",
"call-bind": "^1.0.8",
"call-bound": "^1.0.4",
"for-each": "^0.3.5",
"get-proto": "^1.0.1",
"gopd": "^1.2.0",
"has-tostringtag": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/word-wrap": {
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
......
......@@ -18,6 +18,10 @@ import { ApiKeyController } from './api-key/api-key.controller';
import { SrvproService } from './srvpro/srvpro.service';
import { SrvproController } from './srvpro/srvpro.controller';
import { HttpModule } from '@nestjs/axios';
import { AragamiModule } from 'nestjs-aragami';
import { TournamentSubscriberService } from './tournament-subscriber/tournament-subscriber.service';
import { ParticipantSubscriberService } from './participant-subscriber/participant-subscriber.service';
import { MatchSubscriberService } from './match-subscriber/match-subscriber.service';
@Module({
imports: [
......@@ -54,6 +58,20 @@ import { HttpModule } from '@nestjs/axios';
}),
}),
TypeOrmModule.forFeature([Tournament, Match, Participant, ApiKey]),
AragamiModule.registerAsync({
inject: [ConfigService],
useFactory: (config: ConfigService) => {
const redisUrl = config.get<string>('REDIS_URL');
if (redisUrl) {
return {
redis: {
uri: redisUrl,
},
};
}
return {};
},
}),
HttpModule,
],
providers: [
......@@ -62,6 +80,9 @@ import { HttpModule } from '@nestjs/axios';
ParticipantService,
ApiKeyService,
SrvproService,
TournamentSubscriberService,
ParticipantSubscriberService,
MatchSubscriberService,
],
controllers: [
TournamentController,
......
import { Test, TestingModule } from '@nestjs/testing';
import { MatchSubscriberService } from './match-subscriber.service';
describe('MatchSubscriberService', () => {
let service: MatchSubscriberService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [MatchSubscriberService],
}).compile();
service = module.get<MatchSubscriberService>(MatchSubscriberService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});
import { Injectable, OnModuleInit } from '@nestjs/common';
import {
DataSource,
EntitySubscriberInterface,
InsertEvent,
RemoveEvent,
SoftRemoveEvent,
UpdateEvent,
} from 'typeorm';
import { InjectDataSource } from '@nestjs/typeorm';
import { Match } from '../match/entities/match.entity';
import { TournamentService } from '../tournament/tournament.service';
import { getFieldFromTypeormEvent } from '../utility/get-field-from-typeorm-event';
@Injectable()
export class MatchSubscriberService
implements EntitySubscriberInterface<Match>, OnModuleInit
{
constructor(
private tournamentService: TournamentService,
@InjectDataSource() private db: DataSource,
) {}
onModuleInit() {
this.db.subscribers.push(this);
}
listenTo() {
return Match;
}
async clearCacheOnEvent(
event:
| UpdateEvent<Match>
| RemoveEvent<Match>
| SoftRemoveEvent<Match>
| InsertEvent<Match>,
) {
let tournamentId = getFieldFromTypeormEvent(event, 'tournamentId');
if (!tournamentId) {
const id = getFieldFromTypeormEvent(event, 'id');
if (id) {
const match = await this.db
.getRepository(Match)
.findOne({ where: { id }, select: ['tournamentId'] });
tournamentId = match?.tournamentId;
}
}
if (tournamentId) {
await this.tournamentService.clearTournamentCache(tournamentId);
}
}
async afterInsert(event: InsertEvent<Match>) {
await this.clearCacheOnEvent(event);
}
async afterUpdate(event: UpdateEvent<Match>) {
await this.clearCacheOnEvent(event);
}
async afterRemove(event: RemoveEvent<Match>) {
await this.clearCacheOnEvent(event);
}
async afterSoftRemove(event: SoftRemoveEvent<Match>) {
await this.clearCacheOnEvent(event);
}
}
import { Test, TestingModule } from '@nestjs/testing';
import { ParticipantSubscriberService } from './participant-subscriber.service';
describe('ParticipantSubscriberService', () => {
let service: ParticipantSubscriberService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [ParticipantSubscriberService],
}).compile();
service = module.get<ParticipantSubscriberService>(ParticipantSubscriberService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});
import { Injectable, OnModuleInit } from '@nestjs/common';
import {
DataSource,
EntitySubscriberInterface,
InsertEvent,
RemoveEvent,
SoftRemoveEvent,
UpdateEvent,
} from 'typeorm';
import { InjectDataSource } from '@nestjs/typeorm';
import { Participant } from '../participant/entities/participant.entity';
import { TournamentService } from '../tournament/tournament.service';
import { getFieldFromTypeormEvent } from '../utility/get-field-from-typeorm-event';
@Injectable()
export class ParticipantSubscriberService
implements EntitySubscriberInterface<Participant>, OnModuleInit
{
constructor(
private tournamentService: TournamentService,
@InjectDataSource() private db: DataSource,
) {}
onModuleInit() {
this.db.subscribers.push(this);
}
listenTo() {
return Participant;
}
async clearCacheOnEvent(
event:
| UpdateEvent<Participant>
| RemoveEvent<Participant>
| SoftRemoveEvent<Participant>
| InsertEvent<Participant>,
) {
let tournamentId = getFieldFromTypeormEvent(event, 'tournamentId');
if (!tournamentId) {
const id = getFieldFromTypeormEvent(event, 'id');
if (id) {
const participant = await this.db
.getRepository(Participant)
.findOne({ where: { id }, select: ['tournamentId'] });
tournamentId = participant?.tournamentId;
}
}
if (tournamentId) {
await this.tournamentService.clearTournamentCache(tournamentId);
}
}
// 4 event handlers for different events
async afterUpdate(event: UpdateEvent<Participant>) {
await this.clearCacheOnEvent(event);
}
async afterSoftRemove(event: SoftRemoveEvent<Participant>) {
await this.clearCacheOnEvent(event);
}
async afterRemove(event: RemoveEvent<Participant>) {
await this.clearCacheOnEvent(event);
}
async afterInsert(event: InsertEvent<Participant>) {
await this.clearCacheOnEvent(event);
}
}
import { Test, TestingModule } from '@nestjs/testing';
import { TournamentSubscriberService } from './tournament-subscriber.service';
describe('TournamentSubscriberService', () => {
let service: TournamentSubscriberService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [TournamentSubscriberService],
}).compile();
service = module.get<TournamentSubscriberService>(TournamentSubscriberService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});
import { Injectable, OnModuleInit } from '@nestjs/common';
import {
DataSource,
EntitySubscriberInterface,
RemoveEvent,
SoftRemoveEvent,
UpdateEvent,
} from 'typeorm';
import { Tournament } from '../tournament/entities/Tournament.entity';
import { TournamentService } from '../tournament/tournament.service';
import { InjectDataSource } from '@nestjs/typeorm';
import { getFieldFromTypeormEvent } from '../utility/get-field-from-typeorm-event';
@Injectable()
export class TournamentSubscriberService
implements EntitySubscriberInterface<Tournament>, OnModuleInit
{
constructor(
private tournamentService: TournamentService,
@InjectDataSource() private db: DataSource,
) {}
onModuleInit() {
this.db.subscribers.push(this);
}
listenTo() {
return Tournament;
}
async clearCacheOnEvent(
event:
| UpdateEvent<Tournament>
| SoftRemoveEvent<Tournament>
| RemoveEvent<Tournament>,
) {
await this.tournamentService.clearTournamentCache(
getFieldFromTypeormEvent(event, 'id'),
);
}
// three event handlers for different events
async afterUpdate(event: UpdateEvent<Tournament>) {
await this.clearCacheOnEvent(event);
}
async afterSoftRemove(event: SoftRemoveEvent<Tournament>) {
await this.clearCacheOnEvent(event);
}
async afterRemove(event: RemoveEvent<Tournament>) {
await this.clearCacheOnEvent(event);
}
}
......@@ -43,6 +43,7 @@ import { TournamentRules } from '../../tournament-rules/rule-map';
import _ from 'lodash';
import { RenameClass } from 'nicot/dist/src/utility/rename-class';
import { QueryIn } from '../../utility/decorators/query-in';
import { CacheTTL } from 'aragami';
export enum TournamentRule {
SingleElimination = 'SingleElimination',
......@@ -78,6 +79,7 @@ export class RuleSettings {
hasThirdPlaceMatch: boolean;
}
@CacheTTL(7200000)
@Entity()
export class Tournament extends DescBase {
@QueryEqual()
......@@ -242,6 +244,16 @@ export class Tournament extends DescBase {
return this.checkPermissionWithUserId(user.id);
}
wipeDeckBuf(user: MycardUser | number) {
try {
this.checkPermission(user);
} catch (e) {
this.participants?.forEach((p) => {
p.deckbuf = undefined;
});
}
}
calculateScore() {
const rule = this.getRuleHandler();
this.participants.forEach((p) => {
......
......@@ -28,6 +28,8 @@ import { DragParticipantDto } from './dto/drag-participant.dto';
import { dragRearrange } from '../utility/drag-rearrange';
import { normalSeq } from '../utility/normal-seq';
import { sortAfterSwiss } from '../utility/soft-after-swiss';
import { InjectAragami } from 'nestjs-aragami';
import { Aragami } from 'aragami';
@Injectable()
export class TournamentService extends CrudService(Tournament, {
......@@ -56,6 +58,7 @@ export class TournamentService extends CrudService(Tournament, {
private readonly participantService: ParticipantService,
private config: ConfigService,
private http: HttpService,
@InjectAragami() private aragami: Aragami,
) {
super(repo);
}
......@@ -72,18 +75,23 @@ export class TournamentService extends CrudService(Tournament, {
user: MycardUser | number,
noAnalytics = false,
) {
const result = await this.findOne(id, (qb) =>
Tournament.extraQueryForUser(user, qb, this.entityAliasName),
);
// we check for permission first
await this.findOne(id, (qb) => {
Tournament.extraQueryForUser(user, qb, this.entityAliasName);
qb.select(`${this.entityAliasName}.id`);
});
const key = `tournament_cache:${id}:${noAnalytics ? 1 : 0}`;
const res = await this.aragami.cache(Tournament, key, async () => {
const result = await this.findOne(id);
if (result.data) {
result.data.participants?.forEach((p) =>
this.participantService.wipeDeckbuf(user, p, result.data),
);
if (result.data.status === TournamentStatus.Ready && !noAnalytics) {
result.data.analytics();
}
}
return result;
return result.data;
});
res.wipeDeckBuf(user);
return new GenericReturnMessageDto(200, 'success', res);
}
async getTournaments(dto: Partial<Tournament>, user: MycardUser | number) {
......@@ -91,11 +99,7 @@ export class TournamentService extends CrudService(Tournament, {
const res = await new tmpCls(this.repo).findAll(dto, (qb) =>
Tournament.extraQueryForUser(user, qb, this.entityAliasName),
);
res.data?.forEach((t) =>
t.participants?.forEach((p) =>
this.participantService.wipeDeckbuf(user, p, t),
),
);
res.data?.forEach((t) => t.wipeDeckBuf(user));
return res;
}
......@@ -511,4 +515,9 @@ export class TournamentService extends CrudService(Tournament, {
const { updates } = dragRearrange(participants, draggingIndex, insertAfter);
return this.updateParticipantSeq(updates);
}
async clearTournamentCache(id: number) {
if (!id) return;
await this.aragami.clear(Tournament, `tournament_cache:${id}:`);
}
}
import {
InsertEvent,
RemoveEvent,
SoftRemoveEvent,
UpdateEvent,
} from 'typeorm';
export const getFieldFromTypeormEvent = <T, K extends keyof T>(
evt: InsertEvent<T> | UpdateEvent<T> | SoftRemoveEvent<T> | RemoveEvent<T>,
field: K,
) => {
return (evt.entity as T)?.[field] ?? (evt['databaseEntity'] as T)?.[field];
};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment