Compare commits

..

1 commit

Author SHA1 Message Date
c5731f133a remove archive related commands
All checks were successful
Lint and Format Check / lint-and-format (pull_request) Successful in 20s
2024-09-04 10:05:30 +02:00
33 changed files with 296 additions and 235 deletions

View file

@ -1,7 +1,6 @@
{ {
"editor.tabSize": 2, "editor.tabSize": 2,
"editor.insertSpaces": false, "editor.insertSpaces": false,
"editor.rulers": [100],
"files.insertFinalNewline": true, "files.insertFinalNewline": true,
"files.trimFinalNewlines": true, "files.trimFinalNewlines": true,

View file

@ -56,10 +56,10 @@ La norme pour les nom dans les fichiers est la suivante :
Évidemment ça peut s'additionner, Évidemment ça peut s'additionner,
par exemple : `c_NOM-COMMANDE_subX_optX_desc`. par exemple : `c_NOM-COMMANDE_subX_optX_desc`.
- Chaîne de caractère des évènements : - Chaîne de charactère des évènements :
`e` est utilisé pour `E`vènements. `e` est utilisé pour `E`vènements.
- `e_NOM-EVENEMENT_N` : `N` le nom de la chaîne de caractère - `e_NOM-EVENEMENT_N` : `N` le nom de la chaîne de caractère
- Chaîne de caractère des utils : - Chaîne de charactère des utils :
`u` est utilisé pour `U`tilitaires. `u` est utilisé pour `U`tilitaires.
- `u_NOM-FICHIER-UTILS_N` : `N` le nom de la chaîne de caractère - `u_NOM-FICHIER-UTILS_N` : `N` le nom de la chaîne de caractère
@ -69,7 +69,7 @@ La norme pour les nom dans les fichiers est la suivante :
doit être nommé `langue.json` avec `langue` suivant doit être nommé `langue.json` avec `langue` suivant
[cette liste](https://discord.com/developers/docs/reference#locales). [cette liste](https://discord.com/developers/docs/reference#locales).
2. Le contenu du fichier peut être copié du fichier de la langue par défaut, 2. Le contenu du fichier peut être copié du fichier de la langue par défaut,
[cf. au-dessus](#langues). [cf. au dessus](#langues).
3. Ce sont les valeurs des clés (le texte à gauche des `:`) qui doivent 3. Ce sont les valeurs des clés (le texte à gauche des `:`) qui doivent
être traduits. Merci par avance ! être traduits. Merci par avance !
> Ne vous forcez pas à tout traduire. Même une contribution avec > Ne vous forcez pas à tout traduire. Même une contribution avec
@ -80,27 +80,27 @@ La norme pour les nom dans les fichiers est la suivante :
1. Rechercher la langue dans le dossier [src/locales/](./src/locales/). 1. Rechercher la langue dans le dossier [src/locales/](./src/locales/).
2. Modifier/Ajouter des traductions comme 2. Modifier/Ajouter des traductions comme
[expliquer au-dessus](#ajouter-une-langue) (à partir du `3.`). [expliquer au dessus](#ajouter-une-langue) (à partir du `3.`).
> Pensez à vérifier si de nouvelles valeurs n'ont pas été ajouté dans > Pensez à vérifier si de nouvelles valeurs n'ont pas été ajouté dans
> le fichier langue par défaut, [cf. au-dessus](#langues). > le fichier langue par défaut, [cf. au dessus](#langues).
## Projet ## Projet
Le code se trouve dans le dossier [src/](./src/). Dans ce dossier il y a : Le code se trouve dans le dosier [src/](./src/). Dans ce dossier il y a :
- [commands/](./src/commands/) qui contient toutes les commandes, rangés par - [commands/](./src/commands/) qui contient toutes les commandes, rangés par
catégories catégories
- [events/](./src/events/) qui contient tous les évènements, rangés par - [events/](./src/events/) qui contient tous les évènements, rangés par
catégories catégories
- [locales/](./src/locales/) qui contient tous les fichiers de langue - [locales/](./src/locales/) qui contient tous les fichiers de langue
- [modules/](./src/modules/) qui contient les extensions utilisées, - [modules/](./src/modules/) qui contient les extensions utilisé,
par exemple, pour utiliser la fonction `capitalize()` d'un string, il faut par exemple, pour utiliser la fonction `capitalize()` d'un string, il faut
importer le fichier `string.ts` qui se trouve dans le dossier importer le fichier `string.ts` qui se trouve dans le dossier
- [utils/](./src/utils/) qui contient toutes les fonctions utilitaires, rangés - [utils/](./src/utils/) qui contient toutes les fonctions utilitaires, rangés
par fichiers par fichiers
Les dossiers [commands/](./src/commands/) et [events/](./src/events/) Les dossiers [commands/](./src/commands/) et [events/](./src/events/)
contiennent chacun un fichier `loader.js` qui charge respectivement contiennent chaquin un fichier `loader.js` qui charge respectivement
les commandes et les évènements dans le bot. les commandes et les évènements dans le bot.
## Ajouter une commande ## Ajouter une commande
@ -124,7 +124,9 @@ export default {
const filename = getFilename(__filename); const filename = getFilename(__filename);
return new SlashCommandBuilder() return new SlashCommandBuilder()
.setName(filename.toLowerCase()) .setName(filename.toLowerCase())
.setDescription(client.locales.get(client.config.default_lang)!.get(`c_${filename}_desc`)!) .setDescription(
client.locales.get(client.config.default_lang)?.get(`c_${filename}_desc`) ?? ""
)
.setNameLocalizations(getLocalizations(client, `c_${filename}_name`, true)) .setNameLocalizations(getLocalizations(client, `c_${filename}_name`, true))
.setDescriptionLocalizations(getLocalizations(client, `c_${filename}_desc`)); .setDescriptionLocalizations(getLocalizations(client, `c_${filename}_desc`));
}, },
@ -139,14 +141,14 @@ export default {
Rapidement, cette structure comporte 3 éléments : Rapidement, cette structure comporte 3 éléments :
- `scope` : une liste de guildId où la commande est disponible, si la liste est vide, - `scope` : une liste de guildId où la commande est disponible, si la liste est
la commande est disponible partout est vide, la commande est disponible partout
- `data` : représente les données envoyées à l'API de Discord - `data` : représente les données envoyées à l'API de Discord
- `interaction` : représente le comportement de la commande - `interaction` : représente le comportement de la commande
Ce modèle vous permet de commencer rapidement votre commande, car il contient Ce template vous permet de commencé rapidement votre commande car il contient
déjà tout ce qu'il faut pour le support des langues. Pensez bien à ne pas écrire déjà tout ce qu'il faut pour le support des langues. Pensez bien à ne pas écrire
directement vos chaînes de caractères ici, mais bien dans directement vos chaînes de caractères ici mais bien dans
les [fichiers de langues](./src/locales/), c'est à ça que la variable les [fichiers de langues](./src/locales/), c'est à ça que la variable
`loc` sert. `loc` sert.
@ -157,8 +159,8 @@ Vous devez aussi ajouter **obligatoirement** :
- `"c_COMMANDE_desc": "DESCRIPTION"` au fichier de langue, avec `COMMANDE` - `"c_COMMANDE_desc": "DESCRIPTION"` au fichier de langue, avec `COMMANDE`
le nom de la commande et `DESCRIPTION` la description de votre commande. le nom de la commande et `DESCRIPTION` la description de votre commande.
> Note : Il est possible d'ajouter de l'autocomplétion via > Note: Il est possible d'ajouter de l'autocomplétion via
> un 4 élément : `autocomplete`. > un 4ème élément : `autocomplete`.
## Ajouter un évènement ## Ajouter un évènement
@ -179,10 +181,10 @@ de discord.js de l'évènement
### Player ### Player
Les évènements du player ont la même logique les autres, mais sont placés Les évènement du player ont la même logique les autres, mais sont placés
dans le dossier [`player`](./src/events/player/). dans le dossier [`player`](./src/events/player/).
> Pour déboguer le player, il est possible d'ajouter un évènement `debug`, en > Pour débogguer le player, il est possible d'ajouter un évènement `debug`, en
> voici un exemple : > voici un exemple :
> >
> ```ts > ```ts
@ -202,7 +204,7 @@ Les modèles sont gérés [en dehors séparément du reste](./src/modals/).
Les boutons sont gérés [en dehors séparément du reste](./src/buttons/) Les boutons sont gérés [en dehors séparément du reste](./src/buttons/)
Chaque bouton à une implémentation séparée des autres, même s'ils sont dans le Chaque bouton à une implémentation séparée des autres, même si ils sont dans le
même message. même message.
Contrairement aux autres éléments, les boutons doivent se faire collecter via Contrairement aux autres éléments, les boutons doivent se faire collecter via
@ -210,7 +212,7 @@ la fonction [`collect`](./src/buttons/loader.ts#L46) juste après leur déclarat
## Autocomplétion ## Autocomplétion
La réponse qu'attend Discord doit se faire obligatoirement sous 3 secondes. La réponse qu'attent Discord doit se faire obligatoirement sous 3 secondes.
Pour se faire on peut utiliser un timeout avec Pour se faire on peut utiliser un timeout avec
[une race](https://fr.wikipedia.org/wiki/Situation_de_comp%C3%A9tition). [une race](https://fr.wikipedia.org/wiki/Situation_de_comp%C3%A9tition).
@ -241,7 +243,7 @@ la traduction.
- [Créez un fork](https://git.mylloon.fr/repo/fork/76) et poussez - [Créez un fork](https://git.mylloon.fr/repo/fork/76) et poussez
vos modifications dans ce dernier. vos modifications dans ce dernier.
Pour commencer, vous pouvez jeter un œil aux Pour commencer, vous pouvez jeté un oeil aux
[tickets facilement résolvable](https://git.mylloon.fr/ConfrerieDuKassoulait/Botanique/issues?state=open&labels=82). [tickets facilement résolvable](https://git.mylloon.fr/ConfrerieDuKassoulait/Botanique/issues?state=open&labels=82).
- De préférences, les fonctions, méthodes et variables seront écrites - De préférences, les fonctions, méthodes et variables seront écrites
@ -250,7 +252,7 @@ Pour commencer, vous pouvez jeter un œil aux
## Soumettre ses modifications ## Soumettre ses modifications
1. Pensez à bien commenter votre code (en anglais) pour que n'importe qui 1. Pensez à bien commenter votre code (en anglais) pour que n'importe qui
comprennent vos modifications. Vérifier bien dans tous les fichiers si ce que comprennent vos modifications. Vérifier bien dans tout les fichiers si ce que
vous avez modifié n'est pas référencer ailleurs (exemple : si vous modifier vous avez modifié n'est pas référencer ailleurs (exemple : si vous modifier
une variable d'environnement, il faut penser à mettre à jour le une variable d'environnement, il faut penser à mettre à jour le
[`README`](./README.md#variables-denvironnements)). [`README`](./README.md#variables-denvironnements)).
@ -270,10 +272,10 @@ Pour commencer, vous pouvez jeter un œil aux
> **Explication** > **Explication**
> >
> `npm run debug` exécute le code depuis le dossier [`src`](src/) > `npm run debug` execute le code depuis le dossier [`src`](src/)
> tandis que `npm run main` et l'image Docker le fait depuis le dossier `dist`. > tandis que `npm run main` et l'image Docker le fait depuis le dossier `dist`.
> >
> Docker est cependant différent, car dans l'image, le dossier [`src`](src/) est > Docker est cependant différent car dans l'image, le dossier [`src`](src/) est
> supprimé. > supprimé.
## Gestion du dépôt ## Gestion du dépôt
@ -281,6 +283,6 @@ Pour commencer, vous pouvez jeter un œil aux
- On ne push jamais directement sur la branche `main`. - On ne push jamais directement sur la branche `main`.
- Quand on merge des modifications vers `main`, on fait un _squash_, - Quand on merge des modifications vers `main`, on fait un _squash_,
l'historique des modifications reste disponible dans l'historique des modifications reste disponible dans
[le graphe](https://git.mylloon.fr/ConfrerieDuKassoulait/Botanique/graph). [le graph](https://git.mylloon.fr/ConfrerieDuKassoulait/Botanique/graph).
- De préférences, suivre [ces conventions](https://www.conventionalcommits.org/fr/v1.0.0/) - De préférences, suivre [ces conventions](https://www.conventionalcommits.org/fr/v1.0.0/)
(cf. cette [partie précédente](#soumettre-ses-modifications)). (cf. cette [partie précédente](#soumettre-ses-modifications)).

View file

@ -1,6 +1,6 @@
# syntax=docker/dockerfile:1 # syntax=docker/dockerfile:1
FROM node:22.8-bullseye-slim FROM node:22.2.0-bullseye-slim
ENV DOCKERIZED=1 ENV DOCKERIZED=1
RUN mkdir /config && \ RUN mkdir /config && \
@ -19,4 +19,5 @@ RUN npm ci --omit=dev && \
npm uninstall typescript @types/sqlite3 && \ npm uninstall typescript @types/sqlite3 && \
npm cache clean --force npm cache clean --force
ENV DP_FORCE_YTDL_MOD=@distube/ytdl-core
CMD ["dumb-init", "node", "./dist/index.js"] CMD ["dumb-init", "node", "./dist/index.js"]

View file

@ -1,4 +1,4 @@
# 🌱 Botanique [![status-badge](https://git.mylloon.fr/ConfrerieDuKassoulait/Botanique/badges/workflows/publish.yml/badge.svg)](https://git.mylloon.fr/ConfrerieDuKassoulait/Botanique/actions?workflow=publish.yml) # 🌱 Botanique ![status-badge](https://git.mylloon.fr/ConfrerieDuKassoulait/Botanique/badges/workflows/publish.yml/badge.svg)
[**Ajoute le bot à ton serveur**](https://discord.com/api/oauth2/authorize?client_id=965598852407230494&permissions=8&scope=bot%20applications.commands) [**Ajoute le bot à ton serveur**](https://discord.com/api/oauth2/authorize?client_id=965598852407230494&permissions=8&scope=bot%20applications.commands)
@ -39,10 +39,10 @@ services:
## Variables d'environnements ## Variables d'environnements
| Nom | Description | Par défaut | Commentaire | | Nom | Description | Par défaut | Commentaire |
| :-----------: | :---------------: | :--------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | | :-----------: | :---------------: | :--------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |
| TOKEN_DISCORD | Token Discord | Aucune | | TOKEN_DISCORD | Token Discord | Aucune |
| DEFAULT_LANG | Langue par défaut | `fr` | Expérimental, si la langue par défaut n'est pas complète (c.-à-d. 100%), le bot pourrait ne pas fonctionner correctement.<br>Liste des traductions disponibles [ici](./src/locales/) | | DEFAULT_LANG | Langue par défaut | `fr` | Expérimental, si la langue par défaut n'est pas complète (càd 100%), le bot pourrait ne pas fonctionner correctement.<br>Liste des traductions disponibles [ici](./src/locales/) |
## Volumes ## Volumes

View file

@ -1 +1,2 @@
TOKEN_DISCORD="your-token-goes-here" TOKEN_DISCORD="your-token-goes-here"
DP_FORCE_YTDL_MOD="@distube/ytdl-core"

172
package-lock.json generated
View file

@ -15,15 +15,15 @@
"@types/uuid": "^10.0.0", "@types/uuid": "^10.0.0",
"discord-player": "^6.7.1", "discord-player": "^6.7.1",
"discord-player-youtubei": "^1.3.1", "discord-player-youtubei": "^1.3.1",
"discord.js": "^14.16.2", "discord.js": "^14.16.1",
"mediaplex": "^0.0.9", "mediaplex": "^0.0.9",
"sqlite3": "^5.1.7", "sqlite3": "^5.1.7",
"typescript": "^5.6.2", "typescript": "^5.5.4",
"uuid": "^10.0.0" "uuid": "^10.0.0"
}, },
"devDependencies": { "devDependencies": {
"@typescript-eslint/eslint-plugin": "~8.6.0", "@typescript-eslint/eslint-plugin": "~8.4.0",
"@typescript-eslint/parser": "~8.6.0", "@typescript-eslint/parser": "~8.4.0",
"dotenv": "~16.4.5", "dotenv": "~16.4.5",
"prettier-eslint": "~16.3.0", "prettier-eslint": "~16.3.0",
"ts-node-dev": "~2.0.0" "ts-node-dev": "~2.0.0"
@ -223,9 +223,9 @@
} }
}, },
"node_modules/@eslint-community/regexpp": { "node_modules/@eslint-community/regexpp": {
"version": "4.11.1", "version": "4.11.0",
"resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.1.tgz", "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz",
"integrity": "sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==", "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
@ -281,9 +281,9 @@
} }
}, },
"node_modules/@eslint/js": { "node_modules/@eslint/js": {
"version": "8.57.1", "version": "8.57.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz",
"integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
@ -307,14 +307,14 @@
"optional": true "optional": true
}, },
"node_modules/@humanwhocodes/config-array": { "node_modules/@humanwhocodes/config-array": {
"version": "0.13.0", "version": "0.11.14",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz",
"integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==",
"deprecated": "Use @eslint/config-array instead", "deprecated": "Use @eslint/config-array instead",
"dev": true, "dev": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"@humanwhocodes/object-schema": "^2.0.3", "@humanwhocodes/object-schema": "^2.0.2",
"debug": "^4.3.1", "debug": "^4.3.1",
"minimatch": "^3.0.5" "minimatch": "^3.0.5"
}, },
@ -558,9 +558,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "22.5.5", "version": "22.5.3",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.5.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.3.tgz",
"integrity": "sha512-Xjs4y5UPO/CLdzpgR6GirZJx36yScjh73+2NlLlkFRSoQN8B0DpfXPdZGnvVmLRLOsqDpOfTNv7D9trgGhmOIA==", "integrity": "sha512-njripolh85IA9SQGTAqbmnNZTdxv7X/4OYGPz8tgy5JDr8MP+uDBa921GpYEoDDnwm0Hmn5ZPeJgiiSTPoOzkQ==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"undici-types": "~6.19.2" "undici-types": "~6.19.2"
@ -605,17 +605,17 @@
} }
}, },
"node_modules/@typescript-eslint/eslint-plugin": { "node_modules/@typescript-eslint/eslint-plugin": {
"version": "8.6.0", "version": "8.4.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.6.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.4.0.tgz",
"integrity": "sha512-UOaz/wFowmoh2G6Mr9gw60B1mm0MzUtm6Ic8G2yM1Le6gyj5Loi/N+O5mocugRGY+8OeeKmkMmbxNqUCq3B4Sg==", "integrity": "sha512-rg8LGdv7ri3oAlenMACk9e+AR4wUV0yrrG+XKsGKOK0EVgeEDqurkXMPILG2836fW4ibokTB5v4b6Z9+GYQDEw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@eslint-community/regexpp": "^4.10.0", "@eslint-community/regexpp": "^4.10.0",
"@typescript-eslint/scope-manager": "8.6.0", "@typescript-eslint/scope-manager": "8.4.0",
"@typescript-eslint/type-utils": "8.6.0", "@typescript-eslint/type-utils": "8.4.0",
"@typescript-eslint/utils": "8.6.0", "@typescript-eslint/utils": "8.4.0",
"@typescript-eslint/visitor-keys": "8.6.0", "@typescript-eslint/visitor-keys": "8.4.0",
"graphemer": "^1.4.0", "graphemer": "^1.4.0",
"ignore": "^5.3.1", "ignore": "^5.3.1",
"natural-compare": "^1.4.0", "natural-compare": "^1.4.0",
@ -639,16 +639,16 @@
} }
}, },
"node_modules/@typescript-eslint/parser": { "node_modules/@typescript-eslint/parser": {
"version": "8.6.0", "version": "8.4.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.6.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.4.0.tgz",
"integrity": "sha512-eQcbCuA2Vmw45iGfcyG4y6rS7BhWfz9MQuk409WD47qMM+bKCGQWXxvoOs1DUp+T7UBMTtRTVT+kXr7Sh4O9Ow==", "integrity": "sha512-NHgWmKSgJk5K9N16GIhQ4jSobBoJwrmURaLErad0qlLjrpP5bECYg+wxVTGlGZmJbU03jj/dfnb6V9bw+5icsA==",
"dev": true, "dev": true,
"license": "BSD-2-Clause", "license": "BSD-2-Clause",
"dependencies": { "dependencies": {
"@typescript-eslint/scope-manager": "8.6.0", "@typescript-eslint/scope-manager": "8.4.0",
"@typescript-eslint/types": "8.6.0", "@typescript-eslint/types": "8.4.0",
"@typescript-eslint/typescript-estree": "8.6.0", "@typescript-eslint/typescript-estree": "8.4.0",
"@typescript-eslint/visitor-keys": "8.6.0", "@typescript-eslint/visitor-keys": "8.4.0",
"debug": "^4.3.4" "debug": "^4.3.4"
}, },
"engines": { "engines": {
@ -668,14 +668,14 @@
} }
}, },
"node_modules/@typescript-eslint/scope-manager": { "node_modules/@typescript-eslint/scope-manager": {
"version": "8.6.0", "version": "8.4.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.6.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.4.0.tgz",
"integrity": "sha512-ZuoutoS5y9UOxKvpc/GkvF4cuEmpokda4wRg64JEia27wX+PysIE9q+lzDtlHHgblwUWwo5/Qn+/WyTUvDwBHw==", "integrity": "sha512-n2jFxLeY0JmKfUqy3P70rs6vdoPjHK8P/w+zJcV3fk0b0BwRXC/zxRTEnAsgYT7MwdQDt/ZEbtdzdVC+hcpF0A==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@typescript-eslint/types": "8.6.0", "@typescript-eslint/types": "8.4.0",
"@typescript-eslint/visitor-keys": "8.6.0" "@typescript-eslint/visitor-keys": "8.4.0"
}, },
"engines": { "engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0" "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -686,14 +686,14 @@
} }
}, },
"node_modules/@typescript-eslint/type-utils": { "node_modules/@typescript-eslint/type-utils": {
"version": "8.6.0", "version": "8.4.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.6.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.4.0.tgz",
"integrity": "sha512-dtePl4gsuenXVwC7dVNlb4mGDcKjDT/Ropsk4za/ouMBPplCLyznIaR+W65mvCvsyS97dymoBRrioEXI7k0XIg==", "integrity": "sha512-pu2PAmNrl9KX6TtirVOrbLPLwDmASpZhK/XU7WvoKoCUkdtq9zF7qQ7gna0GBZFN0hci0vHaSusiL2WpsQk37A==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@typescript-eslint/typescript-estree": "8.6.0", "@typescript-eslint/typescript-estree": "8.4.0",
"@typescript-eslint/utils": "8.6.0", "@typescript-eslint/utils": "8.4.0",
"debug": "^4.3.4", "debug": "^4.3.4",
"ts-api-utils": "^1.3.0" "ts-api-utils": "^1.3.0"
}, },
@ -711,9 +711,9 @@
} }
}, },
"node_modules/@typescript-eslint/types": { "node_modules/@typescript-eslint/types": {
"version": "8.6.0", "version": "8.4.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.6.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.4.0.tgz",
"integrity": "sha512-rojqFZGd4MQxw33SrOy09qIDS8WEldM8JWtKQLAjf/X5mGSeEFh5ixQlxssMNyPslVIk9yzWqXCsV2eFhYrYUw==", "integrity": "sha512-T1RB3KQdskh9t3v/qv7niK6P8yvn7ja1mS7QK7XfRVL6wtZ8/mFs/FHf4fKvTA0rKnqnYxl/uHFNbnEt0phgbw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
@ -725,14 +725,14 @@
} }
}, },
"node_modules/@typescript-eslint/typescript-estree": { "node_modules/@typescript-eslint/typescript-estree": {
"version": "8.6.0", "version": "8.4.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.6.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.4.0.tgz",
"integrity": "sha512-MOVAzsKJIPIlLK239l5s06YXjNqpKTVhBVDnqUumQJja5+Y94V3+4VUFRA0G60y2jNnTVwRCkhyGQpavfsbq/g==", "integrity": "sha512-kJ2OIP4dQw5gdI4uXsaxUZHRwWAGpREJ9Zq6D5L0BweyOrWsL6Sz0YcAZGWhvKnH7fm1J5YFE1JrQL0c9dd53A==",
"dev": true, "dev": true,
"license": "BSD-2-Clause", "license": "BSD-2-Clause",
"dependencies": { "dependencies": {
"@typescript-eslint/types": "8.6.0", "@typescript-eslint/types": "8.4.0",
"@typescript-eslint/visitor-keys": "8.6.0", "@typescript-eslint/visitor-keys": "8.4.0",
"debug": "^4.3.4", "debug": "^4.3.4",
"fast-glob": "^3.3.2", "fast-glob": "^3.3.2",
"is-glob": "^4.0.3", "is-glob": "^4.0.3",
@ -754,16 +754,16 @@
} }
}, },
"node_modules/@typescript-eslint/utils": { "node_modules/@typescript-eslint/utils": {
"version": "8.6.0", "version": "8.4.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.6.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.4.0.tgz",
"integrity": "sha512-eNp9cWnYf36NaOVjkEUznf6fEgVy1TWpE0o52e4wtojjBx7D1UV2WAWGzR+8Y5lVFtpMLPwNbC67T83DWSph4A==", "integrity": "sha512-swULW8n1IKLjRAgciCkTCafyTHHfwVQFt8DovmaF69sKbOxTSFMmIZaSHjqO9i/RV0wIblaawhzvtva8Nmm7lQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@eslint-community/eslint-utils": "^4.4.0", "@eslint-community/eslint-utils": "^4.4.0",
"@typescript-eslint/scope-manager": "8.6.0", "@typescript-eslint/scope-manager": "8.4.0",
"@typescript-eslint/types": "8.6.0", "@typescript-eslint/types": "8.4.0",
"@typescript-eslint/typescript-estree": "8.6.0" "@typescript-eslint/typescript-estree": "8.4.0"
}, },
"engines": { "engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0" "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -777,13 +777,13 @@
} }
}, },
"node_modules/@typescript-eslint/visitor-keys": { "node_modules/@typescript-eslint/visitor-keys": {
"version": "8.6.0", "version": "8.4.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.6.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.4.0.tgz",
"integrity": "sha512-wapVFfZg9H0qOYh4grNVQiMklJGluQrOUiOhYRrQWhx7BY/+I1IYb8BczWNbbUpO+pqy0rDciv3lQH5E1bCLrg==", "integrity": "sha512-zTQD6WLNTre1hj5wp09nBIDiOc2U5r/qmzo7wxPn4ZgAjHql09EofqhF9WF+fZHzL5aCyaIpPcT2hyxl73kr9A==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@typescript-eslint/types": "8.6.0", "@typescript-eslint/types": "8.4.0",
"eslint-visitor-keys": "^3.4.3" "eslint-visitor-keys": "^3.4.3"
}, },
"engines": { "engines": {
@ -850,9 +850,9 @@
} }
}, },
"node_modules/acorn-walk": { "node_modules/acorn-walk": {
"version": "8.3.4", "version": "8.3.3",
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz",
"integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -1353,13 +1353,13 @@
} }
}, },
"node_modules/debug": { "node_modules/debug": {
"version": "4.3.7", "version": "4.3.6",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz",
"integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==",
"devOptional": true, "devOptional": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"ms": "^2.1.3" "ms": "2.1.2"
}, },
"engines": { "engines": {
"node": ">=6.0" "node": ">=6.0"
@ -1498,9 +1498,9 @@
} }
}, },
"node_modules/discord.js": { "node_modules/discord.js": {
"version": "14.16.2", "version": "14.16.1",
"resolved": "https://registry.npmjs.org/discord.js/-/discord.js-14.16.2.tgz", "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-14.16.1.tgz",
"integrity": "sha512-VGNi9WE2dZIxYM8/r/iatQQ+3LT8STW4hhczJOwm+DBeHq66vsKDCk8trChNCB01sMO9crslYuEMeZl2d7r3xw==", "integrity": "sha512-/diX4shp3q1F3EySGQbQl10el+KIpffLSOJdtM35gGV7zw2ED7rKbASKJT7UIR9L/lTd0KtNenZ/h739TN7diA==",
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"@discordjs/builders": "^1.9.0", "@discordjs/builders": "^1.9.0",
@ -1699,17 +1699,17 @@
} }
}, },
"node_modules/eslint": { "node_modules/eslint": {
"version": "8.57.1", "version": "8.57.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz",
"integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.6.1", "@eslint-community/regexpp": "^4.6.1",
"@eslint/eslintrc": "^2.1.4", "@eslint/eslintrc": "^2.1.4",
"@eslint/js": "8.57.1", "@eslint/js": "8.57.0",
"@humanwhocodes/config-array": "^0.13.0", "@humanwhocodes/config-array": "^0.11.14",
"@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/module-importer": "^1.0.1",
"@nodelib/fs.walk": "^1.2.8", "@nodelib/fs.walk": "^1.2.8",
"@ungap/structured-clone": "^1.2.0", "@ungap/structured-clone": "^1.2.0",
@ -2734,9 +2734,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/loglevel": { "node_modules/loglevel": {
"version": "1.9.2", "version": "1.9.1",
"resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.9.2.tgz", "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.9.1.tgz",
"integrity": "sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==", "integrity": "sha512-hP3I3kCrDIMuRwAwHltphhDM1r8i55H33GgqjXbrisuJhF4kRhW1dNuxsRklp4bXl8DSdLaNLuiL4A/LWRfxvg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
@ -3235,9 +3235,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/ms": { "node_modules/ms": {
"version": "2.1.3", "version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"devOptional": true, "devOptional": true,
"license": "MIT" "license": "MIT"
}, },
@ -3858,9 +3858,9 @@
} }
}, },
"node_modules/pump": { "node_modules/pump": {
"version": "3.0.2", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
"integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"end-of-stream": "^1.1.0", "end-of-stream": "^1.1.0",
@ -4768,9 +4768,9 @@
} }
}, },
"node_modules/typescript": { "node_modules/typescript": {
"version": "5.6.2", "version": "5.5.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz",
"integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==", "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==",
"license": "Apache-2.0", "license": "Apache-2.0",
"bin": { "bin": {
"tsc": "bin/tsc", "tsc": "bin/tsc",

View file

@ -23,15 +23,15 @@
"@types/uuid": "^10.0.0", "@types/uuid": "^10.0.0",
"discord-player": "^6.7.1", "discord-player": "^6.7.1",
"discord-player-youtubei": "^1.3.1", "discord-player-youtubei": "^1.3.1",
"discord.js": "^14.16.2", "discord.js": "^14.16.1",
"mediaplex": "^0.0.9", "mediaplex": "^0.0.9",
"sqlite3": "^5.1.7", "sqlite3": "^5.1.7",
"typescript": "^5.6.2", "typescript": "^5.5.4",
"uuid": "^10.0.0" "uuid": "^10.0.0"
}, },
"devDependencies": { "devDependencies": {
"@typescript-eslint/eslint-plugin": "~8.6.0", "@typescript-eslint/eslint-plugin": "~8.4.0",
"@typescript-eslint/parser": "~8.6.0", "@typescript-eslint/parser": "~8.4.0",
"dotenv": "~16.4.5", "dotenv": "~16.4.5",
"prettier-eslint": "~16.3.0", "prettier-eslint": "~16.3.0",
"ts-node-dev": "~2.0.0" "ts-node-dev": "~2.0.0"

View file

@ -31,7 +31,7 @@ export default {
} }
// Get queue // Get queue
const queue = useQueue(interaction.guildId!); const queue = useQueue(interaction.guildId ?? "");
const embed = new EmbedBuilder(); const embed = new EmbedBuilder();
const rows = []; const rows = [];

View file

@ -31,7 +31,7 @@ export default {
} }
// Get queue // Get queue
const queue = useQueue(interaction.guildId!); const queue = useQueue(interaction.guildId ?? "");
const embed = new EmbedBuilder(); const embed = new EmbedBuilder();
const rows = []; const rows = [];

View file

@ -4,9 +4,9 @@ import { Client } from "discord.js";
import { readdir } from "fs/promises"; import { readdir } from "fs/promises";
import { removeExtension } from "../utils/misc"; import { removeExtension } from "../utils/misc";
/** Load all the commands */ /** Load all the commands. */
export default async (client: Client) => { export default async (client: Client) => {
const rest = new REST({ version: "10" }).setToken(client.token!); const rest = new REST({ version: "10" }).setToken(client.token ?? "");
const command_categories = (await readdir(__dirname)).filter( const command_categories = (await readdir(__dirname)).filter(
(element) => !element.endsWith(".js") && !element.endsWith(".ts"), (element) => !element.endsWith(".js") && !element.endsWith(".ts"),

View file

@ -13,7 +13,9 @@ export default {
return ( return (
new SlashCommandBuilder() new SlashCommandBuilder()
.setName(filename.toLowerCase()) .setName(filename.toLowerCase())
.setDescription(client.locales.get(client.config.default_lang)!.get(`c_${filename}_desc`)!) .setDescription(
client.locales.get(client.config.default_lang)?.get(`c_${filename}_desc`) ?? "",
)
.setNameLocalizations(getLocalizations(client, `c_${filename}_name`, true)) .setNameLocalizations(getLocalizations(client, `c_${filename}_name`, true))
.setDescriptionLocalizations(getLocalizations(client, `c_${filename}_desc`)) .setDescriptionLocalizations(getLocalizations(client, `c_${filename}_desc`))
@ -21,10 +23,10 @@ export default {
.addStringOption((option) => .addStringOption((option) =>
option option
.setName( .setName(
client.locales.get(client.config.default_lang)!.get(`c_${filename}_opt1_name`)!, client.locales.get(client.config.default_lang)?.get(`c_${filename}_opt1_name`) ?? "",
) )
.setDescription( .setDescription(
client.locales.get(client.config.default_lang)!.get(`c_${filename}_opt1_desc`)!, client.locales.get(client.config.default_lang)?.get(`c_${filename}_opt1_desc`) ?? "",
) )
.setNameLocalizations(getLocalizations(client, `c_${filename}_opt1_name`, true)) .setNameLocalizations(getLocalizations(client, `c_${filename}_opt1_name`, true))
.setDescriptionLocalizations(getLocalizations(client, `c_${filename}_opt1_desc`)), .setDescriptionLocalizations(getLocalizations(client, `c_${filename}_opt1_desc`)),
@ -36,8 +38,8 @@ export default {
const loc = getLocale(client, interaction.locale); const loc = getLocale(client, interaction.locale);
const desired_command = interaction.options.getString( const desired_command = interaction.options.getString(
client.locales client.locales
.get(client.config.default_lang)! .get(client.config.default_lang)
.get(`c_${getFilename(__filename)}_opt1_name`)!, ?.get(`c_${getFilename(__filename)}_opt1_name`) ?? "",
); );
// If a command isn't specified // If a command isn't specified

View file

@ -10,7 +10,9 @@ export default {
const filename = getFilename(__filename); const filename = getFilename(__filename);
return new SlashCommandBuilder() return new SlashCommandBuilder()
.setName(filename.toLowerCase()) .setName(filename.toLowerCase())
.setDescription(client.locales.get(client.config.default_lang)!.get(`c_${filename}_desc`)!) .setDescription(
client.locales.get(client.config.default_lang)?.get(`c_${filename}_desc`) ?? "",
)
.setNameLocalizations(getLocalizations(client, `c_${filename}_name`, true)) .setNameLocalizations(getLocalizations(client, `c_${filename}_name`, true))
.setDescriptionLocalizations(getLocalizations(client, `c_${filename}_desc`)); .setDescriptionLocalizations(getLocalizations(client, `c_${filename}_desc`));
}, },

View file

@ -35,23 +35,23 @@ export default {
new SlashCommandBuilder() new SlashCommandBuilder()
// Command // Command
.setName(filename.toLowerCase()) .setName(filename.toLowerCase())
.setDescription(loc_default.get(`c_${filename}_desc`)!) .setDescription(loc_default.get(`c_${filename}_desc`) ?? "")
.setNameLocalizations(getLocalizations(client, `c_${filename}_name`, true)) .setNameLocalizations(getLocalizations(client, `c_${filename}_name`, true))
.setDescriptionLocalizations(getLocalizations(client, `c_${filename}_desc`)) .setDescriptionLocalizations(getLocalizations(client, `c_${filename}_desc`))
// New reminder // New reminder
.addSubcommand((subcommand) => .addSubcommand((subcommand) =>
subcommand subcommand
.setName(loc_default.get(`c_${filename}_sub1_name`)!.toLowerCase()) .setName(loc_default.get(`c_${filename}_sub1_name`)?.toLowerCase() ?? "")
.setDescription(loc_default.get(`c_${filename}_sub1_desc`)!) .setDescription(loc_default.get(`c_${filename}_sub1_desc`) ?? "")
.setNameLocalizations(getLocalizations(client, `c_${filename}_sub1_name`, true)) .setNameLocalizations(getLocalizations(client, `c_${filename}_sub1_name`, true))
.setDescriptionLocalizations(getLocalizations(client, `c_${filename}_sub1_desc`)) .setDescriptionLocalizations(getLocalizations(client, `c_${filename}_sub1_desc`))
// Specified Time // Specified Time
.addStringOption((option) => .addStringOption((option) =>
option option
.setName(loc_default.get(`c_${filename}_sub1_opt1_name`)!.toLowerCase()) .setName(loc_default.get(`c_${filename}_sub1_opt1_name`)?.toLowerCase() ?? "")
.setDescription(loc_default.get(`c_${filename}_sub1_opt1_desc`)!) .setDescription(loc_default.get(`c_${filename}_sub1_opt1_desc`) ?? "")
.setNameLocalizations( .setNameLocalizations(
getLocalizations(client, `c_${filename}_sub1_opt1_name`, true), getLocalizations(client, `c_${filename}_sub1_opt1_name`, true),
) )
@ -63,8 +63,8 @@ export default {
// Specified message (not required) // Specified message (not required)
.addStringOption((option) => .addStringOption((option) =>
option option
.setName(loc_default.get(`c_${filename}_sub1_opt2_name`)!.toLowerCase()) .setName(loc_default.get(`c_${filename}_sub1_opt2_name`)?.toLowerCase() ?? "")
.setDescription(loc_default.get(`c_${filename}_sub1_opt2_desc`)!) .setDescription(loc_default.get(`c_${filename}_sub1_opt2_desc`) ?? "")
.setNameLocalizations( .setNameLocalizations(
getLocalizations(client, `c_${filename}_sub1_opt2_name`, true), getLocalizations(client, `c_${filename}_sub1_opt2_name`, true),
) )
@ -77,16 +77,16 @@ export default {
// List reminders // List reminders
.addSubcommand((subcommand) => .addSubcommand((subcommand) =>
subcommand subcommand
.setName(loc_default.get(`c_${filename}_sub2_name`)!.toLowerCase()) .setName(loc_default.get(`c_${filename}_sub2_name`)?.toLowerCase() ?? "")
.setDescription(loc_default.get(`c_${filename}_sub2_desc`)!) .setDescription(loc_default.get(`c_${filename}_sub2_desc`) ?? "")
.setNameLocalizations(getLocalizations(client, `c_${filename}_sub2_name`, true)) .setNameLocalizations(getLocalizations(client, `c_${filename}_sub2_name`, true))
.setDescriptionLocalizations(getLocalizations(client, `c_${filename}_sub2_desc`)) .setDescriptionLocalizations(getLocalizations(client, `c_${filename}_sub2_desc`))
// User // User
.addUserOption((option) => .addUserOption((option) =>
option option
.setName(loc_default.get(`c_${filename}_sub2_opt1_name`)!.toLowerCase()) .setName(loc_default.get(`c_${filename}_sub2_opt1_name`)?.toLowerCase() ?? "")
.setDescription(loc_default.get(`c_${filename}_sub2_opt1_desc`)!) .setDescription(loc_default.get(`c_${filename}_sub2_opt1_desc`) ?? "")
.setNameLocalizations( .setNameLocalizations(
getLocalizations(client, `c_${filename}_sub2_opt1_name`, true), getLocalizations(client, `c_${filename}_sub2_opt1_name`, true),
) )
@ -98,8 +98,8 @@ export default {
// Page // Page
.addIntegerOption((option) => .addIntegerOption((option) =>
option option
.setName(loc_default.get(`c_${filename}_sub2_opt2_name`)!.toLowerCase()) .setName(loc_default.get(`c_${filename}_sub2_opt2_name`)?.toLowerCase() ?? "")
.setDescription(loc_default.get(`c_${filename}_sub2_opt2_desc`)!) .setDescription(loc_default.get(`c_${filename}_sub2_opt2_desc`) ?? "")
.setNameLocalizations( .setNameLocalizations(
getLocalizations(client, `c_${filename}_sub2_opt2_name`, true), getLocalizations(client, `c_${filename}_sub2_opt2_name`, true),
) )
@ -112,16 +112,16 @@ export default {
// Delete a reminder // Delete a reminder
.addSubcommand((subcommand) => .addSubcommand((subcommand) =>
subcommand subcommand
.setName(loc_default.get(`c_${filename}_sub3_name`)!.toLowerCase()) .setName(loc_default.get(`c_${filename}_sub3_name`)?.toLowerCase() ?? "")
.setDescription(loc_default.get(`c_${filename}_sub3_desc`)!) .setDescription(loc_default.get(`c_${filename}_sub3_desc`) ?? "")
.setNameLocalizations(getLocalizations(client, `c_${filename}_sub3_name`, true)) .setNameLocalizations(getLocalizations(client, `c_${filename}_sub3_name`, true))
.setDescriptionLocalizations(getLocalizations(client, `c_${filename}_sub3_desc`)) .setDescriptionLocalizations(getLocalizations(client, `c_${filename}_sub3_desc`))
// ID // ID
.addIntegerOption((option) => .addIntegerOption((option) =>
option option
.setName(loc_default.get(`c_${filename}_sub3_opt1_name`)!.toLowerCase()) .setName(loc_default.get(`c_${filename}_sub3_opt1_name`)?.toLowerCase() ?? "")
.setDescription(loc_default.get(`c_${filename}_sub3_opt1_desc`)!) .setDescription(loc_default.get(`c_${filename}_sub3_opt1_desc`) ?? "")
.setNameLocalizations( .setNameLocalizations(
getLocalizations(client, `c_${filename}_sub3_opt1_name`, true), getLocalizations(client, `c_${filename}_sub3_opt1_name`, true),
) )
@ -142,7 +142,7 @@ export default {
const subcommand = interaction.options.getSubcommand(); const subcommand = interaction.options.getSubcommand();
switch (subcommand) { switch (subcommand) {
// New reminder // New reminder
case loc_default?.get(`c_${filename}_sub1_name`)?.toLowerCase(): { case loc_default?.get(`c_${filename}_sub1_name`)?.toLowerCase() ?? "": {
// If time is already renseigned // If time is already renseigned
const time = interaction.options.getString( const time = interaction.options.getString(
loc_default?.get(`c_${filename}_sub1_opt1_name`) as string, loc_default?.get(`c_${filename}_sub1_opt1_name`) as string,
@ -193,7 +193,7 @@ export default {
} }
} }
// List reminders // List reminders
case loc_default?.get(`c_${filename}_sub2_name`)?.toLowerCase(): { case loc_default?.get(`c_${filename}_sub2_name`)?.toLowerCase() ?? "": {
// Which user to show // Which user to show
let user = interaction.options.getUser( let user = interaction.options.getUser(
loc_default?.get(`c_${filename}_sub2_opt1_name`) as string, loc_default?.get(`c_${filename}_sub2_opt1_name`) as string,
@ -244,7 +244,7 @@ export default {
return; return;
} }
// Delete a reminder // Delete a reminder
case loc_default?.get(`c_${filename}_sub3_name`)?.toLowerCase(): { case loc_default?.get(`c_${filename}_sub3_name`)?.toLowerCase() ?? "": {
const id = interaction.options.getInteger( const id = interaction.options.getInteger(
loc_default?.get(`c_${filename}_sub3_opt1_name`) as string, loc_default?.get(`c_${filename}_sub3_opt1_name`) as string,
); );

View file

@ -1,6 +1,6 @@
import { SlashCommandBuilder } from "@discordjs/builders"; import { SlashCommandBuilder } from "@discordjs/builders";
import { Player, useMainPlayer, useQueue } from "discord-player"; import { Player, useMainPlayer, useQueue } from "discord-player";
import { ChatInputCommandInteraction, Client, EmbedBuilder } from "discord.js"; import { ChannelType, ChatInputCommandInteraction, Client, EmbedBuilder } from "discord.js";
import { getLocale, getLocalizations } from "../../utils/locales"; import { getLocale, getLocalizations } from "../../utils/locales";
import { getFilename } from "../../utils/misc"; import { getFilename } from "../../utils/misc";
@ -17,23 +17,23 @@ export default {
return ( return (
new SlashCommandBuilder() new SlashCommandBuilder()
.setName(filename.toLowerCase()) .setName(filename.toLowerCase())
.setDescription(loc_default.get(`c_${filename}_desc`)!) .setDescription(loc_default.get(`c_${filename}_desc`) ?? "")
.setNameLocalizations(getLocalizations(client, `c_${filename}_name`, true)) .setNameLocalizations(getLocalizations(client, `c_${filename}_name`, true))
.setDescriptionLocalizations(getLocalizations(client, `c_${filename}_desc`)) .setDescriptionLocalizations(getLocalizations(client, `c_${filename}_desc`))
// Normal // Normal
.addSubcommand((subcommand) => .addSubcommand((subcommand) =>
subcommand subcommand
.setName(loc_default.get(`c_${filename}_sub1_name`)!.toLowerCase()) .setName(loc_default.get(`c_${filename}_sub1_name`)?.toLowerCase() ?? "")
.setDescription(loc_default.get(`c_${filename}_sub1_desc`)!) .setDescription(loc_default.get(`c_${filename}_sub1_desc`) ?? "")
.setNameLocalizations(getLocalizations(client, `c_${filename}_sub1_name`, true)) .setNameLocalizations(getLocalizations(client, `c_${filename}_sub1_name`, true))
.setDescriptionLocalizations(getLocalizations(client, `c_${filename}_sub1_desc`)) .setDescriptionLocalizations(getLocalizations(client, `c_${filename}_sub1_desc`))
// Command option // Command option
.addStringOption((option) => .addStringOption((option) =>
option option
.setName(loc_default.get(`c_${filename}_opt1_name`)!.toLowerCase()) .setName(loc_default.get(`c_${filename}_opt1_name`)?.toLowerCase() ?? "")
.setDescription(loc_default.get(`c_${filename}_opt1_desc`)!) .setDescription(loc_default.get(`c_${filename}_opt1_desc`) ?? "")
.setNameLocalizations(getLocalizations(client, `c_${filename}_opt1_name`, true)) .setNameLocalizations(getLocalizations(client, `c_${filename}_opt1_name`, true))
.setDescriptionLocalizations(getLocalizations(client, `c_${filename}_opt1_desc`)), .setDescriptionLocalizations(getLocalizations(client, `c_${filename}_opt1_desc`)),
), ),
@ -42,16 +42,16 @@ export default {
// Romanized // Romanized
.addSubcommand((subcommand) => .addSubcommand((subcommand) =>
subcommand subcommand
.setName(loc_default.get(`c_${filename}_sub2_name`)!.toLowerCase()) .setName(loc_default.get(`c_${filename}_sub2_name`)?.toLowerCase() ?? "")
.setDescription(loc_default.get(`c_${filename}_sub2_desc`)!) .setDescription(loc_default.get(`c_${filename}_sub2_desc`) ?? "")
.setNameLocalizations(getLocalizations(client, `c_${filename}_sub2_name`, true)) .setNameLocalizations(getLocalizations(client, `c_${filename}_sub2_name`, true))
.setDescriptionLocalizations(getLocalizations(client, `c_${filename}_sub2_desc`)) .setDescriptionLocalizations(getLocalizations(client, `c_${filename}_sub2_desc`))
// Command option // Command option
.addStringOption((option) => .addStringOption((option) =>
option option
.setName(loc_default.get(`c_${filename}_opt1_name`)!.toLowerCase()) .setName(loc_default.get(`c_${filename}_opt1_name`)?.toLowerCase() ?? "")
.setDescription(loc_default.get(`c_${filename}_opt1_desc`)!) .setDescription(loc_default.get(`c_${filename}_opt1_desc`) ?? "")
.setNameLocalizations(getLocalizations(client, `c_${filename}_opt1_name`, true)) .setNameLocalizations(getLocalizations(client, `c_${filename}_opt1_name`, true))
.setDescriptionLocalizations(getLocalizations(client, `c_${filename}_opt1_desc`)), .setDescriptionLocalizations(getLocalizations(client, `c_${filename}_opt1_desc`)),
), ),
@ -60,8 +60,8 @@ export default {
// Synced // Synced
.addSubcommand((subcommand) => .addSubcommand((subcommand) =>
subcommand subcommand
.setName(loc_default.get(`c_${filename}_sub3_name`)!.toLowerCase()) .setName(loc_default.get(`c_${filename}_sub3_name`)?.toLowerCase() ?? "")
.setDescription(loc_default.get(`c_${filename}_sub3_desc`)!) .setDescription(loc_default.get(`c_${filename}_sub3_desc`) ?? "")
.setNameLocalizations(getLocalizations(client, `c_${filename}_sub3_name`, true)) .setNameLocalizations(getLocalizations(client, `c_${filename}_sub3_name`, true))
.setDescriptionLocalizations(getLocalizations(client, `c_${filename}_sub3_desc`)), .setDescriptionLocalizations(getLocalizations(client, `c_${filename}_sub3_desc`)),
) )
@ -82,11 +82,12 @@ export default {
await interaction.deferReply(); await interaction.deferReply();
const player = useMainPlayer() as Player; const player = useMainPlayer() as Player;
const queue = useQueue(interaction.guildId!); const queue = useQueue(interaction.guildId ?? "");
if (request) { if (request) {
if ( if (
interaction.options.getSubcommand() == interaction.options.getSubcommand() ==
loc_default?.get(`c_${filename}_sub2_name`)?.toLowerCase() loc_default?.get(`c_${filename}_sub2_name`)?.toLowerCase() ??
""
) { ) {
// Romanized // Romanized
request += " romanized"; request += " romanized";
@ -112,7 +113,8 @@ export default {
if ( if (
interaction.options.getSubcommand() == interaction.options.getSubcommand() ==
loc_default?.get(`c_${filename}_sub3_name`)?.toLowerCase() loc_default?.get(`c_${filename}_sub3_name`)?.toLowerCase() ??
""
) { ) {
if (queue === null) { if (queue === null) {
return await interaction.followUp(`❌ | ${loc.get("c_lyrics1")}`); return await interaction.followUp(`❌ | ${loc.get("c_lyrics1")}`);
@ -129,12 +131,12 @@ export default {
syncedLyrics?.onChange(async (lyrics) => { syncedLyrics?.onChange(async (lyrics) => {
const content = `[${data[0].trackName}]: ${lyrics}`; const content = `[${data[0].trackName}]: ${lyrics}`;
if (interaction.channel?.isSendable()) { if (interaction.channel?.type === ChannelType.GroupDM) {
await interaction.channel?.send({ await interaction.followUp({
content, content,
}); });
} else { } else {
await interaction.followUp({ await interaction.channel?.send({
content, content,
}); });
} }

View file

@ -16,14 +16,14 @@ export default {
return new SlashCommandBuilder() return new SlashCommandBuilder()
.setName(filename.toLowerCase()) .setName(filename.toLowerCase())
.setDescription(loc_default.get(`c_${filename}_desc`)!) .setDescription(loc_default.get(`c_${filename}_desc`) ?? "")
.setNameLocalizations(getLocalizations(client, `c_${filename}_name`, true)) .setNameLocalizations(getLocalizations(client, `c_${filename}_name`, true))
.setDescriptionLocalizations(getLocalizations(client, `c_${filename}_desc`)); .setDescriptionLocalizations(getLocalizations(client, `c_${filename}_desc`));
}, },
interaction: async (interaction: ChatInputCommandInteraction, client: Client) => { interaction: async (interaction: ChatInputCommandInteraction, client: Client) => {
const loc = getLocale(client, interaction.locale); const loc = getLocale(client, interaction.locale);
const queue = useQueue(interaction.guildId!); const queue = useQueue(interaction.guildId ?? "");
if (queue) { if (queue) {
const embed = new EmbedBuilder(); const embed = new EmbedBuilder();

View file

@ -25,15 +25,15 @@ export default {
return ( return (
new SlashCommandBuilder() new SlashCommandBuilder()
.setName(filename.toLowerCase()) .setName(filename.toLowerCase())
.setDescription(loc_default.get(`c_${filename}_desc`)!) .setDescription(loc_default.get(`c_${filename}_desc`) ?? "")
.setNameLocalizations(getLocalizations(client, `c_${filename}_name`, true)) .setNameLocalizations(getLocalizations(client, `c_${filename}_name`, true))
.setDescriptionLocalizations(getLocalizations(client, `c_${filename}_desc`)) .setDescriptionLocalizations(getLocalizations(client, `c_${filename}_desc`))
// Command option // Command option
.addStringOption((option) => .addStringOption((option) =>
option option
.setName(loc_default.get(`c_${filename}_opt1_name`)!.toLowerCase()) .setName(loc_default.get(`c_${filename}_opt1_name`)?.toLowerCase() ?? "")
.setDescription(loc_default.get(`c_${filename}_opt1_desc`)!) .setDescription(loc_default.get(`c_${filename}_opt1_desc`) ?? "")
.setNameLocalizations(getLocalizations(client, `c_${filename}_opt1_name`, true)) .setNameLocalizations(getLocalizations(client, `c_${filename}_opt1_name`, true))
.setDescriptionLocalizations(getLocalizations(client, `c_${filename}_opt1_desc`)) .setDescriptionLocalizations(getLocalizations(client, `c_${filename}_opt1_desc`))
.setAutocomplete(true), .setAutocomplete(true),
@ -47,8 +47,8 @@ export default {
const filename = getFilename(__filename); const filename = getFilename(__filename);
const member = client.guilds.cache const member = client.guilds.cache
.get(interaction.guildId!) .get(interaction.guildId ?? "")
?.members.cache.get(interaction.member!.user.id); ?.members.cache.get(interaction.member?.user.id ?? "");
if (!member?.voice.channelId) { if (!member?.voice.channelId) {
return await interaction.reply({ return await interaction.reply({
@ -75,7 +75,7 @@ export default {
if (!query) { if (!query) {
// Now playing // Now playing
const queue = useQueue(interaction.guildId!); const queue = useQueue(interaction.guildId ?? "");
if (queue) { if (queue) {
const track = queue.history.currentTrack; const track = queue.history.currentTrack;

View file

@ -27,23 +27,23 @@ export default {
return ( return (
new SlashCommandBuilder() new SlashCommandBuilder()
.setName(filename.toLowerCase()) .setName(filename.toLowerCase())
.setDescription(loc_default.get(`c_${filename}_desc`)!) .setDescription(loc_default.get(`c_${filename}_desc`) ?? "")
.setNameLocalizations(getLocalizations(client, `c_${filename}_name`, true)) .setNameLocalizations(getLocalizations(client, `c_${filename}_name`, true))
.setDescriptionLocalizations(getLocalizations(client, `c_${filename}_desc`)) .setDescriptionLocalizations(getLocalizations(client, `c_${filename}_desc`))
// Show the queue // Show the queue
.addSubcommand((subcommand) => .addSubcommand((subcommand) =>
subcommand subcommand
.setName(loc_default.get(`c_${filename}_sub1_name`)!.toLowerCase()) .setName(loc_default.get(`c_${filename}_sub1_name`)?.toLowerCase() ?? "")
.setDescription(loc_default.get(`c_${filename}_sub1_desc`)!) .setDescription(loc_default.get(`c_${filename}_sub1_desc`) ?? "")
.setNameLocalizations(getLocalizations(client, `c_${filename}_sub1_name`, true)) .setNameLocalizations(getLocalizations(client, `c_${filename}_sub1_name`, true))
.setDescriptionLocalizations(getLocalizations(client, `c_${filename}_sub1_desc`)) .setDescriptionLocalizations(getLocalizations(client, `c_${filename}_sub1_desc`))
// Specified Page // Specified Page
.addNumberOption((option) => .addNumberOption((option) =>
option option
.setName(loc_default.get(`c_${filename}_sub1_opt1_name`)!.toLowerCase()) .setName(loc_default.get(`c_${filename}_sub1_opt1_name`)?.toLowerCase() ?? "")
.setDescription(loc_default.get(`c_${filename}_sub1_opt1_desc`)!) .setDescription(loc_default.get(`c_${filename}_sub1_opt1_desc`) ?? "")
.setNameLocalizations( .setNameLocalizations(
getLocalizations(client, `c_${filename}_sub1_opt1_name`, true), getLocalizations(client, `c_${filename}_sub1_opt1_name`, true),
) )
@ -56,8 +56,8 @@ export default {
// Shuffle Queue // Shuffle Queue
.addSubcommand((subcommand) => .addSubcommand((subcommand) =>
subcommand subcommand
.setName(loc_default.get(`c_${filename}_sub2_name`)!.toLowerCase()) .setName(loc_default.get(`c_${filename}_sub2_name`)?.toLowerCase() ?? "")
.setDescription(loc_default.get(`c_${filename}_sub2_desc`)!) .setDescription(loc_default.get(`c_${filename}_sub2_desc`) ?? "")
.setNameLocalizations(getLocalizations(client, `c_${filename}_sub2_name`, true)) .setNameLocalizations(getLocalizations(client, `c_${filename}_sub2_name`, true))
.setDescriptionLocalizations(getLocalizations(client, `c_${filename}_sub2_desc`)), .setDescriptionLocalizations(getLocalizations(client, `c_${filename}_sub2_desc`)),
) )
@ -65,8 +65,8 @@ export default {
// Remove <ID> // Remove <ID>
.addSubcommand((subcommand) => .addSubcommand((subcommand) =>
subcommand subcommand
.setName(loc_default.get(`c_${filename}_sub3_name`)!.toLowerCase()) .setName(loc_default.get(`c_${filename}_sub3_name`)?.toLowerCase() ?? "")
.setDescription(loc_default.get(`c_${filename}_sub3_desc`)!) .setDescription(loc_default.get(`c_${filename}_sub3_desc`) ?? "")
.setNameLocalizations(getLocalizations(client, `c_${filename}_sub3_name`, true)) .setNameLocalizations(getLocalizations(client, `c_${filename}_sub3_name`, true))
.setDescriptionLocalizations(getLocalizations(client, `c_${filename}_sub3_desc`)) .setDescriptionLocalizations(getLocalizations(client, `c_${filename}_sub3_desc`))
@ -74,8 +74,8 @@ export default {
// TODO?: ID range -> as a string: 5-8 remove 5, 6, 7, 8 // TODO?: ID range -> as a string: 5-8 remove 5, 6, 7, 8
.addNumberOption((option) => .addNumberOption((option) =>
option option
.setName(loc_default.get(`c_${filename}_sub3_opt1_name`)!.toLowerCase()) .setName(loc_default.get(`c_${filename}_sub3_opt1_name`)?.toLowerCase() ?? "")
.setDescription(loc_default.get(`c_${filename}_sub3_opt1_desc`)!) .setDescription(loc_default.get(`c_${filename}_sub3_opt1_desc`) ?? "")
.setNameLocalizations( .setNameLocalizations(
getLocalizations(client, `c_${filename}_sub3_opt1_name`, true), getLocalizations(client, `c_${filename}_sub3_opt1_name`, true),
) )
@ -93,7 +93,7 @@ export default {
const filename = getFilename(__filename); const filename = getFilename(__filename);
const loc = getLocale(client, interaction.locale); const loc = getLocale(client, interaction.locale);
const queue = useQueue(interaction.guildId!); const queue = useQueue(interaction.guildId ?? "");
const embed = new EmbedBuilder(); const embed = new EmbedBuilder();
@ -101,7 +101,7 @@ export default {
const subcommand = interaction.options.getSubcommand(); const subcommand = interaction.options.getSubcommand();
switch (subcommand) { switch (subcommand) {
// Show the queue // Show the queue
case loc_default?.get(`c_${filename}_sub1_name`)?.toLowerCase(): { case loc_default?.get(`c_${filename}_sub1_name`)?.toLowerCase() ?? "": {
const page = const page =
interaction.options.getNumber( interaction.options.getNumber(
loc_default?.get(`c_${filename}_sub1_opt1_name`) as string, loc_default?.get(`c_${filename}_sub1_opt1_name`) as string,
@ -142,7 +142,7 @@ export default {
} }
// Shuffle Queue // Shuffle Queue
case loc_default?.get(`c_${filename}_sub2_name`)?.toLowerCase(): { case loc_default?.get(`c_${filename}_sub2_name`)?.toLowerCase() ?? "": {
queue.tracks.shuffle(); queue.tracks.shuffle();
embed.setDescription(loc.get("c_queue3")); embed.setDescription(loc.get("c_queue3"));
@ -150,7 +150,7 @@ export default {
} }
// Remove <ID> // Remove <ID>
case loc_default?.get(`c_${filename}_sub3_name`)?.toLowerCase(): { case loc_default?.get(`c_${filename}_sub3_name`)?.toLowerCase() ?? "": {
const id = interaction.options.getNumber( const id = interaction.options.getNumber(
loc_default?.get(`c_${filename}_sub3_opt1_name`) as string, loc_default?.get(`c_${filename}_sub3_opt1_name`) as string,
) as number; ) as number;

View file

@ -17,15 +17,15 @@ export default {
return ( return (
new SlashCommandBuilder() new SlashCommandBuilder()
.setName(filename.toLowerCase()) .setName(filename.toLowerCase())
.setDescription(loc_default.get(`c_${filename}_desc`)!) .setDescription(loc_default.get(`c_${filename}_desc`) ?? "")
.setNameLocalizations(getLocalizations(client, `c_${filename}_name`, true)) .setNameLocalizations(getLocalizations(client, `c_${filename}_name`, true))
.setDescriptionLocalizations(getLocalizations(client, `c_${filename}_desc`)) .setDescriptionLocalizations(getLocalizations(client, `c_${filename}_desc`))
// Disable repeat // Disable repeat
.addSubcommand((subcommand) => .addSubcommand((subcommand) =>
subcommand subcommand
.setName(loc_default.get(`c_${filename}_sub1_name`)!.toLowerCase()) .setName(loc_default.get(`c_${filename}_sub1_name`)?.toLowerCase() ?? "")
.setDescription(loc_default.get(`c_${filename}_sub1_desc`)!) .setDescription(loc_default.get(`c_${filename}_sub1_desc`) ?? "")
.setNameLocalizations(getLocalizations(client, `c_${filename}_sub1_name`, true)) .setNameLocalizations(getLocalizations(client, `c_${filename}_sub1_name`, true))
.setDescriptionLocalizations(getLocalizations(client, `c_${filename}_sub1_desc`)), .setDescriptionLocalizations(getLocalizations(client, `c_${filename}_sub1_desc`)),
) )
@ -33,8 +33,8 @@ export default {
// Repeat current track // Repeat current track
.addSubcommand((subcommand) => .addSubcommand((subcommand) =>
subcommand subcommand
.setName(loc_default.get(`c_${filename}_sub2_name`)!.toLowerCase()) .setName(loc_default.get(`c_${filename}_sub2_name`)?.toLowerCase() ?? "")
.setDescription(loc_default.get(`c_${filename}_sub2_desc`)!) .setDescription(loc_default.get(`c_${filename}_sub2_desc`) ?? "")
.setNameLocalizations(getLocalizations(client, `c_${filename}_sub2_name`, true)) .setNameLocalizations(getLocalizations(client, `c_${filename}_sub2_name`, true))
.setDescriptionLocalizations(getLocalizations(client, `c_${filename}_sub2_desc`)), .setDescriptionLocalizations(getLocalizations(client, `c_${filename}_sub2_desc`)),
) )
@ -42,8 +42,8 @@ export default {
// Repeat queue // Repeat queue
.addSubcommand((subcommand) => .addSubcommand((subcommand) =>
subcommand subcommand
.setName(loc_default.get(`c_${filename}_sub3_name`)!.toLowerCase()) .setName(loc_default.get(`c_${filename}_sub3_name`)?.toLowerCase() ?? "")
.setDescription(loc_default.get(`c_${filename}_sub3_desc`)!) .setDescription(loc_default.get(`c_${filename}_sub3_desc`) ?? "")
.setNameLocalizations(getLocalizations(client, `c_${filename}_sub3_name`, true)) .setNameLocalizations(getLocalizations(client, `c_${filename}_sub3_name`, true))
.setDescriptionLocalizations(getLocalizations(client, `c_${filename}_sub3_desc`)), .setDescriptionLocalizations(getLocalizations(client, `c_${filename}_sub3_desc`)),
) )
@ -51,8 +51,8 @@ export default {
// Enable autoplay // Enable autoplay
.addSubcommand((subcommand) => .addSubcommand((subcommand) =>
subcommand subcommand
.setName(loc_default.get(`c_${filename}_sub4_name`)!.toLowerCase()) .setName(loc_default.get(`c_${filename}_sub4_name`)?.toLowerCase() ?? "")
.setDescription(loc_default.get(`c_${filename}_sub4_desc`)!) .setDescription(loc_default.get(`c_${filename}_sub4_desc`) ?? "")
.setNameLocalizations(getLocalizations(client, `c_${filename}_sub4_name`, true)) .setNameLocalizations(getLocalizations(client, `c_${filename}_sub4_name`, true))
.setDescriptionLocalizations(getLocalizations(client, `c_${filename}_sub4_desc`)), .setDescriptionLocalizations(getLocalizations(client, `c_${filename}_sub4_desc`)),
) )
@ -64,31 +64,31 @@ export default {
const filename = getFilename(__filename); const filename = getFilename(__filename);
const loc = getLocale(client, interaction.locale); const loc = getLocale(client, interaction.locale);
const queue = useQueue(interaction.guildId!); const queue = useQueue(interaction.guildId ?? "");
if (queue) { if (queue) {
const subcommand = interaction.options.getSubcommand(); const subcommand = interaction.options.getSubcommand();
switch (subcommand) { switch (subcommand) {
// Disable // Disable
case loc_default?.get(`c_${filename}_sub1_name`)?.toLowerCase(): { case loc_default?.get(`c_${filename}_sub1_name`)?.toLowerCase() ?? "": {
queue.setRepeatMode(QueueRepeatMode.OFF); queue.setRepeatMode(QueueRepeatMode.OFF);
return interaction.reply(loc.get("c_repeat2") + "."); return interaction.reply(loc.get("c_repeat2") + ".");
} }
// Queue Repeat // Queue Repeat
case loc_default?.get(`c_${filename}_sub3_name`)?.toLowerCase(): { case loc_default?.get(`c_${filename}_sub3_name`)?.toLowerCase() ?? "": {
queue.setRepeatMode(QueueRepeatMode.QUEUE); queue.setRepeatMode(QueueRepeatMode.QUEUE);
return interaction.reply(`${loc.get("c_repeat3")} ${loc.get("c_repeat6")}.`); return interaction.reply(`${loc.get("c_repeat3")} ${loc.get("c_repeat6")}.`);
} }
// Autoplay // Autoplay
case loc_default?.get(`c_${filename}_sub4_name`)?.toLowerCase(): { case loc_default?.get(`c_${filename}_sub4_name`)?.toLowerCase() ?? "": {
queue.setRepeatMode(QueueRepeatMode.AUTOPLAY); queue.setRepeatMode(QueueRepeatMode.AUTOPLAY);
return interaction.reply(`${loc.get("c_repeat4")} ${loc.get("c_repeat6")}.`); return interaction.reply(`${loc.get("c_repeat4")} ${loc.get("c_repeat6")}.`);
} }
// Track repeat // Track repeat
case loc_default?.get(`c_${filename}_sub2_name`)?.toLowerCase(): { case loc_default?.get(`c_${filename}_sub2_name`)?.toLowerCase() ?? "": {
queue.setRepeatMode(QueueRepeatMode.TRACK); queue.setRepeatMode(QueueRepeatMode.TRACK);
return interaction.reply( return interaction.reply(
`${loc.get("c_repeat5")} ${queue.history.currentTrack?.title} ${loc.get("c_repeat6")}.`, `${loc.get("c_repeat5")} ${queue.history.currentTrack?.title} ${loc.get("c_repeat6")}.`,

View file

@ -17,15 +17,15 @@ export default {
return ( return (
new SlashCommandBuilder() new SlashCommandBuilder()
.setName(filename.toLowerCase()) .setName(filename.toLowerCase())
.setDescription(loc_default.get(`c_${filename}_desc`)!) .setDescription(loc_default.get(`c_${filename}_desc`) ?? "")
.setNameLocalizations(getLocalizations(client, `c_${filename}_name`, true)) .setNameLocalizations(getLocalizations(client, `c_${filename}_name`, true))
.setDescriptionLocalizations(getLocalizations(client, `c_${filename}_desc`)) .setDescriptionLocalizations(getLocalizations(client, `c_${filename}_desc`))
// Command option // Command option
.addNumberOption((option) => .addNumberOption((option) =>
option option
.setName(loc_default.get(`c_${filename}_opt1_name`)!.toLowerCase()) .setName(loc_default.get(`c_${filename}_opt1_name`)?.toLowerCase() ?? "")
.setDescription(loc_default.get(`c_${filename}_opt1_desc`)!) .setDescription(loc_default.get(`c_${filename}_opt1_desc`) ?? "")
.setNameLocalizations(getLocalizations(client, `c_${filename}_opt1_name`, true)) .setNameLocalizations(getLocalizations(client, `c_${filename}_opt1_name`, true))
.setDescriptionLocalizations(getLocalizations(client, `c_${filename}_opt1_desc`)), .setDescriptionLocalizations(getLocalizations(client, `c_${filename}_opt1_desc`)),
) )
@ -37,7 +37,7 @@ export default {
const filename = getFilename(__filename); const filename = getFilename(__filename);
const loc = getLocale(client, interaction.locale); const loc = getLocale(client, interaction.locale);
const queue = useQueue(interaction.guildId!); const queue = useQueue(interaction.guildId ?? "");
const id = interaction.options.getNumber(loc_default?.get(`c_${filename}_opt1_name`) as string); const id = interaction.options.getNumber(loc_default?.get(`c_${filename}_opt1_name`) as string);

View file

@ -17,7 +17,7 @@ export default {
return new SlashCommandBuilder() return new SlashCommandBuilder()
.setName(filename.toLowerCase()) .setName(filename.toLowerCase())
.setDescription(loc_default.get(`c_${filename}_desc`)!) .setDescription(loc_default.get(`c_${filename}_desc`) ?? "")
.setNameLocalizations(getLocalizations(client, `c_${filename}_name`, true)) .setNameLocalizations(getLocalizations(client, `c_${filename}_name`, true))
.setDescriptionLocalizations(getLocalizations(client, `c_${filename}_desc`)); .setDescriptionLocalizations(getLocalizations(client, `c_${filename}_desc`));
}, },

View file

@ -2,7 +2,7 @@ import { Player, PlayerEvents, useMainPlayer } from "discord-player";
import { Client } from "discord.js"; import { Client } from "discord.js";
import { readdir } from "fs/promises"; import { readdir } from "fs/promises";
/** Load all the events */ /** Load all the events. */
export default async (client: Client) => { export default async (client: Client) => {
const events_categories = (await readdir(__dirname)).filter( const events_categories = (await readdir(__dirname)).filter(
(element) => !element.endsWith(".js") && !element.endsWith(".ts"), (element) => !element.endsWith(".js") && !element.endsWith(".ts"),

View file

@ -1,4 +1,11 @@
import { Client, EmbedBuilder, GuildMember, Message, TextBasedChannel } from "discord.js"; import {
ChannelType,
Client,
EmbedBuilder,
GuildMember,
Message,
TextBasedChannel,
} from "discord.js";
import { getLocale } from "../../utils/locales"; import { getLocale } from "../../utils/locales";
import { isImage, userWithNickname } from "../../utils/misc"; import { isImage, userWithNickname } from "../../utils/misc";
import { showDate } from "../../utils/time"; import { showDate } from "../../utils/time";
@ -165,7 +172,7 @@ export default async (message: Message, client: Client) => {
!message.content.replace(new RegExp(regex, "g"), "").trim() && !message.content.replace(new RegExp(regex, "g"), "").trim() &&
messages.length === urls.length && messages.length === urls.length &&
!message.mentions.repliedUser && !message.mentions.repliedUser &&
message.channel.isSendable() message.channel.type !== ChannelType.GroupDM
) { ) {
message.delete(); message.delete();
return message.channel.send({ embeds: [embed] }); return message.channel.send({ embeds: [embed] });

View file

@ -1,6 +1,6 @@
import { EmbedBuilder } from "@discordjs/builders"; import { EmbedBuilder } from "@discordjs/builders";
import { GuildQueue, Track } from "discord-player"; import { GuildQueue, Track } from "discord-player";
import { Client } from "discord.js"; import { ChannelType, Client } from "discord.js";
import { Metadata } from "../../utils/metadata"; import { Metadata } from "../../utils/metadata";
import { emojiPng } from "../../utils/misc"; import { emojiPng } from "../../utils/misc";
@ -20,7 +20,7 @@ export default (queue: GuildQueue<Metadata>, track: Track, client: Client) => {
iconURL: emojiPng("🎶"), iconURL: emojiPng("🎶"),
}); });
if (queue.metadata.channel?.isSendable()) { if (queue.metadata.channel?.type !== ChannelType.GroupDM) {
queue.metadata?.channel?.send({ embeds: [embed] }); queue.metadata?.channel?.send({ embeds: [embed] });
} }
}; };

View file

@ -1,4 +1,4 @@
/** Load the app */ /** Load the app. */
const start_app = () => { const start_app = () => {
import("./load").then((l) => l.run().catch((error) => console.error(error))); import("./load").then((l) => l.run().catch((error) => console.error(error)));
}; };

View file

@ -6,7 +6,7 @@ import loadClient, { quit } from "./utils/client";
import { logStart } from "./utils/misc"; import { logStart } from "./utils/misc";
/** Run the bot */ /** Run the bot. */
export const run = async () => { export const run = async () => {
console.log("Starting Botanique..."); console.log("Starting Botanique...");

View file

@ -16,6 +16,29 @@
"c_help2": "`/help <command>` to get more information about a command.", "c_help2": "`/help <command>` to get more information about a command.",
"c_help3": "Can't find :", "c_help3": "Can't find :",
"c_archive_name": "clean",
"c_archive_desc": "Clean category for new year",
"c_archive_opt1_name": "category",
"c_archive_opt1_desc": "Name of the category to be cleaned",
"c_archive1": "List of categories subject to cleaning",
"c_archive2": "`L1`, `L2`, `L3`, `M1`, `M2`",
"c_archive3": "Unable to find/clean the channel:",
"c_archive4": "List of archived channels in the category",
"c_archive5": "to",
"c_archive6": "Cleaning",
"c_archive7": "Category already cleaned",
"c_prep_name": "Preparation",
"c_prep_desc": "Preparation of general channels for the new year",
"c_prep_opt1_name": "year",
"c_prep_opt1_desc": "Name of the year to be prepared",
"c_prep1": "List of categories submitted to the preparation",
"c_prep2": "`L1`, `L2`, `L3`, `M1`, `M2`",
"c_prep3": "Unable to find/clean the channel:",
"c_prep4": "Lists of prepared channels `",
"c_prep5": "created",
"c_prep6": "No preparation required",
"u_time_at": "at", "u_time_at": "at",
"c_reminder_name": "reminder", "c_reminder_name": "reminder",

View file

@ -17,6 +17,29 @@
"c_help2": "`/help <commande>` pour obtenir plus d'informations sur une commande.", "c_help2": "`/help <commande>` pour obtenir plus d'informations sur une commande.",
"c_help3": "Impossible de trouver :", "c_help3": "Impossible de trouver :",
"c_archive_name": "Nettoyer",
"c_archive_desc": "Nettoyage pour le passage à niveau",
"c_archive_opt1_name": "catégorie",
"c_archive_opt1_desc": "Nom de la catégorie à nettoyer",
"c_archive1": "Liste des catégories soumis au nettoyage",
"c_archive2": "`L1`, `L2`, `L3`, `M1`, `M2`",
"c_archive3": "Impossible de trouver/nettoyer le salon :",
"c_archive4": "Liste des salons archivés de la catégorie",
"c_archive5": "vers",
"c_archive6": "Nettoyage",
"c_archive7": "Catégorie déjà nettoyée",
"c_prep_name": "Préparation",
"c_prep_desc": "Préparation des salons généraux pour la nouvelle année",
"c_prep_opt1_name": "année",
"c_prep_opt1_desc": "Nom de l'année à préparer",
"c_prep1": "Liste des catégories soumis à la préparation",
"c_prep2": "`L1`, `L2`, `L3`, `M1`, `M2`",
"c_prep3": "Impossible de trouver/nettoyer le salon :",
"c_prep4": "Listes des Salons préparés `",
"c_prep5": "créé",
"c_prep6": "Pas besoin de préparation",
"u_time_at": "à", "u_time_at": "à",
"c_reminder_name": "rappel", "c_reminder_name": "rappel",

View file

@ -4,7 +4,7 @@ declare global {
// Declarations // Declarations
interface String { interface String {
/** /**
* Returns a copy of the string with the first letter capitalized * Returns a copy of the string with the first letter capitalized.
*/ */
capitalize(): string; capitalize(): string;
} }

View file

@ -6,10 +6,9 @@ import "../modules/client";
import { loadLocales } from "./locales"; import { loadLocales } from "./locales";
import { YoutubeiExtractor } from "discord-player-youtubei"; import { YoutubeiExtractor } from "discord-player-youtubei";
/** Creation of the client and definition of its properties */ /** Creation of the client and definition of its properties. */
export default async () => { export default async () => {
const client: Client = new Client({ const client: Client = new Client({
shards: "auto",
intents: [ intents: [
GatewayIntentBits.Guilds, GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages, GatewayIntentBits.GuildMessages,

View file

@ -3,7 +3,7 @@ import { readdir } from "fs/promises";
import { removeExtension } from "./misc"; import { removeExtension } from "./misc";
/** /**
* Load the localizations files into memory * Load the localizations files into memory.
* *
* Show percentage of translations. * Show percentage of translations.
* @param default_lang default lang * @param default_lang default lang
@ -47,7 +47,7 @@ export const loadLocales = async (default_lang: string) => {
/** /**
* Builds a dictionary, if a translation is not available, * Builds a dictionary, if a translation is not available,
* we fallback to default lang * we fallback to default lang.
* @param client Client * @param client Client
* @param text Name of string to fetch * @param text Name of string to fetch
* @param lowercase Should the output be lowercased? * @param lowercase Should the output be lowercased?
@ -76,7 +76,7 @@ export const getLocalizations = (client: Client, text: string, lowercase = false
/** /**
* Return the locale data for a lang, * Return the locale data for a lang,
* fallback to default language when a string isn't available * fallback to default language when a string isn't available.
* @param client Client * @param client Client
* @param lang Lang to fetch * @param lang Lang to fetch
* @returns the map with the desired languaged clogged with the default one * @returns the map with the desired languaged clogged with the default one
@ -101,10 +101,10 @@ export const getLocale = (client: Client, lang: string) => {
}; };
/** /**
* Show percentage of translation progression * Show percentage of translation progression.
* *
* Raise an error if the default lang isn't * Raise an error if the default lang isn't
* the lang with most text * the lang with most text.
* @param locales Locales loaded * @param locales Locales loaded
* @param default_lang default lang * @param default_lang default lang
* @returns void * @returns void

View file

@ -1,7 +1,7 @@
import { GuildMember } from "discord.js"; import { GuildMember } from "discord.js";
/** /**
* Log module status * Log module status.
* @param {string} name Module name * @param {string} name Module name
* @param {boolean} status Module status * @param {boolean} status Module status
* @returns String * @returns String
@ -12,7 +12,7 @@ export const logStart = (name: string, status: boolean) => {
}; };
/** /**
* Filename without path and extension * Filename without path and extension.
* @param path __filename * @param path __filename
* @returns string * @returns string
*/ */
@ -29,7 +29,7 @@ export const getFilename = (path: string) => {
}; };
/** /**
* Remove extension from a filename * Remove extension from a filename.
* @param filename string of the filename with an extension * @param filename string of the filename with an extension
* @returns string of the filename without an extension * @returns string of the filename without an extension
*/ */
@ -41,7 +41,7 @@ export const removeExtension = (filename: string) => {
}; };
/** /**
* Get extension from a filename * Get extension from a filename.
* @param filename string of the filename * @param filename string of the filename
* @returns string of the extension if it exists * @returns string of the extension if it exists
*/ */
@ -52,7 +52,7 @@ export const getExtension = (filename: string) => {
}; };
/** /**
* Define if a media is a media based on file extension * Define if a media is a media based on file extension.
* @param filename string of the filename * @param filename string of the filename
* @returns true is file is a media * @returns true is file is a media
*/ */
@ -61,7 +61,7 @@ export const isImage = (filename: string) => {
}; };
/** /**
* String with pseudo and nickname if available * String with pseudo and nickname if available.
* @param member Member * @param member Member
* @returns string * @returns string
*/ */

View file

@ -1,4 +1,4 @@
import { Client, Colors, EmbedBuilder, User } from "discord.js"; import { ChannelType, Client, Colors, EmbedBuilder, User } from "discord.js";
import { getLocale } from "./locales"; import { getLocale } from "./locales";
import { cleanCodeBlock } from "./misc"; import { cleanCodeBlock } from "./misc";
import { showDate, strToSeconds, timeDeltaToString } from "./time"; import { showDate, strToSeconds, timeDeltaToString } from "./time";
@ -168,8 +168,8 @@ export const sendReminder = (client: Client, info: infoReminder, option: OptionR
} }
} else { } else {
// Channel // Channel
client.channels.fetch(info.channelId!).then((channel) => { client.channels.fetch(info.channelId ?? "").then((channel) => {
if (channel?.isSendable()) { if (channel?.isTextBased() && channel.type !== ChannelType.GroupDM) {
let content = `<@${info.userId}>`; let content = `<@${info.userId}>`;
embed.setFooter({ embed.setFooter({
text: `${loc.get("c_reminder17")} ${timeDeltaToString(info.createdAt)}`, text: `${loc.get("c_reminder17")} ${timeDeltaToString(info.createdAt)}`,

View file

@ -1,5 +1,5 @@
/** /**
* Parsed string adapted with TZ (locales) and format for the specified lang * Parsed string adapted with TZ (locales) and format for the specified lang.
* @param tz Lang * @param tz Lang
* @param locale Locales * @param locale Locales
* @param date Date * @param date Date