diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 38a1597848e..33ed845b821 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -87,6 +87,7 @@ libs/common/src/platform @bitwarden/team-platform-dev libs/common/spec @bitwarden/team-platform-dev libs/common/src/state-migrations @bitwarden/team-platform-dev libs/platform @bitwarden/team-platform-dev +libs/storage @bitwarden/team-platform-dev # Web utils used across app and connectors apps/web/src/utils/ @bitwarden/team-platform-dev # Web core and shared files diff --git a/libs/common/src/platform/abstractions/storage.service.ts b/libs/common/src/platform/abstractions/storage.service.ts index 390d71ae2ad..9881933f189 100644 --- a/libs/common/src/platform/abstractions/storage.service.ts +++ b/libs/common/src/platform/abstractions/storage.service.ts @@ -1,26 +1,6 @@ -import { Observable } from "rxjs"; - -import { StorageOptions } from "../models/domain/storage-options"; - -export type StorageUpdateType = "save" | "remove"; -export type StorageUpdate = { - key: string; - updateType: StorageUpdateType; -}; - -export interface ObservableStorageService { - /** - * Provides an {@link Observable} that represents a stream of updates that - * have happened in this storage service or in the storage this service provides - * an interface to. - */ - get updates$(): Observable; -} - -export abstract class AbstractStorageService { - abstract get valuesRequireDeserialization(): boolean; - abstract get(key: string, options?: StorageOptions): Promise; - abstract has(key: string, options?: StorageOptions): Promise; - abstract save(key: string, obj: T, options?: StorageOptions): Promise; - abstract remove(key: string, options?: StorageOptions): Promise; -} +export { + StorageUpdateType, + StorageUpdate, + ObservableStorageService, + StorageService as AbstractStorageService, +} from "@bitwarden/storage"; diff --git a/libs/common/src/platform/enums/html-storage-location.enum.ts b/libs/common/src/platform/enums/html-storage-location.enum.ts index 1d018a72869..2605fead813 100644 --- a/libs/common/src/platform/enums/html-storage-location.enum.ts +++ b/libs/common/src/platform/enums/html-storage-location.enum.ts @@ -1,7 +1 @@ -// FIXME: update to use a const object instead of a typescript enum -// eslint-disable-next-line @bitwarden/platform/no-enums -export enum HtmlStorageLocation { - Local = "local", - Memory = "memory", - Session = "session", -} +export { HtmlStorageLocation } from "@bitwarden/storage"; diff --git a/libs/common/src/platform/enums/storage-location.enum.ts b/libs/common/src/platform/enums/storage-location.enum.ts index 9f6e22babec..673be4c0a37 100644 --- a/libs/common/src/platform/enums/storage-location.enum.ts +++ b/libs/common/src/platform/enums/storage-location.enum.ts @@ -1,7 +1 @@ -// FIXME: update to use a const object instead of a typescript enum -// eslint-disable-next-line @bitwarden/platform/no-enums -export enum StorageLocation { - Both = "both", - Disk = "disk", - Memory = "memory", -} +export { StorageLocation } from "@bitwarden/storage"; diff --git a/libs/common/src/platform/models/domain/storage-options.ts b/libs/common/src/platform/models/domain/storage-options.ts index e27628b8502..b4888730e0d 100644 --- a/libs/common/src/platform/models/domain/storage-options.ts +++ b/libs/common/src/platform/models/domain/storage-options.ts @@ -1,9 +1 @@ -import { HtmlStorageLocation, StorageLocation } from "../../enums"; - -export type StorageOptions = { - storageLocation?: StorageLocation; - useSecureStorage?: boolean; - userId?: string; - htmlStorageLocation?: HtmlStorageLocation; - keySuffix?: string; -}; +export { StorageOptions } from "@bitwarden/storage"; diff --git a/libs/storage/README.md b/libs/storage/README.md new file mode 100644 index 00000000000..1d008d014e0 --- /dev/null +++ b/libs/storage/README.md @@ -0,0 +1,5 @@ +# storage + +Owned by: platform + +Basic primitives for storage. diff --git a/libs/storage/eslint.config.mjs b/libs/storage/eslint.config.mjs new file mode 100644 index 00000000000..9c37d10e3ff --- /dev/null +++ b/libs/storage/eslint.config.mjs @@ -0,0 +1,3 @@ +import baseConfig from "../../eslint.config.mjs"; + +export default [...baseConfig]; diff --git a/libs/storage/jest.config.js b/libs/storage/jest.config.js new file mode 100644 index 00000000000..d36fdf9918b --- /dev/null +++ b/libs/storage/jest.config.js @@ -0,0 +1,10 @@ +module.exports = { + displayName: "storage", + preset: "../../jest.preset.js", + testEnvironment: "node", + transform: { + "^.+\\.[tj]s$": ["ts-jest", { tsconfig: "/tsconfig.spec.json" }], + }, + moduleFileExtensions: ["ts", "js", "html"], + coverageDirectory: "../../coverage/libs/storage", +}; diff --git a/libs/storage/package.json b/libs/storage/package.json new file mode 100644 index 00000000000..2642b77a74f --- /dev/null +++ b/libs/storage/package.json @@ -0,0 +1,10 @@ +{ + "name": "@bitwarden/storage", + "version": "0.0.0", + "description": "Basic primitives for storage.", + "type": "commonjs", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "license": "GPL-3.0", + "author": "platform" +} diff --git a/libs/storage/project.json b/libs/storage/project.json new file mode 100644 index 00000000000..2e4b0f28ba1 --- /dev/null +++ b/libs/storage/project.json @@ -0,0 +1,27 @@ +{ + "name": "storage", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "libs/storage/src", + "projectType": "library", + "tags": [], + "targets": { + "build": { + "executor": "@nx/js:tsc", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/libs/storage", + "main": "libs/storage/src/index.ts", + "tsConfig": "libs/storage/tsconfig.lib.json", + "assets": ["libs/storage/*.md"] + } + }, + "test": { + "executor": "@nx/jest:jest", + "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], + "options": { + "jestConfig": "libs/storage/jest.config.js", + "passWithNoTests": true + } + } + } +} diff --git a/libs/storage/src/index.ts b/libs/storage/src/index.ts new file mode 100644 index 00000000000..db1e87d4605 --- /dev/null +++ b/libs/storage/src/index.ts @@ -0,0 +1,3 @@ +export * from "./observable-storage.service"; +export * from "./storage.service"; +export * from "./storage-options"; diff --git a/libs/storage/src/observable-storage.service.ts b/libs/storage/src/observable-storage.service.ts new file mode 100644 index 00000000000..b75ff87c9db --- /dev/null +++ b/libs/storage/src/observable-storage.service.ts @@ -0,0 +1,17 @@ +import { Observable } from "rxjs"; + +export type StorageUpdateType = "save" | "remove"; + +export type StorageUpdate = { + key: string; + updateType: StorageUpdateType; +}; + +export interface ObservableStorageService { + /** + * Provides an {@link Observable} that represents a stream of updates that + * have happened in this storage service or in the storage this service provides + * an interface to. + */ + get updates$(): Observable; +} diff --git a/libs/storage/src/storage-options.ts b/libs/storage/src/storage-options.ts new file mode 100644 index 00000000000..a19342bfb18 --- /dev/null +++ b/libs/storage/src/storage-options.ts @@ -0,0 +1,23 @@ +export const StorageLocation = { + Both: "both", + Disk: "disk", + Memory: "memory", +} as const; + +export type StorageLocation = (typeof StorageLocation)[keyof typeof StorageLocation]; + +export const HtmlStorageLocation = { + Local: "local", + Memory: "memory", + Session: "session", +} as const; + +export type HtmlStorageLocation = (typeof HtmlStorageLocation)[keyof typeof HtmlStorageLocation]; + +export type StorageOptions = { + storageLocation?: StorageLocation; + useSecureStorageLocation?: boolean; + userId?: string; + htmlStorageLocation?: HtmlStorageLocation; + keySuffix?: string; +}; diff --git a/libs/storage/src/storage.service.ts b/libs/storage/src/storage.service.ts new file mode 100644 index 00000000000..3b7e5ca8033 --- /dev/null +++ b/libs/storage/src/storage.service.ts @@ -0,0 +1,9 @@ +import { StorageOptions } from "./storage-options"; + +export abstract class StorageService { + abstract get valuesRequireDeserialization(): boolean; + abstract get(key: string, options?: StorageOptions): Promise; + abstract has(key: string, options?: StorageOptions): Promise; + abstract save(key: string, obj: T, options?: StorageOptions): Promise; + abstract remove(key: string, options?: StorageOptions): Promise; +} diff --git a/libs/storage/tsconfig.json b/libs/storage/tsconfig.json new file mode 100644 index 00000000000..62ebbd94647 --- /dev/null +++ b/libs/storage/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "../../tsconfig.base.json", + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/libs/storage/tsconfig.lib.json b/libs/storage/tsconfig.lib.json new file mode 100644 index 00000000000..9cbf6736007 --- /dev/null +++ b/libs/storage/tsconfig.lib.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "declaration": true, + "types": ["node"] + }, + "include": ["src/**/*.ts"], + "exclude": ["jest.config.js", "src/**/*.spec.ts"] +} diff --git a/libs/storage/tsconfig.spec.json b/libs/storage/tsconfig.spec.json new file mode 100644 index 00000000000..901c72378dd --- /dev/null +++ b/libs/storage/tsconfig.spec.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../..//dist/out-tsc", + "module": "commonjs", + "moduleResolution": "node10", + "types": ["jest", "node"] + }, + "include": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts", "src/**/*.d.ts"] +} diff --git a/package-lock.json b/package-lock.json index 691705cc280..83da57cc6ba 100644 --- a/package-lock.json +++ b/package-lock.json @@ -302,6 +302,10 @@ "version": "0.0.0", "license": "GPL-3.0" }, + "libs/storage": { + "version": "0.0.0", + "license": "GPL-3.0" + }, "libs/tools/card": { "name": "@bitwarden/tools-card", "version": "0.0.0", @@ -5219,6 +5223,10 @@ "resolved": "libs/tools/send/send-ui", "link": true }, + "node_modules/@bitwarden/storage": { + "resolved": "libs/storage", + "link": true + }, "node_modules/@bitwarden/tools-card": { "resolved": "libs/tools/card", "link": true diff --git a/tsconfig.base.json b/tsconfig.base.json index 68d158f18e4..2ffa6c79489 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -40,6 +40,7 @@ "@bitwarden/platform": ["./libs/platform/src"], "@bitwarden/platform/*": ["./libs/platform/src/*"], "@bitwarden/send-ui": ["./libs/tools/send/send-ui/src"], + "@bitwarden/storage": ["libs/storage/src/index.ts"], "@bitwarden/tools-card": ["./libs/tools/card/src"], "@bitwarden/ui-common": ["./libs/ui/common/src"], "@bitwarden/ui-common/setup-jest": ["./libs/ui/common/src/setup-jest"],