@bifold/remote-logs 2.6.0 → 2.7.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.
package/build/logger.d.ts CHANGED
@@ -1,9 +1,60 @@
1
- import { BifoldError, BifoldLogger } from '@bifold/core';
1
+ import { BifoldError } from '@bifold/core';
2
2
  import { RemoteLoggerOptions } from './transports';
3
3
  export declare enum RemoteLoggerEventTypes {
4
4
  ENABLE_REMOTE_LOGGING = "RemoteLogging.Enable"
5
5
  }
6
- export declare class RemoteLogger extends BifoldLogger {
6
+ /**
7
+ * Standardized logging method interface with consistent overloads
8
+ * Supports all combinations of message, data, and error parameters
9
+ */
10
+ interface LogMethod {
11
+ (message: string): void;
12
+ (message: string, data: Record<string, unknown>): void;
13
+ (message: string, error: Error): void;
14
+ (message: string, data: Record<string, unknown>, error: Error): void;
15
+ }
16
+ /**
17
+ * Internal logger instance interface for type safety
18
+ */
19
+ interface InternalLoggerInstance {
20
+ test?: (props: {
21
+ message: string;
22
+ data?: Record<string, unknown>;
23
+ error?: Error;
24
+ }) => void;
25
+ trace?: (props: {
26
+ message: string;
27
+ data?: Record<string, unknown>;
28
+ error?: Error;
29
+ }) => void;
30
+ debug?: (props: {
31
+ message: string;
32
+ data?: Record<string, unknown>;
33
+ error?: Error;
34
+ }) => void;
35
+ info?: (props: {
36
+ message: string;
37
+ data?: Record<string, unknown>;
38
+ error?: Error;
39
+ }) => void;
40
+ warn?: (props: {
41
+ message: string;
42
+ data?: Record<string, unknown>;
43
+ error?: Error;
44
+ }) => void;
45
+ error?: (props: {
46
+ message: string;
47
+ data?: Record<string, unknown>;
48
+ error?: Error;
49
+ }) => void;
50
+ fatal?: (props: {
51
+ message: string;
52
+ data?: Record<string, unknown>;
53
+ error?: Error;
54
+ }) => void;
55
+ }
56
+ export declare class RemoteLogger {
57
+ private readonly baseLogger;
7
58
  private _remoteLoggingEnabled;
8
59
  private _sessionId;
9
60
  private _autoDisableRemoteLoggingIntervalInMinutes;
@@ -11,21 +62,21 @@ export declare class RemoteLogger extends BifoldLogger {
11
62
  private lokiLabels;
12
63
  private remoteLoggingAutoDisableTimer;
13
64
  private eventListener;
14
- protected _log: any;
65
+ protected _log: InternalLoggerInstance | null;
15
66
  protected _config: {
16
- levels: {
17
- test: number;
18
- trace: number;
19
- debug: number;
20
- info: number;
21
- warn: number;
22
- error: number;
23
- fatal: number;
67
+ readonly levels: {
68
+ readonly test: 0;
69
+ readonly trace: 0;
70
+ readonly debug: 0;
71
+ readonly info: 1;
72
+ readonly warn: 2;
73
+ readonly error: 3;
74
+ readonly fatal: 4;
24
75
  };
25
- severity: string;
26
- async: boolean;
27
- dateFormat: string;
28
- printDate: boolean;
76
+ readonly severity: "debug";
77
+ readonly async: true;
78
+ readonly dateFormat: "time";
79
+ readonly printDate: false;
29
80
  };
30
81
  constructor(options: RemoteLoggerOptions);
31
82
  get sessionId(): number;
@@ -37,12 +88,20 @@ export declare class RemoteLogger extends BifoldLogger {
37
88
  startEventListeners(): void;
38
89
  stopEventListeners(): void;
39
90
  overrideCurrentAutoDisableExpiration(expirationInMinutes: number): void;
40
- test(message: string, data?: Record<string, unknown> | Error): void;
41
- trace(message: string, data?: Record<string, unknown> | Error): void;
42
- debug(message: string, data?: Record<string, unknown> | Error): void;
43
- info(message: string, data?: Record<string, unknown> | Error): void;
44
- warn(message: string, data?: Record<string, unknown> | Error): void;
45
- error(message: string, data?: Record<string, unknown> | Error): void;
46
- fatal(message: string, data?: Record<string, unknown> | Error): void;
47
91
  report(bifoldError: BifoldError): void;
92
+ test: LogMethod;
93
+ trace: LogMethod;
94
+ debug: LogMethod;
95
+ info: LogMethod;
96
+ warn: LogMethod;
97
+ error: LogMethod;
98
+ fatal: LogMethod;
99
+ /**
100
+ * Helper method to parse logging arguments consistently across all log levels
101
+ * @param dataOrError - Either data object or Error instance
102
+ * @param error - Optional Error instance when first param is data
103
+ * @returns Parsed data and error objects
104
+ */
105
+ private parseLogArguments;
48
106
  }
107
+ export {};
package/build/logger.js CHANGED
@@ -9,27 +9,75 @@ var RemoteLoggerEventTypes;
9
9
  (function (RemoteLoggerEventTypes) {
10
10
  RemoteLoggerEventTypes["ENABLE_REMOTE_LOGGING"] = "RemoteLogging.Enable";
11
11
  })(RemoteLoggerEventTypes || (exports.RemoteLoggerEventTypes = RemoteLoggerEventTypes = {}));
12
- class RemoteLogger extends core_1.BifoldLogger {
12
+ /**
13
+ * Default logging configuration constants
14
+ */
15
+ const DEFAULT_LOG_CONFIG = {
16
+ levels: {
17
+ test: 0,
18
+ trace: 0,
19
+ debug: 0,
20
+ info: 1,
21
+ warn: 2,
22
+ error: 3,
23
+ fatal: 4,
24
+ },
25
+ severity: 'debug',
26
+ async: true,
27
+ dateFormat: 'time',
28
+ printDate: false,
29
+ };
30
+ /**
31
+ * Session ID generation constants
32
+ */
33
+ const SESSION_ID_RANGE = {
34
+ MIN: 100000,
35
+ MAX: 999999,
36
+ };
37
+ class RemoteLogger {
13
38
  constructor(options) {
14
39
  var _a, _b, _c;
15
- super();
16
40
  this._remoteLoggingEnabled = false;
17
41
  this._autoDisableRemoteLoggingIntervalInMinutes = 0;
18
- this._config = {
19
- levels: {
20
- test: 0,
21
- trace: 0,
22
- debug: 0,
23
- info: 1,
24
- warn: 2,
25
- error: 3,
26
- fatal: 4,
27
- },
28
- severity: 'debug',
29
- async: true,
30
- dateFormat: 'time',
31
- printDate: false,
42
+ this._log = null;
43
+ this._config = DEFAULT_LOG_CONFIG;
44
+ // Standardized logging methods with consistent overloads
45
+ this.test = (message, dataOrError, error) => {
46
+ var _a, _b;
47
+ const { data, actualError } = this.parseLogArguments(dataOrError, error);
48
+ (_b = (_a = this._log) === null || _a === void 0 ? void 0 : _a.test) === null || _b === void 0 ? void 0 : _b.call(_a, { message, data, error: actualError });
49
+ };
50
+ this.trace = (message, dataOrError, error) => {
51
+ var _a, _b;
52
+ const { data, actualError } = this.parseLogArguments(dataOrError, error);
53
+ (_b = (_a = this._log) === null || _a === void 0 ? void 0 : _a.trace) === null || _b === void 0 ? void 0 : _b.call(_a, { message, data, error: actualError });
54
+ };
55
+ this.debug = (message, dataOrError, error) => {
56
+ var _a, _b;
57
+ const { data, actualError } = this.parseLogArguments(dataOrError, error);
58
+ (_b = (_a = this._log) === null || _a === void 0 ? void 0 : _a.debug) === null || _b === void 0 ? void 0 : _b.call(_a, { message, data, error: actualError });
59
+ };
60
+ this.info = (message, dataOrError, error) => {
61
+ var _a, _b;
62
+ const { data, actualError } = this.parseLogArguments(dataOrError, error);
63
+ (_b = (_a = this._log) === null || _a === void 0 ? void 0 : _a.info) === null || _b === void 0 ? void 0 : _b.call(_a, { message, data, error: actualError });
64
+ };
65
+ this.warn = (message, dataOrError, error) => {
66
+ var _a, _b;
67
+ const { data, actualError } = this.parseLogArguments(dataOrError, error);
68
+ (_b = (_a = this._log) === null || _a === void 0 ? void 0 : _a.warn) === null || _b === void 0 ? void 0 : _b.call(_a, { message, data, error: actualError });
32
69
  };
70
+ this.error = (message, dataOrError, error) => {
71
+ var _a, _b;
72
+ const { data, actualError } = this.parseLogArguments(dataOrError, error);
73
+ (_b = (_a = this._log) === null || _a === void 0 ? void 0 : _a.error) === null || _b === void 0 ? void 0 : _b.call(_a, { message, data, error: actualError });
74
+ };
75
+ this.fatal = (message, dataOrError, error) => {
76
+ var _a, _b;
77
+ const { data, actualError } = this.parseLogArguments(dataOrError, error);
78
+ (_b = (_a = this._log) === null || _a === void 0 ? void 0 : _a.fatal) === null || _b === void 0 ? void 0 : _b.call(_a, { message, data, error: actualError });
79
+ };
80
+ this.baseLogger = new core_1.BifoldLogger();
33
81
  this.lokiUrl = (_a = options.lokiUrl) !== null && _a !== void 0 ? _a : undefined;
34
82
  this.lokiLabels = (_b = options.lokiLabels) !== null && _b !== void 0 ? _b : {};
35
83
  this._autoDisableRemoteLoggingIntervalInMinutes = (_c = options.autoDisableRemoteLoggingIntervalInMinutes) !== null && _c !== void 0 ? _c : 0;
@@ -37,7 +85,7 @@ class RemoteLogger extends core_1.BifoldLogger {
37
85
  }
38
86
  get sessionId() {
39
87
  if (!this._sessionId) {
40
- this._sessionId = Math.floor(100000 + Math.random() * 900000);
88
+ this._sessionId = Math.floor(SESSION_ID_RANGE.MIN + Math.random() * (SESSION_ID_RANGE.MAX - SESSION_ID_RANGE.MIN + 1));
41
89
  }
42
90
  return this._sessionId;
43
91
  }
@@ -96,37 +144,9 @@ class RemoteLogger extends core_1.BifoldLogger {
96
144
  this.remoteLoggingEnabled = false;
97
145
  }, expirationInMinutes * 60000);
98
146
  }
99
- test(message, data) {
100
- var _a;
101
- (_a = this._log) === null || _a === void 0 ? void 0 : _a.test({ message, data });
102
- }
103
- trace(message, data) {
104
- var _a;
105
- (_a = this._log) === null || _a === void 0 ? void 0 : _a.trace({ message, data });
106
- }
107
- debug(message, data) {
108
- var _a;
109
- (_a = this._log) === null || _a === void 0 ? void 0 : _a.debug({ message, data });
110
- }
111
- info(message, data) {
112
- var _a;
113
- (_a = this._log) === null || _a === void 0 ? void 0 : _a.info({ message, data });
114
- }
115
- warn(message, data) {
116
- var _a;
117
- (_a = this._log) === null || _a === void 0 ? void 0 : _a.warn({ message, data });
118
- }
119
- error(message, data) {
120
- var _a;
121
- (_a = this._log) === null || _a === void 0 ? void 0 : _a.error({ message, data });
122
- }
123
- fatal(message, data) {
124
- var _a;
125
- (_a = this._log) === null || _a === void 0 ? void 0 : _a.fatal({ message, data });
126
- }
127
147
  report(bifoldError) {
128
- var _a;
129
- (_a = this._log) === null || _a === void 0 ? void 0 : _a.info({ message: 'Sending Loki report' });
148
+ var _a, _b;
149
+ (_b = (_a = this._log) === null || _a === void 0 ? void 0 : _a.info) === null || _b === void 0 ? void 0 : _b.call(_a, { message: 'Sending Loki report' });
130
150
  const { title, description, code, message } = bifoldError;
131
151
  (0, transports_1.lokiTransport)({
132
152
  msg: title,
@@ -139,5 +159,25 @@ class RemoteLogger extends core_1.BifoldLogger {
139
159
  },
140
160
  });
141
161
  }
162
+ /**
163
+ * Helper method to parse logging arguments consistently across all log levels
164
+ * @param dataOrError - Either data object or Error instance
165
+ * @param error - Optional Error instance when first param is data
166
+ * @returns Parsed data and error objects
167
+ */
168
+ parseLogArguments(dataOrError, error) {
169
+ let data;
170
+ let actualError;
171
+ if (dataOrError instanceof Error) {
172
+ // Second parameter is an Error, so no data
173
+ actualError = dataOrError;
174
+ }
175
+ else {
176
+ // Second parameter is data (or undefined)
177
+ data = dataOrError;
178
+ actualError = error;
179
+ }
180
+ return { data, actualError };
181
+ }
142
182
  }
143
183
  exports.RemoteLogger = RemoteLogger;
@@ -43,26 +43,49 @@ const messageDataFormatter = (...msgs) => {
43
43
  stack: (_b = (_a = msg.stack) === null || _a === void 0 ? void 0 : _a.split('\n').slice(1).map((line) => line.trim())) !== null && _b !== void 0 ? _b : [],
44
44
  }, null, 2);
45
45
  }
46
- return typeof msg === 'object' ? JSON.stringify(msg, null, 2) : msg;
46
+ if (typeof msg === 'object' && msg !== null) {
47
+ try {
48
+ return JSON.stringify(msg, null, 2);
49
+ }
50
+ catch (error) {
51
+ // Handle JSON serialization errors (circular references, BigInt, etc.)
52
+ if (error instanceof TypeError && error.message.includes('circular')) {
53
+ return '[Circular Reference]';
54
+ }
55
+ if (error instanceof TypeError && error.message.includes('BigInt')) {
56
+ return '[BigInt value cannot be serialized]';
57
+ }
58
+ // Handle other JSON serialization errors
59
+ return `[Serialization Error: ${error instanceof Error ? error.message : 'Unknown error'}]`;
60
+ }
61
+ }
62
+ return msg;
47
63
  });
48
64
  };
