@botonic/plugin-contentful
Version:
## What Does This Plugin Do?
141 lines • 5.18 kB
JavaScript
import { __awaiter } from "tslib";
import { andArrays } from '../../util/arrays';
import { asyncEach } from '../../util/async';
import { CmsException, MESSAGE_CONTENT_TYPES, TOP_CONTENT_TYPES, } from '../';
import { Carousel, StartUp, Text } from '../contents';
export function getButtons(content) {
if (content instanceof Carousel) {
return Array.prototype.concat(...content.elements.map(e => e.buttons));
}
if (content instanceof Text || content instanceof StartUp) {
return content.buttons;
}
return [];
}
/**
* Goes through a content's buttons and followups
* TODO add cache
*/
export class MessageContentTraverser {
/**
* It does not take care of circular loops
*/
constructor(cms, visitor, options = {}) {
this.cms = cms;
this.visitor = visitor;
this.options = Object.assign({ depth: 1, ignoreButtons: false, ignoreFollowUps: false }, options);
if (this.options.depth > 1) {
throw new CmsException('Depth>1 not supported yet for MessageContentTraverser');
}
}
traverse(content, context) {
return __awaiter(this, void 0, void 0, function* () {
const promises = [];
if (!this.options.ignoreButtons) {
promises.push(this.traverseButtons(content, context));
}
if (!this.options.ignoreFollowUps) {
this.traverseFollowUps(content);
}
yield Promise.all(promises);
});
}
traverseButtons(content, context) {
return __awaiter(this, void 0, void 0, function* () {
const buttons = getButtons(content);
for (const button of buttons) {
const contentId = button.callback.asContentId();
if (contentId) {
const reference = (yield contentId.deliver(this.cms, context));
this.visitor(reference);
}
}
});
}
traverseFollowUps(content) {
var _a;
while ((_a = content.common) === null || _a === void 0 ? void 0 : _a.followUp) {
this.visitor(content.common.followUp);
content = content.common.followUp;
}
}
}
export function reachableFrom(cms, fromContents, context, options = {}) {
return __awaiter(this, void 0, void 0, function* () {
const reachable = new Set();
const visitor = (content) => {
reachable.add(content);
};
const traverser = new MessageContentTraverser(cms, visitor, options);
yield asyncEach(context, fromContents, fromContent => traverser.traverse(fromContent, context));
return reachable;
});
}
/**
* To obtain which contents have references (eg. buttons) to a given
* content
*/
export class MessageContentInverseTraverser {
constructor(cms, info, context, options = {}) {
this.cms = cms;
this.info = info;
this.context = context;
this.options = options;
this.referencesTo = new Map();
if (options.depth && options.depth > 1) {
throw new CmsException('Depth>1 not supported yet for MessageContentInverseTraverser');
}
}
isLoaded() {
return this.referencesTo.size > 0;
}
messageContentTypes() {
return __awaiter(this, void 0, void 0, function* () {
return andArrays(MESSAGE_CONTENT_TYPES, yield this.info.contentTypes());
});
}
load(fromContents) {
return __awaiter(this, void 0, void 0, function* () {
fromContents =
fromContents ||
(yield allMessageContents(this.cms, this.context, yield this.messageContentTypes()));
for (const fromContent of fromContents) {
const reachable = yield reachableFrom(this.cms, [fromContent], this.context, this.options);
for (const r of reachable) {
const set = this.referencesTo.get(r.id);
if (set) {
set.add(fromContent);
}
else {
this.referencesTo.set(r.id, new Set([fromContent]));
}
}
}
});
}
getReferencesTo(contentId) {
return this.referencesTo.get(contentId.id) || new Set();
}
}
export function allContents(cms, context, contentTypes) {
return __awaiter(this, void 0, void 0, function* () {
const contents = [];
for (const model of contentTypes) {
for (const c of yield cms.contents(model, context)) {
contents.push(c);
}
}
return contents;
});
}
export function allTopContents(cms, context, contentTypes = TOP_CONTENT_TYPES) {
return __awaiter(this, void 0, void 0, function* () {
return allContents(cms, context, contentTypes);
});
}
export function allMessageContents(cms, context, contentTypes = MESSAGE_CONTENT_TYPES) {
return __awaiter(this, void 0, void 0, function* () {
return allContents(cms, context, contentTypes);
});
}
//# sourceMappingURL=message-visitors.js.map