@wgtechlabs/log-engine 2.1.0 → 2.2.0

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.
Files changed (171) hide show
  1. package/README.md +67 -1
  2. package/dist/cjs/__tests__/async-test-utils.cjs +276 -0
  3. package/dist/cjs/__tests__/async-test-utils.d.ts +51 -0
  4. package/dist/cjs/__tests__/async-test-utils.d.ts.map +1 -0
  5. package/dist/cjs/__tests__/async-test-utils.js.map +1 -0
  6. package/dist/cjs/__tests__/redaction/test-utils.cjs +72 -0
  7. package/dist/cjs/__tests__/redaction/test-utils.d.ts +33 -0
  8. package/dist/cjs/__tests__/redaction/test-utils.d.ts.map +1 -0
  9. package/dist/cjs/__tests__/redaction/test-utils.js.map +1 -0
  10. package/dist/cjs/__tests__/test-utils.cjs +49 -0
  11. package/dist/cjs/__tests__/test-utils.d.ts +41 -0
  12. package/dist/cjs/__tests__/test-utils.d.ts.map +1 -0
  13. package/dist/cjs/__tests__/test-utils.js.map +1 -0
  14. package/dist/{formatter/colors.js → cjs/formatter/colors.cjs} +1 -0
  15. package/dist/cjs/formatter/colors.d.ts.map +1 -0
  16. package/dist/cjs/formatter/colors.js.map +1 -0
  17. package/dist/{formatter/data-formatter.js → cjs/formatter/data-formatter.cjs} +1 -0
  18. package/dist/cjs/formatter/data-formatter.d.ts.map +1 -0
  19. package/dist/cjs/formatter/data-formatter.js.map +1 -0
  20. package/dist/{formatter/index.js → cjs/formatter/index.cjs} +6 -5
  21. package/dist/cjs/formatter/index.d.ts.map +1 -0
  22. package/dist/cjs/formatter/index.js.map +1 -0
  23. package/dist/{formatter/message-formatter.js → cjs/formatter/message-formatter.cjs} +61 -11
  24. package/dist/{formatter → cjs/formatter}/message-formatter.d.ts +9 -3
  25. package/dist/cjs/formatter/message-formatter.d.ts.map +1 -0
  26. package/dist/cjs/formatter/message-formatter.js.map +1 -0
  27. package/dist/{formatter/timestamp.js → cjs/formatter/timestamp.cjs} +1 -0
  28. package/dist/cjs/formatter/timestamp.d.ts.map +1 -0
  29. package/dist/cjs/formatter/timestamp.js.map +1 -0
  30. package/dist/{index.js → cjs/index.cjs} +5 -4
  31. package/dist/{index.d.ts → cjs/index.d.ts} +1 -1
  32. package/dist/cjs/index.d.ts.map +1 -0
  33. package/dist/cjs/index.js.map +1 -0
  34. package/dist/{logger/advanced-outputs.js → cjs/logger/advanced-outputs.cjs} +1 -0
  35. package/dist/cjs/logger/advanced-outputs.d.ts.map +1 -0
  36. package/dist/cjs/logger/advanced-outputs.js.map +1 -0
  37. package/dist/{logger/config.js → cjs/logger/config.cjs} +4 -3
  38. package/dist/cjs/logger/config.d.ts.map +1 -0
  39. package/dist/cjs/logger/config.js.map +1 -0
  40. package/dist/{logger/core.js → cjs/logger/core.cjs} +48 -16
  41. package/dist/{logger → cjs/logger}/core.d.ts +19 -0
  42. package/dist/cjs/logger/core.d.ts.map +1 -0
  43. package/dist/cjs/logger/core.js.map +1 -0
  44. package/dist/{logger/environment.js → cjs/logger/environment.cjs} +2 -1
  45. package/dist/cjs/logger/environment.d.ts.map +1 -0
  46. package/dist/cjs/logger/environment.js.map +1 -0
  47. package/dist/{logger/filtering.js → cjs/logger/filtering.cjs} +2 -1
  48. package/dist/cjs/logger/filtering.d.ts.map +1 -0
  49. package/dist/cjs/logger/filtering.js.map +1 -0
  50. package/dist/{logger/index.js → cjs/logger/index.cjs} +6 -5
  51. package/dist/cjs/logger/index.d.ts.map +1 -0
  52. package/dist/cjs/logger/index.js.map +1 -0
  53. package/dist/cjs/package.json +3 -0
  54. package/dist/{redaction/config.js → cjs/redaction/config.cjs} +1 -0
  55. package/dist/cjs/redaction/config.d.ts.map +1 -0
  56. package/dist/cjs/redaction/config.js.map +1 -0
  57. package/dist/{redaction/index.js → cjs/redaction/index.cjs} +3 -2
  58. package/dist/cjs/redaction/index.d.ts.map +1 -0
  59. package/dist/cjs/redaction/index.js.map +1 -0
  60. package/dist/{redaction/redactor.js → cjs/redaction/redactor.cjs} +2 -1
  61. package/dist/cjs/redaction/redactor.d.ts.map +1 -0
  62. package/dist/cjs/redaction/redactor.js.map +1 -0
  63. package/dist/{types/index.js → cjs/types/index.cjs} +1 -0
  64. package/dist/{types → cjs/types}/index.d.ts +12 -0
  65. package/dist/cjs/types/index.d.ts.map +1 -0
  66. package/dist/cjs/types/index.js.map +1 -0
  67. package/dist/esm/__tests__/async-test-utils.d.ts +51 -0
  68. package/dist/esm/__tests__/async-test-utils.d.ts.map +1 -0
  69. package/dist/esm/__tests__/async-test-utils.js +231 -0
  70. package/dist/esm/__tests__/async-test-utils.js.map +1 -0
  71. package/dist/esm/__tests__/redaction/test-utils.d.ts +33 -0
  72. package/dist/esm/__tests__/redaction/test-utils.d.ts.map +1 -0
  73. package/dist/esm/__tests__/redaction/test-utils.js +65 -0
  74. package/dist/esm/__tests__/redaction/test-utils.js.map +1 -0
  75. package/dist/esm/__tests__/test-utils.d.ts +41 -0
  76. package/dist/esm/__tests__/test-utils.d.ts.map +1 -0
  77. package/dist/esm/__tests__/test-utils.js +42 -0
  78. package/dist/esm/__tests__/test-utils.js.map +1 -0
  79. package/dist/esm/formatter/colors.d.ts +32 -0
  80. package/dist/esm/formatter/colors.d.ts.map +1 -0
  81. package/dist/esm/formatter/colors.js +32 -0
  82. package/dist/esm/formatter/colors.js.map +1 -0
  83. package/dist/esm/formatter/data-formatter.d.ts +26 -0
  84. package/dist/esm/formatter/data-formatter.d.ts.map +1 -0
  85. package/dist/esm/formatter/data-formatter.js +50 -0
  86. package/dist/esm/formatter/data-formatter.js.map +1 -0
  87. package/dist/esm/formatter/index.d.ts +10 -0
  88. package/dist/esm/formatter/index.d.ts.map +1 -0
  89. package/dist/esm/formatter/index.js +11 -0
  90. package/dist/esm/formatter/index.js.map +1 -0
  91. package/dist/esm/formatter/message-formatter.d.ts +47 -0
  92. package/dist/esm/formatter/message-formatter.d.ts.map +1 -0
  93. package/dist/esm/formatter/message-formatter.js +133 -0
  94. package/dist/esm/formatter/message-formatter.js.map +1 -0
  95. package/dist/esm/formatter/timestamp.d.ts +27 -0
  96. package/dist/esm/formatter/timestamp.d.ts.map +1 -0
  97. package/dist/esm/formatter/timestamp.js +36 -0
  98. package/dist/esm/formatter/timestamp.js.map +1 -0
  99. package/dist/esm/index.d.ts +180 -0
  100. package/dist/esm/index.d.ts.map +1 -0
  101. package/dist/esm/index.js +194 -0
  102. package/dist/esm/index.js.map +1 -0
  103. package/dist/esm/logger/advanced-outputs.d.ts +159 -0
  104. package/dist/esm/logger/advanced-outputs.d.ts.map +1 -0
  105. package/dist/esm/logger/advanced-outputs.js +542 -0
  106. package/dist/esm/logger/advanced-outputs.js.map +1 -0
  107. package/dist/esm/logger/config.d.ts +42 -0
  108. package/dist/esm/logger/config.d.ts.map +1 -0
  109. package/dist/esm/logger/config.js +101 -0
  110. package/dist/esm/logger/config.js.map +1 -0
  111. package/dist/esm/logger/core.d.ts +171 -0
  112. package/dist/esm/logger/core.d.ts.map +1 -0
  113. package/dist/esm/logger/core.js +398 -0
  114. package/dist/esm/logger/core.js.map +1 -0
  115. package/dist/esm/logger/environment.d.ts +36 -0
  116. package/dist/esm/logger/environment.d.ts.map +1 -0
  117. package/dist/esm/logger/environment.js +58 -0
  118. package/dist/esm/logger/environment.js.map +1 -0
  119. package/dist/esm/logger/filtering.d.ts +36 -0
  120. package/dist/esm/logger/filtering.d.ts.map +1 -0
  121. package/dist/esm/logger/filtering.js +77 -0
  122. package/dist/esm/logger/filtering.js.map +1 -0
  123. package/dist/esm/logger/index.d.ts +10 -0
  124. package/dist/esm/logger/index.d.ts.map +1 -0
  125. package/dist/esm/logger/index.js +11 -0
  126. package/dist/esm/logger/index.js.map +1 -0
  127. package/dist/esm/redaction/config.d.ts +29 -0
  128. package/dist/esm/redaction/config.d.ts.map +1 -0
  129. package/dist/esm/redaction/config.js +92 -0
  130. package/dist/esm/redaction/config.js.map +1 -0
  131. package/dist/esm/redaction/index.d.ts +8 -0
  132. package/dist/esm/redaction/index.d.ts.map +1 -0
  133. package/dist/esm/redaction/index.js +7 -0
  134. package/dist/esm/redaction/index.js.map +1 -0
  135. package/dist/esm/redaction/redactor.d.ts +99 -0
  136. package/dist/esm/redaction/redactor.d.ts.map +1 -0
  137. package/dist/esm/redaction/redactor.js +259 -0
  138. package/dist/esm/redaction/redactor.js.map +1 -0
  139. package/dist/esm/types/index.d.ts +322 -0
  140. package/dist/esm/types/index.d.ts.map +1 -0
  141. package/dist/esm/types/index.js +41 -0
  142. package/dist/esm/types/index.js.map +1 -0
  143. package/package.json +59 -10
  144. package/dist/formatter/colors.d.ts.map +0 -1
  145. package/dist/formatter/data-formatter.d.ts.map +0 -1
  146. package/dist/formatter/index.d.ts.map +0 -1
  147. package/dist/formatter/message-formatter.d.ts.map +0 -1
  148. package/dist/formatter/timestamp.d.ts.map +0 -1
  149. package/dist/index.d.ts.map +0 -1
  150. package/dist/logger/advanced-outputs.d.ts.map +0 -1
  151. package/dist/logger/config.d.ts.map +0 -1
  152. package/dist/logger/core.d.ts.map +0 -1
  153. package/dist/logger/environment.d.ts.map +0 -1
  154. package/dist/logger/filtering.d.ts.map +0 -1
  155. package/dist/logger/index.d.ts.map +0 -1
  156. package/dist/redaction/config.d.ts.map +0 -1
  157. package/dist/redaction/index.d.ts.map +0 -1
  158. package/dist/redaction/redactor.d.ts.map +0 -1
  159. package/dist/types/index.d.ts.map +0 -1
  160. /package/dist/{formatter → cjs/formatter}/colors.d.ts +0 -0
  161. /package/dist/{formatter → cjs/formatter}/data-formatter.d.ts +0 -0
  162. /package/dist/{formatter → cjs/formatter}/index.d.ts +0 -0
  163. /package/dist/{formatter → cjs/formatter}/timestamp.d.ts +0 -0
  164. /package/dist/{logger → cjs/logger}/advanced-outputs.d.ts +0 -0
  165. /package/dist/{logger → cjs/logger}/config.d.ts +0 -0
  166. /package/dist/{logger → cjs/logger}/environment.d.ts +0 -0
  167. /package/dist/{logger → cjs/logger}/filtering.d.ts +0 -0
  168. /package/dist/{logger → cjs/logger}/index.d.ts +0 -0
  169. /package/dist/{redaction → cjs/redaction}/config.d.ts +0 -0
  170. /package/dist/{redaction → cjs/redaction}/index.d.ts +0 -0
  171. /package/dist/{redaction → cjs/redaction}/redactor.d.ts +0 -0
@@ -0,0 +1,180 @@
1
+ /**
2
+ * Main LogEngine module - provides a comprehensive logging solution
3
+ * with mode-based filtering, colorized output, and automatic data redaction
4
+ *
5
+ * Features a modular architecture with separate modules for:
6
+ * - Logger: Core logging functionality with environment-based configuration
7
+ * - Formatter: Message formatting with ANSI colors and timestamps
8
+ * - Redaction: Automatic sensitive data protection with customizable patterns
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * import { LogEngine, LogMode } from '@wgtechlabs/log-engine';
13
+ *
14
+ * // Configure logging mode
15
+ * LogEngine.configure({ mode: LogMode.DEBUG });
16
+ *
17
+ * // Log with automatic redaction
18
+ * LogEngine.info('User login', { username: 'john', password: 'secret123' });
19
+ * // Output: [2025-06-18T...][3:45PM][INFO]: User login { username: 'john', password: '[REDACTED]' }
20
+ * ```
21
+ */
22
+ import type { LoggerConfig, RedactionConfig, ILogEngineWithoutRedaction, LogData } from './types';
23
+ /**
24
+ * LogEngine - The main interface for logging operations
25
+ * Provides a simple, intuitive API for all logging needs with security-first design
26
+ */
27
+ export declare const LogEngine: {
28
+ /**
29
+ * Configure the logger with new settings
30
+ * @param config - Configuration object containing logger settings
31
+ * @example
32
+ * ```typescript
33
+ * LogEngine.configure({ mode: LogMode.PRODUCTION });
34
+ * ```
35
+ */
36
+ configure: (config: Partial<LoggerConfig>) => void;
37
+ /**
38
+ * Log a debug message with automatic data redaction
39
+ * Only shown in DEVELOPMENT mode
40
+ * @param message - The debug message to log
41
+ * @param data - Optional data object to log (sensitive data will be redacted)
42
+ * @example
43
+ * ```typescript
44
+ * LogEngine.debug('Processing user data', { userId: 123, email: 'user@example.com' });
45
+ * ```
46
+ */
47
+ debug: (message: string, data?: LogData) => void;
48
+ /**
49
+ * Log an info message with automatic data redaction
50
+ * Shown in DEVELOPMENT and PRODUCTION modes
51
+ * @param message - The info message to log
52
+ * @param data - Optional data object to log (sensitive data will be redacted)
53
+ * @example
54
+ * ```typescript
55
+ * LogEngine.info('User login successful', { username: 'john' });
56
+ * ```
57
+ */
58
+ info: (message: string, data?: LogData) => void;
59
+ /**
60
+ * Log a warning message with automatic data redaction
61
+ * Shown in DEVELOPMENT and PRODUCTION modes
62
+ * @param message - The warning message to log
63
+ * @param data - Optional data object to log (sensitive data will be redacted)
64
+ * @example
65
+ * ```typescript
66
+ * LogEngine.warn('API rate limit approaching', { requestsRemaining: 10 });
67
+ * ```
68
+ */
69
+ warn: (message: string, data?: LogData) => void;
70
+ /**
71
+ * Log an error message with automatic data redaction
72
+ * Shown in DEVELOPMENT and PRODUCTION modes
73
+ * @param message - The error message to log
74
+ * @param data - Optional data object to log (sensitive data will be redacted)
75
+ * @example
76
+ * ```typescript
77
+ * LogEngine.error('Database connection failed', { host: 'localhost', port: 5432 });
78
+ * ```
79
+ */
80
+ error: (message: string, data?: LogData) => void;
81
+ /**
82
+ * Log a critical message with automatic data redaction
83
+ * Always shown regardless of mode (except OFF)
84
+ * @param message - The critical log message to log
85
+ * @param data - Optional data object to log (sensitive data will be redacted)
86
+ * @example
87
+ * ```typescript
88
+ * LogEngine.log('Application starting', { version: '1.0.0' });
89
+ * ```
90
+ */
91
+ log: (message: string, data?: LogData) => void;
92
+ /**
93
+ * Log a debug message without redaction (use with caution)
94
+ * Bypasses automatic data redaction for debugging purposes
95
+ * @param message - The debug message to log
96
+ * @param data - Optional data object to log (no redaction applied)
97
+ */
98
+ debugRaw: (message: string, data?: LogData) => void;
99
+ /**
100
+ * Log an info message without redaction (use with caution)
101
+ * Bypasses automatic data redaction for debugging purposes
102
+ * @param message - The info message to log
103
+ * @param data - Optional data object to log (no redaction applied)
104
+ */
105
+ infoRaw: (message: string, data?: LogData) => void;
106
+ /**
107
+ * Log a warning message without redaction (use with caution)
108
+ * Bypasses automatic data redaction for debugging purposes
109
+ * @param message - The warning message to log
110
+ * @param data - Optional data object to log (no redaction applied)
111
+ */
112
+ warnRaw: (message: string, data?: LogData) => void;
113
+ /**
114
+ * Log an error message without redaction (use with caution)
115
+ * Bypasses automatic data redaction for debugging purposes
116
+ * @param message - The error message to log
117
+ * @param data - Optional data object to log (no redaction applied)
118
+ */
119
+ errorRaw: (message: string, data?: LogData) => void;
120
+ /**
121
+ * Log a critical message without redaction (use with caution)
122
+ * Bypasses automatic data redaction for debugging purposes
123
+ * @param message - The critical log message to log
124
+ * @param data - Optional data object to log (no redaction applied)
125
+ */
126
+ logRaw: (message: string, data?: LogData) => void;
127
+ /**
128
+ * Configure data redaction settings
129
+ * @param config - Partial redaction configuration to apply
130
+ */
131
+ configureRedaction: (config: Partial<RedactionConfig>) => void;
132
+ /**
133
+ * Refresh redaction configuration from environment variables
134
+ * Useful for picking up runtime environment changes
135
+ */
136
+ refreshRedactionConfig: () => void;
137
+ /**
138
+ * Reset redaction configuration to defaults
139
+ */
140
+ resetRedactionConfig: () => void;
141
+ /**
142
+ * Get current redaction configuration
143
+ * @returns Current redaction configuration
144
+ */
145
+ getRedactionConfig: () => RedactionConfig;
146
+ /**
147
+ * Add custom regex patterns for advanced field detection
148
+ * @param patterns - Array of regex patterns to add
149
+ */
150
+ addCustomRedactionPatterns: (patterns: RegExp[]) => void;
151
+ /**
152
+ * Clear all custom redaction patterns
153
+ */
154
+ clearCustomRedactionPatterns: () => void;
155
+ /**
156
+ * Add custom sensitive field names to the existing list
157
+ * @param fields - Array of field names to add
158
+ */
159
+ addSensitiveFields: (fields: string[]) => void;
160
+ /**
161
+ * Test if a field name would be redacted with current configuration
162
+ * @param fieldName - Field name to test
163
+ * @returns true if field would be redacted, false otherwise
164
+ */
165
+ testFieldRedaction: (fieldName: string) => boolean;
166
+ /**
167
+ * Temporarily disable redaction for a specific logging call
168
+ * @returns LogEngine instance with redaction bypassed
169
+ * @example
170
+ * ```typescript
171
+ * LogEngine.withoutRedaction().info('Debug data', sensitiveObject);
172
+ * ```
173
+ */
174
+ withoutRedaction: () => ILogEngineWithoutRedaction;
175
+ };
176
+ export { LogMode, LogLevel } from './types';
177
+ export type { LoggerConfig, LogFormatConfig, RedactionConfig, LogOutputHandler, BuiltInOutputHandler, OutputTarget, FileOutputConfig, HttpOutputConfig, AdvancedOutputConfig, EnhancedOutputTarget } from './types';
178
+ export { DataRedactor, defaultRedactionConfig, RedactionController } from './redaction';
179
+ export default LogEngine;
180
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,0BAA0B,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAMlG;;;GAGG;AACH,eAAO,MAAM,SAAS;IACpB;;;;;;;SAOK;wBACe,OAAO,CAAC,YAAY,CAAC,KAAG,IAAI;IAGhD;;;;;;;;;SASK;qBACY,MAAM,SAAS,OAAO,KAAG,IAAI;IAE9C;;;;;;;;;SASK;oBACW,MAAM,SAAS,OAAO,KAAG,IAAI;IAE7C;;;;;;;;;SASK;oBACW,MAAM,SAAS,OAAO,KAAG,IAAI;IAE7C;;;;;;;;;SASK;qBACY,MAAM,SAAS,OAAO,KAAG,IAAI;IAE9C;;;;;;;;;SASK;mBACU,MAAM,SAAS,OAAO,KAAG,IAAI;IAG5C;;;;;SAKK;wBACe,MAAM,SAAS,OAAO,KAAG,IAAI;IAEjD;;;;;SAKK;uBACc,MAAM,SAAS,OAAO,KAAG,IAAI;IAEhD;;;;;SAKK;uBACc,MAAM,SAAS,OAAO,KAAG,IAAI;IAEhD;;;;;SAKK;wBACe,MAAM,SAAS,OAAO,KAAG,IAAI;IAEjD;;;;;SAKK;sBACa,MAAM,SAAS,OAAO,KAAG,IAAI;IAG/C;;;SAGK;iCACwB,OAAO,CAAC,eAAe,CAAC,KAAG,IAAI;IAE5D;;;SAGK;kCACuB,IAAI;IAEhC;;SAEK;gCACqB,IAAI;IAE9B;;;SAGK;8BACmB,eAAe;IAGvC;;;SAGK;2CACkC,MAAM,EAAE,KAAG,IAAI;IAEtD;;SAEK;wCAC6B,IAAI;IAEtC;;;SAGK;iCACwB,MAAM,EAAE,KAAG,IAAI;IAE5C;;;;SAIK;oCAC2B,MAAM,KAAG,OAAO;IAEhD;;;;;;;SAOK;4BACiB,0BAA0B;CAOjD,CAAC;AAGF,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC5C,YAAY,EACV,YAAY,EACZ,eAAe,EACf,eAAe,EACf,gBAAgB,EAChB,oBAAoB,EACpB,YAAY,EAEZ,gBAAgB,EAChB,gBAAgB,EAChB,oBAAoB,EACpB,oBAAoB,EACrB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,YAAY,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAGxF,eAAe,SAAS,CAAC"}
@@ -0,0 +1,194 @@
1
+ /**
2
+ * Main LogEngine module - provides a comprehensive logging solution
3
+ * with mode-based filtering, colorized output, and automatic data redaction
4
+ *
5
+ * Features a modular architecture with separate modules for:
6
+ * - Logger: Core logging functionality with environment-based configuration
7
+ * - Formatter: Message formatting with ANSI colors and timestamps
8
+ * - Redaction: Automatic sensitive data protection with customizable patterns
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * import { LogEngine, LogMode } from '@wgtechlabs/log-engine';
13
+ *
14
+ * // Configure logging mode
15
+ * LogEngine.configure({ mode: LogMode.DEBUG });
16
+ *
17
+ * // Log with automatic redaction
18
+ * LogEngine.info('User login', { username: 'john', password: 'secret123' });
19
+ * // Output: [2025-06-18T...][3:45PM][INFO]: User login { username: 'john', password: '[REDACTED]' }
20
+ * ```
21
+ */
22
+ import { Logger } from './logger/index.js';
23
+ import { DataRedactor, defaultRedactionConfig } from './redaction/index.js';
24
+ // Create a singleton logger instance
25
+ const logger = new Logger();
26
+ /**
27
+ * LogEngine - The main interface for logging operations
28
+ * Provides a simple, intuitive API for all logging needs with security-first design
29
+ */
30
+ export const LogEngine = {
31
+ /**
32
+ * Configure the logger with new settings
33
+ * @param config - Configuration object containing logger settings
34
+ * @example
35
+ * ```typescript
36
+ * LogEngine.configure({ mode: LogMode.PRODUCTION });
37
+ * ```
38
+ */
39
+ configure: (config) => logger.configure(config),
40
+ // Standard logging methods with automatic redaction
41
+ /**
42
+ * Log a debug message with automatic data redaction
43
+ * Only shown in DEVELOPMENT mode
44
+ * @param message - The debug message to log
45
+ * @param data - Optional data object to log (sensitive data will be redacted)
46
+ * @example
47
+ * ```typescript
48
+ * LogEngine.debug('Processing user data', { userId: 123, email: 'user@example.com' });
49
+ * ```
50
+ */
51
+ debug: (message, data) => logger.debug(message, data),
52
+ /**
53
+ * Log an info message with automatic data redaction
54
+ * Shown in DEVELOPMENT and PRODUCTION modes
55
+ * @param message - The info message to log
56
+ * @param data - Optional data object to log (sensitive data will be redacted)
57
+ * @example
58
+ * ```typescript
59
+ * LogEngine.info('User login successful', { username: 'john' });
60
+ * ```
61
+ */
62
+ info: (message, data) => logger.info(message, data),
63
+ /**
64
+ * Log a warning message with automatic data redaction
65
+ * Shown in DEVELOPMENT and PRODUCTION modes
66
+ * @param message - The warning message to log
67
+ * @param data - Optional data object to log (sensitive data will be redacted)
68
+ * @example
69
+ * ```typescript
70
+ * LogEngine.warn('API rate limit approaching', { requestsRemaining: 10 });
71
+ * ```
72
+ */
73
+ warn: (message, data) => logger.warn(message, data),
74
+ /**
75
+ * Log an error message with automatic data redaction
76
+ * Shown in DEVELOPMENT and PRODUCTION modes
77
+ * @param message - The error message to log
78
+ * @param data - Optional data object to log (sensitive data will be redacted)
79
+ * @example
80
+ * ```typescript
81
+ * LogEngine.error('Database connection failed', { host: 'localhost', port: 5432 });
82
+ * ```
83
+ */
84
+ error: (message, data) => logger.error(message, data),
85
+ /**
86
+ * Log a critical message with automatic data redaction
87
+ * Always shown regardless of mode (except OFF)
88
+ * @param message - The critical log message to log
89
+ * @param data - Optional data object to log (sensitive data will be redacted)
90
+ * @example
91
+ * ```typescript
92
+ * LogEngine.log('Application starting', { version: '1.0.0' });
93
+ * ```
94
+ */
95
+ log: (message, data) => logger.log(message, data),
96
+ // Raw methods that bypass redaction (use with caution)
97
+ /**
98
+ * Log a debug message without redaction (use with caution)
99
+ * Bypasses automatic data redaction for debugging purposes
100
+ * @param message - The debug message to log
101
+ * @param data - Optional data object to log (no redaction applied)
102
+ */
103
+ debugRaw: (message, data) => logger.debugRaw(message, data),
104
+ /**
105
+ * Log an info message without redaction (use with caution)
106
+ * Bypasses automatic data redaction for debugging purposes
107
+ * @param message - The info message to log
108
+ * @param data - Optional data object to log (no redaction applied)
109
+ */
110
+ infoRaw: (message, data) => logger.infoRaw(message, data),
111
+ /**
112
+ * Log a warning message without redaction (use with caution)
113
+ * Bypasses automatic data redaction for debugging purposes
114
+ * @param message - The warning message to log
115
+ * @param data - Optional data object to log (no redaction applied)
116
+ */
117
+ warnRaw: (message, data) => logger.warnRaw(message, data),
118
+ /**
119
+ * Log an error message without redaction (use with caution)
120
+ * Bypasses automatic data redaction for debugging purposes
121
+ * @param message - The error message to log
122
+ * @param data - Optional data object to log (no redaction applied)
123
+ */
124
+ errorRaw: (message, data) => logger.errorRaw(message, data),
125
+ /**
126
+ * Log a critical message without redaction (use with caution)
127
+ * Bypasses automatic data redaction for debugging purposes
128
+ * @param message - The critical log message to log
129
+ * @param data - Optional data object to log (no redaction applied)
130
+ */
131
+ logRaw: (message, data) => logger.logRaw(message, data),
132
+ // Redaction configuration methods
133
+ /**
134
+ * Configure data redaction settings
135
+ * @param config - Partial redaction configuration to apply
136
+ */
137
+ configureRedaction: (config) => DataRedactor.updateConfig(config),
138
+ /**
139
+ * Refresh redaction configuration from environment variables
140
+ * Useful for picking up runtime environment changes
141
+ */
142
+ refreshRedactionConfig: () => DataRedactor.refreshConfig(),
143
+ /**
144
+ * Reset redaction configuration to defaults
145
+ */
146
+ resetRedactionConfig: () => DataRedactor.updateConfig(defaultRedactionConfig),
147
+ /**
148
+ * Get current redaction configuration
149
+ * @returns Current redaction configuration
150
+ */
151
+ getRedactionConfig: () => DataRedactor.getConfig(),
152
+ // Advanced redaction methods
153
+ /**
154
+ * Add custom regex patterns for advanced field detection
155
+ * @param patterns - Array of regex patterns to add
156
+ */
157
+ addCustomRedactionPatterns: (patterns) => DataRedactor.addCustomPatterns(patterns),
158
+ /**
159
+ * Clear all custom redaction patterns
160
+ */
161
+ clearCustomRedactionPatterns: () => DataRedactor.clearCustomPatterns(),
162
+ /**
163
+ * Add custom sensitive field names to the existing list
164
+ * @param fields - Array of field names to add
165
+ */
166
+ addSensitiveFields: (fields) => DataRedactor.addSensitiveFields(fields),
167
+ /**
168
+ * Test if a field name would be redacted with current configuration
169
+ * @param fieldName - Field name to test
170
+ * @returns true if field would be redacted, false otherwise
171
+ */
172
+ testFieldRedaction: (fieldName) => DataRedactor.testFieldRedaction(fieldName),
173
+ /**
174
+ * Temporarily disable redaction for a specific logging call
175
+ * @returns LogEngine instance with redaction bypassed
176
+ * @example
177
+ * ```typescript
178
+ * LogEngine.withoutRedaction().info('Debug data', sensitiveObject);
179
+ * ```
180
+ */
181
+ withoutRedaction: () => ({
182
+ debug: (message, data) => logger.debugRaw(message, data),
183
+ info: (message, data) => logger.infoRaw(message, data),
184
+ warn: (message, data) => logger.warnRaw(message, data),
185
+ error: (message, data) => logger.errorRaw(message, data),
186
+ log: (message, data) => logger.logRaw(message, data)
187
+ })
188
+ };
189
+ // Re-export types and utilities for external use
190
+ export { LogMode, LogLevel } from './types/index.js';
191
+ export { DataRedactor, defaultRedactionConfig, RedactionController } from './redaction/index.js';
192
+ // Default export for convenience
193
+ export default LogEngine;
194
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,159 @@
1
+ /**
2
+ * Advanced output handlers for log-engine
3
+ * Provides file, HTTP, and other production-ready output handlers
4
+ */
5
+ import * as fs from 'fs';
6
+ import type { FileOutputConfig, HttpOutputConfig } from '../types';
7
+ /**
8
+ * Secure filesystem operations for logging operations
9
+ *
10
+ * SECURITY NOTE: These functions implement comprehensive path validation and access controls
11
+ * to prevent path traversal attacks, directory injection, and unauthorized file access.
12
+ * ESLint security rules are disabled for specific fs operations because:
13
+ *
14
+ * 1. All paths are validated through validatePath() which:
15
+ * - Prevents directory traversal (../)
16
+ * - Restricts access to predefined safe directories
17
+ * - Blocks access to system directories
18
+ * - Normalizes and resolves paths securely
19
+ *
20
+ * 2. The logging library requires dynamic file paths by design (user-configurable log files)
21
+ * 3. All operations are wrapped in try-catch with comprehensive error handling
22
+ * 4. File operations are restricted to log and temp directories only
23
+ */
24
+ /**
25
+ * Predefined safe base directories for different operation types
26
+ * Restricted to specific subdirectories to prevent unauthorized access
27
+ */
28
+ declare const SAFE_BASE_DIRS: {
29
+ readonly LOG_FILES: readonly [string, string, string];
30
+ readonly TEMP_FILES: readonly [string, string, string, string];
31
+ readonly CONFIG_FILES: readonly [string, string, string];
32
+ };
33
+ /**
34
+ * Validates file path with comprehensive security checks
35
+ * Prevents path traversal, restricts to safe directories, blocks system paths
36
+ */
37
+ declare function validatePath(filePath: string): string;
38
+ /**
39
+ * Secure file existence check
40
+ * Uses fs.accessSync instead of fs.existsSync for better security practices
41
+ */
42
+ declare function secureExistsSync(filePath: string): boolean;
43
+ /**
44
+ * Secure directory creation with recursive option support
45
+ * Restricted to log and temp directories only
46
+ */
47
+ declare function secureMkdirSync(dirPath: string, options?: {
48
+ recursive?: boolean;
49
+ }): void;
50
+ /**
51
+ * Secure file stat operation
52
+ * Returns file system statistics for validated paths only
53
+ */
54
+ declare function secureStatSync(filePath: string): fs.Stats;
55
+ /**
56
+ * Secure file write operation
57
+ * Validates path and data before writing to prevent injection attacks
58
+ */
59
+ declare function secureWriteFileSync(filePath: string, data: string, options?: {
60
+ flag?: string;
61
+ }): void;
62
+ /**
63
+ * Secure file deletion
64
+ * Restricted to log and temp files only for safety
65
+ */
66
+ declare function secureUnlinkSync(filePath: string): void;
67
+ /**
68
+ * Secure file rename/move operation
69
+ * Both source and destination must be in safe directories
70
+ */
71
+ declare function secureRenameSync(oldPath: string, newPath: string): void;
72
+ /**
73
+ * File output handler with rotation support and concurrency protection
74
+ * Implements atomic file operations and write queuing to prevent corruption
75
+ */
76
+ export declare class FileOutputHandler {
77
+ private config;
78
+ private currentFileSize;
79
+ private rotationInProgress;
80
+ private writeQueue;
81
+ constructor(config: FileOutputConfig);
82
+ /**
83
+ * Default formatter for file output
84
+ */
85
+ private defaultFormatter;
86
+ /**
87
+ * Write log to file with rotation support and concurrency protection
88
+ * Queues writes during rotation to prevent file corruption
89
+ */
90
+ write: (level: string, message: string, data?: unknown) => void;
91
+ /**
92
+ * Write to file with concurrency protection and rotation check
93
+ * If rotation is in progress, messages are queued to prevent corruption
94
+ */
95
+ private writeToFile;
96
+ /**
97
+ * Process queued writes after rotation completes
98
+ */
99
+ private processWriteQueue;
100
+ /**
101
+ * Rotate log files when size limit is reached
102
+ * Implements concurrency protection to prevent corruption during rotation
103
+ */
104
+ private rotateFile;
105
+ /**
106
+ * Clean up resources and process any remaining queued writes
107
+ */
108
+ destroy(): void;
109
+ }
110
+ /**
111
+ * HTTP output handler for sending logs to remote endpoints
112
+ */
113
+ export declare class HttpOutputHandler {
114
+ private config;
115
+ private logBuffer;
116
+ private flushTimeout;
117
+ constructor(config: HttpOutputConfig);
118
+ /**
119
+ * Default formatter for HTTP output
120
+ */
121
+ private defaultFormatter;
122
+ /**
123
+ * Write log to HTTP endpoint with batching support
124
+ */
125
+ write: (level: string, message: string, data?: unknown) => void;
126
+ /**
127
+ * Flush buffered logs to HTTP endpoint
128
+ */
129
+ private flush;
130
+ /**
131
+ * Send HTTP request with appropriate method based on environment
132
+ */
133
+ private sendHttpRequest;
134
+ /**
135
+ * Fallback HTTP implementation for Node.js environments without fetch
136
+ */
137
+ private sendHttpRequestNodeJS;
138
+ /**
139
+ * Cleanup method to prevent memory leaks
140
+ */
141
+ destroy(): void;
142
+ }
143
+ /**
144
+ * Returns a logging handler function based on the specified type and configuration.
145
+ *
146
+ * Supported types are:
147
+ * - `'console'`: Logs to the console using the appropriate method for the log level.
148
+ * - `'silent'`: Returns a no-op handler that discards all logs.
149
+ * - `'file'`: Writes logs to a file with optional rotation; requires `filePath` in config.
150
+ * - `'http'`: Sends logs to a remote HTTP endpoint; requires `url` in config.
151
+ *
152
+ * If required configuration is missing or initialization fails, logs an error and returns either a fallback handler or `null`.
153
+ *
154
+ * @param type - The type of output handler to create (`'console'`, `'silent'`, `'file'`, or `'http'`)
155
+ * @returns A log handler function or `null` if the handler cannot be created
156
+ */
157
+ export declare function createBuiltInHandler(type: string, config?: Record<string, unknown>): ((level: string, message: string, data?: unknown) => void) | null;
158
+ export { secureExistsSync, secureMkdirSync, secureStatSync, secureWriteFileSync, secureUnlinkSync, secureRenameSync, validatePath, SAFE_BASE_DIRS };
159
+ //# sourceMappingURL=advanced-outputs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"advanced-outputs.d.ts","sourceRoot":"","sources":["../../../src/logger/advanced-outputs.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AAGzB,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAuBnE;;;;;;;;;;;;;;;;GAgBG;AAEH;;;GAGG;AACH,QAAA,MAAM,cAAc;;;;CAIV,CAAC;AAEX;;;GAGG;AACH,iBAAS,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAqC9C;AAED;;;GAGG;AACH,iBAAS,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CASnD;AAED;;;GAGG;AACH,iBAAS,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CAWjF;AAED;;;GAGG;AACH,iBAAS,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,EAAE,CAAC,KAAK,CAUlD;AAED;;;GAGG;AACH,iBAAS,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAgB9F;AAED;;;GAGG;AACH,iBAAS,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAkBhD;AAED;;;GAGG;AACH,iBAAS,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAoBhE;AAED;;;GAGG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAA6B;IAC3C,OAAO,CAAC,eAAe,CAAa;IACpC,OAAO,CAAC,kBAAkB,CAAkB;IAC5C,OAAO,CAAC,UAAU,CAAiE;gBAEvE,MAAM,EAAE,gBAAgB;IA6BpC;;SAEK;IACL,OAAO,CAAC,gBAAgB,CAItB;IAEF;;;SAGK;IACE,KAAK,GAAI,OAAO,MAAM,EAAE,SAAS,MAAM,EAAE,OAAO,OAAO,KAAG,IAAI,CAcnE;IAEF;;;OAGG;IACH,OAAO,CAAC,WAAW;IAgBnB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAczB;;;SAGK;IACL,OAAO,CAAC,UAAU;IAwClB;;OAEG;IACI,OAAO,IAAI,IAAI;CAUvB;AAED;;GAEG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAA6B;IAC3C,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,YAAY,CAA+B;gBAEvC,MAAM,EAAE,gBAAgB;IAYpC;;SAEK;IACL,OAAO,CAAC,gBAAgB,CAStB;IAEF;;SAEK;IACE,KAAK,GAAI,OAAO,MAAM,EAAE,SAAS,MAAM,EAAE,OAAO,OAAO,KAAG,IAAI,CA0BnE;IAEF;;SAEK;IACL,OAAO,CAAC,KAAK;IAqBb;;SAEK;IACL,OAAO,CAAC,eAAe;IAiBvB;;SAEK;IACL,OAAO,CAAC,qBAAqB;IAgD7B;;OAEG;IACI,OAAO,IAAI,IAAI;CAQvB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC,GAAG,IAAI,CA2CtJ;AAGD,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,EACZ,cAAc,EACf,CAAC"}