mirror of
https://github.com/sern-handler/sern-community
synced 2026-06-06 01:16:57 +00:00
feat: Write4, moving to version 4, giveaway command (#46)
* fix compile errors * v4 * giveaway progress * forgot to fix warning * 15+ minute should work * giveaway command functional * should now exclude host * date-fns + host excluded * minor fixes + more exclude host --------- Co-authored-by: kingomes <83099848+kingomes@users.noreply.github.com>
This commit is contained in:
@@ -28,7 +28,9 @@
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@octokit/rest": "19.0.7",
|
||||
"@sern/handler": "^3.3.2",
|
||||
"@sern/handler": "^4.0.0",
|
||||
"better-sqlite3": "^11.1.2",
|
||||
"date-fns": "^3.6.0",
|
||||
"discord.js": "^14.14.1",
|
||||
"dotenv": "16.0.3",
|
||||
"jsdoc-parse-plus": "1.3.0",
|
||||
|
||||
@@ -19,6 +19,7 @@ function handleComments(sum: PurpleSummary) {
|
||||
}
|
||||
const docHandler = new DocHandler();
|
||||
docHandler.setup();
|
||||
|
||||
export default commandModule({
|
||||
type: CommandType.Slash,
|
||||
description: "Query documentation",
|
||||
@@ -43,8 +44,8 @@ export default commandModule({
|
||||
},
|
||||
},
|
||||
],
|
||||
execute: async (context, options) => {
|
||||
const option = options[1].getString("search", true);
|
||||
execute: async (context) => {
|
||||
const option = context.options.getString("search", true);
|
||||
const result = docHandler.DocTrie.search(option);
|
||||
|
||||
if (!result.length) {
|
||||
|
||||
@@ -44,15 +44,15 @@ export default slashCommand({
|
||||
],
|
||||
},
|
||||
],
|
||||
execute: async (ctx, [, args]) => {
|
||||
const command = args.getSubcommand();
|
||||
execute: async (ctx) => {
|
||||
const command = ctx.options.getSubcommand();
|
||||
|
||||
await ctx.interaction.deferReply();
|
||||
switch (command) {
|
||||
case "submit": {
|
||||
const attachment = args.getAttachment("attachment");
|
||||
const urlString = args.getString("url");
|
||||
const name = args.getString("name", true);
|
||||
const attachment = ctx.options.getAttachment("attachment");
|
||||
const urlString = ctx.options.getString("url");
|
||||
const name = ctx.options.getString("name", true);
|
||||
const send = sendTo("1014582281907753080", ctx.member as GuildMember, name);
|
||||
|
||||
if (attachment) {
|
||||
@@ -60,11 +60,8 @@ export default slashCommand({
|
||||
attachment,
|
||||
(a) => a.size <= 256_000,
|
||||
(a) => a.contentType?.startsWith("image/") || false,
|
||||
(a) =>
|
||||
["image/png", "image/jpg", "image/gif"].includes(
|
||||
a.contentType ??
|
||||
"Something that is not png or jpg when contentType is null",
|
||||
),
|
||||
(a) => ["image/png", "image/jpg", "image/gif"].includes(
|
||||
a.contentType ?? "Something that is not png or jpg when contentType is null"),
|
||||
);
|
||||
if (!isValidAttachment) {
|
||||
return ctx.interaction.editReply({
|
||||
|
||||
@@ -6,11 +6,10 @@ import { Evo, Seren, Mina } from "#constants";
|
||||
export default commandModule({
|
||||
type: CommandType.Text,
|
||||
description: "Eval something",
|
||||
alias: ["ev"],
|
||||
execute: async (ctx, args) => {
|
||||
execute: async (ctx) => {
|
||||
if (![Evo, Seren, Mina].includes(ctx.user.id)) return;
|
||||
|
||||
let code: string[] | string = args[1];
|
||||
let code: string[] | string = ctx.options;
|
||||
|
||||
code = code.join(" ") as string;
|
||||
if (code.includes("await")) {
|
||||
@@ -45,27 +44,7 @@ export default commandModule({
|
||||
if ((result as string).length > 2000) {
|
||||
channel!.send("Result is too long to send");
|
||||
}
|
||||
|
||||
ctx.channel!.send({ content: result as string });
|
||||
|
||||
function send(id: string, ping = false) {
|
||||
const channel = client.channels.cache.get(id);
|
||||
if (!channel) return;
|
||||
const embed = new EmbedBuilder()
|
||||
.setColor(0xcc5279)
|
||||
.setTitle("v2 is out!")
|
||||
.setThumbnail(client.user?.displayAvatarURL() ?? "")
|
||||
.setImage("https://raw.githubusercontent.com/sern-handler/.github/main/banner.png")
|
||||
.setAuthor({ name: "sern", url: "https://sern.dev/" })
|
||||
.setDescription(
|
||||
`__**Quick Look:**__\n\n${text()}\n\nThank you all for being patient!`,
|
||||
)
|
||||
.setFooter({ text: "Supports DJS v14.7 and above" })
|
||||
.setTimestamp();
|
||||
const content = ping ? "@everyone" : undefined;
|
||||
channel.isTextBased() && channel.send({ content, embeds: [embed] });
|
||||
return "Done sir";
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { publish } from "#plugins";
|
||||
import { CommandType, Service, commandModule } from "@sern/handler";
|
||||
import { CommandType, commandModule } from "@sern/handler";
|
||||
import { ApplicationCommandOptionType } from "discord.js";
|
||||
import { Timestamp } from "#utils";
|
||||
import { Emojis } from "#constants";
|
||||
const prefix = (t: unknown) => (t ? "$" : "#");
|
||||
const octokit = Service("octokit");
|
||||
|
||||
export default commandModule({
|
||||
type: CommandType.Slash,
|
||||
description: "Get info about a PR or issue",
|
||||
@@ -18,7 +18,7 @@ export default commandModule({
|
||||
autocomplete: true,
|
||||
command: {
|
||||
onEvent: [],
|
||||
async execute(ctx) {
|
||||
async execute(ctx, { deps: { octokit } }) {
|
||||
const text = ctx.options.getFocused();
|
||||
const org = await octokit.repos.listForOrg({
|
||||
org: "sern-handler",
|
||||
@@ -32,10 +32,8 @@ export default commandModule({
|
||||
|
||||
const publicRepos = topRepos
|
||||
.filter((r) => !r.private)
|
||||
.map((repo) => ({
|
||||
name: `sern/${repo.name}`,
|
||||
value: repo.name,
|
||||
}));
|
||||
.map((repo) => ({ name: `sern/${repo.name}`,
|
||||
value: repo.name }));
|
||||
|
||||
if (!text.length) {
|
||||
return ctx.respond(publicRepos.slice(0, 25)).catch(() => null);
|
||||
@@ -60,7 +58,7 @@ export default commandModule({
|
||||
autocomplete: true,
|
||||
command: {
|
||||
onEvent: [],
|
||||
async execute(ctx) {
|
||||
async execute(ctx, { deps }) {
|
||||
const text = ctx.options.getFocused();
|
||||
const repo = ctx.options.getString("repo");
|
||||
if (!repo) return ctx.respond([]);
|
||||
@@ -68,7 +66,7 @@ export default commandModule({
|
||||
let search;
|
||||
|
||||
if (text.length) {
|
||||
search = await octokit.search
|
||||
search = await deps.octokit.search
|
||||
.issuesAndPullRequests({
|
||||
q: `repo:sern-handler/${repo} ${text} in:title`,
|
||||
})
|
||||
@@ -76,7 +74,7 @@ export default commandModule({
|
||||
}
|
||||
|
||||
if (!text.length) {
|
||||
const issues = await octokit.issues
|
||||
const issues = await deps.octokit.issues
|
||||
.listForRepo({
|
||||
owner: "sern-handler",
|
||||
repo,
|
||||
@@ -120,10 +118,10 @@ export default commandModule({
|
||||
required: false,
|
||||
},
|
||||
],
|
||||
async execute(ctx, [, options]) {
|
||||
const repo = options.getString("repo", true);
|
||||
const number = options.getInteger("number", true);
|
||||
const target = options.getUser("target");
|
||||
async execute(ctx, { deps: { octokit }}) {
|
||||
const repo = ctx.options.getString("repo", true);
|
||||
const number = ctx.options.getInteger("number", true);
|
||||
const target = ctx.options.getUser("target");
|
||||
|
||||
const issue = await octokit.issues
|
||||
.get({
|
||||
|
||||
165
src/commands/giveaway.ts
Normal file
165
src/commands/giveaway.ts
Normal file
@@ -0,0 +1,165 @@
|
||||
import { commandModule, CommandType, scheduledTask } from "@sern/handler";
|
||||
import { publish } from "#plugins";
|
||||
import { ApplicationCommandOptionType, EmbedBuilder } from "discord.js";
|
||||
import { db } from "../utils/db.js";
|
||||
import { add, addDays, addHours, addMinutes, addSeconds } from "date-fns"
|
||||
import { Timestamp } from "#utils";
|
||||
|
||||
export default commandModule({
|
||||
type: CommandType.Slash,
|
||||
description: "Start a giveaway involving users who react to the embed",
|
||||
plugins: [publish()],
|
||||
options: [
|
||||
{
|
||||
name: "item",
|
||||
description: "The item that will be given away",
|
||||
type: ApplicationCommandOptionType.String,
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: "time",
|
||||
description: "The amount of time that the giveaway will be up",
|
||||
type: ApplicationCommandOptionType.String,
|
||||
required: true
|
||||
}
|
||||
],
|
||||
execute: async (ctx, { deps }) => {
|
||||
const item = ctx.options.getString("item")
|
||||
const timeLeftString = ctx.options.getString("time")
|
||||
|
||||
let timeUnit1
|
||||
let timeLeft1
|
||||
let timeUnit2
|
||||
let timeLeft2
|
||||
|
||||
const [part1, part2] = timeLeftString?.split("and")
|
||||
timeUnit1 = part1?.split(" ")[1]
|
||||
timeLeft1 = Number(part1?.split(" ")[0])
|
||||
|
||||
if (part2) {
|
||||
const timeLeftStringPart2 = part2.replace(part2.substring(0, 1), "")
|
||||
timeUnit2 = timeLeftStringPart2?.split(" ")[1]
|
||||
timeLeft2 = Number(timeLeftStringPart2?.split(" ")[0])
|
||||
}
|
||||
|
||||
const startTime = new Date()
|
||||
|
||||
let endTime: Date
|
||||
|
||||
const secondNames = ['seconds', 'second', 'sec', 'secs']
|
||||
const minuteNames = ['minutes', 'minute', 'min', 'mins']
|
||||
const hourNames = ['hours', 'hour', 'hr', 'hrs']
|
||||
const dayNames = ['days', 'day']
|
||||
|
||||
endTime = add(startTime, {
|
||||
timeUnit1: timeLeft1,
|
||||
timeUnit2: timeLeft2
|
||||
})
|
||||
|
||||
// This if chain uses date-fns to correctly calculate the time allocated to the giveaway based on what the
|
||||
// user types (seconds, minutes, etc.)
|
||||
|
||||
// if the time unit before the "and" is "seconds" or one of the other entries in the secondNames array, add the time entered
|
||||
// to the startTime and save that in the endTime
|
||||
if (secondNames.includes(timeUnit1!)) {
|
||||
endTime = endTime === startTime ? addSeconds(startTime, timeLeft1) : addSeconds(endTime, timeLeft1)
|
||||
}
|
||||
// if the time unit after the "and" is "seconds" or one of the other entries in the secondNames array, add the time entered
|
||||
// to the startTime and save that in the endTime
|
||||
if (secondNames.includes(timeUnit2!)) {
|
||||
endTime = endTime === startTime ? addSeconds(startTime, timeLeft2!) : addSeconds(endTime, timeLeft2!)
|
||||
}
|
||||
// if the time unit before the "and" is "minutes" or one of the other entries in the minuteNames array, add the time entered
|
||||
// to the startTime and save that in the endTime
|
||||
if (minuteNames.includes(timeUnit1!)) {
|
||||
endTime = endTime === startTime ? addMinutes(startTime, timeLeft1) : addMinutes(endTime, timeLeft1)
|
||||
}
|
||||
// if the time unit after the "and" is "minutes" or one of the other entries in the minuteNames array, add the time entered
|
||||
// to the startTime and save that in the endTime
|
||||
if (minuteNames.includes(timeUnit2!)) {
|
||||
endTime = endTime === startTime ? addMinutes(startTime, timeLeft2!) : addMinutes(endTime, timeLeft2!)
|
||||
}
|
||||
// if the time unit before the "and" is "hours" or one of the other entries in the hourNames array, add the time entered
|
||||
// to the startTime and save that in the endTime
|
||||
if (hourNames.includes(timeUnit1!)) {
|
||||
endTime = endTime === startTime ? addHours(startTime, timeLeft1) : addHours(endTime, timeLeft1)
|
||||
}
|
||||
// if the time unit after the "and" is "hours" or one of the other entries in the hourNames array, add the time entered
|
||||
// to the startTime and save that in the endTime
|
||||
if (hourNames.includes(timeUnit2!)) {
|
||||
endTime = endTime === startTime ? addHours(startTime, timeLeft2!) : addHours(endTime, timeLeft2!)
|
||||
}
|
||||
// if the time unit before the "and" is "days" or one of the other entries in the dayNames array, add the time entered
|
||||
// to the startTime and save that in the endTime
|
||||
if (dayNames.includes(timeUnit1!)) {
|
||||
endTime = endTime === startTime ? addDays(startTime, timeLeft1) : addDays(endTime, timeLeft1)
|
||||
}
|
||||
// if the time unit after the "and" is "days" or one of the other entries in the dayNames array, add the time entered
|
||||
// to the startTime and save that in the endTime
|
||||
if (dayNames.includes(timeUnit2!)) {
|
||||
endTime = endTime === startTime ? addDays(startTime, timeLeft2!) : addDays(endTime, timeLeft2!)
|
||||
}
|
||||
|
||||
const endTimeStamp: string = `<t:${Math.floor(endTime!.getTime() / 1000)}:f>`
|
||||
const endTimeStamp2 = new Timestamp(endTime.getTime()).timestamp
|
||||
|
||||
let embed = new EmbedBuilder()
|
||||
.setTitle(`🥳 ${item} giveaway 🥳`)
|
||||
.setDescription('React to enter the giveaway!')
|
||||
.addFields(
|
||||
{name: '\u200b', value: `Hosted by: <@${ctx.userId}>`},
|
||||
{name: '\u200b', value: `Ends: ${new Timestamp(Number(endTimeStamp2)).getRelativeTime()} (${endTimeStamp})`}
|
||||
)
|
||||
|
||||
|
||||
await ctx.reply({
|
||||
embeds: [embed],
|
||||
}).then(embedMessage => {
|
||||
embedMessage.react("🎉")
|
||||
|
||||
setInterval(() => {
|
||||
const userReactions = embedMessage.reactions.cache.filter(reaction => reaction.users.cache.has(ctx.userId));
|
||||
|
||||
for (const reaction of userReactions.values()) {
|
||||
reaction.users.remove(ctx.userId);
|
||||
}
|
||||
}, 1000)
|
||||
|
||||
let intervalTime = endTime.getTime() - startTime.getTime()
|
||||
|
||||
setTimeout(() => {
|
||||
const stmt = db.prepare(`SELECT * FROM entrees`).all()
|
||||
|
||||
let winnerIndex = Math.floor(Math.random() * stmt.length)
|
||||
|
||||
if (stmt.length > 0 && stmt[winnerIndex].user_id !== ctx.userId) {
|
||||
const winnerId = stmt[winnerIndex].user_id
|
||||
|
||||
embed.setDescription('\u200b')
|
||||
embed.setFields(
|
||||
{name: '\u200b', value: `Winner: <@${winnerId}>`},
|
||||
{name: '\u200b', value: `Hosted by: <@${ctx.userId}>`},
|
||||
{name: '\u200b', value: `Ended: ${new Timestamp(Number(endTimeStamp2)).getRelativeTime()} (${endTimeStamp})`}
|
||||
)
|
||||
|
||||
embedMessage.edit({embeds: [embed]})
|
||||
}
|
||||
else if (stmt.length > 1 && stmt[winnerIndex].user_id === ctx.userId) {
|
||||
winnerIndex = Math.floor(Math.random() * stmt.length)
|
||||
}
|
||||
else if ((stmt.length === 1 && stmt[winnerIndex].user_id === ctx.userId) || stmt.length === 0) {
|
||||
embed.setDescription('\u200b')
|
||||
embed.setFields(
|
||||
{name: '\u200b', value: `Not enough eligible users`},
|
||||
{name: '\u200b', value: `Hosted by: <@${ctx.userId}>`},
|
||||
{name: '\u200b', value: `Ended: ${new Timestamp(Number(endTimeStamp2)).getRelativeTime()} (${endTimeStamp})`}
|
||||
)
|
||||
|
||||
embedMessage.edit({embeds: [embed]})
|
||||
}
|
||||
}, intervalTime)
|
||||
})
|
||||
|
||||
db.prepare(`DELETE FROM entrees`).run()
|
||||
}
|
||||
})
|
||||
@@ -25,8 +25,7 @@ export default commandModule({
|
||||
.setPlaceholder("Name of the emoji")
|
||||
.setRequired()
|
||||
.setStyle(TextInputStyle.Short)
|
||||
.setValue(suggestedName),
|
||||
);
|
||||
.setValue(suggestedName));
|
||||
modal.setComponents(row);
|
||||
|
||||
await ctx.showModal(modal);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { ownerIDs } from "#constants";
|
||||
import { commandModule, CommandType } from "@sern/handler";
|
||||
import { ActionRowBuilder, ButtonBuilder, EmbedBuilder } from "discord.js";
|
||||
import { ActionRowBuilder, ButtonBuilder, ButtonComponentData, EmbedBuilder } from "discord.js";
|
||||
|
||||
export default commandModule({
|
||||
type: CommandType.Button,
|
||||
@@ -17,9 +17,7 @@ export default commandModule({
|
||||
const components = [
|
||||
new ActionRowBuilder<ButtonBuilder>().setComponents(
|
||||
ctx.message!.components[0].components.map((c) =>
|
||||
new ButtonBuilder(c.data).setDisabled(),
|
||||
),
|
||||
),
|
||||
new ButtonBuilder(c.data as ButtonComponentData).setDisabled())),
|
||||
];
|
||||
|
||||
const embed = new EmbedBuilder(ctx.message?.embeds[0]?.data) //
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { commandModule, CommandType } from "@sern/handler";
|
||||
import { ActionRowBuilder, ButtonBuilder, EmbedBuilder } from "discord.js";
|
||||
import { ActionRowBuilder, ButtonBuilder, ButtonComponentData, EmbedBuilder } from "discord.js";
|
||||
|
||||
export default commandModule({
|
||||
type: CommandType.Modal,
|
||||
@@ -33,9 +33,7 @@ export default commandModule({
|
||||
const components = [
|
||||
new ActionRowBuilder<ButtonBuilder>().setComponents(
|
||||
ctx.message!.components[0].components.map((c) =>
|
||||
new ButtonBuilder(c.data).setDisabled(),
|
||||
),
|
||||
),
|
||||
new ButtonBuilder(c.data as Readonly<ButtonComponentData>).setDisabled())),
|
||||
];
|
||||
|
||||
const embed = new EmbedBuilder(ctx.message?.embeds[0]?.data) //
|
||||
|
||||
@@ -17,15 +17,11 @@ export default commandModule({
|
||||
name: tagName,
|
||||
content: tagContent,
|
||||
keywords: keywords
|
||||
? [
|
||||
...new Set(
|
||||
keywords
|
||||
? [ ...new Set(keywords
|
||||
.trim()
|
||||
.split(",")
|
||||
.map((c) => c.trim())
|
||||
.filter((c) => !!c.length),
|
||||
),
|
||||
]
|
||||
.filter((c) => !!c.length))]
|
||||
: [],
|
||||
};
|
||||
const filePath = `./tags.json`;
|
||||
|
||||
@@ -18,11 +18,10 @@ export default commandModule({
|
||||
name: tagName,
|
||||
content: tagContent,
|
||||
keywords: keywords
|
||||
? keywords
|
||||
.trim()
|
||||
.split(",")
|
||||
.map((c) => c.trim())
|
||||
.filter((c) => !!c.length)
|
||||
? keywords.trim()
|
||||
.split(",")
|
||||
.map((c) => c.trim())
|
||||
.filter((c) => !!c.length)
|
||||
: [],
|
||||
};
|
||||
const filePath = `./tags.json`;
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
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?");
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -19,7 +19,7 @@ export default slashCommand({
|
||||
name: "channel",
|
||||
type: ApplicationCommandOptionType.Channel,
|
||||
description: "The channel to send the message to",
|
||||
channelTypes: [ChannelType.GuildText],
|
||||
channel_types: [ChannelType.GuildText],
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
@@ -35,7 +35,8 @@ export default slashCommand({
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
async execute(ctx, [, options]) {
|
||||
async execute(ctx) {
|
||||
const options = ctx.options;
|
||||
const channel = options.getChannel("channel", true) as TextChannel;
|
||||
const role = new Resolver(options.getString("role", true), ctx.interaction).roles;
|
||||
const message = options.getString("message", true);
|
||||
@@ -71,14 +72,11 @@ function createMenu(channel: TextChannel, role: Collection<string, Role>) {
|
||||
.setMaxValues(role.size)
|
||||
.setMinValues(0)
|
||||
.setPlaceholder("Pick some roles here!")
|
||||
.setOptions(
|
||||
role.map((r) => {
|
||||
.setOptions(role.map((r) => {
|
||||
return {
|
||||
label: r.name,
|
||||
value: r.id,
|
||||
};
|
||||
}),
|
||||
);
|
||||
const row = new ActionRowBuilder<StringSelectMenuBuilder>().setComponents(menu);
|
||||
return row;
|
||||
}));
|
||||
return new ActionRowBuilder<StringSelectMenuBuilder>().setComponents(menu);
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ export default slashCommand({
|
||||
required: true,
|
||||
autocomplete: true,
|
||||
command: {
|
||||
onEvent: [],
|
||||
async execute(ctx) {
|
||||
const plugins = require(PluginList) as Plugin[];
|
||||
|
||||
@@ -45,7 +44,8 @@ export default slashCommand({
|
||||
}),
|
||||
),
|
||||
],
|
||||
async execute(ctx, [, options]) {
|
||||
async execute(ctx) {
|
||||
const { options } = ctx;
|
||||
const plugins = require(PluginList) as Plugin[];
|
||||
|
||||
if (!plugins.length) return ctx.reply("Plugins are uncached, contact Evo!");
|
||||
|
||||
@@ -6,10 +6,8 @@ import type { Plugin } from "typings";
|
||||
|
||||
export default slashCommand({
|
||||
plugins: [
|
||||
publish({
|
||||
dmPermission: false,
|
||||
defaultMemberPermissions: ["Administrator"],
|
||||
}),
|
||||
publish({ dmPermission: false,
|
||||
defaultMemberPermissions: ["Administrator"], }),
|
||||
ownerOnly([Evo]),
|
||||
],
|
||||
description: "refresh plugins cache",
|
||||
@@ -31,7 +29,7 @@ export async function cp(): Promise<number | null> {
|
||||
const link = `https://raw.githubusercontent.com/sern-handler/awesome-plugins/main/pluginlist.json`;
|
||||
const resp = await fetch(link).catch(() => null);
|
||||
if (!resp) return null;
|
||||
const dataArray = (await resp.json()) as Plugin[];
|
||||
const dataArray = await resp.json() as Plugin[];
|
||||
|
||||
writeFileSync(PluginList, JSON.stringify(dataArray, null, 2), { flag: "w" });
|
||||
return dataArray.length;
|
||||
|
||||
@@ -19,7 +19,6 @@ export default slashCommand({
|
||||
content: "Something bad happened, Please contact Evo!",
|
||||
ephemeral: true,
|
||||
});
|
||||
|
||||
const memberCount = `• \`${ctx.channel.memberCount}\` member(s) participated in this post!`;
|
||||
const msgCount = `• \`${(ctx.channel.messageCount ?? 0) + 1}\` message(s) are present here`;
|
||||
const msgSent = `• \`${
|
||||
|
||||
@@ -41,8 +41,7 @@ export default slashCommand({
|
||||
? t.toLowerCase().includes(focus.toLowerCase())
|
||||
: true,
|
||||
)
|
||||
.map((t) => ({ name: t, value: t })),
|
||||
);
|
||||
.map((t) => ({ name: t, value: t })));
|
||||
}
|
||||
},
|
||||
},
|
||||
@@ -56,8 +55,8 @@ export default slashCommand({
|
||||
],
|
||||
},
|
||||
],
|
||||
execute(ctx, args) {
|
||||
const [, options] = args;
|
||||
execute(ctx) {
|
||||
const options = ctx.options;
|
||||
const subCmd = options.getSubcommand();
|
||||
switch (subCmd) {
|
||||
case "list": {
|
||||
@@ -74,15 +73,15 @@ export default slashCommand({
|
||||
.setTimestamp();
|
||||
return embed;
|
||||
});
|
||||
const paginator = new Paginator({ embeds }).setSelectMenuOptions(
|
||||
...Array(embeds.length)
|
||||
.fill(null)
|
||||
.map((_, i) => ({
|
||||
label: embeds[i].data.title!,
|
||||
value: `${i}`,
|
||||
default: i === 0,
|
||||
})),
|
||||
);
|
||||
const paginator = new Paginator({ embeds })
|
||||
.setSelectMenuOptions(
|
||||
...Array(embeds.length)
|
||||
.fill(null)
|
||||
.map((_, i) => ({
|
||||
label: embeds[i].data.title!,
|
||||
value: `${i}`,
|
||||
default: i === 0,
|
||||
})));
|
||||
|
||||
return paginator.run(ctx.interaction);
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ export default slashCommand({
|
||||
},
|
||||
],
|
||||
execute: async (context, args) => {
|
||||
const [, options] = args;
|
||||
const { options } = context;
|
||||
const subcmd = options.getSubcommand();
|
||||
|
||||
const file: TagData[] = require(TagList);
|
||||
|
||||
@@ -20,10 +20,8 @@ export default slashCommand({
|
||||
required: true,
|
||||
autocomplete: true,
|
||||
command: {
|
||||
onEvent: [],
|
||||
execute: async (autocomplete) => {
|
||||
const input = autocomplete.options.getFocused();
|
||||
|
||||
return autocomplete.respond(fuzz(input)).catch(() => null);
|
||||
},
|
||||
},
|
||||
@@ -49,7 +47,8 @@ export default slashCommand({
|
||||
type: ApplicationCommandOptionType.Subcommand,
|
||||
},
|
||||
],
|
||||
execute: async (ctx, [, options]) => {
|
||||
execute: async (ctx) => {
|
||||
const { options } = ctx;
|
||||
switch (options.getSubcommand()) {
|
||||
case "create": {
|
||||
const reqData = {
|
||||
@@ -84,7 +83,7 @@ export default slashCommand({
|
||||
`https://api.srizan.dev/sern/getTime?userid=${option.id}`,
|
||||
).catch(() => null);
|
||||
|
||||
const data = (await request?.json()) as APIResponse;
|
||||
const data = await request?.json() as APIResponse;
|
||||
|
||||
if (!data)
|
||||
return ctx.reply({
|
||||
|
||||
@@ -16,3 +16,8 @@ export const enum Emojis {
|
||||
|
||||
export const PluginList = `${process.cwd()}/pluginlist.json`;
|
||||
export const TagList = `${process.cwd()}/tags.json`;
|
||||
|
||||
|
||||
export const commands = './dist/src/commands';
|
||||
export const events = './dist/src/events'
|
||||
export const defaultPrefix= "sern";
|
||||
|
||||
15
src/dependencies.d.ts
vendored
15
src/dependencies.d.ts
vendored
@@ -5,22 +5,17 @@
|
||||
*/
|
||||
|
||||
import type {
|
||||
SernEmitter,
|
||||
Logging,
|
||||
CoreModuleStore,
|
||||
ModuleManager,
|
||||
ErrorHandling,
|
||||
CoreDependencies,
|
||||
Singleton,
|
||||
} from "@sern/handler";
|
||||
import type { Client } from "discord.js";
|
||||
import type { SernLogger } from "./utils/Logger";
|
||||
import type { Octokit } from "@octokit/rest";
|
||||
declare global {
|
||||
interface Dependencies extends Dependencies {
|
||||
"@sern/client": Singleton<Client>;
|
||||
"@sern/logger": Singleton<SernLogger>;
|
||||
octokit: Singleton<Octokit>;
|
||||
interface Dependencies extends CoreDependencies {
|
||||
"@sern/client": Client;
|
||||
"@sern/logger": SernLogger;
|
||||
octokit: Octokit;
|
||||
process: NodeJS.Process
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
15
src/events/embedReact.ts
Normal file
15
src/events/embedReact.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { discordEvent } from "@sern/handler";
|
||||
import { db } from "../utils/db.js"
|
||||
|
||||
export default discordEvent({
|
||||
name: 'messageReactionAdd',
|
||||
execute: async (reaction, potentialWinners) => {
|
||||
const startTime = reaction.message.createdTimestamp
|
||||
|
||||
const stmt = db.prepare(`INSERT INTO entrees(timestamp, user_id) VALUES (?, ?)`)
|
||||
|
||||
if (potentialWinners.bot === false) {
|
||||
stmt.run([startTime, potentialWinners.id])
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -1,13 +1,25 @@
|
||||
import { eventModule, EventType } from "@sern/handler";
|
||||
import { AnyThreadChannel, EmbedBuilder } from "discord.js";
|
||||
import { onCorrectThread } from "../plugins/onCorrectThread.js";
|
||||
import { AnyThreadChannel, ChannelType, EmbedBuilder } from "discord.js";
|
||||
import { forumID } from "#constants";
|
||||
|
||||
function onCorrectThread(thread: AnyThreadChannel, parentId: string, newlyMade: boolean) {
|
||||
const isBadThread =
|
||||
!thread.parent ||
|
||||
thread.parentId !== parentId ||
|
||||
thread.parent.type !== ChannelType.GuildForum ||
|
||||
!newlyMade;
|
||||
if (!isBadThread) {
|
||||
return true
|
||||
}
|
||||
return false;
|
||||
}
|
||||
export default eventModule({
|
||||
type: EventType.Discord,
|
||||
plugins: [onCorrectThread(forumID)],
|
||||
name: "threadCreate",
|
||||
async execute(thread: AnyThreadChannel, _: boolean) {
|
||||
async execute(thread: AnyThreadChannel, newlyMade: boolean) {
|
||||
if(!onCorrectThread(thread, forumID, newlyMade)) {
|
||||
return;
|
||||
}
|
||||
if (thread.appliedTags.length > 3)
|
||||
await thread.setAppliedTags(thread.appliedTags.slice(0, 3));
|
||||
|
||||
@@ -17,20 +29,15 @@ export default eventModule({
|
||||
const list = `• What is your [\`discord.js\`](https://discord.js.org/) version?\n• What is your [\`@sern/handler\`](https://sern.dev) version?\n• If any error is occuring, what error?`;
|
||||
|
||||
const embed = new EmbedBuilder()
|
||||
.setDescription(
|
||||
`Hello ${msg.author}! Thank you for creating a dedicated post for your issue\n` +
|
||||
`Please make sure you've read the **__Post Guidelines__**!\n` +
|
||||
`In the meanwhile you wait for your answer, It is recommended to provide details as much as possible\n`
|
||||
.concat(list)
|
||||
.concat(`\n\n\nIssue Solved? Run </solved:1026499792194510939>`),
|
||||
)
|
||||
.setDescription(`Hello ${msg.author}! Thank you for creating a dedicated post for your issue\n` +
|
||||
'Please make sure you\'ve read the **__Post Guidelines__**!\n \
|
||||
In the meanwhile wait for the answer, It is recommended to provide details as much as possible\n'
|
||||
.concat(list)
|
||||
.concat(`\n\n\nIssue Solved? Run </solved:1026499792194510939>`))
|
||||
.setColor("Random")
|
||||
.setTimestamp()
|
||||
.setThumbnail(msg.client.user!.displayAvatarURL({ size: 2048 }))
|
||||
.setTitle("Things you should know");
|
||||
|
||||
await msg.reply({
|
||||
embeds: [embed],
|
||||
});
|
||||
await msg.reply({ embeds: [embed] });
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,18 +1,14 @@
|
||||
import {
|
||||
controller,
|
||||
EventControlPlugin,
|
||||
eventModule,
|
||||
EventType,
|
||||
Payload,
|
||||
PayloadType,
|
||||
Service,
|
||||
} from "@sern/handler";
|
||||
|
||||
export default eventModule({
|
||||
name: "module.activate",
|
||||
type: EventType.Sern,
|
||||
plugins: [filterFailedActivation()],
|
||||
execute(payload: Payload & { type: PayloadType.Failure }) {
|
||||
execute(payload: Payload & { type: 'failure' }) {
|
||||
const logger = Service("@sern/logger");
|
||||
logger.warning({
|
||||
message: `A module (${payload.module?.name} failed to execute: ${payload.reason}`,
|
||||
@@ -20,12 +16,3 @@ export default eventModule({
|
||||
},
|
||||
});
|
||||
|
||||
function filterFailedActivation() {
|
||||
return EventControlPlugin<EventType.Sern>((payload) => {
|
||||
if (payload.type == PayloadType.Failure) {
|
||||
return controller.next();
|
||||
} else {
|
||||
return controller.stop();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
18
src/index.ts
18
src/index.ts
@@ -1,6 +1,7 @@
|
||||
import "dotenv/config";
|
||||
import * as config from './config.js'
|
||||
import { Client, GatewayIntentBits, Partials } from "discord.js";
|
||||
import { Sern, single, makeDependencies, Service } from "@sern/handler";
|
||||
import { Sern, makeDependencies, Service } from "@sern/handler";
|
||||
import { SernLogger } from "#utils";
|
||||
import { Octokit } from "@octokit/rest";
|
||||
import { cp } from "./commands/refresh.js";
|
||||
@@ -11,6 +12,7 @@ const client = new Client({
|
||||
GatewayIntentBits.GuildMembers,
|
||||
GatewayIntentBits.GuildMessages,
|
||||
GatewayIntentBits.MessageContent,
|
||||
GatewayIntentBits.GuildMessageReactions,
|
||||
],
|
||||
partials: [Partials.GuildMember, Partials.Message, Partials.ThreadMember, Partials.Channel],
|
||||
sweepers: {
|
||||
@@ -21,15 +23,11 @@ const client = new Client({
|
||||
},
|
||||
});
|
||||
|
||||
await makeDependencies({
|
||||
build: (root) =>
|
||||
root
|
||||
.add({ "@sern/client": () => client })
|
||||
.upsert({ "@sern/logger": () => new SernLogger("info") })
|
||||
.add({
|
||||
process: () => process,
|
||||
octokit: () => new Octokit({ auth: process.env.GITHUB_TOKEN }),
|
||||
}),
|
||||
await makeDependencies(root => {
|
||||
root.add("@sern/client", client);
|
||||
root.swap("@sern/logger", new SernLogger("info"))
|
||||
root.add('octokit', new Octokit({ auth: process.env.GITHUB_TOKEN }))
|
||||
root.add('process', process)
|
||||
});
|
||||
|
||||
Sern.init({
|
||||
|
||||
@@ -1,147 +1,180 @@
|
||||
// @ts-nocheck
|
||||
/**
|
||||
* Allows you to set cooldowns (or "ratelimits") for commands
|
||||
* limits user/channel/guild actions,
|
||||
* @plugin
|
||||
* Allows you to set cooldowns (or "ratelimits") for commands, limits user/channel/guild actions.
|
||||
* An extra function cooldown2 is exported if you want your cooldown to be local to the command.
|
||||
* @author @trueharuu [<@504698587221852172>]
|
||||
* @version 1.0.0
|
||||
* @example
|
||||
* ```ts
|
||||
* import { cooldown } from "../plugins/cooldown";
|
||||
* import { cooldown, cooldown2 } from "../plugins/cooldown";
|
||||
* import { commandModule } from "@sern/handler";
|
||||
* //IF you want this cooldown to be local to this command:
|
||||
* const localCooldown = cooldown2()
|
||||
* export default commandModule({
|
||||
* plugins: [cooldown.add( [ ['channel', '1/4'] ] )], // limit to 1 action every 4 seconds per channel
|
||||
* execute: (ctx) => {
|
||||
* //your code here
|
||||
* }
|
||||
* plugins: [cooldown.add([['channel', '1/4']]), // limit to 1 action every 4 seconds per channel
|
||||
* localCooldown.add([["user", "1/10"]])], // limit to 1 action every 10 seconds, local to command
|
||||
* execute: (ctx) => { //your code here }
|
||||
* })
|
||||
* ```
|
||||
* @end
|
||||
*/
|
||||
|
||||
import { CommandControlPlugin, CommandType, Context, controller } from "@sern/handler";
|
||||
import {
|
||||
CommandControlPlugin,
|
||||
CommandType,
|
||||
Context,
|
||||
controller,
|
||||
} from "@sern/handler";
|
||||
import { GuildMember } from "discord.js";
|
||||
/**
|
||||
* actions/seconds
|
||||
*/
|
||||
export type CooldownString = `${number}/${number}`;
|
||||
export interface Cooldown {
|
||||
location: CooldownLocation;
|
||||
seconds: number;
|
||||
actions: number;
|
||||
location: CooldownLocation;
|
||||
seconds: number;
|
||||
actions: number;
|
||||
}
|
||||
export enum CooldownLocation {
|
||||
channel = "channel",
|
||||
user = "user",
|
||||
guild = "guild",
|
||||
channel = "channel",
|
||||
user = "user",
|
||||
guild = "guild",
|
||||
}
|
||||
|
||||
export class ExpiryMap<K, V> extends Map<K, V> {
|
||||
public readonly expiry: number;
|
||||
constructor(expiry: number = Infinity, iterable: [K, V][] | ReadonlyMap<K, V> = []) {
|
||||
super(iterable);
|
||||
this.expiry = expiry;
|
||||
}
|
||||
public readonly expiry: number;
|
||||
constructor(
|
||||
expiry: number = Infinity,
|
||||
iterable: [K, V][] | ReadonlyMap<K, V> = [],
|
||||
) {
|
||||
super(iterable);
|
||||
this.expiry = expiry;
|
||||
}
|
||||
|
||||
public set(key: K, value: V, expiry: number = this.expiry): this {
|
||||
super.set(key, value);
|
||||
if (expiry !== Infinity)
|
||||
setTimeout(() => {
|
||||
super.delete(key);
|
||||
}, expiry);
|
||||
return this;
|
||||
}
|
||||
public set(key: K, value: V, expiry: number = this.expiry): this {
|
||||
super.set(key, value);
|
||||
if (expiry !== Infinity)
|
||||
setTimeout(() => {
|
||||
super.delete(key);
|
||||
}, expiry);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
export const map = new ExpiryMap<string, number>();
|
||||
|
||||
function parseCooldown(location: CooldownLocation, cooldown: CooldownString): Cooldown {
|
||||
const [actions, seconds] = cooldown.split("/").map((s) => Number(s));
|
||||
function parseCooldown(
|
||||
location: CooldownLocation,
|
||||
cooldown: CooldownString,
|
||||
): Cooldown {
|
||||
const [actions, seconds] = cooldown.split("/").map((s) => Number(s));
|
||||
|
||||
if (
|
||||
!Number.isSafeInteger(actions) ||
|
||||
!Number.isSafeInteger(seconds) ||
|
||||
actions === undefined ||
|
||||
seconds === undefined
|
||||
) {
|
||||
throw new Error(`Invalid cooldown string: ${cooldown}`);
|
||||
}
|
||||
if (
|
||||
!Number.isSafeInteger(actions) ||
|
||||
!Number.isSafeInteger(seconds) ||
|
||||
actions === undefined ||
|
||||
seconds === undefined
|
||||
) {
|
||||
throw new Error(`Invalid cooldown string: ${cooldown}`);
|
||||
}
|
||||
|
||||
return {
|
||||
actions,
|
||||
seconds,
|
||||
location,
|
||||
};
|
||||
return {
|
||||
actions,
|
||||
seconds,
|
||||
location,
|
||||
};
|
||||
}
|
||||
|
||||
function getPropertyForLocation(context: Context, location: CooldownLocation) {
|
||||
switch (location) {
|
||||
case CooldownLocation.channel:
|
||||
return context.channel!.id;
|
||||
case CooldownLocation.user:
|
||||
if (!context.member || !(context.member instanceof GuildMember)) {
|
||||
throw new Error("context.member is not a GuildMember");
|
||||
}
|
||||
return context.member.id;
|
||||
case CooldownLocation.guild:
|
||||
return context.guildId;
|
||||
}
|
||||
switch (location) {
|
||||
case CooldownLocation.channel:
|
||||
return context.channel!.id;
|
||||
case CooldownLocation.user:
|
||||
if (!context.member || !(context.member instanceof GuildMember)) {
|
||||
throw new Error("context.member is not a GuildMember");
|
||||
}
|
||||
return context.member.id;
|
||||
case CooldownLocation.guild:
|
||||
return context.guildId;
|
||||
}
|
||||
}
|
||||
|
||||
export interface RecievedCooldown {
|
||||
location: CooldownLocation;
|
||||
actions: number;
|
||||
maxActions: number;
|
||||
seconds: number;
|
||||
context: Context;
|
||||
location: CooldownLocation;
|
||||
actions: number;
|
||||
maxActions: number;
|
||||
seconds: number;
|
||||
context: Context;
|
||||
}
|
||||
type CooldownResponse = (cooldown: RecievedCooldown) => any;
|
||||
|
||||
function add(
|
||||
items: Array<[CooldownLocation | keyof typeof CooldownLocation, CooldownString] | Cooldown>,
|
||||
message?: CooldownResponse,
|
||||
) {
|
||||
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!);
|
||||
function __add(map : ExpiryMap<string, number>,
|
||||
items: Array<| [CooldownLocation
|
||||
| keyof typeof CooldownLocation, CooldownString]
|
||||
| Cooldown>,
|
||||
message?: CooldownResponse) {
|
||||
const raw = items.map((c) => {
|
||||
if (!Array.isArray(c)) return c;
|
||||
return parseCooldown(c[0] as CooldownLocation, c[1]);
|
||||
}) as Array<Cooldown>;
|
||||
|
||||
if (!cooldown) {
|
||||
map.set(id!, 1, seconds * 1000);
|
||||
continue;
|
||||
}
|
||||
return CommandControlPlugin<CommandType.Both>(async (context, args) => {
|
||||
for (const { location, actions, seconds } of raw) {
|
||||
const id = getPropertyForLocation(context, location);
|
||||
const cooldown = map.get(id!);
|
||||
|
||||
if (cooldown >= actions) {
|
||||
if (message) {
|
||||
await message({
|
||||
location,
|
||||
actions: cooldown,
|
||||
maxActions: actions,
|
||||
seconds,
|
||||
context,
|
||||
});
|
||||
}
|
||||
return controller.stop();
|
||||
}
|
||||
if (!cooldown) {
|
||||
map.set(id!, 1, seconds * 1000);
|
||||
continue;
|
||||
}
|
||||
|
||||
map.set(id!, cooldown + 1, seconds * 1000);
|
||||
}
|
||||
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>;
|
||||
type Location = (value: CooldownString) => ReturnType<typeof __add>;
|
||||
|
||||
const locations: Record<CooldownLocation, Location> = {
|
||||
[CooldownLocation.channel]: (value) => add([[CooldownLocation.channel, value]]),
|
||||
[CooldownLocation.user]: (value) => add([[CooldownLocation.user, value]]),
|
||||
[CooldownLocation.guild]: (value) => add([[CooldownLocation.guild, value]]),
|
||||
const locationsFn = (map: ExpiryMap<string, number>)=> ({
|
||||
[CooldownLocation.channel]: (value) => __add(map, [[CooldownLocation.channel, value]]),
|
||||
[CooldownLocation.user]: (value) => __add(map, [[CooldownLocation.user, value]]),
|
||||
[CooldownLocation.guild]: (value) => __add(map, [[CooldownLocation.guild, value]]),
|
||||
} as Record<CooldownLocation, Location>);
|
||||
|
||||
|
||||
|
||||
export const cooldown2 = () => {
|
||||
const cooldownMap = new ExpiryMap<string, number>();
|
||||
return {
|
||||
add:(items: Array<| [CooldownLocation
|
||||
| keyof typeof CooldownLocation, CooldownString]
|
||||
| Cooldown>,
|
||||
message?: CooldownResponse) => __add(cooldownMap, items, message),
|
||||
locations: locationsFn(cooldownMap),
|
||||
map: cooldownMap
|
||||
}
|
||||
};
|
||||
|
||||
const map = new ExpiryMap<string, number>();
|
||||
export const cooldown = {
|
||||
add,
|
||||
locations,
|
||||
map,
|
||||
};
|
||||
locations: locationsFn(map),
|
||||
add: (items: Array<| [CooldownLocation
|
||||
| keyof typeof CooldownLocation, CooldownString]
|
||||
| Cooldown>,
|
||||
message?: CooldownResponse) => __add(map, items, message)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
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();
|
||||
});
|
||||
}
|
||||
@@ -25,7 +25,6 @@ import {
|
||||
controller,
|
||||
SernOptionsData,
|
||||
SlashCommand,
|
||||
Service,
|
||||
} from "@sern/handler";
|
||||
import {
|
||||
ApplicationCommandData,
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
// 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;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
@@ -1,22 +1,25 @@
|
||||
import {
|
||||
AnyCommandPlugin,
|
||||
BaseOptions,
|
||||
commandModule,
|
||||
CommandType,
|
||||
Context,
|
||||
SernSubCommandData,
|
||||
SernSubCommandGroupData,
|
||||
SlashOptions,
|
||||
Plugin,
|
||||
SDT,
|
||||
SlashCommand
|
||||
} from "@sern/handler";
|
||||
import { ChatInputCommandInteraction } from "discord.js";
|
||||
|
||||
export function slashCommand(data: {
|
||||
name?: string;
|
||||
description: string;
|
||||
plugins?: AnyCommandPlugin[];
|
||||
options?: (SernSubCommandData | SernSubCommandGroupData | BaseOptions)[] | undefined;
|
||||
execute: (ctx: Context, args: ["slash", SlashOptions]) => any;
|
||||
plugins?: Plugin[];
|
||||
options?: SlashCommand['options'];
|
||||
execute: (ctx: Context & { get options(): ChatInputCommandInteraction['options'] }, args: SDT) => any;
|
||||
|
||||
}) {
|
||||
//Weird fix for explicit undefined fields in an object
|
||||
const resolvedData = { type: CommandType.Slash, ...data } as const;
|
||||
return commandModule(resolvedData);
|
||||
}
|
||||
|
||||
|
||||
6
src/utils/db.ts
Normal file
6
src/utils/db.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import Database from 'better-sqlite3';
|
||||
export const db = new Database('giveaway.db');
|
||||
db.pragma('journal_mode = WAL');
|
||||
|
||||
|
||||
db.exec(`CREATE TABLE IF NOT EXISTS entrees(timestamp, user_id)`);
|
||||
375
yarn.lock
375
yarn.lock
@@ -479,15 +479,24 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@sern/handler@npm:^3.3.2":
|
||||
version: 3.3.2
|
||||
resolution: "@sern/handler@npm:3.3.2"
|
||||
"@sern/handler@npm:^4.0.0":
|
||||
version: 4.0.1
|
||||
resolution: "@sern/handler@npm:4.0.1"
|
||||
dependencies:
|
||||
"@sern/ioc": ^1.1.0
|
||||
callsites: ^3.1.0
|
||||
iti: ^0.6.0
|
||||
cron: ^3.1.7
|
||||
deepmerge: ^4.3.1
|
||||
rxjs: ^7.8.0
|
||||
ts-results-es: ^4.0.0
|
||||
checksum: a405f9f4e914245dc0c0a9091508871a2cdbb50947a71797ec4faa64ba0ec775dc8b9aa0f116c4699752520ca4b5f54b624898d7da0f53375e4534a698d0c3d4
|
||||
ts-results-es: ^4.1.0
|
||||
checksum: ab461fa953f2086b5b8ebc089078a55535d0cccd6f5b3210c45bde33022d3be1f3b47bb3ab251b129c7ed33bfe08b873416c70aace50c101ac03d0097206552a
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@sern/ioc@npm:^1.1.0":
|
||||
version: 1.1.0
|
||||
resolution: "@sern/ioc@npm:1.1.0"
|
||||
checksum: 0882ef51c3fcd28e7fe803762f2a8d7eb3dca4e494d3475ef7d4a43158d3b24243bda3679c3d58485c89bdc820719d22351007503e44b5cf8e6f2d0efe342921
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -498,6 +507,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/luxon@npm:~3.4.0":
|
||||
version: 3.4.2
|
||||
resolution: "@types/luxon@npm:3.4.2"
|
||||
checksum: 6f92d5bd02e89f310395753506bcd9cef3a56f5940f7a50db2a2b9822bce753553ac767d143cb5b4f9ed5ddd4a84e64f89ff538082ceb4d18739af7781b56925
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/node@npm:*":
|
||||
version: 18.11.18
|
||||
resolution: "@types/node@npm:18.11.18"
|
||||
@@ -643,6 +659,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"base64-js@npm:^1.3.1":
|
||||
version: 1.5.1
|
||||
resolution: "base64-js@npm:1.5.1"
|
||||
checksum: 669632eb3745404c2f822a18fc3a0122d2f9a7a13f7fb8b5823ee19d1d2ff9ee5b52c53367176ea4ad093c332fd5ab4bd0ebae5a8e27917a4105a4cfc86b1005
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"before-after-hook@npm:^2.2.0":
|
||||
version: 2.2.3
|
||||
resolution: "before-after-hook@npm:2.2.3"
|
||||
@@ -650,6 +673,17 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"better-sqlite3@npm:^11.1.2":
|
||||
version: 11.1.2
|
||||
resolution: "better-sqlite3@npm:11.1.2"
|
||||
dependencies:
|
||||
bindings: ^1.5.0
|
||||
node-gyp: latest
|
||||
prebuild-install: ^7.1.1
|
||||
checksum: fec9e5ea8236206ef2b334ae1d779217cbcd327f4d1822e745148c810fea3412c54483fff0cef5b3133b9a7fd1311ae7c7498b54b274074c6c04bd8e5c9dc54c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"binary-extensions@npm:^2.0.0":
|
||||
version: 2.2.0
|
||||
resolution: "binary-extensions@npm:2.2.0"
|
||||
@@ -657,6 +691,26 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"bindings@npm:^1.5.0":
|
||||
version: 1.5.0
|
||||
resolution: "bindings@npm:1.5.0"
|
||||
dependencies:
|
||||
file-uri-to-path: 1.0.0
|
||||
checksum: 65b6b48095717c2e6105a021a7da4ea435aa8d3d3cd085cb9e85bcb6e5773cf318c4745c3f7c504412855940b585bdf9b918236612a1c7a7942491de176f1ae7
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"bl@npm:^4.0.3":
|
||||
version: 4.1.0
|
||||
resolution: "bl@npm:4.1.0"
|
||||
dependencies:
|
||||
buffer: ^5.5.0
|
||||
inherits: ^2.0.4
|
||||
readable-stream: ^3.4.0
|
||||
checksum: 9e8521fa7e83aa9427c6f8ccdcba6e8167ef30cc9a22df26effcc5ab682ef91d2cbc23a239f945d099289e4bbcfae7a192e9c28c84c6202e710a0dfec3722662
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"bmp-js@npm:^0.1.0":
|
||||
version: 0.1.0
|
||||
resolution: "bmp-js@npm:0.1.0"
|
||||
@@ -692,6 +746,16 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"buffer@npm:^5.5.0":
|
||||
version: 5.7.1
|
||||
resolution: "buffer@npm:5.7.1"
|
||||
dependencies:
|
||||
base64-js: ^1.3.1
|
||||
ieee754: ^1.1.13
|
||||
checksum: e2cf8429e1c4c7b8cbd30834ac09bd61da46ce35f5c22a78e6c2f04497d6d25541b16881e30a019c6fd3154150650ccee27a308eff3e26229d788bbdeb08ab84
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"bundle-require@npm:^4.0.0":
|
||||
version: 4.0.1
|
||||
resolution: "bundle-require@npm:4.0.1"
|
||||
@@ -771,6 +835,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"chownr@npm:^1.1.1":
|
||||
version: 1.1.4
|
||||
resolution: "chownr@npm:1.1.4"
|
||||
checksum: 115648f8eb38bac5e41c3857f3e663f9c39ed6480d1349977c4d96c95a47266fcacc5a5aabf3cb6c481e22d72f41992827db47301851766c4fd77ac21a4f081d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"chownr@npm:^2.0.0":
|
||||
version: 2.0.0
|
||||
resolution: "chownr@npm:2.0.0"
|
||||
@@ -868,6 +939,16 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"cron@npm:^3.1.7":
|
||||
version: 3.1.7
|
||||
resolution: "cron@npm:3.1.7"
|
||||
dependencies:
|
||||
"@types/luxon": ~3.4.0
|
||||
luxon: ~3.4.0
|
||||
checksum: d98ee5297543c138221d96dd49270bf6576db80134e6041f4ce4a3c0cb6060863d76910209b34fee66fbf134461449ec3bd283d6a76d1c50da220cde7fc10c65
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"cross-spawn@npm:^7.0.3":
|
||||
version: 7.0.3
|
||||
resolution: "cross-spawn@npm:7.0.3"
|
||||
@@ -879,6 +960,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"date-fns@npm:^3.6.0":
|
||||
version: 3.6.0
|
||||
resolution: "date-fns@npm:3.6.0"
|
||||
checksum: 0daa1e9a436cf99f9f2ae9232b55e11f3dd46132bee10987164f3eebd29f245b2e066d7d7db40782627411ecf18551d8f4c9fcdf2226e48bb66545407d448ab7
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.3.1, debug@npm:^4.3.3":
|
||||
version: 4.3.4
|
||||
resolution: "debug@npm:4.3.4"
|
||||
@@ -891,6 +979,29 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"decompress-response@npm:^6.0.0":
|
||||
version: 6.0.0
|
||||
resolution: "decompress-response@npm:6.0.0"
|
||||
dependencies:
|
||||
mimic-response: ^3.1.0
|
||||
checksum: d377cf47e02d805e283866c3f50d3d21578b779731e8c5072d6ce8c13cc31493db1c2f6784da9d1d5250822120cefa44f1deab112d5981015f2e17444b763812
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"deep-extend@npm:^0.6.0":
|
||||
version: 0.6.0
|
||||
resolution: "deep-extend@npm:0.6.0"
|
||||
checksum: 7be7e5a8d468d6b10e6a67c3de828f55001b6eb515d014f7aeb9066ce36bd5717161eb47d6a0f7bed8a9083935b465bc163ee2581c8b128d29bf61092fdf57a7
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"deepmerge@npm:^4.3.1":
|
||||
version: 4.3.1
|
||||
resolution: "deepmerge@npm:4.3.1"
|
||||
checksum: 2024c6a980a1b7128084170c4cf56b0fd58a63f2da1660dcfe977415f27b17dbe5888668b59d0b063753f3220719d5e400b7f113609489c90160bb9a5518d052
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"delegates@npm:^1.0.0":
|
||||
version: 1.0.0
|
||||
resolution: "delegates@npm:1.0.0"
|
||||
@@ -912,6 +1023,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"detect-libc@npm:^2.0.0":
|
||||
version: 2.0.3
|
||||
resolution: "detect-libc@npm:2.0.3"
|
||||
checksum: 2ba6a939ae55f189aea996ac67afceb650413c7a34726ee92c40fb0deb2400d57ef94631a8a3f052055eea7efb0f99a9b5e6ce923415daa3e68221f963cfc27d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"dir-glob@npm:^3.0.1":
|
||||
version: 3.0.1
|
||||
resolution: "dir-glob@npm:3.0.1"
|
||||
@@ -980,6 +1098,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"end-of-stream@npm:^1.1.0, end-of-stream@npm:^1.4.1":
|
||||
version: 1.4.4
|
||||
resolution: "end-of-stream@npm:1.4.4"
|
||||
dependencies:
|
||||
once: ^1.4.0
|
||||
checksum: 530a5a5a1e517e962854a31693dbb5c0b2fc40b46dad2a56a2deec656ca040631124f4795823acc68238147805f8b021abbe221f4afed5ef3c8e8efc2024908b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"env-paths@npm:^2.2.0":
|
||||
version: 2.2.1
|
||||
resolution: "env-paths@npm:2.2.1"
|
||||
@@ -1088,6 +1215,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"expand-template@npm:^2.0.3":
|
||||
version: 2.0.3
|
||||
resolution: "expand-template@npm:2.0.3"
|
||||
checksum: 588c19847216421ed92befb521767b7018dc88f88b0576df98cb242f20961425e96a92cbece525ef28cc5becceae5d544ae0f5b9b5e2aa05acb13716ca5b3099
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"fast-deep-equal@npm:3.1.3, fast-deep-equal@npm:^3.1.3":
|
||||
version: 3.1.3
|
||||
resolution: "fast-deep-equal@npm:3.1.3"
|
||||
@@ -1124,6 +1258,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"file-uri-to-path@npm:1.0.0":
|
||||
version: 1.0.0
|
||||
resolution: "file-uri-to-path@npm:1.0.0"
|
||||
checksum: b648580bdd893a008c92c7ecc96c3ee57a5e7b6c4c18a9a09b44fb5d36d79146f8e442578bc0e173dc027adf3987e254ba1dfd6e3ec998b7c282873010502144
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"fill-range@npm:^7.0.1":
|
||||
version: 7.0.1
|
||||
resolution: "fill-range@npm:7.0.1"
|
||||
@@ -1140,6 +1281,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"fs-constants@npm:^1.0.0":
|
||||
version: 1.0.0
|
||||
resolution: "fs-constants@npm:1.0.0"
|
||||
checksum: 18f5b718371816155849475ac36c7d0b24d39a11d91348cfcb308b4494824413e03572c403c86d3a260e049465518c4f0d5bd00f0371cdfcad6d4f30a85b350d
|
||||
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"
|
||||
@@ -1198,6 +1346,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"github-from-package@npm:0.0.0":
|
||||
version: 0.0.0
|
||||
resolution: "github-from-package@npm:0.0.0"
|
||||
checksum: 14e448192a35c1e42efee94c9d01a10f42fe790375891a24b25261246ce9336ab9df5d274585aedd4568f7922246c2a78b8a8cd2571bfe99c693a9718e7dd0e3
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"glob-parent@npm:^5.1.2, glob-parent@npm:~5.1.2":
|
||||
version: 5.1.2
|
||||
resolution: "glob-parent@npm:5.1.2"
|
||||
@@ -1345,6 +1500,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"ieee754@npm:^1.1.13":
|
||||
version: 1.2.1
|
||||
resolution: "ieee754@npm:1.2.1"
|
||||
checksum: 5144c0c9815e54ada181d80a0b810221a253562422e7c6c3a60b1901154184f49326ec239d618c416c1c5945a2e197107aee8d986a3dd836b53dffefd99b5e7e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"ignore@npm:^5.2.0":
|
||||
version: 5.2.0
|
||||
resolution: "ignore@npm:5.2.0"
|
||||
@@ -1383,13 +1545,20 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"inherits@npm:2, inherits@npm:^2.0.3":
|
||||
"inherits@npm:2, inherits@npm:^2.0.3, inherits@npm:^2.0.4":
|
||||
version: 2.0.4
|
||||
resolution: "inherits@npm:2.0.4"
|
||||
checksum: 4a48a733847879d6cf6691860a6b1e3f0f4754176e4d71494c41f3475553768b10f84b5ce1d40fbd0e34e6bfbb864ee35858ad4dd2cf31e02fc4a154b724d7f1
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"ini@npm:~1.3.0":
|
||||
version: 1.3.8
|
||||
resolution: "ini@npm:1.3.8"
|
||||
checksum: dfd98b0ca3a4fc1e323e38a6c8eb8936e31a97a918d3b377649ea15bdb15d481207a0dda1021efbd86b464cae29a0d33c1d7dcaf6c5672bee17fa849bc50a1b3
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"ip@npm:^2.0.0":
|
||||
version: 2.0.0
|
||||
resolution: "ip@npm:2.0.0"
|
||||
@@ -1485,15 +1654,6 @@ __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"
|
||||
@@ -1593,6 +1753,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"luxon@npm:~3.4.0":
|
||||
version: 3.4.4
|
||||
resolution: "luxon@npm:3.4.4"
|
||||
checksum: 36c1f99c4796ee4bfddf7dc94fa87815add43ebc44c8934c924946260a58512f0fd2743a629302885df7f35ccbd2d13f178c15df046d0e3b6eb71db178f1c60c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"magic-bytes.js@npm:^1.5.0":
|
||||
version: 1.8.0
|
||||
resolution: "magic-bytes.js@npm:1.8.0"
|
||||
@@ -1655,6 +1822,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"mimic-response@npm:^3.1.0":
|
||||
version: 3.1.0
|
||||
resolution: "mimic-response@npm:3.1.0"
|
||||
checksum: 25739fee32c17f433626bf19f016df9036b75b3d84a3046c7d156e72ec963dd29d7fc8a302f55a3d6c5a4ff24259676b15d915aad6480815a969ff2ec0836867
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"minimatch@npm:^3.0.4, minimatch@npm:^3.1.1":
|
||||
version: 3.1.2
|
||||
resolution: "minimatch@npm:3.1.2"
|
||||
@@ -1673,6 +1847,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"minimist@npm:^1.2.0, minimist@npm:^1.2.3":
|
||||
version: 1.2.8
|
||||
resolution: "minimist@npm:1.2.8"
|
||||
checksum: 75a6d645fb122dad29c06a7597bddea977258957ed88d7a6df59b5cd3fe4a527e253e9bbf2e783e4b73657f9098b96a5fe96ab8a113655d4109108577ecf85b0
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"minipass-collect@npm:^1.0.2":
|
||||
version: 1.0.2
|
||||
resolution: "minipass-collect@npm:1.0.2"
|
||||
@@ -1743,6 +1924,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"mkdirp-classic@npm:^0.5.2, mkdirp-classic@npm:^0.5.3":
|
||||
version: 0.5.3
|
||||
resolution: "mkdirp-classic@npm:0.5.3"
|
||||
checksum: 3f4e088208270bbcc148d53b73e9a5bd9eef05ad2cbf3b3d0ff8795278d50dd1d11a8ef1875ff5aea3fa888931f95bfcb2ad5b7c1061cfefd6284d199e6776ac
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"mkdirp@npm:^1.0.3, mkdirp@npm:^1.0.4":
|
||||
version: 1.0.4
|
||||
resolution: "mkdirp@npm:1.0.4"
|
||||
@@ -1777,6 +1965,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"napi-build-utils@npm:^1.0.1":
|
||||
version: 1.0.2
|
||||
resolution: "napi-build-utils@npm:1.0.2"
|
||||
checksum: 06c14271ee966e108d55ae109f340976a9556c8603e888037145d6522726aebe89dd0c861b4b83947feaf6d39e79e08817559e8693deedc2c94e82c5cbd090c7
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"negotiator@npm:^0.6.3":
|
||||
version: 0.6.3
|
||||
resolution: "negotiator@npm:0.6.3"
|
||||
@@ -1784,6 +1979,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"node-abi@npm:^3.3.0":
|
||||
version: 3.65.0
|
||||
resolution: "node-abi@npm:3.65.0"
|
||||
dependencies:
|
||||
semver: ^7.3.5
|
||||
checksum: 5a60f2b0c73fe0a1123e581bd99e43729f4aa3f4b9b19f1915567128d52540e8f812474410a446cd77d708a3a1139e0b2abf1d0823ba6b5f5d47aa4345931706
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"node-fetch@npm:^2.6.7":
|
||||
version: 2.6.9
|
||||
resolution: "node-fetch@npm:2.6.9"
|
||||
@@ -1878,7 +2082,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"once@npm:^1.3.0, once@npm:^1.4.0":
|
||||
"once@npm:^1.3.0, once@npm:^1.3.1, once@npm:^1.4.0":
|
||||
version: 1.4.0
|
||||
resolution: "once@npm:1.4.0"
|
||||
dependencies:
|
||||
@@ -1976,6 +2180,28 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"prebuild-install@npm:^7.1.1":
|
||||
version: 7.1.2
|
||||
resolution: "prebuild-install@npm:7.1.2"
|
||||
dependencies:
|
||||
detect-libc: ^2.0.0
|
||||
expand-template: ^2.0.3
|
||||
github-from-package: 0.0.0
|
||||
minimist: ^1.2.3
|
||||
mkdirp-classic: ^0.5.3
|
||||
napi-build-utils: ^1.0.1
|
||||
node-abi: ^3.3.0
|
||||
pump: ^3.0.0
|
||||
rc: ^1.2.7
|
||||
simple-get: ^4.0.0
|
||||
tar-fs: ^2.0.0
|
||||
tunnel-agent: ^0.6.0
|
||||
bin:
|
||||
prebuild-install: bin.js
|
||||
checksum: 543dadf8c60e004ae9529e6013ca0cbeac8ef38b5f5ba5518cb0b622fe7f8758b34e4b5cb1a791db3cdc9d2281766302df6088bd1a225f206925d6fee17d6c5c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"promise-inflight@npm:^1.0.1":
|
||||
version: 1.0.1
|
||||
resolution: "promise-inflight@npm:1.0.1"
|
||||
@@ -1993,6 +2219,16 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"pump@npm:^3.0.0":
|
||||
version: 3.0.0
|
||||
resolution: "pump@npm:3.0.0"
|
||||
dependencies:
|
||||
end-of-stream: ^1.1.0
|
||||
once: ^1.3.1
|
||||
checksum: e42e9229fba14732593a718b04cb5e1cfef8254544870997e0ecd9732b189a48e1256e4e5478148ecb47c8511dca2b09eae56b4d0aad8009e6fac8072923cfc9
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"punycode@npm:^2.1.0":
|
||||
version: 2.1.1
|
||||
resolution: "punycode@npm:2.1.1"
|
||||
@@ -2007,6 +2243,31 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"rc@npm:^1.2.7":
|
||||
version: 1.2.8
|
||||
resolution: "rc@npm:1.2.8"
|
||||
dependencies:
|
||||
deep-extend: ^0.6.0
|
||||
ini: ~1.3.0
|
||||
minimist: ^1.2.0
|
||||
strip-json-comments: ~2.0.1
|
||||
bin:
|
||||
rc: ./cli.js
|
||||
checksum: 2e26e052f8be2abd64e6d1dabfbd7be03f80ec18ccbc49562d31f617d0015fbdbcf0f9eed30346ea6ab789e0fdfe4337f033f8016efdbee0df5354751842080e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"readable-stream@npm:^3.1.1":
|
||||
version: 3.6.2
|
||||
resolution: "readable-stream@npm:3.6.2"
|
||||
dependencies:
|
||||
inherits: ^2.0.3
|
||||
string_decoder: ^1.1.1
|
||||
util-deprecate: ^1.0.1
|
||||
checksum: bdcbe6c22e846b6af075e32cf8f4751c2576238c5043169a1c221c92ee2878458a816a4ea33f4c67623c0b6827c8a400409bfb3cf0bf3381392d0b1dfb52ac8d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"readable-stream@npm:^3.4.0, readable-stream@npm:^3.6.0":
|
||||
version: 3.6.0
|
||||
resolution: "readable-stream@npm:3.6.0"
|
||||
@@ -2098,7 +2359,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"safe-buffer@npm:~5.2.0":
|
||||
"safe-buffer@npm:^5.0.1, safe-buffer@npm:~5.2.0":
|
||||
version: 5.2.1
|
||||
resolution: "safe-buffer@npm:5.2.1"
|
||||
checksum: b99c4b41fdd67a6aaf280fcd05e9ffb0813654894223afb78a31f14a19ad220bba8aba1cb14eddce1fcfb037155fe6de4e861784eb434f7d11ed58d1e70dd491
|
||||
@@ -2135,9 +2396,11 @@ __metadata:
|
||||
resolution: "sern-community@workspace:."
|
||||
dependencies:
|
||||
"@octokit/rest": 19.0.7
|
||||
"@sern/handler": ^3.3.2
|
||||
"@sern/handler": ^4.0.0
|
||||
"@types/node": 18.16.3
|
||||
"@types/string-similarity": 4.0.0
|
||||
better-sqlite3: ^11.1.2
|
||||
date-fns: ^3.6.0
|
||||
discord.js: ^14.14.1
|
||||
dotenv: 16.0.3
|
||||
jsdoc-parse-plus: 1.3.0
|
||||
@@ -2181,6 +2444,24 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"simple-concat@npm:^1.0.0":
|
||||
version: 1.0.1
|
||||
resolution: "simple-concat@npm:1.0.1"
|
||||
checksum: 4d211042cc3d73a718c21ac6c4e7d7a0363e184be6a5ad25c8a1502e49df6d0a0253979e3d50dbdd3f60ef6c6c58d756b5d66ac1e05cda9cacd2e9fc59e3876a
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"simple-get@npm:^4.0.0":
|
||||
version: 4.0.1
|
||||
resolution: "simple-get@npm:4.0.1"
|
||||
dependencies:
|
||||
decompress-response: ^6.0.0
|
||||
once: ^1.3.1
|
||||
simple-concat: ^1.0.0
|
||||
checksum: e4132fd27cf7af230d853fa45c1b8ce900cb430dd0a3c6d3829649fe4f2b26574c803698076c4006450efb0fad2ba8c5455fbb5755d4b0a5ec42d4f12b31d27e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"simple-swizzle@npm:^0.2.2":
|
||||
version: 0.2.2
|
||||
resolution: "simple-swizzle@npm:0.2.2"
|
||||
@@ -2300,6 +2581,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"strip-json-comments@npm:~2.0.1":
|
||||
version: 2.0.1
|
||||
resolution: "strip-json-comments@npm:2.0.1"
|
||||
checksum: 1074ccb63270d32ca28edfb0a281c96b94dc679077828135141f27d52a5a398ef5e78bcf22809d23cadc2b81dfbe345eb5fd8699b385c8b1128907dec4a7d1e1
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"sucrase@npm:^3.20.3":
|
||||
version: 3.25.0
|
||||
resolution: "sucrase@npm:3.25.0"
|
||||
@@ -2317,6 +2605,31 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"tar-fs@npm:^2.0.0":
|
||||
version: 2.1.1
|
||||
resolution: "tar-fs@npm:2.1.1"
|
||||
dependencies:
|
||||
chownr: ^1.1.1
|
||||
mkdirp-classic: ^0.5.2
|
||||
pump: ^3.0.0
|
||||
tar-stream: ^2.1.4
|
||||
checksum: f5b9a70059f5b2969e65f037b4e4da2daf0fa762d3d232ffd96e819e3f94665dbbbe62f76f084f1acb4dbdcce16c6e4dac08d12ffc6d24b8d76720f4d9cf032d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"tar-stream@npm:^2.1.4":
|
||||
version: 2.2.0
|
||||
resolution: "tar-stream@npm:2.2.0"
|
||||
dependencies:
|
||||
bl: ^4.0.3
|
||||
end-of-stream: ^1.4.1
|
||||
fs-constants: ^1.0.0
|
||||
inherits: ^2.0.3
|
||||
readable-stream: ^3.1.1
|
||||
checksum: 699831a8b97666ef50021c767f84924cfee21c142c2eb0e79c63254e140e6408d6d55a065a2992548e72b06de39237ef2b802b99e3ece93ca3904a37622a66f3
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"tar@npm:^6.1.11, tar@npm:^6.1.2":
|
||||
version: 6.1.12
|
||||
resolution: "tar@npm:6.1.12"
|
||||
@@ -2445,10 +2758,10 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"ts-results-es@npm:^4.0.0":
|
||||
version: 4.0.0
|
||||
resolution: "ts-results-es@npm:4.0.0"
|
||||
checksum: 32a7059491e36d06c5a1084fe9be8021a0beb2d94a94b0c3fa85dc3e96561bf34fb8fd60ebe661064c9fc2bafcf437b6b65f119e8d7497af7f76cda9d9a2a945
|
||||
"ts-results-es@npm:^4.1.0":
|
||||
version: 4.2.0
|
||||
resolution: "ts-results-es@npm:4.2.0"
|
||||
checksum: ff475c2f6d44377e0204211e6eafdbcabddf3ad09d40540ad5dee3d817eefbd48c07a21f5ad86864ef82cd8a5542a266af9dd8dd4d58d4766fdd6e79370519bb
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -2502,6 +2815,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"tunnel-agent@npm:^0.6.0":
|
||||
version: 0.6.0
|
||||
resolution: "tunnel-agent@npm:0.6.0"
|
||||
dependencies:
|
||||
safe-buffer: ^5.0.1
|
||||
checksum: 05f6510358f8afc62a057b8b692f05d70c1782b70db86d6a1e0d5e28a32389e52fa6e7707b6c5ecccacc031462e4bc35af85ecfe4bbc341767917b7cf6965711
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"typescript@npm:5.0.4":
|
||||
version: 5.0.4
|
||||
resolution: "typescript@npm:5.0.4"
|
||||
@@ -2572,13 +2894,6 @@ __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
|
||||
|
||||
"wasm-feature-detect@npm:^1.2.11":
|
||||
version: 1.6.1
|
||||
resolution: "wasm-feature-detect@npm:1.6.1"
|
||||
|
||||
Reference in New Issue
Block a user