@devrev/ts-adaas 1.0.4 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/README.md +4 -0
  2. package/dist/common/constants.d.ts +2 -0
  3. package/dist/common/constants.js +14 -2
  4. package/dist/common/control-protocol.d.ts +2 -1
  5. package/dist/common/helpers.d.ts +15 -3
  6. package/dist/common/helpers.js +68 -3
  7. package/dist/logger/logger.test.js +3 -0
  8. package/dist/mappers/mappers.d.ts +10 -0
  9. package/dist/mappers/mappers.interface.d.ts +85 -0
  10. package/dist/mappers/mappers.interface.js +9 -0
  11. package/dist/mappers/mappers.js +37 -0
  12. package/dist/state/state.d.ts +1 -0
  13. package/dist/state/state.interfaces.d.ts +8 -5
  14. package/dist/state/state.interfaces.js +1 -0
  15. package/dist/state/state.js +21 -12
  16. package/dist/tests/from_devrev/loading.test.d.ts +1 -0
  17. package/dist/tests/from_devrev/loading.test.js +146 -0
  18. package/dist/tests/test-helpers.js +12 -6
  19. package/dist/types/extraction.d.ts +42 -9
  20. package/dist/types/extraction.js +21 -1
  21. package/dist/types/index.d.ts +2 -1
  22. package/dist/types/index.js +5 -1
  23. package/dist/types/loading.d.ts +95 -0
  24. package/dist/types/loading.js +21 -0
  25. package/dist/types/workers.d.ts +2 -1
  26. package/dist/uploader/uploader.d.ts +4 -0
  27. package/dist/uploader/uploader.interfaces.d.ts +9 -0
  28. package/dist/uploader/uploader.js +20 -0
  29. package/dist/workers/create-worker.js +2 -2
  30. package/dist/workers/default-workers/data-loading.d.ts +1 -0
  31. package/dist/workers/default-workers/data-loading.js +19 -0
  32. package/dist/workers/spawn.js +20 -8
  33. package/dist/workers/worker-adapter.d.ts +14 -1
  34. package/dist/workers/worker-adapter.js +330 -1
  35. package/package.json +1 -1
@@ -1,12 +1,22 @@
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;
8
+ const axios_1 = __importDefault(require("axios"));
5
9
  const extraction_1 = require("../types/extraction");
10
+ const loading_1 = require("../types/loading");
6
11
  const constants_1 = require("../common/constants");
7
12
  const control_protocol_1 = require("../common/control-protocol");
8
13
  const workers_1 = require("../types/workers");
9
14
  const repo_1 = require("../repo/repo");
