client/components/mma/identity/identity.ts (129 lines of code) (raw):

import * as ConsentsAPI from './idapi/consents'; import * as NewslettersAPI from './idapi/newsletters'; import * as NewslettersSubscriptionsAPI from './idapi/newsletterSubscriptions'; import * as RemoveSubscriptionsAPI from './idapi/removeSubscriptions'; import * as SupportRemindersApi from './idapi/supportReminders'; import * as UserAPI from './idapi/user'; import type { ConsentOption, ConsentOptionCollection, User, UserCollection, } from './models'; import { ConsentOptionType } from './models'; const isNewsletter = (option: ConsentOption): boolean => option.type === ConsentOptionType.NEWSLETTER; const isConsent = (option: ConsentOption): boolean => option.type !== ConsentOptionType.NEWSLETTER; const isSupportReminderConsent = (option: ConsentOption): boolean => option.type === ConsentOptionType.SUPPORT_REMINDER; export const mapSubscriptions = ( subscriptions: string[], options: ConsentOption[], ): ConsentOption[] => options.map((option) => ({ ...option, subscribed: option.subscribed ? true : subscriptions.includes(option.id), })); const diff = (a: User, b: User): Partial<User> => { type UserKey = keyof User; let fields: Partial<User> = {}; Object.keys(b).forEach((key) => { const k: UserKey = key as UserKey; if (a[k] !== b[k]) { fields = { ...fields, [k]: b[k] }; } }); return fields; }; const diffWithCompositeFields = (a: User, b: User): Partial<User> => { const fields = diff(a, b); if (fields.localNumber || fields.countryCode) { return { ...fields, localNumber: b.localNumber, countryCode: b.countryCode, }; } else { return fields; } }; export const Users: UserCollection = { async getCurrentUser(): Promise<User> { return await UserAPI.read(); }, async save(user: User): Promise<User> { return await UserAPI.write(user); }, async saveChanges(original: User, changed: User): Promise<User> { const fields: Partial<User> = diffWithCompositeFields( original, changed, ); return await UserAPI.write(fields); }, getChangedFields(original: User, changed: User): Partial<User> { return diffWithCompositeFields(original, changed); }, async setUsername(user: User): Promise<User> { return await UserAPI.setUsername(user); }, }; export const ConsentOptions: ConsentOptionCollection = { async getAll(): Promise<ConsentOption[]> { const [newsletters, subscriptions] = await Promise.all([ NewslettersAPI.read(), NewslettersSubscriptionsAPI.read(), ]); const [consents, user] = await Promise.all([ ConsentsAPI.read(), UserAPI.read(), ]); const supportReminders = await SupportRemindersApi.read(); return mapSubscriptions( [...subscriptions, ...user.consents], [...newsletters, ...consents, ...supportReminders], ); }, async subscribe(option: ConsentOption): Promise<void> { if (isNewsletter(option)) { return NewslettersAPI.update(option.id, true); } else if (isSupportReminderConsent(option)) { return SupportRemindersApi.update(option.id, true); } else { return ConsentsAPI.update(option.id, true); } }, async unsubscribe(option: ConsentOption): Promise<void> { if (isNewsletter(option)) { return NewslettersAPI.update(option.id, false); } else if (isSupportReminderConsent(option)) { return SupportRemindersApi.update(option.id, false); } else { return ConsentsAPI.update(option.id, false); } }, async unsubscribeAll(): Promise<void> { return await RemoveSubscriptionsAPI.execute(); }, newsletters(options: ConsentOption[]): ConsentOption[] { return ( options .filter(isNewsletter) // @AB_TEST: Default Onboarding Newsletter Test: START // Prevent trial newsletter from displaying. .filter((newsletter: ConsentOption) => newsletter.id !== '6028') // identityId: 'saturday-roundup-trial' // @AB_TEST: Default Onboarding Newsletter Test: END ); }, consents(options: ConsentOption[]): ConsentOption[] { return options.filter(isConsent); }, findById(options, id): ConsentOption | undefined { return options.find((o) => id === o.id); }, findByIds(options, ids): ConsentOption[] { return ids .map((id) => options.find((c) => c.id === id)) .filter((x): x is ConsentOption => x !== undefined); }, };