zario 0.2.6 → 0.2.9

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
@@ -1,161 +1,190 @@
1
- # zario
2
-
3
- A minimal, fast logging library for Node.js with TypeScript support.
4
-
5
- ## Installation
6
-
7
- ```bash
8
- npm install zario
9
- ```
10
-
11
- ## Quick Start
12
-
13
- ```js
14
- import { Logger } from "zario";
15
-
16
- const logger = new Logger({
17
- level: "info",
18
- colorize: true,
19
- transports: [{ type: "console" }],
20
- prefix: "[MyApp]",
21
- });
22
-
23
- // Start logging
24
- logger.info("🚀 Server started on port 3000");
25
- logger.warn("⚠️ High memory usage detected");
26
- logger.error("❌ Database connection failed", { code: 500 });
27
- ```
28
-
29
- ## API Documentation
30
-
31
- ### Logger Constructor Options
32
-
33
- | Option | Type | Description |
34
- | -------------- | -------- | ----------------------- |
35
- | **level** | `string` | Log level threshold |
36
- | **json** | `boolean`| Output in JSON format |
37
- | **timestamp** | `boolean`| Include timestamps |
38
- | **prefix** | `string` | Prepended label |
39
- | **transports** | `array` | Where logs are written (with transport-specific options like `path`, `maxSize`, `maxFiles` for file transport) |
40
- | **customLevels** | `object` | Define custom log levels and their priorities |
41
- | **customColors** | `object` | Assign colors to custom log levels |
42
-
43
- ### Log Levels
44
-
45
- | Level | Method | Use Case |
46
- |----------|---------------|----------------------------|
47
- | 🔍 DEBUG | `logger.debug()` | Detailed debugging info |
48
- | INFO | `logger.info()` | General information |
49
- | ⚠️ WARN | `logger.warn()` | Warning messages |
50
- | ERROR | `logger.error()` | Error messages |
51
- | 🤫 SILENT | `logger.silent()`| Not output to console |
52
- | 📝 BORING | `logger.boring()`| Lowest priority messages |
53
-
54
- ### Transports
55
-
56
- #### Console Transport
57
- ```js
58
- const logger = new Logger({
59
- transports: [{
60
- type: 'console',
61
- options: {
62
- colorize: true
63
- }
64
- }]
65
- });
66
- ```
67
-
68
- #### File Transport
69
- ```js
70
- const logger = new Logger({
71
- transports: [{
72
- type: 'file',
73
- options: {
74
- path: './logs/app.log',
75
- maxSize: 10485760, // 10MB in bytes
76
- maxFiles: 5
77
- }
78
- }]
79
- });
80
- ```
81
-
82
- ### Methods
83
-
84
- - `logger.debug(message, metadata?)` - Debug level logging
85
- - `logger.info(message, metadata?)` - Info level logging
86
- - `logger.warn(message, metadata?)` - Warning level logging
87
- - `logger.error(message, metadata?)` - Error level logging
88
- - `logger.createChild(options)` - Creates a child logger with inherited settings
89
- - `logger.setLevel(level)` - Change the logger level at runtime
90
- - `logger.setFormat(format)` - Set the output format to text or json
91
-
92
- ## Usage Examples
93
-
94
- ### Basic Usage
95
- ```js
96
- import { Logger } from "zario";
97
-
98
- const logger = new Logger({
99
- level: "info",
100
- colorize: true,
101
- transports: [{ type: "console" }]
102
- });
103
-
104
- logger.info("Application started");
105
- logger.error("Something went wrong", { userId: 123 });
106
- ```
107
-
108
- ### JSON Format
109
- ```js
110
- const logger = new Logger({ json: true });
111
- ```
112
-
113
- ### Custom Levels & Colors
114
- ```js
115
- import { Logger } from "zario";
116
-
117
- const logger = new Logger({
118
- level: 'info',
119
- customLevels: {
120
- 'success': 6, // Higher priority than error (5).
121
- 'verbose': 1, // Lower priority than debug (2).
122
- 'critical': 7, // Highest priority.
123
- },
124
- customColors: {
125
- 'success': 'green',
126
- 'verbose': 'cyan',
127
- 'critical': 'brightRed',
128
- },
129
- transports: [
130
- { type: 'console' }
131
- ]
132
- });
133
-
134
- // Using custom levels.
135
- logger.logWithLevel('success', 'This is a success message in green!');
136
- logger.logWithLevel('verbose', 'This is a verbose message in cyan');
137
- logger.logWithLevel('critical', 'This is a critical message in bright red');
138
- ```
139
-
140
- ### Child Loggers
141
- ```js
142
- const main = new Logger({ prefix: "[APP]" });
143
- const db = main.createChild({ prefix: "[DB]" });
144
-
145
- main.info("App initialized");
146
- db.error("Connection timeout");
147
- ```
148
-
149
- ### Multiple Transports
150
- ```js
151
- const logger = new Logger({
152
- level: 'info',
153
- transports: [
154
- { type: 'console' },
155
- {
156
- type: 'file',
157
- options: { path: './logs/app.log' }
158
- }
159
- ]
160
- });
161
- ```
1
+ # zario
2
+
3
+ A minimal, fast logging library for Node.js with TypeScript support.
4
+
5
+ ## UPDATE 2.9
6
+
7
+ - Added HTTP transport support with new HttpTransport class
8
+ - Added log batching functionality for efficient writes
9
+ - Added compression support (.gz for gzip, .zz for deflate) for rotated files
10
+ - Enhanced rotation with maxSize, maxFiles, and configurable compression
11
+
12
+ ## Installation
13
+
14
+ ```bash
15
+ npm install zario
16
+ ```
17
+
18
+ ## Quick Start
19
+
20
+ ```js
21
+ import { Logger, ConsoleTransport } from "zario";
22
+
23
+ const logger = new Logger({
24
+ level: "info",
25
+ colorize: true,
26
+ transports: [new ConsoleTransport()],
27
+ prefix: "[MyApp]",
28
+ });
29
+
30
+ // Start logging
31
+ logger.info("🚀 Server started on port 3000");
32
+ logger.warn("⚠️ High memory usage detected");
33
+ logger.error("❌ Database connection failed", { code: 500 });
34
+ ```
35
+
36
+ ## API Documentation
37
+
38
+ ### Logger Constructor Options
39
+
40
+ | Option | Type | Description |
41
+ | -------------- | -------- | ----------------------- |
42
+ | **level** | `string` | Log level threshold |
43
+ | **json** | `boolean`| Output in JSON format |
44
+ | **timestamp** | `boolean`| Include timestamps |
45
+ | **prefix** | `string` | Prepended label |
46
+ | **transports** | `array` | Where logs are written (with transport-specific options like `path`, `maxSize`, `maxFiles`, `compression`, `batchInterval`, `compressOldFiles` for file transport) |
47
+ | **customLevels** | `object` | Define custom log levels and their priorities |
48
+ | **customColors** | `object` | Assign colors to custom log levels |
49
+
50
+ ### Log Levels
51
+
52
+ | Level | Method | Use Case |
53
+ |----------|---------------|----------------------------|
54
+ | 🔍 DEBUG | `logger.debug()` | Detailed debugging info |
55
+ | ✨ INFO | `logger.info()` | General information |
56
+ | ⚠️ WARN | `logger.warn()` | Warning messages |
57
+ | ❌ ERROR | `logger.error()` | Error messages |
58
+ | 🤫 SILENT | `logger.silent()`| Not output to console |
59
+ | 📝 BORING | `logger.boring()`| Lowest priority messages |
60
+
61
+ ### Transports
62
+
63
+ #### Console Transport
64
+ ```js
65
+ import { Logger, ConsoleTransport } from "zario";
66
+
67
+ const logger = new Logger({
68
+ transports: [
69
+ new ConsoleTransport({ colorize: true })
70
+ ]
71
+ });
72
+ ```
73
+
74
+ #### File Transport
75
+ ```js
76
+ import { Logger, FileTransport } from "zario";
77
+
78
+ const logger = new Logger({
79
+ transports: [
80
+ new FileTransport({
81
+ path: './logs/app.log',
82
+ maxSize: 10485760, // 10MB in bytes
83
+ maxFiles: 5,
84
+ compression: 'gzip', // 'gzip', 'deflate', or 'none' (default: 'none')
85
+ batchInterval: 1000, // Batch interval in ms (0 to disable, default: 0)
86
+ compressOldFiles: true // Whether to compress old files during rotation (default: true)
87
+ })
88
+ ]
89
+ });
90
+ ```
91
+
92
+ #### HTTP Transport
93
+ ```js
94
+ import { Logger, HttpTransport } from "zario";
95
+
96
+ const logger = new Logger({
97
+ transports: [
98
+ new HttpTransport({
99
+ url: 'https://api.example.com/logs',
100
+ method: 'POST',
101
+ headers: {
102
+ 'Content-Type': 'application/json',
103
+ 'Authorization': 'Bearer your-token-here'
104
+ },
105
+ timeout: 10000, // Request timeout in ms
106
+ retries: 3 // Number of retry attempts
107
+ })
108
+ ]
109
+ });
110
+ ```
111
+
112
+ ### Methods
113
+
114
+ - `logger.debug(message, metadata?)` - Debug level logging
115
+ - `logger.info(message, metadata?)` - Info level logging
116
+ - `logger.warn(message, metadata?)` - Warning level logging
117
+ - `logger.error(message, metadata?)` - Error level logging
118
+ - `logger.createChild(options)` - Creates a child logger with inherited settings
119
+ - `logger.setLevel(level)` - Change the logger level at runtime
120
+ - `logger.setFormat(format)` - Set the output format to text or json
121
+
122
+ ## Usage Examples
123
+
124
+ ### Basic Usage
125
+ ```js
126
+ import { Logger, ConsoleTransport } from "zario";
127
+
128
+ const logger = new Logger({
129
+ level: "info",
130
+ colorize: true,
131
+ transports: [new ConsoleTransport()]
132
+ });
133
+
134
+ logger.info("Application started");
135
+ logger.error("Something went wrong", { userId: 123 });
136
+ ```
137
+
138
+ ### JSON Format
139
+ ```js
140
+ const logger = new Logger({ json: true });
141
+ ```
142
+
143
+ ### Custom Levels & Colors
144
+ ```js
145
+ import { Logger, ConsoleTransport } from "zario";
146
+
147
+ const logger = new Logger({
148
+ level: 'info',
149
+ customLevels: {
150
+ 'success': 6, // Higher priority than error (5).
151
+ 'verbose': 1, // Lower priority than debug (2).
152
+ 'critical': 7, // Highest priority.
153
+ },
154
+ customColors: {
155
+ 'success': 'green',
156
+ 'verbose': 'cyan',
157
+ 'critical': 'brightRed',
158
+ },
159
+ transports: [
160
+ new ConsoleTransport()
161
+ ]
162
+ });
163
+
164
+ // Using custom levels.
165
+ logger.logWithLevel('success', 'This is a success message in green!');
166
+ logger.logWithLevel('verbose', 'This is a verbose message in cyan');
167
+ logger.logWithLevel('critical', 'This is a critical message in bright red');
168
+ ```
169
+
170
+ ### Child Loggers
171
+ ```js
172
+ const main = new Logger({ prefix: "[APP]" });
173
+ const db = main.createChild({ prefix: "[DB]" });
174
+
175
+ main.info("App initialized");
176
+ db.error("Connection timeout");
177
+ ```
178
+
179
+ ### Multiple Transports
180
+ ```js
181
+ import { Logger, ConsoleTransport, FileTransport } from "zario";
182
+
183
+ const logger = new Logger({
184
+ level: 'info',
185
+ transports: [
186
+ new ConsoleTransport(),
187
+ new FileTransport({ path: './logs/app.log' })
188
+ ]
189
+ });
190
+ ```
package/README.npm.md CHANGED
@@ -1,161 +1,190 @@
1
- # zario
2
-
3
- A minimal, fast logging library for Node.js with TypeScript support.
4
-
5
- ## Installation
6
-
7
- ```bash
8
- npm install zario
9
- ```
10
-
11
- ## Quick Start
12
-
13
- ```js
14
- import { Logger } from "zario";
15
-
16
- const logger = new Logger({
17
- level: "info",
18
- colorize: true,
19
- transports: [{ type: "console" }],
20
- prefix: "[MyApp]",
21
- });
22
-
23
- // Start logging
24
- logger.info("🚀 Server started on port 3000");
25
- logger.warn("⚠️ High memory usage detected");
26
- logger.error("❌ Database connection failed", { code: 500 });
27
- ```
28
-
29
- ## API Documentation
30
-
31
- ### Logger Constructor Options
32
-
33
- | Option | Type | Description |
34
- | -------------- | -------- | ----------------------- |
35
- | **level** | `string` | Log level threshold |
36
- | **json** | `boolean`| Output in JSON format |
37
- | **timestamp** | `boolean`| Include timestamps |
38
- | **prefix** | `string` | Prepended label |
39
- | **transports** | `array` | Where logs are written (with transport-specific options like `path`, `maxSize`, `maxFiles` for file transport) |
40
- | **customLevels** | `object` | Define custom log levels and their priorities |
41
- | **customColors** | `object` | Assign colors to custom log levels |
42
-
43
- ### Log Levels
44
-
45
- | Level | Method | Use Case |
46
- |----------|---------------|----------------------------|
47
- | 🔍 DEBUG | `logger.debug()` | Detailed debugging info |
48
- | INFO | `logger.info()` | General information |
49
- | ⚠️ WARN | `logger.warn()` | Warning messages |
50
- | ERROR | `logger.error()` | Error messages |
51
- | 🤫 SILENT | `logger.silent()`| Not output to console |
52
- | 📝 BORING | `logger.boring()`| Lowest priority messages |
53
-
54
- ### Transports
55
-
56
- #### Console Transport
57
- ```js
58
- const logger = new Logger({
59
- transports: [{
60
- type: 'console',
61
- options: {
62
- colorize: true
63
- }
64
- }]
65
- });
66
- ```
67
-
68
- #### File Transport
69
- ```js
70
- const logger = new Logger({
71
- transports: [{
72
- type: 'file',
73
- options: {
74
- path: './logs/app.log',
75
- maxSize: 10485760, // 10MB in bytes
76
- maxFiles: 5
77
- }
78
- }]
79
- });
80
- ```
81
-
82
- ### Methods
83
-
84
- - `logger.debug(message, metadata?)` - Debug level logging
85
- - `logger.info(message, metadata?)` - Info level logging
86
- - `logger.warn(message, metadata?)` - Warning level logging
87
- - `logger.error(message, metadata?)` - Error level logging
88
- - `logger.createChild(options)` - Creates a child logger with inherited settings
89
- - `logger.setLevel(level)` - Change the logger level at runtime
90
- - `logger.setFormat(format)` - Set the output format to text or json
91
-
92
- ## Usage Examples
93
-
94
- ### Basic Usage
95
- ```js
96
- import { Logger } from "zario";
97
-
98
- const logger = new Logger({
99
- level: "info",
100
- colorize: true,
101
- transports: [{ type: "console" }]
102
- });
103
-
104
- logger.info("Application started");
105
- logger.error("Something went wrong", { userId: 123 });
106
- ```
107
-
108
- ### JSON Format
109
- ```js
110
- const logger = new Logger({ json: true });
111
- ```
112
-
113
- ### Custom Levels & Colors
114
- ```js
115
- import { Logger } from "zario";
116
-
117
- const logger = new Logger({
118
- level: 'info',
119
- customLevels: {
120
- 'success': 6, // Higher priority than error (5).
121
- 'verbose': 1, // Lower priority than debug (2).
122
- 'critical': 7, // Highest priority.
123
- },
124
- customColors: {
125
- 'success': 'green',
126
- 'verbose': 'cyan',
127
- 'critical': 'brightRed',
128
- },
129
- transports: [
130
- { type: 'console' }
131
- ]
132
- });
133
-
134
- // Using custom levels.
135
- logger.logWithLevel('success', 'This is a success message in green!');
136
- logger.logWithLevel('verbose', 'This is a verbose message in cyan');
137
- logger.logWithLevel('critical', 'This is a critical message in bright red');
138
- ```
139
-
140
- ### Child Loggers
141
- ```js
142
- const main = new Logger({ prefix: "[APP]" });
143
- const db = main.createChild({ prefix: "[DB]" });
144
-
145
- main.info("App initialized");
146
- db.error("Connection timeout");
147
- ```
148
-
149
- ### Multiple Transports
150
- ```js
151
- const logger = new Logger({
152
- level: 'info',
153
- transports: [
154
- { type: 'console' },
155
- {
156
- type: 'file',
157
- options: { path: './logs/app.log' }
158
- }
159
- ]
160
- });
161
- ```
1
+ # zario
2
+
3
+ A minimal, fast logging library for Node.js with TypeScript support.
4
+
5
+ ## UPDATE 2.9
6
+
7
+ - Added HTTP transport support with new HttpTransport class
8
+ - Added log batching functionality for efficient writes
9
+ - Added compression support (.gz for gzip, .zz for deflate) for rotated files
10
+ - Enhanced rotation with maxSize, maxFiles, and configurable compression
11
+
12
+ ## Installation
13
+
14
+ ```bash
15
+ npm install zario
16
+ ```
17
+
18
+ ## Quick Start
19
+
20
+ ```js
21
+ import { Logger, ConsoleTransport } from "zario";
22
+
23
+ const logger = new Logger({
24
+ level: "info",
25
+ colorize: true,
26
+ transports: [new ConsoleTransport()],
27
+ prefix: "[MyApp]",
28
+ });
29
+
30
+ // Start logging
31
+ logger.info("🚀 Server started on port 3000");
32
+ logger.warn("⚠️ High memory usage detected");
33
+ logger.error("❌ Database connection failed", { code: 500 });
34
+ ```
35
+
36
+ ## API Documentation
37
+
38
+ ### Logger Constructor Options
39
+
40
+ | Option | Type | Description |
41
+ | -------------- | -------- | ----------------------- |
42
+ | **level** | `string` | Log level threshold |
43
+ | **json** | `boolean`| Output in JSON format |
44
+ | **timestamp** | `boolean`| Include timestamps |
45
+ | **prefix** | `string` | Prepended label |
46
+ | **transports** | `array` | Where logs are written (with transport-specific options like `path`, `maxSize`, `maxFiles`, `compression`, `batchInterval`, `compressOldFiles` for file transport) |
47
+ | **customLevels** | `object` | Define custom log levels and their priorities |
48
+ | **customColors** | `object` | Assign colors to custom log levels |
49
+
50
+ ### Log Levels
51
+
52
+ | Level | Method | Use Case |
53
+ |----------|---------------|----------------------------|
54
+ | 🔍 DEBUG | `logger.debug()` | Detailed debugging info |
55
+ | ✨ INFO | `logger.info()` | General information |
56
+ | ⚠️ WARN | `logger.warn()` | Warning messages |
57
+ | ❌ ERROR | `logger.error()` | Error messages |
58
+ | 🤫 SILENT | `logger.silent()`| Not output to console |
59
+ | 📝 BORING | `logger.boring()`| Lowest priority messages |
60
+
61
+ ### Transports
62
+
63
+ #### Console Transport
64
+ ```js
65
+ import { Logger, ConsoleTransport } from "zario";
66
+
67
+ const logger = new Logger({
68
+ transports: [
69
+ new ConsoleTransport({ colorize: true })
70
+ ]
71
+ });
72
+ ```
73
+
74
+ #### File Transport
75
+ ```js
76
+ import { Logger, FileTransport } from "zario";
77
+
78
+ const logger = new Logger({
79
+ transports: [
80
+ new FileTransport({
81
+ path: './logs/app.log',
82
+ maxSize: 10485760, // 10MB in bytes
83
+ maxFiles: 5,
84
+ compression: 'gzip', // 'gzip', 'deflate', or 'none' (default: 'none')
85
+ batchInterval: 1000, // Batch interval in ms (0 to disable, default: 0)
86
+ compressOldFiles: true // Whether to compress old files during rotation (default: true)
87
+ })
88
+ ]
89
+ });
90
+ ```
91
+
92
+ #### HTTP Transport
93
+ ```js
94
+ import { Logger, HttpTransport } from "zario";
95
+
96
+ const logger = new Logger({
97
+ transports: [
98
+ new HttpTransport({
99
+ url: 'https://api.example.com/logs',
100
+ method: 'POST',
101
+ headers: {
102
+ 'Content-Type': 'application/json',
103
+ 'Authorization': 'Bearer your-token-here'
104
+ },
105
+ timeout: 10000, // Request timeout in ms
106
+ retries: 3 // Number of retry attempts
107
+ })
108
+ ]
109
+ });
110
+ ```
111
+
112
+ ### Methods
113
+
114
+ - `logger.debug(message, metadata?)` - Debug level logging
115
+ - `logger.info(message, metadata?)` - Info level logging
116
+ - `logger.warn(message, metadata?)` - Warning level logging
117
+ - `logger.error(message, metadata?)` - Error level logging
118
+ - `logger.createChild(options)` - Creates a child logger with inherited settings
119
+ - `logger.setLevel(level)` - Change the logger level at runtime
120
+ - `logger.setFormat(format)` - Set the output format to text or json
121
+
122
+ ## Usage Examples
123
+
124
+ ### Basic Usage
125
+ ```js
126
+ import { Logger, ConsoleTransport } from "zario";
127
+
128
+ const logger = new Logger({
129
+ level: "info",
130
+ colorize: true,
131
+ transports: [new ConsoleTransport()]
132
+ });
133
+
134
+ logger.info("Application started");
135
+ logger.error("Something went wrong", { userId: 123 });
136
+ ```
137
+
138
+ ### JSON Format
139
+ ```js
140
+ const logger = new Logger({ json: true });
141
+ ```
142
+
143
+ ### Custom Levels & Colors
144
+ ```js
145
+ import { Logger, ConsoleTransport } from "zario";
146
+
147
+ const logger = new Logger({
148
+ level: 'info',
149
+ customLevels: {
150
+ 'success': 6, // Higher priority than error (5).
151
+ 'verbose': 1, // Lower priority than debug (2).
152
+ 'critical': 7, // Highest priority.
153
+ },
154
+ customColors: {
155
+ 'success': 'green',
156
+ 'verbose': 'cyan',
157
+ 'critical': 'brightRed',
158
+ },
159
+ transports: [
160
+ new ConsoleTransport()
161
+ ]
162
+ });
163
+
164
+ // Using custom levels.
165
+ logger.logWithLevel('success', 'This is a success message in green!');
166
+ logger.logWithLevel('verbose', 'This is a verbose message in cyan');
167
+ logger.logWithLevel('critical', 'This is a critical message in bright red');
168
+ ```
169
+
170
+ ### Child Loggers
171
+ ```js
172
+ const main = new Logger({ prefix: "[APP]" });
173
+ const db = main.createChild({ prefix: "[DB]" });
174
+
175
+ main.info("App initialized");
176
+ db.error("Connection timeout");
177
+ ```
178
+
179
+ ### Multiple Transports
180
+ ```js
181
+ import { Logger, ConsoleTransport, FileTransport } from "zario";
182
+
183
+ const logger = new Logger({
184
+ level: 'info',
185
+ transports: [
186
+ new ConsoleTransport(),
187
+ new FileTransport({ path: './logs/app.log' })
188
+ ]
189
+ });
190
+ ```
@@ -1,11 +1,11 @@
1
1
  import { LogLevel } from "./LogLevel";