15
+ const helpers_1 = require("../common/helpers");
16
+ const mappers_1 = require("../mappers/mappers");
17
+ const uploader_1 = require("../uploader/uploader");
18
+ const logger_1 = require("../logger/logger");
19
+ const mappers_interface_1 = require("../mappers/mappers.interface");
10
20
  function createWorkerAdapter({ event, adapterState, parentPort, options, }) {
11
21
  return new WorkerAdapter({
12
22
  event,
@@ -39,6 +49,17 @@ class WorkerAdapter {
39
49
  this.parentPort = parentPort;
40
50
  this.hasWorkerEmitted = false;
41
51
  this.isTimeout = false;
52
+ // Loader
53
+ this.loaderReports = [];
54
+ this._processedFiles = [];
55
+ this.mappers = new mappers_1.Mappers({
56
+ event,
57
+ options,
58
+ });
59
+ this.uploader = new uploader_1.Uploader({
60
+ event,
61
+ options,
62
+ });
42
63
  }
43
64
  get state() {
44
65
  return this.adapterState.state;
@@ -48,6 +69,12 @@ class WorkerAdapter {
48
69
  this.adapterState.state = value;
49
70
  }
50
71
  }
72
+ get reports() {
73
+ return this.loaderReports;
74
+ }
75
+ get processedFiles() {
76
+ return this._processedFiles;
77
+ }
51
78
  initializeRepos(repos) {
52
79
  this.repos = repos.map((repo) => {
53
80
  const shouldNormalize = !Object.values(constants_1.AIRDROP_DEFAULT_ITEM_TYPES).includes(repo.itemType);
@@ -112,7 +139,9 @@ class WorkerAdapter {
112
139
  await (0, control_protocol_1.emit)({
113
140
  eventType: newEventType,
114
141
  event: this.event,
115
- data: Object.assign(Object.assign({}, data), { artifacts: this.artifacts }),
142
+ data: Object.assign(Object.assign({}, data), (constants_1.ALLOWED_EXTRACTION_EVENT_TYPES.includes(this.event.payload.event_type)
143
+ ? { artifacts: this.artifacts }
144
+ : {})),
116
145
  });
117
146
  const message = {
118
147
  subject: workers_1.WorkerMessageSubject.WorkerMessageEmitted,
@@ -134,5 +163,305 @@ class WorkerAdapter {
134
163
  handleTimeout() {
135
164
  this.isTimeout = true;
136
165
  }
166
+ async loadItemTypes({ itemTypesToLoad, }) {
167
+ var _a, _b, _c;
168
+ const statsFileArtifactId = (_a = this.event.payload.event_data) === null || _a === void 0 ? void 0 : _a.stats_file;
169
+ if (!statsFileArtifactId) {
170
+ console.error('Stats file artifact id not found in event data.');
171
+ await (0, control_protocol_1.emit)({
172
+ event: this.event,
173
+ eventType: loading_1.LoaderEventType.DataLoadingError,
174
+ data: {
175
+ error: {
176
+ message: 'Stats file artifact id not found in event data.',
177
+ },
178
+ },
179
+ });
180
+ return {
181
+ reports: this.reports,
182
+ processed_files: this.processedFiles,
183
+ };
184
+ }
185
+ const statsFile = (await this.uploader.getJsonObjectByArtifactId({
186
+ artifactId: statsFileArtifactId,
187
+ }));
188
+ console.log('Stats file', statsFile);
189
+ if (!statsFile || statsFile.length === 0) {
190
+ console.warn('Stats file not found or empty.');
191
+ return {
192
+ reports: this.reports,
193
+ processed_files: this.processedFiles,
194
+ };
195
+ }
196
+ if (this.event.payload.event_type === extraction_1.EventType.StartLoadingData) {
197
+ console.log('Recieved event type ' +
198
+ extraction_1.EventType.StartLoadingData +
199
+ '. Preparing files to load.');
200
+ const filesToLoad = (0, helpers_1.getFilesToLoad)({
201
+ itemTypesToLoad,
202
+ statsFile,
203
+ });
204
+ if (filesToLoad.length === 0) {
205
+ console.warn('No files to load, returning.');
206
+ return {
207
+ reports: this.reports,
208
+ processed_files: this.processedFiles,
209
+ };
210
+ }
211
+ this.adapterState.state.fromDevRev = { filesToLoad };
212
+ }
213
+ console.log('Files to load in state', (_b = this.adapterState.state.fromDevRev) === null || _b === void 0 ? void 0 : _b.filesToLoad);
214
+ if (!this.adapterState.state.fromDevRev) {
215
+ await (0, control_protocol_1.emit)({
216
+ event: this.event,
217
+ eventType: loading_1.LoaderEventType.DataLoadingError,
218
+ data: {
219
+ error: {
220
+ message: 'Unexpected state set in LOAD_DATA.',
221
+ },
222
+ },
223
+ });
224
+ return {
225
+ reports: this.reports,
226
+ processed_files: this.processedFiles,
227
+ };
228
+ }
229
+ outerloop: for (const fileToLoad of (_c = this.adapterState.state.fromDevRev) === null || _c === void 0 ? void 0 : _c.filesToLoad) {
230
+ const itemTypeToLoad = itemTypesToLoad.find((itemTypeToLoad) => itemTypeToLoad.itemType === fileToLoad.itemType);
231
+ if (!itemTypeToLoad) {
232
+ console.error(`Item type to load not found for item type: ${fileToLoad.itemType}.`);
233
+ await (0, control_protocol_1.emit)({
234
+ event: this.event,
235
+ eventType: loading_1.LoaderEventType.DataLoadingError,
236
+ data: {
237
+ error: {
238
+ message: `Item type to load not found for item type: ${fileToLoad.itemType}.`,
239
+ },
240
+ },
241
+ });
242
+ break;
243
+ }
244
+ if (!fileToLoad.completed) {
245
+ const transformerFile = (await this.uploader.getJsonObjectByArtifactId({
246
+ artifactId: fileToLoad.id,
247
+ isGzipped: true,
248
+ }));
249
+ if (!transformerFile) {
250
+ console.error('Transformer file not found.');
251
+ break outerloop;
252
+ }
253
+ for (let i = fileToLoad.lineToProcess; i < fileToLoad.count; i++) {
254
+ const { report, rateLimit, error } = await this.loadItem({
255
+ item: transformerFile[i],
256
+ itemTypeToLoad,
257
+ });
258
+ if (error) {
259
+ await (0, control_protocol_1.emit)({
260
+ event: this.event,
261
+ eventType: loading_1.LoaderEventType.DataLoadingError,
262
+ data: {
263
+ error,
264
+ },
265
+ });
266
+ break outerloop;
267
+ }
268
+ if (rateLimit === null || rateLimit === void 0 ? void 0 : rateLimit.delay) {
269
+ await (0, control_protocol_1.emit)({
270
+ event: this.event,
271
+ eventType: loading_1.LoaderEventType.DataLoadingDelay,
272
+ data: {
273
+ delay: rateLimit.delay,
274
+ reports: this.reports,
275
+ processed_files: this.processedFiles,
276
+ },
277
+ });
278
+ break outerloop;
279
+ }
280
+ if (report) {
281
+ (0, helpers_1.addReportToLoaderReport)({
282
+ loaderReports: this.loaderReports,
283
+ report,
284
+ });
285
+ fileToLoad.lineToProcess = fileToLoad.lineToProcess + 1;
286
+ }
287
+ }
288
+ fileToLoad.completed = true;
289
+ this._processedFiles.push(fileToLoad.id);
290
+ }
291
+ }
292
+ return {
293
+ reports: this.reports,
294
+ processed_files: this.processedFiles,
295
+ };
296
+ }
297
+ async loadItem({ item, itemTypeToLoad, }) {
298
+ var _a;
299
+ const devrevId = item.id.devrev;
300
+ try {
301
+ const syncMapperRecordResponse = await this.mappers.getByTargetId({
302
+ sync_unit: this.event.payload.event_context.sync_unit,
303
+ target: devrevId,
304
+ });
305
+ const syncMapperRecord = syncMapperRecordResponse.data;
306
+ if (!syncMapperRecord) {
307
+ console.error('Failed to get sync mapper record from response.');
308
+ return {
309
+ error: {
310
+ message: 'Failed to get sync mapper record from response.',
311
+ },
312
+ };
313
+ }
314
+ // Update item
315
+ const { id, modifiedDate, delay, error } = await itemTypeToLoad.update({
316
+ item,
317
+ mappers: this.mappers,
318
+ event: this.event,
319
+ });
320
+ if (id) {
321
+ if (modifiedDate) {
322
+ try {
323
+ const updateSyncMapperRecordResponse = await this.mappers.update({
324
+ id: syncMapperRecord.sync_mapper_record.id,
325
+ sync_unit: this.event.payload.event_context.sync_unit,
326
+ status: mappers_interface_1.SyncMapperRecordStatus.OPERATIONAL,
327
+ external_versions: {
328
+ add: [
329
+ {
330
+ modified_date: modifiedDate,
331
+ recipe_version: 0,
332
+ },
333
+ ],
334
+ },
335
+ external_ids: {
336
+ add: [id],
337
+ },
338
+ targets: {
339
+ add: [devrevId],
340
+ },
341
+ });
342
+ console.log('Updated sync mapper record', JSON.stringify(updateSyncMapperRecordResponse.data));
343
+ }
344
+ catch (error) {
345
+ if (axios_1.default.isAxiosError(error)) {
346
+ console.error('Failed to update sync mapper record', (0, logger_1.formatAxiosError)(error));
347
+ return {
348
+ error: {
349
+ message: error.message,
350
+ },
351
+ };
352
+ }
353
+ else {
354
+ console.error('Failed to update sync mapper record', error);
355
+ return {
356
+ error: {
357
+ message: 'Failed to update sync mapper record' + error,
358
+ },
359
+ };
360
+ }
361
+ }
362
+ }
363
+ return {
364
+ report: {
365
+ item_type: itemTypeToLoad.itemType,
366
+ [loading_1.ActionType.UPDATED]: 1,
367
+ },
368
+ };
369
+ }
370
+ else if (delay) {
371
+ console.log('Rate limited, delaying for', delay);
372
+ return {
373
+ rateLimit: {
374
+ delay,
375
+ },
376
+ };
377
+ }
378
+ else {
379
+ console.error('Failed to update item', error);
380
+ return {
381
+ report: {
382
+ item_type: itemTypeToLoad.itemType,
383
+ [loading_1.ActionType.FAILED]: 1,
384
+ },
385
+ };
386
+ }
387
+ // Update mapper (optional)
388
+ }
389
+ catch (error) {
390
+ if (axios_1.default.isAxiosError(error)) {
391
+ if (((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) === 404) {
392
+ // Create item
393
+ const { id, delay, error } = await itemTypeToLoad.create({
394
+ item,
395
+ mappers: this.mappers,
396
+ event: this.event,
397
+ });
398
+ if (id) {
399
+ // Create mapper
400
+ try {
401
+ const createdSyncMapperRecordResponse = await this.mappers.create({
402
+ sync_unit: this.event.payload.event_context.sync_unit,
403
+ status: mappers_interface_1.SyncMapperRecordStatus.OPERATIONAL,
404
+ external_ids: [id],
405
+ targets: [devrevId],
406
+ });
407
+ console.log('Created sync mapper record', createdSyncMapperRecordResponse.data.sync_mapper_record.id);
408
+ return {
409
+ report: {
410
+ item_type: itemTypeToLoad.itemType,
411
+ [loading_1.ActionType.CREATED]: 1,
412
+ },
413
+ };
414
+ }
415
+ catch (error) {
416
+ if (axios_1.default.isAxiosError(error)) {
417
+ console.error('Failed to create sync mapper record', (0, logger_1.formatAxiosError)(error));
418
+ return {
419
+ error: {
420
+ message: error.message,
421
+ },
422
+ };
423
+ }
424
+ console.error('Failed to create sync mapper record', error);
425
+ return {
426
+ error: {
427
+ message: 'Failed to create sync mapper record' + error,
428
+ },
429
+ };
430
+ }
431
+ }
432
+ else if (delay) {
433
+ return {
434
+ rateLimit: {
435
+ delay,
436
+ },
437
+ };
438
+ }
439
+ else {
440
+ console.error('Failed to create item', error);
441
+ return {
442
+ report: {
443
+ item_type: itemTypeToLoad.itemType,
444
+ [loading_1.ActionType.FAILED]: 1,
445
+ },
446
+ };
447
+ }
448
+ }
449
+ else {
450
+ console.error('Failed to get sync mapper record', (0, logger_1.formatAxiosError)(error));
451
+ return {
452
+ error: {
453
+ message: error.message,
454
+ },
455
+ };
456
+ }
457
+ }
458
+ console.error('Failed to get sync mapper record', error);
459
+ return {
460
+ error: {
461
+ message: 'Failed to get sync mapper record' + error,
462
+ },
463
+ };
464
+ }
465
+ }
137
466
  }
138
467
  exports.WorkerAdapter = WorkerAdapter;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devrev/ts-adaas",
3
- "version": "1.0.4",
3
+ "version": "1.1.0",
4
4
  "description": "Typescript library containing the ADaaS(AirDrop as a Service) control protocol.",
5
5
  "type": "commonjs",
6
6
  "main": "./dist/index.js",