diff --git a/README.md b/README.md index 848c53a..7d7f876 100644 --- a/README.md +++ b/README.md @@ -95,6 +95,29 @@ import { GatewayIntentBits, Partials } from "discord.js"; await client.connect(process.env.TOKEN); })(); + +// If you need internationalisation: +import { initTranslations } from "@stelliajs/framework"; + +await use(Backend).init( + { + lng: StelliaLocale.English, // StelliaLocale is an enum with all the supported languages by Discord + backend: { + // With namespace: path.join(import.meta.dirname, "../locales/{{lng}}/{{ns}}.json") + loadPath: path.join(import.meta.dirname, "../locales/{{lng}}.json") + }, + fallbackLng: StelliaLocale.English, + supportedLngs: Object.values(AmariLocale), + preload: Object.values(AmariLocale) + // ns: ["common", "commands", "errors"] + }, + (error) => { + if (error) { + console.error(error); + } + } +); +initTranslations(i18next); ``` #### Environment model diff --git a/eslint.config.ts b/eslint.config.ts index 230a486..73df6a6 100644 --- a/eslint.config.ts +++ b/eslint.config.ts @@ -28,7 +28,7 @@ export default defineConfig([ } }, rules: { - "import-x/namespace": "off", + "key-spacing": ["error", { beforeColon: false, afterColon: true }], "import-x/no-unresolved": "error", "import-x/no-duplicates": "error", "import-x/newline-after-import": ["error", { count: 1 }], @@ -49,6 +49,7 @@ export default defineConfig([ } } ], + "@typescript-eslint/no-namespace": "off", "@typescript-eslint/explicit-function-return-type": "off", "@typescript-eslint/no-explicit-any": "warn", "@typescript-eslint/consistent-type-imports": [ diff --git a/package.json b/package.json index 53b7660..03eaadf 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,11 @@ { "name": "@stelliajs/framework", - "version": "1.7.3", + "version": "1.8.0", "type": "module", "description": "A framework for simplifying the creation of discord bots", "author": "Tweenty_", "license": "ISC", - "packageManager": "pnpm@11.1.3", + "packageManager": "pnpm@11.8.0", "engines": { "node": ">=24.0.0" }, @@ -37,7 +37,7 @@ }, "peerDependencies": { "discord.js": "^14.26.4", - "i18next": "26.2.0" + "i18next": "26.3.1" }, "dependencies": { "log-symbols": "^7.0.1" @@ -45,15 +45,15 @@ "devDependencies": { "@eslint/js": "^10.0.1", "discord.js": "^14.26.4", - "eslint": "^10.4.0", + "eslint": "^10.5.0", "eslint-config-prettier": "^10.1.8", - "eslint-import-resolver-typescript": "^4.4.4", + "eslint-import-resolver-typescript": "^4.4.5", "eslint-plugin-import-x": "^4.16.2", "globals": "^17.6.0", "jiti": "^2.7.0", - "prettier": "^3.8.3", - "tsdown": "^0.22.0", + "prettier": "^3.8.4", + "tsdown": "^0.22.3", "typescript": "^6.0.3", - "typescript-eslint": "^8.59.4" + "typescript-eslint": "^8.61.1" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 319387e..8df2eff 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,30 +9,30 @@ importers: .: dependencies: i18next: - specifier: 26.2.0 - version: 26.2.0(typescript@6.0.3) + specifier: 26.3.1 + version: 26.3.1(typescript@6.0.3) log-symbols: specifier: ^7.0.1 version: 7.0.1 devDependencies: '@eslint/js': specifier: ^10.0.1 - version: 10.0.1(eslint@10.4.0(jiti@2.7.0)) + version: 10.0.1(eslint@10.5.0(jiti@2.7.0)) discord.js: specifier: ^14.26.4 version: 14.26.4 eslint: - specifier: ^10.4.0 - version: 10.4.0(jiti@2.7.0) + specifier: ^10.5.0 + version: 10.5.0(jiti@2.7.0) eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@10.4.0(jiti@2.7.0)) + version: 10.1.8(eslint@10.5.0(jiti@2.7.0)) eslint-import-resolver-typescript: - specifier: ^4.4.4 - version: 4.4.4(eslint-plugin-import-x@4.16.2(@typescript-eslint/utils@8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.4.0(jiti@2.7.0)))(eslint@10.4.0(jiti@2.7.0)) + specifier: ^4.4.5 + version: 4.4.5(eslint-plugin-import-x@4.16.2(@typescript-eslint/utils@8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.5.0(jiti@2.7.0)))(eslint@10.5.0(jiti@2.7.0)) eslint-plugin-import-x: specifier: ^4.16.2 - version: 4.16.2(@typescript-eslint/utils@8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.4.0(jiti@2.7.0)) + version: 4.16.2(@typescript-eslint/utils@8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.5.0(jiti@2.7.0)) globals: specifier: ^17.6.0 version: 17.6.0 @@ -40,44 +40,39 @@ importers: specifier: ^2.7.0 version: 2.7.0 prettier: - specifier: ^3.8.3 - version: 3.8.3 + specifier: ^3.8.4 + version: 3.8.4 tsdown: - specifier: ^0.22.0 - version: 0.22.0(typescript@6.0.3) + specifier: ^0.22.3 + version: 0.22.3(typescript@6.0.3) typescript: specifier: ^6.0.3 version: 6.0.3 typescript-eslint: - specifier: ^8.59.4 - version: 8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3) + specifier: ^8.61.1 + version: 8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) packages: - '@babel/generator@8.0.0-rc.5': - resolution: {integrity: sha512-nFZPWz3FHIS7y6rMIVoa/WBwjdutfIaRJIBQjzn+t3RnecZoRNlGmGcyR2wb0T/IgSd50Kz/6dG8/LvMCRunjg==} + '@babel/generator@8.0.0': + resolution: {integrity: sha512-NT9NrVwJsbSV6Y2FSstWa71EETOnzrjkL5/wX3D2mYHtKM+qvqB1DvR4D0Setb/gDBsHzRICifwEWMO8CnTF6g==} engines: {node: ^22.18.0 || >=24.11.0} - '@babel/helper-string-parser@8.0.0-rc.5': - resolution: {integrity: sha512-sN7R8rBvDurfaziNfDEIjIntlazmlkCDGO4SNl2RJ3wRCn+QxspLV7hzYAE8WWVd2joVuT8sUxeePdLp2idI1A==} + '@babel/helper-string-parser@8.0.0': + resolution: {integrity: sha512-6mJgmFFFIIO82vvoLt9XtRC7/TkzXfts1t/SpRX4IHSzMgqoPYCWesVu1udUPUWioAE/2fcG6WuI8zrkE1gwrg==} engines: {node: ^22.18.0 || >=24.11.0} - '@babel/helper-validator-identifier@8.0.0-rc.5': - resolution: {integrity: sha512-ehJDxHvtbZ85RtX/L2fi0h9AGsBNqB5Euv1EB8RMAvGYvD+2X+QbpzzOpbklnNXO+WSZJNOaetw2BBj27xsWVg==} + '@babel/helper-validator-identifier@8.0.2': + resolution: {integrity: sha512-9Fr9QeyCAyi1BR1jKZ6uYQ24EIhQUx5ReHfQU7drOE+TPOb+w11/dsqLkMOT2U29OdCT71XajrOT8xDc1C7orA==} engines: {node: ^22.18.0 || >=24.11.0} - '@babel/parser@8.0.0-rc.4': - resolution: {integrity: sha512-0S/1yefMa15N4i2v3t8Fw9pgMHhf2gF6Lc1UEXI96Ls6FNAjqvHHZouZ2ZS/deqLhbMFtmfVeFac6iTsvFbLwA==} - engines: {node: ^20.19.0 || >=22.12.0} - hasBin: true - - '@babel/parser@8.0.0-rc.5': - resolution: {integrity: sha512-/Mfg83rK3+jsRbl4Vbd0jqxc6M1A1/WNFtgrowRM1unEsD3XcNnrBdMM0JWakd0/RN9lseQKwPduW1TiEwKOlQ==} + '@babel/parser@8.0.0': + resolution: {integrity: sha512-aLxAE+imI9bCcyaPrUDjBv3uSkWieifjLe0kuFOZF0zli0L6GCsTmsePnTr55adbIAgYz2zhN1vnFimCBUYcRQ==} engines: {node: ^22.18.0 || >=24.11.0} hasBin: true - '@babel/types@8.0.0-rc.5': - resolution: {integrity: sha512-JeSVu/m8x/zpp4CLjYHVNXuhEyOkhPXuxM8YOXjh6L4LlvQNKuUNOTo5KdBuKAcTDHw8DquToTaEkhsBqPXOaA==} + '@babel/types@8.0.0': + resolution: {integrity: sha512-K8ponJDxBwDHigkeFqaqT5wLGl4bTlwMafR8k7b5CPxr6Ww+UG9ls8Yx6Tcpboxu97eeGVEEyKcHmEyOwN1vSw==} engines: {node: ^22.18.0 || >=24.11.0} '@discordjs/builders@1.14.1': @@ -111,12 +106,21 @@ packages: '@emnapi/core@1.10.0': resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==} + '@emnapi/core@1.11.1': + resolution: {integrity: sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==} + '@emnapi/runtime@1.10.0': resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==} + '@emnapi/runtime@1.11.1': + resolution: {integrity: sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==} + '@emnapi/wasi-threads@1.2.1': resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} + '@emnapi/wasi-threads@1.2.2': + resolution: {integrity: sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==} + '@eslint-community/eslint-utils@4.9.1': resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -152,8 +156,8 @@ packages: resolution: {integrity: sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} - '@eslint/plugin-kit@0.7.1': - resolution: {integrity: sha512-rZAP3aVgB9ds9KOeUSL+zZ21hPmo8dh6fnIFwRQj5EAZl9gzR7wxYbYXYysAM8CTqGmUGyp2S4kUdV17MnGuWQ==} + '@eslint/plugin-kit@0.7.2': + resolution: {integrity: sha512-+CNAzxglkrpNf/kKywqQfk74QjtceuOE7Qm+AF8miRvPF/wmmK5+OJOgVh3AVTT3RP2mH3+FOaxlE5v72owk0A==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} '@humanfs/core@0.19.2': @@ -189,14 +193,14 @@ packages: '@jridgewell/trace-mapping@0.3.31': resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} - '@napi-rs/wasm-runtime@1.1.4': - resolution: {integrity: sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==} + '@napi-rs/wasm-runtime@1.1.5': + resolution: {integrity: sha512-AWPoBRJ9tsnVhor4sjO7rkni+7p+2IAEFj6cx06UgP10jkQHqay/36uRV/bFkgrh18D9vb4cr8Q0Pthskgzy+Q==} peerDependencies: '@emnapi/core': ^1.7.1 '@emnapi/runtime': ^1.7.1 - '@oxc-project/types@0.130.0': - resolution: {integrity: sha512-ibD2usx9JRu7f5pu2tMKMI4cpA4NgXJQoYRP4pQ7Pxmn1l6k/53qWtQWZayhYy3X4QZkt90Ot+mJEaeXouio6Q==} + '@oxc-project/types@0.137.0': + resolution: {integrity: sha512-WT+Gb24i8hmvo85AIv2oEYouEXkRlKAlT9WaCa3TfLgNCN+GhrJOGZuIlMouAh38Qe4QOx26eUOVsq70qXrywA==} '@package-json/types@0.0.12': resolution: {integrity: sha512-uu43FGU34B5VM9mCNjXCwLaGHYjXdNincqKLaraaCW+7S2+SmiBg1Nv8bPnmschrIfZmfKNY9f3fC376MRrObw==} @@ -204,97 +208,97 @@ packages: '@quansync/fs@1.0.0': resolution: {integrity: sha512-4TJ3DFtlf1L5LDMaM6CanJ/0lckGNtJcMjQ1NAV6zDmA0tEHKZtxNKin8EgPaVX1YzljbxckyT2tJrpQKAtngQ==} - '@rolldown/binding-android-arm64@1.0.1': - resolution: {integrity: sha512-fJI3I0r3C3Oj/zdBCpaCmBRZYf07xpaq4yCfDDoSFm+beWNzbIl26puW8RraUdugoJw/95zerNOn6jasAhzSmg==} + '@rolldown/binding-android-arm64@1.1.2': + resolution: {integrity: sha512-2cZ+7xRS+DBcuJBJKnfzsbleumJhBqSlJVpuzHC0nTqfd3QQ7Vx2/x5YR/D7cBamKSeWplwo82Fn9lqYUDEMfA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@rolldown/binding-darwin-arm64@1.0.1': - resolution: {integrity: sha512-cKnAhWEsV7TPcA/5EAteDp6KcJZBQ2G+BqE7zayMMi7kMvwRsbv7WT9aOnn0WNl4SKEIf43vjS31iUPu80nzXg==} + '@rolldown/binding-darwin-arm64@1.1.2': + resolution: {integrity: sha512-RkPMJnygxsgOYdkfqgpwY0/Fzm8d0VQe6HGU2/B00Xa9eqdLbrII+DOKAodbJAn3ZL1AJxGHkZRPYazgGY6Ljw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@rolldown/binding-darwin-x64@1.0.1': - resolution: {integrity: sha512-YKrVwQjIRBPo+5G/u03wGjbdy4q7pyzCe93DK9VJ7zkVmeg8LJ7GbgsiHWdR4xSoe4CAXRD7Bcjgbtr64bkXNg==} + '@rolldown/binding-darwin-x64@1.1.2': + resolution: {integrity: sha512-Uiczh6vFhwyfd7WNe7Q7mCA4KxAiLdz7jPE/WGizfRpIieoyFuNVMmM8HqZ9HwudTkY6/AeMQwlNJ9NJijguWw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@rolldown/binding-freebsd-x64@1.0.1': - resolution: {integrity: sha512-z/oBsREo46SsFqBwYtFe0kpJeBijAT48O/WXLI4suiCLBkr03RTtTJMCzSdDd2znlh8VJizL09XVkQgk8IZonw==} + '@rolldown/binding-freebsd-x64@1.1.2': + resolution: {integrity: sha512-+TpdtTRgHiJFjCVFbw311SuLk3KfytPOQQn+VlAEv+gBxYPtL7E6JS9e/tk+8CwxhIZvemJKo4rTKgfWNsKkkA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@rolldown/binding-linux-arm-gnueabihf@1.0.1': - resolution: {integrity: sha512-ik8q7GM11zxvYxFc2PeDcT6TBvhCQMaUxfph/M5l9sKuTs/Sjg3L+Byw0F7w0ZVLBZmx30P+gG0ECzzN+MFcmQ==} + '@rolldown/binding-linux-arm-gnueabihf@1.1.2': + resolution: {integrity: sha512-4lv1/tkmi7ueIVHnyreaOeUpiZP26BH9rRy6hoYfR9310A2B9nUEVRDvBx69vx64Nr3eTPPRkyciqJJs+j9Jmw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@rolldown/binding-linux-arm64-gnu@1.0.1': - resolution: {integrity: sha512-QoSx2EkyrrdZ6kcyE8stqZ62t0Yra8Fs5ia9lOxJrh6TMQJK7gQKmscdTHf7pOXKREKrVwOtJcQG3qVSfc866A==} + '@rolldown/binding-linux-arm64-gnu@1.1.2': + resolution: {integrity: sha512-gBSUVO0eaWgw1JMjK3gB8BMlX2Mk148s2lTiVT3e9vjVxbl7UDfMWWY8CfIaaqiXuM9fVTMxIpUz6CAo/B6Vlw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-arm64-musl@1.0.1': - resolution: {integrity: sha512-uwNwFpwKeNiZawfAWBgg0VIztPTV3ihhh1vV334h9ivnNLorxnQMU6Fz8wG1Zb4Qh9LC1/MkcyT3YlDXG3Rsgg==} + '@rolldown/binding-linux-arm64-musl@1.1.2': + resolution: {integrity: sha512-LjQP/iZLBu8o8PjIfk4x3At0/mT6h282pvz8Z5LAyhGbu/kDezyO7ea62rF5uoqmgnIYqbN/MqJ3Si3Aymi7xQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [musl] - '@rolldown/binding-linux-ppc64-gnu@1.0.1': - resolution: {integrity: sha512-zY1bul7OWr7DFBiJ++wofXvnr8B45ce3QsQUhKrIhXsygAh7bTkwyeM1bi1a2g5C/yC/N8TZyGDEoMfm/l9mpg==} + '@rolldown/binding-linux-ppc64-gnu@1.1.2': + resolution: {integrity: sha512-X/7bVLWelEsbyWDUSXt7zVsTniLLPIY2n1rH58qr78l9i7MNbbxBWD8gI2vRfBWf4NUXJCUuQnfZDsp32LqsfQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-s390x-gnu@1.0.1': - resolution: {integrity: sha512-0frlsT/f4Ft6I7SMESTKnF3cZsdicQn1dCMkF/jT9wDLE+gGoiQfv1nmT9e+s7s/fekvvy6tZM2jHvI2tkbJDQ==} + '@rolldown/binding-linux-s390x-gnu@1.1.2': + resolution: {integrity: sha512-gb6dYKW/1KDorGXyy48glEBJs/sxVSC5pcVrox/pFGV4mvwSFeg2sK5L2tRkVsVlh7kueqOgg4GEcuipJcGuKg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] libc: [glibc] - '@rolldown/binding-linux-x64-gnu@1.0.1': - resolution: {integrity: sha512-XABVmGp9Tg0WspTVvwduTc4fpqy6JnAUrSQe6OuyqD/03nI7r0O9OWUkMIwFrjKAIqolvqoA4ZrJppgwE0Gxmw==} + '@rolldown/binding-linux-x64-gnu@1.1.2': + resolution: {integrity: sha512-JY4w85pU3iAiJVMh5nuk4/Mh9GjMsupe8MrIN53rwxAZW64GKrWeJBuN6SxQg9QTU5uB1cxyhDzW8jqRn1EABw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-x64-musl@1.0.1': - resolution: {integrity: sha512-bV4fzswuzVcKD90o/VM6QqKxnxlDq0g2BISDLNVmxrnhpv1DDbyPhCIjYfvzYLV+MvkKKnQt2Q6AO86SEBULUQ==} + '@rolldown/binding-linux-x64-musl@1.1.2': + resolution: {integrity: sha512-xvpA7o5KCYLB0Rwscmuylb1/zHHSUx4g4xilm4prC5jP76pEUlzBmMbgpbh7bVDbId4NcfT96gN5i6mE6UDaiw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [musl] - '@rolldown/binding-openharmony-arm64@1.0.1': - resolution: {integrity: sha512-/Mh0Zhq3OP7fVs0kcQHZP6lZEthMGTaSf8UBQYSFEZDWGXXlEC+nJ6EqenaK2t4LBXMe3A+K/G2BVXXdtOr4PQ==} + '@rolldown/binding-openharmony-arm64@1.1.2': + resolution: {integrity: sha512-p/ts6KBLjuk49Bp21XH77poQGt02iNz7ChgHep7tudPOaLinR/De/RHdxF8w8Yj4r/bF/bqXwH6PZrB2sA+Nvw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@rolldown/binding-wasm32-wasi@1.0.1': - resolution: {integrity: sha512-+1xc9X45l8ufsBAm6Gjvx2qDRIY9lTVt0cgWNcJ+1gdhXvkbxePA60yRTwSTuXL09CMhyJmjpV7E3NoyxbqFQQ==} + '@rolldown/binding-wasm32-wasi@1.1.2': + resolution: {integrity: sha512-VMu/wmrZ9hJzYlRhbw7jK5PODlugyKZ5mOdX78+lS8OvuFkWNQdz1pFLrI2p3P0pjXOmUZ7B48o5VnMH9QOGtg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [wasm32] - '@rolldown/binding-win32-arm64-msvc@1.0.1': - resolution: {integrity: sha512-1D+UqZdfnuR+Jy1GgMJwi85bD40H21uNmOPRWQhw4oRSuolZ/B5rixZ45DK2KXOTCvmVCecauWgEhbw8bI7tOw==} + '@rolldown/binding-win32-arm64-msvc@1.1.2': + resolution: {integrity: sha512-xtUJqs8qEkuSviS0n1tsohaPuz3a1SPhZywOji4Oo+sgrJs8daEDMZ0QtqL0OS7dx8PoVpg2J/ZZycPY5I2+Zg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@rolldown/binding-win32-x64-msvc@1.0.1': - resolution: {integrity: sha512-INAycaWuhlOK3wk4mRHGsdgwYWmd9cChdPdE9bwWmy6rn9VqVNYNFGhOdXrofXUxwHIncSiPNb8tNm8knDVIeQ==} + '@rolldown/binding-win32-x64-msvc@1.1.2': + resolution: {integrity: sha512-85YiLQqjUKgSO/Zjnf9e0XIn5Ymrh1fLDWBeAkZqpuBR/3R8TpfoHXuyblqyQrftSSgWO9qpcHN8mkyKsLraoA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] @@ -333,176 +337,188 @@ packages: '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - '@types/node@25.9.0': - resolution: {integrity: sha512-AOQwYUNolgy3VosiRqXrACUXTN8nJUtPl7FJXMqZVyxiiCLhQuG3jXKvCS1ALr+Y2OmZhzzLVlYPEqJaiqkaJQ==} + '@types/node@26.0.0': + resolution: {integrity: sha512-vf2YFi1iY9lHGwNJMs01biZFbKJkrZR1T6/MlzjhJLPdntOHLhTrDSnSVcdtvjihi4VQNlrFRIxLsDBlQpAipA==} '@types/ws@8.18.1': resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} - '@typescript-eslint/eslint-plugin@8.59.4': - resolution: {integrity: sha512-PegsU+XfyJJNjd4+u/k6f9yTyp0lEXXiPopUNobZcIAUJFGICFLN+sP0Rb3JehVmiij1Ph0dFGYqODoRo/2+6A==} + '@typescript-eslint/eslint-plugin@8.61.1': + resolution: {integrity: sha512-ZPlVl3PB3et/59Ne0fv/sci6ZXz4T4Hp4nTJ56i/Y0gR89ARb+KphojTq6j+56E5PIezmOIOOWyY+aWQFd+IkQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.59.4 + '@typescript-eslint/parser': ^8.61.1 eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/parser@8.59.4': - resolution: {integrity: sha512-zORHqO/tuhxY1zWuTvMUqddRxpiFJ72xVfcNoWpqdLjs6lfPbuQBJuW4pk+49/uBMy7Ssr4bzgjiKmmDB1UbZQ==} + '@typescript-eslint/parser@8.61.1': + resolution: {integrity: sha512-PJ5vePq5/ognBbrIcoC5+SHO5dfpeLPzP9FpLkzWrguoYQEeeSjlJpVwOpo1JRSTEi7dRcwNy4h4dzV70PqHcg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/project-service@8.59.4': - resolution: {integrity: sha512-Ly00Vu4oAacfDeHp2Zg85ioNG6l8HG+tN1D7J+xTHSxu9y0awYKJ2zH1rFBn8ZSfuGK+7FxK3Cgl3uAz0aZZLg==} + '@typescript-eslint/project-service@8.61.1': + resolution: {integrity: sha512-PrC4JYGmR241lYnfhmKGTXkFqv8+ymbTFgSAY0fVXpY82/QkMw5TZPl+vGzuDDU2QYJk9fIDOBTntF+yDv9LEA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/scope-manager@8.59.4': - resolution: {integrity: sha512-mUeR/3H1WrTAddJrwut8OoPjfauaztMQmRwV5fQTUyNVJCLiUXXe4lGEyYIL2oFDpP7UtgbGJXCt72wT0z2S3Q==} + '@typescript-eslint/scope-manager@8.61.1': + resolution: {integrity: sha512-L2bdIeoQS8FlKAvONAr20w6OcLXeB+qiDKbAooS9A0Ben+iSIkBef0FxqwKWYqt5sa0i4KJtxVyVmhMylKzF5w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.59.4': - resolution: {integrity: sha512-DLCpnKgD4alVxTBSKulK+gU1KCqOgUXfDRDXh2mZgzokQKa/70ax93I2uVO3m/LLvIAtWZIFoiifudmIqAxpMA==} + '@typescript-eslint/tsconfig-utils@8.61.1': + resolution: {integrity: sha512-UN/H4di+OO7EWx2ovME+8t31YO+KVnK0RRKEHR3kOt21/Ay8BOq3M1OMvWs5vNiqcFCYGYoxK3MXPZzmMUE+yg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/type-utils@8.59.4': - resolution: {integrity: sha512-uonTuPAAKr9XaBGqJ3LjYTh72zy5DyGesljO9gtmk/eFW0W1fRHjnwVYKB35Lm8d5Q5CluEW3gPHjTvZTmgrfA==} + '@typescript-eslint/type-utils@8.61.1': + resolution: {integrity: sha512-GYRicKmVK0C4fsKgaACaknOUAq9Oa2kwsjnpFhFcS/5p4Ht5IP9OVLbgIgcK4SRk92nVHFluurg1lumD9dBcLw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/types@8.59.4': - resolution: {integrity: sha512-F1o7WJcCq+bc8dwcO/YsSEOudAH8RDtaOhM6wcAQhcUsFhnWQl81JKy48q1hoxAU0qrzM89+31GYh1515Zde3Q==} + '@typescript-eslint/types@8.61.1': + resolution: {integrity: sha512-G+CRlPqLv7Bz1IZVs03x5K59F1veqL0EJUROAdGhKsEq8qOiRiZbI+HUojPq5l0fEGOKModD9br6lObhB8zkoA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.59.4': - resolution: {integrity: sha512-F+RuOmcDXo4+TPdfd/TCLS3m2nw8gE9XXyZLrA3JBfaA5tz9TtdkyD3YJFmPxulyc2cKbEok/CvFE3MgSLWnag==} + '@typescript-eslint/typescript-estree@8.61.1': + resolution: {integrity: sha512-u+oQD3BqYWPc8YV9Zab4vaJElJuwOLPRc10Jm1o/qS+6Qwen14HCWwx0Seo4LnSn2wxea2Ik8DxPt2/FHmuhrg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/utils@8.59.4': - resolution: {integrity: sha512-cYXeNAUsG4lJo5dbc1FcKm+JwIWrj1/UpTORsC6tGMjEZ81DYcvIr9/ueikhMa/Y/gDQYGp+YX9/xQrXje5BJw==} + '@typescript-eslint/utils@8.61.1': + resolution: {integrity: sha512-1+P/3Dj6jvtybE1q0HQ6yBt/gq+oKJyLdEv4HdnqasaEXRSYCAsD59mXEVQnM/ULNdQxbX77tdG4jPRjIS6knA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/visitor-keys@8.59.4': - resolution: {integrity: sha512-U3gxVaDVnuZKhSspW/MzMxE1kq7zOdc072FcSNoqA1I9p8HyKbBFfEHoWckBAMgNMph4MamwS5iTVzFmrnt8TQ==} + '@typescript-eslint/visitor-keys@8.61.1': + resolution: {integrity: sha512-6fJ9MHWtK14C1DSkiMlHUSOmrVebL7150xZJBlJiL62jjhIA4JmOq6flwBgDxIdBKKdoiZRel+dfPD5MLfny3w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@unrs/resolver-binding-android-arm-eabi@1.12.0': - resolution: {integrity: sha512-FmIJ5Bq2UUrpj2TrJiOvtfvgh98QqB3PKVqWrHp0SrYqlNSlch4YXToiiNK+mSTNFes07DipzT/JpJIq8xsOrg==} + '@unrs/resolver-binding-android-arm-eabi@1.12.2': + resolution: {integrity: sha512-g5T90pqg1bo/7mytQx6F4iBNC0Wsh9cu+z9veDbFjc7HjpesJFWD7QMS0NGStXM075+7dJPPVvBbpZlnrdpi/w==} cpu: [arm] os: [android] - '@unrs/resolver-binding-android-arm64@1.12.0': - resolution: {integrity: sha512-XqE7sTuM4wquiiSptDC18/7SRh5LOQhmjRgu7j65T+m7lP0FzJQl0fSL+Zd7aATVJciVpcNkk0ml4hMwASvfXQ==} + '@unrs/resolver-binding-android-arm64@1.12.2': + resolution: {integrity: sha512-YGCRZv/9GLhwmz6mYDeTsm/92BAyR28l6c2ReweVW5pWgfsitWLY8upvfRlGdoyD8HjeTHSYJWyZGD4KJA/nFQ==} cpu: [arm64] os: [android] - '@unrs/resolver-binding-darwin-arm64@1.12.0': - resolution: {integrity: sha512-7aOfLOGYIh3Whvzv6fi3bA9aj8tuf7XDYbzTtsMeXixdRGLT6luR1htBSbjvWXyCn4TbKgz5SDa5gURYdlM0GQ==} + '@unrs/resolver-binding-darwin-arm64@1.12.2': + resolution: {integrity: sha512-u9DiNT1auQMO20A9SyTuG3wUgQWB9Z7KjAg0uFuCDR1FsAY8A0CG2S6JpHS1xwm/w1G08bjXZDcyOCjv1WAm2w==} cpu: [arm64] os: [darwin] - '@unrs/resolver-binding-darwin-x64@1.12.0': - resolution: {integrity: sha512-2NiHBibXXDCBnjpzpwHoq4Fs6kvt9QYD6ravNA3D8KQaKr7r0qu6CyvqJfDLYssijCSs2UwEmkKcAmCxP/HOXA==} + '@unrs/resolver-binding-darwin-x64@1.12.2': + resolution: {integrity: sha512-f7rPLi/T1HVKZu/u6t87lroib16n8vrSzcyxI7lg4BGO9UF26KhQL44sd9eOUgrTYhvRXtWOIZT5PejdPyJfUA==} cpu: [x64] os: [darwin] - '@unrs/resolver-binding-freebsd-x64@1.12.0': - resolution: {integrity: sha512-x/k1Vy1QoDrOYLJzQg2/WsRGQPS0Saw4basKqjZDQlPdkSApsvDdB9h8oRQDUTJCCazSlqLm+Ry9NQFlJicacQ==} + '@unrs/resolver-binding-freebsd-x64@1.12.2': + resolution: {integrity: sha512-BpcOjWCJub6nRZUS2zA20pmLvjtqAtGejETaIyRLiZiQf++cbrjltLA5NN/xaXfqeOBOSlMFbemIl5/S5tljmg==} cpu: [x64] os: [freebsd] - '@unrs/resolver-binding-linux-arm-gnueabihf@1.12.0': - resolution: {integrity: sha512-zuHruxqemJqM2lrVwIgw7o3/0rLrskWDqVRAc8974nNy3cZR2N9cfatIE5PzmSNeRSafh0rAaS3ev294yCyj7A==} + '@unrs/resolver-binding-linux-arm-gnueabihf@1.12.2': + resolution: {integrity: sha512-vZTDvdSISZjJx66OzJqtsOhzifbqRjbmI1Mnu49fQDwog5GtDI4QidRiEAYbZCRj9C8YZEW+3ZjqsyS9GR4k2A==} cpu: [arm] os: [linux] - '@unrs/resolver-binding-linux-arm-musleabihf@1.12.0': - resolution: {integrity: sha512-s2WgKQXQXhV14OT3jNoS1jN4c+8Mvamxq6jG3L7Igl8teXaGZvjI3RfZksqoxL3UAEin9UkZSApXZ+shocI1ZQ==} + '@unrs/resolver-binding-linux-arm-musleabihf@1.12.2': + resolution: {integrity: sha512-BiPI+IrIlwcW4nLLMM21+B1dFPzd55yAVgVGrdgDjNef+ch03GdxrcyaIz8X9SsQirh/kCQ7mviyWlMxdh2D7g==} cpu: [arm] os: [linux] - '@unrs/resolver-binding-linux-arm64-gnu@1.12.0': - resolution: {integrity: sha512-ghMWlxxa3aCW9sk5FpzrTXSo/NSanKs/RovDal5q+T2Q+dAKLFyGXWmQ6AAMsl6k/TgXHw+jj9Q9sELLx9mfJw==} + '@unrs/resolver-binding-linux-arm64-gnu@1.12.2': + resolution: {integrity: sha512-zJc0H99FEPoFfSrNpa91HYfxzfAJCr502oxNK1cfdC9hlaFI43RT+JFCann9JUgZmLzzntChHyn13Sgn9ljHNg==} cpu: [arm64] os: [linux] libc: [glibc] - '@unrs/resolver-binding-linux-arm64-musl@1.12.0': - resolution: {integrity: sha512-ldOaKTzXNIHjGzRtzgfh+g6mqt30Q8hnR+EFdfeKYgeuMqnwsllk6IaN2kadvuRRQNBr1ycI45pmgGA5EUxzuA==} + '@unrs/resolver-binding-linux-arm64-musl@1.12.2': + resolution: {integrity: sha512-KQ3Lki6l+Pz1k/eBipN41ES+YUK30beLGb9YqcB1O542cyLCNE6GaxrfcY3T6EezmGGk84wb5XyO9loTM9tkcA==} cpu: [arm64] os: [linux] libc: [musl] - '@unrs/resolver-binding-linux-ppc64-gnu@1.12.0': - resolution: {integrity: sha512-PQRjWSz5v+7K9CHh8a11t6JHfmuG2o3ozHgj/9IsEtSMBc/S8p8eZoJO0+i7FUq0JEjnIfLRLUADXOF/2jx4SQ==} + '@unrs/resolver-binding-linux-loong64-gnu@1.12.2': + resolution: {integrity: sha512-3SJGEh1DborhG6pyxvhPzCT4bbSIVihsvgJc13P1bHG7KLdNDaF9T3gsTwFc7Jw/5Y5/iWOjkEx7Zy0NvCGX3Q==} + cpu: [loong64] + os: [linux] + libc: [glibc] + + '@unrs/resolver-binding-linux-loong64-musl@1.12.2': + resolution: {integrity: sha512-jiuG/Obbel7uw1PwHNFfrkiKhLAF6mnyZ6aWlOAVN9WqKm8v0OFGnciJIHu8+CMvXLQ8AD51LPzAoUfT21D5Ew==} + cpu: [loong64] + os: [linux] + libc: [musl] + + '@unrs/resolver-binding-linux-ppc64-gnu@1.12.2': + resolution: {integrity: sha512-q7xRvVpmcfeL+LlZg8Pbbo6QaTZwDU5BaGZbwfhkEsXJn3Was8xYfE0RBH266xZt0rM6B7i8xAYIvjthuUIWHg==} cpu: [ppc64] os: [linux] libc: [glibc] - '@unrs/resolver-binding-linux-riscv64-gnu@1.12.0': - resolution: {integrity: sha512-slpQUuAp3+I0jsFyHxBaqETZSe8+OaG019nDOCBD0ZqZSNv0z7lMXKDgpH9BsSD+1Z5BSvV1QUbWS/MbGxpI+A==} + '@unrs/resolver-binding-linux-riscv64-gnu@1.12.2': + resolution: {integrity: sha512-0CVdx6lcnT3Q9inOH8tsMIOJ6ImndllMjqJHg8RLVdB7Vq4SfkEXl9mCSsVNuNA4MCYycRicCUxPCabVHJRr6A==} cpu: [riscv64] os: [linux] libc: [glibc] - '@unrs/resolver-binding-linux-riscv64-musl@1.12.0': - resolution: {integrity: sha512-v30e31aTFDfl1R+On53cNpd4sMQ+lzYTE4dxVia1B++Ds+27lEZSOlwjPfPN20mxb9ENis1mwUW+5SO6OzXJcA==} + '@unrs/resolver-binding-linux-riscv64-musl@1.12.2': + resolution: {integrity: sha512-iOwlRo9vnp6R6ohHQS11n0NnfdXx/omhkocmIfaPRpQhKZ+3BDMkkdRVh53qjkFkpPddf+FETA28NwGN7l5l+w==} cpu: [riscv64] os: [linux] libc: [musl] - '@unrs/resolver-binding-linux-s390x-gnu@1.12.0': - resolution: {integrity: sha512-yn6cnDhoH1IOgYvLnTeu7iAf1iknc7SXjqyLPCr3umbaeuFD8Uy2x3c3F82x2SDVEX/JpEkAGNd18lUBw4w9aQ==} + '@unrs/resolver-binding-linux-s390x-gnu@1.12.2': + resolution: {integrity: sha512-HYJtLfXq94q8iZNFT1lknx258wlkkWhZeUXJRqzKBBUJ00CvZ+N33zgbCqimLjsyw5Va6uUxhVa12mI+kaveEw==} cpu: [s390x] os: [linux] libc: [glibc] - '@unrs/resolver-binding-linux-x64-gnu@1.12.0': - resolution: {integrity: sha512-M0zUTXIoRbPdWmLOs8hG3CnLVKTMbcAkC1++GJzjLAlGfH5gvhbePa6+TFniTgqiizGr0/3fdXI7R8aNwy/N4g==} + '@unrs/resolver-binding-linux-x64-gnu@1.12.2': + resolution: {integrity: sha512-mPsUhunKKDih5O96Y6enDQyHc1SqBPlY1E/SfMWDM3EdJ95Z9CArPeCVwCCqbP45ljvivdEk8Fxn+SIb1rDAJQ==} cpu: [x64] os: [linux] libc: [glibc] - '@unrs/resolver-binding-linux-x64-musl@1.12.0': - resolution: {integrity: sha512-GJUwROe22qValEd7JRT7FG/u36Iv/IL9AedRw7pEdbc8KcfbODcygvQHAVigBFReylyLe8UkPYxJy7F5Sm+Ldw==} + '@unrs/resolver-binding-linux-x64-musl@1.12.2': + resolution: {integrity: sha512-azrt6+5ydLd8Vt210AAFis/lZevSfPw93EJRIJG+xPu4WCJ8K0kppCTpMyLPcKT7H15M4Jnt2tMp5bOvCkRC6A==} cpu: [x64] os: [linux] libc: [musl] - '@unrs/resolver-binding-openharmony-arm64@1.12.0': - resolution: {integrity: sha512-UwIkgOapYxrSPf8KTOtXeZKJD69upM9hQQuty1W0wQAJwsZrJSXFEoxuJ6lcjmEp/iJvx5PUknMqqBXJlzPTyw==} + '@unrs/resolver-binding-openharmony-arm64@1.12.2': + resolution: {integrity: sha512-YZ9hP4O0X9PQb8eO980qmLNGH4zT3I9+SZTdt0Pr0YyuGQhYKoOZkV02VzrzyOZJ5xIJ3UFIenKkUkGg8GjgWQ==} cpu: [arm64] os: [openharmony] - '@unrs/resolver-binding-wasm32-wasi@1.12.0': - resolution: {integrity: sha512-hE7r1jGIYXTR+inEZxKpUUT+P44RS/J5fz6x5UVvLjVsmHlkpeHOetRs5eglgoPskXwfROZlChCWBq+UoS+6Qg==} + '@unrs/resolver-binding-wasm32-wasi@1.12.2': + resolution: {integrity: sha512-tYFDIkMxSflfEc/h92ZWNsZlHSwgimbNHSO3PL2JWQHfCuC2q316jMyYU9TIWZsFK2bQwyK5VAdYgn8ygPj69A==} engines: {node: '>=14.0.0'} cpu: [wasm32] - '@unrs/resolver-binding-win32-arm64-msvc@1.12.0': - resolution: {integrity: sha512-zkwy74gxj0z6G6KxCaVsQJQDlLs8g3sUYtNJYrmThB0GHsK7cmCFtRLLqaeFUvf+K2lWG8KXv1PpQr18NgNOWw==} + '@unrs/resolver-binding-win32-arm64-msvc@1.12.2': + resolution: {integrity: sha512-qzNyg3xL0VPQmCaUh+N5jSitce6k+uCBfMDesWRnlULOZaqUkaJ0ybdT+UqlAWJoQjuqfIU/0Ptx9bteN4D82g==} cpu: [arm64] os: [win32] - '@unrs/resolver-binding-win32-ia32-msvc@1.12.0': - resolution: {integrity: sha512-dDLr9aigi1kz+sjL9o/TSVe+5Xf5zjSrXlSJALCJE2hY/J2Ml1qKxmFZYJVEWvp72hRjIxnHH83o0cPXLkJqiA==} + '@unrs/resolver-binding-win32-ia32-msvc@1.12.2': + resolution: {integrity: sha512-WD9sY00OfpHVGfsnHZoA8jVT+esS/Bg8z8jzxp5BnDCjjwsuKsPQrzswwpFy4J1AUJbXPRfkpcX0mXrzeXW79g==} cpu: [ia32] os: [win32] - '@unrs/resolver-binding-win32-x64-msvc@1.12.0': - resolution: {integrity: sha512-xLJGnOAnh4eYwZLoPW27FsCAI1zwgXpeOsxUUYRNjbSmEip5j4B8fPazsoicTN+YcaAET64JyuMvazxZUe/Wzg==} + '@unrs/resolver-binding-win32-x64-msvc@1.12.2': + resolution: {integrity: sha512-nAB74NfSNKknqQ1RrYj6uz8FcXEomu/MATJZxh/x+BArzN2U3JbOYC0APYzUIGhVY3m5hRxA8VPNdPBoG8txlA==} cpu: [x64] os: [win32] @@ -515,21 +531,21 @@ packages: peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - acorn@8.16.0: - resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} + acorn@8.17.0: + resolution: {integrity: sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==} engines: {node: '>=0.4.0'} hasBin: true ajv@6.15.0: resolution: {integrity: sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==} - ansis@4.3.0: - resolution: {integrity: sha512-44mvgtPvohuU/70DdY5Oz2AIrLJ9k6/5x4KmoSvPwO+5Moijo0+N9D0fKbbYZQWP1hNm5CpOf+E01jhxG/r8xg==} + ansis@4.3.1: + resolution: {integrity: sha512-BJ8/l4R5LRE7hW9WdSuGYrLSHi2ynxeFpDFbH0K/CgNeY/tyhk+vO6TYxXC5r5CpUhNVX310xzPsN/H9lCdfOA==} engines: {node: '>=14'} - ast-kit@3.0.0-beta.1: - resolution: {integrity: sha512-trmleAnZ2PxN/loHWVhhx1qeOHSRXq4TDsBBxq3GqeJitfk3+jTQ+v/C1km/KYq9M7wKqCewMh+/NAvVH7m+bw==} - engines: {node: '>=20.19.0'} + ast-kit@3.0.0: + resolution: {integrity: sha512-8OG92q3R35qjC/4i6BLBMg8IB+fClWu/1PEwg2Z9Rn+BuNaiEgJzpzn+pxWOdHJWDCAwu2JP0wCDTozAM4QirQ==} + engines: {node: ^22.18.0 || >=24.11.0} balanced-match@4.0.4: resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} @@ -546,8 +562,8 @@ packages: resolution: {integrity: sha512-tixWYgm5ZoOD+3g6UTea91eow5z6AAHaho3g0V9CNSNb45gM8SmflpAc+GRd1InC4AqN/07Unrgp56Y94N9hJQ==} engines: {node: '>=20.19.0'} - comment-parser@1.4.6: - resolution: {integrity: sha512-ObxuY6vnbWTN6Od72xfwN9DbzC7Y2vv8u1Soi9ahRKL37gb6y1qk6/dgjs+3JWuXJHWvsg3BXIwzd/rkmAwavg==} + comment-parser@1.4.7: + resolution: {integrity: sha512-0h+uSNtQGW3D98eQt3jJ8L06Fves8hncB4V/PKdw/Qb8Hnk19VaKuTr55UNRYiSoVa7WwrFls+rh3ux9agmkeQ==} engines: {node: '>= 12.0.0'} cross-spawn@7.0.6: @@ -569,8 +585,8 @@ packages: defu@6.1.7: resolution: {integrity: sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==} - discord-api-types@0.38.47: - resolution: {integrity: sha512-XgXQodHQBAE6kfD7kMvVo30863iHX1LHSqNq6MGUTDwIFCCvHva13+rwxyxVXDqudyApMNAd32PGjgVETi5rjA==} + discord-api-types@0.38.49: + resolution: {integrity: sha512-XnqcWmnFZFAE8ZM8SHAw9DIV8D3Or00rMQ8iQLotrEA2PmXhl+ykaf6L6q4l474hrSUH1JaYcv+iOMRWp2p6Tg==} discord.js@14.26.4: resolution: {integrity: sha512-4oBp8tc6Kf8IDBwAHhbsMaAqx1b5fob9SNasZT7V6yyyUydoO5i5fGuX7TmvRtR+q/WgKRnRViRoAWnG7fNyvA==} @@ -608,8 +624,8 @@ packages: unrs-resolver: optional: true - eslint-import-resolver-typescript@4.4.4: - resolution: {integrity: sha512-1iM2zeBvrYmUNTj2vSC/90JTHDth+dfOfiNKkxApWRsTJYNrc8rOdxxIf5vazX+BiAXTeOT0UvWpGI/7qIWQOw==} + eslint-import-resolver-typescript@4.4.5: + resolution: {integrity: sha512-nbE5XLph6TLtGYcu/U6e6ZVXyKBhbDWK5cLGk76eJ7NdZpwf1P9EFkpt1Z01mNZNrrilsAYWKH6zUkL4reoXbw==} engines: {node: ^16.17.0 || >=18.6.0} peerDependencies: eslint: '*' @@ -646,8 +662,8 @@ packages: resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} - eslint@10.4.0: - resolution: {integrity: sha512-loXy6bWOoP3EP6JA7jo6p5jMpBJmHmsNZM5SFRHLdh1MGOPurMnNBj4ZlAbaqUAaQWbCr7jHV4P7gzAyryZWkQ==} + eslint@10.5.0: + resolution: {integrity: sha512-1y+7C+vi12bUK1IpZeaV3gsH9fHLBmPvYmPx42pvT/E9yG0IC8g3PUZZgp0+JLJl7ZDK0flc2gc+Aw9dpCvIsQ==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} hasBin: true peerDependencies: @@ -730,8 +746,8 @@ packages: hookable@6.1.1: resolution: {integrity: sha512-U9LYDy1CwhMCnprUfeAZWZGByVbhd54hwepegYTK7Pi5NvqEj63ifz5z+xukznehT7i6NIZRu89Ay1AZmRsLEQ==} - i18next@26.2.0: - resolution: {integrity: sha512-zwBHldHdTmwN7r6UNc7lC6GWNN+YYg3DrRSeHR5PRRBf5QnJZcYHrQc0uaU26qZeYxR7iFZD+Y315dPnKP47wA==} + i18next@26.3.1: + resolution: {integrity: sha512-txQqd5EULsqEh9OJqRH15aCaOuy/nLJyhw5EHCSKLKJE1aBbb3Zve2+uQIxgWhPm1QqUQoWyQBm2kfmmIrzkcQ==} peerDependencies: typescript: ^5 || ^6 peerDependenciesMeta: @@ -829,8 +845,9 @@ packages: natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - obug@2.1.1: - resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} + obug@2.1.3: + resolution: {integrity: sha512-9miFgM2OFba7hB+pRgvtV84pYTBaoTHohvmIgiRt6dRIzbwEOIaNaP+dIlGs2fNFoB0SeISs0Jz5WFVRid6Xyg==} + engines: {node: '>=12.20.0'} optionator@0.9.4: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} @@ -863,8 +880,8 @@ packages: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} - prettier@3.8.3: - resolution: {integrity: sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==} + prettier@3.8.4: + resolution: {integrity: sha512-N2MylSdi48+5N/6S5j+maeHbUSIzzZ5uOcX5Hm4QpV8Dkb1HFjfAKTKX6yNPJQD9AhcT3ifHNB66tWTTJDi11Q==} engines: {node: '>=14'} hasBin: true @@ -878,15 +895,15 @@ packages: resolve-pkg-maps@1.0.0: resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} - rolldown-plugin-dts@0.25.1: - resolution: {integrity: sha512-zK82aC/8z1iVW+g0bCnlQZq04Y5bNeL/RcRwTYBwsnU6wH0N+6vpIFkN7JC0kYRS5qKA+pxQyfIPvXJ6Q5xSpQ==} - engines: {node: ^22.18.0 || >=24.0.0} + rolldown-plugin-dts@0.26.0: + resolution: {integrity: sha512-e+kEPtUiDES0htk5iqkSeF4EzAV7R+vugGB44iPDuw1Kw9E+WyL1VG7PaV0IIjGHLiacztMBcMTyrr8ON9CT1Q==} + engines: {node: ^22.18.0 || >=24.11.0} peerDependencies: '@ts-macro/tsc': ^0.3.6 '@typescript/native-preview': '>=7.0.0-dev.20260325.1' rolldown: ^1.0.0 typescript: ^5.0.0 || ^6.0.0 - vue-tsc: ~3.2.0 + vue-tsc: ~3.2.0 || ~3.3.0 peerDependenciesMeta: '@ts-macro/tsc': optional: true @@ -897,13 +914,13 @@ packages: vue-tsc: optional: true - rolldown@1.0.1: - resolution: {integrity: sha512-X0KQHljNnEkWNqqiz9zJrGunh1B0HgOxLXvnFpCOcadzcy5qohZ3tqMEUg00vncoRovXuK3ZqCT9KnnKzoInFQ==} + rolldown@1.1.2: + resolution: {integrity: sha512-x0CrQQqCXWGeI8dTvFfN/Dnv3yMKT9hv5jFjlOreKAx9wqLq9wz7VvLLHyaAXC90/CpggTu9SisSbsJJTPSjNQ==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true - semver@7.8.0: - resolution: {integrity: sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==} + semver@7.8.5: + resolution: {integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==} engines: {node: '>=10'} hasBin: true @@ -919,12 +936,12 @@ packages: resolution: {integrity: sha512-o3yWv49B/o4QZk5ZcsALc6t0+eCelPc44zZsLtCQnZPDwFpDYSWcDnrv2TtMmMbQ7uKo3J0HTURCqckw23czNQ==} engines: {node: '>=12.0.0'} - tinyexec@1.1.2: - resolution: {integrity: sha512-dAqSqE/RabpBKI8+h26GfLq6Vb3JVXs30XYQjdMjaj/c2tS8IYYMbIzP599KtRj7c57/wYApb3QjgRgXmrCukA==} + tinyexec@1.2.4: + resolution: {integrity: sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==} engines: {node: '>=18'} - tinyglobby@0.2.16: - resolution: {integrity: sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==} + tinyglobby@0.2.17: + resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} engines: {node: '>=12.0.0'} tree-kill@1.2.2: @@ -940,14 +957,14 @@ packages: ts-mixer@6.0.4: resolution: {integrity: sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA==} - tsdown@0.22.0: - resolution: {integrity: sha512-FgW0hHb27nGQA/+F3d5+U9wKXkfilk9DVkc5+7x/ZqF03g+Hoz/eeApT32jqxATt9eRoR+1jxk7MUMON+O4CXw==} - engines: {node: ^22.18.0 || >=24.0.0} + tsdown@0.22.3: + resolution: {integrity: sha512-louqbfA8Qf//B9jTTL0FPtXTNpjCWv1VPkbcmQMph2pTpzs+LnB1tbe4tDDRVpo2BjF5SgUXaTZe45SxB8pWHg==} + engines: {node: ^22.18.0 || >=24.11.0} hasBin: true peerDependencies: '@arethetypeswrong/core': ^0.18.1 - '@tsdown/css': 0.22.0 - '@tsdown/exe': 0.22.0 + '@tsdown/css': 0.22.3 + '@tsdown/exe': 0.22.3 '@vitejs/devtools': '*' publint: ^0.3.8 tsx: '*' @@ -981,8 +998,8 @@ packages: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} - typescript-eslint@8.59.4: - resolution: {integrity: sha512-Rw6+44QNFaXtgHSjPy+Kw8hrJniMYzR85E9yLmOLcfZ91/rz+JXQbDTCmc6ccxMPY6K6PgAq26f0JCBfR7LIPQ==} + typescript-eslint@8.61.1: + resolution: {integrity: sha512-V7PayAfJokV3pEHgN7/v03D1SpujhRfQtYLbLIiBfDDncdg4PAiRBfoS4cnCANK4jmAPncczi59QO3afiXUlNw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 @@ -996,15 +1013,15 @@ packages: unconfig-core@7.5.0: resolution: {integrity: sha512-Su3FauozOGP44ZmKdHy2oE6LPjk51M/TRRjHv2HNCWiDvfvCoxC2lno6jevMA91MYAdCdwP05QnWdWpSbncX/w==} - undici-types@7.24.6: - resolution: {integrity: sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==} + undici-types@8.3.0: + resolution: {integrity: sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==} undici@6.24.1: resolution: {integrity: sha512-sC+b0tB1whOCzbtlx20fx3WgCXwkW627p4EA9uM+/tNNPkSS+eSEld6pAs9nDv7WbY1UUljBMYPtu9BCOrCWKA==} engines: {node: '>=18.17'} - unrs-resolver@1.12.0: - resolution: {integrity: sha512-hiJjN9x3O/SF2yGpNX7swfg24bi4t+uqEww16EeH9LT2I6mkGNf8uZvAS9PL1pvkA/fBagTaxbgHfYQPRfahuQ==} + unrs-resolver@1.12.2: + resolution: {integrity: sha512-dmlRxBJJayXjqTwC+JtF1HhJmgf3ftQ3YejFcZrf4+KKtJv0qDsK1pjqaaVjG7wJ5NJ6UVP1OqRMQ71Z4C3rxQ==} uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} @@ -1018,8 +1035,8 @@ packages: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} - ws@8.20.1: - resolution: {integrity: sha512-It4dO0K5v//JtTXuPkfEOaI3uUN87iYPnqo/ZzqCoG3g8uhA66QUMs/SrM0YK7/NAu+r4LMh/9dq2A7k+rHs+w==} + ws@8.21.0: + resolution: {integrity: sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 @@ -1040,38 +1057,34 @@ packages: snapshots: - '@babel/generator@8.0.0-rc.5': + '@babel/generator@8.0.0': dependencies: - '@babel/parser': 8.0.0-rc.5 - '@babel/types': 8.0.0-rc.5 + '@babel/parser': 8.0.0 + '@babel/types': 8.0.0 '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 '@types/jsesc': 2.5.1 jsesc: 3.1.0 - '@babel/helper-string-parser@8.0.0-rc.5': {} + '@babel/helper-string-parser@8.0.0': {} - '@babel/helper-validator-identifier@8.0.0-rc.5': {} + '@babel/helper-validator-identifier@8.0.2': {} - '@babel/parser@8.0.0-rc.4': + '@babel/parser@8.0.0': dependencies: - '@babel/types': 8.0.0-rc.5 + '@babel/types': 8.0.0 - '@babel/parser@8.0.0-rc.5': + '@babel/types@8.0.0': dependencies: - '@babel/types': 8.0.0-rc.5 - - '@babel/types@8.0.0-rc.5': - dependencies: - '@babel/helper-string-parser': 8.0.0-rc.5 - '@babel/helper-validator-identifier': 8.0.0-rc.5 + '@babel/helper-string-parser': 8.0.0 + '@babel/helper-validator-identifier': 8.0.2 '@discordjs/builders@1.14.1': dependencies: '@discordjs/formatters': 0.6.2 '@discordjs/util': 1.2.0 '@sapphire/shapeshift': 4.0.0 - discord-api-types: 0.38.47 + discord-api-types: 0.38.49 fast-deep-equal: 3.1.3 ts-mixer: 6.0.4 tslib: 2.8.1 @@ -1082,7 +1095,7 @@ snapshots: '@discordjs/formatters@0.6.2': dependencies: - discord-api-types: 0.38.47 + discord-api-types: 0.38.49 '@discordjs/rest@2.6.1': dependencies: @@ -1091,14 +1104,14 @@ snapshots: '@sapphire/async-queue': 1.5.5 '@sapphire/snowflake': 3.5.5 '@vladfrangu/async_event_emitter': 2.4.7 - discord-api-types: 0.38.47 + discord-api-types: 0.38.49 magic-bytes.js: 1.13.0 tslib: 2.8.1 undici: 6.24.1 '@discordjs/util@1.2.0': dependencies: - discord-api-types: 0.38.47 + discord-api-types: 0.38.49 '@discordjs/ws@1.2.3': dependencies: @@ -1108,9 +1121,9 @@ snapshots: '@sapphire/async-queue': 1.5.5 '@types/ws': 8.18.1 '@vladfrangu/async_event_emitter': 2.4.7 - discord-api-types: 0.38.47 + discord-api-types: 0.38.49 tslib: 2.8.1 - ws: 8.20.1 + ws: 8.21.0 transitivePeerDependencies: - bufferutil - utf-8-validate @@ -1121,19 +1134,35 @@ snapshots: tslib: 2.8.1 optional: true + '@emnapi/core@1.11.1': + dependencies: + '@emnapi/wasi-threads': 1.2.2 + tslib: 2.8.1 + optional: true + '@emnapi/runtime@1.10.0': dependencies: tslib: 2.8.1 optional: true + '@emnapi/runtime@1.11.1': + dependencies: + tslib: 2.8.1 + optional: true + '@emnapi/wasi-threads@1.2.1': dependencies: tslib: 2.8.1 optional: true - '@eslint-community/eslint-utils@4.9.1(eslint@10.4.0(jiti@2.7.0))': + '@emnapi/wasi-threads@1.2.2': + dependencies: + tslib: 2.8.1 + optional: true + + '@eslint-community/eslint-utils@4.9.1(eslint@10.5.0(jiti@2.7.0))': dependencies: - eslint: 10.4.0(jiti@2.7.0) + eslint: 10.5.0(jiti@2.7.0) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.2': {} @@ -1154,13 +1183,13 @@ snapshots: dependencies: '@types/json-schema': 7.0.15 - '@eslint/js@10.0.1(eslint@10.4.0(jiti@2.7.0))': + '@eslint/js@10.0.1(eslint@10.5.0(jiti@2.7.0))': optionalDependencies: - eslint: 10.4.0(jiti@2.7.0) + eslint: 10.5.0(jiti@2.7.0) '@eslint/object-schema@3.0.5': {} - '@eslint/plugin-kit@0.7.1': + '@eslint/plugin-kit@0.7.2': dependencies: '@eslint/core': 1.2.1 levn: 0.4.1 @@ -1195,14 +1224,21 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 - '@napi-rs/wasm-runtime@1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': + '@napi-rs/wasm-runtime@1.1.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': dependencies: '@emnapi/core': 1.10.0 '@emnapi/runtime': 1.10.0 '@tybys/wasm-util': 0.10.2 optional: true - '@oxc-project/types@0.130.0': {} + '@napi-rs/wasm-runtime@1.1.5(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)': + dependencies: + '@emnapi/core': 1.11.1 + '@emnapi/runtime': 1.11.1 + '@tybys/wasm-util': 0.10.2 + optional: true + + '@oxc-project/types@0.137.0': {} '@package-json/types@0.0.12': {} @@ -1210,53 +1246,53 @@ snapshots: dependencies: quansync: 1.0.0 - '@rolldown/binding-android-arm64@1.0.1': + '@rolldown/binding-android-arm64@1.1.2': optional: true - '@rolldown/binding-darwin-arm64@1.0.1': + '@rolldown/binding-darwin-arm64@1.1.2': optional: true - '@rolldown/binding-darwin-x64@1.0.1': + '@rolldown/binding-darwin-x64@1.1.2': optional: true - '@rolldown/binding-freebsd-x64@1.0.1': + '@rolldown/binding-freebsd-x64@1.1.2': optional: true - '@rolldown/binding-linux-arm-gnueabihf@1.0.1': + '@rolldown/binding-linux-arm-gnueabihf@1.1.2': optional: true - '@rolldown/binding-linux-arm64-gnu@1.0.1': + '@rolldown/binding-linux-arm64-gnu@1.1.2': optional: true - '@rolldown/binding-linux-arm64-musl@1.0.1': + '@rolldown/binding-linux-arm64-musl@1.1.2': optional: true - '@rolldown/binding-linux-ppc64-gnu@1.0.1': + '@rolldown/binding-linux-ppc64-gnu@1.1.2': optional: true - '@rolldown/binding-linux-s390x-gnu@1.0.1': + '@rolldown/binding-linux-s390x-gnu@1.1.2': optional: true - '@rolldown/binding-linux-x64-gnu@1.0.1': + '@rolldown/binding-linux-x64-gnu@1.1.2': optional: true - '@rolldown/binding-linux-x64-musl@1.0.1': + '@rolldown/binding-linux-x64-musl@1.1.2': optional: true - '@rolldown/binding-openharmony-arm64@1.0.1': + '@rolldown/binding-openharmony-arm64@1.1.2': optional: true - '@rolldown/binding-wasm32-wasi@1.0.1': + '@rolldown/binding-wasm32-wasi@1.1.2': dependencies: - '@emnapi/core': 1.10.0 - '@emnapi/runtime': 1.10.0 - '@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + '@emnapi/core': 1.11.1 + '@emnapi/runtime': 1.11.1 + '@napi-rs/wasm-runtime': 1.1.5(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1) optional: true - '@rolldown/binding-win32-arm64-msvc@1.0.1': + '@rolldown/binding-win32-arm64-msvc@1.1.2': optional: true - '@rolldown/binding-win32-x64-msvc@1.0.1': + '@rolldown/binding-win32-x64-msvc@1.1.2': optional: true '@rolldown/pluginutils@1.0.1': {} @@ -1285,23 +1321,23 @@ snapshots: '@types/json-schema@7.0.15': {} - '@types/node@25.9.0': + '@types/node@26.0.0': dependencies: - undici-types: 7.24.6 + undici-types: 8.3.0 '@types/ws@8.18.1': dependencies: - '@types/node': 25.9.0 + '@types/node': 26.0.0 - '@typescript-eslint/eslint-plugin@8.59.4(@typescript-eslint/parser@8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3)': + '@typescript-eslint/eslint-plugin@8.61.1(@typescript-eslint/parser@8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3) - '@typescript-eslint/scope-manager': 8.59.4 - '@typescript-eslint/type-utils': 8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3) - '@typescript-eslint/utils': 8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3) - '@typescript-eslint/visitor-keys': 8.59.4 - eslint: 10.4.0(jiti@2.7.0) + '@typescript-eslint/parser': 8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/scope-manager': 8.61.1 + '@typescript-eslint/type-utils': 8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/utils': 8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/visitor-keys': 8.61.1 + eslint: 10.5.0(jiti@2.7.0) ignore: 7.0.5 natural-compare: 1.4.0 ts-api-utils: 2.5.0(typescript@6.0.3) @@ -1309,152 +1345,158 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3)': + '@typescript-eslint/parser@8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3)': dependencies: - '@typescript-eslint/scope-manager': 8.59.4 - '@typescript-eslint/types': 8.59.4 - '@typescript-eslint/typescript-estree': 8.59.4(typescript@6.0.3) - '@typescript-eslint/visitor-keys': 8.59.4 + '@typescript-eslint/scope-manager': 8.61.1 + '@typescript-eslint/types': 8.61.1 + '@typescript-eslint/typescript-estree': 8.61.1(typescript@6.0.3) + '@typescript-eslint/visitor-keys': 8.61.1 debug: 4.4.3 - eslint: 10.4.0(jiti@2.7.0) + eslint: 10.5.0(jiti@2.7.0) typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.59.4(typescript@6.0.3)': + '@typescript-eslint/project-service@8.61.1(typescript@6.0.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.59.4(typescript@6.0.3) - '@typescript-eslint/types': 8.59.4 + '@typescript-eslint/tsconfig-utils': 8.61.1(typescript@6.0.3) + '@typescript-eslint/types': 8.61.1 debug: 4.4.3 typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.59.4': + '@typescript-eslint/scope-manager@8.61.1': dependencies: - '@typescript-eslint/types': 8.59.4 - '@typescript-eslint/visitor-keys': 8.59.4 + '@typescript-eslint/types': 8.61.1 + '@typescript-eslint/visitor-keys': 8.61.1 - '@typescript-eslint/tsconfig-utils@8.59.4(typescript@6.0.3)': + '@typescript-eslint/tsconfig-utils@8.61.1(typescript@6.0.3)': dependencies: typescript: 6.0.3 - '@typescript-eslint/type-utils@8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3)': + '@typescript-eslint/type-utils@8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3)': dependencies: - '@typescript-eslint/types': 8.59.4 - '@typescript-eslint/typescript-estree': 8.59.4(typescript@6.0.3) - '@typescript-eslint/utils': 8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/types': 8.61.1 + '@typescript-eslint/typescript-estree': 8.61.1(typescript@6.0.3) + '@typescript-eslint/utils': 8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) debug: 4.4.3 - eslint: 10.4.0(jiti@2.7.0) + eslint: 10.5.0(jiti@2.7.0) ts-api-utils: 2.5.0(typescript@6.0.3) typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.59.4': {} + '@typescript-eslint/types@8.61.1': {} - '@typescript-eslint/typescript-estree@8.59.4(typescript@6.0.3)': + '@typescript-eslint/typescript-estree@8.61.1(typescript@6.0.3)': dependencies: - '@typescript-eslint/project-service': 8.59.4(typescript@6.0.3) - '@typescript-eslint/tsconfig-utils': 8.59.4(typescript@6.0.3) - '@typescript-eslint/types': 8.59.4 - '@typescript-eslint/visitor-keys': 8.59.4 + '@typescript-eslint/project-service': 8.61.1(typescript@6.0.3) + '@typescript-eslint/tsconfig-utils': 8.61.1(typescript@6.0.3) + '@typescript-eslint/types': 8.61.1 + '@typescript-eslint/visitor-keys': 8.61.1 debug: 4.4.3 minimatch: 10.2.5 - semver: 7.8.0 - tinyglobby: 0.2.16 + semver: 7.8.5 + tinyglobby: 0.2.17 ts-api-utils: 2.5.0(typescript@6.0.3) typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3)': + '@typescript-eslint/utils@8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3)': dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.4.0(jiti@2.7.0)) - '@typescript-eslint/scope-manager': 8.59.4 - '@typescript-eslint/types': 8.59.4 - '@typescript-eslint/typescript-estree': 8.59.4(typescript@6.0.3) - eslint: 10.4.0(jiti@2.7.0) + '@eslint-community/eslint-utils': 4.9.1(eslint@10.5.0(jiti@2.7.0)) + '@typescript-eslint/scope-manager': 8.61.1 + '@typescript-eslint/types': 8.61.1 + '@typescript-eslint/typescript-estree': 8.61.1(typescript@6.0.3) + eslint: 10.5.0(jiti@2.7.0) typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.59.4': + '@typescript-eslint/visitor-keys@8.61.1': dependencies: - '@typescript-eslint/types': 8.59.4 + '@typescript-eslint/types': 8.61.1 eslint-visitor-keys: 5.0.1 - '@unrs/resolver-binding-android-arm-eabi@1.12.0': + '@unrs/resolver-binding-android-arm-eabi@1.12.2': + optional: true + + '@unrs/resolver-binding-android-arm64@1.12.2': + optional: true + + '@unrs/resolver-binding-darwin-arm64@1.12.2': optional: true - '@unrs/resolver-binding-android-arm64@1.12.0': + '@unrs/resolver-binding-darwin-x64@1.12.2': optional: true - '@unrs/resolver-binding-darwin-arm64@1.12.0': + '@unrs/resolver-binding-freebsd-x64@1.12.2': optional: true - '@unrs/resolver-binding-darwin-x64@1.12.0': + '@unrs/resolver-binding-linux-arm-gnueabihf@1.12.2': optional: true - '@unrs/resolver-binding-freebsd-x64@1.12.0': + '@unrs/resolver-binding-linux-arm-musleabihf@1.12.2': optional: true - '@unrs/resolver-binding-linux-arm-gnueabihf@1.12.0': + '@unrs/resolver-binding-linux-arm64-gnu@1.12.2': optional: true - '@unrs/resolver-binding-linux-arm-musleabihf@1.12.0': + '@unrs/resolver-binding-linux-arm64-musl@1.12.2': optional: true - '@unrs/resolver-binding-linux-arm64-gnu@1.12.0': + '@unrs/resolver-binding-linux-loong64-gnu@1.12.2': optional: true - '@unrs/resolver-binding-linux-arm64-musl@1.12.0': + '@unrs/resolver-binding-linux-loong64-musl@1.12.2': optional: true - '@unrs/resolver-binding-linux-ppc64-gnu@1.12.0': + '@unrs/resolver-binding-linux-ppc64-gnu@1.12.2': optional: true - '@unrs/resolver-binding-linux-riscv64-gnu@1.12.0': + '@unrs/resolver-binding-linux-riscv64-gnu@1.12.2': optional: true - '@unrs/resolver-binding-linux-riscv64-musl@1.12.0': + '@unrs/resolver-binding-linux-riscv64-musl@1.12.2': optional: true - '@unrs/resolver-binding-linux-s390x-gnu@1.12.0': + '@unrs/resolver-binding-linux-s390x-gnu@1.12.2': optional: true - '@unrs/resolver-binding-linux-x64-gnu@1.12.0': + '@unrs/resolver-binding-linux-x64-gnu@1.12.2': optional: true - '@unrs/resolver-binding-linux-x64-musl@1.12.0': + '@unrs/resolver-binding-linux-x64-musl@1.12.2': optional: true - '@unrs/resolver-binding-openharmony-arm64@1.12.0': + '@unrs/resolver-binding-openharmony-arm64@1.12.2': optional: true - '@unrs/resolver-binding-wasm32-wasi@1.12.0': + '@unrs/resolver-binding-wasm32-wasi@1.12.2': dependencies: '@emnapi/core': 1.10.0 '@emnapi/runtime': 1.10.0 - '@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + '@napi-rs/wasm-runtime': 1.1.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) optional: true - '@unrs/resolver-binding-win32-arm64-msvc@1.12.0': + '@unrs/resolver-binding-win32-arm64-msvc@1.12.2': optional: true - '@unrs/resolver-binding-win32-ia32-msvc@1.12.0': + '@unrs/resolver-binding-win32-ia32-msvc@1.12.2': optional: true - '@unrs/resolver-binding-win32-x64-msvc@1.12.0': + '@unrs/resolver-binding-win32-x64-msvc@1.12.2': optional: true '@vladfrangu/async_event_emitter@2.4.7': {} - acorn-jsx@5.3.2(acorn@8.16.0): + acorn-jsx@5.3.2(acorn@8.17.0): dependencies: - acorn: 8.16.0 + acorn: 8.17.0 - acorn@8.16.0: {} + acorn@8.17.0: {} ajv@6.15.0: dependencies: @@ -1463,11 +1505,11 @@ snapshots: json-schema-traverse: 0.4.1 uri-js: 4.4.1 - ansis@4.3.0: {} + ansis@4.3.1: {} - ast-kit@3.0.0-beta.1: + ast-kit@3.0.0: dependencies: - '@babel/parser': 8.0.0-rc.4 + '@babel/parser': 8.0.0 estree-walker: 3.0.3 pathe: 2.0.3 @@ -1481,7 +1523,7 @@ snapshots: cac@7.0.0: {} - comment-parser@1.4.6: {} + comment-parser@1.4.7: {} cross-spawn@7.0.6: dependencies: @@ -1497,7 +1539,7 @@ snapshots: defu@6.1.7: {} - discord-api-types@0.38.47: {} + discord-api-types@0.38.49: {} discord.js@14.26.4: dependencies: @@ -1508,7 +1550,7 @@ snapshots: '@discordjs/util': 1.2.0 '@discordjs/ws': 1.2.3 '@sapphire/snowflake': 3.5.3 - discord-api-types: 0.38.47 + discord-api-types: 0.38.49 fast-deep-equal: 3.1.3 lodash.snakecase: 4.1.1 magic-bytes.js: 1.13.0 @@ -1524,47 +1566,47 @@ snapshots: escape-string-regexp@4.0.0: {} - eslint-config-prettier@10.1.8(eslint@10.4.0(jiti@2.7.0)): + eslint-config-prettier@10.1.8(eslint@10.5.0(jiti@2.7.0)): dependencies: - eslint: 10.4.0(jiti@2.7.0) + eslint: 10.5.0(jiti@2.7.0) - eslint-import-context@0.1.9(unrs-resolver@1.12.0): + eslint-import-context@0.1.9(unrs-resolver@1.12.2): dependencies: get-tsconfig: 4.14.0 stable-hash-x: 0.2.0 optionalDependencies: - unrs-resolver: 1.12.0 + unrs-resolver: 1.12.2 - eslint-import-resolver-typescript@4.4.4(eslint-plugin-import-x@4.16.2(@typescript-eslint/utils@8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.4.0(jiti@2.7.0)))(eslint@10.4.0(jiti@2.7.0)): + eslint-import-resolver-typescript@4.4.5(eslint-plugin-import-x@4.16.2(@typescript-eslint/utils@8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.5.0(jiti@2.7.0)))(eslint@10.5.0(jiti@2.7.0)): dependencies: debug: 4.4.3 - eslint: 10.4.0(jiti@2.7.0) - eslint-import-context: 0.1.9(unrs-resolver@1.12.0) + eslint: 10.5.0(jiti@2.7.0) + eslint-import-context: 0.1.9(unrs-resolver@1.12.2) get-tsconfig: 4.14.0 is-bun-module: 2.0.0 stable-hash-x: 0.2.0 - tinyglobby: 0.2.16 - unrs-resolver: 1.12.0 + tinyglobby: 0.2.17 + unrs-resolver: 1.12.2 optionalDependencies: - eslint-plugin-import-x: 4.16.2(@typescript-eslint/utils@8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.4.0(jiti@2.7.0)) + eslint-plugin-import-x: 4.16.2(@typescript-eslint/utils@8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.5.0(jiti@2.7.0)) transitivePeerDependencies: - supports-color - eslint-plugin-import-x@4.16.2(@typescript-eslint/utils@8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.4.0(jiti@2.7.0)): + eslint-plugin-import-x@4.16.2(@typescript-eslint/utils@8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.5.0(jiti@2.7.0)): dependencies: '@package-json/types': 0.0.12 - '@typescript-eslint/types': 8.59.4 - comment-parser: 1.4.6 + '@typescript-eslint/types': 8.61.1 + comment-parser: 1.4.7 debug: 4.4.3 - eslint: 10.4.0(jiti@2.7.0) - eslint-import-context: 0.1.9(unrs-resolver@1.12.0) + eslint: 10.5.0(jiti@2.7.0) + eslint-import-context: 0.1.9(unrs-resolver@1.12.2) is-glob: 4.0.3 minimatch: 10.2.5 - semver: 7.8.0 + semver: 7.8.5 stable-hash-x: 0.2.0 - unrs-resolver: 1.12.0 + unrs-resolver: 1.12.2 optionalDependencies: - '@typescript-eslint/utils': 8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/utils': 8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) transitivePeerDependencies: - supports-color @@ -1579,14 +1621,14 @@ snapshots: eslint-visitor-keys@5.0.1: {} - eslint@10.4.0(jiti@2.7.0): + eslint@10.5.0(jiti@2.7.0): dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.4.0(jiti@2.7.0)) + '@eslint-community/eslint-utils': 4.9.1(eslint@10.5.0(jiti@2.7.0)) '@eslint-community/regexpp': 4.12.2 '@eslint/config-array': 0.23.5 '@eslint/config-helpers': 0.6.0 '@eslint/core': 1.2.1 - '@eslint/plugin-kit': 0.7.1 + '@eslint/plugin-kit': 0.7.2 '@humanfs/node': 0.16.8 '@humanwhocodes/module-importer': 1.0.1 '@humanwhocodes/retry': 0.4.3 @@ -1618,8 +1660,8 @@ snapshots: espree@11.2.0: dependencies: - acorn: 8.16.0 - acorn-jsx: 5.3.2(acorn@8.16.0) + acorn: 8.17.0 + acorn-jsx: 5.3.2(acorn@8.17.0) eslint-visitor-keys: 5.0.1 esquery@1.7.0: @@ -1680,7 +1722,7 @@ snapshots: hookable@6.1.1: {} - i18next@26.2.0(typescript@6.0.3): + i18next@26.3.1(typescript@6.0.3): optionalDependencies: typescript: 6.0.3 @@ -1694,7 +1736,7 @@ snapshots: is-bun-module@2.0.0: dependencies: - semver: 7.8.0 + semver: 7.8.5 is-extglob@2.1.1: {} @@ -1750,7 +1792,7 @@ snapshots: natural-compare@1.4.0: {} - obug@2.1.1: {} + obug@2.1.3: {} optionator@0.9.4: dependencies: @@ -1779,7 +1821,7 @@ snapshots: prelude-ls@1.2.1: {} - prettier@3.8.3: {} + prettier@3.8.4: {} punycode@2.3.1: {} @@ -1787,44 +1829,44 @@ snapshots: resolve-pkg-maps@1.0.0: {} - rolldown-plugin-dts@0.25.1(rolldown@1.0.1)(typescript@6.0.3): + rolldown-plugin-dts@0.26.0(rolldown@1.1.2)(typescript@6.0.3): dependencies: - '@babel/generator': 8.0.0-rc.5 - '@babel/helper-validator-identifier': 8.0.0-rc.5 - '@babel/parser': 8.0.0-rc.4 - ast-kit: 3.0.0-beta.1 + '@babel/generator': 8.0.0 + '@babel/helper-validator-identifier': 8.0.2 + '@babel/parser': 8.0.0 + ast-kit: 3.0.0 birpc: 4.0.0 dts-resolver: 3.0.0 get-tsconfig: 5.0.0-beta.5 - obug: 2.1.1 - rolldown: 1.0.1 + obug: 2.1.3 + rolldown: 1.1.2 optionalDependencies: typescript: 6.0.3 transitivePeerDependencies: - oxc-resolver - rolldown@1.0.1: + rolldown@1.1.2: dependencies: - '@oxc-project/types': 0.130.0 + '@oxc-project/types': 0.137.0 '@rolldown/pluginutils': 1.0.1 optionalDependencies: - '@rolldown/binding-android-arm64': 1.0.1 - '@rolldown/binding-darwin-arm64': 1.0.1 - '@rolldown/binding-darwin-x64': 1.0.1 - '@rolldown/binding-freebsd-x64': 1.0.1 - '@rolldown/binding-linux-arm-gnueabihf': 1.0.1 - '@rolldown/binding-linux-arm64-gnu': 1.0.1 - '@rolldown/binding-linux-arm64-musl': 1.0.1 - '@rolldown/binding-linux-ppc64-gnu': 1.0.1 - '@rolldown/binding-linux-s390x-gnu': 1.0.1 - '@rolldown/binding-linux-x64-gnu': 1.0.1 - '@rolldown/binding-linux-x64-musl': 1.0.1 - '@rolldown/binding-openharmony-arm64': 1.0.1 - '@rolldown/binding-wasm32-wasi': 1.0.1 - '@rolldown/binding-win32-arm64-msvc': 1.0.1 - '@rolldown/binding-win32-x64-msvc': 1.0.1 - - semver@7.8.0: {} + '@rolldown/binding-android-arm64': 1.1.2 + '@rolldown/binding-darwin-arm64': 1.1.2 + '@rolldown/binding-darwin-x64': 1.1.2 + '@rolldown/binding-freebsd-x64': 1.1.2 + '@rolldown/binding-linux-arm-gnueabihf': 1.1.2 + '@rolldown/binding-linux-arm64-gnu': 1.1.2 + '@rolldown/binding-linux-arm64-musl': 1.1.2 + '@rolldown/binding-linux-ppc64-gnu': 1.1.2 + '@rolldown/binding-linux-s390x-gnu': 1.1.2 + '@rolldown/binding-linux-x64-gnu': 1.1.2 + '@rolldown/binding-linux-x64-musl': 1.1.2 + '@rolldown/binding-openharmony-arm64': 1.1.2 + '@rolldown/binding-wasm32-wasi': 1.1.2 + '@rolldown/binding-win32-arm64-msvc': 1.1.2 + '@rolldown/binding-win32-x64-msvc': 1.1.2 + + semver@7.8.5: {} shebang-command@2.0.0: dependencies: @@ -1834,9 +1876,9 @@ snapshots: stable-hash-x@0.2.0: {} - tinyexec@1.1.2: {} + tinyexec@1.2.4: {} - tinyglobby@0.2.16: + tinyglobby@0.2.17: dependencies: fdir: 6.5.0(picomatch@4.0.4) picomatch: 4.0.4 @@ -1849,21 +1891,21 @@ snapshots: ts-mixer@6.0.4: {} - tsdown@0.22.0(typescript@6.0.3): + tsdown@0.22.3(typescript@6.0.3): dependencies: - ansis: 4.3.0 + ansis: 4.3.1 cac: 7.0.0 defu: 6.1.7 empathic: 2.0.1 hookable: 6.1.1 import-without-cache: 0.4.0 - obug: 2.1.1 + obug: 2.1.3 picomatch: 4.0.4 - rolldown: 1.0.1 - rolldown-plugin-dts: 0.25.1(rolldown@1.0.1)(typescript@6.0.3) - semver: 7.8.0 - tinyexec: 1.1.2 - tinyglobby: 0.2.16 + rolldown: 1.1.2 + rolldown-plugin-dts: 0.26.0(rolldown@1.1.2)(typescript@6.0.3) + semver: 7.8.5 + tinyexec: 1.2.4 + tinyglobby: 0.2.17 tree-kill: 1.2.2 unconfig-core: 7.5.0 optionalDependencies: @@ -1880,13 +1922,13 @@ snapshots: dependencies: prelude-ls: 1.2.1 - typescript-eslint@8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3): + typescript-eslint@8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.59.4(@typescript-eslint/parser@8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3) - '@typescript-eslint/parser': 8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3) - '@typescript-eslint/typescript-estree': 8.59.4(typescript@6.0.3) - '@typescript-eslint/utils': 8.59.4(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3) - eslint: 10.4.0(jiti@2.7.0) + '@typescript-eslint/eslint-plugin': 8.61.1(@typescript-eslint/parser@8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/parser': 8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/typescript-estree': 8.61.1(typescript@6.0.3) + '@typescript-eslint/utils': 8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + eslint: 10.5.0(jiti@2.7.0) typescript: 6.0.3 transitivePeerDependencies: - supports-color @@ -1898,34 +1940,36 @@ snapshots: '@quansync/fs': 1.0.0 quansync: 1.0.0 - undici-types@7.24.6: {} + undici-types@8.3.0: {} undici@6.24.1: {} - unrs-resolver@1.12.0: + unrs-resolver@1.12.2: dependencies: napi-postinstall: 0.3.4 optionalDependencies: - '@unrs/resolver-binding-android-arm-eabi': 1.12.0 - '@unrs/resolver-binding-android-arm64': 1.12.0 - '@unrs/resolver-binding-darwin-arm64': 1.12.0 - '@unrs/resolver-binding-darwin-x64': 1.12.0 - '@unrs/resolver-binding-freebsd-x64': 1.12.0 - '@unrs/resolver-binding-linux-arm-gnueabihf': 1.12.0 - '@unrs/resolver-binding-linux-arm-musleabihf': 1.12.0 - '@unrs/resolver-binding-linux-arm64-gnu': 1.12.0 - '@unrs/resolver-binding-linux-arm64-musl': 1.12.0 - '@unrs/resolver-binding-linux-ppc64-gnu': 1.12.0 - '@unrs/resolver-binding-linux-riscv64-gnu': 1.12.0 - '@unrs/resolver-binding-linux-riscv64-musl': 1.12.0 - '@unrs/resolver-binding-linux-s390x-gnu': 1.12.0 - '@unrs/resolver-binding-linux-x64-gnu': 1.12.0 - '@unrs/resolver-binding-linux-x64-musl': 1.12.0 - '@unrs/resolver-binding-openharmony-arm64': 1.12.0 - '@unrs/resolver-binding-wasm32-wasi': 1.12.0 - '@unrs/resolver-binding-win32-arm64-msvc': 1.12.0 - '@unrs/resolver-binding-win32-ia32-msvc': 1.12.0 - '@unrs/resolver-binding-win32-x64-msvc': 1.12.0 + '@unrs/resolver-binding-android-arm-eabi': 1.12.2 + '@unrs/resolver-binding-android-arm64': 1.12.2 + '@unrs/resolver-binding-darwin-arm64': 1.12.2 + '@unrs/resolver-binding-darwin-x64': 1.12.2 + '@unrs/resolver-binding-freebsd-x64': 1.12.2 + '@unrs/resolver-binding-linux-arm-gnueabihf': 1.12.2 + '@unrs/resolver-binding-linux-arm-musleabihf': 1.12.2 + '@unrs/resolver-binding-linux-arm64-gnu': 1.12.2 + '@unrs/resolver-binding-linux-arm64-musl': 1.12.2 + '@unrs/resolver-binding-linux-loong64-gnu': 1.12.2 + '@unrs/resolver-binding-linux-loong64-musl': 1.12.2 + '@unrs/resolver-binding-linux-ppc64-gnu': 1.12.2 + '@unrs/resolver-binding-linux-riscv64-gnu': 1.12.2 + '@unrs/resolver-binding-linux-riscv64-musl': 1.12.2 + '@unrs/resolver-binding-linux-s390x-gnu': 1.12.2 + '@unrs/resolver-binding-linux-x64-gnu': 1.12.2 + '@unrs/resolver-binding-linux-x64-musl': 1.12.2 + '@unrs/resolver-binding-openharmony-arm64': 1.12.2 + '@unrs/resolver-binding-wasm32-wasi': 1.12.2 + '@unrs/resolver-binding-win32-arm64-msvc': 1.12.2 + '@unrs/resolver-binding-win32-ia32-msvc': 1.12.2 + '@unrs/resolver-binding-win32-x64-msvc': 1.12.2 uri-js@4.4.1: dependencies: @@ -1937,7 +1981,7 @@ snapshots: word-wrap@1.2.5: {} - ws@8.20.1: {} + ws@8.21.0: {} yocto-queue@0.1.0: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index f8cf35d..6b457c8 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -2,4 +2,6 @@ packages: - "." allowBuilds: - unrs-resolver: true \ No newline at end of file + unrs-resolver: true + +minimumReleaseAge: 0 \ No newline at end of file diff --git a/src/client/StelliaClient.ts b/src/client/StelliaClient.ts index bc28514..22c582d 100644 --- a/src/client/StelliaClient.ts +++ b/src/client/StelliaClient.ts @@ -100,9 +100,7 @@ export class StelliaClient extends Client( - guildId: string - ): CustomGuildConfiguration | null => { + public getGuildConfiguration = (guildId: string): CustomGuildConfiguration | null => { return this.utils.getGuildConfiguration(guildId); }; diff --git a/src/structures/index.ts b/src/structures/index.ts index 8693d51..439bc65 100644 --- a/src/structures/index.ts +++ b/src/structures/index.ts @@ -1,2 +1,3 @@ +export * from "@structures/paginators/index.js"; export * from "@structures/Event.js"; export * from "@structures/Interaction.js"; diff --git a/src/structures/paginators/builders/BasePaginatorBuilder.ts b/src/structures/paginators/builders/BasePaginatorBuilder.ts new file mode 100644 index 0000000..9ba97cc --- /dev/null +++ b/src/structures/paginators/builders/BasePaginatorBuilder.ts @@ -0,0 +1,75 @@ +import { type ComponentEmojiResolvable, type ContainerBuilder } from "discord.js"; + +export abstract class BasePaginatorBuilder { + protected pages: T; + protected timeout?: number; + protected firstPageLabel?: string; + protected previousPageLabel?: string; + protected nextPageLabel?: string; + protected lastPageLabel?: string; + protected firstPageEmoji?: ComponentEmojiResolvable; + protected previousPageEmoji?: ComponentEmojiResolvable; + protected nextPageEmoji?: ComponentEmojiResolvable; + protected lastPageEmoji?: ComponentEmojiResolvable; + protected showFirstLastButtons?: boolean; + + setPages(pages: T): this { + this.pages = pages; + return this; + } + + addPage(page: ContainerBuilder): this { + this.pages.push(page); + return this; + } + + setTimeout(seconds: number): this { + this.timeout = seconds * 1000; + return this; + } + + setFirstPageLabel(label: string): this { + this.firstPageLabel = label; + return this; + } + + setPreviousPageLabel(label: string): this { + this.previousPageLabel = label; + return this; + } + + setNextPageLabel(label: string): this { + this.nextPageLabel = label; + return this; + } + + setLastPageLabel(label: string): this { + this.lastPageLabel = label; + return this; + } + + setFirstPageEmoji(emoji: ComponentEmojiResolvable): this { + this.firstPageEmoji = emoji; + return this; + } + + setPreviousPageEmoji(emoji: ComponentEmojiResolvable): this { + this.previousPageEmoji = emoji; + return this; + } + + setNextPageEmoji(emoji: ComponentEmojiResolvable): this { + this.nextPageEmoji = emoji; + return this; + } + + setLastPageEmoji(emoji: ComponentEmojiResolvable): this { + this.lastPageEmoji = emoji; + return this; + } + + setShowFirstLastButtons(show: boolean): this { + this.showFirstLastButtons = show; + return this; + } +} \ No newline at end of file diff --git a/src/structures/paginators/builders/PaginatorContainerBuilder.ts b/src/structures/paginators/builders/PaginatorContainerBuilder.ts new file mode 100644 index 0000000..0453251 --- /dev/null +++ b/src/structures/paginators/builders/PaginatorContainerBuilder.ts @@ -0,0 +1,21 @@ +import { type ContainerBuilder } from "discord.js"; +import { BasePaginatorBuilder } from "structures/paginators/builders/BasePaginatorBuilder.js"; +import { PaginatorContainerComponent, type PaginatorContainerComponents } from "structures/paginators/components/PaginatorContainerComponent.js"; + +export class PaginatorContainerBuilder extends BasePaginatorBuilder{ + build(): PaginatorContainerComponents { + return new PaginatorContainerComponent({ + pages: this.pages, + timeout: this.timeout, + firstPageLabel: this.firstPageLabel, + previousPageLabel: this.previousPageLabel, + nextPageLabel: this.nextPageLabel, + lastPageLabel: this.lastPageLabel, + firstPageEmoji: this.firstPageEmoji, + previousPageEmoji: this.previousPageEmoji, + nextPageEmoji: this.nextPageEmoji, + lastPageEmoji: this.lastPageEmoji, + showFirstLastButtons: this.showFirstLastButtons + }).build(); + } +} diff --git a/src/structures/paginators/builders/PaginatorEmbedBuilder.ts b/src/structures/paginators/builders/PaginatorEmbedBuilder.ts new file mode 100644 index 0000000..27df0e8 --- /dev/null +++ b/src/structures/paginators/builders/PaginatorEmbedBuilder.ts @@ -0,0 +1,23 @@ +import { type APIEmbed } from "discord.js"; +import { BasePaginatorBuilder } from "structures/paginators/builders/BasePaginatorBuilder.js"; +import { + PaginatorEmbedComponent, type PaginatorEmbedComponents +} from "structures/paginators/components/PaginatorEmbedComponent.js"; + +export class PaginatorEmbedBuilder extends BasePaginatorBuilder { + build(): PaginatorEmbedComponents { + return new PaginatorEmbedComponent({ + pages: this.pages, + timeout: this.timeout, + firstPageLabel: this.firstPageLabel, + previousPageLabel: this.previousPageLabel, + nextPageLabel: this.nextPageLabel, + lastPageLabel: this.lastPageLabel, + firstPageEmoji: this.firstPageEmoji, + previousPageEmoji: this.previousPageEmoji, + nextPageEmoji: this.nextPageEmoji, + lastPageEmoji: this.lastPageEmoji, + showFirstLastButtons: this.showFirstLastButtons, + }).build(); + } +} diff --git a/src/structures/paginators/builders/PaginatorSelectMenuBuilder.ts b/src/structures/paginators/builders/PaginatorSelectMenuBuilder.ts new file mode 100644 index 0000000..c6e08fe --- /dev/null +++ b/src/structures/paginators/builders/PaginatorSelectMenuBuilder.ts @@ -0,0 +1,85 @@ +import { type APISelectMenuOption, type ComponentEmojiResolvable } from "discord.js"; +import { PaginatorSelectMenuComponent, type PaginatorSelectMenuComponents } from "structures/paginators/components/PaginatorSelectMenuComponent.js"; + +export class PaginatorSelectMenuBuilder { + private customId: string; + private options: APISelectMenuOption[] = []; + private placeholder?: string; + private chunkSize?: number; + private timeout?: number; + private nextPageLabel?: string; + private nextPageEmoji: ComponentEmojiResolvable; + private previousPageLabel?: string; + private previousPageEmoji: ComponentEmojiResolvable; + + setCustomId(customId: string): this { + this.customId = customId; + return this; + } + + setOptions(options: APISelectMenuOption[]): this { + this.options = options; + return this; + } + + addOption(option: APISelectMenuOption): this { + this.options.push(option); + return this; + } + + setPlaceholder(placeholder: string): this { + this.placeholder = placeholder; + return this; + } + + setChunkSize(chunkSize: number): this { + this.chunkSize = chunkSize; + return this; + } + + setTimeout(timeout: number): this { + this.timeout = timeout * 1000; + return this; + } + + setNextPageLabel(label: string): this { + this.nextPageLabel = label; + return this; + } + + setNextPageEmoji(emoji: ComponentEmojiResolvable): this { + this.nextPageEmoji = emoji; + return this; + } + + setPreviousPageLabel(label: string): this { + this.previousPageLabel = label; + return this; + } + + setPreviousPageEmoji(emoji: ComponentEmojiResolvable): this { + this.previousPageEmoji = emoji; + return this; + } + + build(): PaginatorSelectMenuComponents { + if (!this.customId) { + throw new Error("PaginatorSelectMenuBuilder: customId is required."); + } + if (!this.options.length) { + throw new Error("PaginatorSelectMenuBuilder: at least one option is required."); + } + + return new PaginatorSelectMenuComponent({ + customId: this.customId, + options: this.options, + placeholder: this.placeholder, + chunkSize: this.chunkSize, + timeout: this.timeout, + nextPageLabel: this.nextPageLabel, + nextPageEmoji: this.nextPageEmoji, + previousPageLabel: this.previousPageLabel, + previousPageEmoji: this.previousPageEmoji + }).build(); + } +} diff --git a/src/structures/paginators/builders/index.ts b/src/structures/paginators/builders/index.ts new file mode 100644 index 0000000..e4ae066 --- /dev/null +++ b/src/structures/paginators/builders/index.ts @@ -0,0 +1,3 @@ +export * from "@structures/paginators/builders/PaginatorContainerBuilder.js"; +export * from "@structures/paginators/builders/PaginatorEmbedBuilder.js"; +export * from "@structures/paginators/builders/PaginatorSelectMenuBuilder.js"; \ No newline at end of file diff --git a/src/structures/paginators/components/BasePaginatorComponent.ts b/src/structures/paginators/components/BasePaginatorComponent.ts new file mode 100644 index 0000000..b51fa83 --- /dev/null +++ b/src/structures/paginators/components/BasePaginatorComponent.ts @@ -0,0 +1,212 @@ +import { + ActionRowBuilder, + ButtonBuilder, + type ButtonInteraction, + ButtonStyle, + type ComponentEmojiResolvable, + ComponentType, + type Message, + type MessageEditOptions, + type RepliableInteraction +} from "discord.js"; +import { logger } from "@utils/index.js"; + +export interface BasePaginatorComponentConfiguration { + pages: T; + timeout?: number; + firstPageLabel?: string; + previousPageLabel?: string; + nextPageLabel?: string; + lastPageLabel?: string; + firstPageEmoji?: ComponentEmojiResolvable; + previousPageEmoji?: ComponentEmojiResolvable; + nextPageEmoji?: ComponentEmojiResolvable; + lastPageEmoji?: ComponentEmojiResolvable; + showFirstLastButtons?: boolean; + filterUserId?: string; +} + +export abstract class BasePaginatorComponent { + protected abstract readonly paginatorInteractionCustomIds: { + first: string; + previous: string; + next: string; + last: string; + }; + + protected readonly pages: T; + protected readonly timeout: number; + protected readonly firstPageLabel: string; + protected readonly previousPageLabel: string; + protected readonly nextPageLabel: string; + protected readonly lastPageLabel: string; + protected readonly firstPageEmoji?: ComponentEmojiResolvable; + protected readonly previousPageEmoji?: ComponentEmojiResolvable; + protected readonly nextPageEmoji?: ComponentEmojiResolvable; + protected readonly lastPageEmoji?: ComponentEmojiResolvable; + protected readonly showFirstLastButtons: boolean; + + protected currentPage = 0; + + constructor({ + pages, + timeout = 60_000, + firstPageLabel = "First", + previousPageLabel = "Previous", + nextPageLabel = "Next", + lastPageLabel = "Last", + firstPageEmoji, + previousPageEmoji, + nextPageEmoji, + lastPageEmoji, + showFirstLastButtons = true + }: BasePaginatorComponentConfiguration) { + if (pages.length === 0) { + logger.error("Paginator: at least one page is required"); + return; + } + + this.pages = pages; + this.timeout = timeout; + this.firstPageLabel = firstPageLabel; + this.previousPageLabel = previousPageLabel; + this.nextPageLabel = nextPageLabel; + this.lastPageLabel = lastPageLabel; + this.firstPageEmoji = firstPageEmoji; + this.previousPageEmoji = previousPageEmoji; + this.nextPageEmoji = nextPageEmoji; + this.lastPageEmoji = lastPageEmoji; + this.showFirstLastButtons = showFirstLastButtons; + } + + protected abstract buildUpdatePayload(disabled?: boolean): MessageEditOptions; + + protected attachCollector(message: Message, interaction?: RepliableInteraction, filterUserId?: string): void { + if (!this.isPaginated) { + return; + } + + const collector = message.createMessageComponentCollector({ + componentType: ComponentType.Button, + filter: filterUserId ? (i) => i.user.id === filterUserId : undefined, + time: this.timeout + }); + + collector.on("collect", async (buttonInteraction: ButtonInteraction) => { + if (!this.handleNavigation(buttonInteraction.customId)) { + return; + } + + await buttonInteraction.update(this.buildUpdatePayload()); + }); + + collector.on("end", async () => { + const disabledPayload = this.buildUpdatePayload(true); + + if (interaction) { + await interaction.editReply(disabledPayload).catch(console.error); + } else { + await message.edit(disabledPayload).catch(console.error); + } + }); + } + + protected buildPaginatorRow(disabled = false): ActionRowBuilder { + return new ActionRowBuilder().addComponents(this.buildPaginatorButtons(disabled)); + } + + protected handleNavigation(customId: string): boolean { + switch (customId) { + case this.paginatorInteractionCustomIds.first: + this.currentPage = 0; + break; + case this.paginatorInteractionCustomIds.previous: + this.currentPage = Math.max(0, this.currentPage - 1); + break; + case this.paginatorInteractionCustomIds.next: + this.currentPage = Math.min(this.pages.length - 1, this.currentPage + 1); + break; + case this.paginatorInteractionCustomIds.last: + this.currentPage = this.pages.length - 1; + break; + default: + return false; + } + + return true; + } + + protected buildPaginatorButtons(disabled = false): ButtonBuilder[] { + const buttons: ButtonBuilder[] = []; + + if (this.showFirstLastButtons && this.pages.length > 2) { + const firstButton = new ButtonBuilder() + .setCustomId(this.paginatorInteractionCustomIds.first) + .setStyle(ButtonStyle.Secondary) + .setDisabled(disabled || this.isFirstPage); + + if (this.firstPageEmoji) { + firstButton.setEmoji(this.firstPageEmoji); + } else { + firstButton.setLabel(this.firstPageLabel); + } + + buttons.push(firstButton); + } + + const previousButton = new ButtonBuilder() + .setCustomId(this.paginatorInteractionCustomIds.previous) + .setStyle(ButtonStyle.Primary) + .setDisabled(disabled || this.isFirstPage); + + if (this.previousPageEmoji) { + previousButton.setEmoji(this.previousPageEmoji); + } else { + previousButton.setLabel(this.previousPageLabel); + } + + buttons.push(previousButton); + + const nextButton = new ButtonBuilder() + .setCustomId(this.paginatorInteractionCustomIds.next) + .setStyle(ButtonStyle.Primary) + .setDisabled(disabled || this.isLastPage); + + if (this.nextPageEmoji) { + nextButton.setEmoji(this.nextPageEmoji); + } else { + nextButton.setLabel(this.nextPageLabel); + } + + buttons.push(nextButton); + + if (this.showFirstLastButtons && this.pages.length > 2) { + const lastButton = new ButtonBuilder() + .setCustomId(this.paginatorInteractionCustomIds.last) + .setStyle(ButtonStyle.Secondary) + .setDisabled(disabled || this.isLastPage); + + if (this.lastPageEmoji) { + lastButton.setEmoji(this.lastPageEmoji); + } else { + lastButton.setLabel(this.lastPageLabel); + } + + buttons.push(lastButton); + } + + return buttons; + } + + protected get isPaginated(): boolean { + return this.pages.length > 1; + } + + protected get isFirstPage(): boolean { + return this.currentPage === 0; + } + + protected get isLastPage(): boolean { + return this.currentPage === this.pages.length - 1; + } +} \ No newline at end of file diff --git a/src/structures/paginators/components/PaginatorContainerComponent.ts b/src/structures/paginators/components/PaginatorContainerComponent.ts new file mode 100644 index 0000000..0f1fa7b --- /dev/null +++ b/src/structures/paginators/components/PaginatorContainerComponent.ts @@ -0,0 +1,87 @@ +import { + type BaseMessageOptions, + ContainerBuilder, + type Message, + type MessageEditOptions, + MessageFlags, + type RepliableInteraction, + SeparatorBuilder, + SeparatorSpacingSize +} from "discord.js"; +import { + BasePaginatorComponent, type BasePaginatorComponentConfiguration +} from "structures/paginators/components/BasePaginatorComponent.js"; + +interface PaginatorContainerConfiguration extends BasePaginatorComponentConfiguration {} + +export interface PaginatorContainerComponents { + components: BaseMessageOptions["components"]; + attachCollector: (message: Message, interaction?: RepliableInteraction, filterUserId?: string) => void; +} + +export class PaginatorContainerComponent extends BasePaginatorComponent { + protected readonly paginatorInteractionCustomIds = { + first: "__paginator_container_first__", + previous: "__paginator_container_previous__", + next: "__paginator_container_next__", + last: "__paginator_container_last__" + }; + + constructor({ + pages, + timeout = 60_000, + firstPageLabel = "First", + previousPageLabel = "Previous", + nextPageLabel = "Next", + lastPageLabel = "Last", + firstPageEmoji, + previousPageEmoji, + nextPageEmoji, + lastPageEmoji, + showFirstLastButtons = true + }: PaginatorContainerConfiguration) { + super({ + pages, + timeout, + firstPageLabel, + previousPageLabel, + nextPageLabel, + lastPageLabel, + firstPageEmoji, + previousPageEmoji, + nextPageEmoji, + lastPageEmoji, + showFirstLastButtons + }); + } + + build(): PaginatorContainerComponents { + this.currentPage = 0; + + return { + components: [this.buildCurrentContainer()], + attachCollector: (message: Message, interaction?: RepliableInteraction, filterUserId?: string) => { + this.attachCollector(message, interaction, filterUserId); + } + }; + } + + protected buildUpdatePayload(disabled = false): MessageEditOptions { + return { + components: [this.buildCurrentContainer(disabled)], + flags: MessageFlags.IsComponentsV2 as const + }; + } + + private buildCurrentContainer(disabled = false): ContainerBuilder { + const originalContainer = this.pages[this.currentPage]; + if (!this.isPaginated) { + return originalContainer; + } + + const container = new ContainerBuilder(originalContainer.toJSON()); + return container + .addSeparatorComponents(new SeparatorBuilder().setSpacing(SeparatorSpacingSize.Large).setDivider(true)) + .addActionRowComponents(this.buildPaginatorRow(disabled)); + } +} diff --git a/src/structures/paginators/components/PaginatorEmbedComponent.ts b/src/structures/paginators/components/PaginatorEmbedComponent.ts new file mode 100644 index 0000000..eb3da7e --- /dev/null +++ b/src/structures/paginators/components/PaginatorEmbedComponent.ts @@ -0,0 +1,79 @@ +import { + type ActionRowBuilder, + type APIEmbed, + type ButtonBuilder, + type Message, + type MessageEditOptions, + type RepliableInteraction +} from "discord.js"; +import { + BasePaginatorComponent, type BasePaginatorComponentConfiguration +} from "structures/paginators/components/BasePaginatorComponent.js"; + +interface PaginatorEmbedConfiguration extends BasePaginatorComponentConfiguration {} + +export interface PaginatorEmbedComponents { + embeds: APIEmbed[]; + components: ActionRowBuilder[]; + attachCollector: (message: Message, interaction?: RepliableInteraction, filterUserId?: string) => void; +} + +export class PaginatorEmbedComponent extends BasePaginatorComponent { + protected readonly paginatorInteractionCustomIds = { + first: "__paginator_embed_first__", + previous: "__paginator_embed_previous__", + next: "__paginator_embed_next__", + last: "__paginator_embed_last__" + }; + + constructor({ + pages, + timeout = 60_000, + firstPageLabel = "First", + previousPageLabel = "Previous", + nextPageLabel = "Next", + lastPageLabel = "Last", + firstPageEmoji, + previousPageEmoji, + nextPageEmoji, + lastPageEmoji, + showFirstLastButtons = true + }: PaginatorEmbedConfiguration) { + super({ + pages, + timeout, + firstPageLabel, + previousPageLabel, + nextPageLabel, + lastPageLabel, + firstPageEmoji, + previousPageEmoji, + nextPageEmoji, + lastPageEmoji, + showFirstLastButtons + }); + } + + build(): PaginatorEmbedComponents { + this.currentPage = 0; + + return { + embeds: [this.buildCurrentEmbed()], + components: this.isPaginated ? [this.buildPaginatorRow()] : [], + attachCollector: (message: Message, interaction?: RepliableInteraction, filterUserId?: string) => { + this.attachCollector(message, interaction, filterUserId); + } + }; + } + + protected buildUpdatePayload(disabled = false): MessageEditOptions { + return { + embeds: [this.buildCurrentEmbed()], + components: [this.buildPaginatorRow(disabled)] + }; + } + + private buildCurrentEmbed(): APIEmbed { + return this.pages[this.currentPage]; + } +} diff --git a/src/structures/paginators/components/PaginatorSelectMenuComponent.ts b/src/structures/paginators/components/PaginatorSelectMenuComponent.ts new file mode 100644 index 0000000..afed09f --- /dev/null +++ b/src/structures/paginators/components/PaginatorSelectMenuComponent.ts @@ -0,0 +1,183 @@ +import { + ActionRowBuilder, + type APISelectMenuOption, + type ComponentEmojiResolvable, + ComponentType, + type Message, + type RepliableInteraction, + StringSelectMenuBuilder, type StringSelectMenuInteraction, + StringSelectMenuOptionBuilder +} from "discord.js"; + +interface PaginatorSelectMenuConfiguration { + customId: string; + options: APISelectMenuOption[]; + placeholder?: string; + chunkSize?: number; + timeout?: number; + nextPageLabel?: string; + nextPageEmoji?: ComponentEmojiResolvable; + previousPageLabel?: string; + previousPageEmoji?: ComponentEmojiResolvable; +} + +export interface PaginatorSelectMenuComponents { + components: ActionRowBuilder[]; + attachCollector: (message: Message, interaction?: RepliableInteraction, filterUserId?: string) => void; +} + +const NEXT_PAGE_VALUE = "__paginator_next__"; +const PREV_PAGE_VALUE = "__paginator_previous__"; + +export class PaginatorSelectMenuComponent { + private readonly customId: string; + private readonly options: APISelectMenuOption[]; + private readonly chunks: APISelectMenuOption[][]; + private readonly placeholder: string; + private readonly chunkSize: number; + private readonly timeout: number; + private readonly nextPageLabel: string; + private readonly nextPageEmoji?: ComponentEmojiResolvable; + private readonly previousPageLabel: string; + private readonly previousPageEmoji?: ComponentEmojiResolvable; + + private currentChunk = 0; + + constructor({ + customId, + options, + placeholder = "", + chunkSize = 23, + timeout = 60_000, + nextPageLabel = "Next page", + nextPageEmoji, + previousPageLabel = "Previous page", + previousPageEmoji + }: PaginatorSelectMenuConfiguration) { + if (options.length === 0) { + throw new Error("PaginatorSelectMenu: at least one option is required."); + } + + if (chunkSize < 1 || chunkSize > 23) { + throw new Error("PaginatorSelectMenu: chunkSize must be between 1 and 23."); + } + + this.customId = customId; + this.options = options; + this.chunkSize = chunkSize; + this.placeholder = placeholder; + this.timeout = timeout; + this.nextPageLabel = nextPageLabel; + this.nextPageEmoji = nextPageEmoji; + this.previousPageLabel = previousPageLabel; + this.previousPageEmoji = previousPageEmoji; + this.chunks = this.buildChunks(); + } + + build(): PaginatorSelectMenuComponents { + this.currentChunk = 0; + + return { + components: this.buildComponents(), + attachCollector: (message: Message, interaction?: RepliableInteraction, filterUserId?: string) => { + this.attachCollector(message, interaction, filterUserId); + } + }; + } + + private attachCollector(message: Message, interaction?: RepliableInteraction, filterUserId?: string): void { + const collector = message.createMessageComponentCollector({ + componentType: ComponentType.StringSelect, + filter: filterUserId ? (i) => i.user.id === filterUserId : undefined, + time: this.timeout + }); + + collector.on("collect", async (selectInteraction: StringSelectMenuInteraction<"cached">) => { + const [value] = selectInteraction.values; + if (value === NEXT_PAGE_VALUE || value === PREV_PAGE_VALUE) { + this.currentChunk += value === NEXT_PAGE_VALUE ? 1 : -1; + await selectInteraction.update({ components: this.buildComponents() }); + } + }); + + collector.on("end", async () => { + const disabledComponents = { components: this.buildComponents(true) }; + if (interaction) { + await interaction.editReply(disabledComponents).catch(console.error); + } else { + await message.edit(disabledComponents).catch(console.error); + } + }); + } + + private buildChunks(): APISelectMenuOption[][] { + const chunks: APISelectMenuOption[][] = []; + for (let i = 0; i < this.options.length; i += this.chunkSize) { + chunks.push(this.options.slice(i, i + this.chunkSize)); + } + + return chunks; + } + + private get isPaginated(): boolean { + return this.chunks.length > 1; + } + + private get isFirstChunk(): boolean { + return this.currentChunk === 0; + } + + private get isLastChunk(): boolean { + return this.currentChunk === this.chunks.length - 1; + } + + private buildPageRow(disabled = false): ActionRowBuilder { + const chunk = this.chunks[this.currentChunk]; + const options: StringSelectMenuOptionBuilder[] = []; + + if (this.isPaginated && !this.isFirstChunk) { + const previousPageOption = new StringSelectMenuOptionBuilder().setLabel(this.previousPageLabel).setValue(PREV_PAGE_VALUE); + if (this.previousPageEmoji) { + previousPageOption.setEmoji(this.previousPageEmoji); + } + + options.push(previousPageOption); + } + + for (const page of chunk) { + const option = new StringSelectMenuOptionBuilder() + .setLabel(page.label) + .setValue(page.value); + + if (page.description) { + option.setDescription(page.description); + } + if (page.emoji) { + option.setEmoji(page.emoji); + } + + options.push(option); + } + + if (this.isPaginated && !this.isLastChunk) { + const previousPageOption = new StringSelectMenuOptionBuilder().setLabel(this.nextPageLabel).setValue(NEXT_PAGE_VALUE); + if (this.nextPageEmoji) { + previousPageOption.setEmoji(this.nextPageEmoji); + } + + options.push(previousPageOption); + } + + return new ActionRowBuilder().addComponents( + new StringSelectMenuBuilder() + .setCustomId(this.customId) + .setPlaceholder(this.placeholder) + .setDisabled(disabled) + .addOptions(options) + ); + } + + private buildComponents(disabled = false): ActionRowBuilder[] { + return [this.buildPageRow(disabled)]; + } +} diff --git a/src/structures/paginators/components/index.ts b/src/structures/paginators/components/index.ts new file mode 100644 index 0000000..6683500 --- /dev/null +++ b/src/structures/paginators/components/index.ts @@ -0,0 +1,3 @@ +export * from "@structures/paginators/components/PaginatorContainerComponent.js"; +export * from "@structures/paginators/components/PaginatorEmbedComponent.js"; +export * from "@structures/paginators/components/PaginatorSelectMenuComponent.js"; \ No newline at end of file diff --git a/src/structures/paginators/index.ts b/src/structures/paginators/index.ts new file mode 100644 index 0000000..3bed102 --- /dev/null +++ b/src/structures/paginators/index.ts @@ -0,0 +1,2 @@ +export * from "@structures/paginators/builders/index.js"; +export * from "@structures/paginators/components/index.js"; \ No newline at end of file diff --git a/src/utils/ComponentUtils.ts b/src/utils/ComponentUtils.ts new file mode 100644 index 0000000..21e7084 --- /dev/null +++ b/src/utils/ComponentUtils.ts @@ -0,0 +1,17 @@ +import { type APIContainerComponent, type APIEmbed, embedLength, TextDisplayComponent } from "discord.js"; + +export namespace ComponentUtils { + export const getEmbedContentLength = (embed: APIEmbed) => { + return embedLength(embed); + }; + + export const getContainerContentLength = (container: APIContainerComponent) => { + return container.components.map((component) => { + if (component instanceof TextDisplayComponent) { + return component.content.length; + } + + return 0; + }).reduce((a, b) => a + b); + }; +} \ No newline at end of file diff --git a/src/utils/ContentUtils.ts b/src/utils/ContentUtils.ts new file mode 100644 index 0000000..4a387cf --- /dev/null +++ b/src/utils/ContentUtils.ts @@ -0,0 +1,5 @@ +export namespace ContentUtils { + export const ellipsis = (content: string, max: number) => { + return content.length > max ? content.slice(0, max) + "..." : content; + }; +} diff --git a/src/utils/TimestampUtils.ts b/src/utils/TimestampUtils.ts new file mode 100644 index 0000000..fca7054 --- /dev/null +++ b/src/utils/TimestampUtils.ts @@ -0,0 +1,39 @@ +import { time, TimestampStyles } from "discord.js"; + +export namespace TimestampUtils { + export const toShortTime = (timestamp: number): string => { + return time(Math.round(timestamp / 1000), TimestampStyles.ShortTime); + }; + + export const toMediumTime = (timestamp: number): string => { + return time(Math.round(timestamp / 1000), TimestampStyles.MediumTime); + }; + + export const toShortDate = (timestamp: number): string => { + return time(Math.round(timestamp / 1000), TimestampStyles.ShortDate); + }; + + export const toLongDate = (timestamp: number): string => { + return time(Math.round(timestamp / 1000), TimestampStyles.LongDate); + }; + + export const toLongDateShortTime = (timestamp: number): string => { + return time(Math.round(timestamp / 1000), TimestampStyles.LongDateShortTime); + }; + + export const toFullDateShortTime = (timestamp: number): string => { + return time(Math.round(timestamp / 1000), TimestampStyles.FullDateShortTime); + }; + + export const toShortDateShortTime = (timestamp: number): string => { + return time(Math.round(timestamp / 1000), TimestampStyles.ShortDateShortTime); + }; + + export const toShortDateMediumTime = (timestamp: number): string => { + return time(Math.round(timestamp / 1000), TimestampStyles.ShortDateMediumTime); + }; + + export const toRelativeTime = (timestamp: number): string => { + return time(Math.round(timestamp / 1000), TimestampStyles.RelativeTime); + }; +} \ No newline at end of file diff --git a/src/utils/dateFormatters.ts b/src/utils/dateFormatters.ts deleted file mode 100644 index e2f29a8..0000000 --- a/src/utils/dateFormatters.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { time, TimestampStyles } from "discord.js"; - -export const formatTimestampToShortTime = (timestamp: number): string => { - return time(Math.round(timestamp / 1000), TimestampStyles.ShortTime); -}; - -export const formatTimestampToMediumTime = (timestamp: number): string => { - return time(Math.round(timestamp / 1000), TimestampStyles.MediumTime); -}; - -export const formatTimestampToShortDate = (timestamp: number): string => { - return time(Math.round(timestamp / 1000), TimestampStyles.ShortDate); -}; - -export const formatTimestampToLongDate = (timestamp: number): string => { - return time(Math.round(timestamp / 1000), TimestampStyles.LongDate); -}; - -export const formatTimestampToLongDateShortTime = (timestamp: number): string => { - return time(Math.round(timestamp / 1000), TimestampStyles.LongDateShortTime); -}; - -export const formatTimestampToFullDateShortTime = (timestamp: number): string => { - return time(Math.round(timestamp / 1000), TimestampStyles.FullDateShortTime); -}; - -export const formatTimestampToShortDateShortTime = (timestamp: number): string => { - return time(Math.round(timestamp / 1000), TimestampStyles.ShortDateShortTime); -}; - -export const formatTimestampToShortDateMediumTime = (timestamp: number): string => { - return time(Math.round(timestamp / 1000), TimestampStyles.ShortDateMediumTime); -}; - -export const formatTimestampToRelativeTime = (timestamp: number): string => { - return time(Math.round(timestamp / 1000), TimestampStyles.RelativeTime); -}; diff --git a/src/utils/index.ts b/src/utils/index.ts index cf2069d..6897c84 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1,5 +1,7 @@ -export * from "@utils/dateFormatters.js"; +export * from "@utils/ComponentUtils.js"; +export * from "@utils/ContentUtils.js"; export * from "@utils/error.js"; export * from "@utils/files.js"; export * from "@utils/logger.js"; export * from "@utils/translation.js"; +export * from "@utils/TimestampUtils.js";