diff --git a/Dockerfile b/Dockerfile index 364a334..bace206 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,10 +1,10 @@ # syntax = docker/dockerfile:1 # Adjust NODE_VERSION as desired -ARG NODE_VERSION=18.14.2 -FROM node:${NODE_VERSION}-slim as base +ARG BUN_VERSION=1.0.9 +FROM oven/bun:${BUN_VERSION} as base -LABEL fly_launch_runtime="Node.js" +LABEL fly_launch_runtime="Bun" # Node.js app lives here WORKDIR /app @@ -12,11 +12,6 @@ WORKDIR /app # Set production environment ENV NODE_ENV="production" -# Install pnpm -ARG PNPM_VERSION=8.9.0 -RUN npm install -g pnpm@$PNPM_VERSION - - # Throw-away build stage to reduce size of final image FROM base as build @@ -25,19 +20,12 @@ RUN apt-get update -qq && \ apt-get install -y build-essential pkg-config python-is-python3 # Install node modules -COPY --link .npmrc package.json pnpm-lock.yaml ./ -RUN pnpm install --frozen-lockfile --prod=false +COPY --link .npmrc package.json bun.lockb ./ +RUN bun install --ci # Copy application code COPY --link . . -# Build application -RUN pnpm run build - -# Remove development dependencies -RUN pnpm prune --prod - - # Final stage for app image FROM base @@ -46,4 +34,4 @@ COPY --from=build /app /app # Start the server by default, this can be overwritten at runtime EXPOSE 3000 -CMD [ "pnpm", "run", "start" ] +CMD [ "bun", "start" ] diff --git a/bun.lockb b/bun.lockb new file mode 100755 index 0000000..3d74b83 Binary files /dev/null and b/bun.lockb differ diff --git a/package.json b/package.json index b1ef5a1..e1a293e 100644 --- a/package.json +++ b/package.json @@ -34,10 +34,9 @@ "scripts": { "sapphire": "sapphire", "generate": "sapphire generate", - "build": "tsc", "watch": "tsc -w", - "start": "node dist/index.js", - "dev": "npm run build && npm run start", + "start": "bun run src/index.ts", + "dev": "bun run src/index.ts", "watch:start": "tsc-watch --onSuccess \"npm run start\"", "format": "prettier --write \"src/\"" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml deleted file mode 100644 index b1a2fe1..0000000 --- a/pnpm-lock.yaml +++ /dev/null @@ -1,1082 +0,0 @@ -lockfileVersion: '6.0' - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -dependencies: - '@sapphire/decorators': - specifier: ^6.0.2 - version: 6.0.2 - '@sapphire/discord.js-utilities': - specifier: 7.1.2 - version: 7.1.2 - '@sapphire/framework': - specifier: ^4.8.4 - version: 4.8.4 - '@sapphire/plugin-logger': - specifier: ^3.0.7 - version: 3.0.7 - '@sapphire/utilities': - specifier: ^3.13.0 - version: 3.13.0 - '@skyra/env-utilities': - specifier: ^1.2.1 - version: 1.2.1 - colorette: - specifier: ^2.0.20 - version: 2.0.20 - discord.js: - specifier: ^14.14.1 - version: 14.14.1 - openai: - specifier: ^4.20.1 - version: 4.20.1 - replicate: - specifier: ^0.22.0 - version: 0.22.0 - -devDependencies: - '@flydotio/dockerfile': - specifier: ^0.4.11 - version: 0.4.11 - '@sapphire/cli': - specifier: ^1.9.0 - version: 1.9.0 - '@sapphire/prettier-config': - specifier: ^2.0.0 - version: 2.0.0 - '@sapphire/ts-config': - specifier: ^5.0.0 - version: 5.0.0 - '@types/node': - specifier: ^20.10.2 - version: 20.10.2 - '@types/ws': - specifier: ^8.5.10 - version: 8.5.10 - prettier: - specifier: ^3.1.0 - version: 3.1.0 - tsc-watch: - specifier: ^6.0.4 - version: 6.0.4(typescript@5.3.2) - typescript: - specifier: ^5.3.2 - version: 5.3.2 - -packages: - - /@discordjs/builders@1.7.0: - resolution: {integrity: sha512-GDtbKMkg433cOZur8Dv6c25EHxduNIBsxeHrsRoIM8+AwmEZ8r0tEpckx/sHwTLwQPOF3e2JWloZh9ofCaMfAw==} - engines: {node: '>=16.11.0'} - dependencies: - '@discordjs/formatters': 0.3.3 - '@discordjs/util': 1.0.2 - '@sapphire/shapeshift': 3.9.3 - discord-api-types: 0.37.61 - fast-deep-equal: 3.1.3 - ts-mixer: 6.0.3 - tslib: 2.6.2 - dev: false - - /@discordjs/collection@1.5.3: - resolution: {integrity: sha512-SVb428OMd3WO1paV3rm6tSjM4wC+Kecaa1EUGX7vc6/fddvw/6lg90z4QtCqm21zvVe92vMMDt9+DkIvjXImQQ==} - engines: {node: '>=16.11.0'} - dev: false - - /@discordjs/collection@2.0.0: - resolution: {integrity: sha512-YTWIXLrf5FsrLMycpMM9Q6vnZoR/lN2AWX23/Cuo8uOOtS8eHB2dyQaaGnaF8aZPYnttf2bkLMcXn/j6JUOi3w==} - engines: {node: '>=18'} - dev: false - - /@discordjs/formatters@0.3.3: - resolution: {integrity: sha512-wTcI1Q5cps1eSGhl6+6AzzZkBBlVrBdc9IUhJbijRgVjCNIIIZPgqnUj3ntFODsHrdbGU8BEG9XmDQmgEEYn3w==} - engines: {node: '>=16.11.0'} - dependencies: - discord-api-types: 0.37.61 - dev: false - - /@discordjs/rest@2.2.0: - resolution: {integrity: sha512-nXm9wT8oqrYFRMEqTXQx9DUTeEtXUDMmnUKIhZn6O2EeDY9VCdwj23XCPq7fkqMPKdF7ldAfeVKyxxFdbZl59A==} - engines: {node: '>=16.11.0'} - dependencies: - '@discordjs/collection': 2.0.0 - '@discordjs/util': 1.0.2 - '@sapphire/async-queue': 1.5.0 - '@sapphire/snowflake': 3.5.1 - '@vladfrangu/async_event_emitter': 2.2.4 - discord-api-types: 0.37.61 - magic-bytes.js: 1.5.0 - tslib: 2.6.2 - undici: 5.27.2 - dev: false - - /@discordjs/util@1.0.2: - resolution: {integrity: sha512-IRNbimrmfb75GMNEjyznqM1tkI7HrZOf14njX7tCAAUetyZM1Pr8hX/EK2lxBCOgWDRmigbp24fD1hdMfQK5lw==} - engines: {node: '>=16.11.0'} - dev: false - - /@discordjs/ws@1.0.2: - resolution: {integrity: sha512-+XI82Rm2hKnFwAySXEep4A7Kfoowt6weO6381jgW+wVdTpMS/56qCvoXyFRY0slcv7c/U8My2PwIB2/wEaAh7Q==} - engines: {node: '>=16.11.0'} - dependencies: - '@discordjs/collection': 2.0.0 - '@discordjs/rest': 2.2.0 - '@discordjs/util': 1.0.2 - '@sapphire/async-queue': 1.5.0 - '@types/ws': 8.5.10 - '@vladfrangu/async_event_emitter': 2.2.4 - discord-api-types: 0.37.61 - tslib: 2.6.2 - ws: 8.14.2 - transitivePeerDependencies: - - bufferutil - - utf-8-validate - dev: false - - /@fastify/busboy@2.1.0: - resolution: {integrity: sha512-+KpH+QxZU7O4675t3mnkQKcZZg56u+K/Ct2K+N2AZYNVK8kyeo/bI18tI8aPm3tvNNRyTWfj6s5tnGNlcbQRsA==} - engines: {node: '>=14'} - dev: false - - /@favware/colorette-spinner@1.0.1: - resolution: {integrity: sha512-PPYtcLzhSafdylp8NBOxMCYIcLqTUMNiQc7ciBoAIvxNG2egM+P7e2nNPui5+Svyk89Q+Tnbrp139ZRIIBw3IA==} - engines: {node: '>=v16'} - dependencies: - colorette: 2.0.20 - dev: true - - /@flydotio/dockerfile@0.4.11: - resolution: {integrity: sha512-L52UAfrOhmAn3T4TxpeRofQOSO+Kctg+uraB4nLzo4mvvh+4Z7HYxSi7Dnq0Kirz+xx6fDIc4OMNT1EdaORecA==} - engines: {node: '>=16.0.0'} - hasBin: true - dependencies: - chalk: 5.3.0 - diff: 5.1.0 - ejs: 3.1.9 - shell-quote: 1.8.1 - yargs: 17.7.2 - dev: true - - /@sapphire/async-queue@1.5.0: - resolution: {integrity: sha512-JkLdIsP8fPAdh9ZZjrbHWR/+mZj0wvKS5ICibcLrRI1j84UmLMshx5n9QmL8b95d4onJ2xxiyugTgSAX7AalmA==} - engines: {node: '>=v14.0.0', npm: '>=7.0.0'} - dev: false - - /@sapphire/cli@1.9.0: - resolution: {integrity: sha512-2WNMscS9c1+Y3W3Aem+BdgqgMnkbGrwmGaYr7kH+aGGG2Od12Drkq+umdNzF8DbiAiSaB6CK8sHe6HOqBvXfOA==} - engines: {node: '>=v18'} - hasBin: true - dependencies: - '@favware/colorette-spinner': 1.0.1 - '@sapphire/node-utilities': 1.0.0 - '@sapphire/result': 2.6.4 - colorette: 2.0.20 - commander: 11.1.0 - execa: 8.0.1 - find-up: 5.0.0 - js-yaml: 4.1.0 - prompts: 2.4.2 - tslib: 2.6.2 - dev: true - - /@sapphire/decorators@6.0.2: - resolution: {integrity: sha512-R0bsVvvT/iclElvdglpneIB6UGhzqT3DbMy8b0VHcjSSWArAfxFXiv7mVO/5VeiQduZFhWPgqtTWayKdRYY1NA==} - engines: {node: '>=v14.0.0', npm: '>=7.0.0'} - dependencies: - tslib: 2.6.2 - dev: false - - /@sapphire/discord-utilities@3.2.0: - resolution: {integrity: sha512-gKgTkWIBgkG0c+V3ALXeoD7XeciAYQtHNewjltSMaxCLF/wsy6NFj6xxqdEeSJMF40tcfUJ7F44r2DR5r3K8Eg==} - engines: {node: '>=v14.0.0', npm: '>=7.0.0'} - dependencies: - discord-api-types: 0.37.65 - dev: false - - /@sapphire/discord.js-utilities@7.1.2: - resolution: {integrity: sha512-Ly/mtykmX7lak4+fzVbDvch0xnlAwDIDGZGg9mGuZVHdA4sINWcVoCNulI+OqoZWdLCfUKph32KvXGESzriD7A==} - engines: {node: '>=16.6.0', npm: '>=7.0.0'} - dependencies: - '@sapphire/discord-utilities': 3.2.0 - '@sapphire/duration': 1.1.0 - '@sapphire/utilities': 3.13.0 - tslib: 2.6.2 - dev: false - - /@sapphire/duration@1.1.0: - resolution: {integrity: sha512-ATb2pWPLcSgG7bzvT6MglUcDexFSufr2FLXUmhipWGFtZbvDhkopGBIuHyzoGy7LZvL8UY5T6pRLNdFv5pl/Lg==} - engines: {node: '>=v14.0.0', npm: '>=7.0.0'} - dev: false - - /@sapphire/framework@4.8.4: - resolution: {integrity: sha512-ErnsCcvgtC/8/KS2gvV88EFtN4uteFzLKDfEjYebdXU7AVr9AoOBJtymYu42GHVZJ3eaYKGadUBJn6015LxaLw==} - engines: {node: '>=v18', npm: '>=7'} - dependencies: - '@discordjs/builders': 1.7.0 - '@sapphire/discord-utilities': 3.2.0 - '@sapphire/discord.js-utilities': 7.1.2 - '@sapphire/lexure': 1.1.5 - '@sapphire/pieces': 3.10.0 - '@sapphire/ratelimits': 2.4.7 - '@sapphire/result': 2.6.4 - '@sapphire/stopwatch': 1.5.0 - '@sapphire/utilities': 3.13.0 - dev: false - - /@sapphire/lexure@1.1.5: - resolution: {integrity: sha512-afVTCLHezlyvdvvOcEeCzMA05l1yje9axtY7gWQpDcppOazskYPgGMVCdAbfHz5BsyABMZYT2MznY+phEgFc8Q==} - engines: {node: '>=v14.0.0', npm: '>=7.0.0'} - dependencies: - '@sapphire/result': 2.6.4 - dev: false - - /@sapphire/node-utilities@1.0.0: - resolution: {integrity: sha512-xFC4UyzSKs6juyFtsUV4VNybg0KIpwaThED2TH3TGtNT5b0VFpILTXQtqXpPf+Rfmj+O/mLCm319xy4ohsQqxQ==} - engines: {node: '>=v16.0.0', npm: '>=7.0.0'} - dev: true - - /@sapphire/pieces@3.10.0: - resolution: {integrity: sha512-iBaux50dA+VYjtBqmaceWcskdmw7ua51ojEPkyaSJyg2t9ln/Wc9NqYoQheRCWltZeDTERCUBIYYMqDuCs1Okw==} - engines: {node: '>=v14.0.0', npm: '>=7.0.0'} - dependencies: - '@discordjs/collection': 1.5.3 - '@sapphire/utilities': 3.13.0 - tslib: 2.6.2 - dev: false - - /@sapphire/plugin-logger@3.0.7: - resolution: {integrity: sha512-QNQRHMgvyxhBNdYBktIfAQvNdsvzYd6vVWCvnggrcN56mvXJyolZaPkDcUNh3PdtjcB7XTChpynbLlTby2vsyQ==} - engines: {node: '>=v18', npm: '>=7'} - dependencies: - '@sapphire/timestamp': 1.0.1 - colorette: 2.0.20 - dev: false - - /@sapphire/prettier-config@2.0.0: - resolution: {integrity: sha512-Vie8KR5zQ6sbEP4+biW/IR7k55saGfZkTSuRlgvxCBKb4SBJdRWcOBI80i+JxMVIDDZKgXlgYnXEST+FgZiWXA==} - engines: {node: '>=v14.0.0', npm: '>=7.0.0'} - dependencies: - prettier: 3.1.0 - dev: true - - /@sapphire/ratelimits@2.4.7: - resolution: {integrity: sha512-IJQySiK+A8P4E+0oW2TGDy4RBjMsw3hccFL0y4kjQ2VZNzPDHJSYR4Pb1TzlG6V9YTVdCNWJODFXXyVn3tEQ/A==} - engines: {node: '>=v14.0.0', npm: '>=7.0.0'} - dev: false - - /@sapphire/result@2.6.4: - resolution: {integrity: sha512-o6rAnNbtumhR4Iy9t1p3xtOG9WtfO2OyyyaBrGUNThmhqf1cwvl5CO3/E0Hd66qdkuSqpJqC9TnnGzTmSoDd6A==} - engines: {node: '>=v14.0.0', npm: '>=7.0.0'} - - /@sapphire/shapeshift@3.9.3: - resolution: {integrity: sha512-WzKJSwDYloSkHoBbE8rkRW8UNKJiSRJ/P8NqJ5iVq7U2Yr/kriIBx2hW+wj2Z5e5EnXL1hgYomgaFsdK6b+zqQ==} - engines: {node: '>=v14.0.0', npm: '>=7.0.0'} - dependencies: - fast-deep-equal: 3.1.3 - lodash: 4.17.21 - dev: false - - /@sapphire/snowflake@3.5.1: - resolution: {integrity: sha512-BxcYGzgEsdlG0dKAyOm0ehLGm2CafIrfQTZGWgkfKYbj+pNNsorZ7EotuZukc2MT70E0UbppVbtpBrqpzVzjNA==} - engines: {node: '>=v14.0.0', npm: '>=7.0.0'} - dev: false - - /@sapphire/stopwatch@1.5.0: - resolution: {integrity: sha512-DtyKugdy3JTqm6JnEepTY64fGJAqlusDVrlrzifEgSCfGYCqpvB+SBldkWtDH+z+zLcp+PyaFLq7xpVfkhmvGg==} - engines: {node: '>=v14.0.0', npm: '>=7.0.0'} - dependencies: - tslib: 2.6.2 - dev: false - - /@sapphire/timestamp@1.0.1: - resolution: {integrity: sha512-uLg+rBFuBiaQY/pFGDDzZSOH2cfv4ONIB7zQGNuRCTpYKBW/iIhRBIZjJZyn8NVkXQhVi+Q94DI4i6gDhYVs7w==} - engines: {node: '>=v14.0.0', npm: '>=7.0.0'} - dev: false - - /@sapphire/ts-config@5.0.0: - resolution: {integrity: sha512-E4JfpCK/OxaH8lYEP0+xbRUeIBanEOkA5IUtvj+Uib2TG2p7H0Sb1mF1fpmf0ICyDaOu9/201Il/ymV3cr/isw==} - engines: {node: '>=v16.0.0', npm: '>=8.0.0'} - dependencies: - tslib: 2.6.2 - typescript: 5.3.2 - dev: true - - /@sapphire/utilities@3.13.0: - resolution: {integrity: sha512-BD5ycPjZX5dXxrAb90dJTY8ukpPVBXgU17gA5ghK2memS4hwAzFYpvK+R+6zh4d6HYIKVuqrVhGXjvZenAa/Aw==} - engines: {node: '>=v14.0.0', npm: '>=7.0.0'} - dev: false - - /@skyra/env-utilities@1.2.1: - resolution: {integrity: sha512-blyw0zCtrdP5SEiPAw62UuCd69bXdIBTtyzCXamVOcN2wqXt8HWkYrz8IdmZ2cvgnYIXpz7hzAmrIi3fGG7zzQ==} - engines: {node: '>=16.9.0', npm: '>=8.0.0'} - dependencies: - dotenv: 16.3.1 - dotenv-expand: 10.0.0 - dev: false - - /@types/node-fetch@2.6.9: - resolution: {integrity: sha512-bQVlnMLFJ2d35DkPNjEPmd9ueO/rh5EiaZt2bhqiSarPjZIuIV6bPQVqcrEyvNo+AfTrRGVazle1tl597w3gfA==} - dependencies: - '@types/node': 20.10.2 - form-data: 4.0.0 - dev: false - - /@types/node@18.19.1: - resolution: {integrity: sha512-mZJ9V11gG5Vp0Ox2oERpeFDl+JvCwK24PGy76vVY/UgBtjwJWc5rYBThFxmbnYOm9UPZNm6wEl/sxHt2SU7x9A==} - dependencies: - undici-types: 5.26.5 - dev: false - - /@types/node@20.10.2: - resolution: {integrity: sha512-37MXfxkb0vuIlRKHNxwCkb60PNBpR94u4efQuN4JgIAm66zfCDXGSAFCef9XUWFovX2R1ok6Z7MHhtdVXXkkIw==} - dependencies: - undici-types: 5.26.5 - - /@types/ws@8.5.10: - resolution: {integrity: sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==} - dependencies: - '@types/node': 20.10.2 - - /@types/ws@8.5.9: - resolution: {integrity: sha512-jbdrY0a8lxfdTp/+r7Z4CkycbOFN8WX+IOchLJr3juT/xzbJ8URyTVSJ/hvNdadTgM1mnedb47n+Y31GsFnQlg==} - dependencies: - '@types/node': 20.10.2 - dev: false - - /@vladfrangu/async_event_emitter@2.2.4: - resolution: {integrity: sha512-ButUPz9E9cXMLgvAW8aLAKKJJsPu1dY1/l/E8xzLFuysowXygs6GBcyunK9rnGC4zTsnIc2mQo71rGw9U+Ykug==} - engines: {node: '>=v14.0.0', npm: '>=7.0.0'} - dev: false - - /abort-controller@3.0.0: - resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} - engines: {node: '>=6.5'} - dependencies: - event-target-shim: 5.0.1 - dev: false - - /agentkeepalive@4.5.0: - resolution: {integrity: sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==} - engines: {node: '>= 8.0.0'} - dependencies: - humanize-ms: 1.2.1 - dev: false - - /ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} - dev: true - - /ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} - dependencies: - color-convert: 2.0.1 - dev: true - - /argparse@2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - dev: true - - /async@3.2.5: - resolution: {integrity: sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==} - dev: true - - /asynckit@0.4.0: - resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - dev: false - - /balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - dev: true - - /base-64@0.1.0: - resolution: {integrity: sha512-Y5gU45svrR5tI2Vt/X9GPd3L0HNIKzGu202EjxrXMpuc2V2CiKgemAbUUsqYmZJvPtCXoUKjNZwBJzsNScUbXA==} - dev: false - - /brace-expansion@1.1.11: - resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} - dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 - dev: true - - /brace-expansion@2.0.1: - resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} - dependencies: - balanced-match: 1.0.2 - dev: true - - /chalk@4.1.2: - resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} - engines: {node: '>=10'} - dependencies: - ansi-styles: 4.3.0 - supports-color: 7.2.0 - dev: true - - /chalk@5.3.0: - resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} - engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} - dev: true - - /charenc@0.0.2: - resolution: {integrity: sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==} - dev: false - - /cliui@8.0.1: - resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} - engines: {node: '>=12'} - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 7.0.0 - dev: true - - /color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} - dependencies: - color-name: 1.1.4 - dev: true - - /color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - dev: true - - /colorette@2.0.20: - resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} - - /combined-stream@1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} - dependencies: - delayed-stream: 1.0.0 - dev: false - - /commander@11.1.0: - resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} - engines: {node: '>=16'} - dev: true - - /concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - dev: true - - /cross-spawn@7.0.3: - resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} - engines: {node: '>= 8'} - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - dev: true - - /crypt@0.0.2: - resolution: {integrity: sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==} - dev: false - - /delayed-stream@1.0.0: - resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} - engines: {node: '>=0.4.0'} - dev: false - - /diff@5.1.0: - resolution: {integrity: sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==} - engines: {node: '>=0.3.1'} - dev: true - - /digest-fetch@1.3.0: - resolution: {integrity: sha512-CGJuv6iKNM7QyZlM2T3sPAdZWd/p9zQiRNS9G+9COUCwzWFTs0Xp8NF5iePx7wtvhDykReiRRrSeNb4oMmB8lA==} - dependencies: - base-64: 0.1.0 - md5: 2.3.0 - dev: false - - /discord-api-types@0.37.61: - resolution: {integrity: sha512-o/dXNFfhBpYHpQFdT6FWzeO7pKc838QeeZ9d91CfVAtpr5XLK4B/zYxQbYgPdoMiTDvJfzcsLW5naXgmHGDNXw==} - dev: false - - /discord-api-types@0.37.65: - resolution: {integrity: sha512-CQHW3Nu04LEHIj1Xps/sfGhTdrowilxnek2tirpLhwvrmgmLr1C6A+4JFLs+0kJMH2IX2QgDyA9GfNehqN+xPQ==} - dev: false - - /discord.js@14.14.1: - resolution: {integrity: sha512-/hUVzkIerxKHyRKopJy5xejp4MYKDPTszAnpYxzVVv4qJYf+Tkt+jnT2N29PIPschicaEEpXwF2ARrTYHYwQ5w==} - engines: {node: '>=16.11.0'} - dependencies: - '@discordjs/builders': 1.7.0 - '@discordjs/collection': 1.5.3 - '@discordjs/formatters': 0.3.3 - '@discordjs/rest': 2.2.0 - '@discordjs/util': 1.0.2 - '@discordjs/ws': 1.0.2 - '@sapphire/snowflake': 3.5.1 - '@types/ws': 8.5.9 - discord-api-types: 0.37.61 - fast-deep-equal: 3.1.3 - lodash.snakecase: 4.1.1 - tslib: 2.6.2 - undici: 5.27.2 - ws: 8.14.2 - transitivePeerDependencies: - - bufferutil - - utf-8-validate - dev: false - - /dotenv-expand@10.0.0: - resolution: {integrity: sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A==} - engines: {node: '>=12'} - dev: false - - /dotenv@16.3.1: - resolution: {integrity: sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==} - engines: {node: '>=12'} - dev: false - - /duplexer@0.1.2: - resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} - dev: true - - /ejs@3.1.9: - resolution: {integrity: sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==} - engines: {node: '>=0.10.0'} - hasBin: true - dependencies: - jake: 10.8.7 - dev: true - - /emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - dev: true - - /escalade@3.1.1: - resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} - engines: {node: '>=6'} - dev: true - - /event-stream@3.3.4: - resolution: {integrity: sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==} - dependencies: - duplexer: 0.1.2 - from: 0.1.7 - map-stream: 0.1.0 - pause-stream: 0.0.11 - split: 0.3.3 - stream-combiner: 0.0.4 - through: 2.3.8 - dev: true - - /event-target-shim@5.0.1: - resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} - engines: {node: '>=6'} - dev: false - - /execa@8.0.1: - resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} - engines: {node: '>=16.17'} - dependencies: - cross-spawn: 7.0.3 - get-stream: 8.0.1 - human-signals: 5.0.0 - is-stream: 3.0.0 - merge-stream: 2.0.0 - npm-run-path: 5.1.0 - onetime: 6.0.0 - signal-exit: 4.1.0 - strip-final-newline: 3.0.0 - dev: true - - /fast-deep-equal@3.1.3: - resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - dev: false - - /filelist@1.0.4: - resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} - dependencies: - minimatch: 5.1.6 - dev: true - - /find-up@5.0.0: - resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} - engines: {node: '>=10'} - dependencies: - locate-path: 6.0.0 - path-exists: 4.0.0 - dev: true - - /form-data-encoder@1.7.2: - resolution: {integrity: sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==} - dev: false - - /form-data@4.0.0: - resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} - engines: {node: '>= 6'} - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - mime-types: 2.1.35 - dev: false - - /formdata-node@4.4.1: - resolution: {integrity: sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==} - engines: {node: '>= 12.20'} - dependencies: - node-domexception: 1.0.0 - web-streams-polyfill: 4.0.0-beta.3 - dev: false - - /from@0.1.7: - resolution: {integrity: sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==} - dev: true - - /get-caller-file@2.0.5: - resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} - engines: {node: 6.* || 8.* || >= 10.*} - dev: true - - /get-stream@8.0.1: - resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} - engines: {node: '>=16'} - dev: true - - /has-flag@4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} - dev: true - - /human-signals@5.0.0: - resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} - engines: {node: '>=16.17.0'} - dev: true - - /humanize-ms@1.2.1: - resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} - dependencies: - ms: 2.1.3 - dev: false - - /is-buffer@1.1.6: - resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==} - dev: false - - /is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} - dev: true - - /is-stream@3.0.0: - resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dev: true - - /isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - dev: true - - /jake@10.8.7: - resolution: {integrity: sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==} - engines: {node: '>=10'} - hasBin: true - dependencies: - async: 3.2.5 - chalk: 4.1.2 - filelist: 1.0.4 - minimatch: 3.1.2 - dev: true - - /js-yaml@4.1.0: - resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} - hasBin: true - dependencies: - argparse: 2.0.1 - dev: true - - /kleur@3.0.3: - resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} - engines: {node: '>=6'} - dev: true - - /locate-path@6.0.0: - resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} - engines: {node: '>=10'} - dependencies: - p-locate: 5.0.0 - dev: true - - /lodash.snakecase@4.1.1: - resolution: {integrity: sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==} - dev: false - - /lodash@4.17.21: - resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - dev: false - - /magic-bytes.js@1.5.0: - resolution: {integrity: sha512-wJkXvutRbNWcc37tt5j1HyOK1nosspdh3dj6LUYYAvF6JYNqs53IfRvK9oEpcwiDA1NdoIi64yAMfdivPeVAyw==} - dev: false - - /map-stream@0.1.0: - resolution: {integrity: sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==} - dev: true - - /md5@2.3.0: - resolution: {integrity: sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==} - dependencies: - charenc: 0.0.2 - crypt: 0.0.2 - is-buffer: 1.1.6 - dev: false - - /merge-stream@2.0.0: - resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} - dev: true - - /mime-db@1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} - engines: {node: '>= 0.6'} - dev: false - - /mime-types@2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} - engines: {node: '>= 0.6'} - dependencies: - mime-db: 1.52.0 - dev: false - - /mimic-fn@4.0.0: - resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} - engines: {node: '>=12'} - dev: true - - /minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} - dependencies: - brace-expansion: 1.1.11 - dev: true - - /minimatch@5.1.6: - resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} - engines: {node: '>=10'} - dependencies: - brace-expansion: 2.0.1 - dev: true - - /ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - dev: false - - /node-cleanup@2.1.2: - resolution: {integrity: sha512-qN8v/s2PAJwGUtr1/hYTpNKlD6Y9rc4p8KSmJXyGdYGZsDGKXrGThikLFP9OCHFeLeEpQzPwiAtdIvBLqm//Hw==} - dev: true - - /node-domexception@1.0.0: - resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} - engines: {node: '>=10.5.0'} - dev: false - - /node-fetch@2.7.0: - resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} - engines: {node: 4.x || >=6.0.0} - peerDependencies: - encoding: ^0.1.0 - peerDependenciesMeta: - encoding: - optional: true - dependencies: - whatwg-url: 5.0.0 - dev: false - - /npm-run-path@5.1.0: - resolution: {integrity: sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - path-key: 4.0.0 - dev: true - - /onetime@6.0.0: - resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} - engines: {node: '>=12'} - dependencies: - mimic-fn: 4.0.0 - dev: true - - /openai@4.20.1: - resolution: {integrity: sha512-Dd3q8EvINfganZFtg6V36HjrMaihqRgIcKiHua4Nq9aw/PxOP48dhbsk8x5klrxajt5Lpnc1KTOG5i1S6BKAJA==} - hasBin: true - dependencies: - '@types/node': 18.19.1 - '@types/node-fetch': 2.6.9 - abort-controller: 3.0.0 - agentkeepalive: 4.5.0 - digest-fetch: 1.3.0 - form-data-encoder: 1.7.2 - formdata-node: 4.4.1 - node-fetch: 2.7.0 - web-streams-polyfill: 3.2.1 - transitivePeerDependencies: - - encoding - dev: false - - /p-limit@3.1.0: - resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} - engines: {node: '>=10'} - dependencies: - yocto-queue: 0.1.0 - dev: true - - /p-locate@5.0.0: - resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} - engines: {node: '>=10'} - dependencies: - p-limit: 3.1.0 - dev: true - - /path-exists@4.0.0: - resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} - engines: {node: '>=8'} - dev: true - - /path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} - dev: true - - /path-key@4.0.0: - resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} - engines: {node: '>=12'} - dev: true - - /pause-stream@0.0.11: - resolution: {integrity: sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==} - dependencies: - through: 2.3.8 - dev: true - - /prettier@3.1.0: - resolution: {integrity: sha512-TQLvXjq5IAibjh8EpBIkNKxO749UEWABoiIZehEPiY4GNpVdhaFKqSTu+QrlU6D2dPAfubRmtJTi4K4YkQ5eXw==} - engines: {node: '>=14'} - hasBin: true - dev: true - - /prompts@2.4.2: - resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} - engines: {node: '>= 6'} - dependencies: - kleur: 3.0.3 - sisteransi: 1.0.5 - dev: true - - /ps-tree@1.2.0: - resolution: {integrity: sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA==} - engines: {node: '>= 0.10'} - hasBin: true - dependencies: - event-stream: 3.3.4 - dev: true - - /replicate@0.22.0: - resolution: {integrity: sha512-jUfvYCcnnzG0l3NzgNLUBRfv7e5ZcZpBWzxGqx3v8bkvJmY0jK19JRtFtBgJFRBye61ggH1zC9cubGkburF82g==} - engines: {git: '>=2.11.0', node: '>=18.0.0', npm: '>=7.19.0', yarn: '>=1.7.0'} - dev: false - - /require-directory@2.1.1: - resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} - engines: {node: '>=0.10.0'} - dev: true - - /shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} - dependencies: - shebang-regex: 3.0.0 - dev: true - - /shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} - dev: true - - /shell-quote@1.8.1: - resolution: {integrity: sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==} - dev: true - - /signal-exit@4.1.0: - resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} - engines: {node: '>=14'} - dev: true - - /sisteransi@1.0.5: - resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} - dev: true - - /split@0.3.3: - resolution: {integrity: sha512-wD2AeVmxXRBoX44wAycgjVpMhvbwdI2aZjCkvfNcH1YqHQvJVa1duWc73OyVGJUc05fhFaTZeQ/PYsrmyH0JVA==} - dependencies: - through: 2.3.8 - dev: true - - /stream-combiner@0.0.4: - resolution: {integrity: sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==} - dependencies: - duplexer: 0.1.2 - dev: true - - /string-argv@0.3.2: - resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} - engines: {node: '>=0.6.19'} - dev: true - - /string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} - dependencies: - emoji-regex: 8.0.0 - is-fullwidth-code-point: 3.0.0 - strip-ansi: 6.0.1 - dev: true - - /strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} - dependencies: - ansi-regex: 5.0.1 - dev: true - - /strip-final-newline@3.0.0: - resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} - engines: {node: '>=12'} - dev: true - - /supports-color@7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} - dependencies: - has-flag: 4.0.0 - dev: true - - /through@2.3.8: - resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} - dev: true - - /tr46@0.0.3: - resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} - dev: false - - /ts-mixer@6.0.3: - resolution: {integrity: sha512-k43M7uCG1AkTyxgnmI5MPwKoUvS/bRvLvUb7+Pgpdlmok8AoqmUaZxUUw8zKM5B1lqZrt41GjYgnvAi0fppqgQ==} - dev: false - - /tsc-watch@6.0.4(typescript@5.3.2): - resolution: {integrity: sha512-cHvbvhjO86w2aGlaHgSCeQRl+Aqw6X6XN4sQMPZKF88GoP30O+oTuh5lRIJr5pgFWrRpF1AgXnJJ2DoFEIPHyg==} - engines: {node: '>=12.12.0'} - hasBin: true - peerDependencies: - typescript: '*' - dependencies: - cross-spawn: 7.0.3 - node-cleanup: 2.1.2 - ps-tree: 1.2.0 - string-argv: 0.3.2 - typescript: 5.3.2 - dev: true - - /tslib@2.6.2: - resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} - - /typescript@5.3.2: - resolution: {integrity: sha512-6l+RyNy7oAHDfxC4FzSJcz9vnjTKxrLpDG5M2Vu4SHRVNg6xzqZp6LYSR9zjqQTu8DU/f5xwxUdADOkbrIX2gQ==} - engines: {node: '>=14.17'} - hasBin: true - dev: true - - /undici-types@5.26.5: - resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} - - /undici@5.27.2: - resolution: {integrity: sha512-iS857PdOEy/y3wlM3yRp+6SNQQ6xU0mmZcwRSriqk+et/cwWAtwmIGf6WkoDN2EK/AMdCO/dfXzIwi+rFMrjjQ==} - engines: {node: '>=14.0'} - dependencies: - '@fastify/busboy': 2.1.0 - dev: false - - /web-streams-polyfill@3.2.1: - resolution: {integrity: sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==} - engines: {node: '>= 8'} - dev: false - - /web-streams-polyfill@4.0.0-beta.3: - resolution: {integrity: sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==} - engines: {node: '>= 14'} - dev: false - - /webidl-conversions@3.0.1: - resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} - dev: false - - /whatwg-url@5.0.0: - resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} - dependencies: - tr46: 0.0.3 - webidl-conversions: 3.0.1 - dev: false - - /which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true - dependencies: - isexe: 2.0.0 - dev: true - - /wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - dev: true - - /ws@8.14.2: - resolution: {integrity: sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==} - engines: {node: '>=10.0.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: '>=5.0.2' - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - dev: false - - /y18n@5.0.8: - resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} - engines: {node: '>=10'} - dev: true - - /yargs-parser@21.1.1: - resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} - engines: {node: '>=12'} - dev: true - - /yargs@17.7.2: - resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} - engines: {node: '>=12'} - dependencies: - cliui: 8.0.1 - escalade: 3.1.1 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - string-width: 4.2.3 - y18n: 5.0.8 - yargs-parser: 21.1.1 - dev: true - - /yocto-queue@0.1.0: - resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} - engines: {node: '>=10'} - dev: true diff --git a/src/commands/ask.ts b/src/commands/ask.ts index 1d43803..19fb2b7 100644 --- a/src/commands/ask.ts +++ b/src/commands/ask.ts @@ -1,19 +1,19 @@ -import { ApplyOptions } from '@sapphire/decorators'; -import { Args, Command } from '@sapphire/framework'; -import { AttachmentBuilder, Message, blockQuote, codeBlock } from 'discord.js'; +import { Command, container } from '@sapphire/framework'; +import { AttachmentBuilder, blockQuote, codeBlock } from 'discord.js'; import OpenAI from 'openai'; const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY }); -// @ts-ignore -@ApplyOptions({ - description: 'You can ACTUALLY ask Himbot something! So cool!', - options: ['prompt'] -}) -export class UserCommand extends Command { - // Register Chat Input and Context Menu command +export class AskCommand extends Command { + public constructor(context: Command.LoaderContext) { + super(context, { + description: 'You can ACTUALLY ask Himbot something! So cool!', + options: ['prompt'] + }); + } + public override registerApplicationCommands(registry: Command.Registry) { registry.registerChatInputCommand((builder) => builder @@ -25,21 +25,10 @@ export class UserCommand extends Command { ); } - // Message command - public async messageRun(message: Message, args: Args) { - return this.ask(message, args.getOption('prompt') || message.content.split('!ask ')[1]); - } - - // Chat Input (slash) command public async chatInputRun(interaction: Command.ChatInputCommandInteraction) { - return this.ask(interaction, interaction.options.getString('prompt') || 'NOTHING'); - } + const prompt = interaction.options.getString('prompt'); - private async ask(interactionOrMessage: Message | Command.ChatInputCommandInteraction | Command.ContextMenuCommandInteraction, prompt: string) { - const askMessage = - interactionOrMessage instanceof Message - ? await interactionOrMessage.channel.send({ content: '🤔 Thinking... 🤔' }) - : await interactionOrMessage.reply({ content: '🤔 Thinking... 🤔', fetchReply: true }); + await interaction.reply({ content: '🤔 Thinking... 🤔', fetchReply: true }); const chatCompletion = await openai.chat.completions.create({ model: 'gpt-4-1106-preview', @@ -64,17 +53,7 @@ export class UserCommand extends Command { ); } - if (interactionOrMessage instanceof Message) { - return askMessage.edit({ - content: - content.length < 2000 - ? content - : `Discord only allows messages with 2000 characters or less. Please see your response in the attached file!`, - files: messageAttachment - }); - } - - return interactionOrMessage.editReply({ + return interaction.editReply({ content: content.length < 2000 ? content @@ -83,3 +62,9 @@ export class UserCommand extends Command { }); } } + +void container.stores.loadPiece({ + store: 'commands', + name: 'ask', + piece: AskCommand +}); diff --git a/src/commands/borf.ts b/src/commands/borf.ts index 948a865..c97705f 100644 --- a/src/commands/borf.ts +++ b/src/commands/borf.ts @@ -1,12 +1,12 @@ -import { ApplyOptions } from '@sapphire/decorators'; -import { Command } from '@sapphire/framework'; -import { Message } from 'discord.js'; +import { Command, container } from '@sapphire/framework'; + +export class BorfCommand extends Command { + public constructor(context: Command.LoaderContext) { + super(context, { + description: 'Borf! Borf!' + }); + } -// @ts-ignore -@ApplyOptions({ - description: 'Borf! Borf!' -}) -export class UserCommand extends Command { // Register Chat Input and Context Menu command public override registerApplicationCommands(registry: Command.Registry) { // Register Chat Input command @@ -16,27 +16,20 @@ export class UserCommand extends Command { }); } - // Message command - public async messageRun(message: Message) { - return this.sendBorf(message); - } - // Chat Input (slash) command public async chatInputRun(interaction: Command.ChatInputCommandInteraction) { - return this.sendBorf(interaction); - } - - private async sendBorf(interactionOrMessage: Message | Command.ChatInputCommandInteraction | Command.ContextMenuCommandInteraction) { const dogResponse = await fetch('https://dog.ceo/api/breeds/image/random'); const dogData = (await dogResponse.json()) as { message: string; status: string }; - interactionOrMessage instanceof Message - ? await interactionOrMessage.channel.send({ - content: dogData?.status === 'success' ? dogData.message : 'Error: I had troubles fetching perfect puppies for you... :(' - }) - : await interactionOrMessage.reply({ - content: dogData.status === 'success' ? dogData.message : 'Error: I had troubles fetching perfect puppies for you... :(', - fetchReply: true - }); + await interaction.reply({ + content: dogData.status === 'success' ? dogData.message : 'Error: I had troubles fetching perfect puppies for you... :(', + fetchReply: true + }); } } + +void container.stores.loadPiece({ + store: 'commands', + name: 'borf', + piece: BorfCommand +}); diff --git a/src/commands/hdpic.ts b/src/commands/hdpic.ts index 25ea176..7fa7e79 100644 --- a/src/commands/hdpic.ts +++ b/src/commands/hdpic.ts @@ -1,23 +1,23 @@ -import { ApplyOptions } from '@sapphire/decorators'; -import { Args, BucketScope, Command } from '@sapphire/framework'; -import { AttachmentBuilder, Message } from 'discord.js'; +import { BucketScope, Command, container } from '@sapphire/framework'; +import { AttachmentBuilder } from 'discord.js'; import OpenAI from 'openai'; const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY }); -// @ts-ignore -@ApplyOptions({ - description: 'Generate an image using OpenAI! Cooldown of 10 Minutes due to cost!', - options: ['prompt'], - cooldownDelay: 480_000, - cooldownLimit: 1, - // Yes... I did hardcode myself. - cooldownFilteredUsers: ['83679718401904640'], - cooldownScope: BucketScope.User -}) -export class UserCommand extends Command { +export class HDPicCommand extends Command { + public constructor(context: Command.LoaderContext) { + super(context, { + description: 'Generate an image using OpenAI! Cooldown of 10 Minutes due to cost!', + options: ['prompt'], + cooldownDelay: 480_000, + cooldownLimit: 1, + cooldownFilteredUsers: ['83679718401904640'], + cooldownScope: BucketScope.User + }); + } + // Register Chat Input and Context Menu command public override registerApplicationCommands(registry: Command.Registry) { registry.registerChatInputCommand((builder) => @@ -30,21 +30,11 @@ export class UserCommand extends Command { ); } - // Message command - public async messageRun(message: Message, args: Args) { - return this.pic(message, args.getOption('prompt') || 'NOTHING'); - } - // Chat Input (slash) command public async chatInputRun(interaction: Command.ChatInputCommandInteraction) { - return this.pic(interaction, interaction.options.getString('prompt') || 'NOTHING'); - } + const prompt = interaction.options.getString('prompt') || ''; - private async pic(interactionOrMessage: Message | Command.ChatInputCommandInteraction | Command.ContextMenuCommandInteraction, prompt: string) { - const askMessage = - interactionOrMessage instanceof Message - ? await interactionOrMessage.channel.send({ content: '🤔 Thinking... 🤔' }) - : await interactionOrMessage.reply({ content: '🤔 Thinking... 🤔', fetchReply: true }); + await interaction.reply({ content: '🤔 Thinking... 🤔', fetchReply: true }); try { const response = await openai.images.generate({ @@ -70,22 +60,20 @@ export class UserCommand extends Command { const content = `Prompt: ${prompt}:`; - if (interactionOrMessage instanceof Message) { - return askMessage.edit({ content, files: imageAttachment }); - } - - return interactionOrMessage.editReply({ + return interaction.editReply({ content, files: imageAttachment }); } catch (error) { const content = "Sorry, I can't complete the prompt for: " + prompt + '\n' + error; - if (interactionOrMessage instanceof Message) { - return askMessage.edit({ content }); - } - - return interactionOrMessage.editReply({ content }); + return interaction.editReply({ content }); } } } + +void container.stores.loadPiece({ + store: 'commands', + name: 'hdpic', + piece: HDPicCommand +}); diff --git a/src/commands/hdtts.ts b/src/commands/hdtts.ts index 5833033..10cc4f7 100644 --- a/src/commands/hdtts.ts +++ b/src/commands/hdtts.ts @@ -1,23 +1,24 @@ -import { ApplyOptions } from '@sapphire/decorators'; -import { Args, BucketScope, Command } from '@sapphire/framework'; -import { AttachmentBuilder, Message, MessageFlags } from 'discord.js'; +import { BucketScope, Command, container } from '@sapphire/framework'; +import { AttachmentBuilder, MessageFlags } from 'discord.js'; import OpenAI from 'openai'; const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY }); -// @ts-ignore -@ApplyOptions({ - description: 'Generate "HD" TTS every 2 minutes!', - options: ['prompt'], - cooldownDelay: 200_000, - cooldownLimit: 1, - // Yes... I did hardcode myself. - cooldownFilteredUsers: ['83679718401904640'], - cooldownScope: BucketScope.User -}) -export class UserCommand extends Command { +export class HDTTSCommand extends Command { + public constructor(context: Command.LoaderContext) { + super(context, { + description: 'Generate "HD" TTS every 2 minutes!', + options: ['prompt'], + cooldownDelay: 200_000, + cooldownLimit: 1, + // Yes... I did hardcode myself. + cooldownFilteredUsers: ['83679718401904640'], + cooldownScope: BucketScope.User + }); + } + // Register Chat Input and Context Menu command public override registerApplicationCommands(registry: Command.Registry) { registry.registerChatInputCommand((builder) => @@ -28,22 +29,11 @@ export class UserCommand extends Command { ); } - // Message command - public async messageRun(message: Message, args: Args) { - return this.tts(message, args.getOption('prompt') || 'NOTHING'); - } - // Chat Input (slash) command public async chatInputRun(interaction: Command.ChatInputCommandInteraction) { - return this.tts(interaction, interaction.options.getString('prompt') || 'NOTHING'); - } - - private async tts(interactionOrMessage: Message | Command.ChatInputCommandInteraction | Command.ContextMenuCommandInteraction, prompt: string) { - const askMessage = - interactionOrMessage instanceof Message - ? await interactionOrMessage.channel.send({ content: '🤔 Thinking... 🤔' }) - : await interactionOrMessage.reply({ content: '🤔 Thinking... 🤔', fetchReply: true }); + const prompt = interaction.options.getString('prompt') || 'NOTHING'; + await interaction.reply({ content: '🤔 Thinking... 🤔', fetchReply: true }); try { enum voice { alloy = 'alloy', @@ -73,15 +63,7 @@ export class UserCommand extends Command { const content = `Prompt: ${prompt}:`; - if (interactionOrMessage instanceof Message) { - return askMessage.edit({ - content, - files: mp3Attachment, - flags: '8192' - }); - } - - return interactionOrMessage.editReply({ + return interaction.editReply({ content, files: mp3Attachment, options: { @@ -91,15 +73,15 @@ export class UserCommand extends Command { } catch (error) { const content = "Sorry, I can't complete the prompt for: " + prompt + '\n' + error; - if (interactionOrMessage instanceof Message) { - return askMessage.edit({ - content - }); - } - - return interactionOrMessage.editReply({ + return interaction.editReply({ content }); } } } + +void container.stores.loadPiece({ + store: 'commands', + name: 'hdtts', + piece: HDTTSCommand +}); diff --git a/src/commands/hs.ts b/src/commands/hs.ts index 2c414c9..4c3cc8a 100644 --- a/src/commands/hs.ts +++ b/src/commands/hs.ts @@ -1,13 +1,13 @@ -import { ApplyOptions } from '@sapphire/decorators'; -import { Args, Command } from '@sapphire/framework'; -import { Message } from 'discord.js'; +import { Command, container } from '@sapphire/framework'; + +export class HighSchoolCommand extends Command { + public constructor(context: Command.LoaderContext) { + super(context, { + description: 'This command was your nickname in highschool!', + options: ['nickname'] + }); + } -// @ts-ignore -@ApplyOptions({ - description: 'This command was your nickname in highschool!', - options: ['nickname'] -}) -export class UserCommand extends Command { // Register Chat Input and Context Menu command public override registerApplicationCommands(registry: Command.Registry) { registry.registerChatInputCommand((builder) => @@ -18,27 +18,18 @@ export class UserCommand extends Command { ); } - // Message command - public async messageRun(message: Message, args: Args) { - return this.sendPing(message, args.getOption('nickname') || message.content.split('!wryna ')[1]); - } - // Chat Input (slash) command public async chatInputRun(interaction: Command.ChatInputCommandInteraction) { - return this.sendPing(interaction, interaction.options.getString('nickname') || 'NOTHING'); - } - - private async sendPing( - interactionOrMessage: Message | Command.ChatInputCommandInteraction | Command.ContextMenuCommandInteraction, - nickname: string - ) { - interactionOrMessage instanceof Message - ? await interactionOrMessage.channel.send({ - content: `${nickname} was ${interactionOrMessage.author.username}'s nickname in highschool!` - }) - : await interactionOrMessage.reply({ - content: `${nickname} was ${interactionOrMessage.user.username}'s nickname in highschool!`, - fetchReply: true - }); + const nickname = interaction.options.getString('nickname') || 'NOTHING'; + await interaction.reply({ + content: `${nickname} was ${interaction.user.username}'s nickname in highschool!`, + fetchReply: true + }); } } + +void container.stores.loadPiece({ + store: 'commands', + name: 'hs', + piece: HighSchoolCommand +}); diff --git a/src/commands/pic.ts b/src/commands/pic.ts index 46b22ed..8de66cc 100644 --- a/src/commands/pic.ts +++ b/src/commands/pic.ts @@ -1,24 +1,24 @@ -import { ApplyOptions } from '@sapphire/decorators'; -import { Args, BucketScope, Command } from '@sapphire/framework'; -import { AttachmentBuilder, Message } from 'discord.js'; +import { BucketScope, Command, container } from '@sapphire/framework'; +import { AttachmentBuilder } from 'discord.js'; import Replicate from 'replicate'; const replicate = new Replicate({ auth: process.env.REPLICATE_API_TOKEN }); -// @ts-ignore -@ApplyOptions({ - description: 'Generate an image using Stability AI! Cooldown 1 Minute to prevent spam!', - options: ['prompt'], - // 10mins - cooldownDelay: 100_000, - cooldownLimit: 1, - // Yes... I did hardcode myself. - cooldownFilteredUsers: ['83679718401904640'], - cooldownScope: BucketScope.User -}) -export class UserCommand extends Command { +export class PicCommand extends Command { + public constructor(context: Command.LoaderContext) { + super(context, { + description: 'Generate an image using Stability AI! Cooldown 1 Minute to prevent spam!', + options: ['prompt'], + cooldownDelay: 100_000, + cooldownLimit: 1, + // Yes... I did hardcode myself. + cooldownFilteredUsers: ['83679718401904640'], + cooldownScope: BucketScope.User + }); + } + // Register Chat Input and Context Menu command public override registerApplicationCommands(registry: Command.Registry) { registry.registerChatInputCommand((builder) => @@ -31,21 +31,11 @@ export class UserCommand extends Command { ); } - // Message command - public async messageRun(message: Message, args: Args) { - return this.picHr(message, args.getOption('prompt') || 'Scold me for not passing any prompt in.'); - } - // Chat Input (slash) command public async chatInputRun(interaction: Command.ChatInputCommandInteraction) { - return this.picHr(interaction, interaction.options.getString('prompt') || 'NOTHING'); - } + const prompt = interaction.options.getString('prompt') || 'NOTHING'; - private async picHr(interactionOrMessage: Message | Command.ChatInputCommandInteraction | Command.ContextMenuCommandInteraction, prompt: string) { - const askMessage = - interactionOrMessage instanceof Message - ? await interactionOrMessage.channel.send({ content: '🤔 Thinking... 🤔' }) - : await interactionOrMessage.reply({ content: '🤔 Thinking... 🤔', fetchReply: true }); + await interaction.reply({ content: '🤔 Thinking... 🤔', fetchReply: true }); let result = (await replicate.run('stability-ai/sdxl:39ed52f2a78e934b3ba6e2a89f5b1c712de7dfea535525255b1aa35c5565e08b', { input: { @@ -66,11 +56,7 @@ export class UserCommand extends Command { if (result.length <= 0) { const content = `Sorry, I can't complete the prompt for: ${prompt}`; - if (interactionOrMessage instanceof Message) { - return askMessage.edit({ content }); - } - - return interactionOrMessage.editReply({ + return interaction.editReply({ content: content }); } else { @@ -89,14 +75,16 @@ export class UserCommand extends Command { const content = `Prompt: ${prompt}`; - if (interactionOrMessage instanceof Message) { - return askMessage.edit({ content, files: imageAttachment }); - } - - return interactionOrMessage.editReply({ + return interaction.editReply({ content, files: imageAttachment }); } } } + +void container.stores.loadPiece({ + store: 'commands', + name: 'pic', + piece: PicCommand +}); diff --git a/src/commands/ping.ts b/src/commands/ping.ts deleted file mode 100644 index 04febbe..0000000 --- a/src/commands/ping.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { ApplyOptions } from '@sapphire/decorators'; -import { Command } from '@sapphire/framework'; -import { Message } from 'discord.js'; - -// @ts-ignore -@ApplyOptions({ - description: 'Pong!' -}) -export class UserCommand extends Command { - // Register Chat Input and Context Menu command - public override registerApplicationCommands(registry: Command.Registry) { - // Register Chat Input command - registry.registerChatInputCommand({ - name: this.name, - description: this.description - }); - } - - // Message command - public async messageRun(message: Message) { - return this.sendPing(message); - } - - // Chat Input (slash) command - public async chatInputRun(interaction: Command.ChatInputCommandInteraction) { - return this.sendPing(interaction); - } - - private async sendPing(interactionOrMessage: Message | Command.ChatInputCommandInteraction | Command.ContextMenuCommandInteraction) { - const pingMessage = - interactionOrMessage instanceof Message - ? await interactionOrMessage.channel.send({ content: 'Ping?' }) - : await interactionOrMessage.reply({ content: 'Ping?', fetchReply: true }); - - const content = `Pong! Bot Latency ${Math.round(this.container.client.ws.ping)}ms. API Latency ${ - pingMessage.createdTimestamp - interactionOrMessage.createdTimestamp - }ms.`; - - if (interactionOrMessage instanceof Message) { - return pingMessage.edit({ content }); - } - - return interactionOrMessage.editReply({ - content: content - }); - } -} diff --git a/src/commands/quack.ts b/src/commands/quack.ts deleted file mode 100644 index 8e04d98..0000000 --- a/src/commands/quack.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { ApplyOptions } from '@sapphire/decorators'; -import { Command } from '@sapphire/framework'; -import { Message } from 'discord.js'; - -// @ts-ignore -@ApplyOptions({ - description: 'Quack!' -}) -export class UserCommand extends Command { - // Register Chat Input and Context Menu command - public override registerApplicationCommands(registry: Command.Registry) { - // Register Chat Input command - registry.registerChatInputCommand({ - name: this.name, - description: this.description - }); - } - - // Message command - public async messageRun(message: Message) { - return this.sendQuack(message); - } - - // Chat Input (slash) command - public async chatInputRun(interaction: Command.ChatInputCommandInteraction) { - return this.sendQuack(interaction); - } - - private async sendQuack(interactionOrMessage: Message | Command.ChatInputCommandInteraction | Command.ContextMenuCommandInteraction) { - const duckResponse = await fetch('https://random-d.uk/api/v2/quack'); - const duckData = (await duckResponse.json()) as { url: string }; - - interactionOrMessage instanceof Message - ? await interactionOrMessage.channel.send({ - content: duckData.url - }) - : await interactionOrMessage.reply({ - content: duckData.url, - fetchReply: true - }); - } -} diff --git a/src/commands/support.ts b/src/commands/support.ts deleted file mode 100644 index f9ecc78..0000000 --- a/src/commands/support.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { ApplyOptions } from '@sapphire/decorators'; -import { Command } from '@sapphire/framework'; -import { Message } from 'discord.js'; - -// @ts-ignore -@ApplyOptions({ - description: "Help support HimBot's AI features." -}) -export class UserCommand extends Command { - // Register Chat Input and Context Menu command - public override registerApplicationCommands(registry: Command.Registry) { - registry.registerChatInputCommand((builder) => builder.setName(this.name).setDescription(this.description)); - } - - // Message command - public async messageRun(message: Message) { - return this.sendSupport(message); - } - - // Chat Input (slash) command - public async chatInputRun(interaction: Command.ChatInputCommandInteraction) { - return this.sendSupport(interaction); - } - - private async sendSupport(interactionOrMessage: Message | Command.ChatInputCommandInteraction | Command.ContextMenuCommandInteraction) { - interactionOrMessage instanceof Message - ? await interactionOrMessage.channel.send({ - content: 'Thanks! The link to donate is here: https://buy.stripe.com/eVa6p95ho0Kn33a8wx' - }) - : await interactionOrMessage.reply({ - content: 'Thanks! The link to donate is here: https://buy.stripe.com/eVa6p95ho0Kn33a8wx', - fetchReply: true - }); - } -} diff --git a/src/commands/title.ts b/src/commands/title.ts index 56716dc..c344dab 100644 --- a/src/commands/title.ts +++ b/src/commands/title.ts @@ -1,13 +1,13 @@ -import { ApplyOptions } from '@sapphire/decorators'; -import { Args, Command } from '@sapphire/framework'; -import { Message } from 'discord.js'; +import { Command, container } from '@sapphire/framework'; + +export class TitleCommand extends Command { + public constructor(context: Command.LoaderContext) { + super(context, { + description: 'This command is the title of your sextape.', + options: ['title'] + }); + } -// @ts-ignore -@ApplyOptions({ - description: 'This command is the title of your sextape.', - options: ['title'] -}) -export class UserCommand extends Command { // Register Chat Input and Context Menu command public override registerApplicationCommands(registry: Command.Registry) { registry.registerChatInputCommand((builder) => @@ -18,27 +18,19 @@ export class UserCommand extends Command { ); } - // Message command - public async messageRun(message: Message, args: Args) { - return this.titleHandler(message, args.getOption('title') || message.content.split('!title ')[1]); - } - // Chat Input (slash) command public async chatInputRun(interaction: Command.ChatInputCommandInteraction) { - return this.titleHandler(interaction, interaction.options.getString('title') || 'NOTHING'); - } + const title = interaction.options.getString('title') || 'NOTHING'; - private async titleHandler( - interactionOrMessage: Message | Command.ChatInputCommandInteraction | Command.ContextMenuCommandInteraction, - title: string - ) { - interactionOrMessage instanceof Message - ? await interactionOrMessage.channel.send({ - content: `${title}: Title of ${interactionOrMessage.author.username}'s sex tape!` - }) - : await interactionOrMessage.reply({ - content: `${title}: Title of ${interactionOrMessage.user.username}'s sex tape!`, - fetchReply: true - }); + await interaction.reply({ + content: `${title}: Title of ${interaction.user.username}'s sex tape!`, + fetchReply: true + }); } } + +void container.stores.loadPiece({ + store: 'commands', + name: 'title', + piece: TitleCommand +}); diff --git a/src/commands/tts.ts b/src/commands/tts.ts index afe55a9..8968fd2 100644 --- a/src/commands/tts.ts +++ b/src/commands/tts.ts @@ -1,23 +1,24 @@ -import { ApplyOptions } from '@sapphire/decorators'; -import { Args, BucketScope, Command } from '@sapphire/framework'; -import { AttachmentBuilder, Message, MessageFlags } from 'discord.js'; +import { BucketScope, Command, container } from '@sapphire/framework'; +import { AttachmentBuilder, MessageFlags } from 'discord.js'; import OpenAI from 'openai'; const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY }); -// @ts-ignore -@ApplyOptions({ - description: 'Generate TTS every minute!', - options: ['prompt'], - cooldownDelay: 100_000, - cooldownLimit: 1, - // Yes... I did hardcode myself. - cooldownFilteredUsers: ['83679718401904640'], - cooldownScope: BucketScope.User -}) -export class UserCommand extends Command { +export class TTSCommand extends Command { + public constructor(context: Command.LoaderContext) { + super(context, { + description: 'Generate TTS every minute!', + options: ['prompt'], + cooldownDelay: 100_000, + cooldownLimit: 1, + // Yes... I did hardcode myself. + cooldownFilteredUsers: ['83679718401904640'], + cooldownScope: BucketScope.User + }); + } + // Register Chat Input and Context Menu command public override registerApplicationCommands(registry: Command.Registry) { registry.registerChatInputCommand((builder) => @@ -28,21 +29,11 @@ export class UserCommand extends Command { ); } - // Message command - public async messageRun(message: Message, args: Args) { - return this.tts(message, args.getOption('prompt') || 'NOTHING'); - } - // Chat Input (slash) command public async chatInputRun(interaction: Command.ChatInputCommandInteraction) { - return this.tts(interaction, interaction.options.getString('prompt') || 'NOTHING'); - } + const prompt = interaction.options.getString('prompt') || 'NOTHING'; - private async tts(interactionOrMessage: Message | Command.ChatInputCommandInteraction | Command.ContextMenuCommandInteraction, prompt: string) { - const askMessage = - interactionOrMessage instanceof Message - ? await interactionOrMessage.channel.send({ content: '🤔 Thinking... 🤔' }) - : await interactionOrMessage.reply({ content: '🤔 Thinking... 🤔', fetchReply: true }); + await interaction.reply({ content: '🤔 Thinking... 🤔', fetchReply: true }); try { enum voice { @@ -73,15 +64,7 @@ export class UserCommand extends Command { const content = `Prompt: ${prompt}:`; - if (interactionOrMessage instanceof Message) { - return askMessage.edit({ - content, - files: mp3Attachment, - flags: '8192' - }); - } - - return interactionOrMessage.editReply({ + return interaction.editReply({ content, files: mp3Attachment, options: { @@ -91,15 +74,15 @@ export class UserCommand extends Command { } catch (error) { const content = "Sorry, I can't complete the prompt for: " + prompt + '\n' + error; - if (interactionOrMessage instanceof Message) { - return askMessage.edit({ - content - }); - } - - return interactionOrMessage.editReply({ + return interaction.editReply({ content }); } } } + +void container.stores.loadPiece({ + store: 'commands', + name: 'tts', + piece: TTSCommand +}); diff --git a/src/index.ts b/src/index.ts index 0ebbc69..d7c38da 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,14 @@ import './lib/setup'; +import './listeners/ready'; +import './commands/ask'; +import './commands/borf'; +import './commands/hdpic'; +import './commands/hdtts'; +import './commands/hs'; +import './commands/pic'; +import './commands/title'; +import './commands/tts'; +import './listeners/commands/chatInputCommands/chatInputCommandSuccess'; import { LogLevel, SapphireClient, BucketScope } from '@sapphire/framework'; import { ActivityType, GatewayIntentBits } from 'discord.js'; @@ -18,7 +28,6 @@ const client = new SapphireClient({ level: LogLevel.Debug }, intents: [GatewayIntentBits.DirectMessages, GatewayIntentBits.GuildMessages, GatewayIntentBits.Guilds, GatewayIntentBits.MessageContent], - loadMessageCommandListeners: true, defaultCooldown: { // 10s delay: 10_000, @@ -27,7 +36,8 @@ const client = new SapphireClient({ // Yes... I did hardcode myself. filteredUsers: ['83679718401904640'], scope: BucketScope.User - } + }, + baseUserDirectory: null }); const main = async () => { diff --git a/src/lib/utils.ts b/src/lib/utils.ts index 08e3dce..eeba90c 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -1,21 +1,11 @@ -import { - container, - type ChatInputCommandSuccessPayload, - type Command, - type ContextMenuCommandSuccessPayload, - type MessageCommandSuccessPayload -} from '@sapphire/framework'; +import { container, type ChatInputCommandSuccessPayload, type Command, type ContextMenuCommandSuccessPayload } from '@sapphire/framework'; import { cyan } from 'colorette'; import type { APIUser, Guild, User } from 'discord.js'; -export function logSuccessCommand(payload: ContextMenuCommandSuccessPayload | ChatInputCommandSuccessPayload | MessageCommandSuccessPayload): void { +export function logSuccessCommand(payload: ContextMenuCommandSuccessPayload | ChatInputCommandSuccessPayload): void { let successLoggerData: ReturnType; - if ('interaction' in payload) { - successLoggerData = getSuccessLoggerData(payload.interaction.guild, payload.interaction.user, payload.command); - } else { - successLoggerData = getSuccessLoggerData(payload.message.guild, payload.message.author, payload.command); - } + successLoggerData = getSuccessLoggerData(payload.interaction.guild, payload.interaction.user, payload.command); container.logger.debug(`${successLoggerData.shard} - ${successLoggerData.commandName} ${successLoggerData.author} ${successLoggerData.sentAt}`); } diff --git a/src/listeners/commands/messageCommands/messageCommandDenied.ts b/src/listeners/commands/messageCommands/messageCommandDenied.ts deleted file mode 100644 index e0ea3e3..0000000 --- a/src/listeners/commands/messageCommands/messageCommandDenied.ts +++ /dev/null @@ -1,12 +0,0 @@ -import type { Events, MessageCommandDeniedPayload } from '@sapphire/framework'; -import { Listener, type UserError } from '@sapphire/framework'; - -export class UserEvent extends Listener { - public async run({ context, message: content }: UserError, { message }: MessageCommandDeniedPayload) { - // `context: { silent: true }` should make UserError silent: - // Use cases for this are for example permissions error when running the `eval` command. - if (Reflect.get(Object(context), 'silent')) return; - - return message.reply({ content, allowedMentions: { users: [message.author.id], roles: [] } }); - } -} diff --git a/src/listeners/commands/messageCommands/messageCommandSuccess.ts b/src/listeners/commands/messageCommands/messageCommandSuccess.ts deleted file mode 100644 index bccb0cb..0000000 --- a/src/listeners/commands/messageCommands/messageCommandSuccess.ts +++ /dev/null @@ -1,15 +0,0 @@ -import type { MessageCommandSuccessPayload } from '@sapphire/framework'; -import { Listener, LogLevel } from '@sapphire/framework'; -import type { Logger } from '@sapphire/plugin-logger'; -import { logSuccessCommand } from '../../../lib/utils'; - -export class UserEvent extends Listener { - public run(payload: MessageCommandSuccessPayload) { - logSuccessCommand(payload); - } - - public onLoad() { - this.enabled = (this.container.logger as Logger).level <= LogLevel.Debug; - return super.onLoad(); - } -} diff --git a/src/listeners/ready.ts b/src/listeners/ready.ts index aadc73e..f7ab85a 100644 --- a/src/listeners/ready.ts +++ b/src/listeners/ready.ts @@ -1,5 +1,5 @@ import { ApplyOptions } from '@sapphire/decorators'; -import { Listener, Store } from '@sapphire/framework'; +import { Listener, Store, container } from '@sapphire/framework'; import { blue, gray, green, magenta, magentaBright, white, yellow } from 'colorette'; const dev = process.env.NODE_ENV !== 'production'; @@ -41,11 +41,17 @@ ${line03}${dev ? ` ${pad}${blc('<')}${llc('/')}${blc('>')} ${llc('DEVELOPMENT MO const stores = [...client.stores.values()]; const last = stores.pop()!; - for (const store of stores) logger.info(this.styleStore(store, false)); - logger.info(this.styleStore(last, true)); + for (const store of stores) logger.info(this.styleStore(store)); + logger.info(this.styleStore(last)); } - private styleStore(store: Store, last: boolean) { - return gray(`${last ? '└─' : '├─'} Loaded ${this.style(store.size.toString().padEnd(3, ' '))} ${store.name}.`); + private styleStore(store: Store) { + return gray(`${'└─'} Loaded ${this.style(store.size.toString().padEnd(3, ' '))} ${store.name}.`); } } + +void container.stores.loadPiece({ + piece: UserEvent, + name: 'ready', + store: 'listeners' +});