import type { GetTranscendPolicies, TranscendPolicy, } from '@transcend-io/airgap.js-types'; import type { ConsentManagerSupportedTranslationValue, LocaleValue, } from '@transcend-io/internationalization'; import type { ObjByString } from '@transcend-io/type-utils'; import { compile } from './compile'; /** * Update a translation for a particular message * * @param translations - Translations * @param locale - The language to fetch * @returns The message with the translation updated or created */ function getTranslation( translations: { /** Language of translation */ locale: LocaleValue; /** Value of translation */ value: string; }[], locale: LocaleValue, ): string { return ( translations.find((translation) => translation.locale === locale)?.value || '' ); } /** * Fetch a set of policy documents defined in Transcend. * * Pull the proper translation for the specified policies, and inject any template variables. * * @param input - Input for fetching policies * @param cdnLocation - Location of the CDN to fetch the policy from * @param activeLocale - The currently active locale * @param activeVariables - Active global variables * @returns the fetched policies */ export async function getTranscendPolicies( input: GetTranscendPolicies, cdnLocation: string, activeLocale: ConsentManagerSupportedTranslationValue, activeVariables: ObjByString, ): Promise { // The URL to pull the translation from const resolvedUrl = `${cdnLocation}/privacyCenterPolicies-${ input.locale || activeLocale }.json`; // Fetch the content const response = await fetch(resolvedUrl); // Check if the response is ok (status code 200-299) if (!response.ok) { throw new Error(`Network response was not ok ${response.statusText}`); } // Parse the JSON data from the response const parsed = await response.json(); // Grab all variables const allVariables = { ...activeVariables, ...input.variables, }; // TODO: https://transcend.height.app/T-39372 - enforce API shape with codec // Convert the parsed data into the expected format const formatted: TranscendPolicy[] = parsed.map( (policy: { /** ID of policy */ id: string; /** Title of policy */ title: { /** Default message of title */ defaultMessage: string; }; /** Versions of policy */ versions: { /** Content of policy */ content: { /** Default message of content */ defaultMessage: string; /** Translations */ translations: { /** Language of translation */ locale: LocaleValue; /** Value of translation */ value: string; }[]; }; }[]; }): TranscendPolicy => { const content = getTranslation(policy.versions[0].content.translations, activeLocale) || policy.versions[0].content.defaultMessage; return { id: policy.id, title: policy.title.defaultMessage, content: Object.keys(allVariables).length ? compile(content, allVariables) : content, }; }, ); // Filter by IDs of titles return input.policyIds || input.policyTitles ? formatted.filter( (policy) => (input.policyIds || []).includes(policy.id) || (input.policyTitles || []).includes(policy.title), ) : formatted; }