@dynamic-labs/logger 5.9.4 → 5.10.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/CHANGELOG.md CHANGED
@@ -1,4 +1,29 @@
1
1
 
2
+ ## [5.10.0](https://github.com/dynamic-labs/dynamic-auth/compare/v5.9.6...v5.10.0) (2026-10-09)
3
+
4
+
5
+ ### Features
6
+
7
+ * add lockWallets/lockWallet to re-lock password-encrypted WaaS wallets ([#12461](https://github.com/dynamic-labs/dynamic-auth/issues/12461)) ([090f544](https://github.com/dynamic-labs/dynamic-auth/commit/090f544150f4359bbfd9c0ffb4c450868adb6759))
8
+
9
+
10
+ ### Bug Fixes
11
+
12
+ * **logger:** scope server error forwarding per instance ([#12477](https://github.com/dynamic-labs/dynamic-auth/issues/12477)) ([baa8c78](https://github.com/dynamic-labs/dynamic-auth/commit/baa8c780f4ef3cc35d62c363e03e74412ece91b9))
13
+ * **waas:** fall back when crypto.randomUUID is unavailable ([#12435](https://github.com/dynamic-labs/dynamic-auth/issues/12435)) ([5756f53](https://github.com/dynamic-labs/dynamic-auth/commit/5756f53423bd8316bce97e46ce38fc923fd5d574))
14
+ * **waas:** include every wallet in password update batches ([#12462](https://github.com/dynamic-labs/dynamic-auth/issues/12462)) ([80218f7](https://github.com/dynamic-labs/dynamic-auth/commit/80218f702dadfee9673cec4037889449bcd5ceb6))
15
+
16
+ ### [5.9.6](https://github.com/dynamic-labs/dynamic-auth/compare/v5.9.5...v5.9.6) (2026-10-06)
17
+
18
+ ### [5.9.5](https://github.com/dynamic-labs/dynamic-auth/compare/v5.9.4...v5.9.5) (2026-10-06)
19
+
20
+
21
+ ### Bug Fixes
22
+
23
+ * **ton:** move encodeComment to base TonWalletConnector ([#12459](https://github.com/dynamic-labs/dynamic-auth/issues/12459)) ([647df5b](https://github.com/dynamic-labs/dynamic-auth/commit/647df5bc3986d59d89dbe31bbd3ebe1c4605ec40))
24
+ * **waas-svm:** apply overrideBlockhash before sponsorship ([#12319](https://github.com/dynamic-labs/dynamic-auth/issues/12319)) ([074ce3c](https://github.com/dynamic-labs/dynamic-auth/commit/074ce3c4ecfa080b683c84120fa7643e8fe064d4)), closes [#10599](https://github.com/dynamic-labs/dynamic-auth/issues/10599) [#10599](https://github.com/dynamic-labs/dynamic-auth/issues/10599) [#10599](https://github.com/dynamic-labs/dynamic-auth/issues/10599) [#10599](https://github.com/dynamic-labs/dynamic-auth/issues/10599)
25
+ * **wallet-book:** use phantom.com for Phantom in-app-browser links ([#12456](https://github.com/dynamic-labs/dynamic-auth/issues/12456)) ([e762553](https://github.com/dynamic-labs/dynamic-auth/commit/e7625534f8beda3e649f121e637451e2188faef6))
26
+
2
27
  ### [5.9.4](https://github.com/dynamic-labs/dynamic-auth/compare/v5.9.3...v5.9.4) (2026-10-02)
3
28
 
4
29
  ### [5.9.3](https://github.com/dynamic-labs/dynamic-auth/compare/v5.9.2...v5.9.3) (2026-10-02)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dynamic-labs/logger",
3
- "version": "5.9.4",
3
+ "version": "5.10.0",
4
4
  "description": "A simple client side logging library used in Dynamic SDK",
5
5
  "author": "Dynamic Labs, Inc.",
6
6
  "license": "MIT",
package/src/index.cjs CHANGED
@@ -67,11 +67,13 @@ class Logger {
67
67
  static set troubleshootModeEnabled(val) {
68
68
  globalState.troubleshootModeEnabled = val;
69
69
  }
70
- constructor(name, level) {
70
+ constructor(name, level, options = {}) {
71
71
  this.name = name;
72
72
  this._level = undefined;
73
73
  this.metaData = new MetaData.MetaData();
74
74
  this._level = level;
75
+ this.emitErrors = options.emitErrors;
76
+ this.environmentId = options.environmentId;
75
77
  if (typeof window !== 'undefined' && window.localStorage !== undefined) {
76
78
  // Don't unset the value if it's already set
77
79
  Logger.troubleshootModeEnabled =
@@ -93,16 +95,25 @@ class Logger {
93
95
  globalState.keys.emitErrors = emit;
94
96
  }
95
97
  }
98
+ setEmitErrors(emit) {
99
+ this.emitErrors = emit;
100
+ }
96
101
  static setEnvironmentId(environmentId) {
97
102
  if (environmentId !== undefined) {
98
103
  globalState.keys.environmentId = environmentId;
99
104
  }
100
105
  }
106
+ setEnvironmentId(environmentId) {
107
+ this.environmentId = environmentId;
108
+ }
101
109
  getNameArray(name) {
102
110
  return Array.isArray(name) ? name : [name];
103
111
  }
104
112
  createLogger(name, level) {
105
- return new Logger([...this.getNameArray(this.name), ...this.getNameArray(name)], level !== null && level !== void 0 ? level : this.level);
113
+ return new Logger([...this.getNameArray(this.name), ...this.getNameArray(name)], level !== null && level !== void 0 ? level : this.level, {
114
+ emitErrors: this.emitErrors,
115
+ environmentId: this.environmentId,
116
+ });
106
117
  }
107
118
  get logLevel() {
108
119
  return types.LogLevel[this.level];
@@ -150,24 +161,29 @@ class Logger {
150
161
  }
151
162
  captureAndSend(level, message, ...args) {
152
163
  return _tslib.__awaiter(this, void 0, void 0, function* () {
164
+ var _a;
153
165
  // `fetch` (not `window`) is the actual requirement: this also lets Node
154
166
  // (which has had a global `fetch` since v18) forward logs, not just browsers.
155
- if (globalState.keys.emitErrors &&
167
+ if (((_a = this.emitErrors) !== null && _a !== void 0 ? _a : globalState.keys.emitErrors) &&
156
168
  !IGNORE_MESSAGES.includes(message === null || message === void 0 ? void 0 : message.toString()) &&
157
169
  typeof fetch !== 'undefined') {
158
170
  this.emitHttpLogs(level, message, { args });
159
171
  }
160
172
  });
161
173
  }
162
- emitHttpLogs(level, message, { args = [], transformMeta = (meta) => meta }) {
174
+ emitHttpLogs(level, message, _a) {
175
+ var _b;
176
+ var { args = [], environmentId = (_b = this.environmentId) !== null && _b !== void 0 ? _b : globalState.keys.environmentId, stackField = 'stack', transformMeta = (meta) => meta, } = _a;
163
177
  const stack = getStack.getStack(this.emitHttpLogs);
164
- // Captured now, not at flush time — see MessageQueueMessage.environmentId.
165
178
  messageQueue.push({
166
179
  args,
167
- environmentId: globalState.keys.environmentId,
180
+ environmentId,
168
181
  level,
169
182
  message,
183
+ meta: globalState.metaData.merge(this.metaData).get(),
170
184
  stack,
185
+ stackField,
186
+ transformMeta,
171
187
  });
172
188
  if (messageQueue.length === 1) {
173
189
  /**
@@ -183,69 +199,53 @@ class Logger {
183
199
  try {
184
200
  // Grab all pending messages immediately and clear the queue
185
201
  const currentBatch = messageQueue.splice(0, messageQueue.length);
186
- // Group by the environmentId each message was queued under (not
187
- // whatever is globally current now) and send one request per
188
- // group, so a concurrent Logger.setEnvironmentId() call — a
189
- // different tenant/request in the same Node process — can't
190
- // redirect an already-queued message to the wrong destination.
191
- const batchesByEnvironmentId = new Map();
202
+ const messagesByEnvironment = new Map();
192
203
  currentBatch.forEach((msg) => {
193
- const existing = batchesByEnvironmentId.get(msg.environmentId);
194
- if (existing) {
195
- existing.push(msg);
196
- }
197
- else {
198
- batchesByEnvironmentId.set(msg.environmentId, [msg]);
204
+ var _a, _b, _c, _d, _e, _f, _g, _h;
205
+ if (!msg.environmentId) {
206
+ this.debug('Environment ID not set, skipping log message');
207
+ return;
199
208
  }
200
- });
201
- yield Promise.all(Array.from(batchesByEnvironmentId.entries()).map((_a) => _tslib.__awaiter(this, [_a], void 0, function* ([environmentId, msgs]) {
202
- if (!environmentId) {
203
- throw new Error('Environment ID not set');
204
- }
205
- const messages = [];
206
- msgs.forEach((msg) => {
207
- var _a, _b, _c, _d, _e, _f;
208
- const body = {};
209
- const { objectArgs, remainingArgs } = processArgs.processArgs(msg);
210
- Object.assign(body, ...objectArgs);
211
- const hasWindow = typeof window !== 'undefined';
212
- Object.assign(body, {
213
- level: types.LogLevel[msg.level],
214
- message: [msg.message, ...remainingArgs].join(' '),
215
- meta: transformMeta(globalState.metaData.merge(this.metaData).get()),
216
- stack: msg.stack,
217
- // Node/server environments have no window/location/navigator.
218
- url: hasWindow
219
- ? {
220
- hostname: (_a = window.location) === null || _a === void 0 ? void 0 : _a.hostname,
221
- origin: (_b = window.location) === null || _b === void 0 ? void 0 : _b.origin,
222
- pathname: (_c = window.location) === null || _c === void 0 ? void 0 : _c.pathname,
223
- port: (_d = window.location) === null || _d === void 0 ? void 0 : _d.port,
224
- protocol: (_e = window.location) === null || _e === void 0 ? void 0 : _e.protocol,
225
- }
226
- : undefined,
227
- userAgent: hasWindow
228
- ? (_f = window.navigator) === null || _f === void 0 ? void 0 : _f.userAgent
229
- : undefined,
230
- });
231
- // Credential/key-material redaction (@dynamic-labs/redaction) —
232
- // scrubs both denylisted keys and credential-shaped free text
233
- // (JWTs, Bearer/Basic, dyn_* keys) anywhere in the payload,
234
- // including inside `message`/`stack`/caller-supplied context.
235
- messages.push(redaction.redact(body, redaction.DEFAULT_REDACT_KEYS));
236
- });
237
- yield fetch(`https://logs.dynamicauth.com/api/v1/${environmentId}`, {
238
- body: JSON.stringify(messages, createLogPayloadReplacer.createLogPayloadReplacer()),
239
- headers: {
240
- 'Content-Type': 'application/json',
241
- },
242
- // keepalive lets queued logs (e.g. wallet-creation timeout /
243
- // abandonment events) flush even as the tab is unloading.
244
- keepalive: true,
245
- method: 'POST',
246
- mode: 'cors',
247
- referrerPolicy: 'origin-when-cross-origin',
209
+ const body = {};
210
+ const { objectArgs, remainingArgs } = processArgs.processArgs(msg);
211
+ Object.assign(body, ...objectArgs);
212
+ const hasWindow = typeof window !== 'undefined';
213
+ Object.assign(body, {
214
+ level: types.LogLevel[msg.level],
215
+ message: [msg.message, ...remainingArgs].join(' '),
216
+ meta: msg.transformMeta ? msg.transformMeta(msg.meta) : msg.meta,
217
+ [(_a = msg.stackField) !== null && _a !== void 0 ? _a : 'stack']: msg.stack,
218
+ // Node/server environments have no window/location/navigator.
219
+ url: hasWindow
220
+ ? {
221
+ hostname: (_b = window.location) === null || _b === void 0 ? void 0 : _b.hostname,
222
+ origin: (_c = window.location) === null || _c === void 0 ? void 0 : _c.origin,
223
+ pathname: (_d = window.location) === null || _d === void 0 ? void 0 : _d.pathname,
224
+ port: (_e = window.location) === null || _e === void 0 ? void 0 : _e.port,
225
+ protocol: (_f = window.location) === null || _f === void 0 ? void 0 : _f.protocol,
226
+ }
227
+ : undefined,
228
+ userAgent: hasWindow ? (_g = window.navigator) === null || _g === void 0 ? void 0 : _g.userAgent : undefined,
248
229
  });
230
+ // Credential/key-material redaction (@dynamic-labs/redaction) —
231
+ // scrubs both denylisted keys and credential-shaped free text
232
+ // (JWTs, Bearer/Basic, dyn_* keys) anywhere in the payload,
233
+ // including inside `message`/`stack`/caller-supplied context.
234
+ const messages = (_h = messagesByEnvironment.get(msg.environmentId)) !== null && _h !== void 0 ? _h : [];
235
+ messages.push(redaction.redact(body, redaction.DEFAULT_REDACT_KEYS));
236
+ messagesByEnvironment.set(msg.environmentId, messages);
237
+ });
238
+ yield Promise.all(Array.from(messagesByEnvironment.entries()).map(([batchEnvironmentId, messages]) => fetch(`https://logs.dynamicauth.com/api/v1/${batchEnvironmentId}`, {
239
+ body: JSON.stringify(messages, createLogPayloadReplacer.createLogPayloadReplacer()),
240
+ headers: {
241
+ 'Content-Type': 'application/json',
242
+ },
243
+ // keepalive lets queued logs (e.g. wallet-creation timeout /
244
+ // abandonment events) flush even as the tab is unloading.
245
+ keepalive: true,
246
+ method: 'POST',
247
+ mode: 'cors',
248
+ referrerPolicy: 'origin-when-cross-origin',
249
249
  })));
250
250
  }
251
251
  catch (error) {
package/src/index.d.ts CHANGED
@@ -4,8 +4,14 @@ import { LogLevel, Message } from './types';
4
4
  export { LogLevel, type Message } from './types';
5
5
  type EmitHttpOptions = {
6
6
  args?: any[];
7
+ environmentId?: string;
8
+ stackField?: 'stack' | 'callsiteStack';
7
9
  transformMeta?: (meta: Record<string, any> | undefined) => Record<string, any> | undefined;
8
10
  };
11
+ export type LoggerOptions = {
12
+ emitErrors?: boolean;
13
+ environmentId?: string;
14
+ };
9
15
  export type InstrumentOptions = {
10
16
  extraArgs?: NonNullable<EmitHttpOptions['args']>;
11
17
  /** Identifies which resource is being instrumented */
@@ -21,6 +27,8 @@ export type InstrumentOptions = {
21
27
  export declare class Logger {
22
28
  private name;
23
29
  private _level;
30
+ private emitErrors;
31
+ private environmentId;
24
32
  static get troubleshootModeEnabled(): boolean;
25
33
  static set troubleshootModeEnabled(val: boolean);
26
34
  static globalMetaData: MetaData;
@@ -28,9 +36,11 @@ export declare class Logger {
28
36
  static events: EventEmitter<{
29
37
  log: (level: LogLevel, message: unknown, ...args: any[]) => void;
30
38
  }, any>;
31
- constructor(name: string | string[], level?: LogLevel);
39
+ constructor(name: string | string[], level?: LogLevel, options?: LoggerOptions);
32
40
  static setEmitErrors(emit?: boolean): void;
41
+ setEmitErrors(emit?: boolean): void;
33
42
  static setEnvironmentId(environmentId?: string): void;
43
+ setEnvironmentId(environmentId?: string): void;
34
44
  private getNameArray;
35
45
  createLogger(name: string | string[], level?: LogLevel): Logger;
36
46
  get logLevel(): string;
@@ -40,7 +50,7 @@ export declare class Logger {
40
50
  get level(): LogLevel;
41
51
  private formatMessage;
42
52
  private captureAndSend;
43
- emitHttpLogs(level: LogLevel, message: Message, { args, transformMeta }: EmitHttpOptions): void;
53
+ emitHttpLogs(level: LogLevel, message: Message, { args, environmentId, stackField, transformMeta, }: EmitHttpOptions): void;
44
54
  /**
45
55
  * Emits an INFO type message to the backend for analysis and debugging
46
56
  */
package/src/index.js CHANGED
@@ -60,11 +60,13 @@ class Logger {
60
60
  static set troubleshootModeEnabled(val) {
61
61
  globalState.troubleshootModeEnabled = val;
62
62
  }
63
- constructor(name, level) {
63
+ constructor(name, level, options = {}) {
64
64
  this.name = name;
65
65
  this._level = undefined;
66
66
  this.metaData = new MetaData();
67
67
  this._level = level;
68
+ this.emitErrors = options.emitErrors;
69
+ this.environmentId = options.environmentId;
68
70
  if (typeof window !== 'undefined' && window.localStorage !== undefined) {
69
71
  // Don't unset the value if it's already set
70
72
  Logger.troubleshootModeEnabled =
@@ -86,16 +88,25 @@ class Logger {
86
88
  globalState.keys.emitErrors = emit;
87
89
  }
88
90
  }
91
+ setEmitErrors(emit) {
92
+ this.emitErrors = emit;
93
+ }
89
94
  static setEnvironmentId(environmentId) {
90
95
  if (environmentId !== undefined) {
91
96
  globalState.keys.environmentId = environmentId;
92
97
  }
93
98
  }
99
+ setEnvironmentId(environmentId) {
100
+ this.environmentId = environmentId;
101
+ }
94
102
  getNameArray(name) {
95
103
  return Array.isArray(name) ? name : [name];
96
104
  }
97
105
  createLogger(name, level) {
98
- return new Logger([...this.getNameArray(this.name), ...this.getNameArray(name)], level !== null && level !== void 0 ? level : this.level);
106
+ return new Logger([...this.getNameArray(this.name), ...this.getNameArray(name)], level !== null && level !== void 0 ? level : this.level, {
107
+ emitErrors: this.emitErrors,
108
+ environmentId: this.environmentId,
109
+ });
99
110
  }
100
111
  get logLevel() {
101
112
  return LogLevel[this.level];
@@ -143,24 +154,29 @@ class Logger {
143
154
  }
144
155
  captureAndSend(level, message, ...args) {
145
156
  return __awaiter(this, void 0, void 0, function* () {
157
+ var _a;
146
158
  // `fetch` (not `window`) is the actual requirement: this also lets Node
147
159
  // (which has had a global `fetch` since v18) forward logs, not just browsers.
148
- if (globalState.keys.emitErrors &&
160
+ if (((_a = this.emitErrors) !== null && _a !== void 0 ? _a : globalState.keys.emitErrors) &&
149
161
  !IGNORE_MESSAGES.includes(message === null || message === void 0 ? void 0 : message.toString()) &&
150
162
  typeof fetch !== 'undefined') {
151
163
  this.emitHttpLogs(level, message, { args });
152
164
  }
153
165
  });
154
166
  }
155
- emitHttpLogs(level, message, { args = [], transformMeta = (meta) => meta }) {
167
+ emitHttpLogs(level, message, _a) {
168
+ var _b;
169
+ var { args = [], environmentId = (_b = this.environmentId) !== null && _b !== void 0 ? _b : globalState.keys.environmentId, stackField = 'stack', transformMeta = (meta) => meta, } = _a;
156
170
  const stack = getStack(this.emitHttpLogs);
157
- // Captured now, not at flush time — see MessageQueueMessage.environmentId.
158
171
  messageQueue.push({
159
172
  args,
160
- environmentId: globalState.keys.environmentId,
173
+ environmentId,
161
174
  level,
162
175
  message,
176
+ meta: globalState.metaData.merge(this.metaData).get(),
163
177
  stack,
178
+ stackField,
179
+ transformMeta,
164
180
  });
165
181
  if (messageQueue.length === 1) {
166
182
  /**
@@ -176,69 +192,53 @@ class Logger {
176
192
  try {
177
193
  // Grab all pending messages immediately and clear the queue
178
194
  const currentBatch = messageQueue.splice(0, messageQueue.length);
179
- // Group by the environmentId each message was queued under (not
180
- // whatever is globally current now) and send one request per
181
- // group, so a concurrent Logger.setEnvironmentId() call — a
182
- // different tenant/request in the same Node process — can't
183
- // redirect an already-queued message to the wrong destination.
184
- const batchesByEnvironmentId = new Map();
195
+ const messagesByEnvironment = new Map();
185
196
  currentBatch.forEach((msg) => {
186
- const existing = batchesByEnvironmentId.get(msg.environmentId);
187
- if (existing) {
188
- existing.push(msg);
189
- }
190
- else {
191
- batchesByEnvironmentId.set(msg.environmentId, [msg]);
197
+ var _a, _b, _c, _d, _e, _f, _g, _h;
198
+ if (!msg.environmentId) {
199
+ this.debug('Environment ID not set, skipping log message');
200
+ return;
192
201
  }
193
- });
194
- yield Promise.all(Array.from(batchesByEnvironmentId.entries()).map((_a) => __awaiter(this, [_a], void 0, function* ([environmentId, msgs]) {
195
- if (!environmentId) {
196
- throw new Error('Environment ID not set');
197
- }
198
- const messages = [];
199
- msgs.forEach((msg) => {
200
- var _a, _b, _c, _d, _e, _f;
201
- const body = {};
202
- const { objectArgs, remainingArgs } = processArgs(msg);
203
- Object.assign(body, ...objectArgs);
204
- const hasWindow = typeof window !== 'undefined';
205
- Object.assign(body, {
206
- level: LogLevel[msg.level],
207
- message: [msg.message, ...remainingArgs].join(' '),
208
- meta: transformMeta(globalState.metaData.merge(this.metaData).get()),
209
- stack: msg.stack,
210
- // Node/server environments have no window/location/navigator.
211
- url: hasWindow
212
- ? {
213
- hostname: (_a = window.location) === null || _a === void 0 ? void 0 : _a.hostname,
214
- origin: (_b = window.location) === null || _b === void 0 ? void 0 : _b.origin,
215
- pathname: (_c = window.location) === null || _c === void 0 ? void 0 : _c.pathname,
216
- port: (_d = window.location) === null || _d === void 0 ? void 0 : _d.port,
217
- protocol: (_e = window.location) === null || _e === void 0 ? void 0 : _e.protocol,
218
- }
219
- : undefined,
220
- userAgent: hasWindow
221
- ? (_f = window.navigator) === null || _f === void 0 ? void 0 : _f.userAgent
222
- : undefined,
223
- });
224
- // Credential/key-material redaction (@dynamic-labs/redaction) —
225
- // scrubs both denylisted keys and credential-shaped free text
226
- // (JWTs, Bearer/Basic, dyn_* keys) anywhere in the payload,
227
- // including inside `message`/`stack`/caller-supplied context.
228
- messages.push(redact(body, DEFAULT_REDACT_KEYS));
229
- });
230
- yield fetch(`https://logs.dynamicauth.com/api/v1/${environmentId}`, {
231
- body: JSON.stringify(messages, createLogPayloadReplacer()),
232
- headers: {
233
- 'Content-Type': 'application/json',
234
- },
235
- // keepalive lets queued logs (e.g. wallet-creation timeout /
236
- // abandonment events) flush even as the tab is unloading.
237
- keepalive: true,
238
- method: 'POST',
239
- mode: 'cors',
240
- referrerPolicy: 'origin-when-cross-origin',
202
+ const body = {};
203
+ const { objectArgs, remainingArgs } = processArgs(msg);
204
+ Object.assign(body, ...objectArgs);
205
+ const hasWindow = typeof window !== 'undefined';
206
+ Object.assign(body, {
207
+ level: LogLevel[msg.level],
208
+ message: [msg.message, ...remainingArgs].join(' '),
209
+ meta: msg.transformMeta ? msg.transformMeta(msg.meta) : msg.meta,
210
+ [(_a = msg.stackField) !== null && _a !== void 0 ? _a : 'stack']: msg.stack,
211
+ // Node/server environments have no window/location/navigator.
212
+ url: hasWindow
213
+ ? {
214
+ hostname: (_b = window.location) === null || _b === void 0 ? void 0 : _b.hostname,
215
+ origin: (_c = window.location) === null || _c === void 0 ? void 0 : _c.origin,
216
+ pathname: (_d = window.location) === null || _d === void 0 ? void 0 : _d.pathname,
217
+ port: (_e = window.location) === null || _e === void 0 ? void 0 : _e.port,
218
+ protocol: (_f = window.location) === null || _f === void 0 ? void 0 : _f.protocol,
219
+ }
220
+ : undefined,
221
+ userAgent: hasWindow ? (_g = window.navigator) === null || _g === void 0 ? void 0 : _g.userAgent : undefined,
241
222
  });
223
+ // Credential/key-material redaction (@dynamic-labs/redaction) —
224
+ // scrubs both denylisted keys and credential-shaped free text
225
+ // (JWTs, Bearer/Basic, dyn_* keys) anywhere in the payload,
226
+ // including inside `message`/`stack`/caller-supplied context.
227
+ const messages = (_h = messagesByEnvironment.get(msg.environmentId)) !== null && _h !== void 0 ? _h : [];
228
+ messages.push(redact(body, DEFAULT_REDACT_KEYS));
229
+ messagesByEnvironment.set(msg.environmentId, messages);
230
+ });
231
+ yield Promise.all(Array.from(messagesByEnvironment.entries()).map(([batchEnvironmentId, messages]) => fetch(`https://logs.dynamicauth.com/api/v1/${batchEnvironmentId}`, {
232
+ body: JSON.stringify(messages, createLogPayloadReplacer()),
233
+ headers: {
234
+ 'Content-Type': 'application/json',
235
+ },
236
+ // keepalive lets queued logs (e.g. wallet-creation timeout /
237
+ // abandonment events) flush even as the tab is unloading.
238
+ keepalive: true,
239
+ method: 'POST',
240
+ mode: 'cors',
241
+ referrerPolicy: 'origin-when-cross-origin',
242
242
  })));
243
243
  }
244
244
  catch (error) {
package/src/types.d.ts CHANGED
@@ -16,6 +16,9 @@ export type MessageQueueMessage = {
16
16
  level: LogLevel;
17
17
  message: Message;
18
18
  args: any[];
19
+ meta?: Record<string, any>;
19
20
  stack?: string;
20
21
  environmentId?: string;
22
+ stackField?: 'stack' | 'callsiteStack';
23
+ transformMeta?: (meta: Record<string, any> | undefined) => Record<string, any> | undefined;
21
24
  };