feat!: update to sern v2 (#29)

This commit is contained in:
Jacob Nguyen
2023-03-21 11:30:15 -05:00
committed by GitHub
38 changed files with 13199 additions and 6322 deletions

4
.gitignore vendored
View File

@@ -6,3 +6,7 @@
# Yarn files
.yarn/install-state.gz
.yarn/build-state.yml
# Yarn files
.yarn/install-state.gz
.yarn/build-state.yml

File diff suppressed because one or more lines are too long

823
.yarn/releases/yarn-3.3.1.cjs vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -2,4 +2,4 @@ enableGlobalCache: true
nodeLinker: node-modules
yarnPath: .yarn/releases/yarn-3.2.3.cjs
yarnPath: .yarn/releases/yarn-3.3.1.cjs

16563
docs.json

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{
"name": "sern-community",
"version": "1.1.0",
"version": "2.0.0",
"description": "",
"main": "dist/src/index.js",
"type": "module",
@@ -27,18 +27,19 @@
],
"license": "MIT",
"dependencies": {
"@sern/handler": "1.2.1",
"discord.js": "14.5.0",
"dotenv": "16.0.2",
"@sern/handler": "2.6.1",
"discord.js": "14.8.0",
"dotenv": "16.0.3",
"jsdoc-parse-plus": "1.3.0",
"string-similarity": "4.0.4",
"trie-search": "1.3.6",
"undici": "5.10.0"
"undici": "5.14.0",
"winston": "3.8.2"
},
"devDependencies": {
"@types/node": "18.7.23",
"@types/node": "18.11.18",
"@types/string-similarity": "4.0.0",
"tsup": "6.2.3"
"tsup": "6.5.0"
},
"packageManager": "yarn@3.2.3"
"packageManager": "yarn@3.3.1"
}

View File

