UNPKG

@amplience/dc-cli

Version:
232 lines (231 loc) 10.1 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.handler = exports.processItems = exports.getEvents = exports.builder = exports.coerceLog = exports.LOG_FILENAME = exports.desc = exports.command = void 0; const dynamic_content_client_factory_1 = __importDefault(require("../../services/dynamic-content-client-factory")); const paginator_1 = __importDefault(require("../../common/dc-management-sdk-js/paginator")); const confirm_all_content_1 = require("../../common/content-item/confirm-all-content"); const filter_1 = require("../../common/filter/filter"); const log_helpers_1 = require("../../common/log-helpers"); const maxAttempts = 30; exports.command = 'archive [id]'; exports.desc = 'Archive Events'; const LOG_FILENAME = (platform = process.platform) => (0, log_helpers_1.getDefaultLogPath)('event', 'archive', platform); exports.LOG_FILENAME = LOG_FILENAME; const coerceLog = (logFile) => (0, log_helpers_1.createLog)(logFile, 'Events Archive Log'); exports.coerceLog = coerceLog; const builder = (yargs) => { yargs .positional('id', { type: 'string', describe: 'The ID of an Event to be archived. If id is not provided, this command will not archive something.' }) .option('name', { type: 'string', describe: 'The name of an Event to be archived.\nA regex can be provided to select multiple items with similar or matching names (eg /.header/).\nA single --name option may be given to match a single event pattern.\nMultiple --name options may be given to match multiple events patterns at the same time, or even multiple regex.' }) .alias('f', 'force') .option('f', { type: 'boolean', boolean: true, describe: 'If present, there will be no confirmation prompt before archiving the found content.' }) .alias('s', 'silent') .option('s', { type: 'boolean', boolean: true, describe: 'If present, no log file will be produced.' }) .option('logFile', { type: 'string', default: exports.LOG_FILENAME, describe: 'Path to a log file to write to.', coerce: exports.coerceLog }); }; exports.builder = builder; const getResourceUntilSuccess = async ({ id = '', resource = 'archive', getter }) => { let resourceEvent; for (let i = 0; i < maxAttempts; i++) { const obj = await getter(id); const link = obj._links && obj._links[resource]; if (link) { resourceEvent = obj; break; } } return resourceEvent; }; const getEventUntilSuccess = async ({ id = '', resource = 'archive', client }) => { return (await getResourceUntilSuccess({ id, resource, getter: client.events.get })); }; const getEditionUntilSuccess = async ({ id = '', resource = 'archive', client }) => { return (await getResourceUntilSuccess({ id, resource, getter: client.editions.get })); }; const getEvents = async ({ id, client, hubId, name }) => { try { if (id != null) { const ids = Array.isArray(id) ? id : [id]; return await Promise.all(ids.map(async (id) => { const event = await client.events.get(id); const editions = await (0, paginator_1.default)(event.related.editions.list); return { event, editions, command: 'ARCHIVE', unscheduleEditions: [], deleteEditions: [], archiveEditions: [] }; })); } const hub = await client.hubs.get(hubId); const eventsList = await (0, paginator_1.default)(hub.related.events.list); let events = eventsList; if (name != null) { const itemsArray = Array.isArray(name) ? name : [name]; events = eventsList.filter(({ name: eventName }) => itemsArray.findIndex(id => { return (0, filter_1.equalsOrRegex)(eventName || '', id); }) != -1); } return await Promise.all(events.map(async (event) => ({ event, editions: await (0, paginator_1.default)(event.related.editions.list), command: 'ARCHIVE', unscheduleEditions: [], deleteEditions: [], archiveEditions: [] }))); } catch (e) { console.log(e); return []; } }; exports.getEvents = getEvents; const processItems = async ({ client, events, force, silent, missingContent, logFile }) => { try { for (let i = 0; i < events.length; i++) { events[i].deleteEditions = events[i].editions.filter(({ publishingStatus }) => publishingStatus === 'DRAFT' || publishingStatus === 'UNSCHEDULING'); events[i].unscheduleEditions = events[i].editions.filter(({ publishingStatus }) => publishingStatus === 'SCHEDULED' || publishingStatus === 'SCHEDULING'); events[i].archiveEditions = events[i].editions.filter(({ publishingStatus }) => publishingStatus === 'PUBLISHED' || publishingStatus === 'PUBLISHING'); if (events[i].deleteEditions.length + events[i].unscheduleEditions.length === events[i].editions.length) { events[i].command = 'DELETE'; } } console.log('The following events are processing:'); events.forEach(({ event, command = '', deleteEditions, unscheduleEditions, archiveEditions }) => { console.log(`${command}: ${event.name} (${event.id})`); if (deleteEditions.length || unscheduleEditions.length) { console.log(' Editions:'); deleteEditions.forEach(({ name, id }) => { console.log(` DELETE: ${name} (${id})`); }); archiveEditions.forEach(({ name, id }) => { console.log(` ARCHIVE: ${name} (${id})`); }); unscheduleEditions.forEach(({ name, id }) => { console.log(` UNSCHEDULE: ${name} (${id})`); }); } }); console.log(`Total: ${events.length}`); if (!force) { const yes = await (0, confirm_all_content_1.confirmAllContent)('perform', 'actions', false, missingContent); if (!yes) { return; } } const log = logFile.open(); let successCount = 0; for (let i = 0; i < events.length; i++) { try { const index = i; await Promise.all(events[i].unscheduleEditions.map(async (edition) => { await edition.related.unschedule(); if (events[index].command === 'ARCHIVE') { const unscheduled = await getEditionUntilSuccess({ id: edition.id, resource: 'delete', client }); if (unscheduled) { await unscheduled.related.delete(); } else { log.addComment(`UNSCHEDULE+DELETE FAILED: ${edition.id}`); log.addComment(`The edition may have taken too long to unschedule. Try again later or contact support.`); } } })); if (events[i].command === 'ARCHIVE') { await Promise.all(events[i].deleteEditions.map(edition => edition.related.delete())); await Promise.all(events[i].archiveEditions.map(edition => edition.related.archive())); } const resource = await getEventUntilSuccess({ id: events[i].event.id || '', resource: events[i].command.toLowerCase(), client }); if (!resource) { log.addComment(`${events[i].command} FAILED: ${events[i].event.id}`); log.addComment(`You don't have access to perform this action, try again later or contact support.`); } if (events[i].command === 'DELETE') { resource && (await resource.related.delete()); log.addAction(events[i].command, `${events[i].event.id}\n`); successCount++; } else { resource && (await resource.related.archive()); log.addAction(events[i].command, `${events[i].event.id}\n`); successCount++; } } catch (e) { console.log(e); log.addComment(`${events[i].command} FAILED: ${events[i].event.id}`); log.addComment(e.toString()); } } await log.close(!silent); return console.log(`Processed ${successCount} events.`); } catch (e) { return; } }; exports.processItems = processItems; const handler = async (argv) => { const { id, logFile, force, silent, name, hubId } = argv; const client = (0, dynamic_content_client_factory_1.default)(argv); const missingContent = false; if (name && id) { console.log('ID of event is specified, ignoring name'); } if (!name && !id) { console.log('No ID or name is specified'); return; } const events = await (0, exports.getEvents)({ id, client, hubId, name }); if (events.length == 0) { console.log('Nothing found to archive, aborting.'); return; } await (0, exports.processItems)({ client, events, missingContent, logFile, force, silent }); }; exports.handler = handler;