UNPKG

contensis-delivery-api

Version:

Client for retrieving content using the read-only Contensis Delivery API

179 lines (159 loc) 6.36 kB
import { Entry } from '../models'; interface ResolvedEntry { entries: Entry[]; value: any; } function isUnresolvedEntry(value: any): boolean { if (value && value.sys && value.sys.id) { let keys = Object.keys(value); return (keys.length === 1); } return false; } function isUnresolvedImage(value: any): boolean { if (value && value.asset) { let keys = Object.keys(value); return (keys.length <= 2) && isUnresolvedEntry(value.asset); } return false; } function isComposer(value: any): boolean { if (Array.isArray(value) && (value.length > 0)) { return isComposerItem(value[0]); } return false; } function isComposerItem(value: any): boolean { if (value && value.type && value.value) { let keys = Object.keys(value); return (keys.length === 2); } return false; } export class EntryResolver { constructor(private entry: Entry, private paths: string[], private getEntry: (id: string, language: string) => Promise<Entry>) { } resolve(): Promise<Entry> { let paths: string[] = this.paths || Object.keys(this.entry); let promises: Promise<ResolvedEntry>[] = paths.map(path => { let parts = path.split('.'); let field = parts.shift(); let promise: Promise<ResolvedEntry> = null; let value = this.entry[field]; if (value) { promise = this.resolveField(value); if (!promise && isComposer(value)) { let composerType = (parts.length > 0) ? parts.shift() : null; promise = this.resolveComposerField(value, composerType); } } promise = !promise ? Promise.resolve(null) : promise.then(resolvedValue => { this.entry[field] = resolvedValue.value; return resolvedValue; }); return promise.then(v => { return this.next(v, parts.join('.')); }); }); return Promise.all(promises).then(values => { return this.entry; }); } next(resolvedEntry: ResolvedEntry, path: string): Promise<any> { if (!path || !resolvedEntry || !resolvedEntry.entries || (resolvedEntry.entries.length <= 0)) { return Promise.resolve(resolvedEntry); } let promises = resolvedEntry.entries.map(entry => { let resolver = new EntryResolver(entry, [path], (id: string, language: string) => this.getEntry(id, language)); return resolver.resolve(); }); return Promise.all(promises); } private resolveField(value: any): Promise<ResolvedEntry> { if (isUnresolvedEntry(value)) { return this.resolveEntry(value); } if (isUnresolvedImage(value)) { return this.resolveImage(value); } if (Array.isArray(value)) { let isResolving = false; let promises = value.map(item => { if (isUnresolvedEntry(item)) { isResolving = true; return this.resolveEntry(item); } if (isUnresolvedImage(item)) { isResolving = true; return this.resolveImage(item); } return Promise.resolve({ entries: [], value: item }); }); if (isResolving) { return Promise.all(promises).then((resolvedEntries) => { let list = []; let entries = []; for (let e of resolvedEntries) { list.push(e.value); entries = entries.concat(e.entries); } return { entries, value: list }; }); } } return null; } private resolveComposerField(value: any, type: string): Promise<ResolvedEntry> { if (Array.isArray(value)) { let isResolving = false; let promises: Promise<ResolvedEntry>[] = value.map(item => { if (isComposerItem(item)) { if (!type || (type === item.type)) { let itemPromise = this.resolveField(item.value); if (itemPromise) { isResolving = true; return itemPromise.then((v) => { item.value = v; return item; }); } } } return Promise.resolve({ entries: [], value: item }); }); if (isResolving) { return Promise.all(promises).then((resolvedEntries) => { let list = []; let entries = []; for (let e of resolvedEntries) { list.push(e.value); entries = entries.concat(e.entries); } return { entries, value: list }; }); } } return null; } private async resolveEntry(value: any): Promise<ResolvedEntry> { if (value && value.sys && value.sys.id) { let language = value.sys.language || this.entry.sys.language; let entry = await this.getEntry(value.sys.id, language); return { entries: [entry], value: entry }; } return Promise.resolve({ entries: [], value }); } private resolveImage(value: any): Promise<ResolvedEntry> { if (value && value.asset && value.asset.sys && value.asset.sys.id) { let language = value.asset.sys.language || this.entry.sys.language; return this.getEntry(value.asset.sys.id, language) .then((image) => { value.asset = image; return { entries: [image], value }; }); } return Promise.resolve({ entries: [], value }); } }