wip more stuff
This commit is contained in:
@@ -10,14 +10,14 @@ export class AsyncQueue {
|
||||
private items: QueueItem[] = []
|
||||
private running = false
|
||||
|
||||
add<T>(callback: AsyncCallback<T>): Promise<Awaited<T>> {
|
||||
append<T>(callback: AsyncCallback<T>): Promise<Awaited<T>> {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.items.push({ callback, resolve: resolve as any, reject })
|
||||
void this.runQueue()
|
||||
void this.run()
|
||||
})
|
||||
}
|
||||
|
||||
private async runQueue() {
|
||||
private async run() {
|
||||
if (this.running) return
|
||||
this.running = true
|
||||
|
||||
|
||||
21
packages/playground/package.json
Normal file
21
packages/playground/package.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "@reacord/playground",
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "tsx watch src/main.tsx"
|
||||
},
|
||||
"dependencies": {
|
||||
"@reacord/helpers": "workspace:*",
|
||||
"discord.js": "^14.1.2",
|
||||
"dotenv": "^16.0.1",
|
||||
"ora": "^6.1.2",
|
||||
"react": "^18.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "*",
|
||||
"@types/react": "^18.0.16",
|
||||
"tsx": "^3.8.0",
|
||||
"typescript": "^4.7.4"
|
||||
}
|
||||
}
|
||||
54
packages/playground/src/main.tsx
Normal file
54
packages/playground/src/main.tsx
Normal file
@@ -0,0 +1,54 @@
|
||||
import { raise } from "@reacord/helpers/raise"
|
||||
import { Client, GatewayIntentBits } from "discord.js"
|
||||
import * as dotenv from "dotenv"
|
||||
import { join } from "node:path"
|
||||
import { fileURLToPath } from "node:url"
|
||||
import { oraPromise } from "ora"
|
||||
import React from "react"
|
||||
import { Button, ReacordClient } from "../../reacord/src/main"
|
||||
|
||||
dotenv.config({
|
||||
path: join(fileURLToPath(import.meta.url), "../../../../.env"),
|
||||
override: true,
|
||||
})
|
||||
|
||||
const token = process.env.TEST_BOT_TOKEN ?? raise("TEST_BOT_TOKEN not defined")
|
||||
|
||||
const client = new Client({ intents: [GatewayIntentBits.Guilds] })
|
||||
const reacord = new ReacordClient({ token })
|
||||
|
||||
client.once("ready", async (client) => {
|
||||
try {
|
||||
await oraPromise(
|
||||
client.application.commands.create({
|
||||
name: "counter",
|
||||
description: "counts things",
|
||||
}),
|
||||
"Registering commands",
|
||||
)
|
||||
} catch (error) {
|
||||
console.error("Failed to register commands:", error)
|
||||
}
|
||||
})
|
||||
|
||||
client.on("interactionCreate", async (interaction) => {
|
||||
if (
|
||||
interaction.isChatInputCommand() &&
|
||||
interaction.commandName === "counter"
|
||||
) {
|
||||
reacord.reply(interaction, <Counter />)
|
||||
// reacord.reply(interaction, "test3").render("test4")
|
||||
}
|
||||
})
|
||||
|
||||
await oraPromise(client.login(token), "Logging in")
|
||||
|
||||
function Counter() {
|
||||
const [count, setCount] = React.useState(0)
|
||||
return (
|
||||
<>
|
||||
count: {count}
|
||||
<Button label="+" onClick={() => setCount(count + 1)} />
|
||||
</>
|
||||
)
|
||||
}
|
||||
3
packages/playground/tsconfig.json
Normal file
3
packages/playground/tsconfig.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json"
|
||||
}
|
||||
@@ -2,14 +2,21 @@ import type { APIInteraction, Client } from "discord.js"
|
||||
import {
|
||||
GatewayDispatchEvents,
|
||||
GatewayIntentBits,
|
||||
InteractionResponseType,
|
||||
InteractionType,
|
||||
Routes,
|
||||
} from "discord.js"
|
||||
import * as React from "react"
|
||||
import { createDiscordClient } from "./create-discord-client"
|
||||
import type { ReacordInstance } from "./reacord-instance"
|
||||
import { ReacordInstancePrivate } from "./reacord-instance"
|
||||
import { InstanceProvider } from "./react/instance-context"
|
||||
import { Renderer } from "./renderer"
|
||||
import type { Renderer } from "./renderer"
|
||||
import {
|
||||
ChannelMessageRenderer,
|
||||
EphemeralInteractionReplyRenderer,
|
||||
InteractionReplyRenderer,
|
||||
} from "./renderer"
|
||||
|
||||
/**
|
||||
* @category Core
|
||||
@@ -65,10 +72,28 @@ export class ReacordClient {
|
||||
|
||||
this.discordClientPromise
|
||||
.then((client) => {
|
||||
// we listen to the websocket message instead of the normal "interactionCreate" event,
|
||||
// so that we can pass a library-agnostic APIInteraction object to the user's component callbacks
|
||||
// the DJS MessageComponentInteraction doesn't have the raw data on it (as of writing this)
|
||||
client.ws.on(
|
||||
GatewayDispatchEvents.InteractionCreate,
|
||||
(interaction: APIInteraction) => {
|
||||
async (interaction: APIInteraction) => {
|
||||
if (interaction.type !== InteractionType.MessageComponent) return
|
||||
|
||||
// handling a component interaction may not always result in a re-render,
|
||||
// and in the case that it doesn't, discord will incorrectly show "interaction failed",
|
||||
// so here, we'll just always defer an update just in case
|
||||
//
|
||||
// we _can_ be a little smarter and check to see if an update happened before deferring,
|
||||
// but I can figure that out later
|
||||
//
|
||||
// or we can make the user defer themselves if they don't update,
|
||||
// but that's bad UX probably
|
||||
await client.rest.post(
|
||||
Routes.interactionCallback(interaction.id, interaction.token),
|
||||
{ body: { type: InteractionResponseType.DeferredMessageUpdate } },
|
||||
)
|
||||
|
||||
for (const instance of this.instances) {
|
||||
instance.handleInteraction(interaction, this)
|
||||
}
|
||||
@@ -88,7 +113,7 @@ export class ReacordClient {
|
||||
|
||||
reply(interaction: InteractionInfo, initialContent?: React.ReactNode) {
|
||||
return this.createInstance(
|
||||
new InteractionReplyRenderer(interaction),
|
||||
new InteractionReplyRenderer(interaction, this.discordClientPromise),
|
||||
initialContent,
|
||||
)
|
||||
}
|
||||
@@ -98,7 +123,10 @@ export class ReacordClient {
|
||||
initialContent?: React.ReactNode,
|
||||
) {
|
||||
return this.createInstance(
|
||||
new EphemeralInteractionReplyRenderer(interaction),
|
||||
new EphemeralInteractionReplyRenderer(
|
||||
interaction,
|
||||
this.discordClientPromise,
|
||||
),
|
||||
initialContent,
|
||||
)
|
||||
}
|
||||
@@ -132,11 +160,11 @@ export class ReacordClient {
|
||||
},
|
||||
deactivate: () => {
|
||||
this.removeInstance(instance)
|
||||
renderer.deactivate().catch(console.error)
|
||||
renderer.deactivate()
|
||||
},
|
||||
destroy: () => {
|
||||
this.removeInstance(instance)
|
||||
renderer.destroy().catch(console.error)
|
||||
renderer.destroy()
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -50,35 +50,23 @@ export class ReacordInstancePrivate {
|
||||
readonly tree = new Node({})
|
||||
private latestTree?: Node
|
||||
|
||||
constructor(private readonly renderer: Renderer) {}
|
||||
constructor(readonly renderer: Renderer) {}
|
||||
|
||||
render(content: React.ReactNode) {
|
||||
reconciler.updateContainer(content, this.container)
|
||||
}
|
||||
|
||||
async update(tree: Node) {
|
||||
try {
|
||||
await this.renderer.update(tree)
|
||||
this.latestTree = tree
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
}
|
||||
update(tree: Node) {
|
||||
this.renderer.update(tree)
|
||||
this.latestTree = tree
|
||||
}
|
||||
|
||||
async deactivate() {
|
||||
try {
|
||||
await this.renderer.deactivate()
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
}
|
||||
deactivate() {
|
||||
this.renderer.deactivate()
|
||||
}
|
||||
|
||||
async destroy() {
|
||||
try {
|
||||
await this.renderer.destroy()
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
}
|
||||
destroy() {
|
||||
this.renderer.destroy()
|
||||
}
|
||||
|
||||
handleInteraction(
|
||||
@@ -87,6 +75,8 @@ export class ReacordInstancePrivate {
|
||||
) {
|
||||
if (!this.latestTree) return
|
||||
|
||||
this.renderer.onComponentInteraction(interaction)
|
||||
|
||||
const baseEvent: ComponentEvent = {
|
||||
reply: (content) => client.reply(interaction, content),
|
||||
ephemeralReply: (content) => client.ephemeralReply(interaction, content),
|
||||
@@ -102,7 +92,7 @@ export class ReacordInstancePrivate {
|
||||
...baseEvent,
|
||||
interaction: interaction as APIMessageComponentButtonInteraction,
|
||||
})
|
||||
break
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -124,6 +114,7 @@ export class ReacordInstancePrivate {
|
||||
if (interaction.data.values[0]) {
|
||||
node.props.onChangeValue?.(interaction.data.values[0], event)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,22 @@
|
||||
import { AsyncQueue } from "@reacord/helpers/async-queue.js"
|
||||
import type { Client, Message } from "discord.js"
|
||||
import { TextChannel } from "discord.js"
|
||||
import type { MessageUpdatePayload } from "./make-message-update-payload.js"
|
||||
import { makeMessageUpdatePayload } from "./make-message-update-payload.js"
|
||||
import type { Node } from "./node.js"
|
||||
import type { InteractionInfo } from "./reacord-client.js"
|
||||
import { AsyncQueue } from "@reacord/helpers/async-queue"
|
||||
import type {
|
||||
Client,
|
||||
Message,
|
||||
RESTPostAPIInteractionFollowupResult,
|
||||
Snowflake,
|
||||
} from "discord.js"
|
||||
import { InteractionResponseType, Routes, TextChannel } from "discord.js"
|
||||
import type { MessageUpdatePayload } from "./make-message-update-payload"
|
||||
import { makeMessageUpdatePayload } from "./make-message-update-payload"
|
||||
import type { Node } from "./node"
|
||||
import type { InteractionInfo } from "./reacord-client"
|
||||
|
||||
export abstract class Renderer {
|
||||
private readonly queue = new AsyncQueue()
|
||||
private active = true
|
||||
private destroyPromise?: Promise<void>
|
||||
private componentInteraction?: InteractionInfo
|
||||
private readonly queue = new AsyncQueue()
|
||||
|
||||
constructor(protected readonly clientPromise: Promise<Client<true>>) {}
|
||||
|
||||
protected abstract handleUpdate(payload: MessageUpdatePayload): Promise<void>
|
||||
protected abstract handleDestroy(): Promise<void>
|
||||
@@ -17,59 +24,97 @@ export abstract class Renderer {
|
||||
|
||||
update(tree: Node) {
|
||||
const payload = makeMessageUpdatePayload(tree)
|
||||
return this.queue.add(async () => {
|
||||
if (!this.active) return
|
||||
await this.handleUpdate(payload)
|
||||
})
|
||||
|
||||
this.queue
|
||||
.append(async () => {
|
||||
if (!this.active) return
|
||||
|
||||
if (this.componentInteraction) {
|
||||
await this.updateInteractionMessage(
|
||||
this.componentInteraction,
|
||||
payload,
|
||||
)
|
||||
this.componentInteraction = undefined
|
||||
return
|
||||
}
|
||||
|
||||
await this.handleUpdate(payload)
|
||||
})
|
||||
.catch(console.error)
|
||||
}
|
||||
|
||||
destroy() {
|
||||
if (this.destroyPromise) return this.destroyPromise
|
||||
if (!this.active) return
|
||||
this.active = false
|
||||
|
||||
const promise = this.queue.add(() => this.handleDestroy())
|
||||
|
||||
// if it failed, we'll want to try again
|
||||
promise.catch((error) => {
|
||||
console.error("Failed to destroy message:", error)
|
||||
this.destroyPromise = undefined
|
||||
})
|
||||
|
||||
return (this.destroyPromise = promise)
|
||||
this.queue.append(() => this.handleDestroy()).catch(console.error)
|
||||
}
|
||||
|
||||
deactivate() {
|
||||
return this.queue.add(async () => {
|
||||
if (!this.active) return
|
||||
this.queue
|
||||
.append(async () => {
|
||||
await this.handleDeactivate()
|
||||
this.active = false
|
||||
})
|
||||
.catch(console.error)
|
||||
}
|
||||
|
||||
await this.handleDeactivate()
|
||||
onComponentInteraction(info: InteractionInfo) {
|
||||
this.componentInteraction = info
|
||||
|
||||
// set active to false *after* running deactivation,
|
||||
// so that other queued operations run first,
|
||||
// and we can show the correct deactivated state
|
||||
this.active = false
|
||||
// a component update might not happen in response to this interaction,
|
||||
// so we'll defer it after a timeout if it's not handled by then
|
||||
setTimeout(() => {
|
||||
this.queue
|
||||
.append(() => {
|
||||
if (!this.componentInteraction) return
|
||||
const info = this.componentInteraction
|
||||
this.componentInteraction = undefined
|
||||
return this.deferMessageUpdate(info)
|
||||
})
|
||||
.catch(console.error)
|
||||
}, 500)
|
||||
}
|
||||
|
||||
private async updateInteractionMessage(
|
||||
{ id, token }: InteractionInfo,
|
||||
payload: MessageUpdatePayload,
|
||||
) {
|
||||
const client = await this.clientPromise
|
||||
await client.rest.post(Routes.interactionCallback(id, token), {
|
||||
body: {
|
||||
type: InteractionResponseType.UpdateMessage,
|
||||
data: payload,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
private async deferMessageUpdate({ id, token }: InteractionInfo) {
|
||||
const client = await this.clientPromise
|
||||
await client.rest.post(Routes.interactionCallback(id, token), {
|
||||
body: { type: InteractionResponseType.DeferredMessageUpdate },
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export class ChannelMessageRenderer extends Renderer {
|
||||
private channel: TextChannel | undefined
|
||||
private message: Message | undefined
|
||||
private channel?: TextChannel
|
||||
private message?: Message
|
||||
|
||||
constructor(
|
||||
private readonly channelId: string,
|
||||
private readonly clientPromise: Promise<Client<true>>,
|
||||
clientPromise: Promise<Client<true>>,
|
||||
) {
|
||||
super()
|
||||
super(clientPromise)
|
||||
}
|
||||
|
||||
override async handleUpdate(payload: MessageUpdatePayload): Promise<void> {
|
||||
if (this.message) {
|
||||
await this.message.edit(payload)
|
||||
} else {
|
||||
const channel = await this.getChannel()
|
||||
this.message = await channel.send(payload)
|
||||
return
|
||||
}
|
||||
|
||||
const channel = await this.getChannel()
|
||||
this.message = await channel.send(payload)
|
||||
}
|
||||
|
||||
override async handleDestroy(): Promise<void> {
|
||||
@@ -101,14 +146,80 @@ export class ChannelMessageRenderer extends Renderer {
|
||||
}
|
||||
|
||||
export class InteractionReplyRenderer extends Renderer {
|
||||
constructor(private readonly interaction: InteractionInfo) {
|
||||
super()
|
||||
private messageCreated = false
|
||||
|
||||
constructor(
|
||||
private interaction: InteractionInfo,
|
||||
clientPromise: Promise<Client<true>>,
|
||||
) {
|
||||
super(clientPromise)
|
||||
}
|
||||
|
||||
handleUpdate(payload: MessageUpdatePayload): Promise<void> {
|
||||
async handleUpdate(payload: MessageUpdatePayload): Promise<void> {
|
||||
const client = await this.clientPromise
|
||||
if (!this.messageCreated) {
|
||||
await client.rest.post(
|
||||
Routes.interactionCallback(this.interaction.id, this.interaction.token),
|
||||
{
|
||||
body: {
|
||||
type: InteractionResponseType.ChannelMessageWithSource,
|
||||
data: payload,
|
||||
},
|
||||
},
|
||||
)
|
||||
this.messageCreated = true
|
||||
} else {
|
||||
await client.rest.patch(
|
||||
Routes.webhookMessage(
|
||||
client.application.id,
|
||||
this.interaction.token,
|
||||
"@original",
|
||||
),
|
||||
{ body: payload },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
handleDestroy(): Promise<void> {
|
||||
throw new Error("Method not implemented.")
|
||||
}
|
||||
|
||||
handleDeactivate(): Promise<void> {
|
||||
throw new Error("Method not implemented.")
|
||||
}
|
||||
}
|
||||
|
||||
export class InteractionFollowUpRenderer extends Renderer {
|
||||
private messageId?: Snowflake
|
||||
|
||||
constructor(
|
||||
readonly interaction: InteractionInfo,
|
||||
clientPromise: Promise<Client<true>>,
|
||||
) {
|
||||
super(clientPromise)
|
||||
}
|
||||
|
||||
async handleUpdate(payload: MessageUpdatePayload): Promise<void> {
|
||||
const client = await this.clientPromise
|
||||
|
||||
if (!this.messageId) {
|
||||
const response = (await client.rest.post(
|
||||
Routes.webhookMessage(client.application.id, this.interaction.token),
|
||||
{ body: payload },
|
||||
)) as RESTPostAPIInteractionFollowupResult
|
||||
this.messageId = response.id
|
||||
} else {
|
||||
await client.rest.patch(
|
||||
Routes.webhookMessage(
|
||||
client.application.id,
|
||||
this.interaction.token,
|
||||
this.messageId,
|
||||
),
|
||||
{ body: payload },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
handleDestroy(): Promise<void> {
|
||||
throw new Error("Method not implemented.")
|
||||
}
|
||||
@@ -119,8 +230,11 @@ export class InteractionReplyRenderer extends Renderer {
|
||||
}
|
||||
|
||||
export class EphemeralInteractionReplyRenderer extends Renderer {
|
||||
constructor(private readonly interaction: InteractionInfo) {
|
||||
super()
|
||||
constructor(
|
||||
private readonly interaction: InteractionInfo,
|
||||
clientPromise: Promise<Client<true>>,
|
||||
) {
|
||||
super(clientPromise)
|
||||
}
|
||||
|
||||
handleUpdate(payload: MessageUpdatePayload): Promise<void> {
|
||||
|
||||
75
pnpm-lock.yaml
generated
75
pnpm-lock.yaml
generated
@@ -43,6 +43,29 @@ importers:
|
||||
lodash-es: 4.17.21
|
||||
type-fest: 2.18.0
|
||||
|
||||
packages/playground:
|
||||
specifiers:
|
||||
'@reacord/helpers': workspace:*
|
||||
'@types/node': '*'
|
||||
'@types/react': ^18.0.16
|
||||
discord.js: ^14.1.2
|
||||
dotenv: ^16.0.1
|
||||
ora: ^6.1.2
|
||||
react: ^18.2.0
|
||||
tsx: ^3.8.0
|
||||
typescript: ^4.7.4
|
||||
dependencies:
|
||||
'@reacord/helpers': link:../helpers
|
||||
discord.js: 14.1.2
|
||||
dotenv: 16.0.1
|
||||
ora: 6.1.2
|
||||
react: 18.2.0
|
||||
devDependencies:
|
||||
'@types/node': 18.6.4
|
||||
'@types/react': 18.0.16
|
||||
tsx: 3.8.0
|
||||
typescript: 4.7.4
|
||||
|
||||
packages/reacord:
|
||||
specifiers:
|
||||
'@reacord/helpers': workspace:*
|
||||
@@ -1654,12 +1677,10 @@ packages:
|
||||
fast-deep-equal: 3.1.3
|
||||
ts-mixer: 6.0.1
|
||||
tslib: 2.4.0
|
||||
dev: true
|
||||
|
||||
/@discordjs/collection/1.0.1:
|
||||
resolution: {integrity: sha512-5V/wswzR3r2RVYXLxxg4TvrAnBhVCNgHTXhC+OUtLoriJ072rPMHo+Iw1SS1vrCckp8Es40XM411+WkNRPaXFw==}
|
||||
engines: {node: '>=16.9.0'}
|
||||
dev: true
|
||||
|
||||
/@discordjs/rest/1.0.1:
|
||||
resolution: {integrity: sha512-w08CTKVzzYYvKxEjXKOs9AdS7KQ1J502TrPfF8eCZ2lF6AfKuMP/32YgDakiwIyYTDjEQS/v0nKLSFcncHRMtg==}
|
||||
@@ -1672,7 +1693,6 @@ packages:
|
||||
file-type: 17.1.6
|
||||
tslib: 2.4.0
|
||||
undici: 5.8.1
|
||||
dev: true
|
||||
|
||||
/@esbuild-kit/cjs-loader/2.3.2:
|
||||
resolution: {integrity: sha512-3UIFKrGfq2d2R2A/SpJaeHTP5z3nrOnVMxE+cNpOuuW+Lotm0Sfbc9lVHCjcxaxgcx0MKI7g2FvxvWlylzDRKg==}
|
||||
@@ -2263,7 +2283,6 @@ packages:
|
||||
/@sapphire/async-queue/1.3.2:
|
||||
resolution: {integrity: sha512-rUpMLATsoAMnlN3gecAcr9Ecnw1vG7zi5Xr+IX22YzRzi1k9PF9vKzoT8RuEJbiIszjcimu3rveqUnvwDopz8g==}
|
||||
engines: {node: '>=v14.0.0', npm: '>=7.0.0'}
|
||||
dev: true
|
||||
|
||||
/@sapphire/shapeshift/3.5.1:
|
||||
resolution: {integrity: sha512-7JFsW5IglyOIUQI1eE0g6h06D/Far6HqpcowRScgCiLSqTf3hhkPWCWotVTtVycnDCMYIwPeaw6IEPBomKC8pA==}
|
||||
@@ -2271,12 +2290,10 @@ packages:
|
||||
dependencies:
|
||||
fast-deep-equal: 3.1.3
|
||||
lodash.uniqwith: 4.5.0
|
||||
dev: true
|
||||
|
||||
/@sapphire/snowflake/3.2.2:
|
||||
resolution: {integrity: sha512-ula2O0kpSZtX9rKXNeQMrHwNd7E4jPDJYUXmEGTFdMRfyfMw+FPyh04oKMjAiDuOi64bYgVkOV3MjK+loImFhQ==}
|
||||
engines: {node: '>=v14.0.0', npm: '>=7.0.0'}
|
||||
dev: true
|
||||
|
||||
/@sideway/address/4.1.4:
|
||||
resolution: {integrity: sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==}
|
||||
@@ -2354,7 +2371,6 @@ packages:
|
||||
|
||||
/@tokenizer/token/0.3.0:
|
||||
resolution: {integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==}
|
||||
dev: true
|
||||
|
||||
/@tootallnate/once/1.1.2:
|
||||
resolution: {integrity: sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==}
|
||||
@@ -2562,6 +2578,14 @@ packages:
|
||||
'@types/scheduler': 0.16.2
|
||||
csstype: 3.1.0
|
||||
|
||||
/@types/react/18.0.16:
|
||||
resolution: {integrity: sha512-3vX1dzVucqc2nhXtzyaParTIIRZeNbisRqLE7QdeLomVybEyeiuAouzZXgz71P+2kbJOqj3dy0fzoATg2I06GQ==}
|
||||
dependencies:
|
||||
'@types/prop-types': 15.7.5
|
||||
'@types/scheduler': 0.16.2
|
||||
csstype: 3.1.0
|
||||
dev: true
|
||||
|
||||
/@types/responselike/1.0.0:
|
||||
resolution: {integrity: sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==}
|
||||
dependencies:
|
||||
@@ -2603,7 +2627,6 @@ packages:
|
||||
resolution: {integrity: sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==}
|
||||
dependencies:
|
||||
'@types/node': 18.6.4
|
||||
dev: true
|
||||
|
||||
/@types/yauzl/2.10.0:
|
||||
resolution: {integrity: sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==}
|
||||
@@ -2882,7 +2905,6 @@ packages:
|
||||
/ansi-regex/6.0.1:
|
||||
resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==}
|
||||
engines: {node: '>=12'}
|
||||
dev: true
|
||||
|
||||
/ansi-styles/3.2.1:
|
||||
resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==}
|
||||
@@ -3226,7 +3248,6 @@ packages:
|
||||
|
||||
/base64-js/1.5.1:
|
||||
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
|
||||
dev: true
|
||||
|
||||
/basic-auth/2.0.1:
|
||||
resolution: {integrity: sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==}
|
||||
@@ -3280,7 +3301,6 @@ packages:
|
||||
buffer: 6.0.3
|
||||
inherits: 2.0.4
|
||||
readable-stream: 3.6.0
|
||||
dev: true
|
||||
|
||||
/blob-util/2.0.2:
|
||||
resolution: {integrity: sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ==}
|
||||
@@ -3402,7 +3422,6 @@ packages:
|
||||
dependencies:
|
||||
base64-js: 1.5.1
|
||||
ieee754: 1.2.1
|
||||
dev: true
|
||||
|
||||
/builtin-modules/3.3.0:
|
||||
resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==}
|
||||
@@ -3595,7 +3614,6 @@ packages:
|
||||
/chalk/5.0.1:
|
||||
resolution: {integrity: sha512-Fo07WOYGqMfCWHOzSXOt2CxDbC6skS/jO9ynEcmpANMoPrD+W1r1K6Vx7iNm+AQmETU1Xr2t+n8nzkV9t6xh3w==}
|
||||
engines: {node: ^12.17.0 || ^14.13 || >=16.0.0}
|
||||
dev: true
|
||||
|
||||
/character-entities-html4/2.1.0:
|
||||
resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==}
|
||||
@@ -3699,12 +3717,10 @@ packages:
|
||||
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
||||
dependencies:
|
||||
restore-cursor: 4.0.0
|
||||
dev: true
|
||||
|
||||
/cli-spinners/2.7.0:
|
||||
resolution: {integrity: sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw==}
|
||||
engines: {node: '>=6'}
|
||||
dev: true
|
||||
|
||||
/cli-table3/0.6.2:
|
||||
resolution: {integrity: sha512-QyavHCaIC80cMivimWu4aWHilIpiDpfm3hGmqAmXVL1UsnbLuBSMd21hTX6VY4ZSDSM73ESLeF8TOYId3rBTbw==}
|
||||
@@ -3767,7 +3783,6 @@ packages:
|
||||
/clone/1.0.4:
|
||||
resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==}
|
||||
engines: {node: '>=0.8'}
|
||||
dev: true
|
||||
|
||||
/clsx/1.2.1:
|
||||
resolution: {integrity: sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==}
|
||||
@@ -4254,7 +4269,6 @@ packages:
|
||||
resolution: {integrity: sha512-s82itHOnYrN0Ib8r+z7laQz3sdE+4FP3d9Q7VLO7U+KRT+CR0GsWuyHxzdAY82I7cXv0G/twrqomTJLOssO5HA==}
|
||||
dependencies:
|
||||
clone: 1.0.4
|
||||
dev: true
|
||||
|
||||
/defer-to-connect/2.0.1:
|
||||
resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==}
|
||||
@@ -4370,7 +4384,6 @@ packages:
|
||||
|
||||
/discord-api-types/0.36.3:
|
||||
resolution: {integrity: sha512-bz/NDyG0KBo/tY14vSkrwQ/n3HKPf87a0WFW/1M9+tXYK+vp5Z5EksawfCWo2zkAc6o7CClc0eff1Pjrqznlwg==}
|
||||
dev: true
|
||||
|
||||
/discord-api-types/0.37.1:
|
||||
resolution: {integrity: sha512-mePTvycgxnXh1wZO2BTj0mVKsxX69tuc1Zgf4A7dZDGX/HT/geb/26ZLIVqBU9BREJbySuDQlluyIjwZFQj3qw==}
|
||||
@@ -4394,7 +4407,6 @@ packages:
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
- utf-8-validate
|
||||
dev: true
|
||||
|
||||
/dlv/1.1.3:
|
||||
resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==}
|
||||
@@ -4427,7 +4439,6 @@ packages:
|
||||
/dotenv/16.0.1:
|
||||
resolution: {integrity: sha512-1K6hR6wtk2FviQ4kEiSjFiH5rpzEVi8WW0x96aztHVMhEspNpc4DVOUTEHtEva5VThQ8IaBX1Pe4gSzpVVUsKQ==}
|
||||
engines: {node: '>=12'}
|
||||
dev: true
|
||||
|
||||
/duplexify/3.7.1:
|
||||
resolution: {integrity: sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==}
|
||||
@@ -5267,7 +5278,6 @@ packages:
|
||||
|
||||
/fast-deep-equal/3.1.3:
|
||||
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
|
||||
dev: true
|
||||
|
||||
/fast-glob/3.2.11:
|
||||
resolution: {integrity: sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==}
|
||||
@@ -5341,7 +5351,6 @@ packages:
|
||||
readable-web-to-node-stream: 3.0.2
|
||||
strtok3: 7.0.0
|
||||
token-types: 5.0.1
|
||||
dev: true
|
||||
|
||||
/file-uri-to-path/1.0.0:
|
||||
resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==}
|
||||
@@ -6117,7 +6126,6 @@ packages:
|
||||
|
||||
/ieee754/1.2.1:
|
||||
resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
|
||||
dev: true
|
||||
|
||||
/ignore-by-default/1.0.1:
|
||||
resolution: {integrity: sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==}
|
||||
@@ -6458,7 +6466,6 @@ packages:
|
||||
/is-interactive/2.0.0:
|
||||
resolution: {integrity: sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==}
|
||||
engines: {node: '>=12'}
|
||||
dev: true
|
||||
|
||||
/is-js-type/2.0.0:
|
||||
resolution: {integrity: sha512-Aj13l47+uyTjlQNHtXBV8Cji3jb037vxwMWCgopRR8h6xocgBGW3qG8qGlIOEmbXQtkKShKuBM9e8AA1OeQ+xw==}
|
||||
@@ -6631,7 +6638,6 @@ packages:
|
||||
/is-unicode-supported/1.2.0:
|
||||
resolution: {integrity: sha512-wH+U77omcRzevfIG8dDhTS0V9zZyweakfD01FULl97+0EHiJTTZtJqxPSkIIo/SDPv/i07k/C9jAPY+jwLLeUQ==}
|
||||
engines: {node: '>=12'}
|
||||
dev: true
|
||||
|
||||
/is-weakref/1.0.2:
|
||||
resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==}
|
||||
@@ -7054,7 +7060,6 @@ packages:
|
||||
|
||||
/lodash.snakecase/4.1.1:
|
||||
resolution: {integrity: sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==}
|
||||
dev: true
|
||||
|
||||
/lodash.sortby/4.7.0:
|
||||
resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==}
|
||||
@@ -7066,7 +7071,6 @@ packages:
|
||||
|
||||
/lodash.uniqwith/4.5.0:
|
||||
resolution: {integrity: sha512-7lYL8bLopMoy4CTICbxygAUq6CdRJ36vFc80DucPueUee+d5NBRxz3FdT9Pes/HEx5mPoT9jwnsEJWz1N7uq7Q==}
|
||||
dev: true
|
||||
|
||||
/lodash/4.17.21:
|
||||
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
|
||||
@@ -7086,7 +7090,6 @@ packages:
|
||||
dependencies:
|
||||
chalk: 5.0.1
|
||||
is-unicode-supported: 1.2.0
|
||||
dev: true
|
||||
|
||||
/log-update/4.0.0:
|
||||
resolution: {integrity: sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==}
|
||||
@@ -7680,7 +7683,6 @@ packages:
|
||||
/mimic-fn/2.1.0:
|
||||
resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==}
|
||||
engines: {node: '>=6'}
|
||||
dev: true
|
||||
|
||||
/mimic-fn/4.0.0:
|
||||
resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==}
|
||||
@@ -8111,7 +8113,6 @@ packages:
|
||||
engines: {node: '>=6'}
|
||||
dependencies:
|
||||
mimic-fn: 2.1.0
|
||||
dev: true
|
||||
|
||||
/onetime/6.0.0:
|
||||
resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==}
|
||||
@@ -8181,7 +8182,6 @@ packages:
|
||||
log-symbols: 5.1.0
|
||||
strip-ansi: 7.0.1
|
||||
wcwidth: 1.0.1
|
||||
dev: true
|
||||
|
||||
/os-name/5.0.1:
|
||||
resolution: {integrity: sha512-0EQpaHUHq7olp2/YFUr+0vZi9tMpDTblHGz+Ch5RntKxiRXOAY0JOz1UlxhSjMSksHvkm13eD6elJj3M8Ht/kw==}
|
||||
@@ -8465,7 +8465,6 @@ packages:
|
||||
/peek-readable/5.0.0:
|
||||
resolution: {integrity: sha512-YtCKvLUOvwtMGmrniQPdO7MwPjgkFBtFIrmfSbYmYuq3tKDV/mcfAhBth1+C3ru7uXIZasc/pHnb+YDYNkkj4A==}
|
||||
engines: {node: '>=14.16'}
|
||||
dev: true
|
||||
|
||||
/peek-stream/1.1.3:
|
||||
resolution: {integrity: sha512-FhJ+YbOSBb9/rIl2ZeE/QHEsWn7PqNYt8ARAY3kIgNGOk13g9FGyIY6JIl/xB/3TFRVoTv5as0l11weORrTekA==}
|
||||
@@ -9068,14 +9067,12 @@ packages:
|
||||
inherits: 2.0.4
|
||||
string_decoder: 1.3.0
|
||||
util-deprecate: 1.0.2
|
||||
dev: true
|
||||
|
||||
/readable-web-to-node-stream/3.0.2:
|
||||
resolution: {integrity: sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==}
|
||||
engines: {node: '>=8'}
|
||||
dependencies:
|
||||
readable-stream: 3.6.0
|
||||
dev: true
|
||||
|
||||
/readdirp/3.6.0:
|
||||
resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
|
||||
@@ -9376,7 +9373,6 @@ packages:
|
||||
dependencies:
|
||||
onetime: 5.1.2
|
||||
signal-exit: 3.0.7
|
||||
dev: true
|
||||
|
||||
/ret/0.1.15:
|
||||
resolution: {integrity: sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==}
|
||||
@@ -9645,7 +9641,6 @@ packages:
|
||||
|
||||
/signal-exit/3.0.7:
|
||||
resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
|
||||
dev: true
|
||||
|
||||
/simple-update-notifier/1.0.7:
|
||||
resolution: {integrity: sha512-BBKgR84BJQJm6WjWFMHgLVuo61FBDSj1z/xSFUIozqO6wO7ii0JxCqlIud7Enr/+LhlbNI0whErq96P2qHNWew==}
|
||||
@@ -9980,7 +9975,6 @@ packages:
|
||||
resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==}
|
||||
dependencies:
|
||||
safe-buffer: 5.2.1
|
||||
dev: true
|
||||
|
||||
/stringify-entities/4.0.3:
|
||||
resolution: {integrity: sha512-BP9nNHMhhfcMbiuQKCqMjhDP5yBCAxsPu4pHFFzJ6Alo9dZgY4VLDPutXqIjpRiMoKdp7Av85Gr73Q5uH9k7+g==}
|
||||
@@ -10001,7 +9995,6 @@ packages:
|
||||
engines: {node: '>=12'}
|
||||
dependencies:
|
||||
ansi-regex: 6.0.1
|
||||
dev: true
|
||||
|
||||
/strip-bom-string/1.0.0:
|
||||
resolution: {integrity: sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==}
|
||||
@@ -10046,7 +10039,6 @@ packages:
|
||||
dependencies:
|
||||
'@tokenizer/token': 0.3.0
|
||||
peek-readable: 5.0.0
|
||||
dev: true
|
||||
|
||||
/style-to-object/0.3.0:
|
||||
resolution: {integrity: sha512-CzFnRRXhzWIdItT3OmF8SQfWyahHhjq3HwcMNCNLn+N7klOOqPjMeG/4JSu77D7ypZdGvSzvkrbyeTMizz2VrA==}
|
||||
@@ -10281,7 +10273,6 @@ packages:
|
||||
dependencies:
|
||||
'@tokenizer/token': 0.3.0
|
||||
ieee754: 1.2.1
|
||||
dev: true
|
||||
|
||||
/toml/3.0.0:
|
||||
resolution: {integrity: sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==}
|
||||
@@ -10337,7 +10328,6 @@ packages:
|
||||
|
||||
/ts-mixer/6.0.1:
|
||||
resolution: {integrity: sha512-hvE+ZYXuINrx6Ei6D6hz+PTim0Uf++dYbK9FFifLNwQj+RwKquhQpn868yZsCtJYiclZF1u8l6WZxxKi+vv7Rg==}
|
||||
dev: true
|
||||
|
||||
/ts-morph/15.1.0:
|
||||
resolution: {integrity: sha512-RBsGE2sDzUXFTnv8Ba22QfeuKbgvAGJFuTN7HfmIRUkgT/NaVLfDM/8OFm2NlFkGlWEXdpW5OaFIp1jvqdDuOg==}
|
||||
@@ -10542,7 +10532,6 @@ packages:
|
||||
/undici/5.8.1:
|
||||
resolution: {integrity: sha512-iDRmWX4Zar/4A/t+1LrKQRm102zw2l9Wgat3LtTlTn8ykvMZmAmpq9tjyHEigx18FsY7IfATvyN3xSw9BDz0eA==}
|
||||
engines: {node: '>=12.18'}
|
||||
dev: true
|
||||
|
||||
/unicode-canonical-property-names-ecmascript/2.0.0:
|
||||
resolution: {integrity: sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==}
|
||||
@@ -10979,7 +10968,6 @@ packages:
|
||||
resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==}
|
||||
dependencies:
|
||||
defaults: 1.0.3
|
||||
dev: true
|
||||
|
||||
/web-encoding/1.1.5:
|
||||
resolution: {integrity: sha512-HYLeVCdJ0+lBYV2FvNZmv3HJ2Nt0QYXqZojk3d9FJOLkwnuhzM9tmamh8d7HPM8QqjKH8DeHkFTx+CFlWpZZDA==}
|
||||
@@ -11161,7 +11149,6 @@ packages:
|
||||
optional: true
|
||||
utf-8-validate:
|
||||
optional: true
|
||||
dev: true
|
||||
|
||||
/xdg-basedir/5.1.0:
|
||||
resolution: {integrity: sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==}
|
||||
|
||||
Reference in New Issue
Block a user