@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
141 lines • 5.17 kB
JavaScript
import { __awaiter } from "tslib";
import { MultiError } from 'async-parallel';
import { CmsException, ContentId, MessageContent, TOP_CONTENT_TYPES, } from '../cms';
import { ensureError } from '../cms/exceptions';
import { reachableFrom } from '../cms/visitors/message-visitors';
export class ContentsValidator {
/**
*
* @param onlyValidateReachable only validate searchable contents (with keywords) or
* which are linked from other contents
* @param initialContentIds contents to be validated even if they're not
* reachable
*/
constructor(cms, report = new DefaultContentsValidatorReports(), onlyValidateReachable = true, initialContentIds = []) {
this.cms = cms;
this.report = report;
this.onlyValidateReachable = onlyValidateReachable;
this.initialContentIds = initialContentIds;
}
/**
* Deliver all TopContent's to validate that they won't fail in production.
* A content delivery might fail if:
* - It has a link to a deleted content
* - There are infinite loops
* - There's a bug on the CMS plugin
* - An URL has empty URL empty
*/
validateAllTopContents(context) {
return __awaiter(this, void 0, void 0, function* () {
const messageContents = yield this.cacheMessageContents(context);
const messageContentsToValidate = this.onlyValidateReachable
? yield this.reachableContents(messageContents, context)
: messageContents;
for (const c of messageContentsToValidate) {
this.validate(c);
}
});
}
cacheMessageContents(context) {
return __awaiter(this, void 0, void 0, function* () {
const messageContents = [];
// TODO also validate non TopContent contents
for (const model of TOP_CONTENT_TYPES) {
try {
// TODO use async to improve concurrency
const modelContents = yield this.cms.topContents(model, context);
for (const content of modelContents) {
if (content instanceof MessageContent) {
messageContents.push(content);
}
else {
this.validate(content);
}
}
}
catch (e) {
this.processException(model, e);
}
}
return messageContents;
});
}
processException(model, e) {
const resourceId = e instanceof CmsException && e.resourceId;
const multiError = this.getMultiError(e);
if (multiError && !resourceId) {
for (const e1 of multiError.list) {
this.processException(model, e1);
}
}
else {
this.report.deliveryError(resourceId || new ContentId(model, '??'), ensureError(e));
}
}
getMultiError(e) {
if (e instanceof MultiError) {
return e;
}
if (e instanceof CmsException && e.reason instanceof MultiError) {
return e.reason;
}
return undefined;
}
reachableContents(allContents, context) {
return __awaiter(this, void 0, void 0, function* () {
const reachable = yield reachableFrom(this.cms, allContents, context);
allContents.filter(c => c.isSearchable()).forEach(c => reachable.add(c));
this.addInitialContents(allContents, reachable);
return reachable;
});
}
validate(content) {
const res = content.validate();
if (res) {
this.report.validationError(content.contentId, res);
}
else {
this.report.successfulValidation(content.contentId);
}
}
addInitialContents(allContents, reachable) {
if (this.initialContentIds.length == 0) {
return;
}
for (const c of allContents) {
if (this.initialContentIds.includes(c.id)) {
reachable.add(c);
}
}
}
}
export class DefaultContentsValidatorReports {
constructor(logErrors = true) {
this.logErrors = logErrors;
this.errors = [];
this.successContents = [];
}
successfulValidation(resourceId) {
this.successContents.push(resourceId);
}
deliveryError(resourceId, exception) {
let msg = exception.message;
if (exception instanceof CmsException) {
msg += exception.messageFromReason();
}
this.processError(resourceId, msg, true);
}
validationError(resourceId, error) {
this.processError(resourceId, error, false);
}
processError(resourceId, msg, critical) {
if (this.logErrors) {
if (!msg.includes(resourceId.id)) {
msg = `${resourceId.toString()}: ${msg}`;
}
console.log(msg);
}
this.errors.push({ resourceId, msg, critical });
}
}
//# sourceMappingURL=validate-all-contents.js.map