@kontent-ai/delivery-sdk
Version:
Official Kontent.AI Delivery API SDK
192 lines (167 loc) • 6.42 kB
text/typescript
import { Contracts } from '../../contracts';
import { IDeliveryClientConfig } from '../../config';
import {
Filters,
IContentItem,
IDeliveryNetworkResponse,
Parameters,
Responses,
IItemFeedQueryConfig,
ClientTypes
} from '../../models';
import { QueryService } from '../../services';
import { BaseItemListingQuery } from '../common/base-item-listing-query.class';
export class ItemsFeedQuery<
TClientTypes extends ClientTypes,
TContentItem extends IContentItem = IContentItem
> extends BaseItemListingQuery<
TClientTypes,
Responses.IListItemsFeedResponse<TContentItem, TClientTypes['contentItemType']>,
Responses.IListItemsFeedAllResponse<TContentItem, TClientTypes['contentItemType']>,
IItemFeedQueryConfig,
Contracts.IItemsFeedContract
> {
protected _queryConfig: IItemFeedQueryConfig = {};
constructor(protected config: IDeliveryClientConfig, protected queryService: QueryService<TClientTypes>) {
super(config, queryService);
}
/**
* Gets only item of given type
* @param type Codename of type to get
*/
type(type: TClientTypes['contentTypeCodenames']): this {
this.parameters.push(new Filters.TypeFilter(type));
return this;
}
/**
* Gets items of given types (logical or)
* I.e. get items of either 'Actor' or 'Movie' type
* @param types Types to get
*/
types(types: TClientTypes['contentTypeCodenames'][]): this {
this.parameters.push(new Filters.TypeFilter(types));
return this;
}
/**
* Gets only item from given collection
* @param collection Codename of collection to get
*/
collection(collection: TClientTypes['collectionCodenames']): this {
this.parameters.push(new Filters.CollectionFilter(collection));
return this;
}
/**
* Gets items from given collections (logical or)
* I.e. get items of either 'default' or 'christmas-campaign' collection
* @param collections Collections to get
*/
collections(collections: TClientTypes['collectionCodenames'][]): this {
this.parameters.push(new Filters.CollectionFilter(collections));
return this;
}
/**
* Language codename
* @param languageCodename Codename of the language
*/
languageParameter(languageCodename: TClientTypes['languageCodenames']): this {
this.parameters.push(new Parameters.LanguageParameter(languageCodename));
return this;
}
/**
* Used to limit the number of elements returned by query.
* @param elementCodenames Array of element codenames to fetch
*/
elementsParameter(elementCodenames: TClientTypes['elementCodenames'][]): this {
this.parameters.push(new Parameters.ElementsParameter(elementCodenames));
return this;
}
/**
* Used to exclude elements returned by query.
* @param elementCodenames Array of element codenames to exclude
*/
excludeElementsParameter(elementCodenames: TClientTypes['elementCodenames'][]): this {
this.parameters.push(new Parameters.ExcludeElementsParameter(elementCodenames));
return this;
}
toPromise(): Promise<
IDeliveryNetworkResponse<
Responses.IListItemsFeedResponse<TContentItem, TClientTypes['contentItemType']>,
Contracts.IItemsFeedContract
>
> {
return this.queryService.getItemsFeed(this.getUrl(), this._queryConfig ?? {});
}
getUrl(): string {
const action = '/items-feed';
// add default language is necessary
this.processDefaultLanguageParameter();
//process client level archived item exclusion
this.processExcludeArchivedItemsParameter();
return super.resolveUrlInternal(action);
}
/**
* Used to configure query
* @param queryConfig Query configuration
*/
queryConfig(queryConfig: IItemFeedQueryConfig): this {
this._queryConfig = queryConfig;
return this;
}
map(json: any): Responses.IListItemsFeedResponse<TContentItem, TClientTypes['contentItemType']> {
return this.queryService.mappingService.itemsFeedResponse(json);
}
protected allResponseFactory(
items: TContentItem[],
responses: IDeliveryNetworkResponse<
Responses.IListItemsFeedResponse<TContentItem, TClientTypes['contentItemType']>,
Contracts.IItemsFeedContract
>[]
): Responses.IListItemsFeedAllResponse<TContentItem, TClientTypes['contentItemType']> {
if (this.canLinkItems()) {
this.linkFeedItems(items, responses);
}
return {
items: items,
responses: responses
};
}
private linkFeedItems(
items: TContentItem[],
responses: IDeliveryNetworkResponse<
Responses.IListItemsFeedResponse<TContentItem, TClientTypes['contentItemType']>,
Contracts.IItemsFeedContract
>[]
): void {
// prepare all available items (including components) for linking
const allAvailableContentItems: IContentItem[] = [];
// process linked items (modular_content part of the response)
for (const response of responses) {
allAvailableContentItems.push(
...Object.values(response.data.linkedItems)
.filter((m) => m !== undefined)
.map((m) => m as TClientTypes['contentItemType'])
);
}
// add standard items
for (const item of items) {
if (
!allAvailableContentItems.find(
(m) => m.system.codename.toLowerCase() === item.system.codename.toLowerCase()
)
) {
allAvailableContentItems.push(item);
}
}
// process main items
this.linkItemsInRte(allAvailableContentItems);
}
private canLinkItems(): boolean {
if (this.config.linkedItemsReferenceHandler === 'ignore') {
return false;
}
if (this._queryConfig.disableItemLinking === true) {
return false;
}
return true;
}
}