@devrev/ts-adaas 1.10.0 → 1.10.1-beta.2

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,5 +1,6 @@
1
1
  import { ErrorRecord } from '../types/common';
2
2
  import { Item } from '../repo/repo.interfaces';
3
+ import { Artifact } from '../uploader/uploader.interfaces';
3
4
  import { RepoFactoryInterface, NormalizedItem, NormalizedAttachment } from './repo.interfaces';
4
5
  export declare class Repo {
5
6
  readonly itemType: string;
@@ -8,6 +9,7 @@ export declare class Repo {
8
9
  private uploader;
9
10
  private onUpload;
10
11
  private options?;
12
+ uploadedArtifacts: Artifact[];
11
13
  constructor({ event, itemType, normalize, onUpload, options, }: RepoFactoryInterface);
12
14
  getItems(): (NormalizedItem | NormalizedAttachment | Item)[];
13
15
  upload(batch?: (NormalizedItem | NormalizedAttachment | Item)[]): Promise<void | ErrorRecord>;
@@ -1 +1 @@
1
- {"version":3,"file":"repo.d.ts","sourceRoot":"","sources":["../../src/repo/repo.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,IAAI,EAAE,MAAM,yBAAyB,CAAC;AAI/C,OAAO,EACL,oBAAoB,EACpB,cAAc,EACd,oBAAoB,EACrB,MAAM,mBAAmB,CAAC;AAG3B,qBAAa,IAAI;IACf,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,KAAK,CAAmD;IAChE,OAAO,CAAC,SAAS,CAAC,CAAwD;IAC1E,OAAO,CAAC,QAAQ,CAAW;IAC3B,OAAO,CAAC,QAAQ,CAA+B;IAC/C,OAAO,CAAC,OAAO,CAAC,CAAuB;gBAE3B,EACV,KAAK,EACL,QAAQ,EACR,SAAS,EACT,QAAQ,EACR,OAAO,GACR,EAAE,oBAAoB;IASvB,QAAQ,IAAI,CAAC,cAAc,GAAG,oBAAoB,GAAG,IAAI,CAAC,EAAE;IAItD,MAAM,CACV,KAAK,CAAC,EAAE,CAAC,cAAc,GAAG,oBAAoB,GAAG,IAAI,CAAC,EAAE,GACvD,OAAO,CAAC,IAAI,GAAG,WAAW,CAAC;IAmCxB,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;CAuC5C"}
1
+ {"version":3,"file":"repo.d.ts","sourceRoot":"","sources":["../../src/repo/repo.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,IAAI,EAAE,MAAM,yBAAyB,CAAC;AAE/C,OAAO,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAE3D,OAAO,EACL,oBAAoB,EACpB,cAAc,EACd,oBAAoB,EACrB,MAAM,mBAAmB,CAAC;AAG3B,qBAAa,IAAI;IACf,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,KAAK,CAAmD;IAChE,OAAO,CAAC,SAAS,CAAC,CAAwD;IAC1E,OAAO,CAAC,QAAQ,CAAW;IAC3B,OAAO,CAAC,QAAQ,CAA+B;IAC/C,OAAO,CAAC,OAAO,CAAC,CAAuB;IAChC,iBAAiB,EAAE,QAAQ,EAAE,CAAC;gBAEzB,EACV,KAAK,EACL,QAAQ,EACR,SAAS,EACT,QAAQ,EACR,OAAO,GACR,EAAE,oBAAoB;IAUvB,QAAQ,IAAI,CAAC,cAAc,GAAG,oBAAoB,GAAG,IAAI,CAAC,EAAE;IAItD,MAAM,CACV,KAAK,CAAC,EAAE,CAAC,cAAc,GAAG,oBAAoB,GAAG,IAAI,CAAC,EAAE,GACvD,OAAO,CAAC,IAAI,GAAG,WAAW,CAAC;IAqCxB,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;CAuC5C"}
package/dist/repo/repo.js CHANGED
@@ -11,6 +11,7 @@ class Repo {
11
11
  this.onUpload = onUpload;
12
12
  this.uploader = new uploader_1.Uploader({ event, options });
13
13
  this.options = options;
14
+ this.uploadedArtifacts = [];
14
15
  }
15
16
  getItems() {
16
17
  return this.items;
@@ -25,6 +26,7 @@ class Repo {
25
26
  return error;
26
27
  }
27
28
  this.onUpload(artifact);
29
+ this.uploadedArtifacts.push(artifact);
28
30
  // Clear the uploaded items from the main items array if no batch was specified
29
31
  if (!batch) {
30
32
  this.items = [];
@@ -23,6 +23,11 @@ export declare class Uploader {
23
23
  uploadArtifact(artifact: ArtifactToUpload, file: Buffer): Promise<AxiosResponse | void>;
24
24
  streamArtifact(artifact: ArtifactToUpload, fileStream: any): Promise<AxiosResponse | void>;
25
25
  confirmArtifactUpload(artifactId: string): Promise<AxiosResponse | void>;
26
+ /**
27
+ * Destroys a stream to prevent resource leaks.
28
+ * @param {any} fileStream - The axios response stream to destroy
29
+ */
30
+ private destroyStream;
26
31
  getAttachmentsFromArtifactId({ artifact, }: {
27
32
  artifact: string;
28
33
  }): Promise<{
@@ -1 +1 @@
1
- {"version":3,"file":"uploader.d.ts","sourceRoot":"","sources":["../../src/uploader/uploader.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAG/D,OAAO,EAEL,cAAc,EACd,wBAAwB,EACxB,gBAAgB,EACjB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAEtC,qBAAa,QAAQ;IACnB,OAAO,CAAC,KAAK,CAAe;IAC5B,OAAO,CAAC,kBAAkB,CAAC,CAAU;IACrC,OAAO,CAAC,iBAAiB,CAAS;IAClC,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,cAAc,CAAyB;gBAEnC,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,wBAAwB;IAWxD;;;;;;;;OAQG;IACG,MAAM,CACV,QAAQ,EAAE,MAAM,EAChB,cAAc,EAAE,MAAM,EAAE,GAAG,MAAM,GAChC,OAAO,CAAC,cAAc,CAAC;IAwDpB,oBAAoB,CACxB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAuB7B,cAAc,CAClB,QAAQ,EAAE,gBAAgB,EAC1B,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAmB1B,cAAc,CAClB,QAAQ,EAAE,gBAAgB,EAC1B,UAAU,EAAE,GAAG,GACd,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAkC1B,qBAAqB,CACzB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAwB1B,4BAA4B,CAAC,EACjC,QAAQ,GACT,EAAE;QACD,QAAQ,EAAE,MAAM,CAAC;KAClB,GAAG,OAAO,CAAC;QACV,WAAW,CAAC,EAAE,oBAAoB,EAAE,CAAC;QACrC,KAAK,CAAC,EAAE;YAAE,OAAO,EAAE,MAAM,CAAA;SAAE,CAAC;KAC7B,CAAC;YAqCY,sBAAsB;YAyBtB,gBAAgB;IAe9B,OAAO,CAAC,YAAY;IAQpB,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,UAAU;IASZ,yBAAyB,CAAC,EAC9B,UAAU,EACV,SAAiB,GAClB,EAAE;QACD,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,CAAC,EAAE,OAAO,CAAC;KACrB,GAAG,OAAO,CAAC,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CAAC;YAyBvB,eAAe;CA8B9B"}
1
+ {"version":3,"file":"uploader.d.ts","sourceRoot":"","sources":["../../src/uploader/uploader.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAG/D,OAAO,EAEL,cAAc,EACd,wBAAwB,EACxB,gBAAgB,EACjB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAEtC,qBAAa,QAAQ;IACnB,OAAO,CAAC,KAAK,CAAe;IAC5B,OAAO,CAAC,kBAAkB,CAAC,CAAU;IACrC,OAAO,CAAC,iBAAiB,CAAS;IAClC,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,cAAc,CAAyB;gBAEnC,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,wBAAwB;IAWxD;;;;;;;;OAQG;IACG,MAAM,CACV,QAAQ,EAAE,MAAM,EAChB,cAAc,EAAE,MAAM,EAAE,GAAG,MAAM,GAChC,OAAO,CAAC,cAAc,CAAC;IAwDpB,oBAAoB,CACxB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAuB7B,cAAc,CAClB,QAAQ,EAAE,gBAAgB,EAC1B,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAmB1B,cAAc,CAClB,QAAQ,EAAE,gBAAgB,EAC1B,UAAU,EAAE,GAAG,GACd,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAoC1B,qBAAqB,CACzB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAwBhC;;;OAGG;IACH,OAAO,CAAC,aAAa;IAef,4BAA4B,CAAC,EACjC,QAAQ,GACT,EAAE;QACD,QAAQ,EAAE,MAAM,CAAC;KAClB,GAAG,OAAO,CAAC;QACV,WAAW,CAAC,EAAE,oBAAoB,EAAE,CAAC;QACrC,KAAK,CAAC,EAAE;YAAE,OAAO,EAAE,MAAM,CAAA;SAAE,CAAC;KAC7B,CAAC;YAqCY,sBAAsB;YAyBtB,gBAAgB;IAe9B,OAAO,CAAC,YAAY;IAQpB,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,UAAU;IASZ,yBAAyB,CAAC,EAC9B,UAAU,EACV,SAAiB,GAClB,EAAE;QACD,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,CAAC,EAAE,OAAO,CAAC;KACrB,GAAG,OAAO,CAAC,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CAAC;YAyBvB,eAAe;CA8B9B"}
@@ -148,6 +148,7 @@ class Uploader {
148
148
  formData.append('file', fileStream.data);
149
149
  if (fileStream.headers['content-length'] > constants_1.MAX_DEVREV_ARTIFACT_SIZE) {
150
150
  console.warn(`File size exceeds the maximum limit of ${constants_1.MAX_DEVREV_ARTIFACT_SIZE} bytes.`);
151
+ this.destroyStream(fileStream);
151
152
  return;
152
153
  }
153
154
  try {
@@ -164,6 +165,7 @@ class Uploader {
164
165
  }
165
166
  catch (error) {
166
167
  console.error('Error while streaming artifact.', (0, logger_1.serializeError)(error));
168
+ this.destroyStream(fileStream);
167
169
  return;
168
170
  }
169
171
  }
@@ -182,6 +184,26 @@ class Uploader {
182
184
  console.error('Error while confirming artifact upload.', (0, logger_1.serializeError)(error));
183
185
  }
184
186
  }
187
+ /**
188
+ * Destroys a stream to prevent resource leaks.
189
+ * @param {any} fileStream - The axios response stream to destroy
190
+ */
191
+ destroyStream(fileStream) {
192
+ try {
193
+ if (fileStream && fileStream.data) {
194
+ // For axios response streams, the data property contains the actual stream
195
+ if (typeof fileStream.data.destroy === 'function') {
196
+ fileStream.data.destroy();
197
+ }
198
+ else if (typeof fileStream.data.close === 'function') {
199
+ fileStream.data.close();
200
+ }
201
+ }
202
+ }
203
+ catch (error) {
204
+ console.warn('Error while destroying stream:', (0, logger_1.serializeError)(error));
205
+ }
206
+ }
185
207
  async getAttachmentsFromArtifactId({ artifact, }) {
186
208
  // Get the URL of the attachments metadata artifact
187
209
  const artifactUrl = await this.getArtifactDownloadUrl(artifact);
@@ -6,10 +6,28 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const axios_1 = __importDefault(require("axios"));
7
7
  const index_1 = require("../../index");
8
8
  const axios_client_internal_1 = require("../../http/axios-client-internal");
9
+ const constants_1 = require("../../common/constants");
9
10
  const getAttachmentStream = async ({ item, }) => {
10
11
  const { id, url } = item;
12
+ let fileStreamResponse = null;
11
13
  try {
12
- const fileStreamResponse = await axios_client_internal_1.axiosClient.get(url, {
14
+ // First, check file size with HEAD request to avoid downloading large files
15
+ const headResponse = await axios_client_internal_1.axiosClient.head(url, {
16
+ headers: {
17
+ 'Accept-Encoding': 'identity',
18
+ },
19
+ });
20
+ const contentLength = headResponse.headers['content-length'];
21
+ if (contentLength && parseInt(contentLength) > constants_1.MAX_DEVREV_ARTIFACT_SIZE) {
22
+ console.warn(`Attachment ${id} size (${contentLength} bytes) exceeds maximum limit of ${constants_1.MAX_DEVREV_ARTIFACT_SIZE} bytes. Skipping download.`);
23
+ return {
24
+ error: {
25
+ message: `File size exceeds maximum limit of ${constants_1.MAX_DEVREV_ARTIFACT_SIZE} bytes.`,
26
+ },
27
+ };
28
+ }
29
+ // If size is acceptable, proceed with streaming
30
+ fileStreamResponse = await axios_client_internal_1.axiosClient.get(url, {
13
31
  responseType: 'stream',
14
32
  headers: {
15
33
  'Accept-Encoding': 'identity',
@@ -18,6 +36,10 @@ const getAttachmentStream = async ({ item, }) => {
18
36
  return { httpStream: fileStreamResponse };
19
37
  }
20
38
  catch (error) {
39
+ // If we created a stream but failed afterwards, destroy it
40
+ if (fileStreamResponse) {
41
+ destroyHttpStream(fileStreamResponse);
42
+ }
21
43
  if (axios_1.default.isAxiosError(error)) {
22
44
  console.warn(`Error while fetching attachment ${id} from URL.`, (0, index_1.serializeAxiosError)(error));
23
45
  console.warn('Failed attachment metadata', item);
@@ -33,6 +55,25 @@ const getAttachmentStream = async ({ item, }) => {
33
55
  };
34
56
  }
35
57
  };
58
+ /**
59
+ * Destroys a stream to prevent memory leaks.
60
+ * @param {any} httpStream - The axios response stream to destroy
61
+ */
62
+ const destroyHttpStream = (httpStream) => {
63
+ try {
64
+ if (httpStream && httpStream.data) {
65
+ if (typeof httpStream.data.destroy === 'function') {
66
+ httpStream.data.destroy();
67
+ }
68
+ else if (typeof httpStream.data.close === 'function') {
69
+ httpStream.data.close();
70
+ }
71
+ }
72
+ }
73
+ catch (error) {
74
+ console.warn('Error while destroying HTTP stream:', error);
75
+ }
76
+ };
36
77
  (0, index_1.processTask)({
37
78
  task: async ({ adapter }) => {
38
79
  try {
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=worker-adapter.artifacts.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker-adapter.artifacts.test.d.ts","sourceRoot":"","sources":["../../src/workers/worker-adapter.artifacts.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,135 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const test_helpers_1 = require("../tests/test-helpers");
4
+ const worker_adapter_1 = require("./worker-adapter");
5
+ const state_1 = require("../state/state");
6
+ const types_1 = require("../types");
7
+ // 1. Create a mock function for the method you want to override.
8
+ const mockUpload = (itemType, objects) => {
9
+ return {
10
+ error: null,
11
+ artifact: {
12
+ id: `artifact-${itemType}-${Math.random().toString(36).substring(2, 15)}`,
13
+ item_type: itemType,
14
+ item_count: objects.length,
15
+ }
16
+ };
17
+ };
18
+ // 2. Mock the entire 'uploader' module.
19
+ // The factory function () => { ... } returns the mock implementation.
20
+ jest.mock('../uploader/uploader', () => {
21
+ return {
22
+ // The mocked Uploader class
23
+ Uploader: jest.fn().mockImplementation(() => {
24
+ // The constructor of the mocked Uploader returns an object
25
+ // with the methods you want to control.
26
+ return {
27
+ upload: mockUpload,
28
+ };
29
+ }),
30
+ };
31
+ });
32
+ function checkArtifactOrder(artifacts, expectedOrder) {
33
+ let outerIndex = 0;
34
+ for (const artifact of artifacts) {
35
+ try {
36
+ // Always increase outer index. If items are out of order, the array will overflow and exception will be thrown
37
+ while (artifact.item_type != expectedOrder[outerIndex].itemType) {
38
+ outerIndex++;
39
+ }
40
+ }
41
+ catch (e) {
42
+ console.error("Error finding artifact type in repos:", e);
43
+ return false;
44
+ }
45
+ }
46
+ return true;
47
+ }
48
+ describe("Artifact ordering when artifacts overflow batch sizes in repositories", () => {
49
+ let testAdapter;
50
+ beforeEach(() => {
51
+ // Create a fresh adapter instance for this test to avoid mocking conflicts
52
+ let mockEvent = (0, test_helpers_1.createEvent)({ eventType: types_1.EventType.ExtractionDataStart });
53
+ let mockAdapterState = new state_1.State({
54
+ event: mockEvent,
55
+ initialState: { attachments: { completed: false } },
56
+ });
57
+ testAdapter = new worker_adapter_1.WorkerAdapter({
58
+ event: mockEvent,
59
+ adapterState: mockAdapterState,
60
+ options: {
61
+ batchSize: 50
62
+ }
63
+ });
64
+ });
65
+ it('should maintain artifact ordering when repo ItemTypeA has items below batch size and repo ItemTypeB has items above batch size', async () => {
66
+ var _a, _b;
67
+ const repos = [
68
+ { itemType: 'ItemTypeA' },
69
+ { itemType: 'ItemTypeB' }
70
+ ];
71
+ // Initialize repos
72
+ testAdapter.initializeRepos(repos);
73
+ await ((_a = testAdapter.getRepo('ItemTypeA')) === null || _a === void 0 ? void 0 : _a.push((0, test_helpers_1.createItems)(5)));
74
+ await ((_b = testAdapter.getRepo('ItemTypeB')) === null || _b === void 0 ? void 0 : _b.push((0, test_helpers_1.createItems)(105)));
75
+ await testAdapter.uploadAllRepos();
76
+ const artifacts = testAdapter.artifacts;
77
+ expect(artifacts.length).toBe(4);
78
+ expect(checkArtifactOrder(artifacts, repos)).toBe(true);
79
+ });
80
+ it('should work with more than 2 repos', async () => {
81
+ var _a, _b, _c, _d;
82
+ const repos = [
83
+ { itemType: 'ItemTypeA' },
84
+ { itemType: 'ItemTypeB' },
85
+ { itemType: 'ItemTypeC' },
86
+ { itemType: 'ItemTypeD' },
87
+ ];
88
+ // Initialize repos
89
+ testAdapter.initializeRepos(repos);
90
+ await ((_a = testAdapter.getRepo('ItemTypeA')) === null || _a === void 0 ? void 0 : _a.push((0, test_helpers_1.createItems)(101)));
91
+ await ((_b = testAdapter.getRepo('ItemTypeB')) === null || _b === void 0 ? void 0 : _b.push((0, test_helpers_1.createItems)(102)));
92
+ await ((_c = testAdapter.getRepo('ItemTypeC')) === null || _c === void 0 ? void 0 : _c.push((0, test_helpers_1.createItems)(103)));
93
+ await ((_d = testAdapter.getRepo('ItemTypeD')) === null || _d === void 0 ? void 0 : _d.push((0, test_helpers_1.createItems)(104)));
94
+ await testAdapter.uploadAllRepos();
95
+ const artifacts = testAdapter.artifacts;
96
+ expect(artifacts.length).toBe(12);
97
+ expect(checkArtifactOrder(artifacts, repos)).toBe(true);
98
+ });
99
+ it('should maintain order with multiple pushes and uploads', async () => {
100
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
101
+ const repos = [
102
+ { itemType: 'ItemTypeA' },
103
+ { itemType: 'ItemTypeB' },
104
+ ];
105
+ // Initialize repos
106
+ testAdapter.initializeRepos(repos);
107
+ await ((_a = testAdapter.getRepo('ItemTypeA')) === null || _a === void 0 ? void 0 : _a.push((0, test_helpers_1.createItems)(101)));
108
+ await ((_b = testAdapter.getRepo('ItemTypeB')) === null || _b === void 0 ? void 0 : _b.push((0, test_helpers_1.createItems)(102)));
109
+ await ((_c = testAdapter.getRepo('ItemTypeA')) === null || _c === void 0 ? void 0 : _c.push((0, test_helpers_1.createItems)(101)));
110
+ await ((_d = testAdapter.getRepo('ItemTypeB')) === null || _d === void 0 ? void 0 : _d.push((0, test_helpers_1.createItems)(102)));
111
+ await ((_e = testAdapter.getRepo('ItemTypeA')) === null || _e === void 0 ? void 0 : _e.upload());
112
+ await ((_f = testAdapter.getRepo('ItemTypeB')) === null || _f === void 0 ? void 0 : _f.upload());
113
+ await ((_g = testAdapter.getRepo('ItemTypeA')) === null || _g === void 0 ? void 0 : _g.push((0, test_helpers_1.createItems)(101)));
114
+ await ((_h = testAdapter.getRepo('ItemTypeB')) === null || _h === void 0 ? void 0 : _h.push((0, test_helpers_1.createItems)(102)));
115
+ await ((_j = testAdapter.getRepo('ItemTypeA')) === null || _j === void 0 ? void 0 : _j.push((0, test_helpers_1.createItems)(101)));
116
+ await ((_k = testAdapter.getRepo('ItemTypeB')) === null || _k === void 0 ? void 0 : _k.push((0, test_helpers_1.createItems)(102)));
117
+ await testAdapter.uploadAllRepos();
118
+ const artifacts = testAdapter.artifacts;
119
+ expect(artifacts.length).toBe(20);
120
+ expect(checkArtifactOrder(artifacts, repos)).toBe(true);
121
+ });
122
+ it('should not count artifacts if 0 items are pushed to the repo', async () => {
123
+ var _a;
124
+ const repos = [
125
+ { itemType: 'ItemTypeA' }
126
+ ];
127
+ // Initialize repos
128
+ testAdapter.initializeRepos(repos);
129
+ await ((_a = testAdapter.getRepo('ItemTypeA')) === null || _a === void 0 ? void 0 : _a.push([]));
130
+ await testAdapter.uploadAllRepos();
131
+ const artifacts = testAdapter.artifacts;
132
+ expect(artifacts.length).toBe(0);
133
+ expect(checkArtifactOrder(artifacts, repos)).toBe(true);
134
+ });
135
+ });
@@ -67,6 +67,11 @@ export declare class WorkerAdapter<ConnectorState> {
67
67
  itemTypeToLoad: ItemTypeToLoad;
68
68
  }): Promise<LoadItemResponse>;
69
69
  processAttachment(attachment: NormalizedAttachment, stream: ExternalSystemAttachmentStreamingFunction): Promise<ProcessAttachmentReturnType>;
70
+ /**
71
+ * Destroys a stream to prevent memory leaks.
72
+ * @param {any} httpStream - The axios response stream to destroy
73
+ */
74
+ private destroyHttpStream;
70
75
  loadAttachment({ item, create, }: {
71
76
  item: ExternalSystemAttachment;
72
77
  create: ExternalSystemLoadingFunction<ExternalSystemAttachment>;
@@ -1 +1 @@
1
- {"version":3,"file":"worker-adapter.d.ts","sourceRoot":"","sources":["../../src/workers/worker-adapter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"worker-adapter.d.ts","sourceRoot":"","sources":["../../src/workers/worker-adapter.ts"],"names":[],"mappings":"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"}
@@ -85,7 +85,6 @@ class WorkerAdapter {
85
85
  repo.itemType !== constants_1.AIRDROP_DEFAULT_ITEM_TYPES.SSOR_ATTACHMENT;
86
86
  return new repo_1.Repo(Object.assign(Object.assign({ event: this.event, itemType: repo.itemType }, (shouldNormalize && { normalize: repo.normalize })), { onUpload: (artifact) => {
87
87
  var _a;
88
- this.artifacts.push(artifact);
89
88
  // We need to store artifacts ids in state for later use when streaming attachments
90
89
  if (repo.itemType === constants_1.AIRDROP_DEFAULT_ITEM_TYPES.ATTACHMENTS) {
91
90
  (_a = this.state.toDevRev) === null || _a === void 0 ? void 0 : _a.attachmentsMetadata.artifactIds.push(artifact.id);
@@ -180,6 +179,7 @@ class WorkerAdapter {
180
179
  async uploadAllRepos() {
181
180
  for (const repo of this.repos) {
182
181
  const error = await repo.upload();
182
+ this.artifacts.push(...repo.uploadedArtifacts);
183
183
  if (error) {
184
184
  throw error;
185
185
  }
@@ -514,9 +514,11 @@ class WorkerAdapter {
514
514
  const preparedArtifact = await this.uploader.getArtifactUploadUrl(attachment.file_name, fileType);
515
515
  if (!preparedArtifact) {
516
516
  console.warn(`Error while preparing artifact for attachment ID ${attachment.id}. Skipping attachment.`);
517
+ this.destroyHttpStream(httpStream);
517
518
  return;
518
519
  }
519
520
  if (this.isTimeout) {
521
+ this.destroyHttpStream(httpStream);
520
522
  return;
521
523
  }
522
524
  // Stream attachment
@@ -557,6 +559,25 @@ class WorkerAdapter {
557
559
  }
558
560
  return;
559
561
  }
562
+ /**
563
+ * Destroys a stream to prevent memory leaks.
564
+ * @param {any} httpStream - The axios response stream to destroy
565
+ */
566
+ destroyHttpStream(httpStream) {
567
+ try {
568
+ if (httpStream && httpStream.data) {
569
+ if (typeof httpStream.data.destroy === 'function') {
570
+ httpStream.data.destroy();
571
+ }
572
+ else if (typeof httpStream.data.close === 'function') {
573
+ httpStream.data.close();
574
+ }
575
+ }
576
+ }
577
+ catch (error) {
578
+ console.warn('Error while destroying HTTP stream:', error);
579
+ }
580
+ }
560
581
  async loadAttachment({ item, create, }) {
561
582
  // Create item
562
583
  const { id, delay, error } = await create({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devrev/ts-adaas",
3
- "version": "1.10.0",
3
+ "version": "1.10.1-beta.2",
4
4
  "description": "Typescript library containing the ADaaS(AirDrop as a Service) control protocol.",
5
5
  "type": "commonjs",
6
6
  "main": "./dist/index.js",
@@ -38,17 +38,16 @@
38
38
  "eslint-config-prettier": "^10.1.5",
39
39
  "eslint-plugin-prettier": "^5.1.3",
40
40
  "jest": "^29.7.0",
41
- "ts-jest": "^29.3.3"
41
+ "ts-jest": "^29.4.4",
42
+ "ts-node": "^10.9.2",
43
+ "typescript": "^5.3.3"
42
44
  },
43
45
  "dependencies": {
44
46
  "@devrev/typescript-sdk": "^1.1.59",
45
47
  "axios": "^1.12.1",
46
- "@microsoft/api-extractor": "^7.52.11",
47
48
  "axios-retry": "^4.5.0",
48
49
  "form-data": "^4.0.4",
49
50
  "js-jsonl": "^1.1.1",
50
- "ts-node": "^10.9.2",
51
- "typescript": "^5.3.3",
52
51
  "yargs": "^17.7.2"
53
52
  },
54
53
  "files": [