@devrev/ts-adaas 1.8.0 → 1.8.1-beta.1

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.
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.emit = void 0;
4
- const axios_client_1 = require("../http/axios-client");
4
+ const axios_client_internal_1 = require("../http/axios-client-internal");
5
5
  const constants_1 = require("./constants");
6
6
  const emit = async ({ event, eventType, data, }) => {
7
7
  const newEvent = {
@@ -13,7 +13,7 @@ const emit = async ({ event, eventType, data, }) => {
13
13
  },
14
14
  };
15
15
  console.info('Emitting event', newEvent);
16
- return axios_client_1.axiosClient.post(event.payload.event_context.callback_url, Object.assign({}, newEvent), {
16
+ return axios_client_internal_1.axiosClient.post(event.payload.event_context.callback_url, Object.assign({}, newEvent), {
17
17
  headers: {
18
18
  Accept: 'application/json, text/plain, */*',
19
19
  Authorization: event.context.secrets.service_account_token,
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.installInitialDomainMapping = installInitialDomainMapping;
4
- const axios_client_1 = require("../http/axios-client");
4
+ const axios_client_internal_1 = require("../http/axios-client-internal");
5
5
  const logger_1 = require("../logger/logger");
6
6
  async function installInitialDomainMapping(event, initialDomainMappingJson) {
7
7
  var _a, _b, _c, _d, _e, _f, _g;
@@ -13,7 +13,7 @@ async function installInitialDomainMapping(event, initialDomainMappingJson) {
13
13
  return;
14
14
  }
15
15
  // Get snap-in details
16
- const snapInResponse = await axios_client_1.axiosClient.get(devrevEndpoint + '/internal/snap-ins.get', {
16
+ const snapInResponse = await axios_client_internal_1.axiosClient.get(devrevEndpoint + '/internal/snap-ins.get', {
17
17
  headers: {
18
18
  Authorization: devrevToken,
19
19
  },
@@ -33,7 +33,7 @@ async function installInitialDomainMapping(event, initialDomainMappingJson) {
33
33
  if (startingRecipeBlueprint &&
34
34
  Object.keys(startingRecipeBlueprint).length !== 0) {
35
35
  try {
36
- const recipeBlueprintResponse = await axios_client_1.axiosClient.post(`${devrevEndpoint}/internal/airdrop.recipe.blueprints.create`, Object.assign({}, startingRecipeBlueprint), {
36
+ const recipeBlueprintResponse = await axios_client_internal_1.axiosClient.post(`${devrevEndpoint}/internal/airdrop.recipe.blueprints.create`, Object.assign({}, startingRecipeBlueprint), {
37
37
  headers: {
38
38
  Authorization: devrevToken,
39
39
  },
@@ -47,7 +47,7 @@ async function installInitialDomainMapping(event, initialDomainMappingJson) {
47
47
  }
48
48
  // Install the initial domain mappings
49
49
  const additionalMappings = initialDomainMappingJson.additional_mappings || {};
50
- const initialDomainMappingInstallResponse = await axios_client_1.axiosClient.post(`${devrevEndpoint}/internal/airdrop.recipe.initial-domain-mappings.install`, Object.assign(Object.assign({ external_system_type: 'ADaaS', import_slug: importSlug, snap_in_slug: snapInSlug }, (recipeBlueprintId && {
50
+ const initialDomainMappingInstallResponse = await axios_client_internal_1.axiosClient.post(`${devrevEndpoint}/internal/airdrop.recipe.initial-domain-mappings.install`, Object.assign(Object.assign({ external_system_type: 'ADaaS', import_slug: importSlug, snap_in_slug: snapInSlug }, (recipeBlueprintId && {
51
51
  starting_recipe_blueprint: recipeBlueprintId,
52
52
  })), additionalMappings), {
53
53
  headers: {
@@ -5,14 +5,20 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const axios_1 = __importDefault(require("axios"));
7
7
  const install_initial_domain_mapping_1 = require("./install-initial-domain-mapping");
8
- const axios_client_1 = require("../http/axios-client");
8
+ const axios_client_internal_1 = require("../http/axios-client-internal");
9
9
  const test_helpers_1 = require("../tests/test-helpers");
10
10
  const extraction_1 = require("../types/extraction");
11
11
  // Mock dependencies
12
12
  jest.mock('axios', () => (Object.assign(Object.assign({}, jest.requireActual('axios')), { isAxiosError: jest.fn() })));
13
- jest.mock('../http/axios-client');
13
+ jest.mock('../http/axios-client-internal', () => {
14
+ const originalModule = jest.requireActual('../http/axios-client-internal');
15
+ return Object.assign(Object.assign({}, originalModule), { axiosClient: {
16
+ get: jest.fn(),
17
+ post: jest.fn(),
18
+ } });
19
+ });
14
20
  jest.mock('../logger/logger');
15
- const mockAxiosClient = axios_client_1.axiosClient;
21
+ const mockAxiosClient = axios_client_internal_1.axiosClient;
16
22
  const mockIsAxiosError = axios_1.default.isAxiosError;
17
23
  describe('installInitialDomainMapping', () => {
18
24
  // Create mock objects
@@ -34,7 +34,7 @@ var __importStar = (this && this.__importStar) || (function () {
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.Uploader = void 0;
37
- const axios_client_1 = require("../../http/axios-client");
37
+ const axios_client_internal_1 = require("../../http/axios-client-internal");
38
38
  const typescript_sdk_1 = require("@devrev/typescript-sdk");
39
39
  const fs_1 = __importStar(require("fs"));
40
40
  const helpers_1 = require("../common/helpers");
@@ -118,7 +118,7 @@ class Uploader {
118
118
  ) {
119
119
  const formData = (0, helpers_1.createFormData)(preparedArtifact, fetchedObjects);
120
120
  try {
121
- const response = await axios_client_1.axiosClient.post(preparedArtifact.url, formData, {
121
+ const response = await axios_client_internal_1.axiosClient.post(preparedArtifact.url, formData, {
122
122
  headers: {
123
123
  'Content-Type': 'multipart/form-data',
124
124
  },
@@ -0,0 +1,2 @@
1
+ declare const axiosClient: import("axios").AxiosInstance;
2
+ export { axiosClient };
@@ -0,0 +1,60 @@
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
+ exports.axiosClient = void 0;
7
+ const axios_1 = __importDefault(require("axios"));
8
+ const axios_retry_1 = __importDefault(require("axios-retry"));
9
+ const axiosClient = axios_1.default.create();
10
+ exports.axiosClient = axiosClient;
11
+ (0, axios_retry_1.default)(axiosClient, {
12
+ retries: 5,
13
+ retryDelay: (retryCount, error) => {
14
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
15
+ // If the response status is 429, retry after the time specified in the Retry-After header
16
+ if (((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) === 429) {
17
+ const retryAfter = ((_c = (_b = error.response) === null || _b === void 0 ? void 0 : _b.headers) === null || _c === void 0 ? void 0 : _c['retry-after']) ||
18
+ ((_e = (_d = error.response) === null || _d === void 0 ? void 0 : _d.headers) === null || _e === void 0 ? void 0 : _e['Retry-After']);
19
+ // Since DevRev API returns the retry-after header in seconds and axios-retry expects milliseconds, we need to convert it to milliseconds
20
+ const delay = parseInt(retryAfter, 10) * 1000;
21
+ const delayInSeconds = Math.round(delay / 1000);
22
+ console.warn(`Retrying ${(_f = error.config) === null || _f === void 0 ? void 0 : _f.method} request to ${(_g = error.config) === null || _g === void 0 ? void 0 : _g.url} in ${delayInSeconds}s due to 429 Too Many Requests.`);
23
+ return delay;
24
+ }
25
+ // Default exponential backoff algorithm: 1 * 2 ^ retryCount * 1000ms
26
+ // This will retry requests after 2, 4, 8, 16 and 32 seconds
27
+ const delay = axios_retry_1.default.exponentialDelay(retryCount, error, 1000);
28
+ const delayInSeconds = Math.round(delay / 1000);
29
+ console.warn(`Retrying ${(_h = error.config) === null || _h === void 0 ? void 0 : _h.method} request to ${(_j = error.config) === null || _j === void 0 ? void 0 : _j.url} in ${delayInSeconds}s due to ${(_k = error.response) === null || _k === void 0 ? void 0 : _k.status} error.`);
30
+ return delay;
31
+ },
32
+ retryCondition: (error) => {
33
+ var _a, _b, _c, _d, _e, _f;
34
+ const retryAfter = ((_b = (_a = error.response) === null || _a === void 0 ? void 0 : _a.headers) === null || _b === void 0 ? void 0 : _b['retry-after']) ||
35
+ ((_d = (_c = error.response) === null || _c === void 0 ? void 0 : _c.headers) === null || _d === void 0 ? void 0 : _d['Retry-After']);
36
+ // 5xx errors
37
+ if (((_e = error.response) === null || _e === void 0 ? void 0 : _e.status) && error.response.status >= 500) {
38
+ return true;
39
+ }
40
+ // 429 errors when retry-after header is present
41
+ else if (((_f = error.response) === null || _f === void 0 ? void 0 : _f.status) &&
42
+ error.response.status === 429 &&
43
+ retryAfter &&
44
+ !isNaN(Number(retryAfter)) &&
45
+ Number(retryAfter) >= 0) {
46
+ return true;
47
+ }
48
+ // all other errors
49
+ else {
50
+ return false;
51
+ }
52
+ },
53
+ onMaxRetryTimesExceeded(error) {
54
+ var _a, _b, _c, _d, _e, _f;
55
+ (_b = (_a = error.config) === null || _a === void 0 ? void 0 : _a.headers) === null || _b === void 0 ? true : delete _b.authorization;
56
+ (_d = (_c = error.config) === null || _c === void 0 ? void 0 : _c.headers) === null || _d === void 0 ? true : delete _d.Authorization;
57
+ (_e = error.request) === null || _e === void 0 ? true : delete _e._header;
58
+ console.error(`Request to ${(_f = error.config) === null || _f === void 0 ? void 0 : _f.url} failed after max retries. Error`, error);
59
+ },
60
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -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
+ });
@@ -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
  },
@@ -1,8 +1,12 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.State = void 0;
4
7
  exports.createAdapterState = createAdapterState;
5
- const axios_client_1 = require("../http/axios-client");
8
+ const axios_1 = __importDefault(require("axios"));
9
+ const axios_client_internal_1 = require("../http/axios-client-internal");
6
10
  const extraction_1 = require("../types/extraction");
7
11
  const constants_1 = require("../common/constants");
8
12
  const logger_1 = require("../logger/logger");
@@ -88,7 +92,7 @@ class State {
88
92
  */
89
93
  async postState(state) {
90
94
  try {
91
- await axios_client_1.axiosClient.post(this.workerUrl + '.update', {
95
+ await axios_client_internal_1.axiosClient.post(this.workerUrl + '.update', {
92
96
  state: JSON.stringify(state || this.state),
93
97
  }, {
94
98
  headers: {
@@ -118,7 +122,7 @@ class State {
118
122
  this.event.payload.event_context.sync_unit_id +
119
123
  '.');
120
124
  try {
121
- const response = await axios_client_1.axiosClient.get(this.workerUrl + '.get', {
125
+ const response = await axios_client_internal_1.axiosClient.get(this.workerUrl + '.get', {
122
126
  headers: {
123
127
  Authorization: this.devrevToken,
124
128
  },
@@ -132,7 +136,7 @@ class State {
132
136
  return this.state;
133
137
  }
134
138
  catch (error) {
135
- if (axios_client_1.axios.isAxiosError(error) && ((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) === 404) {
139
+ if (axios_1.default.isAxiosError(error) && ((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) === 404) {
136
140
  const state = Object.assign(Object.assign({}, initialState), this.initialSdkState);
137
141
  this.state = state;
138
142
  console.log('State not found, returning initial state. Current state', (0, logger_1.getPrintableState)(this.state));
@@ -38,7 +38,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
39
  exports.Uploader = void 0;
40
40
  const fs_1 = __importStar(require("fs"));
41
- const axios_client_1 = require("../http/axios-client");
41
+ const axios_client_internal_1 = require("../http/axios-client-internal");
42
42
  const zlib_1 = __importDefault(require("zlib"));
43
43
  const js_jsonl_1 = require("js-jsonl");
44
44
  const form_data_1 = __importDefault(require("form-data"));
@@ -110,7 +110,7 @@ class Uploader {
110
110
  async getArtifactUploadUrl(filename, fileType) {
111
111
  const url = `${this.devrevApiEndpoint}/internal/airdrop.artifacts.upload-url`;
112
112
  try {
113
- const response = await axios_client_1.axiosClient.get(url, {
113
+ const response = await axios_client_internal_1.axiosClient.get(url, {
114
114
  headers: Object.assign({}, this.defaultHeaders),
115
115
  params: {
116
116
  request_id: this.requestId,
@@ -131,7 +131,7 @@ class Uploader {
131
131
  }
132
132
  formData.append('file', file);
133
133
  try {
134
- const response = await axios_client_1.axiosClient.post(artifact.upload_url, formData, {
134
+ const response = await axios_client_internal_1.axiosClient.post(artifact.upload_url, formData, {
135
135
  headers: Object.assign({}, formData.getHeaders()),
136
136
  });
137
137
  return response;
@@ -151,7 +151,7 @@ class Uploader {
151
151
  return;
152
152
  }
153
153
  try {
154
- const response = await axios_client_1.axiosClient.post(artifact.upload_url, formData, {
154
+ const response = await axios_client_internal_1.axiosClient.post(artifact.upload_url, formData, {
155
155
  headers: Object.assign(Object.assign({}, formData.getHeaders()), (!fileStream.headers['content-length']
156
156
  ? {
157
157
  'Content-Length': constants_1.MAX_DEVREV_ARTIFACT_SIZE,
@@ -170,7 +170,7 @@ class Uploader {
170
170
  async confirmArtifactUpload(artifactId) {
171
171
  const url = `${this.devrevApiEndpoint}/internal/airdrop.artifacts.confirm-upload`;
172
172
  try {
173
- const response = await axios_client_1.axiosClient.post(url, {
173
+ const response = await axios_client_internal_1.axiosClient.post(url, {
174
174
  request_id: this.requestId,
175
175
  artifact_id: artifactId,
176
176
  }, {
@@ -216,7 +216,7 @@ class Uploader {
216
216
  async getArtifactDownloadUrl(artifactId) {
217
217
  const url = `${this.devrevApiEndpoint}/internal/airdrop.artifacts.download-url`;
218
218
  try {
219
- const response = await axios_client_1.axiosClient.get(url, {
219
+ const response = await axios_client_internal_1.axiosClient.get(url, {
220
220
  headers: Object.assign({}, this.defaultHeaders),
221
221
  params: {
222
222
  request_id: this.requestId,
@@ -231,7 +231,7 @@ class Uploader {
231
231
  }
232
232
  async downloadArtifact(artifactUrl) {
233
233
  try {
234
- const response = await axios_client_1.axiosClient.get(artifactUrl, {
234
+ const response = await axios_client_internal_1.axiosClient.get(artifactUrl, {
235
235
  responseType: 'arraybuffer',
236
236
  });
237
237
  return response.data;
@@ -3,9 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const test_helpers_1 = require("../tests/test-helpers");
4
4
  const types_1 = require("../types");
5
5
  const uploader_1 = require("./uploader");
6
- const axios_client_1 = require("../http/axios-client");
7
- jest.mock('../http/axios-client', () => {
8
- const originalModule = jest.requireActual('../http/axios-client');
6
+ const axios_client_internal_1 = require("../http/axios-client-internal");
7
+ jest.mock('../http/axios-client-internal', () => {
8
+ const originalModule = jest.requireActual('../http/axios-client-internal');
9
9
  return Object.assign(Object.assign({}, originalModule), { axiosClient: {
10
10
  get: jest.fn(),
11
11
  post: jest.fn(),
@@ -41,9 +41,9 @@ describe('Uploader Class Tests', () => {
41
41
  });
42
42
  it('should upload the file to the DevRev platform and return the artifact information', async () => {
43
43
  // Mock successful response from getArtifactUploadUrl
44
- axios_client_1.axiosClient.get.mockResolvedValueOnce(getArtifactUploadUrlMockResponse);
44
+ axios_client_internal_1.axiosClient.get.mockResolvedValueOnce(getArtifactUploadUrlMockResponse);
45
45
  // Mock successful response from confirmArtifactUpload and uploadArtifact
46
- axios_client_1.axiosClient.post.mockResolvedValue(getSuccessResponse());
46
+ axios_client_internal_1.axiosClient.post.mockResolvedValue(getSuccessResponse());
47
47
  const entity = 'entity';
48
48
  const fetchedObjects = [{ key: 'value' }];
49
49
  const uploadResponse = await uploader.upload(entity, fetchedObjects);
@@ -58,7 +58,7 @@ describe('Uploader Class Tests', () => {
58
58
  it('should handle failure in getArtifactUploadUrl', async () => {
59
59
  var _a;
60
60
  // Mock unsuccessful response for getArtifactUploadUrl
61
- axios_client_1.axiosClient.get.mockResolvedValueOnce(undefined);
61
+ axios_client_internal_1.axiosClient.get.mockResolvedValueOnce(undefined);
62
62
  const entity = 'entity';
63
63
  const fetchedObjects = [{ key: 'value' }];
64
64
  const uploadResponse = await uploader.upload(entity, fetchedObjects);
@@ -68,9 +68,9 @@ describe('Uploader Class Tests', () => {
68
68
  it('should handle failure in uploadArtifact', async () => {
69
69
  var _a;
70
70
  // Mock successful response for getArtifactUploadUrl
71
- axios_client_1.axiosClient.get.mockResolvedValueOnce(getArtifactUploadUrlMockResponse);
71
+ axios_client_internal_1.axiosClient.get.mockResolvedValueOnce(getArtifactUploadUrlMockResponse);
72
72
  // Mock unsuccessful response for uploadArtifact
73
- axios_client_1.axiosClient.post.mockResolvedValueOnce(undefined);
73
+ axios_client_internal_1.axiosClient.post.mockResolvedValueOnce(undefined);
74
74
  const entity = 'entity';
75
75
  const fetchedObjects = [{ key: 'value' }];
76
76
  const uploadResponse = await uploader.upload(entity, fetchedObjects);
@@ -80,11 +80,11 @@ describe('Uploader Class Tests', () => {
80
80
  it('should handle failure in confirmArtifactUpload', async () => {
81
81
  var _a;
82
82
  // Mock successful response for getArtifactUploadUrl
83
- axios_client_1.axiosClient.get.mockResolvedValueOnce(getArtifactUploadUrlMockResponse);
83
+ axios_client_internal_1.axiosClient.get.mockResolvedValueOnce(getArtifactUploadUrlMockResponse);
84
84
  // Mock successful response from uploadArtifact
85
- axios_client_1.axiosClient.post.mockResolvedValueOnce(getSuccessResponse());
85
+ axios_client_internal_1.axiosClient.post.mockResolvedValueOnce(getSuccessResponse());
86
86
  // Mock unsuccessful response from confirmArtifactUpload
87
- axios_client_1.axiosClient.post.mockResolvedValueOnce(undefined);
87
+ axios_client_internal_1.axiosClient.post.mockResolvedValueOnce(undefined);
88
88
  const entity = 'entity';
89
89
  const fetchedObjects = [{ key: 'value' }];
90
90
  const uploadResponse = await uploader.upload(entity, fetchedObjects);
@@ -1,11 +1,15 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ const axios_1 = __importDefault(require("axios"));
3
7
  const index_1 = require("../../index");
4
- const axios_client_1 = require("../../http/axios-client");
8
+ const axios_client_internal_1 = require("../../http/axios-client-internal");
5
9
  const getAttachmentStream = async ({ item, }) => {
6
10
  const { id, url } = item;
7
11
  try {
8
- const fileStreamResponse = await axios_client_1.axiosClient.get(url, {
12
+ const fileStreamResponse = await axios_client_internal_1.axiosClient.get(url, {
9
13
  responseType: 'stream',
10
14
  headers: {
11
15
  'Accept-Encoding': 'identity',
@@ -14,7 +18,7 @@ const getAttachmentStream = async ({ item, }) => {
14
18
  return { httpStream: fileStreamResponse };
15
19
  }
16
20
  catch (error) {
17
- if (axios_client_1.axios.isAxiosError(error)) {
21
+ if (axios_1.default.isAxiosError(error)) {
18
22
  console.warn(`Error while fetching attachment ${id} from URL.`, (0, index_1.serializeAxiosError)(error));
19
23
  console.warn('Failed attachment metadata', item);
20
24
  }
@@ -1,8 +1,11 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.WorkerAdapter = void 0;
4
7
  exports.createWorkerAdapter = createWorkerAdapter;
5
- const axios_client_1 = require("../http/axios-client");
8
+ const axios_1 = __importDefault(require("axios"));
6
9
  const extraction_1 = require("../types/extraction");
7
10
  const loading_1 = require("../types/loading");
8
11
  const constants_1 = require("../common/constants");
@@ -419,7 +422,7 @@ class WorkerAdapter {
419
422
  // TODO: Update mapper (optional)
420
423
  }
421
424
  catch (error) {
422
- if (axios_client_1.axios.isAxiosError(error)) {
425
+ if (axios_1.default.isAxiosError(error)) {
423
426
  if (((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) === 404) {
424
427
  // Create item in external system if mapper record not found
425
428
  const { id, delay, error } = await itemTypeToLoad.create({
@@ -74,16 +74,32 @@ describe('WorkerAdapter', () => {
74
74
  },
75
75
  };
76
76
  // Mock getting attachments from each artifact
77
- adapter['uploader'].getAttachmentsFromArtifactId = jest.fn()
77
+ adapter['uploader'].getAttachmentsFromArtifactId = jest
78
+ .fn()
78
79
  .mockResolvedValueOnce({
79
80
  attachments: [
80
- { url: 'http://example.com/file1.pdf', id: 'attachment1', file_name: 'file1.pdf', parent_id: 'parent1' },
81
- { url: 'http://example.com/file2.pdf', id: 'attachment2', file_name: 'file2.pdf', parent_id: 'parent2' },
81
+ {
82
+ url: 'http://example.com/file1.pdf',
83
+ id: 'attachment1',
84
+ file_name: 'file1.pdf',
85
+ parent_id: 'parent1',
86
+ },
87
+ {
88
+ url: 'http://example.com/file2.pdf',
89
+ id: 'attachment2',
90
+ file_name: 'file2.pdf',
91
+ parent_id: 'parent2',
92
+ },
82
93
  ],
83
94
  })
84
95
  .mockResolvedValueOnce({
85
96
  attachments: [
86
- { url: 'http://example.com/file3.pdf', id: 'attachment3', file_name: 'file3.pdf', parent_id: 'parent3' },
97
+ {
98
+ url: 'http://example.com/file3.pdf',
99
+ id: 'attachment3',
100
+ file_name: 'file3.pdf',
101
+ parent_id: 'parent3',
102
+ },
87
103
  ],
88
104
  });
89
105
  // Mock the initializeRepos method
@@ -115,9 +131,16 @@ describe('WorkerAdapter', () => {
115
131
  },
116
132
  };
117
133
  // Mock getting attachments
118
- adapter['uploader'].getAttachmentsFromArtifactId = jest.fn().mockResolvedValue({
134
+ adapter['uploader'].getAttachmentsFromArtifactId = jest
135
+ .fn()
136
+ .mockResolvedValue({
119
137
  attachments: [
120
- { url: 'http://example.com/file1.pdf', id: 'attachment1', file_name: 'file1.pdf', parent_id: 'parent1' },
138
+ {
139
+ url: 'http://example.com/file1.pdf',
140
+ id: 'attachment1',
141
+ file_name: 'file1.pdf',
142
+ parent_id: 'parent1',
143
+ },
121
144
  ],
122
145
  });
123
146
  adapter.initializeRepos = jest.fn();
@@ -145,9 +168,16 @@ describe('WorkerAdapter', () => {
145
168
  },
146
169
  };
147
170
  // Mock getting attachments
148
- adapter['uploader'].getAttachmentsFromArtifactId = jest.fn().mockResolvedValue({
171
+ adapter['uploader'].getAttachmentsFromArtifactId = jest
172
+ .fn()
173
+ .mockResolvedValue({
149
174
  attachments: [
150
- { url: 'http://example.com/file1.pdf', id: 'attachment1', file_name: 'file1.pdf', parent_id: 'parent1' },
175
+ {
176
+ url: 'http://example.com/file1.pdf',
177
+ id: 'attachment1',
178
+ file_name: 'file1.pdf',
179
+ parent_id: 'parent1',
180
+ },
151
181
  ],
152
182
  });
153
183
  // Mock the required methods
@@ -197,7 +227,9 @@ describe('WorkerAdapter', () => {
197
227
  };
198
228
  // Mock error when getting attachments
199
229
  const mockError = new Error('Failed to get attachments');
200
- adapter['uploader'].getAttachmentsFromArtifactId = jest.fn().mockResolvedValue({
230
+ adapter['uploader'].getAttachmentsFromArtifactId = jest
231
+ .fn()
232
+ .mockResolvedValue({
201
233
  error: mockError,
202
234
  });
203
235
  // Mock methods
@@ -227,7 +259,9 @@ describe('WorkerAdapter', () => {
227
259
  },
228
260
  };
229
261
  // Mock getting empty attachments
230
- adapter['uploader'].getAttachmentsFromArtifactId = jest.fn().mockResolvedValue({
262
+ adapter['uploader'].getAttachmentsFromArtifactId = jest
263
+ .fn()
264
+ .mockResolvedValue({
231
265
  attachments: [],
232
266
  });
233
267
  // Mock methods
@@ -258,7 +292,9 @@ describe('WorkerAdapter', () => {
258
292
  },
259
293
  };
260
294
  // Mock getting attachments
261
- adapter['uploader'].getAttachmentsFromArtifactId = jest.fn().mockResolvedValue({
295
+ adapter['uploader'].getAttachmentsFromArtifactId = jest
296
+ .fn()
297
+ .mockResolvedValue({
262
298
  attachments: [{ id: 'attachment1' }],
263
299
  });
264
300
  // Mock methods
@@ -305,7 +341,9 @@ describe('WorkerAdapter', () => {
305
341
  },
306
342
  };
307
343
  // Mock getting attachments
308
- adapter['uploader'].getAttachmentsFromArtifactId = jest.fn().mockResolvedValue({
344
+ adapter['uploader'].getAttachmentsFromArtifactId = jest
345
+ .fn()
346
+ .mockResolvedValue({
309
347
  attachments: [{ id: 'attachment1' }],
310
348
  });
311
349
  // Mock methods
@@ -319,7 +357,9 @@ describe('WorkerAdapter', () => {
319
357
  delay: 30,
320
358
  });
321
359
  // The artifactIds array should remain unchanged
322
- expect(adapter.state.toDevRev.attachmentsMetadata.artifactIds).toEqual(['artifact1']);
360
+ expect(adapter.state.toDevRev.attachmentsMetadata.artifactIds).toEqual([
361
+ 'artifact1',
362
+ ]);
323
363
  });
324
364
  it('should handle error from iterator', async () => {
325
365
  // Arrange
@@ -328,7 +368,7 @@ describe('WorkerAdapter', () => {
328
368
  return {
329
369
  // Return an object with a `streamAll` method that resolves to your desired value.
330
370
  streamAll: jest.fn().mockResolvedValue({
331
- error: "Mock error",
371
+ error: 'Mock error',
332
372
  }),
333
373
  };
334
374
  });
@@ -341,7 +381,9 @@ describe('WorkerAdapter', () => {
341
381
  },
342
382
  };
343
383
  // Mock getting attachments
344
- adapter['uploader'].getAttachmentsFromArtifactId = jest.fn().mockResolvedValue({
384
+ adapter['uploader'].getAttachmentsFromArtifactId = jest
385
+ .fn()
386
+ .mockResolvedValue({
345
387
  attachments: [{ id: 'attachment1' }],
346
388
  });
347
389
  // Mock methods
@@ -352,10 +394,12 @@ describe('WorkerAdapter', () => {
352
394
  });
353
395
  // Assert
354
396
  expect(result).toEqual({
355
- error: "Mock error",
397
+ error: 'Mock error',
356
398
  });
357
399
  // The artifactIds array should remain unchanged
358
- expect(adapter.state.toDevRev.attachmentsMetadata.artifactIds).toEqual(['artifact1']);
400
+ expect(adapter.state.toDevRev.attachmentsMetadata.artifactIds).toEqual([
401
+ 'artifact1',
402
+ ]);
359
403
  });
360
404
  it('should reset lastProcessed and attachment IDs list after processing all artifacts', async () => {
361
405
  const mockStream = jest.fn();
@@ -366,12 +410,28 @@ describe('WorkerAdapter', () => {
366
410
  lastProcessedAttachmentsIdsList: [],
367
411
  },
368
412
  };
369
- adapter['uploader'].getAttachmentsFromArtifactId = jest.fn()
413
+ adapter['uploader'].getAttachmentsFromArtifactId = jest
414
+ .fn()
370
415
  .mockResolvedValueOnce({
371
416
  attachments: [
372
- { url: 'http://example.com/file1.pdf', id: 'attachment1', file_name: 'file1.pdf', parent_id: 'parent1' },
373
- { url: 'http://example.com/file2.pdf', id: 'attachment2', file_name: 'file2.pdf', parent_id: 'parent2' },
374
- { url: 'http://example.com/file3.pdf', id: 'attachment3', file_name: 'file3.pdf', parent_id: 'parent3' },
417
+ {
418
+ url: 'http://example.com/file1.pdf',
419
+ id: 'attachment1',
420
+ file_name: 'file1.pdf',
421
+ parent_id: 'parent1',
422
+ },
423
+ {
424
+ url: 'http://example.com/file2.pdf',
425
+ id: 'attachment2',
426
+ file_name: 'file2.pdf',
427
+ parent_id: 'parent2',
428
+ },
429
+ {
430
+ url: 'http://example.com/file3.pdf',
431
+ id: 'attachment3',
432
+ file_name: 'file3.pdf',
433
+ parent_id: 'parent3',
434
+ },
375
435
  ],
376
436
  });
377
437
  adapter.processAttachment = jest.fn().mockResolvedValue(null);
@@ -395,7 +455,9 @@ describe('WorkerAdapter', () => {
395
455
  });
396
456
  // Spy on the parentPort.postMessage method
397
457
  if (workerThreads.parentPort) {
398
- jest.spyOn(workerThreads.parentPort, 'postMessage').mockImplementation(mockPostMessage);
458
+ jest
459
+ .spyOn(workerThreads.parentPort, 'postMessage')
460
+ .mockImplementation(mockPostMessage);
399
461
  }
400
462
  else {
401
463
  // If parentPort is null (not in worker context), create a mock
@@ -409,7 +471,9 @@ describe('WorkerAdapter', () => {
409
471
  jest.restoreAllMocks();
410
472
  });
411
473
  test('should correctly emit event', async () => {
412
- adapter['adapterState'].postState = jest.fn().mockResolvedValue(undefined);
474
+ adapter['adapterState'].postState = jest
475
+ .fn()
476
+ .mockResolvedValue(undefined);
413
477
  adapter.uploadAllRepos = jest.fn().mockResolvedValue(undefined);
414
478
  await adapter.emit(types_1.ExtractorEventType.ExtractionMetadataError, {
415
479
  reports: [],
@@ -426,7 +490,9 @@ describe('WorkerAdapter', () => {
426
490
  expect(counter.counter).toBe(1);
427
491
  });
428
492
  test('should correctly emit one event even if postState errors', async () => {
429
- adapter['adapterState'].postState = jest.fn().mockRejectedValue(new Error('postState error'));
493
+ adapter['adapterState'].postState = jest
494
+ .fn()
495
+ .mockRejectedValue(new Error('postState error'));
430
496
  adapter.uploadAllRepos = jest.fn().mockResolvedValue(undefined);
431
497
  await adapter.emit(types_1.ExtractorEventType.ExtractionMetadataError, {
432
498
  reports: [],
@@ -435,8 +501,12 @@ describe('WorkerAdapter', () => {
435
501
  expect(counter.counter).toBe(1);
436
502
  });
437
503
  test('should correctly emit one event even if uploadAllRepos errors', async () => {
438
- adapter['adapterState'].postState = jest.fn().mockResolvedValue(undefined);
439
- adapter.uploadAllRepos = jest.fn().mockRejectedValue(new Error('uploadAllRepos error'));
504
+ adapter['adapterState'].postState = jest
505
+ .fn()
506
+ .mockResolvedValue(undefined);
507
+ adapter.uploadAllRepos = jest
508
+ .fn()
509
+ .mockRejectedValue(new Error('uploadAllRepos error'));
440
510
  await adapter.emit(types_1.ExtractorEventType.ExtractionMetadataError, {
441
511
  reports: [],
442
512
  processed_files: [],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devrev/ts-adaas",
3
- "version": "1.8.0",
3
+ "version": "1.8.1-beta.1",
4
4
  "description": "Typescript library containing the ADaaS(AirDrop as a Service) control protocol.",
5
5
  "type": "commonjs",
6
6
  "main": "./dist/index.js",
@@ -30,6 +30,7 @@
30
30
  "@types/yargs": "^17.0.33",
31
31
  "@typescript-eslint/eslint-plugin": "^8.32.1",
32
32
  "@typescript-eslint/parser": "^8.32.1",
33
+ "axios-mock-adapter": "^2.1.0",
33
34
  "eslint": "^9.26.0",
34
35
  "eslint-config-prettier": "^10.1.5",
35
36
  "eslint-plugin-prettier": "^5.1.3",