@seedcord/services 0.6.0 → 0.7.0-next.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/Logger.ts","../src/CooldownManager.ts","../src/Errors/ErrorCodes.ts","../src/Errors/ErrorMessages.ts","../src/Errors/SeedcordError.ts","../src/Lifecycle/CoordinatedLifecycle.ts","../src/Lifecycle/CoordinatedShutdown.ts","../src/HealthCheck.ts","../src/StrictEventEmitter.ts","../src/Lifecycle/CoordinatedStartup.ts"],"names":["Logger","instances","Map","instance","prefix","get","set","transportName","consoleTransport","createConsoleTransport","initializeLogger","getFormatCustomizations","padding","format","errors","stack","splat","colorize","level","timestamp","printf","info","ts","String","lvl","padEnd","lbl","label","msg","message","base","splatSym","Symbol","for","raw","extras","Array","isArray","cleaned","filter","x","Error","Object","keys","length","rendered","parts","push","JSON","stringify","join","transports","Console","combine","Envapter","isDevelopment","isStaging","transportsArray","maxSizeInMB","File","filename","uncolorize","json","bigint","space","maxsize","maxFiles","tailable","logger","createLogger","error","args","warn","http","verbose","debug","silly","Info","Warn","Debug","Silly","CooldownManager","window","Err","map","opts","cooldown","err","key","Date","now","check","last","remaining","undefined","isActive","clear","delete","SeedcordErrorCode","messages","ConfigMissingDiscordToken","ConfigUnknownExceptionWebhookMissing","ConfigUnknownExceptionWebhookInvalid","LifecycleAddAfterCompletion","LifecycleAddDuringRun","LifecycleRemoveDuringRun","LifecycleUnknownPhase","phase","LifecyclePhaseFailures","failures","LifecycleTaskTimeout","taskName","timeout","CoreSingletonViolation","CorePluginAfterInit","CorePluginKeyExists","CoreBotRoleMissing","guildId","DecoratorInteractionEventFilter","DecoratorMethodNotFound","DecoratorCommandAlreadyRegistered","commandName","existingScope","requestedScope","DecoratorCommandGlobalWithGuilds","DecoratorCommandGuildWithoutGuilds","DecoratorInvalidMiddlewarePriority","UtilHexInputType","UtilHexInvalid","UtilInvalidSlashRouteArgument","PluginMongoServiceDecoratorMissing","className","PluginMongoModelDecoratorMissing","PluginMongoConnectionFailed","databaseName","PluginKpgServiceDecoratorMissing","PluginKpgServiceTableMissing","PluginKpgInvalidStepCount","PluginKpgUnknownDirection","direction","PluginKpgUnresolvedMigrationsPath","PluginKpgNoMigrationFiles","PluginKpgInvalidMigrationModule","filePath","PluginKpgNonErrorFailure","formatSeedcordErrorMessage","code","formatter","resolvedArgs","resolveIdentifier","resolveMessage","formatErrorName","name","_identifier","chalk","bold","red","gray","SeedcordError","identifier","options","setPrototypeOf","prototype","captureStackTrace","SeedcordTypeError","TypeError","SeedcordRangeError","RangeError","SeedcordErrors","isSeedcordError","CoordinatedLifecycle","events","EventEmitter","tasksMap","loggerName","phaseOrder","phaseEnum","forEach","addTask","task","timeoutMs","canAddTask","tasks","italic","getTaskType","cyan","magenta","removeTask","canRemoveTask","initialLength","filteredTasks","removed","runPhase","yellow","emit","results","executeTasksInPhase","r","status","green","runTaskWithTimeout","Promise","race","_","reject","setTimeout","on","event","listener","off","ShutdownPhase","PHASE_ORDER","LOG_FLUSH_DELAY_MS","CoordinatedShutdown","isShuttingDown","exitCode","registerSignalHandlers","isShutdownEnabled","resolve","then","value","reason","process","run","exit","fallback","HTTP_OK","HTTP_NOT_FOUND","HealthCheck","server","shutdown","StopServices","stop","init","createServer","req","res","method","url","path","writeHead","end","once","address","host","port","listen","close","StrictEventEmitter","addListener","removeListener","listeners","listenerCountTyped","listenerCount","eventNamesTyped","eventNames","waitFor","onEvent","cleanup","onAbort","assign","timeoutId","signal","removeEventListener","aborted","addEventListener","StartupPhase","CoordinatedStartup","isStartingUp","hasStarted","isReady","isRunning"],"mappings":"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","file":"index.mjs","sourcesContent":["/* eslint-disable @typescript-eslint/no-base-to-string */\n/* eslint-disable @typescript-eslint/naming-convention */\nimport { Envapter } from 'envapt';\nimport { createLogger, format, transports } from 'winston';\n\nimport type { ILogger } from '@seedcord/types';\nimport type { Logform, Logger as Winston } from 'winston';\nimport type { ConsoleTransportInstance } from 'winston/lib/winston/transports';\n\n/**\n * Logging service with console and file output support\n *\n * Provides structured logging with timestamps, levels, and labels.\n * Instances are cached by transport name for consistent formatting.\n */\nexport class Logger implements ILogger {\n declare private logger: Winston;\n private static readonly instances = new Map<string, Logger>();\n\n private static instance(prefix: string): Logger {\n let instance = this.instances.get(prefix);\n if (!instance) {\n instance = new Logger(prefix);\n this.instances.set(prefix, instance);\n }\n return instance;\n }\n\n constructor(transportName: string) {\n const consoleTransport = this.createConsoleTransport(transportName);\n this.initializeLogger(consoleTransport);\n }\n\n private getFormatCustomizations(): Logform.Format[] {\n const padding = 7;\n return [\n format.errors({ stack: true }),\n format.splat(),\n format.colorize({ level: true }),\n format.timestamp({ format: 'D MMM, hh:mm:ss a' }),\n format.printf((info: Logform.TransformableInfo) => {\n const ts = String(info.timestamp ?? '');\n const lvl = String(info.level).padEnd(padding);\n const lbl = String(info.label ?? '');\n const msg = String(info.message ?? '');\n\n const base = `${ts} [${lvl}]: ${lbl} - ${msg}`;\n\n const splatSym = Symbol.for('splat');\n const raw = (info as unknown as Record<string | symbol, unknown>)[splatSym];\n const extras = Array.isArray(raw) ? raw : [];\n\n const cleaned = extras\n .filter((x) => !(x instanceof Error))\n .filter((x) => {\n if (!x) return false;\n if (typeof x !== 'object') return true;\n return Object.keys(x as object).length > 0;\n });\n\n let rendered = base;\n\n if (typeof info.stack === 'string') {\n rendered += `\\n${String(info.stack)}`;\n }\n\n if (cleaned.length) {\n const parts: string[] = [];\n for (const x of cleaned) {\n if (typeof x === 'string') parts.push(x);\n else {\n try {\n parts.push(JSON.stringify(x, null, 2));\n } catch {\n parts.push(String(x));\n }\n }\n }\n rendered += `\\n${parts.join(' ')}`;\n }\n\n return rendered;\n })\n ];\n }\n\n private createConsoleTransport(transportName: string): ConsoleTransportInstance {\n return new transports.Console({\n format: format.combine(format.label({ label: transportName }), ...this.getFormatCustomizations()),\n level: Envapter.isDevelopment ? 'silly' : Envapter.isStaging ? 'debug' : 'info'\n });\n }\n\n private initializeLogger(consoleTransport: transports.ConsoleTransportInstance): void {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const transportsArray: any[] = [consoleTransport];\n\n // Add file transport only in non-production environments\n if (Envapter.isDevelopment) {\n const maxSizeInMB = 10;\n transportsArray.push(\n new transports.File({\n filename: 'logs/application.log',\n level: 'debug',\n format: format.combine(\n format.uncolorize(),\n format.errors({ stack: true }),\n format.timestamp(),\n format.json({ bigint: true, space: 2 })\n ),\n maxsize: maxSizeInMB * 1024 * 1024, // 10MB\n maxFiles: 5,\n tailable: true\n })\n );\n }\n\n this.logger = createLogger({\n transports: transportsArray\n });\n }\n\n /**\n * Logs an error message with optional additional data.\n *\n * @param msg - The error message to log\n * @param args - Additional data to include in the log entry\n */\n public error(msg: string, ...args: unknown[]): void {\n this.logger.error(msg, ...args);\n }\n\n /**\n * Logs a warning message with optional additional data.\n *\n * @param msg - The warning message to log\n * @param args - Additional data to include in the log entry\n */\n public warn(msg: string, ...args: unknown[]): void {\n this.logger.warn(msg, ...args);\n }\n\n /**\n * Logs an informational message with optional additional data.\n *\n * @param msg - The informational message to log\n * @param args - Additional data to include in the log entry\n */\n public info(msg: string, ...args: unknown[]): void {\n this.logger.info(msg, ...args);\n }\n\n /**\n * Logs an HTTP-related message with optional additional data.\n *\n * @param msg - The HTTP message to log\n * @param args - Additional data to include in the log entry\n */\n public http(msg: string, ...args: unknown[]): void {\n this.logger.http(msg, ...args);\n }\n\n /**\n * Logs a verbose message with optional additional data.\n *\n * @param msg - The verbose message to log\n * @param args - Additional data to include in the log entry\n */\n public verbose(msg: string, ...args: unknown[]): void {\n this.logger.verbose(msg, ...args);\n }\n\n /**\n * Logs a debug message with optional additional data.\n *\n * @param msg - The debug message to log\n * @param args - Additional data to include in the log entry\n */\n public debug(msg: string, ...args: unknown[]): void {\n this.logger.debug(msg, ...args);\n }\n\n /**\n * Logs a silly/trace level message with optional additional data.\n *\n * @param msg - The silly message to log\n * @param args - Additional data to include in the log entry\n */\n public silly(msg: string, ...args: unknown[]): void {\n this.logger.silly(msg, ...args);\n }\n\n /**\n * Static method to log an error message with a specific prefix.\n * Creates or retrieves a logger instance for the given prefix.\n *\n * @param prefix - The logger prefix/label to use\n * @param msg - The error message to log\n * @param args - Additional data to include in the log entry\n */\n public static Error(prefix: string, msg: string, ...args: unknown[]): void {\n const logger = this.instance(prefix);\n logger.error(msg, ...args);\n }\n\n /**\n * Static method to log an informational message with a specific prefix.\n * Creates or retrieves a logger instance for the given prefix.\n *\n * @param prefix - The logger prefix/label to use\n * @param msg - The informational message to log\n * @param args - Additional data to include in the log entry\n */\n public static Info(prefix: string, msg: string, ...args: unknown[]): void {\n const logger = this.instance(prefix);\n logger.info(msg, ...args);\n }\n\n /**\n * Static method to log a warning message with a specific prefix.\n * Creates or retrieves a logger instance for the given prefix.\n *\n * @param prefix - The logger prefix/label to use\n * @param msg - The warning message to log\n * @param args - Additional data to include in the log entry\n */\n public static Warn(prefix: string, msg: string, ...args: unknown[]): void {\n const logger = this.instance(prefix);\n logger.warn(msg, ...args);\n }\n\n /**\n * Static method to log a debug message with a specific prefix.\n * Creates or retrieves a logger instance for the given prefix.\n *\n * @param prefix - The logger prefix/label to use\n * @param msg - The debug message to log\n * @param args - Additional data to include in the log entry\n */\n public static Debug(prefix: string, msg: string, ...args: unknown[]): void {\n const logger = this.instance(prefix);\n logger.debug(msg, ...args);\n }\n\n /**\n * Static method to log a silly/trace level message with a specific prefix.\n * Creates or retrieves a logger instance for the given prefix.\n *\n * @param prefix - The logger prefix/label to use\n * @param msg - The silly message to log\n * @param args - Additional data to include in the log entry\n */\n public static Silly(prefix: string, msg: string, ...args: unknown[]): void {\n const logger = this.instance(prefix);\n logger.silly(msg, ...args);\n }\n}\n","import { Envapter } from 'envapt';\n\nimport { Logger } from './Logger';\n\n/**\n * Configuration options for CooldownManager.\n */\nexport interface CooldownOptions {\n /** Cooldown window in milliseconds (default 1000) */\n cooldown?: number;\n /** Custom error class to throw when a key is still cooling down */\n err?: new (msg: string, ...args: any[]) => Error;\n /** Message passed to the error constructor (default \"Cooldown active\") */\n message?: string;\n}\n\n/**\n * Lightweight utility for per-key cooldowns.\n *\n * Manages time-based restrictions on operations by key,\n * useful for rate limiting, command cooldowns, and spam prevention.\n */\nexport class CooldownManager {\n private readonly window: number;\n private readonly Err: new (msg: string, ...args: any[]) => Error;\n private readonly msg: string;\n private readonly map = new Map<string, number>();\n\n /**\n * Creates a new CooldownManager instance.\n *\n * @param opts - Configuration options for the cooldown behavior\n */\n constructor(opts: CooldownOptions = {}) {\n this.window = opts.cooldown ?? 1_000;\n this.Err = opts.err ?? Error;\n this.msg = opts.message ?? 'Cooldown active';\n }\n\n /**\n * Records usage timestamp for a key without any cooldown checks.\n *\n * @param key - The unique identifier for the cooldown entry\n */\n set(key: string): void {\n this.map.set(key, Date.now());\n }\n\n /**\n * Verifies cooldown status for a key and updates timestamp if not active.\n *\n * If the cooldown is still active, throws the configured error.\n * If not active, updates the timestamp and returns successfully.\n *\n * @param key - The unique identifier to check cooldown for\n * @throws An {@link Err} When the cooldown is still active for the given key\n */\n check(key: string): void {\n const now = Date.now();\n const last = this.map.get(key);\n const remaining = this.window - (now - (last ?? 0));\n\n if (Envapter.isDevelopment && remaining > 0) {\n Logger.Debug('CooldownManager', `${key} - ${remaining}ms remaining`);\n }\n\n if (last !== undefined && remaining > 0) {\n throw new this.Err(this.msg, remaining);\n }\n this.map.set(key, now);\n }\n\n /**\n * Checks if a key is currently cooling down without updating timestamp.\n *\n * @param key - The unique identifier to check\n * @returns True if the key is still cooling down, false otherwise\n */\n isActive(key: string): boolean {\n const last = this.map.get(key);\n return last !== undefined && Date.now() - last < this.window;\n }\n\n /**\n * Removes a key from the cooldown map.\n *\n * @param key - The unique identifier to remove (useful for manual resets)\n */\n clear(key: string): void {\n this.map.delete(key);\n }\n}\n","/* eslint-disable no-magic-numbers */\n\nexport enum SeedcordErrorCode {\n ConfigMissingDiscordToken = 1001,\n ConfigUnknownExceptionWebhookMissing = 1002,\n ConfigUnknownExceptionWebhookInvalid = 1003,\n\n LifecycleAddAfterCompletion = 1101,\n LifecycleAddDuringRun = 1102,\n LifecycleRemoveDuringRun = 1103,\n LifecycleUnknownPhase = 1104,\n LifecyclePhaseFailures = 1105,\n LifecycleTaskTimeout = 1106,\n\n CoreSingletonViolation = 1201,\n CorePluginAfterInit = 1202,\n CorePluginKeyExists = 1203,\n CoreBotRoleMissing = 1204,\n\n DecoratorInteractionEventFilter = 1301,\n DecoratorMethodNotFound = 1302,\n DecoratorCommandAlreadyRegistered = 1303,\n DecoratorCommandGlobalWithGuilds = 1304,\n DecoratorCommandGuildWithoutGuilds = 1305,\n DecoratorInvalidMiddlewarePriority = 1306,\n\n UtilHexInputType = 1401,\n UtilHexInvalid = 1402,\n UtilInvalidSlashRouteArgument = 1403,\n\n PluginMongoServiceDecoratorMissing = 2101,\n PluginMongoModelDecoratorMissing = 2102,\n PluginMongoConnectionFailed = 2103,\n\n PluginKpgServiceDecoratorMissing = 2201,\n PluginKpgServiceTableMissing = 2202,\n PluginKpgInvalidStepCount = 2203,\n PluginKpgUnknownDirection = 2204,\n PluginKpgUnresolvedMigrationsPath = 2205,\n PluginKpgNoMigrationFiles = 2206,\n PluginKpgInvalidMigrationModule = 2207,\n PluginKpgNonErrorFailure = 2208\n}\n","import { SeedcordErrorCode } from './ErrorCodes';\n\nconst messages = {\n [SeedcordErrorCode.ConfigMissingDiscordToken]: () => 'Missing DISCORD_BOT_TOKEN environment variable.',\n [SeedcordErrorCode.ConfigUnknownExceptionWebhookMissing]: () =>\n 'Missing UNKNOWN_EXCEPTION_WEBHOOK_URL environment variable.',\n [SeedcordErrorCode.ConfigUnknownExceptionWebhookInvalid]: () => 'Invalid UNKNOWN_EXCEPTION_WEBHOOK_URL value.',\n\n [SeedcordErrorCode.LifecycleAddAfterCompletion]: () =>\n 'Cannot add tasks after startup sequence has already completed.',\n [SeedcordErrorCode.LifecycleAddDuringRun]: () => 'Cannot add tasks while startup sequence is in progress.',\n [SeedcordErrorCode.LifecycleRemoveDuringRun]: () => 'Cannot remove tasks while startup sequence is in progress.',\n [SeedcordErrorCode.LifecycleUnknownPhase]: (phase: unknown) => `Unknown phase: ${String(phase)}.`,\n [SeedcordErrorCode.LifecyclePhaseFailures]: (phase: string, failures: number) =>\n `Phase ${phase} completed with ${failures} failed task${failures === 1 ? '' : 's'}.`,\n [SeedcordErrorCode.LifecycleTaskTimeout]: (taskName: string, timeout: number) =>\n `Task \"${taskName}\" timed out after ${timeout}ms.`,\n\n [SeedcordErrorCode.CoreSingletonViolation]: () =>\n 'Seedcord can only be instantiated once. Use the existing instance instead.',\n [SeedcordErrorCode.CorePluginAfterInit]: () => 'Cannot attach a plugin after initialization.',\n [SeedcordErrorCode.CorePluginKeyExists]: (key: string) => `Plugin with key \"${key}\" already exists.`,\n [SeedcordErrorCode.CoreBotRoleMissing]: (guildId?: string) =>\n guildId ? `Bot role not found in guild ${guildId}.` : 'Bot role not found in guild.',\n\n [SeedcordErrorCode.DecoratorInteractionEventFilter]: () => 'Interaction middleware cannot specify event filters.',\n [SeedcordErrorCode.DecoratorMethodNotFound]: () =>\n 'Decorator could not locate the original method. Ensure the method exists before applying the decorator.',\n [SeedcordErrorCode.DecoratorCommandAlreadyRegistered]: (\n commandName: string,\n existingScope: string,\n requestedScope: string\n ) =>\n `Command \"${commandName}\" is already registered as a \"${existingScope}\" command and cannot be re-registered as a \"${requestedScope}\" command.`,\n [SeedcordErrorCode.DecoratorCommandGlobalWithGuilds]: () =>\n 'RegisterCommand(\"global\") cannot have guilds specified.',\n [SeedcordErrorCode.DecoratorCommandGuildWithoutGuilds]: () =>\n 'RegisterCommand(\"guild\") requires a non-empty guilds array.',\n [SeedcordErrorCode.DecoratorInvalidMiddlewarePriority]: () => 'Middleware priority must be a finite number.',\n\n [SeedcordErrorCode.UtilHexInputType]: () => 'hexToNumber expects a string input.',\n [SeedcordErrorCode.UtilHexInvalid]: () => 'Invalid hex string.',\n [SeedcordErrorCode.UtilInvalidSlashRouteArgument]: () => 'Invalid argument passed to buildSlashRoute.',\n\n [SeedcordErrorCode.PluginMongoServiceDecoratorMissing]: (className: string) =>\n `Missing @RegisterMongoService on ${className}.`,\n [SeedcordErrorCode.PluginMongoModelDecoratorMissing]: (className: string) =>\n `Missing @RegisterMongoModel on ${className}.`,\n [SeedcordErrorCode.PluginMongoConnectionFailed]: (databaseName?: string) =>\n databaseName ? `Could not connect to MongoDB (${databaseName}).` : 'Could not connect to MongoDB.',\n\n [SeedcordErrorCode.PluginKpgServiceDecoratorMissing]: (className: string) =>\n `Missing @RegisterKpgService on ${className}.`,\n [SeedcordErrorCode.PluginKpgServiceTableMissing]: (className: string) =>\n `Missing table metadata for ${className}. Provide a table via @RegisterKpgService().`,\n [SeedcordErrorCode.PluginKpgInvalidStepCount]: () => 'Migration step count must be a non-negative integer.',\n [SeedcordErrorCode.PluginKpgUnknownDirection]: (direction: unknown) =>\n `Unknown migration direction: ${String(direction)}.`,\n [SeedcordErrorCode.PluginKpgUnresolvedMigrationsPath]: (label: string) =>\n `Unable to resolve migrations at path: ${label}.`,\n [SeedcordErrorCode.PluginKpgNoMigrationFiles]: () => 'No migration files provided.',\n [SeedcordErrorCode.PluginKpgInvalidMigrationModule]: (filePath: string) =>\n `Migration file ${filePath} must export async functions up and down.`,\n [SeedcordErrorCode.PluginKpgNonErrorFailure]: (message: string) => `Migration failure: ${message}.`\n} as const;\n\nexport type SeedcordErrorArguments<TCode extends SeedcordErrorCode> = Parameters<(typeof messages)[TCode]>;\n\nexport function formatSeedcordErrorMessage<TCode extends SeedcordErrorCode>(\n code: TCode,\n args?: SeedcordErrorArguments<TCode>\n): string {\n const formatter = messages[code];\n const resolvedArgs = (args ?? []) as unknown[];\n return (formatter as (...params: unknown[]) => string)(...resolvedArgs);\n}\n\nexport { messages as seedcordErrorMessages };\n","import chalk from 'chalk';\n\nimport { SeedcordErrorCode } from './ErrorCodes';\nimport { formatSeedcordErrorMessage, type SeedcordErrorArguments } from './ErrorMessages';\n\nexport type SeedcordErrorIdentifier = keyof typeof SeedcordErrorCode;\n\nexport interface SeedcordErrorOptions extends ErrorOptions {}\n\nfunction resolveIdentifier(code: SeedcordErrorCode): SeedcordErrorIdentifier {\n return SeedcordErrorCode[code] as SeedcordErrorIdentifier;\n}\n\nfunction resolveMessage(code: SeedcordErrorCode, args?: SeedcordErrorArguments<SeedcordErrorCode>): string {\n return formatSeedcordErrorMessage(code, args);\n}\n\nfunction formatErrorName(name: string, _identifier: SeedcordErrorIdentifier, code: SeedcordErrorCode): string {\n return `${chalk.bold.red(name)}[${chalk.gray(code)}]`;\n}\n\nexport class SeedcordError extends Error {\n public readonly code: SeedcordErrorCode;\n public readonly identifier: SeedcordErrorIdentifier;\n\n constructor(\n code: SeedcordErrorCode,\n args?: SeedcordErrorArguments<SeedcordErrorCode>,\n options?: SeedcordErrorOptions\n ) {\n const message = resolveMessage(code, args);\n super(message, options);\n this.code = code;\n this.identifier = resolveIdentifier(code);\n this.name = formatErrorName(new.target.name, this.identifier, this.code);\n Object.setPrototypeOf(this, new.target.prototype);\n if (typeof Error.captureStackTrace === 'function') {\n Error.captureStackTrace(this, new.target);\n }\n }\n}\n\nexport class SeedcordTypeError extends TypeError {\n public readonly code: SeedcordErrorCode;\n public readonly identifier: SeedcordErrorIdentifier;\n\n constructor(\n code: SeedcordErrorCode,\n args?: SeedcordErrorArguments<SeedcordErrorCode>,\n options?: SeedcordErrorOptions\n ) {\n const message = resolveMessage(code, args);\n super(message, options);\n this.code = code;\n this.identifier = resolveIdentifier(code);\n this.name = formatErrorName(new.target.name, this.identifier, this.code);\n Object.setPrototypeOf(this, new.target.prototype);\n if (typeof Error.captureStackTrace === 'function') {\n Error.captureStackTrace(this, new.target);\n }\n }\n}\n\nexport class SeedcordRangeError extends RangeError {\n public readonly code: SeedcordErrorCode;\n public readonly identifier: SeedcordErrorIdentifier;\n\n constructor(\n code: SeedcordErrorCode,\n args?: SeedcordErrorArguments<SeedcordErrorCode>,\n options?: SeedcordErrorOptions\n ) {\n const message = resolveMessage(code, args);\n super(message, options);\n this.code = code;\n this.identifier = resolveIdentifier(code);\n this.name = formatErrorName(new.target.name, this.identifier, this.code);\n Object.setPrototypeOf(this, new.target.prototype);\n if (typeof Error.captureStackTrace === 'function') {\n Error.captureStackTrace(this, new.target);\n }\n }\n}\n\nexport const SeedcordErrors = {\n Error: SeedcordError,\n TypeError: SeedcordTypeError,\n RangeError: SeedcordRangeError\n} as const;\n\nexport type AnySeedcordError = SeedcordError | SeedcordTypeError | SeedcordRangeError;\n\nexport function isSeedcordError(error: unknown): error is AnySeedcordError {\n return (\n typeof error === 'object' &&\n error !== null &&\n 'code' in error &&\n typeof (error as { code: unknown }).code === 'number' &&\n 'identifier' in error &&\n typeof (error as { identifier: unknown }).identifier === 'string'\n );\n}\n","/*\n * Inspired by Akka Coordinated Shutdown: https://doc.akka.io/libraries/akka-core/current/coordinated-shutdown.html\n * and Lewis's implementation in a private repo elsewhere (https://github.com/Yomanz)\n */\n\nimport { EventEmitter } from 'node:events';\n\nimport chalk from 'chalk';\n\nimport { SeedcordError, SeedcordErrorCode } from '../Errors';\nimport { Logger } from '../Logger';\n\nimport type { LifecycleTask } from './LifecycleTypes';\n\n/**\n * Abstract base class for coordinated lifecycle management (startup/shutdown)\n */\nexport abstract class CoordinatedLifecycle<TPhase extends number> {\n protected readonly logger: Logger;\n protected readonly events = new EventEmitter();\n protected readonly tasksMap = new Map<TPhase, LifecycleTask[]>();\n\n protected constructor(\n loggerName: string,\n protected readonly phaseOrder: TPhase[],\n protected readonly phaseEnum: Record<number, string>\n ) {\n this.logger = new Logger(loggerName);\n // Initialize phases\n this.phaseOrder.forEach((phase) => this.tasksMap.set(phase, []));\n }\n\n /**\n * Adds a lifecycle task to a specific phase.\n *\n * Tasks are executed in phase order during lifecycle operations.\n * Each task has a timeout to prevent hanging operations.\n *\n * @param phase - The lifecycle phase to add the task to\n * @param taskName - Unique name for the task (used for logging and removal)\n * @param task - Async function to execute during the phase\n * @param timeoutMs - Maximum time allowed for task execution in milliseconds\n * @example\n * ```typescript\n * lifecycle.addTask(StartupPhase.Services, 'start-database', async () => {\n * await database.connect();\n * }, 10000);\n * ```\n */\n public addTask(phase: TPhase, taskName: string, task: () => Promise<void>, timeoutMs: number): void {\n if (!this.canAddTask()) return;\n\n const tasks = this.tasksMap.get(phase);\n if (!tasks) {\n throw new SeedcordError(SeedcordErrorCode.LifecycleUnknownPhase, [phase]);\n }\n\n tasks.push({ name: taskName, task, timeout: timeoutMs });\n this.logger.debug(\n `${chalk.italic('Added')} ${this.getTaskType()} task ${chalk.bold.cyan(taskName)} to phase ${chalk.bold.magenta(this.phaseEnum[phase])}`\n );\n }\n\n /**\n * Removes a lifecycle task from a specific phase.\n *\n * @param phase - The lifecycle phase to remove the task from\n * @param taskName - Name of the task to remove\n * @returns True if the task was found and removed, false otherwise\n */\n public removeTask(phase: TPhase, taskName: string): boolean {\n if (!this.canRemoveTask()) return false;\n\n const tasks = this.tasksMap.get(phase);\n if (!tasks) return false;\n\n const initialLength = tasks.length;\n const filteredTasks = tasks.filter((task) => task.name !== taskName);\n this.tasksMap.set(phase, filteredTasks);\n\n const removed = initialLength !== filteredTasks.length;\n if (removed) {\n this.logger.debug(\n `${chalk.italic('Removed')} ${this.getTaskType()} task ${chalk.bold.cyan(taskName)} from phase ${chalk.bold.magenta(this.phaseEnum[phase])}`\n );\n }\n\n return removed;\n }\n\n /**\n * Run all tasks in a specific phase\n */\n protected async runPhase(phase: TPhase): Promise<void> {\n const tasks = this.tasksMap.get(phase) ?? [];\n if (tasks.length === 0) {\n this.logger.warn(`No tasks to run in phase ${chalk.bold.magenta(this.phaseEnum[phase])}`);\n return;\n }\n\n this.logger.info(\n `${chalk.bold.yellow('Running')} ${this.getTaskType()} phase ${chalk.bold.magenta(this.phaseEnum[phase])} with ${chalk.bold.cyan(tasks.length)} tasks`\n );\n this.emit(`phase:${phase}:start`);\n\n // Execute all tasks with the execution strategy\n const results: PromiseSettledResult<void>[] = await this.executeTasksInPhase(phase, tasks);\n\n // Check results\n const failures = results.filter((r) => r.status === 'rejected').length;\n if (failures > 0) {\n throw new SeedcordError(SeedcordErrorCode.LifecyclePhaseFailures, [\n chalk.bold.magenta(this.phaseEnum[phase]),\n failures\n ]);\n } else {\n this.logger.info(\n `Phase ${chalk.bold.magenta(this.phaseEnum[phase])} ${chalk.bold.green('completed successfully')}`\n );\n }\n\n this.emit(`phase:${phase}:complete`);\n }\n\n /**\n * Run a single task with timeout\n */\n protected async runTaskWithTimeout(phase: TPhase, task: LifecycleTask): Promise<void> {\n this.logger.info(\n `${chalk.italic('Starting')} task ${chalk.bold.cyan(task.name)} in phase ${chalk.bold.magenta(this.phaseEnum[phase])}`\n );\n\n try {\n // Create a race between the task and a timeout\n await Promise.race([\n task.task(),\n new Promise<void>((_, reject) => {\n setTimeout(() => {\n reject(new SeedcordError(SeedcordErrorCode.LifecycleTaskTimeout, [task.name, task.timeout]));\n }, task.timeout);\n })\n ]);\n\n this.logger.info(\n `${chalk.italic('Completed')} task ${chalk.bold.cyan(task.name)} in phase ${chalk.bold.magenta(this.phaseEnum[phase])}`\n );\n } catch (error) {\n this.logger.error(\n `${chalk.italic('Failed')} task ${chalk.bold.cyan(task.name)} in phase ${chalk.bold.magenta(this.phaseEnum[phase])}:`,\n error\n );\n throw error;\n }\n }\n\n /**\n * Subscribe to lifecycle events\n */\n public on(event: string, listener: (...args: unknown[]) => void): void {\n this.events.on(event, listener);\n }\n\n /**\n * Unsubscribe from lifecycle events\n */\n public off(event: string, listener: (...args: unknown[]) => void): void {\n this.events.off(event, listener);\n }\n\n protected emit(event: string, ...args: unknown[]): boolean {\n return this.events.emit(event, ...args);\n }\n\n // Abstract methods to be implemented by subclasses\n protected abstract canAddTask(): boolean;\n protected abstract canRemoveTask(): boolean;\n protected abstract getTaskType(): string;\n protected abstract executeTasksInPhase(\n phase: TPhase,\n tasks: LifecycleTask[]\n ): Promise<PromiseSettledResult<void>[]>;\n}\n","import chalk from 'chalk';\nimport { Envapt } from 'envapt';\n\nimport { CoordinatedLifecycle } from './CoordinatedLifecycle';\n\nimport type { LifecycleTask, PhaseEvents } from './LifecycleTypes';\nimport type { UnionToTuple } from 'type-fest';\n\n/**\n * Shutdown phases for coordinated application shutdown.\n */\nexport enum ShutdownPhase {\n /** Stop accepting new requests/interactions */\n StopAcceptingRequests = 1,\n /** Stop background services (health checks, etc.) */\n StopServices,\n /** Disconnect from external resources (database, APIs) */\n ExternalResources,\n /** Disconnect from Discord */\n DiscordCleanup,\n /** Final cleanup tasks */\n FinalCleanup\n}\n\n/** Define the order of phases */\nconst PHASE_ORDER: ShutdownPhase[] = [\n ShutdownPhase.StopAcceptingRequests,\n ShutdownPhase.StopServices,\n ShutdownPhase.ExternalResources,\n ShutdownPhase.DiscordCleanup,\n ShutdownPhase.FinalCleanup\n];\n\n/**\n * Event keys for coordinated shutdown phases\n */\nexport type CoordinatedShutdownEventKey = PhaseEvents<'shutdown', UnionToTuple<ShutdownPhase>>;\n\nconst LOG_FLUSH_DELAY_MS = 500;\n\n/**\n * CoordinatedShutdown manages graceful application shutdown by executing registered tasks across defined phases.\n *\n * It listens for termination signals (SIGINT, SIGTERM) and runs tasks in parallel within each phase.\n * Tasks can be added or removed dynamically, and each task has an associated timeout.\n *\n * Enable or disable the shutdown mechanism via the SHUTDOWN_IS_ENABLED environment variable. It's disabled by default. I recommend enabling it in production environments.\n */\nexport class CoordinatedShutdown extends CoordinatedLifecycle<ShutdownPhase> {\n @Envapt('SHUTDOWN_IS_ENABLED', { fallback: true })\n declare private readonly isShutdownEnabled: boolean;\n\n private isShuttingDown = false;\n private exitCode = 0;\n\n public constructor() {\n super('CoordinatedShutdown', PHASE_ORDER, ShutdownPhase);\n\n // Register signal effects\n this.registerSignalHandlers();\n }\n\n protected canAddTask(): boolean {\n return this.isShutdownEnabled;\n }\n\n protected canRemoveTask(): boolean {\n return true;\n }\n\n protected getTaskType(): string {\n return 'shutdown';\n }\n\n protected async executeTasksInPhase(\n phase: ShutdownPhase,\n tasks: LifecycleTask[]\n ): Promise<PromiseSettledResult<void>[]> {\n // Execute all tasks in parallel (unlike startup which uses sequential)\n const results: PromiseSettledResult<void>[] = [];\n for (const task of tasks) {\n results.push(\n await Promise.resolve()\n .then(() => this.runTaskWithTimeout(phase, task))\n .then(\n () => ({ status: 'fulfilled', value: undefined }) satisfies PromiseSettledResult<void>,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n (reason) => ({ status: 'rejected', reason }) satisfies PromiseSettledResult<void>\n )\n );\n }\n return results;\n }\n\n private registerSignalHandlers(): void {\n if (!this.isShutdownEnabled) return;\n\n process.on('SIGTERM', () => {\n this.logger.info(`Received ${chalk.yellow.bold('SIGTERM')} signal`);\n void this.run(0);\n });\n\n process.on('SIGINT', () => {\n this.logger.info(`Received ${chalk.yellow.bold('SIGINT')} signal`);\n void this.run(0);\n });\n }\n\n /**\n * Adds a task to a specific shutdown phase with timeout.\n *\n * @param phase - The shutdown phase from {@link ShutdownPhase}\n * @param taskName - Unique identifier for the task\n * @param task - Async function to execute\n * @param timeoutMs - Task timeout in milliseconds (default: 5000)\n */\n public override addTask(phase: ShutdownPhase, taskName: string, task: () => Promise<void>, timeoutMs = 5000): void {\n super.addTask(phase, taskName, task, timeoutMs);\n }\n\n /**\n * Removes a task from a specific shutdown phase.\n *\n * @param phase - The shutdown phase to remove from\n * @param taskName - Name of the task to remove\n * @returns True if task was found and removed\n */\n public override removeTask(phase: ShutdownPhase, taskName: string): boolean {\n return super.removeTask(phase, taskName);\n }\n\n /**\n * Executes the coordinated shutdown sequence.\n *\n * Runs all registered tasks across shutdown phases in reverse order.\n * Tasks within each phase are executed in parallel for faster shutdown.\n * Process exits with the specified code when complete.\n *\n * @param exitCode - Process exit code (default: `0`)\n * @returns Promise that resolves when shutdown is complete\n * @example\n * ```typescript\n * shutdown.addTask(ShutdownPhase.Services, 'database', () => db.disconnect(), 5000);\n * await shutdown.run(0); // Graceful shutdown\n * ```\n */\n public async run(exitCode = 0): Promise<void> {\n if (this.isShuttingDown) {\n this.logger.warn('Shutdown sequence already in progress');\n return;\n }\n\n this.isShuttingDown = true;\n this.exitCode = exitCode;\n this.logger.info(\n `${chalk.bold.yellow('Starting')} coordinated shutdown with exit code ${chalk.bold.cyan(exitCode)}`\n );\n this.emit('shutdown:start');\n\n try {\n // Execute each phase in order\n for (const phase of PHASE_ORDER) {\n await this.runPhase(phase);\n }\n\n this.logger.info(`${chalk.bold.green('Coordinated shutdown completed')} successfully`);\n this.emit('shutdown:complete');\n } catch (error) {\n this.logger.error(`${chalk.bold.red('Coordinated shutdown failed')}`);\n this.emit('shutdown:error', error);\n } finally {\n this.logger.info(`${chalk.bold.red('Exiting')} process with code ${chalk.bold.cyan(this.exitCode)}`);\n setTimeout(() => {\n process.exit(this.exitCode);\n }, LOG_FLUSH_DELAY_MS);\n }\n }\n\n /**\n * Subscribe to shutdown events\n */\n public override on(event: CoordinatedShutdownEventKey, listener: (...args: unknown[]) => void): void {\n super.on(event, listener);\n }\n\n /**\n * Unsubscribe from shutdown events\n */\n public override off(event: CoordinatedShutdownEventKey, listener: (...args: unknown[]) => void): void {\n super.off(event, listener);\n }\n}\n","import { createServer } from 'http';\n\nimport chalk from 'chalk';\nimport { Envapt } from 'envapt';\n\nimport { CoordinatedShutdown, ShutdownPhase } from './Lifecycle/CoordinatedShutdown';\nimport { Logger } from './Logger';\n\nimport type { IncomingMessage, Server, ServerResponse } from 'http';\n\nconst HTTP_OK = 200;\nconst HTTP_NOT_FOUND = 404;\n\n/**\n * HTTP health check service for monitoring bot status.\n *\n * Provides a simple HTTP endpoint that responds with JSON status\n * information, useful for container orchestration and monitoring.\n */\nexport class HealthCheck {\n public readonly logger = new Logger('HealthCheck');\n\n /**\n * Set `PORT` in your `.env` to change the default port (6956).\n */\n @Envapt('HEALTH_CHECK_PORT', { fallback: 6956 })\n declare public readonly port: number;\n\n /**\n * Set `HEALTH_CHECK_PATH` in your `.env` to change the default path (`/healthcheck`).\n */\n @Envapt('HEALTH_CHECK_PATH', { fallback: '/healthcheck' })\n declare public readonly path: string;\n\n /**\n * Set `HEALTH_CHECK_HOST` in your `.env` to change the host. Defaults to `null` (all interfaces).\n */\n @Envapt('HEALTH_CHECK_HOST')\n declare public readonly host: string | null;\n\n private server?: Server;\n\n constructor(shutdown: CoordinatedShutdown) {\n // Register shutdown task\n shutdown.addTask(ShutdownPhase.StopServices, 'stop-healthcheck-server', async () => await this.stop());\n }\n\n /**\n * Starts the health check server.\n * @returns Promise that resolves when the server is listening\n */\n public async init(): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n this.server = createServer((req: IncomingMessage, res: ServerResponse) => {\n if (req.method === 'GET' && req.url === this.path) {\n res.writeHead(HTTP_OK, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ status: 'ok', timestamp: Date.now() }));\n } else {\n res.writeHead(HTTP_NOT_FOUND, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ status: 'not found' }));\n }\n });\n\n this.server.on('error', reject);\n this.server.once('listening', () => {\n const address = this.host ?? 'localhost';\n this.logger.info(\n `${chalk.green.bold('✓')} Health check server listening on ${chalk.cyan(`http://${address}:${this.port}${this.path}`)}`\n );\n resolve();\n });\n\n if (this.host) {\n this.logger.debug(`Binding health check server to ${this.host}`);\n this.server.listen(this.port, this.host);\n } else {\n this.logger.debug('Binding health check server to all interfaces');\n this.server.listen(this.port);\n }\n });\n }\n\n /**\n * Stops the health check server.\n *\n * @returns Promise that resolves when the server is closed\n */\n public stop(): Promise<void> {\n if (this.server !== undefined) {\n const server = this.server;\n return new Promise((resolve) => {\n server.once('close', () => resolve());\n\n server.close(() => {\n this.logger.info(chalk.bold.red('Health check server stopped'));\n });\n });\n }\n\n return Promise.resolve();\n }\n}\n","import { EventEmitter } from 'node:events';\n\n/** Tuple type used for all event payloads. */\nexport type SEArgsTuple = readonly unknown[];\n\n/** Convenience map for emitters that intentionally expose no events. */\nexport type SENoEvents = Record<never, SEArgsTuple>;\n\n/**\n * Accepts any object type and constrains every value to be a tuple.\n *\n * @typeParam TEvents - Map of event names to readonly tuple payloads\n */\nexport type SEEventMapLike<TEvents extends object> = { [K in keyof TEvents]: SEArgsTuple };\n\n/**\n * Narrows a provided event map to the keys that can be emitted or listened for.\n *\n * @typeParam TEvents - Map of event names to readonly tuple payloads\n * @internal\n */\nexport type SEEventKey<TEvents extends object> = Extract<keyof TEvents, string | symbol>;\n\n/**\n * Typed wrapper around Node.js {@link EventEmitter} enforcing tuple payloads per event name.\n *\n * @typeParam TEvents - Map of event names to readonly tuple payloads\n */\nexport class StrictEventEmitter<TEvents extends SEEventMapLike<TEvents>> extends EventEmitter {\n /**\n * Registers a persistent listener with tuple-safe arguments for the given event.\n *\n * @param event - The event name to attach to\n * @param listener - Callback operating on the typed argument tuple for the event\n * @returns This emitter instance for chaining\n */\n override on<TEventKey extends SEEventKey<TEvents>>(\n event: TEventKey,\n listener: (...args: TEvents[TEventKey]) => void\n ): this {\n return super.on(event, listener as unknown as (...args: unknown[]) => void);\n }\n\n /**\n * Registers a one time listener that is removed after the first invocation.\n *\n * @param event - The event name to attach to\n * @param listener - Callback operating on the typed argument tuple for the event\n * @returns This emitter instance for chaining\n */\n override once<TEventKey extends SEEventKey<TEvents>>(\n event: TEventKey,\n listener: (...args: TEvents[TEventKey]) => void\n ): this {\n return super.once(event, listener as unknown as (...args: unknown[]) => void);\n }\n\n /**\n * Removes a previously registered listener for the given event.\n *\n * @param event - The event name whose listener should be removed\n * @param listener - Callback originally registered for the event\n * @returns This emitter instance for chaining\n */\n override off<TEventKey extends SEEventKey<TEvents>>(\n event: TEventKey,\n listener: (...args: TEvents[TEventKey]) => void\n ): this {\n return super.off(event, listener as unknown as (...args: unknown[]) => void);\n }\n\n /**\n * Alias of {@link StrictEventEmitter.on} for compatibility with Node.js EventEmitter APIs.\n *\n * @param event - The event name to attach to\n * @param listener - Callback operating on the typed argument tuple for the event\n * @returns This emitter instance for chaining\n */\n override addListener<TEventKey extends SEEventKey<TEvents>>(\n event: TEventKey,\n listener: (...args: TEvents[TEventKey]) => void\n ): this {\n return this.on(event, listener);\n }\n\n /**\n * Alias of {@link StrictEventEmitter.off} for compatibility with Node.js EventEmitter APIs.\n *\n * @param event - The event name whose listener should be removed\n * @param listener - Callback originally registered for the event\n * @returns This emitter instance for chaining\n */\n override removeListener<TEventKey extends SEEventKey<TEvents>>(\n event: TEventKey,\n listener: (...args: TEvents[TEventKey]) => void\n ): this {\n return super.removeListener(event, listener as unknown as (...args: unknown[]) => void);\n }\n\n /**\n * Emits an event with the strictly typed argument tuple for the event name.\n *\n * @param event - The event name to emit\n * @param args - Tuple payload for the event\n * @returns True when the event had listeners, false otherwise\n */\n override emit<TEventKey extends SEEventKey<TEvents>>(event: TEventKey, ...args: TEvents[TEventKey]): boolean {\n return super.emit(event, ...(args as unknown as unknown[]));\n }\n\n /**\n * Retrieves the listener list for a given event with the correct tuple signature.\n *\n * @param event - The event name to inspect\n * @returns Array of listeners registered for the event\n */\n override listeners<TEventKey extends SEEventKey<TEvents>>(\n event: TEventKey\n ): ((...args: TEvents[TEventKey]) => void)[] {\n return super.listeners(event) as ((...args: TEvents[TEventKey]) => void)[];\n }\n\n /**\n * Counts listeners for an event without widening the return type of {@link EventEmitter.listenerCount}.\n *\n * @param event - The event name to inspect\n * @returns The total number of listeners registered for the event\n */\n listenerCountTyped<TEventKey extends SEEventKey<TEvents>>(event: TEventKey): number {\n return super.listenerCount(event);\n }\n\n /**\n * Returns the list of event names known to the emitter with the mapped key type.\n *\n * @returns Array of event keys supported by the emitter\n */\n eventNamesTyped(): SEEventKey<TEvents>[] {\n return super.eventNames() as SEEventKey<TEvents>[];\n }\n\n /**\n * Waits for an event to be emitted, resolving with the listener arguments tuple once triggered.\n * Supports optional abort signals and timeouts for cancellation semantics.\n *\n * @param event - The event name to wait for\n * @param opts - Optional abort signal or timeout in milliseconds\n * @returns Promise resolving with the emitted argument tuple; rejects when aborted or timed out\n */\n waitFor<TEventKey extends SEEventKey<TEvents>>(\n event: TEventKey,\n opts?: { signal?: AbortSignal; timeoutMs?: number }\n ): Promise<TEvents[TEventKey]> {\n return new Promise<TEvents[TEventKey]>((resolve, reject) => {\n const onEvent = (...args: TEvents[TEventKey]): void => {\n cleanup();\n resolve(args);\n };\n\n const onAbort = (): void => {\n cleanup();\n reject(Object.assign(new Error('Aborted'), { name: 'AbortError' }));\n };\n\n let timeoutId: NodeJS.Timeout | null = null;\n\n const cleanup = (): void => {\n this.off(event, onEvent);\n opts?.signal?.removeEventListener('abort', onAbort);\n if (timeoutId) clearTimeout(timeoutId);\n };\n\n this.once(event, onEvent);\n\n if (opts?.signal) {\n if (opts.signal.aborted) return onAbort();\n opts.signal.addEventListener('abort', onAbort, { once: true });\n }\n\n if (opts?.timeoutMs !== undefined) {\n timeoutId = setTimeout(() => {\n cleanup();\n reject(new Error('Timed out'));\n }, opts.timeoutMs);\n }\n });\n }\n}\n","import chalk from 'chalk';\n\nimport { SeedcordError, SeedcordErrorCode } from '../Errors';\nimport { CoordinatedLifecycle } from './CoordinatedLifecycle';\n\nimport type { LifecycleTask, PhaseEvents } from './LifecycleTypes';\nimport type { UnionToTuple } from 'type-fest';\n\n/**\n * Startup phases for coordinated initialization\n *\n * Defines the order in which different components are initialized during bot startup.\n */\nexport enum StartupPhase {\n /** Validate environment variables and config files */\n Validation = 1,\n /** Discover plugin constructors via decorators or registry */\n Discovery,\n /** Register plugin metadata and declared dependencies */\n Registration,\n /** Inject and validate plugin-specific configuration */\n Configuration,\n /** Instantiate plugin classes with Core and arguments */\n Instantiation,\n /** Activate plugins by calling their init/setup effects */\n Activation,\n /** Mark seedcord as ready and start handling interactions */\n Ready\n}\n\n/** Define the order of phases */\nconst PHASE_ORDER: StartupPhase[] = [\n StartupPhase.Validation,\n StartupPhase.Discovery,\n StartupPhase.Registration,\n StartupPhase.Configuration,\n StartupPhase.Instantiation,\n StartupPhase.Activation,\n StartupPhase.Ready\n];\n\n/**\n * Event keys for coordinated startup phases\n */\nexport type CoordinatedStartupEventKey = PhaseEvents<'startup', UnionToTuple<StartupPhase>>;\n\n/**\n * Manages bot startup lifecycle with ordered phases\n *\n * Coordinates initialization of all bot components in a predictable sequence.\n * Tasks are executed within their designated phases to ensure proper dependency order.\n */\nexport class CoordinatedStartup extends CoordinatedLifecycle<StartupPhase> {\n private isStartingUp = false;\n private hasStarted = false;\n\n public constructor() {\n super('CoordinatedStartup', PHASE_ORDER, StartupPhase);\n }\n\n /**\n * Adds a task to a specific startup phase with timeout.\n *\n * @param phase - The startup phase from {@link StartupPhase}\n * @param taskName - Unique identifier for the task\n * @param task - Async function to execute\n * @param timeoutMs - Task timeout in milliseconds (default: 10000)\n */\n public override addTask(phase: StartupPhase, taskName: string, task: () => Promise<void>, timeoutMs = 10000): void {\n super.addTask(phase, taskName, task, timeoutMs);\n }\n\n protected canAddTask(): boolean {\n if (this.hasStarted) {\n throw new SeedcordError(SeedcordErrorCode.LifecycleAddAfterCompletion);\n }\n\n if (this.isStartingUp) {\n throw new SeedcordError(SeedcordErrorCode.LifecycleAddDuringRun);\n }\n\n return true;\n }\n\n protected canRemoveTask(): boolean {\n if (this.isStartingUp) {\n throw new SeedcordError(SeedcordErrorCode.LifecycleRemoveDuringRun);\n }\n\n return true;\n }\n\n protected getTaskType(): string {\n return 'startup';\n }\n\n protected async executeTasksInPhase(\n phase: StartupPhase,\n tasks: LifecycleTask[]\n ): Promise<PromiseSettledResult<void>[]> {\n // Execute all tasks in sequence\n const results: PromiseSettledResult<void>[] = [];\n for (const task of tasks) {\n results.push(\n await Promise.resolve()\n .then(() => this.runTaskWithTimeout(phase, task))\n .then(\n () => ({ status: 'fulfilled', value: undefined }) satisfies PromiseSettledResult<void>,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n (reason) => ({ status: 'rejected', reason }) satisfies PromiseSettledResult<void>\n )\n );\n }\n return results;\n }\n\n /**\n * Executes the coordinated startup sequence.\n *\n * Runs all registered tasks across startup phases in the correct order.\n * Each phase completes before the next phase begins. Tasks within a phase\n * are executed sequentially to maintain predictable initialization.\n *\n * @returns Promise that resolves when startup is complete\n * @throws An {@link Error} If startup fails or is called multiple times\n * @example\n * ```typescript\n * const startup = new CoordinatedStartup();\n * startup.addTask(StartupPhase.Services, 'database', () => db.connect(), 10000);\n * await startup.run();\n * ```\n */\n public async run(): Promise<void> {\n if (this.hasStarted) {\n this.logger.warn('Startup sequence has already completed');\n return;\n }\n\n if (this.isStartingUp) {\n this.logger.warn('Startup sequence already in progress');\n return;\n }\n\n this.isStartingUp = true;\n this.logger.info(`${chalk.bold.green('Starting')} coordinated startup sequence`);\n this.emit('startup:start');\n\n try {\n // Execute each phase in order\n for (const phase of PHASE_ORDER) await this.runPhase(phase);\n\n this.hasStarted = true;\n this.logger.info(`${chalk.bold.green('Coordinated startup completed')} successfully`);\n this.emit('startup:complete');\n } catch (error) {\n this.logger.error(`${chalk.bold.red('Coordinated startup failed')}`);\n this.emit('startup:error', error);\n throw error;\n } finally {\n this.isStartingUp = false;\n }\n }\n\n /**\n * Subscribe to startup events\n */\n public override on(event: CoordinatedStartupEventKey, listener: (...args: unknown[]) => void): void {\n super.on(event, listener);\n }\n\n /**\n * Unsubscribe from startup events\n */\n public override off(event: CoordinatedStartupEventKey, listener: (...args: unknown[]) => void): void {\n super.off(event, listener);\n }\n\n /**\n * Check if startup has completed\n */\n public get isReady(): boolean {\n return this.hasStarted;\n }\n\n /**\n * Check if startup is currently running\n */\n public get isRunning(): boolean {\n return this.isStartingUp;\n }\n}\n"]}
1
+ {"version":3,"file":"index.mjs","names":["PHASE_ORDER"],"sources":["../src/Logger/LogFormatter.ts","../src/Logger/Transports/SinkTransport.ts","../src/Logger/TransportFactory.ts","../src/Logger/LoggerChannelRegistry.ts","../src/Logger/LoggerUtilities.ts","../src/Logger/Logger.ts","../src/CooldownManager.ts","../src/StrictEventEmitter.ts","../src/Lifecycle/CoordinatedLifecycle.ts","../src/Lifecycle/CoordinatedShutdown.ts","../src/HealthCheck.ts","../src/Lifecycle/CoordinatedStartup.ts","../src/index.ts"],"sourcesContent":["import stripAnsi from 'strip-ansi';\nimport { format } from 'winston';\n\nimport type { Logform } from 'winston';\n\n/** An Error temporarily annotated with its ANSI-formatted name while pretty-printing stacks. */\ntype FormattedError = Error & { __formattedName?: string; __plainName?: string };\n\n/**\n * Options for pretty log formatting.\n */\nexport interface PrettyFormatOptions {\n /** Number of spaces to pad the log level to. {@default `7`} */\n padding?: number;\n /** Whether to strip ANSI codes from extra log data. {@default false} */\n stripExtras?: boolean;\n}\n\n/**\n * Options for JSON log formatting.\n * @internal\n */\nexport interface JsonFormatOptions {\n /** Whether to strip ANSI codes from log messages and extra data. {@default false} */\n stripAnsi?: boolean;\n /** Whether to produce minimal JSON output without extra fields. {@default false} */\n minimal?: boolean;\n}\n\n/**\n * Formats log records for console and file outputs.\n *\n * Supports pretty-printed colored logs for development\n * and JSON logs for production with optional ANSI stripping.\n * @internal\n */\nexport class LogFormatter {\n private readonly DEFAULT_PADDING = 7;\n private readonly SPLAT: symbol = Symbol.for('splat');\n\n private safeString(value: unknown): string {\n if (typeof value === 'string') return value;\n if (value === undefined || value === null) return '';\n if (typeof (value as { toString?: () => string }).toString === 'function') {\n return String((value as { toString: () => string }).toString());\n }\n if (typeof value === 'object') {\n try {\n return JSON.stringify(value);\n } catch {\n return '';\n }\n }\n return '';\n }\n\n private sanitizeAnsi(value: unknown): unknown {\n if (typeof value === 'string') return stripAnsi(value);\n if (value instanceof Error) {\n const error = value;\n const sanitized = new Error(stripAnsi(error.message));\n sanitized.name = error.name;\n if (typeof error.stack === 'string') sanitized.stack = stripAnsi(error.stack);\n return sanitized;\n }\n return value;\n }\n\n private getExtras(info: Logform.TransformableInfo): unknown[] {\n const raw = info[this.SPLAT];\n return Array.isArray(raw) ? raw : [];\n }\n\n private readonly FORMAT_SPECIFIERS = /%[sdifjoO]/gu;\n private readonly HAD_FORMAT_KEY = Symbol.for('hadFormatSpecifiers');\n private readonly SAVED_SPLAT_KEY = Symbol.for('savedSplat');\n\n private markFormatSpecifiers(): Logform.Format {\n return format((info) => {\n const msg = typeof info.message === 'string' ? info.message : '';\n const extras = this.getExtras(info);\n const matches = msg.match(this.FORMAT_SPECIFIERS);\n const formatCount = matches ? matches.length : 0;\n info[this.HAD_FORMAT_KEY] = formatCount;\n info[this.SAVED_SPLAT_KEY] = [...extras];\n return info;\n })();\n }\n\n public createPreFormat(): Logform.Format {\n return this.markFormatSpecifiers();\n }\n\n private preserveErrorFormatting(): Logform.Format {\n return format((info) => {\n const extras = this.getExtras(info);\n\n for (const item of extras) {\n if (item instanceof Error && /\\u001b/.test(item.name)) {\n const originalName = item.name;\n const plainName = stripAnsi(item.name);\n\n const formatted = item as FormattedError;\n formatted.__formattedName = originalName;\n formatted.__plainName = plainName;\n }\n }\n\n return info;\n })();\n }\n\n private restoreErrorFormatting(): Logform.Format {\n return format((info) => {\n if (typeof info.stack === 'string') {\n const extras = this.getExtras(info);\n\n for (const item of extras) {\n if (item instanceof Error) {\n const { __formattedName: formattedName, __plainName: plainName } = item as FormattedError;\n\n if (typeof formattedName === 'string' && typeof plainName === 'string') {\n info.stack = (info.stack as string).replace(\n new RegExp(`^${this.escapeRegex(plainName)}`, 'm'),\n formattedName\n );\n }\n }\n }\n }\n\n return info;\n })();\n }\n\n private escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n }\n\n /**\n * Creates pretty-printed format with colors and timestamps.\n *\n * Ideal for development environments where human readability matters.\n *\n * @param options - Formatting options including padding and ANSI stripping\n * @returns Array of Winston format transformers\n */\n public pretty(options: PrettyFormatOptions = {}): Logform.Format[] {\n const padding = options.padding ?? this.DEFAULT_PADDING;\n return [\n this.preserveErrorFormatting(),\n format.errors({ stack: true }),\n this.restoreErrorFormatting(),\n format.splat(),\n format.colorize({ level: true }),\n format.timestamp({ format: 'D MMM, hh:mm:ss a' }),\n // eslint-disable-next-line max-statements\n format.printf((info: Logform.TransformableInfo) => {\n let ts = this.safeString(info.timestamp);\n let lvl = this.safeString(info.level).padEnd(padding);\n let lbl = this.safeString(info.label);\n let msg = this.safeString(info.message);\n\n if (options.stripExtras) {\n ts = stripAnsi(ts);\n lvl = stripAnsi(lvl);\n lbl = stripAnsi(lbl);\n msg = stripAnsi(msg);\n }\n\n const base = `${ts} [${lvl}]: ${lbl} - ${msg}`;\n const savedExtras = info[this.SAVED_SPLAT_KEY];\n // Array.isArray narrows to any[]; keep the elements as unknown so the filter below stays safe.\n const extras: unknown[] = Array.isArray(savedExtras) ? savedExtras : this.getExtras(info);\n\n let rendered = base;\n\n if (typeof info.stack === 'string') {\n let stack = this.safeString(info.stack);\n if (options.stripExtras) stack = stripAnsi(stack);\n rendered += `\\n${stack}`;\n }\n\n const cleaned = options.stripExtras ? extras.map((entry) => this.sanitizeAnsi(entry)) : extras;\n const rawFormatCount = info[this.HAD_FORMAT_KEY];\n const formatSpecifierCount = typeof rawFormatCount === 'number' ? rawFormatCount : 0;\n const filtered = cleaned.filter((x, index) => {\n if (x === null || x === undefined) return false;\n if (x instanceof Error && typeof info.stack === 'string') return false;\n if (typeof x !== 'object') {\n return index >= formatSpecifierCount;\n }\n return Object.keys(x).length > 0;\n });\n\n if (filtered.length) {\n const primitives: string[] = [];\n const objects: string[] = [];\n\n for (const x of filtered) {\n if (typeof x === 'string' || typeof x === 'number' || typeof x === 'boolean') {\n primitives.push(String(x));\n } else {\n try {\n objects.push(JSON.stringify(x, null, 2));\n } catch {\n objects.push(String(x));\n }\n }\n }\n\n if (primitives.length) {\n rendered += ` ${primitives.join(' ')}`;\n }\n if (objects.length) {\n rendered += `\\n${objects.join('\\n')}`;\n }\n }\n\n return rendered;\n })\n ];\n }\n\n /**\n * Creates JSON format for structured logging.\n *\n * Best for production environments where logs are parsed by tools.\n *\n * @param options - JSON formatting options including ANSI stripping and minimal mode\n * @returns Array of Winston format transformers\n */\n public json(options: JsonFormatOptions = {}): Logform.Format[] {\n const base = [format.timestamp(), format.errors({ stack: true })];\n\n if (options.stripAnsi) {\n base.push(\n format((info) => {\n info.message = typeof info.message === 'string' ? stripAnsi(info.message) : info.message;\n if (typeof info.stack === 'string') info.stack = stripAnsi(info.stack);\n const extras = this.getExtras(info);\n if (extras.length) info.extras = extras.map((entry) => this.sanitizeAnsi(entry));\n return info;\n })()\n );\n }\n\n base.push(options.minimal ? format.json({}) : format.json({ bigint: true, space: 0 }));\n\n return base;\n }\n}\n","import TransportStream from 'winston-transport';\n\nimport type { Logform } from 'winston';\nimport type { TransportStreamOptions } from 'winston-transport';\n\n/**\n * Options for creating a SinkTransport.\n * @internal\n */\nexport interface SinkTransportOptions extends TransportStreamOptions {\n readonly channel: string;\n readonly sink: ILoggerSink;\n}\n\n/**\n * A log entry passed to custom sinks.\n */\nexport interface LoggerSinkLogEntry {\n /** Channel the log originated from */\n readonly channel: string;\n /** Pre-formatted log message ready for display */\n readonly rendered: string;\n /** Raw Winston log info object */\n readonly info: Logform.TransformableInfo;\n}\n\n/**\n * Custom sink interface for capturing logger output.\n *\n * Implement this to route logs to custom destinations.\n */\nexport interface ILoggerSink {\n /**\n * Called when a log entry is emitted.\n *\n * @param entry - The log entry with channel, rendered message, and raw info\n */\n onLog(entry: LoggerSinkLogEntry): void;\n}\n\n/**\n * Handle for managing a sink's lifecycle.\n */\nexport interface ILoggerSinkHandle {\n /**\n * Removes the sink and restores console output if muted.\n */\n dispose(): void;\n}\n\n/**\n * Winston transport that forwards logs to custom sinks.\n * @internal\n */\nexport class SinkTransport extends TransportStream {\n private readonly channelName: string;\n private readonly sink: ILoggerSink;\n\n public constructor(options: SinkTransportOptions) {\n super(options);\n this.channelName = options.channel;\n this.sink = options.sink;\n }\n\n public override log(info: Logform.TransformableInfo, callback: () => void): void {\n setImmediate(() => this.emit('logged', info));\n\n const rendered = this.resolveRendered(info);\n const channel = this.resolveChannel(info);\n\n this.sink.onLog({ channel, rendered, info });\n\n callback();\n }\n\n private resolveChannel(info: Logform.TransformableInfo): string {\n const channel = info.channel;\n return typeof channel === 'string' ? channel : this.channelName;\n }\n\n private resolveRendered(info: Logform.TransformableInfo): string {\n const msg = info[Symbol.for('message')];\n\n if (typeof msg === 'string') return msg;\n\n const fallback = info.message;\n if (typeof fallback === 'string') return fallback;\n\n if (fallback instanceof Error) return fallback.stack ?? fallback.message;\n\n // eslint-disable-next-line @typescript-eslint/no-base-to-string -- last-resort stringify for a non-string, non-Error message value\n return String(fallback ?? '');\n }\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\n\nimport { Envapter } from 'envapt';\nimport { format, transports } from 'winston';\n\nimport { LogFormatter } from './LogFormatter';\nimport { SinkTransport } from './Transports/SinkTransport';\n\nimport type { ILoggerSink } from './Transports/SinkTransport';\nimport type { LoggerFormatMode, LoggerLevel, TransportConfig, WinstonTransport } from './Types';\n\n/**\n * Input parameters for building a Winston transport.\n * @internal\n */\nexport interface TransportBuildInput {\n channel: string;\n label: string;\n level: LoggerLevel;\n config: TransportConfig;\n defaultFormat: LoggerFormatMode;\n stripAnsi: boolean;\n}\n\n/**\n * Input parameters for building a sink transport.\n * @internal\n */\ninterface BuildInput {\n readonly channel: string;\n readonly label: string;\n readonly level: LoggerLevel;\n}\n\n/**\n * Creates Winston transports with proper formatting and file path resolution.\n *\n * Builds console and file transports with environment-aware defaults,\n * filename template expansion, and format selection.\n * @internal\n */\nexport class TransportFactory {\n private readonly formatter: LogFormatter;\n private readonly MILLISECOND_PAD = 3;\n private cachedSessionTimestamp: { date: string; timestamp: string } | null = null;\n\n constructor() {\n this.formatter = new LogFormatter();\n }\n\n private ensureDir(filepath: string): void {\n const dir = path.dirname(filepath);\n if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });\n }\n\n private withDefaultLabel(label: string): ReturnType<typeof format.combine> {\n return format.combine(\n format((info) => {\n info.label ??= label;\n return info;\n })()\n );\n }\n\n public buildPreFormat(): ReturnType<typeof format.combine> {\n return format.combine(this.formatter.createPreFormat());\n }\n\n private buildConsoleFormat(label: string): ReturnType<typeof format.combine> {\n // Use JSON format in production, pretty format in development\n if (Envapter.isProduction) {\n return format.combine(this.withDefaultLabel(label), ...this.formatter.json({ stripAnsi: true }));\n }\n return format.combine(this.withDefaultLabel(label), ...this.formatter.pretty());\n }\n\n private buildFileFormat(\n label: string,\n mode: LoggerFormatMode,\n stripAnsi: boolean\n ): ReturnType<typeof format.combine> {\n const formats =\n mode === 'pretty' ? this.formatter.pretty({ stripExtras: stripAnsi }) : this.formatter.json({ stripAnsi });\n return format.combine(this.withDefaultLabel(label), ...formats);\n }\n\n private buildStreamFormat(\n label: string,\n mode: LoggerFormatMode,\n stripAnsi: boolean\n ): ReturnType<typeof format.combine> {\n // Stream transport uses similar formatting to file transport\n const formats =\n mode === 'pretty' ? this.formatter.pretty({ stripExtras: stripAnsi }) : this.formatter.json({ stripAnsi });\n return format.combine(this.withDefaultLabel(label), ...formats);\n }\n\n private pad(value: number): string {\n return value.toString().padStart(2, '0');\n }\n\n private buildTimestamp(): { date: string; timestamp: string } {\n if (this.cachedSessionTimestamp) {\n return this.cachedSessionTimestamp;\n }\n\n const now = new Date();\n const yyyy = now.getFullYear();\n const mm = this.pad(now.getMonth() + 1);\n const dd = this.pad(now.getDate());\n const hh = this.pad(now.getHours());\n const min = this.pad(now.getMinutes());\n const ss = this.pad(now.getSeconds());\n const ms = now.getMilliseconds().toString().padStart(this.MILLISECOND_PAD, '0');\n\n const date = `${yyyy}-${mm}-${dd}`;\n const timestamp = `${date}-${hh}${min}${ss}-${ms}`;\n\n this.cachedSessionTimestamp = { date, timestamp };\n return this.cachedSessionTimestamp;\n }\n\n private resolveFilename(template: string, channel: string): string {\n const { date, timestamp } = this.buildTimestamp();\n return template\n .replaceAll('{channel}', channel)\n .replaceAll('{date}', date)\n .replaceAll('{timestamp}', timestamp);\n }\n\n /**\n * Builds a Winston transport from configuration.\n *\n * Creates console, file, or stream transport with proper formatting,\n * level filtering, and file rotation settings.\n *\n * @param input - Transport configuration parameters\n * @returns Configured Winston transport instance\n */\n public build(input: TransportBuildInput): WinstonTransport {\n const effectiveFormat = input.config.format ?? input.defaultFormat;\n const shouldStripAnsi = input.config.stripAnsi ?? input.stripAnsi;\n const level = input.config.level ?? input.level;\n\n if (input.config.type === 'console') {\n return new transports.Console({\n level,\n format: this.buildConsoleFormat(input.label)\n });\n }\n\n if (input.config.type === 'stream') {\n return new transports.Stream({\n level,\n stream: input.config.stream,\n format: this.buildStreamFormat(input.label, effectiveFormat, shouldStripAnsi)\n });\n }\n\n const filenameTemplate = input.config.filename ?? 'logs/application-{timestamp}.log';\n const resolvedFilename = this.resolveFilename(filenameTemplate, input.channel);\n this.ensureDir(resolvedFilename);\n\n return new transports.File({\n level,\n filename: resolvedFilename,\n ...(input.config.maxSize !== undefined ? { maxsize: input.config.maxSize } : {}),\n ...(input.config.maxFiles !== undefined ? { maxFiles: input.config.maxFiles } : {}),\n tailable: true,\n format: this.buildFileFormat(input.label, effectiveFormat, shouldStripAnsi)\n });\n }\n\n /**\n * Builds a sink transport for routing logs to custom destinations.\n *\n * @param input - Transport configuration with channel and level info\n * @param sink - Custom sink to receive log entries\n * @returns Configured sink transport instance\n */\n public buildSinkTransport(input: BuildInput, sink: ILoggerSink): WinstonTransport {\n const format = this.buildConsoleFormat(input.label);\n\n return new SinkTransport({\n level: input.level,\n channel: input.channel,\n sink,\n format\n });\n }\n}\n","import path from 'node:path';\n\nimport { Envapter } from 'envapt';\nimport winston, { createLogger } from 'winston';\n\nimport { TransportFactory } from './TransportFactory';\n\nimport type { ILoggerSink, ILoggerSinkHandle } from './Transports/SinkTransport';\nimport type {\n ChannelConfig,\n LoggerConfiguration,\n LoggerLevel,\n TransportConfig,\n WinstonInstance,\n WinstonTransport\n} from './Types';\n\n/**\n * Manages Winston logger instances per channel with caching.\n *\n * Stores channel configuration and creates transports for each channel\n * with environment-aware defaults.\n */\nexport class LoggerChannelRegistry {\n private static _instance: LoggerChannelRegistry | null = null;\n\n private nextSinkId = 1;\n private readonly sinks = new Map<\n number,\n {\n readonly sink: ILoggerSink;\n readonly muteConsole: boolean;\n readonly transportsByChannel: Map<string, WinstonTransport>;\n readonly removedConsoleByChannel: Map<string, WinstonTransport[]>;\n }\n >();\n\n private readonly DEFAULT_LEVEL: LoggerLevel = Envapter.isDevelopment\n ? 'silly'\n : Envapter.isStaging\n ? 'debug'\n : 'info';\n\n private config: LoggerConfiguration = {\n defaultChannel: 'default',\n channels: {},\n files: {\n maxSizeMB: 10,\n maxFiles: 5,\n patterns: {\n dev: 'logs/{channel}-{timestamp}.log',\n staging: 'logs/staging-{date}-{timestamp}.jsonl',\n prod: 'logs/production-{date}.jsonl'\n }\n }\n };\n\n private readonly FORMAT = Envapter.isDevelopment ? 'pretty' : 'json';\n\n private readonly cache = new Map<string, WinstonInstance>();\n private readonly transportFactory: TransportFactory;\n\n private constructor() {\n this.transportFactory = new TransportFactory();\n }\n\n /**\n * Gets the singleton instance of the registry.\n */\n public static get instance(): LoggerChannelRegistry {\n return (this._instance ??= new LoggerChannelRegistry());\n }\n\n private getDefaultChannelConfig(name: string): ChannelConfig {\n return {\n name,\n level: this.DEFAULT_LEVEL,\n transports: [\n { type: 'console', level: this.DEFAULT_LEVEL, format: this.FORMAT, stripAnsi: !Envapter.isDevelopment },\n {\n type: 'file',\n level: this.DEFAULT_LEVEL,\n filename: Envapter.isDevelopment\n ? this.config.files.patterns.dev\n : Envapter.isStaging\n ? this.config.files.patterns.staging\n : this.config.files.patterns.prod,\n format: this.FORMAT,\n stripAnsi: true,\n maxSize: this.config.files.maxSizeMB * 1024 * 1024,\n maxFiles: this.config.files.maxFiles\n }\n ]\n };\n }\n\n private mergeChannelConfig(base: ChannelConfig, override?: ChannelConfig): ChannelConfig {\n if (!override) return base;\n\n const level = override.level ?? base.level;\n const stripAnsi = override.stripAnsi ?? base.stripAnsi;\n const format = override.format ?? base.format;\n const transports = override.transports ?? base.transports;\n const name = override.name || base.name;\n\n return {\n name,\n ...(level !== undefined ? { level } : {}),\n ...(stripAnsi !== undefined ? { stripAnsi } : {}),\n ...(format !== undefined ? { format } : {}),\n ...(transports !== undefined ? { transports } : {})\n };\n }\n\n /**\n * Updates global logger configuration and clears cache.\n *\n * @param config - Partial configuration to merge with existing settings\n */\n public configure(config: Partial<LoggerConfiguration>): void {\n this.disposeCachedLoggers();\n this.config = { ...this.config, ...config, channels: { ...this.config.channels, ...(config.channels ?? {}) } };\n this.cache.clear();\n }\n\n // configure() rebuilds every logger; detach + close the old transports and reset sink\n // bookkeeping first, or the discarded loggers leak transports (and their file handles /\n // sink wrappers) across reconfigures, e.g. on every dev HMR cycle.\n private disposeCachedLoggers(): void {\n for (const logger of this.cache.values()) {\n for (const transport of [...logger.transports]) {\n logger.remove(transport);\n transport.close?.();\n }\n }\n for (const record of this.sinks.values()) {\n record.transportsByChannel.clear();\n record.removedConsoleByChannel.clear();\n }\n }\n\n /**\n * Returns the name of the default channel.\n */\n public getDefaultChannel(): string {\n return this.config.defaultChannel;\n }\n\n /**\n * Returns a list of all known channels (configured or cached).\n */\n public getChannels(): string[] {\n const configuredChannels = Object.keys(this.config.channels);\n const cachedChannels = Array.from(this.cache.keys());\n const allChannels = new Set([...configuredChannels, ...cachedChannels, this.config.defaultChannel]);\n return Array.from(allChannels).sort();\n }\n\n /**\n * Gets the log file path for a specific channel, if one exists.\n *\n * @param channel - Channel name to get log file path for\n * @returns The log file path, or null if no file transport exists\n */\n public getLogFilePath(channel: string): string | null {\n const logger = this.cache.get(channel);\n if (!logger) return null;\n\n for (const transport of logger.transports) {\n if (transport instanceof winston.transports.File) {\n return path.resolve(transport.dirname, transport.filename);\n }\n }\n\n return null;\n }\n\n /**\n * Gets or creates a Winston logger instance for the given channel.\n *\n * @param channel - Channel name to get logger for\n * @returns Configured Winston logger instance\n */\n public get(channel: string): WinstonInstance {\n const cached = this.cache.get(channel);\n if (cached) return cached;\n\n const channelConfig = this.mergeChannelConfig(\n this.getDefaultChannelConfig(channel),\n this.config.channels[channel]\n );\n\n const effectiveLevel = channelConfig.level ?? this.DEFAULT_LEVEL;\n\n const consoleMuted = this.isConsoleMuted();\n\n const transports = (channelConfig.transports ?? [])\n .filter((transportConfig: TransportConfig) => !(consoleMuted && transportConfig.type === 'console'))\n .map((transportConfig: TransportConfig) =>\n this.transportFactory.build({\n channel,\n label: channel,\n level: effectiveLevel,\n config: transportConfig,\n defaultFormat: channelConfig.format ?? 'pretty',\n stripAnsi: channelConfig.stripAnsi ?? true\n })\n );\n\n const logger = createLogger({\n level: effectiveLevel,\n format: this.transportFactory.buildPreFormat(),\n transports\n });\n\n for (const entry of this.sinks.values()) {\n this.applySinkToCachedLogger(channel, logger, entry);\n }\n\n this.cache.set(channel, logger);\n return logger;\n }\n\n private isConsoleMuted(): boolean {\n for (const entry of this.sinks.values()) {\n if (entry.muteConsole) return true;\n }\n return false;\n }\n\n /**\n * Installs a custom sink to capture log output across all channels.\n *\n * Useful for routing logs to custom destinations like TUIs or remote services.\n *\n * @param sink - Custom sink implementation to receive log entries\n * @param options - Optional configuration for console muting behavior\n * @returns Handle to dispose the sink when no longer needed\n */\n public installSink(sink: ILoggerSink, options?: { muteConsole?: boolean }): ILoggerSinkHandle {\n const id = this.nextSinkId;\n this.nextSinkId += 1;\n\n const record = {\n sink,\n muteConsole: options?.muteConsole ?? true,\n transportsByChannel: new Map<string, WinstonTransport>(),\n removedConsoleByChannel: new Map<string, WinstonTransport[]>()\n };\n\n this.sinks.set(id, record);\n\n for (const [channel, logger] of this.cache.entries()) {\n this.applySinkToCachedLogger(channel, logger, record);\n }\n\n return new (class implements ILoggerSinkHandle {\n public constructor(\n private readonly registry: LoggerChannelRegistry,\n private readonly key: number\n ) {}\n public dispose(): void {\n this.registry.uninstallSink(this.key);\n }\n })(this, id);\n }\n\n private uninstallSink(id: number): void {\n const record = this.sinks.get(id);\n if (!record) return;\n\n for (const [channel, logger] of this.cache.entries()) {\n const sinkTransport = record.transportsByChannel.get(channel);\n if (sinkTransport) logger.remove(sinkTransport);\n\n const removed = record.removedConsoleByChannel.get(channel);\n if (removed?.length) {\n for (const t of removed) logger.add(t);\n }\n }\n\n this.sinks.delete(id);\n }\n\n private applySinkToCachedLogger(\n channel: string,\n logger: WinstonInstance,\n record: {\n readonly sink: ILoggerSink;\n readonly muteConsole: boolean;\n readonly transportsByChannel: Map<string, WinstonTransport>;\n readonly removedConsoleByChannel: Map<string, WinstonTransport[]>;\n }\n ): void {\n if (record.muteConsole) {\n const removed: WinstonTransport[] = [];\n for (const t of logger.transports) {\n if (t instanceof winston.transports.Console) {\n removed.push(t);\n }\n }\n if (removed.length) {\n for (const t of removed) logger.remove(t);\n record.removedConsoleByChannel.set(channel, removed);\n }\n }\n\n const sinkTransport = this.transportFactory.buildSinkTransport(\n { channel, label: channel, level: logger.level as unknown as LoggerLevel },\n record.sink\n );\n\n logger.add(sinkTransport);\n record.transportsByChannel.set(channel, sinkTransport);\n }\n}\n","import { formatFilePath } from '@seedcord/utils';\nimport chalk from 'chalk';\n\nimport type { LoggerLevel } from './Types';\nimport type { ILogger } from '@seedcord/types';\n\n/**\n * Provides access to common logging utilities.\n */\nexport class LoggerUtilities {\n constructor(private readonly logger: ILogger) {}\n\n private arrow(text: string): string {\n return `${chalk.gray('→')} ${text}`;\n }\n\n /**\n * Logs a single item with an arrow prefix.\n * @param text - The text to log\n */\n public item(text: string, level: LoggerLevel = 'info'): void {\n this.logger[level](this.arrow(text));\n }\n\n /**\n * Logs a list of items with optional heading.\n *\n * @param items - Array of items to log as a list\n * @param heading - Optional heading to display above the list\n */\n public list(items: string[], heading?: string, level: LoggerLevel = 'info'): void {\n if (heading) this.logger[level](heading);\n for (const item of items) {\n this.logger[level](this.arrow(item));\n }\n }\n\n /**\n * Logs a summary with title and key-value pairs.\n * Example: \"Loaded: 5 handlers, 3 commands\"\n *\n * @param title - The title of the summary\n * @param items - Object with counts/values to display\n */\n public summary(title: string, items: Record<string, number | string>, level: LoggerLevel = 'info'): void {\n const entries = Object.entries(items).map(([key, value]) => `${chalk.magenta.bold(String(value))} ${key}`);\n this.logger[level](`${chalk.bold.green(title)}: ${entries.join(', ')}`);\n }\n\n /**\n * Logs a component registration message.\n *\n * @param name - Name of the component being registered\n * @param from - File path the component is from\n * @param type - Optional type label (e.g., 'middleware', 'handler')\n */\n public registration(name: string, from: string, type?: string, level: LoggerLevel = 'info'): void {\n const scope = type ? `${type} ` : '';\n this.logger[level](\n `${chalk.italic('Registered')} ${chalk.bold.yellow(scope)}${chalk.cyan.bold(name)} from ${chalk.gray(formatFilePath(from))}`\n );\n }\n\n /**\n * Logs component initialization start/end.\n *\n * @param component - Name of the component\n * @param action - 'start' or 'end' to indicate initialization phase\n */\n public initialization(component: string, action: 'start' | 'end', level: LoggerLevel = 'info'): void {\n const verb = action === 'start' ? 'Initializing' : 'Initialized';\n this.logger[level](chalk.bold(`${verb} ${component}`));\n }\n\n /**\n * Logs progress as \"[current/total]\" with optional item label.\n *\n * @param current - Current progress count\n * @param total - Total count\n * @param item - Optional item label to append\n */\n public progress(current: number, total: number, item?: string, level: LoggerLevel = 'info'): void {\n const base = `[${current}/${total}]`;\n const suffix = item ? ` ${item}` : '';\n this.logger[level](`${chalk.cyan(base)}${suffix}`);\n }\n\n /**\n * Logs content in a decorative box.\n *\n * @param title - Title to display in the box\n * @param content - Lines of content to display in the box\n */\n public box(title: string, content: string[], level: LoggerLevel = 'info'): void {\n const width = Math.max(title.length, ...content.map((line) => line.length)) + 2;\n const horizontal = '─'.repeat(width);\n this.logger[level](`╭${horizontal}╮`);\n this.logger[level](`│ ${title.padEnd(width - 1, ' ')}│`);\n for (const line of content) {\n this.logger[level](`│ ${line.padEnd(width - 1, ' ')}│`);\n }\n this.logger[level](`╰${horizontal}╯`);\n }\n}\n","import { LoggerChannelRegistry } from './LoggerChannelRegistry';\nimport { LoggerUtilities } from './LoggerUtilities';\n\nimport type { LoggerConfiguration, LoggerOptions } from './Types';\nimport type { ILogger } from '@seedcord/types';\nimport type { Logger as Winston } from 'winston';\n\n/**\n * Public logging service with channel-aware transports and per-run file output.\n *\n * - Channel separation (e.g., bot, cli, hmr)\n * - Production-safe JSON logs with ANSI stripping\n * - Unique log files per run via filename templates\n */\nexport class Logger implements ILogger {\n declare private logger: Winston;\n private readonly label: string;\n private channel: string;\n private readonly registry = LoggerChannelRegistry.instance;\n\n public readonly utils: LoggerUtilities;\n\n private static readonly instances = new Map<string, Logger>();\n\n private static instance(prefix: string, channel?: string): Logger {\n const key = channel ? `${channel}::${prefix}` : prefix;\n let instance = this.instances.get(key);\n if (!instance) {\n instance = new Logger(prefix, channel ? { channel } : undefined);\n this.instances.set(key, instance);\n }\n return instance;\n }\n\n /**\n * Configures global logger settings.\n *\n * Applies configuration to all channels and clears instance cache.\n *\n * @param config - Partial configuration to merge with defaults\n */\n public static configure(config: Partial<LoggerConfiguration>): void {\n LoggerChannelRegistry.instance.configure(config);\n this.instances.clear();\n }\n\n /**\n * Creates a new Logger instance.\n *\n * @param label - Prefix/label for all log entries from this logger\n * @param options - Optional configuration for channel, format, and ANSI handling\n */\n constructor(label: string, options?: LoggerOptions) {\n this.label = label;\n this.channel = options?.channel ?? this.registry.getDefaultChannel();\n this.logger = this.registry.get(this.channel).child({ label: this.label, channel: this.channel });\n\n this.utils = new LoggerUtilities(this);\n }\n\n /**\n * Switches this logger to a different channel.\n *\n * @param channel - Channel name to switch to\n */\n public setChannel(channel: string): void {\n this.channel = channel;\n this.logger = this.registry.get(channel).child({ label: this.label, channel });\n }\n\n /**\n * Returns a new Logger instance configured for the specified channel. Loggers are cached per (label, channel) pair.\n *\n * @param channel - Channel name to use\n */\n public inChannel(channel: string): Logger {\n return Logger.instance(this.label, channel);\n }\n\n /**\n * Logs an error message with optional additional data.\n *\n * @param msg - The error message to log\n * @param args - Additional data to include in the log entry\n */\n public error(msg: string, ...args: unknown[]): void {\n this.logger.error(msg, ...args);\n }\n\n /**\n * Logs a warning message with optional additional data.\n *\n * @param msg - The warning message to log\n * @param args - Additional data to include in the log entry\n */\n public warn(msg: string, ...args: unknown[]): void {\n this.logger.warn(msg, ...args);\n }\n\n /**\n * Logs an informational message with optional additional data.\n *\n * @param msg - The informational message to log\n * @param args - Additional data to include in the log entry\n */\n public info(msg: string, ...args: unknown[]): void {\n this.logger.info(msg, ...args);\n }\n\n /**\n * Logs an HTTP-related message with optional additional data.\n *\n * @param msg - The HTTP message to log\n * @param args - Additional data to include in the log entry\n */\n public http(msg: string, ...args: unknown[]): void {\n this.logger.http(msg, ...args);\n }\n\n /**\n * Logs a verbose message with optional additional data.\n *\n * @param msg - The verbose message to log\n * @param args - Additional data to include in the log entry\n */\n public verbose(msg: string, ...args: unknown[]): void {\n this.logger.verbose(msg, ...args);\n }\n\n /**\n * Logs a debug message with optional additional data.\n *\n * @param msg - The debug message to log\n * @param args - Additional data to include in the log entry\n */\n public debug(msg: string, ...args: unknown[]): void {\n this.logger.debug(msg, ...args);\n }\n\n /**\n * Logs a silly/trace level message with optional additional data.\n *\n * @param msg - The silly message to log\n * @param args - Additional data to include in the log entry\n */\n public silly(msg: string, ...args: unknown[]): void {\n this.logger.silly(msg, ...args);\n }\n}\n","import { Envapter } from 'envapt';\n\nimport { Logger } from './Logger';\n\nconst logger = new Logger('CooldownManager');\n\n/**\n * Configuration options for CooldownManager.\n */\nexport interface CooldownOptions {\n /** Cooldown window in milliseconds (default 1000) */\n cooldown?: number;\n /** Custom error class to throw when a key is still cooling down; receives the remaining ms. */\n err?: new (msg: string, remaining: number) => Error;\n /** Message passed to the error constructor (default \"Cooldown active\") */\n message?: string;\n}\n\n/**\n * Lightweight utility for per-key cooldowns.\n *\n * Manages time-based restrictions on operations by key,\n * useful for rate limiting, command cooldowns, and spam prevention.\n */\nexport class CooldownManager {\n private readonly window: number;\n private readonly Err: new (msg: string, remaining: number) => Error;\n private readonly msg: string;\n private readonly map = new Map<string, number>();\n\n /**\n * Creates a new CooldownManager instance.\n *\n * @param opts - Configuration options for the cooldown behavior\n */\n constructor(opts: CooldownOptions = {}) {\n this.window = opts.cooldown ?? 1_000;\n this.Err = opts.err ?? Error;\n this.msg = opts.message ?? 'Cooldown active';\n }\n\n /**\n * Records usage timestamp for a key without any cooldown checks.\n *\n * @param key - The unique identifier for the cooldown entry\n */\n set(key: string): void {\n this.map.set(key, Date.now());\n }\n\n /**\n * Verifies cooldown status for a key and updates timestamp if not active.\n *\n * If the cooldown is still active, throws the configured error.\n * If not active, updates the timestamp and returns successfully.\n *\n * @param key - The unique identifier to check cooldown for\n * @throws An {@link Err} When the cooldown is still active for the given key\n */\n check(key: string): void {\n const now = Date.now();\n const last = this.map.get(key);\n const remaining = this.window - (now - (last ?? 0));\n\n if (Envapter.isDevelopment && remaining > 0) {\n logger.debug(`${key} - ${remaining}ms remaining`);\n }\n\n if (last !== undefined && remaining > 0) {\n throw new this.Err(this.msg, remaining);\n }\n this.map.set(key, now);\n }\n\n /**\n * Checks if a key is currently cooling down without updating timestamp.\n *\n * @param key - The unique identifier to check\n * @returns True if the key is still cooling down, false otherwise\n */\n isActive(key: string): boolean {\n const last = this.map.get(key);\n return last !== undefined && Date.now() - last < this.window;\n }\n\n /**\n * Removes a key from the cooldown map.\n *\n * @param key - The unique identifier to remove (useful for manual resets)\n */\n clear(key: string): void {\n this.map.delete(key);\n }\n}\n","import { EventEmitter } from 'node:events';\n\nimport { SeedcordErrorCode } from './Errors';\nimport { SeedcordError } from './Errors/SeedcordError';\n\n/** Tuple type used for all event payloads. */\nexport type SEArgsTuple = readonly unknown[];\n\n/** Convenience map for emitters that intentionally expose no events. */\nexport type SENoEvents = Record<never, SEArgsTuple>;\n\n/**\n * Accepts any object type and constrains every value to be a tuple.\n *\n * @typeParam TEvents - Map of event names to readonly tuple payloads\n */\nexport type SEEventMapLike<TEvents extends object> = { [K in keyof TEvents]: SEArgsTuple };\n\n/**\n * Narrows a provided event map to the keys that can be emitted or listened for.\n *\n * @typeParam TEvents - Map of event names to readonly tuple payloads\n * @internal\n */\ntype SEEventKey<TEvents extends object> = Extract<keyof TEvents, string | symbol>;\n\n/**\n * Typed wrapper around Node.js {@link EventEmitter} enforcing tuple payloads per event name.\n *\n * @typeParam TEvents - Map of event names to readonly tuple payloads\n */\nexport class StrictEventEmitter<TEvents extends SEEventMapLike<TEvents>> extends EventEmitter {\n /**\n * Registers a persistent listener with tuple-safe arguments for the given event.\n *\n * @param event - The event name to attach to\n * @param listener - Callback operating on the typed argument tuple for the event\n * @returns This emitter instance for chaining\n */\n override on<TEventKey extends SEEventKey<TEvents>>(\n event: TEventKey,\n listener: (...args: TEvents[TEventKey]) => void\n ): this {\n return super.on(event, listener);\n }\n\n /**\n * Registers a one time listener that is removed after the first invocation.\n *\n * @param event - The event name to attach to\n * @param listener - Callback operating on the typed argument tuple for the event\n * @returns This emitter instance for chaining\n */\n override once<TEventKey extends SEEventKey<TEvents>>(\n event: TEventKey,\n listener: (...args: TEvents[TEventKey]) => void\n ): this {\n return super.once(event, listener);\n }\n\n /**\n * Removes a previously registered listener for the given event.\n *\n * @param event - The event name whose listener should be removed\n * @param listener - Callback originally registered for the event\n * @returns This emitter instance for chaining\n */\n override off<TEventKey extends SEEventKey<TEvents>>(\n event: TEventKey,\n listener: (...args: TEvents[TEventKey]) => void\n ): this {\n return super.off(event, listener);\n }\n\n /**\n * Alias of {@link StrictEventEmitter.on} for compatibility with Node.js EventEmitter APIs.\n *\n * @param event - The event name to attach to\n * @param listener - Callback operating on the typed argument tuple for the event\n * @returns This emitter instance for chaining\n */\n override addListener<TEventKey extends SEEventKey<TEvents>>(\n event: TEventKey,\n listener: (...args: TEvents[TEventKey]) => void\n ): this {\n return this.on(event, listener);\n }\n\n /**\n * Alias of {@link StrictEventEmitter.off} for compatibility with Node.js EventEmitter APIs.\n *\n * @param event - The event name whose listener should be removed\n * @param listener - Callback originally registered for the event\n * @returns This emitter instance for chaining\n */\n override removeListener<TEventKey extends SEEventKey<TEvents>>(\n event: TEventKey,\n listener: (...args: TEvents[TEventKey]) => void\n ): this {\n return super.removeListener(event, listener);\n }\n\n /**\n * Emits an event with the strictly typed argument tuple for the event name.\n *\n * @param event - The event name to emit\n * @param args - Tuple payload for the event\n * @returns True when the event had listeners, false otherwise\n */\n override emit<TEventKey extends SEEventKey<TEvents>>(event: TEventKey, ...args: TEvents[TEventKey]): boolean {\n // justified: widen the per-event tuple to its base array type so it spreads into Node's\n // `emit(event, ...args: any[])`. There's no declaration fix for Node's base signature.\n return super.emit(event, ...(args as readonly unknown[]));\n }\n\n /**\n * Retrieves the listener list for a given event with the correct tuple signature.\n *\n * @param event - The event name to inspect\n * @returns Array of listeners registered for the event\n */\n override listeners<TEventKey extends SEEventKey<TEvents>>(\n event: TEventKey\n ): ((...args: TEvents[TEventKey]) => void)[] {\n return super.listeners(event) as ((...args: TEvents[TEventKey]) => void)[];\n }\n\n /**\n * Counts listeners for an event without widening the return type of {@link EventEmitter.listenerCount}.\n *\n * @param event - The event name to inspect\n * @returns The total number of listeners registered for the event\n */\n listenerCountTyped<TEventKey extends SEEventKey<TEvents>>(event: TEventKey): number {\n return super.listenerCount(event);\n }\n\n /**\n * Returns the list of event names known to the emitter with the mapped key type.\n *\n * @returns Array of event keys supported by the emitter\n */\n eventNamesTyped(): SEEventKey<TEvents>[] {\n return super.eventNames() as SEEventKey<TEvents>[];\n }\n\n /**\n * Waits for an event to be emitted, resolving with the listener arguments tuple once triggered.\n * Supports optional abort signals and timeouts for cancellation semantics.\n *\n * @param event - The event name to wait for\n * @param opts - Optional abort signal or timeout in milliseconds\n * @returns Promise resolving with the emitted argument tuple; rejects when aborted or timed out\n */\n waitFor<TEventKey extends SEEventKey<TEvents>>(\n event: TEventKey,\n opts?: { signal?: AbortSignal; timeoutMs?: number }\n ): Promise<TEvents[TEventKey]> {\n return new Promise<TEvents[TEventKey]>((resolve, reject) => {\n const onEvent = (...args: TEvents[TEventKey]): void => {\n cleanup();\n resolve(args);\n };\n\n const onAbort = (): void => {\n cleanup();\n reject(new SeedcordError(SeedcordErrorCode.EventEmitterWaitForAborted));\n };\n\n let timeoutId: NodeJS.Timeout | null = null;\n\n const cleanup = (): void => {\n this.off(event, onEvent);\n opts?.signal?.removeEventListener('abort', onAbort);\n if (timeoutId) clearTimeout(timeoutId);\n };\n\n this.once(event, onEvent);\n\n if (opts?.signal) {\n if (opts.signal.aborted) return onAbort();\n opts.signal.addEventListener('abort', onAbort, { once: true });\n }\n\n if (opts?.timeoutMs !== undefined) {\n const timeoutMs = opts.timeoutMs;\n timeoutId = setTimeout(() => {\n cleanup();\n reject(new SeedcordError(SeedcordErrorCode.EventEmitterWaitForTimeout, [timeoutMs]));\n }, timeoutMs);\n }\n });\n }\n}\n","/*\n * Inspired by Akka Coordinated Shutdown: https://doc.akka.io/libraries/akka-core/current/coordinated-shutdown.html\n * and Lewis's implementation in a private repo elsewhere (https://github.com/Yomanz)\n */\n\nimport { EventEmitter } from 'node:events';\n\nimport chalk from 'chalk';\n\nimport { SeedcordErrorCode } from '../Errors';\nimport { SeedcordError } from '../Errors/SeedcordError';\nimport { Logger } from '../Logger';\nimport { StrictEventEmitter } from '../StrictEventEmitter';\n\nimport type { LifecycleTask } from './LifecycleTypes';\nimport type { SEEventMapLike } from '../StrictEventEmitter';\n\n/**\n * Abstract base class for coordinated lifecycle management (startup/shutdown)\n */\nexport abstract class CoordinatedLifecycle<\n TPhase extends number,\n TEvents extends SEEventMapLike<TEvents>\n> extends StrictEventEmitter<TEvents> {\n protected readonly logger: Logger;\n protected readonly tasksMap = new Map<TPhase, LifecycleTask[]>();\n\n protected constructor(\n loggerName: string,\n protected readonly phaseOrder: TPhase[],\n protected readonly phaseEnum: Record<number, string>\n ) {\n super();\n this.logger = new Logger(loggerName);\n this.phaseOrder.forEach((phase) => this.tasksMap.set(phase, []));\n }\n\n /**\n * Adds a lifecycle task to a specific phase.\n *\n * Tasks are executed in phase order during lifecycle operations.\n * Each task has a timeout to prevent hanging operations.\n *\n * @param phase - The lifecycle phase to add the task to\n * @param taskName - Unique name for the task (used for logging and removal)\n * @param task - Async function to execute during the phase\n * @param timeoutMs - Maximum time allowed for task execution in milliseconds\n * @example\n * ```typescript\n * lifecycle.addTask(StartupPhase.Services, 'start-database', async () => {\n * await database.connect();\n * }, 10000);\n * ```\n */\n public addTask(phase: TPhase, taskName: string, task: () => Promise<void>, timeoutMs: number): void {\n if (!this.canAddTask()) return;\n\n const tasks = this.tasksMap.get(phase);\n if (!tasks) {\n throw new SeedcordError(SeedcordErrorCode.LifecycleUnknownPhase, [phase]);\n }\n\n tasks.push({ name: taskName, task, timeout: timeoutMs });\n this.logger.debug(\n `${chalk.italic('Added')} ${this.getTaskType()} task ${chalk.bold.cyan(taskName)} to phase ${chalk.bold.magenta(this.phaseEnum[phase])}`\n );\n }\n\n /**\n * Removes a lifecycle task from a specific phase.\n *\n * @param phase - The lifecycle phase to remove the task from\n * @param taskName - Name of the task to remove\n * @returns True if the task was found and removed, false otherwise\n */\n public removeTask(phase: TPhase, taskName: string): boolean {\n if (!this.canRemoveTask()) return false;\n\n const tasks = this.tasksMap.get(phase);\n if (!tasks) return false;\n\n const initialLength = tasks.length;\n const filteredTasks = tasks.filter((task) => task.name !== taskName);\n this.tasksMap.set(phase, filteredTasks);\n\n const removed = initialLength !== filteredTasks.length;\n if (removed) {\n this.logger.debug(\n `${chalk.italic('Removed')} ${this.getTaskType()} task ${chalk.bold.cyan(taskName)} from phase ${chalk.bold.magenta(this.phaseEnum[phase])}`\n );\n }\n\n return removed;\n }\n\n /**\n * Run all tasks in a specific phase\n */\n protected async runPhase(phase: TPhase): Promise<void> {\n const tasks = this.tasksMap.get(phase) ?? [];\n if (tasks.length === 0) {\n this.logger.warn(`No tasks to run in phase ${chalk.bold.magenta(this.phaseEnum[phase])}`);\n return;\n }\n\n this.logger.info(\n `${chalk.bold.yellow('Running')} ${this.getTaskType()} phase ${chalk.bold.magenta(this.phaseEnum[phase])} with ${chalk.bold.cyan(tasks.length)} tasks`\n );\n this.emitPhase(phase, 'start');\n\n const results: PromiseSettledResult<void>[] = await this.executeTasksInPhase(phase, tasks);\n\n const failures = results.filter((r) => r.status === 'rejected').length;\n if (failures > 0) {\n // Pass the raw phase name; chalk's ANSI codes would otherwise leak into the serialized\n // error message (e.g. the unknown-exception webhook payload).\n throw new SeedcordError(SeedcordErrorCode.LifecyclePhaseFailures, [this.phaseEnum[phase], failures]);\n } else {\n this.logger.info(\n `Phase ${chalk.bold.magenta(this.phaseEnum[phase])} ${chalk.bold.green('completed successfully')}`\n );\n }\n\n this.emitPhase(phase, 'complete');\n }\n\n /**\n * Run a single task with timeout\n */\n protected async runTaskWithTimeout(phase: TPhase, task: LifecycleTask): Promise<void> {\n this.logger.info(\n `${chalk.italic('Starting')} task ${chalk.bold.cyan(task.name)} in phase ${chalk.bold.magenta(this.phaseEnum[phase])}`\n );\n\n let timeoutId: NodeJS.Timeout | undefined;\n\n try {\n await Promise.race([\n task.task(),\n new Promise<void>((_, reject) => {\n timeoutId = setTimeout(() => {\n reject(new SeedcordError(SeedcordErrorCode.LifecycleTaskTimeout, [task.name, task.timeout]));\n }, task.timeout);\n })\n ]);\n\n this.logger.info(\n `${chalk.italic('Completed')} task ${chalk.bold.cyan(task.name)} in phase ${chalk.bold.magenta(this.phaseEnum[phase])}`\n );\n } catch (error) {\n this.logger.error(\n `${chalk.italic('Failed')} task ${chalk.bold.cyan(task.name)} in phase ${chalk.bold.magenta(this.phaseEnum[phase])}:`,\n error\n );\n throw error;\n } finally {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n }\n }\n\n // The phase event key is interpolated from phaseOrder at runtime; the subclass event map derives\n // its phase keys from the same range, so the key is always valid, but TS can't correlate a\n // template-literal key with the generic TEvents. Emit the no-payload event via the base emitter.\n private emitPhase(phase: TPhase, action: 'start' | 'complete'): void {\n EventEmitter.prototype.emit.call(this, `phase:${phase}:${action}`);\n }\n\n // Abstract methods to be implemented by subclasses\n protected abstract canAddTask(): boolean;\n protected abstract canRemoveTask(): boolean;\n protected abstract getTaskType(): string;\n protected abstract executeTasksInPhase(\n phase: TPhase,\n tasks: LifecycleTask[]\n ): Promise<PromiseSettledResult<void>[]>;\n}\n","import chalk from 'chalk';\n\nimport { CoordinatedLifecycle } from './CoordinatedLifecycle';\n\nimport type { LifecycleTask, PhaseEventMap } from './LifecycleTypes';\nimport type { UnionToTuple } from 'type-fest';\n\n/**\n * Shutdown phases for coordinated application shutdown.\n */\nexport enum ShutdownPhase {\n /** Stop accepting new requests/interactions */\n StopAcceptingRequests = 1,\n /** Stop background services (health checks, etc.) */\n StopServices,\n /** Disconnect from external resources (database, APIs) */\n ExternalResources,\n /** Disconnect from Discord */\n DiscordCleanup,\n /** Final cleanup tasks */\n FinalCleanup\n}\n\n/** Define the order of phases */\nconst PHASE_ORDER: ShutdownPhase[] = [\n ShutdownPhase.StopAcceptingRequests,\n ShutdownPhase.StopServices,\n ShutdownPhase.ExternalResources,\n ShutdownPhase.DiscordCleanup,\n ShutdownPhase.FinalCleanup\n];\n\n/**\n * Strict-event-emitter payload map for coordinated shutdown phases.\n */\nexport type CoordinatedShutdownEvents = PhaseEventMap<'shutdown', UnionToTuple<ShutdownPhase>>;\n\n// Delay process.exit so winston has a window to flush buffered log lines before the event loop dies.\nconst LOG_FLUSH_DELAY_MS = 500;\n\n/**\n * CoordinatedShutdown manages graceful application shutdown by executing registered tasks across defined phases.\n *\n * It listens for termination signals (SIGINT, SIGTERM) and runs tasks in parallel within each phase.\n * Tasks can be added or removed dynamically, and each task has an associated timeout.\n */\nexport class CoordinatedShutdown extends CoordinatedLifecycle<ShutdownPhase, CoordinatedShutdownEvents> {\n private readonly isShutdownEnabled: boolean;\n\n private isShuttingDown = false;\n private exitCode = 0;\n private onSigTerm: (() => void) | null = null;\n private onSigInt: (() => void) | null = null;\n\n public constructor(enabled = true) {\n super('CoordinatedShutdown', PHASE_ORDER, ShutdownPhase);\n\n this.isShutdownEnabled = enabled;\n this.registerSignalHandlers();\n }\n\n protected canAddTask(): boolean {\n return this.isShutdownEnabled;\n }\n\n protected canRemoveTask(): boolean {\n return true;\n }\n\n protected getTaskType(): string {\n return 'shutdown';\n }\n\n protected async executeTasksInPhase(\n phase: ShutdownPhase,\n tasks: LifecycleTask[]\n ): Promise<PromiseSettledResult<void>[]> {\n const promises = tasks.map((task) => this.runTaskWithTimeout(phase, task));\n return Promise.allSettled(promises);\n }\n\n private registerSignalHandlers(): void {\n if (!this.isShutdownEnabled) return;\n\n this.onSigTerm = () => {\n this.logger.info(`Received ${chalk.yellow.bold('SIGTERM')} signal`);\n void this.run(0);\n };\n\n this.onSigInt = () => {\n this.logger.info(`Received ${chalk.yellow.bold('SIGINT')} signal`);\n void this.run(0);\n };\n\n process.on('SIGTERM', this.onSigTerm);\n process.on('SIGINT', this.onSigInt);\n }\n\n private removeSignalHandlers(): void {\n if (this.onSigTerm) {\n process.off('SIGTERM', this.onSigTerm);\n this.onSigTerm = null;\n }\n if (this.onSigInt) {\n process.off('SIGINT', this.onSigInt);\n this.onSigInt = null;\n }\n }\n\n /**\n * Adds a task to a specific shutdown phase with timeout.\n *\n * @param phase - The shutdown phase from {@link ShutdownPhase}\n * @param taskName - Unique identifier for the task\n * @param task - Async function to execute\n * @param timeoutMs - Task timeout in milliseconds {@default 5000}\n */\n public override addTask(phase: ShutdownPhase, taskName: string, task: () => Promise<void>, timeoutMs = 5000): void {\n super.addTask(phase, taskName, task, timeoutMs);\n }\n\n /**\n * Removes a task from a specific shutdown phase.\n *\n * @param phase - The shutdown phase to remove from\n * @param taskName - Name of the task to remove\n * @returns True if task was found and removed\n */\n public override removeTask(phase: ShutdownPhase, taskName: string): boolean {\n return super.removeTask(phase, taskName);\n }\n\n /**\n * Executes the coordinated shutdown sequence.\n *\n * Runs all registered tasks across shutdown phases in reverse order.\n * Tasks within each phase are executed in parallel for faster shutdown.\n * Process exits with the specified code when complete.\n *\n * @param exitCode - Process exit code {@default 0}\n * @param exitProcess - Whether to exit the process after shutdown {@default true}\n * @returns Promise that resolves when shutdown is complete\n * @example\n * ```typescript\n * shutdown.addTask(ShutdownPhase.Services, 'database', () => db.disconnect(), 5000);\n * await shutdown.run(0); // Graceful shutdown\n * ```\n */\n public async run(exitCode = 0, exitProcess = true): Promise<void> {\n this.removeSignalHandlers();\n\n if (this.isShuttingDown) {\n this.logger.warn('Shutdown sequence already in progress');\n return;\n }\n\n this.isShuttingDown = true;\n this.exitCode = exitCode;\n this.logger.info(\n `${chalk.bold.yellow('Starting')} coordinated shutdown with exit code ${chalk.bold.cyan(exitCode)}`\n );\n this.emit('shutdown:start');\n\n try {\n for (const phase of PHASE_ORDER) {\n await this.runPhase(phase);\n }\n\n this.logger.info(`${chalk.bold.green('Coordinated shutdown completed')} successfully`);\n this.emit('shutdown:complete');\n } catch (error) {\n this.logger.error(`${chalk.bold.red('Coordinated shutdown failed')}`);\n this.emit('shutdown:error', error);\n } finally {\n if (exitProcess) {\n this.logger.info(`${chalk.bold.red('Exiting')} process with code ${chalk.bold.cyan(this.exitCode)}`);\n setTimeout(() => {\n process.exit(this.exitCode);\n }, LOG_FLUSH_DELAY_MS);\n } else {\n this.logger.info(`${chalk.bold.yellow('Skipping')} process exit (dev mode)`);\n this.isShuttingDown = false;\n }\n }\n }\n}\n","import { createServer } from 'http';\n\nimport chalk from 'chalk';\n\nimport { ShutdownPhase } from './Lifecycle/CoordinatedShutdown';\nimport { Logger } from './Logger';\n\nimport type { CoordinatedShutdown } from './Lifecycle/CoordinatedShutdown';\nimport type { HealthCheckConfig } from '@seedcord/types';\nimport type { IncomingMessage, Server, ServerResponse } from 'http';\n\nconst HTTP_OK = 200;\nconst HTTP_NOT_FOUND = 404;\n\nconst DEFAULT_HEALTH_CHECK_PORT = 6967;\nconst DEFAULT_HEALTH_CHECK_PATH = '/healthcheck';\n\n/**\n * HTTP health check service for monitoring bot status.\n *\n * Provides a simple HTTP endpoint that responds with JSON status\n * information, useful for container orchestration and monitoring.\n */\nexport class HealthCheck {\n public readonly logger = new Logger('HealthCheck');\n\n public readonly port: number;\n public readonly path: string;\n public readonly host: string | undefined;\n\n private server?: Server;\n\n constructor(shutdown: CoordinatedShutdown, options?: HealthCheckConfig) {\n this.port = options?.port ?? DEFAULT_HEALTH_CHECK_PORT;\n this.path = options?.path ?? DEFAULT_HEALTH_CHECK_PATH;\n this.host = options?.host;\n\n shutdown.addTask(ShutdownPhase.StopServices, 'stop-healthcheck-server', async () => await this.stop());\n }\n\n /**\n * Starts the health check server.\n * @returns Promise that resolves when the server is listening\n */\n public async init(): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n const server = createServer((req: IncomingMessage, res: ServerResponse) => {\n if (req.method === 'GET' && req.url === this.path) {\n res.writeHead(HTTP_OK, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ status: 'ok', timestamp: Date.now() }));\n } else {\n res.writeHead(HTTP_NOT_FOUND, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ status: 'not found' }));\n }\n });\n this.server = server;\n\n const onListenError = (err: Error): void => reject(err);\n server.on('error', onListenError);\n\n server.once('listening', () => {\n // Swap the listen-time reject handler for a logging one: keeping it would reject an\n // already-settled promise on a late error, and removing it without a replacement\n // would crash the process on an unhandled 'error' event.\n server.removeListener('error', onListenError);\n server.on('error', (err) => this.logger.error('Health check server error', err));\n\n const address = this.host ?? 'localhost';\n this.logger.info(\n `${chalk.green.bold('✓')} Health check server listening on ${chalk.cyan(`http://${address}:${this.port}${this.path}`)}`\n );\n resolve();\n });\n\n if (this.host) {\n this.logger.debug(`Binding health check server to ${this.host}`);\n server.listen(this.port, this.host);\n } else {\n this.logger.debug('Binding health check server to all interfaces');\n server.listen(this.port);\n }\n });\n }\n\n /**\n * Stops the health check server.\n *\n * @returns Promise that resolves when the server is closed\n */\n public stop(): Promise<void> {\n const server = this.server;\n // close() on a non-listening server invokes its callback with ERR_SERVER_NOT_RUNNING and\n // never fires 'close', so without this guard the promise would hang the shutdown phase.\n if (!server?.listening) return Promise.resolve();\n\n return new Promise((resolve, reject) => {\n server.once('close', () => resolve());\n server.close((err) => {\n if (err) {\n reject(err);\n return;\n }\n this.logger.info(chalk.bold.red('Health check server stopped'));\n });\n });\n }\n}\n","import chalk from 'chalk';\n\nimport { SeedcordErrorCode } from '../Errors';\nimport { CoordinatedLifecycle } from './CoordinatedLifecycle';\nimport { SeedcordError } from '../Errors/SeedcordError';\n\nimport type { LifecycleTask, PhaseEventMap } from './LifecycleTypes';\nimport type { UnionToTuple } from 'type-fest';\n\n/**\n * Startup phases for coordinated initialization\n *\n * Defines the order in which different components are initialized during bot startup.\n */\nexport enum StartupPhase {\n /** Validate environment variables and config files */\n Validation = 1,\n /** Discover plugin constructors via decorators or registry */\n Discovery,\n /** Register plugin metadata and declared dependencies */\n Registration,\n /** Inject and validate plugin-specific configuration */\n Configuration,\n /** Instantiate plugin classes with Core and arguments */\n Instantiation,\n /** Activate plugins by calling their init/setup methods */\n Activation,\n /** Mark seedcord as ready and start handling interactions */\n Ready\n}\n\n/** Define the order of phases */\nconst PHASE_ORDER: StartupPhase[] = [\n StartupPhase.Validation,\n StartupPhase.Discovery,\n StartupPhase.Registration,\n StartupPhase.Configuration,\n StartupPhase.Instantiation,\n StartupPhase.Activation,\n StartupPhase.Ready\n];\n\n/**\n * Strict-event-emitter payload map for coordinated startup phases.\n */\nexport type CoordinatedStartupEvents = PhaseEventMap<'startup', UnionToTuple<StartupPhase>>;\n\n/**\n * Manages bot startup lifecycle with ordered phases\n *\n * Coordinates initialization of all bot components in a predictable sequence.\n * Tasks are executed within their designated phases to ensure proper dependency order.\n */\nexport class CoordinatedStartup extends CoordinatedLifecycle<StartupPhase, CoordinatedStartupEvents> {\n private isStartingUp = false;\n private hasStarted = false;\n\n public constructor() {\n super('CoordinatedStartup', PHASE_ORDER, StartupPhase);\n }\n\n /**\n * Adds a task to a specific startup phase with timeout.\n *\n * @param phase - The startup phase from {@link StartupPhase}\n * @param taskName - Unique identifier for the task\n * @param task - Async function to execute\n * @param timeoutMs - Task timeout in milliseconds {@default 10000}\n */\n public override addTask(phase: StartupPhase, taskName: string, task: () => Promise<void>, timeoutMs = 10000): void {\n super.addTask(phase, taskName, task, timeoutMs);\n }\n\n protected canAddTask(): boolean {\n if (this.hasStarted) {\n throw new SeedcordError(SeedcordErrorCode.LifecycleAddAfterCompletion);\n }\n\n if (this.isStartingUp) {\n throw new SeedcordError(SeedcordErrorCode.LifecycleAddDuringRun);\n }\n\n return true;\n }\n\n protected canRemoveTask(): boolean {\n if (this.isStartingUp) {\n throw new SeedcordError(SeedcordErrorCode.LifecycleRemoveDuringRun);\n }\n\n return true;\n }\n\n protected getTaskType(): string {\n return 'startup';\n }\n\n protected async executeTasksInPhase(\n phase: StartupPhase,\n tasks: LifecycleTask[]\n ): Promise<PromiseSettledResult<void>[]> {\n const promises = tasks.map((task) => this.runTaskWithTimeout(phase, task));\n return Promise.allSettled(promises);\n }\n\n /**\n * Executes the coordinated startup sequence.\n *\n * Runs all registered tasks across startup phases in the correct order.\n * Each phase completes before the next phase begins. Tasks within a phase\n * are executed sequentially to maintain predictable initialization.\n *\n * @returns Promise that resolves when startup is complete\n * @throws An {@link Error} If startup fails or is called multiple times\n * @example\n * ```typescript\n * const startup = new CoordinatedStartup();\n * startup.addTask(StartupPhase.Services, 'database', () => db.connect(), 10000);\n * await startup.run();\n * ```\n */\n public async run(): Promise<void> {\n if (this.hasStarted) {\n this.logger.warn('Startup sequence has already completed');\n return;\n }\n\n if (this.isStartingUp) {\n this.logger.warn('Startup sequence already in progress');\n return;\n }\n\n this.isStartingUp = true;\n this.logger.info(`${chalk.bold.green('Starting')} coordinated startup sequence`);\n this.emit('startup:start');\n\n try {\n for (const phase of PHASE_ORDER) {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- abort() can flip isStartingUp to false mid-loop from the cli\n if (!this.isStartingUp) {\n this.logger.warn('Startup sequence aborted');\n return;\n }\n await this.runPhase(phase);\n }\n\n this.hasStarted = true;\n this.logger.info(`${chalk.bold.green('Coordinated startup completed')} successfully`);\n this.emit('startup:complete');\n } catch (error) {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- abort() can flip isStartingUp to false before this catch runs\n if (!this.isStartingUp) {\n this.logger.warn('Startup sequence aborted during error handling');\n return;\n }\n this.logger.error(`${chalk.bold.red('Coordinated startup failed')}`);\n this.emit('startup:error', error);\n throw error;\n } finally {\n this.isStartingUp = false;\n }\n }\n\n protected override async runTaskWithTimeout(phase: StartupPhase, task: LifecycleTask): Promise<void> {\n this.logger.info(\n `${chalk.italic('Starting')} task ${chalk.bold.cyan(task.name)} in phase ${chalk.bold.magenta(StartupPhase[phase])}`\n );\n\n let timeoutId: NodeJS.Timeout | undefined;\n\n try {\n await Promise.race([\n task.task(),\n new Promise<void>((_, reject) => {\n timeoutId = setTimeout(() => {\n reject(new SeedcordError(SeedcordErrorCode.LifecycleTaskTimeout, [task.name, task.timeout]));\n }, task.timeout);\n })\n ]);\n\n this.logger.info(\n `${chalk.italic('Completed')} task ${chalk.bold.cyan(task.name)} in phase ${chalk.bold.magenta(StartupPhase[phase])}`\n );\n } catch (error) {\n if (!this.isStartingUp) {\n return;\n }\n\n this.logger.error(\n `${chalk.italic('Failed')} task ${chalk.bold.cyan(task.name)} in phase ${chalk.bold.magenta(StartupPhase[phase])}:`,\n error\n );\n throw error;\n } finally {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n }\n }\n\n /**\n * Aborts the startup sequence if it is currently running.\n */\n public abort(): void {\n if (this.isStartingUp) {\n this.isStartingUp = false;\n this.logger.warn('Aborting coordinated startup sequence');\n }\n }\n\n /**\n * Check if startup has completed\n */\n public get isReady(): boolean {\n return this.hasStarted;\n }\n\n /**\n * Check if startup is currently running\n */\n public get isRunning(): boolean {\n return this.isStartingUp;\n }\n}\n","export * from './CooldownManager';\nexport * from './Errors';\nexport * from './HealthCheck';\nexport * from './Lifecycle';\nexport * from './Logger';\nexport * from './StrictEventEmitter';\n\n/** Package version */\nexport const version = process.env.PACKAGE_VERSION ?? '0.0.0';\n"],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+ const require_SeedcordError = require('./SeedcordError-wt7_KePP.cjs');
3
+
4
+ exports.SeedcordError = require_SeedcordError.SeedcordError;
5
+ exports.SeedcordRangeError = require_SeedcordError.SeedcordRangeError;
6
+ exports.SeedcordTypeError = require_SeedcordError.SeedcordTypeError;
@@ -0,0 +1 @@
1
+ export type * from './internal.index.d.mts'
@@ -0,0 +1,2 @@
1
+ import { a as SeedcordTypeError, i as SeedcordRangeError, n as SeedcordError } from "./SeedcordError-BuWVIe6m.mjs";
2
+ export { SeedcordError, SeedcordRangeError, SeedcordTypeError };
@@ -0,0 +1,3 @@
1
+ import { n as SeedcordRangeError, r as SeedcordTypeError, t as SeedcordError } from "./SeedcordError-xd-Ib_-z.mjs";
2
+
3
+ export { SeedcordError, SeedcordRangeError, SeedcordTypeError };
package/package.json CHANGED
@@ -1,20 +1,34 @@
1
1
  {
2
2
  "name": "@seedcord/services",
3
3
  "type": "module",
4
- "version": "0.6.0",
4
+ "version": "0.7.0-next.0",
5
5
  "description": "Services for Seedcord packages",
6
6
  "repository": {
7
7
  "type": "git",
8
- "url": "https://github.com/materwelonDhruv/seedcord.git",
8
+ "url": "https://github.com/seedcord/seedcord.git",
9
9
  "directory": "packages/services"
10
10
  },
11
- "types": "./dist/index.d.ts",
11
+ "types": "./dist/index.d.mts",
12
12
  "exports": {
13
13
  ".": {
14
- "types": "./dist/index.d.ts",
15
- "import": "./dist/index.mjs",
16
- "require": "./dist/index.cjs",
17
- "default": "./dist/index.mjs"
14
+ "import": {
15
+ "types": "./dist/index.d.mts",
16
+ "default": "./dist/index.mjs"
17
+ },
18
+ "require": {
19
+ "types": "./dist/index.d.cts",
20
+ "default": "./dist/index.cjs"
21
+ }
22
+ },
23
+ "./internal": {
24
+ "import": {
25
+ "types": "./dist/internal.index.d.mts",
26
+ "default": "./dist/internal.index.mjs"
27
+ },
28
+ "require": {
29
+ "types": "./dist/internal.index.d.cts",
30
+ "default": "./dist/internal.index.cjs"
31
+ }
18
32
  }
19
33
  },
20
34
  "files": [
@@ -24,35 +38,40 @@
24
38
  "LICENSE"
25
39
  ],
26
40
  "peerDependencies": {
27
- "typescript": "5.9.3"
41
+ "typescript": "^6.0.3"
28
42
  },
29
43
  "dependencies": {
30
- "chalk": "5.6.2",
31
- "discord.js": "14.25.1",
32
- "envapt": "4.1.0",
33
- "type-fest": "5.2.0",
34
- "winston": "^3.18.3",
35
- "@seedcord/types": "^0.3.5"
44
+ "chalk": "^5.6.2",
45
+ "envapt": "^5.0.3",
46
+ "strip-ansi": "^7.2.0",
47
+ "winston": "^3.19.0",
48
+ "winston-transport": "^4.9.0",
49
+ "@seedcord/types": "0.4.0-next.0",
50
+ "@seedcord/utils": "0.4.0-next.0"
36
51
  },
37
52
  "devDependencies": {
38
- "@seedcord/eslint-config": "^1.3.3",
39
- "@seedcord/tsconfig": "^1.1.2",
40
- "@seedcord/tsup-config": "^1.1.2"
53
+ "type-fest": "^5.6.0",
54
+ "@seedcord/eslint-config": "1.4.0-next.0",
55
+ "@seedcord/tsconfig": "2.0.0-next.0",
56
+ "@seedcord/tsdown-config": "2.0.0"
41
57
  },
42
58
  "publishConfig": {
43
59
  "access": "public",
44
60
  "provenance": true
45
61
  },
46
62
  "scripts": {
47
- "build": "tsup",
63
+ "build": "tsdown",
48
64
  "clean": "rm -rf dist",
49
- "lint": "eslint 'src/**/*.{ts,tsx}' --cache",
50
- "lint:fix": "eslint 'src/**/*.{ts,tsx}' --fix --cache",
51
- "fmt": "prettier --write 'src/**/*.{ts,tsx,json,md}' --cache",
52
- "fmt:check": "prettier --check 'src/**/*.{ts,tsx,json,md}' --cache",
65
+ "lint": "eslint 'src/**/*.{ts,tsx}' 'tests/**/*.{ts,tsx}' --cache",
66
+ "lint:fix": "eslint 'src/**/*.{ts,tsx}' 'tests/**/*.{ts,tsx}' --fix --cache",
67
+ "fmt": "prettier --write 'src/**/*.{ts,tsx,json,md}' 'tests/**/*.{ts,tsx,json,md}' --cache",
68
+ "fmt:check": "prettier --check 'src/**/*.{ts,tsx,json,md}' 'tests/**/*.{ts,tsx,json,md}' --cache",
53
69
  "tc": "tsc --noEmit",
54
- "test": "vitest run",
70
+ "test": "pnpm run test:unit && pnpm run test:types",
71
+ "test:unit": "vitest run",
55
72
  "test:watch": "vitest dev",
56
- "coverage": "vitest run --coverage"
57
- }
73
+ "coverage": "vitest run --coverage",
74
+ "test:types": "tsd --files \"tests/**/*.test-d.ts\""
75
+ },
76
+ "readme": "<p align=\"center\">\n <img src=\"../../assets/banner.png\" alt=\"seedcord\" width=\"100%\" />\n</p>\n\n---\n\n_This repository is a work in progress._\n\n- There are no stable releases yet but changes are being made actively.\n- Till a major v1.0.0 release for seedcord, expect breaking changes in minor versions.\n- Documentation will come soon as well!\n\nI'm planning to release the first major version by Q1 2026. But till then, if you'd like to try using it, you can check out the code in `mock`\n"
58
77
  }