@amplience/dc-cli
Version:
Dynamic Content CLI Tool
245 lines (244 loc) • 12 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.handler = exports.processContentTypeSchemas = exports.getContentTypeSchemaExports = exports.filterContentTypeSchemasBySchemaId = exports.getExportRecordForContentTypeSchema = exports.writeSchemaBody = exports.generateSchemaPath = exports.builder = exports.LOG_FILENAME = exports.desc = exports.command = exports.streamTableOptions = void 0;
const dynamic_content_client_factory_1 = __importDefault(require("../../services/dynamic-content-client-factory"));
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 path = __importStar(require("path"));
const fs = __importStar(require("fs"));
const resolve_schema_body_1 = require("../../services/resolve-schema-body");
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.streamTableOptions = {
...table_consts_1.baseTableConfig,
columnDefault: {
width: 50
},
columnCount: 4,
columns: {
0: {
width: 30
},
1: {
width: 30
},
2: {
width: 100
},
3: {
width: 10
}
}
};
exports.command = 'export <dir>';
exports.desc = 'Export Content Type Schemas';
const LOG_FILENAME = (platform = process.platform) => (0, log_helpers_1.getDefaultLogPath)('schema', 'export', platform);
exports.LOG_FILENAME = LOG_FILENAME;
const builder = (yargs) => {
yargs
.positional('dir', {
describe: 'Output directory for the exported Content Type Schema definitions',
type: 'string'
})
.option('schemaId', {
type: 'string',
describe: 'The Schema ID of a Content Type Schema to be exported.\nIf no --schemaId option is given, all content type schemas for the hub are exported.\nA regex can be provided to select multiple type schemas with similar or matching schema ids (eg /schema(0-9)\\.json/).\nA single --schemaId option may be given to export a single content type schema.\nMultiple --schemaId options may be given to export multiple content type schemas at the same time.',
requiresArg: true
})
.alias('f', 'force')
.option('f', {
type: 'boolean',
boolean: true,
describe: 'Overwrite content type schema without asking.'
})
.option('archived', {
type: 'boolean',
describe: 'If present, archived content type schemas 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.schemaId === b.schemaId && a.body === b.body && a.validationLevel === b.validationLevel;
const SCHEMA_DIR = 'schemas';
const generateSchemaPath = (filepath) => SCHEMA_DIR + path.sep + path.basename(filepath).replace('.json', '-schema.json');
exports.generateSchemaPath = generateSchemaPath;
const writeSchemaBody = (filename, body) => {
if (!body) {
return;
}
const dir = path.dirname(filename);
if (fs.existsSync(dir)) {
const dirStat = fs.lstatSync(dir);
if (!dirStat || !dirStat.isDirectory()) {
throw new Error(`Unable to write schema to "${filename}" as "${dir}" is not a directory.`);
}
}
else {
try {
fs.mkdirSync(dir);
}
catch {
throw new Error(`Unable to create directory: "${dir}".`);
}
}
try {
fs.writeFileSync(filename, body);
}
catch {
throw new Error(`Unable to write file: "${filename}".`);
}
};
exports.writeSchemaBody = writeSchemaBody;
const getExportRecordForContentTypeSchema = (contentTypeSchema, outputDir, previouslyExportedContentTypeSchemas) => {
const indexOfExportedContentTypeSchema = Object.values(previouslyExportedContentTypeSchemas).findIndex(c => c.schemaId === contentTypeSchema.schemaId);
if (indexOfExportedContentTypeSchema < 0) {
const filename = (0, export_service_1.uniqueFilename)(outputDir, contentTypeSchema.schemaId, 'json', Object.keys(previouslyExportedContentTypeSchemas));
previouslyExportedContentTypeSchemas[filename] = contentTypeSchema;
return {
filename: filename,
status: 'CREATED',
contentTypeSchema
};
}
const filename = Object.keys(previouslyExportedContentTypeSchemas)[indexOfExportedContentTypeSchema];
const previouslyExportedContentTypeSchema = Object.values(previouslyExportedContentTypeSchemas)[indexOfExportedContentTypeSchema];
if (equals(previouslyExportedContentTypeSchema, contentTypeSchema)) {
return { filename, status: 'UP-TO-DATE', contentTypeSchema };
}
return {
filename,
status: 'UPDATED',
contentTypeSchema
};
};
exports.getExportRecordForContentTypeSchema = getExportRecordForContentTypeSchema;
const filterContentTypeSchemasBySchemaId = (listToFilter, listToMatch = []) => {
if (listToMatch.length === 0) {
return listToFilter;
}
const unmatchedIdList = listToMatch.filter(match => !listToFilter.some(schema => (0, filter_1.equalsOrRegex)(schema.schemaId, match)));
if (unmatchedIdList.length > 0) {
throw new Error(`The following schema ID(s) could not be found: [${unmatchedIdList
.map(u => `'${u}'`)
.join(', ')}].\nNothing was exported, exiting.`);
}
return listToFilter.filter(schema => listToMatch.some(match => (0, filter_1.equalsOrRegex)(schema.schemaId, match)));
};
exports.filterContentTypeSchemasBySchemaId = filterContentTypeSchemasBySchemaId;
const getContentTypeSchemaExports = (outputDir, previouslyExportedContentTypeSchemas, contentTypeSchemasBeingExported) => {
const allExports = [];
const updatedExportsMap = [];
for (const contentTypeSchema of contentTypeSchemasBeingExported) {
if (!contentTypeSchema.schemaId) {
continue;
}
const exportRecord = (0, exports.getExportRecordForContentTypeSchema)(contentTypeSchema, outputDir, previouslyExportedContentTypeSchemas);
allExports.push(exportRecord);
if (exportRecord.status === 'UPDATED') {
updatedExportsMap.push({ schemaId: contentTypeSchema.schemaId, filename: exportRecord.filename });
}
}
return [allExports, updatedExportsMap];
};
exports.getContentTypeSchemaExports = getContentTypeSchemaExports;
const processContentTypeSchemas = async (outputDir, previouslyExportedContentTypeSchemas, storedContentTypeSchemas, log, force) => {
if (storedContentTypeSchemas.length === 0) {
(0, export_service_1.nothingExportedExit)(log, 'No content type schemas to export from this hub, exiting.');
return;
}
const [allExports, updatedExportsMap] = (0, exports.getContentTypeSchemaExports)(outputDir, previouslyExportedContentTypeSchemas, storedContentTypeSchemas);
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 file'), chalk_1.default.bold('Schema ID'), chalk_1.default.bold('Result')]
];
for (const { filename, status, contentTypeSchema } of allExports) {
let schemaFilename = '';
if (status !== 'UP-TO-DATE') {
delete contentTypeSchema.id;
const schemaBody = contentTypeSchema.body;
const schemaBodyFilename = (0, exports.generateSchemaPath)(filename);
const posixFilename = schemaBodyFilename.split(path.sep).join(path.posix.sep);
contentTypeSchema.body = '.' + path.posix.sep + posixFilename;
schemaFilename = outputDir + path.sep + schemaBodyFilename;
(0, exports.writeSchemaBody)(schemaFilename, schemaBody);
(0, export_service_1.writeJsonToFile)(filename, new dc_management_sdk_js_1.ContentTypeSchema({
body: contentTypeSchema.body,
schemaId: contentTypeSchema.schemaId,
validationLevel: contentTypeSchema.validationLevel
}));
}
progress.increment();
data.push([filename, schemaFilename, contentTypeSchema.schemaId || '', status]);
}
progress.stop();
log.appendLine((0, table_1.table)(data, exports.streamTableOptions));
};
exports.processContentTypeSchemas = processContentTypeSchemas;
const handler = async (argv) => {
const { dir, schemaId, logFile, force } = argv;
const [contentTypeSchemas] = await (0, resolve_schema_body_1.resolveSchemaBody)((0, import_service_1.loadJsonFromDirectory)(dir, dc_management_sdk_js_1.ContentTypeSchema), dir);
const client = (0, dynamic_content_client_factory_1.default)(argv);
const hub = await client.hubs.get(argv.hubId);
const log = logFile.open();
const storedContentTypeSchemas = await (0, paginate_with_progress_1.paginateWithProgress)(hub.related.contentTypeSchema.list, argv.archived ? undefined : { status: dc_management_sdk_js_1.Status.ACTIVE }, { title: 'Retrieving content type schemas' });
const schemaIdArray = schemaId ? (Array.isArray(schemaId) ? schemaId : [schemaId]) : [];
const filteredContentTypeSchemas = (0, exports.filterContentTypeSchemasBySchemaId)(storedContentTypeSchemas, schemaIdArray);
await (0, exports.processContentTypeSchemas)(dir, contentTypeSchemas, filteredContentTypeSchemas, log, force || false);
await log.close();
};
exports.handler = handler;