From e01741261a0e8b0c5f88e9a546220f37d486fe04 Mon Sep 17 00:00:00 2001 From: Lajos Szoke <63732287+laliconfigcat@users.noreply.github.com> Date: Wed, 20 Dec 2023 17:15:39 +0100 Subject: [PATCH] Cache latin1 fix (#45) * cache latin1 fix * version * cache test --- package-lock.json | 4 ++-- package.json | 2 +- src/Cache.test.ts | 10 ++++++++++ src/Cache.ts | 16 ++++++++++++++-- 4 files changed, 27 insertions(+), 5 deletions(-) create mode 100644 src/Cache.test.ts diff --git a/package-lock.json b/package-lock.json index f3c33f9..0c63831 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "configcat-react", - "version": "4.0.0", + "version": "4.1.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "configcat-react", - "version": "4.0.0", + "version": "4.1.0", "license": "MIT", "dependencies": { "configcat-common": "^9.0.0", diff --git a/package.json b/package.json index 8390d3a..d79aeb6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "configcat-react", - "version": "4.0.0", + "version": "4.1.0", "scripts": { "build": "npm run build:esm && npm run build:cjs", "build:esm": "tsc -p tsconfig.build.esm.json && gulp esm", diff --git a/src/Cache.test.ts b/src/Cache.test.ts new file mode 100644 index 0000000..5ef10ab --- /dev/null +++ b/src/Cache.test.ts @@ -0,0 +1,10 @@ +import { LocalStorageCache } from "./Cache"; + +it("LocalStorageCache works with non latin 1 characters", () => { + const cache = new LocalStorageCache(); + const key = "testkey"; + const text = "äöüÄÖÜçéèñışğ⢙✓😀"; + cache.set(key, text); + const retrievedValue = cache.get(key); + expect(retrievedValue).toStrictEqual(text); +}); diff --git a/src/Cache.ts b/src/Cache.ts index 60e4d98..3e7e51c 100644 --- a/src/Cache.ts +++ b/src/Cache.ts @@ -3,7 +3,7 @@ import type { IConfigCatCache } from "configcat-common"; export class LocalStorageCache implements IConfigCatCache { set(key: string, value: string): void { try { - localStorage.setItem(key, btoa(value)); + localStorage.setItem(key, this.b64EncodeUnicode(value)); } catch (ex) { // local storage is unavailable @@ -14,7 +14,7 @@ export class LocalStorageCache implements IConfigCatCache { try { const configString = localStorage.getItem(key); if (configString) { - return atob(configString); + return this.b64DecodeUnicode(configString); } } catch (ex) { @@ -22,4 +22,16 @@ export class LocalStorageCache implements IConfigCatCache { } return void 0; } + + private b64EncodeUnicode(str: string): string { + return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function (_, p1) { + return String.fromCharCode(parseInt(p1, 16)) + })); + } + + private b64DecodeUnicode(str: string): string { + return decodeURIComponent(Array.prototype.map.call(atob(str), function (c: string) { + return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2) + }).join('')); + } }