Skip to content

Commit

Permalink
✨ feat(key-value): add domains to key value
Browse files Browse the repository at this point in the history
  • Loading branch information
thrownullexception committed Sep 24, 2023
1 parent 59550b7 commit ca7e0a8
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 32 deletions.
9 changes: 5 additions & 4 deletions src/__tests__/api/_test-utils/_all.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { ConfigDomain } from "backend/lib/config-persistence/types";
import { KeyValueDomain } from "backend/lib/key-value/types";
import { setupAppConfigTestData } from "./_app-config";
import { setupIntegrationsConstantsTestData } from "./_integrations-constants";
import { setupCredentialsTestData } from "./_credentials";
Expand All @@ -13,10 +14,10 @@ import { setupActivatedStorageTestData } from "./_activated-storage";
import { setupTestDatabaseData } from "./_data";
import { portalTestData } from "./portal";

export const setupAllTestData = async (
domains: Array<ConfigDomain | "data">
) => {
const allTestData: [ConfigDomain | "data", () => Promise<void>][] = [
type DomainTypes = ConfigDomain | KeyValueDomain | "data";

export const setupAllTestData = async (domains: DomainTypes[]) => {
const allTestData: [DomainTypes, () => Promise<void>][] = [
["roles", setupRolesTestData],
["app-config", setupAppConfigTestData],
["users", setupUsersTestData],
Expand Down
35 changes: 21 additions & 14 deletions src/backend/lib/key-value/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,34 @@ import {
AbstractConfigDataPersistenceService,
createConfigDomainPersistenceService,
} from "../config-persistence";
import { KeyValueDomain } from "./types";

interface IStorge {
interface IStorage {
data: string;
}

export class KeyValueStoreApiService {
export class KeyValueStoreApiService<T> {
constructor(
private readonly _keyValueStorePersistenceService: AbstractConfigDataPersistenceService<IStorge>
private readonly key: KeyValueDomain,
private readonly _keyValueStorePersistenceService: AbstractConfigDataPersistenceService<IStorage>
) {}

async bootstrap() {
await this._keyValueStorePersistenceService.setup();
}

async clearItem(key: string) {
await this._keyValueStorePersistenceService.removeItem(key);
async clearItem() {
await this._keyValueStorePersistenceService.removeItem(this.key);
}

async persistItem(key: string, data: unknown) {
await this._keyValueStorePersistenceService.persistItem(key, {
async persistItem(data: T) {
await this._keyValueStorePersistenceService.persistItem(this.key, {
data: JSON.stringify(data),
});
}

async getItem<T>(key: string): Promise<T | null> {
const data = await this._keyValueStorePersistenceService.getItem(key);
async getItem(): Promise<T | null> {
const data = await this._keyValueStorePersistenceService.getItem(this.key);
if (!data) {
return null;
}
Expand All @@ -36,8 +38,13 @@ export class KeyValueStoreApiService {
}

const keyValueStorePersistenceService =
createConfigDomainPersistenceService<IStorge>("key-value");

export const keyValueStoreApiService = new KeyValueStoreApiService(
keyValueStorePersistenceService
);
createConfigDomainPersistenceService<IStorage>("key-value");

export function createKeyValueDomainPersistenceService<T>(
keyValueDomain: KeyValueDomain
) {
return new KeyValueStoreApiService<T>(
keyValueDomain,
keyValueStorePersistenceService
);
}
47 changes: 33 additions & 14 deletions src/backend/lib/key-value/key-value.spec.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,45 @@
import { keyValueStoreApiService } from ".";
import { createKeyValueDomainPersistenceService } from ".";
import { KeyValueDomain } from "./types";

const keyValueStoreApiService = createKeyValueDomainPersistenceService<
Record<string, unknown>
>("test-me" as KeyValueDomain);

const unTouchedkeyValueStoreApiService = createKeyValueDomainPersistenceService<
Record<string, unknown>
>("un-touched" as KeyValueDomain);

describe("KeyValueStoreApiService", () => {
it("should return empty for none saved items", async () => {
expect(await keyValueStoreApiService.getItem("non-existent")).toBeNull();
});
it("should upsert data", async () => {
await keyValueStoreApiService.persistItem({ bar: "bar" });
await unTouchedkeyValueStoreApiService.persistItem({ bar: "bar" });
expect(await keyValueStoreApiService.getItem()).toEqual({
bar: "bar",
});

it("should persist items", async () => {
await keyValueStoreApiService.persistItem("persist", { bar: "baz" });
expect(await keyValueStoreApiService.getItem("persist")).toEqual({
bar: "baz",
expect(await unTouchedkeyValueStoreApiService.getItem()).toEqual({
bar: "bar",
});

await keyValueStoreApiService.persistItem({ foo: "foo" });
expect(await keyValueStoreApiService.getItem()).toEqual({
foo: "foo",
});

expect(await unTouchedkeyValueStoreApiService.getItem()).toEqual({
bar: "bar",
});
});

it("should clear items", async () => {
await keyValueStoreApiService.persistItem("clear1", { bar1: "baz1" });
await keyValueStoreApiService.persistItem("clear2", { bar2: "baz2" });
await keyValueStoreApiService.persistItem({ bar2: "baz2" });

await keyValueStoreApiService.clearItem();

await keyValueStoreApiService.clearItem("clear1");
expect(await keyValueStoreApiService.getItem()).toBeNull();

expect(await keyValueStoreApiService.getItem("clear1")).toBeNull();
expect(await keyValueStoreApiService.getItem("clear2")).toEqual({
bar2: "baz2",
expect(await unTouchedkeyValueStoreApiService.getItem()).toEqual({
bar: "bar",
});
});
});
1 change: 1 addition & 0 deletions src/backend/lib/key-value/portal/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { type PortalKeyValueDomain } from "./main";
1 change: 1 addition & 0 deletions src/backend/lib/key-value/portal/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export type PortalKeyValueDomain = "";
3 changes: 3 additions & 0 deletions src/backend/lib/key-value/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { PortalKeyValueDomain } from "./portal";

export type KeyValueDomain = PortalKeyValueDomain;

0 comments on commit ca7e0a8

Please sign in to comment.