@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
155 lines (134 loc) • 3.99 kB
text/typescript
import * as contentful from 'contentful'
import { Asset, ContentType, Entry, EntryCollection } from 'contentful'
import { Context } from '../cms'
import { ContentfulOptions } from '../plugin'
import { DeliveryApi } from './delivery-api'
import { convertContentfulException } from './delivery-utils'
import {
ContentfulVisitor,
I18nEntryTraverser,
I18nValue,
VisitedField,
} from './traverser'
/**
* It requests contentful to deliver all locales for each entry, and we discard all except the one in the context
*/
export class IgnoreFallbackDecorator implements DeliveryApi {
constructor(private readonly api: DeliveryApi) {}
async getEntries<T>(
context: Context,
query: any = {}
): Promise<EntryCollection<T>> {
if (!context.ignoreFallbackLocale) {
return this.api.getEntries(context, query)
}
try {
let entries = await this.api.getEntries<T>(
this.i18nContext(context),
query
)
entries = { ...entries }
entries.items = await this.traverseEntries(context, entries.items)
return entries
} catch (e) {
throw convertContentfulException(e, query)
}
}
async getEntry<T>(
id: string,
context: Context,
query: any = {}
): Promise<Entry<T>> {
if (!context.ignoreFallbackLocale) {
return this.api.getEntry(id, context, query)
}
const entry = await this.api.getEntry<T>(
id,
this.i18nContext(context),
query
)
return (await this.traverseEntries(context, [entry]))[0]
}
async traverseEntries<T>(
context: Context,
entries: Entry<T>[]
): Promise<Entry<T>[]> {
const visitor = new IgnoreFallbackVisitor(context)
return Promise.all(
entries.map(async item => {
const traverser = new I18nEntryTraverser(this.api, visitor)
return await traverser.traverse(item, context)
})
)
}
getAsset(id: string, context: Context, query?: any): Promise<Asset> {
console.warn(
'IgnoreFallbackDecorator does not any special treatment for getAsset'
)
return this.api.getAsset(id, context, query)
}
async getAssets(
context: Context,
query?: any
): Promise<contentful.AssetCollection> {
console.warn(
'IgnoreFallbackDecorator does not any special treatment for getAssets'
)
return this.api.getAssets(context, query)
}
getContentType(id: string): Promise<ContentType> {
return this.api.getContentType(id)
}
getOptions(): ContentfulOptions {
return this.api.getOptions()
}
private i18nContext(context: Context) {
return {
...context,
locale: '*',
} as Context
}
}
class IgnoreFallbackVisitor implements ContentfulVisitor {
contextForContentful: Context
constructor(readonly context: Context) {
if (!context.locale) {
throw new Error(
'Context.ignoreFallbackLocale set but Context.locale not set'
)
}
this.contextForContentful = {
...context,
locale: '*',
}
}
visitEntry<T>(entry: Entry<T>): Entry<T> {
return entry
}
visitOtherField(vf: VisitedField<any>): I18nValue<any> {
return this.hackType(vf.value[vf.locale], undefined)
}
visitStringField(vf: VisitedField<string>): I18nValue<string> {
return this.hackType(vf.value[vf.locale], '')
}
hackType<T>(t: T, defaultValue?: T): I18nValue<T> {
if (defaultValue != undefined) {
t = t ?? defaultValue
}
return t as any as I18nValue<T>
}
visitMultipleStringField(vf: VisitedField<string[]>): I18nValue<string[]> {
return this.hackType(vf.value[vf.locale], [])
}
visitSingleReference<T>(vf: VisitedField<Entry<T>>): I18nValue<Entry<T>> {
return this.hackType(vf.value[vf.locale], undefined as any as Entry<T>)
}
visitMultipleReference<T>(
vf: VisitedField<EntryCollection<T>>
): I18nValue<EntryCollection<T>> {
return this.hackType(vf.value[vf.locale])
}
name(): string {
return 'ignoreFallbackLocale'
}
}