@somehiddenkey/discord-command-utils 2.4.0 → 2.5.1

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
@@ -21,7 +21,7 @@ We will use 3 different kinds of configurations:
21
21
  ### Local configuration
22
22
  Loads the local configuration of that specific bot. It only contains public configs, no secrets, and may thus be included in the git tracing. Load a new instance of your local config through the following code:
23
23
  ```js
24
- export const localConfig = LocalConfig.load("./configs/local_config.json");
24
+ export const localConfig = LocalConfig.load("./config/local_config.json");
25
25
  ```
26
26
 
27
27
  Your local configuration JSON file should look like this:
@@ -64,29 +64,29 @@ You can fetch and cache the value of a guild, channel or role from discordjs, as
64
64
  console.write(globalConfig.main.guild.name); //error: not fetched yet
65
65
  console.write(globalConfig.main.guild.id); //still fine, ID always accessible
66
66
 
67
- await globalConfig.main.guild.fetch();
68
- await globalConfig.main.channels.international.fetch();
67
+ await globalConfig.main.guild.fetchFromBot();
68
+ await globalConfig.main.channels.international.fetchFromBot();
69
69
  console.write(globalConfig.main.guild.name); //uses the cached value
70
70
  ```
71
71
 
72
- Please keep in mind that cached value may contain outdated data! If you call `fetch()` it will either return the cached value or fetch the value once. If you want to reload the value e.g. to read the updated members that are in a specific voicechannel, you must call `refresh()`
72
+ Please keep in mind that cached value may contain outdated data! If you call `fetchFromBot()` it will either return the cached value or fetch the value once. If you want to reload the value e.g. to read the updated members that are in a specific voicechannel, you must call `refreshFromBot()`
73
73
 
74
74
  ```js
75
75
  console.write(globalConfig.main.channels.break_afk.members.length);
76
- //shows the member count at the time of the fetch()
76
+ //shows the member count at the time of the fetchFromBot()
77
77
 
78
- await globalConfig.main.channels.break_afk.refresh();
78
+ await globalConfig.main.channels.break_afk.refreshFromBot();
79
79
  //fetches the value again, and caches it again
80
80
 
81
81
  console.write(globalConfig.main.channels.break_afk.members.length);
82
82
  //shows the now updated member count
83
83
  ```
84
84
 
85
- You can fetch and refresh entire groups or guilds. Please keep in mind that, if you fetch the values of a specific guild, the bot has to actually be part of that server. A value that cannot be fetched will result in an error.
85
+ You can fetch and refreshFromBot entire groups or guilds. Please keep in mind that, if you fetch the values of a specific guild, the bot has to actually be part of that server. A value that cannot be fetched will result in an error.
86
86
 
87
87
  ```js
88
- await globalConfig.community.fetch();
89
- await globalConfig.main.channels.fetch();
88
+ await globalConfig.community.fetchFromBot();
89
+ await globalConfig.main.channels.fetchFromBot();
90
90
 
91
91
  console.write(globalConfig.main.channel.international.name); //uses the cached value
92
92
  ```
@@ -122,7 +122,7 @@ export const db_connection_0 = knex(secretConfig.DatabaseConfig[0]);
122
122
  ```
123
123
  You can initiate the bot with the following code:
124
124
  ```js
125
- bot.login(secretConfig.Token);
125
+ bot.login(secretConfig.token);
126
126
  ```
127
127
  ## Interactions
128
128
  ### Register Interaction
@@ -171,4 +171,4 @@ const rest = interactionContainer.Rest
171
171
  .register(secretConfig.token);
