@devrev/airsync-sdk 2.0.0-beta.0 → 2.0.0-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.
- package/README.md +0 -4
- package/dist/airsync-sdk.d.ts +1802 -0
- package/dist/attachments-streaming/attachments-streaming-pool.d.ts +7 -0
- package/dist/attachments-streaming/attachments-streaming-pool.d.ts.map +1 -1
- package/dist/attachments-streaming/attachments-streaming-pool.js +44 -4
- package/dist/attachments-streaming/attachments-streaming-pool.test.js +259 -10
- package/dist/common/constants.d.ts +16 -5
- package/dist/common/constants.d.ts.map +1 -1
- package/dist/common/constants.js +20 -6
- package/dist/common/control-protocol.d.ts +2 -2
- package/dist/common/control-protocol.d.ts.map +1 -1
- package/dist/common/control-protocol.js +1 -5
- package/dist/common/helpers.d.ts +8 -0
- package/dist/common/helpers.d.ts.map +1 -1
- package/dist/common/helpers.js +15 -0
- package/dist/common/install-initial-domain-mapping.d.ts +2 -2
- package/dist/common/install-initial-domain-mapping.test.js +7 -3
- package/dist/common/test-utils.d.ts +19 -0
- package/dist/common/test-utils.d.ts.map +1 -0
- package/dist/common/test-utils.js +101 -0
- package/dist/common/time-value-resolver.d.ts +47 -0
- package/dist/common/time-value-resolver.d.ts.map +1 -0
- package/dist/common/time-value-resolver.js +141 -0
- package/dist/common/time-value-resolver.test.d.ts +2 -0
- package/dist/common/time-value-resolver.test.d.ts.map +1 -0
- package/dist/common/time-value-resolver.test.js +268 -0
- package/dist/http/axios-client-internal.d.ts.map +1 -1
- package/dist/http/axios-client-internal.js +7 -0
- package/dist/http/axios-client-internal.test.js +27 -6
- package/dist/http/axios-client.d.ts.map +1 -1
- package/dist/http/axios-client.js +6 -3
- package/dist/http/index.d.ts +0 -1
- package/dist/http/index.d.ts.map +1 -1
- package/dist/http/index.js +0 -1
- package/dist/index.d.ts +9 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -10
- package/dist/logger/logger.d.ts +1 -17
- package/dist/logger/logger.d.ts.map +1 -1
- package/dist/logger/logger.interfaces.d.ts +2 -2
- package/dist/logger/logger.js +35 -27
- package/dist/logger/logger.test.js +66 -19
- package/dist/mappers/mappers.interface.d.ts +5 -5
- package/dist/mappers/mappers.interface.js +3 -3
- package/dist/mappers/mappers.test.js +8 -10
- package/dist/mock-server/mock-server.d.ts +47 -0
- package/dist/mock-server/mock-server.d.ts.map +1 -0
- package/dist/mock-server/mock-server.interfaces.d.ts +73 -0
- package/dist/mock-server/mock-server.interfaces.d.ts.map +1 -0
- package/dist/mock-server/mock-server.interfaces.js +4 -0
- package/dist/mock-server/mock-server.js +278 -0
- package/dist/multithreading/create-worker.test.js +36 -17
- package/dist/multithreading/process-task.d.ts.map +1 -1
- package/dist/multithreading/process-task.js +46 -44
- package/dist/multithreading/process-task.test.d.ts +2 -0
- package/dist/multithreading/process-task.test.d.ts.map +1 -0
- package/dist/multithreading/process-task.test.js +146 -0
- package/dist/multithreading/spawn/spawn.d.ts +4 -3
- package/dist/multithreading/spawn/spawn.d.ts.map +1 -1
- package/dist/multithreading/spawn/spawn.helpers.d.ts.map +1 -1
- package/dist/multithreading/spawn/spawn.helpers.js +6 -14
- package/dist/multithreading/spawn/spawn.helpers.test.js +8 -8
- package/dist/multithreading/spawn/spawn.js +41 -31
- package/dist/multithreading/spawn/spawn.test.d.ts +2 -0
- package/dist/multithreading/spawn/spawn.test.d.ts.map +1 -0
- package/dist/multithreading/spawn/spawn.test.js +232 -0
- package/dist/multithreading/worker-adapter/worker-adapter.artifacts.test.js +49 -1
- package/dist/multithreading/worker-adapter/worker-adapter.d.ts +11 -5
- package/dist/multithreading/worker-adapter/worker-adapter.d.ts.map +1 -1
- package/dist/multithreading/worker-adapter/worker-adapter.emit.test.d.ts +2 -0
- package/dist/multithreading/worker-adapter/worker-adapter.emit.test.d.ts.map +1 -0
- package/dist/multithreading/worker-adapter/worker-adapter.emit.test.js +390 -0
- package/dist/multithreading/worker-adapter/worker-adapter.extraction.test.d.ts +2 -0
- package/dist/multithreading/worker-adapter/worker-adapter.extraction.test.d.ts.map +1 -0
- package/dist/multithreading/worker-adapter/worker-adapter.extraction.test.js +799 -0
- package/dist/multithreading/worker-adapter/worker-adapter.js +233 -134
- package/dist/multithreading/worker-adapter/worker-adapter.loading.test.d.ts +2 -0
- package/dist/multithreading/worker-adapter/worker-adapter.loading.test.d.ts.map +1 -0
- package/dist/multithreading/worker-adapter/worker-adapter.loading.test.js +596 -0
- package/dist/multithreading/worker-adapter/worker-adapter.serialization.test.d.ts +2 -0
- package/dist/multithreading/worker-adapter/worker-adapter.serialization.test.d.ts.map +1 -0
- package/dist/multithreading/worker-adapter/worker-adapter.serialization.test.js +71 -0
- package/dist/repo/repo.d.ts.map +1 -1
- package/dist/repo/repo.interfaces.d.ts +4 -2
- package/dist/repo/repo.interfaces.d.ts.map +1 -1
- package/dist/repo/repo.js +4 -3
- package/dist/repo/repo.test.js +60 -7
- package/dist/state/state.d.ts +7 -1
- package/dist/state/state.d.ts.map +1 -1
- package/dist/state/state.extract-window.test.d.ts +2 -0
- package/dist/state/state.extract-window.test.d.ts.map +1 -0
- package/dist/state/state.extract-window.test.js +163 -0
- package/dist/state/state.interfaces.d.ts +25 -8
- package/dist/state/state.interfaces.d.ts.map +1 -1
- package/dist/state/state.interfaces.js +4 -2
- package/dist/state/state.js +111 -12
- package/dist/state/state.pending-boundaries.test.d.ts +2 -0
- package/dist/state/state.pending-boundaries.test.d.ts.map +1 -0
- package/dist/state/state.pending-boundaries.test.js +189 -0
- package/dist/state/state.post-state.test.d.ts +2 -0
- package/dist/state/state.post-state.test.d.ts.map +1 -0
- package/dist/state/state.post-state.test.js +77 -0
- package/dist/state/state.test.js +117 -73
- package/dist/state/state.time-value-resolution.test.d.ts +2 -0
- package/dist/state/state.time-value-resolution.test.d.ts.map +1 -0
- package/dist/state/state.time-value-resolution.test.js +175 -0
- package/dist/tsdoc-metadata.json +11 -0
- package/dist/types/common.d.ts +0 -25
- package/dist/types/common.d.ts.map +1 -1
- package/dist/types/common.js +1 -11
- package/dist/types/external-domain-metadata.d.ts +338 -0
- package/dist/types/external-domain-metadata.d.ts.map +1 -0
- package/dist/types/extraction.d.ts +89 -218
- package/dist/types/extraction.d.ts.map +1 -1
- package/dist/types/extraction.js +56 -124
- package/dist/types/extraction.test.js +69 -43
- package/dist/types/index.d.ts +4 -2
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +6 -3
- package/dist/types/loading.d.ts +4 -24
- package/dist/types/loading.d.ts.map +1 -1
- package/dist/types/loading.js +1 -22
- package/dist/types/workers.d.ts +31 -14
- package/dist/types/workers.d.ts.map +1 -1
- package/dist/types/workers.js +1 -0
- package/dist/uploader/uploader.d.ts +1 -0
- package/dist/uploader/uploader.d.ts.map +1 -1
- package/dist/uploader/uploader.helpers.test.js +0 -11
- package/dist/uploader/uploader.interfaces.d.ts +3 -3
- package/dist/uploader/uploader.js +53 -20
- package/dist/uploader/uploader.test.js +22 -10
- package/package.json +12 -11
- package/dist/common/event-type-translation.d.ts +0 -24
- package/dist/common/event-type-translation.d.ts.map +0 -1
- package/dist/common/event-type-translation.js +0 -117
- package/dist/deprecated/adapter/index.d.ts +0 -62
- package/dist/deprecated/adapter/index.d.ts.map +0 -1
- package/dist/deprecated/adapter/index.js +0 -151
- package/dist/deprecated/common/helpers.d.ts +0 -7
- package/dist/deprecated/common/helpers.d.ts.map +0 -1
- package/dist/deprecated/common/helpers.js +0 -47
- package/dist/deprecated/demo-extractor/external_domain_metadata.json +0 -38
- package/dist/deprecated/demo-extractor/index.d.ts +0 -18
- package/dist/deprecated/demo-extractor/index.d.ts.map +0 -1
- package/dist/deprecated/demo-extractor/index.js +0 -161
- package/dist/deprecated/http/client.d.ts +0 -22
- package/dist/deprecated/http/client.d.ts.map +0 -1
- package/dist/deprecated/http/client.js +0 -161
- package/dist/deprecated/uploader/index.d.ts +0 -35
- package/dist/deprecated/uploader/index.d.ts.map +0 -1
- package/dist/deprecated/uploader/index.js +0 -161
- package/dist/http/types.d.ts +0 -17
- package/dist/http/types.d.ts.map +0 -1
- package/dist/multithreading/worker-adapter/worker-adapter.test.d.ts +0 -2
- package/dist/multithreading/worker-adapter/worker-adapter.test.d.ts.map +0 -1
- package/dist/multithreading/worker-adapter/worker-adapter.test.js +0 -483
- /package/dist/{http/types.js → types/external-domain-metadata.js} +0 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { IncomingMessage, ServerResponse } from 'http';
|
|
2
|
+
export declare const DEFAULT_MOCK_SERVER_PORT = 3001;
|
|
3
|
+
export interface ParsedRequest extends IncomingMessage {
|
|
4
|
+
/** Parsed URL path (without query string) */
|
|
5
|
+
path: string;
|
|
6
|
+
/** Parsed JSON body (if any) */
|
|
7
|
+
body?: unknown;
|
|
8
|
+
}
|
|
9
|
+
export interface MockResponse extends ServerResponse {
|
|
10
|
+
/** Set response headers from a record */
|
|
11
|
+
set(headers: Record<string, string>): MockResponse;
|
|
12
|
+
/** Set the HTTP status code */
|
|
13
|
+
status(code: number): MockResponse;
|
|
14
|
+
/** Send a JSON response */
|
|
15
|
+
json(data: unknown): void;
|
|
16
|
+
/** Send an empty response */
|
|
17
|
+
send(): void;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Configuration for retry simulation behavior.
|
|
21
|
+
*/
|
|
22
|
+
export interface RetryConfig {
|
|
23
|
+
/** Number of times to return error before succeeding (default: 4) */
|
|
24
|
+
failureCount?: number;
|
|
25
|
+
/** 5xx status code to return during failures (default: 500) */
|
|
26
|
+
errorStatus?: number;
|
|
27
|
+
/** Optional error response body to send as JSON during failures */
|
|
28
|
+
errorBody?: unknown;
|
|
29
|
+
/** Optional headers to send with the error response */
|
|
30
|
+
headers?: Record<string, string>;
|
|
31
|
+
/** Optional delay in milliseconds before sending each failure response */
|
|
32
|
+
delay?: number;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Configuration object for setting up a route response.
|
|
36
|
+
*/
|
|
37
|
+
export interface RouteConfig {
|
|
38
|
+
/** The path of the route (e.g., '/callback_url', '/worker_data_url.get') */
|
|
39
|
+
path: string;
|
|
40
|
+
/** The HTTP method (e.g., 'GET', 'POST', 'PUT', 'DELETE') */
|
|
41
|
+
method: string;
|
|
42
|
+
/** The HTTP status code to return (e.g., 200, 401, 500) */
|
|
43
|
+
status: number;
|
|
44
|
+
/** Optional response body to send as JSON */
|
|
45
|
+
body?: unknown;
|
|
46
|
+
/** Optional headers to send with the response */
|
|
47
|
+
headers?: Record<string, string>;
|
|
48
|
+
/** Optional retry configuration for simulating failures before success */
|
|
49
|
+
retry?: RetryConfig;
|
|
50
|
+
/** Optional delay in milliseconds before sending the response */
|
|
51
|
+
delay?: number;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Type for custom route handler functions.
|
|
55
|
+
*/
|
|
56
|
+
export type RouteHandler = (req: ParsedRequest, res: MockResponse) => unknown;
|
|
57
|
+
/**
|
|
58
|
+
* Information about a request received by the mock server.
|
|
59
|
+
*/
|
|
60
|
+
export interface RequestInfo {
|
|
61
|
+
/** The HTTP method (e.g., 'GET', 'POST') */
|
|
62
|
+
method: string;
|
|
63
|
+
/** The full URL path of the request */
|
|
64
|
+
url: string;
|
|
65
|
+
/** Optional request body (for POST/PUT requests) */
|
|
66
|
+
body?: unknown;
|
|
67
|
+
}
|
|
68
|
+
export type RouteHandlers = Map<string, RouteHandler>;
|
|
69
|
+
/**
|
|
70
|
+
* Type for tracking request counts per route.
|
|
71
|
+
*/
|
|
72
|
+
export type RequestCounts = Map<string, number>;
|
|
73
|
+
//# sourceMappingURL=mock-server.interfaces.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mock-server.interfaces.d.ts","sourceRoot":"","sources":["../../src/mock-server/mock-server.interfaces.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,MAAM,CAAC;AAEvD,eAAO,MAAM,wBAAwB,OAAO,CAAC;AAE7C,MAAM,WAAW,aAAc,SAAQ,eAAe;IACpD,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,gCAAgC;IAChC,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,YAAa,SAAQ,cAAc;IAClD,yCAAyC;IACzC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,YAAY,CAAC;IACnD,+BAA+B;IAC/B,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAAC;IACnC,2BAA2B;IAC3B,IAAI,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAC1B,6BAA6B;IAC7B,IAAI,IAAI,IAAI,CAAC;CACd;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,qEAAqE;IACrE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,+DAA+D;IAC/D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mEAAmE;IACnE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,uDAAuD;IACvD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,0EAA0E;IAC1E,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,4EAA4E;IAC5E,IAAI,EAAE,MAAM,CAAC;IACb,6DAA6D;IAC7D,MAAM,EAAE,MAAM,CAAC;IACf,2DAA2D;IAC3D,MAAM,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,iDAAiD;IACjD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,0EAA0E;IAC1E,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,iEAAiE;IACjE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,GAAG,EAAE,aAAa,EAAE,GAAG,EAAE,YAAY,KAAK,OAAO,CAAC;AAE9E;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,4CAA4C;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,uCAAuC;IACvC,GAAG,EAAE,MAAM,CAAC;IACZ,oDAAoD;IACpD,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,MAAM,aAAa,GAAG,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;AAEtD;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC"}
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MockServer = void 0;
|
|
4
|
+
const http_1 = require("http");
|
|
5
|
+
const mock_server_interfaces_1 = require("./mock-server.interfaces");
|
|
6
|
+
const MAX_BODY_SIZE = 10 * 1024 * 1024; // 10mb
|
|
7
|
+
/**
|
|
8
|
+
* Parses the JSON body from an incoming request.
|
|
9
|
+
*/
|
|
10
|
+
async function parseJsonBody(req) {
|
|
11
|
+
return new Promise((resolve, reject) => {
|
|
12
|
+
const chunks = [];
|
|
13
|
+
let size = 0;
|
|
14
|
+
req.on('data', (chunk) => {
|
|
15
|
+
size += chunk.length;
|
|
16
|
+
if (size > MAX_BODY_SIZE) {
|
|
17
|
+
reject(new Error('Request body too large'));
|
|
18
|
+
req.destroy();
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
chunks.push(chunk);
|
|
22
|
+
});
|
|
23
|
+
req.on('end', () => {
|
|
24
|
+
if (chunks.length === 0) {
|
|
25
|
+
resolve(undefined);
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
try {
|
|
29
|
+
const raw = Buffer.concat(chunks).toString('utf-8');
|
|
30
|
+
resolve(JSON.parse(raw));
|
|
31
|
+
}
|
|
32
|
+
catch (_a) {
|
|
33
|
+
resolve(undefined);
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
req.on('error', reject);
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Wraps a ServerResponse with helper methods (status, json, set, send).
|
|
41
|
+
*/
|
|
42
|
+
function wrapResponse(res) {
|
|
43
|
+
const mock = res;
|
|
44
|
+
let statusCode = 200;
|
|
45
|
+
mock.set = (headers) => {
|
|
46
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
47
|
+
res.setHeader(key, value);
|
|
48
|
+
}
|
|
49
|
+
return mock;
|
|
50
|
+
};
|
|
51
|
+
mock.status = (code) => {
|
|
52
|
+
statusCode = code;
|
|
53
|
+
return mock;
|
|
54
|
+
};
|
|
55
|
+
mock.json = (data) => {
|
|
56
|
+
res.writeHead(statusCode, { 'Content-Type': 'application/json' });
|
|
57
|
+
res.end(JSON.stringify(data));
|
|
58
|
+
};
|
|
59
|
+
mock.send = () => {
|
|
60
|
+
res.writeHead(statusCode);
|
|
61
|
+
res.end();
|
|
62
|
+
};
|
|
63
|
+
return mock;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* MockServer used in tests to mock internal AirSync endpoints.
|
|
67
|
+
* This is a simple mock server that listens on a port and responds to requests.
|
|
68
|
+
* Supports per-test route configuration to simulate different response scenarios.
|
|
69
|
+
*/
|
|
70
|
+
class MockServer {
|
|
71
|
+
constructor(port = mock_server_interfaces_1.DEFAULT_MOCK_SERVER_PORT) {
|
|
72
|
+
this.server = null;
|
|
73
|
+
this.routeHandlers = new Map();
|
|
74
|
+
this.requests = [];
|
|
75
|
+
this.requestCounts = new Map();
|
|
76
|
+
this.internalPort = port;
|
|
77
|
+
this.port = port;
|
|
78
|
+
this.baseUrl = `http://localhost:${this.port}`;
|
|
79
|
+
}
|
|
80
|
+
async start() {
|
|
81
|
+
return new Promise((resolve) => {
|
|
82
|
+
this.server = (0, http_1.createServer)((req, res) => {
|
|
83
|
+
this.handleRequest(req, res).catch(() => {
|
|
84
|
+
res.writeHead(500);
|
|
85
|
+
res.end();
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
this.server.listen(this.internalPort, () => {
|
|
89
|
+
var _a, _b;
|
|
90
|
+
const actualPort = (_b = (_a = this.server) === null || _a === void 0 ? void 0 : _a.address()) === null || _b === void 0 ? void 0 : _b.port;
|
|
91
|
+
if (actualPort) {
|
|
92
|
+
this.port = actualPort;
|
|
93
|
+
this.baseUrl = `http://localhost:${this.port}`;
|
|
94
|
+
}
|
|
95
|
+
console.log(`Mock server running on http://localhost:${this.port}.`);
|
|
96
|
+
resolve();
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
async stop() {
|
|
101
|
+
if (!this.server) {
|
|
102
|
+
return Promise.resolve();
|
|
103
|
+
}
|
|
104
|
+
return new Promise((resolve, reject) => {
|
|
105
|
+
this.server.close((err) => {
|
|
106
|
+
if (err) {
|
|
107
|
+
reject(err);
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
console.log('Mock server stopped.');
|
|
111
|
+
this.server = null;
|
|
112
|
+
resolve();
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
async handleRequest(raw, rawRes) {
|
|
118
|
+
const req = raw;
|
|
119
|
+
const res = wrapResponse(rawRes);
|
|
120
|
+
const urlPath = (req.url || '/').split('?')[0];
|
|
121
|
+
req.path = urlPath;
|
|
122
|
+
req.body = await parseJsonBody(req);
|
|
123
|
+
const requestInfo = Object.assign({ method: req.method || 'GET', url: req.url || urlPath }, (req.body !== undefined && req.body !== null
|
|
124
|
+
? { body: req.body }
|
|
125
|
+
: {}));
|
|
126
|
+
this.requests.push(requestInfo);
|
|
127
|
+
const method = (req.method || 'GET').toUpperCase();
|
|
128
|
+
const key = `${method}:${urlPath}`;
|
|
129
|
+
const customHandler = this.routeHandlers.get(key);
|
|
130
|
+
if (customHandler) {
|
|
131
|
+
customHandler(req, res);
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
this.defaultRouteHandler(req, res);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Default route handler for the mock server. Returns { success: true } for
|
|
139
|
+
* routes that are not explicitly set.
|
|
140
|
+
*/
|
|
141
|
+
defaultRouteHandler(req, res) {
|
|
142
|
+
if (req.method === 'GET' && req.path === '/worker_data_url.get') {
|
|
143
|
+
res.status(200).json({
|
|
144
|
+
state: JSON.stringify({}),
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
else if (req.method === 'GET' && req.path === '/internal/snap-ins.get') {
|
|
148
|
+
res.status(200).json({
|
|
149
|
+
snap_in: {
|
|
150
|
+
imports: [{ name: 'test_import_slug' }],
|
|
151
|
+
snap_in_version: { slug: 'test_snap_in_slug' },
|
|
152
|
+
},
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
else if (req.method === 'GET' &&
|
|
156
|
+
req.path === '/internal/airdrop.artifacts.upload-url') {
|
|
157
|
+
const artifactId = `artifact-${Date.now()}-${Math.random()
|
|
158
|
+
.toString(36)
|
|
159
|
+
.substr(2, 9)}`;
|
|
160
|
+
res.status(200).json({
|
|
161
|
+
upload_url: `${this.baseUrl}/file-upload-url`,
|
|
162
|
+
artifact_id: artifactId,
|
|
163
|
+
form_data: [],
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
res.status(200).json({ success: true });
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
getRouteKey(method, path) {
|
|
171
|
+
return `${method.toUpperCase()}:${path}`;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Configures a route to return a specific status code and optional response body.
|
|
175
|
+
*/
|
|
176
|
+
setRoute(config) {
|
|
177
|
+
const { path, method, status, body, retry, headers, delay } = config;
|
|
178
|
+
const key = this.getRouteKey(method, path);
|
|
179
|
+
if (retry) {
|
|
180
|
+
this.requestCounts.set(key, 0);
|
|
181
|
+
}
|
|
182
|
+
this.routeHandlers.set(key, (req, res) => {
|
|
183
|
+
const sendResponse = (responseDelay) => {
|
|
184
|
+
const send = () => {
|
|
185
|
+
var _a, _b;
|
|
186
|
+
if (retry) {
|
|
187
|
+
const currentCount = this.requestCounts.get(key) || 0;
|
|
188
|
+
const failureCount = (_a = retry.failureCount) !== null && _a !== void 0 ? _a : 4;
|
|
189
|
+
const errorStatus = (_b = retry.errorStatus) !== null && _b !== void 0 ? _b : 500;
|
|
190
|
+
if (currentCount < failureCount) {
|
|
191
|
+
this.requestCounts.set(key, currentCount + 1);
|
|
192
|
+
const sendFailure = () => {
|
|
193
|
+
if (retry.headers) {
|
|
194
|
+
res.set(retry.headers);
|
|
195
|
+
}
|
|
196
|
+
if (retry.errorBody !== undefined) {
|
|
197
|
+
res.status(errorStatus).json(retry.errorBody);
|
|
198
|
+
}
|
|
199
|
+
else {
|
|
200
|
+
res.status(errorStatus).send();
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
if (retry.delay) {
|
|
204
|
+
setTimeout(sendFailure, retry.delay);
|
|
205
|
+
}
|
|
206
|
+
else {
|
|
207
|
+
sendFailure();
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
this.requestCounts.set(key, currentCount + 1);
|
|
212
|
+
if (headers) {
|
|
213
|
+
res.set(headers);
|
|
214
|
+
}
|
|
215
|
+
if (body !== undefined) {
|
|
216
|
+
res.status(status).json(body);
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
this.defaultRouteHandler(req, res);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
if (headers) {
|
|
225
|
+
res.set(headers);
|
|
226
|
+
}
|
|
227
|
+
if (body !== undefined) {
|
|
228
|
+
res.status(status).json(body);
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
res.status(status).send();
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
};
|
|
235
|
+
if (responseDelay) {
|
|
236
|
+
setTimeout(send, responseDelay);
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
send();
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
sendResponse(delay);
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Resets all custom route handlers, restoring all default handlers.
|
|
247
|
+
* Also clears request tracking data.
|
|
248
|
+
*/
|
|
249
|
+
resetRoutes() {
|
|
250
|
+
this.routeHandlers.clear();
|
|
251
|
+
this.requestCounts.clear();
|
|
252
|
+
this.requests = [];
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Returns the most recent request or undefined if no requests exist.
|
|
256
|
+
*/
|
|
257
|
+
getLastRequest() {
|
|
258
|
+
if (this.requests.length === 0) {
|
|
259
|
+
return undefined;
|
|
260
|
+
}
|
|
261
|
+
return this.requests[this.requests.length - 1];
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Gets the number of requests made to a specific endpoint.
|
|
265
|
+
*/
|
|
266
|
+
getRequestCount(method, path) {
|
|
267
|
+
return this.getRequests(method, path).length;
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Gets all requests made to a specific endpoint.
|
|
271
|
+
*/
|
|
272
|
+
getRequests(method, path) {
|
|
273
|
+
const pathWithoutQuery = path.split('?')[0];
|
|
274
|
+
return this.requests.filter((req) => req.method.toUpperCase() === method.toUpperCase() &&
|
|
275
|
+
req.url.split('?')[0] === pathWithoutQuery);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
exports.MockServer = MockServer;
|
|
@@ -1,21 +1,26 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const worker_threads_1 = require("worker_threads");
|
|
4
|
-
const
|
|
4
|
+
const jest_setup_1 = require("../tests/jest.setup");
|
|
5
|
+
const test_utils_1 = require("../common/test-utils");
|
|
5
6
|
const extraction_1 = require("../types/extraction");
|
|
6
7
|
const create_worker_1 = require("./create-worker");
|
|
7
8
|
describe(create_worker_1.createWorker.name, () => {
|
|
8
9
|
it('should create a Worker instance when valid parameters are provided', async () => {
|
|
10
|
+
// Arrange
|
|
9
11
|
const workerPath = __dirname + '../tests/dummy-worker.ts';
|
|
12
|
+
const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
|
|
13
|
+
payload: { event_type: extraction_1.EventType.StartExtractingExternalSyncUnits },
|
|
14
|
+
});
|
|
15
|
+
// Act
|
|
10
16
|
const worker = worker_threads_1.isMainThread
|
|
11
17
|
? await (0, create_worker_1.createWorker)({
|
|
12
|
-
event
|
|
13
|
-
eventType: extraction_1.EventType.ExtractionExternalSyncUnitsStart,
|
|
14
|
-
}),
|
|
18
|
+
event,
|
|
15
19
|
initialState: {},
|
|
16
20
|
workerPath,
|
|
17
21
|
})
|
|
18
22
|
: null;
|
|
23
|
+
// Assert
|
|
19
24
|
expect(worker).not.toBeNull();
|
|
20
25
|
expect(worker).toBeInstanceOf(worker_threads_1.Worker);
|
|
21
26
|
if (worker) {
|
|
@@ -23,36 +28,43 @@ describe(create_worker_1.createWorker.name, () => {
|
|
|
23
28
|
}
|
|
24
29
|
});
|
|
25
30
|
it('should throw error when not in main thread', async () => {
|
|
31
|
+
// Arrange
|
|
26
32
|
const originalIsMainThread = worker_threads_1.isMainThread;
|
|
27
33
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
28
34
|
worker_threads_1.isMainThread = false;
|
|
29
35
|
const workerPath = __dirname + '../tests/dummy-worker.ts';
|
|
36
|
+
const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
|
|
37
|
+
payload: { event_type: extraction_1.EventType.StartExtractingExternalSyncUnits },
|
|
38
|
+
});
|
|
39
|
+
// Act & Assert
|
|
30
40
|
await expect((0, create_worker_1.createWorker)({
|
|
31
|
-
event
|
|
32
|
-
eventType: extraction_1.EventType.ExtractionExternalSyncUnitsStart,
|
|
33
|
-
}),
|
|
41
|
+
event,
|
|
34
42
|
initialState: {},
|
|
35
43
|
workerPath,
|
|
36
44
|
})).rejects.toThrow('Worker threads can not start more worker threads.');
|
|
37
|
-
// Restore original value
|
|
38
45
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
39
46
|
worker_threads_1.isMainThread = originalIsMainThread;
|
|
40
47
|
});
|
|
41
48
|
it('[edge] should handle worker creation with minimal valid data', async () => {
|
|
49
|
+
// Arrange
|
|
42
50
|
const workerPath = __dirname + '../tests/dummy-worker.ts';
|
|
51
|
+
const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
|
|
52
|
+
payload: { event_type: extraction_1.EventType.StartExtractingExternalSyncUnits },
|
|
53
|
+
});
|
|
43
54
|
if (worker_threads_1.isMainThread) {
|
|
55
|
+
// Act
|
|
44
56
|
const worker = await (0, create_worker_1.createWorker)({
|
|
45
|
-
event
|
|
46
|
-
eventType: extraction_1.EventType.ExtractionExternalSyncUnitsStart,
|
|
47
|
-
}),
|
|
57
|
+
event,
|
|
48
58
|
initialState: {},
|
|
49
59
|
workerPath,
|
|
50
60
|
});
|
|
61
|
+
// Assert
|
|
51
62
|
expect(worker).toBeInstanceOf(worker_threads_1.Worker);
|
|
52
63
|
await worker.terminate();
|
|
53
64
|
}
|
|
54
65
|
});
|
|
55
66
|
it('[edge] should handle worker creation with complex initial state', async () => {
|
|
67
|
+
// Arrange
|
|
56
68
|
const workerPath = __dirname + '../tests/dummy-worker.ts';
|
|
57
69
|
const complexState = {
|
|
58
70
|
nested: {
|
|
@@ -60,28 +72,35 @@ describe(create_worker_1.createWorker.name, () => {
|
|
|
60
72
|
config: { enabled: true },
|
|
61
73
|
},
|
|
62
74
|
};
|
|
75
|
+
const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
|
|
76
|
+
payload: { event_type: extraction_1.EventType.StartExtractingData },
|
|
77
|
+
});
|
|
63
78
|
if (worker_threads_1.isMainThread) {
|
|
79
|
+
// Act
|
|
64
80
|
const worker = await (0, create_worker_1.createWorker)({
|
|
65
|
-
event
|
|
66
|
-
eventType: extraction_1.EventType.ExtractionDataStart,
|
|
67
|
-
}),
|
|
81
|
+
event,
|
|
68
82
|
initialState: complexState,
|
|
69
83
|
workerPath,
|
|
70
84
|
});
|
|
85
|
+
// Assert
|
|
71
86
|
expect(worker).toBeInstanceOf(worker_threads_1.Worker);
|
|
72
87
|
await worker.terminate();
|
|
73
88
|
}
|
|
74
89
|
});
|
|
75
90
|
it('[edge] should handle different event types', async () => {
|
|
91
|
+
// Arrange
|
|
76
92
|
const workerPath = __dirname + '../tests/dummy-worker.ts';
|
|
93
|
+
const event = (0, test_utils_1.createMockEvent)(jest_setup_1.mockServer.baseUrl, {
|
|
94
|
+
payload: { event_type: extraction_1.EventType.StartExtractingMetadata },
|
|
95
|
+
});
|
|
77
96
|
if (worker_threads_1.isMainThread) {
|
|
97
|
+
// Act
|
|
78
98
|
const worker = await (0, create_worker_1.createWorker)({
|
|
79
|
-
event
|
|
80
|
-
eventType: extraction_1.EventType.ExtractionMetadataStart,
|
|
81
|
-
}),
|
|
99
|
+
event,
|
|
82
100
|
initialState: {},
|
|
83
101
|
workerPath,
|
|
84
102
|
});
|
|
103
|
+
// Assert
|
|
85
104
|
expect(worker).toBeInstanceOf(worker_threads_1.Worker);
|
|
86
105
|
await worker.terminate();
|
|
87
106
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process-task.d.ts","sourceRoot":"","sources":["../../src/multithreading/process-task.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"process-task.d.ts","sourceRoot":"","sources":["../../src/multithreading/process-task.ts"],"names":[],"mappings":"AAOA,OAAO,EACL,oBAAoB,EAGrB,MAAM,kBAAkB,CAAC;AAG1B,wBAAgB,WAAW,CAAC,cAAc,EAAE,EAC1C,IAAI,EACJ,SAAS,GACV,EAAE,oBAAoB,CAAC,cAAc,CAAC,QAwDtC"}
|
|
@@ -2,57 +2,59 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.processTask = processTask;
|
|
4
4
|
const node_worker_threads_1 = require("node:worker_threads");
|
|
5
|
-
const event_type_translation_1 = require("../common/event-type-translation");
|
|
6
5
|
const logger_1 = require("../logger/logger");
|
|
7
6
|
const logger_context_1 = require("../logger/logger.context");
|
|
8
7
|
const state_1 = require("../state/state");
|
|
9
8
|
const workers_1 = require("../types/workers");
|
|
10
9
|
const worker_adapter_1 = require("./worker-adapter/worker-adapter");
|
|
11
10
|
function processTask({ task, onTimeout, }) {
|
|
12
|
-
if (
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
if (message.subject === workers_1.WorkerMessageSubject.WorkerMessageExit) {
|
|
39
|
-
console.log('Worker received message to gracefully exit. Setting isTimeout flag and executing onTimeout function.');
|
|
40
|
-
adapter.handleTimeout();
|
|
41
|
-
await (0, logger_context_1.runWithUserLogContext)(async () => onTimeout({ adapter }));
|
|
42
|
-
console.log('Finished executing onTimeout function. Exiting worker.');
|
|
43
|
-
process.exit(0);
|
|
44
|
-
}
|
|
45
|
-
});
|
|
46
|
-
})());
|
|
47
|
-
await (0, logger_context_1.runWithUserLogContext)(async () => task({ adapter }));
|
|
48
|
-
process.exit(0);
|
|
11
|
+
if (node_worker_threads_1.isMainThread) {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
void (async () => {
|
|
15
|
+
await (0, logger_context_1.runWithSdkLogContext)(async () => {
|
|
16
|
+
try {
|
|
17
|
+
const event = node_worker_threads_1.workerData.event;
|
|
18
|
+
const initialState = node_worker_threads_1.workerData.initialState;
|
|
19
|
+
const initialDomainMapping = node_worker_threads_1.workerData.initialDomainMapping;
|
|
20
|
+
const options = node_worker_threads_1.workerData.options;
|
|
21
|
+
// eslint-disable-next-line no-global-assign
|
|
22
|
+
console = new logger_1.Logger({ event, options });
|
|
23
|
+
const adapterState = await (0, state_1.createAdapterState)({
|
|
24
|
+
event,
|
|
25
|
+
initialState,
|
|
26
|
+
initialDomainMapping,
|
|
27
|
+
options,
|
|
28
|
+
});
|
|
29
|
+
const adapter = new worker_adapter_1.WorkerAdapter({
|
|
30
|
+
event,
|
|
31
|
+
adapterState,
|
|
32
|
+
options,
|
|
33
|
+
});
|
|
34
|
+
node_worker_threads_1.parentPort === null || node_worker_threads_1.parentPort === void 0 ? void 0 : node_worker_threads_1.parentPort.on(workers_1.WorkerEvent.WorkerMessage, (message) => {
|
|
35
|
+
if (message.subject !== workers_1.WorkerMessageSubject.WorkerMessageExit) {
|
|
36
|
+
return;
|
|
49
37
|
}
|
|
38
|
+
console.log('Timeout received. Waiting for the task to finish.');
|
|
39
|
+
adapter.isTimeout = true;
|
|
40
|
+
});
|
|
41
|
+
await (0, logger_context_1.runWithUserLogContext)(async () => task({ adapter }));
|
|
42
|
+
if (adapter.isTimeout && !adapter.hasWorkerEmitted) {
|
|
43
|
+
await (0, logger_context_1.runWithUserLogContext)(async () => onTimeout({ adapter }));
|
|
50
44
|
}
|
|
51
|
-
|
|
52
|
-
|
|
45
|
+
process.exit(0);
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
(0, logger_context_1.runWithUserLogContext)(() => {
|
|
49
|
+
const errorMessage = `Error while processing task. ${(0, logger_1.serializeError)(error)}`;
|
|
50
|
+
console.error(errorMessage);
|
|
51
|
+
node_worker_threads_1.parentPort === null || node_worker_threads_1.parentPort === void 0 ? void 0 : node_worker_threads_1.parentPort.postMessage({
|
|
52
|
+
subject: workers_1.WorkerMessageSubject.WorkerMessageFailed,
|
|
53
|
+
payload: { message: errorMessage },
|
|
54
|
+
});
|
|
53
55
|
process.exit(1);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
})
|
|
57
|
-
}
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
})();
|
|
58
60
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-task.test.d.ts","sourceRoot":"","sources":["../../src/multithreading/process-task.test.ts"],"names":[],"mappings":""}
|