import { RedeemableToken } from '../models/redeemable-token'; import { MembershipRedeemableTokenData } from '../types/redeemable-token'; import { InvalidResponseError } from '../errors'; /** * Maps membership response to redeemableToken model. * @param tokenData Response to redeemableToken request. * @throws {InvalidResponseError} If the membership request does not return the expected response. * @returns RedeemableToken instance. */ export function mapRedeemableTokenResponse (tokenData: MembershipRedeemableTokenData): RedeemableToken { /* Regarding optionalLicenceId - licenceId field in tokenData.redeemableFor is populated either from redeemableForLicence or redeemableForNewspaper. For new AIM graphql endpoint - - licenceId is required for redeemableForLicence (Datatype - String!) - but optional for redeemableForNewspaper (Datatype - String) In this case Graphql query fails because of data types mismatch. Hence AIM team advised to use alias for one of the licenceId field. licenceId field from redeemableForNewspaper fragment is called optionalLicenceId AIM graphql doc link - https://github.com/Financial-Times/aim-graphql-api/blob/a91bea7ce1d057c3cad718333a6947b15cc62c90/aim-graphql-api/graph/schema/query/redeem_token/redeemable_token.graphqls#L5 Change while populating accessLicenceId supports old as well as new AIM graphql endpoints */ const mappedTokenData = { id: tokenData.id, accessDuration: tokenData.redeemableFor.accessDuration, accessLicenceId: tokenData.redeemableFor.licenceId ?? tokenData.redeemableFor.optionalLicenceId, type: tokenData.redeemableFor.type, status: tokenData.status, redeemability: tokenData.redeemability }; if (Object.values(mappedTokenData).includes(undefined)) { throw new InvalidResponseError('Membership redeemable token data response contains undefined values', { mappedTokenData }); } return new RedeemableToken(mappedTokenData); }