djs-builder 0.6.401 → 0.7.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.
@@ -9,6 +9,7 @@ const giveawaySchema = new Schema({
9
9
  hoster: { type: String, required: true },
10
10
  endEmbed: { type: Object, required: true },
11
11
  winnerCount: { type: Number, default: 1 },
12
+ prize: { type: String, required: true },
12
13
  winners: Array,
13
14
  paused: { type: Boolean, default: false },
14
15
  pausedTime: Array,
@@ -19,6 +20,7 @@ const giveawaySchema = new Schema({
19
20
  enum: ["reaction", "button"],
20
21
  default: "reaction",
21
22
  },
23
+ requiredRoles: { type: [String], default: [] },
22
24
 
23
25
  users: { type: [String], default: [] },
24
26
  });
@@ -32,6 +34,7 @@ async function Gstart({
32
34
  endTime: endTime,
33
35
  winers: winnerCount,
34
36
  channelId: channelId,
37
+ prize: prize,
35
38
  embed: {
36
39
  custom: Scustom = false,
37
40
  title: Stitle = false,
@@ -53,13 +56,15 @@ async function Gstart({
53
56
  emoji: emoji = false,
54
57
  label: label = false,
55
58
  style: style = false,
56
- id : id = false
59
+ id: id = false,
57
60
  },
61
+ requirements: { requiredRoles: requiredRoles = [] } = {},
58
62
  }) {
59
63
  if (!winnerCount) winnerCount = 1;
60
64
  if (!endTime) return { error: "End time is required." };
61
65
  if (!channelId) return { error: "Channel ID is required." };
62
66
  if (!context) return { error: "Context is required." };
67
+ if (!prize) return { error: "Prize is required." };
63
68
 
64
69
  if (type === "reaction" && !emoji) return { error: "Emoji is not required." };
65
70
 
@@ -91,11 +96,20 @@ async function Gstart({
91
96
  if (Sthumbnail) embed.setThumbnail(Sthumbnail);
92
97
  }
93
98
 
99
+ let requirementsText = "";
100
+ if (requiredRoles.length > 0) {
101
+ requirementsText = `\n- Required Roles: ${requiredRoles
102
+ .map((r) => `<@&${r}>`)
103
+ .join(", ")}`;
104
+ }
105
+
94
106
  embed.addFields({
95
107
  name: "🎉 Giveaway",
96
- value: `- Winer(s) : ${winnerCount}\n- Time : <t:${Math.floor(
108
+ value: `- Prize: ${prize}\n- Winner(s) : ${winnerCount}\n- Time : <t:${Math.floor(
97
109
  endTime / 1000
98
- )}:R>\n- Hosted By : ${context.user ? context.user : context.author}`,
110
+ )}:R>\n- Hosted By : ${
111
+ context.user ? context.user : context.author
112
+ }${requirementsText}`,
99
113
  inline: true,
100
114
  });
101
115
 
@@ -124,7 +138,7 @@ async function Gstart({
124
138
 
125
139
  end_embed.addFields({
126
140
  name: "🎉 Giveaway",
127
- value: `- Winer(s): ${winnerCount}\n- Time : <t:${Math.floor(
141
+ value: `- Prize: ${prize}\n- Winner(s): ${winnerCount}\n- Time : <t:${Math.floor(
128
142
  endTime / 1000
129
143
  )}:R>\n- Hosted By : ${context.user ? context.user : context.author}`,
130
144
  inline: true,
@@ -136,6 +150,7 @@ async function Gstart({
136
150
  messageId: message.id,
137
151
  hoster: context.user ? context.user.id : context.author.id,
138
152
  endTime: endTime,
153
+ prize: prize,
139
154
  endType: false,
140
155
  paused: false,
141
156
  pausedTime: [],
@@ -145,6 +160,7 @@ async function Gstart({
145
160
  reaction: type,
146
161
  endEmbed: end_embed.toJSON(),
147
162
  users: [],
163
+ requiredRoles: requiredRoles,
148
164
  });
149
165
 
150
166
  if (type === "reaction") message.react(emoji);
@@ -293,6 +309,7 @@ async function Glist(type) {
293
309
 
294
310
  const list = giveaways.map((g) => {
295
311
  return {
312
+ prize: g.prize,
296
313
  messageId: g.messageId,
297
314
  guildId: g.guildId,
298
315
  channelId: g.channelId,
@@ -328,7 +345,7 @@ async function Gpause(client, messageId) {
328
345
 
329
346
  message.embeds[0].data.fields.find(
330
347
  (f) => f.name === "🎉 Giveaway"
331
- ).value = `- Winer(s): ${g.winnerCount}\n- Time : Pause ⏸️\n- Hosted By : <@${g.hoster}>`;
348
+ ).value = `- Winner(s): ${g.winnerCount}\n- Time : Pause ⏸️\n- Hosted By : <@${g.hoster}>`;
332
349
 
333
350
  await message.edit({ embeds: [message.embeds[0]] });
334
351
  await giveaway.findOneAndUpdate(
@@ -343,7 +360,7 @@ async function Gresume(client, messageId) {
343
360
  const g = await giveaway.findOne({ messageId });
344
361
  if (!g) return { error: "❌ Giveaway Data Not Found" };
345
362
 
346
- if (g.paused === true) return { error: "❌ Giveaway Already Paused" };
363
+ if (g.paused === false) return { error: "❌ Giveaway Already Paused" };
347
364
  if (g.ended === true) return { error: "❌ Giveaway Already Ended" };
348
365
 
349
366
  const guild = await client.guilds.cache.get(g.guildId);
@@ -356,7 +373,7 @@ async function Gresume(client, messageId) {
356
373
 
357
374
  message.embeds[0].data.fields.find(
358
375
  (f) => f.name === "🎉 Giveaway"
359
- ).value = `- Winer(s): ${g.winnerCount}\n- Time : <t:${Math.floor(
376
+ ).value = `- Winner(s): ${g.winnerCount}\n- Time : <t:${Math.floor(
360
377
  time / 1000
361
378
  )}:R>\n- Hosted By : <@${g.hoster}>`;
362
379
 
@@ -386,13 +403,32 @@ async function Gdelete(messageId) {
386
403
  }
387
404
 
388
405
  ////////////////////////////////////* Giveaway Add User
389
- async function GaddUser(messageId, userId) {
406
+ async function GaddUser(messageId, userId, guild) {
390
407
  const g = await giveaway.findOne({ messageId });
391
408
  if (!g) return { error: "❌ Giveaway Data Not Found" };
392
409
 
410
+ if (g.ended) return { error: "❌ Giveaway Already Ended" };
411
+
393
412
  const all_users = g.users || [];
394
413
  if (all_users.includes(userId)) return { error: "❌ User Already Joined" };
395
414
 
415
+ if (g.requiredRoles && g.requiredRoles.length > 0) {
416
+ if (!guild) return { error: "❌ Guild object is required to check roles." };
417
+ const member = await guild.members.fetch(userId).catch(() => null);
418
+ if (!member) return { error: "❌ Member not found in guild." };
419
+
420
+ const hasRole = g.requiredRoles.some((roleId) =>
421
+ member.roles.cache.has(roleId)
422
+ );
423
+ if (!hasRole) {
424
+ return {
425
+ error: `❌ You need one of the following roles to join: ${g.requiredRoles
426
+ .map((r) => `<@&${r}>`)
427
+ .join(", ")}`,
428
+ };
429
+ }
430
+ }
431
+
396
432
  if (!all_users.includes(userId)) {
397
433
  all_users.push(userId);
398
434
  await giveaway.findOneAndUpdate({ messageId }, { users: all_users });
@@ -434,7 +470,7 @@ async function GaddTime(messageId, client, time) {
434
470
 
435
471
  message.embeds[0].data.fields.find(
436
472
  (f) => f.name === "🎉 Giveaway"
437
- ).value = `- Winer(s): ${g.winnerCount}\n- Time : <t:${Math.floor(
473
+ ).value = `- Winner(s): ${g.winnerCount}\n- Time : <t:${Math.floor(
438
474
  finel_time / 1000
439
475
  )}:R>\n- Hosted By : <@${g.hoster}>`;
440
476
 
@@ -466,7 +502,7 @@ async function GremoveTime(messageId, client, time) {
466
502
 
467
503
  message.embeds[0].data.fields.find(
468
504
  (f) => f.name === "🎉 Giveaway"
469
- ).value = `- Winer(s): ${g.winnerCount}\n- Time : <t:${Math.floor(
505
+ ).value = `- Winner(s): ${g.winnerCount}\n- Time : <t:${Math.floor(
470
506
  finel_time / 1000
471
507
  )}:R>\n- Hosted By : <@${g.hoster}>`;
472
508
 
@@ -487,6 +523,7 @@ async function Gdata(messageId) {
487
523
  }
488
524
 
489
525
  module.exports = {
526
+ giveaway,
490
527
  Gstart,
491
528
  Gcheck,
492
529
  Greroll,
File without changes
@@ -150,7 +150,13 @@ async function starter(client, options) {
150
150
  const events = options.events || null;
151
151
  const anticrash = options.anticrash || null;
152
152
  const terminal = options.terminal || null;
153
+ const dashboard = options.dashboard || null;
153
154
 
155
+ //////////////////////////////////////////? Dashboard Loader ////////////////////////////////////////////////////////
156
+ if (dashboard) {
157
+ await dashboard(client, dashboard);
158
+ }
159
+ //////////////////////////////////////////! terminal info !////////////////////////////////////////////////////////
154
160
  if (terminal) {
155
161
  console.log("🚀 Bot is starting...");
156
162
  }
@@ -260,12 +266,13 @@ async function starter(client, options) {
260
266
  if (command.guildOnly && !message.guild) return;
261
267
  if (command.dmOnly && message.guild) return;
262
268
  if (command.devOnly && message.author.id !== client.owner.id) return;
263
- if (
264
- command.ownerOnly &&
265
- message.guild &&
266
- message.author.id !== (await message.guild.fetchOwner()).id
267
- )
268
- return;
269
+ if (command.ownerOnly) {
270
+ if (
271
+ message.guild &&
272
+ message.author.id !== (await message.guild.fetchOwner()).id
273
+ )
274
+ return;
275
+ }
269
276
 
270
277
  if (
271
278
  command.Permissions &&
@@ -274,11 +281,13 @@ async function starter(client, options) {
274
281
  )
275
282
  return;
276
283
 
277
-
278
- if(command.Blacklist) {
279
-
280
- const userBlacklisted = await isBlacklisted(message.guild ? message.guild.id : null, 'user', message.author.id);
281
- if(userBlacklisted) {
284
+ if (command.Blacklist) {
285
+ const userBlacklisted = await isBlacklisted(
286
+ message.guild ? message.guild.id : null,
287
+ "user",
288
+ message.author.id
289
+ );
290
+ if (userBlacklisted) {
282
291
  return message.reply({
283
292
  content: "`❌` You are blacklisted from using bot commands.",
284
293
  flags: 64,
@@ -287,23 +296,33 @@ async function starter(client, options) {
287
296
 
288
297
  let roleBlacklist = null;
289
298
  for (const [id, role] of message.member.roles.cache) {
290
- const isBlocked = await isBlacklisted(message.guild ? message.guild.id : null, 'role', id);
299
+ const isBlocked = await isBlacklisted(
300
+ message.guild ? message.guild.id : null,
301
+ "role",
302
+ id
303
+ );
291
304
  if (isBlocked) {
292
305
  roleBlacklist = isBlocked;
293
306
  break;
294
307
  }
295
308
  }
296
-
297
- if(roleBlacklist) {
309
+
310
+ if (roleBlacklist) {
298
311
  const role = message.guild.roles.cache.get(roleBlacklist.id);
299
312
  return message.reply({
300
- content: `\`❌\` The role **${role ? role.name : 'Unknown'}** is blacklisted from using bot commands.`,
313
+ content: `\`❌\` The role **${
314
+ role ? role.name : "Unknown"
315
+ }** is blacklisted from using bot commands.`,
301
316
  flags: 64,
302
317
  });
303
318
  }
304
319
 
305
- const channelBlacklist = await isBlacklisted(message.guild ? message.guild.id : null, 'channel', message.channel.id);
306
- if(channelBlacklist) {
320
+ const channelBlacklist = await isBlacklisted(
321
+ message.guild ? message.guild.id : null,
322
+ "channel",
323
+ message.channel.id
324
+ );
325
+ if (channelBlacklist) {
307
326
  return message.reply({
308
327
  content: "`❌` This channel is blacklisted from using bot commands.",
309
328
  flags: 64,
@@ -346,15 +365,15 @@ async function starter(client, options) {
346
365
  if (cooldown.type) return interaction.reply(cooldown.text);
347
366
  }
348
367
 
349
- if (
350
- command.ownerOnly &&
351
- interaction.guild &&
352
- interaction.user.id !== (await interaction.guild.fetchOwner()).id
353
- ) {
354
- return interaction.reply({
355
- content: "`❌` This command is restricted to the server owner only!",
356
- flags: 64,
357
- });
368
+ if (command.ownerOnly) {
369
+ if (
370
+ interaction.guild &&
371
+ interaction.user.id !== (await interaction.guild.fetchOwner()).id
372
+ )
373
+ return interaction.reply({
374
+ content: "`❌` This command is restricted to the server owner only!",
375
+ flags: 64,
376
+ });
358
377
  }
359
378
 
360
379
  if (command.devOnly && interaction.user.id !== client.owner.id) {
@@ -386,15 +405,19 @@ async function starter(client, options) {
386
405
  )
387
406
  ) {
388
407
  return interaction.reply({
389
- content: "`❌` You do not have enough permissions to execute this command.",
408
+ content:
409
+ "`❌` You do not have enough permissions to execute this command.",
390
410
  flags: 64,
391
411
  });
392
412
  }
393
413
 
394
- if(command.Blacklist) {
395
-
396
- const userBlacklisted = await isBlacklisted(interaction.guild ? interaction.guild.id : null, 'user', interaction.user.id);
397
- if(userBlacklisted) {
414
+ if (command.Blacklist) {
415
+ const userBlacklisted = await isBlacklisted(
416
+ interaction.guild ? interaction.guild.id : null,
417
+ "user",
418
+ interaction.user.id
419
+ );
420
+ if (userBlacklisted) {
398
421
  return interaction.reply({
399
422
  content: "`❌` You are blacklisted from using bot commands.",
400
423
  flags: 64,
@@ -403,23 +426,33 @@ async function starter(client, options) {
403
426
 
404
427
  let roleBlacklist = null;
405
428
  for (const [id, role] of interaction.member.roles.cache) {
406
- const isBlocked = await isBlacklisted(interaction.guild ? interaction.guild.id : null, 'role', id);
429
+ const isBlocked = await isBlacklisted(
430
+ interaction.guild ? interaction.guild.id : null,
431
+ "role",
432
+ id
433
+ );
407
434
  if (isBlocked) {
408
435
  roleBlacklist = isBlocked;
409
436
  break;
410
437
  }
411
438
  }
412
439
 
413
- if(roleBlacklist) {
440
+ if (roleBlacklist) {
414
441
  const role = interaction.guild.roles.cache.get(roleBlacklist.id);
415
442
  return interaction.reply({
416
- content: `\`❌\` The role **${role ? role.name : 'Unknown'}** is blacklisted from using bot commands.`,
443
+ content: `\`❌\` The role **${
444
+ role ? role.name : "Unknown"
445
+ }** is blacklisted from using bot commands.`,
417
446
  flags: 64,
418
447
  });
419
448
  }
420
449
 
421
- const channelBlacklist = await isBlacklisted(interaction.guild ? interaction.guild.id : null, 'channel', interaction.channel.id);
422
- if(channelBlacklist) {
450
+ const channelBlacklist = await isBlacklisted(
451
+ interaction.guild ? interaction.guild.id : null,
452
+ "channel",
453
+ interaction.channel.id
454
+ );
455
+ if (channelBlacklist) {
423
456
  return interaction.reply({
424
457
  content: "`❌` This channel is blacklisted from using bot commands.",
425
458
  flags: 64,
@@ -483,12 +516,13 @@ async function starter(client, options) {
483
516
  const { Wait, CreateBar, CreateRow, GetUser } = require("../function/function");
484
517
  const { Level, addXP, UserLevel, leaderboard } = require("../function/level");
485
518
  const { log } = require("../function/log");
519
+ const { dashboard } = require("../function/dash");
486
520
  const {
487
521
  Blacklist,
488
522
  isBlacklisted,
489
523
  addToBlacklist,
490
524
  removeFromBlacklist,
491
- getBlacklist
525
+ getBlacklist,
492
526
  } = require("../function/blacklist");
493
527
  const {
494
528
  giveaway,
@@ -510,6 +544,7 @@ module.exports = {
510
544
  Level,
511
545
  giveaway,
512
546
  starter,
547
+ dashboard,
513
548
  reload,
514
549
  log,
515
550
  Wait,
@@ -535,5 +570,5 @@ module.exports = {
535
570
  isBlacklisted,
536
571
  addToBlacklist,
537
572
  removeFromBlacklist,
538
- getBlacklist
573
+ getBlacklist,
539
574
  };
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "djs-builder",
3
- "version": "0.6.401",
4
- "note": "🎉 Package Update! 🥏\n\n- 📚 Documentation: Added full guide for Giveaway System & Hot Reloading.\n- 🐛 Bug Fixes: Fixed critical issue in Giveaway winner selection.\n\n🔗 Learn more on [NPM](https://www.npmjs.com/package/djs-builder)",
5
- "description": "🎉 Package Update! 🥏",
3
+ "version": "0.7.0",
4
+ "note": "🎉 Package Update! 🥏\n\n- 🌐 NEW: Dashboard System - Modern web-based control panel!\n • Discord OAuth2 Login\n • Server Management\n • Level System Control\n • Giveaway Management\n • Blacklist Management\n- � Documentation: Full Dashboard guide added to README.\n- Standalone Usage: Use Dashboard with or without Starter!\n\n🔗 Learn more on [NPM](https://www.npmjs.com/package/djs-builder)",
5
+ "description": "🎉 NEW: Dashboard System - Web Control Panel! 🌐",
6
6
  "main": "handler/starter.js",
7
7
  "dependencies": {
8
8
  "axios": "^1.11.0",
@@ -10,6 +10,11 @@
10
10
  "cli-table3": "^0.6.5",
11
11
  "discord-inviter": "^0.9.3",
12
12
  "discord.js": "^14.21.0",
13
- "mongoose": "^8.18.0"
13
+ "mongoose": "^8.18.0",
14
+ "express": "^4.18.2",
15
+ "express-session": "^1.17.3",
16
+ "passport": "^0.7.0",
17
+ "passport-discord": "^0.1.4",
18
+ "ejs": "^3.1.9"
14
19
  }
15
20
  }
package/views/404.ejs ADDED
@@ -0,0 +1,40 @@
1
+ <!DOCTYPE html>
2
+ <html lang="ar" dir="rtl">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>404 - الصفحة غير موجودة</title>
7
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
8
+ <link href="https://cdn.jsdelivr.net/npm/remixicon@3.5.0/fonts/remixicon.css" rel="stylesheet">
9
+ <style>
10
+ :root { --bg-primary: #0f0f0f; --bg-secondary: #1a1a1a; --bg-card: #242424; --accent: #5865F2; --accent-hover: #4752C4; --text-primary: #fff; --text-secondary: #b9bbbe; --text-muted: #72767d; --border: #2f2f2f; --radius: 12px; --radius-sm: 8px; }
11
+ * { margin: 0; padding: 0; box-sizing: border-box; }
12
+ body { font-family: 'Inter', sans-serif; background: var(--bg-primary); color: var(--text-primary); min-height: 100vh; display: flex; align-items: center; justify-content: center; }
13
+ .error-container { text-align: center; padding: 40px; max-width: 500px; }
14
+ .error-code { font-size: 120px; font-weight: 700; color: var(--accent); line-height: 1; margin-bottom: 16px; text-shadow: 0 0 60px rgba(88, 101, 242, 0.3); }
15
+ .error-icon { font-size: 64px; color: var(--text-muted); margin-bottom: 24px; }
16
+ .error-title { font-size: 28px; font-weight: 600; margin-bottom: 12px; }
17
+ .error-desc { font-size: 16px; color: var(--text-secondary); margin-bottom: 32px; line-height: 1.6; }
18
+ .btn { display: inline-flex; align-items: center; gap: 8px; padding: 12px 24px; border-radius: var(--radius-sm); font-weight: 500; font-size: 15px; transition: all 0.2s ease; text-decoration: none; }
19
+ .btn-primary { background: var(--accent); color: white; }
20
+ .btn-primary:hover { background: var(--accent-hover); transform: translateY(-2px); }
21
+ .btn-secondary { background: var(--bg-card); color: var(--text-primary); border: 1px solid var(--border); margin-right: 12px; }
22
+ .btn-secondary:hover { background: var(--bg-secondary); }
23
+ .buttons { display: flex; justify-content: center; gap: 12px; flex-wrap: wrap; }
24
+ @keyframes float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-10px); } }
25
+ .error-icon { animation: float 3s ease-in-out infinite; }
26
+ </style>
27
+ </head>
28
+ <body>
29
+ <div class="error-container">
30
+ <div class="error-code">404</div>
31
+ <i class="ri-compass-discover-line error-icon"></i>
32
+ <h1 class="error-title">الصفحة غير موجودة</h1>
33
+ <p class="error-desc">عذراً، الصفحة التي تبحث عنها غير موجودة أو تم نقلها. تأكد من صحة الرابط أو عد للصفحة الرئيسية.</p>
34
+ <div class="buttons">
35
+ <a href="/" class="btn btn-primary"><i class="ri-home-line"></i> الصفحة الرئيسية</a>
36
+ <a href="/dashboard" class="btn btn-secondary"><i class="ri-dashboard-line"></i> لوحة التحكم</a>
37
+ </div>
38
+ </div>
39
+ </body>
40
+ </html>