@devrev/ts-adaas 1.19.7 → 1.19.9-beta.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.
Files changed (49) hide show
  1. package/dist/common/control-protocol.d.ts +3 -2
  2. package/dist/common/control-protocol.d.ts.map +1 -1
  3. package/dist/common/control-protocol.js +2 -4
  4. package/dist/common/control-protocol.test.d.ts +2 -0
  5. package/dist/common/control-protocol.test.d.ts.map +1 -0
  6. package/dist/common/control-protocol.test.js +126 -0
  7. package/dist/common/errors.d.ts +4 -1
  8. package/dist/common/errors.d.ts.map +1 -1
  9. package/dist/http/axios-client-internal.d.ts.map +1 -1
  10. package/dist/http/axios-client-internal.js +19 -1
  11. package/dist/mock-server/mock-server.d.ts +4 -0
  12. package/dist/mock-server/mock-server.d.ts.map +1 -1
  13. package/dist/mock-server/mock-server.interfaces.d.ts +9 -0
  14. package/dist/mock-server/mock-server.interfaces.d.ts.map +1 -1
  15. package/dist/mock-server/mock-server.js +28 -6
  16. package/dist/multithreading/spawn/spawn.d.ts +1 -1
  17. package/dist/multithreading/spawn/spawn.d.ts.map +1 -1
  18. package/dist/multithreading/spawn/spawn.js +11 -6
  19. package/dist/multithreading/spawn/spawn.test.js +1 -0
  20. package/dist/multithreading/worker-adapter/worker-adapter.artifacts.test.js +1 -1
  21. package/dist/multithreading/worker-adapter/worker-adapter.d.ts +10 -0
  22. package/dist/multithreading/worker-adapter/worker-adapter.d.ts.map +1 -1
  23. package/dist/multithreading/worker-adapter/worker-adapter.emit.test.js +90 -9
  24. package/dist/multithreading/worker-adapter/worker-adapter.extraction.test.js +1 -1
  25. package/dist/multithreading/worker-adapter/worker-adapter.js +91 -46
  26. package/dist/multithreading/worker-adapter/worker-adapter.upload-failure.test.d.ts +2 -0
  27. package/dist/multithreading/worker-adapter/worker-adapter.upload-failure.test.d.ts.map +1 -0
  28. package/dist/multithreading/worker-adapter/worker-adapter.upload-failure.test.js +135 -0
  29. package/dist/repo/repo.d.ts +11 -2
  30. package/dist/repo/repo.d.ts.map +1 -1
  31. package/dist/repo/repo.interfaces.d.ts +2 -0
  32. package/dist/repo/repo.interfaces.d.ts.map +1 -1
  33. package/dist/repo/repo.js +37 -11
  34. package/dist/repo/repo.test.js +184 -0
  35. package/dist/types/extraction.d.ts +8 -1
  36. package/dist/types/extraction.d.ts.map +1 -1
  37. package/dist/types/workers.d.ts +4 -0
  38. package/dist/types/workers.d.ts.map +1 -1
  39. package/dist/uploader/uploader.d.ts.map +1 -1
  40. package/dist/uploader/uploader.helpers.d.ts +6 -1
  41. package/dist/uploader/uploader.helpers.d.ts.map +1 -1
  42. package/dist/uploader/uploader.helpers.js +65 -0
  43. package/dist/uploader/uploader.helpers.test.js +148 -7
  44. package/dist/uploader/uploader.interfaces.d.ts +11 -0
  45. package/dist/uploader/uploader.interfaces.d.ts.map +1 -1
  46. package/dist/uploader/uploader.interfaces.js +11 -0
  47. package/dist/uploader/uploader.js +2 -5
  48. package/dist/uploader/uploader.test.js +54 -3
  49. package/package.json +1 -1
@@ -1,10 +1,11 @@
1
1
  import { AxiosResponse } from 'axios';
2
- import { AirdropEvent, EventData, ExtractorEventType } from '../types/extraction';
2
+ import { AirdropEvent, EventData, ExtractorEventType, WorkerMetadata } from '../types/extraction';
3
3
  import { LoaderEventType } from '../types/loading';
4
4
  export interface EmitInterface {
5
5
  event: AirdropEvent;
6
6
  eventType: ExtractorEventType | LoaderEventType;
7
7
  data?: EventData;
8
+ worker_metadata?: WorkerMetadata;
8
9
  }
9
- export declare const emit: ({ event, eventType, data, }: EmitInterface) => Promise<AxiosResponse>;
10
+ export declare const emit: ({ event, eventType, data, worker_metadata, }: EmitInterface) => Promise<AxiosResponse>;
10
11
  //# sourceMappingURL=control-protocol.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"control-protocol.d.ts","sourceRoot":"","sources":["../../src/common/control-protocol.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAEtC,OAAO,EACL,YAAY,EACZ,SAAS,EAET,kBAAkB,EAEnB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAInD,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,YAAY,CAAC;IACpB,SAAS,EAAE,kBAAkB,GAAG,eAAe,CAAC;IAChD,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB;AAED,eAAO,MAAM,IAAI,GAAU,6BAIxB,aAAa,KAAG,OAAO,CAAC,aAAa,CAgCvC,CAAC"}
