UNPKG

@didomi/iabtcf-cmpapi

Version:

Ensures other in-page digital marketing technologies have access to CMP transparency and consent information for the iab. Transparency and Consent Framework (TCF).

102 lines (101 loc) 4.03 kB
import { CmpApiModel } from './CmpApiModel.js'; import { CmpStatus, DisplayStatus, EventStatus } from './status/index.js'; import { CallResponder } from './CallResponder.js'; import { TCString, TCModel } from '@didomi/iabtcf-core'; export class CmpApi { callResponder; isServiceSpecific; numUpdates = 0; /** * @param {number} cmpId - IAB assigned CMP ID * @param {number} cmpVersion - integer version of the CMP * @param {boolean} isServiceSpecific - whether or not this cmp is configured to be service specific * @param {CustomCommands} [customCommands] - custom commands from the cmp */ constructor(cmpId, cmpVersion, isServiceSpecific = true, customCommands) { this.throwIfInvalidInt(cmpId, 'cmpId', 2); this.throwIfInvalidInt(cmpVersion, 'cmpVersion', 0); CmpApiModel.cmpId = cmpId; CmpApiModel.cmpVersion = cmpVersion; CmpApiModel.tcfPolicyVersion = 5; this.isServiceSpecific = !!isServiceSpecific; this.callResponder = new CallResponder(customCommands); } throwIfInvalidInt(value, name, minValue) { if (!(typeof value === 'number' && Number.isInteger(value) && value >= minValue)) { throw new Error(`Invalid ${name}: ${value}`); } } /** * update - When the state of a CMP changes this function should be called * with the updated tc string and whether or not the UI is visible or not * * @param {string|null} encodedTCString - set a string to signal that * gdprApplies and that an encoded tc string is being passed. If GDPR does * not apply, set to null. * @param {boolean} uiVisible - default false. set to true if the ui is * being shown with this tc string update, this will set the correct values * for eventStatus and displayStatus. * @return {void} */ update(encodedTCString, uiVisible = false) { if (CmpApiModel.disabled) { throw new Error('CmpApi Disabled'); } CmpApiModel.cmpStatus = CmpStatus.LOADED; if (uiVisible) { CmpApiModel.displayStatus = DisplayStatus.VISIBLE; CmpApiModel.eventStatus = EventStatus.CMP_UI_SHOWN; } else { if (CmpApiModel.tcModel === undefined) { CmpApiModel.displayStatus = DisplayStatus.DISABLED; CmpApiModel.eventStatus = EventStatus.TC_LOADED; } else { CmpApiModel.displayStatus = DisplayStatus.HIDDEN; CmpApiModel.eventStatus = EventStatus.USER_ACTION_COMPLETE; } } CmpApiModel.gdprApplies = (encodedTCString !== null); if (!CmpApiModel.gdprApplies) { CmpApiModel.tcModel = null; } else { if (encodedTCString === '') { CmpApiModel.tcModel = new TCModel(); CmpApiModel.tcModel.cmpId = CmpApiModel.cmpId; CmpApiModel.tcModel.cmpVersion = CmpApiModel.cmpVersion; } else { CmpApiModel.tcModel = TCString.decode(encodedTCString); } CmpApiModel.tcModel.isServiceSpecific = this.isServiceSpecific; CmpApiModel.tcfPolicyVersion = Number(CmpApiModel.tcModel.policyVersion); CmpApiModel.tcString = encodedTCString; } if (this.numUpdates === 0) { /** * Will make AddEventListener Commands respond immediately. */ this.callResponder.purgeQueuedCalls(); } else { /** * Should be no queued calls and only any addEventListener commands */ CmpApiModel.eventQueue.exec(); } this.numUpdates++; } /** * Disables the CmpApi from serving anything but ping and custom commands * Cannot be undone * * @return {void} */ disable() { CmpApiModel.disabled = true; CmpApiModel.cmpStatus = CmpStatus.ERROR; } }