Intiial commit
This commit is contained in:
30
.env.development
Normal file
30
.env.development
Normal file
@@ -0,0 +1,30 @@
|
||||
#/-------------------[DOTENV_PUBLIC_KEY]--------------------/
|
||||
#/ public-key encryption for .env files /
|
||||
#/ [how it works](https://dotenvx.com/encryption) /
|
||||
#/----------------------------------------------------------/
|
||||
DOTENV_PUBLIC_KEY_DEVELOPMENT="02572da3d4f3a844588a944214c0e142a5a01deaa6551456af146d34b574024416"
|
||||
|
||||
# .env.development
|
||||
#/-------------------[DOTENV_PUBLIC_KEY]--------------------/
|
||||
#/ public-key encryption for .env files /
|
||||
#/ [how it works](https://dotenvx.com/encryption) /
|
||||
#/----------------------------------------------------------/
|
||||
DOTENV_PUBLIC_KEY="02292a330aa041b5f7efc51504e0c208accba67a6877a217ab43cbb59c3c0c3e66"
|
||||
|
||||
# .env
|
||||
DISCORD_BOT_TOKEN="encrypted:BHWtrKfWm5sdv5MwMVnvwaqsgGlUXQ35/Dxhu+6NqWSdwa0pesu8EmXMZr64fLXEMzsSpbH0rDTj3NUe64jbGyxL2f9LRbMWExj8o7rz9qeM2vdXCBAiOWPYOqLiqqhKvBRvpGuFCZlMeA7dsLxr0t4RPzPbAAUINaLKMmyxTVRsLJO7NVcMK5u/0FczmjoLkz2+woka9RcVZoL2XRMfWM4uLKm8WMrccg=="
|
||||
DEBUG="encrypted:BFqmdpn+2mZ4wU0KT5qhlRJ6J/TMKqhDjiCGEYIdOM9O8CBaSRO5dAduODmr3k/PR3/L9ruk81q0Na4DR0JnnArNB9+mUP9tUkCC/KKBWkQJenwaUpxxZ/Xs1WbTmKCiquTWRVE="
|
||||
PORT="encrypted:BB7uSrGyN0EL1gv/JLl9ltjadMqLLnKg7p6XAS1z96Qt1z+/KuwQ8EQ4BQY+dx19Q4H443vtIWmNSLPWTbZI1Swj6xBwirZ8VmitlnazSYxotkz2nq2sdvALQH5mQlj0iZ0NHLQ="
|
||||
NODE_ENV="encrypted:BFCK2qYG9T55sxJPTGx+xqeGCFx2EPSvnzwX5PM8CoHGmN+6X5Irj1/PZ9m1QbFtQAibDj0CH/i1yHQQ9he4vN0RUqq7uGXsIbSsApvRYSKPaIdi7DKOhMwYRMCd1a4CjHemt2w1n1BizUxf"
|
||||
LOG_LEVEL="encrypted:BFYODyDKQ+uvLGCOk7eZQ8uZJdfI4iy/wUJeC2rNGHJYxIK/2icQ3LvV04DlD8a75kg5zUKC951U0nqT/8vmlp3BCso7CYvOAXISggfMBwFXIaBh2UrDHGOIWDMQWPqjcziCnucj"
|
||||
BASE_URL="encrypted:BNJ+cwBs/2His4iT0aPhsTgxTqkOH28DNsZZ1ctf/Ru4TCr4Q28d9jE/5KSkBlYpWOBItRJ/PK28uJVSdwFuPiCPrpycniLccWS3GvcQFXrMLsfvc9Jo0PoXAFtpmbivlDa7rK6Zhe2y7/16V112hXdeWDGFWlYO9N/iQQM2Vg=="
|
||||
EVE_CLIENT_ID="encrypted:BFv8tNHSS6tb8cWDpnhfC393UcKJZsRgvBTbx4l36+lN3m3oSNmouzRa/KPIXglqkAujt+OyzTyxQ59XxaQ/+ORi6nPNVMr7xDsWwpp24iz509qReOKlTqwk4y2PQ7xVbMskJD65GTg2ZyRwtqc0klBjvvF9frDzlitRpUiL06cS"
|
||||
EVE_CLIENT_SECRET="encrypted:BJIPWclcu2Ok/PQSI8evLfxP7Ze3ULQGoluCCjTQORfzqb8IixKty6lpQurFmt6ez4p1rlf8s73zRjaI6jYKrnPhZ+4sFYfgrCCZUUObsVctFoR7REvYYXD/k/mr5ryRCkR1L7NWihPyQ9fgNViWb+sQPtayf+WrArbqxYRRI5vDD2MMEbakxRCEpg=="
|
||||
EVE_CALLBACK_URL="encrypted:BGiF/m1Zd3jL4Q/p58mE9XUIGoL+Cc7wpxX6PHKt5L0uSat6X74pXC11y0IcO77jSKmpcQ1Zj/pXMz3YLCbHK7toqucZlvTatvka+ad0YAylrLwUBCYeamHmi2CU17qJSPqD9E6Q33yTvqFqf3zBiyZfI8L/PbH9+ok7e8RP+L4xsQ8Jx3piFjS0lFmOC3iznw=="
|
||||
ESI_USER_AGENT="encrypted:BO8zPPwVUKscBZzw8RcePwvuWkYjdCgz9vGrvhFzNJNCNthij3rhN7F5hK1UGPl6RPLOssV1Ke681e6rjldFdi3S1BxWeKQo8QOdjkyHTjmGbOdHoDd6QesMIsx+K9bwJvPl+XFhh+LPnIDzRPEQnTmGOTbvMsxGW9IkJDrm0Oq/aNdO6Blyh4GKzMyW2elgt+s+39/UT5nD2FCe5MlMdLk1/2z8lVV363MfZP1k8qUrbKAvdnZOLJWoWG6Nlg0vDg=="
|
||||
JANICE_KEY="encrypted:BPTKebIZjiHeXHafRCIi7fX2DVYPz5ZwIpPX2GtINQEfrI7DYHhG2NMsxlLaiSFmaGcYA7GAK0DGXt9yTJpIGUBkg73bTE1Pbh1DgtVbpK74xFDbfA7748toAWypDz0B+erh6k6hzz7TywMe+fc80r+OWmQkTpz5pgwg7LaqmT0x"
|
||||
PERPLEXITY_API_KEY="encrypted:BOzm0zV+Nl0sHq9KvoazlqbpgFwj8Gy2crn64Qw5+t4X51OWi1HbCPR82hxuH3CDRKJyuTQMG06s0Z6ovV0N3kMheFlX9qK0SogYympxtVcPd8723IWy6Nr1IioNcajfNW4S38ruRhcrmU4/8rddpyEiWMPB8/Ewb6ycfrnfWHvul4ZqBg6H60IbLDxOQ6AZPWZjRAEy"
|
||||
STAR_KITTEN_KV_DB_PATH="encrypted:BKCUDzngHkpO2Dtqzh++hCsEAAzWfabiF/NdtnP1BzwSN84Y2I+PjUp4mdAiDgPrUWgi3BFS74kZtsutzEF3h3rNi/doKZyOU1cY1DY6aBbQ+WVWPKDiAcENU1GgUp8sUezJNbZ7GXI3Qhnpkz4i"
|
||||
SCOPES=encrypted:BNLqmvLSqQFAMExxaGcx9zUWErl/UO+cbQXOYeQVDgR9JJyo1D8aaPfy06uQDlR+Euv3hy/1NL6tx75KMVChR2p+2fhVcKEC43fx3rt1JxuOvoWck81r6kv/yu5v+YUkw1BVcQNvNp4iiqqOifrro1bylyZkOML6D1DYu7Ns+6srYI4MbJGTDacV6eyRFnGcPdbxCyIophCDEP2iXw==
|
||||
CONCIERGE_DB_PATH="encrypted:BD4/iLtpn7+sqAm/Lm9CSA6ur1AjEZRaYCSy/Z9qCZMPCtoPIeHfCjYs+s+A9PBCxezqJikxbMS8IPhR0EKWQTDzeBsjHRpWGA9mJGKuUYBDtGySH+WQG6+3TEEMU/uqwpLwEUtaULKF9khJdnHlyr5znz5gSw=="
|
||||
ADMIN_USER_ID="encrypted:BFM6XD3HUmF0to4PO8RlGG71OF5aDoV4N3E34/HGwV8Rq4NiIJ+wtxLag8tWjaeIYkTgbknlE8GHiXmJUJMc8eEVhIxNFCC0xmlSJe2NipTLSBbTilfSQPOexURnNXE2I/u+3+il2QvGP7ziReuNM5QiWQ=="
|
||||
23
.env.production
Normal file
23
.env.production
Normal file
@@ -0,0 +1,23 @@
|
||||
#/-------------------[DOTENV_PUBLIC_KEY]--------------------/
|
||||
#/ public-key encryption for .env files /
|
||||
#/ [how it works](https://dotenvx.com/encryption) /
|
||||
#/----------------------------------------------------------/
|
||||
DOTENV_PUBLIC_KEY_PRODUCTION="02f0469506f6722d8fcc179c199ff159ca32f082000c8e7a1465891adb50a4c031"
|
||||
|
||||
# .env.production
|
||||
DEBUG="encrypted:BK1CLEV0fBG5FnYN581CvgIftBf431wzAqxR6CTQdkpY/FSbLpNtm+7sBCD8pdfOGzqlWO6Vp0WPkd56kSYgFSWyChBiWipUIou6lva/1mzIPW0v/s53azEdPlo2k3VpxVcVSWC8"
|
||||
PORT="encrypted:BIxJSVnlk4yf4r5Yrs3emdnRwO2MuH3YS8cRedHKOpTWtwmxFUyRpr7Psn8McOqhVX1pznNrqbnP8LYAjfmuesYZeon8khD0D2OXepb53J3y+7jf5uoOsNOgTHobH3B/djqKEzY="
|
||||
NODE_ENV="encrypted:BGwvbXEi7Zx49wiBZNE+05VHntm/2zIM3mCQE31J4sthkvW3q5KRR5gPmjyzkzN02juqWC/6lCF6ar73nsIwLzDKZabZiYCxEMcn3B/QYPQ1AiTguu8lVPZWTEdRA2S6kFsiKoV9Rfokry8="
|
||||
LOG_LEVEL="encrypted:BPyfUBe3+m9DP+S48GN9QUNedicrn0ICcUYzQeSfBO25NU60lGRLfyx+iPY1Cn3UmH6izR4V+fJ9UedowHRQYrivAzhk2GUa8p4wbld9HXp2kyo3jZpQXzzUOGtf1cWRSdGr0r4="
|
||||
BASE_URL="encrypted:BAHgrTREjKsjKJCogVttpFTOV84iKFzz8+NAtW9+FEDyZlZPixPYoDYRg2qG+7aOs/YNK7GaxpE6gGyV5EIit9l3V8Fb+p157Ra4tdEevF4xmNZcjnjB6GN2fGDNtTddFwMl71X2NcopxwV5auMhQdC14hk9UIkO"
|
||||
DISCORD_APP_ID="encrypted:BJE5LiHHvSEbz500t8+cew4UPf7khvKKFYy5rlfXeTKahQ/eM94e7MDO3nxMZqnlQ9OO0Ge7N3yOvJEb5x/hKlhqwLJo9sKbVHWS6bKnH9/Ft64rcN+g4pSZJeQBG1jFg/zyPJQq4tVyg7C4htnqQU4TiEI="
|
||||
DISCORD_APP_SECRET="encrypted:BGPATPBLvmFcnZSlyUSkT4hrnM4cH56f92/kQgOHDN+5XvSYq5RFyu0soM6Q6/0wCLb92sdVfKbc5x//84k/im245OCmpsKc7RCMoJNlJ/72uEsFQEADxglYrpevy1gVMI7Rs621gEfaVuoJn5AcQDwpX685ydnlr6Ev0vRtzfLD"
|
||||
DISCORD_PUBLIC_KEY="encrypted:BF3QEgKgm86nnO5LegRHlo/Jr/PNpBoY1BMFNgCJ4LdHTw+XkF//JISwQWxaU0aswwYa4duMSUYjc9DMs/mc1yLpf1DZ2R58X86vTcjCX0SiTiLFhYOpQf0JA+3HfIB/4j7GzM1D99DNK8ZsnzY/YXzHAc+R4aRwl1uu8AlGgtZpv7kgu0QjTNJshz9TUoGUROwbUD7RZABZwom0PYW2Wbw="
|
||||
DISCORD_BOT_TOKEN="encrypted:BMGsG954WBMxPgMgeJX5B9FZmJk4oPrGkDJXPaOfXnqkrOaaSP8Oq2tD+m2Pzfwbkla3xoWp2a3863lumgIsOcjoyFT0jj51tyC7CL9pbLmhLqOmnUwGjl9Vv8MHA369WUFwqm0Sum7bUD4HnMrc5Q+qEKF8zut96hTYmZWn6ACqmoxHqxEp9393NFeUzXUD5tdUhkFCYkxFGvBoy1l/EX7x0aSCkB1iiQ=="
|
||||
EVE_CLIENT_ID="encrypted:BK738Cb0M9aVcW49g7MR9YjjyLXn/if25nCjEBVoT5/+9y6seI2BwxsnXIidQ2253NyuZLzJCf8ual+HN5ouwO4r4ckqKYnk7SwDqj6yTuB47yAqgJDi8SnVManX+oRz6URNiSD7eUTYFxPHfC5XdCYFjMOtGDvLndEbqOiKSvGT"
|
||||
EVE_CLIENT_SECRET="encrypted:BBZdQ+o77YtfV/ic+dfx9nORoFs8iIRwQxToUN65I310uhwMeBWbgjJFu3P1pkR5niHxjkQkyBmEWCBKFNsmNZh/zHyjMpXu5ORIsTpDc45ivu96Cuw5PbtnD+3DwAIdJQIjQR9ufYMIdI6DsrEscJg/XX7Yqk703g0s5e4ODm+jDVlLS6maRW8="
|
||||
EVE_CALLBACK_URL="encrypted:BHrxPwPrv8WoHYPZI7nKyJCnggzxBS4JZKxoWXOKa70fglSvAuujGLWktt1LppJ2qvm8uU+J2qltJq0xCwFjzWB/qkRCQ4mK1tLc+cEh9S9mwKXK+55xntl/cxvfUvNt3dyHTL6Bwtxb1UfUxAkMtvPjtDfFKtJxtZBuXnk4Wv72SHZuGmUCp/Yd"
|
||||
ESI_USER_AGENT="encrypted:BN2TE5wokSxMPBgfek0sxyg3sJHTdTm7vPYnMoyqAux93SzvH06wJ+8sVOLo9dmzHbKzSBn1rVNkoLiZV+fvvbrXMrTGL6Ai2jDzrFoIFTHOU9QNL2dk9LmklgmILhy/RPD5ZJlyFHFPffK9laBVws2aOMepoCgq0wPws5dKEd7SYw8jg/wtmw3EYb68wVghzpdnKIpYRqJAlduDfCJv9FRe5J7XFsZxhVxQSSc="
|
||||
AUTH_DB_PATH="encrypted:BM9HDaWwoYJZrHIQtT2FCMQou8NPbom55bvnNdE916P20UlpDHLkopypRxrnFYn6+ufJVanOl6/1AiD7gHqUP/GfT9mrnnXT8qU9XT43hVtyr+N91t6r4fQkgEs31mFnzrCEvOO8VHx+Ps4Kn3tkhdgnoC798OZv"
|
||||
JANICE_KEY="encrypted:BLrwoFguAtfDtopwRBkaM129x3kq8HLYDHddiNLV8unvaJPXPUHOzL+MySnK0lH2s43f1nqx759C2wT/95PHsU8mk29DUT2FbhwDCtqBccrjTZHJdXNZrzEXhyVUAdgoHdyyGugu/xwhaVqKYyTZJNCviceDcW4c/3iBiRBXpan8"
|
||||
PERPLEXITY_API_KEY="encrypted:BMMVGTrkVOeh5a/iP9dIUMRXmcf0gIhj+KUQeyz4Cm0nKbAS/obENMn24NqmBRQtU/4M5Xj1lIpqV+C5MsBmdY/LW/9LX0z1okvaPRKjrudRyj24Mmj0HZLm+RCv0VTYBL2Yx4dszYCYkxBAEihDR/eQfGIMU7KoRNjMot0uF8BonC6fzSIWI0iwxsRm2k3ZAo/MoaRB"
|
||||
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
dist
|
||||
node_modules
|
||||
data
|
||||
.env.keys
|
||||
packages/**/coverage
|
||||
*.tsbuildinfo
|
||||
.vscode/settings.json
|
||||
2
.husky/pre-commit
Normal file
2
.husky/pre-commit
Normal file
@@ -0,0 +1,2 @@
|
||||
bun run encrypt
|
||||
git add .env.development .env.production
|
||||
1
.npmrc
Normal file
1
.npmrc
Normal file
@@ -0,0 +1 @@
|
||||
@star-kitten:registry=https://git.f302.me/api/packages/jb/npm/
|
||||
8
.prettierrc.yaml
Normal file
8
.prettierrc.yaml
Normal file
@@ -0,0 +1,8 @@
|
||||
trailingComma: all
|
||||
tabWidth: 2
|
||||
useTabs: false
|
||||
semi: true
|
||||
singleQuote: true
|
||||
printWidth: 140
|
||||
experimentalTernaries: true
|
||||
quoteProps: consistent
|
||||
15
README.md
Normal file
15
README.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# concierge-bot
|
||||
|
||||
To install dependencies:
|
||||
|
||||
```bash
|
||||
bun install
|
||||
```
|
||||
|
||||
To run:
|
||||
|
||||
```bash
|
||||
bun run index.ts
|
||||
```
|
||||
|
||||
This project was created using `bun init` in bun v1.3.5. [Bun](https://bun.com) is a fast all-in-one JavaScript runtime.
|
||||
177
bun.lock
Normal file
177
bun.lock
Normal file
@@ -0,0 +1,177 @@
|
||||
{
|
||||
"lockfileVersion": 1,
|
||||
"configVersion": 1,
|
||||
"workspaces": {
|
||||
"": {
|
||||
"name": "concierge-bot",
|
||||
"dependencies": {
|
||||
"@projectdysnomia/dysnomia": "github:projectdysnomia/dysnomia#dev",
|
||||
"@star-kitten/discord": "link:@star-kitten/discord",
|
||||
"@star-kitten/eve": "link:@star-kitten/eve",
|
||||
"@star-kitten/eve-discord": "link:@star-kitten/eve-discord",
|
||||
"@star-kitten/util": "link:@star-kitten/util",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bun": "latest",
|
||||
"husky": "^9.1.7",
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@dotenvx/dotenvx": "^1.49.0",
|
||||
"@types/bun": "^1.2.21",
|
||||
"prettier": "^3.6.2",
|
||||
"typescript": "^5",
|
||||
},
|
||||
},
|
||||
},
|
||||
"packages": {
|
||||
"@dotenvx/dotenvx": ["@dotenvx/dotenvx@1.52.0", "", { "dependencies": { "commander": "^11.1.0", "dotenv": "^17.2.1", "eciesjs": "^0.4.10", "execa": "^5.1.1", "fdir": "^6.2.0", "ignore": "^5.3.0", "object-treeify": "1.1.33", "picomatch": "^4.0.2", "which": "^4.0.0" }, "bin": { "dotenvx": "src/cli/dotenvx.js" } }, "sha512-CaQcc8JvtzQhUSm9877b6V4Tb7HCotkcyud9X2YwdqtQKwgljkMRwU96fVYKnzN3V0Hj74oP7Es+vZ0mS+Aa1w=="],
|
||||
|
||||
"@ecies/ciphers": ["@ecies/ciphers@0.2.5", "", { "peerDependencies": { "@noble/ciphers": "^1.0.0" } }, "sha512-GalEZH4JgOMHYYcYmVqnFirFsjZHeoGMDt9IxEnM9F7GRUUyUksJ7Ou53L83WHJq3RWKD3AcBpo0iQh0oMpf8A=="],
|
||||
|
||||
"@emnapi/core": ["@emnapi/core@1.8.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" } }, "sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg=="],
|
||||
|
||||
"@emnapi/runtime": ["@emnapi/runtime@1.8.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg=="],
|
||||
|
||||
"@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.1.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ=="],
|
||||
|
||||
"@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.1", "", { "dependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1", "@tybys/wasm-util": "^0.10.1" } }, "sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A=="],
|
||||
|
||||
"@noble/ciphers": ["@noble/ciphers@1.3.0", "", {}, "sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw=="],
|
||||
|
||||
"@noble/curves": ["@noble/curves@1.9.7", "", { "dependencies": { "@noble/hashes": "1.8.0" } }, "sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw=="],
|
||||
|
||||
"@noble/hashes": ["@noble/hashes@1.8.0", "", {}, "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A=="],
|
||||
|
||||
"@projectdysnomia/dysnomia": ["@projectdysnomia/dysnomia@github:projectdysnomia/dysnomia#cd9fe97", { "dependencies": { "ws": "^8.18.0" }, "optionalDependencies": { "@snazzah/davey": "^0.1.6", "@stablelib/xchacha20poly1305": "~1.0.1", "opusscript": "^0.1.1" }, "peerDependencies": { "@discordjs/opus": "^0.9.0", "erlpack": "github:discord/erlpack", "eventemitter3": "^5.0.1", "pako": "^2.1.0", "sodium-native": "^4.1.1", "zlib-sync": "^0.1.9" }, "optionalPeers": ["@discordjs/opus", "erlpack", "eventemitter3", "pako", "sodium-native", "zlib-sync"] }, "projectdysnomia-dysnomia-cd9fe97"],
|
||||
|
||||
"@snazzah/davey": ["@snazzah/davey@0.1.9", "", { "optionalDependencies": { "@snazzah/davey-android-arm-eabi": "0.1.9", "@snazzah/davey-android-arm64": "0.1.9", "@snazzah/davey-darwin-arm64": "0.1.9", "@snazzah/davey-darwin-x64": "0.1.9", "@snazzah/davey-freebsd-x64": "0.1.9", "@snazzah/davey-linux-arm-gnueabihf": "0.1.9", "@snazzah/davey-linux-arm64-gnu": "0.1.9", "@snazzah/davey-linux-arm64-musl": "0.1.9", "@snazzah/davey-linux-x64-gnu": "0.1.9", "@snazzah/davey-linux-x64-musl": "0.1.9", "@snazzah/davey-wasm32-wasi": "0.1.9", "@snazzah/davey-win32-arm64-msvc": "0.1.9", "@snazzah/davey-win32-ia32-msvc": "0.1.9", "@snazzah/davey-win32-x64-msvc": "0.1.9" } }, "sha512-vNZk5y+IsxjwzTAXikvzz5pqMLb35YytC64nVF2MAFVhjpXu9ITOKUriZ0JG/llwzCAi56jb5x0cXDRIyE2A2A=="],
|
||||
|
||||
"@snazzah/davey-android-arm-eabi": ["@snazzah/davey-android-arm-eabi@0.1.9", "", { "os": "android", "cpu": "arm" }, "sha512-Dq0WyeVGBw+uQbisV/6PeCQV2ndJozfhZqiNIfQxu6ehIdXB7iHILv+oY+AQN2n+qxiFmLh/MOX9RF+pIWdPbA=="],
|
||||
|
||||
"@snazzah/davey-android-arm64": ["@snazzah/davey-android-arm64@0.1.9", "", { "os": "android", "cpu": "arm64" }, "sha512-OE16OZjv7F/JrD7Mzw5eL2gY2vXRPC8S7ZrmkcMyz/sHHJsGHlT+L7X5s56Bec1YDTVmzAsH4UBuvVBoXuIWEQ=="],
|
||||
|
||||
"@snazzah/davey-darwin-arm64": ["@snazzah/davey-darwin-arm64@0.1.9", "", { "os": "darwin", "cpu": "arm64" }, "sha512-z7oORvAPExikFkH6tvHhbUdZd77MYZp9VqbCpKEiI+sisWFVXgHde7F7iH3G4Bz6gUYJfgvKhWXiDRc+0SC4dg=="],
|
||||
|
||||
"@snazzah/davey-darwin-x64": ["@snazzah/davey-darwin-x64@0.1.9", "", { "os": "darwin", "cpu": "x64" }, "sha512-f1LzGyRGlM414KpXml3OgWVSd7CgylcdYaFj/zDBb8bvWjxyvsI9iMeuPfe/cduloxRj8dELde/yCDZtFR6PdQ=="],
|
||||
|
||||
"@snazzah/davey-freebsd-x64": ["@snazzah/davey-freebsd-x64@0.1.9", "", { "os": "freebsd", "cpu": "x64" }, "sha512-k6p3JY2b8rD6j0V9Ql7kBUMR4eJdcpriNwiHltLzmtGuz/nK5RGQdkEP68gTLc+Uj3xs5Cy0jRKmv2xJQBR4sA=="],
|
||||
|
||||
"@snazzah/davey-linux-arm-gnueabihf": ["@snazzah/davey-linux-arm-gnueabihf@0.1.9", "", { "os": "linux", "cpu": "arm" }, "sha512-xDaAFUC/1+n/YayNwKsqKOBMuW0KI6F0SjgWU+krYTQTVmAKNjOM80IjemrVoqTpBOxBsT80zEtct2wj11CE3Q=="],
|
||||
|
||||
"@snazzah/davey-linux-arm64-gnu": ["@snazzah/davey-linux-arm64-gnu@0.1.9", "", { "os": "linux", "cpu": "arm64" }, "sha512-t1VxFBzWExPNpsNY/9oStdAAuHqFvwZvIO2YPYyVNstxfi2KmAbHMweHUW7xb2ppXuhVQZ4VGmmeXiXcXqhPBw=="],
|
||||
|
||||
"@snazzah/davey-linux-arm64-musl": ["@snazzah/davey-linux-arm64-musl@0.1.9", "", { "os": "linux", "cpu": "arm64" }, "sha512-Xvlr+nBPzuFV4PXHufddlt08JsEyu0p8mX2DpqdPxdpysYIH4I8V86yJiS4tk04a6pLBDd8IxTbBwvXJKqd/LQ=="],
|
||||
|
||||
"@snazzah/davey-linux-x64-gnu": ["@snazzah/davey-linux-x64-gnu@0.1.9", "", { "os": "linux", "cpu": "x64" }, "sha512-6Uunc/NxiEkg1reroAKZAGfOtjl1CGa7hfTTVClb2f+DiA8ZRQWBh+3lgkq/0IeL262B4F14X8QRv5Bsv128qw=="],
|
||||
|
||||
"@snazzah/davey-linux-x64-musl": ["@snazzah/davey-linux-x64-musl@0.1.9", "", { "os": "linux", "cpu": "x64" }, "sha512-fFQ/n3aWt1lXhxSdy+Ge3gi5bR3VETMVsWhH0gwBALUKrbo3ZzgSktm4lNrXE9i0ncMz/CDpZ5i0wt/N3XphEQ=="],
|
||||
|
||||
"@snazzah/davey-wasm32-wasi": ["@snazzah/davey-wasm32-wasi@0.1.9", "", { "dependencies": { "@napi-rs/wasm-runtime": "^1.1.0" }, "cpu": "none" }, "sha512-xWvzej8YCVlUvzlpmqJMIf0XmLlHqulKZ2e7WNe2TxQmsK+o0zTZqiQYs2MwaEbrNXBhYlHDkdpuwoXkJdscNQ=="],
|
||||
|
||||
"@snazzah/davey-win32-arm64-msvc": ["@snazzah/davey-win32-arm64-msvc@0.1.9", "", { "os": "win32", "cpu": "arm64" }, "sha512-sTqry/DfltX2OdW1CTLKa3dFYN5FloAEb2yhGsY1i5+Bms6OhwByXfALvyMHYVo61Th2+sD+9BJpQffHFKDA3w=="],
|
||||
|
||||
"@snazzah/davey-win32-ia32-msvc": ["@snazzah/davey-win32-ia32-msvc@0.1.9", "", { "os": "win32", "cpu": "ia32" }, "sha512-twD3LwlkGnSwphsCtpGb5ztpBIWEvGdc0iujoVkdzZ6nJiq5p8iaLjJMO4hBm9h3s28fc+1Qd7AMVnagiOasnA=="],
|
||||
|
||||
"@snazzah/davey-win32-x64-msvc": ["@snazzah/davey-win32-x64-msvc@0.1.9", "", { "os": "win32", "cpu": "x64" }, "sha512-eMnXbv4GoTngWYY538i/qHz2BS+RgSXFsvKltPzKqnqzPzhQZIY7TemEJn3D5yWGfW4qHve9u23rz93FQqnQMA=="],
|
||||
|
||||
"@stablelib/aead": ["@stablelib/aead@1.0.1", "", {}, "sha512-q39ik6sxGHewqtO0nP4BuSe3db5G1fEJE8ukvngS2gLkBXyy6E7pLubhbYgnkDFv6V8cWaxcE4Xn0t6LWcJkyg=="],
|
||||
|
||||
"@stablelib/binary": ["@stablelib/binary@1.0.1", "", { "dependencies": { "@stablelib/int": "^1.0.1" } }, "sha512-ClJWvmL6UBM/wjkvv/7m5VP3GMr9t0osr4yVgLZsLCOz4hGN9gIAFEqnJ0TsSMAN+n840nf2cHZnA5/KFqHC7Q=="],
|
||||
|
||||
"@stablelib/chacha": ["@stablelib/chacha@1.0.1", "", { "dependencies": { "@stablelib/binary": "^1.0.1", "@stablelib/wipe": "^1.0.1" } }, "sha512-Pmlrswzr0pBzDofdFuVe1q7KdsHKhhU24e8gkEwnTGOmlC7PADzLVxGdn2PoNVBBabdg0l/IfLKg6sHAbTQugg=="],
|
||||
|
||||
"@stablelib/chacha20poly1305": ["@stablelib/chacha20poly1305@1.0.1", "", { "dependencies": { "@stablelib/aead": "^1.0.1", "@stablelib/binary": "^1.0.1", "@stablelib/chacha": "^1.0.1", "@stablelib/constant-time": "^1.0.1", "@stablelib/poly1305": "^1.0.1", "@stablelib/wipe": "^1.0.1" } }, "sha512-MmViqnqHd1ymwjOQfghRKw2R/jMIGT3wySN7cthjXCBdO+qErNPUBnRzqNpnvIwg7JBCg3LdeCZZO4de/yEhVA=="],
|
||||
|
||||
"@stablelib/constant-time": ["@stablelib/constant-time@1.0.1", "", {}, "sha512-tNOs3uD0vSJcK6z1fvef4Y+buN7DXhzHDPqRLSXUel1UfqMB1PWNsnnAezrKfEwTLpN0cGH2p9NNjs6IqeD0eg=="],
|
||||
|
||||
"@stablelib/int": ["@stablelib/int@1.0.1", "", {}, "sha512-byr69X/sDtDiIjIV6m4roLVWnNNlRGzsvxw+agj8CIEazqWGOQp2dTYgQhtyVXV9wpO6WyXRQUzLV/JRNumT2w=="],
|
||||
|
||||
"@stablelib/poly1305": ["@stablelib/poly1305@1.0.1", "", { "dependencies": { "@stablelib/constant-time": "^1.0.1", "@stablelib/wipe": "^1.0.1" } }, "sha512-1HlG3oTSuQDOhSnLwJRKeTRSAdFNVB/1djy2ZbS35rBSJ/PFqx9cf9qatinWghC2UbfOYD8AcrtbUQl8WoxabA=="],
|
||||
|
||||
"@stablelib/wipe": ["@stablelib/wipe@1.0.1", "", {}, "sha512-WfqfX/eXGiAd3RJe4VU2snh/ZPwtSjLG4ynQ/vYzvghTh7dHFcI1wl+nrkWG6lGhukOxOsUHfv8dUXr58D0ayg=="],
|
||||
|
||||
"@stablelib/xchacha20": ["@stablelib/xchacha20@1.0.1", "", { "dependencies": { "@stablelib/binary": "^1.0.1", "@stablelib/chacha": "^1.0.1", "@stablelib/wipe": "^1.0.1" } }, "sha512-1YkiZnFF4veUwBVhDnDYwo6EHeKzQK4FnLiO7ezCl/zu64uG0bCCAUROJaBkaLH+5BEsO3W7BTXTguMbSLlWSw=="],
|
||||
|
||||
"@stablelib/xchacha20poly1305": ["@stablelib/xchacha20poly1305@1.0.1", "", { "dependencies": { "@stablelib/aead": "^1.0.1", "@stablelib/chacha20poly1305": "^1.0.1", "@stablelib/constant-time": "^1.0.1", "@stablelib/wipe": "^1.0.1", "@stablelib/xchacha20": "^1.0.1" } }, "sha512-B1Abj0sMJ8h3HNmGnJ7vHBrAvxuNka6cJJoZ1ILN7iuacXp7sUYcgOVEOTLWj+rtQMpspY9tXSCRLPmN1mQNWg=="],
|
||||
|
||||
"@star-kitten/discord": ["@star-kitten/discord@link:@star-kitten/discord", {}],
|
||||
|
||||
"@star-kitten/eve": ["@star-kitten/eve@link:@star-kitten/eve", {}],
|
||||
|
||||
"@star-kitten/eve-discord": ["@star-kitten/eve-discord@link:@star-kitten/eve-discord", {}],
|
||||
|
||||
"@star-kitten/util": ["@star-kitten/util@link:@star-kitten/util", {}],
|
||||
|
||||
"@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="],
|
||||
|
||||
"@types/bun": ["@types/bun@1.3.9", "", { "dependencies": { "bun-types": "1.3.9" } }, "sha512-KQ571yULOdWJiMH+RIWIOZ7B2RXQGpL1YQrBtLIV3FqDcCu6FsbFUBwhdKUlCKUpS3PJDsHlJ1QKlpxoVR+xtw=="],
|
||||
|
||||
"@types/node": ["@types/node@25.2.3", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-m0jEgYlYz+mDJZ2+F4v8D1AyQb+QzsNqRuI7xg1VQX/KlKS0qT9r1Mo16yo5F/MtifXFgaofIFsdFMox2SxIbQ=="],
|
||||
|
||||
"bun-types": ["bun-types@1.3.9", "", { "dependencies": { "@types/node": "*" } }, "sha512-+UBWWOakIP4Tswh0Bt0QD0alpTY8cb5hvgiYeWCMet9YukHbzuruIEeXC2D7nMJPB12kbh8C7XJykSexEqGKJg=="],
|
||||
|
||||
"commander": ["commander@11.1.0", "", {}, "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ=="],
|
||||
|
||||
"cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="],
|
||||
|
||||
"dotenv": ["dotenv@17.3.1", "", {}, "sha512-IO8C/dzEb6O3F9/twg6ZLXz164a2fhTnEWb95H23Dm4OuN+92NmEAlTrupP9VW6Jm3sO26tQlqyvyi4CsnY9GA=="],
|
||||
|
||||
"eciesjs": ["eciesjs@0.4.17", "", { "dependencies": { "@ecies/ciphers": "^0.2.5", "@noble/ciphers": "^1.3.0", "@noble/curves": "^1.9.7", "@noble/hashes": "^1.8.0" } }, "sha512-TOOURki4G7sD1wDCjj7NfLaXZZ49dFOeEb5y39IXpb8p0hRzVvfvzZHOi5JcT+PpyAbi/Y+lxPb8eTag2WYH8w=="],
|
||||
|
||||
"execa": ["execa@5.1.1", "", { "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.0", "human-signals": "^2.1.0", "is-stream": "^2.0.0", "merge-stream": "^2.0.0", "npm-run-path": "^4.0.1", "onetime": "^5.1.2", "signal-exit": "^3.0.3", "strip-final-newline": "^2.0.0" } }, "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg=="],
|
||||
|
||||
"fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="],
|
||||
|
||||
"get-stream": ["get-stream@6.0.1", "", {}, "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg=="],
|
||||
|
||||
"human-signals": ["human-signals@2.1.0", "", {}, "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw=="],
|
||||
|
||||
"husky": ["husky@9.1.7", "", { "bin": { "husky": "bin.js" } }, "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA=="],
|
||||
|
||||
"ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="],
|
||||
|
||||
"is-stream": ["is-stream@2.0.1", "", {}, "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg=="],
|
||||
|
||||
"isexe": ["isexe@3.1.5", "", {}, "sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w=="],
|
||||
|
||||
"merge-stream": ["merge-stream@2.0.0", "", {}, "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="],
|
||||
|
||||
"mimic-fn": ["mimic-fn@2.1.0", "", {}, "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="],
|
||||
|
||||
"npm-run-path": ["npm-run-path@4.0.1", "", { "dependencies": { "path-key": "^3.0.0" } }, "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw=="],
|
||||
|
||||
"object-treeify": ["object-treeify@1.1.33", "", {}, "sha512-EFVjAYfzWqWsBMRHPMAXLCDIJnpMhdWAqR7xG6M6a2cs6PMFpl/+Z20w9zDW4vkxOFfddegBKq9Rehd0bxWE7A=="],
|
||||
|
||||
"onetime": ["onetime@5.1.2", "", { "dependencies": { "mimic-fn": "^2.1.0" } }, "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg=="],
|
||||
|
||||
"opusscript": ["opusscript@0.1.1", "", {}, "sha512-mL0fZZOUnXdZ78woRXp18lApwpp0lF5tozJOD1Wut0dgrA9WuQTgSels/CSmFleaAZrJi/nci5KOVtbuxeWoQA=="],
|
||||
|
||||
"path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="],
|
||||
|
||||
"picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="],
|
||||
|
||||
"prettier": ["prettier@3.8.1", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg=="],
|
||||
|
||||
"shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="],
|
||||
|
||||
"shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="],
|
||||
|
||||
"signal-exit": ["signal-exit@3.0.7", "", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="],
|
||||
|
||||
"strip-final-newline": ["strip-final-newline@2.0.0", "", {}, "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA=="],
|
||||
|
||||
"tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
||||
|
||||
"typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
|
||||
|
||||
"undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="],
|
||||
|
||||
"which": ["which@4.0.0", "", { "dependencies": { "isexe": "^3.1.1" }, "bin": { "node-which": "bin/which.js" } }, "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg=="],
|
||||
|
||||
"ws": ["ws@8.19.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg=="],
|
||||
|
||||
"cross-spawn/which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="],
|
||||
|
||||
"cross-spawn/which/isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="],
|
||||
}
|
||||
}
|
||||
34
package.json
Normal file
34
package.json
Normal file
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"name": "concierge-bot",
|
||||
"type": "module",
|
||||
"module": "src/main.ts",
|
||||
"private": true,
|
||||
"devDependencies": {
|
||||
"@types/bun": "latest",
|
||||
"husky": "^9.1.7"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@dotenvx/dotenvx": "^1.49.0",
|
||||
"@types/bun": "^1.2.21",
|
||||
"prettier": "^3.6.2",
|
||||
"typescript": "^5"
|
||||
},
|
||||
"dependencies": {
|
||||
"@projectdysnomia/dysnomia": "github:projectdysnomia/dysnomia#dev",
|
||||
"@star-kitten/util": "link:@star-kitten/util",
|
||||
"@star-kitten/discord": "link:@star-kitten/discord",
|
||||
"@star-kitten/eve": "link:@star-kitten/eve",
|
||||
"@star-kitten/eve-discord": "link:@star-kitten/eve-discord"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "bunx dotenvx run -f .env.development -- bun run --watch src/main.ts",
|
||||
"start": "bunx @dotenvx/dotenvx run -f .env.production -- bun src/main.ts",
|
||||
"build": "mkdirp ./db && bun build --minify --sourcemap src/main.ts --target bun --outdir ./dist",
|
||||
"lint": "prettier --check .",
|
||||
"format": "prettier --write .",
|
||||
"test": "bun test",
|
||||
"encrypt": "bunx dotenvx encrypt -f .env.development && bunx dotenvx encrypt -f .env.production",
|
||||
"decrypt": "bunx dotenvx decrypt -f .env.development && bunx dotenvx decrypt -f .env.production",
|
||||
"prepare": "husky"
|
||||
}
|
||||
}
|
||||
124
src/commands/create-route.command.ts
Normal file
124
src/commands/create-route.command.ts
Normal file
@@ -0,0 +1,124 @@
|
||||
import { getDB } from '@/lib/db';
|
||||
import { Constants } from '@projectdysnomia/dysnomia';
|
||||
import {
|
||||
createChatCommand,
|
||||
integerOption,
|
||||
stringOption,
|
||||
subCommandGroupOption,
|
||||
subCommandRouter,
|
||||
} from '@star-kitten/discord';
|
||||
import { numberOption, subCommandOption } from '@star-kitten/discord';
|
||||
|
||||
export default createChatCommand(
|
||||
{
|
||||
name: 'route',
|
||||
description: 'Routes',
|
||||
defaultMemberPermissions: Constants.Permissions.administrator,
|
||||
options: [
|
||||
subCommandGroupOption({
|
||||
name: 'group',
|
||||
description: 'a group',
|
||||
options: [
|
||||
subCommandOption({
|
||||
name: 'add',
|
||||
description: 'add a route',
|
||||
options: [
|
||||
stringOption({
|
||||
name: 'start',
|
||||
description: 'starting location',
|
||||
autocomplete: true,
|
||||
required: true,
|
||||
}),
|
||||
stringOption({
|
||||
name: 'end',
|
||||
description: 'end location',
|
||||
autocomplete: true,
|
||||
required: true,
|
||||
}),
|
||||
integerOption({
|
||||
name: 'isk-per-m3',
|
||||
description: 'ISK per m3',
|
||||
required: true,
|
||||
}),
|
||||
numberOption({
|
||||
name: 'collateral-percent',
|
||||
description: 'percentage of collateral to add onto the cost.',
|
||||
required: true,
|
||||
}),
|
||||
integerOption({
|
||||
name: 'max-volume',
|
||||
description: 'Maximum volume allowed for this route',
|
||||
required: true,
|
||||
}),
|
||||
integerOption({
|
||||
name: 'min-reward',
|
||||
description: 'Minimum required reward for this route',
|
||||
required: true,
|
||||
}),
|
||||
integerOption({
|
||||
name: 'expiration',
|
||||
description: 'Expiration the client should set on the contract',
|
||||
required: true,
|
||||
}),
|
||||
integerOption({
|
||||
name: 'completion',
|
||||
description: 'Days to complete time the client should set on the contract',
|
||||
required: true,
|
||||
}),
|
||||
integerOption({
|
||||
name: 'max-collateral',
|
||||
description: 'Maximum collateral allowed for this route',
|
||||
}),
|
||||
],
|
||||
}),
|
||||
subCommandOption({
|
||||
name: 'remove',
|
||||
description: 'remove a route',
|
||||
options: [
|
||||
integerOption({
|
||||
name: 'id',
|
||||
description: 'ID of the route to remove',
|
||||
required: true,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
},
|
||||
subCommandRouter({
|
||||
group: {
|
||||
add: async (interaction, ctx, data) => {
|
||||
console.log(`in add`);
|
||||
if (interaction.isAutocomplete()) {
|
||||
const focused = data.options?.find((opt) => opt.focused);
|
||||
console.log(`focused`, focused);
|
||||
if (focused) {
|
||||
switch (focused.name) {
|
||||
case 'start': {
|
||||
const locations = getDB().getAllLocations();
|
||||
console.log(JSON.stringify(locations.length));
|
||||
return await interaction.result(
|
||||
locations.map((l) => ({ name: l.short_name, value: String(l.location_id) })),
|
||||
);
|
||||
}
|
||||
case 'end': {
|
||||
const locations = getDB().getAllLocations();
|
||||
console.log(JSON.stringify(locations.length));
|
||||
return await interaction.result(
|
||||
locations.map((l) => ({ name: l.short_name, value: String(l.location_id) })),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
remove: (interaction, ctx) => {
|
||||
console.log('remove handler');
|
||||
if (interaction.isApplicationCommand()) {
|
||||
interaction.createMessage(`Thanks`);
|
||||
}
|
||||
},
|
||||
},
|
||||
}),
|
||||
);
|
||||
6
src/commands/index.ts
Normal file
6
src/commands/index.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import '@star-kitten/eve-discord/commands/time.command.js';
|
||||
import '@star-kitten/eve-discord/commands/time-from-now.command.js';
|
||||
|
||||
import './locations/command';
|
||||
import './quoute.command';
|
||||
import './create-route.command';
|
||||
35
src/commands/locations/add-location.modal.ts
Normal file
35
src/commands/locations/add-location.modal.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import { type PageContext, input, label, modal, stringSelect } from '@star-kitten/discord';
|
||||
import type { LocationsState } from './state';
|
||||
import { Page } from './router';
|
||||
import { StructureType } from '@/lib/db/types/routes';
|
||||
|
||||
export default async function (ctx: PageContext<LocationsState>) {
|
||||
const isAdd = ctx.custom_id === Page.addLocationModal;
|
||||
const location = ctx.state.data.selected;
|
||||
|
||||
|
||||
return modal(isAdd ? Page.addLocationModalSubmit : Page.editLocationModalSubmit,
|
||||
`${isAdd ? 'Add Location' : 'Edit: ' + ctx.state.data.selected?.short_name || ''}`,
|
||||
isAdd && label({ label: 'Location ID' },
|
||||
input('loc-id', { placeholder: 'Enter the structure id', required: true }),
|
||||
),
|
||||
label({ label: 'Location Name' },
|
||||
input('loc-name', { placeholder: 'Enter the location name', required: true, value: location?.name }),
|
||||
),
|
||||
label({ label: 'Location Short Name' },
|
||||
input('loc-short-name', { placeholder: 'Enter the location short name', required: true, value: location?.short_name }),
|
||||
),
|
||||
label({ label: 'System' },
|
||||
input('loc-system', { placeholder: 'Enter the system (e.g. Jita)', required: true, value: location?.system }),
|
||||
),
|
||||
label({ label: 'Structure Type' },
|
||||
stringSelect('loc-structure-type', { placeholder: 'Select Structure Type', min_values: 1, max_values: 1, required: true },
|
||||
...Object.values(StructureType).map((type) => ({
|
||||
label: type,
|
||||
value: type,
|
||||
default: location?.structure_type === type,
|
||||
})),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
62
src/commands/locations/command.ts
Normal file
62
src/commands/locations/command.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
import {
|
||||
createChatCommand,
|
||||
type CommandContext,
|
||||
type ExecutableInteraction,
|
||||
PageType,
|
||||
usePages,
|
||||
hasUserId,
|
||||
PermissionType,
|
||||
} from '@star-kitten/discord';
|
||||
import mainPage from './main.page';
|
||||
import addLocationModal from './add-location.modal';
|
||||
import editServicesModal from './edit-services.modal';
|
||||
import removeLocationModal from './remove-location.modal';
|
||||
import type { LocationsState } from './state';
|
||||
import router, { Page } from './router';
|
||||
import { Constants } from '@projectdysnomia/dysnomia';
|
||||
|
||||
export default createChatCommand(
|
||||
{
|
||||
name: 'locations',
|
||||
description: 'location management',
|
||||
defaultMemberPermissions: Constants.Permissions.administrator,
|
||||
},
|
||||
async (interaction: ExecutableInteraction, commandCtx: CommandContext) => {
|
||||
await usePages<LocationsState>(
|
||||
{
|
||||
pages: {
|
||||
[Page.main]: {
|
||||
key: Page.main,
|
||||
type: PageType.MESSAGE,
|
||||
render: mainPage,
|
||||
},
|
||||
[Page.addLocationModal]: {
|
||||
key: Page.addLocationModal,
|
||||
type: PageType.MODAL,
|
||||
render: addLocationModal,
|
||||
},
|
||||
[Page.editLocationModal]: {
|
||||
key: Page.editLocationModal,
|
||||
type: PageType.MODAL,
|
||||
render: addLocationModal,
|
||||
},
|
||||
[Page.editServicesModal]: {
|
||||
key: Page.editServicesModal,
|
||||
type: PageType.MODAL,
|
||||
render: editServicesModal,
|
||||
},
|
||||
[Page.removeLocationModal]: {
|
||||
key: Page.removeLocationModal,
|
||||
type: PageType.MODAL,
|
||||
render: removeLocationModal,
|
||||
},
|
||||
},
|
||||
router,
|
||||
initialPage: Page.main,
|
||||
ephemeral: true,
|
||||
},
|
||||
interaction,
|
||||
commandCtx,
|
||||
);
|
||||
},
|
||||
);
|
||||
128
src/commands/locations/edit-services.modal.ts
Normal file
128
src/commands/locations/edit-services.modal.ts
Normal file
@@ -0,0 +1,128 @@
|
||||
import { label, modal, option, stringSelect, type PageContext } from '@star-kitten/discord';
|
||||
import type { LocationsState } from './state';
|
||||
import { Page } from './router';
|
||||
import { locationSupportsType, RouteType } from '@/lib/db/types/routes';
|
||||
|
||||
export default function (ctx: PageContext<LocationsState>) {
|
||||
const location = ctx.state.data.selected!;
|
||||
|
||||
return modal(
|
||||
Page.editServicesModalSubmit,
|
||||
`Services: ${ctx.state.data.selected?.short_name || ''}`,
|
||||
label(
|
||||
{
|
||||
label: 'Can JF',
|
||||
},
|
||||
stringSelect(
|
||||
'can-jf',
|
||||
{
|
||||
placeholder: 'Can JF',
|
||||
min_values: 1,
|
||||
max_values: 1,
|
||||
},
|
||||
option({
|
||||
label: 'Yes',
|
||||
value: RouteType.JF + '',
|
||||
default: locationSupportsType(location, RouteType.JF),
|
||||
}),
|
||||
option({
|
||||
label: 'No',
|
||||
value: '0',
|
||||
default: !locationSupportsType(location, RouteType.JF),
|
||||
}),
|
||||
),
|
||||
),
|
||||
label(
|
||||
{
|
||||
label: 'Can DST',
|
||||
},
|
||||
stringSelect(
|
||||
'can-dst',
|
||||
{
|
||||
placeholder: 'Can DST',
|
||||
min_values: 1,
|
||||
max_values: 1,
|
||||
},
|
||||
option({
|
||||
label: 'Yes',
|
||||
value: RouteType.DST + '',
|
||||
default: locationSupportsType(location, RouteType.DST),
|
||||
}),
|
||||
option({
|
||||
label: 'No',
|
||||
value: '0',
|
||||
default: !locationSupportsType(location, RouteType.DST),
|
||||
}),
|
||||
),
|
||||
),
|
||||
label(
|
||||
{
|
||||
label: 'Can BR',
|
||||
},
|
||||
stringSelect(
|
||||
'can-br',
|
||||
{
|
||||
placeholder: 'Can BR',
|
||||
min_values: 1,
|
||||
max_values: 1,
|
||||
},
|
||||
option({
|
||||
label: 'Yes',
|
||||
value: RouteType.BR + '',
|
||||
default: locationSupportsType(location, RouteType.BR),
|
||||
}),
|
||||
option({
|
||||
label: 'No',
|
||||
value: '0',
|
||||
default: !locationSupportsType(location, RouteType.BR),
|
||||
}),
|
||||
),
|
||||
),
|
||||
label(
|
||||
{
|
||||
label: 'Can SMB',
|
||||
},
|
||||
stringSelect(
|
||||
'can-smb',
|
||||
{
|
||||
placeholder: 'Can SMB',
|
||||
min_values: 1,
|
||||
max_values: 1,
|
||||
},
|
||||
option({
|
||||
label: 'Yes',
|
||||
value: RouteType.SMB + '',
|
||||
default: locationSupportsType(location, RouteType.SMB),
|
||||
}),
|
||||
option({
|
||||
label: 'No',
|
||||
value: '0',
|
||||
default: !locationSupportsType(location, RouteType.SMB),
|
||||
}),
|
||||
),
|
||||
),
|
||||
label(
|
||||
{
|
||||
label: 'Can Bridge',
|
||||
},
|
||||
stringSelect(
|
||||
'can-bridge',
|
||||
{
|
||||
placeholder: 'Can Bridge',
|
||||
min_values: 1,
|
||||
max_values: 1,
|
||||
},
|
||||
option({
|
||||
label: 'Yes',
|
||||
value: RouteType.BRIDGE + '',
|
||||
default: locationSupportsType(location, RouteType.BRIDGE),
|
||||
}),
|
||||
option({
|
||||
label: 'No',
|
||||
value: '0',
|
||||
default: !locationSupportsType(location, RouteType.BRIDGE),
|
||||
}),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
55
src/commands/locations/main.page.ts
Normal file
55
src/commands/locations/main.page.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
import { actionRow, button, ButtonStyle, container, option, stringSelect, text, type PageContext } from '@star-kitten/discord';
|
||||
import type { LocationsState } from './state';
|
||||
import { getDB } from '@/lib/db';
|
||||
import { Page } from './router';
|
||||
import { locationSupportsType, RouteType } from '@/lib/db/types/routes';
|
||||
|
||||
export default function (ctx: PageContext<LocationsState>) {
|
||||
const locations = getDB().getAllLocations();
|
||||
const hasLocations = locations.length > 0;
|
||||
|
||||
const renderLocations = () => {
|
||||
if (locations.length === 0) {
|
||||
return 'No locations added yet.';
|
||||
}
|
||||
return locations
|
||||
.map(
|
||||
(loc) =>
|
||||
`${loc.location_id}\t|\t${loc.short_name}\t|\t${locationSupportsType(loc, RouteType.JF) ? 'JF' : ''}${locationSupportsType(loc, RouteType.DST) ? ', DST' : ''}${locationSupportsType(loc, RouteType.BR) ? ', BR' : ''}${locationSupportsType(loc, RouteType.SMB) ? ', SMB' : ''}${locationSupportsType(loc, RouteType.BRIDGE) ? ', BRIDGE' : ''}`,
|
||||
)
|
||||
.join('\n');
|
||||
};
|
||||
|
||||
if (!hasLocations) {
|
||||
return container(
|
||||
{ accent_color: 0x11cc33 },
|
||||
text(`# Locations\nNo locations added yet.`),
|
||||
actionRow(
|
||||
button(Page.addLocationModal, 'Add Location', { style: ButtonStyle.PRIMARY }),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
const locationOptions = locations.map((loc) => option({ label: loc.short_name, value: loc.location_id.toString() }));
|
||||
|
||||
return container(
|
||||
{ accent_color: 0x11cc33 },
|
||||
text(`# Locations\n${renderLocations()}`),
|
||||
actionRow(
|
||||
button(Page.addLocationModal, 'Add Location', { style: ButtonStyle.PRIMARY }),
|
||||
),
|
||||
text(`## Edit services at`),
|
||||
actionRow(
|
||||
stringSelect(Page.editServicesModal, { placeholder: 'Select location to edit services', min_values: 1, max_values: 1 }, ...locationOptions),
|
||||
),
|
||||
text(`## Edit location details`),
|
||||
actionRow(
|
||||
stringSelect(Page.editLocationModal, { placeholder: 'Select location to edit', min_values: 1, max_values: 1 }, ...locationOptions),
|
||||
),
|
||||
text(`## Remove location`),
|
||||
actionRow(
|
||||
stringSelect(Page.removeLocationModal, { placeholder: 'Select location to remove', min_values: 1, max_values: 1 }, ...locationOptions),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
11
src/commands/locations/remove-location.modal.ts
Normal file
11
src/commands/locations/remove-location.modal.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { modal, text, type PageContext } from '@star-kitten/discord';
|
||||
import type { LocationsState } from './state';
|
||||
import { Page } from './router';
|
||||
|
||||
export default function (ctx: PageContext<LocationsState>) {
|
||||
return modal(
|
||||
Page.removeLocationModalSubmit,
|
||||
`Remove ${ctx.state.data.selected?.short_name || ''}?`,
|
||||
text(`# Are you sure?\n\nConfrim that you want remove **${ctx.state.data.selected.name}**.\n\n*This action cannot be undone. Click submit to confirm.*`),
|
||||
);
|
||||
}
|
||||
140
src/commands/locations/router.ts
Normal file
140
src/commands/locations/router.ts
Normal file
@@ -0,0 +1,140 @@
|
||||
import * as StarKitten from '@star-kitten/discord';
|
||||
import type { LocationsState } from './state';
|
||||
import { getDB } from '@/lib/db';
|
||||
import type { StructureType } from '@/lib/db/types/routes';
|
||||
|
||||
export enum Page {
|
||||
main = 'main',
|
||||
addLocationModal = 'add-location-modal',
|
||||
addLocationModalSubmit = 'add-location-modal-submit',
|
||||
editLocationModal = 'edit-location-modal',
|
||||
editLocationModalSubmit = 'edit-location-modal-submit',
|
||||
editServicesModal = 'edit-services-modal',
|
||||
editServicesModalSubmit = 'edit-services-modal-submit',
|
||||
removeLocationModal = 'remove-location-modal',
|
||||
removeLocationModalSubmit = 'remove-location-modal-submit',
|
||||
}
|
||||
|
||||
export default function (ctx: StarKitten.PageContext<LocationsState>): Page {
|
||||
switch (ctx.custom_id) {
|
||||
case Page.addLocationModal:
|
||||
ctx.state.data.selected = undefined;
|
||||
return Page.addLocationModal;
|
||||
|
||||
case Page.editLocationModalSubmit:
|
||||
case Page.addLocationModalSubmit: {
|
||||
if (!ctx.interaction.isModalSubmit()) {
|
||||
throw new Error('Expected a modal submit interaction.');
|
||||
}
|
||||
|
||||
const location: any = {};
|
||||
for (const component of ctx.interaction.data.components) {
|
||||
if (StarKitten.isModalLabel(component)) {
|
||||
if (StarKitten.isModalTextInput(component.component)) {
|
||||
if (StarKitten.componentHasIdPrefix(component.component, 'loc-id')) {
|
||||
location.location_id = component.component.value.trim();
|
||||
} else if (StarKitten.componentHasIdPrefix(component.component, 'loc-name')) {
|
||||
location.name = component.component.value.trim();
|
||||
} else if (StarKitten.componentHasIdPrefix(component.component, 'loc-short-name')) {
|
||||
location.short_name = component.component.value.trim();
|
||||
} else if (StarKitten.componentHasIdPrefix(component.component, 'loc-system')) {
|
||||
location.system = component.component.value.trim();
|
||||
}
|
||||
} else if (
|
||||
StarKitten.isStringSelectMenu(component.component) &&
|
||||
StarKitten.componentHasIdPrefix(component.component, 'loc-structure-type')
|
||||
) {
|
||||
location.structure_type = component.component.values[0] as StructureType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ctx.custom_id === Page.addLocationModalSubmit ? getDB().addLocation(location) : getDB().updateLocation(location);
|
||||
ctx.state.data.selected = undefined;
|
||||
return Page.main;
|
||||
}
|
||||
|
||||
case Page.editLocationModal: {
|
||||
if (!ctx.interaction.isSelectMenu()) {
|
||||
console.error('Expected a message component interaction.');
|
||||
return Page.main;
|
||||
}
|
||||
const data = ctx.interaction.data;
|
||||
const locationId = Number.parseInt(data.values[0]);
|
||||
const location = getDB().getLocationById(locationId);
|
||||
if (location) {
|
||||
ctx.state.data.selected = location;
|
||||
return Page.editLocationModal;
|
||||
}
|
||||
return Page.main;
|
||||
}
|
||||
|
||||
case Page.editServicesModal: {
|
||||
if (!ctx.interaction.isSelectMenu()) {
|
||||
console.error('Expected a message component interaction.');
|
||||
return Page.main;
|
||||
}
|
||||
const data = ctx.interaction.data;
|
||||
const locationId = Number.parseInt(data.values[0]);
|
||||
const location = getDB().getLocationById(locationId);
|
||||
if (location) {
|
||||
ctx.state.data.selected = location;
|
||||
return Page.editServicesModal;
|
||||
}
|
||||
return Page.main;
|
||||
}
|
||||
|
||||
case Page.editServicesModalSubmit: {
|
||||
if (ctx.interaction.isModalSubmit()) {
|
||||
const location = ctx.state.data.selected;
|
||||
if (!location) {
|
||||
return Page.main;
|
||||
}
|
||||
|
||||
let supported_route_types = 0;
|
||||
for (const component of ctx.interaction.data.components) {
|
||||
if (StarKitten.isModalLabel(component) && StarKitten.isStringSelectMenu(component.component)) {
|
||||
supported_route_types = supported_route_types | parseInt(component.component.values[0]);
|
||||
}
|
||||
}
|
||||
|
||||
getDB().updateLocation({
|
||||
...location,
|
||||
supported_route_types,
|
||||
});
|
||||
}
|
||||
ctx.state.data.selected = undefined;
|
||||
return Page.main;
|
||||
}
|
||||
|
||||
case Page.removeLocationModal: {
|
||||
if (!ctx.interaction.isSelectMenu()) {
|
||||
console.error('Expected a message component interaction.');
|
||||
return Page.main;
|
||||
}
|
||||
const data = ctx.interaction.data;
|
||||
const locationId = Number.parseInt(data.values[0]);
|
||||
const location = getDB().getLocationById(locationId);
|
||||
if (location) {
|
||||
ctx.state.data.selected = location;
|
||||
return Page.removeLocationModal;
|
||||
}
|
||||
return Page.main;
|
||||
}
|
||||
|
||||
case Page.removeLocationModalSubmit: {
|
||||
if (ctx.interaction.isModalSubmit()) {
|
||||
const location = ctx.state.data.selected;
|
||||
if (!location) {
|
||||
return Page.main;
|
||||
}
|
||||
getDB().removeLocation(location.location_id);
|
||||
}
|
||||
ctx.state.data.selected = undefined;
|
||||
return Page.main;
|
||||
}
|
||||
|
||||
default:
|
||||
return Page.main;
|
||||
}
|
||||
}
|
||||
5
src/commands/locations/state.ts
Normal file
5
src/commands/locations/state.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import type { Location } from '@/lib/db';
|
||||
|
||||
export interface LocationsState {
|
||||
selected?: Location;
|
||||
}
|
||||
225
src/commands/quoute.command.ts
Normal file
225
src/commands/quoute.command.ts
Normal file
@@ -0,0 +1,225 @@
|
||||
import {
|
||||
Constants,
|
||||
type ChatInputApplicationCommandStructure,
|
||||
type ComponentInteractionSelectMenuData,
|
||||
} from '@projectdysnomia/dysnomia';
|
||||
import { appraiseItems, type Appraisal } from '@star-kitten/eve/third-party/janice.js';
|
||||
import { actionRow, button, ButtonStyle, componentHasIdPrefix, componentsV2, container, input, isModalLabel, isModalTextInput, label, modal, stringSelect, text} from '@star-kitten/discord';
|
||||
import { createChatCommand, type CommandContext, type ExecutableInteraction } from '@star-kitten/discord';
|
||||
import { PageType, usePages } from '@star-kitten/discord/pages';
|
||||
|
||||
const definition: ChatInputApplicationCommandStructure = {
|
||||
type: Constants.ApplicationCommandTypes.CHAT_INPUT,
|
||||
name: 'quote',
|
||||
nameLocalizations: {
|
||||
de: 'angebot',
|
||||
'es-ES': 'cotización',
|
||||
fr: 'devis',
|
||||
ja: '見積もり',
|
||||
ko: '견적',
|
||||
ru: 'цитата',
|
||||
'zh-CN': '报价',
|
||||
},
|
||||
description: 'Get a quote for moving your items',
|
||||
descriptionLocalizations: {
|
||||
de: 'Holen Sie Sie sich ein Angebot für den Umzug Ihrer Gegenstände',
|
||||
'es-ES': 'Obtén una cotización para mover tus artículos',
|
||||
fr: 'Obtenez un devis pour déplacer vos articles',
|
||||
ja: 'アイテムを移動するための見積もりを取得します',
|
||||
ko: '항목을 이동하기 위한 견적 받기',
|
||||
ru: 'Получите предложение по перемещению ваших предметов',
|
||||
'zh-CN': '获取移动您的物品的报价',
|
||||
},
|
||||
};
|
||||
|
||||
interface QuouteState {
|
||||
serviceType: RouteType;
|
||||
originId?: number;
|
||||
destinationId?: number;
|
||||
items?: string;
|
||||
appraisal?: Appraisal;
|
||||
}
|
||||
|
||||
// Hardcoded routes for now
|
||||
interface RouteType {
|
||||
id: number;
|
||||
short: string;
|
||||
label: string;
|
||||
}
|
||||
|
||||
const routeTypes: Record<string, RouteType> = {
|
||||
JF: { id: 1, short: 'JF', label: 'Jump Freighter' },
|
||||
DST: { id: 2, short: 'DST', label: 'Deep Space Transport' },
|
||||
SMB: { id: 3, short: 'SMB', label: 'Ship Maintenance Bay' },
|
||||
BR: { id: 4, short: 'BR', label: 'Blockade Runner' },
|
||||
CUSTOM: { id: 5, short: 'CUSTOM', label: 'Custom' },
|
||||
};
|
||||
|
||||
interface Location {
|
||||
id: number;
|
||||
name: string;
|
||||
supported_types: number[]; // RouteType IDs
|
||||
}
|
||||
|
||||
const locations: Location[] = [
|
||||
{ id: 1, name: 'Jita 4-4', supported_types: [1, 2, 3, 4, 5] },
|
||||
{ id: 2, name: 'B-9', supported_types: [1, 2] },
|
||||
{ id: 3, name: '3T7', supported_types: [1, 2, 3, 4, 5] },
|
||||
{ id: 4, name: '4-H', supported_types: [1, 2] },
|
||||
{ id: 5, name: 'Odebeinn', supported_types: [1, 2, 3, 4, 5] },
|
||||
];
|
||||
|
||||
interface Route {
|
||||
origin: number;
|
||||
destination: number;
|
||||
type: number; // RouteType ID
|
||||
}
|
||||
|
||||
const routes: Route[] = [
|
||||
{ origin: 1, destination: 2, type: routeTypes.JF.id },
|
||||
{ origin: 2, destination: 1, type: routeTypes.JF.id },
|
||||
{ origin: 2, destination: 3, type: routeTypes.JF.id },
|
||||
{ origin: 3, destination: 2, type: routeTypes.JF.id },
|
||||
{ origin: 3, destination: 4, type: routeTypes.JF.id },
|
||||
{ origin: 4, destination: 3, type: routeTypes.JF.id },
|
||||
{ origin: 4, destination: 5, type: routeTypes.JF.id },
|
||||
{ origin: 5, destination: 4, type: routeTypes.JF.id },
|
||||
{ origin: 5, destination: 2, type: routeTypes.JF.id },
|
||||
{ origin: 2, destination: 3, type: routeTypes.JF.id },
|
||||
{ origin: 3, destination: 4, type: routeTypes.JF.id },
|
||||
{ origin: 4, destination: 5, type: routeTypes.JF.id },
|
||||
{ origin: 5, destination: 2, type: routeTypes.JF.id },
|
||||
{ origin: 3, destination: 2, type: routeTypes.DST.id },
|
||||
{ origin: 2, destination: 4, type: routeTypes.SMB.id },
|
||||
{ origin: 2, destination: 5, type: routeTypes.BR.id },
|
||||
{ origin: 1, destination: 3, type: routeTypes.DST.id },
|
||||
{ origin: 1, destination: 4, type: routeTypes.SMB.id },
|
||||
{ origin: 1, destination: 5, type: routeTypes.BR.id },
|
||||
{ origin: 2, destination: 1, type: routeTypes.JF.id },
|
||||
{ origin: 3, destination: 1, type: routeTypes.DST.id },
|
||||
{ origin: 4, destination: 1, type: routeTypes.SMB.id },
|
||||
{ origin: 5, destination: 1, type: routeTypes.BR.id },
|
||||
];
|
||||
|
||||
const defaultState: QuouteState = {
|
||||
serviceType: routeTypes.JF,
|
||||
originId: undefined,
|
||||
destinationId: undefined,
|
||||
items: undefined,
|
||||
appraisal: undefined,
|
||||
};
|
||||
|
||||
function uniqueDestinationForOriginAndType(typeId?: number, originId?: number) {
|
||||
if (!typeId) return locations;
|
||||
|
||||
if (!originId) {
|
||||
return locations.filter((loc) => loc.supported_types.includes(typeId));
|
||||
}
|
||||
|
||||
const filtered = routes.filter((r) => r.origin === originId && r.type === typeId);
|
||||
const locSet = new Set<Location>();
|
||||
filtered.forEach((route, index) => {
|
||||
locSet.add(locations.find((l) => l.id === route.destination)!);
|
||||
});
|
||||
return Array.from(locSet);
|
||||
}
|
||||
|
||||
async function execute(interaction: ExecutableInteraction, ctx: CommandContext) {
|
||||
await usePages<QuouteState>(
|
||||
{
|
||||
pages: {
|
||||
main: {
|
||||
key: 'main',
|
||||
type: PageType.MESSAGE,
|
||||
render: (pageCtx) => {
|
||||
console.log('Rendering main page with state:', pageCtx.state.data);
|
||||
return componentsV2({},
|
||||
container({ accent_color: 0x11cc33 },
|
||||
text(`# Quote`),
|
||||
text(`### Service: ${pageCtx.state.data.serviceType?.label ?? ''}`),
|
||||
actionRow(
|
||||
...Object.keys(routeTypes).map((key) => (
|
||||
button(routeTypes[key].short, `type-${key}`, { style: ButtonStyle.SECONDARY })
|
||||
)),
|
||||
),
|
||||
text(`### Origin: ${locations.find((loc) => loc.id === pageCtx.state.data.originId)?.name ?? ''}`),
|
||||
actionRow(
|
||||
stringSelect('route-origin', { placeholder: 'Select Origin' },
|
||||
...uniqueDestinationForOriginAndType(pageCtx.state.data.serviceType.id)
|
||||
.map((loc) => {
|
||||
return { label: loc.name, value: loc.id.toString() };
|
||||
}),
|
||||
),
|
||||
),
|
||||
text(`### Destination: ${locations.find((loc) => loc.id === pageCtx.state.data.destinationId)?.name ?? ''}`),
|
||||
actionRow(
|
||||
stringSelect('route-destination', { placeholder: 'Select Destination' },
|
||||
...uniqueDestinationForOriginAndType(pageCtx.state.data.serviceType.id, pageCtx.state.data.originId)
|
||||
.map((loc) => {
|
||||
return { label: loc.name, value: loc.id.toString() };
|
||||
}),
|
||||
),
|
||||
),
|
||||
text(`### Items:\n${pageCtx.state.data.items ?? ''}`),
|
||||
actionRow(
|
||||
button('Add Items', 'addItems', { style: ButtonStyle.PRIMARY }),
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
},
|
||||
addItems: {
|
||||
key: 'add-items',
|
||||
type: PageType.MODAL,
|
||||
render: () => {
|
||||
return modal('add-items-modal', 'Add Items',
|
||||
label({ label: 'Items', description: 'Discord limits input to 4000 characters. Add more items by submitting multiple times.' },
|
||||
input('items-input', { placeholder: `e.g. Tritanium 22222\nPyerite 8000\nMexallon 2444`, isParagraph: true, required: true }),
|
||||
),
|
||||
);
|
||||
},
|
||||
},
|
||||
},
|
||||
initialPage: 'main',
|
||||
initialStateData: defaultState,
|
||||
ephemeral: true,
|
||||
router: (pageCtx) => {
|
||||
if (pageCtx.custom_id.startsWith('type-')) {
|
||||
const key = pageCtx.custom_id.replace('type-', '');
|
||||
pageCtx.state.data.serviceType = routeTypes[key];
|
||||
return 'main';
|
||||
}
|
||||
if (pageCtx.custom_id === 'route-origin' && pageCtx.interaction.isMessageComponent()) {
|
||||
const data = pageCtx.interaction.data as ComponentInteractionSelectMenuData;
|
||||
pageCtx.state.data.originId = Number.parseInt(data.values[0]);
|
||||
return 'main';
|
||||
}
|
||||
if (pageCtx.custom_id === 'route-destination' && pageCtx.interaction.isMessageComponent()) {
|
||||
const data = pageCtx.interaction.data as ComponentInteractionSelectMenuData;
|
||||
pageCtx.state.data.destinationId = Number.parseInt(data.values[0]);
|
||||
return 'main';
|
||||
}
|
||||
if (pageCtx.custom_id === 'addItems') {
|
||||
return 'addItems';
|
||||
}
|
||||
|
||||
if (pageCtx.custom_id === 'add-items-modal' && pageCtx.interaction.isModalSubmit()) {
|
||||
let items = '';
|
||||
pageCtx.interaction.data.components.forEach((comp) => {
|
||||
if (isModalLabel(comp)) {
|
||||
if (isModalTextInput(comp.component) && componentHasIdPrefix(comp.component, 'items-input')) {
|
||||
items = comp.component.value || items;
|
||||
}
|
||||
}
|
||||
});
|
||||
pageCtx.state.data.items = pageCtx.state.data.items ? `${pageCtx.state.data.items}\n${items}` : items;
|
||||
}
|
||||
return 'main';
|
||||
},
|
||||
},
|
||||
interaction,
|
||||
ctx,
|
||||
);
|
||||
}
|
||||
|
||||
export default createChatCommand(definition, execute);
|
||||
62
src/lib/db/index.ts
Normal file
62
src/lib/db/index.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
import { Database } from 'bun:sqlite';
|
||||
import locationTables, * as locationQueries from './location';
|
||||
export * from './location';
|
||||
export * from './types/routes';
|
||||
|
||||
let db: Database = undefined;
|
||||
const queries = {
|
||||
...locationQueries,
|
||||
};
|
||||
|
||||
function createTables() {
|
||||
locationTables.createTable(db!);
|
||||
}
|
||||
|
||||
function dropTables() {
|
||||
locationTables.dropTable(db!);
|
||||
}
|
||||
|
||||
function close() {
|
||||
if (db) {
|
||||
db.close();
|
||||
db = null;
|
||||
}
|
||||
}
|
||||
|
||||
function initializeDatabase(dbPath: string = process.env.CONCIERGE_DB_PATH || ':memory:') {
|
||||
db = new Database(dbPath);
|
||||
createTables();
|
||||
|
||||
Object.keys(queries).forEach((key) => {
|
||||
if (typeof queries[key] === 'function') {
|
||||
queries[key] = queries[key].bind(null, db);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
type OmitFirstArg<F> = F extends (arg1: any, ...args: infer R) => infer Ret ? (...args: R) => Ret : never;
|
||||
|
||||
type CurriedObject<T, O> = {
|
||||
[K in keyof T]: T[K] extends (arg1: O, ...args: infer R) => infer Ret ? OmitFirstArg<T[K]> : T[K];
|
||||
};
|
||||
|
||||
export type DB = CurriedObject<Omit<typeof queries, 'default'>, Database> & {
|
||||
db: Database;
|
||||
createTables: () => void;
|
||||
dropTables: () => void;
|
||||
close: () => void;
|
||||
};
|
||||
|
||||
export function getDB(): DB {
|
||||
if (!db) {
|
||||
initializeDatabase();
|
||||
}
|
||||
return {
|
||||
...(queries as any),
|
||||
default: undefined,
|
||||
createTables,
|
||||
dropTables,
|
||||
close,
|
||||
db,
|
||||
} as DB;
|
||||
}
|
||||
46
src/lib/db/location.ts
Normal file
46
src/lib/db/location.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import type { Database } from 'bun:sqlite';
|
||||
import { dynamicInsert, dynamicUpdate, remove, select, type QueryOptions } from '@star-kitten/util/sqlite.js';
|
||||
import type { Location } from './types/routes';
|
||||
|
||||
const TABLE_NAME = 'locations';
|
||||
|
||||
export default {
|
||||
createTable: (db: Database) => {
|
||||
db.run(
|
||||
`CREATE TABLE IF NOT EXISTS ${TABLE_NAME} (
|
||||
location_id INTEGER PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
short_name TEXT NOT NULL,
|
||||
structure_type TEXT NOT NULL,
|
||||
system TEXT NOT NULL,
|
||||
supported_route_types INT NOT NULL DEFAULT 0
|
||||
)`,
|
||||
);
|
||||
},
|
||||
|
||||
dropTable: (db: Database) => {
|
||||
db.run(`DROP TABLE IF EXISTS ${TABLE_NAME}`);
|
||||
},
|
||||
};
|
||||
|
||||
export function addLocation(db: Database, location: Location) {
|
||||
return dynamicInsert(db, TABLE_NAME, location);
|
||||
}
|
||||
|
||||
export function updateLocation(db: Database, location: Location) {
|
||||
const id = location.location_id;
|
||||
delete location.location_id;
|
||||
return dynamicUpdate(db, TABLE_NAME, location, 'location_id', id);
|
||||
}
|
||||
|
||||
export function getLocationById(db: Database, location_id: number) {
|
||||
return select<Location>(db, TABLE_NAME, {}, '*', { location_id })?.[0];
|
||||
}
|
||||
|
||||
export function getAllLocations(db: Database, options?: QueryOptions<Location>): Location[] {
|
||||
return select<Location>(db, TABLE_NAME, options);
|
||||
}
|
||||
|
||||
export function removeLocation(db: Database, location_id: number) {
|
||||
return remove<Location>(db, TABLE_NAME, { location_id });
|
||||
}
|
||||
51
src/lib/db/route.ts
Normal file
51
src/lib/db/route.ts
Normal file
@@ -0,0 +1,51 @@
|
||||
import type { Database } from 'bun:sqlite';
|
||||
import { dynamicInsert, dynamicUpdate, remove, select, type QueryOptions } from '@star-kitten/util/sqlite.js';
|
||||
import type { Route } from './types/routes';
|
||||
|
||||
const TABLE_NAME = 'routes';
|
||||
|
||||
export default {
|
||||
createTable: (db: Database) => {
|
||||
db.run(
|
||||
`CREATE TABLE IF NOT EXISTS ${TABLE_NAME} (
|
||||
route_id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
start_location_id INTEGER NOT NULL,
|
||||
end_location_id INTEGER NOT NULL,
|
||||
isk_per_m3 INTEGER NOT NULL,
|
||||
collat_pct REAL NOT NULL,
|
||||
max_volume INTEGER NOT NULL,
|
||||
min_reward INTEGER NOT NULL,
|
||||
expiration INTEGER NOT NULL,
|
||||
completion INTEGER NOT NULL,
|
||||
max_collateral INTEGER
|
||||
)
|
||||
`,
|
||||
);
|
||||
},
|
||||
|
||||
dropTable: (db: Database) => {
|
||||
db.run(`DROP TABLE IF EXISTS ${TABLE_NAME}`);
|
||||
},
|
||||
};
|
||||
|
||||
export function addRoute(db: Database, route: Omit<Route, 'route_id'>) {
|
||||
return dynamicInsert(db, TABLE_NAME, route);
|
||||
}
|
||||
|
||||
export function updateLocation(db: Database, location: Route) {
|
||||
const id = location.route_id;
|
||||
delete location.route_id;
|
||||
return dynamicUpdate(db, TABLE_NAME, location, 'route_id', id);
|
||||
}
|
||||
|
||||
export function getRoutes(db: Database, options?: QueryOptions<Route>) {
|
||||
return select<Route>(db, TABLE_NAME, options);
|
||||
}
|
||||
|
||||
export function getRoute(db: Database, route_id: number) {
|
||||
return select<Route>(db, TABLE_NAME, {}, '*', { route_id })?.[0];
|
||||
}
|
||||
|
||||
export function removeRoute(db: Database, route_id: number) {
|
||||
return remove<Route>(db, TABLE_NAME, { route_id });
|
||||
}
|
||||
10
src/lib/db/types/courier-contract.ts
Normal file
10
src/lib/db/types/courier-contract.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import type { ContractStatus } from '@star-kitten/eve';
|
||||
|
||||
export interface CourierContract {
|
||||
concierge_id: number; // internal id to track this db record
|
||||
contract_id: number; // id of the contract for this courier
|
||||
assigned_to: number;
|
||||
received: string;
|
||||
last_updated: string;
|
||||
status: ContractStatus;
|
||||
}
|
||||
45
src/lib/db/types/routes.ts
Normal file
45
src/lib/db/types/routes.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
export enum RouteType {
|
||||
JF = 1 << 0,
|
||||
DST = 1 << 1,
|
||||
BR = 1 << 2,
|
||||
SMB = 1 << 3,
|
||||
BRIDGE = 1 << 4,
|
||||
}
|
||||
|
||||
export enum StructureType {
|
||||
NPC = 'NPC',
|
||||
Keepstar = 'Keepstar',
|
||||
Fortizar = 'Fortizar',
|
||||
Astrahus = 'Astrahus',
|
||||
Sotiyo = 'Sotiyo',
|
||||
Azbel = 'Azbel',
|
||||
Raitaru = 'Raitaru',
|
||||
Athanor = 'Athanor',
|
||||
Tatara = 'Tatara',
|
||||
}
|
||||
|
||||
export interface Location {
|
||||
location_id: number;
|
||||
name: string;
|
||||
short_name: string;
|
||||
structure_type: StructureType;
|
||||
system: string;
|
||||
supported_route_types: number;
|
||||
}
|
||||
|
||||
export interface Route {
|
||||
route_id: number;
|
||||
start_location_id: number;
|
||||
end_location_id: number;
|
||||
isk_per_m3: number;
|
||||
collat_pct: number; // collateral percent as a float, 1.5 = 1.5%
|
||||
max_volume: number;
|
||||
min_reward: number;
|
||||
expiration: number;
|
||||
completion: number;
|
||||
max_collateral: number;
|
||||
}
|
||||
|
||||
export function locationSupportsType(loc: Location, rt: RouteType) {
|
||||
return (loc.supported_route_types & rt) !== 0;
|
||||
}
|
||||
4
src/main.ts
Normal file
4
src/main.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import { startBot } from '@star-kitten/discord';
|
||||
import './commands';
|
||||
|
||||
startBot();
|
||||
35
tsconfig.json
Normal file
35
tsconfig.json
Normal file
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
// Enable latest features
|
||||
"lib": ["ESNext"],
|
||||
"target": "ESNext",
|
||||
"module": "ESNext",
|
||||
"moduleDetection": "force",
|
||||
|
||||
// Bundler mode
|
||||
"moduleResolution": "bundler",
|
||||
"allowImportingTsExtensions": true,
|
||||
"verbatimModuleSyntax": true,
|
||||
"noEmit": true,
|
||||
|
||||
// Best practices
|
||||
"strict": false,
|
||||
"skipLibCheck": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
|
||||
// Some stricter flags (disabled by default)
|
||||
"noUnusedLocals": false,
|
||||
"noUnusedParameters": false,
|
||||
"noPropertyAccessFromIndexSignature": false,
|
||||
|
||||
"experimentalDecorators": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"composite": true,
|
||||
"paths": {
|
||||
"@/*": ["./src/*"]
|
||||
},
|
||||
"typeRoots": ["src/types", "./node_modules/@types"]
|
||||
},
|
||||
"include": ["src", "types"],
|
||||
"exclude": ["node_modules", "dist", "build", "**/*.test.ts"]
|
||||
}
|
||||
Reference in New Issue
Block a user