feat: v1 done
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
node_modules/
|
||||
.env
|
||||
77
dist/commands/issue.js
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
import { commandModule, CommandType } from '@sern/handler';
|
||||
import { publish } from '../plugins/publish.js';
|
||||
import { ApplicationCommandOptionType, codeBlock, EmbedBuilder } from 'discord.js';
|
||||
import { linear } from '../index.js';
|
||||
import dayjs from 'dayjs';
|
||||
function statusEmojiResolver(type) {
|
||||
switch (type) {
|
||||
case 'backlog':
|
||||
return '<:linearBacklog:1129435189207113821>';
|
||||
case 'unstarted':
|
||||
return '<:linearTodo:1129435201647415346>';
|
||||
case 'started':
|
||||
return '<:linearInProgress:1129435196928835686>';
|
||||
case 'completed':
|
||||
return '<:linearDone:1129435193820839977>';
|
||||
case 'canceled':
|
||||
return '<:linearCanceledOrDuplicate:1129435191845335100>';
|
||||
}
|
||||
}
|
||||
function issuePriorityResolver(priorityNumber) {
|
||||
switch (priorityNumber) {
|
||||
case 0:
|
||||
return { emoji: '<:linearNoPriority:1129447473400782848>', title: 'No priority' };
|
||||
case 1:
|
||||
return { emoji: '<:linearUrgent:1129447509270474832>', title: 'Urgent' };
|
||||
case 2:
|
||||
return { emoji: '<:linearHigh:1129447346514702356>', title: 'High' };
|
||||
case 3:
|
||||
return { emoji: '<:linearMedium:1129447410322657422>', title: 'Medium' };
|
||||
case 4:
|
||||
return { emoji: '<:linearLow:1129447378823422062>', title: 'Low' };
|
||||
}
|
||||
}
|
||||
export default commandModule({
|
||||
type: CommandType.Slash,
|
||||
plugins: [publish()],
|
||||
description: 'Mention a linear issue',
|
||||
options: [
|
||||
{
|
||||
name: 'issue',
|
||||
description: 'Look up the issue',
|
||||
type: ApplicationCommandOptionType.String,
|
||||
required: true,
|
||||
autocomplete: true,
|
||||
command: {
|
||||
onEvent: [],
|
||||
async execute(ctx) {
|
||||
const focusedValue = ctx.options.getFocused();
|
||||
const choices = (await linear.issues()).nodes;
|
||||
const generatedString = choices.map(choice => { return { generatedString: `${choice.identifier} - ${choice.title}`, id: choice.id }; });
|
||||
const filtered = generatedString.filter(choice => choice.generatedString.includes(focusedValue)).slice(0, 25);
|
||||
await ctx.respond(filtered.map(choice => ({ name: choice.generatedString, value: choice.id })));
|
||||
},
|
||||
}
|
||||
}
|
||||
],
|
||||
execute: async (ctx, [, args]) => {
|
||||
try {
|
||||
const issueid = args.getString('issue', true);
|
||||
const issue = await linear.issue(issueid);
|
||||
const issueCreator = await issue.creator;
|
||||
const issueState = await issue.state;
|
||||
const issuePriority = issue.priority;
|
||||
const issueAssignee = await issue.assignee;
|
||||
const issueProject = await issue.project;
|
||||
const embed = new EmbedBuilder()
|
||||
.setColor('Random')
|
||||
.setAuthor({ name: issueCreator.displayName || issueCreator.email, iconURL: issueCreator.avatarUrl, url: issueCreator.url })
|
||||
.setTitle(issue.title)
|
||||
.setDescription(`${issue.description ? codeBlock(issue.description) : ''}\nInfo:\n- Status: ${statusEmojiResolver(issueState.type)} ${issueState.name}\n- Priority: ${issuePriorityResolver(issuePriority).emoji} ${issuePriorityResolver(issuePriority).title}\n- Assignee: ${issueAssignee ? `[${issueAssignee.name}](${issueAssignee.url})` : 'none'}\n- Project: ${issueProject ? `[${issueProject.name}](${issueProject.url})` : 'none'}\n- On project milestone: ${issue.projectMilestone || 'none'}\n- Due date: ${issue.dueDate ? dayjs(issue.dueDate).format('MM/DD/YYYY HH:mm') : 'none'}`);
|
||||
ctx.reply({ embeds: [embed] });
|
||||
}
|
||||
catch {
|
||||
await ctx.reply({ content: `Something went wrong while trying to run the command. Try again.`, ephemeral: true });
|
||||
}
|
||||
},
|
||||
});
|
||||
33
dist/index.js
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
import { Client, GatewayIntentBits } from 'discord.js';
|
||||
import { Sern, makeDependencies, single } from '@sern/handler';
|
||||
import { LinearClient } from '@linear/sdk';
|
||||
import 'dotenv/config';
|
||||
const client = new Client({
|
||||
intents: [
|
||||
GatewayIntentBits.Guilds,
|
||||
GatewayIntentBits.GuildMessages,
|
||||
],
|
||||
});
|
||||
/**
|
||||
* Where all of your dependencies are composed.
|
||||
* '@sern/client' is usually your Discord Client.
|
||||
* View documentation for pluggable dependencies
|
||||
* Configure your dependency root to your liking.
|
||||
* It follows the npm package iti https://itijs.org/.
|
||||
* Use this function to access all of your dependencies.
|
||||
* This is used for external event modules as well
|
||||
*/
|
||||
await makeDependencies({
|
||||
build: (root) => root
|
||||
.add({ '@sern/client': single(() => client) })
|
||||
});
|
||||
export const linear = new LinearClient({
|
||||
apiKey: process.env.LINEAR_API
|
||||
});
|
||||
//View docs for all options
|
||||
Sern.init({
|
||||
commands: 'dist/commands',
|
||||
// events: 'dist/events', //(optional)
|
||||
});
|
||||
client.on('ready', () => console.log('Client ready!'));
|
||||
client.login();
|
||||
129
dist/plugins/publish.js
vendored
Normal file
@@ -0,0 +1,129 @@
|
||||
// @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 { CommandInitPlugin, CommandType, controller, Service, } from "@sern/handler";
|
||||
import { ApplicationCommandType, ApplicationCommandOptionType, } from "discord.js";
|
||||
export const CommandTypeRaw = {
|
||||
[CommandType.Both]: ApplicationCommandType.ChatInput,
|
||||
[CommandType.CtxUser]: ApplicationCommandType.User,
|
||||
[CommandType.CtxMsg]: ApplicationCommandType.Message,
|
||||
[CommandType.Slash]: ApplicationCommandType.ChatInput,
|
||||
};
|
||||
export function publish(options) {
|
||||
return CommandInitPlugin(async ({ module }) => {
|
||||
// Users need to provide their own useContainer function.
|
||||
const client = Service("@sern/client");
|
||||
const defaultOptions = {
|
||||
guildIds: [],
|
||||
dmPermission: undefined,
|
||||
defaultMemberPermissions: null,
|
||||
};
|
||||
options = { ...defaultOptions, ...options };
|
||||
let { defaultMemberPermissions, dmPermission, guildIds } = options;
|
||||
function c(e) {
|
||||
console.error("publish command didnt work for", module.name);
|
||||
console.error(e);
|
||||
}
|
||||
const log = (...message) => () => console.log(...message);
|
||||
const logged = (...message) => 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 = (t) => {
|
||||
return (is, els) => ((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.options ?? []), []),
|
||||
defaultMemberPermissions,
|
||||
dmPermission,
|
||||
};
|
||||
};
|
||||
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!`));
|
||||
}
|
||||
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 === 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;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
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) {
|
||||
return ops.map((el) => {
|
||||
switch (el.type) {
|
||||
case ApplicationCommandOptionType.String:
|
||||
case ApplicationCommandOptionType.Number:
|
||||
case ApplicationCommandOptionType.Integer: {
|
||||
return el.autocomplete && "command" in el
|
||||
? (({ command, ...el }) => el)(el)
|
||||
: el;
|
||||
}
|
||||
default:
|
||||
return el;
|
||||
}
|
||||
});
|
||||
}
|
||||
1
dist/util/uuid-check.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export const uuidcheck = /^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/gi;
|
||||
29
package.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "ts-example",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "dist/index.js",
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"start": "tsc && node ./dist/index.js",
|
||||
"dev": "tsc-watch --onSuccess \"node dist/index.js\""
|
||||
},
|
||||
"keywords": [
|
||||
"typescript",
|
||||
"sern",
|
||||
"discord.js"
|
||||
],
|
||||
"license": "UNLICENSED",
|
||||
"dependencies": {
|
||||
"@linear/sdk": "^6.0.0",
|
||||
"@sern/handler": "alpha",
|
||||
"dayjs": "^1.11.9",
|
||||
"discord.js": "latest",
|
||||
"dotenv": "^16.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^17.0.25",
|
||||
"typescript": "5.0"
|
||||
},
|
||||
"type": "module"
|
||||
}
|
||||
7
sern.config.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"language": "typescript",
|
||||
"paths": {
|
||||
"base": "src",
|
||||
"commands": "commands"
|
||||
}
|
||||
}
|
||||
97
src/commands/issue.ts
Normal file
@@ -0,0 +1,97 @@
|
||||
import { commandModule, CommandType } from '@sern/handler';
|
||||
import { publish } from '../plugins/publish.js';
|
||||
import { ApplicationCommandOptionType, codeBlock, EmbedBuilder } from 'discord.js';
|
||||
import { linear } from '../index.js';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
function statusEmojiResolver(type: IssueStateType) {
|
||||
switch (type) {
|
||||
case 'backlog':
|
||||
return '<:linearBacklog:1129435189207113821>'
|
||||
case 'unstarted':
|
||||
return '<:linearTodo:1129435201647415346>'
|
||||
case 'started':
|
||||
return '<:linearInProgress:1129435196928835686>'
|
||||
case 'completed':
|
||||
return '<:linearDone:1129435193820839977>'
|
||||
case 'canceled':
|
||||
return '<:linearCanceledOrDuplicate:1129435191845335100>'
|
||||
}
|
||||
}
|
||||
|
||||
function issuePriorityResolver(priorityNumber: IssuePriorityPossibleNumbers): IssuePriority {
|
||||
switch (priorityNumber) {
|
||||
case 0:
|
||||
return { emoji: '<:linearNoPriority:1129447473400782848>', title: 'No priority' }
|
||||
case 1:
|
||||
return { emoji: '<:linearUrgent:1129447509270474832>', title: 'Urgent' }
|
||||
case 2:
|
||||
return { emoji: '<:linearHigh:1129447346514702356>', title: 'High' }
|
||||
case 3:
|
||||
return { emoji: '<:linearMedium:1129447410322657422>', title: 'Medium' }
|
||||
case 4:
|
||||
return { emoji: '<:linearLow:1129447378823422062>', title: 'Low' }
|
||||
}
|
||||
}
|
||||
|
||||
export default commandModule({
|
||||
type: CommandType.Slash,
|
||||
plugins: [publish()],
|
||||
description: 'Mention a linear issue',
|
||||
options: [
|
||||
{
|
||||
name: 'issue',
|
||||
description: 'Look up the issue',
|
||||
type: ApplicationCommandOptionType.String,
|
||||
required: true,
|
||||
autocomplete: true,
|
||||
command: {
|
||||
onEvent: [],
|
||||
async execute (ctx) {
|
||||
const focusedValue = ctx.options.getFocused();
|
||||
const choices = (await linear.issues()).nodes
|
||||
const generatedString = choices.map(choice => { return { generatedString: `${choice.identifier} - ${choice.title}`, id: choice.id } as Choice })
|
||||
const filtered = generatedString.filter(choice => choice.generatedString.includes(focusedValue)).slice(0, 25)
|
||||
await ctx.respond(
|
||||
filtered.map(choice => ({ name: choice.generatedString, value: choice.id })),
|
||||
);
|
||||
},
|
||||
}
|
||||
}
|
||||
],
|
||||
execute: async (ctx, [, args]) => {
|
||||
try {
|
||||
const issueid = args.getString('issue', true)
|
||||
|
||||
const issue = await linear.issue(issueid)
|
||||
const issueCreator = await issue.creator!
|
||||
const issueState = await issue.state!
|
||||
const issuePriority = issue.priority as IssuePriorityPossibleNumbers
|
||||
const issueAssignee = await issue.assignee
|
||||
const issueProject = await issue.project
|
||||
|
||||
const embed = new EmbedBuilder()
|
||||
.setColor('Random')
|
||||
.setAuthor({ name: issueCreator.displayName || issueCreator.email!, iconURL: issueCreator.avatarUrl, url: issueCreator.url })
|
||||
.setTitle(issue.title)
|
||||
.setDescription(`${issue.description ? codeBlock(issue.description) : ''}\nInfo:\n- Status: ${statusEmojiResolver(issueState.type as IssueStateType)} ${issueState.name}\n- Priority: ${issuePriorityResolver(issuePriority).emoji} ${issuePriorityResolver(issuePriority).title}\n- Assignee: ${issueAssignee ? `[${issueAssignee.name}](${issueAssignee.url})` : 'none'}\n- Project: ${issueProject ? `[${issueProject.name}](${issueProject.url})` : 'none'}\n- On project milestone: ${issue.projectMilestone || 'none'}\n- Due date: ${issue.dueDate ? dayjs(issue.dueDate).format('MM/DD/YYYY HH:mm') : 'none'}`)
|
||||
|
||||
ctx.reply({ embeds: [embed] })
|
||||
} catch {
|
||||
await ctx.reply({ content: `Something went wrong while trying to run the command. Try again.`, ephemeral: true })
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
interface Choice {
|
||||
generatedString: string,
|
||||
id: string
|
||||
}
|
||||
|
||||
type IssueStateType = 'backlog' | 'unstarted' | 'started' | 'completed' | 'canceled'
|
||||
type IssuePriorityPossibleNumbers = 0 | 1 | 2 | 3 | 4
|
||||
|
||||
interface IssuePriority {
|
||||
emoji: string
|
||||
title: string
|
||||
}
|
||||
17
src/dependencies.d.ts
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* This file serves as intellisense for sern projects.
|
||||
* Types are declared here for dependencies to function properly
|
||||
* Service(s) api rely on this file to provide a better developer experience.
|
||||
*/
|
||||
|
||||
import { SernEmitter, Logging, CoreModuleStore, ModuleManager, ErrorHandling, CoreDependencies, Singleton } from '@sern/handler'
|
||||
import { Client } from 'discord.js'
|
||||
|
||||
declare global {
|
||||
interface Dependencies extends CoreDependencies {
|
||||
'@sern/client': Singleton<Client>
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export {}
|
||||
1
src/icons/priority/high.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg fill="#9b9ba9" width="16" height="16" viewBox="0 0 16 16" aria-label="High Priority"><rect x="1" y="8" width="3" height="6" rx="1"></rect><rect x="6" y="5" width="3" height="9" rx="1"></rect><rect x="11" y="2" width="3" height="12" rx="1"></rect></svg>
|
||||
|
After Width: | Height: | Size: 257 B |
1
src/icons/priority/low.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg fill="#DCD8FE93" width="16" height="16" viewBox="0 0 16 16" aria-label="Low Priority"><rect x="1" y="8" width="3" height="6" rx="1"></rect><rect x="6" y="5" width="3" height="9" rx="1" fill-opacity="0.4"></rect><rect x="11" y="2" width="3" height="12" rx="1" fill-opacity="0.4"></rect></svg>
|
||||
|
After Width: | Height: | Size: 296 B |
1
src/icons/priority/medium.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg fill="#9b9ba9" width="16" height="16" viewBox="0 0 16 16" aria-label="Medium Priority"><rect x="1" y="8" width="3" height="6" rx="1"></rect><rect x="6" y="5" width="3" height="9" rx="1"></rect><rect x="11" y="2" width="3" height="12" rx="1" fill-opacity="0.4"></rect></svg>
|
||||
|
After Width: | Height: | Size: 278 B |
1
src/icons/priority/noPriority.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" aria-label="No Priority" fill="#9b9ba9"><rect x="1" y="7.25" width="3" height="1.5" rx="0.5" opacity="0.9"></rect><rect x="6" y="7.25" width="3" height="1.5" rx="0.5" opacity="0.9"></rect><rect x="11" y="7.25" width="3" height="1.5" rx="0.5" opacity="0.9"></rect></svg>
|
||||
|
After Width: | Height: | Size: 317 B |
1
src/icons/priority/urgent.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="#9b9ba9" aria-label="Urgent Priority"><path d="M3 1.346a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-10a2 2 0 0 0-2-2H3Zm3.914 3h1.738L8.5 9.948H7.07l-.156-5.602Zm1.809 7.164a.95.95 0 0 1-.938.938.934.934 0 1 1 0-1.867c.5 0 .934.417.938.929Z"></path></svg>
|
||||
|
After Width: | Height: | Size: 314 B |
1
src/icons/status/backlog.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="14" height="14" viewBox="0 0 14 14" aria-label="Backlog" fill="#bec2c8" class="color-override sc-jigNDC jrRYYl"><path d="M13.9408 7.91426L11.9576 7.65557C11.9855 7.4419 12 7.22314 12 7C12 6.77686 11.9855 6.5581 11.9576 6.34443L13.9408 6.08573C13.9799 6.38496 14 6.69013 14 7C14 7.30987 13.9799 7.61504 13.9408 7.91426ZM13.4688 4.32049C13.2328 3.7514 12.9239 3.22019 12.5538 2.73851L10.968 3.95716C11.2328 4.30185 11.4533 4.68119 11.6214 5.08659L13.4688 4.32049ZM11.2615 1.4462L10.0428 3.03204C9.69815 2.76716 9.31881 2.54673 8.91341 2.37862L9.67951 0.531163C10.2486 0.767153 10.7798 1.07605 11.2615 1.4462ZM7.91426 0.0591659L7.65557 2.04237C7.4419 2.01449 7.22314 2 7 2C6.77686 2 6.5581 2.01449 6.34443 2.04237L6.08574 0.059166C6.38496 0.0201343 6.69013 0 7 0C7.30987 0 7.61504 0.0201343 7.91426 0.0591659ZM4.32049 0.531164L5.08659 2.37862C4.68119 2.54673 4.30185 2.76716 3.95716 3.03204L2.73851 1.4462C3.22019 1.07605 3.7514 0.767153 4.32049 0.531164ZM1.4462 2.73851L3.03204 3.95716C2.76716 4.30185 2.54673 4.68119 2.37862 5.08659L0.531164 4.32049C0.767153 3.7514 1.07605 3.22019 1.4462 2.73851ZM0.0591659 6.08574C0.0201343 6.38496 0 6.69013 0 7C0 7.30987 0.0201343 7.61504 0.059166 7.91426L2.04237 7.65557C2.01449 7.4419 2 7.22314 2 7C2 6.77686 2.01449 6.5581 2.04237 6.34443L0.0591659 6.08574ZM0.531164 9.67951L2.37862 8.91341C2.54673 9.31881 2.76716 9.69815 3.03204 10.0428L1.4462 11.2615C1.07605 10.7798 0.767153 10.2486 0.531164 9.67951ZM2.73851 12.5538L3.95716 10.968C4.30185 11.2328 4.68119 11.4533 5.08659 11.6214L4.32049 13.4688C3.7514 13.2328 3.22019 12.9239 2.73851 12.5538ZM6.08574 13.9408L6.34443 11.9576C6.5581 11.9855 6.77686 12 7 12C7.22314 12 7.4419 11.9855 7.65557 11.9576L7.91427 13.9408C7.61504 13.9799 7.30987 14 7 14C6.69013 14 6.38496 13.9799 6.08574 13.9408ZM9.67951 13.4688L8.91341 11.6214C9.31881 11.4533 9.69815 11.2328 10.0428 10.968L11.2615 12.5538C10.7798 12.9239 10.2486 13.2328 9.67951 13.4688ZM12.5538 11.2615L10.968 10.0428C11.2328 9.69815 11.4533 9.31881 11.6214 8.91341L13.4688 9.67951C13.2328 10.2486 12.924 10.7798 12.5538 11.2615Z" stroke="none"></path></svg>
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
1
src/icons/status/canceledOrDuplicate.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="14" height="14" viewBox="0 0 14 14" aria-label="Canceled" fill="#95a2b3" class="color-override sc-jigNDC jrRYYl"><path fill-rule="evenodd" clip-rule="evenodd" d="M7 14C10.866 14 14 10.866 14 7C14 3.13401 10.866 0 7 0C3.13401 0 0 3.13401 0 7C0 10.866 3.13401 14 7 14ZM5.03033 3.96967C4.73744 3.67678 4.26256 3.67678 3.96967 3.96967C3.67678 4.26256 3.67678 4.73744 3.96967 5.03033L5.93934 7L3.96967 8.96967C3.67678 9.26256 3.67678 9.73744 3.96967 10.0303C4.26256 10.3232 4.73744 10.3232 5.03033 10.0303L7 8.06066L8.96967 10.0303C9.26256 10.3232 9.73744 10.3232 10.0303 10.0303C10.3232 9.73744 10.3232 9.26256 10.0303 8.96967L8.06066 7L10.0303 5.03033C10.3232 4.73744 10.3232 4.26256 10.0303 3.96967C9.73744 3.67678 9.26256 3.67678 8.96967 3.96967L7 5.93934L5.03033 3.96967Z" stroke="none"></path></svg>
|
||||
|
After Width: | Height: | Size: 812 B |
1
src/icons/status/done.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="14" height="14" viewBox="0 0 14 14" aria-label="Done" fill="#5e6ad2" class="color-override sc-jigNDC jrRYYl"><path fill-rule="evenodd" clip-rule="evenodd" d="M7 0C3.13401 0 0 3.13401 0 7C0 10.866 3.13401 14 7 14C10.866 14 14 10.866 14 7C14 3.13401 10.866 0 7 0ZM11.101 5.10104C11.433 4.76909 11.433 4.23091 11.101 3.89896C10.7691 3.56701 10.2309 3.56701 9.89896 3.89896L5.5 8.29792L4.10104 6.89896C3.7691 6.56701 3.2309 6.56701 2.89896 6.89896C2.56701 7.2309 2.56701 7.7691 2.89896 8.10104L4.89896 10.101C5.2309 10.433 5.7691 10.433 6.10104 10.101L11.101 5.10104Z"></path></svg>
|
||||
|
After Width: | Height: | Size: 590 B |
1
src/icons/status/inProgress.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" aria-label="In Progress" class="color-override sc-jigNDC jrRYYl"><rect x="1" y="1" width="12" height="12" rx="6" stroke="#f2c94c" stroke-width="2" fill="none"></rect><path fill="#f2c94c" stroke="none" d="M 3.5,3.5 L3.5,0 A3.5,3.5 0 0,1 3.5, 7 z" transform="translate(3.5,3.5)"></path></svg>
|
||||
|
After Width: | Height: | Size: 350 B |
1
src/icons/status/inReview.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" aria-label="In Progress" class="color-override sc-jigNDC jrRYYl"><rect x="1" y="1" width="12" height="12" rx="6" stroke="#0f783c" stroke-width="2" fill="none"></rect><path fill="#0f783c" stroke="none" d="M 3.5,3.5 L3.5,0 A3.5,3.5 0 1,1 0, 3.5 z" transform="translate(3.5,3.5)"></path></svg>
|
||||
|
After Width: | Height: | Size: 350 B |
1
src/icons/status/todo.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" aria-label="Todo" class="color-override sc-jigNDC jrRYYl"><rect x="1" y="1" width="12" height="12" rx="6" stroke="#e2e2e2" stroke-width="2" fill="none"></rect><path fill="#e2e2e2" stroke="none" d="M 3.5,3.5 L3.5,0 A3.5,3.5 0 0,1 3.5, 0 z" transform="translate(3.5,3.5)"></path></svg>
|
||||
|
After Width: | Height: | Size: 343 B |
40
src/index.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import { Client, GatewayIntentBits } from 'discord.js';
|
||||
import { Sern, makeDependencies, single } from '@sern/handler';
|
||||
import { LinearClient } from '@linear/sdk'
|
||||
import 'dotenv/config'
|
||||
|
||||
const client = new Client({
|
||||
intents: [
|
||||
GatewayIntentBits.Guilds,
|
||||
GatewayIntentBits.GuildMessages,
|
||||
],
|
||||
});
|
||||
|
||||
/**
|
||||
* Where all of your dependencies are composed.
|
||||
* '@sern/client' is usually your Discord Client.
|
||||
* View documentation for pluggable dependencies
|
||||
* Configure your dependency root to your liking.
|
||||
* It follows the npm package iti https://itijs.org/.
|
||||
* Use this function to access all of your dependencies.
|
||||
* This is used for external event modules as well
|
||||
*/
|
||||
await makeDependencies({
|
||||
build: (root) =>
|
||||
root
|
||||
.add({ '@sern/client': single(() => client) })
|
||||
});
|
||||
|
||||
export const linear = new LinearClient({
|
||||
apiKey: process.env.LINEAR_API
|
||||
})
|
||||
|
||||
//View docs for all options
|
||||
Sern.init({
|
||||
commands: 'dist/commands',
|
||||
// events: 'dist/events', //(optional)
|
||||
});
|
||||
|
||||
client.on('ready', () => console.log('Client ready!'))
|
||||
|
||||
client.login();
|
||||
207
src/plugins/publish.ts
Normal file
@@ -0,0 +1,207 @@
|
||||
// @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 {
|
||||
CommandInitPlugin,
|
||||
CommandType,
|
||||
controller,
|
||||
SernOptionsData,
|
||||
Service,
|
||||
SlashCommand,
|
||||
} from "@sern/handler";
|
||||
import {
|
||||
ApplicationCommandData,
|
||||
ApplicationCommandType,
|
||||
ApplicationCommandOptionType,
|
||||
PermissionResolvable,
|
||||
} from "discord.js";
|
||||
|
||||
export const CommandTypeRaw = {
|
||||
[CommandType.Both]: ApplicationCommandType.ChatInput,
|
||||
[CommandType.CtxUser]: ApplicationCommandType.User,
|
||||
[CommandType.CtxMsg]: ApplicationCommandType.Message,
|
||||
[CommandType.Slash]: ApplicationCommandType.ChatInput,
|
||||
} as const;
|
||||
|
||||
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 = Service("@sern/client");
|
||||
const defaultOptions = {
|
||||
guildIds: [],
|
||||
dmPermission: undefined,
|
||||
defaultMemberPermissions: null,
|
||||
};
|
||||
|
||||
options = { ...defaultOptions, ...options } as PublishOptions &
|
||||
ValidPublishOptions;
|
||||
let { defaultMemberPermissions, dmPermission, guildIds } =
|
||||
options as unknown as ValidPublishOptions;
|
||||
|
||||
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!`
|
||||
)
|
||||
);
|
||||
}
|
||||
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 === 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;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
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>) {
|
||||
return ops.map((el) => {
|
||||
switch (el.type) {
|
||||
case ApplicationCommandOptionType.String:
|
||||
case ApplicationCommandOptionType.Number:
|
||||
case ApplicationCommandOptionType.Integer: {
|
||||
return el.autocomplete && "command" in el
|
||||
? (({ command, ...el }) => el)(el)
|
||||
: el;
|
||||
}
|
||||
default:
|
||||
return el;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export type NonEmptyArray<T extends `${number}` = `${number}`> = [T, ...T[]];
|
||||
|
||||
export interface ValidPublishOptions {
|
||||
guildIds: string[];
|
||||
dmPermission: boolean;
|
||||
defaultMemberPermissions: PermissionResolvable;
|
||||
}
|
||||
|
||||
interface GuildPublishOptions {
|
||||
guildIds?: NonEmptyArray;
|
||||
defaultMemberPermissions?: PermissionResolvable;
|
||||
dmPermission?: never;
|
||||
}
|
||||
|
||||
interface GlobalPublishOptions {
|
||||
defaultMemberPermissions?: PermissionResolvable;
|
||||
dmPermission?: false;
|
||||
guildIds?: never;
|
||||
}
|
||||
|
||||
type BasePublishOptions = GuildPublishOptions | GlobalPublishOptions;
|
||||
|
||||
export type PublishOptions = BasePublishOptions &
|
||||
(
|
||||
| Required<Pick<BasePublishOptions, "defaultMemberPermissions">>
|
||||
| (
|
||||
| Required<Pick<BasePublishOptions, "dmPermission">>
|
||||
| Required<Pick<BasePublishOptions, "guildIds">>
|
||||
)
|
||||
);
|
||||
1
src/util/uuid-check.ts
Normal file
@@ -0,0 +1 @@
|
||||
export const uuidcheck = /^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/gi
|
||||
16
tsconfig.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
"target": "ESNext",
|
||||
"module": "ESNext",
|
||||
"outDir": "dist",
|
||||
"rootDir": "src",
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"noImplicitAny": true,
|
||||
"strictNullChecks": true,
|
||||
"skipLibCheck": true,
|
||||
"forceConsistentCasingInFileNames": true
|
||||
}
|
||||
}
|
||||
359
yarn.lock
Normal file
@@ -0,0 +1,359 @@
|
||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@discordjs/builders@^1.6.3":
|
||||
version "1.6.3"
|
||||
resolved "https://registry.yarnpkg.com/@discordjs/builders/-/builders-1.6.3.tgz#994b4fe57e77b47096f74bb5a1f664870a930a43"
|
||||
integrity sha512-CTCh8NqED3iecTNuiz49mwSsrc2iQb4d0MjMdmS/8pb69Y4IlzJ/DIy/p5GFlgOrFbNO2WzMHkWKQSiJ3VNXaw==
|
||||
dependencies:
|
||||
"@discordjs/formatters" "^0.3.1"
|
||||
"@discordjs/util" "^0.3.1"
|
||||
"@sapphire/shapeshift" "^3.8.2"
|
||||
discord-api-types "^0.37.41"
|
||||
fast-deep-equal "^3.1.3"
|
||||
ts-mixer "^6.0.3"
|
||||
tslib "^2.5.0"
|
||||
|
||||
"@discordjs/collection@^1.5.1":
|
||||
version "1.5.1"
|
||||
resolved "https://registry.yarnpkg.com/@discordjs/collection/-/collection-1.5.1.tgz#bc7ca557838dc29247bf19860426637f103bc383"
|
||||
integrity sha512-aWEc9DCf3TMDe9iaJoOnO2+JVAjeRNuRxPZQA6GVvBf+Z3gqUuWYBy2NWh4+5CLYq5uoc3MOvUQ5H5m8CJBqOA==
|
||||
|
||||
"@discordjs/formatters@^0.3.1":
|
||||
version "0.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@discordjs/formatters/-/formatters-0.3.1.tgz#81393cf25e6e3223361061629752ea727475e842"
|
||||
integrity sha512-M7X4IGiSeh4znwcRGcs+49B5tBkNDn4k5bmhxJDAUhRxRHTiFAOTVUNQ6yAKySu5jZTnCbSvTYHW3w0rAzV1MA==
|
||||
dependencies:
|
||||
discord-api-types "^0.37.41"
|
||||
|
||||
"@discordjs/rest@^1.7.1":
|
||||
version "1.7.1"
|
||||
resolved "https://registry.yarnpkg.com/@discordjs/rest/-/rest-1.7.1.tgz#eeef0e71a37c95fa27962129729b2aa9de8e3752"
|
||||
integrity sha512-Ofa9UqT0U45G/eX86cURQnX7gzOJLG2oC28VhIk/G6IliYgQF7jFByBJEykPSHE4MxPhqCleYvmsrtfKh1nYmQ==
|
||||
dependencies:
|
||||
"@discordjs/collection" "^1.5.1"
|
||||
"@discordjs/util" "^0.3.0"
|
||||
"@sapphire/async-queue" "^1.5.0"
|
||||
"@sapphire/snowflake" "^3.4.2"
|
||||
discord-api-types "^0.37.41"
|
||||
file-type "^18.3.0"
|
||||
tslib "^2.5.0"
|
||||
undici "^5.22.0"
|
||||
|
||||
"@discordjs/util@^0.3.0", "@discordjs/util@^0.3.1":
|
||||
version "0.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@discordjs/util/-/util-0.3.1.tgz#4e8737e1dcff7e9f5eccc3116fb44755b65b1e97"
|
||||
integrity sha512-HxXKYKg7vohx2/OupUN/4Sd02Ev3PBJ5q0gtjdcvXb0ErCva8jNHWfe/v5sU3UKjIB/uxOhc+TDOnhqffj9pRA==
|
||||
|
||||
"@discordjs/ws@^0.8.3":
|
||||
version "0.8.3"
|
||||
resolved "https://registry.yarnpkg.com/@discordjs/ws/-/ws-0.8.3.tgz#77db8d563b731a2198c1b40f63b1ef8d230504f7"
|
||||
integrity sha512-hcYtppanjHecbdNyCKQNH2I4RP9UrphDgmRgLYrATEQF1oo4sYSve7ZmGsBEXSzH72MO2tBPdWSThunbxUVk0g==
|
||||
dependencies:
|
||||
"@discordjs/collection" "^1.5.1"
|
||||
"@discordjs/rest" "^1.7.1"
|
||||
"@discordjs/util" "^0.3.1"
|
||||
"@sapphire/async-queue" "^1.5.0"
|
||||
"@types/ws" "^8.5.4"
|
||||
"@vladfrangu/async_event_emitter" "^2.2.1"
|
||||
discord-api-types "^0.37.41"
|
||||
tslib "^2.5.0"
|
||||
ws "^8.13.0"
|
||||
|
||||
"@graphql-typed-document-node/core@^3.1.0":
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@graphql-typed-document-node/core/-/core-3.2.0.tgz#5f3d96ec6b2354ad6d8a28bf216a1d97b5426861"
|
||||
integrity sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==
|
||||
|
||||
"@linear/sdk@^6.0.0":
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@linear/sdk/-/sdk-6.0.0.tgz#9c0c572e9fa9ae3978264226a0278e7671e8ce85"
|
||||
integrity sha512-EvDoE3pgnU6TW8GUP+BgiXSD0mKRNV/d5r4uxvCczVk6AxDiABDZJjkf1OowKECNyMo/GoNQZHmvSJqehtQoug==
|
||||
dependencies:
|
||||
"@graphql-typed-document-node/core" "^3.1.0"
|
||||
graphql "^15.4.0"
|
||||
isomorphic-unfetch "^3.1.0"
|
||||
|
||||
"@sapphire/async-queue@^1.5.0":
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@sapphire/async-queue/-/async-queue-1.5.0.tgz#2f255a3f186635c4fb5a2381e375d3dfbc5312d8"
|
||||
integrity sha512-JkLdIsP8fPAdh9ZZjrbHWR/+mZj0wvKS5ICibcLrRI1j84UmLMshx5n9QmL8b95d4onJ2xxiyugTgSAX7AalmA==
|
||||
|
||||
"@sapphire/shapeshift@^3.8.2":
|
||||
version "3.9.2"
|
||||
resolved "https://registry.yarnpkg.com/@sapphire/shapeshift/-/shapeshift-3.9.2.tgz#a9c12cd51e1bc467619bb56df804450dd14871ac"
|
||||
integrity sha512-YRbCXWy969oGIdqR/wha62eX8GNHsvyYi0Rfd4rNW6tSVVa8p0ELiMEuOH/k8rgtvRoM+EMV7Csqz77YdwiDpA==
|
||||
dependencies:
|
||||
fast-deep-equal "^3.1.3"
|
||||
lodash "^4.17.21"
|
||||
|
||||
"@sapphire/snowflake@^3.4.2":
|
||||
version "3.5.1"
|
||||
resolved "https://registry.yarnpkg.com/@sapphire/snowflake/-/snowflake-3.5.1.tgz#254521c188b49e8b2d4cc048b475fb2b38737fec"
|
||||
integrity sha512-BxcYGzgEsdlG0dKAyOm0ehLGm2CafIrfQTZGWgkfKYbj+pNNsorZ7EotuZukc2MT70E0UbppVbtpBrqpzVzjNA==
|
||||
|
||||
"@sern/handler@alpha":
|
||||
version "3.0.0-rc10"
|
||||
resolved "https://registry.yarnpkg.com/@sern/handler/-/handler-3.0.0-rc10.tgz#bcf476c39a3e43d6da1c1bbee1517fc98312542e"
|
||||
integrity sha512-bBlQ5zRkyk0oZUCc9pnJec1i0+yh3/bFBalOdGI9bPV+03bYhxOS4N95jpANn0cVo44p82N/nqQHo8wdfN3luA==
|
||||
dependencies:
|
||||
iti "^0.6.0"
|
||||
rxjs "^7.8.0"
|
||||
ts-results-es "^3.6.0"
|
||||
|
||||
"@tokenizer/token@^0.3.0":
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@tokenizer/token/-/token-0.3.0.tgz#fe98a93fe789247e998c75e74e9c7c63217aa276"
|
||||
integrity sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==
|
||||
|
||||
"@types/node@*":
|
||||
version "20.4.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.4.2.tgz#129cc9ae69f93824f92fac653eebfb4812ab4af9"
|
||||
integrity sha512-Dd0BYtWgnWJKwO1jkmTrzofjK2QXXcai0dmtzvIBhcA+RsG5h8R3xlyta0kGOZRNfL9GuRtb1knmPEhQrePCEw==
|
||||
|
||||
"@types/node@^17.0.25":
|
||||
version "17.0.45"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.45.tgz#2c0fafd78705e7a18b7906b5201a522719dc5190"
|
||||
integrity sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==
|
||||
|
||||
"@types/ws@^8.5.4":
|
||||
version "8.5.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.5.tgz#af587964aa06682702ee6dcbc7be41a80e4b28eb"
|
||||
integrity sha512-lwhs8hktwxSjf9UaZ9tG5M03PGogvFaH8gUgLNbN9HKIg0dvv6q+gkSuJ8HN4/VbyxkuLzCjlN7GquQ0gUJfIg==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@vladfrangu/async_event_emitter@^2.2.1":
|
||||
version "2.2.2"
|
||||
resolved "https://registry.yarnpkg.com/@vladfrangu/async_event_emitter/-/async_event_emitter-2.2.2.tgz#84c5a3f8d648842cec5cc649b88df599af32ed88"
|
||||
integrity sha512-HIzRG7sy88UZjBJamssEczH5q7t5+axva19UbZLO6u0ySbYPrwzWiXBcC0WuHyhKKoeCyneH+FvYzKQq/zTtkQ==
|
||||
|
||||
busboy@^1.6.0:
|
||||
version "1.6.0"
|
||||
resolved "https://registry.yarnpkg.com/busboy/-/busboy-1.6.0.tgz#966ea36a9502e43cdb9146962523b92f531f6893"
|
||||
integrity sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==
|
||||
dependencies:
|
||||
streamsearch "^1.1.0"
|
||||
|
||||
dayjs@^1.11.9:
|
||||
version "1.11.9"
|
||||
resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.9.tgz#9ca491933fadd0a60a2c19f6c237c03517d71d1a"
|
||||
integrity sha512-QvzAURSbQ0pKdIye2txOzNaHmxtUBXerpY0FJsFXUMKbIZeFm5ht1LS/jFsrncjnmtv8HsG0W2g6c0zUjZWmpA==
|
||||
|
||||
discord-api-types@^0.37.41:
|
||||
version "0.37.48"
|
||||
resolved "https://registry.yarnpkg.com/discord-api-types/-/discord-api-types-0.37.48.tgz#347907bce8f3c00e746b2a7afcf98628d7065731"
|
||||
integrity sha512-vu2NQJD7SZRjpKDC2DPNsxTz34KS53OrotA+LGRW6mcyT55Hjqu66aRrouzjYhea7tllL9I7rvWVX7bg3aT2AQ==
|
||||
|
||||
discord.js@latest:
|
||||
version "14.11.0"
|
||||
resolved "https://registry.yarnpkg.com/discord.js/-/discord.js-14.11.0.tgz#6529d49f30d10fc5a9ff8e6796661aa998769afe"
|
||||
integrity sha512-CkueWYFQ28U38YPR8HgsBR/QT35oPpMbEsTNM30Fs8loBIhnA4s70AwQEoy6JvLcpWWJO7GY0y2BUzZmuBMepQ==
|
||||
dependencies:
|
||||
"@discordjs/builders" "^1.6.3"
|
||||
"@discordjs/collection" "^1.5.1"
|
||||
"@discordjs/formatters" "^0.3.1"
|
||||
"@discordjs/rest" "^1.7.1"
|
||||
"@discordjs/util" "^0.3.1"
|
||||
"@discordjs/ws" "^0.8.3"
|
||||
"@sapphire/snowflake" "^3.4.2"
|
||||
"@types/ws" "^8.5.4"
|
||||
discord-api-types "^0.37.41"
|
||||
fast-deep-equal "^3.1.3"
|
||||
lodash.snakecase "^4.1.1"
|
||||
tslib "^2.5.0"
|
||||
undici "^5.22.0"
|
||||
ws "^8.13.0"
|
||||
|
||||
dotenv@^16.3.1:
|
||||
version "16.3.1"
|
||||
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.3.1.tgz#369034de7d7e5b120972693352a3bf112172cc3e"
|
||||
integrity sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==
|
||||
|
||||
fast-deep-equal@^3.1.3:
|
||||
version "3.1.3"
|
||||
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
|
||||
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
|
||||
|
||||
file-type@^18.3.0:
|
||||
version "18.5.0"
|
||||
resolved "https://registry.yarnpkg.com/file-type/-/file-type-18.5.0.tgz#604a001ba0d32577d4c3fa420ee104d656b914d2"
|
||||
integrity sha512-yvpl5U868+V6PqXHMmsESpg6unQ5GfnPssl4dxdJudBrr9qy7Fddt7EVX1VLlddFfe8Gj9N7goCZH22FXuSQXQ==
|
||||
dependencies:
|
||||
readable-web-to-node-stream "^3.0.2"
|
||||
strtok3 "^7.0.0"
|
||||
token-types "^5.0.1"
|
||||
|
||||
graphql@^15.4.0:
|
||||
version "15.8.0"
|
||||
resolved "https://registry.yarnpkg.com/graphql/-/graphql-15.8.0.tgz#33410e96b012fa3bdb1091cc99a94769db212b38"
|
||||
integrity sha512-5gghUc24tP9HRznNpV2+FIoq3xKkj5dTQqf4v0CpdPbFVwFkWoxOM+o+2OC9ZSvjEMTjfmG9QT+gcvggTwW1zw==
|
||||
|
||||
ieee754@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
|
||||
integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
|
||||
|
||||
inherits@^2.0.3:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
|
||||
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
||||
|
||||
isomorphic-unfetch@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/isomorphic-unfetch/-/isomorphic-unfetch-3.1.0.tgz#87341d5f4f7b63843d468438128cb087b7c3e98f"
|
||||
integrity sha512-geDJjpoZ8N0kWexiwkX8F9NkTsXhetLPVbZFQ+JTW239QNOwvB0gniuR1Wc6f0AMTn7/mFGyXvHTifrCp/GH8Q==
|
||||
dependencies:
|
||||
node-fetch "^2.6.1"
|
||||
unfetch "^4.2.0"
|
||||
|
||||
iti@^0.6.0:
|
||||
version "0.6.0"
|
||||
resolved "https://registry.yarnpkg.com/iti/-/iti-0.6.0.tgz#e763b4089fd8e5cbd1eb753a9d93e80ad11f3d9b"
|
||||
integrity sha512-JqujcnAIF3pmzitjbT3acc0LkordU6oHBDvWeT6a25wvEVBddFX3DFx/p6YBwGX1TTFsyLgVZtwhGOknthC96A==
|
||||
dependencies:
|
||||
utility-types "^3.10.0"
|
||||
|
||||
lodash.snakecase@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz#39d714a35357147837aefd64b5dcbb16becd8f8d"
|
||||
integrity sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==
|
||||
|
||||
lodash@^4.17.21:
|
||||
version "4.17.21"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
||||
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
||||
|
||||
node-fetch@^2.6.1:
|
||||
version "2.6.12"
|
||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.12.tgz#02eb8e22074018e3d5a83016649d04df0e348fba"
|
||||
integrity sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==
|
||||
dependencies:
|
||||
whatwg-url "^5.0.0"
|
||||
|
||||
peek-readable@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/peek-readable/-/peek-readable-5.0.0.tgz#7ead2aff25dc40458c60347ea76cfdfd63efdfec"
|
||||
integrity sha512-YtCKvLUOvwtMGmrniQPdO7MwPjgkFBtFIrmfSbYmYuq3tKDV/mcfAhBth1+C3ru7uXIZasc/pHnb+YDYNkkj4A==
|
||||
|
||||
readable-stream@^3.6.0:
|
||||
version "3.6.2"
|
||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967"
|
||||
integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==
|
||||
dependencies:
|
||||
inherits "^2.0.3"
|
||||
string_decoder "^1.1.1"
|
||||
util-deprecate "^1.0.1"
|
||||
|
||||
readable-web-to-node-stream@^3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz#5d52bb5df7b54861fd48d015e93a2cb87b3ee0bb"
|
||||
integrity sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==
|
||||
dependencies:
|
||||
readable-stream "^3.6.0"
|
||||
|
||||
rxjs@^7.8.0:
|
||||
version "7.8.1"
|
||||
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543"
|
||||
integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==
|
||||
dependencies:
|
||||
tslib "^2.1.0"
|
||||
|
||||
safe-buffer@~5.2.0:
|
||||
version "5.2.1"
|
||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
|
||||
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
|
||||
|
||||
streamsearch@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764"
|
||||
integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==
|
||||
|
||||
string_decoder@^1.1.1:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e"
|
||||
integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==
|
||||
dependencies:
|
||||
safe-buffer "~5.2.0"
|
||||
|
||||
strtok3@^7.0.0:
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-7.0.0.tgz#868c428b4ade64a8fd8fee7364256001c1a4cbe5"
|
||||
integrity sha512-pQ+V+nYQdC5H3Q7qBZAz/MO6lwGhoC2gOAjuouGf/VO0m7vQRh8QNMl2Uf6SwAtzZ9bOw3UIeBukEGNJl5dtXQ==
|
||||
dependencies:
|
||||
"@tokenizer/token" "^0.3.0"
|
||||
peek-readable "^5.0.0"
|
||||
|
||||
token-types@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/token-types/-/token-types-5.0.1.tgz#aa9d9e6b23c420a675e55413b180635b86a093b4"
|
||||
integrity sha512-Y2fmSnZjQdDb9W4w4r1tswlMHylzWIeOKpx0aZH9BgGtACHhrk3OkT52AzwcuqTRBZtvvnTjDBh8eynMulu8Vg==
|
||||
dependencies:
|
||||
"@tokenizer/token" "^0.3.0"
|
||||
ieee754 "^1.2.1"
|
||||
|
||||
tr46@~0.0.3:
|
||||
version "0.0.3"
|
||||
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
|
||||
integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==
|
||||
|
||||
ts-mixer@^6.0.3:
|
||||
version "6.0.3"
|
||||
resolved "https://registry.yarnpkg.com/ts-mixer/-/ts-mixer-6.0.3.tgz#69bd50f406ff39daa369885b16c77a6194c7cae6"
|
||||
integrity sha512-k43M7uCG1AkTyxgnmI5MPwKoUvS/bRvLvUb7+Pgpdlmok8AoqmUaZxUUw8zKM5B1lqZrt41GjYgnvAi0fppqgQ==
|
||||
|
||||
ts-results-es@^3.6.0:
|
||||
version "3.6.0"
|
||||
resolved "https://registry.yarnpkg.com/ts-results-es/-/ts-results-es-3.6.0.tgz#351023246249ef558c2fe3700099e1535226ce47"
|
||||
integrity sha512-swha7PpeUNX93LzwhNtlk97FZZdTkCsI4j2ShletEmQ4cEi9SWy95x8XRTpfOP8gr16ikEBSi4U8xD43BYHDFg==
|
||||
|
||||
tslib@^2.1.0, tslib@^2.5.0:
|
||||
version "2.6.0"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.0.tgz#b295854684dbda164e181d259a22cd779dcd7bc3"
|
||||
integrity sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA==
|
||||
|
||||
typescript@5.0:
|
||||
version "5.0.4"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.0.4.tgz#b217fd20119bd61a94d4011274e0ab369058da3b"
|
||||
integrity sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==
|
||||
|
||||
undici@^5.22.0:
|
||||
version "5.22.1"
|
||||
resolved "https://registry.yarnpkg.com/undici/-/undici-5.22.1.tgz#877d512effef2ac8be65e695f3586922e1a57d7b"
|
||||
integrity sha512-Ji2IJhFXZY0x/0tVBXeQwgPlLWw13GVzpsWPQ3rV50IFMMof2I55PZZxtm4P6iNq+L5znYN9nSTAq0ZyE6lSJw==
|
||||
dependencies:
|
||||
busboy "^1.6.0"
|
||||
|
||||
unfetch@^4.2.0:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/unfetch/-/unfetch-4.2.0.tgz#7e21b0ef7d363d8d9af0fb929a5555f6ef97a3be"
|
||||
integrity sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA==
|
||||
|
||||
util-deprecate@^1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
|
||||
integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==
|
||||
|
||||
utility-types@^3.10.0:
|
||||
version "3.10.0"
|
||||
resolved "https://registry.yarnpkg.com/utility-types/-/utility-types-3.10.0.tgz#ea4148f9a741015f05ed74fd615e1d20e6bed82b"
|
||||
integrity sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg==
|
||||
|
||||
webidl-conversions@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"
|
||||
integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==
|
||||
|
||||
whatwg-url@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d"
|
||||
integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==
|
||||
dependencies:
|
||||
tr46 "~0.0.3"
|
||||
webidl-conversions "^3.0.0"
|
||||
|
||||
ws@^8.13.0:
|
||||
version "8.13.0"
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-8.13.0.tgz#9a9fb92f93cf41512a0735c8f4dd09b8a1211cd0"
|
||||
integrity sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==
|
||||