mirror of
https://github.com/SrIzan10/sern-community.git
synced 2026-05-01 11:05:19 +00:00
feat!: update to sern v2 (#29)
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -6,3 +6,7 @@
|
||||
# Yarn files
|
||||
.yarn/install-state.gz
|
||||
.yarn/build-state.yml
|
||||
|
||||
# Yarn files
|
||||
.yarn/install-state.gz
|
||||
.yarn/build-state.yml
|
||||
|
||||
783
.yarn/releases/yarn-3.2.3.cjs
vendored
783
.yarn/releases/yarn-3.2.3.cjs
vendored
File diff suppressed because one or more lines are too long
823
.yarn/releases/yarn-3.3.1.cjs
vendored
Normal file
823
.yarn/releases/yarn-3.3.1.cjs
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -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
|
||||
|
||||
17
package.json
17
package.json
@@ -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"
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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("❌");
|
||||
|
||||
@@ -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: [
|
||||
|
||||
@@ -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: [
|
||||
{
|
||||
|
||||
@@ -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
35
src/commands/logs.ts
Normal 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?");
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
@@ -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: [
|
||||
{
|
||||
|
||||
@@ -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({
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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: [
|
||||
|
||||
@@ -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: [
|
||||
{
|
||||
|
||||
@@ -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: [
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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));
|
||||
|
||||
|
||||
@@ -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);
|
||||
},
|
||||
|
||||
32
src/events/module.activate.ts
Normal file
32
src/events/module.activate.ts
Normal 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();
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
28
src/index.ts
28
src/index.ts
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
},
|
||||
};
|
||||
})
|
||||
}
|
||||
|
||||
@@ -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>;
|
||||
|
||||
19
src/plugins/onCorrectThread.ts
Normal file
19
src/plugins/onCorrectThread.ts
Normal 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();
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -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!
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
40
src/utils/Logger.ts
Normal 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);
|
||||
}
|
||||
}
|
||||
@@ -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
73
src/utils/SyncCommands.ts
Normal 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;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
24
src/utils/composable/slashCommand.ts
Normal file
24
src/utils/composable/slashCommand.ts
Normal 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);
|
||||
}
|
||||
@@ -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';
|
||||
@@ -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
519
yarn.lock
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user