49
65
  const consoleTransport = (props) => {
50
- var _a, _b, _c;
51
- if (!props) {
66
+ var _a, _b, _c, _d;
67
+ if (!((_a = props === null || props === void 0 ? void 0 : props.rawMsg) === null || _a === void 0 ? void 0 : _a.length)) {
52
68
  return;
53
69
  }
54
70
  // Get the last element without mutating the
55
71
  // original array.
56
72
  const lastMessage = props.rawMsg[props.rawMsg.length - 1];
57
- let { message } = lastMessage, rest = __rest(lastMessage, ["message"]);
73
+ if (!lastMessage) {
74
+ return;
75
+ }
76
+ // Destructure the message and rest properties, allow
77
+ // ...rest to be `const`, message to be `let`.
78
+ let { message } = lastMessage;
79
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
80
+ const { message: _ } = lastMessage, rest = __rest(lastMessage, ["message"]);
58
81
  let color;
59
- if (((_a = props.options) === null || _a === void 0 ? void 0 : _a.colors) &&
82
+ if (((_b = props.options) === null || _b === void 0 ? void 0 : _b.colors) &&
60
83
  props.options.colors[props.level.text] &&
61
84
  availableColors[props.options.colors[props.level.text]]) {
62
85
  color = `\x1b[${availableColors[props.options.colors[props.level.text]]}m`;
63
86
  message = `${color}${message}${resetColors}`;
64
87
  }
65
- if (props.extension && ((_b = props.options) === null || _b === void 0 ? void 0 : _b.extensionColors)) {
88
+ if (props.extension && ((_c = props.options) === null || _c === void 0 ? void 0 : _c.extensionColors)) {
66
89
  let extensionColor = '\x1b[7m';
67
90
  const extColor = props.options.extensionColors[props.extension];
68
91
  if (extColor && availableColors[extColor]) {
@@ -77,7 +100,7 @@ const consoleTransport = (props) => {
77
100
  const formattedData = messageDataFormatter(...Object.values(rest)).join(' ');
78
101
  logMessage = `${logMessage} ${formattedData}`;
79
102
  }
80
- if ((_c = props.options) === null || _c === void 0 ? void 0 : _c.consoleFunc) {
103
+ if ((_d = props.options) === null || _d === void 0 ? void 0 : _d.consoleFunc) {
81
104
  props.options.consoleFunc(logMessage);
82
105
  }
83
106
  else {
@@ -12,7 +12,7 @@ const lokiTransport = (props) => {
12
12
  // Loki requires a timestamp with nanosecond precision
13
13
  // however Date.now() only returns milliseconds precision.
14
14
  const timestampEndPadding = '000000';
15
- if (!props.options) {
15
+ if (!(props === null || props === void 0 ? void 0 : props.options)) {
16
16
  throw Error('props.options is required');
17
17
  }
18
18
  if (!props.options.lokiUrl) {
@@ -25,12 +25,12 @@ const lokiTransport = (props) => {
25
25
  // Get the last element without mutating the
26
26
  // original array.
27
27
  const lastMessage = props.rawMsg[props.rawMsg.length - 1];
28
- const { message, data } = lastMessage;
28
+ const { message, data, error } = lastMessage;
29
29
  const payload = {
30
30
  streams: [
31
31
  {
32
32
  stream: Object.assign({ job: (_a = props.options.job) !== null && _a !== void 0 ? _a : 'react-native-logs', level: props.level.text }, lokiLabels),
33
- values: [[`${Date.now()}${timestampEndPadding}`, JSON.stringify({ message, data })]],
33
+ values: [[`${Date.now()}${timestampEndPadding}`, JSON.stringify({ message, data, error })]],
34
34
  },
35
35
  ],
36
36
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bifold/remote-logs",
3
- "version": "2.6.0",
3
+ "version": "2.7.0",
4
4
  "description": "Remote logging for credo-ts agents",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -12,7 +12,10 @@
12
12
  "scripts": {
13
13
  "build": "echo 'building remote-logs 🏗️' && yarn run clean && yarn run compile && echo 'remote-logs built ✅'",
14
14
  "clean": "rimraf ./build",
15
- "compile": "tsc"
15
+ "compile": "tsc",
16
+ "test": "jest",
17
+ "test:watch": "jest --watch",
18
+ "test:coverage": "jest --coverage"
16
19
  },
17
20
  "repository": {
18
21
  "type": "git",
@@ -28,10 +31,19 @@
28
31
  },
29
32
  "homepage": "https://github.com/openwallet-foundation/bifold-wallet",
30
33
  "devDependencies": {
34
+ "@babel/core": "~7.25.2",
35
+ "@babel/plugin-transform-runtime": "~7.25.4",
36
+ "@babel/preset-env": "~7.25.4",
37
+ "@babel/preset-flow": "~7.24.7",
38
+ "@babel/preset-typescript": "~7.24.7",
31
39
  "@babel/runtime": "~7.23.9",
40
+ "@types/jest": "~29.5.12",
32
41
  "@typescript-eslint/parser": "~7.18.0",
42
+ "babel-jest": "~29.7.0",
33
43
  "eslint": "~8.57.1",
34
44
  "eslint-import-resolver-typescript": "~3.6.3",
45
+ "jest": "~29.7.0",
46
+ "react-test-renderer": "~18.3.1",
35
47
  "rimraf": "~5.0.10",
36
48
  "typescript": "~5.5.4"
37
49
  },
@@ -47,7 +59,7 @@
47
59
  "hoistingLimits": "workspaces"
48
60
  },
49
61
  "dependencies": {
50
- "@bifold/core": "2.6.0",
62
+ "@bifold/core": "2.7.0",
51
63
  "@credo-ts/core": "0.5.13",
52
64
  "axios": "~1.4.0",
53
65
  "buffer": "~6.0.3",