Created
November 30, 2022 05:35
-
-
Save dobesv/5bb7d83e1380560042b0f53b9978b697 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import storage, { | |
AnalyticsStorage, | |
ANY, | |
GLOBAL, | |
} from '@analytics/storage-utils'; | |
export interface ConsentAwareStorage extends AnalyticsStorage { | |
getConsent(): boolean; | |
setConsent(newValue: boolean): void; | |
} | |
export default function createConsentAwareStorage( | |
initialConsent: boolean = false, | |
): ConsentAwareStorage { | |
/** | |
* Storage parameter for setItem calls. getItem and removeItem always use | |
* `ALL`. | |
*/ | |
let storageMode: 'global' | 'any' = initialConsent ? ANY : GLOBAL; | |
/** | |
* Track the keys we have see so we know what to migrate/remove in | |
* case consent status changes. | |
*/ | |
const keys: Set<string> = new Set(); | |
/** | |
* Call to set the current persistent consent state. Note that consent is OFF by default. | |
* | |
* @param newValue true if the user consents to storing analytics tracking cookies | |
*/ | |
const setConsent = (newValue: boolean): void => { | |
const newStorageMode = newValue ? ANY : GLOBAL; | |
const oldStorageMode = storageMode; | |
if (oldStorageMode !== newStorageMode) { | |
storageMode = newStorageMode; | |
// Move keys to the new storage location | |
for (const key of keys) { | |
const removed = storage.removeItem(key); | |
const oldValue = Object.values(removed)[0]; | |
if (typeof oldValue !== 'undefined') { | |
storage.setItem(key, oldValue, { storage: newStorageMode }); | |
} | |
} | |
} | |
}; | |
/** | |
* Return the current consent status. | |
*/ | |
const getConsent = (): boolean => { | |
return storageMode === ANY; | |
}; | |
/** | |
* Store an item into storage. | |
* | |
* If the user has given consent and no explicit storage option is provided, this is stored into | |
* localStorage, cookies, or session storage based on what's available. If there is no consent | |
* or none of those storage methods are allowed by the browser it stores it into a global variable. | |
* | |
* When storing to localStorage or sessionStorage the value will be serialized | |
* using JSON.stringify, so only objects compatible with that serialization | |
* method should be used. | |
* | |
* @param key Key to store to | |
* @param value Value - this will be serialized to JSON | |
* @param options If provided this can override the default storage mode | |
*/ | |
const setItem = ( | |
key: string, | |
value: unknown, | |
options: { storage: string } | string = { storage: storageMode }, | |
): void => { | |
keys.add(key); | |
storage.setItem(key, value, options); | |
}; | |
/** | |
* Retrieve a value that was stored using setItem. | |
* | |
* @param key Key to look up | |
* @param options If provided this can override the default storage mode | |
*/ | |
const getItem = ( | |
key: string, | |
options: { storage: string } | string = { storage: storageMode }, | |
): unknown => { | |
return storage.getItem(key, options); | |
}; | |
/** | |
* Remove an item from storage. | |
* | |
* @param key Key to remove | |
* @param options If provided this can override the default storage mode | |
*/ | |
const removeItem = ( | |
key: string, | |
options: { storage: string } | string = { storage: storageMode }, | |
): { | |
global?: any; | |
localStorage?: any; | |
sessionStorage?: any; | |
cookie?: any; | |
} => { | |
keys.delete(key); | |
return storage.removeItem(key); | |
}; | |
return { getConsent, setConsent, setItem, getItem, removeItem }; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment