unnbound-logger-sdk 2.0.10 → 3.0.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.
@@ -1,472 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.UnnboundLogger = void 0;
7
- /**
8
- * Core logger implementation
9
- */
10
- const pino_1 = __importDefault(require("pino"));
11
- const logger_utils_1 = require("./utils/logger-utils");
12
- const uuid_1 = require("uuid");
13
- const trace_context_1 = require("./utils/trace-context");
14
- const axios_1 = require("axios");
15
- const http_status_messages_1 = require("./utils/http-status-messages");
16
- /**
17
- * UnnboundLogger provides typed, structured logging using Pino
18
- */
19
- class UnnboundLogger {
20
- /**
21
- * Creates a new UnnboundLogger instance
22
- * @param options - Configuration options for the logger
23
- */
24
- constructor(options = {}) {
25
- // Trace middleware
26
- this.traceMiddleware = (req, res, next) => {
27
- // Check if the route should be ignored
28
- if (this.shouldIgnorePath(req.path, this.ignoreTraceRoutes)) {
29
- return next();
30
- }
31
- const traceId = req.header(this.traceHeaderKey) || (0, uuid_1.v4)();
32
- res.setHeader(this.traceHeaderKey, traceId);
33
- trace_context_1.traceContext.run(traceId, () => {
34
- // Log the incoming request
35
- const reqLog = this.httpRequest(req, { traceId });
36
- // Capture response body for logging
37
- const originalSend = res.send;
38
- res.send = function (body) {
39
- res.locals.body = body;
40
- return originalSend.call(this, body);
41
- };
42
- // Log the response when it finishes
43
- res.on('finish', () => {
44
- this.httpResponse(res, req, { requestId: reqLog.requestId, traceId });
45
- });
46
- next();
47
- });
48
- };
49
- // Axios trace middleware
50
- this.axiosTraceMiddleware = {
51
- onFulfilled: (config) => {
52
- // Check if the URL should be ignored
53
- if (config.url && this.shouldIgnorePath(config.url, this.ignoreAxiosTraceRoutes)) {
54
- return config;
55
- }
56
- const traceId = trace_context_1.traceContext.getTraceId();
57
- if (traceId) {
58
- const headers = new axios_1.AxiosHeaders(config.headers);
59
- headers.set(this.traceHeaderKey, traceId);
60
- config.headers = headers;
61
- }
62
- // Store request start time and generate requestId for duration calculation and correlation
63
- const startTime = Date.now();
64
- const requestId = (0, uuid_1.v4)();
65
- config.metadata = { startTime, requestId };
66
- // Log the outgoing request using proper httpRequest method
67
- const mockReq = {
68
- method: config.method?.toUpperCase() || 'UNKNOWN',
69
- url: `${config.baseURL || ''}${config.url}`,
70
- originalUrl: `${config.baseURL || ''}${config.url}`,
71
- headers: config.headers || {},
72
- body: (0, logger_utils_1.safeJsonParse)(config.data),
73
- ip: 'outgoing', // Mark as outgoing request
74
- protocol: 'https', // Default for outgoing
75
- secure: true,
76
- get: () => undefined // Mock get method for constructFullUrl
77
- };
78
- this.httpRequest(mockReq, {
79
- traceId,
80
- requestId,
81
- startTime
82
- });
83
- return config;
84
- },
85
- onRejected: (error) => {
86
- return Promise.reject(error);
87
- }
88
- };
89
- // Axios response interceptor (should be used separately)
90
- this.axiosResponseInterceptor = {
91
- onFulfilled: (response) => {
92
- // Check if the URL should be ignored
93
- const url = `${response.config?.baseURL || ''}${response.config?.url}`;
94
- if (url && this.shouldIgnorePath(url, this.ignoreAxiosTraceRoutes)) {
95
- return response;
96
- }
97
- // Calculate duration
98
- const startTime = response.config.metadata?.startTime || Date.now();
99
- const requestId = response.config.metadata?.requestId;
100
- const duration = Date.now() - startTime;
101
- // Log the successful response using proper httpResponse method
102
- const mockReq = {
103
- method: response.config.method?.toUpperCase() || 'UNKNOWN',
104
- url: `${response.config.baseURL || ''}${response.config.url}`,
105
- originalUrl: `${response.config.baseURL || ''}${response.config.url}`,
106
- ip: 'outgoing', // Mark as outgoing request
107
- protocol: 'https', // Default for outgoing
108
- secure: true,
109
- get: () => undefined // Mock get method for constructFullUrl
110
- };
111
- const mockRes = {
112
- statusCode: response.status,
113
- locals: {
114
- body: (0, logger_utils_1.safeJsonParse)(response.data),
115
- startTime: startTime,
116
- traceId: trace_context_1.traceContext.getTraceId(),
117
- requestId: requestId
118
- },
119
- getHeaders: () => response.headers || {}
120
- };
121
- this.httpResponse(mockRes, mockReq, {
122
- requestId,
123
- duration,
124
- traceId: trace_context_1.traceContext.getTraceId()
125
- });
126
- return response;
127
- },
128
- onRejected: (error) => {
129
- // Check if the URL should be ignored
130
- const url = `${error.config?.baseURL || ''}${error.config?.url}`;
131
- if (url && this.shouldIgnorePath(url, this.ignoreAxiosTraceRoutes)) {
132
- return Promise.reject(error);
133
- }
134
- // Calculate duration for error responses
135
- const startTime = error.config?.metadata?.startTime || Date.now();
136
- const requestId = error.config?.metadata?.requestId;
137
- const duration = Date.now() - startTime;
138
- // Log the error response using proper httpResponse method
139
- if (error.response) {
140
- const mockReq = {
141
- method: error.config?.method?.toUpperCase() || 'UNKNOWN',
142
- url: `${error.config?.baseURL || ''}${error.config?.url}`,
143
- originalUrl: `${error.config?.baseURL || ''}${error.config?.url}`,
144
- ip: 'outgoing', // Mark as outgoing request
145
- protocol: 'https', // Default for outgoing
146
- secure: true,
147
- get: () => undefined // Mock get method for constructFullUrl
148
- };
149
- const mockRes = {
150
- statusCode: error.response.status,
151
- locals: {
152
- body: (0, logger_utils_1.safeJsonParse)(error.response.data),
153
- startTime: startTime,
154
- traceId: trace_context_1.traceContext.getTraceId(),
155
- requestId: requestId
156
- },
157
- getHeaders: () => error.response.headers || {}
158
- };
159
- this.httpResponse(mockRes, mockReq, {
160
- requestId,
161
- duration,
162
- traceId: trace_context_1.traceContext.getTraceId()
163
- });
164
- }
165
- else {
166
- // For network errors without response, log as general error
167
- this.error('HTTP Request Failed', {
168
- context: {
169
- reason: 'No response received',
170
- method: error.config?.method?.toUpperCase() || 'UNKNOWN',
171
- url: `${error.config?.baseURL || ''}${error.config?.url}`,
172
- },
173
- error: error.message,
174
- requestId,
175
- traceId: trace_context_1.traceContext.getTraceId()
176
- });
177
- }
178
- return Promise.reject(error);
179
- }
180
- };
181
- this.workflowId = process.env.UNNBOUND_WORKFLOW_ID || '';
182
- this.workflowUrl = process.env.UNNBOUND_WORKFLOW_URL || '';
183
- this.serviceId = process.env.UNNBOUND_SERVICE_ID || '';
184
- this.deploymentId = process.env.UNNBOUND_DEPLOYMENT_ID || '';
185
- this.traceHeaderKey = options.traceHeaderKey || 'unnbound-trace-id';
186
- this.ignoreTraceRoutes = options.ignoreTraceRoutes || [];
187
- this.ignoreAxiosTraceRoutes = options.ignoreAxiosTraceRoutes || [];
188
- // Create Pino logger
189
- this.logger = (0, pino_1.default)({
190
- level: 'info',
191
- base: {}, // Disable all default base fields (pid, hostname)
192
- timestamp: false, // Let CloudWatch handle timestamps
193
- messageKey: 'messages', // Change message field from 'msg' to 'messages'
194
- formatters: {
195
- level: (label) => {
196
- return { level: label };
197
- },
198
- },
199
- });
200
- }
201
- /**
202
- * Checks if a path matches any of the ignore patterns
203
- * @param path - The path to check
204
- * @param patterns - Array of glob patterns to match against
205
- * @returns boolean indicating if the path should be ignored
206
- */
207
- shouldIgnorePath(path, patterns) {
208
- return patterns.some(pattern => {
209
- // Convert glob pattern to regex
210
- const regexPattern = pattern
211
- .replace(/\./g, '\\.') // Escape dots
212
- .replace(/\*/g, '.*') // Convert * to .*
213
- .replace(/\?/g, '.'); // Convert ? to .
214
- const regex = new RegExp(`^${regexPattern}$`);
215
- return regex.test(path);
216
- });
217
- }
218
- /**
219
- * Logs a general message
220
- * @param level - Log level
221
- * @param message - Log message
222
- * @param options - Additional logging options
223
- */
224
- log(level, message, options = {}) {
225
- const logId = (0, uuid_1.v4)();
226
- const traceId = options.traceId || trace_context_1.traceContext.getTraceId() || (0, uuid_1.v4)();
227
- const requestId = options.requestId || (0, uuid_1.v4)();
228
- let logEntry;
229
- const { traceId: optionTraceId, requestId: optionRequestId, level: optionLevel, ...restOptions } = options;
230
- // If restOptions has any properties, we'll add them to data later
231
- const hasRestOptions = Object.keys(restOptions).length > 0;
232
- const baseEntry = {
233
- logId,
234
- type: 'general',
235
- workflowId: this.workflowId,
236
- serviceId: this.serviceId,
237
- traceId,
238
- requestId,
239
- deploymentId: this.deploymentId,
240
- };
241
- if (message instanceof Error) {
242
- const error = {
243
- name: message.name,
244
- message: message.message,
245
- stack: message.stack,
246
- };
247
- logEntry = {
248
- ...baseEntry,
249
- message: message.name,
250
- error,
251
- ...(hasRestOptions && { data: restOptions }),
252
- };
253
- }
254
- else if (typeof message === 'string') {
255
- logEntry = {
256
- ...baseEntry,
257
- message,
258
- ...(hasRestOptions && { data: restOptions }),
259
- };
260
- }
261
- else {
262
- // If message is an object, wrap it in a 'data' key
263
- const messageObj = message;
264
- logEntry = {
265
- ...baseEntry,
266
- message: 'Structured log data',
267
- data: hasRestOptions ? { ...messageObj, ...restOptions } : messageObj,
268
- };
269
- }
270
- // Separate the message from the log data and explicitly exclude any level field
271
- const { message: logMessage, level: excludedLevel, ...logData } = logEntry;
272
- this.logger[level](logData, logMessage);
273
- return logEntry;
274
- }
275
- /**
276
- * Logs an error message
277
- * @param message - Error message or object
278
- * @param options - Additional logging options
279
- */
280
- error(message, options = {}) {
281
- return this.log('error', message, options);
282
- }
283
- /**
284
- * Logs a warning message
285
- * @param message - Warning message
286
- * @param options - Additional logging options
287
- */
288
- warn(message, options = {}) {
289
- return this.log('warn', message, options);
290
- }
291
- /**
292
- * Logs an info message
293
- * @param message - Info message
294
- * @param options - Additional logging options
295
- */
296
- info(message, options = {}) {
297
- return this.log('info', message, options);
298
- }
299
- /**
300
- * Logs a debug message
301
- * @param message - Debug message
302
- * @param options - Additional logging options
303
- */
304
- debug(message, options = {}) {
305
- return this.log('debug', message, options);
306
- }
307
- /**
308
- * Constructs the full URL from request information
309
- * @param req - Express request object
310
- * @returns Full URL string
311
- */
312
- constructFullUrl(req) {
313
- // If the URL is already absolute, return it directly
314
- const reqUrl = req.originalUrl || req.url;
315
- if (reqUrl?.startsWith('http://') || reqUrl?.startsWith('https://')) {
316
- return reqUrl;
317
- }
318
- // Check if we have a workflow URL configured (preferred method)
319
- if (this.workflowUrl) {
320
- // Use workflow URL as the base URL
321
- return `${this.workflowUrl.replace(/\/$/, '')}${reqUrl}`;
322
- }
323
- // Fallback to constructing from request info for incoming requests
324
- const protocol = req.protocol || (req.secure ? 'https' : 'http');
325
- const host = req.get('host') || req.get('x-forwarded-host') || 'localhost';
326
- return `${protocol}://${host}${reqUrl}`;
327
- }
328
- /**
329
- * Logs an HTTP request
330
- * @param req - Express request object
331
- * @param options - Additional logging options
332
- * @returns The request ID for correlating with the response
333
- */
334
- httpRequest(req, options = {}) {
335
- const logId = (0, uuid_1.v4)();
336
- const traceId = options.traceId || trace_context_1.traceContext.getTraceId() || (0, uuid_1.v4)();
337
- const requestId = options.requestId || (0, uuid_1.v4)();
338
- const startTime = options.startTime || Date.now();
339
- // Store request metadata in res.locals for later use
340
- if (req.res) {
341
- req.res.locals.requestId = requestId;
342
- req.res.locals.startTime = startTime;
343
- req.res.locals.traceId = traceId;
344
- req.res.locals.workflowId = this.workflowId;
345
- req.res.locals.workflowUrl = this.workflowUrl;
346
- req.res.locals.serviceId = this.serviceId;
347
- }
348
- const logEntry = {
349
- logId,
350
- type: 'httpRequest',
351
- message: req.ip === 'outgoing' ? 'Outgoing HTTP Request' : 'Incoming HTTP Request',
352
- workflowId: this.workflowId,
353
- serviceId: this.serviceId,
354
- traceId,
355
- requestId,
356
- deploymentId: this.deploymentId,
357
- duration: 0, // Will be updated in response
358
- httpRequest: {
359
- url: this.constructFullUrl(req),
360
- method: req.method,
361
- headers: (0, logger_utils_1.filterHeaders)(req.headers),
362
- ip: (0, logger_utils_1.normalizeIp)(req.ip),
363
- body: (0, logger_utils_1.safeJsonParse)(req.body),
364
- },
365
- };
366
- const { message: logMessage, ...logData } = logEntry;
367
- this.logger[options.level || 'info'](logData, logMessage);
368
- return logEntry;
369
- }
370
- /**
371
- * Logs an HTTP response
372
- * @param res - Express response object
373
- * @param req - Express request object
374
- * @param options - Additional logging options
375
- */
376
- httpResponse(res, req, options = {}) {
377
- const logId = (0, uuid_1.v4)();
378
- const requestId = res.locals.requestId || options.requestId || (0, uuid_1.v4)();
379
- const startTime = res.locals.startTime || options.startTime || Date.now();
380
- const workflowId = res.locals.workflowId || this.workflowId;
381
- const serviceId = res.locals.serviceId || this.serviceId;
382
- const traceId = res.locals.traceId || options.traceId || trace_context_1.traceContext.getTraceId() || (0, uuid_1.v4)();
383
- const duration = options.duration || (Date.now() - startTime);
384
- // Determine log level based on status code
385
- let level = options.level || 'info';
386
- if (!options.level) {
387
- if (res.statusCode >= 400) {
388
- level = 'error';
389
- }
390
- else {
391
- level = 'info';
392
- }
393
- }
394
- const logEntry = {
395
- logId,
396
- type: 'httpResponse',
397
- message: (0, http_status_messages_1.getStatusMessage)(res.statusCode),
398
- workflowId: workflowId || '',
399
- serviceId: serviceId || '',
400
- traceId,
401
- requestId,
402
- deploymentId: this.deploymentId,
403
- duration,
404
- httpResponse: {
405
- url: this.constructFullUrl(req),
406
- method: req.method,
407
- headers: (0, logger_utils_1.filterHeaders)(res.getHeaders()),
408
- ip: (0, logger_utils_1.normalizeIp)(req.ip),
409
- status: res.statusCode,
410
- body: (0, logger_utils_1.safeJsonParse)(res.locals.body),
411
- },
412
- };
413
- const { message: logMessage, ...logData } = logEntry;
414
- this.logger[level](logData, logMessage);
415
- return logEntry;
416
- }
417
- /**
418
- * Logs an SFTP transaction
419
- * @param operation - SFTP operation details
420
- * @param options - Additional logging options
421
- */
422
- sftpTransaction(operation, options = {}) {
423
- const logId = (0, uuid_1.v4)();
424
- const traceId = options.traceId || trace_context_1.traceContext.getTraceId() || (0, uuid_1.v4)();
425
- const requestId = options.requestId || (0, uuid_1.v4)();
426
- const duration = options.duration || (options.startTime ? Date.now() - options.startTime : 0);
427
- const level = operation.status === 'success' ? 'info' : 'error';
428
- const logEntry = {
429
- logId,
430
- type: 'sftpTransaction',
431
- message: `SFTP ${operation.operation} ${operation.status} - ${operation.path}`,
432
- workflowId: this.workflowId,
433
- serviceId: this.serviceId,
434
- traceId,
435
- requestId,
436
- deploymentId: this.deploymentId,
437
- duration,
438
- sftp: operation,
439
- };
440
- const { message: logMessage, ...logData } = logEntry;
441
- this.logger[level](logData, logMessage);
442
- return logEntry;
443
- }
444
- /**
445
- * Logs a database query transaction
446
- * @param query - Database query details
447
- * @param options - Additional logging options
448
- */
449
- dbQueryTransaction(query, options = {}) {
450
- const logId = (0, uuid_1.v4)();
451
- const traceId = options.traceId || trace_context_1.traceContext.getTraceId() || (0, uuid_1.v4)();
452
- const requestId = options.requestId || (0, uuid_1.v4)();
453
- const duration = options.duration || (options.startTime ? Date.now() - options.startTime : 0);
454
- const level = query.status === 'success' ? 'info' : 'error';
455
- const logEntry = {
456
- logId,
457
- type: 'dbQueryTransaction',
458
- message: `DB Query ${query.status} - ${query.vendor}`,
459
- workflowId: this.workflowId,
460
- serviceId: this.serviceId,
461
- traceId,
462
- requestId,
463
- deploymentId: this.deploymentId,
464
- duration,
465
- db: query,
466
- };
467
- const { message: logMessage, ...logData } = logEntry;
468
- this.logger[level](logData, logMessage);
469
- return logEntry;
470
- }
471
- }
472
- exports.UnnboundLogger = UnnboundLogger;
@@ -1,9 +0,0 @@
1
- interface HttpStatus {
2
- message: string;
3
- description: string;
4
- }
5
- export declare const httpStatusDetails: {
6
- [key: number]: HttpStatus;
7
- };
8
- export declare function getStatusMessage(statusCode: number): string;
9
- export {};
@@ -1,55 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.httpStatusDetails = void 0;
4
- exports.getStatusMessage = getStatusMessage;
5
- exports.httpStatusDetails = {
6
- 100: { message: 'Continue', description: 'The server has received the request headers, and the client should proceed to send the request body' },
7
- 101: { message: 'Switching Protocols', description: 'The requester has asked the server to switch protocols' },
8
- 103: { message: 'Early Hints', description: 'Used with the Link header to allow the browser to start preloading resources while the server prepares a response' },
9
- 200: { message: 'OK', description: 'The request is OK' },
10
- 201: { message: 'Created', description: 'The request has been fulfilled, and a new resource is created' },
11
- 202: { message: 'Accepted', description: 'The request has been accepted for processing, but the processing has not been completed' },
12
- 203: { message: 'Non-Authoritative Information', description: 'The request has been successfully processed, but is returning information that may be from another source' },
13
- 204: { message: 'No Content', description: 'The request has been successfully processed, but is not returning any content' },
14
- 205: { message: 'Reset Content', description: 'The request has been successfully processed, but is not returning any content, and requires that the requester reset the document view' },
15
- 206: { message: 'Partial Content', description: 'The server is delivering only part of the resource due to a range header sent by the client' },
16
- 300: { message: 'Multiple Choices', description: 'A link list. The user can select a link and go to that location. Maximum five addresses' },
17
- 301: { message: 'Moved Permanently', description: 'The requested page has moved to a new URL' },
18
- 302: { message: 'Found', description: 'The requested page has moved temporarily to a new URL' },
19
- 303: { message: 'See Other', description: 'The requested page can be found under a different URL' },
20
- 304: { message: 'Not Modified', description: 'Indicates the requested page has not been modified since last requested' },
21
- 307: { message: 'Temporary Redirect', description: 'The requested page has moved temporarily to a new URL' },
22
- 308: { message: 'Permanent Redirect', description: 'The requested page has moved permanently to a new URL' },
23
- 400: { message: 'Bad Request', description: 'The request cannot be fulfilled due to bad syntax' },
24
- 401: { message: 'Unauthorized', description: 'The request was a legal request, but the server is refusing to respond to it. For use when authentication is possible but has failed or not yet been provided' },
25
- 402: { message: 'Payment Required', description: 'Reserved for future use' },
26
- 403: { message: 'Forbidden', description: 'The request was a legal request, but the server is refusing to respond to it' },
27
- 404: { message: 'Not Found', description: 'The requested page could not be found but may be available again in the future' },
28
- 405: { message: 'Method Not Allowed', description: 'A request was made of a page using a request method not supported by that page' },
29
- 406: { message: 'Not Acceptable', description: 'The server can only generate a response that is not accepted by the client' },
30
- 407: { message: 'Proxy Authentication Required', description: 'The client must first authenticate itself with the proxy' },
31
- 408: { message: 'Request Timeout', description: 'The server timed out waiting for the request' },
32
- 409: { message: 'Conflict', description: 'The request could not be completed because of a conflict in the request' },
33
- 410: { message: 'Gone', description: 'The requested page is no longer available' },
34
- 411: { message: 'Length Required', description: 'The "Content-Length" is not defined. The server will not accept the request without it' },
35
- 412: { message: 'Precondition Failed', description: 'The precondition given in the request evaluated to false by the server' },
36
- 413: { message: 'Request Too Large', description: 'The server will not accept the request, because the request entity is too large' },
37
- 414: { message: 'Request-URI Too Long', description: 'The server will not accept the request, because the URI is too long. Occurs when you convert a POST request to a GET request with a long query information' },
38
- 415: { message: 'Unsupported Media Type', description: 'The server will not accept the request, because the media type is not supported' },
39
- 416: { message: 'Range Not Satisfiable', description: 'The client has asked for a portion of the file, but the server cannot supply that portion' },
40
- 417: { message: 'Expectation Failed', description: 'The server cannot meet the requirements of the Expect request-header field' },
41
- 500: { message: 'Internal Server Error', description: 'A generic error message, given when no more specific message is suitable' },
42
- 501: { message: 'Not Implemented', description: 'The server either does not recognize the request method, or it lacks the ability to fulfill the request' },
43
- 502: { message: 'Bad Gateway', description: 'The server was acting as a gateway or proxy and received an invalid response from the upstream server' },
44
- 503: { message: 'Service Unavailable', description: 'The server is currently unavailable (overloaded or down)' },
45
- 504: { message: 'Gateway Timeout', description: 'The server was acting as a gateway or proxy and did not receive a timely response from the upstream server' },
46
- 505: { message: 'HTTP Version Not Supported', description: 'The server does not support the HTTP protocol version used in the request' },
47
- 511: { message: 'Network Authentication Required', description: 'The client needs to authenticate to gain network access' },
48
- };
49
- function getStatusMessage(statusCode) {
50
- const status = exports.httpStatusDetails[statusCode];
51
- if (status) {
52
- return `${statusCode} ${status.message} - ${status.description}`;
53
- }
54
- return `${statusCode} Unknown Status`;
55
- }
@@ -1,34 +0,0 @@
1
- /**
2
- * Generates the current timestamp in ISO format
3
- * @returns ISO timestamp string
4
- */
5
- export declare function generateTimestamp(): string;
6
- /**
7
- * Gets or creates a trace ID for a workflow
8
- * @param workflowId - The workflow ID to get a trace ID for
9
- * @returns A trace ID associated with the workflow
10
- */
11
- export declare function getTraceId(workflowId: string): string;
12
- /**
13
- * Clears a trace ID from the map
14
- * @param workflowId - The workflow ID to clear
15
- */
16
- export declare function clearTraceId(workflowId: string): void;
17
- /**
18
- * Filters an object of headers, returning a new object with only the allowed headers.
19
- * @param headers The original headers object.
20
- * @returns A new object containing only the headers from the allow-list.
21
- */
22
- export declare function filterHeaders(headers: Record<string, any>): Record<string, string>;
23
- /**
24
- * Safely parses JSON strings, returning the original data if parsing fails or if it's not a string.
25
- * @param data The data to potentially parse as JSON.
26
- * @returns Parsed JSON object or the original data.
27
- */
28
- export declare function safeJsonParse(data: any): any;
29
- /**
30
- * Normalizes IP addresses by removing IPv6 mapping prefix for IPv4 addresses.
31
- * @param ip The IP address to normalize.
32
- * @returns Normalized IP address string.
33
- */
34
- export declare function normalizeIp(ip: string | undefined): string | undefined;
@@ -1,96 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.generateTimestamp = generateTimestamp;
4
- exports.getTraceId = getTraceId;
5
- exports.clearTraceId = clearTraceId;
6
- exports.filterHeaders = filterHeaders;
7
- exports.safeJsonParse = safeJsonParse;
8
- exports.normalizeIp = normalizeIp;
9
- /**
10
- * Utility functions for logging
11
- */
12
- const uuid_1 = require("uuid");
13
- /**
14
- * Generates the current timestamp in ISO format
15
- * @returns ISO timestamp string
16
- */
17
- function generateTimestamp() {
18
- return new Date().toISOString();
19
- }
20
- /**
21
- * Stores trace IDs by workflow ID for consistent tracking
22
- */
23
- const traceIdMap = new Map();
24
- /**
25
- * Gets or creates a trace ID for a workflow
26
- * @param workflowId - The workflow ID to get a trace ID for
27
- * @returns A trace ID associated with the workflow
28
- */
29
- function getTraceId(workflowId) {
30
- if (!traceIdMap.has(workflowId)) {
31
- traceIdMap.set(workflowId, (0, uuid_1.v4)());
32
- }
33
- return traceIdMap.get(workflowId);
34
- }
35
- /**
36
- * Clears a trace ID from the map
37
- * @param workflowId - The workflow ID to clear
38
- */
39
- function clearTraceId(workflowId) {
40
- traceIdMap.delete(workflowId);
41
- }
42
- // --- Header Allow-Listing ---
43
- const ALLOWED_HEADERS = new Set([
44
- 'content-type',
45
- 'accept',
46
- 'user-agent',
47
- 'host',
48
- 'x-forwarded-for',
49
- 'x-request-id',
50
- 'content-length',
51
- 'cache-control',
52
- ]);
53
- /**
54
- * Filters an object of headers, returning a new object with only the allowed headers.
55
- * @param headers The original headers object.
56
- * @returns A new object containing only the headers from the allow-list.
57
- */
58
- function filterHeaders(headers) {
59
- const filtered = {};
60
- for (const key in headers) {
61
- if (ALLOWED_HEADERS.has(key.toLowerCase())) {
62
- filtered[key] = String(headers[key]);
63
- }
64
- }
65
- return filtered;
66
- }
67
- /**
68
- * Safely parses JSON strings, returning the original data if parsing fails or if it's not a string.
69
- * @param data The data to potentially parse as JSON.
70
- * @returns Parsed JSON object or the original data.
71
- */
72
- function safeJsonParse(data) {
73
- if (typeof data === 'string') {
74
- try {
75
- return JSON.parse(data);
76
- }
77
- catch {
78
- return data;
79
- }
80
- }
81
- return data;
82
- }
83
- /**
84
- * Normalizes IP addresses by removing IPv6 mapping prefix for IPv4 addresses.
85
- * @param ip The IP address to normalize.
86
- * @returns Normalized IP address string.
87
- */
88
- function normalizeIp(ip) {
89
- if (!ip)
90
- return ip;
91
- // Remove IPv4-mapped IPv6 prefix (::ffff:) to get clean IPv4 address
92
- if (ip.startsWith('::ffff:')) {
93
- return ip.substring(7);
94
- }
95
- return ip;
96
- }
@@ -1,10 +0,0 @@
1
- declare class TraceContextManager {
2
- private static instance;
3
- private storage;
4
- private constructor();
5
- static getInstance(): TraceContextManager;
6
- run<T>(traceId: string, callback: () => T): T;
7
- getTraceId(): string | undefined;
8
- }
9
- export declare const traceContext: TraceContextManager;
10
- export {};