2
2
  import { Transport } from "../transports";
3
- import { TransportOptions } from "../types";
3
+ import { TransportConfig } from "../types";
4
4
  export interface LoggerOptions {
5
5
  level?: LogLevel;
6
6
  colorize?: boolean;
7
7
  json?: boolean;
8
- transports?: TransportOptions[];
8
+ transports?: TransportConfig[];
9
9
  timestampFormat?: string;
10
10
  prefix?: string;
11
11
  timestamp?: boolean;
@@ -40,6 +40,8 @@ export declare class Logger {
40
40
  private getDefaultTransports;
41
41
  private getDefaultAsyncMode;
42
42
  private initTransports;
43
+ private isLegacyTransportOptions;
44
+ private isTransport;
43
45
  private shouldLog;
44
46
  private getLevelPriority;
45
47
  private log;
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import { Logger } from './core/Logger';
2
2
  import { LogLevel } from './core/LogLevel';
3
- import { ConsoleTransport, FileTransport, Transport } from './transports';
4
- import { TransportOptions, LoggerConfig } from './types/index';
3
+ import { ConsoleTransport, FileTransport, HttpTransport, Transport, consoleT, fileT, httpT } from './transports';
4
+ import { TransportConfig, LoggerConfig } from './types/index';
5
5
  import { CustomLogLevelConfig } from './core/CustomLogLevel';
6
- export { Logger, ConsoleTransport, FileTransport };
7
- export type { LogLevel, Transport, TransportOptions, LoggerConfig, CustomLogLevelConfig };
6
+ export { Logger, ConsoleTransport, FileTransport, HttpTransport, consoleT, fileT, httpT };
7
+ export type { LogLevel, Transport, TransportConfig, LoggerConfig, CustomLogLevelConfig };
8
8
  export default Logger;
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
- "use strict";var E=Object.create;var x=Object.defineProperty;var A=Object.getOwnPropertyDescriptor;var I=Object.getOwnPropertyNames;var M=Object.getPrototypeOf,j=Object.prototype.hasOwnProperty;var $=(a,t)=>()=>(a&&(t=a(a=0)),t);var O=(a,t)=>{for(var e in t)x(a,e,{get:t[e],enumerable:!0})},P=(a,t,e,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of I(t))!j.call(a,r)&&r!==e&&x(a,r,{get:()=>t[r],enumerable:!(i=A(t,r))||i.enumerable});return a};var D=(a,t,e)=>(e=a!=null?E(M(a)):{},P(t||!a||!a.__esModule?x(e,"default",{value:a,enumerable:!0}):e,a)),w=a=>P(x({},"__esModule",{value:!0}),a);var C={};O(C,{Timer:()=>S});var S,z=$(()=>{"use strict";S=class{constructor(t,e){this.hasEnded=!1;this.name=t,this.logFn=e,this.startTime=Date.now()}end(){if(this.hasEnded)return;let e=Date.now()-this.startTime;this.logFn(`${this.name} took ${e}ms`),this.hasEnded=!0}}});var Y={};O(Y,{ConsoleTransport:()=>d,FileTransport:()=>v,Logger:()=>y,default:()=>N});module.exports=w(Y);var L=class{static format(t,e){if(e==="ISO")return t.toISOString();if(e==="UTC")return t.toUTCString();if(e==="LOCAL")return t.toLocaleString();let i=t.getFullYear(),r=t.getMonth()+1,o=t.getDate(),l=t.getHours(),p=t.getMinutes(),m=t.getSeconds(),f=t.getMilliseconds(),c=[],s=0,g=0;for(;s<e.length;)e[s]==="Y"&&s+3<e.length&&e.slice(s,s+4)==="YYYY"?(c.push(e.substring(g,s)),c.push(i.toString().padStart(4,"0")),s+=4,g=s):e[s]==="M"&&s+1<e.length&&e.slice(s,s+2)==="MM"?(c.push(e.substring(g,s)),c.push(r.toString().padStart(2,"0")),s+=2,g=s):e[s]==="D"&&s+1<e.length&&e.slice(s,s+2)==="DD"?(c.push(e.substring(g,s)),c.push(o.toString().padStart(2,"0")),s+=2,g=s):e[s]==="H"&&s+1<e.length&&e.slice(s,s+2)==="HH"?(c.push(e.substring(g,s)),c.push(l.toString().padStart(2,"0")),s+=2,g=s):e[s]==="m"&&s+1<e.length&&e.slice(s,s+2)==="mm"?(c.push(e.substring(g,s)),c.push(p.toString().padStart(2,"0")),s+=2,g=s):e[s]==="s"&&s+1<e.length&&e.slice(s,s+2)==="ss"?(c.push(e.substring(g,s)),c.push(m.toString().padStart(2,"0")),s+=2,g=s):e[s]==="S"&&s+2<e.length&&e.slice(s,s+3)==="SSS"?(c.push(e.substring(g,s)),c.push(f.toString().padStart(3,"0")),s+=3,g=s):s++;return c.push(e.substring(g)),c.join("")}};var F=class a{static{this.ANSI_COLORS={black:"\x1B[30m",red:"\x1B[31m",green:"\x1B[32m",yellow:"\x1B[33m",blue:"\x1B[34m",magenta:"\x1B[35m",cyan:"\x1B[36m",white:"\x1B[37m",brightRed:"\x1B[91m",brightGreen:"\x1B[92m",brightYellow:"\x1B[93m",brightBlue:"\x1B[94m",brightMagenta:"\x1B[95m",brightCyan:"\x1B[96m",brightWhite:"\x1B[97m",info:"\x1B[32m",warn:"\x1B[33m",error:"\x1B[31m",debug:"\x1B[36m",boring:"\x1B[37m",reset:"\x1B[0m"}}static colorize(t,e){return process.env.FORCE_COLOR!=="0"&&(process.stdout.isTTY||process.env.FORCE_COLOR==="1")?`${a.ANSI_COLORS[e]||a.ANSI_COLORS.reset}${t}${a.ANSI_COLORS.reset}`:t}};var b=class{constructor(t={}){let{colorize:e=!0,json:i=!1,timestampFormat:r="YYYY-MM-DD HH:mm:ss",timestamp:o=!1,customColors:l={}}=t;this.colorize=e,this.json=i,this.timestampFormat=r,this.timestamp=o,this.customColors=l}format(t){return this.json?this.formatAsJson(t):this.formatAsText(t)}formatAsJson(t){let e={level:t.level,message:t.message,...t.metadata};return this.timestamp&&(e.timestamp=t.timestamp.toISOString()),t.prefix&&(e.prefix=t.prefix),JSON.stringify(e)}formatAsText(t){let e=[];if(this.timestamp){let r=L.format(t.timestamp,this.timestampFormat);e.push(`[${r}] `)}t.prefix&&e.push(`${t.prefix} `);let i=t.level.toUpperCase();if(this.colorize){let r=this.customColors[t.level]||t.level;i=F.colorize(i,r)}return e.push(`[${i}] `),e.push(t.message),t.metadata&&e.push(` ${JSON.stringify(t.metadata)}`),e.join("")}setJson(t){this.json=t}isColorized(){return this.colorize}isJson(){return this.json}getTimestampFormat(){return this.timestampFormat}hasTimestamp(){return this.timestamp}getCustomColors(){return{...this.customColors}}};var d=class{constructor(t={}){let{colorize:e=!0}=t;this.colorize=e}write(t,e){let i=e.colorize;this.colorize!==i&&(e.colorize=this.colorize);let r=e.format(t);switch(this.colorize!==i&&(e.colorize=i),t.level){case"error":console.error(r);break;case"warn":console.warn(r);break;default:console.log(r);break}}async writeAsync(t,e){return setImmediate(()=>{this.write(t,e)}),Promise.resolve()}};var n=D(require("fs"),1),h=D(require("path"),1),v=class{constructor(t){let{path:e,maxSize:i=10*1024*1024,maxFiles:r=5}=t;this.filePath=e,this.maxSize=i,this.maxFiles=r;let o=h.dirname(this.filePath);n.existsSync(o)||n.mkdirSync(o,{recursive:!0}),n.existsSync(this.filePath)||n.writeFileSync(this.filePath,"","utf8")}write(t,e){let r=e.format(t)+`
2
- `;n.appendFileSync(this.filePath,r),this.rotateIfNeeded()}async writeAsync(t,e){let r=e.format(t)+`
3
- `;await new Promise((o,l)=>{n.appendFile(this.filePath,r,p=>{if(p){l(p);return}o()})}),await this.rotateIfNeededAsync()}rotateIfNeeded(){if(n.existsSync(this.filePath))try{n.statSync(this.filePath).size>=this.maxSize&&this.rotateFiles()}catch(t){console.error("Error checking file size for rotation:",t)}}async rotateIfNeededAsync(){if(n.existsSync(this.filePath))try{n.statSync(this.filePath).size>=this.maxSize&&await this.rotateFilesAsync()}catch(t){console.error("Error during rotation check:",t)}}rotateFiles(){try{let t="";n.existsSync(this.filePath)&&(t=n.readFileSync(this.filePath,"utf8"));let e=this.getRotatedFilePath();n.writeFileSync(e,t,"utf8"),n.writeFileSync(this.filePath,"","utf8"),this.cleanupOldFiles()}catch(t){console.error("Error during file rotation:",t)}}async rotateFilesAsync(){try{let t="";n.existsSync(this.filePath)&&(t=await n.promises.readFile(this.filePath,"utf8"));let e=this.getRotatedFilePath();await n.promises.writeFile(e,t,"utf8"),await n.promises.writeFile(this.filePath,"","utf8"),await this.cleanupOldFilesAsync()}catch(t){console.error("Error during async file rotation:",t)}}getRotatedFilePath(){let t=h.dirname(this.filePath),e=h.basename(this.filePath),i=Date.now();return h.join(t,`${e}.${i}`)}cleanupOldFiles(){try{let t=h.dirname(this.filePath),e=h.basename(this.filePath);try{n.accessSync(t,n.constants.F_OK)}catch{return}let r=n.readdirSync(t).filter(o=>!o||o===e?!1:new RegExp(`^${e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}\\.\\d+$`).test(o)).sort((o,l)=>{let p=parseInt(o.split(".").pop()||"0");return parseInt(l.split(".").pop()||"0")-p});for(let o=this.maxFiles;o<r.length;o++){let l=r[o];if(l){if(l.includes("../")||l.includes("..\\")||l.startsWith(".."))continue;let p=h.join(t,l),m=h.resolve(p),f=h.resolve(t);if(!m.startsWith(f+h.sep)&&m!==f)continue;try{n.unlinkSync(p)}catch(c){console.error(`Failed to delete old log file ${p}:`,c)}}}}catch(t){console.error("Error during cleanup of old files:",t)}}async cleanupOldFilesAsync(){try{let t=h.dirname(this.filePath),e=h.basename(this.filePath);try{await n.promises.access(t,n.constants.F_OK)}catch{return}let r=(await n.promises.readdir(t)).filter(l=>!l||l===e?!1:new RegExp(`^${e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}\\.\\d+$`).test(l)).sort((l,p)=>{let m=parseInt(l.split(".").pop()||"0");return parseInt(p.split(".").pop()||"0")-m}),o=[];for(let l=this.maxFiles;l<r.length;l++){let p=r[l];if(p){if(p.includes("../")||p.includes("..\\")||p.startsWith(".."))continue;let m=h.join(t,p),f=h.resolve(m),c=h.resolve(t);if(!f.startsWith(c+h.sep)&&f!==c)continue;o.push(n.promises.access(m,n.constants.F_OK).then(()=>n.promises.unlink(m)).catch(s=>{s.code!=="ENOENT"&&console.error(`Failed to delete old log file ${m}:`,s)}))}}await Promise.all(o)}catch(t){console.error("Error during async cleanup of old files:",t)}}};var y=class a{constructor(t={}){this.transports=[];let{level:e,colorize:i,json:r,transports:o=[],timestampFormat:l="YYYY-MM-DD HH:mm:ss",prefix:p,timestamp:m,context:f={},parent:c,asyncMode:s,customLevels:g={},customColors:T={}}=t;if(this.parent=c,this.context={...f},this.customLevels=g,this.asyncMode=!1,this.parent){this.level=e??this.parent.level,this.prefix=p??this.parent.prefix,this.timestamp=m??this.parent.timestamp,this.asyncMode=s??this.parent.asyncMode,this.transports=o&&o.length>0?this.initTransports(o,this.getDefaultColorizeValue(i)):this.parent.transports;let u={...this.parent.formatter.getCustomColors(),...T};this.formatter=new b({colorize:this.getDefaultColorizeValue(i)??this.parent.formatter.isColorized(),json:r??this.parent.formatter.isJson(),timestampFormat:l??this.parent.formatter.getTimestampFormat(),timestamp:m??this.parent.formatter.hasTimestamp(),customColors:u}),this.context={...this.parent.context,...this.context},this.customLevels={...this.parent.customLevels,...g}}else{let u=this.isProductionEnvironment();this.level=e??this.getDefaultLevel(u),this.prefix=p??"",this.timestamp=m??this.getDefaultTimestamp(u);let R=o&&o.length>0?o:this.getDefaultTransports(u);this.asyncMode=s??this.getDefaultAsyncMode(u),this.transports=this.initTransports(R,this.getDefaultColorizeValue(i)),this.formatter=new b({colorize:this.getDefaultColorizeValue(i),json:r??this.getDefaultJson(u),timestampFormat:l,timestamp:this.getDefaultTimestamp(u),customColors:T})}a._global||(a._global=this)}static{this.LEVEL_PRIORITIES={silent:0,boring:1,debug:2,info:3,warn:4,error:5}}isProductionEnvironment(){let t=process.env.NODE_ENV?.toLowerCase();return t==="production"||t==="prod"}getDefaultLevel(t){return t?"warn":"debug"}getDefaultColorizeValue(t){return t!==void 0?t:!this.isProductionEnvironment()}getDefaultJson(t){return t}getDefaultTimestamp(t){return!0}getDefaultTransports(t){return t?[{type:"console"},{type:"file",options:{path:"./logs/app.log"}}]:[{type:"console"}]}getDefaultAsyncMode(t){return t}initTransports(t,e){let i=[];for(let r of t)if(r.type==="console"){let o=new d({colorize:r.options?.colorize??e});i.push(o)}else if(r.type==="file"){if(r.options?.path){let o={path:r.options.path};r.options.maxSize!==void 0&&(o.maxSize=r.options.maxSize),r.options.maxFiles!==void 0&&(o.maxFiles=r.options.maxFiles);let l=new v(o);i.push(l)}}else r.type==="custom"&&r.instance&&i.push(r.instance);return i}shouldLog(t){let e=this.getLevelPriority(this.level);return this.getLevelPriority(t)>=e}getLevelPriority(t){if(a.LEVEL_PRIORITIES.hasOwnProperty(t))return a.LEVEL_PRIORITIES[t];if(this.customLevels&&t in this.customLevels){let e=this.customLevels[t];return e!==void 0?e:999}return 999}log(t,e,i){if(this.shouldLog(t)&&t!=="silent")if(this.asyncMode)this.logAsyncDirect(t,e,i);else{let r=new Date,o;this.context&&Object.keys(this.context).length>0?i?o={...this.context,...i}:o=this.context:i&&(o=i);let l={level:t,message:e,timestamp:r,metadata:o&&Object.keys(o).length>0?o:void 0,prefix:this.prefix};for(let p of this.transports)p.write(l,this.formatter)}}logAsyncDirect(t,e,i){if(!this.shouldLog(t)||t==="silent")return;let r=new Date,o;this.context&&Object.keys(this.context).length>0?i?o={...this.context,...i}:o=this.context:i&&(o=i);let l={level:t,message:e,timestamp:r,metadata:o&&Object.keys(o).length>0?o:void 0,prefix:this.prefix};for(let p of this.transports)p.writeAsync?p.writeAsync(l,this.formatter).catch(m=>{console.error("Error during async logging:",m)}):setImmediate(()=>{p.write(l,this.formatter)})}debug(t,e){this.log("debug",t,e)}info(t,e){this.log("info",t,e)}warn(t,e){this.log("warn",t,e)}error(t,e){this.log("error",t,e)}silent(t,e){this.log("silent",t,e)}boring(t,e){this.log("boring",t,e)}logWithLevel(t,e,i){this.log(t,e,i)}setLevel(t){this.level=t}setFormat(t){this.formatter.setJson(t==="json")}setAsyncMode(t){this.asyncMode=t}addTransport(t){this.transports.push(t)}getTimestampSetting(){return this.timestamp}static get global(){return a._global||(a._global=new a),a._global}createChild(t={}){return new a({...t,parent:this})}startTimer(t){let{Timer:e}=(z(),w(C));return new e(t,i=>this.info(i))}};var N=y;0&&(module.exports={ConsoleTransport,FileTransport,Logger});
1
+ "use strict";var N=Object.create;var F=Object.defineProperty;var k=Object.getOwnPropertyDescriptor;var Y=Object.getOwnPropertyNames;var B=Object.getPrototypeOf,q=Object.prototype.hasOwnProperty;var J=(a,t)=>()=>(a&&(t=a(a=0)),t);var z=(a,t)=>{for(var e in t)F(a,e,{get:t[e],enumerable:!0})},D=(a,t,e,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of Y(t))!q.call(a,o)&&o!==e&&F(a,o,{get:()=>t[o],enumerable:!(s=k(t,o))||s.enumerable});return a};var y=(a,t,e)=>(e=a!=null?N(B(a)):{},D(t||!a||!a.__esModule?F(e,"default",{value:a,enumerable:!0}):e,a)),R=a=>D(F({},"__esModule",{value:!0}),a);var M={};z(M,{Timer:()=>S});var S,H=J(()=>{"use strict";S=class{constructor(t,e){this.hasEnded=!1;this.name=t,this.logFn=e,this.startTime=Date.now()}end(){if(this.hasEnded)return;let e=Date.now()-this.startTime;this.logFn(`${this.name} took ${e}ms`),this.hasEnded=!0}}});var K={};z(K,{ConsoleTransport:()=>f,FileTransport:()=>d,HttpTransport:()=>T,Logger:()=>x,consoleT:()=>E,default:()=>_,fileT:()=>A,httpT:()=>$});module.exports=R(K);var w=class{static format(t,e){if(e==="ISO")return t.toISOString();if(e==="UTC")return t.toUTCString();if(e==="LOCAL")return t.toLocaleString();let s=t.getFullYear(),o=t.getMonth()+1,r=t.getDate(),n=t.getHours(),p=t.getMinutes(),c=t.getSeconds(),u=t.getMilliseconds(),h=[],i=0,g=0;for(;i<e.length;)e[i]==="Y"&&i+3<e.length&&e.slice(i,i+4)==="YYYY"?(h.push(e.substring(g,i)),h.push(s.toString().padStart(4,"0")),i+=4,g=i):e[i]==="M"&&i+1<e.length&&e.slice(i,i+2)==="MM"?(h.push(e.substring(g,i)),h.push(o.toString().padStart(2,"0")),i+=2,g=i):e[i]==="D"&&i+1<e.length&&e.slice(i,i+2)==="DD"?(h.push(e.substring(g,i)),h.push(r.toString().padStart(2,"0")),i+=2,g=i):e[i]==="H"&&i+1<e.length&&e.slice(i,i+2)==="HH"?(h.push(e.substring(g,i)),h.push(n.toString().padStart(2,"0")),i+=2,g=i):e[i]==="m"&&i+1<e.length&&e.slice(i,i+2)==="mm"?(h.push(e.substring(g,i)),h.push(p.toString().padStart(2,"0")),i+=2,g=i):e[i]==="s"&&i+1<e.length&&e.slice(i,i+2)==="ss"?(h.push(e.substring(g,i)),h.push(c.toString().padStart(2,"0")),i+=2,g=i):e[i]==="S"&&i+2<e.length&&e.slice(i,i+3)==="SSS"?(h.push(e.substring(g,i)),h.push(u.toString().padStart(3,"0")),i+=3,g=i):i++;return h.push(e.substring(g)),h.join("")}};var O=class a{static{this.ANSI_COLORS={black:"\x1B[30m",red:"\x1B[31m",green:"\x1B[32m",yellow:"\x1B[33m",blue:"\x1B[34m",magenta:"\x1B[35m",cyan:"\x1B[36m",white:"\x1B[37m",brightRed:"\x1B[91m",brightGreen:"\x1B[92m",brightYellow:"\x1B[93m",brightBlue:"\x1B[94m",brightMagenta:"\x1B[95m",brightCyan:"\x1B[96m",brightWhite:"\x1B[97m",info:"\x1B[32m",warn:"\x1B[33m",error:"\x1B[31m",debug:"\x1B[36m",boring:"\x1B[37m",reset:"\x1B[0m"}}static colorize(t,e){return process.env.FORCE_COLOR!=="0"&&(process.stdout.isTTY||process.env.FORCE_COLOR==="1")?`${a.ANSI_COLORS[e]||a.ANSI_COLORS.reset}${t}${a.ANSI_COLORS.reset}`:t}};var L=class{constructor(t={}){let{colorize:e=!0,json:s=!1,timestampFormat:o="YYYY-MM-DD HH:mm:ss",timestamp:r=!1,customColors:n={}}=t;this.colorize=e,this.json=s,this.timestampFormat=o,this.timestamp=r,this.customColors=n}format(t){return this.json?this.formatAsJson(t):this.formatAsText(t)}formatAsJson(t){let e={...t.metadata,level:t.level,message:t.message};return this.timestamp&&(e.timestamp=t.timestamp.toISOString()),t.prefix&&(e.prefix=t.prefix),JSON.stringify(e)}formatAsText(t){let e=[];if(this.timestamp){let o=w.format(t.timestamp,this.timestampFormat);e.push(`[${o}] `)}t.prefix&&e.push(`${t.prefix} `);let s=t.level.toUpperCase();if(this.colorize){let o=this.customColors[t.level]||t.level;s=O.colorize(s,o)}return e.push(`[${s}] `),e.push(t.message),t.metadata&&e.push(` ${JSON.stringify(t.metadata)}`),e.join("")}setJson(t){this.json=t}isColorized(){return this.colorize}isJson(){return this.json}getTimestampFormat(){return this.timestampFormat}hasTimestamp(){return this.timestamp}getCustomColors(){return{...this.customColors}}};var f=class{constructor(t={}){let{colorize:e=!0}=t;this.colorize=e}write(t,e){let s=e.colorize;this.colorize!==s&&(e.colorize=this.colorize);let o=e.format(t);switch(this.colorize!==s&&(e.colorize=s),t.level){case"error":console.error(o);break;case"warn":console.warn(o);break;default:console.log(o);break}}async writeAsync(t,e){return setImmediate(()=>{this.write(t,e)}),Promise.resolve()}};var l=y(require("fs"),1),m=y(require("path"),1),b=y(require("zlib"),1),C=require("util"),Q=(0,C.promisify)(b.gzip),V=(0,C.promisify)(b.deflate),d=class{constructor(t){this.batchQueue=[];this.batchTimer=null;let{path:e,maxSize:s=10*1024*1024,maxFiles:o=5,compression:r="none",batchInterval:n=0,compressOldFiles:p=!0}=t;this.filePath=e,this.maxSize=s,this.maxFiles=o,this.compression=r,this.batchInterval=n,this.compressOldFiles=p;let c=m.dirname(this.filePath);l.existsSync(c)||l.mkdirSync(c,{recursive:!0}),l.existsSync(this.filePath)||l.writeFileSync(this.filePath,"","utf8"),n>0&&this.startBatching()}write(t,e){let o=e.format(t)+`
2
+ `;this.batchInterval>0?this.batchQueue.push({data:o,timestamp:new Date}):(l.appendFileSync(this.filePath,o),this.rotateIfNeeded())}async writeAsync(t,e){let o=e.format(t)+`
3
+ `;this.batchInterval>0?this.batchQueue.push({data:o,timestamp:new Date}):(await new Promise((r,n)=>{l.appendFile(this.filePath,o,p=>{if(p){n(p);return}r()})}),await this.rotateIfNeededAsync())}rotateIfNeeded(){if(l.existsSync(this.filePath))try{l.statSync(this.filePath).size>=this.maxSize&&this.rotateFiles()}catch(t){console.error("Error checking file size for rotation:",t)}}async rotateIfNeededAsync(){if(l.existsSync(this.filePath))try{l.statSync(this.filePath).size>=this.maxSize&&await this.rotateFilesAsync()}catch(t){console.error("Error during rotation check:",t)}}rotateFiles(){try{let t="";l.existsSync(this.filePath)&&(t=l.readFileSync(this.filePath,"utf8"));let e=this.getRotatedFilePath();if(this.compression!=="none"&&this.compressOldFiles){e=`${e}.${this.compression==="gzip"?"gz":"zz"}`;let s=this.compression==="gzip"?b.gzipSync(t):b.deflateSync(t);l.writeFileSync(e,s)}else l.writeFileSync(e,t,"utf8");l.writeFileSync(this.filePath,"","utf8"),this.cleanupOldFiles()}catch(t){console.error("Error during file rotation:",t)}}async rotateFilesAsync(){try{let t="";l.existsSync(this.filePath)&&(t=await l.promises.readFile(this.filePath,"utf8"));let e=this.getRotatedFilePath();if(this.compression!=="none"&&this.compressOldFiles){e=`${e}.${this.compression==="gzip"?"gz":"zz"}`;let s=this.compression==="gzip"?await Q(t):await V(t);await l.promises.writeFile(e,s)}else await l.promises.writeFile(e,t,"utf8");await l.promises.writeFile(this.filePath,"","utf8"),await this.cleanupOldFilesAsync()}catch(t){console.error("Error during async file rotation:",t)}}getRotatedFilePath(){let t=m.dirname(this.filePath),e=m.basename(this.filePath),s=Date.now();return m.join(t,`${e}.${s}`)}cleanupOldFiles(){try{let t=m.dirname(this.filePath),e=m.basename(this.filePath);try{l.accessSync(t,l.constants.F_OK)}catch{return}let o=l.readdirSync(t).filter(r=>!r||r===e?!1:new RegExp(`^${e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}\\.\\d+(\\.gz|\\.zz)?$`).test(r)).sort((r,n)=>{let p=parseInt(r.slice(e.length+1).split(".")[0]||"0");return parseInt(n.slice(e.length+1).split(".")[0]||"0")-p});for(let r=this.maxFiles;r<o.length;r++){let n=o[r];if(n){if(n.includes("../")||n.includes("..\\")||n.startsWith(".."))continue;let p=m.join(t,n),c=m.resolve(p),u=m.resolve(t);if(!c.startsWith(u+m.sep)&&c!==u)continue;try{l.unlinkSync(p)}catch(h){console.error(`Failed to delete old log file ${p}:`,h)}}}}catch(t){console.error("Error during cleanup of old files:",t)}}async cleanupOldFilesAsync(){try{let t=m.dirname(this.filePath),e=m.basename(this.filePath);try{await l.promises.access(t,l.constants.F_OK)}catch{return}let o=(await l.promises.readdir(t)).filter(n=>!n||n===e?!1:new RegExp(`^${e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}\\.\\d+(\\.gz|\\.zz)?$`).test(n)).sort((n,p)=>{let c=parseInt(n.slice(e.length+1).split(".")[0]||"0");return parseInt(p.slice(e.length+1).split(".")[0]||"0")-c}),r=[];for(let n=this.maxFiles;n<o.length;n++){let p=o[n];if(p){if(p.includes("../")||p.includes("..\\")||p.startsWith(".."))continue;let c=m.join(t,p),u=m.resolve(c),h=m.resolve(t);if(!u.startsWith(h+m.sep)&&u!==h)continue;r.push(l.promises.access(c,l.constants.F_OK).then(()=>l.promises.unlink(c)).catch(i=>{i.code!=="ENOENT"&&console.error(`Failed to delete old log file ${c}:`,i)}))}}await Promise.all(r)}catch(t){console.error("Error during async cleanup of old files:",t)}}startBatching(){this.batchInterval>0&&(this.batchTimer=setInterval(()=>{this.processBatch().catch(t=>{console.error("Error in batch processing timer:",t)})},this.batchInterval))}async processBatch(){if(this.batchQueue.length===0)return;let t=this.batchQueue;this.batchQueue=[];let e=t.map(s=>s.data).join("");try{await new Promise((s,o)=>{l.appendFile(this.filePath,e,r=>{if(r){o(r);return}s()})}),await this.rotateIfNeededAsync()}catch(s){console.error("Error processing log batch:",s),this.batchQueue=[...t,...this.batchQueue]}}async destroy(){if(this.batchTimer&&(clearInterval(this.batchTimer),this.batchTimer=null),this.batchQueue.length>0)try{await this.processBatch()}catch(t){console.error("Error processing final batch:",t)}}};var W=y(require("http"),1),U=y(require("https"),1),I=y(require("url"),1),T=class{constructor(t){let{url:e,method:s="POST",headers:o={},timeout:r=5e3,retries:n=3}=t;if(!e)throw new Error("HttpTransport requires a URL option");this.url=e,this.method=s.toUpperCase(),this.headers={...o},this.timeout=r,this.retries=n,!this.headers["Content-Type"]&&!this.headers["content-type"]&&(this.headers["Content-Type"]="application/json")}write(t,e){let s=this.parseFormattedData(t),o=JSON.stringify(s);setImmediate(()=>{this.sendHttpRequestWithRetry(o,0).catch(r=>{console.error("HttpTransport error (sync mode):",r.message)})})}async writeAsync(t,e){let s=this.parseFormattedData(t),o=JSON.stringify(s);await this.sendHttpRequestWithRetry(o,this.retries)}parseFormattedData(t){return{level:t.level,message:t.message,timestamp:t.timestamp.toISOString(),...t.prefix&&{prefix:t.prefix},...t.metadata&&{metadata:t.metadata}}}async sendHttpRequestWithRetry(t,e){let s=null;for(let o=0;o<=e;o++)try{await this.sendHttpRequest(t);return}catch(r){if(s=r,o===e)break;await this.delay(Math.pow(2,o)*1e3)}if(s)throw s}sendHttpRequest(t){return new Promise((e,s)=>{let o=new I.URL(this.url),n=o.protocol==="https:"?U:W,p={hostname:o.hostname,port:o.port,path:o.pathname+o.search,method:this.method,headers:{...this.headers,"Content-Length":Buffer.byteLength(t,"utf8")},timeout:this.timeout},c=n.request(p,u=>{let h="";u.on("data",i=>{h+=i}),u.on("end",()=>{u.statusCode&&u.statusCode>=200&&u.statusCode<300?e():s(new Error(`HTTP request failed with status ${u.statusCode}: ${h}`))})});c.on("error",u=>{s(u)}),c.on("timeout",()=>{c.destroy(),s(new Error("Request timeout"))}),c.write(t),c.end()})}delay(t){return new Promise(e=>setTimeout(e,t))}};function E(a){return new f(a)}function A(a){return new d(a)}function $(a){return new T(a)}var x=class a{constructor(t={}){this.transports=[];let{level:e,colorize:s,json:o,transports:r=[],timestampFormat:n="YYYY-MM-DD HH:mm:ss",prefix:p,timestamp:c,context:u={},parent:h,asyncMode:i,customLevels:g={},customColors:P={}}=t;if(this.parent=h,this.context={...u},this.customLevels=g,this.asyncMode=!1,this.parent){this.level=e??this.parent.level,this.prefix=p??this.parent.prefix,this.timestamp=c??this.parent.timestamp,this.asyncMode=i??this.parent.asyncMode,this.transports=r&&r.length>0?this.initTransports(r,this.getDefaultColorizeValue(s)):this.parent.transports;let v={...this.parent.formatter.getCustomColors(),...P};this.formatter=new L({colorize:this.getDefaultColorizeValue(s)??this.parent.formatter.isColorized(),json:o??this.parent.formatter.isJson(),timestampFormat:n??this.parent.formatter.getTimestampFormat(),timestamp:c??this.parent.formatter.hasTimestamp(),customColors:v}),this.context={...this.parent.context,...this.context},this.customLevels={...this.parent.customLevels,...g}}else{let v=this.isProductionEnvironment();this.level=e??this.getDefaultLevel(v),this.prefix=p??"",this.timestamp=c??this.getDefaultTimestamp(v);let j=r&&r.length>0?r:this.getDefaultTransports(v);this.asyncMode=i??this.getDefaultAsyncMode(v),this.transports=this.initTransports(j,this.getDefaultColorizeValue(s)),this.formatter=new L({colorize:this.getDefaultColorizeValue(s),json:o??this.getDefaultJson(v),timestampFormat:n,timestamp:this.getDefaultTimestamp(v),customColors:P})}a._global||(a._global=this)}static{this.LEVEL_PRIORITIES={silent:0,boring:1,debug:2,info:3,warn:4,error:5}}isProductionEnvironment(){let t=process.env.NODE_ENV?.toLowerCase();return t==="production"||t==="prod"}getDefaultLevel(t){return t?"warn":"debug"}getDefaultColorizeValue(t){return t!==void 0?t:!this.isProductionEnvironment()}getDefaultJson(t){return t}getDefaultTimestamp(t){return!0}getDefaultTransports(t){return t?[new f,new d({path:"./logs/app.log"})]:[new f]}getDefaultAsyncMode(t){return t}initTransports(t,e){let s=[];for(let o of t)if(this.isLegacyTransportOptions(o)){let r=o;if(r.type==="console"){let n=new f({colorize:r.options?.colorize??e});s.push(n)}else if(r.type==="file"){if(r.options?.path){let n={path:r.options.path};r.options.maxSize!==void 0&&(n.maxSize=r.options.maxSize),r.options.maxFiles!==void 0&&(n.maxFiles=r.options.maxFiles),r.options.compression!==void 0&&(n.compression=r.options.compression),r.options.batchInterval!==void 0&&(n.batchInterval=r.options.batchInterval),r.options.compressOldFiles!==void 0&&(n.compressOldFiles=r.options.compressOldFiles);let p=new d(n);s.push(p)}}else r.type==="custom"&&r.instance&&s.push(r.instance)}else this.isTransport(o)&&s.push(o);return s}isLegacyTransportOptions(t){return typeof t=="object"&&t!==null&&"type"in t}isTransport(t){return t&&typeof t.write=="function"&&(typeof t.writeAsync=="function"||t.writeAsync===void 0)}shouldLog(t){let e=this.getLevelPriority(this.level);return this.getLevelPriority(t)>=e}getLevelPriority(t){if(a.LEVEL_PRIORITIES.hasOwnProperty(t))return a.LEVEL_PRIORITIES[t];if(this.customLevels&&t in this.customLevels){let e=this.customLevels[t];return e!==void 0?e:999}return 999}log(t,e,s){if(this.shouldLog(t)&&t!=="silent")if(this.asyncMode)this.logAsyncDirect(t,e,s);else{let o=new Date,r;this.context&&Object.keys(this.context).length>0?s?r={...this.context,...s}:r=this.context:s&&(r=s);let n={level:t,message:e,timestamp:o,metadata:r&&Object.keys(r).length>0?r:void 0,prefix:this.prefix};for(let p of this.transports)p.write(n,this.formatter)}}logAsyncDirect(t,e,s){if(!this.shouldLog(t)||t==="silent")return;let o=new Date,r;this.context&&Object.keys(this.context).length>0?s?r={...this.context,...s}:r=this.context:s&&(r=s);let n={level:t,message:e,timestamp:o,metadata:r&&Object.keys(r).length>0?r:void 0,prefix:this.prefix};for(let p of this.transports)p.writeAsync?p.writeAsync(n,this.formatter).catch(c=>{console.error("Error during async logging:",c)}):setImmediate(()=>{p.write(n,this.formatter)})}debug(t,e){this.log("debug",t,e)}info(t,e){this.log("info",t,e)}warn(t,e){this.log("warn",t,e)}error(t,e){this.log("error",t,e)}silent(t,e){this.log("silent",t,e)}boring(t,e){this.log("boring",t,e)}logWithLevel(t,e,s){this.log(t,e,s)}setLevel(t){this.level=t}setFormat(t){this.formatter.setJson(t==="json")}setAsyncMode(t){this.asyncMode=t}addTransport(t){this.transports.push(t)}getTimestampSetting(){return this.timestamp}static get global(){return a._global||(a._global=new a),a._global}createChild(t={}){return new a({...t,parent:this})}startTimer(t){let{Timer:e}=(H(),R(M));return new e(t,s=>this.info(s))}};var _=x;0&&(module.exports={ConsoleTransport,FileTransport,HttpTransport,Logger,consoleT,fileT,httpT});
package/dist/index.mjs CHANGED
@@ -1,3 +1,3 @@
1
- var F=Object.defineProperty;var w=Object.getOwnPropertyDescriptor;var C=Object.getOwnPropertyNames;var z=Object.prototype.hasOwnProperty;var R=(l,t)=>()=>(l&&(t=l(l=0)),t);var E=(l,t)=>{for(var e in t)F(l,e,{get:t[e],enumerable:!0})},A=(l,t,e,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of C(t))!z.call(l,r)&&r!==e&&F(l,r,{get:()=>t[r],enumerable:!(i=w(t,r))||i.enumerable});return l};var I=l=>A(F({},"__esModule",{value:!0}),l);var O={};E(O,{Timer:()=>S});var S,P=R(()=>{"use strict";S=class{constructor(t,e){this.hasEnded=!1;this.name=t,this.logFn=e,this.startTime=Date.now()}end(){if(this.hasEnded)return;let e=Date.now()-this.startTime;this.logFn(`${this.name} took ${e}ms`),this.hasEnded=!0}}});var y=class{static format(t,e){if(e==="ISO")return t.toISOString();if(e==="UTC")return t.toUTCString();if(e==="LOCAL")return t.toLocaleString();let i=t.getFullYear(),r=t.getMonth()+1,o=t.getDate(),a=t.getHours(),p=t.getMinutes(),m=t.getSeconds(),f=t.getMilliseconds(),c=[],s=0,g=0;for(;s<e.length;)e[s]==="Y"&&s+3<e.length&&e.slice(s,s+4)==="YYYY"?(c.push(e.substring(g,s)),c.push(i.toString().padStart(4,"0")),s+=4,g=s):e[s]==="M"&&s+1<e.length&&e.slice(s,s+2)==="MM"?(c.push(e.substring(g,s)),c.push(r.toString().padStart(2,"0")),s+=2,g=s):e[s]==="D"&&s+1<e.length&&e.slice(s,s+2)==="DD"?(c.push(e.substring(g,s)),c.push(o.toString().padStart(2,"0")),s+=2,g=s):e[s]==="H"&&s+1<e.length&&e.slice(s,s+2)==="HH"?(c.push(e.substring(g,s)),c.push(a.toString().padStart(2,"0")),s+=2,g=s):e[s]==="m"&&s+1<e.length&&e.slice(s,s+2)==="mm"?(c.push(e.substring(g,s)),c.push(p.toString().padStart(2,"0")),s+=2,g=s):e[s]==="s"&&s+1<e.length&&e.slice(s,s+2)==="ss"?(c.push(e.substring(g,s)),c.push(m.toString().padStart(2,"0")),s+=2,g=s):e[s]==="S"&&s+2<e.length&&e.slice(s,s+3)==="SSS"?(c.push(e.substring(g,s)),c.push(f.toString().padStart(3,"0")),s+=3,g=s):s++;return c.push(e.substring(g)),c.join("")}};var x=class l{static{this.ANSI_COLORS={black:"\x1B[30m",red:"\x1B[31m",green:"\x1B[32m",yellow:"\x1B[33m",blue:"\x1B[34m",magenta:"\x1B[35m",cyan:"\x1B[36m",white:"\x1B[37m",brightRed:"\x1B[91m",brightGreen:"\x1B[92m",brightYellow:"\x1B[93m",brightBlue:"\x1B[94m",brightMagenta:"\x1B[95m",brightCyan:"\x1B[96m",brightWhite:"\x1B[97m",info:"\x1B[32m",warn:"\x1B[33m",error:"\x1B[31m",debug:"\x1B[36m",boring:"\x1B[37m",reset:"\x1B[0m"}}static colorize(t,e){return process.env.FORCE_COLOR!=="0"&&(process.stdout.isTTY||process.env.FORCE_COLOR==="1")?`${l.ANSI_COLORS[e]||l.ANSI_COLORS.reset}${t}${l.ANSI_COLORS.reset}`:t}};var d=class{constructor(t={}){let{colorize:e=!0,json:i=!1,timestampFormat:r="YYYY-MM-DD HH:mm:ss",timestamp:o=!1,customColors:a={}}=t;this.colorize=e,this.json=i,this.timestampFormat=r,this.timestamp=o,this.customColors=a}format(t){return this.json?this.formatAsJson(t):this.formatAsText(t)}formatAsJson(t){let e={level:t.level,message:t.message,...t.metadata};return this.timestamp&&(e.timestamp=t.timestamp.toISOString()),t.prefix&&(e.prefix=t.prefix),JSON.stringify(e)}formatAsText(t){let e=[];if(this.timestamp){let r=y.format(t.timestamp,this.timestampFormat);e.push(`[${r}] `)}t.prefix&&e.push(`${t.prefix} `);let i=t.level.toUpperCase();if(this.colorize){let r=this.customColors[t.level]||t.level;i=x.colorize(i,r)}return e.push(`[${i}] `),e.push(t.message),t.metadata&&e.push(` ${JSON.stringify(t.metadata)}`),e.join("")}setJson(t){this.json=t}isColorized(){return this.colorize}isJson(){return this.json}getTimestampFormat(){return this.timestampFormat}hasTimestamp(){return this.timestamp}getCustomColors(){return{...this.customColors}}};var v=class{constructor(t={}){let{colorize:e=!0}=t;this.colorize=e}write(t,e){let i=e.colorize;this.colorize!==i&&(e.colorize=this.colorize);let r=e.format(t);switch(this.colorize!==i&&(e.colorize=i),t.level){case"error":console.error(r);break;case"warn":console.warn(r);break;default:console.log(r);break}}async writeAsync(t,e){return setImmediate(()=>{this.write(t,e)}),Promise.resolve()}};import*as n from"fs";import*as h from"path";var b=class{constructor(t){let{path:e,maxSize:i=10*1024*1024,maxFiles:r=5}=t;this.filePath=e,this.maxSize=i,this.maxFiles=r;let o=h.dirname(this.filePath);n.existsSync(o)||n.mkdirSync(o,{recursive:!0}),n.existsSync(this.filePath)||n.writeFileSync(this.filePath,"","utf8")}write(t,e){let r=e.format(t)+`
2
- `;n.appendFileSync(this.filePath,r),this.rotateIfNeeded()}async writeAsync(t,e){let r=e.format(t)+`
3
- `;await new Promise((o,a)=>{n.appendFile(this.filePath,r,p=>{if(p){a(p);return}o()})}),await this.rotateIfNeededAsync()}rotateIfNeeded(){if(n.existsSync(this.filePath))try{n.statSync(this.filePath).size>=this.maxSize&&this.rotateFiles()}catch(t){console.error("Error checking file size for rotation:",t)}}async rotateIfNeededAsync(){if(n.existsSync(this.filePath))try{n.statSync(this.filePath).size>=this.maxSize&&await this.rotateFilesAsync()}catch(t){console.error("Error during rotation check:",t)}}rotateFiles(){try{let t="";n.existsSync(this.filePath)&&(t=n.readFileSync(this.filePath,"utf8"));let e=this.getRotatedFilePath();n.writeFileSync(e,t,"utf8"),n.writeFileSync(this.filePath,"","utf8"),this.cleanupOldFiles()}catch(t){console.error("Error during file rotation:",t)}}async rotateFilesAsync(){try{let t="";n.existsSync(this.filePath)&&(t=await n.promises.readFile(this.filePath,"utf8"));let e=this.getRotatedFilePath();await n.promises.writeFile(e,t,"utf8"),await n.promises.writeFile(this.filePath,"","utf8"),await this.cleanupOldFilesAsync()}catch(t){console.error("Error during async file rotation:",t)}}getRotatedFilePath(){let t=h.dirname(this.filePath),e=h.basename(this.filePath),i=Date.now();return h.join(t,`${e}.${i}`)}cleanupOldFiles(){try{let t=h.dirname(this.filePath),e=h.basename(this.filePath);try{n.accessSync(t,n.constants.F_OK)}catch{return}let r=n.readdirSync(t).filter(o=>!o||o===e?!1:new RegExp(`^${e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}\\.\\d+$`).test(o)).sort((o,a)=>{let p=parseInt(o.split(".").pop()||"0");return parseInt(a.split(".").pop()||"0")-p});for(let o=this.maxFiles;o<r.length;o++){let a=r[o];if(a){if(a.includes("../")||a.includes("..\\")||a.startsWith(".."))continue;let p=h.join(t,a),m=h.resolve(p),f=h.resolve(t);if(!m.startsWith(f+h.sep)&&m!==f)continue;try{n.unlinkSync(p)}catch(c){console.error(`Failed to delete old log file ${p}:`,c)}}}}catch(t){console.error("Error during cleanup of old files:",t)}}async cleanupOldFilesAsync(){try{let t=h.dirname(this.filePath),e=h.basename(this.filePath);try{await n.promises.access(t,n.constants.F_OK)}catch{return}let r=(await n.promises.readdir(t)).filter(a=>!a||a===e?!1:new RegExp(`^${e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}\\.\\d+$`).test(a)).sort((a,p)=>{let m=parseInt(a.split(".").pop()||"0");return parseInt(p.split(".").pop()||"0")-m}),o=[];for(let a=this.maxFiles;a<r.length;a++){let p=r[a];if(p){if(p.includes("../")||p.includes("..\\")||p.startsWith(".."))continue;let m=h.join(t,p),f=h.resolve(m),c=h.resolve(t);if(!f.startsWith(c+h.sep)&&f!==c)continue;o.push(n.promises.access(m,n.constants.F_OK).then(()=>n.promises.unlink(m)).catch(s=>{s.code!=="ENOENT"&&console.error(`Failed to delete old log file ${m}:`,s)}))}}await Promise.all(o)}catch(t){console.error("Error during async cleanup of old files:",t)}}};var L=class l{constructor(t={}){this.transports=[];let{level:e,colorize:i,json:r,transports:o=[],timestampFormat:a="YYYY-MM-DD HH:mm:ss",prefix:p,timestamp:m,context:f={},parent:c,asyncMode:s,customLevels:g={},customColors:T={}}=t;if(this.parent=c,this.context={...f},this.customLevels=g,this.asyncMode=!1,this.parent){this.level=e??this.parent.level,this.prefix=p??this.parent.prefix,this.timestamp=m??this.parent.timestamp,this.asyncMode=s??this.parent.asyncMode,this.transports=o&&o.length>0?this.initTransports(o,this.getDefaultColorizeValue(i)):this.parent.transports;let u={...this.parent.formatter.getCustomColors(),...T};this.formatter=new d({colorize:this.getDefaultColorizeValue(i)??this.parent.formatter.isColorized(),json:r??this.parent.formatter.isJson(),timestampFormat:a??this.parent.formatter.getTimestampFormat(),timestamp:m??this.parent.formatter.hasTimestamp(),customColors:u}),this.context={...this.parent.context,...this.context},this.customLevels={...this.parent.customLevels,...g}}else{let u=this.isProductionEnvironment();this.level=e??this.getDefaultLevel(u),this.prefix=p??"",this.timestamp=m??this.getDefaultTimestamp(u);let D=o&&o.length>0?o:this.getDefaultTransports(u);this.asyncMode=s??this.getDefaultAsyncMode(u),this.transports=this.initTransports(D,this.getDefaultColorizeValue(i)),this.formatter=new d({colorize:this.getDefaultColorizeValue(i),json:r??this.getDefaultJson(u),timestampFormat:a,timestamp:this.getDefaultTimestamp(u),customColors:T})}l._global||(l._global=this)}static{this.LEVEL_PRIORITIES={silent:0,boring:1,debug:2,info:3,warn:4,error:5}}isProductionEnvironment(){let t=process.env.NODE_ENV?.toLowerCase();return t==="production"||t==="prod"}getDefaultLevel(t){return t?"warn":"debug"}getDefaultColorizeValue(t){return t!==void 0?t:!this.isProductionEnvironment()}getDefaultJson(t){return t}getDefaultTimestamp(t){return!0}getDefaultTransports(t){return t?[{type:"console"},{type:"file",options:{path:"./logs/app.log"}}]:[{type:"console"}]}getDefaultAsyncMode(t){return t}initTransports(t,e){let i=[];for(let r of t)if(r.type==="console"){let o=new v({colorize:r.options?.colorize??e});i.push(o)}else if(r.type==="file"){if(r.options?.path){let o={path:r.options.path};r.options.maxSize!==void 0&&(o.maxSize=r.options.maxSize),r.options.maxFiles!==void 0&&(o.maxFiles=r.options.maxFiles);let a=new b(o);i.push(a)}}else r.type==="custom"&&r.instance&&i.push(r.instance);return i}shouldLog(t){let e=this.getLevelPriority(this.level);return this.getLevelPriority(t)>=e}getLevelPriority(t){if(l.LEVEL_PRIORITIES.hasOwnProperty(t))return l.LEVEL_PRIORITIES[t];if(this.customLevels&&t in this.customLevels){let e=this.customLevels[t];return e!==void 0?e:999}return 999}log(t,e,i){if(this.shouldLog(t)&&t!=="silent")if(this.asyncMode)this.logAsyncDirect(t,e,i);else{let r=new Date,o;this.context&&Object.keys(this.context).length>0?i?o={...this.context,...i}:o=this.context:i&&(o=i);let a={level:t,message:e,timestamp:r,metadata:o&&Object.keys(o).length>0?o:void 0,prefix:this.prefix};for(let p of this.transports)p.write(a,this.formatter)}}logAsyncDirect(t,e,i){if(!this.shouldLog(t)||t==="silent")return;let r=new Date,o;this.context&&Object.keys(this.context).length>0?i?o={...this.context,...i}:o=this.context:i&&(o=i);let a={level:t,message:e,timestamp:r,metadata:o&&Object.keys(o).length>0?o:void 0,prefix:this.prefix};for(let p of this.transports)p.writeAsync?p.writeAsync(a,this.formatter).catch(m=>{console.error("Error during async logging:",m)}):setImmediate(()=>{p.write(a,this.formatter)})}debug(t,e){this.log("debug",t,e)}info(t,e){this.log("info",t,e)}warn(t,e){this.log("warn",t,e)}error(t,e){this.log("error",t,e)}silent(t,e){this.log("silent",t,e)}boring(t,e){this.log("boring",t,e)}logWithLevel(t,e,i){this.log(t,e,i)}setLevel(t){this.level=t}setFormat(t){this.formatter.setJson(t==="json")}setAsyncMode(t){this.asyncMode=t}addTransport(t){this.transports.push(t)}getTimestampSetting(){return this.timestamp}static get global(){return l._global||(l._global=new l),l._global}createChild(t={}){return new l({...t,parent:this})}startTimer(t){let{Timer:e}=(P(),I(O));return new e(t,i=>this.info(i))}};var et=L;export{v as ConsoleTransport,b as FileTransport,L as Logger,et as default};
1
+ var w=Object.defineProperty;var I=Object.getOwnPropertyDescriptor;var E=Object.getOwnPropertyNames;var A=Object.prototype.hasOwnProperty;var $=(l,t)=>()=>(l&&(t=l(l=0)),t);var M=(l,t)=>{for(var e in t)w(l,e,{get:t[e],enumerable:!0})},H=(l,t,e,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of E(t))!A.call(l,o)&&o!==e&&w(l,o,{get:()=>t[o],enumerable:!(s=I(t,o))||s.enumerable});return l};var j=l=>H(w({},"__esModule",{value:!0}),l);var z={};M(z,{Timer:()=>O});var O,D=$(()=>{"use strict";O=class{constructor(t,e){this.hasEnded=!1;this.name=t,this.logFn=e,this.startTime=Date.now()}end(){if(this.hasEnded)return;let e=Date.now()-this.startTime;this.logFn(`${this.name} took ${e}ms`),this.hasEnded=!0}}});var L=class{static format(t,e){if(e==="ISO")return t.toISOString();if(e==="UTC")return t.toUTCString();if(e==="LOCAL")return t.toLocaleString();let s=t.getFullYear(),o=t.getMonth()+1,r=t.getDate(),n=t.getHours(),p=t.getMinutes(),c=t.getSeconds(),u=t.getMilliseconds(),h=[],i=0,g=0;for(;i<e.length;)e[i]==="Y"&&i+3<e.length&&e.slice(i,i+4)==="YYYY"?(h.push(e.substring(g,i)),h.push(s.toString().padStart(4,"0")),i+=4,g=i):e[i]==="M"&&i+1<e.length&&e.slice(i,i+2)==="MM"?(h.push(e.substring(g,i)),h.push(o.toString().padStart(2,"0")),i+=2,g=i):e[i]==="D"&&i+1<e.length&&e.slice(i,i+2)==="DD"?(h.push(e.substring(g,i)),h.push(r.toString().padStart(2,"0")),i+=2,g=i):e[i]==="H"&&i+1<e.length&&e.slice(i,i+2)==="HH"?(h.push(e.substring(g,i)),h.push(n.toString().padStart(2,"0")),i+=2,g=i):e[i]==="m"&&i+1<e.length&&e.slice(i,i+2)==="mm"?(h.push(e.substring(g,i)),h.push(p.toString().padStart(2,"0")),i+=2,g=i):e[i]==="s"&&i+1<e.length&&e.slice(i,i+2)==="ss"?(h.push(e.substring(g,i)),h.push(c.toString().padStart(2,"0")),i+=2,g=i):e[i]==="S"&&i+2<e.length&&e.slice(i,i+3)==="SSS"?(h.push(e.substring(g,i)),h.push(u.toString().padStart(3,"0")),i+=3,g=i):i++;return h.push(e.substring(g)),h.join("")}};var x=class l{static{this.ANSI_COLORS={black:"\x1B[30m",red:"\x1B[31m",green:"\x1B[32m",yellow:"\x1B[33m",blue:"\x1B[34m",magenta:"\x1B[35m",cyan:"\x1B[36m",white:"\x1B[37m",brightRed:"\x1B[91m",brightGreen:"\x1B[92m",brightYellow:"\x1B[93m",brightBlue:"\x1B[94m",brightMagenta:"\x1B[95m",brightCyan:"\x1B[96m",brightWhite:"\x1B[97m",info:"\x1B[32m",warn:"\x1B[33m",error:"\x1B[31m",debug:"\x1B[36m",boring:"\x1B[37m",reset:"\x1B[0m"}}static colorize(t,e){return process.env.FORCE_COLOR!=="0"&&(process.stdout.isTTY||process.env.FORCE_COLOR==="1")?`${l.ANSI_COLORS[e]||l.ANSI_COLORS.reset}${t}${l.ANSI_COLORS.reset}`:t}};var y=class{constructor(t={}){let{colorize:e=!0,json:s=!1,timestampFormat:o="YYYY-MM-DD HH:mm:ss",timestamp:r=!1,customColors:n={}}=t;this.colorize=e,this.json=s,this.timestampFormat=o,this.timestamp=r,this.customColors=n}format(t){return this.json?this.formatAsJson(t):this.formatAsText(t)}formatAsJson(t){let e={...t.metadata,level:t.level,message:t.message};return this.timestamp&&(e.timestamp=t.timestamp.toISOString()),t.prefix&&(e.prefix=t.prefix),JSON.stringify(e)}formatAsText(t){let e=[];if(this.timestamp){let o=L.format(t.timestamp,this.timestampFormat);e.push(`[${o}] `)}t.prefix&&e.push(`${t.prefix} `);let s=t.level.toUpperCase();if(this.colorize){let o=this.customColors[t.level]||t.level;s=x.colorize(s,o)}return e.push(`[${s}] `),e.push(t.message),t.metadata&&e.push(` ${JSON.stringify(t.metadata)}`),e.join("")}setJson(t){this.json=t}isColorized(){return this.colorize}isJson(){return this.json}getTimestampFormat(){return this.timestampFormat}hasTimestamp(){return this.timestamp}getCustomColors(){return{...this.customColors}}};var f=class{constructor(t={}){let{colorize:e=!0}=t;this.colorize=e}write(t,e){let s=e.colorize;this.colorize!==s&&(e.colorize=this.colorize);let o=e.format(t);switch(this.colorize!==s&&(e.colorize=s),t.level){case"error":console.error(o);break;case"warn":console.warn(o);break;default:console.log(o);break}}async writeAsync(t,e){return setImmediate(()=>{this.write(t,e)}),Promise.resolve()}};import*as a from"fs";import*as m from"path";import*as b from"zlib";import{promisify as S}from"util";var N=S(b.gzip),k=S(b.deflate),v=class{constructor(t){this.batchQueue=[];this.batchTimer=null;let{path:e,maxSize:s=10*1024*1024,maxFiles:o=5,compression:r="none",batchInterval:n=0,compressOldFiles:p=!0}=t;this.filePath=e,this.maxSize=s,this.maxFiles=o,this.compression=r,this.batchInterval=n,this.compressOldFiles=p;let c=m.dirname(this.filePath);a.existsSync(c)||a.mkdirSync(c,{recursive:!0}),a.existsSync(this.filePath)||a.writeFileSync(this.filePath,"","utf8"),n>0&&this.startBatching()}write(t,e){let o=e.format(t)+`
2
+ `;this.batchInterval>0?this.batchQueue.push({data:o,timestamp:new Date}):(a.appendFileSync(this.filePath,o),this.rotateIfNeeded())}async writeAsync(t,e){let o=e.format(t)+`
3
+ `;this.batchInterval>0?this.batchQueue.push({data:o,timestamp:new Date}):(await new Promise((r,n)=>{a.appendFile(this.filePath,o,p=>{if(p){n(p);return}r()})}),await this.rotateIfNeededAsync())}rotateIfNeeded(){if(a.existsSync(this.filePath))try{a.statSync(this.filePath).size>=this.maxSize&&this.rotateFiles()}catch(t){console.error("Error checking file size for rotation:",t)}}async rotateIfNeededAsync(){if(a.existsSync(this.filePath))try{a.statSync(this.filePath).size>=this.maxSize&&await this.rotateFilesAsync()}catch(t){console.error("Error during rotation check:",t)}}rotateFiles(){try{let t="";a.existsSync(this.filePath)&&(t=a.readFileSync(this.filePath,"utf8"));let e=this.getRotatedFilePath();if(this.compression!=="none"&&this.compressOldFiles){e=`${e}.${this.compression==="gzip"?"gz":"zz"}`;let s=this.compression==="gzip"?b.gzipSync(t):b.deflateSync(t);a.writeFileSync(e,s)}else a.writeFileSync(e,t,"utf8");a.writeFileSync(this.filePath,"","utf8"),this.cleanupOldFiles()}catch(t){console.error("Error during file rotation:",t)}}async rotateFilesAsync(){try{let t="";a.existsSync(this.filePath)&&(t=await a.promises.readFile(this.filePath,"utf8"));let e=this.getRotatedFilePath();if(this.compression!=="none"&&this.compressOldFiles){e=`${e}.${this.compression==="gzip"?"gz":"zz"}`;let s=this.compression==="gzip"?await N(t):await k(t);await a.promises.writeFile(e,s)}else await a.promises.writeFile(e,t,"utf8");await a.promises.writeFile(this.filePath,"","utf8"),await this.cleanupOldFilesAsync()}catch(t){console.error("Error during async file rotation:",t)}}getRotatedFilePath(){let t=m.dirname(this.filePath),e=m.basename(this.filePath),s=Date.now();return m.join(t,`${e}.${s}`)}cleanupOldFiles(){try{let t=m.dirname(this.filePath),e=m.basename(this.filePath);try{a.accessSync(t,a.constants.F_OK)}catch{return}let o=a.readdirSync(t).filter(r=>!r||r===e?!1:new RegExp(`^${e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}\\.\\d+(\\.gz|\\.zz)?$`).test(r)).sort((r,n)=>{let p=parseInt(r.slice(e.length+1).split(".")[0]||"0");return parseInt(n.slice(e.length+1).split(".")[0]||"0")-p});for(let r=this.maxFiles;r<o.length;r++){let n=o[r];if(n){if(n.includes("../")||n.includes("..\\")||n.startsWith(".."))continue;let p=m.join(t,n),c=m.resolve(p),u=m.resolve(t);if(!c.startsWith(u+m.sep)&&c!==u)continue;try{a.unlinkSync(p)}catch(h){console.error(`Failed to delete old log file ${p}:`,h)}}}}catch(t){console.error("Error during cleanup of old files:",t)}}async cleanupOldFilesAsync(){try{let t=m.dirname(this.filePath),e=m.basename(this.filePath);try{await a.promises.access(t,a.constants.F_OK)}catch{return}let o=(await a.promises.readdir(t)).filter(n=>!n||n===e?!1:new RegExp(`^${e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}\\.\\d+(\\.gz|\\.zz)?$`).test(n)).sort((n,p)=>{let c=parseInt(n.slice(e.length+1).split(".")[0]||"0");return parseInt(p.slice(e.length+1).split(".")[0]||"0")-c}),r=[];for(let n=this.maxFiles;n<o.length;n++){let p=o[n];if(p){if(p.includes("../")||p.includes("..\\")||p.startsWith(".."))continue;let c=m.join(t,p),u=m.resolve(c),h=m.resolve(t);if(!u.startsWith(h+m.sep)&&u!==h)continue;r.push(a.promises.access(c,a.constants.F_OK).then(()=>a.promises.unlink(c)).catch(i=>{i.code!=="ENOENT"&&console.error(`Failed to delete old log file ${c}:`,i)}))}}await Promise.all(r)}catch(t){console.error("Error during async cleanup of old files:",t)}}startBatching(){this.batchInterval>0&&(this.batchTimer=setInterval(()=>{this.processBatch().catch(t=>{console.error("Error in batch processing timer:",t)})},this.batchInterval))}async processBatch(){if(this.batchQueue.length===0)return;let t=this.batchQueue;this.batchQueue=[];let e=t.map(s=>s.data).join("");try{await new Promise((s,o)=>{a.appendFile(this.filePath,e,r=>{if(r){o(r);return}s()})}),await this.rotateIfNeededAsync()}catch(s){console.error("Error processing log batch:",s),this.batchQueue=[...t,...this.batchQueue]}}async destroy(){if(this.batchTimer&&(clearInterval(this.batchTimer),this.batchTimer=null),this.batchQueue.length>0)try{await this.processBatch()}catch(t){console.error("Error processing final batch:",t)}}};import*as Y from"http";import*as B from"https";import*as P from"url";var T=class{constructor(t){let{url:e,method:s="POST",headers:o={},timeout:r=5e3,retries:n=3}=t;if(!e)throw new Error("HttpTransport requires a URL option");this.url=e,this.method=s.toUpperCase(),this.headers={...o},this.timeout=r,this.retries=n,!this.headers["Content-Type"]&&!this.headers["content-type"]&&(this.headers["Content-Type"]="application/json")}write(t,e){let s=this.parseFormattedData(t),o=JSON.stringify(s);setImmediate(()=>{this.sendHttpRequestWithRetry(o,0).catch(r=>{console.error("HttpTransport error (sync mode):",r.message)})})}async writeAsync(t,e){let s=this.parseFormattedData(t),o=JSON.stringify(s);await this.sendHttpRequestWithRetry(o,this.retries)}parseFormattedData(t){return{level:t.level,message:t.message,timestamp:t.timestamp.toISOString(),...t.prefix&&{prefix:t.prefix},...t.metadata&&{metadata:t.metadata}}}async sendHttpRequestWithRetry(t,e){let s=null;for(let o=0;o<=e;o++)try{await this.sendHttpRequest(t);return}catch(r){if(s=r,o===e)break;await this.delay(Math.pow(2,o)*1e3)}if(s)throw s}sendHttpRequest(t){return new Promise((e,s)=>{let o=new P.URL(this.url),n=o.protocol==="https:"?B:Y,p={hostname:o.hostname,port:o.port,path:o.pathname+o.search,method:this.method,headers:{...this.headers,"Content-Length":Buffer.byteLength(t,"utf8")},timeout:this.timeout},c=n.request(p,u=>{let h="";u.on("data",i=>{h+=i}),u.on("end",()=>{u.statusCode&&u.statusCode>=200&&u.statusCode<300?e():s(new Error(`HTTP request failed with status ${u.statusCode}: ${h}`))})});c.on("error",u=>{s(u)}),c.on("timeout",()=>{c.destroy(),s(new Error("Request timeout"))}),c.write(t),c.end()})}delay(t){return new Promise(e=>setTimeout(e,t))}};function q(l){return new f(l)}function J(l){return new v(l)}function Q(l){return new T(l)}var F=class l{constructor(t={}){this.transports=[];let{level:e,colorize:s,json:o,transports:r=[],timestampFormat:n="YYYY-MM-DD HH:mm:ss",prefix:p,timestamp:c,context:u={},parent:h,asyncMode:i,customLevels:g={},customColors:C={}}=t;if(this.parent=h,this.context={...u},this.customLevels=g,this.asyncMode=!1,this.parent){this.level=e??this.parent.level,this.prefix=p??this.parent.prefix,this.timestamp=c??this.parent.timestamp,this.asyncMode=i??this.parent.asyncMode,this.transports=r&&r.length>0?this.initTransports(r,this.getDefaultColorizeValue(s)):this.parent.transports;let d={...this.parent.formatter.getCustomColors(),...C};this.formatter=new y({colorize:this.getDefaultColorizeValue(s)??this.parent.formatter.isColorized(),json:o??this.parent.formatter.isJson(),timestampFormat:n??this.parent.formatter.getTimestampFormat(),timestamp:c??this.parent.formatter.hasTimestamp(),customColors:d}),this.context={...this.parent.context,...this.context},this.customLevels={...this.parent.customLevels,...g}}else{let d=this.isProductionEnvironment();this.level=e??this.getDefaultLevel(d),this.prefix=p??"",this.timestamp=c??this.getDefaultTimestamp(d);let R=r&&r.length>0?r:this.getDefaultTransports(d);this.asyncMode=i??this.getDefaultAsyncMode(d),this.transports=this.initTransports(R,this.getDefaultColorizeValue(s)),this.formatter=new y({colorize:this.getDefaultColorizeValue(s),json:o??this.getDefaultJson(d),timestampFormat:n,timestamp:this.getDefaultTimestamp(d),customColors:C})}l._global||(l._global=this)}static{this.LEVEL_PRIORITIES={silent:0,boring:1,debug:2,info:3,warn:4,error:5}}isProductionEnvironment(){let t=process.env.NODE_ENV?.toLowerCase();return t==="production"||t==="prod"}getDefaultLevel(t){return t?"warn":"debug"}getDefaultColorizeValue(t){return t!==void 0?t:!this.isProductionEnvironment()}getDefaultJson(t){return t}getDefaultTimestamp(t){return!0}getDefaultTransports(t){return t?[new f,new v({path:"./logs/app.log"})]:[new f]}getDefaultAsyncMode(t){return t}initTransports(t,e){let s=[];for(let o of t)if(this.isLegacyTransportOptions(o)){let r=o;if(r.type==="console"){let n=new f({colorize:r.options?.colorize??e});s.push(n)}else if(r.type==="file"){if(r.options?.path){let n={path:r.options.path};r.options.maxSize!==void 0&&(n.maxSize=r.options.maxSize),r.options.maxFiles!==void 0&&(n.maxFiles=r.options.maxFiles),r.options.compression!==void 0&&(n.compression=r.options.compression),r.options.batchInterval!==void 0&&(n.batchInterval=r.options.batchInterval),r.options.compressOldFiles!==void 0&&(n.compressOldFiles=r.options.compressOldFiles);let p=new v(n);s.push(p)}}else r.type==="custom"&&r.instance&&s.push(r.instance)}else this.isTransport(o)&&s.push(o);return s}isLegacyTransportOptions(t){return typeof t=="object"&&t!==null&&"type"in t}isTransport(t){return t&&typeof t.write=="function"&&(typeof t.writeAsync=="function"||t.writeAsync===void 0)}shouldLog(t){let e=this.getLevelPriority(this.level);return this.getLevelPriority(t)>=e}getLevelPriority(t){if(l.LEVEL_PRIORITIES.hasOwnProperty(t))return l.LEVEL_PRIORITIES[t];if(this.customLevels&&t in this.customLevels){let e=this.customLevels[t];return e!==void 0?e:999}return 999}log(t,e,s){if(this.shouldLog(t)&&t!=="silent")if(this.asyncMode)this.logAsyncDirect(t,e,s);else{let o=new Date,r;this.context&&Object.keys(this.context).length>0?s?r={...this.context,...s}:r=this.context:s&&(r=s);let n={level:t,message:e,timestamp:o,metadata:r&&Object.keys(r).length>0?r:void 0,prefix:this.prefix};for(let p of this.transports)p.write(n,this.formatter)}}logAsyncDirect(t,e,s){if(!this.shouldLog(t)||t==="silent")return;let o=new Date,r;this.context&&Object.keys(this.context).length>0?s?r={...this.context,...s}:r=this.context:s&&(r=s);let n={level:t,message:e,timestamp:o,metadata:r&&Object.keys(r).length>0?r:void 0,prefix:this.prefix};for(let p of this.transports)p.writeAsync?p.writeAsync(n,this.formatter).catch(c=>{console.error("Error during async logging:",c)}):setImmediate(()=>{p.write(n,this.formatter)})}debug(t,e){this.log("debug",t,e)}info(t,e){this.log("info",t,e)}warn(t,e){this.log("warn",t,e)}error(t,e){this.log("error",t,e)}silent(t,e){this.log("silent",t,e)}boring(t,e){this.log("boring",t,e)}logWithLevel(t,e,s){this.log(t,e,s)}setLevel(t){this.level=t}setFormat(t){this.formatter.setJson(t==="json")}setAsyncMode(t){this.asyncMode=t}addTransport(t){this.transports.push(t)}getTimestampSetting(){return this.timestamp}static get global(){return l._global||(l._global=new l),l._global}createChild(t={}){return new l({...t,parent:this})}startTimer(t){let{Timer:e}=(D(),j(z));return new e(t,s=>this.info(s))}};var xt=F;export{f as ConsoleTransport,v as FileTransport,T as HttpTransport,F as Logger,q as consoleT,xt as default,J as fileT,Q as httpT};
@@ -1,15 +1,28 @@
1
1
  import { Transport } from "./Transport";
