UNPKG

@scaleway/use-analytics

Version:

A small hook to handle events analytics

157 lines (156 loc) 5.17 kB
"use strict"; Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }); const jsxRuntime = require("react/jsx-runtime"); const cookie = require("cookie"); const react = require("react"); const useDestinations = require("../analytics/useDestinations.cjs"); const constants = require("../constants.cjs"); const array = require("../helpers/array.cjs"); const isClient = require("../helpers/isClient.cjs"); const misc = require("../helpers/misc.cjs"); const types = require("../types.cjs"); const CookieConsentContext = react.createContext(void 0); const useCookieConsent = () => { const context = react.useContext(CookieConsentContext); if (context === void 0) { throw new Error( "useCookieConsent must be used within a CookieConsentProvider" ); } return context; }; const CookieConsentProvider = ({ children, isConsentRequired, manualDestinations, config, cookiePrefix = constants.COOKIE_PREFIX, consentMaxAge = constants.CONSENT_MAX_AGE, consentAdvertisingMaxAge = constants.CONSENT_ADVERTISING_MAX_AGE, cookiesOptions = constants.COOKIES_OPTIONS }) => { const [needConsent, setNeedsConsent] = react.useState(false); const [cookies, setCookies] = react.useState( isClient.IS_CLIENT ? cookie.parse(document.cookie) : {} ); const { destinations: analyticsDestinations, isLoaded: isDestinationsLoaded } = useDestinations.useDestinations(config); const destinations = react.useMemo( () => array.uniq([ ...(analyticsDestinations ?? []).map( (dest) => ({ category: dest.consents[0] ?? "essential", displayName: dest.displayName, name: dest.name }) ), ...manualDestinations ?? [] ]), [analyticsDestinations, manualDestinations] ); const destinationsHash = react.useMemo( () => misc.stringToHash( array.uniq(destinations.map(({ name }) => name)).sort().join(void 0) ), [destinations] ); react.useEffect(() => { setNeedsConsent( isConsentRequired && cookies[constants.HASH_COOKIE] !== destinationsHash.toString() && analyticsDestinations !== void 0 ); }, [isConsentRequired, destinationsHash, analyticsDestinations, cookies]); const cookieConsent = react.useMemo( () => constants.CATEGORIES.reduce( (acc, category) => ({ ...acc, [category]: isConsentRequired || needConsent ? cookies[`${cookiePrefix}_${category}`] === "true" : true }), {} ), [isConsentRequired, cookiePrefix, needConsent, cookies] ); const saveConsent = react.useCallback( (categoriesConsent) => { for (const [consentName, consentValue] of Object.entries( categoriesConsent )) { const consentCategoryName = types.isCategoryKind(consentName) ? consentName : "unknown"; const cookieName = `${cookiePrefix}_${consentCategoryName}`; if (!consentValue) { document.cookie = cookie.serialize(cookieName, "", { ...cookiesOptions, expires: /* @__PURE__ */ new Date(0) }); } else { document.cookie = cookie.serialize(cookieName, consentValue.toString(), { ...cookiesOptions, maxAge: consentCategoryName === "advertising" ? consentAdvertisingMaxAge : consentMaxAge }); } setCookies((prevCookies) => ({ ...prevCookies, [cookieName]: consentValue ? "true" : "false" })); } document.cookie = cookie.serialize(constants.HASH_COOKIE, destinationsHash.toString(), { ...cookiesOptions, // Here we use the shortest max age to force to ask again for expired consent maxAge: consentAdvertisingMaxAge }); setCookies((prevCookies) => ({ ...prevCookies, [constants.HASH_COOKIE]: destinationsHash.toString() })); setNeedsConsent(false); }, [ destinationsHash, consentAdvertisingMaxAge, consentMaxAge, cookiePrefix, cookiesOptions ] ); const allowedConsents = react.useMemo( () => Object.keys(cookieConsent).filter( // oxlint-disable-next-line @typescript-eslint/no-unsafe-type-assertion (key) => !cookieConsent[key] ), [cookieConsent] ); const deniedConsents = react.useMemo( () => Object.keys(cookieConsent).filter( // oxlint-disable-next-line @typescript-eslint/no-unsafe-type-assertion (key) => !allowedConsents.includes(key) ), [cookieConsent, allowedConsents] ); const value = react.useMemo( () => ({ allowedConsents, categories: constants.CATEGORIES, categoriesConsent: cookieConsent, cookies, deniedConsents, destinations, isDestinationsLoaded, needConsent, saveConsent }), [ destinations, isDestinationsLoaded, needConsent, allowedConsents, deniedConsents, cookieConsent, saveConsent, cookies ] ); return /* @__PURE__ */ jsxRuntime.jsx(CookieConsentContext.Provider, { value, children }); }; exports.CookieConsentProvider = CookieConsentProvider; exports.useCookieConsent = useCookieConsent;