172
172
  ```
173
173
  ## Utils
174
- Contains various check functions to verify the access level of a user as well as useful enums for scoping, community modlevels, etc
174
+ Contains various check functions to verify the access level of a user as well as useful enums for scoping, community modlevels, etc
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@somehiddenkey/discord-command-utils",
3
- "version": "2.4.0",
3
+ "version": "2.5.1",
4
4
  "description": "A utility library for building Discord bot commands using discord.js",
5
5
  "author": {
6
6
  "email": "k3y.throwaway@gmail.com",
@@ -8,6 +8,8 @@ import { Client } from 'discord.js';
8
8
  export default class Fetchable {
9
9
  /** @type {string[]} */
10
10
  _config_keys = [];
11
+ /** @type {Object<string, Proxy<{id: Snowflake, fetch: () => Promise<any>, refreshFromBot: () => Promise<any>}>>} */
12
+ _lazy_values = {};
11
13
 
12
14
  /**
13
15
  * @param {Client} bot
@@ -15,24 +17,25 @@ export default class Fetchable {
15
17
  * @param {((id: Snowflake) => Promise<any>)} fetcher
16
18
  * @returns {Proxy<any>}
17
19
  */
18
- _createLazyObject(id, fetcher) {
20
+ static createLazyObject(id, fetcher) {
19
21
  let cachedObject = null;
20
22
 
21
- return new Proxy(
22
- {},
23
+ const proxy = new Proxy(
24
+ {id},
23
25
  {
24
26
  get(_, prop) {
25
27
  if (prop === "id")
26
28
  return id;
27
29
 
28
- if (prop === "refresh") {
30
+ if (prop === "refreshFromBot") {
29
31
  return async () => {
30
32
  cachedObject = await fetcher(id);
33
+ consola.debug(`Fetched config object with ID ${id}`);
31
34
  return cachedObject;
32
35
  };
33
36
  }
34
37
 
35
- if (prop === "fetch") {
38
+ if (prop === "fetchFromBot") {
36
39
  return async () => {
37
40
  if (!cachedObject){
38
41
  cachedObject = await fetcher(id);
@@ -45,7 +48,7 @@ export default class Fetchable {
45
48
  }
46
49
 
47
50
  if (!cachedObject)
48
- throw new Error(`Cannot access property "${prop}" of unfetched object with ID ${id}. Call "fetch()" first.`);
51
+ throw new Error(`Cannot access property "${prop}" of unfetched object with ID ${id}. Call "fetchFromBot()" first.`);
49
52
 
50
53
  const value = cachedObject[prop];
51
54
  return typeof value === "function"
@@ -54,32 +57,39 @@ export default class Fetchable {
54
57
  }
55
58
  }
56
59
  );
60
+ return proxy;
57
61
  }
58
62
 
59
- constructor(data) {
60
- const lazy = Object.fromEntries(
61
- Object.entries(data).map(([k, v]) => [k, Array.isArray(v) ? new Set(v) : this._createLazyObject(v)])
63
+ constructor(data, fetcher) {
64
+ if(!data)
65
+ return;
66
+
67
+ this._lazy_values = Object.fromEntries(
68
+ Object.entries(data).map(([k, v]) => [k, Array.isArray(v) ? new Set(v) : Fetchable.createLazyObject(v, fetcher)])
62
69
  );
63
70
  this._config_keys = Object.entries(data).filter(([_, v]) => !Array.isArray(v)).map(([k, _]) => k);
64
-
65
- Object.assign(this, lazy);
66
71
  }
67
72
 
68
73
  /**
69
74
  * @returns {Promise<void[]>}
70
75
  */
71
- fetch() {
76
+ fetchFromBot() {
72
77
  return Promise.all(
73
- this._config_keys.map((key) => this[key]?.fetch())
78
+ this._config_keys.map((key) => this[key]?.fetchFromBot())
74
79
  );
75
80
  }
76
81
 
82
+ assingValues() {
83
+ Object.assign(this, this._lazy_values);
84
+ this._lazy_values = {};
85
+ }
86
+
77
87
  /**
78
88
  * @returns {Promise<void[]>}
79
89
  */
80
- refresh() {
90
+ refreshFromBot() {
81
91
  return Promise.all(
82
- this._config_keys.map((key) => this[key]?.refresh())
92
+ this._config_keys.map((key) => this[key]?.refreshFromBot())
83
93
  );
84
94
  }
85
95
  }
@@ -1,5 +1,17 @@
1
1
  /**
2
2
  * @typedef {string} Snowflake
3
+ *
4
+ * @typedef {import('discord.js').GuildBasedChannel} GuildBasedChannel
5
+ * @typedef {GuildBasedChannel & {
6
+ * fetchFromBot(): Promise<GuildBasedChannel>,
7
+ * refreshFromBot(): Promise<GuildBasedChannel>
8
+ * }} FetchableGuildBasedChannel
9
+ *
10
+ * @typedef {import('discord.js').Role} Role
11
+ * @typedef {Role & {
12
+ * fetchFromBot(): Promise<Role>,
13
+ * refreshFromBot(): Promise<Role>
14
+ * }} FetchableRole
3
15
  */
4
16
 
5
17
  import fs from 'fs';
@@ -11,6 +23,7 @@ import GuildStaff from './GlobalConfigStaff.js';
11
23
  import { GuildBased } from '../NestedGlobalConfig.js';
12
24
  import { Client } from 'discord.js';
13
25
  import ConfigError from '../ConfigError.js';
26
+ import consola from 'consola';
14
27
 
15
28
  export default class GlobalConfig {
16
29
  /** @type {GuildMain} */
@@ -1,11 +1,11 @@
1
1
  /**
2
2
  * @typedef {string} Snowflake
3
+ * @typedef {import('./GlobalConfig.js').FetchableGuildBasedChannel} FetchableGuildBasedChannel
4
+ * @typedef {import('./GlobalConfig.js').FetchableRole} FetchableRole
3
5
  */
4
6
 
5
7
  import ConfigError from "../ConfigError.js";
6
- import pkg from 'discord.js';
7
8
  import { GuildBased, ChannelBased, RoleBased } from '../NestedGlobalConfig.js';
8
- const { GuildBasedChannel } = pkg;
9
9
 
10
10
  export default class GuildCommunity extends GuildBased {
11
11
  /** @type {CategoriesCommunity} */
@@ -26,30 +26,51 @@ export default class GuildCommunity extends GuildBased {
26
26
  this.channels = new ChannelsCommunity(data.channels, this.guild);
27
27
  this.logs = new LogsCommunity(data.logs, this.guild);
28
28
  this.roles = new RolesCommunity(data.roles, this.guild);
29
+ this.channels.general
29
30
  }
30
31
  }
31
32
 
32
- class CategoriesCommunity extends ChannelBased {}
33
+ class CategoriesCommunity extends ChannelBased {
34
+ constructor(data, guild) {
35
+ super(data, guild);
36
+ this.assingValues();
37
+ }
38
+ }
33
39
 
34
40
  class ChannelsCommunity extends ChannelBased {
35
- /** @type {GuildBasedChannel} */
41
+ /** @type {FetchableGuildBasedChannel} */
36
42
  general;
37
- /** @type {GuildBasedChannel} */
43
+ /** @type {FetchableGuildBasedChannel} */
38
44
  com_requests;
39
- /** @type {GuildBasedChannel} */
45
+ /** @type {FetchableGuildBasedChannel} */
40
46
  managers;
41
- /** @type {GuildBasedChannel} */
47
+ /** @type {FetchableGuildBasedChannel} */
42
48
  staff;
49
+
50
+ constructor(data, guild) {
51
+ super(data, guild);
52
+ this.assingValues();
53
+ }
43
54
  }
44
55
 
45
56
  class LogsCommunity extends ChannelBased {
46
- /** @type {GuildBasedChannel} */
57
+ /** @type {FetchableGuildBasedChannel} */
47
58
  communities;
59
+
60
+ constructor(data, guild) {
61
+ super(data, guild);
62
+ this.assingValues();
63
+ }
48
64
  }
49
65
 
50
66
  class RolesCommunity extends RoleBased {
51
- /** @type {Role} */
67
+ /** @type {FetchableRole} */
52
68
  staff;
53
- /** @type {Role} */
69
+ /** @type {FetchableRole} */
54
70
  com_manager;
71
+
72
+ constructor(data, guild) {
73
+ super(data, guild);
74
+ this.assingValues();
75
+ }
55
76
  }
@@ -1,11 +1,11 @@
1
1
  /**
2
2
  * @typedef {string} Snowflake
3
+ * @typedef {import('./GlobalConfig.js').FetchableGuildBasedChannel} FetchableGuildBasedChannel
4
+ * @typedef {import('./GlobalConfig.js').FetchableRole} FetchableRole
3
5
  */
4
6
 
5
7
  import ConfigError from "../ConfigError.js";
6
- import pkg, { Role } from 'discord.js';
7
8
  import { GuildBased, ChannelBased, RoleBased } from '../NestedGlobalConfig.js';
8
- const { GuildBasedChannel } = pkg;
9
9
 
10
10
  export default class GuildMain extends GuildBased {
11
11
  /** @type {CategoriesMain} */
@@ -22,10 +22,10 @@ export default class GuildMain extends GuildBased {
22
22
  throw new ConfigError('No data initialized for GlobalConfig');
23
23
 
24
24
  super(data, bot);
25
- this.categories = new CategoriesMain(data.categories, this.guild);
26
- this.channels = new ChannelsMain(data.channels, this.guild);
27
- this.logs = new LogsMain(data.logs, this.guild);
28
- this.roles = new RolesMain(data.roles, this.guild);
25
+ this.categories = new CategoriesMain(data.categories, this);
26
+ this.channels = new ChannelsMain(data.channels, this);
27
+ this.logs = new LogsMain(data.logs, this);
28
+ this.roles = new RolesMain(data.roles, this);
29
29
  }
30
30
  }
31
31
 
@@ -35,29 +35,29 @@ class CategoriesMain extends ChannelBased {
35
35
  /** @type {Set<Snowflake>} */
36
36
  verified_com;
37
37
 
38
- /** @type {GuildBasedChannel} */
38
+ /** @type {FetchableGuildBasedChannel} */
39
39
  chat;
40
- /** @type {GuildBasedChannel} */
40
+ /** @type {FetchableGuildBasedChannel} */
41
41
  chill;
42
- /** @type {GuildBasedChannel} */
42
+ /** @type {FetchableGuildBasedChannel} */
43
43
  events;
44
- /** @type {GuildBasedChannel} */
44
+ /** @type {FetchableGuildBasedChannel} */
45
45
  music;
46
- /** @type {GuildBasedChannel} */
46
+ /** @type {FetchableGuildBasedChannel} */
47
47
  timer_25;
48
- /** @type {GuildBasedChannel} */
48
+ /** @type {FetchableGuildBasedChannel} */
49
49
  timer_50;
50
- /** @type {GuildBasedChannel} */
50
+ /** @type {FetchableGuildBasedChannel} */
51
51
  screen_cam;
52
- /** @type {GuildBasedChannel} */
52
+ /** @type {FetchableGuildBasedChannel} */
53
53
  staff;
54
- /** @type {GuildBasedChannel} */
54
+ /** @type {FetchableGuildBasedChannel} */
55
55
  subjects;
56
- /** @type {GuildBasedChannel} */
56
+ /** @type {FetchableGuildBasedChannel} */
57
57
  subjects_col;
58
- /** @type {GuildBasedChannel} */
58
+ /** @type {FetchableGuildBasedChannel} */
59
59
  subjects_uni;
60
- /** @type {GuildBasedChannel} */
60
+ /** @type {FetchableGuildBasedChannel} */
61
61
  to_do;
62
62
 
63
63
  /** @type {Set<Snowflake>} */
@@ -67,97 +67,110 @@ class CategoriesMain extends ChannelBased {
67
67
 
68
68
  constructor(data, guild) {
69
69
  super(data, guild);
70
+ this.assingValues();
70
71
  this.custom_study_rooms = new Set(data.custom_rooms.concat(data.verified_com));
71
72
  this.study_rooms = new Set([...this.custom_study_rooms, data.music, data.timer_25, data.timer_50, data.screen_cam]);
72
73
  }
73
74
  }
74
75
 
75
76
  class ChannelsMain extends ChannelBased {
76
- /** @type {GuildBasedChannel} */
77
- timer_control;
78
- /** @type {GuildBasedChannel} */
79
- accountability;
80
- /** @type {GuildBasedChannel} */
81
- break_afk;
82
- /** @type {GuildBasedChannel} */
83
- create_room;
84
- /** @type {GuildBasedChannel} */
77
+ /** @type {FetchableGuildBasedChannel} */
78
+ timer_control
79
+ /** @type {FetchableGuildBasedChannel} */
80
+ accountability
81
+ /** @type {FetchableGuildBasedChannel} */
82
+ break_afk
83
+ /** @type {FetchableGuildBasedChannel} */
84
+ create_room
85
+ /** @type {FetchableGuildBasedChannel} */
85
86
  commands;
86
- /** @type {GuildBasedChannel} */
87
+ /** @type {FetchableGuildBasedChannel} */
87
88
  general;
88
- /** @type {GuildBasedChannel} */
89
+ /** @type {FetchableGuildBasedChannel} */
89
90
  international;
90
- /** @type {GuildBasedChannel} */
91
+ /** @type {FetchableGuildBasedChannel} */
91
92
  introductions;
92
- /** @type {GuildBasedChannel} */
93
+ /** @type {FetchableGuildBasedChannel} */
93
94
  mod_commands;
94
- /** @type {GuildBasedChannel} */
95
+ /** @type {FetchableGuildBasedChannel} */
95
96
  support_commands;
96
- /** @type {GuildBasedChannel} */
97
+ /** @type {FetchableGuildBasedChannel} */
97
98
  session_goals;
98
- /** @type {GuildBasedChannel} */
99
+ /** @type {FetchableGuildBasedChannel} */
99
100
  silent_study;
100
- /** @type {GuildBasedChannel} */
101
+ /** @type {FetchableGuildBasedChannel} */
101
102
  welcome;
103
+
104
+ constructor(data, guild) {
105
+ super(data, guild);
106
+ this.assingValues();
107
+ }
102
108
  }
103
109
 
104
110
  class LogsMain extends ChannelBased {
105
- /** @type {GuildBasedChannel} */
106
- error;
107
- /** @type {GuildBasedChannel} */
108
- votekick;
109
- /** @type {GuildBasedChannel} */
110
- room_commands;
111
- /** @type {GuildBasedChannel} */
112
- room_admin;
113
- /** @type {GuildBasedChannel} */
114
- invites;
115
- /** @type {GuildBasedChannel} */
116
- command;
111
+ /** @type {FetchableGuildBasedChannel} */
112
+ error
113
+ /** @type {FetchableGuildBasedChannel} */
114
+ votekick
115
+ /** @type {FetchableGuildBasedChannel} */
116
+ room_commands
117
+ /** @type {FetchableGuildBasedChannel} */
118
+ room_admin
119
+ /** @type {FetchableGuildBasedChannel} */
120
+ invites
121
+ /** @type {FetchableGuildBasedChannel} */
122
+ command
123
+ /** @type {FetchableGuildBasedChannel} */
124
+ communities
125
+
126
+ constructor(data, guild) {
127
+ super(data, guild);
128
+ this.assingValues();
129
+ }
117
130
  }
118
131
 
119
132
  class RolesMain extends RoleBased {
120
- /** @type {Role} */
133
+ /** @type {FetchableRole} */
121
134
  cuckoo_ping;
122
- /** @type {Role} */
135
+ /** @type {FetchableRole} */
123
136
  developer
124
- /** @type {Role} */
137
+ /** @type {FetchableRole} */
125
138
  forest_ping;
126
- /** @type {Role} */
139
+ /** @type {FetchableRole} */
127
140
  helper;
128
- /** @type {Role} */
141
+ /** @type {FetchableRole} */
129
142
  member;
130
- /** @type {Role} */
143
+ /** @type {FetchableRole} */
131
144
  music;
132
- /** @type {Role} */
145
+ /** @type {FetchableRole} */
133
146
  muted;
134
- /** @type {Role} */
147
+ /** @type {FetchableRole} */
135
148
  no_pc;
136
- /** @type {Role} */
149
+ /** @type {FetchableRole} */
137
150
  screen_cam;
138
- /** @type {Role} */
151
+ /** @type {FetchableRole} */
139
152
  studying;
140
- /** @type {Role} */
153
+ /** @type {FetchableRole} */
141
154
  timer_25;
142
- /** @type {Role} */
155
+ /** @type {FetchableRole} */
143
156
  timer_50;
144
- /** @type {Role} */
157
+ /** @type {FetchableRole} */
145
158
  tutor;
146
- /** @type {Role} */
159
+ /** @type {FetchableRole} */
147
160
  verified_com;
148
- /** @type {Role} */
161
+ /** @type {FetchableRole} */
149
162
  water_ping;
150
- /** @type {Role} */
163
+ /** @type {FetchableRole} */
151
164
  deepfocus;
152
- /** @type {Role} */
165
+ /** @type {FetchableRole} */
153
166
  sr_staff;
154
- /** @type {Role} */
167
+ /** @type {FetchableRole} */
155
168
  staff;
156
- /** @type {Role} */
169
+ /** @type {FetchableRole} */
157
170
  jr_staff;
158
- /** @type {Role} */
171
+ /** @type {FetchableRole} */
159
172
  st_team;
160
- /** @type {Role} */
173
+ /** @type {FetchableRole} */
161
174
  coordinator;
162
175
 
163
176
  /** @type {Set<Snowflake>} */
@@ -166,6 +179,7 @@ class RolesMain extends RoleBased {
166
179
 
167
180
  constructor(data, guild) {
168
181
  super(data, guild);
182
+ this.assingValues();
169
183
  this.all_staff = new Set([data.jr_staff, data.sr_staff, data.st_team, data.coordinator]);
170
184
  }
171
185
  }
@@ -1,11 +1,11 @@
1
1
  /**
2
2
  * @typedef {string} Snowflake
3
+ * @typedef {import('./GlobalConfig.js').FetchableGuildBasedChannel} FetchableGuildBasedChannel
4
+ * @typedef {import('./GlobalConfig.js').FetchableRole} FetchableRole
3
5
  */
4
6
 
5
7
  import ConfigError from "../ConfigError.js";
6
- import pkg, {Role} from 'discord.js';
7
8
  import { GuildBased, ChannelBased, RoleBased } from '../NestedGlobalConfig.js';
8
- const { GuildBasedChannel } = pkg;
9
9
 
10
10
  export default class GuildStaff extends GuildBased {
11
11
  /** @type {CategoriesStaff} */
@@ -32,6 +32,11 @@ export default class GuildStaff extends GuildBased {
32
32
  class CategoriesStaff extends ChannelBased {
33
33
  /** @type {GuildBasedChannel} */
34
34
  modmail;
35
+
36
+ constructor(data, guild) {
37
+ super(data, guild);
38
+ this.assingValues();
39
+ }
35
40
  }
36
41
 
37
42
  class ChannelsStaff extends ChannelBased {
@@ -43,28 +48,43 @@ class ChannelsStaff extends ChannelBased {
43
48
  developer;
44
49
  /** @type {GuildBasedChannel} */
45
50
  commands;
51
+
52
+ constructor(data, guild) {
53
+ super(data, guild);
54
+ this.assingValues();
55
+ }
56
+ }
57
+ class LogsStaff extends ChannelBased {
58
+ constructor(data, guild) {
59
+ super(data, guild);
60
+ this.assingValues();
61
+ }
46
62
  }
47
- class LogsStaff extends ChannelBased {}
48
63
 
49
64
  class RolesStaff extends RoleBased {
50
- /** @type {Role} */
65
+ /** @type {FetchableRole} */
51
66
  int_coordinator;
52
- /** @type {Role} */
67
+ /** @type {FetchableRole} */
53
68
  ext_coordinator;
54
- /** @type {Role} */
69
+ /** @type {FetchableRole} */
55
70
  modmail_access;
56
- /** @type {Role} */
71
+ /** @type {FetchableRole} */
57
72
  sr_staff;
58
- /** @type {Role} */
73
+ /** @type {FetchableRole} */
59
74
  staff;
60
- /** @type {Role} */
75
+ /** @type {FetchableRole} */
61
76
  jr_staff;
62
- /** @type {Role} */
77
+ /** @type {FetchableRole} */
63
78
  developer;
64
- /** @type {Role} */
79
+ /** @type {FetchableRole} */
65
80
  sr_developer;
66
- /** @type {Role} */
81
+ /** @type {FetchableRole} */
67
82
  helper;
68
- /** @type {Role} */
83
+ /** @type {FetchableRole} */
69
84
  events;
85
+
86
+ constructor(data, guild) {
87
+ super(data, guild);
88
+ this.assingValues();
89
+ }
70
90
  }
@@ -1,11 +1,11 @@
1
1
  /**
2
2
  * @typedef {string} Snowflake
3
+ * @typedef {import('./GlobalConfig.js').FetchableGuildBasedChannel} FetchableGuildBasedChannel
4
+ * @typedef {import('./GlobalConfig.js').FetchableRole} FetchableRole
3
5
  */
4
6
 
5
7
  import ConfigError from "../ConfigError.js";
6
- import pkg, {Role} from 'discord.js';
7
8
  import { GuildBased, ChannelBased, RoleBased } from '../NestedGlobalConfig.js';
8
- const { GuildBasedChannel } = pkg;
9
9
 
10
10
  export default class GuildTutor extends GuildBased {
11
11
  /** @type {CategoriesTutor} */
@@ -32,6 +32,11 @@ export default class GuildTutor extends GuildBased {
32
32
  class CategoriesTutor extends ChannelBased {
33
33
  /** @type {GuildBasedChannel} */
34
34
  staff;
35
+
36
+ constructor(data, guild) {
37
+ super(data, guild);
38
+ this.assingValues();
39
+ }
35
40
  }
36
41
 
37
42
  class ChannelsTutor extends ChannelBased {
@@ -43,17 +48,32 @@ class ChannelsTutor extends ChannelBased {
43
48
  staff_commands;
44
49
  /** @type {GuildBasedChannel} */
45
50
  applications;
51
+
52
+ constructor(data, guild) {
53
+ super(data, guild);
54
+ this.assingValues();
55
+ }
46
56
  }
47
57
 
48
- class LogsTutor extends ChannelBased {}
58
+ class LogsTutor extends ChannelBased {
59
+ constructor(data, guild) {
60
+ super(data, guild);
61
+ this.assingValues();
62
+ }
63
+ }
49
64
 
50
65
  class RolesTutor extends RoleBased {
51
- /** @type {Role} */
66
+ /** @type {FetchableRole} */
52
67
  staff;
53
- /** @type {Role} */
68
+ /** @type {FetchableRole} */
54
69
  dev;
55
- /** @type {Role} */
70
+ /** @type {FetchableRole} */
56
71
  tutor;
57
- /** @type {Role} */
72
+ /** @type {FetchableRole} */
58
73
  sr_tutor;
74
+
75
+ constructor(data, guild) {
76
+ super(data, guild);
77
+ this.assingValues();
78
+ }
59
79
  }
@@ -7,58 +7,34 @@ import {Guild} from 'discord.js';
7
7
 
8
8
  export class GuildBased extends Fetchable {
9
9
  /** @type {Guild} */
10
- guild;
11
- categories;
12
- channels;
13
- logs;
14
- roles;
15
-
16
- /**
17
- * @param {Snowflake} id
18
- * @returns {Proxy}
19
- */
20
- _createLazyObject(id, bot) {
21
- return super._createLazyObject(id, async (id) => await bot.guilds.fetch(id));
22
- }
10
+ #guild;
23
11
 
24
12
  constructor(data, bot) {
25
- this.guild = this._createLazyObject(data.id, bot);
26
- this._config_keys = Object.keys(data).filter(k => k !== 'id').push('guild');
13
+ super();
14
+ this.#guild = Fetchable.createLazyObject(data.id, async (id) => await bot.guilds.fetch(id));
15
+ this._config_keys = Object.keys(data).filter(k => k !== 'id');
16
+ this._config_keys.push('guild');
27
17
  }
28
- }
29
-
30
- export class ChannelBased extends Fetchable {
31
- /** @type {Guild} */
32
- #guild;
33
18
 
34
- constructor(data, guild) {
35
- this.#guild = guild;
36
- super(data);
19
+ get guild() {
20
+ return this.#guild;
37
21
  }
38
22
 
39
- /**
40
- * @param {Snowflake} id
41
- * @returns {Proxy}
42
- */
43
- _createLazyObject(id) {
44
- return super._createLazyObject(id, async (id) => await this.#guild.fetch().then(guild => guild.channels.fetch(id)));
23
+ async fetchFromBot() {
24
+ const guild = await this.guild.fetchFromBot();
25
+ await super.fetchFromBot();
26
+ return guild;
45
27
  }
46
28
  }
47
29
 
48
- export class RoleBased extends Fetchable {
49
- /** @type {Guild} */
50
- #guild;
51
-
52
- constructor(data, guild) {
53
- this.#guild = guild;
54
- super(data);
30
+ export class ChannelBased extends Fetchable {
31
+ constructor(data, config) {
32
+ super(data, async (id) => await config.guild.fetchFromBot().then(guild => guild.channels.fetch(id)));
55
33
  }
34
+ }
56
35
 
57
- /**
58
- * @param {Snowflake} id
59
- * @returns {Proxy}
60
- */
61
- _createLazyObject(id) {
62
- return super._createLazyObject(id, async (id) => await this.#guild.fetch().then(guild => guild.roles.fetch(id)));
36
+ export class RoleBased extends Fetchable {
37
+ constructor(data, config) {
38
+ super(data, async (id) => await config.guild.fetchFromBot().then(guild => guild.roles.fetch(id)));
63
39
  }
64
40
  }
@@ -5,6 +5,17 @@ import ConfigError from "./ConfigError.js";
5
5
  * @typedef {{client: string, connection: {host: string, user: string, password: string, database: string}}} DatabaseConfig
6
6
  */
7
7
 
8
+ const levels = {
9
+ silent: -1,
10
+ fatal: 0,
11
+ error: 1,
12
+ warn: 2,
13
+ info: 3,
14
+ debug: 4,
15
+ trace: 5,
16
+ };
17
+ consola.level = levels[process.env.LOG_LEVEL?.toLowerCase() || "info"] ?? 3;
18
+
8
19
  export default class SecretConfig {
9
20
  /** @type {string} */
10
21
  token;