@hyperneutrino/djs-lite 1.4.6 → 1.5.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.
Files changed (2) hide show
  1. package/index.ts +35 -27
  2. package/package.json +1 -1
package/index.ts CHANGED
@@ -140,14 +140,14 @@ async function loadSubcommands(directory: string): Promise<{
140
140
  const options: ApplicationCommandSubCommandData[] = [];
141
141
  const handlers = new Map<string, Handler<ChatInputCommandInteraction>>();
142
142
 
143
- await importAll({ directory, recursive: false }, async ({ file, relativePath, item }) => {
143
+ await importAll({ directory, recursive: false }, async ({ file, absolutePath, item }) => {
144
144
  if (item instanceof Subcommand) {
145
145
  options.push({ ...item.data, type: ApplicationCommandOptionType.Subcommand });
146
146
  handlers.set(item.data.name, item.handler);
147
- } else throw new Error(`Loading commands failed: export from ${relativePath} (third-level in commands folder) was not an instance of Subcommand.`);
147
+ } else throw new Error(`Loading commands failed: export from ${absolutePath} (third-level in commands folder) was not an instance of Subcommand.`);
148
148
 
149
149
  if (item.data.name !== file.name.replace(/.[^/.]+$/, ""))
150
- throw new Error(`Code style enforcement: name exported from ${relativePath} does not match the filename`);
150
+ throw new Error(`Code style enforcement: name exported from ${absolutePath} does not match the filename`);
151
151
  });
152
152
 
153
153
  return { options, handlers };
@@ -162,7 +162,7 @@ async function loadSubcommandsAndGroups(directory: string): Promise<{
162
162
  const options: (ApplicationCommandSubGroupData | ApplicationCommandSubCommandData)[] = [];
163
163
  const handlers = new Map<string, Handler<ChatInputCommandInteraction>>();
164
164
 
165
- await importAll({ directory, recursive: false }, async ({ file, relativePath, item }) => {
165
+ await importAll({ directory, recursive: false }, async ({ file, absolutePath, relativePath, item }) => {
166
166
  if (item instanceof Subcommand) {
167
167
  options.push({ ...item.data, type: ApplicationCommandOptionType.Subcommand });
168
168
  handlers.set(`/${item.data.name}`, item.handler);
@@ -172,11 +172,11 @@ async function loadSubcommandsAndGroups(directory: string): Promise<{
172
172
  subcommands.handlers.entries().forEach(([key, handler]) => handlers.set(`${item.data.name}/${key}`, handler));
173
173
  } else
174
174
  throw new Error(
175
- `Loading commands failed: export from ${relativePath} (second-level in commands folder) was not an instance of SubcommandGroup or Subcommand.`,
175
+ `Loading commands failed: export from ${absolutePath} (second-level in commands folder) was not an instance of SubcommandGroup or Subcommand.`,
176
176
  );
177
177
 
178
178
  if (item.data.name !== file.name.replace(/.[^/.]+$/, ""))
179
- throw new Error(`Code style enforcement: name exported from ${relativePath} does not match the filename`);
179
+ throw new Error(`Code style enforcement: name exported from ${absolutePath} does not match the filename`);
180
180
  });
181
181
 
182
182
  return {
@@ -185,7 +185,7 @@ async function loadSubcommandsAndGroups(directory: string): Promise<{
185
185
  };
186
186
  }
187
187
 
188
- export async function loadCommands(client: Client<true>, directory: string, options?: { guildId?: string; skipSettingCommands?: boolean }) {
188
+ export async function loadCommands(client: Client<true>, directory: string, guildId?: string) {
189
189
  const commandData: (ChatInputApplicationCommandData | UserApplicationCommandData | MessageApplicationCommandData)[] = [];
190
190
 
191
191
  const slashCommandHandlers = new Map<string, Handler<ChatInputCommandInteraction>>();
@@ -194,7 +194,7 @@ export async function loadCommands(client: Client<true>, directory: string, opti
194
194
 
195
195
  const slashCommandAutocompletes = new Map<string, Handler<AutocompleteInteraction>>();
196
196
 
197
- await importAll({ directory, recursive: false }, async ({ file, relativePath, item }) => {
197
+ await importAll({ directory, recursive: false }, async ({ file, absolutePath, relativePath, item }) => {
198
198
  if (item instanceof SlashCommand) {
199
199
  commandData.push({ ...item.data, type: ApplicationCommandType.ChatInput });
200
200
  slashCommandHandlers.set(item.data.name, item.handler);
@@ -210,11 +210,11 @@ export async function loadCommands(client: Client<true>, directory: string, opti
210
210
  commandData.push({ ...item.data, options });
211
211
  slashCommandHandlers.set(item.data.name, handler);
212
212
  } else {
213
- throw new Error(`Loading commands failed: export from ${relativePath} was not an instance of <Type>Command.`);
213
+ throw new Error(`Loading commands failed: export from ${absolutePath} was not an instance of <Type>Command.`);
214
214
  }
215
215
 
216
216
  if (item.data.name !== file.name.replace(/.[^/.]+$/, ""))
217
- throw new Error(`Code style enforcement: name exported from ${relativePath} does not match the filename`);
217
+ throw new Error(`Code style enforcement: name exported from ${absolutePath} does not match the filename`);
218
218
  });
219
219
 
220
220
  client.on(Events.InteractionCreate, (interaction) => {
@@ -224,19 +224,27 @@ export async function loadCommands(client: Client<true>, directory: string, opti
224
224
  else if (interaction.isAutocomplete()) slashCommandAutocompletes.get(interaction.commandName)?.(interaction);
225
225
  });
226
226
 
227
- if (options?.skipSettingCommands) "Do nothing";
228
- else if (options?.guildId) {
229
- const testGuild = client.guilds.resolve(options.guildId);
230
- if (!testGuild)
231
- throw new Error(
232
- `Provided test guild (${options.guildId}) can not be found, please make sure the bot you started this project on is in this guild.`,
233
- );
234
- await testGuild.commands.set(commandData);
235
- } else {
236
- await client.application.commands.set(commandData);
227
+ const commandDataHasBeenUpdated = await fs
228
+ .readFile(".cache/command-data.json")
229
+ .then((buffer) => buffer.toString("utf-8"))
230
+ .then((string) => JSON.stringify(commandData) !== string)
231
+ .catch(() => true);
232
+
233
+ if (commandDataHasBeenUpdated) {
234
+ await fs.mkdir(".cache", { recursive: true }).catch(() => null);
235
+ await fs.writeFile(".cache/command-data.json", JSON.stringify(commandData)).catch(() => null);
236
+
237
+ if (guildId) {
238
+ const testGuild = client.guilds.resolve(guildId);
239
+ if (!testGuild)
240
+ throw new Error(`Provided test guild (${guildId}) can not be found, please make sure the bot you started this project on is in this guild.`);
241
+ await testGuild.commands.set(commandData);
242
+ } else {
243
+ await client.application.commands.set(commandData);
244
+ }
237
245
  }
238
246
 
239
- return { commands: commandData, slashCommandHandlers, userCommandHandlers, messageCommandHandlers };
247
+ return { commands: commandData, slashCommandHandlers, userCommandHandlers, messageCommandHandlers, setCommands: commandDataHasBeenUpdated };
240
248
  }
241
249
 
242
250
  export async function loadInteractions(client: Client, directory: string, argumentSeparator: string = ":") {
@@ -248,9 +256,9 @@ export async function loadInteractions(client: Client, directory: string, argume
248
256
  const mentionSelectHandlers = new Map<string, Handler<MentionableSelectMenuInteraction>>();
249
257
  const channelSelectHandlers = new Map<string, Handler<ChannelSelectMenuInteraction>>();
250
258
 
251
- await importAll({ directory, recursive: true }, async ({ relativePath, item }) => {
259
+ await importAll({ directory, recursive: true }, async ({ absolutePath, item }) => {
252
260
  const handlerKey = path
253
- .relative(directory, relativePath)
261
+ .relative(path.resolve(directory), absolutePath)
254
262
  .replace(/\.[^/.]+$/, "")
255
263
  .replace(/\\/g, "/");
256
264
 
@@ -261,7 +269,7 @@ export async function loadInteractions(client: Client, directory: string, argume
261
269
  else if (item instanceof RoleSelectHandler) roleSelectHandlers.set(handlerKey, item.handler);
262
270
  else if (item instanceof MentionSelectHandler) mentionSelectHandlers.set(handlerKey, item.handler);
263
271
  else if (item instanceof ChannelSelectHandler) channelSelectHandlers.set(handlerKey, item.handler);
264
- else throw new Error(`Loading interactions failed: export from ${relativePath} was not an instance of <InteractionType>Handler.`);
272
+ else throw new Error(`Loading interactions failed: export from ${absolutePath} was not an instance of <InteractionType>Handler.`);
265
273
  });
266
274
 
267
275
  client.on(Events.InteractionCreate, (interaction) => {
@@ -286,12 +294,12 @@ export async function loadEvents(client: Client, directory: string, recursive: b
286
294
  const handlers: Partial<{ [K in keyof ClientEvents]: ((...args: ClientEvents[K]) => unknown)[] }> = {};
287
295
  const filenames: Partial<{ [K in keyof ClientEvents]: string[] }> = {};
288
296
 
289
- await importAll({ directory, recursive }, async ({ relativePath, item }) => {
297
+ await importAll({ directory, recursive }, async ({ absolutePath, item }) => {
290
298
  if (item instanceof EventHandler) {
291
299
  (handlers[item.event as keyof ClientEvents] ??= []).push(item.handler);
292
- (filenames[item.event as keyof ClientEvents] ??= []).push(path.relative(directory, relativePath));
300
+ (filenames[item.event as keyof ClientEvents] ??= []).push(path.relative(path.resolve(directory), absolutePath));
293
301
  } else {
294
- throw new Error(`Loading events failed: export from ${relativePath} was not an instance of EventHandler<T>.`);
302
+ throw new Error(`Loading events failed: export from ${absolutePath} was not an instance of EventHandler<T>.`);
295
303
  }
296
304
  });
297
305
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@hyperneutrino/djs-lite",
3
3
  "private": false,
4
- "version": "1.4.6",
4
+ "version": "1.5.0",
5
5
  "module": "index.ts",
6
6
  "type": "module",
7
7
  "devDependencies": {