@devrev/ts-adaas 1.9.0-beta.0 → 1.9.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 (41) hide show
  1. package/dist/attachments-streaming/attachments-streaming-pool.test.js +33 -40
  2. package/dist/common/constants.d.ts +6 -1
  3. package/dist/common/constants.js +20 -9
  4. package/dist/common/control-protocol.js +2 -2
  5. package/dist/common/helpers.test.js +29 -29
  6. package/dist/common/install-initial-domain-mapping.js +4 -4
  7. package/dist/common/install-initial-domain-mapping.test.js +17 -27
  8. package/dist/deprecated/uploader/index.js +2 -2
  9. package/dist/http/axios-client-internal.d.ts +2 -0
  10. package/dist/http/axios-client-internal.js +60 -0
  11. package/dist/http/axios-client-internal.test.d.ts +1 -0
  12. package/dist/http/axios-client-internal.test.js +189 -0
  13. package/dist/logger/logger.js +1 -1
  14. package/dist/logger/logger.test.js +12 -12
  15. package/dist/mappers/mappers.js +4 -4
  16. package/dist/repo/repo.test.js +51 -37
  17. package/dist/state/state.d.ts +12 -8
  18. package/dist/state/state.interfaces.d.ts +18 -0
  19. package/dist/state/state.interfaces.js +19 -0
  20. package/dist/state/state.js +85 -67
  21. package/dist/state/state.test.d.ts +1 -0
  22. package/dist/state/state.test.js +223 -0
  23. package/dist/tests/test-helpers.js +8 -0
  24. package/dist/tests/timeout-handling/timeout-1.test.js +1 -1
  25. package/dist/tests/timeout-handling/timeout-2.test.js +1 -1
  26. package/dist/tests/timeout-handling/timeout-3a.test.js +1 -1
  27. package/dist/tests/timeout-handling/timeout-3b.test.js +1 -1
  28. package/dist/types/common.d.ts +11 -0
  29. package/dist/types/common.js +13 -1
  30. package/dist/types/extraction.d.ts +32 -9
  31. package/dist/types/extraction.js +1 -11
  32. package/dist/types/extraction.test.js +51 -5
  33. package/dist/types/index.d.ts +2 -2
  34. package/dist/types/index.js +2 -2
  35. package/dist/uploader/uploader.js +7 -7
  36. package/dist/uploader/uploader.test.js +18 -21
  37. package/dist/workers/create-worker.test.js +64 -2
  38. package/dist/workers/default-workers/attachments-extraction.js +7 -3
  39. package/dist/workers/worker-adapter.js +10 -3
  40. package/dist/workers/worker-adapter.test.js +140 -71
  41. package/package.json +3 -2
