@botonic/plugin-contentful
Version:
Botonic Plugin Contentful is one of the **[available](https://github.com/hubtype/botonic/tree/master/packages)** plugins for Botonic. **[Contentful](http://www.contentful.com)** is a CMS (Content Management System) which manages contents of a great variet
175 lines • 6.65 kB
JavaScript
import { __awaiter } from "tslib";
import { BotonicContentType, ContentId, ContentType, MessageContentType, } from '../../cms';
import { ExceptionUnpacker } from '../../cms/exceptions';
import { allContents } from '../../cms/visitors/message-visitors';
import { ContentFieldType } from '../../manage-cms';
import { CONTENT_FIELDS, ContentFieldValueType, getFieldsForContentType, } from '../../manage-cms/fields';
import { andArrays } from '../../util/arrays';
import { isOfType } from '../../util/enums';
import { RecordFixer, recordId } from './csv-import';
import { EXPORTABLE_CONTENT_TYPES } from './fields';
export class ContentToImport {
constructor(contentId, name, fields) {
this.contentId = contentId;
this.name = name;
this.fields = fields;
}
toString() {
const fields = Object.keys(this.fields)
.map(k => `${k}:${String(this.fields[k])}`)
.join('/');
return [this.contentId, this.name, fields].join('/');
}
}
/**
* Reduce all the records read from a csv into ContentToImport's
* and delegates to ContentUpdater.
* It also checks consistency of all records of a given content
*/
export class ImportRecordReducer {
constructor(importer, options) {
this.importer = importer;
this.options = options;
this.pending = [];
}
consume(record) {
return __awaiter(this, void 0, void 0, function* () {
if (!isOfType(record.Model, ContentType)) {
console.error(`Bad model '${String(record.Model)}'. Should be one of ${String(Object.values(BotonicContentType))}`);
return;
}
const field = CONTENT_FIELDS.get(record.Field);
if (!field) {
console.error(`Bad field '${record.Field}'`);
return;
}
const last = this.last();
if (last) {
if (last.Id == record.Id) {
if (!this.checkLast(record, last)) {
return;
}
}
else {
yield this.flush();
}
}
this.pending.push(record);
});
}
checkLast(record, last) {
let diffField = undefined;
if (last.Model != record.Model) {
diffField = 'model';
}
if (last.Code != record.Code) {
diffField = 'code';
}
if (diffField) {
console.error(`Records ${recordId(record)} & ${recordId(last)} with same id have different ${diffField}`);
return false;
}
return true;
}
flush() {
return __awaiter(this, void 0, void 0, function* () {
const last = this.last();
if (!last)
return;
const fields = {};
for (const r of this.pending) {
fields[r.Field] = this.value(r);
}
const contentImport = new ContentToImport(ContentId.create(last.Model, last.Id), last.Code, fields);
try {
yield this.importer.update(contentImport);
}
catch (e) {
if (this.options.resumeErrors) {
const msgs = new ExceptionUnpacker().unpack(e).join('\n');
console.error(`Skipping after error when importing ${contentImport.contentId.toString()}:\n${msgs}`);
}
else {
throw e;
}
}
this.pending = [];
});
}
last() {
if (!this.pending.length)
return undefined;
return this.pending[this.pending.length - 1];
}
value(record) {
const field = CONTENT_FIELDS.get(record.Field);
const fixer = new RecordFixer(record);
fixer.fix();
return field.parse(record.to);
}
}
/**
* - If ContentToImport only has shortText and its value is empty,
* it'll assume that the content needs to be removed for this locale.
* Its fields will be deleted and all buttons which target it will be removed.
* - Otherwise, the specified fields will be overwritten
*/
export class ImportContentUpdater {
constructor(manageCms, cms, info, context, deleter) {
this.manageCms = manageCms;
this.cms = cms;
this.info = info;
this.context = context;
this.deleter = deleter;
}
update(content) {
return __awaiter(this, void 0, void 0, function* () {
if (this.mustBeDeleted(content)) {
yield this.deleter.deleteContent(content.contentId, content.name);
}
else {
yield this.updateFields(content);
}
});
}
updateFields(content) {
return __awaiter(this, void 0, void 0, function* () {
const newVal = yield this.manageCms.updateFields(this.context, content.contentId, content.fields);
yield this.warnMissingFields(content, newVal);
});
}
contentTypes() {
return __awaiter(this, void 0, void 0, function* () {
return andArrays(EXPORTABLE_CONTENT_TYPES, yield this.info.contentTypes());
});
}
warnMissingFields(content, _newVals) {
return __awaiter(this, void 0, void 0, function* () {
if (!this.defaultLocaleContents) {
this.defaultLocaleContents = yield allContents(this.cms, {}, yield this.contentTypes());
}
for (const field of getFieldsForContentType(content.contentId.model)) {
const f = CONTENT_FIELDS.get(field);
if (![
ContentFieldValueType.STRING,
ContentFieldValueType.STRING_ARRAY,
].includes(f.valueType)) {
continue;
}
const defaultLocaleContent = this.defaultLocaleContents.find(c => c.id == content.contentId.id);
if (!content.fields[field] &&
defaultLocaleContent &&
f.isNotEmptyAt(defaultLocaleContent)) {
console.warn(`Missing field '${field}' for ${content.contentId.toString()} (${content.name})`);
}
}
});
}
mustBeDeleted(content) {
return (isOfType(content.contentId.model, MessageContentType) &&
Object.keys(content.fields).length === 1 &&
ContentFieldType.SHORT_TEXT in content.fields &&
content.fields[ContentFieldType.SHORT_TEXT].trim() === '');
}
}
//# sourceMappingURL=import-updater.js.map