@bifold/remote-logs 2.6.0 → 2.7.1

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,20 @@
1
- import { BifoldError, BifoldLogger } from '@bifold/core';
1
+ import { BifoldError, AbstractBifoldLogger } 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
+ export declare class RemoteLogger extends AbstractBifoldLogger {
17
+ private readonly baseLogger;
7
18
  private _remoteLoggingEnabled;
8
19
  private _sessionId;
9
20
  private _autoDisableRemoteLoggingIntervalInMinutes;
@@ -11,22 +22,6 @@ export declare class RemoteLogger extends BifoldLogger {
11
22
  private lokiLabels;
12
23
  private remoteLoggingAutoDisableTimer;
13
24
  private eventListener;
14
- protected _log: any;
15
- 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;
24
- };
25
- severity: string;
26
- async: boolean;
27
- dateFormat: string;
28
- printDate: boolean;
29
- };
30
25
  constructor(options: RemoteLoggerOptions);
31
26
  get sessionId(): number;
32
27
  set sessionId(value: number);
@@ -37,12 +32,20 @@ export declare class RemoteLogger extends BifoldLogger {
37
32
  startEventListeners(): void;
38
33
  stopEventListeners(): void;
39
34
  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
35
  report(bifoldError: BifoldError): void;
36
+ test: LogMethod;
37
+ trace: LogMethod;
38
+ debug: LogMethod;
39
+ info: LogMethod;
40
+ warn: LogMethod;
41
+ error: LogMethod;
42
+ fatal: LogMethod;
43
+ /**
44
+ * Helper method to parse logging arguments consistently across all log levels
45
+ * @param dataOrError - Either data object or Error instance
46
+ * @param error - Optional Error instance when first param is data
47
+ * @returns Parsed data and error objects
48
+ */
49
+ private parseLogArguments;
48
50
  }
51
+ export {};
package/build/logger.js CHANGED
@@ -9,27 +9,74 @@ 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 extends core_1.AbstractBifoldLogger {
13
38
  constructor(options) {
14
39
  var _a, _b, _c;
15
40
  super();
16
41
  this._remoteLoggingEnabled = false;
17
42
  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,
43
+ // Standardized logging methods with consistent overloads
44
+ this.test = (message, dataOrError, error) => {
45
+ var _a, _b;
46
+ const { data, actualError } = this.parseLogArguments(dataOrError, error);
47
+ (_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 });
48
+ };
49
+ this.trace = (message, dataOrError, error) => {
50
+ var _a, _b;
51
+ const { data, actualError } = this.parseLogArguments(dataOrError, error);
52
+ (_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 });
53
+ };
54
+ this.debug = (message, dataOrError, error) => {
55
+ var _a, _b;
56
+ const { data, actualError } = this.parseLogArguments(dataOrError, error);
57
+ (_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 });
58
+ };
59
+ this.info = (message, dataOrError, error) => {
60
+ var _a, _b;
61
+ const { data, actualError } = this.parseLogArguments(dataOrError, error);
62
+ (_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 });
63
+ };
64
+ this.warn = (message, dataOrError, error) => {
65
+ var _a, _b;
66
+ const { data, actualError } = this.parseLogArguments(dataOrError, error);
67
+ (_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
68
  };
69
+ this.error = (message, dataOrError, error) => {
70
+ var _a, _b;
71
+ const { data, actualError } = this.parseLogArguments(dataOrError, error);
72
+ (_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 });
73
+ };
74
+ this.fatal = (message, dataOrError, error) => {
75
+ var _a, _b;
76
+ const { data, actualError } = this.parseLogArguments(dataOrError, error);
77
+ (_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 });
78
+ };
79
+ this.baseLogger = new core_1.BifoldLogger();
33
80
  this.lokiUrl = (_a = options.lokiUrl) !== null && _a !== void 0 ? _a : undefined;
34
81
  this.lokiLabels = (_b = options.lokiLabels) !== null && _b !== void 0 ? _b : {};
35
82
  this._autoDisableRemoteLoggingIntervalInMinutes = (_c = options.autoDisableRemoteLoggingIntervalInMinutes) !== null && _c !== void 0 ? _c : 0;
@@ -37,7 +84,7 @@ class RemoteLogger extends core_1.BifoldLogger {
37
84
  }
38
85
  get sessionId() {
39
86
  if (!this._sessionId) {
40
- this._sessionId = Math.floor(100000 + Math.random() * 900000);
87
+ this._sessionId = Math.floor(SESSION_ID_RANGE.MIN + Math.random() * (SESSION_ID_RANGE.MAX - SESSION_ID_RANGE.MIN + 1));
41
88
  }
42
89
  return this._sessionId;
43
90
  }
@@ -96,37 +143,9 @@ class RemoteLogger extends core_1.BifoldLogger {
96
143
  this.remoteLoggingEnabled = false;
97
144
  }, expirationInMinutes * 60000);
98
145
  }
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
146
  report(bifoldError) {
128
- var _a;
129
- (_a = this._log) === null || _a === void 0 ? void 0 : _a.info({ message: 'Sending Loki report' });
147
+ var _a, _b;
148
+ (_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
149
  const { title, description, code, message } = bifoldError;
131
150
  (0, transports_1.lokiTransport)({
132
151
  msg: title,
@@ -139,5 +158,25 @@ class RemoteLogger extends core_1.BifoldLogger {
139
158
  },
140
159
  });
141
160
  }
161
+ /**
162
+ * Helper method to parse logging arguments consistently across all log levels
163
+ * @param dataOrError - Either data object or Error instance
164
+ * @param error - Optional Error instance when first param is data
165
+ * @returns Parsed data and error objects
166
+ */
167
+ parseLogArguments(dataOrError, error) {
168
+ let data;
169
+ let actualError;
170
+ if (dataOrError instanceof Error) {
171
+ // Second parameter is an Error, so no data
172
+ actualError = dataOrError;
173
+ }
174
+ else {
175
+ // Second parameter is data (or undefined)
176
+ data = dataOrError;
177
+ actualError = error;
178
+ }
179
+ return { data, actualError };
180
+ }
142
181
  }
143
182
  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.1",
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.1",
51
63
  "@credo-ts/core": "0.5.13",
52
64
  "axios": "~1.4.0",
53
65
  "buffer": "~6.0.3",