vue3-cookies
Version:
A simple Vue.js 3 plugin for handling browser cookies
246 lines (227 loc) • 7.19 kB
text/typescript
/**
* Vue3 Cookies v1.0.0
*
* Forked from
* https://github.com/cmp-cc/vue-cookies
* And changed format to support Vue.js 3
*
*/
import type { App } from "vue";
import { VueCookies, CookiesConfig } from "./interfaces";
import { reactive } from "vue";
const defaultConfig: CookiesConfig = {
expireTimes: "1d",
path: "; path=/",
domain: "",
secure: false,
sameSite: "; SameSite=Lax",
};
class VueCookiesManager implements VueCookies {
private current_default_config: CookiesConfig;
constructor() {
this.current_default_config = defaultConfig;
}
config(config: CookiesConfig): void {
for (const propertyName in this.current_default_config) {
this.current_default_config[propertyName] = config[propertyName]
? config[propertyName]
: defaultConfig[propertyName];
}
}
get(keyName: string): string {
let value =
decodeURIComponent(
document.cookie.replace(
new RegExp(
"(?:(?:^|.*;)\\s*" +
encodeURIComponent(keyName).replace(/[\-\.\+\*]/g, "\\$&") +
"\\s*\\=\\s*([^;]*).*$)|^.*$"
),
"$1"
)
) || null;
if (
value &&
value.substring(0, 1) === "{" &&
value.substring(value.length - 1, value.length) === "}"
) {
try {
value = JSON.parse(value);
} catch (e) {
return value;
}
}
return value;
}
set(
keyName: string,
value: string,
expireTimes?: string | number | Date,
path?: string,
domain?: string,
secure?: boolean,
sameSite?: string
): this {
if (!keyName) {
throw new Error("Cookie name is not found in the first argument.");
} else if (
/^(?:expires|max-age|path|domain|secure|SameSite)$/i.test(keyName)
) {
throw new Error(
'Cookie name illegality. Cannot be set to ["expires","max-age","path","domain","secure","SameSite"]\t current key name: ' +
keyName
);
}
// support json object
if (value && value.constructor === Object) {
value = JSON.stringify(value);
}
let _expires = "";
if (expireTimes == undefined) {
expireTimes = this.current_default_config.expireTimes
? this.current_default_config.expireTimes
: "";
}
if (expireTimes && expireTimes != 0) {
switch (expireTimes.constructor) {
case Number:
if (expireTimes === Infinity || expireTimes === -1)
_expires = "; expires=Fri, 31 Dec 9999 23:59:59 GMT";
else _expires = "; max-age=" + expireTimes;
break;
case String:
if (/^(?:\d+(y|m|d|h|min|s))$/i.test(<string>expireTimes)) {
// get capture number group
const _expireTime = (<string>expireTimes).replace(
/^(\d+)(?:y|m|d|h|min|s)$/i,
"$1"
);
// get capture type group , to lower case
switch (
(<string>expireTimes)
.replace(/^(?:\d+)(y|m|d|h|min|s)$/i, "$1")
.toLowerCase()
) {
// Frequency sorting
case "m":
_expires = "; max-age=" + +_expireTime * 2592000;
break; // 60 * 60 * 24 * 30
case "d":
_expires = "; max-age=" + +_expireTime * 86400;
break; // 60 * 60 * 24
case "h":
_expires = "; max-age=" + +_expireTime * 3600;
break; // 60 * 60
case "min":
_expires = "; max-age=" + +_expireTime * 60;
break; // 60
case "s":
_expires = "; max-age=" + _expireTime;
break;
case "y":
_expires = "; max-age=" + +_expireTime * 31104000;
break; // 60 * 60 * 24 * 30 * 12
default:
new Error('unknown exception of "set operation"');
}
} else {
_expires = "; expires=" + expireTimes;
}
break;
case Date:
_expires = "; expires=" + (<Date>expireTimes).toUTCString();
break;
}
}
document.cookie =
encodeURIComponent(keyName) +
"=" +
encodeURIComponent(value) +
_expires +
(domain
? "; domain=" + domain
: this.current_default_config.domain
? this.current_default_config.domain
: "") +
(path
? "; path=" + path
: this.current_default_config.path
? this.current_default_config.path
: "; path=/") +
(secure == undefined
? this.current_default_config.secure
? "; Secure"
: ""
: secure
? "; Secure"
: "") +
(sameSite == undefined
? this.current_default_config.sameSite
? "; SameSute=" + this.current_default_config.sameSite
: ""
: sameSite
? "; SameSite=" + sameSite
: "");
return this;
}
remove(keyName: string, path?: string, domain?: string): boolean {
if (!keyName || !this.isKey(keyName)) {
return false;
}
document.cookie =
encodeURIComponent(keyName) +
"=; expires=Thu, 01 Jan 1970 00:00:00 GMT" +
(domain
? "; domain=" + domain
: this.current_default_config.domain
? this.current_default_config.domain
: "") +
(path
? "; path=" + path
: this.current_default_config.path
? this.current_default_config.path
: "; path=/") +
"; SameSite=Lax";
return true;
}
isKey(keyName: string): boolean {
return new RegExp(
"(?:^|;\\s*)" +
encodeURIComponent(keyName).replace(/[\-\.\+\*]/g, "\\$&") +
"\\s*\\="
).test(document.cookie);
}
keys(): string[] {
if (!document.cookie) return [];
const _keys = document.cookie
.replace(/((?:^|\s*;)[^\=]+)(?=;|$)|^\s*|\s*(?:\=[^;]*)?(?:\1|$)/g, "")
.split(/\s*(?:\=[^;]*)?;\s*/);
for (let _index = 0; _index < _keys.length; _index++) {
_keys[_index] = decodeURIComponent(_keys[_index]);
}
return _keys;
}
}
export default {
install: function (app: App, options?: CookiesConfig): void {
app.config.globalProperties.$cookies = new VueCookiesManager();
if (options) {
app.config.globalProperties.$cookies.config(options);
}
},
};
let GLOBAL_COOKIES_MANAGER: VueCookiesManager | null = null;
function globalCookiesConfig(options?: CookiesConfig) {
if (GLOBAL_COOKIES_MANAGER == null) {
GLOBAL_COOKIES_MANAGER = new VueCookiesManager();
}
GLOBAL_COOKIES_MANAGER.config(options);
}
function useCookies() {
if (GLOBAL_COOKIES_MANAGER == null) {
GLOBAL_COOKIES_MANAGER = new VueCookiesManager();
}
const cookies = reactive<VueCookiesManager>(GLOBAL_COOKIES_MANAGER);
return { cookies };
}
export { globalCookiesConfig, useCookies };