2
2
  import { LogData } from "../types";
3
3
  import { Formatter } from "../core/Formatter";
4
+ export type CompressionType = "gzip" | "deflate" | "none";
4
5
  export interface FileTransportOptions {
5
6
  path: string;
6
7
  maxSize?: number;
7
8
  maxFiles?: number;
9
+ compression?: CompressionType;
10
+ batchInterval?: number;
11
+ compressOldFiles?: boolean;
12
+ }
13
+ export interface BatchLogEntry {
14
+ data: string;
15
+ timestamp: Date;
8
16
  }
9
17
  export declare class FileTransport implements Transport {
10
18
  private filePath;
11
19
  private maxSize;
12
20
  private maxFiles;
21
+ private compression;
22
+ private batchInterval;
23
+ private compressOldFiles;
24
+ private batchQueue;
25
+ private batchTimer;
13
26
  constructor(options: FileTransportOptions);
14
27
  write(data: LogData, formatter: Formatter): void;
15
28
  writeAsync(data: LogData, formatter: Formatter): Promise<void>;
@@ -20,4 +33,7 @@ export declare class FileTransport implements Transport {
20
33
  private getRotatedFilePath;
21
34
  private cleanupOldFiles;
22
35
  private cleanupOldFilesAsync;
36
+ private startBatching;
37
+ private processBatch;
38
+ destroy(): Promise<void>;
23
39
  }
@@ -0,0 +1,24 @@
1
+ import { Transport } from "./Transport";
2
+ import { LogData } from "../types";
3
+ import { Formatter } from "../core/Formatter";
4
+ export interface HttpTransportOptions {
5
+ url: string;
6
+ method?: string;
7
+ headers?: Record<string, string>;
8
+ timeout?: number;
9
+ retries?: number;
10
+ }
11
+ export declare class HttpTransport implements Transport {
12
+ private url;
13
+ private method;
14
+ private headers;
15
+ private timeout;
16
+ private retries;
17
+ constructor(options: HttpTransportOptions);
18
+ write(data: LogData, formatter: Formatter): void;
19
+ writeAsync(data: LogData, formatter: Formatter): Promise<void>;
20
+ private parseFormattedData;
21
+ private sendHttpRequestWithRetry;
22
+ private sendHttpRequest;
23
+ private delay;
24
+ }
@@ -1,3 +1,28 @@
1
+ import { ConsoleTransport, ConsoleTransportOptions } from "./ConsoleTransport";
2
+ import { FileTransport, FileTransportOptions } from "./FileTransport";
3
+ import { HttpTransport, HttpTransportOptions } from "./HttpTransport";
1
4
  export * from "./Transport";
2
5
  export * from "./ConsoleTransport";
3
6
  export * from "./FileTransport";
7
+ export * from "./HttpTransport";
8
+ /**
9
+ * Create a ConsoleTransport instance configured with the given options.
10
+ *
11
+ * @param options - Configuration options for the console transport
12
+ * @returns A `ConsoleTransport` instance
13
+ */
14
+ export declare function consoleT(options?: ConsoleTransportOptions): ConsoleTransport;
15
+ /**
16
+ * Create a FileTransport configured with the provided options.
17
+ *
18
+ * @param options - Options to configure the FileTransport
19
+ * @returns A new `FileTransport` instance configured according to `options`
20
+ */
21
+ export declare function fileT(options: FileTransportOptions): FileTransport;
22
+ /**
23
+ * Creates an HttpTransport using the provided configuration.
24
+ *
25
+ * @param options - Configuration options for the HttpTransport
26
+ * @returns The constructed `HttpTransport` instance
27
+ */
28
+ export declare function httpT(options: HttpTransportOptions): HttpTransport;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zario",
3
- "version": "0.2.6",
3
+ "version": "0.2.9",
4
4
  "description": "A minimal, fast logging library for Node.js.",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -40,7 +40,7 @@
40
40
  "homepage": "https://github.com/Dev-Dami/zario#readme",
41
41
  "devDependencies": {
42
42
  "@types/jest": "^30.0.0",
43
- "@types/node": "^24.10.0",
43
+ "@types/node": "^24.10.1",
44
44
  "@typescript-eslint/eslint-plugin": "^8.46.4",
45
45
  "@typescript-eslint/parser": "^8.46.4",
46
46
  "esbuild": "^0.27.0",
@@ -53,5 +53,10 @@
53
53
  "dist/**/*",
54
54
  "README.md",
55
55
  "README.npm.md"
56
- ]
57
- }
56
+ ],
57
+ "dependencies": {
58
+ "@types/express": "^5.0.6",
59
+ "express": "^5.2.1",
60
+ "fastify": "^5.6.2"
61
+ }
62
+ }