@fend/firo 0.0.1

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/index.cjs ADDED
@@ -0,0 +1,352 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ FIRO_COLORS: () => FIRO_COLORS,
34
+ createDevTransport: () => createDevTransport,
35
+ createJsonTransport: () => createJsonTransport,
36
+ createLogger: () => createLogger
37
+ });
38
+ module.exports = __toCommonJS(index_exports);
39
+
40
+ // src/utils.ts
41
+ var LOG_LEVELS = {
42
+ debug: 20,
43
+ info: 30,
44
+ warn: 40,
45
+ error: 50
46
+ };
47
+ var FIRO_COLORS = {
48
+ // Basic ANSI (safe for any terminal)
49
+ cyan: "36",
50
+ green: "32",
51
+ yellow: "33",
52
+ magenta: "35",
53
+ blue: "34",
54
+ brightCyan: "96",
55
+ brightGreen: "92",
56
+ brightYellow: "93",
57
+ brightMagenta: "95",
58
+ brightBlue: "94",
59
+ // Extended 256-color palette
60
+ orange: "38;5;214",
61
+ pink: "38;5;213",
62
+ lilac: "38;5;141",
63
+ skyBlue: "38;5;117",
64
+ mint: "38;5;156",
65
+ salmon: "38;5;210",
66
+ lemon: "38;5;228",
67
+ lavender: "38;5;183",
68
+ sage: "38;5;114",
69
+ coral: "38;5;209",
70
+ teal: "38;5;116",
71
+ rose: "38;5;219",
72
+ pistachio: "38;5;150",
73
+ mauve: "38;5;175",
74
+ aqua: "38;5;81",
75
+ gold: "38;5;222",
76
+ thistle: "38;5;182",
77
+ seafoam: "38;5;115",
78
+ tangerine: "38;5;208",
79
+ periwinkle: "38;5;147"
80
+ };
81
+ var COLORS_LIST = Object.values(FIRO_COLORS);
82
+ var SAFE_COLORS_COUNT = 10;
83
+ var getColorIndex = (str, useAllColors = false) => {
84
+ let hash = 0;
85
+ str.split("").forEach((char) => {
86
+ hash = char.charCodeAt(0) + ((hash << 5) - hash);
87
+ });
88
+ const range = useAllColors ? COLORS_LIST.length : SAFE_COLORS_COUNT;
89
+ return Math.abs(hash % range);
90
+ };
91
+ var colorize = (text, colorIndex, color) => {
92
+ const code = color ?? (COLORS_LIST[colorIndex] || COLORS_LIST[colorIndex % SAFE_COLORS_COUNT]);
93
+ return `\x1B[${code}m${text}\x1B[0m`;
94
+ };
95
+ var colorizeLevel = (level, text) => {
96
+ if (level === "info") return text;
97
+ switch (level) {
98
+ case "error":
99
+ return `\x1B[31m${text}\x1B[0m`;
100
+ // Red
101
+ case "warn":
102
+ return `\x1B[33m${text}\x1B[0m`;
103
+ // Yellow
104
+ case "debug":
105
+ return `\x1B[2m${text}\x1B[0m`;
106
+ // Dim
107
+ default:
108
+ return text;
109
+ }
110
+ };
111
+
112
+ // src/transports.ts
113
+ var import_node_util = require("util");
114
+ var import_node_process = __toESM(require("process"), 1);
115
+ var import_node_fs = __toESM(require("fs"), 1);
116
+ var createDevTransport = (config = {}) => {
117
+ const locale = config.locale ?? void 0;
118
+ const timeOpts = {
119
+ hour12: false,
120
+ hour: "2-digit",
121
+ minute: "2-digit",
122
+ second: "2-digit",
123
+ fractionalSecondDigits: 3,
124
+ ...config.timeOptions || {}
125
+ };
126
+ const transport = (level, context, msg, data, opts) => {
127
+ const now = /* @__PURE__ */ new Date();
128
+ const timestamp = now.toLocaleTimeString(locale, timeOpts);
129
+ const contextStr = context.map((ctx) => {
130
+ const key = ctx.options?.omitKey ? "" : `${ctx.key}:`;
131
+ const content = `${key}${ctx.value}`;
132
+ return colorize(`[${content}]`, ctx.options.colorIndex, ctx.options.color);
133
+ }).join(" ");
134
+ if (level === "error" && data === void 0) {
135
+ const realError = wrapToError(msg);
136
+ data = realError;
137
+ msg = realError.message;
138
+ }
139
+ let dataStr = "";
140
+ if (data !== void 0) {
141
+ const inspectOptions = opts?.pretty ? { compact: false, colors: true, depth: null } : { compact: true, breakLength: Infinity, colors: true, depth: null };
142
+ dataStr = (0, import_node_util.inspect)(data, inspectOptions);
143
+ }
144
+ const msgStr = typeof msg === "object" && msg !== null ? (0, import_node_util.inspect)(msg, { colors: true, compact: true, breakLength: Infinity }) : String(msg);
145
+ const parts = [
146
+ `[${timestamp}]`,
147
+ // Normal (not dimmed)
148
+ contextStr,
149
+ level === "error" ? colorizeLevel("error", `[ERROR] ${msgStr}`) : level === "warn" ? colorizeLevel("warn", `[WARN] ${msgStr}`) : level === "debug" ? colorizeLevel("debug", msgStr) : msgStr,
150
+ level === "debug" && dataStr ? `\x1B[2m${dataStr.replace(/\x1b\[0m/g, "\x1B[0m\x1B[2m")}\x1B[0m` : dataStr
151
+ ];
152
+ let finalLine = parts.filter(Boolean).join(" ") + "\n";
153
+ if (level === "error") import_node_process.default.stderr.write(finalLine);
154
+ else import_node_process.default.stdout.write(finalLine);
155
+ };
156
+ return transport;
157
+ };
158
+ var safeStringify = (obj) => {
159
+ try {
160
+ return JSON.stringify(obj);
161
+ } catch {
162
+ return (0, import_node_util.inspect)(obj);
163
+ }
164
+ };
165
+ var wrapToError = (obj) => {
166
+ if (obj instanceof Error) return obj;
167
+ return new Error(
168
+ typeof obj === "object" && obj !== null ? safeStringify(obj) : String(obj)
169
+ );
170
+ };
171
+ var serializeError = (_err) => {
172
+ const err = wrapToError(_err);
173
+ return {
174
+ message: err.message,
175
+ stack: err.stack,
176
+ name: err.name,
177
+ ...err
178
+ };
179
+ };
180
+ var buildRecord = (level, context, msg, data) => {
181
+ const contextObj = context.reduce((acc, item) => {
182
+ acc[item.key] = item.value;
183
+ return acc;
184
+ }, {});
185
+ const logRecord = {
186
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
187
+ level,
188
+ ...contextObj
189
+ };
190
+ if (level === "error") {
191
+ const message = typeof msg === "string" ? msg : msg instanceof Error ? msg.message : typeof msg === "object" && msg !== null ? safeStringify(msg) : String(msg);
192
+ logRecord.message = message;
193
+ if (data instanceof Error) {
194
+ logRecord.error = serializeError(data);
195
+ } else if (msg instanceof Error) {
196
+ logRecord.error = serializeError(msg);
197
+ if (data !== void 0) logRecord.data = data;
198
+ } else {
199
+ logRecord.error = serializeError(msg);
200
+ if (data !== void 0) logRecord.data = data;
201
+ }
202
+ } else {
203
+ logRecord.message = typeof msg === "object" && msg !== null ? safeStringify(msg) : String(msg);
204
+ if (data !== void 0) {
205
+ logRecord.data = data instanceof Error ? serializeError(data) : data;
206
+ }
207
+ }
208
+ return logRecord;
209
+ };
210
+ var createJsonTransport = (config = {}) => {
211
+ const queue = [];
212
+ const maxQueueSize = config.maxQueueSize ?? 1e3;
213
+ let isDraining = false;
214
+ const flush = () => {
215
+ if (queue.length === 0 || isDraining) return;
216
+ while (queue.length > 0) {
217
+ const line = queue.shift();
218
+ const ok = import_node_process.default.stdout.write(line);
219
+ if (!ok) {
220
+ isDraining = true;
221
+ import_node_process.default.stdout.once("drain", () => {
222
+ isDraining = false;
223
+ flush();
224
+ });
225
+ return;
226
+ }
227
+ }
228
+ };
229
+ const flushSync = () => {
230
+ while (queue.length > 0) {
231
+ const line = queue.shift();
232
+ if (line) {
233
+ try {
234
+ import_node_fs.default.writeSync(1, line);
235
+ } catch {
236
+ }
237
+ }
238
+ }
239
+ };
240
+ if (config.async) {
241
+ import_node_process.default.on("beforeExit", flushSync);
242
+ import_node_process.default.on("exit", flushSync);
243
+ }
244
+ return (level, context, msg, data) => {
245
+ const record = buildRecord(level, context, msg, data);
246
+ let line;
247
+ try {
248
+ line = JSON.stringify(record) + "\n";
249
+ } catch {
250
+ if (record.data) record.data = (0, import_node_util.inspect)(record.data);
251
+ try {
252
+ line = JSON.stringify(record) + "\n";
253
+ } catch {
254
+ line = JSON.stringify({
255
+ timestamp: record.timestamp,
256
+ level,
257
+ message: record.message,
258
+ error: "Failed to serialize log record"
259
+ }) + "\n";
260
+ }
261
+ }
262
+ if (!config.async) {
263
+ import_node_process.default.stdout.write(line);
264
+ return;
265
+ }
266
+ queue.push(line);
267
+ if (queue.length > maxQueueSize) {
268
+ queue.shift();
269
+ }
270
+ flush();
271
+ };
272
+ };
273
+
274
+ // src/index.ts
275
+ var fillContextItem = (item, useAllColors = false) => {
276
+ return {
277
+ ...item,
278
+ options: {
279
+ colorIndex: item.options && typeof item.options.colorIndex === "number" ? item.options.colorIndex : getColorIndex(item.key, useAllColors),
280
+ color: item.options?.color,
281
+ omitKey: item.options?.omitKey ?? false
282
+ }
283
+ };
284
+ };
285
+ var createLoggerInternal = (config, parentContext) => {
286
+ const useAllColors = config.useAllColors ?? false;
287
+ const fill = (item) => fillContextItem(item, useAllColors);
288
+ const appendContextWithInvokeContext = (context2, invokeContext) => {
289
+ if (!invokeContext || invokeContext.length === 0) return context2;
290
+ return [...context2, ...invokeContext.map(fill)];
291
+ };
292
+ const context = [...parentContext.map(fill)];
293
+ const transport = config.transport ?? (config.mode === "prod" ? createJsonTransport({ async: config.async }) : createDevTransport(config.devTransportConfig));
294
+ const minLevelName = config.mode === "prod" ? config.minLevelInProd ?? config.minLevel : config.minLevelInDev ?? config.minLevel;
295
+ const minLevel = LOG_LEVELS[minLevelName ?? "debug"];
296
+ const getContext = () => context;
297
+ const addContext = (key, value, options) => {
298
+ let item = typeof key === "string" ? { key, value, options } : key;
299
+ context.push(fill(item));
300
+ };
301
+ const removeKeyFromContext = (key) => {
302
+ const index = context.findIndex((ctx) => ctx.key === key);
303
+ if (index !== -1) context.splice(index, 1);
304
+ };
305
+ const child = (ctx) => {
306
+ const newItems = Object.entries(ctx).map(([key, value]) => ({
307
+ key,
308
+ value,
309
+ options: { colorIndex: getColorIndex(key, useAllColors) }
310
+ }));
311
+ return createLoggerInternal({ transport, minLevel: minLevelName, useAllColors }, [...context, ...newItems]);
312
+ };
313
+ const debug = (msg, data, opts) => {
314
+ if (minLevel > LOG_LEVELS.debug) return;
315
+ transport("debug", appendContextWithInvokeContext(context, opts?.ctx), msg, data, opts);
316
+ };
317
+ const info = (msg, data, opts) => {
318
+ if (minLevel > LOG_LEVELS.info) return;
319
+ transport("info", appendContextWithInvokeContext(context, opts?.ctx), msg, data, opts);
320
+ };
321
+ const warn = (msg, data, opts) => {
322
+ if (minLevel > LOG_LEVELS.warn) return;
323
+ transport("warn", appendContextWithInvokeContext(context, opts?.ctx), msg, data, opts);
324
+ };
325
+ const error = (msgOrError, err, opts) => {
326
+ if (minLevel > LOG_LEVELS.error) return;
327
+ transport("error", appendContextWithInvokeContext(context, opts?.ctx), msgOrError, err, opts);
328
+ };
329
+ const logInstance = ((msg, data, opts) => {
330
+ info(msg, data, opts);
331
+ });
332
+ return Object.assign(logInstance, {
333
+ debug,
334
+ info,
335
+ warn,
336
+ error,
337
+ child,
338
+ addContext,
339
+ getContext,
340
+ removeFromContext: removeKeyFromContext
341
+ });
342
+ };
343
+ var createLogger = (config = {}) => {
344
+ return createLoggerInternal(config, []);
345
+ };
346
+ // Annotate the CommonJS export names for ESM import in node:
347
+ 0 && (module.exports = {
348
+ FIRO_COLORS,
349
+ createDevTransport,
350
+ createJsonTransport,
351
+ createLogger
352
+ });
@@ -0,0 +1,166 @@
1
+ /** Available log severity levels. */
2
+ type LogLevel = 'debug' | 'info' | 'warn' | 'error';
3
+ /** Primitive types allowed as context values. */
4
+ type ContextValue = string | number | boolean | null | undefined;
5
+ /** Options to customize how a context item is rendered. */
6
+ type ContextOptions = {
7
+ /** Color index: 0-9 for safe terminal colors (used by auto-hash), 10+ for extended 256-color palette. */
8
+ colorIndex?: number;
9
+ /** Raw ANSI color code string (e.g. '36', '38;5;214', '38;2;255;100;0'). Takes priority over colorIndex. */
10
+ color?: string;
11
+ /** If true, the key name is hidden, and only the value is printed. */
12
+ omitKey?: boolean;
13
+ };
14
+ /** A single key-value context entry. */
15
+ type ContextItem = {
16
+ key: string;
17
+ value: ContextValue;
18
+ options?: ContextOptions;
19
+ };
20
+ /** A context entry where options have been fully resolved with defaults. */
21
+ type ContextItemWithOptions = ContextItem & {
22
+ options: Required<Pick<ContextOptions, 'colorIndex' | 'omitKey'>> & Pick<ContextOptions, 'color'>;
23
+ };
24
+ /** Options that can be passed to a single log call. */
25
+ type LogOptions = {
26
+ /** If true, stringifies objects with indentation and line breaks. */
27
+ pretty?: boolean;
28
+ /** Additional inline context items applied only to this log call. */
29
+ ctx?: ContextItem[];
30
+ };
31
+ /** The signature of a function responsible for formatting and emitting log records. */
32
+ type TransportFn = (level: LogLevel, context: ContextItemWithOptions[], message: string | Error | unknown, data?: Error | unknown, options?: LogOptions) => void;
33
+ /** Named color palette for context badges. Use with `color` option: `{ color: FIRO_COLORS.skyBlue }` */
34
+ declare const FIRO_COLORS: {
35
+ readonly cyan: "36";
36
+ readonly green: "32";
37
+ readonly yellow: "33";
38
+ readonly magenta: "35";
39
+ readonly blue: "34";
40
+ readonly brightCyan: "96";
41
+ readonly brightGreen: "92";
42
+ readonly brightYellow: "93";
43
+ readonly brightMagenta: "95";
44
+ readonly brightBlue: "94";
45
+ readonly orange: "38;5;214";
46
+ readonly pink: "38;5;213";
47
+ readonly lilac: "38;5;141";
48
+ readonly skyBlue: "38;5;117";
49
+ readonly mint: "38;5;156";
50
+ readonly salmon: "38;5;210";
51
+ readonly lemon: "38;5;228";
52
+ readonly lavender: "38;5;183";
53
+ readonly sage: "38;5;114";
54
+ readonly coral: "38;5;209";
55
+ readonly teal: "38;5;116";
56
+ readonly rose: "38;5;219";
57
+ readonly pistachio: "38;5;150";
58
+ readonly mauve: "38;5;175";
59
+ readonly aqua: "38;5;81";
60
+ readonly gold: "38;5;222";
61
+ readonly thistle: "38;5;182";
62
+ readonly seafoam: "38;5;115";
63
+ readonly tangerine: "38;5;208";
64
+ readonly periwinkle: "38;5;147";
65
+ };
66
+
67
+ /**
68
+ * Configuration options for the development transport.
69
+ */
70
+ type DevTransportConfig = {
71
+ /** The locale used for formatting the timestamp. Defaults to the system locale. */
72
+ locale?: string;
73
+ /** Standard Intl.DateTimeFormatOptions to customize the timestamp output. */
74
+ timeOptions?: Intl.DateTimeFormatOptions;
75
+ };
76
+ /**
77
+ * Creates a built-in transport optimized for local development.
78
+ * Emits colored, human-readable strings to stdout/stderr.
79
+ *
80
+ * @param config Optional configuration for the transport, like timestamp formats.
81
+ * @returns A `TransportFn` that writes to the console.
82
+ */
83
+ declare const createDevTransport: (config?: DevTransportConfig) => TransportFn;
84
+ /**
85
+ * Configuration for the JSON transport.
86
+ */
87
+ type JsonTransportConfig = {
88
+ /**
89
+ * Enable asynchronous/buffered output.
90
+ * When true, logs are queued and written when the stream is ready (handling backpressure).
91
+ */
92
+ async?: boolean;
93
+ /** Maximum number of log lines to buffer when async is enabled. Defaults to 1000. */
94
+ maxQueueSize?: number;
95
+ };
96
+ /**
97
+ * Creates a built-in transport optimized for production.
98
+ * Emits strictly structured NDJSON (Newline Delimited JSON) to stdout.
99
+ *
100
+ * @param config Optional configuration for async and buffering behavior.
101
+ * @returns A `TransportFn` that writes JSON to standard output.
102
+ */
103
+ declare const createJsonTransport: (config?: JsonTransportConfig) => TransportFn;
104
+
105
+ /**
106
+ * Configuration options for creating a logger instance.
107
+ */
108
+ type LoggerConfig = {
109
+ /** The minimum log level for both modes. Overridden by mode-specific thresholds. */
110
+ minLevel?: LogLevel;
111
+ /** Minimum log level to emit in 'dev' mode. */
112
+ minLevelInDev?: LogLevel;
113
+ /** Minimum log level to emit in 'prod' mode. */
114
+ minLevelInProd?: LogLevel;
115
+ /** Specifies the built-in transport to use. Defaults to 'dev'. */
116
+ mode?: 'dev' | 'prod';
117
+ /** Provide a custom transport function to override the built-in behaviors. */
118
+ transport?: TransportFn;
119
+ /** Options for fine-tuning the built-in development transport (e.g. timestamp format). */
120
+ devTransportConfig?: DevTransportConfig;
121
+ /** Enable asynchronous/buffered output for 'prod' mode to avoid event loop blocking. */
122
+ async?: boolean;
123
+ /** Use the full extended color palette (30 colors including 256-color) for auto-assigned context badges. Defaults to false (safe 10-color palette). */
124
+ useAllColors?: boolean;
125
+ };
126
+ /**
127
+ * The logger instance returned by `createLogger`.
128
+ * It is a callable object: calling `log(msg)` is shorthand for `log.info(msg)`.
129
+ */
130
+ interface ILogger {
131
+ /** Shorthand for log.info() */
132
+ (msg: string, data?: unknown, opts?: LogOptions): void;
133
+ /** Log a debug message (dimmed in dev mode). */
134
+ debug: (msg: string, data?: unknown, opts?: LogOptions) => void;
135
+ /** Log an informational message. */
136
+ info: (msg: string, data?: unknown, opts?: LogOptions) => void;
137
+ /** Log a warning message. */
138
+ warn: (msg: string, data?: unknown, opts?: LogOptions) => void;
139
+ /** Log an error object directly. */
140
+ error(err: Error | unknown): void;
141
+ /** Log a message alongside an error or custom data object. */
142
+ error(msg: string, err?: Error | unknown, opts?: LogOptions): void;
143
+ /**
144
+ * Create a scoped child logger that inherits the current logger's context.
145
+ * @param ctx An object containing key-value pairs to add to the child logger's context.
146
+ */
147
+ child: (ctx: Record<string, ContextValue>) => ILogger;
148
+ /** Add a context entry by key and value. */
149
+ addContext(key: string, value: ContextValue, opts?: ContextOptions): void;
150
+ /** Add a context entry using the object form. */
151
+ addContext(item: ContextItem): void;
152
+ /** Remove a context entry by its key. */
153
+ removeFromContext(key: string): void;
154
+ /** Return the current context array attached to this logger instance. */
155
+ getContext(): ContextItem[];
156
+ }
157
+
158
+ /**
159
+ * Creates a new logger instance with the specified configuration.
160
+ *
161
+ * @param config Optional configuration for log levels, mode, and transports.
162
+ * @returns A fully configured `ILogger` instance.
163
+ */
164
+ declare const createLogger: (config?: LoggerConfig) => ILogger;
165
+
166
+ export { type ContextItem, type ContextItemWithOptions, type ContextOptions, type ContextValue, type DevTransportConfig, FIRO_COLORS, type ILogger, type JsonTransportConfig, type LogLevel, type LogOptions, type LoggerConfig, type TransportFn, createDevTransport, createJsonTransport, createLogger };
@@ -0,0 +1,166 @@
1
+ /** Available log severity levels. */
2
+ type LogLevel = 'debug' | 'info' | 'warn' | 'error';
3
+ /** Primitive types allowed as context values. */
4
+ type ContextValue = string | number | boolean | null | undefined;
5
+ /** Options to customize how a context item is rendered. */
6
+ type ContextOptions = {
7
+ /** Color index: 0-9 for safe terminal colors (used by auto-hash), 10+ for extended 256-color palette. */
8
+ colorIndex?: number;
9
+ /** Raw ANSI color code string (e.g. '36', '38;5;214', '38;2;255;100;0'). Takes priority over colorIndex. */
10
+ color?: string;
11
+ /** If true, the key name is hidden, and only the value is printed. */
12
+ omitKey?: boolean;
13
+ };
14
+ /** A single key-value context entry. */
15
+ type ContextItem = {
16
+ key: string;
17
+ value: ContextValue;
18
+ options?: ContextOptions;
19
+ };
20
+ /** A context entry where options have been fully resolved with defaults. */
21
+ type ContextItemWithOptions = ContextItem & {
22
+ options: Required<Pick<ContextOptions, 'colorIndex' | 'omitKey'>> & Pick<ContextOptions, 'color'>;
23
+ };
24
+ /** Options that can be passed to a single log call. */
25
+ type LogOptions = {
26
+ /** If true, stringifies objects with indentation and line breaks. */
27
+ pretty?: boolean;
28
+ /** Additional inline context items applied only to this log call. */
29
+ ctx?: ContextItem[];
30
+ };
31
+ /** The signature of a function responsible for formatting and emitting log records. */
32
+ type TransportFn = (level: LogLevel, context: ContextItemWithOptions[], message: string | Error | unknown, data?: Error | unknown, options?: LogOptions) => void;
33
+ /** Named color palette for context badges. Use with `color` option: `{ color: FIRO_COLORS.skyBlue }` */
34
+ declare const FIRO_COLORS: {
35
+ readonly cyan: "36";
36
+ readonly green: "32";
37
+ readonly yellow: "33";
38
+ readonly magenta: "35";
39
+ readonly blue: "34";
40
+ readonly brightCyan: "96";
41
+ readonly brightGreen: "92";
42
+ readonly brightYellow: "93";
43
+ readonly brightMagenta: "95";
44
+ readonly brightBlue: "94";
45
+ readonly orange: "38;5;214";
46
+ readonly pink: "38;5;213";
47
+ readonly lilac: "38;5;141";
48
+ readonly skyBlue: "38;5;117";
49
+ readonly mint: "38;5;156";
50
+ readonly salmon: "38;5;210";
51
+ readonly lemon: "38;5;228";
52
+ readonly lavender: "38;5;183";
53
+ readonly sage: "38;5;114";
54
+ readonly coral: "38;5;209";
55
+ readonly teal: "38;5;116";
56
+ readonly rose: "38;5;219";
57
+ readonly pistachio: "38;5;150";
58
+ readonly mauve: "38;5;175";
59
+ readonly aqua: "38;5;81";
60
+ readonly gold: "38;5;222";
61
+ readonly thistle: "38;5;182";
62
+ readonly seafoam: "38;5;115";
63
+ readonly tangerine: "38;5;208";
64
+ readonly periwinkle: "38;5;147";
65
+ };
66
+
67
+ /**
68
+ * Configuration options for the development transport.
69
+ */
70
+ type DevTransportConfig = {
71
+ /** The locale used for formatting the timestamp. Defaults to the system locale. */
72
+ locale?: string;
73
+ /** Standard Intl.DateTimeFormatOptions to customize the timestamp output. */
74
+ timeOptions?: Intl.DateTimeFormatOptions;
75
+ };
76
+ /**
77
+ * Creates a built-in transport optimized for local development.
78
+ * Emits colored, human-readable strings to stdout/stderr.
79
+ *
80
+ * @param config Optional configuration for the transport, like timestamp formats.
81
+ * @returns A `TransportFn` that writes to the console.
82
+ */
83
+ declare const createDevTransport: (config?: DevTransportConfig) => TransportFn;
84
+ /**
85
+ * Configuration for the JSON transport.
86
+ */
87
+ type JsonTransportConfig = {
88
+ /**
89
+ * Enable asynchronous/buffered output.
90
+ * When true, logs are queued and written when the stream is ready (handling backpressure).
91
+ */
92
+ async?: boolean;
93
+ /** Maximum number of log lines to buffer when async is enabled. Defaults to 1000. */
94
+ maxQueueSize?: number;
95
+ };
96
+ /**
97
+ * Creates a built-in transport optimized for production.
98
+ * Emits strictly structured NDJSON (Newline Delimited JSON) to stdout.
99
+ *
100
+ * @param config Optional configuration for async and buffering behavior.
101
+ * @returns A `TransportFn` that writes JSON to standard output.
102
+ */
103
+ declare const createJsonTransport: (config?: JsonTransportConfig) => TransportFn;
104
+
105
+ /**
106
+ * Configuration options for creating a logger instance.
107
+ */
108
+ type LoggerConfig = {
109
+ /** The minimum log level for both modes. Overridden by mode-specific thresholds. */
110
+ minLevel?: LogLevel;
111
+ /** Minimum log level to emit in 'dev' mode. */
112
+ minLevelInDev?: LogLevel;
113
+ /** Minimum log level to emit in 'prod' mode. */
114
+ minLevelInProd?: LogLevel;
115
+ /** Specifies the built-in transport to use. Defaults to 'dev'. */
116
+ mode?: 'dev' | 'prod';
117
+ /** Provide a custom transport function to override the built-in behaviors. */
118
+ transport?: TransportFn;
119
+ /** Options for fine-tuning the built-in development transport (e.g. timestamp format). */
120
+ devTransportConfig?: DevTransportConfig;
121
+ /** Enable asynchronous/buffered output for 'prod' mode to avoid event loop blocking. */
122
+ async?: boolean;
123
+ /** Use the full extended color palette (30 colors including 256-color) for auto-assigned context badges. Defaults to false (safe 10-color palette). */
124
+ useAllColors?: boolean;
125
+ };
126
+ /**
127
+ * The logger instance returned by `createLogger`.
128
+ * It is a callable object: calling `log(msg)` is shorthand for `log.info(msg)`.
129
+ */
130
+ interface ILogger {
131
+ /** Shorthand for log.info() */
132
+ (msg: string, data?: unknown, opts?: LogOptions): void;
133
+ /** Log a debug message (dimmed in dev mode). */
134
+ debug: (msg: string, data?: unknown, opts?: LogOptions) => void;
135
+ /** Log an informational message. */
136
+ info: (msg: string, data?: unknown, opts?: LogOptions) => void;
137
+ /** Log a warning message. */
138
+ warn: (msg: string, data?: unknown, opts?: LogOptions) => void;
139
+ /** Log an error object directly. */
140
+ error(err: Error | unknown): void;
141
+ /** Log a message alongside an error or custom data object. */
142
+ error(msg: string, err?: Error | unknown, opts?: LogOptions): void;
143
+ /**
144
+ * Create a scoped child logger that inherits the current logger's context.
145
+ * @param ctx An object containing key-value pairs to add to the child logger's context.
146
+ */
147
+ child: (ctx: Record<string, ContextValue>) => ILogger;
148
+ /** Add a context entry by key and value. */
149
+ addContext(key: string, value: ContextValue, opts?: ContextOptions): void;
150
+ /** Add a context entry using the object form. */
151
+ addContext(item: ContextItem): void;
152
+ /** Remove a context entry by its key. */
153
+ removeFromContext(key: string): void;
154
+ /** Return the current context array attached to this logger instance. */
155
+ getContext(): ContextItem[];
156
+ }
157
+
158
+ /**
159
+ * Creates a new logger instance with the specified configuration.
160
+ *
161
+ * @param config Optional configuration for log levels, mode, and transports.
162
+ * @returns A fully configured `ILogger` instance.
163
+ */
164
+ declare const createLogger: (config?: LoggerConfig) => ILogger;
165
+
166
+ export { type ContextItem, type ContextItemWithOptions, type ContextOptions, type ContextValue, type DevTransportConfig, FIRO_COLORS, type ILogger, type JsonTransportConfig, type LogLevel, type LogOptions, type LoggerConfig, type TransportFn, createDevTransport, createJsonTransport, createLogger };