├── src ├── utils │ ├── poster.ts │ └── bsky-prompt.ts ├── lib │ ├── schemas │ │ ├── post.schema.ts │ │ └── code-verifier.schema.ts │ ├── bsky-thread.ts │ ├── twitter.ts │ ├── gpt.ts │ └── db.ts ├── bsky.ts └── index.ts ├── .gitignore ├── Dockerfile ├── docker-compose.yaml ├── .env.example ├── tsconfig.json ├── package.json ├── README.md └── yarn.lock /src/utils/poster.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .env 3 | dist -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM mongo:4.4 2 | 3 | EXPOSE 27017 4 | 5 | CMD ["mongod"] -------------------------------------------------------------------------------- /docker-compose.yaml: -------------------------------------------------------------------------------- 1 | version: "3.8" 2 | 3 | services: 4 | mongo: 5 | image: mongo:4.4 6 | ports: 7 | - "27017:27017" 8 | volumes: 9 | - mongo_data:/data/db 10 | 11 | volumes: 12 | mongo_data: 13 | -------------------------------------------------------------------------------- /src/lib/schemas/post.schema.ts: -------------------------------------------------------------------------------- 1 | import mongoose from "mongoose"; 2 | 3 | const PostSchema = new mongoose.Schema({ 4 | title: String, 5 | postDate: Date, 6 | content: String, 7 | hashtags: [String], 8 | isPosted: Boolean, 9 | }); 10 | 11 | export const Post = mongoose.model("Post", PostSchema); 12 | -------------------------------------------------------------------------------- /src/lib/schemas/code-verifier.schema.ts: -------------------------------------------------------------------------------- 1 | import { Schema, model } from "mongoose"; 2 | 3 | const codeVerifierSchema = new Schema({ 4 | codeVerifier: { type: String, required: true }, 5 | state: { type: String, required: true }, 6 | createdAt: { type: Date, default: Date.now, expires: 600 }, // expires in 10 minutes 7 | }); 8 | 9 | export const CodeVerifier = model("CodeVerifier", codeVerifierSchema); 10 | -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | # IF YOU WANT TO AUTOMATE TWITTER 2 | TWITTER_API_KEY= 3 | TWITTER_API_SECRET= 4 | TWITTER_ACCESS_TOKEN= 5 | TWITTER_ACCESS_SECRET= 6 | TWITTER_BEARER_TOKEN= 7 | TWITTER_OAUTH_CLIENT_KEY= 8 | TWITTER_OAUTH_CLIENT_SECRET= 9 | TWITTER_OAUTH_CALLBACK_URL= 10 | TWITTER_ACCESS_TOKEN= 11 | 12 | # IF YOU WANT TO AUTOMATE BSKY 13 | BSKY_HANDLE= 14 | BSKY_PASSWORD= 15 | 16 | # FOR AI PURPOSES 17 | OPENAI_API_KEY= -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "strict": true, 6 | "esModuleInterop": true, 7 | "emitDecoratorMetadata": true, 8 | "experimentalDecorators": true, 9 | "skipLibCheck": true, 10 | "outDir": "./dist" 11 | }, 12 | "include": ["src/**/*.ts"], 13 | "exclude": ["node_modules"], 14 | "strictPropertyInitialization": false 15 | } 16 | -------------------------------------------------------------------------------- /src/utils/bsky-prompt.ts: -------------------------------------------------------------------------------- 1 | export const getBskyPrompt = (subject: string, lang: string): string => { 2 | return `Create a casual and concise explanation of the ${subject}. It should be written in all lowercase, without line breaks or hashtags. Ensure the text is complete and readable. Write this thread in the language: ${lang}. Search the subject in the internet and provide links that the users can go and read to learn more about the theme.`; 3 | }; 4 | -------------------------------------------------------------------------------- /src/lib/bsky-thread.ts: -------------------------------------------------------------------------------- 1 | export function createBskyThread(text: string): string[] { 2 | const maxLength = 280 - 2; 3 | const words = text.split(" "); 4 | const threadParts: string[] = []; 5 | 6 | let currentPart = ""; 7 | 8 | for (const word of words) { 9 | if ((currentPart + word + " +").length > maxLength) { 10 | threadParts.push(currentPart.trim() + " +"); 11 | currentPart = word + " "; 12 | } else { 13 | currentPart += word + " "; 14 | } 15 | } 16 | 17 | if (currentPart.trim().length > 0) { 18 | threadParts.push(currentPart.trim() + " +"); 19 | } 20 | 21 | threadParts[threadParts.length - 1] = threadParts[ 22 | threadParts.length - 1 23 | ].replace(/ \+$/, ""); 24 | 25 | return threadParts; 26 | } 27 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "twitter-blogpost-automation", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "dependencies": { 7 | "@atproto/api": "^0.13.5", 8 | "@fastify/cookie": "^9.4.0", 9 | "@fastify/session": "^10.9.0", 10 | "dotenv": "^16.4.5", 11 | "fastify": "^4.28.1", 12 | "mongoose": "^8.6.0", 13 | "openai": "^4.57.0", 14 | "pino": "^9.3.2", 15 | "pino-pretty": "^11.2.2", 16 | "tsx": "^4.19.0", 17 | "twitter-api-v2": "^1.17.2", 18 | "typescript": "^5.5.4" 19 | }, 20 | "scripts": { 21 | "dev": "tsx watch --clear-screen=false src/index.ts", 22 | "build": "tsc", 23 | "start": "node dist/index.js" 24 | }, 25 | "devDependencies": { 26 | "@types/node": "^22.5.1" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/lib/twitter.ts: -------------------------------------------------------------------------------- 1 | import { TwitterApi } from "twitter-api-v2"; 2 | import pino from "pino"; 3 | 4 | const logger = pino({ 5 | transport: { 6 | target: "pino-pretty", 7 | options: { colorize: false, translateTime: false, ignore: "pid,hostname" }, 8 | }, 9 | }); 10 | 11 | let client: TwitterApi; 12 | 13 | export function initializeTwitterClient() { 14 | client = new TwitterApi(process.env.TWITTER_ACCESS_TOKEN ?? ""); 15 | } 16 | 17 | export async function sendTweet(content: string): Promise { 18 | try { 19 | logger.info("Attempting to send tweet"); 20 | await client.v2.tweet(content); 21 | logger.info("Tweet sent successfully"); 22 | } catch (error) { 23 | if (error instanceof Error && "code" in error && error.code === 401) { 24 | logger.error( 25 | { error }, 26 | "Unauthorized: Twitter API credentials may be invalid" 27 | ); 28 | throw new Error("Unauthorized: Twitter API credentials may be invalid"); 29 | } else { 30 | logger.error({ error }, "Error sending tweet"); 31 | throw error; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/lib/gpt.ts: -------------------------------------------------------------------------------- 1 | import OpenAI from "openai"; 2 | import pino from "pino"; 3 | 4 | const logger = pino({ 5 | transport: { 6 | target: "pino-pretty", 7 | options: { colorize: false, translateTime: false, ignore: "pid,hostname" }, 8 | }, 9 | }); 10 | 11 | const openai = new OpenAI({ 12 | apiKey: process.env.OPENAI_API_KEY, 13 | }); 14 | 15 | export async function generateGPTResponse(prompt: string): Promise { 16 | try { 17 | logger.info("Generating GPT-4 response"); 18 | const response = await openai.chat.completions.create({ 19 | model: "gpt-4", 20 | messages: [{ role: "user", content: prompt }], 21 | max_tokens: 150, 22 | temperature: 0.7, 23 | }); 24 | 25 | if (response.choices && response.choices.length > 0) { 26 | const generatedText = response.choices[0].message.content?.trim() || ""; 27 | logger.info("GPT-4 response generated successfully"); 28 | return generatedText; 29 | } else { 30 | throw new Error("No response generated"); 31 | } 32 | } catch (error) { 33 | logger.error({ error }, "Error generating GPT-4 response"); 34 | throw error; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/lib/db.ts: -------------------------------------------------------------------------------- 1 | import mongoose from "mongoose"; 2 | import dotenv from "dotenv"; 3 | import pino from "pino"; 4 | 5 | dotenv.config(); 6 | 7 | const logger = pino({ 8 | transport: { 9 | target: "pino-pretty", 10 | options: { colorize: false, translateTime: false, ignore: "pid,hostname" }, 11 | }, 12 | }); 13 | 14 | const MONGODB_URL = 15 | process.env.MONGODB_URL || "mongodb://localhost:27017/mydatabase"; 16 | 17 | async function connectToDatabase() { 18 | try { 19 | logger.info(`Attempting to connect to MongoDB at ${MONGODB_URL}`); 20 | await mongoose.connect(MONGODB_URL); 21 | logger.info("Connected to MongoDB"); 22 | 23 | mongoose.connection.on("connected", () => { 24 | logger.info("Mongoose connected to DB"); 25 | }); 26 | 27 | mongoose.connection.on("error", (err) => { 28 | logger.error({ err }, "Mongoose connection error"); 29 | }); 30 | 31 | mongoose.connection.on("disconnected", () => { 32 | logger.info("Mongoose disconnected"); 33 | }); 34 | } catch (error) { 35 | logger.error({ error }, "Error connecting to MongoDB"); 36 | process.exit(1); 37 | } 38 | } 39 | 40 | export { connectToDatabase }; 41 | -------------------------------------------------------------------------------- /src/bsky.ts: -------------------------------------------------------------------------------- 1 | import { BskyAgent } from "@atproto/api"; 2 | import { createBskyThread } from "./lib/bsky-thread"; 3 | 4 | export const initializeBskyAgent = async () => { 5 | const agent = new BskyAgent({ 6 | service: "https://bsky.social", 7 | }); 8 | 9 | await agent.login({ 10 | identifier: process.env.BSKY_HANDLE ?? "", 11 | password: process.env.BSKY_PASSWORD ?? "", 12 | }); 13 | 14 | return agent; 15 | }; 16 | 17 | export const sendBlueskyPost = async (content: string) => { 18 | const agent = await initializeBskyAgent(); 19 | try { 20 | const response = await agent.api.com.atproto.repo.createRecord({ 21 | collection: "app.bsky.feed.post", 22 | repo: "duca.dev", 23 | record: { 24 | text: content, 25 | createdAt: new Date().toISOString(), 26 | }, 27 | }); 28 | 29 | console.log({ response }); 30 | 31 | if (response.success) { 32 | console.log("Post successfully sent to Bluesky"); 33 | } else { 34 | console.error("Failed to send post to Bluesky", response); 35 | } 36 | } catch (error) { 37 | const errorMessage = (error as Error).message; 38 | throw new Error(errorMessage); 39 | } 40 | }; 41 | 42 | export async function postBskyThread(text: string, bskyClient: BskyAgent) { 43 | const threadParts = createBskyThread(text); 44 | let rootPostUri: string | null = null; 45 | let rootPostCid: string | null = null; 46 | let previousPostUri: string | null = null; 47 | let previousPostCid: string | null = null; 48 | 49 | for (const [index, part] of threadParts.entries()) { 50 | console.log(`Posting part ${index + 1}/${threadParts.length}: "${part}"`); 51 | 52 | const record: { 53 | text: string; 54 | reply?: { 55 | root: { uri: string; cid: string }; 56 | parent: { uri: string; cid: string }; 57 | }; 58 | } = { 59 | text: part, 60 | }; 61 | 62 | if (rootPostUri && rootPostCid && previousPostUri && previousPostCid) { 63 | record.reply = { 64 | root: { uri: rootPostUri, cid: rootPostCid }, 65 | parent: { uri: previousPostUri, cid: previousPostCid }, 66 | }; 67 | console.log(`Replying to parent post: ${previousPostUri}`); 68 | } else if (rootPostUri && rootPostCid) { 69 | // For the first reply, the parent is also the root 70 | record.reply = { 71 | root: { uri: rootPostUri, cid: rootPostCid }, 72 | parent: { uri: rootPostUri, cid: rootPostCid }, 73 | }; 74 | console.log(`Replying to root post: ${rootPostUri}`); 75 | } else { 76 | console.log("This is the first post in the thread."); 77 | } 78 | 79 | console.log("Record being sent:", JSON.stringify(record, null, 2)); 80 | 81 | const response = await bskyClient.api.com.atproto.repo.createRecord({ 82 | collection: "app.bsky.feed.post", 83 | repo: "duca.dev", 84 | record: { 85 | text: record.text, 86 | reply: record.reply, 87 | createdAt: new Date().toISOString(), 88 | }, 89 | }); 90 | 91 | console.log("Response received:", response); 92 | 93 | const isResponseSuccessful = response.success && response.data; 94 | 95 | if (isResponseSuccessful) { 96 | const { uri, cid } = response.data; 97 | 98 | console.log(`Post created successfully with URI: ${uri}`); 99 | 100 | if (!rootPostUri || !rootPostCid) { 101 | rootPostUri = uri; 102 | rootPostCid = cid; 103 | console.log(`Root post set to URI: ${rootPostUri}`); 104 | } 105 | 106 | previousPostUri = uri; 107 | previousPostCid = cid; 108 | } else { 109 | console.error("Failed to create post in the thread", response); 110 | break; 111 | } 112 | } 113 | 114 | console.log("Thread posting complete."); 115 | } 116 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Twitter/Bluesky Blogpost Automation 2 | 3 | This project automates the process of creating blog posts and tweeting them using Fastify, MongoDB, the Twitter API and the Bluesky API. 4 | 5 | ## Prerequisites 6 | 7 | - Node.js (v14 or higher) 8 | - MongoDB 9 | - Twitter Developer Account 10 | - Docker 11 | - Docker Compose 12 | - Ngrok (for local development) 13 | 14 | ## Installation 15 | 16 | 1. Clone the repository: 17 | 18 | ```sh 19 | git clone https://github.com/yourusername/twitter-blogpost-automation.git 20 | cd twitter-blogpost-automation 21 | ``` 22 | 23 | 2. Install dependencies: 24 | 25 | ```sh 26 | npm install 27 | ``` 28 | 29 | 3.1. If you're willing to automate your twitter posts, create a `.env` file in the root directory and add the following environment variables: 30 | 31 | ```env 32 | TWITTER_API_KEY= 33 | TWITTER_API_SECRET= 34 | TWITTER_ACCESS_TOKEN= 35 | TWITTER_ACCESS_SECRET= 36 | TWITTER_BEARER_TOKEN= 37 | TWITTER_OAUTH_CLIENT_KEY= 38 | TWITTER_OAUTH_CLIENT_SECRET= 39 | TWITTER_OAUTH_CALLBACK_URL= 40 | TWITTER_ACCESS_TOKEN= 41 | ``` 42 | 43 | You can obtain these keys and tokens from the Twitter Developer Dashboard. 44 | 45 | 3.2. If you're willing to automate your bluesky posts, create a `.env` file in the root directory and add the following environment variables: 46 | 47 | ```env 48 | BSKY_HANDLE= 49 | BSKY_PASSWORD= 50 | ``` 51 | 52 | These keys are the login information you use to sign in your account. 53 | 54 | ## Running the Project 55 | 56 | 1. Start the server: 57 | 58 | ```sh 59 | yarn dev 60 | ``` 61 | 62 | 2. The server will be running at `http://localhost:8000`. 63 | 64 | ## Running with Docker Compose 65 | 66 | 1. Ensure you have Docker and Docker Compose installed on your machine. 67 | 68 | 2. Start the services: 69 | 70 | ```sh 71 | docker-compose up --build 72 | ``` 73 | 74 | 3. The local MongoDB server will be running at `http://localhost:27017`. 75 | 76 | ## Authentication 77 | 78 | ## Twitter authentication 79 | 80 | 1. Navigate to `http://localhost:8000/auth/twitter` to initiate the Twitter OAuth flow. 81 | 2. After successful authentication, you will be redirected to the callback URL, and your access token will be 82 | displayed in the browser. Copy it and paste in the .env `TWITTER_ACCESS_TOKEN`. 83 | 84 | ## Bsky authentication 85 | 86 | Once you've passed all required bsky envs (handle and password) you're already good to go. 87 | 88 | ## Using Ngrok for Local Development (twitter-only) 89 | 90 | To use Ngrok for local development, follow these steps: 91 | 92 | 1. Download and install Ngrok from [ngrok.com](https://ngrok.com/). 93 | 94 | 2. Start Ngrok to create a tunnel to your local server: 95 | 96 | ```sh 97 | ngrok http 8000 98 | ``` 99 | 100 | 3. Ngrok will provide a public URL (e.g., `https://abcd1234.ngrok.io`). Use this URL as the callback URL in your Twitter Developer Dashboard: 101 | 102 | ```env 103 | TWITTER_OAUTH_CALLBACK_URL=https://abcd1234.ngrok.io/callback 104 | ``` 105 | 106 | 4. Update your `.env` file with the new callback URL. 107 | 108 | ## Postman collection 109 | 110 | ```json 111 | { 112 | "info": { 113 | "_postman_id": "d120d597-833b-4264-903e-03fc3ee88ee2", 114 | "name": "Twitter/Bsky BlogPost Scheduler", 115 | "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", 116 | "_exporter_id": "10880151", 117 | "_collection_link": "https://igorfelipeduca.postman.co/workspace/Duca's-Workspace~4a387d03-407e-4328-8f39-876d5a45807b/collection/10880151-d120d597-833b-4264-903e-03fc3ee88ee2?action=share&source=collection_link&creator=10880151" 118 | }, 119 | "item": [ 120 | { 121 | "name": "Posts", 122 | "item": [ 123 | { 124 | "name": "Create post", 125 | "request": { 126 | "method": "POST", 127 | "header": [], 128 | "body": { 129 | "mode": "raw", 130 | "raw": "{\n \"prompt\": \"escreva um post curto em portugues, quero que esse post tenha um formato adequado para tweets. esse post precisa falar sobre IA na vida das pessoas\",\n \"postDate\": \"2024-08-30T21:53:56.349056Z\"\n}", 131 | "options": { 132 | "raw": { 133 | "language": "json" 134 | } 135 | } 136 | }, 137 | "url": { 138 | "raw": "http://localhost:8000/posts/create", 139 | "protocol": "http", 140 | "host": ["localhost"], 141 | "port": "8000", 142 | "path": ["posts", "create"] 143 | } 144 | }, 145 | "response": [] 146 | }, 147 | { 148 | "name": "Add post to database", 149 | "request": { 150 | "method": "POST", 151 | "header": [], 152 | "body": { 153 | "mode": "raw", 154 | "raw": "{\n \"title\": \"\",\n \"content\": \"testando\",\n \"hashtags\": [],\n \"postDate\": \"2024-08-30T21:53:56.349056Z\"\n}", 155 | "options": { 156 | "raw": { 157 | "language": "json" 158 | } 159 | } 160 | }, 161 | "url": { 162 | "raw": "http://localhost:8000/posts/add", 163 | "protocol": "http", 164 | "host": ["localhost"], 165 | "port": "8000", 166 | "path": ["posts", "add"] 167 | } 168 | }, 169 | "response": [] 170 | }, 171 | { 172 | "name": "Retrieve all posts", 173 | "request": { 174 | "method": "GET", 175 | "header": [], 176 | "url": { 177 | "raw": "http://localhost:8000/posts", 178 | "protocol": "http", 179 | "host": ["localhost"], 180 | "port": "8000", 181 | "path": ["posts"] 182 | } 183 | }, 184 | "response": [] 185 | }, 186 | { 187 | "name": "Edit post", 188 | "request": { 189 | "method": "PUT", 190 | "header": [], 191 | "body": { 192 | "mode": "raw", 193 | "raw": "{\n \"content\": \"testando api ao vivo\"\n}", 194 | "options": { 195 | "raw": { 196 | "language": "json" 197 | } 198 | } 199 | }, 200 | "url": { 201 | "raw": "http://localhost:8000/posts/:id", 202 | "protocol": "http", 203 | "host": ["localhost"], 204 | "port": "8000", 205 | "path": ["posts", ":id"], 206 | "variable": [ 207 | { 208 | "key": "id", 209 | "value": "66d23e855cdafd5df55f19ba" 210 | } 211 | ] 212 | } 213 | }, 214 | "response": [] 215 | } 216 | ] 217 | }, 218 | { 219 | "name": "Twitter", 220 | "item": [ 221 | { 222 | "name": "Tweet post", 223 | "request": { 224 | "method": "POST", 225 | "header": [], 226 | "url": { 227 | "raw": "http://localhost:8000/posts/:id/tweet", 228 | "protocol": "http", 229 | "host": ["localhost"], 230 | "port": "8000", 231 | "path": ["posts", ":id", "tweet"], 232 | "variable": [ 233 | { 234 | "key": "id", 235 | "value": "66d23e855cdafd5df55f19ba" 236 | } 237 | ] 238 | } 239 | }, 240 | "response": [] 241 | } 242 | ] 243 | }, 244 | { 245 | "name": "Bsky", 246 | "item": [ 247 | { 248 | "name": "Post on Bsky", 249 | "request": { 250 | "method": "POST", 251 | "header": [], 252 | "body": { 253 | "mode": "raw", 254 | "raw": "{\n \"content\": \"golang, aka go, is considered a procedural language because it follows a step-by-step approach to break down a task into a collection of variables, procedures, and routines, or functions. this means, in go, blocks of code are organized into procedures (functions) that can be used and reused, making it easier to debug and maintain. also, go has a strong focus on concurrency, which is a big plus for procedural programming. so, yeah, that's why go is seen as a procedural language. remember, it's not just about the language, it's about how you use it.\"\n}", 255 | "options": { 256 | "raw": { 257 | "language": "json" 258 | } 259 | } 260 | }, 261 | "url": { 262 | "raw": "http://localhost:8000/bsky/post", 263 | "protocol": "http", 264 | "host": ["localhost"], 265 | "port": "8000", 266 | "path": ["bsky", "post"] 267 | } 268 | }, 269 | "response": [] 270 | } 271 | ] 272 | }, 273 | { 274 | "name": "AI", 275 | "item": [ 276 | { 277 | "name": "Generate text with GPT", 278 | "request": { 279 | "method": "POST", 280 | "header": [], 281 | "body": { 282 | "mode": "raw", 283 | "raw": "{\n \"prompt\": \"please generate a thread explaining the decentralized architecture of the bluesky network. keep the text casual and concise, using only lowercase. focus on how the architecture empowers users and promotes a more open internet. finish the thread with a question to engage followers.\"\n}", 284 | "options": { 285 | "raw": { 286 | "language": "json" 287 | } 288 | } 289 | }, 290 | "url": { 291 | "raw": "http://localhost:8000/gpt/generate", 292 | "protocol": "http", 293 | "host": ["localhost"], 294 | "port": "8000", 295 | "path": ["gpt", "generate"] 296 | } 297 | }, 298 | "response": [] 299 | } 300 | ] 301 | }, 302 | { 303 | "name": "Bsky Threads", 304 | "item": [ 305 | { 306 | "name": "Post bsky thread", 307 | "request": { 308 | "method": "POST", 309 | "header": [], 310 | "body": { 311 | "mode": "raw", 312 | "raw": "{\n \"text\": \"procedural programming is a straightforward approach where you break down a task into a series of step-by-step instructions, or procedures, making your code easy to follow and maintain. this method empowers users by giving them full control over the flow of their programs, leading to more transparent and accessible software. when code is clear and logical, it promotes collaboration and innovation, contributing to a more open and user-driven internet. what do you think are the biggest benefits of procedural programming in today's tech landscape?\"\n}", 313 | "options": { 314 | "raw": { 315 | "language": "json" 316 | } 317 | } 318 | }, 319 | "url": { 320 | "raw": "http://localhost:8000/bsky/thread", 321 | "protocol": "http", 322 | "host": ["localhost"], 323 | "port": "8000", 324 | "path": ["bsky", "thread"] 325 | } 326 | }, 327 | "response": [] 328 | }, 329 | { 330 | "name": "Generate thread with AI", 331 | "request": { 332 | "method": "POST", 333 | "header": [], 334 | "body": { 335 | "mode": "raw", 336 | "raw": "{\n \"subject\": \"python for machine learning\"\n}", 337 | "options": { 338 | "raw": { 339 | "language": "json" 340 | } 341 | } 342 | }, 343 | "url": { 344 | "raw": "http://localhost:8000/bsky/thread/generate", 345 | "protocol": "http", 346 | "host": ["localhost"], 347 | "port": "8000", 348 | "path": ["bsky", "thread", "generate"] 349 | } 350 | }, 351 | "response": [] 352 | } 353 | ] 354 | }, 355 | { 356 | "name": "Hello", 357 | "request": { 358 | "method": "GET", 359 | "header": [], 360 | "url": { 361 | "raw": "http://localhost:8000", 362 | "protocol": "http", 363 | "host": ["localhost"], 364 | "port": "8000" 365 | } 366 | }, 367 | "response": [] 368 | } 369 | ], 370 | "event": [ 371 | { 372 | "listen": "prerequest", 373 | "script": { 374 | "type": "text/javascript", 375 | "packages": {}, 376 | "exec": [""] 377 | } 378 | }, 379 | { 380 | "listen": "test", 381 | "script": { 382 | "type": "text/javascript", 383 | "packages": {}, 384 | "exec": [""] 385 | } 386 | } 387 | ] 388 | } 389 | ``` 390 | 391 | ## License 392 | 393 | This project is licensed under the MIT License. 394 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import fastify from "fastify"; 2 | import pino from "pino"; 3 | import { Post } from "./lib/schemas/post.schema"; 4 | import { connectToDatabase } from "./lib/db"; 5 | import { generateGPTResponse } from "./lib/gpt"; 6 | import { sendTweet, initializeTwitterClient } from "./lib/twitter"; 7 | import { initializeBskyAgent, sendBlueskyPost } from "./bsky"; 8 | import { ApiResponseError, TwitterApi } from "twitter-api-v2"; 9 | import fastifySession from "@fastify/session"; 10 | import fastifyCookie from "@fastify/cookie"; 11 | import crypto from "crypto"; 12 | import { FastifyRequest } from "fastify"; 13 | import { CodeVerifier } from "./lib/schemas/code-verifier.schema"; 14 | import { postBskyThread } from "./bsky"; // Import the function 15 | import { getBskyPrompt } from "./utils/bsky-prompt"; 16 | 17 | declare module "fastify" { 18 | interface Session { 19 | codeVerifier?: string; 20 | state?: string; 21 | accessToken?: string; 22 | refreshToken?: string; 23 | set(key: string, value: any): void; 24 | [key: string]: any; 25 | } 26 | } 27 | 28 | const logger = pino({ 29 | transport: { 30 | target: "pino-pretty", 31 | options: { colorize: false, translateTime: false, ignore: "pid,hostname" }, 32 | }, 33 | }); 34 | const server = fastify({ logger }); 35 | 36 | server.register(fastifyCookie); 37 | server.register(fastifySession, { 38 | secret: crypto.randomBytes(32).toString("hex"), 39 | cookie: { secure: false }, 40 | }); 41 | 42 | const client = new TwitterApi({ 43 | clientId: process.env.TWITTER_OAUTH_CLIENT_KEY ?? "", 44 | clientSecret: process.env.TWITTER_OAUTH_CLIENT_SECRET ?? "", 45 | }); 46 | 47 | server.get("/", async (request, reply) => { 48 | return reply.send("hello world"); 49 | }); 50 | 51 | server.post("/posts/add", async (request, reply) => { 52 | try { 53 | logger.info("Received request to add a new post"); 54 | const { title, content, hashtags, postDate } = request.body as { 55 | title: string; 56 | content: string; 57 | hashtags: string[]; 58 | postDate?: string; 59 | }; 60 | 61 | logger.debug({ title, content, hashtags, postDate }, "Parsed request body"); 62 | 63 | logger.info("Creating new Post instance"); 64 | 65 | const newPost = new Post({ 66 | title, 67 | content, 68 | hashtags, 69 | postDate: postDate ? new Date(postDate) : new Date(), 70 | isPosted: false, 71 | }); 72 | 73 | logger.info("Attempting to save new post to database"); 74 | 75 | const savedPost = await newPost.save(); 76 | 77 | logger.info({ postId: savedPost._id }, "Post saved successfully"); 78 | 79 | reply 80 | .code(201) 81 | .send({ message: "Post created successfully", post: savedPost }); 82 | logger.info({ postId: savedPost._id }, "Response sent to client"); 83 | } catch (error) { 84 | logger.error(error, "Error occurred while creating the post"); 85 | reply.code(500).send({ 86 | error: "An error occurred while creating the post", 87 | details: error as any, 88 | }); 89 | } 90 | }); 91 | 92 | server.post("/posts/create", async (request, reply) => { 93 | try { 94 | logger.info("Received request to create a new post using GPT"); 95 | const { prompt, postDate } = request.body as { 96 | prompt: string; 97 | postDate?: string; 98 | }; 99 | 100 | logger.debug({ prompt, postDate }, "Parsed request body"); 101 | 102 | logger.info("Generating content using GPT"); 103 | const generatedContent = await generateGPTResponse(prompt); 104 | 105 | logger.info("Creating new Post instance"); 106 | const newPost = new Post({ 107 | title: prompt.substring(0, 50), 108 | content: generatedContent, 109 | hashtags: [], 110 | postDate: postDate ? new Date(postDate) : new Date(), 111 | isPosted: false, 112 | }); 113 | 114 | logger.info("Attempting to save new post to database"); 115 | const savedPost = await newPost.save(); 116 | 117 | logger.info({ postId: savedPost._id }, "Post saved successfully"); 118 | 119 | reply 120 | .code(201) 121 | .send({ message: "Post created successfully", post: savedPost }); 122 | 123 | logger.info({ postId: savedPost._id }, "Response sent to client"); 124 | } catch (error) { 125 | logger.error(error, "Error occurred while creating the post"); 126 | reply.code(500).send({ 127 | error: "An error occurred while creating the post", 128 | details: error as any, 129 | }); 130 | } 131 | }); 132 | 133 | server.post("/gpt/generate", async (request, reply) => { 134 | try { 135 | logger.info("Received request to generate text using GPT"); 136 | const { prompt } = request.body as { prompt: string }; 137 | 138 | logger.debug({ prompt }, "Parsed request body"); 139 | 140 | logger.info("Generating content using GPT"); 141 | const generatedContent = await generateGPTResponse(prompt); 142 | 143 | reply.code(200).send({ content: generatedContent }); 144 | 145 | logger.info("Generated content sent to client"); 146 | } catch (error) { 147 | logger.error(error, "Error occurred while generating text with GPT"); 148 | reply.code(500).send({ 149 | error: "An error occurred while generating text", 150 | details: error as any, 151 | }); 152 | } 153 | }); 154 | 155 | server.put("/posts/:id", async (request, reply) => { 156 | try { 157 | const { id } = request.params as { id: string }; 158 | logger.info({ postId: id }, "Received request to edit a post"); 159 | 160 | const { title, content, hashtags, postDate } = request.body as { 161 | title?: string; 162 | content?: string; 163 | hashtags?: string[]; 164 | postDate?: string; 165 | }; 166 | 167 | logger.debug({ title, content, hashtags, postDate }, "Parsed request body"); 168 | 169 | const post = await Post.findById(id); 170 | 171 | if (!post) { 172 | logger.warn({ postId: id }, "Post not found"); 173 | reply.code(404).send({ error: "Post not found" }); 174 | return; 175 | } 176 | 177 | if (title) post.title = title; 178 | if (content) post.content = content; 179 | if (hashtags) post.hashtags = hashtags; 180 | if (postDate) post.postDate = new Date(postDate); 181 | 182 | logger.info("Attempting to save updated post to database"); 183 | const updatedPost = await post.save(); 184 | 185 | logger.info({ postId: updatedPost._id }, "Post updated successfully"); 186 | 187 | reply 188 | .code(200) 189 | .send({ message: "Post updated successfully", post: updatedPost }); 190 | 191 | logger.info({ postId: updatedPost._id }, "Response sent to client"); 192 | } catch (error) { 193 | logger.error(error, "Error occurred while updating the post"); 194 | reply.code(500).send({ 195 | error: "An error occurred while updating the post", 196 | details: error as any, 197 | }); 198 | } 199 | }); 200 | 201 | server.post("/posts/:id/tweet", async (request, reply) => { 202 | try { 203 | const { id } = request.params as { id: string }; 204 | logger.info({ postId: id }, "Received request to post to Twitter"); 205 | 206 | const post = await Post.findById(id); 207 | const accessToken = process.env.TWITTER_ACCESS_TOKEN; 208 | 209 | if (!post) { 210 | logger.warn({ postId: id }, "Post not found"); 211 | reply.code(404).send({ error: "Post not found" }); 212 | return; 213 | } 214 | 215 | if (!accessToken) { 216 | logger.error("No access token found in session"); 217 | reply.code(401).send({ error: "Unauthorized" }); 218 | return; 219 | } 220 | 221 | initializeTwitterClient(); 222 | 223 | const tweet = `${post.title}\n\n${ 224 | post.content?.substring(0, 240) ?? "" 225 | }...`; 226 | 227 | await sendTweet(tweet); 228 | 229 | post.isPosted = true; 230 | await post.save(); 231 | 232 | logger.info({ postId: id }, "Updated post isPosted status to true"); 233 | 234 | reply.code(200).send({ message: "Successfully posted to Twitter" }); 235 | 236 | logger.info( 237 | { postId: id }, 238 | "Successfully posted to Twitter and response sent to client" 239 | ); 240 | } catch (error) { 241 | logger.error(error, "Error occurred while posting to Twitter"); 242 | reply.code(500).send({ 243 | error: "An error occurred while posting to Twitter", 244 | details: error as any, 245 | }); 246 | } 247 | }); 248 | 249 | server.post("/posts/:id/bsky", async (request, reply) => { 250 | try { 251 | const { id } = request.params as { id: string }; 252 | logger.info({ postId: id }, "Received request to post to Bluesky"); 253 | 254 | const post = await Post.findById(id); 255 | 256 | if (!post) { 257 | logger.warn({ postId: id }, "Post not found"); 258 | reply.code(404).send({ error: "Post not found" }); 259 | return; 260 | } 261 | 262 | const blueskyPostContent = `${post.title}\n\n${ 263 | post.content?.substring(0, 240) ?? "" 264 | }...`; 265 | 266 | await sendBlueskyPost(blueskyPostContent); 267 | 268 | post.isPosted = true; 269 | await post.save(); 270 | 271 | logger.info({ postId: id }, "Updated post isPosted status to true"); 272 | 273 | reply.code(200).send({ message: "Successfully posted to Bluesky" }); 274 | 275 | logger.info( 276 | { postId: id }, 277 | "Successfully posted to Bluesky and response sent to client" 278 | ); 279 | } catch (error) { 280 | logger.error(error, "Error occurred while posting to Bluesky"); 281 | reply.code(500).send({ 282 | error: "An error occurred while posting to Bluesky", 283 | details: error as any, 284 | }); 285 | } 286 | }); 287 | 288 | server.post("/bsky/post", async (request, reply) => { 289 | try { 290 | const { content } = request.body as { content: string }; 291 | logger.info("Received request to post to Bluesky"); 292 | 293 | await sendBlueskyPost(content); 294 | 295 | reply.code(200).send({ message: "Successfully posted to Bluesky" }); 296 | 297 | logger.info("Successfully posted to Bluesky and response sent to client"); 298 | } catch (error) { 299 | logger.error(error, "Error occurred while posting to Bluesky"); 300 | reply.code(500).send({ 301 | error: "An error occurred while posting to Bluesky", 302 | details: error instanceof Error ? error.message : String(error), 303 | }); 304 | } 305 | }); 306 | 307 | server.post("/bsky/thread", async (request, reply) => { 308 | try { 309 | const { text } = request.body as { text: string }; 310 | logger.info("Received request to post a thread to Bluesky"); 311 | 312 | const agent = await initializeBskyAgent(); 313 | await postBskyThread(text, agent); 314 | 315 | reply.code(200).send({ message: "Successfully posted thread to Bluesky" }); 316 | 317 | logger.info( 318 | "Successfully posted thread to Bluesky and response sent to client" 319 | ); 320 | } catch (error) { 321 | logger.error(error, "Error occurred while posting thread to Bluesky"); 322 | reply.code(500).send({ 323 | error: "An error occurred while posting thread to Bluesky", 324 | details: error instanceof Error ? error.message : String(error), 325 | }); 326 | } 327 | }); 328 | 329 | server.post("/bsky/thread/generate", async (request, reply) => { 330 | try { 331 | const { subject, lang } = request.body as { subject: string; lang: string }; 332 | logger.info("Received request to generate and post a thread to Bluesky"); 333 | 334 | logger.info(`Generating prompt based on subject: ${subject}`); 335 | const bskyPrompt = getBskyPrompt(subject, lang ?? "en-US"); 336 | const generatedText = await generateGPTResponse(bskyPrompt); 337 | 338 | logger.info(`Generated text: ${generatedText}`); 339 | 340 | const agent = await initializeBskyAgent(); 341 | await postBskyThread(`🤖 GENERATED WITH AI\n\n${generatedText}`, agent); 342 | 343 | reply 344 | .code(200) 345 | .send({ message: "Successfully generated and posted thread to Bluesky" }); 346 | 347 | logger.info( 348 | "Successfully generated and posted thread to Bluesky and response sent to client" 349 | ); 350 | } catch (error) { 351 | logger.error( 352 | error, 353 | "Error occurred while generating or posting thread to Bluesky" 354 | ); 355 | reply.code(500).send({ 356 | error: "An error occurred while generating or posting thread to Bluesky", 357 | details: error instanceof Error ? error.message : String(error), 358 | }); 359 | } 360 | }); 361 | 362 | server.get("/auth/twitter", async (request, reply) => { 363 | try { 364 | const { url, codeVerifier, state } = await client.generateOAuth2AuthLink( 365 | process.env.TWITTER_OAUTH_CALLBACK_URL ?? "", 366 | { scope: ["tweet.read", "tweet.write", "users.read"] } 367 | ); 368 | 369 | await new CodeVerifier({ codeVerifier, state }).save(); 370 | 371 | reply.redirect(url); 372 | } catch (error) { 373 | logger.error(error, "Error initiating Twitter OAuth flow"); 374 | reply.code(500).send({ 375 | error: "An error occurred while initiating Twitter login", 376 | details: error as any, 377 | }); 378 | } 379 | }); 380 | 381 | server.get("/callback", async (request: FastifyRequest, reply) => { 382 | try { 383 | const { state, code } = request.query as { state?: string; code?: string }; 384 | 385 | logger.info({ state, code }, "Received callback parameters"); 386 | 387 | if (!state || !code) { 388 | reply.code(400).send({ error: "Missing state or code" }); 389 | return; 390 | } 391 | 392 | const codeVerifierDoc = await CodeVerifier.findOne({ state }); 393 | 394 | if (!codeVerifierDoc) { 395 | reply.code(400).send({ error: "Invalid state" }); 396 | return; 397 | } 398 | 399 | const { codeVerifier } = codeVerifierDoc; 400 | 401 | const { accessToken, refreshToken } = await client.loginWithOAuth2({ 402 | code, 403 | codeVerifier, 404 | redirectUri: process.env.TWITTER_OAUTH_CALLBACK_URL ?? "", 405 | }); 406 | 407 | request.session.accessToken = accessToken; 408 | request.session.refreshToken = refreshToken; 409 | 410 | reply.code(200).send({ accessToken, refreshToken }); 411 | } catch (error) { 412 | logger.error(error, "Error completing Twitter OAuth flow"); 413 | if (error instanceof ApiResponseError && error.code === 400) { 414 | reply.code(400).send({ 415 | error: "Invalid request", 416 | details: "The authorization code or other parameters were invalid.", 417 | }); 418 | } else { 419 | reply.code(500).send({ 420 | error: "An error occurred during authentication", 421 | details: error instanceof Error ? error.message : String(error), 422 | }); 423 | } 424 | } 425 | }); 426 | 427 | server.get("/posts", async (request, reply) => { 428 | const posts = await Post.find().sort({ postDate: -1 }).limit(10); 429 | 430 | reply.send(posts); 431 | }); 432 | 433 | const start = async () => { 434 | try { 435 | await connectToDatabase(); 436 | 437 | const port = Number(process.env.PORT) || 8000; 438 | await server.listen({ port, host: "0.0.0.0" }); 439 | console.log(`Server listening on http://localhost:${port}`); 440 | 441 | const checkAndPostBlueskyPosts = async () => { 442 | try { 443 | const now = new Date(); 444 | const posts = await Post.find({ 445 | isPosted: false, 446 | postDate: { $lt: now }, 447 | }); 448 | 449 | for (const post of posts) { 450 | const content = `${post.title}\n\n${ 451 | post.content?.substring(0, 240) ?? "" 452 | }...`; 453 | 454 | try { 455 | await sendBlueskyPost(content); 456 | 457 | post.isPosted = true; 458 | await post.save(); 459 | 460 | logger.info( 461 | { postId: post._id }, 462 | "Automatically posted to Bluesky" 463 | ); 464 | } catch (error) { 465 | logger.error(error, "Error occurred while posting to Bluesky"); 466 | } 467 | } 468 | } catch (error) { 469 | logger.error(error, "Error occurred during automatic post checking"); 470 | } finally { 471 | setTimeout(checkAndPostBlueskyPosts, 5 * 60 * 1000); 472 | } 473 | }; 474 | 475 | checkAndPostBlueskyPosts(); 476 | } catch (err) { 477 | console.error(err); 478 | process.exit(1); 479 | } 480 | }; 481 | 482 | start(); 483 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@atproto/api@^0.13.5": 6 | version "0.13.5" 7 | resolved "https://registry.yarnpkg.com/@atproto/api/-/api-0.13.5.tgz#04305cdb0a467ba366305c5e95cebb7ce0d39735" 8 | integrity sha512-yT/YimcKYkrI0d282Zxo7O30OSYR+KDW89f81C6oYZfDRBcShC1aniVV8kluP5LrEAg8O27yrOSnBgx2v7XPew== 9 | dependencies: 10 | "@atproto/common-web" "^0.3.0" 11 | "@atproto/lexicon" "^0.4.1" 12 | "@atproto/syntax" "^0.3.0" 13 | "@atproto/xrpc" "^0.6.1" 14 | await-lock "^2.2.2" 15 | multiformats "^9.9.0" 16 | tlds "^1.234.0" 17 | 18 | "@atproto/common-web@^0.3.0": 19 | version "0.3.0" 20 | resolved "https://registry.yarnpkg.com/@atproto/common-web/-/common-web-0.3.0.tgz#36da8c2c31d8cf8a140c3c8f03223319bf4430bb" 21 | integrity sha512-67VnV6JJyX+ZWyjV7xFQMypAgDmjVaR9ZCuU/QW+mqlqI7fex2uL4Fv+7/jHadgzhuJHVd6OHOvNn0wR5WZYtA== 22 | dependencies: 23 | graphemer "^1.4.0" 24 | multiformats "^9.9.0" 25 | uint8arrays "3.0.0" 26 | zod "^3.21.4" 27 | 28 | "@atproto/lexicon@^0.4.1": 29 | version "0.4.1" 30 | resolved "https://registry.yarnpkg.com/@atproto/lexicon/-/lexicon-0.4.1.tgz#19155210570a2fafbcc7d4f655d9b813948e72a0" 31 | integrity sha512-bzyr+/VHXLQWbumViX5L7h1NKQObfs8Z+XZJl43OUK8nYFUI4e/sW1IZKRNfw7Wvi5YVNK+J+yP3DWIBZhkCYA== 32 | dependencies: 33 | "@atproto/common-web" "^0.3.0" 34 | "@atproto/syntax" "^0.3.0" 35 | iso-datestring-validator "^2.2.2" 36 | multiformats "^9.9.0" 37 | zod "^3.23.8" 38 | 39 | "@atproto/syntax@^0.3.0": 40 | version "0.3.0" 41 | resolved "https://registry.yarnpkg.com/@atproto/syntax/-/syntax-0.3.0.tgz#fafa2dbea9add37253005cb663e7373e05e618b3" 42 | integrity sha512-Weq0ZBxffGHDXHl9U7BQc2BFJi/e23AL+k+i5+D9hUq/bzT4yjGsrCejkjq0xt82xXDjmhhvQSZ0LqxyZ5woxA== 43 | 44 | "@atproto/xrpc@^0.6.1": 45 | version "0.6.1" 46 | resolved "https://registry.yarnpkg.com/@atproto/xrpc/-/xrpc-0.6.1.tgz#dcd1315c8c60eef5af2db7fa4e35a38ebc6d79d5" 47 | integrity sha512-Zy5ydXEdk6sY7FDUZcEVfCL1jvbL4tXu5CcdPqbEaW6LQtk9GLds/DK1bCX9kswTGaBC88EMuqQMfkxOhp2t4A== 48 | dependencies: 49 | "@atproto/lexicon" "^0.4.1" 50 | zod "^3.23.8" 51 | 52 | "@esbuild/aix-ppc64@0.23.1": 53 | version "0.23.1" 54 | resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.23.1.tgz#51299374de171dbd80bb7d838e1cfce9af36f353" 55 | integrity sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ== 56 | 57 | "@esbuild/android-arm64@0.23.1": 58 | version "0.23.1" 59 | resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.23.1.tgz#58565291a1fe548638adb9c584237449e5e14018" 60 | integrity sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw== 61 | 62 | "@esbuild/android-arm@0.23.1": 63 | version "0.23.1" 64 | resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.23.1.tgz#5eb8c652d4c82a2421e3395b808e6d9c42c862ee" 65 | integrity sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ== 66 | 67 | "@esbuild/android-x64@0.23.1": 68 | version "0.23.1" 69 | resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.23.1.tgz#ae19d665d2f06f0f48a6ac9a224b3f672e65d517" 70 | integrity sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg== 71 | 72 | "@esbuild/darwin-arm64@0.23.1": 73 | version "0.23.1" 74 | resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.23.1.tgz#05b17f91a87e557b468a9c75e9d85ab10c121b16" 75 | integrity sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q== 76 | 77 | "@esbuild/darwin-x64@0.23.1": 78 | version "0.23.1" 79 | resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.23.1.tgz#c58353b982f4e04f0d022284b8ba2733f5ff0931" 80 | integrity sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw== 81 | 82 | "@esbuild/freebsd-arm64@0.23.1": 83 | version "0.23.1" 84 | resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.23.1.tgz#f9220dc65f80f03635e1ef96cfad5da1f446f3bc" 85 | integrity sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA== 86 | 87 | "@esbuild/freebsd-x64@0.23.1": 88 | version "0.23.1" 89 | resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.23.1.tgz#69bd8511fa013b59f0226d1609ac43f7ce489730" 90 | integrity sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g== 91 | 92 | "@esbuild/linux-arm64@0.23.1": 93 | version "0.23.1" 94 | resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.23.1.tgz#8050af6d51ddb388c75653ef9871f5ccd8f12383" 95 | integrity sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g== 96 | 97 | "@esbuild/linux-arm@0.23.1": 98 | version "0.23.1" 99 | resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.23.1.tgz#ecaabd1c23b701070484990db9a82f382f99e771" 100 | integrity sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ== 101 | 102 | "@esbuild/linux-ia32@0.23.1": 103 | version "0.23.1" 104 | resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.23.1.tgz#3ed2273214178109741c09bd0687098a0243b333" 105 | integrity sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ== 106 | 107 | "@esbuild/linux-loong64@0.23.1": 108 | version "0.23.1" 109 | resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.23.1.tgz#a0fdf440b5485c81b0fbb316b08933d217f5d3ac" 110 | integrity sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw== 111 | 112 | "@esbuild/linux-mips64el@0.23.1": 113 | version "0.23.1" 114 | resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.23.1.tgz#e11a2806346db8375b18f5e104c5a9d4e81807f6" 115 | integrity sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q== 116 | 117 | "@esbuild/linux-ppc64@0.23.1": 118 | version "0.23.1" 119 | resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.23.1.tgz#06a2744c5eaf562b1a90937855b4d6cf7c75ec96" 120 | integrity sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw== 121 | 122 | "@esbuild/linux-riscv64@0.23.1": 123 | version "0.23.1" 124 | resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.23.1.tgz#65b46a2892fc0d1af4ba342af3fe0fa4a8fe08e7" 125 | integrity sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA== 126 | 127 | "@esbuild/linux-s390x@0.23.1": 128 | version "0.23.1" 129 | resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.23.1.tgz#e71ea18c70c3f604e241d16e4e5ab193a9785d6f" 130 | integrity sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw== 131 | 132 | "@esbuild/linux-x64@0.23.1": 133 | version "0.23.1" 134 | resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.23.1.tgz#d47f97391e80690d4dfe811a2e7d6927ad9eed24" 135 | integrity sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ== 136 | 137 | "@esbuild/netbsd-x64@0.23.1": 138 | version "0.23.1" 139 | resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.23.1.tgz#44e743c9778d57a8ace4b72f3c6b839a3b74a653" 140 | integrity sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA== 141 | 142 | "@esbuild/openbsd-arm64@0.23.1": 143 | version "0.23.1" 144 | resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.23.1.tgz#05c5a1faf67b9881834758c69f3e51b7dee015d7" 145 | integrity sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q== 146 | 147 | "@esbuild/openbsd-x64@0.23.1": 148 | version "0.23.1" 149 | resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.23.1.tgz#2e58ae511bacf67d19f9f2dcd9e8c5a93f00c273" 150 | integrity sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA== 151 | 152 | "@esbuild/sunos-x64@0.23.1": 153 | version "0.23.1" 154 | resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.23.1.tgz#adb022b959d18d3389ac70769cef5a03d3abd403" 155 | integrity sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA== 156 | 157 | "@esbuild/win32-arm64@0.23.1": 158 | version "0.23.1" 159 | resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.23.1.tgz#84906f50c212b72ec360f48461d43202f4c8b9a2" 160 | integrity sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A== 161 | 162 | "@esbuild/win32-ia32@0.23.1": 163 | version "0.23.1" 164 | resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.23.1.tgz#5e3eacc515820ff729e90d0cb463183128e82fac" 165 | integrity sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ== 166 | 167 | "@esbuild/win32-x64@0.23.1": 168 | version "0.23.1" 169 | resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.23.1.tgz#81fd50d11e2c32b2d6241470e3185b70c7b30699" 170 | integrity sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg== 171 | 172 | "@fastify/ajv-compiler@^3.5.0": 173 | version "3.6.0" 174 | resolved "https://registry.yarnpkg.com/@fastify/ajv-compiler/-/ajv-compiler-3.6.0.tgz#907497a0e62a42b106ce16e279cf5788848e8e79" 175 | integrity sha512-LwdXQJjmMD+GwLOkP7TVC68qa+pSSogeWWmznRJ/coyTcfe9qA05AHFSe1eZFwK6q+xVRpChnvFUkf1iYaSZsQ== 176 | dependencies: 177 | ajv "^8.11.0" 178 | ajv-formats "^2.1.1" 179 | fast-uri "^2.0.0" 180 | 181 | "@fastify/cookie@^9.4.0": 182 | version "9.4.0" 183 | resolved "https://registry.yarnpkg.com/@fastify/cookie/-/cookie-9.4.0.tgz#1be3bff03dbe746d3bbddbf31a37354076a190c1" 184 | integrity sha512-Th+pt3kEkh4MQD/Q2q1bMuJIB5NX/D5SwSpOKu3G/tjoGbwfpurIMJsWSPS0SJJ4eyjtmQ8OipDQspf8RbUOlg== 185 | dependencies: 186 | cookie-signature "^1.1.0" 187 | fastify-plugin "^4.0.0" 188 | 189 | "@fastify/error@^3.3.0", "@fastify/error@^3.4.0": 190 | version "3.4.1" 191 | resolved "https://registry.yarnpkg.com/@fastify/error/-/error-3.4.1.tgz#b14bb4cac3dd4ec614becbc643d1511331a6425c" 192 | integrity sha512-wWSvph+29GR783IhmvdwWnN4bUxTD01Vm5Xad4i7i1VuAOItLvbPAb69sb0IQ2N57yprvhNIwAP5B6xfKTmjmQ== 193 | 194 | "@fastify/fast-json-stringify-compiler@^4.3.0": 195 | version "4.3.0" 196 | resolved "https://registry.yarnpkg.com/@fastify/fast-json-stringify-compiler/-/fast-json-stringify-compiler-4.3.0.tgz#5df89fa4d1592cbb8780f78998355feb471646d5" 197 | integrity sha512-aZAXGYo6m22Fk1zZzEUKBvut/CIIQe/BapEORnxiD5Qr0kPHqqI69NtEMCme74h+at72sPhbkb4ZrLd1W3KRLA== 198 | dependencies: 199 | fast-json-stringify "^5.7.0" 200 | 201 | "@fastify/merge-json-schemas@^0.1.0": 202 | version "0.1.1" 203 | resolved "https://registry.yarnpkg.com/@fastify/merge-json-schemas/-/merge-json-schemas-0.1.1.tgz#3551857b8a17a24e8c799e9f51795edb07baa0bc" 204 | integrity sha512-fERDVz7topgNjtXsJTTW1JKLy0rhuLRcquYqNR9rF7OcVpCa2OVW49ZPDIhaRRCaUuvVxI+N416xUoF76HNSXA== 205 | dependencies: 206 | fast-deep-equal "^3.1.3" 207 | 208 | "@fastify/session@^10.9.0": 209 | version "10.9.0" 210 | resolved "https://registry.yarnpkg.com/@fastify/session/-/session-10.9.0.tgz#7c703a4513274a5a183bd3095eb9b49714b494a5" 211 | integrity sha512-u/c42RuAaxCeEuRCAwK2+/SfGqKOd0NSyRzEvDwFBWySQoKUZQyb9OmmJSWJBbOP1OfaU2OsDrjbPbghE1l/YQ== 212 | dependencies: 213 | fastify-plugin "^4.0.0" 214 | safe-stable-stringify "^2.3.1" 215 | 216 | "@mongodb-js/saslprep@^1.1.5": 217 | version "1.1.8" 218 | resolved "https://registry.yarnpkg.com/@mongodb-js/saslprep/-/saslprep-1.1.8.tgz#d39744540be8800d17749990b0da95b4271840d1" 219 | integrity sha512-qKwC/M/nNNaKUBMQ0nuzm47b7ZYWQHN3pcXq4IIcoSBc2hOIrflAxJduIvvqmhoz3gR2TacTAs8vlsCVPkiEdQ== 220 | dependencies: 221 | sparse-bitfield "^3.0.3" 222 | 223 | "@types/node-fetch@^2.6.4": 224 | version "2.6.11" 225 | resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.11.tgz#9b39b78665dae0e82a08f02f4967d62c66f95d24" 226 | integrity sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g== 227 | dependencies: 228 | "@types/node" "*" 229 | form-data "^4.0.0" 230 | 231 | "@types/node@*", "@types/node@^22.5.1": 232 | version "22.5.1" 233 | resolved "https://registry.yarnpkg.com/@types/node/-/node-22.5.1.tgz#de01dce265f6b99ed32b295962045d10b5b99560" 234 | integrity sha512-KkHsxej0j9IW1KKOOAA/XBA0z08UFSrRQHErzEfA3Vgq57eXIMYboIlHJuYIfd+lwCQjtKqUu3UnmKbtUc9yRw== 235 | dependencies: 236 | undici-types "~6.19.2" 237 | 238 | "@types/node@^18.11.18": 239 | version "18.19.47" 240 | resolved "https://registry.yarnpkg.com/@types/node/-/node-18.19.47.tgz#18076201ad7dd3445046df6ce9ead5fe5abd9387" 241 | integrity sha512-1f7dB3BL/bpd9tnDJrrHb66Y+cVrhxSOTGorRNdHwYTUlTay3HuTDPKo9a/4vX9pMQkhYBcAbL4jQdNlhCFP9A== 242 | dependencies: 243 | undici-types "~5.26.4" 244 | 245 | "@types/qs@^6.9.7": 246 | version "6.9.15" 247 | resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.15.tgz#adde8a060ec9c305a82de1babc1056e73bd64dce" 248 | integrity sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg== 249 | 250 | "@types/webidl-conversions@*": 251 | version "7.0.3" 252 | resolved "https://registry.yarnpkg.com/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz#1306dbfa53768bcbcfc95a1c8cde367975581859" 253 | integrity sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA== 254 | 255 | "@types/whatwg-url@^11.0.2": 256 | version "11.0.5" 257 | resolved "https://registry.yarnpkg.com/@types/whatwg-url/-/whatwg-url-11.0.5.tgz#aaa2546e60f0c99209ca13360c32c78caf2c409f" 258 | integrity sha512-coYR071JRaHa+xoEvvYqvnIHaVqaYrLPbsufM9BF63HkwI5Lgmy2QR8Q5K/lYDYo5AK82wOvSOS0UsLTpTG7uQ== 259 | dependencies: 260 | "@types/webidl-conversions" "*" 261 | 262 | abort-controller@^3.0.0: 263 | version "3.0.0" 264 | resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" 265 | integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== 266 | dependencies: 267 | event-target-shim "^5.0.0" 268 | 269 | abstract-logging@^2.0.1: 270 | version "2.0.1" 271 | resolved "https://registry.yarnpkg.com/abstract-logging/-/abstract-logging-2.0.1.tgz#6b0c371df212db7129b57d2e7fcf282b8bf1c839" 272 | integrity sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA== 273 | 274 | agentkeepalive@^4.2.1: 275 | version "4.5.0" 276 | resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.5.0.tgz#2673ad1389b3c418c5a20c5d7364f93ca04be923" 277 | integrity sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew== 278 | dependencies: 279 | humanize-ms "^1.2.1" 280 | 281 | ajv-formats@^2.1.1: 282 | version "2.1.1" 283 | resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" 284 | integrity sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA== 285 | dependencies: 286 | ajv "^8.0.0" 287 | 288 | ajv-formats@^3.0.1: 289 | version "3.0.1" 290 | resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-3.0.1.tgz#3d5dc762bca17679c3c2ea7e90ad6b7532309578" 291 | integrity sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ== 292 | dependencies: 293 | ajv "^8.0.0" 294 | 295 | ajv@^8.0.0, ajv@^8.10.0, ajv@^8.11.0: 296 | version "8.17.1" 297 | resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.17.1.tgz#37d9a5c776af6bc92d7f4f9510eba4c0a60d11a6" 298 | integrity sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g== 299 | dependencies: 300 | fast-deep-equal "^3.1.3" 301 | fast-uri "^3.0.1" 302 | json-schema-traverse "^1.0.0" 303 | require-from-string "^2.0.2" 304 | 305 | asynckit@^0.4.0: 306 | version "0.4.0" 307 | resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" 308 | integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== 309 | 310 | atomic-sleep@^1.0.0: 311 | version "1.0.0" 312 | resolved "https://registry.yarnpkg.com/atomic-sleep/-/atomic-sleep-1.0.0.tgz#eb85b77a601fc932cfe432c5acd364a9e2c9075b" 313 | integrity sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ== 314 | 315 | avvio@^8.3.0: 316 | version "8.4.0" 317 | resolved "https://registry.yarnpkg.com/avvio/-/avvio-8.4.0.tgz#7cbd5bca74f0c9effa944ced601f94ffd8afc5ed" 318 | integrity sha512-CDSwaxINFy59iNwhYnkvALBwZiTydGkOecZyPkqBpABYR1KqGEsET0VOOYDwtleZSUIdeY36DC2bSZ24CO1igA== 319 | dependencies: 320 | "@fastify/error" "^3.3.0" 321 | fastq "^1.17.1" 322 | 323 | await-lock@^2.2.2: 324 | version "2.2.2" 325 | resolved "https://registry.yarnpkg.com/await-lock/-/await-lock-2.2.2.tgz#a95a9b269bfd2f69d22b17a321686f551152bcef" 326 | integrity sha512-aDczADvlvTGajTDjcjpJMqRkOF6Qdz3YbPZm/PyW6tKPkx2hlYBzxMhEywM/tU72HrVZjgl5VCdRuMlA7pZ8Gw== 327 | 328 | base64-js@^1.3.1: 329 | version "1.5.1" 330 | resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" 331 | integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== 332 | 333 | bson@^6.7.0: 334 | version "6.8.0" 335 | resolved "https://registry.yarnpkg.com/bson/-/bson-6.8.0.tgz#5063c41ba2437c2b8ff851b50d9e36cb7aaa7525" 336 | integrity sha512-iOJg8pr7wq2tg/zSlCCHMi3hMm5JTOxLTagf3zxhcenHsFp+c6uOs6K7W5UE7A4QIJGtqh/ZovFNMP4mOPJynQ== 337 | 338 | buffer@^6.0.3: 339 | version "6.0.3" 340 | resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" 341 | integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== 342 | dependencies: 343 | base64-js "^1.3.1" 344 | ieee754 "^1.2.1" 345 | 346 | call-bind@^1.0.7: 347 | version "1.0.7" 348 | resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9" 349 | integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w== 350 | dependencies: 351 | es-define-property "^1.0.0" 352 | es-errors "^1.3.0" 353 | function-bind "^1.1.2" 354 | get-intrinsic "^1.2.4" 355 | set-function-length "^1.2.1" 356 | 357 | colorette@^2.0.7: 358 | version "2.0.20" 359 | resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" 360 | integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== 361 | 362 | combined-stream@^1.0.8: 363 | version "1.0.8" 364 | resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" 365 | integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== 366 | dependencies: 367 | delayed-stream "~1.0.0" 368 | 369 | cookie-signature@^1.1.0: 370 | version "1.2.1" 371 | resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.2.1.tgz#790dea2cce64638c7ae04d9fabed193bd7ccf3b4" 372 | integrity sha512-78KWk9T26NhzXtuL26cIJ8/qNHANyJ/ZYrmEXFzUmhZdjpBv+DlWlOANRTGBt48YcyslsLrj0bMLFTmXvLRCOw== 373 | 374 | cookie@^0.6.0: 375 | version "0.6.0" 376 | resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.6.0.tgz#2798b04b071b0ecbff0dbb62a505a8efa4e19051" 377 | integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw== 378 | 379 | dateformat@^4.6.3: 380 | version "4.6.3" 381 | resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-4.6.3.tgz#556fa6497e5217fedb78821424f8a1c22fa3f4b5" 382 | integrity sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA== 383 | 384 | debug@4.x: 385 | version "4.3.6" 386 | resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.6.tgz#2ab2c38fbaffebf8aa95fdfe6d88438c7a13c52b" 387 | integrity sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg== 388 | dependencies: 389 | ms "2.1.2" 390 | 391 | define-data-property@^1.1.4: 392 | version "1.1.4" 393 | resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e" 394 | integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A== 395 | dependencies: 396 | es-define-property "^1.0.0" 397 | es-errors "^1.3.0" 398 | gopd "^1.0.1" 399 | 400 | delayed-stream@~1.0.0: 401 | version "1.0.0" 402 | resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" 403 | integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== 404 | 405 | dotenv@^16.4.5: 406 | version "16.4.5" 407 | resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.5.tgz#cdd3b3b604cb327e286b4762e13502f717cb099f" 408 | integrity sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg== 409 | 410 | end-of-stream@^1.1.0: 411 | version "1.4.4" 412 | resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" 413 | integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== 414 | dependencies: 415 | once "^1.4.0" 416 | 417 | es-define-property@^1.0.0: 418 | version "1.0.0" 419 | resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845" 420 | integrity sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ== 421 | dependencies: 422 | get-intrinsic "^1.2.4" 423 | 424 | es-errors@^1.3.0: 425 | version "1.3.0" 426 | resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" 427 | integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== 428 | 429 | esbuild@~0.23.0: 430 | version "0.23.1" 431 | resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.23.1.tgz#40fdc3f9265ec0beae6f59824ade1bd3d3d2dab8" 432 | integrity sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg== 433 | optionalDependencies: 434 | "@esbuild/aix-ppc64" "0.23.1" 435 | "@esbuild/android-arm" "0.23.1" 436 | "@esbuild/android-arm64" "0.23.1" 437 | "@esbuild/android-x64" "0.23.1" 438 | "@esbuild/darwin-arm64" "0.23.1" 439 | "@esbuild/darwin-x64" "0.23.1" 440 | "@esbuild/freebsd-arm64" "0.23.1" 441 | "@esbuild/freebsd-x64" "0.23.1" 442 | "@esbuild/linux-arm" "0.23.1" 443 | "@esbuild/linux-arm64" "0.23.1" 444 | "@esbuild/linux-ia32" "0.23.1" 445 | "@esbuild/linux-loong64" "0.23.1" 446 | "@esbuild/linux-mips64el" "0.23.1" 447 | "@esbuild/linux-ppc64" "0.23.1" 448 | "@esbuild/linux-riscv64" "0.23.1" 449 | "@esbuild/linux-s390x" "0.23.1" 450 | "@esbuild/linux-x64" "0.23.1" 451 | "@esbuild/netbsd-x64" "0.23.1" 452 | "@esbuild/openbsd-arm64" "0.23.1" 453 | "@esbuild/openbsd-x64" "0.23.1" 454 | "@esbuild/sunos-x64" "0.23.1" 455 | "@esbuild/win32-arm64" "0.23.1" 456 | "@esbuild/win32-ia32" "0.23.1" 457 | "@esbuild/win32-x64" "0.23.1" 458 | 459 | event-target-shim@^5.0.0: 460 | version "5.0.1" 461 | resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" 462 | integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== 463 | 464 | events@^3.3.0: 465 | version "3.3.0" 466 | resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" 467 | integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== 468 | 469 | fast-content-type-parse@^1.1.0: 470 | version "1.1.0" 471 | resolved "https://registry.yarnpkg.com/fast-content-type-parse/-/fast-content-type-parse-1.1.0.tgz#4087162bf5af3294d4726ff29b334f72e3a1092c" 472 | integrity sha512-fBHHqSTFLVnR61C+gltJuE5GkVQMV0S2nqUO8TJ+5Z3qAKG8vAx4FKai1s5jq/inV1+sREynIWSuQ6HgoSXpDQ== 473 | 474 | fast-copy@^3.0.2: 475 | version "3.0.2" 476 | resolved "https://registry.yarnpkg.com/fast-copy/-/fast-copy-3.0.2.tgz#59c68f59ccbcac82050ba992e0d5c389097c9d35" 477 | integrity sha512-dl0O9Vhju8IrcLndv2eU4ldt1ftXMqqfgN4H1cpmGV7P6jeB9FwpN9a2c8DPGE1Ys88rNUJVYDHq73CGAGOPfQ== 478 | 479 | fast-decode-uri-component@^1.0.1: 480 | version "1.0.1" 481 | resolved "https://registry.yarnpkg.com/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz#46f8b6c22b30ff7a81357d4f59abfae938202543" 482 | integrity sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg== 483 | 484 | fast-deep-equal@^3.1.3: 485 | version "3.1.3" 486 | resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" 487 | integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== 488 | 489 | fast-json-stringify@^5.7.0, fast-json-stringify@^5.8.0: 490 | version "5.16.1" 491 | resolved "https://registry.yarnpkg.com/fast-json-stringify/-/fast-json-stringify-5.16.1.tgz#a6d0c575231a3a08c376a00171d757372f2ca46e" 492 | integrity sha512-KAdnLvy1yu/XrRtP+LJnxbBGrhN+xXu+gt3EUvZhYGKCr3lFHq/7UFJHHFgmJKoqlh6B40bZLEv7w46B0mqn1g== 493 | dependencies: 494 | "@fastify/merge-json-schemas" "^0.1.0" 495 | ajv "^8.10.0" 496 | ajv-formats "^3.0.1" 497 | fast-deep-equal "^3.1.3" 498 | fast-uri "^2.1.0" 499 | json-schema-ref-resolver "^1.0.1" 500 | rfdc "^1.2.0" 501 | 502 | fast-querystring@^1.0.0: 503 | version "1.1.2" 504 | resolved "https://registry.yarnpkg.com/fast-querystring/-/fast-querystring-1.1.2.tgz#a6d24937b4fc6f791b4ee31dcb6f53aeafb89f53" 505 | integrity sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg== 506 | dependencies: 507 | fast-decode-uri-component "^1.0.1" 508 | 509 | fast-redact@^3.1.1: 510 | version "3.5.0" 511 | resolved "https://registry.yarnpkg.com/fast-redact/-/fast-redact-3.5.0.tgz#e9ea02f7e57d0cd8438180083e93077e496285e4" 512 | integrity sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A== 513 | 514 | fast-safe-stringify@^2.1.1: 515 | version "2.1.1" 516 | resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz#c406a83b6e70d9e35ce3b30a81141df30aeba884" 517 | integrity sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA== 518 | 519 | fast-uri@^2.0.0, fast-uri@^2.1.0: 520 | version "2.4.0" 521 | resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-2.4.0.tgz#67eae6fbbe9f25339d5d3f4c4234787b65d7d55e" 522 | integrity sha512-ypuAmmMKInk5q7XcepxlnUWDLWv4GFtaJqAzWKqn62IpQ3pejtr5dTVbt3vwqVaMKmkNR55sTT+CqUKIaT21BA== 523 | 524 | fast-uri@^3.0.1: 525 | version "3.0.1" 526 | resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.0.1.tgz#cddd2eecfc83a71c1be2cc2ef2061331be8a7134" 527 | integrity sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw== 528 | 529 | fastify-plugin@^4.0.0: 530 | version "4.5.1" 531 | resolved "https://registry.yarnpkg.com/fastify-plugin/-/fastify-plugin-4.5.1.tgz#44dc6a3cc2cce0988bc09e13f160120bbd91dbee" 532 | integrity sha512-stRHYGeuqpEZTL1Ef0Ovr2ltazUT9g844X5z/zEBFLG8RYlpDiOCIG+ATvYEp+/zmc7sN29mcIMp8gvYplYPIQ== 533 | 534 | fastify@^4.28.1: 535 | version "4.28.1" 536 | resolved "https://registry.yarnpkg.com/fastify/-/fastify-4.28.1.tgz#39626dedf445d702ef03818da33064440b469cd1" 537 | integrity sha512-kFWUtpNr4i7t5vY2EJPCN2KgMVpuqfU4NjnJNCgiNB900oiDeYqaNDRcAfeBbOF5hGixixxcKnOU4KN9z6QncQ== 538 | dependencies: 539 | "@fastify/ajv-compiler" "^3.5.0" 540 | "@fastify/error" "^3.4.0" 541 | "@fastify/fast-json-stringify-compiler" "^4.3.0" 542 | abstract-logging "^2.0.1" 543 | avvio "^8.3.0" 544 | fast-content-type-parse "^1.1.0" 545 | fast-json-stringify "^5.8.0" 546 | find-my-way "^8.0.0" 547 | light-my-request "^5.11.0" 548 | pino "^9.0.0" 549 | process-warning "^3.0.0" 550 | proxy-addr "^2.0.7" 551 | rfdc "^1.3.0" 552 | secure-json-parse "^2.7.0" 553 | semver "^7.5.4" 554 | toad-cache "^3.3.0" 555 | 556 | fastq@^1.17.1: 557 | version "1.17.1" 558 | resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.17.1.tgz#2a523f07a4e7b1e81a42b91b8bf2254107753b47" 559 | integrity sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w== 560 | dependencies: 561 | reusify "^1.0.4" 562 | 563 | find-my-way@^8.0.0: 564 | version "8.2.0" 565 | resolved "https://registry.yarnpkg.com/find-my-way/-/find-my-way-8.2.0.tgz#ef1b83d008114a300118c9c707d8dc65947d9960" 566 | integrity sha512-HdWXgFYc6b1BJcOBDBwjqWuHJj1WYiqrxSh25qtU4DabpMFdj/gSunNBQb83t+8Zt67D7CXEzJWTkxaShMTMOA== 567 | dependencies: 568 | fast-deep-equal "^3.1.3" 569 | fast-querystring "^1.0.0" 570 | safe-regex2 "^3.1.0" 571 | 572 | form-data-encoder@1.7.2: 573 | version "1.7.2" 574 | resolved "https://registry.yarnpkg.com/form-data-encoder/-/form-data-encoder-1.7.2.tgz#1f1ae3dccf58ed4690b86d87e4f57c654fbab040" 575 | integrity sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A== 576 | 577 | form-data@^4.0.0: 578 | version "4.0.0" 579 | resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" 580 | integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== 581 | dependencies: 582 | asynckit "^0.4.0" 583 | combined-stream "^1.0.8" 584 | mime-types "^2.1.12" 585 | 586 | formdata-node@^4.3.2: 587 | version "4.4.1" 588 | resolved "https://registry.yarnpkg.com/formdata-node/-/formdata-node-4.4.1.tgz#23f6a5cb9cb55315912cbec4ff7b0f59bbd191e2" 589 | integrity sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ== 590 | dependencies: 591 | node-domexception "1.0.0" 592 | web-streams-polyfill "4.0.0-beta.3" 593 | 594 | forwarded@0.2.0: 595 | version "0.2.0" 596 | resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" 597 | integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== 598 | 599 | fsevents@~2.3.3: 600 | version "2.3.3" 601 | resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" 602 | integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== 603 | 604 | function-bind@^1.1.2: 605 | version "1.1.2" 606 | resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" 607 | integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== 608 | 609 | get-intrinsic@^1.1.3, get-intrinsic@^1.2.4: 610 | version "1.2.4" 611 | resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd" 612 | integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ== 613 | dependencies: 614 | es-errors "^1.3.0" 615 | function-bind "^1.1.2" 616 | has-proto "^1.0.1" 617 | has-symbols "^1.0.3" 618 | hasown "^2.0.0" 619 | 620 | get-tsconfig@^4.7.5: 621 | version "4.8.0" 622 | resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.8.0.tgz#125dc13a316f61650a12b20c97c11b8fd996fedd" 623 | integrity sha512-Pgba6TExTZ0FJAn1qkJAjIeKoDJ3CsI2ChuLohJnZl/tTU8MVrq3b+2t5UOPfRa4RMsorClBjJALkJUMjG1PAw== 624 | dependencies: 625 | resolve-pkg-maps "^1.0.0" 626 | 627 | gopd@^1.0.1: 628 | version "1.0.1" 629 | resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" 630 | integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== 631 | dependencies: 632 | get-intrinsic "^1.1.3" 633 | 634 | graphemer@^1.4.0: 635 | version "1.4.0" 636 | resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" 637 | integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== 638 | 639 | has-property-descriptors@^1.0.2: 640 | version "1.0.2" 641 | resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854" 642 | integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg== 643 | dependencies: 644 | es-define-property "^1.0.0" 645 | 646 | has-proto@^1.0.1: 647 | version "1.0.3" 648 | resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.3.tgz#b31ddfe9b0e6e9914536a6ab286426d0214f77fd" 649 | integrity sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q== 650 | 651 | has-symbols@^1.0.3: 652 | version "1.0.3" 653 | resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" 654 | integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== 655 | 656 | hasown@^2.0.0: 657 | version "2.0.2" 658 | resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" 659 | integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== 660 | dependencies: 661 | function-bind "^1.1.2" 662 | 663 | help-me@^5.0.0: 664 | version "5.0.0" 665 | resolved "https://registry.yarnpkg.com/help-me/-/help-me-5.0.0.tgz#b1ebe63b967b74060027c2ac61f9be12d354a6f6" 666 | integrity sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg== 667 | 668 | humanize-ms@^1.2.1: 669 | version "1.2.1" 670 | resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" 671 | integrity sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ== 672 | dependencies: 673 | ms "^2.0.0" 674 | 675 | ieee754@^1.2.1: 676 | version "1.2.1" 677 | resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" 678 | integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== 679 | 680 | ipaddr.js@1.9.1: 681 | version "1.9.1" 682 | resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" 683 | integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== 684 | 685 | iso-datestring-validator@^2.2.2: 686 | version "2.2.2" 687 | resolved "https://registry.yarnpkg.com/iso-datestring-validator/-/iso-datestring-validator-2.2.2.tgz#2daa80d2900b7a954f9f731d42f96ee0c19a6895" 688 | integrity sha512-yLEMkBbLZTlVQqOnQ4FiMujR6T4DEcCb1xizmvXS+OxuhwcbtynoosRzdMA69zZCShCNAbi+gJ71FxZBBXx1SA== 689 | 690 | joycon@^3.1.1: 691 | version "3.1.1" 692 | resolved "https://registry.yarnpkg.com/joycon/-/joycon-3.1.1.tgz#bce8596d6ae808f8b68168f5fc69280996894f03" 693 | integrity sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw== 694 | 695 | json-schema-ref-resolver@^1.0.1: 696 | version "1.0.1" 697 | resolved "https://registry.yarnpkg.com/json-schema-ref-resolver/-/json-schema-ref-resolver-1.0.1.tgz#6586f483b76254784fc1d2120f717bdc9f0a99bf" 698 | integrity sha512-EJAj1pgHc1hxF6vo2Z3s69fMjO1INq6eGHXZ8Z6wCQeldCuwxGK9Sxf4/cScGn3FZubCVUehfWtcDM/PLteCQw== 699 | dependencies: 700 | fast-deep-equal "^3.1.3" 701 | 702 | json-schema-traverse@^1.0.0: 703 | version "1.0.0" 704 | resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" 705 | integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== 706 | 707 | kareem@2.6.3: 708 | version "2.6.3" 709 | resolved "https://registry.yarnpkg.com/kareem/-/kareem-2.6.3.tgz#23168ec8ffb6c1abfd31b7169a6fb1dd285992ac" 710 | integrity sha512-C3iHfuGUXK2u8/ipq9LfjFfXFxAZMQJJq7vLS45r3D9Y2xQ/m4S8zaR4zMLFWh9AsNPXmcFfUDhTEO8UIC/V6Q== 711 | 712 | light-my-request@^5.11.0: 713 | version "5.13.0" 714 | resolved "https://registry.yarnpkg.com/light-my-request/-/light-my-request-5.13.0.tgz#b29905e55e8605b77fee2a946e17b219bca35113" 715 | integrity sha512-9IjUN9ZyCS9pTG+KqTDEQo68Sui2lHsYBrfMyVUTTZ3XhH8PMZq7xO94Kr+eP9dhi/kcKsx4N41p2IXEBil1pQ== 716 | dependencies: 717 | cookie "^0.6.0" 718 | process-warning "^3.0.0" 719 | set-cookie-parser "^2.4.1" 720 | 721 | memory-pager@^1.0.2: 722 | version "1.5.0" 723 | resolved "https://registry.yarnpkg.com/memory-pager/-/memory-pager-1.5.0.tgz#d8751655d22d384682741c972f2c3d6dfa3e66b5" 724 | integrity sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg== 725 | 726 | mime-db@1.52.0: 727 | version "1.52.0" 728 | resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" 729 | integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== 730 | 731 | mime-types@^2.1.12: 732 | version "2.1.35" 733 | resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" 734 | integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== 735 | dependencies: 736 | mime-db "1.52.0" 737 | 738 | minimist@^1.2.6: 739 | version "1.2.8" 740 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" 741 | integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== 742 | 743 | mongodb-connection-string-url@^3.0.0: 744 | version "3.0.1" 745 | resolved "https://registry.yarnpkg.com/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.1.tgz#c13e6ac284ae401752ebafdb8cd7f16c6723b141" 746 | integrity sha512-XqMGwRX0Lgn05TDB4PyG2h2kKO/FfWJyCzYQbIhXUxz7ETt0I/FqHjUeqj37irJ+Dl1ZtU82uYyj14u2XsZKfg== 747 | dependencies: 748 | "@types/whatwg-url" "^11.0.2" 749 | whatwg-url "^13.0.0" 750 | 751 | mongodb@6.8.0: 752 | version "6.8.0" 753 | resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-6.8.0.tgz#680450f113cdea6d2d9f7121fe57cd29111fd2ce" 754 | integrity sha512-HGQ9NWDle5WvwMnrvUxsFYPd3JEbqD3RgABHBQRuoCEND0qzhsd0iH5ypHsf1eJ+sXmvmyKpP+FLOKY8Il7jMw== 755 | dependencies: 756 | "@mongodb-js/saslprep" "^1.1.5" 757 | bson "^6.7.0" 758 | mongodb-connection-string-url "^3.0.0" 759 | 760 | mongoose@^8.6.0: 761 | version "8.6.0" 762 | resolved "https://registry.yarnpkg.com/mongoose/-/mongoose-8.6.0.tgz#52a7cc6026c4d49cd14e4a40e6601c44b1186e49" 763 | integrity sha512-p6VSbYKvD4ZIabqo8C0kS5eKX1Xpji+opTAIJ9wyuPJ8Y/FblgXSMnFRXnB40bYZLKPQT089K5KU8+bqIXtFdw== 764 | dependencies: 765 | bson "^6.7.0" 766 | kareem "2.6.3" 767 | mongodb "6.8.0" 768 | mpath "0.9.0" 769 | mquery "5.0.0" 770 | ms "2.1.3" 771 | sift "17.1.3" 772 | 773 | mpath@0.9.0: 774 | version "0.9.0" 775 | resolved "https://registry.yarnpkg.com/mpath/-/mpath-0.9.0.tgz#0c122fe107846e31fc58c75b09c35514b3871904" 776 | integrity sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew== 777 | 778 | mquery@5.0.0: 779 | version "5.0.0" 780 | resolved "https://registry.yarnpkg.com/mquery/-/mquery-5.0.0.tgz#a95be5dfc610b23862df34a47d3e5d60e110695d" 781 | integrity sha512-iQMncpmEK8R8ncT8HJGsGc9Dsp8xcgYMVSbs5jgnm1lFHTZqMJTUWTDx1LBO8+mK3tPNZWFLBghQEIOULSTHZg== 782 | dependencies: 783 | debug "4.x" 784 | 785 | ms@2.1.2: 786 | version "2.1.2" 787 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" 788 | integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== 789 | 790 | ms@2.1.3, ms@^2.0.0: 791 | version "2.1.3" 792 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" 793 | integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== 794 | 795 | multiformats@^9.4.2, multiformats@^9.9.0: 796 | version "9.9.0" 797 | resolved "https://registry.yarnpkg.com/multiformats/-/multiformats-9.9.0.tgz#c68354e7d21037a8f1f8833c8ccd68618e8f1d37" 798 | integrity sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg== 799 | 800 | node-domexception@1.0.0: 801 | version "1.0.0" 802 | resolved "https://registry.yarnpkg.com/node-domexception/-/node-domexception-1.0.0.tgz#6888db46a1f71c0b76b3f7555016b63fe64766e5" 803 | integrity sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ== 804 | 805 | node-fetch@^2.6.7: 806 | version "2.7.0" 807 | resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" 808 | integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== 809 | dependencies: 810 | whatwg-url "^5.0.0" 811 | 812 | object-inspect@^1.13.1: 813 | version "1.13.2" 814 | resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.2.tgz#dea0088467fb991e67af4058147a24824a3043ff" 815 | integrity sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g== 816 | 817 | on-exit-leak-free@^2.1.0: 818 | version "2.1.2" 819 | resolved "https://registry.yarnpkg.com/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz#fed195c9ebddb7d9e4c3842f93f281ac8dadd3b8" 820 | integrity sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA== 821 | 822 | once@^1.3.1, once@^1.4.0: 823 | version "1.4.0" 824 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 825 | integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== 826 | dependencies: 827 | wrappy "1" 828 | 829 | openai@^4.57.0: 830 | version "4.57.0" 831 | resolved "https://registry.yarnpkg.com/openai/-/openai-4.57.0.tgz#c1c735e9bbccf1fc42fdcfc9676643cad56258fe" 832 | integrity sha512-JnwBSIYqiZ3jYjB5f2in8hQ0PRA092c6m+/6dYB0MzK0BEbn+0dioxZsPLBm5idJbg9xzLNOiGVm2OSuhZ+BdQ== 833 | dependencies: 834 | "@types/node" "^18.11.18" 835 | "@types/node-fetch" "^2.6.4" 836 | "@types/qs" "^6.9.7" 837 | abort-controller "^3.0.0" 838 | agentkeepalive "^4.2.1" 839 | form-data-encoder "1.7.2" 840 | formdata-node "^4.3.2" 841 | node-fetch "^2.6.7" 842 | qs "^6.10.3" 843 | 844 | pino-abstract-transport@^1.0.0, pino-abstract-transport@^1.2.0: 845 | version "1.2.0" 846 | resolved "https://registry.yarnpkg.com/pino-abstract-transport/-/pino-abstract-transport-1.2.0.tgz#97f9f2631931e242da531b5c66d3079c12c9d1b5" 847 | integrity sha512-Guhh8EZfPCfH+PMXAb6rKOjGQEoy0xlAIn+irODG5kgfYV+BQ0rGYYWTIel3P5mmyXqkYkPmdIkywsn6QKUR1Q== 848 | dependencies: 849 | readable-stream "^4.0.0" 850 | split2 "^4.0.0" 851 | 852 | pino-pretty@^11.2.2: 853 | version "11.2.2" 854 | resolved "https://registry.yarnpkg.com/pino-pretty/-/pino-pretty-11.2.2.tgz#5e8ec69b31e90eb187715af07b1d29a544e60d39" 855 | integrity sha512-2FnyGir8nAJAqD3srROdrF1J5BIcMT4nwj7hHSc60El6Uxlym00UbCCd8pYIterstVBFlMyF1yFV8XdGIPbj4A== 856 | dependencies: 857 | colorette "^2.0.7" 858 | dateformat "^4.6.3" 859 | fast-copy "^3.0.2" 860 | fast-safe-stringify "^2.1.1" 861 | help-me "^5.0.0" 862 | joycon "^3.1.1" 863 | minimist "^1.2.6" 864 | on-exit-leak-free "^2.1.0" 865 | pino-abstract-transport "^1.0.0" 866 | pump "^3.0.0" 867 | readable-stream "^4.0.0" 868 | secure-json-parse "^2.4.0" 869 | sonic-boom "^4.0.1" 870 | strip-json-comments "^3.1.1" 871 | 872 | pino-std-serializers@^7.0.0: 873 | version "7.0.0" 874 | resolved "https://registry.yarnpkg.com/pino-std-serializers/-/pino-std-serializers-7.0.0.tgz#7c625038b13718dbbd84ab446bd673dc52259e3b" 875 | integrity sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA== 876 | 877 | pino@^9.0.0, pino@^9.3.2: 878 | version "9.3.2" 879 | resolved "https://registry.yarnpkg.com/pino/-/pino-9.3.2.tgz#a530d6d28f1d954b6f54416a218cbb616f52f901" 880 | integrity sha512-WtARBjgZ7LNEkrGWxMBN/jvlFiE17LTbBoH0konmBU684Kd0uIiDwBXlcTCW7iJnA6HfIKwUssS/2AC6cDEanw== 881 | dependencies: 882 | atomic-sleep "^1.0.0" 883 | fast-redact "^3.1.1" 884 | on-exit-leak-free "^2.1.0" 885 | pino-abstract-transport "^1.2.0" 886 | pino-std-serializers "^7.0.0" 887 | process-warning "^4.0.0" 888 | quick-format-unescaped "^4.0.3" 889 | real-require "^0.2.0" 890 | safe-stable-stringify "^2.3.1" 891 | sonic-boom "^4.0.1" 892 | thread-stream "^3.0.0" 893 | 894 | process-warning@^3.0.0: 895 | version "3.0.0" 896 | resolved "https://registry.yarnpkg.com/process-warning/-/process-warning-3.0.0.tgz#96e5b88884187a1dce6f5c3166d611132058710b" 897 | integrity sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ== 898 | 899 | process-warning@^4.0.0: 900 | version "4.0.0" 901 | resolved "https://registry.yarnpkg.com/process-warning/-/process-warning-4.0.0.tgz#581e3a7a1fb456c5f4fd239f76bce75897682d5a" 902 | integrity sha512-/MyYDxttz7DfGMMHiysAsFE4qF+pQYAA8ziO/3NcRVrQ5fSk+Mns4QZA/oRPFzvcqNoVJXQNWNAsdwBXLUkQKw== 903 | 904 | process@^0.11.10: 905 | version "0.11.10" 906 | resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" 907 | integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== 908 | 909 | proxy-addr@^2.0.7: 910 | version "2.0.7" 911 | resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" 912 | integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== 913 | dependencies: 914 | forwarded "0.2.0" 915 | ipaddr.js "1.9.1" 916 | 917 | pump@^3.0.0: 918 | version "3.0.0" 919 | resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" 920 | integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== 921 | dependencies: 922 | end-of-stream "^1.1.0" 923 | once "^1.3.1" 924 | 925 | punycode@^2.3.0: 926 | version "2.3.1" 927 | resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" 928 | integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== 929 | 930 | qs@^6.10.3: 931 | version "6.13.0" 932 | resolved "https://registry.yarnpkg.com/qs/-/qs-6.13.0.tgz#6ca3bd58439f7e245655798997787b0d88a51906" 933 | integrity sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg== 934 | dependencies: 935 | side-channel "^1.0.6" 936 | 937 | quick-format-unescaped@^4.0.3: 938 | version "4.0.4" 939 | resolved "https://registry.yarnpkg.com/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz#93ef6dd8d3453cbc7970dd614fad4c5954d6b5a7" 940 | integrity sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg== 941 | 942 | readable-stream@^4.0.0: 943 | version "4.5.2" 944 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-4.5.2.tgz#9e7fc4c45099baeed934bff6eb97ba6cf2729e09" 945 | integrity sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g== 946 | dependencies: 947 | abort-controller "^3.0.0" 948 | buffer "^6.0.3" 949 | events "^3.3.0" 950 | process "^0.11.10" 951 | string_decoder "^1.3.0" 952 | 953 | real-require@^0.2.0: 954 | version "0.2.0" 955 | resolved "https://registry.yarnpkg.com/real-require/-/real-require-0.2.0.tgz#209632dea1810be2ae063a6ac084fee7e33fba78" 956 | integrity sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg== 957 | 958 | require-from-string@^2.0.2: 959 | version "2.0.2" 960 | resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" 961 | integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== 962 | 963 | resolve-pkg-maps@^1.0.0: 964 | version "1.0.0" 965 | resolved "https://registry.yarnpkg.com/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz#616b3dc2c57056b5588c31cdf4b3d64db133720f" 966 | integrity sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw== 967 | 968 | ret@~0.4.0: 969 | version "0.4.3" 970 | resolved "https://registry.yarnpkg.com/ret/-/ret-0.4.3.tgz#5243fa30e704a2e78a9b9b1e86079e15891aa85c" 971 | integrity sha512-0f4Memo5QP7WQyUEAYUO3esD/XjOc3Zjjg5CPsAq1p8sIu0XPeMbHJemKA0BO7tV0X7+A0FoEpbmHXWxPyD3wQ== 972 | 973 | reusify@^1.0.4: 974 | version "1.0.4" 975 | resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" 976 | integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== 977 | 978 | rfdc@^1.2.0, rfdc@^1.3.0: 979 | version "1.4.1" 980 | resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.4.1.tgz#778f76c4fb731d93414e8f925fbecf64cce7f6ca" 981 | integrity sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA== 982 | 983 | safe-buffer@~5.2.0: 984 | version "5.2.1" 985 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" 986 | integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== 987 | 988 | safe-regex2@^3.1.0: 989 | version "3.1.0" 990 | resolved "https://registry.yarnpkg.com/safe-regex2/-/safe-regex2-3.1.0.tgz#fd7ec23908e2c730e1ce7359a5b72883a87d2763" 991 | integrity sha512-RAAZAGbap2kBfbVhvmnTFv73NWLMvDGOITFYTZBAaY8eR+Ir4ef7Up/e7amo+y1+AH+3PtLkrt9mvcTsG9LXug== 992 | dependencies: 993 | ret "~0.4.0" 994 | 995 | safe-stable-stringify@^2.3.1: 996 | version "2.5.0" 997 | resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz#4ca2f8e385f2831c432a719b108a3bf7af42a1dd" 998 | integrity sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA== 999 | 1000 | secure-json-parse@^2.4.0, secure-json-parse@^2.7.0: 1001 | version "2.7.0" 1002 | resolved "https://registry.yarnpkg.com/secure-json-parse/-/secure-json-parse-2.7.0.tgz#5a5f9cd6ae47df23dba3151edd06855d47e09862" 1003 | integrity sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw== 1004 | 1005 | semver@^7.5.4: 1006 | version "7.6.3" 1007 | resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" 1008 | integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== 1009 | 1010 | set-cookie-parser@^2.4.1: 1011 | version "2.7.0" 1012 | resolved "https://registry.yarnpkg.com/set-cookie-parser/-/set-cookie-parser-2.7.0.tgz#ef5552b56dc01baae102acb5fc9fb8cd060c30f9" 1013 | integrity sha512-lXLOiqpkUumhRdFF3k1osNXCy9akgx/dyPZ5p8qAg9seJzXr5ZrlqZuWIMuY6ejOsVLE6flJ5/h3lsn57fQ/PQ== 1014 | 1015 | set-function-length@^1.2.1: 1016 | version "1.2.2" 1017 | resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449" 1018 | integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg== 1019 | dependencies: 1020 | define-data-property "^1.1.4" 1021 | es-errors "^1.3.0" 1022 | function-bind "^1.1.2" 1023 | get-intrinsic "^1.2.4" 1024 | gopd "^1.0.1" 1025 | has-property-descriptors "^1.0.2" 1026 | 1027 | side-channel@^1.0.6: 1028 | version "1.0.6" 1029 | resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.6.tgz#abd25fb7cd24baf45466406b1096b7831c9215f2" 1030 | integrity sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA== 1031 | dependencies: 1032 | call-bind "^1.0.7" 1033 | es-errors "^1.3.0" 1034 | get-intrinsic "^1.2.4" 1035 | object-inspect "^1.13.1" 1036 | 1037 | sift@17.1.3: 1038 | version "17.1.3" 1039 | resolved "https://registry.yarnpkg.com/sift/-/sift-17.1.3.tgz#9d2000d4d41586880b0079b5183d839c7a142bf7" 1040 | integrity sha512-Rtlj66/b0ICeFzYTuNvX/EF1igRbbnGSvEyT79McoZa/DeGhMyC5pWKOEsZKnpkqtSeovd5FL/bjHWC3CIIvCQ== 1041 | 1042 | sonic-boom@^4.0.1: 1043 | version "4.0.1" 1044 | resolved "https://registry.yarnpkg.com/sonic-boom/-/sonic-boom-4.0.1.tgz#515b7cef2c9290cb362c4536388ddeece07aed30" 1045 | integrity sha512-hTSD/6JMLyT4r9zeof6UtuBDpjJ9sO08/nmS5djaA9eozT9oOlNdpXSnzcgj4FTqpk3nkLrs61l4gip9r1HCrQ== 1046 | dependencies: 1047 | atomic-sleep "^1.0.0" 1048 | 1049 | sparse-bitfield@^3.0.3: 1050 | version "3.0.3" 1051 | resolved "https://registry.yarnpkg.com/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz#ff4ae6e68656056ba4b3e792ab3334d38273ca11" 1052 | integrity sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ== 1053 | dependencies: 1054 | memory-pager "^1.0.2" 1055 | 1056 | split2@^4.0.0: 1057 | version "4.2.0" 1058 | resolved "https://registry.yarnpkg.com/split2/-/split2-4.2.0.tgz#c9c5920904d148bab0b9f67145f245a86aadbfa4" 1059 | integrity sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg== 1060 | 1061 | string_decoder@^1.3.0: 1062 | version "1.3.0" 1063 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" 1064 | integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== 1065 | dependencies: 1066 | safe-buffer "~5.2.0" 1067 | 1068 | strip-json-comments@^3.1.1: 1069 | version "3.1.1" 1070 | resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" 1071 | integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== 1072 | 1073 | thread-stream@^3.0.0: 1074 | version "3.1.0" 1075 | resolved "https://registry.yarnpkg.com/thread-stream/-/thread-stream-3.1.0.tgz#4b2ef252a7c215064507d4ef70c05a5e2d34c4f1" 1076 | integrity sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A== 1077 | dependencies: 1078 | real-require "^0.2.0" 1079 | 1080 | tlds@^1.234.0: 1081 | version "1.254.0" 1082 | resolved "https://registry.yarnpkg.com/tlds/-/tlds-1.254.0.tgz#7131955376f7c195d5edc0a94b4a203bc36668d0" 1083 | integrity sha512-YY4ei7K7gPGifqNSrfMaPdqTqiHcwYKUJ7zhLqQOK2ildlGgti5TSwJiXXN1YqG17I2GYZh5cZqv2r5fwBUM+w== 1084 | 1085 | toad-cache@^3.3.0: 1086 | version "3.7.0" 1087 | resolved "https://registry.yarnpkg.com/toad-cache/-/toad-cache-3.7.0.tgz#b9b63304ea7c45ec34d91f1d2fa513517025c441" 1088 | integrity sha512-/m8M+2BJUpoJdgAHoG+baCwBT+tf2VraSfkBgl0Y00qIWt41DJ8R5B8nsEw0I58YwF5IZH6z24/2TobDKnqSWw== 1089 | 1090 | tr46@^4.1.1: 1091 | version "4.1.1" 1092 | resolved "https://registry.yarnpkg.com/tr46/-/tr46-4.1.1.tgz#281a758dcc82aeb4fe38c7dfe4d11a395aac8469" 1093 | integrity sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw== 1094 | dependencies: 1095 | punycode "^2.3.0" 1096 | 1097 | tr46@~0.0.3: 1098 | version "0.0.3" 1099 | resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" 1100 | integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== 1101 | 1102 | tsx@^4.19.0: 1103 | version "4.19.0" 1104 | resolved "https://registry.yarnpkg.com/tsx/-/tsx-4.19.0.tgz#6166cb399b17d14d125e6158d23384045cfdf4f6" 1105 | integrity sha512-bV30kM7bsLZKZIOCHeMNVMJ32/LuJzLVajkQI/qf92J2Qr08ueLQvW00PUZGiuLPP760UINwupgUj8qrSCPUKg== 1106 | dependencies: 1107 | esbuild "~0.23.0" 1108 | get-tsconfig "^4.7.5" 1109 | optionalDependencies: 1110 | fsevents "~2.3.3" 1111 | 1112 | twitter-api-v2@^1.17.2: 1113 | version "1.17.2" 1114 | resolved "https://registry.yarnpkg.com/twitter-api-v2/-/twitter-api-v2-1.17.2.tgz#cee633a62511c48866d0c5bf1280ab4e3dfbb72b" 1115 | integrity sha512-V8QvCkuQ+ydIakwYbVC4cuQxGlvjdRZI0L7TT5v9zGsf+SwX40rv3IFRHB8Z1cXJLcRFT0FI3xG3/f4zwS6cRA== 1116 | 1117 | typescript@^5.5.4: 1118 | version "5.5.4" 1119 | resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.5.4.tgz#d9852d6c82bad2d2eda4fd74a5762a8f5909e9ba" 1120 | integrity sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q== 1121 | 1122 | uint8arrays@3.0.0: 1123 | version "3.0.0" 1124 | resolved "https://registry.yarnpkg.com/uint8arrays/-/uint8arrays-3.0.0.tgz#260869efb8422418b6f04e3fac73a3908175c63b" 1125 | integrity sha512-HRCx0q6O9Bfbp+HHSfQQKD7wU70+lydKVt4EghkdOvlK/NlrF90z+eXV34mUd48rNvVJXwkrMSPpCATkct8fJA== 1126 | dependencies: 1127 | multiformats "^9.4.2" 1128 | 1129 | undici-types@~5.26.4: 1130 | version "5.26.5" 1131 | resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" 1132 | integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== 1133 | 1134 | undici-types@~6.19.2: 1135 | version "6.19.8" 1136 | resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02" 1137 | integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw== 1138 | 1139 | web-streams-polyfill@4.0.0-beta.3: 1140 | version "4.0.0-beta.3" 1141 | resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz#2898486b74f5156095e473efe989dcf185047a38" 1142 | integrity sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug== 1143 | 1144 | webidl-conversions@^3.0.0: 1145 | version "3.0.1" 1146 | resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" 1147 | integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== 1148 | 1149 | webidl-conversions@^7.0.0: 1150 | version "7.0.0" 1151 | resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-7.0.0.tgz#256b4e1882be7debbf01d05f0aa2039778ea080a" 1152 | integrity sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g== 1153 | 1154 | whatwg-url@^13.0.0: 1155 | version "13.0.0" 1156 | resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-13.0.0.tgz#b7b536aca48306394a34e44bda8e99f332410f8f" 1157 | integrity sha512-9WWbymnqj57+XEuqADHrCJ2eSXzn8WXIW/YSGaZtb2WKAInQ6CHfaUUcTyyver0p8BDg5StLQq8h1vtZuwmOig== 1158 | dependencies: 1159 | tr46 "^4.1.1" 1160 | webidl-conversions "^7.0.0" 1161 | 1162 | whatwg-url@^5.0.0: 1163 | version "5.0.0" 1164 | resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" 1165 | integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== 1166 | dependencies: 1167 | tr46 "~0.0.3" 1168 | webidl-conversions "^3.0.0" 1169 | 1170 | wrappy@1: 1171 | version "1.0.2" 1172 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 1173 | integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== 1174 | 1175 | zod@^3.21.4, zod@^3.23.8: 1176 | version "3.23.8" 1177 | resolved "https://registry.yarnpkg.com/zod/-/zod-3.23.8.tgz#e37b957b5d52079769fb8097099b592f0ef4067d" 1178 | integrity sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g== 1179 | --------------------------------------------------------------------------------