@devrev/airsync-sdk 2.0.0-beta.1 → 2.0.0-beta.3

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 (191) hide show
  1. package/README.md +0 -4
  2. package/dist/airsync-sdk.d.ts +2059 -0
  3. package/dist/attachments-streaming/attachments-streaming-pool.d.ts +2 -1
  4. package/dist/attachments-streaming/attachments-streaming-pool.d.ts.map +1 -1
  5. package/dist/attachments-streaming/attachments-streaming-pool.interfaces.d.ts +8 -2
  6. package/dist/attachments-streaming/attachments-streaming-pool.interfaces.d.ts.map +1 -1
  7. package/dist/attachments-streaming/attachments-streaming-pool.js +27 -16
  8. package/dist/attachments-streaming/attachments-streaming-pool.test.js +246 -27
  9. package/dist/common/constants.d.ts +16 -5
  10. package/dist/common/constants.d.ts.map +1 -1
  11. package/dist/common/constants.js +20 -6
  12. package/dist/common/control-protocol.d.ts +2 -2
  13. package/dist/common/control-protocol.d.ts.map +1 -1
  14. package/dist/common/control-protocol.js +1 -5
  15. package/dist/common/helpers.d.ts +8 -0
  16. package/dist/common/helpers.d.ts.map +1 -1
  17. package/dist/common/helpers.js +15 -0
  18. package/dist/common/install-initial-domain-mapping.d.ts +2 -2
  19. package/dist/common/install-initial-domain-mapping.test.js +5 -2
  20. package/dist/common/test-utils.d.ts +19 -0
  21. package/dist/common/test-utils.d.ts.map +1 -0
  22. package/dist/common/test-utils.js +101 -0
  23. package/dist/common/time-value-resolver.d.ts +47 -0
  24. package/dist/common/time-value-resolver.d.ts.map +1 -0
  25. package/dist/common/time-value-resolver.js +141 -0
  26. package/dist/common/time-value-resolver.test.d.ts +2 -0
  27. package/dist/common/time-value-resolver.test.d.ts.map +1 -0
  28. package/dist/common/time-value-resolver.test.js +268 -0
  29. package/dist/http/axios-client-internal.d.ts.map +1 -1
  30. package/dist/http/axios-client-internal.js +7 -0
  31. package/dist/http/axios-client-internal.test.js +21 -0
  32. package/dist/http/axios-client.d.ts.map +1 -1
  33. package/dist/http/axios-client.js +6 -3
  34. package/dist/http/index.d.ts +0 -1
  35. package/dist/http/index.d.ts.map +1 -1
  36. package/dist/http/index.js +0 -1
  37. package/dist/index.d.ts +12 -10
  38. package/dist/index.d.ts.map +1 -1
  39. package/dist/index.js +18 -13
  40. package/dist/logger/logger.d.ts +1 -17
  41. package/dist/logger/logger.d.ts.map +1 -1
  42. package/dist/logger/logger.interfaces.d.ts +2 -2
  43. package/dist/logger/logger.js +35 -27
  44. package/dist/logger/logger.test.js +66 -19
  45. package/dist/mappers/mappers.interface.d.ts +5 -5
  46. package/dist/mappers/mappers.interface.js +3 -3
  47. package/dist/mappers/mappers.test.js +8 -10
  48. package/dist/mock-server/mock-server.d.ts +47 -0
  49. package/dist/mock-server/mock-server.d.ts.map +1 -0
  50. package/dist/mock-server/mock-server.interfaces.d.ts +73 -0
  51. package/dist/mock-server/mock-server.interfaces.d.ts.map +1 -0
  52. package/dist/mock-server/mock-server.interfaces.js +4 -0
  53. package/dist/mock-server/mock-server.js +278 -0
  54. package/dist/multithreading/adapters/base-adapter.d.ts +56 -0
  55. package/dist/multithreading/adapters/base-adapter.d.ts.map +1 -0
  56. package/dist/multithreading/adapters/base-adapter.emit.test.d.ts +2 -0
  57. package/dist/multithreading/adapters/base-adapter.emit.test.d.ts.map +1 -0
  58. package/dist/multithreading/adapters/base-adapter.emit.test.js +403 -0
  59. package/dist/multithreading/adapters/base-adapter.js +105 -0
  60. package/dist/multithreading/adapters/extraction-adapter.artifacts.test.d.ts +2 -0
  61. package/dist/multithreading/adapters/extraction-adapter.artifacts.test.d.ts.map +1 -0
  62. package/dist/multithreading/{worker-adapter/worker-adapter.artifacts.test.js → adapters/extraction-adapter.artifacts.test.js} +53 -5
  63. package/dist/multithreading/adapters/extraction-adapter.d.ts +58 -0
  64. package/dist/multithreading/adapters/extraction-adapter.d.ts.map +1 -0
  65. package/dist/multithreading/adapters/extraction-adapter.js +325 -0
  66. package/dist/multithreading/adapters/extraction-adapter.test.d.ts +2 -0
  67. package/dist/multithreading/adapters/extraction-adapter.test.d.ts.map +1 -0
  68. package/dist/multithreading/adapters/extraction-adapter.test.js +789 -0
  69. package/dist/multithreading/adapters/loading-adapter.d.ts +44 -0
  70. package/dist/multithreading/adapters/loading-adapter.d.ts.map +1 -0
  71. package/dist/multithreading/{worker-adapter/worker-adapter.helpers.d.ts → adapters/loading-adapter.helpers.d.ts} +1 -1
  72. package/dist/multithreading/adapters/loading-adapter.helpers.d.ts.map +1 -0
  73. package/dist/multithreading/adapters/loading-adapter.helpers.test.d.ts +2 -0
  74. package/dist/multithreading/adapters/loading-adapter.helpers.test.d.ts.map +1 -0
  75. package/dist/multithreading/{worker-adapter/worker-adapter.helpers.test.js → adapters/loading-adapter.helpers.test.js} +26 -26
  76. package/dist/multithreading/adapters/loading-adapter.js +461 -0
  77. package/dist/multithreading/adapters/loading-adapter.test.d.ts +2 -0
  78. package/dist/multithreading/adapters/loading-adapter.test.d.ts.map +1 -0
  79. package/dist/multithreading/adapters/loading-adapter.test.js +589 -0
  80. package/dist/multithreading/adapters/serialization.test.d.ts +2 -0
  81. package/dist/multithreading/adapters/serialization.test.d.ts.map +1 -0
  82. package/dist/multithreading/adapters/serialization.test.js +71 -0
  83. package/dist/multithreading/create-worker.test.js +36 -17
  84. package/dist/multithreading/process-task.d.ts +16 -1
  85. package/dist/multithreading/process-task.d.ts.map +1 -1
  86. package/dist/multithreading/process-task.js +97 -82
  87. package/dist/multithreading/process-task.test.d.ts +2 -0
  88. package/dist/multithreading/process-task.test.d.ts.map +1 -0
  89. package/dist/multithreading/process-task.test.js +146 -0
  90. package/dist/multithreading/spawn/spawn.d.ts +3 -3
  91. package/dist/multithreading/spawn/spawn.d.ts.map +1 -1
  92. package/dist/multithreading/spawn/spawn.helpers.d.ts.map +1 -1
  93. package/dist/multithreading/spawn/spawn.helpers.js +6 -14
  94. package/dist/multithreading/spawn/spawn.helpers.test.js +8 -8
  95. package/dist/multithreading/spawn/spawn.js +20 -25
  96. package/dist/multithreading/spawn/spawn.test.d.ts +2 -0
  97. package/dist/multithreading/spawn/spawn.test.d.ts.map +1 -0
  98. package/dist/multithreading/spawn/spawn.test.js +232 -0
  99. package/dist/repo/repo.d.ts.map +1 -1
  100. package/dist/repo/repo.interfaces.d.ts +4 -2
  101. package/dist/repo/repo.interfaces.d.ts.map +1 -1
  102. package/dist/repo/repo.js +4 -3
  103. package/dist/repo/repo.test.js +60 -7
  104. package/dist/state/base-state.d.ts +75 -0
  105. package/dist/state/base-state.d.ts.map +1 -0
  106. package/dist/state/base-state.js +261 -0
  107. package/dist/state/extraction-state.d.ts +29 -0
  108. package/dist/state/extraction-state.d.ts.map +1 -0
  109. package/dist/state/extraction-state.js +122 -0
  110. package/dist/state/loading-state.d.ts +19 -0
  111. package/dist/state/loading-state.d.ts.map +1 -0
  112. package/dist/state/loading-state.js +40 -0
  113. package/dist/state/state.extract-window.test.d.ts +2 -0
  114. package/dist/state/state.extract-window.test.d.ts.map +1 -0
  115. package/dist/state/state.extract-window.test.js +163 -0
  116. package/dist/state/state.interfaces.d.ts +44 -27
  117. package/dist/state/state.interfaces.d.ts.map +1 -1
  118. package/dist/state/state.interfaces.js +18 -5
  119. package/dist/state/state.pending-boundaries.test.d.ts +2 -0
  120. package/dist/state/state.pending-boundaries.test.d.ts.map +1 -0
  121. package/dist/state/state.pending-boundaries.test.js +189 -0
  122. package/dist/state/state.post-state.test.d.ts +2 -0
  123. package/dist/state/state.post-state.test.d.ts.map +1 -0
  124. package/dist/state/state.post-state.test.js +78 -0
  125. package/dist/state/state.test.js +135 -88
  126. package/dist/state/state.time-value-resolution.test.d.ts +2 -0
  127. package/dist/state/state.time-value-resolution.test.d.ts.map +1 -0
  128. package/dist/state/state.time-value-resolution.test.js +175 -0
  129. package/dist/tsdoc-metadata.json +11 -0
  130. package/dist/types/common.d.ts +0 -25
  131. package/dist/types/common.d.ts.map +1 -1
  132. package/dist/types/common.js +1 -11
  133. package/dist/types/external-domain-metadata.d.ts +20 -1
  134. package/dist/types/external-domain-metadata.d.ts.map +1 -1
  135. package/dist/types/extraction.d.ts +92 -221
  136. package/dist/types/extraction.d.ts.map +1 -1
  137. package/dist/types/extraction.js +56 -124
  138. package/dist/types/extraction.test.js +69 -43
  139. package/dist/types/index.d.ts +3 -3
  140. package/dist/types/index.d.ts.map +1 -1
  141. package/dist/types/index.js +6 -3
  142. package/dist/types/loading.d.ts +4 -24
  143. package/dist/types/loading.d.ts.map +1 -1
  144. package/dist/types/loading.js +1 -22
  145. package/dist/types/workers.d.ts +47 -29
  146. package/dist/types/workers.d.ts.map +1 -1
  147. package/dist/types/workers.js +1 -0
  148. package/dist/uploader/uploader.d.ts +1 -0
  149. package/dist/uploader/uploader.d.ts.map +1 -1
  150. package/dist/uploader/uploader.helpers.test.js +0 -11
  151. package/dist/uploader/uploader.interfaces.d.ts +3 -3
  152. package/dist/uploader/uploader.js +53 -20
  153. package/dist/uploader/uploader.test.js +22 -10
  154. package/package.json +10 -13
  155. package/dist/common/event-type-translation.d.ts +0 -24
  156. package/dist/common/event-type-translation.d.ts.map +0 -1
  157. package/dist/common/event-type-translation.js +0 -117
  158. package/dist/deprecated/adapter/index.d.ts +0 -62
  159. package/dist/deprecated/adapter/index.d.ts.map +0 -1
  160. package/dist/deprecated/adapter/index.js +0 -151
  161. package/dist/deprecated/common/helpers.d.ts +0 -7
  162. package/dist/deprecated/common/helpers.d.ts.map +0 -1
  163. package/dist/deprecated/common/helpers.js +0 -47
  164. package/dist/deprecated/demo-extractor/external_domain_metadata.json +0 -38
  165. package/dist/deprecated/demo-extractor/index.d.ts +0 -18
  166. package/dist/deprecated/demo-extractor/index.d.ts.map +0 -1
  167. package/dist/deprecated/demo-extractor/index.js +0 -161
  168. package/dist/deprecated/http/client.d.ts +0 -22
  169. package/dist/deprecated/http/client.d.ts.map +0 -1
  170. package/dist/deprecated/http/client.js +0 -161
  171. package/dist/deprecated/uploader/index.d.ts +0 -35
  172. package/dist/deprecated/uploader/index.d.ts.map +0 -1
  173. package/dist/deprecated/uploader/index.js +0 -161
  174. package/dist/http/types.d.ts +0 -17
  175. package/dist/http/types.d.ts.map +0 -1
  176. package/dist/http/types.js +0 -2
  177. package/dist/multithreading/worker-adapter/worker-adapter.artifacts.test.d.ts +0 -2
  178. package/dist/multithreading/worker-adapter/worker-adapter.artifacts.test.d.ts.map +0 -1
  179. package/dist/multithreading/worker-adapter/worker-adapter.d.ts +0 -91
  180. package/dist/multithreading/worker-adapter/worker-adapter.d.ts.map +0 -1
  181. package/dist/multithreading/worker-adapter/worker-adapter.helpers.d.ts.map +0 -1
  182. package/dist/multithreading/worker-adapter/worker-adapter.helpers.test.d.ts +0 -2
  183. package/dist/multithreading/worker-adapter/worker-adapter.helpers.test.d.ts.map +0 -1
  184. package/dist/multithreading/worker-adapter/worker-adapter.js +0 -745
  185. package/dist/multithreading/worker-adapter/worker-adapter.test.d.ts +0 -2
  186. package/dist/multithreading/worker-adapter/worker-adapter.test.d.ts.map +0 -1
  187. package/dist/multithreading/worker-adapter/worker-adapter.test.js +0 -483
  188. package/dist/state/state.d.ts +0 -30
  189. package/dist/state/state.d.ts.map +0 -1
  190. package/dist/state/state.js +0 -166
  191. /package/dist/multithreading/{worker-adapter/worker-adapter.helpers.js → adapters/loading-adapter.helpers.js} +0 -0
