-17
.env.example
-17
.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=
+68
CONTRIBUTING.md
+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.
+51
-8
Dockerfile
+51
-8
Dockerfile
···
1
1
FROM node:24-alpine AS base
2
2
ENV PNPM_HOME="/pnpm"
3
3
ENV PATH="$PNPM_HOME:$PATH"
4
-
ENV NODE_ENV=production
5
4
RUN corepack enable
6
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
+
7
15
FROM base AS build
8
-
COPY . /app
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/
9
25
WORKDIR /app
10
26
11
27
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile
···
14
30
RUN pnpm deploy --filter=./apps/bot --prod /prod/bot
15
31
RUN pnpm deploy --filter=./apps/tapper --prod /prod/tapper
16
32
33
+
17
34
FROM base AS web
18
-
COPY --from=build /prod/web /prod/web
35
+
COPY --from=build --chown=1000:1000 /prod/web /prod/web
19
36
WORKDIR /prod/web
20
37
EXPOSE 8002
21
-
CMD ["pnpm", "start"]
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
+
22
48
23
49
FROM base AS bot
24
-
COPY --from=build /prod/bot /prod/bot
50
+
COPY --from=build --chown=1000:1000 /prod/bot /prod/bot
25
51
WORKDIR /prod/bot
26
-
CMD ["pnpm", "start"]
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
+
27
62
28
63
FROM base AS tapper
29
-
COPY --from=build /prod/tapper /prod/tapper
64
+
COPY --from=build --chown=1000:1000 /prod/tapper /prod/tapper
30
65
WORKDIR /prod/tapper
31
-
CMD ["pnpm", "start"]
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"
+167
-2
README.md
+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.
+13
-18
apps/bot/commands/auth.ts
+13
-18
apps/bot/commands/auth.ts
···
1
+
import { env } from "@tealfmbot/common/constants";
1
2
import { logger } from "@tealfmbot/common/logger";
2
-
import {
3
-
ChatInputCommandInteraction,
4
-
InteractionContextType,
5
-
SlashCommandBuilder,
6
-
} from "discord.js";
3
+
import { ChatInputCommandInteraction, SlashCommandBuilder } from "discord.js";
4
+
5
+
const LOGIN_URL =
6
+
process.env.NODE_ENV === "development" ? `127.0.0.1:${env.WEB_SERVICE_PORT}` : env.PUBLIC_URL;
7
7
8
8
export default {
9
9
data: new SlashCommandBuilder()
10
-
.setName("auth")
11
-
.setDescription("Authenticate your account with the teal.fm bot to start tracking your listens")
12
-
.addStringOption((option) =>
13
-
option
14
-
.setName("identifier")
15
-
.setDescription("e.g. 'handle.bsky.social or did:plc...'")
16
-
.setRequired(true)
17
-
.setMinLength(1),
18
-
)
19
-
.setContexts(InteractionContextType.Guild),
10
+
.setName("login")
11
+
.setDescription(
12
+
"Authenticate with your Atmosphere account and request your listens to be tracked",
13
+
),
20
14
async execute(interaction: ChatInputCommandInteraction) {
21
-
const identifier = interaction.options.getString("identifier");
22
-
await interaction.reply(`hello ${identifier}`);
23
-
logger.info(`starting authentication process for ${identifier} at ${new Date().toJSON()}`);
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
+
);
24
19
},
25
20
};
+17
apps/bot/commands/recent.ts
+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
+
};
+4
-8
apps/bot/deploy-commands.ts
+4
-8
apps/bot/deploy-commands.ts
···
1
-
import {
2
-
DISCORD_APPLICATION_ID,
3
-
DISCORD_BOT_TOKEN,
4
-
DISCORD_GUILD_ID,
5
-
} from "@tealfmbot/common/constants";
1
+
import { env } from "@tealfmbot/common/constants";
6
2
import { REST, Routes } from "discord.js";
7
3
import fs from "node:fs";
8
4
import path from "node:path";
9
5
10
6
const commands = [];
11
-
const commandPaths = fs.globSync("commands/**/*.js");
7
+
const commandPaths = fs.globSync("dist/commands/*.js");
12
8
13
9
for await (const cmdPath of commandPaths) {
14
10
const absoluteCommandPath = path.join(import.meta.dirname, cmdPath);
···
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
25
console.log(`Started refreshing ${commands.length} application (/) commands.`);
30
26
31
27
const data = (await rest.put(
32
-
Routes.applicationGuildCommands(DISCORD_APPLICATION_ID, DISCORD_GUILD_ID),
28
+
Routes.applicationGuildCommands(env.DISCORD_APPLICATION_ID, env.DISCORD_GUILD_ID),
33
29
{ body: commands },
34
30
)) as unknown[];
35
31
+3
-3
apps/bot/main.ts
+3
-3
apps/bot/main.ts
···
1
-
import { DISCORD_BOT_TOKEN } from "@tealfmbot/common/constants";
1
+
import { env } from "@tealfmbot/common/constants";
2
2
import { logger } from "@tealfmbot/common/logger";
3
3
import { Client, Collection, Events, GatewayIntentBits, MessageFlags } from "discord.js";
4
4
import fs from "node:fs";
···
10
10
console.log(`teal.fm bot ready and logged in as ${readyClient.user.tag}`);
11
11
});
12
12
13
-
client.login(DISCORD_BOT_TOKEN);
13
+
client.login(env.DISCORD_BOT_TOKEN);
14
14
15
15
client.on(Events.InteractionCreate, async (interaction) => {
16
16
if (!interaction.isChatInputCommand()) return;
···
39
39
40
40
client.commands = new Collection();
41
41
42
-
const commandPaths = fs.globSync("commands/*.js");
42
+
const commandPaths = fs.globSync("dist/commands/*.js");
43
43
for await (const file of commandPaths) {
44
44
const absoluteCommandPath = path.join(import.meta.dirname, file);
45
45
const command = await import(absoluteCommandPath);
+4
-2
apps/bot/package.json
+4
-2
apps/bot/package.json
···
4
4
"private": true,
5
5
"type": "module",
6
6
"scripts": {
7
-
"dev": "tsx --watch 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",
10
11
"start": "node dist/main.js",
11
12
"typecheck": "tsc --noEmit"
12
13
},
13
14
"dependencies": {
14
15
"@tealfmbot/common": "workspace:*",
15
-
"@tealfmbot/tsconfig": "workspace:*",
16
+
"@tealfmbot/database": "workspace:*",
16
17
"discord.js": "^14.25.1"
17
18
},
18
19
"devDependencies": {
20
+
"@tealfmbot/tsconfig": "workspace:*",
19
21
"@types/node": "^25.0.3",
20
22
"tsx": "^4.21.0",
21
23
"typescript": "^5.9.3"
+22
-10
apps/tapper/index.ts
+22
-10
apps/tapper/index.ts
···
1
1
import { SimpleIndexer, Tap } from "@atproto/tap";
2
-
import { TAP_ADMIN_PASSWORD } from "@tealfmbot/common/constants";
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()
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
+
}
20
32
console.log(evt.record);
21
33
} else {
22
34
console.log(`deleted: ${uri}`);
+2
-1
apps/tapper/package.json
+2
-1
apps/tapper/package.json
···
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"
+24
apps/tapper/utils.ts
+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
+
}
+19
-11
apps/web/client.ts
+19
-11
apps/web/client.ts
···
5
5
NodeOAuthClient,
6
6
type OAuthClientMetadataInput,
7
7
} from "@atproto/oauth-client-node";
8
-
import { PUBLIC_URL, PRIVATE_KEYS } from "@tealfmbot/common/constants";
8
+
import { env } from "@tealfmbot/common/constants";
9
9
import { db } from "@tealfmbot/database/db";
10
10
import assert from "node:assert";
11
11
12
12
import { SessionStore, StateStore } from "./storage.js";
13
13
14
-
const keyset =
15
-
PUBLIC_URL && PRIVATE_KEYS
16
-
? new Keyset(await Promise.all(PRIVATE_KEYS.map((jwk) => JoseKey.fromJWK(jwk))))
17
-
: undefined;
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
+
};
18
24
19
-
assert(!PUBLIC_URL || keyset?.size, "PRIVATE_KEYS environment variable must be set");
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");
20
28
21
29
const pk = keyset?.findPrivateKey({ usage: "sign" });
22
30
23
-
const metadata: OAuthClientMetadataInput = PUBLIC_URL
31
+
const metadata: OAuthClientMetadataInput = env.PUBLIC_URL
24
32
? {
25
33
client_name: "Disco Stu - Teal.fm Discord Bot",
26
-
client_id: `${PUBLIC_URL}/oauth-client-metadata.json`,
27
-
jwks_uri: `${PUBLIC_URL}/.well-known/jwks.json`,
28
-
redirect_uris: [`${PUBLIC_URL}/oauth/callback`],
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`],
29
37
scope: "atproto",
30
38
grant_types: ["authorization_code", "refresh_token"],
31
39
response_types: ["code"],
···
36
44
}
37
45
: atprotoLoopbackClientMetadata(
38
46
`http://localhost?${new URLSearchParams([
39
-
["redirect_uri", "http://127.0.0.1:8002/oauth/callback"],
47
+
["redirect_uri", `http://127.0.0.1:${env.WEB_SERVICE_PORT}/oauth/callback`],
40
48
["scope", "atproto"],
41
49
])}`,
42
50
);
+27
-15
apps/web/index.ts
+27
-15
apps/web/index.ts
···
1
1
import { serve, type HttpBindings } from "@hono/node-server";
2
-
import { COOKIE_SECRET } from "@tealfmbot/common/constants";
2
+
import { env } from "@tealfmbot/common/constants";
3
3
import { logger } from "@tealfmbot/common/logger";
4
4
import { Hono } from "hono";
5
5
import { deleteCookie, getSignedCookie } from "hono/cookie";
···
8
8
import pinoHttpLogger from "pino-http";
9
9
10
10
import { client } from "./client.js";
11
-
import { createSession, getSessionAgent, MAX_AGE, validateIdentifier } from "./utils.js";
11
+
import {
12
+
createSession,
13
+
getSessionAgent,
14
+
MAX_AGE,
15
+
validateIdentifier,
16
+
getSession,
17
+
} from "./utils.js";
12
18
13
19
type Variables = {
14
20
logger: typeof logger;
···
29
35
});
30
36
31
37
app.get("/dashboard", async (c) => {
32
-
const agent = await getSessionAgent(c);
33
-
if (agent?.assertAuthenticated()) {
34
-
return c.redirect("/login");
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
+
`);
35
48
}
36
-
return c.html(html`
37
-
<h1>Dashboard</h1>
38
-
<p>DID: ${agent?.assertDid}</p>
39
-
<form method="post" action="/logout">
40
-
<button type="submit">Log out</button>
41
-
</form>
42
-
`);
49
+
return c.redirect("/login");
43
50
});
44
51
45
52
app.get("/health", (c) => {
···
61
68
const params = new URLSearchParams(c.req.url.split("?")[1]);
62
69
63
70
try {
64
-
const session = await getSignedCookie(c, COOKIE_SECRET, "__teal_fm_bot_session");
71
+
const session = await getSession(c, env);
65
72
if (session) {
66
73
try {
67
74
const oauthSession = await client.restore(session);
···
80
87
return c.redirect("/dashboard");
81
88
});
82
89
83
-
app.get("/login", (c) => {
90
+
app.get("/login", async (c) => {
91
+
const session = await getSession(c, env);
92
+
if (session) {
93
+
return c.redirect("/dashboard");
94
+
}
95
+
84
96
return c.html(
85
97
html`
86
98
<form action="/login" method="post">
···
122
134
123
135
app.post("/logout", async (c) => {
124
136
c.header("Cache-Control", "no-store");
125
-
const session = await getSignedCookie(c, COOKIE_SECRET, "__teal_fm_bot_session");
137
+
const session = await getSession(c, env);
126
138
if (session) {
127
139
try {
128
140
const oauthSession = await client.restore(session);
+2
-1
apps/web/package.json
+2
-1
apps/web/package.json
···
7
7
"dev": "tsx --watch index.ts",
8
8
"build": "tsc",
9
9
"start": "node dist/index.js",
10
+
"watch": "tsc --watch",
10
11
"typecheck": "tsc --noEmit"
11
12
},
12
13
"dependencies": {
···
17
18
"@hono/node-server": "^1.19.7",
18
19
"@tealfmbot/common": "workspace:*",
19
20
"@tealfmbot/database": "workspace:*",
20
-
"@tealfmbot/tsconfig": "workspace:*",
21
21
"hono": "^4.11.3",
22
22
"pino-http": "^11.0.0"
23
23
},
24
24
"devDependencies": {
25
+
"@tealfmbot/tsconfig": "workspace:*",
25
26
"@types/node": "^25.0.3",
26
27
"tsx": "^4.21.0",
27
28
"typescript": "^5.9.3"
+8
-3
apps/web/utils.ts
+8
-3
apps/web/utils.ts
···
3
3
import { Agent } from "@atproto/api";
4
4
import { isAtprotoDid, isAtprotoDidWeb } from "@atproto/did";
5
5
import { isValidHandle } from "@atproto/syntax";
6
-
import { COOKIE_SECRET } from "@tealfmbot/common/constants";
6
+
import { env } from "@tealfmbot/common/constants";
7
7
import { logger } from "@tealfmbot/common/logger";
8
8
import { deleteCookie, generateSignedCookie, getSignedCookie } from "hono/cookie";
9
9
···
12
12
export const MAX_AGE = process.env.NODE_ENV === "production" ? 60 : 0;
13
13
14
14
export async function createSession(value: string) {
15
-
const cookie = await generateSignedCookie("__teal_fm_bot_session", value, COOKIE_SECRET, {
15
+
const cookie = await generateSignedCookie("__teal_fm_bot_session", value, env.COOKIE_SECRET, {
16
16
path: "/",
17
17
secure: process.env.NODE_ENV === "production",
18
18
httpOnly: true,
···
25
25
26
26
export async function getSessionAgent(c: Context) {
27
27
c.header("Vary", "Cookie");
28
-
const session = await getSignedCookie(c, COOKIE_SECRET, "__teal_fm_bot_session");
28
+
const session = await getSignedCookie(c, env.COOKIE_SECRET, "__teal_fm_bot_session");
29
29
if (!session) return null;
30
30
c.header("Cache-Control", `max-age=${MAX_AGE}, private`);
31
31
···
37
37
deleteCookie(c, "__teal_fm_bot_session");
38
38
return null;
39
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;
40
45
}
41
46
42
47
export function isValidUrl(url: string) {
+28
build-and-publish-images.sh
+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
+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
+6
-3
docker-compose.prod.yml
+6
-3
docker-compose.prod.yml
···
1
+
name: "Disco Stu Compose - Prod"
1
2
services:
2
3
web:
3
4
container_name: web
4
5
restart: always
5
6
build:
6
7
context: .
7
-
dockerfile: Dockerfile
8
+
dockerfile: atcr.io/besaid.zone/discostuweb:1.0
8
9
target: web
9
10
ports:
10
11
- 8002:8002
···
29
30
container_name: tapper
30
31
build:
31
32
context: .
32
-
dockerfile: Dockerfile
33
+
dockerfile: atcr.io/besaid.zone/discostutapper:1.0
33
34
target: tapper
34
35
35
36
depends_on:
···
37
38
condition: service_healthy
38
39
39
40
environment:
41
+
NODE_ENV: production
40
42
TAP_ADMIN_PASSWORD: "${TAP_ADMIN_PASSWORD:?TAP_ADMIN_PASSWORD is required}"
41
43
bot:
42
44
container_name: bot
43
45
restart: always
44
46
build:
45
47
context: .
46
-
dockerfile: Dockerfile
48
+
dockerfile: atcr.io/besaid.zone/discostubot:1.0
47
49
target: bot
48
50
49
51
depends_on:
···
51
53
condition: service_healthy
52
54
53
55
environment:
56
+
NODE_ENV: production
54
57
DISCORD_BOT_TOKEN: "${DISCORD_BOT_TOKEN:?DISCORD_BOT_TOKEN is required}"
55
58
DISCORD_APPLICATION_ID: "${DISCORD_APPLICATION_ID:?DISCORD_APPLICATION_ID is required}"
56
59
DISCORD_GUILD_ID: "${DISCORD_GUILD_ID:?DISCORD_GUILD_ID is required}"
+53
justfile
+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
+7
-3
package.json
+7
-3
package.json
···
16
16
"tap": "pnpm --filter tapper dev",
17
17
"web": "pnpm --filter web dev",
18
18
"build": "pnpm -r build",
19
-
"build:watch": "pnpm -r build:watch",
20
-
"docker:web": "docker build . --target web --tag web:latest",
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",
21
24
"dev:all": "pnpm --filter './apps/**' dev",
22
-
"typecheck": "pnpm --filter './apps/**' typecheck",
25
+
"typecheck": "pnpm --filter './{packages,apps}/**' typecheck",
23
26
"lint": "oxlint",
24
27
"format": "oxfmt --no-error-on-unmatched-pattern"
25
28
},
26
29
"devDependencies": {
27
30
"lefthook": "^2.0.13",
31
+
"npm-run-all": "^4.1.5",
28
32
"oxfmt": "^0.20.0",
29
33
"oxlint": "^1.35.0",
30
34
"typescript": "^5.9.3"
+17
packages/.env.example
+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=
+12
-8
packages/common/constants.ts
+12
-8
packages/common/constants.ts
···
1
+
import { cleanEnv, str, num } from "envalid";
1
2
import path from "node:path";
2
3
import { loadEnvFile } from "node:process";
3
4
···
5
6
loadEnvFile(path.join(import.meta.dirname, "../../.env"));
6
7
}
7
8
8
-
export const DISCORD_BOT_TOKEN = process.env.DISCORD_BOT_TOKEN as string;
9
-
export const DISCORD_APPLICATION_ID = process.env.DISCORD_APPLICATION_ID as string;
10
-
export const DISCORD_GUILD_ID = process.env.DISCORD_GUILD_ID as string;
11
-
export const TAP_ADMIN_PASSWORD = process.env.TAP_ADMIN_PASSWORD as string;
12
-
export const DATABASE_URL = process.env.DATABASE_URL as string;
13
-
export const PUBLIC_URL = process.env.PUBLIC_URL as string;
14
-
export const COOKIE_SECRET = process.env.COOKIE_SECRET as string;
15
-
export const PRIVATE_KEYS = process.env.PRIVATE_KEYS as unknown 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
-1
packages/common/package.json
+2
-1
packages/common/package.json
+3
-1
packages/common/tsconfig.json
+3
-1
packages/common/tsconfig.json
+6
-2
packages/database/database.d.ts
+6
-2
packages/database/database.d.ts
···
28
28
}
29
29
30
30
export interface Plays {
31
+
cid: string | null;
31
32
id: Generated<number>;
32
33
indexed_at: Generated<Timestamp>;
33
-
played_time: Timestamp;
34
-
release_name: string;
34
+
live: boolean | null;
35
+
played_time: Timestamp | null;
36
+
release_name: string | null;
37
+
rkey: string | null;
35
38
track_name: string;
39
+
uri: string | null;
36
40
user_id: number;
37
41
}
38
42
+2
-2
packages/database/db.ts
+2
-2
packages/database/db.ts
···
1
-
import { DATABASE_URL } from "@tealfmbot/common/constants";
1
+
import { env } from "@tealfmbot/common/constants";
2
2
import { Kysely, PostgresDialect } from "kysely";
3
3
import { Pool } from "pg";
4
4
···
6
6
7
7
const dialect = new PostgresDialect({
8
8
pool: new Pool({
9
-
connectionString: DATABASE_URL,
9
+
connectionString: env.DATABASE_URL,
10
10
}),
11
11
});
12
12
+2
-2
packages/database/migrate.ts
+2
-2
packages/database/migrate.ts
···
1
-
import { DATABASE_URL } from "@tealfmbot/common/constants.js";
1
+
import { env } from "@tealfmbot/common/constants";
2
2
import { Kysely, Migrator, PostgresDialect, FileMigrationProvider } from "kysely";
3
3
import { run } from "kysely-migration-cli";
4
4
import fs from "node:fs/promises";
···
13
13
const db = new Kysely<DB>({
14
14
dialect: new PostgresDialect({
15
15
pool: new Pool({
16
-
connectionString: DATABASE_URL,
16
+
connectionString: env.DATABASE_URL,
17
17
}),
18
18
}),
19
19
});
+17
packages/database/migrations/1767547891854_track_record_status.ts
+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
+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
+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
+
}
+2
-2
packages/database/package.json
+2
-2
packages/database/package.json
···
14
14
}
15
15
},
16
16
"scripts": {
17
-
"build:watch": "tsc --watch",
17
+
"watch": "tsc --watch",
18
18
"build": "tsc",
19
19
"migrate": "kysely migrate latest",
20
-
"codegen": "kysely-codegen --dialect postgres --env-file='../../.env' --out-file ./database.d.ts",
20
+
"codegen": "kysely-codegen --dialect postgres --env-file='../.env' --out-file ./database.d.ts",
21
21
"seed": "tsx seed.ts",
22
22
"typecheck": "tsc --noEmit"
23
23
},
+1124
-6
pnpm-lock.yaml
+1124
-6
pnpm-lock.yaml
···
12
12
lefthook:
13
13
specifier: ^2.0.13
14
14
version: 2.0.13
15
+
npm-run-all:
16
+
specifier: ^4.1.5
17
+
version: 4.1.5
15
18
oxfmt:
16
19
specifier: ^0.20.0
17
20
version: 0.20.0
···
27
30
'@tealfmbot/common':
28
31
specifier: workspace:*
29
32
version: link:../../packages/common
30
-
'@tealfmbot/tsconfig':
33
+
'@tealfmbot/database':
31
34
specifier: workspace:*
32
-
version: link:../../packages/tsconfig
35
+
version: link:../../packages/database
33
36
discord.js:
34
37
specifier: ^14.25.1
35
38
version: 14.25.1
36
39
devDependencies:
40
+
'@tealfmbot/tsconfig':
41
+
specifier: workspace:*
42
+
version: link:../../packages/tsconfig
37
43
'@types/node':
38
44
specifier: ^25.0.3
39
45
version: 25.0.3
···
52
58
'@tealfmbot/common':
53
59
specifier: workspace:*
54
60
version: link:../../packages/common
61
+
'@tealfmbot/database':
62
+
specifier: workspace:*
63
+
version: link:../../packages/database
64
+
devDependencies:
55
65
'@tealfmbot/tsconfig':
56
66
specifier: workspace:*
57
67
version: link:../../packages/tsconfig
58
-
devDependencies:
59
68
'@types/node':
60
69
specifier: ^25.0.3
61
70
version: 25.0.3
···
89
98
'@tealfmbot/database':
90
99
specifier: workspace:*
91
100
version: link:../../packages/database
92
-
'@tealfmbot/tsconfig':
93
-
specifier: workspace:*
94
-
version: link:../../packages/tsconfig
95
101
hono:
96
102
specifier: ^4.11.3
97
103
version: 4.11.3
···
99
105
specifier: ^11.0.0
100
106
version: 11.0.0
101
107
devDependencies:
108
+
'@tealfmbot/tsconfig':
109
+
specifier: workspace:*
110
+
version: link:../../packages/tsconfig
102
111
'@types/node':
103
112
specifier: ^25.0.3
104
113
version: 25.0.3
···
111
120
112
121
packages/common:
113
122
dependencies:
123
+
envalid:
124
+
specifier: ^8.1.1
125
+
version: 8.1.1
114
126
pino:
115
127
specifier: ^10.1.0
116
128
version: 10.1.0
···
585
597
argparse@2.0.1:
586
598
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
587
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
+
588
612
atomic-sleep@1.0.0:
589
613
resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==}
590
614
engines: {node: '>=8.0.0'}
591
615
616
+
available-typed-arrays@1.0.7:
617
+
resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==}
618
+
engines: {node: '>= 0.4'}
619
+
592
620
await-lock@2.2.2:
593
621
resolution: {integrity: sha512-aDczADvlvTGajTDjcjpJMqRkOF6Qdz3YbPZm/PyW6tKPkx2hlYBzxMhEywM/tU72HrVZjgl5VCdRuMlA7pZ8Gw==}
594
622
···
615
643
peerDependenciesMeta:
616
644
magicast:
617
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'}
618
658
619
659
callsites@3.1.0:
620
660
resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
···
677
717
typescript:
678
718
optional: true
679
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
+
680
736
dateformat@4.6.3:
681
737
resolution: {integrity: sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==}
682
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
+
683
747
defu@6.1.4:
684
748
resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==}
685
749
···
709
773
resolution: {integrity: sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==}
710
774
engines: {node: '>=12'}
711
775
776
+
dunder-proto@1.0.1:
777
+
resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
778
+
engines: {node: '>= 0.4'}
779
+
712
780
end-of-stream@1.4.5:
713
781
resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==}
714
782
···
716
784
resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==}
717
785
engines: {node: '>=6'}
718
786
787
+
envalid@8.1.1:
788
+
resolution: {integrity: sha512-vOUfHxAFFvkBjbVQbBfgnCO9d3GcNfMMTtVfgqSU2rQGMFEVqWy9GBuoSfHnwGu7EqR0/GeukQcL3KjFBaga9w==}
789
+
engines: {node: '>=18'}
790
+
719
791
error-ex@1.3.4:
720
792
resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==}
721
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
+
722
818
esbuild@0.27.2:
723
819
resolution: {integrity: sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==}
724
820
engines: {node: '>=18'}
···
756
852
resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
757
853
engines: {node: '>=8'}
758
854
855
+
for-each@0.3.5:
856
+
resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==}
857
+
engines: {node: '>= 0.4'}
858
+
759
859
fs.realpath@1.0.0:
760
860
resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
761
861
···
767
867
function-bind@1.1.2:
768
868
resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
769
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
+
770
881
get-caller-file@2.0.5:
771
882
resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
772
883
engines: {node: 6.* || 8.* || >= 10.*}
773
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
+
774
897
get-tsconfig@4.13.0:
775
898
resolution: {integrity: sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==}
776
899
···
786
909
resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
787
910
deprecated: Glob versions prior to v9 are no longer supported
788
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
+
789
927
has-flag@3.0.0:
790
928
resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==}
791
929
engines: {node: '>=4'}
···
794
932
resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
795
933
engines: {node: '>=8'}
796
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
+
797
950
hasown@2.0.2:
798
951
resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
799
952
engines: {node: '>= 0.4'}
···
805
958
resolution: {integrity: sha512-PmQi306+M/ct/m5s66Hrg+adPnkD5jiO6IjA7WhWw0gSBSo1EcRegwuI1deZ+wd5pzCGynCcn2DprnE4/yEV4w==}
806
959
engines: {node: '>=16.9.0'}
807
960
961
+
hosted-git-info@2.8.9:
962
+
resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==}
963
+
808
964
ieee754@1.2.1:
809
965
resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
810
966
···
819
975
inherits@2.0.4:
820
976
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
821
977
978
+
internal-slot@1.1.0:
979
+
resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==}
980
+
engines: {node: '>= 0.4'}
981
+
822
982
interpret@1.4.0:
823
983
resolution: {integrity: sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==}
824
984
engines: {node: '>= 0.10'}
···
827
987
resolution: {integrity: sha512-Zv/pA+ciVFbCSBBjGfaKUya/CcGmUHzTydLMaTwrUUEM2DIEO3iZvueGxmacvmN50fGpGVKeTXpb2LcYQxeVdg==}
828
988
engines: {node: '>= 10'}
829
989
990
+
is-array-buffer@3.0.5:
991
+
resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==}
992
+
engines: {node: '>= 0.4'}
993
+
830
994
is-arrayish@0.2.1:
831
995
resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==}
832
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
+
833
1013
is-core-module@2.16.1:
834
1014
resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==}
835
1015
engines: {node: '>= 0.4'}
836
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
+
837
1045
is-number@7.0.0:
838
1046
resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
839
1047
engines: {node: '>=0.12.0'}
840
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
+
841
1091
iso-datestring-validator@2.2.2:
842
1092
resolution: {integrity: sha512-yLEMkBbLZTlVQqOnQ4FiMujR6T4DEcCb1xizmvXS+OxuhwcbtynoosRzdMA69zZCShCNAbi+gJ71FxZBBXx1SA==}
843
1093
···
858
1108
js-yaml@4.1.1:
859
1109
resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==}
860
1110
hasBin: true
1111
+
1112
+
json-parse-better-errors@1.0.2:
1113
+
resolution: {integrity: sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==}
861
1114
862
1115
json-parse-even-better-errors@2.3.1:
863
1116
resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==}
···
979
1232
lines-and-columns@1.2.4:
980
1233
resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
981
1234
1235
+
load-json-file@4.0.0:
1236
+
resolution: {integrity: sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==}
1237
+
engines: {node: '>=4'}
1238
+
982
1239
lodash.snakecase@4.1.1:
983
1240
resolution: {integrity: sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==}
984
1241
···
995
1252
magic-bytes.js@1.12.1:
996
1253
resolution: {integrity: sha512-ThQLOhN86ZkJ7qemtVRGYM+gRgR8GEXNli9H/PMvpnZsE44Xfh3wx9kGJaldg314v85m+bFW6WBMaVHJc/c3zA==}
997
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
+
998
1263
micromatch@4.0.8:
999
1264
resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
1000
1265
engines: {node: '>=8.6'}
···
1008
1273
multiformats@9.9.0:
1009
1274
resolution: {integrity: sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==}
1010
1275
1276
+
nice-try@1.0.5:
1277
+
resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==}
1278
+
1011
1279
node-fetch-native@1.6.7:
1012
1280
resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==}
1013
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
+
1014
1290
nypm@0.6.2:
1015
1291
resolution: {integrity: sha512-7eM+hpOtrKrBDCh7Ypu2lJ9Z7PNZBdi/8AT3AX8xoCj43BBVHD0hPSTEvMtkMpfs8FCqBGhxB+uToIQimA111g==}
1016
1292
engines: {node: ^14.16.0 || >=16.10.0}
1017
1293
hasBin: true
1018
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
+
1019
1307
ofetch@1.5.1:
1020
1308
resolution: {integrity: sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==}
1021
1309
···
1029
1317
once@1.4.0:
1030
1318
resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
1031
1319
1320
+
own-keys@1.0.1:
1321
+
resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==}
1322
+
engines: {node: '>= 0.4'}
1323
+
1032
1324
oxfmt@0.20.0:
1033
1325
resolution: {integrity: sha512-+7f8eV8iaK3tENN/FUVxZM1g78HjPehybN8/+/dvEA1O893Dcvk6O7/Q1wTQOHMD7wvdwWdujKl+Uo8QMiKDrQ==}
1034
1326
engines: {node: ^20.19.0 || >=22.12.0}
···
1048
1340
resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
1049
1341
engines: {node: '>=6'}
1050
1342
1343
+
parse-json@4.0.0:
1344
+
resolution: {integrity: sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==}
1345
+
engines: {node: '>=4'}
1346
+
1051
1347
parse-json@5.2.0:
1052
1348
resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==}
1053
1349
engines: {node: '>=8'}
···
1056
1352
resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
1057
1353
engines: {node: '>=0.10.0'}
1058
1354
1355
+
path-key@2.0.1:
1356
+
resolution: {integrity: sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==}
1357
+
engines: {node: '>=4'}
1358
+
1059
1359
path-parse@1.0.7:
1060
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'}
1061
1365
1062
1366
pathe@2.0.3:
1063
1367
resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==}
···
1106
1410
resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
1107
1411
engines: {node: '>=8.6'}
1108
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
+
1109
1422
pino-abstract-transport@1.2.0:
1110
1423
resolution: {integrity: sha512-Guhh8EZfPCfH+PMXAb6rKOjGQEoy0xlAIn+irODG5kgfYV+BQ0rGYYWTIel3P5mmyXqkYkPmdIkywsn6QKUR1Q==}
1111
1424
···
1143
1456
resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==}
1144
1457
engines: {node: '>=4'}
1145
1458
1459
+
possible-typed-array-names@1.1.0:
1460
+
resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==}
1461
+
engines: {node: '>= 0.4'}
1462
+
1146
1463
postgres-array@2.0.0:
1147
1464
resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==}
1148
1465
engines: {node: '>=4'}
···
1178
1495
rc9@2.1.2:
1179
1496
resolution: {integrity: sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==}
1180
1497
1498
+
read-pkg@3.0.0:
1499
+
resolution: {integrity: sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==}
1500
+
engines: {node: '>=4'}
1501
+
1181
1502
readable-stream@4.7.0:
1182
1503
resolution: {integrity: sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==}
1183
1504
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
···
1194
1515
resolution: {integrity: sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==}
1195
1516
engines: {node: '>= 0.10'}
1196
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
+
1197
1526
resolve-from@4.0.0:
1198
1527
resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
1199
1528
engines: {node: '>=4'}
···
1206
1535
engines: {node: '>= 0.4'}
1207
1536
hasBin: true
1208
1537
1538
+
safe-array-concat@1.1.3:
1539
+
resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==}
1540
+
engines: {node: '>=0.4'}
1541
+
1209
1542
safe-buffer@5.2.1:
1210
1543
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
1211
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
+
1212
1553
safe-stable-stringify@2.5.0:
1213
1554
resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==}
1214
1555
engines: {node: '>=10'}
···
1216
1557
secure-json-parse@4.1.0:
1217
1558
resolution: {integrity: sha512-l4KnYfEyqYJxDwlNVyRfO2E4NTHfMKAWdUuA8J0yve2Dz/E/PdBepY03RvyJpssIpRFwJoCD55wA+mEDs6ByWA==}
1218
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
+
1219
1588
shelljs.exec@1.1.8:
1220
1589
resolution: {integrity: sha512-vFILCw+lzUtiwBAHV8/Ex8JsFjelFMdhONIsgKNLgTzeRckp2AOYRQtHJE/9LhNvdMmE27AGtzWx0+DHpwIwSw==}
1221
1590
engines: {node: '>= 4.0.0'}
···
1225
1594
engines: {node: '>=4'}
1226
1595
hasBin: true
1227
1596
1597
+
side-channel-list@1.0.0:
1598
+
resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==}
1599
+
engines: {node: '>= 0.4'}
1600
+
1601
+
side-channel-map@1.0.1:
1602
+
resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==}
1603
+
engines: {node: '>= 0.4'}
1604
+
1605
+
side-channel-weakmap@1.0.2:
1606
+
resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==}
1607
+
engines: {node: '>= 0.4'}
1608
+
1609
+
side-channel@1.1.0:
1610
+
resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==}
1611
+
engines: {node: '>= 0.4'}
1612
+
1228
1613
sonic-boom@3.8.1:
1229
1614
resolution: {integrity: sha512-y4Z8LCDBuum+PBP3lSV7RHrXscqksve/bi0as7mhwVnBW+/wUqKT/2Kb7um8yqcFy0duYbbPxzt89Zy2nOCaxg==}
1230
1615
1231
1616
sonic-boom@4.2.0:
1232
1617
resolution: {integrity: sha512-INb7TM37/mAcsGmc9hyyI6+QR3rR1zVRu36B0NeGXKnOOLiZOfER5SA+N7X7k3yUYRzLWafduTDvJAfDswwEww==}
1233
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
+
1234
1631
split2@4.2.0:
1235
1632
resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==}
1236
1633
engines: {node: '>= 10.x'}
···
1238
1635
std-env@3.10.0:
1239
1636
resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==}
1240
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
+
1241
1658
string_decoder@1.3.0:
1242
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'}
1243
1664
1244
1665
strip-json-comments@5.0.3:
1245
1666
resolution: {integrity: sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw==}
···
1300
1721
engines: {node: '>=18.0.0'}
1301
1722
hasBin: true
1302
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
+
1303
1740
typescript@5.9.2:
1304
1741
resolution: {integrity: sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==}
1305
1742
engines: {node: '>=14.17'}
···
1316
1753
uint8arrays@3.0.0:
1317
1754
resolution: {integrity: sha512-HRCx0q6O9Bfbp+HHSfQQKD7wU70+lydKVt4EghkdOvlK/NlrF90z+eXV34mUd48rNvVJXwkrMSPpCATkct8fJA==}
1318
1755
1756
+
unbox-primitive@1.1.0:
1757
+
resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==}
1758
+
engines: {node: '>= 0.4'}
1759
+
1319
1760
undici-types@6.21.0:
1320
1761
resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==}
1321
1762
···
1328
1769
1329
1770
unicode-segmenter@0.14.4:
1330
1771
resolution: {integrity: sha512-pR5VCiCrLrKOL6FRW61jnk9+wyMtKKowq+jyFY9oc6uHbWKhDL4yVRiI4YZPksGMK72Pahh8m0cn/0JvbDDyJg==}
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
1331
1795
1332
1796
wrappy@1.0.2:
1333
1797
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
···
1772
2236
1773
2237
argparse@2.0.1: {}
1774
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
+
1775
2256
atomic-sleep@1.0.0: {}
2257
+
2258
+
available-typed-arrays@1.0.7:
2259
+
dependencies:
2260
+
possible-typed-array-names: 1.1.0
1776
2261
1777
2262
await-lock@2.2.2: {}
1778
2263
···
1809
2294
pkg-types: 2.3.0
1810
2295
rc9: 2.1.2
1811
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
+
1812
2314
callsites@3.1.0: {}
1813
2315
1814
2316
chalk@2.4.2:
···
1863
2365
optionalDependencies:
1864
2366
typescript: 5.9.2
1865
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
+
1866
2394
dateformat@4.6.3: {}
1867
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
+
1868
2408
defu@6.1.4: {}
1869
2409
1870
2410
destr@2.0.5: {}
···
1900
2440
1901
2441
dotenv@17.2.3: {}
1902
2442
2443
+
dunder-proto@1.0.1:
2444
+
dependencies:
2445
+
call-bind-apply-helpers: 1.0.2
2446
+
es-errors: 1.3.0
2447
+
gopd: 1.2.0
2448
+
1903
2449
end-of-stream@1.4.5:
1904
2450
dependencies:
1905
2451
once: 1.4.0
1906
2452
1907
2453
env-paths@2.2.1: {}
1908
2454
2455
+
envalid@8.1.1:
2456
+
dependencies:
2457
+
tslib: 2.8.1
2458
+
1909
2459
error-ex@1.3.4:
1910
2460
dependencies:
1911
2461
is-arrayish: 0.2.1
1912
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
+
1913
2541
esbuild@0.27.2:
1914
2542
optionalDependencies:
1915
2543
'@esbuild/aix-ppc64': 0.27.2
···
1959
2587
dependencies:
1960
2588
to-regex-range: 5.0.1
1961
2589
2590
+
for-each@0.3.5:
2591
+
dependencies:
2592
+
is-callable: 1.2.7
2593
+
1962
2594
fs.realpath@1.0.0: {}
1963
2595
1964
2596
fsevents@2.3.3:
···
1966
2598
1967
2599
function-bind@1.1.2: {}
1968
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
+
1969
2614
get-caller-file@2.0.5: {}
1970
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
+
1971
2640
get-tsconfig@4.13.0:
1972
2641
dependencies:
1973
2642
resolve-pkg-maps: 1.0.0
···
1998
2667
once: 1.4.0
1999
2668
path-is-absolute: 1.0.1
2000
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
+
2001
2681
has-flag@3.0.0: {}
2002
2682
2003
2683
has-flag@4.0.0: {}
2004
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
+
2005
2699
hasown@2.0.2:
2006
2700
dependencies:
2007
2701
function-bind: 1.1.2
···
2010
2704
2011
2705
hono@4.11.3: {}
2012
2706
2707
+
hosted-git-info@2.8.9: {}
2708
+
2013
2709
ieee754@1.2.1: {}
2014
2710
2015
2711
import-fresh@3.3.1:
···
2024
2720
2025
2721
inherits@2.0.4: {}
2026
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
+
2027
2729
interpret@1.4.0: {}
2028
2730
2029
2731
ipaddr.js@2.3.0: {}
2030
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
+
2031
2739
is-arrayish@0.2.1: {}
2032
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
+
2033
2760
is-core-module@2.16.1:
2034
2761
dependencies:
2035
2762
hasown: 2.0.2
2036
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
+
2037
2796
is-number@7.0.0: {}
2038
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
+
2039
2841
iso-datestring-validator@2.2.2: {}
2040
2842
2041
2843
jiti@2.6.1: {}
···
2049
2851
js-yaml@4.1.1:
2050
2852
dependencies:
2051
2853
argparse: 2.0.1
2854
+
2855
+
json-parse-better-errors@1.0.2: {}
2052
2856
2053
2857
json-parse-even-better-errors@2.3.1: {}
2054
2858
···
2139
2943
2140
2944
lines-and-columns@1.2.4: {}
2141
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
+
2142
2953
lodash.snakecase@4.1.1: {}
2143
2954
2144
2955
lodash@4.17.21: {}
···
2149
2960
2150
2961
magic-bytes.js@1.12.1: {}
2151
2962
2963
+
math-intrinsics@1.1.0: {}
2964
+
2965
+
memorystream@0.3.1: {}
2966
+
2152
2967
micromatch@4.0.8:
2153
2968
dependencies:
2154
2969
braces: 3.0.3
···
2162
2977
2163
2978
multiformats@9.9.0: {}
2164
2979
2980
+
nice-try@1.0.5: {}
2981
+
2165
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
2166
3002
2167
3003
nypm@0.6.2:
2168
3004
dependencies:
···
2172
3008
pkg-types: 2.3.0
2173
3009
tinyexec: 1.0.2
2174
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
+
2175
3024
ofetch@1.5.1:
2176
3025
dependencies:
2177
3026
destr: 2.0.5
···
2186
3035
dependencies:
2187
3036
wrappy: 1.0.2
2188
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
+
2189
3044
oxfmt@0.20.0:
2190
3045
dependencies:
2191
3046
tinypool: 2.0.0
···
2214
3069
dependencies:
2215
3070
callsites: 3.1.0
2216
3071
3072
+
parse-json@4.0.0:
3073
+
dependencies:
3074
+
error-ex: 1.3.4
3075
+
json-parse-better-errors: 1.0.2
3076
+
2217
3077
parse-json@5.2.0:
2218
3078
dependencies:
2219
3079
'@babel/code-frame': 7.27.1
···
2223
3083
2224
3084
path-is-absolute@1.0.1: {}
2225
3085
3086
+
path-key@2.0.1: {}
3087
+
2226
3088
path-parse@1.0.7: {}
2227
3089
3090
+
path-type@3.0.0:
3091
+
dependencies:
3092
+
pify: 3.0.0
3093
+
2228
3094
pathe@2.0.3: {}
2229
3095
2230
3096
perfect-debounce@2.0.0: {}
···
2267
3133
picocolors@1.1.1: {}
2268
3134
2269
3135
picomatch@2.3.1: {}
3136
+
3137
+
pidtree@0.3.1: {}
3138
+
3139
+
pify@3.0.0: {}
2270
3140
2271
3141
pino-abstract-transport@1.2.0:
2272
3142
dependencies:
···
2343
3213
pathe: 2.0.3
2344
3214
2345
3215
pluralize@8.0.0: {}
3216
+
3217
+
possible-typed-array-names@1.1.0: {}
2346
3218
2347
3219
postgres-array@2.0.0: {}
2348
3220
···
2372
3244
defu: 6.1.4
2373
3245
destr: 2.0.5
2374
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
+
2375
3253
readable-stream@4.7.0:
2376
3254
dependencies:
2377
3255
abort-controller: 3.0.0
···
2388
3266
dependencies:
2389
3267
resolve: 1.22.11
2390
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
+
2391
3289
resolve-from@4.0.0: {}
2392
3290
2393
3291
resolve-pkg-maps@1.0.0: {}
···
2398
3296
path-parse: 1.0.7
2399
3297
supports-preserve-symlinks-flag: 1.0.0
2400
3298
3299
+
safe-array-concat@1.1.3:
3300
+
dependencies:
3301
+
call-bind: 1.0.8
3302
+
call-bound: 1.0.4
3303
+
get-intrinsic: 1.3.0
3304
+
has-symbols: 1.1.0
3305
+
isarray: 2.0.5
3306
+
2401
3307
safe-buffer@5.2.1: {}
2402
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
+
2403
3320
safe-stable-stringify@2.5.0: {}
2404
3321
2405
3322
secure-json-parse@4.1.0: {}
2406
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
+
2407
3356
shelljs.exec@1.1.8: {}
2408
3357
2409
3358
shelljs@0.8.5:
···
2411
3360
glob: 7.2.3
2412
3361
interpret: 1.4.0
2413
3362
rechoir: 0.6.2
3363
+
3364
+
side-channel-list@1.0.0:
3365
+
dependencies:
3366
+
es-errors: 1.3.0
3367
+
object-inspect: 1.13.4
3368
+
3369
+
side-channel-map@1.0.1:
3370
+
dependencies:
3371
+
call-bound: 1.0.4
3372
+
es-errors: 1.3.0
3373
+
get-intrinsic: 1.3.0
3374
+
object-inspect: 1.13.4
3375
+
3376
+
side-channel-weakmap@1.0.2:
3377
+
dependencies:
3378
+
call-bound: 1.0.4
3379
+
es-errors: 1.3.0
3380
+
get-intrinsic: 1.3.0
3381
+
object-inspect: 1.13.4
3382
+
side-channel-map: 1.0.1
3383
+
3384
+
side-channel@1.1.0:
3385
+
dependencies:
3386
+
es-errors: 1.3.0
3387
+
object-inspect: 1.13.4
3388
+
side-channel-list: 1.0.0
3389
+
side-channel-map: 1.0.1
3390
+
side-channel-weakmap: 1.0.2
2414
3391
2415
3392
sonic-boom@3.8.1:
2416
3393
dependencies:
···
2420
3397
dependencies:
2421
3398
atomic-sleep: 1.0.0
2422
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
+
2423
3414
split2@4.2.0: {}
2424
3415
2425
3416
std-env@3.10.0: {}
2426
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
+
2427
3453
string_decoder@1.3.0:
2428
3454
dependencies:
2429
3455
safe-buffer: 5.2.1
3456
+
3457
+
strip-bom@3.0.0: {}
2430
3458
2431
3459
strip-json-comments@5.0.3: {}
2432
3460
···
2473
3501
optionalDependencies:
2474
3502
fsevents: 2.3.3
2475
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
+
2476
3537
typescript@5.9.2: {}
2477
3538
2478
3539
typescript@5.9.3: {}
···
2483
3544
dependencies:
2484
3545
multiformats: 9.9.0
2485
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
+
2486
3554
undici-types@6.21.0: {}
2487
3555
2488
3556
undici-types@7.16.0: {}
···
2490
3558
undici@6.21.3: {}
2491
3559
2492
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
2493
3611
2494
3612
wrappy@1.0.2: {}
2495
3613