@devrev/ts-adaas 1.5.1 → 1.7.0-beta.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/dist/common/constants.d.ts +5 -1
- package/dist/common/constants.js +6 -2
- package/dist/common/control-protocol.js +1 -1
- package/dist/common/helpers.d.ts +2 -1
- package/dist/common/helpers.js +15 -0
- package/dist/{tests/from_devrev/loading.test.js → common/helpers.test.js} +1 -1
- package/dist/common/install-initial-domain-mapping.js +36 -56
- package/dist/common/install-initial-domain-mapping.test.js +217 -0
- package/dist/logger/logger.d.ts +2 -0
- package/dist/logger/logger.js +28 -11
- package/dist/logger/logger.test.js +178 -0
- package/dist/repo/repo.interfaces.d.ts +1 -0
- package/dist/state/state.js +21 -12
- package/dist/tests/mock-server.d.ts +20 -0
- package/dist/tests/mock-server.js +278 -0
- package/dist/tests/test-helpers.d.ts +1 -1
- package/dist/tests/test-helpers.interfaces.d.ts +3 -1
- package/dist/tests/test-helpers.js +27 -28
- package/dist/tests/timeout-handling/extraction.d.ts +3 -0
- package/dist/tests/timeout-handling/extraction.js +21 -0
- package/dist/tests/timeout-handling/timeout-1.d.ts +1 -0
- package/dist/tests/timeout-handling/timeout-1.js +14 -0
- package/dist/tests/timeout-handling/timeout-1.test.d.ts +1 -0
- package/dist/tests/timeout-handling/timeout-1.test.js +45 -0
- package/dist/tests/timeout-handling/timeout-2.d.ts +1 -0
- package/dist/tests/timeout-handling/timeout-2.js +42 -0
- package/dist/tests/timeout-handling/timeout-2.test.d.ts +1 -0
- package/dist/tests/timeout-handling/timeout-2.test.js +46 -0
- package/dist/tests/timeout-handling/timeout-3a.d.ts +1 -0
- package/dist/tests/timeout-handling/timeout-3a.js +37 -0
- package/dist/tests/timeout-handling/timeout-3a.test.d.ts +1 -0
- package/dist/tests/timeout-handling/timeout-3a.test.js +46 -0
- package/dist/tests/timeout-handling/timeout-3b.d.ts +1 -0
- package/dist/tests/timeout-handling/timeout-3b.js +38 -0
- package/dist/tests/timeout-handling/timeout-3b.test.d.ts +1 -0
- package/dist/tests/timeout-handling/timeout-3b.test.js +46 -0
- package/dist/types/workers.d.ts +1 -8
- package/dist/types/workers.js +0 -1
- package/dist/uploader/uploader.js +2 -1
- package/dist/uploader/uploader.test.js +3 -0
- package/dist/workers/process-task.js +0 -4
- package/dist/workers/spawn.d.ts +3 -1
- package/dist/workers/spawn.js +47 -39
- package/package.json +5 -5
- package/dist/tests/test-worker.js +0 -14
- /package/dist/{tests/from_devrev/loading.test.d.ts → common/helpers.test.d.ts} +0 -0
- /package/dist/{tests/test-worker.d.ts → common/install-initial-domain-mapping.test.d.ts} +0 -0
|
@@ -5,10 +5,14 @@ export declare const ALLOWED_LOADING_EVENT_TYPES: EventType[];
|
|
|
5
5
|
export declare const ALLOWED_EVENT_TYPES: EventType[];
|
|
6
6
|
export declare const ARTIFACT_BATCH_SIZE = 2000;
|
|
7
7
|
export declare const MAX_DEVREV_ARTIFACT_SIZE = 262144000;
|
|
8
|
+
export declare const MAX_DEVREV_FILENAME_LENGTH = 256;
|
|
9
|
+
export declare const MAX_DEVREV_FILENAME_EXTENSION_LENGTH = 20;
|
|
8
10
|
export declare const AIRDROP_DEFAULT_ITEM_TYPES: {
|
|
9
11
|
EXTERNAL_DOMAIN_METADATA: string;
|
|
10
12
|
ATTACHMENTS: string;
|
|
11
13
|
SSOR_ATTACHMENT: string;
|
|
12
14
|
};
|
|
13
15
|
export declare const LIBRARY_VERSION: any;
|
|
14
|
-
export declare const
|
|
16
|
+
export declare const DEFAULT_LAMBDA_TIMEOUT: number;
|
|
17
|
+
export declare const HARD_TIMEOUT_MULTIPLIER = 1.3;
|
|
18
|
+
export declare const DEFAULT_SLEEP_DELAY_MS: number;
|
package/dist/common/constants.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DEFAULT_SLEEP_DELAY_MS = exports.LIBRARY_VERSION = exports.AIRDROP_DEFAULT_ITEM_TYPES = exports.MAX_DEVREV_ARTIFACT_SIZE = exports.ARTIFACT_BATCH_SIZE = exports.ALLOWED_EVENT_TYPES = exports.ALLOWED_LOADING_EVENT_TYPES = exports.ALLOWED_EXTRACTION_EVENT_TYPES = exports.STATELESS_EVENT_TYPES = void 0;
|
|
3
|
+
exports.DEFAULT_SLEEP_DELAY_MS = exports.HARD_TIMEOUT_MULTIPLIER = exports.DEFAULT_LAMBDA_TIMEOUT = exports.LIBRARY_VERSION = exports.AIRDROP_DEFAULT_ITEM_TYPES = exports.MAX_DEVREV_FILENAME_EXTENSION_LENGTH = exports.MAX_DEVREV_FILENAME_LENGTH = exports.MAX_DEVREV_ARTIFACT_SIZE = exports.ARTIFACT_BATCH_SIZE = exports.ALLOWED_EVENT_TYPES = exports.ALLOWED_LOADING_EVENT_TYPES = exports.ALLOWED_EXTRACTION_EVENT_TYPES = exports.STATELESS_EVENT_TYPES = void 0;
|
|
4
4
|
const extraction_1 = require("../types/extraction");
|
|
5
5
|
const helpers_1 = require("./helpers");
|
|
6
6
|
exports.STATELESS_EVENT_TYPES = [
|
|
@@ -33,10 +33,14 @@ exports.ALLOWED_EVENT_TYPES = [
|
|
|
33
33
|
];
|
|
34
34
|
exports.ARTIFACT_BATCH_SIZE = 2000;
|
|
35
35
|
exports.MAX_DEVREV_ARTIFACT_SIZE = 262144000; // 250MB
|
|
36
|
+
exports.MAX_DEVREV_FILENAME_LENGTH = 256;
|
|
37
|
+
exports.MAX_DEVREV_FILENAME_EXTENSION_LENGTH = 20; // 20 characters for the file extension
|
|
36
38
|
exports.AIRDROP_DEFAULT_ITEM_TYPES = {
|
|
37
39
|
EXTERNAL_DOMAIN_METADATA: 'external_domain_metadata',
|
|
38
40
|
ATTACHMENTS: 'attachments',
|
|
39
41
|
SSOR_ATTACHMENT: 'ssor_attachment',
|
|
40
42
|
};
|
|
41
43
|
exports.LIBRARY_VERSION = (0, helpers_1.getLibraryVersion)();
|
|
42
|
-
exports.
|
|
44
|
+
exports.DEFAULT_LAMBDA_TIMEOUT = 10 * 60 * 1000; // 10 minutes
|
|
45
|
+
exports.HARD_TIMEOUT_MULTIPLIER = 1.3;
|
|
46
|
+
exports.DEFAULT_SLEEP_DELAY_MS = 3 * 60 * 1000; // 3 minutes
|
|
@@ -12,7 +12,7 @@ const emit = async ({ event, eventType, data, }) => {
|
|
|
12
12
|
adaas_library_version: constants_1.LIBRARY_VERSION,
|
|
13
13
|
},
|
|
14
14
|
};
|
|
15
|
-
console.info('Emitting event',
|
|
15
|
+
console.info('Emitting event', newEvent);
|
|
16
16
|
return axios_client_1.axiosClient.post(event.payload.event_context.callback_url, Object.assign({}, newEvent), {
|
|
17
17
|
headers: {
|
|
18
18
|
Accept: 'application/json, text/plain, */*',
|
package/dist/common/helpers.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { AirdropEvent, EventType, ExtractorEventType } from '../types/extraction
|
|
|
2
2
|
import { FileToLoad, LoaderEventType, LoaderReport, StatsFileObject } from '../types/loading';
|
|
3
3
|
export declare function getTimeoutErrorEventType(eventType: EventType): {
|
|
4
4
|
eventType: ExtractorEventType | LoaderEventType;
|
|
5
|
-
}
|
|
5
|
+
};
|
|
6
6
|
export declare function getSyncDirection({ event }: {
|
|
7
7
|
event: AirdropEvent;
|
|
8
8
|
}): string;
|
|
@@ -17,3 +17,4 @@ export declare function addReportToLoaderReport({ loaderReports, report, }: {
|
|
|
17
17
|
export declare function getCircularReplacer(): (key: any, value: any) => any;
|
|
18
18
|
export declare function getLibraryVersion(): any;
|
|
19
19
|
export declare function sleep(ms: number): Promise<unknown>;
|
|
20
|
+
export declare function truncateFilename(filename: string): string;
|
package/dist/common/helpers.js
CHANGED
|
@@ -40,10 +40,12 @@ exports.addReportToLoaderReport = addReportToLoaderReport;
|
|
|
40
40
|
exports.getCircularReplacer = getCircularReplacer;
|
|
41
41
|
exports.getLibraryVersion = getLibraryVersion;
|
|
42
42
|
exports.sleep = sleep;
|
|
43
|
+
exports.truncateFilename = truncateFilename;
|
|
43
44
|
const extraction_1 = require("../types/extraction");
|
|
44
45
|
const loading_1 = require("../types/loading");
|
|
45
46
|
const fs_1 = require("fs");
|
|
46
47
|
const path = __importStar(require("path"));
|
|
48
|
+
const constants_1 = require("./constants");
|
|
47
49
|
function getTimeoutErrorEventType(eventType) {
|
|
48
50
|
switch (eventType) {
|
|
49
51
|
case extraction_1.EventType.ExtractionMetadataStart:
|
|
@@ -181,3 +183,16 @@ function sleep(ms) {
|
|
|
181
183
|
console.log(`Sleeping for ${ms}ms.`);
|
|
182
184
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
183
185
|
}
|
|
186
|
+
function truncateFilename(filename) {
|
|
187
|
+
// If the filename is already within the limit, return it as is.
|
|
188
|
+
if (filename.length <= constants_1.MAX_DEVREV_FILENAME_LENGTH) {
|
|
189
|
+
return filename;
|
|
190
|
+
}
|
|
191
|
+
console.warn(`Filename length exceeds the maximum limit of ${constants_1.MAX_DEVREV_FILENAME_LENGTH} characters. Truncating filename.`);
|
|
192
|
+
let extension = filename.slice(-constants_1.MAX_DEVREV_FILENAME_EXTENSION_LENGTH);
|
|
193
|
+
// Calculate how many characters are available for the name part after accounting for the extension and "..."
|
|
194
|
+
const availableNameLength = constants_1.MAX_DEVREV_FILENAME_LENGTH - constants_1.MAX_DEVREV_FILENAME_EXTENSION_LENGTH - 3; // -3 for "..."
|
|
195
|
+
// Truncate the name part and add an ellipsis
|
|
196
|
+
const truncatedFilename = filename.slice(0, availableNameLength);
|
|
197
|
+
return `${truncatedFilename}...${extension}`;
|
|
198
|
+
}
|
|
@@ -12,73 +12,53 @@ async function installInitialDomainMapping(event, initialDomainMappingJson) {
|
|
|
12
12
|
console.warn('No initial domain mapping found.');
|
|
13
13
|
return;
|
|
14
14
|
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
const recipeBlueprintResponse = await axios_client_1.axiosClient.post(`${devrevEndpoint}/internal/airdrop.recipe.blueprints.create`, Object.assign({}, startingRecipeBlueprint), {
|
|
36
|
-
headers: {
|
|
37
|
-
Authorization: devrevToken,
|
|
38
|
-
},
|
|
39
|
-
});
|
|
40
|
-
recipeBlueprintId = recipeBlueprintResponse.data.recipe_blueprint.id;
|
|
41
|
-
console.log('Successfully created recipe blueprint with id: ' + recipeBlueprintId);
|
|
42
|
-
}
|
|
43
|
-
catch (error) {
|
|
44
|
-
if (axios_client_1.axios.isAxiosError(error)) {
|
|
45
|
-
console.error('Error while creating recipe blueprint', (0, logger_1.serializeAxiosError)(error));
|
|
46
|
-
}
|
|
47
|
-
else {
|
|
48
|
-
console.error('Error while creating recipe blueprint', error);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
}
|
|
15
|
+
// Get snap-in details
|
|
16
|
+
const snapInResponse = await axios_client_1.axiosClient.get(devrevEndpoint + '/internal/snap-ins.get', {
|
|
17
|
+
headers: {
|
|
18
|
+
Authorization: devrevToken,
|
|
19
|
+
},
|
|
20
|
+
params: {
|
|
21
|
+
id: snapInId,
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
const importSlug = (_d = (_c = (_b = (_a = snapInResponse.data) === null || _a === void 0 ? void 0 : _a.snap_in) === null || _b === void 0 ? void 0 : _b.imports) === null || _c === void 0 ? void 0 : _c[0]) === null || _d === void 0 ? void 0 : _d.name;
|
|
25
|
+
const snapInSlug = (_g = (_f = (_e = snapInResponse.data) === null || _e === void 0 ? void 0 : _e.snap_in) === null || _f === void 0 ? void 0 : _f.snap_in_version) === null || _g === void 0 ? void 0 : _g.slug;
|
|
26
|
+
if (!importSlug || !snapInSlug) {
|
|
27
|
+
const errorMessage = `No import slug or snap-in slug found. Snap-in response: ${snapInResponse.data}`;
|
|
28
|
+
throw new Error(errorMessage);
|
|
29
|
+
}
|
|
30
|
+
const startingRecipeBlueprint = initialDomainMappingJson === null || initialDomainMappingJson === void 0 ? void 0 : initialDomainMappingJson.starting_recipe_blueprint;
|
|
31
|
+
// Try to create a recipe blueprint
|
|
32
|
+
let recipeBlueprintId;
|
|
33
|
+
if (startingRecipeBlueprint &&
|
|
34
|
+
Object.keys(startingRecipeBlueprint).length !== 0) {
|
|
52
35
|
try {
|
|
53
|
-
|
|
54
|
-
const additionalMappings = initialDomainMappingJson.additional_mappings || {};
|
|
55
|
-
const initialDomainMappingInstallResponse = await axios_client_1.axiosClient.post(`${devrevEndpoint}/internal/airdrop.recipe.initial-domain-mappings.install`, Object.assign(Object.assign({ external_system_type: 'ADaaS', import_slug: importSlug, snap_in_slug: snapInSlug }, (recipeBlueprintId && {
|
|
56
|
-
starting_recipe_blueprint: recipeBlueprintId,
|
|
57
|
-
})), additionalMappings), {
|
|
36
|
+
const recipeBlueprintResponse = await axios_client_1.axiosClient.post(`${devrevEndpoint}/internal/airdrop.recipe.blueprints.create`, Object.assign({}, startingRecipeBlueprint), {
|
|
58
37
|
headers: {
|
|
59
38
|
Authorization: devrevToken,
|
|
60
39
|
},
|
|
61
40
|
});
|
|
62
|
-
|
|
63
|
-
|
|
41
|
+
recipeBlueprintId = recipeBlueprintResponse.data.recipe_blueprint.id;
|
|
42
|
+
console.log('Successfully created recipe blueprint with id: ' + recipeBlueprintId);
|
|
64
43
|
}
|
|
65
44
|
catch (error) {
|
|
45
|
+
const errorMessage = `Error while creating recipe blueprint. Continuing without it.`;
|
|
66
46
|
if (axios_client_1.axios.isAxiosError(error)) {
|
|
67
|
-
console.error(
|
|
47
|
+
console.error(errorMessage, (0, logger_1.serializeAxiosError)(error));
|
|
68
48
|
}
|
|
69
49
|
else {
|
|
70
|
-
console.error(
|
|
50
|
+
console.error(errorMessage, error);
|
|
71
51
|
}
|
|
72
|
-
return;
|
|
73
52
|
}
|
|
74
53
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
}
|
|
54
|
+
// Install the initial domain mappings
|
|
55
|
+
const additionalMappings = initialDomainMappingJson.additional_mappings || {};
|
|
56
|
+
const initialDomainMappingInstallResponse = await axios_client_1.axiosClient.post(`${devrevEndpoint}/internal/airdrop.recipe.initial-domain-mappings.install`, Object.assign(Object.assign({ external_system_type: 'ADaaS', import_slug: importSlug, snap_in_slug: snapInSlug }, (recipeBlueprintId && {
|
|
57
|
+
starting_recipe_blueprint: recipeBlueprintId,
|
|
58
|
+
})), additionalMappings), {
|
|
59
|
+
headers: {
|
|
60
|
+
Authorization: devrevToken,
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
console.log(`Successfully installed initial domain mapping ${JSON.stringify(initialDomainMappingInstallResponse.data)}`);
|
|
84
64
|
}
|
|
@@ -0,0 +1,217 @@
|
|
|
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 axios_1 = __importDefault(require("axios"));
|
|
7
|
+
const install_initial_domain_mapping_1 = require("./install-initial-domain-mapping");
|
|
8
|
+
const axios_client_1 = require("../http/axios-client");
|
|
9
|
+
const logger_1 = require("../logger/logger");
|
|
10
|
+
const test_helpers_1 = require("../tests/test-helpers");
|
|
11
|
+
const extraction_1 = require("../types/extraction");
|
|
12
|
+
// Mock dependencies
|
|
13
|
+
jest.mock('axios', () => (Object.assign(Object.assign({}, jest.requireActual('axios')), { isAxiosError: jest.fn() })));
|
|
14
|
+
jest.mock('../http/axios-client');
|
|
15
|
+
jest.mock('../logger/logger');
|
|
16
|
+
const mockAxiosClient = axios_client_1.axiosClient;
|
|
17
|
+
const mockIsAxiosError = axios_1.default.isAxiosError;
|
|
18
|
+
const mockSerializeAxiosError = logger_1.serializeAxiosError;
|
|
19
|
+
describe('installInitialDomainMapping', () => {
|
|
20
|
+
// Create mock objects
|
|
21
|
+
const mockEvent = (0, test_helpers_1.createEvent)({ eventType: extraction_1.EventType.ExtractionDataStart });
|
|
22
|
+
const mockInitialDomainMapping = {
|
|
23
|
+
starting_recipe_blueprint: {
|
|
24
|
+
name: 'Test Recipe Blueprint',
|
|
25
|
+
description: 'Test description',
|
|
26
|
+
},
|
|
27
|
+
additional_mappings: {
|
|
28
|
+
custom_field: 'custom_value',
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
const mockSnapInResponse = {
|
|
32
|
+
data: {
|
|
33
|
+
snap_in: {
|
|
34
|
+
imports: [{ name: 'import-slug-123' }],
|
|
35
|
+
snap_in_version: { slug: 'snap-in-slug-123' },
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
const mockEndpoint = 'test_devrev_endpoint';
|
|
40
|
+
const mockToken = 'test_token';
|
|
41
|
+
let mockConsoleLog;
|
|
42
|
+
let mockConsoleWarn;
|
|
43
|
+
let mockConsoleError;
|
|
44
|
+
// Before each test, create a fresh spy.
|
|
45
|
+
beforeEach(() => {
|
|
46
|
+
// Re-initialize the spy and its mock implementation
|
|
47
|
+
mockConsoleLog = jest.spyOn(console, 'log').mockImplementation(() => { });
|
|
48
|
+
mockConsoleWarn = jest.spyOn(console, 'warn').mockImplementation(() => { });
|
|
49
|
+
mockConsoleError = jest
|
|
50
|
+
.spyOn(console, 'error')
|
|
51
|
+
.mockImplementation(() => { });
|
|
52
|
+
});
|
|
53
|
+
// After each test, clear all mocks to prevent state from leaking.
|
|
54
|
+
afterEach(() => {
|
|
55
|
+
jest.clearAllMocks();
|
|
56
|
+
});
|
|
57
|
+
it('should successfully install initial domain mapping with recipe blueprint', async () => {
|
|
58
|
+
// Mock successful snap-in response
|
|
59
|
+
mockAxiosClient.get.mockResolvedValueOnce(mockSnapInResponse);
|
|
60
|
+
// Mock successful recipe blueprint creation
|
|
61
|
+
const mockRecipeBlueprintResponse = {
|
|
62
|
+
data: {
|
|
63
|
+
recipe_blueprint: {
|
|
64
|
+
id: 'recipe-blueprint-123',
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
mockAxiosClient.post.mockResolvedValueOnce(mockRecipeBlueprintResponse);
|
|
69
|
+
// Mock successful domain mapping installation
|
|
70
|
+
const mockDomainMappingResponse = {
|
|
71
|
+
data: {
|
|
72
|
+
success: true,
|
|
73
|
+
mapping_id: 'mapping-123',
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
mockAxiosClient.post.mockResolvedValueOnce(mockDomainMappingResponse);
|
|
77
|
+
await (0, install_initial_domain_mapping_1.installInitialDomainMapping)(mockEvent, mockInitialDomainMapping);
|
|
78
|
+
// Verify snap-in details request
|
|
79
|
+
expect(mockAxiosClient.get).toHaveBeenCalledWith(`${mockEndpoint}/internal/snap-ins.get`, {
|
|
80
|
+
headers: {
|
|
81
|
+
Authorization: mockToken,
|
|
82
|
+
},
|
|
83
|
+
params: {
|
|
84
|
+
id: 'test_snap_in_id',
|
|
85
|
+
},
|
|
86
|
+
});
|
|
87
|
+
// Verify recipe blueprint creation
|
|
88
|
+
expect(mockAxiosClient.post).toHaveBeenCalledWith(`${mockEndpoint}/internal/airdrop.recipe.blueprints.create`, {
|
|
89
|
+
name: 'Test Recipe Blueprint',
|
|
90
|
+
description: 'Test description',
|
|
91
|
+
}, {
|
|
92
|
+
headers: {
|
|
93
|
+
Authorization: mockToken,
|
|
94
|
+
},
|
|
95
|
+
});
|
|
96
|
+
// Verify domain mapping installation
|
|
97
|
+
expect(mockAxiosClient.post).toHaveBeenCalledWith(`${mockEndpoint}/internal/airdrop.recipe.initial-domain-mappings.install`, {
|
|
98
|
+
external_system_type: 'ADaaS',
|
|
99
|
+
import_slug: 'import-slug-123',
|
|
100
|
+
snap_in_slug: 'snap-in-slug-123',
|
|
101
|
+
starting_recipe_blueprint: 'recipe-blueprint-123',
|
|
102
|
+
custom_field: 'custom_value',
|
|
103
|
+
}, {
|
|
104
|
+
headers: {
|
|
105
|
+
Authorization: mockToken,
|
|
106
|
+
},
|
|
107
|
+
});
|
|
108
|
+
expect(mockConsoleLog).toHaveBeenCalledWith('Successfully created recipe blueprint with id: recipe-blueprint-123');
|
|
109
|
+
expect(mockConsoleLog).toHaveBeenCalledWith(`Successfully installed initial domain mapping ${JSON.stringify(mockDomainMappingResponse.data)}`);
|
|
110
|
+
});
|
|
111
|
+
it('should successfully install without recipe blueprint when not provided', async () => {
|
|
112
|
+
const mappingWithoutBlueprint = {
|
|
113
|
+
additional_mappings: {
|
|
114
|
+
custom_field: 'custom_value',
|
|
115
|
+
},
|
|
116
|
+
};
|
|
117
|
+
mockAxiosClient.get.mockResolvedValueOnce(mockSnapInResponse);
|
|
118
|
+
const mockDomainMappingResponse = {
|
|
119
|
+
data: { success: true },
|
|
120
|
+
};
|
|
121
|
+
mockAxiosClient.post.mockResolvedValueOnce(mockDomainMappingResponse);
|
|
122
|
+
await (0, install_initial_domain_mapping_1.installInitialDomainMapping)(mockEvent, mappingWithoutBlueprint);
|
|
123
|
+
// Should only make one POST request (no recipe blueprint creation)
|
|
124
|
+
expect(mockAxiosClient.post).toHaveBeenCalledTimes(1);
|
|
125
|
+
expect(mockAxiosClient.post).toHaveBeenCalledWith(`${mockEndpoint}/internal/airdrop.recipe.initial-domain-mappings.install`, {
|
|
126
|
+
external_system_type: 'ADaaS',
|
|
127
|
+
import_slug: 'import-slug-123',
|
|
128
|
+
snap_in_slug: 'snap-in-slug-123',
|
|
129
|
+
custom_field: 'custom_value',
|
|
130
|
+
}, {
|
|
131
|
+
headers: {
|
|
132
|
+
Authorization: mockToken,
|
|
133
|
+
},
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
it('should handle empty starting_recipe_blueprint object', async () => {
|
|
137
|
+
const mappingWithEmptyBlueprint = {
|
|
138
|
+
starting_recipe_blueprint: {},
|
|
139
|
+
additional_mappings: {
|
|
140
|
+
custom_field: 'custom_value',
|
|
141
|
+
},
|
|
142
|
+
};
|
|
143
|
+
mockAxiosClient.get.mockResolvedValueOnce(mockSnapInResponse);
|
|
144
|
+
const mockDomainMappingResponse = {
|
|
145
|
+
data: { success: true },
|
|
146
|
+
};
|
|
147
|
+
mockAxiosClient.post.mockResolvedValueOnce(mockDomainMappingResponse);
|
|
148
|
+
await (0, install_initial_domain_mapping_1.installInitialDomainMapping)(mockEvent, mappingWithEmptyBlueprint);
|
|
149
|
+
// Should only make one POST request (no recipe blueprint creation for empty object)
|
|
150
|
+
expect(mockAxiosClient.post).toHaveBeenCalledTimes(1);
|
|
151
|
+
});
|
|
152
|
+
it('should return early with warning when no initial domain mapping provided', async () => {
|
|
153
|
+
await (0, install_initial_domain_mapping_1.installInitialDomainMapping)(mockEvent, null);
|
|
154
|
+
expect(mockConsoleWarn).toHaveBeenCalledWith('No initial domain mapping found.');
|
|
155
|
+
expect(mockAxiosClient.get).not.toHaveBeenCalled();
|
|
156
|
+
expect(mockAxiosClient.post).not.toHaveBeenCalled();
|
|
157
|
+
});
|
|
158
|
+
it('should return early with warning when undefined initial domain mapping provided', async () => {
|
|
159
|
+
await (0, install_initial_domain_mapping_1.installInitialDomainMapping)(mockEvent, undefined);
|
|
160
|
+
expect(mockConsoleWarn).toHaveBeenCalledWith('No initial domain mapping found.');
|
|
161
|
+
expect(mockAxiosClient.get).not.toHaveBeenCalled();
|
|
162
|
+
expect(mockAxiosClient.post).not.toHaveBeenCalled();
|
|
163
|
+
});
|
|
164
|
+
it('should throw error when import slug is missing', async () => {
|
|
165
|
+
const snapInResponseWithoutImport = {
|
|
166
|
+
data: {
|
|
167
|
+
snap_in: {
|
|
168
|
+
imports: [],
|
|
169
|
+
snap_in_version: { slug: 'snap-in-slug-123' },
|
|
170
|
+
},
|
|
171
|
+
},
|
|
172
|
+
};
|
|
173
|
+
mockAxiosClient.get.mockResolvedValueOnce(snapInResponseWithoutImport);
|
|
174
|
+
await expect((0, install_initial_domain_mapping_1.installInitialDomainMapping)(mockEvent, mockInitialDomainMapping)).rejects.toThrow('No import slug or snap-in slug found');
|
|
175
|
+
});
|
|
176
|
+
it('should throw error when snap-in slug is missing', async () => {
|
|
177
|
+
const snapInResponseWithoutSlug = {
|
|
178
|
+
data: {
|
|
179
|
+
snap_in: {
|
|
180
|
+
imports: [{ name: 'import-slug-123' }],
|
|
181
|
+
snap_in_version: {},
|
|
182
|
+
},
|
|
183
|
+
},
|
|
184
|
+
};
|
|
185
|
+
mockAxiosClient.get.mockResolvedValueOnce(snapInResponseWithoutSlug);
|
|
186
|
+
await expect((0, install_initial_domain_mapping_1.installInitialDomainMapping)(mockEvent, mockInitialDomainMapping)).rejects.toThrow('No import slug or snap-in slug found');
|
|
187
|
+
});
|
|
188
|
+
it('should handle the error during recipe blueprint creation', async () => {
|
|
189
|
+
mockAxiosClient.get.mockResolvedValueOnce(mockSnapInResponse);
|
|
190
|
+
const genericError = new Error('Generic error during blueprint creation');
|
|
191
|
+
// Mock axios.isAxiosError to return false
|
|
192
|
+
mockIsAxiosError.mockReturnValue(false);
|
|
193
|
+
mockAxiosClient.post.mockRejectedValueOnce(genericError);
|
|
194
|
+
const mockDomainMappingResponse = {
|
|
195
|
+
data: { success: true },
|
|
196
|
+
};
|
|
197
|
+
mockAxiosClient.post.mockResolvedValueOnce(mockDomainMappingResponse);
|
|
198
|
+
await (0, install_initial_domain_mapping_1.installInitialDomainMapping)(mockEvent, mockInitialDomainMapping);
|
|
199
|
+
// Should still proceed with domain mapping installation
|
|
200
|
+
expect(mockAxiosClient.post).toHaveBeenCalledTimes(2);
|
|
201
|
+
});
|
|
202
|
+
it('should propagate error from domain mapping installation', async () => {
|
|
203
|
+
mockAxiosClient.get.mockResolvedValueOnce(mockSnapInResponse);
|
|
204
|
+
// Mock successful recipe blueprint creation
|
|
205
|
+
const mockRecipeBlueprintResponse = {
|
|
206
|
+
data: {
|
|
207
|
+
recipe_blueprint: {
|
|
208
|
+
id: 'recipe-blueprint-123',
|
|
209
|
+
},
|
|
210
|
+
},
|
|
211
|
+
};
|
|
212
|
+
mockAxiosClient.post.mockResolvedValueOnce(mockRecipeBlueprintResponse);
|
|
213
|
+
const domainMappingError = new Error('Domain mapping installation failed');
|
|
214
|
+
mockAxiosClient.post.mockRejectedValueOnce(domainMappingError);
|
|
215
|
+
await expect((0, install_initial_domain_mapping_1.installInitialDomainMapping)(mockEvent, mockInitialDomainMapping)).rejects.toThrow('Domain mapping installation failed');
|
|
216
|
+
});
|
|
217
|
+
});
|
package/dist/logger/logger.d.ts
CHANGED
|
@@ -3,7 +3,9 @@ import { LoggerFactoryInterface, LogLevel, PrintableState } from './logger.inter
|
|
|
3
3
|
import { AxiosError, RawAxiosResponseHeaders } from 'axios';
|
|
4
4
|
export declare class Logger extends Console {
|
|
5
5
|
private options?;
|
|
6
|
+
private tags;
|
|
6
7
|
constructor({ event, options }: LoggerFactoryInterface);
|
|
8
|
+
private valueToString;
|
|
7
9
|
logFn(args: unknown[], level: LogLevel): void;
|
|
8
10
|
log(...args: unknown[]): void;
|
|
9
11
|
info(...args: unknown[]): void;
|
package/dist/logger/logger.js
CHANGED
|
@@ -1,26 +1,29 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.serializeError = exports.Logger = void 0;
|
|
7
4
|
exports.getPrintableState = getPrintableState;
|
|
8
5
|
exports.formatAxiosError = formatAxiosError;
|
|
9
6
|
exports.serializeAxiosError = serializeAxiosError;
|
|
10
|
-
const lambda_log_1 = __importDefault(require("lambda-log"));
|
|
11
7
|
const node_console_1 = require("node:console");
|
|
8
|
+
const node_util_1 = require("node:util");
|
|
12
9
|
const logger_interfaces_1 = require("./logger.interfaces");
|
|
13
10
|
const node_worker_threads_1 = require("node:worker_threads");
|
|
14
11
|
const workers_1 = require("../types/workers");
|
|
15
|
-
const helpers_1 = require("../common/helpers");
|
|
16
12
|
class Logger extends node_console_1.Console {
|
|
17
13
|
constructor({ event, options }) {
|
|
18
14
|
super(process.stdout, process.stderr);
|
|
19
15
|
this.options = options;
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
16
|
+
this.tags = Object.assign(Object.assign({}, event.payload.event_context), { dev_oid: event.payload.event_context.dev_org });
|
|
17
|
+
}
|
|
18
|
+
valueToString(value) {
|
|
19
|
+
if (typeof value === 'string') {
|
|
20
|
+
return value;
|
|
21
|
+
}
|
|
22
|
+
// Use Node.js built-in inspect for everything including errors
|
|
23
|
+
return (0, node_util_1.inspect)(value, {
|
|
24
|
+
compact: false,
|
|
25
|
+
breakLength: Infinity,
|
|
26
|
+
});
|
|
24
27
|
}
|
|
25
28
|
logFn(args, level) {
|
|
26
29
|
var _a;
|
|
@@ -29,14 +32,28 @@ class Logger extends node_console_1.Console {
|
|
|
29
32
|
console[level](...args);
|
|
30
33
|
}
|
|
31
34
|
else {
|
|
32
|
-
|
|
35
|
+
let message;
|
|
36
|
+
if (args.length === 1 && typeof args[0] === 'string') {
|
|
37
|
+
// Single string argument - use directly
|
|
38
|
+
message = args[0];
|
|
39
|
+
}
|
|
40
|
+
else if (args.length === 1) {
|
|
41
|
+
// Single non-string argument - convert to string properly
|
|
42
|
+
message = this.valueToString(args[0]);
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
// Multiple arguments - create a readable format
|
|
46
|
+
message = args.map((arg) => this.valueToString(arg)).join(' ');
|
|
47
|
+
}
|
|
48
|
+
const logObject = Object.assign({ message }, this.tags);
|
|
49
|
+
console[level](JSON.stringify(logObject));
|
|
33
50
|
}
|
|
34
51
|
}
|
|
35
52
|
else {
|
|
36
53
|
node_worker_threads_1.parentPort === null || node_worker_threads_1.parentPort === void 0 ? void 0 : node_worker_threads_1.parentPort.postMessage({
|
|
37
54
|
subject: workers_1.WorkerMessageSubject.WorkerMessageLog,
|
|
38
55
|
payload: {
|
|
39
|
-
args:
|
|
56
|
+
args: args.map((arg) => this.valueToString(arg)),
|
|
40
57
|
level,
|
|
41
58
|
},
|
|
42
59
|
});
|