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

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 (198) hide show
  1. package/README.md +5 -11
  2. package/dist/attachments-streaming/attachments-streaming-pool.d.ts +2 -10
  3. package/dist/attachments-streaming/attachments-streaming-pool.d.ts.map +1 -1
  4. package/dist/attachments-streaming/attachments-streaming-pool.interfaces.d.ts +2 -7
  5. package/dist/attachments-streaming/attachments-streaming-pool.interfaces.d.ts.map +1 -1
  6. package/dist/attachments-streaming/attachments-streaming-pool.js +15 -43
  7. package/dist/common/constants.d.ts +1 -0
  8. package/dist/common/constants.d.ts.map +1 -1
  9. package/dist/common/constants.js +2 -1
  10. package/dist/common/helpers.d.ts +0 -14
  11. package/dist/common/helpers.d.ts.map +1 -1
  12. package/dist/common/helpers.js +0 -36
  13. package/dist/http/{axios-client-internal.d.ts → client.d.ts} +1 -1
  14. package/dist/http/client.d.ts.map +1 -0
  15. package/dist/index.d.ts +22 -11
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +46 -28
  18. package/dist/logger/logger.d.ts +14 -0
  19. package/dist/logger/logger.d.ts.map +1 -1
  20. package/dist/logger/logger.js +55 -8
  21. package/dist/mappers/mappers.d.ts +9 -10
  22. package/dist/mappers/mappers.d.ts.map +1 -1
  23. package/dist/mappers/{mappers.interface.d.ts → mappers.interfaces.d.ts} +5 -5
  24. package/dist/mappers/mappers.interfaces.d.ts.map +1 -0
  25. package/dist/mappers/{mappers.interface.js → mappers.interfaces.js} +3 -3
  26. package/dist/mappers/mappers.js +13 -9
  27. package/dist/multithreading/adapters/base-adapter.d.ts +23 -8
  28. package/dist/multithreading/adapters/base-adapter.d.ts.map +1 -1
  29. package/dist/multithreading/adapters/base-adapter.js +41 -8
  30. package/dist/multithreading/adapters/extraction-adapter.d.ts +8 -9
  31. package/dist/multithreading/adapters/extraction-adapter.d.ts.map +1 -1
  32. package/dist/multithreading/adapters/extraction-adapter.js +24 -26
  33. package/dist/multithreading/adapters/loading-adapter.d.ts +7 -7
  34. package/dist/multithreading/adapters/loading-adapter.d.ts.map +1 -1
  35. package/dist/multithreading/adapters/loading-adapter.js +53 -83
  36. package/dist/{common/control-protocol.d.ts → multithreading/emit.d.ts} +1 -1
  37. package/dist/multithreading/emit.d.ts.map +1 -0
  38. package/dist/{common/control-protocol.js → multithreading/emit.js} +3 -3
  39. package/dist/multithreading/process-task.d.ts.map +1 -1
  40. package/dist/multithreading/process-task.js +26 -9
  41. package/dist/multithreading/spawn/spawn.helpers.d.ts +23 -3
  42. package/dist/multithreading/spawn/spawn.helpers.d.ts.map +1 -1
  43. package/dist/multithreading/spawn/spawn.helpers.js +152 -2
  44. package/dist/multithreading/spawn/spawn.js +7 -7
  45. package/dist/multithreading/worker.js +1 -2
  46. package/dist/repo/repo.js +2 -2
  47. package/dist/state/base-state.d.ts +5 -5
  48. package/dist/state/base-state.d.ts.map +1 -1
  49. package/dist/state/base-state.js +7 -7
  50. package/dist/state/extraction-state.d.ts +9 -9
  51. package/dist/state/extraction-state.d.ts.map +1 -1
  52. package/dist/state/extraction-state.js +10 -10
  53. package/dist/state/install-initial-domain-mapping.d.ts.map +1 -0
  54. package/dist/{common → state}/install-initial-domain-mapping.js +4 -4
  55. package/dist/state/loading-state.d.ts +7 -8
  56. package/dist/state/loading-state.d.ts.map +1 -1
  57. package/dist/state/loading-state.js +6 -7
  58. package/dist/state/state.d.ts +4 -0
  59. package/dist/state/state.d.ts.map +1 -0
  60. package/dist/state/state.interfaces.d.ts +28 -18
  61. package/dist/state/state.interfaces.d.ts.map +1 -1
  62. package/dist/state/state.interfaces.js +13 -6
  63. package/dist/state/state.js +11 -0
  64. package/dist/{common → state}/time-value-resolver.d.ts +6 -7
  65. package/dist/state/time-value-resolver.d.ts.map +1 -0
  66. package/dist/{common → state}/time-value-resolver.js +9 -8
  67. package/dist/{common/test-utils.d.ts → testing/mock-event.d.ts} +1 -2
  68. package/dist/testing/mock-event.d.ts.map +1 -0
  69. package/dist/{common/test-utils.js → testing/mock-event.js} +14 -3
  70. package/dist/{mock-server → testing}/mock-server.d.ts +5 -0
  71. package/dist/testing/mock-server.d.ts.map +1 -0
  72. package/dist/testing/mock-server.interfaces.d.ts.map +1 -0
  73. package/dist/{mock-server → testing}/mock-server.js +6 -1
  74. package/dist/types/errors.d.ts +9 -0
  75. package/dist/types/errors.d.ts.map +1 -0
  76. package/dist/types/extraction.d.ts +70 -15
  77. package/dist/types/extraction.d.ts.map +1 -1
  78. package/dist/types/extraction.js +4 -6
  79. package/dist/types/loading.d.ts +1 -2
  80. package/dist/types/loading.d.ts.map +1 -1
  81. package/dist/types/loading.js +0 -1
  82. package/dist/types/workers.d.ts +66 -23
  83. package/dist/types/workers.d.ts.map +1 -1
  84. package/dist/uploader/uploader.d.ts +5 -4
  85. package/dist/uploader/uploader.d.ts.map +1 -1
  86. package/dist/uploader/uploader.interfaces.d.ts +1 -1
  87. package/dist/uploader/uploader.js +10 -10
  88. package/package.json +3 -3
  89. package/dist/airsync-sdk.d.ts +0 -2059
  90. package/dist/attachments-streaming/attachments-streaming-pool.test.d.ts +0 -2
  91. package/dist/attachments-streaming/attachments-streaming-pool.test.d.ts.map +0 -1
  92. package/dist/attachments-streaming/attachments-streaming-pool.test.js +0 -540
  93. package/dist/common/control-protocol.d.ts.map +0 -1
  94. package/dist/common/errors.d.ts +0 -6
  95. package/dist/common/errors.d.ts.map +0 -1
  96. package/dist/common/install-initial-domain-mapping.d.ts.map +0 -1
  97. package/dist/common/install-initial-domain-mapping.test.d.ts +0 -2
  98. package/dist/common/install-initial-domain-mapping.test.d.ts.map +0 -1
  99. package/dist/common/install-initial-domain-mapping.test.js +0 -211
  100. package/dist/common/test-utils.d.ts.map +0 -1
  101. package/dist/common/time-value-resolver.d.ts.map +0 -1
  102. package/dist/common/time-value-resolver.test.d.ts +0 -2
  103. package/dist/common/time-value-resolver.test.d.ts.map +0 -1
  104. package/dist/common/time-value-resolver.test.js +0 -268
  105. package/dist/http/axios-client-internal.d.ts.map +0 -1
  106. package/dist/http/axios-client-internal.test.d.ts +0 -2
  107. package/dist/http/axios-client-internal.test.d.ts.map +0 -1
  108. package/dist/http/axios-client-internal.test.js +0 -175
  109. package/dist/http/axios-client.d.ts +0 -27
  110. package/dist/http/axios-client.d.ts.map +0 -1
  111. package/dist/http/axios-client.js +0 -60
  112. package/dist/http/constants.d.ts +0 -4
  113. package/dist/http/constants.d.ts.map +0 -1
  114. package/dist/http/constants.js +0 -6
  115. package/dist/http/index.d.ts +0 -2
  116. package/dist/http/index.d.ts.map +0 -1
  117. package/dist/http/index.js +0 -17
  118. package/dist/logger/logger.constants.d.ts +0 -6
  119. package/dist/logger/logger.constants.d.ts.map +0 -1
  120. package/dist/logger/logger.constants.js +0 -13
  121. package/dist/logger/logger.context.d.ts +0 -58
  122. package/dist/logger/logger.context.d.ts.map +0 -1
  123. package/dist/logger/logger.context.js +0 -86
  124. package/dist/logger/logger.test.d.ts +0 -2
  125. package/dist/logger/logger.test.d.ts.map +0 -1
  126. package/dist/logger/logger.test.js +0 -537
  127. package/dist/mappers/mappers.interface.d.ts.map +0 -1
  128. package/dist/mappers/mappers.test.d.ts +0 -2
  129. package/dist/mappers/mappers.test.d.ts.map +0 -1
  130. package/dist/mappers/mappers.test.js +0 -105
  131. package/dist/mock-server/mock-server.d.ts.map +0 -1
  132. package/dist/mock-server/mock-server.interfaces.d.ts.map +0 -1
  133. package/dist/multithreading/adapters/base-adapter.emit.test.d.ts +0 -2
  134. package/dist/multithreading/adapters/base-adapter.emit.test.d.ts.map +0 -1
  135. package/dist/multithreading/adapters/base-adapter.emit.test.js +0 -403
  136. package/dist/multithreading/adapters/extraction-adapter.artifacts.test.d.ts +0 -2
  137. package/dist/multithreading/adapters/extraction-adapter.artifacts.test.d.ts.map +0 -1
  138. package/dist/multithreading/adapters/extraction-adapter.artifacts.test.js +0 -175
  139. package/dist/multithreading/adapters/extraction-adapter.test.d.ts +0 -2
  140. package/dist/multithreading/adapters/extraction-adapter.test.d.ts.map +0 -1
  141. package/dist/multithreading/adapters/extraction-adapter.test.js +0 -789
  142. package/dist/multithreading/adapters/loading-adapter.helpers.test.d.ts +0 -2
  143. package/dist/multithreading/adapters/loading-adapter.helpers.test.d.ts.map +0 -1
  144. package/dist/multithreading/adapters/loading-adapter.helpers.test.js +0 -514
  145. package/dist/multithreading/adapters/loading-adapter.test.d.ts +0 -2
  146. package/dist/multithreading/adapters/loading-adapter.test.d.ts.map +0 -1
  147. package/dist/multithreading/adapters/loading-adapter.test.js +0 -589
  148. package/dist/multithreading/adapters/serialization.test.d.ts +0 -2
  149. package/dist/multithreading/adapters/serialization.test.d.ts.map +0 -1
  150. package/dist/multithreading/adapters/serialization.test.js +0 -71
  151. package/dist/multithreading/create-worker.test.d.ts +0 -2
  152. package/dist/multithreading/create-worker.test.d.ts.map +0 -1
  153. package/dist/multithreading/create-worker.test.js +0 -108
  154. package/dist/multithreading/process-task.test.d.ts +0 -2
  155. package/dist/multithreading/process-task.test.d.ts.map +0 -1
  156. package/dist/multithreading/process-task.test.js +0 -146
  157. package/dist/multithreading/spawn/spawn.helpers.test.d.ts +0 -2
  158. package/dist/multithreading/spawn/spawn.helpers.test.d.ts.map +0 -1
  159. package/dist/multithreading/spawn/spawn.helpers.test.js +0 -293
  160. package/dist/multithreading/spawn/spawn.test.d.ts +0 -2
  161. package/dist/multithreading/spawn/spawn.test.d.ts.map +0 -1
  162. package/dist/multithreading/spawn/spawn.test.js +0 -232
  163. package/dist/repo/repo.test.d.ts +0 -2
  164. package/dist/repo/repo.test.d.ts.map +0 -1
  165. package/dist/repo/repo.test.js +0 -184
  166. package/dist/state/state.extract-window.test.d.ts +0 -2
  167. package/dist/state/state.extract-window.test.d.ts.map +0 -1
  168. package/dist/state/state.extract-window.test.js +0 -163
  169. package/dist/state/state.pending-boundaries.test.d.ts +0 -2
  170. package/dist/state/state.pending-boundaries.test.d.ts.map +0 -1
  171. package/dist/state/state.pending-boundaries.test.js +0 -189
  172. package/dist/state/state.post-state.test.d.ts +0 -2
  173. package/dist/state/state.post-state.test.d.ts.map +0 -1
  174. package/dist/state/state.post-state.test.js +0 -78
  175. package/dist/state/state.test.d.ts +0 -2
  176. package/dist/state/state.test.d.ts.map +0 -1
  177. package/dist/state/state.test.js +0 -271
  178. package/dist/state/state.time-value-resolution.test.d.ts +0 -2
  179. package/dist/state/state.time-value-resolution.test.d.ts.map +0 -1
  180. package/dist/state/state.time-value-resolution.test.js +0 -175
  181. package/dist/tsdoc-metadata.json +0 -11
  182. package/dist/types/extraction.test.d.ts +0 -2
  183. package/dist/types/extraction.test.d.ts.map +0 -1
  184. package/dist/types/extraction.test.js +0 -96
  185. package/dist/types/index.d.ts +0 -10
  186. package/dist/types/index.d.ts.map +0 -1
  187. package/dist/types/index.js +0 -21
  188. package/dist/uploader/uploader.helpers.test.d.ts +0 -2
  189. package/dist/uploader/uploader.helpers.test.d.ts.map +0 -1
  190. package/dist/uploader/uploader.helpers.test.js +0 -256
  191. package/dist/uploader/uploader.test.d.ts +0 -2
  192. package/dist/uploader/uploader.test.d.ts.map +0 -1
  193. package/dist/uploader/uploader.test.js +0 -601
  194. /package/dist/http/{axios-client-internal.js → client.js} +0 -0
  195. /package/dist/{common → state}/install-initial-domain-mapping.d.ts +0 -0
  196. /package/dist/{mock-server → testing}/mock-server.interfaces.d.ts +0 -0
  197. /package/dist/{mock-server → testing}/mock-server.interfaces.js +0 -0
  198. /package/dist/{common → types}/errors.js +0 -0
