@devrev/ts-adaas 1.11.1-beta.24 → 1.11.1-beta.25

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.
@@ -22,5 +22,7 @@ export declare const DEFAULT_LAMBDA_TIMEOUT: number;
22
22
  export declare const HARD_TIMEOUT_MULTIPLIER = 1.3;
23
23
  export declare const MEMORY_LOG_INTERVAL: number;
24
24
  export declare const DEFAULT_SLEEP_DELAY_MS: number;
25
- export declare const MAX_STRING_LENGTH = 10000;
25
+ export declare const MAX_LOG_DEPTH = 10;
26
+ export declare const MAX_LOG_ARRAY_LENGTH = 100;
27
+ export declare const MAX_LOG_STRING_LENGTH = 10000;
26
28
  //# sourceMappingURL=constants.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/common/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAGhD,eAAO,MAAM,8BAA8B,aAS1C,CAAC;AAEF,eAAO,MAAM,2BAA2B,aAKvC,CAAC;AAEF,eAAO,MAAM,mBAAmB,aAG/B,CAAC;AAEF,eAAO,MAAM,gCAAgC,aAI5C,CAAC;AAEF,eAAO,MAAM,6BAA6B,aAGzC,CAAC;AAEF,eAAO,MAAM,qBAAqB,aAGjC,CAAC;AAEF,eAAO,MAAM,+BAA+B,aAGzC,CAAC;AAEJ,eAAO,MAAM,4BAA4B,aAExC,CAAC;AAEF,eAAO,MAAM,oBAAoB,aAGhC,CAAC;AAEF,eAAO,MAAM,mBAAmB,OAAO,CAAC;AACxC,eAAO,MAAM,wBAAwB,YAAY,CAAC;AAClD,eAAO,MAAM,0BAA0B,MAAM,CAAC;AAC9C,eAAO,MAAM,oCAAoC,KAAK,CAAC;AAEvD,eAAO,MAAM,0BAA0B;;;;CAItC,CAAC;AAEF,eAAO,MAAM,eAAe,KAAsB,CAAC;AAEnD,eAAO,MAAM,sBAAsB,QAAiB,CAAC;AACrD,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAC3C,eAAO,MAAM,mBAAmB,QAAY,CAAC;AAE7C,eAAO,MAAM,sBAAsB,QAAgB,CAAC;AAEpD,eAAO,MAAM,iBAAiB,QAAQ,CAAC"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/common/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAGhD,eAAO,MAAM,8BAA8B,aAS1C,CAAC;AAEF,eAAO,MAAM,2BAA2B,aAKvC,CAAC;AAEF,eAAO,MAAM,mBAAmB,aAG/B,CAAC;AAEF,eAAO,MAAM,gCAAgC,aAI5C,CAAC;AAEF,eAAO,MAAM,6BAA6B,aAGzC,CAAC;AAEF,eAAO,MAAM,qBAAqB,aAGjC,CAAC;AAEF,eAAO,MAAM,+BAA+B,aAGzC,CAAC;AAEJ,eAAO,MAAM,4BAA4B,aAExC,CAAC;AAEF,eAAO,MAAM,oBAAoB,aAGhC,CAAC;AAEF,eAAO,MAAM,mBAAmB,OAAO,CAAC;AACxC,eAAO,MAAM,wBAAwB,YAAY,CAAC;AAClD,eAAO,MAAM,0BAA0B,MAAM,CAAC;AAC9C,eAAO,MAAM,oCAAoC,KAAK,CAAC;AAEvD,eAAO,MAAM,0BAA0B;;;;CAItC,CAAC;AAEF,eAAO,MAAM,eAAe,KAAsB,CAAC;AAEnD,eAAO,MAAM,sBAAsB,QAAiB,CAAC;AACrD,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAC3C,eAAO,MAAM,mBAAmB,QAAY,CAAC;AAE7C,eAAO,MAAM,sBAAsB,QAAgB,CAAC;AAEpD,eAAO,MAAM,aAAa,KAAK,CAAC;AAChC,eAAO,MAAM,oBAAoB,MAAM,CAAC;AACxC,eAAO,MAAM,qBAAqB,QAAQ,CAAC"}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MAX_STRING_LENGTH = exports.DEFAULT_SLEEP_DELAY_MS = exports.MEMORY_LOG_INTERVAL = exports.HARD_TIMEOUT_MULTIPLIER = exports.DEFAULT_LAMBDA_TIMEOUT = exports.LIBRARY_VERSION = exports.AIRDROP_DEFAULT_ITEM_TYPES = exports.MAX_DEVREV_FILENAME_EXTENSION_LENGTH = exports.MAX_DEVREV_FILENAME_LENGTH = exports.MAX_DEVREV_ARTIFACT_SIZE = exports.ARTIFACT_BATCH_SIZE = exports.STATEFUL_EVENT_TYPES = exports.STATEFUL_LOADING_EVENT_TYPES = exports.STATEFUL_EXTRACTION_EVENT_TYPES = exports.STATELESS_EVENT_TYPES = exports.STATELESS_LOADING_EVENT_TYPES = exports.STATELESS_EXTRACTION_EVENT_TYPES = exports.ALLOWED_EVENT_TYPES = exports.ALLOWED_LOADING_EVENT_TYPES = exports.ALLOWED_EXTRACTION_EVENT_TYPES = void 0;
