@parsrun/core 0.1.29 → 0.1.31
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.
- package/dist/decimal.d.ts +176 -46
- package/dist/decimal.js +123 -40
- package/dist/decimal.js.map +1 -1
- package/dist/errors.d.ts +39 -3
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +184 -15
- package/dist/index.js +155 -40
- package/dist/index.js.map +1 -1
- package/dist/{logger-3oVznpFY.d.ts → logger-DrxxwI7C.d.ts} +136 -11
- package/dist/logger.d.ts +1 -1
- package/dist/logger.js +32 -0
- package/dist/logger.js.map +1 -1
- package/dist/transports/index.d.ts +58 -7
- package/dist/transports/index.js.map +1 -1
- package/dist/types.d.ts +176 -0
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
|
@@ -122,7 +122,19 @@ interface BatchTransportOptions extends BaseTransportOptions {
|
|
|
122
122
|
|
|
123
123
|
/**
|
|
124
124
|
* @parsrun/core - Console Transport
|
|
125
|
-
*
|
|
125
|
+
*
|
|
126
|
+
* Default log transport that outputs to the console.
|
|
127
|
+
* Supports pretty printing with colors for development and JSON output for production.
|
|
128
|
+
*
|
|
129
|
+
* @example
|
|
130
|
+
* ```typescript
|
|
131
|
+
* import { ConsoleTransport } from '@parsrun/core';
|
|
132
|
+
*
|
|
133
|
+
* const transport = new ConsoleTransport({
|
|
134
|
+
* pretty: true, // Enable colored, human-readable output
|
|
135
|
+
* colors: true // Enable ANSI colors
|
|
136
|
+
* });
|
|
137
|
+
* ```
|
|
126
138
|
*/
|
|
127
139
|
|
|
128
140
|
/**
|
|
@@ -173,7 +185,8 @@ declare class ConsoleTransport implements LogTransport {
|
|
|
173
185
|
*/
|
|
174
186
|
|
|
175
187
|
/**
|
|
176
|
-
* Log
|
|
188
|
+
* Log level constants mapping level names to numeric values.
|
|
189
|
+
* Lower values are more verbose; higher values are more severe.
|
|
177
190
|
*/
|
|
178
191
|
declare const LogLevel: {
|
|
179
192
|
readonly TRACE: 10;
|
|
@@ -184,29 +197,42 @@ declare const LogLevel: {
|
|
|
184
197
|
readonly FATAL: 60;
|
|
185
198
|
readonly SILENT: 100;
|
|
186
199
|
};
|
|
200
|
+
/** Log level name string literal type (TRACE, DEBUG, INFO, WARN, ERROR, FATAL, SILENT) */
|
|
187
201
|
type LogLevelName = keyof typeof LogLevel;
|
|
202
|
+
/** Numeric log level value type */
|
|
188
203
|
type LogLevelValue = (typeof LogLevel)[LogLevelName];
|
|
189
204
|
/**
|
|
190
|
-
*
|
|
205
|
+
* Structured error information included in log entries.
|
|
206
|
+
* Extracted from Error objects for serialization.
|
|
191
207
|
*/
|
|
192
208
|
interface ErrorInfo {
|
|
209
|
+
/** Error class name (e.g., "TypeError", "ValidationError") */
|
|
193
210
|
name: string;
|
|
211
|
+
/** Error message */
|
|
194
212
|
message: string;
|
|
213
|
+
/** Stack trace if available */
|
|
195
214
|
stack: string | undefined;
|
|
196
215
|
}
|
|
197
216
|
/**
|
|
198
|
-
*
|
|
217
|
+
* Structured log entry passed to transports.
|
|
218
|
+
* Contains all information about a single log event.
|
|
199
219
|
*/
|
|
200
220
|
interface LogEntry {
|
|
221
|
+
/** Log level name */
|
|
201
222
|
level: LogLevelName;
|
|
223
|
+
/** Numeric log level value */
|
|
202
224
|
levelValue: LogLevelValue;
|
|
225
|
+
/** Log message */
|
|
203
226
|
message: string;
|
|
227
|
+
/** ISO 8601 timestamp */
|
|
204
228
|
timestamp: string;
|
|
229
|
+
/** Additional context data */
|
|
205
230
|
context: Record<string, unknown> | undefined;
|
|
231
|
+
/** Error information if an error was logged */
|
|
206
232
|
error: ErrorInfo | undefined;
|
|
207
233
|
}
|
|
208
234
|
/**
|
|
209
|
-
* Logger
|
|
235
|
+
* Configuration options for creating a Logger instance.
|
|
210
236
|
*/
|
|
211
237
|
interface LoggerConfig {
|
|
212
238
|
/** Minimum log level */
|
|
@@ -225,7 +251,15 @@ interface LoggerConfig {
|
|
|
225
251
|
timestamp: boolean | (() => string) | undefined;
|
|
226
252
|
}
|
|
227
253
|
/**
|
|
228
|
-
*
|
|
254
|
+
* Structured logger with support for multiple transports and redaction.
|
|
255
|
+
* Thread-safe and edge-compatible.
|
|
256
|
+
*
|
|
257
|
+
* @example
|
|
258
|
+
* ```typescript
|
|
259
|
+
* const logger = new Logger({ name: 'api', level: 'DEBUG' });
|
|
260
|
+
* logger.info('Request received', { path: '/users' });
|
|
261
|
+
* logger.error('Request failed', new Error('Not found'), { userId: '123' });
|
|
262
|
+
* ```
|
|
229
263
|
*/
|
|
230
264
|
declare class Logger {
|
|
231
265
|
private level;
|
|
@@ -243,31 +277,122 @@ declare class Logger {
|
|
|
243
277
|
* Log a message
|
|
244
278
|
*/
|
|
245
279
|
private log;
|
|
280
|
+
/**
|
|
281
|
+
* Log a trace message (most verbose level).
|
|
282
|
+
* @param message - Log message
|
|
283
|
+
* @param context - Optional context data
|
|
284
|
+
*/
|
|
246
285
|
trace(message: string, context?: Record<string, unknown>): void;
|
|
286
|
+
/**
|
|
287
|
+
* Log a debug message.
|
|
288
|
+
* @param message - Log message
|
|
289
|
+
* @param context - Optional context data
|
|
290
|
+
*/
|
|
247
291
|
debug(message: string, context?: Record<string, unknown>): void;
|
|
292
|
+
/**
|
|
293
|
+
* Log an informational message.
|
|
294
|
+
* @param message - Log message
|
|
295
|
+
* @param context - Optional context data
|
|
296
|
+
*/
|
|
248
297
|
info(message: string, context?: Record<string, unknown>): void;
|
|
298
|
+
/**
|
|
299
|
+
* Log a warning message.
|
|
300
|
+
* @param message - Log message
|
|
301
|
+
* @param context - Optional context data
|
|
302
|
+
*/
|
|
249
303
|
warn(message: string, context?: Record<string, unknown>): void;
|
|
304
|
+
/**
|
|
305
|
+
* Log an error message with optional Error object.
|
|
306
|
+
* @param message - Log message
|
|
307
|
+
* @param error - Optional Error object or context
|
|
308
|
+
* @param context - Optional additional context
|
|
309
|
+
*/
|
|
250
310
|
error(message: string, error?: Error | unknown, context?: Record<string, unknown>): void;
|
|
311
|
+
/**
|
|
312
|
+
* Log a fatal error message (most severe level).
|
|
313
|
+
* @param message - Log message
|
|
314
|
+
* @param error - Optional Error object or context
|
|
315
|
+
* @param context - Optional additional context
|
|
316
|
+
*/
|
|
251
317
|
fatal(message: string, error?: Error | unknown, context?: Record<string, unknown>): void;
|
|
252
318
|
}
|
|
253
319
|
/**
|
|
254
|
-
* Create a
|
|
320
|
+
* Create a new Logger instance with the specified configuration.
|
|
321
|
+
*
|
|
322
|
+
* @param config - Logger configuration options
|
|
323
|
+
* @returns A new Logger instance
|
|
324
|
+
*
|
|
325
|
+
* @example
|
|
326
|
+
* ```typescript
|
|
327
|
+
* const log = createLogger({
|
|
328
|
+
* name: 'my-service',
|
|
329
|
+
* level: 'DEBUG',
|
|
330
|
+
* pretty: true
|
|
331
|
+
* });
|
|
332
|
+
* ```
|
|
255
333
|
*/
|
|
256
334
|
declare function createLogger(config?: Partial<LoggerConfig>): Logger;
|
|
257
335
|
/**
|
|
258
|
-
* Default logger instance
|
|
336
|
+
* Default logger instance using default configuration.
|
|
337
|
+
* Level can be controlled via LOG_LEVEL environment variable.
|
|
259
338
|
*/
|
|
260
339
|
declare const logger: Logger;
|
|
261
340
|
/**
|
|
262
|
-
* Utility
|
|
341
|
+
* Utility function to log an error with proper formatting.
|
|
342
|
+
* Handles both Error objects and unknown error types.
|
|
343
|
+
*
|
|
344
|
+
* @param log - The logger instance to use
|
|
345
|
+
* @param error - The error to log
|
|
346
|
+
* @param message - Human-readable error message
|
|
347
|
+
* @param context - Optional additional context
|
|
348
|
+
*
|
|
349
|
+
* @example
|
|
350
|
+
* ```typescript
|
|
351
|
+
* try {
|
|
352
|
+
* await doSomething();
|
|
353
|
+
* } catch (error) {
|
|
354
|
+
* logError(logger, error, 'Operation failed', { userId });
|
|
355
|
+
* }
|
|
356
|
+
* ```
|
|
263
357
|
*/
|
|
264
358
|
declare function logError(log: Logger, error: unknown, message: string, context?: Record<string, unknown>): void;
|
|
265
359
|
/**
|
|
266
|
-
*
|
|
360
|
+
* Measure and log the execution time of an async operation.
|
|
361
|
+
* Logs completion time on success, or error details on failure.
|
|
362
|
+
*
|
|
363
|
+
* @param log - The logger instance to use
|
|
364
|
+
* @param operation - Name of the operation being measured
|
|
365
|
+
* @param fn - Async function to execute and measure
|
|
366
|
+
* @returns The result of the function
|
|
367
|
+
*
|
|
368
|
+
* @example
|
|
369
|
+
* ```typescript
|
|
370
|
+
* const users = await measureTime(logger, 'fetchUsers', async () => {
|
|
371
|
+
* return await db.users.findMany();
|
|
372
|
+
* });
|
|
373
|
+
* // Logs: "fetchUsers completed" { operation: 'fetchUsers', durationMs: 45 }
|
|
374
|
+
* ```
|
|
267
375
|
*/
|
|
268
376
|
declare function measureTime<T>(log: Logger, operation: string, fn: () => Promise<T>): Promise<T>;
|
|
269
377
|
/**
|
|
270
|
-
*
|
|
378
|
+
* Create a child logger with request context for HTTP request logging.
|
|
379
|
+
* Automatically extracts the pathname from the URL.
|
|
380
|
+
*
|
|
381
|
+
* @param baseLogger - The parent logger instance
|
|
382
|
+
* @param request - Request information to include in all logs
|
|
383
|
+
* @returns A child Logger with request context
|
|
384
|
+
*
|
|
385
|
+
* @example
|
|
386
|
+
* ```typescript
|
|
387
|
+
* const requestLog = createRequestLogger(logger, {
|
|
388
|
+
* requestId: 'abc-123',
|
|
389
|
+
* method: 'GET',
|
|
390
|
+
* url: 'https://api.example.com/users',
|
|
391
|
+
* userId: 'user-456'
|
|
392
|
+
* });
|
|
393
|
+
* requestLog.info('Processing request');
|
|
394
|
+
* // Includes: requestId, method, path, userId in all logs
|
|
395
|
+
* ```
|
|
271
396
|
*/
|
|
272
397
|
declare function createRequestLogger(baseLogger: Logger, request: {
|
|
273
398
|
method?: string;
|
package/dist/logger.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { C as ConsoleTransport, q as ConsoleTransportOptions, r as ErrorInfo, g as LogEntry, a as LogLevel, e as LogLevelName, f as LogLevelValue, h as LogTransport, L as Logger, i as LoggerConfig, c as createLogger, d as createRequestLogger, b as logError, l as logger, m as measureTime } from './logger-
|
|
1
|
+
export { C as ConsoleTransport, q as ConsoleTransportOptions, r as ErrorInfo, g as LogEntry, a as LogLevel, e as LogLevelName, f as LogLevelValue, h as LogTransport, L as Logger, i as LoggerConfig, c as createLogger, d as createRequestLogger, b as logError, l as logger, m as measureTime } from './logger-DrxxwI7C.js';
|
package/dist/logger.js
CHANGED
|
@@ -257,23 +257,55 @@ var Logger = class _Logger {
|
|
|
257
257
|
transport.log(entry);
|
|
258
258
|
}
|
|
259
259
|
}
|
|
260
|
+
/**
|
|
261
|
+
* Log a trace message (most verbose level).
|
|
262
|
+
* @param message - Log message
|
|
263
|
+
* @param context - Optional context data
|
|
264
|
+
*/
|
|
260
265
|
trace(message, context) {
|
|
261
266
|
this.log("TRACE", message, context);
|
|
262
267
|
}
|
|
268
|
+
/**
|
|
269
|
+
* Log a debug message.
|
|
270
|
+
* @param message - Log message
|
|
271
|
+
* @param context - Optional context data
|
|
272
|
+
*/
|
|
263
273
|
debug(message, context) {
|
|
264
274
|
this.log("DEBUG", message, context);
|
|
265
275
|
}
|
|
276
|
+
/**
|
|
277
|
+
* Log an informational message.
|
|
278
|
+
* @param message - Log message
|
|
279
|
+
* @param context - Optional context data
|
|
280
|
+
*/
|
|
266
281
|
info(message, context) {
|
|
267
282
|
this.log("INFO", message, context);
|
|
268
283
|
}
|
|
284
|
+
/**
|
|
285
|
+
* Log a warning message.
|
|
286
|
+
* @param message - Log message
|
|
287
|
+
* @param context - Optional context data
|
|
288
|
+
*/
|
|
269
289
|
warn(message, context) {
|
|
270
290
|
this.log("WARN", message, context);
|
|
271
291
|
}
|
|
292
|
+
/**
|
|
293
|
+
* Log an error message with optional Error object.
|
|
294
|
+
* @param message - Log message
|
|
295
|
+
* @param error - Optional Error object or context
|
|
296
|
+
* @param context - Optional additional context
|
|
297
|
+
*/
|
|
272
298
|
error(message, error, context) {
|
|
273
299
|
const err = error instanceof Error ? error : void 0;
|
|
274
300
|
const ctx = error instanceof Error ? context : error;
|
|
275
301
|
this.log("ERROR", message, ctx, err);
|
|
276
302
|
}
|
|
303
|
+
/**
|
|
304
|
+
* Log a fatal error message (most severe level).
|
|
305
|
+
* @param message - Log message
|
|
306
|
+
* @param error - Optional Error object or context
|
|
307
|
+
* @param context - Optional additional context
|
|
308
|
+
*/
|
|
277
309
|
fatal(message, error, context) {
|
|
278
310
|
const err = error instanceof Error ? error : void 0;
|
|
279
311
|
const ctx = error instanceof Error ? context : error;
|
package/dist/logger.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/runtime.ts","../src/env.ts","../src/transports/console.ts","../src/logger.ts"],"sourcesContent":["/**\n * @module\n * Runtime detection for Node.js, Deno, Bun, and Cloudflare Workers.\n * Detects the current JavaScript runtime and provides helper functions.\n *\n * @example\n * ```typescript\n * import { runtime, isNode, isDeno, isBun, isCloudflare, getRuntimeVersion } from '@parsrun/core';\n *\n * console.log(`Running on ${runtime}`); // \"node\", \"deno\", \"bun\", \"cloudflare\", etc.\n *\n * if (isNode()) {\n * // Node.js specific code\n * } else if (isCloudflare()) {\n * // Cloudflare Workers specific code\n * }\n *\n * console.log(getRuntimeVersion()); // \"Node.js 20.0.0\"\n * ```\n */\n\nexport type Runtime = \"node\" | \"deno\" | \"bun\" | \"cloudflare\" | \"edge\" | \"browser\" | \"unknown\";\n\n/**\n * Detect the current JavaScript runtime\n */\nexport function detectRuntime(): Runtime {\n // Bun check (must be before Node since Bun also has process)\n if (typeof globalThis !== \"undefined\" && \"Bun\" in globalThis) {\n return \"bun\";\n }\n\n // Deno check\n if (typeof globalThis !== \"undefined\" && \"Deno\" in globalThis) {\n return \"deno\";\n }\n\n // Cloudflare Workers check (has caches but no process)\n if (\n typeof globalThis !== \"undefined\" &&\n typeof (globalThis as any).caches !== \"undefined\" &&\n typeof (globalThis as any).process === \"undefined\"\n ) {\n return \"cloudflare\";\n }\n\n // Generic Edge runtime check (Vercel Edge, etc.)\n if (\n typeof globalThis !== \"undefined\" &&\n typeof (globalThis as any).EdgeRuntime !== \"undefined\"\n ) {\n return \"edge\";\n }\n\n // Browser check\n if (\n typeof globalThis !== \"undefined\" &&\n typeof (globalThis as any).window !== \"undefined\" &&\n typeof (globalThis as any).document !== \"undefined\"\n ) {\n return \"browser\";\n }\n\n // Node.js check\n if (\n typeof process !== \"undefined\" &&\n process.versions &&\n process.versions.node\n ) {\n return \"node\";\n }\n\n return \"unknown\";\n}\n\n/**\n * Current runtime (cached)\n */\nexport const runtime = detectRuntime();\n\n/**\n * Runtime information helpers\n */\nexport const runtimeInfo = {\n runtime,\n isNode: runtime === \"node\",\n isDeno: runtime === \"deno\",\n isBun: runtime === \"bun\",\n isCloudflare: runtime === \"cloudflare\",\n isEdge: runtime === \"cloudflare\" || runtime === \"edge\" || runtime === \"deno\",\n isBrowser: runtime === \"browser\",\n isServer: runtime !== \"browser\",\n supportsWebCrypto: typeof globalThis.crypto?.subtle !== \"undefined\",\n supportsStreams: typeof globalThis.ReadableStream !== \"undefined\",\n} as const;\n\n/**\n * Check if running in Node.js\n */\nexport function isNode(): boolean {\n return runtime === \"node\";\n}\n\n/**\n * Check if running in Deno\n */\nexport function isDeno(): boolean {\n return runtime === \"deno\";\n}\n\n/**\n * Check if running in Bun\n */\nexport function isBun(): boolean {\n return runtime === \"bun\";\n}\n\n/**\n * Check if running in Cloudflare Workers\n */\nexport function isCloudflare(): boolean {\n return runtime === \"cloudflare\";\n}\n\n/**\n * Check if running in any edge environment\n */\nexport function isEdge(): boolean {\n return runtimeInfo.isEdge;\n}\n\n/**\n * Check if running in browser\n */\nexport function isBrowser(): boolean {\n return runtime === \"browser\";\n}\n\n/**\n * Check if running on server (not browser)\n */\nexport function isServer(): boolean {\n return runtimeInfo.isServer;\n}\n\n/**\n * Get runtime version string\n */\nexport function getRuntimeVersion(): string {\n switch (runtime) {\n case \"node\":\n return `Node.js ${process?.versions?.node ?? \"unknown\"}`;\n case \"bun\":\n return `Bun ${(globalThis as any).Bun.version}`;\n case \"deno\":\n return `Deno ${(globalThis as any).Deno.version.deno}`;\n case \"cloudflare\":\n return \"Cloudflare Workers\";\n case \"edge\":\n return \"Edge Runtime\";\n case \"browser\":\n return typeof navigator !== \"undefined\" ? navigator.userAgent : \"Browser\";\n default:\n return \"Unknown\";\n }\n}\n","/**\n * @module\n * Runtime-agnostic environment variable access.\n * Works in Node.js, Deno, Bun, and Cloudflare Workers.\n *\n * @example\n * ```typescript\n * import { getEnv, requireEnv, getEnvNumber, isDevelopment } from '@parsrun/core';\n *\n * // Get optional env var with default\n * const port = getEnvNumber('PORT', 3000);\n *\n * // Get required env var (throws if missing)\n * const apiKey = requireEnv('API_KEY');\n *\n * // Check environment\n * if (isDevelopment()) {\n * console.log('Running in development mode');\n * }\n * ```\n */\n\nimport { runtime } from \"./runtime.js\";\n\n/**\n * Environment variable store for edge runtimes\n * Must be set from the request handler's env parameter\n */\nlet edgeEnvStore: Record<string, string | undefined> = {};\n\n/**\n * Set environment variables for edge runtimes (Cloudflare Workers, etc.)\n * Call this from your worker's fetch handler with the env parameter\n *\n * @example\n * ```typescript\n * export default {\n * async fetch(request, env) {\n * setEdgeEnv(env);\n * // ... rest of handler\n * }\n * }\n * ```\n */\nexport function setEdgeEnv(env: Record<string, string | undefined>): void {\n edgeEnvStore = { ...edgeEnvStore, ...env };\n}\n\n/**\n * Clear edge environment store\n */\nexport function clearEdgeEnv(): void {\n edgeEnvStore = {};\n}\n\n/**\n * Get an environment variable value\n * Works across all runtimes\n */\nexport function getEnv(key: string, defaultValue?: string): string | undefined {\n // Edge runtimes (Cloudflare Workers, etc.)\n if (runtime === \"cloudflare\" || runtime === \"edge\") {\n return edgeEnvStore[key] ?? defaultValue;\n }\n\n // Deno\n if (runtime === \"deno\") {\n try {\n return (globalThis as any).Deno.env.get(key) ?? defaultValue;\n } catch {\n return defaultValue;\n }\n }\n\n // Node.js / Bun (both use process.env)\n if (typeof process !== \"undefined\" && process.env) {\n return process.env[key] ?? defaultValue;\n }\n\n // Browser - check for injected env\n if (runtime === \"browser\" && typeof (globalThis as any).__ENV__ !== \"undefined\") {\n return (globalThis as any).__ENV__[key] ?? defaultValue;\n }\n\n return defaultValue;\n}\n\n/**\n * Get an environment variable, throwing if not found\n */\nexport function requireEnv(key: string): string {\n const value = getEnv(key);\n if (value === undefined || value === \"\") {\n throw new Error(`Required environment variable \"${key}\" is not set`);\n }\n return value;\n}\n\n/**\n * Get an environment variable as a number\n */\nexport function getEnvNumber(key: string, defaultValue?: number): number | undefined {\n const value = getEnv(key);\n if (value === undefined || value === \"\") {\n return defaultValue;\n }\n const parsed = parseInt(value, 10);\n return isNaN(parsed) ? defaultValue : parsed;\n}\n\n/**\n * Get an environment variable as a float\n */\nexport function getEnvFloat(key: string, defaultValue?: number): number | undefined {\n const value = getEnv(key);\n if (value === undefined || value === \"\") {\n return defaultValue;\n }\n const parsed = parseFloat(value);\n return isNaN(parsed) ? defaultValue : parsed;\n}\n\n/**\n * Get an environment variable as a boolean\n */\nexport function getEnvBoolean(key: string, defaultValue: boolean = false): boolean {\n const value = getEnv(key);\n if (value === undefined || value === \"\") {\n return defaultValue;\n }\n return value === \"true\" || value === \"1\" || value === \"yes\";\n}\n\n/**\n * Get an environment variable as an array (comma-separated)\n */\nexport function getEnvArray(key: string, defaultValue: string[] = []): string[] {\n const value = getEnv(key);\n if (value === undefined || value === \"\") {\n return defaultValue;\n }\n return value.split(\",\").map((s) => s.trim()).filter(Boolean);\n}\n\n/**\n * Get an environment variable as JSON\n */\nexport function getEnvJson<T>(key: string, defaultValue?: T): T | undefined {\n const value = getEnv(key);\n if (value === undefined || value === \"\") {\n return defaultValue;\n }\n try {\n return JSON.parse(value) as T;\n } catch {\n return defaultValue;\n }\n}\n\n/**\n * Check if running in development mode\n */\nexport function isDevelopment(): boolean {\n const env = getEnv(\"NODE_ENV\");\n return env === \"development\" || env === undefined;\n}\n\n/**\n * Check if running in production mode\n */\nexport function isProduction(): boolean {\n return getEnv(\"NODE_ENV\") === \"production\";\n}\n\n/**\n * Check if running in test mode\n */\nexport function isTest(): boolean {\n return getEnv(\"NODE_ENV\") === \"test\";\n}\n\n/**\n * Environment mode\n */\nexport type EnvMode = \"development\" | \"production\" | \"test\";\n\n/**\n * Get current environment mode\n */\nexport function getEnvMode(): EnvMode {\n const env = getEnv(\"NODE_ENV\");\n if (env === \"production\") return \"production\";\n if (env === \"test\") return \"test\";\n return \"development\";\n}\n\n/**\n * Create a typed environment configuration object\n *\n * @example\n * ```typescript\n * const env = createEnvConfig({\n * DATABASE_URL: { required: true },\n * PORT: { type: 'number', default: 3000 },\n * DEBUG: { type: 'boolean', default: false },\n * });\n *\n * env.DATABASE_URL // string\n * env.PORT // number\n * env.DEBUG // boolean\n * ```\n */\nexport function createEnvConfig<T extends EnvSchema>(schema: T): EnvResult<T> {\n const result: Record<string, unknown> = {};\n\n for (const [key, config] of Object.entries(schema)) {\n const envConfig = config as EnvConfigItem;\n let value: unknown;\n\n switch (envConfig.type) {\n case \"number\":\n value = getEnvNumber(key, envConfig.default as number | undefined);\n break;\n case \"boolean\":\n value = getEnvBoolean(key, envConfig.default as boolean | undefined);\n break;\n case \"array\":\n value = getEnvArray(key, envConfig.default as string[] | undefined);\n break;\n case \"json\":\n value = getEnvJson(key, envConfig.default);\n break;\n default:\n value = getEnv(key, envConfig.default as string | undefined);\n }\n\n if (envConfig.required && (value === undefined || value === \"\")) {\n throw new Error(`Required environment variable \"${key}\" is not set`);\n }\n\n result[key] = value;\n }\n\n return result as EnvResult<T>;\n}\n\n// Type helpers for createEnvConfig\ntype EnvConfigItem = {\n type?: \"string\" | \"number\" | \"boolean\" | \"array\" | \"json\";\n required?: boolean;\n default?: unknown;\n};\n\ntype EnvSchema = Record<string, EnvConfigItem>;\n\ntype EnvResult<T extends EnvSchema> = {\n [K in keyof T]: T[K][\"type\"] extends \"number\"\n ? number\n : T[K][\"type\"] extends \"boolean\"\n ? boolean\n : T[K][\"type\"] extends \"array\"\n ? string[]\n : T[K][\"type\"] extends \"json\"\n ? unknown\n : string;\n};\n","/**\n * @parsrun/core - Console Transport\n * Default transport that outputs to console\n */\n\nimport { runtime } from \"../runtime.js\";\nimport { isDevelopment } from \"../env.js\";\nimport type { LogEntry, LogLevelName } from \"../logger.js\";\nimport type { LogTransport } from \"./types.js\";\n\n/**\n * Console transport options\n */\nexport interface ConsoleTransportOptions {\n /** Enable pretty printing (default: true in development) */\n pretty?: boolean;\n /** Enable ANSI colors (default: true in Node/Bun) */\n colors?: boolean;\n}\n\n/**\n * Console transport\n * Outputs logs to console with optional pretty printing and colors\n */\nexport class ConsoleTransport implements LogTransport {\n readonly name = \"console\";\n\n private pretty: boolean;\n private colors: boolean;\n\n constructor(options: ConsoleTransportOptions = {}) {\n this.pretty = options.pretty ?? isDevelopment();\n this.colors = options.colors ?? (runtime === \"node\" || runtime === \"bun\");\n }\n\n log(entry: LogEntry): void {\n if (this.pretty) {\n this.logPretty(entry);\n } else {\n this.logJson(entry);\n }\n }\n\n private logJson(entry: LogEntry): void {\n const { level, message, timestamp, context, error } = entry;\n\n const output: Record<string, unknown> = {\n level,\n time: timestamp,\n msg: message,\n };\n\n if (context && Object.keys(context).length > 0) {\n Object.assign(output, context);\n }\n\n if (error) {\n output[\"err\"] = error;\n }\n\n console.log(JSON.stringify(output));\n }\n\n private logPretty(entry: LogEntry): void {\n const { level, message, timestamp, context, error } = entry;\n\n const levelColors: Record<LogLevelName, string> = {\n TRACE: \"\\x1b[90m\", // Gray\n DEBUG: \"\\x1b[36m\", // Cyan\n INFO: \"\\x1b[32m\", // Green\n WARN: \"\\x1b[33m\", // Yellow\n ERROR: \"\\x1b[31m\", // Red\n FATAL: \"\\x1b[35m\", // Magenta\n SILENT: \"\",\n };\n\n const reset = \"\\x1b[0m\";\n const color = this.colors ? levelColors[level] : \"\";\n const resetCode = this.colors ? reset : \"\";\n\n // Extract time part from ISO timestamp\n const timePart = timestamp.split(\"T\")[1];\n const time = timePart ? timePart.slice(0, 8) : timestamp;\n\n let output = `${color}[${time}] ${level.padEnd(5)}${resetCode} ${message}`;\n\n if (context && Object.keys(context).length > 0) {\n output += ` ${JSON.stringify(context)}`;\n }\n\n // Route to appropriate console method\n if (level === \"ERROR\" || level === \"FATAL\") {\n console.error(output);\n if (error?.stack) {\n console.error(error.stack);\n }\n } else if (level === \"WARN\") {\n console.warn(output);\n } else if (level === \"DEBUG\" || level === \"TRACE\") {\n console.debug(output);\n } else {\n console.log(output);\n }\n }\n}\n","/**\n * @module\n * Lightweight, edge-compatible structured logging.\n * Works standalone or as abstraction over pino/winston in Node.js.\n *\n * @example\n * ```typescript\n * import { createLogger, Logger, LogLevel } from '@parsrun/core';\n *\n * // Create a logger\n * const log = createLogger({\n * name: 'my-service',\n * level: 'DEBUG',\n * pretty: true\n * });\n *\n * log.info('Server started', { port: 3000 });\n * log.error('Request failed', error, { userId: '123' });\n *\n * // Create child logger with context\n * const requestLog = log.child({ requestId: 'abc123' });\n * ```\n */\n\nimport { getEnv } from \"./env.js\";\nimport { ConsoleTransport } from \"./transports/console.js\";\nimport type { LogTransport } from \"./transports/types.js\";\n\n// Re-export ConsoleTransport for backward compatibility\nexport { ConsoleTransport, type ConsoleTransportOptions } from \"./transports/console.js\";\n\n// Re-export transport types\nexport type { LogTransport } from \"./transports/types.js\";\n\n/**\n * Log levels\n */\nexport const LogLevel = {\n TRACE: 10,\n DEBUG: 20,\n INFO: 30,\n WARN: 40,\n ERROR: 50,\n FATAL: 60,\n SILENT: 100,\n} as const;\n\nexport type LogLevelName = keyof typeof LogLevel;\nexport type LogLevelValue = (typeof LogLevel)[LogLevelName];\n\n/**\n * Error info structure\n */\nexport interface ErrorInfo {\n name: string;\n message: string;\n stack: string | undefined;\n}\n\n/**\n * Log entry structure\n */\nexport interface LogEntry {\n level: LogLevelName;\n levelValue: LogLevelValue;\n message: string;\n timestamp: string;\n context: Record<string, unknown> | undefined;\n error: ErrorInfo | undefined;\n}\n\n\n/**\n * Logger configuration\n */\nexport interface LoggerConfig {\n /** Minimum log level */\n level: LogLevelName | undefined;\n /** Logger name/module */\n name: string | undefined;\n /** Base context added to all logs */\n context: Record<string, unknown> | undefined;\n /** Custom transports */\n transports: LogTransport[] | undefined;\n /** Pretty print in development */\n pretty: boolean | undefined;\n /** Redact sensitive fields */\n redact: string[] | undefined;\n /** Timestamp format */\n timestamp: boolean | (() => string) | undefined;\n}\n\n\n/**\n * Redact sensitive fields from context\n */\nfunction redactFields(\n obj: Record<string, unknown>,\n fields: string[]\n): Record<string, unknown> {\n const result = { ...obj };\n for (const field of fields) {\n if (field in result) {\n result[field] = \"[REDACTED]\";\n }\n // Handle nested fields like \"user.password\"\n const parts = field.split(\".\");\n if (parts.length > 1) {\n let current: Record<string, unknown> | undefined = result;\n for (let i = 0; i < parts.length - 1; i++) {\n const part = parts[i];\n if (part && current && typeof current === \"object\" && part in current) {\n const val = current[part];\n if (val && typeof val === \"object\") {\n current = val as Record<string, unknown>;\n } else {\n current = undefined;\n break;\n }\n } else {\n current = undefined;\n break;\n }\n }\n const lastPart = parts[parts.length - 1];\n if (lastPart && current && typeof current === \"object\" && lastPart in current) {\n current[lastPart] = \"[REDACTED]\";\n }\n }\n }\n return result;\n}\n\n/**\n * Default redact fields\n */\nconst DEFAULT_REDACT_FIELDS = [\n \"password\",\n \"secret\",\n \"token\",\n \"accessToken\",\n \"refreshToken\",\n \"apiKey\",\n \"authorization\",\n \"cookie\",\n \"creditCard\",\n \"ssn\",\n];\n\n/**\n * Logger class\n */\nexport class Logger {\n private level: LogLevelValue;\n private name: string | undefined;\n private context: Record<string, unknown>;\n private transports: LogTransport[];\n private redactFields: string[];\n private timestampFn: () => string;\n\n constructor(config: Partial<LoggerConfig> = {}) {\n const levelName = config.level ?? (getEnv(\"LOG_LEVEL\") as LogLevelName | undefined) ?? \"INFO\";\n this.level = LogLevel[levelName] ?? LogLevel.INFO;\n this.name = config.name;\n this.context = config.context ?? {};\n this.transports = config.transports ?? [\n new ConsoleTransport(\n config.pretty !== undefined ? { pretty: config.pretty } : {}\n ),\n ];\n this.redactFields = [...DEFAULT_REDACT_FIELDS, ...(config.redact ?? [])];\n\n if (config.timestamp === false) {\n this.timestampFn = () => \"\";\n } else if (typeof config.timestamp === \"function\") {\n this.timestampFn = config.timestamp;\n } else {\n this.timestampFn = () => new Date().toISOString();\n }\n }\n\n /**\n * Create a child logger with additional context\n */\n child(context: Record<string, unknown>): Logger {\n const levelEntry = Object.entries(LogLevel).find(([_, v]) => v === this.level);\n const levelName = levelEntry ? (levelEntry[0] as LogLevelName) : \"INFO\";\n\n const child = new Logger({\n level: levelName,\n name: this.name,\n context: { ...this.context, ...context },\n transports: this.transports,\n redact: this.redactFields,\n });\n return child;\n }\n\n /**\n * Log a message\n */\n private log(\n level: LogLevelName,\n message: string,\n context?: Record<string, unknown>,\n error?: Error\n ): void {\n const levelValue = LogLevel[level];\n if (levelValue < this.level) return;\n\n let finalContext = { ...this.context };\n if (this.name) {\n finalContext[\"module\"] = this.name;\n }\n if (context) {\n finalContext = { ...finalContext, ...context };\n }\n\n // Redact sensitive fields\n finalContext = redactFields(finalContext, this.redactFields);\n\n const entry: LogEntry = {\n level,\n levelValue,\n message,\n timestamp: this.timestampFn(),\n context: Object.keys(finalContext).length > 0 ? finalContext : undefined,\n error: error\n ? {\n name: error.name,\n message: error.message,\n stack: error.stack,\n }\n : undefined,\n };\n\n for (const transport of this.transports) {\n transport.log(entry);\n }\n }\n\n trace(message: string, context?: Record<string, unknown>): void {\n this.log(\"TRACE\", message, context);\n }\n\n debug(message: string, context?: Record<string, unknown>): void {\n this.log(\"DEBUG\", message, context);\n }\n\n info(message: string, context?: Record<string, unknown>): void {\n this.log(\"INFO\", message, context);\n }\n\n warn(message: string, context?: Record<string, unknown>): void {\n this.log(\"WARN\", message, context);\n }\n\n error(message: string, error?: Error | unknown, context?: Record<string, unknown>): void {\n const err = error instanceof Error ? error : undefined;\n const ctx = error instanceof Error ? context : (error as Record<string, unknown> | undefined);\n this.log(\"ERROR\", message, ctx, err);\n }\n\n fatal(message: string, error?: Error | unknown, context?: Record<string, unknown>): void {\n const err = error instanceof Error ? error : undefined;\n const ctx = error instanceof Error ? context : (error as Record<string, unknown> | undefined);\n this.log(\"FATAL\", message, ctx, err);\n }\n}\n\n/**\n * Create a logger instance\n */\nexport function createLogger(config?: Partial<LoggerConfig>): Logger {\n return new Logger(config);\n}\n\n/**\n * Default logger instance\n */\nexport const logger = createLogger();\n\n/**\n * Utility: Log error with proper formatting\n */\nexport function logError(\n log: Logger,\n error: unknown,\n message: string,\n context?: Record<string, unknown>\n): void {\n if (error instanceof Error) {\n log.error(message, error, context);\n } else {\n log.error(message, { error: String(error), ...context });\n }\n}\n\n/**\n * Utility: Measure execution time\n */\nexport async function measureTime<T>(\n log: Logger,\n operation: string,\n fn: () => Promise<T>\n): Promise<T> {\n const start = Date.now();\n try {\n const result = await fn();\n const duration = Date.now() - start;\n log.info(`${operation} completed`, { operation, durationMs: duration });\n return result;\n } catch (error) {\n const duration = Date.now() - start;\n logError(log, error, `${operation} failed`, { operation, durationMs: duration });\n throw error;\n }\n}\n\n/**\n * Utility: Create request logger middleware context\n */\nexport function createRequestLogger(\n baseLogger: Logger,\n request: {\n method?: string;\n url?: string;\n requestId?: string;\n userId?: string;\n tenantId?: string;\n }\n): Logger {\n const pathname = request.url ? new URL(request.url).pathname : undefined;\n return baseLogger.child({\n requestId: request.requestId,\n method: request.method,\n path: pathname,\n userId: request.userId,\n tenantId: request.tenantId,\n });\n}\n"],"mappings":";AA0BO,SAAS,gBAAyB;AAEvC,MAAI,OAAO,eAAe,eAAe,SAAS,YAAY;AAC5D,WAAO;AAAA,EACT;AAGA,MAAI,OAAO,eAAe,eAAe,UAAU,YAAY;AAC7D,WAAO;AAAA,EACT;AAGA,MACE,OAAO,eAAe,eACtB,OAAQ,WAAmB,WAAW,eACtC,OAAQ,WAAmB,YAAY,aACvC;AACA,WAAO;AAAA,EACT;AAGA,MACE,OAAO,eAAe,eACtB,OAAQ,WAAmB,gBAAgB,aAC3C;AACA,WAAO;AAAA,EACT;AAGA,MACE,OAAO,eAAe,eACtB,OAAQ,WAAmB,WAAW,eACtC,OAAQ,WAAmB,aAAa,aACxC;AACA,WAAO;AAAA,EACT;AAGA,MACE,OAAO,YAAY,eACnB,QAAQ,YACR,QAAQ,SAAS,MACjB;AACA,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAKO,IAAM,UAAU,cAAc;AAK9B,IAAM,cAAc;AAAA,EACzB;AAAA,EACA,QAAQ,YAAY;AAAA,EACpB,QAAQ,YAAY;AAAA,EACpB,OAAO,YAAY;AAAA,EACnB,cAAc,YAAY;AAAA,EAC1B,QAAQ,YAAY,gBAAgB,YAAY,UAAU,YAAY;AAAA,EACtE,WAAW,YAAY;AAAA,EACvB,UAAU,YAAY;AAAA,EACtB,mBAAmB,OAAO,WAAW,QAAQ,WAAW;AAAA,EACxD,iBAAiB,OAAO,WAAW,mBAAmB;AACxD;;;AClEA,IAAI,eAAmD,CAAC;AA+BjD,SAAS,OAAO,KAAa,cAA2C;AAE7E,MAAI,YAAY,gBAAgB,YAAY,QAAQ;AAClD,WAAO,aAAa,GAAG,KAAK;AAAA,EAC9B;AAGA,MAAI,YAAY,QAAQ;AACtB,QAAI;AACF,aAAQ,WAAmB,KAAK,IAAI,IAAI,GAAG,KAAK;AAAA,IAClD,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAGA,MAAI,OAAO,YAAY,eAAe,QAAQ,KAAK;AACjD,WAAO,QAAQ,IAAI,GAAG,KAAK;AAAA,EAC7B;AAGA,MAAI,YAAY,aAAa,OAAQ,WAAmB,YAAY,aAAa;AAC/E,WAAQ,WAAmB,QAAQ,GAAG,KAAK;AAAA,EAC7C;AAEA,SAAO;AACT;AA6EO,SAAS,gBAAyB;AACvC,QAAM,MAAM,OAAO,UAAU;AAC7B,SAAO,QAAQ,iBAAiB,QAAQ;AAC1C;;;AC7IO,IAAM,mBAAN,MAA+C;AAAA,EAC3C,OAAO;AAAA,EAER;AAAA,EACA;AAAA,EAER,YAAY,UAAmC,CAAC,GAAG;AACjD,SAAK,SAAS,QAAQ,UAAU,cAAc;AAC9C,SAAK,SAAS,QAAQ,WAAW,YAAY,UAAU,YAAY;AAAA,EACrE;AAAA,EAEA,IAAI,OAAuB;AACzB,QAAI,KAAK,QAAQ;AACf,WAAK,UAAU,KAAK;AAAA,IACtB,OAAO;AACL,WAAK,QAAQ,KAAK;AAAA,IACpB;AAAA,EACF;AAAA,EAEQ,QAAQ,OAAuB;AACrC,UAAM,EAAE,OAAO,SAAS,WAAW,SAAS,MAAM,IAAI;AAEtD,UAAM,SAAkC;AAAA,MACtC;AAAA,MACA,MAAM;AAAA,MACN,KAAK;AAAA,IACP;AAEA,QAAI,WAAW,OAAO,KAAK,OAAO,EAAE,SAAS,GAAG;AAC9C,aAAO,OAAO,QAAQ,OAAO;AAAA,IAC/B;AAEA,QAAI,OAAO;AACT,aAAO,KAAK,IAAI;AAAA,IAClB;AAEA,YAAQ,IAAI,KAAK,UAAU,MAAM,CAAC;AAAA,EACpC;AAAA,EAEQ,UAAU,OAAuB;AACvC,UAAM,EAAE,OAAO,SAAS,WAAW,SAAS,MAAM,IAAI;AAEtD,UAAM,cAA4C;AAAA,MAChD,OAAO;AAAA;AAAA,MACP,OAAO;AAAA;AAAA,MACP,MAAM;AAAA;AAAA,MACN,MAAM;AAAA;AAAA,MACN,OAAO;AAAA;AAAA,MACP,OAAO;AAAA;AAAA,MACP,QAAQ;AAAA,IACV;AAEA,UAAM,QAAQ;AACd,UAAM,QAAQ,KAAK,SAAS,YAAY,KAAK,IAAI;AACjD,UAAM,YAAY,KAAK,SAAS,QAAQ;AAGxC,UAAM,WAAW,UAAU,MAAM,GAAG,EAAE,CAAC;AACvC,UAAM,OAAO,WAAW,SAAS,MAAM,GAAG,CAAC,IAAI;AAE/C,QAAI,SAAS,GAAG,KAAK,IAAI,IAAI,KAAK,MAAM,OAAO,CAAC,CAAC,GAAG,SAAS,IAAI,OAAO;AAExE,QAAI,WAAW,OAAO,KAAK,OAAO,EAAE,SAAS,GAAG;AAC9C,gBAAU,IAAI,KAAK,UAAU,OAAO,CAAC;AAAA,IACvC;AAGA,QAAI,UAAU,WAAW,UAAU,SAAS;AAC1C,cAAQ,MAAM,MAAM;AACpB,UAAI,OAAO,OAAO;AAChB,gBAAQ,MAAM,MAAM,KAAK;AAAA,MAC3B;AAAA,IACF,WAAW,UAAU,QAAQ;AAC3B,cAAQ,KAAK,MAAM;AAAA,IACrB,WAAW,UAAU,WAAW,UAAU,SAAS;AACjD,cAAQ,MAAM,MAAM;AAAA,IACtB,OAAO;AACL,cAAQ,IAAI,MAAM;AAAA,IACpB;AAAA,EACF;AACF;;;ACnEO,IAAM,WAAW;AAAA,EACtB,OAAO;AAAA,EACP,OAAO;AAAA,EACP,MAAM;AAAA,EACN,MAAM;AAAA,EACN,OAAO;AAAA,EACP,OAAO;AAAA,EACP,QAAQ;AACV;AAmDA,SAAS,aACP,KACA,QACyB;AACzB,QAAM,SAAS,EAAE,GAAG,IAAI;AACxB,aAAW,SAAS,QAAQ;AAC1B,QAAI,SAAS,QAAQ;AACnB,aAAO,KAAK,IAAI;AAAA,IAClB;AAEA,UAAM,QAAQ,MAAM,MAAM,GAAG;AAC7B,QAAI,MAAM,SAAS,GAAG;AACpB,UAAI,UAA+C;AACnD,eAAS,IAAI,GAAG,IAAI,MAAM,SAAS,GAAG,KAAK;AACzC,cAAM,OAAO,MAAM,CAAC;AACpB,YAAI,QAAQ,WAAW,OAAO,YAAY,YAAY,QAAQ,SAAS;AACrE,gBAAM,MAAM,QAAQ,IAAI;AACxB,cAAI,OAAO,OAAO,QAAQ,UAAU;AAClC,sBAAU;AAAA,UACZ,OAAO;AACL,sBAAU;AACV;AAAA,UACF;AAAA,QACF,OAAO;AACL,oBAAU;AACV;AAAA,QACF;AAAA,MACF;AACA,YAAM,WAAW,MAAM,MAAM,SAAS,CAAC;AACvC,UAAI,YAAY,WAAW,OAAO,YAAY,YAAY,YAAY,SAAS;AAC7E,gBAAQ,QAAQ,IAAI;AAAA,MACtB;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAKA,IAAM,wBAAwB;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAKO,IAAM,SAAN,MAAM,QAAO;AAAA,EACV;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAER,YAAY,SAAgC,CAAC,GAAG;AAC9C,UAAM,YAAY,OAAO,SAAU,OAAO,WAAW,KAAkC;AACvF,SAAK,QAAQ,SAAS,SAAS,KAAK,SAAS;AAC7C,SAAK,OAAO,OAAO;AACnB,SAAK,UAAU,OAAO,WAAW,CAAC;AAClC,SAAK,aAAa,OAAO,cAAc;AAAA,MACrC,IAAI;AAAA,QACF,OAAO,WAAW,SAAY,EAAE,QAAQ,OAAO,OAAO,IAAI,CAAC;AAAA,MAC7D;AAAA,IACF;AACA,SAAK,eAAe,CAAC,GAAG,uBAAuB,GAAI,OAAO,UAAU,CAAC,CAAE;AAEvE,QAAI,OAAO,cAAc,OAAO;AAC9B,WAAK,cAAc,MAAM;AAAA,IAC3B,WAAW,OAAO,OAAO,cAAc,YAAY;AACjD,WAAK,cAAc,OAAO;AAAA,IAC5B,OAAO;AACL,WAAK,cAAc,OAAM,oBAAI,KAAK,GAAE,YAAY;AAAA,IAClD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SAA0C;AAC9C,UAAM,aAAa,OAAO,QAAQ,QAAQ,EAAE,KAAK,CAAC,CAAC,GAAG,CAAC,MAAM,MAAM,KAAK,KAAK;AAC7E,UAAM,YAAY,aAAc,WAAW,CAAC,IAAqB;AAEjE,UAAM,QAAQ,IAAI,QAAO;AAAA,MACvB,OAAO;AAAA,MACP,MAAM,KAAK;AAAA,MACX,SAAS,EAAE,GAAG,KAAK,SAAS,GAAG,QAAQ;AAAA,MACvC,YAAY,KAAK;AAAA,MACjB,QAAQ,KAAK;AAAA,IACf,CAAC;AACD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,IACN,OACA,SACA,SACA,OACM;AACN,UAAM,aAAa,SAAS,KAAK;AACjC,QAAI,aAAa,KAAK,MAAO;AAE7B,QAAI,eAAe,EAAE,GAAG,KAAK,QAAQ;AACrC,QAAI,KAAK,MAAM;AACb,mBAAa,QAAQ,IAAI,KAAK;AAAA,IAChC;AACA,QAAI,SAAS;AACX,qBAAe,EAAE,GAAG,cAAc,GAAG,QAAQ;AAAA,IAC/C;AAGA,mBAAe,aAAa,cAAc,KAAK,YAAY;AAE3D,UAAM,QAAkB;AAAA,MACtB;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAW,KAAK,YAAY;AAAA,MAC5B,SAAS,OAAO,KAAK,YAAY,EAAE,SAAS,IAAI,eAAe;AAAA,MAC/D,OAAO,QACH;AAAA,QACE,MAAM,MAAM;AAAA,QACZ,SAAS,MAAM;AAAA,QACf,OAAO,MAAM;AAAA,MACf,IACA;AAAA,IACN;AAEA,eAAW,aAAa,KAAK,YAAY;AACvC,gBAAU,IAAI,KAAK;AAAA,IACrB;AAAA,EACF;AAAA,EAEA,MAAM,SAAiB,SAAyC;AAC9D,SAAK,IAAI,SAAS,SAAS,OAAO;AAAA,EACpC;AAAA,EAEA,MAAM,SAAiB,SAAyC;AAC9D,SAAK,IAAI,SAAS,SAAS,OAAO;AAAA,EACpC;AAAA,EAEA,KAAK,SAAiB,SAAyC;AAC7D,SAAK,IAAI,QAAQ,SAAS,OAAO;AAAA,EACnC;AAAA,EAEA,KAAK,SAAiB,SAAyC;AAC7D,SAAK,IAAI,QAAQ,SAAS,OAAO;AAAA,EACnC;AAAA,EAEA,MAAM,SAAiB,OAAyB,SAAyC;AACvF,UAAM,MAAM,iBAAiB,QAAQ,QAAQ;AAC7C,UAAM,MAAM,iBAAiB,QAAQ,UAAW;AAChD,SAAK,IAAI,SAAS,SAAS,KAAK,GAAG;AAAA,EACrC;AAAA,EAEA,MAAM,SAAiB,OAAyB,SAAyC;AACvF,UAAM,MAAM,iBAAiB,QAAQ,QAAQ;AAC7C,UAAM,MAAM,iBAAiB,QAAQ,UAAW;AAChD,SAAK,IAAI,SAAS,SAAS,KAAK,GAAG;AAAA,EACrC;AACF;AAKO,SAAS,aAAa,QAAwC;AACnE,SAAO,IAAI,OAAO,MAAM;AAC1B;AAKO,IAAM,SAAS,aAAa;AAK5B,SAAS,SACd,KACA,OACA,SACA,SACM;AACN,MAAI,iBAAiB,OAAO;AAC1B,QAAI,MAAM,SAAS,OAAO,OAAO;AAAA,EACnC,OAAO;AACL,QAAI,MAAM,SAAS,EAAE,OAAO,OAAO,KAAK,GAAG,GAAG,QAAQ,CAAC;AAAA,EACzD;AACF;AAKA,eAAsB,YACpB,KACA,WACA,IACY;AACZ,QAAM,QAAQ,KAAK,IAAI;AACvB,MAAI;AACF,UAAM,SAAS,MAAM,GAAG;AACxB,UAAM,WAAW,KAAK,IAAI,IAAI;AAC9B,QAAI,KAAK,GAAG,SAAS,cAAc,EAAE,WAAW,YAAY,SAAS,CAAC;AACtE,WAAO;AAAA,EACT,SAAS,OAAO;AACd,UAAM,WAAW,KAAK,IAAI,IAAI;AAC9B,aAAS,KAAK,OAAO,GAAG,SAAS,WAAW,EAAE,WAAW,YAAY,SAAS,CAAC;AAC/E,UAAM;AAAA,EACR;AACF;AAKO,SAAS,oBACd,YACA,SAOQ;AACR,QAAM,WAAW,QAAQ,MAAM,IAAI,IAAI,QAAQ,GAAG,EAAE,WAAW;AAC/D,SAAO,WAAW,MAAM;AAAA,IACtB,WAAW,QAAQ;AAAA,IACnB,QAAQ,QAAQ;AAAA,IAChB,MAAM;AAAA,IACN,QAAQ,QAAQ;AAAA,IAChB,UAAU,QAAQ;AAAA,EACpB,CAAC;AACH;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/runtime.ts","../src/env.ts","../src/transports/console.ts","../src/logger.ts"],"sourcesContent":["/**\n * @module\n * Runtime detection for Node.js, Deno, Bun, and Cloudflare Workers.\n * Detects the current JavaScript runtime and provides helper functions.\n *\n * @example\n * ```typescript\n * import { runtime, isNode, isDeno, isBun, isCloudflare, getRuntimeVersion } from '@parsrun/core';\n *\n * console.log(`Running on ${runtime}`); // \"node\", \"deno\", \"bun\", \"cloudflare\", etc.\n *\n * if (isNode()) {\n * // Node.js specific code\n * } else if (isCloudflare()) {\n * // Cloudflare Workers specific code\n * }\n *\n * console.log(getRuntimeVersion()); // \"Node.js 20.0.0\"\n * ```\n */\n\nexport type Runtime = \"node\" | \"deno\" | \"bun\" | \"cloudflare\" | \"edge\" | \"browser\" | \"unknown\";\n\n/**\n * Detect the current JavaScript runtime\n */\nexport function detectRuntime(): Runtime {\n // Bun check (must be before Node since Bun also has process)\n if (typeof globalThis !== \"undefined\" && \"Bun\" in globalThis) {\n return \"bun\";\n }\n\n // Deno check\n if (typeof globalThis !== \"undefined\" && \"Deno\" in globalThis) {\n return \"deno\";\n }\n\n // Cloudflare Workers check (has caches but no process)\n if (\n typeof globalThis !== \"undefined\" &&\n typeof (globalThis as any).caches !== \"undefined\" &&\n typeof (globalThis as any).process === \"undefined\"\n ) {\n return \"cloudflare\";\n }\n\n // Generic Edge runtime check (Vercel Edge, etc.)\n if (\n typeof globalThis !== \"undefined\" &&\n typeof (globalThis as any).EdgeRuntime !== \"undefined\"\n ) {\n return \"edge\";\n }\n\n // Browser check\n if (\n typeof globalThis !== \"undefined\" &&\n typeof (globalThis as any).window !== \"undefined\" &&\n typeof (globalThis as any).document !== \"undefined\"\n ) {\n return \"browser\";\n }\n\n // Node.js check\n if (\n typeof process !== \"undefined\" &&\n process.versions &&\n process.versions.node\n ) {\n return \"node\";\n }\n\n return \"unknown\";\n}\n\n/**\n * Current runtime (cached)\n */\nexport const runtime = detectRuntime();\n\n/**\n * Runtime information helpers\n */\nexport const runtimeInfo = {\n runtime,\n isNode: runtime === \"node\",\n isDeno: runtime === \"deno\",\n isBun: runtime === \"bun\",\n isCloudflare: runtime === \"cloudflare\",\n isEdge: runtime === \"cloudflare\" || runtime === \"edge\" || runtime === \"deno\",\n isBrowser: runtime === \"browser\",\n isServer: runtime !== \"browser\",\n supportsWebCrypto: typeof globalThis.crypto?.subtle !== \"undefined\",\n supportsStreams: typeof globalThis.ReadableStream !== \"undefined\",\n} as const;\n\n/**\n * Check if running in Node.js\n */\nexport function isNode(): boolean {\n return runtime === \"node\";\n}\n\n/**\n * Check if running in Deno\n */\nexport function isDeno(): boolean {\n return runtime === \"deno\";\n}\n\n/**\n * Check if running in Bun\n */\nexport function isBun(): boolean {\n return runtime === \"bun\";\n}\n\n/**\n * Check if running in Cloudflare Workers\n */\nexport function isCloudflare(): boolean {\n return runtime === \"cloudflare\";\n}\n\n/**\n * Check if running in any edge environment\n */\nexport function isEdge(): boolean {\n return runtimeInfo.isEdge;\n}\n\n/**\n * Check if running in browser\n */\nexport function isBrowser(): boolean {\n return runtime === \"browser\";\n}\n\n/**\n * Check if running on server (not browser)\n */\nexport function isServer(): boolean {\n return runtimeInfo.isServer;\n}\n\n/**\n * Get runtime version string\n */\nexport function getRuntimeVersion(): string {\n switch (runtime) {\n case \"node\":\n return `Node.js ${process?.versions?.node ?? \"unknown\"}`;\n case \"bun\":\n return `Bun ${(globalThis as any).Bun.version}`;\n case \"deno\":\n return `Deno ${(globalThis as any).Deno.version.deno}`;\n case \"cloudflare\":\n return \"Cloudflare Workers\";\n case \"edge\":\n return \"Edge Runtime\";\n case \"browser\":\n return typeof navigator !== \"undefined\" ? navigator.userAgent : \"Browser\";\n default:\n return \"Unknown\";\n }\n}\n","/**\n * @module\n * Runtime-agnostic environment variable access.\n * Works in Node.js, Deno, Bun, and Cloudflare Workers.\n *\n * @example\n * ```typescript\n * import { getEnv, requireEnv, getEnvNumber, isDevelopment } from '@parsrun/core';\n *\n * // Get optional env var with default\n * const port = getEnvNumber('PORT', 3000);\n *\n * // Get required env var (throws if missing)\n * const apiKey = requireEnv('API_KEY');\n *\n * // Check environment\n * if (isDevelopment()) {\n * console.log('Running in development mode');\n * }\n * ```\n */\n\nimport { runtime } from \"./runtime.js\";\n\n/**\n * Environment variable store for edge runtimes\n * Must be set from the request handler's env parameter\n */\nlet edgeEnvStore: Record<string, string | undefined> = {};\n\n/**\n * Set environment variables for edge runtimes (Cloudflare Workers, etc.)\n * Call this from your worker's fetch handler with the env parameter\n *\n * @example\n * ```typescript\n * export default {\n * async fetch(request, env) {\n * setEdgeEnv(env);\n * // ... rest of handler\n * }\n * }\n * ```\n */\nexport function setEdgeEnv(env: Record<string, string | undefined>): void {\n edgeEnvStore = { ...edgeEnvStore, ...env };\n}\n\n/**\n * Clear edge environment store\n */\nexport function clearEdgeEnv(): void {\n edgeEnvStore = {};\n}\n\n/**\n * Get an environment variable value\n * Works across all runtimes\n */\nexport function getEnv(key: string, defaultValue?: string): string | undefined {\n // Edge runtimes (Cloudflare Workers, etc.)\n if (runtime === \"cloudflare\" || runtime === \"edge\") {\n return edgeEnvStore[key] ?? defaultValue;\n }\n\n // Deno\n if (runtime === \"deno\") {\n try {\n return (globalThis as any).Deno.env.get(key) ?? defaultValue;\n } catch {\n return defaultValue;\n }\n }\n\n // Node.js / Bun (both use process.env)\n if (typeof process !== \"undefined\" && process.env) {\n return process.env[key] ?? defaultValue;\n }\n\n // Browser - check for injected env\n if (runtime === \"browser\" && typeof (globalThis as any).__ENV__ !== \"undefined\") {\n return (globalThis as any).__ENV__[key] ?? defaultValue;\n }\n\n return defaultValue;\n}\n\n/**\n * Get an environment variable, throwing if not found\n */\nexport function requireEnv(key: string): string {\n const value = getEnv(key);\n if (value === undefined || value === \"\") {\n throw new Error(`Required environment variable \"${key}\" is not set`);\n }\n return value;\n}\n\n/**\n * Get an environment variable as a number\n */\nexport function getEnvNumber(key: string, defaultValue?: number): number | undefined {\n const value = getEnv(key);\n if (value === undefined || value === \"\") {\n return defaultValue;\n }\n const parsed = parseInt(value, 10);\n return isNaN(parsed) ? defaultValue : parsed;\n}\n\n/**\n * Get an environment variable as a float\n */\nexport function getEnvFloat(key: string, defaultValue?: number): number | undefined {\n const value = getEnv(key);\n if (value === undefined || value === \"\") {\n return defaultValue;\n }\n const parsed = parseFloat(value);\n return isNaN(parsed) ? defaultValue : parsed;\n}\n\n/**\n * Get an environment variable as a boolean\n */\nexport function getEnvBoolean(key: string, defaultValue: boolean = false): boolean {\n const value = getEnv(key);\n if (value === undefined || value === \"\") {\n return defaultValue;\n }\n return value === \"true\" || value === \"1\" || value === \"yes\";\n}\n\n/**\n * Get an environment variable as an array (comma-separated)\n */\nexport function getEnvArray(key: string, defaultValue: string[] = []): string[] {\n const value = getEnv(key);\n if (value === undefined || value === \"\") {\n return defaultValue;\n }\n return value.split(\",\").map((s) => s.trim()).filter(Boolean);\n}\n\n/**\n * Get an environment variable as JSON\n */\nexport function getEnvJson<T>(key: string, defaultValue?: T): T | undefined {\n const value = getEnv(key);\n if (value === undefined || value === \"\") {\n return defaultValue;\n }\n try {\n return JSON.parse(value) as T;\n } catch {\n return defaultValue;\n }\n}\n\n/**\n * Check if running in development mode\n */\nexport function isDevelopment(): boolean {\n const env = getEnv(\"NODE_ENV\");\n return env === \"development\" || env === undefined;\n}\n\n/**\n * Check if running in production mode\n */\nexport function isProduction(): boolean {\n return getEnv(\"NODE_ENV\") === \"production\";\n}\n\n/**\n * Check if running in test mode\n */\nexport function isTest(): boolean {\n return getEnv(\"NODE_ENV\") === \"test\";\n}\n\n/**\n * Environment mode\n */\nexport type EnvMode = \"development\" | \"production\" | \"test\";\n\n/**\n * Get current environment mode\n */\nexport function getEnvMode(): EnvMode {\n const env = getEnv(\"NODE_ENV\");\n if (env === \"production\") return \"production\";\n if (env === \"test\") return \"test\";\n return \"development\";\n}\n\n/**\n * Create a typed environment configuration object\n *\n * @example\n * ```typescript\n * const env = createEnvConfig({\n * DATABASE_URL: { required: true },\n * PORT: { type: 'number', default: 3000 },\n * DEBUG: { type: 'boolean', default: false },\n * });\n *\n * env.DATABASE_URL // string\n * env.PORT // number\n * env.DEBUG // boolean\n * ```\n */\nexport function createEnvConfig<T extends EnvSchema>(schema: T): EnvResult<T> {\n const result: Record<string, unknown> = {};\n\n for (const [key, config] of Object.entries(schema)) {\n const envConfig = config as EnvConfigItem;\n let value: unknown;\n\n switch (envConfig.type) {\n case \"number\":\n value = getEnvNumber(key, envConfig.default as number | undefined);\n break;\n case \"boolean\":\n value = getEnvBoolean(key, envConfig.default as boolean | undefined);\n break;\n case \"array\":\n value = getEnvArray(key, envConfig.default as string[] | undefined);\n break;\n case \"json\":\n value = getEnvJson(key, envConfig.default);\n break;\n default:\n value = getEnv(key, envConfig.default as string | undefined);\n }\n\n if (envConfig.required && (value === undefined || value === \"\")) {\n throw new Error(`Required environment variable \"${key}\" is not set`);\n }\n\n result[key] = value;\n }\n\n return result as EnvResult<T>;\n}\n\n// Type helpers for createEnvConfig\ntype EnvConfigItem = {\n type?: \"string\" | \"number\" | \"boolean\" | \"array\" | \"json\";\n required?: boolean;\n default?: unknown;\n};\n\ntype EnvSchema = Record<string, EnvConfigItem>;\n\ntype EnvResult<T extends EnvSchema> = {\n [K in keyof T]: T[K][\"type\"] extends \"number\"\n ? number\n : T[K][\"type\"] extends \"boolean\"\n ? boolean\n : T[K][\"type\"] extends \"array\"\n ? string[]\n : T[K][\"type\"] extends \"json\"\n ? unknown\n : string;\n};\n","/**\n * @parsrun/core - Console Transport\n *\n * Default log transport that outputs to the console.\n * Supports pretty printing with colors for development and JSON output for production.\n *\n * @example\n * ```typescript\n * import { ConsoleTransport } from '@parsrun/core';\n *\n * const transport = new ConsoleTransport({\n * pretty: true, // Enable colored, human-readable output\n * colors: true // Enable ANSI colors\n * });\n * ```\n */\n\nimport { runtime } from \"../runtime.js\";\nimport { isDevelopment } from \"../env.js\";\nimport type { LogEntry, LogLevelName } from \"../logger.js\";\nimport type { LogTransport } from \"./types.js\";\n\n/**\n * Console transport options\n */\nexport interface ConsoleTransportOptions {\n /** Enable pretty printing (default: true in development) */\n pretty?: boolean;\n /** Enable ANSI colors (default: true in Node/Bun) */\n colors?: boolean;\n}\n\n/**\n * Console transport\n * Outputs logs to console with optional pretty printing and colors\n */\nexport class ConsoleTransport implements LogTransport {\n readonly name = \"console\";\n\n private pretty: boolean;\n private colors: boolean;\n\n constructor(options: ConsoleTransportOptions = {}) {\n this.pretty = options.pretty ?? isDevelopment();\n this.colors = options.colors ?? (runtime === \"node\" || runtime === \"bun\");\n }\n\n log(entry: LogEntry): void {\n if (this.pretty) {\n this.logPretty(entry);\n } else {\n this.logJson(entry);\n }\n }\n\n private logJson(entry: LogEntry): void {\n const { level, message, timestamp, context, error } = entry;\n\n const output: Record<string, unknown> = {\n level,\n time: timestamp,\n msg: message,\n };\n\n if (context && Object.keys(context).length > 0) {\n Object.assign(output, context);\n }\n\n if (error) {\n output[\"err\"] = error;\n }\n\n console.log(JSON.stringify(output));\n }\n\n private logPretty(entry: LogEntry): void {\n const { level, message, timestamp, context, error } = entry;\n\n const levelColors: Record<LogLevelName, string> = {\n TRACE: \"\\x1b[90m\", // Gray\n DEBUG: \"\\x1b[36m\", // Cyan\n INFO: \"\\x1b[32m\", // Green\n WARN: \"\\x1b[33m\", // Yellow\n ERROR: \"\\x1b[31m\", // Red\n FATAL: \"\\x1b[35m\", // Magenta\n SILENT: \"\",\n };\n\n const reset = \"\\x1b[0m\";\n const color = this.colors ? levelColors[level] : \"\";\n const resetCode = this.colors ? reset : \"\";\n\n // Extract time part from ISO timestamp\n const timePart = timestamp.split(\"T\")[1];\n const time = timePart ? timePart.slice(0, 8) : timestamp;\n\n let output = `${color}[${time}] ${level.padEnd(5)}${resetCode} ${message}`;\n\n if (context && Object.keys(context).length > 0) {\n output += ` ${JSON.stringify(context)}`;\n }\n\n // Route to appropriate console method\n if (level === \"ERROR\" || level === \"FATAL\") {\n console.error(output);\n if (error?.stack) {\n console.error(error.stack);\n }\n } else if (level === \"WARN\") {\n console.warn(output);\n } else if (level === \"DEBUG\" || level === \"TRACE\") {\n console.debug(output);\n } else {\n console.log(output);\n }\n }\n}\n","/**\n * @module\n * Lightweight, edge-compatible structured logging.\n * Works standalone or as abstraction over pino/winston in Node.js.\n *\n * @example\n * ```typescript\n * import { createLogger, Logger, LogLevel } from '@parsrun/core';\n *\n * // Create a logger\n * const log = createLogger({\n * name: 'my-service',\n * level: 'DEBUG',\n * pretty: true\n * });\n *\n * log.info('Server started', { port: 3000 });\n * log.error('Request failed', error, { userId: '123' });\n *\n * // Create child logger with context\n * const requestLog = log.child({ requestId: 'abc123' });\n * ```\n */\n\nimport { getEnv } from \"./env.js\";\nimport { ConsoleTransport } from \"./transports/console.js\";\nimport type { LogTransport } from \"./transports/types.js\";\n\n// Re-export ConsoleTransport for backward compatibility\nexport { ConsoleTransport, type ConsoleTransportOptions } from \"./transports/console.js\";\n\n// Re-export transport types\nexport type { LogTransport } from \"./transports/types.js\";\n\n/**\n * Log level constants mapping level names to numeric values.\n * Lower values are more verbose; higher values are more severe.\n */\nexport const LogLevel = {\n TRACE: 10,\n DEBUG: 20,\n INFO: 30,\n WARN: 40,\n ERROR: 50,\n FATAL: 60,\n SILENT: 100,\n} as const;\n\n/** Log level name string literal type (TRACE, DEBUG, INFO, WARN, ERROR, FATAL, SILENT) */\nexport type LogLevelName = keyof typeof LogLevel;\n\n/** Numeric log level value type */\nexport type LogLevelValue = (typeof LogLevel)[LogLevelName];\n\n/**\n * Structured error information included in log entries.\n * Extracted from Error objects for serialization.\n */\nexport interface ErrorInfo {\n /** Error class name (e.g., \"TypeError\", \"ValidationError\") */\n name: string;\n /** Error message */\n message: string;\n /** Stack trace if available */\n stack: string | undefined;\n}\n\n/**\n * Structured log entry passed to transports.\n * Contains all information about a single log event.\n */\nexport interface LogEntry {\n /** Log level name */\n level: LogLevelName;\n /** Numeric log level value */\n levelValue: LogLevelValue;\n /** Log message */\n message: string;\n /** ISO 8601 timestamp */\n timestamp: string;\n /** Additional context data */\n context: Record<string, unknown> | undefined;\n /** Error information if an error was logged */\n error: ErrorInfo | undefined;\n}\n\n\n/**\n * Configuration options for creating a Logger instance.\n */\nexport interface LoggerConfig {\n /** Minimum log level */\n level: LogLevelName | undefined;\n /** Logger name/module */\n name: string | undefined;\n /** Base context added to all logs */\n context: Record<string, unknown> | undefined;\n /** Custom transports */\n transports: LogTransport[] | undefined;\n /** Pretty print in development */\n pretty: boolean | undefined;\n /** Redact sensitive fields */\n redact: string[] | undefined;\n /** Timestamp format */\n timestamp: boolean | (() => string) | undefined;\n}\n\n\n/**\n * Redact sensitive fields from context\n */\nfunction redactFields(\n obj: Record<string, unknown>,\n fields: string[]\n): Record<string, unknown> {\n const result = { ...obj };\n for (const field of fields) {\n if (field in result) {\n result[field] = \"[REDACTED]\";\n }\n // Handle nested fields like \"user.password\"\n const parts = field.split(\".\");\n if (parts.length > 1) {\n let current: Record<string, unknown> | undefined = result;\n for (let i = 0; i < parts.length - 1; i++) {\n const part = parts[i];\n if (part && current && typeof current === \"object\" && part in current) {\n const val = current[part];\n if (val && typeof val === \"object\") {\n current = val as Record<string, unknown>;\n } else {\n current = undefined;\n break;\n }\n } else {\n current = undefined;\n break;\n }\n }\n const lastPart = parts[parts.length - 1];\n if (lastPart && current && typeof current === \"object\" && lastPart in current) {\n current[lastPart] = \"[REDACTED]\";\n }\n }\n }\n return result;\n}\n\n/**\n * Default redact fields\n */\nconst DEFAULT_REDACT_FIELDS = [\n \"password\",\n \"secret\",\n \"token\",\n \"accessToken\",\n \"refreshToken\",\n \"apiKey\",\n \"authorization\",\n \"cookie\",\n \"creditCard\",\n \"ssn\",\n];\n\n/**\n * Structured logger with support for multiple transports and redaction.\n * Thread-safe and edge-compatible.\n *\n * @example\n * ```typescript\n * const logger = new Logger({ name: 'api', level: 'DEBUG' });\n * logger.info('Request received', { path: '/users' });\n * logger.error('Request failed', new Error('Not found'), { userId: '123' });\n * ```\n */\nexport class Logger {\n private level: LogLevelValue;\n private name: string | undefined;\n private context: Record<string, unknown>;\n private transports: LogTransport[];\n private redactFields: string[];\n private timestampFn: () => string;\n\n constructor(config: Partial<LoggerConfig> = {}) {\n const levelName = config.level ?? (getEnv(\"LOG_LEVEL\") as LogLevelName | undefined) ?? \"INFO\";\n this.level = LogLevel[levelName] ?? LogLevel.INFO;\n this.name = config.name;\n this.context = config.context ?? {};\n this.transports = config.transports ?? [\n new ConsoleTransport(\n config.pretty !== undefined ? { pretty: config.pretty } : {}\n ),\n ];\n this.redactFields = [...DEFAULT_REDACT_FIELDS, ...(config.redact ?? [])];\n\n if (config.timestamp === false) {\n this.timestampFn = () => \"\";\n } else if (typeof config.timestamp === \"function\") {\n this.timestampFn = config.timestamp;\n } else {\n this.timestampFn = () => new Date().toISOString();\n }\n }\n\n /**\n * Create a child logger with additional context\n */\n child(context: Record<string, unknown>): Logger {\n const levelEntry = Object.entries(LogLevel).find(([_, v]) => v === this.level);\n const levelName = levelEntry ? (levelEntry[0] as LogLevelName) : \"INFO\";\n\n const child = new Logger({\n level: levelName,\n name: this.name,\n context: { ...this.context, ...context },\n transports: this.transports,\n redact: this.redactFields,\n });\n return child;\n }\n\n /**\n * Log a message\n */\n private log(\n level: LogLevelName,\n message: string,\n context?: Record<string, unknown>,\n error?: Error\n ): void {\n const levelValue = LogLevel[level];\n if (levelValue < this.level) return;\n\n let finalContext = { ...this.context };\n if (this.name) {\n finalContext[\"module\"] = this.name;\n }\n if (context) {\n finalContext = { ...finalContext, ...context };\n }\n\n // Redact sensitive fields\n finalContext = redactFields(finalContext, this.redactFields);\n\n const entry: LogEntry = {\n level,\n levelValue,\n message,\n timestamp: this.timestampFn(),\n context: Object.keys(finalContext).length > 0 ? finalContext : undefined,\n error: error\n ? {\n name: error.name,\n message: error.message,\n stack: error.stack,\n }\n : undefined,\n };\n\n for (const transport of this.transports) {\n transport.log(entry);\n }\n }\n\n /**\n * Log a trace message (most verbose level).\n * @param message - Log message\n * @param context - Optional context data\n */\n trace(message: string, context?: Record<string, unknown>): void {\n this.log(\"TRACE\", message, context);\n }\n\n /**\n * Log a debug message.\n * @param message - Log message\n * @param context - Optional context data\n */\n debug(message: string, context?: Record<string, unknown>): void {\n this.log(\"DEBUG\", message, context);\n }\n\n /**\n * Log an informational message.\n * @param message - Log message\n * @param context - Optional context data\n */\n info(message: string, context?: Record<string, unknown>): void {\n this.log(\"INFO\", message, context);\n }\n\n /**\n * Log a warning message.\n * @param message - Log message\n * @param context - Optional context data\n */\n warn(message: string, context?: Record<string, unknown>): void {\n this.log(\"WARN\", message, context);\n }\n\n /**\n * Log an error message with optional Error object.\n * @param message - Log message\n * @param error - Optional Error object or context\n * @param context - Optional additional context\n */\n error(message: string, error?: Error | unknown, context?: Record<string, unknown>): void {\n const err = error instanceof Error ? error : undefined;\n const ctx = error instanceof Error ? context : (error as Record<string, unknown> | undefined);\n this.log(\"ERROR\", message, ctx, err);\n }\n\n /**\n * Log a fatal error message (most severe level).\n * @param message - Log message\n * @param error - Optional Error object or context\n * @param context - Optional additional context\n */\n fatal(message: string, error?: Error | unknown, context?: Record<string, unknown>): void {\n const err = error instanceof Error ? error : undefined;\n const ctx = error instanceof Error ? context : (error as Record<string, unknown> | undefined);\n this.log(\"FATAL\", message, ctx, err);\n }\n}\n\n/**\n * Create a new Logger instance with the specified configuration.\n *\n * @param config - Logger configuration options\n * @returns A new Logger instance\n *\n * @example\n * ```typescript\n * const log = createLogger({\n * name: 'my-service',\n * level: 'DEBUG',\n * pretty: true\n * });\n * ```\n */\nexport function createLogger(config?: Partial<LoggerConfig>): Logger {\n return new Logger(config);\n}\n\n/**\n * Default logger instance using default configuration.\n * Level can be controlled via LOG_LEVEL environment variable.\n */\nexport const logger = createLogger();\n\n/**\n * Utility function to log an error with proper formatting.\n * Handles both Error objects and unknown error types.\n *\n * @param log - The logger instance to use\n * @param error - The error to log\n * @param message - Human-readable error message\n * @param context - Optional additional context\n *\n * @example\n * ```typescript\n * try {\n * await doSomething();\n * } catch (error) {\n * logError(logger, error, 'Operation failed', { userId });\n * }\n * ```\n */\nexport function logError(\n log: Logger,\n error: unknown,\n message: string,\n context?: Record<string, unknown>\n): void {\n if (error instanceof Error) {\n log.error(message, error, context);\n } else {\n log.error(message, { error: String(error), ...context });\n }\n}\n\n/**\n * Measure and log the execution time of an async operation.\n * Logs completion time on success, or error details on failure.\n *\n * @param log - The logger instance to use\n * @param operation - Name of the operation being measured\n * @param fn - Async function to execute and measure\n * @returns The result of the function\n *\n * @example\n * ```typescript\n * const users = await measureTime(logger, 'fetchUsers', async () => {\n * return await db.users.findMany();\n * });\n * // Logs: \"fetchUsers completed\" { operation: 'fetchUsers', durationMs: 45 }\n * ```\n */\nexport async function measureTime<T>(\n log: Logger,\n operation: string,\n fn: () => Promise<T>\n): Promise<T> {\n const start = Date.now();\n try {\n const result = await fn();\n const duration = Date.now() - start;\n log.info(`${operation} completed`, { operation, durationMs: duration });\n return result;\n } catch (error) {\n const duration = Date.now() - start;\n logError(log, error, `${operation} failed`, { operation, durationMs: duration });\n throw error;\n }\n}\n\n/**\n * Create a child logger with request context for HTTP request logging.\n * Automatically extracts the pathname from the URL.\n *\n * @param baseLogger - The parent logger instance\n * @param request - Request information to include in all logs\n * @returns A child Logger with request context\n *\n * @example\n * ```typescript\n * const requestLog = createRequestLogger(logger, {\n * requestId: 'abc-123',\n * method: 'GET',\n * url: 'https://api.example.com/users',\n * userId: 'user-456'\n * });\n * requestLog.info('Processing request');\n * // Includes: requestId, method, path, userId in all logs\n * ```\n */\nexport function createRequestLogger(\n baseLogger: Logger,\n request: {\n method?: string;\n url?: string;\n requestId?: string;\n userId?: string;\n tenantId?: string;\n }\n): Logger {\n const pathname = request.url ? new URL(request.url).pathname : undefined;\n return baseLogger.child({\n requestId: request.requestId,\n method: request.method,\n path: pathname,\n userId: request.userId,\n tenantId: request.tenantId,\n });\n}\n"],"mappings":";AA0BO,SAAS,gBAAyB;AAEvC,MAAI,OAAO,eAAe,eAAe,SAAS,YAAY;AAC5D,WAAO;AAAA,EACT;AAGA,MAAI,OAAO,eAAe,eAAe,UAAU,YAAY;AAC7D,WAAO;AAAA,EACT;AAGA,MACE,OAAO,eAAe,eACtB,OAAQ,WAAmB,WAAW,eACtC,OAAQ,WAAmB,YAAY,aACvC;AACA,WAAO;AAAA,EACT;AAGA,MACE,OAAO,eAAe,eACtB,OAAQ,WAAmB,gBAAgB,aAC3C;AACA,WAAO;AAAA,EACT;AAGA,MACE,OAAO,eAAe,eACtB,OAAQ,WAAmB,WAAW,eACtC,OAAQ,WAAmB,aAAa,aACxC;AACA,WAAO;AAAA,EACT;AAGA,MACE,OAAO,YAAY,eACnB,QAAQ,YACR,QAAQ,SAAS,MACjB;AACA,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAKO,IAAM,UAAU,cAAc;AAK9B,IAAM,cAAc;AAAA,EACzB;AAAA,EACA,QAAQ,YAAY;AAAA,EACpB,QAAQ,YAAY;AAAA,EACpB,OAAO,YAAY;AAAA,EACnB,cAAc,YAAY;AAAA,EAC1B,QAAQ,YAAY,gBAAgB,YAAY,UAAU,YAAY;AAAA,EACtE,WAAW,YAAY;AAAA,EACvB,UAAU,YAAY;AAAA,EACtB,mBAAmB,OAAO,WAAW,QAAQ,WAAW;AAAA,EACxD,iBAAiB,OAAO,WAAW,mBAAmB;AACxD;;;AClEA,IAAI,eAAmD,CAAC;AA+BjD,SAAS,OAAO,KAAa,cAA2C;AAE7E,MAAI,YAAY,gBAAgB,YAAY,QAAQ;AAClD,WAAO,aAAa,GAAG,KAAK;AAAA,EAC9B;AAGA,MAAI,YAAY,QAAQ;AACtB,QAAI;AACF,aAAQ,WAAmB,KAAK,IAAI,IAAI,GAAG,KAAK;AAAA,IAClD,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAGA,MAAI,OAAO,YAAY,eAAe,QAAQ,KAAK;AACjD,WAAO,QAAQ,IAAI,GAAG,KAAK;AAAA,EAC7B;AAGA,MAAI,YAAY,aAAa,OAAQ,WAAmB,YAAY,aAAa;AAC/E,WAAQ,WAAmB,QAAQ,GAAG,KAAK;AAAA,EAC7C;AAEA,SAAO;AACT;AA6EO,SAAS,gBAAyB;AACvC,QAAM,MAAM,OAAO,UAAU;AAC7B,SAAO,QAAQ,iBAAiB,QAAQ;AAC1C;;;ACjIO,IAAM,mBAAN,MAA+C;AAAA,EAC3C,OAAO;AAAA,EAER;AAAA,EACA;AAAA,EAER,YAAY,UAAmC,CAAC,GAAG;AACjD,SAAK,SAAS,QAAQ,UAAU,cAAc;AAC9C,SAAK,SAAS,QAAQ,WAAW,YAAY,UAAU,YAAY;AAAA,EACrE;AAAA,EAEA,IAAI,OAAuB;AACzB,QAAI,KAAK,QAAQ;AACf,WAAK,UAAU,KAAK;AAAA,IACtB,OAAO;AACL,WAAK,QAAQ,KAAK;AAAA,IACpB;AAAA,EACF;AAAA,EAEQ,QAAQ,OAAuB;AACrC,UAAM,EAAE,OAAO,SAAS,WAAW,SAAS,MAAM,IAAI;AAEtD,UAAM,SAAkC;AAAA,MACtC;AAAA,MACA,MAAM;AAAA,MACN,KAAK;AAAA,IACP;AAEA,QAAI,WAAW,OAAO,KAAK,OAAO,EAAE,SAAS,GAAG;AAC9C,aAAO,OAAO,QAAQ,OAAO;AAAA,IAC/B;AAEA,QAAI,OAAO;AACT,aAAO,KAAK,IAAI;AAAA,IAClB;AAEA,YAAQ,IAAI,KAAK,UAAU,MAAM,CAAC;AAAA,EACpC;AAAA,EAEQ,UAAU,OAAuB;AACvC,UAAM,EAAE,OAAO,SAAS,WAAW,SAAS,MAAM,IAAI;AAEtD,UAAM,cAA4C;AAAA,MAChD,OAAO;AAAA;AAAA,MACP,OAAO;AAAA;AAAA,MACP,MAAM;AAAA;AAAA,MACN,MAAM;AAAA;AAAA,MACN,OAAO;AAAA;AAAA,MACP,OAAO;AAAA;AAAA,MACP,QAAQ;AAAA,IACV;AAEA,UAAM,QAAQ;AACd,UAAM,QAAQ,KAAK,SAAS,YAAY,KAAK,IAAI;AACjD,UAAM,YAAY,KAAK,SAAS,QAAQ;AAGxC,UAAM,WAAW,UAAU,MAAM,GAAG,EAAE,CAAC;AACvC,UAAM,OAAO,WAAW,SAAS,MAAM,GAAG,CAAC,IAAI;AAE/C,QAAI,SAAS,GAAG,KAAK,IAAI,IAAI,KAAK,MAAM,OAAO,CAAC,CAAC,GAAG,SAAS,IAAI,OAAO;AAExE,QAAI,WAAW,OAAO,KAAK,OAAO,EAAE,SAAS,GAAG;AAC9C,gBAAU,IAAI,KAAK,UAAU,OAAO,CAAC;AAAA,IACvC;AAGA,QAAI,UAAU,WAAW,UAAU,SAAS;AAC1C,cAAQ,MAAM,MAAM;AACpB,UAAI,OAAO,OAAO;AAChB,gBAAQ,MAAM,MAAM,KAAK;AAAA,MAC3B;AAAA,IACF,WAAW,UAAU,QAAQ;AAC3B,cAAQ,KAAK,MAAM;AAAA,IACrB,WAAW,UAAU,WAAW,UAAU,SAAS;AACjD,cAAQ,MAAM,MAAM;AAAA,IACtB,OAAO;AACL,cAAQ,IAAI,MAAM;AAAA,IACpB;AAAA,EACF;AACF;;;AC9EO,IAAM,WAAW;AAAA,EACtB,OAAO;AAAA,EACP,OAAO;AAAA,EACP,MAAM;AAAA,EACN,MAAM;AAAA,EACN,OAAO;AAAA,EACP,OAAO;AAAA,EACP,QAAQ;AACV;AAiEA,SAAS,aACP,KACA,QACyB;AACzB,QAAM,SAAS,EAAE,GAAG,IAAI;AACxB,aAAW,SAAS,QAAQ;AAC1B,QAAI,SAAS,QAAQ;AACnB,aAAO,KAAK,IAAI;AAAA,IAClB;AAEA,UAAM,QAAQ,MAAM,MAAM,GAAG;AAC7B,QAAI,MAAM,SAAS,GAAG;AACpB,UAAI,UAA+C;AACnD,eAAS,IAAI,GAAG,IAAI,MAAM,SAAS,GAAG,KAAK;AACzC,cAAM,OAAO,MAAM,CAAC;AACpB,YAAI,QAAQ,WAAW,OAAO,YAAY,YAAY,QAAQ,SAAS;AACrE,gBAAM,MAAM,QAAQ,IAAI;AACxB,cAAI,OAAO,OAAO,QAAQ,UAAU;AAClC,sBAAU;AAAA,UACZ,OAAO;AACL,sBAAU;AACV;AAAA,UACF;AAAA,QACF,OAAO;AACL,oBAAU;AACV;AAAA,QACF;AAAA,MACF;AACA,YAAM,WAAW,MAAM,MAAM,SAAS,CAAC;AACvC,UAAI,YAAY,WAAW,OAAO,YAAY,YAAY,YAAY,SAAS;AAC7E,gBAAQ,QAAQ,IAAI;AAAA,MACtB;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAKA,IAAM,wBAAwB;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAaO,IAAM,SAAN,MAAM,QAAO;AAAA,EACV;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAER,YAAY,SAAgC,CAAC,GAAG;AAC9C,UAAM,YAAY,OAAO,SAAU,OAAO,WAAW,KAAkC;AACvF,SAAK,QAAQ,SAAS,SAAS,KAAK,SAAS;AAC7C,SAAK,OAAO,OAAO;AACnB,SAAK,UAAU,OAAO,WAAW,CAAC;AAClC,SAAK,aAAa,OAAO,cAAc;AAAA,MACrC,IAAI;AAAA,QACF,OAAO,WAAW,SAAY,EAAE,QAAQ,OAAO,OAAO,IAAI,CAAC;AAAA,MAC7D;AAAA,IACF;AACA,SAAK,eAAe,CAAC,GAAG,uBAAuB,GAAI,OAAO,UAAU,CAAC,CAAE;AAEvE,QAAI,OAAO,cAAc,OAAO;AAC9B,WAAK,cAAc,MAAM;AAAA,IAC3B,WAAW,OAAO,OAAO,cAAc,YAAY;AACjD,WAAK,cAAc,OAAO;AAAA,IAC5B,OAAO;AACL,WAAK,cAAc,OAAM,oBAAI,KAAK,GAAE,YAAY;AAAA,IAClD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SAA0C;AAC9C,UAAM,aAAa,OAAO,QAAQ,QAAQ,EAAE,KAAK,CAAC,CAAC,GAAG,CAAC,MAAM,MAAM,KAAK,KAAK;AAC7E,UAAM,YAAY,aAAc,WAAW,CAAC,IAAqB;AAEjE,UAAM,QAAQ,IAAI,QAAO;AAAA,MACvB,OAAO;AAAA,MACP,MAAM,KAAK;AAAA,MACX,SAAS,EAAE,GAAG,KAAK,SAAS,GAAG,QAAQ;AAAA,MACvC,YAAY,KAAK;AAAA,MACjB,QAAQ,KAAK;AAAA,IACf,CAAC;AACD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,IACN,OACA,SACA,SACA,OACM;AACN,UAAM,aAAa,SAAS,KAAK;AACjC,QAAI,aAAa,KAAK,MAAO;AAE7B,QAAI,eAAe,EAAE,GAAG,KAAK,QAAQ;AACrC,QAAI,KAAK,MAAM;AACb,mBAAa,QAAQ,IAAI,KAAK;AAAA,IAChC;AACA,QAAI,SAAS;AACX,qBAAe,EAAE,GAAG,cAAc,GAAG,QAAQ;AAAA,IAC/C;AAGA,mBAAe,aAAa,cAAc,KAAK,YAAY;AAE3D,UAAM,QAAkB;AAAA,MACtB;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAW,KAAK,YAAY;AAAA,MAC5B,SAAS,OAAO,KAAK,YAAY,EAAE,SAAS,IAAI,eAAe;AAAA,MAC/D,OAAO,QACH;AAAA,QACE,MAAM,MAAM;AAAA,QACZ,SAAS,MAAM;AAAA,QACf,OAAO,MAAM;AAAA,MACf,IACA;AAAA,IACN;AAEA,eAAW,aAAa,KAAK,YAAY;AACvC,gBAAU,IAAI,KAAK;AAAA,IACrB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,SAAiB,SAAyC;AAC9D,SAAK,IAAI,SAAS,SAAS,OAAO;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,SAAiB,SAAyC;AAC9D,SAAK,IAAI,SAAS,SAAS,OAAO;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,KAAK,SAAiB,SAAyC;AAC7D,SAAK,IAAI,QAAQ,SAAS,OAAO;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,KAAK,SAAiB,SAAyC;AAC7D,SAAK,IAAI,QAAQ,SAAS,OAAO;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,SAAiB,OAAyB,SAAyC;AACvF,UAAM,MAAM,iBAAiB,QAAQ,QAAQ;AAC7C,UAAM,MAAM,iBAAiB,QAAQ,UAAW;AAChD,SAAK,IAAI,SAAS,SAAS,KAAK,GAAG;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,SAAiB,OAAyB,SAAyC;AACvF,UAAM,MAAM,iBAAiB,QAAQ,QAAQ;AAC7C,UAAM,MAAM,iBAAiB,QAAQ,UAAW;AAChD,SAAK,IAAI,SAAS,SAAS,KAAK,GAAG;AAAA,EACrC;AACF;AAiBO,SAAS,aAAa,QAAwC;AACnE,SAAO,IAAI,OAAO,MAAM;AAC1B;AAMO,IAAM,SAAS,aAAa;AAoB5B,SAAS,SACd,KACA,OACA,SACA,SACM;AACN,MAAI,iBAAiB,OAAO;AAC1B,QAAI,MAAM,SAAS,OAAO,OAAO;AAAA,EACnC,OAAO;AACL,QAAI,MAAM,SAAS,EAAE,OAAO,OAAO,KAAK,GAAG,GAAG,QAAQ,CAAC;AAAA,EACzD;AACF;AAmBA,eAAsB,YACpB,KACA,WACA,IACY;AACZ,QAAM,QAAQ,KAAK,IAAI;AACvB,MAAI;AACF,UAAM,SAAS,MAAM,GAAG;AACxB,UAAM,WAAW,KAAK,IAAI,IAAI;AAC9B,QAAI,KAAK,GAAG,SAAS,cAAc,EAAE,WAAW,YAAY,SAAS,CAAC;AACtE,WAAO;AAAA,EACT,SAAS,OAAO;AACd,UAAM,WAAW,KAAK,IAAI,IAAI;AAC9B,aAAS,KAAK,OAAO,GAAG,SAAS,WAAW,EAAE,WAAW,YAAY,SAAS,CAAC;AAC/E,UAAM;AAAA,EACR;AACF;AAsBO,SAAS,oBACd,YACA,SAOQ;AACR,QAAM,WAAW,QAAQ,MAAM,IAAI,IAAI,QAAQ,GAAG,EAAE,WAAW;AAC/D,SAAO,WAAW,MAAM;AAAA,IACtB,WAAW,QAAQ;AAAA,IACnB,QAAQ,QAAQ;AAAA,IAChB,MAAM;AAAA,IACN,QAAQ,QAAQ;AAAA,IAChB,UAAU,QAAQ;AAAA,EACpB,CAAC;AACH;","names":[]}
|
|
@@ -1,10 +1,27 @@
|
|
|
1
|
-
import { h as LogTransport, p as BatchTransportOptions, g as LogEntry, E as ErrorTransport, o as BaseTransportOptions, k as ErrorContext, n as ErrorUser, B as Breadcrumb } from '../logger-
|
|
2
|
-
export { j as CombinedTransport, C as ConsoleTransport, q as ConsoleTransportOptions } from '../logger-
|
|
1
|
+
import { h as LogTransport, p as BatchTransportOptions, g as LogEntry, E as ErrorTransport, o as BaseTransportOptions, k as ErrorContext, n as ErrorUser, B as Breadcrumb } from '../logger-DrxxwI7C.js';
|
|
2
|
+
export { j as CombinedTransport, C as ConsoleTransport, q as ConsoleTransportOptions } from '../logger-DrxxwI7C.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* @parsrun/core - Axiom Transport
|
|
6
|
-
*
|
|
7
|
-
*
|
|
6
|
+
*
|
|
7
|
+
* Log ingestion transport for Axiom (axiom.co).
|
|
8
|
+
* Uses native fetch - works on all runtimes (Node, Deno, Bun, Workers).
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* import { createLogger, AxiomTransport } from '@parsrun/core';
|
|
13
|
+
*
|
|
14
|
+
* const axiom = new AxiomTransport({
|
|
15
|
+
* token: process.env.AXIOM_TOKEN!,
|
|
16
|
+
* dataset: 'my-app-logs',
|
|
17
|
+
* batchSize: 100, // Send every 100 logs
|
|
18
|
+
* flushInterval: 5000, // Or every 5 seconds
|
|
19
|
+
* });
|
|
20
|
+
*
|
|
21
|
+
* const logger = createLogger({
|
|
22
|
+
* transports: [axiom]
|
|
23
|
+
* });
|
|
24
|
+
* ```
|
|
8
25
|
*/
|
|
9
26
|
|
|
10
27
|
/**
|
|
@@ -38,7 +55,18 @@ declare class AxiomTransport implements LogTransport {
|
|
|
38
55
|
close(): Promise<void>;
|
|
39
56
|
}
|
|
40
57
|
/**
|
|
41
|
-
* Create Axiom transport
|
|
58
|
+
* Create an Axiom transport instance.
|
|
59
|
+
*
|
|
60
|
+
* @param options - Axiom transport configuration
|
|
61
|
+
* @returns A new AxiomTransport instance
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```typescript
|
|
65
|
+
* const axiom = createAxiomTransport({
|
|
66
|
+
* token: 'xaat-xxx',
|
|
67
|
+
* dataset: 'logs'
|
|
68
|
+
* });
|
|
69
|
+
* ```
|
|
42
70
|
*/
|
|
43
71
|
declare function createAxiomTransport(options: AxiomTransportOptions): AxiomTransport;
|
|
44
72
|
|
|
@@ -248,7 +276,18 @@ declare class SentryTransport implements LogTransport, ErrorTransport {
|
|
|
248
276
|
private sendHttpEvent;
|
|
249
277
|
}
|
|
250
278
|
/**
|
|
251
|
-
* Create Sentry transport
|
|
279
|
+
* Create a Sentry transport instance.
|
|
280
|
+
*
|
|
281
|
+
* @param options - Sentry transport configuration
|
|
282
|
+
* @returns A new SentryTransport instance
|
|
283
|
+
*
|
|
284
|
+
* @example
|
|
285
|
+
* ```typescript
|
|
286
|
+
* const sentry = createSentryTransport({
|
|
287
|
+
* dsn: 'https://xxx@sentry.io/123',
|
|
288
|
+
* environment: 'production'
|
|
289
|
+
* });
|
|
290
|
+
* ```
|
|
252
291
|
*/
|
|
253
292
|
declare function createSentryTransport(options: SentryTransportOptions): SentryTransport;
|
|
254
293
|
|
|
@@ -340,7 +379,19 @@ declare class LogtapeTransport implements LogTransport {
|
|
|
340
379
|
private buildProperties;
|
|
341
380
|
}
|
|
342
381
|
/**
|
|
343
|
-
* Create Logtape transport
|
|
382
|
+
* Create a Logtape transport instance.
|
|
383
|
+
*
|
|
384
|
+
* @param options - Logtape transport configuration
|
|
385
|
+
* @returns A new LogtapeTransport instance
|
|
386
|
+
*
|
|
387
|
+
* @example
|
|
388
|
+
* ```typescript
|
|
389
|
+
* import { getLogger } from '@logtape/logtape';
|
|
390
|
+
*
|
|
391
|
+
* const transport = createLogtapeTransport({
|
|
392
|
+
* logger: getLogger('my-app')
|
|
393
|
+
* });
|
|
394
|
+
* ```
|
|
344
395
|
*/
|
|
345
396
|
declare function createLogtapeTransport(options?: LogtapeTransportOptions): LogtapeTransport;
|
|
346
397
|
|