@mojaloop/sdk-scheme-adapter 24.10.6-snapshot.0 → 24.10.8

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.
Files changed (27) hide show
  1. package/.yarn/cache/{@eslint-compat-npm-1.3.1-41a44c7960-688231f00b.zip → @eslint-compat-npm-1.3.2-b403da4a15-e710ec5ed8.zip} +0 -0
  2. package/.yarn/cache/@hapi-address-npm-5.1.1-2944e6ed9b-9462b22f96.zip +0 -0
  3. package/.yarn/cache/@hapi-formula-npm-3.0.2-70d8fffc4e-c6d4fdcd19.zip +0 -0
  4. package/.yarn/cache/@hapi-hapi-npm-21.4.2-b5f92c52c3-efe9025469.zip +0 -0
  5. package/.yarn/cache/@hapi-pinpoint-npm-2.0.1-4da9d8fcbc-28e72305c1.zip +0 -0
  6. package/.yarn/cache/@hapi-tlds-npm-1.1.2-80b5f7031d-339761cd1a.zip +0 -0
  7. package/.yarn/cache/@ioredis-commands-npm-1.3.0-c1ff038fb4-203029f09d.zip +0 -0
  8. package/.yarn/cache/@mojaloop-central-services-shared-npm-18.30.7-291fa1aea3-aee239baa2.zip +0 -0
  9. package/.yarn/cache/@redocly-openapi-core-npm-1.34.5-6e131049a1-9ecce1975b.zip +0 -0
  10. package/.yarn/cache/@standard-schema-spec-npm-1.0.0-e86c6647f1-aee780cc14.zip +0 -0
  11. package/.yarn/cache/{@types-node-npm-24.2.0-62c65eafa6-b81501e05f.zip → @types-node-npm-24.2.1-00ab09acd1-cdfa7b30b2.zip} +0 -0
  12. package/.yarn/cache/ioredis-npm-5.7.0-870b1dbe10-7407736226.zip +0 -0
  13. package/.yarn/cache/joi-npm-18.0.0-1ebac7eadf-568004d69f.zip +0 -0
  14. package/.yarn/cache/openapi-typescript-npm-7.9.0-08903574eb-c787cfde94.zip +0 -0
  15. package/.yarn/cache/supports-color-npm-10.1.0-48517f80a7-28d191c4ad.zip +0 -0
  16. package/.yarn/cache/yaml-npm-2.8.1-b364b3bec4-eae07b3947.zip +0 -0
  17. package/.yarn/install-state.gz +0 -0
  18. package/CHANGELOG.md +36 -0
  19. package/modules/api-svc/package.json +2 -2
  20. package/modules/api-svc/src/lib/cache.js +79 -27
  21. package/modules/api-svc/src/lib/model/OutboundTransfersModel.js +4 -4
  22. package/modules/api-svc/test/unit/lib/cache.test.js +150 -0
  23. package/modules/outbound-command-event-handler/package.json +3 -3
  24. package/modules/outbound-domain-event-handler/package.json +1 -1
  25. package/modules/private-shared-lib/package.json +3 -3
  26. package/package.json +2 -2
  27. package/{sbom-v24.10.5.csv → sbom-v24.10.7.csv} +88 -92
Binary file
package/CHANGELOG.md CHANGED
@@ -1,4 +1,40 @@
1
1
  # Changelog: [mojaloop/sdk-scheme-adapter](https://github.com/mojaloop/sdk-scheme-adapter)