@@ -1,4 +1,3 @@
import { commandModule, CommandType } from "@sern/handler";
import {
ActionRowBuilder,
ApplicationCommandOptionType,
@@ -13,10 +12,10 @@ import {
} from "discord.js";
import { fetch } from "undici";
import { cooldown, publish } from "#plugins";
import { Resolver } from "#utils";
import { Resolver, slashCommand } from "#utils";
export default commandModule({
type: CommandType.Slash,
export default slashCommand({
description: "Submit an emoji",
plugins: [publish({ dmPermission: false }), cooldown.add([["user", "1/15"]])],
options: [
{
@@ -45,7 +44,7 @@ export default commandModule({
],
},
],
async execute(ctx, [, args]) {
execute: async (ctx, [, args]) => {
const command = args.getSubcommand();
await ctx.interaction.deferReply();

View File

@@ -22,7 +22,7 @@ export default commandModule({
}
const { channel, guild, client, user, member, message: msg } = ctx;
if (
["TOKEN", "process.env", "token"].some((e) => code.includes(e)) &&
["TOKEN", "process..env", "token"].some((e) => code.includes(e)) &&
ctx.user.id !== "697795666373640213"
)
return ctx.message.react("❌");

View File

@@ -1,4 +1,3 @@
import { commandModule, CommandType } from "@sern/handler";
import {
ActionRowBuilder,
ApplicationCommandOptionType,
@@ -9,9 +8,9 @@ import {
User,
} from "discord.js";
import { publish } from "#plugins";
import { slashCommand } from "#utils";
export default commandModule({
type: CommandType.Slash,
export default slashCommand({
plugins: [publish({ dmPermission: false })],
description: "wanna win in rps?",
options: [

View File

@@ -1,11 +1,8 @@
import { commandModule, CommandType } from "@sern/handler";
import { ApplicationCommandOptionType } from "discord.js";
import { publish } from "../../plugins/publish.js";
import { TicTacToe } from "../../utils/TicTacToe.js";
import { Timestamp } from "../../utils/Timestamp.js";
import { publish } from "#plugins";
import { slashCommand, Timestamp, TicTacToe } from "#utils";
export default commandModule({
type: CommandType.Slash,
export default slashCommand({
plugins: [publish({ dmPermission: false })],
options: [
{

View File

@@ -1,8 +1,8 @@
import { commandModule, CommandType } from "@sern/handler";
import type { APISelectMenuComponent, GuildMember } from "discord.js";
import type { GuildMember, APIStringSelectComponent } from "discord.js";
export default commandModule({
type: CommandType.MenuSelect,
type: CommandType.StringSelect,
name: "role-menu",
async execute(interaction) {
await interaction.deferReply({ ephemeral: true });
@@ -11,7 +11,7 @@ export default commandModule({
const menuRoles: string[] = (
interaction.message.components[0].components[0]
.data as Readonly<APISelectMenuComponent>
.data as Readonly<APIStringSelectComponent>
).options.map((o: { label: string; value: string }) => o.value);
const member = interaction.member as GuildMember;

35
src/commands/logs.ts Normal file
View File

@@ -0,0 +1,35 @@
import { slashCommand } from "#utils";
import { readFile } from "fs/promises";
import path from "path";
import type { Context, ReplyOptions } from "@sern/handler";
import { ownerOnly, publish } from "#plugins";
import * as fs from "fs";
import { AttachmentBuilder } from "discord.js";
async function ephemeral(ctx: Context, options: ReplyOptions) {
const resolvedOptions =
typeof options == "string" ? { content: options } : options;
await ctx.interaction.editReply({ ...resolvedOptions });
}
export default slashCommand({
description: "Fetch logs",
plugins: [publish(), ownerOnly()],
execute: async (ctx, args) => {
try {
const controller = new AbortController();
const logPath = path.join(process.cwd(), "error.log");
const readHandle = readFile(logPath, { signal: controller.signal });
await ctx.interaction.deferReply({ ephemeral: true });
if (!fs.existsSync(logPath)) {
controller.abort();
}
const log = await readHandle;
await ephemeral(ctx, {
files: [new AttachmentBuilder(log).setName("error.log")],
});
} catch (e) {
await ephemeral(ctx, "Couldn't find log. In dev mode?");
}
},
});

View File

@@ -1,20 +1,18 @@
import { commandModule, CommandType } from "@sern/handler";
import {
ActionRowBuilder,
Collection,
Role,
TextChannel,
SelectMenuBuilder,
StringSelectMenuBuilder,
ApplicationCommandOptionType,
ChannelType,
EmbedBuilder,
} from "discord.js";
import { ownerOnly, publish } from "#plugins";
import { Resolver } from "#utils";
import { Resolver, slashCommand } from "#utils";
export default commandModule({
export default slashCommand({
plugins: [ownerOnly(), publish()],
type: CommandType.Slash,
description: "Select Menu Role",
options: [
{
@@ -73,7 +71,7 @@ export default commandModule({
function createMenu(channel: TextChannel, role: Collection<string, Role>) {
if (!channel || !role) throw new Error("Missing channel or role");
const menu = new SelectMenuBuilder()
const menu = new StringSelectMenuBuilder()
.setCustomId("role-menu")
.setMaxValues(role.size)
.setMinValues(0)
@@ -86,6 +84,6 @@ function createMenu(channel: TextChannel, role: Collection<string, Role>) {
};
})
);
const row = new ActionRowBuilder<SelectMenuBuilder>().setComponents(menu);
const row = new ActionRowBuilder<StringSelectMenuBuilder>().setComponents(menu);
return row;
}

View File

@@ -1,9 +1,7 @@
import { commandModule, CommandType } from "@sern/handler";
import { publish } from "#plugins";
import { Timestamp } from "#utils";
import { Timestamp, slashCommand } from "#utils";
export default commandModule({
type: CommandType.Slash,
export default slashCommand({
plugins: [publish()],
description: "Pong!",
execute: async (context) => {

View File

@@ -1,9 +1,9 @@
import { commandModule, CommandType } from "@sern/handler";
import { ApplicationCommandOptionType, EmbedBuilder } from "discord.js";
import { cooldown, publish } from "#plugins";
import { parse } from "jsdoc-parse-plus";
export default commandModule({
type: CommandType.Slash,
import { slashCommand } from "#utils";
export default slashCommand({
description: "View sern plugins",
options: [
{

View File

@@ -1,12 +1,11 @@
import { commandModule, CommandType } from "@sern/handler";
import { Collection, Client } from "discord.js";
import { fetch } from "undici";
import type { Data } from "./plugin.js";
import { ownerOnly, publish, refreshCache } from "#plugins";
import { Evo } from "#constants";
import { slashCommand } from "#utils";
export default commandModule({
type: CommandType.Slash,
export default slashCommand({
plugins: [
refreshCache(),
publish({

View File

@@ -1,15 +1,13 @@
import { commandModule, CommandType } from "@sern/handler";
import { ChannelType } from "discord.js";
import { publish, channelOnly } from "#plugins";
import { ownerIDs } from "#constants";
import { Timestamp } from "#utils";
import { forumID, ownerIDs } from "#constants";
import { Timestamp, slashCommand } from "#utils";
export default commandModule({
type: CommandType.Slash,
export default slashCommand({
description: "Solved the issue? Close the post!",
plugins: [
publish({ guildIds: ["889026545715400705"] }),
channelOnly(["1019807803935825922"]),
channelOnly([forumID]),
],
async execute(ctx) {
if (!ctx.channel) return;

View File

@@ -1,15 +1,13 @@
import { commandModule, CommandType } from "@sern/handler";
import { ApplicationCommandOptionType, EmbedBuilder } from "discord.js";
import { existsSync } from "fs";
import { publish } from "#plugins";
import { Paginator } from "#utils";
import { Paginator, slashCommand } from "#utils";
import { createRequire } from "module";
import type { TagData } from "../types/index.js";
const require = createRequire(import.meta.url);
export default commandModule({
type: CommandType.Slash,
export default slashCommand({
description: "Send a tag",
plugins: [publish()],
options: [

View File

@@ -1,4 +1,3 @@
import { commandModule, CommandType } from "@sern/handler";
import {
ActionRowBuilder,
ApplicationCommandOptionType,
@@ -11,10 +10,11 @@ import { createRequire } from "module";
import { Evo, Seren } from "#constants";
import { ownerOnly, publish } from "#plugins";
import type { TagData } from "../types";
import { slashCommand } from "#utils";
const require = createRequire(import.meta.url);
export default commandModule({
type: CommandType.Slash,
export default slashCommand({
description: "Edit tags",
plugins: [publish(), ownerOnly([Evo, Seren])],
options: [
{

View File

@@ -1,11 +1,10 @@
import { commandModule, CommandType } from "@sern/handler";
import { ApplicationCommandOptionType, GuildMember } from "discord.js";
import { publish } from "#plugins";
import { fetch } from "undici";
import { readFileSync } from "fs";
import { slashCommand } from "#utils";
export default commandModule({
type: CommandType.Slash,
export default slashCommand({
plugins: [publish()],
description: "Get the time of a person.",
options: [

View File

@@ -3,3 +3,4 @@ export const Seren = "182326315813306368";
export const Ropox = "756393473430519849";
export const Mina = "504698587221852172";
export const ownerIDs = [Evo, Seren, Ropox];
export const forumID = "1019807803935825922";

View File

@@ -1,15 +1,13 @@
import { eventModule, EventType } from "@sern/handler";
import { AnyThreadChannel, ChannelType, EmbedBuilder } from "discord.js";
import { AnyThreadChannel, EmbedBuilder } from "discord.js";
import { onCorrectThread } from "../plugins/onCorrectThread.js";
import { forumID } from "#constants";
export default eventModule({
type: EventType.Discord,
plugins: [onCorrectThread(forumID)],
name: "threadCreate",
async execute(thread: AnyThreadChannel, newlyMade: boolean) {
if (!thread.parent) return;
if (thread.parentId !== "1019807803935825922") return;
if (thread.parent.type !== ChannelType.GuildForum) return;
if (!newlyMade) return;
async execute(thread: AnyThreadChannel, _: boolean) {
if (thread.appliedTags.length > 3)
await thread.setAppliedTags(thread.appliedTags.slice(0, 3));

View File

@@ -1,5 +1,6 @@
import { eventModule, EventType } from "@sern/handler";
import type { GuildMember } from "discord.js";
import { useContainer } from "../index.js";
export default eventModule({
type: EventType.Discord,
@@ -7,6 +8,8 @@ export default eventModule({
async execute(member: GuildMember) {
// TODO: This should be inferred
if (member.pending) return;
const [logger] = useContainer("@sern/logger");
logger.info({ message: `${member.user.username} joined` });
const requiredRoles = ["980118655738212407"];
await member.roles.add(requiredRoles);
},

View File

@@ -0,0 +1,32 @@
import {
controller,
EventControlPlugin,
eventModule,
EventType,
Payload,
PayloadType,
} from "@sern/handler";
import { useContainer } from "../index.js";
export default eventModule({
name: "module.activate",
type: EventType.Sern,
plugins: [filterFailedActivation()],
execute(payload: Payload & { type: PayloadType.Failure }) {
const [logger] = useContainer("@sern/logger");
logger.warning({
message: `A module (${payload.module?.name} failed to execute: ${payload.reason}`,
});
},
});
function filterFailedActivation() {
return EventControlPlugin<EventType.Sern>(payload => {
if (payload.type == PayloadType.Failure) {
return controller.next();
} else {
return controller.stop();
}
})
}

View File

@@ -1,7 +1,7 @@
import { Client, GatewayIntentBits, Partials } from "discord.js";
import { Sern, SernEmitter } from "@sern/handler";
import { Dependencies, Sern, single, Singleton } from "@sern/handler";
import "dotenv/config";
import { randomStatus } from "./utils/randomStatus.js";
import { randomStatus, SernLogger, /*CommandSyncer*/ } from "#utils";
const client = new Client({
intents: [
@@ -24,18 +24,34 @@ const client = new Client({
},
});
Sern.addExternal(process);
export interface BotDependencies extends Dependencies {
"@sern/client": Singleton<Client>;
"@sern/logger": Singleton<SernLogger>;
}
export const useContainer = Sern.makeDependencies<BotDependencies>({
build: (root) =>
root
.add({ "@sern/client": single(() => client) })
.upsert({ "@sern/logger": single(() => new SernLogger("info")) })
.add({ process: single(() => process) })
// .add(ctx =>
// ({'sync' : single(() => new CommandSyncer(ctx['@sern/logger'], ctx['@sern/client'], ["941002690211766332"]))}
// ))
});
Sern.init({
client,
sernEmitter: new SernEmitter(),
defaultPrefix: "sern",
commands: "dist/src/commands",
events: "dist/src/events",
containerConfig: {
get: useContainer,
},
});
client.once("ready", (client) => {
randomStatus(client);
console.log(`[✅]: Logged in as ${client.user.username}`);
const [logger] = useContainer("@sern/logger");
logger.info({ message: `[✅]: Logged in as ${client.user.username}` });
});
await client.login();

View File

@@ -1,25 +1,20 @@
import { CommandType, EventPlugin, PluginType } from "@sern/handler";
import { CommandType, CommandControlPlugin, controller } from "@sern/handler";
export function channelOnly(
channelIds: string[],
onFail?: string
): EventPlugin<CommandType.Both> {
return {
type: PluginType.Event,
description: "Runs the command only in certain channels",
execute([ctx], controller) {
if (!ctx.channel) throw new Error("Channel not found!");
) {
return CommandControlPlugin<CommandType.Both>((ctx, _) => {
if (!ctx.channel) throw new Error("Channel not found!");
if (
!channelIds.includes(ctx.channel.id) &&
ctx.channel.isThread() &&
!channelIds.includes(ctx.channel.parentId!)
) {
onFail ? ctx.reply({ content: onFail, ephemeral: true }) : null;
return controller.stop();
}
return controller.next();
if (
!channelIds.includes(ctx.channel.id) &&
ctx.channel.isThread() &&
!channelIds.includes(ctx.channel.parentId!)
) {
onFail ? ctx.reply({ content: onFail, ephemeral: true }) : null;
return controller.stop();
}
return controller.next();
},
};
})
}

View File

@@ -1,4 +1,28 @@
import { CommandType, Context, EventPlugin, PluginType } from "@sern/handler";
// @ts-nocheck
/**
* Allows you to set cooldowns (or "ratelimits") for commands
* limits user/channel/guild actions,
* @author @trueharuu [<@504698587221852172>]
* @version 1.0.0
* @example
* ```ts
* import { cooldown } from "../plugins/cooldown";
* import { commandModule } from "@sern/handler";
* export default commandModule({
* plugins: [cooldown.add( [ ['channel', '1/4'] ] )], // limit to 1 action every 4 seconds per channel
* execute: (ctx) => {
* //your code here
* }
* })
* ```
*/
import {
CommandControlPlugin,
CommandType,
Context,
controller,
} from "@sern/handler";
import { GuildMember } from "discord.js";
/**
* actions/seconds
@@ -88,44 +112,38 @@ function add(
| Cooldown
>,
message?: CooldownResponse
): EventPlugin<CommandType.Both> {
) {
const raw = items.map((c) => {
if (!Array.isArray(c)) return c;
return parseCooldown(c[0] as CooldownLocation, c[1]);
}) as Array<Cooldown>;
return CommandControlPlugin<CommandType.Both>(async (context, args) => {
for (const { location, actions, seconds } of raw) {
const id = getPropertyForLocation(context, location);
const cooldown = map.get(id!);
return {
name: "cooldown",
description: "limits user/channel/guild actions",
type: PluginType.Event,
async execute([context], controller) {
for (const { location, actions, seconds } of raw) {
const id = getPropertyForLocation(context, location);
const cooldown = map.get(id);
if (!cooldown) {
map.set(id, 1, seconds * 1000);
continue;
}
if (cooldown >= actions) {
if (message) {
await message({
location,
actions: cooldown,
maxActions: actions,
seconds,
context,
});
}
return controller.stop();
}
map.set(id, cooldown + 1, seconds * 1000);
if (!cooldown) {
map.set(id!, 1, seconds * 1000);
continue;
}
return controller.next();
},
};
if (cooldown >= actions) {
if (message) {
await message({
location,
actions: cooldown,
maxActions: actions,
seconds,
context,
});
}
return controller.stop();
}
map.set(id!, cooldown + 1, seconds * 1000);
}
return controller.next();
});
}
type Location = (value: CooldownString) => ReturnType<typeof add>;

View File

@@ -0,0 +1,19 @@
import { controller, DiscordEventControlPlugin } from "@sern/handler";
import { ChannelType } from "discord.js";
export function onCorrectThread(parentId: string) {
return DiscordEventControlPlugin(
"threadCreate",
(thread, newlyMade) => {
const isBadThread =
!thread.parent ||
thread.parentId !== parentId ||
thread.parent.type !== ChannelType.GuildForum ||
!newlyMade;
if (!isBadThread) {
return controller.next();
}
return controller.stop();
}
)
}

View File

@@ -1,27 +1,38 @@
import { CommandType, EventPlugin, PluginType } from "@sern/handler";
// @ts-nocheck
/**
* This is OwnerOnly plugin, it allows only bot owners to run the command, like eval.
*
* @author @EvolutionX-10 [<@697795666373640213>]
* @version 1.0.0
* @example
* ```ts
* import { ownerOnly } from "../plugins/ownerOnly";
* import { commandModule } from "@sern/handler";
* export default commandModule({
* plugins: [ ownerOnly() ],
* execute: (ctx) => {
* //your code here
* }
* })
* ```
*/
import { CommandType, CommandControlPlugin, controller } from "@sern/handler";
import { ownerIDs } from "#constants";
export function ownerOnly(override?: string[]): EventPlugin<CommandType.Both> {
return {
type: PluginType.Event,
description: "Allows only bot owner to run command",
async execute(event, controller) {
const [ctx] = event;
if ((override ?? ownerIDs).includes(ctx.user.id))
return controller.next();
await ctx.reply({
content: `Not for you! Only these users can run this\n${map(
override ?? ownerIDs
)}`,
ephemeral: true,
allowedMentions: { repliedUser: false },
});
return controller.stop();
function map(s: string[]) {
const userMention = (s: string) => `<@!${s}>`;
return s.map((id) => `\` - \` ${userMention(id)}`).join("\n");
}
},
};
function map(s: string[]) {
const userMention = (s: string) => `<@!${s}>`;
return s.map((id) => `\` - \` ${userMention(id)}`).join("\n");
}
export function ownerOnly(override?: string[]) {
return CommandControlPlugin<CommandType.Both>(async (ctx, args) => {
if ((override ?? ownerIDs).includes(ctx.user.id)) return controller.next();
//* If you want to reply when the command fails due to user not being owner, you can use following
await ctx.reply({
content: `Not for you! Only these users can run this\n${map(override ?? ownerIDs)}`,
ephemeral: true,
allowedMentions: { repliedUser: false },
});
return controller.stop(); //! Important: It stops the execution of command!
});
}

View File

@@ -1,7 +1,26 @@
// @ts-nocheck
/**
* This is publish plugin, it allows you to publish your application commands using the discord.js library with ease.
*
* @author @EvolutionX-10 [<@697795666373640213>]
* @version 2.0.0
* @example
* ```ts
* import { publish } from "../plugins/publish";
* import { commandModule } from "@sern/handler";
* export default commandModule({
* plugins: [ publish() ], // put an object containing permissions, ids for guild commands, boolean for dmPermission
* // plugins: [ publish({ guildIds: ['guildId'], defaultMemberPermissions: 'Administrator'})]
* execute: (ctx) => {
* //your code here
* }
* })
* ```
*/
import {
CommandPlugin,
CommandInitPlugin,
CommandType,
PluginType,
controller,
SernOptionsData,
SlashCommand,
} from "@sern/handler";
@@ -10,113 +29,133 @@ import {
ApplicationCommandType,
PermissionResolvable,
} from "discord.js";
import { useContainer } from "../index.js";
export function publish(
options?: PublishOptions
): CommandPlugin<
| CommandType.Slash
| CommandType.Both
| CommandType.MenuMsg
| CommandType.MenuUser
> {
return {
type: PluginType.Command,
description: "Manage Slash Commands",
name: "slash-auto-publish",
async execute({ client }, { mod: module }, controller) {
const defaultOptions = {
guildIds: [],
dmPermission: undefined,
defaultMemberPermissions: null,
};
export const CommandTypeRaw = {
[CommandType.Both]: ApplicationCommandType.ChatInput,
[CommandType.CtxUser]: ApplicationCommandType.User,
[CommandType.CtxMsg]: ApplicationCommandType.Message,
[CommandType.Slash]: ApplicationCommandType.ChatInput,
} as const;
options = { ...defaultOptions, ...options } as PublishOptions &
ValidPublishOptions;
let { defaultMemberPermissions, dmPermission, guildIds } =
options as unknown as ValidPublishOptions;
export function publish<
T extends
| CommandType.Both
| CommandType.Slash
| CommandType.CtxMsg
| CommandType.CtxUser
>(options?: PublishOptions) {
return CommandInitPlugin<T>(async ({ module }) => {
// Users need to provide their own useContainer function.
const [client] = useContainer("@sern/client");
const defaultOptions = {
guildIds: [],
dmPermission: undefined,
defaultMemberPermissions: null,
};
function c(e: unknown) {
console.error("publish command didnt work for", module.name!);
console.error(e);
}
try {
const commandData = {
type: CommandTypeRaw[module.type],
name: module.name!,
description: [CommandType.Slash, CommandType.Both].includes(
module.type
)
? module.description
: undefined,
options: [CommandType.Slash, CommandType.Both].includes(module.type)
? optionsTransformer((module as SlashCommand).options ?? [])
: [],
defaultMemberPermissions,
dmPermission,
} as ApplicationCommandData;
options = { ...defaultOptions, ...options } as PublishOptions &
ValidPublishOptions;
let { defaultMemberPermissions, dmPermission, guildIds } =
options as unknown as ValidPublishOptions;
if (!guildIds.length) {
const cmd = (await client.application!.commands.fetch()).find(
(c) =>
c.name === module.name && c.type === CommandTypeRaw[module.type]
);
if (cmd) {
if (!cmd.equals(commandData, true)) {
console.log(`Found differences in global command ${module.name}`);
cmd.edit(commandData).then(() => {
console.log(
`${module.name} updated with new data successfully!`
);
});
}
return controller.next();
function c(e: unknown) {
console.error("publish command didnt work for", module.name);
console.error(e);
}
const log =
(...message: any[]) =>
() =>
console.log(...message);
const logged = (...message: any[]) => log(message);
/**
* a local function that returns either one value or the other,
* depending on {t}'s CommandType. If the commandtype of
* this module is CommandType.Both or CommandType.Text or CommandType.Slash,
* return 'is', else return 'els'
* @param t
* @returns S | T
*/
const appCmd = <V extends CommandType, S, T>(t: V) => {
return (is: S, els: T) => ((t & CommandType.Both) !== 0 ? is : els);
};
const curAppType = CommandTypeRaw[module.type];
const createCommandData = () => {
const cmd = appCmd(module.type);
return {
name: module.name,
type: curAppType,
description: cmd(module.description, ""),
options: cmd(
optionsTransformer((module as SlashCommand).options ?? []),
[]
),
defaultMemberPermissions,
dmPermission,
} as ApplicationCommandData;
};
try {
const commandData = createCommandData();
if (!guildIds.length) {
const cmd = (await client.application!.commands.fetch()).find(
(c) => c.name === module.name && c.type === curAppType
);
if (cmd) {
if (!cmd.equals(commandData, true)) {
logged(
`Found differences in global command ${module.name}`
);
cmd.edit(commandData).then(
log(
`${module.name} updated with new data successfully!`
)
);
}
client
.application!.commands.create(commandData)
.then(() => {
console.log("Command created", module.name!);
})
.catch(c);
return controller.next();
}
client
.application!.commands.create(commandData)
.then(log("Command created", module.name))
.catch(c);
return controller.next();
}
for (const id of guildIds) {
const guild = await client.guilds.fetch(id).catch(c);
if (!guild) continue;
const guildcmd = (await guild.commands.fetch()).find(
(c) =>
c.name === module.name && c.type === CommandTypeRaw[module.type]
);
if (guildcmd) {
if (!guildcmd.equals(commandData, true)) {
console.log(`Found differences in command ${module.name}`);
guildcmd
.edit(commandData)
.then(() =>
console.log(
`${module.name} updated with new data successfully!`
)
for (const id of guildIds) {
const guild = await client.guilds.fetch(id).catch(c);
if (!guild) continue;
const guildCmd = (await guild.commands.fetch()).find(
(c) => c.name === module.name && c.type === curAppType
);
if (guildCmd) {
if (!guildCmd.equals(commandData, true)) {
logged(`Found differences in command ${module.name}`);
guildCmd
.edit(commandData)
.then(
log(
`${module.name} updated with new data successfully!`
)
.catch(c);
continue;
}
)
.catch(c);
continue;
}
guild.commands
.create(commandData)
.then(() =>
console.log("Guild Command created", module.name!, guild.name)
)
.catch(c);
continue;
}
return controller.next();
} catch (e) {
console.log("Command did not register" + module.name!);
console.log(e);
return controller.stop();
guild.commands
.create(commandData)
.then(log("Guild Command created", module.name, guild.name))
.catch(c);
}
},
};
return controller.next();
} catch (e) {
logged("Command did not register" + module.name);
logged(e);
return controller.stop();
}
});
}
export function optionsTransformer(ops: Array<SernOptionsData>) {
@@ -125,13 +164,6 @@ export function optionsTransformer(ops: Array<SernOptionsData>) {
);
}
export const CommandTypeRaw = {
[CommandType.Both]: ApplicationCommandType.ChatInput,
[CommandType.MenuMsg]: ApplicationCommandType.Message,
[CommandType.MenuUser]: ApplicationCommandType.User,
[CommandType.Slash]: ApplicationCommandType.ChatInput,
} as const;
export type NonEmptyArray<T extends `${number}` = `${number}`> = [T, ...T[]];
export interface ValidPublishOptions {
@@ -139,11 +171,13 @@ export interface ValidPublishOptions {
dmPermission: boolean;
defaultMemberPermissions: PermissionResolvable;
}
interface GuildPublishOptions {
guildIds?: NonEmptyArray;
defaultMemberPermissions?: PermissionResolvable;
dmPermission?: never;
}
interface GlobalPublishOptions {
defaultMemberPermissions?: PermissionResolvable;
dmPermission?: false;

View File

@@ -1,17 +1,15 @@
import { CommandPlugin, CommandType, PluginType } from "@sern/handler";
import { CommandInitPlugin, CommandPlugin, CommandType, controller, PluginType } from "@sern/handler";
import type { Collection } from "discord.js";
import { cp } from "../commands/refresh.js";
import type { Data } from "../commands/plugin.js";
export function refreshCache(): CommandPlugin<CommandType.Slash> {
return {
type: PluginType.Command,
description: "refreshes cache",
async execute(wrapper, payload, controller) {
const cache = await cp(wrapper.client);
wrapper.client.cache = cache;
return controller.next();
},
};
import { useContainer } from "../../src/index.js";
export function refreshCache() {
return CommandInitPlugin<CommandType.Slash>(async (payload) => {
const [client] = useContainer("@sern/client");
const cache = await cp(client);
client.cache = cache;
return controller.next();
})
}
declare module "discord.js" {

40
src/utils/Logger.ts Normal file
View File

@@ -0,0 +1,40 @@
import type { Logging, LogPayload } from "@sern/handler";
import winston from "winston";
import util from "util";
export class SernLogger implements Logging {
private _winston!: winston.Logger;
public constructor(level: string, isProd = false) {
this._winston = winston.createLogger({
level,
format: winston.format.json(),
});
if (!isProd) {
this._winston.add(
new winston.transports.Console({
format: winston.format.simple(),
})
);
} else {
this._winston.add(
new winston.transports.File({ filename: "error.log" })
);
}
}
public error(payload: LogPayload<unknown>): void {
this._winston.error(payload.message);
}
public warning(payload: LogPayload<unknown>): void {
this._winston.warn(util.format(payload.message));
}
public info(payload: LogPayload<unknown>): void {
this._winston.info(payload.message);
}
public debug(payload: LogPayload<unknown>): void {
this._winston.debug(payload.message);
}
}

View File

@@ -1,7 +1,6 @@
import {
ActionRow,
ActionRowBuilder,
APISelectMenuComponent,
APISelectMenuOption,
ButtonBuilder,
ButtonStyle,
@@ -10,10 +9,11 @@ import {
Message,
MessageActionRowComponent,
RestOrArray,
SelectMenuBuilder,
StringSelectMenuBuilder,
SelectMenuComponentOptionData,
SelectMenuOptionBuilder,
User,
APIStringSelectComponent,
} from "discord.js";
export class Paginator {
@@ -106,7 +106,7 @@ export class Paginator {
message: Message,
embeds: EmbedBuilder[],
rows: (
| ActionRowBuilder<SelectMenuBuilder>
| ActionRowBuilder<StringSelectMenuBuilder>
| ActionRowBuilder<ButtonBuilder>
)[]
) {
@@ -121,7 +121,7 @@ export class Paginator {
interaction: CommandInteraction,
embeds: EmbedBuilder[],
rows: (
| ActionRowBuilder<SelectMenuBuilder>
| ActionRowBuilder<StringSelectMenuBuilder>
| ActionRowBuilder<ButtonBuilder>
)[]
) {
@@ -238,7 +238,7 @@ export class Paginator {
private buildSelect() {
if (this.options.includeSelectMenu === false) return;
const select = new SelectMenuBuilder()
const select = new StringSelectMenuBuilder()
.setCustomId("@paginator/select")
.setMaxValues(1)
.setMinValues(1)
@@ -254,7 +254,9 @@ export class Paginator {
default: i === this.currentCount,
})))
);
const row = new ActionRowBuilder<SelectMenuBuilder>().setComponents(select);
const row = new ActionRowBuilder<StringSelectMenuBuilder>().setComponents(
select
);
return row;
}
@@ -278,7 +280,7 @@ export class Paginator {
private updateSelect(components: ActionRow<MessageActionRowComponent>[]) {
const selectMenuOption = (
components[1].components[0].data as APISelectMenuComponent
components[1].components[0].data as APIStringSelectComponent
).options;
for (const option of selectMenuOption) {
if (option.value === `${this.currentCount}`) option.default = true;

73
src/utils/SyncCommands.ts Normal file
View File

@@ -0,0 +1,73 @@
// import type { SernLogger } from "./Logger";
// import { readdir } from "fs/promises";
// import path from "path";
// import type { Client } from "discord.js";
// import { ApplicationCommandType, basename } from "discord.js";
// import type { BothCommand, CommandModule, ContextMenuMsg, ContextMenuUser, SlashCommand } from "@sern/handler";
// import { CommandType } from "@sern/handler";
//
// async function* getFiles(dir: string): AsyncGenerator<string> {
// const dirents = await readdir(dir, { withFileTypes: true });
// for (const dirent of dirents) {
// const res = path.resolve(dir, dirent.name);
// if (dirent.isDirectory()) {
// yield* getFiles(res);
// } else {
// yield res;
// }
// }
// }
//
// export class CommandSyncer {
// private commandsPath = "dist/src/commands";
//
// constructor(
// private logger: SernLogger,
// private client: Client,
// private scopedGuilds : string[] = []
// ) {
// setTimeout(() => {
// this
// .sync()
// .catch((e) => logger.error({ message: e ?? "Something went wrong with syncing" }));
// }, 20_000)
// }
// private publishable(module: CommandModule) {
// const publishableTypes = (CommandType.Both | CommandType.CtxUser | CommandType.CtxMsg | CommandType.Slash)
// return ((publishableTypes & ~CommandType.Text) & module.type) != 0
// }
// private async handleSlashCommand(module: SlashCommand | BothCommand, resolvedName: string) {
// this.logger.debug({ message: `Checking if ${resolvedName} is already registered` });
// if (this.scopedGuilds.length) {
// for (const guildId of this.scopedGuilds) {
// const guild = await this.client.guilds.fetch(guildId).catch(() => null);
//
// if (!guild) throw new Error(`Found no Guild with id ${guildId}!`);
// console.log(guild.name)
// console.log(await guild.commands.fetch())
// }
// }
// }
// private handleContextMenus(module: ContextMenuUser | ContextMenuMsg, resolvedName: string) {
//
// }
// private async sync() {
// this.logger.info({ message: "Syncing commands" });
// for await(const path of getFiles(this.commandsPath)) {
// const module = await import("file:///"+path).then(imp => imp.default) as CommandModule; //i would retrieve from the module store, but its a little bugged since
// if(this.publishable(module)) {
// const resolvedName = module.name ?? basename(path).slice(0, -3)
// switch(module.type) {
// case CommandType.Both:
// case CommandType.Slash: {
// await this.handleSlashCommand(module, resolvedName)
// } break;
// case CommandType.CtxMsg:
// case CommandType.CtxUser: {
// this.handleContextMenus(module, resolvedName)
// } break;
// }
// }
// }
// }
// }

View File

@@ -0,0 +1,24 @@
import {
AnyCommandPlugin,
BaseOptions,
commandModule,
CommandType,
Context,
SernSubCommandData,
SernSubCommandGroupData,
SlashOptions,
} from "@sern/handler";
export function slashCommand(data: {
name?: string;
description: string;
plugins?: AnyCommandPlugin[];
options?:
| (SernSubCommandData | SernSubCommandGroupData | BaseOptions)[]
| undefined;
execute: (ctx: Context, args: ["slash", SlashOptions]) => any;
}) {
//Weird fix for explicit undefined fields in an object
const resolvedData = { type: CommandType.Slash, ...data } as const;
return commandModule(resolvedData);
}

View File

@@ -6,3 +6,6 @@ export * from "./Timestamp.js";
export * from "./pagination.js";
export * from "./randomStatus.js";
export * from "./codeUpload.js";
export * from "./Logger.js";
export * from "./composable/slashCommand.js";
//export * from './SyncCommands.js';

View File

@@ -15,7 +15,6 @@ const statues: [
];
export function randomStatus(client: Client) {
console.clear();
setInterval(() => {
const shuffledStatuses = shuffleArray(statues);
const [type, name, status] = [...shuffledStatuses].shift()!;

519
yarn.lock
View File

@@ -5,38 +5,75 @@ __metadata:
version: 6
cacheKey: 8
"@discordjs/builders@npm:^1.2.0":
version: 1.2.0
resolution: "@discordjs/builders@npm:1.2.0"
"@colors/colors@npm:1.5.0":
version: 1.5.0
resolution: "@colors/colors@npm:1.5.0"
checksum: d64d5260bed1d5012ae3fc617d38d1afc0329fec05342f4e6b838f46998855ba56e0a73833f4a80fa8378c84810da254f76a8a19c39d038260dc06dc4e007425
languageName: node
linkType: hard
"@dabh/diagnostics@npm:^2.0.2":
version: 2.0.3
resolution: "@dabh/diagnostics@npm:2.0.3"
dependencies:
"@sapphire/shapeshift": ^3.5.1
discord-api-types: ^0.37.3
colorspace: 1.1.x
enabled: 2.0.x
kuler: ^2.0.0
checksum: 4879600c55c8315a0fb85fbb19057bad1adc08f0a080a8cb4e2b63f723c379bfc4283b68123a2b078d367b327dd8df12fcb27464efe791addc0a48b9df6d79a1
languageName: node
linkType: hard
"@discordjs/builders@npm:^1.5.0":
version: 1.5.0
resolution: "@discordjs/builders@npm:1.5.0"
dependencies:
"@discordjs/formatters": ^0.2.0
"@discordjs/util": ^0.2.0
"@sapphire/shapeshift": ^3.8.1
discord-api-types: ^0.37.35
fast-deep-equal: ^3.1.3
ts-mixer: ^6.0.1
tslib: ^2.4.0
checksum: 19949a574496ff353ce4d6c00b7bd2be8e5f8a30b0cee817d8e8e9d83127adfecc1d18bf2ec0e73013cdfb8bbe6da2e3c234cf43a1c776a777efa128038c968f
ts-mixer: ^6.0.3
tslib: ^2.5.0
checksum: 054bf380879412f19ae2ead6731fdce91ff3d3e91c93fa6c689392bffe75748c68ecb9fcd96e5d6119f8b793a485f5a5d4da943c8fdd8048827226755e3f048c
languageName: node
linkType: hard
"@discordjs/collection@npm:^1.1.0":
version: 1.1.0
resolution: "@discordjs/collection@npm:1.1.0"
checksum: 9a78763a181130d91b51d0d93553fd75d09d0aabd6556890a35404bbefe9c5112cb74c3b1e486a213607f6577f9d2d8ee94ee3177652116bac80516e7d3083d6
"@discordjs/collection@npm:^1.4.0":
version: 1.4.0
resolution: "@discordjs/collection@npm:1.4.0"
checksum: fb6da43b3df8eeade104490a024918cb58690db58ef8bdc2e2812ffee7e166c9baae0c244306a8187179ffa17cab679dcd50ea7fde9bf137c76275a608acd6b3
languageName: node
linkType: hard
"@discordjs/rest@npm:^1.2.0":
version: 1.2.0
resolution: "@discordjs/rest@npm:1.2.0"
"@discordjs/formatters@npm:^0.2.0":
version: 0.2.0
resolution: "@discordjs/formatters@npm:0.2.0"
dependencies:
"@discordjs/collection": ^1.1.0
discord-api-types: ^0.37.35
checksum: cc721d1904501910288b48ae4c20df5fb1beff78f2463f780463f7fa7efe661bb739e324fb9e8b2c09aded3ce7cfcc2f58cd3793c0d61da96f87c50f666bf998
languageName: node
linkType: hard
"@discordjs/rest@npm:^1.6.0":
version: 1.6.0
resolution: "@discordjs/rest@npm:1.6.0"
dependencies:
"@discordjs/collection": ^1.4.0
"@discordjs/util": ^0.2.0
"@sapphire/async-queue": ^1.5.0
"@sapphire/snowflake": ^3.2.2
discord-api-types: ^0.37.10
file-type: ^18.0.0
tslib: ^2.4.0
undici: ^5.10.0
checksum: fa414f2a92e94ad587c0a793e5a378cc0597ed062fe1509314b7c29f925b7a9cc013efad8f572f589d520a9dca4f19a4cc2403f14b89d38e6c61aa2292d96cfe
"@sapphire/snowflake": ^3.4.0
discord-api-types: ^0.37.35
file-type: ^18.2.1
tslib: ^2.5.0
undici: ^5.20.0
checksum: 4370919696401b052602b34bc0a421811efb1360eed7f904206e20216cba052a63bf08e0307222523f8c5d8066b08264ae95a8037b2e86969cffba68e18aaefe
languageName: node
linkType: hard
"@discordjs/util@npm:^0.2.0":
version: 0.2.0
resolution: "@discordjs/util@npm:0.2.0"
checksum: 1e6c02a2881c98ccee2ffd34f487b751e1f16bce007e0a3e9fa538170c1ddb3d68e2b1d88c84b3406191ba9dfec3a999a828603a142c359703fc53482269e7fa
languageName: node
linkType: hard
@@ -115,33 +152,31 @@ __metadata:
languageName: node
linkType: hard
"@sapphire/shapeshift@npm:^3.5.1":
version: 3.6.0
resolution: "@sapphire/shapeshift@npm:3.6.0"
"@sapphire/shapeshift@npm:^3.8.1":
version: 3.8.1
resolution: "@sapphire/shapeshift@npm:3.8.1"
dependencies:
fast-deep-equal: ^3.1.3
lodash.uniqwith: ^4.5.0
checksum: 31b426424d064c516144c6eda07dfa0e44d7cbb8309dde919b923aa6ae939faac6384fa4d08db391a8da11efa3a83c18c9be1ebd053ba29403e61f5e2450b788
lodash: ^4.17.21
checksum: 2a5954c76ee9a91506ae269141ffd2d71e05891c7f1618d0acbf3670312f0b473e356f9c3dafe484d8dc89282d7554f1fd7d720a2a3b0e921fb4e969d09513ee
languageName: node
linkType: hard
"@sapphire/snowflake@npm:^3.2.2":
version: 3.2.2
resolution: "@sapphire/snowflake@npm:3.2.2"
checksum: 315fecef4738092c2a2f3509b132b811fcbfa6c98d5d45d951adaf3ca21608be69043bcc137cc6933a7c3e55cbdc066daa5bb484603e6575422b335445b59315
"@sapphire/snowflake@npm:^3.4.0":
version: 3.4.0
resolution: "@sapphire/snowflake@npm:3.4.0"
checksum: 556b7001f33d6edbbbcbca46f6abfa56c732a29e78b693161e358688e688edcb012d2c1bc944e7ffb41bd6c9950d261bc73f95656dc01643361a218b4f5ab985
languageName: node
linkType: hard
"@sern/handler@npm:1.2.1":
version: 1.2.1
resolution: "@sern/handler@npm:1.2.1"
"@sern/handler@npm:2.6.1":
version: 2.6.1
resolution: "@sern/handler@npm:2.6.1"
dependencies:
rxjs: ^7.5.6
ts-pattern: ^4.0.2
iti: ^0.6.0
rxjs: ^7.8.0
ts-results-es: ^3.5.0
peerDependencies:
discord.js: ^14.5.x
checksum: ec194ec682144f6bd5ecf6b990bacd4e6ffcb4ff9425ef142bf048c8f549704ef0bd284ed2ea0a2e3cc83acef390381f32e5b4ca108745149cba4682cb1896aa
checksum: 137220f5833afff0f907821acf4bfb07f4793d092884f706a62b88a7387e323b9ff4a6a0d9438d8ffc2730fc55c1d5d28c2417b95396df59269ada291b62da28
languageName: node
linkType: hard
@@ -159,10 +194,10 @@ __metadata:
languageName: node
linkType: hard
"@types/node@npm:*, @types/node@npm:18.7.23":
version: 18.7.23
resolution: "@types/node@npm:18.7.23"
checksum: 2c8df0830d8345e5cd1ca17feb9cf43fa667aae749888e0a068c5c1b35eaedd2f9b24ed987a0758078395edf7a03681e5e0b7790a518ff7afe1ff6d8459f7b4a
"@types/node@npm:*, @types/node@npm:18.11.18":
version: 18.11.18
resolution: "@types/node@npm:18.11.18"
checksum: 03f17f9480f8d775c8a72da5ea7e9383db5f6d85aa5fefde90dd953a1449bd5e4ffde376f139da4f3744b4c83942166d2a7603969a6f8ea826edfb16e6e3b49d
languageName: node
linkType: hard
@@ -173,12 +208,12 @@ __metadata:
languageName: node
linkType: hard
"@types/ws@npm:^8.5.3":
version: 8.5.3
resolution: "@types/ws@npm:8.5.3"
"@types/ws@npm:^8.5.4":
version: 8.5.4
resolution: "@types/ws@npm:8.5.4"
dependencies:
"@types/node": "*"
checksum: 0ce46f850d41383fcdc2149bcacc86d7232fa7a233f903d2246dff86e31701a02f8566f40af5f8b56d1834779255c04ec6ec78660fe0f9b2a69cf3d71937e4ae
checksum: fefbad20d211929bb996285c4e6f699b12192548afedbe4930ab4384f8a94577c9cd421acaad163cacd36b88649509970a05a0b8f20615b30c501ed5269038d1
languageName: node
linkType: hard
@@ -267,6 +302,13 @@ __metadata:
languageName: node
linkType: hard
"async@npm:^3.2.3":
version: 3.2.4
resolution: "async@npm:3.2.4"
checksum: 43d07459a4e1d09b84a20772414aa684ff4de085cbcaec6eea3c7a8f8150e8c62aa6cd4e699fe8ee93c3a5b324e777d34642531875a0817a35697522c1b02e89
languageName: node
linkType: hard
"balanced-match@npm:^1.0.0":
version: 1.0.2
resolution: "balanced-match@npm:1.0.2"
@@ -309,14 +351,23 @@ __metadata:
languageName: node
linkType: hard
"bundle-require@npm:^3.1.0":
version: 3.1.0
resolution: "bundle-require@npm:3.1.0"
"bundle-require@npm:^3.1.2":
version: 3.1.2
resolution: "bundle-require@npm:3.1.2"
dependencies:
load-tsconfig: ^0.2.0
peerDependencies:
esbuild: ">=0.13"
checksum: e433dd18ad2ccaf9d210040c5ce300a8c60f4caf0472856fd5162ec407f7b5b3e0559e540aa92b7381a18a6ff2b45bbe9270dc2fd7ace17e445e72a9cbc7fa95
checksum: 71f8cb81bcde97825317b0e516b7e479ec70bd2370f55a8f02795c0df6d541e6562c4b9ec0427cc7b5b835103a8dcf306da04e3846fa468146358471490fcf81
languageName: node
linkType: hard
"busboy@npm:^1.6.0":
version: 1.6.0
resolution: "busboy@npm:1.6.0"
dependencies:
streamsearch: ^1.1.0
checksum: 32801e2c0164e12106bf236291a00795c3c4e4b709ae02132883fe8478ba2ae23743b11c5735a0aae8afe65ac4b6ca4568b91f0d9fed1fdbc32ede824a73746e
languageName: node
linkType: hard
@@ -386,6 +437,39 @@ __metadata:
languageName: node
linkType: hard
"color-convert@npm:^1.9.3":
version: 1.9.3
resolution: "color-convert@npm:1.9.3"
dependencies:
color-name: 1.1.3
checksum: fd7a64a17cde98fb923b1dd05c5f2e6f7aefda1b60d67e8d449f9328b4e53b228a428fd38bfeaeb2db2ff6b6503a776a996150b80cdf224062af08a5c8a3a203
languageName: node
linkType: hard
"color-name@npm:1.1.3":
version: 1.1.3
resolution: "color-name@npm:1.1.3"
checksum: 09c5d3e33d2105850153b14466501f2bfb30324a2f76568a408763a3b7433b0e50e5b4ab1947868e65cb101bb7cb75029553f2c333b6d4b8138a73fcc133d69d
languageName: node
linkType: hard
"color-name@npm:^1.0.0":
version: 1.1.4
resolution: "color-name@npm:1.1.4"
checksum: b0445859521eb4021cd0fb0cc1a75cecf67fceecae89b63f62b201cca8d345baf8b952c966862a9d9a2632987d4f6581f0ec8d957dfacece86f0a7919316f610
languageName: node
linkType: hard
"color-string@npm:^1.6.0":
version: 1.9.1
resolution: "color-string@npm:1.9.1"
dependencies:
color-name: ^1.0.0
simple-swizzle: ^0.2.2
checksum: c13fe7cff7885f603f49105827d621ce87f4571d78ba28ef4a3f1a104304748f620615e6bf065ecd2145d0d9dad83a3553f52bb25ede7239d18e9f81622f1cc5
languageName: node
linkType: hard
"color-support@npm:^1.1.3":
version: 1.1.3
resolution: "color-support@npm:1.1.3"
@@ -395,6 +479,26 @@ __metadata:
languageName: node
linkType: hard
"color@npm:^3.1.3":
version: 3.2.1
resolution: "color@npm:3.2.1"
dependencies:
color-convert: ^1.9.3
color-string: ^1.6.0
checksum: f81220e8b774d35865c2561be921f5652117638dcda7ca4029262046e37fc2444ac7bbfdd110cf1fd9c074a4ee5eda8f85944ffbdda26186b602dd9bb05f6400
languageName: node
linkType: hard
"colorspace@npm:1.1.x":
version: 1.1.4
resolution: "colorspace@npm:1.1.4"
dependencies:
color: ^3.1.3
text-hex: 1.0.x
checksum: bb3934ef3c417e961e6d03d7ca60ea6e175947029bfadfcdb65109b01881a1c0ecf9c2b0b59abcd0ee4a0d7c1eae93beed01b0e65848936472270a0b341ebce8
languageName: node
linkType: hard
"commander@npm:^4.0.0":
version: 4.1.1
resolution: "commander@npm:4.1.1"
@@ -462,36 +566,38 @@ __metadata:
languageName: node
linkType: hard
"discord-api-types@npm:^0.37.10, discord-api-types@npm:^0.37.3":
version: 0.37.11
resolution: "discord-api-types@npm:0.37.11"
checksum: 61af711c29dc089f150c0dd41f257e59583d6ef72789bdb63183d328efe73d2df86ef4b6867390ad31441fe3588985a99a2a1ed8fc920b7ba1deda1dceaf5f84
"discord-api-types@npm:^0.37.35":
version: 0.37.36
resolution: "discord-api-types@npm:0.37.36"
checksum: ba3de3640270738c6fcef515a5d3a22069c89973e7d95984a7ddf1633a6e01fef2b99d4524f4535771694f87e4d779aa7511f21e06abd1c25707b4791c29d386
languageName: node
linkType: hard
"discord.js@npm:14.5.0":
version: 14.5.0
resolution: "discord.js@npm:14.5.0"
"discord.js@npm:14.8.0":
version: 14.8.0
resolution: "discord.js@npm:14.8.0"
dependencies:
"@discordjs/builders": ^1.2.0
"@discordjs/collection": ^1.1.0
"@discordjs/rest": ^1.2.0
"@sapphire/snowflake": ^3.2.2
"@types/ws": ^8.5.3
discord-api-types: ^0.37.10
"@discordjs/builders": ^1.5.0
"@discordjs/collection": ^1.4.0
"@discordjs/formatters": ^0.2.0
"@discordjs/rest": ^1.6.0
"@discordjs/util": ^0.2.0
"@sapphire/snowflake": ^3.4.0
"@types/ws": ^8.5.4
discord-api-types: ^0.37.35
fast-deep-equal: ^3.1.3
lodash.snakecase: ^4.1.1
tslib: ^2.4.0
undici: ^5.10.0
ws: ^8.9.0
checksum: 1534ac6a36966c448580a8e26ddde65d6a17dd0874c9b6e99b6534f3a41f97ad0a87e79af852b8e483a2c1d25924476a58be951bb67878a4c268153b099f3f24
tslib: ^2.5.0
undici: ^5.20.0
ws: ^8.12.1
checksum: 47d20ee2c48cb612edd791e5908af120889cdb277b9e8fff0edd4013ce5a2eb459f7492bd01af59b229ac22966c35f8b1ce45b4668d48cee878b4093d6d48bd3
languageName: node
linkType: hard
"dotenv@npm:16.0.2":
version: 16.0.2
resolution: "dotenv@npm:16.0.2"
checksum: ca8f9ca2d67929c7771069f4c31b4e46b9932621009e658e5afd655dde2d69b77642bf36dbc9e72bc170523dfd908a9ee41c26f034c1fdc605ace3b1b4b10faf
"dotenv@npm:16.0.3":
version: 16.0.3
resolution: "dotenv@npm:16.0.3"
checksum: afcf03f373d7a6d62c7e9afea6328e62851d627a4e73f2e12d0a8deae1cd375892004f3021883f8aec85932cd2834b091f568ced92b4774625b321db83b827f8
languageName: node
linkType: hard
@@ -502,6 +608,13 @@ __metadata:
languageName: node
linkType: hard
"enabled@npm:2.0.x":
version: 2.0.0
resolution: "enabled@npm:2.0.0"
checksum: 9d256d89f4e8a46ff988c6a79b22fa814b4ffd82826c4fdacd9b42e9b9465709d3b748866d0ab4d442dfc6002d81de7f7b384146ccd1681f6a7f868d2acca063
languageName: node
linkType: hard
"encoding@npm:^0.1.13":
version: 0.1.13
resolution: "encoding@npm:0.1.13"
@@ -788,14 +901,21 @@ __metadata:
languageName: node
linkType: hard
"file-type@npm:^18.0.0":
version: 18.0.0
resolution: "file-type@npm:18.0.0"
"fecha@npm:^4.2.0":
version: 4.2.3
resolution: "fecha@npm:4.2.3"
checksum: f94e2fb3acf5a7754165d04549460d3ae6c34830394d20c552197e3e000035d69732d74af04b9bed3283bf29fe2a9ebdcc0085e640b0be3cc3658b9726265e31
languageName: node
linkType: hard
"file-type@npm:^18.2.1":
version: 18.2.1
resolution: "file-type@npm:18.2.1"
dependencies:
readable-web-to-node-stream: ^3.0.2
strtok3: ^7.0.0
token-types: ^5.0.1
checksum: 67f5a927b8030e35a4faf9dd9dea9e17bcb042fb61b9851b7dd1b1b3bb3ecfdd9f83bc3bc72686316ea2bac70df652c61e10affa9b5957b1a3d731df4925e3cb
checksum: bbc9381292e96a72ecd892f9f5e1a9a8d3f9717955841346e55891acfe099135bfa149f7dad51f35ee52b5e7e0a1a02d7375061b2800758011682c2e9d96953e
languageName: node
linkType: hard
@@ -808,6 +928,13 @@ __metadata:
languageName: node
linkType: hard
"fn.name@npm:1.x.x":
version: 1.1.0
resolution: "fn.name@npm:1.1.0"
checksum: e357144f48cfc9a7f52a82bbc6c23df7c8de639fce049cac41d41d62cabb740cdb9f14eddc6485e29c933104455bdd7a69bb14a9012cef9cd4fa252a4d0cf293
languageName: node
linkType: hard
"fs-minipass@npm:^2.0.0, fs-minipass@npm:^2.1.0":
version: 2.1.0
resolution: "fs-minipass@npm:2.1.0"
@@ -836,7 +963,7 @@ __metadata:
"fsevents@patch:fsevents@~2.3.2#~builtin<compat/fsevents>":
version: 2.3.2
resolution: "fsevents@patch:fsevents@npm%3A2.3.2#~builtin<compat/fsevents>::version=2.3.2&hash=18f3a7"
resolution: "fsevents@patch:fsevents@npm%3A2.3.2#~builtin<compat/fsevents>::version=2.3.2&hash=df0bf1"
dependencies:
node-gyp: latest
conditions: os=darwin
@@ -1065,6 +1192,13 @@ __metadata:
languageName: node
linkType: hard
"is-arrayish@npm:^0.3.1":
version: 0.3.2
resolution: "is-arrayish@npm:0.3.2"
checksum: 977e64f54d91c8f169b59afcd80ff19227e9f5c791fa28fa2e5bce355cbaf6c2c356711b734656e80c9dd4a854dd7efcf7894402f1031dfc5de5d620775b4d5f
languageName: node
linkType: hard
"is-binary-path@npm:~2.1.0":
version: 2.1.0
resolution: "is-binary-path@npm:2.1.0"
@@ -1125,6 +1259,15 @@ __metadata:
languageName: node
linkType: hard
"iti@npm:^0.6.0":
version: 0.6.0
resolution: "iti@npm:0.6.0"
dependencies:
utility-types: ^3.10.0
checksum: 19e484aa8b00bf57642c73c56b658d06d70d7b5acf5725a6aca9948c6b3c8d1fab18d71fb25f482a13d8c6acac137799fa80e7dbdc97cc24ed5afc94f03811e3
languageName: node
linkType: hard
"jclass@npm:^1.0.1":
version: 1.2.1
resolution: "jclass@npm:1.2.1"
@@ -1146,6 +1289,13 @@ __metadata:
languageName: node
linkType: hard
"kuler@npm:^2.0.0":
version: 2.0.0
resolution: "kuler@npm:2.0.0"
checksum: 9e10b5a1659f9ed8761d38df3c35effabffbd19fc6107324095238e4ef0ff044392cae9ac64a1c2dda26e532426485342226b93806bd97504b174b0dcf04ed81
languageName: node
linkType: hard
"lilconfig@npm:^2.0.5":
version: 2.0.6
resolution: "lilconfig@npm:2.0.6"
@@ -1181,10 +1331,23 @@ __metadata:
languageName: node
linkType: hard
"lodash.uniqwith@npm:^4.5.0":
version: 4.5.0
resolution: "lodash.uniqwith@npm:4.5.0"
checksum: d49a4565ed64efd86674127d321622673c29cde3e060baebc0f30372f22886c61b2ead44709db8c890053db1b9660e8ed689689812c1a485eb5703caa94d1150
"lodash@npm:^4.17.21":
version: 4.17.21
resolution: "lodash@npm:4.17.21"
checksum: eb835a2e51d381e561e508ce932ea50a8e5a68f4ebdd771ea240d3048244a8d13658acbd502cd4829768c56f2e16bdd4340b9ea141297d472517b83868e677f7
languageName: node
linkType: hard
"logform@npm:^2.3.2, logform@npm:^2.4.0":
version: 2.4.2
resolution: "logform@npm:2.4.2"
dependencies:
"@colors/colors": 1.5.0
fecha: ^4.2.0
ms: ^2.1.1
safe-stable-stringify: ^2.3.1
triple-beam: ^1.3.0
checksum: 3d00f4e1ccaf0a86886aabbf66d1f1d207441d5b408f103457da6d64d055aee76c02af4b40a31ca77a1db4cbcdecb007149f731536c39cbd89b7b6ba3dda6d7b
languageName: node
linkType: hard
@@ -1363,7 +1526,7 @@ __metadata:
languageName: node
linkType: hard
"ms@npm:^2.0.0":
"ms@npm:^2.0.0, ms@npm:^2.1.1":
version: 2.1.3
resolution: "ms@npm:2.1.3"
checksum: aa92de608021b242401676e35cfa5aa42dd70cbdc082b916da7fb925c542173e36bce97ea3e804923fe92c0ad991434e4a38327e15a1b5b5f945d66df615ae6d
@@ -1463,6 +1626,15 @@ __metadata:
languageName: node
linkType: hard
"one-time@npm:^1.0.0":
version: 1.0.0
resolution: "one-time@npm:1.0.0"
dependencies:
fn.name: 1.x.x
checksum: fd008d7e992bdec1c67f53a2f9b46381ee12a9b8c309f88b21f0223546003fb47e8ad7c1fd5843751920a8d276c63bd4b45670ef80c61fb3e07dbccc962b5c7d
languageName: node
linkType: hard
"onetime@npm:^5.1.2":
version: 5.1.2
resolution: "onetime@npm:5.1.2"
@@ -1572,7 +1744,7 @@ __metadata:
languageName: node
linkType: hard
"readable-stream@npm:^3.6.0":
"readable-stream@npm:^3.4.0, readable-stream@npm:^3.6.0":
version: 3.6.0
resolution: "readable-stream@npm:3.6.0"
dependencies:
@@ -1633,9 +1805,9 @@ __metadata:
languageName: node
linkType: hard
"rollup@npm:^2.74.1":
version: 2.78.1
resolution: "rollup@npm:2.78.1"
"rollup@npm:^3.2.5":
version: 3.9.1
resolution: "rollup@npm:3.9.1"
dependencies:
fsevents: ~2.3.2
dependenciesMeta:
@@ -1643,7 +1815,7 @@ __metadata:
optional: true
bin:
rollup: dist/bin/rollup
checksum: 9034814383ca5bdb4bea6d499270aeb31cdb0bb884f81b0c6a1d19c63cc973f040e6ee09b7af8a7169dd231c090f4b44ef8b99c4bfdf884aceeb3dcefb8cfa14
checksum: 929cfab6b8bb2e20c28d7a4c3909b53729f4a63d8cc14f3b1a217d5f8e550737ee0903124ba58a1f2e7efd45c596e044a968aa379411731d0e76c910621d7d3f
languageName: node
linkType: hard
@@ -1656,12 +1828,12 @@ __metadata:
languageName: node
linkType: hard
"rxjs@npm:^7.5.6":
version: 7.5.6
resolution: "rxjs@npm:7.5.6"
"rxjs@npm:^7.8.0":
version: 7.8.0
resolution: "rxjs@npm:7.8.0"
dependencies:
tslib: ^2.1.0
checksum: fc05f01364a74dac57490fb3e07ea63b422af04017fae1db641a009073f902ef69f285c5daac31359620dc8d9aee7d81e42b370ca2a8573d1feae0b04329383b
checksum: 61b4d4fd323c1043d8d6ceb91f24183b28bcf5def4f01ca111511d5c6b66755bc5578587fe714ef5d67cf4c9f2e26f4490d4e1d8cabf9bd5967687835e9866a2
languageName: node
linkType: hard
@@ -1672,6 +1844,13 @@ __metadata:
languageName: node
linkType: hard
"safe-stable-stringify@npm:^2.3.1":
version: 2.4.2
resolution: "safe-stable-stringify@npm:2.4.2"
checksum: 0324ba2e40f78cae63e31a02b1c9bdf1b786621f9e8760845608eb9e81aef401944ac2078e5c9c1533cf516aea34d08fa8052ca853637ced84b791caaf1e394e
languageName: node
linkType: hard
"safer-buffer@npm:>= 2.1.2 < 3.0.0":
version: 2.1.2
resolution: "safer-buffer@npm:2.1.2"
@@ -1694,16 +1873,17 @@ __metadata:
version: 0.0.0-use.local
resolution: "sern-community@workspace:."
dependencies:
"@sern/handler": 1.2.1
"@types/node": 18.7.23
"@sern/handler": 2.6.1
"@types/node": 18.11.18
"@types/string-similarity": 4.0.0
discord.js: 14.5.0
dotenv: 16.0.2
discord.js: 14.8.0
dotenv: 16.0.3
jsdoc-parse-plus: 1.3.0
string-similarity: 4.0.4
trie-search: 1.3.6
tsup: 6.2.3
undici: 5.10.0
tsup: 6.5.0
undici: 5.14.0
winston: 3.8.2
languageName: unknown
linkType: soft
@@ -1737,6 +1917,15 @@ __metadata:
languageName: node
linkType: hard
"simple-swizzle@npm:^0.2.2":
version: 0.2.2
resolution: "simple-swizzle@npm:0.2.2"
dependencies:
is-arrayish: ^0.3.1
checksum: a7f3f2ab5c76c4472d5c578df892e857323e452d9f392e1b5cf74b74db66e6294a1e1b8b390b519fa1b96b5b613f2a37db6cffef52c3f1f8f3c5ea64eb2d54c0
languageName: node
linkType: hard
"slash@npm:^3.0.0":
version: 3.0.0
resolution: "slash@npm:3.0.0"
@@ -1790,6 +1979,20 @@ __metadata:
languageName: node
linkType: hard
"stack-trace@npm:0.0.x":
version: 0.0.10
resolution: "stack-trace@npm:0.0.10"
checksum: 473036ad32f8c00e889613153d6454f9be0536d430eb2358ca51cad6b95cea08a3cc33cc0e34de66b0dad221582b08ed2e61ef8e13f4087ab690f388362d6610
languageName: node
linkType: hard
"streamsearch@npm:^1.1.0":
version: 1.1.0
resolution: "streamsearch@npm:1.1.0"
checksum: 1cce16cea8405d7a233d32ca5e00a00169cc0e19fbc02aa839959985f267335d435c07f96e5e0edd0eadc6d39c98d5435fb5bbbdefc62c41834eadc5622ad942
languageName: node
linkType: hard
"string-similarity@npm:4.0.4":
version: 4.0.4
resolution: "string-similarity@npm:4.0.4"
@@ -1874,6 +2077,13 @@ __metadata:
languageName: node
linkType: hard
"text-hex@npm:1.0.x":
version: 1.0.0
resolution: "text-hex@npm:1.0.0"
checksum: 1138f68adc97bf4381a302a24e2352f04992b7b1316c5003767e9b0d3367ffd0dc73d65001ea02b07cd0ecc2a9d186de0cf02f3c2d880b8a522d4ccb9342244a
languageName: node
linkType: hard
"thenify-all@npm:^1.0.0":
version: 1.6.0
resolution: "thenify-all@npm:1.6.0"
@@ -1938,6 +2148,13 @@ __metadata:
languageName: node
linkType: hard
"triple-beam@npm:^1.3.0":
version: 1.3.0
resolution: "triple-beam@npm:1.3.0"
checksum: 7d7b77d8625fb252c126c24984a68de462b538a8fcd1de2abd0a26421629cf3527d48e23b3c2264f08f4a6c3bc40a478a722176f4d7b6a1acc154cb70c359f2b
languageName: node
linkType: hard
"ts-interface-checker@npm:^0.1.9":
version: 0.1.13
resolution: "ts-interface-checker@npm:0.1.13"
@@ -1945,17 +2162,10 @@ __metadata:
languageName: node
linkType: hard
"ts-mixer@npm:^6.0.1":
version: 6.0.1
resolution: "ts-mixer@npm:6.0.1"
checksum: 7050f6e85a24155d18cecdcc0a098d1038991cc498317fcffa9d7a8654c776d417fb97e65de1ce8e7ed54ef4814abd8057d0efb9c3b24e9cc78ac3c0f48bbf53
languageName: node
linkType: hard
"ts-pattern@npm:^4.0.2":
version: 4.0.5
resolution: "ts-pattern@npm:4.0.5"
checksum: b1ecf36afb567ee6adbaee6e885e51775b1a390ed528589ae3bcb1e376412ed0774b54495ffca7be2a324e75268f894d34379b84388930485cf1359b30d5bc8b
"ts-mixer@npm:^6.0.3":
version: 6.0.3
resolution: "ts-mixer@npm:6.0.3"
checksum: 7fbaba0a413bf817835a6a23d46bccf4192dd4d7345b6bae9d594c88acffac35bf4995ef3cce753090c8abcdf2afd16dba8899365584a1f960ccc2a15bf2e2d6
languageName: node
linkType: hard
@@ -1966,18 +2176,25 @@ __metadata:
languageName: node
linkType: hard
"tslib@npm:^2.1.0, tslib@npm:^2.4.0":
version: 2.4.0
resolution: "tslib@npm:2.4.0"
checksum: 8c4aa6a3c5a754bf76aefc38026134180c053b7bd2f81338cb5e5ebf96fefa0f417bff221592bf801077f5bf990562f6264fecbc42cd3309b33872cb6fc3b113
"tslib@npm:^2.1.0":
version: 2.4.1
resolution: "tslib@npm:2.4.1"
checksum: 19480d6e0313292bd6505d4efe096a6b31c70e21cf08b5febf4da62e95c265c8f571f7b36fcc3d1a17e068032f59c269fab3459d6cd3ed6949eafecf64315fca
languageName: node
linkType: hard
"tsup@npm:6.2.3":
version: 6.2.3
resolution: "tsup@npm:6.2.3"
"tslib@npm:^2.5.0":
version: 2.5.0
resolution: "tslib@npm:2.5.0"
checksum: ae3ed5f9ce29932d049908ebfdf21b3a003a85653a9a140d614da6b767a93ef94f460e52c3d787f0e4f383546981713f165037dc2274df212ea9f8a4541004e1
languageName: node
linkType: hard
"tsup@npm:6.5.0":
version: 6.5.0
resolution: "tsup@npm:6.5.0"
dependencies:
bundle-require: ^3.1.0
bundle-require: ^3.1.2
cac: ^6.7.12
chokidar: ^3.5.1
debug: ^4.3.1
@@ -1987,7 +2204,7 @@ __metadata:
joycon: ^3.0.1
postcss-load-config: ^3.0.1
resolve-from: ^5.0.0
rollup: ^2.74.1
rollup: ^3.2.5
source-map: 0.8.0-beta.0
sucrase: ^3.20.3
tree-kill: ^1.2.2
@@ -2005,14 +2222,25 @@ __metadata:
bin:
tsup: dist/cli-default.js
tsup-node: dist/cli-node.js
checksum: f1cb8f4f83a4a304f61d57dc62fb7176d1fa8842485a7dec4c3fd7cb98e169dbdc4bf52c45ff8cede6843b791fe4a0f70579b34684f568af3c2c3cb2f8469af4
checksum: 625082f2a2afc63024ddd54f5aca28372a7b4ec4f7c402f8aacefd0c56d8da7250665dbb4097d40edcf2cbd4168d96ed4593ecb903ab36e625628f375980e266
languageName: node
linkType: hard
"undici@npm:5.10.0, undici@npm:^5.10.0":
version: 5.10.0
resolution: "undici@npm:5.10.0"
checksum: 7ba2b71dccc74cd2bdf645b83e9aaef374ae04855943d0a2f42a3d0b9e5556f37cc9b5156fb5288277a2fa95fd46a56f3ae0d5cf73db3f008d75ec41104b136c
"undici@npm:5.14.0":
version: 5.14.0
resolution: "undici@npm:5.14.0"
dependencies:
busboy: ^1.6.0
checksum: 7a076e44d84b25844b4eb657034437b8b9bb91f17d347de474fdea1d4263ce7ae9406db79cd30de5642519277b4893f43073258bcc8fed420b295da3fdd11b26
languageName: node
linkType: hard
"undici@npm:^5.20.0":
version: 5.21.0
resolution: "undici@npm:5.21.0"
dependencies:
busboy: ^1.6.0
checksum: 013d5fd503b631d607942c511c2ab3f3fa78ebcab302acab998b43176b4815503ec15ed9752c5a47918b3bff8a0137768001d3eb57625b2bb6f6d30d8a794d6c
languageName: node
linkType: hard
@@ -2041,6 +2269,13 @@ __metadata:
languageName: node
linkType: hard
"utility-types@npm:^3.10.0":
version: 3.10.0
resolution: "utility-types@npm:3.10.0"
checksum: 8f274415c6196ab62883b8bd98c9d2f8829b58016e4269aaa1ebd84184ac5dda7dc2ca45800c0d5e0e0650966ba063bf9a412aaeaea6850ca4440a391283d5c8
languageName: node
linkType: hard
"webidl-conversions@npm:^4.0.2":
version: 4.0.2
resolution: "webidl-conversions@npm:4.0.2"
@@ -2079,6 +2314,36 @@ __metadata:
languageName: node
linkType: hard
"winston-transport@npm:^4.5.0":
version: 4.5.0
resolution: "winston-transport@npm:4.5.0"
dependencies:
logform: ^2.3.2
readable-stream: ^3.6.0
triple-beam: ^1.3.0
checksum: a56e5678a80b88a73e77ed998fc6e19d0db19c989a356b137ec236782f2bf58ae4511b11c29163f99391fa4dc12102c7bc5738dcb6543f28877fa2819adc3ee9
languageName: node
linkType: hard
"winston@npm:3.8.2":
version: 3.8.2
resolution: "winston@npm:3.8.2"
dependencies:
"@colors/colors": 1.5.0
"@dabh/diagnostics": ^2.0.2
async: ^3.2.3
is-stream: ^2.0.0
logform: ^2.4.0
one-time: ^1.0.0
readable-stream: ^3.4.0
safe-stable-stringify: ^2.3.1
stack-trace: 0.0.x
triple-beam: ^1.3.0
winston-transport: ^4.5.0
checksum: f7b901798b92ab9e93c850110bf6e98500e9a0e762b62dab410cf928b2a4145533dfa6d3d2b24f7bf0dc94b53808d5bd28aaaeff9a4b43b89ea4c798cce308ea
languageName: node
linkType: hard
"wrappy@npm:1":
version: 1.0.2
resolution: "wrappy@npm:1.0.2"
@@ -2086,18 +2351,18 @@ __metadata:
languageName: node
linkType: hard
"ws@npm:^8.9.0":
version: 8.9.0
resolution: "ws@npm:8.9.0"
"ws@npm:^8.12.1":
version: 8.13.0
resolution: "ws@npm:8.13.0"
peerDependencies:
bufferutil: ^4.0.1
utf-8-validate: ^5.0.2
utf-8-validate: ">=5.0.2"
peerDependenciesMeta:
bufferutil:
optional: true
utf-8-validate:
optional: true
checksum: 23aa0f021b2eb65c108ec4c3e08c0d81ba01f82b500432dfe327fd6be36079c1d81fdb0eac6464d2a0eb49904d34a9ab8c59619d673fa07b8346f83aeb0cbf12
checksum: 53e991bbf928faf5dc6efac9b8eb9ab6497c69feeb94f963d648b7a3530a720b19ec2e0ec037344257e05a4f35bd9ad04d9de6f289615ffb133282031b18c61c
languageName: node
linkType: hard