djs-builder 0.7.11 → 0.7.12

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/README.md CHANGED
@@ -704,7 +704,10 @@ const components = await CreateComponents("array", [
704
704
  ]);
705
705
 
706
706
  // Send the components
707
- await channel.send({ components });
707
+ await channel.send({
708
+ flags: 32768,
709
+ components : components
710
+ });
708
711
  ```
709
712
 
710
713
  ---
@@ -714,7 +717,7 @@ await channel.send({ components });
714
717
  ```js
715
718
  const { CreateComponents } = require("djs-builder");
716
719
 
717
- const components = await CreateComponents("container", [
720
+ const components = await CreateComponents(true, [
718
721
  {
719
722
  type: "text",
720
723
  content: "# 📢 Server Announcement\nWelcome everyone!",
package/function/dash.js CHANGED
@@ -1,9 +1,4 @@
1
- /**
2
- * DJS-Builder Dashboard
3
- * لوحة تحكم عصرية وخفيفة متوافقة مع حزمة djs-builder
4
- * @version 2.0.0
5
- * @author DJS-Builder Team
6
- */
1
+
7
2
 
8
3
  const express = require("express");
9
4
  const session = require("express-session");
@@ -41,11 +36,7 @@ const {
41
36
  } = require("./giveaway");
42
37
  const { Log, getLogConfigData } = require("./log");
43
38
 
44
- /**
45
- * دالة لإنشاء وتشغيل لوحة التحكم
46
- * @param {Client} client - كائن البوت
47
- * @param {Object} options - خيارات اللوحة
48
- */
39
+
49
40
  function dashboard(client, options) {
50
41
  const app = express();
51
42
  const {
@@ -56,13 +47,13 @@ function dashboard(client, options) {
56
47
  } = options;
57
48
 
58
49
  clientID = client.user.id;
59
- // إعداد المسارات
50
+
60
51
  app.set("view engine", "ejs");
61
52
  app.set("views", path.join(__dirname, "..", "views"));
62
53
  app.use(express.json());
63
54
  app.use(express.urlencoded({ extended: true }));
64
55
 
65
- // إعداد الجلسات
56
+
66
57
  app.use(
67
58
  session({
68
59
  secret: sessionSecret,
@@ -74,7 +65,7 @@ function dashboard(client, options) {
74
65
  })
75
66
  );
76
67
 
77
- // إعداد Passport
68
+
78
69
  app.use(passport.initialize());
79
70
  app.use(passport.session());
80
71
 
@@ -95,22 +86,22 @@ function dashboard(client, options) {
95
86
  )
96
87
  );
97
88
 
98
- // Middleware للتحقق من تسجيل الدخول
89
+
99
90
  function isAuthenticated(req, res, next) {
100
91
  if (req.isAuthenticated()) return next();
101
92
  res.redirect("/login");
102
93
  }
103
94
 
104
- // تمرير بيانات المستخدم والبوت لكل الصفحات
95
+
105
96
  app.use((req, res, next) => {
106
97
  res.locals.user = req.user || null;
107
98
  res.locals.client = client;
108
99
  res.locals.path = req.path;
109
- res.locals.dashboardEnabled = options.Dashboard !== false; // الإعداد من الكود
100
+ res.locals.dashboardEnabled = options.Dashboard !== false;
110
101
  next();
111
102
  });
112
103
 
113
- // ==================== دالة مساعدة للإحصائيات ====================
104
+
114
105
  function getBotStats() {
115
106
  const uniquePrefixCommands = new Set();
116
107
  if (client.prefixCommands) {
@@ -119,7 +110,7 @@ function dashboard(client, options) {
119
110
  });
120
111
  }
121
112
 
122
- // محاولة الحصول على البادئة من client
113
+
123
114
  const prefix = client.prefix || options.prefix || "-";
124
115
 
125
116
  return {
@@ -141,22 +132,20 @@ function dashboard(client, options) {
141
132
  };
142
133
  }
143
134
 
144
- // ==================== المسارات الرئيسية ====================
145
135
 
146
- // الصفحة الرئيسية
147
136
  app.get("/", (req, res) => {
148
137
  res.render("index", {
149
138
  botStats: getBotStats(),
150
139
  });
151
140
  });
152
141
 
153
- // صفحة تسجيل الدخول
142
+
154
143
  app.get("/login", (req, res) => {
155
144
  if (req.isAuthenticated()) return res.redirect("/dashboard");
156
145
  res.render("login", { botStats: getBotStats() });
157
146
  });
158
147
 
159
- // OAuth2 مع Discord
148
+
160
149
  app.get("/auth/discord", passport.authenticate("discord"));
161
150
 
162
151
  app.get(
@@ -169,16 +158,14 @@ function dashboard(client, options) {
169
158
  }
170
159
  );
171
160
 
172
- // تسجيل الخروج
161
+
173
162
  app.get("/logout", (req, res) => {
174
163
  req.logout(() => {
175
164
  res.redirect("/");
176
165
  });
177
166
  });
178
167
 
179
- // ==================== لوحة التحكم ====================
180
168
 
181
- // لوحة التحكم الرئيسية
182
169
  app.get("/dashboard", isAuthenticated, (req, res) => {
183
170
  const userGuilds = req.user.guilds.filter(
184
171
  (g) => (g.permissions & 0x20) === 0x20 && client.guilds.cache.has(g.id)
@@ -189,7 +176,7 @@ function dashboard(client, options) {
189
176
  });
190
177
  });
191
178
 
192
- // إدارة سيرفر معين - نظرة عامة
179
+
193
180
  app.get("/dashboard/:guildId", isAuthenticated, async (req, res) => {
194
181
  const guild = client.guilds.cache.get(req.params.guildId);
195
182
  if (!guild) return res.redirect("/dashboard");
@@ -199,7 +186,7 @@ function dashboard(client, options) {
199
186
  return res.redirect("/dashboard");
200
187
  }
201
188
 
202
- // جمع إحصائيات السيرفر
189
+
203
190
  let levelCount = 0;
204
191
  let giveawayCount = 0;
205
192
  let blacklistCount = 0;
@@ -233,7 +220,7 @@ function dashboard(client, options) {
233
220
  });
234
221
  });
235
222
 
236
- // ==================== صفحة الأوامر ====================
223
+
237
224
  app.get("/dashboard/:guildId/commands", isAuthenticated, async (req, res) => {
238
225
  const guild = client.guilds.cache.get(req.params.guildId);
239
226
  if (!guild) return res.redirect("/dashboard");
@@ -242,7 +229,7 @@ function dashboard(client, options) {
242
229
  ? Array.from(client.slashCommands.values())
243
230
  : [];
244
231
 
245
- // إزالة التكرارات من prefix commands
232
+
246
233
  const uniquePrefixCommands = [];
247
234
  const seen = new Set();
248
235
  if (client.prefixCommands) {
@@ -263,7 +250,6 @@ function dashboard(client, options) {
263
250
  });
264
251
  });
265
252
 
266
- // ==================== نظام اللفل ====================
267
253
  app.get("/dashboard/:guildId/levels", isAuthenticated, async (req, res) => {
268
254
  const guild = client.guilds.cache.get(req.params.guildId);
269
255
  if (!guild) return res.redirect("/dashboard");
@@ -271,21 +257,20 @@ function dashboard(client, options) {
271
257
  const mongoConnected = mongoose.connection.readyState === 1;
272
258
  let levelConfigDb = null;
273
259
  let configSource = null;
274
- let databaseEnabled = false; // Only true if guild uses Dashboard mode in setLevel
260
+ let databaseEnabled = false;
275
261
 
276
- // Check if modifying via dashboard is allowed
277
262
  const canModify = options.Dashboard !== false;
278
263
 
279
- // Check if guild uses Dashboard mode (Dashboard: true in setLevel)
264
+
280
265
  const usesDashboardMode = client.levelDashboardGuilds && client.levelDashboardGuilds.has(guild.id);
281
266
 
282
- // Get guild config from database
267
+
283
268
  if (mongoConnected) {
284
269
  try {
285
270
  levelConfigDb = await getGuildConfig(guild.id);
286
271
  if (levelConfigDb && usesDashboardMode) {
287
272
  configSource = "database";
288
- databaseEnabled = true; // Config exists AND guild uses Dashboard mode
273
+ databaseEnabled = true;
289
274
  }
290
275
  } catch (e) {
291
276
  console.error("Error fetching level config:", e);
@@ -299,7 +284,7 @@ function dashboard(client, options) {
299
284
  .sort({ totalXP: -1 })
300
285
  .limit(100);
301
286
 
302
- // Fetch members to ensure they are in cache/get real data
287
+
303
288
  const memberIds = rawLeaderboard.map(u => u.userId);
304
289
  const fetchedMembers = await guild.members.fetch({ user: memberIds }).catch(() => new Map());
305
290
 
@@ -318,13 +303,13 @@ function dashboard(client, options) {
318
303
  }
319
304
  }
320
305
 
321
- // Get guild roles for role rewards
306
+
322
307
  const roles = guild.roles.cache
323
308
  .filter((r) => r.id !== guild.id && !r.managed)
324
309
  .map((r) => ({ id: r.id, name: r.name, color: r.hexColor }))
325
310
  .sort((a, b) => a.name.localeCompare(b.name));
326
311
 
327
- // Get guild channels for level up messages
312
+
328
313
  const channels = guild.channels.cache
329
314
  .filter((c) => c.type === 0)
330
315
  .map((c) => ({ id: c.id, name: c.name }))
@@ -345,7 +330,7 @@ function dashboard(client, options) {
345
330
  });
346
331
  });
347
332
 
348
- // Middleware للتحقق من إمكانية التعديل عبر الداش بورد
333
+
349
334
  function canModifySettings(req, res, next) {
350
335
  if (options.Dashboard === false) {
351
336
  return res.status(403).json({ success: false, error: "تم تعطيل التعديل من الداش بورد في ملف الإعدادات الرئيسي للبوت." });
@@ -353,7 +338,7 @@ function dashboard(client, options) {
353
338
  next();
354
339
  }
355
340
 
356
- // API للحصول على بيانات مستخدم
341
+
357
342
  app.get("/api/:guildId/user/:userId", isAuthenticated, async (req, res) => {
358
343
  if (!Level) return res.json({ error: "Level system not available" });
359
344
 
@@ -368,7 +353,7 @@ function dashboard(client, options) {
368
353
  }
369
354
  });
370
355
 
371
- // ==================== نظام الجيف اوي ====================
356
+
372
357
  app.get(
373
358
  "/dashboard/:guildId/giveaways",
374
359
  isAuthenticated,
@@ -396,7 +381,7 @@ function dashboard(client, options) {
396
381
  }
397
382
  );
398
383
 
399
- // API للجيف اوي
384
+
400
385
  app.post(
401
386
  "/api/:guildId/giveaway/:action",
402
387
  isAuthenticated,
@@ -411,20 +396,20 @@ function dashboard(client, options) {
411
396
  if (Gpause) await Gpause(client, messageId);
412
397
  break;
413
398
  case "resume":
414
- // تنفيذ يدوي للاستئناف لأن Gresume في djs-builder يحتوي على خطأ
399
+
415
400
  if (Gresume) await Gresume(client, messageId);
416
401
  break;
417
402
  case "end":
418
- // إنهاء الجيف اوي فوراً بتعديل وقت الانتهاء للوقت الحالي
403
+
419
404
  if (giveaway) {
420
405
  const g = await giveaway.findOne({ messageId });
421
406
  if (g && !g.ended) {
422
- // إذا كان متوقفاً مؤقتاً، نلغي الإيقاف أولاً
407
+
423
408
  await giveaway.findOneAndUpdate(
424
409
  { messageId },
425
410
  { paused: false, endTime: Date.now().toString() }
426
411
  );
427
- // إعطاء Gcheck فرصة للتشغيل
412
+
428
413
  setTimeout(() => Gcheck && Gcheck(client), 1000);
429
414
  }
430
415
  }
@@ -446,8 +431,7 @@ function dashboard(client, options) {
446
431
  }
447
432
  );
448
433
 
449
- // ==================== نظام السجلات (Logs) ====================
450
- // قائمة أنواع الأحداث المدعومة
434
+
451
435
  const LOG_EVENT_TYPES = [
452
436
  { name: "حذف رسالة", value: "messageDelete", icon: "ri-delete-bin-line" },
453
437
  { name: "تعديل رسالة", value: "messageUpdate", icon: "ri-edit-line" },
@@ -500,7 +484,7 @@ function dashboard(client, options) {
500
484
  { name: "تعديل ستيكر", value: "stickerUpdate", icon: "ri-file-edit-line" },
501
485
  ];
502
486
 
503
- // صفحة السجلات
487
+
504
488
  app.get("/dashboard/:guildId/logs", isAuthenticated, async (req, res) => {
505
489
  const guild = client.guilds.cache.get(req.params.guildId);
506
490
  if (!guild) return res.redirect("/dashboard");
@@ -510,14 +494,14 @@ function dashboard(client, options) {
510
494
  return res.redirect("/dashboard");
511
495
  }
512
496
 
513
- // الحصول على بيانات الـ log
497
+
514
498
  const logData = getLogConfigData();
515
499
  const databaseEnabled = logData.databaseEnabled;
516
500
  let logConfig = null;
517
- let configSource = null; // "database" أو "code" أو null
501
+ let configSource = null;
518
502
 
519
503
  if (databaseEnabled) {
520
- // وضع Database - قراءة من قاعدة البيانات
504
+
521
505
  try {
522
506
  logConfig = await Log.findOne({ guildId: guild.id });
523
507
  if (logConfig) configSource = "database";
@@ -525,7 +509,7 @@ function dashboard(client, options) {
525
509
  console.error("Error fetching log config:", e);
526
510
  }
527
511
  } else {
528
- // وضع Code - قراءة من الكود المكتوب
512
+
529
513
  const codeConfig = logData.configs.find((c) => c.guildId === guild.id);
530
514
  if (codeConfig) {
531
515
  logConfig = codeConfig;
@@ -533,13 +517,13 @@ function dashboard(client, options) {
533
517
  }
534
518
  }
535
519
 
536
- // الحصول على قنوات السيرفر النصية
520
+
537
521
  const channels = guild.channels.cache
538
- .filter((c) => c.type === 0) // GuildText
522
+ .filter((c) => c.type === 0)
539
523
  .map((c) => ({ id: c.id, name: c.name }))
540
524
  .sort((a, b) => a.name.localeCompare(b.name));
541
525
 
542
- // حساب الإحصائيات
526
+
543
527
  const disabledEvents = logConfig?.disable?.length || 0;
544
528
  const enabledEvents = LOG_EVENT_TYPES.length - disabledEvents;
545
529
  const customColors = logConfig?.colors
@@ -565,7 +549,7 @@ function dashboard(client, options) {
565
549
  });
566
550
  });
567
551
 
568
- // API - تحديث القناة الافتراضية
552
+
569
553
  app.post("/api/:guildId/logs/channel", isAuthenticated, canModifySettings, async (req, res) => {
570
554
  const logData = getLogConfigData();
571
555
  if (!logData.databaseEnabled)
@@ -580,7 +564,7 @@ function dashboard(client, options) {
580
564
  { guildId, channelId },
581
565
  { upsert: true, new: true }
582
566
  );
583
- // تنظيف الـ cache
567
+
584
568
  if (logData.clearCache) logData.clearCache(guildId);
585
569
  res.json({ success: true });
586
570
  } catch (e) {
@@ -588,7 +572,7 @@ function dashboard(client, options) {
588
572
  }
589
573
  });
590
574
 
591
- // API - تفعيل/تعطيل حدث
575
+
592
576
  app.post("/api/:guildId/logs/toggle", isAuthenticated, canModifySettings, async (req, res) => {
593
577
  const logData = getLogConfigData();
594
578
  if (!logData.databaseEnabled)
@@ -599,21 +583,21 @@ function dashboard(client, options) {
599
583
 
600
584
  try {
601
585
  if (enable) {
602
- // تفعيل (إزالة من قائمة المعطل)
586
+
603
587
  await Log.findOneAndUpdate(
604
588
  { guildId },
605
589
  { $pull: { disable: eventType } },
606
590
  { upsert: true }
607
591
  );
608
592
  } else {
609
- // تعطيل (إضافة لقائمة المعطل)
593
+
610
594
  await Log.findOneAndUpdate(
611
595
  { guildId },
612
596
  { $addToSet: { disable: eventType } },
613
597
  { upsert: true }
614
598
  );
615
599
  }
616
- // تنظيف الـ cache
600
+
617
601
  const logData = getLogConfigData();
618
602
  if (logData.clearCache) logData.clearCache(guildId);
619
603
  res.json({ success: true });
@@ -622,7 +606,7 @@ function dashboard(client, options) {
622
606
  }
623
607
  });
624
608
 
625
- // API - تحديث إعدادات حدث معين
609
+
626
610
  app.post("/api/:guildId/logs/event", isAuthenticated, canModifySettings, async (req, res) => {
627
611
  const logData = getLogConfigData();
628
612
  if (!logData.databaseEnabled)
@@ -637,7 +621,7 @@ function dashboard(client, options) {
637
621
  if (channel) {
638
622
  updateObj[`channels.${eventType}`] = channel;
639
623
  } else {
640
- // إذا كانت فارغة، نحذف القناة المخصصة
624
+
641
625
  await Log.findOneAndUpdate(
642
626
  { guildId },
643
627
  { $unset: { [`channels.${eventType}`]: "" } }
@@ -647,7 +631,7 @@ function dashboard(client, options) {
647
631
  if (color) {
648
632
  updateObj[`colors.${eventType}`] = color;
649
633
  } else {
650
- // إذا كان فارغاً، نحذف اللون المخصص
634
+
651
635
  await Log.findOneAndUpdate(
652
636
  { guildId },
653
637
  { $unset: { [`colors.${eventType}`]: "" } }
@@ -662,7 +646,7 @@ function dashboard(client, options) {
662
646
  );
663
647
  }
664
648
 
665
- // تنظيف الـ cache
649
+
666
650
  const logData2 = getLogConfigData();
667
651
  if (logData2.clearCache) logData2.clearCache(guildId);
668
652
  res.json({ success: true });
@@ -671,7 +655,7 @@ function dashboard(client, options) {
671
655
  }
672
656
  });
673
657
 
674
- // API - إعادة تعيين إعدادات السجلات
658
+
675
659
  app.post("/api/:guildId/logs/reset", isAuthenticated, canModifySettings, async (req, res) => {
676
660
  const logData = getLogConfigData();
677
661
  if (!logData.databaseEnabled)
@@ -681,7 +665,7 @@ function dashboard(client, options) {
681
665
 
682
666
  try {
683
667
  await Log.findOneAndDelete({ guildId });
684
- // تنظيف الـ cache
668
+
685
669
  if (logData.clearCache) logData.clearCache(guildId);
686
670
  res.json({ success: true });
687
671
  } catch (e) {
@@ -689,8 +673,7 @@ function dashboard(client, options) {
689
673
  }
690
674
  });
691
675
 
692
- // ==================== نظام البلاك ليست ====================
693
- // API لإضافة للبلاك ليست
676
+
694
677
  app.post(
695
678
  "/api/guild/:guildId/blacklist",
696
679
  isAuthenticated,
@@ -716,7 +699,7 @@ function dashboard(client, options) {
716
699
  }
717
700
  );
718
701
 
719
- // API لحذف من البلاك ليست
702
+
720
703
  app.delete(
721
704
  "/api/guild/:guildId/blacklist",
722
705
  isAuthenticated,
@@ -739,7 +722,6 @@ function dashboard(client, options) {
739
722
  }
740
723
  );
741
724
 
742
- // ==================== API القائمة السوداء العامة ====================
743
725
  app.get("/api/blacklist/:type", isAuthenticated, async (req, res) => {
744
726
  const { type } = req.params;
745
727
  try {
@@ -783,7 +765,7 @@ function dashboard(client, options) {
783
765
  }
784
766
  });
785
767
 
786
- // API لجلب بيانات مستخدم (عام)
768
+
787
769
  app.get("/api/user/:userId", isAuthenticated, async (req, res) => {
788
770
  try {
789
771
  const user = await client.users
@@ -804,8 +786,7 @@ function dashboard(client, options) {
804
786
  }
805
787
  });
806
788
 
807
- // ==================== API للأعضاء ====================
808
- // الحصول على معلومات عضو
789
+
809
790
  app.get("/api/:guildId/member/:userId", isAuthenticated, async (req, res) => {
810
791
  const guild = client.guilds.cache.get(req.params.guildId);
811
792
  if (!guild) return res.json({ error: "Guild not found" });
@@ -832,7 +813,7 @@ function dashboard(client, options) {
832
813
  }
833
814
  });
834
815
 
835
- // البحث عن أعضاء
816
+
836
817
  app.get("/api/:guildId/members/search", isAuthenticated, async (req, res) => {
837
818
  const guild = client.guilds.cache.get(req.params.guildId);
838
819
  if (!guild) return res.json({ members: [] });
@@ -841,7 +822,7 @@ function dashboard(client, options) {
841
822
  if (query.length < 2) return res.json({ members: [] });
842
823
 
843
824
  try {
844
- // جلب الأعضاء من الكاش
825
+
845
826
  const members = guild.members.cache
846
827
  .filter(
847
828
  (m) =>
@@ -864,8 +845,7 @@ function dashboard(client, options) {
864
845
  }
865
846
  });
866
847
 
867
- // ==================== API للمستويات ====================
868
- // تحديث مستوى مستخدم
848
+
869
849
  app.post("/api/:guildId/level/update", isAuthenticated, canModifySettings, async (req, res) => {
870
850
  const { userId, xp, level } = req.body;
871
851
  const guildId = req.params.guildId;
@@ -874,7 +854,7 @@ function dashboard(client, options) {
874
854
  if (!Level) return res.json({ error: "Level system not available" });
875
855
 
876
856
  if (level !== undefined) {
877
- // تعيين المستوى مباشرة
857
+
878
858
  const config = await getGuildConfig(guildId);
879
859
  const totalXP = xpNeeded(level - 1, config || {});
880
860
  await Level.findOneAndUpdate(
@@ -883,7 +863,7 @@ function dashboard(client, options) {
883
863
  { upsert: true, new: true }
884
864
  );
885
865
  } else if (xp !== undefined) {
886
- // تعيين XP مباشرة
866
+
887
867
  const config = await getGuildConfig(guildId);
888
868
  const newLevel = calculateLevel(xp, config || {});
889
869
  await Level.findOneAndUpdate(
@@ -898,7 +878,7 @@ function dashboard(client, options) {
898
878
  }
899
879
  });
900
880
 
901
- // تعيين مستوى مستخدم مباشرة
881
+
902
882
  app.post("/api/:guildId/level/set", isAuthenticated, canModifySettings, async (req, res) => {
903
883
  const { userId, level } = req.body;
904
884
  const guildId = req.params.guildId;
@@ -918,7 +898,7 @@ function dashboard(client, options) {
918
898
  }
919
899
  });
920
900
 
921
- // تعيين XP مستخدم مباشرة
901
+
922
902
  app.post("/api/:guildId/level/setxp", isAuthenticated, canModifySettings, async (req, res) => {
923
903
  const { userId, xp } = req.body;
924
904
  const guildId = req.params.guildId;
@@ -938,7 +918,7 @@ function dashboard(client, options) {
938
918
  }
939
919
  });
940
920
 
941
- // إضافة XP لمستخدم
921
+
942
922
  app.post("/api/:guildId/level/add", isAuthenticated, canModifySettings, async (req, res) => {
943
923
  const { userId, xp } = req.body;
944
924
  const guildId = req.params.guildId;
@@ -967,7 +947,7 @@ function dashboard(client, options) {
967
947
  }
968
948
  });
969
949
 
970
- // إعادة تعيين مستوى مستخدم (استخدام resetUser)
950
+
971
951
  app.post("/api/:guildId/level/reset", isAuthenticated, canModifySettings, async (req, res) => {
972
952
  const { userId } = req.body;
973
953
  const guildId = req.params.guildId;
@@ -981,7 +961,7 @@ function dashboard(client, options) {
981
961
  }
982
962
  });
983
963
 
984
- // الحصول على ترتيب مستخدم
964
+
985
965
  app.get("/api/:guildId/level/rank/:userId", isAuthenticated, async (req, res) => {
986
966
  const { guildId, userId } = req.params;
987
967
 
@@ -1000,9 +980,7 @@ function dashboard(client, options) {
1000
980
  }
1001
981
  });
1002
982
 
1003
- // ==================== API إعدادات Level System ====================
1004
-
1005
- // الحصول على إعدادات السيرفر
983
+
1006
984
  app.get("/api/:guildId/level/config", isAuthenticated, async (req, res) => {
1007
985
  try {
1008
986
  const config = await getGuildConfig(req.params.guildId);
@@ -1013,7 +991,7 @@ function dashboard(client, options) {
1013
991
  }
1014
992
  });
1015
993
 
1016
- // إضافة/تعديل Role Reward
994
+
1017
995
  app.post("/api/:guildId/level/config/role", isAuthenticated, canModifySettings, async (req, res) => {
1018
996
  const { level, roleId } = req.body;
1019
997
  const guildId = req.params.guildId;
@@ -1035,7 +1013,7 @@ function dashboard(client, options) {
1035
1013
  }
1036
1014
  });
1037
1015
 
1038
- // تحديث إعدادات XP
1016
+
1039
1017
  app.post("/api/:guildId/level/config/xp", isAuthenticated, canModifySettings, async (req, res) => {
1040
1018
  const { minXP, maxXP, xpMultiplier, maxLevel, cooldown, leveling } = req.body;
1041
1019
  const guildId = req.params.guildId;
@@ -1056,9 +1034,9 @@ function dashboard(client, options) {
1056
1034
  }
1057
1035
  });
1058
1036
 
1059
- // إضافة/إزالة قناة من Blacklist
1037
+
1060
1038
  app.post("/api/:guildId/level/config/blacklist", isAuthenticated, canModifySettings, async (req, res) => {
1061
- const { channelId, action } = req.body; // action: "add" | "remove"
1039
+ const { channelId, action } = req.body;
1062
1040
  const guildId = req.params.guildId;
1063
1041
 
1064
1042
  try {
@@ -1078,7 +1056,7 @@ function dashboard(client, options) {
1078
1056
  }
1079
1057
  });
1080
1058
 
1081
- // تفعيل/تعطيل نظام Level للسيرفر
1059
+
1082
1060
  app.post("/api/:guildId/level/config/toggle", isAuthenticated, canModifySettings, async (req, res) => {
1083
1061
  const { disabled } = req.body;
1084
1062
  const guildId = req.params.guildId;
@@ -1091,7 +1069,7 @@ function dashboard(client, options) {
1091
1069
  }
1092
1070
  });
1093
1071
 
1094
- // إعادة تعيين إعدادات السيرفر
1072
+
1095
1073
  app.post("/api/:guildId/level/config/reset", isAuthenticated, canModifySettings, async (req, res) => {
1096
1074
  const guildId = req.params.guildId;
1097
1075
 
@@ -1103,12 +1081,12 @@ function dashboard(client, options) {
1103
1081
  }
1104
1082
  });
1105
1083
 
1106
- // ==================== API للإحصائيات ====================
1084
+
1107
1085
  app.get("/api/stats", (req, res) => {
1108
1086
  res.json(getBotStats());
1109
1087
  });
1110
1088
 
1111
- // API لإحصائيات السيرفر
1089
+
1112
1090
  app.get("/api/:guildId/stats", isAuthenticated, async (req, res) => {
1113
1091
  const guild = client.guilds.cache.get(req.params.guildId);
1114
1092
  if (!guild) return res.json({ error: "Guild not found" });
@@ -1141,12 +1119,12 @@ function dashboard(client, options) {
1141
1119
  });
1142
1120
  });
1143
1121
 
1144
- // ==================== صفحة 404 ====================
1122
+
1145
1123
  app.use((req, res) => {
1146
1124
  res.status(404).render("404", { botStats: getBotStats() });
1147
1125
  });
1148
1126
 
1149
- // تشغيل الخادم
1127
+
1150
1128
  app.listen(port, () => {});
1151
1129
 
1152
1130
  return app;
@@ -209,6 +209,7 @@ function CreateRow(components, rowOnly = false) {
209
209
 
210
210
  selectMenu.setCustomId(id);
211
211
  selectMenu.setPlaceholder(placeholder);
212
+ selectMenu.setRequired(options.required || false);
212
213
 
213
214
  if (min) {
214
215
  selectMenu.setMinValues(Math.min(min, data.length));
@@ -309,6 +310,7 @@ async function CreateModal(options) {
309
310
  ],
310
311
  true,
311
312
  );
313
+
312
314
 
313
315
  const menu = new LabelBuilder().setLabel(
314
316
  options.mine_label || "Select an option",
@@ -325,14 +327,18 @@ async function CreateModal(options) {
325
327
  if (options.mine_description)
326
328
  menu.setDescription(options.mine_description);
327
329
 
330
+
331
+
332
+
328
333
  modal.addLabelComponents(menu);
329
334
  } else if (com.type === "file") {
330
- const { id, label, description } = com.components;
335
+ const { id, label, description, required } = com.components;
331
336
 
332
337
  const fileUpload = new LabelBuilder().setLabel(label);
333
338
  if (description) fileUpload.setDescription(description);
339
+
334
340
  fileUpload.setFileUploadComponent(
335
- new FileUploadBuilder().setCustomId(id),
341
+ new FileUploadBuilder().setCustomId(id).setRequired(required === undefined ? false : required)
336
342
  );
337
343
 
338
344
  modal.addLabelComponents(fileUpload);
package/function/level.js CHANGED
@@ -140,7 +140,7 @@ async function setLevel(client, guilds, callbacks = {}) {
140
140
  client.on("messageCreate", async (msg) => {
141
141
  if (msg.author.bot || !msg.guild) return;
142
142
 
143
- // ✅ Check if guild is in active level system
143
+
144
144
  if (!client.levelGuilds || !client.levelGuilds.has(msg.guild.id)) return;
145
145
 
146
146
  const guildConfig = await getCachedConfig(msg.guild.id);
package/function/log.js CHANGED
@@ -16,7 +16,7 @@ const logschema = new Schema({
16
16
 
17
17
  const Log = model("Log", logschema);
18
18
 
19
- // تخزين بيانات الـ log للداشبورد
19
+
20
20
  let logConfigData = {
21
21
  databaseEnabled: false,
22
22
  configs: []
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "djs-builder",
3
- "version": "0.7.11",
4
- "note": "🎉 Package Update v0.7.11! \n\n- 🎮 NEW: setLevel Function!\n • All-in-one level system setup\n • Automatic message listener\n • Callbacks: onLevelUp, onRoleReward, onXP\n • Dashboard Mode & Code Mode support\n • Auto role rewards on level up\n • Voice XP support via addVoiceXP\n\n- 📊 Level System Improvements!\n • getGuildConfig with full output example\n • updateGuildConfig for programmatic changes\n • XP Calculation Types: line, exponential, balanced, custom\n • Cooldown & Blacklist support\n\n- 🌐 Dashboard System!\n • Discord OAuth2 Login\n • Server, Level, Giveaway & Blacklist Management\n • Logs Management Page\n\n- <:npm:1107014411375353968> Learn more on [NPM](https://www.npmjs.com/package/djs-builder)\n- <:Discord:906936109114753024> DISCORD SERVER : [LINK](https://discord.gg/uYcKCZk3)",
3
+ "version": "0.7.12",
4
+ "note": "🎉 Package Update v0.7.12! \n\n- 🎮 NEW: setLevel Function!\n • All-in-one level system setup\n • Automatic message listener\n • Callbacks: onLevelUp, onRoleReward, onXP\n • Dashboard Mode & Code Mode support\n • Auto role rewards on level up\n • Voice XP support via addVoiceXP\n\n- 📊 Level System Improvements!\n • getGuildConfig with full output example\n • updateGuildConfig for programmatic changes\n • XP Calculation Types: line, exponential, balanced, custom\n • Cooldown & Blacklist support\n\n- 🌐 Dashboard System!\n • Discord OAuth2 Login\n • Server, Level, Giveaway & Blacklist Management\n • Logs Management Page\n\n- <:npm:1107014411375353968> Learn more on [NPM](https://www.npmjs.com/package/djs-builder)\n- <:Discord:906936109114753024> DISCORD SERVER : [LINK](https://discord.gg/uYcKCZk3)",
5
5
  "description": "🎉 Full-featured Discord.js utilities: CreateComponents, CreateModal, Dashboard, Logging & more! 🥏",
6
6
  "main": "handler/starter.js",
7
7
  "dependencies": {