diff --git a/examples/.devcontainer/Dockerfile b/examples/.devcontainer/Dockerfile deleted file mode 100644 index 4ed5f73f9..000000000 --- a/examples/.devcontainer/Dockerfile +++ /dev/null @@ -1,13 +0,0 @@ -FROM mcr.microsoft.com/vscode/devcontainers/base:0-buster - -ENV DENO_INSTALL=/deno -RUN mkdir -p /deno \ - && curl -fsSL https://deno.land/x/install/install.sh | sh \ - && chown -R vscode /deno - -ENV PATH=${DENO_INSTALL}/bin:${PATH} \ - DENO_DIR=${DENO_INSTALL}/.cache/deno - -# [Optional] Uncomment this section to install additional OS packages. -# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ -# && apt-get -y install --no-install-recommends diff --git a/examples/.devcontainer/devcontainer.json b/examples/.devcontainer/devcontainer.json deleted file mode 100644 index 1c8524dd5..000000000 --- a/examples/.devcontainer/devcontainer.json +++ /dev/null @@ -1,51 +0,0 @@ -// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: -// https://github.com/microsoft/vscode-dev-containers/tree/v0.162.0/containers/deno -{ - "name": "Deno", - "dockerFile": "Dockerfile", - // Set *default* container specific settings.json values on container create. - "settings": { - "terminal.integrated.shell.linux": "/bin/bash", - "deno.enable": true, - "editor.defaultFormatter": "denoland.vscode-deno", - "editor.minimap.enabled": false, - "editor.wordWrap": "on", - "editor.codeActionsOnSave": { - "source.organizeImports": true, - "source.fixAll": true - }, - "editor.fontSize": 16, - "workbench.colorTheme": "Material Theme Darker", - "workbench.iconTheme": "eq-material-theme-icons-darker", - "breadcrumbs.enabled": true, - "editor.renderWhitespace": "all", - "editor.suggestSelection": "first", - "editor.formatOnSave": true, - "files.autoSave": "afterDelay", - "editor.fontFamily": "Fira Code, Menlo, Monaco, 'Courier New', monospace", - "typescript.updateImportsOnFileMove.enabled": "always", - "javascript.updateImportsOnFileMove.enabled": "always", - "deno.inlayHints.enumMemberValues.enabled": true, - "deno.inlayHints.functionLikeReturnTypes.enabled": true, - "deno.inlayHints.parameterNames.enabled": "all", - "deno.inlayHints.parameterNames.suppressWhenArgumentMatchesName": false, - "deno.inlayHints.parameterTypes.enabled": true, - "deno.inlayHints.propertyDeclarationTypes.enabled": true, - "deno.inlayHints.variableTypes.enabled": true, - "deno.inlayHints.variableTypes.suppressWhenTypeMatchesName": false - }, - // Add the Ids of extensions you want installed when the container is created. - "extensions": [ - "denoland.vscode-deno", - "pkief.material-icon-theme", - "coenraads.bracket-pair-colorizer", - "equinusocio.vsc-material-theme", - "tabnine.tabnine-vscode" - ], - // Use 'forwardPorts' to make a list of ports inside the container available locally. - // "forwardPorts": [], - // Uncomment to use the Docker CLI from inside the container. See https://aka.ms/vscode-remote/samples/docker-from-docker. - // "mounts": [ "source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind" ], - // Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. - "remoteUser": "vscode" -} diff --git a/examples/.gitignore b/examples/.gitignore deleted file mode 100644 index 7550c4abc..000000000 --- a/examples/.gitignore +++ /dev/null @@ -1,9 +0,0 @@ -.env -fileloader.ts - -config.json - -# Folder made by Kwik db to watch guild command versions -db/ -node_modules -package-lock.json \ No newline at end of file diff --git a/examples/.vscode/settings.json b/examples/.vscode/settings.json deleted file mode 100644 index 1eafdc762..000000000 --- a/examples/.vscode/settings.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "deno.enable": true, - "deno.lint": true, - "editor.formatOnSave": true, - "editor.codeActionsOnSave": { - "source.organizeImports": true, - "source.fixAll": true - }, - "editor.defaultFormatter": "denoland.vscode-deno", - "deno.suggest.imports.hosts": { - "https://deno.land": true - }, - "discord.enabled": true, - "cSpell.words": ["denoland", "Discordeno", "Kwik", "Loglevels", "msgpack", "Slowmode", "upsert"], - "deno.unstable": true, - "deno.inlayHints.enumMemberValues.enabled": true, - "deno.inlayHints.functionLikeReturnTypes.enabled": true, - "deno.inlayHints.parameterNames.enabled": "all", - "deno.inlayHints.parameterNames.suppressWhenArgumentMatchesName": false, - "deno.inlayHints.parameterTypes.enabled": true, - "deno.inlayHints.propertyDeclarationTypes.enabled": true, - "deno.inlayHints.variableTypes.enabled": true, - "deno.inlayHints.variableTypes.suppressWhenTypeMatchesName": false -} diff --git a/examples/README.md b/examples/README.md index d13167d7c..7e4607aa7 100644 --- a/examples/README.md +++ b/examples/README.md @@ -1,10 +1,27 @@ -# Discordeno Bot Template +# Discordeno Bot Templates + +In this directory you will find some example bots written using Discordeno. + +In each template directory you will find more information on how to setup and run the template. + +## Minimal & Beginner + +A very minimal bot with only a /ping command to show how to set-up a discordeno bot for interactions + +The beginner template is a bit more complete and has a caching system already setup using the `dd-cache-proxy` library + +## Advanced + +A more complex bot compared to beginner. It also has a /ping command, but also a /warn command showing how to deal with permissions and sending DMs + +This template has a caching system already setup using the `dd-cache-proxy` library + +## BigBot ![Log Image](https://i.imgur.com/09skKfz.png) -This repo is meant as a template which you can use to create a Discord bot very easily using the -[Discordeno library](https://github.com/discordeno/discordeno). +The BigBot template is intended for more complex systems that need scaling. -[Website/Guide](https://discordeno.js.org/) +The template consists of 3 folders with some common files. The template is configured with a REST proxy, the Gateway in a separate process and the Bot code in another. -[Discord Server](https://discord.com/invite/5vBgXk3UcZ) +While the template does not include any caching by default, you can either install `dd-cache-proxy` and setup it or roll your own solution diff --git a/examples/advanced/.env.example b/examples/advanced/.env.example new file mode 100644 index 000000000..f656e0f9b --- /dev/null +++ b/examples/advanced/.env.example @@ -0,0 +1 @@ +TOKEN= diff --git a/examples/advanced/.gitignore b/examples/advanced/.gitignore new file mode 100644 index 000000000..4bc2fcfaf --- /dev/null +++ b/examples/advanced/.gitignore @@ -0,0 +1,32 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +node_modules + +.pnp.* +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/sdks +!.yarn/versions + +# build +dist + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.pnpm-debug.log* + +# local env files +.env +.env.local +.env.development.local +.env.test.local +.env.production.local diff --git a/examples/advanced/.swcrc b/examples/advanced/.swcrc new file mode 100644 index 000000000..751b8edf8 --- /dev/null +++ b/examples/advanced/.swcrc @@ -0,0 +1,24 @@ +{ + "$schema": "https://json.schemastore.org/swcrc", + "jsc": { + "parser": { + "syntax": "typescript", + "decorators": true, + "dynamicImport": true + }, + "transform": { + "legacyDecorator": true, + "decoratorMetadata": true + }, + "target": "es2022", + "keepClassNames": true, + "loose": true + }, + "module": { + "type": "es6", + "strict": false, + "strictMode": true, + "lazy": false, + "noInterop": false + } +} diff --git a/examples/advanced/README.md b/examples/advanced/README.md new file mode 100644 index 000000000..b9be104cf --- /dev/null +++ b/examples/advanced/README.md @@ -0,0 +1,20 @@ +# Advanced Bot Template + +This template contains more advanced code. + +This template includes caching (using `dd-proxy-cache`), user permission handling, and slash commands options support +This template also includes a /ping command to show the bot latency and a /warn command to show how to send a DM to a user and how to check for permissions + +## Setup + +- Download the source +- Install the dependencies using `yarn` +- Copy the .env.example file and rename it to .env +- Fill out the .env file + +## Run Bot + +- run `yarn` to install the dependencies +- run `yarn build` to build the source +- run `node dist/register-commands.js` to register the slash commands +- run `yarn start` to run the bot diff --git a/examples/advanced/package.json b/examples/advanced/package.json new file mode 100644 index 000000000..a2bf434e8 --- /dev/null +++ b/examples/advanced/package.json @@ -0,0 +1,26 @@ +{ + "name": "dd-advanced-bot", + "version": "1.0.0", + "description": "A bit more advanced bot that has some permission handling and slash command options.", + "main": "dist/index.js", + "type": "module", + "license": "ISC", + "private": true, + "packageManager": "yarn@4.0.2", + "scripts": { + "start": "node dist/index.js", + "build": "swc src --strip-leading-paths --delete-dir-on-start --out-dir dist", + "setup-dd": "" + }, + "dependencies": { + "@discordeno/bot": "19.0.0-next.92bf166", + "dd-cache-proxy": "^2.1.1", + "dotenv": "^16.4.5" + }, + "devDependencies": { + "@swc/cli": "^0.3.12", + "@swc/core": "^1.6.3", + "@types/node": "^20.14.6", + "typescript": "^5.5.2" + } +} diff --git a/examples/advanced/src/bot.ts b/examples/advanced/src/bot.ts new file mode 100644 index 000000000..ea1a2246b --- /dev/null +++ b/examples/advanced/src/bot.ts @@ -0,0 +1,49 @@ +import { createBot, Intents, LogDepth, type logger as discordenoLogger } from '@discordeno/bot' +import { createProxyCache } from 'dd-cache-proxy' +import { configs } from './config.js' + +export const bot = createProxyCache( + createBot({ + token: configs.token, + intents: Intents.Guilds, + }), + { + desiredProps: { + guilds: ['id', 'name', 'roles'], + roles: ['id', 'guildId', 'permissions'], + }, + cacheInMemory: { + guilds: true, + roles: true, + default: false, + }, + }, +) + +// By default, bot.logger will use an instance of the logger from @discordeno/bot, this logger supports depth and we need to change it, so we need to say to TS that we know what we are doing with as +;(bot.logger as typeof discordenoLogger).setDepth(LogDepth.Full) + +// Setup desired proprieties +bot.transformers.desiredProperties.interaction.id = true +bot.transformers.desiredProperties.interaction.type = true +bot.transformers.desiredProperties.interaction.data = true +bot.transformers.desiredProperties.interaction.token = true +bot.transformers.desiredProperties.interaction.guildId = true +bot.transformers.desiredProperties.interaction.member = true + +bot.transformers.desiredProperties.guild.id = true +bot.transformers.desiredProperties.guild.name = true +bot.transformers.desiredProperties.guild.roles = true + +bot.transformers.desiredProperties.role.id = true +bot.transformers.desiredProperties.role.guildId = true +bot.transformers.desiredProperties.role.permissions = true + +bot.transformers.desiredProperties.member.id = true +bot.transformers.desiredProperties.member.roles = true + +bot.transformers.desiredProperties.channel.id = true + +bot.transformers.desiredProperties.user.id = true +bot.transformers.desiredProperties.user.username = true +bot.transformers.desiredProperties.user.discriminator = true diff --git a/examples/advanced/src/commands.ts b/examples/advanced/src/commands.ts new file mode 100644 index 000000000..2b2fa49e2 --- /dev/null +++ b/examples/advanced/src/commands.ts @@ -0,0 +1,20 @@ +import { Collection, type ApplicationCommandOption, type ApplicationCommandTypes, type Interaction } from '@discordeno/bot' + +export const commands = new Collection() + +export function createCommand(command: Command): void { + commands.set(command.name, command) +} + +export interface Command { + /** The name of this command. */ + name: string + /** What does this command do? */ + description: string + /** The type of command this is. */ + type: ApplicationCommandTypes + /** The options for this command */ + options?: ApplicationCommandOption[] + /** This will be executed when the command is run. */ + execute: (interaction: Interaction, options: Record) => unknown +} diff --git a/examples/advanced/src/commands/ping.ts b/examples/advanced/src/commands/ping.ts new file mode 100644 index 000000000..c7eb55b3c --- /dev/null +++ b/examples/advanced/src/commands/ping.ts @@ -0,0 +1,15 @@ +import { ApplicationCommandTypes, createEmbeds, snowflakeToTimestamp } from '@discordeno/bot' +import { createCommand } from '../commands.js' + +createCommand({ + name: 'ping', + description: 'See if the bot latency is okay', + type: ApplicationCommandTypes.ChatInput, + async execute(interaction) { + const ping = Date.now() - snowflakeToTimestamp(interaction.id) + + const embeds = createEmbeds().setTitle(`The bot ping is ${ping}ms`) + + await interaction.respond({ embeds }) + }, +}) diff --git a/examples/advanced/src/commands/warn.ts b/examples/advanced/src/commands/warn.ts new file mode 100644 index 000000000..4eea54dbb --- /dev/null +++ b/examples/advanced/src/commands/warn.ts @@ -0,0 +1,80 @@ +import { ApplicationCommandOptionTypes, ApplicationCommandTypes, createEmbeds, Permissions, type Member, type User } from '@discordeno/bot' +import { bot } from '../bot.js' +import { createCommand } from '../commands.js' +import { calculateMemberPermissions } from '../utils/permissions.js' + +createCommand({ + name: 'warn', + description: 'Warn a user from the server', + type: ApplicationCommandTypes.ChatInput, + options: [ + { + name: 'user', + description: 'The user you want to warn', + type: ApplicationCommandOptionTypes.User, + required: true, + }, + { + name: 'reason', + description: 'The reason for the warn', + type: ApplicationCommandOptionTypes.String, + maxLength: 300, + }, + ], + async execute(interaction, options) { + if (!interaction.guildId || !interaction.member) { + await interaction.respond('This command can only be ran in guilds') + return + } + + // Type based on the options declared above + const { user, reason } = options as { user: UserResolved; reason?: string } + + const guild = await bot.cache.guilds.get(interaction.guildId) + + if (!guild) { + await interaction.respond('An error has occurred') + return + } + + await interaction.defer() + + const perms = new Permissions(await calculateMemberPermissions(guild, interaction.member)) + + const adminPerm = perms.has('ADMINISTRATOR') + const kickMembersPerm = adminPerm || perms.has('KICK_MEMBERS') + + if (!kickMembersPerm) { + await interaction.respond("You don't have the necessary permissions to warn a members (this command requires `Kick members`)") + return + } + + const embeds = createEmbeds() + .setTitle('Warned User:') + .setDescription(`User: <@${user.user.id}>\nReason: ${reason}`) + .setColor(0x00ff00) + .setTimestamp(Date.now()) + + const warnEmbeds = createEmbeds() + .setTitle('Warning:') + .setDescription(`You have been warned in **${guild.name}** for \`${reason}\``) + .setTimestamp(Date.now()) + + try { + const dmChannel = await bot.helpers.getDmChannel(user.user.id) + await bot.helpers.sendMessage(dmChannel.id, { embeds: warnEmbeds }) + } catch (error) { + bot.logger.error(`There was an error in the warn command:`, error) + + await interaction.respond(`Could not warn user <@${user.user.id}> | They likely do not have their DMs open.`) + return + } + + await interaction.respond({ embeds }) + }, +}) + +interface UserResolved { + user: User + member?: Member +} diff --git a/examples/advanced/src/config.ts b/examples/advanced/src/config.ts new file mode 100644 index 000000000..01a52c3e5 --- /dev/null +++ b/examples/advanced/src/config.ts @@ -0,0 +1,11 @@ +const token = process.env.TOKEN + +if (!token) throw new Error('Missing TOKEN environment variable') + +export const configs: Config = { + token, +} + +export interface Config { + token: string +} diff --git a/examples/advanced/src/events/interactionCreate.ts b/examples/advanced/src/events/interactionCreate.ts new file mode 100644 index 000000000..5f80c225f --- /dev/null +++ b/examples/advanced/src/events/interactionCreate.ts @@ -0,0 +1,22 @@ +import { InteractionTypes, commandOptionsParser } from '@discordeno/bot' +import { bot } from '../bot.js' +import { commands } from '../commands.js' + +bot.events.interactionCreate = async (interaction) => { + if (!interaction.data || interaction.type !== InteractionTypes.ApplicationCommand) return + + const command = commands.get(interaction.data.name) + + if (!command) { + bot.logger.error(`Command ${interaction.data.name} not found`) + return + } + + const options = commandOptionsParser(interaction) + + try { + await command.execute(interaction, options) + } catch (error) { + bot.logger.error(`There was an error running the ${command.name} command.`, error) + } +} diff --git a/examples/advanced/src/events/ready.ts b/examples/advanced/src/events/ready.ts new file mode 100644 index 000000000..5b7255836 --- /dev/null +++ b/examples/advanced/src/events/ready.ts @@ -0,0 +1,8 @@ +import { bot } from '../bot.js' + +bot.events.ready = ({ user, shardId }) => { + if (shardId === bot.gateway.lastShardId) { + // All shards are ready + bot.logger.info(`Successfully connected to the gateway as ${user.username}#${user.discriminator}`) + } +} diff --git a/examples/advanced/src/index.ts b/examples/advanced/src/index.ts new file mode 100644 index 000000000..0d69c323b --- /dev/null +++ b/examples/advanced/src/index.ts @@ -0,0 +1,14 @@ +import 'dotenv/config' + +import { bot } from './bot.js' +import importDirectory from './utils/loader.js' + +bot.logger.info('Starting bot...') + +bot.logger.info('Loading commands...') +await importDirectory('./dist/commands') + +bot.logger.info('Loading events...') +await importDirectory('./dist/events') + +await bot.start() diff --git a/examples/advanced/src/register-commands.ts b/examples/advanced/src/register-commands.ts new file mode 100644 index 000000000..db6823181 --- /dev/null +++ b/examples/advanced/src/register-commands.ts @@ -0,0 +1,7 @@ +import 'dotenv/config' + +import { bot } from './bot.js' +import { updateApplicationCommands } from './utils/updateCommands.js' + +bot.logger.info('Updating commands...') +await updateApplicationCommands() diff --git a/examples/advanced/src/utils/loader.ts b/examples/advanced/src/utils/loader.ts new file mode 100644 index 000000000..d3fa9b379 --- /dev/null +++ b/examples/advanced/src/utils/loader.ts @@ -0,0 +1,15 @@ +import { logger } from '@discordeno/bot' +import { readdir } from 'node:fs/promises' + +export default async function importDirectory(folder: string): Promise { + const files = await readdir(folder, { recursive: true }) + + for (const filename of files) { + if (!filename.endsWith('.js')) continue + + // Using `file://` and `process.cwd()` to avoid weird issues with relative paths and/or Windows + await import(`file://${process.cwd()}/${folder}/${filename}`).catch((x) => + logger.fatal(`Cannot import file (${folder}/${filename}) for reason:`, x), + ) + } +} diff --git a/examples/advanced/src/utils/permissions.ts b/examples/advanced/src/utils/permissions.ts new file mode 100644 index 000000000..4d8a9e80c --- /dev/null +++ b/examples/advanced/src/utils/permissions.ts @@ -0,0 +1,20 @@ +import { BitwisePermissionFlags, type Guild, type Member } from '@discordeno/bot' +import assert from 'node:assert' + +export async function calculateMemberPermissions(guild: Guild, member: Member): Promise { + if (member.id === guild.ownerId) return 8n + + let permissions = guild.roles.get(guild.id)?.permissions.bitfield + const rolePerms = member.roles.map((x) => guild.roles.get(x)?.permissions.bitfield).filter((x): x is bigint => x !== undefined) + + // Small hack to avoid calling assert with 0n + if (permissions === undefined) assert(permissions) + + for (const rolePerm of rolePerms) { + permissions |= rolePerm + } + + if ((permissions & BigInt(BitwisePermissionFlags.ADMINISTRATOR)) === BigInt(BitwisePermissionFlags.ADMINISTRATOR)) return 8n + + return permissions +} diff --git a/examples/advanced/src/utils/updateCommands.ts b/examples/advanced/src/utils/updateCommands.ts new file mode 100644 index 000000000..d92a348d6 --- /dev/null +++ b/examples/advanced/src/utils/updateCommands.ts @@ -0,0 +1,6 @@ +import { bot } from '../bot.js' +import { commands } from '../commands.js' + +export async function updateApplicationCommands(): Promise { + await bot.helpers.upsertGlobalApplicationCommands(commands.array()) +} diff --git a/examples/advanced/tsconfig.json b/examples/advanced/tsconfig.json new file mode 100644 index 000000000..04416ddd6 --- /dev/null +++ b/examples/advanced/tsconfig.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "target": "es2022", + "module": "es2022", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "isolatedModules": true, + "moduleResolution": "node", + "skipDefaultLibCheck": true, + "skipLibCheck": true, + "strict": true, + "incremental": true + } +} diff --git a/examples/advanced/yarn.lock b/examples/advanced/yarn.lock new file mode 100644 index 000000000..3953a14f1 --- /dev/null +++ b/examples/advanced/yarn.lock @@ -0,0 +1,2124 @@ +# This file is generated by running "yarn install" inside your project. +# Manual changes might be lost - proceed with caution! + +__metadata: + version: 8 + cacheKey: 10 + +"@discordeno/bot@npm:19.0.0-next.92bf166": + version: 19.0.0-next.92bf166 + resolution: "@discordeno/bot@npm:19.0.0-next.92bf166" + dependencies: + "@discordeno/gateway": "npm:19.0.0-next.92bf166" + "@discordeno/rest": "npm:19.0.0-next.92bf166" + "@discordeno/types": "npm:19.0.0-next.92bf166" + "@discordeno/utils": "npm:19.0.0-next.92bf166" + checksum: 3020e74c774eae34307d434ad38f983e90839dc5fad7578f3cda4fba6c1efb7a22c4f4cdcfff58c54b62cc14976ad974256955d5117e490f78ec9e835e02c682 + languageName: node + linkType: hard + +"@discordeno/gateway@npm:19.0.0-next.92bf166": + version: 19.0.0-next.92bf166 + resolution: "@discordeno/gateway@npm:19.0.0-next.92bf166" + dependencies: + "@discordeno/types": "npm:19.0.0-next.92bf166" + "@discordeno/utils": "npm:19.0.0-next.92bf166" + ws: "npm:^8.16.0" + checksum: 6a11ca7a4cb98f48726664d0baa27d04e26342bf94d6e439494e462636af20d17b567e9d3e2e478465aabcecb98a21e54b860b39b9f1022eef922e76d947ddcb + languageName: node + linkType: hard + +"@discordeno/rest@npm:19.0.0-next.92bf166": + version: 19.0.0-next.92bf166 + resolution: "@discordeno/rest@npm:19.0.0-next.92bf166" + dependencies: + "@discordeno/types": "npm:19.0.0-next.92bf166" + "@discordeno/utils": "npm:19.0.0-next.92bf166" + dotenv: "npm:^16.4.5" + checksum: 45f6ba4791003b77c883e991ad348597197d70e25e335b8628a03bd2effa8e2047a2f987f4c0b6ee8b17c01f77055d7a1ddc9f5350eb8f1c8ff8c8d39f91d787 + languageName: node + linkType: hard + +"@discordeno/types@npm:19.0.0-next.92bf166": + version: 19.0.0-next.92bf166 + resolution: "@discordeno/types@npm:19.0.0-next.92bf166" + checksum: f88e78a18e51c179b94ef14e8bcdd6b5e6c5f25bdd6c4308bec121e5e59533612b36ed0e7a447daedc009053e1e30c6c8e13b2276bb1ce7e2f840ff58473a2ef + languageName: node + linkType: hard + +"@discordeno/utils@npm:19.0.0-next.92bf166": + version: 19.0.0-next.92bf166 + resolution: "@discordeno/utils@npm:19.0.0-next.92bf166" + dependencies: + "@discordeno/types": "npm:19.0.0-next.92bf166" + tweetnacl: "npm:^1.0.3" + checksum: 7962a057ba5908936e4224df70b9ceaffcb8ec7ad220a999b36fc0601365b380bb0de01b6adfa4c36250247e3d15e22215fc63bbe3634b932434411c5f4ca13d + languageName: node + linkType: hard + +"@isaacs/cliui@npm:^8.0.2": + version: 8.0.2 + resolution: "@isaacs/cliui@npm:8.0.2" + dependencies: + string-width: "npm:^5.1.2" + string-width-cjs: "npm:string-width@^4.2.0" + strip-ansi: "npm:^7.0.1" + strip-ansi-cjs: "npm:strip-ansi@^6.0.1" + wrap-ansi: "npm:^8.1.0" + wrap-ansi-cjs: "npm:wrap-ansi@^7.0.0" + checksum: e9ed5fd27c3aec1095e3a16e0c0cf148d1fee55a38665c35f7b3f86a9b5d00d042ddaabc98e8a1cb7463b9378c15f22a94eb35e99469c201453eb8375191f243 + languageName: node + linkType: hard + +"@mole-inc/bin-wrapper@npm:^8.0.1": + version: 8.0.1 + resolution: "@mole-inc/bin-wrapper@npm:8.0.1" + dependencies: + bin-check: "npm:^4.1.0" + bin-version-check: "npm:^5.0.0" + content-disposition: "npm:^0.5.4" + ext-name: "npm:^5.0.0" + file-type: "npm:^17.1.6" + filenamify: "npm:^5.0.2" + got: "npm:^11.8.5" + os-filter-obj: "npm:^2.0.0" + checksum: 565df38f6f91fefe2e2540bf4357024fd912990aecb1873fd9bf21e6a667d9930c73e5cbc87a9aac0cf476b8dffc30a4e00ec97b62e713ef5c00d46823ea599d + languageName: node + linkType: hard + +"@nodelib/fs.scandir@npm:2.1.5": + version: 2.1.5 + resolution: "@nodelib/fs.scandir@npm:2.1.5" + dependencies: + "@nodelib/fs.stat": "npm:2.0.5" + run-parallel: "npm:^1.1.9" + checksum: 6ab2a9b8a1d67b067922c36f259e3b3dfd6b97b219c540877a4944549a4d49ea5ceba5663905ab5289682f1f3c15ff441d02f0447f620a42e1cb5e1937174d4b + languageName: node + linkType: hard + +"@nodelib/fs.stat@npm:2.0.5, @nodelib/fs.stat@npm:^2.0.2": + version: 2.0.5 + resolution: "@nodelib/fs.stat@npm:2.0.5" + checksum: 012480b5ca9d97bff9261571dbbec7bbc6033f69cc92908bc1ecfad0792361a5a1994bc48674b9ef76419d056a03efadfce5a6cf6dbc0a36559571a7a483f6f0 + languageName: node + linkType: hard + +"@nodelib/fs.walk@npm:^1.2.3": + version: 1.2.8 + resolution: "@nodelib/fs.walk@npm:1.2.8" + dependencies: + "@nodelib/fs.scandir": "npm:2.1.5" + fastq: "npm:^1.6.0" + checksum: 40033e33e96e97d77fba5a238e4bba4487b8284678906a9f616b5579ddaf868a18874c0054a75402c9fbaaa033a25ceae093af58c9c30278e35c23c9479e79b0 + languageName: node + linkType: hard + +"@npmcli/agent@npm:^2.0.0": + version: 2.2.2 + resolution: "@npmcli/agent@npm:2.2.2" + dependencies: + agent-base: "npm:^7.1.0" + http-proxy-agent: "npm:^7.0.0" + https-proxy-agent: "npm:^7.0.1" + lru-cache: "npm:^10.0.1" + socks-proxy-agent: "npm:^8.0.3" + checksum: 96fc0036b101bae5032dc2a4cd832efb815ce9b33f9ee2f29909ee49d96a0026b3565f73c507a69eb8603f5cb32e0ae45a70cab1e2655990a4e06ae99f7f572a + languageName: node + linkType: hard + +"@npmcli/fs@npm:^3.1.0": + version: 3.1.1 + resolution: "@npmcli/fs@npm:3.1.1" + dependencies: + semver: "npm:^7.3.5" + checksum: 1e0e04087049b24b38bc0b30d87a9388ee3ca1d3fdfc347c2f77d84fcfe6a51f250bc57ba2c1f614d7e4285c6c62bf8c769bc19aa0949ea39e5b043ee023b0bd + languageName: node + linkType: hard + +"@pkgjs/parseargs@npm:^0.11.0": + version: 0.11.0 + resolution: "@pkgjs/parseargs@npm:0.11.0" + checksum: 115e8ceeec6bc69dff2048b35c0ab4f8bbee12d8bb6c1f4af758604586d802b6e669dcb02dda61d078de42c2b4ddce41b3d9e726d7daa6b4b850f4adbf7333ff + languageName: node + linkType: hard + +"@sindresorhus/is@npm:^4.0.0": + version: 4.6.0 + resolution: "@sindresorhus/is@npm:4.6.0" + checksum: e7f36ed72abfcd5e0355f7423a72918b9748bb1ef370a59f3e5ad8d40b728b85d63b272f65f63eec1faf417cda89dcb0aeebe94015647b6054659c1442fe5ce0 + languageName: node + linkType: hard + +"@swc/cli@npm:^0.3.12": + version: 0.3.12 + resolution: "@swc/cli@npm:0.3.12" + dependencies: + "@mole-inc/bin-wrapper": "npm:^8.0.1" + "@swc/counter": "npm:^0.1.3" + commander: "npm:^8.3.0" + fast-glob: "npm:^3.2.5" + minimatch: "npm:^9.0.3" + piscina: "npm:^4.3.0" + semver: "npm:^7.3.8" + slash: "npm:3.0.0" + source-map: "npm:^0.7.3" + peerDependencies: + "@swc/core": ^1.2.66 + chokidar: ^3.5.1 + peerDependenciesMeta: + chokidar: + optional: true + bin: + spack: bin/spack.js + swc: bin/swc.js + swcx: bin/swcx.js + checksum: fee260434fad8eed0328f4db17f42ce0864b93b90fcb02f3f0eb3aad994b5a6ae4bfdfb6d2329377e0cd8d07adc61cca42e290bf0005c1ab4d004d4a0b152db4 + languageName: node + linkType: hard + +"@swc/core-darwin-arm64@npm:1.6.3": + version: 1.6.3 + resolution: "@swc/core-darwin-arm64@npm:1.6.3" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@swc/core-darwin-x64@npm:1.6.3": + version: 1.6.3 + resolution: "@swc/core-darwin-x64@npm:1.6.3" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@swc/core-linux-arm-gnueabihf@npm:1.6.3": + version: 1.6.3 + resolution: "@swc/core-linux-arm-gnueabihf@npm:1.6.3" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@swc/core-linux-arm64-gnu@npm:1.6.3": + version: 1.6.3 + resolution: "@swc/core-linux-arm64-gnu@npm:1.6.3" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@swc/core-linux-arm64-musl@npm:1.6.3": + version: 1.6.3 + resolution: "@swc/core-linux-arm64-musl@npm:1.6.3" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@swc/core-linux-x64-gnu@npm:1.6.3": + version: 1.6.3 + resolution: "@swc/core-linux-x64-gnu@npm:1.6.3" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@swc/core-linux-x64-musl@npm:1.6.3": + version: 1.6.3 + resolution: "@swc/core-linux-x64-musl@npm:1.6.3" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@swc/core-win32-arm64-msvc@npm:1.6.3": + version: 1.6.3 + resolution: "@swc/core-win32-arm64-msvc@npm:1.6.3" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@swc/core-win32-ia32-msvc@npm:1.6.3": + version: 1.6.3 + resolution: "@swc/core-win32-ia32-msvc@npm:1.6.3" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@swc/core-win32-x64-msvc@npm:1.6.3": + version: 1.6.3 + resolution: "@swc/core-win32-x64-msvc@npm:1.6.3" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@swc/core@npm:^1.6.3": + version: 1.6.3 + resolution: "@swc/core@npm:1.6.3" + dependencies: + "@swc/core-darwin-arm64": "npm:1.6.3" + "@swc/core-darwin-x64": "npm:1.6.3" + "@swc/core-linux-arm-gnueabihf": "npm:1.6.3" + "@swc/core-linux-arm64-gnu": "npm:1.6.3" + "@swc/core-linux-arm64-musl": "npm:1.6.3" + "@swc/core-linux-x64-gnu": "npm:1.6.3" + "@swc/core-linux-x64-musl": "npm:1.6.3" + "@swc/core-win32-arm64-msvc": "npm:1.6.3" + "@swc/core-win32-ia32-msvc": "npm:1.6.3" + "@swc/core-win32-x64-msvc": "npm:1.6.3" + "@swc/counter": "npm:^0.1.3" + "@swc/types": "npm:^0.1.8" + peerDependencies: + "@swc/helpers": "*" + dependenciesMeta: + "@swc/core-darwin-arm64": + optional: true + "@swc/core-darwin-x64": + optional: true + "@swc/core-linux-arm-gnueabihf": + optional: true + "@swc/core-linux-arm64-gnu": + optional: true + "@swc/core-linux-arm64-musl": + optional: true + "@swc/core-linux-x64-gnu": + optional: true + "@swc/core-linux-x64-musl": + optional: true + "@swc/core-win32-arm64-msvc": + optional: true + "@swc/core-win32-ia32-msvc": + optional: true + "@swc/core-win32-x64-msvc": + optional: true + peerDependenciesMeta: + "@swc/helpers": + optional: true + checksum: b4c84a083ecabb0280ba53dffa65a5a575321de94081ad52bd12027fe3b5c8957978f2211b6036e2e28d904dd046fca238106c2106b32d02b752808a51193d35 + languageName: node + linkType: hard + +"@swc/counter@npm:^0.1.3": + version: 0.1.3 + resolution: "@swc/counter@npm:0.1.3" + checksum: df8f9cfba9904d3d60f511664c70d23bb323b3a0803ec9890f60133954173047ba9bdeabce28cd70ba89ccd3fd6c71c7b0bd58be85f611e1ffbe5d5c18616598 + languageName: node + linkType: hard + +"@swc/types@npm:^0.1.8": + version: 0.1.8 + resolution: "@swc/types@npm:0.1.8" + dependencies: + "@swc/counter": "npm:^0.1.3" + checksum: 2d1cda35116e03714137c1c37f4493efe0e26e88285ecc9dcdf6256a77984e367ea7b5f31d650f110fdcfd6ac53dff3ec77f841787ca328d2efa7b07ef1ac318 + languageName: node + linkType: hard + +"@szmarczak/http-timer@npm:^4.0.5": + version: 4.0.6 + resolution: "@szmarczak/http-timer@npm:4.0.6" + dependencies: + defer-to-connect: "npm:^2.0.0" + checksum: c29df3bcec6fc3bdec2b17981d89d9c9fc9bd7d0c9bcfe92821dc533f4440bc890ccde79971838b4ceed1921d456973c4180d7175ee1d0023ad0562240a58d95 + languageName: node + linkType: hard + +"@tokenizer/token@npm:^0.3.0": + version: 0.3.0 + resolution: "@tokenizer/token@npm:0.3.0" + checksum: 889c1f1e63ac7c92c0ea22d4a2861142f1b43c3d92eb70ec42aa9e9851fab2e9952211d50f541b287781280df2f979bf5600a9c1f91fbc61b7fcf9994e9376a5 + languageName: node + linkType: hard + +"@types/cacheable-request@npm:^6.0.1": + version: 6.0.3 + resolution: "@types/cacheable-request@npm:6.0.3" + dependencies: + "@types/http-cache-semantics": "npm:*" + "@types/keyv": "npm:^3.1.4" + "@types/node": "npm:*" + "@types/responselike": "npm:^1.0.0" + checksum: 159f9fdb2a1b7175eef453ae2ced5ea04c0d2b9610cc9ccd9f9abb066d36dacb1f37acd879ace10ad7cbb649490723feb396fb7307004c9670be29636304b988 + languageName: node + linkType: hard + +"@types/http-cache-semantics@npm:*": + version: 4.0.4 + resolution: "@types/http-cache-semantics@npm:4.0.4" + checksum: a59566cff646025a5de396d6b3f44a39ab6a74f2ed8150692e0f31cc52f3661a68b04afe3166ebe0d566bd3259cb18522f46e949576d5204781cd6452b7fe0c5 + languageName: node + linkType: hard + +"@types/keyv@npm:^3.1.4": + version: 3.1.4 + resolution: "@types/keyv@npm:3.1.4" + dependencies: + "@types/node": "npm:*" + checksum: e009a2bfb50e90ca9b7c6e8f648f8464067271fd99116f881073fa6fa76dc8d0133181dd65e6614d5fb1220d671d67b0124aef7d97dc02d7e342ab143a47779d + languageName: node + linkType: hard + +"@types/node@npm:*, @types/node@npm:^20.14.6": + version: 20.14.6 + resolution: "@types/node@npm:20.14.6" + dependencies: + undici-types: "npm:~5.26.4" + checksum: 1dcfeeb03ce3c3a1d8a537fefee7cd0cffb78f89e9535b74ee12940559566b57c39dad20d1b165b60b5727408dd44e1a52e5c01cf02d0a99d93ef3da8062c86e + languageName: node + linkType: hard + +"@types/responselike@npm:^1.0.0": + version: 1.0.3 + resolution: "@types/responselike@npm:1.0.3" + dependencies: + "@types/node": "npm:*" + checksum: 6ac4b35723429b11b117e813c7acc42c3af8b5554caaf1fc750404c1ae59f9b7376bc69b9e9e194a5a97357a597c2228b7173d317320f0360d617b6425212f58 + languageName: node + linkType: hard + +"abbrev@npm:^2.0.0": + version: 2.0.0 + resolution: "abbrev@npm:2.0.0" + checksum: ca0a54e35bea4ece0ecb68a47b312e1a9a6f772408d5bcb9051230aaa94b0460671c5b5c9cb3240eb5b7bc94c52476550eb221f65a0bbd0145bdc9f3113a6707 + languageName: node + linkType: hard + +"agent-base@npm:^7.0.2, agent-base@npm:^7.1.0, agent-base@npm:^7.1.1": + version: 7.1.1 + resolution: "agent-base@npm:7.1.1" + dependencies: + debug: "npm:^4.3.4" + checksum: c478fec8f79953f118704d007a38f2a185458853f5c45579b9669372bd0e12602e88dc2ad0233077831504f7cd6fcc8251c383375bba5eaaf563b102938bda26 + languageName: node + linkType: hard + +"aggregate-error@npm:^3.0.0": + version: 3.1.0 + resolution: "aggregate-error@npm:3.1.0" + dependencies: + clean-stack: "npm:^2.0.0" + indent-string: "npm:^4.0.0" + checksum: 1101a33f21baa27a2fa8e04b698271e64616b886795fd43c31068c07533c7b3facfcaf4e9e0cab3624bd88f729a592f1c901a1a229c9e490eafce411a8644b79 + languageName: node + linkType: hard + +"ansi-regex@npm:^5.0.1": + version: 5.0.1 + resolution: "ansi-regex@npm:5.0.1" + checksum: 2aa4bb54caf2d622f1afdad09441695af2a83aa3fe8b8afa581d205e57ed4261c183c4d3877cee25794443fde5876417d859c108078ab788d6af7e4fe52eb66b + languageName: node + linkType: hard + +"ansi-regex@npm:^6.0.1": + version: 6.0.1 + resolution: "ansi-regex@npm:6.0.1" + checksum: 1ff8b7667cded1de4fa2c9ae283e979fc87036864317da86a2e546725f96406746411d0d85e87a2d12fa5abd715d90006de7fa4fa0477c92321ad3b4c7d4e169 + languageName: node + linkType: hard + +"ansi-styles@npm:^4.0.0": + version: 4.3.0 + resolution: "ansi-styles@npm:4.3.0" + dependencies: + color-convert: "npm:^2.0.1" + checksum: b4494dfbfc7e4591b4711a396bd27e540f8153914123dccb4cdbbcb514015ada63a3809f362b9d8d4f6b17a706f1d7bea3c6f974b15fa5ae76b5b502070889ff + languageName: node + linkType: hard + +"ansi-styles@npm:^6.1.0": + version: 6.2.1 + resolution: "ansi-styles@npm:6.2.1" + checksum: 70fdf883b704d17a5dfc9cde206e698c16bcd74e7f196ab821511651aee4f9f76c9514bdfa6ca3a27b5e49138b89cb222a28caf3afe4567570139577f991df32 + languageName: node + linkType: hard + +"arch@npm:^2.1.0": + version: 2.2.0 + resolution: "arch@npm:2.2.0" + checksum: e35dbc6d362297000ab90930069576ba165fe63cd52383efcce14bd66c1b16a91ce849e1fd239964ed029d5e0bdfc32f68e9c7331b7df6c84ddebebfdbf242f7 + languageName: node + linkType: hard + +"balanced-match@npm:^1.0.0": + version: 1.0.2 + resolution: "balanced-match@npm:1.0.2" + checksum: 9706c088a283058a8a99e0bf91b0a2f75497f185980d9ffa8b304de1d9e58ebda7c72c07ebf01dadedaac5b2907b2c6f566f660d62bd336c3468e960403b9d65 + languageName: node + linkType: hard + +"bin-check@npm:^4.1.0": + version: 4.1.0 + resolution: "bin-check@npm:4.1.0" + dependencies: + execa: "npm:^0.7.0" + executable: "npm:^4.1.0" + checksum: 16f6d5d86df9365dab682c7dd238f93678b773a908b3bccea4b1acb82b9b4e49fcfa24c99b99180a8e4cdd89a8f15f03700b09908ed5ae651f52fd82488a3507 + languageName: node + linkType: hard + +"bin-version-check@npm:^5.0.0": + version: 5.1.0 + resolution: "bin-version-check@npm:5.1.0" + dependencies: + bin-version: "npm:^6.0.0" + semver: "npm:^7.5.3" + semver-truncate: "npm:^3.0.0" + checksum: d99679cfe0964703045fe0145a98f117888942b621dfe2c2377305ee9a9d735374d8e3ecb3b476507b284af2567699f24f7ecb2feb1f27ad6086ad60b3198893 + languageName: node + linkType: hard + +"bin-version@npm:^6.0.0": + version: 6.0.0 + resolution: "bin-version@npm:6.0.0" + dependencies: + execa: "npm:^5.0.0" + find-versions: "npm:^5.0.0" + checksum: 78c29422ea9597eb4c8d4f0eff96df60d09aa82b53a87925bc403efbe5c55251b1a07baac538381d9096377f92d27e3c03963efa86db5bc0d6431b9563946229 + languageName: node + linkType: hard + +"brace-expansion@npm:^2.0.1": + version: 2.0.1 + resolution: "brace-expansion@npm:2.0.1" + dependencies: + balanced-match: "npm:^1.0.0" + checksum: a61e7cd2e8a8505e9f0036b3b6108ba5e926b4b55089eeb5550cd04a471fe216c96d4fe7e4c7f995c728c554ae20ddfc4244cad10aef255e72b62930afd233d1 + languageName: node + linkType: hard + +"braces@npm:^3.0.3": + version: 3.0.3 + resolution: "braces@npm:3.0.3" + dependencies: + fill-range: "npm:^7.1.1" + checksum: fad11a0d4697a27162840b02b1fad249c1683cbc510cd5bf1a471f2f8085c046d41094308c577a50a03a579dd99d5a6b3724c4b5e8b14df2c4443844cfcda2c6 + languageName: node + linkType: hard + +"cacache@npm:^18.0.0": + version: 18.0.3 + resolution: "cacache@npm:18.0.3" + dependencies: + "@npmcli/fs": "npm:^3.1.0" + fs-minipass: "npm:^3.0.0" + glob: "npm:^10.2.2" + lru-cache: "npm:^10.0.1" + minipass: "npm:^7.0.3" + minipass-collect: "npm:^2.0.1" + minipass-flush: "npm:^1.0.5" + minipass-pipeline: "npm:^1.2.4" + p-map: "npm:^4.0.0" + ssri: "npm:^10.0.0" + tar: "npm:^6.1.11" + unique-filename: "npm:^3.0.0" + checksum: d4c161f071524bb636334b8cf94780c014e29c180a886b8184da8f2f44d2aca88d5664797c661e9f74bdbd34697c2f231ed7c24c256cecbb0a0563ad1ada2219 + languageName: node + linkType: hard + +"cacheable-lookup@npm:^5.0.3": + version: 5.0.4 + resolution: "cacheable-lookup@npm:5.0.4" + checksum: 618a8b3eea314060e74cb3285a6154e8343c244a34235acf91cfe626ee0705c24e3cd11e4b1a7b3900bd749ee203ae65afe13adf610c8ab173e99d4a208faf75 + languageName: node + linkType: hard + +"cacheable-request@npm:^7.0.2": + version: 7.0.4 + resolution: "cacheable-request@npm:7.0.4" + dependencies: + clone-response: "npm:^1.0.2" + get-stream: "npm:^5.1.0" + http-cache-semantics: "npm:^4.0.0" + keyv: "npm:^4.0.0" + lowercase-keys: "npm:^2.0.0" + normalize-url: "npm:^6.0.1" + responselike: "npm:^2.0.0" + checksum: 0f4f2001260ecca78b9f64fc8245e6b5a5dcde24ea53006daab71f5e0e1338095aa1512ec099c4f9895a9e5acfac9da423cb7c079e131485891e9214aca46c41 + languageName: node + linkType: hard + +"chownr@npm:^2.0.0": + version: 2.0.0 + resolution: "chownr@npm:2.0.0" + checksum: c57cf9dd0791e2f18a5ee9c1a299ae6e801ff58fee96dc8bfd0dcb4738a6ce58dd252a3605b1c93c6418fe4f9d5093b28ffbf4d66648cb2a9c67eaef9679be2f + languageName: node + linkType: hard + +"clean-stack@npm:^2.0.0": + version: 2.2.0 + resolution: "clean-stack@npm:2.2.0" + checksum: 2ac8cd2b2f5ec986a3c743935ec85b07bc174d5421a5efc8017e1f146a1cf5f781ae962618f416352103b32c9cd7e203276e8c28241bbe946160cab16149fb68 + languageName: node + linkType: hard + +"clone-response@npm:^1.0.2": + version: 1.0.3 + resolution: "clone-response@npm:1.0.3" + dependencies: + mimic-response: "npm:^1.0.0" + checksum: 4e671cac39b11c60aa8ba0a450657194a5d6504df51bca3fac5b3bd0145c4f8e8464898f87c8406b83232e3bc5cca555f51c1f9c8ac023969ebfbf7f6bdabb2e + languageName: node + linkType: hard + +"color-convert@npm:^2.0.1": + version: 2.0.1 + resolution: "color-convert@npm:2.0.1" + dependencies: + color-name: "npm:~1.1.4" + checksum: fa00c91b4332b294de06b443923246bccebe9fab1b253f7fe1772d37b06a2269b4039a85e309abe1fe11b267b11c08d1d0473fda3badd6167f57313af2887a64 + languageName: node + linkType: hard + +"color-name@npm:~1.1.4": + version: 1.1.4 + resolution: "color-name@npm:1.1.4" + checksum: b0445859521eb4021cd0fb0cc1a75cecf67fceecae89b63f62b201cca8d345baf8b952c966862a9d9a2632987d4f6581f0ec8d957dfacece86f0a7919316f610 + languageName: node + linkType: hard + +"commander@npm:^8.3.0": + version: 8.3.0 + resolution: "commander@npm:8.3.0" + checksum: 6b7b5d334483ce24bd73c5dac2eab901a7dbb25fd983ea24a1eeac6e7166bb1967f641546e8abf1920afbde86a45fbfe5812fbc69d0dc451bb45ca416a12a3a3 + languageName: node + linkType: hard + +"content-disposition@npm:^0.5.4": + version: 0.5.4 + resolution: "content-disposition@npm:0.5.4" + dependencies: + safe-buffer: "npm:5.2.1" + checksum: b7f4ce176e324f19324be69b05bf6f6e411160ac94bc523b782248129eb1ef3be006f6cff431aaea5e337fe5d176ce8830b8c2a1b721626ead8933f0cbe78720 + languageName: node + linkType: hard + +"cross-spawn@npm:^5.0.1": + version: 5.1.0 + resolution: "cross-spawn@npm:5.1.0" + dependencies: + lru-cache: "npm:^4.0.1" + shebang-command: "npm:^1.2.0" + which: "npm:^1.2.9" + checksum: 726939c9954fc70c20e538923feaaa33bebc253247d13021737c3c7f68cdc3e0a57f720c0fe75057c0387995349f3f12e20e9bfdbf12274db28019c7ea4ec166 + languageName: node + linkType: hard + +"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.3": + version: 7.0.3 + resolution: "cross-spawn@npm:7.0.3" + dependencies: + path-key: "npm:^3.1.0" + shebang-command: "npm:^2.0.0" + which: "npm:^2.0.1" + checksum: e1a13869d2f57d974de0d9ef7acbf69dc6937db20b918525a01dacb5032129bd552d290d886d981e99f1b624cb03657084cc87bd40f115c07ecf376821c729ce + languageName: node + linkType: hard + +"dd-advanced-bot@workspace:.": + version: 0.0.0-use.local + resolution: "dd-advanced-bot@workspace:." + dependencies: + "@discordeno/bot": "npm:19.0.0-next.92bf166" + "@swc/cli": "npm:^0.3.12" + "@swc/core": "npm:^1.6.3" + "@types/node": "npm:^20.14.6" + dd-cache-proxy: "npm:^2.1.1" + dotenv: "npm:^16.4.5" + typescript: "npm:^5.5.2" + languageName: unknown + linkType: soft + +"dd-cache-proxy@npm:^2.1.1": + version: 2.1.1 + resolution: "dd-cache-proxy@npm:2.1.1" + peerDependencies: + "@discordeno/bot": 19.0.0-next.d69e537 + checksum: 082234277fd0dc91477b0ac4a938aea40b8d3ffa60e7e458ce570b2f4c919671ecd5b601f7ff6c6157a5e4e5eaa3786e6a1884cccb020a938cb76e4e300f0f72 + languageName: node + linkType: hard + +"debug@npm:4, debug@npm:^4.3.4": + version: 4.3.5 + resolution: "debug@npm:4.3.5" + dependencies: + ms: "npm:2.1.2" + peerDependenciesMeta: + supports-color: + optional: true + checksum: cb6eab424c410e07813ca1392888589972ce9a32b8829c6508f5e1f25f3c3e70a76731610ae55b4bbe58d1a2fffa1424b30e97fa8d394e49cd2656a9643aedd2 + languageName: node + linkType: hard + +"decompress-response@npm:^6.0.0": + version: 6.0.0 + resolution: "decompress-response@npm:6.0.0" + dependencies: + mimic-response: "npm:^3.1.0" + checksum: d377cf47e02d805e283866c3f50d3d21578b779731e8c5072d6ce8c13cc31493db1c2f6784da9d1d5250822120cefa44f1deab112d5981015f2e17444b763812 + languageName: node + linkType: hard + +"defer-to-connect@npm:^2.0.0": + version: 2.0.1 + resolution: "defer-to-connect@npm:2.0.1" + checksum: 8a9b50d2f25446c0bfefb55a48e90afd58f85b21bcf78e9207cd7b804354f6409032a1705c2491686e202e64fc05f147aa5aa45f9aa82627563f045937f5791b + languageName: node + linkType: hard + +"dotenv@npm:^16.4.5": + version: 16.4.5 + resolution: "dotenv@npm:16.4.5" + checksum: 55a3134601115194ae0f924e54473459ed0d9fc340ae610b676e248cca45aa7c680d86365318ea964e6da4e2ea80c4514c1adab5adb43d6867fb57ff068f95c8 + languageName: node + linkType: hard + +"eastasianwidth@npm:^0.2.0": + version: 0.2.0 + resolution: "eastasianwidth@npm:0.2.0" + checksum: 9b1d3e1baefeaf7d70799db8774149cef33b97183a6addceeba0cf6b85ba23ee2686f302f14482006df32df75d32b17c509c143a3689627929e4a8efaf483952 + languageName: node + linkType: hard + +"emoji-regex@npm:^8.0.0": + version: 8.0.0 + resolution: "emoji-regex@npm:8.0.0" + checksum: c72d67a6821be15ec11997877c437491c313d924306b8da5d87d2a2bcc2cec9903cb5b04ee1a088460501d8e5b44f10df82fdc93c444101a7610b80c8b6938e1 + languageName: node + linkType: hard + +"emoji-regex@npm:^9.2.2": + version: 9.2.2 + resolution: "emoji-regex@npm:9.2.2" + checksum: 915acf859cea7131dac1b2b5c9c8e35c4849e325a1d114c30adb8cd615970f6dca0e27f64f3a4949d7d6ed86ecd79a1c5c63f02e697513cddd7b5835c90948b8 + languageName: node + linkType: hard + +"encoding@npm:^0.1.13": + version: 0.1.13 + resolution: "encoding@npm:0.1.13" + dependencies: + iconv-lite: "npm:^0.6.2" + checksum: bb98632f8ffa823996e508ce6a58ffcf5856330fde839ae42c9e1f436cc3b5cc651d4aeae72222916545428e54fd0f6aa8862fd8d25bdbcc4589f1e3f3715e7f + languageName: node + linkType: hard + +"end-of-stream@npm:^1.1.0": + version: 1.4.4 + resolution: "end-of-stream@npm:1.4.4" + dependencies: + once: "npm:^1.4.0" + checksum: 530a5a5a1e517e962854a31693dbb5c0b2fc40b46dad2a56a2deec656ca040631124f4795823acc68238147805f8b021abbe221f4afed5ef3c8e8efc2024908b + languageName: node + linkType: hard + +"env-paths@npm:^2.2.0": + version: 2.2.1 + resolution: "env-paths@npm:2.2.1" + checksum: 65b5df55a8bab92229ab2b40dad3b387fad24613263d103a97f91c9fe43ceb21965cd3392b1ccb5d77088021e525c4e0481adb309625d0cb94ade1d1fb8dc17e + languageName: node + linkType: hard + +"err-code@npm:^2.0.2": + version: 2.0.3 + resolution: "err-code@npm:2.0.3" + checksum: 1d20d825cdcce8d811bfbe86340f4755c02655a7feb2f13f8c880566d9d72a3f6c92c192a6867632e490d6da67b678271f46e01044996a6443e870331100dfdd + languageName: node + linkType: hard + +"escape-string-regexp@npm:^5.0.0": + version: 5.0.0 + resolution: "escape-string-regexp@npm:5.0.0" + checksum: 20daabe197f3cb198ec28546deebcf24b3dbb1a5a269184381b3116d12f0532e06007f4bc8da25669d6a7f8efb68db0758df4cd981f57bc5b57f521a3e12c59e + languageName: node + linkType: hard + +"execa@npm:^0.7.0": + version: 0.7.0 + resolution: "execa@npm:0.7.0" + dependencies: + cross-spawn: "npm:^5.0.1" + get-stream: "npm:^3.0.0" + is-stream: "npm:^1.1.0" + npm-run-path: "npm:^2.0.0" + p-finally: "npm:^1.0.0" + signal-exit: "npm:^3.0.0" + strip-eof: "npm:^1.0.0" + checksum: 7c1721de38e51d67cef2367b1f6037c4a89bc64993d93683f9f740fc74d6930dfc92faf2749b917b7337a8d632d7b86a4673400f762bc1fe4a977ea6b0f9055f + languageName: node + linkType: hard + +"execa@npm:^5.0.0": + version: 5.1.1 + resolution: "execa@npm:5.1.1" + dependencies: + cross-spawn: "npm:^7.0.3" + get-stream: "npm:^6.0.0" + human-signals: "npm:^2.1.0" + is-stream: "npm:^2.0.0" + merge-stream: "npm:^2.0.0" + npm-run-path: "npm:^4.0.1" + onetime: "npm:^5.1.2" + signal-exit: "npm:^3.0.3" + strip-final-newline: "npm:^2.0.0" + checksum: 8ada91f2d70f7dff702c861c2c64f21dfdc1525628f3c0454fd6f02fce65f7b958616cbd2b99ca7fa4d474e461a3d363824e91b3eb881705231abbf387470597 + languageName: node + linkType: hard + +"executable@npm:^4.1.0": + version: 4.1.1 + resolution: "executable@npm:4.1.1" + dependencies: + pify: "npm:^2.2.0" + checksum: f01927ce59bccec804e171bf859a26e362c1f50aa9ebc69f7cafdcce3859d29d4b6267fd47237c18b0a1830614bd3f0ee14b7380d9bad18a4e7af9b5f0b6984f + languageName: node + linkType: hard + +"exponential-backoff@npm:^3.1.1": + version: 3.1.1 + resolution: "exponential-backoff@npm:3.1.1" + checksum: 2d9bbb6473de7051f96790d5f9a678f32e60ed0aa70741dc7fdc96fec8d631124ec3374ac144387604f05afff9500f31a1d45bd9eee4cdc2e4f9ad2d9b9d5dbd + languageName: node + linkType: hard + +"ext-list@npm:^2.0.0": + version: 2.2.2 + resolution: "ext-list@npm:2.2.2" + dependencies: + mime-db: "npm:^1.28.0" + checksum: fe69fedbef044e14d4ce9e84c6afceb696ba71500c15b8d0ce0a1e280237e17c95031b3d62d5e597652fea0065b9bf957346b3900d989dff59128222231ac859 + languageName: node + linkType: hard + +"ext-name@npm:^5.0.0": + version: 5.0.0 + resolution: "ext-name@npm:5.0.0" + dependencies: + ext-list: "npm:^2.0.0" + sort-keys-length: "npm:^1.0.0" + checksum: f598269bd5de4295540ea7d6f8f6a01d82a7508f148b7700a05628ef6121648d26e6e5e942049e953b3051863df6b54bd8fe951e7877f185e34ace5d44370b33 + languageName: node + linkType: hard + +"fast-glob@npm:^3.2.5": + version: 3.3.2 + resolution: "fast-glob@npm:3.3.2" + dependencies: + "@nodelib/fs.stat": "npm:^2.0.2" + "@nodelib/fs.walk": "npm:^1.2.3" + glob-parent: "npm:^5.1.2" + merge2: "npm:^1.3.0" + micromatch: "npm:^4.0.4" + checksum: 222512e9315a0efca1276af9adb2127f02105d7288fa746145bf45e2716383fb79eb983c89601a72a399a56b7c18d38ce70457c5466218c5f13fad957cee16df + languageName: node + linkType: hard + +"fastq@npm:^1.6.0": + version: 1.17.1 + resolution: "fastq@npm:1.17.1" + dependencies: + reusify: "npm:^1.0.4" + checksum: a443180068b527dd7b3a63dc7f2a47ceca2f3e97b9c00a1efe5538757e6cc4056a3526df94308075d7727561baf09ebaa5b67da8dcbddb913a021c5ae69d1f69 + languageName: node + linkType: hard + +"file-type@npm:^17.1.6": + version: 17.1.6 + resolution: "file-type@npm:17.1.6" + dependencies: + readable-web-to-node-stream: "npm:^3.0.2" + strtok3: "npm:^7.0.0-alpha.9" + token-types: "npm:^5.0.0-alpha.2" + checksum: 47c69b4046e31142492a135982b9a9e4873b368919a2e66d0ebdc04143b6d2e1225b4bec820668c442ef201b54d03569df08b6052edc6015b1022c236784e1c1 + languageName: node + linkType: hard + +"filename-reserved-regex@npm:^3.0.0": + version: 3.0.0 + resolution: "filename-reserved-regex@npm:3.0.0" + checksum: 1803e19ce64d7cb88ee5a1bd3ce282470a5c263987269222426d889049fc857e302284fa71937de9582eba7a9f39539557d45e0562f2fa51cade8efc68c65dd9 + languageName: node + linkType: hard + +"filenamify@npm:^5.0.2": + version: 5.1.1 + resolution: "filenamify@npm:5.1.1" + dependencies: + filename-reserved-regex: "npm:^3.0.0" + strip-outer: "npm:^2.0.0" + trim-repeated: "npm:^2.0.0" + checksum: 55a7ed0858eb2655bb1bb1e945a59e3fb30ba4767f6924fa064ccd731bff07678aac3cb4f3899ae0e1621fe81d6472b5688232bb6afd4eeb989ade785fc1c6f1 + languageName: node + linkType: hard + +"fill-range@npm:^7.1.1": + version: 7.1.1 + resolution: "fill-range@npm:7.1.1" + dependencies: + to-regex-range: "npm:^5.0.1" + checksum: a7095cb39e5bc32fada2aa7c7249d3f6b01bd1ce461a61b0adabacccabd9198500c6fb1f68a7c851a657e273fce2233ba869638897f3d7ed2e87a2d89b4436ea + languageName: node + linkType: hard + +"find-versions@npm:^5.0.0": + version: 5.1.0 + resolution: "find-versions@npm:5.1.0" + dependencies: + semver-regex: "npm:^4.0.5" + checksum: 680bdb0081f631f7bfb6f0f8edcfa0b74ab8cabc82097a4527a37b0d042aabc56685bf459ff27991eab0baddc04eb8e3bba8a2869f5004ecf7cdd2779b6e51de + languageName: node + linkType: hard + +"foreground-child@npm:^3.1.0": + version: 3.2.1 + resolution: "foreground-child@npm:3.2.1" + dependencies: + cross-spawn: "npm:^7.0.0" + signal-exit: "npm:^4.0.1" + checksum: 77b33b3c438a499201727ca84de39a66350ccd54a8805df712773e963cefb5c4632dbc4386109e97a0df8fb1585aee95fa35acb07587e3e04cfacabfc0ae15dc + languageName: node + linkType: hard + +"fs-minipass@npm:^2.0.0": + version: 2.1.0 + resolution: "fs-minipass@npm:2.1.0" + dependencies: + minipass: "npm:^3.0.0" + checksum: 03191781e94bc9a54bd376d3146f90fe8e082627c502185dbf7b9b3032f66b0b142c1115f3b2cc5936575fc1b44845ce903dd4c21bec2a8d69f3bd56f9cee9ec + languageName: node + linkType: hard + +"fs-minipass@npm:^3.0.0": + version: 3.0.3 + resolution: "fs-minipass@npm:3.0.3" + dependencies: + minipass: "npm:^7.0.3" + checksum: af143246cf6884fe26fa281621d45cfe111d34b30535a475bfa38dafe343dadb466c047a924ffc7d6b7b18265df4110224ce3803806dbb07173bf2087b648d7f + languageName: node + linkType: hard + +"get-stream@npm:^3.0.0": + version: 3.0.0 + resolution: "get-stream@npm:3.0.0" + checksum: de14fbb3b4548ace9ab6376be852eef9898c491282e29595bc908a1814a126d3961b11cd4b7be5220019fe3b2abb84568da7793ad308fc139925a217063fa159 + languageName: node + linkType: hard + +"get-stream@npm:^5.1.0": + version: 5.2.0 + resolution: "get-stream@npm:5.2.0" + dependencies: + pump: "npm:^3.0.0" + checksum: 13a73148dca795e41421013da6e3ebff8ccb7fba4d2f023fd0c6da2c166ec4e789bec9774a73a7b49c08daf2cae552f8a3e914042ac23b5f59dd278cc8f9cbfb + languageName: node + linkType: hard + +"get-stream@npm:^6.0.0": + version: 6.0.1 + resolution: "get-stream@npm:6.0.1" + checksum: 781266d29725f35c59f1d214aedc92b0ae855800a980800e2923b3fbc4e56b3cb6e462c42e09a1cf1a00c64e056a78fa407cbe06c7c92b7e5cd49b4b85c2a497 + languageName: node + linkType: hard + +"glob-parent@npm:^5.1.2": + version: 5.1.2 + resolution: "glob-parent@npm:5.1.2" + dependencies: + is-glob: "npm:^4.0.1" + checksum: 32cd106ce8c0d83731966d31517adb766d02c3812de49c30cfe0675c7c0ae6630c11214c54a5ae67aca882cf738d27fd7768f21aa19118b9245950554be07247 + languageName: node + linkType: hard + +"glob@npm:^10.2.2, glob@npm:^10.3.10": + version: 10.4.2 + resolution: "glob@npm:10.4.2" + dependencies: + foreground-child: "npm:^3.1.0" + jackspeak: "npm:^3.1.2" + minimatch: "npm:^9.0.4" + minipass: "npm:^7.1.2" + package-json-from-dist: "npm:^1.0.0" + path-scurry: "npm:^1.11.1" + bin: + glob: dist/esm/bin.mjs + checksum: e412776b5952a818eba790c830bea161c9a56813fd767d8c4c49f855603b1fb962b3e73f1f627a47298a57d2992b9f0f2fe15cf93e74ecaaa63fb45d63fdd090 + languageName: node + linkType: hard + +"got@npm:^11.8.5": + version: 11.8.6 + resolution: "got@npm:11.8.6" + dependencies: + "@sindresorhus/is": "npm:^4.0.0" + "@szmarczak/http-timer": "npm:^4.0.5" + "@types/cacheable-request": "npm:^6.0.1" + "@types/responselike": "npm:^1.0.0" + cacheable-lookup: "npm:^5.0.3" + cacheable-request: "npm:^7.0.2" + decompress-response: "npm:^6.0.0" + http2-wrapper: "npm:^1.0.0-beta.5.2" + lowercase-keys: "npm:^2.0.0" + p-cancelable: "npm:^2.0.0" + responselike: "npm:^2.0.0" + checksum: a30c74029d81bd5fe50dea1a0c970595d792c568e188ff8be254b5bc11e6158d1b014570772d4a30d0a97723e7dd34e7c8cc1a2f23018f60aece3070a7a5c2a5 + languageName: node + linkType: hard + +"graceful-fs@npm:^4.2.6": + version: 4.2.11 + resolution: "graceful-fs@npm:4.2.11" + checksum: bf152d0ed1dc159239db1ba1f74fdbc40cb02f626770dcd5815c427ce0688c2635a06ed69af364396da4636d0408fcf7d4afdf7881724c3307e46aff30ca49e2 + languageName: node + linkType: hard + +"http-cache-semantics@npm:^4.0.0, http-cache-semantics@npm:^4.1.1": + version: 4.1.1 + resolution: "http-cache-semantics@npm:4.1.1" + checksum: 362d5ed66b12ceb9c0a328fb31200b590ab1b02f4a254a697dc796850cc4385603e75f53ec59f768b2dad3bfa1464bd229f7de278d2899a0e3beffc634b6683f + languageName: node + linkType: hard + +"http-proxy-agent@npm:^7.0.0": + version: 7.0.2 + resolution: "http-proxy-agent@npm:7.0.2" + dependencies: + agent-base: "npm:^7.1.0" + debug: "npm:^4.3.4" + checksum: d062acfa0cb82beeb558f1043c6ba770ea892b5fb7b28654dbc70ea2aeea55226dd34c02a294f6c1ca179a5aa483c4ea641846821b182edbd9cc5d89b54c6848 + languageName: node + linkType: hard + +"http2-wrapper@npm:^1.0.0-beta.5.2": + version: 1.0.3 + resolution: "http2-wrapper@npm:1.0.3" + dependencies: + quick-lru: "npm:^5.1.1" + resolve-alpn: "npm:^1.0.0" + checksum: 8097ee2699440c2e64bda52124990cc5b0fb347401c7797b1a0c1efd5a0f79a4ebaa68e8a6ac3e2dde5f09460c1602764da6da2412bad628ed0a3b0ae35e72d4 + languageName: node + linkType: hard + +"https-proxy-agent@npm:^7.0.1": + version: 7.0.4 + resolution: "https-proxy-agent@npm:7.0.4" + dependencies: + agent-base: "npm:^7.0.2" + debug: "npm:4" + checksum: 405fe582bba461bfe5c7e2f8d752b384036854488b828ae6df6a587c654299cbb2c50df38c4b6ab303502c3c5e029a793fbaac965d1e86ee0be03faceb554d63 + languageName: node + linkType: hard + +"human-signals@npm:^2.1.0": + version: 2.1.0 + resolution: "human-signals@npm:2.1.0" + checksum: df59be9e0af479036798a881d1f136c4a29e0b518d4abb863afbd11bf30efa3eeb1d0425fc65942dcc05ab3bf40205ea436b0ff389f2cd20b75b8643d539bf86 + languageName: node + linkType: hard + +"iconv-lite@npm:^0.6.2": + version: 0.6.3 + resolution: "iconv-lite@npm:0.6.3" + dependencies: + safer-buffer: "npm:>= 2.1.2 < 3.0.0" + checksum: 24e3292dd3dadaa81d065c6f8c41b274a47098150d444b96e5f53b4638a9a71482921ea6a91a1f59bb71d9796de25e04afd05919fa64c360347ba65d3766f10f + languageName: node + linkType: hard + +"ieee754@npm:^1.2.1": + version: 1.2.1 + resolution: "ieee754@npm:1.2.1" + checksum: d9f2557a59036f16c282aaeb107832dc957a93d73397d89bbad4eb1130560560eb695060145e8e6b3b498b15ab95510226649a0b8f52ae06583575419fe10fc4 + languageName: node + linkType: hard + +"imurmurhash@npm:^0.1.4": + version: 0.1.4 + resolution: "imurmurhash@npm:0.1.4" + checksum: 2d30b157a91fe1c1d7c6f653cbf263f039be6c5bfa959245a16d4ee191fc0f2af86c08545b6e6beeb041c56b574d2d5b9f95343d378ab49c0f37394d541e7fc8 + languageName: node + linkType: hard + +"indent-string@npm:^4.0.0": + version: 4.0.0 + resolution: "indent-string@npm:4.0.0" + checksum: cd3f5cbc9ca2d624c6a1f53f12e6b341659aba0e2d3254ae2b4464aaea8b4294cdb09616abbc59458f980531f2429784ed6a420d48d245bcad0811980c9efae9 + languageName: node + linkType: hard + +"inherits@npm:^2.0.3": + version: 2.0.4 + resolution: "inherits@npm:2.0.4" + checksum: cd45e923bee15186c07fa4c89db0aace24824c482fb887b528304694b2aa6ff8a898da8657046a5dcf3e46cd6db6c61629551f9215f208d7c3f157cf9b290521 + languageName: node + linkType: hard + +"ip-address@npm:^9.0.5": + version: 9.0.5 + resolution: "ip-address@npm:9.0.5" + dependencies: + jsbn: "npm:1.1.0" + sprintf-js: "npm:^1.1.3" + checksum: 1ed81e06721af012306329b31f532b5e24e00cb537be18ddc905a84f19fe8f83a09a1699862bf3a1ec4b9dea93c55a3fa5faf8b5ea380431469df540f38b092c + languageName: node + linkType: hard + +"is-extglob@npm:^2.1.1": + version: 2.1.1 + resolution: "is-extglob@npm:2.1.1" + checksum: df033653d06d0eb567461e58a7a8c9f940bd8c22274b94bf7671ab36df5719791aae15eef6d83bbb5e23283967f2f984b8914559d4449efda578c775c4be6f85 + languageName: node + linkType: hard + +"is-fullwidth-code-point@npm:^3.0.0": + version: 3.0.0 + resolution: "is-fullwidth-code-point@npm:3.0.0" + checksum: 44a30c29457c7fb8f00297bce733f0a64cd22eca270f83e58c105e0d015e45c019491a4ab2faef91ab51d4738c670daff901c799f6a700e27f7314029e99e348 + languageName: node + linkType: hard + +"is-glob@npm:^4.0.1": + version: 4.0.3 + resolution: "is-glob@npm:4.0.3" + dependencies: + is-extglob: "npm:^2.1.1" + checksum: 3ed74f2b0cdf4f401f38edb0442ddfde3092d79d7d35c9919c86641efdbcbb32e45aa3c0f70ce5eecc946896cd5a0f26e4188b9f2b881876f7cb6c505b82da11 + languageName: node + linkType: hard + +"is-lambda@npm:^1.0.1": + version: 1.0.1 + resolution: "is-lambda@npm:1.0.1" + checksum: 93a32f01940220532e5948538699ad610d5924ac86093fcee83022252b363eb0cc99ba53ab084a04e4fb62bf7b5731f55496257a4c38adf87af9c4d352c71c35 + languageName: node + linkType: hard + +"is-number@npm:^7.0.0": + version: 7.0.0 + resolution: "is-number@npm:7.0.0" + checksum: 6a6c3383f68afa1e05b286af866017c78f1226d43ac8cb064e115ff9ed85eb33f5c4f7216c96a71e4dfea289ef52c5da3aef5bbfade8ffe47a0465d70c0c8e86 + languageName: node + linkType: hard + +"is-plain-obj@npm:^1.0.0": + version: 1.1.0 + resolution: "is-plain-obj@npm:1.1.0" + checksum: 0ee04807797aad50859652a7467481816cbb57e5cc97d813a7dcd8915da8195dc68c436010bf39d195226cde6a2d352f4b815f16f26b7bf486a5754290629931 + languageName: node + linkType: hard + +"is-stream@npm:^1.1.0": + version: 1.1.0 + resolution: "is-stream@npm:1.1.0" + checksum: 351aa77c543323c4e111204482808cfad68d2e940515949e31ccd0b010fc13d5fba4b9c230e4887fd24284713040f43e542332fbf172f6b9944b7d62e389c0ec + languageName: node + linkType: hard + +"is-stream@npm:^2.0.0": + version: 2.0.1 + resolution: "is-stream@npm:2.0.1" + checksum: b8e05ccdf96ac330ea83c12450304d4a591f9958c11fd17bed240af8d5ffe08aedafa4c0f4cfccd4d28dc9d4d129daca1023633d5c11601a6cbc77521f6fae66 + languageName: node + linkType: hard + +"isexe@npm:^2.0.0": + version: 2.0.0 + resolution: "isexe@npm:2.0.0" + checksum: 7c9f715c03aff08f35e98b1fadae1b9267b38f0615d501824f9743f3aab99ef10e303ce7db3f186763a0b70a19de5791ebfc854ff884d5a8c4d92211f642ec92 + languageName: node + linkType: hard + +"isexe@npm:^3.1.1": + version: 3.1.1 + resolution: "isexe@npm:3.1.1" + checksum: 7fe1931ee4e88eb5aa524cd3ceb8c882537bc3a81b02e438b240e47012eef49c86904d0f0e593ea7c3a9996d18d0f1f3be8d3eaa92333977b0c3a9d353d5563e + languageName: node + linkType: hard + +"jackspeak@npm:^3.1.2": + version: 3.4.0 + resolution: "jackspeak@npm:3.4.0" + dependencies: + "@isaacs/cliui": "npm:^8.0.2" + "@pkgjs/parseargs": "npm:^0.11.0" + dependenciesMeta: + "@pkgjs/parseargs": + optional: true + checksum: 5032c43c0c1fb92e72846ce496df559214253bc6870c90399cbd7858571c53169d9494b7c152df04abcb75f2fb5e9cffe65651c67d573380adf3a482b150d84b + languageName: node + linkType: hard + +"jsbn@npm:1.1.0": + version: 1.1.0 + resolution: "jsbn@npm:1.1.0" + checksum: bebe7ae829bbd586ce8cbe83501dd8cb8c282c8902a8aeeed0a073a89dc37e8103b1244f3c6acd60278bcbfe12d93a3f83c9ac396868a3b3bbc3c5e5e3b648ef + languageName: node + linkType: hard + +"json-buffer@npm:3.0.1": + version: 3.0.1 + resolution: "json-buffer@npm:3.0.1" + checksum: 82876154521b7b68ba71c4f969b91572d1beabadd87bd3a6b236f85fbc7dc4695089191ed60bb59f9340993c51b33d479f45b6ba9f3548beb519705281c32c3c + languageName: node + linkType: hard + +"keyv@npm:^4.0.0": + version: 4.5.4 + resolution: "keyv@npm:4.5.4" + dependencies: + json-buffer: "npm:3.0.1" + checksum: 167eb6ef64cc84b6fa0780ee50c9de456b422a1e18802209234f7c2cf7eae648c7741f32e50d7e24ccb22b24c13154070b01563d642755b156c357431a191e75 + languageName: node + linkType: hard + +"lowercase-keys@npm:^2.0.0": + version: 2.0.0 + resolution: "lowercase-keys@npm:2.0.0" + checksum: 1c233d2da35056e8c49fae8097ee061b8c799b2f02e33c2bf32f9913c7de8fb481ab04dab7df35e94156c800f5f34e99acbf32b21781d87c3aa43ef7b748b79e + languageName: node + linkType: hard + +"lru-cache@npm:^10.0.1, lru-cache@npm:^10.2.0": + version: 10.2.2 + resolution: "lru-cache@npm:10.2.2" + checksum: ff1a496d30b5eaec2c9079080965bb0cede203cf878371f7033a007f1e54cd4aa13cc8abf7ccec4c994a83a22ed5476e83a55bb57cc07e6c1547a42937e42c37 + languageName: node + linkType: hard + +"lru-cache@npm:^4.0.1": + version: 4.1.5 + resolution: "lru-cache@npm:4.1.5" + dependencies: + pseudomap: "npm:^1.0.2" + yallist: "npm:^2.1.2" + checksum: 9ec7d73f11a32cba0e80b7a58fdf29970814c0c795acaee1a6451ddfd609bae6ef9df0837f5bbeabb571ecd49c1e2d79e10e9b4ed422cfba17a0cb6145b018a9 + languageName: node + linkType: hard + +"make-fetch-happen@npm:^13.0.0": + version: 13.0.1 + resolution: "make-fetch-happen@npm:13.0.1" + dependencies: + "@npmcli/agent": "npm:^2.0.0" + cacache: "npm:^18.0.0" + http-cache-semantics: "npm:^4.1.1" + is-lambda: "npm:^1.0.1" + minipass: "npm:^7.0.2" + minipass-fetch: "npm:^3.0.0" + minipass-flush: "npm:^1.0.5" + minipass-pipeline: "npm:^1.2.4" + negotiator: "npm:^0.6.3" + proc-log: "npm:^4.2.0" + promise-retry: "npm:^2.0.1" + ssri: "npm:^10.0.0" + checksum: 11bae5ad6ac59b654dbd854f30782f9de052186c429dfce308eda42374528185a100ee40ac9ffdc36a2b6c821ecaba43913e4730a12f06f15e895ea9cb23fa59 + languageName: node + linkType: hard + +"merge-stream@npm:^2.0.0": + version: 2.0.0 + resolution: "merge-stream@npm:2.0.0" + checksum: 6fa4dcc8d86629705cea944a4b88ef4cb0e07656ebf223fa287443256414283dd25d91c1cd84c77987f2aec5927af1a9db6085757cb43d90eb170ebf4b47f4f4 + languageName: node + linkType: hard + +"merge2@npm:^1.3.0": + version: 1.4.1 + resolution: "merge2@npm:1.4.1" + checksum: 7268db63ed5169466540b6fb947aec313200bcf6d40c5ab722c22e242f651994619bcd85601602972d3c85bd2cc45a358a4c61937e9f11a061919a1da569b0c2 + languageName: node + linkType: hard + +"micromatch@npm:^4.0.4": + version: 4.0.7 + resolution: "micromatch@npm:4.0.7" + dependencies: + braces: "npm:^3.0.3" + picomatch: "npm:^2.3.1" + checksum: a11ed1cb67dcbbe9a5fc02c4062cf8bb0157d73bf86956003af8dcfdf9b287f9e15ec0f6d6925ff6b8b5b496202335e497b01de4d95ef6cf06411bc5e5c474a0 + languageName: node + linkType: hard + +"mime-db@npm:^1.28.0": + version: 1.52.0 + resolution: "mime-db@npm:1.52.0" + checksum: 54bb60bf39e6f8689f6622784e668a3d7f8bed6b0d886f5c3c446cb3284be28b30bf707ed05d0fe44a036f8469976b2629bbea182684977b084de9da274694d7 + languageName: node + linkType: hard + +"mimic-fn@npm:^2.1.0": + version: 2.1.0 + resolution: "mimic-fn@npm:2.1.0" + checksum: d2421a3444848ce7f84bd49115ddacff29c15745db73f54041edc906c14b131a38d05298dae3081667627a59b2eb1ca4b436ff2e1b80f69679522410418b478a + languageName: node + linkType: hard + +"mimic-response@npm:^1.0.0": + version: 1.0.1 + resolution: "mimic-response@npm:1.0.1" + checksum: 034c78753b0e622bc03c983663b1cdf66d03861050e0c8606563d149bc2b02d63f62ce4d32be4ab50d0553ae0ffe647fc34d1f5281184c6e1e8cf4d85e8d9823 + languageName: node + linkType: hard + +"mimic-response@npm:^3.1.0": + version: 3.1.0 + resolution: "mimic-response@npm:3.1.0" + checksum: 7e719047612411fe071332a7498cf0448bbe43c485c0d780046c76633a771b223ff49bd00267be122cedebb897037fdb527df72335d0d0f74724604ca70b37ad + languageName: node + linkType: hard + +"minimatch@npm:^9.0.3, minimatch@npm:^9.0.4": + version: 9.0.4 + resolution: "minimatch@npm:9.0.4" + dependencies: + brace-expansion: "npm:^2.0.1" + checksum: 4cdc18d112b164084513e890d6323370db14c22249d536ad1854539577a895e690a27513dc346392f61a4a50afbbd8abc88f3f25558bfbbbb862cd56508b20f5 + languageName: node + linkType: hard + +"minipass-collect@npm:^2.0.1": + version: 2.0.1 + resolution: "minipass-collect@npm:2.0.1" + dependencies: + minipass: "npm:^7.0.3" + checksum: b251bceea62090f67a6cced7a446a36f4cd61ee2d5cea9aee7fff79ba8030e416327a1c5aa2908dc22629d06214b46d88fdab8c51ac76bacbf5703851b5ad342 + languageName: node + linkType: hard + +"minipass-fetch@npm:^3.0.0": + version: 3.0.5 + resolution: "minipass-fetch@npm:3.0.5" + dependencies: + encoding: "npm:^0.1.13" + minipass: "npm:^7.0.3" + minipass-sized: "npm:^1.0.3" + minizlib: "npm:^2.1.2" + dependenciesMeta: + encoding: + optional: true + checksum: c669948bec1373313aaa8f104b962a3ced9f45c49b26366a4b0ae27ccdfa9c5740d72c8a84d3f8623d7a61c5fc7afdfda44789008c078f61a62441142efc4a97 + languageName: node + linkType: hard + +"minipass-flush@npm:^1.0.5": + version: 1.0.5 + resolution: "minipass-flush@npm:1.0.5" + dependencies: + minipass: "npm:^3.0.0" + checksum: 56269a0b22bad756a08a94b1ffc36b7c9c5de0735a4dd1ab2b06c066d795cfd1f0ac44a0fcae13eece5589b908ecddc867f04c745c7009be0b566421ea0944cf + languageName: node + linkType: hard + +"minipass-pipeline@npm:^1.2.4": + version: 1.2.4 + resolution: "minipass-pipeline@npm:1.2.4" + dependencies: + minipass: "npm:^3.0.0" + checksum: b14240dac0d29823c3d5911c286069e36d0b81173d7bdf07a7e4a91ecdef92cdff4baaf31ea3746f1c61e0957f652e641223970870e2353593f382112257971b + languageName: node + linkType: hard + +"minipass-sized@npm:^1.0.3": + version: 1.0.3 + resolution: "minipass-sized@npm:1.0.3" + dependencies: + minipass: "npm:^3.0.0" + checksum: 40982d8d836a52b0f37049a0a7e5d0f089637298e6d9b45df9c115d4f0520682a78258905e5c8b180fb41b593b0a82cc1361d2c74b45f7ada66334f84d1ecfdd + languageName: node + linkType: hard + +"minipass@npm:^3.0.0": + version: 3.3.6 + resolution: "minipass@npm:3.3.6" + dependencies: + yallist: "npm:^4.0.0" + checksum: a5c6ef069f70d9a524d3428af39f2b117ff8cd84172e19b754e7264a33df460873e6eb3d6e55758531580970de50ae950c496256bb4ad3691a2974cddff189f0 + languageName: node + linkType: hard + +"minipass@npm:^5.0.0": + version: 5.0.0 + resolution: "minipass@npm:5.0.0" + checksum: 61682162d29f45d3152b78b08bab7fb32ca10899bc5991ffe98afc18c9e9543bd1e3be94f8b8373ba6262497db63607079dc242ea62e43e7b2270837b7347c93 + languageName: node + linkType: hard + +"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.2, minipass@npm:^7.0.3, minipass@npm:^7.1.2": + version: 7.1.2 + resolution: "minipass@npm:7.1.2" + checksum: c25f0ee8196d8e6036661104bacd743785b2599a21de5c516b32b3fa2b83113ac89a2358465bc04956baab37ffb956ae43be679b2262bf7be15fce467ccd7950 + languageName: node + linkType: hard + +"minizlib@npm:^2.1.1, minizlib@npm:^2.1.2": + version: 2.1.2 + resolution: "minizlib@npm:2.1.2" + dependencies: + minipass: "npm:^3.0.0" + yallist: "npm:^4.0.0" + checksum: ae0f45436fb51344dcb87938446a32fbebb540d0e191d63b35e1c773d47512e17307bf54aa88326cc6d176594d00e4423563a091f7266c2f9a6872cdc1e234d1 + languageName: node + linkType: hard + +"mkdirp@npm:^1.0.3": + version: 1.0.4 + resolution: "mkdirp@npm:1.0.4" + bin: + mkdirp: bin/cmd.js + checksum: d71b8dcd4b5af2fe13ecf3bd24070263489404fe216488c5ba7e38ece1f54daf219e72a833a3a2dc404331e870e9f44963a33399589490956bff003a3404d3b2 + languageName: node + linkType: hard + +"ms@npm:2.1.2": + version: 2.1.2 + resolution: "ms@npm:2.1.2" + checksum: 673cdb2c3133eb050c745908d8ce632ed2c02d85640e2edb3ace856a2266a813b30c613569bf3354fdf4ea7d1a1494add3bfa95e2713baa27d0c2c71fc44f58f + languageName: node + linkType: hard + +"negotiator@npm:^0.6.3": + version: 0.6.3 + resolution: "negotiator@npm:0.6.3" + checksum: 2723fb822a17ad55c93a588a4bc44d53b22855bf4be5499916ca0cab1e7165409d0b288ba2577d7b029f10ce18cf2ed8e703e5af31c984e1e2304277ef979837 + languageName: node + linkType: hard + +"nice-napi@npm:^1.0.2": + version: 1.0.2 + resolution: "nice-napi@npm:1.0.2" + dependencies: + node-addon-api: "npm:^3.0.0" + node-gyp: "npm:latest" + node-gyp-build: "npm:^4.2.2" + conditions: "!os=win32" + languageName: node + linkType: hard + +"node-addon-api@npm:^3.0.0": + version: 3.2.1 + resolution: "node-addon-api@npm:3.2.1" + dependencies: + node-gyp: "npm:latest" + checksum: 681b52dfa3e15b0a8e5cf283cc0d8cd5fd2a57c559ae670fcfd20544cbb32f75de7648674110defcd17ab2c76ebef630aa7d2d2f930bc7a8cc439b20fe233518 + languageName: node + linkType: hard + +"node-gyp-build@npm:^4.2.2": + version: 4.8.1 + resolution: "node-gyp-build@npm:4.8.1" + bin: + node-gyp-build: bin.js + node-gyp-build-optional: optional.js + node-gyp-build-test: build-test.js + checksum: b9297770f96a92e5f2b854f3fd5e4bd418df81d7785a81ab60cec5cf2e5e72dc2c3319808978adc572cfa3885e6b12338cb5f4034bed2cab35f0d76a4b75ccdf + languageName: node + linkType: hard + +"node-gyp@npm:latest": + version: 10.1.0 + resolution: "node-gyp@npm:10.1.0" + dependencies: + env-paths: "npm:^2.2.0" + exponential-backoff: "npm:^3.1.1" + glob: "npm:^10.3.10" + graceful-fs: "npm:^4.2.6" + make-fetch-happen: "npm:^13.0.0" + nopt: "npm:^7.0.0" + proc-log: "npm:^3.0.0" + semver: "npm:^7.3.5" + tar: "npm:^6.1.2" + which: "npm:^4.0.0" + bin: + node-gyp: bin/node-gyp.js + checksum: 89e105e495e66cd4568af3cf79cdeb67d670eb069e33163c7781d3366470a30367c9bd8dea59e46db16370020139e5bf78b1fbc03284cb571754dfaa59744db5 + languageName: node + linkType: hard + +"nopt@npm:^7.0.0": + version: 7.2.1 + resolution: "nopt@npm:7.2.1" + dependencies: + abbrev: "npm:^2.0.0" + bin: + nopt: bin/nopt.js + checksum: 95a1f6dec8a81cd18cdc2fed93e6f0b4e02cf6bdb4501c848752c6e34f9883d9942f036a5e3b21a699047d8a448562d891e67492df68ec9c373e6198133337ae + languageName: node + linkType: hard + +"normalize-url@npm:^6.0.1": + version: 6.1.0 + resolution: "normalize-url@npm:6.1.0" + checksum: 5ae699402c9d5ffa330adc348fcd6fc6e6a155ab7c811b96e30b7ecab60ceef821d8f86443869671dda71bbc47f4b9625739c82ad247e883e9aefe875bfb8659 + languageName: node + linkType: hard + +"npm-run-path@npm:^2.0.0": + version: 2.0.2 + resolution: "npm-run-path@npm:2.0.2" + dependencies: + path-key: "npm:^2.0.0" + checksum: acd5ad81648ba4588ba5a8effb1d98d2b339d31be16826a118d50f182a134ac523172101b82eab1d01cb4c2ba358e857d54cfafd8163a1ffe7bd52100b741125 + languageName: node + linkType: hard + +"npm-run-path@npm:^4.0.1": + version: 4.0.1 + resolution: "npm-run-path@npm:4.0.1" + dependencies: + path-key: "npm:^3.0.0" + checksum: 5374c0cea4b0bbfdfae62da7bbdf1e1558d338335f4cacf2515c282ff358ff27b2ecb91ffa5330a8b14390ac66a1e146e10700440c1ab868208430f56b5f4d23 + languageName: node + linkType: hard + +"once@npm:^1.3.1, once@npm:^1.4.0": + version: 1.4.0 + resolution: "once@npm:1.4.0" + dependencies: + wrappy: "npm:1" + checksum: cd0a88501333edd640d95f0d2700fbde6bff20b3d4d9bdc521bdd31af0656b5706570d6c6afe532045a20bb8dc0849f8332d6f2a416e0ba6d3d3b98806c7db68 + languageName: node + linkType: hard + +"onetime@npm:^5.1.2": + version: 5.1.2 + resolution: "onetime@npm:5.1.2" + dependencies: + mimic-fn: "npm:^2.1.0" + checksum: e9fd0695a01cf226652f0385bf16b7a24153dbbb2039f764c8ba6d2306a8506b0e4ce570de6ad99c7a6eb49520743afdb66edd95ee979c1a342554ed49a9aadd + languageName: node + linkType: hard + +"os-filter-obj@npm:^2.0.0": + version: 2.0.0 + resolution: "os-filter-obj@npm:2.0.0" + dependencies: + arch: "npm:^2.1.0" + checksum: 08808a109b2dba9be8686cc006e082a0f6595e6d87e2a30e4147cb1d22b62a30a6e5f4fd78226aee76d9158c84db3cea292adec02e6591452e93cb33bf5da877 + languageName: node + linkType: hard + +"p-cancelable@npm:^2.0.0": + version: 2.1.1 + resolution: "p-cancelable@npm:2.1.1" + checksum: 7f1b64db17fc54acf359167d62898115dcf2a64bf6b3b038e4faf36fc059e5ed762fb9624df8ed04b25bee8de3ab8d72dea9879a2a960cd12e23c420a4aca6ed + languageName: node + linkType: hard + +"p-finally@npm:^1.0.0": + version: 1.0.0 + resolution: "p-finally@npm:1.0.0" + checksum: 93a654c53dc805dd5b5891bab16eb0ea46db8f66c4bfd99336ae929323b1af2b70a8b0654f8f1eae924b2b73d037031366d645f1fd18b3d30cbd15950cc4b1d4 + languageName: node + linkType: hard + +"p-map@npm:^4.0.0": + version: 4.0.0 + resolution: "p-map@npm:4.0.0" + dependencies: + aggregate-error: "npm:^3.0.0" + checksum: 7ba4a2b1e24c05e1fc14bbaea0fc6d85cf005ae7e9c9425d4575550f37e2e584b1af97bcde78eacd7559208f20995988d52881334db16cf77bc1bcf68e48ed7c + languageName: node + linkType: hard + +"package-json-from-dist@npm:^1.0.0": + version: 1.0.0 + resolution: "package-json-from-dist@npm:1.0.0" + checksum: ac706ec856a5a03f5261e4e48fa974f24feb044d51f84f8332e2af0af04fbdbdd5bbbfb9cbbe354190409bc8307c83a9e38c6672c3c8855f709afb0006a009ea + languageName: node + linkType: hard + +"path-key@npm:^2.0.0": + version: 2.0.1 + resolution: "path-key@npm:2.0.1" + checksum: 6e654864e34386a2a8e6bf72cf664dcabb76574dd54013add770b374384d438aca95f4357bb26935b514a4e4c2c9b19e191f2200b282422a76ee038b9258c5e7 + languageName: node + linkType: hard + +"path-key@npm:^3.0.0, path-key@npm:^3.1.0": + version: 3.1.1 + resolution: "path-key@npm:3.1.1" + checksum: 55cd7a9dd4b343412a8386a743f9c746ef196e57c823d90ca3ab917f90ab9f13dd0ded27252ba49dbdfcab2b091d998bc446f6220cd3cea65db407502a740020 + languageName: node + linkType: hard + +"path-scurry@npm:^1.11.1": + version: 1.11.1 + resolution: "path-scurry@npm:1.11.1" + dependencies: + lru-cache: "npm:^10.2.0" + minipass: "npm:^5.0.0 || ^6.0.2 || ^7.0.0" + checksum: 5e8845c159261adda6f09814d7725683257fcc85a18f329880ab4d7cc1d12830967eae5d5894e453f341710d5484b8fdbbd4d75181b4d6e1eb2f4dc7aeadc434 + languageName: node + linkType: hard + +"peek-readable@npm:^5.0.0": + version: 5.0.0 + resolution: "peek-readable@npm:5.0.0" + checksum: d342f02dd0c8a6b4bd0e7519a93d545b2b19375200e79a7431f0f1ec3f91e22b2217fa3a15cde95f6ab388ce6fce8aae75794d84b9b39c5836eb7c5f55e7ee9e + languageName: node + linkType: hard + +"picomatch@npm:^2.3.1": + version: 2.3.1 + resolution: "picomatch@npm:2.3.1" + checksum: 60c2595003b05e4535394d1da94850f5372c9427ca4413b71210f437f7b2ca091dbd611c45e8b37d10036fa8eade25c1b8951654f9d3973bfa66a2ff4d3b08bc + languageName: node + linkType: hard + +"pify@npm:^2.2.0": + version: 2.3.0 + resolution: "pify@npm:2.3.0" + checksum: 9503aaeaf4577acc58642ad1d25c45c6d90288596238fb68f82811c08104c800e5a7870398e9f015d82b44ecbcbef3dc3d4251a1cbb582f6e5959fe09884b2ba + languageName: node + linkType: hard + +"piscina@npm:^4.3.0": + version: 4.6.0 + resolution: "piscina@npm:4.6.0" + dependencies: + nice-napi: "npm:^1.0.2" + dependenciesMeta: + nice-napi: + optional: true + checksum: 2ffc0806f5b40bbe19b8384c5b07a8e2e15cae33eac508585ec127ed96a9459d363010376d5124b9de469c45290c739708a3d7e560a919b7e1b8a7db320bf355 + languageName: node + linkType: hard + +"proc-log@npm:^3.0.0": + version: 3.0.0 + resolution: "proc-log@npm:3.0.0" + checksum: 02b64e1b3919e63df06f836b98d3af002b5cd92655cab18b5746e37374bfb73e03b84fe305454614b34c25b485cc687a9eebdccf0242cda8fda2475dd2c97e02 + languageName: node + linkType: hard + +"proc-log@npm:^4.2.0": + version: 4.2.0 + resolution: "proc-log@npm:4.2.0" + checksum: 4e1394491b717f6c1ade15c570ecd4c2b681698474d3ae2d303c1e4b6ab9455bd5a81566211e82890d5a5ae9859718cc6954d5150bb18b09b72ecb297beae90a + languageName: node + linkType: hard + +"promise-retry@npm:^2.0.1": + version: 2.0.1 + resolution: "promise-retry@npm:2.0.1" + dependencies: + err-code: "npm:^2.0.2" + retry: "npm:^0.12.0" + checksum: 96e1a82453c6c96eef53a37a1d6134c9f2482f94068f98a59145d0986ca4e497bf110a410adf73857e588165eab3899f0ebcf7b3890c1b3ce802abc0d65967d4 + languageName: node + linkType: hard + +"pseudomap@npm:^1.0.2": + version: 1.0.2 + resolution: "pseudomap@npm:1.0.2" + checksum: 856c0aae0ff2ad60881168334448e898ad7a0e45fe7386d114b150084254c01e200c957cf378378025df4e052c7890c5bd933939b0e0d2ecfcc1dc2f0b2991f5 + languageName: node + linkType: hard + +"pump@npm:^3.0.0": + version: 3.0.0 + resolution: "pump@npm:3.0.0" + dependencies: + end-of-stream: "npm:^1.1.0" + once: "npm:^1.3.1" + checksum: e42e9229fba14732593a718b04cb5e1cfef8254544870997e0ecd9732b189a48e1256e4e5478148ecb47c8511dca2b09eae56b4d0aad8009e6fac8072923cfc9 + languageName: node + linkType: hard + +"queue-microtask@npm:^1.2.2": + version: 1.2.3 + resolution: "queue-microtask@npm:1.2.3" + checksum: 72900df0616e473e824202113c3df6abae59150dfb73ed13273503127235320e9c8ca4aaaaccfd58cf417c6ca92a6e68ee9a5c3182886ae949a768639b388a7b + languageName: node + linkType: hard + +"quick-lru@npm:^5.1.1": + version: 5.1.1 + resolution: "quick-lru@npm:5.1.1" + checksum: a516faa25574be7947969883e6068dbe4aa19e8ef8e8e0fd96cddd6d36485e9106d85c0041a27153286b0770b381328f4072aa40d3b18a19f5f7d2b78b94b5ed + languageName: node + linkType: hard + +"readable-stream@npm:^3.6.0": + version: 3.6.2 + resolution: "readable-stream@npm:3.6.2" + dependencies: + inherits: "npm:^2.0.3" + string_decoder: "npm:^1.1.1" + util-deprecate: "npm:^1.0.1" + checksum: d9e3e53193adcdb79d8f10f2a1f6989bd4389f5936c6f8b870e77570853561c362bee69feca2bbb7b32368ce96a85504aa4cedf7cf80f36e6a9de30d64244048 + languageName: node + linkType: hard + +"readable-web-to-node-stream@npm:^3.0.2": + version: 3.0.2 + resolution: "readable-web-to-node-stream@npm:3.0.2" + dependencies: + readable-stream: "npm:^3.6.0" + checksum: d3a5bf9d707c01183d546a64864aa63df4d9cb835dfd2bf89ac8305e17389feef2170c4c14415a10d38f9b9bfddf829a57aaef7c53c8b40f11d499844bf8f1a4 + languageName: node + linkType: hard + +"resolve-alpn@npm:^1.0.0": + version: 1.2.1 + resolution: "resolve-alpn@npm:1.2.1" + checksum: 744e87888f0b6fa0b256ab454ca0b9c0b80808715e2ef1f3672773665c92a941f6181194e30ccae4a8cd0adbe0d955d3f133102636d2ee0cca0119fec0bc9aec + languageName: node + linkType: hard + +"responselike@npm:^2.0.0": + version: 2.0.1 + resolution: "responselike@npm:2.0.1" + dependencies: + lowercase-keys: "npm:^2.0.0" + checksum: b122535466e9c97b55e69c7f18e2be0ce3823c5d47ee8de0d9c0b114aa55741c6db8bfbfce3766a94d1272e61bfb1ebf0a15e9310ac5629fbb7446a861b4fd3a + languageName: node + linkType: hard + +"retry@npm:^0.12.0": + version: 0.12.0 + resolution: "retry@npm:0.12.0" + checksum: 1f914879f97e7ee931ad05fe3afa629bd55270fc6cf1c1e589b6a99fab96d15daad0fa1a52a00c729ec0078045fe3e399bd4fd0c93bcc906957bdc17f89cb8e6 + languageName: node + linkType: hard + +"reusify@npm:^1.0.4": + version: 1.0.4 + resolution: "reusify@npm:1.0.4" + checksum: 14222c9e1d3f9ae01480c50d96057228a8524706db79cdeb5a2ce5bb7070dd9f409a6f84a02cbef8cdc80d39aef86f2dd03d155188a1300c599b05437dcd2ffb + languageName: node + linkType: hard + +"run-parallel@npm:^1.1.9": + version: 1.2.0 + resolution: "run-parallel@npm:1.2.0" + dependencies: + queue-microtask: "npm:^1.2.2" + checksum: cb4f97ad25a75ebc11a8ef4e33bb962f8af8516bb2001082ceabd8902e15b98f4b84b4f8a9b222e5d57fc3bd1379c483886ed4619367a7680dad65316993021d + languageName: node + linkType: hard + +"safe-buffer@npm:5.2.1, safe-buffer@npm:~5.2.0": + version: 5.2.1 + resolution: "safe-buffer@npm:5.2.1" + checksum: 32872cd0ff68a3ddade7a7617b8f4c2ae8764d8b7d884c651b74457967a9e0e886267d3ecc781220629c44a865167b61c375d2da6c720c840ecd73f45d5d9451 + languageName: node + linkType: hard + +"safer-buffer@npm:>= 2.1.2 < 3.0.0": + version: 2.1.2 + resolution: "safer-buffer@npm:2.1.2" + checksum: 7eaf7a0cf37cc27b42fb3ef6a9b1df6e93a1c6d98c6c6702b02fe262d5fcbd89db63320793b99b21cb5348097d0a53de81bd5f4e8b86e20cc9412e3f1cfb4e83 + languageName: node + linkType: hard + +"semver-regex@npm:^4.0.5": + version: 4.0.5 + resolution: "semver-regex@npm:4.0.5" + checksum: b9e5c0573c4a997fb7e6e76321385d254797e86c8dba5e23f3cd8cf8f40b40414097a51514e5fead61dcb88ff10d3676355c01e2040f3c68f6c24bfd2073da2e + languageName: node + linkType: hard + +"semver-truncate@npm:^3.0.0": + version: 3.0.0 + resolution: "semver-truncate@npm:3.0.0" + dependencies: + semver: "npm:^7.3.5" + checksum: d8c23812218ff147f512ac4830e86860a377dba8a9733ae97d816102aca33236fa1c44c06544727153fffb93d15d0e45c49b2c40a7964aa3671769e9aed2f3f9 + languageName: node + linkType: hard + +"semver@npm:^7.3.5, semver@npm:^7.3.8, semver@npm:^7.5.3": + version: 7.6.2 + resolution: "semver@npm:7.6.2" + bin: + semver: bin/semver.js + checksum: 296b17d027f57a87ef645e9c725bff4865a38dfc9caf29b26aa084b85820972fbe7372caea1ba6857162fa990702c6d9c1d82297cecb72d56c78ab29070d2ca2 + languageName: node + linkType: hard + +"shebang-command@npm:^1.2.0": + version: 1.2.0 + resolution: "shebang-command@npm:1.2.0" + dependencies: + shebang-regex: "npm:^1.0.0" + checksum: 9eed1750301e622961ba5d588af2212505e96770ec376a37ab678f965795e995ade7ed44910f5d3d3cb5e10165a1847f52d3348c64e146b8be922f7707958908 + languageName: node + linkType: hard + +"shebang-command@npm:^2.0.0": + version: 2.0.0 + resolution: "shebang-command@npm:2.0.0" + dependencies: + shebang-regex: "npm:^3.0.0" + checksum: 6b52fe87271c12968f6a054e60f6bde5f0f3d2db483a1e5c3e12d657c488a15474121a1d55cd958f6df026a54374ec38a4a963988c213b7570e1d51575cea7fa + languageName: node + linkType: hard + +"shebang-regex@npm:^1.0.0": + version: 1.0.0 + resolution: "shebang-regex@npm:1.0.0" + checksum: 404c5a752cd40f94591dfd9346da40a735a05139dac890ffc229afba610854d8799aaa52f87f7e0c94c5007f2c6af55bdcaeb584b56691926c5eaf41dc8f1372 + languageName: node + linkType: hard + +"shebang-regex@npm:^3.0.0": + version: 3.0.0 + resolution: "shebang-regex@npm:3.0.0" + checksum: 1a2bcae50de99034fcd92ad4212d8e01eedf52c7ec7830eedcf886622804fe36884278f2be8be0ea5fde3fd1c23911643a4e0f726c8685b61871c8908af01222 + languageName: node + linkType: hard + +"signal-exit@npm:^3.0.0, signal-exit@npm:^3.0.3": + version: 3.0.7 + resolution: "signal-exit@npm:3.0.7" + checksum: a2f098f247adc367dffc27845853e9959b9e88b01cb301658cfe4194352d8d2bb32e18467c786a7fe15f1d44b233ea35633d076d5e737870b7139949d1ab6318 + languageName: node + linkType: hard + +"signal-exit@npm:^4.0.1": + version: 4.1.0 + resolution: "signal-exit@npm:4.1.0" + checksum: c9fa63bbbd7431066174a48ba2dd9986dfd930c3a8b59de9c29d7b6854ec1c12a80d15310869ea5166d413b99f041bfa3dd80a7947bcd44ea8e6eb3ffeabfa1f + languageName: node + linkType: hard + +"slash@npm:3.0.0": + version: 3.0.0 + resolution: "slash@npm:3.0.0" + checksum: 94a93fff615f25a999ad4b83c9d5e257a7280c90a32a7cb8b4a87996e4babf322e469c42b7f649fd5796edd8687652f3fb452a86dc97a816f01113183393f11c + languageName: node + linkType: hard + +"smart-buffer@npm:^4.2.0": + version: 4.2.0 + resolution: "smart-buffer@npm:4.2.0" + checksum: 927484aa0b1640fd9473cee3e0a0bcad6fce93fd7bbc18bac9ad0c33686f5d2e2c422fba24b5899c184524af01e11dd2bd051c2bf2b07e47aff8ca72cbfc60d2 + languageName: node + linkType: hard + +"socks-proxy-agent@npm:^8.0.3": + version: 8.0.3 + resolution: "socks-proxy-agent@npm:8.0.3" + dependencies: + agent-base: "npm:^7.1.1" + debug: "npm:^4.3.4" + socks: "npm:^2.7.1" + checksum: c2112c66d6322e497d68e913c3780f3683237fd394bfd480b9283486a86e36095d0020db96145d88f8ccd9cc73261b98165b461f9c1bf5dc17abfe75c18029ce + languageName: node + linkType: hard + +"socks@npm:^2.7.1": + version: 2.8.3 + resolution: "socks@npm:2.8.3" + dependencies: + ip-address: "npm:^9.0.5" + smart-buffer: "npm:^4.2.0" + checksum: ffcb622c22481dfcd7589aae71fbfd71ca34334064d181df64bf8b7feaeee19706aba4cffd1de35cc7bbaeeaa0af96be2d7f40fcbc7bc0ab69533a7ae9ffc4fb + languageName: node + linkType: hard + +"sort-keys-length@npm:^1.0.0": + version: 1.0.1 + resolution: "sort-keys-length@npm:1.0.1" + dependencies: + sort-keys: "npm:^1.0.0" + checksum: f9acac5fb31580a9e3d43b419dc86a1b75e85b79036a084d95dd4d1062b621c9589906588ac31e370a0dd381be46d8dbe900efa306d087ca9c912d7a59b5a590 + languageName: node + linkType: hard + +"sort-keys@npm:^1.0.0": + version: 1.1.2 + resolution: "sort-keys@npm:1.1.2" + dependencies: + is-plain-obj: "npm:^1.0.0" + checksum: 0ac2ea2327d92252f07aa7b2f8c7023a1f6ce3306439a3e81638cce9905893c069521d168f530fb316d1a929bdb052b742969a378190afaef1bc64fa69e29576 + languageName: node + linkType: hard + +"source-map@npm:^0.7.3": + version: 0.7.4 + resolution: "source-map@npm:0.7.4" + checksum: a0f7c9b797eda93139842fd28648e868a9a03ea0ad0d9fa6602a0c1f17b7fb6a7dcca00c144476cccaeaae5042e99a285723b1a201e844ad67221bf5d428f1dc + languageName: node + linkType: hard + +"sprintf-js@npm:^1.1.3": + version: 1.1.3 + resolution: "sprintf-js@npm:1.1.3" + checksum: e7587128c423f7e43cc625fe2f87e6affdf5ca51c1cc468e910d8aaca46bb44a7fbcfa552f787b1d3987f7043aeb4527d1b99559e6621e01b42b3f45e5a24cbb + languageName: node + linkType: hard + +"ssri@npm:^10.0.0": + version: 10.0.6 + resolution: "ssri@npm:10.0.6" + dependencies: + minipass: "npm:^7.0.3" + checksum: f92c1b3cc9bfd0a925417412d07d999935917bc87049f43ebec41074661d64cf720315661844106a77da9f8204b6d55ae29f9514e673083cae39464343af2a8b + languageName: node + linkType: hard + +"string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^4.1.0": + version: 4.2.3 + resolution: "string-width@npm:4.2.3" + dependencies: + emoji-regex: "npm:^8.0.0" + is-fullwidth-code-point: "npm:^3.0.0" + strip-ansi: "npm:^6.0.1" + checksum: e52c10dc3fbfcd6c3a15f159f54a90024241d0f149cf8aed2982a2d801d2e64df0bf1dc351cf8e95c3319323f9f220c16e740b06faecd53e2462df1d2b5443fb + languageName: node + linkType: hard + +"string-width@npm:^5.0.1, string-width@npm:^5.1.2": + version: 5.1.2 + resolution: "string-width@npm:5.1.2" + dependencies: + eastasianwidth: "npm:^0.2.0" + emoji-regex: "npm:^9.2.2" + strip-ansi: "npm:^7.0.1" + checksum: 7369deaa29f21dda9a438686154b62c2c5f661f8dda60449088f9f980196f7908fc39fdd1803e3e01541970287cf5deae336798337e9319a7055af89dafa7193 + languageName: node + linkType: hard + +"string_decoder@npm:^1.1.1": + version: 1.3.0 + resolution: "string_decoder@npm:1.3.0" + dependencies: + safe-buffer: "npm:~5.2.0" + checksum: 54d23f4a6acae0e93f999a585e673be9e561b65cd4cca37714af1e893ab8cd8dfa52a9e4f58f48f87b4a44918d3a9254326cb80ed194bf2e4c226e2b21767e56 + languageName: node + linkType: hard + +"strip-ansi-cjs@npm:strip-ansi@^6.0.1, strip-ansi@npm:^6.0.0, strip-ansi@npm:^6.0.1": + version: 6.0.1 + resolution: "strip-ansi@npm:6.0.1" + dependencies: + ansi-regex: "npm:^5.0.1" + checksum: ae3b5436d34fadeb6096367626ce987057713c566e1e7768818797e00ac5d62023d0f198c4e681eae9e20701721980b26a64a8f5b91238869592a9c6800719a2 + languageName: node + linkType: hard + +"strip-ansi@npm:^7.0.1": + version: 7.1.0 + resolution: "strip-ansi@npm:7.1.0" + dependencies: + ansi-regex: "npm:^6.0.1" + checksum: 475f53e9c44375d6e72807284024ac5d668ee1d06010740dec0b9744f2ddf47de8d7151f80e5f6190fc8f384e802fdf9504b76a7e9020c9faee7103623338be2 + languageName: node + linkType: hard + +"strip-eof@npm:^1.0.0": + version: 1.0.0 + resolution: "strip-eof@npm:1.0.0" + checksum: 40bc8ddd7e072f8ba0c2d6d05267b4e0a4800898c3435b5fb5f5a21e6e47dfaff18467e7aa0d1844bb5d6274c3097246595841fbfeb317e541974ee992cac506 + languageName: node + linkType: hard + +"strip-final-newline@npm:^2.0.0": + version: 2.0.0 + resolution: "strip-final-newline@npm:2.0.0" + checksum: 69412b5e25731e1938184b5d489c32e340605bb611d6140344abc3421b7f3c6f9984b21dff296dfcf056681b82caa3bb4cc996a965ce37bcfad663e92eae9c64 + languageName: node + linkType: hard + +"strip-outer@npm:^2.0.0": + version: 2.0.0 + resolution: "strip-outer@npm:2.0.0" + checksum: 14ef9fe861e59a5f1555f1860982ae4edce2edb4ed34ab1b37cb62a8ba2f7c3540cbca6c884eabe4006e6cd729ab5d708a631169dd5b66fda570836e7e3b6589 + languageName: node + linkType: hard + +"strtok3@npm:^7.0.0-alpha.9": + version: 7.0.0 + resolution: "strtok3@npm:7.0.0" + dependencies: + "@tokenizer/token": "npm:^0.3.0" + peek-readable: "npm:^5.0.0" + checksum: 4f2269679fcfce1e9fe0600eff361ea4c687ae0a0e8d9dab6703811071cd92545cbcb32d4ace3d3aa591f777cec1a3e8aeecd5efd71ae216fd2962a7a238b4ab + languageName: node + linkType: hard + +"tar@npm:^6.1.11, tar@npm:^6.1.2": + version: 6.2.1 + resolution: "tar@npm:6.2.1" + dependencies: + chownr: "npm:^2.0.0" + fs-minipass: "npm:^2.0.0" + minipass: "npm:^5.0.0" + minizlib: "npm:^2.1.1" + mkdirp: "npm:^1.0.3" + yallist: "npm:^4.0.0" + checksum: bfbfbb2861888077fc1130b84029cdc2721efb93d1d1fb80f22a7ac3a98ec6f8972f29e564103bbebf5e97be67ebc356d37fa48dbc4960600a1eb7230fbd1ea0 + languageName: node + linkType: hard + +"to-regex-range@npm:^5.0.1": + version: 5.0.1 + resolution: "to-regex-range@npm:5.0.1" + dependencies: + is-number: "npm:^7.0.0" + checksum: 10dda13571e1f5ad37546827e9b6d4252d2e0bc176c24a101252153ef435d83696e2557fe128c4678e4e78f5f01e83711c703eef9814eb12dab028580d45980a + languageName: node + linkType: hard + +"token-types@npm:^5.0.0-alpha.2": + version: 5.0.1 + resolution: "token-types@npm:5.0.1" + dependencies: + "@tokenizer/token": "npm:^0.3.0" + ieee754: "npm:^1.2.1" + checksum: 0985369bbea9f53a5ccd79bb9899717b41401a813deb2c7fb1add5d0baf2f702aaf6da78f6e0ccf346d5a9f7acaa7cb5efed7d092d89d8c1e6962959e9509bc0 + languageName: node + linkType: hard + +"trim-repeated@npm:^2.0.0": + version: 2.0.0 + resolution: "trim-repeated@npm:2.0.0" + dependencies: + escape-string-regexp: "npm:^5.0.0" + checksum: 4086eb0bc560f3da0370f427f423db4e3fc0a8e1560ecffc3b68512071319fe82dc9dd86d76b981d36ada76d7d49c3f8897ac054c87bc177e7a25abfd29e2bcd + languageName: node + linkType: hard + +"tweetnacl@npm:^1.0.3": + version: 1.0.3 + resolution: "tweetnacl@npm:1.0.3" + checksum: ca122c2f86631f3c0f6d28efb44af2a301d4a557a62a3e2460286b08e97567b258c2212e4ad1cfa22bd6a57edcdc54ba76ebe946847450ab0999e6d48ccae332 + languageName: node + linkType: hard + +"typescript@npm:^5.5.2": + version: 5.5.2 + resolution: "typescript@npm:5.5.2" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 9118b20f248e76b0dbff8737fef65dfa89d02668d4e633d2c5ceac99033a0ca5e8a1c1a53bc94da68e8f67677a88f318663dde859c9e9a09c1e116415daec2ba + languageName: node + linkType: hard + +"typescript@patch:typescript@npm%3A^5.5.2#optional!builtin": + version: 5.5.2 + resolution: "typescript@patch:typescript@npm%3A5.5.2#optional!builtin::version=5.5.2&hash=e012d7" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 28b3de2ddaf63a7620e7ddbe5d377af71ce93ecc558c41bf0e3d88661d8e6e7aa6c7739164fef98055f69819e41faca49252938ef3633a3dff2734cca6a9042e + languageName: node + linkType: hard + +"undici-types@npm:~5.26.4": + version: 5.26.5 + resolution: "undici-types@npm:5.26.5" + checksum: 0097779d94bc0fd26f0418b3a05472410408877279141ded2bd449167be1aed7ea5b76f756562cb3586a07f251b90799bab22d9019ceba49c037c76445f7cddd + languageName: node + linkType: hard + +"unique-filename@npm:^3.0.0": + version: 3.0.0 + resolution: "unique-filename@npm:3.0.0" + dependencies: + unique-slug: "npm:^4.0.0" + checksum: 8e2f59b356cb2e54aab14ff98a51ac6c45781d15ceaab6d4f1c2228b780193dc70fae4463ce9e1df4479cb9d3304d7c2043a3fb905bdeca71cc7e8ce27e063df + languageName: node + linkType: hard + +"unique-slug@npm:^4.0.0": + version: 4.0.0 + resolution: "unique-slug@npm:4.0.0" + dependencies: + imurmurhash: "npm:^0.1.4" + checksum: 40912a8963fc02fb8b600cf50197df4a275c602c60de4cac4f75879d3c48558cfac48de08a25cc10df8112161f7180b3bbb4d662aadb711568602f9eddee54f0 + languageName: node + linkType: hard + +"util-deprecate@npm:^1.0.1": + version: 1.0.2 + resolution: "util-deprecate@npm:1.0.2" + checksum: 474acf1146cb2701fe3b074892217553dfcf9a031280919ba1b8d651a068c9b15d863b7303cb15bd00a862b498e6cf4ad7b4a08fb134edd5a6f7641681cb54a2 + languageName: node + linkType: hard + +"which@npm:^1.2.9": + version: 1.3.1 + resolution: "which@npm:1.3.1" + dependencies: + isexe: "npm:^2.0.0" + bin: + which: ./bin/which + checksum: 549dcf1752f3ee7fbb64f5af2eead4b9a2f482108b7de3e85c781d6c26d8cf6a52d37cfbe0642a155fa6470483fe892661a859c03157f24c669cf115f3bbab5e + languageName: node + linkType: hard + +"which@npm:^2.0.1": + version: 2.0.2 + resolution: "which@npm:2.0.2" + dependencies: + isexe: "npm:^2.0.0" + bin: + node-which: ./bin/node-which + checksum: 4782f8a1d6b8fc12c65e968fea49f59752bf6302dc43036c3bf87da718a80710f61a062516e9764c70008b487929a73546125570acea95c5b5dcc8ac3052c70f + languageName: node + linkType: hard + +"which@npm:^4.0.0": + version: 4.0.0 + resolution: "which@npm:4.0.0" + dependencies: + isexe: "npm:^3.1.1" + bin: + node-which: bin/which.js + checksum: f17e84c042592c21e23c8195108cff18c64050b9efb8459589116999ea9da6dd1509e6a1bac3aeebefd137be00fabbb61b5c2bc0aa0f8526f32b58ee2f545651 + languageName: node + linkType: hard + +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": + version: 7.0.0 + resolution: "wrap-ansi@npm:7.0.0" + dependencies: + ansi-styles: "npm:^4.0.0" + string-width: "npm:^4.1.0" + strip-ansi: "npm:^6.0.0" + checksum: cebdaeca3a6880da410f75209e68cd05428580de5ad24535f22696d7d9cab134d1f8498599f344c3cf0fb37c1715807a183778d8c648d6cc0cb5ff2bb4236540 + languageName: node + linkType: hard + +"wrap-ansi@npm:^8.1.0": + version: 8.1.0 + resolution: "wrap-ansi@npm:8.1.0" + dependencies: + ansi-styles: "npm:^6.1.0" + string-width: "npm:^5.0.1" + strip-ansi: "npm:^7.0.1" + checksum: 7b1e4b35e9bb2312d2ee9ee7dc95b8cb5f8b4b5a89f7dde5543fe66c1e3715663094defa50d75454ac900bd210f702d575f15f3f17fa9ec0291806d2578d1ddf + languageName: node + linkType: hard + +"wrappy@npm:1": + version: 1.0.2 + resolution: "wrappy@npm:1.0.2" + checksum: 159da4805f7e84a3d003d8841557196034155008f817172d4e986bd591f74aa82aa7db55929a54222309e01079a65a92a9e6414da5a6aa4b01ee44a511ac3ee5 + languageName: node + linkType: hard + +"ws@npm:^8.16.0": + version: 8.17.1 + resolution: "ws@npm:8.17.1" + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ">=5.0.2" + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: 4264ae92c0b3e59c7e309001e93079b26937aab181835fb7af79f906b22cd33b6196d96556dafb4e985742dd401e99139572242e9847661fdbc96556b9e6902d + languageName: node + linkType: hard + +"yallist@npm:^2.1.2": + version: 2.1.2 + resolution: "yallist@npm:2.1.2" + checksum: 75fc7bee4821f52d1c6e6021b91b3e079276f1a9ce0ad58da3c76b79a7e47d6f276d35e206a96ac16c1cf48daee38a8bb3af0b1522a3d11c8ffe18f898828832 + languageName: node + linkType: hard + +"yallist@npm:^4.0.0": + version: 4.0.0 + resolution: "yallist@npm:4.0.0" + checksum: 4cb02b42b8a93b5cf50caf5d8e9beb409400a8a4d85e83bb0685c1457e9ac0b7a00819e9f5991ac25ffabb56a78e2f017c1acc010b3a1babfe6de690ba531abd + languageName: node + linkType: hard diff --git a/examples/beginner/.env.example b/examples/beginner/.env.example index 7acf6fd79..522003cc8 100644 --- a/examples/beginner/.env.example +++ b/examples/beginner/.env.example @@ -1,2 +1 @@ BOT_TOKEN='' -DEV_GUILD_ID='' \ No newline at end of file diff --git a/examples/beginner/.gitignore b/examples/beginner/.gitignore new file mode 100644 index 000000000..4bc2fcfaf --- /dev/null +++ b/examples/beginner/.gitignore @@ -0,0 +1,32 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +node_modules + +.pnp.* +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/sdks +!.yarn/versions + +# build +dist + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.pnpm-debug.log* + +# local env files +.env +.env.local +.env.development.local +.env.test.local +.env.production.local diff --git a/examples/beginner/.swcrc b/examples/beginner/.swcrc new file mode 100644 index 000000000..751b8edf8 --- /dev/null +++ b/examples/beginner/.swcrc @@ -0,0 +1,24 @@ +{ + "$schema": "https://json.schemastore.org/swcrc", + "jsc": { + "parser": { + "syntax": "typescript", + "decorators": true, + "dynamicImport": true + }, + "transform": { + "legacyDecorator": true, + "decoratorMetadata": true + }, + "target": "es2022", + "keepClassNames": true, + "loose": true + }, + "module": { + "type": "es6", + "strict": false, + "strictMode": true, + "lazy": false, + "noInterop": false + } +} diff --git a/examples/beginner/README.md b/examples/beginner/README.md index 1b47675a8..e1aea42b5 100644 --- a/examples/beginner/README.md +++ b/examples/beginner/README.md @@ -1,18 +1,20 @@ # Beginner Bot Template -This template is designed for the beginner developer to start coding discord bots. +This template is designed for beginners to start coding discord bots. -Make sure to install the latest version when you use it. +This template includes caching (using `dd-cache-proxy`) and support for slash subcommands. +This template also includes a /ping command to show the bot latency ## Setup -- [Click here](https://github.com/discordeno/template/generate) to make your own copy. -- Delete all the template folders except the beginner folder. -- Move all files from this folder to the root of the project. - - You may encounter an issue with README.md file but force move the files to the root of the project. -- Rename the .env.example file to .env OR create a new .env file and copy the example file code to this new file. +- Download the source +- Install the dependencies using `yarn` +- Copy the .env.example file and rename it to .env - Fill out the .env file ## Run Bot -- deno run -A mod.ts +- run `yarn` to install the dependencies +- run `yarn build` to build the source +- run `node dist/register-commands.js` to register the slash commands +- run `yarn start` to run the bot diff --git a/examples/beginner/bot.ts b/examples/beginner/bot.ts deleted file mode 100644 index 444693eda..000000000 --- a/examples/beginner/bot.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { configs } from './configs.ts.js' -import type { BotWithCache, BotWithHelpersPlugin } from './deps.ts.js' -import { - Collection, - createBot, - enableCachePlugin, - enableCacheSweepers, - enableHelpersPlugin, - enablePermissionsPlugin, - GatewayIntents, -} from './deps.ts.js' -import type { Command } from './src/types/commands.ts.js' - -// MAKE THE BASIC BOT OBJECT -const bot = createBot({ - token: configs.token, - botId: configs.botId, - intents: GatewayIntents.Guilds, - events: {}, -}) - -// ENABLE ALL THE PLUGINS THAT WILL HELP MAKE IT EASIER TO CODE YOUR BOT -enableHelpersPlugin(bot) -enableCachePlugin(bot) -enableCacheSweepers(bot as BotWithCache) -enablePermissionsPlugin(bot as BotWithCache) - -export interface BotClient extends BotWithCache { - commands: Collection -} - -// THIS IS THE BOT YOU WANT TO USE EVERYWHERE IN YOUR CODE! IT HAS EVERYTHING BUILT INTO IT! -export const Bot = bot as BotClient -// PREPARE COMMANDS HOLDER -Bot.commands = new Collection() diff --git a/examples/beginner/configs.ts b/examples/beginner/configs.ts deleted file mode 100644 index 536e902a0..000000000 --- a/examples/beginner/configs.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { dotEnvConfig } from './deps.ts.js' - -// Get the .env file that the user should have created, and get the token -const env = dotEnvConfig({ export: true, path: './.env' }) -const token = env.BOT_TOKEN || '' - -export interface Config { - token: string - botId: bigint -} - -export const configs = { - /** Get token from ENV variable */ - token, - /** Get the BotId from the token */ - botId: BigInt(atob(token.split('.')[0])), - /** The server id where you develop your bot and want dev commands created. */ - devGuildId: BigInt(env.DEV_GUILD_ID!), -} diff --git a/examples/beginner/deps.ts b/examples/beginner/deps.ts deleted file mode 100644 index 9cf710fa8..000000000 --- a/examples/beginner/deps.ts +++ /dev/null @@ -1,9 +0,0 @@ -export * from 'https://deno.land/x/discordeno@17.0.0/mod.ts' -export * from 'https://deno.land/x/discordeno@17.0.0/plugins/mod.ts' - -// Terminal Colors! -export * from 'https://deno.land/std@0.117.0/fmt/colors.ts' -// Get data from .env files -export { config as dotEnvConfig } from 'https://deno.land/x/dotenv@v3.1.0/mod.ts' -// Database, thx Tri! -export { decode as KwikDecode, encode as KwikEncode, Kwik } from 'https://deno.land/x/kwik@v1.3.1/mod.ts' diff --git a/examples/beginner/mod.ts b/examples/beginner/mod.ts deleted file mode 100644 index 97b1dbdfd..000000000 --- a/examples/beginner/mod.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { startBot } from './deps.ts.js' -import log from './src/utils/logger.ts.js' -import { fileLoader, importDirectory } from './src/utils/loader.ts.js' -import { updateApplicationCommands } from './src/utils/updateCommands.ts.js' -// setup db -import './src/database/mod.ts.js' -import { Bot } from './bot.ts.js' - -log.info('Starting bot...') - -// Forces deno to read all the files which will fill the commands/inhibitors cache etc. -await Promise.all( - [ - './src/commands', - './src/events', - // "./src/tasks", - ].map((path) => importDirectory(Deno.realPathSync(path))), -) -await fileLoader() - -// UPDATES YOUR COMMANDS TO LATEST COMMANDS -await updateApplicationCommands() - -// STARTS THE CONNECTION TO DISCORD -await startBot(Bot) diff --git a/examples/beginner/package.json b/examples/beginner/package.json new file mode 100644 index 000000000..b9bff5023 --- /dev/null +++ b/examples/beginner/package.json @@ -0,0 +1,27 @@ +{ + "name": "dd-beginner-bot", + "version": "1.0.0", + "description": "An example bot for beginner developers to start coding discord bots.", + "main": "dist/index.js", + "type": "module", + "license": "ISC", + "private": true, + "packageManager": "yarn@4.0.2", + "scripts": { + "start": "node dist/index.js", + "build": "swc src --strip-leading-paths --delete-dir-on-start --out-dir dist", + "setup-dd": "" + }, + "dependencies": { + "@discordeno/bot": "19.0.0-next.92bf166", + "chalk": "^5.3.0", + "dd-cache-proxy": "^2.1.1", + "dotenv": "^16.4.5" + }, + "devDependencies": { + "@swc/cli": "^0.3.12", + "@swc/core": "^1.6.3", + "@types/node": "^20.14.6", + "typescript": "^5.5.2" + } +} diff --git a/examples/beginner/src/bot.ts b/examples/beginner/src/bot.ts new file mode 100644 index 000000000..e2602b3b5 --- /dev/null +++ b/examples/beginner/src/bot.ts @@ -0,0 +1,32 @@ +import { Intents, createBot } from '@discordeno/bot' +import { createProxyCache } from 'dd-cache-proxy' +import { configs } from './config.js' + +export const bot = createProxyCache( + createBot({ + token: configs.token, + intents: Intents.Guilds, + }), + { + desiredProps: { + guilds: ['id', 'name'], + }, + cacheInMemory: { + guilds: true, + default: false, + }, + }, +) + +// Setup desired proprieties +bot.transformers.desiredProperties.interaction.id = true +bot.transformers.desiredProperties.interaction.type = true +bot.transformers.desiredProperties.interaction.data = true +bot.transformers.desiredProperties.interaction.user = true +bot.transformers.desiredProperties.interaction.token = true +bot.transformers.desiredProperties.interaction.guildId = true + +bot.transformers.desiredProperties.guild.id = true +bot.transformers.desiredProperties.guild.name = true + +bot.transformers.desiredProperties.user.username = true diff --git a/examples/beginner/src/commands.ts b/examples/beginner/src/commands.ts new file mode 100644 index 000000000..895b36a88 --- /dev/null +++ b/examples/beginner/src/commands.ts @@ -0,0 +1,26 @@ +import { Collection, type ApplicationCommandOption, type ApplicationCommandTypes, type Interaction } from '@discordeno/bot' + +export const commands = new Collection() + +export function createCommand(command: Command): void { + commands.set(command.name, command) +} + +export interface Command { + name: string + description: string + usage?: string[] + options?: ApplicationCommandOption[] + type: ApplicationCommandTypes + /** Defaults to `Guild` */ + scope?: 'Global' | 'Guild' + execute: (interaction: Interaction) => unknown + subcommands?: Array +} + +export type SubCommand = Omit + +export interface SubCommandGroup { + name: string + subCommands: SubCommand[] +} diff --git a/examples/beginner/src/commands/mod.ts b/examples/beginner/src/commands/mod.ts deleted file mode 100644 index 27bbef957..000000000 --- a/examples/beginner/src/commands/mod.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { Bot } from '../../bot.ts.js' -import type { Command } from '../types/commands.ts.js' - -export function createCommand(command: Command) { - Bot.commands.set(command.name, command) -} diff --git a/examples/beginner/src/commands/ping.ts b/examples/beginner/src/commands/ping.ts index 1922edcf4..436fab402 100644 --- a/examples/beginner/src/commands/ping.ts +++ b/examples/beginner/src/commands/ping.ts @@ -1,18 +1,15 @@ -import { ApplicationCommandTypes, InteractionResponseTypes } from '../../deps.ts.js' -import { snowflakeToTimestamp } from '../utils/helpers.ts.js' -import { createCommand } from './mod.ts.js' +import { ApplicationCommandTypes, snowflakeToTimestamp } from '@discordeno/bot' +import { createCommand } from '../commands.js' +import { humanizeMilliseconds } from '../utils/helpers.js' createCommand({ name: 'ping', description: 'Ping the Bot!', type: ApplicationCommandTypes.ChatInput, - execute: async (Bot, interaction) => { + scope: 'Global', + async execute(interaction) { const ping = Date.now() - snowflakeToTimestamp(interaction.id) - await Bot.helpers.sendInteractionResponse(interaction.id, interaction.token, { - type: InteractionResponseTypes.ChannelMessageWithSource, - data: { - content: `🏓 Pong! ${ping}ms`, - }, - }) + + await interaction.respond(`🏓 Pong! Ping ${ping}ms (${humanizeMilliseconds(ping)})`) }, }) diff --git a/examples/beginner/src/config.ts b/examples/beginner/src/config.ts new file mode 100644 index 000000000..a196faa4d --- /dev/null +++ b/examples/beginner/src/config.ts @@ -0,0 +1,12 @@ +const token = process.env.BOT_TOKEN + +if (!token) throw new Error('Missing BOT_TOKEN environment variable') + +export const configs: Config = { + /** Get token from ENV variable */ + token, +} + +export interface Config { + token: string +} diff --git a/examples/beginner/src/database/mod.ts b/examples/beginner/src/database/mod.ts deleted file mode 100644 index 434328763..000000000 --- a/examples/beginner/src/database/mod.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Kwik, KwikDecode, KwikEncode } from '../../deps.ts.js' -import { logger } from '../utils/logger.ts.js' - -const log = logger({ name: 'DB Manager' }) - -log.info('Initializing Database') - -const kwik = new Kwik() - -// Add BigInt Support -kwik.msgpackExtensionCodec.register({ - type: 0, - encode: (object: unknown): Uint8Array | null => { - if (typeof object === 'bigint') { - if (object <= Number.MAX_SAFE_INTEGER && object >= Number.MIN_SAFE_INTEGER) { - return KwikEncode(parseInt(object.toString(), 10), {}) - } else { - return KwikEncode(object.toString(), {}) - } - } else { - return null - } - }, - decode: (data: Uint8Array) => { - return BigInt(KwikDecode(data, {}) as string) - }, -}) - -// Initialize the Database -await kwik.init() - -log.info('Database Initialized!') diff --git a/examples/beginner/src/events/guildCreate.ts b/examples/beginner/src/events/guildCreate.ts new file mode 100644 index 000000000..5e5692d31 --- /dev/null +++ b/examples/beginner/src/events/guildCreate.ts @@ -0,0 +1,4 @@ +import { bot } from '../bot.js' +import { updateGuildCommands } from '../utils/helpers.js' + +bot.events.guildCreate = async (guild) => await updateGuildCommands(bot, guild) diff --git a/examples/beginner/src/events/interactionCreate.ts b/examples/beginner/src/events/interactionCreate.ts index 178680dff..4bb1c24f8 100644 --- a/examples/beginner/src/events/interactionCreate.ts +++ b/examples/beginner/src/events/interactionCreate.ts @@ -1,14 +1,94 @@ -import { Bot } from '../../bot.ts.js' -import { InteractionTypes } from '../../deps.ts.js' -import log from '../utils/logger.ts.js' +import { ApplicationCommandOptionTypes, hasProperty, type Guild } from '@discordeno/bot' +import chalk from 'chalk' +import { bot } from '../bot.js' +import { commands } from '../commands.js' +import { getGuildFromId, isSubCommand, isSubCommandGroup } from '../utils/helpers.js' +import { createLogger } from '../utils/logger.js' -Bot.events.interactionCreate = (_, interaction) => { - if (!interaction.data) return +const logger = createLogger({ name: 'Event: InteractionCreate' }) - switch (interaction.type) { - case InteractionTypes.ApplicationCommand: - log.info(`[Application Command] ${interaction.data.name} command executed.`) - Bot.commands.get(interaction.data.name!)?.execute(Bot, interaction) - break +bot.events.interactionCreate = async (interaction) => { + if (!interaction.data || !interaction.id) return + + let guildName = 'Direct Message' + let guild = {} as Guild + + // Set guild, if there was an error getting the guild, then just say it was a DM. (What else are we going to do?) + if (interaction.guildId) { + const guildOrVoid = await getGuildFromId(interaction.guildId).catch((err) => { + logger.error(err) + }) + + if (guildOrVoid) { + guild = guildOrVoid + guildName = guild.name + } + } + + logger.info( + `[Command: ${chalk.bgYellow.black(interaction.data.name)} - ${chalk.bgBlack.white(`Trigger`)}] by @${interaction.user.username} in ${guildName}${guildName !== 'Direct Message' ? ` (${guild.id})` : ``}`, + ) + + let command = commands.get(interaction.data.name) + + if (!command) { + logger.warn( + `[Command: ${chalk.bgYellow.black(interaction.data.name)} - ${chalk.bgBlack.yellow(`Not Found`)}] by @${interaction.user.username} in ${guildName}${guildName !== 'Direct Message' ? ` (${guild.id})` : ``}`, + ) + + return + } + + if (interaction.data.options?.[0]) { + const optionType = interaction.data.options[0].type + + if (optionType === ApplicationCommandOptionTypes.SubCommandGroup) { + // Check if command has subcommand and handle types + if (!command.subcommands) return + + // Try to find the subcommand group + const subCommandGroup = command.subcommands?.find((command) => command.name === interaction.data?.options?.[0].name) + if (!subCommandGroup) return + + if (isSubCommand(subCommandGroup)) return + + // Get name of the command which we are looking for + const targetCmdName = interaction.data.options?.[0].options?.[0].name ?? interaction.data.options?.[0].options?.[0].name + if (!targetCmdName) return + + // Try to find the command + command = subCommandGroup.subCommands.find((c) => c.name === targetCmdName) + } + + if (optionType === ApplicationCommandOptionTypes.SubCommand) { + // Check if command has subcommand and handle types + if (!command?.subcommands) return + + // Try to find the command + const found = command.subcommands.find((command) => command.name === interaction.data?.options?.[0].name) + if (!found) return + + if (isSubCommandGroup(found)) return + + command = found + } + } + + try { + if (!command) throw new Error('Not command could be found') + + await command.execute(interaction) + + logger.info( + `[Command: ${chalk.bgYellow.black(interaction.data.name)} - ${chalk.bgBlack.green(`Success`)}] by @${interaction.user.username} in ${guildName}${guildName !== 'Direct Message' ? ` (${guild.id})` : ``}`, + ) + } catch (err) { + logger.error( + `[Command: ${chalk.bgYellow.black(interaction.data.name)} - ${chalk.bgBlack.red(`Error`)}] by @${interaction.user.username} in ${guildName}${guildName !== 'Direct Message' ? ` (${guild.id})` : ``}`, + ) + + if (typeof err !== 'object' || !err || !hasProperty(err, 'message') || err.message === 'Not command could be found') return + + logger.error(err) } } diff --git a/examples/beginner/src/events/ready.ts b/examples/beginner/src/events/ready.ts index 1d57aeccc..5d615cd54 100644 --- a/examples/beginner/src/events/ready.ts +++ b/examples/beginner/src/events/ready.ts @@ -1,16 +1,22 @@ -import { Bot } from '../../bot.ts.js' -import log from '../utils/logger.ts.js' +import { ActivityTypes } from '@discordeno/bot' +import { bot } from '../bot.js' +import { createLogger } from '../utils/logger.js' -Bot.events.ready = (_, payload) => { - log.info(`[READY] Shard ID ${payload.shardId} of ${Bot.gateway.lastShardId + 1} shards is ready!`) +const logger = createLogger({ name: 'Event: Ready' }) - if (payload.shardId === Bot.gateway.lastShardId) { - botFullyReady() - } -} - -// This function lets you run custom code when all your bot's shards are online. -function botFullyReady() { - // DO STUFF YOU WANT HERE ONCE BOT IS FULLY ONLINE. - log.info('[READY] Bot is fully online.') +bot.events.ready = async ({ shardId }) => { + logger.info('Bot Ready') + + await bot.gateway.editShardStatus(shardId, { + status: 'online', + activities: [ + { + name: 'Discordeno is the Best Lib', + type: ActivityTypes.Game, + timestamps: { + start: Date.now(), + }, + }, + ], + }) } diff --git a/examples/beginner/src/index.ts b/examples/beginner/src/index.ts new file mode 100644 index 000000000..b0f5f89cf --- /dev/null +++ b/examples/beginner/src/index.ts @@ -0,0 +1,15 @@ +import 'dotenv/config' + +import { bot } from './bot.js' +import importDirectory from './utils/loader.js' +import logger from './utils/logger.js' + +logger.info('Starting bot...') + +logger.info('Loading commands...') +await importDirectory('./dist/commands') + +logger.info('Loading events...') +await importDirectory('./dist/events') + +await bot.start() diff --git a/examples/beginner/src/register-commands.ts b/examples/beginner/src/register-commands.ts new file mode 100644 index 000000000..21a0ff23a --- /dev/null +++ b/examples/beginner/src/register-commands.ts @@ -0,0 +1,7 @@ +import 'dotenv/config' + +import { bot } from './bot.js' +import { updateCommands } from './utils/helpers.js' + +bot.logger.info('Updating commands...') +await updateCommands() diff --git a/examples/beginner/src/types/mod.ts b/examples/beginner/src/types/mod.ts deleted file mode 100644 index 88fce63cc..000000000 --- a/examples/beginner/src/types/mod.ts +++ /dev/null @@ -1,3 +0,0 @@ -// This file will export all of the types in this directory. - -export * from './commands.ts.js' diff --git a/examples/beginner/src/utils/helpers.ts b/examples/beginner/src/utils/helpers.ts index d5f880cdc..485797656 100644 --- a/examples/beginner/src/utils/helpers.ts +++ b/examples/beginner/src/utils/helpers.ts @@ -1,3 +1,101 @@ -export function snowflakeToTimestamp(id: bigint) { - return Number(id / 4194304n + 1420070400000n) +import { hasProperty, type Bot, type CreateApplicationCommand, type Guild } from '@discordeno/bot' +import { bot } from '../bot.js' +import { commands, type SubCommand, type SubCommandGroup } from '../commands.js' +import { createLogger } from './logger.js' + +const logger = createLogger({ name: 'Helpers' }) + +/** This function will update all commands, or the defined scope */ +export async function updateCommands(scope?: 'Guild' | 'Global'): Promise { + const globalCommands: Array> = [] + const perGuildCommands: Array> = [] + + for (const command of commands.values()) { + if (command.scope === 'Guild') { + perGuildCommands.push({ + name: command.name, + description: command.description, + type: command.type, + options: command.options ? command.options : undefined, + }) + } else { + globalCommands.push({ + name: command.name, + description: command.description, + type: command.type, + options: command.options ? command.options : undefined, + }) + } + } + + if (globalCommands.length && (scope === 'Global' || scope === undefined)) { + logger.info('Updating Global Commands, changes should apply in short...') + await bot.helpers.upsertGlobalApplicationCommands(globalCommands).catch(logger.error) + } + + if (perGuildCommands.length && (scope === 'Guild' || scope === undefined)) { + await Promise.all( + bot.cache.guilds.memory.map(async (guild: Guild) => { + await bot.helpers.upsertGuildApplicationCommands(guild.id, perGuildCommands) + }), + ) + } +} + +/** Update commands for a guild */ +export async function updateGuildCommands(bot: Bot, guild: Guild): Promise { + const perGuildCommands: Array> = [] + + for (const command of commands.values()) { + if (command.scope === 'Guild') { + perGuildCommands.push({ + name: command.name, + description: command.description, + type: command.type, + options: command.options ? command.options : undefined, + }) + } + } + + if (perGuildCommands.length) { + await bot.helpers.upsertGuildApplicationCommands(guild.id, perGuildCommands) + } +} + +export async function getGuildFromId(guildId: bigint): Promise { + const cached = await bot.cache.guilds.get(guildId) + + if (cached) return cached + + return await bot.helpers.getGuild(guildId) +} + +export function humanizeMilliseconds(milliseconds: number): string { + // Gets ms into seconds + const time = milliseconds / 1000 + if (time < 1) return '< 1s' + + const days = Math.floor(time / 86400) + const hours = Math.floor((time % 86400) / 3600) + const minutes = Math.floor(((time % 86400) % 3600) / 60) + const seconds = Math.floor(((time % 86400) % 3600) % 60) + + const dayString = days ? `${days}d ` : '' + const hourString = hours ? `${hours}h ` : '' + const minuteString = minutes ? `${minutes}m ` : '' + const secondString = seconds ? `${seconds}s ` : '' + + return `${dayString}${hourString}${minuteString}${secondString}` +} + +export function isSubCommand(data: SubCommand | SubCommandGroup): data is SubCommand { + return !hasProperty(data, 'subCommands') +} + +export function isSubCommandGroup(data: SubCommand | SubCommandGroup): data is SubCommandGroup { + return hasProperty(data, 'subCommands') +} + +type MakeRequired = TObj & { + [Key in TKey]-?: TObj[Key] } diff --git a/examples/beginner/src/utils/loader.ts b/examples/beginner/src/utils/loader.ts index 807cec5a6..5b1c6f541 100644 --- a/examples/beginner/src/utils/loader.ts +++ b/examples/beginner/src/utils/loader.ts @@ -1,40 +1,15 @@ -import log from './logger.ts.js' +import { readdir } from 'node:fs/promises' +import logger from './logger.js' -// Very important to make sure files are reloaded properly -let uniqueFilePathCounter = 0 -let paths: string[] = [] +export default async function importDirectory(folder: string): Promise { + const files = await readdir(folder, { recursive: true }) -/** This function allows reading all files in a folder. Useful for loading/reloading commands, monitors etc */ -export async function importDirectory(path: string) { - path = path.replaceAll('\\', '/') - const files = Deno.readDirSync(Deno.realPathSync(path)) - const folder = path.substring(path.indexOf('/src/') + 5) + for (const filename of files) { + if (!filename.endsWith('.js')) continue - if (!folder.includes('/')) log.info(`Loading ${folder}...`) - - for (const file of files) { - if (!file.name) continue - - const currentPath = `${path}/${file.name}` - if (file.isFile) { - if (!currentPath.endsWith('.ts')) continue - paths.push( - `import "${Deno.mainModule.substring(0, Deno.mainModule.lastIndexOf('/'))}/${currentPath.substring( - currentPath.indexOf('src/'), - )}#${uniqueFilePathCounter}";`, - ) - continue - } - - await importDirectory(currentPath) + // Using `file://` and `process.cwd()` to avoid weird issues with relative paths and/or Windows + await import(`file://${process.cwd()}/${folder}/${filename}`).catch((x) => + logger.fatal(`Cannot import file (${folder}/${filename}) for reason:`, x), + ) } - - uniqueFilePathCounter++ -} - -/** Imports all everything in fileloader.ts */ -export async function fileLoader() { - await Deno.writeTextFile('fileloader.ts', paths.join('\n').replaceAll('\\', '/')) - await import(`${Deno.mainModule.substring(0, Deno.mainModule.lastIndexOf('/'))}/fileloader.ts#${uniqueFilePathCounter}`) - paths = [] } diff --git a/examples/beginner/src/utils/logger.ts b/examples/beginner/src/utils/logger.ts index c69924a23..4838e581b 100644 --- a/examples/beginner/src/utils/logger.ts +++ b/examples/beginner/src/utils/logger.ts @@ -1,5 +1,5 @@ -// deno-lint-ignore-file no-explicit-any -import { bold, cyan, gray, italic, red, yellow } from '../../deps.ts.js' +/* eslint-disable @typescript-eslint/no-unsafe-argument */ +import chalk from 'chalk' export enum LogLevels { Debug, @@ -19,21 +19,15 @@ const prefixes = new Map([ const noColor: (str: string) => string = (msg) => msg const colorFunctions = new Map string>([ - [LogLevels.Debug, gray], - [LogLevels.Info, cyan], - [LogLevels.Warn, yellow], - [LogLevels.Error, (str: string) => red(str)], - [LogLevels.Fatal, (str: string) => red(bold(italic(str)))], + [LogLevels.Debug, chalk.gray], + [LogLevels.Info, chalk.cyan], + [LogLevels.Warn, chalk.yellow], + [LogLevels.Error, (str: string) => chalk.red(str)], + [LogLevels.Fatal, (str: string) => chalk.red.bold.italic(str)], ]) -export function logger({ - logLevel = LogLevels.Info, - name, -}: { - logLevel?: LogLevels - name?: string -} = {}) { - function log(level: LogLevels, ...args: any[]) { +export function createLogger({ logLevel = LogLevels.Info, name }: { logLevel?: LogLevels; name?: string } = {}): Logger { + function log(level: LogLevels, ...args: any[]): void { if (level < logLevel) return let color = colorFunctions.get(level) @@ -42,7 +36,7 @@ export function logger({ const date = new Date() const log = [ `[${date.toLocaleDateString()} ${date.toLocaleTimeString()}]`, - color(prefixes.get(level) || 'DEBUG'), + color(prefixes.get(level) ?? 'DEBUG'), name ? `${name} >` : '>', ...args, ] @@ -63,27 +57,27 @@ export function logger({ } } - function setLevel(level: LogLevels) { + function setLevel(level: LogLevels): void { logLevel = level } - function debug(...args: any[]) { + function debug(...args: any[]): void { log(LogLevels.Debug, ...args) } - function info(...args: any[]) { + function info(...args: any[]): void { log(LogLevels.Info, ...args) } - function warn(...args: any[]) { + function warn(...args: any[]): void { log(LogLevels.Warn, ...args) } - function error(...args: any[]) { + function error(...args: any[]): void { log(LogLevels.Error, ...args) } - function fatal(...args: any[]) { + function fatal(...args: any[]): void { log(LogLevels.Fatal, ...args) } @@ -98,5 +92,15 @@ export function logger({ } } -export const log = logger({ name: 'Main' }) -export default log +export const logger = createLogger({ name: 'Main' }) +export default logger + +export interface Logger { + log: (level: LogLevels, ...args: any[]) => void + debug: (...args: any[]) => void + info: (...args: any[]) => void + warn: (...args: any[]) => void + error: (...args: any[]) => void + fatal: (...args: any[]) => void + setLevel: (level: LogLevels) => void +} diff --git a/examples/beginner/src/utils/updateCommands.ts b/examples/beginner/src/utils/updateCommands.ts deleted file mode 100644 index f2751e7a8..000000000 --- a/examples/beginner/src/utils/updateCommands.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Bot } from '../../bot.ts.js' -import { configs } from '../../configs.ts.js' - -export async function updateApplicationCommands() { - await Bot.helpers.upsertGlobalApplicationCommands( - Bot.commands - // ONLY GLOBAL COMMANDS - .filter((command) => !command.devOnly) - .array(), - ) - - await Bot.helpers.upsertGuildApplicationCommands( - configs.devGuildId, - Bot.commands - // ONLY GLOBAL COMMANDS - .filter((command) => !!command.devOnly) - .array(), - ) -} diff --git a/examples/beginner/tsconfig.json b/examples/beginner/tsconfig.json new file mode 100644 index 000000000..04416ddd6 --- /dev/null +++ b/examples/beginner/tsconfig.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "target": "es2022", + "module": "es2022", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "isolatedModules": true, + "moduleResolution": "node", + "skipDefaultLibCheck": true, + "skipLibCheck": true, + "strict": true, + "incremental": true + } +} diff --git a/examples/beginner/yarn.lock b/examples/beginner/yarn.lock new file mode 100644 index 000000000..c3c9ec7a1 --- /dev/null +++ b/examples/beginner/yarn.lock @@ -0,0 +1,2133 @@ +# This file is generated by running "yarn install" inside your project. +# Manual changes might be lost - proceed with caution! + +__metadata: + version: 8 + cacheKey: 10 + +"@discordeno/bot@npm:19.0.0-next.92bf166": + version: 19.0.0-next.92bf166 + resolution: "@discordeno/bot@npm:19.0.0-next.92bf166" + dependencies: + "@discordeno/gateway": "npm:19.0.0-next.92bf166" + "@discordeno/rest": "npm:19.0.0-next.92bf166" + "@discordeno/types": "npm:19.0.0-next.92bf166" + "@discordeno/utils": "npm:19.0.0-next.92bf166" + checksum: 3020e74c774eae34307d434ad38f983e90839dc5fad7578f3cda4fba6c1efb7a22c4f4cdcfff58c54b62cc14976ad974256955d5117e490f78ec9e835e02c682 + languageName: node + linkType: hard + +"@discordeno/gateway@npm:19.0.0-next.92bf166": + version: 19.0.0-next.92bf166 + resolution: "@discordeno/gateway@npm:19.0.0-next.92bf166" + dependencies: + "@discordeno/types": "npm:19.0.0-next.92bf166" + "@discordeno/utils": "npm:19.0.0-next.92bf166" + ws: "npm:^8.16.0" + checksum: 6a11ca7a4cb98f48726664d0baa27d04e26342bf94d6e439494e462636af20d17b567e9d3e2e478465aabcecb98a21e54b860b39b9f1022eef922e76d947ddcb + languageName: node + linkType: hard + +"@discordeno/rest@npm:19.0.0-next.92bf166": + version: 19.0.0-next.92bf166 + resolution: "@discordeno/rest@npm:19.0.0-next.92bf166" + dependencies: + "@discordeno/types": "npm:19.0.0-next.92bf166" + "@discordeno/utils": "npm:19.0.0-next.92bf166" + dotenv: "npm:^16.4.5" + checksum: 45f6ba4791003b77c883e991ad348597197d70e25e335b8628a03bd2effa8e2047a2f987f4c0b6ee8b17c01f77055d7a1ddc9f5350eb8f1c8ff8c8d39f91d787 + languageName: node + linkType: hard + +"@discordeno/types@npm:19.0.0-next.92bf166": + version: 19.0.0-next.92bf166 + resolution: "@discordeno/types@npm:19.0.0-next.92bf166" + checksum: f88e78a18e51c179b94ef14e8bcdd6b5e6c5f25bdd6c4308bec121e5e59533612b36ed0e7a447daedc009053e1e30c6c8e13b2276bb1ce7e2f840ff58473a2ef + languageName: node + linkType: hard + +"@discordeno/utils@npm:19.0.0-next.92bf166": + version: 19.0.0-next.92bf166 + resolution: "@discordeno/utils@npm:19.0.0-next.92bf166" + dependencies: + "@discordeno/types": "npm:19.0.0-next.92bf166" + tweetnacl: "npm:^1.0.3" + checksum: 7962a057ba5908936e4224df70b9ceaffcb8ec7ad220a999b36fc0601365b380bb0de01b6adfa4c36250247e3d15e22215fc63bbe3634b932434411c5f4ca13d + languageName: node + linkType: hard + +"@isaacs/cliui@npm:^8.0.2": + version: 8.0.2 + resolution: "@isaacs/cliui@npm:8.0.2" + dependencies: + string-width: "npm:^5.1.2" + string-width-cjs: "npm:string-width@^4.2.0" + strip-ansi: "npm:^7.0.1" + strip-ansi-cjs: "npm:strip-ansi@^6.0.1" + wrap-ansi: "npm:^8.1.0" + wrap-ansi-cjs: "npm:wrap-ansi@^7.0.0" + checksum: e9ed5fd27c3aec1095e3a16e0c0cf148d1fee55a38665c35f7b3f86a9b5d00d042ddaabc98e8a1cb7463b9378c15f22a94eb35e99469c201453eb8375191f243 + languageName: node + linkType: hard + +"@mole-inc/bin-wrapper@npm:^8.0.1": + version: 8.0.1 + resolution: "@mole-inc/bin-wrapper@npm:8.0.1" + dependencies: + bin-check: "npm:^4.1.0" + bin-version-check: "npm:^5.0.0" + content-disposition: "npm:^0.5.4" + ext-name: "npm:^5.0.0" + file-type: "npm:^17.1.6" + filenamify: "npm:^5.0.2" + got: "npm:^11.8.5" + os-filter-obj: "npm:^2.0.0" + checksum: 565df38f6f91fefe2e2540bf4357024fd912990aecb1873fd9bf21e6a667d9930c73e5cbc87a9aac0cf476b8dffc30a4e00ec97b62e713ef5c00d46823ea599d + languageName: node + linkType: hard + +"@nodelib/fs.scandir@npm:2.1.5": + version: 2.1.5 + resolution: "@nodelib/fs.scandir@npm:2.1.5" + dependencies: + "@nodelib/fs.stat": "npm:2.0.5" + run-parallel: "npm:^1.1.9" + checksum: 6ab2a9b8a1d67b067922c36f259e3b3dfd6b97b219c540877a4944549a4d49ea5ceba5663905ab5289682f1f3c15ff441d02f0447f620a42e1cb5e1937174d4b + languageName: node + linkType: hard + +"@nodelib/fs.stat@npm:2.0.5, @nodelib/fs.stat@npm:^2.0.2": + version: 2.0.5 + resolution: "@nodelib/fs.stat@npm:2.0.5" + checksum: 012480b5ca9d97bff9261571dbbec7bbc6033f69cc92908bc1ecfad0792361a5a1994bc48674b9ef76419d056a03efadfce5a6cf6dbc0a36559571a7a483f6f0 + languageName: node + linkType: hard + +"@nodelib/fs.walk@npm:^1.2.3": + version: 1.2.8 + resolution: "@nodelib/fs.walk@npm:1.2.8" + dependencies: + "@nodelib/fs.scandir": "npm:2.1.5" + fastq: "npm:^1.6.0" + checksum: 40033e33e96e97d77fba5a238e4bba4487b8284678906a9f616b5579ddaf868a18874c0054a75402c9fbaaa033a25ceae093af58c9c30278e35c23c9479e79b0 + languageName: node + linkType: hard + +"@npmcli/agent@npm:^2.0.0": + version: 2.2.2 + resolution: "@npmcli/agent@npm:2.2.2" + dependencies: + agent-base: "npm:^7.1.0" + http-proxy-agent: "npm:^7.0.0" + https-proxy-agent: "npm:^7.0.1" + lru-cache: "npm:^10.0.1" + socks-proxy-agent: "npm:^8.0.3" + checksum: 96fc0036b101bae5032dc2a4cd832efb815ce9b33f9ee2f29909ee49d96a0026b3565f73c507a69eb8603f5cb32e0ae45a70cab1e2655990a4e06ae99f7f572a + languageName: node + linkType: hard + +"@npmcli/fs@npm:^3.1.0": + version: 3.1.1 + resolution: "@npmcli/fs@npm:3.1.1" + dependencies: + semver: "npm:^7.3.5" + checksum: 1e0e04087049b24b38bc0b30d87a9388ee3ca1d3fdfc347c2f77d84fcfe6a51f250bc57ba2c1f614d7e4285c6c62bf8c769bc19aa0949ea39e5b043ee023b0bd + languageName: node + linkType: hard + +"@pkgjs/parseargs@npm:^0.11.0": + version: 0.11.0 + resolution: "@pkgjs/parseargs@npm:0.11.0" + checksum: 115e8ceeec6bc69dff2048b35c0ab4f8bbee12d8bb6c1f4af758604586d802b6e669dcb02dda61d078de42c2b4ddce41b3d9e726d7daa6b4b850f4adbf7333ff + languageName: node + linkType: hard + +"@sindresorhus/is@npm:^4.0.0": + version: 4.6.0 + resolution: "@sindresorhus/is@npm:4.6.0" + checksum: e7f36ed72abfcd5e0355f7423a72918b9748bb1ef370a59f3e5ad8d40b728b85d63b272f65f63eec1faf417cda89dcb0aeebe94015647b6054659c1442fe5ce0 + languageName: node + linkType: hard + +"@swc/cli@npm:^0.3.12": + version: 0.3.12 + resolution: "@swc/cli@npm:0.3.12" + dependencies: + "@mole-inc/bin-wrapper": "npm:^8.0.1" + "@swc/counter": "npm:^0.1.3" + commander: "npm:^8.3.0" + fast-glob: "npm:^3.2.5" + minimatch: "npm:^9.0.3" + piscina: "npm:^4.3.0" + semver: "npm:^7.3.8" + slash: "npm:3.0.0" + source-map: "npm:^0.7.3" + peerDependencies: + "@swc/core": ^1.2.66 + chokidar: ^3.5.1 + peerDependenciesMeta: + chokidar: + optional: true + bin: + spack: bin/spack.js + swc: bin/swc.js + swcx: bin/swcx.js + checksum: fee260434fad8eed0328f4db17f42ce0864b93b90fcb02f3f0eb3aad994b5a6ae4bfdfb6d2329377e0cd8d07adc61cca42e290bf0005c1ab4d004d4a0b152db4 + languageName: node + linkType: hard + +"@swc/core-darwin-arm64@npm:1.6.3": + version: 1.6.3 + resolution: "@swc/core-darwin-arm64@npm:1.6.3" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@swc/core-darwin-x64@npm:1.6.3": + version: 1.6.3 + resolution: "@swc/core-darwin-x64@npm:1.6.3" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@swc/core-linux-arm-gnueabihf@npm:1.6.3": + version: 1.6.3 + resolution: "@swc/core-linux-arm-gnueabihf@npm:1.6.3" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@swc/core-linux-arm64-gnu@npm:1.6.3": + version: 1.6.3 + resolution: "@swc/core-linux-arm64-gnu@npm:1.6.3" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@swc/core-linux-arm64-musl@npm:1.6.3": + version: 1.6.3 + resolution: "@swc/core-linux-arm64-musl@npm:1.6.3" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@swc/core-linux-x64-gnu@npm:1.6.3": + version: 1.6.3 + resolution: "@swc/core-linux-x64-gnu@npm:1.6.3" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@swc/core-linux-x64-musl@npm:1.6.3": + version: 1.6.3 + resolution: "@swc/core-linux-x64-musl@npm:1.6.3" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@swc/core-win32-arm64-msvc@npm:1.6.3": + version: 1.6.3 + resolution: "@swc/core-win32-arm64-msvc@npm:1.6.3" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@swc/core-win32-ia32-msvc@npm:1.6.3": + version: 1.6.3 + resolution: "@swc/core-win32-ia32-msvc@npm:1.6.3" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@swc/core-win32-x64-msvc@npm:1.6.3": + version: 1.6.3 + resolution: "@swc/core-win32-x64-msvc@npm:1.6.3" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@swc/core@npm:^1.6.3": + version: 1.6.3 + resolution: "@swc/core@npm:1.6.3" + dependencies: + "@swc/core-darwin-arm64": "npm:1.6.3" + "@swc/core-darwin-x64": "npm:1.6.3" + "@swc/core-linux-arm-gnueabihf": "npm:1.6.3" + "@swc/core-linux-arm64-gnu": "npm:1.6.3" + "@swc/core-linux-arm64-musl": "npm:1.6.3" + "@swc/core-linux-x64-gnu": "npm:1.6.3" + "@swc/core-linux-x64-musl": "npm:1.6.3" + "@swc/core-win32-arm64-msvc": "npm:1.6.3" + "@swc/core-win32-ia32-msvc": "npm:1.6.3" + "@swc/core-win32-x64-msvc": "npm:1.6.3" + "@swc/counter": "npm:^0.1.3" + "@swc/types": "npm:^0.1.8" + peerDependencies: + "@swc/helpers": "*" + dependenciesMeta: + "@swc/core-darwin-arm64": + optional: true + "@swc/core-darwin-x64": + optional: true + "@swc/core-linux-arm-gnueabihf": + optional: true + "@swc/core-linux-arm64-gnu": + optional: true + "@swc/core-linux-arm64-musl": + optional: true + "@swc/core-linux-x64-gnu": + optional: true + "@swc/core-linux-x64-musl": + optional: true + "@swc/core-win32-arm64-msvc": + optional: true + "@swc/core-win32-ia32-msvc": + optional: true + "@swc/core-win32-x64-msvc": + optional: true + peerDependenciesMeta: + "@swc/helpers": + optional: true + checksum: b4c84a083ecabb0280ba53dffa65a5a575321de94081ad52bd12027fe3b5c8957978f2211b6036e2e28d904dd046fca238106c2106b32d02b752808a51193d35 + languageName: node + linkType: hard + +"@swc/counter@npm:^0.1.3": + version: 0.1.3 + resolution: "@swc/counter@npm:0.1.3" + checksum: df8f9cfba9904d3d60f511664c70d23bb323b3a0803ec9890f60133954173047ba9bdeabce28cd70ba89ccd3fd6c71c7b0bd58be85f611e1ffbe5d5c18616598 + languageName: node + linkType: hard + +"@swc/types@npm:^0.1.8": + version: 0.1.8 + resolution: "@swc/types@npm:0.1.8" + dependencies: + "@swc/counter": "npm:^0.1.3" + checksum: 2d1cda35116e03714137c1c37f4493efe0e26e88285ecc9dcdf6256a77984e367ea7b5f31d650f110fdcfd6ac53dff3ec77f841787ca328d2efa7b07ef1ac318 + languageName: node + linkType: hard + +"@szmarczak/http-timer@npm:^4.0.5": + version: 4.0.6 + resolution: "@szmarczak/http-timer@npm:4.0.6" + dependencies: + defer-to-connect: "npm:^2.0.0" + checksum: c29df3bcec6fc3bdec2b17981d89d9c9fc9bd7d0c9bcfe92821dc533f4440bc890ccde79971838b4ceed1921d456973c4180d7175ee1d0023ad0562240a58d95 + languageName: node + linkType: hard + +"@tokenizer/token@npm:^0.3.0": + version: 0.3.0 + resolution: "@tokenizer/token@npm:0.3.0" + checksum: 889c1f1e63ac7c92c0ea22d4a2861142f1b43c3d92eb70ec42aa9e9851fab2e9952211d50f541b287781280df2f979bf5600a9c1f91fbc61b7fcf9994e9376a5 + languageName: node + linkType: hard + +"@types/cacheable-request@npm:^6.0.1": + version: 6.0.3 + resolution: "@types/cacheable-request@npm:6.0.3" + dependencies: + "@types/http-cache-semantics": "npm:*" + "@types/keyv": "npm:^3.1.4" + "@types/node": "npm:*" + "@types/responselike": "npm:^1.0.0" + checksum: 159f9fdb2a1b7175eef453ae2ced5ea04c0d2b9610cc9ccd9f9abb066d36dacb1f37acd879ace10ad7cbb649490723feb396fb7307004c9670be29636304b988 + languageName: node + linkType: hard + +"@types/http-cache-semantics@npm:*": + version: 4.0.4 + resolution: "@types/http-cache-semantics@npm:4.0.4" + checksum: a59566cff646025a5de396d6b3f44a39ab6a74f2ed8150692e0f31cc52f3661a68b04afe3166ebe0d566bd3259cb18522f46e949576d5204781cd6452b7fe0c5 + languageName: node + linkType: hard + +"@types/keyv@npm:^3.1.4": + version: 3.1.4 + resolution: "@types/keyv@npm:3.1.4" + dependencies: + "@types/node": "npm:*" + checksum: e009a2bfb50e90ca9b7c6e8f648f8464067271fd99116f881073fa6fa76dc8d0133181dd65e6614d5fb1220d671d67b0124aef7d97dc02d7e342ab143a47779d + languageName: node + linkType: hard + +"@types/node@npm:*": + version: 20.14.2 + resolution: "@types/node@npm:20.14.2" + dependencies: + undici-types: "npm:~5.26.4" + checksum: c38e47b190fa0a8bdfde24b036dddcf9401551f2fb170a90ff33625c7d6f218907e81c74e0fa6e394804a32623c24c60c50e249badc951007830f0d02c48ee0f + languageName: node + linkType: hard + +"@types/node@npm:^20.14.6": + version: 20.14.6 + resolution: "@types/node@npm:20.14.6" + dependencies: + undici-types: "npm:~5.26.4" + checksum: 1dcfeeb03ce3c3a1d8a537fefee7cd0cffb78f89e9535b74ee12940559566b57c39dad20d1b165b60b5727408dd44e1a52e5c01cf02d0a99d93ef3da8062c86e + languageName: node + linkType: hard + +"@types/responselike@npm:^1.0.0": + version: 1.0.3 + resolution: "@types/responselike@npm:1.0.3" + dependencies: + "@types/node": "npm:*" + checksum: 6ac4b35723429b11b117e813c7acc42c3af8b5554caaf1fc750404c1ae59f9b7376bc69b9e9e194a5a97357a597c2228b7173d317320f0360d617b6425212f58 + languageName: node + linkType: hard + +"abbrev@npm:^2.0.0": + version: 2.0.0 + resolution: "abbrev@npm:2.0.0" + checksum: ca0a54e35bea4ece0ecb68a47b312e1a9a6f772408d5bcb9051230aaa94b0460671c5b5c9cb3240eb5b7bc94c52476550eb221f65a0bbd0145bdc9f3113a6707 + languageName: node + linkType: hard + +"agent-base@npm:^7.0.2, agent-base@npm:^7.1.0, agent-base@npm:^7.1.1": + version: 7.1.1 + resolution: "agent-base@npm:7.1.1" + dependencies: + debug: "npm:^4.3.4" + checksum: c478fec8f79953f118704d007a38f2a185458853f5c45579b9669372bd0e12602e88dc2ad0233077831504f7cd6fcc8251c383375bba5eaaf563b102938bda26 + languageName: node + linkType: hard + +"aggregate-error@npm:^3.0.0": + version: 3.1.0 + resolution: "aggregate-error@npm:3.1.0" + dependencies: + clean-stack: "npm:^2.0.0" + indent-string: "npm:^4.0.0" + checksum: 1101a33f21baa27a2fa8e04b698271e64616b886795fd43c31068c07533c7b3facfcaf4e9e0cab3624bd88f729a592f1c901a1a229c9e490eafce411a8644b79 + languageName: node + linkType: hard + +"ansi-regex@npm:^5.0.1": + version: 5.0.1 + resolution: "ansi-regex@npm:5.0.1" + checksum: 2aa4bb54caf2d622f1afdad09441695af2a83aa3fe8b8afa581d205e57ed4261c183c4d3877cee25794443fde5876417d859c108078ab788d6af7e4fe52eb66b + languageName: node + linkType: hard + +"ansi-regex@npm:^6.0.1": + version: 6.0.1 + resolution: "ansi-regex@npm:6.0.1" + checksum: 1ff8b7667cded1de4fa2c9ae283e979fc87036864317da86a2e546725f96406746411d0d85e87a2d12fa5abd715d90006de7fa4fa0477c92321ad3b4c7d4e169 + languageName: node + linkType: hard + +"ansi-styles@npm:^4.0.0": + version: 4.3.0 + resolution: "ansi-styles@npm:4.3.0" + dependencies: + color-convert: "npm:^2.0.1" + checksum: b4494dfbfc7e4591b4711a396bd27e540f8153914123dccb4cdbbcb514015ada63a3809f362b9d8d4f6b17a706f1d7bea3c6f974b15fa5ae76b5b502070889ff + languageName: node + linkType: hard + +"ansi-styles@npm:^6.1.0": + version: 6.2.1 + resolution: "ansi-styles@npm:6.2.1" + checksum: 70fdf883b704d17a5dfc9cde206e698c16bcd74e7f196ab821511651aee4f9f76c9514bdfa6ca3a27b5e49138b89cb222a28caf3afe4567570139577f991df32 + languageName: node + linkType: hard + +"arch@npm:^2.1.0": + version: 2.2.0 + resolution: "arch@npm:2.2.0" + checksum: e35dbc6d362297000ab90930069576ba165fe63cd52383efcce14bd66c1b16a91ce849e1fd239964ed029d5e0bdfc32f68e9c7331b7df6c84ddebebfdbf242f7 + languageName: node + linkType: hard + +"balanced-match@npm:^1.0.0": + version: 1.0.2 + resolution: "balanced-match@npm:1.0.2" + checksum: 9706c088a283058a8a99e0bf91b0a2f75497f185980d9ffa8b304de1d9e58ebda7c72c07ebf01dadedaac5b2907b2c6f566f660d62bd336c3468e960403b9d65 + languageName: node + linkType: hard + +"bin-check@npm:^4.1.0": + version: 4.1.0 + resolution: "bin-check@npm:4.1.0" + dependencies: + execa: "npm:^0.7.0" + executable: "npm:^4.1.0" + checksum: 16f6d5d86df9365dab682c7dd238f93678b773a908b3bccea4b1acb82b9b4e49fcfa24c99b99180a8e4cdd89a8f15f03700b09908ed5ae651f52fd82488a3507 + languageName: node + linkType: hard + +"bin-version-check@npm:^5.0.0": + version: 5.1.0 + resolution: "bin-version-check@npm:5.1.0" + dependencies: + bin-version: "npm:^6.0.0" + semver: "npm:^7.5.3" + semver-truncate: "npm:^3.0.0" + checksum: d99679cfe0964703045fe0145a98f117888942b621dfe2c2377305ee9a9d735374d8e3ecb3b476507b284af2567699f24f7ecb2feb1f27ad6086ad60b3198893 + languageName: node + linkType: hard + +"bin-version@npm:^6.0.0": + version: 6.0.0 + resolution: "bin-version@npm:6.0.0" + dependencies: + execa: "npm:^5.0.0" + find-versions: "npm:^5.0.0" + checksum: 78c29422ea9597eb4c8d4f0eff96df60d09aa82b53a87925bc403efbe5c55251b1a07baac538381d9096377f92d27e3c03963efa86db5bc0d6431b9563946229 + languageName: node + linkType: hard + +"brace-expansion@npm:^2.0.1": + version: 2.0.1 + resolution: "brace-expansion@npm:2.0.1" + dependencies: + balanced-match: "npm:^1.0.0" + checksum: a61e7cd2e8a8505e9f0036b3b6108ba5e926b4b55089eeb5550cd04a471fe216c96d4fe7e4c7f995c728c554ae20ddfc4244cad10aef255e72b62930afd233d1 + languageName: node + linkType: hard + +"braces@npm:^3.0.3": + version: 3.0.3 + resolution: "braces@npm:3.0.3" + dependencies: + fill-range: "npm:^7.1.1" + checksum: fad11a0d4697a27162840b02b1fad249c1683cbc510cd5bf1a471f2f8085c046d41094308c577a50a03a579dd99d5a6b3724c4b5e8b14df2c4443844cfcda2c6 + languageName: node + linkType: hard + +"cacache@npm:^18.0.0": + version: 18.0.3 + resolution: "cacache@npm:18.0.3" + dependencies: + "@npmcli/fs": "npm:^3.1.0" + fs-minipass: "npm:^3.0.0" + glob: "npm:^10.2.2" + lru-cache: "npm:^10.0.1" + minipass: "npm:^7.0.3" + minipass-collect: "npm:^2.0.1" + minipass-flush: "npm:^1.0.5" + minipass-pipeline: "npm:^1.2.4" + p-map: "npm:^4.0.0" + ssri: "npm:^10.0.0" + tar: "npm:^6.1.11" + unique-filename: "npm:^3.0.0" + checksum: d4c161f071524bb636334b8cf94780c014e29c180a886b8184da8f2f44d2aca88d5664797c661e9f74bdbd34697c2f231ed7c24c256cecbb0a0563ad1ada2219 + languageName: node + linkType: hard + +"cacheable-lookup@npm:^5.0.3": + version: 5.0.4 + resolution: "cacheable-lookup@npm:5.0.4" + checksum: 618a8b3eea314060e74cb3285a6154e8343c244a34235acf91cfe626ee0705c24e3cd11e4b1a7b3900bd749ee203ae65afe13adf610c8ab173e99d4a208faf75 + languageName: node + linkType: hard + +"cacheable-request@npm:^7.0.2": + version: 7.0.4 + resolution: "cacheable-request@npm:7.0.4" + dependencies: + clone-response: "npm:^1.0.2" + get-stream: "npm:^5.1.0" + http-cache-semantics: "npm:^4.0.0" + keyv: "npm:^4.0.0" + lowercase-keys: "npm:^2.0.0" + normalize-url: "npm:^6.0.1" + responselike: "npm:^2.0.0" + checksum: 0f4f2001260ecca78b9f64fc8245e6b5a5dcde24ea53006daab71f5e0e1338095aa1512ec099c4f9895a9e5acfac9da423cb7c079e131485891e9214aca46c41 + languageName: node + linkType: hard + +"chalk@npm:^5.3.0": + version: 5.3.0 + resolution: "chalk@npm:5.3.0" + checksum: 6373caaab21bd64c405bfc4bd9672b145647fc9482657b5ea1d549b3b2765054e9d3d928870cdf764fb4aad67555f5061538ff247b8310f110c5c888d92397ea + languageName: node + linkType: hard + +"chownr@npm:^2.0.0": + version: 2.0.0 + resolution: "chownr@npm:2.0.0" + checksum: c57cf9dd0791e2f18a5ee9c1a299ae6e801ff58fee96dc8bfd0dcb4738a6ce58dd252a3605b1c93c6418fe4f9d5093b28ffbf4d66648cb2a9c67eaef9679be2f + languageName: node + linkType: hard + +"clean-stack@npm:^2.0.0": + version: 2.2.0 + resolution: "clean-stack@npm:2.2.0" + checksum: 2ac8cd2b2f5ec986a3c743935ec85b07bc174d5421a5efc8017e1f146a1cf5f781ae962618f416352103b32c9cd7e203276e8c28241bbe946160cab16149fb68 + languageName: node + linkType: hard + +"clone-response@npm:^1.0.2": + version: 1.0.3 + resolution: "clone-response@npm:1.0.3" + dependencies: + mimic-response: "npm:^1.0.0" + checksum: 4e671cac39b11c60aa8ba0a450657194a5d6504df51bca3fac5b3bd0145c4f8e8464898f87c8406b83232e3bc5cca555f51c1f9c8ac023969ebfbf7f6bdabb2e + languageName: node + linkType: hard + +"color-convert@npm:^2.0.1": + version: 2.0.1 + resolution: "color-convert@npm:2.0.1" + dependencies: + color-name: "npm:~1.1.4" + checksum: fa00c91b4332b294de06b443923246bccebe9fab1b253f7fe1772d37b06a2269b4039a85e309abe1fe11b267b11c08d1d0473fda3badd6167f57313af2887a64 + languageName: node + linkType: hard + +"color-name@npm:~1.1.4": + version: 1.1.4 + resolution: "color-name@npm:1.1.4" + checksum: b0445859521eb4021cd0fb0cc1a75cecf67fceecae89b63f62b201cca8d345baf8b952c966862a9d9a2632987d4f6581f0ec8d957dfacece86f0a7919316f610 + languageName: node + linkType: hard + +"commander@npm:^8.3.0": + version: 8.3.0 + resolution: "commander@npm:8.3.0" + checksum: 6b7b5d334483ce24bd73c5dac2eab901a7dbb25fd983ea24a1eeac6e7166bb1967f641546e8abf1920afbde86a45fbfe5812fbc69d0dc451bb45ca416a12a3a3 + languageName: node + linkType: hard + +"content-disposition@npm:^0.5.4": + version: 0.5.4 + resolution: "content-disposition@npm:0.5.4" + dependencies: + safe-buffer: "npm:5.2.1" + checksum: b7f4ce176e324f19324be69b05bf6f6e411160ac94bc523b782248129eb1ef3be006f6cff431aaea5e337fe5d176ce8830b8c2a1b721626ead8933f0cbe78720 + languageName: node + linkType: hard + +"cross-spawn@npm:^5.0.1": + version: 5.1.0 + resolution: "cross-spawn@npm:5.1.0" + dependencies: + lru-cache: "npm:^4.0.1" + shebang-command: "npm:^1.2.0" + which: "npm:^1.2.9" + checksum: 726939c9954fc70c20e538923feaaa33bebc253247d13021737c3c7f68cdc3e0a57f720c0fe75057c0387995349f3f12e20e9bfdbf12274db28019c7ea4ec166 + languageName: node + linkType: hard + +"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.3": + version: 7.0.3 + resolution: "cross-spawn@npm:7.0.3" + dependencies: + path-key: "npm:^3.1.0" + shebang-command: "npm:^2.0.0" + which: "npm:^2.0.1" + checksum: e1a13869d2f57d974de0d9ef7acbf69dc6937db20b918525a01dacb5032129bd552d290d886d981e99f1b624cb03657084cc87bd40f115c07ecf376821c729ce + languageName: node + linkType: hard + +"dd-beginner-bot@workspace:.": + version: 0.0.0-use.local + resolution: "dd-beginner-bot@workspace:." + dependencies: + "@discordeno/bot": "npm:19.0.0-next.92bf166" + "@swc/cli": "npm:^0.3.12" + "@swc/core": "npm:^1.6.3" + "@types/node": "npm:^20.14.6" + chalk: "npm:^5.3.0" + dd-cache-proxy: "npm:^2.1.1" + dotenv: "npm:^16.4.5" + typescript: "npm:^5.5.2" + languageName: unknown + linkType: soft + +"dd-cache-proxy@npm:^2.1.1": + version: 2.1.1 + resolution: "dd-cache-proxy@npm:2.1.1" + peerDependencies: + "@discordeno/bot": 19.0.0-next.d69e537 + checksum: 082234277fd0dc91477b0ac4a938aea40b8d3ffa60e7e458ce570b2f4c919671ecd5b601f7ff6c6157a5e4e5eaa3786e6a1884cccb020a938cb76e4e300f0f72 + languageName: node + linkType: hard + +"debug@npm:4, debug@npm:^4.3.4": + version: 4.3.5 + resolution: "debug@npm:4.3.5" + dependencies: + ms: "npm:2.1.2" + peerDependenciesMeta: + supports-color: + optional: true + checksum: cb6eab424c410e07813ca1392888589972ce9a32b8829c6508f5e1f25f3c3e70a76731610ae55b4bbe58d1a2fffa1424b30e97fa8d394e49cd2656a9643aedd2 + languageName: node + linkType: hard + +"decompress-response@npm:^6.0.0": + version: 6.0.0 + resolution: "decompress-response@npm:6.0.0" + dependencies: + mimic-response: "npm:^3.1.0" + checksum: d377cf47e02d805e283866c3f50d3d21578b779731e8c5072d6ce8c13cc31493db1c2f6784da9d1d5250822120cefa44f1deab112d5981015f2e17444b763812 + languageName: node + linkType: hard + +"defer-to-connect@npm:^2.0.0": + version: 2.0.1 + resolution: "defer-to-connect@npm:2.0.1" + checksum: 8a9b50d2f25446c0bfefb55a48e90afd58f85b21bcf78e9207cd7b804354f6409032a1705c2491686e202e64fc05f147aa5aa45f9aa82627563f045937f5791b + languageName: node + linkType: hard + +"dotenv@npm:^16.4.5": + version: 16.4.5 + resolution: "dotenv@npm:16.4.5" + checksum: 55a3134601115194ae0f924e54473459ed0d9fc340ae610b676e248cca45aa7c680d86365318ea964e6da4e2ea80c4514c1adab5adb43d6867fb57ff068f95c8 + languageName: node + linkType: hard + +"eastasianwidth@npm:^0.2.0": + version: 0.2.0 + resolution: "eastasianwidth@npm:0.2.0" + checksum: 9b1d3e1baefeaf7d70799db8774149cef33b97183a6addceeba0cf6b85ba23ee2686f302f14482006df32df75d32b17c509c143a3689627929e4a8efaf483952 + languageName: node + linkType: hard + +"emoji-regex@npm:^8.0.0": + version: 8.0.0 + resolution: "emoji-regex@npm:8.0.0" + checksum: c72d67a6821be15ec11997877c437491c313d924306b8da5d87d2a2bcc2cec9903cb5b04ee1a088460501d8e5b44f10df82fdc93c444101a7610b80c8b6938e1 + languageName: node + linkType: hard + +"emoji-regex@npm:^9.2.2": + version: 9.2.2 + resolution: "emoji-regex@npm:9.2.2" + checksum: 915acf859cea7131dac1b2b5c9c8e35c4849e325a1d114c30adb8cd615970f6dca0e27f64f3a4949d7d6ed86ecd79a1c5c63f02e697513cddd7b5835c90948b8 + languageName: node + linkType: hard + +"encoding@npm:^0.1.13": + version: 0.1.13 + resolution: "encoding@npm:0.1.13" + dependencies: + iconv-lite: "npm:^0.6.2" + checksum: bb98632f8ffa823996e508ce6a58ffcf5856330fde839ae42c9e1f436cc3b5cc651d4aeae72222916545428e54fd0f6aa8862fd8d25bdbcc4589f1e3f3715e7f + languageName: node + linkType: hard + +"end-of-stream@npm:^1.1.0": + version: 1.4.4 + resolution: "end-of-stream@npm:1.4.4" + dependencies: + once: "npm:^1.4.0" + checksum: 530a5a5a1e517e962854a31693dbb5c0b2fc40b46dad2a56a2deec656ca040631124f4795823acc68238147805f8b021abbe221f4afed5ef3c8e8efc2024908b + languageName: node + linkType: hard + +"env-paths@npm:^2.2.0": + version: 2.2.1 + resolution: "env-paths@npm:2.2.1" + checksum: 65b5df55a8bab92229ab2b40dad3b387fad24613263d103a97f91c9fe43ceb21965cd3392b1ccb5d77088021e525c4e0481adb309625d0cb94ade1d1fb8dc17e + languageName: node + linkType: hard + +"err-code@npm:^2.0.2": + version: 2.0.3 + resolution: "err-code@npm:2.0.3" + checksum: 1d20d825cdcce8d811bfbe86340f4755c02655a7feb2f13f8c880566d9d72a3f6c92c192a6867632e490d6da67b678271f46e01044996a6443e870331100dfdd + languageName: node + linkType: hard + +"escape-string-regexp@npm:^5.0.0": + version: 5.0.0 + resolution: "escape-string-regexp@npm:5.0.0" + checksum: 20daabe197f3cb198ec28546deebcf24b3dbb1a5a269184381b3116d12f0532e06007f4bc8da25669d6a7f8efb68db0758df4cd981f57bc5b57f521a3e12c59e + languageName: node + linkType: hard + +"execa@npm:^0.7.0": + version: 0.7.0 + resolution: "execa@npm:0.7.0" + dependencies: + cross-spawn: "npm:^5.0.1" + get-stream: "npm:^3.0.0" + is-stream: "npm:^1.1.0" + npm-run-path: "npm:^2.0.0" + p-finally: "npm:^1.0.0" + signal-exit: "npm:^3.0.0" + strip-eof: "npm:^1.0.0" + checksum: 7c1721de38e51d67cef2367b1f6037c4a89bc64993d93683f9f740fc74d6930dfc92faf2749b917b7337a8d632d7b86a4673400f762bc1fe4a977ea6b0f9055f + languageName: node + linkType: hard + +"execa@npm:^5.0.0": + version: 5.1.1 + resolution: "execa@npm:5.1.1" + dependencies: + cross-spawn: "npm:^7.0.3" + get-stream: "npm:^6.0.0" + human-signals: "npm:^2.1.0" + is-stream: "npm:^2.0.0" + merge-stream: "npm:^2.0.0" + npm-run-path: "npm:^4.0.1" + onetime: "npm:^5.1.2" + signal-exit: "npm:^3.0.3" + strip-final-newline: "npm:^2.0.0" + checksum: 8ada91f2d70f7dff702c861c2c64f21dfdc1525628f3c0454fd6f02fce65f7b958616cbd2b99ca7fa4d474e461a3d363824e91b3eb881705231abbf387470597 + languageName: node + linkType: hard + +"executable@npm:^4.1.0": + version: 4.1.1 + resolution: "executable@npm:4.1.1" + dependencies: + pify: "npm:^2.2.0" + checksum: f01927ce59bccec804e171bf859a26e362c1f50aa9ebc69f7cafdcce3859d29d4b6267fd47237c18b0a1830614bd3f0ee14b7380d9bad18a4e7af9b5f0b6984f + languageName: node + linkType: hard + +"exponential-backoff@npm:^3.1.1": + version: 3.1.1 + resolution: "exponential-backoff@npm:3.1.1" + checksum: 2d9bbb6473de7051f96790d5f9a678f32e60ed0aa70741dc7fdc96fec8d631124ec3374ac144387604f05afff9500f31a1d45bd9eee4cdc2e4f9ad2d9b9d5dbd + languageName: node + linkType: hard + +"ext-list@npm:^2.0.0": + version: 2.2.2 + resolution: "ext-list@npm:2.2.2" + dependencies: + mime-db: "npm:^1.28.0" + checksum: fe69fedbef044e14d4ce9e84c6afceb696ba71500c15b8d0ce0a1e280237e17c95031b3d62d5e597652fea0065b9bf957346b3900d989dff59128222231ac859 + languageName: node + linkType: hard + +"ext-name@npm:^5.0.0": + version: 5.0.0 + resolution: "ext-name@npm:5.0.0" + dependencies: + ext-list: "npm:^2.0.0" + sort-keys-length: "npm:^1.0.0" + checksum: f598269bd5de4295540ea7d6f8f6a01d82a7508f148b7700a05628ef6121648d26e6e5e942049e953b3051863df6b54bd8fe951e7877f185e34ace5d44370b33 + languageName: node + linkType: hard + +"fast-glob@npm:^3.2.5": + version: 3.3.2 + resolution: "fast-glob@npm:3.3.2" + dependencies: + "@nodelib/fs.stat": "npm:^2.0.2" + "@nodelib/fs.walk": "npm:^1.2.3" + glob-parent: "npm:^5.1.2" + merge2: "npm:^1.3.0" + micromatch: "npm:^4.0.4" + checksum: 222512e9315a0efca1276af9adb2127f02105d7288fa746145bf45e2716383fb79eb983c89601a72a399a56b7c18d38ce70457c5466218c5f13fad957cee16df + languageName: node + linkType: hard + +"fastq@npm:^1.6.0": + version: 1.17.1 + resolution: "fastq@npm:1.17.1" + dependencies: + reusify: "npm:^1.0.4" + checksum: a443180068b527dd7b3a63dc7f2a47ceca2f3e97b9c00a1efe5538757e6cc4056a3526df94308075d7727561baf09ebaa5b67da8dcbddb913a021c5ae69d1f69 + languageName: node + linkType: hard + +"file-type@npm:^17.1.6": + version: 17.1.6 + resolution: "file-type@npm:17.1.6" + dependencies: + readable-web-to-node-stream: "npm:^3.0.2" + strtok3: "npm:^7.0.0-alpha.9" + token-types: "npm:^5.0.0-alpha.2" + checksum: 47c69b4046e31142492a135982b9a9e4873b368919a2e66d0ebdc04143b6d2e1225b4bec820668c442ef201b54d03569df08b6052edc6015b1022c236784e1c1 + languageName: node + linkType: hard + +"filename-reserved-regex@npm:^3.0.0": + version: 3.0.0 + resolution: "filename-reserved-regex@npm:3.0.0" + checksum: 1803e19ce64d7cb88ee5a1bd3ce282470a5c263987269222426d889049fc857e302284fa71937de9582eba7a9f39539557d45e0562f2fa51cade8efc68c65dd9 + languageName: node + linkType: hard + +"filenamify@npm:^5.0.2": + version: 5.1.1 + resolution: "filenamify@npm:5.1.1" + dependencies: + filename-reserved-regex: "npm:^3.0.0" + strip-outer: "npm:^2.0.0" + trim-repeated: "npm:^2.0.0" + checksum: 55a7ed0858eb2655bb1bb1e945a59e3fb30ba4767f6924fa064ccd731bff07678aac3cb4f3899ae0e1621fe81d6472b5688232bb6afd4eeb989ade785fc1c6f1 + languageName: node + linkType: hard + +"fill-range@npm:^7.1.1": + version: 7.1.1 + resolution: "fill-range@npm:7.1.1" + dependencies: + to-regex-range: "npm:^5.0.1" + checksum: a7095cb39e5bc32fada2aa7c7249d3f6b01bd1ce461a61b0adabacccabd9198500c6fb1f68a7c851a657e273fce2233ba869638897f3d7ed2e87a2d89b4436ea + languageName: node + linkType: hard + +"find-versions@npm:^5.0.0": + version: 5.1.0 + resolution: "find-versions@npm:5.1.0" + dependencies: + semver-regex: "npm:^4.0.5" + checksum: 680bdb0081f631f7bfb6f0f8edcfa0b74ab8cabc82097a4527a37b0d042aabc56685bf459ff27991eab0baddc04eb8e3bba8a2869f5004ecf7cdd2779b6e51de + languageName: node + linkType: hard + +"foreground-child@npm:^3.1.0": + version: 3.1.1 + resolution: "foreground-child@npm:3.1.1" + dependencies: + cross-spawn: "npm:^7.0.0" + signal-exit: "npm:^4.0.1" + checksum: 087edd44857d258c4f73ad84cb8df980826569656f2550c341b27adf5335354393eec24ea2fabd43a253233fb27cee177ebe46bd0b7ea129c77e87cb1e9936fb + languageName: node + linkType: hard + +"fs-minipass@npm:^2.0.0": + version: 2.1.0 + resolution: "fs-minipass@npm:2.1.0" + dependencies: + minipass: "npm:^3.0.0" + checksum: 03191781e94bc9a54bd376d3146f90fe8e082627c502185dbf7b9b3032f66b0b142c1115f3b2cc5936575fc1b44845ce903dd4c21bec2a8d69f3bd56f9cee9ec + languageName: node + linkType: hard + +"fs-minipass@npm:^3.0.0": + version: 3.0.3 + resolution: "fs-minipass@npm:3.0.3" + dependencies: + minipass: "npm:^7.0.3" + checksum: af143246cf6884fe26fa281621d45cfe111d34b30535a475bfa38dafe343dadb466c047a924ffc7d6b7b18265df4110224ce3803806dbb07173bf2087b648d7f + languageName: node + linkType: hard + +"get-stream@npm:^3.0.0": + version: 3.0.0 + resolution: "get-stream@npm:3.0.0" + checksum: de14fbb3b4548ace9ab6376be852eef9898c491282e29595bc908a1814a126d3961b11cd4b7be5220019fe3b2abb84568da7793ad308fc139925a217063fa159 + languageName: node + linkType: hard + +"get-stream@npm:^5.1.0": + version: 5.2.0 + resolution: "get-stream@npm:5.2.0" + dependencies: + pump: "npm:^3.0.0" + checksum: 13a73148dca795e41421013da6e3ebff8ccb7fba4d2f023fd0c6da2c166ec4e789bec9774a73a7b49c08daf2cae552f8a3e914042ac23b5f59dd278cc8f9cbfb + languageName: node + linkType: hard + +"get-stream@npm:^6.0.0": + version: 6.0.1 + resolution: "get-stream@npm:6.0.1" + checksum: 781266d29725f35c59f1d214aedc92b0ae855800a980800e2923b3fbc4e56b3cb6e462c42e09a1cf1a00c64e056a78fa407cbe06c7c92b7e5cd49b4b85c2a497 + languageName: node + linkType: hard + +"glob-parent@npm:^5.1.2": + version: 5.1.2 + resolution: "glob-parent@npm:5.1.2" + dependencies: + is-glob: "npm:^4.0.1" + checksum: 32cd106ce8c0d83731966d31517adb766d02c3812de49c30cfe0675c7c0ae6630c11214c54a5ae67aca882cf738d27fd7768f21aa19118b9245950554be07247 + languageName: node + linkType: hard + +"glob@npm:^10.2.2, glob@npm:^10.3.10": + version: 10.4.1 + resolution: "glob@npm:10.4.1" + dependencies: + foreground-child: "npm:^3.1.0" + jackspeak: "npm:^3.1.2" + minimatch: "npm:^9.0.4" + minipass: "npm:^7.1.2" + path-scurry: "npm:^1.11.1" + bin: + glob: dist/esm/bin.mjs + checksum: d7bb49d2b413f77bdd59fea4ca86dcc12450deee221af0ca93e09534b81b9ef68fe341345751d8ff0c5b54bad422307e0e44266ff8ad7fbbd0c200e8ec258b16 + languageName: node + linkType: hard + +"got@npm:^11.8.5": + version: 11.8.6 + resolution: "got@npm:11.8.6" + dependencies: + "@sindresorhus/is": "npm:^4.0.0" + "@szmarczak/http-timer": "npm:^4.0.5" + "@types/cacheable-request": "npm:^6.0.1" + "@types/responselike": "npm:^1.0.0" + cacheable-lookup: "npm:^5.0.3" + cacheable-request: "npm:^7.0.2" + decompress-response: "npm:^6.0.0" + http2-wrapper: "npm:^1.0.0-beta.5.2" + lowercase-keys: "npm:^2.0.0" + p-cancelable: "npm:^2.0.0" + responselike: "npm:^2.0.0" + checksum: a30c74029d81bd5fe50dea1a0c970595d792c568e188ff8be254b5bc11e6158d1b014570772d4a30d0a97723e7dd34e7c8cc1a2f23018f60aece3070a7a5c2a5 + languageName: node + linkType: hard + +"graceful-fs@npm:^4.2.6": + version: 4.2.11 + resolution: "graceful-fs@npm:4.2.11" + checksum: bf152d0ed1dc159239db1ba1f74fdbc40cb02f626770dcd5815c427ce0688c2635a06ed69af364396da4636d0408fcf7d4afdf7881724c3307e46aff30ca49e2 + languageName: node + linkType: hard + +"http-cache-semantics@npm:^4.0.0, http-cache-semantics@npm:^4.1.1": + version: 4.1.1 + resolution: "http-cache-semantics@npm:4.1.1" + checksum: 362d5ed66b12ceb9c0a328fb31200b590ab1b02f4a254a697dc796850cc4385603e75f53ec59f768b2dad3bfa1464bd229f7de278d2899a0e3beffc634b6683f + languageName: node + linkType: hard + +"http-proxy-agent@npm:^7.0.0": + version: 7.0.2 + resolution: "http-proxy-agent@npm:7.0.2" + dependencies: + agent-base: "npm:^7.1.0" + debug: "npm:^4.3.4" + checksum: d062acfa0cb82beeb558f1043c6ba770ea892b5fb7b28654dbc70ea2aeea55226dd34c02a294f6c1ca179a5aa483c4ea641846821b182edbd9cc5d89b54c6848 + languageName: node + linkType: hard + +"http2-wrapper@npm:^1.0.0-beta.5.2": + version: 1.0.3 + resolution: "http2-wrapper@npm:1.0.3" + dependencies: + quick-lru: "npm:^5.1.1" + resolve-alpn: "npm:^1.0.0" + checksum: 8097ee2699440c2e64bda52124990cc5b0fb347401c7797b1a0c1efd5a0f79a4ebaa68e8a6ac3e2dde5f09460c1602764da6da2412bad628ed0a3b0ae35e72d4 + languageName: node + linkType: hard + +"https-proxy-agent@npm:^7.0.1": + version: 7.0.4 + resolution: "https-proxy-agent@npm:7.0.4" + dependencies: + agent-base: "npm:^7.0.2" + debug: "npm:4" + checksum: 405fe582bba461bfe5c7e2f8d752b384036854488b828ae6df6a587c654299cbb2c50df38c4b6ab303502c3c5e029a793fbaac965d1e86ee0be03faceb554d63 + languageName: node + linkType: hard + +"human-signals@npm:^2.1.0": + version: 2.1.0 + resolution: "human-signals@npm:2.1.0" + checksum: df59be9e0af479036798a881d1f136c4a29e0b518d4abb863afbd11bf30efa3eeb1d0425fc65942dcc05ab3bf40205ea436b0ff389f2cd20b75b8643d539bf86 + languageName: node + linkType: hard + +"iconv-lite@npm:^0.6.2": + version: 0.6.3 + resolution: "iconv-lite@npm:0.6.3" + dependencies: + safer-buffer: "npm:>= 2.1.2 < 3.0.0" + checksum: 24e3292dd3dadaa81d065c6f8c41b274a47098150d444b96e5f53b4638a9a71482921ea6a91a1f59bb71d9796de25e04afd05919fa64c360347ba65d3766f10f + languageName: node + linkType: hard + +"ieee754@npm:^1.2.1": + version: 1.2.1 + resolution: "ieee754@npm:1.2.1" + checksum: d9f2557a59036f16c282aaeb107832dc957a93d73397d89bbad4eb1130560560eb695060145e8e6b3b498b15ab95510226649a0b8f52ae06583575419fe10fc4 + languageName: node + linkType: hard + +"imurmurhash@npm:^0.1.4": + version: 0.1.4 + resolution: "imurmurhash@npm:0.1.4" + checksum: 2d30b157a91fe1c1d7c6f653cbf263f039be6c5bfa959245a16d4ee191fc0f2af86c08545b6e6beeb041c56b574d2d5b9f95343d378ab49c0f37394d541e7fc8 + languageName: node + linkType: hard + +"indent-string@npm:^4.0.0": + version: 4.0.0 + resolution: "indent-string@npm:4.0.0" + checksum: cd3f5cbc9ca2d624c6a1f53f12e6b341659aba0e2d3254ae2b4464aaea8b4294cdb09616abbc59458f980531f2429784ed6a420d48d245bcad0811980c9efae9 + languageName: node + linkType: hard + +"inherits@npm:^2.0.3": + version: 2.0.4 + resolution: "inherits@npm:2.0.4" + checksum: cd45e923bee15186c07fa4c89db0aace24824c482fb887b528304694b2aa6ff8a898da8657046a5dcf3e46cd6db6c61629551f9215f208d7c3f157cf9b290521 + languageName: node + linkType: hard + +"ip-address@npm:^9.0.5": + version: 9.0.5 + resolution: "ip-address@npm:9.0.5" + dependencies: + jsbn: "npm:1.1.0" + sprintf-js: "npm:^1.1.3" + checksum: 1ed81e06721af012306329b31f532b5e24e00cb537be18ddc905a84f19fe8f83a09a1699862bf3a1ec4b9dea93c55a3fa5faf8b5ea380431469df540f38b092c + languageName: node + linkType: hard + +"is-extglob@npm:^2.1.1": + version: 2.1.1 + resolution: "is-extglob@npm:2.1.1" + checksum: df033653d06d0eb567461e58a7a8c9f940bd8c22274b94bf7671ab36df5719791aae15eef6d83bbb5e23283967f2f984b8914559d4449efda578c775c4be6f85 + languageName: node + linkType: hard + +"is-fullwidth-code-point@npm:^3.0.0": + version: 3.0.0 + resolution: "is-fullwidth-code-point@npm:3.0.0" + checksum: 44a30c29457c7fb8f00297bce733f0a64cd22eca270f83e58c105e0d015e45c019491a4ab2faef91ab51d4738c670daff901c799f6a700e27f7314029e99e348 + languageName: node + linkType: hard + +"is-glob@npm:^4.0.1": + version: 4.0.3 + resolution: "is-glob@npm:4.0.3" + dependencies: + is-extglob: "npm:^2.1.1" + checksum: 3ed74f2b0cdf4f401f38edb0442ddfde3092d79d7d35c9919c86641efdbcbb32e45aa3c0f70ce5eecc946896cd5a0f26e4188b9f2b881876f7cb6c505b82da11 + languageName: node + linkType: hard + +"is-lambda@npm:^1.0.1": + version: 1.0.1 + resolution: "is-lambda@npm:1.0.1" + checksum: 93a32f01940220532e5948538699ad610d5924ac86093fcee83022252b363eb0cc99ba53ab084a04e4fb62bf7b5731f55496257a4c38adf87af9c4d352c71c35 + languageName: node + linkType: hard + +"is-number@npm:^7.0.0": + version: 7.0.0 + resolution: "is-number@npm:7.0.0" + checksum: 6a6c3383f68afa1e05b286af866017c78f1226d43ac8cb064e115ff9ed85eb33f5c4f7216c96a71e4dfea289ef52c5da3aef5bbfade8ffe47a0465d70c0c8e86 + languageName: node + linkType: hard + +"is-plain-obj@npm:^1.0.0": + version: 1.1.0 + resolution: "is-plain-obj@npm:1.1.0" + checksum: 0ee04807797aad50859652a7467481816cbb57e5cc97d813a7dcd8915da8195dc68c436010bf39d195226cde6a2d352f4b815f16f26b7bf486a5754290629931 + languageName: node + linkType: hard + +"is-stream@npm:^1.1.0": + version: 1.1.0 + resolution: "is-stream@npm:1.1.0" + checksum: 351aa77c543323c4e111204482808cfad68d2e940515949e31ccd0b010fc13d5fba4b9c230e4887fd24284713040f43e542332fbf172f6b9944b7d62e389c0ec + languageName: node + linkType: hard + +"is-stream@npm:^2.0.0": + version: 2.0.1 + resolution: "is-stream@npm:2.0.1" + checksum: b8e05ccdf96ac330ea83c12450304d4a591f9958c11fd17bed240af8d5ffe08aedafa4c0f4cfccd4d28dc9d4d129daca1023633d5c11601a6cbc77521f6fae66 + languageName: node + linkType: hard + +"isexe@npm:^2.0.0": + version: 2.0.0 + resolution: "isexe@npm:2.0.0" + checksum: 7c9f715c03aff08f35e98b1fadae1b9267b38f0615d501824f9743f3aab99ef10e303ce7db3f186763a0b70a19de5791ebfc854ff884d5a8c4d92211f642ec92 + languageName: node + linkType: hard + +"isexe@npm:^3.1.1": + version: 3.1.1 + resolution: "isexe@npm:3.1.1" + checksum: 7fe1931ee4e88eb5aa524cd3ceb8c882537bc3a81b02e438b240e47012eef49c86904d0f0e593ea7c3a9996d18d0f1f3be8d3eaa92333977b0c3a9d353d5563e + languageName: node + linkType: hard + +"jackspeak@npm:^3.1.2": + version: 3.3.0 + resolution: "jackspeak@npm:3.3.0" + dependencies: + "@isaacs/cliui": "npm:^8.0.2" + "@pkgjs/parseargs": "npm:^0.11.0" + dependenciesMeta: + "@pkgjs/parseargs": + optional: true + checksum: 8a72147e68cfbb8714fff4305a8b2efe02ae7ac81116355132740156973f6e520e339f8e23b01834d9f9431afd3e4616e4613f66571e0b13b9d0d52c65d3d633 + languageName: node + linkType: hard + +"jsbn@npm:1.1.0": + version: 1.1.0 + resolution: "jsbn@npm:1.1.0" + checksum: bebe7ae829bbd586ce8cbe83501dd8cb8c282c8902a8aeeed0a073a89dc37e8103b1244f3c6acd60278bcbfe12d93a3f83c9ac396868a3b3bbc3c5e5e3b648ef + languageName: node + linkType: hard + +"json-buffer@npm:3.0.1": + version: 3.0.1 + resolution: "json-buffer@npm:3.0.1" + checksum: 82876154521b7b68ba71c4f969b91572d1beabadd87bd3a6b236f85fbc7dc4695089191ed60bb59f9340993c51b33d479f45b6ba9f3548beb519705281c32c3c + languageName: node + linkType: hard + +"keyv@npm:^4.0.0": + version: 4.5.4 + resolution: "keyv@npm:4.5.4" + dependencies: + json-buffer: "npm:3.0.1" + checksum: 167eb6ef64cc84b6fa0780ee50c9de456b422a1e18802209234f7c2cf7eae648c7741f32e50d7e24ccb22b24c13154070b01563d642755b156c357431a191e75 + languageName: node + linkType: hard + +"lowercase-keys@npm:^2.0.0": + version: 2.0.0 + resolution: "lowercase-keys@npm:2.0.0" + checksum: 1c233d2da35056e8c49fae8097ee061b8c799b2f02e33c2bf32f9913c7de8fb481ab04dab7df35e94156c800f5f34e99acbf32b21781d87c3aa43ef7b748b79e + languageName: node + linkType: hard + +"lru-cache@npm:^10.0.1, lru-cache@npm:^10.2.0": + version: 10.2.2 + resolution: "lru-cache@npm:10.2.2" + checksum: ff1a496d30b5eaec2c9079080965bb0cede203cf878371f7033a007f1e54cd4aa13cc8abf7ccec4c994a83a22ed5476e83a55bb57cc07e6c1547a42937e42c37 + languageName: node + linkType: hard + +"lru-cache@npm:^4.0.1": + version: 4.1.5 + resolution: "lru-cache@npm:4.1.5" + dependencies: + pseudomap: "npm:^1.0.2" + yallist: "npm:^2.1.2" + checksum: 9ec7d73f11a32cba0e80b7a58fdf29970814c0c795acaee1a6451ddfd609bae6ef9df0837f5bbeabb571ecd49c1e2d79e10e9b4ed422cfba17a0cb6145b018a9 + languageName: node + linkType: hard + +"make-fetch-happen@npm:^13.0.0": + version: 13.0.1 + resolution: "make-fetch-happen@npm:13.0.1" + dependencies: + "@npmcli/agent": "npm:^2.0.0" + cacache: "npm:^18.0.0" + http-cache-semantics: "npm:^4.1.1" + is-lambda: "npm:^1.0.1" + minipass: "npm:^7.0.2" + minipass-fetch: "npm:^3.0.0" + minipass-flush: "npm:^1.0.5" + minipass-pipeline: "npm:^1.2.4" + negotiator: "npm:^0.6.3" + proc-log: "npm:^4.2.0" + promise-retry: "npm:^2.0.1" + ssri: "npm:^10.0.0" + checksum: 11bae5ad6ac59b654dbd854f30782f9de052186c429dfce308eda42374528185a100ee40ac9ffdc36a2b6c821ecaba43913e4730a12f06f15e895ea9cb23fa59 + languageName: node + linkType: hard + +"merge-stream@npm:^2.0.0": + version: 2.0.0 + resolution: "merge-stream@npm:2.0.0" + checksum: 6fa4dcc8d86629705cea944a4b88ef4cb0e07656ebf223fa287443256414283dd25d91c1cd84c77987f2aec5927af1a9db6085757cb43d90eb170ebf4b47f4f4 + languageName: node + linkType: hard + +"merge2@npm:^1.3.0": + version: 1.4.1 + resolution: "merge2@npm:1.4.1" + checksum: 7268db63ed5169466540b6fb947aec313200bcf6d40c5ab722c22e242f651994619bcd85601602972d3c85bd2cc45a358a4c61937e9f11a061919a1da569b0c2 + languageName: node + linkType: hard + +"micromatch@npm:^4.0.4": + version: 4.0.7 + resolution: "micromatch@npm:4.0.7" + dependencies: + braces: "npm:^3.0.3" + picomatch: "npm:^2.3.1" + checksum: a11ed1cb67dcbbe9a5fc02c4062cf8bb0157d73bf86956003af8dcfdf9b287f9e15ec0f6d6925ff6b8b5b496202335e497b01de4d95ef6cf06411bc5e5c474a0 + languageName: node + linkType: hard + +"mime-db@npm:^1.28.0": + version: 1.52.0 + resolution: "mime-db@npm:1.52.0" + checksum: 54bb60bf39e6f8689f6622784e668a3d7f8bed6b0d886f5c3c446cb3284be28b30bf707ed05d0fe44a036f8469976b2629bbea182684977b084de9da274694d7 + languageName: node + linkType: hard + +"mimic-fn@npm:^2.1.0": + version: 2.1.0 + resolution: "mimic-fn@npm:2.1.0" + checksum: d2421a3444848ce7f84bd49115ddacff29c15745db73f54041edc906c14b131a38d05298dae3081667627a59b2eb1ca4b436ff2e1b80f69679522410418b478a + languageName: node + linkType: hard + +"mimic-response@npm:^1.0.0": + version: 1.0.1 + resolution: "mimic-response@npm:1.0.1" + checksum: 034c78753b0e622bc03c983663b1cdf66d03861050e0c8606563d149bc2b02d63f62ce4d32be4ab50d0553ae0ffe647fc34d1f5281184c6e1e8cf4d85e8d9823 + languageName: node + linkType: hard + +"mimic-response@npm:^3.1.0": + version: 3.1.0 + resolution: "mimic-response@npm:3.1.0" + checksum: 7e719047612411fe071332a7498cf0448bbe43c485c0d780046c76633a771b223ff49bd00267be122cedebb897037fdb527df72335d0d0f74724604ca70b37ad + languageName: node + linkType: hard + +"minimatch@npm:^9.0.3, minimatch@npm:^9.0.4": + version: 9.0.4 + resolution: "minimatch@npm:9.0.4" + dependencies: + brace-expansion: "npm:^2.0.1" + checksum: 4cdc18d112b164084513e890d6323370db14c22249d536ad1854539577a895e690a27513dc346392f61a4a50afbbd8abc88f3f25558bfbbbb862cd56508b20f5 + languageName: node + linkType: hard + +"minipass-collect@npm:^2.0.1": + version: 2.0.1 + resolution: "minipass-collect@npm:2.0.1" + dependencies: + minipass: "npm:^7.0.3" + checksum: b251bceea62090f67a6cced7a446a36f4cd61ee2d5cea9aee7fff79ba8030e416327a1c5aa2908dc22629d06214b46d88fdab8c51ac76bacbf5703851b5ad342 + languageName: node + linkType: hard + +"minipass-fetch@npm:^3.0.0": + version: 3.0.5 + resolution: "minipass-fetch@npm:3.0.5" + dependencies: + encoding: "npm:^0.1.13" + minipass: "npm:^7.0.3" + minipass-sized: "npm:^1.0.3" + minizlib: "npm:^2.1.2" + dependenciesMeta: + encoding: + optional: true + checksum: c669948bec1373313aaa8f104b962a3ced9f45c49b26366a4b0ae27ccdfa9c5740d72c8a84d3f8623d7a61c5fc7afdfda44789008c078f61a62441142efc4a97 + languageName: node + linkType: hard + +"minipass-flush@npm:^1.0.5": + version: 1.0.5 + resolution: "minipass-flush@npm:1.0.5" + dependencies: + minipass: "npm:^3.0.0" + checksum: 56269a0b22bad756a08a94b1ffc36b7c9c5de0735a4dd1ab2b06c066d795cfd1f0ac44a0fcae13eece5589b908ecddc867f04c745c7009be0b566421ea0944cf + languageName: node + linkType: hard + +"minipass-pipeline@npm:^1.2.4": + version: 1.2.4 + resolution: "minipass-pipeline@npm:1.2.4" + dependencies: + minipass: "npm:^3.0.0" + checksum: b14240dac0d29823c3d5911c286069e36d0b81173d7bdf07a7e4a91ecdef92cdff4baaf31ea3746f1c61e0957f652e641223970870e2353593f382112257971b + languageName: node + linkType: hard + +"minipass-sized@npm:^1.0.3": + version: 1.0.3 + resolution: "minipass-sized@npm:1.0.3" + dependencies: + minipass: "npm:^3.0.0" + checksum: 40982d8d836a52b0f37049a0a7e5d0f089637298e6d9b45df9c115d4f0520682a78258905e5c8b180fb41b593b0a82cc1361d2c74b45f7ada66334f84d1ecfdd + languageName: node + linkType: hard + +"minipass@npm:^3.0.0": + version: 3.3.6 + resolution: "minipass@npm:3.3.6" + dependencies: + yallist: "npm:^4.0.0" + checksum: a5c6ef069f70d9a524d3428af39f2b117ff8cd84172e19b754e7264a33df460873e6eb3d6e55758531580970de50ae950c496256bb4ad3691a2974cddff189f0 + languageName: node + linkType: hard + +"minipass@npm:^5.0.0": + version: 5.0.0 + resolution: "minipass@npm:5.0.0" + checksum: 61682162d29f45d3152b78b08bab7fb32ca10899bc5991ffe98afc18c9e9543bd1e3be94f8b8373ba6262497db63607079dc242ea62e43e7b2270837b7347c93 + languageName: node + linkType: hard + +"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.2, minipass@npm:^7.0.3, minipass@npm:^7.1.2": + version: 7.1.2 + resolution: "minipass@npm:7.1.2" + checksum: c25f0ee8196d8e6036661104bacd743785b2599a21de5c516b32b3fa2b83113ac89a2358465bc04956baab37ffb956ae43be679b2262bf7be15fce467ccd7950 + languageName: node + linkType: hard + +"minizlib@npm:^2.1.1, minizlib@npm:^2.1.2": + version: 2.1.2 + resolution: "minizlib@npm:2.1.2" + dependencies: + minipass: "npm:^3.0.0" + yallist: "npm:^4.0.0" + checksum: ae0f45436fb51344dcb87938446a32fbebb540d0e191d63b35e1c773d47512e17307bf54aa88326cc6d176594d00e4423563a091f7266c2f9a6872cdc1e234d1 + languageName: node + linkType: hard + +"mkdirp@npm:^1.0.3": + version: 1.0.4 + resolution: "mkdirp@npm:1.0.4" + bin: + mkdirp: bin/cmd.js + checksum: d71b8dcd4b5af2fe13ecf3bd24070263489404fe216488c5ba7e38ece1f54daf219e72a833a3a2dc404331e870e9f44963a33399589490956bff003a3404d3b2 + languageName: node + linkType: hard + +"ms@npm:2.1.2": + version: 2.1.2 + resolution: "ms@npm:2.1.2" + checksum: 673cdb2c3133eb050c745908d8ce632ed2c02d85640e2edb3ace856a2266a813b30c613569bf3354fdf4ea7d1a1494add3bfa95e2713baa27d0c2c71fc44f58f + languageName: node + linkType: hard + +"negotiator@npm:^0.6.3": + version: 0.6.3 + resolution: "negotiator@npm:0.6.3" + checksum: 2723fb822a17ad55c93a588a4bc44d53b22855bf4be5499916ca0cab1e7165409d0b288ba2577d7b029f10ce18cf2ed8e703e5af31c984e1e2304277ef979837 + languageName: node + linkType: hard + +"nice-napi@npm:^1.0.2": + version: 1.0.2 + resolution: "nice-napi@npm:1.0.2" + dependencies: + node-addon-api: "npm:^3.0.0" + node-gyp: "npm:latest" + node-gyp-build: "npm:^4.2.2" + conditions: "!os=win32" + languageName: node + linkType: hard + +"node-addon-api@npm:^3.0.0": + version: 3.2.1 + resolution: "node-addon-api@npm:3.2.1" + dependencies: + node-gyp: "npm:latest" + checksum: 681b52dfa3e15b0a8e5cf283cc0d8cd5fd2a57c559ae670fcfd20544cbb32f75de7648674110defcd17ab2c76ebef630aa7d2d2f930bc7a8cc439b20fe233518 + languageName: node + linkType: hard + +"node-gyp-build@npm:^4.2.2": + version: 4.8.1 + resolution: "node-gyp-build@npm:4.8.1" + bin: + node-gyp-build: bin.js + node-gyp-build-optional: optional.js + node-gyp-build-test: build-test.js + checksum: b9297770f96a92e5f2b854f3fd5e4bd418df81d7785a81ab60cec5cf2e5e72dc2c3319808978adc572cfa3885e6b12338cb5f4034bed2cab35f0d76a4b75ccdf + languageName: node + linkType: hard + +"node-gyp@npm:latest": + version: 10.1.0 + resolution: "node-gyp@npm:10.1.0" + dependencies: + env-paths: "npm:^2.2.0" + exponential-backoff: "npm:^3.1.1" + glob: "npm:^10.3.10" + graceful-fs: "npm:^4.2.6" + make-fetch-happen: "npm:^13.0.0" + nopt: "npm:^7.0.0" + proc-log: "npm:^3.0.0" + semver: "npm:^7.3.5" + tar: "npm:^6.1.2" + which: "npm:^4.0.0" + bin: + node-gyp: bin/node-gyp.js + checksum: 89e105e495e66cd4568af3cf79cdeb67d670eb069e33163c7781d3366470a30367c9bd8dea59e46db16370020139e5bf78b1fbc03284cb571754dfaa59744db5 + languageName: node + linkType: hard + +"nopt@npm:^7.0.0": + version: 7.2.1 + resolution: "nopt@npm:7.2.1" + dependencies: + abbrev: "npm:^2.0.0" + bin: + nopt: bin/nopt.js + checksum: 95a1f6dec8a81cd18cdc2fed93e6f0b4e02cf6bdb4501c848752c6e34f9883d9942f036a5e3b21a699047d8a448562d891e67492df68ec9c373e6198133337ae + languageName: node + linkType: hard + +"normalize-url@npm:^6.0.1": + version: 6.1.0 + resolution: "normalize-url@npm:6.1.0" + checksum: 5ae699402c9d5ffa330adc348fcd6fc6e6a155ab7c811b96e30b7ecab60ceef821d8f86443869671dda71bbc47f4b9625739c82ad247e883e9aefe875bfb8659 + languageName: node + linkType: hard + +"npm-run-path@npm:^2.0.0": + version: 2.0.2 + resolution: "npm-run-path@npm:2.0.2" + dependencies: + path-key: "npm:^2.0.0" + checksum: acd5ad81648ba4588ba5a8effb1d98d2b339d31be16826a118d50f182a134ac523172101b82eab1d01cb4c2ba358e857d54cfafd8163a1ffe7bd52100b741125 + languageName: node + linkType: hard + +"npm-run-path@npm:^4.0.1": + version: 4.0.1 + resolution: "npm-run-path@npm:4.0.1" + dependencies: + path-key: "npm:^3.0.0" + checksum: 5374c0cea4b0bbfdfae62da7bbdf1e1558d338335f4cacf2515c282ff358ff27b2ecb91ffa5330a8b14390ac66a1e146e10700440c1ab868208430f56b5f4d23 + languageName: node + linkType: hard + +"once@npm:^1.3.1, once@npm:^1.4.0": + version: 1.4.0 + resolution: "once@npm:1.4.0" + dependencies: + wrappy: "npm:1" + checksum: cd0a88501333edd640d95f0d2700fbde6bff20b3d4d9bdc521bdd31af0656b5706570d6c6afe532045a20bb8dc0849f8332d6f2a416e0ba6d3d3b98806c7db68 + languageName: node + linkType: hard + +"onetime@npm:^5.1.2": + version: 5.1.2 + resolution: "onetime@npm:5.1.2" + dependencies: + mimic-fn: "npm:^2.1.0" + checksum: e9fd0695a01cf226652f0385bf16b7a24153dbbb2039f764c8ba6d2306a8506b0e4ce570de6ad99c7a6eb49520743afdb66edd95ee979c1a342554ed49a9aadd + languageName: node + linkType: hard + +"os-filter-obj@npm:^2.0.0": + version: 2.0.0 + resolution: "os-filter-obj@npm:2.0.0" + dependencies: + arch: "npm:^2.1.0" + checksum: 08808a109b2dba9be8686cc006e082a0f6595e6d87e2a30e4147cb1d22b62a30a6e5f4fd78226aee76d9158c84db3cea292adec02e6591452e93cb33bf5da877 + languageName: node + linkType: hard + +"p-cancelable@npm:^2.0.0": + version: 2.1.1 + resolution: "p-cancelable@npm:2.1.1" + checksum: 7f1b64db17fc54acf359167d62898115dcf2a64bf6b3b038e4faf36fc059e5ed762fb9624df8ed04b25bee8de3ab8d72dea9879a2a960cd12e23c420a4aca6ed + languageName: node + linkType: hard + +"p-finally@npm:^1.0.0": + version: 1.0.0 + resolution: "p-finally@npm:1.0.0" + checksum: 93a654c53dc805dd5b5891bab16eb0ea46db8f66c4bfd99336ae929323b1af2b70a8b0654f8f1eae924b2b73d037031366d645f1fd18b3d30cbd15950cc4b1d4 + languageName: node + linkType: hard + +"p-map@npm:^4.0.0": + version: 4.0.0 + resolution: "p-map@npm:4.0.0" + dependencies: + aggregate-error: "npm:^3.0.0" + checksum: 7ba4a2b1e24c05e1fc14bbaea0fc6d85cf005ae7e9c9425d4575550f37e2e584b1af97bcde78eacd7559208f20995988d52881334db16cf77bc1bcf68e48ed7c + languageName: node + linkType: hard + +"path-key@npm:^2.0.0": + version: 2.0.1 + resolution: "path-key@npm:2.0.1" + checksum: 6e654864e34386a2a8e6bf72cf664dcabb76574dd54013add770b374384d438aca95f4357bb26935b514a4e4c2c9b19e191f2200b282422a76ee038b9258c5e7 + languageName: node + linkType: hard + +"path-key@npm:^3.0.0, path-key@npm:^3.1.0": + version: 3.1.1 + resolution: "path-key@npm:3.1.1" + checksum: 55cd7a9dd4b343412a8386a743f9c746ef196e57c823d90ca3ab917f90ab9f13dd0ded27252ba49dbdfcab2b091d998bc446f6220cd3cea65db407502a740020 + languageName: node + linkType: hard + +"path-scurry@npm:^1.11.1": + version: 1.11.1 + resolution: "path-scurry@npm:1.11.1" + dependencies: + lru-cache: "npm:^10.2.0" + minipass: "npm:^5.0.0 || ^6.0.2 || ^7.0.0" + checksum: 5e8845c159261adda6f09814d7725683257fcc85a18f329880ab4d7cc1d12830967eae5d5894e453f341710d5484b8fdbbd4d75181b4d6e1eb2f4dc7aeadc434 + languageName: node + linkType: hard + +"peek-readable@npm:^5.0.0": + version: 5.0.0 + resolution: "peek-readable@npm:5.0.0" + checksum: d342f02dd0c8a6b4bd0e7519a93d545b2b19375200e79a7431f0f1ec3f91e22b2217fa3a15cde95f6ab388ce6fce8aae75794d84b9b39c5836eb7c5f55e7ee9e + languageName: node + linkType: hard + +"picomatch@npm:^2.3.1": + version: 2.3.1 + resolution: "picomatch@npm:2.3.1" + checksum: 60c2595003b05e4535394d1da94850f5372c9427ca4413b71210f437f7b2ca091dbd611c45e8b37d10036fa8eade25c1b8951654f9d3973bfa66a2ff4d3b08bc + languageName: node + linkType: hard + +"pify@npm:^2.2.0": + version: 2.3.0 + resolution: "pify@npm:2.3.0" + checksum: 9503aaeaf4577acc58642ad1d25c45c6d90288596238fb68f82811c08104c800e5a7870398e9f015d82b44ecbcbef3dc3d4251a1cbb582f6e5959fe09884b2ba + languageName: node + linkType: hard + +"piscina@npm:^4.3.0": + version: 4.5.1 + resolution: "piscina@npm:4.5.1" + dependencies: + nice-napi: "npm:^1.0.2" + dependenciesMeta: + nice-napi: + optional: true + checksum: a450140a3266920417844c11164bba208d4df2ddcb683bf3ee99d8d4b7db9de9751f5b83f6f5b2146391d18012d9f4af30a69ed751b9d4aa5eea1771a37df275 + languageName: node + linkType: hard + +"proc-log@npm:^3.0.0": + version: 3.0.0 + resolution: "proc-log@npm:3.0.0" + checksum: 02b64e1b3919e63df06f836b98d3af002b5cd92655cab18b5746e37374bfb73e03b84fe305454614b34c25b485cc687a9eebdccf0242cda8fda2475dd2c97e02 + languageName: node + linkType: hard + +"proc-log@npm:^4.2.0": + version: 4.2.0 + resolution: "proc-log@npm:4.2.0" + checksum: 4e1394491b717f6c1ade15c570ecd4c2b681698474d3ae2d303c1e4b6ab9455bd5a81566211e82890d5a5ae9859718cc6954d5150bb18b09b72ecb297beae90a + languageName: node + linkType: hard + +"promise-retry@npm:^2.0.1": + version: 2.0.1 + resolution: "promise-retry@npm:2.0.1" + dependencies: + err-code: "npm:^2.0.2" + retry: "npm:^0.12.0" + checksum: 96e1a82453c6c96eef53a37a1d6134c9f2482f94068f98a59145d0986ca4e497bf110a410adf73857e588165eab3899f0ebcf7b3890c1b3ce802abc0d65967d4 + languageName: node + linkType: hard + +"pseudomap@npm:^1.0.2": + version: 1.0.2 + resolution: "pseudomap@npm:1.0.2" + checksum: 856c0aae0ff2ad60881168334448e898ad7a0e45fe7386d114b150084254c01e200c957cf378378025df4e052c7890c5bd933939b0e0d2ecfcc1dc2f0b2991f5 + languageName: node + linkType: hard + +"pump@npm:^3.0.0": + version: 3.0.0 + resolution: "pump@npm:3.0.0" + dependencies: + end-of-stream: "npm:^1.1.0" + once: "npm:^1.3.1" + checksum: e42e9229fba14732593a718b04cb5e1cfef8254544870997e0ecd9732b189a48e1256e4e5478148ecb47c8511dca2b09eae56b4d0aad8009e6fac8072923cfc9 + languageName: node + linkType: hard + +"queue-microtask@npm:^1.2.2": + version: 1.2.3 + resolution: "queue-microtask@npm:1.2.3" + checksum: 72900df0616e473e824202113c3df6abae59150dfb73ed13273503127235320e9c8ca4aaaaccfd58cf417c6ca92a6e68ee9a5c3182886ae949a768639b388a7b + languageName: node + linkType: hard + +"quick-lru@npm:^5.1.1": + version: 5.1.1 + resolution: "quick-lru@npm:5.1.1" + checksum: a516faa25574be7947969883e6068dbe4aa19e8ef8e8e0fd96cddd6d36485e9106d85c0041a27153286b0770b381328f4072aa40d3b18a19f5f7d2b78b94b5ed + languageName: node + linkType: hard + +"readable-stream@npm:^3.6.0": + version: 3.6.2 + resolution: "readable-stream@npm:3.6.2" + dependencies: + inherits: "npm:^2.0.3" + string_decoder: "npm:^1.1.1" + util-deprecate: "npm:^1.0.1" + checksum: d9e3e53193adcdb79d8f10f2a1f6989bd4389f5936c6f8b870e77570853561c362bee69feca2bbb7b32368ce96a85504aa4cedf7cf80f36e6a9de30d64244048 + languageName: node + linkType: hard + +"readable-web-to-node-stream@npm:^3.0.2": + version: 3.0.2 + resolution: "readable-web-to-node-stream@npm:3.0.2" + dependencies: + readable-stream: "npm:^3.6.0" + checksum: d3a5bf9d707c01183d546a64864aa63df4d9cb835dfd2bf89ac8305e17389feef2170c4c14415a10d38f9b9bfddf829a57aaef7c53c8b40f11d499844bf8f1a4 + languageName: node + linkType: hard + +"resolve-alpn@npm:^1.0.0": + version: 1.2.1 + resolution: "resolve-alpn@npm:1.2.1" + checksum: 744e87888f0b6fa0b256ab454ca0b9c0b80808715e2ef1f3672773665c92a941f6181194e30ccae4a8cd0adbe0d955d3f133102636d2ee0cca0119fec0bc9aec + languageName: node + linkType: hard + +"responselike@npm:^2.0.0": + version: 2.0.1 + resolution: "responselike@npm:2.0.1" + dependencies: + lowercase-keys: "npm:^2.0.0" + checksum: b122535466e9c97b55e69c7f18e2be0ce3823c5d47ee8de0d9c0b114aa55741c6db8bfbfce3766a94d1272e61bfb1ebf0a15e9310ac5629fbb7446a861b4fd3a + languageName: node + linkType: hard + +"retry@npm:^0.12.0": + version: 0.12.0 + resolution: "retry@npm:0.12.0" + checksum: 1f914879f97e7ee931ad05fe3afa629bd55270fc6cf1c1e589b6a99fab96d15daad0fa1a52a00c729ec0078045fe3e399bd4fd0c93bcc906957bdc17f89cb8e6 + languageName: node + linkType: hard + +"reusify@npm:^1.0.4": + version: 1.0.4 + resolution: "reusify@npm:1.0.4" + checksum: 14222c9e1d3f9ae01480c50d96057228a8524706db79cdeb5a2ce5bb7070dd9f409a6f84a02cbef8cdc80d39aef86f2dd03d155188a1300c599b05437dcd2ffb + languageName: node + linkType: hard + +"run-parallel@npm:^1.1.9": + version: 1.2.0 + resolution: "run-parallel@npm:1.2.0" + dependencies: + queue-microtask: "npm:^1.2.2" + checksum: cb4f97ad25a75ebc11a8ef4e33bb962f8af8516bb2001082ceabd8902e15b98f4b84b4f8a9b222e5d57fc3bd1379c483886ed4619367a7680dad65316993021d + languageName: node + linkType: hard + +"safe-buffer@npm:5.2.1, safe-buffer@npm:~5.2.0": + version: 5.2.1 + resolution: "safe-buffer@npm:5.2.1" + checksum: 32872cd0ff68a3ddade7a7617b8f4c2ae8764d8b7d884c651b74457967a9e0e886267d3ecc781220629c44a865167b61c375d2da6c720c840ecd73f45d5d9451 + languageName: node + linkType: hard + +"safer-buffer@npm:>= 2.1.2 < 3.0.0": + version: 2.1.2 + resolution: "safer-buffer@npm:2.1.2" + checksum: 7eaf7a0cf37cc27b42fb3ef6a9b1df6e93a1c6d98c6c6702b02fe262d5fcbd89db63320793b99b21cb5348097d0a53de81bd5f4e8b86e20cc9412e3f1cfb4e83 + languageName: node + linkType: hard + +"semver-regex@npm:^4.0.5": + version: 4.0.5 + resolution: "semver-regex@npm:4.0.5" + checksum: b9e5c0573c4a997fb7e6e76321385d254797e86c8dba5e23f3cd8cf8f40b40414097a51514e5fead61dcb88ff10d3676355c01e2040f3c68f6c24bfd2073da2e + languageName: node + linkType: hard + +"semver-truncate@npm:^3.0.0": + version: 3.0.0 + resolution: "semver-truncate@npm:3.0.0" + dependencies: + semver: "npm:^7.3.5" + checksum: d8c23812218ff147f512ac4830e86860a377dba8a9733ae97d816102aca33236fa1c44c06544727153fffb93d15d0e45c49b2c40a7964aa3671769e9aed2f3f9 + languageName: node + linkType: hard + +"semver@npm:^7.3.5, semver@npm:^7.3.8, semver@npm:^7.5.3": + version: 7.6.2 + resolution: "semver@npm:7.6.2" + bin: + semver: bin/semver.js + checksum: 296b17d027f57a87ef645e9c725bff4865a38dfc9caf29b26aa084b85820972fbe7372caea1ba6857162fa990702c6d9c1d82297cecb72d56c78ab29070d2ca2 + languageName: node + linkType: hard + +"shebang-command@npm:^1.2.0": + version: 1.2.0 + resolution: "shebang-command@npm:1.2.0" + dependencies: + shebang-regex: "npm:^1.0.0" + checksum: 9eed1750301e622961ba5d588af2212505e96770ec376a37ab678f965795e995ade7ed44910f5d3d3cb5e10165a1847f52d3348c64e146b8be922f7707958908 + languageName: node + linkType: hard + +"shebang-command@npm:^2.0.0": + version: 2.0.0 + resolution: "shebang-command@npm:2.0.0" + dependencies: + shebang-regex: "npm:^3.0.0" + checksum: 6b52fe87271c12968f6a054e60f6bde5f0f3d2db483a1e5c3e12d657c488a15474121a1d55cd958f6df026a54374ec38a4a963988c213b7570e1d51575cea7fa + languageName: node + linkType: hard + +"shebang-regex@npm:^1.0.0": + version: 1.0.0 + resolution: "shebang-regex@npm:1.0.0" + checksum: 404c5a752cd40f94591dfd9346da40a735a05139dac890ffc229afba610854d8799aaa52f87f7e0c94c5007f2c6af55bdcaeb584b56691926c5eaf41dc8f1372 + languageName: node + linkType: hard + +"shebang-regex@npm:^3.0.0": + version: 3.0.0 + resolution: "shebang-regex@npm:3.0.0" + checksum: 1a2bcae50de99034fcd92ad4212d8e01eedf52c7ec7830eedcf886622804fe36884278f2be8be0ea5fde3fd1c23911643a4e0f726c8685b61871c8908af01222 + languageName: node + linkType: hard + +"signal-exit@npm:^3.0.0, signal-exit@npm:^3.0.3": + version: 3.0.7 + resolution: "signal-exit@npm:3.0.7" + checksum: a2f098f247adc367dffc27845853e9959b9e88b01cb301658cfe4194352d8d2bb32e18467c786a7fe15f1d44b233ea35633d076d5e737870b7139949d1ab6318 + languageName: node + linkType: hard + +"signal-exit@npm:^4.0.1": + version: 4.1.0 + resolution: "signal-exit@npm:4.1.0" + checksum: c9fa63bbbd7431066174a48ba2dd9986dfd930c3a8b59de9c29d7b6854ec1c12a80d15310869ea5166d413b99f041bfa3dd80a7947bcd44ea8e6eb3ffeabfa1f + languageName: node + linkType: hard + +"slash@npm:3.0.0": + version: 3.0.0 + resolution: "slash@npm:3.0.0" + checksum: 94a93fff615f25a999ad4b83c9d5e257a7280c90a32a7cb8b4a87996e4babf322e469c42b7f649fd5796edd8687652f3fb452a86dc97a816f01113183393f11c + languageName: node + linkType: hard + +"smart-buffer@npm:^4.2.0": + version: 4.2.0 + resolution: "smart-buffer@npm:4.2.0" + checksum: 927484aa0b1640fd9473cee3e0a0bcad6fce93fd7bbc18bac9ad0c33686f5d2e2c422fba24b5899c184524af01e11dd2bd051c2bf2b07e47aff8ca72cbfc60d2 + languageName: node + linkType: hard + +"socks-proxy-agent@npm:^8.0.3": + version: 8.0.3 + resolution: "socks-proxy-agent@npm:8.0.3" + dependencies: + agent-base: "npm:^7.1.1" + debug: "npm:^4.3.4" + socks: "npm:^2.7.1" + checksum: c2112c66d6322e497d68e913c3780f3683237fd394bfd480b9283486a86e36095d0020db96145d88f8ccd9cc73261b98165b461f9c1bf5dc17abfe75c18029ce + languageName: node + linkType: hard + +"socks@npm:^2.7.1": + version: 2.8.3 + resolution: "socks@npm:2.8.3" + dependencies: + ip-address: "npm:^9.0.5" + smart-buffer: "npm:^4.2.0" + checksum: ffcb622c22481dfcd7589aae71fbfd71ca34334064d181df64bf8b7feaeee19706aba4cffd1de35cc7bbaeeaa0af96be2d7f40fcbc7bc0ab69533a7ae9ffc4fb + languageName: node + linkType: hard + +"sort-keys-length@npm:^1.0.0": + version: 1.0.1 + resolution: "sort-keys-length@npm:1.0.1" + dependencies: + sort-keys: "npm:^1.0.0" + checksum: f9acac5fb31580a9e3d43b419dc86a1b75e85b79036a084d95dd4d1062b621c9589906588ac31e370a0dd381be46d8dbe900efa306d087ca9c912d7a59b5a590 + languageName: node + linkType: hard + +"sort-keys@npm:^1.0.0": + version: 1.1.2 + resolution: "sort-keys@npm:1.1.2" + dependencies: + is-plain-obj: "npm:^1.0.0" + checksum: 0ac2ea2327d92252f07aa7b2f8c7023a1f6ce3306439a3e81638cce9905893c069521d168f530fb316d1a929bdb052b742969a378190afaef1bc64fa69e29576 + languageName: node + linkType: hard + +"source-map@npm:^0.7.3": + version: 0.7.4 + resolution: "source-map@npm:0.7.4" + checksum: a0f7c9b797eda93139842fd28648e868a9a03ea0ad0d9fa6602a0c1f17b7fb6a7dcca00c144476cccaeaae5042e99a285723b1a201e844ad67221bf5d428f1dc + languageName: node + linkType: hard + +"sprintf-js@npm:^1.1.3": + version: 1.1.3 + resolution: "sprintf-js@npm:1.1.3" + checksum: e7587128c423f7e43cc625fe2f87e6affdf5ca51c1cc468e910d8aaca46bb44a7fbcfa552f787b1d3987f7043aeb4527d1b99559e6621e01b42b3f45e5a24cbb + languageName: node + linkType: hard + +"ssri@npm:^10.0.0": + version: 10.0.6 + resolution: "ssri@npm:10.0.6" + dependencies: + minipass: "npm:^7.0.3" + checksum: f92c1b3cc9bfd0a925417412d07d999935917bc87049f43ebec41074661d64cf720315661844106a77da9f8204b6d55ae29f9514e673083cae39464343af2a8b + languageName: node + linkType: hard + +"string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^4.1.0": + version: 4.2.3 + resolution: "string-width@npm:4.2.3" + dependencies: + emoji-regex: "npm:^8.0.0" + is-fullwidth-code-point: "npm:^3.0.0" + strip-ansi: "npm:^6.0.1" + checksum: e52c10dc3fbfcd6c3a15f159f54a90024241d0f149cf8aed2982a2d801d2e64df0bf1dc351cf8e95c3319323f9f220c16e740b06faecd53e2462df1d2b5443fb + languageName: node + linkType: hard + +"string-width@npm:^5.0.1, string-width@npm:^5.1.2": + version: 5.1.2 + resolution: "string-width@npm:5.1.2" + dependencies: + eastasianwidth: "npm:^0.2.0" + emoji-regex: "npm:^9.2.2" + strip-ansi: "npm:^7.0.1" + checksum: 7369deaa29f21dda9a438686154b62c2c5f661f8dda60449088f9f980196f7908fc39fdd1803e3e01541970287cf5deae336798337e9319a7055af89dafa7193 + languageName: node + linkType: hard + +"string_decoder@npm:^1.1.1": + version: 1.3.0 + resolution: "string_decoder@npm:1.3.0" + dependencies: + safe-buffer: "npm:~5.2.0" + checksum: 54d23f4a6acae0e93f999a585e673be9e561b65cd4cca37714af1e893ab8cd8dfa52a9e4f58f48f87b4a44918d3a9254326cb80ed194bf2e4c226e2b21767e56 + languageName: node + linkType: hard + +"strip-ansi-cjs@npm:strip-ansi@^6.0.1, strip-ansi@npm:^6.0.0, strip-ansi@npm:^6.0.1": + version: 6.0.1 + resolution: "strip-ansi@npm:6.0.1" + dependencies: + ansi-regex: "npm:^5.0.1" + checksum: ae3b5436d34fadeb6096367626ce987057713c566e1e7768818797e00ac5d62023d0f198c4e681eae9e20701721980b26a64a8f5b91238869592a9c6800719a2 + languageName: node + linkType: hard + +"strip-ansi@npm:^7.0.1": + version: 7.1.0 + resolution: "strip-ansi@npm:7.1.0" + dependencies: + ansi-regex: "npm:^6.0.1" + checksum: 475f53e9c44375d6e72807284024ac5d668ee1d06010740dec0b9744f2ddf47de8d7151f80e5f6190fc8f384e802fdf9504b76a7e9020c9faee7103623338be2 + languageName: node + linkType: hard + +"strip-eof@npm:^1.0.0": + version: 1.0.0 + resolution: "strip-eof@npm:1.0.0" + checksum: 40bc8ddd7e072f8ba0c2d6d05267b4e0a4800898c3435b5fb5f5a21e6e47dfaff18467e7aa0d1844bb5d6274c3097246595841fbfeb317e541974ee992cac506 + languageName: node + linkType: hard + +"strip-final-newline@npm:^2.0.0": + version: 2.0.0 + resolution: "strip-final-newline@npm:2.0.0" + checksum: 69412b5e25731e1938184b5d489c32e340605bb611d6140344abc3421b7f3c6f9984b21dff296dfcf056681b82caa3bb4cc996a965ce37bcfad663e92eae9c64 + languageName: node + linkType: hard + +"strip-outer@npm:^2.0.0": + version: 2.0.0 + resolution: "strip-outer@npm:2.0.0" + checksum: 14ef9fe861e59a5f1555f1860982ae4edce2edb4ed34ab1b37cb62a8ba2f7c3540cbca6c884eabe4006e6cd729ab5d708a631169dd5b66fda570836e7e3b6589 + languageName: node + linkType: hard + +"strtok3@npm:^7.0.0-alpha.9": + version: 7.0.0 + resolution: "strtok3@npm:7.0.0" + dependencies: + "@tokenizer/token": "npm:^0.3.0" + peek-readable: "npm:^5.0.0" + checksum: 4f2269679fcfce1e9fe0600eff361ea4c687ae0a0e8d9dab6703811071cd92545cbcb32d4ace3d3aa591f777cec1a3e8aeecd5efd71ae216fd2962a7a238b4ab + languageName: node + linkType: hard + +"tar@npm:^6.1.11, tar@npm:^6.1.2": + version: 6.2.1 + resolution: "tar@npm:6.2.1" + dependencies: + chownr: "npm:^2.0.0" + fs-minipass: "npm:^2.0.0" + minipass: "npm:^5.0.0" + minizlib: "npm:^2.1.1" + mkdirp: "npm:^1.0.3" + yallist: "npm:^4.0.0" + checksum: bfbfbb2861888077fc1130b84029cdc2721efb93d1d1fb80f22a7ac3a98ec6f8972f29e564103bbebf5e97be67ebc356d37fa48dbc4960600a1eb7230fbd1ea0 + languageName: node + linkType: hard + +"to-regex-range@npm:^5.0.1": + version: 5.0.1 + resolution: "to-regex-range@npm:5.0.1" + dependencies: + is-number: "npm:^7.0.0" + checksum: 10dda13571e1f5ad37546827e9b6d4252d2e0bc176c24a101252153ef435d83696e2557fe128c4678e4e78f5f01e83711c703eef9814eb12dab028580d45980a + languageName: node + linkType: hard + +"token-types@npm:^5.0.0-alpha.2": + version: 5.0.1 + resolution: "token-types@npm:5.0.1" + dependencies: + "@tokenizer/token": "npm:^0.3.0" + ieee754: "npm:^1.2.1" + checksum: 0985369bbea9f53a5ccd79bb9899717b41401a813deb2c7fb1add5d0baf2f702aaf6da78f6e0ccf346d5a9f7acaa7cb5efed7d092d89d8c1e6962959e9509bc0 + languageName: node + linkType: hard + +"trim-repeated@npm:^2.0.0": + version: 2.0.0 + resolution: "trim-repeated@npm:2.0.0" + dependencies: + escape-string-regexp: "npm:^5.0.0" + checksum: 4086eb0bc560f3da0370f427f423db4e3fc0a8e1560ecffc3b68512071319fe82dc9dd86d76b981d36ada76d7d49c3f8897ac054c87bc177e7a25abfd29e2bcd + languageName: node + linkType: hard + +"tweetnacl@npm:^1.0.3": + version: 1.0.3 + resolution: "tweetnacl@npm:1.0.3" + checksum: ca122c2f86631f3c0f6d28efb44af2a301d4a557a62a3e2460286b08e97567b258c2212e4ad1cfa22bd6a57edcdc54ba76ebe946847450ab0999e6d48ccae332 + languageName: node + linkType: hard + +"typescript@npm:^5.5.2": + version: 5.5.2 + resolution: "typescript@npm:5.5.2" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 9118b20f248e76b0dbff8737fef65dfa89d02668d4e633d2c5ceac99033a0ca5e8a1c1a53bc94da68e8f67677a88f318663dde859c9e9a09c1e116415daec2ba + languageName: node + linkType: hard + +"typescript@patch:typescript@npm%3A^5.5.2#optional!builtin": + version: 5.5.2 + resolution: "typescript@patch:typescript@npm%3A5.5.2#optional!builtin::version=5.5.2&hash=e012d7" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 28b3de2ddaf63a7620e7ddbe5d377af71ce93ecc558c41bf0e3d88661d8e6e7aa6c7739164fef98055f69819e41faca49252938ef3633a3dff2734cca6a9042e + languageName: node + linkType: hard + +"undici-types@npm:~5.26.4": + version: 5.26.5 + resolution: "undici-types@npm:5.26.5" + checksum: 0097779d94bc0fd26f0418b3a05472410408877279141ded2bd449167be1aed7ea5b76f756562cb3586a07f251b90799bab22d9019ceba49c037c76445f7cddd + languageName: node + linkType: hard + +"unique-filename@npm:^3.0.0": + version: 3.0.0 + resolution: "unique-filename@npm:3.0.0" + dependencies: + unique-slug: "npm:^4.0.0" + checksum: 8e2f59b356cb2e54aab14ff98a51ac6c45781d15ceaab6d4f1c2228b780193dc70fae4463ce9e1df4479cb9d3304d7c2043a3fb905bdeca71cc7e8ce27e063df + languageName: node + linkType: hard + +"unique-slug@npm:^4.0.0": + version: 4.0.0 + resolution: "unique-slug@npm:4.0.0" + dependencies: + imurmurhash: "npm:^0.1.4" + checksum: 40912a8963fc02fb8b600cf50197df4a275c602c60de4cac4f75879d3c48558cfac48de08a25cc10df8112161f7180b3bbb4d662aadb711568602f9eddee54f0 + languageName: node + linkType: hard + +"util-deprecate@npm:^1.0.1": + version: 1.0.2 + resolution: "util-deprecate@npm:1.0.2" + checksum: 474acf1146cb2701fe3b074892217553dfcf9a031280919ba1b8d651a068c9b15d863b7303cb15bd00a862b498e6cf4ad7b4a08fb134edd5a6f7641681cb54a2 + languageName: node + linkType: hard + +"which@npm:^1.2.9": + version: 1.3.1 + resolution: "which@npm:1.3.1" + dependencies: + isexe: "npm:^2.0.0" + bin: + which: ./bin/which + checksum: 549dcf1752f3ee7fbb64f5af2eead4b9a2f482108b7de3e85c781d6c26d8cf6a52d37cfbe0642a155fa6470483fe892661a859c03157f24c669cf115f3bbab5e + languageName: node + linkType: hard + +"which@npm:^2.0.1": + version: 2.0.2 + resolution: "which@npm:2.0.2" + dependencies: + isexe: "npm:^2.0.0" + bin: + node-which: ./bin/node-which + checksum: 4782f8a1d6b8fc12c65e968fea49f59752bf6302dc43036c3bf87da718a80710f61a062516e9764c70008b487929a73546125570acea95c5b5dcc8ac3052c70f + languageName: node + linkType: hard + +"which@npm:^4.0.0": + version: 4.0.0 + resolution: "which@npm:4.0.0" + dependencies: + isexe: "npm:^3.1.1" + bin: + node-which: bin/which.js + checksum: f17e84c042592c21e23c8195108cff18c64050b9efb8459589116999ea9da6dd1509e6a1bac3aeebefd137be00fabbb61b5c2bc0aa0f8526f32b58ee2f545651 + languageName: node + linkType: hard + +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": + version: 7.0.0 + resolution: "wrap-ansi@npm:7.0.0" + dependencies: + ansi-styles: "npm:^4.0.0" + string-width: "npm:^4.1.0" + strip-ansi: "npm:^6.0.0" + checksum: cebdaeca3a6880da410f75209e68cd05428580de5ad24535f22696d7d9cab134d1f8498599f344c3cf0fb37c1715807a183778d8c648d6cc0cb5ff2bb4236540 + languageName: node + linkType: hard + +"wrap-ansi@npm:^8.1.0": + version: 8.1.0 + resolution: "wrap-ansi@npm:8.1.0" + dependencies: + ansi-styles: "npm:^6.1.0" + string-width: "npm:^5.0.1" + strip-ansi: "npm:^7.0.1" + checksum: 7b1e4b35e9bb2312d2ee9ee7dc95b8cb5f8b4b5a89f7dde5543fe66c1e3715663094defa50d75454ac900bd210f702d575f15f3f17fa9ec0291806d2578d1ddf + languageName: node + linkType: hard + +"wrappy@npm:1": + version: 1.0.2 + resolution: "wrappy@npm:1.0.2" + checksum: 159da4805f7e84a3d003d8841557196034155008f817172d4e986bd591f74aa82aa7db55929a54222309e01079a65a92a9e6414da5a6aa4b01ee44a511ac3ee5 + languageName: node + linkType: hard + +"ws@npm:^8.16.0": + version: 8.17.1 + resolution: "ws@npm:8.17.1" + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ">=5.0.2" + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: 4264ae92c0b3e59c7e309001e93079b26937aab181835fb7af79f906b22cd33b6196d96556dafb4e985742dd401e99139572242e9847661fdbc96556b9e6902d + languageName: node + linkType: hard + +"yallist@npm:^2.1.2": + version: 2.1.2 + resolution: "yallist@npm:2.1.2" + checksum: 75fc7bee4821f52d1c6e6021b91b3e079276f1a9ce0ad58da3c76b79a7e47d6f276d35e206a96ac16c1cf48daee38a8bb3af0b1522a3d11c8ffe18f898828832 + languageName: node + linkType: hard + +"yallist@npm:^4.0.0": + version: 4.0.0 + resolution: "yallist@npm:4.0.0" + checksum: 4cb02b42b8a93b5cf50caf5d8e9beb409400a8a4d85e83bb0685c1457e9ac0b7a00819e9f5991ac25ffabb56a78e2f017c1acc010b3a1babfe6de690ba531abd + languageName: node + linkType: hard diff --git a/examples/bigbot/.dockerignore b/examples/bigbot/.dockerignore new file mode 100644 index 000000000..eff53cf82 --- /dev/null +++ b/examples/bigbot/.dockerignore @@ -0,0 +1,31 @@ +# Include any files or directories that you don't want to be copied to your +# container here (e.g., local build artifacts, temporary files, etc.). +# +# For more help, visit the .dockerignore file reference guide at +# https://docs.docker.com/go/build-context-dockerignore/ + + +# local env files +.env +.env.local +.env.development.local +.env.test.local +.env.production.local + +# Git files +.git +.gitignore + +# Docker files +.dockerignore +docker-compose* +compose.y*ml +Dockerfile* + +# Local build files +node_modules +dist +.yarn + +LICENSE +README.md diff --git a/examples/bigbot/.env.example b/examples/bigbot/.env.example index 6f525fcf8..12de839af 100644 --- a/examples/bigbot/.env.example +++ b/examples/bigbot/.env.example @@ -1,104 +1,142 @@ -# For Prisma use. Remember to remove the [ and ] -DATABASE_URL=postgres:#[username]:[password]@[host]:[port]/[db] - -# For other configs, update src/configs.ts - +# # General Configurations -# Whether or not this process is a local development version. Change to false for the main production bot. */ -# SETUP-DD-TEMP: Change this to false in your server for production bot. Keep true in local testing. +# + +# Whether or not this process is a local development version +# In production this value should be set to false +# TEMPLATE-SETUP: When deploying, set this value to false DEVELOPMENT=true -# The server id where you develop/test the bot. */ -# SETUP-DD-TEMP: Change the id to a server where you develop the bot privately. +# The server id where you develop/test the bot +# TEMPLATE-SETUP: Add the id to a server where you develop the bot DEV_SERVER_ID= -# The discord bot token, without the BOT prefix. */ -# SETUP-DD-TEMP: Add the bot token here. +# The discord bot token +# NOTE: It should not be prefixed with Bot +# TEMPLATE-SETUP: Add the bot token here. DISCORD_TOKEN= -# Bot Configurations -# The secret passcode that the bot code (event handler) is listening for. This is used to prevent someone else from trying to send malicious messages to your bot. */ -# SETUP-DD-TEMP: Add a secret passcode here. -EVENT_HANDLER_AUTHORIZATION=SuperSecretPassword +# +# Bot Configuration +# -# The host where the event handler will run. Must follow https:#nodejs.org/api/net.html#serverlistenoptions-callback. */ -# SETUP-DD-TEMP: Set the event handler's host here. +# NOTE: With "bot code" we refer to the code that will handle the events + +# The secret passcode that the bot code is checking for +# This is used to prevent someone else from trying to send malicious events to your bot +# TEMPLATE-SETUP: Add a secret passcode here. It can be whatever you want +EVENT_HANDLER_AUTHORIZATION= + +# The host where the event handler will run +# Will be used together with EVENT_HANDLER_PORT to compose the HTTP url to send the events to +# TEMPLATE-SETUP: Set the event handler's host here EVENT_HANDLER_HOST=localhost -# The port where the event handler is listening for events. */ -# SETUP-DD-TEMP: Set the desired port where events will be sent to be processed. +# The port where the event handler will listening for events +# TEMPLATE-SETUP: Set the port where events will be sent EVENT_HANDLER_PORT=8081 -# The full webhook url where the bot can send errors to alert you that the bot is missing translations. */ -# SETUP-DD-TEMP: Set a full discord webhook url here. -MISSING_TRANSLATION_WEBHOOK= - -# The full webhook url where the bot can send errors to alert you that the bot is throwing errors. */ -# SETUP-DD-TEMP: Set a full discord webhook url here. +# The full webhook url where the bot can send errors to alert you that the bot is throwing errors. +# TEMPLATE-SETUP: Add the full discord webhook url BUGS_ERRORS_REPORT_WEBHOOK= +# # Rest Proxy Configurations -# The authorization code that the REST proxy will check for to make sure the requests are coming from you. */ -# SETUP-DD-TEMP: Add a secret passcode here. -REST_AUTHORIZATION=password123 +# -# The host where the REST proxy will run. Must follow https:#nodejs.org/api/net.html#serverlistenoptions-callback. */ -# SETUP-DD-TEMP: Set the REST proxy's host here. +# The passcode that the REST proxy is checking for +# This is used to prevent someone else from trying to send malicious API requests from your bot +# TEMPLATE-SETUP: Add a secret passcode here. It can be whatever you want +REST_AUTHORIZATION= + +# The host where the REST proxy will run +# Will be used together with REST_PORT to compose the HTTP url to send the API requests to +# TEMPLATE-SETUP: Set the REST proxy's host here REST_HOST=localhost -# The port that will run the REST proxy. */ -# SETUP-DD-TEMP: Choose the port number here that will be used for the REST proxy. +# The port where the REST proxy will listen for API requests +# TEMPLATE-SETUP: Set the port where API requests will be sent REST_PORT=8000 +# # Gateway Proxy Configurations +# -# The amount of shards to start. Useful with multiple servers where each server is handling a portion of your bot. */ -# SETUP-DD-TEMP: To start all bots, leave it as undefined. Specify he number of shards this process should handle. +# The amount of shards to start +# Useful with multiple servers where each server is handling a portion of your bot +# OPTIONAL: You can leave this value unspecified if you want this server to manage all shards +# TEMPLATE-SETUP: If you have separate servers, add the number of shards this process should handle TOTAL_SHARDS= -# The amount of shards to start per worker. */ -# SETUP-DD-TEMP: Choose how many shards to start per worker. If you are not sure just stick to 16. +# The amount of shards to start per worker. +# NOTE: If you are not sure just stick to 16 +# TEMPLATE-SETUP: Set how many shards to start per worker SHARDS_PER_WORKER=16 -# The total amount of workers to start. Generally this should be equal to the number of cores your server has. */ -# SETUP-DD-TEMP: Choose how many workers to start up. If you are not sure, check how many cores your server has. +# The total amount of workers to start. +# NOTE: Generally this should be equal to the number of cores your server has +# TEMPLATE-SETUP: Choose how many workers to start up TOTAL_WORKERS=4 -# The secret passcode that the gateway is listening for. This is used to prevent someone else from trying to send malicious messages to your bot. */ -# SETUP-DD-TEMP: Add a secret passcode here. +# The passcode that the gateway is checking for +# This is used to prevent someone else from trying to send malicious messages to your bot +# TEMPLATE-SETUP: Set a secret passcode here. It can be whatever you want GATEWAY_AUTHORIZATION= -# The host where the gateway will run. Must follow https:#nodejs.org/api/net.html#serverlistenoptions-callback. */ -# SETUP-DD-TEMP: Set the gateways's host here. +# The host where the gateway will run +# Will be used together with GATEWAY_PORT to compose the HTTP url to send the gateway messages to +# TEMPLATE-SETUP: Set the gateway's host here GATEWAY_HOST=localhost -# The port where the gateway will run. This is where the bot will send its messages to the gateway. */ -# SETUP-DD-TEMP: Set the gateways's port here. +# The port where the gateway will listen for gateway messages +# TEMPLATE-SETUP: Set the port where gateway messages will be sent GATEWAY_PORT=8080 -# Messsage queue / RabbitMQ configuration -# enable using messages queue to send messages from gateway to bot +# +# Message queue (RabbitMQ configuration) +# + +# Whatever to queue messages from the gateway to bot +# NOTE: If this is set to true, all other configuration in this section are requried +# NOTE: if this is set to false, gateway messages will be sent directly to the bot code, and will fail if the bot code is not running MESSAGEQUEUE_ENABLE=false -# The url of the message queue -MESSAGEQUEUE_URL=rabbitmq:5672 +# The url of the RabbitMQ instance +MESSAGEQUEUE_URL=localhost:5672 -# username and password for the message queue -MESSAGEQUEUE_USERNAME=guest -MESSAGEQUEUE_PASSWORD=guest +# Username for the authentication against the RabbitMQ instance +MESSAGEQUEUE_USERNAME= -# Database Configurations +# Password for the authentication against the RabbitMQ instance +MESSAGEQUEUE_PASSWORD= -# These INFLUX configs are only if you wish to enable analytics. */ -# SETUP-DD-TEMP: This is optional. If you want to build analytics, add influxdb here. +# +# Analytics (InfluxDB configuration) +# + +# NOTE: This entire section is optional +# TEMPLATE-SETUP: If you want to enable analytics, add the the following values + +# The InfluxDB organization INFLUX_ORG= + +# The InfluxDB bucket INFLUX_BUCKET= + +# The InfluxDB secret API token +# NOTE: this may need to be in quotes ("...") if it contains the = sign INFLUX_TOKEN= -INFLUX_URL=http://influxdb:8086 + +# The InfluxDB Instance url +INFLUX_URL=http://localhost:8086 + +# +# Docker InfluxDB +# DOCKER_INFLUXDB_INIT_MODE=setup -DOCKER_INFLUXDB_INIT_USERNAME=skillz -DOCKER_INFLUXDB_INIT_PASSWORD=ILoveskillz +DOCKER_INFLUXDB_INIT_USERNAME=discordeno +DOCKER_INFLUXDB_INIT_PASSWORD=discordeno DOCKER_INFLUXDB_INIT_ORG=discordeno DOCKER_INFLUXDB_INIT_BUCKET=discordeno -DOCKER_INFLUXDB_INIT_ADMIN_TOKEN=skillzPrefersID +DOCKER_INFLUXDB_INIT_ADMIN_TOKEN=discordeno diff --git a/examples/bigbot/.gitignore b/examples/bigbot/.gitignore index 76add878f..4bc2fcfaf 100644 --- a/examples/bigbot/.gitignore +++ b/examples/bigbot/.gitignore @@ -1,2 +1,32 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies node_modules -dist \ No newline at end of file + +.pnp.* +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/sdks +!.yarn/versions + +# build +dist + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.pnpm-debug.log* + +# local env files +.env +.env.local +.env.development.local +.env.test.local +.env.production.local diff --git a/examples/bigbot/.swcrc b/examples/bigbot/.swcrc index 1ac85e6bd..751b8edf8 100644 --- a/examples/bigbot/.swcrc +++ b/examples/bigbot/.swcrc @@ -1,25 +1,24 @@ { - "$schema": "https://json.schemastore.org/swcrc", - "jsc": { - "parser": { - "syntax": "typescript", - "decorators": true, - "dynamicImport": true - }, - "transform": { - "legacyDecorator": true, - "decoratorMetadata": true - }, - "target": "es2022", - "keepClassNames": true, - "loose": true - }, - "module": { - "type": "es6", - "strict": false, - "strictMode": true, - "lazy": false, - "noInterop": false - }, - "sourceMaps": true -} \ No newline at end of file + "$schema": "https://json.schemastore.org/swcrc", + "jsc": { + "parser": { + "syntax": "typescript", + "decorators": true, + "dynamicImport": true + }, + "transform": { + "legacyDecorator": true, + "decoratorMetadata": true + }, + "target": "es2022", + "keepClassNames": true, + "loose": true + }, + "module": { + "type": "es6", + "strict": false, + "strictMode": true, + "lazy": false, + "noInterop": false + } +} diff --git a/examples/bigbot/.yarnrc.yml b/examples/bigbot/.yarnrc.yml new file mode 100644 index 000000000..1e1db93ad --- /dev/null +++ b/examples/bigbot/.yarnrc.yml @@ -0,0 +1,4 @@ +# This file is needed or else when yarn runs in `docker build` will attempt to use PnP +compressionLevel: mixed +enableGlobalCache: false +nodeLinker: node-modules diff --git a/examples/bigbot/Dockerfile b/examples/bigbot/Dockerfile index cbb98b230..7d98d341d 100644 --- a/examples/bigbot/Dockerfile +++ b/examples/bigbot/Dockerfile @@ -1,37 +1,75 @@ -FROM node:16.18.0-alpine3.16 AS deps -WORKDIR /app -COPY package.json package-lock.json .swcrc ./ -RUN npm install +# syntax=docker/dockerfile:1 -FROM node:16.18.0-alpine3.16 as rest -COPY --from=deps /app /app -WORKDIR /app -COPY src/analytics.ts src/configs.ts src/ -COPY src/rest src/rest -RUN npm run build +ARG NODE_VERSION=20 + +################################################################################ + +FROM node:${NODE_VERSION}-alpine as base + +# Set working directory for all build stages. +WORKDIR /usr/src/app + +# Enable corepack so it can install the needed yarn version +RUN corepack enable + +COPY package.json . +COPY yarn.lock . +# We need to copy the yarnrc or else yarn will attempt to use PnP +COPY .yarnrc.yml . + +RUN yarn install + +# Copy the rest of the source files into the image. +COPY . . + +# Run the build script. +RUN yarn build + +# Use production node environment by default. +ENV NODE_ENV production + +# Run the application as a non-root user. +USER node + +################################################################################ + +FROM base as rest + +# Expose the port that the application listens on. EXPOSE 8000 -CMD ["npm","run","startr"] -FROM node:16.18.0-alpine3.16 as gateway -COPY --from=deps /app /app -WORKDIR /app -COPY src/configs.ts src/ -COPY src/gateway src/gateway -RUN npm run build +# Run the application. +CMD node dist/rest/index.js + +################################################################################ + +FROM base as gateway + +# Expose the port that the application listens on. EXPOSE 8080 -CMD ["npm","run","startg"] -FROM node:16.18.0-alpine3.16 as bot -COPY --from=deps /app /app -WORKDIR /app -COPY prisma prisma -COPY node_modules/.prisma/client node_modules/.prisma/client -COPY src/analytics.ts src/prisma.ts src/configs.ts src/ -COPY src/bot src/bot -RUN npm run build -EXPOSE 8080 -CMD ["npm","run","startb"] +# Run the application. +CMD node dist/gateway/index.js -FROM rabbitmq:3.11.2-management-alpine as rabbitmq -COPY src/rabbitmq/plugins plugins +################################################################################ + +FROM base as bot + +# Expose the port that the application listens on. +EXPOSE 8081 + +# Run the application. +CMD node dist/bot/index.js + +################################################################################ + +FROM rabbitmq:3.12-management-alpine as rabbitmq + +# Copy the rabbitmq plugins +COPY rabbitmq/plugins/** plugins + +HEALTHCHECK CMD [ "rabbitmq-diagnostics", "-q", "status" ] \ + --interval=30s --timeout=30s --start-period=30s --retries=5 + +# Enable the required plugins RUN rabbitmq-plugins enable rabbitmq_message_deduplication diff --git a/examples/bigbot/README.md b/examples/bigbot/README.md index 5cff93acd..0d5275fb3 100644 --- a/examples/bigbot/README.md +++ b/examples/bigbot/README.md @@ -1,66 +1,105 @@ -# Discordeno Big Bot Template +# Big Bot Template -Support: +> [!TIP] +> If you have any issue you can join the discord server for support: https://discord.gg/ddeno -This template is designed for bots that aim or are already in millions of Discord servers. It is written with Node.js as -currently Deno & Bun are not ready to run something at such a scale. The general idea of this template can be modified -for any other runtime if this improves in the future. - -Make sure to install the latest version when you use it. +This template is designed for bots that aim to be in millions of Discord services or already are. ## Setup -1. Run a find all for `// SETUP-DD-TEMP:` and follow all instructions and delete the comments as you finish them. +- Download the source +- Copy the .env.example file and rename it to .env +- Fill out the .env file +- Find all the `TEMPLATE-SETUP:` comments and follow the instructions and delete the comments as you finish them. ## Startup -There are two ways to start your bot, using docker and node. Using docker will be the simplest and easiest way to start -your bot. The default configuation will be set for Docker. +You can run the template using either Docker or Node. + +Using docker will be the simplest and easiest way to start your bot. ### Using Docker -The docker compose file include the discordeno bot and influxdb, this would create an enviroment more close to the -production enviroment. +The docker compose file includes the discordeno bot and influxdb. This will create an environment close to the production environment. -First, rename the .env.example file to .env, and set the discord token and your dev guild id, change the `REST_URL` to -`rest` and `EVENT_HANDLER_URL` to `bot`, set `MESSAGEQUEUE_ENABLE` to true to use message queue, copy the value of -`DOCKER_INFLUXDB_INIT_xxxx` to `INFLUX_xxxx` +First, copy the `.env.example` file, rename it to `.env`, and fill in the values. Pre-set values can be left to their default value, except for the following: -Then, run ... to build/rebuild the bot +> [!IMPORTANT] +> The following values must be set to enable the docker container to communicate between different parts of your bot, InfluxDB, and RabbitMQ +> +> - `EVENT_HANDLER_HOST` should be set to `bot` +> - `REST_HOST` should be set to `rest` +> - `GATEWAY_HOST` should be set to `gateway` +> - Setup the message queue: +> - `MESSAGEQUEUE_ENABLE` should be set to `true` +> - `MESSAGEQUEUE_URL` should be set to `rabbitmq:5672` +> - `MESSAGEQUEUE_USERNAME` should be set to `guest` +> - `MESSAGEQUEUE_PASSWORD` should be set to `guest` +> - Set the value for influxDB: +> - Copy `DOCKER_INFLUXDB_INIT_ORG` to `INFLUX_ORG` +> - Copy `DOCKER_INFLUXDB_INIT_BUCKET` to `INFLUX_BUCKET` +> - Copy `DOCKER_INFLUXDB_INIT_ADMIN_TOKEN` to `INFLUX_TOKEN` +> - Set `INFLUX_URL` to `http://influxdb:8086` -- `docker-compose build` +After setting the aforementioned values, run `docker compose build` to build/rebuild the bot -And, run ... to start +Finally, run `docker compose up -d` to start -- `docker-compose up -d` +> [!NOTE] +> Docker will start the REST proxy, Gateway and Bot, however you won't see any command in Discord. +> You will need to manually run the `bot/register-commands.js` file. +> +> You can do this locally, but you will need to change some environment variables like the `REST_HOST` to point to something accessible from your machine -Your bot should be running now, you can check the rest/bot process fetch analytics (methods, status...) in influxdb's -webgui - with the username and password in the .env file, message queue's information (number of -events...) at with user: guest and pass: guest. +Your bot should be running now. + +You can check the REST process fetch analytics (methods, status...) in influxdb's WebUI at http://localhost:8086 with the username and password in the .env file (`DOCKER_INFLUXDB_INIT_USERNAME` and `DOCKER_INFLUXDB_INIT_PASSWORD`, respectively). You can also check the message queue's information (number of events, ...) in the RabbitMQ WebUI at http://localhost:15672 with the username `guest` and password `guest`. ### Using Node -you will need to start a few processes. The instructions below will use `node` but you can use something like `pm2` to -help keep your processes alive. +> [!NOTE] +> This template has been tested with the following versions: +> +> - NodeJS: v18.20.3, v20.14.0 and v22.2.0 +> - Any NodeJS version between v18.20.3 and v22.2.0 should work, anything below v18 will not run correctly, anything above v22 should work +> - RabbitMQ: v3.12.14 with: +> - Erlang: v26.2.5 +> - [RabbitMQ Message Deduplication Plugin](https://github.com/noxdafox/rabbitmq-message-deduplication): v0.6.2 +> - InfluxDB: v2.7.6 -First, rename the .env.example file to .env, and set the discord token and your dev guild id, change the `REST_URL` and -`EVENT_HANDLER_URL` to `localhost` +You will need to start a few processes. -Then compile everything with `npm run build`. +The preset value of `EVENT_HANDLER_HOST`, `REST_HOST`, and `GATEWAY_HOST` all use localhost. If you are using different servers you will need to change those values -After that, you can start your bot one by one with the following order. +#### Setup process -- Start REST - - `npm run startr` -- Start Bot - - `npm run startb` -- Start Gateway - - `npm run startg` +- Install the dependencies with yarn +- Build the code with `yarn build` -Other things you can add: +You can start different parts of your bot in the following order. -- InfluxDB for logging fetch analytics, by change value of `INFLUX_xxxx` to your influxdb config, leave it empty will - disable it. -- RabbitMQ for using message queues instead of fetch calls, by change value of `MESSAGEQUEUE_ENABLE` to true, and - `MESSAGEQUEUE_xxx` of your rabbitmq config
Note: the RabbitMQ must installed the - [RabbitMQ Message Deduplication Plugin](https://github.com/noxdafox/rabbitmq-message-deduplication) +- Start the REST Proxy: `yarn start:rest` +- Deploy the commands: `node dist/bot/register-commands.js` +- Start the Bot: `yarn start:bot` +- Start Gateway: `yarn start:gateway` + +#### InfluxDB + +To enable InfluxDB you will need to set the `INFLUX_ORG`, `INFLUX_BUCKET`, `INFLUX_TOKEN`, and `INFLUX_URL` variables in the `.env`. file + +For `INFLUX_URL`, the preset value uses localhost. If your InfluxDB is not running on the same machine, change the URL accordingly (do not include any protocol prefix, just `HOST:PORT`) + +If you do not set one of the values mentioned above, InfluxDB will be disabled. + +#### RabbitMQ + +To enable RabbitMQ you will need to set `MESSAGEQUEUE_ENABLE` to `true` and set `MESSAGEQUEUE_URL`, `MESSAGEQUEUE_USERNAME`, and `MESSAGEQUEUE_PASSWORD` variables in the `.env` file. + +`MESSAGEQUEUE_USERNAME` and `MESSAGEQUEUE_PASSWORD` will both default to `guest` in a RabbitMQ instance unless changed. + +> [!IMPORTANT] +> The [RabbitMQ Message Deduplication Plugin](https://github.com/noxdafox/rabbitmq-message-deduplication) must be installed +> +> The plugin files (`.ez`) are in the `rabbitmq/plugins/message-deduplication` folder. You can copy those into your `plugins` folder for the RabbitMQ installation folder or download them from the original repo (make sure to download the correct version). +> +> To enable the plugin you will need to run: `rabbitmq-plugins enable rabbitmq_message_deduplication` diff --git a/examples/bigbot/docker-compose.yml b/examples/bigbot/compose.yaml similarity index 54% rename from examples/bigbot/docker-compose.yml rename to examples/bigbot/compose.yaml index f0d2a9d15..090092821 100644 --- a/examples/bigbot/docker-compose.yml +++ b/examples/bigbot/compose.yaml @@ -1,25 +1,29 @@ -version: '3.8' services: influxdb: - image: 'influxdb:2.4.0-alpine' + image: influxdb:2.7.6-alpine ports: - 127.0.0.1:8086:8086 env_file: - .env + healthcheck: + test: "curl -f http://localhost:8086/ping" + interval: 5s + timeout: 10s + retries: 5 rabbitmq: build: context: . target: rabbitmq ports: - 127.0.0.1:15672:15672 + rest: build: context: . target: rest - deploy: - replicas: 2 depends_on: - - influxdb + influxdb: + condition: service_healthy env_file: - .env gateway: @@ -27,9 +31,10 @@ services: context: . target: gateway depends_on: - - rest - deploy: - replicas: 2 + rest: + condition: service_started + rabbitmq: + condition: service_healthy env_file: - .env bot: @@ -37,8 +42,9 @@ services: context: . target: bot depends_on: - - rest - deploy: - replicas: 2 + rest: + condition: service_started + rabbitmq: + condition: service_healthy env_file: - .env diff --git a/examples/bigbot/nodemon.json b/examples/bigbot/nodemon.json deleted file mode 100644 index cfc23ffd7..000000000 --- a/examples/bigbot/nodemon.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "watch": "./src/**/*.ts", - "ext ": "env,ts", - "signal": "SIGKILL", - "exec": "npm run build && node" -} diff --git a/examples/bigbot/package.json b/examples/bigbot/package.json index fdbf492a6..e13ae5f4d 100644 --- a/examples/bigbot/package.json +++ b/examples/bigbot/package.json @@ -1,51 +1,36 @@ { - "name": "dd-big-bot", - "version": "1.0.0", - "main": "index.js", - "type": "module", - "scripts": { - "devbg": "npx prisma generate && tsc --watch", - "fmt": "eslint --fix \"src/**/*.ts*\"", - "devg": "nodemon --ignore ./src/bot/**/* --ignore ./src/rest/**/* --ignore ./dist/**/* -e ts dist/gateway/index.js", - "devr": "nodemon --ignore ./src/bot/**/* --ignore ./src/gateway/**/* --ignore ./dist/**/* -e ts dist/rest/index.js", - "devb": "nodemon --ignore ./src/rest/**/* --ignore ./src/gateway/**/* --ignore ./dist/**/* -e ts dist/bot/index.js", - "type": "tsc --noEmit", - "build": "swc --delete-dir-on-start src --out-dir dist", - "startr": "node dist/rest/index.js", - "startg": "node dist/gateway/index.js", - "startb": "node dist/bot/index.js" - }, - "dependencies": { - "@influxdata/influxdb-client": "^1.29.0", - "@prisma/client": "^3.15.2", - "amqplib": "^0.10.3", - "colorette": "^2.0.19", - "discordeno": "^16.0.1", - "dotenv": "^16.0.3", - "express": "^4.18.1", - "fastify": "^4.10.2", - "nanoid": "^4.0.0", - "node-fetch": "^3.2.10", - "web-worker": "^1.2.0" - }, - "devDependencies": { - "@swc/cli": "^0.1.57", - "@swc/core": "^1.3.9", - "@types/amqplib": "^0.8.2", - "@types/express": "^4.17.13", - "@types/node": "^17.0.23", - "@types/ws": "^8.5.3", - "nodemon": "^2.0.15", - "prettier": "2.6.2", - "prisma": "^4.2.1", - "typescript": "^4.6.3" - }, - "prettier": { - "trailingComma": "all", - "useTabs": true, - "tabWidth": 2, - "singleQuote": true, - "semi": true, - "printWidth": 120 - } + "name": "dd-bigbot", + "version": "1.0.0", + "description": "A scalable bot for big bot developers.", + "main": "dist/index.js", + "type": "module", + "license": "ISC", + "private": true, + "packageManager": "yarn@4.0.2", + "scripts": { + "start:bot": "node dist/bot/index.js", + "start:rest": "node dist/rest/index.js", + "start:gateway": "node dist/gateway/index.js", + "build": "swc src --strip-leading-paths --delete-dir-on-start --out-dir dist", + "build:watch": "swc src --strip-leading-paths --delete-dir-on-start --watch --out-dir dist", + "dev:bot": "node --watch --watch-preserve-output dist/bot/index.js", + "dev:rest": "node --watch --watch-preserve-output dist/rest/index.js", + "dev:gateway": "node --watch --watch-preserve-output dist/gateway/index.js", + "setup-dd": "" + }, + "dependencies": { + "@discordeno/bot": "19.0.0-next.92bf166", + "@fastify/multipart": "^8.3.0", + "@influxdata/influxdb-client": "^1.33.2", + "amqplib": "^0.10.4", + "chalk": "^5.3.0", + "fastify": "^4.28.0" + }, + "devDependencies": { + "@swc/cli": "^0.3.12", + "@swc/core": "^1.6.3", + "@types/amqplib": "^0.10.5", + "@types/node": "^20.14.6", + "typescript": "^5.5.2" + } } diff --git a/examples/bigbot/prisma/schema.prisma b/examples/bigbot/prisma/schema.prisma deleted file mode 100644 index 513df891f..000000000 --- a/examples/bigbot/prisma/schema.prisma +++ /dev/null @@ -1,25 +0,0 @@ -// This is your Prisma schema file, -// learn more about it in the docs: https://pris.ly/d/prisma-schema - -generator client { - provider = "prisma-client-js" -} - -datasource db { - provider = "postgresql" - url = env("DATABASE_URL") -} - -model Guilds { - /// The server id - id BigInt @unique @id - /// The language the server uses. - language String @default("english") -} - -model Commands { - /// The server id - id BigInt @unique @id - /// The version number this server is using for it's commands. - version Int -} \ No newline at end of file diff --git a/examples/bigbot/rabbitmq/README.md b/examples/bigbot/rabbitmq/README.md new file mode 100644 index 000000000..eaf2f0a02 --- /dev/null +++ b/examples/bigbot/rabbitmq/README.md @@ -0,0 +1,18 @@ +# RabbitMQ + +This template has been tested using RabbitMQ v3.12.14 (Erlang v26.2.5) + +## Plugins + +The template needs the [rabbitmq_message_deduplication](https://github.com/noxdafox/rabbitmq-message-deduplication) plugin. + +This template has been tested with version v0.6.2 of said plugin. The `.ez` files are already in the `message-deduplication` folder, but you can re-download them from the original repository if needed. + +To enable the plugin you will need to run the following command: + +```sh +rabbitmq-plugins enable rabbitmq_message_deduplication +``` + +> [!NOTE] +> You may need to prefix the command with `sudo` based on your RabbitMQ setup/current shell permissions diff --git a/examples/bigbot/rabbitmq/plugins/.gitattributes b/examples/bigbot/rabbitmq/plugins/.gitattributes new file mode 100644 index 000000000..fd727c970 --- /dev/null +++ b/examples/bigbot/rabbitmq/plugins/.gitattributes @@ -0,0 +1,2 @@ +# RabbitMQ plugins are stored in a zip format (.ez files), just for security we tell git to always threat them as binary files +* binary diff --git a/examples/bigbot/rabbitmq/plugins/message-deduplication/elixir-1.14.0.ez b/examples/bigbot/rabbitmq/plugins/message-deduplication/elixir-1.14.0.ez new file mode 100644 index 000000000..9c525fcdc Binary files /dev/null and b/examples/bigbot/rabbitmq/plugins/message-deduplication/elixir-1.14.0.ez differ diff --git a/examples/bigbot/rabbitmq/plugins/message-deduplication/rabbitmq_message_deduplication-0.6.2.ez b/examples/bigbot/rabbitmq/plugins/message-deduplication/rabbitmq_message_deduplication-0.6.2.ez new file mode 100644 index 000000000..5254659d7 Binary files /dev/null and b/examples/bigbot/rabbitmq/plugins/message-deduplication/rabbitmq_message_deduplication-0.6.2.ez differ diff --git a/examples/bigbot/src/analytics.ts b/examples/bigbot/src/analytics.ts deleted file mode 100644 index 85638d167..000000000 --- a/examples/bigbot/src/analytics.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { InfluxDB, Point } from '@influxdata/influxdb-client'; -import type { RestManager } from 'discordeno/rest'; - -const INFLUX_ORG = process.env.INFLUX_ORG as string; -const INFLUX_BUCKET = process.env.INFLUX_BUCKET as string; -const INFLUX_TOKEN = process.env.INFLUX_TOKEN as string; -const INFLUX_URL = process.env.INFLUX_URL as string; - -export const influxDB = INFLUX_URL && INFLUX_TOKEN ? new InfluxDB({ url: INFLUX_URL, token: INFLUX_TOKEN }) : undefined; -export const Influx = influxDB?.getWriteApi(INFLUX_ORG, INFLUX_BUCKET); - -export const setupAnalyticsHooks = (rest: RestManager) => { - // If influxdb data is provided, enable analytics in this proxy. - if (Influx) { - rest.fetching = function (options) { - Influx?.writePoint( - new Point('restEvents') - // MARK THE TIME WHEN EVENT ARRIVED - .timestamp(new Date()) - // SET THE GUILD ID - .stringField('type', 'REQUEST_FETCHING') - .tag('method', options.method) - .tag('url', options.url) - .tag('bucket', options.bucketId ?? 'NA'), - ); - }; - - rest.fetched = function (options, response) { - Influx?.writePoint( - new Point('restEvents') - // MARK THE TIME WHEN EVENT ARRIVED - .timestamp(new Date()) - // SET THE GUILD ID - .stringField('type', 'REQUEST_FETCHED') - .tag('method', options.method) - .tag('url', options.url) - .tag('bucket', options.bucketId ?? 'NA') - .intField('status', response.status) - .tag('statusText', response.statusText), - ); - }; - - setInterval(() => { - console.log(`[Influx - REST] Saving events...`); - Influx?.flush() - .then(() => { - console.log(`[Influx - REST] Saved events!`); - }) - .catch((error) => { - console.log(`[Influx - REST] Error saving events!`, error); - }); - // Every 30seconds - }, 30000); - } -}; diff --git a/examples/bigbot/src/bot/README.md b/examples/bigbot/src/bot/README.md deleted file mode 100644 index f38d12f24..000000000 --- a/examples/bigbot/src/bot/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# Bot Code - -This folder will contain the code for our bot. When events are received from the gateway, they will be handled here. - -## Further Steps - -- Express framework to create the listener however, you can replace it with anything you like. Express is quite a - bloated framework. Feel free to optimize to a better framework. diff --git a/examples/bigbot/src/bot/bot.ts b/examples/bigbot/src/bot/bot.ts index fbaca1ac9..c3d4c8518 100644 --- a/examples/bigbot/src/bot/bot.ts +++ b/examples/bigbot/src/bot/bot.ts @@ -1,63 +1,101 @@ -import type { Bot } from 'discordeno'; -import { Collection, createBot, createRestManager } from 'discordeno'; -import enableHelpersPlugin from 'discordeno/helpers-plugin'; -import { createLogger } from 'discordeno/logger'; -import { setupAnalyticsHooks } from '../analytics.js'; -import { INTENTS, REST_URL } from '../configs.js'; -import { setupEventHandlers } from './events/mod.js'; -import type { MessageCollector } from './utils/collectors.js'; -import { customizeInternals } from './utils/internals/mod.js'; +import { Collection, LogDepth, createBot, type Bot, type logger } from '@discordeno/bot' +import { DISCORD_TOKEN, GATEWAY_AUTHORIZATION, GATEWAY_INTENTS, GATEWAY_URL, REST_AUTHORIZATION, REST_URL } from '../config.js' +import type { ManagerGetShardInfoFromGuildId, ShardInfo, WorkerPresencesUpdate, WorkerShardPayload } from '../gateway/worker/types.js' +import type { Command } from './commands.js' -const DISCORD_TOKEN = process.env.DISCORD_TOKEN as string; -const REST_AUTHORIZATION = process.env.REST_AUTHORIZATION as string; +export const bot = createCustomBot( + createBot({ + token: DISCORD_TOKEN, + intents: GATEWAY_INTENTS, + rest: { + token: DISCORD_TOKEN, + proxy: { + baseUrl: REST_URL, + authorization: REST_AUTHORIZATION, + }, + }, + }), +) -export const bot = enableHelpersPlugin( - customizeBot( - createBot({ - token: DISCORD_TOKEN, - intents: INTENTS, - }), - ), -); +overrideGatewayImplementations(bot) -/** Add custom props to your `bot` here */ -// SETUP-DD-TEMP: If you want to add any custom props to `bot` you can do so here. Please make sure to also add them in the type below. As an example, i have added a `logger` property. You can add any useful methods or props you wish to have easily available. -function customizeBot(bot: B): BotWithCustomProps { - const customized = bot as unknown as BotWithCustomProps; - customized.logger = createLogger({ name: '[Bot]' }); - customized.collectors = { - messages: new Collection(), - }; - customized.commandVersions = new Collection(); +// TEMPLATE-SETUP: Add/Remove the desired proprieties that you don't need +const props = bot.transformers.desiredProperties - return customized; +props.interaction.id = true +props.interaction.data = true +props.interaction.type = true +props.interaction.user = true +props.interaction.token = true +props.interaction.guildId = true + +props.user.id = true +props.user.username = true + +// TEMPLATE-SETUP: If you want/need to add any custom proprieties on the Bot type, you can do it in this function and the `CustomBot` type below. Make sure to do it in both or else you will get an error by TypeScript +function createCustomBot(rawBot: TBot): CustomBot { + const bot = rawBot as CustomBot + + // We need to set the log depth for the default discordeno logger or else only the first param will be logged + ;(bot.logger as typeof logger).setDepth(LogDepth.Full) + + bot.commands = new Collection() + + return bot } -// SETUP-DD-TEMP: If you want to add any custom props to `bot` you can do so here. Please make sure to also add them in the function above. Run a find all and change this to your Bot's name. For example, if your bot's name is Gamer change BotWithCustomProps to Gamer. This way whenever you need to provide the type for the Bot with your custom props it is your bots name. -// Note: ALWAYS edit the function above first before adding the type here. -export type BotWithCustomProps = B & { - /** A easy to use logger to make clean log messages. */ - logger: ReturnType; - /** Collectors that can be used to get input from users. */ - collectors: { - /** Holds the pending messages collectors that users can respond to. */ - messages: Collection; - }; - /** The command versions for each guild id. */ - commandVersions: Collection; -}; +export type CustomBot = TBot & { + commands: Collection +} -// Example of how to customize internal discordeno stuff easily. -customizeInternals(bot); +// Override the default gateway functions to allow the methods on the gateway object to proxy the requests to the gateway proxy +function overrideGatewayImplementations(bot: CustomBot): void { + bot.gateway.sendPayload = async (shardId, payload) => { + await fetch(GATEWAY_URL, { + method: 'POST', + body: JSON.stringify({ + type: 'ShardPayload', + shardId, + payload, + } satisfies WorkerShardPayload), + headers: { + 'Content-Type': 'application/json', + Authorization: GATEWAY_AUTHORIZATION, + }, + }) + } -// Setup event handlers. -setupEventHandlers(); + bot.gateway.editBotStatus = async (payload) => { + await fetch(GATEWAY_URL, { + method: 'POST', + body: JSON.stringify({ + type: 'EditShardsPresence', + payload, + } satisfies WorkerPresencesUpdate), + headers: { + 'Content-Type': 'application/json', + Authorization: GATEWAY_AUTHORIZATION, + }, + }) + } +} -bot.rest = createRestManager({ - token: DISCORD_TOKEN, - secretKey: REST_AUTHORIZATION, - customUrl: REST_URL, -}); +export async function getShardInfoFromGuild(guildId?: bigint): Promise> { + const req = await fetch(GATEWAY_URL, { + method: 'POST', + body: JSON.stringify({ + type: 'ShardInfoFromGuild', + guildId: guildId?.toString(), + } as ManagerGetShardInfoFromGuildId), + headers: { + 'Content-Type': 'application/json', + Authorization: GATEWAY_AUTHORIZATION, + }, + }) -// Add send fetching analytics hook to rest -setupAnalyticsHooks(bot.rest); + const res = await req.json() + + if (req.ok) return res + + throw new Error(`There was an issue getting the shard info: ${res.error}`) +} diff --git a/examples/bigbot/src/bot/commands.ts b/examples/bigbot/src/bot/commands.ts new file mode 100644 index 000000000..2feb17281 --- /dev/null +++ b/examples/bigbot/src/bot/commands.ts @@ -0,0 +1,85 @@ +import type { + ApplicationCommandOptionTypes, + Attachment, + CamelizedDiscordApplicationCommandOption, + ChannelTypes, + CreateApplicationCommand, + Interaction, + Member, + Role, + User, +} from '@discordeno/bot' +import { bot } from './bot.js' + +export default function createCommand(command: Command): void { + bot.commands.set(command.name, command as Command) +} + +export type Command = CreateApplicationCommand & { + /** @inheritdoc */ + options?: TOptions + /** + * Should this command be only deployed on the Dev guild? + * + * @default false + */ + devOnly?: boolean + /** Function to run when the interaction is executed */ + run: (interaction: Interaction, options: GetCommandOptions) => unknown + /** Function to run when an autocomplete interaction is fired */ + autoComplete?: (interaction: Interaction, options: GetCommandOptions) => unknown +} + +export type GetCommandOptions = T extends CommandOptions + ? { [Prop in keyof BuildOptions as Prop]: BuildOptions[Prop] } + : never + +export type CommandOption = CamelizedDiscordApplicationCommandOption +export type CommandOptions = CommandOption[] + +// Option parsing + +interface UserResolved { + user: User + member: Member | undefined +} + +interface ChannelResolved { + id: bigint + name: string + type: ChannelTypes + permissions: bigint +} + +type ResolvedValues = number | boolean | UserResolved | Role | ChannelResolved | Attachment + +/** + * From here SubCommandGroup and SubCommand are missing, this is wanted. + * + * The entries are sorted based on the enum value + */ +interface TypeToResolvedMap { + [ApplicationCommandOptionTypes.String]: string + [ApplicationCommandOptionTypes.Integer]: number + [ApplicationCommandOptionTypes.Boolean]: boolean + [ApplicationCommandOptionTypes.User]: UserResolved + [ApplicationCommandOptionTypes.Channel]: ChannelResolved + [ApplicationCommandOptionTypes.Role]: Role + [ApplicationCommandOptionTypes.Mentionable]: Role | UserResolved + [ApplicationCommandOptionTypes.Number]: number + [ApplicationCommandOptionTypes.Attachment]: Attachment +} + +type ConvertTypeToResolved = T extends keyof TypeToResolvedMap ? TypeToResolvedMap[T] : ResolvedValues + +type SubCommandApplicationCommand = ApplicationCommandOptionTypes.SubCommand | ApplicationCommandOptionTypes.SubCommandGroup +type GetOptionName = T extends { name: string } ? T['name'] : never +type GetOptionValue = T extends { type: ApplicationCommandOptionTypes; required?: boolean } + ? T extends { type: SubCommandApplicationCommand; options?: CommandOptions } + ? BuildOptions + : ConvertTypeToResolved | (T['required'] extends true ? never : undefined) + : never + +type BuildOptions = { + [Prop in keyof Omit as GetOptionName]: GetOptionValue +} diff --git a/examples/bigbot/src/bot/commands/language.ts b/examples/bigbot/src/bot/commands/language.ts deleted file mode 100644 index 3f25e4d9f..000000000 --- a/examples/bigbot/src/bot/commands/language.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { ApplicationCommandOptionTypes } from 'discordeno'; -import { prisma } from '../../prisma.js'; -import languages from '../languages/languages.js'; -import { serverLanguages, translate } from '../languages/translate.js'; -import { createCommand } from '../utils/slash/createCommand.js'; - -export default createCommand({ - name: 'LANGUAGE_NAME', - description: 'LANGUAGE_DESCRIPTION', - options: [ - { - name: 'LANGUAGE_KEY_NAME', - description: 'LANGUAGE_KEY_DESCRIPTION', - type: ApplicationCommandOptionTypes.String, - choices: Object.keys(languages).map((key) => ({ name: key, value: key })), - required: true, - }, - ], - execute: async function (_, interaction, args) { - if (!interaction.guildId) return; - - // Set the new language in cache - serverLanguages.set(interaction.guildId, args.name); - // Let the user know its been updated. - await interaction.reply(translate(interaction.guildId!, 'LANGUAGE_UPDATED', args.name)); - // Update the db - return await prisma.guilds.upsert({ - where: { id: interaction.guildId }, - create: { language: args.name, id: interaction.guildId }, - update: { language: args.name }, - }); - }, -}); diff --git a/examples/bigbot/src/bot/commands/mod.ts b/examples/bigbot/src/bot/commands/mod.ts deleted file mode 100644 index b25e3edf5..000000000 --- a/examples/bigbot/src/bot/commands/mod.ts +++ /dev/null @@ -1,9 +0,0 @@ -import language from './language.js'; -import ping from './ping.js'; - -export const COMMANDS = { - language, - ping, -}; - -export default COMMANDS; diff --git a/examples/bigbot/src/bot/commands/ping.ts b/examples/bigbot/src/bot/commands/ping.ts index b733f9b3f..8562faf0c 100644 --- a/examples/bigbot/src/bot/commands/ping.ts +++ b/examples/bigbot/src/bot/commands/ping.ts @@ -1,17 +1,16 @@ -import { translate } from '../languages/translate.js'; -import { createCommand } from '../utils/slash/createCommand.js'; +import { snowflakeToTimestamp } from '@discordeno/bot' +import { getShardInfoFromGuild } from '../bot.js' +import createCommand from '../commands.js' -export default createCommand({ - name: 'PING_NAME', - description: 'PING_DESCRIPTION', - execute: async function (_, interaction) { - return await interaction.reply( - translate(interaction.guildId!, 'PING_RESPONSE_WITH_TIME', Date.now() - snowflakeToTimestamp(interaction.id)), - ); - }, -}); +createCommand({ + name: 'ping', + description: '🏓 Check whether the bot is online and responsive.', + async run(interaction) { + const ping = Date.now() - snowflakeToTimestamp(interaction.id) + const shardInfo = await getShardInfoFromGuild(interaction.guildId) -// TODO: This should be deleted once this is available in the helpers plugin. -export function snowflakeToTimestamp(id: bigint) { - return Number(id / 4194304n + 1420070400000n); -} + const shardPing = shardInfo.rtt === -1 ? '*Not yet available*' : `${shardInfo.rtt}ms` + + await interaction.respond(`🏓 Pong! Gateway Latency: ${shardPing}, Roundtrip Latency: ${ping}ms. I am online and responsive! 🕙`) + }, +}) diff --git a/examples/bigbot/src/bot/events/interactions/button.ts b/examples/bigbot/src/bot/events/interactions/button.ts deleted file mode 100644 index a863ceb0c..000000000 --- a/examples/bigbot/src/bot/events/interactions/button.ts +++ /dev/null @@ -1,14 +0,0 @@ -import type { Interaction } from 'discordeno'; -import type { BotWithCustomProps } from '../../bot.js'; - -export async function executeButtonClick(bot: BotWithCustomProps, interaction: Interaction) { - if (!interaction.data) return; - - bot.logger.info( - `[Button] The ${interaction.data.customId} button was clicked in Guild: ${interaction.guildId} by ${interaction.user.id}.`, - ); - - await Promise.allSettled([ - // SETUP-DD-TEMP: Insert any functions you wish to run when a user clicks a button. - ]).catch(console.log); -} diff --git a/examples/bigbot/src/bot/events/interactions/command.ts b/examples/bigbot/src/bot/events/interactions/command.ts deleted file mode 100644 index 137041f4d..000000000 --- a/examples/bigbot/src/bot/events/interactions/command.ts +++ /dev/null @@ -1,304 +0,0 @@ -import { bgBlack, bgGreen, bgMagenta, bgYellow, black, green, red, white } from 'colorette'; -import type { - ApplicationCommandOption, - Bot, - Channel, - ChannelTypes, - Interaction, - InteractionDataOption, - Member, - Role, - User, -} from 'discordeno'; -import { ApplicationCommandOptionTypes, InteractionResponseTypes } from 'discordeno'; -import type { BotWithCustomProps } from '../../bot.js'; -import { bot } from '../../bot.js'; -import COMMANDS from '../../commands/mod.js'; -import type { translationKeys } from '../../languages/translate.js'; -import { getLanguage, loadLanguage, serverLanguages, translate } from '../../languages/translate.js'; -import type { InteractionWithCustomProps } from '../../typings/discordeno.js'; -import type { Command, ConvertArgumentDefinitionsToArgs } from '../../utils/slash/createCommand.js'; - -function logCommand( - info: Interaction, - type: 'Failure' | 'Success' | 'Trigger' | 'Slowmode' | 'Missing' | 'Inhibit', - commandName: string, -) { - const command = `[COMMAND: ${bgYellow(black(commandName || 'Unknown'))} - ${bgBlack( - ['Failure', 'Slowmode', 'Missing'].includes(type) ? red(type) : type === 'Success' ? green(type) : white(type), - )}]`; - - const user = bgGreen( - black(`${info.user.username}#${info.user.discriminator.toString().padStart(4, '0')}(${info.id})`), - ); - const guild = bgMagenta(black(`${info.guildId ? `Guild ID: (${info.guildId})` : 'DM'}`)); - - bot.logger.info(`${command} by ${user} in ${guild} with MessageID: ${info.id}`); -} - -export async function executeSlashCommand(bot: BotWithCustomProps, interaction: InteractionWithCustomProps) { - const data = interaction.data; - const name = data?.name as keyof typeof COMMANDS; - - const command: Command | undefined = COMMANDS[name]; - - // Command could not be found - if (!command?.execute) { - return await interaction - .reply(translate(interaction.guildId!, 'EXECUTE_COMMAND_NOT_FOUND')) - .catch(bot.logger.error); - } - - // HAVE TO CONVERT OUTSIDE OF TRY SO IT CAN BE USED IN CATCH TOO - try { - logCommand(interaction, 'Trigger', name); - - // Check subcommand permissions and options - if (!(await commandAllowed(interaction, command))) return; - - // Load the language for this guild - if (interaction.guildId && !serverLanguages.has(interaction.guildId)) { - // Todo: make command.execute reply change to editReply after running this - // await interaction.reply({ - // type: InteractionResponseTypes.DeferredChannelMessageWithSource, - // }); - await loadLanguage(interaction.guildId); - } // Load the language for this guild - else if (command.acknowledge) { - // Acknowledge the command - await interaction.reply({ - type: InteractionResponseTypes.DeferredChannelMessageWithSource, - }); - } - - // FIRST GET THE TRANSLATIONS FOR ALL OPTIONS - const translatedOptionNames = - interaction.guildId && command.options ? translateOptionNames(bot, interaction.guildId, command.options) : {}; - - // PARSE THE OPTIONS TO A NICE OBJECT AND TRANSLATE THE KEYS TO ENGLISH - const parsedArguments = optionParser(interaction, translatedOptionNames); - - await command.execute(bot, interaction, parsedArguments as ConvertArgumentDefinitionsToArgs); - logCommand(interaction, 'Success', name); - } catch (error) { - console.error(error); - logCommand(interaction, 'Failure', name); - - try { - console.log('try'); - // try to reply the interaction, becuase we don't know if it replied or deffered - return await interaction.reply(translate(interaction.id, 'EXECUTE_COMMAND_ERROR')); - } catch { - console.log('catch'); - // edit the reply or deffered reply of interaction - return await interaction.editReply(translate(interaction.id, 'EXECUTE_COMMAND_ERROR')).catch(bot.logger.error); - } - } -} - -/** Runs the inhibitors to see if a command is allowed to run. */ -export async function commandAllowed(interaction: InteractionWithCustomProps, command: Command) { - // CHECK WHETHER THE USER/GUILD IS VIP - if (command.vipOnly) { - // SETUP-DD-TEMP: Check if this server/user is a vip. - const isVIP = true; - - if (!isVIP) { - await interaction.reply(translate(interaction.id, 'NEED_VIP')).catch(bot.logger.error); - - return false; - } - } - - return true; -} - -// Mapped by `language-commandName` -const translatedOptionNamesCache = new Map>(); - -/** Translates all options of the command to an object: translatedOptionName: optionName */ -export function translateOptionNames( - bot: Bot, - guildId: bigint, - options: ApplicationCommandOption[], - commandName?: string, -): Record { - const language = getLanguage(guildId); - // RETURN THE ALREADY TRANSLATED OPTIONS WHICH ARE IN CACHE - if (commandName && translatedOptionNamesCache.has(`${language}-${commandName}`)) { - return translatedOptionNamesCache.get(`${language}-${commandName}`)!; - } - - // TRANSLATE ALL OPTIONS - let translated: Record = {}; - for (const option of options) { - translated[translate(guildId, option.name as translationKeys).toLowerCase()] = translate( - 'english', - option.name as translationKeys, - ); - if (option.options) { - translated = { - ...translated, - ...translateOptionNames(bot, guildId, option.options), - }; - } - } - - // SAVE THE TRANSLATED OPTIONS IN CACHE FOR FASTER ACCESS - if (commandName) { - translatedOptionNamesCache.set(`${language}-${commandName}`, translated); - } - - return translated; -} - -function convertOptionValue( - interaction: Interaction, - option: InteractionDataOption, - translateOptions?: Record, -): [ - string, - ( - | { user: User; member: Member } - | Role - | { - id: bigint; - name: string; - type: ChannelTypes; - permissions: bigint; - } - | boolean - | string - | number - ), -] { - // THE OPTION IS A CHANNEL - if (option.type === ApplicationCommandOptionTypes.Channel) { - const channel = interaction.data?.resolved?.channels?.get(BigInt(option.value as string)); - - // SAVE THE ARGUMENT WITH THE CORRECT NAME - return [translateOptions?.[option.name] ?? option.name, channel]; - } - - // THE OPTION IS A ROLE - if (option.type === ApplicationCommandOptionTypes.Role) { - const role = interaction.data?.resolved?.roles?.get(BigInt(option.value as string)); - - // SAVE THE ARGUMENT WITH THE CORRECT NAME - return [translateOptions?.[option.name] ?? option.name, role]; - } - - // THE OPTION IS A USER - if (option.type === ApplicationCommandOptionTypes.User) { - const user = interaction.data?.resolved?.users?.get(BigInt(option.value as string)); - const member = interaction.data?.resolved?.members?.get(BigInt(option.value as string)); - - // SAVE THE ARGUMENT WITH THE CORRECT NAME - return [ - translateOptions?.[option.name] ?? option.name, - { - member, - user, - }, - ]; - } - - // THE OPTION IS A MENTIONABLE - if (option.type === ApplicationCommandOptionTypes.Mentionable) { - const role = interaction.data?.resolved?.roles?.get(BigInt(option.value as string)); - const user = interaction.data?.resolved?.users?.get(BigInt(option.value as string)); - const member = interaction.data?.resolved?.members?.get(BigInt(option.value as string)); - - const final = user && member ? { user, member } : role; - - // SAVE THE ARGUMENT WITH THE CORRECT NAME - return [translateOptions?.[option.name] ?? option.name, final]; - } - - // THE REST OF OPTIONS DON'T NEED ANY CONVERTION - // SAVE THE ARGUMENT WITH THE CORRECT NAME - // @ts-expect-error - return [translateOptions?.[option.name] ?? option.name, option.value]; -} - -/** Parse the options to a nice object. - * NOTE: this does not work with subcommands - */ -export function optionParser( - interaction: Interaction, - translateOptions?: Record, -): - | InteractionCommandArgs - | { [key: string]: InteractionCommandArgs } - | { [key: string]: { [key: string]: InteractionCommandArgs } } { - // OPTIONS CAN BE UNDEFINED SO WE JUST RETURN AN EMPTY OBJECT - if (!interaction.data?.options) return {}; - - // A SUBCOMMAND WAS USED - if (interaction.data.options[0]?.type === ApplicationCommandOptionTypes.SubCommand) { - const convertedOptions: Record< - string, - | { user: User; member: Member } - | Role - | { - id: bigint; - name: string; - type: ChannelTypes; - permissions: bigint; - } - | boolean - | string - | number - > = {}; - // CONVERT ALL THE OPTIONS - for (const option of interaction.data.options[0].options ?? []) { - const [name, value] = convertOptionValue(interaction, option, translateOptions); - convertedOptions[name] = value; - } - - // @ts-expect-error - return { - [translateOptions?.[interaction.data.options[0].name] ?? interaction.data.options[0].name]: convertedOptions, - }; - } - - // A SUBCOMMAND GROUP WAS USED - if (interaction.data.options[0]?.type === ApplicationCommandOptionTypes.SubCommandGroup) { - const convertedOptions: Record = {}; - // CONVERT ALL THE OPTIONS - for (const option of interaction.data.options[0]?.options![0]?.options ?? []) { - const [name, value] = convertOptionValue(interaction, option, translateOptions); - // @ts-expect-error - convertedOptions[name] = value; - } - - // @ts-expect-error - return { - [translateOptions?.[interaction.data.options[0].name] ?? interaction.data.options[0].name]: { - [translateOptions?.[interaction.data.options[0]!.options![0]!.name] ?? - interaction.data.options[0]!.options![0]!.name]: convertedOptions, - }, - }; - } - - // A NORMAL COMMAND WAS USED - const convertedOptions: Record< - string, - Member | Role | Record> | boolean | string | number - > = {}; - for (const option of interaction.data.options ?? []) { - const [name, value] = convertOptionValue(interaction, option, translateOptions); - // @ts-expect-error - convertedOptions[name] = value; - } - - return convertedOptions; -} - -/** The interaction arguments. - * Important the members `deaf` and `mute` properties will always be false. - */ -export type InteractionCommandArgs = Record< - string, - Member | Role | Record> | boolean | string | number ->; diff --git a/examples/bigbot/src/bot/events/interactions/create.ts b/examples/bigbot/src/bot/events/interactions/create.ts new file mode 100644 index 000000000..981bae55c --- /dev/null +++ b/examples/bigbot/src/bot/events/interactions/create.ts @@ -0,0 +1,53 @@ +import { InteractionTypes, LogLevels, commandOptionsParser, type Interaction, type logger } from '@discordeno/bot' +import chalk from 'chalk' +import { bot } from '../../bot.js' + +bot.events.interactionCreate = async (interaction) => { + const isAutocomplete = interaction.type === InteractionTypes.ApplicationCommandAutocomplete + const isCommandOrAutocomplete = interaction.type === InteractionTypes.ApplicationCommand || isAutocomplete + + if (!interaction.data || !isCommandOrAutocomplete) return + + const command = bot.commands.get(interaction.data.name) + + if (!command) { + logCommand(interaction, 'Missing', interaction.data.name) + await interaction.respond('❌ Something went wrong. I was not able to find this command.') + + return + } + + logCommand(interaction, 'Trigger', interaction.data.name) + + const options = commandOptionsParser(interaction) + + try { + if (isAutocomplete) { + await command.autoComplete?.(interaction, options) + } else { + await command.run(interaction, options) + } + + logCommand(interaction, 'Success', interaction.data.name) + } catch (error) { + logCommand(interaction, 'Failure', interaction.data.name, LogLevels.Error, error) + await interaction.respond('❌ Something went wrong. The command execution has thrown an error.') + } +} + +function logCommand( + interaction: Interaction, + type: 'Failure' | 'Success' | 'Trigger' | 'Missing', + commandName: string, + logLevel: LogLevels = LogLevels.Info, + ...restArgs: unknown[] +): void { + const typeColor = ['Failure', 'Missing'].includes(type) ? chalk.red(type) : type === 'Success' ? chalk.green(type) : chalk.white(type) + + const autocomplete = interaction.type === InteractionTypes.ApplicationCommandAutocomplete ? ' (AutoComplete) ' : '' + const command = `Command${autocomplete}: ${chalk.bgYellow.black(commandName || 'Unknown')} - ${chalk.bgBlack(typeColor)}` + const user = chalk.bgGreen.black(`@${interaction.user.username} (${interaction.user.id})`) + const guild = chalk.bgMagenta.black(interaction.guildId ? `guildId: ${interaction.guildId}` : 'DM') + + ;(bot.logger as typeof logger).log(logLevel, `${command} - By ${user} in ${guild}`, ...restArgs) +} diff --git a/examples/bigbot/src/bot/events/interactions/mod.ts b/examples/bigbot/src/bot/events/interactions/mod.ts deleted file mode 100644 index 63de86904..000000000 --- a/examples/bigbot/src/bot/events/interactions/mod.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { InteractionTypes, MessageComponentTypes } from 'discordeno'; -import { bot } from '../../bot.js'; -import type { InteractionWithCustomProps } from '../../typings/discordeno.js'; -import { executeButtonClick } from './button.js'; -import { executeSlashCommand } from './command.js'; -import { executeModalSubmit } from './modal.js'; - -export function setInteractionCreateEvent() { - bot.events.interactionCreate = async function (_, interaction) { - if (interaction.type === InteractionTypes.ApplicationCommand) { - await executeSlashCommand(bot, interaction as InteractionWithCustomProps); - } else if (interaction.type === InteractionTypes.MessageComponent) { - if (!interaction.data) return; - - // THE INTERACTION CAME FROM A BUTTON - if (interaction.data.componentType === MessageComponentTypes.Button) { - await executeButtonClick(bot, interaction); - } - } else if (interaction.type === InteractionTypes.ModalSubmit) { - await executeModalSubmit(bot, interaction); - } - }; -} diff --git a/examples/bigbot/src/bot/events/interactions/modal.ts b/examples/bigbot/src/bot/events/interactions/modal.ts deleted file mode 100644 index faf395edc..000000000 --- a/examples/bigbot/src/bot/events/interactions/modal.ts +++ /dev/null @@ -1,16 +0,0 @@ -import type { Interaction } from 'discordeno'; -import type { BotWithCustomProps } from '../../bot.js'; - -export async function executeModalSubmit(bot: BotWithCustomProps, interaction: Interaction) { - if (!interaction.data) return; - - bot.logger.info( - `[Modal] The ${interaction.data?.customId || 'UNKNWON'} modal was submitted in Guild: ${interaction.guildId} by ${ - interaction.user.id - }.`, - ); - - await Promise.allSettled([ - // SETUP-DD-TEMP: Insert any functions you wish to run when a user clicks a button. - ]).catch(console.log); -} diff --git a/examples/bigbot/src/bot/events/messages/create.ts b/examples/bigbot/src/bot/events/messages/create.ts deleted file mode 100644 index e612077a4..000000000 --- a/examples/bigbot/src/bot/events/messages/create.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { bot } from '../../bot.js'; -import { processMessageCollectors } from '../../utils/collectors.js'; - -export function setMessageCreateEvent() { - bot.events.messageCreate = async function (_, message) { - processMessageCollectors(message); - - await Promise.allSettled([ - // SETUP-DD-TEMP: Add any functions you want to run on every message here. For example, automoderation filters. - ]).catch(console.log); - }; -} diff --git a/examples/bigbot/src/bot/events/mod.ts b/examples/bigbot/src/bot/events/mod.ts deleted file mode 100644 index d9494d269..000000000 --- a/examples/bigbot/src/bot/events/mod.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { setInteractionCreateEvent } from './interactions/mod.js'; -import { setMessageCreateEvent } from './messages/create.js'; -import { setRawEvent } from './raw.js'; - -export function setupEventHandlers() { - setInteractionCreateEvent(); - setRawEvent(); - setMessageCreateEvent(); -} diff --git a/examples/bigbot/src/bot/events/nodejs.ts b/examples/bigbot/src/bot/events/nodejs.ts new file mode 100644 index 000000000..1e27e0044 --- /dev/null +++ b/examples/bigbot/src/bot/events/nodejs.ts @@ -0,0 +1,21 @@ +import { createEmbeds } from '@discordeno/bot' +import { inspect } from 'node:util' +import { BUGS_ERRORS_REPORT_WEBHOOK } from '../../config.js' +import { bot } from '../bot.js' +import { webhookURLToIDAndToken } from '../utils/webhook.js' + +process.on('unhandledRejection', async (error) => { + bot.logger.error('An unhandled rejection occurred', error) + + if (!BUGS_ERRORS_REPORT_WEBHOOK || !error) return + + const { id, token } = webhookURLToIDAndToken(BUGS_ERRORS_REPORT_WEBHOOK) + + if (!id || !token) return + + const inspectedError = inspect(error) + + const embeds = createEmbeds().setDescription(`\`\`\`${inspectedError}\`\`\``).setFooter('Unhandled rejection occurred').setTimestamp(Date.now()) + + await bot.helpers.executeWebhook(id, token, { embeds }) +}) diff --git a/examples/bigbot/src/bot/events/raw.ts b/examples/bigbot/src/bot/events/raw.ts deleted file mode 100644 index c5211497f..000000000 --- a/examples/bigbot/src/bot/events/raw.ts +++ /dev/null @@ -1,38 +0,0 @@ -import type { DiscordUnavailableGuild } from 'discordeno'; -import { prisma } from '../../prisma.js'; -import { bot } from '../bot.js'; -import { updateGuildCommands, usesLatestCommandVersion } from '../utils/slash/updateCommands.js'; - -/** To prevent updating every guild when a shard goes ready we have to ignore them using this */ -// export const initialyLoadingGuildIds = new Set() - -export function setRawEvent() { - bot.events.raw = async function (_, data) { - if (data.t === 'GUILD_DELETE') { - const id = (data.d as DiscordUnavailableGuild).id; - - return await prisma.commands.delete({ where: { id: bot.transformers.snowflake(id) } }); - } - - const id = bot.transformers.snowflake( - (data.t && ['GUILD_UPDATE', 'GUILD_CREATE'].includes(data.t) - ? // deno-lint-ignore no-explicit-any - data.d?.id - : // deno-lint-ignore no-explicit-any - data.d?.guild_id) ?? '', - ); - - // The GUILD_CREATE event came from a shard loaded event so ignore it - if (['READY', 'GUILD_LOADED_DD', null].includes(data.t)) return; - - // console.log({ id, v: await usesLatestCommandVersion(id) }) - - if (!id || (await usesLatestCommandVersion(id))) return; - // dev guild - if (id === 547046977578336286n) return; - - // NEW GUILD AVAILABLE - bot.logger.info(`[Slash Setup] Installing Slash commands on Guild ${id} event type: ${data.t}`); - await updateGuildCommands(bot, id).catch(bot.logger.error); - }; -} diff --git a/examples/bigbot/src/bot/fastify.ts b/examples/bigbot/src/bot/fastify.ts new file mode 100644 index 000000000..800784db1 --- /dev/null +++ b/examples/bigbot/src/bot/fastify.ts @@ -0,0 +1,17 @@ +import fastify, { type FastifyInstance } from 'fastify' +import { EVENT_HANDLER_AUTHORIZATION } from '../config.js' + +export function buildFastifyApp(): FastifyInstance { + const app = fastify() + + // Authorization check + app.addHook('onRequest', async (req, res) => { + if (req.headers.authorization !== EVENT_HANDLER_AUTHORIZATION) { + res.status(401).send({ + message: 'Credentials not valid.', + }) + } + }) + + return app +} diff --git a/examples/bigbot/src/bot/index.ts b/examples/bigbot/src/bot/index.ts index 32040f629..a511965ac 100644 --- a/examples/bigbot/src/bot/index.ts +++ b/examples/bigbot/src/bot/index.ts @@ -1,185 +1,123 @@ -import dotenv from 'dotenv'; +import type { DiscordGatewayPayload, GatewayDispatchEventNames } from '@discordeno/bot' +import { connect as connectAmqp } from 'amqplib' +import { join as joinPath } from 'node:path' +import { + EVENT_HANDLER_HOST, + EVENT_HANDLER_PORT, + MESSAGEQUEUE_ENABLE, + MESSAGEQUEUE_PASSWORD, + MESSAGEQUEUE_URL, + MESSAGEQUEUE_USERNAME, +} from '../config.js' +import { getDirnameFromFileUrl } from '../util.js' +import { bot } from './bot.js' +import { buildFastifyApp } from './fastify.js' +import importDirectory from './utils/loader.js' -import type { DiscordGatewayPayload } from 'discordeno'; -// ReferenceError: publishMessage is not defined -// import Embeds from "discordeno/embeds"; -import amqplib from 'amqplib'; -import express from 'express'; -import { BOT_ID, EVENT_HANDLER_URL } from '../configs.js'; -import { bot } from './bot.js'; -import { updateDevCommands } from './utils/slash/updateCommands.js'; -import { webhookURLToIDAndToken } from './utils/webhook.js'; -dotenv.config(); +// The importDirectory function uses 'readdir' that requires either a relative path compared to the process CWD or an absolute one, so to get one relative we need to use import.meta.url +const currentDirectory = getDirnameFromFileUrl(import.meta.url) -const BUGS_ERRORS_REPORT_WEBHOOK = process.env.BUGS_ERRORS_REPORT_WEBHOOK; -const EVENT_HANDLER_AUTHORIZATION = process.env.EVENT_HANDLER_AUTHORIZATION as string; -const EVENT_HANDLER_PORT = process.env.EVENT_HANDLER_PORT as string; +await importDirectory(joinPath(currentDirectory, './commands')) +await importDirectory(joinPath(currentDirectory, './events')) -process - .on('unhandledRejection', (error) => { - if (!BUGS_ERRORS_REPORT_WEBHOOK) return; - const { id, token } = webhookURLToIDAndToken(BUGS_ERRORS_REPORT_WEBHOOK); - if (!id || !token) return; - - // DO NOT SEND ERRORS FROM NON PRODUCTION - if (BOT_ID !== 270010330782892032n) { - return console.error(error); - } - - // An unhandled error occurred on the bot in production - console.error(error ?? `An unhandled rejection error occurred but error was null or undefined`); - - if (!error) return; - - // ReferenceError: publishMessage is not defined - /* - const embeds = new Embeds() - .setDescription(["```js", error, "```"].join(`\n`)) - .setTimestamp() - .setFooter("Unhandled Rejection Error Occurred"); - - // SEND ERROR TO THE LOG CHANNEL ON THE DEV SERVER - return bot.helpers.sendWebhookMessage(bot.transformers.snowflake(id), token, { embeds }).catch(console.error); - */ - }) - .on('uncaughtException', async (error) => { - if (!BUGS_ERRORS_REPORT_WEBHOOK) return; - const { id, token } = webhookURLToIDAndToken(BUGS_ERRORS_REPORT_WEBHOOK); - if (!id || !token) return; - - // DO NOT SEND ERRORS FROM NON PRODUCTION - if (BOT_ID !== 270010330782892032n) { - return console.error(error); - } - - // An unhandled error occurred on the bot in production - console.error(error ?? `An unhandled exception occurred but error was null or undefined`); - - if (!error) process.exit(1); - - /* - const embeds = new Embeds() - .setDescription(["```js", error.stack, "```"].join(`\n`)) - .setTimestamp() - .setFooter("Unhandled Exception Error Occurred"); - // SEND ERROR TO THE LOG CHANNEL ON THE DEV SERVER - await bot.helpers.sendWebhookMessage(bot.transformers.snowflake(id), token, { embeds }).catch(console.error); - */ - - process.exit(1); - }); - -if (process.env.DEVELOPMENT === 'true') { - bot.logger.info(`[DEV MODE] Updating slash commands for dev server.`); - updateDevCommands(bot); +if (MESSAGEQUEUE_ENABLE) { + await connectToRabbitMQ() } -// Handle events from the gateway -const handleEvent = async (message: DiscordGatewayPayload, shardId: number) => { - // EMITS RAW EVENT - bot.events.raw(bot, message, shardId); +const app = buildFastifyApp() - if (message.t && message.t !== 'RESUMED') { - // When a guild or something isnt in cache this will fetch it before doing anything else - if (!['READY', 'GUILD_LOADED_DD'].includes(message.t)) { - await bot.events.dispatchRequirements(bot, message, shardId); - } +app.get('/timecheck', async (_req, res) => { + res.status(200).send({ message: Date.now() }) +}) - bot.handlers[message.t]?.(bot, message, shardId); - } -}; +app.post('/', async (req, res) => { + const body = req.body as GatewayEvent -const app = express(); + try { + handleGatewayEvent(body.payload, body.shardId) -app.use( - express.urlencoded({ - extended: true, - }), -); + res.status(200).send() + } catch (error) { + bot.logger.error('There was an error handling the incoming gateway command', error) + res.status(500).send() + } +}) -app.use(express.json()); +await app.listen({ + host: EVENT_HANDLER_HOST, + port: EVENT_HANDLER_PORT, +}) -app.all('/', async (req, res) => { - try { - if (!EVENT_HANDLER_AUTHORIZATION || EVENT_HANDLER_AUTHORIZATION !== req.headers.authorization) { - return res.status(401).json({ error: 'Invalid authorization key.' }); - } +bot.logger.info(`Bot event handler is listening on port ${EVENT_HANDLER_PORT}`) - const json = req.body as { - message: DiscordGatewayPayload; - shardId: number; - }; +async function handleGatewayEvent(payload: DiscordGatewayPayload, shardId: number): Promise { + bot.events.raw?.(payload, shardId) - await handleEvent(json.message, json.shardId); + // If we don't have the event type we don't process it further + if (!payload.t) return - res.status(200).json({ success: true }); - } catch (error: any) { - bot.logger.error(error); - res.status(error.code).json(error); - } -}); + // Run the dispatch check + await bot.events.dispatchRequirements?.(payload, shardId) -app.listen(EVENT_HANDLER_PORT, () => { - console.log(`Bot is listening at ${EVENT_HANDLER_URL};`); -}); - -const connectRabbitmq = async () => { - let connection: amqplib.Connection | undefined; - - try { - connection = await amqplib.connect( - `amqp://${process.env.MESSAGEQUEUE_USERNAME}:${process.env.MESSAGEQUEUE_PASSWORD}@${process.env.MESSAGEQUEUE_URL}`, - ); - } catch (error) { - console.error(error); - setTimeout(connectRabbitmq, 1000); - } - - if (!connection) return; - connection.on('error', (err) => { - console.error(err); - setTimeout(connectRabbitmq, 1000); - }); - - connection.on('close', () => { - setTimeout(connectRabbitmq, 1000); - }); - - try { - const channel = await connection.createChannel(); - - await channel.assertExchange('gatewayMessage', 'x-message-deduplication', { - durable: true, - arguments: { - 'x-cache-size': 1000, - 'x-cache-ttl': 500, - }, - }); - - await channel.assertQueue('gatewayMessageQueue'); - await channel.bindQueue('gatewayMessageQueue', 'gatewayMessage', ''); - await channel.consume( - 'gatewayMessageQueue', - async (msg) => { - if (!msg) return; - const json = JSON.parse(msg.content.toString()) as { - message: DiscordGatewayPayload; - shardId: number; - }; - - await handleEvent(json.message, json.shardId); - - await channel.ack(msg); - }, - { - noAck: false, - }, - ); - } catch (error) { - console.error(error); - } -}; - -if (process.env.MESSAGEQUEUE_ENABLE === 'true') { - connectRabbitmq(); + bot.handlers[payload.t as GatewayDispatchEventNames]?.(bot, payload, shardId) +} + +async function connectToRabbitMQ(): Promise { + const connection = await connectAmqp(`amqp://${MESSAGEQUEUE_USERNAME}:${MESSAGEQUEUE_PASSWORD}@${MESSAGEQUEUE_URL}`).catch((error) => { + bot.logger.error('Failed to connect to RabbitMQ, retrying in 1s.', error) + setTimeout(connectToRabbitMQ, 1000) + }) + + if (!connection) return + + connection.on('close', () => { + setTimeout(connectToRabbitMQ, 1000) + }) + connection.on('error', (error) => { + bot.logger.error('There was an error in the connection with RabbitMQ, reconnecting in 1s.', error) + setTimeout(connectToRabbitMQ, 1000) + }) + + const channel = await connection.createChannel().catch((error) => { + bot.logger.error('There was an error creating the RabbitMQ channel', error) + }) + + if (!channel) return + + const exchange = await channel + .assertExchange('gatewayMessage', 'x-message-deduplication', { + durable: true, + arguments: { + 'x-cache-size': 1000, // maximum number of entries + 'x-cache-ttl': 500, // 500ms + }, + }) + .catch((error) => { + bot.logger.error('There was an error asserting the exchange', error) + }) + + if (!exchange) return + + await channel.assertQueue('gatewayMessageQueue').catch(bot.logger.error) + await channel.bindQueue('gatewayMessageQueue', 'gatewayMessage', '').catch(bot.logger.error) + await channel + .consume('gatewayMessageQueue', async (message) => { + if (!message) return + + try { + const messageBody = JSON.parse(message.content.toString()) as GatewayEvent + + await handleGatewayEvent(messageBody.payload, messageBody.shardId) + + channel.ack(message) + } catch (error) { + bot.logger.error('There was an error handling events received from RabbitMQ', error) + } + }) + .catch(bot.logger.error) +} + +interface GatewayEvent { + payload: DiscordGatewayPayload + shardId: number } diff --git a/examples/bigbot/src/bot/languages/english.ts b/examples/bigbot/src/bot/languages/english.ts deleted file mode 100644 index 08b37aa4d..000000000 --- a/examples/bigbot/src/bot/languages/english.ts +++ /dev/null @@ -1,23 +0,0 @@ -const english = { - // Permissions - NEED_VIP: '❌ Only VIP users or servers can use this feature.', - - // Execute Command - EXECUTE_COMMAND_NOT_FOUND: '❌ Something went wrong. I was not able to find this command.', - EXECUTE_COMMAND_ERROR: '❌ Something went wrong. The command execution has thrown an error.', - - // Language Command - LANGUAGE_NAME: 'language', - LANGUAGE_DESCRIPTION: '⚙️ Change the bots language.', - LANGUAGE_KEY_NAME: 'name', - LANGUAGE_KEY_DESCRIPTION: 'What language would you like to set?', - LANGUAGE_UPDATED: (language: string) => `The language has been updated to ${language}`, - - // Ping Command - PING_NAME: 'ping', - PING_DESCRIPTION: '🏓 Check whether the bot is online and responsive.', - PING_RESPONSE: '🏓 Pong! I am online and responsive! :clock10:', - PING_RESPONSE_WITH_TIME: (time: number) => `🏓 Pong! ${time / 1000} seconds! I am online and responsive! :clock10:`, -} as const; - -export default english; diff --git a/examples/bigbot/src/bot/languages/languages.ts b/examples/bigbot/src/bot/languages/languages.ts deleted file mode 100644 index ca1142f49..000000000 --- a/examples/bigbot/src/bot/languages/languages.ts +++ /dev/null @@ -1,20 +0,0 @@ -import english from './english.js'; -// import french from './french' -// import german from './german' -// import portuguese from './portuguese' -// import russian from './russian' -// import spanish from './spanish' - -const languages: Record & Record = { - english, - // french, - // german, - // portuguese, - // russian, - // spanish, -}; - -export default languages; - -export type Language = Record string)>; -export type LanguageNames = 'english'; diff --git a/examples/bigbot/src/bot/languages/translate.ts b/examples/bigbot/src/bot/languages/translate.ts deleted file mode 100644 index 492ec860f..000000000 --- a/examples/bigbot/src/bot/languages/translate.ts +++ /dev/null @@ -1,84 +0,0 @@ -import Embeds from 'discordeno/embeds'; -import { bot } from '../bot.js'; -import { webhookURLToIDAndToken } from '../utils/webhook.js'; -import type english from './english.js'; -import languages from './languages.js'; - -const MISSING_TRANSLATION_WEBHOOK = process.env.MISSING_TRANSLATION_WEBHOOK; - -/** This should hold the language names per guild id. */ -export const serverLanguages = new Map(); - -export function translate( - guildIdOrLanguage: bigint | keyof typeof languages, - key: K, - ...params: getArgs -): string { - const language = getLanguage(guildIdOrLanguage); - let value: string | ((...any: any[]) => string) | string[] | undefined = languages[language]?.[key]; - - // Was not able to be translated - if (!value) { - // Check if this key is available in english - if (language !== 'english') { - value = languages.english[key]; - } - - // Still not found in english so default to using the KEY_ITSELF - if (!value) value = key; - - // Send a log webhook so the devs know sth is missing - missingTranslation(language, key); - } - - if (Array.isArray(value)) return value.join('\n'); - - if (typeof value === 'function') return value(...(params || [])); - - return value; -} - -/** Get the language this guild has set, will always return "english" if it is not in cache */ -export function getLanguage(guildIdOrLanguage: bigint | keyof typeof languages) { - return typeof guildIdOrLanguage === 'string' - ? guildIdOrLanguage - : serverLanguages.get(guildIdOrLanguage) ?? 'english'; -} - -export async function loadLanguage(guildId: bigint) { - // TODO: add this settings - // const settings = await database.findOne('guilds', guildId) - const settings = { language: 'undefined' }; - - if (settings?.language && languages[settings.language]) { - serverLanguages.set(guildId, settings.language); - } else serverLanguages.set(guildId, 'english'); -} - -/** Send a webhook for a missing translation key */ -export async function missingTranslation(language: keyof typeof languages, key: string) { - if (!MISSING_TRANSLATION_WEBHOOK) return; - const { id, token } = webhookURLToIDAndToken(MISSING_TRANSLATION_WEBHOOK); - if (!id || !token) return; - - const embeds = new Embeds() - .setTitle('Missing Translation') - .setColor('RANDOM') - .addField('Language', language, true) - .addField('Key', key, true); - - await bot.helpers - .sendWebhookMessage(bot.transformers.snowflake(id), token, { - // SETUP-DD-TEMP: If you wish to make it @ mention you, please edit the next line. - // content: `<@${owner id here}>`, - embeds, - wait: false, - }) - .catch(bot.logger.error); -} - -// type translationKeys = keyof typeof english | string -export type translationKeys = keyof typeof english; -type getArgs = (typeof english)[K] extends (...any: any[]) => unknown - ? Parameters<(typeof english)[K]> - : []; diff --git a/examples/bigbot/src/bot/register-commands.ts b/examples/bigbot/src/bot/register-commands.ts new file mode 100644 index 000000000..ba33db29e --- /dev/null +++ b/examples/bigbot/src/bot/register-commands.ts @@ -0,0 +1,5 @@ +import 'dotenv/config' + +import { updateCommands } from './utils/updateCommands.js' + +await updateCommands() diff --git a/examples/bigbot/src/bot/typings/discordeno.ts b/examples/bigbot/src/bot/typings/discordeno.ts deleted file mode 100644 index fecaf6ec0..000000000 --- a/examples/bigbot/src/bot/typings/discordeno.ts +++ /dev/null @@ -1,12 +0,0 @@ -// This file allows you to tell typescript about any additions you have made to the internal discordeno objects. -import type { Interaction, InteractionCallbackData, InteractionResponse, Message } from 'discordeno'; - -export interface InteractionWithCustomProps extends Interaction { - // Normally, to send a response you would have to do something like bot.helpers.sendInteractionResponse(interaction.id, interaction.token, { type: InteractionResponseTypes.ChannelMessageWithSource, data: { content: "text here" } }) - // But with this reply method we added, it is as simple as interaction.reply("text here"). - // Feel free to delete these comments once you have understood the concept. - /** Send a reply to an interaction. */ - reply: (response: InteractionResponse | string) => Promise; - /** Edit a deferred reply of an interaction. */ - editReply: (response: InteractionCallbackData | string) => Promise; -} diff --git a/examples/bigbot/src/bot/utils/collectors.ts b/examples/bigbot/src/bot/utils/collectors.ts deleted file mode 100644 index e9e97c2b8..000000000 --- a/examples/bigbot/src/bot/utils/collectors.ts +++ /dev/null @@ -1,151 +0,0 @@ -import type { Interaction, Member, Message } from 'discordeno'; -import { bot } from '../bot.js'; - -export async function needMessage( - memberId: bigint, - channelId: bigint, - options: MessageCollectorOptions & { amount?: 1 }, -): Promise; -export async function needMessage( - memberId: bigint, - channelId: bigint, - options: MessageCollectorOptions & { amount?: number }, -): Promise; -export async function needMessage(memberId: bigint, channelId: bigint): Promise; -export async function needMessage(memberId: bigint, channelId: bigint, options?: MessageCollectorOptions) { - const messages = await collectMessages({ - key: memberId, - channelId, - createdAt: Date.now(), - filter: options?.filter || ((msg) => memberId === msg.authorId), - amount: options?.amount || 1, - duration: options?.duration || 1000 * 60 * 5, - }); - - return (options?.amount || 1) > 1 ? messages : messages[0]; -} - -export async function collectMessages(options: CollectMessagesOptions): Promise { - return await new Promise((resolve, reject) => { - bot.collectors.messages - .get(options.key) - ?.reject('A new collector began before the user responded to the previous one.'); - - bot.collectors.messages.set(options.key, { - ...options, - messages: [], - resolve, - reject, - }); - }); -} - -export function processMessageCollectors(message: Message) { - // IGNORE DMS - if (!message.guildId) return; - - const collector = bot.collectors.messages.get(message.authorId); - // This user has no collectors pending or the message is in a different channel - if (!collector || message.channelId !== collector.channelId) return; - // This message is a response to a collector. Now running the filter function. - if (!collector.filter(message)) return; - - // If the necessary amount has been collected - if (collector.amount === 1 || collector.amount === collector.messages.length + 1) { - // Remove the collector - bot.collectors.messages.delete(message.authorId); - // Resolve the collector - return collector.resolve([...collector.messages, message]); - } - - // More messages still need to be collected - collector.messages.push(message); -} - -export interface BaseCollectorOptions { - /** The amount of messages to collect before resolving. Defaults to 1 */ - amount?: number; - /** The amount of milliseconds this should collect for before expiring. Defaults to 5 minutes. */ - duration?: number; -} - -export interface MessageCollectorOptions extends BaseCollectorOptions { - /** Function that will filter messages to determine whether to collect this message. Defaults to making sure the message is sent by the same member. */ - filter?: (message: Message) => boolean; - /** The amount of messages to collect before resolving. Defaults to 1 */ - amount?: number; - /** The amount of milliseconds this should collect for before expiring. Defaults to 5 minutes. */ - duration?: number; -} - -export interface ReactionCollectorOptions extends BaseCollectorOptions { - /** Function that will filter messages to determine whether to collect this message. Defaults to making sure the message is sent by the same member. */ - filter?: (userId: bigint, reaction: string, message: Message | { id: string }) => boolean; -} - -export interface BaseCollectorCreateOptions { - /** The unique key that will be used to get responses for this. Ideally, meant to be for member id. */ - key: bigint; - /** The amount of messages to collect before resolving. */ - amount: number; - /** The timestamp when this collector was created */ - createdAt: number; - /** The duration in milliseconds how long this collector should last. */ - duration: number; -} - -export interface CollectMessagesOptions extends BaseCollectorCreateOptions { - /** The channel Id where this is listening to */ - channelId: bigint; - /** Function that will filter messages to determine whether to collect this message */ - filter: (message: Message) => boolean; -} - -export interface CollectReactionsOptions extends BaseCollectorCreateOptions { - /** The message Id where this is listening to */ - messageId: bigint; - /** Function that will filter messages to determine whether to collect this message */ - filter: (userId: bigint, reaction: string, message: Message | { id: string }) => boolean; -} - -export interface MessageCollector extends CollectMessagesOptions { - resolve: (value: Message[] | PromiseLike) => void; - // deno-lint-ignore no-explicit-any - reject: (reason?: any) => void; - /** Where the messages are stored if the amount to collect is more than 1. */ - messages: Message[]; -} - -export interface ReactionCollector extends CollectReactionsOptions { - resolve: (value: string[] | PromiseLike) => void; - // deno-lint-ignore no-explicit-any - reject: (reason?: any) => void; - /** Where the reactions are stored if the amount to collect is more than 1. */ - reactions: string[]; -} - -export interface CollectButtonOptions extends BaseCollectorCreateOptions { - /** The message Id where this is listening to */ - messageId: bigint; - /** Function that will filter messages to determine whether to collect this message */ - filter: (message: Message, member?: Member) => boolean; -} - -export interface ButtonCollector extends CollectButtonOptions { - resolve: (value: ButtonCollectorReturn[] | PromiseLike) => void; - // deno-lint-ignore no-explicit-any - reject: (reason?: any) => void; - /** Where the buttons are stored if the amount to collect is more than 1. */ - buttons: ButtonCollectorReturn[]; -} - -export interface ButtonCollectorOptions extends BaseCollectorOptions { - /** Function that will filter messages to determine whether to collect this message. Defaults to making sure the message is sent by the same member. */ - filter?: (message: Message, member?: Member) => boolean; -} - -export interface ButtonCollectorReturn { - customId: string; - interaction: Omit; - member?: Member; -} diff --git a/examples/bigbot/src/bot/utils/internals/mod.ts b/examples/bigbot/src/bot/utils/internals/mod.ts deleted file mode 100644 index d9508bc27..000000000 --- a/examples/bigbot/src/bot/utils/internals/mod.ts +++ /dev/null @@ -1,6 +0,0 @@ -import type { BotWithCustomProps } from '../../bot.js'; -import { customizeTransformers } from './transformers/mod.js'; - -export function customizeInternals(bot: BotWithCustomProps) { - customizeTransformers(bot); -} diff --git a/examples/bigbot/src/bot/utils/internals/transformers/guild.ts b/examples/bigbot/src/bot/utils/internals/transformers/guild.ts deleted file mode 100644 index a614ead07..000000000 --- a/examples/bigbot/src/bot/utils/internals/transformers/guild.ts +++ /dev/null @@ -1,29 +0,0 @@ -// SETUP-DD-TEMP: This file is an example, of how to customize an object properties that you do not want. -// Only keep the properties your bot uses. If your bot does not use emojis in cache, you can save all that memory. -// This file is currently disabled, but you can enable it should you choose when you go the customizer file. -// Feel free to delete this comment or file as you wish. -import type { Guild } from 'discordeno'; -import { Collection } from 'discordeno'; -import type { BotWithCustomProps } from '../../../bot.js'; - -export function customizeGuildTransformer(bot: BotWithCustomProps) { - bot.transformers.guild = function (bot, payload) { - const guildId = bot.transformers.snowflake(payload.guild.id); - - return { - name: payload.guild.name, - joinedAt: payload.guild.joined_at ? Date.parse(payload.guild.joined_at) : undefined, - memberCount: payload.guild.member_count ?? 0, - shardId: payload.shardId, - icon: payload.guild.icon ? bot.utils.iconHashToBigInt(payload.guild.icon) : undefined, - roles: new Collection( - payload.guild.roles?.map((role) => { - const result = bot.transformers.role(bot, { role, guildId }); - return [result.id, result]; - }), - ), - id: guildId, - ownerId: bot.transformers.snowflake(payload.guild.owner_id), - } as unknown as Guild; - }; -} diff --git a/examples/bigbot/src/bot/utils/internals/transformers/interaction.ts b/examples/bigbot/src/bot/utils/internals/transformers/interaction.ts deleted file mode 100644 index 5129e5485..000000000 --- a/examples/bigbot/src/bot/utils/internals/transformers/interaction.ts +++ /dev/null @@ -1,40 +0,0 @@ -// SETUP-DD-TEMP: This file serves as an example, of how to customize internal discordeno objects. Feel free to use, add more or remove as desired. -import type { InteractionCallbackData, InteractionResponse } from 'discordeno'; -import { InteractionResponseTypes } from 'discordeno'; -import type { BotWithCustomProps } from '../../../bot.js'; - -export function customizeInteractionTransformer(bot: BotWithCustomProps) { - // Store the internal transformer function - const oldInteraction = bot.transformers.interaction; - - // Overwrite the internal function. - bot.transformers.interaction = function (_, payload) { - // Run the old function to get the internal value. - const interaction = oldInteraction(bot, payload); - - // Add anything to this object. In this case we add a Interaction.reply() method. - Object.defineProperty(interaction, 'reply', { - value: function (response: InteractionResponse | string) { - if (typeof response === 'string') { - response = { type: InteractionResponseTypes.ChannelMessageWithSource, data: { content: response } }; - } - - return bot.helpers.sendInteractionResponse(interaction.id, interaction.token, response); - }, - }); - Object.defineProperty(interaction, 'editReply', { - value: function (response: InteractionCallbackData | string) { - if (typeof response === 'string') { - response = { content: response }; - } - - return bot.helpers.editOriginalInteractionResponse(interaction.token, response); - }, - }); - // Add as many properties or methods you would like here. - // NOTE: Whenever you add anything here, in order to get nice autocomplete you should also add it to the src/types/discordeno.ts file. - - // Return the new customized object. - return interaction; - }; -} diff --git a/examples/bigbot/src/bot/utils/internals/transformers/mod.ts b/examples/bigbot/src/bot/utils/internals/transformers/mod.ts deleted file mode 100644 index f3c3d4c84..000000000 --- a/examples/bigbot/src/bot/utils/internals/transformers/mod.ts +++ /dev/null @@ -1,10 +0,0 @@ -import type { BotWithCustomProps } from '../../../bot.js'; -// SETUP-DD-TEMP: Enable this comment if you want to enable this customizer. -// import { customizeGuildTransformer } from "./guild.js"; -import { customizeInteractionTransformer } from './interaction.js'; - -export function customizeTransformers(bot: BotWithCustomProps) { - customizeInteractionTransformer(bot); - // SETUP-DD-TEMP: Enable this comment if you want to enable this customizer. - // customizeGuildTransformer(bot); -} diff --git a/examples/bigbot/src/bot/utils/loader.ts b/examples/bigbot/src/bot/utils/loader.ts new file mode 100644 index 000000000..ff0af7113 --- /dev/null +++ b/examples/bigbot/src/bot/utils/loader.ts @@ -0,0 +1,13 @@ +import { readdir } from 'node:fs/promises' +import { bot } from '../bot.js' + +export default async function importDirectory(folder: string): Promise { + const files = await readdir(folder, { recursive: true }) + + for (const filename of files) { + if (!filename.endsWith('.js')) continue + + // Using `file://` to avoid weird issues with paths on Windows + await import(`file://${folder}/${filename}`).catch((x) => bot.logger.fatal(`Cannot import file (${folder}/${filename}) for reason:`, x)) + } +} diff --git a/examples/bigbot/src/bot/utils/slash/createCommand.ts b/examples/bigbot/src/bot/utils/slash/createCommand.ts deleted file mode 100644 index e4e360d4d..000000000 --- a/examples/bigbot/src/bot/utils/slash/createCommand.ts +++ /dev/null @@ -1,307 +0,0 @@ -import type { - ApplicationCommandOptionTypes, - ApplicationCommandTypes, - Bot, - Channel, - Interaction, - Member, - PermissionStrings, - Role, - User, -} from 'discordeno'; -import type english from '../../languages/english.js'; -import type { translationKeys } from '../../languages/translate.js'; -import type { InteractionWithCustomProps } from '../../typings/discordeno.js'; -import type { PermissionLevelHandlers } from './permLevels.js'; - -export function createCommand(command: Command) { - return command; -} - -type UnionToIntersection = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never; - -type Identity = { [P in keyof T]: T[P] }; - -// TODO: make required by default true -// Define each of the types here -interface BaseDefinition { - description: translationKeys; -} - -// Subcommand -type SubcommandArgumentDefinition = BaseDefinition & { - name: N; - type: ApplicationCommandOptionTypes.SubCommand; - // options: Omit[] - options?: readonly ArgumentDefinition[]; -}; - -// SubcommandGroup -type SubcommandGroupArgumentDefinition = BaseDefinition & { - name: N; - type: ApplicationCommandOptionTypes.SubCommandGroup; - options: readonly SubcommandArgumentDefinition[]; -}; - -// String -type StringArgumentDefinition = BaseDefinition & { - name: N; - type: ApplicationCommandOptionTypes.String; - choices?: ReadonlyArray<{ name: string; value: string }>; - required?: true; -}; -type StringOptionalArgumentDefinition = BaseDefinition & { - name: N; - type: ApplicationCommandOptionTypes.String; - choices?: ReadonlyArray<{ name: string; value: string }>; - required?: false; -}; - -// Integer -type IntegerArgumentDefinition = BaseDefinition & { - name: N; - type: ApplicationCommandOptionTypes.Integer; - choices?: ReadonlyArray<{ name: string; value: number }>; - required: true; -}; -type IntegerOptionalArgumentDefinition = BaseDefinition & { - name: N; - type: ApplicationCommandOptionTypes.Integer; - choices?: ReadonlyArray<{ name: string; value: number }>; - required?: false; -}; - -// BOOLEAN -type BooleanArgumentDefinition = BaseDefinition & { - name: N; - type: ApplicationCommandOptionTypes.Boolean; - required: true; -}; -type BooleanOptionalArgumentDefinition = BaseDefinition & { - name: N; - type: ApplicationCommandOptionTypes.Boolean; - required?: false; -}; - -// USER -type UserArgumentDefinition = BaseDefinition & { - name: N; - type: ApplicationCommandOptionTypes.User; - required: true; -}; -type UserOptionalArgumentDefinition = BaseDefinition & { - name: N; - type: ApplicationCommandOptionTypes.User; - required?: false; -}; - -// CHANNEL -type ChannelArgumentDefinition = BaseDefinition & { - name: N; - type: ApplicationCommandOptionTypes.Channel; - required: true; -}; -type ChannelOptionalArgumentDefinition = BaseDefinition & { - name: N; - type: ApplicationCommandOptionTypes.Channel; - required?: false; -}; - -// ROLE -type RoleArgumentDefinition = BaseDefinition & { - name: N; - type: ApplicationCommandOptionTypes.Role; - required: true; -}; -type RoleOptionalArgumentDefinition = BaseDefinition & { - name: N; - type: ApplicationCommandOptionTypes.Role; - required?: false; -}; - -// MENTIONABLE -type MentionableArgumentDefinition = BaseDefinition & { - name: N; - type: ApplicationCommandOptionTypes.Mentionable; - required: true; -}; -type MentionableOptionalArgumentDefinition = BaseDefinition & { - name: N; - type: ApplicationCommandOptionTypes.Mentionable; - required?: false; -}; - -// Add each of known ArgumentDefinitions to this union. -export type ArgumentDefinition = - | StringArgumentDefinition - | StringOptionalArgumentDefinition - | IntegerArgumentDefinition - | IntegerOptionalArgumentDefinition - | BooleanArgumentDefinition - | BooleanOptionalArgumentDefinition - | UserArgumentDefinition - | UserOptionalArgumentDefinition - | ChannelArgumentDefinition - | ChannelOptionalArgumentDefinition - | RoleArgumentDefinition - | RoleOptionalArgumentDefinition - | MentionableArgumentDefinition - | MentionableOptionalArgumentDefinition - | SubcommandArgumentDefinition - | SubcommandGroupArgumentDefinition; - -type getName = (typeof english)[K] extends string ? (typeof english)[K] : never; - -// OPTIONALS MUST BE FIRST!!! -export type ConvertArgumentDefinitionsToArgs = Identity< - UnionToIntersection< - { - [P in keyof T]: T[P] extends StringOptionalArgumentDefinition // STRING - ? { - // @ts-expect-error TODO: fix this some day - [_ in getName]?: T[P]['choices'] extends ReadonlyArray<{ name: string; value: string }> // @ts-expect-error - ? T[P]['choices'][number]['value'] - : string; - } - : T[P] extends StringArgumentDefinition - ? { - // @ts-expect-error TODO: fix this some day - [_ in getName]: T[P]['choices'] extends ReadonlyArray<{ name: string; value: string }> // @ts-expect-error - ? T[P]['choices'][number]['value'] - : string; - } - : // INTEGER - T[P] extends IntegerOptionalArgumentDefinition - ? { - [_ in getName]?: T[P]['choices'] extends ReadonlyArray<{ name: string; value: number }> // @ts-expect-error - ? T[P]['choices'][number]['value'] - : number; - } - : T[P] extends IntegerArgumentDefinition - ? { - [_ in getName]: T[P]['choices'] extends ReadonlyArray<{ name: string; value: number }> // @ts-expect-error - ? T[P]['choices'][number]['value'] - : number; - } - : // BOOLEAN - T[P] extends BooleanOptionalArgumentDefinition - ? { [_ in getName]?: boolean } - : T[P] extends BooleanArgumentDefinition - ? { [_ in getName]: boolean } - : // USER - T[P] extends UserOptionalArgumentDefinition - ? { - [_ in getName]?: { - user: User; - member: Member; - }; - } - : T[P] extends UserArgumentDefinition - ? { - [_ in getName]: { - user: User; - member: Member; - }; - } - : // CHANNEL - T[P] extends ChannelOptionalArgumentDefinition - ? { [_ in getName]?: Channel } - : T[P] extends ChannelArgumentDefinition - ? { [_ in getName]: Channel } - : // ROLE - T[P] extends RoleOptionalArgumentDefinition - ? { [_ in getName]?: Role } - : T[P] extends RoleArgumentDefinition - ? { [_ in getName]: Role } - : // MENTIONABLE - T[P] extends MentionableOptionalArgumentDefinition - ? { - [_ in getName]?: - | Role - | { - user: User; - member: Member; - }; - } - : T[P] extends MentionableArgumentDefinition - ? { - [_ in getName]: - | Role - | { - user: User; - member: Member; - }; - } - : // SUBCOMMAND - T[P] extends SubcommandArgumentDefinition - ? { - [_ in getName]?: T[P]['options'] extends readonly ArgumentDefinition[] // @ts-expect-error somehow this check does not work - ? ConvertArgumentDefinitionsToArgs - : {}; - } - : // SUBCOMMANDGROUP - T[P] extends SubcommandGroupArgumentDefinition - ? { - [_ in getName]?: ConvertArgumentDefinitionsToArgs; - } - : never; - }[number] - > ->; - -export interface Command { - /** The name of the command, used for both slash and message commands. */ - name: translationKeys; - /** The type of command. */ - type?: ApplicationCommandTypes; - /** The description of the command */ - description: translationKeys; - // TODO: consider type being a string like "number" | "user" for better ux - /** The options for the command, used for both slash and message commands. */ - // options?: ApplicationCommandOption[]; - options?: T; - execute: (bot: Bot, data: InteractionWithCustomProps, args: ConvertArgumentDefinitionsToArgs) => unknown; - subcommands?: Record, 'subcommands'> & { group?: string }>; - /** Whether the command should have a cooldown */ - cooldown?: { - /** How long the user needs to wait after the first execution until he can use the command again */ - seconds: number; - /** How often the user is allowed to use the command until he is in cooldown */ - allowedUses?: number; - }; - nsfw?: boolean; - /** By default false */ - global?: boolean; - /** Dm only by default false */ - dmOnly?: boolean; - - /** VIP only by default false */ - vipOnly?: boolean; - - advanced?: boolean; - - /** Whether or not this slash command should be enabled right now. Defaults to true. */ - enabled?: boolean; - /** Whether or not this command is still in development and should be setup in the dev server for testing. */ - dev?: boolean; - /** Whether or not this command will take longer than 3s and need to acknowledge to discord. */ - acknowledge?: boolean; - - permissionLevels?: - | Array - | ((data: Interaction, command: Command) => boolean | Promise); - botServerPermissions?: PermissionStrings[]; - botChannelPermissions?: PermissionStrings[]; - userServerPermissions?: PermissionStrings[]; - userChannelPermissions?: PermissionStrings[]; -} - -export enum PermissionLevels { - Member, - Moderator, - Admin, - ServerOwner, - BotSupporter, - BotDev, - BotOwner, -} diff --git a/examples/bigbot/src/bot/utils/slash/limiter.ts b/examples/bigbot/src/bot/utils/slash/limiter.ts deleted file mode 100644 index d6cb48ccc..000000000 --- a/examples/bigbot/src/bot/utils/slash/limiter.ts +++ /dev/null @@ -1,31 +0,0 @@ -import COMMANDS from '../../commands/mod.js'; - -export async function validateSlashLimits() { - const MAX_ALLOWED_CHARACTERS = 4000; - - const commands = await fetch('https://cmd-counter-play.deno.dev/', { - body: JSON.stringify(COMMANDS), - headers: { - 'content-type': 'application/json', - }, - }) - .then(async (res) => await res.json()) - .catch(() => undefined); - - if (!commands) return; - - const invalidCommandNames: string[] = []; - - if (commands[0]?.characters > MAX_ALLOWED_CHARACTERS) { - for (const command of commands) { - if (command.characters <= MAX_ALLOWED_CHARACTERS) continue; - - invalidCommandNames.push(command.name); - console.log( - `[Invalid Command] The ${command.name} is not a valid command. It's total characters are (${command.characters}) which is more than the max allowed ${MAX_ALLOWED_CHARACTERS}.`, - ); - } - } - - if (invalidCommandNames.length) throw new Error(`[Startup] Invalid commands: ${invalidCommandNames.join(', ')}`); -} diff --git a/examples/bigbot/src/bot/utils/slash/permLevels.ts b/examples/bigbot/src/bot/utils/slash/permLevels.ts deleted file mode 100644 index 38cc3a70f..000000000 --- a/examples/bigbot/src/bot/utils/slash/permLevels.ts +++ /dev/null @@ -1,48 +0,0 @@ -import type { Interaction } from 'discordeno'; -import { validatePermissions } from 'discordeno/permissions-plugin'; -import type { Command } from './createCommand.js'; - -export default async function hasPermissionLevel(command: Command, payload: Interaction) { - // This command doesnt require a perm level so allow the command. - if (!command.permissionLevels) return true; - - // If a custom function was provided - if (typeof command.permissionLevels === 'function') { - return await command.permissionLevels(payload, command); - } - - // If an array of perm levels was provided - for (const permlevel of command.permissionLevels) { - // If this user has one of the allowed perm level, the loop is canceled and command is allowed. - if (await PermissionLevelHandlers[permlevel](payload, command)) return true; - } - - // None of the perm levels were met. So cancel the command - return false; -} - -export const PermissionLevelHandlers: Record< - keyof typeof PermissionLevels, - (payload: Interaction, command: Command) => boolean | Promise -> = { - MEMBER: () => true, - MODERATOR: (payload) => - Boolean(payload.member?.permissions) && validatePermissions(payload.member!.permissions!, ['MANAGE_GUILD']), - ADMIN: (payload) => - Boolean(payload.member?.permissions) && validatePermissions(payload.member!.permissions!, ['ADMINISTRATOR']), - // TODO(cache): fix this - SERVER_OWNER: () => false, - BOT_SUPPORT: () => false, - BOT_DEVS: () => false, - BOT_OWNERS: (payload) => [130136895395987456n, 615542460151496705n].includes(payload.user.id), -}; - -export enum PermissionLevels { - MEMBER, - MODERATOR, - ADMIN, - SERVER_OWNER, - BOT_SUPPORT, - BOT_DEVS, - BOT_OWNERS, -} diff --git a/examples/bigbot/src/bot/utils/slash/updateCommands.ts b/examples/bigbot/src/bot/utils/slash/updateCommands.ts deleted file mode 100644 index 43bc9d69a..000000000 --- a/examples/bigbot/src/bot/utils/slash/updateCommands.ts +++ /dev/null @@ -1,149 +0,0 @@ -import type { ApplicationCommandOption, Bot } from 'discordeno'; -import { ApplicationCommandTypes } from 'discordeno'; -import { prisma } from '../../../prisma.js'; -import { bot } from '../../bot.js'; -import COMMANDS from '../../commands/mod.js'; -import { serverLanguages, translate } from '../../languages/translate.js'; -import type { ArgumentDefinition } from './createCommand.js'; - -const DEV_SERVER_ID = process.env.DEV_SERVER_ID as string; - -export async function updateDevCommands(bot: Bot) { - const cmds = Object.entries(COMMANDS) - // ONLY DEV COMMANDS - .filter(([_name, command]) => command?.dev); - - if (!cmds.length) return; - - // DEV RELATED COMMANDS, USE upsertGlobalApplicationCommands TO UPDATE GLOBALLY - await bot.helpers.upsertGuildApplicationCommands( - bot.transformers.snowflake(DEV_SERVER_ID), - cmds.map(([name, command]) => { - const translatedName = translate(DEV_SERVER_ID, command.name); - const translatedDescription = command.description ? translate(DEV_SERVER_ID, command.description) : ''; - - if (command.type && command.type !== ApplicationCommandTypes.ChatInput) { - return { - name: (translatedName || name).toLowerCase(), - type: command.type, - }; - } - - return { - name: (translatedName || name).toLowerCase(), - description: translatedDescription || command.description, - options: command.options - ? createOptions(bot.transformers.snowflake(DEV_SERVER_ID), command.options, command.name) - : undefined, - }; - }), - ); -} - -// SETUP-DD-TEMP: You can make this able to be updated dynicamally by moving this value to something in the database and having a command to update it on the fly or as part of CI. -export const CURRENT_SLASH_COMMAND_VERSION = 1; - -/** Whether the guild has the latest slash command version */ -export async function usesLatestCommandVersion(guildId: bigint): Promise { - return (await getCurrentCommandVersion(guildId)) === CURRENT_SLASH_COMMAND_VERSION; -} - -/** Get the current slash command version for this guild */ -export async function getCurrentCommandVersion(guildId: bigint): Promise { - if (bot.commandVersions.has(guildId)) return bot.commandVersions.get(guildId)!; - - const commandVersion = await prisma.commands.findUnique({ where: { id: guildId } }); - if (commandVersion) bot.commandVersions.set(guildId, commandVersion.version); - - return commandVersion?.version ?? 0; -} - -export async function updateCommandVersion(guildId: bigint): Promise { - // UPDATE THE VERSION SAVED IN THE DB - await prisma.commands.upsert({ - where: { id: guildId }, - create: { id: guildId, version: CURRENT_SLASH_COMMAND_VERSION }, - update: { version: CURRENT_SLASH_COMMAND_VERSION }, - }); - - bot.commandVersions.set(guildId, CURRENT_SLASH_COMMAND_VERSION); - return CURRENT_SLASH_COMMAND_VERSION; -} - -export async function updateGuildCommands(bot: Bot, guildId: bigint) { - if (guildId === 547046977578336286n) return await updateDevCommands(bot); - - await updateCommandVersion(guildId); - - // GUILD RELATED COMMANDS - await bot.helpers.upsertGuildApplicationCommands( - guildId, - Object.entries(COMMANDS) - // ONLY GUILD COMMANDS - .filter(([_name, command]) => !command.global && !command.dev) - .map(([name, command]) => { - // USER OPTED TO USE BASIC VERSION ONLY - if (command.advanced === false) { - return { - name, - description: translate('english', command.description), - options: command.options ? createOptions('english', command.options, command.name) : undefined, - }; - } - - // ADVANCED VERSION WILL ALLOW TRANSLATION - const translatedName = translate(guildId, command.name); - const translatedDescription = translate(guildId, command.description); - - return { - name: translatedName.toLowerCase(), - description: translatedDescription, - options: command.options ? createOptions(guildId, command.options, command.name) : undefined, - }; - }), - ); -} - -// USED TO CACHE CONVERTED COMMANDS AFTER START TO PREVENT UNNECESSARY LOOPS -const convertedCache = new Map(); - -/** Creates the commands options including subcommands. Also translates them. */ -function createOptions( - guildId: bigint | 'english', - options: readonly ArgumentDefinition[], - commandName?: string, -): ApplicationCommandOption[] | undefined { - const language = guildId === 'english' ? 'english' : serverLanguages.get(guildId) ?? 'english'; - if (commandName && convertedCache.has(`${language}-${commandName}`)) { - return convertedCache.get(`${language}-${commandName}`)!; - } - - const newOptions: ApplicationCommandOption[] = []; - - for (const option of options || []) { - const optionName = translate(guildId, option.name); - const optionDescription = translate(guildId, option.description); - - // TODO: remove this ts ignore - // @ts-expect-error - const choices = option.choices?.map((choice) => ({ - ...choice, - name: translate(guildId, choice.name), - })); - - newOptions.push({ - ...option, - name: optionName.toLowerCase(), - description: optionDescription || 'No description available.', - choices, - // @ts-expect-error fix this - options: option.options - ? // @ts-expect-error fix this - createOptions(bot, guildId, option.options) - : undefined, - } as ApplicationCommandOption); - } - if (commandName) convertedCache.set(`${language}-${commandName}`, newOptions); - - return newOptions; -} diff --git a/examples/bigbot/src/bot/utils/updateCommands.ts b/examples/bigbot/src/bot/utils/updateCommands.ts new file mode 100644 index 000000000..52ed9b3a4 --- /dev/null +++ b/examples/bigbot/src/bot/utils/updateCommands.ts @@ -0,0 +1,19 @@ +import assert from 'node:assert' +import { DEVELOPMENT, DEV_SERVER_ID } from '../../config.js' +import { bot } from '../bot.js' + +export async function updateCommands(): Promise { + bot.logger.info('Updating commands') + + const userCommands = bot.commands.filter((x) => !x.devOnly).array() + await bot.helpers.upsertGlobalApplicationCommands(userCommands) + + if (DEVELOPMENT) { + assert(DEV_SERVER_ID, 'The DEV_SERVER_ID environment is missing') + + bot.logger.info('Updating developer commands') + + const devCommands = bot.commands.filter((x) => x.devOnly ?? false).array() + await bot.helpers.upsertGuildApplicationCommands(DEV_SERVER_ID, devCommands) + } +} diff --git a/examples/bigbot/src/bot/utils/webhook.ts b/examples/bigbot/src/bot/utils/webhook.ts index b4897f0a6..2dea8f7f6 100644 --- a/examples/bigbot/src/bot/utils/webhook.ts +++ b/examples/bigbot/src/bot/utils/webhook.ts @@ -1,9 +1,9 @@ /** Get the webhook id and token from a webhook url. */ -export function webhookURLToIDAndToken(url: string) { - const [id, token] = url.substring(url.indexOf('webhooks/') + 9).split('/'); +export function webhookURLToIDAndToken(url: string): { id?: string; token?: string } { + const [id, token] = url.substring(url.indexOf('webhooks/') + 9).split('/') - return { - id, - token, - }; + return { + id, + token, + } } diff --git a/examples/bigbot/src/config.ts b/examples/bigbot/src/config.ts new file mode 100644 index 000000000..5d70ad6fc --- /dev/null +++ b/examples/bigbot/src/config.ts @@ -0,0 +1,77 @@ +import { Intents } from '@discordeno/bot' +import 'dotenv/config' + +// #region Mapping of environment variables to javascript variables with some minimal parsing + +// General Configurations + +export const DEVELOPMENT = process.env.DEVELOPMENT ?? false +export const DEV_SERVER_ID = process.env.DEV_SERVER_ID +export const DISCORD_TOKEN = assertEnv('DISCORD_TOKEN') + +// Bot Configuration + +export const EVENT_HANDLER_AUTHORIZATION = assertEnv('EVENT_HANDLER_AUTHORIZATION') + +export const EVENT_HANDLER_HOST = assertEnv('EVENT_HANDLER_HOST') +export const EVENT_HANDLER_PORT = parseNumber(assertEnv('EVENT_HANDLER_PORT'), 'EVENT_HANDLER_PORT') + +export const BUGS_ERRORS_REPORT_WEBHOOK = process.env.BUGS_ERRORS_REPORT_WEBHOOK + +// Rest Proxy Configurations + +export const REST_AUTHORIZATION = assertEnv('REST_AUTHORIZATION') +export const REST_HOST = assertEnv('REST_HOST') +export const REST_PORT = parseNumber(assertEnv('REST_PORT'), 'REST_PORT') + +// Gateway Proxy Configurations + +export const TOTAL_SHARDS = process.env.TOTAL_SHARDS ? parseNumber(process.env.TOTAL_SHARDS, 'TOTAL_SHARDS') : undefined +export const SHARDS_PER_WORKER = parseNumber(process.env.SHARDS_PER_WORKER ?? '16', 'SHARDS_PER_WORKER') +export const TOTAL_WORKERS = parseNumber(process.env.TOTAL_WORKERS ?? '4', 'TOTAL_WORKERS') + +export const GATEWAY_AUTHORIZATION = assertEnv('GATEWAY_AUTHORIZATION') +export const GATEWAY_HOST = assertEnv('GATEWAY_HOST') +export const GATEWAY_PORT = parseNumber(assertEnv('GATEWAY_PORT'), 'GATEWAY_PORT') + +// Message queue (RabbitMQ configuration) + +export const MESSAGEQUEUE_ENABLE = process.env.MESSAGEQUEUE_ENABLE ?? false + +export const MESSAGEQUEUE_URL = process.env.MESSAGEQUEUE_URL +export const MESSAGEQUEUE_USERNAME = process.env.MESSAGEQUEUE_USERNAME +export const MESSAGEQUEUE_PASSWORD = process.env.MESSAGEQUEUE_PASSWORD + +// Analytics (InfluxDB configuration) + +export const INFLUX_ORG = process.env.INFLUX_ORG +export const INFLUX_BUCKET = process.env.INFLUX_BUCKET +export const INFLUX_TOKEN = process.env.INFLUX_TOKEN +export const INFLUX_URL = process.env.INFLUX_URL + +export const INFLUX_ENABLED = INFLUX_URL && INFLUX_TOKEN && INFLUX_ORG && INFLUX_BUCKET + +// #endregion + +export const EVENT_HANDLER_URL = `http://${EVENT_HANDLER_HOST}:${EVENT_HANDLER_PORT}` +export const REST_URL = `http://${REST_HOST}:${REST_PORT}` +export const GATEWAY_URL = `http://${GATEWAY_HOST}:${GATEWAY_PORT}` + +// TEMPLATE-SETUP: Add/Remove the intents you need/don't need +export const GATEWAY_INTENTS = Intents.Guilds | Intents.GuildMessages + +// Helper functions + +function assertEnv(env: string): string { + if (process.env[env]) return process.env[env]! + + throw new TypeError(`The '${env}' environment variable must be set`) +} + +function parseNumber(envValue: string, env: string): number { + const parsed = Number.parseInt(envValue) + + if (Number.isFinite(parsed)) return parsed + + throw new TypeError(`The '${env}' environment variable must be a number`) +} diff --git a/examples/bigbot/src/configs.ts b/examples/bigbot/src/configs.ts deleted file mode 100644 index dc185ea76..000000000 --- a/examples/bigbot/src/configs.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { getBotIdFromToken, Intents } from 'discordeno'; -import dotenv from 'dotenv'; -dotenv.config(); - -/** The bot id, derived from the bot token. */ -export const BOT_ID = getBotIdFromToken(process.env.DISCORD_TOKEN as string); -export const EVENT_HANDLER_URL = `http://${process.env.EVENT_HANDLER_HOST}:${process.env.EVENT_HANDLER_PORT}`; -export const REST_URL = `http://${process.env.REST_HOST}:${process.env.REST_PORT}`; -export const GATEWAY_URL = `http://${process.env.GATEWAY_HOST}:${process.env.GATEWAY_PORT}`; - -// Gateway Proxy Configurations -/** The gateway intents you would like to use. */ -export const INTENTS: Intents = - // SETUP-DD-TEMP: Add the intents you want enabled here. Or Delete the intents you don't want in your bot. - Intents.DirectMessageReactions | - Intents.DirectMessageTyping | - Intents.DirectMessages | - Intents.GuildBans | - Intents.GuildEmojis | - Intents.GuildIntegrations | - Intents.GuildInvites | - Intents.GuildMembers | - Intents.GuildMessageReactions | - Intents.GuildMessageTyping | - Intents.GuildMessages | - Intents.GuildPresences | - Intents.GuildVoiceStates | - Intents.GuildWebhooks | - Intents.Guilds; diff --git a/examples/bigbot/src/gateway/README.md b/examples/bigbot/src/gateway/README.md deleted file mode 100644 index 9459a4af8..000000000 --- a/examples/bigbot/src/gateway/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# Big Bot Gateway Proxy Server - -This folder will contain the code for our gateway. When events are received from Discord they are sent here and this -proxy will forward them to our event handler. - -## Further Steps - -- Resharding diff --git a/examples/bigbot/src/gateway/fastify.ts b/examples/bigbot/src/gateway/fastify.ts new file mode 100644 index 000000000..35e6aa159 --- /dev/null +++ b/examples/bigbot/src/gateway/fastify.ts @@ -0,0 +1,17 @@ +import fastify, { type FastifyInstance } from 'fastify' +import { GATEWAY_AUTHORIZATION } from '../config.js' + +export function buildFastifyApp(): FastifyInstance { + const app = fastify() + + // Authorization check + app.addHook('onRequest', async (req, res) => { + if (req.headers.authorization !== GATEWAY_AUTHORIZATION) { + res.status(401).send({ + message: 'Credentials not valid.', + }) + } + }) + + return app +} diff --git a/examples/bigbot/src/gateway/gatewayManager.ts b/examples/bigbot/src/gateway/gatewayManager.ts new file mode 100644 index 000000000..730f661f9 --- /dev/null +++ b/examples/bigbot/src/gateway/gatewayManager.ts @@ -0,0 +1,66 @@ +import { createGatewayManager, createLogger, createRestManager, LogDepth } from '@discordeno/bot' +import type { Worker } from 'node:worker_threads' +import { DISCORD_TOKEN, GATEWAY_INTENTS, REST_AUTHORIZATION, REST_URL, SHARDS_PER_WORKER, TOTAL_SHARDS, TOTAL_WORKERS } from '../config.js' +import { createWorker } from './worker/createWorker.js' +import type { WorkerMessage } from './worker/types.js' + +export const workers = new Map() +export const logger = createLogger({ name: 'GATEWAY' }) +logger.setDepth(LogDepth.Full) + +const restManager = createRestManager({ + token: DISCORD_TOKEN, + proxy: { + baseUrl: REST_URL, + authorization: REST_AUTHORIZATION, + }, +}) + +const gatewayBotConfig = await restManager.getGatewayBot() + +const gatewayManager = createGatewayManager({ + token: DISCORD_TOKEN, + intents: GATEWAY_INTENTS, + connection: gatewayBotConfig, + shardsPerWorker: SHARDS_PER_WORKER, + totalShards: TOTAL_SHARDS, + totalWorkers: TOTAL_WORKERS, +}) + +gatewayManager.tellWorkerToIdentify = async (workerId, shardId, bucketId) => { + logger.info(`Tell worker to identify, workerId: ${workerId}, shardId: ${shardId}, bucketId: ${bucketId}`) + + const worker = workers.get(workerId) ?? createWorker(workerId) + workers.set(workerId, worker) + + worker.postMessage({ + type: 'IdentifyShard', + shardId, + } satisfies WorkerMessage) +} + +gatewayManager.sendPayload = async (shardId, payload) => { + const workerId = gatewayManager.calculateWorkerId(shardId) + const worker = workers.get(workerId) + + if (!worker) return + + worker.postMessage({ + type: 'ShardPayload', + shardId, + payload, + } satisfies WorkerMessage) +} + +gatewayManager.editBotStatus = async (payload) => { + const workersArray = Array.from(workers.values()) + + for (const worker of workersArray) { + worker.postMessage({ + type: 'EditShardsPresence', + payload, + } satisfies WorkerMessage) + } +} + +export default gatewayManager diff --git a/examples/bigbot/src/gateway/index.ts b/examples/bigbot/src/gateway/index.ts index 3ca1eece8..d81def825 100644 --- a/examples/bigbot/src/gateway/index.ts +++ b/examples/bigbot/src/gateway/index.ts @@ -1,204 +1,72 @@ -import dotenv from 'dotenv'; +import { GATEWAY_HOST, GATEWAY_PORT } from '../config.js' +import { promiseWithResolvers } from '../util.js' +import { buildFastifyApp } from './fastify.js' +import gatewayManager, { logger, workers } from './gatewayManager.js' +import { shardInfoRequests } from './worker/createWorker.js' +import type { ManagerGetShardInfoFromGuildId, ShardInfo, WorkerMessage, WorkerPresencesUpdate, WorkerShardPayload } from './worker/types.js' -import { Collection, createBot, createGatewayManager, createRestManager } from 'discordeno'; -import { createLogger } from 'discordeno/logger'; -import fastify from 'fastify'; -import { nanoid } from 'nanoid'; -import { Worker } from 'worker_threads'; -import { EVENT_HANDLER_URL, INTENTS, REST_URL } from '../configs.js'; -import type { - WorkerCreateData, - WorkerGetShardInfo, - WorkerMessage, - WorkerShardInfo, - WorkerShardPayload, -} from './worker.js'; -dotenv.config(); +const app = buildFastifyApp() -const DISCORD_TOKEN = process.env.DISCORD_TOKEN as string; -const EVENT_HANDLER_AUTHORIZATION = process.env.EVENT_HANDLER_AUTHORIZATION as string; -const GATEWAY_AUTHORIZATION = process.env.GATEWAY_AUTHORIZATION as string; -const GATEWAY_PORT = Number(process.env.GATEWAY_PORT as string); -const REST_AUTHORIZATION = process.env.REST_AUTHORIZATION as string; -const SHARDS_PER_WORKER = Number(process.env.SHARDS_PER_WORKER as string); -const TOTAL_SHARDS = process.env.TOTAL_SHARDS ? Number(process.env.TOTAL_SHARDS) : undefined; -const TOTAL_WORKERS = Number(process.env.TOTAL_WORKERS as string); +app.get('/timecheck', (_req, res) => { + res.status(200).send({ message: Date.now() }) +}) -const log = createLogger({ name: '[MANAGER]' }); +app.post('/', async (req, res) => { + if (!req.body) { + res.status(400).send({ message: 'Invalid body' }) + return + } -const bot = createBot({ - token: DISCORD_TOKEN, -}); + const data = req.body as WorkerShardPayload | WorkerPresencesUpdate | ManagerGetShardInfoFromGuildId -bot.rest = createRestManager({ - token: DISCORD_TOKEN, - secretKey: REST_AUTHORIZATION, - customUrl: REST_URL, -}); + if (data.type === 'ShardPayload') { + await gatewayManager.sendPayload(data.shardId, data.payload) + return + } + if (data.type === 'EditShardsPresence') { + await gatewayManager.editBotStatus(data.payload) + return + } + if (data.type === 'ShardInfoFromGuild') { + // If we don't have a guildId, we use shard 0 + const shardId = data.guildId ? gatewayManager.calculateShardId(data.guildId) : 0 + const workerId = gatewayManager.calculateWorkerId(shardId) + const worker = workers.get(workerId) -const gatewayBot = await bot.helpers.getGatewayBot(); + if (!worker) { + await res.status(400).send({ error: `worker for shard ${shardId} not found` }) + return + } -const gateway = createGatewayManager({ - gatewayBot, - gatewayConfig: { - token: DISCORD_TOKEN, - intents: INTENTS, - }, - // force the total amount of shards - totalShards: TOTAL_SHARDS, - shardsPerWorker: SHARDS_PER_WORKER, - totalWorkers: TOTAL_WORKERS, + const nonce = crypto.randomUUID() - handleDiscordPayload: () => {}, + const { promise, resolve } = promiseWithResolvers() - tellWorkerToIdentify: async (_gateway, workerId, shardId, _bucketId) => { - log.info('TELL TO IDENTIFY', { workerId, shardId, _bucketId }); + shardInfoRequests.set(nonce, resolve) - let worker = workers.get(workerId); - if (!worker) { - worker = createWorker(workerId); - workers.set(workerId, worker); - } + worker.postMessage({ + type: 'GetShardInfo', + shardId, + nonce, + } satisfies WorkerMessage) - const identify: WorkerMessage = { - type: 'IDENTIFY_SHARD', - shardId, - }; + const shardInfo = await promise - worker.postMessage(identify); - }, -}); + await res.status(200).send({ + shardId: shardInfo.shardId, + rtt: shardInfo.rtt, + } satisfies Omit) + return + } -const workers = new Collection(); -const nonces = new Collection void>(); + logger.warn(`Manager - Received unknown data type: ${(data as { type: string }).type}`) +}) -function createWorker(workerId: number) { - console.log(TOTAL_SHARDS, gateway.manager.totalShards, 'SHARDS'); +await app.listen({ + host: GATEWAY_HOST, + port: GATEWAY_PORT, +}) - const workerData: WorkerCreateData = { - intents: gateway.manager.gatewayConfig.intents ?? 0, - token: DISCORD_TOKEN, - handlerUrls: [EVENT_HANDLER_URL], - handlerAuthorization: EVENT_HANDLER_AUTHORIZATION, - path: './worker.ts', - totalShards: gateway.manager.totalShards, - workerId, - }; +logger.info(`Gateway manager listening on port ${GATEWAY_PORT}`) - const worker = new Worker('./dist/gateway/worker.js', { - workerData, - }); - - worker.on('message', async (data: ManagerMessage) => { - log.info({ data }); - switch (data.type) { - case 'REQUEST_IDENTIFY': { - log.info('REQUESTING IDENTIFY #', data.shardId); - await gateway.manager.requestIdentify(data.shardId); - - const allowIdentify: WorkerMessage = { - type: 'ALLOW_IDENTIFY', - shardId: data.shardId, - }; - - worker.postMessage(allowIdentify); - - break; - } - case 'NONCE_REPLY': { - nonces.get(data.nonce)?.(data.data); - } - } - }); - - return worker; -} - -gateway.spawnShards(); - -const server = fastify(); - -server.post('/', async (request, reply) => { - if (request.headers.authorization !== GATEWAY_AUTHORIZATION) { - reply.code(StatusCodes.Unauthorized); - - return reply.send({ processing: false, error: false, message: 'Invalid authorization header.' }); - } - - if (!request.body) { - reply.code(StatusCodes.BadRequest); - - return reply.send({ processing: false, error: false, message: 'Empty body.' }); - } - - try { - const data = request.body as WorkerShardPayload | Omit; - switch (data.type) { - case 'SHARD_PAYLOAD': { - const workerId = gateway.calculateWorkerId(data.shardId); - const worker = workers.get(workerId); - - worker?.postMessage(data); - - break; - } - case 'GET_SHARD_INFO': { - const infos = await Promise.all( - workers.map(async (worker) => { - const nonce = nanoid(); - - return await new Promise((resolve) => { - worker.postMessage({ type: 'GET_SHARD_INFO', nonce }); - - nonces.set(nonce, resolve); - }); - }), - ).then((res) => - res.reduce((acc, cur) => { - acc.push(...cur); - return acc; - }, [] as WorkerShardInfo[]), - ); - - reply.code(StatusCodes.Ok); - - return reply.send(infos); - } - } - - reply.code(StatusCodes.Ok); - - return reply.send({ processing: true }); - } catch { - reply.code(StatusCodes.BadRequest); - - return reply.send({ processing: false, error: true, message: 'Failed to parse body.' }); - } -}); - -server.listen({ port: GATEWAY_PORT }).catch((error) => { - log.error(['[FASTIFY ERROR', error].join('\n')); - process.exit(1); -}); - -export type ManagerMessage = ManagerRequestIdentify | ManagerNonceReply; - -export interface ManagerRequestIdentify { - type: 'REQUEST_IDENTIFY'; - shardId: number; -} - -export interface ManagerNonceReply { - type: 'NONCE_REPLY'; - nonce: string; - data: T; -} - -enum StatusCodes { - Ok = 200, - - BadRequest = 400, - Unauthorized = 401, - - InternalServerError = 500, -} +await gatewayManager.spawnShards() diff --git a/examples/bigbot/src/gateway/worker.ts b/examples/bigbot/src/gateway/worker.ts deleted file mode 100644 index 7987af85a..000000000 --- a/examples/bigbot/src/gateway/worker.ts +++ /dev/null @@ -1,230 +0,0 @@ -import dotenv from 'dotenv'; - -import amqplib from 'amqplib'; -import type { - DiscordGuild, - DiscordReady, - DiscordUnavailableGuild, - Shard, - ShardSocketRequest, - ShardState, -} from 'discordeno'; -import { createShardManager, GatewayEventNames } from 'discordeno'; -import { createLogger } from 'discordeno/logger'; -import fetch from 'node-fetch'; -import crypto from 'node:crypto'; -import { parentPort, workerData } from 'worker_threads'; -import type { ManagerMessage } from './index.js'; -dotenv.config(); - -if (!parentPort) { - throw new Error('Parent port is null'); -} - -const script: WorkerCreateData = workerData; - -const log = createLogger({ name: `[WORKER #${script.workerId}]` }); - -const identifyPromises = new Map void>(); - -let channel: amqplib.Channel | undefined; - -const useMessageQueue = process.env.MESSAGEQUEUE_ENABLE === 'true'; - -// Store guild ids, loading guild ids to change GUILD_CREATE event to GUILD_LOADED_DD if needed. -const guildIds: Set = new Set(); -const loadingGuildIds: Set = new Set(); - -const manager = createShardManager({ - gatewayConfig: { - intents: script.intents, - token: script.token, - }, - shardIds: [], - totalShards: script.totalShards, - handleMessage: async (shard, message) => { - const url = script.handlerUrls[shard.id % script.handlerUrls.length]; - if (!url) return console.log('ERROR: NO URL FOUND TO SEND MESSAGE'); - - if (message.t === 'READY') { - // Marks which guilds the bot in when initial loading in cache. - (message.d as DiscordReady).guilds.forEach((g) => loadingGuildIds.add(BigInt(g.id))); - } - - // If GUILD_CREATE event came from a shard loaded event, change event to GUILD_LOADED_DD. - if (message.t === 'GUILD_CREATE') { - const guild = message.d as DiscordGuild; - const id = BigInt(guild.id); - - const existing = guildIds.has(id); - if (existing) return; - - if (loadingGuildIds.has(id)) { - message.t = 'GUILD_LOADED_DD'; - - loadingGuildIds.delete(id); - } - - guildIds.add(id); - } - - // Delete guild id from cache so GUILD_CREATE from the same guild later works properly. - if (message.t === 'GUILD_DELETE') { - const guild = message.d as DiscordUnavailableGuild; - - if (guild.unavailable) return; - - guildIds.delete(BigInt(guild.id)); - } - - if (useMessageQueue) { - if (!channel) return; - await channel.publish('gatewayMessage', '', Buffer.from(JSON.stringify({ shard, message })), { - contentType: 'application/json', - headers: { - 'x-deduplication-header': crypto.createHash('md5').update(JSON.stringify(message.d)).digest('hex'), - }, - }); - } else { - await fetch(url, { - method: 'POST', - body: JSON.stringify({ message, shardId: shard.id }), - headers: { 'Content-Type': 'application/json', Authorization: script.handlerAuthorization }, - }).catch((error) => log.error(error)); - } - - log.debug({ shardId: shard.id, message }); - }, - requestIdentify: async function (shardId: number): Promise { - return await new Promise((resolve) => { - identifyPromises.set(shardId, resolve); - - const identifyRequest: ManagerMessage = { - type: 'REQUEST_IDENTIFY', - shardId, - }; - - parentPort?.postMessage(identifyRequest); - }); - }, -}); - -function buildShardInfo(shard: Shard): WorkerShardInfo { - return { - workerId: script.workerId, - shardId: shard.id, - rtt: shard.heart.rtt || -1, - state: shard.state, - }; -} - -parentPort.on('message', async (data: WorkerMessage) => { - switch (data.type) { - case 'IDENTIFY_SHARD': { - log.info(`starting to identify shard #${data.shardId}`); - await manager.identify(data.shardId); - - break; - } - case 'ALLOW_IDENTIFY': { - identifyPromises.get(data.shardId)?.(); - identifyPromises.delete(data.shardId); - - break; - } - case 'SHARD_PAYLOAD': { - manager.shards.get(data.shardId)?.send(data.data); - - break; - } - case 'GET_SHARD_INFO': { - const infos = manager.shards.map(buildShardInfo); - - parentPort?.postMessage({ type: 'NONCE_REPLY', nonce: data.nonce, data: infos }); - } - } -}); - -export type WorkerMessage = WorkerIdentifyShard | WorkerAllowIdentify | WorkerShardPayload | WorkerGetShardInfo; - -export interface WorkerIdentifyShard { - type: 'IDENTIFY_SHARD'; - shardId: number; -} - -export interface WorkerAllowIdentify { - type: 'ALLOW_IDENTIFY'; - shardId: number; -} - -export interface WorkerShardPayload { - type: 'SHARD_PAYLOAD'; - shardId: number; - data: ShardSocketRequest; -} - -export interface WorkerGetShardInfo { - type: 'GET_SHARD_INFO'; - nonce: string; -} - -export interface WorkerCreateData { - intents: number; - token: string; - handlerUrls: string[]; - handlerAuthorization: string; - path: string; - totalShards: number; - workerId: number; -} - -export interface WorkerShardInfo { - workerId: number; - shardId: number; - rtt: number; - state: ShardState; -} - -const connectRabbitmq = async () => { - let connection: amqplib.Connection | undefined; - - try { - connection = await amqplib.connect( - `amqp://${process.env.MESSAGEQUEUE_USERNAME}:${process.env.MESSAGEQUEUE_PASSWORD}@${process.env.MESSAGEQUEUE_URL}`, - ); - } catch (error) { - channel = undefined; - log.error(error); - setTimeout(connectRabbitmq, 1000); - } - - if (!connection) return; - connection.on('error', (err) => { - channel = undefined; - log.error(err); - setTimeout(connectRabbitmq, 1000); - }); - - connection.on('close', () => { - channel = undefined; - setTimeout(connectRabbitmq, 1000); - }); - - try { - channel = await connection.createChannel(); - await channel.assertExchange('gatewayMessage', 'x-message-deduplication', { - durable: true, - arguments: { - 'x-cache-size': 1000, - 'x-cache-ttl': 500, - }, - }); - } catch (error) { - log.error(error); - channel = undefined; - } -}; - -if (useMessageQueue) { - connectRabbitmq(); -} diff --git a/examples/bigbot/src/gateway/worker/createWorker.ts b/examples/bigbot/src/gateway/worker/createWorker.ts new file mode 100644 index 000000000..2def9c6cc --- /dev/null +++ b/examples/bigbot/src/gateway/worker/createWorker.ts @@ -0,0 +1,70 @@ +import { join as joinPath } from 'node:path' +import { Worker } from 'node:worker_threads' +import { + DISCORD_TOKEN, + EVENT_HANDLER_AUTHORIZATION, + EVENT_HANDLER_URL, + GATEWAY_INTENTS, + MESSAGEQUEUE_ENABLE, + MESSAGEQUEUE_PASSWORD, + MESSAGEQUEUE_URL, + MESSAGEQUEUE_USERNAME, +} from '../../config.js' +import { getDirnameFromFileUrl } from '../../util.js' +import gatewayManager, { logger } from '../gatewayManager.js' +import type { ManagerMessage, ShardInfo, WorkerCreateData, WorkerMessage } from './types.js' + +// the string is the nonce of the request +export const shardInfoRequests = new Map void>() + +export function createWorker(workerId: number): Worker { + // the Worker constructor requires either a relative path compared to the process CWD or an absolute one, so to get one relative we need to use import.meta.url + const currentFolder = getDirnameFromFileUrl(import.meta.url) + const workerFilePath = joinPath(currentFolder, './worker.js') + + const worker = new Worker(workerFilePath, { + workerData: { + connectionData: { + intents: GATEWAY_INTENTS, + token: DISCORD_TOKEN, + totalShards: gatewayManager.totalShards, + url: gatewayManager.url, + version: gatewayManager.version, + }, + eventHandler: { + urls: [EVENT_HANDLER_URL], + authentication: EVENT_HANDLER_AUTHORIZATION, + }, + workerId, + messageQueue: { + enabled: MESSAGEQUEUE_ENABLE === 'true', + username: MESSAGEQUEUE_USERNAME, + password: MESSAGEQUEUE_PASSWORD, + url: MESSAGEQUEUE_URL, + }, + } satisfies WorkerCreateData, + }) + + worker.on('message', async (message: ManagerMessage) => { + if (message.type === 'RequestIdentify') { + logger.info(`Requesting identify for shardId: #${message.shardId}`) + await gatewayManager.requestIdentify(message.shardId) + + worker.postMessage({ + type: 'AllowIdentify', + shardId: message.shardId, + } satisfies WorkerMessage) + + return + } + if (message.type === 'ShardInfo') { + shardInfoRequests.get(message.nonce)?.(message) + shardInfoRequests.delete(message.nonce) + return + } + + logger.warn(`Worker - Received unknown message type: ${(message as { type: string }).type}`) + }) + + return worker +} diff --git a/examples/bigbot/src/gateway/worker/types.ts b/examples/bigbot/src/gateway/worker/types.ts new file mode 100644 index 000000000..18739254f --- /dev/null +++ b/examples/bigbot/src/gateway/worker/types.ts @@ -0,0 +1,73 @@ +import type { ShardSocketRequest, StatusUpdate } from '@discordeno/bot' + +export type ManagerMessage = ManagerRequestIdentify | ManagerShardInfo +export type WorkerMessage = WorkerIdentifyShard | WorkerAllowIdentify | WorkerShardPayload | WorkerPresencesUpdate | WorkerShardInfo + +export interface WorkerIdentifyShard { + type: 'IdentifyShard' + shardId: number +} + +export interface WorkerAllowIdentify { + type: 'AllowIdentify' + shardId: number +} + +export interface ManagerRequestIdentify { + type: 'RequestIdentify' + shardId: number +} + +export interface WorkerShardPayload { + type: 'ShardPayload' + shardId: number + payload: ShardSocketRequest +} + +export interface WorkerPresencesUpdate { + type: 'EditShardsPresence' + payload: StatusUpdate +} + +export interface WorkerShardInfo { + type: 'GetShardInfo' + shardId: number + nonce: string +} + +export interface WorkerCreateData { + connectionData: { + intents: number + token: string + url: string + version: number + totalShards: number + } + eventHandler: { + urls: string[] + authentication: string + } + workerId: number + messageQueue: { + enabled: boolean + username?: string + password?: string + url?: string + } +} + +export interface ShardInfo { + shardId: number + rtt: number + // the nonce is to bind to the request + nonce: string +} + +export interface ManagerShardInfo extends ShardInfo { + type: 'ShardInfo' +} + +export interface ManagerGetShardInfoFromGuildId { + type: 'ShardInfoFromGuild' + guildId: string | undefined +} diff --git a/examples/bigbot/src/gateway/worker/worker.ts b/examples/bigbot/src/gateway/worker/worker.ts new file mode 100644 index 000000000..8a9ee0845 --- /dev/null +++ b/examples/bigbot/src/gateway/worker/worker.ts @@ -0,0 +1,208 @@ +import { createLogger, DiscordenoShard, GatewayOpcodes, LogDepth } from '@discordeno/bot' +import { connect as connectAmqp, type Channel as amqpChannel } from 'amqplib' +import assert from 'node:assert' +import { createHash } from 'node:crypto' +import { workerData as _workerData, parentPort } from 'node:worker_threads' +import { promiseWithResolvers } from '../../util.js' +import type { ManagerMessage, WorkerCreateData, WorkerMessage } from './types.js' + +assert(parentPort) + +const workerData: WorkerCreateData = _workerData + +const logger = createLogger({ name: `Worker #${workerData.workerId}` }) +logger.setDepth(LogDepth.Full) + +const identifyPromises = new Map void>() +const shards = new Map() + +let rabbitMQChannel: amqpChannel | undefined + +if (workerData.messageQueue.enabled) { + await connectToRabbitMQ() +} + +parentPort.on('message', async (message: WorkerMessage) => { + if (message.type === 'IdentifyShard') { + logger.info(`Starting to identify shard #${message.shardId}`) + const shard = shards.get(message.shardId) ?? createShard(message.shardId) + shards.set(message.shardId, shard) + + await shard.identify() + + return + } + if (message.type === 'AllowIdentify') { + identifyPromises.get(message.shardId)?.() + identifyPromises.delete(message.shardId) + + return + } + if (message.type === 'ShardPayload') { + const shard = shards.get(message.shardId) + + if (!shard) return + + await shard.send(message.payload) + + return + } + if (message.type === 'EditShardsPresence') { + const shardsArray = Array.from(shards.values()) + const promises = shardsArray.map(async (shard) => { + await shard.send({ + op: GatewayOpcodes.PresenceUpdate, + d: { + since: null, + afk: false, + activities: message.payload.activities, + status: message.payload.status, + }, + }) + }) + + await Promise.all(promises) + return + } + if (message.type === 'GetShardInfo') { + const status = { + type: 'ShardInfo', + shardId: message.shardId, + rtt: shards.get(message.shardId)?.heart.rtt ?? -1, + nonce: message.nonce, + } satisfies ManagerMessage + + parentPort?.postMessage(status) + + return + } + + logger.warn(`Received unknown message type: ${(message as { type: string }).type}`) +}) + +function createShard(shardId: number): DiscordenoShard { + const shard = new DiscordenoShard({ + id: shardId, + events: {}, + connection: { + compress: false, + intents: workerData.connectionData.intents, + properties: { + os: process.platform, + browser: 'Discordeno', + device: 'Discordeno', + }, + token: workerData.connectionData.token, + totalShards: workerData.connectionData.totalShards, + url: workerData.connectionData.url, + version: workerData.connectionData.version, + }, + }) + + shard.requestIdentify = async () => { + assert(parentPort) + + const { promise, resolve } = promiseWithResolvers() + + parentPort.postMessage({ + type: 'RequestIdentify', + shardId, + } satisfies ManagerMessage) + + identifyPromises.set(shardId, resolve) + + return await promise + } + + // We do not want to camelize the packet, so we need to override the function as the default behavior is to camelize + shard.forwardToBot = (packet) => { + shard.events.message?.(shard, packet) + } + + shard.events.message = async (shard, payload) => { + const body = JSON.stringify({ payload, shardId: shard.id }) + + if (workerData.messageQueue.enabled) { + if (!rabbitMQChannel) { + logger.error('The RabbitMQ channel has not been created. The event will be lost') + return + } + + const message = Buffer.from(body) + const discordData = JSON.stringify(payload.d) + + const deduplicationHash = createHash('sha1') + deduplicationHash.update(discordData) + + rabbitMQChannel.publish('gatewayMessage', '', message, { + contentType: 'application/json', + headers: { + 'x-deduplication-header': deduplicationHash.digest('hex'), + }, + }) + + return + } + + const url = workerData.eventHandler.urls[shard.id % workerData.eventHandler.urls.length] + if (!url) { + logger.error('No url found to send events to') + return + } + + await fetch(url, { + method: 'POST', + body, + headers: { + 'Content-Type': 'application/json', + Authorization: workerData.eventHandler.authentication, + }, + }).catch((error) => logger.error('Failed to send events to the bot code', error)) + } + + return shard +} + +async function connectToRabbitMQ(): Promise { + rabbitMQChannel = undefined + const messageQueue = workerData.messageQueue + + const connection = await connectAmqp(`amqp://${messageQueue.username}:${messageQueue.password}@${messageQueue.url}`).catch((error) => { + logger.error('Failed to connect to RabbitMQ, retrying in 1s.', error) + setTimeout(connectToRabbitMQ, 1000) + }) + + if (!connection) return + + connection.on('close', () => { + rabbitMQChannel = undefined + setTimeout(connectToRabbitMQ, 1000) + }) + connection.on('error', (error) => { + rabbitMQChannel = undefined + logger.error('There was an error in the connection with RabbitMQ, reconnecting in 1s.', error) + setTimeout(connectToRabbitMQ, 1000) + }) + + const channel = await connection.createChannel().catch((error) => { + logger.error('There was an error creating the RabbitMQ channel', error) + }) + + if (!channel) return + + const exchange = await channel + .assertExchange('gatewayMessage', 'x-message-deduplication', { + durable: true, + arguments: { + 'x-cache-size': 1000, // maximum number of entries + 'x-cache-ttl': 500, // 500ms + }, + }) + .catch((error) => { + logger.error('There was an error asserting the exchange', error) + }) + + if (!exchange) return + + rabbitMQChannel = channel +} diff --git a/examples/bigbot/src/prisma.ts b/examples/bigbot/src/prisma.ts deleted file mode 100644 index 9b6c4ce30..000000000 --- a/examples/bigbot/src/prisma.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { PrismaClient } from '@prisma/client'; - -export const prisma = new PrismaClient(); diff --git a/examples/bigbot/src/rabbitmq/plugins/elixir-1.12.2.ez b/examples/bigbot/src/rabbitmq/plugins/elixir-1.12.2.ez deleted file mode 100644 index 5409636f7..000000000 Binary files a/examples/bigbot/src/rabbitmq/plugins/elixir-1.12.2.ez and /dev/null differ diff --git a/examples/bigbot/src/rabbitmq/plugins/rabbitmq_message_deduplication-0.5.4.ez b/examples/bigbot/src/rabbitmq/plugins/rabbitmq_message_deduplication-0.5.4.ez deleted file mode 100644 index 368d3e0b4..000000000 Binary files a/examples/bigbot/src/rabbitmq/plugins/rabbitmq_message_deduplication-0.5.4.ez and /dev/null differ diff --git a/examples/bigbot/src/rest/README.md b/examples/bigbot/src/rest/README.md deleted file mode 100644 index 5629d2809..000000000 --- a/examples/bigbot/src/rest/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# REST Proxy - -This folder will contain the code for our REST proxy. This is going to become the single source that all of our bot will -use to communciate to the Discord API. - -## Further Steps - -- Express framework to create the listener however, you can replace it with anything you like. Express is quite a - bloated framework. Feel free to optimize to a better framework. diff --git a/examples/bigbot/src/rest/fastify.ts b/examples/bigbot/src/rest/fastify.ts new file mode 100644 index 000000000..b377ddd20 --- /dev/null +++ b/examples/bigbot/src/rest/fastify.ts @@ -0,0 +1,39 @@ +import fastifyMultipart, { type MultipartFile, type MultipartValue } from '@fastify/multipart' +import fastify, { type FastifyInstance } from 'fastify' +import { REST_AUTHORIZATION } from '../config.js' + +export function buildFastifyApp(): FastifyInstance { + const app = fastify() + + app.register(fastifyMultipart, { attachFieldsToBody: true }) + + // Authorization check + app.addHook('onRequest', async (req, res) => { + if (req.headers.authorization !== REST_AUTHORIZATION) { + res.status(401).send({ + message: 'Credentials not valid.', + }) + } + }) + + return app +} + +export async function parseMultiformBody(body: unknown): Promise { + const form = new FormData() + + if (typeof body !== 'object' || !body) return form + + for (const objectValue of Object.values(body)) { + const value = objectValue as MultipartFile | MultipartValue + + if (value.type === 'file') { + form.append(value.fieldname, new Blob([await value.toBuffer()]), value.filename) + } + if (value.type === 'field' && typeof value.value === 'string') { + form.append(value.fieldname, value.value) + } + } + + return form +} diff --git a/examples/bigbot/src/rest/index.ts b/examples/bigbot/src/rest/index.ts index 4521baa46..2aa3503ff 100644 --- a/examples/bigbot/src/rest/index.ts +++ b/examples/bigbot/src/rest/index.ts @@ -1,60 +1,48 @@ -import dotenv from 'dotenv'; +import { type RequestMethods } from '@discordeno/bot' +import { REST_HOST, REST_PORT } from '../config.js' +import { buildFastifyApp, parseMultiformBody } from './fastify.js' +import restManager, { logger } from './restManager.js' -import { BASE_URL, createRestManager } from 'discordeno'; -import express from 'express'; -import { setupAnalyticsHooks } from '../analytics.js'; -import { REST_URL } from '../configs.js'; -dotenv.config(); +const app = buildFastifyApp() -const DISCORD_TOKEN = process.env.DISCORD_TOKEN as string; -const REST_AUTHORIZATION = process.env.REST_AUTHORIZATION as string; -const REST_PORT = process.env.REST_PORT as string; - -const rest = createRestManager({ - token: DISCORD_TOKEN, - secretKey: REST_AUTHORIZATION, - customUrl: REST_URL, - debug: console.log, -}); - -// Add send fetching analytics hook to rest -setupAnalyticsHooks(rest); - -// @ts-expect-error -rest.convertRestError = (errorStack, data) => { - if (!data) return { message: errorStack.message }; - return { ...data, message: errorStack.message }; -}; - -const app = express(); - -app.use( - express.urlencoded({ - extended: true, - }), -); - -app.use(express.json()); +app.get('/timecheck', async (_req, res) => { + res.status(200).send({ message: Date.now() }) +}) app.all('/*', async (req, res) => { - if (!REST_AUTHORIZATION || REST_AUTHORIZATION !== req.headers.authorization) { - return res.status(401).json({ error: 'Invalid authorization key.' }); - } + let url = req.originalUrl - try { - const result = await rest.runMethod(rest, req.method, `${BASE_URL}${req.url}`, req.body); + if (url.startsWith('/v')) { + url = url.slice(url.indexOf('/', 2)) + } - if (result) { - res.status(200).json(result); - } else { - res.status(204).json(); - } - } catch (error: any) { - console.log(error); - res.status(500).json(error); - } -}); + const isMultipart = req.headers['content-type']?.startsWith('multipart/form-data') + const hasBody = req.method !== 'GET' && req.method !== 'DELETE' + const body = hasBody ? (isMultipart ? await parseMultiformBody(req.body) : req.body) : undefined -app.listen(REST_PORT, () => { - console.log(`REST listening at ${REST_URL}`); -}); + try { + const result = await restManager.makeRequest(req.method as RequestMethods, url, { + body, + }) + + if (result) { + res.status(200).send(result) + return + } + + res.status(204).send({}) + } catch (error) { + logger.error(error) + + res.status(500).send({ + message: error, + }) + } +}) + +await app.listen({ + host: REST_HOST, + port: REST_PORT, +}) + +logger.info(`REST Proxy listening on port ${REST_PORT}`) diff --git a/examples/bigbot/src/rest/influx.ts b/examples/bigbot/src/rest/influx.ts new file mode 100644 index 000000000..475e70020 --- /dev/null +++ b/examples/bigbot/src/rest/influx.ts @@ -0,0 +1,47 @@ +import type { RestManager } from '@discordeno/bot' +import { InfluxDB, Point } from '@influxdata/influxdb-client' +import { INFLUX_BUCKET, INFLUX_ENABLED, INFLUX_ORG, INFLUX_TOKEN, INFLUX_URL } from '../config.js' + +export const influxDB = INFLUX_ENABLED ? new InfluxDB({ url: INFLUX_URL!, token: INFLUX_TOKEN! }) : undefined +export const influx = INFLUX_ENABLED && influxDB ? influxDB.getWriteApi(INFLUX_ORG!, INFLUX_BUCKET!) : undefined + +export const setupRestAnalyticsHooks = (rest: RestManager, logger: RestManager['logger']): void => { + // If influxdb data is provided, enable analytics in this proxy. + if (!influx) return + + const originalSendRequest = rest.sendRequest + + rest.sendRequest = async (options) => { + const fetchingPoint = new Point('restEvents') + .timestamp(new Date()) + .stringField('type', 'REQUEST_FETCHING') + .tag('method', options.method) + .tag('route', options.route) + .tag('bucket', options.bucketId ?? 'NA') + + influx.writePoint(fetchingPoint) + + await originalSendRequest(options) + + const fetchedPoint = new Point('restEvents') + .timestamp(new Date()) + .stringField('type', 'REQUEST_FETCHED') + .tag('method', options.method) + .tag('route', options.route) + .tag('bucket', options.bucketId ?? 'NA') + // FIXME: rest.sendRequest returns Promise, so there is no way currently to get the response status + // .intField('status', response.status) + + influx.writePoint(fetchedPoint) + } + + setInterval(async () => { + logger.info('Influx - Saving events...') + try { + await influx.flush() + logger.info('Influx - events saved!') + } catch (error) { + logger.error('Influx - error saving events!', error) + } + }, 30_000 /* 30s */) +} diff --git a/examples/bigbot/src/rest/restManager.ts b/examples/bigbot/src/rest/restManager.ts new file mode 100644 index 000000000..dc7806a4a --- /dev/null +++ b/examples/bigbot/src/rest/restManager.ts @@ -0,0 +1,14 @@ +import { createLogger, createRestManager, LogDepth } from '@discordeno/bot' +import { DISCORD_TOKEN } from '../config.js' +import { setupRestAnalyticsHooks } from './influx.js' + +const manager = createRestManager({ + token: DISCORD_TOKEN, +}) + +export const logger = createLogger({ name: 'REST' }) +logger.setDepth(LogDepth.Full) + +setupRestAnalyticsHooks(manager, logger) + +export default manager diff --git a/examples/bigbot/src/util.ts b/examples/bigbot/src/util.ts new file mode 100644 index 000000000..51130370e --- /dev/null +++ b/examples/bigbot/src/util.ts @@ -0,0 +1,25 @@ +import { dirname } from 'node:path' +import { fileURLToPath } from 'node:url' + +// This is a "polyfill" for the `Promise.withResolves`, while node 22 does support it, node 18 does not and this template does support node 18 +export function promiseWithResolvers(): PromiseWithResolvers { + let resolve!: (data: T | PromiseLike) => void + let reject!: (reason?: any) => void + const promise = new Promise((_resolve, _reject) => { + resolve = _resolve + reject = _reject + }) + + return { promise, resolve, reject } +} + +// This re-creates the `__dirname` that exists in CommonJS, in ESM node added `import.meta.dirname` but it is for node 20+, so we need this util to support node 18 +export function getDirnameFromFileUrl(url: string): string { + return dirname(fileURLToPath(url)) +} + +export interface PromiseWithResolvers { + promise: Promise + resolve: (data: T | PromiseLike) => void + reject: (reason?: any) => void +} diff --git a/examples/bigbot/tsconfig.json b/examples/bigbot/tsconfig.json index eb019398f..04416ddd6 100644 --- a/examples/bigbot/tsconfig.json +++ b/examples/bigbot/tsconfig.json @@ -1,30 +1,14 @@ { - "compilerOptions": { - "target": "es2022", - "module": "es2022", - "experimentalDecorators": true, - "emitDecoratorMetadata": true, - "outDir": "./dist", - "rootDir": "./src", - "esModuleInterop": true, - "importHelpers": true, - "allowUnusedLabels": false, - "noImplicitOverride": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "noUncheckedIndexedAccess": true, - "strict": true, - "stripInternal": true, - "noFallthroughCasesInSwitch": true, - "useUnknownInCatchVariables": false, - "allowUnreachableCode": false, - "skipLibCheck": true, - "moduleResolution": "node" - }, - "include": ["./src/**/*", ".env"], - "ts-node": { - "esm": true, - "experimentalSpecifierResolution": "node", - "swc": true - } + "compilerOptions": { + "target": "es2022", + "module": "es2022", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "isolatedModules": true, + "moduleResolution": "node", + "skipDefaultLibCheck": true, + "skipLibCheck": true, + "strict": true, + "incremental": true + } } diff --git a/examples/bigbot/yarn.lock b/examples/bigbot/yarn.lock new file mode 100644 index 000000000..df9a8bf6b --- /dev/null +++ b/examples/bigbot/yarn.lock @@ -0,0 +1,2756 @@ +# This file is generated by running "yarn install" inside your project. +# Manual changes might be lost - proceed with caution! + +__metadata: + version: 8 + cacheKey: 10 + +"@acuminous/bitsyntax@npm:^0.1.2": + version: 0.1.2 + resolution: "@acuminous/bitsyntax@npm:0.1.2" + dependencies: + buffer-more-ints: "npm:~1.0.0" + debug: "npm:^4.3.4" + safe-buffer: "npm:~5.1.2" + checksum: abdc4313ae08e52fb8eeaebf53759c3b9a38983a696d77c46c24de1c065247355a1b5c02ad3618700d3fb3628ccf3ec39227a080bd1fe7adc864144ccf84b0cc + languageName: node + linkType: hard + +"@discordeno/bot@npm:19.0.0-next.92bf166": + version: 19.0.0-next.92bf166 + resolution: "@discordeno/bot@npm:19.0.0-next.92bf166" + dependencies: + "@discordeno/gateway": "npm:19.0.0-next.92bf166" + "@discordeno/rest": "npm:19.0.0-next.92bf166" + "@discordeno/types": "npm:19.0.0-next.92bf166" + "@discordeno/utils": "npm:19.0.0-next.92bf166" + checksum: 3020e74c774eae34307d434ad38f983e90839dc5fad7578f3cda4fba6c1efb7a22c4f4cdcfff58c54b62cc14976ad974256955d5117e490f78ec9e835e02c682 + languageName: node + linkType: hard + +"@discordeno/gateway@npm:19.0.0-next.92bf166": + version: 19.0.0-next.92bf166 + resolution: "@discordeno/gateway@npm:19.0.0-next.92bf166" + dependencies: + "@discordeno/types": "npm:19.0.0-next.92bf166" + "@discordeno/utils": "npm:19.0.0-next.92bf166" + ws: "npm:^8.16.0" + checksum: 6a11ca7a4cb98f48726664d0baa27d04e26342bf94d6e439494e462636af20d17b567e9d3e2e478465aabcecb98a21e54b860b39b9f1022eef922e76d947ddcb + languageName: node + linkType: hard + +"@discordeno/rest@npm:19.0.0-next.92bf166": + version: 19.0.0-next.92bf166 + resolution: "@discordeno/rest@npm:19.0.0-next.92bf166" + dependencies: + "@discordeno/types": "npm:19.0.0-next.92bf166" + "@discordeno/utils": "npm:19.0.0-next.92bf166" + dotenv: "npm:^16.4.5" + checksum: 45f6ba4791003b77c883e991ad348597197d70e25e335b8628a03bd2effa8e2047a2f987f4c0b6ee8b17c01f77055d7a1ddc9f5350eb8f1c8ff8c8d39f91d787 + languageName: node + linkType: hard + +"@discordeno/types@npm:19.0.0-next.92bf166": + version: 19.0.0-next.92bf166 + resolution: "@discordeno/types@npm:19.0.0-next.92bf166" + checksum: f88e78a18e51c179b94ef14e8bcdd6b5e6c5f25bdd6c4308bec121e5e59533612b36ed0e7a447daedc009053e1e30c6c8e13b2276bb1ce7e2f840ff58473a2ef + languageName: node + linkType: hard + +"@discordeno/utils@npm:19.0.0-next.92bf166": + version: 19.0.0-next.92bf166 + resolution: "@discordeno/utils@npm:19.0.0-next.92bf166" + dependencies: + "@discordeno/types": "npm:19.0.0-next.92bf166" + tweetnacl: "npm:^1.0.3" + checksum: 7962a057ba5908936e4224df70b9ceaffcb8ec7ad220a999b36fc0601365b380bb0de01b6adfa4c36250247e3d15e22215fc63bbe3634b932434411c5f4ca13d + languageName: node + linkType: hard + +"@fastify/ajv-compiler@npm:^3.5.0": + version: 3.5.0 + resolution: "@fastify/ajv-compiler@npm:3.5.0" + dependencies: + ajv: "npm:^8.11.0" + ajv-formats: "npm:^2.1.1" + fast-uri: "npm:^2.0.0" + checksum: c46c4680bf583e37b97ffc85b69070712c9c47e18ddf89b9fb93dbc0b6ba3c6496cf624aabe9aac25dafc4a404b738ab0fedcff66503df0ce18d9dcad9e44b26 + languageName: node + linkType: hard + +"@fastify/busboy@npm:^2.1.0": + version: 2.1.1 + resolution: "@fastify/busboy@npm:2.1.1" + checksum: 2bb8a7eca8289ed14c9eb15239bc1019797454624e769b39a0b90ed204d032403adc0f8ed0d2aef8a18c772205fa7808cf5a1b91f21c7bfc7b6032150b1062c5 + languageName: node + linkType: hard + +"@fastify/deepmerge@npm:^1.0.0": + version: 1.3.0 + resolution: "@fastify/deepmerge@npm:1.3.0" + checksum: 6ddfc230ed46bfb158dbf83c2cc7f6119c9c1afb96d885cf5d95ac17b56126d04eef83ddb1ee7a1b044e65a128c76ebf8b391a26490b19f5812fa0d2d2a3a675 + languageName: node + linkType: hard + +"@fastify/error@npm:^3.0.0, @fastify/error@npm:^3.3.0, @fastify/error@npm:^3.4.0": + version: 3.4.1 + resolution: "@fastify/error@npm:3.4.1" + checksum: 4d63660f7d4a0d6091abf869208d30898bde82f513ca7be542243d9d740df743dd4be293e7db30858fca612dd512d28a818ea06dc674e06b445278fcefcdda92 + languageName: node + linkType: hard + +"@fastify/fast-json-stringify-compiler@npm:^4.3.0": + version: 4.3.0 + resolution: "@fastify/fast-json-stringify-compiler@npm:4.3.0" + dependencies: + fast-json-stringify: "npm:^5.7.0" + checksum: 9ad575907d44bbd371dbc23a51853fd349a459092340fe91c50317f92707961f2e6ca6c9d17707a8e4a087c635e09bce1166e082d54f191769a582339c94badd + languageName: node + linkType: hard + +"@fastify/merge-json-schemas@npm:^0.1.0": + version: 0.1.1 + resolution: "@fastify/merge-json-schemas@npm:0.1.1" + dependencies: + fast-deep-equal: "npm:^3.1.3" + checksum: 99d0795f8dde75c204ee86fd2d42d8b24da3818c4bb6de8e3d595da1b123e678dcf832d14bd8ab3167fc22e36762ecd5b473ef764888a04dd94831befadac7f0 + languageName: node + linkType: hard + +"@fastify/multipart@npm:^8.3.0": + version: 8.3.0 + resolution: "@fastify/multipart@npm:8.3.0" + dependencies: + "@fastify/busboy": "npm:^2.1.0" + "@fastify/deepmerge": "npm:^1.0.0" + "@fastify/error": "npm:^3.0.0" + fastify-plugin: "npm:^4.0.0" + secure-json-parse: "npm:^2.4.0" + stream-wormhole: "npm:^1.1.0" + checksum: 23b9b709a499af0c0beaaaabd52032a92fa8f4a398ed821c2b4f272e68602ed7bcf91b5daed1e5270c3c61a8b3e8ea1bc2924f21fbcfdbdbd07f4342bd17cd81 + languageName: node + linkType: hard + +"@influxdata/influxdb-client@npm:^1.33.2": + version: 1.33.2 + resolution: "@influxdata/influxdb-client@npm:1.33.2" + checksum: 438a538ccd3ea7b8286b62e5ac9ef88b9c56b36465e889f088f5a210aa2fe638f4b5e255c383a12dec39cad979121e1743daeb163cfe46f60a70949a7f0bb49d + languageName: node + linkType: hard + +"@isaacs/cliui@npm:^8.0.2": + version: 8.0.2 + resolution: "@isaacs/cliui@npm:8.0.2" + dependencies: + string-width: "npm:^5.1.2" + string-width-cjs: "npm:string-width@^4.2.0" + strip-ansi: "npm:^7.0.1" + strip-ansi-cjs: "npm:strip-ansi@^6.0.1" + wrap-ansi: "npm:^8.1.0" + wrap-ansi-cjs: "npm:wrap-ansi@^7.0.0" + checksum: e9ed5fd27c3aec1095e3a16e0c0cf148d1fee55a38665c35f7b3f86a9b5d00d042ddaabc98e8a1cb7463b9378c15f22a94eb35e99469c201453eb8375191f243 + languageName: node + linkType: hard + +"@mole-inc/bin-wrapper@npm:^8.0.1": + version: 8.0.1 + resolution: "@mole-inc/bin-wrapper@npm:8.0.1" + dependencies: + bin-check: "npm:^4.1.0" + bin-version-check: "npm:^5.0.0" + content-disposition: "npm:^0.5.4" + ext-name: "npm:^5.0.0" + file-type: "npm:^17.1.6" + filenamify: "npm:^5.0.2" + got: "npm:^11.8.5" + os-filter-obj: "npm:^2.0.0" + checksum: 565df38f6f91fefe2e2540bf4357024fd912990aecb1873fd9bf21e6a667d9930c73e5cbc87a9aac0cf476b8dffc30a4e00ec97b62e713ef5c00d46823ea599d + languageName: node + linkType: hard + +"@nodelib/fs.scandir@npm:2.1.5": + version: 2.1.5 + resolution: "@nodelib/fs.scandir@npm:2.1.5" + dependencies: + "@nodelib/fs.stat": "npm:2.0.5" + run-parallel: "npm:^1.1.9" + checksum: 6ab2a9b8a1d67b067922c36f259e3b3dfd6b97b219c540877a4944549a4d49ea5ceba5663905ab5289682f1f3c15ff441d02f0447f620a42e1cb5e1937174d4b + languageName: node + linkType: hard + +"@nodelib/fs.stat@npm:2.0.5, @nodelib/fs.stat@npm:^2.0.2": + version: 2.0.5 + resolution: "@nodelib/fs.stat@npm:2.0.5" + checksum: 012480b5ca9d97bff9261571dbbec7bbc6033f69cc92908bc1ecfad0792361a5a1994bc48674b9ef76419d056a03efadfce5a6cf6dbc0a36559571a7a483f6f0 + languageName: node + linkType: hard + +"@nodelib/fs.walk@npm:^1.2.3": + version: 1.2.8 + resolution: "@nodelib/fs.walk@npm:1.2.8" + dependencies: + "@nodelib/fs.scandir": "npm:2.1.5" + fastq: "npm:^1.6.0" + checksum: 40033e33e96e97d77fba5a238e4bba4487b8284678906a9f616b5579ddaf868a18874c0054a75402c9fbaaa033a25ceae093af58c9c30278e35c23c9479e79b0 + languageName: node + linkType: hard + +"@npmcli/agent@npm:^2.0.0": + version: 2.2.2 + resolution: "@npmcli/agent@npm:2.2.2" + dependencies: + agent-base: "npm:^7.1.0" + http-proxy-agent: "npm:^7.0.0" + https-proxy-agent: "npm:^7.0.1" + lru-cache: "npm:^10.0.1" + socks-proxy-agent: "npm:^8.0.3" + checksum: 96fc0036b101bae5032dc2a4cd832efb815ce9b33f9ee2f29909ee49d96a0026b3565f73c507a69eb8603f5cb32e0ae45a70cab1e2655990a4e06ae99f7f572a + languageName: node + linkType: hard + +"@npmcli/fs@npm:^3.1.0": + version: 3.1.1 + resolution: "@npmcli/fs@npm:3.1.1" + dependencies: + semver: "npm:^7.3.5" + checksum: 1e0e04087049b24b38bc0b30d87a9388ee3ca1d3fdfc347c2f77d84fcfe6a51f250bc57ba2c1f614d7e4285c6c62bf8c769bc19aa0949ea39e5b043ee023b0bd + languageName: node + linkType: hard + +"@pkgjs/parseargs@npm:^0.11.0": + version: 0.11.0 + resolution: "@pkgjs/parseargs@npm:0.11.0" + checksum: 115e8ceeec6bc69dff2048b35c0ab4f8bbee12d8bb6c1f4af758604586d802b6e669dcb02dda61d078de42c2b4ddce41b3d9e726d7daa6b4b850f4adbf7333ff + languageName: node + linkType: hard + +"@sindresorhus/is@npm:^4.0.0": + version: 4.6.0 + resolution: "@sindresorhus/is@npm:4.6.0" + checksum: e7f36ed72abfcd5e0355f7423a72918b9748bb1ef370a59f3e5ad8d40b728b85d63b272f65f63eec1faf417cda89dcb0aeebe94015647b6054659c1442fe5ce0 + languageName: node + linkType: hard + +"@swc/cli@npm:^0.3.12": + version: 0.3.12 + resolution: "@swc/cli@npm:0.3.12" + dependencies: + "@mole-inc/bin-wrapper": "npm:^8.0.1" + "@swc/counter": "npm:^0.1.3" + commander: "npm:^8.3.0" + fast-glob: "npm:^3.2.5" + minimatch: "npm:^9.0.3" + piscina: "npm:^4.3.0" + semver: "npm:^7.3.8" + slash: "npm:3.0.0" + source-map: "npm:^0.7.3" + peerDependencies: + "@swc/core": ^1.2.66 + chokidar: ^3.5.1 + peerDependenciesMeta: + chokidar: + optional: true + bin: + spack: bin/spack.js + swc: bin/swc.js + swcx: bin/swcx.js + checksum: fee260434fad8eed0328f4db17f42ce0864b93b90fcb02f3f0eb3aad994b5a6ae4bfdfb6d2329377e0cd8d07adc61cca42e290bf0005c1ab4d004d4a0b152db4 + languageName: node + linkType: hard + +"@swc/core-darwin-arm64@npm:1.6.3": + version: 1.6.3 + resolution: "@swc/core-darwin-arm64@npm:1.6.3" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@swc/core-darwin-x64@npm:1.6.3": + version: 1.6.3 + resolution: "@swc/core-darwin-x64@npm:1.6.3" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@swc/core-linux-arm-gnueabihf@npm:1.6.3": + version: 1.6.3 + resolution: "@swc/core-linux-arm-gnueabihf@npm:1.6.3" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@swc/core-linux-arm64-gnu@npm:1.6.3": + version: 1.6.3 + resolution: "@swc/core-linux-arm64-gnu@npm:1.6.3" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@swc/core-linux-arm64-musl@npm:1.6.3": + version: 1.6.3 + resolution: "@swc/core-linux-arm64-musl@npm:1.6.3" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@swc/core-linux-x64-gnu@npm:1.6.3": + version: 1.6.3 + resolution: "@swc/core-linux-x64-gnu@npm:1.6.3" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@swc/core-linux-x64-musl@npm:1.6.3": + version: 1.6.3 + resolution: "@swc/core-linux-x64-musl@npm:1.6.3" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@swc/core-win32-arm64-msvc@npm:1.6.3": + version: 1.6.3 + resolution: "@swc/core-win32-arm64-msvc@npm:1.6.3" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@swc/core-win32-ia32-msvc@npm:1.6.3": + version: 1.6.3 + resolution: "@swc/core-win32-ia32-msvc@npm:1.6.3" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@swc/core-win32-x64-msvc@npm:1.6.3": + version: 1.6.3 + resolution: "@swc/core-win32-x64-msvc@npm:1.6.3" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@swc/core@npm:^1.6.3": + version: 1.6.3 + resolution: "@swc/core@npm:1.6.3" + dependencies: + "@swc/core-darwin-arm64": "npm:1.6.3" + "@swc/core-darwin-x64": "npm:1.6.3" + "@swc/core-linux-arm-gnueabihf": "npm:1.6.3" + "@swc/core-linux-arm64-gnu": "npm:1.6.3" + "@swc/core-linux-arm64-musl": "npm:1.6.3" + "@swc/core-linux-x64-gnu": "npm:1.6.3" + "@swc/core-linux-x64-musl": "npm:1.6.3" + "@swc/core-win32-arm64-msvc": "npm:1.6.3" + "@swc/core-win32-ia32-msvc": "npm:1.6.3" + "@swc/core-win32-x64-msvc": "npm:1.6.3" + "@swc/counter": "npm:^0.1.3" + "@swc/types": "npm:^0.1.8" + peerDependencies: + "@swc/helpers": "*" + dependenciesMeta: + "@swc/core-darwin-arm64": + optional: true + "@swc/core-darwin-x64": + optional: true + "@swc/core-linux-arm-gnueabihf": + optional: true + "@swc/core-linux-arm64-gnu": + optional: true + "@swc/core-linux-arm64-musl": + optional: true + "@swc/core-linux-x64-gnu": + optional: true + "@swc/core-linux-x64-musl": + optional: true + "@swc/core-win32-arm64-msvc": + optional: true + "@swc/core-win32-ia32-msvc": + optional: true + "@swc/core-win32-x64-msvc": + optional: true + peerDependenciesMeta: + "@swc/helpers": + optional: true + checksum: b4c84a083ecabb0280ba53dffa65a5a575321de94081ad52bd12027fe3b5c8957978f2211b6036e2e28d904dd046fca238106c2106b32d02b752808a51193d35 + languageName: node + linkType: hard + +"@swc/counter@npm:^0.1.3": + version: 0.1.3 + resolution: "@swc/counter@npm:0.1.3" + checksum: df8f9cfba9904d3d60f511664c70d23bb323b3a0803ec9890f60133954173047ba9bdeabce28cd70ba89ccd3fd6c71c7b0bd58be85f611e1ffbe5d5c18616598 + languageName: node + linkType: hard + +"@swc/types@npm:^0.1.8": + version: 0.1.8 + resolution: "@swc/types@npm:0.1.8" + dependencies: + "@swc/counter": "npm:^0.1.3" + checksum: 2d1cda35116e03714137c1c37f4493efe0e26e88285ecc9dcdf6256a77984e367ea7b5f31d650f110fdcfd6ac53dff3ec77f841787ca328d2efa7b07ef1ac318 + languageName: node + linkType: hard + +"@szmarczak/http-timer@npm:^4.0.5": + version: 4.0.6 + resolution: "@szmarczak/http-timer@npm:4.0.6" + dependencies: + defer-to-connect: "npm:^2.0.0" + checksum: c29df3bcec6fc3bdec2b17981d89d9c9fc9bd7d0c9bcfe92821dc533f4440bc890ccde79971838b4ceed1921d456973c4180d7175ee1d0023ad0562240a58d95 + languageName: node + linkType: hard + +"@tokenizer/token@npm:^0.3.0": + version: 0.3.0 + resolution: "@tokenizer/token@npm:0.3.0" + checksum: 889c1f1e63ac7c92c0ea22d4a2861142f1b43c3d92eb70ec42aa9e9851fab2e9952211d50f541b287781280df2f979bf5600a9c1f91fbc61b7fcf9994e9376a5 + languageName: node + linkType: hard + +"@types/amqplib@npm:^0.10.5": + version: 0.10.5 + resolution: "@types/amqplib@npm:0.10.5" + dependencies: + "@types/node": "npm:*" + checksum: 7c7fb01c08ad399d67b573990d4072a64c486264af01249c278c43171ce47228525ae73c73aa686c28a0474468561b34e5fe2d7a8bec2da1464bf852a06a0d4a + languageName: node + linkType: hard + +"@types/cacheable-request@npm:^6.0.1": + version: 6.0.3 + resolution: "@types/cacheable-request@npm:6.0.3" + dependencies: + "@types/http-cache-semantics": "npm:*" + "@types/keyv": "npm:^3.1.4" + "@types/node": "npm:*" + "@types/responselike": "npm:^1.0.0" + checksum: 159f9fdb2a1b7175eef453ae2ced5ea04c0d2b9610cc9ccd9f9abb066d36dacb1f37acd879ace10ad7cbb649490723feb396fb7307004c9670be29636304b988 + languageName: node + linkType: hard + +"@types/http-cache-semantics@npm:*": + version: 4.0.4 + resolution: "@types/http-cache-semantics@npm:4.0.4" + checksum: a59566cff646025a5de396d6b3f44a39ab6a74f2ed8150692e0f31cc52f3661a68b04afe3166ebe0d566bd3259cb18522f46e949576d5204781cd6452b7fe0c5 + languageName: node + linkType: hard + +"@types/keyv@npm:^3.1.4": + version: 3.1.4 + resolution: "@types/keyv@npm:3.1.4" + dependencies: + "@types/node": "npm:*" + checksum: e009a2bfb50e90ca9b7c6e8f648f8464067271fd99116f881073fa6fa76dc8d0133181dd65e6614d5fb1220d671d67b0124aef7d97dc02d7e342ab143a47779d + languageName: node + linkType: hard + +"@types/node@npm:*": + version: 20.14.2 + resolution: "@types/node@npm:20.14.2" + dependencies: + undici-types: "npm:~5.26.4" + checksum: c38e47b190fa0a8bdfde24b036dddcf9401551f2fb170a90ff33625c7d6f218907e81c74e0fa6e394804a32623c24c60c50e249badc951007830f0d02c48ee0f + languageName: node + linkType: hard + +"@types/node@npm:^20.14.6": + version: 20.14.6 + resolution: "@types/node@npm:20.14.6" + dependencies: + undici-types: "npm:~5.26.4" + checksum: 1dcfeeb03ce3c3a1d8a537fefee7cd0cffb78f89e9535b74ee12940559566b57c39dad20d1b165b60b5727408dd44e1a52e5c01cf02d0a99d93ef3da8062c86e + languageName: node + linkType: hard + +"@types/responselike@npm:^1.0.0": + version: 1.0.3 + resolution: "@types/responselike@npm:1.0.3" + dependencies: + "@types/node": "npm:*" + checksum: 6ac4b35723429b11b117e813c7acc42c3af8b5554caaf1fc750404c1ae59f9b7376bc69b9e9e194a5a97357a597c2228b7173d317320f0360d617b6425212f58 + languageName: node + linkType: hard + +"abbrev@npm:^2.0.0": + version: 2.0.0 + resolution: "abbrev@npm:2.0.0" + checksum: ca0a54e35bea4ece0ecb68a47b312e1a9a6f772408d5bcb9051230aaa94b0460671c5b5c9cb3240eb5b7bc94c52476550eb221f65a0bbd0145bdc9f3113a6707 + languageName: node + linkType: hard + +"abort-controller@npm:^3.0.0": + version: 3.0.0 + resolution: "abort-controller@npm:3.0.0" + dependencies: + event-target-shim: "npm:^5.0.0" + checksum: ed84af329f1828327798229578b4fe03a4dd2596ba304083ebd2252666bdc1d7647d66d0b18704477e1f8aa315f055944aa6e859afebd341f12d0a53c37b4b40 + languageName: node + linkType: hard + +"abstract-logging@npm:^2.0.1": + version: 2.0.1 + resolution: "abstract-logging@npm:2.0.1" + checksum: 6967d15e5abbafd17f56eaf30ba8278c99333586fa4f7935fd80e93cfdc006c37fcc819c5d63ee373a12e6cb2d0417f7c3c6b9e42b957a25af9937d26749415e + languageName: node + linkType: hard + +"agent-base@npm:^7.0.2, agent-base@npm:^7.1.0, agent-base@npm:^7.1.1": + version: 7.1.1 + resolution: "agent-base@npm:7.1.1" + dependencies: + debug: "npm:^4.3.4" + checksum: c478fec8f79953f118704d007a38f2a185458853f5c45579b9669372bd0e12602e88dc2ad0233077831504f7cd6fcc8251c383375bba5eaaf563b102938bda26 + languageName: node + linkType: hard + +"aggregate-error@npm:^3.0.0": + version: 3.1.0 + resolution: "aggregate-error@npm:3.1.0" + dependencies: + clean-stack: "npm:^2.0.0" + indent-string: "npm:^4.0.0" + checksum: 1101a33f21baa27a2fa8e04b698271e64616b886795fd43c31068c07533c7b3facfcaf4e9e0cab3624bd88f729a592f1c901a1a229c9e490eafce411a8644b79 + languageName: node + linkType: hard + +"ajv-formats@npm:^2.1.1": + version: 2.1.1 + resolution: "ajv-formats@npm:2.1.1" + dependencies: + ajv: "npm:^8.0.0" + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + checksum: 70c263ded219bf277ffd9127f793b625f10a46113b2e901e150da41931fcfd7f5592da6d66862f4449bb157ffe65867c3294a7df1d661cc232c4163d5a1718ed + languageName: node + linkType: hard + +"ajv-formats@npm:^3.0.1": + version: 3.0.1 + resolution: "ajv-formats@npm:3.0.1" + dependencies: + ajv: "npm:^8.0.0" + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + checksum: 5679b9f9ced9d0213a202a37f3aa91efcffe59a6de1a6e3da5c873344d3c161820a1f11cc29899661fee36271fd2895dd3851b6461c902a752ad661d1c1e8722 + languageName: node + linkType: hard + +"ajv@npm:^8.0.0, ajv@npm:^8.10.0, ajv@npm:^8.11.0": + version: 8.16.0 + resolution: "ajv@npm:8.16.0" + dependencies: + fast-deep-equal: "npm:^3.1.3" + json-schema-traverse: "npm:^1.0.0" + require-from-string: "npm:^2.0.2" + uri-js: "npm:^4.4.1" + checksum: 9b4b380efaf8be2639736d535662bd142a6972b43075b404380165c37ab6ceb72f01c7c987536747ff3e9e21eb5cd2e2a194f1e0fa8355364ea6204b1262fcd1 + languageName: node + linkType: hard + +"amqplib@npm:^0.10.4": + version: 0.10.4 + resolution: "amqplib@npm:0.10.4" + dependencies: + "@acuminous/bitsyntax": "npm:^0.1.2" + buffer-more-ints: "npm:~1.0.0" + readable-stream: "npm:1.x >=1.1.9" + url-parse: "npm:~1.5.10" + checksum: de96a1da2be66e8367174a6a76266e9e5088cff60c8ef4ca0843eaf320a8a745f37e17316d4fa8bc895e9ff7dadbe572ae2dd7db5d9e4a42f67e69fa00d0309e + languageName: node + linkType: hard + +"ansi-regex@npm:^5.0.1": + version: 5.0.1 + resolution: "ansi-regex@npm:5.0.1" + checksum: 2aa4bb54caf2d622f1afdad09441695af2a83aa3fe8b8afa581d205e57ed4261c183c4d3877cee25794443fde5876417d859c108078ab788d6af7e4fe52eb66b + languageName: node + linkType: hard + +"ansi-regex@npm:^6.0.1": + version: 6.0.1 + resolution: "ansi-regex@npm:6.0.1" + checksum: 1ff8b7667cded1de4fa2c9ae283e979fc87036864317da86a2e546725f96406746411d0d85e87a2d12fa5abd715d90006de7fa4fa0477c92321ad3b4c7d4e169 + languageName: node + linkType: hard + +"ansi-styles@npm:^4.0.0": + version: 4.3.0 + resolution: "ansi-styles@npm:4.3.0" + dependencies: + color-convert: "npm:^2.0.1" + checksum: b4494dfbfc7e4591b4711a396bd27e540f8153914123dccb4cdbbcb514015ada63a3809f362b9d8d4f6b17a706f1d7bea3c6f974b15fa5ae76b5b502070889ff + languageName: node + linkType: hard + +"ansi-styles@npm:^6.1.0": + version: 6.2.1 + resolution: "ansi-styles@npm:6.2.1" + checksum: 70fdf883b704d17a5dfc9cde206e698c16bcd74e7f196ab821511651aee4f9f76c9514bdfa6ca3a27b5e49138b89cb222a28caf3afe4567570139577f991df32 + languageName: node + linkType: hard + +"arch@npm:^2.1.0": + version: 2.2.0 + resolution: "arch@npm:2.2.0" + checksum: e35dbc6d362297000ab90930069576ba165fe63cd52383efcce14bd66c1b16a91ce849e1fd239964ed029d5e0bdfc32f68e9c7331b7df6c84ddebebfdbf242f7 + languageName: node + linkType: hard + +"atomic-sleep@npm:^1.0.0": + version: 1.0.0 + resolution: "atomic-sleep@npm:1.0.0" + checksum: 3ab6d2cf46b31394b4607e935ec5c1c3c4f60f3e30f0913d35ea74b51b3585e84f590d09e58067f11762eec71c87d25314ce859030983dc0e4397eed21daa12e + languageName: node + linkType: hard + +"avvio@npm:^8.3.0": + version: 8.3.2 + resolution: "avvio@npm:8.3.2" + dependencies: + "@fastify/error": "npm:^3.3.0" + fastq: "npm:^1.17.1" + checksum: 5edef27388ac4c3f07453460b1cc66bad9ae9be2af9b55150ddf720729e2bf12be1dd81c822744363fdea4bb682edcf4c28d8235114e17b78f85f5c398e5bf68 + languageName: node + linkType: hard + +"balanced-match@npm:^1.0.0": + version: 1.0.2 + resolution: "balanced-match@npm:1.0.2" + checksum: 9706c088a283058a8a99e0bf91b0a2f75497f185980d9ffa8b304de1d9e58ebda7c72c07ebf01dadedaac5b2907b2c6f566f660d62bd336c3468e960403b9d65 + languageName: node + linkType: hard + +"base64-js@npm:^1.3.1": + version: 1.5.1 + resolution: "base64-js@npm:1.5.1" + checksum: 669632eb3745404c2f822a18fc3a0122d2f9a7a13f7fb8b5823ee19d1d2ff9ee5b52c53367176ea4ad093c332fd5ab4bd0ebae5a8e27917a4105a4cfc86b1005 + languageName: node + linkType: hard + +"bin-check@npm:^4.1.0": + version: 4.1.0 + resolution: "bin-check@npm:4.1.0" + dependencies: + execa: "npm:^0.7.0" + executable: "npm:^4.1.0" + checksum: 16f6d5d86df9365dab682c7dd238f93678b773a908b3bccea4b1acb82b9b4e49fcfa24c99b99180a8e4cdd89a8f15f03700b09908ed5ae651f52fd82488a3507 + languageName: node + linkType: hard + +"bin-version-check@npm:^5.0.0": + version: 5.1.0 + resolution: "bin-version-check@npm:5.1.0" + dependencies: + bin-version: "npm:^6.0.0" + semver: "npm:^7.5.3" + semver-truncate: "npm:^3.0.0" + checksum: d99679cfe0964703045fe0145a98f117888942b621dfe2c2377305ee9a9d735374d8e3ecb3b476507b284af2567699f24f7ecb2feb1f27ad6086ad60b3198893 + languageName: node + linkType: hard + +"bin-version@npm:^6.0.0": + version: 6.0.0 + resolution: "bin-version@npm:6.0.0" + dependencies: + execa: "npm:^5.0.0" + find-versions: "npm:^5.0.0" + checksum: 78c29422ea9597eb4c8d4f0eff96df60d09aa82b53a87925bc403efbe5c55251b1a07baac538381d9096377f92d27e3c03963efa86db5bc0d6431b9563946229 + languageName: node + linkType: hard + +"brace-expansion@npm:^2.0.1": + version: 2.0.1 + resolution: "brace-expansion@npm:2.0.1" + dependencies: + balanced-match: "npm:^1.0.0" + checksum: a61e7cd2e8a8505e9f0036b3b6108ba5e926b4b55089eeb5550cd04a471fe216c96d4fe7e4c7f995c728c554ae20ddfc4244cad10aef255e72b62930afd233d1 + languageName: node + linkType: hard + +"braces@npm:^3.0.3": + version: 3.0.3 + resolution: "braces@npm:3.0.3" + dependencies: + fill-range: "npm:^7.1.1" + checksum: fad11a0d4697a27162840b02b1fad249c1683cbc510cd5bf1a471f2f8085c046d41094308c577a50a03a579dd99d5a6b3724c4b5e8b14df2c4443844cfcda2c6 + languageName: node + linkType: hard + +"buffer-more-ints@npm:~1.0.0": + version: 1.0.0 + resolution: "buffer-more-ints@npm:1.0.0" + checksum: 603a7f35793426c8efd733eb716c2c3bf3e2f5bab95ca13ba31546d89ead3636586479c5a0d8438dd015115361a3b09b1b37ddabc170b6d42bc6c6dc2554dc61 + languageName: node + linkType: hard + +"buffer@npm:^6.0.3": + version: 6.0.3 + resolution: "buffer@npm:6.0.3" + dependencies: + base64-js: "npm:^1.3.1" + ieee754: "npm:^1.2.1" + checksum: b6bc68237ebf29bdacae48ce60e5e28fc53ae886301f2ad9496618efac49427ed79096750033e7eab1897a4f26ae374ace49106a5758f38fb70c78c9fda2c3b1 + languageName: node + linkType: hard + +"cacache@npm:^18.0.0": + version: 18.0.3 + resolution: "cacache@npm:18.0.3" + dependencies: + "@npmcli/fs": "npm:^3.1.0" + fs-minipass: "npm:^3.0.0" + glob: "npm:^10.2.2" + lru-cache: "npm:^10.0.1" + minipass: "npm:^7.0.3" + minipass-collect: "npm:^2.0.1" + minipass-flush: "npm:^1.0.5" + minipass-pipeline: "npm:^1.2.4" + p-map: "npm:^4.0.0" + ssri: "npm:^10.0.0" + tar: "npm:^6.1.11" + unique-filename: "npm:^3.0.0" + checksum: d4c161f071524bb636334b8cf94780c014e29c180a886b8184da8f2f44d2aca88d5664797c661e9f74bdbd34697c2f231ed7c24c256cecbb0a0563ad1ada2219 + languageName: node + linkType: hard + +"cacheable-lookup@npm:^5.0.3": + version: 5.0.4 + resolution: "cacheable-lookup@npm:5.0.4" + checksum: 618a8b3eea314060e74cb3285a6154e8343c244a34235acf91cfe626ee0705c24e3cd11e4b1a7b3900bd749ee203ae65afe13adf610c8ab173e99d4a208faf75 + languageName: node + linkType: hard + +"cacheable-request@npm:^7.0.2": + version: 7.0.4 + resolution: "cacheable-request@npm:7.0.4" + dependencies: + clone-response: "npm:^1.0.2" + get-stream: "npm:^5.1.0" + http-cache-semantics: "npm:^4.0.0" + keyv: "npm:^4.0.0" + lowercase-keys: "npm:^2.0.0" + normalize-url: "npm:^6.0.1" + responselike: "npm:^2.0.0" + checksum: 0f4f2001260ecca78b9f64fc8245e6b5a5dcde24ea53006daab71f5e0e1338095aa1512ec099c4f9895a9e5acfac9da423cb7c079e131485891e9214aca46c41 + languageName: node + linkType: hard + +"chalk@npm:^5.3.0": + version: 5.3.0 + resolution: "chalk@npm:5.3.0" + checksum: 6373caaab21bd64c405bfc4bd9672b145647fc9482657b5ea1d549b3b2765054e9d3d928870cdf764fb4aad67555f5061538ff247b8310f110c5c888d92397ea + languageName: node + linkType: hard + +"chownr@npm:^2.0.0": + version: 2.0.0 + resolution: "chownr@npm:2.0.0" + checksum: c57cf9dd0791e2f18a5ee9c1a299ae6e801ff58fee96dc8bfd0dcb4738a6ce58dd252a3605b1c93c6418fe4f9d5093b28ffbf4d66648cb2a9c67eaef9679be2f + languageName: node + linkType: hard + +"clean-stack@npm:^2.0.0": + version: 2.2.0 + resolution: "clean-stack@npm:2.2.0" + checksum: 2ac8cd2b2f5ec986a3c743935ec85b07bc174d5421a5efc8017e1f146a1cf5f781ae962618f416352103b32c9cd7e203276e8c28241bbe946160cab16149fb68 + languageName: node + linkType: hard + +"clone-response@npm:^1.0.2": + version: 1.0.3 + resolution: "clone-response@npm:1.0.3" + dependencies: + mimic-response: "npm:^1.0.0" + checksum: 4e671cac39b11c60aa8ba0a450657194a5d6504df51bca3fac5b3bd0145c4f8e8464898f87c8406b83232e3bc5cca555f51c1f9c8ac023969ebfbf7f6bdabb2e + languageName: node + linkType: hard + +"color-convert@npm:^2.0.1": + version: 2.0.1 + resolution: "color-convert@npm:2.0.1" + dependencies: + color-name: "npm:~1.1.4" + checksum: fa00c91b4332b294de06b443923246bccebe9fab1b253f7fe1772d37b06a2269b4039a85e309abe1fe11b267b11c08d1d0473fda3badd6167f57313af2887a64 + languageName: node + linkType: hard + +"color-name@npm:~1.1.4": + version: 1.1.4 + resolution: "color-name@npm:1.1.4" + checksum: b0445859521eb4021cd0fb0cc1a75cecf67fceecae89b63f62b201cca8d345baf8b952c966862a9d9a2632987d4f6581f0ec8d957dfacece86f0a7919316f610 + languageName: node + linkType: hard + +"commander@npm:^8.3.0": + version: 8.3.0 + resolution: "commander@npm:8.3.0" + checksum: 6b7b5d334483ce24bd73c5dac2eab901a7dbb25fd983ea24a1eeac6e7166bb1967f641546e8abf1920afbde86a45fbfe5812fbc69d0dc451bb45ca416a12a3a3 + languageName: node + linkType: hard + +"content-disposition@npm:^0.5.4": + version: 0.5.4 + resolution: "content-disposition@npm:0.5.4" + dependencies: + safe-buffer: "npm:5.2.1" + checksum: b7f4ce176e324f19324be69b05bf6f6e411160ac94bc523b782248129eb1ef3be006f6cff431aaea5e337fe5d176ce8830b8c2a1b721626ead8933f0cbe78720 + languageName: node + linkType: hard + +"cookie@npm:^0.6.0": + version: 0.6.0 + resolution: "cookie@npm:0.6.0" + checksum: c1f8f2ea7d443b9331680598b0ae4e6af18a618c37606d1bbdc75bec8361cce09fe93e727059a673f2ba24467131a9fb5a4eec76bb1b149c1b3e1ccb268dc583 + languageName: node + linkType: hard + +"core-util-is@npm:~1.0.0": + version: 1.0.3 + resolution: "core-util-is@npm:1.0.3" + checksum: 9de8597363a8e9b9952491ebe18167e3b36e7707569eed0ebf14f8bba773611376466ae34575bca8cfe3c767890c859c74056084738f09d4e4a6f902b2ad7d99 + languageName: node + linkType: hard + +"cross-spawn@npm:^5.0.1": + version: 5.1.0 + resolution: "cross-spawn@npm:5.1.0" + dependencies: + lru-cache: "npm:^4.0.1" + shebang-command: "npm:^1.2.0" + which: "npm:^1.2.9" + checksum: 726939c9954fc70c20e538923feaaa33bebc253247d13021737c3c7f68cdc3e0a57f720c0fe75057c0387995349f3f12e20e9bfdbf12274db28019c7ea4ec166 + languageName: node + linkType: hard + +"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.3": + version: 7.0.3 + resolution: "cross-spawn@npm:7.0.3" + dependencies: + path-key: "npm:^3.1.0" + shebang-command: "npm:^2.0.0" + which: "npm:^2.0.1" + checksum: e1a13869d2f57d974de0d9ef7acbf69dc6937db20b918525a01dacb5032129bd552d290d886d981e99f1b624cb03657084cc87bd40f115c07ecf376821c729ce + languageName: node + linkType: hard + +"dd-bigbot@workspace:.": + version: 0.0.0-use.local + resolution: "dd-bigbot@workspace:." + dependencies: + "@discordeno/bot": "npm:19.0.0-next.92bf166" + "@fastify/multipart": "npm:^8.3.0" + "@influxdata/influxdb-client": "npm:^1.33.2" + "@swc/cli": "npm:^0.3.12" + "@swc/core": "npm:^1.6.3" + "@types/amqplib": "npm:^0.10.5" + "@types/node": "npm:^20.14.6" + amqplib: "npm:^0.10.4" + chalk: "npm:^5.3.0" + fastify: "npm:^4.28.0" + typescript: "npm:^5.5.2" + languageName: unknown + linkType: soft + +"debug@npm:4, debug@npm:^4.3.4": + version: 4.3.5 + resolution: "debug@npm:4.3.5" + dependencies: + ms: "npm:2.1.2" + peerDependenciesMeta: + supports-color: + optional: true + checksum: cb6eab424c410e07813ca1392888589972ce9a32b8829c6508f5e1f25f3c3e70a76731610ae55b4bbe58d1a2fffa1424b30e97fa8d394e49cd2656a9643aedd2 + languageName: node + linkType: hard + +"decompress-response@npm:^6.0.0": + version: 6.0.0 + resolution: "decompress-response@npm:6.0.0" + dependencies: + mimic-response: "npm:^3.1.0" + checksum: d377cf47e02d805e283866c3f50d3d21578b779731e8c5072d6ce8c13cc31493db1c2f6784da9d1d5250822120cefa44f1deab112d5981015f2e17444b763812 + languageName: node + linkType: hard + +"defer-to-connect@npm:^2.0.0": + version: 2.0.1 + resolution: "defer-to-connect@npm:2.0.1" + checksum: 8a9b50d2f25446c0bfefb55a48e90afd58f85b21bcf78e9207cd7b804354f6409032a1705c2491686e202e64fc05f147aa5aa45f9aa82627563f045937f5791b + languageName: node + linkType: hard + +"dotenv@npm:^16.4.5": + version: 16.4.5 + resolution: "dotenv@npm:16.4.5" + checksum: 55a3134601115194ae0f924e54473459ed0d9fc340ae610b676e248cca45aa7c680d86365318ea964e6da4e2ea80c4514c1adab5adb43d6867fb57ff068f95c8 + languageName: node + linkType: hard + +"eastasianwidth@npm:^0.2.0": + version: 0.2.0 + resolution: "eastasianwidth@npm:0.2.0" + checksum: 9b1d3e1baefeaf7d70799db8774149cef33b97183a6addceeba0cf6b85ba23ee2686f302f14482006df32df75d32b17c509c143a3689627929e4a8efaf483952 + languageName: node + linkType: hard + +"emoji-regex@npm:^8.0.0": + version: 8.0.0 + resolution: "emoji-regex@npm:8.0.0" + checksum: c72d67a6821be15ec11997877c437491c313d924306b8da5d87d2a2bcc2cec9903cb5b04ee1a088460501d8e5b44f10df82fdc93c444101a7610b80c8b6938e1 + languageName: node + linkType: hard + +"emoji-regex@npm:^9.2.2": + version: 9.2.2 + resolution: "emoji-regex@npm:9.2.2" + checksum: 915acf859cea7131dac1b2b5c9c8e35c4849e325a1d114c30adb8cd615970f6dca0e27f64f3a4949d7d6ed86ecd79a1c5c63f02e697513cddd7b5835c90948b8 + languageName: node + linkType: hard + +"encoding@npm:^0.1.13": + version: 0.1.13 + resolution: "encoding@npm:0.1.13" + dependencies: + iconv-lite: "npm:^0.6.2" + checksum: bb98632f8ffa823996e508ce6a58ffcf5856330fde839ae42c9e1f436cc3b5cc651d4aeae72222916545428e54fd0f6aa8862fd8d25bdbcc4589f1e3f3715e7f + languageName: node + linkType: hard + +"end-of-stream@npm:^1.1.0": + version: 1.4.4 + resolution: "end-of-stream@npm:1.4.4" + dependencies: + once: "npm:^1.4.0" + checksum: 530a5a5a1e517e962854a31693dbb5c0b2fc40b46dad2a56a2deec656ca040631124f4795823acc68238147805f8b021abbe221f4afed5ef3c8e8efc2024908b + languageName: node + linkType: hard + +"env-paths@npm:^2.2.0": + version: 2.2.1 + resolution: "env-paths@npm:2.2.1" + checksum: 65b5df55a8bab92229ab2b40dad3b387fad24613263d103a97f91c9fe43ceb21965cd3392b1ccb5d77088021e525c4e0481adb309625d0cb94ade1d1fb8dc17e + languageName: node + linkType: hard + +"err-code@npm:^2.0.2": + version: 2.0.3 + resolution: "err-code@npm:2.0.3" + checksum: 1d20d825cdcce8d811bfbe86340f4755c02655a7feb2f13f8c880566d9d72a3f6c92c192a6867632e490d6da67b678271f46e01044996a6443e870331100dfdd + languageName: node + linkType: hard + +"escape-string-regexp@npm:^5.0.0": + version: 5.0.0 + resolution: "escape-string-regexp@npm:5.0.0" + checksum: 20daabe197f3cb198ec28546deebcf24b3dbb1a5a269184381b3116d12f0532e06007f4bc8da25669d6a7f8efb68db0758df4cd981f57bc5b57f521a3e12c59e + languageName: node + linkType: hard + +"event-target-shim@npm:^5.0.0": + version: 5.0.1 + resolution: "event-target-shim@npm:5.0.1" + checksum: 49ff46c3a7facbad3decb31f597063e761785d7fdb3920d4989d7b08c97a61c2f51183e2f3a03130c9088df88d4b489b1b79ab632219901f184f85158508f4c8 + languageName: node + linkType: hard + +"events@npm:^3.3.0": + version: 3.3.0 + resolution: "events@npm:3.3.0" + checksum: a3d47e285e28d324d7180f1e493961a2bbb4cad6412090e4dec114f4db1f5b560c7696ee8e758f55e23913ede856e3689cd3aa9ae13c56b5d8314cd3b3ddd1be + languageName: node + linkType: hard + +"execa@npm:^0.7.0": + version: 0.7.0 + resolution: "execa@npm:0.7.0" + dependencies: + cross-spawn: "npm:^5.0.1" + get-stream: "npm:^3.0.0" + is-stream: "npm:^1.1.0" + npm-run-path: "npm:^2.0.0" + p-finally: "npm:^1.0.0" + signal-exit: "npm:^3.0.0" + strip-eof: "npm:^1.0.0" + checksum: 7c1721de38e51d67cef2367b1f6037c4a89bc64993d93683f9f740fc74d6930dfc92faf2749b917b7337a8d632d7b86a4673400f762bc1fe4a977ea6b0f9055f + languageName: node + linkType: hard + +"execa@npm:^5.0.0": + version: 5.1.1 + resolution: "execa@npm:5.1.1" + dependencies: + cross-spawn: "npm:^7.0.3" + get-stream: "npm:^6.0.0" + human-signals: "npm:^2.1.0" + is-stream: "npm:^2.0.0" + merge-stream: "npm:^2.0.0" + npm-run-path: "npm:^4.0.1" + onetime: "npm:^5.1.2" + signal-exit: "npm:^3.0.3" + strip-final-newline: "npm:^2.0.0" + checksum: 8ada91f2d70f7dff702c861c2c64f21dfdc1525628f3c0454fd6f02fce65f7b958616cbd2b99ca7fa4d474e461a3d363824e91b3eb881705231abbf387470597 + languageName: node + linkType: hard + +"executable@npm:^4.1.0": + version: 4.1.1 + resolution: "executable@npm:4.1.1" + dependencies: + pify: "npm:^2.2.0" + checksum: f01927ce59bccec804e171bf859a26e362c1f50aa9ebc69f7cafdcce3859d29d4b6267fd47237c18b0a1830614bd3f0ee14b7380d9bad18a4e7af9b5f0b6984f + languageName: node + linkType: hard + +"exponential-backoff@npm:^3.1.1": + version: 3.1.1 + resolution: "exponential-backoff@npm:3.1.1" + checksum: 2d9bbb6473de7051f96790d5f9a678f32e60ed0aa70741dc7fdc96fec8d631124ec3374ac144387604f05afff9500f31a1d45bd9eee4cdc2e4f9ad2d9b9d5dbd + languageName: node + linkType: hard + +"ext-list@npm:^2.0.0": + version: 2.2.2 + resolution: "ext-list@npm:2.2.2" + dependencies: + mime-db: "npm:^1.28.0" + checksum: fe69fedbef044e14d4ce9e84c6afceb696ba71500c15b8d0ce0a1e280237e17c95031b3d62d5e597652fea0065b9bf957346b3900d989dff59128222231ac859 + languageName: node + linkType: hard + +"ext-name@npm:^5.0.0": + version: 5.0.0 + resolution: "ext-name@npm:5.0.0" + dependencies: + ext-list: "npm:^2.0.0" + sort-keys-length: "npm:^1.0.0" + checksum: f598269bd5de4295540ea7d6f8f6a01d82a7508f148b7700a05628ef6121648d26e6e5e942049e953b3051863df6b54bd8fe951e7877f185e34ace5d44370b33 + languageName: node + linkType: hard + +"fast-content-type-parse@npm:^1.1.0": + version: 1.1.0 + resolution: "fast-content-type-parse@npm:1.1.0" + checksum: 8637228a19b11296992af5d9b5f5ae84c6f27a465cf36a901b303b784ce0ca6f10502375da59958eb2b9c4949b98e5cc460ecb4bd777d22c3fa236c1e8da1ed8 + languageName: node + linkType: hard + +"fast-decode-uri-component@npm:^1.0.1": + version: 1.0.1 + resolution: "fast-decode-uri-component@npm:1.0.1" + checksum: 4b6ed26974414f688be4a15eab6afa997bad4a7c8605cb1deb928b28514817b4523a1af0fa06621c6cbfedb7e5615144c2c3e7512860e3a333a31a28d537dca7 + languageName: node + linkType: hard + +"fast-deep-equal@npm:^3.1.3": + version: 3.1.3 + resolution: "fast-deep-equal@npm:3.1.3" + checksum: e21a9d8d84f53493b6aa15efc9cfd53dd5b714a1f23f67fb5dc8f574af80df889b3bce25dc081887c6d25457cce704e636395333abad896ccdec03abaf1f3f9d + languageName: node + linkType: hard + +"fast-glob@npm:^3.2.5": + version: 3.3.2 + resolution: "fast-glob@npm:3.3.2" + dependencies: + "@nodelib/fs.stat": "npm:^2.0.2" + "@nodelib/fs.walk": "npm:^1.2.3" + glob-parent: "npm:^5.1.2" + merge2: "npm:^1.3.0" + micromatch: "npm:^4.0.4" + checksum: 222512e9315a0efca1276af9adb2127f02105d7288fa746145bf45e2716383fb79eb983c89601a72a399a56b7c18d38ce70457c5466218c5f13fad957cee16df + languageName: node + linkType: hard + +"fast-json-stringify@npm:^5.7.0, fast-json-stringify@npm:^5.8.0": + version: 5.16.0 + resolution: "fast-json-stringify@npm:5.16.0" + dependencies: + "@fastify/merge-json-schemas": "npm:^0.1.0" + ajv: "npm:^8.10.0" + ajv-formats: "npm:^3.0.1" + fast-deep-equal: "npm:^3.1.3" + fast-uri: "npm:^2.1.0" + json-schema-ref-resolver: "npm:^1.0.1" + rfdc: "npm:^1.2.0" + checksum: 06ae46bba0d362c515aed21326cd9496723dd34422b7d86a5da7442807b9b02ecea856e4ed42b4aa96dce61c806c2bf29eb483efa17ef63a4ff76aab3c2cc21b + languageName: node + linkType: hard + +"fast-querystring@npm:^1.0.0": + version: 1.1.2 + resolution: "fast-querystring@npm:1.1.2" + dependencies: + fast-decode-uri-component: "npm:^1.0.1" + checksum: 981da9b914f2b639dc915bdfa4f34ab028b967d428f02fbd293d99258593fde69c48eea73dfa03ced088268e0a8045c642e8debcd9b4821ebd125e130a0430c7 + languageName: node + linkType: hard + +"fast-redact@npm:^3.1.1": + version: 3.5.0 + resolution: "fast-redact@npm:3.5.0" + checksum: 24b27e2023bd5a62f908d97a753b1adb8d89206b260f97727728e00b693197dea2fc2aa3711147a385d0ec6e713569fd533df37a4ef947e08cb65af3019c7ad5 + languageName: node + linkType: hard + +"fast-uri@npm:^2.0.0, fast-uri@npm:^2.1.0": + version: 2.3.1 + resolution: "fast-uri@npm:2.3.1" + checksum: 362e90cafd6fa1700ce12eb2f10a21e02a5b6c016f9f015eeb2b65f450775d8341e3fd4022f09134d3cf1415b112777c4502f3e9da009699dcc78053a641fba5 + languageName: node + linkType: hard + +"fastify-plugin@npm:^4.0.0": + version: 4.5.1 + resolution: "fastify-plugin@npm:4.5.1" + checksum: 7c6d777ada0f01c8a1166a2a669cccfd6074c7764121f07cce997745f198227a271c7a317aaf0da273b329f24307f0eba3f093d872d29b839b33deb525bbafe2 + languageName: node + linkType: hard + +"fastify@npm:^4.28.0": + version: 4.28.0 + resolution: "fastify@npm:4.28.0" + dependencies: + "@fastify/ajv-compiler": "npm:^3.5.0" + "@fastify/error": "npm:^3.4.0" + "@fastify/fast-json-stringify-compiler": "npm:^4.3.0" + abstract-logging: "npm:^2.0.1" + avvio: "npm:^8.3.0" + fast-content-type-parse: "npm:^1.1.0" + fast-json-stringify: "npm:^5.8.0" + find-my-way: "npm:^8.0.0" + light-my-request: "npm:^5.11.0" + pino: "npm:^9.0.0" + process-warning: "npm:^3.0.0" + proxy-addr: "npm:^2.0.7" + rfdc: "npm:^1.3.0" + secure-json-parse: "npm:^2.7.0" + semver: "npm:^7.5.4" + toad-cache: "npm:^3.3.0" + checksum: 8f3991b1ae2b5248ca9fb09f57f0fc083ca3ca26ab418fb2b0b768c5cec5c01aa4aaa9e7697018457a5f53fe43d74747bac2393509eeac96bb535d5cbba4e062 + languageName: node + linkType: hard + +"fastq@npm:^1.17.1, fastq@npm:^1.6.0": + version: 1.17.1 + resolution: "fastq@npm:1.17.1" + dependencies: + reusify: "npm:^1.0.4" + checksum: a443180068b527dd7b3a63dc7f2a47ceca2f3e97b9c00a1efe5538757e6cc4056a3526df94308075d7727561baf09ebaa5b67da8dcbddb913a021c5ae69d1f69 + languageName: node + linkType: hard + +"file-type@npm:^17.1.6": + version: 17.1.6 + resolution: "file-type@npm:17.1.6" + dependencies: + readable-web-to-node-stream: "npm:^3.0.2" + strtok3: "npm:^7.0.0-alpha.9" + token-types: "npm:^5.0.0-alpha.2" + checksum: 47c69b4046e31142492a135982b9a9e4873b368919a2e66d0ebdc04143b6d2e1225b4bec820668c442ef201b54d03569df08b6052edc6015b1022c236784e1c1 + languageName: node + linkType: hard + +"filename-reserved-regex@npm:^3.0.0": + version: 3.0.0 + resolution: "filename-reserved-regex@npm:3.0.0" + checksum: 1803e19ce64d7cb88ee5a1bd3ce282470a5c263987269222426d889049fc857e302284fa71937de9582eba7a9f39539557d45e0562f2fa51cade8efc68c65dd9 + languageName: node + linkType: hard + +"filenamify@npm:^5.0.2": + version: 5.1.1 + resolution: "filenamify@npm:5.1.1" + dependencies: + filename-reserved-regex: "npm:^3.0.0" + strip-outer: "npm:^2.0.0" + trim-repeated: "npm:^2.0.0" + checksum: 55a7ed0858eb2655bb1bb1e945a59e3fb30ba4767f6924fa064ccd731bff07678aac3cb4f3899ae0e1621fe81d6472b5688232bb6afd4eeb989ade785fc1c6f1 + languageName: node + linkType: hard + +"fill-range@npm:^7.1.1": + version: 7.1.1 + resolution: "fill-range@npm:7.1.1" + dependencies: + to-regex-range: "npm:^5.0.1" + checksum: a7095cb39e5bc32fada2aa7c7249d3f6b01bd1ce461a61b0adabacccabd9198500c6fb1f68a7c851a657e273fce2233ba869638897f3d7ed2e87a2d89b4436ea + languageName: node + linkType: hard + +"find-my-way@npm:^8.0.0": + version: 8.2.0 + resolution: "find-my-way@npm:8.2.0" + dependencies: + fast-deep-equal: "npm:^3.1.3" + fast-querystring: "npm:^1.0.0" + safe-regex2: "npm:^3.1.0" + checksum: 07e46c94c594f7f3f3bf3acb5839753c4d02dca83ecd0d3e966b11effc741d212d15050c365ab104e5ea3312f44d08a68fa7939bb759b851d6c874e0cf106523 + languageName: node + linkType: hard + +"find-versions@npm:^5.0.0": + version: 5.1.0 + resolution: "find-versions@npm:5.1.0" + dependencies: + semver-regex: "npm:^4.0.5" + checksum: 680bdb0081f631f7bfb6f0f8edcfa0b74ab8cabc82097a4527a37b0d042aabc56685bf459ff27991eab0baddc04eb8e3bba8a2869f5004ecf7cdd2779b6e51de + languageName: node + linkType: hard + +"foreground-child@npm:^3.1.0": + version: 3.1.1 + resolution: "foreground-child@npm:3.1.1" + dependencies: + cross-spawn: "npm:^7.0.0" + signal-exit: "npm:^4.0.1" + checksum: 087edd44857d258c4f73ad84cb8df980826569656f2550c341b27adf5335354393eec24ea2fabd43a253233fb27cee177ebe46bd0b7ea129c77e87cb1e9936fb + languageName: node + linkType: hard + +"forwarded@npm:0.2.0": + version: 0.2.0 + resolution: "forwarded@npm:0.2.0" + checksum: 29ba9fd347117144e97cbb8852baae5e8b2acb7d1b591ef85695ed96f5b933b1804a7fac4a15dd09ca7ac7d0cdc104410e8102aae2dd3faa570a797ba07adb81 + languageName: node + linkType: hard + +"fs-minipass@npm:^2.0.0": + version: 2.1.0 + resolution: "fs-minipass@npm:2.1.0" + dependencies: + minipass: "npm:^3.0.0" + checksum: 03191781e94bc9a54bd376d3146f90fe8e082627c502185dbf7b9b3032f66b0b142c1115f3b2cc5936575fc1b44845ce903dd4c21bec2a8d69f3bd56f9cee9ec + languageName: node + linkType: hard + +"fs-minipass@npm:^3.0.0": + version: 3.0.3 + resolution: "fs-minipass@npm:3.0.3" + dependencies: + minipass: "npm:^7.0.3" + checksum: af143246cf6884fe26fa281621d45cfe111d34b30535a475bfa38dafe343dadb466c047a924ffc7d6b7b18265df4110224ce3803806dbb07173bf2087b648d7f + languageName: node + linkType: hard + +"get-stream@npm:^3.0.0": + version: 3.0.0 + resolution: "get-stream@npm:3.0.0" + checksum: de14fbb3b4548ace9ab6376be852eef9898c491282e29595bc908a1814a126d3961b11cd4b7be5220019fe3b2abb84568da7793ad308fc139925a217063fa159 + languageName: node + linkType: hard + +"get-stream@npm:^5.1.0": + version: 5.2.0 + resolution: "get-stream@npm:5.2.0" + dependencies: + pump: "npm:^3.0.0" + checksum: 13a73148dca795e41421013da6e3ebff8ccb7fba4d2f023fd0c6da2c166ec4e789bec9774a73a7b49c08daf2cae552f8a3e914042ac23b5f59dd278cc8f9cbfb + languageName: node + linkType: hard + +"get-stream@npm:^6.0.0": + version: 6.0.1 + resolution: "get-stream@npm:6.0.1" + checksum: 781266d29725f35c59f1d214aedc92b0ae855800a980800e2923b3fbc4e56b3cb6e462c42e09a1cf1a00c64e056a78fa407cbe06c7c92b7e5cd49b4b85c2a497 + languageName: node + linkType: hard + +"glob-parent@npm:^5.1.2": + version: 5.1.2 + resolution: "glob-parent@npm:5.1.2" + dependencies: + is-glob: "npm:^4.0.1" + checksum: 32cd106ce8c0d83731966d31517adb766d02c3812de49c30cfe0675c7c0ae6630c11214c54a5ae67aca882cf738d27fd7768f21aa19118b9245950554be07247 + languageName: node + linkType: hard + +"glob@npm:^10.2.2, glob@npm:^10.3.10": + version: 10.4.1 + resolution: "glob@npm:10.4.1" + dependencies: + foreground-child: "npm:^3.1.0" + jackspeak: "npm:^3.1.2" + minimatch: "npm:^9.0.4" + minipass: "npm:^7.1.2" + path-scurry: "npm:^1.11.1" + bin: + glob: dist/esm/bin.mjs + checksum: d7bb49d2b413f77bdd59fea4ca86dcc12450deee221af0ca93e09534b81b9ef68fe341345751d8ff0c5b54bad422307e0e44266ff8ad7fbbd0c200e8ec258b16 + languageName: node + linkType: hard + +"got@npm:^11.8.5": + version: 11.8.6 + resolution: "got@npm:11.8.6" + dependencies: + "@sindresorhus/is": "npm:^4.0.0" + "@szmarczak/http-timer": "npm:^4.0.5" + "@types/cacheable-request": "npm:^6.0.1" + "@types/responselike": "npm:^1.0.0" + cacheable-lookup: "npm:^5.0.3" + cacheable-request: "npm:^7.0.2" + decompress-response: "npm:^6.0.0" + http2-wrapper: "npm:^1.0.0-beta.5.2" + lowercase-keys: "npm:^2.0.0" + p-cancelable: "npm:^2.0.0" + responselike: "npm:^2.0.0" + checksum: a30c74029d81bd5fe50dea1a0c970595d792c568e188ff8be254b5bc11e6158d1b014570772d4a30d0a97723e7dd34e7c8cc1a2f23018f60aece3070a7a5c2a5 + languageName: node + linkType: hard + +"graceful-fs@npm:^4.2.6": + version: 4.2.11 + resolution: "graceful-fs@npm:4.2.11" + checksum: bf152d0ed1dc159239db1ba1f74fdbc40cb02f626770dcd5815c427ce0688c2635a06ed69af364396da4636d0408fcf7d4afdf7881724c3307e46aff30ca49e2 + languageName: node + linkType: hard + +"http-cache-semantics@npm:^4.0.0, http-cache-semantics@npm:^4.1.1": + version: 4.1.1 + resolution: "http-cache-semantics@npm:4.1.1" + checksum: 362d5ed66b12ceb9c0a328fb31200b590ab1b02f4a254a697dc796850cc4385603e75f53ec59f768b2dad3bfa1464bd229f7de278d2899a0e3beffc634b6683f + languageName: node + linkType: hard + +"http-proxy-agent@npm:^7.0.0": + version: 7.0.2 + resolution: "http-proxy-agent@npm:7.0.2" + dependencies: + agent-base: "npm:^7.1.0" + debug: "npm:^4.3.4" + checksum: d062acfa0cb82beeb558f1043c6ba770ea892b5fb7b28654dbc70ea2aeea55226dd34c02a294f6c1ca179a5aa483c4ea641846821b182edbd9cc5d89b54c6848 + languageName: node + linkType: hard + +"http2-wrapper@npm:^1.0.0-beta.5.2": + version: 1.0.3 + resolution: "http2-wrapper@npm:1.0.3" + dependencies: + quick-lru: "npm:^5.1.1" + resolve-alpn: "npm:^1.0.0" + checksum: 8097ee2699440c2e64bda52124990cc5b0fb347401c7797b1a0c1efd5a0f79a4ebaa68e8a6ac3e2dde5f09460c1602764da6da2412bad628ed0a3b0ae35e72d4 + languageName: node + linkType: hard + +"https-proxy-agent@npm:^7.0.1": + version: 7.0.4 + resolution: "https-proxy-agent@npm:7.0.4" + dependencies: + agent-base: "npm:^7.0.2" + debug: "npm:4" + checksum: 405fe582bba461bfe5c7e2f8d752b384036854488b828ae6df6a587c654299cbb2c50df38c4b6ab303502c3c5e029a793fbaac965d1e86ee0be03faceb554d63 + languageName: node + linkType: hard + +"human-signals@npm:^2.1.0": + version: 2.1.0 + resolution: "human-signals@npm:2.1.0" + checksum: df59be9e0af479036798a881d1f136c4a29e0b518d4abb863afbd11bf30efa3eeb1d0425fc65942dcc05ab3bf40205ea436b0ff389f2cd20b75b8643d539bf86 + languageName: node + linkType: hard + +"iconv-lite@npm:^0.6.2": + version: 0.6.3 + resolution: "iconv-lite@npm:0.6.3" + dependencies: + safer-buffer: "npm:>= 2.1.2 < 3.0.0" + checksum: 24e3292dd3dadaa81d065c6f8c41b274a47098150d444b96e5f53b4638a9a71482921ea6a91a1f59bb71d9796de25e04afd05919fa64c360347ba65d3766f10f + languageName: node + linkType: hard + +"ieee754@npm:^1.2.1": + version: 1.2.1 + resolution: "ieee754@npm:1.2.1" + checksum: d9f2557a59036f16c282aaeb107832dc957a93d73397d89bbad4eb1130560560eb695060145e8e6b3b498b15ab95510226649a0b8f52ae06583575419fe10fc4 + languageName: node + linkType: hard + +"imurmurhash@npm:^0.1.4": + version: 0.1.4 + resolution: "imurmurhash@npm:0.1.4" + checksum: 2d30b157a91fe1c1d7c6f653cbf263f039be6c5bfa959245a16d4ee191fc0f2af86c08545b6e6beeb041c56b574d2d5b9f95343d378ab49c0f37394d541e7fc8 + languageName: node + linkType: hard + +"indent-string@npm:^4.0.0": + version: 4.0.0 + resolution: "indent-string@npm:4.0.0" + checksum: cd3f5cbc9ca2d624c6a1f53f12e6b341659aba0e2d3254ae2b4464aaea8b4294cdb09616abbc59458f980531f2429784ed6a420d48d245bcad0811980c9efae9 + languageName: node + linkType: hard + +"inherits@npm:^2.0.3, inherits@npm:~2.0.1": + version: 2.0.4 + resolution: "inherits@npm:2.0.4" + checksum: cd45e923bee15186c07fa4c89db0aace24824c482fb887b528304694b2aa6ff8a898da8657046a5dcf3e46cd6db6c61629551f9215f208d7c3f157cf9b290521 + languageName: node + linkType: hard + +"ip-address@npm:^9.0.5": + version: 9.0.5 + resolution: "ip-address@npm:9.0.5" + dependencies: + jsbn: "npm:1.1.0" + sprintf-js: "npm:^1.1.3" + checksum: 1ed81e06721af012306329b31f532b5e24e00cb537be18ddc905a84f19fe8f83a09a1699862bf3a1ec4b9dea93c55a3fa5faf8b5ea380431469df540f38b092c + languageName: node + linkType: hard + +"ipaddr.js@npm:1.9.1": + version: 1.9.1 + resolution: "ipaddr.js@npm:1.9.1" + checksum: 864d0cced0c0832700e9621913a6429ccdc67f37c1bd78fb8c6789fff35c9d167cb329134acad2290497a53336813ab4798d2794fd675d5eb33b5fdf0982b9ca + languageName: node + linkType: hard + +"is-extglob@npm:^2.1.1": + version: 2.1.1 + resolution: "is-extglob@npm:2.1.1" + checksum: df033653d06d0eb567461e58a7a8c9f940bd8c22274b94bf7671ab36df5719791aae15eef6d83bbb5e23283967f2f984b8914559d4449efda578c775c4be6f85 + languageName: node + linkType: hard + +"is-fullwidth-code-point@npm:^3.0.0": + version: 3.0.0 + resolution: "is-fullwidth-code-point@npm:3.0.0" + checksum: 44a30c29457c7fb8f00297bce733f0a64cd22eca270f83e58c105e0d015e45c019491a4ab2faef91ab51d4738c670daff901c799f6a700e27f7314029e99e348 + languageName: node + linkType: hard + +"is-glob@npm:^4.0.1": + version: 4.0.3 + resolution: "is-glob@npm:4.0.3" + dependencies: + is-extglob: "npm:^2.1.1" + checksum: 3ed74f2b0cdf4f401f38edb0442ddfde3092d79d7d35c9919c86641efdbcbb32e45aa3c0f70ce5eecc946896cd5a0f26e4188b9f2b881876f7cb6c505b82da11 + languageName: node + linkType: hard + +"is-lambda@npm:^1.0.1": + version: 1.0.1 + resolution: "is-lambda@npm:1.0.1" + checksum: 93a32f01940220532e5948538699ad610d5924ac86093fcee83022252b363eb0cc99ba53ab084a04e4fb62bf7b5731f55496257a4c38adf87af9c4d352c71c35 + languageName: node + linkType: hard + +"is-number@npm:^7.0.0": + version: 7.0.0 + resolution: "is-number@npm:7.0.0" + checksum: 6a6c3383f68afa1e05b286af866017c78f1226d43ac8cb064e115ff9ed85eb33f5c4f7216c96a71e4dfea289ef52c5da3aef5bbfade8ffe47a0465d70c0c8e86 + languageName: node + linkType: hard + +"is-plain-obj@npm:^1.0.0": + version: 1.1.0 + resolution: "is-plain-obj@npm:1.1.0" + checksum: 0ee04807797aad50859652a7467481816cbb57e5cc97d813a7dcd8915da8195dc68c436010bf39d195226cde6a2d352f4b815f16f26b7bf486a5754290629931 + languageName: node + linkType: hard + +"is-stream@npm:^1.1.0": + version: 1.1.0 + resolution: "is-stream@npm:1.1.0" + checksum: 351aa77c543323c4e111204482808cfad68d2e940515949e31ccd0b010fc13d5fba4b9c230e4887fd24284713040f43e542332fbf172f6b9944b7d62e389c0ec + languageName: node + linkType: hard + +"is-stream@npm:^2.0.0": + version: 2.0.1 + resolution: "is-stream@npm:2.0.1" + checksum: b8e05ccdf96ac330ea83c12450304d4a591f9958c11fd17bed240af8d5ffe08aedafa4c0f4cfccd4d28dc9d4d129daca1023633d5c11601a6cbc77521f6fae66 + languageName: node + linkType: hard + +"isarray@npm:0.0.1": + version: 0.0.1 + resolution: "isarray@npm:0.0.1" + checksum: 49191f1425681df4a18c2f0f93db3adb85573bcdd6a4482539d98eac9e705d8961317b01175627e860516a2fc45f8f9302db26e5a380a97a520e272e2a40a8d4 + languageName: node + linkType: hard + +"isexe@npm:^2.0.0": + version: 2.0.0 + resolution: "isexe@npm:2.0.0" + checksum: 7c9f715c03aff08f35e98b1fadae1b9267b38f0615d501824f9743f3aab99ef10e303ce7db3f186763a0b70a19de5791ebfc854ff884d5a8c4d92211f642ec92 + languageName: node + linkType: hard + +"isexe@npm:^3.1.1": + version: 3.1.1 + resolution: "isexe@npm:3.1.1" + checksum: 7fe1931ee4e88eb5aa524cd3ceb8c882537bc3a81b02e438b240e47012eef49c86904d0f0e593ea7c3a9996d18d0f1f3be8d3eaa92333977b0c3a9d353d5563e + languageName: node + linkType: hard + +"jackspeak@npm:^3.1.2": + version: 3.4.0 + resolution: "jackspeak@npm:3.4.0" + dependencies: + "@isaacs/cliui": "npm:^8.0.2" + "@pkgjs/parseargs": "npm:^0.11.0" + dependenciesMeta: + "@pkgjs/parseargs": + optional: true + checksum: 5032c43c0c1fb92e72846ce496df559214253bc6870c90399cbd7858571c53169d9494b7c152df04abcb75f2fb5e9cffe65651c67d573380adf3a482b150d84b + languageName: node + linkType: hard + +"jsbn@npm:1.1.0": + version: 1.1.0 + resolution: "jsbn@npm:1.1.0" + checksum: bebe7ae829bbd586ce8cbe83501dd8cb8c282c8902a8aeeed0a073a89dc37e8103b1244f3c6acd60278bcbfe12d93a3f83c9ac396868a3b3bbc3c5e5e3b648ef + languageName: node + linkType: hard + +"json-buffer@npm:3.0.1": + version: 3.0.1 + resolution: "json-buffer@npm:3.0.1" + checksum: 82876154521b7b68ba71c4f969b91572d1beabadd87bd3a6b236f85fbc7dc4695089191ed60bb59f9340993c51b33d479f45b6ba9f3548beb519705281c32c3c + languageName: node + linkType: hard + +"json-schema-ref-resolver@npm:^1.0.1": + version: 1.0.1 + resolution: "json-schema-ref-resolver@npm:1.0.1" + dependencies: + fast-deep-equal: "npm:^3.1.3" + checksum: 5ec9879fd939e0ddf84740fbdef31c574a6999cc4ecd8cee8e2a07d2627ec395f1a588d9433173cfe59d2473759389cea2782d67f850f9b95212f5bd2940a24b + languageName: node + linkType: hard + +"json-schema-traverse@npm:^1.0.0": + version: 1.0.0 + resolution: "json-schema-traverse@npm:1.0.0" + checksum: 02f2f466cdb0362558b2f1fd5e15cce82ef55d60cd7f8fa828cf35ba74330f8d767fcae5c5c2adb7851fa811766c694b9405810879bc4e1ddd78a7c0e03658ad + languageName: node + linkType: hard + +"keyv@npm:^4.0.0": + version: 4.5.4 + resolution: "keyv@npm:4.5.4" + dependencies: + json-buffer: "npm:3.0.1" + checksum: 167eb6ef64cc84b6fa0780ee50c9de456b422a1e18802209234f7c2cf7eae648c7741f32e50d7e24ccb22b24c13154070b01563d642755b156c357431a191e75 + languageName: node + linkType: hard + +"light-my-request@npm:^5.11.0": + version: 5.13.0 + resolution: "light-my-request@npm:5.13.0" + dependencies: + cookie: "npm:^0.6.0" + process-warning: "npm:^3.0.0" + set-cookie-parser: "npm:^2.4.1" + checksum: 29407ecd0fcc240fbc4ac53457247e7f796962aaa228e9c5057bb4a7d84fda4f14eaaf39212f2dbfe0869b78a2a42ec82ec4a597a181b9ee19ac23a636c0160d + languageName: node + linkType: hard + +"lowercase-keys@npm:^2.0.0": + version: 2.0.0 + resolution: "lowercase-keys@npm:2.0.0" + checksum: 1c233d2da35056e8c49fae8097ee061b8c799b2f02e33c2bf32f9913c7de8fb481ab04dab7df35e94156c800f5f34e99acbf32b21781d87c3aa43ef7b748b79e + languageName: node + linkType: hard + +"lru-cache@npm:^10.0.1, lru-cache@npm:^10.2.0": + version: 10.2.2 + resolution: "lru-cache@npm:10.2.2" + checksum: ff1a496d30b5eaec2c9079080965bb0cede203cf878371f7033a007f1e54cd4aa13cc8abf7ccec4c994a83a22ed5476e83a55bb57cc07e6c1547a42937e42c37 + languageName: node + linkType: hard + +"lru-cache@npm:^4.0.1": + version: 4.1.5 + resolution: "lru-cache@npm:4.1.5" + dependencies: + pseudomap: "npm:^1.0.2" + yallist: "npm:^2.1.2" + checksum: 9ec7d73f11a32cba0e80b7a58fdf29970814c0c795acaee1a6451ddfd609bae6ef9df0837f5bbeabb571ecd49c1e2d79e10e9b4ed422cfba17a0cb6145b018a9 + languageName: node + linkType: hard + +"make-fetch-happen@npm:^13.0.0": + version: 13.0.1 + resolution: "make-fetch-happen@npm:13.0.1" + dependencies: + "@npmcli/agent": "npm:^2.0.0" + cacache: "npm:^18.0.0" + http-cache-semantics: "npm:^4.1.1" + is-lambda: "npm:^1.0.1" + minipass: "npm:^7.0.2" + minipass-fetch: "npm:^3.0.0" + minipass-flush: "npm:^1.0.5" + minipass-pipeline: "npm:^1.2.4" + negotiator: "npm:^0.6.3" + proc-log: "npm:^4.2.0" + promise-retry: "npm:^2.0.1" + ssri: "npm:^10.0.0" + checksum: 11bae5ad6ac59b654dbd854f30782f9de052186c429dfce308eda42374528185a100ee40ac9ffdc36a2b6c821ecaba43913e4730a12f06f15e895ea9cb23fa59 + languageName: node + linkType: hard + +"merge-stream@npm:^2.0.0": + version: 2.0.0 + resolution: "merge-stream@npm:2.0.0" + checksum: 6fa4dcc8d86629705cea944a4b88ef4cb0e07656ebf223fa287443256414283dd25d91c1cd84c77987f2aec5927af1a9db6085757cb43d90eb170ebf4b47f4f4 + languageName: node + linkType: hard + +"merge2@npm:^1.3.0": + version: 1.4.1 + resolution: "merge2@npm:1.4.1" + checksum: 7268db63ed5169466540b6fb947aec313200bcf6d40c5ab722c22e242f651994619bcd85601602972d3c85bd2cc45a358a4c61937e9f11a061919a1da569b0c2 + languageName: node + linkType: hard + +"micromatch@npm:^4.0.4": + version: 4.0.7 + resolution: "micromatch@npm:4.0.7" + dependencies: + braces: "npm:^3.0.3" + picomatch: "npm:^2.3.1" + checksum: a11ed1cb67dcbbe9a5fc02c4062cf8bb0157d73bf86956003af8dcfdf9b287f9e15ec0f6d6925ff6b8b5b496202335e497b01de4d95ef6cf06411bc5e5c474a0 + languageName: node + linkType: hard + +"mime-db@npm:^1.28.0": + version: 1.52.0 + resolution: "mime-db@npm:1.52.0" + checksum: 54bb60bf39e6f8689f6622784e668a3d7f8bed6b0d886f5c3c446cb3284be28b30bf707ed05d0fe44a036f8469976b2629bbea182684977b084de9da274694d7 + languageName: node + linkType: hard + +"mimic-fn@npm:^2.1.0": + version: 2.1.0 + resolution: "mimic-fn@npm:2.1.0" + checksum: d2421a3444848ce7f84bd49115ddacff29c15745db73f54041edc906c14b131a38d05298dae3081667627a59b2eb1ca4b436ff2e1b80f69679522410418b478a + languageName: node + linkType: hard + +"mimic-response@npm:^1.0.0": + version: 1.0.1 + resolution: "mimic-response@npm:1.0.1" + checksum: 034c78753b0e622bc03c983663b1cdf66d03861050e0c8606563d149bc2b02d63f62ce4d32be4ab50d0553ae0ffe647fc34d1f5281184c6e1e8cf4d85e8d9823 + languageName: node + linkType: hard + +"mimic-response@npm:^3.1.0": + version: 3.1.0 + resolution: "mimic-response@npm:3.1.0" + checksum: 7e719047612411fe071332a7498cf0448bbe43c485c0d780046c76633a771b223ff49bd00267be122cedebb897037fdb527df72335d0d0f74724604ca70b37ad + languageName: node + linkType: hard + +"minimatch@npm:^9.0.3, minimatch@npm:^9.0.4": + version: 9.0.4 + resolution: "minimatch@npm:9.0.4" + dependencies: + brace-expansion: "npm:^2.0.1" + checksum: 4cdc18d112b164084513e890d6323370db14c22249d536ad1854539577a895e690a27513dc346392f61a4a50afbbd8abc88f3f25558bfbbbb862cd56508b20f5 + languageName: node + linkType: hard + +"minipass-collect@npm:^2.0.1": + version: 2.0.1 + resolution: "minipass-collect@npm:2.0.1" + dependencies: + minipass: "npm:^7.0.3" + checksum: b251bceea62090f67a6cced7a446a36f4cd61ee2d5cea9aee7fff79ba8030e416327a1c5aa2908dc22629d06214b46d88fdab8c51ac76bacbf5703851b5ad342 + languageName: node + linkType: hard + +"minipass-fetch@npm:^3.0.0": + version: 3.0.5 + resolution: "minipass-fetch@npm:3.0.5" + dependencies: + encoding: "npm:^0.1.13" + minipass: "npm:^7.0.3" + minipass-sized: "npm:^1.0.3" + minizlib: "npm:^2.1.2" + dependenciesMeta: + encoding: + optional: true + checksum: c669948bec1373313aaa8f104b962a3ced9f45c49b26366a4b0ae27ccdfa9c5740d72c8a84d3f8623d7a61c5fc7afdfda44789008c078f61a62441142efc4a97 + languageName: node + linkType: hard + +"minipass-flush@npm:^1.0.5": + version: 1.0.5 + resolution: "minipass-flush@npm:1.0.5" + dependencies: + minipass: "npm:^3.0.0" + checksum: 56269a0b22bad756a08a94b1ffc36b7c9c5de0735a4dd1ab2b06c066d795cfd1f0ac44a0fcae13eece5589b908ecddc867f04c745c7009be0b566421ea0944cf + languageName: node + linkType: hard + +"minipass-pipeline@npm:^1.2.4": + version: 1.2.4 + resolution: "minipass-pipeline@npm:1.2.4" + dependencies: + minipass: "npm:^3.0.0" + checksum: b14240dac0d29823c3d5911c286069e36d0b81173d7bdf07a7e4a91ecdef92cdff4baaf31ea3746f1c61e0957f652e641223970870e2353593f382112257971b + languageName: node + linkType: hard + +"minipass-sized@npm:^1.0.3": + version: 1.0.3 + resolution: "minipass-sized@npm:1.0.3" + dependencies: + minipass: "npm:^3.0.0" + checksum: 40982d8d836a52b0f37049a0a7e5d0f089637298e6d9b45df9c115d4f0520682a78258905e5c8b180fb41b593b0a82cc1361d2c74b45f7ada66334f84d1ecfdd + languageName: node + linkType: hard + +"minipass@npm:^3.0.0": + version: 3.3.6 + resolution: "minipass@npm:3.3.6" + dependencies: + yallist: "npm:^4.0.0" + checksum: a5c6ef069f70d9a524d3428af39f2b117ff8cd84172e19b754e7264a33df460873e6eb3d6e55758531580970de50ae950c496256bb4ad3691a2974cddff189f0 + languageName: node + linkType: hard + +"minipass@npm:^5.0.0": + version: 5.0.0 + resolution: "minipass@npm:5.0.0" + checksum: 61682162d29f45d3152b78b08bab7fb32ca10899bc5991ffe98afc18c9e9543bd1e3be94f8b8373ba6262497db63607079dc242ea62e43e7b2270837b7347c93 + languageName: node + linkType: hard + +"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.2, minipass@npm:^7.0.3, minipass@npm:^7.1.2": + version: 7.1.2 + resolution: "minipass@npm:7.1.2" + checksum: c25f0ee8196d8e6036661104bacd743785b2599a21de5c516b32b3fa2b83113ac89a2358465bc04956baab37ffb956ae43be679b2262bf7be15fce467ccd7950 + languageName: node + linkType: hard + +"minizlib@npm:^2.1.1, minizlib@npm:^2.1.2": + version: 2.1.2 + resolution: "minizlib@npm:2.1.2" + dependencies: + minipass: "npm:^3.0.0" + yallist: "npm:^4.0.0" + checksum: ae0f45436fb51344dcb87938446a32fbebb540d0e191d63b35e1c773d47512e17307bf54aa88326cc6d176594d00e4423563a091f7266c2f9a6872cdc1e234d1 + languageName: node + linkType: hard + +"mkdirp@npm:^1.0.3": + version: 1.0.4 + resolution: "mkdirp@npm:1.0.4" + bin: + mkdirp: bin/cmd.js + checksum: d71b8dcd4b5af2fe13ecf3bd24070263489404fe216488c5ba7e38ece1f54daf219e72a833a3a2dc404331e870e9f44963a33399589490956bff003a3404d3b2 + languageName: node + linkType: hard + +"ms@npm:2.1.2": + version: 2.1.2 + resolution: "ms@npm:2.1.2" + checksum: 673cdb2c3133eb050c745908d8ce632ed2c02d85640e2edb3ace856a2266a813b30c613569bf3354fdf4ea7d1a1494add3bfa95e2713baa27d0c2c71fc44f58f + languageName: node + linkType: hard + +"negotiator@npm:^0.6.3": + version: 0.6.3 + resolution: "negotiator@npm:0.6.3" + checksum: 2723fb822a17ad55c93a588a4bc44d53b22855bf4be5499916ca0cab1e7165409d0b288ba2577d7b029f10ce18cf2ed8e703e5af31c984e1e2304277ef979837 + languageName: node + linkType: hard + +"nice-napi@npm:^1.0.2": + version: 1.0.2 + resolution: "nice-napi@npm:1.0.2" + dependencies: + node-addon-api: "npm:^3.0.0" + node-gyp: "npm:latest" + node-gyp-build: "npm:^4.2.2" + conditions: "!os=win32" + languageName: node + linkType: hard + +"node-addon-api@npm:^3.0.0": + version: 3.2.1 + resolution: "node-addon-api@npm:3.2.1" + dependencies: + node-gyp: "npm:latest" + checksum: 681b52dfa3e15b0a8e5cf283cc0d8cd5fd2a57c559ae670fcfd20544cbb32f75de7648674110defcd17ab2c76ebef630aa7d2d2f930bc7a8cc439b20fe233518 + languageName: node + linkType: hard + +"node-gyp-build@npm:^4.2.2": + version: 4.8.1 + resolution: "node-gyp-build@npm:4.8.1" + bin: + node-gyp-build: bin.js + node-gyp-build-optional: optional.js + node-gyp-build-test: build-test.js + checksum: b9297770f96a92e5f2b854f3fd5e4bd418df81d7785a81ab60cec5cf2e5e72dc2c3319808978adc572cfa3885e6b12338cb5f4034bed2cab35f0d76a4b75ccdf + languageName: node + linkType: hard + +"node-gyp@npm:latest": + version: 10.1.0 + resolution: "node-gyp@npm:10.1.0" + dependencies: + env-paths: "npm:^2.2.0" + exponential-backoff: "npm:^3.1.1" + glob: "npm:^10.3.10" + graceful-fs: "npm:^4.2.6" + make-fetch-happen: "npm:^13.0.0" + nopt: "npm:^7.0.0" + proc-log: "npm:^3.0.0" + semver: "npm:^7.3.5" + tar: "npm:^6.1.2" + which: "npm:^4.0.0" + bin: + node-gyp: bin/node-gyp.js + checksum: 89e105e495e66cd4568af3cf79cdeb67d670eb069e33163c7781d3366470a30367c9bd8dea59e46db16370020139e5bf78b1fbc03284cb571754dfaa59744db5 + languageName: node + linkType: hard + +"nopt@npm:^7.0.0": + version: 7.2.1 + resolution: "nopt@npm:7.2.1" + dependencies: + abbrev: "npm:^2.0.0" + bin: + nopt: bin/nopt.js + checksum: 95a1f6dec8a81cd18cdc2fed93e6f0b4e02cf6bdb4501c848752c6e34f9883d9942f036a5e3b21a699047d8a448562d891e67492df68ec9c373e6198133337ae + languageName: node + linkType: hard + +"normalize-url@npm:^6.0.1": + version: 6.1.0 + resolution: "normalize-url@npm:6.1.0" + checksum: 5ae699402c9d5ffa330adc348fcd6fc6e6a155ab7c811b96e30b7ecab60ceef821d8f86443869671dda71bbc47f4b9625739c82ad247e883e9aefe875bfb8659 + languageName: node + linkType: hard + +"npm-run-path@npm:^2.0.0": + version: 2.0.2 + resolution: "npm-run-path@npm:2.0.2" + dependencies: + path-key: "npm:^2.0.0" + checksum: acd5ad81648ba4588ba5a8effb1d98d2b339d31be16826a118d50f182a134ac523172101b82eab1d01cb4c2ba358e857d54cfafd8163a1ffe7bd52100b741125 + languageName: node + linkType: hard + +"npm-run-path@npm:^4.0.1": + version: 4.0.1 + resolution: "npm-run-path@npm:4.0.1" + dependencies: + path-key: "npm:^3.0.0" + checksum: 5374c0cea4b0bbfdfae62da7bbdf1e1558d338335f4cacf2515c282ff358ff27b2ecb91ffa5330a8b14390ac66a1e146e10700440c1ab868208430f56b5f4d23 + languageName: node + linkType: hard + +"on-exit-leak-free@npm:^2.1.0": + version: 2.1.2 + resolution: "on-exit-leak-free@npm:2.1.2" + checksum: f7b4b7200026a08f6e4a17ba6d72e6c5cbb41789ed9cf7deaf9d9e322872c7dc5a7898549a894651ee0ee9ae635d34a678115bf8acdfba8ebd2ba2af688b563c + languageName: node + linkType: hard + +"once@npm:^1.3.1, once@npm:^1.4.0": + version: 1.4.0 + resolution: "once@npm:1.4.0" + dependencies: + wrappy: "npm:1" + checksum: cd0a88501333edd640d95f0d2700fbde6bff20b3d4d9bdc521bdd31af0656b5706570d6c6afe532045a20bb8dc0849f8332d6f2a416e0ba6d3d3b98806c7db68 + languageName: node + linkType: hard + +"onetime@npm:^5.1.2": + version: 5.1.2 + resolution: "onetime@npm:5.1.2" + dependencies: + mimic-fn: "npm:^2.1.0" + checksum: e9fd0695a01cf226652f0385bf16b7a24153dbbb2039f764c8ba6d2306a8506b0e4ce570de6ad99c7a6eb49520743afdb66edd95ee979c1a342554ed49a9aadd + languageName: node + linkType: hard + +"os-filter-obj@npm:^2.0.0": + version: 2.0.0 + resolution: "os-filter-obj@npm:2.0.0" + dependencies: + arch: "npm:^2.1.0" + checksum: 08808a109b2dba9be8686cc006e082a0f6595e6d87e2a30e4147cb1d22b62a30a6e5f4fd78226aee76d9158c84db3cea292adec02e6591452e93cb33bf5da877 + languageName: node + linkType: hard + +"p-cancelable@npm:^2.0.0": + version: 2.1.1 + resolution: "p-cancelable@npm:2.1.1" + checksum: 7f1b64db17fc54acf359167d62898115dcf2a64bf6b3b038e4faf36fc059e5ed762fb9624df8ed04b25bee8de3ab8d72dea9879a2a960cd12e23c420a4aca6ed + languageName: node + linkType: hard + +"p-finally@npm:^1.0.0": + version: 1.0.0 + resolution: "p-finally@npm:1.0.0" + checksum: 93a654c53dc805dd5b5891bab16eb0ea46db8f66c4bfd99336ae929323b1af2b70a8b0654f8f1eae924b2b73d037031366d645f1fd18b3d30cbd15950cc4b1d4 + languageName: node + linkType: hard + +"p-map@npm:^4.0.0": + version: 4.0.0 + resolution: "p-map@npm:4.0.0" + dependencies: + aggregate-error: "npm:^3.0.0" + checksum: 7ba4a2b1e24c05e1fc14bbaea0fc6d85cf005ae7e9c9425d4575550f37e2e584b1af97bcde78eacd7559208f20995988d52881334db16cf77bc1bcf68e48ed7c + languageName: node + linkType: hard + +"path-key@npm:^2.0.0": + version: 2.0.1 + resolution: "path-key@npm:2.0.1" + checksum: 6e654864e34386a2a8e6bf72cf664dcabb76574dd54013add770b374384d438aca95f4357bb26935b514a4e4c2c9b19e191f2200b282422a76ee038b9258c5e7 + languageName: node + linkType: hard + +"path-key@npm:^3.0.0, path-key@npm:^3.1.0": + version: 3.1.1 + resolution: "path-key@npm:3.1.1" + checksum: 55cd7a9dd4b343412a8386a743f9c746ef196e57c823d90ca3ab917f90ab9f13dd0ded27252ba49dbdfcab2b091d998bc446f6220cd3cea65db407502a740020 + languageName: node + linkType: hard + +"path-scurry@npm:^1.11.1": + version: 1.11.1 + resolution: "path-scurry@npm:1.11.1" + dependencies: + lru-cache: "npm:^10.2.0" + minipass: "npm:^5.0.0 || ^6.0.2 || ^7.0.0" + checksum: 5e8845c159261adda6f09814d7725683257fcc85a18f329880ab4d7cc1d12830967eae5d5894e453f341710d5484b8fdbbd4d75181b4d6e1eb2f4dc7aeadc434 + languageName: node + linkType: hard + +"peek-readable@npm:^5.0.0": + version: 5.0.0 + resolution: "peek-readable@npm:5.0.0" + checksum: d342f02dd0c8a6b4bd0e7519a93d545b2b19375200e79a7431f0f1ec3f91e22b2217fa3a15cde95f6ab388ce6fce8aae75794d84b9b39c5836eb7c5f55e7ee9e + languageName: node + linkType: hard + +"picomatch@npm:^2.3.1": + version: 2.3.1 + resolution: "picomatch@npm:2.3.1" + checksum: 60c2595003b05e4535394d1da94850f5372c9427ca4413b71210f437f7b2ca091dbd611c45e8b37d10036fa8eade25c1b8951654f9d3973bfa66a2ff4d3b08bc + languageName: node + linkType: hard + +"pify@npm:^2.2.0": + version: 2.3.0 + resolution: "pify@npm:2.3.0" + checksum: 9503aaeaf4577acc58642ad1d25c45c6d90288596238fb68f82811c08104c800e5a7870398e9f015d82b44ecbcbef3dc3d4251a1cbb582f6e5959fe09884b2ba + languageName: node + linkType: hard + +"pino-abstract-transport@npm:^1.2.0": + version: 1.2.0 + resolution: "pino-abstract-transport@npm:1.2.0" + dependencies: + readable-stream: "npm:^4.0.0" + split2: "npm:^4.0.0" + checksum: 6ec1d19a7ff3347fd21576f744c31c3e38ca4463ae638818408f43698c936f96be6a0bc750af5f7c1ae81873183bfcb062b7a0d12dc159a1813ea900c388c693 + languageName: node + linkType: hard + +"pino-std-serializers@npm:^7.0.0": + version: 7.0.0 + resolution: "pino-std-serializers@npm:7.0.0" + checksum: 884e08f65aa5463d820521ead3779d4472c78fc434d8582afb66f9dcb8d8c7119c69524b68106cb8caf92c0487be7794cf50e5b9c0383ae65b24bf2a03480951 + languageName: node + linkType: hard + +"pino@npm:^9.0.0": + version: 9.1.0 + resolution: "pino@npm:9.1.0" + dependencies: + atomic-sleep: "npm:^1.0.0" + fast-redact: "npm:^3.1.1" + on-exit-leak-free: "npm:^2.1.0" + pino-abstract-transport: "npm:^1.2.0" + pino-std-serializers: "npm:^7.0.0" + process-warning: "npm:^3.0.0" + quick-format-unescaped: "npm:^4.0.3" + real-require: "npm:^0.2.0" + safe-stable-stringify: "npm:^2.3.1" + sonic-boom: "npm:^4.0.1" + thread-stream: "npm:^3.0.0" + bin: + pino: bin.js + checksum: b7b0bdfdc2d9db017fa690e85f2e8ad2ddda09b1cbccb9868bc55d9a218ab3e9e4d75e6beb9d44fef10c4982d8719db4cf2325ea1f866d2fb37b7dff7f7297b1 + languageName: node + linkType: hard + +"piscina@npm:^4.3.0": + version: 4.5.1 + resolution: "piscina@npm:4.5.1" + dependencies: + nice-napi: "npm:^1.0.2" + dependenciesMeta: + nice-napi: + optional: true + checksum: a450140a3266920417844c11164bba208d4df2ddcb683bf3ee99d8d4b7db9de9751f5b83f6f5b2146391d18012d9f4af30a69ed751b9d4aa5eea1771a37df275 + languageName: node + linkType: hard + +"proc-log@npm:^3.0.0": + version: 3.0.0 + resolution: "proc-log@npm:3.0.0" + checksum: 02b64e1b3919e63df06f836b98d3af002b5cd92655cab18b5746e37374bfb73e03b84fe305454614b34c25b485cc687a9eebdccf0242cda8fda2475dd2c97e02 + languageName: node + linkType: hard + +"proc-log@npm:^4.2.0": + version: 4.2.0 + resolution: "proc-log@npm:4.2.0" + checksum: 4e1394491b717f6c1ade15c570ecd4c2b681698474d3ae2d303c1e4b6ab9455bd5a81566211e82890d5a5ae9859718cc6954d5150bb18b09b72ecb297beae90a + languageName: node + linkType: hard + +"process-warning@npm:^3.0.0": + version: 3.0.0 + resolution: "process-warning@npm:3.0.0" + checksum: 2d82fa641e50a5789eaf0f2b33453760996e373d4591aac576a22d696186ab7e240a0592db86c264d4f28a46c2abbe9b94689752017db7dadc90f169f12b0924 + languageName: node + linkType: hard + +"process@npm:^0.11.10": + version: 0.11.10 + resolution: "process@npm:0.11.10" + checksum: dbaa7e8d1d5cf375c36963ff43116772a989ef2bb47c9bdee20f38fd8fc061119cf38140631cf90c781aca4d3f0f0d2c834711952b728953f04fd7d238f59f5b + languageName: node + linkType: hard + +"promise-retry@npm:^2.0.1": + version: 2.0.1 + resolution: "promise-retry@npm:2.0.1" + dependencies: + err-code: "npm:^2.0.2" + retry: "npm:^0.12.0" + checksum: 96e1a82453c6c96eef53a37a1d6134c9f2482f94068f98a59145d0986ca4e497bf110a410adf73857e588165eab3899f0ebcf7b3890c1b3ce802abc0d65967d4 + languageName: node + linkType: hard + +"proxy-addr@npm:^2.0.7": + version: 2.0.7 + resolution: "proxy-addr@npm:2.0.7" + dependencies: + forwarded: "npm:0.2.0" + ipaddr.js: "npm:1.9.1" + checksum: f24a0c80af0e75d31e3451398670d73406ec642914da11a2965b80b1898ca6f66a0e3e091a11a4327079b2b268795f6fa06691923fef91887215c3d0e8ea3f68 + languageName: node + linkType: hard + +"pseudomap@npm:^1.0.2": + version: 1.0.2 + resolution: "pseudomap@npm:1.0.2" + checksum: 856c0aae0ff2ad60881168334448e898ad7a0e45fe7386d114b150084254c01e200c957cf378378025df4e052c7890c5bd933939b0e0d2ecfcc1dc2f0b2991f5 + languageName: node + linkType: hard + +"pump@npm:^3.0.0": + version: 3.0.0 + resolution: "pump@npm:3.0.0" + dependencies: + end-of-stream: "npm:^1.1.0" + once: "npm:^1.3.1" + checksum: e42e9229fba14732593a718b04cb5e1cfef8254544870997e0ecd9732b189a48e1256e4e5478148ecb47c8511dca2b09eae56b4d0aad8009e6fac8072923cfc9 + languageName: node + linkType: hard + +"punycode@npm:^2.1.0": + version: 2.3.1 + resolution: "punycode@npm:2.3.1" + checksum: febdc4362bead22f9e2608ff0171713230b57aff9dddc1c273aa2a651fbd366f94b7d6a71d78342a7c0819906750351ca7f2edd26ea41b626d87d6a13d1bd059 + languageName: node + linkType: hard + +"querystringify@npm:^2.1.1": + version: 2.2.0 + resolution: "querystringify@npm:2.2.0" + checksum: 46ab16f252fd892fc29d6af60966d338cdfeea68a231e9457631ffd22d67cec1e00141e0a5236a2eb16c0d7d74175d9ec1d6f963660c6f2b1c2fc85b194c5680 + languageName: node + linkType: hard + +"queue-microtask@npm:^1.2.2": + version: 1.2.3 + resolution: "queue-microtask@npm:1.2.3" + checksum: 72900df0616e473e824202113c3df6abae59150dfb73ed13273503127235320e9c8ca4aaaaccfd58cf417c6ca92a6e68ee9a5c3182886ae949a768639b388a7b + languageName: node + linkType: hard + +"quick-format-unescaped@npm:^4.0.3": + version: 4.0.4 + resolution: "quick-format-unescaped@npm:4.0.4" + checksum: 591eca457509a99368b623db05248c1193aa3cedafc9a077d7acab09495db1231017ba3ad1b5386e5633271edd0a03b312d8640a59ee585b8516a42e15438aa7 + languageName: node + linkType: hard + +"quick-lru@npm:^5.1.1": + version: 5.1.1 + resolution: "quick-lru@npm:5.1.1" + checksum: a516faa25574be7947969883e6068dbe4aa19e8ef8e8e0fd96cddd6d36485e9106d85c0041a27153286b0770b381328f4072aa40d3b18a19f5f7d2b78b94b5ed + languageName: node + linkType: hard + +"readable-stream@npm:1.x >=1.1.9": + version: 1.1.14 + resolution: "readable-stream@npm:1.1.14" + dependencies: + core-util-is: "npm:~1.0.0" + inherits: "npm:~2.0.1" + isarray: "npm:0.0.1" + string_decoder: "npm:~0.10.x" + checksum: 1aa2cf4bd02f9ab3e1d57842a43a413b52be5300aa089ad1f2e3cea00684532d73edc6a2ba52b0c3210d8b57eb20a695a6d2b96d1c6085ee979c6021ad48ad20 + languageName: node + linkType: hard + +"readable-stream@npm:^3.6.0": + version: 3.6.2 + resolution: "readable-stream@npm:3.6.2" + dependencies: + inherits: "npm:^2.0.3" + string_decoder: "npm:^1.1.1" + util-deprecate: "npm:^1.0.1" + checksum: d9e3e53193adcdb79d8f10f2a1f6989bd4389f5936c6f8b870e77570853561c362bee69feca2bbb7b32368ce96a85504aa4cedf7cf80f36e6a9de30d64244048 + languageName: node + linkType: hard + +"readable-stream@npm:^4.0.0": + version: 4.5.2 + resolution: "readable-stream@npm:4.5.2" + dependencies: + abort-controller: "npm:^3.0.0" + buffer: "npm:^6.0.3" + events: "npm:^3.3.0" + process: "npm:^0.11.10" + string_decoder: "npm:^1.3.0" + checksum: 01b128a559c5fd76a898495f858cf0a8839f135e6a69e3409f986e88460134791657eb46a2ff16826f331682a3c4d0c5a75cef5e52ef259711021ba52b1c2e82 + languageName: node + linkType: hard + +"readable-web-to-node-stream@npm:^3.0.2": + version: 3.0.2 + resolution: "readable-web-to-node-stream@npm:3.0.2" + dependencies: + readable-stream: "npm:^3.6.0" + checksum: d3a5bf9d707c01183d546a64864aa63df4d9cb835dfd2bf89ac8305e17389feef2170c4c14415a10d38f9b9bfddf829a57aaef7c53c8b40f11d499844bf8f1a4 + languageName: node + linkType: hard + +"real-require@npm:^0.2.0": + version: 0.2.0 + resolution: "real-require@npm:0.2.0" + checksum: ddf44ee76301c774e9c9f2826da8a3c5c9f8fc87310f4a364e803ef003aa1a43c378b4323051ced212097fff1af459070f4499338b36a7469df1d4f7e8c0ba4c + languageName: node + linkType: hard + +"require-from-string@npm:^2.0.2": + version: 2.0.2 + resolution: "require-from-string@npm:2.0.2" + checksum: 839a3a890102a658f4cb3e7b2aa13a1f80a3a976b512020c3d1efc418491c48a886b6e481ea56afc6c4cb5eef678f23b2a4e70575e7534eccadf5e30ed2e56eb + languageName: node + linkType: hard + +"requires-port@npm:^1.0.0": + version: 1.0.0 + resolution: "requires-port@npm:1.0.0" + checksum: 878880ee78ccdce372784f62f52a272048e2d0827c29ae31e7f99da18b62a2b9463ea03a75f277352f4697c100183debb0532371ad515a2d49d4bfe596dd4c20 + languageName: node + linkType: hard + +"resolve-alpn@npm:^1.0.0": + version: 1.2.1 + resolution: "resolve-alpn@npm:1.2.1" + checksum: 744e87888f0b6fa0b256ab454ca0b9c0b80808715e2ef1f3672773665c92a941f6181194e30ccae4a8cd0adbe0d955d3f133102636d2ee0cca0119fec0bc9aec + languageName: node + linkType: hard + +"responselike@npm:^2.0.0": + version: 2.0.1 + resolution: "responselike@npm:2.0.1" + dependencies: + lowercase-keys: "npm:^2.0.0" + checksum: b122535466e9c97b55e69c7f18e2be0ce3823c5d47ee8de0d9c0b114aa55741c6db8bfbfce3766a94d1272e61bfb1ebf0a15e9310ac5629fbb7446a861b4fd3a + languageName: node + linkType: hard + +"ret@npm:~0.4.0": + version: 0.4.3 + resolution: "ret@npm:0.4.3" + checksum: d6a00f0920400b78b6aa96ce1c953d2f783f4fd5d56b5e842a744c40e33545e7955fb132386ada406361881353292fe7282f4e6e82b2c1e61f6c96a6ea4bb2d7 + languageName: node + linkType: hard + +"retry@npm:^0.12.0": + version: 0.12.0 + resolution: "retry@npm:0.12.0" + checksum: 1f914879f97e7ee931ad05fe3afa629bd55270fc6cf1c1e589b6a99fab96d15daad0fa1a52a00c729ec0078045fe3e399bd4fd0c93bcc906957bdc17f89cb8e6 + languageName: node + linkType: hard + +"reusify@npm:^1.0.4": + version: 1.0.4 + resolution: "reusify@npm:1.0.4" + checksum: 14222c9e1d3f9ae01480c50d96057228a8524706db79cdeb5a2ce5bb7070dd9f409a6f84a02cbef8cdc80d39aef86f2dd03d155188a1300c599b05437dcd2ffb + languageName: node + linkType: hard + +"rfdc@npm:^1.2.0, rfdc@npm:^1.3.0": + version: 1.3.1 + resolution: "rfdc@npm:1.3.1" + checksum: 44cc6a82e2fe1db13b7d3c54e9ffd0b40ef070cbde69ffbfbb38dab8cee46bd68ba686784b96365ff08d04798bc121c3465663a0c91f2c421c90546c4366f4a6 + languageName: node + linkType: hard + +"run-parallel@npm:^1.1.9": + version: 1.2.0 + resolution: "run-parallel@npm:1.2.0" + dependencies: + queue-microtask: "npm:^1.2.2" + checksum: cb4f97ad25a75ebc11a8ef4e33bb962f8af8516bb2001082ceabd8902e15b98f4b84b4f8a9b222e5d57fc3bd1379c483886ed4619367a7680dad65316993021d + languageName: node + linkType: hard + +"safe-buffer@npm:5.2.1, safe-buffer@npm:~5.2.0": + version: 5.2.1 + resolution: "safe-buffer@npm:5.2.1" + checksum: 32872cd0ff68a3ddade7a7617b8f4c2ae8764d8b7d884c651b74457967a9e0e886267d3ecc781220629c44a865167b61c375d2da6c720c840ecd73f45d5d9451 + languageName: node + linkType: hard + +"safe-buffer@npm:~5.1.2": + version: 5.1.2 + resolution: "safe-buffer@npm:5.1.2" + checksum: 7eb5b48f2ed9a594a4795677d5a150faa7eb54483b2318b568dc0c4fc94092a6cce5be02c7288a0500a156282f5276d5688bce7259299568d1053b2150ef374a + languageName: node + linkType: hard + +"safe-regex2@npm:^3.1.0": + version: 3.1.0 + resolution: "safe-regex2@npm:3.1.0" + dependencies: + ret: "npm:~0.4.0" + checksum: 4f9f7172662763619052a45599e515efc5dd10a932690f610c8ab808a4baa41be3feafefa444f7532651d721d12871a1c9a85330626cdd013b804e8f4240dff1 + languageName: node + linkType: hard + +"safe-stable-stringify@npm:^2.3.1": + version: 2.4.3 + resolution: "safe-stable-stringify@npm:2.4.3" + checksum: a6c192bbefe47770a11072b51b500ed29be7b1c15095371c1ee1dc13e45ce48ee3c80330214c56764d006c485b88bd0b24940d868948170dddc16eed312582d8 + languageName: node + linkType: hard + +"safer-buffer@npm:>= 2.1.2 < 3.0.0": + version: 2.1.2 + resolution: "safer-buffer@npm:2.1.2" + checksum: 7eaf7a0cf37cc27b42fb3ef6a9b1df6e93a1c6d98c6c6702b02fe262d5fcbd89db63320793b99b21cb5348097d0a53de81bd5f4e8b86e20cc9412e3f1cfb4e83 + languageName: node + linkType: hard + +"secure-json-parse@npm:^2.4.0, secure-json-parse@npm:^2.7.0": + version: 2.7.0 + resolution: "secure-json-parse@npm:2.7.0" + checksum: 974386587060b6fc5b1ac06481b2f9dbbb0d63c860cc73dc7533f27835fdb67b0ef08762dbfef25625c15bc0a0c366899e00076cb0d556af06b71e22f1dede4c + languageName: node + linkType: hard + +"semver-regex@npm:^4.0.5": + version: 4.0.5 + resolution: "semver-regex@npm:4.0.5" + checksum: b9e5c0573c4a997fb7e6e76321385d254797e86c8dba5e23f3cd8cf8f40b40414097a51514e5fead61dcb88ff10d3676355c01e2040f3c68f6c24bfd2073da2e + languageName: node + linkType: hard + +"semver-truncate@npm:^3.0.0": + version: 3.0.0 + resolution: "semver-truncate@npm:3.0.0" + dependencies: + semver: "npm:^7.3.5" + checksum: d8c23812218ff147f512ac4830e86860a377dba8a9733ae97d816102aca33236fa1c44c06544727153fffb93d15d0e45c49b2c40a7964aa3671769e9aed2f3f9 + languageName: node + linkType: hard + +"semver@npm:^7.3.5, semver@npm:^7.3.8, semver@npm:^7.5.3, semver@npm:^7.5.4": + version: 7.6.2 + resolution: "semver@npm:7.6.2" + bin: + semver: bin/semver.js + checksum: 296b17d027f57a87ef645e9c725bff4865a38dfc9caf29b26aa084b85820972fbe7372caea1ba6857162fa990702c6d9c1d82297cecb72d56c78ab29070d2ca2 + languageName: node + linkType: hard + +"set-cookie-parser@npm:^2.4.1": + version: 2.6.0 + resolution: "set-cookie-parser@npm:2.6.0" + checksum: 8d451ebadb760989f93b634942c79de3c925ca7a986d133d08a80c40b5ae713ce12e354f0d5245c49f288c52daa7bd6554d5dc52f8a4eecaaf5e192881cf2b1f + languageName: node + linkType: hard + +"shebang-command@npm:^1.2.0": + version: 1.2.0 + resolution: "shebang-command@npm:1.2.0" + dependencies: + shebang-regex: "npm:^1.0.0" + checksum: 9eed1750301e622961ba5d588af2212505e96770ec376a37ab678f965795e995ade7ed44910f5d3d3cb5e10165a1847f52d3348c64e146b8be922f7707958908 + languageName: node + linkType: hard + +"shebang-command@npm:^2.0.0": + version: 2.0.0 + resolution: "shebang-command@npm:2.0.0" + dependencies: + shebang-regex: "npm:^3.0.0" + checksum: 6b52fe87271c12968f6a054e60f6bde5f0f3d2db483a1e5c3e12d657c488a15474121a1d55cd958f6df026a54374ec38a4a963988c213b7570e1d51575cea7fa + languageName: node + linkType: hard + +"shebang-regex@npm:^1.0.0": + version: 1.0.0 + resolution: "shebang-regex@npm:1.0.0" + checksum: 404c5a752cd40f94591dfd9346da40a735a05139dac890ffc229afba610854d8799aaa52f87f7e0c94c5007f2c6af55bdcaeb584b56691926c5eaf41dc8f1372 + languageName: node + linkType: hard + +"shebang-regex@npm:^3.0.0": + version: 3.0.0 + resolution: "shebang-regex@npm:3.0.0" + checksum: 1a2bcae50de99034fcd92ad4212d8e01eedf52c7ec7830eedcf886622804fe36884278f2be8be0ea5fde3fd1c23911643a4e0f726c8685b61871c8908af01222 + languageName: node + linkType: hard + +"signal-exit@npm:^3.0.0, signal-exit@npm:^3.0.3": + version: 3.0.7 + resolution: "signal-exit@npm:3.0.7" + checksum: a2f098f247adc367dffc27845853e9959b9e88b01cb301658cfe4194352d8d2bb32e18467c786a7fe15f1d44b233ea35633d076d5e737870b7139949d1ab6318 + languageName: node + linkType: hard + +"signal-exit@npm:^4.0.1": + version: 4.1.0 + resolution: "signal-exit@npm:4.1.0" + checksum: c9fa63bbbd7431066174a48ba2dd9986dfd930c3a8b59de9c29d7b6854ec1c12a80d15310869ea5166d413b99f041bfa3dd80a7947bcd44ea8e6eb3ffeabfa1f + languageName: node + linkType: hard + +"slash@npm:3.0.0": + version: 3.0.0 + resolution: "slash@npm:3.0.0" + checksum: 94a93fff615f25a999ad4b83c9d5e257a7280c90a32a7cb8b4a87996e4babf322e469c42b7f649fd5796edd8687652f3fb452a86dc97a816f01113183393f11c + languageName: node + linkType: hard + +"smart-buffer@npm:^4.2.0": + version: 4.2.0 + resolution: "smart-buffer@npm:4.2.0" + checksum: 927484aa0b1640fd9473cee3e0a0bcad6fce93fd7bbc18bac9ad0c33686f5d2e2c422fba24b5899c184524af01e11dd2bd051c2bf2b07e47aff8ca72cbfc60d2 + languageName: node + linkType: hard + +"socks-proxy-agent@npm:^8.0.3": + version: 8.0.3 + resolution: "socks-proxy-agent@npm:8.0.3" + dependencies: + agent-base: "npm:^7.1.1" + debug: "npm:^4.3.4" + socks: "npm:^2.7.1" + checksum: c2112c66d6322e497d68e913c3780f3683237fd394bfd480b9283486a86e36095d0020db96145d88f8ccd9cc73261b98165b461f9c1bf5dc17abfe75c18029ce + languageName: node + linkType: hard + +"socks@npm:^2.7.1": + version: 2.8.3 + resolution: "socks@npm:2.8.3" + dependencies: + ip-address: "npm:^9.0.5" + smart-buffer: "npm:^4.2.0" + checksum: ffcb622c22481dfcd7589aae71fbfd71ca34334064d181df64bf8b7feaeee19706aba4cffd1de35cc7bbaeeaa0af96be2d7f40fcbc7bc0ab69533a7ae9ffc4fb + languageName: node + linkType: hard + +"sonic-boom@npm:^4.0.1": + version: 4.0.1 + resolution: "sonic-boom@npm:4.0.1" + dependencies: + atomic-sleep: "npm:^1.0.0" + checksum: 449bdc39f4333a321bb754319e9452c3e94409654b2ddf8e40307a1a413b953bed3b3b092a4992ab3fb7cd1a7c95bdde5a046ac4e0405d7c92c60802452c060c + languageName: node + linkType: hard + +"sort-keys-length@npm:^1.0.0": + version: 1.0.1 + resolution: "sort-keys-length@npm:1.0.1" + dependencies: + sort-keys: "npm:^1.0.0" + checksum: f9acac5fb31580a9e3d43b419dc86a1b75e85b79036a084d95dd4d1062b621c9589906588ac31e370a0dd381be46d8dbe900efa306d087ca9c912d7a59b5a590 + languageName: node + linkType: hard + +"sort-keys@npm:^1.0.0": + version: 1.1.2 + resolution: "sort-keys@npm:1.1.2" + dependencies: + is-plain-obj: "npm:^1.0.0" + checksum: 0ac2ea2327d92252f07aa7b2f8c7023a1f6ce3306439a3e81638cce9905893c069521d168f530fb316d1a929bdb052b742969a378190afaef1bc64fa69e29576 + languageName: node + linkType: hard + +"source-map@npm:^0.7.3": + version: 0.7.4 + resolution: "source-map@npm:0.7.4" + checksum: a0f7c9b797eda93139842fd28648e868a9a03ea0ad0d9fa6602a0c1f17b7fb6a7dcca00c144476cccaeaae5042e99a285723b1a201e844ad67221bf5d428f1dc + languageName: node + linkType: hard + +"split2@npm:^4.0.0": + version: 4.2.0 + resolution: "split2@npm:4.2.0" + checksum: 09bbefc11bcf03f044584c9764cd31a252d8e52cea29130950b26161287c11f519807c5e54bd9e5804c713b79c02cefe6a98f4688630993386be353e03f534ab + languageName: node + linkType: hard + +"sprintf-js@npm:^1.1.3": + version: 1.1.3 + resolution: "sprintf-js@npm:1.1.3" + checksum: e7587128c423f7e43cc625fe2f87e6affdf5ca51c1cc468e910d8aaca46bb44a7fbcfa552f787b1d3987f7043aeb4527d1b99559e6621e01b42b3f45e5a24cbb + languageName: node + linkType: hard + +"ssri@npm:^10.0.0": + version: 10.0.6 + resolution: "ssri@npm:10.0.6" + dependencies: + minipass: "npm:^7.0.3" + checksum: f92c1b3cc9bfd0a925417412d07d999935917bc87049f43ebec41074661d64cf720315661844106a77da9f8204b6d55ae29f9514e673083cae39464343af2a8b + languageName: node + linkType: hard + +"stream-wormhole@npm:^1.1.0": + version: 1.1.0 + resolution: "stream-wormhole@npm:1.1.0" + checksum: cc19e0235c5d031bd530fa83913c807d9525fa4ba33d51691dd822c0726b8b7ef138b34f289d063a3018cddba67d3ba7fd0ecedaa97242a0f1ed2eed3c6a2ab1 + languageName: node + linkType: hard + +"string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^4.1.0": + version: 4.2.3 + resolution: "string-width@npm:4.2.3" + dependencies: + emoji-regex: "npm:^8.0.0" + is-fullwidth-code-point: "npm:^3.0.0" + strip-ansi: "npm:^6.0.1" + checksum: e52c10dc3fbfcd6c3a15f159f54a90024241d0f149cf8aed2982a2d801d2e64df0bf1dc351cf8e95c3319323f9f220c16e740b06faecd53e2462df1d2b5443fb + languageName: node + linkType: hard + +"string-width@npm:^5.0.1, string-width@npm:^5.1.2": + version: 5.1.2 + resolution: "string-width@npm:5.1.2" + dependencies: + eastasianwidth: "npm:^0.2.0" + emoji-regex: "npm:^9.2.2" + strip-ansi: "npm:^7.0.1" + checksum: 7369deaa29f21dda9a438686154b62c2c5f661f8dda60449088f9f980196f7908fc39fdd1803e3e01541970287cf5deae336798337e9319a7055af89dafa7193 + languageName: node + linkType: hard + +"string_decoder@npm:^1.1.1, string_decoder@npm:^1.3.0": + version: 1.3.0 + resolution: "string_decoder@npm:1.3.0" + dependencies: + safe-buffer: "npm:~5.2.0" + checksum: 54d23f4a6acae0e93f999a585e673be9e561b65cd4cca37714af1e893ab8cd8dfa52a9e4f58f48f87b4a44918d3a9254326cb80ed194bf2e4c226e2b21767e56 + languageName: node + linkType: hard + +"string_decoder@npm:~0.10.x": + version: 0.10.31 + resolution: "string_decoder@npm:0.10.31" + checksum: cc43e6b1340d4c7843da0e37d4c87a4084c2342fc99dcf6563c3ec273bb082f0cbd4ebf25d5da19b04fb16400d393885fda830be5128e1c416c73b5a6165f175 + languageName: node + linkType: hard + +"strip-ansi-cjs@npm:strip-ansi@^6.0.1, strip-ansi@npm:^6.0.0, strip-ansi@npm:^6.0.1": + version: 6.0.1 + resolution: "strip-ansi@npm:6.0.1" + dependencies: + ansi-regex: "npm:^5.0.1" + checksum: ae3b5436d34fadeb6096367626ce987057713c566e1e7768818797e00ac5d62023d0f198c4e681eae9e20701721980b26a64a8f5b91238869592a9c6800719a2 + languageName: node + linkType: hard + +"strip-ansi@npm:^7.0.1": + version: 7.1.0 + resolution: "strip-ansi@npm:7.1.0" + dependencies: + ansi-regex: "npm:^6.0.1" + checksum: 475f53e9c44375d6e72807284024ac5d668ee1d06010740dec0b9744f2ddf47de8d7151f80e5f6190fc8f384e802fdf9504b76a7e9020c9faee7103623338be2 + languageName: node + linkType: hard + +"strip-eof@npm:^1.0.0": + version: 1.0.0 + resolution: "strip-eof@npm:1.0.0" + checksum: 40bc8ddd7e072f8ba0c2d6d05267b4e0a4800898c3435b5fb5f5a21e6e47dfaff18467e7aa0d1844bb5d6274c3097246595841fbfeb317e541974ee992cac506 + languageName: node + linkType: hard + +"strip-final-newline@npm:^2.0.0": + version: 2.0.0 + resolution: "strip-final-newline@npm:2.0.0" + checksum: 69412b5e25731e1938184b5d489c32e340605bb611d6140344abc3421b7f3c6f9984b21dff296dfcf056681b82caa3bb4cc996a965ce37bcfad663e92eae9c64 + languageName: node + linkType: hard + +"strip-outer@npm:^2.0.0": + version: 2.0.0 + resolution: "strip-outer@npm:2.0.0" + checksum: 14ef9fe861e59a5f1555f1860982ae4edce2edb4ed34ab1b37cb62a8ba2f7c3540cbca6c884eabe4006e6cd729ab5d708a631169dd5b66fda570836e7e3b6589 + languageName: node + linkType: hard + +"strtok3@npm:^7.0.0-alpha.9": + version: 7.0.0 + resolution: "strtok3@npm:7.0.0" + dependencies: + "@tokenizer/token": "npm:^0.3.0" + peek-readable: "npm:^5.0.0" + checksum: 4f2269679fcfce1e9fe0600eff361ea4c687ae0a0e8d9dab6703811071cd92545cbcb32d4ace3d3aa591f777cec1a3e8aeecd5efd71ae216fd2962a7a238b4ab + languageName: node + linkType: hard + +"tar@npm:^6.1.11, tar@npm:^6.1.2": + version: 6.2.1 + resolution: "tar@npm:6.2.1" + dependencies: + chownr: "npm:^2.0.0" + fs-minipass: "npm:^2.0.0" + minipass: "npm:^5.0.0" + minizlib: "npm:^2.1.1" + mkdirp: "npm:^1.0.3" + yallist: "npm:^4.0.0" + checksum: bfbfbb2861888077fc1130b84029cdc2721efb93d1d1fb80f22a7ac3a98ec6f8972f29e564103bbebf5e97be67ebc356d37fa48dbc4960600a1eb7230fbd1ea0 + languageName: node + linkType: hard + +"thread-stream@npm:^3.0.0": + version: 3.0.2 + resolution: "thread-stream@npm:3.0.2" + dependencies: + real-require: "npm:^0.2.0" + checksum: 988aa87a2f4102d0160ccc76b764d219c6bb44b3f723ffda608d44016323f9066c563e663ff2e80be417fe81d15203f5c340b2284adf8bfb7e56554349fe2dab + languageName: node + linkType: hard + +"to-regex-range@npm:^5.0.1": + version: 5.0.1 + resolution: "to-regex-range@npm:5.0.1" + dependencies: + is-number: "npm:^7.0.0" + checksum: 10dda13571e1f5ad37546827e9b6d4252d2e0bc176c24a101252153ef435d83696e2557fe128c4678e4e78f5f01e83711c703eef9814eb12dab028580d45980a + languageName: node + linkType: hard + +"toad-cache@npm:^3.3.0": + version: 3.7.0 + resolution: "toad-cache@npm:3.7.0" + checksum: cdc62aacc047e94eab21697943e117bbb1938168a03e5e85fdba28ab6ea66f4796ff16b219019a64d2115048378f9dd1f4e62c78c1f1d4961d0b3d23f9a9374d + languageName: node + linkType: hard + +"token-types@npm:^5.0.0-alpha.2": + version: 5.0.1 + resolution: "token-types@npm:5.0.1" + dependencies: + "@tokenizer/token": "npm:^0.3.0" + ieee754: "npm:^1.2.1" + checksum: 0985369bbea9f53a5ccd79bb9899717b41401a813deb2c7fb1add5d0baf2f702aaf6da78f6e0ccf346d5a9f7acaa7cb5efed7d092d89d8c1e6962959e9509bc0 + languageName: node + linkType: hard + +"trim-repeated@npm:^2.0.0": + version: 2.0.0 + resolution: "trim-repeated@npm:2.0.0" + dependencies: + escape-string-regexp: "npm:^5.0.0" + checksum: 4086eb0bc560f3da0370f427f423db4e3fc0a8e1560ecffc3b68512071319fe82dc9dd86d76b981d36ada76d7d49c3f8897ac054c87bc177e7a25abfd29e2bcd + languageName: node + linkType: hard + +"tweetnacl@npm:^1.0.3": + version: 1.0.3 + resolution: "tweetnacl@npm:1.0.3" + checksum: ca122c2f86631f3c0f6d28efb44af2a301d4a557a62a3e2460286b08e97567b258c2212e4ad1cfa22bd6a57edcdc54ba76ebe946847450ab0999e6d48ccae332 + languageName: node + linkType: hard + +"typescript@npm:^5.5.2": + version: 5.5.2 + resolution: "typescript@npm:5.5.2" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 9118b20f248e76b0dbff8737fef65dfa89d02668d4e633d2c5ceac99033a0ca5e8a1c1a53bc94da68e8f67677a88f318663dde859c9e9a09c1e116415daec2ba + languageName: node + linkType: hard + +"typescript@patch:typescript@npm%3A^5.5.2#optional!builtin": + version: 5.5.2 + resolution: "typescript@patch:typescript@npm%3A5.5.2#optional!builtin::version=5.5.2&hash=e012d7" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 28b3de2ddaf63a7620e7ddbe5d377af71ce93ecc558c41bf0e3d88661d8e6e7aa6c7739164fef98055f69819e41faca49252938ef3633a3dff2734cca6a9042e + languageName: node + linkType: hard + +"undici-types@npm:~5.26.4": + version: 5.26.5 + resolution: "undici-types@npm:5.26.5" + checksum: 0097779d94bc0fd26f0418b3a05472410408877279141ded2bd449167be1aed7ea5b76f756562cb3586a07f251b90799bab22d9019ceba49c037c76445f7cddd + languageName: node + linkType: hard + +"unique-filename@npm:^3.0.0": + version: 3.0.0 + resolution: "unique-filename@npm:3.0.0" + dependencies: + unique-slug: "npm:^4.0.0" + checksum: 8e2f59b356cb2e54aab14ff98a51ac6c45781d15ceaab6d4f1c2228b780193dc70fae4463ce9e1df4479cb9d3304d7c2043a3fb905bdeca71cc7e8ce27e063df + languageName: node + linkType: hard + +"unique-slug@npm:^4.0.0": + version: 4.0.0 + resolution: "unique-slug@npm:4.0.0" + dependencies: + imurmurhash: "npm:^0.1.4" + checksum: 40912a8963fc02fb8b600cf50197df4a275c602c60de4cac4f75879d3c48558cfac48de08a25cc10df8112161f7180b3bbb4d662aadb711568602f9eddee54f0 + languageName: node + linkType: hard + +"uri-js@npm:^4.4.1": + version: 4.4.1 + resolution: "uri-js@npm:4.4.1" + dependencies: + punycode: "npm:^2.1.0" + checksum: b271ca7e3d46b7160222e3afa3e531505161c9a4e097febae9664e4b59912f4cbe94861361a4175edac3a03fee99d91e44b6a58c17a634bc5a664b19fc76fbcb + languageName: node + linkType: hard + +"url-parse@npm:~1.5.10": + version: 1.5.10 + resolution: "url-parse@npm:1.5.10" + dependencies: + querystringify: "npm:^2.1.1" + requires-port: "npm:^1.0.0" + checksum: c9e96bc8c5b34e9f05ddfeffc12f6aadecbb0d971b3cc26015b58d5b44676a99f50d5aeb1e5c9e61fa4d49961ae3ab1ae997369ed44da51b2f5ac010d188e6ad + languageName: node + linkType: hard + +"util-deprecate@npm:^1.0.1": + version: 1.0.2 + resolution: "util-deprecate@npm:1.0.2" + checksum: 474acf1146cb2701fe3b074892217553dfcf9a031280919ba1b8d651a068c9b15d863b7303cb15bd00a862b498e6cf4ad7b4a08fb134edd5a6f7641681cb54a2 + languageName: node + linkType: hard + +"which@npm:^1.2.9": + version: 1.3.1 + resolution: "which@npm:1.3.1" + dependencies: + isexe: "npm:^2.0.0" + bin: + which: ./bin/which + checksum: 549dcf1752f3ee7fbb64f5af2eead4b9a2f482108b7de3e85c781d6c26d8cf6a52d37cfbe0642a155fa6470483fe892661a859c03157f24c669cf115f3bbab5e + languageName: node + linkType: hard + +"which@npm:^2.0.1": + version: 2.0.2 + resolution: "which@npm:2.0.2" + dependencies: + isexe: "npm:^2.0.0" + bin: + node-which: ./bin/node-which + checksum: 4782f8a1d6b8fc12c65e968fea49f59752bf6302dc43036c3bf87da718a80710f61a062516e9764c70008b487929a73546125570acea95c5b5dcc8ac3052c70f + languageName: node + linkType: hard + +"which@npm:^4.0.0": + version: 4.0.0 + resolution: "which@npm:4.0.0" + dependencies: + isexe: "npm:^3.1.1" + bin: + node-which: bin/which.js + checksum: f17e84c042592c21e23c8195108cff18c64050b9efb8459589116999ea9da6dd1509e6a1bac3aeebefd137be00fabbb61b5c2bc0aa0f8526f32b58ee2f545651 + languageName: node + linkType: hard + +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": + version: 7.0.0 + resolution: "wrap-ansi@npm:7.0.0" + dependencies: + ansi-styles: "npm:^4.0.0" + string-width: "npm:^4.1.0" + strip-ansi: "npm:^6.0.0" + checksum: cebdaeca3a6880da410f75209e68cd05428580de5ad24535f22696d7d9cab134d1f8498599f344c3cf0fb37c1715807a183778d8c648d6cc0cb5ff2bb4236540 + languageName: node + linkType: hard + +"wrap-ansi@npm:^8.1.0": + version: 8.1.0 + resolution: "wrap-ansi@npm:8.1.0" + dependencies: + ansi-styles: "npm:^6.1.0" + string-width: "npm:^5.0.1" + strip-ansi: "npm:^7.0.1" + checksum: 7b1e4b35e9bb2312d2ee9ee7dc95b8cb5f8b4b5a89f7dde5543fe66c1e3715663094defa50d75454ac900bd210f702d575f15f3f17fa9ec0291806d2578d1ddf + languageName: node + linkType: hard + +"wrappy@npm:1": + version: 1.0.2 + resolution: "wrappy@npm:1.0.2" + checksum: 159da4805f7e84a3d003d8841557196034155008f817172d4e986bd591f74aa82aa7db55929a54222309e01079a65a92a9e6414da5a6aa4b01ee44a511ac3ee5 + languageName: node + linkType: hard + +"ws@npm:^8.16.0": + version: 8.17.1 + resolution: "ws@npm:8.17.1" + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ">=5.0.2" + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: 4264ae92c0b3e59c7e309001e93079b26937aab181835fb7af79f906b22cd33b6196d96556dafb4e985742dd401e99139572242e9847661fdbc96556b9e6902d + languageName: node + linkType: hard + +"yallist@npm:^2.1.2": + version: 2.1.2 + resolution: "yallist@npm:2.1.2" + checksum: 75fc7bee4821f52d1c6e6021b91b3e079276f1a9ce0ad58da3c76b79a7e47d6f276d35e206a96ac16c1cf48daee38a8bb3af0b1522a3d11c8ffe18f898828832 + languageName: node + linkType: hard + +"yallist@npm:^4.0.0": + version: 4.0.0 + resolution: "yallist@npm:4.0.0" + checksum: 4cb02b42b8a93b5cf50caf5d8e9beb409400a8a4d85e83bb0685c1457e9ac0b7a00819e9f5991ac25ffabb56a78e2f017c1acc010b3a1babfe6de690ba531abd + languageName: node + linkType: hard diff --git a/examples/deno.json b/examples/deno.json deleted file mode 100644 index b8feb70b5..000000000 --- a/examples/deno.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "lint": { - "rules": { - "tags": ["recommended"], - "include": ["ban-untagged-todo"], - "exclude": ["no-unused-vars"] - } - }, - "fmt": { - "options": { - "useTabs": false, - "lineWidth": 120, - "indentWidth": 2, - "singleQuote": false, - "proseWrap": "preserve" - } - } -} diff --git a/examples/minimal/.env.example b/examples/minimal/.env.example index a5b93e7f6..7acf6fd79 100644 --- a/examples/minimal/.env.example +++ b/examples/minimal/.env.example @@ -1 +1,2 @@ -BOT_TOKEN='' \ No newline at end of file +BOT_TOKEN='' +DEV_GUILD_ID='' \ No newline at end of file diff --git a/examples/minimal/.gitignore b/examples/minimal/.gitignore new file mode 100644 index 000000000..4bc2fcfaf --- /dev/null +++ b/examples/minimal/.gitignore @@ -0,0 +1,32 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +node_modules + +.pnp.* +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/sdks +!.yarn/versions + +# build +dist + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.pnpm-debug.log* + +# local env files +.env +.env.local +.env.development.local +.env.test.local +.env.production.local diff --git a/examples/minimal/.swcrc b/examples/minimal/.swcrc new file mode 100644 index 000000000..751b8edf8 --- /dev/null +++ b/examples/minimal/.swcrc @@ -0,0 +1,24 @@ +{ + "$schema": "https://json.schemastore.org/swcrc", + "jsc": { + "parser": { + "syntax": "typescript", + "decorators": true, + "dynamicImport": true + }, + "transform": { + "legacyDecorator": true, + "decoratorMetadata": true + }, + "target": "es2022", + "keepClassNames": true, + "loose": true + }, + "module": { + "type": "es6", + "strict": false, + "strictMode": true, + "lazy": false, + "noInterop": false + } +} diff --git a/examples/minimal/README.md b/examples/minimal/README.md index fbbd7b058..e020ef912 100644 --- a/examples/minimal/README.md +++ b/examples/minimal/README.md @@ -2,12 +2,19 @@ Just the minimum to get a working bot using interactions. -Make sure to install the latest version when you use it. +This template does not include any caching or other features you might need. +This template also includes a /ping command to show the bot latency ## Setup -Just rename `.env.example` to `.env` and fill it with your bot token. +- Download the source +- Install the dependencies using `yarn` +- Copy the .env.example file and rename it to .env +- Fill out the .env file ## Run Bot -- deno run -A mod.ts +- run `yarn` to install the dependencies +- run `yarn build` to build the source +- run `node dist/register-commands.js` to register the slash commands +- run `yarn start` to run the bot diff --git a/examples/minimal/configs.ts b/examples/minimal/configs.ts deleted file mode 100644 index 5409e62f4..000000000 --- a/examples/minimal/configs.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { dotEnvConfig } from './deps.ts.js' - -dotEnvConfig({ export: true }) -export const BOT_TOKEN = process.env.BOT_TOKEN || '' -export const BOT_ID = BigInt(atob(BOT_TOKEN.split('.')[0])) diff --git a/examples/minimal/deps.ts b/examples/minimal/deps.ts deleted file mode 100644 index d78783606..000000000 --- a/examples/minimal/deps.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from 'https://deno.land/x/discordeno@17.0.0/mod.ts' -export * from 'https://deno.land/x/discordeno@17.0.0/plugins/mod.ts' -export { config as dotEnvConfig } from 'https://deno.land/x/dotenv@v3.1.0/mod.ts' -export * from 'https://deno.land/std@0.117.0/fmt/colors.ts' diff --git a/examples/minimal/mod.ts b/examples/minimal/mod.ts deleted file mode 100644 index 67ecc25d2..000000000 --- a/examples/minimal/mod.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { ActivityTypes, createBot, enableCachePlugin, enableCacheSweepers, fastFileLoader, GatewayIntents, startBot } from './deps.ts.js' -import { BOT_ID, BOT_TOKEN } from './configs.ts.js' -import { logger } from './src/utils/logger.ts.js' -import { events } from './src/events/mod.ts.js' -import { updateCommands } from './src/utils/helpers.ts.js' - -const log = logger({ name: 'Main' }) - -log.info('Starting Bot, this might take a while...') - -const paths = ['./src/events', './src/commands'] -await fastFileLoader(paths).catch((err) => { - log.fatal(`Unable to Import ${paths}`) - log.fatal(err) - Deno.exit(1) -}) - -export const bot = enableCachePlugin( - createBot({ - token: BOT_TOKEN, - botId: BOT_ID, - intents: GatewayIntents.Guilds, - events, - }), -) - -// @ts-nocheck: no-updated-depencdencies -enableCacheSweepers(bot) - -bot.gateway.manager.createShardOptions.makePresence = (shardId: number) => { - return { - shardId, - status: 'online', - activities: [ - { - name: 'Discordeno is the Best Lib', - type: ActivityTypes.Game, - createdAt: Date.now(), - }, - ], - } -} - -await startBot(bot) - -await updateCommands(bot) diff --git a/examples/minimal/package.json b/examples/minimal/package.json new file mode 100644 index 000000000..47d83008a --- /dev/null +++ b/examples/minimal/package.json @@ -0,0 +1,26 @@ +{ + "name": "dd-minimal-bot", + "version": "1.0.0", + "description": "A minimal bot written with discordeno.", + "main": "dist/index.js", + "type": "module", + "license": "ISC", + "private": true, + "packageManager": "yarn@4.0.2", + "scripts": { + "start": "node dist/index.js", + "build": "swc src --strip-leading-paths --delete-dir-on-start --out-dir dist", + "setup-dd": "" + }, + "dependencies": { + "@discordeno/bot": "19.0.0-next.92bf166", + "chalk": "^5.3.0", + "dotenv": "^16.4.5" + }, + "devDependencies": { + "@swc/cli": "^0.3.12", + "@swc/core": "^1.6.3", + "@types/node": "^20.14.6", + "typescript": "^5.5.2" + } +} diff --git a/examples/minimal/src/bot.ts b/examples/minimal/src/bot.ts new file mode 100644 index 000000000..86da0d9b9 --- /dev/null +++ b/examples/minimal/src/bot.ts @@ -0,0 +1,23 @@ +import { Collection, Intents, createBot, type Bot } from '@discordeno/bot' +import { configs } from './config.js' +import type { Command } from './types/commands.js' + +const rawBot = createBot({ + token: configs.token, + intents: Intents.Guilds, +}) + +// Setup desired proprieties +rawBot.transformers.desiredProperties.interaction.id = true +rawBot.transformers.desiredProperties.interaction.type = true +rawBot.transformers.desiredProperties.interaction.data = true +rawBot.transformers.desiredProperties.interaction.token = true + +export const bot = rawBot as BotWithCommands + +// Create the command collection +bot.commands = new Collection() + +export interface BotWithCommands extends Bot { + commands: Collection +} diff --git a/examples/minimal/src/commands.ts b/examples/minimal/src/commands.ts new file mode 100644 index 000000000..490f3a81e --- /dev/null +++ b/examples/minimal/src/commands.ts @@ -0,0 +1,6 @@ +import { bot } from './bot.js' +import type { Command } from './types/commands.js' + +export function createCommand(command: Command): void { + bot.commands.set(command.name, command) +} diff --git a/examples/minimal/src/commands/mod.ts b/examples/minimal/src/commands/mod.ts deleted file mode 100644 index e4390adc8..000000000 --- a/examples/minimal/src/commands/mod.ts +++ /dev/null @@ -1,25 +0,0 @@ -import type { ApplicationCommandOption, ApplicationCommandTypes, Bot, Interaction } from '../../deps.ts.js' -import { Collection } from '../../deps.ts.js' - -export type subCommand = Omit -export interface subCommandGroup { - name: string - subCommands: subCommand[] -} -export interface Command { - name: string - description: string - usage?: string[] - options?: ApplicationCommandOption[] - type: ApplicationCommandTypes - /** Defaults to `Guild` */ - scope?: 'Global' | 'Guild' - execute: (bot: Bot, interaction: Interaction) => unknown - subcommands?: Array -} - -export const commands = new Collection() - -export function createCommand(command: Command) { - commands.set(command.name, command) -} diff --git a/examples/minimal/src/commands/ping.ts b/examples/minimal/src/commands/ping.ts index e3ae23803..b293cdfe0 100644 --- a/examples/minimal/src/commands/ping.ts +++ b/examples/minimal/src/commands/ping.ts @@ -1,19 +1,13 @@ -import { ApplicationCommandTypes, InteractionResponseTypes } from '../../deps.ts.js' -import { humanizeMilliseconds, snowflakeToTimestamp } from '../utils/helpers.ts.js' -import { createCommand } from './mod.ts.js' +import { ApplicationCommandTypes, snowflakeToTimestamp } from '@discordeno/bot' +import { createCommand } from '../commands.js' createCommand({ name: 'ping', description: 'Ping the Bot!', type: ApplicationCommandTypes.ChatInput, - scope: 'Global', - execute: async (bot, interaction) => { + async execute(interaction) { const ping = Date.now() - snowflakeToTimestamp(interaction.id) - await bot.helpers.sendInteractionResponse(interaction.id, interaction.token, { - type: InteractionResponseTypes.ChannelMessageWithSource, - data: { - content: `🏓 Pong! Ping ${ping}ms (${humanizeMilliseconds(ping)})`, - }, - }) + + await interaction.respond(`🏓 Pong! ${ping}ms`) }, }) diff --git a/examples/minimal/src/config.ts b/examples/minimal/src/config.ts new file mode 100644 index 000000000..32b9c49c2 --- /dev/null +++ b/examples/minimal/src/config.ts @@ -0,0 +1,17 @@ +const token = process.env.BOT_TOKEN +const devGuildId = process.env.DEV_GUILD_ID + +if (!token) throw new Error('Missing BOT_TOKEN environment variable') +if (!devGuildId) throw new Error('Missing DEV_GUILD_ID environment variable') + +export const configs: Config = { + /** Get token from ENV variable */ + token, + /** The server id where you develop your bot and want dev commands created. */ + devGuildId: BigInt(devGuildId), +} + +export interface Config { + token: string + devGuildId: bigint +} diff --git a/examples/minimal/src/events/guildCreate.ts b/examples/minimal/src/events/guildCreate.ts deleted file mode 100644 index a7f2e892c..000000000 --- a/examples/minimal/src/events/guildCreate.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { events } from './mod.ts.js' -import { updateGuildCommands } from '../utils/helpers.ts.js' - -events.guildCreate = async (bot, guild) => await updateGuildCommands(bot, guild) diff --git a/examples/minimal/src/events/interactionCreate.ts b/examples/minimal/src/events/interactionCreate.ts index 4772d2ad2..bed68eda8 100644 --- a/examples/minimal/src/events/interactionCreate.ts +++ b/examples/minimal/src/events/interactionCreate.ts @@ -1,225 +1,15 @@ -import type { BotWithCache, Guild } from '../../deps.ts.js' -import { ApplicationCommandOptionTypes, bgBlack, bgYellow, black, green, red, white, yellow } from '../../deps.ts.js' -import { events } from './mod.ts.js' -import { logger } from '../utils/logger.ts.js' -import { getGuildFromId, isSubCommand, isSubCommandGroup } from '../utils/helpers.ts.js' -import type { Command } from '../commands/mod.ts.js' -import { commands } from '../commands/mod.ts.js' +import { InteractionTypes } from '@discordeno/bot' +import { bot } from '../bot.js' +import logger from '../utils/logger.js' -const log = logger({ name: 'Event: InteractionCreate' }) +bot.events.interactionCreate = (interaction) => { + if (!interaction.data) return -events.interactionCreate = async (rawBot, interaction) => { - const bot = rawBot as BotWithCache + switch (interaction.type) { + case InteractionTypes.ApplicationCommand: + logger.info(`[Application Command] ${interaction.data.name} command executed.`) - if (interaction.data && interaction.id) { - let guildName = 'Direct Message' - let guild = {} as Guild - - // Set guild, if there was an error getting the guild, then just say it was a DM. (What else are we going to do?) - if (interaction.guildId) { - const guildOrVoid = await getGuildFromId(bot, interaction.guildId).catch((err) => { - log.error(err) - }) - if (guildOrVoid) { - guild = guildOrVoid - guildName = guild.name - } - } - - log.info( - `[Command: ${bgYellow(black(String(interaction.data.name)))} - ${bgBlack(white(`Trigger`))}] by ${interaction.user.username}#${ - interaction.user.discriminator - } in ${guildName}${guildName !== 'Direct Message' ? ` (${guild.id})` : ``}`, - ) - - let command: undefined | Command = interaction.data.name ? commands.get(interaction.data.name) : undefined - let commandName = command?.name - - if (command !== undefined) { - if (interaction.data.name) { - if (interaction.data.options?.[0]) { - const optionType = interaction.data.options[0].type - - if (optionType === ApplicationCommandOptionTypes.SubCommandGroup) { - // Check if command has subcommand and handle types - if (!command.subcommands) return - - // Try to find the subcommand group - const subCommandGroup = command.subcommands?.find((command) => command.name == interaction.data?.options?.[0].name) - if (!subCommandGroup) return - - if (isSubCommand(subCommandGroup)) return - - // Get name of the command which we are looking for - const targetCmdName = interaction.data.options?.[0].options?.[0].name || interaction.data.options?.[0].options?.[0].name - if (!targetCmdName) return - - // Try to find the command - command = subCommandGroup.subCommands.find((c) => c.name === targetCmdName) - - commandName += ` ${subCommandGroup.name} ${command?.name}` - - // Normal - } - - if (optionType === ApplicationCommandOptionTypes.SubCommandGroup) { - // Check if command has subcommand and handle types - if (!command?.subcommands) return - - // Try to find the command - const found = command.subcommands.find((command) => command.name == interaction.data?.options?.[0].name) - if (!found) return - - if (isSubCommandGroup(found)) return - - command = found - commandName += ` ${command?.name}` - } - } - - try { - if (command) { - command.execute(rawBot, interaction) - log.info( - `[Command: ${bgYellow(black(String(interaction.data.name)))} - ${bgBlack(green(`Success`))}] by ${interaction.user.username}#${ - interaction.user.discriminator - } in ${guildName}${guildName !== 'Direct Message' ? ` (${guild.id})` : ``}`, - ) - } else { - throw '' - } - } catch (err) { - log.error( - `[Command: ${bgYellow(black(String(interaction.data.name)))} - ${bgBlack(red(`Error`))}] by ${interaction.user.username}#${ - interaction.user.discriminator - } in ${guildName}${guildName !== 'Direct Message' ? ` (${guild.id})` : ``}`, - ) - err.length ? log.error(err) : undefined - } - } else { - log.warn( - `[Command: ${bgYellow(black(String(interaction.data.name)))} - ${bgBlack(yellow(`Not Found`))}] by ${interaction.user.username}#${ - interaction.user.discriminator - } in ${guildName}${guildName !== 'Direct Message' ? ` (${guild.id})` : ``}`, - ) - } - } + bot.commands.get(interaction.data.name)?.execute(interaction) + break } } - -/* - // Handle subcommands - let cmdName = cmd.name; - - // Group - if (interaction.data?.options?.[0].type === DiscordApplicationCommandOptionTypes.SubCommandGroup) { - // Check if command has subcommand and handle types - if (!cmd.subcommands) return; - - // Try to find the subcommand group - const subCmdGroup = cmd.subcommands?.find((cmd) => cmd.name == interaction?.data?.options?.[0].name); - if (!subCmdGroup) return; - - if (isSubCommand(subCmdGroup)) return; - - // Get name of the command which we are looking for - const targetCmdName = - interaction.data.options?.[0].options?.[0].name || interaction.data.options?.[0].options?.[0].name; - if (!targetCmdName) return; - - // Try to find the command - cmd = subCmdGroup.subCommands.find((c) => c.name === targetCmdName); - - cmdName += ` ${subCmdGroup.name} ${cmd?.name}`; - - // Normal - } else if (interaction.data?.options?.[0].type === DiscordApplicationCommandOptionTypes.SubCommand) { - // Check if command has subcommand and handle types - if (!cmd.subcommands) return; - - // Try to find the command - const found = cmd.subcommands.find((cmd) => cmd.name == interaction.data?.options?.[0].name); - if (!found) return; - - if (isSubCommandGroup(found)) return; - - cmd = found; - cmdName += ` ${cmd?.name}`; - } - if (!cmd) return; - - // Get options - const options = - interaction.data?.options?.[0].type === DiscordApplicationCommandOptionTypes.SubCommandGroup - ? interaction.data?.options?.[0].options?.[0].options - : interaction.data?.options?.[0].type === DiscordApplicationCommandOptionTypes.SubCommand - ? interaction.data?.options[0].options - : interaction.data?.options; - - // Prepare info for logs - const user = member || interaction.user; - const guild = interaction.guildId - ? await customCacheHandlers.get("guilds", snowflakeToBigint(interaction.guildId)) - : undefined; - - // Log cmd trigger - logSlashCommand(cmdName, user, guild, "trigger"); - - // Check inhibitors - for await (const inhibitor of bot.inhibitors.values()) { - const inhibited = await inhibitor(cmd, interaction, member); - if (inhibited) { - // Log cmd inhibition - logSlashCommand(cmdName, user, guild, "inhibited"); - return; - } - } - - // Check if command has execute - if (!cmd.execute) { - logger.error(`Command ${cmdName} is missing execute.`); - sendBasicResponse(data.id, data.token, "This command is not configured to be executed."); - return; - } - - // Get Command context - const cmdCtx = createCommandCtx(interaction, undefined, undefined, options, member); - - // Execute command - let err; - try { - if (cmd.longExecution) - // Thinking.... - await sendInteractionResponse(interaction.id, interaction.token, { - type: DiscordInteractionResponseTypes.DeferredChannelMessageWithSource, - }); - - await cmd.execute(cmdCtx); - } catch (error) { - err = true; - - // Log command fail - logSlashCommand(cmdName, user, guild, "failed", error); - - // Log the error - logger.error(`Error ${cmdName}`, error); - - // Send error message to user - sendInteractionResponse(interaction.id, interaction.token, { - type: DiscordInteractionResponseTypes.ChannelMessageWithSource, - data: { - embeds: [ - createSimpleEmbed("error") - .setDescription("Unexpected Error") - .setFooter("This error has been reported to the developers of this bot."), - ], - }, - }).catch(logger.error); - } - - // Log success - if (!err) logSlashCommand(cmdName, user, guild, "success"); - }, -}); - -*/ diff --git a/examples/minimal/src/events/mod.ts b/examples/minimal/src/events/mod.ts deleted file mode 100644 index e7861048e..000000000 --- a/examples/minimal/src/events/mod.ts +++ /dev/null @@ -1,3 +0,0 @@ -import type { EventHandlers } from '../../deps.ts.js' - -export const events: Partial = {} diff --git a/examples/minimal/src/events/ready.ts b/examples/minimal/src/events/ready.ts index 324bc42eb..f6f7c3271 100644 --- a/examples/minimal/src/events/ready.ts +++ b/examples/minimal/src/events/ready.ts @@ -1,8 +1,17 @@ -import { events } from './mod.ts.js' -import { logger } from '../utils/logger.ts.js' +import { bot } from '../bot.js' +import logger from '../utils/logger.js' -const log = logger({ name: 'Event: Ready' }) +bot.events.ready = ({ shardId }) => { + logger.info(`[READY] Shard ${shardId} is ready!`) -events.ready = () => { - log.info('Bot Ready') + if (shardId === bot.gateway.lastShardId) { + botFullyReady() + } +} + +// This function lets you run custom code when all your bot's shards are online. +function botFullyReady(): void { + // Do stuff that you want that get execute only when the bot is fully online. + + logger.info('[READY] Bot is fully online.') } diff --git a/examples/minimal/src/index.ts b/examples/minimal/src/index.ts new file mode 100644 index 000000000..b0f5f89cf --- /dev/null +++ b/examples/minimal/src/index.ts @@ -0,0 +1,15 @@ +import 'dotenv/config' + +import { bot } from './bot.js' +import importDirectory from './utils/loader.js' +import logger from './utils/logger.js' + +logger.info('Starting bot...') + +logger.info('Loading commands...') +await importDirectory('./dist/commands') + +logger.info('Loading events...') +await importDirectory('./dist/events') + +await bot.start() diff --git a/examples/minimal/src/register-commands.ts b/examples/minimal/src/register-commands.ts new file mode 100644 index 000000000..726dd9c36 --- /dev/null +++ b/examples/minimal/src/register-commands.ts @@ -0,0 +1,7 @@ +import 'dotenv/config' + +import logger from './utils/logger.js' +import { updateApplicationCommands } from './utils/updateCommands.js' + +logger.info('Updating commands...') +await updateApplicationCommands() diff --git a/examples/beginner/src/types/commands.ts b/examples/minimal/src/types/commands.ts similarity index 76% rename from examples/beginner/src/types/commands.ts rename to examples/minimal/src/types/commands.ts index aeddaf60a..744dd8a93 100644 --- a/examples/beginner/src/types/commands.ts +++ b/examples/minimal/src/types/commands.ts @@ -1,5 +1,4 @@ -import type { BotClient } from '../../bot.ts.js' -import type { ApplicationCommandOption, ApplicationCommandTypes, Interaction } from '../../deps.ts.js' +import type { ApplicationCommandOption, ApplicationCommandTypes, Interaction } from '@discordeno/bot' export interface Command { /** The name of this command. */ @@ -13,5 +12,5 @@ export interface Command { /** The options for this command */ options?: ApplicationCommandOption[] /** This will be executed when the command is run. */ - execute: (bot: BotClient, interaction: Interaction) => unknown + execute: (interaction: Interaction) => unknown } diff --git a/examples/minimal/src/utils/helpers.ts b/examples/minimal/src/utils/helpers.ts deleted file mode 100644 index 93490835a..000000000 --- a/examples/minimal/src/utils/helpers.ts +++ /dev/null @@ -1,120 +0,0 @@ -import type { Bot, BotWithCache, CreateApplicationCommand, Guild, MakeRequired } from '../../deps.ts.js' -import { getGuild, hasProperty, upsertGuildApplicationCommands } from '../../deps.ts.js' -import { logger } from './logger.ts.js' -import type { subCommand, subCommandGroup } from '../commands/mod.ts.js' -import { commands } from '../commands/mod.ts.js' - -const log = logger({ name: 'Helpers' }) - -/** This function will update all commands, or the defined scope */ -export async function updateCommands(bot: BotWithCache, scope?: 'Guild' | 'Global') { - const globalCommands: Array> = [] - const perGuildCommands: Array> = [] - - for (const command of commands.values()) { - if (command.scope) { - if (command.scope === 'Guild') { - perGuildCommands.push({ - name: command.name, - description: command.description, - type: command.type, - options: command.options ? command.options : undefined, - }) - } else if (command.scope === 'Global') { - globalCommands.push({ - name: command.name, - description: command.description, - type: command.type, - options: command.options ? command.options : undefined, - }) - } - } else { - perGuildCommands.push({ - name: command.name, - description: command.description, - type: command.type, - options: command.options ? command.options : undefined, - }) - } - } - - if (globalCommands.length && (scope === 'Global' || scope === undefined)) { - log.info('Updating Global Commands, changes should apply in short...') - await bot.helpers.upsertGlobalApplicationCommands(globalCommands).catch(log.error) - } - - if (perGuildCommands.length && (scope === 'Guild' || scope === undefined)) { - await bot.guilds.forEach(async (guild: Guild) => { - await upsertGuildApplicationCommands(bot, guild.id, perGuildCommands) - }) - } -} - -/** Update commands for a guild */ -export async function updateGuildCommands(bot: Bot, guild: Guild) { - const perGuildCommands: Array> = [] - - for (const command of commands.values()) { - if (command.scope) { - if (command.scope === 'Guild') { - perGuildCommands.push({ - name: command.name, - description: command.description, - type: command.type, - options: command.options ? command.options : undefined, - }) - } - } - } - - if (perGuildCommands.length) { - await upsertGuildApplicationCommands(bot, guild.id, perGuildCommands) - } -} - -export async function getGuildFromId(bot: BotWithCache, guildId: bigint): Promise { - let returnValue: Guild = {} as Guild - - if (guildId !== 0n) { - if (bot.guilds.get(guildId)) { - returnValue = bot.guilds.get(guildId) as Guild - } - - await getGuild(bot, guildId).then((guild) => { - if (guild) bot.guilds.set(guildId, guild) - if (guild) returnValue = guild - }) - } - - return returnValue -} - -export function snowflakeToTimestamp(id: bigint) { - return Number(id / 4194304n + 1420070400000n) -} - -export function humanizeMilliseconds(milliseconds: number) { - // Gets ms into seconds - const time = milliseconds / 1000 - if (time < 1) return '1s' - - const days = Math.floor(time / 86400) - const hours = Math.floor((time % 86400) / 3600) - const minutes = Math.floor(((time % 86400) % 3600) / 60) - const seconds = Math.floor(((time % 86400) % 3600) % 60) - - const dayString = days ? `${days}d ` : '' - const hourString = hours ? `${hours}h ` : '' - const minuteString = minutes ? `${minutes}m ` : '' - const secondString = seconds ? `${seconds}s ` : '' - - return `${dayString}${hourString}${minuteString}${secondString}` -} - -export function isSubCommand(data: subCommand | subCommandGroup): data is subCommand { - return !hasProperty(data, 'subCommands') -} - -export function isSubCommandGroup(data: subCommand | subCommandGroup): data is subCommandGroup { - return hasProperty(data, 'subCommands') -} diff --git a/examples/minimal/src/utils/loader.ts b/examples/minimal/src/utils/loader.ts new file mode 100644 index 000000000..5b1c6f541 --- /dev/null +++ b/examples/minimal/src/utils/loader.ts @@ -0,0 +1,15 @@ +import { readdir } from 'node:fs/promises' +import logger from './logger.js' + +export default async function importDirectory(folder: string): Promise { + const files = await readdir(folder, { recursive: true }) + + for (const filename of files) { + if (!filename.endsWith('.js')) continue + + // Using `file://` and `process.cwd()` to avoid weird issues with relative paths and/or Windows + await import(`file://${process.cwd()}/${folder}/${filename}`).catch((x) => + logger.fatal(`Cannot import file (${folder}/${filename}) for reason:`, x), + ) + } +} diff --git a/examples/minimal/src/utils/logger.ts b/examples/minimal/src/utils/logger.ts index 9228b7074..4838e581b 100644 --- a/examples/minimal/src/utils/logger.ts +++ b/examples/minimal/src/utils/logger.ts @@ -1,5 +1,5 @@ -// deno-lint-ignore-file no-explicit-any -import { bold, cyan, gray, italic, red, yellow } from '../../deps.ts.js' +/* eslint-disable @typescript-eslint/no-unsafe-argument */ +import chalk from 'chalk' export enum LogLevels { Debug, @@ -19,21 +19,15 @@ const prefixes = new Map([ const noColor: (str: string) => string = (msg) => msg const colorFunctions = new Map string>([ - [LogLevels.Debug, gray], - [LogLevels.Info, cyan], - [LogLevels.Warn, yellow], - [LogLevels.Error, (str: string) => red(str)], - [LogLevels.Fatal, (str: string) => red(bold(italic(str)))], + [LogLevels.Debug, chalk.gray], + [LogLevels.Info, chalk.cyan], + [LogLevels.Warn, chalk.yellow], + [LogLevels.Error, (str: string) => chalk.red(str)], + [LogLevels.Fatal, (str: string) => chalk.red.bold.italic(str)], ]) -export function logger({ - logLevel = LogLevels.Info, - name, -}: { - logLevel?: LogLevels - name?: string -} = {}) { - function log(level: LogLevels, ...args: any[]) { +export function createLogger({ logLevel = LogLevels.Info, name }: { logLevel?: LogLevels; name?: string } = {}): Logger { + function log(level: LogLevels, ...args: any[]): void { if (level < logLevel) return let color = colorFunctions.get(level) @@ -42,7 +36,7 @@ export function logger({ const date = new Date() const log = [ `[${date.toLocaleDateString()} ${date.toLocaleTimeString()}]`, - color(prefixes.get(level) || 'DEBUG'), + color(prefixes.get(level) ?? 'DEBUG'), name ? `${name} >` : '>', ...args, ] @@ -63,27 +57,27 @@ export function logger({ } } - function setLevel(level: LogLevels) { + function setLevel(level: LogLevels): void { logLevel = level } - function debug(...args: any[]) { + function debug(...args: any[]): void { log(LogLevels.Debug, ...args) } - function info(...args: any[]) { + function info(...args: any[]): void { log(LogLevels.Info, ...args) } - function warn(...args: any[]) { + function warn(...args: any[]): void { log(LogLevels.Warn, ...args) } - function error(...args: any[]) { + function error(...args: any[]): void { log(LogLevels.Error, ...args) } - function fatal(...args: any[]) { + function fatal(...args: any[]): void { log(LogLevels.Fatal, ...args) } @@ -98,4 +92,15 @@ export function logger({ } } -export const log = logger() +export const logger = createLogger({ name: 'Main' }) +export default logger + +export interface Logger { + log: (level: LogLevels, ...args: any[]) => void + debug: (...args: any[]) => void + info: (...args: any[]) => void + warn: (...args: any[]) => void + error: (...args: any[]) => void + fatal: (...args: any[]) => void + setLevel: (level: LogLevels) => void +} diff --git a/examples/minimal/src/utils/updateCommands.ts b/examples/minimal/src/utils/updateCommands.ts new file mode 100644 index 000000000..c98d3cc48 --- /dev/null +++ b/examples/minimal/src/utils/updateCommands.ts @@ -0,0 +1,19 @@ +import { bot } from '../bot.js' +import { configs } from '../config.js' + +export async function updateApplicationCommands(): Promise { + await bot.helpers.upsertGlobalApplicationCommands( + bot.commands + // ONLY GLOBAL COMMANDS + .filter((command) => !command.devOnly) + .array(), + ) + + await bot.helpers.upsertGuildApplicationCommands( + configs.devGuildId, + bot.commands + // ONLY GLOBAL COMMANDS + .filter((command) => !!command.devOnly) + .array(), + ) +} diff --git a/examples/minimal/tsconfig.json b/examples/minimal/tsconfig.json new file mode 100644 index 000000000..04416ddd6 --- /dev/null +++ b/examples/minimal/tsconfig.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "target": "es2022", + "module": "es2022", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "isolatedModules": true, + "moduleResolution": "node", + "skipDefaultLibCheck": true, + "skipLibCheck": true, + "strict": true, + "incremental": true + } +} diff --git a/examples/minimal/yarn.lock b/examples/minimal/yarn.lock new file mode 100644 index 000000000..459e182d0 --- /dev/null +++ b/examples/minimal/yarn.lock @@ -0,0 +1,2123 @@ +# This file is generated by running "yarn install" inside your project. +# Manual changes might be lost - proceed with caution! + +__metadata: + version: 8 + cacheKey: 10 + +"@discordeno/bot@npm:19.0.0-next.92bf166": + version: 19.0.0-next.92bf166 + resolution: "@discordeno/bot@npm:19.0.0-next.92bf166" + dependencies: + "@discordeno/gateway": "npm:19.0.0-next.92bf166" + "@discordeno/rest": "npm:19.0.0-next.92bf166" + "@discordeno/types": "npm:19.0.0-next.92bf166" + "@discordeno/utils": "npm:19.0.0-next.92bf166" + checksum: 3020e74c774eae34307d434ad38f983e90839dc5fad7578f3cda4fba6c1efb7a22c4f4cdcfff58c54b62cc14976ad974256955d5117e490f78ec9e835e02c682 + languageName: node + linkType: hard + +"@discordeno/gateway@npm:19.0.0-next.92bf166": + version: 19.0.0-next.92bf166 + resolution: "@discordeno/gateway@npm:19.0.0-next.92bf166" + dependencies: + "@discordeno/types": "npm:19.0.0-next.92bf166" + "@discordeno/utils": "npm:19.0.0-next.92bf166" + ws: "npm:^8.16.0" + checksum: 6a11ca7a4cb98f48726664d0baa27d04e26342bf94d6e439494e462636af20d17b567e9d3e2e478465aabcecb98a21e54b860b39b9f1022eef922e76d947ddcb + languageName: node + linkType: hard + +"@discordeno/rest@npm:19.0.0-next.92bf166": + version: 19.0.0-next.92bf166 + resolution: "@discordeno/rest@npm:19.0.0-next.92bf166" + dependencies: + "@discordeno/types": "npm:19.0.0-next.92bf166" + "@discordeno/utils": "npm:19.0.0-next.92bf166" + dotenv: "npm:^16.4.5" + checksum: 45f6ba4791003b77c883e991ad348597197d70e25e335b8628a03bd2effa8e2047a2f987f4c0b6ee8b17c01f77055d7a1ddc9f5350eb8f1c8ff8c8d39f91d787 + languageName: node + linkType: hard + +"@discordeno/types@npm:19.0.0-next.92bf166": + version: 19.0.0-next.92bf166 + resolution: "@discordeno/types@npm:19.0.0-next.92bf166" + checksum: f88e78a18e51c179b94ef14e8bcdd6b5e6c5f25bdd6c4308bec121e5e59533612b36ed0e7a447daedc009053e1e30c6c8e13b2276bb1ce7e2f840ff58473a2ef + languageName: node + linkType: hard + +"@discordeno/utils@npm:19.0.0-next.92bf166": + version: 19.0.0-next.92bf166 + resolution: "@discordeno/utils@npm:19.0.0-next.92bf166" + dependencies: + "@discordeno/types": "npm:19.0.0-next.92bf166" + tweetnacl: "npm:^1.0.3" + checksum: 7962a057ba5908936e4224df70b9ceaffcb8ec7ad220a999b36fc0601365b380bb0de01b6adfa4c36250247e3d15e22215fc63bbe3634b932434411c5f4ca13d + languageName: node + linkType: hard + +"@isaacs/cliui@npm:^8.0.2": + version: 8.0.2 + resolution: "@isaacs/cliui@npm:8.0.2" + dependencies: + string-width: "npm:^5.1.2" + string-width-cjs: "npm:string-width@^4.2.0" + strip-ansi: "npm:^7.0.1" + strip-ansi-cjs: "npm:strip-ansi@^6.0.1" + wrap-ansi: "npm:^8.1.0" + wrap-ansi-cjs: "npm:wrap-ansi@^7.0.0" + checksum: e9ed5fd27c3aec1095e3a16e0c0cf148d1fee55a38665c35f7b3f86a9b5d00d042ddaabc98e8a1cb7463b9378c15f22a94eb35e99469c201453eb8375191f243 + languageName: node + linkType: hard + +"@mole-inc/bin-wrapper@npm:^8.0.1": + version: 8.0.1 + resolution: "@mole-inc/bin-wrapper@npm:8.0.1" + dependencies: + bin-check: "npm:^4.1.0" + bin-version-check: "npm:^5.0.0" + content-disposition: "npm:^0.5.4" + ext-name: "npm:^5.0.0" + file-type: "npm:^17.1.6" + filenamify: "npm:^5.0.2" + got: "npm:^11.8.5" + os-filter-obj: "npm:^2.0.0" + checksum: 565df38f6f91fefe2e2540bf4357024fd912990aecb1873fd9bf21e6a667d9930c73e5cbc87a9aac0cf476b8dffc30a4e00ec97b62e713ef5c00d46823ea599d + languageName: node + linkType: hard + +"@nodelib/fs.scandir@npm:2.1.5": + version: 2.1.5 + resolution: "@nodelib/fs.scandir@npm:2.1.5" + dependencies: + "@nodelib/fs.stat": "npm:2.0.5" + run-parallel: "npm:^1.1.9" + checksum: 6ab2a9b8a1d67b067922c36f259e3b3dfd6b97b219c540877a4944549a4d49ea5ceba5663905ab5289682f1f3c15ff441d02f0447f620a42e1cb5e1937174d4b + languageName: node + linkType: hard + +"@nodelib/fs.stat@npm:2.0.5, @nodelib/fs.stat@npm:^2.0.2": + version: 2.0.5 + resolution: "@nodelib/fs.stat@npm:2.0.5" + checksum: 012480b5ca9d97bff9261571dbbec7bbc6033f69cc92908bc1ecfad0792361a5a1994bc48674b9ef76419d056a03efadfce5a6cf6dbc0a36559571a7a483f6f0 + languageName: node + linkType: hard + +"@nodelib/fs.walk@npm:^1.2.3": + version: 1.2.8 + resolution: "@nodelib/fs.walk@npm:1.2.8" + dependencies: + "@nodelib/fs.scandir": "npm:2.1.5" + fastq: "npm:^1.6.0" + checksum: 40033e33e96e97d77fba5a238e4bba4487b8284678906a9f616b5579ddaf868a18874c0054a75402c9fbaaa033a25ceae093af58c9c30278e35c23c9479e79b0 + languageName: node + linkType: hard + +"@npmcli/agent@npm:^2.0.0": + version: 2.2.2 + resolution: "@npmcli/agent@npm:2.2.2" + dependencies: + agent-base: "npm:^7.1.0" + http-proxy-agent: "npm:^7.0.0" + https-proxy-agent: "npm:^7.0.1" + lru-cache: "npm:^10.0.1" + socks-proxy-agent: "npm:^8.0.3" + checksum: 96fc0036b101bae5032dc2a4cd832efb815ce9b33f9ee2f29909ee49d96a0026b3565f73c507a69eb8603f5cb32e0ae45a70cab1e2655990a4e06ae99f7f572a + languageName: node + linkType: hard + +"@npmcli/fs@npm:^3.1.0": + version: 3.1.1 + resolution: "@npmcli/fs@npm:3.1.1" + dependencies: + semver: "npm:^7.3.5" + checksum: 1e0e04087049b24b38bc0b30d87a9388ee3ca1d3fdfc347c2f77d84fcfe6a51f250bc57ba2c1f614d7e4285c6c62bf8c769bc19aa0949ea39e5b043ee023b0bd + languageName: node + linkType: hard + +"@pkgjs/parseargs@npm:^0.11.0": + version: 0.11.0 + resolution: "@pkgjs/parseargs@npm:0.11.0" + checksum: 115e8ceeec6bc69dff2048b35c0ab4f8bbee12d8bb6c1f4af758604586d802b6e669dcb02dda61d078de42c2b4ddce41b3d9e726d7daa6b4b850f4adbf7333ff + languageName: node + linkType: hard + +"@sindresorhus/is@npm:^4.0.0": + version: 4.6.0 + resolution: "@sindresorhus/is@npm:4.6.0" + checksum: e7f36ed72abfcd5e0355f7423a72918b9748bb1ef370a59f3e5ad8d40b728b85d63b272f65f63eec1faf417cda89dcb0aeebe94015647b6054659c1442fe5ce0 + languageName: node + linkType: hard + +"@swc/cli@npm:^0.3.12": + version: 0.3.12 + resolution: "@swc/cli@npm:0.3.12" + dependencies: + "@mole-inc/bin-wrapper": "npm:^8.0.1" + "@swc/counter": "npm:^0.1.3" + commander: "npm:^8.3.0" + fast-glob: "npm:^3.2.5" + minimatch: "npm:^9.0.3" + piscina: "npm:^4.3.0" + semver: "npm:^7.3.8" + slash: "npm:3.0.0" + source-map: "npm:^0.7.3" + peerDependencies: + "@swc/core": ^1.2.66 + chokidar: ^3.5.1 + peerDependenciesMeta: + chokidar: + optional: true + bin: + spack: bin/spack.js + swc: bin/swc.js + swcx: bin/swcx.js + checksum: fee260434fad8eed0328f4db17f42ce0864b93b90fcb02f3f0eb3aad994b5a6ae4bfdfb6d2329377e0cd8d07adc61cca42e290bf0005c1ab4d004d4a0b152db4 + languageName: node + linkType: hard + +"@swc/core-darwin-arm64@npm:1.6.3": + version: 1.6.3 + resolution: "@swc/core-darwin-arm64@npm:1.6.3" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@swc/core-darwin-x64@npm:1.6.3": + version: 1.6.3 + resolution: "@swc/core-darwin-x64@npm:1.6.3" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@swc/core-linux-arm-gnueabihf@npm:1.6.3": + version: 1.6.3 + resolution: "@swc/core-linux-arm-gnueabihf@npm:1.6.3" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@swc/core-linux-arm64-gnu@npm:1.6.3": + version: 1.6.3 + resolution: "@swc/core-linux-arm64-gnu@npm:1.6.3" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@swc/core-linux-arm64-musl@npm:1.6.3": + version: 1.6.3 + resolution: "@swc/core-linux-arm64-musl@npm:1.6.3" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@swc/core-linux-x64-gnu@npm:1.6.3": + version: 1.6.3 + resolution: "@swc/core-linux-x64-gnu@npm:1.6.3" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@swc/core-linux-x64-musl@npm:1.6.3": + version: 1.6.3 + resolution: "@swc/core-linux-x64-musl@npm:1.6.3" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@swc/core-win32-arm64-msvc@npm:1.6.3": + version: 1.6.3 + resolution: "@swc/core-win32-arm64-msvc@npm:1.6.3" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@swc/core-win32-ia32-msvc@npm:1.6.3": + version: 1.6.3 + resolution: "@swc/core-win32-ia32-msvc@npm:1.6.3" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@swc/core-win32-x64-msvc@npm:1.6.3": + version: 1.6.3 + resolution: "@swc/core-win32-x64-msvc@npm:1.6.3" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@swc/core@npm:^1.6.3": + version: 1.6.3 + resolution: "@swc/core@npm:1.6.3" + dependencies: + "@swc/core-darwin-arm64": "npm:1.6.3" + "@swc/core-darwin-x64": "npm:1.6.3" + "@swc/core-linux-arm-gnueabihf": "npm:1.6.3" + "@swc/core-linux-arm64-gnu": "npm:1.6.3" + "@swc/core-linux-arm64-musl": "npm:1.6.3" + "@swc/core-linux-x64-gnu": "npm:1.6.3" + "@swc/core-linux-x64-musl": "npm:1.6.3" + "@swc/core-win32-arm64-msvc": "npm:1.6.3" + "@swc/core-win32-ia32-msvc": "npm:1.6.3" + "@swc/core-win32-x64-msvc": "npm:1.6.3" + "@swc/counter": "npm:^0.1.3" + "@swc/types": "npm:^0.1.8" + peerDependencies: + "@swc/helpers": "*" + dependenciesMeta: + "@swc/core-darwin-arm64": + optional: true + "@swc/core-darwin-x64": + optional: true + "@swc/core-linux-arm-gnueabihf": + optional: true + "@swc/core-linux-arm64-gnu": + optional: true + "@swc/core-linux-arm64-musl": + optional: true + "@swc/core-linux-x64-gnu": + optional: true + "@swc/core-linux-x64-musl": + optional: true + "@swc/core-win32-arm64-msvc": + optional: true + "@swc/core-win32-ia32-msvc": + optional: true + "@swc/core-win32-x64-msvc": + optional: true + peerDependenciesMeta: + "@swc/helpers": + optional: true + checksum: b4c84a083ecabb0280ba53dffa65a5a575321de94081ad52bd12027fe3b5c8957978f2211b6036e2e28d904dd046fca238106c2106b32d02b752808a51193d35 + languageName: node + linkType: hard + +"@swc/counter@npm:^0.1.3": + version: 0.1.3 + resolution: "@swc/counter@npm:0.1.3" + checksum: df8f9cfba9904d3d60f511664c70d23bb323b3a0803ec9890f60133954173047ba9bdeabce28cd70ba89ccd3fd6c71c7b0bd58be85f611e1ffbe5d5c18616598 + languageName: node + linkType: hard + +"@swc/types@npm:^0.1.8": + version: 0.1.8 + resolution: "@swc/types@npm:0.1.8" + dependencies: + "@swc/counter": "npm:^0.1.3" + checksum: 2d1cda35116e03714137c1c37f4493efe0e26e88285ecc9dcdf6256a77984e367ea7b5f31d650f110fdcfd6ac53dff3ec77f841787ca328d2efa7b07ef1ac318 + languageName: node + linkType: hard + +"@szmarczak/http-timer@npm:^4.0.5": + version: 4.0.6 + resolution: "@szmarczak/http-timer@npm:4.0.6" + dependencies: + defer-to-connect: "npm:^2.0.0" + checksum: c29df3bcec6fc3bdec2b17981d89d9c9fc9bd7d0c9bcfe92821dc533f4440bc890ccde79971838b4ceed1921d456973c4180d7175ee1d0023ad0562240a58d95 + languageName: node + linkType: hard + +"@tokenizer/token@npm:^0.3.0": + version: 0.3.0 + resolution: "@tokenizer/token@npm:0.3.0" + checksum: 889c1f1e63ac7c92c0ea22d4a2861142f1b43c3d92eb70ec42aa9e9851fab2e9952211d50f541b287781280df2f979bf5600a9c1f91fbc61b7fcf9994e9376a5 + languageName: node + linkType: hard + +"@types/cacheable-request@npm:^6.0.1": + version: 6.0.3 + resolution: "@types/cacheable-request@npm:6.0.3" + dependencies: + "@types/http-cache-semantics": "npm:*" + "@types/keyv": "npm:^3.1.4" + "@types/node": "npm:*" + "@types/responselike": "npm:^1.0.0" + checksum: 159f9fdb2a1b7175eef453ae2ced5ea04c0d2b9610cc9ccd9f9abb066d36dacb1f37acd879ace10ad7cbb649490723feb396fb7307004c9670be29636304b988 + languageName: node + linkType: hard + +"@types/http-cache-semantics@npm:*": + version: 4.0.4 + resolution: "@types/http-cache-semantics@npm:4.0.4" + checksum: a59566cff646025a5de396d6b3f44a39ab6a74f2ed8150692e0f31cc52f3661a68b04afe3166ebe0d566bd3259cb18522f46e949576d5204781cd6452b7fe0c5 + languageName: node + linkType: hard + +"@types/keyv@npm:^3.1.4": + version: 3.1.4 + resolution: "@types/keyv@npm:3.1.4" + dependencies: + "@types/node": "npm:*" + checksum: e009a2bfb50e90ca9b7c6e8f648f8464067271fd99116f881073fa6fa76dc8d0133181dd65e6614d5fb1220d671d67b0124aef7d97dc02d7e342ab143a47779d + languageName: node + linkType: hard + +"@types/node@npm:*": + version: 20.14.2 + resolution: "@types/node@npm:20.14.2" + dependencies: + undici-types: "npm:~5.26.4" + checksum: c38e47b190fa0a8bdfde24b036dddcf9401551f2fb170a90ff33625c7d6f218907e81c74e0fa6e394804a32623c24c60c50e249badc951007830f0d02c48ee0f + languageName: node + linkType: hard + +"@types/node@npm:^20.14.6": + version: 20.14.6 + resolution: "@types/node@npm:20.14.6" + dependencies: + undici-types: "npm:~5.26.4" + checksum: 1dcfeeb03ce3c3a1d8a537fefee7cd0cffb78f89e9535b74ee12940559566b57c39dad20d1b165b60b5727408dd44e1a52e5c01cf02d0a99d93ef3da8062c86e + languageName: node + linkType: hard + +"@types/responselike@npm:^1.0.0": + version: 1.0.3 + resolution: "@types/responselike@npm:1.0.3" + dependencies: + "@types/node": "npm:*" + checksum: 6ac4b35723429b11b117e813c7acc42c3af8b5554caaf1fc750404c1ae59f9b7376bc69b9e9e194a5a97357a597c2228b7173d317320f0360d617b6425212f58 + languageName: node + linkType: hard + +"abbrev@npm:^2.0.0": + version: 2.0.0 + resolution: "abbrev@npm:2.0.0" + checksum: ca0a54e35bea4ece0ecb68a47b312e1a9a6f772408d5bcb9051230aaa94b0460671c5b5c9cb3240eb5b7bc94c52476550eb221f65a0bbd0145bdc9f3113a6707 + languageName: node + linkType: hard + +"agent-base@npm:^7.0.2, agent-base@npm:^7.1.0, agent-base@npm:^7.1.1": + version: 7.1.1 + resolution: "agent-base@npm:7.1.1" + dependencies: + debug: "npm:^4.3.4" + checksum: c478fec8f79953f118704d007a38f2a185458853f5c45579b9669372bd0e12602e88dc2ad0233077831504f7cd6fcc8251c383375bba5eaaf563b102938bda26 + languageName: node + linkType: hard + +"aggregate-error@npm:^3.0.0": + version: 3.1.0 + resolution: "aggregate-error@npm:3.1.0" + dependencies: + clean-stack: "npm:^2.0.0" + indent-string: "npm:^4.0.0" + checksum: 1101a33f21baa27a2fa8e04b698271e64616b886795fd43c31068c07533c7b3facfcaf4e9e0cab3624bd88f729a592f1c901a1a229c9e490eafce411a8644b79 + languageName: node + linkType: hard + +"ansi-regex@npm:^5.0.1": + version: 5.0.1 + resolution: "ansi-regex@npm:5.0.1" + checksum: 2aa4bb54caf2d622f1afdad09441695af2a83aa3fe8b8afa581d205e57ed4261c183c4d3877cee25794443fde5876417d859c108078ab788d6af7e4fe52eb66b + languageName: node + linkType: hard + +"ansi-regex@npm:^6.0.1": + version: 6.0.1 + resolution: "ansi-regex@npm:6.0.1" + checksum: 1ff8b7667cded1de4fa2c9ae283e979fc87036864317da86a2e546725f96406746411d0d85e87a2d12fa5abd715d90006de7fa4fa0477c92321ad3b4c7d4e169 + languageName: node + linkType: hard + +"ansi-styles@npm:^4.0.0": + version: 4.3.0 + resolution: "ansi-styles@npm:4.3.0" + dependencies: + color-convert: "npm:^2.0.1" + checksum: b4494dfbfc7e4591b4711a396bd27e540f8153914123dccb4cdbbcb514015ada63a3809f362b9d8d4f6b17a706f1d7bea3c6f974b15fa5ae76b5b502070889ff + languageName: node + linkType: hard + +"ansi-styles@npm:^6.1.0": + version: 6.2.1 + resolution: "ansi-styles@npm:6.2.1" + checksum: 70fdf883b704d17a5dfc9cde206e698c16bcd74e7f196ab821511651aee4f9f76c9514bdfa6ca3a27b5e49138b89cb222a28caf3afe4567570139577f991df32 + languageName: node + linkType: hard + +"arch@npm:^2.1.0": + version: 2.2.0 + resolution: "arch@npm:2.2.0" + checksum: e35dbc6d362297000ab90930069576ba165fe63cd52383efcce14bd66c1b16a91ce849e1fd239964ed029d5e0bdfc32f68e9c7331b7df6c84ddebebfdbf242f7 + languageName: node + linkType: hard + +"balanced-match@npm:^1.0.0": + version: 1.0.2 + resolution: "balanced-match@npm:1.0.2" + checksum: 9706c088a283058a8a99e0bf91b0a2f75497f185980d9ffa8b304de1d9e58ebda7c72c07ebf01dadedaac5b2907b2c6f566f660d62bd336c3468e960403b9d65 + languageName: node + linkType: hard + +"bin-check@npm:^4.1.0": + version: 4.1.0 + resolution: "bin-check@npm:4.1.0" + dependencies: + execa: "npm:^0.7.0" + executable: "npm:^4.1.0" + checksum: 16f6d5d86df9365dab682c7dd238f93678b773a908b3bccea4b1acb82b9b4e49fcfa24c99b99180a8e4cdd89a8f15f03700b09908ed5ae651f52fd82488a3507 + languageName: node + linkType: hard + +"bin-version-check@npm:^5.0.0": + version: 5.1.0 + resolution: "bin-version-check@npm:5.1.0" + dependencies: + bin-version: "npm:^6.0.0" + semver: "npm:^7.5.3" + semver-truncate: "npm:^3.0.0" + checksum: d99679cfe0964703045fe0145a98f117888942b621dfe2c2377305ee9a9d735374d8e3ecb3b476507b284af2567699f24f7ecb2feb1f27ad6086ad60b3198893 + languageName: node + linkType: hard + +"bin-version@npm:^6.0.0": + version: 6.0.0 + resolution: "bin-version@npm:6.0.0" + dependencies: + execa: "npm:^5.0.0" + find-versions: "npm:^5.0.0" + checksum: 78c29422ea9597eb4c8d4f0eff96df60d09aa82b53a87925bc403efbe5c55251b1a07baac538381d9096377f92d27e3c03963efa86db5bc0d6431b9563946229 + languageName: node + linkType: hard + +"brace-expansion@npm:^2.0.1": + version: 2.0.1 + resolution: "brace-expansion@npm:2.0.1" + dependencies: + balanced-match: "npm:^1.0.0" + checksum: a61e7cd2e8a8505e9f0036b3b6108ba5e926b4b55089eeb5550cd04a471fe216c96d4fe7e4c7f995c728c554ae20ddfc4244cad10aef255e72b62930afd233d1 + languageName: node + linkType: hard + +"braces@npm:^3.0.3": + version: 3.0.3 + resolution: "braces@npm:3.0.3" + dependencies: + fill-range: "npm:^7.1.1" + checksum: fad11a0d4697a27162840b02b1fad249c1683cbc510cd5bf1a471f2f8085c046d41094308c577a50a03a579dd99d5a6b3724c4b5e8b14df2c4443844cfcda2c6 + languageName: node + linkType: hard + +"cacache@npm:^18.0.0": + version: 18.0.3 + resolution: "cacache@npm:18.0.3" + dependencies: + "@npmcli/fs": "npm:^3.1.0" + fs-minipass: "npm:^3.0.0" + glob: "npm:^10.2.2" + lru-cache: "npm:^10.0.1" + minipass: "npm:^7.0.3" + minipass-collect: "npm:^2.0.1" + minipass-flush: "npm:^1.0.5" + minipass-pipeline: "npm:^1.2.4" + p-map: "npm:^4.0.0" + ssri: "npm:^10.0.0" + tar: "npm:^6.1.11" + unique-filename: "npm:^3.0.0" + checksum: d4c161f071524bb636334b8cf94780c014e29c180a886b8184da8f2f44d2aca88d5664797c661e9f74bdbd34697c2f231ed7c24c256cecbb0a0563ad1ada2219 + languageName: node + linkType: hard + +"cacheable-lookup@npm:^5.0.3": + version: 5.0.4 + resolution: "cacheable-lookup@npm:5.0.4" + checksum: 618a8b3eea314060e74cb3285a6154e8343c244a34235acf91cfe626ee0705c24e3cd11e4b1a7b3900bd749ee203ae65afe13adf610c8ab173e99d4a208faf75 + languageName: node + linkType: hard + +"cacheable-request@npm:^7.0.2": + version: 7.0.4 + resolution: "cacheable-request@npm:7.0.4" + dependencies: + clone-response: "npm:^1.0.2" + get-stream: "npm:^5.1.0" + http-cache-semantics: "npm:^4.0.0" + keyv: "npm:^4.0.0" + lowercase-keys: "npm:^2.0.0" + normalize-url: "npm:^6.0.1" + responselike: "npm:^2.0.0" + checksum: 0f4f2001260ecca78b9f64fc8245e6b5a5dcde24ea53006daab71f5e0e1338095aa1512ec099c4f9895a9e5acfac9da423cb7c079e131485891e9214aca46c41 + languageName: node + linkType: hard + +"chalk@npm:^5.3.0": + version: 5.3.0 + resolution: "chalk@npm:5.3.0" + checksum: 6373caaab21bd64c405bfc4bd9672b145647fc9482657b5ea1d549b3b2765054e9d3d928870cdf764fb4aad67555f5061538ff247b8310f110c5c888d92397ea + languageName: node + linkType: hard + +"chownr@npm:^2.0.0": + version: 2.0.0 + resolution: "chownr@npm:2.0.0" + checksum: c57cf9dd0791e2f18a5ee9c1a299ae6e801ff58fee96dc8bfd0dcb4738a6ce58dd252a3605b1c93c6418fe4f9d5093b28ffbf4d66648cb2a9c67eaef9679be2f + languageName: node + linkType: hard + +"clean-stack@npm:^2.0.0": + version: 2.2.0 + resolution: "clean-stack@npm:2.2.0" + checksum: 2ac8cd2b2f5ec986a3c743935ec85b07bc174d5421a5efc8017e1f146a1cf5f781ae962618f416352103b32c9cd7e203276e8c28241bbe946160cab16149fb68 + languageName: node + linkType: hard + +"clone-response@npm:^1.0.2": + version: 1.0.3 + resolution: "clone-response@npm:1.0.3" + dependencies: + mimic-response: "npm:^1.0.0" + checksum: 4e671cac39b11c60aa8ba0a450657194a5d6504df51bca3fac5b3bd0145c4f8e8464898f87c8406b83232e3bc5cca555f51c1f9c8ac023969ebfbf7f6bdabb2e + languageName: node + linkType: hard + +"color-convert@npm:^2.0.1": + version: 2.0.1 + resolution: "color-convert@npm:2.0.1" + dependencies: + color-name: "npm:~1.1.4" + checksum: fa00c91b4332b294de06b443923246bccebe9fab1b253f7fe1772d37b06a2269b4039a85e309abe1fe11b267b11c08d1d0473fda3badd6167f57313af2887a64 + languageName: node + linkType: hard + +"color-name@npm:~1.1.4": + version: 1.1.4 + resolution: "color-name@npm:1.1.4" + checksum: b0445859521eb4021cd0fb0cc1a75cecf67fceecae89b63f62b201cca8d345baf8b952c966862a9d9a2632987d4f6581f0ec8d957dfacece86f0a7919316f610 + languageName: node + linkType: hard + +"commander@npm:^8.3.0": + version: 8.3.0 + resolution: "commander@npm:8.3.0" + checksum: 6b7b5d334483ce24bd73c5dac2eab901a7dbb25fd983ea24a1eeac6e7166bb1967f641546e8abf1920afbde86a45fbfe5812fbc69d0dc451bb45ca416a12a3a3 + languageName: node + linkType: hard + +"content-disposition@npm:^0.5.4": + version: 0.5.4 + resolution: "content-disposition@npm:0.5.4" + dependencies: + safe-buffer: "npm:5.2.1" + checksum: b7f4ce176e324f19324be69b05bf6f6e411160ac94bc523b782248129eb1ef3be006f6cff431aaea5e337fe5d176ce8830b8c2a1b721626ead8933f0cbe78720 + languageName: node + linkType: hard + +"cross-spawn@npm:^5.0.1": + version: 5.1.0 + resolution: "cross-spawn@npm:5.1.0" + dependencies: + lru-cache: "npm:^4.0.1" + shebang-command: "npm:^1.2.0" + which: "npm:^1.2.9" + checksum: 726939c9954fc70c20e538923feaaa33bebc253247d13021737c3c7f68cdc3e0a57f720c0fe75057c0387995349f3f12e20e9bfdbf12274db28019c7ea4ec166 + languageName: node + linkType: hard + +"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.3": + version: 7.0.3 + resolution: "cross-spawn@npm:7.0.3" + dependencies: + path-key: "npm:^3.1.0" + shebang-command: "npm:^2.0.0" + which: "npm:^2.0.1" + checksum: e1a13869d2f57d974de0d9ef7acbf69dc6937db20b918525a01dacb5032129bd552d290d886d981e99f1b624cb03657084cc87bd40f115c07ecf376821c729ce + languageName: node + linkType: hard + +"dd-minimal-bot@workspace:.": + version: 0.0.0-use.local + resolution: "dd-minimal-bot@workspace:." + dependencies: + "@discordeno/bot": "npm:19.0.0-next.92bf166" + "@swc/cli": "npm:^0.3.12" + "@swc/core": "npm:^1.6.3" + "@types/node": "npm:^20.14.6" + chalk: "npm:^5.3.0" + dotenv: "npm:^16.4.5" + typescript: "npm:^5.5.2" + languageName: unknown + linkType: soft + +"debug@npm:4, debug@npm:^4.3.4": + version: 4.3.5 + resolution: "debug@npm:4.3.5" + dependencies: + ms: "npm:2.1.2" + peerDependenciesMeta: + supports-color: + optional: true + checksum: cb6eab424c410e07813ca1392888589972ce9a32b8829c6508f5e1f25f3c3e70a76731610ae55b4bbe58d1a2fffa1424b30e97fa8d394e49cd2656a9643aedd2 + languageName: node + linkType: hard + +"decompress-response@npm:^6.0.0": + version: 6.0.0 + resolution: "decompress-response@npm:6.0.0" + dependencies: + mimic-response: "npm:^3.1.0" + checksum: d377cf47e02d805e283866c3f50d3d21578b779731e8c5072d6ce8c13cc31493db1c2f6784da9d1d5250822120cefa44f1deab112d5981015f2e17444b763812 + languageName: node + linkType: hard + +"defer-to-connect@npm:^2.0.0": + version: 2.0.1 + resolution: "defer-to-connect@npm:2.0.1" + checksum: 8a9b50d2f25446c0bfefb55a48e90afd58f85b21bcf78e9207cd7b804354f6409032a1705c2491686e202e64fc05f147aa5aa45f9aa82627563f045937f5791b + languageName: node + linkType: hard + +"dotenv@npm:^16.4.5": + version: 16.4.5 + resolution: "dotenv@npm:16.4.5" + checksum: 55a3134601115194ae0f924e54473459ed0d9fc340ae610b676e248cca45aa7c680d86365318ea964e6da4e2ea80c4514c1adab5adb43d6867fb57ff068f95c8 + languageName: node + linkType: hard + +"eastasianwidth@npm:^0.2.0": + version: 0.2.0 + resolution: "eastasianwidth@npm:0.2.0" + checksum: 9b1d3e1baefeaf7d70799db8774149cef33b97183a6addceeba0cf6b85ba23ee2686f302f14482006df32df75d32b17c509c143a3689627929e4a8efaf483952 + languageName: node + linkType: hard + +"emoji-regex@npm:^8.0.0": + version: 8.0.0 + resolution: "emoji-regex@npm:8.0.0" + checksum: c72d67a6821be15ec11997877c437491c313d924306b8da5d87d2a2bcc2cec9903cb5b04ee1a088460501d8e5b44f10df82fdc93c444101a7610b80c8b6938e1 + languageName: node + linkType: hard + +"emoji-regex@npm:^9.2.2": + version: 9.2.2 + resolution: "emoji-regex@npm:9.2.2" + checksum: 915acf859cea7131dac1b2b5c9c8e35c4849e325a1d114c30adb8cd615970f6dca0e27f64f3a4949d7d6ed86ecd79a1c5c63f02e697513cddd7b5835c90948b8 + languageName: node + linkType: hard + +"encoding@npm:^0.1.13": + version: 0.1.13 + resolution: "encoding@npm:0.1.13" + dependencies: + iconv-lite: "npm:^0.6.2" + checksum: bb98632f8ffa823996e508ce6a58ffcf5856330fde839ae42c9e1f436cc3b5cc651d4aeae72222916545428e54fd0f6aa8862fd8d25bdbcc4589f1e3f3715e7f + languageName: node + linkType: hard + +"end-of-stream@npm:^1.1.0": + version: 1.4.4 + resolution: "end-of-stream@npm:1.4.4" + dependencies: + once: "npm:^1.4.0" + checksum: 530a5a5a1e517e962854a31693dbb5c0b2fc40b46dad2a56a2deec656ca040631124f4795823acc68238147805f8b021abbe221f4afed5ef3c8e8efc2024908b + languageName: node + linkType: hard + +"env-paths@npm:^2.2.0": + version: 2.2.1 + resolution: "env-paths@npm:2.2.1" + checksum: 65b5df55a8bab92229ab2b40dad3b387fad24613263d103a97f91c9fe43ceb21965cd3392b1ccb5d77088021e525c4e0481adb309625d0cb94ade1d1fb8dc17e + languageName: node + linkType: hard + +"err-code@npm:^2.0.2": + version: 2.0.3 + resolution: "err-code@npm:2.0.3" + checksum: 1d20d825cdcce8d811bfbe86340f4755c02655a7feb2f13f8c880566d9d72a3f6c92c192a6867632e490d6da67b678271f46e01044996a6443e870331100dfdd + languageName: node + linkType: hard + +"escape-string-regexp@npm:^5.0.0": + version: 5.0.0 + resolution: "escape-string-regexp@npm:5.0.0" + checksum: 20daabe197f3cb198ec28546deebcf24b3dbb1a5a269184381b3116d12f0532e06007f4bc8da25669d6a7f8efb68db0758df4cd981f57bc5b57f521a3e12c59e + languageName: node + linkType: hard + +"execa@npm:^0.7.0": + version: 0.7.0 + resolution: "execa@npm:0.7.0" + dependencies: + cross-spawn: "npm:^5.0.1" + get-stream: "npm:^3.0.0" + is-stream: "npm:^1.1.0" + npm-run-path: "npm:^2.0.0" + p-finally: "npm:^1.0.0" + signal-exit: "npm:^3.0.0" + strip-eof: "npm:^1.0.0" + checksum: 7c1721de38e51d67cef2367b1f6037c4a89bc64993d93683f9f740fc74d6930dfc92faf2749b917b7337a8d632d7b86a4673400f762bc1fe4a977ea6b0f9055f + languageName: node + linkType: hard + +"execa@npm:^5.0.0": + version: 5.1.1 + resolution: "execa@npm:5.1.1" + dependencies: + cross-spawn: "npm:^7.0.3" + get-stream: "npm:^6.0.0" + human-signals: "npm:^2.1.0" + is-stream: "npm:^2.0.0" + merge-stream: "npm:^2.0.0" + npm-run-path: "npm:^4.0.1" + onetime: "npm:^5.1.2" + signal-exit: "npm:^3.0.3" + strip-final-newline: "npm:^2.0.0" + checksum: 8ada91f2d70f7dff702c861c2c64f21dfdc1525628f3c0454fd6f02fce65f7b958616cbd2b99ca7fa4d474e461a3d363824e91b3eb881705231abbf387470597 + languageName: node + linkType: hard + +"executable@npm:^4.1.0": + version: 4.1.1 + resolution: "executable@npm:4.1.1" + dependencies: + pify: "npm:^2.2.0" + checksum: f01927ce59bccec804e171bf859a26e362c1f50aa9ebc69f7cafdcce3859d29d4b6267fd47237c18b0a1830614bd3f0ee14b7380d9bad18a4e7af9b5f0b6984f + languageName: node + linkType: hard + +"exponential-backoff@npm:^3.1.1": + version: 3.1.1 + resolution: "exponential-backoff@npm:3.1.1" + checksum: 2d9bbb6473de7051f96790d5f9a678f32e60ed0aa70741dc7fdc96fec8d631124ec3374ac144387604f05afff9500f31a1d45bd9eee4cdc2e4f9ad2d9b9d5dbd + languageName: node + linkType: hard + +"ext-list@npm:^2.0.0": + version: 2.2.2 + resolution: "ext-list@npm:2.2.2" + dependencies: + mime-db: "npm:^1.28.0" + checksum: fe69fedbef044e14d4ce9e84c6afceb696ba71500c15b8d0ce0a1e280237e17c95031b3d62d5e597652fea0065b9bf957346b3900d989dff59128222231ac859 + languageName: node + linkType: hard + +"ext-name@npm:^5.0.0": + version: 5.0.0 + resolution: "ext-name@npm:5.0.0" + dependencies: + ext-list: "npm:^2.0.0" + sort-keys-length: "npm:^1.0.0" + checksum: f598269bd5de4295540ea7d6f8f6a01d82a7508f148b7700a05628ef6121648d26e6e5e942049e953b3051863df6b54bd8fe951e7877f185e34ace5d44370b33 + languageName: node + linkType: hard + +"fast-glob@npm:^3.2.5": + version: 3.3.2 + resolution: "fast-glob@npm:3.3.2" + dependencies: + "@nodelib/fs.stat": "npm:^2.0.2" + "@nodelib/fs.walk": "npm:^1.2.3" + glob-parent: "npm:^5.1.2" + merge2: "npm:^1.3.0" + micromatch: "npm:^4.0.4" + checksum: 222512e9315a0efca1276af9adb2127f02105d7288fa746145bf45e2716383fb79eb983c89601a72a399a56b7c18d38ce70457c5466218c5f13fad957cee16df + languageName: node + linkType: hard + +"fastq@npm:^1.6.0": + version: 1.17.1 + resolution: "fastq@npm:1.17.1" + dependencies: + reusify: "npm:^1.0.4" + checksum: a443180068b527dd7b3a63dc7f2a47ceca2f3e97b9c00a1efe5538757e6cc4056a3526df94308075d7727561baf09ebaa5b67da8dcbddb913a021c5ae69d1f69 + languageName: node + linkType: hard + +"file-type@npm:^17.1.6": + version: 17.1.6 + resolution: "file-type@npm:17.1.6" + dependencies: + readable-web-to-node-stream: "npm:^3.0.2" + strtok3: "npm:^7.0.0-alpha.9" + token-types: "npm:^5.0.0-alpha.2" + checksum: 47c69b4046e31142492a135982b9a9e4873b368919a2e66d0ebdc04143b6d2e1225b4bec820668c442ef201b54d03569df08b6052edc6015b1022c236784e1c1 + languageName: node + linkType: hard + +"filename-reserved-regex@npm:^3.0.0": + version: 3.0.0 + resolution: "filename-reserved-regex@npm:3.0.0" + checksum: 1803e19ce64d7cb88ee5a1bd3ce282470a5c263987269222426d889049fc857e302284fa71937de9582eba7a9f39539557d45e0562f2fa51cade8efc68c65dd9 + languageName: node + linkType: hard + +"filenamify@npm:^5.0.2": + version: 5.1.1 + resolution: "filenamify@npm:5.1.1" + dependencies: + filename-reserved-regex: "npm:^3.0.0" + strip-outer: "npm:^2.0.0" + trim-repeated: "npm:^2.0.0" + checksum: 55a7ed0858eb2655bb1bb1e945a59e3fb30ba4767f6924fa064ccd731bff07678aac3cb4f3899ae0e1621fe81d6472b5688232bb6afd4eeb989ade785fc1c6f1 + languageName: node + linkType: hard + +"fill-range@npm:^7.1.1": + version: 7.1.1 + resolution: "fill-range@npm:7.1.1" + dependencies: + to-regex-range: "npm:^5.0.1" + checksum: a7095cb39e5bc32fada2aa7c7249d3f6b01bd1ce461a61b0adabacccabd9198500c6fb1f68a7c851a657e273fce2233ba869638897f3d7ed2e87a2d89b4436ea + languageName: node + linkType: hard + +"find-versions@npm:^5.0.0": + version: 5.1.0 + resolution: "find-versions@npm:5.1.0" + dependencies: + semver-regex: "npm:^4.0.5" + checksum: 680bdb0081f631f7bfb6f0f8edcfa0b74ab8cabc82097a4527a37b0d042aabc56685bf459ff27991eab0baddc04eb8e3bba8a2869f5004ecf7cdd2779b6e51de + languageName: node + linkType: hard + +"foreground-child@npm:^3.1.0": + version: 3.1.1 + resolution: "foreground-child@npm:3.1.1" + dependencies: + cross-spawn: "npm:^7.0.0" + signal-exit: "npm:^4.0.1" + checksum: 087edd44857d258c4f73ad84cb8df980826569656f2550c341b27adf5335354393eec24ea2fabd43a253233fb27cee177ebe46bd0b7ea129c77e87cb1e9936fb + languageName: node + linkType: hard + +"fs-minipass@npm:^2.0.0": + version: 2.1.0 + resolution: "fs-minipass@npm:2.1.0" + dependencies: + minipass: "npm:^3.0.0" + checksum: 03191781e94bc9a54bd376d3146f90fe8e082627c502185dbf7b9b3032f66b0b142c1115f3b2cc5936575fc1b44845ce903dd4c21bec2a8d69f3bd56f9cee9ec + languageName: node + linkType: hard + +"fs-minipass@npm:^3.0.0": + version: 3.0.3 + resolution: "fs-minipass@npm:3.0.3" + dependencies: + minipass: "npm:^7.0.3" + checksum: af143246cf6884fe26fa281621d45cfe111d34b30535a475bfa38dafe343dadb466c047a924ffc7d6b7b18265df4110224ce3803806dbb07173bf2087b648d7f + languageName: node + linkType: hard + +"get-stream@npm:^3.0.0": + version: 3.0.0 + resolution: "get-stream@npm:3.0.0" + checksum: de14fbb3b4548ace9ab6376be852eef9898c491282e29595bc908a1814a126d3961b11cd4b7be5220019fe3b2abb84568da7793ad308fc139925a217063fa159 + languageName: node + linkType: hard + +"get-stream@npm:^5.1.0": + version: 5.2.0 + resolution: "get-stream@npm:5.2.0" + dependencies: + pump: "npm:^3.0.0" + checksum: 13a73148dca795e41421013da6e3ebff8ccb7fba4d2f023fd0c6da2c166ec4e789bec9774a73a7b49c08daf2cae552f8a3e914042ac23b5f59dd278cc8f9cbfb + languageName: node + linkType: hard + +"get-stream@npm:^6.0.0": + version: 6.0.1 + resolution: "get-stream@npm:6.0.1" + checksum: 781266d29725f35c59f1d214aedc92b0ae855800a980800e2923b3fbc4e56b3cb6e462c42e09a1cf1a00c64e056a78fa407cbe06c7c92b7e5cd49b4b85c2a497 + languageName: node + linkType: hard + +"glob-parent@npm:^5.1.2": + version: 5.1.2 + resolution: "glob-parent@npm:5.1.2" + dependencies: + is-glob: "npm:^4.0.1" + checksum: 32cd106ce8c0d83731966d31517adb766d02c3812de49c30cfe0675c7c0ae6630c11214c54a5ae67aca882cf738d27fd7768f21aa19118b9245950554be07247 + languageName: node + linkType: hard + +"glob@npm:^10.2.2, glob@npm:^10.3.10": + version: 10.4.1 + resolution: "glob@npm:10.4.1" + dependencies: + foreground-child: "npm:^3.1.0" + jackspeak: "npm:^3.1.2" + minimatch: "npm:^9.0.4" + minipass: "npm:^7.1.2" + path-scurry: "npm:^1.11.1" + bin: + glob: dist/esm/bin.mjs + checksum: d7bb49d2b413f77bdd59fea4ca86dcc12450deee221af0ca93e09534b81b9ef68fe341345751d8ff0c5b54bad422307e0e44266ff8ad7fbbd0c200e8ec258b16 + languageName: node + linkType: hard + +"got@npm:^11.8.5": + version: 11.8.6 + resolution: "got@npm:11.8.6" + dependencies: + "@sindresorhus/is": "npm:^4.0.0" + "@szmarczak/http-timer": "npm:^4.0.5" + "@types/cacheable-request": "npm:^6.0.1" + "@types/responselike": "npm:^1.0.0" + cacheable-lookup: "npm:^5.0.3" + cacheable-request: "npm:^7.0.2" + decompress-response: "npm:^6.0.0" + http2-wrapper: "npm:^1.0.0-beta.5.2" + lowercase-keys: "npm:^2.0.0" + p-cancelable: "npm:^2.0.0" + responselike: "npm:^2.0.0" + checksum: a30c74029d81bd5fe50dea1a0c970595d792c568e188ff8be254b5bc11e6158d1b014570772d4a30d0a97723e7dd34e7c8cc1a2f23018f60aece3070a7a5c2a5 + languageName: node + linkType: hard + +"graceful-fs@npm:^4.2.6": + version: 4.2.11 + resolution: "graceful-fs@npm:4.2.11" + checksum: bf152d0ed1dc159239db1ba1f74fdbc40cb02f626770dcd5815c427ce0688c2635a06ed69af364396da4636d0408fcf7d4afdf7881724c3307e46aff30ca49e2 + languageName: node + linkType: hard + +"http-cache-semantics@npm:^4.0.0, http-cache-semantics@npm:^4.1.1": + version: 4.1.1 + resolution: "http-cache-semantics@npm:4.1.1" + checksum: 362d5ed66b12ceb9c0a328fb31200b590ab1b02f4a254a697dc796850cc4385603e75f53ec59f768b2dad3bfa1464bd229f7de278d2899a0e3beffc634b6683f + languageName: node + linkType: hard + +"http-proxy-agent@npm:^7.0.0": + version: 7.0.2 + resolution: "http-proxy-agent@npm:7.0.2" + dependencies: + agent-base: "npm:^7.1.0" + debug: "npm:^4.3.4" + checksum: d062acfa0cb82beeb558f1043c6ba770ea892b5fb7b28654dbc70ea2aeea55226dd34c02a294f6c1ca179a5aa483c4ea641846821b182edbd9cc5d89b54c6848 + languageName: node + linkType: hard + +"http2-wrapper@npm:^1.0.0-beta.5.2": + version: 1.0.3 + resolution: "http2-wrapper@npm:1.0.3" + dependencies: + quick-lru: "npm:^5.1.1" + resolve-alpn: "npm:^1.0.0" + checksum: 8097ee2699440c2e64bda52124990cc5b0fb347401c7797b1a0c1efd5a0f79a4ebaa68e8a6ac3e2dde5f09460c1602764da6da2412bad628ed0a3b0ae35e72d4 + languageName: node + linkType: hard + +"https-proxy-agent@npm:^7.0.1": + version: 7.0.4 + resolution: "https-proxy-agent@npm:7.0.4" + dependencies: + agent-base: "npm:^7.0.2" + debug: "npm:4" + checksum: 405fe582bba461bfe5c7e2f8d752b384036854488b828ae6df6a587c654299cbb2c50df38c4b6ab303502c3c5e029a793fbaac965d1e86ee0be03faceb554d63 + languageName: node + linkType: hard + +"human-signals@npm:^2.1.0": + version: 2.1.0 + resolution: "human-signals@npm:2.1.0" + checksum: df59be9e0af479036798a881d1f136c4a29e0b518d4abb863afbd11bf30efa3eeb1d0425fc65942dcc05ab3bf40205ea436b0ff389f2cd20b75b8643d539bf86 + languageName: node + linkType: hard + +"iconv-lite@npm:^0.6.2": + version: 0.6.3 + resolution: "iconv-lite@npm:0.6.3" + dependencies: + safer-buffer: "npm:>= 2.1.2 < 3.0.0" + checksum: 24e3292dd3dadaa81d065c6f8c41b274a47098150d444b96e5f53b4638a9a71482921ea6a91a1f59bb71d9796de25e04afd05919fa64c360347ba65d3766f10f + languageName: node + linkType: hard + +"ieee754@npm:^1.2.1": + version: 1.2.1 + resolution: "ieee754@npm:1.2.1" + checksum: d9f2557a59036f16c282aaeb107832dc957a93d73397d89bbad4eb1130560560eb695060145e8e6b3b498b15ab95510226649a0b8f52ae06583575419fe10fc4 + languageName: node + linkType: hard + +"imurmurhash@npm:^0.1.4": + version: 0.1.4 + resolution: "imurmurhash@npm:0.1.4" + checksum: 2d30b157a91fe1c1d7c6f653cbf263f039be6c5bfa959245a16d4ee191fc0f2af86c08545b6e6beeb041c56b574d2d5b9f95343d378ab49c0f37394d541e7fc8 + languageName: node + linkType: hard + +"indent-string@npm:^4.0.0": + version: 4.0.0 + resolution: "indent-string@npm:4.0.0" + checksum: cd3f5cbc9ca2d624c6a1f53f12e6b341659aba0e2d3254ae2b4464aaea8b4294cdb09616abbc59458f980531f2429784ed6a420d48d245bcad0811980c9efae9 + languageName: node + linkType: hard + +"inherits@npm:^2.0.3": + version: 2.0.4 + resolution: "inherits@npm:2.0.4" + checksum: cd45e923bee15186c07fa4c89db0aace24824c482fb887b528304694b2aa6ff8a898da8657046a5dcf3e46cd6db6c61629551f9215f208d7c3f157cf9b290521 + languageName: node + linkType: hard + +"ip-address@npm:^9.0.5": + version: 9.0.5 + resolution: "ip-address@npm:9.0.5" + dependencies: + jsbn: "npm:1.1.0" + sprintf-js: "npm:^1.1.3" + checksum: 1ed81e06721af012306329b31f532b5e24e00cb537be18ddc905a84f19fe8f83a09a1699862bf3a1ec4b9dea93c55a3fa5faf8b5ea380431469df540f38b092c + languageName: node + linkType: hard + +"is-extglob@npm:^2.1.1": + version: 2.1.1 + resolution: "is-extglob@npm:2.1.1" + checksum: df033653d06d0eb567461e58a7a8c9f940bd8c22274b94bf7671ab36df5719791aae15eef6d83bbb5e23283967f2f984b8914559d4449efda578c775c4be6f85 + languageName: node + linkType: hard + +"is-fullwidth-code-point@npm:^3.0.0": + version: 3.0.0 + resolution: "is-fullwidth-code-point@npm:3.0.0" + checksum: 44a30c29457c7fb8f00297bce733f0a64cd22eca270f83e58c105e0d015e45c019491a4ab2faef91ab51d4738c670daff901c799f6a700e27f7314029e99e348 + languageName: node + linkType: hard + +"is-glob@npm:^4.0.1": + version: 4.0.3 + resolution: "is-glob@npm:4.0.3" + dependencies: + is-extglob: "npm:^2.1.1" + checksum: 3ed74f2b0cdf4f401f38edb0442ddfde3092d79d7d35c9919c86641efdbcbb32e45aa3c0f70ce5eecc946896cd5a0f26e4188b9f2b881876f7cb6c505b82da11 + languageName: node + linkType: hard + +"is-lambda@npm:^1.0.1": + version: 1.0.1 + resolution: "is-lambda@npm:1.0.1" + checksum: 93a32f01940220532e5948538699ad610d5924ac86093fcee83022252b363eb0cc99ba53ab084a04e4fb62bf7b5731f55496257a4c38adf87af9c4d352c71c35 + languageName: node + linkType: hard + +"is-number@npm:^7.0.0": + version: 7.0.0 + resolution: "is-number@npm:7.0.0" + checksum: 6a6c3383f68afa1e05b286af866017c78f1226d43ac8cb064e115ff9ed85eb33f5c4f7216c96a71e4dfea289ef52c5da3aef5bbfade8ffe47a0465d70c0c8e86 + languageName: node + linkType: hard + +"is-plain-obj@npm:^1.0.0": + version: 1.1.0 + resolution: "is-plain-obj@npm:1.1.0" + checksum: 0ee04807797aad50859652a7467481816cbb57e5cc97d813a7dcd8915da8195dc68c436010bf39d195226cde6a2d352f4b815f16f26b7bf486a5754290629931 + languageName: node + linkType: hard + +"is-stream@npm:^1.1.0": + version: 1.1.0 + resolution: "is-stream@npm:1.1.0" + checksum: 351aa77c543323c4e111204482808cfad68d2e940515949e31ccd0b010fc13d5fba4b9c230e4887fd24284713040f43e542332fbf172f6b9944b7d62e389c0ec + languageName: node + linkType: hard + +"is-stream@npm:^2.0.0": + version: 2.0.1 + resolution: "is-stream@npm:2.0.1" + checksum: b8e05ccdf96ac330ea83c12450304d4a591f9958c11fd17bed240af8d5ffe08aedafa4c0f4cfccd4d28dc9d4d129daca1023633d5c11601a6cbc77521f6fae66 + languageName: node + linkType: hard + +"isexe@npm:^2.0.0": + version: 2.0.0 + resolution: "isexe@npm:2.0.0" + checksum: 7c9f715c03aff08f35e98b1fadae1b9267b38f0615d501824f9743f3aab99ef10e303ce7db3f186763a0b70a19de5791ebfc854ff884d5a8c4d92211f642ec92 + languageName: node + linkType: hard + +"isexe@npm:^3.1.1": + version: 3.1.1 + resolution: "isexe@npm:3.1.1" + checksum: 7fe1931ee4e88eb5aa524cd3ceb8c882537bc3a81b02e438b240e47012eef49c86904d0f0e593ea7c3a9996d18d0f1f3be8d3eaa92333977b0c3a9d353d5563e + languageName: node + linkType: hard + +"jackspeak@npm:^3.1.2": + version: 3.3.0 + resolution: "jackspeak@npm:3.3.0" + dependencies: + "@isaacs/cliui": "npm:^8.0.2" + "@pkgjs/parseargs": "npm:^0.11.0" + dependenciesMeta: + "@pkgjs/parseargs": + optional: true + checksum: 8a72147e68cfbb8714fff4305a8b2efe02ae7ac81116355132740156973f6e520e339f8e23b01834d9f9431afd3e4616e4613f66571e0b13b9d0d52c65d3d633 + languageName: node + linkType: hard + +"jsbn@npm:1.1.0": + version: 1.1.0 + resolution: "jsbn@npm:1.1.0" + checksum: bebe7ae829bbd586ce8cbe83501dd8cb8c282c8902a8aeeed0a073a89dc37e8103b1244f3c6acd60278bcbfe12d93a3f83c9ac396868a3b3bbc3c5e5e3b648ef + languageName: node + linkType: hard + +"json-buffer@npm:3.0.1": + version: 3.0.1 + resolution: "json-buffer@npm:3.0.1" + checksum: 82876154521b7b68ba71c4f969b91572d1beabadd87bd3a6b236f85fbc7dc4695089191ed60bb59f9340993c51b33d479f45b6ba9f3548beb519705281c32c3c + languageName: node + linkType: hard + +"keyv@npm:^4.0.0": + version: 4.5.4 + resolution: "keyv@npm:4.5.4" + dependencies: + json-buffer: "npm:3.0.1" + checksum: 167eb6ef64cc84b6fa0780ee50c9de456b422a1e18802209234f7c2cf7eae648c7741f32e50d7e24ccb22b24c13154070b01563d642755b156c357431a191e75 + languageName: node + linkType: hard + +"lowercase-keys@npm:^2.0.0": + version: 2.0.0 + resolution: "lowercase-keys@npm:2.0.0" + checksum: 1c233d2da35056e8c49fae8097ee061b8c799b2f02e33c2bf32f9913c7de8fb481ab04dab7df35e94156c800f5f34e99acbf32b21781d87c3aa43ef7b748b79e + languageName: node + linkType: hard + +"lru-cache@npm:^10.0.1, lru-cache@npm:^10.2.0": + version: 10.2.2 + resolution: "lru-cache@npm:10.2.2" + checksum: ff1a496d30b5eaec2c9079080965bb0cede203cf878371f7033a007f1e54cd4aa13cc8abf7ccec4c994a83a22ed5476e83a55bb57cc07e6c1547a42937e42c37 + languageName: node + linkType: hard + +"lru-cache@npm:^4.0.1": + version: 4.1.5 + resolution: "lru-cache@npm:4.1.5" + dependencies: + pseudomap: "npm:^1.0.2" + yallist: "npm:^2.1.2" + checksum: 9ec7d73f11a32cba0e80b7a58fdf29970814c0c795acaee1a6451ddfd609bae6ef9df0837f5bbeabb571ecd49c1e2d79e10e9b4ed422cfba17a0cb6145b018a9 + languageName: node + linkType: hard + +"make-fetch-happen@npm:^13.0.0": + version: 13.0.1 + resolution: "make-fetch-happen@npm:13.0.1" + dependencies: + "@npmcli/agent": "npm:^2.0.0" + cacache: "npm:^18.0.0" + http-cache-semantics: "npm:^4.1.1" + is-lambda: "npm:^1.0.1" + minipass: "npm:^7.0.2" + minipass-fetch: "npm:^3.0.0" + minipass-flush: "npm:^1.0.5" + minipass-pipeline: "npm:^1.2.4" + negotiator: "npm:^0.6.3" + proc-log: "npm:^4.2.0" + promise-retry: "npm:^2.0.1" + ssri: "npm:^10.0.0" + checksum: 11bae5ad6ac59b654dbd854f30782f9de052186c429dfce308eda42374528185a100ee40ac9ffdc36a2b6c821ecaba43913e4730a12f06f15e895ea9cb23fa59 + languageName: node + linkType: hard + +"merge-stream@npm:^2.0.0": + version: 2.0.0 + resolution: "merge-stream@npm:2.0.0" + checksum: 6fa4dcc8d86629705cea944a4b88ef4cb0e07656ebf223fa287443256414283dd25d91c1cd84c77987f2aec5927af1a9db6085757cb43d90eb170ebf4b47f4f4 + languageName: node + linkType: hard + +"merge2@npm:^1.3.0": + version: 1.4.1 + resolution: "merge2@npm:1.4.1" + checksum: 7268db63ed5169466540b6fb947aec313200bcf6d40c5ab722c22e242f651994619bcd85601602972d3c85bd2cc45a358a4c61937e9f11a061919a1da569b0c2 + languageName: node + linkType: hard + +"micromatch@npm:^4.0.4": + version: 4.0.7 + resolution: "micromatch@npm:4.0.7" + dependencies: + braces: "npm:^3.0.3" + picomatch: "npm:^2.3.1" + checksum: a11ed1cb67dcbbe9a5fc02c4062cf8bb0157d73bf86956003af8dcfdf9b287f9e15ec0f6d6925ff6b8b5b496202335e497b01de4d95ef6cf06411bc5e5c474a0 + languageName: node + linkType: hard + +"mime-db@npm:^1.28.0": + version: 1.52.0 + resolution: "mime-db@npm:1.52.0" + checksum: 54bb60bf39e6f8689f6622784e668a3d7f8bed6b0d886f5c3c446cb3284be28b30bf707ed05d0fe44a036f8469976b2629bbea182684977b084de9da274694d7 + languageName: node + linkType: hard + +"mimic-fn@npm:^2.1.0": + version: 2.1.0 + resolution: "mimic-fn@npm:2.1.0" + checksum: d2421a3444848ce7f84bd49115ddacff29c15745db73f54041edc906c14b131a38d05298dae3081667627a59b2eb1ca4b436ff2e1b80f69679522410418b478a + languageName: node + linkType: hard + +"mimic-response@npm:^1.0.0": + version: 1.0.1 + resolution: "mimic-response@npm:1.0.1" + checksum: 034c78753b0e622bc03c983663b1cdf66d03861050e0c8606563d149bc2b02d63f62ce4d32be4ab50d0553ae0ffe647fc34d1f5281184c6e1e8cf4d85e8d9823 + languageName: node + linkType: hard + +"mimic-response@npm:^3.1.0": + version: 3.1.0 + resolution: "mimic-response@npm:3.1.0" + checksum: 7e719047612411fe071332a7498cf0448bbe43c485c0d780046c76633a771b223ff49bd00267be122cedebb897037fdb527df72335d0d0f74724604ca70b37ad + languageName: node + linkType: hard + +"minimatch@npm:^9.0.3, minimatch@npm:^9.0.4": + version: 9.0.4 + resolution: "minimatch@npm:9.0.4" + dependencies: + brace-expansion: "npm:^2.0.1" + checksum: 4cdc18d112b164084513e890d6323370db14c22249d536ad1854539577a895e690a27513dc346392f61a4a50afbbd8abc88f3f25558bfbbbb862cd56508b20f5 + languageName: node + linkType: hard + +"minipass-collect@npm:^2.0.1": + version: 2.0.1 + resolution: "minipass-collect@npm:2.0.1" + dependencies: + minipass: "npm:^7.0.3" + checksum: b251bceea62090f67a6cced7a446a36f4cd61ee2d5cea9aee7fff79ba8030e416327a1c5aa2908dc22629d06214b46d88fdab8c51ac76bacbf5703851b5ad342 + languageName: node + linkType: hard + +"minipass-fetch@npm:^3.0.0": + version: 3.0.5 + resolution: "minipass-fetch@npm:3.0.5" + dependencies: + encoding: "npm:^0.1.13" + minipass: "npm:^7.0.3" + minipass-sized: "npm:^1.0.3" + minizlib: "npm:^2.1.2" + dependenciesMeta: + encoding: + optional: true + checksum: c669948bec1373313aaa8f104b962a3ced9f45c49b26366a4b0ae27ccdfa9c5740d72c8a84d3f8623d7a61c5fc7afdfda44789008c078f61a62441142efc4a97 + languageName: node + linkType: hard + +"minipass-flush@npm:^1.0.5": + version: 1.0.5 + resolution: "minipass-flush@npm:1.0.5" + dependencies: + minipass: "npm:^3.0.0" + checksum: 56269a0b22bad756a08a94b1ffc36b7c9c5de0735a4dd1ab2b06c066d795cfd1f0ac44a0fcae13eece5589b908ecddc867f04c745c7009be0b566421ea0944cf + languageName: node + linkType: hard + +"minipass-pipeline@npm:^1.2.4": + version: 1.2.4 + resolution: "minipass-pipeline@npm:1.2.4" + dependencies: + minipass: "npm:^3.0.0" + checksum: b14240dac0d29823c3d5911c286069e36d0b81173d7bdf07a7e4a91ecdef92cdff4baaf31ea3746f1c61e0957f652e641223970870e2353593f382112257971b + languageName: node + linkType: hard + +"minipass-sized@npm:^1.0.3": + version: 1.0.3 + resolution: "minipass-sized@npm:1.0.3" + dependencies: + minipass: "npm:^3.0.0" + checksum: 40982d8d836a52b0f37049a0a7e5d0f089637298e6d9b45df9c115d4f0520682a78258905e5c8b180fb41b593b0a82cc1361d2c74b45f7ada66334f84d1ecfdd + languageName: node + linkType: hard + +"minipass@npm:^3.0.0": + version: 3.3.6 + resolution: "minipass@npm:3.3.6" + dependencies: + yallist: "npm:^4.0.0" + checksum: a5c6ef069f70d9a524d3428af39f2b117ff8cd84172e19b754e7264a33df460873e6eb3d6e55758531580970de50ae950c496256bb4ad3691a2974cddff189f0 + languageName: node + linkType: hard + +"minipass@npm:^5.0.0": + version: 5.0.0 + resolution: "minipass@npm:5.0.0" + checksum: 61682162d29f45d3152b78b08bab7fb32ca10899bc5991ffe98afc18c9e9543bd1e3be94f8b8373ba6262497db63607079dc242ea62e43e7b2270837b7347c93 + languageName: node + linkType: hard + +"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.2, minipass@npm:^7.0.3, minipass@npm:^7.1.2": + version: 7.1.2 + resolution: "minipass@npm:7.1.2" + checksum: c25f0ee8196d8e6036661104bacd743785b2599a21de5c516b32b3fa2b83113ac89a2358465bc04956baab37ffb956ae43be679b2262bf7be15fce467ccd7950 + languageName: node + linkType: hard + +"minizlib@npm:^2.1.1, minizlib@npm:^2.1.2": + version: 2.1.2 + resolution: "minizlib@npm:2.1.2" + dependencies: + minipass: "npm:^3.0.0" + yallist: "npm:^4.0.0" + checksum: ae0f45436fb51344dcb87938446a32fbebb540d0e191d63b35e1c773d47512e17307bf54aa88326cc6d176594d00e4423563a091f7266c2f9a6872cdc1e234d1 + languageName: node + linkType: hard + +"mkdirp@npm:^1.0.3": + version: 1.0.4 + resolution: "mkdirp@npm:1.0.4" + bin: + mkdirp: bin/cmd.js + checksum: d71b8dcd4b5af2fe13ecf3bd24070263489404fe216488c5ba7e38ece1f54daf219e72a833a3a2dc404331e870e9f44963a33399589490956bff003a3404d3b2 + languageName: node + linkType: hard + +"ms@npm:2.1.2": + version: 2.1.2 + resolution: "ms@npm:2.1.2" + checksum: 673cdb2c3133eb050c745908d8ce632ed2c02d85640e2edb3ace856a2266a813b30c613569bf3354fdf4ea7d1a1494add3bfa95e2713baa27d0c2c71fc44f58f + languageName: node + linkType: hard + +"negotiator@npm:^0.6.3": + version: 0.6.3 + resolution: "negotiator@npm:0.6.3" + checksum: 2723fb822a17ad55c93a588a4bc44d53b22855bf4be5499916ca0cab1e7165409d0b288ba2577d7b029f10ce18cf2ed8e703e5af31c984e1e2304277ef979837 + languageName: node + linkType: hard + +"nice-napi@npm:^1.0.2": + version: 1.0.2 + resolution: "nice-napi@npm:1.0.2" + dependencies: + node-addon-api: "npm:^3.0.0" + node-gyp: "npm:latest" + node-gyp-build: "npm:^4.2.2" + conditions: "!os=win32" + languageName: node + linkType: hard + +"node-addon-api@npm:^3.0.0": + version: 3.2.1 + resolution: "node-addon-api@npm:3.2.1" + dependencies: + node-gyp: "npm:latest" + checksum: 681b52dfa3e15b0a8e5cf283cc0d8cd5fd2a57c559ae670fcfd20544cbb32f75de7648674110defcd17ab2c76ebef630aa7d2d2f930bc7a8cc439b20fe233518 + languageName: node + linkType: hard + +"node-gyp-build@npm:^4.2.2": + version: 4.8.1 + resolution: "node-gyp-build@npm:4.8.1" + bin: + node-gyp-build: bin.js + node-gyp-build-optional: optional.js + node-gyp-build-test: build-test.js + checksum: b9297770f96a92e5f2b854f3fd5e4bd418df81d7785a81ab60cec5cf2e5e72dc2c3319808978adc572cfa3885e6b12338cb5f4034bed2cab35f0d76a4b75ccdf + languageName: node + linkType: hard + +"node-gyp@npm:latest": + version: 10.1.0 + resolution: "node-gyp@npm:10.1.0" + dependencies: + env-paths: "npm:^2.2.0" + exponential-backoff: "npm:^3.1.1" + glob: "npm:^10.3.10" + graceful-fs: "npm:^4.2.6" + make-fetch-happen: "npm:^13.0.0" + nopt: "npm:^7.0.0" + proc-log: "npm:^3.0.0" + semver: "npm:^7.3.5" + tar: "npm:^6.1.2" + which: "npm:^4.0.0" + bin: + node-gyp: bin/node-gyp.js + checksum: 89e105e495e66cd4568af3cf79cdeb67d670eb069e33163c7781d3366470a30367c9bd8dea59e46db16370020139e5bf78b1fbc03284cb571754dfaa59744db5 + languageName: node + linkType: hard + +"nopt@npm:^7.0.0": + version: 7.2.1 + resolution: "nopt@npm:7.2.1" + dependencies: + abbrev: "npm:^2.0.0" + bin: + nopt: bin/nopt.js + checksum: 95a1f6dec8a81cd18cdc2fed93e6f0b4e02cf6bdb4501c848752c6e34f9883d9942f036a5e3b21a699047d8a448562d891e67492df68ec9c373e6198133337ae + languageName: node + linkType: hard + +"normalize-url@npm:^6.0.1": + version: 6.1.0 + resolution: "normalize-url@npm:6.1.0" + checksum: 5ae699402c9d5ffa330adc348fcd6fc6e6a155ab7c811b96e30b7ecab60ceef821d8f86443869671dda71bbc47f4b9625739c82ad247e883e9aefe875bfb8659 + languageName: node + linkType: hard + +"npm-run-path@npm:^2.0.0": + version: 2.0.2 + resolution: "npm-run-path@npm:2.0.2" + dependencies: + path-key: "npm:^2.0.0" + checksum: acd5ad81648ba4588ba5a8effb1d98d2b339d31be16826a118d50f182a134ac523172101b82eab1d01cb4c2ba358e857d54cfafd8163a1ffe7bd52100b741125 + languageName: node + linkType: hard + +"npm-run-path@npm:^4.0.1": + version: 4.0.1 + resolution: "npm-run-path@npm:4.0.1" + dependencies: + path-key: "npm:^3.0.0" + checksum: 5374c0cea4b0bbfdfae62da7bbdf1e1558d338335f4cacf2515c282ff358ff27b2ecb91ffa5330a8b14390ac66a1e146e10700440c1ab868208430f56b5f4d23 + languageName: node + linkType: hard + +"once@npm:^1.3.1, once@npm:^1.4.0": + version: 1.4.0 + resolution: "once@npm:1.4.0" + dependencies: + wrappy: "npm:1" + checksum: cd0a88501333edd640d95f0d2700fbde6bff20b3d4d9bdc521bdd31af0656b5706570d6c6afe532045a20bb8dc0849f8332d6f2a416e0ba6d3d3b98806c7db68 + languageName: node + linkType: hard + +"onetime@npm:^5.1.2": + version: 5.1.2 + resolution: "onetime@npm:5.1.2" + dependencies: + mimic-fn: "npm:^2.1.0" + checksum: e9fd0695a01cf226652f0385bf16b7a24153dbbb2039f764c8ba6d2306a8506b0e4ce570de6ad99c7a6eb49520743afdb66edd95ee979c1a342554ed49a9aadd + languageName: node + linkType: hard + +"os-filter-obj@npm:^2.0.0": + version: 2.0.0 + resolution: "os-filter-obj@npm:2.0.0" + dependencies: + arch: "npm:^2.1.0" + checksum: 08808a109b2dba9be8686cc006e082a0f6595e6d87e2a30e4147cb1d22b62a30a6e5f4fd78226aee76d9158c84db3cea292adec02e6591452e93cb33bf5da877 + languageName: node + linkType: hard + +"p-cancelable@npm:^2.0.0": + version: 2.1.1 + resolution: "p-cancelable@npm:2.1.1" + checksum: 7f1b64db17fc54acf359167d62898115dcf2a64bf6b3b038e4faf36fc059e5ed762fb9624df8ed04b25bee8de3ab8d72dea9879a2a960cd12e23c420a4aca6ed + languageName: node + linkType: hard + +"p-finally@npm:^1.0.0": + version: 1.0.0 + resolution: "p-finally@npm:1.0.0" + checksum: 93a654c53dc805dd5b5891bab16eb0ea46db8f66c4bfd99336ae929323b1af2b70a8b0654f8f1eae924b2b73d037031366d645f1fd18b3d30cbd15950cc4b1d4 + languageName: node + linkType: hard + +"p-map@npm:^4.0.0": + version: 4.0.0 + resolution: "p-map@npm:4.0.0" + dependencies: + aggregate-error: "npm:^3.0.0" + checksum: 7ba4a2b1e24c05e1fc14bbaea0fc6d85cf005ae7e9c9425d4575550f37e2e584b1af97bcde78eacd7559208f20995988d52881334db16cf77bc1bcf68e48ed7c + languageName: node + linkType: hard + +"path-key@npm:^2.0.0": + version: 2.0.1 + resolution: "path-key@npm:2.0.1" + checksum: 6e654864e34386a2a8e6bf72cf664dcabb76574dd54013add770b374384d438aca95f4357bb26935b514a4e4c2c9b19e191f2200b282422a76ee038b9258c5e7 + languageName: node + linkType: hard + +"path-key@npm:^3.0.0, path-key@npm:^3.1.0": + version: 3.1.1 + resolution: "path-key@npm:3.1.1" + checksum: 55cd7a9dd4b343412a8386a743f9c746ef196e57c823d90ca3ab917f90ab9f13dd0ded27252ba49dbdfcab2b091d998bc446f6220cd3cea65db407502a740020 + languageName: node + linkType: hard + +"path-scurry@npm:^1.11.1": + version: 1.11.1 + resolution: "path-scurry@npm:1.11.1" + dependencies: + lru-cache: "npm:^10.2.0" + minipass: "npm:^5.0.0 || ^6.0.2 || ^7.0.0" + checksum: 5e8845c159261adda6f09814d7725683257fcc85a18f329880ab4d7cc1d12830967eae5d5894e453f341710d5484b8fdbbd4d75181b4d6e1eb2f4dc7aeadc434 + languageName: node + linkType: hard + +"peek-readable@npm:^5.0.0": + version: 5.0.0 + resolution: "peek-readable@npm:5.0.0" + checksum: d342f02dd0c8a6b4bd0e7519a93d545b2b19375200e79a7431f0f1ec3f91e22b2217fa3a15cde95f6ab388ce6fce8aae75794d84b9b39c5836eb7c5f55e7ee9e + languageName: node + linkType: hard + +"picomatch@npm:^2.3.1": + version: 2.3.1 + resolution: "picomatch@npm:2.3.1" + checksum: 60c2595003b05e4535394d1da94850f5372c9427ca4413b71210f437f7b2ca091dbd611c45e8b37d10036fa8eade25c1b8951654f9d3973bfa66a2ff4d3b08bc + languageName: node + linkType: hard + +"pify@npm:^2.2.0": + version: 2.3.0 + resolution: "pify@npm:2.3.0" + checksum: 9503aaeaf4577acc58642ad1d25c45c6d90288596238fb68f82811c08104c800e5a7870398e9f015d82b44ecbcbef3dc3d4251a1cbb582f6e5959fe09884b2ba + languageName: node + linkType: hard + +"piscina@npm:^4.3.0": + version: 4.5.1 + resolution: "piscina@npm:4.5.1" + dependencies: + nice-napi: "npm:^1.0.2" + dependenciesMeta: + nice-napi: + optional: true + checksum: a450140a3266920417844c11164bba208d4df2ddcb683bf3ee99d8d4b7db9de9751f5b83f6f5b2146391d18012d9f4af30a69ed751b9d4aa5eea1771a37df275 + languageName: node + linkType: hard + +"proc-log@npm:^3.0.0": + version: 3.0.0 + resolution: "proc-log@npm:3.0.0" + checksum: 02b64e1b3919e63df06f836b98d3af002b5cd92655cab18b5746e37374bfb73e03b84fe305454614b34c25b485cc687a9eebdccf0242cda8fda2475dd2c97e02 + languageName: node + linkType: hard + +"proc-log@npm:^4.2.0": + version: 4.2.0 + resolution: "proc-log@npm:4.2.0" + checksum: 4e1394491b717f6c1ade15c570ecd4c2b681698474d3ae2d303c1e4b6ab9455bd5a81566211e82890d5a5ae9859718cc6954d5150bb18b09b72ecb297beae90a + languageName: node + linkType: hard + +"promise-retry@npm:^2.0.1": + version: 2.0.1 + resolution: "promise-retry@npm:2.0.1" + dependencies: + err-code: "npm:^2.0.2" + retry: "npm:^0.12.0" + checksum: 96e1a82453c6c96eef53a37a1d6134c9f2482f94068f98a59145d0986ca4e497bf110a410adf73857e588165eab3899f0ebcf7b3890c1b3ce802abc0d65967d4 + languageName: node + linkType: hard + +"pseudomap@npm:^1.0.2": + version: 1.0.2 + resolution: "pseudomap@npm:1.0.2" + checksum: 856c0aae0ff2ad60881168334448e898ad7a0e45fe7386d114b150084254c01e200c957cf378378025df4e052c7890c5bd933939b0e0d2ecfcc1dc2f0b2991f5 + languageName: node + linkType: hard + +"pump@npm:^3.0.0": + version: 3.0.0 + resolution: "pump@npm:3.0.0" + dependencies: + end-of-stream: "npm:^1.1.0" + once: "npm:^1.3.1" + checksum: e42e9229fba14732593a718b04cb5e1cfef8254544870997e0ecd9732b189a48e1256e4e5478148ecb47c8511dca2b09eae56b4d0aad8009e6fac8072923cfc9 + languageName: node + linkType: hard + +"queue-microtask@npm:^1.2.2": + version: 1.2.3 + resolution: "queue-microtask@npm:1.2.3" + checksum: 72900df0616e473e824202113c3df6abae59150dfb73ed13273503127235320e9c8ca4aaaaccfd58cf417c6ca92a6e68ee9a5c3182886ae949a768639b388a7b + languageName: node + linkType: hard + +"quick-lru@npm:^5.1.1": + version: 5.1.1 + resolution: "quick-lru@npm:5.1.1" + checksum: a516faa25574be7947969883e6068dbe4aa19e8ef8e8e0fd96cddd6d36485e9106d85c0041a27153286b0770b381328f4072aa40d3b18a19f5f7d2b78b94b5ed + languageName: node + linkType: hard + +"readable-stream@npm:^3.6.0": + version: 3.6.2 + resolution: "readable-stream@npm:3.6.2" + dependencies: + inherits: "npm:^2.0.3" + string_decoder: "npm:^1.1.1" + util-deprecate: "npm:^1.0.1" + checksum: d9e3e53193adcdb79d8f10f2a1f6989bd4389f5936c6f8b870e77570853561c362bee69feca2bbb7b32368ce96a85504aa4cedf7cf80f36e6a9de30d64244048 + languageName: node + linkType: hard + +"readable-web-to-node-stream@npm:^3.0.2": + version: 3.0.2 + resolution: "readable-web-to-node-stream@npm:3.0.2" + dependencies: + readable-stream: "npm:^3.6.0" + checksum: d3a5bf9d707c01183d546a64864aa63df4d9cb835dfd2bf89ac8305e17389feef2170c4c14415a10d38f9b9bfddf829a57aaef7c53c8b40f11d499844bf8f1a4 + languageName: node + linkType: hard + +"resolve-alpn@npm:^1.0.0": + version: 1.2.1 + resolution: "resolve-alpn@npm:1.2.1" + checksum: 744e87888f0b6fa0b256ab454ca0b9c0b80808715e2ef1f3672773665c92a941f6181194e30ccae4a8cd0adbe0d955d3f133102636d2ee0cca0119fec0bc9aec + languageName: node + linkType: hard + +"responselike@npm:^2.0.0": + version: 2.0.1 + resolution: "responselike@npm:2.0.1" + dependencies: + lowercase-keys: "npm:^2.0.0" + checksum: b122535466e9c97b55e69c7f18e2be0ce3823c5d47ee8de0d9c0b114aa55741c6db8bfbfce3766a94d1272e61bfb1ebf0a15e9310ac5629fbb7446a861b4fd3a + languageName: node + linkType: hard + +"retry@npm:^0.12.0": + version: 0.12.0 + resolution: "retry@npm:0.12.0" + checksum: 1f914879f97e7ee931ad05fe3afa629bd55270fc6cf1c1e589b6a99fab96d15daad0fa1a52a00c729ec0078045fe3e399bd4fd0c93bcc906957bdc17f89cb8e6 + languageName: node + linkType: hard + +"reusify@npm:^1.0.4": + version: 1.0.4 + resolution: "reusify@npm:1.0.4" + checksum: 14222c9e1d3f9ae01480c50d96057228a8524706db79cdeb5a2ce5bb7070dd9f409a6f84a02cbef8cdc80d39aef86f2dd03d155188a1300c599b05437dcd2ffb + languageName: node + linkType: hard + +"run-parallel@npm:^1.1.9": + version: 1.2.0 + resolution: "run-parallel@npm:1.2.0" + dependencies: + queue-microtask: "npm:^1.2.2" + checksum: cb4f97ad25a75ebc11a8ef4e33bb962f8af8516bb2001082ceabd8902e15b98f4b84b4f8a9b222e5d57fc3bd1379c483886ed4619367a7680dad65316993021d + languageName: node + linkType: hard + +"safe-buffer@npm:5.2.1, safe-buffer@npm:~5.2.0": + version: 5.2.1 + resolution: "safe-buffer@npm:5.2.1" + checksum: 32872cd0ff68a3ddade7a7617b8f4c2ae8764d8b7d884c651b74457967a9e0e886267d3ecc781220629c44a865167b61c375d2da6c720c840ecd73f45d5d9451 + languageName: node + linkType: hard + +"safer-buffer@npm:>= 2.1.2 < 3.0.0": + version: 2.1.2 + resolution: "safer-buffer@npm:2.1.2" + checksum: 7eaf7a0cf37cc27b42fb3ef6a9b1df6e93a1c6d98c6c6702b02fe262d5fcbd89db63320793b99b21cb5348097d0a53de81bd5f4e8b86e20cc9412e3f1cfb4e83 + languageName: node + linkType: hard + +"semver-regex@npm:^4.0.5": + version: 4.0.5 + resolution: "semver-regex@npm:4.0.5" + checksum: b9e5c0573c4a997fb7e6e76321385d254797e86c8dba5e23f3cd8cf8f40b40414097a51514e5fead61dcb88ff10d3676355c01e2040f3c68f6c24bfd2073da2e + languageName: node + linkType: hard + +"semver-truncate@npm:^3.0.0": + version: 3.0.0 + resolution: "semver-truncate@npm:3.0.0" + dependencies: + semver: "npm:^7.3.5" + checksum: d8c23812218ff147f512ac4830e86860a377dba8a9733ae97d816102aca33236fa1c44c06544727153fffb93d15d0e45c49b2c40a7964aa3671769e9aed2f3f9 + languageName: node + linkType: hard + +"semver@npm:^7.3.5, semver@npm:^7.3.8, semver@npm:^7.5.3": + version: 7.6.2 + resolution: "semver@npm:7.6.2" + bin: + semver: bin/semver.js + checksum: 296b17d027f57a87ef645e9c725bff4865a38dfc9caf29b26aa084b85820972fbe7372caea1ba6857162fa990702c6d9c1d82297cecb72d56c78ab29070d2ca2 + languageName: node + linkType: hard + +"shebang-command@npm:^1.2.0": + version: 1.2.0 + resolution: "shebang-command@npm:1.2.0" + dependencies: + shebang-regex: "npm:^1.0.0" + checksum: 9eed1750301e622961ba5d588af2212505e96770ec376a37ab678f965795e995ade7ed44910f5d3d3cb5e10165a1847f52d3348c64e146b8be922f7707958908 + languageName: node + linkType: hard + +"shebang-command@npm:^2.0.0": + version: 2.0.0 + resolution: "shebang-command@npm:2.0.0" + dependencies: + shebang-regex: "npm:^3.0.0" + checksum: 6b52fe87271c12968f6a054e60f6bde5f0f3d2db483a1e5c3e12d657c488a15474121a1d55cd958f6df026a54374ec38a4a963988c213b7570e1d51575cea7fa + languageName: node + linkType: hard + +"shebang-regex@npm:^1.0.0": + version: 1.0.0 + resolution: "shebang-regex@npm:1.0.0" + checksum: 404c5a752cd40f94591dfd9346da40a735a05139dac890ffc229afba610854d8799aaa52f87f7e0c94c5007f2c6af55bdcaeb584b56691926c5eaf41dc8f1372 + languageName: node + linkType: hard + +"shebang-regex@npm:^3.0.0": + version: 3.0.0 + resolution: "shebang-regex@npm:3.0.0" + checksum: 1a2bcae50de99034fcd92ad4212d8e01eedf52c7ec7830eedcf886622804fe36884278f2be8be0ea5fde3fd1c23911643a4e0f726c8685b61871c8908af01222 + languageName: node + linkType: hard + +"signal-exit@npm:^3.0.0, signal-exit@npm:^3.0.3": + version: 3.0.7 + resolution: "signal-exit@npm:3.0.7" + checksum: a2f098f247adc367dffc27845853e9959b9e88b01cb301658cfe4194352d8d2bb32e18467c786a7fe15f1d44b233ea35633d076d5e737870b7139949d1ab6318 + languageName: node + linkType: hard + +"signal-exit@npm:^4.0.1": + version: 4.1.0 + resolution: "signal-exit@npm:4.1.0" + checksum: c9fa63bbbd7431066174a48ba2dd9986dfd930c3a8b59de9c29d7b6854ec1c12a80d15310869ea5166d413b99f041bfa3dd80a7947bcd44ea8e6eb3ffeabfa1f + languageName: node + linkType: hard + +"slash@npm:3.0.0": + version: 3.0.0 + resolution: "slash@npm:3.0.0" + checksum: 94a93fff615f25a999ad4b83c9d5e257a7280c90a32a7cb8b4a87996e4babf322e469c42b7f649fd5796edd8687652f3fb452a86dc97a816f01113183393f11c + languageName: node + linkType: hard + +"smart-buffer@npm:^4.2.0": + version: 4.2.0 + resolution: "smart-buffer@npm:4.2.0" + checksum: 927484aa0b1640fd9473cee3e0a0bcad6fce93fd7bbc18bac9ad0c33686f5d2e2c422fba24b5899c184524af01e11dd2bd051c2bf2b07e47aff8ca72cbfc60d2 + languageName: node + linkType: hard + +"socks-proxy-agent@npm:^8.0.3": + version: 8.0.3 + resolution: "socks-proxy-agent@npm:8.0.3" + dependencies: + agent-base: "npm:^7.1.1" + debug: "npm:^4.3.4" + socks: "npm:^2.7.1" + checksum: c2112c66d6322e497d68e913c3780f3683237fd394bfd480b9283486a86e36095d0020db96145d88f8ccd9cc73261b98165b461f9c1bf5dc17abfe75c18029ce + languageName: node + linkType: hard + +"socks@npm:^2.7.1": + version: 2.8.3 + resolution: "socks@npm:2.8.3" + dependencies: + ip-address: "npm:^9.0.5" + smart-buffer: "npm:^4.2.0" + checksum: ffcb622c22481dfcd7589aae71fbfd71ca34334064d181df64bf8b7feaeee19706aba4cffd1de35cc7bbaeeaa0af96be2d7f40fcbc7bc0ab69533a7ae9ffc4fb + languageName: node + linkType: hard + +"sort-keys-length@npm:^1.0.0": + version: 1.0.1 + resolution: "sort-keys-length@npm:1.0.1" + dependencies: + sort-keys: "npm:^1.0.0" + checksum: f9acac5fb31580a9e3d43b419dc86a1b75e85b79036a084d95dd4d1062b621c9589906588ac31e370a0dd381be46d8dbe900efa306d087ca9c912d7a59b5a590 + languageName: node + linkType: hard + +"sort-keys@npm:^1.0.0": + version: 1.1.2 + resolution: "sort-keys@npm:1.1.2" + dependencies: + is-plain-obj: "npm:^1.0.0" + checksum: 0ac2ea2327d92252f07aa7b2f8c7023a1f6ce3306439a3e81638cce9905893c069521d168f530fb316d1a929bdb052b742969a378190afaef1bc64fa69e29576 + languageName: node + linkType: hard + +"source-map@npm:^0.7.3": + version: 0.7.4 + resolution: "source-map@npm:0.7.4" + checksum: a0f7c9b797eda93139842fd28648e868a9a03ea0ad0d9fa6602a0c1f17b7fb6a7dcca00c144476cccaeaae5042e99a285723b1a201e844ad67221bf5d428f1dc + languageName: node + linkType: hard + +"sprintf-js@npm:^1.1.3": + version: 1.1.3 + resolution: "sprintf-js@npm:1.1.3" + checksum: e7587128c423f7e43cc625fe2f87e6affdf5ca51c1cc468e910d8aaca46bb44a7fbcfa552f787b1d3987f7043aeb4527d1b99559e6621e01b42b3f45e5a24cbb + languageName: node + linkType: hard + +"ssri@npm:^10.0.0": + version: 10.0.6 + resolution: "ssri@npm:10.0.6" + dependencies: + minipass: "npm:^7.0.3" + checksum: f92c1b3cc9bfd0a925417412d07d999935917bc87049f43ebec41074661d64cf720315661844106a77da9f8204b6d55ae29f9514e673083cae39464343af2a8b + languageName: node + linkType: hard + +"string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^4.1.0": + version: 4.2.3 + resolution: "string-width@npm:4.2.3" + dependencies: + emoji-regex: "npm:^8.0.0" + is-fullwidth-code-point: "npm:^3.0.0" + strip-ansi: "npm:^6.0.1" + checksum: e52c10dc3fbfcd6c3a15f159f54a90024241d0f149cf8aed2982a2d801d2e64df0bf1dc351cf8e95c3319323f9f220c16e740b06faecd53e2462df1d2b5443fb + languageName: node + linkType: hard + +"string-width@npm:^5.0.1, string-width@npm:^5.1.2": + version: 5.1.2 + resolution: "string-width@npm:5.1.2" + dependencies: + eastasianwidth: "npm:^0.2.0" + emoji-regex: "npm:^9.2.2" + strip-ansi: "npm:^7.0.1" + checksum: 7369deaa29f21dda9a438686154b62c2c5f661f8dda60449088f9f980196f7908fc39fdd1803e3e01541970287cf5deae336798337e9319a7055af89dafa7193 + languageName: node + linkType: hard + +"string_decoder@npm:^1.1.1": + version: 1.3.0 + resolution: "string_decoder@npm:1.3.0" + dependencies: + safe-buffer: "npm:~5.2.0" + checksum: 54d23f4a6acae0e93f999a585e673be9e561b65cd4cca37714af1e893ab8cd8dfa52a9e4f58f48f87b4a44918d3a9254326cb80ed194bf2e4c226e2b21767e56 + languageName: node + linkType: hard + +"strip-ansi-cjs@npm:strip-ansi@^6.0.1, strip-ansi@npm:^6.0.0, strip-ansi@npm:^6.0.1": + version: 6.0.1 + resolution: "strip-ansi@npm:6.0.1" + dependencies: + ansi-regex: "npm:^5.0.1" + checksum: ae3b5436d34fadeb6096367626ce987057713c566e1e7768818797e00ac5d62023d0f198c4e681eae9e20701721980b26a64a8f5b91238869592a9c6800719a2 + languageName: node + linkType: hard + +"strip-ansi@npm:^7.0.1": + version: 7.1.0 + resolution: "strip-ansi@npm:7.1.0" + dependencies: + ansi-regex: "npm:^6.0.1" + checksum: 475f53e9c44375d6e72807284024ac5d668ee1d06010740dec0b9744f2ddf47de8d7151f80e5f6190fc8f384e802fdf9504b76a7e9020c9faee7103623338be2 + languageName: node + linkType: hard + +"strip-eof@npm:^1.0.0": + version: 1.0.0 + resolution: "strip-eof@npm:1.0.0" + checksum: 40bc8ddd7e072f8ba0c2d6d05267b4e0a4800898c3435b5fb5f5a21e6e47dfaff18467e7aa0d1844bb5d6274c3097246595841fbfeb317e541974ee992cac506 + languageName: node + linkType: hard + +"strip-final-newline@npm:^2.0.0": + version: 2.0.0 + resolution: "strip-final-newline@npm:2.0.0" + checksum: 69412b5e25731e1938184b5d489c32e340605bb611d6140344abc3421b7f3c6f9984b21dff296dfcf056681b82caa3bb4cc996a965ce37bcfad663e92eae9c64 + languageName: node + linkType: hard + +"strip-outer@npm:^2.0.0": + version: 2.0.0 + resolution: "strip-outer@npm:2.0.0" + checksum: 14ef9fe861e59a5f1555f1860982ae4edce2edb4ed34ab1b37cb62a8ba2f7c3540cbca6c884eabe4006e6cd729ab5d708a631169dd5b66fda570836e7e3b6589 + languageName: node + linkType: hard + +"strtok3@npm:^7.0.0-alpha.9": + version: 7.0.0 + resolution: "strtok3@npm:7.0.0" + dependencies: + "@tokenizer/token": "npm:^0.3.0" + peek-readable: "npm:^5.0.0" + checksum: 4f2269679fcfce1e9fe0600eff361ea4c687ae0a0e8d9dab6703811071cd92545cbcb32d4ace3d3aa591f777cec1a3e8aeecd5efd71ae216fd2962a7a238b4ab + languageName: node + linkType: hard + +"tar@npm:^6.1.11, tar@npm:^6.1.2": + version: 6.2.1 + resolution: "tar@npm:6.2.1" + dependencies: + chownr: "npm:^2.0.0" + fs-minipass: "npm:^2.0.0" + minipass: "npm:^5.0.0" + minizlib: "npm:^2.1.1" + mkdirp: "npm:^1.0.3" + yallist: "npm:^4.0.0" + checksum: bfbfbb2861888077fc1130b84029cdc2721efb93d1d1fb80f22a7ac3a98ec6f8972f29e564103bbebf5e97be67ebc356d37fa48dbc4960600a1eb7230fbd1ea0 + languageName: node + linkType: hard + +"to-regex-range@npm:^5.0.1": + version: 5.0.1 + resolution: "to-regex-range@npm:5.0.1" + dependencies: + is-number: "npm:^7.0.0" + checksum: 10dda13571e1f5ad37546827e9b6d4252d2e0bc176c24a101252153ef435d83696e2557fe128c4678e4e78f5f01e83711c703eef9814eb12dab028580d45980a + languageName: node + linkType: hard + +"token-types@npm:^5.0.0-alpha.2": + version: 5.0.1 + resolution: "token-types@npm:5.0.1" + dependencies: + "@tokenizer/token": "npm:^0.3.0" + ieee754: "npm:^1.2.1" + checksum: 0985369bbea9f53a5ccd79bb9899717b41401a813deb2c7fb1add5d0baf2f702aaf6da78f6e0ccf346d5a9f7acaa7cb5efed7d092d89d8c1e6962959e9509bc0 + languageName: node + linkType: hard + +"trim-repeated@npm:^2.0.0": + version: 2.0.0 + resolution: "trim-repeated@npm:2.0.0" + dependencies: + escape-string-regexp: "npm:^5.0.0" + checksum: 4086eb0bc560f3da0370f427f423db4e3fc0a8e1560ecffc3b68512071319fe82dc9dd86d76b981d36ada76d7d49c3f8897ac054c87bc177e7a25abfd29e2bcd + languageName: node + linkType: hard + +"tweetnacl@npm:^1.0.3": + version: 1.0.3 + resolution: "tweetnacl@npm:1.0.3" + checksum: ca122c2f86631f3c0f6d28efb44af2a301d4a557a62a3e2460286b08e97567b258c2212e4ad1cfa22bd6a57edcdc54ba76ebe946847450ab0999e6d48ccae332 + languageName: node + linkType: hard + +"typescript@npm:^5.5.2": + version: 5.5.2 + resolution: "typescript@npm:5.5.2" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 9118b20f248e76b0dbff8737fef65dfa89d02668d4e633d2c5ceac99033a0ca5e8a1c1a53bc94da68e8f67677a88f318663dde859c9e9a09c1e116415daec2ba + languageName: node + linkType: hard + +"typescript@patch:typescript@npm%3A^5.5.2#optional!builtin": + version: 5.5.2 + resolution: "typescript@patch:typescript@npm%3A5.5.2#optional!builtin::version=5.5.2&hash=e012d7" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 28b3de2ddaf63a7620e7ddbe5d377af71ce93ecc558c41bf0e3d88661d8e6e7aa6c7739164fef98055f69819e41faca49252938ef3633a3dff2734cca6a9042e + languageName: node + linkType: hard + +"undici-types@npm:~5.26.4": + version: 5.26.5 + resolution: "undici-types@npm:5.26.5" + checksum: 0097779d94bc0fd26f0418b3a05472410408877279141ded2bd449167be1aed7ea5b76f756562cb3586a07f251b90799bab22d9019ceba49c037c76445f7cddd + languageName: node + linkType: hard + +"unique-filename@npm:^3.0.0": + version: 3.0.0 + resolution: "unique-filename@npm:3.0.0" + dependencies: + unique-slug: "npm:^4.0.0" + checksum: 8e2f59b356cb2e54aab14ff98a51ac6c45781d15ceaab6d4f1c2228b780193dc70fae4463ce9e1df4479cb9d3304d7c2043a3fb905bdeca71cc7e8ce27e063df + languageName: node + linkType: hard + +"unique-slug@npm:^4.0.0": + version: 4.0.0 + resolution: "unique-slug@npm:4.0.0" + dependencies: + imurmurhash: "npm:^0.1.4" + checksum: 40912a8963fc02fb8b600cf50197df4a275c602c60de4cac4f75879d3c48558cfac48de08a25cc10df8112161f7180b3bbb4d662aadb711568602f9eddee54f0 + languageName: node + linkType: hard + +"util-deprecate@npm:^1.0.1": + version: 1.0.2 + resolution: "util-deprecate@npm:1.0.2" + checksum: 474acf1146cb2701fe3b074892217553dfcf9a031280919ba1b8d651a068c9b15d863b7303cb15bd00a862b498e6cf4ad7b4a08fb134edd5a6f7641681cb54a2 + languageName: node + linkType: hard + +"which@npm:^1.2.9": + version: 1.3.1 + resolution: "which@npm:1.3.1" + dependencies: + isexe: "npm:^2.0.0" + bin: + which: ./bin/which + checksum: 549dcf1752f3ee7fbb64f5af2eead4b9a2f482108b7de3e85c781d6c26d8cf6a52d37cfbe0642a155fa6470483fe892661a859c03157f24c669cf115f3bbab5e + languageName: node + linkType: hard + +"which@npm:^2.0.1": + version: 2.0.2 + resolution: "which@npm:2.0.2" + dependencies: + isexe: "npm:^2.0.0" + bin: + node-which: ./bin/node-which + checksum: 4782f8a1d6b8fc12c65e968fea49f59752bf6302dc43036c3bf87da718a80710f61a062516e9764c70008b487929a73546125570acea95c5b5dcc8ac3052c70f + languageName: node + linkType: hard + +"which@npm:^4.0.0": + version: 4.0.0 + resolution: "which@npm:4.0.0" + dependencies: + isexe: "npm:^3.1.1" + bin: + node-which: bin/which.js + checksum: f17e84c042592c21e23c8195108cff18c64050b9efb8459589116999ea9da6dd1509e6a1bac3aeebefd137be00fabbb61b5c2bc0aa0f8526f32b58ee2f545651 + languageName: node + linkType: hard + +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": + version: 7.0.0 + resolution: "wrap-ansi@npm:7.0.0" + dependencies: + ansi-styles: "npm:^4.0.0" + string-width: "npm:^4.1.0" + strip-ansi: "npm:^6.0.0" + checksum: cebdaeca3a6880da410f75209e68cd05428580de5ad24535f22696d7d9cab134d1f8498599f344c3cf0fb37c1715807a183778d8c648d6cc0cb5ff2bb4236540 + languageName: node + linkType: hard + +"wrap-ansi@npm:^8.1.0": + version: 8.1.0 + resolution: "wrap-ansi@npm:8.1.0" + dependencies: + ansi-styles: "npm:^6.1.0" + string-width: "npm:^5.0.1" + strip-ansi: "npm:^7.0.1" + checksum: 7b1e4b35e9bb2312d2ee9ee7dc95b8cb5f8b4b5a89f7dde5543fe66c1e3715663094defa50d75454ac900bd210f702d575f15f3f17fa9ec0291806d2578d1ddf + languageName: node + linkType: hard + +"wrappy@npm:1": + version: 1.0.2 + resolution: "wrappy@npm:1.0.2" + checksum: 159da4805f7e84a3d003d8841557196034155008f817172d4e986bd591f74aa82aa7db55929a54222309e01079a65a92a9e6414da5a6aa4b01ee44a511ac3ee5 + languageName: node + linkType: hard + +"ws@npm:^8.16.0": + version: 8.17.1 + resolution: "ws@npm:8.17.1" + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ">=5.0.2" + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: 4264ae92c0b3e59c7e309001e93079b26937aab181835fb7af79f906b22cd33b6196d96556dafb4e985742dd401e99139572242e9847661fdbc96556b9e6902d + languageName: node + linkType: hard + +"yallist@npm:^2.1.2": + version: 2.1.2 + resolution: "yallist@npm:2.1.2" + checksum: 75fc7bee4821f52d1c6e6021b91b3e079276f1a9ce0ad58da3c76b79a7e47d6f276d35e206a96ac16c1cf48daee38a8bb3af0b1522a3d11c8ffe18f898828832 + languageName: node + linkType: hard + +"yallist@npm:^4.0.0": + version: 4.0.0 + resolution: "yallist@npm:4.0.0" + checksum: 4cb02b42b8a93b5cf50caf5d8e9beb409400a8a4d85e83bb0685c1457e9ac0b7a00819e9f5991ac25ffabb56a78e2f017c1acc010b3a1babfe6de690ba531abd + languageName: node + linkType: hard diff --git a/examples/nodejs/.env.example b/examples/nodejs/.env.example deleted file mode 100644 index f74c6612b..000000000 --- a/examples/nodejs/.env.example +++ /dev/null @@ -1 +0,0 @@ -TOKEN= \ No newline at end of file diff --git a/examples/nodejs/Managers/CommandManager.js b/examples/nodejs/Managers/CommandManager.js deleted file mode 100644 index 69670e352..000000000 --- a/examples/nodejs/Managers/CommandManager.js +++ /dev/null @@ -1,137 +0,0 @@ -const resolveFolder = (folderName) => path.resolve(__dirname, '.', folderName) -const fs = require('fs') -const path = require('path') - -class CommandManager { - constructor(client) { - this.client = client - this.cache = new Map() - this.aliases = new Map() - } - - load(options = {}) { - const commandFolderPath = options.path || '../Plugins' - const commandFolder = resolveFolder(commandFolderPath) - if (options.category === undefined) options.category = true - if (options.plugins === undefined) options.plugins = true - // PluginMode will iterate through all SubFolders - fs.readdirSync(commandFolder).map(async (dir) => { - if (dir.endsWith('.txt')) return - if (!options.category && dir.endsWith('.js')) { - const commandPath = path.join(commandFolder, dir) - this.loadCommand(commandPath) - } else { - fs.readdirSync(path.join(commandFolder, dir)).map((cmd) => { - if (cmd.endsWith('.js') && !options.plugins) { - const commandPath = path.join(commandFolder, dir, cmd) - this.loadCommand(commandPath) - } else if (commandFolderPath === '../Plugins') { - if (cmd !== 'commands') return - fs.readdirSync(path.join(commandFolder, dir, cmd)).map((cmdfile) => { - if (!cmdfile.endsWith('.js')) return - const commandPath = path.join(commandFolder, dir, cmd, cmdfile) - this.loadCommand(commandPath) - }) - } - }) - } - }) - } - - loadCommand(commandPath) { - const pull = require(path.join(commandPath)) - if (pull.name) { - pull.path = commandPath - this.cache.set(pull.name, pull) - } - if (pull.aliases) { - pull.aliases.map((p) => this.aliases.set(p, pull)) - } - return pull - } - - reloadCommand(commandName) { - const command = this.cache.get(commandName) - if (!command) return - const commandPath = path.join(command.path) - delete require.cache[require.resolve(commandPath)] - return this.loadCommand(commandPath) - } - - isCommand(message) { - if (message.isFromBot) return false - const prefix = '!' - const escapeRegex = (str) => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') - const prefixRegex = new RegExp(`^(<@!?${this.client.id}>|${escapeRegex(prefix)})\\s*`) - if (!prefixRegex.test(message.content)) return false - - const [, matchedPrefix] = message.content.match(prefixRegex) - const args = message.content.slice(matchedPrefix.length).trim().split(/ +/) - - this.onMessage(message, prefix, args) - return true - } - - isInteraction(interaction) { - if (interaction.type !== 2) return - this.onInteraction(interaction) - } - - async onMessage(message, guild, args) { - const commandName = args.shift().toLowerCase() - const command = this.cache.get(commandName) // || this.cache.find(cmd => cmd.aliases && cmd.aliases.includes(commandName)); - if (!command && message.content.includes(this.client.id)) { - // Handle, when Command has not been found - const options = { content: 'I did not found the Command!' } - this.client.helpers.sendMessage(message.channelId, options) - } - if (!command) return - - const messagecommand = new command({ - manager: this, - message, - client: this.client, - args, - settings: {}, - commandName: command.name, - }) - messagecommand.execute()?.catch?.((error) => { - console.log(error) - // Call Function on CommandResponse.js, handle the error - return messagecommand.onError(error ?? 'custom') - }) - } - - async onInteraction(interaction) { - const command = this.cache.get(interaction.data.name) - if (!command) return - - const args = [] - // Map all Values and Args - interaction.data.options?.map((o) => { - if (o.name) args.push(o.name) - if (o.options) { - o.options.map((o2) => { - if (o2.value) return args.push(o2.value) - if (o2.name) args.push(o2.name) - if (o2.options) o2.options.map((v) => args.push(v.value)) - }) - } - }) - - const messagecommand = new command({ - manager: this, - interaction, - client: this.client, - args, - settings: {}, - commandName: command.name, - }) - messagecommand.execute()?.catch?.((error) => { - console.log(error) - // Call Function on CommandResponse.js, handle the error - return messagecommand.onError(error ?? 'custom') - }) - } -} -module.exports = CommandManager diff --git a/examples/nodejs/Managers/EventManager.js b/examples/nodejs/Managers/EventManager.js deleted file mode 100644 index 3512fd1b8..000000000 --- a/examples/nodejs/Managers/EventManager.js +++ /dev/null @@ -1,32 +0,0 @@ -const fs = require('fs') -const path = require('path') -const resolveFolder = (folderName) => path.resolve(__dirname, '.', folderName) - -const EventEmitter = require('events') - -class EventManager extends EventEmitter { - constructor() { - super() - this.cache = new Map() - this.allEvents = {} - } - - load(options = {}) { - const eventsFolder = resolveFolder('../events') - let i = 0 - fs.readdirSync(eventsFolder).map(async (file) => { - if (!file.endsWith('.js')) return - i++ - const fileName = path.join(eventsFolder, file) - const event = require(fileName) - const eventName = file.split('.')[0] - - this.allEvents[`${eventName}`] = (...args) => { - this.emit(eventName, ...args) - return event(...args) - } - }) - return this.allEvents - } -} -module.exports = EventManager diff --git a/examples/nodejs/Plugins/Developer/commands/eval.js b/examples/nodejs/Plugins/Developer/commands/eval.js deleted file mode 100644 index a690a472e..000000000 --- a/examples/nodejs/Plugins/Developer/commands/eval.js +++ /dev/null @@ -1,56 +0,0 @@ -const Discord = require('discordeno.js') - -const BaseCommand = require('../../../Structures/BaseCommand.js') -class evalcommand extends BaseCommand { - static name = 'eval' - static description = 'danger !!!' - static category = 'Developer' - static slash = { name: 'eval', category: 'dev' } - constructor(data) { - super(data) - } - - async execute() { - if (!this.client.config.owners.includes(String(this.user.id))) return - if (!(this.args.length > 0)) return this.reply({ content: '**You must provide something to eval!**' }) - - const inputOfEval = this.args.join(' ') - let outputOfEval - let typeOfEval - - try { - if (this.args.includes('await')) { - outputOfEval = await eval('(async () => {' + inputOfEval + '})()') - } else { - outputOfEval = await eval(inputOfEval) - } - } catch (e) { - outputOfEval = e.message - typeOfEval = e.name - } - - const seen = [] - outputOfEval = - typeof outputOfEval === 'object' - ? JSON.stringify( - outputOfEval, - (_, value) => { - if (value == `Bot ${this.client.config.token}`) return `BOT_TOKEN` - if (typeof value === 'bigint') value = value.toString() - if (typeof value === 'object' && value !== null) { - if (seen.indexOf(value) !== -1) return - else seen.push(value) - } - return value - }, - 1, - ) - : outputOfEval - - const embed = new Discord.Embed() - .addField({ name: 'Input', value: '```js\n' + inputOfEval + '```' }) - .addField({ name: 'Output', value: '```json\n' + `${outputOfEval}`.slice(0, 1000) + '```' }) - this.reply({ embeds: [embed] }) - } -} -module.exports = evalcommand diff --git a/examples/nodejs/Plugins/Developer/commands/reload.js b/examples/nodejs/Plugins/Developer/commands/reload.js deleted file mode 100644 index 59f283bf9..000000000 --- a/examples/nodejs/Plugins/Developer/commands/reload.js +++ /dev/null @@ -1,19 +0,0 @@ -const BaseCommand = require('../../../Structures/BaseCommand.js') -class reloadcommand extends BaseCommand { - static name = 'reload' - static description = 'Reloads a Command' - static category = 'Developer' - static slash = { name: 'reload', category: 'dev' } - constructor(data) { - super(data) - } - - async execute() { - if (!this.client.config.owners.includes(String(this.user.id))) return - if (!this.args[0]) return this.reply({ content: '**You must provide a command to reload!**' }) - const op = this.client.commands.reloadCommand(this.args[0]) - if (!op) return this.reply({ content: "**That command doesn't exist!**" }) - return this.reply({ content: '**Reloaded Command: `' + this.args[0] + '`**' }) - } -} -module.exports = reloadcommand diff --git a/examples/nodejs/Plugins/Developer/index.js b/examples/nodejs/Plugins/Developer/index.js deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/nodejs/Plugins/General/commands/ping.js b/examples/nodejs/Plugins/General/commands/ping.js deleted file mode 100644 index f4b672536..000000000 --- a/examples/nodejs/Plugins/General/commands/ping.js +++ /dev/null @@ -1,23 +0,0 @@ -const BaseCommand = require('../../../Structures/BaseCommand.js') -const Discord = require('discordeno.js') -class pingcommand extends BaseCommand { - static name = 'ping' - static description = 'See if the bot latency is okay' - static usage = '' - static category = 'General' - static slash = { name: 'ping', category: 'info' } - constructor(data) { - super(data) - } - - async execute() { - const msg = await this.channel.send({ content: `Pinging...` }) - // Assign properties to the response - const ping = msg.timestamp - (this.message ? this.message.timestamp : this.interaction.timestamp) - - const embed = new Discord.Embed().setTitle(`The Bots ping is ${ping} ms`).toJSON() - // Edit Message with the Embed - return this.reply({ embeds: [embed] }) - } -} -module.exports = pingcommand diff --git a/examples/nodejs/Plugins/General/index.js b/examples/nodejs/Plugins/General/index.js deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/nodejs/Plugins/Moderation/commands/ban.js b/examples/nodejs/Plugins/Moderation/commands/ban.js deleted file mode 100644 index feede96c7..000000000 --- a/examples/nodejs/Plugins/Moderation/commands/ban.js +++ /dev/null @@ -1,47 +0,0 @@ -const BaseCommand = require('../../../Structures/BaseCommand.js') -const Discord = require('discordeno.js') - -class bancommand extends BaseCommand { - static name = 'ban' - static description = 'Ban a user from the server' - static usage = '' - static category = 'Moderation' - static slash = { name: 'ban', category: 'mod' } - constructor(data) { - super(data) - } - - async execute() { - // Show Case Modal - - // Because no permission system has not been added - if (!this.client.config.owners.includes(String(this.user.id))) return - - const textinput = new Discord.Component() - .setType('TEXT_INPUT') - .setStyle('SHORT') - .setCustomId('t1') - .setLabel('User ID') - .setPlaceholder('User ID') - .setRequired(true) - .setMaxLength(20) - .setMinLength(1) - .setValue(this.args[0]) - .toJSON() - const textinput2 = new Discord.Component() - .setType('TEXT_INPUT') - .setStyle('PARAGRAPH') - .setCustomId('t2') - .setLabel('Reason') - .setPlaceholder('Reason for Ban') - .setRequired(false) - .setMaxLength(300) - .toJSON() - - const actionrow = new Discord.Component().setType(1).setComponents(textinput).toJSON() - const actionrow2 = new Discord.Component().setType(1).setComponents(textinput2).toJSON() - - this.interaction.popupModal({ customId: 'ban_modal', title: 'Ban User', components: [actionrow, actionrow2] }) - } -} -module.exports = bancommand diff --git a/examples/nodejs/Plugins/Moderation/commands/warn.js b/examples/nodejs/Plugins/Moderation/commands/warn.js deleted file mode 100644 index a0975ef00..000000000 --- a/examples/nodejs/Plugins/Moderation/commands/warn.js +++ /dev/null @@ -1,89 +0,0 @@ -const BaseCommand = require('../../../Structures/BaseCommand.js') - -const { Interaction, Collector, ComponentOptions, Embed, Component } = require('discordeno.js') - -class warncommand extends BaseCommand { - static name = 'warn' - static description = 'Warn a user from the server' - static usage = '' - static category = 'Moderation' - static slash = { name: 'warn', category: 'mod' } - constructor(data) { - super(data) - } - - async execute() { - // Show Case Modal - if (!this.interaction) return this.reply('You currently can just use this command as slash command.') - - if (!this.interaction.member.permissions.has('KICK_MEMBERS')) { - return this.reply('You need the permission `KICK_MEMBERS` to use this command.') - } - - const textinput = new Component() - .setType('TEXT_INPUT') - .setStyle('SHORT') - .setCustomId('t1') - .setLabel('User ID') - .setPlaceholder('User ID') - .setRequired(true) - .setMaxLength(20) - .setMinLength(1) - .setValue(this.args[0]) - .toJSON() - const textinput2 = new Component() - .setType('TEXT_INPUT') - .setStyle('PARAGRAPH') - .setCustomId('t2') - .setLabel('Reason') - .setPlaceholder('Reason for Warning') - .setRequired(false) - .setMaxLength(300) - .toJSON() - - const actionrow = new Component().setType(1).setComponents(textinput).toJSON() - const actionrow2 = new Component().setType(1).setComponents(textinput2).toJSON() - - this.interaction.popupModal({ customId: 'warn_modal', title: 'Warn User', components: [actionrow, actionrow2] }) - - const filter = (m) => m.data?.customId === 'warn_modal' - const collector = new Collector('interactionCreate', { client: this.client, timeout: 60000, filter }) - collector.on('collect', (m) => { - const options = new ComponentOptions(m.data.components) - const i = new Interaction(this.client, m) - collector.stop() - - const memberId = options.get('t1').value - const reason = options.get('t2').value - - const embed = new Embed().setTitle('Warned User:').setDescription(`User ID: <@${memberId}> \n Reason: ${reason}`).setColor(0x00ff00).toJSON() - - const warnMessage = new Embed() - .setTitle('Warning:') - .setDescription(`You have been warned in **${this.guild.name}** for ${'`' + reason + '`'}`) - .toJSON() - - this.guild.members - .fetch(memberId) - .then((m) => { - m.send({ embeds: [warnMessage] }) - .then(() => { - i.reply({ embeds: [embed] }) - }) - .catch((e) => { - console.log(e) - i.reply({ content: `Could not warn user ${'<@' + m.id + '>'} | They likely do not have their DMs open.` }) - }) - }) - .catch((e) => { - const embed = new Embed() - .setTitle('Member not found') - .setDescription(`The member with the ID of ${'`' + memberId + '`'} has not been found in this Server.`) - .setColor(0xff0000) - .toJSON() - i.reply({ embeds: [embed] }) - }) - }) - } -} -module.exports = warncommand diff --git a/examples/nodejs/Plugins/Moderation/index.js b/examples/nodejs/Plugins/Moderation/index.js deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/nodejs/README.md b/examples/nodejs/README.md deleted file mode 100644 index 90839fca1..000000000 --- a/examples/nodejs/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Nodejs Bot Template - -This template is a minimal template that uses [discordeno.js](https://www.npmjs.com/package/discordeno.js), a wrapper -around discordeno, which brings up a djs-like interface but also includes the core Features (Cross Ratelimit, Zero -Downtime Restart, Resharding...) - -## Setup - -Rename `.env.example` to `.env` and fill your bot token there. - -## Run Bot - -- node index.js diff --git a/examples/nodejs/Structures/BaseCommand.js b/examples/nodejs/Structures/BaseCommand.js deleted file mode 100644 index 59ca18f58..000000000 --- a/examples/nodejs/Structures/BaseCommand.js +++ /dev/null @@ -1,15 +0,0 @@ -const UtilCommand = require('./CommandResponse.js') -class BaseCommand extends UtilCommand { - constructor(data) { - super(data) - this.message = data.message - this.interaction = data.interaction - this.user = this.message ? this.message.author : this.interaction.user - this.guild = this.message ? this.message.guild : this.interaction.guild - this.member = this.message ? this.message.member : this.interaction.member - this.channel = this.message ? this.message.channel : this.interaction.channel - this.client = data.client - this.settings = data.settings ?? {} - } -} -module.exports = BaseCommand diff --git a/examples/nodejs/Structures/CommandResponse.js b/examples/nodejs/Structures/CommandResponse.js deleted file mode 100644 index 12ef58dce..000000000 --- a/examples/nodejs/Structures/CommandResponse.js +++ /dev/null @@ -1,50 +0,0 @@ -class Responses { - constructor(data) { - this.manager = data.manager - this.args = this._validateArguments(data.args) - this.replied = false - } - - async reply(content) { - // When just a string is passed, we assume it's the content -> transform to correct formatted payload - if (typeof content === 'string') content = { content } - if (this.interaction) { - if (this.replied) return this.followUp(content) - const reply = await this.interaction.reply(content) - this.replied = true - return {} - } - if (this.message) { - if (this.replied) return this.followUp(content) - - const msg = await this.message.channel.send(content) - - // Assign properties to the response - const response = this.client.messages.forge(msg) - this.replied = true - return response - } - } - - async followUp(content) { - if (this.interaction) { - const reply = await this.interaction.followUp(content) - return {} - } - if (this.message) { - const msg = await this.message.channel.send(content) - const response = this.client.messages.forge(msg) - return response - } - } - - onError(error) { - return this.reply({ content: `A unknown Error happend: \n> ${error}` }) - } - - _validateArguments(args) { - this.args = args - return args - } -} -module.exports = Responses diff --git a/examples/nodejs/events/interactionCreate.js b/examples/nodejs/events/interactionCreate.js deleted file mode 100644 index 714d4a826..000000000 --- a/examples/nodejs/events/interactionCreate.js +++ /dev/null @@ -1,4 +0,0 @@ -module.exports = async (client, interaction) => { - interaction = client.interactions.forge(interaction) - client.commands.isInteraction(interaction) -} diff --git a/examples/nodejs/events/messageCreate.js b/examples/nodejs/events/messageCreate.js deleted file mode 100644 index cf34be528..000000000 --- a/examples/nodejs/events/messageCreate.js +++ /dev/null @@ -1,4 +0,0 @@ -module.exports = async (client, message) => { - message = client.messages.forge(message) - client.commands.isCommand(message) -} diff --git a/examples/nodejs/events/ready.js b/examples/nodejs/events/ready.js deleted file mode 100644 index 9b6fb1e23..000000000 --- a/examples/nodejs/events/ready.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = async (client, payload) => { - client.user = client.users.forge(payload.user) - if (payload.shardId === client.gateway.lastShardId) { - // All Shards are ready - console.log('Successfully connected to the gateway as ' + client.user.tag) - } -} diff --git a/examples/nodejs/index.js b/examples/nodejs/index.js deleted file mode 100644 index d01f027c5..000000000 --- a/examples/nodejs/index.js +++ /dev/null @@ -1,32 +0,0 @@ -require('dotenv').config() - -const Discord = require('discordeno.js') - -// Ideally you should switch this to .env but for a template a config json is enough -const config = require('./config.json') - -const EventManager = require('./Managers/EventManager.js') -// looping through all events and registering them -const events = new EventManager({}) - -const baseBot = Discord.createBot({ - events: events.load({}), - intents: Discord.Intents.Guilds | Discord.Intents.GuildMessages | Discord.Intents.MessageContent, - token: process.env.TOKEN, -}) -const client = Discord.enableCachePlugin(baseBot, {}) - -client.config = config - -// looping through all commands and registering them in .cache of the class -const CommandManager = require('./Managers/CommandManager.js') -client.commands = new CommandManager(client) -client.commands.load({}) - -// Starts your Bot -Discord.startBot(client) - -/* - * You should handle all errors and fix the issues in your codes... - * process.on('unhandledRejection', (reason, p) => {console.log(reason, p)}) - */ diff --git a/examples/nodejs/package.json b/examples/nodejs/package.json deleted file mode 100644 index 2a4e41316..000000000 --- a/examples/nodejs/package.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "nodejs-template", - "version": "1.0.0", - "description": "", - "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "keywords": [], - "author": "", - "license": "ISC", - "dependencies": { - "discordeno.js": "github:meister03/discordeno.js", - "dotenv": "^16.0.3" - } -}