@afex-dapps/cookie
Version:
Cookie Consent library for React
551 lines (522 loc) • 17.7 kB
JavaScript
;Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } }var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp.call(b, prop))
__defNormalProp(a, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a, prop, b[prop]);
}
return a;
};
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
var __objRest = (source, exclude) => {
var target = {};
for (var prop in source)
if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
target[prop] = source[prop];
if (source != null && __getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(source)) {
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
target[prop] = source[prop];
}
return target;
};
var __async = (__this, __arguments, generator) => {
return new Promise((resolve, reject) => {
var fulfilled = (value) => {
try {
step(generator.next(value));
} catch (e) {
reject(e);
}
};
var rejected = (value) => {
try {
step(generator.throw(value));
} catch (e) {
reject(e);
}
};
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
step((generator = generator.apply(__this, __arguments)).next());
});
};
// src/constants/attributes.ts
var cookieConsentAttributes = {
/**
* @description
* Use this value to accept all cookie categories.
*
* @example
*
* ```html
* <button type="button" data-cc="accept-all">Accept all categories</button>
* <a href="#" data-cc={cookieConsentAttributes.acceptAll}>Accept all categories</a>
* ```
*/
acceptAll: "accept-all",
/**
* @description
* Use this value to accept the current selection inside the preferences modal.
*
* @example
*
* ```html
* <button type="button" data-cc="accept-custom">Accept selection</button>
* <a href="#" data-cc={cookieConsentAttributes.acceptCustom}>Accept selection</a>
* ```
*/
acceptCustom: "accept-custom",
/**
* @description
* Use this value to accept only the necessary cookie categories.
*
* @example
*
* ```html
* <button type="button" data-cc="accept-necessary">Reject all categories</button>
* <a href="#" data-cc={cookieConsentAttributes.acceptNecessary}>Reject all categories</a>
* ```
*/
acceptNecessary: "accept-necessary",
/**
* @description
* Use this value to show the consentModal. If the consent modal does not exist, it will be generated on the fly.
*
* @example
*
* ```html
* <button type="button" data-cc="show-consentModal">View Consent Modal</button>
* <a href="#" data-cc={cookieConsentAttributes.showConsentModal}>View Consent Modal</a>
* ```
*/
showConsentModal: "show-consentModal",
/**
* @description
* Use this value to show the preferencesModal.
*
* @example
*
* ```html
* <button type="button" data-cc="show-preferencesModal">View Preferences Modal</button>
* <a href="#" data-cc={cookieConsentAttributes.showPreferencesModal}>View Preferences Modal</a>
* ```
*/
showPreferencesModal: "show-preferencesModal"
};
// src/constants/events.ts
var cookieConsentEvents = {
/**
* @description
* This event is triggered when the user modifies their preferences and only if consent has already been provided.
*
* @example
*
* ```js
* cookieConsentEvents.onChange // "cc:onChange"
* window.addEventListener('cc:onChange', ({ detail }) => {
* // detail.cookie
* // detail.changedCategories
* // detail.changedServices
* });
* ```
*/
onChange: "cc:onChange",
/**
* @description
* This event is triggered the very first time the user expresses their choice of consent — just like onFirstConsent — but also on every subsequent page load.
*
* @example
*
* ```js
* cookieConsentEvents.onConsent // "cc:onConsent"
* window.addEventListener('cc:onConsent', ({ detail }) => {
* // detail.cookie
* });
* ```
*/
onConsent: "cc:onConsent",
/**
* @description
* This event is triggered only the very first time that the user expresses their choice of consent (accept/reject).
*
* @example
*
* ```js
* cookieConsentEvents.onFirstConsent // "cc:onFirstConsent"
* window.addEventListener('cc:onFirstConsent', ({ detail }) => {
* // detail.cookie
* });
* ```
*/
onFirstConsent: "cc:onFirstConsent",
/**
* @description
* This event is triggered when one of the modals is hidden.
*
* @example
*
* ```js
* cookieConsentEvents.onModalHide // "cc:onModalHide"
* window.addEventListener('cc:onModalHide', ({ detail }) => {
* // detail.modalName
* });
* ```
*/
onModalHide: "cc:onModalHide",
/**
* @description
* This event is triggered when a modal is created and appended to the DOM.
*
* @example
*
* ```js
* cookieConsentEvents.onModalReady // "cc:onModalReady"
* window.addEventListener('cc:onModalReady', ({ detail }) => {
* // detail.modalName
* // detail.modal
* });
* ```
*/
onModalReady: "cc:onModalReady",
/**
* @description
* This event is triggered when one of the modals is visible.
*
* @example
*
* ```js
* cookieConsentEvents.onModalShow // "cc:onModalShow"
* window.addEventListener('cc:onModalShow', ({ detail }) => {
* // detail.modalName
* });
* ```
*/
onModalShow: "cc:onModalShow"
};
// src/helpers/is-dictionary/index.ts
function isDictionary(value) {
return Object.prototype.toString.call(value) === "[object Object]";
}
// src/helpers/is-valid-key/index.ts
function isValidKey(key) {
return key !== "__proto__" && key !== "constructor" && key !== "prototype";
}
// src/helpers/is-object/index.ts
function isObject(value) {
return value !== null && typeof value === "object";
}
// src/functions/clone-deep/index.ts
function cloneDeep(value, visited = /* @__PURE__ */ new WeakMap()) {
if (!isObject(value)) return value;
if (visited.has(value)) return visited.get(value);
if (value instanceof Date) {
return new Date(value.getTime());
}
if (value instanceof RegExp) {
return new RegExp(value.source, value.flags);
}
if (Array.isArray(value)) {
const clone = [];
visited.set(value, clone);
value.forEach((item, index) => {
clone[index] = cloneDeep(item, visited);
});
return clone;
}
if (isDictionary(value)) {
const result = Object.create(
Object.getPrototypeOf(value),
Object.getOwnPropertyDescriptors(value)
);
visited.set(value, result);
Reflect.ownKeys(result).forEach((key) => {
if (isValidKey(key) && Reflect.has(result, key)) {
const clone = cloneDeep(Reflect.get(result, key), visited);
Reflect.set(result, key, clone);
}
});
return result;
}
return value;
}
// src/functions/deep-merge/index.ts
function deepMerge(target, ...sources) {
return deepMergeInternal(target, sources, /* @__PURE__ */ new WeakMap());
}
function deepMergeInternal(target, sources, visited) {
if (!sources.length || sources.every((source) => !source)) {
return cloneDeep(target, visited);
}
if (isObject(target) && visited.has(target)) {
return visited.get(target);
}
const result = cloneDeep(target, visited);
if (isObject(target)) visited.set(target, result);
for (const source of sources) {
if (!source) continue;
for (const key of Reflect.ownKeys(source)) {
if (!isValidKey(key)) continue;
const targetValue = result[key];
const sourceValue = Reflect.get(source, key);
if (sourceValue === void 0) continue;
if (isObject(sourceValue) && visited.has(sourceValue)) {
Reflect.set(result, key, visited.get(sourceValue));
continue;
}
if (isDictionary(targetValue) && isDictionary(sourceValue)) {
Reflect.set(
result,
key,
deepMergeInternal(targetValue, [sourceValue], visited)
);
continue;
}
Reflect.set(result, key, cloneDeep(sourceValue, visited));
}
}
return result;
}
// src/constants/configuration.ts
var defaultConfiguration = {
autoClearCookies: true,
autoShow: false,
categories: {
analytics: {
enabled: true,
readOnly: false
},
necessary: {
enabled: true,
readOnly: true
}
},
cookie: {
expiresAfterDays: 180,
name: "_cc-cookie",
path: "/",
sameSite: "Strict",
secure: true,
useLocalStorage: false
},
disablePageInteraction: false,
hideFromBots: true,
language: {
autoDetect: "browser",
default: "en",
rtl: "ar",
translations: {
en: {
consentModal: {
acceptAllBtn: "Accept all",
acceptNecessaryBtn: "Reject all",
description: "Our site uses scripts (e.g. cookies) to collect and store data such as personal identifiers (IP address, session details) and browsing activity. This helps us deliver content, ensure security, enhance user experience, and support marketing. You can reject non-essential cookies or adjust your preferences by clicking here.",
showPreferencesBtn: "Manage Individual preferences",
title: "Cookie preferences"
},
preferencesModal: {
acceptAllBtn: "Accept all",
acceptNecessaryBtn: "Reject all",
closeIconLabel: "Close modal",
savePreferencesBtn: "Accept current selection",
sections: [],
title: "Manage cookie preferences"
}
}
}
},
manageScriptTags: true
};
// src/functions/create-cookie-configuration/index.ts
function createCookieConfiguration(options) {
return deepMerge(defaultConfiguration, options);
}
// src/functions/create-cookie-styles/index.ts
function createCookieStyles(styles) {
return styles;
}
// src/functions/css/index.ts
function css(variable) {
return `var(${variable})`;
}
// src/hooks/use-cookie-banner.ts
var _vanillacookieconsent = require('vanilla-cookieconsent'); var CookieConsent2 = _interopRequireWildcard(_vanillacookieconsent); var CookieConsent = _interopRequireWildcard(_vanillacookieconsent);
var _react = require('react');
// src/hooks/use-cookie-styles.ts
// src/functions/serialize-cookie-styles/index.ts
var _serialize = require('@emotion/serialize');
function serializeCookieStyles(styles) {
return _serialize.serializeStyles.call(void 0, [styles]).styles;
}
// src/hooks/use-cookie-styles.ts
var useIsomorphicLayoutEffect = typeof window !== "undefined" ? _react.useLayoutEffect : _react.useEffect;
function useCookieStyles(activeTheme = "light", styles) {
_react.useInsertionEffect.call(void 0, () => {
if (!styles) return;
const style = document.createElement("style");
style.innerHTML = serializeCookieStyles(styles);
document.head.insertAdjacentHTML("beforeend", style.outerHTML);
}, [styles]);
useIsomorphicLayoutEffect(() => {
if (!activeTheme) return;
const variants = { dark: "cc--darkmode", light: "default-light" };
const classes = document.documentElement.classList;
const theme = variants[activeTheme];
classes.toggle(theme, true);
}, [activeTheme]);
}
// src/functions/firebase/index.ts
var _app = require('firebase/app');
var _lite = require('firebase/firestore/lite');
function useSetupFirebase(firebaseConfig = { collectionName: "AFEX" }) {
const { collectionName, projectId } = firebaseConfig;
const app = _react.useMemo.call(void 0, () => {
if (!projectId) return null;
try {
return _app.initializeApp.call(void 0, firebaseConfig);
} catch (error) {
console.error("Failed to initialize Firebase:", error);
return null;
}
}, [firebaseConfig]);
const db = _react.useMemo.call(void 0, () => {
if (!app) return null;
return _lite.getFirestore.call(void 0, app);
}, [app]);
const updateUserCookieData = _react.useCallback.call(void 0,
(_0, ..._1) => __async(null, [_0, ..._1], function* (data, documentId = data.userId, onError) {
if (!collectionName || !documentId || !db) return null;
if (data.userId !== documentId) {
CookieConsent.setCookieData({
mode: "update",
value: { userId: data.userId }
});
}
try {
const cookieSettingsRef = _lite.collection.call(void 0, db, collectionName);
const newDocRef = _lite.doc.call(void 0, cookieSettingsRef, documentId);
yield _lite.setDoc.call(void 0, newDocRef, data);
return newDocRef.id;
} catch (error) {
onError == null ? void 0 : onError(error);
return null;
}
}),
[collectionName, db]
);
const retrieveUserCookieData = _react.useCallback.call(void 0,
(documentId, onError) => __async(null, null, function* () {
if (!collectionName || !documentId || !db) return null;
try {
const cookieSettingsRef = _lite.collection.call(void 0, db, collectionName);
const docRef = _lite.doc.call(void 0, cookieSettingsRef, documentId);
const docSnapshot = yield _lite.getDoc.call(void 0, docRef);
if (!docSnapshot.exists()) return null;
return __spreadValues({ id: docSnapshot.id }, docSnapshot.data());
} catch (error) {
onError == null ? void 0 : onError(error);
return null;
}
}),
[collectionName, db]
);
return { retrieveUserCookieData, updateUserCookieData };
}
// src/hooks/use-unique-user-id/index.ts
var _uuid = require('uuid');
function useUniqueUserId() {
const [userId, setUserId] = _react.useState.call(void 0, () => _uuid.v4.call(void 0, ));
_react.useEffect.call(void 0, () => {
try {
const userInfo = {
browser: navigator.userAgent,
location: document.location.origin,
referrer: document.referrer,
screen_height: screen.height,
screen_width: screen.width
};
const userInfoString = Object.values(userInfo).join("|");
const clientSpecificId = _uuid.v5.call(void 0, userInfoString, _uuid.v5.URL);
setUserId(clientSpecificId);
} catch (error) {
console.error("Error generating client-specific unique user ID; will use initial random UUID:", error);
}
}, []);
return userId;
}
// src/hooks/use-cookie-banner.ts
function useCookieBanner({
activeTheme = "light",
configuration,
delay = 1e3,
firebase,
styles
} = {}) {
const userId = useUniqueUserId();
const _a = _react.useMemo.call(void 0, () => {
return deepMerge(
defaultConfiguration,
configuration
);
}, [configuration]), { onChange, onFirstConsent } = _a, options = __objRest(_a, ["onChange", "onFirstConsent"]);
const { retrieveUserCookieData, updateUserCookieData } = useSetupFirebase(firebase);
const logConsent = _react.useCallback.call(void 0, () => {
const cookie = CookieConsent2.getCookie();
const preferences = CookieConsent2.getUserPreferences();
if (firebase == null ? void 0 : firebase.apiKey) {
updateUserCookieData({
cookie,
language: options.language.default,
preferences,
userId
});
}
}, [
firebase == null ? void 0 : firebase.apiKey,
options.language.default,
updateUserCookieData,
userId
]);
const updateUserId = _react.useCallback.call(void 0,
(newUserId, onError) => __async(null, null, function* () {
if (firebase == null ? void 0 : firebase.apiKey) {
yield updateUserCookieData({ userId: newUserId }, userId, onError);
}
}),
[firebase == null ? void 0 : firebase.apiKey, userId, updateUserCookieData]
);
_react.useEffect.call(void 0, () => {
CookieConsent2.run(__spreadProps(__spreadValues({}, options), {
onChange: (param) => {
logConsent();
onChange == null ? void 0 : onChange(param);
},
onFirstConsent: (param) => {
logConsent();
onFirstConsent == null ? void 0 : onFirstConsent(param);
}
}));
const timeoutId = setTimeout(CookieConsent2.show, delay);
return () => {
clearTimeout(timeoutId);
};
}, [options, delay, logConsent, onFirstConsent, onChange]);
_react.useEffect.call(void 0, () => {
CookieConsent2.setCookieData({
mode: "update",
value: { userId }
});
}, [userId]);
useCookieStyles(activeTheme, styles);
return { retrieveUserCookieData, updateUserCookieData, updateUserId, userId };
}
exports.cookieConsentAttributes = cookieConsentAttributes; exports.cookieConsentEvents = cookieConsentEvents; exports.createCookieConfiguration = createCookieConfiguration; exports.createCookieStyles = createCookieStyles; exports.css = css; exports.useCookieBanner = useCookieBanner;
//# sourceMappingURL=index.cjs.map