discord.simplified.js 0.0.0-stage → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 StratoX Development
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,598 @@
1
- # Temporary Holding Version
1
+ <div align="center">
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ # discord.simplified.js
4
+
5
+ [![npm version](https://img.shields.io/npm/v/discord.simplified.js?style=flat-square&color=cb3837&label=npm)](https://www.npmjs.com/package/discord.simplified.js)
6
+ [![npm downloads](https://img.shields.io/npm/dm/discord.simplified.js?style=flat-square&color=4b5563&label=downloads)](https://www.npmjs.com/package/discord.simplified.js)
7
+ [![license](https://img.shields.io/npm/l/discord.simplified.js?style=flat-square&color=3b82f6)](./LICENSE)
8
+ [![discord.js](https://img.shields.io/badge/discord.js-v14-5865F2?style=flat-square)](https://discord.js.org)
9
+
10
+ **A minimal, fast, and opinionated wrapper for [discord.js v14](https://discord.js.org) that removes boilerplate and adds powerful helpers.**
11
+
12
+ > ⚠️ **Note:** This library is independently developed and maintained. It is **not** affiliated with, a copy of, or derived from any other library. This is an original project.
13
+
14
+ </div>
15
+
16
+ ---
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ npm install discord.simplified.js
22
+ ```
23
+
24
+ ---
25
+
26
+ ## Quick Start
27
+
28
+ ```js
29
+ // CommonJS
30
+ const { Bot, EmbedBuilder, Button } = require("discord.simplified.js");
31
+
32
+ // ESM
33
+ import { Bot, EmbedBuilder, Button } from "discord.simplified.js";
34
+
35
+ const client = new Bot({ intents: "all", owners: ["YOUR_USER_ID"] });
36
+ client.start("YOUR_BOT_TOKEN");
37
+ ```
38
+
39
+ ---
40
+
41
+ ## Bot
42
+
43
+ ```js
44
+ const client = new Bot({
45
+ intents: "all",
46
+ partials: "all",
47
+ owners: ["YOUR_USER_ID"],
48
+ prefix: "!", // default: "!"
49
+ plugins: [] // optional — see Plugin System below
50
+ });
51
+
52
+ await client.start("TOKEN");
53
+ ```
54
+
55
+ ### Methods
56
+
57
+ ```js
58
+ client.isOwner(message.author.id); // true/false
59
+ const channel = await client.getChannel("CHANNEL_ID"); // cache-aware fetch
60
+ const msg = await client.waitFor("message", m => m.author.id === "USER_ID", 15000);
61
+ ```
62
+
63
+ ### Event Aliases
64
+
65
+ Use short clean names instead of discord.js camelCase event strings:
66
+
67
+ ```js
68
+ client.on("message", msg => {});
69
+ client.on("interaction", i => {});
70
+ client.on("join", member => {});
71
+ client.once("ready", () => {});
72
+ ```
73
+
74
+ | Alias | Discord.js Event |
75
+ |---|---|
76
+ | `message` | `messageCreate` |
77
+ | `join` | `guildMemberAdd` |
78
+ | `leave` | `guildMemberRemove` |
79
+ | `ban` | `guildBanAdd` |
80
+ | `unban` | `guildBanRemove` |
81
+ | `interaction` | `interactionCreate` |
82
+ | `reaction` | `messageReactionAdd` |
83
+ | `voiceUpdate` | `voiceStateUpdate` |
84
+ | `auditLog` | `guildAuditLogEntryCreate` |
85
+ | `guildJoin` | `guildCreate` |
86
+ | `guildLeave` | `guildDelete` |
87
+ | *(+ 80 more aliases)* | |
88
+
89
+ ---
90
+
91
+ ## Plugin System
92
+
93
+ The plugin system lets you extend your bot with reusable, npm-publishable modules. Plugins can register slash commands, prefix commands, scheduled tasks, middleware, and hook into any Discord event.
94
+
95
+ ```js
96
+ const myPlugin = require("@my-scope/my-plugin");
97
+ const { Bot } = require("discord.simplified.js");
98
+
99
+ const bot = new Bot({
100
+ intents: "all",
101
+ partials: "all",
102
+ plugins: [myPlugin]
103
+ });
104
+
105
+ bot.plugin.myPlugin.doSomething();
106
+ bot.start("TOKEN");
107
+ ```
108
+
109
+ ### Plugin Contract
110
+
111
+ ```js
112
+ module.exports = {
113
+ name: "example",
114
+
115
+ init(bot) {},
116
+ onReady() {},
117
+ onDestroy() {},
118
+
119
+ onMessage(msg) {},
120
+ onMessageEdit(oldMsg, newMsg) {},
121
+ onMessageDelete(msg) {},
122
+
123
+ onMemberJoin(member) {},
124
+ onMemberLeave(member) {},
125
+ onMemberUpdate(oldMember, newMember) {},
126
+
127
+ onInteraction(interaction) {},
128
+ onSlashCommand(interaction) {},
129
+ onButton(interaction) {},
130
+ onSelectMenu(interaction) {},
131
+ onModal(interaction) {},
132
+
133
+ messageMiddleware(msg) {}, // return false to block further handling
134
+ interactionMiddleware(interaction) {},
135
+
136
+ commands: [
137
+ {
138
+ name: "ping",
139
+ description: "Pings the bot",
140
+ options: [],
141
+ execute(interaction) { interaction.reply({ content: "Pong!" }); }
142
+ }
143
+ ],
144
+
145
+ prefixCommands: [
146
+ {
147
+ name: "hello",
148
+ aliases: ["hi", "hey"],
149
+ execute(msg, args) { msg.channel.send(`Hello, ${msg.author.username}!`); }
150
+ }
151
+ ],
152
+
153
+ tasks: [
154
+ {
155
+ name: "status-update",
156
+ interval: 60000,
157
+ execute(bot) { bot.user.setActivity("with plugins!"); }
158
+ }
159
+ ],
160
+
161
+ onGuildJoin(guild) {},
162
+ onGuildLeave(guild) {},
163
+ onVoiceUpdate(oldState, newState) {},
164
+ onRoleCreate(role) {},
165
+ onRoleDelete(role) {},
166
+ onChannelCreate(channel) {},
167
+ onChannelDelete(channel) {},
168
+ onError(error) {}
169
+ };
170
+ ```
171
+
172
+ ### Plugin Isolation
173
+
174
+ Every plugin runs inside a try/catch. If one plugin throws, it is logged and the rest continue — a broken plugin cannot crash your bot.
175
+
176
+ ---
177
+
178
+ ## Builders
179
+
180
+ ### EmbedBuilder
181
+
182
+ ```js
183
+ const embed = new EmbedBuilder()
184
+ .title("Hello")
185
+ .description("This is an embed")
186
+ .color(Colors.blurple)
187
+ .field("Name", "Value", true)
188
+ .footer("Made with discord.simplified.js")
189
+ .timestamp();
190
+ ```
191
+
192
+ ### Button / Row / Select
193
+
194
+ ```js
195
+ const button = new Button()
196
+ .label("Click Me")
197
+ .style("green") // blue, green, red, gray, link — or ButtonStyle enum
198
+ .id("btn_1");
199
+
200
+ const row = new Row().add(button);
201
+
202
+ const select = new Select()
203
+ .id("menu_1")
204
+ .placeholder("Choose one")
205
+ .min(1).max(1)
206
+ .option("Option 1", "val_1");
207
+ ```
208
+
209
+ ### Modal
210
+
211
+ ```js
212
+ const modal = new Modal()
213
+ .id("feedback_modal")
214
+ .title("Give Feedback")
215
+ .field("Your Name", "name", "short", { placeholder: "Enter your name", required: true })
216
+ .field("Your Message", "message", "paragraph", { placeholder: "Type here...", max: 500 });
217
+
218
+ await interaction.showModal(modal);
219
+ ```
220
+
221
+ ---
222
+
223
+ ## Components V2 (CV2)
224
+
225
+ For bots using the new Discord Components V2 system (`MessageFlags.V2` / `IsComponentsV2`).
226
+
227
+ ### ComponentBuilder
228
+
229
+ Wraps `ContainerBuilder` with chainable helpers:
230
+
231
+ ```js
232
+ const { ComponentBuilder, text, Flags } = require("discord.simplified.js");
233
+
234
+ const container = new ComponentBuilder()
235
+ .addText("## Hello World")
236
+ .addSeparator()
237
+ .addButtons(button1, button2)
238
+ .addMedia(["https://example.com/image.png"])
239
+ .addSection(section)
240
+ .addFile(file);
241
+
242
+ await channel.send({ components: [container], flags: Flags.V2 });
243
+ ```
244
+
245
+ ### Section
246
+
247
+ A section groups text on the left with an accessory (thumbnail or button) on the right. The last `.thumbnail()` or `.button()` call wins.
248
+
249
+ ```js
250
+ const { Section } = require("discord.simplified.js");
251
+
252
+ // With a thumbnail accessory
253
+ const section = new Section()
254
+ .text("**User Profile**\nJoined 3 months ago")
255
+ .thumbnail("https://example.com/avatar.png");
256
+
257
+ // With a button accessory
258
+ const section = new Section()
259
+ .text("Click to open settings")
260
+ .button("Open", "blue", "open_settings");
261
+ ```
262
+
263
+ ### Thumbnail
264
+
265
+ A media thumbnail — only valid as a section accessory, not standalone.
266
+
267
+ ```js
268
+ const { Thumbnail } = require("discord.simplified.js");
269
+
270
+ const thumb = new Thumbnail()
271
+ .url("https://example.com/image.png")
272
+ .description("Alt text for accessibility");
273
+
274
+ const section = new Section()
275
+ .text("Some content")
276
+ .setAccessory(thumb);
277
+ ```
278
+
279
+ ### FileComponent / File
280
+
281
+ Attaches a file URL to a CV2 message. Exported as both `FileComponent` and `File`.
282
+
283
+ ```js
284
+ const { File, ComponentBuilder, Flags } = require("discord.simplified.js");
285
+
286
+ const container = new ComponentBuilder()
287
+ .addText("Here is your report:")
288
+ .addFile("attachment://report.pdf")
289
+ .addFile(new File().url("attachment://report.pdf"));
290
+
291
+ await channel.send({ components: [container], flags: Flags.V2 });
292
+ ```
293
+
294
+ ---
295
+
296
+ ## Logger
297
+
298
+ A built-in logger with timestamps, levels, and ANSI color output. No external dependencies.
299
+
300
+ ```js
301
+ const { Logger, log } = require("discord.simplified.js");
302
+
303
+ // Use the default instance (tag: "dislang")
304
+ log.info("Bot started");
305
+ log.warn("Rate limit approaching");
306
+ log.error("Failed to fetch channel");
307
+ log.success("Connected to gateway");
308
+ log.debug("Raw event received"); // only shown if Logger.debug = true
309
+
310
+ // Create a tagged instance
311
+ const logger = new Logger("Music");
312
+ logger.info("Player started");
313
+ // → [14:23:01] [Music] [INFO] Player started
314
+
315
+ // Enable debug logs globally
316
+ Logger.debug = true;
317
+ ```
318
+
319
+ Output format: `[HH:MM:SS] [TAG] [LEVEL] message`
320
+
321
+ Exported as both `Logger` and `Log`.
322
+
323
+ ---
324
+
325
+ ## Presence / Status
326
+
327
+ Set your bot's status and activity, or rotate through multiple presences automatically.
328
+
329
+ ```js
330
+ const { Bot } = require("discord.simplified.js");
331
+ const bot = new Bot({ intents: "all" });
332
+
333
+ bot.on("ready", () => {
334
+ // Single presence
335
+ bot.setPresence({
336
+ status: "online", // online | idle | dnd | invisible
337
+ type: "playing", // playing | listening | watching | competing | streaming | custom
338
+ text: "with discord.js"
339
+ });
340
+
341
+ // Streaming (requires url)
342
+ bot.setPresence({ type: "streaming", text: "a game", url: "https://twitch.tv/someone" });
343
+
344
+ // Rotate every 15 seconds
345
+ bot.rotatePresence([
346
+ { type: "playing", text: "with slash commands" },
347
+ { type: "watching", text: `${guild.memberCount} members` },
348
+ { type: "listening", text: "your commands" }
349
+ ], 15000);
350
+
351
+ // Stop rotation
352
+ bot.stopRotation();
353
+ });
354
+ ```
355
+
356
+ Exported as both `Presence` and `Status`.
357
+
358
+ ---
359
+
360
+ ## Interaction Collectors
361
+
362
+ Wait for a single component interaction or collect many.
363
+
364
+ ### awaitComponent
365
+
366
+ Available on both `message` and `interaction`.
367
+
368
+ ```js
369
+ // Wait for a button click
370
+ const click = await msg.awaitComponent({
371
+ type: "button", // button | select | modal
372
+ id: "confirm", // optional: match a specific customId
373
+ user: interaction.user.id, // optional: only accept from this user
374
+ time: 30000 // timeout in ms (default: 30000)
375
+ });
376
+ click.ok("Confirmed!");
377
+
378
+ // From an interaction
379
+ const click = await interaction.awaitComponent({ type: "button", id: "confirm" });
380
+ ```
381
+
382
+ On timeout, rejects with: `awaitComponent timed out after 30s waiting for a button interaction`
383
+
384
+ ### collectComponents
385
+
386
+ Collect multiple interactions over time.
387
+
388
+ ```js
389
+ const collector = msg.collectComponents({
390
+ type: "button",
391
+ time: 60000,
392
+ max: 10,
393
+ onCollect: i => i.ok("You clicked: " + i.customId),
394
+ onEnd: collected => log.info("Done, got " + collected.size + " clicks")
395
+ });
396
+
397
+ // Stop early
398
+ collector.stop();
399
+ ```
400
+
401
+ ---
402
+
403
+ ## Interaction Sugar
404
+
405
+ Forget checking `replied` or `deferred` manually — these handle it automatically:
406
+
407
+ ```js
408
+ client.on("interaction", async (i) => {
409
+ await i.ok("Done! ✅"); // normal reply
410
+ await i.ok("Done! ✅", true); // ephemeral
411
+ await i.fail("❌ Something went wrong!"); // always ephemeral
412
+ await i.private("Only you can see this"); // always ephemeral
413
+ await i.think(); // defer (visible)
414
+ await i.think(true); // defer (ephemeral)
415
+ await i.refresh("Updated content"); // edit if already replied
416
+ });
417
+ ```
418
+
419
+ ---
420
+
421
+ ## Timestamp Helper
422
+
423
+ ```js
424
+ import { time } from "discord.simplified.js";
425
+
426
+ time(new Date(), "relative") // → "2 hours ago"
427
+ time(new Date(), "short") // → "9:41 PM"
428
+ time(new Date(), "long") // → "9:41:30 PM"
429
+ time(new Date(), "date") // → "01/01/2024"
430
+ time(new Date(), "longdate") // → "January 1, 2024"
431
+ time(new Date(), "full") // → "January 1, 2024 9:41 PM"
432
+ time(new Date(), "longfull") // → "Friday, January 1, 2024 9:41 PM"
433
+ ```
434
+
435
+ ---
436
+
437
+ ## Color Constants
438
+
439
+ ```js
440
+ import { Colors } from "discord.simplified.js";
441
+
442
+ new EmbedBuilder().color(Colors.blurple);
443
+ new EmbedBuilder().color(Colors.red);
444
+
445
+ // Available: blurple, white, black, dark, gray/grey,
446
+ // red, green, yellow, blue, orange, purple, pink,
447
+ // gold, teal, cyan, navy, transparent
448
+ ```
449
+
450
+ ---
451
+
452
+ ## Cooldown Manager
453
+
454
+ ```js
455
+ import { Cooldown } from "discord.simplified.js";
456
+
457
+ const cd = new Cooldown(5000); // 5 seconds
458
+
459
+ client.on("message", (msg) => {
460
+ if (cd.check(msg.author.id)) {
461
+ return msg.reply(`⏳ Wait ${cd.remainingText(msg.author.id)}`);
462
+ }
463
+ cd.set(msg.author.id);
464
+ // handle command
465
+ });
466
+
467
+ cd.remaining(userId); // → ms remaining
468
+ cd.remainingText(userId); // → "4s" or "1m 30s"
469
+ cd.clear(userId); // remove one user's cooldown
470
+ cd.reset(); // clear all cooldowns
471
+ ```
472
+
473
+ ---
474
+
475
+ ## Message Extensions
476
+
477
+ ```js
478
+ message.reply("Hello!");
479
+ message.reply({ text: "Hey!", ping: true });
480
+ message.ping();
481
+ message.deleteSafe();
482
+ message.reactSafe("👍");
483
+ message.edit("New content");
484
+
485
+ message.collect({
486
+ from: "USER_ID",
487
+ time: 15000,
488
+ onMessage: m => console.log(m.content),
489
+ onEnd: collected => console.log(`Got ${collected.size} messages`)
490
+ });
491
+
492
+ const reply = await message.awaitReply(m => m.author.id === "USER_ID", 15000);
493
+ ```
494
+
495
+ ---
496
+
497
+ ## User / Member / Guild / Channel Extensions
498
+
499
+ ```js
500
+ // User
501
+ await user.dm("Hello!");
502
+ await user.dm({ content: "Hello!", embeds: [embed] });
503
+
504
+ // GuildMember
505
+ if (member.hasRole("ROLE_ID")) {}
506
+ if (member.can("BanMembers")) {}
507
+ await member.addRole("ROLE_ID");
508
+ await member.removeRole("ROLE_ID", "reason");
509
+ await member.timeout(5, "Spamming"); // 5 minutes
510
+ await member.timeout(null); // remove timeout
511
+
512
+ // Guild
513
+ const member = guild.findMember("Karan");
514
+ const role = guild.findRole("Moderator");
515
+ const channel = guild.findChannel("general");
516
+
517
+ // Channel
518
+ await channel.sendEmbed(embed);
519
+ await channel.sendEmbed([embed1, embed2]);
520
+ await channel.sendButtons("Choose:", row1, row2);
521
+ await channel.purge(10);
522
+ ```
523
+
524
+ ---
525
+
526
+ ## VoiceChannelStatus
527
+
528
+ ```js
529
+ await VoiceChannelStatus.set("🎮 Gaming", "CHANNEL_ID");
530
+ await VoiceChannelStatus.remove("CHANNEL_ID");
531
+
532
+ // Aliases
533
+ await VCS.set("🎧 Music", "CHANNEL_ID");
534
+ await VCStatus.remove("CHANNEL_ID");
535
+ ```
536
+
537
+ ---
538
+
539
+ ## sendWebhook
540
+
541
+ ```js
542
+ await sendWebhook("WEBHOOK_URL", "Hello!");
543
+ await sendWebhook("WEBHOOK_URL", { content: "Hello!", username: "My Bot", embeds: [embed] });
544
+ ```
545
+
546
+ ---
547
+
548
+ ## File Structure
549
+
550
+ ```
551
+ discord.simplified.js/
552
+ index.js ← CommonJS (require)
553
+ index.cjs ← CommonJS (explicit .cjs)
554
+ index.mjs ← ESM (import)
555
+ index.d.ts ← TypeScript declarations
556
+ ```
557
+
558
+ ---
559
+
560
+ ## How It Works
561
+
562
+ - Everything is in a **single file per format** — zero internal imports, zero path issues
563
+ - All patches are **auto-applied** when you require/import the library
564
+ - Plugins are **isolated in try/catch** — a broken plugin cannot crash your bot
565
+ - Slash commands from plugins are **auto-registered globally** on ready
566
+ - Plugin tasks are **auto-started on ready** and **auto-cleared on destroy**
567
+ - Errors route through the built-in **Logger** with timestamps and color output
568
+
569
+ ---
570
+
571
+ ## Changelog
572
+
573
+ ### 2.2.0
574
+ - Added **Logger** / `Log` / `log` — built-in timestamped ANSI logger with levels and tag support
575
+ - Added **Presence** / `Status` — `bot.setPresence()`, `bot.rotatePresence()`, `bot.stopRotation()`
576
+ - Added **`awaitComponent`** and **`collectComponents`** on `Message` and `BaseInteraction`
577
+ - `_throwErr` now routes through the Logger for consistent output
578
+
579
+ ### 2.1.0
580
+ - Added **Components V2** builders: `Section`, `Thumbnail`, `FileComponent` / `File`
581
+ - Added `addSection()` and `addFile()` to `ComponentBuilder`
582
+ - `addFile()` accepts a plain URL string or a `FileComponent` instance
583
+ - Full TypeScript declarations for all new classes
584
+
585
+ ### 2.0.1
586
+ - Added full **Plugin System** with slash commands, prefix commands, scheduled tasks, middleware, and event hooks
587
+ - Added `prefix` option to `BotOptions`
588
+ - Added `bot.plugin` map for accessing loaded plugin instances
589
+ - Full TypeScript support for the plugin interface
590
+
591
+ ### 2.0.0
592
+ - Initial release
593
+
594
+ ---
595
+
596
+ ## License
597
+
598
+ MIT License © 2026 discord.simplified.js