UNPKG

@dlillyatx/dc-cli

Version:
230 lines (229 loc) 10.9 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.processIndexes = exports.loadAndRewriteWebhooks = exports.doUpdate = exports.doCreate = exports.enrichIndex = exports.updateWebhookIfDifferent = exports.getIndexProperties = exports.storedIndexMapper = exports.filterIndexesById = exports.rewriteIndexNames = exports.validateNoDuplicateIndexNames = exports.replicaList = exports.builder = exports.LOG_FILENAME = exports.desc = exports.command = void 0; const chalk_1 = __importDefault(require("chalk")); const dc_management_sdk_js_1 = require("dc-management-sdk-js"); const path_1 = require("path"); const table_1 = require("table"); const paginator_1 = __importDefault(require("../../common/dc-management-sdk-js/paginator")); const log_helpers_1 = require("../../common/log-helpers"); const table_consts_1 = require("../../common/table/table.consts"); const dynamic_content_client_factory_1 = __importDefault(require("../../services/dynamic-content-client-factory")); const import_service_1 = require("../../services/import.service"); const export_1 = require("./export"); const webhook_rewriter_1 = require("./webhook-rewriter"); exports.command = 'import <dir>'; exports.desc = 'Import Search Index'; exports.LOG_FILENAME = (platform = process.platform) => log_helpers_1.getDefaultLogPath('search-index', 'import', platform); exports.builder = (yargs) => { yargs.positional('dir', { describe: 'Directory containing Search Indexes', type: 'string' }); yargs.option('logFile', { type: 'string', default: exports.LOG_FILENAME, describe: 'Path to a log file to write to.', coerce: log_helpers_1.createLog }); yargs.option('webhooks', { type: 'boolean', describe: 'Import webhooks as well. The command will attempt to rewrite account names and staging environments in the webhook body to match the destination.', boolean: true }); }; const searchIndexList = (hub, parentId, projection) => { return (options) => hub.related.searchIndexes.list(parentId, projection, options); }; exports.replicaList = (index, projection) => { return (options) => index.related.replicas.list(projection, options); }; exports.validateNoDuplicateIndexNames = (importedIndexes) => { const nameToFilenameMap = new Map(); for (const [filename, index] of Object.entries(importedIndexes)) { if (index.name) { const otherFilenames = nameToFilenameMap.get(index.name) || []; if (filename) { nameToFilenameMap.set(index.name, [...otherFilenames, filename]); } } } const uniqueDuplicateNames = []; nameToFilenameMap.forEach((filenames, name) => { if (filenames.length > 1) { uniqueDuplicateNames.push([name, filenames]); } }); if (uniqueDuplicateNames.length > 0) { throw new Error(`Indexes must have unique name values. Duplicate values found:-\n${uniqueDuplicateNames .map(([name, filenames]) => ` name: '${name}' in files: [${filenames.map(f => `'${f}'`).join(', ')}]`) .join('\n')}`); } }; exports.rewriteIndexNames = (hub, importedIndexes) => { for (const index of Object.values(importedIndexes)) { const name = index.name; const firstDot = name.indexOf('.'); if (firstDot == -1) { index.name = `${hub.name}.${name}`; } else { index.name = `${hub.name}${name.substring(firstDot)}`; } } }; exports.filterIndexesById = (idFilter, importedIndexes) => { for (const [filename, index] of Object.entries(importedIndexes)) { if (idFilter.indexOf(index.id) === -1) { delete importedIndexes[filename]; } } }; exports.storedIndexMapper = (index, storedIndexes) => { const found = storedIndexes.find(stored => stored.name === index.name); const mutatedIndex = found ? { ...index, id: found.id } : index; return new export_1.EnrichedSearchIndex(mutatedIndex); }; exports.getIndexProperties = (index) => { return { label: index.label, name: index.name, suffix: index.suffix, type: index.type }; }; exports.updateWebhookIfDifferent = async (webhook, newWebhook) => { if (newWebhook === undefined) { return; } await webhook.related.update(newWebhook); }; exports.enrichIndex = async (index, enrichedIndex, webhooks) => { const settings = await index.related.settings.get(); const replicas = new Set(settings.replicas || []); if (enrichedIndex.settings.replicas) { enrichedIndex.settings.replicas.forEach((replica) => { replicas.add(replica); }); } enrichedIndex.settings.replicas = Array.from(replicas); await index.related.settings.update(enrichedIndex.settings, false); if (replicas.size) { const replicas = await paginator_1.default(exports.replicaList(index)); for (const importReplica of enrichedIndex.replicas) { let replica = replicas.find(replica => replica.name === importReplica.name); if (replica) { replica = await replica.related.update(new dc_management_sdk_js_1.SearchIndex(exports.getIndexProperties(importReplica))); replica.related.settings.update(importReplica.settings, false); } } } const types = await paginator_1.default(index.related.assignedContentTypes.list); const unassigned = new Set(types); for (const assignment of enrichedIndex.assignedContentTypes) { let existing = types.find(type => type.contentTypeUri === assignment.contentTypeUri); if (!existing) { existing = await index.related.assignedContentTypes.create(assignment); } unassigned.delete(existing); if (webhooks) { await exports.updateWebhookIfDifferent(await existing.related.webhook(), webhooks.get(assignment.webhook)); await exports.updateWebhookIfDifferent(await existing.related.activeContentWebhook(), webhooks.get(assignment.activeContentWebhook)); await exports.updateWebhookIfDifferent(await existing.related.archivedContentWebhook(), webhooks.get(assignment.archivedContentWebhook)); } } for (const toRemove of unassigned) { await toRemove.related.unassign(index.id); } }; exports.doCreate = async (hub, index, webhooks, log) => { try { const assignedContentTypes = index.assignedContentTypes.map(type => ({ contentTypeUri: type.contentTypeUri })); const toCreate = new dc_management_sdk_js_1.SearchIndex({ ...exports.getIndexProperties(index), assignedContentTypes }); const createdIndex = await hub.related.searchIndexes.create(toCreate); await exports.enrichIndex(createdIndex, index, webhooks); log.addAction('CREATE', `${createdIndex.id}`); return createdIndex; } catch (err) { throw new Error(`Error creating index ${index.name}:\n\n${err}`); } }; exports.doUpdate = async (hub, allReplicas, index, webhooks, log) => { try { const retrievedIndex = await hub.related.searchIndexes.get(index.id); const dstWebhooks = new Map(); const enrichedWebhook = await export_1.enrichIndex(dstWebhooks, allReplicas, retrievedIndex); if (export_1.equals(enrichedWebhook, index, false, dstWebhooks, webhooks)) { return { index: retrievedIndex, updateStatus: import_service_1.UpdateStatus.SKIPPED }; } Object.assign(retrievedIndex, exports.getIndexProperties(index)); const updatedIndex = await retrievedIndex.related.update(retrievedIndex); await exports.enrichIndex(updatedIndex, index, webhooks); log.addAction('UPDATE', `${retrievedIndex.id}`); return { index: updatedIndex, updateStatus: import_service_1.UpdateStatus.UPDATED }; } catch (err) { throw new Error(`Error updating index ${index.name}: ${err.message}`); } }; exports.loadAndRewriteWebhooks = async (hub, dir) => { const webhookList = import_service_1.loadJsonFromDirectory(dir, dc_management_sdk_js_1.Webhook); const webhooks = new Map(); for (const webhook of Object.values(webhookList)) { webhooks.set(webhook.id, webhook); } const account = hub.name; const settings = hub.settings; const vseObj = settings.virtualStagingEnvironment; const vse = vseObj ? vseObj.hostname : undefined; webhooks.forEach(webhook => { if (webhook.customPayload) { webhook.customPayload.value = webhook_rewriter_1.rewriteDeliveryContentItem(webhook.customPayload.value, account, vse); } }); return webhooks; }; exports.processIndexes = async (indexesToProcess, allReplicas, webhooks, hub, log) => { const data = []; data.push([chalk_1.default.bold('ID'), chalk_1.default.bold('Name'), chalk_1.default.bold('Result')]); for (const entry of indexesToProcess) { let status; let index; if (entry.id) { const result = await exports.doUpdate(hub, allReplicas, entry, webhooks, log); index = result.index; status = result.updateStatus === import_service_1.UpdateStatus.SKIPPED ? 'UP-TO-DATE' : 'UPDATED'; } else { index = await exports.doCreate(hub, entry, webhooks, log); status = 'CREATED'; } data.push([index.id, index.name, status]); } log.appendLine(table_1.table(data, table_consts_1.streamTableOptions)); }; exports.handler = async (argv, idFilter) => { const { dir, logFile } = argv; const client = dynamic_content_client_factory_1.default(argv); const hub = await client.hubs.get(argv.hubId); const log = logFile.open(); const indexes = import_service_1.loadJsonFromDirectory(dir, export_1.EnrichedSearchIndex); if (Object.keys(indexes).length === 0) { throw new Error(`No indexes found in ${dir}`); } exports.validateNoDuplicateIndexNames(indexes); exports.rewriteIndexNames(hub, indexes); if (idFilter) { exports.filterIndexesById(idFilter, indexes); } const allStoredIndexes = await paginator_1.default(searchIndexList(hub)); const { storedIndexes, allReplicas } = export_1.separateReplicas(allStoredIndexes); const indexesToProcess = Object.values(indexes).map(index => exports.storedIndexMapper(index, storedIndexes)); const webhooks = argv.webhooks ? await exports.loadAndRewriteWebhooks(hub, path_1.join(dir, 'webhooks')) : undefined; await exports.processIndexes(indexesToProcess, allReplicas, webhooks, hub, log); await log.close(); };