3
+ exports.MAX_LOG_STRING_LENGTH = exports.MAX_LOG_ARRAY_LENGTH = exports.MAX_LOG_DEPTH = exports.DEFAULT_SLEEP_DELAY_MS = exports.MEMORY_LOG_INTERVAL = exports.HARD_TIMEOUT_MULTIPLIER = exports.DEFAULT_LAMBDA_TIMEOUT = exports.LIBRARY_VERSION = exports.AIRDROP_DEFAULT_ITEM_TYPES = exports.MAX_DEVREV_FILENAME_EXTENSION_LENGTH = exports.MAX_DEVREV_FILENAME_LENGTH = exports.MAX_DEVREV_ARTIFACT_SIZE = exports.ARTIFACT_BATCH_SIZE = exports.STATEFUL_EVENT_TYPES = exports.STATEFUL_LOADING_EVENT_TYPES = exports.STATEFUL_EXTRACTION_EVENT_TYPES = exports.STATELESS_EVENT_TYPES = exports.STATELESS_LOADING_EVENT_TYPES = exports.STATELESS_EXTRACTION_EVENT_TYPES = exports.ALLOWED_EVENT_TYPES = exports.ALLOWED_LOADING_EVENT_TYPES = exports.ALLOWED_EXTRACTION_EVENT_TYPES = void 0;
4
4
  const extraction_1 = require("../types/extraction");
5
5
  const helpers_1 = require("./helpers");
