From b085335e4c82be7d5594d4ead1d9ca455f2ec695 Mon Sep 17 00:00:00 2001 From: Daniel Rivers Date: Fri, 25 Oct 2024 13:42:14 +0100 Subject: [PATCH 1/7] feat: add setItems to storage --- lib/sessionManager/index.ts | 5 ++++- lib/sessionManager/stores/chromeStore.test.ts | 14 +++++++++++++ lib/sessionManager/stores/chromeStore.ts | 4 ++-- .../stores/expoSecureStore.test.ts | 13 ++++++++++++ lib/sessionManager/stores/expoSecureStore.ts | 5 +++-- lib/sessionManager/stores/memory.test.ts | 13 ++++++++++++ lib/sessionManager/stores/memory.ts | 4 ++-- lib/sessionManager/types.ts | 20 ++++++++++++++++++- 8 files changed, 70 insertions(+), 8 deletions(-) diff --git a/lib/sessionManager/index.ts b/lib/sessionManager/index.ts index 4af815b..aee3d68 100644 --- a/lib/sessionManager/index.ts +++ b/lib/sessionManager/index.ts @@ -16,4 +16,7 @@ export const storageSettings: StorageSettingsType = { export { MemoryStorage } from "./stores/memory.js"; export { ChromeStore } from "./stores/chromeStore.js"; export { ExpoSecureStore } from "./stores/expoSecureStore.js"; -export * from "./types.ts"; +export { + type SessionManager, + StorageKeys +} from "./types.ts"; diff --git a/lib/sessionManager/stores/chromeStore.test.ts b/lib/sessionManager/stores/chromeStore.test.ts index 0fbeb98..32916be 100644 --- a/lib/sessionManager/stores/chromeStore.test.ts +++ b/lib/sessionManager/stores/chromeStore.test.ts @@ -43,6 +43,20 @@ describe.skip("GoogleStorage standard keys", () => { await sessionManager.getSessionItem(StorageKeys.accessToken), ).toBeNull(); }); + + + it("should set many items", async () => { + await sessionManager.setItems({ + [StorageKeys.accessToken]: "accessTokenValue", + [StorageKeys.idToken]: "idTokenValue", + }); + expect(await sessionManager.getSessionItem(StorageKeys.accessToken)).toBe( + "accessTokenValue", + ); + expect(await sessionManager.getSessionItem(StorageKeys.idToken)).toBe( + "idTokenValue", + ); + }); }); // TODO: Fix tests, need to mock chrome storage diff --git a/lib/sessionManager/stores/chromeStore.ts b/lib/sessionManager/stores/chromeStore.ts index 62f3b44..8244f46 100644 --- a/lib/sessionManager/stores/chromeStore.ts +++ b/lib/sessionManager/stores/chromeStore.ts @@ -1,5 +1,5 @@ import { storageSettings } from "../index.js"; -import { StorageKeys, type SessionManager } from "../types.js"; +import { SessionBase, StorageKeys, type SessionManager } from "../types.js"; import { splitString } from "../utils.js"; function getStorageValue(key: string): unknown | undefined { @@ -18,7 +18,7 @@ function getStorageValue(key: string): unknown | undefined { * Provides a chrome.store.local based session manager implementation for the browser. * @class ChromeStore */ -export class ChromeStore implements SessionManager { +export class ChromeStore extends SessionBase implements SessionManager { /** * Clears all items from session store. * @returns {void} diff --git a/lib/sessionManager/stores/expoSecureStore.test.ts b/lib/sessionManager/stores/expoSecureStore.test.ts index 07a08e3..50a6ceb 100644 --- a/lib/sessionManager/stores/expoSecureStore.test.ts +++ b/lib/sessionManager/stores/expoSecureStore.test.ts @@ -43,6 +43,19 @@ describe.skip("ExpoSecureStore standard keys", () => { await sessionManager.getSessionItem(StorageKeys.accessToken), ).toBeNull(); }); + + it("should set many items", async () => { + await sessionManager.setItems({ + [StorageKeys.accessToken]: "accessTokenValue", + [StorageKeys.idToken]: "idTokenValue", + }); + expect(await sessionManager.getSessionItem(StorageKeys.accessToken)).toBe( + "accessTokenValue", + ); + expect(await sessionManager.getSessionItem(StorageKeys.idToken)).toBe( + "idTokenValue", + ); + }); }); describe.skip("ExpoSecureStore keys: storageKeys", () => { diff --git a/lib/sessionManager/stores/expoSecureStore.ts b/lib/sessionManager/stores/expoSecureStore.ts index 958b0e2..36816ab 100644 --- a/lib/sessionManager/stores/expoSecureStore.ts +++ b/lib/sessionManager/stores/expoSecureStore.ts @@ -1,5 +1,5 @@ import { storageSettings } from "../index.js"; -import { StorageKeys, type SessionManager } from "../types.js"; +import { SessionBase, StorageKeys } from "../types.js"; import { splitString } from "../utils.js"; let expoSecureStore: typeof import("expo-secure-store") | undefined = undefined; @@ -16,8 +16,9 @@ async function waitForExpoSecureStore() { * Provides a expo local store based session manager implementation for the browser. * @class ExpoSecureStore */ -export class ExpoSecureStore implements SessionManager { +export class ExpoSecureStore extends SessionBase { constructor() { + super(); this.loadExpoStore(); } diff --git a/lib/sessionManager/stores/memory.test.ts b/lib/sessionManager/stores/memory.test.ts index 010c74e..9edadbd 100644 --- a/lib/sessionManager/stores/memory.test.ts +++ b/lib/sessionManager/stores/memory.test.ts @@ -43,6 +43,19 @@ describe("MemoryStorage standard keys", () => { await sessionManager.getSessionItem(StorageKeys.accessToken), ).toBeNull(); }); + + it("should set many items", async () => { + await sessionManager.setItems({ + [StorageKeys.accessToken]: "accessTokenValue", + [StorageKeys.idToken]: "idTokenValue", + }); + expect(await sessionManager.getSessionItem(StorageKeys.accessToken)).toBe( + "accessTokenValue", + ); + expect(await sessionManager.getSessionItem(StorageKeys.idToken)).toBe( + "idTokenValue", + ); + }); }); describe("MemoryStorage keys: storageKeys", () => { diff --git a/lib/sessionManager/stores/memory.ts b/lib/sessionManager/stores/memory.ts index eb78377..5196604 100644 --- a/lib/sessionManager/stores/memory.ts +++ b/lib/sessionManager/stores/memory.ts @@ -1,12 +1,12 @@ import { storageSettings } from "../index.js"; -import { StorageKeys, type SessionManager } from "../types.js"; +import { SessionBase, StorageKeys, type SessionManager } from "../types.js"; import { splitString } from "../utils.js"; /** * Provides a memory based session manager implementation for the browser. * @class MemoryStorage */ -export class MemoryStorage implements SessionManager { +export class MemoryStorage extends SessionBase implements SessionManager { private memCache: Record = {}; /** diff --git a/lib/sessionManager/types.ts b/lib/sessionManager/types.ts index e028df6..b46e236 100644 --- a/lib/sessionManager/types.ts +++ b/lib/sessionManager/types.ts @@ -18,7 +18,23 @@ export type StorageSettingsType = { maxLength: number; }; -export interface SessionManager { + +export abstract class SessionBase implements SessionManager { + abstract getSessionItem(itemKey: V | StorageKeys): Awaitable; + abstract setSessionItem(itemKey: V | StorageKeys, itemValue: T): Awaitable; + abstract removeSessionItem(itemKey: V | StorageKeys): Awaitable; + abstract destroySession(): Awaitable; + + async setItems(items: Partial>): Promise { + await Promise.all( + Object.entries(items).map(([key, value]) => { + return this.setSessionItem(key as V | StorageKeys, value); + }) + ); + } +} + +export interface SessionManager { /** * * Gets the item for the provided key from the storage. @@ -49,4 +65,6 @@ export interface SessionManager { * Destroys the session */ destroySession: () => Awaitable; + + setItems(items: Record): void } From 382559dcb2e27610f2798449662806794e99d180 Mon Sep 17 00:00:00 2001 From: Daniel Rivers Date: Fri, 25 Oct 2024 13:52:04 +0100 Subject: [PATCH 2/7] chore: lint --- lib/sessionManager/index.ts | 5 +---- lib/sessionManager/stores/chromeStore.test.ts | 1 - lib/sessionManager/stores/chromeStore.ts | 5 ++++- lib/sessionManager/stores/expoSecureStore.ts | 4 +++- lib/sessionManager/stores/memory.ts | 5 ++++- lib/sessionManager/types.ts | 20 ++++++++++++------- 6 files changed, 25 insertions(+), 15 deletions(-) diff --git a/lib/sessionManager/index.ts b/lib/sessionManager/index.ts index aee3d68..9eb0b07 100644 --- a/lib/sessionManager/index.ts +++ b/lib/sessionManager/index.ts @@ -16,7 +16,4 @@ export const storageSettings: StorageSettingsType = { export { MemoryStorage } from "./stores/memory.js"; export { ChromeStore } from "./stores/chromeStore.js"; export { ExpoSecureStore } from "./stores/expoSecureStore.js"; -export { - type SessionManager, - StorageKeys -} from "./types.ts"; +export { type SessionManager, StorageKeys } from "./types.ts"; diff --git a/lib/sessionManager/stores/chromeStore.test.ts b/lib/sessionManager/stores/chromeStore.test.ts index 32916be..ad2f751 100644 --- a/lib/sessionManager/stores/chromeStore.test.ts +++ b/lib/sessionManager/stores/chromeStore.test.ts @@ -44,7 +44,6 @@ describe.skip("GoogleStorage standard keys", () => { ).toBeNull(); }); - it("should set many items", async () => { await sessionManager.setItems({ [StorageKeys.accessToken]: "accessTokenValue", diff --git a/lib/sessionManager/stores/chromeStore.ts b/lib/sessionManager/stores/chromeStore.ts index 8244f46..6f00bf2 100644 --- a/lib/sessionManager/stores/chromeStore.ts +++ b/lib/sessionManager/stores/chromeStore.ts @@ -18,7 +18,10 @@ function getStorageValue(key: string): unknown | undefined { * Provides a chrome.store.local based session manager implementation for the browser. * @class ChromeStore */ -export class ChromeStore extends SessionBase implements SessionManager { +export class ChromeStore + extends SessionBase + implements SessionManager +{ /** * Clears all items from session store. * @returns {void} diff --git a/lib/sessionManager/stores/expoSecureStore.ts b/lib/sessionManager/stores/expoSecureStore.ts index 36816ab..7cc6e07 100644 --- a/lib/sessionManager/stores/expoSecureStore.ts +++ b/lib/sessionManager/stores/expoSecureStore.ts @@ -16,7 +16,9 @@ async function waitForExpoSecureStore() { * Provides a expo local store based session manager implementation for the browser. * @class ExpoSecureStore */ -export class ExpoSecureStore extends SessionBase { +export class ExpoSecureStore< + V extends string = StorageKeys, +> extends SessionBase { constructor() { super(); this.loadExpoStore(); diff --git a/lib/sessionManager/stores/memory.ts b/lib/sessionManager/stores/memory.ts index 5196604..e133351 100644 --- a/lib/sessionManager/stores/memory.ts +++ b/lib/sessionManager/stores/memory.ts @@ -6,7 +6,10 @@ import { splitString } from "../utils.js"; * Provides a memory based session manager implementation for the browser. * @class MemoryStorage */ -export class MemoryStorage extends SessionBase implements SessionManager { +export class MemoryStorage + extends SessionBase + implements SessionManager +{ private memCache: Record = {}; /** diff --git a/lib/sessionManager/types.ts b/lib/sessionManager/types.ts index b46e236..7be97b5 100644 --- a/lib/sessionManager/types.ts +++ b/lib/sessionManager/types.ts @@ -18,18 +18,24 @@ export type StorageSettingsType = { maxLength: number; }; - -export abstract class SessionBase implements SessionManager { - abstract getSessionItem(itemKey: V | StorageKeys): Awaitable; - abstract setSessionItem(itemKey: V | StorageKeys, itemValue: T): Awaitable; +export abstract class SessionBase + implements SessionManager +{ + abstract getSessionItem( + itemKey: V | StorageKeys, + ): Awaitable; + abstract setSessionItem( + itemKey: V | StorageKeys, + itemValue: T, + ): Awaitable; abstract removeSessionItem(itemKey: V | StorageKeys): Awaitable; abstract destroySession(): Awaitable; - + async setItems(items: Partial>): Promise { await Promise.all( Object.entries(items).map(([key, value]) => { return this.setSessionItem(key as V | StorageKeys, value); - }) + }), ); } } @@ -66,5 +72,5 @@ export interface SessionManager { */ destroySession: () => Awaitable; - setItems(items: Record): void + setItems(items: Record): void; } From f2384a1bdabf806be98778f0ebaddbc9219419fc Mon Sep 17 00:00:00 2001 From: Daniel Rivers Date: Fri, 25 Oct 2024 14:09:09 +0100 Subject: [PATCH 3/7] fix: update LocalStorage and fix types --- lib/sessionManager/stores/localStorage.ts | 13 +++++++------ lib/sessionManager/types.ts | 10 ++++++++-- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/lib/sessionManager/stores/localStorage.ts b/lib/sessionManager/stores/localStorage.ts index 3b93fae..35921c1 100644 --- a/lib/sessionManager/stores/localStorage.ts +++ b/lib/sessionManager/stores/localStorage.ts @@ -1,24 +1,25 @@ import { storageSettings } from "../index.js"; -import { StorageKeys, type SessionManager } from "../types.js"; +import { SessionBase, StorageKeys, type SessionManager } from "../types.js"; import { splitString } from "../utils.js"; /** * Provides a localStorage based session manager implementation for the browser. * @class LocalStorage */ -export class LocalStorage implements SessionManager { +export class LocalStorage extends SessionBase implements SessionManager { constructor() { + super(); console.warn("LocalStorage store should not be used in production"); } - setItems: Set = new Set(); + private internalItems: Set = new Set(); /** * Clears all items from session store. * @returns {void} */ async destroySession(): Promise { - this.setItems.forEach((key) => { + this.internalItems.forEach((key) => { this.removeSessionItem(key); }); } @@ -35,7 +36,7 @@ export class LocalStorage implements SessionManager { ): Promise { // clear items first await this.removeSessionItem(itemKey); - this.setItems.add(itemKey); + this.internalItems.add(itemKey); if (typeof itemValue === "string") { splitString(itemValue, storageSettings.maxLength).forEach( @@ -97,6 +98,6 @@ export class LocalStorage implements SessionManager { index++; } - this.setItems.delete(itemKey); + this.internalItems.delete(itemKey); } } diff --git a/lib/sessionManager/types.ts b/lib/sessionManager/types.ts index 7be97b5..b22f99a 100644 --- a/lib/sessionManager/types.ts +++ b/lib/sessionManager/types.ts @@ -31,7 +31,7 @@ export abstract class SessionBase abstract removeSessionItem(itemKey: V | StorageKeys): Awaitable; abstract destroySession(): Awaitable; - async setItems(items: Partial>): Promise { + async setItems(items: Partial>): Awaitable { await Promise.all( Object.entries(items).map(([key, value]) => { return this.setSessionItem(key as V | StorageKeys, value); @@ -72,5 +72,11 @@ export interface SessionManager { */ destroySession: () => Awaitable; - setItems(items: Record): void; + + /** + * Sets multiple items simultaneously. + * @param {Record} items - Object containing key-value pairs to store + * @returns {Promise} + */ + setItems(items: Partial>): Awaitable; } From 6bc8a98f91a323f16b2b92c5ef1ba98cb80a021a Mon Sep 17 00:00:00 2001 From: Daniel Rivers Date: Fri, 25 Oct 2024 14:10:51 +0100 Subject: [PATCH 4/7] chore: lint --- lib/sessionManager/index.ts | 5 +---- lib/sessionManager/stores/localStorage.ts | 5 ++++- lib/sessionManager/types.ts | 9 ++++----- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/lib/sessionManager/index.ts b/lib/sessionManager/index.ts index 01d6100..de392b6 100644 --- a/lib/sessionManager/index.ts +++ b/lib/sessionManager/index.ts @@ -17,7 +17,4 @@ export { MemoryStorage } from "./stores/memory.js"; export { ChromeStore } from "./stores/chromeStore.js"; export { ExpoSecureStore } from "./stores/expoSecureStore.js"; export { LocalStorage } from "./stores/localStorage.ts"; -export { - type SessionManager, - StorageKeys -} from "./types.ts"; +export { type SessionManager, StorageKeys } from "./types.ts"; diff --git a/lib/sessionManager/stores/localStorage.ts b/lib/sessionManager/stores/localStorage.ts index 35921c1..52005d8 100644 --- a/lib/sessionManager/stores/localStorage.ts +++ b/lib/sessionManager/stores/localStorage.ts @@ -6,7 +6,10 @@ import { splitString } from "../utils.js"; * Provides a localStorage based session manager implementation for the browser. * @class LocalStorage */ -export class LocalStorage extends SessionBase implements SessionManager { +export class LocalStorage + extends SessionBase + implements SessionManager +{ constructor() { super(); console.warn("LocalStorage store should not be used in production"); diff --git a/lib/sessionManager/types.ts b/lib/sessionManager/types.ts index b22f99a..57b8bcf 100644 --- a/lib/sessionManager/types.ts +++ b/lib/sessionManager/types.ts @@ -72,11 +72,10 @@ export interface SessionManager { */ destroySession: () => Awaitable; - /** - * Sets multiple items simultaneously. - * @param {Record} items - Object containing key-value pairs to store - * @returns {Promise} - */ + * Sets multiple items simultaneously. + * @param {Record} items - Object containing key-value pairs to store + * @returns {Promise} + */ setItems(items: Partial>): Awaitable; } From cd668a8ff561103082e5f538a13cde631c243660 Mon Sep 17 00:00:00 2001 From: Daniel Rivers Date: Fri, 25 Oct 2024 15:03:16 +0100 Subject: [PATCH 5/7] chore: remove console log --- lib/sessionManager/stores/localStorage.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/sessionManager/stores/localStorage.test.ts b/lib/sessionManager/stores/localStorage.test.ts index c7d91c8..3e6ab1c 100644 --- a/lib/sessionManager/stores/localStorage.test.ts +++ b/lib/sessionManager/stores/localStorage.test.ts @@ -34,7 +34,6 @@ describe("LocalStorage standard keys", () => { }); it("should set and get an item in session storage", async () => { - console.log("here"); await sessionManager.setSessionItem(StorageKeys.accessToken, "testValue"); expect(await sessionManager.getSessionItem(StorageKeys.accessToken)).toBe( "testValue", From 69e55c1ae51c33341a45d54057883b479e4f43fb Mon Sep 17 00:00:00 2001 From: Daniel Rivers Date: Fri, 25 Oct 2024 15:03:31 +0100 Subject: [PATCH 6/7] fix: solidify types more --- lib/sessionManager/types.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/sessionManager/types.ts b/lib/sessionManager/types.ts index 57b8bcf..355bb80 100644 --- a/lib/sessionManager/types.ts +++ b/lib/sessionManager/types.ts @@ -33,10 +33,10 @@ export abstract class SessionBase async setItems(items: Partial>): Awaitable { await Promise.all( - Object.entries(items).map(([key, value]) => { - return this.setSessionItem(key as V | StorageKeys, value); - }), - ); + (Object.entries(items) as [V | StorageKeys, unknown][]).map(([key, value]) => { + return this.setSessionItem(key, value); + } + )); } } From aa264e880f34cbf8cc735d4c80811e52c3b3882c Mon Sep 17 00:00:00 2001 From: Daniel Rivers Date: Fri, 25 Oct 2024 15:44:12 +0100 Subject: [PATCH 7/7] chore: lint --- lib/sessionManager/types.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/sessionManager/types.ts b/lib/sessionManager/types.ts index 355bb80..ceaf89a 100644 --- a/lib/sessionManager/types.ts +++ b/lib/sessionManager/types.ts @@ -33,10 +33,12 @@ export abstract class SessionBase async setItems(items: Partial>): Awaitable { await Promise.all( - (Object.entries(items) as [V | StorageKeys, unknown][]).map(([key, value]) => { - return this.setSessionItem(key, value); - } - )); + (Object.entries(items) as [V | StorageKeys, unknown][]).map( + ([key, value]) => { + return this.setSessionItem(key, value); + }, + ), + ); } }