@@ -2,7 +2,8 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const node_util_1 = require("node:util");
4
4
  const constants_1 = require("../common/constants");
5
- const test_helpers_1 = require("../tests/test-helpers");
5
+ const jest_setup_1 = require("../tests/jest.setup");
6
+ const test_utils_1 = require("../common/test-utils");
6
7
  const extraction_1 = require("../types/extraction");
7
8
  const logger_1 = require("./logger");
8
9
  const logger_constants_1 = require("./logger.constants");
@@ -20,24 +21,8 @@ describe(logger_1.Logger.name, () => {
20
21
  let mockOptions;
21
22
  beforeEach(() => {
22
23
  jest.clearAllMocks();
23
- mockEvent = (0, test_helpers_1.createEvent)({
24
- eventType: extraction_1.EventType.StartExtractingData,
25
- eventContextOverrides: {
26
- dev_org: 'DEV-test',
27
- dev_org_id: 'DEV-test-id',
28
- dev_user: 'DEVU-test',
29
- dev_user_id: 'DEVU-test-id',
30
- external_sync_unit: 'test-unit',
31
- external_sync_unit_id: 'test-unit-id',
32
- external_sync_unit_name: 'test-unit-name',
33
- external_system: 'test-system',
34
- external_system_type: 'test-type',
35
- import_slug: 'test-import',
36
- request_id: 'test-request-id',
37
- snap_in_slug: 'test-snap-slug',
38
- sync_run: 'test-sync-run',
39
- sync_run_id: 'test-sync-run-id',
40
- },
24
+ mockEvent = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
25
+ payload: { event_type: extraction_1.EventType.StartExtractingData },
41
26
  });
42
27
  mockOptions = {
43
28
  isLocalDevelopment: false,
@@ -378,6 +363,68 @@ describe(logger_1.getPrintableState.name, () => {
378
363
  });
379
364
  });
380
365
  });
366
+ describe(logger_1.serializeError.name, () => {
367
+ it('should return the error message string for a standard Error', () => {
368
+ const error = new Error('something went wrong');
369
+ expect((0, logger_1.serializeError)(error)).toBe('something went wrong');
370
+ });
371
+ it('should include error name for named error types', () => {
372
+ const typeError = new TypeError('invalid type');
373
+ expect((0, logger_1.serializeError)(typeError)).toBe('TypeError: invalid type');
374
+ const rangeError = new RangeError('out of range');
375
+ expect((0, logger_1.serializeError)(rangeError)).toBe('RangeError: out of range');
376
+ });
377
+ it('should return a JSON string for an Axios error', () => {
378
+ const axiosError = {
379
+ isAxiosError: true,
380
+ response: {
381
+ status: 500,
382
+ statusText: 'Internal Server Error',
383
+ data: 'fail',
384
+ headers: {},
385
+ },
386
+ config: { method: 'GET', url: '/api/test', params: undefined },
387
+ };
388
+ const result = (0, logger_1.serializeError)(axiosError);
389
+ expect(typeof result).toBe('string');
390
+ const parsed = JSON.parse(result);
391
+ expect(parsed.isAxiosError).toBe(true);
392
+ expect(parsed.response.status).toBe(500);
393
+ });
394
+ it('should return a JSON string for a plain object', () => {
395
+ const obj = { code: 42, detail: 'bad input' };
396
+ const result = (0, logger_1.serializeError)(obj);
397
+ expect(typeof result).toBe('string');
398
+ expect(JSON.parse(result)).toEqual(obj);
399
+ });
400
+ it('should return a JSON string for a string value', () => {
401
+ expect((0, logger_1.serializeError)('raw string error')).toBe('raw string error');
402
+ });
403
+ it('[edge] should handle null without throwing', () => {
404
+ const result = (0, logger_1.serializeError)(null);
405
+ expect(typeof result).toBe('string');
406
+ expect(result).toBe('null');
407
+ });
408
+ it('[edge] should handle undefined without throwing', () => {
409
+ const result = (0, logger_1.serializeError)(undefined);
410
+ expect(typeof result).toBe('string');
411
+ });
412
+ it('[edge] should fall back to extracting own properties for objects that stringify to empty object', () => {
413
+ // Simulate an error-like object with non-enumerable properties
414
+ // (e.g. cross-realm Error that fails instanceof check)
415
+ const errorLike = Object.create(null);
416
+ Object.defineProperty(errorLike, 'message', {
417
+ value: 'cross-realm error',
418
+ enumerable: false,
419
+ });
420
+ const result = (0, logger_1.serializeError)(errorLike);
421
+ expect(typeof result).toBe('string');
422
+ // Should not be '{}' — that's the whole point of the fix
423
+ expect(result).not.toBe('{}');
424
+ // Should have extracted the non-enumerable 'message' property
425
+ expect(result).toContain('cross-realm error');
426
+ });
427
+ });
381
428
  describe(logger_1.serializeAxiosError.name, () => {
382
429
  it('should serialize Axios error with response data', () => {
383
430
  // Arrange
@@ -1,11 +1,11 @@
1
- import { AirdropEvent } from '../types';
1
+ import { AirSyncEvent } from '../types';
2
2
  import { DonV2 } from '../types/loading';
3
3
  import { WorkerAdapterOptions } from '../types/workers';
4
4
  /**
5
5
  * Configuration interface for creating a Mappers instance.
6
6
  */
7
7
  export interface MappersFactoryInterface {
8
- event: AirdropEvent;
8
+ event: AirSyncEvent;
9
9
  options?: WorkerAdapterOptions;
10
10
  }
11
11
  /**
@@ -262,9 +262,9 @@ export interface MappersGetByExternalIdParams {
262
262
  export declare enum SyncMapperRecordTargetType {
263
263
  ACCESS_CONTROL_ENTRY = "access_control_entry",
264
264
  ACCOUNT = "account",
265
- AIRDROP_AUTHORIZATION_POLICY = "airdrop_authorization_policy",
266
- AIRDROP_FIELD_AUTHORIZATION_POLICY = "airdrop_field_authorization_policy",
267
- AIRDROP_PLATFORM_GROUP = "airdrop_platform_group",
265
+ AIRSYNC_AUTHORIZATION_POLICY = "airdrop_authorization_policy",
266
+ AIRSYNC_FIELD_AUTHORIZATION_POLICY = "airdrop_field_authorization_policy",
267
+ AIRSYNC_PLATFORM_GROUP = "airdrop_platform_group",
268
268
  ARTICLE = "article",
269
269
  ARTIFACT = "artifact",
270
270
  CHAT = "chat",
@@ -23,9 +23,9 @@ var SyncMapperRecordTargetType;
23
23
  (function (SyncMapperRecordTargetType) {
24
24
  SyncMapperRecordTargetType["ACCESS_CONTROL_ENTRY"] = "access_control_entry";
25
25
  SyncMapperRecordTargetType["ACCOUNT"] = "account";
26
- SyncMapperRecordTargetType["AIRDROP_AUTHORIZATION_POLICY"] = "airdrop_authorization_policy";
27
- SyncMapperRecordTargetType["AIRDROP_FIELD_AUTHORIZATION_POLICY"] = "airdrop_field_authorization_policy";
28
- SyncMapperRecordTargetType["AIRDROP_PLATFORM_GROUP"] = "airdrop_platform_group";
26
+ SyncMapperRecordTargetType["AIRSYNC_AUTHORIZATION_POLICY"] = "airdrop_authorization_policy";
27
+ SyncMapperRecordTargetType["AIRSYNC_FIELD_AUTHORIZATION_POLICY"] = "airdrop_field_authorization_policy";
28
+ SyncMapperRecordTargetType["AIRSYNC_PLATFORM_GROUP"] = "airdrop_platform_group";
29
29
  SyncMapperRecordTargetType["ARTICLE"] = "article";
30
30
  SyncMapperRecordTargetType["ARTIFACT"] = "artifact";
31
31
  SyncMapperRecordTargetType["CHAT"] = "chat";
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ const test_utils_1 = require("../common/test-utils");
3
4
  const axios_client_internal_1 = require("../http/axios-client-internal");
4
- const test_helpers_1 = require("../tests/test-helpers");
5
5
  const extraction_1 = require("../types/extraction");
6
6
  const mappers_1 = require("./mappers");
7
7
  const mappers_interface_1 = require("./mappers.interface");
@@ -9,7 +9,6 @@ const mappers_interface_1 = require("./mappers.interface");
9
9
  jest.mock('../http/axios-client-internal');
10
10
  const mockAxiosClient = axios_client_internal_1.axiosClient;
11
11
  describe(mappers_1.Mappers.name, () => {
12
- const apiEndpoint = 'test_devrev_endpoint';
13
12
  const apiToken = 'test_service_token';
14
13
  const syncUnit = 'test_sync_unit';
15
14
  const targetId = 'test_target_id';
@@ -17,12 +16,11 @@ describe(mappers_1.Mappers.name, () => {
17
16
  const id = 'test_id';
18
17
  const externalIds = ['test_external_id'];
19
18
  const targets = ['test_target_id'];
20
- const mockEvent = (0, test_helpers_1.createEvent)({
21
- eventType: extraction_1.EventType.ExtractionDataStart,
22
- executionMetadataOverrides: { devrev_endpoint: apiEndpoint },
23
- contextOverrides: {
19
+ const mockEvent = (0, test_utils_1.createMockEvent)(test_utils_1.MOCK_SERVER_DEFAULT_URL, {
20
+ context: {
24
21
  secrets: { service_account_token: apiToken },
25
22
  },
23
+ payload: { event_type: extraction_1.EventType.StartExtractingData },
26
24
  });
27
25
  const mappers = new mappers_1.Mappers({ event: mockEvent });
28
26
  beforeEach(() => {
@@ -38,7 +36,7 @@ describe(mappers_1.Mappers.name, () => {
38
36
  // Act
39
37
  await mappers.getByTargetId(params);
40
38
  // Assert
41
- expect(mockAxiosClient.get).toHaveBeenCalledWith(`${apiEndpoint}/internal/airdrop.sync-mapper-record.get-by-target`, {
39
+ expect(mockAxiosClient.get).toHaveBeenCalledWith(`${test_utils_1.MOCK_SERVER_DEFAULT_URL}/internal/airdrop.sync-mapper-record.get-by-target`, {
42
40
  headers: {
43
41
  Authorization: apiToken,
44
42
  },
@@ -56,7 +54,7 @@ describe(mappers_1.Mappers.name, () => {
56
54
  // Act
57
55
  await mappers.getByExternalId(params);
58
56
  // Assert
59
- expect(mockAxiosClient.get).toHaveBeenCalledWith(`${apiEndpoint}/internal/airdrop.sync-mapper-record.get-by-external-id`, {
57
+ expect(mockAxiosClient.get).toHaveBeenCalledWith(`${test_utils_1.MOCK_SERVER_DEFAULT_URL}/internal/airdrop.sync-mapper-record.get-by-external-id`, {
60
58
  headers: {
61
59
  Authorization: apiToken,
62
60
  },
@@ -79,7 +77,7 @@ describe(mappers_1.Mappers.name, () => {
79
77
  // Act
80
78
  await mappers.create(params);
81
79
  // Assert
82
- expect(mockAxiosClient.post).toHaveBeenCalledWith(`${apiEndpoint}/internal/airdrop.sync-mapper-record.create`, params, {
80
+ expect(mockAxiosClient.post).toHaveBeenCalledWith(`${test_utils_1.MOCK_SERVER_DEFAULT_URL}/internal/airdrop.sync-mapper-record.create`, params, {
83
81
  headers: {
84
82
  Authorization: apiToken,
85
83
  },
@@ -98,7 +96,7 @@ describe(mappers_1.Mappers.name, () => {
98
96
  // Act
99
97
  await mappers.update(params);
100
98
  // Assert
101
- expect(mockAxiosClient.post).toHaveBeenCalledWith(`${apiEndpoint}/internal/airdrop.sync-mapper-record.update`, params, {
99
+ expect(mockAxiosClient.post).toHaveBeenCalledWith(`${test_utils_1.MOCK_SERVER_DEFAULT_URL}/internal/airdrop.sync-mapper-record.update`, params, {
102
100
  headers: {
103
101
  Authorization: apiToken,
104
102
  },
@@ -0,0 +1,47 @@
1
+ import { RequestInfo, RouteConfig } from './mock-server.interfaces';
2
+ /**
3
+ * MockServer used in tests to mock internal AirSync endpoints.
4
+ * This is a simple mock server that listens on a port and responds to requests.
5
+ * Supports per-test route configuration to simulate different response scenarios.
6
+ */
7
+ export declare class MockServer {
8
+ private server;
9
+ private internalPort;
10
+ port: number;
11
+ baseUrl: string;
12
+ private routeHandlers;
13
+ private requests;
14
+ private requestCounts;
15
+ constructor(port?: number);
16
+ start(): Promise<void>;
17
+ stop(): Promise<void>;
18
+ private handleRequest;
19
+ /**
20
+ * Default route handler for the mock server. Returns { success: true } for
21
+ * routes that are not explicitly set.
22
+ */
23
+ private defaultRouteHandler;
24
+ private getRouteKey;
25
+ /**
26
+ * Configures a route to return a specific status code and optional response body.
27
+ */
28
+ setRoute(config: RouteConfig): void;
29
+ /**
30
+ * Resets all custom route handlers, restoring all default handlers.
31
+ * Also clears request tracking data.
32
+ */
33
+ resetRoutes(): void;
34
+ /**
35
+ * Returns the most recent request or undefined if no requests exist.
36
+ */
37
+ getLastRequest(): RequestInfo | undefined;
38
+ /**
39
+ * Gets the number of requests made to a specific endpoint.
40
+ */
41
+ getRequestCount(method: string, path: string): number;
42
+ /**
43
+ * Gets all requests made to a specific endpoint.
44
+ */
45
+ getRequests(method: string, path: string): RequestInfo[];
46
+ }
47
+ //# sourceMappingURL=mock-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mock-server.d.ts","sourceRoot":"","sources":["../../src/mock-server/mock-server.ts"],"names":[],"mappings":"AAEA,OAAO,EAKL,WAAW,EACX,WAAW,EAEZ,MAAM,0BAA0B,CAAC;AAuElC;;;;GAIG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,YAAY,CAAS;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,aAAa,CAA4B;IACjD,OAAO,CAAC,QAAQ,CAAqB;IACrC,OAAO,CAAC,aAAa,CAA4B;gBAErC,IAAI,GAAE,MAAiC;IAMtC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAsBtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;YAkBpB,aAAa;IA+B3B;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IA6B3B,OAAO,CAAC,WAAW;IAInB;;OAEG;IACI,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI;IAyE1C;;;OAGG;IACI,WAAW,IAAI,IAAI;IAM1B;;OAEG;IACI,cAAc,IAAI,WAAW,GAAG,SAAS;IAOhD;;OAEG;IACI,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM;IAI5D;;OAEG;IACI,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,WAAW,EAAE;CAQhE"}
@@ -0,0 +1,73 @@
1
+ import { IncomingMessage, ServerResponse } from 'http';
2
+ export declare const DEFAULT_MOCK_SERVER_PORT = 3001;
3
+ export interface ParsedRequest extends IncomingMessage {
4
+ /** Parsed URL path (without query string) */
5
+ path: string;
6
+ /** Parsed JSON body (if any) */
7
+ body?: unknown;
8
+ }
9
+ export interface MockResponse extends ServerResponse {
10
+ /** Set response headers from a record */
11
+ set(headers: Record<string, string>): MockResponse;
12
+ /** Set the HTTP status code */
13
+ status(code: number): MockResponse;
14
+ /** Send a JSON response */
15
+ json(data: unknown): void;
16
+ /** Send an empty response */
17
+ send(): void;
18
+ }
19
+ /**
20
+ * Configuration for retry simulation behavior.
21
+ */
22
+ export interface RetryConfig {
23
+ /** Number of times to return error before succeeding (default: 4) */
24
+ failureCount?: number;
25
+ /** 5xx status code to return during failures (default: 500) */
26
+ errorStatus?: number;
27
+ /** Optional error response body to send as JSON during failures */
28
+ errorBody?: unknown;
29
+ /** Optional headers to send with the error response */
30
+ headers?: Record<string, string>;
31
+ /** Optional delay in milliseconds before sending each failure response */
32
+ delay?: number;
33
+ }
34
+ /**
35
+ * Configuration object for setting up a route response.
36
+ */
37
+ export interface RouteConfig {
38
+ /** The path of the route (e.g., '/callback_url', '/worker_data_url.get') */
39
+ path: string;
40
+ /** The HTTP method (e.g., 'GET', 'POST', 'PUT', 'DELETE') */
41
+ method: string;
42
+ /** The HTTP status code to return (e.g., 200, 401, 500) */
43
+ status: number;
44
+ /** Optional response body to send as JSON */
45
+ body?: unknown;
46
+ /** Optional headers to send with the response */
47
+ headers?: Record<string, string>;
48
+ /** Optional retry configuration for simulating failures before success */
49
+ retry?: RetryConfig;
50
+ /** Optional delay in milliseconds before sending the response */
51
+ delay?: number;
52
+ }
53
+ /**
54
+ * Type for custom route handler functions.
55
+ */
56
+ export type RouteHandler = (req: ParsedRequest, res: MockResponse) => unknown;
57
+ /**
58
+ * Information about a request received by the mock server.
59
+ */
60
+ export interface RequestInfo {
61
+ /** The HTTP method (e.g., 'GET', 'POST') */
62
+ method: string;
63
+ /** The full URL path of the request */
64
+ url: string;
65
+ /** Optional request body (for POST/PUT requests) */
66
+ body?: unknown;
67
+ }
68
+ export type RouteHandlers = Map<string, RouteHandler>;
69
+ /**
70
+ * Type for tracking request counts per route.
71
+ */
72
+ export type RequestCounts = Map<string, number>;
73
+ //# sourceMappingURL=mock-server.interfaces.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mock-server.interfaces.d.ts","sourceRoot":"","sources":["../../src/mock-server/mock-server.interfaces.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,MAAM,CAAC;AAEvD,eAAO,MAAM,wBAAwB,OAAO,CAAC;AAE7C,MAAM,WAAW,aAAc,SAAQ,eAAe;IACpD,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,gCAAgC;IAChC,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,YAAa,SAAQ,cAAc;IAClD,yCAAyC;IACzC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,YAAY,CAAC;IACnD,+BAA+B;IAC/B,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAAC;IACnC,2BAA2B;IAC3B,IAAI,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAC1B,6BAA6B;IAC7B,IAAI,IAAI,IAAI,CAAC;CACd;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,qEAAqE;IACrE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,+DAA+D;IAC/D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mEAAmE;IACnE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,uDAAuD;IACvD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,0EAA0E;IAC1E,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,4EAA4E;IAC5E,IAAI,EAAE,MAAM,CAAC;IACb,6DAA6D;IAC7D,MAAM,EAAE,MAAM,CAAC;IACf,2DAA2D;IAC3D,MAAM,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,iDAAiD;IACjD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,0EAA0E;IAC1E,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,iEAAiE;IACjE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,GAAG,EAAE,aAAa,EAAE,GAAG,EAAE,YAAY,KAAK,OAAO,CAAC;AAE9E;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,4CAA4C;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,uCAAuC;IACvC,GAAG,EAAE,MAAM,CAAC;IACZ,oDAAoD;IACpD,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,MAAM,aAAa,GAAG,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;AAEtD;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC"}
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DEFAULT_MOCK_SERVER_PORT = void 0;
4
+ exports.DEFAULT_MOCK_SERVER_PORT = 3001;
@@ -0,0 +1,278 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MockServer = void 0;
4
+ const http_1 = require("http");
5
+ const mock_server_interfaces_1 = require("./mock-server.interfaces");
6
+ const MAX_BODY_SIZE = 10 * 1024 * 1024; // 10mb
7
+ /**
8
+ * Parses the JSON body from an incoming request.
9
+ */
10
+ async function parseJsonBody(req) {
11
+ return new Promise((resolve, reject) => {
12
+ const chunks = [];
13
+ let size = 0;
14
+ req.on('data', (chunk) => {
15
+ size += chunk.length;
16
+ if (size > MAX_BODY_SIZE) {
17
+ reject(new Error('Request body too large'));
18
+ req.destroy();
19
+ return;
20
+ }
21
+ chunks.push(chunk);
22
+ });
23
+ req.on('end', () => {
24
+ if (chunks.length === 0) {
25
+ resolve(undefined);
26
+ return;
27
+ }
28
+ try {
29
+ const raw = Buffer.concat(chunks).toString('utf-8');
30
+ resolve(JSON.parse(raw));
31
+ }
32
+ catch (_a) {
33
+ resolve(undefined);
34
+ }
35
+ });
36
+ req.on('error', reject);
37
+ });
38
+ }
39
+ /**
40
+ * Wraps a ServerResponse with helper methods (status, json, set, send).
41
+ */
42
+ function wrapResponse(res) {
43
+ const mock = res;
44
+ let statusCode = 200;
45
+ mock.set = (headers) => {
46
+ for (const [key, value] of Object.entries(headers)) {
47
+ res.setHeader(key, value);
48
+ }
49
+ return mock;
50
+ };
51
+ mock.status = (code) => {
52
+ statusCode = code;
53
+ return mock;
54
+ };
55
+ mock.json = (data) => {
56
+ res.writeHead(statusCode, { 'Content-Type': 'application/json' });
57
+ res.end(JSON.stringify(data));
58
+ };
59
+ mock.send = () => {
60
+ res.writeHead(statusCode);
61
+ res.end();
62
+ };
63
+ return mock;
64
+ }
65
+ /**
66
+ * MockServer used in tests to mock internal AirSync endpoints.
67
+ * This is a simple mock server that listens on a port and responds to requests.
68
+ * Supports per-test route configuration to simulate different response scenarios.
69
+ */
70
+ class MockServer {
71
+ constructor(port = mock_server_interfaces_1.DEFAULT_MOCK_SERVER_PORT) {
72
+ this.server = null;
73
+ this.routeHandlers = new Map();
74
+ this.requests = [];
75
+ this.requestCounts = new Map();
76
+ this.internalPort = port;
77
+ this.port = port;
78
+ this.baseUrl = `http://localhost:${this.port}`;
79
+ }
80
+ async start() {
81
+ return new Promise((resolve) => {
82
+ this.server = (0, http_1.createServer)((req, res) => {
83
+ this.handleRequest(req, res).catch(() => {
84
+ res.writeHead(500);
85
+ res.end();
86
+ });
87
+ });
88
+ this.server.listen(this.internalPort, () => {
89
+ var _a, _b;
90
+ const actualPort = (_b = (_a = this.server) === null || _a === void 0 ? void 0 : _a.address()) === null || _b === void 0 ? void 0 : _b.port;
91
+ if (actualPort) {
92
+ this.port = actualPort;
93
+ this.baseUrl = `http://localhost:${this.port}`;
94
+ }
95
+ console.log(`Mock server running on http://localhost:${this.port}.`);
96
+ resolve();
97
+ });
98
+ });
99
+ }
100
+ async stop() {
101
+ if (!this.server) {
102
+ return Promise.resolve();
103
+ }
104
+ return new Promise((resolve, reject) => {
105
+ this.server.close((err) => {
106
+ if (err) {
107
+ reject(err);
108
+ }
109
+ else {
110
+ console.log('Mock server stopped.');
111
+ this.server = null;
112
+ resolve();
113
+ }
114
+ });
115
+ });
116
+ }
117
+ async handleRequest(raw, rawRes) {
118
+ const req = raw;
119
+ const res = wrapResponse(rawRes);
120
+ const urlPath = (req.url || '/').split('?')[0];
121
+ req.path = urlPath;
122
+ req.body = await parseJsonBody(req);
123
+ const requestInfo = Object.assign({ method: req.method || 'GET', url: req.url || urlPath }, (req.body !== undefined && req.body !== null
124
+ ? { body: req.body }
125
+ : {}));
126
+ this.requests.push(requestInfo);
127
+ const method = (req.method || 'GET').toUpperCase();
128
+ const key = `${method}:${urlPath}`;
129
+ const customHandler = this.routeHandlers.get(key);
130
+ if (customHandler) {
131
+ customHandler(req, res);
132
+ }
133
+ else {
134
+ this.defaultRouteHandler(req, res);
135
+ }
136
+ }
137
+ /**
138
+ * Default route handler for the mock server. Returns { success: true } for
139
+ * routes that are not explicitly set.
140
+ */
141
+ defaultRouteHandler(req, res) {
142
+ if (req.method === 'GET' && req.path === '/worker_data_url.get') {
143
+ res.status(200).json({
144
+ state: JSON.stringify({}),
145
+ });
146
+ }
147
+ else if (req.method === 'GET' && req.path === '/internal/snap-ins.get') {
148
+ res.status(200).json({
149
+ snap_in: {
150
+ imports: [{ name: 'test_import_slug' }],
151
+ snap_in_version: { slug: 'test_snap_in_slug' },
152
+ },
153
+ });
154
+ }
155
+ else if (req.method === 'GET' &&
156
+ req.path === '/internal/airdrop.artifacts.upload-url') {
157
+ const artifactId = `artifact-${Date.now()}-${Math.random()
158
+ .toString(36)
159
+ .substr(2, 9)}`;
160
+ res.status(200).json({
161
+ upload_url: `${this.baseUrl}/file-upload-url`,
162
+ artifact_id: artifactId,
163
+ form_data: [],
164
+ });
165
+ }
166
+ else {
167
+ res.status(200).json({ success: true });
168
+ }
169
+ }
170
+ getRouteKey(method, path) {
171
+ return `${method.toUpperCase()}:${path}`;
172
+ }
173
+ /**
174
+ * Configures a route to return a specific status code and optional response body.
175
+ */
176
+ setRoute(config) {
177
+ const { path, method, status, body, retry, headers, delay } = config;
178
+ const key = this.getRouteKey(method, path);
179
+ if (retry) {
180
+ this.requestCounts.set(key, 0);
181
+ }
182
+ this.routeHandlers.set(key, (req, res) => {
183
+ const sendResponse = (responseDelay) => {
184
+ const send = () => {
185
+ var _a, _b;
186
+ if (retry) {
187
+ const currentCount = this.requestCounts.get(key) || 0;
188
+ const failureCount = (_a = retry.failureCount) !== null && _a !== void 0 ? _a : 4;
189
+ const errorStatus = (_b = retry.errorStatus) !== null && _b !== void 0 ? _b : 500;
190
+ if (currentCount < failureCount) {
191
+ this.requestCounts.set(key, currentCount + 1);
192
+ const sendFailure = () => {
193
+ if (retry.headers) {
194
+ res.set(retry.headers);
195
+ }
196
+ if (retry.errorBody !== undefined) {
197
+ res.status(errorStatus).json(retry.errorBody);
198
+ }
199
+ else {
200
+ res.status(errorStatus).send();
201
+ }
202
+ };
203
+ if (retry.delay) {
204
+ setTimeout(sendFailure, retry.delay);
205
+ }
206
+ else {
207
+ sendFailure();
208
+ }
209
+ }
210
+ else {
211
+ this.requestCounts.set(key, currentCount + 1);
212
+ if (headers) {
213
+ res.set(headers);
214
+ }
215
+ if (body !== undefined) {
216
+ res.status(status).json(body);
217
+ }
218
+ else {
219
+ this.defaultRouteHandler(req, res);
220
+ }
221
+ }
222
+ }
223
+ else {
224
+ if (headers) {
225
+ res.set(headers);
226
+ }
227
+ if (body !== undefined) {
228
+ res.status(status).json(body);
229
+ }
230
+ else {
231
+ res.status(status).send();
232
+ }
233
+ }
234
+ };
235
+ if (responseDelay) {
236
+ setTimeout(send, responseDelay);
237
+ }
238
+ else {
239
+ send();
240
+ }
241
+ };
242
+ sendResponse(delay);
243
+ });
244
+ }
245
+ /**
246
+ * Resets all custom route handlers, restoring all default handlers.
247
+ * Also clears request tracking data.
248
+ */
249
+ resetRoutes() {
250
+ this.routeHandlers.clear();
251
+ this.requestCounts.clear();
252
+ this.requests = [];
253
+ }
254
+ /**
255
+ * Returns the most recent request or undefined if no requests exist.
256
+ */
257
+ getLastRequest() {
258
+ if (this.requests.length === 0) {
259
+ return undefined;
260
+ }
261
+ return this.requests[this.requests.length - 1];
262
+ }
263
+ /**
264
+ * Gets the number of requests made to a specific endpoint.
265
+ */
266
+ getRequestCount(method, path) {
267
+ return this.getRequests(method, path).length;
268
+ }
269
+ /**
270
+ * Gets all requests made to a specific endpoint.
271
+ */
272
+ getRequests(method, path) {
273
+ const pathWithoutQuery = path.split('?')[0];
274
+ return this.requests.filter((req) => req.method.toUpperCase() === method.toUpperCase() &&
275
+ req.url.split('?')[0] === pathWithoutQuery);
276
+ }
277
+ }
278
+ exports.MockServer = MockServer;