/*! * @license * Copyright Squiz Australia Pty Ltd. All Rights Reserved. */ import 'reflect-metadata'; import { provideSingleton } from '../../../singletonProvider'; import { BaseItem, BaseDto } from '../../../model/Base/Base'; import { PaginationInfo } from '../model/PaginationInfo'; import { PaginationTokens } from '../model/PaginationLinks'; import { PaginationResponse } from '../model/PaginationResponse'; import { PAGINATION_DIRECTION_TYPE_BEFORE } from '../model/PaginationTypes'; import { encodeTokenString, getPaginationLinks } from '../utils/PaginationUtils'; /** * Helper service to handle pagination. * @export * @abstract * @class PaginationService */ @provideSingleton(PaginationService) export class PaginationService { public addPaginationLinksToResponse( data: Array, paginationInfo: PaginationInfo, lastEvaluatedKey: string | null, convertToDynamoDbItem: (item: T) => BaseDto, ): PaginationResponse { const { direction, limit, requestUrl } = paginationInfo; const paginationTokens = this.getPaginationTokens(data, paginationInfo, lastEvaluatedKey, convertToDynamoDbItem); const links = getPaginationLinks(requestUrl, paginationTokens); data = data.slice(0, limit); if (direction === PAGINATION_DIRECTION_TYPE_BEFORE) { data = data.reverse(); } return { links, data }; } protected getPaginationTokens( data: Array, paginationInfo: PaginationInfo, lastEvaluatedKey: string | null, convertToDynamoDbItem: (item: T) => BaseDto, ): PaginationTokens { const { token, direction, limit } = paginationInfo; let firstItemToken: string | null = null; let lastItemToken: string | null = null; if (token || direction === PAGINATION_DIRECTION_TYPE_BEFORE) { firstItemToken = this.getTokenForDto(convertToDynamoDbItem(data[0])); } if (data.length <= limit) { lastItemToken = lastEvaluatedKey; } else { data = data.slice(0, limit); lastItemToken = this.getTokenForDto(convertToDynamoDbItem(data[data.length - 1])); } let nextToken = lastItemToken; let prevToken = firstItemToken; if (direction === PAGINATION_DIRECTION_TYPE_BEFORE) { nextToken = firstItemToken; prevToken = lastItemToken; } return { next: nextToken ? encodeURIComponent(nextToken) : null, prev: prevToken ? encodeURIComponent(prevToken) : null, }; } /** * Get the encoded token for the first item of the data array. * @param {BaseDto} dto The array of items. * @returns {string} The token string. * @memberof Repository */ protected getTokenForDto(dto: BaseDto): string { const { pk, sk } = dto; const primaryKey = { pk, sk, }; return encodeTokenString(primaryKey); } }