{"version":3,"file":"ui.mjs","names":[],"sources":["../src/ui.ts"],"sourcesContent":["import type {\n  ConsentManagerSupportedTranslationValue,\n  LocaleValue,\n} from '@transcend-io/internationalization';\n// main\nimport { applyEnum, type ObjByString, valuesOf } from '@transcend-io/type-utils';\n// external\nimport * as t from 'io-ts';\n\nimport { BooleanString, type AirgapAuth, type AirgapAuthMap } from './core.js';\n// local\nimport {\n  ViewState,\n  InitialTranscendViewState,\n  InitialViewState,\n  PrivacyRegimeEnum,\n  DismissedViewState,\n} from './enums/index.js';\nimport { NonTcfVendor } from './iab.js';\n\n/** Transcend Smart Quarantine API (window.transcend) */\nexport type PreInitTranscendAPI = {\n  /** Ready event subscriber */\n  ready(callback: (transcend: TranscendAPI) => void): void;\n  /** Ready event dispatch queue */\n  readyQueue: ((transcend: TranscendAPI) => void)[];\n};\n\n/** showConsentManager() */\nexport interface ShowConsentManagerOptions {\n  /** View state */\n  viewState?: ViewState;\n}\n\n/**\n * Input for fetching a policy from Transcend and inserting template variables\n */\nexport type GetTranscendPolicies = {\n  /** The language to fetch policy for - defaults to currently selected language key */\n  locale?: LocaleValue;\n  /** Template variables to dynamically inject into the policy */\n  variables?: ObjByString;\n  /**\n   * The UUID of the policies defined in Transcend to fetch\n   *\n   * This can be pulled from the URL\n   * @see https://app.transcend.io/privacy-center/policies\n   */\n  policyIds?: string[];\n  /**\n   * The titles of the policies defined in Transcend to fetch\n   *\n   * This can be pulled from the URL\n   * @see https://app.transcend.io/privacy-center/policies\n   */\n  policyTitles?: string[];\n};\n\n/**\n * The returning Transcend policy\n */\nexport type TranscendPolicy = {\n  /** The policy UUID */\n  id: string;\n  /** The policy title */\n  title: string;\n  /** The policy content */\n  content: string;\n};\n\n/**\n * Transcend Consent Manager external methods\n */\nexport type ConsentManagerAPI = Readonly<{\n  /** Possible ViewState values */\n  viewStates: Set<ViewState>;\n  /** Expose an option to grab the current view state */\n  getViewState: () => ViewState;\n  /** Get the current active language */\n  getPolicies: (input?: GetTranscendPolicies) => Promise<TranscendPolicy[]>;\n  /** Callback that sets any dynamic variables that should be exposed to the consent UI messages */\n  setUiVariables: (variables: ObjByString) => Promise<void>;\n  /** Get the current value of Transcend UI variables */\n  getUiVariables: () => ObjByString;\n  /** Set consent change authorization key */\n  setAuth?: (key: AirgapAuthMap['key']) => void;\n  /** Change the current privacy policy URL */\n  setPrivacyPolicy: (privacyPolicyLink: string) => void;\n  /** Change the current secondary policy URL */\n  setSecondaryPolicy: (privacyPolicyLink: string) => void;\n  /** Show consent manager unless recently dismissed */\n  autoShowConsentManager(options?: ShowConsentManagerOptions): Promise<void>;\n  /** Show consent manager */\n  showConsentManager(options?: ShowConsentManagerOptions): Promise<void>;\n  /** Set the current active language */\n  setActiveLocale(locale: ConsentManagerSupportedTranslationValue): Promise<void>;\n  /** Get the currently active locale */\n  getActiveLocale: () => ConsentManagerSupportedTranslationValue;\n  /** Toggle consent manager */\n  toggleConsentManager(options?: ShowConsentManagerOptions): Promise<void>;\n  /** Hide consent manager */\n  hideConsentManager(): Promise<void>;\n  /** Opt out of the sale of personal info & show a disclosure */\n  doNotSell(auth: AirgapAuth, options?: ShowConsentManagerOptions): Promise<void>;\n  /** Opt out of all purposes */\n  optOutNotice(auth: AirgapAuth, options?: ShowConsentManagerOptions): Promise<void>;\n  /** Sets local tcf string (does not sync to xdi or preference store) */\n  setTCFConsent?: (auth: AirgapAuth, tcString: string) => Promise<void>;\n  /** UI version */\n  version?: string;\n}> &\n  EventTarget;\n\n/**\n * `transcend` event types\n */\nexport type TranscendEventType = 'view-state-change';\n\n/** 'view-state-change' custom event details */\nexport type ViewStateEventDetails = {\n  /** The new, now-current view state */\n  viewState: ViewState;\n  /** The previous view state */\n  previousViewState: ViewState | null;\n};\n\n/** Transcend Smart Quarantine API (window.transcend) */\nexport type TranscendAPI = PreInitTranscendAPI & ConsentManagerAPI;\n\n/**\n * Customer theming\n */\nexport const ConsentManagerTheme = t.type({\n  /** Primary color */\n  primaryColor: t.string,\n  /** Font color */\n  fontColor: t.string,\n});\n\n/** Type override */\nexport type ConsentManagerTheme = t.TypeOf<typeof ConsentManagerTheme>;\n\n/**\n * Mobile-first responsive breakpoints\n * No media query for mobile, which is the default\n */\nexport const ConsentManagerBreakpoints = t.type({\n  /** In px, at or above this width is tablet */\n  tablet: t.string,\n  /** In px, at or above this width is desktop */\n  desktop: t.string,\n});\n\n/** Type override */\nexport type ConsentManagerBreakpoints = t.TypeOf<typeof ConsentManagerBreakpoints>;\n\n/**\n * TODO: https://transcend.height.app/T-19149 - remove\n * @deprecated\n */\nexport const PrivacyRegimeToInitialViewStateInput = t.partial(\n  applyEnum(PrivacyRegimeEnum, () => valuesOf(InitialTranscendViewState)),\n);\n\n/**\n * TODO: https://transcend.height.app/T-19149 - remove\n * @deprecated\n */\nexport type PrivacyRegimeToInitialViewStateInput = t.TypeOf<\n  typeof PrivacyRegimeToInitialViewStateInput\n>;\n\n/**\n * TODO: https://transcend.height.app/T-19149 - remove\n * @deprecated\n */\nexport const PrivacyRegimeToInitialViewState = t.record(\n  valuesOf(PrivacyRegimeEnum),\n  valuesOf(InitialTranscendViewState),\n);\n\n/**\n * TODO: https://transcend.height.app/T-19149 - remove\n * @deprecated\n */\nexport type PrivacyRegimeToInitialViewState = t.TypeOf<typeof PrivacyRegimeToInitialViewState>;\n\nexport const ExperienceToInitialViewState = t.record(t.string, valuesOf(InitialViewState));\n\n/** type overload */\nexport type ExperienceToInitialViewState = t.TypeOf<typeof ExperienceToInitialViewState>;\n\nexport const RequiredConsentManagerConfig = t.type({\n  /** Customer theming */\n  theme: ConsentManagerTheme,\n  /** A set of responsive breakpoints */\n  breakpoints: ConsentManagerBreakpoints,\n  /** The privacy policy URL to redirect to */\n  privacyPolicy: t.string,\n  /** The secondary policy URL to redirect to */\n  secondaryPolicy: t.string,\n  /** Custom CSS stylesheet */\n  css: t.string,\n  /** Path to localizations directory */\n  messages: t.string,\n  /** What state the consent manager should launch in */\n  initialViewStateByPrivacyRegime: ExperienceToInitialViewState,\n  /** What state the consent manager should go to when dismissed */\n  dismissedViewState: valuesOf(DismissedViewState),\n});\n\n/** type overload */\nexport type RequiredConsentManagerConfig = t.TypeOf<typeof RequiredConsentManagerConfig>;\n\nexport const OptionalConsentManagerConfig = t.partial({\n  /** The set of enabled languages - CSV of ConsentManagerSupportedTranslationValue */\n  languages: t.string,\n  /** The override value for the consent banner z-index */\n  uiZIndex: t.string,\n  /**\n   * The override value for the consent banner shadow root state\n   *\n   * Potential values: 'closed' (default) and 'open'\n   */\n  uiShadowRoot: t.string,\n  /**\n   * The override value for whether to focus on the first descendant of the root arg w/data-initialFocus attribute\n   * Potential values: `'on'` (default) or `'off'`\n   *\n   */\n  autofocus: BooleanString,\n});\n\n/** type overload */\nexport type OptionalConsentManagerConfig = t.TypeOf<typeof OptionalConsentManagerConfig>;\n\n/** Consent manager UI configuration */\nexport const ConsentManagerConfig = t.intersection([\n  RequiredConsentManagerConfig,\n  OptionalConsentManagerConfig,\n]);\n\n/** Type override */\nexport type ConsentManagerConfig = t.TypeOf<typeof ConsentManagerConfig>;\n\n/** Input for Consent manager UI configuration */\nexport const ConsentManagerConfigInput = t.partial({\n  ...OptionalConsentManagerConfig.props,\n  ...RequiredConsentManagerConfig.props,\n});\n\n/** Type override */\nexport type ConsentManagerConfigInput = t.TypeOf<typeof ConsentManagerConfigInput>;\n\nexport const TCFConfig = t.type({\n  /** Path to vendor-list.json */\n  vendorList: t.string,\n  /** Custom CSS stylesheet */\n  css: t.string,\n  /** Path to localizations directory */\n  messages: t.string,\n});\n\n/** Type override */\nexport type TCFConfig = t.TypeOf<typeof TCFConfig>;\n\n/** Configuration that are passed directly to the TCF module, not via airgap.j */\nexport const TCFBundledDataConfig = t.partial({\n  /** Mapping of TCF Purpose ID to airgap tracking types */\n  purposeMap: t.array(t.tuple([t.number, t.array(t.string)])),\n  /** These TCF purposes cannot be processed on the basis of legitimate interests */\n  restrictLegitimateInterestPurposes: t.array(t.number),\n  /** Vendors that Transcend Consent regulates because they haven't registered with IAB TCF */\n  nonTcfVendors: t.array(NonTcfVendor),\n  /** Comma separated list of languages to support in the UI */\n  languages: t.string,\n  /** Default locale to use for the UI internationalization  */\n  locale: t.string,\n  /**\n   * Whether or not to enable integration between Google Consent Mode and TCF.\n   * More docs here https://developers.google.com/tag-platform/security/guides/implement-TCF-strings#cmp-api\n   */\n  enableAdvertiserConsentMode: t.boolean,\n});\n\n/** Type override */\nexport type TCFBundledDataConfig = t.TypeOf<typeof TCFBundledDataConfig>;\n\n/** Input for Consent manager UI configuration */\nexport const TCFConfigInput = t.partial(TCFConfig.props);\n\n/** Type override */\nexport type TCFConfigInput = t.TypeOf<typeof TCFConfigInput>;\n\n/**\n * Properties exposed on `self` by the Transcend Smart Quarantine\n */\nexport type TranscendView = Window & {\n  /** Transcend Smart Quarantine API */\n  transcend: TranscendAPI;\n};\n\nexport const DEFAULT_VIEW_STATE_BY_PRIVACY_REGIME: ExperienceToInitialViewState = {\n  // EU\n  GDPR: InitialViewState.QuickOptions,\n  // Brazil\n  LGPD: InitialViewState.QuickOptions,\n  // Switzerland\n  nFADP: InitialViewState.QuickOptions,\n  // US: California\n  CPRA: InitialViewState.Hidden,\n  // US: Virginia\n  CDPA: InitialViewState.Hidden,\n  // US: Colorado\n  CPA: InitialViewState.Hidden,\n  // US: Nevada\n  NEVADA_SB220: InitialViewState.Hidden,\n  // Other\n  Unknown: InitialViewState.Hidden,\n  // US Do Not Sell/Share\n  US_DNSS: InitialViewState.Hidden,\n};\n"],"mappings":";;;;;;;;;;AAoIA,MAAa,sBAAsB,EAAE,KAAK;CAExC,cAAc,EAAE;CAEhB,WAAW,EAAE;CACd,CAAC;;;;;AASF,MAAa,4BAA4B,EAAE,KAAK;CAE9C,QAAQ,EAAE;CAEV,SAAS,EAAE;CACZ,CAAC;;;;;AASF,MAAa,uCAAuC,EAAE,QACpD,UAAU,yBAAyB,SAAS,0BAA0B,CAAC,CACxE;;;;;AAcD,MAAa,kCAAkC,EAAE,OAC/C,SAAS,kBAAkB,EAC3B,SAAS,0BAA0B,CACpC;AAQD,MAAa,+BAA+B,EAAE,OAAO,EAAE,QAAQ,SAAS,iBAAiB,CAAC;AAK1F,MAAa,+BAA+B,EAAE,KAAK;CAEjD,OAAO;CAEP,aAAa;CAEb,eAAe,EAAE;CAEjB,iBAAiB,EAAE;CAEnB,KAAK,EAAE;CAEP,UAAU,EAAE;CAEZ,iCAAiC;CAEjC,oBAAoB,SAAS,mBAAmB;CACjD,CAAC;AAKF,MAAa,+BAA+B,EAAE,QAAQ;CAEpD,WAAW,EAAE;CAEb,UAAU,EAAE;CAMZ,cAAc,EAAE;CAMhB,WAAW;CACZ,CAAC;;AAMF,MAAa,uBAAuB,EAAE,aAAa,CACjD,8BACA,6BACD,CAAC;;AAMF,MAAa,4BAA4B,EAAE,QAAQ;CACjD,GAAG,6BAA6B;CAChC,GAAG,6BAA6B;CACjC,CAAC;AAKF,MAAa,YAAY,EAAE,KAAK;CAE9B,YAAY,EAAE;CAEd,KAAK,EAAE;CAEP,UAAU,EAAE;CACb,CAAC;;AAMF,MAAa,uBAAuB,EAAE,QAAQ;CAE5C,YAAY,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CAE3D,oCAAoC,EAAE,MAAM,EAAE,OAAO;CAErD,eAAe,EAAE,MAAM,aAAa;CAEpC,WAAW,EAAE;CAEb,QAAQ,EAAE;CAKV,6BAA6B,EAAE;CAChC,CAAC;;AAMF,MAAa,iBAAiB,EAAE,QAAQ,UAAU,MAAM;AAaxD,MAAa,uCAAqE;CAEhF,MAAM,iBAAiB;CAEvB,MAAM,iBAAiB;CAEvB,OAAO,iBAAiB;CAExB,MAAM,iBAAiB;CAEvB,MAAM,iBAAiB;CAEvB,KAAK,iBAAiB;CAEtB,cAAc,iBAAiB;CAE/B,SAAS,iBAAiB;CAE1B,SAAS,iBAAiB;CAC3B"}