Add cache purging for leaderboards

This commit is contained in:
Justin Maier
2023-05-23 15:14:42 -06:00
parent 2577fe9285
commit c116d1d2d7
9 changed files with 414 additions and 17 deletions
+332
View File
@@ -65,6 +65,7 @@
"axios": "^1.2.3",
"blurhash": "^2.0.4",
"chalk": "^5.2.0",
"cloudflare": "^2.9.1",
"cookies-next": "^2.1.1",
"cron-parser": "^4.6.0",
"dayjs": "^1.11.6",
@@ -118,6 +119,7 @@
"devDependencies": {
"@babel/core": "^7.19.3",
"@next/eslint-plugin-next": "^12.1.4",
"@types/cloudflare": "^2.7.9",
"@types/lodash": "^4.14.189",
"@types/lodash-es": "^4.17.7",
"@types/marked": "^4.0.7",
@@ -4138,6 +4140,12 @@
"integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==",
"dev": true
},
"node_modules/@types/cloudflare": {
"version": "2.7.9",
"resolved": "https://registry.npmjs.org/@types/cloudflare/-/cloudflare-2.7.9.tgz",
"integrity": "sha512-lpIZEZBeN03Bmay43vanPiz06qUY50nyNlYIrWs/YFqxM5YMWW4eWsLFHUDqebHDNpTt0zbhXwRqZwRsucMNxg==",
"dev": true
},
"node_modules/@types/cookie": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz",
@@ -4711,6 +4719,17 @@
"node": ">=0.4.0"
}
},
"node_modules/agent-base": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
"integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
"dependencies": {
"debug": "4"
},
"engines": {
"node": ">= 6.0.0"
}
},
"node_modules/ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
@@ -4901,6 +4920,11 @@
"node": ">=4"
}
},
"node_modules/autocreate": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/autocreate/-/autocreate-1.2.0.tgz",
"integrity": "sha512-69hVJ14Nm6rP5b4fd5TQGbBCPxH3M4L+/eDrCePoa3dCyNHWFS/HhE8mY6DG5q6LMscjMcjpSwEsX8G+8jT5ZA=="
},
"node_modules/available-typed-arrays": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz",
@@ -5180,6 +5204,17 @@
}
]
},
"node_modules/capture-stack-trace": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.2.tgz",
"integrity": "sha512-X/WM2UQs6VMHUtjUDnZTRI+i1crWteJySFzr9UpGoQa4WQffXVTTXuekjl7TjZRlcF2XfjgITT0HxZ9RnxeT0w==",
"engines": {
"node": ">=0.10.0"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/case-anything": {
"version": "2.1.10",
"resolved": "https://registry.npmjs.org/case-anything/-/case-anything-2.1.10.tgz",
@@ -5262,6 +5297,20 @@
"node": ">=0.8"
}
},
"node_modules/cloudflare": {
"version": "2.9.1",
"resolved": "https://registry.npmjs.org/cloudflare/-/cloudflare-2.9.1.tgz",
"integrity": "sha512-x8yXPPoloy7xQ9GCKnsvQ3U1nwvcLndA2B3nxwSjIWxgLTUJOyakeEDsrqxZO8Dr6FkGdaXwy554fQVMpOabiw==",
"dependencies": {
"autocreate": "^1.1.0",
"es-class": "^2.1.1",
"got": "^6.3.0",
"https-proxy-agent": "^5.0.0",
"object-assign": "^4.1.0",
"should-proxy": "^1.0.4",
"url-pattern": "^1.0.3"
}
},
"node_modules/clsx": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/clsx/-/clsx-1.1.1.tgz",
@@ -5427,6 +5476,17 @@
"node": ">=10"
}
},
"node_modules/create-error-class": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz",
"integrity": "sha512-gYTKKexFO3kh200H1Nit76sRwRtOY32vQd3jpAQKpLtZqyNsSQNfI4N7o3eP2wUjV35pTWKRYqFUDBvUha/Pkw==",
"dependencies": {
"capture-stack-trace": "^1.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/create-require": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
@@ -5839,6 +5899,11 @@
"safe-buffer": "~5.1.0"
}
},
"node_modules/duplexer3": {
"version": "0.1.5",
"resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.5.tgz",
"integrity": "sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA=="
},
"node_modules/electron-to-chromium": {
"version": "1.4.365",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.365.tgz",
@@ -5995,6 +6060,11 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/es-class": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/es-class/-/es-class-2.1.1.tgz",
"integrity": "sha512-loFNtCIGY81XvaHMzsxPocOgwZW71p+d/iES+zDSWeK9D4JaxrR/AoO0sZnWbV39D/ESppKbHrApxMi+Vbl8rg=="
},
"node_modules/es-get-iterator": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz",
@@ -7125,6 +7195,14 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/get-stream": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
"integrity": "sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==",
"engines": {
"node": ">=4"
}
},
"node_modules/get-symbol-description": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz",
@@ -7255,6 +7333,27 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/got": {
"version": "6.7.1",
"resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz",
"integrity": "sha512-Y/K3EDuiQN9rTZhBvPRWMLXIKdeD1Rj0nzunfoi0Yyn5WBEbzxXKU9Ub2X41oZBagVWOBU3MuDonFMgPWQFnwg==",
"dependencies": {
"create-error-class": "^3.0.0",
"duplexer3": "^0.1.4",
"get-stream": "^3.0.0",
"is-redirect": "^1.0.0",
"is-retry-allowed": "^1.0.0",
"is-stream": "^1.0.0",
"lowercase-keys": "^1.0.0",
"safe-buffer": "^5.0.1",
"timed-out": "^4.0.0",
"unzip-response": "^2.0.1",
"url-parse-lax": "^1.0.0"
},
"engines": {
"node": ">=4"
}
},
"node_modules/graceful-fs": {
"version": "4.2.11",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
@@ -7682,6 +7781,18 @@
"node": ">=4.0.0"
}
},
"node_modules/https-proxy-agent": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
"integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
"dependencies": {
"agent-base": "6",
"debug": "4"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
@@ -8071,6 +8182,14 @@
"node": ">=0.10.0"
}
},
"node_modules/is-redirect": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz",
"integrity": "sha512-cr/SlUEe5zOGmzvj9bUyC4LVvkNVAXu4GytXLNMr1pny+a65MpQ9IJzFHD5vi7FyJgb4qt27+eS3TuQnqB+RQw==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/is-regex": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
@@ -8086,6 +8205,14 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-retry-allowed": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz",
"integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/is-set": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz",
@@ -8107,6 +8234,14 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-stream": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
"integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/is-string": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz",
@@ -8457,6 +8592,14 @@
"loose-envify": "cli.js"
}
},
"node_modules/lowercase-keys": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
"integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/lru-cache": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
@@ -9928,6 +10071,14 @@
"node": ">= 0.8.0"
}
},
"node_modules/prepend-http": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz",
"integrity": "sha512-PhmXi5XmoyKw1Un4E+opM2KcsJInDvKyuOumcjjw3waw86ZNjHwVUOOWLc4bCzLdcKNaWBH9e99sbWzDQsVaYg==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/prettier": {
"version": "2.8.7",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.7.tgz",
@@ -11047,6 +11198,11 @@
"node": ">=8"
}
},
"node_modules/should-proxy": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/should-proxy/-/should-proxy-1.0.4.tgz",
"integrity": "sha512-RPQhIndEIVUCjkfkQ6rs6sOR6pkxJWCNdxtfG5pP0RVgUYbK5911kLTF0TNcCC0G3YCGd492rMollFT2aTd9iQ=="
},
"node_modules/side-channel": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
@@ -11623,6 +11779,14 @@
"xtend": "~2.1.1"
}
},
"node_modules/timed-out": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz",
"integrity": "sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/tiny-glob": {
"version": "0.2.9",
"resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz",
@@ -12003,6 +12167,14 @@
"node": ">= 0.8"
}
},
"node_modules/unzip-response": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz",
"integrity": "sha512-N0XH6lqDtFH84JxptQoZYmloF4nzrQqqrAymNj+/gW60AO2AZgOcf4O/nUXJcYfyQkqvMo9lSupBZmmgvuVXlw==",
"engines": {
"node": ">=4"
}
},
"node_modules/update-browserslist-db": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz",
@@ -12042,6 +12214,25 @@
"punycode": "^2.1.0"
}
},
"node_modules/url-parse-lax": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz",
"integrity": "sha512-BVA4lR5PIviy2PMseNd2jbFQ+jwSwQGdJejf5ctd1rEXt0Ypd7yanUK9+lYechVlN5VaTJGsu2U/3MDDu6KgBA==",
"dependencies": {
"prepend-http": "^1.0.1"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/url-pattern": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/url-pattern/-/url-pattern-1.0.3.tgz",
"integrity": "sha512-uQcEj/2puA4aq1R3A2+VNVBgaWYR24FdWjl7VNW83rnWftlhyzOZ/tBjezRiC2UkIzuxC8Top3IekN3vUf1WxA==",
"engines": {
"node": ">=0.12.0"
}
},
"node_modules/use-composed-ref": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/use-composed-ref/-/use-composed-ref-1.3.0.tgz",
@@ -15382,6 +15573,12 @@
"integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==",
"dev": true
},
"@types/cloudflare": {
"version": "2.7.9",
"resolved": "https://registry.npmjs.org/@types/cloudflare/-/cloudflare-2.7.9.tgz",
"integrity": "sha512-lpIZEZBeN03Bmay43vanPiz06qUY50nyNlYIrWs/YFqxM5YMWW4eWsLFHUDqebHDNpTt0zbhXwRqZwRsucMNxg==",
"dev": true
},
"@types/cookie": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz",
@@ -15831,6 +16028,14 @@
"integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==",
"dev": true
},
"agent-base": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
"integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
"requires": {
"debug": "4"
}
},
"ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
@@ -15978,6 +16183,11 @@
"resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.2.tgz",
"integrity": "sha512-7prDjvt9HmqiZ0cl5CRjtS84sEyhsHP2coDkaZKRKVfCDo9s7iw7ChVmar78Gu9pC4SoR/28wFu/G5JJhTnqEg=="
},
"autocreate": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/autocreate/-/autocreate-1.2.0.tgz",
"integrity": "sha512-69hVJ14Nm6rP5b4fd5TQGbBCPxH3M4L+/eDrCePoa3dCyNHWFS/HhE8mY6DG5q6LMscjMcjpSwEsX8G+8jT5ZA=="
},
"available-typed-arrays": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz",
@@ -16172,6 +16382,11 @@
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001480.tgz",
"integrity": "sha512-q7cpoPPvZYgtyC4VaBSN0Bt+PJ4c4EYRf0DrduInOz2SkFpHD5p3LnvEpqBp7UnJn+8x1Ogl1s38saUxe+ihQQ=="
},
"capture-stack-trace": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.2.tgz",
"integrity": "sha512-X/WM2UQs6VMHUtjUDnZTRI+i1crWteJySFzr9UpGoQa4WQffXVTTXuekjl7TjZRlcF2XfjgITT0HxZ9RnxeT0w=="
},
"case-anything": {
"version": "2.1.10",
"resolved": "https://registry.npmjs.org/case-anything/-/case-anything-2.1.10.tgz",
@@ -16223,6 +16438,20 @@
"resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
"integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w=="
},
"cloudflare": {
"version": "2.9.1",
"resolved": "https://registry.npmjs.org/cloudflare/-/cloudflare-2.9.1.tgz",
"integrity": "sha512-x8yXPPoloy7xQ9GCKnsvQ3U1nwvcLndA2B3nxwSjIWxgLTUJOyakeEDsrqxZO8Dr6FkGdaXwy554fQVMpOabiw==",
"requires": {
"autocreate": "^1.1.0",
"es-class": "^2.1.1",
"got": "^6.3.0",
"https-proxy-agent": "^5.0.0",
"object-assign": "^4.1.0",
"should-proxy": "^1.0.4",
"url-pattern": "^1.0.3"
}
},
"clsx": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/clsx/-/clsx-1.1.1.tgz",
@@ -16351,6 +16580,14 @@
"yaml": "^1.10.0"
}
},
"create-error-class": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz",
"integrity": "sha512-gYTKKexFO3kh200H1Nit76sRwRtOY32vQd3jpAQKpLtZqyNsSQNfI4N7o3eP2wUjV35pTWKRYqFUDBvUha/Pkw==",
"requires": {
"capture-stack-trace": "^1.0.0"
}
},
"create-require": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
@@ -16667,6 +16904,11 @@
}
}
},
"duplexer3": {
"version": "0.1.5",
"resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.5.tgz",
"integrity": "sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA=="
},
"electron-to-chromium": {
"version": "1.4.365",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.365.tgz",
@@ -16790,6 +17032,11 @@
"which-typed-array": "^1.1.9"
}
},
"es-class": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/es-class/-/es-class-2.1.1.tgz",
"integrity": "sha512-loFNtCIGY81XvaHMzsxPocOgwZW71p+d/iES+zDSWeK9D4JaxrR/AoO0sZnWbV39D/ESppKbHrApxMi+Vbl8rg=="
},
"es-get-iterator": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz",
@@ -17608,6 +17855,11 @@
"has-symbols": "^1.0.3"
}
},
"get-stream": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
"integrity": "sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ=="
},
"get-symbol-description": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz",
@@ -17702,6 +17954,24 @@
"get-intrinsic": "^1.1.3"
}
},
"got": {
"version": "6.7.1",
"resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz",
"integrity": "sha512-Y/K3EDuiQN9rTZhBvPRWMLXIKdeD1Rj0nzunfoi0Yyn5WBEbzxXKU9Ub2X41oZBagVWOBU3MuDonFMgPWQFnwg==",
"requires": {
"create-error-class": "^3.0.0",
"duplexer3": "^0.1.4",
"get-stream": "^3.0.0",
"is-redirect": "^1.0.0",
"is-retry-allowed": "^1.0.0",
"is-stream": "^1.0.0",
"lowercase-keys": "^1.0.0",
"safe-buffer": "^5.0.1",
"timed-out": "^4.0.0",
"unzip-response": "^2.0.1",
"url-parse-lax": "^1.0.0"
}
},
"graceful-fs": {
"version": "4.2.11",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
@@ -18014,6 +18284,15 @@
"debug": "^4.3.4"
}
},
"https-proxy-agent": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
"integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
"requires": {
"agent-base": "6",
"debug": "4"
}
},
"iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
@@ -18262,6 +18541,11 @@
"isobject": "^3.0.1"
}
},
"is-redirect": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz",
"integrity": "sha512-cr/SlUEe5zOGmzvj9bUyC4LVvkNVAXu4GytXLNMr1pny+a65MpQ9IJzFHD5vi7FyJgb4qt27+eS3TuQnqB+RQw=="
},
"is-regex": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
@@ -18271,6 +18555,11 @@
"has-tostringtag": "^1.0.0"
}
},
"is-retry-allowed": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz",
"integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg=="
},
"is-set": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz",
@@ -18286,6 +18575,11 @@
"call-bind": "^1.0.2"
}
},
"is-stream": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
"integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ=="
},
"is-string": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz",
@@ -18557,6 +18851,11 @@
"js-tokens": "^3.0.0 || ^4.0.0"
}
},
"lowercase-keys": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
"integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA=="
},
"lru-cache": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
@@ -19502,6 +19801,11 @@
"integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
"dev": true
},
"prepend-http": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz",
"integrity": "sha512-PhmXi5XmoyKw1Un4E+opM2KcsJInDvKyuOumcjjw3waw86ZNjHwVUOOWLc4bCzLdcKNaWBH9e99sbWzDQsVaYg=="
},
"prettier": {
"version": "2.8.7",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.7.tgz",
@@ -20372,6 +20676,11 @@
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
"dev": true
},
"should-proxy": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/should-proxy/-/should-proxy-1.0.4.tgz",
"integrity": "sha512-RPQhIndEIVUCjkfkQ6rs6sOR6pkxJWCNdxtfG5pP0RVgUYbK5911kLTF0TNcCC0G3YCGd492rMollFT2aTd9iQ=="
},
"side-channel": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
@@ -20797,6 +21106,11 @@
"xtend": "~2.1.1"
}
},
"timed-out": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz",
"integrity": "sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA=="
},
"tiny-glob": {
"version": "0.2.9",
"resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz",
@@ -21067,6 +21381,11 @@
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
"integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="
},
"unzip-response": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz",
"integrity": "sha512-N0XH6lqDtFH84JxptQoZYmloF4nzrQqqrAymNj+/gW60AO2AZgOcf4O/nUXJcYfyQkqvMo9lSupBZmmgvuVXlw=="
},
"update-browserslist-db": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz",
@@ -21086,6 +21405,19 @@
"punycode": "^2.1.0"
}
},
"url-parse-lax": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz",
"integrity": "sha512-BVA4lR5PIviy2PMseNd2jbFQ+jwSwQGdJejf5ctd1rEXt0Ypd7yanUK9+lYechVlN5VaTJGsu2U/3MDDu6KgBA==",
"requires": {
"prepend-http": "^1.0.1"
}
},
"url-pattern": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/url-pattern/-/url-pattern-1.0.3.tgz",
"integrity": "sha512-uQcEj/2puA4aq1R3A2+VNVBgaWYR24FdWjl7VNW83rnWftlhyzOZ/tBjezRiC2UkIzuxC8Top3IekN3vUf1WxA=="
},
"use-composed-ref": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/use-composed-ref/-/use-composed-ref-1.3.0.tgz",
+2
View File
@@ -84,6 +84,7 @@
"axios": "^1.2.3",
"blurhash": "^2.0.4",
"chalk": "^5.2.0",
"cloudflare": "^2.9.1",
"cookies-next": "^2.1.1",
"cron-parser": "^4.6.0",
"dayjs": "^1.11.6",
@@ -137,6 +138,7 @@
"devDependencies": {
"@babel/core": "^7.19.3",
"@next/eslint-plugin-next": "^12.1.4",
"@types/cloudflare": "^2.7.9",
"@types/lodash": "^4.14.189",
"@types/lodash-es": "^4.17.7",
"@types/marked": "^4.0.7",
+2
View File
@@ -58,6 +58,8 @@ export const serverSchema = z.object({
RATE_LIMITING: zc.booleanString,
CF_ACCOUNT_ID: z.string(),
CF_IMAGES_TOKEN: z.string(),
CF_API_TOKEN: z.string().optional(),
CF_ZONE_ID: z.string().optional(),
JOB_TOKEN: z.string(),
WEBHOOK_TOKEN: z.string(),
SCANNING_ENDPOINT: z.string(),
+2 -3
View File
@@ -25,7 +25,7 @@ import { isProd } from '~/env/other';
import { updateMetricsModelJob } from '~/server/jobs/update-metrics-models';
import { applyContestTags } from '~/server/jobs/apply-contest-tags';
import { applyNsfwBaseline } from '~/server/jobs/apply-nsfw-baseline';
import { prepareLeaderboard, updateUserLeaderboardRank } from '~/server/jobs/prepare-leaderboard';
import { leaderboardJobs } from '~/server/jobs/prepare-leaderboard';
import { deliverLeaderboardCosmetics } from '~/server/jobs/deliver-leaderboard-cosmetics';
const jobs: Job[] = [
@@ -48,8 +48,7 @@ const jobs: Job[] = [
applyContestTags,
...applyDiscordRoles,
applyNsfwBaseline,
prepareLeaderboard,
updateUserLeaderboardRank,
...leaderboardJobs,
];
const log = createLogger('jobs', 'green');
+27
View File
@@ -0,0 +1,27 @@
import cloudflare from 'cloudflare';
import { env } from '~/env/server.mjs';
import { createLogger } from '~/utils/logging';
const log = createLogger('cloudflare', 'green');
const getClient = () => {
if (!env.CF_API_TOKEN) return null;
const cf = new cloudflare({
token: env.CF_API_TOKEN,
});
log('Created client');
return cf;
};
const client: ReturnType<typeof getClient> | null = null;
getClient();
export function purgeCache({ urls, tags }: { urls?: string[]; tags?: string[] }) {
if (!env.CF_ZONE_ID) return;
client?.zones.purgeCache(env.CF_ZONE_ID, {
tags,
prefixes: urls,
});
log('Purged cache', { urls, tags });
}
+13 -2
View File
@@ -2,10 +2,11 @@ import { createJob, getJobDate } from './job';
import { dbWrite } from '~/server/db/client';
import dayjs from 'dayjs';
import { createLogger } from '~/utils/logging';
import { purgeCache } from '~/server/cloudflare/client';
const log = createLogger('leaderboard', 'blue');
export const prepareLeaderboard = createJob('prepare-leaderboard', '0 23 * * *', async () => {
const prepareLeaderboard = createJob('prepare-leaderboard', '0 23 * * *', async () => {
const [lastRun, setLastRun] = await getJobDate('prepare-leaderboard');
await setModelCoverImageNsfwLevel();
@@ -49,7 +50,7 @@ export const prepareLeaderboard = createJob('prepare-leaderboard', '0 23 * * *',
await setLastRun();
});
export const updateUserLeaderboardRank = createJob(
const updateUserLeaderboardRank = createJob(
'update-user-leaderboard-rank',
'1 0 * * *',
async () => {
@@ -103,3 +104,13 @@ async function setModelCoverImageNsfwLevel() {
WHERE mnl.id = m.id;
`;
}
const clearLeaderboardCache = createJob('clear-leaderboard-cache', '0 0 * * *', async () => {
await purgeCache({ tags: ['leaderboard'] });
});
export const leaderboardJobs = [
prepareLeaderboard,
updateUserLeaderboardRank,
clearLeaderboardCache,
];
+14 -7
View File
@@ -4,7 +4,7 @@ import { z } from 'zod';
import { BrowsingMode } from '~/server/common/enums';
import { env } from '~/env/server.mjs';
import { redis } from '~/server/redis/client';
import { hashifyObject } from '~/utils/string-helpers';
import { hashifyObject, slugit } from '~/utils/string-helpers';
import { fromJson, toJson } from '~/utils/json-helpers';
import { applyAnonymousUserRules } from '~/server/services/image.service';
import { isProd } from '~/env/other';
@@ -110,14 +110,13 @@ export function cacheIt<TInput extends object>({
}
type EdgeCacheItProps = {
ttl?: number;
ttl?: number | false;
expireAt?: () => Date;
tags?: (input: any) => string[];
};
export function edgeCacheIt({ ttl, expireAt }: EdgeCacheItProps = {}) {
ttl ??= 60 * 3;
return middleware(async ({ next, ctx }) => {
let reqTTL = ttl as number;
export function edgeCacheIt({ ttl, expireAt, tags }: EdgeCacheItProps = {}) {
return middleware(async ({ next, ctx, input }) => {
let reqTTL = ttl === false ? 24 * 60 * 60 : ttl ?? 60 * 3;
if (expireAt) reqTTL = Math.floor((expireAt().getTime() - Date.now()) / 1000);
const result = await next();
@@ -128,6 +127,14 @@ export function edgeCacheIt({ ttl, expireAt }: EdgeCacheItProps = {}) {
);
ctx.res?.removeHeader('Set-Cookie');
}
if (tags) {
ctx.res?.setHeader(
'Cache-Tag',
tags(input)
.map((x) => slugit(x))
.join(',')
);
}
return result;
});
+13 -4
View File
@@ -11,24 +11,33 @@ import {
} from '~/server/services/leaderboard.service';
import { publicProcedure, router } from '~/server/trpc';
const expireAt = () => dayjs().add(1, 'day').startOf('day').add(1, 'minute').toDate();
export const leaderboardRouter = router({
getLeaderboards: publicProcedure.query(({ ctx }) =>
getLeaderboards({ isModerator: ctx?.user?.isModerator ?? false })
),
getLeaderboardPositions: publicProcedure
.input(getLeaderboardPositionsSchema)
.use(
edgeCacheIt({
ttl: false,
tags: (input) => ['leaderboard', `leaderboard-positions-${input.userId}`],
})
)
.query(({ input, ctx }) =>
getLeaderboardPositions({
...input,
userId: input.userId ?? ctx.user?.id,
userId: input.userId,
isModerator: ctx?.user?.isModerator ?? false,
})
),
getLeaderboard: publicProcedure
.input(getLeaderboardSchema)
.use(edgeCacheIt({ expireAt }))
.use(
edgeCacheIt({
ttl: false,
tags: (input) => ['leaderboard', `leaderboard-${input.id}`],
})
)
.query(({ input, ctx }) =>
getLeaderboard({ ...input, isModerator: ctx?.user?.isModerator ?? false })
),
+9 -1
View File
@@ -30,8 +30,16 @@ export async function getLeaderboards(input: IsMod) {
return leaderboards;
}
type LeaderboardPosition = {
leaderboardId: string;
position: number;
score: number;
metrics: Prisma.JsonValue;
};
export async function getLeaderboardPositions(input: GetLeaderboardPositionsInput & IsMod) {
const userId = input.userId;
if (!userId) return [] as LeaderboardPosition[];
// strip time from date
let date = input.date ?? new Date();
date = new Date(date.getFullYear(), date.getMonth(), date.getDate());
@@ -50,7 +58,7 @@ export async function getLeaderboardPositions(input: GetLeaderboardPositionsInpu
},
});
return positions;
return positions as LeaderboardPosition[];
}
const metricOrder = ['ratingCount', 'heart', 'downloadCount', 'viewCount', 'shots', 'hit', 'miss'];