feat: update Copilot instructions for Discord.js 15.0.0-dev and enhance validation steps
This commit is contained in:
51
.github/copilot-instructions.md
vendored
51
.github/copilot-instructions.md
vendored
@@ -1,31 +1,38 @@
|
||||
# Custom instructions for GitHub Copilot
|
||||
# Custom instructions for GitHub Copilot (discord.js 15.0.0-dev)
|
||||
|
||||
Whenever generating code, commit messages, or explanations related to Discord.js or the Discord API:
|
||||
When generating or modifying code for Discord.js version `15.0.0-dev.1759363313-f510b5ffa`:
|
||||
|
||||
1. Always **consult and reference** the following sources for accurate and up-to-date information:
|
||||
1. **Primary Source of Truth**
|
||||
- Do not assume the official docs, guide, or GitHub repositories are fully up-to-date.
|
||||
- Always prioritize the installed package in `node_modules/discord.js` as the most reliable source.
|
||||
- Always cross-reference with the provided file `example.ts.txt` to understand new or experimental APIs.
|
||||
|
||||
2. **Secondary Sources**
|
||||
- Only use these as references when the information is still valid:
|
||||
- [Discord.js Guide](https://discordjs.guide)
|
||||
- [discord.js GitHub Repository](https://github.com/discordjs/discord.js)
|
||||
- [Discord API Types GitHub Repository](https://github.com/discordjs/discord-api-types)
|
||||
- [discord.js GitHub](https://github.com/discordjs/discord.js)
|
||||
- [Discord API Types GitHub](https://github.com/discordjs/discord-api-types)
|
||||
- [Discord Developer Documentation](https://discord.com/developers/docs/intro)
|
||||
- Mark clearly if the information is outdated compared to the development version.
|
||||
|
||||
2. Always **prefer official documentation** over blogs, forums, or tutorials.
|
||||
- If no clear answer is found in docs, **inspect the installed dependency in `node_modules`** to confirm if a method, property, or class truly exists.
|
||||
3. **Code Analysis**
|
||||
- Inspect the type definitions and source files inside `node_modules/discord.js` before suggesting new methods or classes.
|
||||
- If `example.ts.txt` shows usage not covered in documentation, assume that is the intended API for this development version.
|
||||
|
||||
3. When suggesting code, ensure it matches the **latest stable release of Discord.js and related packages (June 2025 or newer)**.
|
||||
- If examples belong to an older version, adapt them to the most recent stable release.
|
||||
- If uncertain, indicate that verification against the `node_modules` implementation is required.
|
||||
|
||||
4. When installing or suggesting npm packages related to Discord.js:
|
||||
- Verify against their **GitHub repository** for recent updates, breaking changes, or migration notes.
|
||||
- Always check if the changelog or releases page contains updates after **June 2025** and adjust suggestions accordingly.
|
||||
|
||||
5. Always provide **links to relevant official documentation** (Discord.js Guide, GitHub repos, or Discord Developer Docs).
|
||||
- If the info is missing in docs, but exists in the actual installed package, explain that and provide the discovered usage.
|
||||
|
||||
6. **Error validation requirement:**
|
||||
- After generating or modifying code, always remind the user to check for TypeScript errors by running:
|
||||
4. **Validation**
|
||||
- Always suggest running:
|
||||
```bash
|
||||
npx tsc --noEmit
|
||||
```
|
||||
(or equivalent `tsc` command).
|
||||
- If type errors are found, propose fixes before finalizing the solution.
|
||||
to validate typings.
|
||||
- Remind to check runtime memory and CPU usage with:
|
||||
```js
|
||||
console.log(process.memoryUsage());
|
||||
```
|
||||
and external profilers if needed.
|
||||
|
||||
5. **Communication**
|
||||
- When suggesting code, state explicitly whether it comes from:
|
||||
- `node_modules` (preferred, authoritative)
|
||||
- `example.ts.txt` (author-provided experimental reference)
|
||||
- official docs (secondary, possibly outdated)
|
||||
|
||||
11
.github/prompts/discord.js-v15-dev.prompt.md
vendored
Normal file
11
.github/prompts/discord.js-v15-dev.prompt.md
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
# Prompt: Discord.js 15 Development Mode
|
||||
|
||||
When assisting with Discord.js version `15.0.0-dev.1759363313-f510b5ffa`:
|
||||
|
||||
- Treat the installed code in `node_modules/discord.js` as the primary and most reliable reference.
|
||||
- Always analyze the file `example.ts.txt` to extract API patterns, since it reflects the intended usage of this dev version.
|
||||
- Do not rely blindly on official docs or the guide; use them only to compare and note differences with the dev version.
|
||||
- Highlight when functionality has changed from v14 to v15, based on observed code and `example.ts.txt`.
|
||||
- Encourage verification by:
|
||||
```bash
|
||||
npx tsc --noEmit
|
||||
28
.github/prompts/error-strict.prompt.md
vendored
Normal file
28
.github/prompts/error-strict.prompt.md
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
# Prompt: TypeScript Strict Error Resolver
|
||||
|
||||
Whenever Copilot generates or modifies code:
|
||||
|
||||
1. **Never ignore compiler errors** like `TS2339`, `TS2345`, or similar.
|
||||
- Always explain what the error means in plain language.
|
||||
- Always suggest at least one concrete fix.
|
||||
|
||||
2. **For missing properties or methods (e.g. `TS2339`)**:
|
||||
- Check if the method exists in the installed `node_modules`.
|
||||
- If it doesn’t exist, assume the API changed in `discord.js@15-dev`.
|
||||
- Propose alternatives based on actual available methods (`example.ts.txt` must be consulted).
|
||||
|
||||
3. **For type mismatches (e.g. `TS2345`)**:
|
||||
- Suggest code changes that handle `null`/`undefined` safely.
|
||||
- Show how to cast or coerce types **without breaking strict typing**.
|
||||
|
||||
4. **Validation step**:
|
||||
- Always remind to rerun:
|
||||
```bash
|
||||
npx tsc --noEmit
|
||||
```
|
||||
until the project compiles cleanly.
|
||||
- Do not consider the task “done” if compiler errors remain.
|
||||
|
||||
5. **Explicitness**:
|
||||
- Always specify: “This code suggestion resolves TS2339 / TS2345.”
|
||||
- Never produce a code snippet that still triggers the same error.
|
||||
205
package-lock.json
generated
205
package-lock.json
generated
@@ -15,7 +15,7 @@
|
||||
"appwrite": "20.1.0",
|
||||
"chrono-node": "2.9.0",
|
||||
"discord-api-types": "0.38.24",
|
||||
"discord.js": "14.22.1",
|
||||
"discord.js": "15.0.0-dev.1759363313-f510b5ffa",
|
||||
"node-appwrite": "19.1.0",
|
||||
"pino": "9.13.0",
|
||||
"prisma": "6.16.2",
|
||||
@@ -41,127 +41,117 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/builders": {
|
||||
"version": "1.11.3",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-1.11.3.tgz",
|
||||
"integrity": "sha512-p3kf5eV49CJiRTfhtutUCeivSyQ/l2JlKodW1ZquRwwvlOWmG9+6jFShX6x8rUiYhnP6wKI96rgN/SXMy5e5aw==",
|
||||
"version": "2.0.0-dev.1759363313-f510b5ffa",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-2.0.0-dev.1759363313-f510b5ffa.tgz",
|
||||
"integrity": "sha512-MORqSl+/RtNHavjgRA4GqYdE4URoFL4J52vu0OCV3UNhQmCj/WQTL/FQHxeGSaPfkDdYNOmwnUn4XEA6dZhc5Q==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@discordjs/formatters": "^0.6.1",
|
||||
"@discordjs/util": "^1.1.1",
|
||||
"@sapphire/shapeshift": "^4.0.0",
|
||||
"discord-api-types": "^0.38.16",
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
"@discordjs/util": "^2.0.0-dev.1759363313-f510b5ffa",
|
||||
"discord-api-types": "^0.38.23",
|
||||
"ts-mixer": "^6.0.4",
|
||||
"tslib": "^2.6.3"
|
||||
"tslib": "^2.8.1",
|
||||
"zod": "^4.0.17"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.11.0"
|
||||
"node": ">=22.12.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/discordjs/discord.js?sponsor"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/collection": {
|
||||
"version": "1.5.3",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-1.5.3.tgz",
|
||||
"integrity": "sha512-SVb428OMd3WO1paV3rm6tSjM4wC+Kecaa1EUGX7vc6/fddvw/6lg90z4QtCqm21zvVe92vMMDt9+DkIvjXImQQ==",
|
||||
"version": "3.0.0-dev.1759363313-f510b5ffa",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-3.0.0-dev.1759363313-f510b5ffa.tgz",
|
||||
"integrity": "sha512-qEeT3PdItXKrZgr3Mx4+Glp2gPylguxAFKFFICe/YIs6RqW7ln5fh+5mW11ekPyhdsE4EZdOY3vP03SuQwC1VQ==",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=16.11.0"
|
||||
"node": ">=22.12.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/discordjs/discord.js?sponsor"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/formatters": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/formatters/-/formatters-0.6.1.tgz",
|
||||
"integrity": "sha512-5cnX+tASiPCqCWtFcFslxBVUaCetB0thvM/JyavhbXInP1HJIEU+Qv/zMrnuwSsX3yWH2lVXNJZeDK3EiP4HHg==",
|
||||
"version": "1.0.0-dev.1759363313-f510b5ffa",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/formatters/-/formatters-1.0.0-dev.1759363313-f510b5ffa.tgz",
|
||||
"integrity": "sha512-94/RDfYgdHRc1JOaMg687O5h53v4FdnJAG8fuRPpkOqZgTLtLSsnfGRUEKqwSr5dtyTOPIO3quTP23B2ImIjpA==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"discord-api-types": "^0.38.1"
|
||||
"discord-api-types": "^0.38.23"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.11.0"
|
||||
"node": ">=22.12.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/discordjs/discord.js?sponsor"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/rest": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/rest/-/rest-2.6.0.tgz",
|
||||
"integrity": "sha512-RDYrhmpB7mTvmCKcpj+pc5k7POKszS4E2O9TYc+U+Y4iaCP+r910QdO43qmpOja8LRr1RJ0b3U+CqVsnPqzf4w==",
|
||||
"version": "3.0.0-dev.1759363313-f510b5ffa",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/rest/-/rest-3.0.0-dev.1759363313-f510b5ffa.tgz",
|
||||
"integrity": "sha512-4LCncMfpZwtPG68Lv36th7WvwDZeTs0zok6AKNXt0Hp6E5CZ76bw92hACJmfergtPsD5/Ds75O9Fh0xptd2B1w==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@discordjs/collection": "^2.1.1",
|
||||
"@discordjs/util": "^1.1.1",
|
||||
"@sapphire/async-queue": "^1.5.3",
|
||||
"@sapphire/snowflake": "^3.5.3",
|
||||
"@discordjs/collection": "^3.0.0-dev.1759363313-f510b5ffa",
|
||||
"@discordjs/util": "^2.0.0-dev.1759363313-f510b5ffa",
|
||||
"@sapphire/async-queue": "^1.5.5",
|
||||
"@sapphire/snowflake": "^3.5.5",
|
||||
"@vladfrangu/async_event_emitter": "^2.4.6",
|
||||
"discord-api-types": "^0.38.16",
|
||||
"magic-bytes.js": "^1.10.0",
|
||||
"tslib": "^2.6.3",
|
||||
"undici": "6.21.3"
|
||||
"discord-api-types": "^0.38.23",
|
||||
"magic-bytes.js": "^1.12.1",
|
||||
"tslib": "^2.8.1",
|
||||
"undici": "7.11.0",
|
||||
"uuid": "^11.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
"node": ">=22.12.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/discordjs/discord.js?sponsor"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/rest/node_modules/@discordjs/collection": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-2.1.1.tgz",
|
||||
"integrity": "sha512-LiSusze9Tc7qF03sLCujF5iZp7K+vRNEDBZ86FT9aQAv3vxMLihUvKvpsCWiQ2DJq1tVckopKm1rxomgNUc9hg==",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/discordjs/discord.js?sponsor"
|
||||
"node_modules/@discordjs/rest/node_modules/uuid": {
|
||||
"version": "11.1.0",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz",
|
||||
"integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==",
|
||||
"funding": [
|
||||
"https://github.com/sponsors/broofa",
|
||||
"https://github.com/sponsors/ctavan"
|
||||
],
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"uuid": "dist/esm/bin/uuid"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/util": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/util/-/util-1.1.1.tgz",
|
||||
"integrity": "sha512-eddz6UnOBEB1oITPinyrB2Pttej49M9FZQY8NxgEvc3tq6ZICZ19m70RsmzRdDHk80O9NoYN/25AqJl8vPVf/g==",
|
||||
"version": "2.0.0-dev.1759363313-f510b5ffa",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/util/-/util-2.0.0-dev.1759363313-f510b5ffa.tgz",
|
||||
"integrity": "sha512-84PwcSH7ZQnsMluBr43IfoCbhPN1V18nH2FOzm6+JdUPKeh0peStaRljSwiTRRFDcdY5CufcNvde/5kksH0kJA==",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
"node": ">=22.12.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/discordjs/discord.js?sponsor"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/ws": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/ws/-/ws-1.2.3.tgz",
|
||||
"integrity": "sha512-wPlQDxEmlDg5IxhJPuxXr3Vy9AjYq5xCvFWGJyD7w7Np8ZGu+Mc+97LCoEc/+AYCo2IDpKioiH0/c/mj5ZR9Uw==",
|
||||
"version": "3.0.0-dev.1759363313-f510b5ffa",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/ws/-/ws-3.0.0-dev.1759363313-f510b5ffa.tgz",
|
||||
"integrity": "sha512-/FZX2LaPkTt3E8KAWB7dJ6uGRFmbtGPdgZ3a/hunePznXDU9syTbWoA4Vh6PNbJN09VKJxW3ihSxgLM/P87KkA==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@discordjs/collection": "^2.1.0",
|
||||
"@discordjs/rest": "^2.5.1",
|
||||
"@discordjs/util": "^1.1.0",
|
||||
"@sapphire/async-queue": "^1.5.2",
|
||||
"@types/ws": "^8.5.10",
|
||||
"@vladfrangu/async_event_emitter": "^2.2.4",
|
||||
"discord-api-types": "^0.38.1",
|
||||
"tslib": "^2.6.2",
|
||||
"ws": "^8.17.0"
|
||||
"@discordjs/collection": "^3.0.0-dev.1759363313-f510b5ffa",
|
||||
"@discordjs/util": "^2.0.0-dev.1759363313-f510b5ffa",
|
||||
"@sapphire/async-queue": "^1.5.5",
|
||||
"@types/ws": "^8.18.1",
|
||||
"@vladfrangu/async_event_emitter": "^2.4.6",
|
||||
"discord-api-types": "^0.38.23",
|
||||
"tslib": "^2.8.1",
|
||||
"ws": "^8.18.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.11.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/discordjs/discord.js?sponsor"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/ws/node_modules/@discordjs/collection": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-2.1.1.tgz",
|
||||
"integrity": "sha512-LiSusze9Tc7qF03sLCujF5iZp7K+vRNEDBZ86FT9aQAv3vxMLihUvKvpsCWiQ2DJq1tVckopKm1rxomgNUc9hg==",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
"node": ">=22.12.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/discordjs/discord.js?sponsor"
|
||||
@@ -374,23 +364,10 @@
|
||||
"npm": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@sapphire/shapeshift": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-4.0.0.tgz",
|
||||
"integrity": "sha512-d9dUmWVA7MMiKobL3VpLF8P2aeanRTu6ypG2OIaEv/ZHH/SUQ2iHOVyi5wAPjQ+HmnMuL0whK9ez8I/raWbtIg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
"lodash": "^4.17.21"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=v16"
|
||||
}
|
||||
},
|
||||
"node_modules/@sapphire/snowflake": {
|
||||
"version": "3.5.3",
|
||||
"resolved": "https://registry.npmjs.org/@sapphire/snowflake/-/snowflake-3.5.3.tgz",
|
||||
"integrity": "sha512-jjmJywLAFoWeBi1W7994zZyiNWPIiqRRNAmSERxyg93xRGzNYvGjlZ0gR6x0F4gPRi2+0O6S71kOZYyr3cxaIQ==",
|
||||
"version": "3.5.5",
|
||||
"resolved": "https://registry.npmjs.org/@sapphire/snowflake/-/snowflake-3.5.5.tgz",
|
||||
"integrity": "sha512-xzvBr1Q1c4lCe7i6sRnrofxeO1QTP/LKQ6A6qy0iB4x5yfiSfARMEQEghojzTNALDTcv8En04qYNIco9/K9eZQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=v14.0.0",
|
||||
@@ -701,27 +678,28 @@
|
||||
]
|
||||
},
|
||||
"node_modules/discord.js": {
|
||||
"version": "14.22.1",
|
||||
"resolved": "https://registry.npmjs.org/discord.js/-/discord.js-14.22.1.tgz",
|
||||
"integrity": "sha512-3k+Kisd/v570Jr68A1kNs7qVhNehDwDJAPe4DZ2Syt+/zobf9zEcuYFvsfIaAOgCa0BiHMfOOKQY4eYINl0z7w==",
|
||||
"version": "15.0.0-dev.1759363313-f510b5ffa",
|
||||
"resolved": "https://registry.npmjs.org/discord.js/-/discord.js-15.0.0-dev.1759363313-f510b5ffa.tgz",
|
||||
"integrity": "sha512-SfnkqY+pzYiEugGKUuhIFgn1PbX2Tn0KntwDR3ggAzZRBZKgByrg2gqCpNb05VeNGUjC7m75gctKLZwSSXbB6A==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@discordjs/builders": "^1.11.2",
|
||||
"@discordjs/collection": "1.5.3",
|
||||
"@discordjs/formatters": "^0.6.1",
|
||||
"@discordjs/rest": "^2.6.0",
|
||||
"@discordjs/util": "^1.1.1",
|
||||
"@discordjs/ws": "^1.2.3",
|
||||
"@sapphire/snowflake": "3.5.3",
|
||||
"discord-api-types": "^0.38.16",
|
||||
"@discordjs/builders": "^2.0.0-dev.1759363313-f510b5ffa",
|
||||
"@discordjs/collection": "^3.0.0-dev.1759363313-f510b5ffa",
|
||||
"@discordjs/formatters": "^1.0.0-dev.1759363313-f510b5ffa",
|
||||
"@discordjs/rest": "^3.0.0-dev.1759363313-f510b5ffa",
|
||||
"@discordjs/util": "^2.0.0-dev.1759363313-f510b5ffa",
|
||||
"@discordjs/ws": "^3.0.0-dev.1759363313-f510b5ffa",
|
||||
"@sapphire/snowflake": "3.5.5",
|
||||
"@vladfrangu/async_event_emitter": "^2.4.6",
|
||||
"discord-api-types": "^0.38.23",
|
||||
"fast-deep-equal": "3.1.3",
|
||||
"lodash.snakecase": "4.1.1",
|
||||
"magic-bytes.js": "^1.10.0",
|
||||
"tslib": "^2.6.3",
|
||||
"undici": "6.21.3"
|
||||
"magic-bytes.js": "^1.12.1",
|
||||
"tslib": "^2.8.1",
|
||||
"undici": "7.11.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
"node": ">=22.12.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/discordjs/discord.js?sponsor"
|
||||
@@ -957,12 +935,6 @@
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/lodash": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.snakecase": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz",
|
||||
@@ -1379,12 +1351,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/undici": {
|
||||
"version": "6.21.3",
|
||||
"resolved": "https://registry.npmjs.org/undici/-/undici-6.21.3.tgz",
|
||||
"integrity": "sha512-gBLkYIlEnSp8pFbT64yFgGE6UIB9tAkhukC23PmMDCe5Nd+cRqKxSjw5y54MK2AZMgZfJWMaNE4nYUHgi1XEOw==",
|
||||
"version": "7.11.0",
|
||||
"resolved": "https://registry.npmjs.org/undici/-/undici-7.11.0.tgz",
|
||||
"integrity": "sha512-heTSIac3iLhsmZhUCjyS3JQEkZELateufzZuBaVM5RHXdSBMb1LPMQf5x+FH7qjsZYDP0ttAc3nnVpUB+wYbOg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18.17"
|
||||
"node": ">=20.18.1"
|
||||
}
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
@@ -1459,6 +1431,15 @@
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/zod": {
|
||||
"version": "4.1.11",
|
||||
"resolved": "https://registry.npmjs.org/zod/-/zod-4.1.11.tgz",
|
||||
"integrity": "sha512-WPsqwxITS2tzx1bzhIKsEs19ABD5vmCVa4xBo2tq/SrV4RNZtfws1EnCWQXM6yh8bD08a1idvkB5MZSBiZsjwg==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/colinhacks"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { CommandMessage } from "../../../core/types/commands";
|
||||
import { CommandMessage } from "../core/types/commands";
|
||||
// @ts-ignore
|
||||
import { EmbedBuilder, ButtonStyle, MessageFlags, ChannelType } from "discord.js";
|
||||
|
||||
392
src/commands/messages/alliaces/listChannelsV2.ts
Normal file
392
src/commands/messages/alliaces/listChannelsV2.ts
Normal file
@@ -0,0 +1,392 @@
|
||||
import { CommandMessage } from "../../../core/types/commands";
|
||||
import type { Message } from "discord.js";
|
||||
import { PermissionFlagsBits } from "discord.js";
|
||||
|
||||
function codeBlock(lines: string[]): string {
|
||||
return [
|
||||
'```',
|
||||
...lines,
|
||||
'```'
|
||||
].join('\n');
|
||||
}
|
||||
|
||||
async function buildChannelListPanel(message: Message) {
|
||||
const guild = message.guild!;
|
||||
const guildId = guild.id;
|
||||
const client = message.client as any;
|
||||
|
||||
// Obtener canales configurados existentes con estadísticas
|
||||
const existingChannels = await client.prisma.allianceChannel.findMany({
|
||||
where: { guildId },
|
||||
include: {
|
||||
_count: {
|
||||
select: {
|
||||
pointsHistory: true
|
||||
}
|
||||
}
|
||||
},
|
||||
orderBy: {
|
||||
createdAt: 'desc'
|
||||
}
|
||||
});
|
||||
|
||||
// Obtener estadísticas generales
|
||||
const totalPointsHistory = await client.prisma.pointHistory.count({
|
||||
where: { guildId }
|
||||
});
|
||||
|
||||
const availableBlocks = await client.prisma.blockV2Config.count({
|
||||
where: { guildId }
|
||||
});
|
||||
|
||||
if (existingChannels.length === 0) {
|
||||
// Panel cuando no hay canales configurados
|
||||
const panel = {
|
||||
type: 17,
|
||||
accent_color: 0x36393f,
|
||||
components: [
|
||||
{ type: 10, content: '## 📋 Canales de Alianza Configurados' },
|
||||
{ type: 10, content: '-# Lista de canales configurados para alianzas.' },
|
||||
{ type: 14, divider: true, spacing: 1 },
|
||||
|
||||
{ type: 10, content: '### 🗂️ Lista vacía' },
|
||||
{ type: 10, content: '📭 **No hay canales configurados** para alianzas en este servidor.' },
|
||||
|
||||
{ type: 14, divider: false, spacing: 1 },
|
||||
{ type: 10, content: '### 🚀 ¿Quieres empezar?' },
|
||||
{ type: 10, content: '• Usa `!setchannel-alliance` para configurar tu primer canal' },
|
||||
{ type: 10, content: '• Crea bloques con `!blockcreate <nombre>`' },
|
||||
|
||||
{ type: 14, divider: true, spacing: 1 },
|
||||
{ type: 10, content: '### 📊 Estadísticas Generales' },
|
||||
{ type: 10, content: `🧩 **Bloques disponibles:** ${availableBlocks}` },
|
||||
{ type: 10, content: `📈 **Puntos totales otorgados:** ${totalPointsHistory}` },
|
||||
|
||||
{ type: 14, divider: false, spacing: 1 },
|
||||
{ type: 10, content: `📅 ${new Date().toLocaleDateString('es-ES', {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric'
|
||||
})}` },
|
||||
|
||||
{ type: 14, divider: false, spacing: 1 },
|
||||
{
|
||||
type: 1,
|
||||
components: [
|
||||
{
|
||||
type: 2,
|
||||
style: 3,
|
||||
label: "Configurar Canal",
|
||||
custom_id: "setup_first_channel",
|
||||
emoji: { name: "🔧" }
|
||||
},
|
||||
{
|
||||
type: 2,
|
||||
style: 2,
|
||||
label: "Ayuda",
|
||||
custom_id: "show_setup_help",
|
||||
emoji: { name: "📖" }
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
return { panel, channelDetails: null, totalPointsHistory };
|
||||
}
|
||||
|
||||
// Crear descripción detallada de canales
|
||||
const channelDetails = await Promise.all(
|
||||
existingChannels.map(async (config: any, index: number) => {
|
||||
const channel = guild.channels.cache.get(config.channelId);
|
||||
const channelName = channel ? `#${channel.name}` : "❌ *Canal Eliminado*";
|
||||
const status = config.isActive ? "🟢 **Activo**" : "🔴 **Inactivo**";
|
||||
const pointsCount = config._count.pointsHistory;
|
||||
|
||||
// Obtener información del bloque
|
||||
const blockInfo = await client.prisma.blockV2Config.findFirst({
|
||||
where: {
|
||||
guildId,
|
||||
name: config.blockConfigName
|
||||
},
|
||||
select: { name: true, id: true }
|
||||
});
|
||||
|
||||
const blockStatus = blockInfo ? "✅ Válido" : "⚠️ Bloque Eliminado";
|
||||
|
||||
const createdDate = new Date(config.createdAt).toLocaleDateString('es-ES', {
|
||||
day: '2-digit',
|
||||
month: '2-digit',
|
||||
year: 'numeric'
|
||||
});
|
||||
|
||||
return {
|
||||
index: index + 1,
|
||||
channelName,
|
||||
status,
|
||||
pointsCount,
|
||||
blockName: config.blockConfigName,
|
||||
blockStatus,
|
||||
createdDate,
|
||||
isValid: !!channel && !!blockInfo
|
||||
};
|
||||
})
|
||||
);
|
||||
|
||||
// Agrupar por estado
|
||||
const activeChannels = channelDetails.filter(c => c.status.includes("Activo"));
|
||||
const inactiveChannels = channelDetails.filter(c => c.status.includes("Inactivo"));
|
||||
|
||||
// Construir lista de canales activos
|
||||
const activeList = activeChannels.length > 0
|
||||
? activeChannels.slice(0, 10).map(c =>
|
||||
`${c.index}. ${c.channelName} - ${c.blockName} (${c.pointsCount} pts)`
|
||||
)
|
||||
: ['Ninguno'];
|
||||
|
||||
// Construir lista de canales inactivos
|
||||
const inactiveList = inactiveChannels.length > 0
|
||||
? inactiveChannels.slice(0, 5).map(c =>
|
||||
`${c.index}. ${c.channelName} - ${c.blockName}`
|
||||
)
|
||||
: [];
|
||||
|
||||
// Obtener canales más activos para estadísticas
|
||||
const topChannels = channelDetails
|
||||
.sort((a, b) => b.pointsCount - a.pointsCount)
|
||||
.slice(0, 3)
|
||||
.map((c, i) => `${i + 1}. ${c.channelName.replace(/[#❌*]/g, '').trim()}`)
|
||||
.join(', ') || 'N/A';
|
||||
|
||||
const now = new Date();
|
||||
const ts = now.toLocaleDateString('es-ES');
|
||||
|
||||
// Crear el panel con components V2
|
||||
const components: any[] = [
|
||||
{ type: 10, content: '## 📋 Canales de Alianza Configurados' },
|
||||
{ type: 10, content: `-# ${existingChannels.length} canal(es) configurado(s) • 🟢 Activos: ${activeChannels.length} • 🔴 Inactivos: ${inactiveChannels.length}` },
|
||||
{ type: 14, divider: true, spacing: 1 }
|
||||
];
|
||||
|
||||
// Añadir canales activos
|
||||
if (activeChannels.length > 0) {
|
||||
components.push(
|
||||
{ type: 10, content: `### 🟢 Canales Activos (${activeChannels.length})` },
|
||||
{ type: 10, content: codeBlock(activeList) }
|
||||
);
|
||||
}
|
||||
|
||||
// Añadir canales inactivos si los hay
|
||||
if (inactiveChannels.length > 0) {
|
||||
components.push(
|
||||
{ type: 14, divider: false, spacing: 1 },
|
||||
{ type: 10, content: `### 🔴 Canales Inactivos (${inactiveChannels.length})` },
|
||||
{ type: 10, content: codeBlock(inactiveList) }
|
||||
);
|
||||
}
|
||||
|
||||
// Añadir estadísticas
|
||||
components.push(
|
||||
{ type: 14, divider: true, spacing: 1 },
|
||||
{ type: 10, content: '### 📊 Estadísticas del Servidor' },
|
||||
{ type: 10, content: `🧩 **Bloques disponibles:** ${availableBlocks}` },
|
||||
{ type: 10, content: `📈 **Total puntos otorgados:** ${totalPointsHistory}` },
|
||||
{ type: 10, content: `⚡ **Canales más activos:** ${topChannels}` },
|
||||
{ type: 14, divider: false, spacing: 1 },
|
||||
{ type: 10, content: `📅 Actualizado: ${ts}` }
|
||||
);
|
||||
|
||||
// Añadir botones
|
||||
components.push(
|
||||
{ type: 14, divider: false, spacing: 1 },
|
||||
{
|
||||
type: 1,
|
||||
components: [
|
||||
{
|
||||
type: 2,
|
||||
style: 3,
|
||||
label: "Añadir Canal",
|
||||
custom_id: "add_channel",
|
||||
emoji: { name: "➕" }
|
||||
},
|
||||
{
|
||||
type: 2,
|
||||
style: 4,
|
||||
label: "Eliminar Canal",
|
||||
custom_id: "remove_channel",
|
||||
emoji: { name: "🗑️" }
|
||||
},
|
||||
{
|
||||
type: 2,
|
||||
style: 1,
|
||||
label: "Actualizar",
|
||||
custom_id: "refresh_list",
|
||||
emoji: { name: "🔄" }
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
type: 1,
|
||||
components: [
|
||||
{
|
||||
type: 2,
|
||||
style: 2,
|
||||
label: "Estadísticas",
|
||||
custom_id: "show_stats",
|
||||
emoji: { name: "📊" }
|
||||
},
|
||||
{
|
||||
type: 2,
|
||||
style: 2,
|
||||
label: "Ver Bloques",
|
||||
custom_id: "show_blocks",
|
||||
emoji: { name: "🧩" }
|
||||
},
|
||||
{
|
||||
type: 2,
|
||||
style: 2,
|
||||
label: "Ayuda",
|
||||
custom_id: "show_help",
|
||||
emoji: { name: "❓" }
|
||||
}
|
||||
]
|
||||
}
|
||||
);
|
||||
|
||||
const panel = {
|
||||
type: 17,
|
||||
accent_color: 0x5865f2,
|
||||
components
|
||||
};
|
||||
|
||||
return { panel, channelDetails, totalPointsHistory };
|
||||
}
|
||||
|
||||
export const command: CommandMessage = {
|
||||
name: "listar-canales-alianza-v2",
|
||||
type: "message",
|
||||
aliases: ["listchannels-alliance-v2", "listalchannel-v2", "channelsally-v2", "alliancechannels-v2"],
|
||||
cooldown: 5,
|
||||
description: "Lista todos los canales configurados para alianzas (versión V2 con components)",
|
||||
category: "Alianzas",
|
||||
usage: "listar-canales-alianza-v2",
|
||||
run: async (message) => {
|
||||
if (!message.guild) {
|
||||
await message.reply({ content: '❌ Este comando solo puede usarse en servidores.' });
|
||||
return;
|
||||
}
|
||||
|
||||
const client = message.client as any;
|
||||
const guildId = message.guild.id;
|
||||
|
||||
try {
|
||||
const result = await buildChannelListPanel(message);
|
||||
|
||||
const response = await message.reply({
|
||||
// @ts-ignore Flag de componentes V2
|
||||
flags: 32768,
|
||||
components: [result.panel]
|
||||
});
|
||||
|
||||
// Solo crear collector si hay canales o para el caso vacío
|
||||
const collector = response.createMessageComponentCollector({
|
||||
time: 600000, // 10 minutos
|
||||
filter: (i) => i.user.id === message.author.id
|
||||
});
|
||||
|
||||
collector.on("collect", async (interaction) => {
|
||||
try {
|
||||
switch (interaction.customId) {
|
||||
case "setup_first_channel":
|
||||
case "add_channel":
|
||||
await interaction.reply({
|
||||
content: "➕ **Añadir Canal**\n\nUsa el comando: `!setchannel-alliance`\n\nEste comando te guiará para configurar un nuevo canal de alianzas.",
|
||||
// @ts-ignore Flag efímero
|
||||
flags: 64
|
||||
});
|
||||
break;
|
||||
|
||||
case "remove_channel":
|
||||
await interaction.reply({
|
||||
content: "🗑️ **Eliminar Canal**\n\nUsa el comando: `!removechannel-alliance`\n\nEste comando te permitirá eliminar canales de la configuración de alianzas.",
|
||||
// @ts-ignore Flag efímero
|
||||
flags: 64
|
||||
});
|
||||
break;
|
||||
|
||||
case "refresh_list":
|
||||
await interaction.reply({
|
||||
content: "🔄 **Lista Actualizada**\n\nUsa el comando nuevamente: `!listchannels-alliance-v2`\n\nEsto mostrará la información más reciente.",
|
||||
// @ts-ignore Flag efímero
|
||||
flags: 64
|
||||
});
|
||||
break;
|
||||
|
||||
case "show_stats":
|
||||
if (result.channelDetails) {
|
||||
const detailedStats = result.channelDetails.map((c: any) =>
|
||||
`• ${c.channelName}: **${c.pointsCount}** puntos`
|
||||
).join('\n');
|
||||
|
||||
await interaction.reply({
|
||||
content: `📊 **Estadísticas Detalladas**\n\n**Puntos por Canal:**\n${detailedStats}\n\n**Total del Servidor:** ${result.totalPointsHistory} puntos`,
|
||||
// @ts-ignore Flag efímero
|
||||
flags: 64
|
||||
});
|
||||
} else {
|
||||
await interaction.reply({
|
||||
content: "📊 **Estadísticas**\n\nNo hay canales configurados aún para mostrar estadísticas.",
|
||||
// @ts-ignore Flag efímero
|
||||
flags: 64
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
||||
case "show_blocks":
|
||||
const blocksList = await client.prisma.blockV2Config.findMany({
|
||||
where: { guildId },
|
||||
select: { name: true, id: true }
|
||||
});
|
||||
|
||||
const blocksText = blocksList.length > 0
|
||||
? blocksList.map((block: any, i: number) => `${i + 1}. \`${block.name}\``).join('\n')
|
||||
: "No hay bloques configurados";
|
||||
|
||||
await interaction.reply({
|
||||
content: `🧩 **Bloques Disponibles (${blocksList.length})**\n\n${blocksText}\n\n💡 Crea bloques con: \`!blockcreate <nombre>\``,
|
||||
// @ts-ignore Flag efímero
|
||||
flags: 64
|
||||
});
|
||||
break;
|
||||
|
||||
case "show_setup_help":
|
||||
case "show_help":
|
||||
await interaction.reply({
|
||||
content: `📖 **Ayuda - Sistema de Alianzas**\n\n**Comandos principales:**\n• \`!setchannel-alliance\` - Configurar canal\n• \`!removechannel-alliance\` - Eliminar canal\n• \`!listchannels-alliance-v2\` - Ver configurados\n\n**Comandos de bloques:**\n• \`!blockcreate <nombre>\` - Crear bloque\n• \`!blockeditv2 <nombre>\` - Editar bloque\n• \`!embedlist\` - Ver todos los bloques`,
|
||||
// @ts-ignore Flag efímero
|
||||
flags: 64
|
||||
});
|
||||
break;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error en collector:', error);
|
||||
}
|
||||
});
|
||||
|
||||
collector.on("end", async () => {
|
||||
try {
|
||||
// Los components V2 no necesitan ser editados al expirar
|
||||
// ya que Discord los maneja automáticamente
|
||||
} catch (error) {
|
||||
// Ignorar errores
|
||||
}
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error en listChannelsV2:', error);
|
||||
await message.reply({
|
||||
content: '❌ **Error**\n\nHubo un problema al cargar la lista de canales. Inténtalo de nuevo.',
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1,67 +0,0 @@
|
||||
import logger from "../../core/lib/logger";
|
||||
import {
|
||||
StringSelectMenuInteraction,
|
||||
MessageFlags,
|
||||
ModalBuilder,
|
||||
TextInputBuilder,
|
||||
TextInputStyle,
|
||||
ActionRowBuilder
|
||||
} from 'discord.js';
|
||||
|
||||
export default {
|
||||
customId: 'ld_select_user',
|
||||
run: async (interaction: StringSelectMenuInteraction) => {
|
||||
if (!interaction.guild) {
|
||||
return interaction.reply({
|
||||
content: '❌ Solo disponible en servidores.',
|
||||
flags: MessageFlags.Ephemeral
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
const selectedUserId = interaction.values[0];
|
||||
|
||||
// Obtener información del usuario seleccionado para mostrar en el modal
|
||||
let userName = 'Usuario';
|
||||
try {
|
||||
const member = await interaction.guild.members.fetch(selectedUserId);
|
||||
userName = member.displayName || member.user.username;
|
||||
} catch {
|
||||
try {
|
||||
const user = await interaction.client.users.fetch(selectedUserId);
|
||||
userName = user.username;
|
||||
} catch {
|
||||
userName = selectedUserId;
|
||||
}
|
||||
}
|
||||
|
||||
// Crear modal para ingresar la cantidad de puntos
|
||||
const modal = new ModalBuilder()
|
||||
.setCustomId(`ld_points_modal:${selectedUserId}`)
|
||||
.setTitle(`Gestionar puntos de ${userName}`);
|
||||
|
||||
// Input para puntos totales (simplificado)
|
||||
const totalInput = new TextInputBuilder()
|
||||
.setCustomId('total_points')
|
||||
.setLabel('Modificar Puntos Totales')
|
||||
.setPlaceholder('+50 (añadir) / -2 (quitar últimos 2) / =100 (establecer)')
|
||||
.setStyle(TextInputStyle.Short)
|
||||
.setRequired(true);
|
||||
|
||||
// Añadir el input al modal
|
||||
// @ts-ignore
|
||||
modal.addComponents(
|
||||
// @ts-ignore
|
||||
new ActionRowBuilder().addComponents(totalInput)
|
||||
);
|
||||
|
||||
await interaction.showModal(modal);
|
||||
} catch (e) {
|
||||
logger.error({ err: e }, 'Error en ldSelectUser');
|
||||
await interaction.reply({
|
||||
content: '❌ Error al procesar la selección.',
|
||||
flags: MessageFlags.Ephemeral
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user