import { equals } from 'ramda'; import { JsonDecoder } from 'ts.data.json'; import { Listing, ListingMeta } from './models'; const metaDecoder = JsonDecoder.object( { limit: JsonDecoder.number, page: JsonDecoder.number, total: JsonDecoder.number }, 'ListingMeta' ); interface ListingDecoderOptions { entityDecoder: JsonDecoder.Decoder; entityDecoderName: string; listingDecoderName: string; apiFormat?: 'Standard' | 'JSON-LD'; } const jsonLdListingDecoder = ( entityDecoder: JsonDecoder.Decoder, entityDecoderName: string, listingDecoderName: string ): JsonDecoder.Decoder> => JsonDecoder.object( { member: JsonDecoder.array(entityDecoder, entityDecoderName), totalItems: JsonDecoder.number }, listingDecoderName ).map((data) => ({ meta: { limit: data.member.length, page: 1, total: data.totalItems }, result: data.member })) as JsonDecoder.Decoder>; const standardListingDecoder = ( entityDecoder: JsonDecoder.Decoder, entityDecoderName: string, listingDecoderName: string ): JsonDecoder.Decoder> => JsonDecoder.object>( { meta: metaDecoder, result: JsonDecoder.array(entityDecoder, entityDecoderName) }, listingDecoderName ); const buildListingDecoder = ({ entityDecoder, entityDecoderName, listingDecoderName, apiFormat = 'Standard' }: ListingDecoderOptions): JsonDecoder.Decoder> => { return ( equals(apiFormat, 'JSON-LD') ? jsonLdListingDecoder : standardListingDecoder )(entityDecoder, entityDecoderName, listingDecoderName); }; export default buildListingDecoder;