A discord bot for teal.fm
discord tealfm music

Compare changes

Choose any two refs to compare.

+10
.dockerignore
··· 1 + node_modules 2 + **/node_modules 3 + **/*.md 4 + .git 5 + .gitignore 6 + **/dist 7 + .pnpm-store 8 + .DS_Store 9 + .env 10 + .env.*
+1 -1
.gitignore
··· 1 1 .env 2 - node_modules 2 + **/node_modules 3 3 dist
-1
.npmrc
··· 1 1 engine-strict=true 2 - use-node-version=24.12.0
+7
.oxfmtrc.json
··· 1 + { 2 + "$schema": "./node_modules/oxfmt/configuration_schema.json", 3 + "ignorePatterns": ["pnpm-lock.yaml", "**/migrations/**.ts"], 4 + "experimentalSortImports": { 5 + "order": "asc" 6 + } 7 + }
+5
.oxlintrc.json
··· 1 + { 2 + "$schema": "./node_modules/oxlint/configuration_schema.json", 3 + "ignorePatterns": ["**/migrations/**.ts"], 4 + "plugins": ["import", "node"] 5 + }
+18
.tangled/workflows/lint.yml
··· 1 + when: 2 + - event: ["push"] 3 + branch: main 4 + 5 + engine: nixery 6 + 7 + dependencies: 8 + nixpkgs: 9 + - nodejs_24 10 + - pnpm 11 + - gnused 12 + 13 + steps: 14 + - name: install 15 + command: pnpm i --frozen-lockfile 16 + 17 + - name: lint 18 + command: pnpm lint
+21
.tangled/workflows/typecheck.yml
··· 1 + when: 2 + - event: ["push"] 3 + branch: main 4 + 5 + engine: nixery 6 + 7 + dependencies: 8 + nixpkgs: 9 + - nodejs_24 10 + - pnpm 11 + - gnused 12 + 13 + steps: 14 + - name: install 15 + command: pnpm i --frozen-lockfile 16 + 17 + - name: build 18 + command: pnpm -r build 19 + 20 + - name: typecheck 21 + command: pnpm typecheck
+68
CONTRIBUTING.md
··· 1 + # Contributing to Disco Stu 2 + 3 + Thanks for your interest in contributing! This document gives a short quickstart and guidelines to help you get changes ready for review. 4 + 5 + ## Quickstart 6 + 7 + 1. Fork the repository and create a feature branch from `main`: 8 + 9 + ```bash 10 + git checkout -b feat/describe-thing 11 + ``` 12 + 13 + 2. Install dependencies: 14 + 15 + ```bash 16 + pnpm install 17 + ``` 18 + 19 + 3. Run the app you are working on (examples): 20 + 21 + ```bash 22 + # Bot 23 + pnpm bot 24 + 25 + # Tapper 26 + pnpm tap 27 + 28 + # Web 29 + pnpm web 30 + 31 + # Build everything 32 + pnpm build 33 + ``` 34 + 35 + 4. Run typechecks and format/lint before pushing: 36 + 37 + ```bash 38 + pnpm typecheck 39 + pnpm lint 40 + pnpm format 41 + ``` 42 + 43 + ## Development workflow 44 + 45 + - Work on a small, focused branch per change. 46 + - Keep commits atomic and with clear messages (imperative tense): `add ping command`, `fix db migration`. 47 + - Rebase or squash as appropriate to keep history clean for PRs. 48 + 49 + ## Tests, linting, and formatting 50 + 51 + - This repo uses `oxfmt` and `oxlint` at the workspace root. Run them locally before opening a PR. 52 + - Run TypeScript checks with `pnpm typecheck`. 53 + 54 + ## Submitting a PR 55 + 56 + - Open a pull request against `main` with a clear description of the change and why itโ€™s needed. 57 + - Include any relevant reproduction steps, screenshots, or logs. 58 + - If your change affects runtime behavior, add or update documentation in `README.md`. 59 + - Link any related issue numbers in the PR description. 60 + 61 + ## Commit message guidance 62 + 63 + - Use short, descriptive commit messages. 64 + - Prefer present-tense verbs: `add`, `fix`, `update`. 65 + 66 + ## Reporting bugs 67 + 68 + - Open an issue with steps to reproduce, expected vs actual behavior, and relevant logs or error messages.
+74
Dockerfile
··· 1 + FROM node:24-alpine AS base 2 + ENV PNPM_HOME="/pnpm" 3 + ENV PATH="$PNPM_HOME:$PATH" 4 + RUN corepack enable 5 + 6 + USER root 7 + RUN mkdir -p /prod/web /prod/bot /prod/tapper && chown -R 1000:1000 /prod 8 + USER 1000 9 + 10 + ARG BUILD_DATE 11 + ARG SHA 12 + ARG VERSION 13 + ARG DID 14 + 15 + FROM base AS build 16 + COPY --chown=1000:1000 apps/bot /app 17 + COPY --chown=1000:1000 apps/tapper /app 18 + COPY --chown=1000:1000 apps/web /app 19 + 20 + COPY --chown=1000:1000 packages/common /app 21 + COPY --chown=1000:1000 packages/database /app 22 + COPY --chown=1000:1000 packages/tsconfig /app 23 + 24 + COPY --chown=1000:1000 package.json pnpm-lock.yaml pnpm-workspace.yaml /app/ 25 + WORKDIR /app 26 + 27 + RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile 28 + RUN pnpm run -r build 29 + RUN pnpm deploy --filter=./apps/web --prod /prod/web 30 + RUN pnpm deploy --filter=./apps/bot --prod /prod/bot 31 + RUN pnpm deploy --filter=./apps/tapper --prod /prod/tapper 32 + 33 + 34 + FROM base AS web 35 + COPY --from=build --chown=1000:1000 /prod/web /prod/web 36 + WORKDIR /prod/web 37 + EXPOSE 8002 38 + CMD ["node", "dist/index.js"] 39 + LABEL org.opencontainers.image.authors="Dane Miller 'me@dane.computer'" \ 40 + org.opencontainers.image.source="https://tangled.org/${DID}/tealfmbot" \ 41 + org.opencontainers.image.title="discostuweb" \ 42 + org.opencontainers.image.description="The web service for authentication for the disco stu discord bot" \ 43 + org.opencontainers.image.version=$VERSION \ 44 + org.opencontainers.image.created=$BUILD_DATE \ 45 + org.opencontainers.image.revision=$SHA \ 46 + org.opencontainers.image.licenses="MIT" 47 + 48 + 49 + FROM base AS bot 50 + COPY --from=build --chown=1000:1000 /prod/bot /prod/bot 51 + WORKDIR /prod/bot 52 + CMD ["node", "dist/main.js"] 53 + LABEL org.opencontainers.image.authors="Dane Miller 'me@dane.computer'" \ 54 + org.opencontainers.image.source="https://tangled.org/${DID}/tealfmbot" \ 55 + org.opencontainers.image.title="discostubot" \ 56 + org.opencontainers.image.description="A discord bot that displays your music listens based on your teal.fm records" \ 57 + org.opencontainers.image.version=$VERSION \ 58 + org.opencontainers.image.created=$BUILD_DATE \ 59 + org.opencontainers.image.revision=$SHA \ 60 + org.opencontainers.image.licenses="MIT" 61 + 62 + 63 + FROM base AS tapper 64 + COPY --from=build --chown=1000:1000 /prod/tapper /prod/tapper 65 + WORKDIR /prod/tapper 66 + CMD ["node", "dist/index.js"] 67 + LABEL org.opencontainers.image.authors="Dane Miller 'me@dane.computer'" \ 68 + org.opencontainers.image.source="https://tangled.org/${DID}/tealfmbot" \ 69 + org.opencontainers.image.title="discostutap" \ 70 + org.opencontainers.image.description="The backfill and firehose listener for teal.fm records" \ 71 + org.opencontainers.image.version=$VERSION \ 72 + org.opencontainers.image.created=$BUILD_DATE \ 73 + org.opencontainers.image.revision=$SHA \ 74 + org.opencontainers.image.licenses="MIT"
+21
LICENSE
··· 1 + MIT License 2 + 3 + Copyright (c) 2025 Dane Miller 4 + 5 + Permission is hereby granted, free of charge, to any person obtaining a copy 6 + of this software and associated documentation files (the "Software"), to deal 7 + in the Software without restriction, including without limitation the rights 8 + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 + copies of the Software, and to permit persons to whom the Software is 10 + furnished to do so, subject to the following conditions: 11 + 12 + The above copyright notice and this permission notice shall be included in all 13 + copies or substantial portions of the Software. 14 + 15 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 + SOFTWARE.
+20
PLAN.md
··· 1 + # rough notes on how I think this should work 2 + 3 + - we start of with no accounts 4 + - `/auth <did or handle>` sends user a link to log in with atproto account 5 + - after auth success, we take did and send http request to tap instance to start backfilling for repo 6 + - user can now use bot commands 7 + 8 + ## planned commands 9 + 10 + - `auth <did or handle>` sends user a link to log in with atproto account 11 + - `top <artist>`: top 10 listeners for artist (total amount of plays across all songs / albums) 12 + - `recent`: most recent play 13 + 14 + ## web interface for account management...maybe..? 15 + 16 + - link/unlink account (unlinking would basically delete an account and all their plays) 17 + 18 + ## authentication flow 19 + 20 + 1.
+167 -2
README.md
··· 1 - # Teal.fm Discord Bot 1 + # Disco Stu - Teal.fm Discord Bot 2 + 3 + This repository contains the Disco Stu Discord bot, supporting services, and shared packages used by the project. The workspace is a monorepo managed with pnpm and TypeScript; each app and package has its own package.json and build/dev scripts. 4 + 5 + **Repository Structure** 6 + 7 + - `apps/` : Application code (runtime programs and services) 8 + - `bot/` : Discord bot (commands, deploy script) 9 + - `tapper/` : Backfill client for Tap service 10 + - `web/` : Web server to handle OAuth 11 + - `packages/` : Shared libraries used across apps 12 + - `common/` : Logging and shared utilities 13 + - `database/` : Database access, Kysely migrations and seed scripts 14 + - `tsconfig/` : Shared TypeScript config packages 15 + 16 + **Apps** 17 + 18 + - `apps/bot` โ€” Discord bot 19 + - Entry: `apps/bot/main.ts`. 20 + - Key files: `apps/bot/commands/*.ts` (command handlers), `apps/bot/deploy-commands.ts` (registers commands with Discord), `apps/bot/discord.d.ts` (types). 21 + - Useful scripts (see [apps/bot/package.json](apps/bot/package.json)): 22 + - `dev` โ€” run bot in watch mode with `tsx --watch main.ts` 23 + - `deploy-commands` โ€” run `deploy-commands.ts` to push slash-command definitions to Discord 24 + - `build` โ€” compile TypeScript to `dist/` 25 + - `start` โ€” run compiled bot from `dist/main.js` 26 + 27 + - `apps/tapper` โ€” Tap client 28 + - Entry: `apps/tapper/index.ts`. 29 + - Purpose: Interact with tap service running at https://tap.xero.systems 30 + - Useful scripts (see [apps/tapper/package.json](apps/tapper/package.json)): 31 + - `dev` โ€” runs `NODE_ENV=development tsx index.ts` 32 + - `start` โ€” run compiled `dist/index.js` in production 33 + 34 + - `apps/web` โ€” Web server 35 + - Entry: `apps/web/index.ts`. 36 + - Integrates with AT Protocol APIs and provides OAuth/web endpoints. 37 + - Useful scripts (see [apps/web/package.json](apps/web/package.json)): 38 + - `dev` โ€” `tsx --watch index.ts` to run in dev 39 + - `build` โ€” compile TypeScript 40 + - `start` โ€” run compiled server from `dist/index.js` 41 + 42 + **Packages** 43 + 44 + - `packages/common` โ€” shared utilities and logging 45 + - Exports logging helpers and other common utilities used by apps. Build with `pnpm --filter @tealfmbot/common build` or use workspace protocol. 46 + - Scripts: `build`, `build:watch`, `typecheck` (see [packages/common/package.json](packages/common/package.json)). 47 + 48 + - `packages/database` โ€” Kysely-based database layer 49 + - Contains DB helpers, `migrate.ts`, `seed.ts`, and Kysely codegen support. 50 + - Scripts (see [packages/database/package.json](packages/database/package.json)): 51 + - `migrate` โ€” run `kysely migrate latest` to apply migrations 52 + - `codegen` โ€” run `kysely-codegen` to regenerate `database.d.ts` 53 + - `seed` โ€” run `tsx seed.ts` to seed data 54 + - `build`, `build:watch`, `typecheck` 55 + 56 + - `packages/tsconfig` โ€” shared TypeScript configs 57 + - Provides base tsconfig settings shared by other packages. 58 + 59 + **Top-level scripts** (see [package.json](package.json)) 60 + 61 + - `pnpm bot` โ€” start the bot dev script (`pnpm --filter bot dev`) 62 + - `pnpm tap` โ€” start the tapper dev script (`pnpm --filter tapper dev`) 63 + - `pnpm web` โ€” start the web app dev script (`pnpm --filter web dev`) 64 + - `pnpm build` โ€” run `pnpm -r build` to build all packages and apps 65 + - `pnpm build:watch` โ€” run watch builds across the monorepo 66 + - `pnpm dev:all` โ€” runs `dev` for all apps under `apps/` 67 + - `pnpm typecheck` โ€” run TypeScript checks across apps 68 + - `pnpm lint` โ€” run `oxlint` (project linter) 69 + - `pnpm format` โ€” run `oxfmt` to format code 70 + 71 + Developer workflow 72 + 73 + - Install dependencies: `pnpm install` (pnpm v10+ recommended) 74 + - Develop a single app: 75 + - Bot: `pnpm --filter bot dev` or `pnpm bot` 76 + - Tapper: `pnpm --filter tapper dev` or `pnpm tap` 77 + - Web: `pnpm --filter web dev` or `pnpm web` 78 + - Develop all apps concurrently: `pnpm dev:all` 79 + - Build all packages and apps: `pnpm build` 80 + 81 + Database tasks 82 + 83 + - Migrations are managed via Kysely. Run migrations from the `packages/database` package: 84 + 85 + ```bash 86 + pnpm --filter @tealfmbot/database migrate 87 + ``` 88 + 89 + - Regenerate types (codegen): 90 + 91 + ```bash 92 + pnpm --filter @tealfmbot/database codegen 93 + ``` 94 + 95 + Docker / deployment 96 + 97 + - `Dockerfile` and `docker-compose.prod.yml` are included for building and deploying container images. 98 + - The repository contains `build-and-publish-images.sh` to build and publish images (will be a CI thing eventually). 2 99 3 - who knows if i'll finish this 100 + Project tooling 101 + 102 + - `lefthook.yml` configures git hooks. 103 + - `oxlint` and `oxfmt` are used for linting and formatting. 104 + 105 + Notes & tips 106 + 107 + - To deploy Discord commands after changes, run the bot package `deploy-commands` script: 108 + 109 + ```bash 110 + pnpm --filter bot deploy-commands 111 + ``` 112 + 113 + **Contributing & Quickstart** 114 + 115 + If you want to contribute or get a local development environment running quickly, follow these steps: 116 + 117 + - Clone the repo and install dependencies: 118 + 119 + ```bash 120 + git clone https://tangled.org/dane.is.extraordinarily.cool/tealfmbot 121 + cd tealfmbot 122 + pnpm install 123 + ``` 124 + 125 + - Start and run database migrations 126 + 127 + ```bash 128 + docker compose -f docker-compose.dev.yml up -d 129 + 130 + cd packages/database 131 + 132 + pnpm migrate 133 + ``` 134 + 135 + - Start individual apps in development: 136 + 137 + ```bash 138 + # Bot 139 + pnpm bot 140 + 141 + # Tapper 142 + pnpm tap 143 + 144 + # Web 145 + pnpm web 146 + ``` 147 + 148 + - Start all apps concurrently (monorepo dev): 149 + 150 + ```bash 151 + pnpm dev:all 152 + ``` 153 + 154 + - Build everything: 155 + 156 + ```bash 157 + pnpm build 158 + ``` 159 + 160 + - Run TypeScript checks and format/lint before opening a PR: 161 + 162 + ```bash 163 + pnpm typecheck 164 + pnpm lint 165 + pnpm format 166 + ``` 167 + 168 + Please open issues or PRs for new features, and include clear reproduction steps and expected behavior.
+20
apps/bot/commands/auth.ts
··· 1 + import { env } from "@tealfmbot/common/constants"; 2 + import { logger } from "@tealfmbot/common/logger"; 3 + import { ChatInputCommandInteraction, SlashCommandBuilder } from "discord.js"; 4 + 5 + const LOGIN_URL = 6 + process.env.NODE_ENV === "development" ? `127.0.0.1:${env.WEB_SERVICE_PORT}` : env.PUBLIC_URL; 7 + 8 + export default { 9 + data: new SlashCommandBuilder() 10 + .setName("login") 11 + .setDescription( 12 + "Authenticate with your Atmosphere account and request your listens to be tracked", 13 + ), 14 + async execute(interaction: ChatInputCommandInteraction) { 15 + await interaction.reply(`Log in here and request to be tracked: ${LOGIN_URL}/login`); 16 + logger.info( 17 + `starting authentication process for ${interaction.user.username} in guild ${interaction.guildId} at ${new Date().toJSON()}`, 18 + ); 19 + }, 20 + };
+10
apps/bot/commands/ping.ts
··· 1 + import { logger } from "@tealfmbot/common/logger"; 2 + import { CommandInteraction, SlashCommandBuilder } from "discord.js"; 3 + 4 + export default { 5 + data: new SlashCommandBuilder().setName("ping").setDescription("replies with pong"), 6 + async execute(interaction: CommandInteraction) { 7 + await interaction.reply("pong lol"); 8 + logger.info("ping command sent"); 9 + }, 10 + };
+17
apps/bot/commands/recent.ts
··· 1 + import { logger } from "@tealfmbot/common/logger"; 2 + // import {db} from "@tealfmbot/database/db" 3 + import { ChatInputCommandInteraction, SlashCommandBuilder } from "discord.js"; 4 + 5 + export default { 6 + data: new SlashCommandBuilder() 7 + .setName("recent") 8 + .setDescription( 9 + "Show your most recently played track", 10 + ), 11 + async execute(interaction: ChatInputCommandInteraction) { 12 + await interaction.reply("recent"); 13 + logger.info( 14 + `fetching recent track for ${interaction.user.username} in guild ${interaction.guildId} at ${new Date().toJSON()}`, 15 + ); 16 + }, 17 + };
+12
apps/bot/commands/top.ts
··· 1 + import { logger } from "@tealfmbot/common/logger"; 2 + import { CommandInteraction, SlashCommandBuilder } from "discord.js"; 3 + 4 + export default { 5 + data: new SlashCommandBuilder() 6 + .setName("top") 7 + .setDescription("Find the top listeners for the specified artist(s)"), 8 + async execute(interaction: CommandInteraction) { 9 + await interaction.reply("placeholder"); 10 + logger.info("top command sent"); 11 + }, 12 + };
+36
apps/bot/deploy-commands.ts
··· 1 + import { env } from "@tealfmbot/common/constants"; 2 + import { REST, Routes } from "discord.js"; 3 + import fs from "node:fs"; 4 + import path from "node:path"; 5 + 6 + const commands = []; 7 + const commandPaths = fs.globSync("dist/commands/*.js"); 8 + 9 + for await (const cmdPath of commandPaths) { 10 + const absoluteCommandPath = path.join(import.meta.dirname, cmdPath); 11 + const command = await import(absoluteCommandPath); 12 + if ("data" in command.default && "execute" in command.default) { 13 + commands.push(command.default.data); 14 + } else { 15 + console.warn( 16 + `[Warning] The command at ${absoluteCommandPath} is missing a required "data" or "execute" property.`, 17 + ); 18 + } 19 + } 20 + 21 + const rest = new REST().setToken(env.DISCORD_BOT_TOKEN); 22 + 23 + (async () => { 24 + try { 25 + console.log(`Started refreshing ${commands.length} application (/) commands.`); 26 + 27 + const data = (await rest.put( 28 + Routes.applicationGuildCommands(env.DISCORD_APPLICATION_ID, env.DISCORD_GUILD_ID), 29 + { body: commands }, 30 + )) as unknown[]; 31 + 32 + console.log(`Successfully reloaded ${data.length} application (/) commands.`); 33 + } catch (error) { 34 + console.error(error); 35 + } 36 + })();
+7
apps/bot/discord.d.ts
··· 1 + import { Collection } from "discord.js"; 2 + 3 + declare module "discord.js" { 4 + export interface Client { 5 + commands: Collection<unknown, any>; 6 + } 7 + }
+53
apps/bot/main.ts
··· 1 + import { env } from "@tealfmbot/common/constants"; 2 + import { logger } from "@tealfmbot/common/logger"; 3 + import { Client, Collection, Events, GatewayIntentBits, MessageFlags } from "discord.js"; 4 + import fs from "node:fs"; 5 + import path from "node:path"; 6 + 7 + const client = new Client({ intents: [GatewayIntentBits.Guilds] }); 8 + 9 + client.once(Events.ClientReady, (readyClient) => { 10 + console.log(`teal.fm bot ready and logged in as ${readyClient.user.tag}`); 11 + }); 12 + 13 + client.login(env.DISCORD_BOT_TOKEN); 14 + 15 + client.on(Events.InteractionCreate, async (interaction) => { 16 + if (!interaction.isChatInputCommand()) return; 17 + const command = interaction.client.commands.get(interaction.commandName); 18 + if (!command) { 19 + console.error(`No command matching ${interaction.commandName} was found.`); 20 + return; 21 + } 22 + try { 23 + await command.execute(interaction); 24 + } catch (error) { 25 + console.error(error); 26 + if (interaction.replied || interaction.deferred) { 27 + await interaction.followUp({ 28 + content: "There was an error while executing this command!", 29 + flags: MessageFlags.Ephemeral, 30 + }); 31 + } else { 32 + await interaction.reply({ 33 + content: "There was an error while executing this command!", 34 + flags: MessageFlags.Ephemeral, 35 + }); 36 + } 37 + } 38 + }); 39 + 40 + client.commands = new Collection(); 41 + 42 + const commandPaths = fs.globSync("dist/commands/*.js"); 43 + for await (const file of commandPaths) { 44 + const absoluteCommandPath = path.join(import.meta.dirname, file); 45 + const command = await import(absoluteCommandPath); 46 + if ("data" in command.default && "execute" in command.default) { 47 + client.commands.set(command.default.data.name, command.default); 48 + } else { 49 + logger.warn( 50 + `[Warning] The command at ${absoluteCommandPath} is missing a required "data" or "execute" property.`, 51 + ); 52 + } 53 + }
+25
apps/bot/package.json
··· 1 + { 2 + "name": "bot", 3 + "version": "0.0.1", 4 + "private": true, 5 + "type": "module", 6 + "scripts": { 7 + "dev": "NODE_ENV=development tsx --watch main.ts", 8 + "deploy-commands": "tsx deploy-commands.ts", 9 + "build": "tsc", 10 + "watch": "tsc --watch", 11 + "start": "node dist/main.js", 12 + "typecheck": "tsc --noEmit" 13 + }, 14 + "dependencies": { 15 + "@tealfmbot/common": "workspace:*", 16 + "@tealfmbot/database": "workspace:*", 17 + "discord.js": "^14.25.1" 18 + }, 19 + "devDependencies": { 20 + "@tealfmbot/tsconfig": "workspace:*", 21 + "@types/node": "^25.0.3", 22 + "tsx": "^4.21.0", 23 + "typescript": "^5.9.3" 24 + } 25 + }
+7
apps/bot/tsconfig.json
··· 1 + { 2 + "extends": "@tealfmbot/tsconfig/tsconfig.node.json", 3 + "compilerOptions": { 4 + "outDir": "./dist" 5 + }, 6 + "exclude": ["node_modules"] 7 + }
+47
apps/tapper/index.ts
··· 1 + import { SimpleIndexer, Tap } from "@atproto/tap"; 2 + import { env } from "@tealfmbot/common/constants"; 3 + import { db } from "@tealfmbot/database/db"; 4 + 5 + import { isTealRecord } from "./utils"; 6 + 7 + const tap = new Tap("https://tap.xero.systems", { 8 + adminPassword: env.TAP_ADMIN_PASSWORD, 9 + }); 10 + 11 + const indexer = new SimpleIndexer(); 12 + 13 + indexer.record(async (evt, opts) => { 14 + const uri = `at://${evt.did}/${evt.collection}/${evt.rkey}`; 15 + if (evt.action === "create") { 16 + if (isTealRecord(evt.record)) { 17 + await db 18 + .insertInto("plays") 19 + .values({ 20 + cid: evt?.cid, 21 + rkey: evt?.rkey, 22 + uri, 23 + release_name: evt?.record?.releaseName, 24 + played_time: evt?.record?.playedTime, 25 + track_name: evt?.record?.trackName, 26 + indexed_at: new Date().toJSON(), 27 + live: evt.live, 28 + user_id: 1, 29 + }) 30 + .execute(); 31 + } 32 + console.log(evt.record); 33 + } else { 34 + console.log(`deleted: ${uri}`); 35 + } 36 + 37 + if (process.env.NODE_ENV === "development") { 38 + // we don't want to ack in development 39 + // @ts-ignore 40 + opts.ack = () => console.log('"acknowledged"'); 41 + } 42 + }); 43 + 44 + indexer.error((err) => console.error(err)); 45 + 46 + const channel = tap.channel(indexer); 47 + channel.start();
+22
apps/tapper/package.json
··· 1 + { 2 + "name": "tapper", 3 + "version": "0.0.1", 4 + "private": true, 5 + "type": "module", 6 + "scripts": { 7 + "dev": "NODE_ENV=development tsx index.ts", 8 + "start": "NODE_ENV=production node dist/index.js", 9 + "typecheck": "tsc --noEmit" 10 + }, 11 + "dependencies": { 12 + "@atproto/tap": "^0.0.2", 13 + "@tealfmbot/common": "workspace:*", 14 + "@tealfmbot/database": "workspace:*" 15 + }, 16 + "devDependencies": { 17 + "@tealfmbot/tsconfig": "workspace:*", 18 + "@types/node": "^25.0.3", 19 + "tsx": "^4.21.0", 20 + "typescript": "^5.9.3" 21 + } 22 + }
+7
apps/tapper/tsconfig.json
··· 1 + { 2 + "extends": "@tealfmbot/tsconfig/tsconfig.node.json", 3 + "compilerOptions": { 4 + "outDir": "./dist" 5 + }, 6 + "exclude": ["node_modules"] 7 + }
+24
apps/tapper/utils.ts
··· 1 + type TealRecord = { 2 + $type: "fm.teal.alpha.feed.play"; 3 + trackName: string; 4 + trackMbId?: string; 5 + recordingMbId?: string; 6 + duration?: number; 7 + releaseName?: string; 8 + releaseMbId?: string; 9 + isrc?: string; 10 + originUrl?: string; 11 + musicServiceBaseDomain?: string; 12 + submissionClientAgent?: string; 13 + playedTime?: Date; 14 + artists: Artist[]; 15 + }; 16 + 17 + type Artist = { 18 + artistMbId?: string; 19 + artistName?: string; 20 + }; 21 + 22 + export function isTealRecord(record: unknown): record is TealRecord { 23 + return (record as TealRecord).$type === "fm.teal.alpha.feed.play"; 24 + }
+15
apps/web/bin/gen-jwk
··· 1 + #!/usr/bin/env node 2 + 3 + 'use strict' 4 + 5 + import { JoseKey } from "@atproto/oauth-client-node" 6 + 7 + async function main() { 8 + const kid = Date.now().toString() 9 + const key = await JoseKey.generate(['ES256'], kid) 10 + const jwk = key.privateJwk 11 + 12 + console.log(JSON.stringify(jwk)) 13 + } 14 + 15 + main()
+57
apps/web/client.ts
··· 1 + import { 2 + Keyset, 3 + JoseKey, 4 + atprotoLoopbackClientMetadata, 5 + NodeOAuthClient, 6 + type OAuthClientMetadataInput, 7 + } from "@atproto/oauth-client-node"; 8 + import { env } from "@tealfmbot/common/constants"; 9 + import { db } from "@tealfmbot/database/db"; 10 + import assert from "node:assert"; 11 + 12 + import { SessionStore, StateStore } from "./storage.js"; 13 + 14 + const loadJwk = async () => { 15 + const raw = env.PRIVATE_KEYS; 16 + if (!raw) return undefined; 17 + const json = JSON.parse(raw); 18 + if (!json) return undefined; 19 + const keys = await Promise.all( 20 + json.map((jwk: string | Record<string, unknown>) => JoseKey.fromJWK(jwk)), 21 + ); 22 + return new Keyset(keys); 23 + }; 24 + 25 + const keyset = env.PUBLIC_URL && env.PRIVATE_KEYS ? await loadJwk() : undefined; 26 + 27 + assert(!env.PUBLIC_URL || keyset?.size, "PRIVATE_KEYS environment variable must be set"); 28 + 29 + const pk = keyset?.findPrivateKey({ usage: "sign" }); 30 + 31 + const metadata: OAuthClientMetadataInput = env.PUBLIC_URL 32 + ? { 33 + client_name: "Disco Stu - Teal.fm Discord Bot", 34 + client_id: `${env.PUBLIC_URL}/oauth-client-metadata.json`, 35 + jwks_uri: `${env.PUBLIC_URL}/.well-known/jwks.json`, 36 + redirect_uris: [`${env.PUBLIC_URL}/oauth/callback`], 37 + scope: "atproto", 38 + grant_types: ["authorization_code", "refresh_token"], 39 + response_types: ["code"], 40 + application_type: "web", 41 + token_endpoint_auth_method: pk ? "private_key_jwt" : "none", 42 + token_endpoint_auth_signing_alg: pk ? pk.alg : undefined, 43 + dpop_bound_access_tokens: true, 44 + } 45 + : atprotoLoopbackClientMetadata( 46 + `http://localhost?${new URLSearchParams([ 47 + ["redirect_uri", `http://127.0.0.1:${env.WEB_SERVICE_PORT}/oauth/callback`], 48 + ["scope", "atproto"], 49 + ])}`, 50 + ); 51 + 52 + export const client = new NodeOAuthClient({ 53 + ...(typeof keyset !== "undefined" ? { keyset } : undefined), 54 + clientMetadata: metadata, 55 + stateStore: new StateStore(db), 56 + sessionStore: new SessionStore(db), 57 + });
+169
apps/web/index.ts
··· 1 + import { serve, type HttpBindings } from "@hono/node-server"; 2 + import { env } from "@tealfmbot/common/constants"; 3 + import { logger } from "@tealfmbot/common/logger"; 4 + import { Hono } from "hono"; 5 + import { deleteCookie, getSignedCookie } from "hono/cookie"; 6 + import { html } from "hono/html"; 7 + import { validator } from "hono/validator"; 8 + import pinoHttpLogger from "pino-http"; 9 + 10 + import { client } from "./client.js"; 11 + import { 12 + createSession, 13 + getSessionAgent, 14 + MAX_AGE, 15 + validateIdentifier, 16 + getSession, 17 + } from "./utils.js"; 18 + 19 + type Variables = { 20 + logger: typeof logger; 21 + }; 22 + 23 + const app = new Hono<{ Bindings: HttpBindings; Variables: Variables }>(); 24 + 25 + app.use(async (c, next) => { 26 + await new Promise<void>((resolve) => 27 + pinoHttpLogger({ 28 + autoLogging: false, 29 + })(c.env.incoming, c.env.outgoing, () => resolve()), 30 + ); 31 + 32 + c.set("logger", c.env.incoming.log); 33 + 34 + await next(); 35 + }); 36 + 37 + app.get("/dashboard", async (c) => { 38 + const session = await getSession(c, env); 39 + if (session) { 40 + const agent = await getSessionAgent(c); 41 + return c.html(html` 42 + <h1>Dashboard</h1> 43 + <p>DID: ${agent?.assertDid}</p> 44 + <form method="post" action="/logout"> 45 + <button type="submit">Log out</button> 46 + </form> 47 + `); 48 + } 49 + return c.redirect("/login"); 50 + }); 51 + 52 + app.get("/health", (c) => { 53 + return c.json({ message: "OK" }, 200); 54 + }); 55 + 56 + app.get("/oauth-client-metadata.json", (c) => { 57 + c.header("Cache-Control", `max-age=${MAX_AGE}, public`); 58 + return c.json(client.clientMetadata); 59 + }); 60 + 61 + app.get("/.well-known/jwks.json", (c) => { 62 + c.header("Cache-Control", `max-age=${MAX_AGE}, public`); 63 + return c.json(client.jwks); 64 + }); 65 + 66 + app.get("/oauth/callback", async (c) => { 67 + c.header("Cache-Control", "no-store"); 68 + const params = new URLSearchParams(c.req.url.split("?")[1]); 69 + 70 + try { 71 + const session = await getSession(c, env); 72 + if (session) { 73 + try { 74 + const oauthSession = await client.restore(session); 75 + if (oauthSession) oauthSession.signOut(); 76 + } catch (error) { 77 + logger.warn({ error }, "oauth restore failed"); 78 + } 79 + } 80 + const oauth = await client.callback(params); 81 + const cookie = await createSession(oauth.session.did); 82 + c.header("Set-Cookie", cookie); 83 + } catch (error) { 84 + logger.error({ error }, "oauth callback failed"); 85 + } 86 + 87 + return c.redirect("/dashboard"); 88 + }); 89 + 90 + app.get("/login", async (c) => { 91 + const session = await getSession(c, env); 92 + if (session) { 93 + return c.redirect("/dashboard"); 94 + } 95 + 96 + return c.html( 97 + html` 98 + <form action="/login" method="post"> 99 + <label for="identifier">Identifier</label> 100 + <input id="identifier" name="identifier" type="text" placeholder="handle.bsky.social" required /> 101 + <button type="submit">Log in</button> 102 + </form> 103 + `, 104 + ); 105 + }); 106 + 107 + app.post( 108 + "/login", 109 + validator("form", (value, c) => { 110 + const identifier = value["identifier"]; 111 + if (typeof identifier !== "string" || !validateIdentifier(identifier)) { 112 + return c.json({ message: "Invalid handle, did or PDS URL" }, 400); 113 + } 114 + 115 + return { 116 + identifier, 117 + }; 118 + }), 119 + async (c) => { 120 + c.header("Cache-Control", "no-store"); 121 + const { identifier } = c.req.valid("form"); 122 + const ac = new AbortController(); 123 + try { 124 + const url = await client.authorize(identifier, { 125 + signal: ac.signal, 126 + }); 127 + return c.redirect(url.href.toString()); 128 + } catch (error) { 129 + logger.error({ error }, "oauth authorize failed"); 130 + return c.json({ message: "oauth authorize failed" }, 500); 131 + } 132 + }, 133 + ); 134 + 135 + app.post("/logout", async (c) => { 136 + c.header("Cache-Control", "no-store"); 137 + const session = await getSession(c, env); 138 + if (session) { 139 + try { 140 + const oauthSession = await client.restore(session); 141 + if (oauthSession) await oauthSession.signOut(); 142 + } catch (error) { 143 + logger.warn({ error }, "Failed to revoke credentials"); 144 + } 145 + } 146 + 147 + deleteCookie(c, "__teal_fm_bot_session"); 148 + 149 + return c.redirect("/login"); 150 + }); 151 + 152 + const server = serve({ 153 + fetch: app.fetch, 154 + port: 8002, 155 + }); 156 + 157 + process.on("SIGINT", () => { 158 + server.close(); 159 + process.exit(0); 160 + }); 161 + process.on("SIGTERM", () => { 162 + server.close((err) => { 163 + if (err) { 164 + console.error(err); 165 + process.exit(1); 166 + } 167 + process.exit(0); 168 + }); 169 + });
+30
apps/web/package.json
··· 1 + { 2 + "name": "web", 3 + "version": "0.0.1", 4 + "private": true, 5 + "type": "module", 6 + "scripts": { 7 + "dev": "tsx --watch index.ts", 8 + "build": "tsc", 9 + "start": "node dist/index.js", 10 + "watch": "tsc --watch", 11 + "typecheck": "tsc --noEmit" 12 + }, 13 + "dependencies": { 14 + "@atproto/api": "^0.18.8", 15 + "@atproto/did": "^0.2.3", 16 + "@atproto/oauth-client-node": "^0.3.13", 17 + "@atproto/syntax": "^0.4.2", 18 + "@hono/node-server": "^1.19.7", 19 + "@tealfmbot/common": "workspace:*", 20 + "@tealfmbot/database": "workspace:*", 21 + "hono": "^4.11.3", 22 + "pino-http": "^11.0.0" 23 + }, 24 + "devDependencies": { 25 + "@tealfmbot/tsconfig": "workspace:*", 26 + "@types/node": "^25.0.3", 27 + "tsx": "^4.21.0", 28 + "typescript": "^5.9.3" 29 + } 30 + }
+55
apps/web/storage.ts
··· 1 + import type { 2 + NodeSavedSession, 3 + NodeSavedSessionStore, 4 + NodeSavedState, 5 + NodeSavedStateStore, 6 + } from "@atproto/oauth-client-node"; 7 + import type { Database } from "@tealfmbot/database/types"; 8 + 9 + export class StateStore implements NodeSavedStateStore { 10 + constructor(private db: Database) {} 11 + async get(key: string): Promise<NodeSavedState | undefined> { 12 + const result = await this.db 13 + .selectFrom("auth_state") 14 + .selectAll() 15 + .where("key", "=", key) 16 + .executeTakeFirst(); 17 + if (!result) return; 18 + return JSON.parse(result.state); 19 + } 20 + async set(key: string, val: NodeSavedState) { 21 + const state = JSON.stringify(val); 22 + await this.db 23 + .insertInto("auth_state") 24 + .values({ key, state }) 25 + .onConflict((oc) => oc.column("key").doUpdateSet({ state })) 26 + .execute(); 27 + } 28 + async del(key: string) { 29 + await this.db.deleteFrom("auth_state").where("key", "=", key).execute(); 30 + } 31 + } 32 + 33 + export class SessionStore implements NodeSavedSessionStore { 34 + constructor(private db: Database) {} 35 + async get(key: string): Promise<NodeSavedSession | undefined> { 36 + const result = await this.db 37 + .selectFrom("auth_session") 38 + .selectAll() 39 + .where("key", "=", key) 40 + .executeTakeFirst(); 41 + if (!result) return; 42 + return JSON.parse(result.session); 43 + } 44 + async set(key: string, val: NodeSavedSession) { 45 + const session = JSON.stringify(val); 46 + await this.db 47 + .insertInto("auth_session") 48 + .values({ key, session }) 49 + .onConflict((oc) => oc.column("key").doUpdateSet({ session })) 50 + .execute(); 51 + } 52 + async del(key: string) { 53 + await this.db.deleteFrom("auth_session").where("key", "=", key).execute(); 54 + } 55 + }
+8
apps/web/tsconfig.json
··· 1 + { 2 + "extends": "@tealfmbot/tsconfig/tsconfig.node.json", 3 + "compilerOptions": { 4 + "outDir": "./dist", 5 + "target": "ESNext" 6 + }, 7 + "exclude": ["node_modules"] 8 + }
+67
apps/web/utils.ts
··· 1 + import type { Context } from "hono"; 2 + 3 + import { Agent } from "@atproto/api"; 4 + import { isAtprotoDid, isAtprotoDidWeb } from "@atproto/did"; 5 + import { isValidHandle } from "@atproto/syntax"; 6 + import { env } from "@tealfmbot/common/constants"; 7 + import { logger } from "@tealfmbot/common/logger"; 8 + import { deleteCookie, generateSignedCookie, getSignedCookie } from "hono/cookie"; 9 + 10 + import { client } from "./client.js"; 11 + 12 + export const MAX_AGE = process.env.NODE_ENV === "production" ? 60 : 0; 13 + 14 + export async function createSession(value: string) { 15 + const cookie = await generateSignedCookie("__teal_fm_bot_session", value, env.COOKIE_SECRET, { 16 + path: "/", 17 + secure: process.env.NODE_ENV === "production", 18 + httpOnly: true, 19 + sameSite: "lax", 20 + maxAge: 60 * 60 * 24 * 7, 21 + }); 22 + 23 + return cookie; 24 + } 25 + 26 + export async function getSessionAgent(c: Context) { 27 + c.header("Vary", "Cookie"); 28 + const session = await getSignedCookie(c, env.COOKIE_SECRET, "__teal_fm_bot_session"); 29 + if (!session) return null; 30 + c.header("Cache-Control", `max-age=${MAX_AGE}, private`); 31 + 32 + try { 33 + const oauthSession = await client.restore(session); 34 + return oauthSession ? new Agent(oauthSession) : null; 35 + } catch (error) { 36 + logger.warn({ error }, "oauth restore failed"); 37 + deleteCookie(c, "__teal_fm_bot_session"); 38 + return null; 39 + } 40 + } 41 + 42 + export async function getSession(c: Context, e: typeof env) { 43 + const session = await getSignedCookie(c, e.COOKIE_SECRET, "__teal_fm_bot_session"); 44 + return session; 45 + } 46 + 47 + export function isValidUrl(url: string) { 48 + if (URL.canParse(url)) { 49 + const pdsUrl = new URL(url); 50 + return pdsUrl.protocol === "http:" || pdsUrl.protocol === "https:"; 51 + } 52 + return false; 53 + } 54 + 55 + // https://github.com/bluesky-social/social-app/blob/main/src/lib/strings/handles.ts#L51 56 + export function validateIdentifier(input: string) { 57 + if (typeof input !== "string") return false; 58 + const results = { 59 + validHandle: isValidHandle(input), 60 + nonEmptyIdentifier: !input.trim(), 61 + validDid: isAtprotoDid(input), 62 + validUrl: isValidUrl(input), 63 + validDidWeb: isAtprotoDidWeb(input), 64 + }; 65 + 66 + return Object.values(results).includes(true); 67 + }
+28
build-and-publish-images.sh
··· 1 + SHA=$(git rev-parse HEAD) 2 + BUILD_DATE=$(date -u +%Y-%m-%dT%H:%M:%SZ) 3 + LAST_BUILT=$(date -u +%Y%m%d) 4 + VERSION=$(git describe --tags --abbrev=0) 5 + REGISTRY=atcr.io/besaid.zone 6 + 7 + services=( 8 + web 9 + bot 10 + tapper 11 + ) 12 + 13 + echo "building versioned containers with version ${VERSION#v} and tagging :latest" 14 + 15 + for svc in ${services[@]}; do 16 + docker buildx build \ 17 + -t $REGISTRY/discostu$svc:${VERSION#v} \ 18 + -t $REGISTRY/discostu$svc:latest \ 19 + --platform linux/amd64,linux/arm64 \ 20 + --target $svc \ 21 + --build-arg VERSION=${VERSION#v} \ 22 + --build-arg SHA=$SHA \ 23 + --build-arg DID=did:plc:qttsv4e7pu2jl3ilanfgc3zn \ 24 + --build-arg BUILD_DATE=$BUILD_DATE \ 25 + --pull \ 26 + --no-cache . 27 + # --push . 28 + done
-10
commands/utility/ping.ts
··· 1 - import { CommandInteraction, SlashCommandBuilder } from "discord.js"; 2 - 3 - export default { 4 - data: new SlashCommandBuilder().setName("ping").setDescription( 5 - "replies with pong", 6 - ), 7 - async execute(interaction: CommandInteraction) { 8 - await interaction.reply("pong lol"); 9 - }, 10 - };
-8
constants.ts
··· 1 - import { loadEnvFile } from "node:process" 2 - 3 - loadEnvFile() 4 - 5 - export const DISCORD_BOT_TOKEN = process.env.DISCORD_BOT_TOKEN as string; 6 - export const DISCORD_APPLICATION_ID = process.env.DISCORD_APPLICATION_ID as string; 7 - export const DISCORD_GUILD_ID = process.env.DISCORD_GUILD_ID as string; 8 - export const TAP_ADMIN_PASSWORD = process.env.TAP_ADMIN_PASSWORD as string;
-44
deploy-commands.ts
··· 1 - import { REST, Routes } from "discord.js"; 2 - import fs from "node:fs"; 3 - import path from "node:path"; 4 - import { 5 - DISCORD_APPLICATION_ID, 6 - DISCORD_BOT_TOKEN, 7 - DISCORD_GUILD_ID, 8 - } from "./constants.ts"; 9 - 10 - const commands = []; 11 - const commandPaths = fs.globSync("commands/**/*.ts"); 12 - 13 - for await (const cmdPath of commandPaths) { 14 - const absoluteCommandPath = path.join(import.meta.dirname, cmdPath) 15 - const command = await import(absoluteCommandPath) 16 - if ("data" in command.default && "execute" in command.default) { 17 - commands.push(command.default.data); 18 - } else { 19 - console.warn( 20 - `[Warning] The command at ${absoluteCommandPath} is missing a required "data" or "execute" property.`, 21 - ); 22 - } 23 - } 24 - 25 - const rest = new REST().setToken(DISCORD_BOT_TOKEN); 26 - 27 - (async () => { 28 - try { 29 - console.log( 30 - `Started refreshing ${commands.length} application (/) commands.`, 31 - ); 32 - 33 - const data = await rest.put( 34 - Routes.applicationGuildCommands(DISCORD_APPLICATION_ID, DISCORD_GUILD_ID), 35 - { body: commands }, 36 - ) as unknown[]; 37 - 38 - console.log( 39 - `Successfully reloaded ${data.length} application (/) commands.`, 40 - ); 41 - } catch (error) { 42 - console.error(error); 43 - } 44 - })();
-7
discord.d.ts
··· 1 - import { Collection } from "discord.js"; 2 - 3 - declare module "discord.js" { 4 - export interface Client { 5 - commands: Collection<unknown, any> 6 - } 7 - }
+16
docker-compose.dev.yml
··· 1 + services: 2 + db: 3 + image: postgres:18.1 4 + healthcheck: 5 + test: ["CMD-SHELL", "pg_isready -U postgres -d tealfmbotdb"] 6 + interval: 10s 7 + retries: 5 8 + start_period: 30s 9 + timeout: 10s 10 + restart: always 11 + environment: 12 + POSTGRES_USER: postgres 13 + POSTGRES_PASSWORD: password 14 + POSTGRES_DB: tealfmbotdb 15 + ports: 16 + - 5432:5432
+80
docker-compose.prod.yml
··· 1 + name: "Disco Stu Compose - Prod" 2 + services: 3 + web: 4 + container_name: web 5 + restart: always 6 + build: 7 + context: . 8 + dockerfile: atcr.io/besaid.zone/discostuweb:1.0 9 + target: web 10 + ports: 11 + - 8002:8002 12 + depends_on: 13 + db: 14 + condition: service_healthy 15 + bot: 16 + condition: service_started 17 + 18 + environment: 19 + PUBLIC_URL: "${PUBLIC_URL:?PUBLIC_URL is required}" 20 + PRIVATE_KEYS: "${PRIVATE_KEYS:?PRIVATE_KEYS is required}" 21 + COOKIE_SECRET: "${COOKIE_SECRET:?COOKIE_SECRET is required}" 22 + healthcheck: 23 + test: ["CMD", "wget", "-q", "--spider", "http://localhost:8002/health"] 24 + interval: 30s 25 + timeout: 10s 26 + retries: 3 27 + start_period: 10s 28 + 29 + tapper: 30 + container_name: tapper 31 + build: 32 + context: . 33 + dockerfile: atcr.io/besaid.zone/discostutapper:1.0 34 + target: tapper 35 + 36 + depends_on: 37 + db: 38 + condition: service_healthy 39 + 40 + environment: 41 + NODE_ENV: production 42 + TAP_ADMIN_PASSWORD: "${TAP_ADMIN_PASSWORD:?TAP_ADMIN_PASSWORD is required}" 43 + bot: 44 + container_name: bot 45 + restart: always 46 + build: 47 + context: . 48 + dockerfile: atcr.io/besaid.zone/discostubot:1.0 49 + target: bot 50 + 51 + depends_on: 52 + db: 53 + condition: service_healthy 54 + 55 + environment: 56 + NODE_ENV: production 57 + DISCORD_BOT_TOKEN: "${DISCORD_BOT_TOKEN:?DISCORD_BOT_TOKEN is required}" 58 + DISCORD_APPLICATION_ID: "${DISCORD_APPLICATION_ID:?DISCORD_APPLICATION_ID is required}" 59 + DISCORD_GUILD_ID: "${DISCORD_GUILD_ID:?DISCORD_GUILD_ID is required}" 60 + db: 61 + image: postgres:18.1 62 + healthcheck: 63 + test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"] 64 + interval: 10s 65 + retries: 5 66 + start_period: 30s 67 + timeout: 10s 68 + restart: always 69 + environment: 70 + POSTGRES_USER: "${POSTGRES_USER:?POSTGRES_USER is required}" 71 + POSTGRES_PASSWORD: "${POSTGRES_PASSWORD:?POSTGRES_PASSWORD is required}" 72 + POSTGRES_DB: "${POSTGRES_DB:?POSTGRES_DB is required}" 73 + ports: 74 + - 5432:5432 75 + 76 + volumes: 77 + - "postgres-data:/var/lib/postgresql/data" 78 + 79 + volumes: 80 + postgres-data:
docker-compose.yml

This is a binary file and will not be displayed.

+53
justfile
··· 1 + sha := `git rev-parse HEAD` 2 + build_date := `date -u +%Y-%m-%dT%H:%M:%SZ` 3 + registry := "atcr.io/besaid.zone" 4 + 5 + default: 6 + @just --list 7 + 8 + release: 9 + #!/usr/bin/env bash 10 + VERSION=$(git describe --tags --abbrev=0) 11 + services=( 12 + web 13 + tapper 14 + bot 15 + ) 16 + 17 + echo "building versioned containers with version ${VERSION#v} and tagging :latest" 18 + 19 + for svc in ${services[@]}; do 20 + docker buildx build \ 21 + -t "{{registry}}"/discostu$svc:${VERSION#v} \ 22 + -t "{{registry}}"/discostu$svc:latest \ 23 + --target $svc \ 24 + --build-arg VERSION=${VERSION#v} \ 25 + --build-arg SHA="{{sha}}" \ 26 + --build-arg DID=did:plc:qttsv4e7pu2jl3ilanfgc3zn \ 27 + --build-arg BUILD_DATE="{{build_date}}" \ 28 + --pull \ 29 + --no-cache \ 30 + --push . 31 + done 32 + 33 + latest: 34 + #!/usr/bin/env bash 35 + VERSION=$(git describe --tags --abbrev=0) 36 + services=( 37 + web 38 + tapper 39 + bot 40 + ) 41 + 42 + for svc in ${services[@]}; do 43 + docker buildx build \ 44 + -t "{{registry}}"/discostu$svc:latest \ 45 + --target $svc \ 46 + --build-arg VERSION=${VERSION#v} \ 47 + --build-arg SHA="{{sha}}" \ 48 + --build-arg DID=did:plc:qttsv4e7pu2jl3ilanfgc3zn \ 49 + --build-arg BUILD_DATE="{{build_date}}" \ 50 + --pull \ 51 + --no-cache \ 52 + --push . 53 + done
+6
lefthook.yml
··· 1 + pre-commit: 2 + jobs: 3 + - name: format 4 + run: pnpm format {staged_files} 5 + exclude: 6 + - "**/node_modules"
-58
main.ts
··· 1 - import { 2 - Client, 3 - Collection, 4 - Events, 5 - GatewayIntentBits, 6 - MessageFlags, 7 - } from "discord.js"; 8 - import fs from "node:fs"; 9 - import path from "node:path"; 10 - import { DISCORD_BOT_TOKEN } from "./constants.ts"; 11 - 12 - const client = new Client({ intents: [GatewayIntentBits.Guilds] }); 13 - 14 - client.once(Events.ClientReady, (readyClient) => { 15 - console.log(`teal.fm bot ready and logged in as ${readyClient.user.tag}`); 16 - }); 17 - 18 - client.login(DISCORD_BOT_TOKEN); 19 - 20 - client.on(Events.InteractionCreate, async (interaction) => { 21 - if (!interaction.isChatInputCommand()) return; 22 - const command = interaction.client.commands.get(interaction.commandName); 23 - if (!command) { 24 - console.error(`No command matching ${interaction.commandName} was found.`); 25 - return; 26 - } 27 - try { 28 - await command.execute(interaction); 29 - } catch (error) { 30 - console.error(error); 31 - if (interaction.replied || interaction.deferred) { 32 - await interaction.followUp({ 33 - content: "There was an error while executing this command!", 34 - flags: MessageFlags.Ephemeral, 35 - }); 36 - } else { 37 - await interaction.reply({ 38 - content: "There was an error while executing this command!", 39 - flags: MessageFlags.Ephemeral, 40 - }); 41 - } 42 - } 43 - }); 44 - 45 - client.commands = new Collection(); 46 - 47 - const commandPaths = fs.globSync("commands/**/*.ts"); 48 - for await (const file of commandPaths) { 49 - const absoluteCommandPath = path.join(import.meta.dirname, file); 50 - const command = await import(absoluteCommandPath); 51 - if ("data" in command.default && "execute" in command.default) { 52 - client.commands.set(command.default.data.name, command.default); 53 - } else { 54 - console.warn( 55 - `[Warning] The command at ${absoluteCommandPath} is missing a required "data" or "execute" property.`, 56 - ); 57 - } 58 - }
+26 -20
package.json
··· 1 1 { 2 2 "name": "tealfmbot", 3 3 "version": "0.0.1", 4 - "type": "module", 4 + "private": true, 5 5 "description": "A discord bot for teal.fm", 6 - "main": "main.ts", 7 - "scripts": { 8 - "dev": "tsx main.ts", 9 - "deploy-commands": "tsx deploy-commands.ts", 10 - "tapper:dev": "NODE_ENV=development tsx tapper.ts", 11 - "tapper:prod": "NODE_ENV=production tsx tapper.ts", 12 - "typecheck": "tsc --noEmit" 13 - }, 14 6 "keywords": [ 15 - "teal.fm", 16 - "atprotocol" 7 + "atprotocol", 8 + "music", 9 + "teal.fm" 17 10 ], 11 + "license": "MIT", 18 12 "author": "Dane Miller <me@dane.computer>", 19 - "license": "MIT", 20 - "packageManager": "pnpm@10.15.0", 21 - "dependencies": { 22 - "@atproto/tap": "^0.0.2", 23 - "discord.js": "^14.25.1", 24 - "kysely": "^0.28.9" 13 + "repository": {}, 14 + "scripts": { 15 + "bot": "pnpm --filter bot dev", 16 + "tap": "pnpm --filter tapper dev", 17 + "web": "pnpm --filter web dev", 18 + "build": "pnpm -r build", 19 + "web:watch": "pnpm --filter web watch", 20 + "bot:watch": "pnpm --filter bot watch", 21 + "common:watch": "pnpm --filter common watch", 22 + "database:watch": "pnpm --filter database watch", 23 + "watch": "run-p *:watch", 24 + "dev:all": "pnpm --filter './apps/**' dev", 25 + "typecheck": "pnpm --filter './{packages,apps}/**' typecheck", 26 + "lint": "oxlint", 27 + "format": "oxfmt --no-error-on-unmatched-pattern" 25 28 }, 26 29 "devDependencies": { 27 - "@types/node": "^25.0.3", 28 - "tsx": "^4.21.0", 30 + "lefthook": "^2.0.13", 31 + "npm-run-all": "^4.1.5", 32 + "oxfmt": "^0.20.0", 33 + "oxlint": "^1.35.0", 29 34 "typescript": "^5.9.3" 30 - } 35 + }, 36 + "packageManager": "pnpm@10.15.0" 31 37 }
+17
packages/.env.example
··· 1 + DISCORD_BOT_TOKEN= 2 + DISCORD_APPLICATION_ID= 3 + DISCORD_GUILD_ID= 4 + TAP_ADMIN_PASSWORD= 5 + 6 + # database credentials 7 + POSTGRES_USER=postgres 8 + POSTGRES_PASSWORD=password 9 + POSTGRES_DB=tealfmbotdb 10 + 11 + # needed for kysely codegen 12 + DATABASE_URL=postgres://postgres:password@localhost:5432/tealfmbotdb 13 + 14 + # oauth 15 + PUBLIC_URL= 16 + PRIVATE_KEYS= 17 + COOKIE_SECRET=
+19
packages/common/constants.ts
··· 1 + import { cleanEnv, str, num } from "envalid"; 2 + import path from "node:path"; 3 + import { loadEnvFile } from "node:process"; 4 + 5 + if (process.env.NODE_ENV !== "production") { 6 + loadEnvFile(path.join(import.meta.dirname, "../../.env")); 7 + } 8 + 9 + export const env = cleanEnv(process.env, { 10 + DISCORD_BOT_TOKEN: str(), 11 + DISCORD_APPLICATION_ID: str(), 12 + DISCORD_GUILD_ID: str(), 13 + TAP_ADMIN_PASSWORD: str(), 14 + DATABASE_URL: str({ devDefault: "postgres://postgres:password@localhost:5432/tealfmbotdb" }), 15 + PUBLIC_URL: str(), 16 + COOKIE_SECRET: str({ devDefault: "00000000000000000000000000000000" }), 17 + PRIVATE_KEYS: str(), 18 + WEB_SERVICE_PORT: num({ devDefault: 8002 }), 19 + });
+2
packages/common/index.ts
··· 1 + export * from "./constants.js"; 2 + export * from "./logger.js";
+13
packages/common/logger.ts
··· 1 + import pino from "pino"; 2 + 3 + export const logger = 4 + process.env.NODE_ENV === "production" 5 + ? pino() 6 + : pino({ 7 + transport: { 8 + target: "pino-pretty", 9 + options: { 10 + colorize: true, 11 + }, 12 + }, 13 + });
+30
packages/common/package.json
··· 1 + { 2 + "name": "@tealfmbot/common", 3 + "version": "0.0.0", 4 + "private": true, 5 + "type": "module", 6 + "imports": { 7 + "#*": "./dist/*" 8 + }, 9 + "exports": { 10 + "./*": { 11 + "types": "./*.ts", 12 + "default": "./dist/*.js" 13 + } 14 + }, 15 + "scripts": { 16 + "watch": "tsc --watch", 17 + "build": "tsc", 18 + "typecheck": "tsc --noEmit" 19 + }, 20 + "dependencies": { 21 + "envalid": "^8.1.1", 22 + "pino": "^10.1.0" 23 + }, 24 + "devDependencies": { 25 + "@tealfmbot/tsconfig": "workspace:*", 26 + "@types/node": "^22.15.3", 27 + "pino-pretty": "^13.1.3", 28 + "typescript": "5.9.2" 29 + } 30 + }
+11
packages/common/tsconfig.json
··· 1 + { 2 + "extends": "@tealfmbot/tsconfig/tsconfig.node.json", 3 + "compilerOptions": { 4 + "module": "NodeNext", 5 + "moduleResolution": "nodenext", 6 + "esModuleInterop": true, 7 + "declaration": true, 8 + "declarationMap": true, 9 + "outDir": "./dist" 10 + } 11 + }
+7
packages/database/.config/kysely.config.ts
··· 1 + import { defineConfig } from "kysely-ctl"; 2 + 3 + import { db as kysely } from "../db"; 4 + 5 + export default defineConfig({ 6 + kysely, 7 + });
+55
packages/database/database.d.ts
··· 1 + /** 2 + * This file was generated by kysely-codegen. 3 + * Please do not edit it manually. 4 + */ 5 + 6 + import type { ColumnType } from "kysely"; 7 + 8 + export type Generated<T> = 9 + T extends ColumnType<infer S, infer I, infer U> 10 + ? ColumnType<S, I | undefined, U> 11 + : ColumnType<T, T | undefined, T>; 12 + 13 + export type Timestamp = ColumnType<Date, Date | string, Date | string>; 14 + 15 + export interface Artists { 16 + artist_name: string; 17 + play_id: number; 18 + } 19 + 20 + export interface AuthSession { 21 + key: string; 22 + session: string; 23 + } 24 + 25 + export interface AuthState { 26 + key: string; 27 + state: string; 28 + } 29 + 30 + export interface Plays { 31 + cid: string | null; 32 + id: Generated<number>; 33 + indexed_at: Generated<Timestamp>; 34 + live: boolean | null; 35 + played_time: Timestamp | null; 36 + release_name: string | null; 37 + rkey: string | null; 38 + track_name: string; 39 + uri: string | null; 40 + user_id: number; 41 + } 42 + 43 + export interface Users { 44 + created_at: Generated<Timestamp>; 45 + did: string; 46 + id: Generated<number>; 47 + } 48 + 49 + export interface DB { 50 + artists: Artists; 51 + auth_session: AuthSession; 52 + auth_state: AuthState; 53 + plays: Plays; 54 + users: Users; 55 + }
+15
packages/database/db.ts
··· 1 + import { env } from "@tealfmbot/common/constants"; 2 + import { Kysely, PostgresDialect } from "kysely"; 3 + import { Pool } from "pg"; 4 + 5 + import type { DB } from "./database.js"; 6 + 7 + const dialect = new PostgresDialect({ 8 + pool: new Pool({ 9 + connectionString: env.DATABASE_URL, 10 + }), 11 + }); 12 + 13 + export const db = new Kysely<DB>({ 14 + dialect, 15 + });
+35
packages/database/migrate.ts
··· 1 + import { env } from "@tealfmbot/common/constants"; 2 + import { Kysely, Migrator, PostgresDialect, FileMigrationProvider } from "kysely"; 3 + import { run } from "kysely-migration-cli"; 4 + import fs from "node:fs/promises"; 5 + import path from "node:path"; 6 + import { Pool } from "pg"; 7 + 8 + import type { DB } from "./database.js"; 9 + 10 + async function migrateToLatest() { 11 + const migrationFolder = new URL("../migrations", import.meta.url).pathname; 12 + 13 + const db = new Kysely<DB>({ 14 + dialect: new PostgresDialect({ 15 + pool: new Pool({ 16 + connectionString: env.DATABASE_URL, 17 + }), 18 + }), 19 + }); 20 + 21 + const migrator = new Migrator({ 22 + db, 23 + provider: new FileMigrationProvider({ 24 + fs, 25 + path, 26 + migrationFolder, 27 + }), 28 + }); 29 + 30 + // @ts-ignore fix later 31 + run(db, migrator, migrationFolder); 32 + await db.destroy(); 33 + } 34 + 35 + migrateToLatest().catch((err) => console.error(err));
+39
packages/database/migrations/1766974086093_initial.ts
··· 1 + import { Kysely, sql } from "kysely"; 2 + 3 + export async function up(db: Kysely<any>): Promise<void> { 4 + await db.schema 5 + .createTable("users") 6 + .ifNotExists() 7 + .addColumn("id", "serial", (col) => col.primaryKey()) 8 + .addColumn("did", "varchar", (col) => col.notNull().unique()) 9 + .addColumn("created_at", "timestamp", (col) => col.defaultTo(sql`now()`).notNull()) 10 + .execute(); 11 + 12 + await db.schema 13 + .createTable("plays") 14 + .ifNotExists() 15 + .addColumn("id", "serial", (col) => col.primaryKey()) 16 + .addColumn("played_time", "timestamptz", (col) => col.notNull()) 17 + .addColumn("release_name", "varchar", (col) => col.notNull()) 18 + .addColumn("track_name", "varchar", (col) => col.notNull()) 19 + .addColumn("indexed_at", "timestamp", (col) => col.defaultTo(sql`now()`).notNull()) 20 + .addColumn("user_id", "integer", (col) => 21 + col.references("users.id").onDelete("cascade").notNull(), 22 + ) 23 + .execute(); 24 + 25 + await db.schema 26 + .createTable("artists") 27 + .ifNotExists() 28 + .addColumn("artist_name", "varchar", (col) => col.notNull()) 29 + .addColumn("play_id", "integer", (col) => 30 + col.references("plays.id").onDelete("cascade").notNull(), 31 + ) 32 + .execute(); 33 + } 34 + 35 + export async function down(db: Kysely<any>): Promise<void> { 36 + await db.schema.dropTable("users").execute(); 37 + await db.schema.dropTable("plays").execute(); 38 + await db.schema.dropTable("artists").execute(); 39 + }
+19
packages/database/migrations/1766974106212_oauth.ts
··· 1 + import { type Kysely } from "kysely"; 2 + 3 + export async function up(db: Kysely<any>): Promise<void> { 4 + await db.schema 5 + .createTable("auth_session") 6 + .addColumn("key", "varchar", (col) => col.primaryKey().unique()) 7 + .addColumn("session", "varchar", (col) => col.notNull()) 8 + .execute(); 9 + await db.schema 10 + .createTable("auth_state") 11 + .addColumn("key", "varchar", (col) => col.primaryKey().unique()) 12 + .addColumn("state", "varchar", (col) => col.notNull()) 13 + .execute(); 14 + } 15 + 16 + export async function down(db: Kysely<any>): Promise<void> { 17 + await db.schema.dropTable("auth_state").execute(); 18 + await db.schema.dropTable("auth_session").execute(); 19 + }
+17
packages/database/migrations/1767547891854_track_record_status.ts
··· 1 + import type { Kysely } from 'kysely' 2 + 3 + // `any` is required here since migrations should be frozen in time. alternatively, keep a "snapshot" db interface. 4 + export async function up(db: Kysely<any>): Promise<void> { 5 + // up migration code goes here... 6 + // note: up migrations are mandatory. you must implement this function. 7 + // For more info, see: https://kysely.dev/docs/migrations 8 + await db.schema.alterTable("plays").addColumn("live", "boolean").execute() 9 + } 10 + 11 + // `any` is required here since migrations should be frozen in time. alternatively, keep a "snapshot" db interface. 12 + export async function down(db: Kysely<any>): Promise<void> { 13 + // down migration code goes here... 14 + // note: down migrations are optional. you can safely delete this function. 15 + // For more info, see: https://kysely.dev/docs/migrations 16 + await db.schema.alterTable("plays").dropColumn("live").execute() 17 + }
+17
packages/database/migrations/1767553973566_add_cid_uri_rkey.ts
··· 1 + import type { Kysely } from 'kysely' 2 + 3 + // `any` is required here since migrations should be frozen in time. alternatively, keep a "snapshot" db interface. 4 + export async function up(db: Kysely<any>): Promise<void> { 5 + // up migration code goes here... 6 + // note: up migrations are mandatory. you must implement this function. 7 + // For more info, see: https://kysely.dev/docs/migrations 8 + await db.schema.alterTable("plays").addColumn("cid", "varchar").addColumn("uri", "varchar").addColumn("rkey", "varchar").execute() 9 + } 10 + 11 + // `any` is required here since migrations should be frozen in time. alternatively, keep a "snapshot" db interface. 12 + export async function down(db: Kysely<any>): Promise<void> { 13 + // down migration code goes here... 14 + // note: down migrations are optional. you can safely delete this function. 15 + // For more info, see: https://kysely.dev/docs/migrations 16 + await db.schema.alterTable("plays").dropColumn("cid").dropColumn("uri").dropColumn("rkey").execute() 17 + }
+18
packages/database/migrations/1767554974033_release_name_and_played_time_optional.ts
··· 1 + import type { Kysely } from 'kysely' 2 + 3 + // `any` is required here since migrations should be frozen in time. alternatively, keep a "snapshot" db interface. 4 + export async function up(db: Kysely<any>): Promise<void> { 5 + // up migration code goes here... 6 + // note: up migrations are mandatory. you must implement this function. 7 + // For more info, see: https://kysely.dev/docs/migrations 8 + await db.schema.alterTable("plays").alterColumn("release_name", (col) => col.dropNotNull()).alterColumn("played_time", (col) => col.dropNotNull()).execute() 9 + } 10 + 11 + // `any` is required here since migrations should be frozen in time. alternatively, keep a "snapshot" db interface. 12 + export async function down(db: Kysely<any>): Promise<void> { 13 + // down migration code goes here... 14 + // note: down migrations are optional. you can safely delete this function. 15 + // For more info, see: https://kysely.dev/docs/migrations 16 + await db.schema.alterTable("plays").alterColumn("played_time", (col) => col.setNotNull()) 17 + .alterColumn("release_name", (col) => col.setNotNull()).execute() 18 + }
+39
packages/database/package.json
··· 1 + { 2 + "name": "@tealfmbot/database", 3 + "version": "0.0.0", 4 + "private": true, 5 + "type": "module", 6 + "types": "./database.d.ts", 7 + "imports": { 8 + "#*": "./dist/*" 9 + }, 10 + "exports": { 11 + "./*": { 12 + "types": "./*.ts", 13 + "default": "./dist/*.js" 14 + } 15 + }, 16 + "scripts": { 17 + "watch": "tsc --watch", 18 + "build": "tsc", 19 + "migrate": "kysely migrate latest", 20 + "codegen": "kysely-codegen --dialect postgres --env-file='../.env' --out-file ./database.d.ts", 21 + "seed": "tsx seed.ts", 22 + "typecheck": "tsc --noEmit" 23 + }, 24 + "dependencies": { 25 + "@tealfmbot/common": "workspace:*", 26 + "@tealfmbot/tsconfig": "workspace:*", 27 + "kysely": "^0.28.9", 28 + "pg": "^8.16.3" 29 + }, 30 + "devDependencies": { 31 + "@types/node": "^22.15.3", 32 + "@types/pg": "^8.16.0", 33 + "kysely-codegen": "^0.19.0", 34 + "kysely-ctl": "^0.19.0", 35 + "kysely-migration-cli": "^0.4.2", 36 + "tsx": "^4.21.0", 37 + "typescript": "5.9.2" 38 + } 39 + }
+16
packages/database/seed.ts
··· 1 + // import { db } from "./db.ts" 2 + 3 + async function main() { 4 + // const result = await db.insertInto("users").values({ 5 + // did: "did:plc:qttsv4e7pu2jl3ilanfgc3zn" 6 + // }).returning(['did', 'created_at']) 7 + // .executeTakeFirst() 8 + // console.log({ result }) 9 + // const users = await db.selectFrom("users").select(["id", "did"]).execute() 10 + // console.log({ users }) 11 + // await db.deleteFrom("users").where("did", "=", "did:plc:qttsv4e7pu2jl3ilanfgc3zn").execute() 12 + // const plays = await db.selectFrom("plays").where("plays.user_id", "=", 4).select(["plays.played_time", "plays.track_name"]).execute() 13 + // console.log({ plays }) 14 + } 15 + 16 + main().catch((error) => console.error(error));
+11
packages/database/tsconfig.json
··· 1 + { 2 + "extends": "@tealfmbot/tsconfig/tsconfig.node.json", 3 + "exclude": ["node_modules"], 4 + "compilerOptions": { 5 + "rootDir": ".", 6 + "declaration": true, 7 + "declarationMap": true, 8 + "outDir": "./dist" 9 + }, 10 + "include": ["db.ts", "database.d.ts", "types.ts"] 11 + }
+5
packages/database/types.ts
··· 1 + import type { Kysely } from "kysely"; 2 + 3 + import type { DB } from "./database.js"; 4 + 5 + export type Database = Kysely<DB>;
+9
packages/tsconfig/package.json
··· 1 + { 2 + "name": "@tealfmbot/tsconfig", 3 + "version": "0.0.0", 4 + "private": true, 5 + "license": "MIT", 6 + "publishConfig": { 7 + "access": "public" 8 + } 9 + }
+17
packages/tsconfig/tsconfig.base.json
··· 1 + { 2 + "compilerOptions": { 3 + "module": "nodenext", 4 + "target": "esnext", 5 + "esModuleInterop": true, 6 + "sourceMap": true, 7 + "noUncheckedIndexedAccess": true, 8 + "exactOptionalPropertyTypes": true, 9 + "strict": true, 10 + "verbatimModuleSyntax": true, 11 + "isolatedModules": true, 12 + "emitDeclarationOnly": false, 13 + "noUncheckedSideEffectImports": true, 14 + "moduleDetection": "force", 15 + "skipLibCheck": true 16 + } 17 + }
+9
packages/tsconfig/tsconfig.node.json
··· 1 + { 2 + "extends": "./tsconfig.base.json", 3 + "compilerOptions": { 4 + "module": "ESNext", 5 + "moduleResolution": "bundler", 6 + "lib": ["esnext"], 7 + "types": ["node"] 8 + } 9 + }
+2811 -6
pnpm-lock.yaml
··· 3 3 settings: 4 4 autoInstallPeers: true 5 5 excludeLinksFromLockfile: false 6 + injectWorkspacePackages: true 6 7 7 8 importers: 8 9 9 10 .: 11 + devDependencies: 12 + lefthook: 13 + specifier: ^2.0.13 14 + version: 2.0.13 15 + npm-run-all: 16 + specifier: ^4.1.5 17 + version: 4.1.5 18 + oxfmt: 19 + specifier: ^0.20.0 20 + version: 0.20.0 21 + oxlint: 22 + specifier: ^1.35.0 23 + version: 1.35.0 24 + typescript: 25 + specifier: ^5.9.3 26 + version: 5.9.3 27 + 28 + apps/bot: 29 + dependencies: 30 + '@tealfmbot/common': 31 + specifier: workspace:* 32 + version: link:../../packages/common 33 + '@tealfmbot/database': 34 + specifier: workspace:* 35 + version: link:../../packages/database 36 + discord.js: 37 + specifier: ^14.25.1 38 + version: 14.25.1 39 + devDependencies: 40 + '@tealfmbot/tsconfig': 41 + specifier: workspace:* 42 + version: link:../../packages/tsconfig 43 + '@types/node': 44 + specifier: ^25.0.3 45 + version: 25.0.3 46 + tsx: 47 + specifier: ^4.21.0 48 + version: 4.21.0 49 + typescript: 50 + specifier: ^5.9.3 51 + version: 5.9.3 52 + 53 + apps/tapper: 10 54 dependencies: 11 55 '@atproto/tap': 12 56 specifier: ^0.0.2 13 57 version: 0.0.2 14 - discord.js: 15 - specifier: ^14.25.1 16 - version: 14.25.1 17 - kysely: 18 - specifier: ^0.28.9 19 - version: 0.28.9 58 + '@tealfmbot/common': 59 + specifier: workspace:* 60 + version: link:../../packages/common 61 + '@tealfmbot/database': 62 + specifier: workspace:* 63 + version: link:../../packages/database 64 + devDependencies: 65 + '@tealfmbot/tsconfig': 66 + specifier: workspace:* 67 + version: link:../../packages/tsconfig 68 + '@types/node': 69 + specifier: ^25.0.3 70 + version: 25.0.3 71 + tsx: 72 + specifier: ^4.21.0 73 + version: 4.21.0 74 + typescript: 75 + specifier: ^5.9.3 76 + version: 5.9.3 77 + 78 + apps/web: 79 + dependencies: 80 + '@atproto/api': 81 + specifier: ^0.18.8 82 + version: 0.18.8 83 + '@atproto/did': 84 + specifier: ^0.2.3 85 + version: 0.2.3 86 + '@atproto/oauth-client-node': 87 + specifier: ^0.3.13 88 + version: 0.3.13 89 + '@atproto/syntax': 90 + specifier: ^0.4.2 91 + version: 0.4.2 92 + '@hono/node-server': 93 + specifier: ^1.19.7 94 + version: 1.19.7(hono@4.11.3) 95 + '@tealfmbot/common': 96 + specifier: workspace:* 97 + version: link:../../packages/common 98 + '@tealfmbot/database': 99 + specifier: workspace:* 100 + version: link:../../packages/database 101 + hono: 102 + specifier: ^4.11.3 103 + version: 4.11.3 104 + pino-http: 105 + specifier: ^11.0.0 106 + version: 11.0.0 20 107 devDependencies: 108 + '@tealfmbot/tsconfig': 109 + specifier: workspace:* 110 + version: link:../../packages/tsconfig 21 111 '@types/node': 22 112 specifier: ^25.0.3 23 113 version: 25.0.3 ··· 28 118 specifier: ^5.9.3 29 119 version: 5.9.3 30 120 121 + packages/common: 122 + dependencies: 123 + envalid: 124 + specifier: ^8.1.1 125 + version: 8.1.1 126 + pino: 127 + specifier: ^10.1.0 128 + version: 10.1.0 129 + devDependencies: 130 + '@tealfmbot/tsconfig': 131 + specifier: workspace:* 132 + version: link:../tsconfig 133 + '@types/node': 134 + specifier: ^22.15.3 135 + version: 22.19.3 136 + pino-pretty: 137 + specifier: ^13.1.3 138 + version: 13.1.3 139 + typescript: 140 + specifier: 5.9.2 141 + version: 5.9.2 142 + 143 + packages/database: 144 + dependencies: 145 + '@tealfmbot/common': 146 + specifier: workspace:* 147 + version: link:../common 148 + '@tealfmbot/tsconfig': 149 + specifier: workspace:* 150 + version: link:../tsconfig 151 + kysely: 152 + specifier: ^0.28.9 153 + version: 0.28.9 154 + pg: 155 + specifier: ^8.16.3 156 + version: 8.16.3 157 + devDependencies: 158 + '@types/node': 159 + specifier: ^22.15.3 160 + version: 22.19.3 161 + '@types/pg': 162 + specifier: ^8.16.0 163 + version: 8.16.0 164 + kysely-codegen: 165 + specifier: ^0.19.0 166 + version: 0.19.0(kysely@0.28.9)(pg@8.16.3)(typescript@5.9.2) 167 + kysely-ctl: 168 + specifier: ^0.19.0 169 + version: 0.19.0(kysely@0.28.9)(typescript@5.9.2) 170 + kysely-migration-cli: 171 + specifier: ^0.4.2 172 + version: 0.4.2 173 + tsx: 174 + specifier: ^4.21.0 175 + version: 4.21.0 176 + typescript: 177 + specifier: 5.9.2 178 + version: 5.9.2 179 + 180 + packages/tsconfig: {} 181 + 31 182 packages: 32 183 184 + '@atproto-labs/did-resolver@0.2.4': 185 + resolution: {integrity: sha512-sbXxBnAJWsKv/FEGG6a/WLz7zQYUr1vA2TXvNnPwwJQJCjPwEJMOh1vM22wBr185Phy7D2GD88PcRokn7eUVyw==} 186 + 187 + '@atproto-labs/fetch-node@0.2.0': 188 + resolution: {integrity: sha512-Krq09nH/aeoiU2s9xdHA0FjTEFWG9B5FFenipv1iRixCcPc7V3DhTNDawxG9gI8Ny0k4dBVS9WTRN/IDzBx86Q==} 189 + engines: {node: '>=18.7.0'} 190 + 191 + '@atproto-labs/fetch@0.2.3': 192 + resolution: {integrity: sha512-NZtbJOCbxKUFRFKMpamT38PUQMY0hX0p7TG5AEYOPhZKZEP7dHZ1K2s1aB8MdVH0qxmqX7nQleNrrvLf09Zfdw==} 193 + 194 + '@atproto-labs/handle-resolver-node@0.1.23': 195 + resolution: {integrity: sha512-tBRr2LCgzn3klk+DL0xrTFv4zg5tEszdeW6vSIFVebBYSb3MLdfhievmSqZdIQ4c9UCC4hN7YXTlZCXj8+2YmQ==} 196 + engines: {node: '>=18.7.0'} 197 + 198 + '@atproto-labs/handle-resolver@0.3.4': 199 + resolution: {integrity: sha512-wsNopfzfgO3uPvfnFDgNeXgDufXxSXhjBjp2WEiSzEiLrMy0Jodnqggw4OzD9MJKf0a4Iu2/ydd537qdy91LrQ==} 200 + 201 + '@atproto-labs/identity-resolver@0.3.4': 202 + resolution: {integrity: sha512-HNUEFQIo2ws6iATxmgHd5D5rAsWYupgxZucgwolVHPiMjE1SY+EmxEsfbEN1wDEzM8/u9AKUg/jrxxPEwsgbew==} 203 + 204 + '@atproto-labs/pipe@0.1.1': 205 + resolution: {integrity: sha512-hdNw2oUs2B6BN1lp+32pF7cp8EMKuIN5Qok2Vvv/aOpG/3tNSJ9YkvfI0k6Zd188LeDDYRUpYpxcoFIcGH/FNg==} 206 + 207 + '@atproto-labs/simple-store-memory@0.1.4': 208 + resolution: {integrity: sha512-3mKY4dP8I7yKPFj9VKpYyCRzGJOi5CEpOLPlRhoJyLmgs3J4RzDrjn323Oakjz2Aj2JzRU/AIvWRAZVhpYNJHw==} 209 + 210 + '@atproto-labs/simple-store@0.3.0': 211 + resolution: {integrity: sha512-nOb6ONKBRJHRlukW1sVawUkBqReLlLx6hT35VS3imaNPwiXDxLnTK7lxw3Lrl9k5yugSBDQAkZAq3MPTEFSUBQ==} 212 + 213 + '@atproto/api@0.18.8': 214 + resolution: {integrity: sha512-Qo3sGd1N5hdHTaEWUBgptvPkULt2SXnMcWRhveSyctSd/IQwTMyaIH6E62A1SU+8xBSN5QLpoUJNE7iSrYM2Zg==} 215 + 33 216 '@atproto/common-web@0.4.7': 34 217 resolution: {integrity: sha512-vjw2+81KPo2/SAbbARGn64Ln+6JTI0FTI4xk8if0ebBfDxFRmHb2oSN1y77hzNq/ybGHqA2mecfhS03pxC5+lg==} 35 218 36 219 '@atproto/common@0.5.3': 37 220 resolution: {integrity: sha512-jMC9ikl8QbJcnh21upe9Gb9mIaSJWsdp8sgaelmntUtChWnxxvCC/pI3TBX11PT7XlHUE6UyuvY+S3hh6WZVEg==} 38 221 engines: {node: '>=18.7.0'} 222 + 223 + '@atproto/did@0.2.3': 224 + resolution: {integrity: sha512-VI8JJkSizvM2cHYJa37WlbzeCm5tWpojyc1/Zy8q8OOjyoy6X4S4BEfoP941oJcpxpMTObamibQIXQDo7tnIjg==} 225 + 226 + '@atproto/jwk-jose@0.1.11': 227 + resolution: {integrity: sha512-i4Fnr2sTBYmMmHXl7NJh8GrCH+tDQEVWrcDMDnV5DjJfkgT17wIqvojIw9SNbSL4Uf0OtfEv6AgG0A+mgh8b5Q==} 228 + 229 + '@atproto/jwk-webcrypto@0.2.0': 230 + resolution: {integrity: sha512-UmgRrrEAkWvxwhlwe30UmDOdTEFidlIzBC7C3cCbeJMcBN1x8B3KH+crXrsTqfWQBG58mXgt8wgSK3Kxs2LhFg==} 231 + 232 + '@atproto/jwk@0.6.0': 233 + resolution: {integrity: sha512-bDoJPvt7TrQVi/rBfBrSSpGykhtIriKxeYCYQTiPRKFfyRhbgpElF0wPXADjIswnbzZdOwbY63az4E/CFVT3Tw==} 39 234 40 235 '@atproto/lex-cbor@0.0.3': 41 236 resolution: {integrity: sha512-N8lCV3kK5ZcjSOWxKLWqzlnaSpK4isjXRZ0EqApl/5y9KB64s78hQ/U3KIE5qnPRlBbW5kSH3YACoU27u9nTOA==} ··· 46 241 '@atproto/lex-json@0.0.3': 47 242 resolution: {integrity: sha512-ZVcY7XlRfdPYvQQ2WroKUepee0+NCovrSXgXURM3Xv+n5jflJCoczguROeRr8sN0xvT0ZbzMrDNHCUYKNnxcjw==} 48 243 244 + '@atproto/lexicon@0.6.0': 245 + resolution: {integrity: sha512-5veb8aD+J5M0qszLJ+73KSFsFrJBgAY/nM1TSAJvGY7fNc9ZAT+PSUlmIyrdye9YznAZ07yktalls/TwNV7cHQ==} 246 + 247 + '@atproto/oauth-client-node@0.3.13': 248 + resolution: {integrity: sha512-k2qT5QM6Mj5I412IZOnktShmI1A5YbwLmLM4BkeEcbcOm7kU1Cr/H/zUC/zniCIj641ZudiXU80Bsyw4A6tejA==} 249 + engines: {node: '>=18.7.0'} 250 + 251 + '@atproto/oauth-client@0.5.11': 252 + resolution: {integrity: sha512-KyxKpnF988BI3m+4NNYDgkN6a2sPORD9uaOEGP4tnJLOvhMVHyATWwq3Jx4LOYotTFDOvLdheWcI1G9DozE88w==} 253 + 254 + '@atproto/oauth-types@0.5.2': 255 + resolution: {integrity: sha512-9DCDvtvCanTwAaU5UakYDO0hzcOITS3RutK5zfLytE5Y9unj0REmTDdN8Xd8YCfUJl7T/9pYpf04Uyq7bFTASg==} 256 + 49 257 '@atproto/syntax@0.4.2': 50 258 resolution: {integrity: sha512-X9XSRPinBy/0VQ677j8VXlBsYSsUXaiqxWVpGGxJYsAhugdQRb0jqaVKJFtm6RskeNkV6y9xclSUi9UYG/COrA==} 51 259 ··· 56 264 '@atproto/ws-client@0.0.4': 57 265 resolution: {integrity: sha512-dox1XIymuC7/ZRhUqKezIGgooZS45C6vHCfu0PnWjfvsLCK2kAlnvX4IBkA/WpcoijDhQ9ejChnFbo/sLmgvAg==} 58 266 engines: {node: '>=18.7.0'} 267 + 268 + '@atproto/xrpc@0.7.7': 269 + resolution: {integrity: sha512-K1ZyO/BU8JNtXX5dmPp7b5UrkLMMqpsIa/Lrj5D3Su+j1Xwq1m6QJ2XJ1AgjEjkI1v4Muzm7klianLE6XGxtmA==} 270 + 271 + '@babel/code-frame@7.27.1': 272 + resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} 273 + engines: {node: '>=6.9.0'} 274 + 275 + '@babel/helper-validator-identifier@7.28.5': 276 + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} 277 + engines: {node: '>=6.9.0'} 278 + 279 + '@commander-js/extra-typings@11.1.0': 280 + resolution: {integrity: sha512-GuvZ38d23H+7Tz2C9DhzCepivsOsky03s5NI+KCy7ke1FNUvsJ2oO47scQ9YaGGhgjgNW5OYYNSADmbjcSoIhw==} 281 + peerDependencies: 282 + commander: 11.1.x 59 283 60 284 '@discordjs/builders@1.13.1': 61 285 resolution: {integrity: sha512-cOU0UDHc3lp/5nKByDxkmRiNZBpdp0kx55aarbiAfakfKJHlxv/yFW1zmIqCAmwH5CRlrH9iMFKJMpvW4DPB+w==} ··· 241 465 cpu: [x64] 242 466 os: [win32] 243 467 468 + '@hono/node-server@1.19.7': 469 + resolution: {integrity: sha512-vUcD0uauS7EU2caukW8z5lJKtoGMokxNbJtBiwHgpqxEXokaHCBkQUmCHhjFB1VUTWdqj25QoMkMKzgjq+uhrw==} 470 + engines: {node: '>=18.14.1'} 471 + peerDependencies: 472 + hono: ^4 473 + 474 + '@oxfmt/darwin-arm64@0.20.0': 475 + resolution: {integrity: sha512-bjR5dqvrd9gxKYfYR0ljUu3/T3+TuDVWcwA7d+tsfmx9lqidlw3zhgBTblnjF1mrd1zkPMoc5zzq86GeSEt1cA==} 476 + cpu: [arm64] 477 + os: [darwin] 478 + 479 + '@oxfmt/darwin-x64@0.20.0': 480 + resolution: {integrity: sha512-esUDes8FlJX3IY4TVjFLgZrnZlIIyPDlhkCaHgGR3+z2eHFZOvQu68kTSpZLCEJmGXdSpU5rlveycQ6n8tk9ew==} 481 + cpu: [x64] 482 + os: [darwin] 483 + 484 + '@oxfmt/linux-arm64-gnu@0.20.0': 485 + resolution: {integrity: sha512-irE0RO9B0R6ziQE6kUVZtZ6IuTdRyuumn1cPWhDfpa0XUa5sE0ly8pjVsvJbj/J9qerVtidU05txeXBB5CirQg==} 486 + cpu: [arm64] 487 + os: [linux] 488 + 489 + '@oxfmt/linux-arm64-musl@0.20.0': 490 + resolution: {integrity: sha512-eXPBLwYJm26DCmwMwhelEwQMRwuGNaYhYZOhd+CYYsmVoF+h6L6dtjwj0Ovuu0Gqh18EL8vfsaoUvb+jr3vEBg==} 491 + cpu: [arm64] 492 + os: [linux] 493 + 494 + '@oxfmt/linux-x64-gnu@0.20.0': 495 + resolution: {integrity: sha512-dTPW38Hjgb7LoD2mNgyQGBaJ1hu5YgPrxImhl5Eb04eiws+ETCM0wrb2TWGduA+Nv3rHKn3vZEkMTEjklZXgRw==} 496 + cpu: [x64] 497 + os: [linux] 498 + 499 + '@oxfmt/linux-x64-musl@0.20.0': 500 + resolution: {integrity: sha512-b4duw9JGDK/kZoqrPNU9tBOOZQdUW8KJPZ7gW7z54X1eGSqCJ1PT0XLNmZ7SOA1BzQwQ0a3qmQWfFVOsH3a5bw==} 501 + cpu: [x64] 502 + os: [linux] 503 + 504 + '@oxfmt/win32-arm64@0.20.0': 505 + resolution: {integrity: sha512-XAzvBhw4K+Fe16dBaFgYAdob9WaM8RYEXl0ibbm5NlNaQEq+5bH9xwc0oaYlHFnLfcgXWmn9ceTAYqNlONQRNA==} 506 + cpu: [arm64] 507 + os: [win32] 508 + 509 + '@oxfmt/win32-x64@0.20.0': 510 + resolution: {integrity: sha512-fkJqHbJaoOMRmrjHSljyb4/7BgXO3xPLBsJSFGtm3mpfW0HHFbAKvd4/6njhqJz9KY+b3RWP1WssjFshcqQQ4w==} 511 + cpu: [x64] 512 + os: [win32] 513 + 514 + '@oxlint/darwin-arm64@1.35.0': 515 + resolution: {integrity: sha512-ieiYVHkNZPo77Hgrxav595wGS4rRNKuDNrljf+4xhwpJsddrxMpM64IQUf2IvR3MhK4FxdGzhhB6OVmGVHY5/w==} 516 + cpu: [arm64] 517 + os: [darwin] 518 + 519 + '@oxlint/darwin-x64@1.35.0': 520 + resolution: {integrity: sha512-1jNHu3j66X5jKySvgtE+jGtjx4ye+xioAucVTi2IuROZO6keK2YG74pnD+9FT+DpWZAtWRZGoW0r0x6aN9sEEg==} 521 + cpu: [x64] 522 + os: [darwin] 523 + 524 + '@oxlint/linux-arm64-gnu@1.35.0': 525 + resolution: {integrity: sha512-T1lc0UaYbTxZyqVpLfC7eipbauNG8pBpkaZEW4JGz8Y68rxTH7d9s+CF0zxUxNr5RCtcmT669RLVjQT7VrKVLg==} 526 + cpu: [arm64] 527 + os: [linux] 528 + 529 + '@oxlint/linux-arm64-musl@1.35.0': 530 + resolution: {integrity: sha512-7Wv5Pke9kwWKFycUziSHsmi3EM0389TLzraB0KE/MArrKxx30ycwfJ5PYoMj9ERoW+Ybs0txdaOF/xJy/XyYkg==} 531 + cpu: [arm64] 532 + os: [linux] 533 + 534 + '@oxlint/linux-x64-gnu@1.35.0': 535 + resolution: {integrity: sha512-HDMPOzyVVy+rQl3H7UOq8oGHt7m1yaiWCanlhAu4jciK8dvXeO9OG/OQd74lD/h05IcJh93pCLEJ3wWOG8hTiQ==} 536 + cpu: [x64] 537 + os: [linux] 538 + 539 + '@oxlint/linux-x64-musl@1.35.0': 540 + resolution: {integrity: sha512-kAPBBsUOM3HQQ6n3nnZauvFR9EoXqCSoj4O3OSXXarzsRTiItNrHabVUwxeswZEc+xMzQNR0FHEWg/d4QAAWLw==} 541 + cpu: [x64] 542 + os: [linux] 543 + 544 + '@oxlint/win32-arm64@1.35.0': 545 + resolution: {integrity: sha512-qrpBkkOASS0WT8ra9xmBRXOEliN6D/MV9JhI/68lFHrtLhfFuRwg4AjzjxrCWrQCnQ0WkvAVpJzu73F4ICLYZw==} 546 + cpu: [arm64] 547 + os: [win32] 548 + 549 + '@oxlint/win32-x64@1.35.0': 550 + resolution: {integrity: sha512-yPFcj6umrhusnG/kMS5wh96vblsqZ0kArQJS+7kEOSJDrH+DsFWaDCsSRF8U6gmSmZJ26KVMU3C3TMpqDN4M1g==} 551 + cpu: [x64] 552 + os: [win32] 553 + 554 + '@pinojs/redact@0.4.0': 555 + resolution: {integrity: sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg==} 556 + 244 557 '@sapphire/async-queue@1.5.5': 245 558 resolution: {integrity: sha512-cvGzxbba6sav2zZkH8GPf2oGk9yYoD5qrNWdu9fRehifgnFZJMV+nuy2nON2roRO4yQQ+v7MK/Pktl/HgfsUXg==} 246 559 engines: {node: '>=v14.0.0', npm: '>=7.0.0'} ··· 253 566 resolution: {integrity: sha512-jjmJywLAFoWeBi1W7994zZyiNWPIiqRRNAmSERxyg93xRGzNYvGjlZ0gR6x0F4gPRi2+0O6S71kOZYyr3cxaIQ==} 254 567 engines: {node: '>=v14.0.0', npm: '>=7.0.0'} 255 568 569 + '@types/node@22.19.3': 570 + resolution: {integrity: sha512-1N9SBnWYOJTrNZCdh/yJE+t910Y128BoyY+zBLWhL3r0TYzlTmFdXrPwHL9DyFZmlEXNQQolTZh3KHV31QDhyA==} 571 + 256 572 '@types/node@25.0.3': 257 573 resolution: {integrity: sha512-W609buLVRVmeW693xKfzHeIV6nJGGz98uCPfeXI1ELMLXVeKYZ9m15fAMSaUPBHYLGFsVRcMmSCksQOrZV9BYA==} 574 + 575 + '@types/pg@8.16.0': 576 + resolution: {integrity: sha512-RmhMd/wD+CF8Dfo+cVIy3RR5cl8CyfXQ0tGgW6XBL8L4LM/UTEbNXYRbLwU6w+CgrKBNbrQWt4FUtTfaU5jSYQ==} 258 577 259 578 '@types/ws@8.18.1': 260 579 resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} ··· 267 586 resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} 268 587 engines: {node: '>=6.5'} 269 588 589 + ansi-styles@3.2.1: 590 + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} 591 + engines: {node: '>=4'} 592 + 593 + ansi-styles@4.3.0: 594 + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} 595 + engines: {node: '>=8'} 596 + 597 + argparse@2.0.1: 598 + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} 599 + 600 + array-buffer-byte-length@1.0.2: 601 + resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} 602 + engines: {node: '>= 0.4'} 603 + 604 + arraybuffer.prototype.slice@1.0.4: 605 + resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} 606 + engines: {node: '>= 0.4'} 607 + 608 + async-function@1.0.0: 609 + resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} 610 + engines: {node: '>= 0.4'} 611 + 270 612 atomic-sleep@1.0.0: 271 613 resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} 272 614 engines: {node: '>=8.0.0'} 615 + 616 + available-typed-arrays@1.0.7: 617 + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} 618 + engines: {node: '>= 0.4'} 619 + 620 + await-lock@2.2.2: 621 + resolution: {integrity: sha512-aDczADvlvTGajTDjcjpJMqRkOF6Qdz3YbPZm/PyW6tKPkx2hlYBzxMhEywM/tU72HrVZjgl5VCdRuMlA7pZ8Gw==} 622 + 623 + balanced-match@1.0.2: 624 + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} 273 625 274 626 base64-js@1.5.1: 275 627 resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} 276 628 629 + brace-expansion@1.1.12: 630 + resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} 631 + 632 + braces@3.0.3: 633 + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} 634 + engines: {node: '>=8'} 635 + 277 636 buffer@6.0.3: 278 637 resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} 279 638 639 + c12@3.3.3: 640 + resolution: {integrity: sha512-750hTRvgBy5kcMNPdh95Qo+XUBeGo8C7nsKSmedDmaQI+E0r82DwHeM6vBewDe4rGFbnxoa4V9pw+sPh5+Iz8Q==} 641 + peerDependencies: 642 + magicast: '*' 643 + peerDependenciesMeta: 644 + magicast: 645 + optional: true 646 + 647 + call-bind-apply-helpers@1.0.2: 648 + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} 649 + engines: {node: '>= 0.4'} 650 + 651 + call-bind@1.0.8: 652 + resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} 653 + engines: {node: '>= 0.4'} 654 + 655 + call-bound@1.0.4: 656 + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} 657 + engines: {node: '>= 0.4'} 658 + 659 + callsites@3.1.0: 660 + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} 661 + engines: {node: '>=6'} 662 + 663 + chalk@2.4.2: 664 + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} 665 + engines: {node: '>=4'} 666 + 667 + chalk@4.1.2: 668 + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} 669 + engines: {node: '>=10'} 670 + 671 + chokidar@5.0.0: 672 + resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==} 673 + engines: {node: '>= 20.19.0'} 674 + 675 + citty@0.1.6: 676 + resolution: {integrity: sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==} 677 + 678 + color-convert@1.9.3: 679 + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} 680 + 681 + color-convert@2.0.1: 682 + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} 683 + engines: {node: '>=7.0.0'} 684 + 685 + color-name@1.1.3: 686 + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} 687 + 688 + color-name@1.1.4: 689 + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} 690 + 691 + colorette@2.0.20: 692 + resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} 693 + 694 + commander@11.1.0: 695 + resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} 696 + engines: {node: '>=16'} 697 + 698 + concat-map@0.0.1: 699 + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} 700 + 701 + confbox@0.2.2: 702 + resolution: {integrity: sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==} 703 + 704 + consola@3.4.2: 705 + resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} 706 + engines: {node: ^14.18.0 || >=16.10.0} 707 + 708 + core-js@3.47.0: 709 + resolution: {integrity: sha512-c3Q2VVkGAUyupsjRnaNX6u8Dq2vAdzm9iuPj5FW0fRxzlxgq9Q39MDq10IvmQSpLgHQNyQzQmOo6bgGHmH3NNg==} 710 + 711 + cosmiconfig@9.0.0: 712 + resolution: {integrity: sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==} 713 + engines: {node: '>=14'} 714 + peerDependencies: 715 + typescript: '>=4.9.5' 716 + peerDependenciesMeta: 717 + typescript: 718 + optional: true 719 + 720 + cross-spawn@6.0.6: 721 + resolution: {integrity: sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==} 722 + engines: {node: '>=4.8'} 723 + 724 + data-view-buffer@1.0.2: 725 + resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} 726 + engines: {node: '>= 0.4'} 727 + 728 + data-view-byte-length@1.0.2: 729 + resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==} 730 + engines: {node: '>= 0.4'} 731 + 732 + data-view-byte-offset@1.0.1: 733 + resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} 734 + engines: {node: '>= 0.4'} 735 + 736 + dateformat@4.6.3: 737 + resolution: {integrity: sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==} 738 + 739 + define-data-property@1.1.4: 740 + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} 741 + engines: {node: '>= 0.4'} 742 + 743 + define-properties@1.2.1: 744 + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} 745 + engines: {node: '>= 0.4'} 746 + 747 + defu@6.1.4: 748 + resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} 749 + 750 + destr@2.0.5: 751 + resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==} 752 + 753 + diff@3.5.0: 754 + resolution: {integrity: sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==} 755 + engines: {node: '>=0.3.1'} 756 + 280 757 discord-api-types@0.38.37: 281 758 resolution: {integrity: sha512-Cv47jzY1jkGkh5sv0bfHYqGgKOWO1peOrGMkDFM4UmaGMOTgOW8QSexhvixa9sVOiz8MnVOBryWYyw/CEVhj7w==} 282 759 ··· 284 761 resolution: {integrity: sha512-2l0gsPOLPs5t6GFZfQZKnL1OJNYFcuC/ETWsW4VtKVD/tg4ICa9x+jb9bkPffkMdRpRpuUaO/fKkHCBeiCKh8g==} 285 762 engines: {node: '>=18'} 286 763 764 + dotenv-expand@12.0.3: 765 + resolution: {integrity: sha512-uc47g4b+4k/M/SeaW1y4OApx+mtLWl92l5LMPP0GNXctZqELk+YGgOPIIC5elYmUH4OuoK3JLhuRUYegeySiFA==} 766 + engines: {node: '>=12'} 767 + 768 + dotenv@16.6.1: 769 + resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} 770 + engines: {node: '>=12'} 771 + 772 + dotenv@17.2.3: 773 + resolution: {integrity: sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==} 774 + engines: {node: '>=12'} 775 + 776 + dunder-proto@1.0.1: 777 + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} 778 + engines: {node: '>= 0.4'} 779 + 780 + end-of-stream@1.4.5: 781 + resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} 782 + 783 + env-paths@2.2.1: 784 + resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} 785 + engines: {node: '>=6'} 786 + 787 + envalid@8.1.1: 788 + resolution: {integrity: sha512-vOUfHxAFFvkBjbVQbBfgnCO9d3GcNfMMTtVfgqSU2rQGMFEVqWy9GBuoSfHnwGu7EqR0/GeukQcL3KjFBaga9w==} 789 + engines: {node: '>=18'} 790 + 791 + error-ex@1.3.4: 792 + resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==} 793 + 794 + es-abstract@1.24.1: 795 + resolution: {integrity: sha512-zHXBLhP+QehSSbsS9Pt23Gg964240DPd6QCf8WpkqEXxQ7fhdZzYsocOr5u7apWonsS5EjZDmTF+/slGMyasvw==} 796 + engines: {node: '>= 0.4'} 797 + 798 + es-define-property@1.0.1: 799 + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} 800 + engines: {node: '>= 0.4'} 801 + 802 + es-errors@1.3.0: 803 + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} 804 + engines: {node: '>= 0.4'} 805 + 806 + es-object-atoms@1.1.1: 807 + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} 808 + engines: {node: '>= 0.4'} 809 + 810 + es-set-tostringtag@2.1.0: 811 + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} 812 + engines: {node: '>= 0.4'} 813 + 814 + es-to-primitive@1.3.0: 815 + resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} 816 + engines: {node: '>= 0.4'} 817 + 287 818 esbuild@0.27.2: 288 819 resolution: {integrity: sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==} 289 820 engines: {node: '>=18'} 290 821 hasBin: true 291 822 823 + escape-string-regexp@1.0.5: 824 + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} 825 + engines: {node: '>=0.8.0'} 826 + 292 827 event-target-shim@5.0.1: 293 828 resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} 294 829 engines: {node: '>=6'} ··· 297 832 resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} 298 833 engines: {node: '>=0.8.x'} 299 834 835 + exsolve@1.0.8: 836 + resolution: {integrity: sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==} 837 + 838 + fast-copy@4.0.2: 839 + resolution: {integrity: sha512-ybA6PDXIXOXivLJK/z9e+Otk7ve13I4ckBvGO5I2RRmBU1gMHLVDJYEuJYhGwez7YNlYji2M2DvVU+a9mSFDlw==} 840 + 300 841 fast-deep-equal@3.1.3: 301 842 resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} 302 843 ··· 304 845 resolution: {integrity: sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==} 305 846 engines: {node: '>=6'} 306 847 848 + fast-safe-stringify@2.1.1: 849 + resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} 850 + 851 + fill-range@7.1.1: 852 + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} 853 + engines: {node: '>=8'} 854 + 855 + for-each@0.3.5: 856 + resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} 857 + engines: {node: '>= 0.4'} 858 + 859 + fs.realpath@1.0.0: 860 + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} 861 + 307 862 fsevents@2.3.3: 308 863 resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} 309 864 engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} 310 865 os: [darwin] 311 866 867 + function-bind@1.1.2: 868 + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} 869 + 870 + function.prototype.name@1.1.8: 871 + resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==} 872 + engines: {node: '>= 0.4'} 873 + 874 + functions-have-names@1.2.3: 875 + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} 876 + 877 + generator-function@2.0.1: 878 + resolution: {integrity: sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==} 879 + engines: {node: '>= 0.4'} 880 + 881 + get-caller-file@2.0.5: 882 + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} 883 + engines: {node: 6.* || 8.* || >= 10.*} 884 + 885 + get-intrinsic@1.3.0: 886 + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} 887 + engines: {node: '>= 0.4'} 888 + 889 + get-proto@1.0.1: 890 + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} 891 + engines: {node: '>= 0.4'} 892 + 893 + get-symbol-description@1.1.0: 894 + resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} 895 + engines: {node: '>= 0.4'} 896 + 312 897 get-tsconfig@4.13.0: 313 898 resolution: {integrity: sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==} 314 899 900 + giget@2.0.0: 901 + resolution: {integrity: sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA==} 902 + hasBin: true 903 + 904 + git-diff@2.0.6: 905 + resolution: {integrity: sha512-/Iu4prUrydE3Pb3lCBMbcSNIf81tgGt0W1ZwknnyF62t3tHmtiJTRj0f+1ZIhp3+Rh0ktz1pJVoa7ZXUCskivA==} 906 + engines: {node: '>= 4.8.0'} 907 + 908 + glob@7.2.3: 909 + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} 910 + deprecated: Glob versions prior to v9 are no longer supported 911 + 912 + globalthis@1.0.4: 913 + resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} 914 + engines: {node: '>= 0.4'} 915 + 916 + gopd@1.2.0: 917 + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} 918 + engines: {node: '>= 0.4'} 919 + 920 + graceful-fs@4.2.11: 921 + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} 922 + 923 + has-bigints@1.1.0: 924 + resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} 925 + engines: {node: '>= 0.4'} 926 + 927 + has-flag@3.0.0: 928 + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} 929 + engines: {node: '>=4'} 930 + 931 + has-flag@4.0.0: 932 + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} 933 + engines: {node: '>=8'} 934 + 935 + has-property-descriptors@1.0.2: 936 + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} 937 + 938 + has-proto@1.2.0: 939 + resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==} 940 + engines: {node: '>= 0.4'} 941 + 942 + has-symbols@1.1.0: 943 + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} 944 + engines: {node: '>= 0.4'} 945 + 946 + has-tostringtag@1.0.2: 947 + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} 948 + engines: {node: '>= 0.4'} 949 + 950 + hasown@2.0.2: 951 + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} 952 + engines: {node: '>= 0.4'} 953 + 954 + help-me@5.0.0: 955 + resolution: {integrity: sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==} 956 + 957 + hono@4.11.3: 958 + resolution: {integrity: sha512-PmQi306+M/ct/m5s66Hrg+adPnkD5jiO6IjA7WhWw0gSBSo1EcRegwuI1deZ+wd5pzCGynCcn2DprnE4/yEV4w==} 959 + engines: {node: '>=16.9.0'} 960 + 961 + hosted-git-info@2.8.9: 962 + resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} 963 + 315 964 ieee754@1.2.1: 316 965 resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} 317 966 967 + import-fresh@3.3.1: 968 + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} 969 + engines: {node: '>=6'} 970 + 971 + inflight@1.0.6: 972 + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} 973 + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. 974 + 975 + inherits@2.0.4: 976 + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} 977 + 978 + internal-slot@1.1.0: 979 + resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} 980 + engines: {node: '>= 0.4'} 981 + 982 + interpret@1.4.0: 983 + resolution: {integrity: sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==} 984 + engines: {node: '>= 0.10'} 985 + 986 + ipaddr.js@2.3.0: 987 + resolution: {integrity: sha512-Zv/pA+ciVFbCSBBjGfaKUya/CcGmUHzTydLMaTwrUUEM2DIEO3iZvueGxmacvmN50fGpGVKeTXpb2LcYQxeVdg==} 988 + engines: {node: '>= 10'} 989 + 990 + is-array-buffer@3.0.5: 991 + resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} 992 + engines: {node: '>= 0.4'} 993 + 994 + is-arrayish@0.2.1: 995 + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} 996 + 997 + is-async-function@2.1.1: 998 + resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==} 999 + engines: {node: '>= 0.4'} 1000 + 1001 + is-bigint@1.1.0: 1002 + resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} 1003 + engines: {node: '>= 0.4'} 1004 + 1005 + is-boolean-object@1.2.2: 1006 + resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} 1007 + engines: {node: '>= 0.4'} 1008 + 1009 + is-callable@1.2.7: 1010 + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} 1011 + engines: {node: '>= 0.4'} 1012 + 1013 + is-core-module@2.16.1: 1014 + resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} 1015 + engines: {node: '>= 0.4'} 1016 + 1017 + is-data-view@1.0.2: 1018 + resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==} 1019 + engines: {node: '>= 0.4'} 1020 + 1021 + is-date-object@1.1.0: 1022 + resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} 1023 + engines: {node: '>= 0.4'} 1024 + 1025 + is-finalizationregistry@1.1.1: 1026 + resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==} 1027 + engines: {node: '>= 0.4'} 1028 + 1029 + is-generator-function@1.1.2: 1030 + resolution: {integrity: sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==} 1031 + engines: {node: '>= 0.4'} 1032 + 1033 + is-map@2.0.3: 1034 + resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} 1035 + engines: {node: '>= 0.4'} 1036 + 1037 + is-negative-zero@2.0.3: 1038 + resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} 1039 + engines: {node: '>= 0.4'} 1040 + 1041 + is-number-object@1.1.1: 1042 + resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} 1043 + engines: {node: '>= 0.4'} 1044 + 1045 + is-number@7.0.0: 1046 + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} 1047 + engines: {node: '>=0.12.0'} 1048 + 1049 + is-regex@1.2.1: 1050 + resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} 1051 + engines: {node: '>= 0.4'} 1052 + 1053 + is-set@2.0.3: 1054 + resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} 1055 + engines: {node: '>= 0.4'} 1056 + 1057 + is-shared-array-buffer@1.0.4: 1058 + resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} 1059 + engines: {node: '>= 0.4'} 1060 + 1061 + is-string@1.1.1: 1062 + resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} 1063 + engines: {node: '>= 0.4'} 1064 + 1065 + is-symbol@1.1.1: 1066 + resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} 1067 + engines: {node: '>= 0.4'} 1068 + 1069 + is-typed-array@1.1.15: 1070 + resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} 1071 + engines: {node: '>= 0.4'} 1072 + 1073 + is-weakmap@2.0.2: 1074 + resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} 1075 + engines: {node: '>= 0.4'} 1076 + 1077 + is-weakref@1.1.1: 1078 + resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==} 1079 + engines: {node: '>= 0.4'} 1080 + 1081 + is-weakset@2.0.4: 1082 + resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} 1083 + engines: {node: '>= 0.4'} 1084 + 1085 + isarray@2.0.5: 1086 + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} 1087 + 1088 + isexe@2.0.0: 1089 + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} 1090 + 318 1091 iso-datestring-validator@2.2.2: 319 1092 resolution: {integrity: sha512-yLEMkBbLZTlVQqOnQ4FiMujR6T4DEcCb1xizmvXS+OxuhwcbtynoosRzdMA69zZCShCNAbi+gJ71FxZBBXx1SA==} 320 1093 1094 + jiti@2.6.1: 1095 + resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} 1096 + hasBin: true 1097 + 1098 + jose@5.10.0: 1099 + resolution: {integrity: sha512-s+3Al/p9g32Iq+oqXxkW//7jk2Vig6FF1CFqzVXoTUXt2qz89YWbL+OwS17NFYEvxC35n0FKeGO2LGYSxeM2Gg==} 1100 + 1101 + joycon@3.1.1: 1102 + resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} 1103 + engines: {node: '>=10'} 1104 + 1105 + js-tokens@4.0.0: 1106 + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} 1107 + 1108 + js-yaml@4.1.1: 1109 + resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} 1110 + hasBin: true 1111 + 1112 + json-parse-better-errors@1.0.2: 1113 + resolution: {integrity: sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==} 1114 + 1115 + json-parse-even-better-errors@2.3.1: 1116 + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} 1117 + 1118 + kysely-codegen@0.19.0: 1119 + resolution: {integrity: sha512-ZpdQQnpfY0kh45CA6yPA9vdFsBE+b06Fx7QVcbL5rX//yjbA0yYGZGhnH7GTd4P4BY/HIv5uAfuOD83JVZf95w==} 1120 + engines: {node: '>=20.0.0'} 1121 + hasBin: true 1122 + peerDependencies: 1123 + '@libsql/kysely-libsql': '>=0.3.0 <0.5.0' 1124 + '@tediousjs/connection-string': '>=0.5.0 <0.6.0' 1125 + better-sqlite3: '>=7.6.2 <13.0.0' 1126 + kysely: '>=0.27.0 <1.0.0' 1127 + kysely-bun-sqlite: '>=0.3.2 <1.0.0' 1128 + kysely-bun-worker: '>=1.2.0 <2.0.0' 1129 + mysql2: '>=2.3.3 <4.0.0' 1130 + pg: '>=8.8.0 <9.0.0' 1131 + tarn: '>=3.0.0 <4.0.0' 1132 + tedious: '>=18.0.0 <20.0.0' 1133 + peerDependenciesMeta: 1134 + '@libsql/kysely-libsql': 1135 + optional: true 1136 + '@tediousjs/connection-string': 1137 + optional: true 1138 + better-sqlite3: 1139 + optional: true 1140 + kysely-bun-sqlite: 1141 + optional: true 1142 + kysely-bun-worker: 1143 + optional: true 1144 + mysql2: 1145 + optional: true 1146 + pg: 1147 + optional: true 1148 + tarn: 1149 + optional: true 1150 + tedious: 1151 + optional: true 1152 + 1153 + kysely-ctl@0.19.0: 1154 + resolution: {integrity: sha512-89hzOd1cy/H063jB2E9wYHq+uKYpaHv6Mb5RiNFpRZL6BYCah9ncsdl3x5b52eirxry4UyWSmGNN3sFv+gK+ig==} 1155 + engines: {node: '>=20'} 1156 + hasBin: true 1157 + peerDependencies: 1158 + kysely: '>=0.18.1 <0.29.0' 1159 + kysely-neon: ^2 1160 + kysely-postgres-js: ^2 || ^3 1161 + kysely-prisma-postgres: ^0.1 1162 + peerDependenciesMeta: 1163 + kysely-neon: 1164 + optional: true 1165 + kysely-postgres-js: 1166 + optional: true 1167 + kysely-prisma-postgres: 1168 + optional: true 1169 + 1170 + kysely-migration-cli@0.4.2: 1171 + resolution: {integrity: sha512-904MSUdzkdxl+k3C67ogvP6ogPOEr0D6ZZDtxAmDeIHEJxZAA+eC+TLAcJt3HQABTPetwsW3pj6y1MPmaveQUg==} 1172 + hasBin: true 1173 + 321 1174 kysely@0.28.9: 322 1175 resolution: {integrity: sha512-3BeXMoiOhpOwu62CiVpO6lxfq4eS6KMYfQdMsN/2kUCRNuF2YiEr7u0HLHaQU+O4Xu8YXE3bHVkwaQ85i72EuA==} 323 1176 engines: {node: '>=20.0.0'} 324 1177 1178 + lefthook-darwin-arm64@2.0.13: 1179 + resolution: {integrity: sha512-KbQqpNSNTugjtPzt97CNcy/XZy5asJ0+uSLoHc4ML8UCJdsXKYJGozJHNwAd0Xfci/rQlj82A7rPOuTdh0jY0Q==} 1180 + cpu: [arm64] 1181 + os: [darwin] 1182 + 1183 + lefthook-darwin-x64@2.0.13: 1184 + resolution: {integrity: sha512-s/vI6sEE8/+rE6CONZzs59LxyuSc/KdU+/3adkNx+Q13R1+p/AvQNeszg3LAHzXmF3NqlxYf8jbj/z5vBzEpRw==} 1185 + cpu: [x64] 1186 + os: [darwin] 1187 + 1188 + lefthook-freebsd-arm64@2.0.13: 1189 + resolution: {integrity: sha512-iQeJTU7Zl8EJlCMQxNZQpJFAQ9xl40pydUIv5SYnbJ4nqIr9ONuvrioNv6N2LtKP5aBl1nIWQQ9vMjgVyb3k+A==} 1190 + cpu: [arm64] 1191 + os: [freebsd] 1192 + 1193 + lefthook-freebsd-x64@2.0.13: 1194 + resolution: {integrity: sha512-99cAXKRIzpq/u3obUXbOQJCHP+0ZkJbN3TF+1ZQZlRo3Y6+mPSCg9fh/oi6dgbtu4gTI5Ifz3o5p2KZzAIF9ZQ==} 1195 + cpu: [x64] 1196 + os: [freebsd] 1197 + 1198 + lefthook-linux-arm64@2.0.13: 1199 + resolution: {integrity: sha512-RWarenY3kLy/DT4/8dY2bwDlYwlELRq9MIFq+FiMYmoBHES3ckWcLX2JMMlM49Y672paQc7MbneSrNUn/FQWhg==} 1200 + cpu: [arm64] 1201 + os: [linux] 1202 + 1203 + lefthook-linux-x64@2.0.13: 1204 + resolution: {integrity: sha512-QZRcxXGf8Uj/75ITBqoBh0zWhJE7+uFoRxEHwBq0Qjv55Q4KcFm7FBN/IFQCSd14reY5pmY3kDaWVVy60cAGJA==} 1205 + cpu: [x64] 1206 + os: [linux] 1207 + 1208 + lefthook-openbsd-arm64@2.0.13: 1209 + resolution: {integrity: sha512-LAuOWwnNmOlRE0RxKMOhIz5Kr9tXi0rCjzXtDARW9lvfAV6Br2wP+47q0rqQ8m/nVwBYoxfJ/RDunLbb86O1nA==} 1210 + cpu: [arm64] 1211 + os: [openbsd] 1212 + 1213 + lefthook-openbsd-x64@2.0.13: 1214 + resolution: {integrity: sha512-n9TIN3QLncyxOHomiKKwzDFHKOCm5H28CVNAZFouKqDwEaUGCs5TJI88V85j4/CgmLVUU8uUn4ClVCxIWYG59w==} 1215 + cpu: [x64] 1216 + os: [openbsd] 1217 + 1218 + lefthook-windows-arm64@2.0.13: 1219 + resolution: {integrity: sha512-sdSC4F9Di7y0t43Of9MOA5g/0CmvkM4juQ3sKfUhRcoygetLJn4PR2/pvuDOIaGf4mNMXBP5IrcKaeDON9HrcA==} 1220 + cpu: [arm64] 1221 + os: [win32] 1222 + 1223 + lefthook-windows-x64@2.0.13: 1224 + resolution: {integrity: sha512-ccl1v7Fl10qYoghEtjXN+JC1x/y/zLM/NSHf3NFGeKEGBNd1P5d/j6w8zVmhfzi+ekS8whXrcNbRAkLdAqUrSw==} 1225 + cpu: [x64] 1226 + os: [win32] 1227 + 1228 + lefthook@2.0.13: 1229 + resolution: {integrity: sha512-D39rCVl7/GpqakvhQvqz07SBpzUWTvWjXKnBZyIy8O6D+Lf9xD6tnbHtG5nWXd9iPvv1AKGQwL9R/e5rNtV6SQ==} 1230 + hasBin: true 1231 + 1232 + lines-and-columns@1.2.4: 1233 + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} 1234 + 1235 + load-json-file@4.0.0: 1236 + resolution: {integrity: sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==} 1237 + engines: {node: '>=4'} 1238 + 325 1239 lodash.snakecase@4.1.1: 326 1240 resolution: {integrity: sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==} 327 1241 328 1242 lodash@4.17.21: 329 1243 resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} 330 1244 1245 + loglevel@1.9.2: 1246 + resolution: {integrity: sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==} 1247 + engines: {node: '>= 0.6.0'} 1248 + 1249 + lru-cache@10.4.3: 1250 + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} 1251 + 331 1252 magic-bytes.js@1.12.1: 332 1253 resolution: {integrity: sha512-ThQLOhN86ZkJ7qemtVRGYM+gRgR8GEXNli9H/PMvpnZsE44Xfh3wx9kGJaldg314v85m+bFW6WBMaVHJc/c3zA==} 333 1254 1255 + math-intrinsics@1.1.0: 1256 + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} 1257 + engines: {node: '>= 0.4'} 1258 + 1259 + memorystream@0.3.1: 1260 + resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==} 1261 + engines: {node: '>= 0.10.0'} 1262 + 1263 + micromatch@4.0.8: 1264 + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} 1265 + engines: {node: '>=8.6'} 1266 + 1267 + minimatch@3.1.2: 1268 + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} 1269 + 1270 + minimist@1.2.8: 1271 + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} 1272 + 334 1273 multiformats@9.9.0: 335 1274 resolution: {integrity: sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==} 336 1275 1276 + nice-try@1.0.5: 1277 + resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==} 1278 + 1279 + node-fetch-native@1.6.7: 1280 + resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==} 1281 + 1282 + normalize-package-data@2.5.0: 1283 + resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} 1284 + 1285 + npm-run-all@4.1.5: 1286 + resolution: {integrity: sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==} 1287 + engines: {node: '>= 4'} 1288 + hasBin: true 1289 + 1290 + nypm@0.6.2: 1291 + resolution: {integrity: sha512-7eM+hpOtrKrBDCh7Ypu2lJ9Z7PNZBdi/8AT3AX8xoCj43BBVHD0hPSTEvMtkMpfs8FCqBGhxB+uToIQimA111g==} 1292 + engines: {node: ^14.16.0 || >=16.10.0} 1293 + hasBin: true 1294 + 1295 + object-inspect@1.13.4: 1296 + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} 1297 + engines: {node: '>= 0.4'} 1298 + 1299 + object-keys@1.1.1: 1300 + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} 1301 + engines: {node: '>= 0.4'} 1302 + 1303 + object.assign@4.1.7: 1304 + resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} 1305 + engines: {node: '>= 0.4'} 1306 + 1307 + ofetch@1.5.1: 1308 + resolution: {integrity: sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==} 1309 + 1310 + ohash@2.0.11: 1311 + resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==} 1312 + 337 1313 on-exit-leak-free@2.1.2: 338 1314 resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==} 339 1315 engines: {node: '>=14.0.0'} 340 1316 1317 + once@1.4.0: 1318 + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} 1319 + 1320 + own-keys@1.0.1: 1321 + resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} 1322 + engines: {node: '>= 0.4'} 1323 + 1324 + oxfmt@0.20.0: 1325 + resolution: {integrity: sha512-+7f8eV8iaK3tENN/FUVxZM1g78HjPehybN8/+/dvEA1O893Dcvk6O7/Q1wTQOHMD7wvdwWdujKl+Uo8QMiKDrQ==} 1326 + engines: {node: ^20.19.0 || >=22.12.0} 1327 + hasBin: true 1328 + 1329 + oxlint@1.35.0: 1330 + resolution: {integrity: sha512-QDX1aUgaiqznkGfTM2qHwva2wtKqhVoqPSVXrnPz+yLUhlNadikD3QRuRtppHl7WGuy3wG6nKAuR8lash3aWSg==} 1331 + engines: {node: ^20.19.0 || >=22.12.0} 1332 + hasBin: true 1333 + peerDependencies: 1334 + oxlint-tsgolint: '>=0.10.0' 1335 + peerDependenciesMeta: 1336 + oxlint-tsgolint: 1337 + optional: true 1338 + 1339 + parent-module@1.0.1: 1340 + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} 1341 + engines: {node: '>=6'} 1342 + 1343 + parse-json@4.0.0: 1344 + resolution: {integrity: sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==} 1345 + engines: {node: '>=4'} 1346 + 1347 + parse-json@5.2.0: 1348 + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} 1349 + engines: {node: '>=8'} 1350 + 1351 + path-is-absolute@1.0.1: 1352 + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} 1353 + engines: {node: '>=0.10.0'} 1354 + 1355 + path-key@2.0.1: 1356 + resolution: {integrity: sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==} 1357 + engines: {node: '>=4'} 1358 + 1359 + path-parse@1.0.7: 1360 + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} 1361 + 1362 + path-type@3.0.0: 1363 + resolution: {integrity: sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==} 1364 + engines: {node: '>=4'} 1365 + 1366 + pathe@2.0.3: 1367 + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} 1368 + 1369 + perfect-debounce@2.0.0: 1370 + resolution: {integrity: sha512-fkEH/OBiKrqqI/yIgjR92lMfs2K8105zt/VT6+7eTjNwisrsh47CeIED9z58zI7DfKdH3uHAn25ziRZn3kgAow==} 1371 + 1372 + pg-cloudflare@1.2.7: 1373 + resolution: {integrity: sha512-YgCtzMH0ptvZJslLM1ffsY4EuGaU0cx4XSdXLRFae8bPP4dS5xL1tNB3k2o/N64cHJpwU7dxKli/nZ2lUa5fLg==} 1374 + 1375 + pg-connection-string@2.9.1: 1376 + resolution: {integrity: sha512-nkc6NpDcvPVpZXxrreI/FOtX3XemeLl8E0qFr6F2Lrm/I8WOnaWNhIPK2Z7OHpw7gh5XJThi6j6ppgNoaT1w4w==} 1377 + 1378 + pg-int8@1.0.1: 1379 + resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==} 1380 + engines: {node: '>=4.0.0'} 1381 + 1382 + pg-pool@3.10.1: 1383 + resolution: {integrity: sha512-Tu8jMlcX+9d8+QVzKIvM/uJtp07PKr82IUOYEphaWcoBhIYkoHpLXN3qO59nAI11ripznDsEzEv8nUxBVWajGg==} 1384 + peerDependencies: 1385 + pg: '>=8.0' 1386 + 1387 + pg-protocol@1.10.3: 1388 + resolution: {integrity: sha512-6DIBgBQaTKDJyxnXaLiLR8wBpQQcGWuAESkRBX/t6OwA8YsqP+iVSiond2EDy6Y/dsGk8rh/jtax3js5NeV7JQ==} 1389 + 1390 + pg-types@2.2.0: 1391 + resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==} 1392 + engines: {node: '>=4'} 1393 + 1394 + pg@8.16.3: 1395 + resolution: {integrity: sha512-enxc1h0jA/aq5oSDMvqyW3q89ra6XIIDZgCX9vkMrnz5DFTw/Ny3Li2lFQ+pt3L6MCgm/5o2o8HW9hiJji+xvw==} 1396 + engines: {node: '>= 16.0.0'} 1397 + peerDependencies: 1398 + pg-native: '>=3.0.1' 1399 + peerDependenciesMeta: 1400 + pg-native: 1401 + optional: true 1402 + 1403 + pgpass@1.0.5: 1404 + resolution: {integrity: sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==} 1405 + 1406 + picocolors@1.1.1: 1407 + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} 1408 + 1409 + picomatch@2.3.1: 1410 + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} 1411 + engines: {node: '>=8.6'} 1412 + 1413 + pidtree@0.3.1: 1414 + resolution: {integrity: sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==} 1415 + engines: {node: '>=0.10'} 1416 + hasBin: true 1417 + 1418 + pify@3.0.0: 1419 + resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} 1420 + engines: {node: '>=4'} 1421 + 341 1422 pino-abstract-transport@1.2.0: 342 1423 resolution: {integrity: sha512-Guhh8EZfPCfH+PMXAb6rKOjGQEoy0xlAIn+irODG5kgfYV+BQ0rGYYWTIel3P5mmyXqkYkPmdIkywsn6QKUR1Q==} 343 1424 1425 + pino-abstract-transport@2.0.0: 1426 + resolution: {integrity: sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==} 1427 + 1428 + pino-abstract-transport@3.0.0: 1429 + resolution: {integrity: sha512-wlfUczU+n7Hy/Ha5j9a/gZNy7We5+cXp8YL+X+PG8S0KXxw7n/JXA3c46Y0zQznIJ83URJiwy7Lh56WLokNuxg==} 1430 + 1431 + pino-http@11.0.0: 1432 + resolution: {integrity: sha512-wqg5XIAGRRIWtTk8qPGxkbrfiwEWz1lgedVLvhLALudKXvg1/L2lTFgTGPJ4Z2e3qcRmxoFxDuSdMdMGNM6I1g==} 1433 + 1434 + pino-pretty@13.1.3: 1435 + resolution: {integrity: sha512-ttXRkkOz6WWC95KeY9+xxWL6AtImwbyMHrL1mSwqwW9u+vLp/WIElvHvCSDg0xO/Dzrggz1zv3rN5ovTRVowKg==} 1436 + hasBin: true 1437 + 344 1438 pino-std-serializers@6.2.2: 345 1439 resolution: {integrity: sha512-cHjPPsE+vhj/tnhCy/wiMh3M3z3h/j15zHQX+S9GkTBgqJuTuJzYJ4gUyACLhDaJ7kk9ba9iRDmbH2tJU03OiA==} 346 1440 1441 + pino-std-serializers@7.0.0: 1442 + resolution: {integrity: sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA==} 1443 + 1444 + pino@10.1.0: 1445 + resolution: {integrity: sha512-0zZC2ygfdqvqK8zJIr1e+wT1T/L+LF6qvqvbzEQ6tiMAoTqEVK9a1K3YRu8HEUvGEvNqZyPJTtb2sNIoTkB83w==} 1446 + hasBin: true 1447 + 347 1448 pino@8.21.0: 348 1449 resolution: {integrity: sha512-ip4qdzjkAyDDZklUaZkcRFb2iA118H9SgRh8yzTkSQK8HilsOJF7rSY8HoW5+I0M46AZgX/pxbprf2vvzQCE0Q==} 349 1450 hasBin: true 350 1451 1452 + pkg-types@2.3.0: 1453 + resolution: {integrity: sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==} 1454 + 1455 + pluralize@8.0.0: 1456 + resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} 1457 + engines: {node: '>=4'} 1458 + 1459 + possible-typed-array-names@1.1.0: 1460 + resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} 1461 + engines: {node: '>= 0.4'} 1462 + 1463 + postgres-array@2.0.0: 1464 + resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==} 1465 + engines: {node: '>=4'} 1466 + 1467 + postgres-bytea@1.0.1: 1468 + resolution: {integrity: sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==} 1469 + engines: {node: '>=0.10.0'} 1470 + 1471 + postgres-date@1.0.7: 1472 + resolution: {integrity: sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==} 1473 + engines: {node: '>=0.10.0'} 1474 + 1475 + postgres-interval@1.2.0: 1476 + resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==} 1477 + engines: {node: '>=0.10.0'} 1478 + 351 1479 process-warning@3.0.0: 352 1480 resolution: {integrity: sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ==} 353 1481 1482 + process-warning@5.0.0: 1483 + resolution: {integrity: sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA==} 1484 + 354 1485 process@0.11.10: 355 1486 resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} 356 1487 engines: {node: '>= 0.6.0'} 357 1488 1489 + pump@3.0.3: 1490 + resolution: {integrity: sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==} 1491 + 358 1492 quick-format-unescaped@4.0.4: 359 1493 resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} 360 1494 1495 + rc9@2.1.2: 1496 + resolution: {integrity: sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==} 1497 + 1498 + read-pkg@3.0.0: 1499 + resolution: {integrity: sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==} 1500 + engines: {node: '>=4'} 1501 + 361 1502 readable-stream@4.7.0: 362 1503 resolution: {integrity: sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==} 363 1504 engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 364 1505 1506 + readdirp@5.0.0: 1507 + resolution: {integrity: sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==} 1508 + engines: {node: '>= 20.19.0'} 1509 + 365 1510 real-require@0.2.0: 366 1511 resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==} 367 1512 engines: {node: '>= 12.13.0'} 368 1513 1514 + rechoir@0.6.2: 1515 + resolution: {integrity: sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==} 1516 + engines: {node: '>= 0.10'} 1517 + 1518 + reflect.getprototypeof@1.0.10: 1519 + resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} 1520 + engines: {node: '>= 0.4'} 1521 + 1522 + regexp.prototype.flags@1.5.4: 1523 + resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} 1524 + engines: {node: '>= 0.4'} 1525 + 1526 + resolve-from@4.0.0: 1527 + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} 1528 + engines: {node: '>=4'} 1529 + 369 1530 resolve-pkg-maps@1.0.0: 370 1531 resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} 371 1532 1533 + resolve@1.22.11: 1534 + resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==} 1535 + engines: {node: '>= 0.4'} 1536 + hasBin: true 1537 + 1538 + safe-array-concat@1.1.3: 1539 + resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==} 1540 + engines: {node: '>=0.4'} 1541 + 372 1542 safe-buffer@5.2.1: 373 1543 resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} 374 1544 1545 + safe-push-apply@1.0.0: 1546 + resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==} 1547 + engines: {node: '>= 0.4'} 1548 + 1549 + safe-regex-test@1.1.0: 1550 + resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} 1551 + engines: {node: '>= 0.4'} 1552 + 375 1553 safe-stable-stringify@2.5.0: 376 1554 resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==} 377 1555 engines: {node: '>=10'} 378 1556 1557 + secure-json-parse@4.1.0: 1558 + resolution: {integrity: sha512-l4KnYfEyqYJxDwlNVyRfO2E4NTHfMKAWdUuA8J0yve2Dz/E/PdBepY03RvyJpssIpRFwJoCD55wA+mEDs6ByWA==} 1559 + 1560 + semver@5.7.2: 1561 + resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} 1562 + hasBin: true 1563 + 1564 + set-function-length@1.2.2: 1565 + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} 1566 + engines: {node: '>= 0.4'} 1567 + 1568 + set-function-name@2.0.2: 1569 + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} 1570 + engines: {node: '>= 0.4'} 1571 + 1572 + set-proto@1.0.0: 1573 + resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} 1574 + engines: {node: '>= 0.4'} 1575 + 1576 + shebang-command@1.2.0: 1577 + resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} 1578 + engines: {node: '>=0.10.0'} 1579 + 1580 + shebang-regex@1.0.0: 1581 + resolution: {integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==} 1582 + engines: {node: '>=0.10.0'} 1583 + 1584 + shell-quote@1.8.3: 1585 + resolution: {integrity: sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==} 1586 + engines: {node: '>= 0.4'} 1587 + 1588 + shelljs.exec@1.1.8: 1589 + resolution: {integrity: sha512-vFILCw+lzUtiwBAHV8/Ex8JsFjelFMdhONIsgKNLgTzeRckp2AOYRQtHJE/9LhNvdMmE27AGtzWx0+DHpwIwSw==} 1590 + engines: {node: '>= 4.0.0'} 1591 + 1592 + shelljs@0.8.5: 1593 + resolution: {integrity: sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==} 1594 + engines: {node: '>=4'} 1595 + hasBin: true 1596 + 1597 + side-channel-list@1.0.0: 1598 + resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} 1599 + engines: {node: '>= 0.4'} 1600 + 1601 + side-channel-map@1.0.1: 1602 + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} 1603 + engines: {node: '>= 0.4'} 1604 + 1605 + side-channel-weakmap@1.0.2: 1606 + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} 1607 + engines: {node: '>= 0.4'} 1608 + 1609 + side-channel@1.1.0: 1610 + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} 1611 + engines: {node: '>= 0.4'} 1612 + 379 1613 sonic-boom@3.8.1: 380 1614 resolution: {integrity: sha512-y4Z8LCDBuum+PBP3lSV7RHrXscqksve/bi0as7mhwVnBW+/wUqKT/2Kb7um8yqcFy0duYbbPxzt89Zy2nOCaxg==} 381 1615 1616 + sonic-boom@4.2.0: 1617 + resolution: {integrity: sha512-INb7TM37/mAcsGmc9hyyI6+QR3rR1zVRu36B0NeGXKnOOLiZOfER5SA+N7X7k3yUYRzLWafduTDvJAfDswwEww==} 1618 + 1619 + spdx-correct@3.2.0: 1620 + resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} 1621 + 1622 + spdx-exceptions@2.5.0: 1623 + resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==} 1624 + 1625 + spdx-expression-parse@3.0.1: 1626 + resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} 1627 + 1628 + spdx-license-ids@3.0.22: 1629 + resolution: {integrity: sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==} 1630 + 382 1631 split2@4.2.0: 383 1632 resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} 384 1633 engines: {node: '>= 10.x'} 385 1634 1635 + std-env@3.10.0: 1636 + resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} 1637 + 1638 + stop-iteration-iterator@1.1.0: 1639 + resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} 1640 + engines: {node: '>= 0.4'} 1641 + 1642 + string.prototype.padend@3.1.6: 1643 + resolution: {integrity: sha512-XZpspuSB7vJWhvJc9DLSlrXl1mcA2BdoY5jjnS135ydXqLoqhs96JjDtCkjJEQHvfqZIp9hBuBMgI589peyx9Q==} 1644 + engines: {node: '>= 0.4'} 1645 + 1646 + string.prototype.trim@1.2.10: 1647 + resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==} 1648 + engines: {node: '>= 0.4'} 1649 + 1650 + string.prototype.trimend@1.0.9: 1651 + resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==} 1652 + engines: {node: '>= 0.4'} 1653 + 1654 + string.prototype.trimstart@1.0.8: 1655 + resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} 1656 + engines: {node: '>= 0.4'} 1657 + 386 1658 string_decoder@1.3.0: 387 1659 resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} 388 1660 1661 + strip-bom@3.0.0: 1662 + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} 1663 + engines: {node: '>=4'} 1664 + 1665 + strip-json-comments@5.0.3: 1666 + resolution: {integrity: sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw==} 1667 + engines: {node: '>=14.16'} 1668 + 1669 + supports-color@5.5.0: 1670 + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} 1671 + engines: {node: '>=4'} 1672 + 1673 + supports-color@7.2.0: 1674 + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} 1675 + engines: {node: '>=8'} 1676 + 1677 + supports-preserve-symlinks-flag@1.0.0: 1678 + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} 1679 + engines: {node: '>= 0.4'} 1680 + 389 1681 thread-stream@2.7.0: 390 1682 resolution: {integrity: sha512-qQiRWsU/wvNolI6tbbCKd9iKaTnCXsTwVxhhKM6nctPdujTyztjlbUkUTUymidWcMnZ5pWR0ej4a0tjsW021vw==} 391 1683 1684 + thread-stream@3.1.0: 1685 + resolution: {integrity: sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==} 1686 + 1687 + tinyexec@1.0.2: 1688 + resolution: {integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==} 1689 + engines: {node: '>=18'} 1690 + 1691 + tinypool@2.0.0: 1692 + resolution: {integrity: sha512-/RX9RzeH2xU5ADE7n2Ykvmi9ED3FBGPAjw9u3zucrNNaEBIO0HPSYgL0NT7+3p147ojeSdaVu08F6hjpv31HJg==} 1693 + engines: {node: ^20.0.0 || >=22.0.0} 1694 + 1695 + tlds@1.261.0: 1696 + resolution: {integrity: sha512-QXqwfEl9ddlGBaRFXIvNKK6OhipSiLXuRuLJX5DErz0o0Q0rYxulWLdFryTkV5PkdZct5iMInwYEGe/eR++1AA==} 1697 + hasBin: true 1698 + 1699 + to-regex-range@5.0.1: 1700 + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} 1701 + engines: {node: '>=8.0'} 1702 + 392 1703 ts-mixer@6.0.4: 393 1704 resolution: {integrity: sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA==} 394 1705 1706 + tsconfck@3.1.6: 1707 + resolution: {integrity: sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w==} 1708 + engines: {node: ^18 || >=20} 1709 + hasBin: true 1710 + peerDependencies: 1711 + typescript: ^5.0.0 1712 + peerDependenciesMeta: 1713 + typescript: 1714 + optional: true 1715 + 395 1716 tslib@2.8.1: 396 1717 resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} 397 1718 ··· 400 1721 engines: {node: '>=18.0.0'} 401 1722 hasBin: true 402 1723 1724 + typed-array-buffer@1.0.3: 1725 + resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} 1726 + engines: {node: '>= 0.4'} 1727 + 1728 + typed-array-byte-length@1.0.3: 1729 + resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==} 1730 + engines: {node: '>= 0.4'} 1731 + 1732 + typed-array-byte-offset@1.0.4: 1733 + resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==} 1734 + engines: {node: '>= 0.4'} 1735 + 1736 + typed-array-length@1.0.7: 1737 + resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} 1738 + engines: {node: '>= 0.4'} 1739 + 1740 + typescript@5.9.2: 1741 + resolution: {integrity: sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==} 1742 + engines: {node: '>=14.17'} 1743 + hasBin: true 1744 + 403 1745 typescript@5.9.3: 404 1746 resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} 405 1747 engines: {node: '>=14.17'} 406 1748 hasBin: true 407 1749 1750 + ufo@1.6.1: 1751 + resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==} 1752 + 408 1753 uint8arrays@3.0.0: 409 1754 resolution: {integrity: sha512-HRCx0q6O9Bfbp+HHSfQQKD7wU70+lydKVt4EghkdOvlK/NlrF90z+eXV34mUd48rNvVJXwkrMSPpCATkct8fJA==} 410 1755 1756 + unbox-primitive@1.1.0: 1757 + resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} 1758 + engines: {node: '>= 0.4'} 1759 + 1760 + undici-types@6.21.0: 1761 + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} 1762 + 411 1763 undici-types@7.16.0: 412 1764 resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} 413 1765 ··· 418 1770 unicode-segmenter@0.14.4: 419 1771 resolution: {integrity: sha512-pR5VCiCrLrKOL6FRW61jnk9+wyMtKKowq+jyFY9oc6uHbWKhDL4yVRiI4YZPksGMK72Pahh8m0cn/0JvbDDyJg==} 420 1772 1773 + validate-npm-package-license@3.0.4: 1774 + resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} 1775 + 1776 + which-boxed-primitive@1.1.1: 1777 + resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} 1778 + engines: {node: '>= 0.4'} 1779 + 1780 + which-builtin-type@1.2.1: 1781 + resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==} 1782 + engines: {node: '>= 0.4'} 1783 + 1784 + which-collection@1.0.2: 1785 + resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} 1786 + engines: {node: '>= 0.4'} 1787 + 1788 + which-typed-array@1.1.19: 1789 + resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==} 1790 + engines: {node: '>= 0.4'} 1791 + 1792 + which@1.3.1: 1793 + resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} 1794 + hasBin: true 1795 + 1796 + wrappy@1.0.2: 1797 + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} 1798 + 421 1799 ws@8.18.3: 422 1800 resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} 423 1801 engines: {node: '>=10.0.0'} ··· 430 1808 utf-8-validate: 431 1809 optional: true 432 1810 1811 + xtend@4.0.2: 1812 + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} 1813 + engines: {node: '>=0.4'} 1814 + 433 1815 zod@3.25.76: 434 1816 resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} 435 1817 1818 + zod@4.2.1: 1819 + resolution: {integrity: sha512-0wZ1IRqGGhMP76gLqz8EyfBXKk0J2qo2+H3fi4mcUP/KtTocoX08nmIAHl1Z2kJIZbZee8KOpBCSNPRgauucjw==} 1820 + 436 1821 snapshots: 437 1822 1823 + '@atproto-labs/did-resolver@0.2.4': 1824 + dependencies: 1825 + '@atproto-labs/fetch': 0.2.3 1826 + '@atproto-labs/pipe': 0.1.1 1827 + '@atproto-labs/simple-store': 0.3.0 1828 + '@atproto-labs/simple-store-memory': 0.1.4 1829 + '@atproto/did': 0.2.3 1830 + zod: 3.25.76 1831 + 1832 + '@atproto-labs/fetch-node@0.2.0': 1833 + dependencies: 1834 + '@atproto-labs/fetch': 0.2.3 1835 + '@atproto-labs/pipe': 0.1.1 1836 + ipaddr.js: 2.3.0 1837 + undici: 6.21.3 1838 + 1839 + '@atproto-labs/fetch@0.2.3': 1840 + dependencies: 1841 + '@atproto-labs/pipe': 0.1.1 1842 + 1843 + '@atproto-labs/handle-resolver-node@0.1.23': 1844 + dependencies: 1845 + '@atproto-labs/fetch-node': 0.2.0 1846 + '@atproto-labs/handle-resolver': 0.3.4 1847 + '@atproto/did': 0.2.3 1848 + 1849 + '@atproto-labs/handle-resolver@0.3.4': 1850 + dependencies: 1851 + '@atproto-labs/simple-store': 0.3.0 1852 + '@atproto-labs/simple-store-memory': 0.1.4 1853 + '@atproto/did': 0.2.3 1854 + zod: 3.25.76 1855 + 1856 + '@atproto-labs/identity-resolver@0.3.4': 1857 + dependencies: 1858 + '@atproto-labs/did-resolver': 0.2.4 1859 + '@atproto-labs/handle-resolver': 0.3.4 1860 + 1861 + '@atproto-labs/pipe@0.1.1': {} 1862 + 1863 + '@atproto-labs/simple-store-memory@0.1.4': 1864 + dependencies: 1865 + '@atproto-labs/simple-store': 0.3.0 1866 + lru-cache: 10.4.3 1867 + 1868 + '@atproto-labs/simple-store@0.3.0': {} 1869 + 1870 + '@atproto/api@0.18.8': 1871 + dependencies: 1872 + '@atproto/common-web': 0.4.7 1873 + '@atproto/lexicon': 0.6.0 1874 + '@atproto/syntax': 0.4.2 1875 + '@atproto/xrpc': 0.7.7 1876 + await-lock: 2.2.2 1877 + multiformats: 9.9.0 1878 + tlds: 1.261.0 1879 + zod: 3.25.76 1880 + 438 1881 '@atproto/common-web@0.4.7': 439 1882 dependencies: 440 1883 '@atproto/lex-data': 0.0.3 ··· 449 1892 iso-datestring-validator: 2.2.2 450 1893 multiformats: 9.9.0 451 1894 pino: 8.21.0 1895 + 1896 + '@atproto/did@0.2.3': 1897 + dependencies: 1898 + zod: 3.25.76 1899 + 1900 + '@atproto/jwk-jose@0.1.11': 1901 + dependencies: 1902 + '@atproto/jwk': 0.6.0 1903 + jose: 5.10.0 1904 + 1905 + '@atproto/jwk-webcrypto@0.2.0': 1906 + dependencies: 1907 + '@atproto/jwk': 0.6.0 1908 + '@atproto/jwk-jose': 0.1.11 1909 + zod: 3.25.76 1910 + 1911 + '@atproto/jwk@0.6.0': 1912 + dependencies: 1913 + multiformats: 9.9.0 1914 + zod: 3.25.76 452 1915 453 1916 '@atproto/lex-cbor@0.0.3': 454 1917 dependencies: ··· 469 1932 '@atproto/lex-data': 0.0.3 470 1933 tslib: 2.8.1 471 1934 1935 + '@atproto/lexicon@0.6.0': 1936 + dependencies: 1937 + '@atproto/common-web': 0.4.7 1938 + '@atproto/syntax': 0.4.2 1939 + iso-datestring-validator: 2.2.2 1940 + multiformats: 9.9.0 1941 + zod: 3.25.76 1942 + 1943 + '@atproto/oauth-client-node@0.3.13': 1944 + dependencies: 1945 + '@atproto-labs/did-resolver': 0.2.4 1946 + '@atproto-labs/handle-resolver-node': 0.1.23 1947 + '@atproto-labs/simple-store': 0.3.0 1948 + '@atproto/did': 0.2.3 1949 + '@atproto/jwk': 0.6.0 1950 + '@atproto/jwk-jose': 0.1.11 1951 + '@atproto/jwk-webcrypto': 0.2.0 1952 + '@atproto/oauth-client': 0.5.11 1953 + '@atproto/oauth-types': 0.5.2 1954 + 1955 + '@atproto/oauth-client@0.5.11': 1956 + dependencies: 1957 + '@atproto-labs/did-resolver': 0.2.4 1958 + '@atproto-labs/fetch': 0.2.3 1959 + '@atproto-labs/handle-resolver': 0.3.4 1960 + '@atproto-labs/identity-resolver': 0.3.4 1961 + '@atproto-labs/simple-store': 0.3.0 1962 + '@atproto-labs/simple-store-memory': 0.1.4 1963 + '@atproto/did': 0.2.3 1964 + '@atproto/jwk': 0.6.0 1965 + '@atproto/oauth-types': 0.5.2 1966 + '@atproto/xrpc': 0.7.7 1967 + core-js: 3.47.0 1968 + multiformats: 9.9.0 1969 + zod: 3.25.76 1970 + 1971 + '@atproto/oauth-types@0.5.2': 1972 + dependencies: 1973 + '@atproto/did': 0.2.3 1974 + '@atproto/jwk': 0.6.0 1975 + zod: 3.25.76 1976 + 472 1977 '@atproto/syntax@0.4.2': {} 473 1978 474 1979 '@atproto/tap@0.0.2': ··· 489 1994 transitivePeerDependencies: 490 1995 - bufferutil 491 1996 - utf-8-validate 1997 + 1998 + '@atproto/xrpc@0.7.7': 1999 + dependencies: 2000 + '@atproto/lexicon': 0.6.0 2001 + zod: 3.25.76 2002 + 2003 + '@babel/code-frame@7.27.1': 2004 + dependencies: 2005 + '@babel/helper-validator-identifier': 7.28.5 2006 + js-tokens: 4.0.0 2007 + picocolors: 1.1.1 2008 + 2009 + '@babel/helper-validator-identifier@7.28.5': {} 2010 + 2011 + '@commander-js/extra-typings@11.1.0(commander@11.1.0)': 2012 + dependencies: 2013 + commander: 11.1.0 492 2014 493 2015 '@discordjs/builders@1.13.1': 494 2016 dependencies: ··· 617 2139 '@esbuild/win32-x64@0.27.2': 618 2140 optional: true 619 2141 2142 + '@hono/node-server@1.19.7(hono@4.11.3)': 2143 + dependencies: 2144 + hono: 4.11.3 2145 + 2146 + '@oxfmt/darwin-arm64@0.20.0': 2147 + optional: true 2148 + 2149 + '@oxfmt/darwin-x64@0.20.0': 2150 + optional: true 2151 + 2152 + '@oxfmt/linux-arm64-gnu@0.20.0': 2153 + optional: true 2154 + 2155 + '@oxfmt/linux-arm64-musl@0.20.0': 2156 + optional: true 2157 + 2158 + '@oxfmt/linux-x64-gnu@0.20.0': 2159 + optional: true 2160 + 2161 + '@oxfmt/linux-x64-musl@0.20.0': 2162 + optional: true 2163 + 2164 + '@oxfmt/win32-arm64@0.20.0': 2165 + optional: true 2166 + 2167 + '@oxfmt/win32-x64@0.20.0': 2168 + optional: true 2169 + 2170 + '@oxlint/darwin-arm64@1.35.0': 2171 + optional: true 2172 + 2173 + '@oxlint/darwin-x64@1.35.0': 2174 + optional: true 2175 + 2176 + '@oxlint/linux-arm64-gnu@1.35.0': 2177 + optional: true 2178 + 2179 + '@oxlint/linux-arm64-musl@1.35.0': 2180 + optional: true 2181 + 2182 + '@oxlint/linux-x64-gnu@1.35.0': 2183 + optional: true 2184 + 2185 + '@oxlint/linux-x64-musl@1.35.0': 2186 + optional: true 2187 + 2188 + '@oxlint/win32-arm64@1.35.0': 2189 + optional: true 2190 + 2191 + '@oxlint/win32-x64@1.35.0': 2192 + optional: true 2193 + 2194 + '@pinojs/redact@0.4.0': {} 2195 + 620 2196 '@sapphire/async-queue@1.5.5': {} 621 2197 622 2198 '@sapphire/shapeshift@4.0.0': ··· 626 2202 627 2203 '@sapphire/snowflake@3.5.3': {} 628 2204 2205 + '@types/node@22.19.3': 2206 + dependencies: 2207 + undici-types: 6.21.0 2208 + 629 2209 '@types/node@25.0.3': 630 2210 dependencies: 631 2211 undici-types: 7.16.0 632 2212 2213 + '@types/pg@8.16.0': 2214 + dependencies: 2215 + '@types/node': 25.0.3 2216 + pg-protocol: 1.10.3 2217 + pg-types: 2.2.0 2218 + 633 2219 '@types/ws@8.18.1': 634 2220 dependencies: 635 2221 '@types/node': 25.0.3 ··· 640 2226 dependencies: 641 2227 event-target-shim: 5.0.1 642 2228 2229 + ansi-styles@3.2.1: 2230 + dependencies: 2231 + color-convert: 1.9.3 2232 + 2233 + ansi-styles@4.3.0: 2234 + dependencies: 2235 + color-convert: 2.0.1 2236 + 2237 + argparse@2.0.1: {} 2238 + 2239 + array-buffer-byte-length@1.0.2: 2240 + dependencies: 2241 + call-bound: 1.0.4 2242 + is-array-buffer: 3.0.5 2243 + 2244 + arraybuffer.prototype.slice@1.0.4: 2245 + dependencies: 2246 + array-buffer-byte-length: 1.0.2 2247 + call-bind: 1.0.8 2248 + define-properties: 1.2.1 2249 + es-abstract: 1.24.1 2250 + es-errors: 1.3.0 2251 + get-intrinsic: 1.3.0 2252 + is-array-buffer: 3.0.5 2253 + 2254 + async-function@1.0.0: {} 2255 + 643 2256 atomic-sleep@1.0.0: {} 644 2257 2258 + available-typed-arrays@1.0.7: 2259 + dependencies: 2260 + possible-typed-array-names: 1.1.0 2261 + 2262 + await-lock@2.2.2: {} 2263 + 2264 + balanced-match@1.0.2: {} 2265 + 645 2266 base64-js@1.5.1: {} 646 2267 2268 + brace-expansion@1.1.12: 2269 + dependencies: 2270 + balanced-match: 1.0.2 2271 + concat-map: 0.0.1 2272 + 2273 + braces@3.0.3: 2274 + dependencies: 2275 + fill-range: 7.1.1 2276 + 647 2277 buffer@6.0.3: 648 2278 dependencies: 649 2279 base64-js: 1.5.1 650 2280 ieee754: 1.2.1 651 2281 2282 + c12@3.3.3: 2283 + dependencies: 2284 + chokidar: 5.0.0 2285 + confbox: 0.2.2 2286 + defu: 6.1.4 2287 + dotenv: 17.2.3 2288 + exsolve: 1.0.8 2289 + giget: 2.0.0 2290 + jiti: 2.6.1 2291 + ohash: 2.0.11 2292 + pathe: 2.0.3 2293 + perfect-debounce: 2.0.0 2294 + pkg-types: 2.3.0 2295 + rc9: 2.1.2 2296 + 2297 + call-bind-apply-helpers@1.0.2: 2298 + dependencies: 2299 + es-errors: 1.3.0 2300 + function-bind: 1.1.2 2301 + 2302 + call-bind@1.0.8: 2303 + dependencies: 2304 + call-bind-apply-helpers: 1.0.2 2305 + es-define-property: 1.0.1 2306 + get-intrinsic: 1.3.0 2307 + set-function-length: 1.2.2 2308 + 2309 + call-bound@1.0.4: 2310 + dependencies: 2311 + call-bind-apply-helpers: 1.0.2 2312 + get-intrinsic: 1.3.0 2313 + 2314 + callsites@3.1.0: {} 2315 + 2316 + chalk@2.4.2: 2317 + dependencies: 2318 + ansi-styles: 3.2.1 2319 + escape-string-regexp: 1.0.5 2320 + supports-color: 5.5.0 2321 + 2322 + chalk@4.1.2: 2323 + dependencies: 2324 + ansi-styles: 4.3.0 2325 + supports-color: 7.2.0 2326 + 2327 + chokidar@5.0.0: 2328 + dependencies: 2329 + readdirp: 5.0.0 2330 + 2331 + citty@0.1.6: 2332 + dependencies: 2333 + consola: 3.4.2 2334 + 2335 + color-convert@1.9.3: 2336 + dependencies: 2337 + color-name: 1.1.3 2338 + 2339 + color-convert@2.0.1: 2340 + dependencies: 2341 + color-name: 1.1.4 2342 + 2343 + color-name@1.1.3: {} 2344 + 2345 + color-name@1.1.4: {} 2346 + 2347 + colorette@2.0.20: {} 2348 + 2349 + commander@11.1.0: {} 2350 + 2351 + concat-map@0.0.1: {} 2352 + 2353 + confbox@0.2.2: {} 2354 + 2355 + consola@3.4.2: {} 2356 + 2357 + core-js@3.47.0: {} 2358 + 2359 + cosmiconfig@9.0.0(typescript@5.9.2): 2360 + dependencies: 2361 + env-paths: 2.2.1 2362 + import-fresh: 3.3.1 2363 + js-yaml: 4.1.1 2364 + parse-json: 5.2.0 2365 + optionalDependencies: 2366 + typescript: 5.9.2 2367 + 2368 + cross-spawn@6.0.6: 2369 + dependencies: 2370 + nice-try: 1.0.5 2371 + path-key: 2.0.1 2372 + semver: 5.7.2 2373 + shebang-command: 1.2.0 2374 + which: 1.3.1 2375 + 2376 + data-view-buffer@1.0.2: 2377 + dependencies: 2378 + call-bound: 1.0.4 2379 + es-errors: 1.3.0 2380 + is-data-view: 1.0.2 2381 + 2382 + data-view-byte-length@1.0.2: 2383 + dependencies: 2384 + call-bound: 1.0.4 2385 + es-errors: 1.3.0 2386 + is-data-view: 1.0.2 2387 + 2388 + data-view-byte-offset@1.0.1: 2389 + dependencies: 2390 + call-bound: 1.0.4 2391 + es-errors: 1.3.0 2392 + is-data-view: 1.0.2 2393 + 2394 + dateformat@4.6.3: {} 2395 + 2396 + define-data-property@1.1.4: 2397 + dependencies: 2398 + es-define-property: 1.0.1 2399 + es-errors: 1.3.0 2400 + gopd: 1.2.0 2401 + 2402 + define-properties@1.2.1: 2403 + dependencies: 2404 + define-data-property: 1.1.4 2405 + has-property-descriptors: 1.0.2 2406 + object-keys: 1.1.1 2407 + 2408 + defu@6.1.4: {} 2409 + 2410 + destr@2.0.5: {} 2411 + 2412 + diff@3.5.0: {} 2413 + 652 2414 discord-api-types@0.38.37: {} 653 2415 654 2416 discord.js@14.25.1: ··· 670 2432 - bufferutil 671 2433 - utf-8-validate 672 2434 2435 + dotenv-expand@12.0.3: 2436 + dependencies: 2437 + dotenv: 16.6.1 2438 + 2439 + dotenv@16.6.1: {} 2440 + 2441 + dotenv@17.2.3: {} 2442 + 2443 + dunder-proto@1.0.1: 2444 + dependencies: 2445 + call-bind-apply-helpers: 1.0.2 2446 + es-errors: 1.3.0 2447 + gopd: 1.2.0 2448 + 2449 + end-of-stream@1.4.5: 2450 + dependencies: 2451 + once: 1.4.0 2452 + 2453 + env-paths@2.2.1: {} 2454 + 2455 + envalid@8.1.1: 2456 + dependencies: 2457 + tslib: 2.8.1 2458 + 2459 + error-ex@1.3.4: 2460 + dependencies: 2461 + is-arrayish: 0.2.1 2462 + 2463 + es-abstract@1.24.1: 2464 + dependencies: 2465 + array-buffer-byte-length: 1.0.2 2466 + arraybuffer.prototype.slice: 1.0.4 2467 + available-typed-arrays: 1.0.7 2468 + call-bind: 1.0.8 2469 + call-bound: 1.0.4 2470 + data-view-buffer: 1.0.2 2471 + data-view-byte-length: 1.0.2 2472 + data-view-byte-offset: 1.0.1 2473 + es-define-property: 1.0.1 2474 + es-errors: 1.3.0 2475 + es-object-atoms: 1.1.1 2476 + es-set-tostringtag: 2.1.0 2477 + es-to-primitive: 1.3.0 2478 + function.prototype.name: 1.1.8 2479 + get-intrinsic: 1.3.0 2480 + get-proto: 1.0.1 2481 + get-symbol-description: 1.1.0 2482 + globalthis: 1.0.4 2483 + gopd: 1.2.0 2484 + has-property-descriptors: 1.0.2 2485 + has-proto: 1.2.0 2486 + has-symbols: 1.1.0 2487 + hasown: 2.0.2 2488 + internal-slot: 1.1.0 2489 + is-array-buffer: 3.0.5 2490 + is-callable: 1.2.7 2491 + is-data-view: 1.0.2 2492 + is-negative-zero: 2.0.3 2493 + is-regex: 1.2.1 2494 + is-set: 2.0.3 2495 + is-shared-array-buffer: 1.0.4 2496 + is-string: 1.1.1 2497 + is-typed-array: 1.1.15 2498 + is-weakref: 1.1.1 2499 + math-intrinsics: 1.1.0 2500 + object-inspect: 1.13.4 2501 + object-keys: 1.1.1 2502 + object.assign: 4.1.7 2503 + own-keys: 1.0.1 2504 + regexp.prototype.flags: 1.5.4 2505 + safe-array-concat: 1.1.3 2506 + safe-push-apply: 1.0.0 2507 + safe-regex-test: 1.1.0 2508 + set-proto: 1.0.0 2509 + stop-iteration-iterator: 1.1.0 2510 + string.prototype.trim: 1.2.10 2511 + string.prototype.trimend: 1.0.9 2512 + string.prototype.trimstart: 1.0.8 2513 + typed-array-buffer: 1.0.3 2514 + typed-array-byte-length: 1.0.3 2515 + typed-array-byte-offset: 1.0.4 2516 + typed-array-length: 1.0.7 2517 + unbox-primitive: 1.1.0 2518 + which-typed-array: 1.1.19 2519 + 2520 + es-define-property@1.0.1: {} 2521 + 2522 + es-errors@1.3.0: {} 2523 + 2524 + es-object-atoms@1.1.1: 2525 + dependencies: 2526 + es-errors: 1.3.0 2527 + 2528 + es-set-tostringtag@2.1.0: 2529 + dependencies: 2530 + es-errors: 1.3.0 2531 + get-intrinsic: 1.3.0 2532 + has-tostringtag: 1.0.2 2533 + hasown: 2.0.2 2534 + 2535 + es-to-primitive@1.3.0: 2536 + dependencies: 2537 + is-callable: 1.2.7 2538 + is-date-object: 1.1.0 2539 + is-symbol: 1.1.1 2540 + 673 2541 esbuild@0.27.2: 674 2542 optionalDependencies: 675 2543 '@esbuild/aix-ppc64': 0.27.2 ··· 698 2566 '@esbuild/win32-arm64': 0.27.2 699 2567 '@esbuild/win32-ia32': 0.27.2 700 2568 '@esbuild/win32-x64': 0.27.2 2569 + 2570 + escape-string-regexp@1.0.5: {} 701 2571 702 2572 event-target-shim@5.0.1: {} 703 2573 704 2574 events@3.3.0: {} 705 2575 2576 + exsolve@1.0.8: {} 2577 + 2578 + fast-copy@4.0.2: {} 2579 + 706 2580 fast-deep-equal@3.1.3: {} 707 2581 708 2582 fast-redact@3.5.0: {} 709 2583 2584 + fast-safe-stringify@2.1.1: {} 2585 + 2586 + fill-range@7.1.1: 2587 + dependencies: 2588 + to-regex-range: 5.0.1 2589 + 2590 + for-each@0.3.5: 2591 + dependencies: 2592 + is-callable: 1.2.7 2593 + 2594 + fs.realpath@1.0.0: {} 2595 + 710 2596 fsevents@2.3.3: 711 2597 optional: true 712 2598 2599 + function-bind@1.1.2: {} 2600 + 2601 + function.prototype.name@1.1.8: 2602 + dependencies: 2603 + call-bind: 1.0.8 2604 + call-bound: 1.0.4 2605 + define-properties: 1.2.1 2606 + functions-have-names: 1.2.3 2607 + hasown: 2.0.2 2608 + is-callable: 1.2.7 2609 + 2610 + functions-have-names@1.2.3: {} 2611 + 2612 + generator-function@2.0.1: {} 2613 + 2614 + get-caller-file@2.0.5: {} 2615 + 2616 + get-intrinsic@1.3.0: 2617 + dependencies: 2618 + call-bind-apply-helpers: 1.0.2 2619 + es-define-property: 1.0.1 2620 + es-errors: 1.3.0 2621 + es-object-atoms: 1.1.1 2622 + function-bind: 1.1.2 2623 + get-proto: 1.0.1 2624 + gopd: 1.2.0 2625 + has-symbols: 1.1.0 2626 + hasown: 2.0.2 2627 + math-intrinsics: 1.1.0 2628 + 2629 + get-proto@1.0.1: 2630 + dependencies: 2631 + dunder-proto: 1.0.1 2632 + es-object-atoms: 1.1.1 2633 + 2634 + get-symbol-description@1.1.0: 2635 + dependencies: 2636 + call-bound: 1.0.4 2637 + es-errors: 1.3.0 2638 + get-intrinsic: 1.3.0 2639 + 713 2640 get-tsconfig@4.13.0: 714 2641 dependencies: 715 2642 resolve-pkg-maps: 1.0.0 716 2643 2644 + giget@2.0.0: 2645 + dependencies: 2646 + citty: 0.1.6 2647 + consola: 3.4.2 2648 + defu: 6.1.4 2649 + node-fetch-native: 1.6.7 2650 + nypm: 0.6.2 2651 + pathe: 2.0.3 2652 + 2653 + git-diff@2.0.6: 2654 + dependencies: 2655 + chalk: 2.4.2 2656 + diff: 3.5.0 2657 + loglevel: 1.9.2 2658 + shelljs: 0.8.5 2659 + shelljs.exec: 1.1.8 2660 + 2661 + glob@7.2.3: 2662 + dependencies: 2663 + fs.realpath: 1.0.0 2664 + inflight: 1.0.6 2665 + inherits: 2.0.4 2666 + minimatch: 3.1.2 2667 + once: 1.4.0 2668 + path-is-absolute: 1.0.1 2669 + 2670 + globalthis@1.0.4: 2671 + dependencies: 2672 + define-properties: 1.2.1 2673 + gopd: 1.2.0 2674 + 2675 + gopd@1.2.0: {} 2676 + 2677 + graceful-fs@4.2.11: {} 2678 + 2679 + has-bigints@1.1.0: {} 2680 + 2681 + has-flag@3.0.0: {} 2682 + 2683 + has-flag@4.0.0: {} 2684 + 2685 + has-property-descriptors@1.0.2: 2686 + dependencies: 2687 + es-define-property: 1.0.1 2688 + 2689 + has-proto@1.2.0: 2690 + dependencies: 2691 + dunder-proto: 1.0.1 2692 + 2693 + has-symbols@1.1.0: {} 2694 + 2695 + has-tostringtag@1.0.2: 2696 + dependencies: 2697 + has-symbols: 1.1.0 2698 + 2699 + hasown@2.0.2: 2700 + dependencies: 2701 + function-bind: 1.1.2 2702 + 2703 + help-me@5.0.0: {} 2704 + 2705 + hono@4.11.3: {} 2706 + 2707 + hosted-git-info@2.8.9: {} 2708 + 717 2709 ieee754@1.2.1: {} 718 2710 2711 + import-fresh@3.3.1: 2712 + dependencies: 2713 + parent-module: 1.0.1 2714 + resolve-from: 4.0.0 2715 + 2716 + inflight@1.0.6: 2717 + dependencies: 2718 + once: 1.4.0 2719 + wrappy: 1.0.2 2720 + 2721 + inherits@2.0.4: {} 2722 + 2723 + internal-slot@1.1.0: 2724 + dependencies: 2725 + es-errors: 1.3.0 2726 + hasown: 2.0.2 2727 + side-channel: 1.1.0 2728 + 2729 + interpret@1.4.0: {} 2730 + 2731 + ipaddr.js@2.3.0: {} 2732 + 2733 + is-array-buffer@3.0.5: 2734 + dependencies: 2735 + call-bind: 1.0.8 2736 + call-bound: 1.0.4 2737 + get-intrinsic: 1.3.0 2738 + 2739 + is-arrayish@0.2.1: {} 2740 + 2741 + is-async-function@2.1.1: 2742 + dependencies: 2743 + async-function: 1.0.0 2744 + call-bound: 1.0.4 2745 + get-proto: 1.0.1 2746 + has-tostringtag: 1.0.2 2747 + safe-regex-test: 1.1.0 2748 + 2749 + is-bigint@1.1.0: 2750 + dependencies: 2751 + has-bigints: 1.1.0 2752 + 2753 + is-boolean-object@1.2.2: 2754 + dependencies: 2755 + call-bound: 1.0.4 2756 + has-tostringtag: 1.0.2 2757 + 2758 + is-callable@1.2.7: {} 2759 + 2760 + is-core-module@2.16.1: 2761 + dependencies: 2762 + hasown: 2.0.2 2763 + 2764 + is-data-view@1.0.2: 2765 + dependencies: 2766 + call-bound: 1.0.4 2767 + get-intrinsic: 1.3.0 2768 + is-typed-array: 1.1.15 2769 + 2770 + is-date-object@1.1.0: 2771 + dependencies: 2772 + call-bound: 1.0.4 2773 + has-tostringtag: 1.0.2 2774 + 2775 + is-finalizationregistry@1.1.1: 2776 + dependencies: 2777 + call-bound: 1.0.4 2778 + 2779 + is-generator-function@1.1.2: 2780 + dependencies: 2781 + call-bound: 1.0.4 2782 + generator-function: 2.0.1 2783 + get-proto: 1.0.1 2784 + has-tostringtag: 1.0.2 2785 + safe-regex-test: 1.1.0 2786 + 2787 + is-map@2.0.3: {} 2788 + 2789 + is-negative-zero@2.0.3: {} 2790 + 2791 + is-number-object@1.1.1: 2792 + dependencies: 2793 + call-bound: 1.0.4 2794 + has-tostringtag: 1.0.2 2795 + 2796 + is-number@7.0.0: {} 2797 + 2798 + is-regex@1.2.1: 2799 + dependencies: 2800 + call-bound: 1.0.4 2801 + gopd: 1.2.0 2802 + has-tostringtag: 1.0.2 2803 + hasown: 2.0.2 2804 + 2805 + is-set@2.0.3: {} 2806 + 2807 + is-shared-array-buffer@1.0.4: 2808 + dependencies: 2809 + call-bound: 1.0.4 2810 + 2811 + is-string@1.1.1: 2812 + dependencies: 2813 + call-bound: 1.0.4 2814 + has-tostringtag: 1.0.2 2815 + 2816 + is-symbol@1.1.1: 2817 + dependencies: 2818 + call-bound: 1.0.4 2819 + has-symbols: 1.1.0 2820 + safe-regex-test: 1.1.0 2821 + 2822 + is-typed-array@1.1.15: 2823 + dependencies: 2824 + which-typed-array: 1.1.19 2825 + 2826 + is-weakmap@2.0.2: {} 2827 + 2828 + is-weakref@1.1.1: 2829 + dependencies: 2830 + call-bound: 1.0.4 2831 + 2832 + is-weakset@2.0.4: 2833 + dependencies: 2834 + call-bound: 1.0.4 2835 + get-intrinsic: 1.3.0 2836 + 2837 + isarray@2.0.5: {} 2838 + 2839 + isexe@2.0.0: {} 2840 + 719 2841 iso-datestring-validator@2.2.2: {} 720 2842 2843 + jiti@2.6.1: {} 2844 + 2845 + jose@5.10.0: {} 2846 + 2847 + joycon@3.1.1: {} 2848 + 2849 + js-tokens@4.0.0: {} 2850 + 2851 + js-yaml@4.1.1: 2852 + dependencies: 2853 + argparse: 2.0.1 2854 + 2855 + json-parse-better-errors@1.0.2: {} 2856 + 2857 + json-parse-even-better-errors@2.3.1: {} 2858 + 2859 + kysely-codegen@0.19.0(kysely@0.28.9)(pg@8.16.3)(typescript@5.9.2): 2860 + dependencies: 2861 + chalk: 4.1.2 2862 + cosmiconfig: 9.0.0(typescript@5.9.2) 2863 + dotenv: 17.2.3 2864 + dotenv-expand: 12.0.3 2865 + git-diff: 2.0.6 2866 + kysely: 0.28.9 2867 + micromatch: 4.0.8 2868 + minimist: 1.2.8 2869 + pluralize: 8.0.0 2870 + zod: 4.2.1 2871 + optionalDependencies: 2872 + pg: 8.16.3 2873 + transitivePeerDependencies: 2874 + - typescript 2875 + 2876 + kysely-ctl@0.19.0(kysely@0.28.9)(typescript@5.9.2): 2877 + dependencies: 2878 + c12: 3.3.3 2879 + citty: 0.1.6 2880 + confbox: 0.2.2 2881 + consola: 3.4.2 2882 + jiti: 2.6.1 2883 + kysely: 0.28.9 2884 + nypm: 0.6.2 2885 + ofetch: 1.5.1 2886 + pathe: 2.0.3 2887 + pkg-types: 2.3.0 2888 + std-env: 3.10.0 2889 + tsconfck: 3.1.6(typescript@5.9.2) 2890 + transitivePeerDependencies: 2891 + - magicast 2892 + - typescript 2893 + 2894 + kysely-migration-cli@0.4.2: 2895 + dependencies: 2896 + '@commander-js/extra-typings': 11.1.0(commander@11.1.0) 2897 + commander: 11.1.0 2898 + 721 2899 kysely@0.28.9: {} 722 2900 2901 + lefthook-darwin-arm64@2.0.13: 2902 + optional: true 2903 + 2904 + lefthook-darwin-x64@2.0.13: 2905 + optional: true 2906 + 2907 + lefthook-freebsd-arm64@2.0.13: 2908 + optional: true 2909 + 2910 + lefthook-freebsd-x64@2.0.13: 2911 + optional: true 2912 + 2913 + lefthook-linux-arm64@2.0.13: 2914 + optional: true 2915 + 2916 + lefthook-linux-x64@2.0.13: 2917 + optional: true 2918 + 2919 + lefthook-openbsd-arm64@2.0.13: 2920 + optional: true 2921 + 2922 + lefthook-openbsd-x64@2.0.13: 2923 + optional: true 2924 + 2925 + lefthook-windows-arm64@2.0.13: 2926 + optional: true 2927 + 2928 + lefthook-windows-x64@2.0.13: 2929 + optional: true 2930 + 2931 + lefthook@2.0.13: 2932 + optionalDependencies: 2933 + lefthook-darwin-arm64: 2.0.13 2934 + lefthook-darwin-x64: 2.0.13 2935 + lefthook-freebsd-arm64: 2.0.13 2936 + lefthook-freebsd-x64: 2.0.13 2937 + lefthook-linux-arm64: 2.0.13 2938 + lefthook-linux-x64: 2.0.13 2939 + lefthook-openbsd-arm64: 2.0.13 2940 + lefthook-openbsd-x64: 2.0.13 2941 + lefthook-windows-arm64: 2.0.13 2942 + lefthook-windows-x64: 2.0.13 2943 + 2944 + lines-and-columns@1.2.4: {} 2945 + 2946 + load-json-file@4.0.0: 2947 + dependencies: 2948 + graceful-fs: 4.2.11 2949 + parse-json: 4.0.0 2950 + pify: 3.0.0 2951 + strip-bom: 3.0.0 2952 + 723 2953 lodash.snakecase@4.1.1: {} 724 2954 725 2955 lodash@4.17.21: {} 726 2956 2957 + loglevel@1.9.2: {} 2958 + 2959 + lru-cache@10.4.3: {} 2960 + 727 2961 magic-bytes.js@1.12.1: {} 728 2962 2963 + math-intrinsics@1.1.0: {} 2964 + 2965 + memorystream@0.3.1: {} 2966 + 2967 + micromatch@4.0.8: 2968 + dependencies: 2969 + braces: 3.0.3 2970 + picomatch: 2.3.1 2971 + 2972 + minimatch@3.1.2: 2973 + dependencies: 2974 + brace-expansion: 1.1.12 2975 + 2976 + minimist@1.2.8: {} 2977 + 729 2978 multiformats@9.9.0: {} 730 2979 2980 + nice-try@1.0.5: {} 2981 + 2982 + node-fetch-native@1.6.7: {} 2983 + 2984 + normalize-package-data@2.5.0: 2985 + dependencies: 2986 + hosted-git-info: 2.8.9 2987 + resolve: 1.22.11 2988 + semver: 5.7.2 2989 + validate-npm-package-license: 3.0.4 2990 + 2991 + npm-run-all@4.1.5: 2992 + dependencies: 2993 + ansi-styles: 3.2.1 2994 + chalk: 2.4.2 2995 + cross-spawn: 6.0.6 2996 + memorystream: 0.3.1 2997 + minimatch: 3.1.2 2998 + pidtree: 0.3.1 2999 + read-pkg: 3.0.0 3000 + shell-quote: 1.8.3 3001 + string.prototype.padend: 3.1.6 3002 + 3003 + nypm@0.6.2: 3004 + dependencies: 3005 + citty: 0.1.6 3006 + consola: 3.4.2 3007 + pathe: 2.0.3 3008 + pkg-types: 2.3.0 3009 + tinyexec: 1.0.2 3010 + 3011 + object-inspect@1.13.4: {} 3012 + 3013 + object-keys@1.1.1: {} 3014 + 3015 + object.assign@4.1.7: 3016 + dependencies: 3017 + call-bind: 1.0.8 3018 + call-bound: 1.0.4 3019 + define-properties: 1.2.1 3020 + es-object-atoms: 1.1.1 3021 + has-symbols: 1.1.0 3022 + object-keys: 1.1.1 3023 + 3024 + ofetch@1.5.1: 3025 + dependencies: 3026 + destr: 2.0.5 3027 + node-fetch-native: 1.6.7 3028 + ufo: 1.6.1 3029 + 3030 + ohash@2.0.11: {} 3031 + 731 3032 on-exit-leak-free@2.1.2: {} 732 3033 3034 + once@1.4.0: 3035 + dependencies: 3036 + wrappy: 1.0.2 3037 + 3038 + own-keys@1.0.1: 3039 + dependencies: 3040 + get-intrinsic: 1.3.0 3041 + object-keys: 1.1.1 3042 + safe-push-apply: 1.0.0 3043 + 3044 + oxfmt@0.20.0: 3045 + dependencies: 3046 + tinypool: 2.0.0 3047 + optionalDependencies: 3048 + '@oxfmt/darwin-arm64': 0.20.0 3049 + '@oxfmt/darwin-x64': 0.20.0 3050 + '@oxfmt/linux-arm64-gnu': 0.20.0 3051 + '@oxfmt/linux-arm64-musl': 0.20.0 3052 + '@oxfmt/linux-x64-gnu': 0.20.0 3053 + '@oxfmt/linux-x64-musl': 0.20.0 3054 + '@oxfmt/win32-arm64': 0.20.0 3055 + '@oxfmt/win32-x64': 0.20.0 3056 + 3057 + oxlint@1.35.0: 3058 + optionalDependencies: 3059 + '@oxlint/darwin-arm64': 1.35.0 3060 + '@oxlint/darwin-x64': 1.35.0 3061 + '@oxlint/linux-arm64-gnu': 1.35.0 3062 + '@oxlint/linux-arm64-musl': 1.35.0 3063 + '@oxlint/linux-x64-gnu': 1.35.0 3064 + '@oxlint/linux-x64-musl': 1.35.0 3065 + '@oxlint/win32-arm64': 1.35.0 3066 + '@oxlint/win32-x64': 1.35.0 3067 + 3068 + parent-module@1.0.1: 3069 + dependencies: 3070 + callsites: 3.1.0 3071 + 3072 + parse-json@4.0.0: 3073 + dependencies: 3074 + error-ex: 1.3.4 3075 + json-parse-better-errors: 1.0.2 3076 + 3077 + parse-json@5.2.0: 3078 + dependencies: 3079 + '@babel/code-frame': 7.27.1 3080 + error-ex: 1.3.4 3081 + json-parse-even-better-errors: 2.3.1 3082 + lines-and-columns: 1.2.4 3083 + 3084 + path-is-absolute@1.0.1: {} 3085 + 3086 + path-key@2.0.1: {} 3087 + 3088 + path-parse@1.0.7: {} 3089 + 3090 + path-type@3.0.0: 3091 + dependencies: 3092 + pify: 3.0.0 3093 + 3094 + pathe@2.0.3: {} 3095 + 3096 + perfect-debounce@2.0.0: {} 3097 + 3098 + pg-cloudflare@1.2.7: 3099 + optional: true 3100 + 3101 + pg-connection-string@2.9.1: {} 3102 + 3103 + pg-int8@1.0.1: {} 3104 + 3105 + pg-pool@3.10.1(pg@8.16.3): 3106 + dependencies: 3107 + pg: 8.16.3 3108 + 3109 + pg-protocol@1.10.3: {} 3110 + 3111 + pg-types@2.2.0: 3112 + dependencies: 3113 + pg-int8: 1.0.1 3114 + postgres-array: 2.0.0 3115 + postgres-bytea: 1.0.1 3116 + postgres-date: 1.0.7 3117 + postgres-interval: 1.2.0 3118 + 3119 + pg@8.16.3: 3120 + dependencies: 3121 + pg-connection-string: 2.9.1 3122 + pg-pool: 3.10.1(pg@8.16.3) 3123 + pg-protocol: 1.10.3 3124 + pg-types: 2.2.0 3125 + pgpass: 1.0.5 3126 + optionalDependencies: 3127 + pg-cloudflare: 1.2.7 3128 + 3129 + pgpass@1.0.5: 3130 + dependencies: 3131 + split2: 4.2.0 3132 + 3133 + picocolors@1.1.1: {} 3134 + 3135 + picomatch@2.3.1: {} 3136 + 3137 + pidtree@0.3.1: {} 3138 + 3139 + pify@3.0.0: {} 3140 + 733 3141 pino-abstract-transport@1.2.0: 734 3142 dependencies: 735 3143 readable-stream: 4.7.0 736 3144 split2: 4.2.0 737 3145 3146 + pino-abstract-transport@2.0.0: 3147 + dependencies: 3148 + split2: 4.2.0 3149 + 3150 + pino-abstract-transport@3.0.0: 3151 + dependencies: 3152 + split2: 4.2.0 3153 + 3154 + pino-http@11.0.0: 3155 + dependencies: 3156 + get-caller-file: 2.0.5 3157 + pino: 10.1.0 3158 + pino-std-serializers: 7.0.0 3159 + process-warning: 5.0.0 3160 + 3161 + pino-pretty@13.1.3: 3162 + dependencies: 3163 + colorette: 2.0.20 3164 + dateformat: 4.6.3 3165 + fast-copy: 4.0.2 3166 + fast-safe-stringify: 2.1.1 3167 + help-me: 5.0.0 3168 + joycon: 3.1.1 3169 + minimist: 1.2.8 3170 + on-exit-leak-free: 2.1.2 3171 + pino-abstract-transport: 3.0.0 3172 + pump: 3.0.3 3173 + secure-json-parse: 4.1.0 3174 + sonic-boom: 4.2.0 3175 + strip-json-comments: 5.0.3 3176 + 738 3177 pino-std-serializers@6.2.2: {} 739 3178 3179 + pino-std-serializers@7.0.0: {} 3180 + 3181 + pino@10.1.0: 3182 + dependencies: 3183 + '@pinojs/redact': 0.4.0 3184 + atomic-sleep: 1.0.0 3185 + on-exit-leak-free: 2.1.2 3186 + pino-abstract-transport: 2.0.0 3187 + pino-std-serializers: 7.0.0 3188 + process-warning: 5.0.0 3189 + quick-format-unescaped: 4.0.4 3190 + real-require: 0.2.0 3191 + safe-stable-stringify: 2.5.0 3192 + sonic-boom: 4.2.0 3193 + thread-stream: 3.1.0 3194 + 740 3195 pino@8.21.0: 741 3196 dependencies: 742 3197 atomic-sleep: 1.0.0 ··· 750 3205 safe-stable-stringify: 2.5.0 751 3206 sonic-boom: 3.8.1 752 3207 thread-stream: 2.7.0 3208 + 3209 + pkg-types@2.3.0: 3210 + dependencies: 3211 + confbox: 0.2.2 3212 + exsolve: 1.0.8 3213 + pathe: 2.0.3 3214 + 3215 + pluralize@8.0.0: {} 3216 + 3217 + possible-typed-array-names@1.1.0: {} 3218 + 3219 + postgres-array@2.0.0: {} 3220 + 3221 + postgres-bytea@1.0.1: {} 3222 + 3223 + postgres-date@1.0.7: {} 3224 + 3225 + postgres-interval@1.2.0: 3226 + dependencies: 3227 + xtend: 4.0.2 753 3228 754 3229 process-warning@3.0.0: {} 755 3230 3231 + process-warning@5.0.0: {} 3232 + 756 3233 process@0.11.10: {} 757 3234 3235 + pump@3.0.3: 3236 + dependencies: 3237 + end-of-stream: 1.4.5 3238 + once: 1.4.0 3239 + 758 3240 quick-format-unescaped@4.0.4: {} 759 3241 3242 + rc9@2.1.2: 3243 + dependencies: 3244 + defu: 6.1.4 3245 + destr: 2.0.5 3246 + 3247 + read-pkg@3.0.0: 3248 + dependencies: 3249 + load-json-file: 4.0.0 3250 + normalize-package-data: 2.5.0 3251 + path-type: 3.0.0 3252 + 760 3253 readable-stream@4.7.0: 761 3254 dependencies: 762 3255 abort-controller: 3.0.0 ··· 765 3258 process: 0.11.10 766 3259 string_decoder: 1.3.0 767 3260 3261 + readdirp@5.0.0: {} 3262 + 768 3263 real-require@0.2.0: {} 769 3264 3265 + rechoir@0.6.2: 3266 + dependencies: 3267 + resolve: 1.22.11 3268 + 3269 + reflect.getprototypeof@1.0.10: 3270 + dependencies: 3271 + call-bind: 1.0.8 3272 + define-properties: 1.2.1 3273 + es-abstract: 1.24.1 3274 + es-errors: 1.3.0 3275 + es-object-atoms: 1.1.1 3276 + get-intrinsic: 1.3.0 3277 + get-proto: 1.0.1 3278 + which-builtin-type: 1.2.1 3279 + 3280 + regexp.prototype.flags@1.5.4: 3281 + dependencies: 3282 + call-bind: 1.0.8 3283 + define-properties: 1.2.1 3284 + es-errors: 1.3.0 3285 + get-proto: 1.0.1 3286 + gopd: 1.2.0 3287 + set-function-name: 2.0.2 3288 + 3289 + resolve-from@4.0.0: {} 3290 + 770 3291 resolve-pkg-maps@1.0.0: {} 771 3292 3293 + resolve@1.22.11: 3294 + dependencies: 3295 + is-core-module: 2.16.1 3296 + path-parse: 1.0.7 3297 + supports-preserve-symlinks-flag: 1.0.0 3298 + 3299 + safe-array-concat@1.1.3: 3300 + dependencies: 3301 + call-bind: 1.0.8 3302 + call-bound: 1.0.4 3303 + get-intrinsic: 1.3.0 3304 + has-symbols: 1.1.0 3305 + isarray: 2.0.5 3306 + 772 3307 safe-buffer@5.2.1: {} 773 3308 3309 + safe-push-apply@1.0.0: 3310 + dependencies: 3311 + es-errors: 1.3.0 3312 + isarray: 2.0.5 3313 + 3314 + safe-regex-test@1.1.0: 3315 + dependencies: 3316 + call-bound: 1.0.4 3317 + es-errors: 1.3.0 3318 + is-regex: 1.2.1 3319 + 774 3320 safe-stable-stringify@2.5.0: {} 775 3321 3322 + secure-json-parse@4.1.0: {} 3323 + 3324 + semver@5.7.2: {} 3325 + 3326 + set-function-length@1.2.2: 3327 + dependencies: 3328 + define-data-property: 1.1.4 3329 + es-errors: 1.3.0 3330 + function-bind: 1.1.2 3331 + get-intrinsic: 1.3.0 3332 + gopd: 1.2.0 3333 + has-property-descriptors: 1.0.2 3334 + 3335 + set-function-name@2.0.2: 3336 + dependencies: 3337 + define-data-property: 1.1.4 3338 + es-errors: 1.3.0 3339 + functions-have-names: 1.2.3 3340 + has-property-descriptors: 1.0.2 3341 + 3342 + set-proto@1.0.0: 3343 + dependencies: 3344 + dunder-proto: 1.0.1 3345 + es-errors: 1.3.0 3346 + es-object-atoms: 1.1.1 3347 + 3348 + shebang-command@1.2.0: 3349 + dependencies: 3350 + shebang-regex: 1.0.0 3351 + 3352 + shebang-regex@1.0.0: {} 3353 + 3354 + shell-quote@1.8.3: {} 3355 + 3356 + shelljs.exec@1.1.8: {} 3357 + 3358 + shelljs@0.8.5: 3359 + dependencies: 3360 + glob: 7.2.3 3361 + interpret: 1.4.0 3362 + rechoir: 0.6.2 3363 + 3364 + side-channel-list@1.0.0: 3365 + dependencies: 3366 + es-errors: 1.3.0 3367 + object-inspect: 1.13.4 3368 + 3369 + side-channel-map@1.0.1: 3370 + dependencies: 3371 + call-bound: 1.0.4 3372 + es-errors: 1.3.0 3373 + get-intrinsic: 1.3.0 3374 + object-inspect: 1.13.4 3375 + 3376 + side-channel-weakmap@1.0.2: 3377 + dependencies: 3378 + call-bound: 1.0.4 3379 + es-errors: 1.3.0 3380 + get-intrinsic: 1.3.0 3381 + object-inspect: 1.13.4 3382 + side-channel-map: 1.0.1 3383 + 3384 + side-channel@1.1.0: 3385 + dependencies: 3386 + es-errors: 1.3.0 3387 + object-inspect: 1.13.4 3388 + side-channel-list: 1.0.0 3389 + side-channel-map: 1.0.1 3390 + side-channel-weakmap: 1.0.2 3391 + 776 3392 sonic-boom@3.8.1: 777 3393 dependencies: 778 3394 atomic-sleep: 1.0.0 779 3395 3396 + sonic-boom@4.2.0: 3397 + dependencies: 3398 + atomic-sleep: 1.0.0 3399 + 3400 + spdx-correct@3.2.0: 3401 + dependencies: 3402 + spdx-expression-parse: 3.0.1 3403 + spdx-license-ids: 3.0.22 3404 + 3405 + spdx-exceptions@2.5.0: {} 3406 + 3407 + spdx-expression-parse@3.0.1: 3408 + dependencies: 3409 + spdx-exceptions: 2.5.0 3410 + spdx-license-ids: 3.0.22 3411 + 3412 + spdx-license-ids@3.0.22: {} 3413 + 780 3414 split2@4.2.0: {} 781 3415 3416 + std-env@3.10.0: {} 3417 + 3418 + stop-iteration-iterator@1.1.0: 3419 + dependencies: 3420 + es-errors: 1.3.0 3421 + internal-slot: 1.1.0 3422 + 3423 + string.prototype.padend@3.1.6: 3424 + dependencies: 3425 + call-bind: 1.0.8 3426 + define-properties: 1.2.1 3427 + es-abstract: 1.24.1 3428 + es-object-atoms: 1.1.1 3429 + 3430 + string.prototype.trim@1.2.10: 3431 + dependencies: 3432 + call-bind: 1.0.8 3433 + call-bound: 1.0.4 3434 + define-data-property: 1.1.4 3435 + define-properties: 1.2.1 3436 + es-abstract: 1.24.1 3437 + es-object-atoms: 1.1.1 3438 + has-property-descriptors: 1.0.2 3439 + 3440 + string.prototype.trimend@1.0.9: 3441 + dependencies: 3442 + call-bind: 1.0.8 3443 + call-bound: 1.0.4 3444 + define-properties: 1.2.1 3445 + es-object-atoms: 1.1.1 3446 + 3447 + string.prototype.trimstart@1.0.8: 3448 + dependencies: 3449 + call-bind: 1.0.8 3450 + define-properties: 1.2.1 3451 + es-object-atoms: 1.1.1 3452 + 782 3453 string_decoder@1.3.0: 783 3454 dependencies: 784 3455 safe-buffer: 5.2.1 785 3456 3457 + strip-bom@3.0.0: {} 3458 + 3459 + strip-json-comments@5.0.3: {} 3460 + 3461 + supports-color@5.5.0: 3462 + dependencies: 3463 + has-flag: 3.0.0 3464 + 3465 + supports-color@7.2.0: 3466 + dependencies: 3467 + has-flag: 4.0.0 3468 + 3469 + supports-preserve-symlinks-flag@1.0.0: {} 3470 + 786 3471 thread-stream@2.7.0: 787 3472 dependencies: 788 3473 real-require: 0.2.0 789 3474 3475 + thread-stream@3.1.0: 3476 + dependencies: 3477 + real-require: 0.2.0 3478 + 3479 + tinyexec@1.0.2: {} 3480 + 3481 + tinypool@2.0.0: {} 3482 + 3483 + tlds@1.261.0: {} 3484 + 3485 + to-regex-range@5.0.1: 3486 + dependencies: 3487 + is-number: 7.0.0 3488 + 790 3489 ts-mixer@6.0.4: {} 791 3490 3491 + tsconfck@3.1.6(typescript@5.9.2): 3492 + optionalDependencies: 3493 + typescript: 5.9.2 3494 + 792 3495 tslib@2.8.1: {} 793 3496 794 3497 tsx@4.21.0: ··· 798 3501 optionalDependencies: 799 3502 fsevents: 2.3.3 800 3503 3504 + typed-array-buffer@1.0.3: 3505 + dependencies: 3506 + call-bound: 1.0.4 3507 + es-errors: 1.3.0 3508 + is-typed-array: 1.1.15 3509 + 3510 + typed-array-byte-length@1.0.3: 3511 + dependencies: 3512 + call-bind: 1.0.8 3513 + for-each: 0.3.5 3514 + gopd: 1.2.0 3515 + has-proto: 1.2.0 3516 + is-typed-array: 1.1.15 3517 + 3518 + typed-array-byte-offset@1.0.4: 3519 + dependencies: 3520 + available-typed-arrays: 1.0.7 3521 + call-bind: 1.0.8 3522 + for-each: 0.3.5 3523 + gopd: 1.2.0 3524 + has-proto: 1.2.0 3525 + is-typed-array: 1.1.15 3526 + reflect.getprototypeof: 1.0.10 3527 + 3528 + typed-array-length@1.0.7: 3529 + dependencies: 3530 + call-bind: 1.0.8 3531 + for-each: 0.3.5 3532 + gopd: 1.2.0 3533 + is-typed-array: 1.1.15 3534 + possible-typed-array-names: 1.1.0 3535 + reflect.getprototypeof: 1.0.10 3536 + 3537 + typescript@5.9.2: {} 3538 + 801 3539 typescript@5.9.3: {} 802 3540 3541 + ufo@1.6.1: {} 3542 + 803 3543 uint8arrays@3.0.0: 804 3544 dependencies: 805 3545 multiformats: 9.9.0 806 3546 3547 + unbox-primitive@1.1.0: 3548 + dependencies: 3549 + call-bound: 1.0.4 3550 + has-bigints: 1.1.0 3551 + has-symbols: 1.1.0 3552 + which-boxed-primitive: 1.1.1 3553 + 3554 + undici-types@6.21.0: {} 3555 + 807 3556 undici-types@7.16.0: {} 808 3557 809 3558 undici@6.21.3: {} 810 3559 811 3560 unicode-segmenter@0.14.4: {} 812 3561 3562 + validate-npm-package-license@3.0.4: 3563 + dependencies: 3564 + spdx-correct: 3.2.0 3565 + spdx-expression-parse: 3.0.1 3566 + 3567 + which-boxed-primitive@1.1.1: 3568 + dependencies: 3569 + is-bigint: 1.1.0 3570 + is-boolean-object: 1.2.2 3571 + is-number-object: 1.1.1 3572 + is-string: 1.1.1 3573 + is-symbol: 1.1.1 3574 + 3575 + which-builtin-type@1.2.1: 3576 + dependencies: 3577 + call-bound: 1.0.4 3578 + function.prototype.name: 1.1.8 3579 + has-tostringtag: 1.0.2 3580 + is-async-function: 2.1.1 3581 + is-date-object: 1.1.0 3582 + is-finalizationregistry: 1.1.1 3583 + is-generator-function: 1.1.2 3584 + is-regex: 1.2.1 3585 + is-weakref: 1.1.1 3586 + isarray: 2.0.5 3587 + which-boxed-primitive: 1.1.1 3588 + which-collection: 1.0.2 3589 + which-typed-array: 1.1.19 3590 + 3591 + which-collection@1.0.2: 3592 + dependencies: 3593 + is-map: 2.0.3 3594 + is-set: 2.0.3 3595 + is-weakmap: 2.0.2 3596 + is-weakset: 2.0.4 3597 + 3598 + which-typed-array@1.1.19: 3599 + dependencies: 3600 + available-typed-arrays: 1.0.7 3601 + call-bind: 1.0.8 3602 + call-bound: 1.0.4 3603 + for-each: 0.3.5 3604 + get-proto: 1.0.1 3605 + gopd: 1.2.0 3606 + has-tostringtag: 1.0.2 3607 + 3608 + which@1.3.1: 3609 + dependencies: 3610 + isexe: 2.0.0 3611 + 3612 + wrappy@1.0.2: {} 3613 + 813 3614 ws@8.18.3: {} 3615 + 3616 + xtend@4.0.2: {} 814 3617 815 3618 zod@3.25.76: {} 3619 + 3620 + zod@4.2.1: {}
+11
pnpm-workspace.yaml
··· 1 1 onlyBuiltDependencies: 2 2 - esbuild 3 + 4 + packages: 5 + - "apps/*" 6 + - "packages/*" 7 + 8 + blockExoticSubdeps: true 9 + minimumReleaseAge: 10080 10 + trustPolicy: no-downgrade 11 + syncInjectedDepsAfterScripts: 12 + - build 13 + injectWorkspacePackages: true
-28
tapper.ts
··· 1 - import { SimpleIndexer, Tap } from "@atproto/tap"; 2 - import { TAP_ADMIN_PASSWORD } from "./constants.ts"; 3 - 4 - const tap = new Tap("https://tap.xero.systems", { 5 - adminPassword: TAP_ADMIN_PASSWORD, 6 - }); 7 - 8 - const indexer = new SimpleIndexer(); 9 - 10 - indexer.record(async (evt, opts) => { 11 - const uri = `at://${evt.did}/${evt.collection}/${evt.rkey}`; 12 - if (evt.action === "create" || evt.action === "update") { 13 - console.log(evt.record); 14 - } else { 15 - console.log(`deleted: ${uri}`); 16 - } 17 - 18 - if (process.env.NODE_ENV === "development") { 19 - // we don't want to ack in development 20 - // @ts-ignore 21 - opts.ack = () => console.log('"acknowledged"'); 22 - } 23 - }); 24 - 25 - indexer.error((err) => console.error(err)); 26 - 27 - const channel = tap.channel(indexer); 28 - channel.start();
-24
tsconfig.json
··· 1 - { 2 - "compilerOptions": { 3 - "outDir": "./dist", 4 - "module": "nodenext", 5 - "target": "esnext", 6 - "lib": [ 7 - "esnext" 8 - ], 9 - "types": [ 10 - "node" 11 - ], 12 - "esModuleInterop": true, 13 - "sourceMap": true, 14 - "noUncheckedIndexedAccess": true, 15 - "exactOptionalPropertyTypes": true, 16 - "strict": true, 17 - "verbatimModuleSyntax": true, 18 - "isolatedModules": true, 19 - "allowImportingTsExtensions": true, 20 - "noUncheckedSideEffectImports": true, 21 - "moduleDetection": "force", 22 - "skipLibCheck": true, 23 - } 24 - }