From 2b63ece70c5530d90190f83805c8faa5e01bd770 Mon Sep 17 00:00:00 2001 From: SrIzan10 <66965250+SrIzan10@users.noreply.github.com> Date: Fri, 14 Jul 2023 17:14:24 +0000 Subject: [PATCH] feat: v1 done --- .gitignore | 2 + dist/commands/issue.js | 77 +++++ dist/index.js | 33 +++ dist/plugins/publish.js | 129 ++++++++ dist/util/uuid-check.js | 1 + package.json | 29 ++ sern.config.json | 7 + src/commands/issue.ts | 97 ++++++ src/dependencies.d.ts | 17 ++ src/icons/priority/high.svg | 1 + src/icons/priority/low.svg | 1 + src/icons/priority/medium.svg | 1 + src/icons/priority/noPriority.svg | 1 + src/icons/priority/urgent.svg | 1 + src/icons/status/backlog.svg | 1 + src/icons/status/canceledOrDuplicate.svg | 1 + src/icons/status/done.svg | 1 + src/icons/status/inProgress.svg | 1 + src/icons/status/inReview.svg | 1 + src/icons/status/todo.svg | 1 + src/index.ts | 40 +++ src/plugins/publish.ts | 207 +++++++++++++ src/util/uuid-check.ts | 1 + tsconfig.json | 16 + yarn.lock | 359 +++++++++++++++++++++++ 25 files changed, 1026 insertions(+) create mode 100644 .gitignore create mode 100644 dist/commands/issue.js create mode 100644 dist/index.js create mode 100644 dist/plugins/publish.js create mode 100644 dist/util/uuid-check.js create mode 100644 package.json create mode 100644 sern.config.json create mode 100644 src/commands/issue.ts create mode 100644 src/dependencies.d.ts create mode 100644 src/icons/priority/high.svg create mode 100644 src/icons/priority/low.svg create mode 100644 src/icons/priority/medium.svg create mode 100644 src/icons/priority/noPriority.svg create mode 100644 src/icons/priority/urgent.svg create mode 100644 src/icons/status/backlog.svg create mode 100644 src/icons/status/canceledOrDuplicate.svg create mode 100644 src/icons/status/done.svg create mode 100644 src/icons/status/inProgress.svg create mode 100644 src/icons/status/inReview.svg create mode 100644 src/icons/status/todo.svg create mode 100644 src/index.ts create mode 100644 src/plugins/publish.ts create mode 100644 src/util/uuid-check.ts create mode 100644 tsconfig.json create mode 100644 yarn.lock diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3ec544c --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node_modules/ +.env \ No newline at end of file diff --git a/dist/commands/issue.js b/dist/commands/issue.js new file mode 100644 index 0000000..e7a52d7 --- /dev/null +++ b/dist/commands/issue.js @@ -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 }); + } + }, +}); diff --git a/dist/index.js b/dist/index.js new file mode 100644 index 0000000..cf1c223 --- /dev/null +++ b/dist/index.js @@ -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(); diff --git a/dist/plugins/publish.js b/dist/plugins/publish.js new file mode 100644 index 0000000..008193a --- /dev/null +++ b/dist/plugins/publish.js @@ -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; + } + }); +} diff --git a/dist/util/uuid-check.js b/dist/util/uuid-check.js new file mode 100644 index 0000000..206506e --- /dev/null +++ b/dist/util/uuid-check.js @@ -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; diff --git a/package.json b/package.json new file mode 100644 index 0000000..cb75e42 --- /dev/null +++ b/package.json @@ -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" +} diff --git a/sern.config.json b/sern.config.json new file mode 100644 index 0000000..267655b --- /dev/null +++ b/sern.config.json @@ -0,0 +1,7 @@ +{ + "language": "typescript", + "paths": { + "base": "src", + "commands": "commands" + } +} \ No newline at end of file diff --git a/src/commands/issue.ts b/src/commands/issue.ts new file mode 100644 index 0000000..7e7ee8b --- /dev/null +++ b/src/commands/issue.ts @@ -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 +} \ No newline at end of file diff --git a/src/dependencies.d.ts b/src/dependencies.d.ts new file mode 100644 index 0000000..c59bf80 --- /dev/null +++ b/src/dependencies.d.ts @@ -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 + } +} + + +export {} diff --git a/src/icons/priority/high.svg b/src/icons/priority/high.svg new file mode 100644 index 0000000..7fefafa --- /dev/null +++ b/src/icons/priority/high.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/priority/low.svg b/src/icons/priority/low.svg new file mode 100644 index 0000000..b1d4799 --- /dev/null +++ b/src/icons/priority/low.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/priority/medium.svg b/src/icons/priority/medium.svg new file mode 100644 index 0000000..bc031b6 --- /dev/null +++ b/src/icons/priority/medium.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/priority/noPriority.svg b/src/icons/priority/noPriority.svg new file mode 100644 index 0000000..349a115 --- /dev/null +++ b/src/icons/priority/noPriority.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/priority/urgent.svg b/src/icons/priority/urgent.svg new file mode 100644 index 0000000..433f09f --- /dev/null +++ b/src/icons/priority/urgent.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/status/backlog.svg b/src/icons/status/backlog.svg new file mode 100644 index 0000000..92605bd --- /dev/null +++ b/src/icons/status/backlog.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/status/canceledOrDuplicate.svg b/src/icons/status/canceledOrDuplicate.svg new file mode 100644 index 0000000..989bf8b --- /dev/null +++ b/src/icons/status/canceledOrDuplicate.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/status/done.svg b/src/icons/status/done.svg new file mode 100644 index 0000000..3e42f15 --- /dev/null +++ b/src/icons/status/done.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/status/inProgress.svg b/src/icons/status/inProgress.svg new file mode 100644 index 0000000..6ffb687 --- /dev/null +++ b/src/icons/status/inProgress.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/status/inReview.svg b/src/icons/status/inReview.svg new file mode 100644 index 0000000..cd6242a --- /dev/null +++ b/src/icons/status/inReview.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/status/todo.svg b/src/icons/status/todo.svg new file mode 100644 index 0000000..f6e24f0 --- /dev/null +++ b/src/icons/status/todo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..6320127 --- /dev/null +++ b/src/index.ts @@ -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(); diff --git a/src/plugins/publish.ts b/src/plugins/publish.ts new file mode 100644 index 0000000..7f429e4 --- /dev/null +++ b/src/plugins/publish.ts @@ -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(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 = (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) { + 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, ...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> + | ( + | Required> + | Required> + ) + ); diff --git a/src/util/uuid-check.ts b/src/util/uuid-check.ts new file mode 100644 index 0000000..8d12a09 --- /dev/null +++ b/src/util/uuid-check.ts @@ -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 \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..c8d206f --- /dev/null +++ b/tsconfig.json @@ -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 + } +} diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..1ba88de --- /dev/null +++ b/yarn.lock @@ -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==