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
.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 + }
+8 -11
.tangled/workflows/lint.yml
··· 6 6 7 7 dependencies: 8 8 nixpkgs: 9 - - nodejs 9 + - nodejs_24 10 + - pnpm 11 + - gnused 12 + 10 13 steps: 11 - # - name: install 12 - # command: pnpm i --frozen-lockfile 14 + - name: install 15 + command: pnpm i --frozen-lockfile 13 16 14 - - name: debug 15 - command: | 16 - corepack enable 17 - pnpm store path 18 - cat /tangled/home/.local/state/bin/node 19 - 20 - # - name: lint 21 - # command: pnpm typecheck 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"
+8 -4
PLAN.md
··· 1 1 # rough notes on how I think this should work 2 2 3 3 - we start of with no accounts 4 - - ``/teal auth`` sends user a link to log in with atproto account 4 + - `/auth <did or handle>` sends user a link to log in with atproto account 5 5 - after auth success, we take did and send http request to tap instance to start backfilling for repo 6 6 - user can now use bot commands 7 7 8 8 ## planned commands 9 9 10 - - ``teal auth`` 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 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 13 14 14 ## web interface for account management...maybe..? 15 15 16 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.
+16 -8
apps/bot/commands/auth.ts
··· 1 - import { CommandInteraction, SlashCommandBuilder } from "discord.js"; 2 - import { logger } from "@tealfmbot/common/logger.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; 3 7 4 8 export default { 5 - data: new SlashCommandBuilder().setName("auth").setDescription( 6 - "Authenticate your account with the teal.fm bot to start tracking your listens", 7 - ), 8 - async execute(interaction: CommandInteraction) { 9 - await interaction.reply("placeholder"); 10 - logger.info("auth command sent") 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 + ); 11 19 }, 12 20 };
+3 -5
apps/bot/commands/ping.ts
··· 1 + import { logger } from "@tealfmbot/common/logger"; 1 2 import { CommandInteraction, SlashCommandBuilder } from "discord.js"; 2 - import { logger } from "@tealfmbot/common/logger.ts"; 3 3 4 4 export default { 5 - data: new SlashCommandBuilder().setName("ping").setDescription( 6 - "replies with pong", 7 - ), 5 + data: new SlashCommandBuilder().setName("ping").setDescription("replies with pong"), 8 6 async execute(interaction: CommandInteraction) { 9 7 await interaction.reply("pong lol"); 10 - logger.info("ping command sent") 8 + logger.info("ping command sent"); 11 9 }, 12 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 + };
+5 -5
apps/bot/commands/top.ts
··· 1 + import { logger } from "@tealfmbot/common/logger"; 1 2 import { CommandInteraction, SlashCommandBuilder } from "discord.js"; 2 - import { logger } from "@tealfmbot/common/logger.ts"; 3 3 4 4 export default { 5 - data: new SlashCommandBuilder().setName("top").setDescription( 6 - "Find the top listeners for the specified artist(s)", 7 - ), 5 + data: new SlashCommandBuilder() 6 + .setName("top") 7 + .setDescription("Find the top listeners for the specified artist(s)"), 8 8 async execute(interaction: CommandInteraction) { 9 9 await interaction.reply("placeholder"); 10 - logger.info("top command sent") 10 + logger.info("top command sent"); 11 11 }, 12 12 };
+10 -18
apps/bot/deploy-commands.ts
··· 1 + import { env } from "@tealfmbot/common/constants"; 1 2 import { REST, Routes } from "discord.js"; 2 3 import fs from "node:fs"; 3 4 import path from "node:path"; 4 - import { 5 - DISCORD_APPLICATION_ID, 6 - DISCORD_BOT_TOKEN, 7 - DISCORD_GUILD_ID, 8 - } from "@tealfmbot/common/constants.ts"; 9 5 10 6 const commands = []; 11 - const commandPaths = fs.globSync("commands/**/*.ts"); 7 + const commandPaths = fs.globSync("dist/commands/*.js"); 12 8 13 9 for await (const cmdPath of commandPaths) { 14 - const absoluteCommandPath = path.join(import.meta.dirname, cmdPath) 15 - const command = await import(absoluteCommandPath) 10 + const absoluteCommandPath = path.join(import.meta.dirname, cmdPath); 11 + const command = await import(absoluteCommandPath); 16 12 if ("data" in command.default && "execute" in command.default) { 17 13 commands.push(command.default.data); 18 14 } else { ··· 22 18 } 23 19 } 24 20 25 - const rest = new REST().setToken(DISCORD_BOT_TOKEN); 21 + const rest = new REST().setToken(env.DISCORD_BOT_TOKEN); 26 22 27 23 (async () => { 28 24 try { 29 - console.log( 30 - `Started refreshing ${commands.length} application (/) commands.`, 31 - ); 25 + console.log(`Started refreshing ${commands.length} application (/) commands.`); 32 26 33 - const data = await rest.put( 34 - Routes.applicationGuildCommands(DISCORD_APPLICATION_ID, DISCORD_GUILD_ID), 27 + const data = (await rest.put( 28 + Routes.applicationGuildCommands(env.DISCORD_APPLICATION_ID, env.DISCORD_GUILD_ID), 35 29 { body: commands }, 36 - ) as unknown[]; 30 + )) as unknown[]; 37 31 38 - console.log( 39 - `Successfully reloaded ${data.length} application (/) commands.`, 40 - ); 32 + console.log(`Successfully reloaded ${data.length} application (/) commands.`); 41 33 } catch (error) { 42 34 console.error(error); 43 35 }
+1 -1
apps/bot/discord.d.ts
··· 2 2 3 3 declare module "discord.js" { 4 4 export interface Client { 5 - commands: Collection<unknown, any> 5 + commands: Collection<unknown, any>; 6 6 } 7 7 }
+5 -11
apps/bot/main.ts
··· 1 - import { 2 - Client, 3 - Collection, 4 - Events, 5 - GatewayIntentBits, 6 - MessageFlags, 7 - } from "discord.js"; 1 + import { env } from "@tealfmbot/common/constants"; 2 + import { logger } from "@tealfmbot/common/logger"; 3 + import { Client, Collection, Events, GatewayIntentBits, MessageFlags } from "discord.js"; 8 4 import fs from "node:fs"; 9 5 import path from "node:path"; 10 - import { DISCORD_BOT_TOKEN } from "@tealfmbot/common/constants.ts"; 11 - import { logger } from "@tealfmbot/common/logger.ts"; 12 6 13 7 const client = new Client({ intents: [GatewayIntentBits.Guilds] }); 14 8 ··· 16 10 console.log(`teal.fm bot ready and logged in as ${readyClient.user.tag}`); 17 11 }); 18 12 19 - client.login(DISCORD_BOT_TOKEN); 13 + client.login(env.DISCORD_BOT_TOKEN); 20 14 21 15 client.on(Events.InteractionCreate, async (interaction) => { 22 16 if (!interaction.isChatInputCommand()) return; ··· 45 39 46 40 client.commands = new Collection(); 47 41 48 - const commandPaths = fs.globSync("commands/*.ts"); 42 + const commandPaths = fs.globSync("dist/commands/*.js"); 49 43 for await (const file of commandPaths) { 50 44 const absoluteCommandPath = path.join(import.meta.dirname, file); 51 45 const command = await import(absoluteCommandPath);
+6 -3
apps/bot/package.json
··· 1 1 { 2 2 "name": "bot", 3 3 "version": "0.0.1", 4 - "type": "module", 5 4 "private": true, 5 + "type": "module", 6 6 "scripts": { 7 - "dev": "tsx main.ts", 7 + "dev": "NODE_ENV=development tsx --watch main.ts", 8 8 "deploy-commands": "tsx deploy-commands.ts", 9 9 "build": "tsc", 10 + "watch": "tsc --watch", 11 + "start": "node dist/main.js", 10 12 "typecheck": "tsc --noEmit" 11 13 }, 12 14 "dependencies": { 13 15 "@tealfmbot/common": "workspace:*", 14 - "@tealfmbot/tsconfig": "workspace:*", 16 + "@tealfmbot/database": "workspace:*", 15 17 "discord.js": "^14.25.1" 16 18 }, 17 19 "devDependencies": { 20 + "@tealfmbot/tsconfig": "workspace:*", 18 21 "@types/node": "^25.0.3", 19 22 "tsx": "^4.21.0", 20 23 "typescript": "^5.9.3"
+2 -4
apps/bot/tsconfig.json
··· 1 1 { 2 2 "extends": "@tealfmbot/tsconfig/tsconfig.node.json", 3 3 "compilerOptions": { 4 - "outDir": "./dist", 4 + "outDir": "./dist" 5 5 }, 6 - "exclude": [ 7 - "node_modules" 8 - ] 6 + "exclude": ["node_modules"] 9 7 }
+23 -12
apps/tapper/index.ts
··· 1 1 import { SimpleIndexer, Tap } from "@atproto/tap"; 2 - import { TAP_ADMIN_PASSWORD } from "@tealfmbot/common/constants.ts"; 3 - // import { db } from "./kysely/db.ts" 2 + import { env } from "@tealfmbot/common/constants"; 3 + import { db } from "@tealfmbot/database/db"; 4 + 5 + import { isTealRecord } from "./utils"; 4 6 5 7 const tap = new Tap("https://tap.xero.systems", { 6 - adminPassword: TAP_ADMIN_PASSWORD, 8 + adminPassword: env.TAP_ADMIN_PASSWORD, 7 9 }); 8 10 9 11 const indexer = new SimpleIndexer(); 10 12 11 13 indexer.record(async (evt, opts) => { 12 14 const uri = `at://${evt.did}/${evt.collection}/${evt.rkey}`; 13 - if (evt.action === "create" || evt.action === "update") { 14 - // await db.insertInto("plays").values({ 15 - // played_time: evt?.record?.playedTime, 16 - // release_name: evt?.record?.releaseName, 17 - // track_name: evt?.record?.trackName, 18 - // user_id: 4 19 - // }).execute() 20 - console.log(evt.record) 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); 21 33 } else { 22 34 console.log(`deleted: ${uri}`); 23 35 } 24 - 25 36 26 37 if (process.env.NODE_ENV === "development") { 27 38 // we don't want to ack in development
+4 -3
apps/tapper/package.json
··· 1 1 { 2 2 "name": "tapper", 3 3 "version": "0.0.1", 4 - "type": "module", 5 4 "private": true, 5 + "type": "module", 6 6 "scripts": { 7 7 "dev": "NODE_ENV=development tsx index.ts", 8 - "start": "NODE_ENV=production tsx index.ts", 8 + "start": "NODE_ENV=production node dist/index.js", 9 9 "typecheck": "tsc --noEmit" 10 10 }, 11 11 "dependencies": { 12 12 "@atproto/tap": "^0.0.2", 13 13 "@tealfmbot/common": "workspace:*", 14 - "@tealfmbot/tsconfig": "workspace:*" 14 + "@tealfmbot/database": "workspace:*" 15 15 }, 16 16 "devDependencies": { 17 + "@tealfmbot/tsconfig": "workspace:*", 17 18 "@types/node": "^25.0.3", 18 19 "tsx": "^4.21.0", 19 20 "typescript": "^5.9.3"
+1 -3
apps/tapper/tsconfig.json
··· 3 3 "compilerOptions": { 4 4 "outDir": "./dist" 5 5 }, 6 - "exclude": [ 7 - "node_modules" 8 - ] 6 + "exclude": ["node_modules"] 9 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
+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:
-8
docker-compose.yml
··· 1 - services: 2 - db: 3 - image: postgres:18.1 4 - restart: always 5 - shm_size: 128mb 6 - env_file: .env 7 - ports: 8 - - 5432:5432
+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"
+24 -11
package.json
··· 3 3 "version": "0.0.1", 4 4 "private": true, 5 5 "description": "A discord bot for teal.fm", 6 - "scripts": { 7 - "bot": "pnpm --filter bot dev", 8 - "tap": "pnpm --filter tapper dev", 9 - "dev": "pnpm --filter './apps/**' dev", 10 - "typecheck": "pnpm --filter './{packages,apps}/**' typecheck" 11 - }, 12 6 "keywords": [ 13 - "teal.fm", 14 7 "atprotocol", 15 - "music" 8 + "music", 9 + "teal.fm" 16 10 ], 11 + "license": "MIT", 17 12 "author": "Dane Miller <me@dane.computer>", 18 - "license": "MIT", 19 - "packageManager": "pnpm@10.15.0", 20 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" 28 + }, 21 29 "devDependencies": { 30 + "lefthook": "^2.0.13", 31 + "npm-run-all": "^4.1.5", 32 + "oxfmt": "^0.20.0", 33 + "oxlint": "^1.35.0", 22 34 "typescript": "^5.9.3" 23 - } 35 + }, 36 + "packageManager": "pnpm@10.15.0" 24 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=
+17 -8
packages/common/constants.ts
··· 1 - import { loadEnvFile } from "node:process" 2 - import path from "node:path" 1 + import { cleanEnv, str, num } from "envalid"; 2 + import path from "node:path"; 3 + import { loadEnvFile } from "node:process"; 3 4 4 - loadEnvFile(path.join(import.meta.dirname, "../../.env")) 5 + if (process.env.NODE_ENV !== "production") { 6 + loadEnvFile(path.join(import.meta.dirname, "../../.env")); 7 + } 5 8 6 - export const DISCORD_BOT_TOKEN = process.env.DISCORD_BOT_TOKEN as string; 7 - export const DISCORD_APPLICATION_ID = process.env.DISCORD_APPLICATION_ID as string; 8 - export const DISCORD_GUILD_ID = process.env.DISCORD_GUILD_ID as string; 9 - export const TAP_ADMIN_PASSWORD = process.env.TAP_ADMIN_PASSWORD as string; 10 - export const DATABASE_URL = process.env.DATABASE_URL as string; 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";
+12 -9
packages/common/logger.ts
··· 1 - import pino from "pino" 1 + import pino from "pino"; 2 2 3 - export const logger = pino({ 4 - transport: { 5 - target: "pino-pretty", 6 - options: { 7 - colorize: true 8 - } 9 - } 10 - }) 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 + });
+16 -7
packages/common/package.json
··· 1 1 { 2 2 "name": "@tealfmbot/common", 3 3 "version": "0.0.0", 4 + "private": true, 4 5 "type": "module", 5 - "private": true, 6 + "imports": { 7 + "#*": "./dist/*" 8 + }, 6 9 "exports": { 7 - "./*": "./*" 10 + "./*": { 11 + "types": "./*.ts", 12 + "default": "./dist/*.js" 13 + } 8 14 }, 9 15 "scripts": { 16 + "watch": "tsc --watch", 17 + "build": "tsc", 10 18 "typecheck": "tsc --noEmit" 11 19 }, 20 + "dependencies": { 21 + "envalid": "^8.1.1", 22 + "pino": "^10.1.0" 23 + }, 12 24 "devDependencies": { 13 25 "@tealfmbot/tsconfig": "workspace:*", 14 26 "@types/node": "^22.15.3", 15 - "typescript": "5.9.2", 16 - "pino-pretty": "^13.1.3" 17 - }, 18 - "dependencies": { 19 - "pino": "^10.1.0" 27 + "pino-pretty": "^13.1.3", 28 + "typescript": "5.9.2" 20 29 } 21 30 }
+8
packages/common/tsconfig.json
··· 1 1 { 2 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 + } 3 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 + }
+10 -9
packages/database/db.ts
··· 1 - import type { DB } from "kysely-codegen" 2 - import { Pool } from "pg" 3 - import { Kysely, PostgresDialect } from "kysely" 4 - import { DATABASE_URL } from "@tealfmbot/common/constants.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"; 5 6 6 7 const dialect = new PostgresDialect({ 7 8 pool: new Pool({ 8 - connectionString: DATABASE_URL 9 - }) 10 - }) 9 + connectionString: env.DATABASE_URL, 10 + }), 11 + }); 11 12 12 13 export const db = new Kysely<DB>({ 13 - dialect 14 - }) 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 + }
-34
packages/database/migrations/schema.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").ifNotExists() 6 - .addColumn("id", "serial", (col) => col.primaryKey()) 7 - .addColumn("did", "varchar", (col) => col.notNull().unique()) 8 - .addColumn('created_at', 'timestamp', (col) => 9 - col.defaultTo(sql`now()`).notNull(), 10 - ) 11 - .execute() 12 - 13 - await db.schema 14 - .createTable("plays").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) => col.references("users.id").onDelete("cascade").notNull()) 21 - .execute() 22 - 23 - await db.schema 24 - .createTable("artists").ifNotExists() 25 - .addColumn("artist_name", "varchar", (col) => col.notNull()) 26 - .addColumn("play_id", "integer", (col) => col.references("plays.id").onDelete("cascade").notNull()) 27 - .execute() 28 - } 29 - 30 - export async function down(db: Kysely<any>): Promise<void> { 31 - await db.schema.dropTable("users").execute() 32 - await db.schema.dropTable("plays").execute() 33 - await db.schema.dropTable("artists").execute() 34 - }
-46
packages/database/migrator.ts
··· 1 - import path from "node:path" 2 - import { Pool } from "pg" 3 - import fs from "node:fs/promises" 4 - import type { DB } from "kysely-codegen" 5 - import { Kysely, Migrator, PostgresDialect, FileMigrationProvider } from "kysely" 6 - import { DATABASE_URL } from "@tealfmbot/common/constants.ts" 7 - 8 - async function migrateToLatest() { 9 - const db = new Kysely<DB>({ 10 - dialect: new PostgresDialect({ 11 - pool: new Pool({ 12 - connectionString: DATABASE_URL 13 - }) 14 - }) 15 - }) 16 - 17 - const migrator = new Migrator({ 18 - db, 19 - provider: new FileMigrationProvider({ 20 - fs, 21 - path, 22 - migrationFolder: path.join(import.meta.dirname, "../migrations") 23 - }) 24 - }) 25 - 26 - 27 - const { error, results } = await migrator.migrateToLatest() 28 - 29 - results?.forEach(result => { 30 - if (result.status === "Success") { 31 - console.log(`migration ${result.migrationName} was executed successfully`) 32 - } else if (result.status === "Error") { 33 - console.error(`failed to execute migration: "${result.migrationName}" `) 34 - } 35 - }) 36 - 37 - if (error) { 38 - console.error("failed to migrate") 39 - console.error(error) 40 - process.exit(1) 41 - } 42 - 43 - await db.destroy() 44 - } 45 - 46 - migrateToLatest().catch(err => console.error(err))
+21 -10
packages/database/package.json
··· 1 1 { 2 2 "name": "@tealfmbot/database", 3 3 "version": "0.0.0", 4 - "type": "module", 5 4 "private": true, 5 + "type": "module", 6 + "types": "./database.d.ts", 7 + "imports": { 8 + "#*": "./dist/*" 9 + }, 6 10 "exports": { 7 - "./db.ts": "./db.ts" 11 + "./*": { 12 + "types": "./*.ts", 13 + "default": "./dist/*.js" 14 + } 8 15 }, 9 16 "scripts": { 10 - "migrate": "tsx migrator.ts", 11 - "codegen": "kysely-codegen --dialect postgres --env-file='../../.env'", 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", 12 21 "seed": "tsx seed.ts", 13 22 "typecheck": "tsc --noEmit" 14 23 }, 24 + "dependencies": { 25 + "@tealfmbot/common": "workspace:*", 26 + "@tealfmbot/tsconfig": "workspace:*", 27 + "kysely": "^0.28.9", 28 + "pg": "^8.16.3" 29 + }, 15 30 "devDependencies": { 16 31 "@types/node": "^22.15.3", 17 32 "@types/pg": "^8.16.0", 18 33 "kysely-codegen": "^0.19.0", 34 + "kysely-ctl": "^0.19.0", 35 + "kysely-migration-cli": "^0.4.2", 19 36 "tsx": "^4.21.0", 20 37 "typescript": "5.9.2" 21 - }, 22 - "dependencies": { 23 - "@tealfmbot/common": "workspace:*", 24 - "@tealfmbot/tsconfig": "workspace:*", 25 - "kysely": "^0.28.9", 26 - "pg": "^8.16.3" 27 38 } 28 39 }
+1 -2
packages/database/seed.ts
··· 6 6 // }).returning(['did', 'created_at']) 7 7 // .executeTakeFirst() 8 8 // console.log({ result }) 9 - 10 9 // const users = await db.selectFrom("users").select(["id", "did"]).execute() 11 10 // console.log({ users }) 12 11 // await db.deleteFrom("users").where("did", "=", "did:plc:qttsv4e7pu2jl3ilanfgc3zn").execute() ··· 14 13 // console.log({ plays }) 15 14 } 16 15 17 - main().catch(error => console.error(error)) 16 + main().catch((error) => console.error(error));
+8 -3
packages/database/tsconfig.json
··· 1 1 { 2 2 "extends": "@tealfmbot/tsconfig/tsconfig.node.json", 3 - "exclude": [ 4 - "node_modules" 5 - ] 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"] 6 11 }
+4 -4
packages/database/types.ts
··· 1 - import type { Artists, Plays } from "kysely-codegen"; 1 + import type { Kysely } from "kysely"; 2 2 3 - export interface TealFMPlay extends Plays { 4 - artists: Artists 5 - } 3 + import type { DB } from "./database.js"; 4 + 5 + export type Database = Kysely<DB>;
+2 -2
packages/tsconfig/tsconfig.base.json
··· 9 9 "strict": true, 10 10 "verbatimModuleSyntax": true, 11 11 "isolatedModules": true, 12 - "allowImportingTsExtensions": true, 12 + "emitDeclarationOnly": false, 13 13 "noUncheckedSideEffectImports": true, 14 14 "moduleDetection": "force", 15 - "skipLibCheck": true, 15 + "skipLibCheck": true 16 16 } 17 17 }
+4 -6
packages/tsconfig/tsconfig.node.json
··· 1 1 { 2 2 "extends": "./tsconfig.base.json", 3 3 "compilerOptions": { 4 - "lib": [ 5 - "esnext" 6 - ], 7 - "types": [ 8 - "node" 9 - ], 4 + "module": "ESNext", 5 + "moduleResolution": "bundler", 6 + "lib": ["esnext"], 7 + "types": ["node"] 10 8 } 11 9 }
+1936 -3
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 .: 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 11 24 typescript: 12 25 specifier: ^5.9.3 13 26 version: 5.9.3 ··· 17 30 '@tealfmbot/common': 18 31 specifier: workspace:* 19 32 version: link:../../packages/common 20 - '@tealfmbot/tsconfig': 33 + '@tealfmbot/database': 21 34 specifier: workspace:* 22 - version: link:../../packages/tsconfig 35 + version: link:../../packages/database 23 36 discord.js: 24 37 specifier: ^14.25.1 25 38 version: 14.25.1 26 39 devDependencies: 40 + '@tealfmbot/tsconfig': 41 + specifier: workspace:* 42 + version: link:../../packages/tsconfig 27 43 '@types/node': 28 44 specifier: ^25.0.3 29 45 version: 25.0.3 ··· 42 58 '@tealfmbot/common': 43 59 specifier: workspace:* 44 60 version: link:../../packages/common 61 + '@tealfmbot/database': 62 + specifier: workspace:* 63 + version: link:../../packages/database 64 + devDependencies: 45 65 '@tealfmbot/tsconfig': 46 66 specifier: workspace:* 47 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 48 107 devDependencies: 108 + '@tealfmbot/tsconfig': 109 + specifier: workspace:* 110 + version: link:../../packages/tsconfig 49 111 '@types/node': 50 112 specifier: ^25.0.3 51 113 version: 25.0.3 ··· 58 120 59 121 packages/common: 60 122 dependencies: 123 + envalid: 124 + specifier: ^8.1.1 125 + version: 8.1.1 61 126 pino: 62 127 specifier: ^10.1.0 63 128 version: 10.1.0 ··· 99 164 kysely-codegen: 100 165 specifier: ^0.19.0 101 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 102 173 tsx: 103 174 specifier: ^4.21.0 104 175 version: 4.21.0 ··· 110 181 111 182 packages: 112 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 + 113 216 '@atproto/common-web@0.4.7': 114 217 resolution: {integrity: sha512-vjw2+81KPo2/SAbbARGn64Ln+6JTI0FTI4xk8if0ebBfDxFRmHb2oSN1y77hzNq/ybGHqA2mecfhS03pxC5+lg==} 115 218 ··· 117 220 resolution: {integrity: sha512-jMC9ikl8QbJcnh21upe9Gb9mIaSJWsdp8sgaelmntUtChWnxxvCC/pI3TBX11PT7XlHUE6UyuvY+S3hh6WZVEg==} 118 221 engines: {node: '>=18.7.0'} 119 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==} 234 + 120 235 '@atproto/lex-cbor@0.0.3': 121 236 resolution: {integrity: sha512-N8lCV3kK5ZcjSOWxKLWqzlnaSpK4isjXRZ0EqApl/5y9KB64s78hQ/U3KIE5qnPRlBbW5kSH3YACoU27u9nTOA==} 122 237 ··· 126 241 '@atproto/lex-json@0.0.3': 127 242 resolution: {integrity: sha512-ZVcY7XlRfdPYvQQ2WroKUepee0+NCovrSXgXURM3Xv+n5jflJCoczguROeRr8sN0xvT0ZbzMrDNHCUYKNnxcjw==} 128 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 + 129 257 '@atproto/syntax@0.4.2': 130 258 resolution: {integrity: sha512-X9XSRPinBy/0VQ677j8VXlBsYSsUXaiqxWVpGGxJYsAhugdQRb0jqaVKJFtm6RskeNkV6y9xclSUi9UYG/COrA==} 131 259 ··· 137 265 resolution: {integrity: sha512-dox1XIymuC7/ZRhUqKezIGgooZS45C6vHCfu0PnWjfvsLCK2kAlnvX4IBkA/WpcoijDhQ9ejChnFbo/sLmgvAg==} 138 266 engines: {node: '>=18.7.0'} 139 267 268 + '@atproto/xrpc@0.7.7': 269 + resolution: {integrity: sha512-K1ZyO/BU8JNtXX5dmPp7b5UrkLMMqpsIa/Lrj5D3Su+j1Xwq1m6QJ2XJ1AgjEjkI1v4Muzm7klianLE6XGxtmA==} 270 + 140 271 '@babel/code-frame@7.27.1': 141 272 resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} 142 273 engines: {node: '>=6.9.0'} ··· 144 275 '@babel/helper-validator-identifier@7.28.5': 145 276 resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} 146 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 147 283 148 284 '@discordjs/builders@1.13.1': 149 285 resolution: {integrity: sha512-cOU0UDHc3lp/5nKByDxkmRiNZBpdp0kx55aarbiAfakfKJHlxv/yFW1zmIqCAmwH5CRlrH9iMFKJMpvW4DPB+w==} ··· 329 465 cpu: [x64] 330 466 os: [win32] 331 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 + 332 554 '@pinojs/redact@0.4.0': 333 555 resolution: {integrity: sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg==} 334 556 ··· 375 597 argparse@2.0.1: 376 598 resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} 377 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 + 378 612 atomic-sleep@1.0.0: 379 613 resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} 380 614 engines: {node: '>=8.0.0'} 381 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 + 382 623 balanced-match@1.0.2: 383 624 resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} 384 625 ··· 395 636 buffer@6.0.3: 396 637 resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} 397 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 + 398 659 callsites@3.1.0: 399 660 resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} 400 661 engines: {node: '>=6'} ··· 407 668 resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} 408 669 engines: {node: '>=10'} 409 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 + 410 678 color-convert@1.9.3: 411 679 resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} 412 680 ··· 423 691 colorette@2.0.20: 424 692 resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} 425 693 694 + commander@11.1.0: 695 + resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} 696 + engines: {node: '>=16'} 697 + 426 698 concat-map@0.0.1: 427 699 resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} 428 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 + 429 711 cosmiconfig@9.0.0: 430 712 resolution: {integrity: sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==} 431 713 engines: {node: '>=14'} ··· 435 717 typescript: 436 718 optional: true 437 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 + 438 736 dateformat@4.6.3: 439 737 resolution: {integrity: sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==} 440 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 + 441 753 diff@3.5.0: 442 754 resolution: {integrity: sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==} 443 755 engines: {node: '>=0.3.1'} ··· 461 773 resolution: {integrity: sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==} 462 774 engines: {node: '>=12'} 463 775 776 + dunder-proto@1.0.1: 777 + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} 778 + engines: {node: '>= 0.4'} 779 + 464 780 end-of-stream@1.4.5: 465 781 resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} 466 782 ··· 468 784 resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} 469 785 engines: {node: '>=6'} 470 786 787 + envalid@8.1.1: 788 + resolution: {integrity: sha512-vOUfHxAFFvkBjbVQbBfgnCO9d3GcNfMMTtVfgqSU2rQGMFEVqWy9GBuoSfHnwGu7EqR0/GeukQcL3KjFBaga9w==} 789 + engines: {node: '>=18'} 790 + 471 791 error-ex@1.3.4: 472 792 resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==} 473 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 + 474 818 esbuild@0.27.2: 475 819 resolution: {integrity: sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==} 476 820 engines: {node: '>=18'} ··· 488 832 resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} 489 833 engines: {node: '>=0.8.x'} 490 834 835 + exsolve@1.0.8: 836 + resolution: {integrity: sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==} 837 + 491 838 fast-copy@4.0.2: 492 839 resolution: {integrity: sha512-ybA6PDXIXOXivLJK/z9e+Otk7ve13I4ckBvGO5I2RRmBU1gMHLVDJYEuJYhGwez7YNlYji2M2DvVU+a9mSFDlw==} 493 840 ··· 505 852 resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} 506 853 engines: {node: '>=8'} 507 854 855 + for-each@0.3.5: 856 + resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} 857 + engines: {node: '>= 0.4'} 858 + 508 859 fs.realpath@1.0.0: 509 860 resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} 510 861 ··· 516 867 function-bind@1.1.2: 517 868 resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} 518 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 + 519 897 get-tsconfig@4.13.0: 520 898 resolution: {integrity: sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==} 521 899 900 + giget@2.0.0: 901 + resolution: {integrity: sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA==} 902 + hasBin: true 903 + 522 904 git-diff@2.0.6: 523 905 resolution: {integrity: sha512-/Iu4prUrydE3Pb3lCBMbcSNIf81tgGt0W1ZwknnyF62t3tHmtiJTRj0f+1ZIhp3+Rh0ktz1pJVoa7ZXUCskivA==} 524 906 engines: {node: '>= 4.8.0'} ··· 527 909 resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} 528 910 deprecated: Glob versions prior to v9 are no longer supported 529 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 + 530 927 has-flag@3.0.0: 531 928 resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} 532 929 engines: {node: '>=4'} ··· 535 932 resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} 536 933 engines: {node: '>=8'} 537 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 + 538 950 hasown@2.0.2: 539 951 resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} 540 952 engines: {node: '>= 0.4'} ··· 542 954 help-me@5.0.0: 543 955 resolution: {integrity: sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==} 544 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 + 545 964 ieee754@1.2.1: 546 965 resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} 547 966 ··· 556 975 inherits@2.0.4: 557 976 resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} 558 977 978 + internal-slot@1.1.0: 979 + resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} 980 + engines: {node: '>= 0.4'} 981 + 559 982 interpret@1.4.0: 560 983 resolution: {integrity: sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==} 561 984 engines: {node: '>= 0.10'} 562 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 + 563 994 is-arrayish@0.2.1: 564 995 resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} 565 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 + 566 1013 is-core-module@2.16.1: 567 1014 resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} 568 1015 engines: {node: '>= 0.4'} 569 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 + 570 1045 is-number@7.0.0: 571 1046 resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} 572 1047 engines: {node: '>=0.12.0'} 573 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 + 574 1091 iso-datestring-validator@2.2.2: 575 1092 resolution: {integrity: sha512-yLEMkBbLZTlVQqOnQ4FiMujR6T4DEcCb1xizmvXS+OxuhwcbtynoosRzdMA69zZCShCNAbi+gJ71FxZBBXx1SA==} 576 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 + 577 1101 joycon@3.1.1: 578 1102 resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} 579 1103 engines: {node: '>=10'} ··· 584 1108 js-yaml@4.1.1: 585 1109 resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} 586 1110 hasBin: true 1111 + 1112 + json-parse-better-errors@1.0.2: 1113 + resolution: {integrity: sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==} 587 1114 588 1115 json-parse-even-better-errors@2.3.1: 589 1116 resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} ··· 623 1150 tedious: 624 1151 optional: true 625 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 + 626 1174 kysely@0.28.9: 627 1175 resolution: {integrity: sha512-3BeXMoiOhpOwu62CiVpO6lxfq4eS6KMYfQdMsN/2kUCRNuF2YiEr7u0HLHaQU+O4Xu8YXE3bHVkwaQ85i72EuA==} 628 1176 engines: {node: '>=20.0.0'} 629 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 + 630 1232 lines-and-columns@1.2.4: 631 1233 resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} 632 1234 1235 + load-json-file@4.0.0: 1236 + resolution: {integrity: sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==} 1237 + engines: {node: '>=4'} 1238 + 633 1239 lodash.snakecase@4.1.1: 634 1240 resolution: {integrity: sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==} 635 1241 ··· 640 1246 resolution: {integrity: sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==} 641 1247 engines: {node: '>= 0.6.0'} 642 1248 1249 + lru-cache@10.4.3: 1250 + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} 1251 + 643 1252 magic-bytes.js@1.12.1: 644 1253 resolution: {integrity: sha512-ThQLOhN86ZkJ7qemtVRGYM+gRgR8GEXNli9H/PMvpnZsE44Xfh3wx9kGJaldg314v85m+bFW6WBMaVHJc/c3zA==} 645 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 + 646 1263 micromatch@4.0.8: 647 1264 resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} 648 1265 engines: {node: '>=8.6'} ··· 656 1273 multiformats@9.9.0: 657 1274 resolution: {integrity: sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==} 658 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 + 659 1313 on-exit-leak-free@2.1.2: 660 1314 resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==} 661 1315 engines: {node: '>=14.0.0'} ··· 663 1317 once@1.4.0: 664 1318 resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} 665 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 + 666 1339 parent-module@1.0.1: 667 1340 resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} 668 1341 engines: {node: '>=6'} 669 1342 1343 + parse-json@4.0.0: 1344 + resolution: {integrity: sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==} 1345 + engines: {node: '>=4'} 1346 + 670 1347 parse-json@5.2.0: 671 1348 resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} 672 1349 engines: {node: '>=8'} ··· 675 1352 resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} 676 1353 engines: {node: '>=0.10.0'} 677 1354 1355 + path-key@2.0.1: 1356 + resolution: {integrity: sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==} 1357 + engines: {node: '>=4'} 1358 + 678 1359 path-parse@1.0.7: 679 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==} 680 1371 681 1372 pg-cloudflare@1.2.7: 682 1373 resolution: {integrity: sha512-YgCtzMH0ptvZJslLM1ffsY4EuGaU0cx4XSdXLRFae8bPP4dS5xL1tNB3k2o/N64cHJpwU7dxKli/nZ2lUa5fLg==} ··· 719 1410 resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} 720 1411 engines: {node: '>=8.6'} 721 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 + 722 1422 pino-abstract-transport@1.2.0: 723 1423 resolution: {integrity: sha512-Guhh8EZfPCfH+PMXAb6rKOjGQEoy0xlAIn+irODG5kgfYV+BQ0rGYYWTIel3P5mmyXqkYkPmdIkywsn6QKUR1Q==} 724 1424 ··· 728 1428 pino-abstract-transport@3.0.0: 729 1429 resolution: {integrity: sha512-wlfUczU+n7Hy/Ha5j9a/gZNy7We5+cXp8YL+X+PG8S0KXxw7n/JXA3c46Y0zQznIJ83URJiwy7Lh56WLokNuxg==} 730 1430 1431 + pino-http@11.0.0: 1432 + resolution: {integrity: sha512-wqg5XIAGRRIWtTk8qPGxkbrfiwEWz1lgedVLvhLALudKXvg1/L2lTFgTGPJ4Z2e3qcRmxoFxDuSdMdMGNM6I1g==} 1433 + 731 1434 pino-pretty@13.1.3: 732 1435 resolution: {integrity: sha512-ttXRkkOz6WWC95KeY9+xxWL6AtImwbyMHrL1mSwqwW9u+vLp/WIElvHvCSDg0xO/Dzrggz1zv3rN5ovTRVowKg==} 733 1436 hasBin: true ··· 746 1449 resolution: {integrity: sha512-ip4qdzjkAyDDZklUaZkcRFb2iA118H9SgRh8yzTkSQK8HilsOJF7rSY8HoW5+I0M46AZgX/pxbprf2vvzQCE0Q==} 747 1450 hasBin: true 748 1451 1452 + pkg-types@2.3.0: 1453 + resolution: {integrity: sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==} 1454 + 749 1455 pluralize@8.0.0: 750 1456 resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} 751 1457 engines: {node: '>=4'} 752 1458 1459 + possible-typed-array-names@1.1.0: 1460 + resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} 1461 + engines: {node: '>= 0.4'} 1462 + 753 1463 postgres-array@2.0.0: 754 1464 resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==} 755 1465 engines: {node: '>=4'} ··· 782 1492 quick-format-unescaped@4.0.4: 783 1493 resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} 784 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 + 785 1502 readable-stream@4.7.0: 786 1503 resolution: {integrity: sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==} 787 1504 engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} 788 1505 1506 + readdirp@5.0.0: 1507 + resolution: {integrity: sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==} 1508 + engines: {node: '>= 20.19.0'} 1509 + 789 1510 real-require@0.2.0: 790 1511 resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==} 791 1512 engines: {node: '>= 12.13.0'} ··· 794 1515 resolution: {integrity: sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==} 795 1516 engines: {node: '>= 0.10'} 796 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 + 797 1526 resolve-from@4.0.0: 798 1527 resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} 799 1528 engines: {node: '>=4'} ··· 806 1535 engines: {node: '>= 0.4'} 807 1536 hasBin: true 808 1537 1538 + safe-array-concat@1.1.3: 1539 + resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==} 1540 + engines: {node: '>=0.4'} 1541 + 809 1542 safe-buffer@5.2.1: 810 1543 resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} 811 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 + 812 1553 safe-stable-stringify@2.5.0: 813 1554 resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==} 814 1555 engines: {node: '>=10'} ··· 816 1557 secure-json-parse@4.1.0: 817 1558 resolution: {integrity: sha512-l4KnYfEyqYJxDwlNVyRfO2E4NTHfMKAWdUuA8J0yve2Dz/E/PdBepY03RvyJpssIpRFwJoCD55wA+mEDs6ByWA==} 818 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 + 819 1588 shelljs.exec@1.1.8: 820 1589 resolution: {integrity: sha512-vFILCw+lzUtiwBAHV8/Ex8JsFjelFMdhONIsgKNLgTzeRckp2AOYRQtHJE/9LhNvdMmE27AGtzWx0+DHpwIwSw==} 821 1590 engines: {node: '>= 4.0.0'} ··· 824 1593 resolution: {integrity: sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==} 825 1594 engines: {node: '>=4'} 826 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'} 827 1612 828 1613 sonic-boom@3.8.1: 829 1614 resolution: {integrity: sha512-y4Z8LCDBuum+PBP3lSV7RHrXscqksve/bi0as7mhwVnBW+/wUqKT/2Kb7um8yqcFy0duYbbPxzt89Zy2nOCaxg==} ··· 831 1616 sonic-boom@4.2.0: 832 1617 resolution: {integrity: sha512-INb7TM37/mAcsGmc9hyyI6+QR3rR1zVRu36B0NeGXKnOOLiZOfER5SA+N7X7k3yUYRzLWafduTDvJAfDswwEww==} 833 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 + 834 1631 split2@4.2.0: 835 1632 resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} 836 1633 engines: {node: '>= 10.x'} 837 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 + 838 1658 string_decoder@1.3.0: 839 1659 resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} 1660 + 1661 + strip-bom@3.0.0: 1662 + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} 1663 + engines: {node: '>=4'} 840 1664 841 1665 strip-json-comments@5.0.3: 842 1666 resolution: {integrity: sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw==} ··· 860 1684 thread-stream@3.1.0: 861 1685 resolution: {integrity: sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==} 862 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 + 863 1699 to-regex-range@5.0.1: 864 1700 resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} 865 1701 engines: {node: '>=8.0'} ··· 867 1703 ts-mixer@6.0.4: 868 1704 resolution: {integrity: sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA==} 869 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 + 870 1716 tslib@2.8.1: 871 1717 resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} 872 1718 ··· 875 1721 engines: {node: '>=18.0.0'} 876 1722 hasBin: true 877 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 + 878 1740 typescript@5.9.2: 879 1741 resolution: {integrity: sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==} 880 1742 engines: {node: '>=14.17'} ··· 885 1747 engines: {node: '>=14.17'} 886 1748 hasBin: true 887 1749 1750 + ufo@1.6.1: 1751 + resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==} 1752 + 888 1753 uint8arrays@3.0.0: 889 1754 resolution: {integrity: sha512-HRCx0q6O9Bfbp+HHSfQQKD7wU70+lydKVt4EghkdOvlK/NlrF90z+eXV34mUd48rNvVJXwkrMSPpCATkct8fJA==} 1755 + 1756 + unbox-primitive@1.1.0: 1757 + resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} 1758 + engines: {node: '>= 0.4'} 890 1759 891 1760 undici-types@6.21.0: 892 1761 resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} ··· 901 1770 unicode-segmenter@0.14.4: 902 1771 resolution: {integrity: sha512-pR5VCiCrLrKOL6FRW61jnk9+wyMtKKowq+jyFY9oc6uHbWKhDL4yVRiI4YZPksGMK72Pahh8m0cn/0JvbDDyJg==} 903 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 + 904 1796 wrappy@1.0.2: 905 1797 resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} 906 1798 ··· 928 1820 929 1821 snapshots: 930 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 + 931 1881 '@atproto/common-web@0.4.7': 932 1882 dependencies: 933 1883 '@atproto/lex-data': 0.0.3 ··· 943 1893 multiformats: 9.9.0 944 1894 pino: 8.21.0 945 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 1915 + 946 1916 '@atproto/lex-cbor@0.0.3': 947 1917 dependencies: 948 1918 '@atproto/lex-data': 0.0.3 ··· 962 1932 '@atproto/lex-data': 0.0.3 963 1933 tslib: 2.8.1 964 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 + 965 1977 '@atproto/syntax@0.4.2': {} 966 1978 967 1979 '@atproto/tap@0.0.2': ··· 983 1995 - bufferutil 984 1996 - utf-8-validate 985 1997 1998 + '@atproto/xrpc@0.7.7': 1999 + dependencies: 2000 + '@atproto/lexicon': 0.6.0 2001 + zod: 3.25.76 2002 + 986 2003 '@babel/code-frame@7.27.1': 987 2004 dependencies: 988 2005 '@babel/helper-validator-identifier': 7.28.5 ··· 990 2007 picocolors: 1.1.1 991 2008 992 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 993 2014 994 2015 '@discordjs/builders@1.13.1': 995 2016 dependencies: ··· 1118 2139 '@esbuild/win32-x64@0.27.2': 1119 2140 optional: true 1120 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 + 1121 2194 '@pinojs/redact@0.4.0': {} 1122 2195 1123 2196 '@sapphire/async-queue@1.5.5': {} ··· 1139 2212 1140 2213 '@types/pg@8.16.0': 1141 2214 dependencies: 1142 - '@types/node': 22.19.3 2215 + '@types/node': 25.0.3 1143 2216 pg-protocol: 1.10.3 1144 2217 pg-types: 2.2.0 1145 2218 ··· 1163 2236 1164 2237 argparse@2.0.1: {} 1165 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 + 1166 2256 atomic-sleep@1.0.0: {} 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: {} 1167 2263 1168 2264 balanced-match@1.0.2: {} 1169 2265 ··· 1183 2279 base64-js: 1.5.1 1184 2280 ieee754: 1.2.1 1185 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 + 1186 2314 callsites@3.1.0: {} 1187 2315 1188 2316 chalk@2.4.2: ··· 1196 2324 ansi-styles: 4.3.0 1197 2325 supports-color: 7.2.0 1198 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 + 1199 2335 color-convert@1.9.3: 1200 2336 dependencies: 1201 2337 color-name: 1.1.3 ··· 1210 2346 1211 2347 colorette@2.0.20: {} 1212 2348 2349 + commander@11.1.0: {} 2350 + 1213 2351 concat-map@0.0.1: {} 1214 2352 2353 + confbox@0.2.2: {} 2354 + 2355 + consola@3.4.2: {} 2356 + 2357 + core-js@3.47.0: {} 2358 + 1215 2359 cosmiconfig@9.0.0(typescript@5.9.2): 1216 2360 dependencies: 1217 2361 env-paths: 2.2.1 ··· 1221 2365 optionalDependencies: 1222 2366 typescript: 5.9.2 1223 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 + 1224 2394 dateformat@4.6.3: {} 1225 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 + 1226 2412 diff@3.5.0: {} 1227 2413 1228 2414 discord-api-types@0.38.37: {} ··· 1253 2439 dotenv@16.6.1: {} 1254 2440 1255 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 1256 2448 1257 2449 end-of-stream@1.4.5: 1258 2450 dependencies: ··· 1260 2452 1261 2453 env-paths@2.2.1: {} 1262 2454 2455 + envalid@8.1.1: 2456 + dependencies: 2457 + tslib: 2.8.1 2458 + 1263 2459 error-ex@1.3.4: 1264 2460 dependencies: 1265 2461 is-arrayish: 0.2.1 1266 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 + 1267 2541 esbuild@0.27.2: 1268 2542 optionalDependencies: 1269 2543 '@esbuild/aix-ppc64': 0.27.2 ··· 1299 2573 1300 2574 events@3.3.0: {} 1301 2575 2576 + exsolve@1.0.8: {} 2577 + 1302 2578 fast-copy@4.0.2: {} 1303 2579 1304 2580 fast-deep-equal@3.1.3: {} ··· 1311 2587 dependencies: 1312 2588 to-regex-range: 5.0.1 1313 2589 2590 + for-each@0.3.5: 2591 + dependencies: 2592 + is-callable: 1.2.7 2593 + 1314 2594 fs.realpath@1.0.0: {} 1315 2595 1316 2596 fsevents@2.3.3: ··· 1318 2598 1319 2599 function-bind@1.1.2: {} 1320 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 + 1321 2640 get-tsconfig@4.13.0: 1322 2641 dependencies: 1323 2642 resolve-pkg-maps: 1.0.0 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 1324 2652 1325 2653 git-diff@2.0.6: 1326 2654 dependencies: ··· 1339 2667 once: 1.4.0 1340 2668 path-is-absolute: 1.0.1 1341 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 + 1342 2681 has-flag@3.0.0: {} 1343 2682 1344 2683 has-flag@4.0.0: {} 1345 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 + 1346 2699 hasown@2.0.2: 1347 2700 dependencies: 1348 2701 function-bind: 1.1.2 1349 2702 1350 2703 help-me@5.0.0: {} 2704 + 2705 + hono@4.11.3: {} 2706 + 2707 + hosted-git-info@2.8.9: {} 1351 2708 1352 2709 ieee754@1.2.1: {} 1353 2710 ··· 1363 2720 1364 2721 inherits@2.0.4: {} 1365 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 + 1366 2729 interpret@1.4.0: {} 1367 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 + 1368 2739 is-arrayish@0.2.1: {} 1369 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 + 1370 2760 is-core-module@2.16.1: 1371 2761 dependencies: 1372 2762 hasown: 2.0.2 1373 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 + 1374 2796 is-number@7.0.0: {} 1375 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 + 1376 2841 iso-datestring-validator@2.2.2: {} 1377 2842 2843 + jiti@2.6.1: {} 2844 + 2845 + jose@5.10.0: {} 2846 + 1378 2847 joycon@3.1.1: {} 1379 2848 1380 2849 js-tokens@4.0.0: {} ··· 1382 2851 js-yaml@4.1.1: 1383 2852 dependencies: 1384 2853 argparse: 2.0.1 2854 + 2855 + json-parse-better-errors@1.0.2: {} 1385 2856 1386 2857 json-parse-even-better-errors@2.3.1: {} 1387 2858 ··· 1402 2873 transitivePeerDependencies: 1403 2874 - typescript 1404 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 + 1405 2899 kysely@0.28.9: {} 1406 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 + 1407 2944 lines-and-columns@1.2.4: {} 1408 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 + 1409 2953 lodash.snakecase@4.1.1: {} 1410 2954 1411 2955 lodash@4.17.21: {} 1412 2956 1413 2957 loglevel@1.9.2: {} 1414 2958 2959 + lru-cache@10.4.3: {} 2960 + 1415 2961 magic-bytes.js@1.12.1: {} 1416 2962 2963 + math-intrinsics@1.1.0: {} 2964 + 2965 + memorystream@0.3.1: {} 2966 + 1417 2967 micromatch@4.0.8: 1418 2968 dependencies: 1419 2969 braces: 3.0.3 ··· 1427 2977 1428 2978 multiformats@9.9.0: {} 1429 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 + 1430 3032 on-exit-leak-free@2.1.2: {} 1431 3033 1432 3034 once@1.4.0: 1433 3035 dependencies: 1434 3036 wrappy: 1.0.2 1435 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 + 1436 3068 parent-module@1.0.1: 1437 3069 dependencies: 1438 3070 callsites: 3.1.0 1439 3071 3072 + parse-json@4.0.0: 3073 + dependencies: 3074 + error-ex: 1.3.4 3075 + json-parse-better-errors: 1.0.2 3076 + 1440 3077 parse-json@5.2.0: 1441 3078 dependencies: 1442 3079 '@babel/code-frame': 7.27.1 ··· 1445 3082 lines-and-columns: 1.2.4 1446 3083 1447 3084 path-is-absolute@1.0.1: {} 3085 + 3086 + path-key@2.0.1: {} 1448 3087 1449 3088 path-parse@1.0.7: {} 1450 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 + 1451 3098 pg-cloudflare@1.2.7: 1452 3099 optional: true 1453 3100 ··· 1487 3134 1488 3135 picomatch@2.3.1: {} 1489 3136 3137 + pidtree@0.3.1: {} 3138 + 3139 + pify@3.0.0: {} 3140 + 1490 3141 pino-abstract-transport@1.2.0: 1491 3142 dependencies: 1492 3143 readable-stream: 4.7.0 ··· 1500 3151 dependencies: 1501 3152 split2: 4.2.0 1502 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 + 1503 3161 pino-pretty@13.1.3: 1504 3162 dependencies: 1505 3163 colorette: 2.0.20 ··· 1548 3206 sonic-boom: 3.8.1 1549 3207 thread-stream: 2.7.0 1550 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 + 1551 3215 pluralize@8.0.0: {} 3216 + 3217 + possible-typed-array-names@1.1.0: {} 1552 3218 1553 3219 postgres-array@2.0.0: {} 1554 3220 ··· 1573 3239 1574 3240 quick-format-unescaped@4.0.4: {} 1575 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 + 1576 3253 readable-stream@4.7.0: 1577 3254 dependencies: 1578 3255 abort-controller: 3.0.0 ··· 1581 3258 process: 0.11.10 1582 3259 string_decoder: 1.3.0 1583 3260 3261 + readdirp@5.0.0: {} 3262 + 1584 3263 real-require@0.2.0: {} 1585 3264 1586 3265 rechoir@0.6.2: 1587 3266 dependencies: 1588 3267 resolve: 1.22.11 1589 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 + 1590 3289 resolve-from@4.0.0: {} 1591 3290 1592 3291 resolve-pkg-maps@1.0.0: {} ··· 1596 3295 is-core-module: 2.16.1 1597 3296 path-parse: 1.0.7 1598 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 1599 3306 1600 3307 safe-buffer@5.2.1: {} 1601 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 + 1602 3320 safe-stable-stringify@2.5.0: {} 1603 3321 1604 3322 secure-json-parse@4.1.0: {} 1605 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 + 1606 3356 shelljs.exec@1.1.8: {} 1607 3357 1608 3358 shelljs@0.8.5: ··· 1611 3361 interpret: 1.4.0 1612 3362 rechoir: 0.6.2 1613 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 + 1614 3392 sonic-boom@3.8.1: 1615 3393 dependencies: 1616 3394 atomic-sleep: 1.0.0 ··· 1619 3397 dependencies: 1620 3398 atomic-sleep: 1.0.0 1621 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 + 1622 3414 split2@4.2.0: {} 1623 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 + 1624 3453 string_decoder@1.3.0: 1625 3454 dependencies: 1626 3455 safe-buffer: 5.2.1 3456 + 3457 + strip-bom@3.0.0: {} 1627 3458 1628 3459 strip-json-comments@5.0.3: {} 1629 3460 ··· 1645 3476 dependencies: 1646 3477 real-require: 0.2.0 1647 3478 3479 + tinyexec@1.0.2: {} 3480 + 3481 + tinypool@2.0.0: {} 3482 + 3483 + tlds@1.261.0: {} 3484 + 1648 3485 to-regex-range@5.0.1: 1649 3486 dependencies: 1650 3487 is-number: 7.0.0 1651 3488 1652 3489 ts-mixer@6.0.4: {} 1653 3490 3491 + tsconfck@3.1.6(typescript@5.9.2): 3492 + optionalDependencies: 3493 + typescript: 5.9.2 3494 + 1654 3495 tslib@2.8.1: {} 1655 3496 1656 3497 tsx@4.21.0: ··· 1660 3501 optionalDependencies: 1661 3502 fsevents: 2.3.3 1662 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 + 1663 3537 typescript@5.9.2: {} 1664 3538 1665 3539 typescript@5.9.3: {} 1666 3540 3541 + ufo@1.6.1: {} 3542 + 1667 3543 uint8arrays@3.0.0: 1668 3544 dependencies: 1669 3545 multiformats: 9.9.0 1670 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 + 1671 3554 undici-types@6.21.0: {} 1672 3555 1673 3556 undici-types@7.16.0: {} ··· 1675 3558 undici@6.21.3: {} 1676 3559 1677 3560 unicode-segmenter@0.14.4: {} 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 1678 3611 1679 3612 wrappy@1.0.2: {} 1680 3613
+7
pnpm-workspace.yaml
··· 4 4 packages: 5 5 - "apps/*" 6 6 - "packages/*" 7 + 8 + blockExoticSubdeps: true 9 + minimumReleaseAge: 10080 10 + trustPolicy: no-downgrade 11 + syncInjectedDepsAfterScripts: 12 + - build 13 + injectWorkspacePackages: true