1
+ {"version":3,"file":"control-protocol.d.ts","sourceRoot":"","sources":["../../src/common/control-protocol.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAEtC,OAAO,EACL,YAAY,EACZ,SAAS,EAET,kBAAkB,EAElB,cAAc,EACf,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAInD,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,YAAY,CAAC;IACpB,SAAS,EAAE,kBAAkB,GAAG,eAAe,CAAC;IAChD,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,eAAe,CAAC,EAAE,cAAc,CAAC;CAClC;AAED,eAAO,MAAM,IAAI,GAAU,8CAKxB,aAAa,KAAG,OAAO,CAAC,aAAa,CAmCvC,CAAC"}
@@ -4,7 +4,7 @@ exports.emit = void 0;
4
4
  const axios_client_internal_1 = require("../http/axios-client-internal");
5
5
  const constants_1 = require("./constants");
6
6
  const event_type_translation_1 = require("./event-type-translation");
7
- const emit = async ({ event, eventType, data, }) => {
7
+ const emit = async ({ event, eventType, data, worker_metadata, }) => {
8
8
  // Translate outgoing event type to ensure we always send new event types
9
9
  // TODO: Remove when the old types are completely phased out
10
10
  const translatedEventType = (0, event_type_translation_1.translateOutgoingEventType)(eventType);
@@ -12,9 +12,7 @@ const emit = async ({ event, eventType, data, }) => {
12
12
  event_type: translatedEventType,
13
13
  event_context: event.payload.event_context,
14
14
  event_data: Object.assign({}, data),
15
- worker_metadata: {
16
- adaas_library_version: constants_1.LIBRARY_VERSION,
17
- },
15
+ worker_metadata: Object.assign(Object.assign({}, worker_metadata), { newest_state_date: event.payload.event_context.extract_to, oldest_state_date: event.payload.event_context.extract_from, adaas_library_version: constants_1.LIBRARY_VERSION }),
18
16
  };
19
17
  console.info('Emitting event', newEvent);
20
18
  return axios_client_internal_1.axiosClient.post(event.payload.event_context.callback_url, Object.assign({}, newEvent), {
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=control-protocol.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"control-protocol.test.d.ts","sourceRoot":"","sources":["../../src/common/control-protocol.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,126 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const axios_client_internal_1 = require("../http/axios-client-internal");
4
+ const test_helpers_1 = require("../tests/test-helpers");
5
+ const test_utils_1 = require("./test-utils");
6
+ const control_protocol_1 = require("./control-protocol");
7
+ const extraction_1 = require("../types/extraction");
8
+ const loading_1 = require("../types/loading");
9
+ jest.mock('../http/axios-client-internal');
10
+ const mockedAxiosClient = jest.mocked(axios_client_internal_1.axiosClient);
11
+ describe('control-protocol.emit', () => {
12
+ beforeEach(() => {
13
+ jest.clearAllMocks();
14
+ mockedAxiosClient.post.mockResolvedValue((0, test_helpers_1.createAxiosResponse)());
15
+ });
16
+ it.each([
17
+ {
18
+ title: 'extractor events',
19
+ inputEventType: extraction_1.EventType.StartExtractingData,
20
+ outputEventType: extraction_1.ExtractorEventType.DataExtractionProgress,
21
+ },
22
+ {
23
+ title: 'loader events',
24
+ inputEventType: extraction_1.EventType.StartLoadingData,
25
+ outputEventType: loading_1.LoaderEventType.DataLoadingProgress,
26
+ },
27
+ {
28
+ title: 'unknown events',
29
+ inputEventType: extraction_1.EventType.StartExtractingData,
30
+ outputEventType: 'SOME_UNKNOWN_EVENT',
31
+ },
32
+ ])('sets state dates from event context for $title', async ({ inputEventType, outputEventType }) => {
33
+ const event = (0, test_utils_1.createMockEvent)(undefined, {
34
+ payload: {
35
+ event_type: inputEventType,
36
+ event_context: {
37
+ extract_from: '2024-01-01T00:00:00.000Z',
38
+ extract_to: '2024-06-01T00:00:00.000Z',
39
+ },
40
+ },
41
+ });
42
+ await (0, control_protocol_1.emit)({
43
+ event,
44
+ eventType: outputEventType,
45
+ });
46
+ expect(mockedAxiosClient.post).toHaveBeenCalledTimes(1);
47
+ const [, body, config] = mockedAxiosClient.post.mock.calls[0];
48
+ expect(body).toMatchObject({
49
+ event_type: outputEventType,
50
+ event_context: expect.objectContaining({
51
+ extract_from: '2024-01-01T00:00:00.000Z',
52
+ extract_to: '2024-06-01T00:00:00.000Z',
53
+ }),
54
+ worker_metadata: expect.objectContaining({
55
+ oldest_state_date: '2024-01-01T00:00:00.000Z',
56
+ newest_state_date: '2024-06-01T00:00:00.000Z',
57
+ }),
58
+ });
59
+ expect(config).toEqual(expect.objectContaining({
60
+ headers: expect.objectContaining({
61
+ 'X-DevRev-Client-Version': expect.any(String),
62
+ }),
63
+ }));
64
+ });
65
+ it.each([
66
+ {
67
+ title: 'only extract_from is set',
68
+ extractFrom: '2024-01-01T00:00:00.000Z',
69
+ extractTo: undefined,
70
+ },
71
+ {
72
+ title: 'only extract_to is set',
73
+ extractFrom: undefined,
74
+ extractTo: '2024-06-01T00:00:00.000Z',
75
+ },
76
+ {
77
+ title: 'neither extract_from nor extract_to is set',
78
+ extractFrom: undefined,
79
+ extractTo: undefined,
80
+ },
81
+ ])('handles state-date absence when $title', async ({ extractFrom, extractTo }) => {
82
+ const event = (0, test_utils_1.createMockEvent)(undefined, {
83
+ payload: {
84
+ event_type: extraction_1.EventType.StartExtractingData,
85
+ event_context: {
86
+ extract_from: extractFrom,
87
+ extract_to: extractTo,
88
+ },
89
+ },
90
+ });
91
+ await (0, control_protocol_1.emit)({
92
+ event,
93
+ eventType: extraction_1.ExtractorEventType.DataExtractionProgress,
94
+ });
95
+ const [, body] = mockedAxiosClient.post.mock.calls[0];
96
+ const workerMetadata = body.worker_metadata;
97
+ expect(workerMetadata.oldest_state_date).toBe(extractFrom);
98
+ expect(workerMetadata.newest_state_date).toBe(extractTo);
99
+ });
100
+ it('overrides caller-provided worker_metadata state dates', async () => {
101
+ const event = (0, test_utils_1.createMockEvent)(undefined, {
102
+ payload: {
103
+ event_type: extraction_1.EventType.StartExtractingData,
104
+ event_context: {
105
+ extract_from: '2024-01-01T00:00:00.000Z',
106
+ extract_to: '2024-06-01T00:00:00.000Z',
107
+ },
108
+ },
109
+ });
110
+ await (0, control_protocol_1.emit)({
111
+ event,
112
+ eventType: extraction_1.ExtractorEventType.DataExtractionProgress,
113
+ worker_metadata: {
114
+ item_type: 'tasks',
115
+ oldest_state_date: 'should-be-overwritten',
116
+ newest_state_date: 'should-be-overwritten',
117
+ },
118
+ });
119
+ const [, body] = mockedAxiosClient.post.mock.calls[0];
120
+ expect(body.worker_metadata).toEqual(expect.objectContaining({
121
+ item_type: 'tasks',
122
+ oldest_state_date: '2024-01-01T00:00:00.000Z',
123
+ newest_state_date: '2024-06-01T00:00:00.000Z',
124
+ }));
125
+ });
126
+ });
@@ -1,6 +1,9 @@
1
1
  export declare const enum ExtractionCommonError {
2
2
  EXTERNAL_SYNC_UNIT_DELETED = "ERROR_CODE=EXTERNAL_SYNC_UNIT_DELETED",
3
3
  EXTERNAL_SYNC_UNIT_DEACTIVATED = "ERROR_CODE=EXTERNAL_SYNC_UNIT_DEACTIVATED",
4
- USER_DELETED = "ERROR_CODE=USER_DELETED"
4
+ USER_DELETED = "ERROR_CODE=USER_DELETED",
5
+ EXTERNAL_SYSTEM_NO_ACCESS = "ERROR_CODE=EXTERNAL_SYSTEM_NO_ACCESS",
6
+ EXTERNAL_SYSTEM_NO_PERMISSION = "ERROR_CODE=EXTERNAL_SYSTEM_NO_PERMISSION",
7
+ HISTORICAL_DATA_EXTRACTION_DONE = "ERROR_CODE=HISTORICAL_DATA_EXTRACTION_DONE"
5
8
  }
6
9
  //# sourceMappingURL=errors.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/common/errors.ts"],"names":[],"mappings":"AAGA,0BAAkB,qBAAqB;IACrC,0BAA0B,0CAAgE;IAC1F,8BAA8B,8CAAoE;IAClG,YAAY,4BAAkD;CAC/D"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/common/errors.ts"],"names":[],"mappings":"AAGA,0BAAkB,qBAAqB;IAIrC,0BAA0B,0CAAgE;IAC1F,8BAA8B,8CAAoE;IAClG,YAAY,4BAAkD;IAG9D,yBAAyB,yCAA+D;IAExF,6BAA6B,6CAAmE;IAEhG,+BAA+B,+CAAqE;CACrG"}
@@ -1 +1 @@
1
- {"version":3,"file":"axios-client-internal.d.ts","sourceRoot":"","sources":["../../src/http/axios-client-internal.ts"],"names":[],"mappings":"AAGA,QAAA,MAAM,WAAW,+BAEf,CAAC;AAyFH,OAAO,EAAE,WAAW,EAAE,CAAC"}
1
+ {"version":3,"file":"axios-client-internal.d.ts","sourceRoot":"","sources":["../../src/http/axios-client-internal.ts"],"names":[],"mappings":"AAwBA,QAAA,MAAM,WAAW,+BAEf,CAAC;AAyFH,OAAO,EAAE,WAAW,EAAE,CAAC"}
@@ -6,12 +6,30 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.axiosClient = void 0;
7
7
  const axios_1 = __importDefault(require("axios"));
8
8
  const axios_retry_1 = __importDefault(require("axios-retry"));
9
+ const node_worker_threads_1 = require("node:worker_threads");
10
+ /** Production default; tests may lower via workerData.options.httpRetries or ADAAS_TEST_HTTP_RETRIES. */
11
+ function getHttpRetryCount() {
12
+ var _a;
13
+ if (!node_worker_threads_1.isMainThread &&
14
+ ((_a = node_worker_threads_1.workerData === null || node_worker_threads_1.workerData === void 0 ? void 0 : node_worker_threads_1.workerData.options) === null || _a === void 0 ? void 0 : _a.httpRetries) !== undefined &&
15
+ node_worker_threads_1.workerData.options.httpRetries >= 0) {
16
+ return node_worker_threads_1.workerData.options.httpRetries;
17
+ }
18
+ const fromEnv = process.env.ADAAS_TEST_HTTP_RETRIES;
19
+ if (fromEnv !== undefined) {
20
+ const parsed = parseInt(fromEnv, 10);
21
+ if (!isNaN(parsed) && parsed >= 0) {
22
+ return parsed;
23
+ }
24
+ }
25
+ return 5;
26
+ }
9
27
  const axiosClient = axios_1.default.create({
10
28
  timeout: 30 * 1000,
11
29
  });
12
30
  exports.axiosClient = axiosClient;
13
31
  (0, axios_retry_1.default)(axiosClient, {
14
- retries: 5,
32
+ retries: getHttpRetryCount(),
15
33
  shouldResetTimeout: true,
16
34
  retryDelay: (retryCount, error) => {
17
35
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
@@ -31,6 +31,10 @@ export declare class MockServer {
31
31
  * Also clears request tracking data.
32
32
  */
33
33
  resetRoutes(): void;
34
+ /**
35
+ * Returns all POST requests to the platform callback URL.
36
+ */
37
+ getCallbackRequests(): RequestInfo[];
34
38
  /**
35
39
  * Returns the most recent request or undefined if no requests exist.
36
40
  */
@@ -1 +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"}
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;IAwF1C;;;OAGG;IACI,WAAW,IAAI,IAAI;IAM1B;;OAEG;IACI,mBAAmB,IAAI,WAAW,EAAE;IAO3C;;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"}
@@ -47,6 +47,15 @@ export interface RouteConfig {
47
47
  headers?: Record<string, string>;
48
48
  /** Optional retry configuration for simulating failures before success */
49
49
  retry?: RetryConfig;
50
+ /**
51
+ * Respond successfully for the first N requests, then return an error.
52
+ * Useful for partial-upload scenarios (first batch succeeds, second fails).
53
+ */
54
+ succeedThenFail?: {
55
+ successCount: number;
56
+ errorStatus?: number;
57
+ errorBody?: unknown;
58
+ };
50
59
  /** Optional delay in milliseconds before sending the response */
51
60
  delay?: number;
52
61
  }
@@ -1 +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"}
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;;;OAGG;IACH,eAAe,CAAC,EAAE;QAChB,YAAY,EAAE,MAAM,CAAC;QACrB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,SAAS,CAAC,EAAE,OAAO,CAAC;KACrB,CAAC;IACF,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"}
@@ -174,19 +174,35 @@ class MockServer {
174
174
  * Configures a route to return a specific status code and optional response body.
175
175
  */
176
176
  setRoute(config) {
177
- const { path, method, status, body, retry, headers, delay } = config;
177
+ const { path, method, status, body, retry, succeedThenFail, headers, delay } = config;
178
178
  const key = this.getRouteKey(method, path);
179
- if (retry) {
179
+ if (retry || succeedThenFail) {
180
180
  this.requestCounts.set(key, 0);
181
181
  }
182
182
  this.routeHandlers.set(key, (req, res) => {
183
183
  const sendResponse = (responseDelay) => {
184
184
  const send = () => {
185
- var _a, _b;
186
- if (retry) {
185
+ var _a, _b, _c;
186
+ if (succeedThenFail) {
187
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;
188
+ this.requestCounts.set(key, currentCount + 1);
189
+ if (currentCount < succeedThenFail.successCount) {
190
+ this.defaultRouteHandler(req, res);
191
+ }
192
+ else {
193
+ const errorStatus = (_a = succeedThenFail.errorStatus) !== null && _a !== void 0 ? _a : 400;
194
+ if (succeedThenFail.errorBody !== undefined) {
195
+ res.status(errorStatus).json(succeedThenFail.errorBody);
196
+ }
197
+ else {
198
+ res.status(errorStatus).send();
199
+ }
200
+ }
201
+ }
202
+ else if (retry) {
203
+ const currentCount = this.requestCounts.get(key) || 0;
204
+ const failureCount = (_b = retry.failureCount) !== null && _b !== void 0 ? _b : 4;
205
+ const errorStatus = (_c = retry.errorStatus) !== null && _c !== void 0 ? _c : 500;
190
206
  if (currentCount < failureCount) {
191
207
  this.requestCounts.set(key, currentCount + 1);
192
208
  const sendFailure = () => {
@@ -251,6 +267,12 @@ class MockServer {
251
267
  this.requestCounts.clear();
252
268
  this.requests = [];
253
269
  }
270
+ /**
271
+ * Returns all POST requests to the platform callback URL.
272
+ */
273
+ getCallbackRequests() {
274
+ return this.requests.filter((req) => req.method.toUpperCase() === 'POST' && req.url.includes('callback_url'));
275
+ }
254
276
  /**
255
277
  * Returns the most recent request or undefined if no requests exist.
256
278
  */
@@ -25,7 +25,7 @@ export declare class Spawn {
25
25
  private originalConsole;
26
26
  private logger;
27
27
  private workerFailedMessage;
28
- constructor({ event, worker, options, resolve, originalConsole, }: SpawnInterface);
28
+ constructor({ event, worker, options, resolve, originalConsole, logger, }: SpawnInterface);
29
29
  private clearTimeouts;
30
30
  private exitFromMainThread;
31
31
  }
@@ -1 +1 @@
1
- {"version":3,"file":"spawn.d.ts","sourceRoot":"","sources":["../../../src/multithreading/spawn/spawn.ts"],"names":[],"mappings":"AAQA,OAAO,EAEL,qBAAqB,EACrB,cAAc,EAGf,MAAM,qBAAqB,CAAC;AA+C7B;;;;;;;;;;;GAWG;AACH,wBAAsB,KAAK,CAAC,cAAc,EAAE,EAC1C,KAAK,EACL,YAAY,EACZ,UAAU,EACV,oBAAoB,EACpB,OAAO,EACP,cAAc,GACf,EAAE,qBAAqB,CAAC,cAAc,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAwFvD;AAED,qBAAa,KAAK;IAChB,OAAO,CAAC,KAAK,CAAe;IAC5B,OAAO,CAAC,cAAc,CAAU;IAChC,OAAO,CAAC,eAAe,CAAU;IACjC,OAAO,CAAC,oBAAoB,CAAkC;IAC9D,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,gBAAgB,CAA4C;IACpE,OAAO,CAAC,gBAAgB,CAA4C;IACpE,OAAO,CAAC,wBAAwB,CAA6C;IAC7E,OAAO,CAAC,OAAO,CAA4C;IAC3D,OAAO,CAAC,eAAe,CAAU;IACjC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,mBAAmB,CAAqB;gBACpC,EACV,KAAK,EACL,MAAM,EACN,OAAO,EACP,OAAO,EACP,eAAe,GAChB,EAAE,cAAc;IAiHjB,OAAO,CAAC,aAAa;YAYP,kBAAkB;CAoCjC"}
1
+ {"version":3,"file":"spawn.d.ts","sourceRoot":"","sources":["../../../src/multithreading/spawn/spawn.ts"],"names":[],"mappings":"AASA,OAAO,EAEL,qBAAqB,EACrB,cAAc,EAGf,MAAM,qBAAqB,CAAC;AA+C7B;;;;;;;;;;;GAWG;AACH,wBAAsB,KAAK,CAAC,cAAc,EAAE,EAC1C,KAAK,EACL,YAAY,EACZ,UAAU,EACV,oBAAoB,EACpB,OAAO,EACP,cAAc,GACf,EAAE,qBAAqB,CAAC,cAAc,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CA0FvD;AAED,qBAAa,KAAK;IAChB,OAAO,CAAC,KAAK,CAAe;IAC5B,OAAO,CAAC,cAAc,CAAU;IAChC,OAAO,CAAC,eAAe,CAAU;IACjC,OAAO,CAAC,oBAAoB,CAAkC;IAC9D,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,gBAAgB,CAA4C;IACpE,OAAO,CAAC,gBAAgB,CAA4C;IACpE,OAAO,CAAC,wBAAwB,CAA6C;IAC7E,OAAO,CAAC,OAAO,CAA4C;IAC3D,OAAO,CAAC,eAAe,CAAU;IACjC,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,mBAAmB,CAAqB;gBACpC,EACV,KAAK,EACL,MAAM,EACN,OAAO,EACP,OAAO,EACP,eAAe,EACf,MAAM,GACP,EAAE,cAAc;IAoHjB,OAAO,CAAC,aAAa;YAYP,kBAAkB;CAoCjC"}
@@ -68,8 +68,9 @@ async function spawn({ event, initialState, workerPath, initialDomainMapping, op
68
68
  options = Object.assign(Object.assign({}, (options || {})), { isLocalDevelopment: true });
69
69
  }
70
70
  const originalConsole = console;
71
+ const logger = new logger_1.Logger({ event, options });
71
72
  // eslint-disable-next-line no-global-assign
72
- console = new logger_1.Logger({ event, options });
73
+ console = logger;
73
74
  if (translatedEventType !== originalEventType) {
74
75
  console.log(`Event type translated from ${originalEventType} to ${translatedEventType}.`);
75
76
  }
@@ -110,6 +111,7 @@ async function spawn({ event, initialState, workerPath, initialDomainMapping, op
110
111
  options,
111
112
  resolve,
112
113
  originalConsole,
114
+ logger,
113
115
  });
114
116
  });
115
117
  }
@@ -132,10 +134,11 @@ async function spawn({ event, initialState, workerPath, initialDomainMapping, op
132
134
  }
133
135
  }
134
136
  class Spawn {
135
- constructor({ event, worker, options, resolve, originalConsole, }) {
137
+ constructor({ event, worker, options, resolve, originalConsole, logger, }) {
136
138
  this.defaultLambdaTimeout = constants_1.DEFAULT_LAMBDA_TIMEOUT;
137
139
  this.originalConsole = originalConsole || console;
138
- this.logger = console;
140
+ this.logger =
141
+ logger !== null && logger !== void 0 ? logger : console;
139
142
  this.alreadyEmitted = false;
140
143
  this.softTimeoutSent = false;
141
144
  this.event = event;
@@ -189,7 +192,7 @@ class Spawn {
189
192
  }
190
193
  });
191
194
  worker.on(workers_1.WorkerEvent.WorkerMessage, (message) => {
192
- var _a, _b, _c, _d, _e;
195
+ var _a, _b, _c, _d, _e, _f;
193
196
  // Since logs from the worker thread are handled differently in snap-in
194
197
  // platform, we need to catch the log messages from worker thread and log
195
198
  // them in main thread.
@@ -197,7 +200,9 @@ class Spawn {
197
200
  const stringifiedArgs = (_a = message.payload) === null || _a === void 0 ? void 0 : _a.stringifiedArgs;
198
201
  const level = (_b = message.payload) === null || _b === void 0 ? void 0 : _b.level;
199
202
  const isSdkLog = (_d = (_c = message.payload) === null || _c === void 0 ? void 0 : _c.isSdkLog) !== null && _d !== void 0 ? _d : true;
200
- this.logger.logFn(stringifiedArgs, level, isSdkLog);
203
+ if (typeof ((_e = this.logger) === null || _e === void 0 ? void 0 : _e.logFn) === 'function') {
204
+ this.logger.logFn(stringifiedArgs, level, isSdkLog);
205
+ }
201
206
  }
202
207
  // If worker sends a message that it has emitted an event, then set alreadyEmitted to true.
203
208
  if ((message === null || message === void 0 ? void 0 : message.subject) === workers_1.WorkerMessageSubject.WorkerMessageEmitted) {
@@ -206,7 +211,7 @@ class Spawn {
206
211
  }
207
212
  // If worker sends a failure message before exiting, capture it for use in the error event.
208
213
  if ((message === null || message === void 0 ? void 0 : message.subject) === workers_1.WorkerMessageSubject.WorkerMessageFailed) {
209
- this.workerFailedMessage = (_e = message.payload) === null || _e === void 0 ? void 0 : _e.message;
214
+ this.workerFailedMessage = (_f = message.payload) === null || _f === void 0 ? void 0 : _f.message;
210
215
  }
211
216
  });
212
217
  // Log memory usage every 30 seconds
@@ -78,6 +78,7 @@ function buildSpawn(overrides) {
78
78
  options: overrides.options,
79
79
  resolve: (_a = overrides.resolve) !== null && _a !== void 0 ? _a : jest.fn(),
80
80
  originalConsole: originalConsole,
81
+ logger: mockLogger,
81
82
  });
82
83
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
83
84
  global.console = originalConsole;
@@ -1,10 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const constants_1 = require("../../common/constants");
4
+ const test_utils_1 = require("../../common/test-utils");
4
5
  const state_1 = require("../../state/state");
5
6
  const jest_setup_1 = require("../../tests/jest.setup");
6
7
  const test_helpers_1 = require("../../tests/test-helpers");
7
- const test_utils_1 = require("../../common/test-utils");
8
8
  const types_1 = require("../../types");
9
9
  const worker_adapter_1 = require("./worker-adapter");
10
10
  // 1. Create a mock function for the method you want to override.
@@ -30,6 +30,7 @@ export declare class WorkerAdapter<ConnectorState> {
30
30
  private adapterState;
31
31
  private _artifacts;
32
32
  private repos;
33
+ private lastExtractedItemType?;
33
34
  private currentEventDataLength;
34
35
  private loaderReports;
35
36
  private _processedFiles;
@@ -60,6 +61,15 @@ export declare class WorkerAdapter<ConnectorState> {
60
61
  */
61
62
  emit(newEventType: ExtractorEventType | LoaderEventType, data?: EventData): Promise<void>;
62
63
  uploadAllRepos(): Promise<void>;
64
+ /**
65
+ * Persists adapter state before emitting, except for stateless worker phases.
66
+ */
67
+ private postStateBeforeEmit;
68
+ /**
69
+ * Posts state (when required), emits to the platform, and notifies the parent
70
+ * worker that an event was emitted.
71
+ */
72
+ private emitToPlatform;
63
73
  loadItemTypes({ itemTypesToLoad, }: ItemTypesToLoadParams): Promise<LoadItemTypesResponse>;
64
74
  getLoaderBatches({ supportedItemTypes, }: {
65
75
  supportedItemTypes: string[];
@@ -1 +1 @@
1
- {"version":3,"file":"worker-adapter.d.ts","sourceRoot":"","sources":["../../../src/multithreading/worker-adapter/worker-adapter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"worker-adapter.d.ts","sourceRoot":"","sources":["../../../src/multithreading/worker-adapter/worker-adapter.ts"],"names":[],"mappings":"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"}
@@ -43,6 +43,7 @@ function makeAdapter(eventType = types_1.EventType.StartExtractingData) {
43
43
  const adapter = new worker_adapter_1.WorkerAdapter({ event, adapterState });
44
44
  return { adapter, event, adapterState };
45
45
  }
46
+ const iso = (ms) => new Date(ms).toISOString();
46
47
  describe(`${worker_adapter_1.WorkerAdapter.name}.emit`, () => {
47
48
  let adapter;
48
49
  let mockPostMessage;
@@ -113,19 +114,25 @@ describe(`${worker_adapter_1.WorkerAdapter.name}.emit`, () => {
113
114
  // Assert
114
115
  expect(mockPostMessage).toHaveBeenCalledTimes(1);
115
116
  });
116
- it('should correctly emit one event even if uploadAllRepos errors', async () => {
117
- // Arrange
117
+ it('should emit phase extraction error when uploadAllRepos fails', async () => {
118
+ const { emit: mockEmit } = require('../../common/control-protocol');
118
119
  adapter['adapterState'].postState = jest.fn().mockResolvedValue(undefined);
119
120
  adapter.uploadAllRepos = jest
120
121
  .fn()
121
122
  .mockRejectedValue(new Error('uploadAllRepos error'));
122
- // Act
123
- await adapter.emit(types_1.ExtractorEventType.MetadataExtractionError, {
124
- reports: [],
125
- processed_files: [],
126
- });
127
- // Assert
128
- expect(mockPostMessage).toHaveBeenCalledTimes(1);
123
+ await adapter.emit(types_1.ExtractorEventType.DataExtractionDone);
124
+ expect(mockEmit).toHaveBeenCalledWith(expect.objectContaining({
125
+ eventType: types_1.ExtractorEventType.DataExtractionError,
126
+ data: expect.objectContaining({
127
+ error: expect.objectContaining({
128
+ message: expect.stringContaining('uploadAllRepos error'),
129
+ }),
130
+ }),
131
+ }));
132
+ expect(mockPostMessage).toHaveBeenCalledWith(expect.objectContaining({
133
+ subject: 'emit',
134
+ payload: { eventType: types_1.ExtractorEventType.DataExtractionError },
135
+ }));
129
136
  });
130
137
  it('should include artifacts in data for extraction events', async () => {
131
138
  // Arrange
@@ -262,6 +269,80 @@ describe(`${worker_adapter_1.WorkerAdapter.name}.emit`, () => {
262
269
  expect(emittedMessage.startsWith('E'.repeat(100))).toBe(true);
263
270
  });
264
271
  });
272
+ describe(`${worker_adapter_1.WorkerAdapter.name}.emit — worker_metadata`, () => {
273
+ let adapter;
274
+ beforeEach(() => {
275
+ jest.clearAllMocks();
276
+ ({ adapter } = makeAdapter());
277
+ adapter['adapterState'].postState = jest.fn().mockResolvedValue(undefined);
278
+ adapter.uploadAllRepos = jest.fn().mockResolvedValue(undefined);
279
+ });
280
+ function setupRepos(adapterInstance, lastExtractedItemType) {
281
+ adapterInstance['repos'] = [
282
+ {
283
+ itemType: 'issues',
284
+ dateRanges: {
285
+ creationDate: { oldest: 100, newest: 200 },
286
+ modifiedDate: { oldest: 150, newest: 250 },
287
+ },
288
+ },
289
+ {
290
+ itemType: 'tasks',
291
+ dateRanges: {
292
+ creationDate: { oldest: 300, newest: 400 },
293
+ modifiedDate: { oldest: 350, newest: 450 },
294
+ },
295
+ },
296
+ ];
297
+ adapterInstance['lastExtractedItemType'] = lastExtractedItemType;
298
+ }
299
+ it('should emit flat worker_metadata for the latest extracted item type only', async () => {
300
+ setupRepos(adapter, 'tasks');
301
+ await adapter.emit(types_1.ExtractorEventType.DataExtractionProgress);
302
+ const { emit: mockEmit } = require('../../common/control-protocol');
303
+ expect(mockEmit.mock.calls[0][0].worker_metadata).toEqual({
304
+ item_type: 'tasks',
305
+ oldest_created_date: iso(300),
306
+ newest_created_date: iso(400),
307
+ oldest_modified_date: iso(350),
308
+ newest_modified_date: iso(450),
309
+ });
310
+ });
311
+ it('should omit unset RFC3339 bounds from worker_metadata', async () => {
312
+ adapter['repos'] = [
313
+ {
314
+ itemType: 'tasks',
315
+ dateRanges: {
316
+ creationDate: { oldest: 0, newest: 0 },
317
+ modifiedDate: { oldest: 0, newest: 0 },
318
+ },
319
+ },
320
+ ];
321
+ adapter['lastExtractedItemType'] = 'tasks';
322
+ await adapter.emit(types_1.ExtractorEventType.DataExtractionProgress);
323
+ const { emit: mockEmit } = require('../../common/control-protocol');
324
+ expect(mockEmit.mock.calls[0][0].worker_metadata).toEqual({
325
+ item_type: 'tasks',
326
+ });
327
+ });
328
+ it('should send empty worker_metadata when no item type has been extracted', async () => {
329
+ await adapter.emit(types_1.ExtractorEventType.DataExtractionProgress);
330
+ const { emit: mockEmit } = require('../../common/control-protocol');
331
+ expect(mockEmit.mock.calls[0][0].worker_metadata).toEqual({});
332
+ });
333
+ it('should send empty worker_metadata for loader events', async () => {
334
+ setupRepos(adapter, 'tasks');
335
+ await adapter.emit(types_1.LoaderEventType.DataLoadingProgress);
336
+ const { emit: mockEmit } = require('../../common/control-protocol');
337
+ expect(mockEmit.mock.calls[0][0].worker_metadata).toEqual({});
338
+ });
339
+ it('should send empty worker_metadata for non-progress extraction events', async () => {
340
+ setupRepos(adapter, 'tasks');
341
+ await adapter.emit(types_1.ExtractorEventType.DataExtractionError);
342
+ const { emit: mockEmit } = require('../../common/control-protocol');
343
+ expect(mockEmit.mock.calls[0][0].worker_metadata).toEqual({});
344
+ });
345
+ });
265
346
  describe(`${worker_adapter_1.WorkerAdapter.name}.emit — ExternalSyncUnitExtractionDone legacy path`, () => {
266
347
  it('should upload ESUs via a repo and strip external_sync_units from the emitted payload', async () => {
267
348
  // Arrange
@@ -1,9 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const attachments_streaming_pool_1 = require("../../attachments-streaming/attachments-streaming-pool");
4
+ const test_utils_1 = require("../../common/test-utils");
4
5
  const state_1 = require("../../state/state");
5
6
  const jest_setup_1 = require("../../tests/jest.setup");
6
- const test_utils_1 = require("../../common/test-utils");
7
7
  const types_1 = require("../../types");
8
8
  const worker_adapter_1 = require("./worker-adapter");
9
9
  /* eslint-disable @typescript-eslint/no-require-imports */