Created
November 29, 2022 23:55
-
-
Save dobesv/9022c95d39461eaa05e9f2125d72a203 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 ConsentStorage extends AnalyticsStorage { | |
getConsent(): boolean; | |
setConsent(newValue: boolean): void; | |
} | |
export default function createConsentStorage(): ConsentStorage { | |
/** | |
* Storage parameter for setItem calls. getItem and removeItem always use | |
* `ALL`. | |
*/ | |
let storageMode: 'global' | '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