@@ -1,601 +0,0 @@
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 form_data_1 = __importDefault(require("form-data"));
7
- const js_jsonl_1 = require("js-jsonl");
8
- const zlib_1 = __importDefault(require("zlib"));
9
- const axios_client_internal_1 = require("../http/axios-client-internal");
10
- const test_helpers_1 = require("../tests/test-helpers");
11
- const jest_setup_1 = require("../tests/jest.setup");
12
- const test_utils_1 = require("../common/test-utils");
13
- const uploader_helpers_1 = require("./uploader.helpers");
14
- const uploader_1 = require("./uploader");
15
- jest.mock('../http/axios-client-internal');
16
- jest.mock('./uploader.helpers', () => (Object.assign(Object.assign({}, jest.requireActual('./uploader.helpers')), { downloadToLocal: jest.fn(), compressGzip: jest.fn(jest.requireActual('./uploader.helpers').compressGzip) })));
17
- const mockedAxiosClient = jest.mocked(axios_client_internal_1.axiosClient);
18
- const mockedDownloadToLocal = jest.mocked(uploader_helpers_1.downloadToLocal);
19
- const mockedCompressGzip = jest.mocked(uploader_helpers_1.compressGzip);
20
- describe(uploader_1.Uploader.name, () => {
21
- const mockEvent = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl);
22
- let uploader;
23
- beforeEach(() => {
24
- uploader = new uploader_1.Uploader({ event: mockEvent });
25
- });
26
- afterEach(() => {
27
- jest.clearAllMocks();
28
- });
29
- describe(uploader_1.Uploader.prototype.upload.name, () => {
30
- const mockArtifactUploadUrlResponse = {
31
- data: (0, test_helpers_1.createArtifact)(),
32
- };
33
- it('should return artifact info when upload flow succeeds', async () => {
34
- // Arrange
35
- const itemType = 'tasks';
36
- const fetchedObjects = [
37
- { id: 1, name: 'Task 1' },
38
- { id: 2, name: 'Task 2' },
39
- ];
40
- mockedAxiosClient.get.mockResolvedValueOnce(mockArtifactUploadUrlResponse);
41
- mockedAxiosClient.post.mockResolvedValue((0, test_helpers_1.createAxiosResponse)());
42
- // Act
43
- const result = await uploader.upload(itemType, fetchedObjects);
44
- // Assert
45
- expect(result).toEqual({
46
- artifact: {
47
- id: 'art_123',
48
- item_type: itemType,
49
- item_count: 2,
50
- },
51
- });
52
- expect(result.error).toBeUndefined();
53
- });
54
- it('should report item_count as 1 when uploading single object', async () => {
55
- var _a;
56
- // Arrange
57
- const itemType = 'metadata';
58
- const fetchedObject = { key: 'value' };
59
- mockedAxiosClient.get.mockResolvedValueOnce(mockArtifactUploadUrlResponse);
60
- mockedAxiosClient.post.mockResolvedValue((0, test_helpers_1.createAxiosResponse)());
61
- // Act
62
- const result = await uploader.upload(itemType, fetchedObject);
63
- // Assert
64
- expect((_a = result.artifact) === null || _a === void 0 ? void 0 : _a.item_count).toBe(1);
65
- expect(result.error).toBeUndefined();
66
- });
67
- it('should call downloadToLocal when isLocalDevelopment is true', async () => {
68
- // Arrange
69
- const localUploader = new uploader_1.Uploader({
70
- event: mockEvent,
71
- options: { isLocalDevelopment: true },
72
- });
73
- const itemType = 'tasks';
74
- const fetchedObjects = [{ id: 1 }];
75
- mockedAxiosClient.get.mockResolvedValueOnce(mockArtifactUploadUrlResponse);
76
- mockedAxiosClient.post.mockResolvedValue((0, test_helpers_1.createAxiosResponse)());
77
- // Act
78
- await localUploader.upload(itemType, fetchedObjects);
79
- // Assert
80
- expect(mockedDownloadToLocal).toHaveBeenCalledWith(itemType, fetchedObjects);
81
- });
82
- it('should return error when getArtifactUploadUrl fails', async () => {
83
- // Arrange
84
- const itemType = 'tasks';
85
- const fetchedObjects = [{ id: 1 }];
86
- mockedAxiosClient.get.mockRejectedValueOnce(new Error('Get artifact upload URL failed'));
87
- // Act
88
- const result = await uploader.upload(itemType, fetchedObjects);
89
- // Assert
90
- expect(result.error).toHaveProperty('message');
91
- expect(result.artifact).toBeUndefined();
92
- });
93
- it('should return error when uploadArtifact fails', async () => {
94
- // Arrange
95
- const itemType = 'tasks';
96
- const fetchedObjects = [{ id: 1 }];
97
- mockedAxiosClient.get.mockResolvedValueOnce(mockArtifactUploadUrlResponse);
98
- mockedAxiosClient.post.mockRejectedValueOnce(new Error('Upload artifact failed'));
99
- // Act
100
- const result = await uploader.upload(itemType, fetchedObjects);
101
- // Assert
102
- expect(result.error).toHaveProperty('message');
103
- expect(result.artifact).toBeUndefined();
104
- });
105
- it('should return error when confirmArtifactUpload fails', async () => {
106
- // Arrange
107
- const itemType = 'tasks';
108
- const fetchedObjects = [{ id: 1 }];
109
- mockedAxiosClient.get.mockResolvedValueOnce(mockArtifactUploadUrlResponse);
110
- mockedAxiosClient.post
111
- .mockResolvedValueOnce((0, test_helpers_1.createAxiosResponse)())
112
- .mockRejectedValueOnce(new Error('Confirm artifact upload failed'));
113
- // Act
114
- const result = await uploader.upload(itemType, fetchedObjects);
115
- // Assert
116
- expect(result.error).toHaveProperty('message');
117
- expect(result.artifact).toBeUndefined();
118
- });
119
- it('should return error when compression fails', async () => {
120
- // Arrange
121
- const itemType = 'tasks';
122
- const fetchedObjects = [{ id: 1 }];
123
- mockedCompressGzip.mockReturnValueOnce({ error: 'Mock error' });
124
- // Act
125
- const result = await uploader.upload(itemType, fetchedObjects);
126
- // Assert
127
- expect(result.error).toHaveProperty('message');
128
- expect(result.artifact).toBeUndefined();
129
- });
130
- });
131
- describe(uploader_1.Uploader.prototype.getArtifactUploadUrl.name, () => {
132
- it('should return artifact upload info when API call succeeds', async () => {
133
- // Arrange
134
- const filename = 'test-file.jsonl.gz';
135
- const fileType = 'application/x-gzip';
136
- const fileSize = 1024;
137
- const expectedArtifact = (0, test_helpers_1.createArtifact)();
138
- mockedAxiosClient.get.mockResolvedValueOnce({
139
- data: expectedArtifact,
140
- });
141
- // Act
142
- const result = await uploader.getArtifactUploadUrl(filename, fileType, fileSize);
143
- // Assert
144
- expect(result.response).toEqual(expectedArtifact);
145
- expect(mockedAxiosClient.get).toHaveBeenCalledWith(expect.stringContaining('/internal/airdrop.artifacts.upload-url'), expect.objectContaining({
146
- params: expect.objectContaining({
147
- file_type: fileType,
148
- file_name: filename,
149
- file_size: fileSize,
150
- }),
151
- }));
152
- });
153
- it('should return undefined when API call fails', async () => {
154
- // Arrange
155
- const filename = 'test-file.jsonl.gz';
156
- const fileType = 'application/x-gzip';
157
- mockedAxiosClient.get.mockRejectedValueOnce(new Error('Get artifact upload URL failed'));
158
- // Act
159
- const result = await uploader.getArtifactUploadUrl(filename, fileType);
160
- // Assert
161
- expect(result.response).toBeUndefined();
162
- expect(result.error).toBeInstanceOf(Error);
163
- expect(mockedAxiosClient.get).toHaveBeenCalled();
164
- });
165
- it('should return error during upload, as it has size of zero', async () => {
166
- // Arrange
167
- const filename = 'test-file.jsonl.gz';
168
- const fileType = 'application/x-gzip';
169
- const fileSize = 0;
170
- // Act
171
- const result = await uploader.getArtifactUploadUrl(filename, fileType, fileSize);
172
- // Assert
173
- expect(result.error).toBeDefined();
174
- });
175
- });
176
- describe(uploader_1.Uploader.prototype.uploadArtifact.name, () => {
177
- it('should return response when posting file as multipart form data', async () => {
178
- // Arrange
179
- const artifact = (0, test_helpers_1.createArtifact)();
180
- const file = (0, test_helpers_1.createFileBuffer)();
181
- const mockResponse = (0, test_helpers_1.createAxiosResponse)();
182
- mockedAxiosClient.post.mockResolvedValueOnce(mockResponse);
183
- // Act
184
- const result = await uploader.uploadArtifact(artifact, file);
185
- // Assert
186
- expect(result.response).toBe(mockResponse);
187
- expect(mockedAxiosClient.post).toHaveBeenCalledWith(artifact.upload_url, expect.any(form_data_1.default), expect.objectContaining({
188
- headers: expect.any(Object),
189
- }));
190
- });
191
- it('should append form_data fields to the multipart form', async () => {
192
- // Arrange
193
- // form_data is typed as array but implementation iterates with for...in
194
- const formDataFields = { key: 'test-key', 'x-amz-credential': 'cred123' };
195
- const artifact = {
196
- artifact_id: 'art_123',
197
- upload_url: 'https://s3.example.com/upload',
198
- form_data: formDataFields,
199
- };
200
- const file = (0, test_helpers_1.createFileBuffer)();
201
- const appendSpy = jest.spyOn(form_data_1.default.prototype, 'append');
202
- mockedAxiosClient.post.mockResolvedValueOnce({ status: 200 });
203
- // Act
204
- await uploader.uploadArtifact(artifact, file);
205
- // Assert
206
- expect(appendSpy).toHaveBeenCalledWith('key', 'test-key');
207
- expect(appendSpy).toHaveBeenCalledWith('x-amz-credential', 'cred123');
208
- expect(appendSpy).toHaveBeenCalledWith('file', file);
209
- appendSpy.mockRestore();
210
- });
211
- it('should return undefined when upload fails', async () => {
212
- // Arrange
213
- const artifact = (0, test_helpers_1.createArtifact)();
214
- const file = (0, test_helpers_1.createFileBuffer)();
215
- mockedAxiosClient.post.mockRejectedValueOnce(new Error('Upload artifact failed'));
216
- // Act
217
- const result = await uploader.uploadArtifact(artifact, file);
218
- // Assert
219
- expect(result.response).toBeUndefined();
220
- expect(result.error).toBeInstanceOf(Error);
221
- });
222
- });
223
- describe(uploader_1.Uploader.prototype.confirmArtifactUpload.name, () => {
224
- it('should return response when confirming artifact upload', async () => {
225
- // Arrange
226
- const artifactId = 'art_123';
227
- const mockResponse = (0, test_helpers_1.createAxiosResponse)();
228
- mockedAxiosClient.post.mockResolvedValueOnce(mockResponse);
229
- // Act
230
- const result = await uploader.confirmArtifactUpload(artifactId);
231
- // Assert
232
- expect(result.response).toBe(mockResponse);
233
- expect(mockedAxiosClient.post).toHaveBeenCalledWith(expect.any(String), expect.objectContaining({
234
- artifact_id: artifactId,
235
- }), expect.any(Object));
236
- });
237
- it('should return undefined when confirmation fails', async () => {
238
- // Arrange
239
- const artifactId = 'art_123';
240
- mockedAxiosClient.post.mockRejectedValueOnce(new Error('Confirmation failed'));
241
- // Act
242
- const result = await uploader.confirmArtifactUpload(artifactId);
243
- // Assert
244
- expect(result.response).toBeUndefined();
245
- expect(result.error).toHaveProperty('message');
246
- });
247
- });
248
- describe(uploader_1.Uploader.prototype.streamArtifact.name, () => {
249
- it('should return response when streaming file to upload URL', async () => {
250
- // Arrange
251
- const artifact = (0, test_helpers_1.createArtifact)();
252
- const destroyFn = jest.fn();
253
- const fileStream = (0, test_helpers_1.createFileStream)({
254
- contentLength: 1024,
255
- destroyFn,
256
- });
257
- const mockResponse = (0, test_helpers_1.createAxiosResponse)();
258
- mockedAxiosClient.post.mockResolvedValueOnce(mockResponse);
259
- // Act
260
- const result = await uploader.streamArtifact(artifact, fileStream);
261
- // Assert
262
- expect(result.response).toBe(mockResponse);
263
- expect(axios_client_internal_1.axiosClient.post).toHaveBeenCalledWith(artifact.upload_url, expect.any(form_data_1.default), expect.objectContaining({
264
- headers: expect.any(Object),
265
- maxRedirects: 0,
266
- validateStatus: expect.any(Function),
267
- }));
268
- expect(destroyFn).toHaveBeenCalled();
269
- });
270
- it('should append form_data fields to the multipart form', async () => {
271
- // Arrange
272
- const formDataFields = { key: 'test-key', 'x-amz-credential': 'cred123' };
273
- const artifact = {
274
- artifact_id: 'art_123',
275
- upload_url: 'https://s3.example.com/upload',
276
- form_data: formDataFields,
277
- };
278
- const fileStream = (0, test_helpers_1.createFileStream)({ contentLength: 1024 });
279
- const appendSpy = jest.spyOn(form_data_1.default.prototype, 'append');
280
- mockedAxiosClient.post.mockResolvedValueOnce({ status: 200 });
281
- // Act
282
- await uploader.streamArtifact(artifact, fileStream);
283
- // Assert
284
- expect(appendSpy).toHaveBeenCalledWith('key', 'test-key');
285
- expect(appendSpy).toHaveBeenCalledWith('x-amz-credential', 'cred123');
286
- appendSpy.mockRestore();
287
- });
288
- it('should use validateStatus that accepts 2xx and 3xx status codes', async () => {
289
- // Arrange
290
- const artifact = (0, test_helpers_1.createArtifact)();
291
- const fileStream = (0, test_helpers_1.createFileStream)({ contentLength: 1024 });
292
- mockedAxiosClient.post.mockResolvedValueOnce((0, test_helpers_1.createAxiosResponse)());
293
- // Act
294
- await uploader.streamArtifact(artifact, fileStream);
295
- // Assert
296
- const callArgs = mockedAxiosClient.post.mock.calls[0];
297
- const config = callArgs[2];
298
- const validateStatus = config === null || config === void 0 ? void 0 : config.validateStatus;
299
- expect(validateStatus === null || validateStatus === void 0 ? void 0 : validateStatus(200)).toBe(true);
300
- expect(validateStatus === null || validateStatus === void 0 ? void 0 : validateStatus(201)).toBe(true);
301
- expect(validateStatus === null || validateStatus === void 0 ? void 0 : validateStatus(299)).toBe(true);
302
- expect(validateStatus === null || validateStatus === void 0 ? void 0 : validateStatus(300)).toBe(true);
303
- expect(validateStatus === null || validateStatus === void 0 ? void 0 : validateStatus(301)).toBe(true);
304
- expect(validateStatus === null || validateStatus === void 0 ? void 0 : validateStatus(399)).toBe(true);
305
- expect(validateStatus === null || validateStatus === void 0 ? void 0 : validateStatus(400)).toBe(false);
306
- expect(validateStatus === null || validateStatus === void 0 ? void 0 : validateStatus(404)).toBe(false);
307
- expect(validateStatus === null || validateStatus === void 0 ? void 0 : validateStatus(500)).toBe(false);
308
- expect(validateStatus === null || validateStatus === void 0 ? void 0 : validateStatus(199)).toBe(false);
309
- });
310
- it('should set Content-Length header when missing from file stream', async () => {
311
- // Arrange
312
- const artifact = (0, test_helpers_1.createArtifact)();
313
- const fileStream = (0, test_helpers_1.createFileStream)({ includeContentLength: false });
314
- mockedAxiosClient.post.mockResolvedValueOnce((0, test_helpers_1.createAxiosResponse)());
315
- // Act
316
- await uploader.streamArtifact(artifact, fileStream);
317
- // Assert
318
- expect(mockedAxiosClient.post).toHaveBeenCalledWith(artifact.upload_url, expect.any(form_data_1.default), expect.objectContaining({
319
- headers: expect.objectContaining({
320
- 'Content-Length': expect.any(Number),
321
- }),
322
- }));
323
- });
324
- it('should destroy stream and return undefined when streaming fails', async () => {
325
- // Arrange
326
- const artifact = (0, test_helpers_1.createArtifact)();
327
- const destroyFn = jest.fn();
328
- const fileStream = (0, test_helpers_1.createFileStream)({ destroyFn });
329
- mockedAxiosClient.post.mockRejectedValueOnce(new Error('Streaming failed'));
330
- // Act
331
- const result = await uploader.streamArtifact(artifact, fileStream);
332
- // Assert
333
- expect(result.response).toBeUndefined();
334
- expect(result.error).toBeInstanceOf(Error);
335
- expect(destroyFn).toHaveBeenCalled();
336
- });
337
- });
338
- describe('Uploader.destroyStream', () => {
339
- it('should call destroy when stream has destroy method', () => {
340
- // Arrange
341
- const destroyStream = (0, test_helpers_1.callPrivateMethod)()(uploader, 'destroyStream');
342
- const destroyFn = jest.fn();
343
- const fileStream = {
344
- data: { destroy: destroyFn },
345
- };
346
- // Act
347
- destroyStream(fileStream);
348
- // Assert
349
- expect(destroyFn).toHaveBeenCalled();
350
- });
351
- it('should call close when stream has close but no destroy method', () => {
352
- // Arrange
353
- const destroyStream = (0, test_helpers_1.callPrivateMethod)()(uploader, 'destroyStream');
354
- const closeFn = jest.fn();
355
- const fileStream = {
356
- data: { close: closeFn },
357
- };
358
- // Act
359
- destroyStream(fileStream);
360
- // Assert
361
- expect(closeFn).toHaveBeenCalled();
362
- });
363
- it('should prefer destroy over close when both are available', () => {
364
- // Arrange
365
- const destroyStream = (0, test_helpers_1.callPrivateMethod)()(uploader, 'destroyStream');
366
- const destroyFn = jest.fn();
367
- const closeFn = jest.fn();
368
- const fileStream = {
369
- data: { destroy: destroyFn, close: closeFn },
370
- };
371
- // Act
372
- destroyStream(fileStream);
373
- // Assert
374
- expect(destroyFn).toHaveBeenCalled();
375
- expect(closeFn).not.toHaveBeenCalled();
376
- });
377
- it('[edge] should handle stream with no destroy or close methods', () => {
378
- // Arrange
379
- const destroyStream = (0, test_helpers_1.callPrivateMethod)()(uploader, 'destroyStream');
380
- const fileStream = {
381
- data: {},
382
- };
383
- // Act & Assert - should not throw
384
- expect(() => destroyStream(fileStream)).not.toThrow();
385
- });
386
- it('[edge] should handle null/undefined data gracefully', () => {
387
- // Arrange
388
- const destroyStream = (0, test_helpers_1.callPrivateMethod)()(uploader, 'destroyStream');
389
- const fileStreamNullData = {
390
- data: null,
391
- };
392
- const fileStreamUndefinedData = {
393
- data: undefined,
394
- };
395
- // Act & Assert - should not throw
396
- expect(() => destroyStream(fileStreamNullData)).not.toThrow();
397
- expect(() => destroyStream(fileStreamUndefinedData)).not.toThrow();
398
- });
399
- it('[edge] should warn when destroy throws an error', () => {
400
- // Arrange
401
- const destroyStream = (0, test_helpers_1.callPrivateMethod)()(uploader, 'destroyStream');
402
- const destroyFn = jest.fn().mockImplementation(() => {
403
- throw new Error('Destroy failed');
404
- });
405
- const fileStream = {
406
- data: { destroy: destroyFn },
407
- };
408
- // Act & Assert - should not throw
409
- expect(() => destroyStream(fileStream)).not.toThrow();
410
- });
411
- });
412
- describe('Uploader.getArtifactDownloadUrl', () => {
413
- it('should return download URL when API call succeeds', async () => {
414
- // Arrange
415
- const getArtifactDownloadUrl = (0, test_helpers_1.callPrivateMethod)()(uploader, 'getArtifactDownloadUrl');
416
- const artifactId = 'art_123';
417
- const expectedDownloadUrl = 'https://s3.example.com/download/art_123';
418
- mockedAxiosClient.get.mockResolvedValueOnce({
419
- data: { download_url: expectedDownloadUrl },
420
- });
421
- // Act
422
- const result = await getArtifactDownloadUrl(artifactId);
423
- // Assert
424
- expect(result.response).toBe(expectedDownloadUrl);
425
- expect(result.error).toBeUndefined();
426
- expect(mockedAxiosClient.get).toHaveBeenCalledWith(expect.any(String), expect.objectContaining({
427
- params: expect.objectContaining({
428
- artifact_id: artifactId,
429
- }),
430
- }));
431
- });
432
- it('should return undefined when API call fails', async () => {
433
- // Arrange
434
- const getArtifactDownloadUrl = (0, test_helpers_1.callPrivateMethod)()(uploader, 'getArtifactDownloadUrl');
435
- const artifactId = 'art_123';
436
- mockedAxiosClient.get.mockRejectedValueOnce(new Error('API error'));
437
- // Act
438
- const result = await getArtifactDownloadUrl(artifactId);
439
- // Assert
440
- expect(result.response).toBeUndefined();
441
- expect(result.error).toBeInstanceOf(Error);
442
- });
443
- });
444
- describe(uploader_1.Uploader.prototype.getAttachmentsFromArtifactId.name, () => {
445
- it('should return attachments when download and parse succeeds', async () => {
446
- // Arrange
447
- const artifactId = 'art_123';
448
- const mockAttachments = [
449
- { id: '1', url: 'https://example.com/1', file_name: 'file1.txt' },
450
- { id: '2', url: 'https://example.com/2', file_name: 'file2.txt' },
451
- ];
452
- const gzippedData = zlib_1.default.gzipSync(js_jsonl_1.jsonl.stringify(mockAttachments));
453
- mockedAxiosClient.get.mockResolvedValueOnce((0, test_helpers_1.createDownloadUrlResponse)());
454
- mockedAxiosClient.get.mockResolvedValueOnce({
455
- data: gzippedData,
456
- });
457
- // Act
458
- const result = await uploader.getAttachmentsFromArtifactId({
459
- artifact: artifactId,
460
- });
461
- // Assert
462
- expect(result.attachments).toEqual(mockAttachments);
463
- expect(result.error).toBeUndefined();
464
- });
465
- it('should return error when getArtifactDownloadUrl fails', async () => {
466
- // Arrange
467
- const artifactId = 'art_123';
468
- (0, test_helpers_1.spyOnPrivateMethod)(uploader, 'getArtifactDownloadUrl').mockResolvedValueOnce({ error: new Error('API error') });
469
- // Act
470
- const result = await uploader.getAttachmentsFromArtifactId({
471
- artifact: artifactId,
472
- });
473
- // Assert
474
- expect(result.error).toHaveProperty('message');
475
- expect(result.attachments).toBeUndefined();
476
- });
477
- it('should return error when downloadArtifact fails', async () => {
478
- // Arrange
479
- const artifactId = 'art_123';
480
- mockedAxiosClient.get.mockResolvedValueOnce((0, test_helpers_1.createDownloadUrlResponse)());
481
- mockedAxiosClient.get.mockRejectedValueOnce(new Error('Download error'));
482
- // Act
483
- const result = await uploader.getAttachmentsFromArtifactId({
484
- artifact: artifactId,
485
- });
486
- // Assert
487
- expect(result.error).toHaveProperty('message');
488
- expect(result.attachments).toBeUndefined();
489
- });
490
- it('should return error when decompression fails', async () => {
491
- // Arrange
492
- const artifactId = 'art_123';
493
- mockedAxiosClient.get.mockResolvedValueOnce((0, test_helpers_1.createDownloadUrlResponse)());
494
- mockedAxiosClient.get.mockResolvedValueOnce({
495
- data: Buffer.from('not valid gzip data'),
496
- });
497
- // Act
498
- const result = await uploader.getAttachmentsFromArtifactId({
499
- artifact: artifactId,
500
- });
501
- // Assert
502
- expect(result.error).toHaveProperty('message');
503
- expect(result.attachments).toBeUndefined();
504
- });
505
- it('should return error when JSONL parsing fails', async () => {
506
- // Arrange
507
- const artifactId = 'art_123';
508
- const gzippedInvalidJsonl = zlib_1.default.gzipSync('not valid jsonl {{{');
509
- mockedAxiosClient.get.mockResolvedValueOnce((0, test_helpers_1.createDownloadUrlResponse)());
510
- mockedAxiosClient.get.mockResolvedValueOnce({
511
- data: gzippedInvalidJsonl,
512
- });
513
- // Act
514
- const result = await uploader.getAttachmentsFromArtifactId({
515
- artifact: artifactId,
516
- });
517
- // Assert
518
- expect(result.error).toHaveProperty('message');
519
- expect(result.attachments).toBeUndefined();
520
- });
521
- });
522
- describe(uploader_1.Uploader.prototype.getJsonObjectByArtifactId.name, () => {
523
- it('should return parsed data when downloading non-gzipped artifact', async () => {
524
- // Arrange
525
- const artifactId = 'art_123';
526
- const mockData = [
527
- { id: 1, name: 'Item 1' },
528
- { id: 2, name: 'Item 2' },
529
- ];
530
- const jsonlData = js_jsonl_1.jsonl.stringify(mockData);
531
- mockedAxiosClient.get.mockResolvedValueOnce((0, test_helpers_1.createDownloadUrlResponse)());
532
- mockedAxiosClient.get.mockResolvedValueOnce({
533
- data: Buffer.from(jsonlData),
534
- });
535
- // Act
536
- const result = await uploader.getJsonObjectByArtifactId({
537
- artifactId,
538
- isGzipped: false,
539
- });
540
- // Assert
541
- expect(result.response).toEqual(mockData);
542
- });
543
- it('should return parsed data when downloading gzipped artifact', async () => {
544
- // Arrange
545
- const artifactId = 'art_123';
546
- const mockData = [
547
- { id: 1, name: 'Item 1' },
548
- { id: 2, name: 'Item 2' },
549
- ];
550
- const gzippedData = zlib_1.default.gzipSync(js_jsonl_1.jsonl.stringify(mockData));
551
- mockedAxiosClient.get.mockResolvedValueOnce((0, test_helpers_1.createDownloadUrlResponse)());
552
- mockedAxiosClient.get.mockResolvedValueOnce({
553
- data: gzippedData,
554
- });
555
- // Act
556
- const result = await uploader.getJsonObjectByArtifactId({
557
- artifactId,
558
- isGzipped: true,
559
- });
560
- // Assert
561
- expect(result.response).toEqual(mockData);
562
- });
563
- it('[edge] should return error when getArtifactDownloadUrl fails', async () => {
564
- // Arrange
565
- const artifactId = 'art_123';
566
- (0, test_helpers_1.spyOnPrivateMethod)(uploader, 'getArtifactDownloadUrl').mockResolvedValueOnce({ error: new Error('API error') });
567
- // Act
568
- const result = await uploader.getJsonObjectByArtifactId({ artifactId });
569
- // Assert
570
- expect(result.response).toBeUndefined();
571
- expect(result.error).toBeInstanceOf(Error);
572
- });
573
- it('[edge] should return error when downloadArtifact fails', async () => {
574
- // Arrange
575
- const artifactId = 'art_123';
576
- mockedAxiosClient.get.mockResolvedValueOnce((0, test_helpers_1.createDownloadUrlResponse)());
577
- mockedAxiosClient.get.mockRejectedValueOnce(new Error('Download error'));
578
- // Act
579
- const result = await uploader.getJsonObjectByArtifactId({ artifactId });
580
- // Assert
581
- expect(result.response).toBeUndefined();
582
- expect(result.error).toBeInstanceOf(Error);
583
- });
584
- it('[edge] should return error when decompression fails for gzipped artifact', async () => {
585
- // Arrange
586
- const artifactId = 'art_123';
587
- mockedAxiosClient.get.mockResolvedValueOnce((0, test_helpers_1.createDownloadUrlResponse)());
588
- mockedAxiosClient.get.mockResolvedValueOnce({
589
- data: Buffer.from('not valid gzip'),
590
- });
591
- // Act
592
- const result = await uploader.getJsonObjectByArtifactId({
593
- artifactId,
594
- isGzipped: true,
595
- });
596
- // Assert
597
- expect(result.response).toBeUndefined();
598
- expect(result.error).toBeDefined();
599
- });
600
- });
601
- });
File without changes