6
6
  exports.ALLOWED_EXTRACTION_EVENT_TYPES = [
@@ -56,4 +56,6 @@ exports.DEFAULT_LAMBDA_TIMEOUT = 10 * 60 * 1000; // 10 minutes
56
56
  exports.HARD_TIMEOUT_MULTIPLIER = 1.3;
57
57
  exports.MEMORY_LOG_INTERVAL = 30 * 1000; // 30 seconds
58
58
  exports.DEFAULT_SLEEP_DELAY_MS = 3 * 60 * 1000; // 3 minutes
59
- exports.MAX_STRING_LENGTH = 10000;
59
+ exports.MAX_LOG_DEPTH = 10;
60
+ exports.MAX_LOG_ARRAY_LENGTH = 100;
61
+ exports.MAX_LOG_STRING_LENGTH = 10000;
@@ -7,7 +7,7 @@ export declare class Logger extends Console {
7
7
  private tags;
8
8
  constructor({ event, options }: LoggerFactoryInterface);
9
9
  private valueToString;
10
- logFn(args: unknown[], level: LogLevel): void;
10
+ logFn(args: unknown[], level: LogLevel, skipSanitization?: boolean): void;
11
11
  log(...args: unknown[]): void;
12
12
  info(...args: unknown[]): void;
13
13
  warn(...args: unknown[]): void;
@@ -1 +1 @@
1
- {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/logger/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAIvC,OAAO,EAAE,UAAU,EAAyC,MAAM,OAAO,CAAC;AAG1E,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EAEtB,QAAQ,EAER,cAAc,EACf,MAAM,qBAAqB,CAAC;AAE7B,qBAAa,MAAO,SAAQ,OAAO;IACjC,OAAO,CAAC,eAAe,CAAU;IACjC,OAAO,CAAC,OAAO,CAAC,CAAuB;IACvC,OAAO,CAAC,IAAI,CAAa;gBAEb,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,sBAAsB;IAUtD,OAAO,CAAC,aAAa;IAerB,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,QAAQ,GAAG,IAAI;IA0BpC,GAAG,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAI7B,IAAI,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAI9B,IAAI,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAI9B,KAAK,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;CAGzC;AAID,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,cAAc,CAyB5E;AACD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAE1D;AAED,eAAO,MAAM,cAAc,GAAI,OAAO,OAAO,YAK5C,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,UAAU,GAAG,kBAAkB,CAwBzE"}
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/logger/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAIvC,OAAO,EAAE,UAAU,EAAyC,MAAM,OAAO,CAAC;AAQ1E,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EAEtB,QAAQ,EAER,cAAc,EACf,MAAM,qBAAqB,CAAC;AAE7B,qBAAa,MAAO,SAAQ,OAAO;IACjC,OAAO,CAAC,eAAe,CAAU;IACjC,OAAO,CAAC,OAAO,CAAC,CAAuB;IACvC,OAAO,CAAC,IAAI,CAAa;gBAEb,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,sBAAsB;IAUtD,OAAO,CAAC,aAAa;IAsBrB,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,gBAAgB,UAAQ,GAAG,IAAI;IA4B9D,GAAG,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAI7B,IAAI,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAI9B,IAAI,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAI9B,KAAK,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;CAGzC;AAID,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,cAAc,CAyB5E;AACD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAE1D;AAED,eAAO,MAAM,cAAc,GAAI,OAAO,OAAO,YAK5C,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,UAAU,GAAG,kBAAkB,CAwBzE"}
@@ -19,38 +19,47 @@ class Logger extends node_console_1.Console {
19
19
  this.tags = Object.assign(Object.assign({}, event.payload.event_context), { sdk_version: constants_1.LIBRARY_VERSION });
20
20
  }
21
21
  valueToString(value) {
22
- // If the value is a string, return it as-is
22
+ // If the value is a string, return the first MAX_LOG_STRING_LENGTH characters
23
23
  if (typeof value === 'string') {
24
- return value;
24
+ if (value.length > constants_1.MAX_LOG_STRING_LENGTH) {
25
+ return `${value.substring(0, constants_1.MAX_LOG_STRING_LENGTH)}... ${value.length - constants_1.MAX_LOG_STRING_LENGTH} more characters`;
26
+ }
27
+ else {
28
+ return value;
29
+ }
25
30
  }
26
31
  // Use inspect for everything else
27
32
  return (0, node_util_1.inspect)(value, {
28
33
  compact: true,
29
- depth: 10,
30
- maxArrayLength: 100,
31
- maxStringLength: 10000,
34
+ breakLength: 80,
35
+ depth: constants_1.MAX_LOG_DEPTH,
36
+ maxArrayLength: constants_1.MAX_LOG_ARRAY_LENGTH,
37
+ maxStringLength: constants_1.MAX_LOG_STRING_LENGTH,
32
38
  });
33
39
  }
34
- logFn(args, level) {
40
+ logFn(args, level, skipSanitization = false) {
35
41
  var _a;
36
- // Worker thread sends the log to the main thread to log it
37
- if (!node_worker_threads_1.isMainThread && node_worker_threads_1.parentPort) {
38
- const sanitizedArgs = args.map((arg) => this.valueToString(arg));
39
- node_worker_threads_1.parentPort.postMessage({
40
- subject: workers_1.WorkerMessageSubject.WorkerMessageLog,
41
- payload: { args: sanitizedArgs, level },
42
- });
43
- return;
44
- }
45
- // Main thread logs the log normally
42
+ const message = skipSanitization
43
+ ? args.join(' ')
44
+ : args.map((arg) => this.valueToString(arg)).join(' ');
45
+ // If local development, log the message to the console and don't add the tags
46
46
  if ((_a = this.options) === null || _a === void 0 ? void 0 : _a.isLocalDevelopment) {
47
- this.originalConsole[level](...args);
47
+ this.originalConsole[level](message);
48
+ return;
48
49
  }
49
- else {
50
- const message = args.map((arg) => this.valueToString(arg)).join(' ');
50
+ if (node_worker_threads_1.isMainThread) {
51
+ // If main thread, log the message to the console and add the tags
51
52
  const logObject = Object.assign({ message }, this.tags);
52
53
  this.originalConsole[level](JSON.stringify(logObject));
53
54
  }
55
+ else {
56
+ // If worker thread, send the message to the main thread to log it
57
+ const sanitizedArgs = args.map((arg) => this.valueToString(arg));
58
+ node_worker_threads_1.parentPort === null || node_worker_threads_1.parentPort === void 0 ? void 0 : node_worker_threads_1.parentPort.postMessage({
59
+ subject: workers_1.WorkerMessageSubject.WorkerMessageLog,
60
+ payload: { args: sanitizedArgs, level },
61
+ });
62
+ }
54
63
  }
55
64
  log(...args) {
56
65
  this.logFn(args, logger_interfaces_1.LogLevel.INFO);
@@ -9,7 +9,6 @@ const logger_1 = require("./logger");
9
9
  const mockConsoleInfo = jest.spyOn(console, 'info').mockImplementation();
10
10
  const mockConsoleWarn = jest.spyOn(console, 'warn').mockImplementation();
11
11
  const mockConsoleError = jest.spyOn(console, 'error').mockImplementation();
12
- /* eslint-disable @typescript-eslint/no-require-imports */
13
12
  // Mock worker_threads
14
13
  jest.mock('node:worker_threads', () => ({
15
14
  isMainThread: true,
@@ -46,207 +45,430 @@ describe(logger_1.Logger.name, () => {
46
45
  afterAll(() => {
47
46
  jest.restoreAllMocks();
48
47
  });
49
- describe('constructor', () => {
50
- it('should initialize logger with event context and sdk_version', () => {
51
- const logger = new logger_1.Logger({ event: mockEvent, options: mockOptions });
52
- // Access private property for testing
53
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
54
- const tags = logger.tags;
55
- expect(tags).toEqual(Object.assign(Object.assign({}, mockEvent.payload.event_context), { sdk_version: constants_1.LIBRARY_VERSION }));
56
- });
48
+ it('should initialize with event context and SDK version in tags', () => {
49
+ // Arrange & Act
50
+ const logger = new logger_1.Logger({ event: mockEvent, options: mockOptions });
51
+ // Assert
52
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
53
+ const tags = logger.tags;
54
+ expect(tags).toEqual(Object.assign(Object.assign({}, mockEvent.payload.event_context), { sdk_version: constants_1.LIBRARY_VERSION }));
57
55
  });
58
- describe('production logging', () => {
59
- let logger;
60
- beforeEach(() => {
61
- mockOptions.isLocalDevelopment = false;
62
- logger = new logger_1.Logger({ event: mockEvent, options: mockOptions });
63
- });
64
- it('should log single string message without backslashes', () => {
65
- const message = 'Worker is online. Started processing the task.';
66
- logger.info(message);
67
- expect(mockConsoleInfo).toHaveBeenCalledWith(JSON.stringify(Object.assign(Object.assign({ message }, mockEvent.payload.event_context), { sdk_version: constants_1.LIBRARY_VERSION })));
68
- });
69
- it('should log single object message with JSON stringify', () => {
70
- const data = { id: 123, name: 'test' };
71
- logger.info(data);
72
- const expectedMessage = (0, node_util_1.inspect)(data, {
73
- compact: true,
74
- breakLength: Infinity,
75
- depth: 10,
76
- maxArrayLength: 100,
77
- maxStringLength: 10000,
78
- });
79
- expect(mockConsoleInfo).toHaveBeenCalledWith(JSON.stringify(Object.assign(Object.assign({ message: expectedMessage }, mockEvent.payload.event_context), { sdk_version: constants_1.LIBRARY_VERSION })));
80
- });
81
- it('should log multiple arguments joined with space', () => {
82
- const text = 'Successfully fetched';
83
- const data = { count: 42 };
84
- logger.info(text, data);
85
- const expectedDataMessage = (0, node_util_1.inspect)(data, {
86
- compact: true,
87
- breakLength: Infinity,
88
- depth: 10,
89
- maxArrayLength: 100,
90
- maxStringLength: 10000,
91
- });
92
- expect(mockConsoleInfo).toHaveBeenCalledWith(JSON.stringify(Object.assign(Object.assign({ message: `${text} ${expectedDataMessage}` }, mockEvent.payload.event_context), { sdk_version: constants_1.LIBRARY_VERSION })));
93
- });
94
- it('should handle mixed string and object arguments', () => {
95
- const text1 = 'Processing';
96
- const data = { id: 123 };
97
- const text2 = 'completed';
98
- logger.info(text1, data, text2);
99
- const expectedDataMessage = (0, node_util_1.inspect)(data, {
100
- compact: true,
101
- breakLength: Infinity,
102
- depth: 10,
103
- maxArrayLength: 100,
104
- maxStringLength: 10000,
105
- });
106
- expect(mockConsoleInfo).toHaveBeenCalledWith(JSON.stringify(Object.assign(Object.assign({ message: `${text1} ${expectedDataMessage} ${text2}` }, mockEvent.payload.event_context), { sdk_version: constants_1.LIBRARY_VERSION })));
107
- });
56
+ it('should log string message as JSON with event context tags in production mode', () => {
57
+ // Arrange
58
+ const message = 'Worker is online. Started processing the task.';
59
+ const logger = new logger_1.Logger({ event: mockEvent, options: mockOptions });
60
+ // Act
61
+ logger.info(message);
62
+ // Assert
63
+ expect(mockConsoleInfo).toHaveBeenCalledWith(JSON.stringify(Object.assign(Object.assign({ message }, mockEvent.payload.event_context), { sdk_version: constants_1.LIBRARY_VERSION })));
108
64
  });
109
- describe('local development logging', () => {
110
- let logger;
111
- beforeEach(() => {
112
- mockOptions.isLocalDevelopment = true;
113
- logger = new logger_1.Logger({ event: mockEvent, options: mockOptions });
114
- });
115
- it('should use regular console methods in local development', () => {
116
- const message = 'Test message';
117
- const data = { test: true };
118
- logger.info(message, data);
119
- expect(mockConsoleInfo).toHaveBeenCalledWith(message, data);
65
+ it('should log object message using inspect with proper formatting in production mode', () => {
66
+ // Arrange
67
+ const data = { id: 123, name: 'test' };
68
+ const logger = new logger_1.Logger({ event: mockEvent, options: mockOptions });
69
+ const expectedMessage = (0, node_util_1.inspect)(data, {
70
+ compact: true,
71
+ depth: 10,
72
+ maxArrayLength: 100,
73
+ maxStringLength: 10000,
120
74
  });
75
+ // Act
76
+ logger.info(data);
77
+ // Assert
78
+ expect(mockConsoleInfo).toHaveBeenCalledWith(JSON.stringify(Object.assign(Object.assign({ message: expectedMessage }, mockEvent.payload.event_context), { sdk_version: constants_1.LIBRARY_VERSION })));
121
79
  });
122
- describe('log levels', () => {
123
- let logger;
124
- beforeEach(() => {
125
- mockOptions.isLocalDevelopment = false;
126
- logger = new logger_1.Logger({ event: mockEvent, options: mockOptions });
127
- });
128
- it('should call console.info for info level', () => {
129
- logger.info('test message');
130
- expect(mockConsoleInfo).toHaveBeenCalled();
131
- });
132
- it('should call console.warn for warn level', () => {
133
- logger.warn('test warning');
134
- expect(mockConsoleWarn).toHaveBeenCalled();
135
- });
136
- it('should call console.error for error level', () => {
137
- logger.error('test error');
138
- expect(mockConsoleError).toHaveBeenCalled();
139
- });
140
- it('should call console.info for log level', () => {
141
- logger.log('test log');
142
- expect(mockConsoleInfo).toHaveBeenCalled();
80
+ it('should join multiple arguments with space when logging in production mode', () => {
81
+ // Arrange
82
+ const text = 'Successfully fetched';
83
+ const data = { count: 42 };
84
+ const logger = new logger_1.Logger({ event: mockEvent, options: mockOptions });
85
+ const expectedDataMessage = (0, node_util_1.inspect)(data, {
86
+ compact: true,
87
+ depth: 10,
88
+ maxArrayLength: 100,
89
+ maxStringLength: 10000,
143
90
  });
91
+ // Act
92
+ logger.info(text, data);
93
+ // Assert
94
+ expect(mockConsoleInfo).toHaveBeenCalledWith(JSON.stringify(Object.assign(Object.assign({ message: `${text} ${expectedDataMessage}` }, mockEvent.payload.event_context), { sdk_version: constants_1.LIBRARY_VERSION })));
144
95
  });
145
- describe('edge cases', () => {
146
- let logger;
147
- beforeEach(() => {
148
- mockOptions.isLocalDevelopment = false;
149
- logger = new logger_1.Logger({ event: mockEvent, options: mockOptions });
96
+ it('should log mixed string and object arguments joined with spaces in production mode', () => {
97
+ // Arrange
98
+ const text1 = 'Processing';
99
+ const data = { id: 123 };
100
+ const text2 = 'completed';
101
+ const logger = new logger_1.Logger({ event: mockEvent, options: mockOptions });
102
+ const expectedDataMessage = (0, node_util_1.inspect)(data, {
103
+ compact: true,
104
+ depth: 10,
105
+ maxArrayLength: 100,
106
+ maxStringLength: 10000,
150
107
  });
151
- it('[edge] should handle empty string message', () => {
152
- logger.info('');
153
- expect(mockConsoleInfo).toHaveBeenCalledTimes(1);
154
- const callArgs = mockConsoleInfo.mock.calls[0][0];
155
- const logObject = JSON.parse(callArgs);
156
- // Empty string is returned as-is
157
- expect(logObject.message).toBe('');
158
- expect(logObject.sdk_version).toBe(constants_1.LIBRARY_VERSION);
159
- expect(logObject.request_id).toBe(mockEvent.payload.event_context.request_id);
108
+ // Act
109
+ logger.info(text1, data, text2);
110
+ // Assert
111
+ expect(mockConsoleInfo).toHaveBeenCalledWith(JSON.stringify(Object.assign(Object.assign({ message: `${text1} ${expectedDataMessage} ${text2}` }, mockEvent.payload.event_context), { sdk_version: constants_1.LIBRARY_VERSION })));
112
+ });
113
+ it('should log directly without JSON wrapping in local development mode', () => {
114
+ // Arrange
115
+ const message = 'Test message';
116
+ const data = { test: true };
117
+ mockOptions.isLocalDevelopment = true;
118
+ const logger = new logger_1.Logger({ event: mockEvent, options: mockOptions });
119
+ const expectedDataMessage = (0, node_util_1.inspect)(data, {
120
+ compact: true,
121
+ depth: 10,
122
+ maxArrayLength: 100,
123
+ maxStringLength: 10000,
160
124
  });
161
- it('[edge] should handle null and undefined values', () => {
162
- logger.info('test', null, undefined);
163
- expect(mockConsoleInfo).toHaveBeenCalledTimes(1);
164
- const callArgs = mockConsoleInfo.mock.calls[0][0];
165
- const logObject = JSON.parse(callArgs);
166
- // Strings returned as-is, null/undefined shown via inspect
167
- expect(logObject.message).toBe('test null undefined');
168
- expect(logObject.sdk_version).toBe(constants_1.LIBRARY_VERSION);
125
+ // Act
126
+ logger.info(message, data);
127
+ // Assert
128
+ expect(mockConsoleInfo).toHaveBeenCalledWith(`${message} ${expectedDataMessage}`);
129
+ });
130
+ it('should truncate long strings and show remaining character count', () => {
131
+ // Arrange
132
+ const longString = 'C'.repeat(20000);
133
+ const logger = new logger_1.Logger({ event: mockEvent, options: mockOptions });
134
+ const expectedTruncatedMessage = `${longString.substring(0, constants_1.MAX_LOG_STRING_LENGTH)}... ${20000 - constants_1.MAX_LOG_STRING_LENGTH} more characters`;
135
+ // Act
136
+ logger.info(longString);
137
+ // Assert
138
+ const callArgs = mockConsoleInfo.mock.calls[0][0];
139
+ const logObject = JSON.parse(callArgs);
140
+ expect(logObject.message).toBe(expectedTruncatedMessage);
141
+ });
142
+ it('should not truncate strings shorter than maximum length', () => {
143
+ // Arrange
144
+ const shortString = 'Short message';
145
+ const logger = new logger_1.Logger({ event: mockEvent, options: mockOptions });
146
+ // Act
147
+ logger.info(shortString);
148
+ // Assert
149
+ const callArgs = mockConsoleInfo.mock.calls[0][0];
150
+ const logObject = JSON.parse(callArgs);
151
+ expect(logObject.message).toBe(shortString);
152
+ });
153
+ it('should skip sanitization when skipSanitization flag is true', () => {
154
+ // Arrange
155
+ const alreadySanitizedArgs = ['Sanitized message 1', 'Sanitized message 2'];
156
+ const logger = new logger_1.Logger({ event: mockEvent, options: mockOptions });
157
+ // Act
158
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
159
+ logger.logFn(alreadySanitizedArgs, 'info', true);
160
+ // Assert
161
+ const callArgs = mockConsoleInfo.mock.calls[0][0];
162
+ const logObject = JSON.parse(callArgs);
163
+ expect(logObject.message).toBe('Sanitized message 1 Sanitized message 2');
164
+ });
165
+ it('should apply sanitization when skipSanitization flag is false', () => {
166
+ // Arrange
167
+ const data = { id: 123 };
168
+ const logger = new logger_1.Logger({ event: mockEvent, options: mockOptions });
169
+ const expectedMessage = (0, node_util_1.inspect)(data, {
170
+ compact: true,
171
+ depth: 10,
172
+ maxArrayLength: 100,
173
+ maxStringLength: 10000,
169
174
  });
170
- it('[edge] should handle complex nested objects', () => {
171
- const complexObject = {
172
- level1: {
173
- level2: {
174
- array: [1, 2, 3],
175
- string: 'nested',
176
- },
175
+ // Act
176
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
177
+ logger.logFn([data], 'info', false);
178
+ // Assert
179
+ const callArgs = mockConsoleInfo.mock.calls[0][0];
180
+ const logObject = JSON.parse(callArgs);
181
+ expect(logObject.message).toBe(expectedMessage);
182
+ });
183
+ it('should call info method for log level', () => {
184
+ // Arrange
185
+ const logger = new logger_1.Logger({ event: mockEvent, options: mockOptions });
186
+ // Act
187
+ logger.log('test log');
188
+ // Assert
189
+ expect(mockConsoleInfo).toHaveBeenCalledTimes(1);
190
+ });
191
+ it('should call info method for info level', () => {
192
+ // Arrange
193
+ const logger = new logger_1.Logger({ event: mockEvent, options: mockOptions });
194
+ // Act
195
+ logger.info('test info');
196
+ // Assert
197
+ expect(mockConsoleInfo).toHaveBeenCalledTimes(1);
198
+ });
199
+ it('should call warn method for warn level', () => {
200
+ // Arrange
201
+ const logger = new logger_1.Logger({ event: mockEvent, options: mockOptions });
202
+ // Act
203
+ logger.warn('test warning');
204
+ // Assert
205
+ expect(mockConsoleWarn).toHaveBeenCalledTimes(1);
206
+ });
207
+ it('should call error method for error level', () => {
208
+ // Arrange
209
+ const logger = new logger_1.Logger({ event: mockEvent, options: mockOptions });
210
+ // Act
211
+ logger.error('test error');
212
+ // Assert
213
+ expect(mockConsoleError).toHaveBeenCalledTimes(1);
214
+ });
215
+ it('[edge] should handle empty string as valid log message', () => {
216
+ // Arrange
217
+ const emptyString = '';
218
+ const logger = new logger_1.Logger({ event: mockEvent, options: mockOptions });
219
+ // Act
220
+ logger.info(emptyString);
221
+ // Assert
222
+ const callArgs = mockConsoleInfo.mock.calls[0][0];
223
+ const logObject = JSON.parse(callArgs);
224
+ expect(logObject.message).toBe('');
225
+ expect(logObject.sdk_version).toBe(constants_1.LIBRARY_VERSION);
226
+ });
227
+ it('[edge] should handle null and undefined values in log arguments', () => {
228
+ // Arrange
229
+ const logger = new logger_1.Logger({ event: mockEvent, options: mockOptions });
230
+ // Act
231
+ logger.info('test', null, undefined);
232
+ // Assert
233
+ const callArgs = mockConsoleInfo.mock.calls[0][0];
234
+ const logObject = JSON.parse(callArgs);
235
+ expect(logObject.message).toBe('test null undefined');
236
+ });
237
+ it('[edge] should handle deeply nested objects with inspect', () => {
238
+ // Arrange
239
+ const complexObject = {
240
+ level1: {
241
+ level2: {
242
+ array: [1, 2, 3],
243
+ string: 'nested',
177
244
  },
178
- };
179
- logger.info(complexObject);
180
- expect(mockConsoleInfo).toHaveBeenCalledTimes(1);
181
- const callArgs = mockConsoleInfo.mock.calls[0][0];
182
- const logObject = JSON.parse(callArgs);
183
- // The logger uses inspect() with compact: true settings
184
- const expectedMessage = require('util').inspect(complexObject, {
185
- compact: true,
186
- breakLength: Infinity,
187
- depth: 10,
188
- maxArrayLength: 100,
189
- maxStringLength: 10000,
190
- });
191
- expect(logObject.message).toBe(expectedMessage);
192
- expect(logObject.sdk_version).toBe(constants_1.LIBRARY_VERSION);
193
- expect(typeof logObject.callback_url).toBe('string');
245
+ },
246
+ };
247
+ const logger = new logger_1.Logger({ event: mockEvent, options: mockOptions });
248
+ const expectedMessage = (0, node_util_1.inspect)(complexObject, {
249
+ compact: true,
250
+ depth: 10,
251
+ maxArrayLength: 100,
252
+ maxStringLength: 10000,
194
253
  });
254
+ // Act
255
+ logger.info(complexObject);
256
+ // Assert
257
+ const callArgs = mockConsoleInfo.mock.calls[0][0];
258
+ const logObject = JSON.parse(callArgs);
259
+ expect(logObject.message).toBe(expectedMessage);
260
+ });
261
+ it('[edge] should handle circular references in objects', () => {
262
+ // Arrange
263
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
264
+ const circularObject = { name: 'test' };
265
+ circularObject.self = circularObject;
266
+ const logger = new logger_1.Logger({ event: mockEvent, options: mockOptions });
267
+ // Act & Assert
268
+ expect(() => logger.info(circularObject)).not.toThrow();
269
+ expect(mockConsoleInfo).toHaveBeenCalledTimes(1);
195
270
  });
196
271
  });
197
- it('getPrintableState should return printable state', () => {
198
- const state = {
199
- test_key: 'test_value',
200
- big_array: Array.from({ length: 1000 }, (_, index) => index),
201
- nested_object: {
202
- nested_key: 'nested_value',
203
- nested_array: Array.from({ length: 1000 }, (_, index) => index),
204
- },
205
- };
206
- const printableState = (0, logger_1.getPrintableState)(state);
207
- expect(printableState).toEqual({
208
- test_key: 'test_value',
209
- big_array: {
210
- type: 'array',
211
- length: 1000,
212
- firstItem: 0,
213
- lastItem: 999,
214
- },
215
- nested_object: {
216
- nested_key: 'nested_value',
217
- nested_array: {
272
+ describe(logger_1.getPrintableState.name, () => {
273
+ it('should convert arrays to summary objects with type, length, and boundary items', () => {
274
+ // Arrange
275
+ const state = {
276
+ test_key: 'test_value',
277
+ big_array: Array.from({ length: 1000 }, (_, index) => index),
278
+ };
279
+ // Act
280
+ const printableState = (0, logger_1.getPrintableState)(state);
281
+ // Assert
282
+ expect(printableState).toEqual({
283
+ test_key: 'test_value',
284
+ big_array: {
218
285
  type: 'array',
219
286
  length: 1000,
220
287
  firstItem: 0,
221
288
  lastItem: 999,
222
289
  },
223
- },
290
+ });
291
+ });
292
+ it('should recursively process nested objects and arrays', () => {
293
+ // Arrange
294
+ const state = {
295
+ test_key: 'test_value',
296
+ nested_object: {
297
+ nested_key: 'nested_value',
298
+ nested_array: Array.from({ length: 1000 }, (_, index) => index),
299
+ },
300
+ };
301
+ // Act
302
+ const printableState = (0, logger_1.getPrintableState)(state);
303
+ // Assert
304
+ expect(printableState).toEqual({
305
+ test_key: 'test_value',
306
+ nested_object: {
307
+ nested_key: 'nested_value',
308
+ nested_array: {
309
+ type: 'array',
310
+ length: 1000,
311
+ firstItem: 0,
312
+ lastItem: 999,
313
+ },
314
+ },
315
+ });
316
+ });
317
+ it('should preserve primitive values without modification', () => {
318
+ // Arrange
319
+ const state = {
320
+ string_key: 'string_value',
321
+ number_key: 42,
322
+ boolean_key: true,
323
+ null_key: null,
324
+ };
325
+ // Act
326
+ const printableState = (0, logger_1.getPrintableState)(state);
327
+ // Assert
328
+ expect(printableState).toEqual(state);
329
+ });
330
+ it('[edge] should handle empty arrays with no first or last items', () => {
331
+ // Arrange
332
+ const state = {
333
+ empty_array: [],
334
+ };
335
+ // Act
336
+ const printableState = (0, logger_1.getPrintableState)(state);
337
+ // Assert
338
+ expect(printableState).toEqual({
339
+ empty_array: {
340
+ type: 'array',
341
+ length: 0,
342
+ firstItem: undefined,
343
+ lastItem: undefined,
344
+ },
345
+ });
346
+ });
347
+ it('[edge] should handle single-item arrays with same first and last item', () => {
348
+ // Arrange
349
+ const state = {
350
+ single_item_array: [42],
351
+ };
352
+ // Act
353
+ const printableState = (0, logger_1.getPrintableState)(state);
354
+ // Assert
355
+ expect(printableState).toEqual({
356
+ single_item_array: {
357
+ type: 'array',
358
+ length: 1,
359
+ firstItem: 42,
360
+ lastItem: undefined,
361
+ },
362
+ });
224
363
  });
225
364
  });
226
- it('serializeAxiosError should return formatted error', () => {
227
- const error = {
228
- response: {
229
- status: 500,
230
- data: 'Internal server error',
231
- },
232
- config: {
233
- method: 'GET',
234
- },
235
- };
236
- const formattedError = (0, logger_1.serializeAxiosError)(error);
237
- expect(formattedError).toEqual({
238
- config: {
239
- method: 'GET',
240
- params: undefined,
241
- url: undefined,
242
- },
243
- isAxiosError: true,
244
- isCorsOrNoNetworkError: false,
245
- response: {
246
- data: 'Internal server error',
247
- headers: undefined,
248
- status: 500,
249
- statusText: undefined,
250
- },
365
+ describe(logger_1.serializeAxiosError.name, () => {
366
+ it('should serialize Axios error with response data', () => {
367
+ // Arrange
368
+ const error = {
369
+ response: {
370
+ status: 500,
371
+ statusText: 'Internal Server Error',
372
+ data: 'Internal server error',
373
+ headers: { 'content-type': 'application/json' },
374
+ },
375
+ config: {
376
+ method: 'GET',
377
+ url: '/api/test',
378
+ params: { id: 123 },
379
+ },
380
+ };
381
+ // Act
382
+ const formattedError = (0, logger_1.serializeAxiosError)(error);
383
+ // Assert
384
+ expect(formattedError).toEqual({
385
+ config: {
386
+ method: 'GET',
387
+ params: { id: 123 },
388
+ url: '/api/test',
389
+ },
390
+ isAxiosError: true,
391
+ isCorsOrNoNetworkError: false,
392
+ response: {
393
+ data: 'Internal server error',
394
+ headers: { 'content-type': 'application/json' },
395
+ status: 500,
396
+ statusText: 'Internal Server Error',
397
+ },
398
+ });
399
+ });
400
+ it('should serialize Axios error without response as CORS or network error', () => {
401
+ // Arrange
402
+ const error = {
403
+ code: 'ERR_NETWORK',
404
+ message: 'Network Error',
405
+ config: {
406
+ method: 'POST',
407
+ url: '/api/create',
408
+ },
409
+ };
410
+ // Act
411
+ const formattedError = (0, logger_1.serializeAxiosError)(error);
412
+ // Assert
413
+ expect(formattedError).toEqual({
414
+ config: {
415
+ method: 'POST',
416
+ params: undefined,
417
+ url: '/api/create',
418
+ },
419
+ isAxiosError: true,
420
+ isCorsOrNoNetworkError: true,
421
+ code: 'ERR_NETWORK',
422
+ message: 'Network Error',
423
+ });
424
+ });
425
+ it('[edge] should handle Axios error with minimal config information', () => {
426
+ // Arrange
427
+ const error = {
428
+ response: {
429
+ status: 404,
430
+ data: 'Not Found',
431
+ },
432
+ config: {},
433
+ };
434
+ // Act
435
+ const formattedError = (0, logger_1.serializeAxiosError)(error);
436
+ // Assert
437
+ expect(formattedError).toEqual({
438
+ config: {
439
+ method: undefined,
440
+ params: undefined,
441
+ url: undefined,
442
+ },
443
+ isAxiosError: true,
444
+ isCorsOrNoNetworkError: false,
445
+ response: {
446
+ data: 'Not Found',
447
+ headers: undefined,
448
+ status: 404,
449
+ statusText: undefined,
450
+ },
451
+ });
452
+ });
453
+ it('[edge] should handle Axios error with no config', () => {
454
+ // Arrange
455
+ const error = {
456
+ code: 'ERR_TIMEOUT',
457
+ message: 'Request timeout',
458
+ };
459
+ // Act
460
+ const formattedError = (0, logger_1.serializeAxiosError)(error);
461
+ // Assert
462
+ expect(formattedError).toEqual({
463
+ config: {
464
+ method: undefined,
465
+ params: undefined,
466
+ url: undefined,
467
+ },
468
+ isAxiosError: true,
469
+ isCorsOrNoNetworkError: true,
470
+ code: 'ERR_TIMEOUT',
471
+ message: 'Request timeout',
472
+ });
251
473
  });
252
474
  });
@@ -1 +1 @@
1
- {"version":3,"file":"spawn.d.ts","sourceRoot":"","sources":["../../src/workers/spawn.ts"],"names":[],"mappings":"AAWA,OAAO,EAEL,qBAAqB,EACrB,cAAc,EAGf,MAAM,kBAAkB,CAAC;AA4D1B;;;;;;;;;;GAUG;AACH,wBAAsB,KAAK,CAAC,cAAc,EAAE,EAC1C,KAAK,EACL,YAAY,EACZ,UAAU,EACV,oBAAoB,EACpB,OAAO,GACR,EAAE,qBAAqB,CAAC,cAAc,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAyEvD;AAED,qBAAa,KAAK;IAChB,OAAO,CAAC,KAAK,CAAe;IAC5B,OAAO,CAAC,cAAc,CAAU;IAChC,OAAO,CAAC,oBAAoB,CAAkC;IAC9D,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,gBAAgB,CAA4C;IACpE,OAAO,CAAC,gBAAgB,CAA4C;IACpE,OAAO,CAAC,wBAAwB,CAA6C;IAC7E,OAAO,CAAC,OAAO,CAA4C;IAC3D,OAAO,CAAC,eAAe,CAAU;gBACrB,EACV,KAAK,EACL,MAAM,EACN,OAAO,EACP,OAAO,EACP,eAAe,GAChB,EAAE,cAAc;IA8FjB,OAAO,CAAC,aAAa;YAYP,kBAAkB;CAiCjC"}
1
+ {"version":3,"file":"spawn.d.ts","sourceRoot":"","sources":["../../src/workers/spawn.ts"],"names":[],"mappings":"AAWA,OAAO,EAEL,qBAAqB,EACrB,cAAc,EAGf,MAAM,kBAAkB,CAAC;AA4D1B;;;;;;;;;;GAUG;AACH,wBAAsB,KAAK,CAAC,cAAc,EAAE,EAC1C,KAAK,EACL,YAAY,EACZ,UAAU,EACV,oBAAoB,EACpB,OAAO,GACR,EAAE,qBAAqB,CAAC,cAAc,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAyEvD;AAED,qBAAa,KAAK;IAChB,OAAO,CAAC,KAAK,CAAe;IAC5B,OAAO,CAAC,cAAc,CAAU;IAChC,OAAO,CAAC,oBAAoB,CAAkC;IAC9D,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,gBAAgB,CAA4C;IACpE,OAAO,CAAC,gBAAgB,CAA4C;IACpE,OAAO,CAAC,wBAAwB,CAA6C;IAC7E,OAAO,CAAC,OAAO,CAA4C;IAC3D,OAAO,CAAC,eAAe,CAAU;gBACrB,EACV,KAAK,EACL,MAAM,EACN,OAAO,EACP,OAAO,EACP,eAAe,GAChB,EAAE,cAAc;IA+FjB,OAAO,CAAC,aAAa;YAYP,kBAAkB;CAiCjC"}
@@ -186,7 +186,8 @@ class Spawn {
186
186
  if ((message === null || message === void 0 ? void 0 : message.subject) === workers_1.WorkerMessageSubject.WorkerMessageLog) {
187
187
  const args = (_a = message.payload) === null || _a === void 0 ? void 0 : _a.args;
188
188
  const level = (_b = message.payload) === null || _b === void 0 ? void 0 : _b.level;
189
- console.logFn(args, level);
189
+ // Args are already sanitized in the worker thread, skip double sanitization
190
+ console.logFn(args, level, true);
190
191
  }
191
192
  // If worker sends a message that it has emitted an event, then set alreadyEmitted to true.
192
193
  if ((message === null || message === void 0 ? void 0 : message.subject) === workers_1.WorkerMessageSubject.WorkerMessageEmitted) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devrev/ts-adaas",
3
- "version": "1.11.1-beta.24",
3
+ "version": "1.11.1-beta.25",
4
4
  "description": "Typescript library containing the ADaaS(AirDrop as a Service) control protocol.",
5
5
  "type": "commonjs",
6
6
  "main": "./dist/index.js",