logan-logger 1.1.2 → 1.1.6

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
@@ -9,6 +9,7 @@ A universal TypeScript logging library that works consistently across all JavaSc
9
9
  ## Features
10
10
 
11
11
  - 🌐 **Universal Runtime Support** - Works in Node.js, Deno, Bun, browsers, and WebAssembly
12
+ - âš›ī¸ **Next.js Ready** - Full compatibility with App Router, Server Components, and API Routes
12
13
  - đŸĒļ **Zero Dependencies** - Core functionality with no required dependencies
13
14
  - ⚡ **Performance First** - Lazy evaluation, zero-allocation logging, minimal memory footprint
14
15
  - đŸŽ¯ **TypeScript Native** - Full type safety with comprehensive type definitions
@@ -58,6 +59,91 @@ const requestLogger = logger.child({
58
59
  requestLogger.info('Processing request', { endpoint: '/api/users' });
59
60
  ```
60
61
 
62
+ ### Next.js Integration
63
+
64
+ Logan Logger is fully compatible with Next.js 13+ App Router, including Server Components, Client Components, and API Routes.
65
+
66
+ #### Server Components
67
+ ```typescript
68
+ import { createLogger, LogLevel } from 'logan-logger';
69
+
70
+ const logger = createLogger({
71
+ level: process.env.NODE_ENV === 'development' ? LogLevel.DEBUG : LogLevel.INFO,
72
+ format: 'json'
73
+ });
74
+
75
+ export default async function ServerComponent() {
76
+ logger.info('Server component rendered');
77
+
78
+ // Server-side data fetching
79
+ const data = await fetchData();
80
+ logger.debug('Data fetched', { recordCount: data.length });
81
+
82
+ return <div>Server content</div>;
83
+ }
84
+ ```
85
+
86
+ #### Client Components
87
+ ```typescript
88
+ 'use client';
89
+
90
+ import { createLogger, LogLevel } from 'logan-logger';
91
+
92
+ const logger = createLogger({
93
+ level: LogLevel.INFO,
94
+ colorize: true
95
+ });
96
+
97
+ export default function ClientComponent() {
98
+ const handleClick = () => {
99
+ logger.info('User interaction', { action: 'button_click' });
100
+ };
101
+
102
+ return <button onClick={handleClick}>Click me</button>;
103
+ }
104
+ ```
105
+
106
+ #### API Routes
107
+ ```typescript
108
+ // app/api/users/route.ts
109
+ import { NextResponse } from 'next/server';
110
+ import { createLogger } from 'logan-logger';
111
+
112
+ const logger = createLogger({
113
+ format: 'json',
114
+ metadata: { service: 'api' }
115
+ });
116
+
117
+ export async function GET() {
118
+ const start = Date.now();
119
+ logger.info('API request started', { endpoint: '/api/users' });
120
+
121
+ try {
122
+ const users = await getUsers();
123
+ const duration = Date.now() - start;
124
+
125
+ logger.info('API request completed', {
126
+ statusCode: 200,
127
+ duration,
128
+ userCount: users.length
129
+ });
130
+
131
+ return NextResponse.json(users);
132
+ } catch (error) {
133
+ const duration = Date.now() - start;
134
+ logger.error('API request failed', {
135
+ statusCode: 500,
136
+ duration,
137
+ error: error instanceof Error ? error.message : 'Unknown error'
138
+ });
139
+
140
+ return NextResponse.json({ error: 'Internal Server Error' }, { status: 500 });
141
+ }
142
+ }
143
+ ```
144
+
145
+ > **📋 See [Next.js Compatibility Guide](./docs/nextjs-compatibility.md) for complete setup instructions, advanced patterns, and troubleshooting.**
146
+
61
147
  ### Advanced Features
62
148
 
63
149
  #### Lazy Evaluation for Performance
@@ -150,6 +236,7 @@ logger.info('User processed', safeData);
150
236
 
151
237
  | Runtime | Import Path | Status | Implementation | Features |
152
238
  |---------|-------------|--------|----------------|----------|
239
+ | **Next.js 13+** | `logan-logger` | ✅ **Full** | **Auto-detection** | **Server/Client Components, API Routes, Edge Runtime** |
153
240
  | Node.js 20+ | `logan-logger/node` | ✅ Full | Winston + Console | File logging, transports, Morgan integration |
154
241
  | Bun | `logan-logger/bun` | ✅ Full | NodeLogger adapter | Same as Node.js |
155
242
  | Browser | `logan-logger/browser` | ✅ Full | Console API | CSS styling, performance marks, grouping |
@@ -0,0 +1 @@
1
+ "use strict";var n=(t=>(t[t.DEBUG=0]="DEBUG",t[t.INFO=1]="INFO",t[t.WARN=2]="WARN",t[t.ERROR=3]="ERROR",t[t.SILENT=4]="SILENT",t))(n||{});function f(){const t=c(),e=m(t),o=g(t);return{name:t,version:e,capabilities:o}}function c(){return typeof globalThis.Deno<"u"?"deno":typeof globalThis.Bun<"u"?"bun":typeof window<"u"&&typeof document<"u"?"browser":typeof globalThis.importScripts=="function"&&typeof window>"u"?"webworker":typeof process<"u"&&process.versions&&process.versions.node?"node":"unknown"}function m(t){switch(t){case"node":return typeof process<"u"?process.version:void 0;case"deno":return typeof globalThis.Deno<"u"?globalThis.Deno.version?.deno:void 0;case"bun":return typeof globalThis.Bun<"u"?globalThis.Bun.version:void 0;case"browser":return typeof navigator<"u"?navigator.userAgent:void 0;default:return}}function g(t){switch(t){case"node":return{fileSystem:!0,colorSupport:!0,processInfo:!0,streams:!0};case"deno":return{fileSystem:!0,colorSupport:!0,processInfo:!0,streams:!0};case"bun":return{fileSystem:!0,colorSupport:!0,processInfo:!0,streams:!0};case"browser":return{fileSystem:!1,colorSupport:!0,processInfo:!1,streams:!1};case"webworker":return{fileSystem:!1,colorSupport:!1,processInfo:!1,streams:!1};default:return{fileSystem:!1,colorSupport:!1,processInfo:!1,streams:!1}}}function h(){return c()==="node"}function y(){return c()==="browser"}function b(){return c()==="deno"}function w(){return c()==="bun"}class l{constructor(e={}){this.childMetadata={},this.config=e,this.level=e.level??n.INFO,this.runtime=f().name}debug(e,o){this.log(n.DEBUG,e,o)}info(e,o){this.log(n.INFO,e,o)}warn(e,o){this.log(n.WARN,e,o)}error(e,o){this.log(n.ERROR,e,o)}log(e,o,s){if(!this.shouldLog(e))return;const r=typeof o=="function"?o():o,i={...this.childMetadata,...s},a={timestamp:new Date,level:e,message:r,metadata:Object.keys(i).length>0?i:void 0,runtime:this.runtime};this.writeLog(a)}setLevel(e){this.level=e}getLevel(){return this.level}child(e){const o=this.createChild();return o.childMetadata={...this.childMetadata,...e},o}shouldLog(e){return e>=this.level}}function d(t,e){const o=new WeakSet;return JSON.stringify(t,(s,r)=>{if(typeof r=="object"&&r!==null){if(o.has(r))return"[Circular]";o.add(r)}return r instanceof Error?{name:r.name,message:r.message,stack:r.stack,...Object.getOwnPropertyNames(r).reduce((i,a)=>(a!=="name"&&a!=="message"&&a!=="stack"&&(i[a]=r[a]),i),{})}:typeof r=="function"?`[Function: ${r.name||"anonymous"}]`:r===void 0?"[undefined]":typeof r=="bigint"?`[BigInt: ${r.toString()}]`:typeof r=="symbol"?`[Symbol: ${r.toString()}]`:r},e)}function p(t,e=["password","token","secret","key","auth"]){if(typeof t!="object"||t===null)return t;const o=Array.isArray(t)?[]:{};for(const[s,r]of Object.entries(t))e.some(a=>s.toLowerCase().includes(a.toLowerCase()))?o[s]="[REDACTED]":typeof r=="object"&&r!==null?o[s]=p(r,e):o[s]=r;return o}function S(t){return t instanceof Error?{name:t.name,message:t.message,stack:t.stack,...t}:t}class u extends l{constructor(e={}){super(e)}writeLog(e){const o=this.formatMessage(e),s=this.getConsoleStyle(e.level),r=e.metadata?` ${d(e.metadata)}`:"",i=`%c${o}${r}`;switch(e.level){case n.DEBUG:console.debug?console.debug(i,s):console.log(i,s);break;case n.INFO:console.info(i,s);break;case n.WARN:console.warn(i,s);break;case n.ERROR:console.error(i,s);break}}createChild(){return new u(this.config)}formatMessage(e){const o=e.timestamp.toISOString(),s=n[e.level].toUpperCase();return`[${o}] ${s}: ${e.message}`}getConsoleStyle(e){if(!this.config.colorize)return"";switch(e){case n.DEBUG:return"color: #888; font-weight: normal;";case n.INFO:return"color: #007acc; font-weight: normal;";case n.WARN:return"color: #ff8c00; font-weight: bold;";case n.ERROR:return"color: #dc3545; font-weight: bold;";default:return""}}shouldLogInProduction(){return(globalThis.process?.env?.NODE_ENV||globalThis.process?.env?.NEXT_PUBLIC_APP_ENV||"development")!=="production"||this.level<=n.ERROR}shouldLog(e){return!this.shouldLogInProduction()&&e<n.ERROR?!1:super.shouldLog(e)}}class R extends u{constructor(){super(...arguments),this.groupStack=[]}group(e){console.group(e),this.groupStack.push(e)}groupCollapsed(e){console.groupCollapsed(e),this.groupStack.push(e)}groupEnd(){console.groupEnd(),this.groupStack.pop()}getCurrentGroupStack(){return[...this.groupStack]}getCurrentGroupPath(){return this.groupStack.join(" > ")}time(e){console.time(e)}timeEnd(e){console.timeEnd(e)}trace(e,o){console.trace(e,o)}count(e){console.count(e)}countReset(e){console.countReset(e)}table(e){console.table(e)}}class k extends u{mark(e){typeof performance<"u"&&performance.mark&&performance.mark(e)}measure(e,o,s){if(typeof performance<"u"&&performance.measure)try{performance.measure(e,o,s);const r=performance.getEntriesByName(e,"measure");if(r.length>0){const i=r[r.length-1];this.info(`Performance: ${e}`,{duration:i.duration,startTime:i.startTime})}}catch(r){this.warn("Failed to measure performance",{name:e,error:r})}}clearMarks(e){typeof performance<"u"&&performance.clearMarks&&performance.clearMarks(e)}clearMeasures(e){typeof performance<"u"&&performance.clearMeasures&&performance.clearMeasures(e)}}exports.BaseLogger=l;exports.BrowserLogger=u;exports.ConsoleGroupLogger=R;exports.LogLevel=n;exports.PerformanceLogger=k;exports.detectRuntime=f;exports.filterSensitiveData=p;exports.isBrowser=y;exports.isBun=w;exports.isDeno=b;exports.isNode=h;exports.safeStringify=d;exports.serializeError=S;
@@ -0,0 +1,293 @@
1
+ var n = /* @__PURE__ */ ((t) => (t[t.DEBUG = 0] = "DEBUG", t[t.INFO = 1] = "INFO", t[t.WARN = 2] = "WARN", t[t.ERROR = 3] = "ERROR", t[t.SILENT = 4] = "SILENT", t))(n || {});
2
+ function f() {
3
+ const t = c(), e = l(t), o = d(t);
4
+ return {
5
+ name: t,
6
+ version: e,
7
+ capabilities: o
8
+ };
9
+ }
10
+ function c() {
11
+ return typeof globalThis.Deno < "u" ? "deno" : typeof globalThis.Bun < "u" ? "bun" : typeof window < "u" && typeof document < "u" ? "browser" : typeof globalThis.importScripts == "function" && typeof window > "u" ? "webworker" : typeof process < "u" && process.versions && process.versions.node ? "node" : "unknown";
12
+ }
13
+ function l(t) {
14
+ switch (t) {
15
+ case "node":
16
+ return typeof process < "u" ? process.version : void 0;
17
+ case "deno":
18
+ return typeof globalThis.Deno < "u" ? globalThis.Deno.version?.deno : void 0;
19
+ case "bun":
20
+ return typeof globalThis.Bun < "u" ? globalThis.Bun.version : void 0;
21
+ case "browser":
22
+ return typeof navigator < "u" ? navigator.userAgent : void 0;
23
+ default:
24
+ return;
25
+ }
26
+ }
27
+ function d(t) {
28
+ switch (t) {
29
+ case "node":
30
+ return {
31
+ fileSystem: !0,
32
+ colorSupport: !0,
33
+ processInfo: !0,
34
+ streams: !0
35
+ };
36
+ case "deno":
37
+ return {
38
+ fileSystem: !0,
39
+ colorSupport: !0,
40
+ processInfo: !0,
41
+ streams: !0
42
+ };
43
+ case "bun":
44
+ return {
45
+ fileSystem: !0,
46
+ colorSupport: !0,
47
+ processInfo: !0,
48
+ streams: !0
49
+ };
50
+ case "browser":
51
+ return {
52
+ fileSystem: !1,
53
+ colorSupport: !0,
54
+ // CSS styling in console
55
+ processInfo: !1,
56
+ streams: !1
57
+ };
58
+ case "webworker":
59
+ return {
60
+ fileSystem: !1,
61
+ colorSupport: !1,
62
+ processInfo: !1,
63
+ streams: !1
64
+ };
65
+ default:
66
+ return {
67
+ fileSystem: !1,
68
+ colorSupport: !1,
69
+ processInfo: !1,
70
+ streams: !1
71
+ };
72
+ }
73
+ }
74
+ function h() {
75
+ return c() === "node";
76
+ }
77
+ function y() {
78
+ return c() === "browser";
79
+ }
80
+ function b() {
81
+ return c() === "deno";
82
+ }
83
+ function w() {
84
+ return c() === "bun";
85
+ }
86
+ class p {
87
+ constructor(e = {}) {
88
+ this.childMetadata = {}, this.config = e, this.level = e.level ?? n.INFO, this.runtime = f().name;
89
+ }
90
+ debug(e, o) {
91
+ this.log(n.DEBUG, e, o);
92
+ }
93
+ info(e, o) {
94
+ this.log(n.INFO, e, o);
95
+ }
96
+ warn(e, o) {
97
+ this.log(n.WARN, e, o);
98
+ }
99
+ error(e, o) {
100
+ this.log(n.ERROR, e, o);
101
+ }
102
+ log(e, o, s) {
103
+ if (!this.shouldLog(e))
104
+ return;
105
+ const r = typeof o == "function" ? o() : o, i = { ...this.childMetadata, ...s }, a = {
106
+ timestamp: /* @__PURE__ */ new Date(),
107
+ level: e,
108
+ message: r,
109
+ metadata: Object.keys(i).length > 0 ? i : void 0,
110
+ runtime: this.runtime
111
+ };
112
+ this.writeLog(a);
113
+ }
114
+ setLevel(e) {
115
+ this.level = e;
116
+ }
117
+ getLevel() {
118
+ return this.level;
119
+ }
120
+ child(e) {
121
+ const o = this.createChild();
122
+ return o.childMetadata = { ...this.childMetadata, ...e }, o;
123
+ }
124
+ shouldLog(e) {
125
+ return e >= this.level;
126
+ }
127
+ }
128
+ function m(t, e) {
129
+ const o = /* @__PURE__ */ new WeakSet();
130
+ return JSON.stringify(t, (s, r) => {
131
+ if (typeof r == "object" && r !== null) {
132
+ if (o.has(r))
133
+ return "[Circular]";
134
+ o.add(r);
135
+ }
136
+ return r instanceof Error ? {
137
+ name: r.name,
138
+ message: r.message,
139
+ stack: r.stack,
140
+ ...Object.getOwnPropertyNames(r).reduce((i, a) => (a !== "name" && a !== "message" && a !== "stack" && (i[a] = r[a]), i), {})
141
+ } : typeof r == "function" ? `[Function: ${r.name || "anonymous"}]` : r === void 0 ? "[undefined]" : typeof r == "bigint" ? `[BigInt: ${r.toString()}]` : typeof r == "symbol" ? `[Symbol: ${r.toString()}]` : r;
142
+ }, e);
143
+ }
144
+ function g(t, e = ["password", "token", "secret", "key", "auth"]) {
145
+ if (typeof t != "object" || t === null)
146
+ return t;
147
+ const o = Array.isArray(t) ? [] : {};
148
+ for (const [s, r] of Object.entries(t))
149
+ e.some(
150
+ (a) => s.toLowerCase().includes(a.toLowerCase())
151
+ ) ? o[s] = "[REDACTED]" : typeof r == "object" && r !== null ? o[s] = g(r, e) : o[s] = r;
152
+ return o;
153
+ }
154
+ function S(t) {
155
+ return t instanceof Error ? {
156
+ name: t.name,
157
+ message: t.message,
158
+ stack: t.stack,
159
+ ...t
160
+ // Include any additional properties
161
+ } : t;
162
+ }
163
+ class u extends p {
164
+ constructor(e = {}) {
165
+ super(e);
166
+ }
167
+ writeLog(e) {
168
+ const o = this.formatMessage(e), s = this.getConsoleStyle(e.level), r = e.metadata ? ` ${m(e.metadata)}` : "", i = `%c${o}${r}`;
169
+ switch (e.level) {
170
+ case n.DEBUG:
171
+ console.debug ? console.debug(i, s) : console.log(i, s);
172
+ break;
173
+ case n.INFO:
174
+ console.info(i, s);
175
+ break;
176
+ case n.WARN:
177
+ console.warn(i, s);
178
+ break;
179
+ case n.ERROR:
180
+ console.error(i, s);
181
+ break;
182
+ }
183
+ }
184
+ createChild() {
185
+ return new u(this.config);
186
+ }
187
+ formatMessage(e) {
188
+ const o = e.timestamp.toISOString(), s = n[e.level].toUpperCase();
189
+ return `[${o}] ${s}: ${e.message}`;
190
+ }
191
+ getConsoleStyle(e) {
192
+ if (!this.config.colorize)
193
+ return "";
194
+ switch (e) {
195
+ case n.DEBUG:
196
+ return "color: #888; font-weight: normal;";
197
+ case n.INFO:
198
+ return "color: #007acc; font-weight: normal;";
199
+ case n.WARN:
200
+ return "color: #ff8c00; font-weight: bold;";
201
+ case n.ERROR:
202
+ return "color: #dc3545; font-weight: bold;";
203
+ default:
204
+ return "";
205
+ }
206
+ }
207
+ shouldLogInProduction() {
208
+ return (globalThis.process?.env?.NODE_ENV || globalThis.process?.env?.NEXT_PUBLIC_APP_ENV || "development") !== "production" || this.level <= n.ERROR;
209
+ }
210
+ shouldLog(e) {
211
+ return !this.shouldLogInProduction() && e < n.ERROR ? !1 : super.shouldLog(e);
212
+ }
213
+ }
214
+ class R extends u {
215
+ constructor() {
216
+ super(...arguments), this.groupStack = [];
217
+ }
218
+ group(e) {
219
+ console.group(e), this.groupStack.push(e);
220
+ }
221
+ groupCollapsed(e) {
222
+ console.groupCollapsed(e), this.groupStack.push(e);
223
+ }
224
+ groupEnd() {
225
+ console.groupEnd(), this.groupStack.pop();
226
+ }
227
+ getCurrentGroupStack() {
228
+ return [...this.groupStack];
229
+ }
230
+ getCurrentGroupPath() {
231
+ return this.groupStack.join(" > ");
232
+ }
233
+ time(e) {
234
+ console.time(e);
235
+ }
236
+ timeEnd(e) {
237
+ console.timeEnd(e);
238
+ }
239
+ trace(e, o) {
240
+ console.trace(e, o);
241
+ }
242
+ count(e) {
243
+ console.count(e);
244
+ }
245
+ countReset(e) {
246
+ console.countReset(e);
247
+ }
248
+ table(e) {
249
+ console.table(e);
250
+ }
251
+ }
252
+ class k extends u {
253
+ mark(e) {
254
+ typeof performance < "u" && performance.mark && performance.mark(e);
255
+ }
256
+ measure(e, o, s) {
257
+ if (typeof performance < "u" && performance.measure)
258
+ try {
259
+ performance.measure(e, o, s);
260
+ const r = performance.getEntriesByName(e, "measure");
261
+ if (r.length > 0) {
262
+ const i = r[r.length - 1];
263
+ this.info(`Performance: ${e}`, {
264
+ duration: i.duration,
265
+ startTime: i.startTime
266
+ });
267
+ }
268
+ } catch (r) {
269
+ this.warn("Failed to measure performance", { name: e, error: r });
270
+ }
271
+ }
272
+ clearMarks(e) {
273
+ typeof performance < "u" && performance.clearMarks && performance.clearMarks(e);
274
+ }
275
+ clearMeasures(e) {
276
+ typeof performance < "u" && performance.clearMeasures && performance.clearMeasures(e);
277
+ }
278
+ }
279
+ export {
280
+ u as B,
281
+ R as C,
282
+ n as L,
283
+ k as P,
284
+ y as a,
285
+ b,
286
+ w as c,
287
+ f as d,
288
+ S as e,
289
+ g as f,
290
+ p as g,
291
+ h as i,
292
+ m as s
293
+ };