Adds ICS
This commit is contained in:
parent
441715675c
commit
a79898b2e9
48 changed files with 2062 additions and 1503 deletions
3
README.md
Normal file
3
README.md
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
# The PnP Scheduler Discord-Bot
|
||||||
|
|
||||||
|
Invite: https://discord.com/oauth2/authorize?client_id=1347546897170173985
|
||||||
393
package-lock.json
generated
393
package-lock.json
generated
|
|
@ -18,9 +18,11 @@
|
||||||
"discord.js": "^14.18.0",
|
"discord.js": "^14.18.0",
|
||||||
"dotenv": "^16.4.7",
|
"dotenv": "^16.4.7",
|
||||||
"esbuild": "^0.25.0",
|
"esbuild": "^0.25.0",
|
||||||
|
"ics": "^3.8.1",
|
||||||
"is-plain-object": "^5.0.0",
|
"is-plain-object": "^5.0.0",
|
||||||
"log4js": "^6.9.1",
|
"log4js": "^6.9.1",
|
||||||
"node-cron": "^4.0.7",
|
"node-cron": "^4.0.7",
|
||||||
|
"node-ical": "^0.20.1",
|
||||||
"object-path-set": "^1.0.2",
|
"object-path-set": "^1.0.2",
|
||||||
"svg2img": "^1.0.0-beta.2"
|
"svg2img": "^1.0.0-beta.2"
|
||||||
},
|
},
|
||||||
|
|
@ -2048,6 +2050,12 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "Python-2.0"
|
"license": "Python-2.0"
|
||||||
},
|
},
|
||||||
|
"node_modules/asynckit": {
|
||||||
|
"version": "0.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||||
|
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/atob": {
|
"node_modules/atob": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
|
||||||
|
|
@ -2060,6 +2068,17 @@
|
||||||
"node": ">= 4.5.0"
|
"node": ">= 4.5.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/axios": {
|
||||||
|
"version": "1.10.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/axios/-/axios-1.10.0.tgz",
|
||||||
|
"integrity": "sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"follow-redirects": "^1.15.6",
|
||||||
|
"form-data": "^4.0.0",
|
||||||
|
"proxy-from-env": "^1.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/balanced-match": {
|
"node_modules/balanced-match": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||||
|
|
@ -2193,6 +2212,19 @@
|
||||||
"node": ">=0.4.0"
|
"node": ">=0.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"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",
|
||||||
|
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"es-errors": "^1.3.0",
|
||||||
|
"function-bind": "^1.1.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/callsites": {
|
"node_modules/callsites": {
|
||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
|
||||||
|
|
@ -2255,6 +2287,18 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/combined-stream": {
|
||||||
|
"version": "1.0.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||||
|
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"delayed-stream": "~1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/concat-map": {
|
"node_modules/concat-map": {
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||||
|
|
@ -2343,6 +2387,15 @@
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/delayed-stream": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/detect-libc": {
|
"node_modules/detect-libc": {
|
||||||
"version": "2.0.3",
|
"version": "2.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz",
|
||||||
|
|
@ -2405,6 +2458,20 @@
|
||||||
"url": "https://dotenvx.com"
|
"url": "https://dotenvx.com"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/dunder-proto": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"call-bind-apply-helpers": "^1.0.1",
|
||||||
|
"es-errors": "^1.3.0",
|
||||||
|
"gopd": "^1.2.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/end-of-stream": {
|
"node_modules/end-of-stream": {
|
||||||
"version": "1.4.4",
|
"version": "1.4.4",
|
||||||
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
|
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
|
||||||
|
|
@ -2414,6 +2481,51 @@
|
||||||
"once": "^1.4.0"
|
"once": "^1.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/es-define-property": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/es-errors": {
|
||||||
|
"version": "1.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
|
||||||
|
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/es-object-atoms": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"es-errors": "^1.3.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/es-set-tostringtag": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"es-errors": "^1.3.0",
|
||||||
|
"get-intrinsic": "^1.2.6",
|
||||||
|
"has-tostringtag": "^1.0.2",
|
||||||
|
"hasown": "^2.0.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/esbuild": {
|
"node_modules/esbuild": {
|
||||||
"version": "0.25.0",
|
"version": "0.25.0",
|
||||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.0.tgz",
|
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.0.tgz",
|
||||||
|
|
@ -2820,6 +2932,22 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/form-data": {
|
||||||
|
"version": "4.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.3.tgz",
|
||||||
|
"integrity": "sha512-qsITQPfmvMOSAdeyZ+12I1c+CKSstAFAwu+97zrnWAbIr5u8wfsExUzCesVLC8NgHuRUqNN4Zy6UPWUTRGslcA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"asynckit": "^0.4.0",
|
||||||
|
"combined-stream": "^1.0.8",
|
||||||
|
"es-set-tostringtag": "^2.1.0",
|
||||||
|
"hasown": "^2.0.2",
|
||||||
|
"mime-types": "^2.1.12"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/fs-constants": {
|
"node_modules/fs-constants": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
|
||||||
|
|
@ -2840,6 +2968,52 @@
|
||||||
"node": ">=6 <7 || >=8"
|
"node": ">=6 <7 || >=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/function-bind": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/get-intrinsic": {
|
||||||
|
"version": "1.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
|
||||||
|
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"call-bind-apply-helpers": "^1.0.2",
|
||||||
|
"es-define-property": "^1.0.1",
|
||||||
|
"es-errors": "^1.3.0",
|
||||||
|
"es-object-atoms": "^1.1.1",
|
||||||
|
"function-bind": "^1.1.2",
|
||||||
|
"get-proto": "^1.0.1",
|
||||||
|
"gopd": "^1.2.0",
|
||||||
|
"has-symbols": "^1.1.0",
|
||||||
|
"hasown": "^2.0.2",
|
||||||
|
"math-intrinsics": "^1.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/get-proto": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"dunder-proto": "^1.0.1",
|
||||||
|
"es-object-atoms": "^1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/gifwrap": {
|
"node_modules/gifwrap": {
|
||||||
"version": "0.9.4",
|
"version": "0.9.4",
|
||||||
"resolved": "https://registry.npmjs.org/gifwrap/-/gifwrap-0.9.4.tgz",
|
"resolved": "https://registry.npmjs.org/gifwrap/-/gifwrap-0.9.4.tgz",
|
||||||
|
|
@ -2892,6 +3066,18 @@
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/gopd": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/graceful-fs": {
|
"node_modules/graceful-fs": {
|
||||||
"version": "4.2.11",
|
"version": "4.2.11",
|
||||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
|
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
|
||||||
|
|
@ -2915,6 +3101,56 @@
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/has-symbols": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/has-tostringtag": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"has-symbols": "^1.0.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/hasown": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
|
||||||
|
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"function-bind": "^1.1.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ics": {
|
||||||
|
"version": "3.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ics/-/ics-3.8.1.tgz",
|
||||||
|
"integrity": "sha512-UqQlfkajfhrS4pUGQfGIJMYz/Jsl/ob3LqcfEhUmLbwumg+ZNkU0/6S734Vsjq3/FYNpEcZVKodLBoe+zBM69g==",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"nanoid": "^3.1.23",
|
||||||
|
"runes2": "^1.1.2",
|
||||||
|
"yup": "^1.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/ieee754": {
|
"node_modules/ieee754": {
|
||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
|
||||||
|
|
@ -3225,6 +3461,15 @@
|
||||||
"integrity": "sha512-ThQLOhN86ZkJ7qemtVRGYM+gRgR8GEXNli9H/PMvpnZsE44Xfh3wx9kGJaldg314v85m+bFW6WBMaVHJc/c3zA==",
|
"integrity": "sha512-ThQLOhN86ZkJ7qemtVRGYM+gRgR8GEXNli9H/PMvpnZsE44Xfh3wx9kGJaldg314v85m+bFW6WBMaVHJc/c3zA==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/math-intrinsics": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/merge2": {
|
"node_modules/merge2": {
|
||||||
"version": "1.4.1",
|
"version": "1.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
|
||||||
|
|
@ -3261,6 +3506,27 @@
|
||||||
"node": ">=4"
|
"node": ">=4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/mime-db": {
|
||||||
|
"version": "1.52.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
||||||
|
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/mime-types": {
|
||||||
|
"version": "2.1.35",
|
||||||
|
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
|
||||||
|
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"mime-db": "1.52.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/mimic-response": {
|
"node_modules/mimic-response": {
|
||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
|
||||||
|
|
@ -3321,12 +3587,51 @@
|
||||||
"integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
|
"integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/moment": {
|
||||||
|
"version": "2.30.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz",
|
||||||
|
"integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/moment-timezone": {
|
||||||
|
"version": "0.5.48",
|
||||||
|
"resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.48.tgz",
|
||||||
|
"integrity": "sha512-f22b8LV1gbTO2ms2j2z13MuPogNoh5UzxL3nzNAYKGraILnbGc9NEE6dyiiiLv46DGRb8A4kg8UKWLjPthxBHw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"moment": "^2.29.4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/ms": {
|
"node_modules/ms": {
|
||||||
"version": "2.1.3",
|
"version": "2.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/nanoid": {
|
||||||
|
"version": "3.3.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
|
||||||
|
"integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/ai"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"bin": {
|
||||||
|
"nanoid": "bin/nanoid.cjs"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/napi-build-utils": {
|
"node_modules/napi-build-utils": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz",
|
||||||
|
|
@ -3361,6 +3666,18 @@
|
||||||
"node": ">=6.0.0"
|
"node": ">=6.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/node-ical": {
|
||||||
|
"version": "0.20.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/node-ical/-/node-ical-0.20.1.tgz",
|
||||||
|
"integrity": "sha512-NrXgzDJd6XcyX9kDMJVA3xYCZmntY7ghA2BOdBeYr3iu8tydHOAb+68jPQhF9V2CRQ0/386X05XhmLzQUN0+Hw==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"axios": "^1.7.7",
|
||||||
|
"moment-timezone": "^0.5.45",
|
||||||
|
"rrule": "2.8.1",
|
||||||
|
"uuid": "^10.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/object-path-set": {
|
"node_modules/object-path-set": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/object-path-set/-/object-path-set-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/object-path-set/-/object-path-set-1.0.2.tgz",
|
||||||
|
|
@ -3598,6 +3915,18 @@
|
||||||
"node": ">= 0.6.0"
|
"node": ">= 0.6.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/property-expr": {
|
||||||
|
"version": "2.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.6.tgz",
|
||||||
|
"integrity": "sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/proxy-from-env": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/pump": {
|
"node_modules/pump": {
|
||||||
"version": "3.0.2",
|
"version": "3.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz",
|
||||||
|
|
@ -3757,6 +4086,15 @@
|
||||||
"integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==",
|
"integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/rrule": {
|
||||||
|
"version": "2.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/rrule/-/rrule-2.8.1.tgz",
|
||||||
|
"integrity": "sha512-hM3dHSBMeaJ0Ktp7W38BJZ7O1zOgaFEsn41PDk+yHoEtfLV+PoJt9E9xAlZiWgf/iqEqionN0ebHFZIDAp+iGw==",
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": "^2.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/run-parallel": {
|
"node_modules/run-parallel": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
|
||||||
|
|
@ -3781,6 +4119,12 @@
|
||||||
"queue-microtask": "^1.2.2"
|
"queue-microtask": "^1.2.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/runes2": {
|
||||||
|
"version": "1.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/runes2/-/runes2-1.1.4.tgz",
|
||||||
|
"integrity": "sha512-LNPnEDPOOU4ehF71m5JoQyzT2yxwD6ZreFJ7MxZUAoMKNMY1XrAo60H1CUoX5ncSm0rIuKlqn9JZNRrRkNou2g==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/safe-buffer": {
|
"node_modules/safe-buffer": {
|
||||||
"version": "5.2.1",
|
"version": "5.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||||
|
|
@ -3998,6 +4342,12 @@
|
||||||
"integrity": "sha512-IjZc9KIotudix8bMaBW6QvMuq64BrJWFs1+4V0lXwWGQZwH+LnX87doAYhem4caOEusRP9/g6jVDQmZ8XOk1nw==",
|
"integrity": "sha512-IjZc9KIotudix8bMaBW6QvMuq64BrJWFs1+4V0lXwWGQZwH+LnX87doAYhem4caOEusRP9/g6jVDQmZ8XOk1nw==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/tiny-case": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/tiny-case/-/tiny-case-1.0.3.tgz",
|
||||||
|
"integrity": "sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/tinycolor2": {
|
"node_modules/tinycolor2": {
|
||||||
"version": "1.6.0",
|
"version": "1.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.6.0.tgz",
|
||||||
|
|
@ -4034,6 +4384,12 @@
|
||||||
"url": "https://github.com/sponsors/Borewit"
|
"url": "https://github.com/sponsors/Borewit"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/toposort": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz",
|
||||||
|
"integrity": "sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/ts-api-utils": {
|
"node_modules/ts-api-utils": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz",
|
||||||
|
|
@ -4084,6 +4440,18 @@
|
||||||
"node": ">= 0.8.0"
|
"node": ">= 0.8.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/type-fest": {
|
||||||
|
"version": "2.19.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz",
|
||||||
|
"integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==",
|
||||||
|
"license": "(MIT OR CC0-1.0)",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12.20"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/typescript": {
|
"node_modules/typescript": {
|
||||||
"version": "5.8.3",
|
"version": "5.8.3",
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
|
||||||
|
|
@ -4171,6 +4539,19 @@
|
||||||
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
|
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/uuid": {
|
||||||
|
"version": "10.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz",
|
||||||
|
"integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==",
|
||||||
|
"funding": [
|
||||||
|
"https://github.com/sponsors/broofa",
|
||||||
|
"https://github.com/sponsors/ctavan"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"bin": {
|
||||||
|
"uuid": "dist/bin/uuid"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/which": {
|
"node_modules/which": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||||
|
|
@ -4285,6 +4666,18 @@
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"node_modules/yup": {
|
||||||
|
"version": "1.6.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/yup/-/yup-1.6.1.tgz",
|
||||||
|
"integrity": "sha512-JED8pB50qbA4FOkDol0bYF/p60qSEDQqBD0/qeIrUCG1KbPBIQ776fCUNb9ldbPcSTxA69g/47XTo4TqWiuXOA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"property-expr": "^2.0.5",
|
||||||
|
"tiny-case": "^1.0.3",
|
||||||
|
"toposort": "^2.0.2",
|
||||||
|
"type-fest": "^2.19.0"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,11 @@
|
||||||
"discord.js": "^14.18.0",
|
"discord.js": "^14.18.0",
|
||||||
"dotenv": "^16.4.7",
|
"dotenv": "^16.4.7",
|
||||||
"esbuild": "^0.25.0",
|
"esbuild": "^0.25.0",
|
||||||
|
"ics": "^3.8.1",
|
||||||
"is-plain-object": "^5.0.0",
|
"is-plain-object": "^5.0.0",
|
||||||
"log4js": "^6.9.1",
|
"log4js": "^6.9.1",
|
||||||
"node-cron": "^4.0.7",
|
"node-cron": "^4.0.7",
|
||||||
|
"node-ical": "^0.20.1",
|
||||||
"object-path-set": "^1.0.2",
|
"object-path-set": "^1.0.2",
|
||||||
"svg2img": "^1.0.0-beta.2"
|
"svg2img": "^1.0.0-beta.2"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -5,14 +5,12 @@ export class Container {
|
||||||
|
|
||||||
private instances: Map<string, object> = new Map();
|
private instances: Map<string, object> = new Map();
|
||||||
|
|
||||||
public set<T extends Class>(instance: T, name: string|null = null): void
|
public set<T extends Class>(instance: T, name: string | null = null): void {
|
||||||
{
|
|
||||||
const settingName = name ?? instance.constructor.name;
|
const settingName = name ?? instance.constructor.name;
|
||||||
this.instances.set(settingName.toLowerCase(), instance);
|
this.instances.set(settingName.toLowerCase(), instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
public get<T extends Class>(name: string): T
|
public get<T extends Class>(name: string): T {
|
||||||
{
|
|
||||||
return <T>this.instances.get(name.toLowerCase());
|
return <T>this.instances.get(name.toLowerCase());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -23,6 +21,7 @@ export class Container {
|
||||||
|
|
||||||
return Container.instance;
|
return Container.instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static get<T>(name: string): T {
|
public static get<T>(name: string): T {
|
||||||
return Container.instance.get<T>(name);
|
return Container.instance.get<T>(name);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,9 @@ import {IconCache} from "../Icons/IconCache";
|
||||||
import {EventHandler} from "../Events/EventHandler";
|
import {EventHandler} from "../Events/EventHandler";
|
||||||
import {InteractionRouter} from "../Discord/InteractionRouter";
|
import {InteractionRouter} from "../Discord/InteractionRouter";
|
||||||
import Commands from "../Discord/Commands/Commands";
|
import Commands from "../Discord/Commands/Commands";
|
||||||
|
import {CommandDeployer} from "../Discord/CommandDeployer";
|
||||||
|
import {REST} from "discord.js";
|
||||||
|
import {log} from "node:util";
|
||||||
|
|
||||||
export enum ServiceHint {
|
export enum ServiceHint {
|
||||||
App,
|
App,
|
||||||
|
|
@ -29,9 +32,14 @@ export class Services {
|
||||||
const database = new DatabaseConnection(env.database);
|
const database = new DatabaseConnection(env.database);
|
||||||
container.set<DatabaseConnection>(database);
|
container.set<DatabaseConnection>(database);
|
||||||
|
|
||||||
|
const restClient = new REST();
|
||||||
|
const commands = new Commands();
|
||||||
const discordClient = new DiscordClient(
|
const discordClient = new DiscordClient(
|
||||||
env.discord.clientId,
|
env.discord.clientId,
|
||||||
new InteractionRouter(new Commands(), logger)
|
new InteractionRouter(commands, logger),
|
||||||
|
new CommandDeployer(env.discord.clientId, restClient, commands, logger),
|
||||||
|
logger,
|
||||||
|
restClient
|
||||||
);
|
);
|
||||||
container.set<DiscordClient>(discordClient);
|
container.set<DiscordClient>(discordClient);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ export class DatabaseConnection {
|
||||||
const preparedQuery = this.database.prepare<BindParameters, Result>(query);
|
const preparedQuery = this.database.prepare<BindParameters, Result>(query);
|
||||||
return preparedQuery.get(args);
|
return preparedQuery.get(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
public fetchAll<BindParameters extends unknown[] | {} = unknown[], Result = unknown>(query: string, ...args: unknown[]): Result[] {
|
public fetchAll<BindParameters extends unknown[] | {} = unknown[], Result = unknown>(query: string, ...args: unknown[]): Result[] {
|
||||||
const preparedQuery = this.database.prepare<BindParameters, Result>(query);
|
const preparedQuery = this.database.prepare<BindParameters, Result>(query);
|
||||||
return preparedQuery.all(args);
|
return preparedQuery.all(args);
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,8 @@ import {Container} from "../Container/Container";
|
||||||
import {Logger} from "log4js";
|
import {Logger} from "log4js";
|
||||||
|
|
||||||
export class DatabaseUpdater {
|
export class DatabaseUpdater {
|
||||||
constructor(private readonly database: DatabaseConnection) {}
|
constructor(private readonly database: DatabaseConnection) {
|
||||||
|
}
|
||||||
|
|
||||||
public ensureAvaliablity(definitions: Iterable<DatabaseDefinition>) {
|
public ensureAvaliablity(definitions: Iterable<DatabaseDefinition>) {
|
||||||
for (const definition of definitions) {
|
for (const definition of definitions) {
|
||||||
|
|
@ -75,7 +76,10 @@ export class DatabaseUpdater {
|
||||||
return values.join(' ');
|
return values.join(' ');
|
||||||
}).join(', ');
|
}).join(', ');
|
||||||
|
|
||||||
const sql = `CREATE TABLE IF NOT EXISTS ${definition.name} (${columnsSQL})`;
|
const sql = `CREATE TABLE IF NOT EXISTS ${definition.name}
|
||||||
|
(
|
||||||
|
${columnsSQL}
|
||||||
|
)`;
|
||||||
this.database.execute(sql);
|
this.database.execute(sql);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,36 +1,28 @@
|
||||||
import {DiscordClient} from "./DiscordClient";
|
import {DiscordClient} from "./DiscordClient";
|
||||||
import {Logger} from "log4js";
|
import {Logger} from "log4js";
|
||||||
import {Routes, Snowflake} from "discord.js";
|
import {REST, Routes, Snowflake} from "discord.js";
|
||||||
|
import Commands from "./Commands/Commands";
|
||||||
|
|
||||||
export class CommandDeployer {
|
export class CommandDeployer {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly client: DiscordClient,
|
private readonly applicationId: string,
|
||||||
|
private readonly restClient: REST,
|
||||||
|
private readonly commands: Commands,
|
||||||
private readonly logger: Logger
|
private readonly logger: Logger
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public async deployAvailableServers() {
|
public async deployServer(serverId: Snowflake) {
|
||||||
const commandInfos: object[] = [];
|
const commandInfos = this.commands.getJsonDefinitions();
|
||||||
this.client.Commands.allCommands.forEach((command) => {
|
|
||||||
commandInfos.push(command.definition().toJSON())
|
|
||||||
})
|
|
||||||
|
|
||||||
const guilds = await this.client.RESTClient.get(Routes.userGuilds());
|
this.logger.debug(`Started refreshing ${commandInfos.length} application (/) commands for ${serverId}.`);
|
||||||
const deployments = guilds.map(guild => {
|
|
||||||
return this.deployServer(commandInfos, guild.id)
|
|
||||||
})
|
|
||||||
|
|
||||||
await Promise.all(deployments);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async deployServer(commandInfos: object[], serverId: Snowflake) {
|
|
||||||
this.logger.log(`Started refreshing ${commandInfos.length} application (/) commands for ${serverId}.`);
|
|
||||||
|
|
||||||
// The put method is used to fully refresh all commands in the guild with the current set
|
// The put method is used to fully refresh all commands in the guild with the current set
|
||||||
await this.client.RESTClient.put(
|
await this.restClient.put(
|
||||||
Routes.applicationGuildCommands(this.client.ApplicationId, serverId),
|
Routes.applicationGuildCommands(this.applicationId, serverId),
|
||||||
{body: commandInfos},
|
{body: commandInfos},
|
||||||
);
|
);
|
||||||
this.logger.log(`Successfully reloaded ${commandInfos.length} application (/) commands for ${serverId}.`);
|
|
||||||
|
this.logger.debug(`Successfully reloaded ${commandInfos.length} application (/) commands for ${serverId}.`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2,6 +2,8 @@ import {HelloWorldCommand} from "./HelloWorldCommand";
|
||||||
import {Command, CommandUnion} from "./Command";
|
import {Command, CommandUnion} from "./Command";
|
||||||
import {GroupCommand} from "./Groups";
|
import {GroupCommand} from "./Groups";
|
||||||
import {PlaydatesCommand} from "./Playdates";
|
import {PlaydatesCommand} from "./Playdates";
|
||||||
|
import {RESTPostAPIChatInputApplicationCommandsJSONBody} from "discord.js";
|
||||||
|
import {Nullable} from "../../types/Nullable";
|
||||||
|
|
||||||
const commands: Set<Command> = new Set<Command>([
|
const commands: Set<Command> = new Set<Command>([
|
||||||
new HelloWorldCommand(),
|
new HelloWorldCommand(),
|
||||||
|
|
@ -11,6 +13,7 @@ const commands: Set<Command> = new Set<Command>([
|
||||||
|
|
||||||
export default class Commands {
|
export default class Commands {
|
||||||
private mappedCommands: Map<string, Command> = new Map<string, Command>();
|
private mappedCommands: Map<string, Command> = new Map<string, Command>();
|
||||||
|
private definitions: Nullable<RESTPostAPIChatInputApplicationCommandsJSONBody[]>;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.mappedCommands = this.getMap();
|
this.mappedCommands = this.getMap();
|
||||||
|
|
@ -28,8 +31,19 @@ export default class Commands {
|
||||||
return commands;
|
return commands;
|
||||||
}
|
}
|
||||||
|
|
||||||
private getMap(): Map<string, Command>
|
public getJsonDefinitions(): RESTPostAPIChatInputApplicationCommandsJSONBody[] {
|
||||||
{
|
if (this.definitions) {
|
||||||
|
return this.definitions;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.definitions = [];
|
||||||
|
commands.forEach((command) => {
|
||||||
|
this.definitions?.push(command.definition().toJSON())
|
||||||
|
})
|
||||||
|
return this.definitions;
|
||||||
|
}
|
||||||
|
|
||||||
|
private getMap(): Map<string, Command> {
|
||||||
const map = new Map<string, Command>();
|
const map = new Map<string, Command>();
|
||||||
for (const command of commands) {
|
for (const command of commands) {
|
||||||
const definition = command.definition()
|
const definition = command.definition()
|
||||||
|
|
|
||||||
|
|
@ -10,12 +10,12 @@ export class HelloWorldCommand implements Command {
|
||||||
'Hello :) How are you?',
|
'Hello :) How are you?',
|
||||||
]
|
]
|
||||||
|
|
||||||
definition(): SlashCommandBuilder
|
definition(): SlashCommandBuilder {
|
||||||
{
|
|
||||||
return new SlashCommandBuilder()
|
return new SlashCommandBuilder()
|
||||||
.setName("hello")
|
.setName("hello")
|
||||||
.setDescription("Displays a random response. (commonly used to test if the bot is online)")
|
.setDescription("Displays a random response. (commonly used to test if the bot is online)")
|
||||||
}
|
}
|
||||||
|
|
||||||
async execute(interaction: CommandInteraction): Promise<void> {
|
async execute(interaction: CommandInteraction): Promise<void> {
|
||||||
const random = Math.floor(Math.random() * HelloWorldCommand.RESPONSES.length);
|
const random = Math.floor(Math.random() * HelloWorldCommand.RESPONSES.length);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import {
|
||||||
SlashCommandBuilder,
|
SlashCommandBuilder,
|
||||||
CommandInteraction,
|
CommandInteraction,
|
||||||
AutocompleteInteraction,
|
AutocompleteInteraction,
|
||||||
EmbedBuilder, MessageFlags, ChatInputCommandInteraction, time
|
EmbedBuilder, MessageFlags, ChatInputCommandInteraction, time, AttachmentBuilder, ActivityFlagsBitField, Options
|
||||||
} from "discord.js";
|
} from "discord.js";
|
||||||
import {AutocompleteCommand, ChatInteractionCommand, Command} from "./Command";
|
import {AutocompleteCommand, ChatInteractionCommand, Command} from "./Command";
|
||||||
import {Container} from "../../Container/Container";
|
import {Container} from "../../Container/Container";
|
||||||
|
|
@ -11,12 +11,10 @@ import {UserError} from "../UserError";
|
||||||
import {PlaydateModel} from "../../Models/PlaydateModel";
|
import {PlaydateModel} from "../../Models/PlaydateModel";
|
||||||
import {PlaydateRepository} from "../../Repositories/PlaydateRepository";
|
import {PlaydateRepository} from "../../Repositories/PlaydateRepository";
|
||||||
import {GroupModel} from "../../Models/GroupModel";
|
import {GroupModel} from "../../Models/GroupModel";
|
||||||
|
import * as ics from 'ics';
|
||||||
|
import ical from 'node-ical';
|
||||||
|
|
||||||
export class PlaydatesCommand implements Command, AutocompleteCommand, ChatInteractionCommand {
|
export class PlaydatesCommand implements Command, AutocompleteCommand, ChatInteractionCommand {
|
||||||
static REGEX = [
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
definition(): SlashCommandBuilder {
|
definition(): SlashCommandBuilder {
|
||||||
// @ts-expect-error Command builder is improperly marked as incomplete.
|
// @ts-expect-error Command builder is improperly marked as incomplete.
|
||||||
return new SlashCommandBuilder()
|
return new SlashCommandBuilder()
|
||||||
|
|
@ -50,6 +48,30 @@ export class PlaydatesCommand implements Command, AutocompleteCommand, ChatInter
|
||||||
.setRequired(true)
|
.setRequired(true)
|
||||||
.setAutocomplete(true)
|
.setAutocomplete(true)
|
||||||
)
|
)
|
||||||
|
)
|
||||||
|
.addSubcommand(subcommand => subcommand
|
||||||
|
.setName('import')
|
||||||
|
.setDescription("Imports playdates from iCal files")
|
||||||
|
.addIntegerOption(GroupSelection.createOptionSetup())
|
||||||
|
.addAttachmentOption(attachment => attachment
|
||||||
|
.setName("file")
|
||||||
|
.setDescription("The iCal File to import")
|
||||||
|
.setRequired(true)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.addSubcommand((subcommand) => subcommand
|
||||||
|
.setName("export")
|
||||||
|
.setDescription("Exports a playdate as iCal file.")
|
||||||
|
.addIntegerOption(GroupSelection.createOptionSetup())
|
||||||
|
.addIntegerOption((option) => option
|
||||||
|
.setName("playdate")
|
||||||
|
.setDescription("Selects a playdate to export")
|
||||||
|
.setAutocomplete(true)
|
||||||
|
)
|
||||||
|
.addBooleanOption(option => option
|
||||||
|
.setName("future-dates")
|
||||||
|
.setDescription("Exports the next playdates as a ical file")
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -66,6 +88,12 @@ export class PlaydatesCommand implements Command, AutocompleteCommand, ChatInter
|
||||||
case "list":
|
case "list":
|
||||||
await this.list(interaction, group);
|
await this.list(interaction, group);
|
||||||
break;
|
break;
|
||||||
|
case "import":
|
||||||
|
await this.import(interaction, group);
|
||||||
|
break;
|
||||||
|
case "export":
|
||||||
|
await this.export(interaction, group);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new UserError("This subcommand is not yet implemented.");
|
throw new UserError("This subcommand is not yet implemented.");
|
||||||
}
|
}
|
||||||
|
|
@ -139,7 +167,7 @@ export class PlaydatesCommand implements Command, AutocompleteCommand, ChatInter
|
||||||
playdates.map(playdate => {
|
playdates.map(playdate => {
|
||||||
return {
|
return {
|
||||||
name: `${playdate.from_time.toLocaleString()} - ${playdate.to_time.toLocaleString()}`,
|
name: `${playdate.from_time.toLocaleString()} - ${playdate.to_time.toLocaleString()}`,
|
||||||
value: playdate.id
|
value: <number>playdate.id
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
@ -151,8 +179,7 @@ export class PlaydatesCommand implements Command, AutocompleteCommand, ChatInter
|
||||||
const embed = new EmbedBuilder()
|
const embed = new EmbedBuilder()
|
||||||
.setTitle("The next playdates:")
|
.setTitle("The next playdates:")
|
||||||
.setFields(
|
.setFields(
|
||||||
playdates.map((playdate) =>
|
playdates.map((playdate) => {
|
||||||
{
|
|
||||||
return {
|
return {
|
||||||
name: `${time(playdate.from_time, 'F')} - ${time(playdate.to_time, 'F')}`,
|
name: `${time(playdate.from_time, 'F')} - ${time(playdate.to_time, 'F')}`,
|
||||||
value: `${time(playdate.from_time, 'R')}`
|
value: `${time(playdate.from_time, 'R')}`
|
||||||
|
|
@ -202,4 +229,107 @@ export class PlaydatesCommand implements Command, AutocompleteCommand, ChatInter
|
||||||
flags: MessageFlags.Ephemeral,
|
flags: MessageFlags.Ephemeral,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async import(interaction: ChatInputCommandInteraction, group: GroupModel): Promise<void> {
|
||||||
|
const file = interaction.options.getAttachment('file', true);
|
||||||
|
const mimeType = file.contentType?.split(';')[0];
|
||||||
|
if (mimeType !== "text/calendar") {
|
||||||
|
throw new UserError(`Invalid ical file. Got: ${mimeType}`, "Providing a valid iCal file");
|
||||||
|
}
|
||||||
|
|
||||||
|
await interaction.deferReply({
|
||||||
|
flags: MessageFlags.Ephemeral
|
||||||
|
});
|
||||||
|
|
||||||
|
const playdateRepo = Container.get<PlaydateRepository>(PlaydateRepository.name);
|
||||||
|
|
||||||
|
const icalFile = await ical.async.fromURL(file.url);
|
||||||
|
const playdates: PlaydateModel[] = [];
|
||||||
|
for (const event of Object.values(icalFile)) {
|
||||||
|
if (event.type !== 'VEVENT') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const playdate: Partial<PlaydateModel> = {
|
||||||
|
group: group,
|
||||||
|
from_time: event.start,
|
||||||
|
to_time: event.end
|
||||||
|
}
|
||||||
|
|
||||||
|
const id = playdateRepo.create(playdate);
|
||||||
|
playdates.push(<PlaydateModel>{
|
||||||
|
id,
|
||||||
|
...playdate
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setTitle("Imported play-dates.")
|
||||||
|
.setDescription(`:white_check_mark: Your ${playdates.length} playdates has been created! You and your group get notified, when its time.`)
|
||||||
|
.setFields({
|
||||||
|
name: "Created playdates",
|
||||||
|
value: playdates.map((playdate) => `${time(playdate.from_time, 'F')} - ${time(playdate.to_time, 'F')}`).join('\n')
|
||||||
|
})
|
||||||
|
.setFooter({
|
||||||
|
text: `Group: ${group.name}`
|
||||||
|
})
|
||||||
|
|
||||||
|
interaction.followUp({
|
||||||
|
embeds: [embed],
|
||||||
|
flags: MessageFlags.Ephemeral
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private async export(interaction: ChatInputCommandInteraction, group: GroupModel): Promise<void> {
|
||||||
|
const playdates = this.getExportTargets(interaction, group);
|
||||||
|
|
||||||
|
const result = ics.createEvents(
|
||||||
|
playdates.map((playdate) => {
|
||||||
|
return {
|
||||||
|
start: ics.convertTimestampToArray(playdate.from_time.getTime(), ''),
|
||||||
|
startInputType: 'utc',
|
||||||
|
startOutputType: 'utc',
|
||||||
|
end: ics.convertTimestampToArray(playdate.to_time.getTime(), ''),
|
||||||
|
endInputType: 'utc',
|
||||||
|
endOutputType: 'utc',
|
||||||
|
title: `PnP with ${group.name}`,
|
||||||
|
status: "CONFIRMED",
|
||||||
|
busyStatus: "FREE",
|
||||||
|
categories: ['PnP']
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
if (!result.value) {
|
||||||
|
throw new Error("Failed creating ics file...")
|
||||||
|
}
|
||||||
|
const attachment = new AttachmentBuilder(Buffer.from(result.value), {
|
||||||
|
name: "ICSExport.ics",
|
||||||
|
description: "Your export :)"
|
||||||
|
});
|
||||||
|
interaction.reply({
|
||||||
|
files: [attachment],
|
||||||
|
flags: MessageFlags.Ephemeral
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private getExportTargets(interaction: ChatInputCommandInteraction, group: GroupModel): PlaydateModel[] {
|
||||||
|
|
||||||
|
const repo = Container.get<PlaydateRepository>(PlaydateRepository.name);
|
||||||
|
const nextPlaydates = interaction.options.getBoolean("future-dates") ?? false;
|
||||||
|
if (nextPlaydates) {
|
||||||
|
return repo.findPlaydatesInRange(new Date());
|
||||||
|
}
|
||||||
|
|
||||||
|
const playdateId = interaction.options.getInteger('playdate');
|
||||||
|
if (!playdateId) {
|
||||||
|
throw new UserError("Nothing to export", "Please specify what you want to export.");
|
||||||
|
}
|
||||||
|
|
||||||
|
const playdate = repo.getById(playdateId);
|
||||||
|
if (!playdate) {
|
||||||
|
throw new UserError("Specified playdate id is invalid");
|
||||||
|
}
|
||||||
|
|
||||||
|
return [playdate];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -8,6 +8,7 @@ import Commands from "./Commands/Commands";
|
||||||
import {Container} from "../Container/Container";
|
import {Container} from "../Container/Container";
|
||||||
import {Logger} from "log4js";
|
import {Logger} from "log4js";
|
||||||
import {InteractionRouter} from "./InteractionRouter";
|
import {InteractionRouter} from "./InteractionRouter";
|
||||||
|
import {CommandDeployer} from "./CommandDeployer";
|
||||||
|
|
||||||
export class DiscordClient {
|
export class DiscordClient {
|
||||||
private readonly client: Client;
|
private readonly client: Client;
|
||||||
|
|
@ -31,6 +32,8 @@ export class DiscordClient {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly applicationId: string,
|
private readonly applicationId: string,
|
||||||
private readonly router: InteractionRouter,
|
private readonly router: InteractionRouter,
|
||||||
|
private readonly deployer: CommandDeployer,
|
||||||
|
private readonly logger: Logger,
|
||||||
private readonly restClient: REST = new REST()
|
private readonly restClient: REST = new REST()
|
||||||
) {
|
) {
|
||||||
this.client = new Client({
|
this.client = new Client({
|
||||||
|
|
@ -44,14 +47,21 @@ export class DiscordClient {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Container.get<Logger>("logger").info(`Ready! Logged in as ${this.client.user.tag}`);
|
this.logger.info(`Ready! Logged in as ${this.client.user.tag}`);
|
||||||
this.client.user.setActivity('your PnP playdates', {
|
this.client.user.setActivity('your PnP playdates', {
|
||||||
type: ActivityType.Watching,
|
type: ActivityType.Watching,
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
this.client.on(Events.GuildAvailable, () => {
|
this.client.on(Events.GuildCreate, (guild) => {
|
||||||
Container.get<Logger>("logger").info("Joined Guild?")
|
this.logger.info(`Joined ${guild.name}`);
|
||||||
|
this.deployer.deployServer(guild.id);
|
||||||
|
})
|
||||||
|
this.client.on(Events.GuildDelete, (guild) => {
|
||||||
|
this.logger.info(`Left ${guild.name}`);
|
||||||
|
})
|
||||||
|
this.client.on(Events.GuildAvailable, (guild) => {
|
||||||
|
this.deployer.deployServer(guild.id);
|
||||||
})
|
})
|
||||||
|
|
||||||
this.client.on(Events.InteractionCreate, this.router.route.bind(this.router));
|
this.client.on(Events.InteractionCreate, this.router.route.bind(this.router));
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,8 @@ export class GroupConfigurationHandler {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly repository: GroupConfigurationRepository,
|
private readonly repository: GroupConfigurationRepository,
|
||||||
private readonly group: GroupModel
|
private readonly group: GroupModel
|
||||||
) { }
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public saveConfiguration(path: string, value: string): void {
|
public saveConfiguration(path: string, value: string): void {
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,8 @@ export class GroupConfigurationRenderer {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly configurationHandler: GroupConfigurationHandler,
|
private readonly configurationHandler: GroupConfigurationHandler,
|
||||||
private readonly transformers: GroupConfigurationTransformers,
|
private readonly transformers: GroupConfigurationTransformers,
|
||||||
) {}
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
public async setup(interaction: ChatInputCommandInteraction) {
|
public async setup(interaction: ChatInputCommandInteraction) {
|
||||||
let response = await interaction.reply(this.getReplyOptions());
|
let response = await interaction.reply(this.getReplyOptions());
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,8 @@ export class IconDeployer {
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private readonly iconCache: IconCache
|
private readonly iconCache: IconCache
|
||||||
) {}
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
public async ensureExistance() {
|
public async ensureExistance() {
|
||||||
const directory = await fs.promises.opendir(IconDeployer.ICON_PATH);
|
const directory = await fs.promises.opendir(IconDeployer.ICON_PATH);
|
||||||
|
|
|
||||||
0
source/Menu/MenuRenderer.ts
Normal file
0
source/Menu/MenuRenderer.ts
Normal file
|
|
@ -1,3 +1,3 @@
|
||||||
export interface Model {
|
export interface Model {
|
||||||
id: number;
|
id: number | bigint;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,8 @@ export class PlaydateRepository extends Repository<PlaydateModel, DBPlaydate> {
|
||||||
|
|
||||||
return finds.map((playdate) => this.convertToModelType(playdate, group));
|
return finds.map((playdate) => this.convertToModelType(playdate, group));
|
||||||
}
|
}
|
||||||
findPlaydatesInRange(fromDate: Date|number, toDate: Date|number, group: GroupModel | undefined = undefined) {
|
|
||||||
|
findPlaydatesInRange(fromDate: Date | number, toDate: Date | number | undefined = undefined, group: GroupModel | undefined = undefined) {
|
||||||
if (fromDate instanceof Date) {
|
if (fromDate instanceof Date) {
|
||||||
fromDate = fromDate.getTime();
|
fromDate = fromDate.getTime();
|
||||||
}
|
}
|
||||||
|
|
@ -42,12 +43,17 @@ export class PlaydateRepository extends Repository<PlaydateModel, DBPlaydate> {
|
||||||
toDate = toDate.getTime();
|
toDate = toDate.getTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
let sql = `SELECT * FROM ${this.schema.name} WHERE time_from > ? AND time_from < ?`;
|
let sql = `SELECT * FROM ${this.schema.name} WHERE time_from > ?`;
|
||||||
const params = [fromDate, toDate];
|
const params = [fromDate];
|
||||||
|
|
||||||
|
if (toDate) {
|
||||||
|
sql = `${sql} AND time_from < ?`
|
||||||
|
params.push(toDate);
|
||||||
|
}
|
||||||
|
|
||||||
if (group) {
|
if (group) {
|
||||||
sql = `${sql} AND groupid = ?`
|
sql = `${sql} AND groupid = ?`
|
||||||
params.push(group.id)
|
params.push(<number>group.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
const finds = this.database.fetchAll<number, DBPlaydate>(
|
const finds = this.database.fetchAll<number, DBPlaydate>(
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,8 @@ export class Repository<ModelType extends Model, IntermediateModelType = unknown
|
||||||
constructor(
|
constructor(
|
||||||
protected readonly database: DatabaseConnection,
|
protected readonly database: DatabaseConnection,
|
||||||
public readonly schema: DatabaseDefinition,
|
public readonly schema: DatabaseDefinition,
|
||||||
) {}
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
public create(instance: Partial<ModelType>): number | bigint {
|
public create(instance: Partial<ModelType>): number | bigint {
|
||||||
const columnNames = this.schema.columns.filter((column) => {
|
const columnNames = this.schema.columns.filter((column) => {
|
||||||
|
|
@ -77,6 +78,7 @@ export class Repository<ModelType extends Model, IntermediateModelType = unknown
|
||||||
protected convertToModelType(intermediateModel: IntermediateModelType | undefined): ModelType {
|
protected convertToModelType(intermediateModel: IntermediateModelType | undefined): ModelType {
|
||||||
return intermediateModel as unknown as ModelType;
|
return intermediateModel as unknown as ModelType;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected convertToCreateObject(instance: Partial<ModelType>): object {
|
protected convertToCreateObject(instance: Partial<ModelType>): object {
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,14 +21,6 @@ const logger = container.get<Logger>("logger");
|
||||||
const client = container.get<DiscordClient>(DiscordClient.name);
|
const client = container.get<DiscordClient>(DiscordClient.name);
|
||||||
client.connectRESTClient(environment.discord.token)
|
client.connectRESTClient(environment.discord.token)
|
||||||
|
|
||||||
logger.log("Deploying Commands...")
|
|
||||||
|
|
||||||
const deployer = new CommandDeployer(client, logger);
|
|
||||||
(async () => {
|
|
||||||
await deployer.deployAvailableServers()
|
|
||||||
})()
|
|
||||||
|
|
||||||
|
|
||||||
logger.log("Ensuring Database...");
|
logger.log("Ensuring Database...");
|
||||||
const updater = new DatabaseUpdater(container.get<DatabaseConnection>(DatabaseConnection.name));
|
const updater = new DatabaseUpdater(container.get<DatabaseConnection>(DatabaseConnection.name));
|
||||||
updater.ensureAvaliablity(Definitions);
|
updater.ensureAvaliablity(Definitions);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue