@amplience/dc-cli
Version:
Dynamic Content CLI Tool
162 lines (161 loc) • 9.32 kB
JavaScript
"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.processContentTypes = exports.getContentTypeExports = exports.getExportRecordForContentType = exports.getReposNamesForContentType = exports.filterContentTypesByUri = exports.builder = 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 dc_management_sdk_js_1 = require("dc-management-sdk-js");
const table_1 = require("table");
const table_consts_1 = require("../../common/table/table.consts");
const chalk_1 = __importDefault(require("chalk"));
const export_service_1 = require("../../services/export.service");
const import_service_1 = require("../../services/import.service");
const import_1 = require("./import");
const lodash_1 = require("lodash");
const directory_utils_1 = require("../../common/import/directory-utils");
const log_helpers_1 = require("../../common/log-helpers");
const filter_1 = require("../../common/filter/filter");
const paginate_with_progress_1 = require("../../common/dc-management-sdk-js/paginate-with-progress");
const progress_bar_1 = require("../../common/progress-bar/progress-bar");
exports.command = 'export <dir>';
exports.desc = 'Export Content Types';
const LOG_FILENAME = (platform = process.platform) => (0, log_helpers_1.getDefaultLogPath)('type', 'export', platform);
exports.LOG_FILENAME = LOG_FILENAME;
const builder = (yargs) => {
yargs
.positional('dir', {
describe: 'Output directory for the exported Content Type definitions',
type: 'string'
})
.option('schemaId', {
type: 'string',
describe: 'The Schema ID of a Content Type to be exported.\nIf no --schemaId option is given, all content types for the hub are exported.\nA regex can be provided to select multiple types with similar or matching schema ids (eg /schema(0-9)\\.json/).\nA single --schemaId option may be given to export a single content type.\nMultiple --schemaId options may be given to export multiple content types at the same time.',
requiresArg: true
})
.alias('f', 'force')
.option('f', {
type: 'boolean',
boolean: true,
describe: 'Overwrite content types without asking.'
})
.option('archived', {
type: 'boolean',
describe: 'If present, archived content types will also be considered.',
boolean: true
})
.option('logFile', {
type: 'string',
default: exports.LOG_FILENAME,
describe: 'Path to a log file to write to.',
coerce: log_helpers_1.createLog
});
};
exports.builder = builder;
const equals = (a, b) => a.contentTypeUri === b.contentTypeUri && (0, lodash_1.isEqual)(a.settings, b.settings);
const filterContentTypesByUri = (listToFilter, contentTypeUriList) => {
if (contentTypeUriList.length === 0) {
return listToFilter;
}
const unmatchedContentTypeUriList = contentTypeUriList.filter(match => !listToFilter.some(contentType => (0, filter_1.equalsOrRegex)(contentType.contentTypeUri, match)));
if (unmatchedContentTypeUriList.length > 0) {
throw new Error(`The following schema ID(s) could not be found: [${unmatchedContentTypeUriList
.map(u => `'${u}'`)
.join(', ')}].\nNothing was exported, exiting.`);
}
return listToFilter.filter(contentType => contentTypeUriList.some(match => (0, filter_1.equalsOrRegex)(contentType.contentTypeUri, match)));
};
exports.filterContentTypesByUri = filterContentTypesByUri;
const getReposNamesForContentType = (repositories = [], contentType) => {
return (0, lodash_1.compact)(repositories
.filter(repo => repo.contentTypes &&
repo.contentTypes.find(el => el.hubContentTypeId === contentType.id && el.contentTypeUri === contentType.contentTypeUri))
.map(repo => repo.name || ''));
};
exports.getReposNamesForContentType = getReposNamesForContentType;
const getExportRecordForContentType = (contentType, outputDir, previouslyExportedContentTypes, repositories) => {
const indexOfExportedContentType = Object.values(previouslyExportedContentTypes).findIndex(c => c.contentTypeUri === contentType.contentTypeUri);
contentType.repositories = (0, exports.getReposNamesForContentType)(repositories, contentType);
if (indexOfExportedContentType < 0) {
const filename = (0, export_service_1.uniqueFilename)(outputDir, contentType.contentTypeUri, 'json', Object.keys(previouslyExportedContentTypes));
previouslyExportedContentTypes[filename] = contentType;
return {
filename: filename,
status: 'CREATED',
contentType
};
}
const filename = Object.keys(previouslyExportedContentTypes)[indexOfExportedContentType];
const previouslyExportedContentType = Object.values(previouslyExportedContentTypes)[indexOfExportedContentType];
if (equals(previouslyExportedContentType, contentType)) {
return { filename, status: 'UP-TO-DATE', contentType };
}
return {
filename,
status: 'UPDATED',
contentType
};
};
exports.getExportRecordForContentType = getExportRecordForContentType;
const getContentTypeExports = (outputDir, previouslyExportedContentTypes, contentTypesBeingExported, repositories) => {
const allExports = [];
const updatedExportsMap = [];
for (const contentType of contentTypesBeingExported) {
if (!contentType.contentTypeUri) {
continue;
}
const exportRecord = (0, exports.getExportRecordForContentType)(contentType, outputDir, previouslyExportedContentTypes, repositories);
allExports.push(exportRecord);
if (exportRecord.status === 'UPDATED') {
updatedExportsMap.push({ uri: contentType.contentTypeUri, filename: exportRecord.filename });
}
}
return [allExports, updatedExportsMap];
};
exports.getContentTypeExports = getContentTypeExports;
const processContentTypes = async (outputDir, previouslyExportedContentTypes, contentTypesBeingExported, repositories, log, force) => {
if (contentTypesBeingExported.length === 0) {
(0, export_service_1.nothingExportedExit)(log, 'No content types to export from this hub, exiting.');
return;
}
const [allExports, updatedExportsMap] = (0, exports.getContentTypeExports)(outputDir, previouslyExportedContentTypes, contentTypesBeingExported, repositories);
if (allExports.length === 0 ||
(Object.keys(updatedExportsMap).length > 0 && !(force || (await (0, export_service_1.promptToOverwriteExports)(updatedExportsMap, log))))) {
(0, export_service_1.nothingExportedExit)(log);
return;
}
await (0, directory_utils_1.ensureDirectoryExists)(outputDir);
const progress = (0, progress_bar_1.progressBar)(allExports.length, 0, { title: 'Exporting content types' });
const data = [[chalk_1.default.bold('File'), chalk_1.default.bold('Schema ID'), chalk_1.default.bold('Result')]];
for (const { filename, status, contentType } of allExports) {
if (status !== 'UP-TO-DATE') {
delete contentType.id;
(0, export_service_1.writeJsonToFile)(filename, contentType);
}
data.push([filename, contentType.contentTypeUri || '', status]);
progress.increment();
}
progress.stop();
log.appendLine((0, table_1.table)(data, table_consts_1.streamTableOptions));
};
exports.processContentTypes = processContentTypes;
const handler = async (argv) => {
const { dir, schemaId, logFile, force } = argv;
const client = (0, dynamic_content_client_factory_1.default)(argv);
const hub = await client.hubs.get(argv.hubId);
const log = logFile.open();
const repositories = (await (0, paginator_1.default)(hub.related.contentRepositories.list)) || [];
const previouslyExportedContentTypes = (0, import_service_1.loadJsonFromDirectory)(dir, dc_management_sdk_js_1.ContentType);
(0, import_1.validateNoDuplicateContentTypeUris)(previouslyExportedContentTypes);
const storedContentTypes = await (0, paginate_with_progress_1.paginateWithProgress)(hub.related.contentTypes.list, { status: dc_management_sdk_js_1.Status.ACTIVE }, { title: 'Retrieving active content types' });
if (argv.archived) {
const archivedContentTypes = await (0, paginate_with_progress_1.paginateWithProgress)(hub.related.contentTypes.list, { status: dc_management_sdk_js_1.Status.ARCHIVED }, { title: 'Retrieving archived content types' });
Array.prototype.push.apply(storedContentTypes, archivedContentTypes);
}
const schemaIdArray = schemaId ? (Array.isArray(schemaId) ? schemaId : [schemaId]) : [];
const filteredContentTypes = (0, exports.filterContentTypesByUri)(storedContentTypes, schemaIdArray);
await (0, exports.processContentTypes)(dir, previouslyExportedContentTypes, filteredContentTypes, repositories, log, force || false);
await log.close();
};
exports.handler = handler;