UNPKG

contensis-delivery-api

Version:

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

235 lines (193 loc) 8.78 kB
import { Entry, EntryGetOptions, EntryListOptions, IEntryOperations, ContensisClient } from '../models'; import { LinkResolver } from './link-resolver'; import { ClientParams, QueryAggregations, defaultMapperForLanguage, defaultMapperForPublishedVersionStatus, FieldLinkDepths, IHttpClient, isBrowser, isIE, MapperFn, PagedList, PagedSearchList, Query, UrlBuilder, ZenqlQuery } from 'contensis-core-api'; const defaultListUrl = `/api/delivery/projects/:projectId/entries`; let listUrl = (options: EntryListOptions, params: ClientParams) => { return !!options.contentTypeId ? `/api/delivery/projects/:projectId/contentTypes/:contentTypeId/entries` : defaultListUrl; }; let getMappers: { [key: string]: MapperFn } = { language: defaultMapperForLanguage, versionStatus: defaultMapperForPublishedVersionStatus, fields: (value: string[]) => (value && value.length > 0 ? value : null), linkDepth: (value: number) => (value && value > 0 ? value : null), fieldLinkDepths: (value: FieldLinkDepths) => Object.keys(value || {}).length > 0 ? JSON.stringify(value) : null, }; let listMappers: { [key: string]: MapperFn } = { ...getMappers, order: (value: string[]) => (value && value.length > 0) ? value : null, pageIndex: (value: number, options: EntryListOptions, params: ClientParams) => (options && options.pageOptions && options.pageOptions.pageIndex) || (params.pageIndex), pageSize: (value: number, options: EntryListOptions, params: ClientParams) => (options && options.pageOptions && options.pageOptions.pageSize) || (params.pageSize) }; let searchMappers: { [key: string]: MapperFn } = { aggregations: (value: QueryAggregations) => Object.keys(value || {}).length > 0 ? JSON.stringify(value) : null, linkDepth: (value: number) => (value && (value > 0)) ? value : null, fieldLinkDepths: (value: FieldLinkDepths) => Object.keys(value || {}).length > 0 ? JSON.stringify(value) : null, }; export class EntryOperations implements IEntryOperations { constructor(private httpClient: IHttpClient, private contensisClient: ContensisClient) { } get(idOrOptions: string | EntryGetOptions): Promise<Entry> { let url = UrlBuilder.create('/api/delivery/projects/:projectId/entries/:id', { language: null, versionStatus: null, linkDepth: null, fieldLinkDepths: null, fields: null }) .addOptions(idOrOptions, 'id') .setParams(this.contensisClient.getParams()) .addMappers(getMappers) .toUrl(); return this.contensisClient.ensureIsAuthorized().then(() => { return this.httpClient.request<Entry>(url, { headers: this.contensisClient.getHeaders() }); }); } list(contentTypeIdOrOptions: string | EntryListOptions): Promise<PagedList<Entry>> { let url = UrlBuilder.create( listUrl, { language: null, versionStatus: null, linkDepth: null, order: null, fieldLinkDepths: null, fields: null, pageIndex: null, pageSize: null }) .addOptions(contentTypeIdOrOptions, 'contentTypeId') .setParams(this.contensisClient.getParams()) .addMappers(listMappers) .toUrl(); return this.contensisClient.ensureIsAuthorized().then(() => { return this.httpClient.request<PagedList<Entry>>(url, { headers: this.contensisClient.getHeaders() }); }); } search<Q extends string | Query | ZenqlQuery>(query: Q, linkDepth: number = 0) { if (!query) { return new Promise((resolve) => { resolve(null); }) as Promise<PagedList<Entry> | PagedSearchList<Entry>>; } let deliveryQuery = query instanceof Query ? query as Query : null; // use duck-typing for backwards compatibility pre v1.2.0 if (deliveryQuery !== null || !!(query as any).where || !!(query as any).orderBy) { return this.searchUsingQuery(deliveryQuery || (query as any), linkDepth); } let zenqlQuery: ZenqlQuery = query instanceof ZenqlQuery ? query as ZenqlQuery : null; if (zenqlQuery === null) { if (typeof query === 'string') { zenqlQuery = new ZenqlQuery(query); } else { throw new Error('A valid query needs to be specified.'); } } let params = this.contensisClient.getParams(); let pageSize = params.pageSize || 25; let pageIndex = params.pageIndex || 0; let fields: string[] = []; let fieldLinkDepths: FieldLinkDepths = {}; pageSize = zenqlQuery.pageSize || pageSize; pageIndex = zenqlQuery.pageIndex || pageIndex; fields = zenqlQuery.fields || fields; fieldLinkDepths = zenqlQuery.fieldLinkDepths || fieldLinkDepths; // eslint-disable-next-line @typescript-eslint/no-unused-vars let { accessToken, projectId, language, responseHandler, rootUrl, versionStatus, ...requestParams } = params; let payload = { ...requestParams, aggregations: zenqlQuery.aggregations, fieldLinkDepths, linkDepth, pageSize, pageIndex, zenql: zenqlQuery.zenql, }; if (fields && fields.length > 0) { payload['fields'] = fields; } let url = UrlBuilder.create(defaultListUrl, { ...payload }) .setParams({ ...(payload as any), projectId }) .addMappers(searchMappers) .toUrl(); return this.contensisClient.ensureIsAuthorized().then(() => { return this.httpClient.request<PagedSearchList<Entry>>(url, { method: 'GET', headers: this.contensisClient.getHeaders('application/json; charset=utf-8') }); }); } resolve<T extends Entry | Entry[] | PagedList<Entry>>(entryOrList: T, fields: string[] = null): Promise<T> { let params = this.contensisClient.getParams(); let resolver = new LinkResolver(entryOrList, fields, params.versionStatus, (query: any) => this.search(query)); return resolver.resolve(); } private searchUsingQuery(query: Query, linkDepth: number = 0): Promise<PagedSearchList<Entry>> { if (!query) { return new Promise((resolve) => { resolve(null); }); } let deliveryQuery = query as Query; let params = this.contensisClient.getParams(); let pageSize = params.pageSize || 25; let pageIndex = params.pageIndex || 0; let fields: string[] = []; let fieldLinkDepths: FieldLinkDepths = {}; pageSize = deliveryQuery.pageSize || pageSize; pageIndex = deliveryQuery.pageIndex || pageIndex; fields = deliveryQuery.fields || fields; fieldLinkDepths = deliveryQuery.fieldLinkDepths || fieldLinkDepths; let orderBy = (deliveryQuery.orderBy && ((deliveryQuery.orderBy as any)._items || deliveryQuery.orderBy)); // eslint-disable-next-line @typescript-eslint/no-unused-vars let { accessToken, projectId, language, responseHandler, rootUrl, versionStatus, ...requestParams } = params; let payload = { ...requestParams, aggregations: deliveryQuery.aggregations, fieldLinkDepths, linkDepth, pageSize, pageIndex, where: JSON.stringify(deliveryQuery.where) }; if (fields && fields.length > 0) { payload['fields'] = fields; } if (deliveryQuery.orderBy && (!Array.isArray(deliveryQuery.orderBy) || deliveryQuery.orderBy.length > 0)) { payload['orderBy'] = JSON.stringify(orderBy); } let url = UrlBuilder.create('/api/delivery/projects/:projectId/entries/search', { ...payload }) .setParams({ ...(payload as any), projectId }) .addMappers(searchMappers) .toUrl(); if (url.length > 8000 || (isBrowser() && isIE() && url.length > 2083)) { return this.searchUsingPost(query, linkDepth); } return this.contensisClient.ensureIsAuthorized().then(() => { return this.httpClient.request<PagedSearchList<Entry>>(url, { method: 'GET', headers: this.contensisClient.getHeaders('application/json; charset=utf-8') }); }); } private searchUsingPost(query: any, linkDepth: number = 0): Promise<PagedSearchList<Entry>> { if (!query) { return new Promise((resolve) => { resolve(null); }); } let params = this.contensisClient.getParams(); query.pageSize = query.pageSize || params.pageSize; query.pageIndex = query.pageIndex || 0; let url = UrlBuilder.create('/api/delivery/projects/:projectId/entries/search', { linkDepth, fieldLinkDepths: query.fieldLinkDepths }) .setParams(this.contensisClient.getParams()) .addMappers(searchMappers) .toUrl(); return this.contensisClient.ensureIsAuthorized().then(() => { // Clone the query instance so we can remove the fieldLinkDepths // from the POST body without mutating the supplied query arg const clone = Object.assign(Object.create(Object.getPrototypeOf(query)), query); delete clone.fieldLinkDepths; return this.httpClient.request<PagedSearchList<Entry>>(url, { method: 'POST', headers: this.contensisClient.getHeaders('application/json; charset=utf-8'), body: JSON.stringify(clone) }); }); } }