├── packages ├── elysia-js │ ├── src │ │ ├── index.ts │ │ ├── global-logger.ts │ │ ├── types.ts │ │ ├── middleware.ts │ │ └── logger.ts │ ├── examples │ │ ├── basic-usage.ts │ │ ├── legacy-use-global.ts │ │ ├── advanced-usage.ts │ │ ├── custom-format.ts │ │ ├── separate-http-global.ts │ │ ├── basic.ts │ │ ├── global-logger.ts │ │ └── test-status-codes.ts │ ├── tsconfig.json │ ├── package.json │ ├── main.ts │ ├── CHANGELOG.md │ ├── README.md │ └── bun.lock └── express │ ├── src │ ├── index.ts │ ├── types.ts │ ├── global-logger.ts │ ├── middleware.ts │ └── logger.ts │ ├── tsconfig.json │ ├── examples │ ├── legacy-use-global.ts │ ├── separate-http-global.ts │ ├── basic.ts │ └── global-logger.ts │ ├── CHANGELOG.md │ ├── package.json │ ├── main.ts │ ├── README.md │ └── bun.lock ├── .gitignore ├── LICENSE.md └── README.md /packages/elysia-js/src/index.ts: -------------------------------------------------------------------------------- 1 | export { 2 | debug, 3 | error, 4 | getLogger, 5 | info, 6 | initializeLogger, 7 | warn, 8 | } from "./global-logger"; 9 | export * from "./logger"; 10 | export * from "./middleware"; 11 | export * from "./types"; 12 | -------------------------------------------------------------------------------- /packages/express/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './logger'; 2 | export * from './middleware'; 3 | export * from './types'; 4 | // Export global logger functions 5 | export { 6 | debug, error, getLogger, info, initializeLogger, warn 7 | } from './global-logger'; 8 | 9 | -------------------------------------------------------------------------------- /packages/elysia-js/examples/basic-usage.ts: -------------------------------------------------------------------------------- 1 | import { logger } from "@rasla/logify"; 2 | import { Elysia } from "elysia"; 3 | 4 | // Basic usage with default options 5 | const app = new Elysia() 6 | .use(logger()) 7 | .get("/", () => "Hello World!") 8 | .listen(3000); 9 | 10 | console.log( 11 | `🦊 Server is running at ${app.server?.hostname}:${app.server?.port}`, 12 | ); 13 | -------------------------------------------------------------------------------- /packages/express/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "module": "commonjs", 5 | "declaration": true, 6 | "outDir": "./dist", 7 | "strict": true, 8 | "esModuleInterop": true, 9 | "skipLibCheck": true, 10 | "forceConsistentCasingInFileNames": true, 11 | "moduleResolution": "node" 12 | }, 13 | "include": ["src"], 14 | "exclude": ["node_modules", "dist", "examples", "**/*.test.ts"] 15 | } 16 | -------------------------------------------------------------------------------- /packages/elysia-js/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "module": "ESNext", 5 | "moduleResolution": "node", 6 | "declaration": true, 7 | "declarationDir": "./dist", 8 | "emitDeclarationOnly": true, 9 | "outDir": "./dist", 10 | "strict": true, 11 | "esModuleInterop": true, 12 | "skipLibCheck": true, 13 | "forceConsistentCasingInFileNames": true 14 | }, 15 | "include": ["src"], 16 | "exclude": ["node_modules", "dist"] 17 | } 18 | -------------------------------------------------------------------------------- /packages/express/examples/legacy-use-global.ts: -------------------------------------------------------------------------------- 1 | import express, { Request, Response } from 'express'; 2 | import { info, logger } from '../src'; 3 | 4 | // Legacy / unified mode: middleware configures & uses the global logger (useGlobal: true) 5 | 6 | const app = express(); 7 | 8 | app.use(logger({ 9 | useGlobal: true, 10 | format: '[{timestamp}] {level} {method} {path} {statusCode} {duration}ms :: {message}', 11 | level: 'debug' 12 | })); 13 | 14 | app.get('/', (req: Request, res: Response) => { 15 | info('This log shares the same format as HTTP logs'); 16 | res.json({ legacy: true }); 17 | }); 18 | 19 | app.listen(3000, () => { 20 | console.log('Legacy unified logger example running on :3000'); 21 | }); 22 | -------------------------------------------------------------------------------- /packages/elysia-js/examples/legacy-use-global.ts: -------------------------------------------------------------------------------- 1 | import { Elysia } from "elysia"; 2 | import { info, logger } from "../src"; 3 | 4 | // Configure ONLY via middleware (legacy style) by passing useGlobal: true 5 | // This will cause the middleware to use the global logger rather than creating a dedicated HTTP logger. 6 | 7 | const app = new Elysia() 8 | .use( 9 | logger({ 10 | useGlobal: true, 11 | format: 12 | "[{timestamp}] {level} {method} {path} {statusCode} {duration}ms :: {message}", 13 | level: "debug", 14 | }) 15 | ) 16 | .get("/", () => { 17 | info("This log shares the same format as HTTP logs"); 18 | return { legacy: true }; 19 | }) 20 | .listen(3000); 21 | 22 | console.log(`Legacy unified logger example running on :${app.server?.port}`); 23 | -------------------------------------------------------------------------------- /packages/elysia-js/examples/advanced-usage.ts: -------------------------------------------------------------------------------- 1 | import { Elysia } from "elysia"; 2 | import { logger } from "@rasla/logify"; 3 | 4 | // Advanced usage with custom configuration 5 | const app = new Elysia() 6 | .use( 7 | logger({ 8 | console: true, 9 | file: true, 10 | filePath: "./logs/app.log", 11 | level: "debug", 12 | skip: ["/health", "/metrics"], 13 | includeIp: true, 14 | }), 15 | ) 16 | .get("/", () => "Hello World!") 17 | .get("/health", () => "OK") // This route will be skipped from logging 18 | .get("/metrics", () => ({ uptime: process.uptime() })) 19 | .get("/error", () => { 20 | throw new Error("Test error handling"); 21 | }) 22 | .listen(3000); 23 | 24 | console.log( 25 | `🦊 Server is running at ${app.server?.hostname}:${app.server?.port}`, 26 | ); 27 | -------------------------------------------------------------------------------- /packages/express/examples/separate-http-global.ts: -------------------------------------------------------------------------------- 1 | import express from 'express'; 2 | import { info, initializeLogger, logger } from '../src'; 3 | 4 | // Configure global logger for application/domain logs 5 | initializeLogger({ 6 | level: 'info', 7 | format: '[{timestamp}] {level}: {message}' 8 | }); 9 | 10 | const app = express(); 11 | 12 | // HTTP middleware uses its own logger instance (different format) 13 | app.use(logger({ 14 | format: '[{timestamp}] {level} {method} {path} {statusCode} | {duration}ms', 15 | level: 'info' 16 | })); 17 | 18 | app.get('/', (req, res) => { 19 | info('🚀 Express server started'); // Global format 20 | res.json({ status: 'ok' }); 21 | }); 22 | 23 | app.get('/users', (req, res) => { 24 | info('Fetching users (business log)'); 25 | res.json([{ id: 1, name: 'Alice' }]); 26 | }); 27 | 28 | app.listen(3000, () => { 29 | console.log('Separate HTTP vs Global logger example running on :3000'); 30 | }); 31 | -------------------------------------------------------------------------------- /packages/elysia-js/examples/custom-format.ts: -------------------------------------------------------------------------------- 1 | import { Elysia } from "elysia"; 2 | import { logger } from "@rasla/logify"; 3 | 4 | // Example with custom format and manual logging 5 | const app = new Elysia() 6 | .use( 7 | logger({ 8 | format: 9 | "🚀 {timestamp} | {level} | {method} {path} | Status: {statusCode} | Time: {duration}ms{ip}", 10 | includeIp: true, 11 | }), 12 | ) 13 | .get("/", ({ log }) => { 14 | // Manual logging examples 15 | log.debug("Debug message"); 16 | log.info("Info message"); 17 | log.warn("Warning message"); 18 | 19 | // Object-style logging 20 | log.info({ 21 | method: "CUSTOM", 22 | path: "/custom-action", 23 | statusCode: 200, 24 | duration: 50, 25 | message: "Custom action performed", 26 | }); 27 | 28 | return "Check your console for different log formats!"; 29 | }) 30 | .listen(3002); 31 | 32 | console.log( 33 | `🦊 Custom format example running at ${app.server?.hostname}:${app.server?.port}`, 34 | ); 35 | -------------------------------------------------------------------------------- /packages/elysia-js/examples/separate-http-global.ts: -------------------------------------------------------------------------------- 1 | import { Elysia } from "elysia"; 2 | import { info, initializeLogger, logger } from "../src"; 3 | 4 | // Global logger configuration for application/business logs ONLY 5 | initializeLogger({ 6 | level: "info", 7 | format: "[{timestamp}] {level}: {message}", 8 | }); 9 | 10 | const app = new Elysia() 11 | // HTTP middleware uses its OWN logger instance with a dedicated HTTP format 12 | .use( 13 | logger({ 14 | format: 15 | "[{timestamp}] {level} {method} {path} {statusCode} | Time: {duration}ms", 16 | level: "info", 17 | }) 18 | ) 19 | .get("/", () => { 20 | // This log is produced by the GLOBAL logger (different format) 21 | info("🚀 Elysia is running"); 22 | return { status: "ok" }; 23 | }) 24 | .get("/users", () => { 25 | info("Fetching users (business log)"); 26 | return [{ id: 1, name: "Alice" }]; 27 | }) 28 | .listen(3000); 29 | 30 | console.log( 31 | `HTTP logger vs Global logger example running on :${app.server?.port}` 32 | ); 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | node_modules/ 3 | .pnp/ 4 | .pnp.js 5 | 6 | # Production build 7 | dist/ 8 | build/ 9 | *.tsbuildinfo 10 | 11 | # Logs 12 | logs/ 13 | *.log 14 | npm-debug.log* 15 | yarn-debug.log* 16 | yarn-error.log* 17 | lerna-debug.log* 18 | 19 | # Runtime data 20 | pids 21 | *.pid 22 | *.seed 23 | *.pid.lock 24 | 25 | # Testing 26 | coverage/ 27 | .nyc_output/ 28 | 29 | # IDEs and editors 30 | .idea/ 31 | .project 32 | .classpath 33 | .c9/ 34 | *.launch 35 | .settings/ 36 | *.sublime-workspace 37 | .vscode/ 38 | 39 | # OS generated files 40 | .DS_Store 41 | .DS_Store? 42 | ._* 43 | .Spotlight-V100 44 | .Trashes 45 | ehthumbs.db 46 | Thumbs.db 47 | 48 | # Environment variables 49 | .env 50 | .env.local 51 | .env.development.local 52 | .env.test.local 53 | .env.production.local 54 | 55 | # Bun 56 | bun.lockb 57 | 58 | # Optional npm cache directory 59 | .npm 60 | 61 | # Optional eslint cache 62 | .eslintcache 63 | 64 | # Optional REPL history 65 | .node_repl_history 66 | 67 | # Output of 'npm pack' 68 | *.tgz 69 | 70 | # Yarn Integrity file 71 | .yarn-integrity -------------------------------------------------------------------------------- /packages/express/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this package will be documented in this file. 4 | 5 | The format is based on Keep a Changelog and this project adheres to Semantic Versioning. 6 | 7 | ## [1.1.0] - 2025-09-20 8 | 9 | ### Added 10 | - Middleware now uses a dedicated HTTP logger instance by default allowing a distinct global logger format (implements feature request #6 parity with Elysia version). 11 | - New option `useGlobal: true` to have the middleware use the global logger (legacy behaviour). 12 | 13 | ### Changed 14 | - Request duration now measured using `performance.now()` with 2 decimal precision for more accurate timings of fast responses. 15 | 16 | ### Notes 17 | - If you previously relied on passing formatting options to `logger()` to configure the global logger, call `initializeLogger()` separately or set `useGlobal: true`. 18 | 19 | ## [1.0.0] - 2025-09-?? 20 | - Initial release. 21 | 22 | [1.1.0]: https://github.com/0xrasla/logify/releases/tag/express-v1.1.0 23 | [1.0.0]: https://github.com/0xrasla/logify/releases/tag/express-v1.0.0 24 | -------------------------------------------------------------------------------- /packages/elysia-js/examples/basic.ts: -------------------------------------------------------------------------------- 1 | import { Elysia } from "elysia"; 2 | import { logger } from "../src"; 3 | 4 | const app = new Elysia() 5 | .use( 6 | logger({ 7 | // Enable both console and file logging 8 | console: true, 9 | file: true, 10 | filePath: "./logs/app.log", 11 | 12 | // Include IP address 13 | includeIp: true, 14 | 15 | // Custom format 16 | format: 17 | "[{timestamp}] {level} [{method}] {path} - {statusCode} {duration}ms - {ip}", 18 | }), 19 | ) 20 | // Basic routes 21 | .get("/", () => "Hello World!") 22 | 23 | // Async route with delay 24 | .get("/slow", async () => { 25 | await new Promise((resolve) => setTimeout(resolve, 1000)); 26 | return "Slow response"; 27 | }) 28 | 29 | // Route with error 30 | .get("/error", () => { 31 | throw new Error("Something went wrong"); 32 | }) 33 | 34 | // Route with params 35 | .get("/users/:id", ({ params: { id } }) => ({ id })) 36 | 37 | // POST route 38 | .post("/users", ({ body }) => ({ created: true, body })); 39 | 40 | // Start server 41 | app.listen(3000); 42 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Logify Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/express/examples/basic.ts: -------------------------------------------------------------------------------- 1 | import express from 'express'; 2 | import { logger } from '../src'; 3 | 4 | const app = express(); 5 | 6 | // Use logger middleware with custom configuration 7 | app.use(logger({ 8 | console: true, 9 | file: true, 10 | filePath: './logs/app.log', 11 | includeIp: true, 12 | format: '[{timestamp}] {level} [{method}] {path} - {statusCode} {duration}ms{ip}', 13 | })); 14 | 15 | // Basic routes 16 | app.get('/', (req, res) => { 17 | res.send('Hello World!'); 18 | }); 19 | 20 | // Async route with delay 21 | app.get('/slow', async (req, res) => { 22 | await new Promise(resolve => setTimeout(resolve, 1000)); 23 | res.send('Slow response'); 24 | }); 25 | 26 | // Route with error 27 | app.get('/error', (req, res) => { 28 | throw new Error('Something went wrong'); 29 | }); 30 | 31 | // Route with params 32 | app.get('/users/:id', (req, res) => { 33 | res.json({ id: req.params.id }); 34 | }); 35 | 36 | // POST route 37 | app.post('/users', express.json(), (req, res) => { 38 | res.json({ created: true, body: req.body }); 39 | }); 40 | 41 | // Start server 42 | const PORT = process.env.PORT || 3000; 43 | app.listen(PORT, () => { 44 | console.log(`🚀 Server is running at http://localhost:${PORT}`); 45 | }); 46 | -------------------------------------------------------------------------------- /packages/express/src/types.ts: -------------------------------------------------------------------------------- 1 | export type LogLevel = 'debug' | 'info' | 'warn' | 'error'; 2 | 3 | export interface LogEntry { 4 | timestamp: Date; 5 | level: LogLevel; 6 | method: string; 7 | path: string; 8 | statusCode: number; 9 | duration: number; 10 | message: string; 11 | ip?: string; 12 | /** Internal flag to differentiate HTTP logs */ 13 | isHttp?: boolean; 14 | } 15 | 16 | export interface LoggerOptions { 17 | /** Enable console logging (default: true) */ 18 | console?: boolean; 19 | /** Enable file logging (default: false) */ 20 | file?: boolean; 21 | /** File path for logging (required if file is true) */ 22 | filePath?: string; 23 | /** Log level (default: "info") */ 24 | level?: LogLevel; 25 | /** Paths to skip from logging */ 26 | skip?: string[]; 27 | /** Include IP address in logs (default: false) */ 28 | includeIp?: boolean; 29 | /** Custom log format */ 30 | format?: string; 31 | /** When true, middleware uses the global logger instead of creating a dedicated HTTP logger */ 32 | useGlobal?: boolean; 33 | } 34 | 35 | export interface ILogger { 36 | /** Log a debug message */ 37 | debug(input: string | Partial): void; 38 | /** Log an info message */ 39 | info(input: string | Partial): void; 40 | /** Log a warning message */ 41 | warn(input: string | Partial): void; 42 | /** Log an error message */ 43 | error(input: string | Partial): void; 44 | /** Log a message with a specific level */ 45 | log(level: LogLevel, input: string | Partial): void; 46 | } 47 | -------------------------------------------------------------------------------- /packages/express/src/global-logger.ts: -------------------------------------------------------------------------------- 1 | import { Logger } from './logger'; 2 | import { ILogger, LoggerOptions } from './types'; 3 | 4 | /** 5 | * Global logger instance that can be accessed from anywhere in the application 6 | */ 7 | let globalLogger: ILogger; 8 | 9 | /** 10 | * Initialize the global logger with the provided options 11 | * 12 | * @param options Logger configuration options 13 | * @returns The configured logger instance 14 | */ 15 | export function initializeLogger(options: LoggerOptions = {}): ILogger { 16 | globalLogger = new Logger(options); 17 | return globalLogger; 18 | } 19 | 20 | /** 21 | * Get the global logger instance 22 | * If the logger hasn't been initialized, it will be created with default options 23 | * 24 | * @returns The global logger instance 25 | */ 26 | export function getLogger(): ILogger { 27 | if (!globalLogger) { 28 | globalLogger = new Logger(); 29 | } 30 | return globalLogger; 31 | } 32 | 33 | /** 34 | * Global debug log method 35 | * @param input Log message or log entry 36 | */ 37 | export function debug(input: string | Partial[0]>): void { 38 | getLogger().debug(input); 39 | } 40 | 41 | /** 42 | * Global info log method 43 | * @param input Log message or log entry 44 | */ 45 | export function info(input: string | Partial[0]>): void { 46 | getLogger().info(input); 47 | } 48 | 49 | /** 50 | * Global warn log method 51 | * @param input Log message or log entry 52 | */ 53 | export function warn(input: string | Partial[0]>): void { 54 | getLogger().warn(input); 55 | } 56 | 57 | /** 58 | * Global error log method 59 | * @param input Log message or log entry 60 | */ 61 | export function error(input: string | Partial[0]>): void { 62 | getLogger().error(input); 63 | } -------------------------------------------------------------------------------- /packages/elysia-js/examples/global-logger.ts: -------------------------------------------------------------------------------- 1 | import { Elysia } from "elysia"; 2 | import { debug, error, info, initializeLogger, logger, warn } from "../src"; 3 | 4 | // Initialize the global logger with custom options 5 | initializeLogger({ 6 | level: "debug", // Set minimum log level to debug to see all logs 7 | console: true, 8 | file: true, 9 | filePath: "./logs/app.log", 10 | includeIp: true, 11 | format: "[{timestamp}] {level} - {message} - {method} {path}{ip}", 12 | }); 13 | 14 | // Now the global logger is configured and can be used anywhere in the app 15 | 16 | const app = new Elysia() 17 | .use(logger()) // The middleware uses the already configured global logger 18 | .get("/", () => { 19 | // Using global logger functions directly in route handlers 20 | debug("Processing root route request"); 21 | return "Hello World!"; 22 | }) 23 | .get("/debug", () => { 24 | debug("This is a debug message"); 25 | return "Check your console for the debug message"; 26 | }) 27 | .get("/info", () => { 28 | info("This is an info message"); 29 | return "Check your console for the info message"; 30 | }) 31 | .get("/warn", () => { 32 | warn("This is a warning message"); 33 | return "Check your console for the warning message"; 34 | }) 35 | .get("/error", () => { 36 | error("This is an error message"); 37 | return "Check your console for the error message"; 38 | }) 39 | .get("/custom", () => { 40 | // You can also pass objects with custom fields 41 | info({ 42 | message: "Custom log entry", 43 | path: "/custom-path", 44 | method: "CUSTOM", 45 | statusCode: 201, 46 | duration: 150, 47 | }); 48 | return "Custom log entry recorded"; 49 | }) 50 | .listen(3000); 51 | 52 | console.log( 53 | `🦊 Server is running at ${app.server?.hostname}:${app.server?.port}` 54 | ); 55 | -------------------------------------------------------------------------------- /packages/express/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@rasla/express-logify", 3 | "version": "1.1.0", 4 | "description": "A beautiful, fast, and type-safe logging middleware for Express.js applications", 5 | "main": "dist/index.js", 6 | "types": "dist/index.d.ts", 7 | "files": [ 8 | "dist", 9 | "LICENSE.md", 10 | "README.md" 11 | ], 12 | "scripts": { 13 | "build": "tsc", 14 | "dev": "ts-node-dev --respawn --transpile-only src/index.ts", 15 | "format": "prettier --write \"src/**/*.ts\" \"examples/**/*.ts\"", 16 | "lint": "eslint \"src/**/*.ts\" --fix", 17 | "test": "jest", 18 | "prepare": "npm run build" 19 | }, 20 | "keywords": [ 21 | "express", 22 | "logger", 23 | "middleware", 24 | "logging", 25 | "typescript", 26 | "console-log", 27 | "file-log", 28 | "http-logger" 29 | ], 30 | "author": { 31 | "name": "0xRasla", 32 | "email": "programmer.rasla@gmail.com", 33 | "url": "https://github.com/0xRasla" 34 | }, 35 | "repository": { 36 | "type": "git", 37 | "url": "git+https://github.com/0xRasla/logify.git" 38 | }, 39 | "bugs": { 40 | "url": "https://github.com/0xRasla/logify/issues" 41 | }, 42 | "homepage": "https://github.com/0xRasla/logify#readme", 43 | "license": "MIT", 44 | "dependencies": { 45 | "chalk": "^4.1.2", 46 | "express": "^4.18.2" 47 | }, 48 | "devDependencies": { 49 | "@types/express": "^4.17.21", 50 | "@types/node": "^20.10.5", 51 | "@typescript-eslint/eslint-plugin": "^6.15.0", 52 | "@typescript-eslint/parser": "^6.15.0", 53 | "eslint": "^8.56.0", 54 | "prettier": "^3.1.1", 55 | "ts-node-dev": "^2.0.0", 56 | "typescript": "^5.3.3" 57 | }, 58 | "peerDependencies": { 59 | "express": ">=4.17.1" 60 | }, 61 | "engines": { 62 | "node": ">=16.0.0" 63 | }, 64 | "publishConfig": { 65 | "access": "public" 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /packages/elysia-js/src/global-logger.ts: -------------------------------------------------------------------------------- 1 | import { Logger } from "./logger"; 2 | import { ILogger, LoggerOptions } from "./types"; 3 | 4 | /** 5 | * Global logger instance that can be accessed from anywhere in the application 6 | */ 7 | let globalLogger: ILogger; 8 | 9 | /** 10 | * Initialize the global logger with the provided options 11 | * 12 | * @param options Logger configuration options 13 | * @returns The configured logger instance 14 | */ 15 | export function initializeLogger(options: LoggerOptions = {}): ILogger { 16 | globalLogger = new Logger(options); 17 | return globalLogger; 18 | } 19 | 20 | /** 21 | * Get the global logger instance 22 | * If the logger hasn't been initialized, it will be created with default options 23 | * 24 | * @returns The global logger instance 25 | */ 26 | export function getLogger(): ILogger { 27 | if (!globalLogger) { 28 | globalLogger = new Logger(); 29 | } 30 | return globalLogger; 31 | } 32 | 33 | /** 34 | * Global debug log method 35 | * @param input Log message or log entry 36 | */ 37 | export function debug( 38 | input: string | Partial[0]>, 39 | ): void { 40 | getLogger().debug(input); 41 | } 42 | 43 | /** 44 | * Global info log method 45 | * @param input Log message or log entry 46 | */ 47 | export function info( 48 | input: string | Partial[0]>, 49 | ): void { 50 | getLogger().info(input); 51 | } 52 | 53 | /** 54 | * Global warn log method 55 | * @param input Log message or log entry 56 | */ 57 | export function warn( 58 | input: string | Partial[0]>, 59 | ): void { 60 | getLogger().warn(input); 61 | } 62 | 63 | /** 64 | * Global error log method 65 | * @param input Log message or log entry 66 | */ 67 | export function error( 68 | input: string | Partial[0]>, 69 | ): void { 70 | getLogger().error(input); 71 | } 72 | -------------------------------------------------------------------------------- /packages/elysia-js/src/types.ts: -------------------------------------------------------------------------------- 1 | export interface LoggerOptions { 2 | /** Enable console logging (default: true) */ 3 | console?: boolean; 4 | /** Enable file logging (default: false) */ 5 | file?: boolean; 6 | /** File path for logs (default: './logs/app.log') */ 7 | filePath?: string; 8 | /** Minimum log level (default: 'info') */ 9 | level?: LogLevel; 10 | /** Custom format for log messages */ 11 | format?: string; 12 | /** Paths to skip from logging */ 13 | skip?: string[]; 14 | /** Include IP address in logs (default: false) */ 15 | includeIp?: boolean; 16 | /** When true, middleware uses the global logger instead of creating a dedicated HTTP logger */ 17 | useGlobal?: boolean; 18 | } 19 | 20 | export type LogLevel = "debug" | "info" | "warn" | "error"; 21 | 22 | export interface LogEntry { 23 | /** Timestamp of the log entry */ 24 | timestamp: Date; 25 | /** Log level */ 26 | level: LogLevel; 27 | /** HTTP method or custom identifier */ 28 | method: string; 29 | /** Request path or log context */ 30 | path: string; 31 | /** HTTP status code */ 32 | statusCode: number; 33 | /** Request duration in milliseconds */ 34 | duration: number; 35 | /** Optional message */ 36 | message?: string; 37 | /** IP address if available and enabled */ 38 | ip?: string; 39 | /** Internal flag to differentiate HTTP logs (not exposed) */ 40 | isHttp?: boolean; 41 | } 42 | 43 | export interface ILogger { 44 | /** Log a debug message */ 45 | debug(input: string | Partial): void; 46 | /** Log an info message */ 47 | info(input: string | Partial): void; 48 | /** Log a warning message */ 49 | warn(input: string | Partial): void; 50 | /** Log an error message */ 51 | error(input: string | Partial): void; 52 | /** Log a message with a specific level */ 53 | log(level: LogLevel, input: string | Partial): void; 54 | } 55 | -------------------------------------------------------------------------------- /packages/express/src/middleware.ts: -------------------------------------------------------------------------------- 1 | import { NextFunction, Request, Response } from "express"; 2 | import { getLogger } from "./global-logger"; 3 | import { Logger } from "./logger"; 4 | import { LoggerOptions } from "./types"; 5 | 6 | export function logger(options: LoggerOptions = {}) { 7 | const useGlobal = (options as any).useGlobal === true; 8 | const httpLogger = useGlobal ? getLogger() : new Logger(options); 9 | 10 | return (req: Request, res: Response, next: NextFunction) => { 11 | // Skip logging for specified paths 12 | if (options.skip?.includes(req.path)) { 13 | return next(); 14 | } 15 | 16 | const startTime = performance.now(); 17 | 18 | // Get IP address 19 | const ip = 20 | (req.headers["x-forwarded-for"] as string) || 21 | req.socket.remoteAddress || 22 | ""; 23 | 24 | // Store the original end function 25 | const originalEnd = res.end; 26 | 27 | // Override end function to capture response 28 | res.end = function ( 29 | chunk: any, 30 | encoding?: string | (() => void), 31 | cb?: () => void 32 | ) { 33 | const duration = Number((performance.now() - startTime).toFixed(2)); 34 | 35 | httpLogger.info({ 36 | method: req.method, 37 | path: req.path, 38 | statusCode: res.statusCode, 39 | duration, 40 | ip, 41 | message: `${req.method} ${req.path}`, 42 | }); 43 | 44 | if (typeof encoding === "function") { 45 | // @ts-ignore 46 | return originalEnd.call(this, chunk, encoding); 47 | } 48 | // @ts-ignore 49 | return originalEnd.call(this, chunk, encoding, cb); 50 | } as any; // Type assertion needed due to complex express types 51 | 52 | // Error handling 53 | res.on("error", (error: Error) => { 54 | const duration = Number((performance.now() - startTime).toFixed(2)); 55 | 56 | httpLogger.error({ 57 | method: req.method, 58 | path: req.path, 59 | statusCode: res.statusCode, 60 | duration, 61 | ip, 62 | message: error.message, 63 | }); 64 | }); 65 | 66 | next(); 67 | }; 68 | } 69 | -------------------------------------------------------------------------------- /packages/elysia-js/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@rasla/logify", 3 | "version": "5.1.2", 4 | "description": "A lightweight, flexible, and easy-to-use logging middleware for Elysia.js applications", 5 | "main": "dist/index.js", 6 | "module": "dist/index.mjs", 7 | "types": "dist/index.d.ts", 8 | "files": [ 9 | "dist", 10 | "LICENSE.md", 11 | "README.md" 12 | ], 13 | "scripts": { 14 | "start": "bun run main.ts", 15 | "typecheck": "tsc", 16 | "build:types": "tsc --emitDeclarationOnly", 17 | "build:js": "bun build ./src/index.ts --outdir=dist --target=node", 18 | "build": "bun run build:types && bun run build:js", 19 | "dev": "bun run --watch main.ts", 20 | "prepublishOnly": "bun run build", 21 | "format": "prettier --write \"src/**/*.ts\" \"examples/**/*.ts\"", 22 | "lint": "eslint \"src/**/*.ts\" --fix", 23 | "test": "bun test", 24 | "bundle": "tar -czf logify-elysia-v5.1.2.tar.gz dist/ package.json README.md LICENSE.md" 25 | }, 26 | "keywords": [ 27 | "elysia", 28 | "logger", 29 | "middleware", 30 | "logging", 31 | "bun", 32 | "typescript", 33 | "console-log", 34 | "file-log", 35 | "http-logger" 36 | ], 37 | "author": { 38 | "name": "0xRasla", 39 | "email": "programmer.rasla@gmail.com", 40 | "url": "https://github.com/0xRasla" 41 | }, 42 | "repository": { 43 | "type": "git", 44 | "url": "git+https://github.com/0xRasla/logify.git" 45 | }, 46 | "bugs": { 47 | "url": "https://github.com/0xRasla/logify/issues" 48 | }, 49 | "homepage": "https://github.com/0xRasla/logify#readme", 50 | "license": "MIT", 51 | "dependencies": { 52 | "chalk": "^5.6.2", 53 | "elysia": "^1.4.6" 54 | }, 55 | "devDependencies": { 56 | "@types/node": "^24.5.2", 57 | "@types/bun": "^1.2.22", 58 | "@typescript-eslint/eslint-plugin": "^8.44.0", 59 | "@typescript-eslint/parser": "^8.44.0", 60 | "eslint": "^9.36.0", 61 | "prettier": "^3.6.2", 62 | "typescript": "^5.9.2" 63 | }, 64 | "peerDependencies": { 65 | "elysia": ">=0.7.0" 66 | }, 67 | "engines": { 68 | "node": ">=16.0.0", 69 | "bun": ">=1.0.0" 70 | }, 71 | "publishConfig": { 72 | "access": "public" 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /packages/express/main.ts: -------------------------------------------------------------------------------- 1 | import Express from "express"; 2 | import { debug, error, info, initializeLogger, logger, warn } from "./src"; 3 | 4 | // Initialize the global logger with custom configuration 5 | initializeLogger({ 6 | file: true, 7 | filePath: "./logs/app.log", 8 | includeIp: true, 9 | level: "debug", // Set to 'debug' to see all log levels 10 | format: "[{timestamp}] {level} {method} {path} {statusCode} {duration}ms{ip}", 11 | }); 12 | 13 | const app = Express(); 14 | 15 | // Use the logger middleware (which now uses the global configuration) 16 | app.use(logger()); 17 | 18 | // Example routes that demonstrate different log levels 19 | app.get("/", (req, res) => { 20 | debug("Processing request to the root endpoint"); 21 | info("Hello World endpoint called"); 22 | res.send("Hello World!"); 23 | }); 24 | 25 | app.get("/debug", (req, res) => { 26 | debug("This is a debug message"); 27 | res.send("Check your console for the debug message"); 28 | }); 29 | 30 | app.get("/info", (req, res) => { 31 | info("This is an info message"); 32 | res.send("Check your console for the info message"); 33 | }); 34 | 35 | app.get("/warn", (req, res) => { 36 | warn("This is a warning message"); 37 | res.send("Check your console for the warning message"); 38 | }); 39 | 40 | app.get("/error", (req, res) => { 41 | error("This is an error message"); 42 | res.send("Check your console for the error message"); 43 | }); 44 | 45 | app.get("/performance-issue", (req, res) => { 46 | debug("Starting intensive operation"); 47 | 48 | // Log before the intensive operation 49 | info("Starting intensive calculation"); 50 | 51 | // Simulate an intensive operation 52 | const start = Date.now(); 53 | for (let i = 0; i < 1000000; i++) { 54 | // Heavy computation simulation 55 | Math.sqrt(i); 56 | } 57 | const duration = Date.now() - start; 58 | 59 | // Log after the intensive operation with timing 60 | warn( 61 | `Intensive operation completed in ${duration}ms - performance may be affected` 62 | ); 63 | 64 | res.send(`Intensive operation completed in ${duration}ms`); 65 | }); 66 | 67 | // Error handling 68 | app.use( 69 | ( 70 | err: Error, 71 | req: Express.Request, 72 | res: Express.Response, 73 | next: Express.NextFunction 74 | ) => { 75 | error(`Error handler caught: ${err.message}`); 76 | res.status(500).send("An error occurred"); 77 | } 78 | ); 79 | 80 | app.listen(3000, () => { 81 | console.log("Server started on port 3000"); 82 | info(`Server started at http://localhost:3000`); 83 | }); 84 | -------------------------------------------------------------------------------- /packages/elysia-js/main.ts: -------------------------------------------------------------------------------- 1 | import { Elysia } from "elysia"; 2 | import { debug, error, info, initializeLogger, logger, warn } from "./src"; 3 | 4 | // Initialize the global logger with custom configuration 5 | initializeLogger({ 6 | file: true, 7 | filePath: "./logs/app.log", 8 | includeIp: true, 9 | level: "debug", // Set to 'debug' to see all log levels 10 | format: "[{timestamp}] {level} {method} {path} {statusCode} {duration}ms{ip}", 11 | }); 12 | 13 | const app = new Elysia(); 14 | 15 | // Use the logger middleware (which now uses the global configuration) 16 | app.use(logger()); 17 | 18 | app.get("/", () => { 19 | debug("Processing request to the root endpoint"); 20 | info("Hello World endpoint called"); 21 | return "Hello World!"; 22 | }); 23 | 24 | app.get("/debug", () => { 25 | debug("This is a debug message"); 26 | return "Check your console for the debug message"; 27 | }); 28 | 29 | app.get("/info", () => { 30 | info("This is an info message"); 31 | return "Check your console for the info message"; 32 | }); 33 | 34 | app.get("/warn", () => { 35 | warn("This is a warning message"); 36 | return "Check your console for the warning message"; 37 | }); 38 | 39 | app.get("/error", () => { 40 | error("This is an error message"); 41 | return "Check your console for the error message"; 42 | }); 43 | 44 | app.get("/performance-issue", () => { 45 | debug("Starting intensive operation"); 46 | 47 | // Log before the intensive operation 48 | info("Starting intensive calculation"); 49 | 50 | // Simulate an intensive operation 51 | const start = Date.now(); 52 | for (let i = 0; i < 1000000; i++) { 53 | // Heavy computation simulation 54 | Math.sqrt(i); 55 | } 56 | const duration = Date.now() - start; 57 | 58 | // Log after the intensive operation with timing 59 | warn( 60 | `Intensive operation completed in ${duration}ms - performance may be affected` 61 | ); 62 | 63 | return `Intensive operation completed in ${duration}ms`; 64 | }); 65 | 66 | app.get("/custom", () => { 67 | // You can also pass objects with custom fields 68 | console.log("Custom log entry started"); 69 | info({ 70 | message: "Custom log entry", 71 | method: "CUSTOM", 72 | statusCode: 200, 73 | duration: 150, 74 | }); 75 | console.log("Custom log entry recorded"); 76 | return "Custom log entry recorded"; 77 | }); 78 | 79 | app.listen(3000, () => { 80 | console.log( 81 | `🦊 Server is running at ${app.server?.hostname}:${app.server?.port}` 82 | ); 83 | info(`Server started at http://${app.server?.hostname}:${app.server?.port}`); 84 | }); 85 | -------------------------------------------------------------------------------- /packages/elysia-js/examples/test-status-codes.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Test script to verify status code logging is working correctly. 3 | * This tests the fix for issue #9: https://github.com/0xrasla/logify/issues/9 4 | * 5 | * Run with: bun run examples/test-status-codes.ts 6 | */ 7 | 8 | import { Elysia, t } from "elysia"; 9 | import { logger } from "../src"; 10 | 11 | const app = new Elysia() 12 | .use(logger()) 13 | // 200 - Success 14 | .get("/", () => "Hello Elysia") 15 | 16 | // 200 - JSON response 17 | .get("/json", () => ({ message: "Hello JSON" })) 18 | 19 | // 404 - Using status helper 20 | .get("/not-found", ({ status }) => { 21 | return status(404, "Resource not found"); 22 | }) 23 | 24 | // 500 - Using status helper (the main bug from issue #9) 25 | .get("/error-status", ({ status }) => { 26 | return status(500, "Internal server error"); 27 | }) 28 | 29 | // 400 - Bad request using status helper 30 | .get("/bad-request", ({ status }) => { 31 | return status(400, "Bad request"); 32 | }) 33 | 34 | // 201 - Created using status helper 35 | .post("/create", ({ status }) => { 36 | return status(201, { id: 1, message: "Created" }); 37 | }) 38 | 39 | // Throw error - should trigger onError handler 40 | .get("/throw-error", () => { 41 | throw new Error("This is a thrown error"); 42 | }) 43 | 44 | // Custom status with response schema (similar to the reported bug) 45 | .get( 46 | "/user/:id", 47 | ({ params: { id }, status }) => { 48 | if (id === "error") { 49 | // Simulate a database error 50 | return status(500, "Failed to get user"); 51 | } 52 | if (id === "notfound") { 53 | return status(404, "User not found"); 54 | } 55 | return { id, name: "Test User" }; 56 | }, 57 | { 58 | response: { 59 | 200: t.Object({ id: t.String(), name: t.String() }), 60 | 404: t.String(), 61 | 500: t.String(), 62 | }, 63 | } 64 | ) 65 | .listen(3456); 66 | 67 | console.log(` 68 | 🧪 Test server running at http://localhost:3456 69 | 70 | Test the following endpoints and verify the logged status codes: 71 | 72 | ✅ Expected: 200 73 | curl http://localhost:3456/ 74 | curl http://localhost:3456/json 75 | curl http://localhost:3456/user/123 76 | 77 | ✅ Expected: 201 78 | curl -X POST http://localhost:3456/create 79 | 80 | ⚠️ Expected: 400 81 | curl http://localhost:3456/bad-request 82 | 83 | ⚠️ Expected: 404 84 | curl http://localhost:3456/not-found 85 | curl http://localhost:3456/user/notfound 86 | 87 | ❌ Expected: 500 (This was the bug - was incorrectly logging 200) 88 | curl http://localhost:3456/error-status 89 | curl http://localhost:3456/user/error 90 | 91 | ❌ Expected: 500 (thrown error) 92 | curl http://localhost:3456/throw-error 93 | 94 | Press Ctrl+C to stop the server. 95 | `); 96 | -------------------------------------------------------------------------------- /packages/elysia-js/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 6 | 7 | ## [5.1.2] - 2025-12-02 8 | 9 | ### Fixed 10 | 11 | - Fixed incorrect status code logging where responses with `status(500, ...)` were logged as 200. Changed from `onAfterHandle` to `onAfterResponse` hook to capture the finalized response status code. Fixes [#9](https://github.com/0xrasla/logify/issues/9). 12 | 13 | ### Changed 14 | 15 | - HTTP logging now uses appropriate log level based on status code: `warn` for 4xx/5xx responses, `info` for successful responses. 16 | - Added `errorLogged` flag to prevent double logging when errors are handled by the `onError` hook. 17 | 18 | ## [5.1.1] - 2025-09-20 19 | 20 | ### Added 21 | 22 | - New examples: `separate-http-global.ts` and `legacy-use-global.ts` demonstrating dual-format logging and legacy unified mode. 23 | 24 | ### Changed 25 | 26 | - Updated dependencies: bumped `elysia` to `^1.4.6` and refreshed dev tooling versions (`@typescript-eslint/*`, `@types/*`, `eslint`). 27 | - README expanded with sections referencing new examples and clarifying HTTP vs global logger usage. 28 | 29 | ### Internal 30 | 31 | - Minor docs polish and consistency improvements; no runtime API changes. 32 | 33 | ### Upgrade Notes 34 | 35 | - Safe patch release; no code changes required for users upgrading from 5.1.0. 36 | 37 | ## [5.1.0] - 2025-09-20 38 | 39 | ### Added 40 | 41 | - Separation of concerns: Middleware now creates its own HTTP logger instance by default so global logger (initialized via `initializeLogger`) can use a different format for application logs. Implements feature request [#6](https://github.com/0xrasla/logify/issues/6). 42 | - New option `useGlobal: true` to keep legacy behaviour where middleware uses the global logger. 43 | 44 | ### Changed 45 | 46 | - HTTP request duration now measured with `performance.now()` for sub-millisecond precision and more reliable logging of very fast responses (previously could show `0ms`). Durations now formatted to 2 decimal places. 47 | 48 | ### Notes 49 | 50 | - If you previously passed formatting options to `logger()` expecting them to update the global logger, you should now call `initializeLogger()` explicitly or pass `useGlobal: true`. 51 | 52 | ## [5.0.1] - 2025-09-10 53 | 54 | ### Fixed 55 | 56 | - Middleware now logs the actual HTTP response status code instead of always defaulting to `200` (success) or `500` (error). Fixes [#5](https://github.com/0xrasla/logify/issues/5). 57 | 58 | ## [5.0.0] - 2025-09-01 59 | 60 | ### Added 61 | 62 | - Major release with expanded logging customization and global logger improvements. 63 | 64 | ## [4.0.0] - 2025-08-15 65 | 66 | ### Changed 67 | 68 | - Previous stable release prior to v5 feature set. 69 | 70 | [5.1.2]: https://github.com/0xrasla/logify/releases/tag/elysia-v5.1.2 71 | [5.0.1]: https://github.com/0xrasla/logify/releases/tag/elysia-v5.0.1 72 | [5.0.0]: https://github.com/0xrasla/logify/releases/tag/elysia-v5.0.0 73 | [4.0.0]: https://github.com/0xrasla/logify/releases/tag/elysia-v4.0.0 74 | [5.1.0]: https://github.com/0xrasla/logify/releases/tag/elysia-v5.1.0 75 | [5.1.1]: https://github.com/0xrasla/logify/releases/tag/elysia-v5.1.1 76 | -------------------------------------------------------------------------------- /packages/elysia-js/src/middleware.ts: -------------------------------------------------------------------------------- 1 | import { Elysia } from "elysia"; 2 | import { getLogger } from "./global-logger"; 3 | import { Logger } from "./logger"; 4 | import { LoggerOptions } from "./types"; 5 | 6 | /** 7 | * HTTP logger middleware for Elysia. 8 | * 9 | * This now logs ONLY HTTP request/response cycles with its own (http) logger instance 10 | * allowing the global logger (initialized via `initializeLogger`) to be used for 11 | * application / business logs with a different format. 12 | * 13 | * To preserve previous behaviour (middleware configuring & using the global logger) 14 | * pass `{ useGlobal: true }`. 15 | */ 16 | export function logger(options: LoggerOptions = {}) { 17 | const useGlobal = (options as any).useGlobal === true; 18 | 19 | // Decide which logger instance to use for HTTP logs 20 | // - use global logger if explicitly requested 21 | // - otherwise create a dedicated HTTP logger (does NOT overwrite the global one) 22 | const httpLogger = useGlobal ? getLogger() : new Logger(options); 23 | 24 | return new Elysia() 25 | .derive( 26 | { 27 | as: "scoped", 28 | }, 29 | ({ headers }) => { 30 | return { 31 | // High resolution start time for accurate duration measurement 32 | startTime: performance.now(), 33 | ip: 34 | headers["x-forwarded-for"] || 35 | headers["x-real-ip"] || 36 | headers["x-client-ip"] || 37 | "", 38 | // Track if error handler was triggered to avoid double logging 39 | errorLogged: false, 40 | }; 41 | } 42 | ) 43 | .onAfterResponse({ as: "global" }, (ctx) => { 44 | // Skip if already logged by error handler 45 | if ((ctx as any).errorLogged) { 46 | return; 47 | } 48 | 49 | const url = new URL(ctx.request.url); 50 | if (options.skip?.includes(url.pathname)) { 51 | return; 52 | } 53 | const duration = Number( 54 | (performance.now() - (ctx.startTime || performance.now())).toFixed(2) 55 | ); 56 | 57 | // Get status code from ctx.set.status - this is now accurate in onAfterResponse 58 | const statusCode = 59 | typeof ctx.set.status === "number" ? ctx.set.status : 200; 60 | 61 | // Use appropriate log level based on status code 62 | const logMethod = statusCode >= 400 ? "warn" : "info"; 63 | 64 | httpLogger[logMethod]({ 65 | method: ctx.request.method, 66 | path: url.pathname, 67 | statusCode, 68 | duration, 69 | ip: ctx.ip, 70 | message: `${ctx.request.method} ${url.pathname}`, 71 | }); 72 | }) 73 | .onError(({ error, request, ip, startTime, set, ...ctx }) => { 74 | // Mark error as logged to prevent double logging in onAfterResponse 75 | (ctx as any).errorLogged = true; 76 | 77 | const url = new URL(request.url); 78 | const duration = 79 | Number( 80 | (performance.now() - (startTime || performance.now())).toFixed(2) 81 | ) || 0.01; 82 | 83 | // Create a safe error message as error might not always have a message property 84 | const errorMessage = 85 | typeof error === "object" && error !== null && "message" in error 86 | ? String(error.message) 87 | : String(error); 88 | 89 | httpLogger.error({ 90 | method: request.method, 91 | path: url.pathname, 92 | statusCode: typeof set.status === "number" ? set.status : 500, 93 | duration, 94 | ip: ip, 95 | message: errorMessage, 96 | }); 97 | }); 98 | } 99 | -------------------------------------------------------------------------------- /packages/express/examples/global-logger.ts: -------------------------------------------------------------------------------- 1 | import express from 'express'; 2 | import { 3 | debug, 4 | error, 5 | info, 6 | initializeLogger, 7 | logger, 8 | warn 9 | } from '../src'; 10 | 11 | // Initialize the global logger with custom options 12 | initializeLogger({ 13 | level: 'debug', // Set minimum log level to debug to see all logs 14 | console: true, 15 | file: true, 16 | filePath: './logs/app.log', 17 | includeIp: true, 18 | format: '[{timestamp}] {level} - {message} - {method} {path}{ip}' 19 | }); 20 | 21 | // Now the global logger is configured and can be used anywhere in the app 22 | 23 | const app = express(); 24 | 25 | // Use the logger middleware (uses the global logger instance) 26 | app.use(logger()); 27 | 28 | // Example routes demonstrating different log levels 29 | app.get('/', (req, res) => { 30 | // Using global logger functions directly in route handlers 31 | debug('Processing root route request'); 32 | info('Root endpoint accessed'); 33 | res.send('Hello World!'); 34 | }); 35 | 36 | app.get('/debug', (req, res) => { 37 | debug('This is a debug message'); 38 | res.send('Check your console for the debug message'); 39 | }); 40 | 41 | app.get('/info', (req, res) => { 42 | info('This is an info message'); 43 | res.send('Check your console for the info message'); 44 | }); 45 | 46 | app.get('/warn', (req, res) => { 47 | warn('This is a warning message'); 48 | res.send('Check your console for the warning message'); 49 | }); 50 | 51 | app.get('/error', (req, res) => { 52 | error('This is an error message'); 53 | res.send('Check your console for the error message'); 54 | }); 55 | 56 | // Route with error 57 | app.get('/throw-error', (req, res, next) => { 58 | error('About to throw an error'); 59 | next(new Error('Something went wrong')); 60 | }); 61 | 62 | // Performance monitoring example 63 | app.get('/performance', (req, res) => { 64 | debug('Starting intensive operation'); 65 | 66 | // Log before the intensive operation 67 | info('Starting intensive calculation'); 68 | 69 | // Simulate an intensive operation 70 | const start = Date.now(); 71 | for (let i = 0; i < 1000000; i++) { 72 | // Heavy computation simulation 73 | Math.sqrt(i); 74 | } 75 | const duration = Date.now() - start; 76 | 77 | // Log after the intensive operation with timing 78 | warn(`Intensive operation completed in ${duration}ms - performance may be affected`); 79 | 80 | res.send(`Intensive operation completed in ${duration}ms`); 81 | }); 82 | 83 | // Service implementation using the global logger 84 | function userService() { 85 | debug('User service initialized'); 86 | 87 | return { 88 | getUser(id: string) { 89 | info(`Getting user with ID: ${id}`); 90 | return { id, name: 'Test User' }; 91 | }, 92 | createUser(data: any) { 93 | if (!data.email) { 94 | warn('Creating user without email'); 95 | } 96 | return { created: true, id: 'new-id' }; 97 | }, 98 | deleteUser(id: string) { 99 | error(`User deletion requested: ${id}`); 100 | return { deleted: true }; 101 | } 102 | }; 103 | } 104 | 105 | // Routes using the service 106 | app.get('/users/:id', (req, res) => { 107 | const service = userService(); 108 | const user = service.getUser(req.params.id); 109 | res.json(user); 110 | }); 111 | 112 | app.post('/users', express.json(), (req, res) => { 113 | const service = userService(); 114 | const result = service.createUser(req.body); 115 | res.json(result); 116 | }); 117 | 118 | app.delete('/users/:id', (req, res) => { 119 | const service = userService(); 120 | const result = service.deleteUser(req.params.id); 121 | res.json(result); 122 | }); 123 | 124 | // Error handling middleware 125 | app.use((err: Error, req: express.Request, res: express.Response, next: express.NextFunction) => { 126 | error(`Error in request: ${err.message}`); 127 | res.status(500).json({ error: err.message }); 128 | }); 129 | 130 | // Start server 131 | const PORT = process.env.PORT || 3000; 132 | app.listen(PORT, () => { 133 | console.log(`🚀 Server is running at http://localhost:${PORT}`); 134 | info(`Server started at http://localhost:${PORT}`); 135 | }); -------------------------------------------------------------------------------- /packages/elysia-js/src/logger.ts: -------------------------------------------------------------------------------- 1 | import chalk from "chalk"; 2 | import { appendFileSync, existsSync, mkdirSync } from "node:fs"; 3 | import { dirname } from "node:path"; 4 | import { ILogger, LogEntry, LoggerOptions, LogLevel } from "./types"; 5 | 6 | const LOG_COLORS = { 7 | debug: chalk.gray, 8 | info: chalk.blue, 9 | warn: chalk.yellow, 10 | error: chalk.red, 11 | } as const; 12 | 13 | export class Logger implements ILogger { 14 | private options: LoggerOptions; 15 | 16 | private static readonly DEFAULT_OPTIONS: LoggerOptions = { 17 | console: true, 18 | file: false, 19 | level: "info", 20 | format: 21 | "[{timestamp}] {level} [{method}] {path} - {statusCode} {duration}ms{ip} {message}", 22 | includeIp: false, 23 | }; 24 | 25 | constructor(options: LoggerOptions = {}) { 26 | this.options = { ...Logger.DEFAULT_OPTIONS, ...options }; 27 | this.initializeFileLogger(); 28 | } 29 | 30 | private initializeFileLogger(): void { 31 | if (this.options.file && this.options.filePath) { 32 | try { 33 | const dir = dirname(this.options.filePath); 34 | if (!existsSync(dir)) { 35 | mkdirSync(dir, { recursive: true }); 36 | } 37 | } catch (error) { 38 | console.error("Failed to initialize log directory:", error); 39 | } 40 | } 41 | } 42 | 43 | private shouldLog(level: LogLevel): boolean { 44 | const levels: LogLevel[] = ["debug", "info", "warn", "error"]; 45 | const configuredLevel = levels.indexOf(this.options.level || "info"); 46 | const currentLevel = levels.indexOf(level); 47 | return currentLevel >= configuredLevel; 48 | } 49 | 50 | private formatLogEntry(entry: LogEntry): string { 51 | const format = this.options.format || Logger.DEFAULT_OPTIONS.format; 52 | const timestamp = entry.timestamp.toISOString(); 53 | const level = entry.level.toUpperCase().padEnd(5); 54 | const method = (entry.method || "").toUpperCase().padEnd(7); 55 | const path = entry.path || "-"; 56 | const statusCode = entry.statusCode ? ` [${entry.statusCode}]` : ""; 57 | const duration = entry.duration ? `${entry.duration}` : ""; 58 | const message = entry.message || ""; 59 | const ip = entry.ip && this.options.includeIp ? ` from ${entry.ip}` : ""; 60 | 61 | return format! 62 | .replace("{timestamp}", timestamp) 63 | .replace("{level}", level) 64 | .replace("{method}", method) 65 | .replace("{path}", path) 66 | .replace("{statusCode}", statusCode) 67 | .replace("{duration}", duration) 68 | .replace("{message}", message) 69 | .replace("{ip}", ip) 70 | .trim(); 71 | } 72 | 73 | private writeToFile(message: string): void { 74 | if (this.options.file && this.options.filePath) { 75 | try { 76 | appendFileSync(this.options.filePath, message + "\n"); 77 | } catch (error) { 78 | console.error("Failed to write to log file:", error); 79 | } 80 | } 81 | } 82 | 83 | private createLogEntry( 84 | level: LogLevel, 85 | input: string | Partial, 86 | ): LogEntry { 87 | const timestamp = new Date(); 88 | 89 | if (typeof input === "string") { 90 | return { 91 | timestamp, 92 | level, 93 | method: "", 94 | path: "", 95 | statusCode: 0, 96 | duration: 0, 97 | message: input, 98 | }; 99 | } 100 | 101 | return { 102 | timestamp, 103 | level, 104 | method: input.method || "", 105 | path: input.path || "", 106 | statusCode: input.statusCode || 0, 107 | duration: input.duration || 0, 108 | message: input.message || "", 109 | ip: input.ip, 110 | }; 111 | } 112 | 113 | public log(level: LogLevel, input: string | Partial): void { 114 | if (!this.shouldLog(level)) return; 115 | 116 | const entry = this.createLogEntry(level, input); 117 | const formattedMessage = this.formatLogEntry(entry); 118 | 119 | if (this.options.console) { 120 | const colorize = LOG_COLORS[level] || chalk.white; 121 | console.log(colorize(formattedMessage)); 122 | } 123 | 124 | if (this.options.file) { 125 | this.writeToFile(formattedMessage); 126 | } 127 | } 128 | 129 | public debug(input: string | Partial): void { 130 | this.log("debug", input); 131 | } 132 | 133 | public info(input: string | Partial): void { 134 | this.log("info", input); 135 | } 136 | 137 | public warn(input: string | Partial): void { 138 | this.log("warn", input); 139 | } 140 | 141 | public error(input: string | Partial): void { 142 | this.log("error", input); 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /packages/express/src/logger.ts: -------------------------------------------------------------------------------- 1 | import chalk from "chalk"; 2 | import { appendFileSync, existsSync, mkdirSync } from "fs"; 3 | import { dirname } from "path"; 4 | import { ILogger, LogEntry, LoggerOptions, LogLevel } from "./types"; 5 | 6 | const LOG_COLORS = { 7 | debug: chalk.gray, 8 | info: chalk.blue, 9 | warn: chalk.yellow, 10 | error: chalk.red, 11 | } as const; 12 | 13 | export class Logger implements ILogger { 14 | private static readonly DEFAULT_OPTIONS: Required = { 15 | console: true, 16 | file: false, 17 | filePath: "./logs/app.log", 18 | level: "info", 19 | skip: [], 20 | includeIp: false, 21 | format: 22 | "[{timestamp}] {level} [{method}] {path} - {statusCode} {duration}ms{ip} {message}", 23 | }; 24 | 25 | private options: LoggerOptions; 26 | 27 | constructor(options: LoggerOptions = {}) { 28 | this.options = { ...Logger.DEFAULT_OPTIONS, ...options }; 29 | this.initializeFileLogger(); 30 | } 31 | 32 | public debug(input: string | Partial): void { 33 | this.log("debug", input); 34 | } 35 | 36 | public info(input: string | Partial): void { 37 | this.log("info", input); 38 | } 39 | 40 | public warn(input: string | Partial): void { 41 | this.log("warn", input); 42 | } 43 | 44 | public error(input: string | Partial): void { 45 | this.log("error", input); 46 | } 47 | 48 | public log(level: LogLevel, input: string | Partial): void { 49 | if (!this.shouldLog(level)) return; 50 | 51 | const entry = this.createLogEntry(level, input); 52 | const formattedMessage = this.formatLogEntry(entry); 53 | 54 | if (this.options.console) { 55 | const colorize = LOG_COLORS[level] || chalk.white; 56 | console.log(colorize(formattedMessage)); 57 | } 58 | 59 | if (this.options.file) { 60 | this.writeToFile(formattedMessage); 61 | } 62 | } 63 | 64 | private shouldLog(level: LogLevel): boolean { 65 | const levels: LogLevel[] = ["debug", "info", "warn", "error"]; 66 | const configuredLevel = levels.indexOf(this.options.level || "info"); 67 | const currentLevel = levels.indexOf(level); 68 | return currentLevel >= configuredLevel; 69 | } 70 | 71 | private createLogEntry( 72 | level: LogLevel, 73 | input: string | Partial 74 | ): LogEntry { 75 | const timestamp = new Date(); 76 | 77 | if (typeof input === "string") { 78 | return { 79 | timestamp, 80 | level, 81 | method: "", 82 | path: "", 83 | statusCode: 0, 84 | duration: 0, 85 | message: input, 86 | }; 87 | } 88 | 89 | return { 90 | timestamp, 91 | level, 92 | method: input.method || "", 93 | path: input.path || "", 94 | statusCode: input.statusCode || 0, 95 | duration: input.duration || 0, 96 | message: input.message || "", 97 | ip: input.ip, 98 | }; 99 | } 100 | 101 | private formatLogEntry(entry: LogEntry): string { 102 | const format = this.options.format || Logger.DEFAULT_OPTIONS.format; 103 | const timestamp = entry.timestamp.toISOString(); 104 | const level = entry.level.toUpperCase().padEnd(5); 105 | const method = (entry.method || "").toUpperCase().padEnd(7); 106 | const path = entry.path || "-"; 107 | const statusCode = entry.statusCode ? `${entry.statusCode}` : ""; 108 | const duration = entry.duration ? `${entry.duration}` : ""; 109 | const message = entry.message || ""; 110 | const ip = entry.ip && this.options.includeIp ? ` from ${entry.ip}` : ""; 111 | 112 | return format! 113 | .replace("{timestamp}", timestamp) 114 | .replace("{level}", level) 115 | .replace("{method}", method) 116 | .replace("{path}", path) 117 | .replace("{statusCode}", statusCode) 118 | .replace("{duration}", duration) 119 | .replace("{message}", message) 120 | .replace("{ip}", ip) 121 | .trim(); 122 | } 123 | 124 | private writeToFile(message: string): void { 125 | if (this.options.file && this.options.filePath) { 126 | try { 127 | appendFileSync(this.options.filePath, message + "\n"); 128 | } catch (error) { 129 | console.error("Failed to write to log file:", error); 130 | } 131 | } 132 | } 133 | 134 | private initializeFileLogger(): void { 135 | if (this.options.file && this.options.filePath) { 136 | try { 137 | const dir = dirname(this.options.filePath); 138 | if (!existsSync(dir)) { 139 | mkdirSync(dir, { recursive: true }); 140 | } 141 | } catch (error) { 142 | console.error("Failed to initialize log directory:", error); 143 | } 144 | } 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Logify 2 | 3 | [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) 4 | 5 | A beautiful, fast, and type-safe logging middleware for Node.js web applications. Get instant insights into your HTTP requests with colorized console output and structured file logging. 6 | 7 | ## 📦 Packages 8 | 9 | This monorepo contains the following packages: 10 | 11 | - [@rasla/logify](./packages/elysia-js) - Logging middleware for Elysia.js 12 | - [@rasla/express-logify](./packages/express) - Logging middleware for Express.js 13 | 14 | ## ✨ Features 15 | 16 | - 🎨 Beautiful console output with color-coded log levels 17 | - ⚡ Zero-config with smart defaults 18 | - 📊 Request duration and status code tracking 19 | - 🌐 IP address logging with proxy support 20 | - 📝 Structured logging with TypeScript support 21 | - 🎯 Path-based request filtering 22 | - 🔄 Automatic log directory creation 23 | - 🎛️ Fully customizable log formats 24 | - 🌍 Global logger instance for application-wide logging 25 | - 📝 Convenient logging functions: debug(), info(), warn(), and error() 26 | 27 | ## 📥 Installation 28 | 29 | Choose the package that matches your framework: 30 | 31 | ### For Elysia.js 32 | 33 | ```bash 34 | bun add @rasla/logify 35 | ``` 36 | 37 | ### For Express.js 38 | 39 | ```bash 40 | npm install @rasla/express-logify 41 | # or 42 | yarn add @rasla/express-logify 43 | # or 44 | pnpm add @rasla/express-logify 45 | ``` 46 | 47 | ## 🚀 Quick Start 48 | 49 | ### Elysia.js 50 | 51 | ```typescript 52 | import { Elysia } from "elysia"; 53 | import { logger } from "@rasla/logify"; 54 | 55 | const app = new Elysia() 56 | .use(logger()) 57 | .get("/", () => "Hello World!") 58 | .listen(3000); 59 | ``` 60 | 61 | ### Express.js 62 | 63 | ```typescript 64 | import express from "express"; 65 | import { logger } from "@rasla/express-logify"; 66 | 67 | const app = express(); 68 | 69 | app.use(logger()); 70 | app.get("/", (req, res) => res.send("Hello World!")); 71 | 72 | app.listen(3000); 73 | ``` 74 | 75 | ## 🌍 Global Logger 76 | 77 | Both packages now include a global logger that can be accessed from anywhere in your application: 78 | 79 | ````typescript 80 | // Elysia.js 81 | import { 82 | initializeLogger, 83 | debug, 84 | info, 85 | warn, 86 | error 87 | } from "@rasla/logify"; 88 | 89 | // Express.js 90 | import { 91 | initializeLogger, 92 | debug, 93 | info, 94 | warn, 95 | error 96 | } from "@rasla/express-logify"; 97 | 98 | // Configure once at startup 99 | initializeLogger({ 100 | level: "debug", 101 | file: true, 102 | filePath: "./logs/app.log" 103 | }); 104 | 105 | // Use anywhere in your code 106 | debug("This is a debug message"); 107 | info("This is an info message"); 108 | warn("This is a warning message"); 109 | error("This is an error message"); 110 | | `{statusCode}` | HTTP status | `200`, `404` | 111 | | `{duration}` | Request time | `123ms` | 112 | | `{ip}` | Client IP | `127.0.0.1` | 113 | ```` 114 | 115 | ## 🎯 Examples 116 | 117 | Check out the examples in each package: 118 | - [Elysia.js Examples](./packages/elysia-js/examples) 119 | - [Express.js Examples](./packages/express/examples) 120 | 121 | ## 🤝 Contributing 122 | 123 | Contributions are welcome! Please feel free to submit a Pull Request. 124 | 125 | ## 🎨 Configuration 126 | 127 | Both packages support the same configuration options: 128 | 129 | ```typescript 130 | { 131 | // Console logging (default: true) 132 | console: true, 133 | 134 | // File logging (default: false) 135 | file: true, 136 | filePath: './logs/app.log', 137 | 138 | // Log level (default: "info") 139 | level: 'debug', // "debug" | "info" | "warn" | "error" 140 | 141 | // Skip certain paths 142 | skip: ['/health', '/metrics'], 143 | 144 | // Include IP address (default: false) 145 | includeIp: true, 146 | 147 | // Custom format (see Format Tokens below) 148 | format: '[{timestamp}] {level} [{method}] {path} - {statusCode} {duration}ms{ip}', 149 | } 150 | ```` 151 | 152 | ## 📝 Format Tokens 153 | 154 | Customize your log format using these tokens: 155 | 156 | | Token | Description | Example | 157 | | -------------- | ------------- | -------------------------- | 158 | | `{timestamp}` | ISO timestamp | `2024-12-03T17:48:54.721Z` | 159 | | `{level}` | Log level | `INFO`, `ERROR` | 160 | | `{method}` | HTTP method | `GET`, `POST` | 161 | | `{path}` | Request path | `/api/users` | 162 | | `{statusCode}` | HTTP status | `200`, `404` | 163 | | `{duration}` | Request time | `123ms` | 164 | | `{ip}` | Client IP | `127.0.0.1` | 165 | 166 | ## 🎯 Examples 167 | 168 | Check out the examples in each package: 169 | 170 | - [Elysia.js Examples](./packages/elysia-js/examples) 171 | - [Express.js Examples](./packages/express/examples) 172 | 173 | ## 🤝 Contributing 174 | 175 | Contributions are welcome! Please feel free to submit a Pull Request. 176 | 177 | ## 📄 License 178 | 179 | MIT License - Created by [0xRasla](https://github.com/0xRasla) 180 | -------------------------------------------------------------------------------- /packages/elysia-js/README.md: -------------------------------------------------------------------------------- 1 | # Logify for Elysia.js 2 | 3 | [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) 4 | 5 | A beautiful, fast, and type-safe logging middleware for Elysia.js applications. Get instant insights into your HTTP requests with colorized console output and structured file logging. 6 | 7 | ## ✨ Features 8 | 9 | - 🎨 Beautiful console output with color-coded log levels 10 | - ⚡ Zero-config with smart defaults 11 | - 📊 Request duration and status code tracking 12 | - 🌐 IP address logging with proxy support 13 | - 📝 Structured logging with TypeScript support 14 | - 🎯 Path-based request filtering 15 | - 🔄 Automatic log directory creation 16 | - 🎛️ Fully customizable log formats 17 | - 🌍 Global logger instance for application-wide logging 18 | - 📝 Convenient logging functions: debug(), info(), warn(), and error() 19 | 20 | ## 📦 Installation 21 | 22 | ```bash 23 | bun add @rasla/logify 24 | ``` 25 | 26 | ## 🚀 Quick Start 27 | 28 | ```typescript 29 | import { Elysia } from "elysia"; 30 | import { logger } from "@rasla/logify"; 31 | 32 | const app = new Elysia() 33 | .use(logger()) 34 | .get("/", () => "Hello World!") 35 | .listen(3000); 36 | ``` 37 | 38 | Output: 39 | 40 | ``` 41 | [2024-12-03T17:48:54.721Z] INFO [GET ] / - 200 1ms 42 | ``` 43 | 44 | ## 🌍 Global Logger 45 | 46 | Logify provides a global logger that can be accessed from anywhere in your application: 47 | 48 | ```typescript 49 | import { Elysia } from "elysia"; 50 | import { 51 | logger, 52 | initializeLogger, 53 | debug, 54 | info, 55 | warn, 56 | error, 57 | } from "@rasla/logify"; 58 | 59 | // Configure the global logger once at startup 60 | initializeLogger({ 61 | level: "debug", 62 | file: true, 63 | filePath: "./logs/app.log", 64 | }); 65 | 66 | // Now you can use logging functions anywhere in your code 67 | const app = new Elysia() 68 | .use(logger()) // Uses the global logger configuration 69 | .get("/", () => { 70 | debug("Processing root request"); // Debug log 71 | return "Hello World!"; 72 | }) 73 | .get("/users", () => { 74 | info("Fetching users"); // Info log 75 | return ["Alice", "Bob"]; 76 | }) 77 | .post("/users", () => { 78 | warn("User validation skipped"); // Warning log 79 | return { created: true }; 80 | }) 81 | .get("/error", () => { 82 | error("Critical error occurred"); // Error log 83 | throw new Error("Something went wrong"); 84 | }) 85 | .listen(3000); 86 | ``` 87 | 88 | ## 🎨 Configuration 89 | 90 | ```typescript 91 | import { Elysia } from "elysia"; 92 | import { logger } from "@rasla/logify"; 93 | 94 | const app = new Elysia(); 95 | 96 | // All options are optional with smart defaults 97 | app.use( 98 | logger({ 99 | // Console logging (default: true) 100 | console: true, 101 | 102 | // File logging (default: false) 103 | file: true, 104 | filePath: "./logs/app.log", 105 | 106 | // Log level (default: "info") 107 | level: "debug", // "debug" | "info" | "warn" | "error" 108 | 109 | // Skip certain paths 110 | skip: ["/health", "/metrics"], 111 | 112 | // Include IP address (default: false) 113 | includeIp: true, 114 | 115 | // Custom format (see Format Tokens below) 116 | format: 117 | "[{timestamp}] {level} [{method}] {path} - {statusCode} {duration}ms{ip}", 118 | }) 119 | ); 120 | 121 | app.listen(3000); 122 | ``` 123 | 124 | ## 📝 Format Tokens 125 | 126 | Customize your log format using these tokens: 127 | 128 | | Token | Description | Example | 129 | | -------------- | ------------- | -------------------------- | 130 | | `{timestamp}` | ISO timestamp | `2024-12-03T17:48:54.721Z` | 131 | | `{level}` | Log level | `INFO`, `ERROR` | 132 | | `{method}` | HTTP method | `GET`, `POST` | 133 | | `{path}` | Request path | `/api/users` | 134 | | `{statusCode}` | HTTP status | `200`, `404` | 135 | | `{duration}` | Request time | `123ms` | 136 | | `{ip}` | Client IP | `127.0.0.1` | 137 | 138 | ## 🎯 Examples 139 | 140 | ### Basic API Server 141 | 142 | ```typescript 143 | import { Elysia } from "elysia"; 144 | import { logger } from "@rasla/logify"; 145 | 146 | const app = new Elysia() 147 | .use(logger()) 148 | .get("/", () => "Hello") 149 | .post("/users", ({ body }) => ({ created: true })) 150 | .get("/users/:id", ({ params: { id } }) => ({ id })) 151 | .listen(3000); 152 | ``` 153 | 154 | ### Using Global Logger Functions 155 | 156 | ```typescript 157 | import { Elysia } from "elysia"; 158 | import { 159 | logger, 160 | initializeLogger, 161 | debug, 162 | info, 163 | warn, 164 | error, 165 | } from "@rasla/logify"; 166 | 167 | // Initialize once with your preferred configuration 168 | initializeLogger({ 169 | level: "debug", 170 | console: true, 171 | file: true, 172 | filePath: "./logs/app.log", 173 | }); 174 | 175 | // Then use anywhere in your application 176 | function userService() { 177 | debug("User service initialized"); 178 | 179 | return { 180 | getUser(id: string) { 181 | info(`Getting user with ID: ${id}`); 182 | // Implementation... 183 | }, 184 | createUser(data: any) { 185 | if (!data.email) { 186 | warn("Creating user without email"); 187 | } 188 | // Implementation... 189 | }, 190 | deleteUser(id: string) { 191 | error(`User deletion requested: ${id}`); 192 | // Implementation... 193 | }, 194 | }; 195 | } 196 | 197 | const app = new Elysia() 198 | .use(logger()) 199 | .get("/users/:id", ({ params }) => { 200 | const service = userService(); 201 | return service.getUser(params.id); 202 | }) 203 | .listen(3000); 204 | ``` 205 | 206 | ### Production Setup 207 | 208 | ```typescript 209 | import { Elysia } from "elysia"; 210 | import { logger, initializeLogger } from "@rasla/logify"; 211 | 212 | // Configure global logger for production 213 | initializeLogger({ 214 | level: "info", // Only info and above in production 215 | file: true, 216 | filePath: "./logs/app.log", 217 | includeIp: true, 218 | format: 219 | "[{timestamp}] {level} [{method}] {path} - {statusCode} {duration}ms - {ip}", 220 | }); 221 | 222 | const app = new Elysia(); 223 | 224 | // Use the configured logger middleware 225 | app.use(logger({ skip: ["/health"] })); 226 | 227 | // Routes 228 | app 229 | .get("/", () => "API v1") 230 | .get("/health", () => "OK") 231 | .get("/users", () => db.users.findMany()) 232 | .post("/users", ({ body }) => db.users.create({ data: body })) 233 | .listen(3000); 234 | ``` 235 | 236 | ### Error Handling 237 | 238 | ```typescript 239 | import { Elysia } from "elysia"; 240 | import { logger, error } from "@rasla/logify"; 241 | 242 | const app = new Elysia() 243 | .use(logger({ level: "debug" })) 244 | .get("/error", () => { 245 | error("Custom error before exception"); 246 | throw new Error("Something went wrong"); 247 | }) 248 | .listen(3000); 249 | 250 | // Middleware output: [2024-12-03T17:48:54.721Z] ERROR [GET ] /error - 500 1ms 251 | // Custom log: [2024-12-03T17:48:54.720Z] ERROR Custom error before exception 252 | ``` 253 | 254 | ### Separate HTTP vs Global Logger (New in v5.1.0) 255 | 256 | See: `examples/separate-http-global.ts` 257 | 258 | Demonstrates using different formats: one for HTTP access logs and one for application logs. 259 | 260 | ### Legacy Unified Logger (useGlobal) 261 | 262 | See: `examples/legacy-use-global.ts` 263 | 264 | Shows how to retain pre-v5.1.0 behaviour where middleware and global logs share the same logger & format. 265 | 266 | ## 🤝 Contributing 267 | 268 | Contributions are welcome! Please feel free to submit a Pull Request. 269 | 270 | ## 📄 License 271 | 272 | MIT License - Created by [0xRasla](https://github.com/0xRasla) 273 | 274 | ## 🔀 HTTP Logger vs Global Logger (v5.1.0+) 275 | 276 | Starting from v5.1.0 the middleware creates its own dedicated HTTP logger instance by default. This lets you: 277 | 278 | - Use one format for HTTP access logs 279 | - Use a different format for your application / domain logs via the global logger 280 | 281 | Example: 282 | 283 | ```ts 284 | import { Elysia } from "elysia"; 285 | import { initializeLogger, logger, info } from "@rasla/logify"; 286 | 287 | // Global logger for application messages 288 | initializeLogger({ 289 | format: "[{timestamp}] {level}: {message}", 290 | level: "info", 291 | }); 292 | 293 | const app = new Elysia() 294 | .use( 295 | logger({ 296 | // Dedicated HTTP log format 297 | format: 298 | "[{timestamp}] {level} {method} {path} {statusCode} | Time: {duration}ms", 299 | level: "info", 300 | }) 301 | ) 302 | .get("/", () => { 303 | info("🚀 Elysia is running"); // Uses the global logger format 304 | return "Hello"; 305 | }); 306 | ``` 307 | 308 | If you want the old behaviour (middleware configuring & using the global logger), pass `useGlobal: true`: 309 | 310 | ```ts 311 | app.use(logger({ format: "...", useGlobal: true })); 312 | ``` 313 | 314 | Performance measurement now uses `performance.now()` for higher precision; extremely fast requests will no longer appear as `0ms`. 315 | -------------------------------------------------------------------------------- /packages/express/README.md: -------------------------------------------------------------------------------- 1 | # Logify for Express.js 2 | 3 | [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) 4 | 5 | A beautiful, fast, and type-safe logging middleware for Express.js applications. Get instant insights into your HTTP requests with colorized console output and structured file logging. 6 | 7 | ## ✨ Features 8 | 9 | - 🎨 Beautiful console output with color-coded log levels 10 | - ⚡ Zero-config with smart defaults 11 | - 📊 Request duration and status code tracking 12 | - 🌐 IP address logging with proxy support 13 | - 📝 Structured logging with TypeScript support 14 | - 🎯 Path-based request filtering 15 | - 🔄 Automatic log directory creation 16 | - 🎛️ Fully customizable log formats 17 | - 🌍 Global logger instance for application-wide logging 18 | - 📝 Convenient logging functions: debug(), info(), warn(), and error() 19 | 20 | ## 📦 Installation 21 | 22 | ```bash 23 | npm install @rasla/express-logify 24 | # or 25 | yarn add @rasla/express-logify 26 | # or 27 | pnpm add @rasla/express-logify 28 | ``` 29 | 30 | ## 🚀 Quick Start 31 | 32 | ```typescript 33 | import express from 'express'; 34 | import { logger } from '@rasla/express-logify'; 35 | 36 | const app = express(); 37 | 38 | app.use(logger()); 39 | app.get('/', (req, res) => res.send('Hello World!')); 40 | 41 | app.listen(3000); 42 | ``` 43 | 44 | Output: 45 | ``` 46 | [2024-12-03T17:48:54.721Z] INFO [GET ] / - 200 1ms 47 | ``` 48 | 49 | ## 🌍 Global Logger 50 | 51 | Logify provides a global logger that can be accessed from anywhere in your application: 52 | 53 | ```typescript 54 | import express from 'express'; 55 | import { 56 | logger, 57 | initializeLogger, 58 | debug, 59 | info, 60 | warn, 61 | error 62 | } from '@rasla/express-logify'; 63 | 64 | // Configure the global logger once at startup 65 | initializeLogger({ 66 | level: 'debug', 67 | file: true, 68 | filePath: './logs/app.log' 69 | }); 70 | 71 | // Now you can use logging functions anywhere in your code 72 | const app = express(); 73 | 74 | app.use(logger()); // Uses the global logger configuration 75 | 76 | app.get('/', (req, res) => { 77 | debug('Processing root request'); // Debug log 78 | res.send('Hello World!'); 79 | }); 80 | 81 | app.get('/users', (req, res) => { 82 | info('Fetching users'); // Info log 83 | res.json(['Alice', 'Bob']); 84 | }); 85 | 86 | app.post('/users', express.json(), (req, res) => { 87 | warn('User validation skipped'); // Warning log 88 | res.json({ created: true }); 89 | }); 90 | 91 | app.get('/error', (req, res, next) => { 92 | error('Critical error occurred'); // Error log 93 | next(new Error('Something went wrong')); 94 | }); 95 | 96 | app.listen(3000); 97 | ``` 98 | 99 | ## 🎨 Configuration 100 | 101 | ```typescript 102 | import express from 'express'; 103 | import { logger } from '@rasla/express-logify'; 104 | 105 | const app = express(); 106 | 107 | // All options are optional with smart defaults 108 | app.use( 109 | logger({ 110 | // Console logging (default: true) 111 | console: true, 112 | 113 | // File logging (default: false) 114 | file: true, 115 | filePath: './logs/app.log', 116 | 117 | // Log level (default: "info") 118 | level: 'debug', // "debug" | "info" | "warn" | "error" 119 | 120 | // Skip certain paths 121 | skip: ['/health', '/metrics'], 122 | 123 | // Include IP address (default: false) 124 | includeIp: true, 125 | 126 | // Custom format (see Format Tokens below) 127 | format: 128 | '[{timestamp}] {level} [{method}] {path} - {statusCode} {duration}ms{ip}', 129 | }) 130 | ); 131 | 132 | app.listen(3000); 133 | ``` 134 | 135 | ## 📝 Format Tokens 136 | 137 | Customize your log format using these tokens: 138 | 139 | | Token | Description | Example | 140 | |-------|-------------|---------| 141 | | `{timestamp}` | ISO timestamp | `2024-12-03T17:48:54.721Z` | 142 | | `{level}` | Log level | `INFO`, `ERROR` | 143 | | `{method}` | HTTP method | `GET`, `POST` | 144 | | `{path}` | Request path | `/api/users` | 145 | | `{statusCode}` | HTTP status | `200`, `404` | 146 | | `{duration}` | Request time | `123ms` | 147 | | `{ip}` | Client IP | `127.0.0.1` | 148 | 149 | ## 🎯 Examples 150 | 151 | ### Basic API Server 152 | 153 | ```typescript 154 | import express from 'express'; 155 | import { logger } from '@rasla/express-logify'; 156 | 157 | const app = express(); 158 | 159 | app.use(logger()); 160 | 161 | app.get('/', (req, res) => res.send('Hello')); 162 | app.post('/users', express.json(), (req, res) => res.json({ created: true })); 163 | app.get('/users/:id', (req, res) => res.json({ id: req.params.id })); 164 | 165 | app.listen(3000); 166 | ``` 167 | 168 | ### Using Global Logger Functions 169 | 170 | ```typescript 171 | import express from 'express'; 172 | import { 173 | logger, 174 | initializeLogger, 175 | debug, 176 | info, 177 | warn, 178 | error 179 | } from '@rasla/express-logify'; 180 | 181 | // Initialize once with your preferred configuration 182 | initializeLogger({ 183 | level: 'debug', 184 | console: true, 185 | file: true, 186 | filePath: './logs/app.log' 187 | }); 188 | 189 | // Then use anywhere in your application 190 | function userService() { 191 | debug('User service initialized'); 192 | 193 | return { 194 | getUser(id: string) { 195 | info(`Getting user with ID: ${id}`); 196 | // Implementation... 197 | return { id }; 198 | }, 199 | createUser(data: any) { 200 | if (!data.email) { 201 | warn('Creating user without email'); 202 | } 203 | // Implementation... 204 | return { created: true }; 205 | }, 206 | deleteUser(id: string) { 207 | error(`User deletion requested: ${id}`); 208 | // Implementation... 209 | return { deleted: true }; 210 | } 211 | }; 212 | } 213 | 214 | const app = express(); 215 | app.use(logger()); 216 | app.use(express.json()); 217 | 218 | app.get('/users/:id', (req, res) => { 219 | const service = userService(); 220 | const user = service.getUser(req.params.id); 221 | res.json(user); 222 | }); 223 | 224 | app.post('/users', (req, res) => { 225 | const service = userService(); 226 | const result = service.createUser(req.body); 227 | res.json(result); 228 | }); 229 | 230 | app.listen(3000); 231 | ``` 232 | 233 | ### Production Setup 234 | 235 | ```typescript 236 | import express from 'express'; 237 | import { logger, initializeLogger } from '@rasla/express-logify'; 238 | 239 | // Configure global logger for production 240 | initializeLogger({ 241 | level: 'info', // Only info and above in production 242 | file: true, 243 | filePath: './logs/app.log', 244 | includeIp: true, 245 | format: '[{timestamp}] {level} [{method}] {path} - {statusCode} {duration}ms - {ip}', 246 | }); 247 | 248 | const app = express(); 249 | 250 | // Use the configured logger middleware 251 | app.use(logger({ skip: ['/health'] })); 252 | 253 | // Routes 254 | app 255 | .get('/', (req, res) => res.send('API v1')) 256 | .get('/health', (req, res) => res.send('OK')) 257 | .get('/users', (req, res) => res.json({ users: [] })) 258 | .post('/users', express.json(), (req, res) => res.json({ created: true })); 259 | 260 | app.listen(3000); 261 | ``` 262 | 263 | ### Error Handling 264 | 265 | ```typescript 266 | import express from 'express'; 267 | import { logger, error } from '@rasla/express-logify'; 268 | 269 | const app = express(); 270 | 271 | app.use(logger({ level: 'debug' })); 272 | 273 | app.get('/error', (req, res, next) => { 274 | error('Custom error before exception'); 275 | next(new Error('Something went wrong')); 276 | }); 277 | 278 | // Error handling middleware 279 | app.use((err: Error, req: express.Request, res: express.Response, next: express.NextFunction) => { 280 | error(`Error handled: ${err.message}`); 281 | res.status(500).json({ error: err.message }); 282 | }); 283 | 284 | app.listen(3000); 285 | ``` 286 | 287 | ### Separate HTTP vs Global Logger (New in v1.1.0) 288 | 289 | See: `examples/separate-http-global.ts` 290 | 291 | Demonstrates dual formatting: one for HTTP access logs and one for business logs via global logger. 292 | 293 | ### Legacy Unified Logger (useGlobal) 294 | 295 | See: `examples/legacy-use-global.ts` 296 | 297 | Shows how to retain legacy behaviour where middleware and global logger share the same format. 298 | 299 | ## 🤝 Contributing 300 | 301 | Contributions are welcome! Please feel free to submit a Pull Request. 302 | 303 | ## 📄 License 304 | 305 | MIT License - Created by [0xRasla](https://github.com/0xRasla) 306 | 307 | ## 🔀 HTTP Logger vs Global Logger (v1.1.0+) 308 | 309 | From v1.1.0 the Express middleware creates its own dedicated HTTP logger instance by default. This lets you: 310 | 311 | - Use one format for HTTP access logs 312 | - Use a different format for your application / domain logs via the global logger 313 | 314 | Example: 315 | 316 | ```ts 317 | import express from 'express'; 318 | import { initializeLogger, logger, info } from '@rasla/express-logify'; 319 | 320 | initializeLogger({ 321 | format: '[{timestamp}] {level}: {message}', 322 | level: 'info' 323 | }); 324 | 325 | const app = express(); 326 | 327 | app.use(logger({ 328 | format: '[{timestamp}] {level} {method} {path} {statusCode} | Time: {duration}ms', 329 | level: 'info' 330 | })); 331 | 332 | app.get('/', (req, res) => { 333 | info('🚀 Express server started'); // Global logger format 334 | res.send('Hello'); 335 | }); 336 | ``` 337 | 338 | To keep old behaviour (middleware configuring global logger) pass `useGlobal: true`: 339 | 340 | ```ts 341 | app.use(logger({ format: '...', useGlobal: true })); 342 | ``` 343 | 344 | Durations now use `performance.now()` for more precise measurement of fast requests. 345 | -------------------------------------------------------------------------------- /packages/elysia-js/bun.lock: -------------------------------------------------------------------------------- 1 | { 2 | "lockfileVersion": 1, 3 | "configVersion": 0, 4 | "workspaces": { 5 | "": { 6 | "name": "@rasla/logify", 7 | "dependencies": { 8 | "chalk": "^5.6.2", 9 | "elysia": "^1.4.6", 10 | }, 11 | "devDependencies": { 12 | "@types/bun": "^1.2.22", 13 | "@types/node": "^24.5.2", 14 | "@typescript-eslint/eslint-plugin": "^8.44.0", 15 | "@typescript-eslint/parser": "^8.44.0", 16 | "eslint": "^9.36.0", 17 | "prettier": "^3.6.2", 18 | "typescript": "^5.9.2", 19 | }, 20 | "peerDependencies": { 21 | "elysia": ">=0.7.0", 22 | }, 23 | }, 24 | }, 25 | "packages": { 26 | "@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.9.0", "", { "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g=="], 27 | 28 | "@eslint-community/regexpp": ["@eslint-community/regexpp@4.12.1", "", {}, "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ=="], 29 | 30 | "@eslint/config-array": ["@eslint/config-array@0.21.0", "", { "dependencies": { "@eslint/object-schema": "^2.1.6", "debug": "^4.3.1", "minimatch": "^3.1.2" } }, "sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ=="], 31 | 32 | "@eslint/config-helpers": ["@eslint/config-helpers@0.3.1", "", {}, "sha512-xR93k9WhrDYpXHORXpxVL5oHj3Era7wo6k/Wd8/IsQNnZUTzkGS29lyn3nAT05v6ltUuTFVCCYDEGfy2Or/sPA=="], 33 | 34 | "@eslint/core": ["@eslint/core@0.15.2", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg=="], 35 | 36 | "@eslint/eslintrc": ["@eslint/eslintrc@3.3.1", "", { "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^10.0.1", "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" } }, "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ=="], 37 | 38 | "@eslint/js": ["@eslint/js@9.36.0", "", {}, "sha512-uhCbYtYynH30iZErszX78U+nR3pJU3RHGQ57NXy5QupD4SBVwDeU8TNBy+MjMngc1UyIW9noKqsRqfjQTBU2dw=="], 39 | 40 | "@eslint/object-schema": ["@eslint/object-schema@2.1.6", "", {}, "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA=="], 41 | 42 | "@eslint/plugin-kit": ["@eslint/plugin-kit@0.3.5", "", { "dependencies": { "@eslint/core": "^0.15.2", "levn": "^0.4.1" } }, "sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w=="], 43 | 44 | "@humanfs/core": ["@humanfs/core@0.19.1", "", {}, "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="], 45 | 46 | "@humanfs/node": ["@humanfs/node@0.16.7", "", { "dependencies": { "@humanfs/core": "^0.19.1", "@humanwhocodes/retry": "^0.4.0" } }, "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ=="], 47 | 48 | "@humanwhocodes/module-importer": ["@humanwhocodes/module-importer@1.0.1", "", {}, "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA=="], 49 | 50 | "@humanwhocodes/retry": ["@humanwhocodes/retry@0.4.3", "", {}, "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ=="], 51 | 52 | "@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="], 53 | 54 | "@nodelib/fs.stat": ["@nodelib/fs.stat@2.0.5", "", {}, "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="], 55 | 56 | "@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="], 57 | 58 | "@sinclair/typebox": ["@sinclair/typebox@0.34.33", "", {}, "sha512-5HAV9exOMcXRUxo+9iYB5n09XxzCXnfy4VTNW4xnDv+FgjzAGY989C28BIdljKqmF+ZltUwujE3aossvcVtq6g=="], 59 | 60 | "@tokenizer/inflate": ["@tokenizer/inflate@0.2.7", "", { "dependencies": { "debug": "^4.4.0", "fflate": "^0.8.2", "token-types": "^6.0.0" } }, "sha512-MADQgmZT1eKjp06jpI2yozxaU9uVs4GzzgSL+uEq7bVcJ9V1ZXQkeGNql1fsSI0gMy1vhvNTNbUqrx+pZfJVmg=="], 61 | 62 | "@tokenizer/token": ["@tokenizer/token@0.3.0", "", {}, "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A=="], 63 | 64 | "@types/bun": ["@types/bun@1.2.22", "", { "dependencies": { "bun-types": "1.2.22" } }, "sha512-5A/KrKos2ZcN0c6ljRSOa1fYIyCKhZfIVYeuyb4snnvomnpFqC0tTsEkdqNxbAgExV384OETQ//WAjl3XbYqQA=="], 65 | 66 | "@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="], 67 | 68 | "@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="], 69 | 70 | "@types/node": ["@types/node@24.5.2", "", { "dependencies": { "undici-types": "~7.12.0" } }, "sha512-FYxk1I7wPv3K2XBaoyH2cTnocQEu8AOZ60hPbsyukMPLv5/5qr7V1i8PLHdl6Zf87I+xZXFvPCXYjiTFq+YSDQ=="], 71 | 72 | "@types/react": ["@types/react@19.1.12", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-cMoR+FoAf/Jyq6+Df2/Z41jISvGZZ2eTlnsaJRptmZ76Caldwy1odD4xTr/gNV9VLj0AWgg/nmkevIyUfIIq5w=="], 73 | 74 | "@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.44.0", "", { "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.44.0", "@typescript-eslint/type-utils": "8.44.0", "@typescript-eslint/utils": "8.44.0", "@typescript-eslint/visitor-keys": "8.44.0", "graphemer": "^1.4.0", "ignore": "^7.0.0", "natural-compare": "^1.4.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.44.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-EGDAOGX+uwwekcS0iyxVDmRV9HX6FLSM5kzrAToLTsr9OWCIKG/y3lQheCq18yZ5Xh78rRKJiEpP0ZaCs4ryOQ=="], 75 | 76 | "@typescript-eslint/parser": ["@typescript-eslint/parser@8.44.0", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.44.0", "@typescript-eslint/types": "8.44.0", "@typescript-eslint/typescript-estree": "8.44.0", "@typescript-eslint/visitor-keys": "8.44.0", "debug": "^4.3.4" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-VGMpFQGUQWYT9LfnPcX8ouFojyrZ/2w3K5BucvxL/spdNehccKhB4jUyB1yBCXpr2XFm0jkECxgrpXBW2ipoAw=="], 77 | 78 | "@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.44.0", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.44.0", "@typescript-eslint/types": "^8.44.0", "debug": "^4.3.4" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-ZeaGNraRsq10GuEohKTo4295Z/SuGcSq2LzfGlqiuEvfArzo/VRrT0ZaJsVPuKZ55lVbNk8U6FcL+ZMH8CoyVA=="], 79 | 80 | "@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.44.0", "", { "dependencies": { "@typescript-eslint/types": "8.44.0", "@typescript-eslint/visitor-keys": "8.44.0" } }, "sha512-87Jv3E+al8wpD+rIdVJm/ItDBe/Im09zXIjFoipOjr5gHUhJmTzfFLuTJ/nPTMc2Srsroy4IBXwcTCHyRR7KzA=="], 81 | 82 | "@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.44.0", "", { "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-x5Y0+AuEPqAInc6yd0n5DAcvtoQ/vyaGwuX5HE9n6qAefk1GaedqrLQF8kQGylLUb9pnZyLf+iEiL9fr8APDtQ=="], 83 | 84 | "@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.44.0", "", { "dependencies": { "@typescript-eslint/types": "8.44.0", "@typescript-eslint/typescript-estree": "8.44.0", "@typescript-eslint/utils": "8.44.0", "debug": "^4.3.4", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-9cwsoSxJ8Sak67Be/hD2RNt/fsqmWnNE1iHohG8lxqLSNY8xNfyY7wloo5zpW3Nu9hxVgURevqfcH6vvKCt6yg=="], 85 | 86 | "@typescript-eslint/types": ["@typescript-eslint/types@8.44.0", "", {}, "sha512-ZSl2efn44VsYM0MfDQe68RKzBz75NPgLQXuGypmym6QVOWL5kegTZuZ02xRAT9T+onqvM6T8CdQk0OwYMB6ZvA=="], 87 | 88 | "@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.44.0", "", { "dependencies": { "@typescript-eslint/project-service": "8.44.0", "@typescript-eslint/tsconfig-utils": "8.44.0", "@typescript-eslint/types": "8.44.0", "@typescript-eslint/visitor-keys": "8.44.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-lqNj6SgnGcQZwL4/SBJ3xdPEfcBuhCG8zdcwCPgYcmiPLgokiNDKlbPzCwEwu7m279J/lBYWtDYL+87OEfn8Jw=="], 89 | 90 | "@typescript-eslint/utils": ["@typescript-eslint/utils@8.44.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", "@typescript-eslint/scope-manager": "8.44.0", "@typescript-eslint/types": "8.44.0", "@typescript-eslint/typescript-estree": "8.44.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-nktOlVcg3ALo0mYlV+L7sWUD58KG4CMj1rb2HUVOO4aL3K/6wcD+NERqd0rrA5Vg06b42YhF6cFxeixsp9Riqg=="], 91 | 92 | "@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.44.0", "", { "dependencies": { "@typescript-eslint/types": "8.44.0", "eslint-visitor-keys": "^4.2.1" } }, "sha512-zaz9u8EJ4GBmnehlrpoKvj/E3dNbuQ7q0ucyZImm3cLqJ8INTc970B1qEqDX/Rzq65r3TvVTN7kHWPBoyW7DWw=="], 93 | 94 | "acorn": ["acorn@8.15.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="], 95 | 96 | "acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="], 97 | 98 | "ajv": ["ajv@6.12.6", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="], 99 | 100 | "ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], 101 | 102 | "argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="], 103 | 104 | "balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], 105 | 106 | "brace-expansion": ["brace-expansion@1.1.11", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA=="], 107 | 108 | "braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="], 109 | 110 | "bun-types": ["bun-types@1.2.22", "", { "dependencies": { "@types/node": "*" }, "peerDependencies": { "@types/react": "^19" } }, "sha512-hwaAu8tct/Zn6Zft4U9BsZcXkYomzpHJX28ofvx7k0Zz2HNz54n1n+tDgxoWFGB4PcFvJXJQloPhaV2eP3Q6EA=="], 111 | 112 | "callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="], 113 | 114 | "chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="], 115 | 116 | "color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="], 117 | 118 | "color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="], 119 | 120 | "concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="], 121 | 122 | "cookie": ["cookie@1.0.2", "", {}, "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA=="], 123 | 124 | "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="], 125 | 126 | "csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="], 127 | 128 | "debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="], 129 | 130 | "deep-is": ["deep-is@0.1.4", "", {}, "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="], 131 | 132 | "elysia": ["elysia@1.4.6", "", { "dependencies": { "cookie": "^1.0.2", "exact-mirror": "0.2.2", "fast-decode-uri-component": "^1.0.1" }, "optionalDependencies": { "@sinclair/typebox": ">= 0.34.0 < 1", "openapi-types": ">= 12.0.0" }, "peerDependencies": { "file-type": ">= 20.0.0", "typescript": ">= 5.0.0" } }, "sha512-u2CorXLPs5ZXyWP+tQR+bgka/lJA4vNpB8lDE2w/sTmdaIwoPQmHEL4J3ai6OAlluWR1kfG7T9gO3EYT9D8viQ=="], 133 | 134 | "escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="], 135 | 136 | "eslint": ["eslint@9.36.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.21.0", "@eslint/config-helpers": "^0.3.1", "@eslint/core": "^0.15.2", "@eslint/eslintrc": "^3.3.1", "@eslint/js": "9.36.0", "@eslint/plugin-kit": "^0.3.5", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^8.4.0", "eslint-visitor-keys": "^4.2.1", "espree": "^10.4.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "optionalPeers": ["jiti"], "bin": { "eslint": "bin/eslint.js" } }, "sha512-hB4FIzXovouYzwzECDcUkJ4OcfOEkXTv2zRY6B9bkwjx/cprAq0uvm1nl7zvQ0/TsUk0zQiN4uPfJpB9m+rPMQ=="], 137 | 138 | "eslint-scope": ["eslint-scope@8.4.0", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg=="], 139 | 140 | "eslint-visitor-keys": ["eslint-visitor-keys@4.2.1", "", {}, "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ=="], 141 | 142 | "espree": ["espree@10.4.0", "", { "dependencies": { "acorn": "^8.15.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^4.2.1" } }, "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ=="], 143 | 144 | "esquery": ["esquery@1.6.0", "", { "dependencies": { "estraverse": "^5.1.0" } }, "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg=="], 145 | 146 | "esrecurse": ["esrecurse@4.3.0", "", { "dependencies": { "estraverse": "^5.2.0" } }, "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag=="], 147 | 148 | "estraverse": ["estraverse@5.3.0", "", {}, "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="], 149 | 150 | "esutils": ["esutils@2.0.3", "", {}, "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="], 151 | 152 | "exact-mirror": ["exact-mirror@0.2.2", "", { "peerDependencies": { "@sinclair/typebox": "^0.34.15" }, "optionalPeers": ["@sinclair/typebox"] }, "sha512-CrGe+4QzHZlnrXZVlo/WbUZ4qQZq8C0uATQVGVgXIrNXgHDBBNFD1VRfssRA2C9t3RYvh3MadZSdg2Wy7HBoQA=="], 153 | 154 | "fast-decode-uri-component": ["fast-decode-uri-component@1.0.1", "", {}, "sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg=="], 155 | 156 | "fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="], 157 | 158 | "fast-glob": ["fast-glob@3.3.3", "", { "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.8" } }, "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg=="], 159 | 160 | "fast-json-stable-stringify": ["fast-json-stable-stringify@2.1.0", "", {}, "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="], 161 | 162 | "fast-levenshtein": ["fast-levenshtein@2.0.6", "", {}, "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="], 163 | 164 | "fastq": ["fastq@1.19.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ=="], 165 | 166 | "fflate": ["fflate@0.8.2", "", {}, "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A=="], 167 | 168 | "file-entry-cache": ["file-entry-cache@8.0.0", "", { "dependencies": { "flat-cache": "^4.0.0" } }, "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ=="], 169 | 170 | "file-type": ["file-type@21.0.0", "", { "dependencies": { "@tokenizer/inflate": "^0.2.7", "strtok3": "^10.2.2", "token-types": "^6.0.0", "uint8array-extras": "^1.4.0" } }, "sha512-ek5xNX2YBYlXhiUXui3D/BXa3LdqPmoLJ7rqEx2bKJ7EAUEfmXgW0Das7Dc6Nr9MvqaOnIqiPV0mZk/r/UpNAg=="], 171 | 172 | "fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="], 173 | 174 | "find-up": ["find-up@5.0.0", "", { "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" } }, "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng=="], 175 | 176 | "flat-cache": ["flat-cache@4.0.1", "", { "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.4" } }, "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw=="], 177 | 178 | "flatted": ["flatted@3.3.3", "", {}, "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg=="], 179 | 180 | "glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="], 181 | 182 | "globals": ["globals@14.0.0", "", {}, "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="], 183 | 184 | "graphemer": ["graphemer@1.4.0", "", {}, "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag=="], 185 | 186 | "has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="], 187 | 188 | "ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="], 189 | 190 | "ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], 191 | 192 | "import-fresh": ["import-fresh@3.3.1", "", { "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ=="], 193 | 194 | "imurmurhash": ["imurmurhash@0.1.4", "", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="], 195 | 196 | "is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="], 197 | 198 | "is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="], 199 | 200 | "is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="], 201 | 202 | "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], 203 | 204 | "js-yaml": ["js-yaml@4.1.0", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA=="], 205 | 206 | "json-buffer": ["json-buffer@3.0.1", "", {}, "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="], 207 | 208 | "json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="], 209 | 210 | "json-stable-stringify-without-jsonify": ["json-stable-stringify-without-jsonify@1.0.1", "", {}, "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw=="], 211 | 212 | "keyv": ["keyv@4.5.4", "", { "dependencies": { "json-buffer": "3.0.1" } }, "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw=="], 213 | 214 | "levn": ["levn@0.4.1", "", { "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="], 215 | 216 | "locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="], 217 | 218 | "lodash.merge": ["lodash.merge@4.6.2", "", {}, "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="], 219 | 220 | "merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="], 221 | 222 | "micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="], 223 | 224 | "minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="], 225 | 226 | "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], 227 | 228 | "natural-compare": ["natural-compare@1.4.0", "", {}, "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="], 229 | 230 | "openapi-types": ["openapi-types@12.1.3", "", {}, "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw=="], 231 | 232 | "optionator": ["optionator@0.9.4", "", { "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", "word-wrap": "^1.2.5" } }, "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g=="], 233 | 234 | "p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="], 235 | 236 | "p-locate": ["p-locate@5.0.0", "", { "dependencies": { "p-limit": "^3.0.2" } }, "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw=="], 237 | 238 | "parent-module": ["parent-module@1.0.1", "", { "dependencies": { "callsites": "^3.0.0" } }, "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g=="], 239 | 240 | "path-exists": ["path-exists@4.0.0", "", {}, "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="], 241 | 242 | "path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="], 243 | 244 | "picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], 245 | 246 | "prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="], 247 | 248 | "prettier": ["prettier@3.6.2", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ=="], 249 | 250 | "punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="], 251 | 252 | "queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="], 253 | 254 | "resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="], 255 | 256 | "reusify": ["reusify@1.1.0", "", {}, "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="], 257 | 258 | "run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="], 259 | 260 | "semver": ["semver@7.7.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA=="], 261 | 262 | "shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="], 263 | 264 | "shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="], 265 | 266 | "strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="], 267 | 268 | "strtok3": ["strtok3@10.3.1", "", { "dependencies": { "@tokenizer/token": "^0.3.0" } }, "sha512-3JWEZM6mfix/GCJBBUrkA8p2Id2pBkyTkVCJKto55w080QBKZ+8R171fGrbiSp+yMO/u6F8/yUh7K4V9K+YCnw=="], 269 | 270 | "supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="], 271 | 272 | "to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="], 273 | 274 | "token-types": ["token-types@6.0.0", "", { "dependencies": { "@tokenizer/token": "^0.3.0", "ieee754": "^1.2.1" } }, "sha512-lbDrTLVsHhOMljPscd0yitpozq7Ga2M5Cvez5AjGg8GASBjtt6iERCAJ93yommPmz62fb45oFIXHEZ3u9bfJEA=="], 275 | 276 | "ts-api-utils": ["ts-api-utils@2.1.0", "", { "peerDependencies": { "typescript": ">=4.8.4" } }, "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ=="], 277 | 278 | "type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="], 279 | 280 | "typescript": ["typescript@5.9.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A=="], 281 | 282 | "uint8array-extras": ["uint8array-extras@1.4.0", "", {}, "sha512-ZPtzy0hu4cZjv3z5NW9gfKnNLjoz4y6uv4HlelAjDK7sY/xOkKZv9xK/WQpcsBB3jEybChz9DPC2U/+cusjJVQ=="], 283 | 284 | "undici-types": ["undici-types@7.12.0", "", {}, "sha512-goOacqME2GYyOZZfb5Lgtu+1IDmAlAEu5xnD3+xTzS10hT0vzpf0SPjkXwAw9Jm+4n/mQGDP3LO8CPbYROeBfQ=="], 285 | 286 | "uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="], 287 | 288 | "which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="], 289 | 290 | "word-wrap": ["word-wrap@1.2.5", "", {}, "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="], 291 | 292 | "yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="], 293 | 294 | "@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="], 295 | 296 | "@eslint/eslintrc/ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="], 297 | 298 | "@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], 299 | 300 | "eslint/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], 301 | 302 | "eslint/ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="], 303 | 304 | "fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], 305 | 306 | "@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="], 307 | } 308 | } 309 | -------------------------------------------------------------------------------- /packages/express/bun.lock: -------------------------------------------------------------------------------- 1 | { 2 | "lockfileVersion": 1, 3 | "workspaces": { 4 | "": { 5 | "name": "@rasla/express-logify", 6 | "dependencies": { 7 | "chalk": "^4.1.2", 8 | "express": "^4.18.2", 9 | }, 10 | "devDependencies": { 11 | "@types/express": "^4.17.21", 12 | "@types/node": "^20.10.5", 13 | "@typescript-eslint/eslint-plugin": "^6.15.0", 14 | "@typescript-eslint/parser": "^6.15.0", 15 | "eslint": "^8.56.0", 16 | "prettier": "^3.1.1", 17 | "ts-node-dev": "^2.0.0", 18 | "typescript": "^5.3.3", 19 | }, 20 | "peerDependencies": { 21 | "express": ">=4.17.1", 22 | }, 23 | }, 24 | }, 25 | "packages": { 26 | "@cspotcode/source-map-support": ["@cspotcode/source-map-support@0.8.1", "", { "dependencies": { "@jridgewell/trace-mapping": "0.3.9" } }, "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw=="], 27 | 28 | "@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.5.1", "", { "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-soEIOALTfTK6EjmKMMoLugwaP0rzkad90iIWd1hMO9ARkSAyjfMfkRRhLvD5qH7vvM0Cg72pieUfR6yh6XxC4w=="], 29 | 30 | "@eslint-community/regexpp": ["@eslint-community/regexpp@4.12.1", "", {}, "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ=="], 31 | 32 | "@eslint/eslintrc": ["@eslint/eslintrc@2.1.4", "", { "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^9.6.0", "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" } }, "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ=="], 33 | 34 | "@eslint/js": ["@eslint/js@8.57.1", "", {}, "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q=="], 35 | 36 | "@humanwhocodes/config-array": ["@humanwhocodes/config-array@0.13.0", "", { "dependencies": { "@humanwhocodes/object-schema": "^2.0.3", "debug": "^4.3.1", "minimatch": "^3.0.5" } }, "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw=="], 37 | 38 | "@humanwhocodes/module-importer": ["@humanwhocodes/module-importer@1.0.1", "", {}, "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA=="], 39 | 40 | "@humanwhocodes/object-schema": ["@humanwhocodes/object-schema@2.0.3", "", {}, "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA=="], 41 | 42 | "@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="], 43 | 44 | "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.0", "", {}, "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ=="], 45 | 46 | "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.9", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" } }, "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ=="], 47 | 48 | "@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="], 49 | 50 | "@nodelib/fs.stat": ["@nodelib/fs.stat@2.0.5", "", {}, "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="], 51 | 52 | "@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="], 53 | 54 | "@tsconfig/node10": ["@tsconfig/node10@1.0.11", "", {}, "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw=="], 55 | 56 | "@tsconfig/node12": ["@tsconfig/node12@1.0.11", "", {}, "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag=="], 57 | 58 | "@tsconfig/node14": ["@tsconfig/node14@1.0.3", "", {}, "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow=="], 59 | 60 | "@tsconfig/node16": ["@tsconfig/node16@1.0.4", "", {}, "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA=="], 61 | 62 | "@types/body-parser": ["@types/body-parser@1.19.5", "", { "dependencies": { "@types/connect": "*", "@types/node": "*" } }, "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg=="], 63 | 64 | "@types/connect": ["@types/connect@3.4.38", "", { "dependencies": { "@types/node": "*" } }, "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug=="], 65 | 66 | "@types/express": ["@types/express@4.17.21", "", { "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.33", "@types/qs": "*", "@types/serve-static": "*" } }, "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ=="], 67 | 68 | "@types/express-serve-static-core": ["@types/express-serve-static-core@4.19.6", "", { "dependencies": { "@types/node": "*", "@types/qs": "*", "@types/range-parser": "*", "@types/send": "*" } }, "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A=="], 69 | 70 | "@types/http-errors": ["@types/http-errors@2.0.4", "", {}, "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA=="], 71 | 72 | "@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="], 73 | 74 | "@types/mime": ["@types/mime@1.3.5", "", {}, "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w=="], 75 | 76 | "@types/node": ["@types/node@20.17.30", "", { "dependencies": { "undici-types": "~6.19.2" } }, "sha512-7zf4YyHA+jvBNfVrk2Gtvs6x7E8V+YDW05bNfG2XkWDJfYRXrTiP/DsB2zSYTaHX0bGIujTBQdMVAhb+j7mwpg=="], 77 | 78 | "@types/qs": ["@types/qs@6.9.18", "", {}, "sha512-kK7dgTYDyGqS+e2Q4aK9X3D7q234CIZ1Bv0q/7Z5IwRDoADNU81xXJK/YVyLbLTZCoIwUoDoffFeF+p/eIklAA=="], 79 | 80 | "@types/range-parser": ["@types/range-parser@1.2.7", "", {}, "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ=="], 81 | 82 | "@types/semver": ["@types/semver@7.7.0", "", {}, "sha512-k107IF4+Xr7UHjwDc7Cfd6PRQfbdkiRabXGRjo07b4WyPahFBZCZ1sE+BNxYIJPPg73UkfOsVOLwqVc/6ETrIA=="], 83 | 84 | "@types/send": ["@types/send@0.17.4", "", { "dependencies": { "@types/mime": "^1", "@types/node": "*" } }, "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA=="], 85 | 86 | "@types/serve-static": ["@types/serve-static@1.15.7", "", { "dependencies": { "@types/http-errors": "*", "@types/node": "*", "@types/send": "*" } }, "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw=="], 87 | 88 | "@types/strip-bom": ["@types/strip-bom@3.0.0", "", {}, "sha512-xevGOReSYGM7g/kUBZzPqCrR/KYAo+F0yiPc85WFTJa0MSLtyFTVTU6cJu/aV4mid7IffDIWqo69THF2o4JiEQ=="], 89 | 90 | "@types/strip-json-comments": ["@types/strip-json-comments@0.0.30", "", {}, "sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ=="], 91 | 92 | "@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@6.21.0", "", { "dependencies": { "@eslint-community/regexpp": "^4.5.1", "@typescript-eslint/scope-manager": "6.21.0", "@typescript-eslint/type-utils": "6.21.0", "@typescript-eslint/utils": "6.21.0", "@typescript-eslint/visitor-keys": "6.21.0", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", "natural-compare": "^1.4.0", "semver": "^7.5.4", "ts-api-utils": "^1.0.1" }, "peerDependencies": { "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", "eslint": "^7.0.0 || ^8.0.0" } }, "sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA=="], 93 | 94 | "@typescript-eslint/parser": ["@typescript-eslint/parser@6.21.0", "", { "dependencies": { "@typescript-eslint/scope-manager": "6.21.0", "@typescript-eslint/types": "6.21.0", "@typescript-eslint/typescript-estree": "6.21.0", "@typescript-eslint/visitor-keys": "6.21.0", "debug": "^4.3.4" }, "peerDependencies": { "eslint": "^7.0.0 || ^8.0.0" } }, "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ=="], 95 | 96 | "@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@6.21.0", "", { "dependencies": { "@typescript-eslint/types": "6.21.0", "@typescript-eslint/visitor-keys": "6.21.0" } }, "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg=="], 97 | 98 | "@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@6.21.0", "", { "dependencies": { "@typescript-eslint/typescript-estree": "6.21.0", "@typescript-eslint/utils": "6.21.0", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, "peerDependencies": { "eslint": "^7.0.0 || ^8.0.0" } }, "sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag=="], 99 | 100 | "@typescript-eslint/types": ["@typescript-eslint/types@6.21.0", "", {}, "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg=="], 101 | 102 | "@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@6.21.0", "", { "dependencies": { "@typescript-eslint/types": "6.21.0", "@typescript-eslint/visitor-keys": "6.21.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", "minimatch": "9.0.3", "semver": "^7.5.4", "ts-api-utils": "^1.0.1" } }, "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ=="], 103 | 104 | "@typescript-eslint/utils": ["@typescript-eslint/utils@6.21.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", "@typescript-eslint/scope-manager": "6.21.0", "@typescript-eslint/types": "6.21.0", "@typescript-eslint/typescript-estree": "6.21.0", "semver": "^7.5.4" }, "peerDependencies": { "eslint": "^7.0.0 || ^8.0.0" } }, "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ=="], 105 | 106 | "@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@6.21.0", "", { "dependencies": { "@typescript-eslint/types": "6.21.0", "eslint-visitor-keys": "^3.4.1" } }, "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A=="], 107 | 108 | "@ungap/structured-clone": ["@ungap/structured-clone@1.3.0", "", {}, "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="], 109 | 110 | "accepts": ["accepts@1.3.8", "", { "dependencies": { "mime-types": "~2.1.34", "negotiator": "0.6.3" } }, "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw=="], 111 | 112 | "acorn": ["acorn@8.14.1", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg=="], 113 | 114 | "acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="], 115 | 116 | "acorn-walk": ["acorn-walk@8.3.4", "", { "dependencies": { "acorn": "^8.11.0" } }, "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g=="], 117 | 118 | "ajv": ["ajv@6.12.6", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="], 119 | 120 | "ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], 121 | 122 | "ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], 123 | 124 | "anymatch": ["anymatch@3.1.3", "", { "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } }, "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw=="], 125 | 126 | "arg": ["arg@4.1.3", "", {}, "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA=="], 127 | 128 | "argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="], 129 | 130 | "array-flatten": ["array-flatten@1.1.1", "", {}, "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="], 131 | 132 | "array-union": ["array-union@2.1.0", "", {}, "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw=="], 133 | 134 | "balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], 135 | 136 | "binary-extensions": ["binary-extensions@2.3.0", "", {}, "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw=="], 137 | 138 | "body-parser": ["body-parser@1.20.3", "", { "dependencies": { "bytes": "3.1.2", "content-type": "~1.0.5", "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", "http-errors": "2.0.0", "iconv-lite": "0.4.24", "on-finished": "2.4.1", "qs": "6.13.0", "raw-body": "2.5.2", "type-is": "~1.6.18", "unpipe": "1.0.0" } }, "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g=="], 139 | 140 | "brace-expansion": ["brace-expansion@1.1.11", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA=="], 141 | 142 | "braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="], 143 | 144 | "buffer-from": ["buffer-from@1.1.2", "", {}, "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="], 145 | 146 | "bytes": ["bytes@3.1.2", "", {}, "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="], 147 | 148 | "call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="], 149 | 150 | "call-bound": ["call-bound@1.0.4", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" } }, "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg=="], 151 | 152 | "callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="], 153 | 154 | "chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], 155 | 156 | "chokidar": ["chokidar@3.6.0", "", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="], 157 | 158 | "color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="], 159 | 160 | "color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="], 161 | 162 | "concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="], 163 | 164 | "content-disposition": ["content-disposition@0.5.4", "", { "dependencies": { "safe-buffer": "5.2.1" } }, "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ=="], 165 | 166 | "content-type": ["content-type@1.0.5", "", {}, "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA=="], 167 | 168 | "cookie": ["cookie@0.7.1", "", {}, "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w=="], 169 | 170 | "cookie-signature": ["cookie-signature@1.0.6", "", {}, "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="], 171 | 172 | "create-require": ["create-require@1.1.1", "", {}, "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ=="], 173 | 174 | "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="], 175 | 176 | "debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="], 177 | 178 | "deep-is": ["deep-is@0.1.4", "", {}, "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="], 179 | 180 | "depd": ["depd@2.0.0", "", {}, "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="], 181 | 182 | "destroy": ["destroy@1.2.0", "", {}, "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg=="], 183 | 184 | "diff": ["diff@4.0.2", "", {}, "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A=="], 185 | 186 | "dir-glob": ["dir-glob@3.0.1", "", { "dependencies": { "path-type": "^4.0.0" } }, "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA=="], 187 | 188 | "doctrine": ["doctrine@3.0.0", "", { "dependencies": { "esutils": "^2.0.2" } }, "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w=="], 189 | 190 | "dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="], 191 | 192 | "dynamic-dedupe": ["dynamic-dedupe@0.3.0", "", { "dependencies": { "xtend": "^4.0.0" } }, "sha512-ssuANeD+z97meYOqd50e04Ze5qp4bPqo8cCkI4TRjZkzAUgIDTrXV1R8QCdINpiI+hw14+rYazvTRdQrz0/rFQ=="], 193 | 194 | "ee-first": ["ee-first@1.1.1", "", {}, "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="], 195 | 196 | "encodeurl": ["encodeurl@2.0.0", "", {}, "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg=="], 197 | 198 | "es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="], 199 | 200 | "es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="], 201 | 202 | "es-object-atoms": ["es-object-atoms@1.1.1", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA=="], 203 | 204 | "escape-html": ["escape-html@1.0.3", "", {}, "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="], 205 | 206 | "escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="], 207 | 208 | "eslint": ["eslint@8.57.1", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.4", "@eslint/js": "8.57.1", "@humanwhocodes/config-array": "^0.13.0", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", "@ungap/structured-clone": "^1.2.0", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", "eslint-scope": "^7.2.2", "eslint-visitor-keys": "^3.4.3", "espree": "^9.6.1", "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "globals": "^13.19.0", "graphemer": "^1.4.0", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "is-path-inside": "^3.0.3", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3", "strip-ansi": "^6.0.1", "text-table": "^0.2.0" }, "bin": { "eslint": "bin/eslint.js" } }, "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA=="], 209 | 210 | "eslint-scope": ["eslint-scope@7.2.2", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg=="], 211 | 212 | "eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="], 213 | 214 | "espree": ["espree@9.6.1", "", { "dependencies": { "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.4.1" } }, "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ=="], 215 | 216 | "esquery": ["esquery@1.6.0", "", { "dependencies": { "estraverse": "^5.1.0" } }, "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg=="], 217 | 218 | "esrecurse": ["esrecurse@4.3.0", "", { "dependencies": { "estraverse": "^5.2.0" } }, "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag=="], 219 | 220 | "estraverse": ["estraverse@5.3.0", "", {}, "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="], 221 | 222 | "esutils": ["esutils@2.0.3", "", {}, "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="], 223 | 224 | "etag": ["etag@1.8.1", "", {}, "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="], 225 | 226 | "express": ["express@4.21.2", "", { "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", "body-parser": "1.20.3", "content-disposition": "0.5.4", "content-type": "~1.0.4", "cookie": "0.7.1", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", "finalhandler": "1.3.1", "fresh": "0.5.2", "http-errors": "2.0.0", "merge-descriptors": "1.0.3", "methods": "~1.1.2", "on-finished": "2.4.1", "parseurl": "~1.3.3", "path-to-regexp": "0.1.12", "proxy-addr": "~2.0.7", "qs": "6.13.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", "send": "0.19.0", "serve-static": "1.16.2", "setprototypeof": "1.2.0", "statuses": "2.0.1", "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" } }, "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA=="], 227 | 228 | "fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="], 229 | 230 | "fast-glob": ["fast-glob@3.3.3", "", { "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.8" } }, "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg=="], 231 | 232 | "fast-json-stable-stringify": ["fast-json-stable-stringify@2.1.0", "", {}, "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="], 233 | 234 | "fast-levenshtein": ["fast-levenshtein@2.0.6", "", {}, "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="], 235 | 236 | "fastq": ["fastq@1.19.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ=="], 237 | 238 | "file-entry-cache": ["file-entry-cache@6.0.1", "", { "dependencies": { "flat-cache": "^3.0.4" } }, "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg=="], 239 | 240 | "fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="], 241 | 242 | "finalhandler": ["finalhandler@1.3.1", "", { "dependencies": { "debug": "2.6.9", "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "on-finished": "2.4.1", "parseurl": "~1.3.3", "statuses": "2.0.1", "unpipe": "~1.0.0" } }, "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ=="], 243 | 244 | "find-up": ["find-up@5.0.0", "", { "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" } }, "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng=="], 245 | 246 | "flat-cache": ["flat-cache@3.2.0", "", { "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.3", "rimraf": "^3.0.2" } }, "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw=="], 247 | 248 | "flatted": ["flatted@3.3.3", "", {}, "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg=="], 249 | 250 | "forwarded": ["forwarded@0.2.0", "", {}, "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="], 251 | 252 | "fresh": ["fresh@0.5.2", "", {}, "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q=="], 253 | 254 | "fs.realpath": ["fs.realpath@1.0.0", "", {}, "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="], 255 | 256 | "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], 257 | 258 | "function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="], 259 | 260 | "get-intrinsic": ["get-intrinsic@1.3.0", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "math-intrinsics": "^1.1.0" } }, "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ=="], 261 | 262 | "get-proto": ["get-proto@1.0.1", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" } }, "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g=="], 263 | 264 | "glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="], 265 | 266 | "glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="], 267 | 268 | "globals": ["globals@13.24.0", "", { "dependencies": { "type-fest": "^0.20.2" } }, "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ=="], 269 | 270 | "globby": ["globby@11.1.0", "", { "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", "fast-glob": "^3.2.9", "ignore": "^5.2.0", "merge2": "^1.4.1", "slash": "^3.0.0" } }, "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g=="], 271 | 272 | "gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="], 273 | 274 | "graphemer": ["graphemer@1.4.0", "", {}, "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag=="], 275 | 276 | "has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="], 277 | 278 | "has-symbols": ["has-symbols@1.1.0", "", {}, "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="], 279 | 280 | "hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="], 281 | 282 | "http-errors": ["http-errors@2.0.0", "", { "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", "setprototypeof": "1.2.0", "statuses": "2.0.1", "toidentifier": "1.0.1" } }, "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ=="], 283 | 284 | "iconv-lite": ["iconv-lite@0.4.24", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3" } }, "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA=="], 285 | 286 | "ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="], 287 | 288 | "import-fresh": ["import-fresh@3.3.1", "", { "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ=="], 289 | 290 | "imurmurhash": ["imurmurhash@0.1.4", "", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="], 291 | 292 | "inflight": ["inflight@1.0.6", "", { "dependencies": { "once": "^1.3.0", "wrappy": "1" } }, "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA=="], 293 | 294 | "inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="], 295 | 296 | "ipaddr.js": ["ipaddr.js@1.9.1", "", {}, "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="], 297 | 298 | "is-binary-path": ["is-binary-path@2.1.0", "", { "dependencies": { "binary-extensions": "^2.0.0" } }, "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw=="], 299 | 300 | "is-core-module": ["is-core-module@2.16.1", "", { "dependencies": { "hasown": "^2.0.2" } }, "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w=="], 301 | 302 | "is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="], 303 | 304 | "is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="], 305 | 306 | "is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="], 307 | 308 | "is-path-inside": ["is-path-inside@3.0.3", "", {}, "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ=="], 309 | 310 | "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], 311 | 312 | "js-yaml": ["js-yaml@4.1.0", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA=="], 313 | 314 | "json-buffer": ["json-buffer@3.0.1", "", {}, "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="], 315 | 316 | "json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="], 317 | 318 | "json-stable-stringify-without-jsonify": ["json-stable-stringify-without-jsonify@1.0.1", "", {}, "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw=="], 319 | 320 | "keyv": ["keyv@4.5.4", "", { "dependencies": { "json-buffer": "3.0.1" } }, "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw=="], 321 | 322 | "levn": ["levn@0.4.1", "", { "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="], 323 | 324 | "locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="], 325 | 326 | "lodash.merge": ["lodash.merge@4.6.2", "", {}, "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="], 327 | 328 | "make-error": ["make-error@1.3.6", "", {}, "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw=="], 329 | 330 | "math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="], 331 | 332 | "media-typer": ["media-typer@0.3.0", "", {}, "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ=="], 333 | 334 | "merge-descriptors": ["merge-descriptors@1.0.3", "", {}, "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ=="], 335 | 336 | "merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="], 337 | 338 | "methods": ["methods@1.1.2", "", {}, "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w=="], 339 | 340 | "micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="], 341 | 342 | "mime": ["mime@1.6.0", "", { "bin": { "mime": "cli.js" } }, "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="], 343 | 344 | "mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="], 345 | 346 | "mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="], 347 | 348 | "minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="], 349 | 350 | "minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="], 351 | 352 | "mkdirp": ["mkdirp@1.0.4", "", { "bin": { "mkdirp": "bin/cmd.js" } }, "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="], 353 | 354 | "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], 355 | 356 | "natural-compare": ["natural-compare@1.4.0", "", {}, "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="], 357 | 358 | "negotiator": ["negotiator@0.6.3", "", {}, "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg=="], 359 | 360 | "normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="], 361 | 362 | "object-inspect": ["object-inspect@1.13.4", "", {}, "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew=="], 363 | 364 | "on-finished": ["on-finished@2.4.1", "", { "dependencies": { "ee-first": "1.1.1" } }, "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg=="], 365 | 366 | "once": ["once@1.4.0", "", { "dependencies": { "wrappy": "1" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="], 367 | 368 | "optionator": ["optionator@0.9.4", "", { "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", "word-wrap": "^1.2.5" } }, "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g=="], 369 | 370 | "p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="], 371 | 372 | "p-locate": ["p-locate@5.0.0", "", { "dependencies": { "p-limit": "^3.0.2" } }, "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw=="], 373 | 374 | "parent-module": ["parent-module@1.0.1", "", { "dependencies": { "callsites": "^3.0.0" } }, "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g=="], 375 | 376 | "parseurl": ["parseurl@1.3.3", "", {}, "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="], 377 | 378 | "path-exists": ["path-exists@4.0.0", "", {}, "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="], 379 | 380 | "path-is-absolute": ["path-is-absolute@1.0.1", "", {}, "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg=="], 381 | 382 | "path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="], 383 | 384 | "path-parse": ["path-parse@1.0.7", "", {}, "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="], 385 | 386 | "path-to-regexp": ["path-to-regexp@0.1.12", "", {}, "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ=="], 387 | 388 | "path-type": ["path-type@4.0.0", "", {}, "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw=="], 389 | 390 | "picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], 391 | 392 | "prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="], 393 | 394 | "prettier": ["prettier@3.5.3", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw=="], 395 | 396 | "proxy-addr": ["proxy-addr@2.0.7", "", { "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" } }, "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg=="], 397 | 398 | "punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="], 399 | 400 | "qs": ["qs@6.13.0", "", { "dependencies": { "side-channel": "^1.0.6" } }, "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg=="], 401 | 402 | "queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="], 403 | 404 | "range-parser": ["range-parser@1.2.1", "", {}, "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="], 405 | 406 | "raw-body": ["raw-body@2.5.2", "", { "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", "iconv-lite": "0.4.24", "unpipe": "1.0.0" } }, "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA=="], 407 | 408 | "readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="], 409 | 410 | "resolve": ["resolve@1.22.10", "", { "dependencies": { "is-core-module": "^2.16.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w=="], 411 | 412 | "resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="], 413 | 414 | "reusify": ["reusify@1.1.0", "", {}, "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="], 415 | 416 | "rimraf": ["rimraf@2.7.1", "", { "dependencies": { "glob": "^7.1.3" }, "bin": { "rimraf": "./bin.js" } }, "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w=="], 417 | 418 | "run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="], 419 | 420 | "safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="], 421 | 422 | "safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="], 423 | 424 | "semver": ["semver@7.7.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA=="], 425 | 426 | "send": ["send@0.19.0", "", { "dependencies": { "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", "http-errors": "2.0.0", "mime": "1.6.0", "ms": "2.1.3", "on-finished": "2.4.1", "range-parser": "~1.2.1", "statuses": "2.0.1" } }, "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw=="], 427 | 428 | "serve-static": ["serve-static@1.16.2", "", { "dependencies": { "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "parseurl": "~1.3.3", "send": "0.19.0" } }, "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw=="], 429 | 430 | "setprototypeof": ["setprototypeof@1.2.0", "", {}, "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="], 431 | 432 | "shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="], 433 | 434 | "shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="], 435 | 436 | "side-channel": ["side-channel@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3", "side-channel-list": "^1.0.0", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" } }, "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw=="], 437 | 438 | "side-channel-list": ["side-channel-list@1.0.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3" } }, "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA=="], 439 | 440 | "side-channel-map": ["side-channel-map@1.0.1", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3" } }, "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA=="], 441 | 442 | "side-channel-weakmap": ["side-channel-weakmap@1.0.2", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3", "side-channel-map": "^1.0.1" } }, "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A=="], 443 | 444 | "slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="], 445 | 446 | "source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="], 447 | 448 | "source-map-support": ["source-map-support@0.5.21", "", { "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" } }, "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w=="], 449 | 450 | "statuses": ["statuses@2.0.1", "", {}, "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ=="], 451 | 452 | "strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], 453 | 454 | "strip-bom": ["strip-bom@3.0.0", "", {}, "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA=="], 455 | 456 | "strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="], 457 | 458 | "supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="], 459 | 460 | "supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="], 461 | 462 | "text-table": ["text-table@0.2.0", "", {}, "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw=="], 463 | 464 | "to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="], 465 | 466 | "toidentifier": ["toidentifier@1.0.1", "", {}, "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="], 467 | 468 | "tree-kill": ["tree-kill@1.2.2", "", { "bin": { "tree-kill": "cli.js" } }, "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A=="], 469 | 470 | "ts-api-utils": ["ts-api-utils@1.4.3", "", { "peerDependencies": { "typescript": ">=4.2.0" } }, "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw=="], 471 | 472 | "ts-node": ["ts-node@10.9.2", "", { "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", "@tsconfig/node12": "^1.0.7", "@tsconfig/node14": "^1.0.0", "@tsconfig/node16": "^1.0.2", "acorn": "^8.4.1", "acorn-walk": "^8.1.1", "arg": "^4.1.0", "create-require": "^1.1.0", "diff": "^4.0.1", "make-error": "^1.1.1", "v8-compile-cache-lib": "^3.0.1", "yn": "3.1.1" }, "peerDependencies": { "@swc/core": ">=1.2.50", "@swc/wasm": ">=1.2.50", "@types/node": "*", "typescript": ">=2.7" }, "optionalPeers": ["@swc/core", "@swc/wasm"], "bin": { "ts-node": "dist/bin.js", "ts-script": "dist/bin-script-deprecated.js", "ts-node-cwd": "dist/bin-cwd.js", "ts-node-esm": "dist/bin-esm.js", "ts-node-script": "dist/bin-script.js", "ts-node-transpile-only": "dist/bin-transpile.js" } }, "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ=="], 473 | 474 | "ts-node-dev": ["ts-node-dev@2.0.0", "", { "dependencies": { "chokidar": "^3.5.1", "dynamic-dedupe": "^0.3.0", "minimist": "^1.2.6", "mkdirp": "^1.0.4", "resolve": "^1.0.0", "rimraf": "^2.6.1", "source-map-support": "^0.5.12", "tree-kill": "^1.2.2", "ts-node": "^10.4.0", "tsconfig": "^7.0.0" }, "peerDependencies": { "node-notifier": "*", "typescript": "*" }, "optionalPeers": ["node-notifier"], "bin": { "ts-node-dev": "lib/bin.js", "tsnd": "lib/bin.js" } }, "sha512-ywMrhCfH6M75yftYvrvNarLEY+SUXtUvU8/0Z6llrHQVBx12GiFk5sStF8UdfE/yfzk9IAq7O5EEbTQsxlBI8w=="], 475 | 476 | "tsconfig": ["tsconfig@7.0.0", "", { "dependencies": { "@types/strip-bom": "^3.0.0", "@types/strip-json-comments": "0.0.30", "strip-bom": "^3.0.0", "strip-json-comments": "^2.0.0" } }, "sha512-vZXmzPrL+EmC4T/4rVlT2jNVMWCi/O4DIiSj3UHg1OE5kCKbk4mfrXc6dZksLgRM/TZlKnousKH9bbTazUWRRw=="], 477 | 478 | "type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="], 479 | 480 | "type-fest": ["type-fest@0.20.2", "", {}, "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ=="], 481 | 482 | "type-is": ["type-is@1.6.18", "", { "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" } }, "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g=="], 483 | 484 | "typescript": ["typescript@5.8.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ=="], 485 | 486 | "undici-types": ["undici-types@6.19.8", "", {}, "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw=="], 487 | 488 | "unpipe": ["unpipe@1.0.0", "", {}, "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="], 489 | 490 | "uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="], 491 | 492 | "utils-merge": ["utils-merge@1.0.1", "", {}, "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA=="], 493 | 494 | "v8-compile-cache-lib": ["v8-compile-cache-lib@3.0.1", "", {}, "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg=="], 495 | 496 | "vary": ["vary@1.1.2", "", {}, "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="], 497 | 498 | "which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="], 499 | 500 | "word-wrap": ["word-wrap@1.2.5", "", {}, "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="], 501 | 502 | "wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="], 503 | 504 | "xtend": ["xtend@4.0.2", "", {}, "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="], 505 | 506 | "yn": ["yn@3.1.1", "", {}, "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q=="], 507 | 508 | "yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="], 509 | 510 | "@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.3", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg=="], 511 | 512 | "body-parser/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], 513 | 514 | "chokidar/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], 515 | 516 | "express/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], 517 | 518 | "fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], 519 | 520 | "finalhandler/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], 521 | 522 | "flat-cache/rimraf": ["rimraf@3.0.2", "", { "dependencies": { "glob": "^7.1.3" }, "bin": { "rimraf": "bin.js" } }, "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA=="], 523 | 524 | "send/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], 525 | 526 | "send/encodeurl": ["encodeurl@1.0.2", "", {}, "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w=="], 527 | 528 | "tsconfig/strip-json-comments": ["strip-json-comments@2.0.1", "", {}, "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ=="], 529 | 530 | "@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="], 531 | 532 | "body-parser/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="], 533 | 534 | "express/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="], 535 | 536 | "finalhandler/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="], 537 | 538 | "send/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="], 539 | } 540 | } 541 | --------------------------------------------------------------------------------