@decaf-ts/logging 0.10.8 → 0.10.10

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/README.md CHANGED
@@ -8,6 +8,16 @@ Decaf’s logging toolkit keeps one fast MiniLogger at the core while exposing a
8
8
  - Apply filter chains, transports, and adapter-specific features (Pino, Winston, custom factories) through the shared `LoggingConfig` contract.
9
9
  - Instrument classes using decorators, `LoggedClass`, and `Logging.because` while StopWatch, text/time utilities, and environment helpers round out the diagnostics surface.
10
10
 
11
+ ### Core Concepts
12
+
13
+ * **`Logging`**: A static class for managing global logging configuration and creating logger instances.
14
+ * **`MiniLogger`**: A lightweight, default logger implementation.
15
+ * **`LoggedClass`**: An abstract base class that provides a pre-configured logger instance to its subclasses.
16
+ * **`LoggedEnvironment`**: A class for managing environment-specific logging configurations.
17
+ * **Decorators**: A set of decorators (`@log`, `@benchmark`, etc.) for easily adding logging and benchmarking to your methods.
18
+ * **Filters and Transports**: A system for filtering sensitive information and transporting logs to different destinations.
19
+ * **Pino and Winston Integration**: Built-in support for two popular logging libraries, Pino and Winston.
20
+
11
21
  ![Licence](https://img.shields.io/github/license/decaf-ts/logging.svg?style=plastic)
12
22
  ![GitHub language count](https://img.shields.io/github/languages/count/decaf-ts/logging?style=plastic)
13
23
  ![GitHub top language](https://img.shields.io/github/languages/top/decaf-ts/logging?style=plastic)
@@ -37,7 +47,7 @@ Decaf’s logging toolkit keeps one fast MiniLogger at the core while exposing a
37
47
 
38
48
  Documentation available [here](https://decaf-ts.github.io/logging/)
39
49
 
40
- Minimal size: 6 KB kb gzipped
50
+ Minimal size: 6.1 KB kb gzipped
41
51
 
42
52
 
43
53
  # Logging Library — Detailed Description
@@ -115,361 +125,160 @@ Intended usage
115
125
  - For advanced deployments, swap to WinstonFactory.
116
126
 
117
127
 
118
- # How to Use the Logging Library
119
-
120
- All snippets import from `@decaf-ts/logging` (swap to a relative path when working inside this repo). Each item below contains a short description, an optional sequence diagram for complex flows, and runnable TypeScript code.
128
+ # How to Use
121
129
 
122
- ## 1. Bootstrapping Global Configuration
123
- Description: Initialize `Logging` once (or hydrate `LoggedEnvironment`) to define levels, formatting, colors, transports, and app identifiers that downstream impersonated loggers inherit without per-call overhead.
130
+ This guide provides examples of how to use the main features of the `@decaf-ts/logging` library.
124
131
 
125
- ```mermaid
126
- sequenceDiagram
127
- autonumber
128
- participant App as App
129
- participant Env as LoggedEnvironment
130
- participant Logging as Logging.setConfig
131
- participant Root as MiniLogger (root)
132
- App->>Env: Environment.accumulate(defaults)
133
- Env-->>App: Env proxy (app name, theme, format)
134
- App->>Logging: setConfig({ level, format, transports })
135
- Logging->>Root: ensureRoot() memoizes MiniLogger
136
- ```
132
+ ## Initial Configuration
137
133
 
138
- ```ts
139
- import { Logging, LogLevel, DefaultLoggingConfig, LoggedEnvironment } from "@decaf-ts/logging";
134
+ You can set the initial logging configuration using `Logging.setConfig()`.
140
135
 
141
- // seed the environment before configuring Logging.
142
- LoggedEnvironment.accumulate({
143
- app: "InventoryAPI",
144
- logging: { separator: "•" },
145
- });
136
+ ```typescript
137
+ import { Logging, LogLevel } from '@decaf-ts/logging';
146
138
 
147
139
  Logging.setConfig({
148
- ...DefaultLoggingConfig,
149
140
  level: LogLevel.debug,
150
- verbose: 2,
151
141
  style: true,
152
- format: "raw",
142
+ timestamp: true,
153
143
  });
154
-
155
- Logging.info("Boot complete");
156
- Logging.verbose("Dependency graph built", 1);
157
- Logging.silly("Deep diagnostics", 3); // ignored because verbose < 3
158
144
  ```
159
145
 
160
- ## 2. Impersonation & Proxy Performance
161
- Description: ONE `MiniLogger` instance powers every context. Calls to `.for(...)` return lightweight proxies that temporarily override context/config without allocating new drivers, so a hot path can derive thousands of child loggers without GC churn.
162
-
163
- ```mermaid
164
- sequenceDiagram
165
- autonumber
166
- participant App as App
167
- participant Logging as Logging.for(...)
168
- participant Root as MiniLogger (root)
169
- participant Proxy as Logger Proxy
170
- App->>Logging: Logging.for("OrderService")
171
- Logging->>Root: ensureRoot() reuse
172
- Root-->>Proxy: Proxy bound to ["OrderService"]
173
- Proxy->>Proxy: `.for("create")` extends context
174
- Proxy-->>App: Proxy emits create log (no new logger)
175
- ```
146
+ ## Impersonation Mechanism
176
147
 
177
- ```ts
178
- import { Logging, LogLevel, type LoggingConfig } from "@decaf-ts/logging";
148
+ The logging framework uses a proxy-based impersonation mechanism to create child loggers. This provides a significant performance gain by avoiding the need to create new logger instances for each context.
179
149
 
180
- Logging.setConfig({ level: LogLevel.info });
181
- const logger = Logging.for("OrderService");
150
+ ```typescript
151
+ import { Logging } from '@decaf-ts/logging';
182
152
 
183
- function runScenario(overrides?: Partial<LoggingConfig>) {
184
- const scoped = logger.for("createOrUpdate", overrides);
185
- scoped.info("Validating payload");
186
- scoped.for("db").debug("Executing UPSERT..."); // reuses the same proxy target
187
- scoped.clear(); // resets context/config so the proxy can serve the next call
188
- }
153
+ const rootLogger = Logging.get();
154
+ const childLogger = rootLogger.for('MyClass');
189
155
 
190
- runScenario({ correlationId: "req-1" });
191
- runScenario({ correlationId: "req-2", style: false });
156
+ // childLogger is a proxy that inherits the configuration of rootLogger
157
+ childLogger.info('This is a message from the child logger');
192
158
  ```
193
159
 
194
- ## 3. Filtering Sensitive Data
195
- Description: Attach `PatternFilter` or custom filters via `LoggingConfig.filters` to redact PII/passwords before formatting. Filters run on the message string after it was rendered in RAW format; JSON output serializes the already-filtered content, so sensitive values disappear in both outputs.
196
-
197
- ```mermaid
198
- sequenceDiagram
199
- autonumber
200
- participant App as App
201
- participant Proxy as Logger Proxy
202
- participant Filter as PatternFilter
203
- participant Console as Transport
204
- App->>Proxy: log("password=secret")
205
- Proxy->>Filter: filter(config, message, context)
206
- Filter-->>Proxy: "password=***"
207
- Proxy->>Console: emit RAW or JSON string
208
- ```
160
+ ## Filters
209
161
 
210
- ```ts
211
- import { Logging, LogLevel, PatternFilter, type LoggingConfig } from "@decaf-ts/logging";
162
+ Filters allow you to process log messages before they are written. You can use them to filter out sensitive information.
212
163
 
213
- class PiiFilter extends PatternFilter {
214
- constructor() {
215
- super(/(password|ssn)=([^&\s]+)/gi, (_full, key) => `${key}=***`);
216
- }
217
- }
164
+ ```typescript
165
+ import { Logging, PatternFilter } from '@decaf-ts/logging';
218
166
 
219
- const filters: LoggingConfig["filters"] = [new PiiFilter()];
167
+ // Filter out passwords
168
+ const passwordFilter = new PatternFilter(/password/i, '********');
220
169
  Logging.setConfig({
221
- level: LogLevel.debug,
222
- filters,
223
- format: "raw",
170
+ filters: [passwordFilter],
224
171
  });
225
172
 
226
- const logger = Logging.for("SignupFlow");
227
- logger.info("Attempt password=abc123&email=user@example.com"); // prints password=***
228
-
229
- Logging.setConfig({ format: "json" });
230
- logger.info("ssn=123-45-6789"); // JSON payload contains ssn=*** already
173
+ const logger = Logging.get();
174
+ logger.info('User logged in with password: mysecretpassword');
175
+ // Output will be: User logged in with password: ********
231
176
  ```
232
177
 
233
- ## 4. Transports & Custom Destinations
234
- Description: Supply writable streams via `LoggingConfig.transports` when using adapters (Pino/Winston) to branch logs to files, sockets, or monitoring systems. Each adapter inspects `transports` and builds either a native transport (Winston) or Pino multistream.
235
-
236
- ```mermaid
237
- sequenceDiagram
238
- autonumber
239
- participant App as App
240
- participant Logging as Logging.setFactory
241
- participant Adapter as Adapter Logger
242
- participant Transport as DestinationStream
243
- App->>Logging: setFactory(WinstonFactory)
244
- App->>Adapter: Logging.for("Gateway", { transports })
245
- Adapter->>Transport: write(formatted line)
246
- ```
178
+ ## Transports
247
179
 
248
- ```ts
249
- import fs from "node:fs";
250
- import { Logging, LogLevel } from "@decaf-ts/logging";
251
- import { WinstonFactory } from "@decaf-ts/logging/winston/winston";
252
- import Transport from "winston-transport";
180
+ Transports are responsible for writing log messages to a destination. The library includes a default console transport, and you can create your own.
253
181
 
254
- class AuditTransport extends Transport {
255
- log(info: any, callback: () => void) {
256
- fs.appendFileSync("audit.log", `${info.message}\n`);
257
- callback();
258
- }
259
- }
182
+ *Note: The library currently focuses on filters and logger implementation, with transport-like functionality being a feature of the underlying adapters (Pino, Winston).*
260
183
 
261
- Logging.setFactory(WinstonFactory);
262
- const auditLogger = Logging.for("AuditTrail", {
263
- level: LogLevel.info,
264
- transports: [new AuditTransport()],
265
- });
184
+ ## Pino and Winston Integration
185
+
186
+ The library includes built-in support for Pino and Winston.
187
+
188
+ ### Pino
189
+
190
+ ```typescript
191
+ import { Logging } from '@decaf-ts/logging';
192
+ import { pino } from 'pino';
193
+ import { PinoLogFactory } from '@decaf-ts/logging/pino';
266
194
 
267
- auditLogger.info("policy=PASSWORD_RESET user=u-9 timestamp=...");
195
+ const pinoInstance = pino();
196
+ Logging.setFactory(new PinoLogFactory(pinoInstance));
197
+
198
+ const logger = Logging.get();
199
+ logger.info('This message will be logged by Pino');
268
200
  ```
269
201
 
270
- ## 5. Pino & Winston Native Features
271
- Description: Use `PinoLogger` and `WinstonLogger` directly (or via `Logging.setFactory`) to access adapter-only functions such as `child()`, `flush()`, or Pino/Winston-specific levels while still honoring the shared `LoggingConfig`.
272
-
273
- ```ts
274
- import pino from "pino";
275
- import { Logging, LogLevel } from "@decaf-ts/logging";
276
- import { PinoLogger, PinoFactory } from "@decaf-ts/logging/pino/pino";
277
- import { WinstonLogger } from "@decaf-ts/logging/winston/winston";
278
-
279
- // Pino: reuse an existing driver and call child()
280
- const sink = pino({ level: "trace", name: "Api" });
281
- const pinoLogger = new PinoLogger("Api", { level: LogLevel.debug }, sink);
282
- pinoLogger.child({ context: "handler" }).info("Child context respects config");
283
- pinoLogger.flush?.();
284
-
285
- // Register the adapter globally so Logging.for uses it
286
- Logging.setFactory(PinoFactory);
287
- Logging.for("BatchJob").debug("Runs through native Pino now");
288
-
289
- // Winston: pass custom transports or formats through LoggingConfig
290
- const winstonLogger = new WinstonLogger("Worker", {
291
- transports: [
292
- new (WinstonLogger as any).prototype.winston.transports.Console(), // or custom
293
- ],
294
- correlationId: "cid-1",
202
+ ### Winston
203
+
204
+ ```typescript
205
+ import { Logging } from '@decaf-ts/logging';
206
+ import * as winston from 'winston';
207
+ import { WinstonLogFactory } from '@decaf-ts/logging/winston';
208
+
209
+ const winstonInstance = winston.createLogger({
210
+ transports: [new winston.transports.Console()],
295
211
  });
296
- winstonLogger.error("Failure");
297
- ```
212
+ Logging.setFactory(new WinstonLogFactory(winstonInstance));
298
213
 
299
- ## 6. Environment Accumulator & Runtime Overrides
300
- Description: `Environment.accumulate` builds a proxy whose properties resolve to runtime ENV variables (Node or browser) with helpers such as `keys`, `get`, and `orThrow`. Extend the shape by calling `accumulate` repeatedly; an empty string marks required values.
301
-
302
- ```mermaid
303
- sequenceDiagram
304
- autonumber
305
- participant App as App
306
- participant Env as Environment.accumulate
307
- participant Proxy as Env Proxy
308
- participant Runtime as process.env/ENV
309
- App->>Env: accumulate({ service: { host: "", port: 8080 } })
310
- Env-->>Proxy: proxy w/ compose-toString keys
311
- App->>Proxy: proxy.service.host
312
- Proxy->>Runtime: check SERVICE__HOST
313
- Runtime-->>Proxy: "api.internal"
314
- Proxy-->>App: returns runtime override or default
214
+ const logger = Logging.get();
215
+ logger.info('This message will be logged by Winston');
315
216
  ```
316
217
 
317
- ```ts
318
- import { Environment, LoggedEnvironment } from "@decaf-ts/logging/environment";
218
+ ## `LoggedEnvironment`
319
219
 
320
- // Extend the singleton shape; string "" means "required"
321
- const Config = Environment.accumulate({
322
- service: { host: "", port: 8080 },
323
- logging: LoggedEnvironment,
324
- });
220
+ The `LoggedEnvironment` class allows you to manage environment-specific logging configurations.
325
221
 
326
- console.log(String((Config as any).service.host)); // SERVICE__HOST
327
- console.log(Environment.keys()); // ["SERVICE", "LOGGING", ...]
222
+ ```typescript
223
+ import { LoggedEnvironment } from '@decaf-ts/logging';
328
224
 
329
- // Fail fast when required env is missing or empty
330
- const runtime = Config.orThrow();
331
- const serviceHost = runtime.service.host; // throws if missing at runtime
225
+ // Set the application name
226
+ LoggedEnvironment.app = 'MyAwesomeApp';
332
227
 
333
- // Programmatic lookups
334
- const verbose = Environment.get("logging.verbose");
228
+ // Accumulate additional environment configuration
229
+ LoggedEnvironment.accumulate({
230
+ database: {
231
+ host: 'localhost',
232
+ port: 5432,
233
+ },
234
+ });
335
235
  ```
336
236
 
337
- ## 7. LoggedClass for Drop-in Contextual Logging
338
- Description: Extend `LoggedClass` to gain a protected `this.log` that’s already scoped to the subclass and works with decorators, impersonation, and adapters.
237
+ ## `LoggedClass`
339
238
 
340
- ```ts
341
- import { LoggedClass, Logging, LogLevel } from "@decaf-ts/logging";
239
+ The `LoggedClass` is an abstract base class that provides a pre-configured logger instance to its subclasses.
342
240
 
343
- Logging.setConfig({ level: LogLevel.info });
241
+ ```typescript
242
+ import { LoggedClass } from '@decaf-ts/logging';
344
243
 
345
- class EmailService extends LoggedClass {
346
- async send(to: string, template: string) {
347
- this.log.info(`Dispatching template=${template} to ${to}`);
348
- return true;
244
+ class MyService extends LoggedClass {
245
+ doSomething() {
246
+ this.log.info('Doing something...');
349
247
  }
350
248
  }
351
249
 
352
- const svc = new EmailService();
353
- await svc.send("user@example.com", "welcome");
250
+ const service = new MyService();
251
+ service.doSomething();
354
252
  ```
355
253
 
356
- ## 8. StopWatch for Benchmarking
357
- Description: `StopWatch` uses the highest resolution clock available (browser `performance.now`, Node `process.hrtime.bigint`, or `Date.now`) to measure laps, pause/resume, and report JSON snapshots—useful for the `@benchmark` decorator or manual instrumentation.
254
+ ## Decorators
358
255
 
359
- ```ts
360
- import { StopWatch } from "@decaf-ts/logging/time";
256
+ The library provides a set of decorators for easily adding logging and benchmarking to your methods.
361
257
 
362
- const sw = new StopWatch(true);
363
- await new Promise((r) => setTimeout(r, 15));
364
- sw.lap("load config");
365
- sw.pause();
258
+ ### `@log`
366
259
 
367
- await new Promise((r) => setTimeout(r, 5)); // paused time ignored
368
- sw.resume();
369
- await new Promise((r) => setTimeout(r, 10));
370
- const lap = sw.lap("connect db");
371
- console.log(lap.ms, lap.totalMs, sw.toString());
372
- console.log(JSON.stringify(sw));
373
- ```
374
-
375
- ## 9. Decorators & Advanced Instrumentation
376
- Description: Use the stock decorators (`@log`, `@debug`, `@info`, `@verbose`, `@silly`, `@benchmark`, `@final`) or extend `@log` to emit structured entry/exit details. Decorators work with `LoggedClass` instances and plain classes alike.
377
-
378
- ```mermaid
379
- sequenceDiagram
380
- autonumber
381
- participant Caller as Caller
382
- participant Decorator as @log
383
- participant Method as Original Method
384
- participant Logger as Logger Proxy
385
- Caller->>Decorator: invoke decorated method
386
- Decorator->>Logger: log(entryMessage(args))
387
- Decorator->>Method: Reflect.apply(...)
388
- Method-->>Decorator: result / Promise
389
- Decorator->>Logger: log(exitMessage or benchmark)
390
- ```
260
+ ```typescript
261
+ import { log, LogLevel } from '@decaf-ts/logging';
391
262
 
392
- ```ts
393
- import {
394
- log,
395
- debug,
396
- info,
397
- silly,
398
- verbose,
399
- benchmark,
400
- LogLevel,
401
- LoggedClass,
402
- } from "@decaf-ts/logging";
403
-
404
- class CustomLogDecorator {
405
- static payload(label: string) {
406
- return log(
407
- LogLevel.info,
408
- 0,
409
- (...args) => `${label}: ${JSON.stringify(args)}`,
410
- (err, result) =>
411
- err ? `${label} failed: ${err.message}` : `${label} ok: ${result}`
412
- );
263
+ class MyDecoratedService {
264
+ @log(LogLevel.info)
265
+ myMethod(arg1: string) {
266
+ // ...
413
267
  }
414
268
  }
269
+ ```
415
270
 
416
- class BillingService extends LoggedClass {
417
- @CustomLogDecorator.payload("charge")
418
- @benchmark()
419
- async charge(userId: string, amount: number) {
420
- if (amount <= 0) throw new Error("invalid amount");
421
- return `charged:${userId}:${amount}`;
422
- }
423
-
424
- @debug()
425
- rebuildIndex() {}
426
-
427
- @info()
428
- activate() {}
271
+ ### `@benchmark`
429
272
 
430
- @silly()
431
- ping() {}
273
+ ```typescript
274
+ import { benchmark } from '@decaf-ts/logging';
432
275
 
433
- @verbose(1)
434
- sync() {}
276
+ class MyBenchmarkedService {
277
+ @benchmark()
278
+ myLongRunningMethod() {
279
+ // ...
280
+ }
435
281
  }
436
-
437
- const svc = new BillingService();
438
- await svc.charge("u-1", 25);
439
- ```
440
-
441
- ## 10. Utility Modules (text, time, utils, web)
442
- Description: Helper functions complement logging by formatting identifiers, generating ENV keys, and detecting runtimes.
443
-
444
- ```ts
445
- import {
446
- padEnd,
447
- patchPlaceholders,
448
- sf,
449
- toCamelCase,
450
- toENVFormat,
451
- toSnakeCase,
452
- toKebabCase,
453
- toPascalCase,
454
- } from "@decaf-ts/logging/text";
455
- import { formatMs, now } from "@decaf-ts/logging/time";
456
- import { getObjectName, isClass, isFunction, isInstance } from "@decaf-ts/logging/utils";
457
- import { isBrowser } from "@decaf-ts/logging/web";
458
-
459
- const padded = padEnd("id", 5, "_"); // "id___"
460
- const greeting = patchPlaceholders("Hello ${name}", { name: "Ada" });
461
- const formatted = sf("{0}-{name}", "A", { name: "B" });
462
- const snake = toSnakeCase("HelloWorld Test"); // "hello_world_test"
463
- const envKey = toENVFormat("service.host"); // "SERVICE_HOST"
464
- const camel = toCamelCase("hello world");
465
- const pascal = toPascalCase("hello world");
466
- const kebab = toKebabCase("Hello World");
467
-
468
- const duration = formatMs(now() - now()); // hh:mm:ss.mmm string
469
- const typeName = getObjectName(new (class Repo {})());
470
- const runtimeIsBrowser = isBrowser();
471
- const plainFn = () => true;
472
- console.log(isFunction(plainFn), isClass(class A {}), isInstance({})); // type guards
473
282
  ```
474
283
 
475
284
 
package/dist/logging.cjs CHANGED
@@ -1,2 +1,2 @@
1
- var t,e;t=this,e=function(t,e,r,o){"use strict";const n="ENV",s="__",i=["${","}"];var a;t.LogLevel=void 0,(a=t.LogLevel||(t.LogLevel={})).benchmark="benchmark",a.error="error",a.warn="warn",a.info="info",a.verbose="verbose",a.debug="debug",a.trace="trace",a.silly="silly";const c={benchmark:0,error:3,warn:6,info:9,verbose:12,debug:15,trace:18,silly:21};var l;t.LoggingMode=void 0,(l=t.LoggingMode||(t.LoggingMode={})).RAW="raw",l.JSON="json";const g={app:{},separator:{},class:{fg:34},id:{fg:36},stack:{},timestamp:{},message:{error:{fg:31}},method:{},logLevel:{benchmark:{fg:32,style:["bold"]},error:{fg:31,style:["bold"]},info:{fg:34,style:["bold"]},verbose:{fg:34,style:["bold"]},debug:{fg:33,style:["bold"]},trace:{fg:33,style:["bold"]},silly:{fg:33,style:["bold"]}}},u={env:"development",verbose:0,level:t.LogLevel.info,logLevel:!0,style:!1,contextSeparator:".",separator:"-",timestamp:!0,timestampFormat:"HH:mm:ss.SSS",context:!0,meta:!0,format:t.LoggingMode.RAW,pattern:"{level} [{timestamp}] {app} {context} {separator} {message} {stack}",theme:g};function f(t,e,r="g"){return Object.entries(e).forEach(([e,o])=>{const n=RegExp(y(e),r);t=t.replace(n,o)}),t}function h(t){return p(t).toUpperCase()}function p(t){return t.replace(/([a-z])([A-Z])/g,"$1_$2").replace(/[\s-]+/g,"_").toLowerCase()}function y(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function b(t,...e){if(e.length>1&&!e.every(t=>"string"==typeof t||"number"==typeof t))throw Error("Only string and number arguments are supported for multiple replacements.");if(1===e.length&&"object"==typeof e[0]){const r=e[0];return Object.entries(r).reduce((t,[e,r])=>t.replace(RegExp(`\\{${e}\\}`,"g"),()=>r),t)}return t.replace(/{(\d+)}/g,(t,r)=>void 0!==e[r]?e[r].toString():"undefined")}const d=b;function m(){return Object.getPrototypeOf(Object.getPrototypeOf(globalThis))!==Object.prototype}const v=Symbol("EnvironmentEmpty"),w=Symbol("EnvironmentModel");class L extends r.ObjectAccumulator{static{this.factory=()=>new L}constructor(){super(),Object.defineProperty(this,w,{value:{},writable:!0,enumerable:!1,configurable:!1})}fromEnv(t){let e;return m()?e=globalThis[n]||{}:(e=globalThis.process.env,t=h(t)),this.parseEnvValue(e[t])}parseEnvValue(t){if("string"!=typeof t)return t;if("true"===t)return!0;if("false"===t)return!1;const e=parseFloat(t);return isNaN(e)?t:e}expand(t){Object.entries(t).forEach(([t,e])=>{L.mergeModel(this[w],t,e),Object.defineProperty(this,t,{get:()=>{const r=this.fromEnv(t);return void 0!==r?r:e&&"object"==typeof e?L.buildEnvProxy(e,[t]):""===e?v:e},set:t=>{e=t},configurable:!0,enumerable:!0})})}orThrow(){const t=this[w],e=t=>t.map(t=>h(t)).join(s),r=t=>L.readRuntimeEnv(t),o=t=>void 0!==t?this.parseEnvValue(t):void 0,n=(t,e=!1)=>L.missingEnvError(t,e),i=(t,s)=>new Proxy({},{get(a,c){if("string"!=typeof c)return;const l=[...s,c],g=e(l),u=r(g);if("string"==typeof u&&0===u.length)throw n(g,!0);const f=o(u);if(void 0!==f){if("string"==typeof f&&0===f.length)throw n(g,!0);return f}if(!t||!Object.prototype.hasOwnProperty.call(t,c))throw n(g);const h=t[c];if(void 0!==h){if(""===h)throw n(g);return h&&"object"==typeof h&&!Array.isArray(h)?i(h,l):h}},ownKeys:()=>t?Reflect.ownKeys(t):[],getOwnPropertyDescriptor(e,r){if(t)return Object.prototype.hasOwnProperty.call(t,r)?{enumerable:!0,configurable:!0}:void 0}});return new Proxy(this,{get(s,a,c){if("string"!=typeof a)return Reflect.get(s,a,c);if(!Object.prototype.hasOwnProperty.call(t,a))return Reflect.get(s,a,c);const l=e([a]),g=r(l);if("string"==typeof g&&0===g.length)throw n(l,!0);const u=o(g);if(void 0!==u){if("string"==typeof u&&0===u.length)throw n(l,!0);return u}const f=t[a];if(f&&"object"==typeof f&&!Array.isArray(f))return i(f,[a]);if(void 0===f)return Reflect.get(s,a,c);const h=Reflect.get(s,a);if(void 0===h||""===h)throw n(l,""===h);return h}})}static instance(...t){if(!L._instance){const e=L.factory(...t),r=new Proxy(e,{get(t,e,r){const o=Reflect.get(t,e,r);if(o!==v&&("string"!=typeof e||!Object.prototype.hasOwnProperty.call(t,e)||void 0!==o)){if(void 0!==o)return o;if("string"==typeof e){if("app"===e)return;return L.buildEnvProxy(void 0,[e])}return o}}});L._instance=r}return L._instance}accumulate(t){return super.accumulate(t),this}static accumulate(t){const e=L.instance();return Object.keys(e).forEach(t=>{const r=Object.getOwnPropertyDescriptor(e,t);r&&r.configurable&&r.enumerable&&Object.defineProperty(e,t,{...r,enumerable:!1})}),e.accumulate(t),e}static get(t){return L._instance.get(t)}static buildEnvProxy(t,e){const r=t=>t.map(t=>h(t)).join(s);return new Proxy({},{get(o,n){if(n===Symbol.toPrimitive)return()=>r(e);if("toString"===n)return()=>r(e);if("valueOf"===n)return()=>r(e);if("symbol"==typeof n)return;const s=!!t&&Object.prototype.hasOwnProperty.call(t,n),i=s?t[n]:void 0,a=[...e,n],c=(l=r(a),L.readRuntimeEnv(l));var l;return void 0!==c?c:i&&"object"==typeof i?L.buildEnvProxy(i,a):s&&""===i||s&&void 0===i?void 0:L.buildEnvProxy(void 0,a)},ownKeys:()=>t?Reflect.ownKeys(t):[],getOwnPropertyDescriptor(e,r){if(t)return Object.prototype.hasOwnProperty.call(t,r)?{enumerable:!0,configurable:!0}:void 0}})}static keys(t=!0){return L.instance().keys().map(e=>t?h(e):e)}static mergeModel(t,e,r){if(t){if(r&&"object"==typeof r&&!Array.isArray(r)){const o=t[e],n=o&&"object"==typeof o&&!Array.isArray(o)?o:{};return t[e]=n,void Object.entries(r).forEach(([t,e])=>{L.mergeModel(n,t,e)})}t[e]=r}}static readRuntimeEnv(t){if(m()){const e=globalThis[n];return e?e[t]:void 0}return globalThis?.process?.env?.[t]}static missingEnvError(t,e){return Error(`Environment variable ${t} is required but was ${e?"an empty string":"undefined"}.`)}}const x=L.accumulate(Object.assign({app:void 0},u,{env:(m()&&globalThis[n]?globalThis[n].NODE_ENV:globalThis.process.env.NODE_ENV)||"development"}));function _(t){if("function"!=typeof t)return!1;try{const e=Function.prototype.toString.call(t);if(/^\s*class[\s{]/.test(e))return!0}catch{}const e=Object.getOwnPropertyDescriptor(t,"prototype");if(!e||!e.value)return!1;if(!1===e.writable)return!0;const r=t.prototype;return!!Object.prototype.hasOwnProperty.call(r,"constructor")&&Object.getOwnPropertyNames(r).filter(t=>"constructor"!==t).length>0}function O(t){return"function"==typeof t&&!_(t)}function E(t){if(!O(t))return!1;const e=Object.getOwnPropertyDescriptor(t,"prototype");return!e||void 0===e.value}function j(t){if(null===t||"object"!=typeof t)return!1;const e=t.constructor;return!(!e||e===Object)&&_(e)}function M(t){if(null===t)return"null";if(void 0===t)return"undefined";if("string"==typeof t)return t;if(_(t))return t.name||"AnonymousClass";if(j(t)){const e=t.toString;if("function"==typeof e&&e!==Object.prototype.toString)try{const r=e.call(t);if("string"==typeof r&&r.length)return r}catch{}const r=t.constructor;return r&&r.name?r.name:"AnonymousInstance"}if(E(t)||O(t)){const e=t;return e.name?e.name:"anonymous"}if("object"==typeof t){const e=Object.prototype.toString.call(t),r=/^\[object ([^\]]+)\]$/.exec(e);return r?.[1]?r[1]:"Object"}return typeof t}const A=Symbol("MiniLoggerRootContext");class P{constructor(t,e,r=[]){this.conf=e,this.baseContext=Array.isArray(r)?[...r]:[],t&&this.baseContext.push(t),this.context=[...this.baseContext],this[A]=[...this.baseContext]}config(t){return this.conf&&t in this.conf?this.conf[t]:C.getConfig()[t]}for(t,e,...r){let o,n=e;const s=Array.isArray(this.context)?[...this.context]:"string"==typeof this.context&&this.context?[this.context]:[],i=this[A],a=Array.isArray(i)?[...i]:Array.isArray(this.baseContext)?[...this.baseContext]:[];"string"==typeof t?o=t:void 0!==t&&(_(t)||j(t)||O(t)?o=M(t):!n&&t&&"object"==typeof t&&(n=t));let c=o?[...s,o]:[...s];return new Proxy(this,{get:(t,e,r)=>{const o=Reflect.get(t,e,r);return"config"===e?new Proxy(this.config,{apply:(t,e,o)=>{const[s]=o;return n&&void 0!==s&&s in n?n[s]:Reflect.apply(t,r,o)},get:(t,e)=>n&&e in n?n[e]:Reflect.get(t,e,r)}):"clear"===e?()=>(c=[...a],n=void 0,r):"context"===e?c:"root"===e?[...a]:e===A?a:"for"===e?(...e)=>{const r=Array.isArray(t.context)?[...t.context]:"string"==typeof t.context&&t.context?[t.context]:[];t.context=[...c];try{return t.for.apply(t,e)}finally{t.context=r}}:o}})}createLog(t,e,r,o){const n={},s=this.config("style"),i=this.config("separator"),a=C.getConfig().app;if(a&&(n.app=s?C.theme(a,"app",t):a),i&&(n.separator=s?C.theme(i,"separator",t):i),this.config("timestamp")){const e=(new Date).toISOString(),r=s?C.theme(e,"timestamp",t):e;n.timestamp=r}if(this.config("logLevel")){const e=s?C.theme(t,"logLevel",t):t;n.level=e.toUpperCase()}if(this.config("context")){const e=Array.isArray(this.context)?this.context:"string"==typeof this.context&&this.context?[this.context]:[];if(e.length){const r=e.join(this.config("contextSeparator")||"."),o=s?C.theme(r,"class",t):r;n.context=o}}if(this.config("correlationId")){const e=s?C.theme(this.config("correlationId").toString(),"id",t):this.config("correlationId").toString();n.correlationId=e}const c=s?C.theme("string"==typeof e?e:e.message,"message",t):"string"==typeof e?e:e.message;n.message=c;const l=this.config("meta")&&o?o:void 0,g=l?this.formatMeta(l):void 0;if(l&&(n.meta=l),r||e instanceof Error){const o=s?C.theme(r?.stack||e.stack,"stack",t):r?.stack||"";n.stack=` | ${(r||e).message} - Stack trace:\n${o}`}switch(this.config("format")){case"json":return JSON.stringify(n);case"raw":{const t=this.config("pattern").split(" ").map(t=>{if(!t.match(/\{.*?}/g))return t;const e=b(t,n);return e!==t?e:void 0}).filter(t=>t).join(" ");return g?`${t} ${g}`:t}default:throw Error("Unsupported logging format: "+this.config("format"))}}formatMeta(t){try{return JSON.stringify(t)}catch(e){return t+""}}log(e,r,o,n){const s=this.config("level");if(c[e]>c[s])return;let i;switch(e){case t.LogLevel.benchmark:case t.LogLevel.info:case t.LogLevel.verbose:i=console.log;break;case t.LogLevel.debug:i=console.debug;break;case t.LogLevel.error:i=console.error;break;case t.LogLevel.trace:i=console.trace;break;case t.LogLevel.warn:i=console.warn;break;case t.LogLevel.silly:i=console.debug;break;default:throw Error("Invalid log level")}i(this.createLog(e,r,o,n))}benchmark(e,r){this.log(t.LogLevel.benchmark,e,void 0,r)}silly(e,r=0,o){const n="number"==typeof r?r:0,s="number"==typeof r?o:r;this.config("verbose")<n||this.log(t.LogLevel.silly,e,void 0,s)}verbose(e,r=0,o){const n="number"==typeof r?r:0,s="number"==typeof r?o:r;this.config("verbose")<n||this.log(t.LogLevel.verbose,e,void 0,s)}info(e,r){this.log(t.LogLevel.info,e,void 0,r)}debug(e,r){this.log(t.LogLevel.debug,e,void 0,r)}error(e,r,o){let n,s;r instanceof Error?(n=r,s=o):s=r,this.log(t.LogLevel.error,e,n,s)}warn(e,r){this.log(t.LogLevel.warn,e,void 0,r)}trace(e,r){this.log(t.LogLevel.trace,e,void 0,r)}setConfig(t){this.conf={...this.conf||{},...t}}get root(){return[...this.baseContext]}clear(){return this.context=[...this.baseContext],this}}class C{static{this._factory=(t,e)=>{const r="string"==typeof x.app?[x.app]:[];return new P(t,e,r)}}static{this._config=x}constructor(){}static setFactory(t){C._factory=t,this.global=void 0}static setConfig(t){Object.entries(t).forEach(([t,e])=>{this._config[t]=e})}static getConfig(){return this._config}static get(){return this.ensureRoot()}static verbose(t,e=0,r){return this.get().verbose(t,e,r)}static info(t,e){return this.get().info(t,e)}static trace(t,e){return this.get().trace(t,e)}static debug(t,e){return this.get().debug(t,e)}static benchmark(t,e){return this.get().benchmark(t,e)}static silly(t,e=0,r){return this.get().silly(t,e,r)}static warn(t,e){return this.get().warn(t,e)}static error(t,e,r){return this.get().error(t,e,r)}static for(t,e,...r){const o=void 0!==e?[t,e]:[t];return(this.global?this.global:this.ensureRoot(r)).for(...o)}static because(t,e){let r=this.ensureRoot().for(t,this._config);return e&&(r=r.for(e)),r}static baseContext(){const t=this._config.app;return"string"==typeof t&&t.length?[t]:[]}static attachRootContext(t){const e=t.root&&Array.isArray(t.root)?[...t.root]:this.baseContext();return(!t.context||Array.isArray(t.context)&&0===t.context.length)&&(t.context=[...e]),t[A]=[...e],t}static ensureRoot(t=[]){if(!this.global){const e=this._factory(void 0,void 0,...t);this.global=this.attachRootContext(e)}return this.global}static theme(r,o,n,s=g){if(!this._config.style)return r;const i=s[o];if(!i||!Object.keys(i).length)return r;let a=i;const c=Object.assign({},t.LogLevel);return Object.keys(i)[0]in c&&(a=i[n]||{}),Object.keys(a).reduce((t,r)=>{const o=a[r];return o?((t,r,o)=>{try{const n=t;let s=e.style(n);function i(t,r=!1){let i=r?s.background:s.foreground;if(!Array.isArray(t))return i.call(s,o);switch(t.length){case 1:return i=r?s.bgColor256:s.color256,i(t[0]);case 3:return i=r?s.bgRgb:s.rgb,s.rgb(t[0],t[1],t[2]);default:return e.style(n)}}function a(t){s="number"==typeof t?s.style(t):s[t]}switch(r){case"bg":case"fg":return i(o).text;case"style":return Array.isArray(o)?o.forEach(a):a(o),s.text;default:return n}}catch(c){return t}})(t,r,o):t},r)}}class k{get log(){return this._log||(this._log=C.for(this)),this._log}constructor(){}}class S extends k{get log(){return super.log.for(this,{filters:[]})}}const R="undefined"!=typeof globalThis&&"function"==typeof globalThis.performance?.now?()=>globalThis.performance.now():"undefined"!=typeof process&&"function"==typeof process.hrtime?.bigint?()=>{const t=process.hrtime.bigint();return Number(t)/1e6}:()=>Date.now();function $(t){const e=0>t?"-":"",r=Math.abs(t),o=Math.floor(r/36e5),n=Math.floor(r%36e5/6e4),s=Math.floor(r%6e4/1e3),i=Math.floor(r%1e3),a=(t,e)=>t.toString().padStart(e,"0");return`${e}${a(o,2)}:${a(n,2)}:${a(s,2)}.${a(i,3)}`}function T(e=t.LogLevel.info,r=0,o=(...t)=>"called with "+t,n){return(t,s,i)=>{if(!i||"number"==typeof i)throw Error("Logging decoration only applies to methods");const a=t instanceof k?t.log.for(t[s]):C.for(t).for(t[s]),c=a[e].bind(a),l=i.value;return i.value=new Proxy(l,{apply(t,e,s){c(o(...s),r);try{const r=Reflect.apply(t,e,s);return r instanceof Promise?r.then(t=>(n&&c(n(void 0,t)),t)).catch(t=>{throw n&&a.error(n(t)),t}):(n&&c(n(void 0,r)),r)}catch(t){throw n&&a.error(n(t)),t}}}),i}}function N(){return(t,e,r)=>{if(!r)throw Error("final decorator can only be used on methods");return r?.configurable&&(r.configurable=!1),r}}class I extends S{constructor(t,e){super(),this.regexp=t,this.replacement=e}match(t){const e=this.regexp.exec(t);return this.regexp.lastIndex=0,e}filter(t,e,r){const o=this.log.for(this.filter);if(!this.match(e))return e;try{return e.replace(this.regexp,this.replacement)}catch(t){o.error("PatternFilter replacement error: "+t)}return""}}o.__decorate([N(),o.__metadata("design:type",Function),o.__metadata("design:paramtypes",[String]),o.__metadata("design:returntype",void 0)],I.prototype,"match",null),t.BrowserEnvKey=n,t.DefaultLoggingConfig=u,t.DefaultPlaceholderWrappers=i,t.DefaultTheme=g,t.ENV_PATH_DELIMITER=s,t.Environment=L,t.LogFilter=S,t.LoggedClass=k,t.LoggedEnvironment=x,t.Logging=C,t.MiniLogger=P,t.NumericLogLevels=c,t.PACKAGE_NAME="##PACKAGE##",t.PatternFilter=I,t.ROOT_CONTEXT_SYMBOL=A,t.StopWatch=class{constructor(t=!1){this._startMs=null,this._elapsedMs=0,this._running=!1,this._laps=[],this._lastLapTotalMs=0,t&&this.start()}get running(){return this._running}get elapsedMs(){return this._running&&null!=this._startMs?this._elapsedMs+(R()-this._startMs):this._elapsedMs}start(){return this._running||(this._running=!0,this._startMs=R()),this}pause(){return this._running&&null!=this._startMs&&(this._elapsedMs+=R()-this._startMs,this._startMs=null,this._running=!1),this}resume(){return this._running||(this._running=!0,this._startMs=R()),this}stop(){return this.pause(),this._elapsedMs}reset(){const t=this._running;return this._startMs=t?R():null,this._elapsedMs=0,this._laps=[],this._lastLapTotalMs=0,this}lap(t){const e=this.elapsedMs,r=e-this._lastLapTotalMs,o={index:this._laps.length,label:t,ms:r,totalMs:e};return this._laps.push(o),this._lastLapTotalMs=e,o}get laps(){return this._laps}toString(){return $(this.elapsedMs)}toJSON(){return{running:this._running,elapsedMs:this.elapsedMs,laps:this._laps.slice()}}},t.VERSION="##VERSION##",t.benchmark=()=>(t,e,r)=>{if(!r||"number"==typeof r)throw Error("benchmark decoration only applies to methods");const o=t instanceof k?t.log.for(t[e]):C.for(t).for(t[e]),n=r.value;return r.value=new Proxy(n,{apply(t,e,r){const n=R();try{const s=Reflect.apply(t,e,r);return s instanceof Promise?s.then(t=>(o.benchmark(`completed in ${R()-n}ms`),t)).catch(t=>{throw o.benchmark(`failed in ${R()-n}ms`),t}):(o.benchmark(`completed in ${R()-n}ms`),s)}catch(t){throw o.benchmark(`failed in ${R()-n}ms`),t}}}),r},t.debug=()=>T(t.LogLevel.debug,0,(...t)=>"called with "+t,(t,e)=>t?"Failed with: "+t:e?"Completed with "+JSON.stringify(e):"completed"),t.escapeRegExp=y,t.final=N,t.formatMs=$,t.getObjectName=M,t.info=()=>T(t.LogLevel.info),t.isBrowser=m,t.isClass=_,t.isFunction=O,t.isInstance=j,t.isMethod=E,t.log=T,t.now=R,t.padEnd=(t,e,r=" ")=>{if(1!==r.length)throw Error("Invalid character length for padding. must be one!");return t.padEnd(e,r)},t.patchPlaceholders=(t,e,r=i[0],o=i[1],n="g")=>f(t,Object.entries(e).reduce((t,[e,n])=>(t[`${r}${e}${o}`]=n,t),{}),n),t.patchString=f,t.sf=b,t.silly=()=>T(t.LogLevel.silly),t.stringFormat=d,t.toCamelCase=t=>t.replace(/(?:^\w|[A-Z]|\b\w)/g,(t,e)=>0===e?t.toLowerCase():t.toUpperCase()).replace(/\s+/g,""),t.toENVFormat=h,t.toKebabCase=t=>t.replace(/([a-z])([A-Z])/g,"$1-$2").replace(/[\s_]+/g,"-").toLowerCase(),t.toPascalCase=t=>t.replace(/(?:^\w|[A-Z]|\b\w)/g,t=>t.toUpperCase()).replace(/\s+/g,""),t.toSnakeCase=p,t.trace=()=>T(t.LogLevel.trace),t.verbose=(e=0)=>(e||(e=0),T(t.LogLevel.verbose,e)),Object.keys(e).forEach(r=>{"default"===r||t.hasOwnProperty(r)||Object.defineProperty(t,r,{enumerable:!0,get:()=>e[r]})})},"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("styled-string-builder"),require("typed-object-accumulator"),require("tslib")):"function"==typeof define&&define.amd?define(["exports","styled-string-builder","typed-object-accumulator","tslib"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).logging={},t.styledStringBuilder,t.typedObjectAccumulator,t.tslib);
1
+ var t,e;t=this,e=function(t,e,r,o){"use strict";const n="ENV",s="__",i=["${","}"];var a;t.LogLevel=void 0,(a=t.LogLevel||(t.LogLevel={})).benchmark="benchmark",a.error="error",a.warn="warn",a.info="info",a.verbose="verbose",a.debug="debug",a.trace="trace",a.silly="silly";const c={benchmark:0,error:3,warn:6,info:9,verbose:12,debug:15,trace:18,silly:21};var l;t.LoggingMode=void 0,(l=t.LoggingMode||(t.LoggingMode={})).RAW="raw",l.JSON="json";const g={app:{},separator:{},class:{fg:34},id:{fg:36},stack:{},timestamp:{},message:{error:{fg:31}},method:{},logLevel:{benchmark:{fg:32,style:["bold"]},error:{fg:31,style:["bold"]},info:{fg:34,style:["bold"]},verbose:{fg:34,style:["bold"]},debug:{fg:33,style:["bold"]},trace:{fg:33,style:["bold"]},silly:{fg:33,style:["bold"]}}},u={env:"development",verbose:0,level:t.LogLevel.info,logLevel:!0,style:!1,contextSeparator:".",separator:"-",timestamp:!0,timestampFormat:"HH:mm:ss.SSS",context:!0,meta:!0,format:t.LoggingMode.RAW,pattern:"{level} [{timestamp}] {app} {context} {separator} {message} {stack}",theme:g};function f(t,e,r="g"){return Object.entries(e).forEach((([e,o])=>{const n=RegExp(y(e),r);t=t.replace(n,o)})),t}function h(t){return p(t).toUpperCase()}function p(t){return t.replace(/([a-z])([A-Z])/g,"$1_$2").replace(/[\s-]+/g,"_").toLowerCase()}function y(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function b(t,...e){if(e.length>1&&!e.every((t=>"string"==typeof t||"number"==typeof t)))throw Error("Only string and number arguments are supported for multiple replacements.");if(1===e.length&&"object"==typeof e[0]){const r=e[0];return Object.entries(r).reduce(((t,[e,r])=>t.replace(RegExp(`\\{${e}\\}`,"g"),(()=>r))),t)}return t.replace(/{(\d+)}/g,((t,r)=>void 0!==e[r]?e[r].toString():"undefined"))}const d=b;function m(){return Object.getPrototypeOf(Object.getPrototypeOf(globalThis))!==Object.prototype}const v=Symbol("EnvironmentEmpty"),w=Symbol("EnvironmentModel");class L extends r.ObjectAccumulator{static{this.factory=()=>new L}constructor(){super(),Object.defineProperty(this,w,{value:{},writable:!0,enumerable:!1,configurable:!1})}fromEnv(t){let e;return m()?e=globalThis[n]||{}:(e=globalThis.process.env,t=h(t)),this.parseEnvValue(e[t])}parseEnvValue(t){return L.parseRuntimeValue(t)}static parseRuntimeValue(t){if("string"!=typeof t)return t;if("true"===t)return!0;if("false"===t)return!1;const e=parseFloat(t);return Number.isNaN(e)?t:e}expand(t){Object.entries(t).forEach((([t,e])=>{L.mergeModel(this[w],t,e),Object.defineProperty(this,t,{get:()=>{const r=this.fromEnv(t);return void 0!==r?r:e&&"object"==typeof e?L.buildEnvProxy(e,[t]):""===e?v:e},set:t=>{e=t},configurable:!0,enumerable:!0})}))}orThrow(){const t=this[w],e=t=>t.map((t=>h(t))).join(s),r=t=>L.readRuntimeEnv(t),o=t=>void 0!==t?this.parseEnvValue(t):void 0,n=(t,e=!1)=>L.missingEnvError(t,e),i=(t,s)=>new Proxy({},{get(a,c){if("string"!=typeof c)return;const l=[...s,c],g=e(l),u=r(g);if("string"==typeof u&&0===u.length)throw n(g,!0);const f=o(u);if(void 0!==f){if("string"==typeof f&&0===f.length)throw n(g,!0);return f}if(!t||!Object.prototype.hasOwnProperty.call(t,c))throw n(g);const h=t[c];if(void 0!==h){if(""===h)throw n(g);return h&&"object"==typeof h&&!Array.isArray(h)?i(h,l):h}},ownKeys:()=>t?Reflect.ownKeys(t):[],getOwnPropertyDescriptor(e,r){if(t)return Object.prototype.hasOwnProperty.call(t,r)?{enumerable:!0,configurable:!0}:void 0}});return new Proxy(this,{get(s,a,c){if("string"!=typeof a)return Reflect.get(s,a,c);if(!Object.prototype.hasOwnProperty.call(t,a))return Reflect.get(s,a,c);const l=e([a]),g=r(l);if("string"==typeof g&&0===g.length)throw n(l,!0);const u=o(g);if(void 0!==u){if("string"==typeof u&&0===u.length)throw n(l,!0);return u}const f=t[a];if(f&&"object"==typeof f&&!Array.isArray(f))return i(f,[a]);if(void 0===f)return Reflect.get(s,a,c);const h=Reflect.get(s,a);if(void 0===h||""===h)throw n(l,""===h);return h}})}static instance(...t){if(!L._instance){const e=L.factory(...t),r=new Proxy(e,{get(t,e,r){const o=Reflect.get(t,e,r);if(o!==v&&("string"!=typeof e||!Object.prototype.hasOwnProperty.call(t,e)||void 0!==o)){if(void 0!==o)return o;if("string"==typeof e){if("app"===e)return;return L.buildEnvProxy(void 0,[e])}return o}}});L._instance=r}return L._instance}accumulate(t){return super.accumulate(t),this}static accumulate(t){const e=L.instance();return Object.keys(e).forEach((t=>{const r=Object.getOwnPropertyDescriptor(e,t);r&&r.configurable&&r.enumerable&&Object.defineProperty(e,t,{...r,enumerable:!1})})),e.accumulate(t),e}static get(t){return L._instance.get(t)}static buildEnvProxy(t,e){const r=t=>t.map((t=>h(t))).join(s);return new Proxy({},{get(o,n){if(n===Symbol.toPrimitive)return()=>r(e);if("toString"===n)return()=>r(e);if("valueOf"===n)return()=>r(e);if("symbol"==typeof n)return;const s=!!t&&Object.prototype.hasOwnProperty.call(t,n),i=s?t[n]:void 0,a=[...e,n],c=(l=r(a),L.readRuntimeEnv(l));var l;return void 0!==c?L.parseRuntimeValue(c):i&&"object"==typeof i?L.buildEnvProxy(i,a):s&&""===i||s&&void 0===i?void 0:L.buildEnvProxy(void 0,a)},ownKeys:()=>t?Reflect.ownKeys(t):[],getOwnPropertyDescriptor(e,r){if(t)return Object.prototype.hasOwnProperty.call(t,r)?{enumerable:!0,configurable:!0}:void 0}})}static keys(t=!0){return L.instance().keys().map((e=>t?h(e):e))}static mergeModel(t,e,r){if(t){if(r&&"object"==typeof r&&!Array.isArray(r)){const o=t[e],n=o&&"object"==typeof o&&!Array.isArray(o)?o:{};return t[e]=n,void Object.entries(r).forEach((([t,e])=>{L.mergeModel(n,t,e)}))}t[e]=r}}static readRuntimeEnv(t){if(m()){const e=globalThis[n];return e?e[t]:void 0}return globalThis?.process?.env?.[t]}static missingEnvError(t,e){return Error(`Environment variable ${t} is required but was ${e?"an empty string":"undefined"}.`)}}const x=L.accumulate(Object.assign({app:void 0},u,{env:(m()&&globalThis[n]?globalThis[n].NODE_ENV:globalThis.process.env.NODE_ENV)||"development"}));function _(t){if("function"!=typeof t)return!1;try{const e=Function.prototype.toString.call(t);if(/^\s*class[\s{]/.test(e))return!0}catch{}const e=Object.getOwnPropertyDescriptor(t,"prototype");if(!e||!e.value)return!1;if(!1===e.writable)return!0;const r=t.prototype;return!!Object.prototype.hasOwnProperty.call(r,"constructor")&&Object.getOwnPropertyNames(r).filter((t=>"constructor"!==t)).length>0}function O(t){return"function"==typeof t&&!_(t)}function E(t){if(!O(t))return!1;const e=Object.getOwnPropertyDescriptor(t,"prototype");return!e||void 0===e.value}function j(t){if(null===t||"object"!=typeof t)return!1;const e=t.constructor;return!(!e||e===Object)&&_(e)}function M(t){if(null===t)return"null";if(void 0===t)return"undefined";if("string"==typeof t)return t;if(_(t))return t.name||"AnonymousClass";if(j(t)){const e=t.toString;if("function"==typeof e&&e!==Object.prototype.toString)try{const r=e.call(t);if("string"==typeof r&&r.length)return r}catch{}const r=t.constructor;return r&&r.name?r.name:"AnonymousInstance"}if(E(t)||O(t)){const e=t;return e.name?e.name:"anonymous"}if("object"==typeof t){const e=Object.prototype.toString.call(t),r=/^\[object ([^\]]+)\]$/.exec(e);return r?.[1]?r[1]:"Object"}return typeof t}const A=Symbol("MiniLoggerRootContext");class P{constructor(t,e,r=[]){this.conf=e,this.baseContext=Array.isArray(r)?[...r]:[],t&&this.baseContext.push(t),this.context=[...this.baseContext],this[A]=[...this.baseContext]}config(t){return this.conf&&t in this.conf?this.conf[t]:C.getConfig()[t]}for(t,e,...r){let o,n=e;const s=Array.isArray(this.context)?[...this.context]:"string"==typeof this.context&&this.context?[this.context]:[],i=this[A],a=Array.isArray(i)?[...i]:Array.isArray(this.baseContext)?[...this.baseContext]:[];"string"==typeof t?o=t:void 0!==t&&(_(t)||j(t)||O(t)?o=M(t):!n&&t&&"object"==typeof t&&(n=t));let c=o?[...s,o]:[...s];return new Proxy(this,{get:(t,e,r)=>{const o=Reflect.get(t,e,r);return"config"===e?new Proxy(this.config,{apply:(t,e,o)=>{const[s]=o;return n&&void 0!==s&&s in n?n[s]:Reflect.apply(t,r,o)},get:(t,e)=>n&&e in n?n[e]:Reflect.get(t,e,r)}):"clear"===e?()=>(c=[...a],n=void 0,r):"context"===e?c:"root"===e?[...a]:e===A?a:"for"===e?(...e)=>{const r=Array.isArray(t.context)?[...t.context]:"string"==typeof t.context&&t.context?[t.context]:[];t.context=[...c];try{return t.for.apply(t,e)}finally{t.context=r}}:o}})}createLog(t,e,r,o){const n={},s=this.config("style"),i=this.config("separator"),a=C.getConfig().app;if(a&&(n.app=s?C.theme(a,"app",t):a),i&&(n.separator=s?C.theme(i,"separator",t):i),this.config("timestamp")){const e=(new Date).toISOString(),r=s?C.theme(e,"timestamp",t):e;n.timestamp=r}if(this.config("logLevel")){const e=s?C.theme(t,"logLevel",t):t;n.level=e.toUpperCase()}if(this.config("context")){const e=Array.isArray(this.context)?this.context:"string"==typeof this.context&&this.context?[this.context]:[];if(e.length){const r=e.join(this.config("contextSeparator")||"."),o=s?C.theme(r,"class",t):r;n.context=o}}if(this.config("correlationId")){const e=s?C.theme(this.config("correlationId").toString(),"id",t):this.config("correlationId").toString();n.correlationId=e}const c=s?C.theme("string"==typeof e?e:e.message,"message",t):"string"==typeof e?e:e.message;n.message=c;const l=this.config("meta")&&o?o:void 0,g=l?this.formatMeta(l):void 0;if(l&&(n.meta=l),r||e instanceof Error){const o=s?C.theme(r?.stack||e.stack,"stack",t):r?.stack||"";n.stack=` | ${(r||e).message} - Stack trace:\n${o}`}switch(this.config("format")){case"json":return JSON.stringify(n);case"raw":{const t=this.config("pattern").split(" ").map((t=>{if(!t.match(/\{.*?}/g))return t;const e=b(t,n);return e!==t?e:void 0})).filter((t=>t)).join(" ");return g?`${t} ${g}`:t}default:throw Error("Unsupported logging format: "+this.config("format"))}}formatMeta(t){try{return JSON.stringify(t)}catch(e){return t+""}}log(e,r,o,n){const s=this.config("level");if(c[e]>c[s])return;let i;switch(e){case t.LogLevel.benchmark:case t.LogLevel.info:case t.LogLevel.verbose:i=console.log;break;case t.LogLevel.debug:i=console.debug;break;case t.LogLevel.error:i=console.error;break;case t.LogLevel.trace:i=console.trace;break;case t.LogLevel.warn:i=console.warn;break;case t.LogLevel.silly:i=console.debug;break;default:throw Error("Invalid log level")}i(this.createLog(e,r,o,n))}benchmark(e,r){this.log(t.LogLevel.benchmark,e,void 0,r)}silly(e,r=0,o){const n="number"==typeof r?r:0,s="number"==typeof r?o:r;this.config("verbose")<n||this.log(t.LogLevel.silly,e,void 0,s)}verbose(e,r=0,o){const n="number"==typeof r?r:0,s="number"==typeof r?o:r;this.config("verbose")<n||this.log(t.LogLevel.verbose,e,void 0,s)}info(e,r){this.log(t.LogLevel.info,e,void 0,r)}debug(e,r){this.log(t.LogLevel.debug,e,void 0,r)}error(e,r,o){let n,s;r instanceof Error?(n=r,s=o):s=r,this.log(t.LogLevel.error,e,n,s)}warn(e,r){this.log(t.LogLevel.warn,e,void 0,r)}trace(e,r){this.log(t.LogLevel.trace,e,void 0,r)}setConfig(t){this.conf={...this.conf||{},...t}}get root(){return[...this.baseContext]}clear(){return this.context=[...this.baseContext],this}}class C{static{this._factory=(t,e)=>{const r="string"==typeof x.app?[x.app]:[];return new P(t,e,r)}}static{this._config=x}constructor(){}static setFactory(t){C._factory=t,this.global=void 0}static setConfig(t){Object.entries(t).forEach((([t,e])=>{this._config[t]=e}))}static getConfig(){return this._config}static get(){return this.ensureRoot()}static verbose(t,e=0,r){return this.get().verbose(t,e,r)}static info(t,e){return this.get().info(t,e)}static trace(t,e){return this.get().trace(t,e)}static debug(t,e){return this.get().debug(t,e)}static benchmark(t,e){return this.get().benchmark(t,e)}static silly(t,e=0,r){return this.get().silly(t,e,r)}static warn(t,e){return this.get().warn(t,e)}static error(t,e,r){return this.get().error(t,e,r)}static for(t,e,...r){const o=void 0!==e?[t,e]:[t];return(this.global?this.global:this.ensureRoot(r)).for(...o)}static because(t,e){let r=this.ensureRoot().for(t,this._config);return e&&(r=r.for(e)),r}static baseContext(){const t=this._config.app;return"string"==typeof t&&t.length?[t]:[]}static attachRootContext(t){const e=t.root&&Array.isArray(t.root)?[...t.root]:this.baseContext();return(!t.context||Array.isArray(t.context)&&0===t.context.length)&&(t.context=[...e]),t[A]=[...e],t}static ensureRoot(t=[]){if(!this.global){const e=this._factory(void 0,void 0,...t);this.global=this.attachRootContext(e)}return this.global}static theme(r,o,n,s=g){if(!this._config.style)return r;const i=s[o];if(!i||!Object.keys(i).length)return r;let a=i;const c=Object.assign({},t.LogLevel);return Object.keys(i)[0]in c&&(a=i[n]||{}),Object.keys(a).reduce(((t,r)=>{const o=a[r];return o?((t,r,o)=>{try{const n=t;let s=e.style(n);function i(t,r=!1){let i=r?s.background:s.foreground;if(!Array.isArray(t))return i.call(s,o);switch(t.length){case 1:return i=r?s.bgColor256:s.color256,i(t[0]);case 3:return i=r?s.bgRgb:s.rgb,s.rgb(t[0],t[1],t[2]);default:return e.style(n)}}function a(t){s="number"==typeof t?s.style(t):s[t]}switch(r){case"bg":case"fg":return i(o).text;case"style":return Array.isArray(o)?o.forEach(a):a(o),s.text;default:return n}}catch(c){return t}})(t,r,o):t}),r)}}class k{get log(){return this._log||(this._log=C.for(this)),this._log}constructor(){}}class S extends k{get log(){return super.log.for(this,{filters:[]})}}const R="undefined"!=typeof globalThis&&"function"==typeof globalThis.performance?.now?()=>globalThis.performance.now():"undefined"!=typeof process&&"function"==typeof process.hrtime?.bigint?()=>{const t=process.hrtime.bigint();return Number(t)/1e6}:()=>Date.now();function $(t){const e=0>t?"-":"",r=Math.abs(t),o=Math.floor(r/36e5),n=Math.floor(r%36e5/6e4),s=Math.floor(r%6e4/1e3),i=Math.floor(r%1e3),a=(t,e)=>t.toString().padStart(e,"0");return`${e}${a(o,2)}:${a(n,2)}:${a(s,2)}.${a(i,3)}`}function T(e=t.LogLevel.info,r=0,o=(...t)=>"called with "+t,n){return(t,s,i)=>{if(!i||"number"==typeof i)throw Error("Logging decoration only applies to methods");const a=t instanceof k?t.log.for(t[s]):C.for(t).for(t[s]),c=a[e].bind(a),l=i.value;return i.value=new Proxy(l,{apply(t,e,s){c(o(...s),r);try{const r=Reflect.apply(t,e,s);return r instanceof Promise?r.then((t=>(n&&c(n(void 0,t)),t))).catch((t=>{throw n&&a.error(n(t)),t})):(n&&c(n(void 0,r)),r)}catch(t){throw n&&a.error(n(t)),t}}}),i}}function N(){return(t,e,r)=>{if(!r)throw Error("final decorator can only be used on methods");return r?.configurable&&(r.configurable=!1),r}}class I extends S{constructor(t,e){super(),this.regexp=t,this.replacement=e}match(t){const e=this.regexp.exec(t);return this.regexp.lastIndex=0,e}filter(t,e,r){const o=this.log.for(this.filter);if(!this.match(e))return e;try{return e.replace(this.regexp,this.replacement)}catch(t){o.error("PatternFilter replacement error: "+t)}return""}}o.__decorate([N(),o.__metadata("design:type",Function),o.__metadata("design:paramtypes",[String]),o.__metadata("design:returntype",void 0)],I.prototype,"match",null),t.BrowserEnvKey=n,t.DefaultLoggingConfig=u,t.DefaultPlaceholderWrappers=i,t.DefaultTheme=g,t.ENV_PATH_DELIMITER=s,t.Environment=L,t.LogFilter=S,t.LoggedClass=k,t.LoggedEnvironment=x,t.Logging=C,t.MiniLogger=P,t.NumericLogLevels=c,t.PACKAGE_NAME="##PACKAGE##",t.PatternFilter=I,t.ROOT_CONTEXT_SYMBOL=A,t.StopWatch=class{constructor(t=!1){this._startMs=null,this._elapsedMs=0,this._running=!1,this._laps=[],this._lastLapTotalMs=0,t&&this.start()}get running(){return this._running}get elapsedMs(){return this._running&&null!=this._startMs?this._elapsedMs+(R()-this._startMs):this._elapsedMs}start(){return this._running||(this._running=!0,this._startMs=R()),this}pause(){return this._running&&null!=this._startMs&&(this._elapsedMs+=R()-this._startMs,this._startMs=null,this._running=!1),this}resume(){return this._running||(this._running=!0,this._startMs=R()),this}stop(){return this.pause(),this._elapsedMs}reset(){const t=this._running;return this._startMs=t?R():null,this._elapsedMs=0,this._laps=[],this._lastLapTotalMs=0,this}lap(t){const e=this.elapsedMs,r=e-this._lastLapTotalMs,o={index:this._laps.length,label:t,ms:r,totalMs:e};return this._laps.push(o),this._lastLapTotalMs=e,o}get laps(){return this._laps}toString(){return $(this.elapsedMs)}toJSON(){return{running:this._running,elapsedMs:this.elapsedMs,laps:this._laps.slice()}}},t.VERSION="##VERSION##",t.benchmark=()=>(t,e,r)=>{if(!r||"number"==typeof r)throw Error("benchmark decoration only applies to methods");const o=t instanceof k?t.log.for(t[e]):C.for(t).for(t[e]),n=r.value;return r.value=new Proxy(n,{apply(t,e,r){const n=R();try{const s=Reflect.apply(t,e,r);return s instanceof Promise?s.then((t=>(o.benchmark(`completed in ${R()-n}ms`),t))).catch((t=>{throw o.benchmark(`failed in ${R()-n}ms`),t})):(o.benchmark(`completed in ${R()-n}ms`),s)}catch(t){throw o.benchmark(`failed in ${R()-n}ms`),t}}}),r},t.debug=()=>T(t.LogLevel.debug,0,((...t)=>"called with "+t),((t,e)=>t?"Failed with: "+t:e?"Completed with "+JSON.stringify(e):"completed")),t.escapeRegExp=y,t.final=N,t.formatMs=$,t.getObjectName=M,t.info=()=>T(t.LogLevel.info),t.isBrowser=m,t.isClass=_,t.isFunction=O,t.isInstance=j,t.isMethod=E,t.log=T,t.now=R,t.padEnd=(t,e,r=" ")=>{if(1!==r.length)throw Error("Invalid character length for padding. must be one!");return t.padEnd(e,r)},t.patchPlaceholders=(t,e,r=i[0],o=i[1],n="g")=>f(t,Object.entries(e).reduce(((t,[e,n])=>(t[`${r}${e}${o}`]=n,t)),{}),n),t.patchString=f,t.sf=b,t.silly=()=>T(t.LogLevel.silly),t.stringFormat=d,t.toCamelCase=t=>t.replace(/(?:^\w|[A-Z]|\b\w)/g,((t,e)=>0===e?t.toLowerCase():t.toUpperCase())).replace(/\s+/g,""),t.toENVFormat=h,t.toKebabCase=t=>t.replace(/([a-z])([A-Z])/g,"$1-$2").replace(/[\s_]+/g,"-").toLowerCase(),t.toPascalCase=t=>t.replace(/(?:^\w|[A-Z]|\b\w)/g,(t=>t.toUpperCase())).replace(/\s+/g,""),t.toSnakeCase=p,t.trace=()=>T(t.LogLevel.trace),t.verbose=(e=0)=>(e||(e=0),T(t.LogLevel.verbose,e)),Object.keys(e).forEach((r=>{"default"===r||t.hasOwnProperty(r)||Object.defineProperty(t,r,{enumerable:!0,get:()=>e[r]})}))},"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("styled-string-builder"),require("typed-object-accumulator"),require("tslib")):"function"==typeof define&&define.amd?define(["exports","styled-string-builder","typed-object-accumulator","tslib"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).logging={},t.styledStringBuilder,t.typedObjectAccumulator,t.tslib);
2
2
  //# sourceMappingURL=logging.cjs.map