2
+ ### [24.10.8](https://github.com/mojaloop/sdk-scheme-adapter/compare/v24.10.7...v24.10.8) (2025-08-11)
3
+
4
+
5
+ ### Bug Fixes
6
+
7
+ * concurrency issues ([#601](https://github.com/mojaloop/sdk-scheme-adapter/issues/601)) ([b693e2f](https://github.com/mojaloop/sdk-scheme-adapter/commit/b693e2fe618f256e4511fe9fad256f48d814ca01))
8
+
9
+
10
+ ### Chore
11
+
12
+ * **sbom:** update sbom [skip ci] ([63b0609](https://github.com/mojaloop/sdk-scheme-adapter/commit/63b06090017264a5d375d48bb9800ca9ae183ddd))
13
+
14
+ ### [24.10.7](https://github.com/mojaloop/sdk-scheme-adapter/compare/v24.10.6...v24.10.7) (2025-08-08)
15
+
16
+
17
+ ### Bug Fixes
18
+
19
+ * revert dockerfile change ([#604](https://github.com/mojaloop/sdk-scheme-adapter/issues/604)) ([8ae897c](https://github.com/mojaloop/sdk-scheme-adapter/commit/8ae897cd4e566aed3469528f829ca201686dfeee))
20
+
21
+
22
+ ### Chore
23
+
24
+ * **sbom:** update sbom [skip ci] ([e831089](https://github.com/mojaloop/sdk-scheme-adapter/commit/e831089e0a8df20a8c002b1fccda92de89631eac))
25
+
26
+ ### [24.10.6](https://github.com/mojaloop/sdk-scheme-adapter/compare/v24.10.5...v24.10.6) (2025-08-07)
27
+
28
+
29
+ ### Bug Fixes
30
+
31
+ * issue EROFS from Yarn + Node 22 ([#603](https://github.com/mojaloop/sdk-scheme-adapter/issues/603)) ([503fe96](https://github.com/mojaloop/sdk-scheme-adapter/commit/503fe96d09e633b151132acd3695b518f0dd9057))
32
+
33
+
34
+ ### Chore
35
+
36
+ * **sbom:** update sbom [skip ci] ([b361f4f](https://github.com/mojaloop/sdk-scheme-adapter/commit/b361f4f4f6a09b7e9e19d9e267e4e875ea76b668))
37
+
2
38
  ### [24.10.5](https://github.com/mojaloop/sdk-scheme-adapter/compare/v24.10.4...v24.10.5) (2025-08-01)
3
39
 
4
40
 
@@ -68,7 +68,7 @@
68
68
  "@mojaloop/central-services-error-handling": "13.1.0",
69
69
  "@mojaloop/central-services-logger": "11.9.0",
70
70
  "@mojaloop/central-services-metrics": "12.6.0",
71
- "@mojaloop/central-services-shared": "18.30.6",
71
+ "@mojaloop/central-services-shared": "18.30.7",
72
72
  "@mojaloop/event-sdk": "14.6.1",
73
73
  "@mojaloop/logging-bc-client-lib": "0.5.8",
74
74
  "@mojaloop/ml-schema-transformer-lib": "2.7.7",
@@ -115,7 +115,7 @@
115
115
  "jest-junit": "16.0.0",
116
116
  "npm-check-updates": "16.7.10",
117
117
  "openapi-response-validator": "12.1.3",
118
- "openapi-typescript": "7.8.0",
118
+ "openapi-typescript": "7.9.0",
119
119
  "redis-mock": "0.56.3",
120
120
  "replace": "1.2.2",
121
121
  "standard-version": "9.5.0",
@@ -200,52 +200,104 @@ class Cache {
200
200
  }
201
201
 
202
202
  /**
203
- * Subscribes to a channel for some period and always returns resolved promise
203
+ * Subscribes to a channel and waits for a single message with timeout support.
204
+ *
205
+ * NOTE:
206
+ * This implementation uses EventEmitter to handle Redis pub/sub concurrency issues
207
+ * that occur when multiple subscribers listen to the same channel simultaneously.
208
+ * It's designed to prevent race conditions in party lookups where concurrent requests
209
+ * for the same party ID could interfere with each other.
210
+ * Currently used for: Party lookup operations
211
+ * Future potential: This function can be extended to other scenarios and potentially
212
+ * replace the existing subscribe, unsubscribe, and subscribeToOneMessageWithTimer
213
+ * functions for a more robust and concurrency-safe pub/sub implementation.
204
214
  *
205
215
  * @param {string} channel - The channel name to subscribe to
206
- * @param {boolean} [needParse=true] - specify if the message should be parsed before returning
216
+ * @param {number} requestProcessingTimeoutSeconds - Timeout in seconds before rejecting with TimeoutError
217
+ * @param {boolean} [needParse=true] - Whether to JSON.parse the received message
207
218
  *
208
- * @returns {Promise} - Promise that resolves with a message or an error
219
+ * @returns {Promise<any>} Promise that resolves with the message or rejects with TimeoutError/Error
209
220
  */
210
221
  async subscribeToOneMessageWithTimerNew(channel, requestProcessingTimeoutSeconds, needParse = true) {
211
- let subscription;
212
-
213
222
  return new Promise((resolve, reject) => {
223
+ let timeoutHandle = null;
224
+ let subscription = null;
225
+ let isResolved = false;
226
+
227
+ // Helper to safely unsubscribe from Redis channel
228
+ const unsubscribeFromRedis = async (reason = 'cleanup') => {
229
+ if (this._channelEmitter.listenerCount(channel) === 0 && this._subscriptionClient) {
230
+ try {
231
+ await this._subscriptionClient.unsubscribe(channel);
232
+ this._logger.push({ channel, reason }).debug('Unsubscribed from Redis channel');
233
+ } catch (unsubscribeErr) {
234
+ this._logger.push({ channel, reason }).warn('Failed to unsubscribe from Redis channel', unsubscribeErr);
235
+ }
236
+ }
237
+ };
214
238
 
215
- const timer = setTimeout(async () => {
239
+ // Helper to clean up resources and prevent multiple resolutions
240
+ const cleanup = () => {
241
+ if (timeoutHandle) {
242
+ clearTimeout(timeoutHandle);
243
+ timeoutHandle = null;
244
+ }
216
245
  if (subscription) {
217
246
  this._channelEmitter.removeListener(channel, subscription);
247
+ subscription = null;
218
248
  }
219
- // If there are no listeners left for this channel, we can unsubscribe
220
- if (this._channelEmitter.listenerCount(channel) === 0) {
221
- if (this._subscriptionClient) {
222
- await this._subscriptionClient.unsubscribe(channel);
223
- }
224
- }
225
- const errMessage = 'Timeout error';
226
- this._logger.push({ channel }).warn(errMessage);
249
+ };
250
+
251
+ // Set up timeout handler
252
+ timeoutHandle = setTimeout(async () => {
253
+ if (isResolved) return;
254
+ isResolved = true;
255
+
256
+ cleanup();
257
+ await unsubscribeFromRedis('timeout');
258
+
259
+ const errMessage = `Subscription timeout after ${requestProcessingTimeoutSeconds}s`;
260
+ this._logger.push({ channel, timeout: requestProcessingTimeoutSeconds }).warn(errMessage);
227
261
  reject(new TimeoutError(errMessage));
228
262
  }, requestProcessingTimeoutSeconds * 1000);
229
263
 
264
+ // Set up message handler
230
265
  subscription = (message) => {
231
- this._logger.push({ channel, message, needParse }).debug('subscribeToOneMessageWithTimer is done');
232
- clearTimeout(timer);
233
- resolve(needParse ? JSON.parse(message) : message);
266
+ if (isResolved) return;
267
+ isResolved = true;
268
+
269
+ this._logger.push({ channel, needParse }).debug('Received message on subscribed channel');
270
+
271
+ cleanup();
272
+
273
+ try {
274
+ const result = needParse ? JSON.parse(message) : message;
275
+ resolve(result);
276
+ } catch (parseErr) {
277
+ this._logger.push({ channel, message }).error('Failed to parse received message', parseErr);
278
+ reject(parseErr);
279
+ }
234
280
  };
281
+
282
+ // Register the one-time listener
235
283
  this._channelEmitter.once(channel, subscription);
236
284
 
237
- this._subscriptionClient.subscribe(channel, async (msg) => {
285
+ // Subscribe to Redis channel
286
+ this._subscriptionClient.subscribe(channel, (msg) => {
238
287
  this._channelEmitter.emit(channel, msg);
239
- // If there are no listeners left for this channel, we can unsubscribe
240
- if (this._channelEmitter.listenerCount(channel) === 0) {
241
- if (this._subscriptionClient) {
242
- await this._subscriptionClient.unsubscribe(channel);
243
- }
244
- }
288
+
289
+ // Auto-unsubscribe if no more listeners
290
+ unsubscribeFromRedis('auto-cleanup').catch(err => {
291
+ this._logger.push({ channel }).warn('Auto-unsubscribe failed', err);
292
+ });
245
293
  })
246
- .catch(err => {
247
- this._logger.push({ channel, err }).warn(`error in subscribeToOneMessageWithTimer: ${err.message}`);
248
- reject(err);
294
+ .catch(subscribeErr => {
295
+ if (isResolved) return;
296
+ isResolved = true;
297
+
298
+ cleanup();
299
+ this._logger.push({ channel }).error('Failed to subscribe to Redis channel', subscribeErr);
300
+ reject(subscribeErr);
249
301
  });
250
302
  });
251
303
  }
@@ -340,7 +340,7 @@ class OutboundTransfersModel {
340
340
  this.data.getPartiesRequest = res.originalRequest;
341
341
 
342
342
  this.metrics.partyLookupRequests.inc();
343
- this._logger.isDebugEnabled && this._logger.push({ peer: res }).debug('Party lookup sent to peer');
343
+ this._logger.push({ peer: res }).debug('Party lookup sent to peer');
344
344
 
345
345
  const message = await subscribing;
346
346
 
@@ -365,7 +365,7 @@ class OutboundTransfersModel {
365
365
 
366
366
  payee = payee.party;
367
367
 
368
- this._logger.isVerboseEnabled && this._logger.push({ payee }).verbose('Payee resolved');
368
+ this._logger.push({ payee }).verbose('Payee resolved');
369
369
 
370
370
  // check we got the right payee and info we need
371
371
  if(payee.partyIdInfo.partyIdType !== this.data.to.idType) {
@@ -412,7 +412,7 @@ class OutboundTransfersModel {
412
412
  this.data.supportedCurrencies = payee.supportedCurrencies;
413
413
  }
414
414
 
415
- this._logger.isVerboseEnabled && this._logger.push({
415
+ this._logger.push({
416
416
  transferId: this.data.transferId,
417
417
  homeTransactionId: this.data.homeTransactionId,
418
418
  needFx: this.data.needFx,
@@ -421,7 +421,7 @@ class OutboundTransfersModel {
421
421
  return resolve(payee);
422
422
  }
423
423
  catch(err) {
424
- this._logger.isErrorEnabled && this._logger.error(`Error in resolvePayee ${payeeKey}: ${err.stack || safeStringify(err)}`);
424
+ this._logger.error(`Error in resolvePayee ${payeeKey}:`, err);
425
425
  // If type of error is BackendError, it will be handled by the state machine
426
426
  if (err instanceof BackendError) {
427
427
  this.data.lastError = err;
@@ -210,4 +210,154 @@ describe('Cache Tests -->', () => {
210
210
  expect(result).toEqual(error);
211
211
  expect(unsubscribeSpy).not.toHaveBeenCalled();
212
212
  });
213
+
214
+ test('subscribeToOneMessageWithTimerNew should resolve with parsed message when received before timeout', async () => {
215
+ const channel = `ch-${randomUUID()}`;
216
+ const message = { id: randomUUID(), data: 'test-data' };
217
+ const requestProcessingTimeoutSeconds = 1;
218
+
219
+ const subscribing = cache.subscribeToOneMessageWithTimerNew(channel, requestProcessingTimeoutSeconds);
220
+
221
+ // Simulate a message being published to the channel via EventEmitter
222
+ setTimeout(() => {
223
+ cache._channelEmitter.emit(channel, JSON.stringify(message));
224
+ }, 100);
225
+
226
+ const result = await subscribing;
227
+ expect(result).toStrictEqual(message);
228
+ });
229
+
230
+ test('subscribeToOneMessageWithTimerNew should resolve with unparsed message when needParse is false', async () => {
231
+ const channel = `ch-${randomUUID()}`;
232
+ const message = 'raw-string-message';
233
+ const requestProcessingTimeoutSeconds = 1;
234
+
235
+ const subscribing = cache.subscribeToOneMessageWithTimerNew(channel, requestProcessingTimeoutSeconds, false);
236
+
237
+ // Simulate a message being published to the channel via EventEmitter
238
+ setTimeout(() => {
239
+ cache._channelEmitter.emit(channel, message);
240
+ }, 100);
241
+
242
+ const result = await subscribing;
243
+ expect(result).toBe(message);
244
+ });
245
+
246
+ test('subscribeToOneMessageWithTimerNew should reject with TimeoutError when no message received within timeout', async () => {
247
+ const channel = `ch-${randomUUID()}`;
248
+ const requestProcessingTimeoutSeconds = 0.1; // 100ms timeout
249
+
250
+ const subscribing = cache.subscribeToOneMessageWithTimerNew(channel, requestProcessingTimeoutSeconds);
251
+
252
+ await expect(subscribing).rejects.toThrow(`Subscription timeout after ${requestProcessingTimeoutSeconds}s`);
253
+
254
+ // Test that it's a TimeoutError instance
255
+ try {
256
+ await subscribing;
257
+ expect(true).toBe(false); // Should not reach here
258
+ } catch (error) {
259
+ expect(error.constructor.name).toBe('TimeoutError');
260
+ }
261
+ });
262
+
263
+ test('subscribeToOneMessageWithTimerNew should reject when JSON parsing fails', async () => {
264
+ const channel = `ch-${randomUUID()}`;
265
+ const invalidJson = '{ invalid json }';
266
+ const requestProcessingTimeoutSeconds = 1;
267
+
268
+ const subscribing = cache.subscribeToOneMessageWithTimerNew(channel, requestProcessingTimeoutSeconds, true);
269
+
270
+ // Simulate a message with invalid JSON
271
+ setTimeout(() => {
272
+ cache._channelEmitter.emit(channel, invalidJson);
273
+ }, 100);
274
+
275
+ await expect(subscribing).rejects.toThrow();
276
+ });
277
+
278
+ test('subscribeToOneMessageWithTimerNew should handle multiple subscribers to same channel', async () => {
279
+ const channel1 = `ch-${randomUUID()}`;
280
+ const channel2 = `ch-${randomUUID()}`;
281
+ const message1 = { id: 'msg1', data: 'test1' };
282
+ const message2 = { id: 'msg2', data: 'test2' };
283
+ const requestProcessingTimeoutSeconds = 1;
284
+
285
+ // Create two subscriptions to different channels to avoid interference
286
+ const subscribing1 = cache.subscribeToOneMessageWithTimerNew(channel1, requestProcessingTimeoutSeconds);
287
+ const subscribing2 = cache.subscribeToOneMessageWithTimerNew(channel2, requestProcessingTimeoutSeconds);
288
+
289
+ // Emit messages to each channel separately
290
+ setTimeout(() => {
291
+ cache._channelEmitter.emit(channel1, JSON.stringify(message1));
292
+ cache._channelEmitter.emit(channel2, JSON.stringify(message2));
293
+ }, 100);
294
+
295
+ // Both should resolve with their respective messages
296
+ const results = await Promise.all([subscribing1, subscribing2]);
297
+ expect(results[0]).toStrictEqual(message1);
298
+ expect(results[1]).toStrictEqual(message2);
299
+ });
300
+
301
+ test('subscribeToOneMessageWithTimerNew should handle concurrent subscribers to same channel (party lookup scenario)', async () => {
302
+ const channel = `party-lookup-${randomUUID()}`;
303
+ const partyResponse = { party: { partyIdInfo: { partyIdType: 'MSISDN', partyIdentifier: '123456789' }}};
304
+ const requestProcessingTimeoutSeconds = 1;
305
+
306
+ // Create multiple concurrent subscriptions to same channel (simulating concurrent party lookups)
307
+ const subscribing1 = cache.subscribeToOneMessageWithTimerNew(channel, requestProcessingTimeoutSeconds);
308
+ const subscribing2 = cache.subscribeToOneMessageWithTimerNew(channel, requestProcessingTimeoutSeconds);
309
+ const subscribing3 = cache.subscribeToOneMessageWithTimerNew(channel, requestProcessingTimeoutSeconds);
310
+
311
+ // Simulate a single party response that should resolve all subscribers
312
+ setTimeout(() => {
313
+ cache._channelEmitter.emit(channel, JSON.stringify(partyResponse));
314
+ }, 100);
315
+
316
+ // All subscribers should resolve with the same party response
317
+ const results = await Promise.all([subscribing1, subscribing2, subscribing3]);
318
+ expect(results[0]).toStrictEqual(partyResponse);
319
+ expect(results[1]).toStrictEqual(partyResponse);
320
+ expect(results[2]).toStrictEqual(partyResponse);
321
+ });
322
+
323
+ test('subscribeToOneMessageWithTimerNew should clean up resources on timeout', async () => {
324
+ const channel = `ch-${randomUUID()}`;
325
+ const requestProcessingTimeoutSeconds = 0.1;
326
+
327
+ const removeListenerSpy = jest.spyOn(cache._channelEmitter, 'removeListener');
328
+
329
+ const subscribing = cache.subscribeToOneMessageWithTimerNew(channel, requestProcessingTimeoutSeconds);
330
+
331
+ await expect(subscribing).rejects.toThrow(`Subscription timeout after ${requestProcessingTimeoutSeconds}s`);
332
+
333
+ // Test that it's a TimeoutError instance
334
+ try {
335
+ await subscribing;
336
+ expect(true).toBe(false); // Should not reach here
337
+ } catch (error) {
338
+ expect(error.constructor.name).toBe('TimeoutError');
339
+ }
340
+
341
+ // Verify cleanup was called
342
+ expect(removeListenerSpy).toHaveBeenCalledWith(channel, expect.any(Function));
343
+
344
+ removeListenerSpy.mockRestore();
345
+ });
346
+
347
+ test('subscribeToOneMessageWithTimerNew should reject when subscription fails', async () => {
348
+ const channel = `ch-${randomUUID()}`;
349
+ const requestProcessingTimeoutSeconds = 1;
350
+ const subscriptionError = new Error('subscription failed');
351
+
352
+ // Mock the _subscriptionClient.subscribe to reject
353
+ const originalSubscribe = cache._subscriptionClient.subscribe;
354
+ cache._subscriptionClient.subscribe = jest.fn().mockRejectedValue(subscriptionError);
355
+
356
+ const subscribing = cache.subscribeToOneMessageWithTimerNew(channel, requestProcessingTimeoutSeconds);
357
+
358
+ await expect(subscribing).rejects.toThrow('subscription failed');
359
+
360
+ // Restore original method
361
+ cache._subscriptionClient.subscribe = originalSubscribe;
362
+ });
213
363
  });
@@ -42,7 +42,7 @@
42
42
  },
43
43
  "dependencies": {
44
44
  "@mojaloop/api-snippets": "18.1.1",
45
- "@mojaloop/central-services-shared": "18.30.6",
45
+ "@mojaloop/central-services-shared": "18.30.7",
46
46
  "@mojaloop/logging-bc-client-lib": "0.5.8",
47
47
  "@mojaloop/logging-bc-public-types-lib": "0.5.6",
48
48
  "@mojaloop/sdk-scheme-adapter-private-shared-lib": "workspace:^",
@@ -56,11 +56,11 @@
56
56
  "yamljs": "0.3.0"
57
57
  },
58
58
  "devDependencies": {
59
- "@eslint/compat": "1.3.1",
59
+ "@eslint/compat": "1.3.2",
60
60
  "@types/convict": "6.1.6",
61
61
  "@types/express": "5.0.3",
62
62
  "@types/jest": "30.0.0",
63
- "@types/node": "24.2.0",
63
+ "@types/node": "24.2.1",
64
64
  "@types/node-cache": "4.2.5",
65
65
  "@types/supertest": "6.0.3",
66
66
  "@types/swagger-ui-express": "4.1.8",
@@ -57,7 +57,7 @@
57
57
  "@types/convict": "6.1.6",
58
58
  "@types/express": "5.0.3",
59
59
  "@types/jest": "30.0.0",
60
- "@types/node": "24.2.0",
60
+ "@types/node": "24.2.1",
61
61
  "@types/node-cache": "4.2.5",
62
62
  "@types/supertest": "6.0.3",
63
63
  "@types/swagger-ui-express": "4.1.8",
@@ -30,7 +30,7 @@
30
30
  },
31
31
  "dependencies": {
32
32
  "@mojaloop/api-snippets": "18.1.1",
33
- "@mojaloop/central-services-shared": "18.30.6",
33
+ "@mojaloop/central-services-shared": "18.30.7",
34
34
  "@mojaloop/logging-bc-public-types-lib": "0.5.6",
35
35
  "@mojaloop/platform-shared-lib-messaging-types-lib": "0.7.3",
36
36
  "@mojaloop/platform-shared-lib-nodejs-kafka-client-lib": "0.5.18",
@@ -39,8 +39,8 @@
39
39
  "uuid": "11.1.0"
40
40
  },
41
41
  "devDependencies": {
42
- "@eslint/compat": "1.3.1",
43
- "@types/node": "24.2.0",
42
+ "@eslint/compat": "1.3.2",
43
+ "@types/node": "24.2.1",
44
44
  "@types/uuid": "10.0.0",
45
45
  "@typescript-eslint/eslint-plugin": "8.39.0",
46
46
  "@typescript-eslint/parser": "8.39.0",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mojaloop/sdk-scheme-adapter",
3
- "version": "24.10.6-snapshot.0",
3
+ "version": "24.10.8",
4
4
  "description": "mojaloop sdk-scheme-adapter",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://github.com/mojaloop/sdk-scheme-adapter",
@@ -82,7 +82,7 @@
82
82
  },
83
83
  "devDependencies": {
84
84
  "@types/jest": "30.0.0",
85
- "@types/node": "24.2.0",
85
+ "@types/node": "24.2.1",
86
86
  "@types/node-cache": "4.2.5",
87
87
  "@typescript-eslint/eslint-plugin": "8.39.0",
88
88
  "@typescript-eslint/parser": "8.39.0",