mirror of
https://github.com/SrIzan10/sern-community.git
synced 2026-05-01 11:05:19 +00:00
feat: updated plugins to co-ordinate with automations (#36)
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -3,6 +3,7 @@
|
||||
.env
|
||||
.vscode/
|
||||
.idea/
|
||||
pluginlist.json
|
||||
# Yarn files
|
||||
.yarn/install-state.gz
|
||||
.yarn/build-state.yml
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { commandModule, CommandType } from "@sern/handler";
|
||||
import type { TagMessage } from "../../types";
|
||||
import type { TagMessage } from "typings";
|
||||
|
||||
export default commandModule({
|
||||
type: CommandType.Button,
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { commandModule, CommandType } from "@sern/handler";
|
||||
import { existsSync, writeFileSync } from "fs";
|
||||
import type { TagData } from "../../types";
|
||||
import type { TagData } from "typings";
|
||||
import { createRequire } from "module";
|
||||
import { TagList } from "#constants";
|
||||
const require = createRequire(import.meta.url);
|
||||
|
||||
export default commandModule({
|
||||
@@ -32,7 +33,7 @@ export default commandModule({
|
||||
const tags = [tag];
|
||||
writeFileSync(filePath, JSON.stringify(tags, null, 2));
|
||||
} else {
|
||||
const file: TagData[] = require(`${process.cwd()}/tags.json`);
|
||||
const file: TagData[] = require(TagList);
|
||||
|
||||
if (file.find((t) => t.name === tagName)) {
|
||||
return ctx.reply(`Tag __${tagName}__ already exists`);
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { TagList } from "#constants";
|
||||
import { commandModule, CommandType } from "@sern/handler";
|
||||
import { writeFileSync } from "fs";
|
||||
import { createRequire } from "module";
|
||||
import type { TagData } from "../../types";
|
||||
import type { TagData } from "typings";
|
||||
const require = createRequire(import.meta.url);
|
||||
|
||||
export default commandModule({
|
||||
@@ -25,7 +26,7 @@ export default commandModule({
|
||||
: [],
|
||||
};
|
||||
const filePath = `./tags.json`;
|
||||
const file: TagData[] = require(`${process.cwd()}/tags.json`);
|
||||
const file: TagData[] = require(TagList);
|
||||
const oldTag = file.find((t) => t.name === (ctx.user.data as { tag: string }).tag)!;
|
||||
|
||||
const similarKeywords = file.filter(
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { ApplicationCommandOptionType, EmbedBuilder } from "discord.js";
|
||||
import { cooldown, publish } from "#plugins";
|
||||
import { parse } from "jsdoc-parse-plus";
|
||||
import { slashCommand } from "#utils";
|
||||
import { slashCommand, require, cutText } from "#utils";
|
||||
import type { Plugin } from "typings";
|
||||
import { PluginList } from "#constants";
|
||||
|
||||
export default slashCommand({
|
||||
description: "View sern plugins",
|
||||
@@ -15,17 +16,20 @@ export default slashCommand({
|
||||
command: {
|
||||
onEvent: [],
|
||||
async execute(ctx) {
|
||||
const { cache } = ctx.client;
|
||||
const focus = ctx.options.getFocused();
|
||||
if (!cache) return ctx.respond([{ name: "No plugins found", value: "" }]);
|
||||
const data = [...cache.values()] as Data[];
|
||||
const plugins = require(PluginList) as Plugin[];
|
||||
|
||||
const focus = ctx.options.getFocused();
|
||||
if (!plugins.length) return ctx.respond([{ name: "No plugins found", value: "" }]);
|
||||
|
||||
const filtered = plugins.filter((p) =>
|
||||
p.name.toLowerCase().includes(focus.toLowerCase())
|
||||
);
|
||||
|
||||
const plugins = data.map((d) => {
|
||||
const name = d.name.replace(".ts", "");
|
||||
return { name, value: d.download_url };
|
||||
});
|
||||
return ctx.respond(
|
||||
plugins.filter((p) => p.name.toLowerCase().includes(focus?.toLowerCase()))
|
||||
filtered.map((p) => ({
|
||||
name: p.name,
|
||||
value: p.link,
|
||||
}))
|
||||
);
|
||||
},
|
||||
},
|
||||
@@ -41,38 +45,38 @@ export default slashCommand({
|
||||
),
|
||||
],
|
||||
async execute(ctx, [, options]) {
|
||||
if (!ctx.client.cache) return ctx.reply("Plugins are uncached, contact Evo!");
|
||||
const plugins = require(PluginList) as Plugin[];
|
||||
|
||||
if (!plugins.length) return ctx.reply("Plugins are uncached, contact Evo!");
|
||||
|
||||
const url = options.getString("plugin", true);
|
||||
const name = ctx.client.cache.findKey((d) => d.download_url === url) as string;
|
||||
const plugin = plugins.find((p) => p.link === url);
|
||||
|
||||
if (!name || !ctx.client.cache.get(name)!.rawData)
|
||||
if (!plugin) {
|
||||
return ctx.reply(`No plugin found at this [link](<${url}>)`);
|
||||
|
||||
const JSdoc = parse(ctx.client.cache.get(name)!.rawData) as A;
|
||||
const github = `https://github.com/sern-handler/awesome-plugins/blob/main/TypeScript/${name}.ts`;
|
||||
}
|
||||
|
||||
const embed = new EmbedBuilder()
|
||||
.setColor("Random")
|
||||
.setTimestamp()
|
||||
.setTitle(`${name}`)
|
||||
.setURL(github)
|
||||
.setTitle(plugin.name)
|
||||
.setURL(plugin.link)
|
||||
.setFields(
|
||||
{
|
||||
name: "Description",
|
||||
value: JSdoc.description.value,
|
||||
value: plugin.description,
|
||||
},
|
||||
{
|
||||
name: "Version",
|
||||
value: JSdoc.version.value,
|
||||
value: plugin.version,
|
||||
},
|
||||
{
|
||||
name: "Author",
|
||||
value: parseAuthor(JSdoc.author.value),
|
||||
value: plugin.author.map(parseAuthor).join("\n"),
|
||||
},
|
||||
{
|
||||
name: "Example",
|
||||
value: (JSdoc as unknown as B).example[0].value,
|
||||
value: plugin.example,
|
||||
}
|
||||
);
|
||||
|
||||
@@ -94,20 +98,3 @@ export interface Data {
|
||||
download_url: string;
|
||||
rawData: string;
|
||||
}
|
||||
|
||||
interface ParsedData {
|
||||
author: DocData;
|
||||
description: DocData;
|
||||
version: DocData;
|
||||
example: DocData[];
|
||||
requires?: DocData[];
|
||||
}
|
||||
|
||||
interface DocData {
|
||||
tag: string;
|
||||
value: string;
|
||||
raw: string;
|
||||
}
|
||||
|
||||
type A = Record<keyof ParsedData, DocData>;
|
||||
type B = Record<keyof ParsedData, DocData[]>;
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
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 { writeFileSync } from "fs";
|
||||
import { ownerOnly, publish } from "#plugins";
|
||||
import { Evo, PluginList } from "#constants";
|
||||
import { slashCommand } from "#utils";
|
||||
import type { Plugin } from "typings";
|
||||
|
||||
export default slashCommand({
|
||||
plugins: [
|
||||
refreshCache(),
|
||||
publish({
|
||||
dmPermission: false,
|
||||
defaultMemberPermissions: ["Administrator"],
|
||||
@@ -16,31 +14,25 @@ export default slashCommand({
|
||||
],
|
||||
description: "refresh plugins cache",
|
||||
async execute(ctx) {
|
||||
const success = await cp(ctx.client);
|
||||
if (!success)
|
||||
return ctx.reply({
|
||||
content: "Fetch failed!",
|
||||
ephemeral: true,
|
||||
});
|
||||
return ctx.reply({
|
||||
content: `Refreshed Plugins! [${success.size} plugins]`,
|
||||
ephemeral: true,
|
||||
await ctx.interaction.deferReply({ ephemeral: true });
|
||||
const size = await cp();
|
||||
if (!size) return ctx.interaction.editReply({ content: "Fetch failed!" });
|
||||
return ctx.interaction.editReply({
|
||||
content: `Refreshed ${size} Plugins!`,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
export async function cp(client: Client) {
|
||||
const cache: Collection<string, Data> = new Collection();
|
||||
const link = `https://api.github.com/repos/sern-handler/awesome-plugins/contents/TypeScript`;
|
||||
/**
|
||||
* Downloads the plugin list from github and writes it to the cache
|
||||
* @returns {Promise<number | null>} The number of plugins fetched
|
||||
*/
|
||||
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 Data[];
|
||||
// TODO: use octokit instead of fetch
|
||||
for (const data of dataArray) {
|
||||
const name = data.name.replace(".ts", "");
|
||||
data.rawData = await (await fetch(data.download_url)).text().catch(() => "");
|
||||
cache.set(name, data);
|
||||
}
|
||||
client.cache = cache;
|
||||
return cache;
|
||||
const dataArray = (await resp.json()) as Plugin[];
|
||||
|
||||
writeFileSync(PluginList, JSON.stringify(dataArray, null, 2), { flag: "w" });
|
||||
return dataArray.length;
|
||||
}
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
import { ApplicationCommandOptionType, EmbedBuilder } from "discord.js";
|
||||
import { existsSync } from "fs";
|
||||
import { publish } from "#plugins";
|
||||
import { Paginator, slashCommand } from "#utils";
|
||||
|
||||
import { createRequire } from "module";
|
||||
import type { TagData } from "../types/index.js";
|
||||
const require = createRequire(import.meta.url);
|
||||
import { Paginator, slashCommand, require } from "#utils";
|
||||
import { Tag, type TagData } from "typings";
|
||||
import { TagList } from "#constants";
|
||||
|
||||
export default slashCommand({
|
||||
description: "Send a tag",
|
||||
@@ -30,12 +28,11 @@ export default slashCommand({
|
||||
command: {
|
||||
onEvent: [],
|
||||
execute(ctx) {
|
||||
const filePath = `./tags.json`;
|
||||
const focus = ctx.options.getFocused();
|
||||
if (!existsSync(filePath)) {
|
||||
if (!existsSync(`./tags.json`)) {
|
||||
return ctx.respond([{ name: "No tags found", value: "" }]);
|
||||
} else {
|
||||
const file: TagData[] = require(`${process.cwd()}/tags.json`);
|
||||
const file: TagData[] = require(TagList);
|
||||
const tags = file.map((t) => t.name);
|
||||
return ctx.respond(
|
||||
tags
|
||||
@@ -62,7 +59,7 @@ export default slashCommand({
|
||||
const subCmd = options.getSubcommand();
|
||||
switch (subCmd) {
|
||||
case "list": {
|
||||
const file: TagData[] = require(`${process.cwd()}/tags.json`);
|
||||
const file: TagData[] = require(TagList);
|
||||
const embeds = file.map((tag) => {
|
||||
const embed = new EmbedBuilder()
|
||||
.setTitle(tag.name)
|
||||
@@ -91,7 +88,7 @@ export default slashCommand({
|
||||
const user = options.getUser("target");
|
||||
const mention = user ? `**Tag suggestion for:** ${user}\n\n` : "";
|
||||
const tag = options.getString("tag", true);
|
||||
const file: TagData[] = require(`${process.cwd()}/tags.json`);
|
||||
const file: TagData[] = require(TagList);
|
||||
const tagData = file.find((t) => t.name === tag);
|
||||
if (!tagData) {
|
||||
return ctx.reply(`No tag found with name __${tag}__`);
|
||||
|
||||
@@ -7,9 +7,9 @@ import {
|
||||
} from "discord.js";
|
||||
import { existsSync, writeFileSync } from "fs";
|
||||
import { createRequire } from "module";
|
||||
import { Evo, Seren } from "#constants";
|
||||
import { Evo, Seren, TagList } from "#constants";
|
||||
import { ownerOnly, publish } from "#plugins";
|
||||
import type { TagData } from "../types";
|
||||
import type { TagData } from "typings";
|
||||
import { slashCommand } from "#utils";
|
||||
const require = createRequire(import.meta.url);
|
||||
|
||||
@@ -41,7 +41,7 @@ export default slashCommand({
|
||||
if (!existsSync(filePath)) {
|
||||
return ctx.respond([{ name: "No tags found", value: "" }]);
|
||||
} else {
|
||||
const file: TagData[] = require(`${process.cwd()}/tags.json`);
|
||||
const file: TagData[] = require(TagList);
|
||||
const tags = file.map((t) => t.name);
|
||||
return ctx.respond(
|
||||
tags
|
||||
@@ -75,7 +75,7 @@ export default slashCommand({
|
||||
if (!existsSync(filePath)) {
|
||||
return ctx.respond([{ name: "No tags found", value: "" }]);
|
||||
} else {
|
||||
const file: TagData[] = require(`${process.cwd()}/tags.json`);
|
||||
const file: TagData[] = require(TagList);
|
||||
const tags = file.map((t) => t.name);
|
||||
return ctx.respond(
|
||||
tags
|
||||
@@ -95,7 +95,7 @@ export default slashCommand({
|
||||
const [, options] = args;
|
||||
const subcmd = options.getSubcommand();
|
||||
|
||||
const file: TagData[] = require(`${process.cwd()}/tags.json`);
|
||||
const file: TagData[] = require(TagList);
|
||||
|
||||
if (subcmd === "create") {
|
||||
const modal = new ModalBuilder().setTitle("Tag Creation").setCustomId("@sern/tag/create");
|
||||
@@ -185,7 +185,7 @@ export default slashCommand({
|
||||
return context.reply("Tag not found");
|
||||
}
|
||||
file.splice(file.indexOf(tagData), 1);
|
||||
writeFileSync(`${process.cwd()}/tags.json`, JSON.stringify(file, null, 2));
|
||||
writeFileSync(TagList, JSON.stringify(file, null, 2));
|
||||
|
||||
return context.reply(`Tag ${tag} deleted`);
|
||||
}
|
||||
|
||||
@@ -13,3 +13,6 @@ export const enum Emojis {
|
||||
IssueClosed = "<:issue_closed:1101716515771920424>",
|
||||
IssueNotPlanned = "<:issue_notplanned:1101719419434045540>",
|
||||
}
|
||||
|
||||
export const PluginList = `${process.cwd()}/pluginlist.json`;
|
||||
export const TagList = `${process.cwd()}/tags.json`;
|
||||
@@ -2,9 +2,10 @@ import { eventModule, EventType } from "@sern/handler";
|
||||
import { ActionRowBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder, Message } from "discord.js";
|
||||
import { createRequire } from "module";
|
||||
import { FuzzyMatcher } from "../utils/FuzzyMatcher.js";
|
||||
import type { TagData, TagMessage } from "../types/index.js";
|
||||
import type { TagData, TagMessage } from "typings";
|
||||
import { TagList } from "#constants";
|
||||
const require = createRequire(import.meta.url);
|
||||
const file: TagData[] = require(`${process.cwd()}/tags.json`);
|
||||
const file: TagData[] = require(TagList);
|
||||
|
||||
export default eventModule({
|
||||
type: EventType.Discord,
|
||||
|
||||
@@ -3,6 +3,7 @@ import { Dependencies, Sern, single, Singleton } from "@sern/handler";
|
||||
import "dotenv/config";
|
||||
import { randomStatus, SernLogger /*CommandSyncer*/ } from "#utils";
|
||||
import { Octokit } from "@octokit/rest";
|
||||
import { cp } from "./commands/refresh.js";
|
||||
|
||||
const client = new Client({
|
||||
intents: [
|
||||
@@ -48,10 +49,11 @@ Sern.init({
|
||||
},
|
||||
});
|
||||
|
||||
client.once("ready", (client) => {
|
||||
client.once("ready", async (client) => {
|
||||
randomStatus(client);
|
||||
const [logger] = useContainer("@sern/logger");
|
||||
logger.info({ message: `[✅]: Logged in as ${client.user.username}` });
|
||||
await cp();
|
||||
});
|
||||
|
||||
await client.login();
|
||||
|
||||
@@ -2,4 +2,3 @@ export * from "./channelOnly.js";
|
||||
export * from "./cooldown.js";
|
||||
export * from "./ownerOnly.js";
|
||||
export * from "./publish.js";
|
||||
export * from "./refreshCache.js";
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
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";
|
||||
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" {
|
||||
interface Client {
|
||||
cache: Collection<string, Data> | null;
|
||||
data: unknown;
|
||||
}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
export * from "./Tags.js";
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { Message, User } from "discord.js";
|
||||
import { findBestMatch } from "string-similarity";
|
||||
import type { TagData } from "../types/index.js";
|
||||
import type { TagData } from "typings";
|
||||
|
||||
export class FuzzyMatcher {
|
||||
public constructor(private readonly message: Message, private readonly tags: TagData[]) {}
|
||||
|
||||
6
src/utils/cutText.ts
Normal file
6
src/utils/cutText.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
export function cutText(text: string) {
|
||||
if (text.length > 100) {
|
||||
return text.slice(0, 97) + "...";
|
||||
}
|
||||
return text;
|
||||
}
|
||||
@@ -8,4 +8,6 @@ export * from "./randomStatus.js";
|
||||
export * from "./codeUpload.js";
|
||||
export * from "./Logger.js";
|
||||
export * from "./composable/slashCommand.js";
|
||||
export * from "./require.js";
|
||||
export * from "./cutText.js";
|
||||
//export * from './SyncCommands.js';
|
||||
|
||||
2
src/utils/require.ts
Normal file
2
src/utils/require.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
import { createRequire } from "module";
|
||||
export const require = createRequire(import.meta.url);
|
||||
3
typings/index.ts
Normal file
3
typings/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export * from './docs.js'
|
||||
export * from './plugin.js'
|
||||
export * from './Tags.js'
|
||||
9
typings/plugin.ts
Normal file
9
typings/plugin.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
export interface Plugin {
|
||||
description: string;
|
||||
hash: string;
|
||||
name: string;
|
||||
author: string[];
|
||||
link: string;
|
||||
example: string;
|
||||
version: string;
|
||||
}
|
||||
Reference in New Issue
Block a user