@@ -0,0 +1,189 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const axios_mock_adapter_1 = __importDefault(require("axios-mock-adapter"));
7
+ const axios_client_internal_1 = require("./axios-client-internal");
8
+ describe('Internal Axios Client', () => {
9
+ let mockAdapter;
10
+ beforeEach(() => {
11
+ jest.clearAllMocks();
12
+ jest.spyOn(console, 'warn').mockImplementation(() => { });
13
+ mockAdapter = new axios_mock_adapter_1.default(axios_client_internal_1.axiosClient);
14
+ });
15
+ afterEach(() => {
16
+ jest.restoreAllMocks();
17
+ mockAdapter.restore();
18
+ });
19
+ it('should not retry on 200 response', async () => {
20
+ // Arrange
21
+ const testUrl = '/test-endpoint';
22
+ const responseData = { id: 1, title: 'test title' };
23
+ mockAdapter.onGet(testUrl).reply(200, responseData);
24
+ // Act
25
+ await axios_client_internal_1.axiosClient.get(testUrl);
26
+ // Assert
27
+ expect(mockAdapter.history.get).toHaveLength(1);
28
+ });
29
+ it('should not retry when response is 400', async () => {
30
+ // Arrange
31
+ const testUrl = '/test-endpoint';
32
+ const errorData = { error: 'Bad Request' };
33
+ mockAdapter.onGet(testUrl).reply(400, errorData);
34
+ // Act
35
+ await expect(axios_client_internal_1.axiosClient.get(testUrl)).rejects.toMatchObject({
36
+ response: { status: 400 },
37
+ });
38
+ // Assert
39
+ expect(mockAdapter.history.get).toHaveLength(1);
40
+ });
41
+ // TODO: This test is working as expected, but it takes too long to run. Not
42
+ // sure if it is good idea to have it.
43
+ // it('should retry on 500 response', async () => {
44
+ // // Arrange
45
+ // const testUrl = '/test-endpoint';
46
+ // mockAdapter.onGet(testUrl).reply(500);
47
+ // // Act & Assert
48
+ // await expect(axiosClient.get(testUrl)).rejects.toMatchObject({
49
+ // response: { status: 500 },
50
+ // });
51
+ // // Assert
52
+ // expect(mockAdapter.history.get).toHaveLength(6);
53
+ // }, 100000);
54
+ it('should retry 2 times when response is 500 and then succeed third time when response is 200', async () => {
55
+ // Arrange
56
+ const testUrl = '/test-endpoint';
57
+ const successData = { message: 'success after 2 retries' };
58
+ mockAdapter
59
+ .onGet(testUrl)
60
+ .replyOnce(500)
61
+ .onGet(testUrl)
62
+ .replyOnce(500)
63
+ .onGet(testUrl)
64
+ .reply(200, successData);
65
+ // Act
66
+ const response = await axios_client_internal_1.axiosClient.get(testUrl);
67
+ // Assert
68
+ expect(response.status).toBe(200);
69
+ expect(response.data).toEqual(successData);
70
+ expect(mockAdapter.history.get).toHaveLength(3); // 1 initial + 2 retries
71
+ }, 10000); // Allow time for 2 retries
72
+ it('should retry once after 2 seconds when response is 429 and Retry-After header is valid value', async () => {
73
+ // Arrange
74
+ const testUrl = '/test-endpoint';
75
+ const errorData = { error: 'Too Many Requests' };
76
+ const successData = { message: 'success after rate limit retry' };
77
+ mockAdapter
78
+ .onGet(testUrl)
79
+ .replyOnce(429, errorData, {
80
+ 'Retry-After': '2',
81
+ })
82
+ .onGet(testUrl)
83
+ .reply(200, successData);
84
+ // Act
85
+ const response = await axios_client_internal_1.axiosClient.get(testUrl);
86
+ // Assert
87
+ expect(response.status).toBe(200);
88
+ expect(response.data).toEqual(successData);
89
+ expect(mockAdapter.history.get).toHaveLength(2); // 1 initial + 1 retry
90
+ });
91
+ it('should retry once after 2 seconds and measure time between retries when response is 429 and Retry-After header is valid value', async () => {
92
+ // Arrange
93
+ const testUrl = '/test-endpoint';
94
+ const errorData = { error: 'Too Many Requests' };
95
+ const successData = { message: 'success after rate limit retry' };
96
+ const retryAfterSeconds = 2;
97
+ mockAdapter
98
+ .onGet(testUrl)
99
+ .replyOnce(429, errorData, {
100
+ 'Retry-After': retryAfterSeconds.toString(),
101
+ })
102
+ .onGet(testUrl)
103
+ .reply(200, successData);
104
+ // Act
105
+ const startTime = Date.now();
106
+ const response = await axios_client_internal_1.axiosClient.get(testUrl);
107
+ const endTime = Date.now();
108
+ const actualWaitTime = endTime - startTime;
109
+ // Assert
110
+ expect(response.status).toBe(200);
111
+ expect(response.data).toEqual(successData);
112
+ expect(mockAdapter.history.get).toHaveLength(2); // 1 initial + 1 retry
113
+ const expectedWaitTime = retryAfterSeconds * 1000;
114
+ expect(actualWaitTime).toBeGreaterThanOrEqual(expectedWaitTime - 100);
115
+ expect(actualWaitTime).toBeLessThan(expectedWaitTime + 1000); // Allow up to 1s extra for processing
116
+ });
117
+ it('should retry when response is 429 and Retry-After header is lowercase', async () => {
118
+ // Arrange
119
+ const testUrl = '/test-endpoint';
120
+ const errorData = { error: 'Too Many Requests' };
121
+ const successData = { message: 'success after rate limit retry' };
122
+ mockAdapter
123
+ .onGet(testUrl)
124
+ .replyOnce(429, errorData, { 'retry-after': '2' })
125
+ .onGet(testUrl)
126
+ .reply(200, successData);
127
+ // Act
128
+ const response = await axios_client_internal_1.axiosClient.get(testUrl);
129
+ // Assert
130
+ expect(response.status).toBe(200);
131
+ expect(response.data).toEqual(successData);
132
+ expect(mockAdapter.history.get).toHaveLength(2); // 1 initial + 1 retry
133
+ });
134
+ it('[edge] should not retry when response is 429 and there is no Retry-After header', async () => {
135
+ // Arrange
136
+ const testUrl = '/test-endpoint';
137
+ const errorData = { error: 'Too Many Requests' };
138
+ mockAdapter.onGet(testUrl).reply(429, errorData);
139
+ // Act
140
+ await expect(axios_client_internal_1.axiosClient.get(testUrl)).rejects.toMatchObject({
141
+ response: { status: 429 },
142
+ });
143
+ // Assert
144
+ expect(mockAdapter.history.get).toHaveLength(1);
145
+ });
146
+ it('[edge] should retry when response is 429 and Retry-After header is 0', async () => {
147
+ // Arrange
148
+ const testUrl = '/test-endpoint';
149
+ const errorData = { error: 'Too Many Requests' };
150
+ const successData = { message: 'success after rate limit retry' };
151
+ mockAdapter
152
+ .onGet(testUrl)
153
+ .replyOnce(429, errorData, { 'Retry-After': '0' })
154
+ .onGet(testUrl)
155
+ .reply(200, successData);
156
+ // Act
157
+ const response = await axios_client_internal_1.axiosClient.get(testUrl);
158
+ // Assert
159
+ expect(response.status).toBe(200);
160
+ expect(response.data).toEqual(successData);
161
+ expect(mockAdapter.history.get).toHaveLength(2); // 1 initial + 1 retry
162
+ });
163
+ it('[edge] should not retry when response is 429 and Retry-After header is negative', async () => {
164
+ // Arrange
165
+ const testUrl = '/test-endpoint';
166
+ const errorData = { error: 'Too Many Requests' };
167
+ mockAdapter.onGet(testUrl).reply(429, errorData, { 'Retry-After': '-1' });
168
+ // Act
169
+ await expect(axios_client_internal_1.axiosClient.get(testUrl)).rejects.toMatchObject({
170
+ response: { status: 429 },
171
+ });
172
+ // Assert
173
+ expect(mockAdapter.history.get).toHaveLength(1);
174
+ });
175
+ it('[edge] should not retry when response is 429 and Retry-After header is invalid value', async () => {
176
+ // Arrange
177
+ const testUrl = '/test-endpoint';
178
+ const errorData = { error: 'Too Many Requests' };
179
+ mockAdapter
180
+ .onGet(testUrl)
181
+ .reply(429, errorData, { 'Retry-After': 'invalid' });
182
+ // Act
183
+ await expect(axios_client_internal_1.axiosClient.get(testUrl)).rejects.toMatchObject({
184
+ response: { status: 429 },
185
+ });
186
+ // Assert
187
+ expect(mockAdapter.history.get).toHaveLength(1);
188
+ });
189
+ });
@@ -14,7 +14,7 @@ class Logger extends node_console_1.Console {
14
14
  constructor({ event, options }) {
15
15
  super(process.stdout, process.stderr);
16
16
  this.options = options;
17
- this.tags = Object.assign(Object.assign({}, event.payload.event_context), { dev_oid: event.payload.event_context.dev_org });
17
+ this.tags = Object.assign(Object.assign({}, event.payload.event_context), { dev_oid: event.payload.event_context.dev_oid });
18
18
  }
19
19
  valueToString(value) {
20
20
  if (typeof value === 'string') {
@@ -14,7 +14,7 @@ jest.mock('node:worker_threads', () => ({
14
14
  isMainThread: true,
15
15
  parentPort: null,
16
16
  }));
17
- describe('Logger', () => {
17
+ describe(logger_1.Logger.name, () => {
18
18
  let mockEvent;
19
19
  let mockOptions;
20
20
  beforeEach(() => {
@@ -50,7 +50,7 @@ describe('Logger', () => {
50
50
  const logger = new logger_1.Logger({ event: mockEvent, options: mockOptions });
51
51
  // Access private property for testing
52
52
  const tags = logger.tags;
53
- expect(tags).toEqual(Object.assign(Object.assign({}, mockEvent.payload.event_context), { dev_oid: mockEvent.payload.event_context.dev_org }));
53
+ expect(tags).toEqual(Object.assign(Object.assign({}, mockEvent.payload.event_context), { dev_oid: mockEvent.payload.event_context.dev_oid }));
54
54
  });
55
55
  });
56
56
  describe('production logging', () => {
@@ -62,7 +62,7 @@ describe('Logger', () => {
62
62
  it('should log single string message without backslashes', () => {
63
63
  const message = 'Worker is online. Started processing the task.';
64
64
  logger.info(message);
65
- expect(mockConsoleInfo).toHaveBeenCalledWith(JSON.stringify(Object.assign(Object.assign({ message }, mockEvent.payload.event_context), { dev_oid: mockEvent.payload.event_context.dev_org })));
65
+ expect(mockConsoleInfo).toHaveBeenCalledWith(JSON.stringify(Object.assign(Object.assign({ message }, mockEvent.payload.event_context), { dev_oid: mockEvent.payload.event_context.dev_oid })));
66
66
  });
67
67
  it('should log single object message with JSON stringify', () => {
68
68
  const data = { id: 123, name: 'test' };
@@ -71,7 +71,7 @@ describe('Logger', () => {
71
71
  compact: false,
72
72
  depth: Infinity,
73
73
  });
74
- expect(mockConsoleInfo).toHaveBeenCalledWith(JSON.stringify(Object.assign(Object.assign({ message: expectedMessage }, mockEvent.payload.event_context), { dev_oid: mockEvent.payload.event_context.dev_org })));
74
+ expect(mockConsoleInfo).toHaveBeenCalledWith(JSON.stringify(Object.assign(Object.assign({ message: expectedMessage }, mockEvent.payload.event_context), { dev_oid: mockEvent.payload.event_context.dev_oid })));
75
75
  });
76
76
  it('should log multiple arguments joined with space', () => {
77
77
  const text = 'Successfully fetched';
@@ -81,7 +81,7 @@ describe('Logger', () => {
81
81
  compact: false,
82
82
  depth: Infinity,
83
83
  });
84
- expect(mockConsoleInfo).toHaveBeenCalledWith(JSON.stringify(Object.assign(Object.assign({ message: `${text} ${expectedDataMessage}` }, mockEvent.payload.event_context), { dev_oid: mockEvent.payload.event_context.dev_org })));
84
+ expect(mockConsoleInfo).toHaveBeenCalledWith(JSON.stringify(Object.assign(Object.assign({ message: `${text} ${expectedDataMessage}` }, mockEvent.payload.event_context), { dev_oid: mockEvent.payload.event_context.dev_oid })));
85
85
  });
86
86
  it('should handle mixed string and object arguments', () => {
87
87
  const text1 = 'Processing';
@@ -92,7 +92,7 @@ describe('Logger', () => {
92
92
  compact: false,
93
93
  depth: Infinity,
94
94
  });
95
- expect(mockConsoleInfo).toHaveBeenCalledWith(JSON.stringify(Object.assign(Object.assign({ message: `${text1} ${expectedDataMessage} ${text2}` }, mockEvent.payload.event_context), { dev_oid: mockEvent.payload.event_context.dev_org })));
95
+ expect(mockConsoleInfo).toHaveBeenCalledWith(JSON.stringify(Object.assign(Object.assign({ message: `${text1} ${expectedDataMessage} ${text2}` }, mockEvent.payload.event_context), { dev_oid: mockEvent.payload.event_context.dev_oid })));
96
96
  });
97
97
  });
98
98
  describe('local development logging', () => {
@@ -137,25 +137,25 @@ describe('Logger', () => {
137
137
  mockOptions.isLocalDevelopment = false;
138
138
  logger = new logger_1.Logger({ event: mockEvent, options: mockOptions });
139
139
  });
140
- it('should handle empty string message', () => {
140
+ it('[edge] should handle empty string message', () => {
141
141
  logger.info('');
142
142
  expect(mockConsoleInfo).toHaveBeenCalledTimes(1);
143
143
  const callArgs = mockConsoleInfo.mock.calls[0][0];
144
144
  const logObject = JSON.parse(callArgs);
145
145
  expect(logObject.message).toBe('');
146
- expect(logObject.dev_oid).toBe(mockEvent.payload.event_context.dev_org);
146
+ expect(logObject.dev_oid).toBe(mockEvent.payload.event_context.dev_oid);
147
147
  expect(logObject.request_id).toBe(mockEvent.payload.event_context.request_id);
148
148
  });
149
- it('should handle null and undefined values', () => {
149
+ it('[edge] should handle null and undefined values', () => {
150
150
  logger.info('test', null, undefined);
151
151
  expect(mockConsoleInfo).toHaveBeenCalledTimes(1);
152
152
  const callArgs = mockConsoleInfo.mock.calls[0][0];
153
153
  const logObject = JSON.parse(callArgs);
154
154
  // inspect shows 'null' and 'undefined' as strings
155
155
  expect(logObject.message).toBe('test null undefined');
156
- expect(logObject.dev_oid).toBe(mockEvent.payload.event_context.dev_org);
156
+ expect(logObject.dev_oid).toBe(mockEvent.payload.event_context.dev_oid);
157
157
  });
158
- it('should handle complex nested objects', () => {
158
+ it('[edge] should handle complex nested objects', () => {
159
159
  const complexObject = {
160
160
  level1: {
161
161
  level2: {
@@ -174,7 +174,7 @@ describe('Logger', () => {
174
174
  depth: Infinity,
175
175
  });
176
176
  expect(logObject.message).toBe(expectedMessage);
177
- expect(logObject.dev_oid).toBe(mockEvent.payload.event_context.dev_org);
177
+ expect(logObject.dev_oid).toBe(mockEvent.payload.event_context.dev_oid);
178
178
  expect(typeof logObject.callback_url).toBe('string');
179
179
  });
180
180
  });
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Mappers = void 0;
4
- const axios_client_1 = require("../http/axios-client");
4
+ const axios_client_internal_1 = require("../http/axios-client-internal");
5
5
  class Mappers {
6
6
  constructor({ event }) {
7
7
  this.devrevApiEndpoint = event.execution_metadata.devrev_endpoint;
@@ -9,7 +9,7 @@ class Mappers {
9
9
  }
10
10
  async getByTargetId(params) {
11
11
  const { sync_unit, target } = params;
12
- return axios_client_1.axiosClient.get(`${this.devrevApiEndpoint}/internal/airdrop.sync-mapper-record.get-by-target`, {
12
+ return axios_client_internal_1.axiosClient.get(`${this.devrevApiEndpoint}/internal/airdrop.sync-mapper-record.get-by-target`, {
13
13
  headers: {
14
14
  Authorization: this.devrevApiToken,
15
15
  },
@@ -17,14 +17,14 @@ class Mappers {
17
17
  });
18
18
  }
19
19
  async create(params) {
20
- return axios_client_1.axiosClient.post(`${this.devrevApiEndpoint}/internal/airdrop.sync-mapper-record.create`, params, {
20
+ return axios_client_internal_1.axiosClient.post(`${this.devrevApiEndpoint}/internal/airdrop.sync-mapper-record.create`, params, {
21
21
  headers: {
22
22
  Authorization: this.devrevApiToken,
23
23
  },
24
24
  });
25
25
  }
26
26
  async update(params) {
27
- return axios_client_1.axiosClient.post(`${this.devrevApiEndpoint}/internal/airdrop.sync-mapper-record.update`, params, {
27
+ return axios_client_internal_1.axiosClient.post(`${this.devrevApiEndpoint}/internal/airdrop.sync-mapper-record.update`, params, {
28
28
  headers: {
29
29
  Authorization: this.devrevApiToken,
30
30
  },
@@ -5,7 +5,7 @@ const test_helpers_1 = require("../tests/test-helpers");
5
5
  const types_1 = require("../types");
6
6
  const repo_1 = require("./repo");
7
7
  jest.mock('../tests/test-helpers', () => (Object.assign(Object.assign({}, jest.requireActual('../tests/test-helpers')), { normalizeItem: jest.fn() })));
8
- describe('Repo class push method', () => {
8
+ describe(repo_1.Repo.name, () => {
9
9
  let repo;
10
10
  let normalize;
11
11
  beforeEach(() => {
@@ -20,18 +20,14 @@ describe('Repo class push method', () => {
20
20
  afterEach(() => {
21
21
  jest.clearAllMocks();
22
22
  });
23
- it('should not push items if items array is empty', async () => {
24
- await repo.push([]);
25
- expect(repo.getItems()).toEqual([]);
26
- });
27
- it('should normalize and push 10 items if array is not empty', async () => {
23
+ it('should normalize and push items when array contains items', async () => {
28
24
  const items = (0, test_helpers_1.createItems)(10);
29
25
  await repo.push(items);
30
26
  expect(normalize).toHaveBeenCalledTimes(10);
31
27
  const normalizedItems = items.map((item) => (0, test_helpers_1.normalizeItem)(item));
32
28
  expect(repo.getItems()).toEqual(normalizedItems);
33
29
  });
34
- it('should not normalize items if normalize function is not provided', async () => {
30
+ it('should not normalize items when normalize function is not provided', async () => {
35
31
  repo = new repo_1.Repo({
36
32
  event: (0, test_helpers_1.createEvent)({ eventType: types_1.EventType.ExtractionDataStart }),
37
33
  itemType: 'test_item_type',
@@ -42,46 +38,56 @@ describe('Repo class push method', () => {
42
38
  await repo.push(items);
43
39
  expect(normalize).not.toHaveBeenCalled();
44
40
  });
45
- describe('should not normalize items if type is "external_domain_metadata" or "ssor_attachment"', () => {
46
- it('item type: external_domain_metadata', async () => {
47
- repo = new repo_1.Repo({
48
- event: (0, test_helpers_1.createEvent)({ eventType: types_1.EventType.ExtractionDataStart }),
49
- itemType: constants_1.AIRDROP_DEFAULT_ITEM_TYPES.EXTERNAL_DOMAIN_METADATA,
50
- normalize,
51
- onUpload: jest.fn(),
52
- options: {},
53
- });
54
- const items = (0, test_helpers_1.createItems)(10);
55
- await repo.push(items);
56
- expect(normalize).not.toHaveBeenCalled();
41
+ it('[edge] should not push items when items array is empty', async () => {
42
+ await repo.push([]);
43
+ expect(repo.getItems()).toEqual([]);
44
+ });
45
+ it('should not normalize items when item type is external_domain_metadata', async () => {
46
+ repo = new repo_1.Repo({
47
+ event: (0, test_helpers_1.createEvent)({ eventType: types_1.EventType.ExtractionDataStart }),
48
+ itemType: constants_1.AIRDROP_DEFAULT_ITEM_TYPES.EXTERNAL_DOMAIN_METADATA,
49
+ normalize,
50
+ onUpload: jest.fn(),
51
+ options: {},
57
52
  });
58
- it('item type: ssor_attachment', async () => {
59
- repo = new repo_1.Repo({
60
- event: (0, test_helpers_1.createEvent)({ eventType: types_1.EventType.ExtractionDataStart }),
61
- itemType: constants_1.AIRDROP_DEFAULT_ITEM_TYPES.SSOR_ATTACHMENT,
62
- normalize,
63
- onUpload: jest.fn(),
64
- options: {},
65
- });
66
- const items = (0, test_helpers_1.createItems)(10);
67
- await repo.push(items);
68
- expect(normalize).not.toHaveBeenCalled();
53
+ const items = (0, test_helpers_1.createItems)(10);
54
+ await repo.push(items);
55
+ expect(normalize).not.toHaveBeenCalled();
56
+ });
57
+ it('should not normalize items when item type is ssor_attachment', async () => {
58
+ repo = new repo_1.Repo({
59
+ event: (0, test_helpers_1.createEvent)({ eventType: types_1.EventType.ExtractionDataStart }),
60
+ itemType: constants_1.AIRDROP_DEFAULT_ITEM_TYPES.SSOR_ATTACHMENT,
61
+ normalize,
62
+ onUpload: jest.fn(),
63
+ options: {},
69
64
  });
65
+ const items = (0, test_helpers_1.createItems)(10);
66
+ await repo.push(items);
67
+ expect(normalize).not.toHaveBeenCalled();
70
68
  });
71
69
  it('should leave 5 items in the items array after pushing 2005 items with batch size of 2000', async () => {
72
70
  const items = (0, test_helpers_1.createItems)(2005);
73
71
  await repo.push(items);
74
72
  expect(repo.getItems().length).toBe(5);
75
73
  });
76
- it('should upload 2 batches of 2000 and leave 5 items in the items array after pushing 4005 items with batch size of 2000', async () => {
77
- const uploadSpy = jest.spyOn(repo, 'upload');
74
+ it('should normalize all items when pushing 4005 items with batch size of 2000', async () => {
78
75
  const items = (0, test_helpers_1.createItems)(4005);
79
76
  await repo.push(items);
80
77
  expect(normalize).toHaveBeenCalledTimes(4005);
81
- expect(repo.getItems().length).toBe(5);
82
- expect(uploadSpy).toHaveBeenCalledTimes(2); // Check that upload was called twice
78
+ });
79
+ it('should upload 2 batches when pushing 4005 items with batch size of 2000', async () => {
80
+ const uploadSpy = jest.spyOn(repo, 'upload');
81
+ const items = (0, test_helpers_1.createItems)(4005);
82
+ await repo.push(items);
83
+ expect(uploadSpy).toHaveBeenCalledTimes(2);
83
84
  uploadSpy.mockRestore();
84
85
  });
86
+ it('should leave 5 items in array after pushing 4005 items with batch size of 2000', async () => {
87
+ const items = (0, test_helpers_1.createItems)(4005);
88
+ await repo.push(items);
89
+ expect(repo.getItems().length).toBe(5);
90
+ });
85
91
  describe('should take batch size into account', () => {
86
92
  beforeEach(() => {
87
93
  repo = new repo_1.Repo({
@@ -104,14 +110,22 @@ describe('Repo class push method', () => {
104
110
  await repo.push(items);
105
111
  expect(repo.getItems().length).toBe(5);
106
112
  });
107
- it('should upload 4 batches of 50 and leave 5 items in the items array after pushing 205 items with batch size of 50', async () => {
108
- const uploadSpy = jest.spyOn(repo, 'upload');
113
+ it('should normalize all items when pushing 205 items with batch size of 50', async () => {
109
114
  const items = (0, test_helpers_1.createItems)(205);
110
115
  await repo.push(items);
111
116
  expect(normalize).toHaveBeenCalledTimes(205);
112
- expect(repo.getItems().length).toBe(5);
117
+ });
118
+ it('should upload 4 batches when pushing 205 items with batch size of 50', async () => {
119
+ const uploadSpy = jest.spyOn(repo, 'upload');
120
+ const items = (0, test_helpers_1.createItems)(205);
121
+ await repo.push(items);
113
122
  expect(uploadSpy).toHaveBeenCalledTimes(4);
114
123
  uploadSpy.mockRestore();
115
124
  });
125
+ it('should leave 5 items in array after pushing 205 items with batch size of 50', async () => {
126
+ const items = (0, test_helpers_1.createItems)(205);
127
+ await repo.push(items);
128
+ expect(repo.getItems().length).toBe(5);
129
+ });
116
130
  });
117
131
  });
@@ -1,25 +1,29 @@
1
- import { ErrorRecord } from '../types/common';
2
1
  import { AdapterState, StateInterface } from './state.interfaces';
3
2
  export declare function createAdapterState<ConnectorState>({ event, initialState, initialDomainMapping, options, }: StateInterface<ConnectorState>): Promise<State<ConnectorState>>;
4
3
  export declare class State<ConnectorState> {
5
4
  private _state;
6
5
  private initialSdkState;
7
- private event;
8
6
  private workerUrl;
9
7
  private devrevToken;
8
+ private syncUnitId;
9
+ private requestId;
10
10
  constructor({ event, initialState }: StateInterface<ConnectorState>);
11
11
  get state(): AdapterState<ConnectorState>;
12
12
  set state(value: AdapterState<ConnectorState>);
13
13
  /**
14
- * Updates the state of the adapter.
15
- *
14
+ * Initializes the state for this adapter instance by fetching from API
15
+ * or creating an initial state if none exists (404).
16
+ * @param initialState The initial connector state provided by the spawn function
17
+ */
18
+ init(initialState: ConnectorState): Promise<void>;
19
+ /**
20
+ * Updates the state of the adapter by posting to API.
16
21
  * @param {object} state - The state to be updated
17
22
  */
18
23
  postState(state?: AdapterState<ConnectorState>): Promise<void>;
19
24
  /**
20
- * Fetches the state of the adapter.
21
- *
22
- * @return The state of the adapter
25
+ * Fetches the state of the adapter from API.
26
+ * @return The raw state data from API
23
27
  */
24
- fetchState(initialState: ConnectorState): Promise<AdapterState<ConnectorState> | ErrorRecord>;
28
+ fetchState(): Promise<string>;
25
29
  }
@@ -30,3 +30,21 @@ export interface StateInterface<ConnectorState> {
30
30
  initialDomainMapping?: InitialDomainMapping;
31
31
  options?: WorkerAdapterOptions;
32
32
  }
33
+ export declare const extractionSdkState: {
34
+ lastSyncStarted: string;
35
+ lastSuccessfulSyncStarted: string;
36
+ snapInVersionId: string;
37
+ toDevRev: {
38
+ attachmentsMetadata: {
39
+ artifactIds: never[];
40
+ lastProcessed: number;
41
+ lastProcessedAttachmentsIdsList: never[];
42
+ };
43
+ };
44
+ };
45
+ export declare const loadingSdkState: {
46
+ snapInVersionId: string;
47
+ fromDevRev: {
48
+ filesToLoad: never[];
49
+ };
50
+ };
@@ -1,2 +1,21 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.loadingSdkState = exports.extractionSdkState = void 0;
4
+ exports.extractionSdkState = {
5
+ lastSyncStarted: '',
6
+ lastSuccessfulSyncStarted: '',
7
+ snapInVersionId: '',
8
+ toDevRev: {
9
+ attachmentsMetadata: {
10
+ artifactIds: [],
11
+ lastProcessed: 0,
12
+ lastProcessedAttachmentsIdsList: [],
13
+ },
14
+ },
15
+ };
16
+ exports.loadingSdkState = {
17
+ snapInVersionId: '',
18
+ fromDevRev: {
19
+ filesToLoad: [],
20
+ },
21
+ };