@devrev/ts-adaas 0.0.2 → 1.0.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.
- package/README.md +186 -116
- package/dist/common/constants.d.ts +10 -0
- package/dist/common/constants.js +27 -0
- package/dist/common/control-protocol.d.ts +7 -0
- package/dist/common/control-protocol.js +41 -0
- package/dist/common/helpers.d.ts +4 -0
- package/dist/common/helpers.js +38 -0
- package/dist/common/install-initial-domain-mapping.d.ts +3 -0
- package/dist/common/install-initial-domain-mapping.js +87 -0
- package/dist/{src → deprecated}/adapter/index.d.ts +10 -7
- package/dist/{src → deprecated}/adapter/index.js +13 -10
- package/dist/{src → deprecated}/common/helpers.d.ts +1 -2
- package/dist/deprecated/common/helpers.js +47 -0
- package/dist/deprecated/demo-extractor/external_domain_metadata.json +38 -0
- package/dist/deprecated/demo-extractor/index.d.ts +17 -0
- package/dist/deprecated/demo-extractor/index.js +161 -0
- package/dist/{src → deprecated}/uploader/index.d.ts +1 -1
- package/dist/{src → deprecated}/uploader/index.js +3 -1
- package/dist/{src/http → http}/client.d.ts +2 -1
- package/dist/index.d.ts +10 -0
- package/dist/index.js +30 -0
- package/dist/logger/logger.d.ts +14 -0
- package/dist/logger/logger.interfaces.d.ts +14 -0
- package/dist/logger/logger.interfaces.js +9 -0
- package/dist/logger/logger.js +91 -0
- package/dist/logger/logger.test.js +49 -0
- package/dist/repo/repo.d.ts +14 -0
- package/dist/repo/repo.interfaces.d.ts +43 -0
- package/dist/repo/repo.interfaces.js +2 -0
- package/dist/repo/repo.js +68 -0
- package/dist/repo/repo.test.js +74 -0
- package/dist/state/state.d.ts +24 -0
- package/dist/state/state.interfaces.d.ts +24 -0
- package/dist/state/state.interfaces.js +2 -0
- package/dist/state/state.js +115 -0
- package/dist/tests/test-helpers.d.ts +9 -0
- package/dist/tests/test-helpers.interfaces.d.ts +11 -0
- package/dist/tests/test-helpers.interfaces.js +2 -0
- package/dist/tests/test-helpers.js +88 -0
- package/dist/tests/test-worker.js +16 -0
- package/dist/types/common.d.ts +39 -0
- package/dist/{src/types → types}/common.js +4 -0
- package/dist/{src/types → types}/extraction.d.ts +57 -12
- package/dist/{src/types → types}/extraction.js +12 -29
- package/dist/types/index.d.ts +5 -0
- package/dist/types/index.js +11 -0
- package/dist/types/workers.d.ts +142 -0
- package/dist/types/workers.js +23 -0
- package/dist/uploader/uploader.d.ts +38 -0
- package/dist/uploader/uploader.interfaces.d.ts +63 -0
- package/dist/uploader/uploader.interfaces.js +2 -0
- package/dist/uploader/uploader.js +351 -0
- package/dist/{tests → uploader}/uploader.test.js +7 -5
- package/dist/workers/create-worker.d.ts +4 -0
- package/dist/workers/create-worker.js +30 -0
- package/dist/workers/create-worker.test.js +25 -0
- package/dist/workers/default-workers/attachments-deletion.d.ts +1 -0
- package/dist/workers/default-workers/attachments-deletion.js +13 -0
- package/dist/workers/default-workers/attachments-extraction.d.ts +1 -0
- package/dist/workers/default-workers/attachments-extraction.js +49 -0
- package/dist/workers/default-workers/data-deletion.d.ts +1 -0
- package/dist/workers/default-workers/data-deletion.js +15 -0
- package/dist/workers/default-workers/data-extraction.d.ts +1 -0
- package/dist/workers/default-workers/data-extraction.js +101 -0
- package/dist/workers/default-workers/external-sync-units-extraction.d.ts +1 -0
- package/dist/workers/default-workers/external-sync-units-extraction.js +27 -0
- package/dist/workers/default-workers/metadata-extraction.d.ts +1 -0
- package/dist/workers/default-workers/metadata-extraction.js +26 -0
- package/dist/workers/dummy-extractor/data-normalization.d.ts +4 -0
- package/dist/workers/dummy-extractor/data-normalization.js +41 -0
- package/dist/workers/dummy-extractor/external_domain_metadata.json +58 -0
- package/dist/workers/process-task.d.ts +2 -0
- package/dist/workers/process-task.js +44 -0
- package/dist/workers/spawn.d.ts +25 -0
- package/dist/workers/spawn.js +163 -0
- package/dist/workers/worker-adapter.d.ts +48 -0
- package/dist/workers/worker-adapter.js +138 -0
- package/dist/workers/worker.d.ts +1 -0
- package/dist/workers/worker.js +6 -0
- package/package.json +9 -5
- package/dist/src/common/constants.d.ts +0 -2
- package/dist/src/common/constants.js +0 -10
- package/dist/src/common/helpers.js +0 -59
- package/dist/src/demo-extractor/index.d.ts +0 -11
- package/dist/src/demo-extractor/index.js +0 -157
- package/dist/src/demo-extractor/initial_domain_mapping.json +0 -107
- package/dist/src/index.d.ts +0 -5
- package/dist/src/index.js +0 -21
- package/dist/src/logging/index.d.ts +0 -18
- package/dist/src/logging/index.js +0 -39
- package/dist/src/state/index.d.ts +0 -23
- package/dist/src/state/index.js +0 -111
- package/dist/src/types/common.d.ts +0 -33
- package/dist/src/types/index.d.ts +0 -2
- package/dist/src/types/index.js +0 -18
- package/dist/tests/adapter.helpers.test.js +0 -60
- package/dist/tests/adapter.test.js +0 -122
- package/dist/tests/demo-extractor.test.js +0 -60
- package/dist/tests/state.test.js +0 -100
- /package/dist/{src/http → http}/client.js +0 -0
- /package/dist/{src/http → http}/constants.d.ts +0 -0
- /package/dist/{src/http → http}/constants.js +0 -0
- /package/dist/{src/http → http}/index.d.ts +0 -0
- /package/dist/{src/http → http}/index.js +0 -0
- /package/dist/{src/http → http}/types.d.ts +0 -0
- /package/dist/{src/http → http}/types.js +0 -0
- /package/dist/{tests/adapter.helpers.test.d.ts → logger/logger.test.d.ts} +0 -0
- /package/dist/{tests/adapter.test.d.ts → repo/repo.test.d.ts} +0 -0
- /package/dist/tests/{demo-extractor.test.d.ts → test-worker.d.ts} +0 -0
- /package/dist/{tests → uploader}/uploader.test.d.ts +0 -0
- /package/dist/{tests/state.test.d.ts → workers/create-worker.test.d.ts} +0 -0
|
@@ -0,0 +1,26 @@
|
|
|
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 index_1 = require("../../index");
|
|
7
|
+
const external_domain_metadata_json_1 = __importDefault(require("../dummy-extractor/external_domain_metadata.json"));
|
|
8
|
+
const repos = [
|
|
9
|
+
{
|
|
10
|
+
itemType: 'external_domain_metadata',
|
|
11
|
+
},
|
|
12
|
+
];
|
|
13
|
+
(0, index_1.processTask)({
|
|
14
|
+
task: async ({ adapter }) => {
|
|
15
|
+
var _a;
|
|
16
|
+
adapter.initializeRepos(repos);
|
|
17
|
+
await ((_a = adapter
|
|
18
|
+
.getRepo('external_domain_metadata')) === null || _a === void 0 ? void 0 : _a.push([external_domain_metadata_json_1.default]));
|
|
19
|
+
await adapter.emit(index_1.ExtractorEventType.ExtractionMetadataDone);
|
|
20
|
+
},
|
|
21
|
+
onTimeout: async ({ adapter }) => {
|
|
22
|
+
await adapter.emit(index_1.ExtractorEventType.ExtractionMetadataError, {
|
|
23
|
+
error: { message: 'Failed to extract metadata. Lambda timeout.' },
|
|
24
|
+
});
|
|
25
|
+
},
|
|
26
|
+
});
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { NormalizedItem, NormalizedAttachment } from '../../index';
|
|
2
|
+
export declare function normalizeIssue(item: any): NormalizedItem;
|
|
3
|
+
export declare function normalizeUser(item: any): NormalizedItem;
|
|
4
|
+
export declare function normalizeAttachment(item: any): NormalizedAttachment;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.normalizeIssue = normalizeIssue;
|
|
4
|
+
exports.normalizeUser = normalizeUser;
|
|
5
|
+
exports.normalizeAttachment = normalizeAttachment;
|
|
6
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
7
|
+
function normalizeIssue(item) {
|
|
8
|
+
return {
|
|
9
|
+
id: item.id,
|
|
10
|
+
created_date: item.created_date,
|
|
11
|
+
modified_date: item.modified_date,
|
|
12
|
+
data: {
|
|
13
|
+
body: item.body,
|
|
14
|
+
creator: item.creator,
|
|
15
|
+
owner: item.owner,
|
|
16
|
+
title: item.title,
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
21
|
+
function normalizeUser(item) {
|
|
22
|
+
return {
|
|
23
|
+
id: item.id,
|
|
24
|
+
created_date: item.created_date,
|
|
25
|
+
modified_date: item.modified_date,
|
|
26
|
+
data: {
|
|
27
|
+
email: item.email,
|
|
28
|
+
name: item.name,
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
33
|
+
function normalizeAttachment(item) {
|
|
34
|
+
return {
|
|
35
|
+
url: item.url,
|
|
36
|
+
id: item.id,
|
|
37
|
+
file_name: item.file_name,
|
|
38
|
+
author_id: item.author_id,
|
|
39
|
+
parent_id: item.parent_id,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"record_types": {
|
|
3
|
+
"issues": {
|
|
4
|
+
"name": "Issues",
|
|
5
|
+
"fields": {
|
|
6
|
+
"title": {
|
|
7
|
+
"is_required": true,
|
|
8
|
+
"type": "text",
|
|
9
|
+
"name": "Title",
|
|
10
|
+
"text": {
|
|
11
|
+
"min_length": 1
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"body": {
|
|
15
|
+
"type": "rich_text",
|
|
16
|
+
"name": "body",
|
|
17
|
+
"is_required": true
|
|
18
|
+
},
|
|
19
|
+
"owner": {
|
|
20
|
+
"is_required": true,
|
|
21
|
+
"type": "reference",
|
|
22
|
+
"reference": {
|
|
23
|
+
"refers_to": {
|
|
24
|
+
"#record:users": {}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"creator": {
|
|
29
|
+
"is_required": true,
|
|
30
|
+
"type": "reference",
|
|
31
|
+
"reference": {
|
|
32
|
+
"refers_to": {
|
|
33
|
+
"#record:users": {}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"users": {
|
|
40
|
+
"name": "Users",
|
|
41
|
+
"fields": {
|
|
42
|
+
"name": {
|
|
43
|
+
"is_required": true,
|
|
44
|
+
"type": "text",
|
|
45
|
+
"name": "Name",
|
|
46
|
+
"text": {
|
|
47
|
+
"min_length": 1
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
"email": {
|
|
51
|
+
"type": "text",
|
|
52
|
+
"name": "Email",
|
|
53
|
+
"is_required": true
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.processTask = processTask;
|
|
4
|
+
const node_worker_threads_1 = require("node:worker_threads");
|
|
5
|
+
const state_1 = require("../state/state");
|
|
6
|
+
const worker_adapter_1 = require("./worker-adapter");
|
|
7
|
+
const workers_1 = require("../types/workers");
|
|
8
|
+
const logger_1 = require("../logger/logger");
|
|
9
|
+
function processTask({ task, onTimeout, }) {
|
|
10
|
+
if (!node_worker_threads_1.isMainThread) {
|
|
11
|
+
(async () => {
|
|
12
|
+
const event = node_worker_threads_1.workerData.event;
|
|
13
|
+
const initialState = node_worker_threads_1.workerData.initialState;
|
|
14
|
+
const options = node_worker_threads_1.workerData.options;
|
|
15
|
+
console = new logger_1.Logger(event);
|
|
16
|
+
const adapterState = await (0, state_1.createAdapterState)({
|
|
17
|
+
event,
|
|
18
|
+
initialState,
|
|
19
|
+
options,
|
|
20
|
+
});
|
|
21
|
+
if (node_worker_threads_1.parentPort && node_worker_threads_1.workerData.event) {
|
|
22
|
+
const adapter = new worker_adapter_1.WorkerAdapter({
|
|
23
|
+
event,
|
|
24
|
+
adapterState,
|
|
25
|
+
parentPort: node_worker_threads_1.parentPort,
|
|
26
|
+
options,
|
|
27
|
+
});
|
|
28
|
+
node_worker_threads_1.parentPort.on(workers_1.WorkerEvent.WorkerMessage, async (message) => {
|
|
29
|
+
if (message.subject === workers_1.WorkerMessageSubject.WorkerMessageExit) {
|
|
30
|
+
adapter.handleTimeout();
|
|
31
|
+
await onTimeout({ adapter });
|
|
32
|
+
process.exit(0);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
await task({ adapter });
|
|
36
|
+
const message = {
|
|
37
|
+
subject: workers_1.WorkerMessageSubject.WorkerMessageDone,
|
|
38
|
+
};
|
|
39
|
+
node_worker_threads_1.parentPort.postMessage(message);
|
|
40
|
+
process.exit(0);
|
|
41
|
+
}
|
|
42
|
+
})();
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { SpawnFactoryInterface, SpawnInterface } from '../types/workers';
|
|
2
|
+
/**
|
|
3
|
+
* Creates a new instance of Spawn class.
|
|
4
|
+
* Spawn class is responsible for spawning a new worker thread and managing the lifecycle of the worker.
|
|
5
|
+
* The class provides utilities to emit control events to the platform and exit the worker gracefully.
|
|
6
|
+
* In case of lambda timeout, the class emits a lambda timeout event to the platform.
|
|
7
|
+
* @param {SpawnFactoryInterface} options - The options to create a new instance of Spawn class
|
|
8
|
+
* @param {AirdropEvent} event - The event object received from the platform
|
|
9
|
+
* @param {object} initialState - The initial state of the adapter
|
|
10
|
+
* @param {string} workerPath - The path to the worker file
|
|
11
|
+
* @returns {Promise<Spawn>} - A new instance of Spawn class
|
|
12
|
+
*/
|
|
13
|
+
export declare function spawn<ConnectorState>({ event, initialState, workerPath, options, }: SpawnFactoryInterface<ConnectorState>): Promise<boolean | PromiseLike<boolean>>;
|
|
14
|
+
export declare class Spawn {
|
|
15
|
+
private event;
|
|
16
|
+
private hasWorkerEmitted;
|
|
17
|
+
private defaultLambdaTimeout;
|
|
18
|
+
private lambdaTimeout;
|
|
19
|
+
private worker;
|
|
20
|
+
private resolve;
|
|
21
|
+
private timer;
|
|
22
|
+
private logger;
|
|
23
|
+
constructor({ event, worker, options, resolve }: SpawnInterface);
|
|
24
|
+
private exitFromMainThread;
|
|
25
|
+
}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Spawn = void 0;
|
|
4
|
+
exports.spawn = spawn;
|
|
5
|
+
const extraction_1 = require("../types/extraction");
|
|
6
|
+
const control_protocol_1 = require("../common/control-protocol");
|
|
7
|
+
const helpers_1 = require("../common/helpers");
|
|
8
|
+
const logger_1 = require("../logger/logger");
|
|
9
|
+
const constants_1 = require("../common/constants");
|
|
10
|
+
const workers_1 = require("../types/workers");
|
|
11
|
+
const create_worker_1 = require("./create-worker");
|
|
12
|
+
function getWorkerPath({ event, connectorWorkerPath, }) {
|
|
13
|
+
const logger = new logger_1.Logger(event);
|
|
14
|
+
if (!constants_1.ALLOWED_EVENT_TYPES.includes(event.payload.event_type)) {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
if (connectorWorkerPath)
|
|
18
|
+
return connectorWorkerPath;
|
|
19
|
+
let path = null;
|
|
20
|
+
switch (event.payload.event_type) {
|
|
21
|
+
case extraction_1.EventType.ExtractionExternalSyncUnitsStart:
|
|
22
|
+
path = __dirname + '/default-workers/external-sync-units-extraction';
|
|
23
|
+
break;
|
|
24
|
+
case extraction_1.EventType.ExtractionMetadataStart:
|
|
25
|
+
path = __dirname + '/default-workers/metadata-extraction';
|
|
26
|
+
break;
|
|
27
|
+
case extraction_1.EventType.ExtractionDataStart:
|
|
28
|
+
case extraction_1.EventType.ExtractionDataContinue:
|
|
29
|
+
path = __dirname + '/default-workers/data-extraction';
|
|
30
|
+
break;
|
|
31
|
+
case extraction_1.EventType.ExtractionAttachmentsStart:
|
|
32
|
+
case extraction_1.EventType.ExtractionAttachmentsContinue:
|
|
33
|
+
path = __dirname + '/default-workers/attachments-extraction';
|
|
34
|
+
break;
|
|
35
|
+
case extraction_1.EventType.ExtractionDataDelete:
|
|
36
|
+
path = __dirname + '/default-workers/data-deletion.js';
|
|
37
|
+
break;
|
|
38
|
+
case extraction_1.EventType.ExtractionAttachmentsDelete:
|
|
39
|
+
path = __dirname + '/default-workers/attachments-deletion';
|
|
40
|
+
break;
|
|
41
|
+
default:
|
|
42
|
+
logger.error('Worker script not found for event type: ' +
|
|
43
|
+
event.payload.event_type +
|
|
44
|
+
'.');
|
|
45
|
+
path = null;
|
|
46
|
+
}
|
|
47
|
+
return path;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Creates a new instance of Spawn class.
|
|
51
|
+
* Spawn class is responsible for spawning a new worker thread and managing the lifecycle of the worker.
|
|
52
|
+
* The class provides utilities to emit control events to the platform and exit the worker gracefully.
|
|
53
|
+
* In case of lambda timeout, the class emits a lambda timeout event to the platform.
|
|
54
|
+
* @param {SpawnFactoryInterface} options - The options to create a new instance of Spawn class
|
|
55
|
+
* @param {AirdropEvent} event - The event object received from the platform
|
|
56
|
+
* @param {object} initialState - The initial state of the adapter
|
|
57
|
+
* @param {string} workerPath - The path to the worker file
|
|
58
|
+
* @returns {Promise<Spawn>} - A new instance of Spawn class
|
|
59
|
+
*/
|
|
60
|
+
async function spawn({ event, initialState, workerPath, options, }) {
|
|
61
|
+
const logger = new logger_1.Logger(event);
|
|
62
|
+
const script = getWorkerPath({
|
|
63
|
+
event,
|
|
64
|
+
connectorWorkerPath: workerPath,
|
|
65
|
+
});
|
|
66
|
+
if (script) {
|
|
67
|
+
try {
|
|
68
|
+
const worker = await (0, create_worker_1.createWorker)({
|
|
69
|
+
event,
|
|
70
|
+
initialState,
|
|
71
|
+
workerPath: script,
|
|
72
|
+
options,
|
|
73
|
+
});
|
|
74
|
+
return new Promise((resolve) => {
|
|
75
|
+
new Spawn({
|
|
76
|
+
event,
|
|
77
|
+
worker,
|
|
78
|
+
options: options || null,
|
|
79
|
+
resolve,
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
logger.error('Worker error while processing task.', error);
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
throw new Error('Worker script not found.');
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
class Spawn {
|
|
93
|
+
constructor({ event, worker, options, resolve }) {
|
|
94
|
+
this.defaultLambdaTimeout = 10 * 60 * 1000; // 10 minutes in milliseconds
|
|
95
|
+
this.hasWorkerEmitted = false;
|
|
96
|
+
this.event = event;
|
|
97
|
+
this.lambdaTimeout = (options === null || options === void 0 ? void 0 : options.timeout)
|
|
98
|
+
? Math.min(options.timeout, this.defaultLambdaTimeout)
|
|
99
|
+
: this.defaultLambdaTimeout;
|
|
100
|
+
this.resolve = resolve;
|
|
101
|
+
this.timer = setTimeout(async () => {
|
|
102
|
+
this.logger.log('Lambda timeout reached. Exiting.');
|
|
103
|
+
if (this.worker) {
|
|
104
|
+
this.worker.postMessage({
|
|
105
|
+
subject: workers_1.WorkerMessageSubject.WorkerMessageExit,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
await this.exitFromMainThread();
|
|
110
|
+
}
|
|
111
|
+
}, this.lambdaTimeout);
|
|
112
|
+
this.logger = new logger_1.Logger(event);
|
|
113
|
+
this.worker = worker;
|
|
114
|
+
worker.on(workers_1.WorkerEvent.WorkerExit, async (code) => {
|
|
115
|
+
this.logger.info('Worker exited with exit code: ' + code + '.');
|
|
116
|
+
if (this.timer) {
|
|
117
|
+
clearTimeout(this.timer);
|
|
118
|
+
await this.exitFromMainThread();
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
worker.on(workers_1.WorkerEvent.WorkerMessage, async (message) => {
|
|
122
|
+
if ((message === null || message === void 0 ? void 0 : message.subject) === workers_1.WorkerMessageSubject.WorkerMessageEmitted) {
|
|
123
|
+
this.logger.info('Worker has emitted message to ADaaS.');
|
|
124
|
+
this.hasWorkerEmitted = true;
|
|
125
|
+
}
|
|
126
|
+
if ((message === null || message === void 0 ? void 0 : message.subject) === workers_1.WorkerMessageSubject.WorkerMessageDone) {
|
|
127
|
+
this.logger.info('Worker has completed work.');
|
|
128
|
+
clearTimeout(this.timer);
|
|
129
|
+
await this.exitFromMainThread();
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
worker.on(workers_1.WorkerEvent.WorkerMessage, (message) => {
|
|
133
|
+
var _a, _b;
|
|
134
|
+
if ((message === null || message === void 0 ? void 0 : message.subject) === workers_1.WorkerMessageSubject.WorkerMessageLog) {
|
|
135
|
+
const args = (_a = message.payload) === null || _a === void 0 ? void 0 : _a.args;
|
|
136
|
+
const level = (_b = message.payload) === null || _b === void 0 ? void 0 : _b.level;
|
|
137
|
+
this.logger.logFn(args, level);
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
async exitFromMainThread() {
|
|
142
|
+
if (this.hasWorkerEmitted) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
const timeoutEventType = (0, helpers_1.getErrorExtractorEventType)(this.event.payload.event_type);
|
|
146
|
+
if (timeoutEventType !== null) {
|
|
147
|
+
const { eventType } = timeoutEventType;
|
|
148
|
+
await (0, control_protocol_1.emit)({
|
|
149
|
+
eventType,
|
|
150
|
+
event: this.event,
|
|
151
|
+
data: {
|
|
152
|
+
error: {
|
|
153
|
+
message: 'Worker has not emitted anything. Exited.',
|
|
154
|
+
},
|
|
155
|
+
},
|
|
156
|
+
}).then(() => {
|
|
157
|
+
this.logger.error('Worker has not emitted anything. Exited.');
|
|
158
|
+
this.resolve(true);
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
exports.Spawn = Spawn;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { AirdropEvent, ExtractorEventType, EventData } from '../types/extraction';
|
|
2
|
+
import { AdapterState } from '../state/state.interfaces';
|
|
3
|
+
import { Artifact } from '../uploader/uploader.interfaces';
|
|
4
|
+
import { WorkerAdapterInterface, WorkerAdapterOptions } from '../types/workers';
|
|
5
|
+
import { Repo } from '../repo/repo';
|
|
6
|
+
import { RepoInterface } from '../repo/repo.interfaces';
|
|
7
|
+
export declare function createWorkerAdapter<ConnectorState>({ event, adapterState, parentPort, options, }: WorkerAdapterInterface<ConnectorState>): WorkerAdapter<ConnectorState>;
|
|
8
|
+
/**
|
|
9
|
+
* WorkerAdapter class is used to interact with Airdrop platform. It is passed to the snap-in
|
|
10
|
+
* as parameter in processTask and onTimeout functions. The class provides
|
|
11
|
+
* utilities to emit control events to the platform, update the state of the connector,
|
|
12
|
+
* and upload artifacts to the platform.
|
|
13
|
+
* @class WorkerAdapter
|
|
14
|
+
* @constructor
|
|
15
|
+
* @param {WorkerAdapterInterface} options - The options to create a new instance of WorkerAdapter class
|
|
16
|
+
* @param {AirdropEvent} event - The event object received from the platform
|
|
17
|
+
* @param {object=} initialState - The initial state of the adapter
|
|
18
|
+
* @param {boolean=} isLocalDevelopment - A flag to indicate if the adapter is being used in local development
|
|
19
|
+
* @param {string} workerPath - The path to the worker file
|
|
20
|
+
*
|
|
21
|
+
*/
|
|
22
|
+
export declare class WorkerAdapter<ConnectorState> {
|
|
23
|
+
readonly event: AirdropEvent;
|
|
24
|
+
readonly options: WorkerAdapterOptions;
|
|
25
|
+
private adapterState;
|
|
26
|
+
private _artifacts;
|
|
27
|
+
private hasWorkerEmitted;
|
|
28
|
+
private parentPort;
|
|
29
|
+
private isTimeout;
|
|
30
|
+
private repos;
|
|
31
|
+
constructor({ event, adapterState, parentPort, options, }: WorkerAdapterInterface<ConnectorState>);
|
|
32
|
+
get state(): AdapterState<ConnectorState>;
|
|
33
|
+
set state(value: AdapterState<ConnectorState>);
|
|
34
|
+
initializeRepos(repos: RepoInterface[]): void;
|
|
35
|
+
getRepo(itemType: string): Repo | undefined;
|
|
36
|
+
postState(): Promise<void>;
|
|
37
|
+
get artifacts(): Artifact[];
|
|
38
|
+
set artifacts(artifacts: Artifact[]);
|
|
39
|
+
/**
|
|
40
|
+
* Emits an event to the platform.
|
|
41
|
+
*
|
|
42
|
+
* @param {ExtractorEventType} newEventType - The event type to be emitted
|
|
43
|
+
* @param {EventData=} data - The data to be sent with the event
|
|
44
|
+
*/
|
|
45
|
+
emit(newEventType: ExtractorEventType, data?: EventData): Promise<void>;
|
|
46
|
+
uploadAllRepos(): Promise<void>;
|
|
47
|
+
handleTimeout(): void;
|
|
48
|
+
}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WorkerAdapter = void 0;
|
|
4
|
+
exports.createWorkerAdapter = createWorkerAdapter;
|
|
5
|
+
const extraction_1 = require("../types/extraction");
|
|
6
|
+
const constants_1 = require("../common/constants");
|
|
7
|
+
const control_protocol_1 = require("../common/control-protocol");
|
|
8
|
+
const workers_1 = require("../types/workers");
|
|
9
|
+
const repo_1 = require("../repo/repo");
|
|
10
|
+
function createWorkerAdapter({ event, adapterState, parentPort, options, }) {
|
|
11
|
+
return new WorkerAdapter({
|
|
12
|
+
event,
|
|
13
|
+
adapterState,
|
|
14
|
+
parentPort,
|
|
15
|
+
options,
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* WorkerAdapter class is used to interact with Airdrop platform. It is passed to the snap-in
|
|
20
|
+
* as parameter in processTask and onTimeout functions. The class provides
|
|
21
|
+
* utilities to emit control events to the platform, update the state of the connector,
|
|
22
|
+
* and upload artifacts to the platform.
|
|
23
|
+
* @class WorkerAdapter
|
|
24
|
+
* @constructor
|
|
25
|
+
* @param {WorkerAdapterInterface} options - The options to create a new instance of WorkerAdapter class
|
|
26
|
+
* @param {AirdropEvent} event - The event object received from the platform
|
|
27
|
+
* @param {object=} initialState - The initial state of the adapter
|
|
28
|
+
* @param {boolean=} isLocalDevelopment - A flag to indicate if the adapter is being used in local development
|
|
29
|
+
* @param {string} workerPath - The path to the worker file
|
|
30
|
+
*
|
|
31
|
+
*/
|
|
32
|
+
class WorkerAdapter {
|
|
33
|
+
constructor({ event, adapterState, parentPort, options, }) {
|
|
34
|
+
this.repos = [];
|
|
35
|
+
this.event = event;
|
|
36
|
+
this.options = options;
|
|
37
|
+
this.adapterState = adapterState;
|
|
38
|
+
this._artifacts = [];
|
|
39
|
+
this.parentPort = parentPort;
|
|
40
|
+
this.hasWorkerEmitted = false;
|
|
41
|
+
this.isTimeout = false;
|
|
42
|
+
}
|
|
43
|
+
get state() {
|
|
44
|
+
return this.adapterState.state;
|
|
45
|
+
}
|
|
46
|
+
set state(value) {
|
|
47
|
+
if (!this.isTimeout) {
|
|
48
|
+
this.adapterState.state = value;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
initializeRepos(repos) {
|
|
52
|
+
this.repos = repos.map((repo) => {
|
|
53
|
+
const shouldNormalize = !Object.values(constants_1.AIRDROP_DEFAULT_ITEM_TYPES).includes(repo.itemType);
|
|
54
|
+
return new repo_1.Repo(Object.assign(Object.assign({ event: this.event, itemType: repo.itemType }, (shouldNormalize && { normalize: repo.normalize })), { onUpload: (artifact) => {
|
|
55
|
+
var _a;
|
|
56
|
+
this.artifacts.push(artifact);
|
|
57
|
+
// We need to store artifacts ids in state for later use when streaming attachments
|
|
58
|
+
if (repo.itemType === constants_1.AIRDROP_DEFAULT_ITEM_TYPES.ATTACHMENTS) {
|
|
59
|
+
(_a = this.state.toDevRev) === null || _a === void 0 ? void 0 : _a.attachmentsMetadata.artifactIds.push(artifact.id);
|
|
60
|
+
}
|
|
61
|
+
}, options: this.options }));
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
getRepo(itemType) {
|
|
65
|
+
const repo = this.repos.find((repo) => repo.itemType === itemType);
|
|
66
|
+
if (!repo) {
|
|
67
|
+
console.error(`Repo not found for item type: ${itemType}.`);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
return repo;
|
|
71
|
+
}
|
|
72
|
+
async postState() {
|
|
73
|
+
await this.adapterState.postState();
|
|
74
|
+
}
|
|
75
|
+
get artifacts() {
|
|
76
|
+
return this._artifacts;
|
|
77
|
+
}
|
|
78
|
+
set artifacts(artifacts) {
|
|
79
|
+
this._artifacts = this._artifacts
|
|
80
|
+
.concat(artifacts)
|
|
81
|
+
.filter((value, index, self) => self.indexOf(value) === index);
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Emits an event to the platform.
|
|
85
|
+
*
|
|
86
|
+
* @param {ExtractorEventType} newEventType - The event type to be emitted
|
|
87
|
+
* @param {EventData=} data - The data to be sent with the event
|
|
88
|
+
*/
|
|
89
|
+
async emit(newEventType, data) {
|
|
90
|
+
if (this.hasWorkerEmitted) {
|
|
91
|
+
console.warn('Unable to emit with event type:' +
|
|
92
|
+
newEventType +
|
|
93
|
+
'. Lambda is going to be stopped.');
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
// We want to upload all the repos before emitting the event, except for the external sync units done event
|
|
97
|
+
if (newEventType !== extraction_1.ExtractorEventType.ExtractionExternalSyncUnitsDone) {
|
|
98
|
+
await this.uploadAllRepos();
|
|
99
|
+
}
|
|
100
|
+
// If the extraction is done, we want to save the timestamp of the last successful sync
|
|
101
|
+
if (newEventType === extraction_1.ExtractorEventType.ExtractionAttachmentsDone) {
|
|
102
|
+
this.state.lastSuccessfulSyncStarted = this.state.lastSyncStarted;
|
|
103
|
+
}
|
|
104
|
+
// We want to save the state every time we emit an event, except for the start and delete events
|
|
105
|
+
if (!constants_1.STATELESS_EVENT_TYPES.includes(this.event.payload.event_type)) {
|
|
106
|
+
console.log(`Saving state before emitting event with event type: ` +
|
|
107
|
+
newEventType +
|
|
108
|
+
'.');
|
|
109
|
+
await this.adapterState.postState(this.state);
|
|
110
|
+
}
|
|
111
|
+
try {
|
|
112
|
+
await (0, control_protocol_1.emit)({
|
|
113
|
+
eventType: newEventType,
|
|
114
|
+
event: this.event,
|
|
115
|
+
data: Object.assign(Object.assign({}, data), { artifacts: this.artifacts }),
|
|
116
|
+
});
|
|
117
|
+
const message = {
|
|
118
|
+
subject: workers_1.WorkerMessageSubject.WorkerMessageEmitted,
|
|
119
|
+
payload: { eventType: newEventType },
|
|
120
|
+
};
|
|
121
|
+
this.artifacts = [];
|
|
122
|
+
this.parentPort.postMessage(message);
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
console.error('Error while emitting event with event type: ' + newEventType + '.', error);
|
|
126
|
+
this.parentPort.postMessage(workers_1.WorkerMessageSubject.WorkerMessageExit);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
async uploadAllRepos() {
|
|
130
|
+
for (const repo of this.repos) {
|
|
131
|
+
await repo.upload();
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
handleTimeout() {
|
|
135
|
+
this.isTimeout = true;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
exports.WorkerAdapter = WorkerAdapter;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@devrev/ts-adaas",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "Typescript library containing the ADaaS(AirDrop as a Service) control protocol.",
|
|
5
5
|
"type": "commonjs",
|
|
6
|
-
"main": "./dist/
|
|
7
|
-
"typings": "./dist/
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"typings": "./dist/index.d.ts",
|
|
8
8
|
"scripts": {
|
|
9
|
-
"build": "tsc",
|
|
9
|
+
"build": "tsc -p ./tsconfig.json",
|
|
10
10
|
"start": "ts-node src/index.ts",
|
|
11
11
|
"lint": "eslint .",
|
|
12
12
|
"lint:fix": "eslint . --fix",
|
|
@@ -17,13 +17,15 @@
|
|
|
17
17
|
"url": "git+https://github.com/devrev/adaas-sdk.git"
|
|
18
18
|
},
|
|
19
19
|
"publishConfig": {
|
|
20
|
-
"registry": "https://
|
|
20
|
+
"registry": "https://npm.pkg.github.com"
|
|
21
21
|
},
|
|
22
22
|
"keywords": [],
|
|
23
23
|
"author": "devrev",
|
|
24
24
|
"license": "ISC",
|
|
25
25
|
"devDependencies": {
|
|
26
26
|
"@types/jest": "^29.5.12",
|
|
27
|
+
"@types/lambda-log": "^3.0.3",
|
|
28
|
+
"@types/node": "20.16.11",
|
|
27
29
|
"@typescript-eslint/eslint-plugin": "^7.12.0",
|
|
28
30
|
"@typescript-eslint/parser": "^7.12.0",
|
|
29
31
|
"eslint": "^8.57.0",
|
|
@@ -36,7 +38,9 @@
|
|
|
36
38
|
"dependencies": {
|
|
37
39
|
"@devrev/typescript-sdk": "^1.1.27",
|
|
38
40
|
"axios": "^1.5.1",
|
|
41
|
+
"form-data": "^4.0.1",
|
|
39
42
|
"js-jsonl": "^1.1.1",
|
|
43
|
+
"lambda-log": "^3.1.0",
|
|
40
44
|
"ts-node": "^10.9.2"
|
|
41
45
|
},
|
|
42
46
|
"files": [
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.STATELESS_EVENT_TYPES = void 0;
|
|
4
|
-
const types_1 = require("../types");
|
|
5
|
-
exports.STATELESS_EVENT_TYPES = [
|
|
6
|
-
types_1.EventType.ExtractionExternalSyncUnitsStart,
|
|
7
|
-
types_1.EventType.ExtractionMetadataStart,
|
|
8
|
-
types_1.EventType.ExtractionDataDelete,
|
|
9
|
-
types_1.EventType.ExtractionAttachmentsDelete,
|
|
10
|
-
];
|