@amplience/dc-cli
Version:
Dynamic Content CLI Tool
199 lines (198 loc) • 8.99 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.handler = exports.importWebhooks = exports.prepareWebhooksForImport = exports.trySaveMapping = exports.createOrUpdateWebhook = exports.builder = exports.LOG_FILENAME = exports.desc = exports.command = void 0;
exports.getDefaultMappingPath = getDefaultMappingPath;
const dynamic_content_client_factory_1 = __importDefault(require("../../services/dynamic-content-client-factory"));
const path_1 = require("path");
const graceful_fs_1 = require("graceful-fs");
const util_1 = require("util");
const dc_management_sdk_js_1 = require("dc-management-sdk-js");
const content_mapping_1 = require("../../common/content-mapping");
const log_helpers_1 = require("../../common/log-helpers");
const question_helpers_1 = require("../../common/question-helpers");
const progress_bar_1 = require("../../common/progress-bar/progress-bar");
function getDefaultMappingPath(name, platform = process.platform) {
return (0, path_1.join)(process.env[platform == 'win32' ? 'USERPROFILE' : 'HOME'] || __dirname, '.amplience', `imports/`, `${name}.json`);
}
exports.command = 'import <dir>';
exports.desc = 'Import Webhooks';
const LOG_FILENAME = (platform = process.platform) => (0, log_helpers_1.getDefaultLogPath)('webhook', 'import', platform);
exports.LOG_FILENAME = LOG_FILENAME;
const builder = (yargs) => {
yargs
.positional('dir', {
describe: 'Directory containing webhooks to import.',
type: 'string',
requiresArg: true
})
.option('mapFile', {
type: 'string',
describe: 'Mapping file to use when updating webhooks that already exists. Updated with any new mappings that are generated. If not present, will be created.'
})
.option('logFile', {
type: 'string',
default: exports.LOG_FILENAME,
describe: 'Path to a log file to write to.',
coerce: log_helpers_1.createLog
})
.alias('f', 'force')
.option('f', {
type: 'boolean',
boolean: true,
describe: 'Overwrite webhooks.'
})
.alias('s', 'silent')
.option('s', {
type: 'boolean',
boolean: true,
describe: 'If present, no log file will be produced.'
});
};
exports.builder = builder;
const createOrUpdateWebhook = async (hub, item, existing) => {
let oldItem = null;
if (typeof existing === 'string') {
oldItem = await hub.related.webhooks.get(existing);
}
else {
oldItem = existing;
}
let result;
if (oldItem == null) {
result = { webhook: await hub.related.webhooks.create(item), state: 'CREATED' };
}
else {
result = { webhook: await oldItem.related.update(item), state: 'UPDATED' };
}
return result;
};
exports.createOrUpdateWebhook = createOrUpdateWebhook;
const trySaveMapping = async (mapFile, mapping, log) => {
if (mapFile != null) {
try {
await mapping.save(mapFile);
}
catch (e) {
log.appendLine(`Failed to save the mapping. ${e.toString()}`);
}
}
};
exports.trySaveMapping = trySaveMapping;
const prepareWebhooksForImport = async (hub, webhookFiles, mapping, log, argv) => {
var _a, _b, _c;
const { force } = argv;
let webhooks = [];
for (const webhookFile of webhookFiles) {
log.appendLine(`Reading webhook data in '${webhookFile}' for hub '${hub.label}'...`);
if ((0, path_1.extname)(webhookFile) !== '.json') {
return null;
}
let webhookJSON;
try {
const webhookText = await (0, util_1.promisify)(graceful_fs_1.readFile)(webhookFile, {
encoding: 'utf8'
});
webhookJSON = JSON.parse(webhookText);
}
catch (e) {
log.appendLine(`Couldn't read webhook at '${webhookFile}': ${e.toString()}`);
return null;
}
const webhook = new dc_management_sdk_js_1.Webhook({
...(webhookJSON.id && { id: webhookJSON.id }),
...(webhookJSON.label && { label: webhookJSON.label }),
...(webhookJSON.events && { events: webhookJSON.events }),
...(webhookJSON.active && { active: webhookJSON.active }),
...(webhookJSON.handlers && { handlers: webhookJSON.handlers }),
...(webhookJSON.notifications && { notifications: webhookJSON.notifications }),
...(webhookJSON.headers && { headers: webhookJSON.headers }),
...(webhookJSON.filters && { filters: webhookJSON.filters }),
...(webhookJSON.customPayload && { customPayload: webhookJSON.customPayload }),
...(webhookJSON.method && { method: webhookJSON.method })
});
if (webhook === null || webhook === void 0 ? void 0 : webhook.headers) {
webhook.headers = webhook.headers.filter(header => {
return !header.secret;
});
}
if ((_a = webhook === null || webhook === void 0 ? void 0 : webhook.customPayload) === null || _a === void 0 ? void 0 : _a.value) {
webhook.customPayload.value = webhook.customPayload.value
.replace(/account="([^"]*)"/g, `account="${hub.name}"`)
.replace(/stagingEnvironment="([^"]*)"/g, `stagingEnvironment="${(_c = (_b = hub.settings) === null || _b === void 0 ? void 0 : _b.virtualStagingEnvironment) === null || _c === void 0 ? void 0 : _c.hostname}"`);
}
webhooks.push(new dc_management_sdk_js_1.Webhook(webhook));
}
const alreadyExists = webhooks.filter(item => mapping.getWebhook(item.id) != null);
if (alreadyExists.length > 0) {
const updateExisting = force ||
(await (0, question_helpers_1.asyncQuestion)(`${alreadyExists.length} of the webhooks being imported already exist in the mapping. Would you like to update these webhooks instead of skipping them? (y/n) `, log));
if (!updateExisting) {
webhooks = webhooks.filter(item => mapping.getWebhook(item.id) == null);
}
}
return webhooks;
};
exports.prepareWebhooksForImport = prepareWebhooksForImport;
const importWebhooks = async (hub, webhooks, mapping, log) => {
const importProgress = (0, progress_bar_1.progressBar)(webhooks.length, 0, {
title: 'Importing webhooks'
});
for (const webhookToImport of webhooks) {
const originalId = webhookToImport.id;
webhookToImport.id = mapping.getWebhook(webhookToImport.id) || '';
if (!webhookToImport.id) {
delete webhookToImport.id;
}
try {
const { webhook, state } = await (0, exports.createOrUpdateWebhook)(hub, webhookToImport, mapping.getWebhook(originalId) || null);
log.addComment(`${state} ${webhook.label}.`);
log.addAction(state, (webhook.id || 'unknown') + (state === 'UPDATED' ? ` ${webhook.label}` : ''));
mapping.registerWebhook(originalId, webhook.id);
importProgress.increment();
}
catch (e) {
importProgress.stop();
log.error(`Failed creating ${webhookToImport.label}:`, e);
throw Error(`Importing webhook failed. Error: ${e.toString()}`);
}
}
importProgress.stop();
};
exports.importWebhooks = importWebhooks;
const handler = async (argv) => {
const { dir, logFile, force, silent, mapFile: mapFileArg } = argv;
const client = (0, dynamic_content_client_factory_1.default)(argv);
const log = logFile.open();
const hub = await client.hubs.get(argv.hubId);
const importTitle = `hub-${hub.id}`;
const mapping = new content_mapping_1.ContentMapping();
const mapFile = mapFileArg ? mapFileArg : getDefaultMappingPath(importTitle);
if (await mapping.load(mapFile)) {
log.appendLine(`Existing mapping loaded from '${mapFile}', changes will be saved back to it.`);
}
else {
log.appendLine(`Creating new mapping file at '${mapFile}'.`);
}
const baseDirContents = await (0, util_1.promisify)(graceful_fs_1.readdir)(dir);
const webhookFiles = baseDirContents.map(wh => {
return `${dir}/${wh}`;
});
const webhooks = await (0, exports.prepareWebhooksForImport)(hub, webhookFiles, mapping, log, argv);
if (webhooks !== null) {
const proceedImport = force ||
(await (0, question_helpers_1.asyncQuestion)(`${webhooks.length} webhook/s will be imported, do you wish to continue? (y/n) `, log));
if (!proceedImport) {
return;
}
await (0, exports.importWebhooks)(hub, webhooks, mapping, log);
}
else {
log.appendLine('No webhooks found to import.');
}
(0, exports.trySaveMapping)(mapFile, mapping, log);
await log.close(!silent);
};
exports.handler = handler;