From d5673cfefcdb07fbdb57fb9414b2dd850b45bb19 Mon Sep 17 00:00:00 2001 From: Ted Xu Date: Thu, 16 May 2024 17:08:25 +0800 Subject: [PATCH 01/13] feat: expose underlying client instance --- pnpm-lock.yaml | 6 +++--- src/drivers/azure-app-configuration.ts | 1 + src/drivers/azure-cosmos.ts | 1 + src/drivers/azure-key-vault.ts | 1 + src/drivers/azure-storage-blob.ts | 1 + src/drivers/azure-storage-table.ts | 1 + src/drivers/capacitor-preferences.ts | 3 ++- src/drivers/cloudflare-kv-binding.ts | 1 + src/drivers/cloudflare-kv-http.ts | 1 + src/drivers/cloudflare-r2-binding.ts | 1 + src/drivers/fs-lite.ts | 1 + src/drivers/fs.ts | 1 + src/drivers/github.ts | 1 + src/drivers/http.ts | 1 + src/drivers/indexedb.ts | 9 ++++++--- src/drivers/localstorage.ts | 1 + src/drivers/lru-cache.ts | 1 + src/drivers/memory.ts | 3 ++- src/drivers/mongodb.ts | 1 + src/drivers/netlify-blobs.ts | 1 + src/drivers/overlay.ts | 1 + src/drivers/planetscale.ts | 1 + src/drivers/redis.ts | 3 ++- src/drivers/session-storage.ts | 1 + src/drivers/utils/index.ts | 10 ++++++---- src/drivers/vercel-kv.ts | 3 ++- src/storage.ts | 10 +++++----- src/types.ts | 3 ++- test/drivers/redis.test.ts | 18 ++++++++++++------ test/drivers/utils.ts | 2 +- 30 files changed, 62 insertions(+), 27 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4d9dad0d..d82ca370 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -26,6 +26,9 @@ importers: lru-cache: specifier: ^10.2.2 version: 10.2.2 + mongodb: + specifier: ^6.6.1 + version: 6.6.1(socks@2.8.3) mri: specifier: ^1.2.0 version: 1.2.0 @@ -129,9 +132,6 @@ importers: monaco-editor: specifier: ^0.48.0 version: 0.48.0 - mongodb: - specifier: ^6.6.1 - version: 6.6.1(socks@2.8.3) mongodb-memory-server: specifier: ^9.2.0 version: 9.2.0 diff --git a/src/drivers/azure-app-configuration.ts b/src/drivers/azure-app-configuration.ts index 934df463..7ddabc7e 100644 --- a/src/drivers/azure-app-configuration.ts +++ b/src/drivers/azure-app-configuration.ts @@ -68,6 +68,7 @@ export default defineDriver((opts: AzureAppConfigurationOptions = {}) => { return { name: DRIVER_NAME, options: opts, + instance: getClient(), async hasItem(key) { try { await getClient().getConfigurationSetting({ diff --git a/src/drivers/azure-cosmos.ts b/src/drivers/azure-cosmos.ts index f4920cf9..908da8e5 100644 --- a/src/drivers/azure-cosmos.ts +++ b/src/drivers/azure-cosmos.ts @@ -86,6 +86,7 @@ export default defineDriver((opts: AzureCosmosOptions) => { return { name: DRIVER_NAME, options: opts, + instance: getCosmosClient(), async hasItem(key) { const item = await (await getCosmosClient()) .item(key) diff --git a/src/drivers/azure-key-vault.ts b/src/drivers/azure-key-vault.ts index be53d1a6..ec4d1015 100644 --- a/src/drivers/azure-key-vault.ts +++ b/src/drivers/azure-key-vault.ts @@ -45,6 +45,7 @@ export default defineDriver((opts: AzureKeyVaultOptions) => { return { name: DRIVER_NAME, options: opts, + instance: getKeyVaultClient(), async hasItem(key) { try { await getKeyVaultClient().getSecret(encode(key)); diff --git a/src/drivers/azure-storage-blob.ts b/src/drivers/azure-storage-blob.ts index a872980c..f088f4ad 100644 --- a/src/drivers/azure-storage-blob.ts +++ b/src/drivers/azure-storage-blob.ts @@ -81,6 +81,7 @@ export default defineDriver((opts: AzureStorageBlobOptions) => { return { name: DRIVER_NAME, options: opts, + instance: getContainerClient(), async hasItem(key) { return await getContainerClient().getBlockBlobClient(key).exists(); }, diff --git a/src/drivers/azure-storage-table.ts b/src/drivers/azure-storage-table.ts index 29307117..8ac8eeba 100644 --- a/src/drivers/azure-storage-table.ts +++ b/src/drivers/azure-storage-table.ts @@ -105,6 +105,7 @@ export default defineDriver((opts: AzureStorageTableOptions) => { return { name: DRIVER_NAME, options: opts, + instance: getClient(), async hasItem(key) { try { await getClient().getEntity(partitionKey, key); diff --git a/src/drivers/capacitor-preferences.ts b/src/drivers/capacitor-preferences.ts index c46db61a..91b8d1cf 100644 --- a/src/drivers/capacitor-preferences.ts +++ b/src/drivers/capacitor-preferences.ts @@ -8,13 +8,14 @@ export interface CapacitorPreferencesOptions { base?: string; } -export default defineDriver((opts) => { +export default defineDriver((opts) => { const base = normalizeKey(opts?.base || ""); const resolveKey = (key: string) => joinKeys(base, key); return { name: DRIVER_NAME, options: opts, + instance: Preferences, hasItem(key) { return Preferences.keys().then((r) => r.keys.includes(resolveKey(key))); }, diff --git a/src/drivers/cloudflare-kv-binding.ts b/src/drivers/cloudflare-kv-binding.ts index 22d9ca20..7fde02de 100644 --- a/src/drivers/cloudflare-kv-binding.ts +++ b/src/drivers/cloudflare-kv-binding.ts @@ -25,6 +25,7 @@ export default defineDriver((opts: KVOptions) => { return { name: DRIVER_NAME, options: opts, + instance: getKVBinding(opts.binding), async hasItem(key) { key = r(key); const binding = getKVBinding(opts.binding); diff --git a/src/drivers/cloudflare-kv-http.ts b/src/drivers/cloudflare-kv-http.ts index 7a54414b..966338c5 100644 --- a/src/drivers/cloudflare-kv-http.ts +++ b/src/drivers/cloudflare-kv-http.ts @@ -206,6 +206,7 @@ export default defineDriver((opts) => { return { name: DRIVER_NAME, options: opts, + instance: undefined, hasItem, getItem, setItem, diff --git a/src/drivers/cloudflare-r2-binding.ts b/src/drivers/cloudflare-r2-binding.ts index 8e56a1f7..973fd216 100644 --- a/src/drivers/cloudflare-r2-binding.ts +++ b/src/drivers/cloudflare-r2-binding.ts @@ -25,6 +25,7 @@ export default defineDriver((opts: CloudflareR2Options = {}) => { return { name: DRIVER_NAME, options: opts, + instance: getR2Binding(opts.binding), async hasItem(key) { key = r(key); const binding = getR2Binding(opts.binding); diff --git a/src/drivers/fs-lite.ts b/src/drivers/fs-lite.ts index 87e79171..bd749597 100644 --- a/src/drivers/fs-lite.ts +++ b/src/drivers/fs-lite.ts @@ -40,6 +40,7 @@ export default defineDriver((opts: FSStorageOptions = {}) => { return { name: DRIVER_NAME, options: opts, + instance: undefined, hasItem(key) { return existsSync(r(key)); }, diff --git a/src/drivers/fs.ts b/src/drivers/fs.ts index 519e67c6..c484ba9b 100644 --- a/src/drivers/fs.ts +++ b/src/drivers/fs.ts @@ -55,6 +55,7 @@ export default defineDriver((opts: FSStorageOptions = {}) => { return { name: DRIVER_NAME, options: opts, + instance: undefined, hasItem(key) { return existsSync(r(key)); }, diff --git a/src/drivers/github.ts b/src/drivers/github.ts index b886afa8..a1b7a8e6 100644 --- a/src/drivers/github.ts +++ b/src/drivers/github.ts @@ -84,6 +84,7 @@ export default defineDriver((_opts) => { return { name: DRIVER_NAME, options: opts, + instance: undefined, async getKeys() { await syncFiles(); return Object.keys(files); diff --git a/src/drivers/http.ts b/src/drivers/http.ts index 8ede6986..2b4063e3 100644 --- a/src/drivers/http.ts +++ b/src/drivers/http.ts @@ -25,6 +25,7 @@ export default defineDriver((opts: HTTPOptions) => { return { name: DRIVER_NAME, options: opts, + instance: undefined, hasItem(key, topts) { return _fetch(r(key), { method: "HEAD", diff --git a/src/drivers/indexedb.ts b/src/drivers/indexedb.ts index 70d74242..7ad1bc5d 100644 --- a/src/drivers/indexedb.ts +++ b/src/drivers/indexedb.ts @@ -1,13 +1,15 @@ import { defineDriver } from "./utils"; -import { +import * as IdbKeyval from 'idb-keyval' +import type { UseStore } from "idb-keyval"; + +const { get, set, clear, del, keys, createStore, - type UseStore, -} from "idb-keyval"; +} = IdbKeyval; export interface IDBKeyvalOptions { base?: string; @@ -29,6 +31,7 @@ export default defineDriver((opts: IDBKeyvalOptions = {}) => { return { name: DRIVER_NAME, options: opts, + instance: IdbKeyval, async hasItem(key) { const item = await get(makeKey(key), customStore); return item === undefined ? false : true; diff --git a/src/drivers/localstorage.ts b/src/drivers/localstorage.ts index 60e70b90..be62d52d 100644 --- a/src/drivers/localstorage.ts +++ b/src/drivers/localstorage.ts @@ -32,6 +32,7 @@ export default defineDriver((opts: LocalStorageOptions = {}) => { return { name: DRIVER_NAME, options: opts, + instance: opts.localStorage!, hasItem(key) { return Object.prototype.hasOwnProperty.call(opts.localStorage!, r(key)); }, diff --git a/src/drivers/lru-cache.ts b/src/drivers/lru-cache.ts index 6d5f5cf4..b66d7a8b 100644 --- a/src/drivers/lru-cache.ts +++ b/src/drivers/lru-cache.ts @@ -25,6 +25,7 @@ export default defineDriver((opts: LRUDriverOptions = {}) => { return { name: DRIVER_NAME, options: opts, + instance: cache, hasItem(key) { return cache.has(key); }, diff --git a/src/drivers/memory.ts b/src/drivers/memory.ts index 2cb31032..edec5a5e 100644 --- a/src/drivers/memory.ts +++ b/src/drivers/memory.ts @@ -2,11 +2,12 @@ import { defineDriver } from "./utils"; const DRIVER_NAME = "memory"; -export default defineDriver(() => { +export default defineDriver>(() => { const data = new Map(); return { name: DRIVER_NAME, + instance: data, options: {}, hasItem(key) { return data.has(key); diff --git a/src/drivers/mongodb.ts b/src/drivers/mongodb.ts index 8e43d780..a0d19e3c 100644 --- a/src/drivers/mongodb.ts +++ b/src/drivers/mongodb.ts @@ -39,6 +39,7 @@ export default defineDriver((opts: MongoDbOptions) => { return { name: DRIVER_NAME, options: opts, + instance: undefined, async hasItem(key) { const result = await getMongoCollection().findOne({ key }); return !!result; diff --git a/src/drivers/netlify-blobs.ts b/src/drivers/netlify-blobs.ts index dbf814b7..9d42badc 100644 --- a/src/drivers/netlify-blobs.ts +++ b/src/drivers/netlify-blobs.ts @@ -70,6 +70,7 @@ export default defineDriver( return { name: DRIVER_NAME, options: {}, + instance: getClient(), async hasItem(key) { return getClient().getMetadata(key).then(Boolean); }, diff --git a/src/drivers/overlay.ts b/src/drivers/overlay.ts index 84d522c5..4f7b4171 100644 --- a/src/drivers/overlay.ts +++ b/src/drivers/overlay.ts @@ -14,6 +14,7 @@ export default defineDriver((options: OverlayStorageOptions) => { return { name: DRIVER_NAME, options: options, + instance: undefined, async hasItem(key, opts) { for (const layer of options.layers) { if (await layer.hasItem(key, opts)) { diff --git a/src/drivers/planetscale.ts b/src/drivers/planetscale.ts index 76d6fb18..90448db1 100644 --- a/src/drivers/planetscale.ts +++ b/src/drivers/planetscale.ts @@ -50,6 +50,7 @@ export default defineDriver((opts: PlanetscaleDriverOptions = {}) => { return { name: DRIVER_NAME, options: opts, + instance: getConnection(), hasItem: async (key) => { const res = await getConnection().execute( `SELECT EXISTS (SELECT 1 FROM ${opts.table} WHERE id = :key) as value;`, diff --git a/src/drivers/redis.ts b/src/drivers/redis.ts index 0694ba88..6fdf609c 100644 --- a/src/drivers/redis.ts +++ b/src/drivers/redis.ts @@ -35,7 +35,7 @@ export interface RedisOptions extends _RedisOptions { const DRIVER_NAME = "redis"; -export default defineDriver((opts: RedisOptions = {}) => { +export default defineDriver((opts) => { let redisClient: Redis | Cluster; const getRedisClient = () => { if (redisClient) { @@ -58,6 +58,7 @@ export default defineDriver((opts: RedisOptions = {}) => { return { name: DRIVER_NAME, options: opts, + instance: getRedisClient(), async hasItem(key) { return Boolean(await getRedisClient().exists(p(key))); }, diff --git a/src/drivers/session-storage.ts b/src/drivers/session-storage.ts index 46e7eb1a..f511ab0b 100644 --- a/src/drivers/session-storage.ts +++ b/src/drivers/session-storage.ts @@ -32,6 +32,7 @@ export default defineDriver((opts: SessionStorageOptions = {}) => { return { name: DRIVER_NAME, options: opts, + instance: opts.sessionStorage!, hasItem(key) { return Object.prototype.hasOwnProperty.call(opts.sessionStorage, r(key)); }, diff --git a/src/drivers/utils/index.ts b/src/drivers/utils/index.ts index 86e507f0..9ea7856f 100644 --- a/src/drivers/utils/index.ts +++ b/src/drivers/utils/index.ts @@ -1,11 +1,13 @@ import type { Driver } from "../.."; -type DriverFactory = (opts: T) => Driver; +type DriverFactory = ( + opts: Opts +) => Driver; interface ErrorOptions {} -export function defineDriver( - factory: DriverFactory -): DriverFactory { +export function defineDriver( + factory: DriverFactory +): DriverFactory { return factory; } diff --git a/src/drivers/vercel-kv.ts b/src/drivers/vercel-kv.ts index e18a9bd0..fd7306ca 100644 --- a/src/drivers/vercel-kv.ts +++ b/src/drivers/vercel-kv.ts @@ -23,7 +23,7 @@ export interface VercelKVOptions extends Partial { const DRIVER_NAME = "vercel-kv"; -export default defineDriver((opts) => { +export default defineDriver((opts) => { const base = normalizeKey(opts?.base); const r = (...keys: string[]) => joinKeys(base, ...keys); @@ -63,6 +63,7 @@ export default defineDriver((opts) => { return { name: DRIVER_NAME, + instance: getClient(), hasItem(key) { return getClient().exists(r(key)).then(Boolean); }, diff --git a/src/storage.ts b/src/storage.ts index c82bf7ef..3fcdd86e 100644 --- a/src/storage.ts +++ b/src/storage.ts @@ -13,19 +13,19 @@ import { asyncCall, deserializeRaw, serializeRaw, stringify } from "./_utils"; import { normalizeKey, normalizeBaseKey, joinKeys } from "./utils"; interface StorageCTX { - mounts: Record; + mounts: Record>; mountpoints: string[]; watching: boolean; unwatch: Record; watchListeners: ((event: WatchEvent, key: string) => void)[]; } -export interface CreateStorageOptions { - driver?: Driver; +export interface CreateStorageOptions { + driver?: Driver; } -export function createStorage( - options: CreateStorageOptions = {} +export function createStorage( + options: CreateStorageOptions = {} ): Storage { const context: StorageCTX = { mounts: { "": options.driver || memory() }, diff --git a/src/types.ts b/src/types.ts index 6a57293d..207930a6 100644 --- a/src/types.ts +++ b/src/types.ts @@ -16,9 +16,10 @@ export interface StorageMeta { export type TransactionOptions = Record; -export interface Driver { +export interface Driver { name?: string; options?: any; + instance: T; hasItem: (key: string, opts: TransactionOptions) => MaybePromise; getItem: ( key: string, diff --git a/test/drivers/redis.test.ts b/test/drivers/redis.test.ts index b8e08f0f..fa27131f 100644 --- a/test/drivers/redis.test.ts +++ b/test/drivers/redis.test.ts @@ -1,17 +1,19 @@ import { describe, vi, it, expect } from "vitest"; import * as ioredis from "ioredis-mock"; -import driver from "../../src/drivers/redis"; +import redisDriver from "../../src/drivers/redis"; import { testDriver } from "./utils"; vi.mock("ioredis", () => ioredis); describe("drivers: redis", () => { + const driver = redisDriver({ + base: "test:", + url: "ioredis://localhost:6379/0", + lazyConnect: false, + }); + testDriver({ - driver: driver({ - base: "test:", - url: "ioredis://localhost:6379/0", - lazyConnect: false, - }), + driver, additionalTests() { it("verify stored keys", async () => { const client = new ioredis.default("ioredis://localhost:6379/0"); @@ -38,6 +40,10 @@ describe("drivers: redis", () => { `); await client.disconnect(); }); + + it("exposes instance", () => { + expect(driver.instance).toBeInstanceOf(ioredis.default); + }); }, }); }); diff --git a/test/drivers/utils.ts b/test/drivers/utils.ts index e4dafa2d..75a9df64 100644 --- a/test/drivers/utils.ts +++ b/test/drivers/utils.ts @@ -7,7 +7,7 @@ export interface TestContext { } export interface TestOptions { - driver: Driver; + driver: Driver; additionalTests?: (ctx: TestContext) => void; } From 42acb4791a702f4af002314aaa73037a0e488091 Mon Sep 17 00:00:00 2001 From: Ted Xu Date: Thu, 16 May 2024 17:10:33 +0800 Subject: [PATCH 02/13] chore(deps): rollback pnpm-lock.yaml --- pnpm-lock.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d82ca370..4d9dad0d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -26,9 +26,6 @@ importers: lru-cache: specifier: ^10.2.2 version: 10.2.2 - mongodb: - specifier: ^6.6.1 - version: 6.6.1(socks@2.8.3) mri: specifier: ^1.2.0 version: 1.2.0 @@ -132,6 +129,9 @@ importers: monaco-editor: specifier: ^0.48.0 version: 0.48.0 + mongodb: + specifier: ^6.6.1 + version: 6.6.1(socks@2.8.3) mongodb-memory-server: specifier: ^9.2.0 version: 9.2.0 From f60bc3c54546fd3c37fde6107530467771551c31 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Thu, 16 May 2024 09:15:18 +0000 Subject: [PATCH 03/13] chore: apply automated lint fixes --- src/drivers/capacitor-preferences.ts | 82 ++++++++++++++-------------- src/drivers/indexedb.ts | 11 +--- 2 files changed, 44 insertions(+), 49 deletions(-) diff --git a/src/drivers/capacitor-preferences.ts b/src/drivers/capacitor-preferences.ts index 91b8d1cf..93fb97c3 100644 --- a/src/drivers/capacitor-preferences.ts +++ b/src/drivers/capacitor-preferences.ts @@ -8,44 +8,46 @@ export interface CapacitorPreferencesOptions { base?: string; } -export default defineDriver((opts) => { - const base = normalizeKey(opts?.base || ""); - const resolveKey = (key: string) => joinKeys(base, key); +export default defineDriver( + (opts) => { + const base = normalizeKey(opts?.base || ""); + const resolveKey = (key: string) => joinKeys(base, key); - return { - name: DRIVER_NAME, - options: opts, - instance: Preferences, - hasItem(key) { - return Preferences.keys().then((r) => r.keys.includes(resolveKey(key))); - }, - getItem(key) { - return Preferences.get({ key: resolveKey(key) }).then((r) => r.value); - }, - getItemRaw(key) { - return Preferences.get({ key: resolveKey(key) }).then((r) => r.value); - }, - setItem(key, value) { - return Preferences.set({ key: resolveKey(key), value }); - }, - setItemRaw(key, value) { - return Preferences.set({ key: resolveKey(key), value }); - }, - removeItem(key) { - return Preferences.remove({ key: resolveKey(key) }); - }, - async getKeys() { - const { keys } = await Preferences.keys(); - return keys.map((key) => key.slice(base.length)); - }, - async clear(prefix) { - const { keys } = await Preferences.keys(); - const _prefix = resolveKey(prefix || ""); - await Promise.all( - keys - .filter((key) => key.startsWith(_prefix)) - .map((key) => Preferences.remove({ key })) - ); - }, - }; -}); + return { + name: DRIVER_NAME, + options: opts, + instance: Preferences, + hasItem(key) { + return Preferences.keys().then((r) => r.keys.includes(resolveKey(key))); + }, + getItem(key) { + return Preferences.get({ key: resolveKey(key) }).then((r) => r.value); + }, + getItemRaw(key) { + return Preferences.get({ key: resolveKey(key) }).then((r) => r.value); + }, + setItem(key, value) { + return Preferences.set({ key: resolveKey(key), value }); + }, + setItemRaw(key, value) { + return Preferences.set({ key: resolveKey(key), value }); + }, + removeItem(key) { + return Preferences.remove({ key: resolveKey(key) }); + }, + async getKeys() { + const { keys } = await Preferences.keys(); + return keys.map((key) => key.slice(base.length)); + }, + async clear(prefix) { + const { keys } = await Preferences.keys(); + const _prefix = resolveKey(prefix || ""); + await Promise.all( + keys + .filter((key) => key.startsWith(_prefix)) + .map((key) => Preferences.remove({ key })) + ); + }, + }; + } +); diff --git a/src/drivers/indexedb.ts b/src/drivers/indexedb.ts index 7ad1bc5d..df762907 100644 --- a/src/drivers/indexedb.ts +++ b/src/drivers/indexedb.ts @@ -1,15 +1,8 @@ import { defineDriver } from "./utils"; -import * as IdbKeyval from 'idb-keyval' +import * as IdbKeyval from "idb-keyval"; import type { UseStore } from "idb-keyval"; -const { - get, - set, - clear, - del, - keys, - createStore, -} = IdbKeyval; +const { get, set, clear, del, keys, createStore } = IdbKeyval; export interface IDBKeyvalOptions { base?: string; From 77e7712254295b078c4d23e1cef3700485f37db8 Mon Sep 17 00:00:00 2001 From: Ted Xu Date: Thu, 16 May 2024 17:22:25 +0800 Subject: [PATCH 04/13] fix: build err --- src/drivers/azure-cosmos.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/drivers/azure-cosmos.ts b/src/drivers/azure-cosmos.ts index 908da8e5..573a865a 100644 --- a/src/drivers/azure-cosmos.ts +++ b/src/drivers/azure-cosmos.ts @@ -86,7 +86,7 @@ export default defineDriver((opts: AzureCosmosOptions) => { return { name: DRIVER_NAME, options: opts, - instance: getCosmosClient(), + instance: getCosmosClient, async hasItem(key) { const item = await (await getCosmosClient()) .item(key) From a0c8a7b6099feb884c5a62e02c76091934b9d080 Mon Sep 17 00:00:00 2001 From: Ted Xu Date: Thu, 16 May 2024 17:37:33 +0800 Subject: [PATCH 05/13] chore: use getInstance instead of instance --- src/drivers/azure-app-configuration.ts | 2 +- src/drivers/azure-cosmos.ts | 2 +- src/drivers/azure-key-vault.ts | 2 +- src/drivers/azure-storage-blob.ts | 2 +- src/drivers/azure-storage-table.ts | 2 +- src/drivers/capacitor-preferences.ts | 85 +++++++++++++------------- src/drivers/cloudflare-kv-binding.ts | 2 +- src/drivers/cloudflare-kv-http.ts | 2 +- src/drivers/cloudflare-r2-binding.ts | 2 +- src/drivers/fs-lite.ts | 2 +- src/drivers/fs.ts | 2 +- src/drivers/github.ts | 2 +- src/drivers/http.ts | 2 +- src/drivers/indexedb.ts | 2 +- src/drivers/localstorage.ts | 2 +- src/drivers/lru-cache.ts | 2 +- src/drivers/memory.ts | 4 +- src/drivers/mongodb.ts | 2 +- src/drivers/netlify-blobs.ts | 2 +- src/drivers/overlay.ts | 2 +- src/drivers/planetscale.ts | 2 +- src/drivers/redis.ts | 4 +- src/drivers/session-storage.ts | 2 +- src/drivers/utils/index.ts | 14 +++-- src/drivers/vercel-kv.ts | 4 +- src/storage.ts | 11 ++-- src/types.ts | 4 +- test/drivers/redis.test.ts | 2 +- 28 files changed, 87 insertions(+), 81 deletions(-) diff --git a/src/drivers/azure-app-configuration.ts b/src/drivers/azure-app-configuration.ts index 7ddabc7e..6c1a86f7 100644 --- a/src/drivers/azure-app-configuration.ts +++ b/src/drivers/azure-app-configuration.ts @@ -68,7 +68,7 @@ export default defineDriver((opts: AzureAppConfigurationOptions = {}) => { return { name: DRIVER_NAME, options: opts, - instance: getClient(), + getInstance: getClient, async hasItem(key) { try { await getClient().getConfigurationSetting({ diff --git a/src/drivers/azure-cosmos.ts b/src/drivers/azure-cosmos.ts index 573a865a..9983318a 100644 --- a/src/drivers/azure-cosmos.ts +++ b/src/drivers/azure-cosmos.ts @@ -86,7 +86,7 @@ export default defineDriver((opts: AzureCosmosOptions) => { return { name: DRIVER_NAME, options: opts, - instance: getCosmosClient, + getInstance: getCosmosClient, async hasItem(key) { const item = await (await getCosmosClient()) .item(key) diff --git a/src/drivers/azure-key-vault.ts b/src/drivers/azure-key-vault.ts index ec4d1015..973f4894 100644 --- a/src/drivers/azure-key-vault.ts +++ b/src/drivers/azure-key-vault.ts @@ -45,7 +45,7 @@ export default defineDriver((opts: AzureKeyVaultOptions) => { return { name: DRIVER_NAME, options: opts, - instance: getKeyVaultClient(), + getInstance: getKeyVaultClient, async hasItem(key) { try { await getKeyVaultClient().getSecret(encode(key)); diff --git a/src/drivers/azure-storage-blob.ts b/src/drivers/azure-storage-blob.ts index f088f4ad..34623527 100644 --- a/src/drivers/azure-storage-blob.ts +++ b/src/drivers/azure-storage-blob.ts @@ -81,7 +81,7 @@ export default defineDriver((opts: AzureStorageBlobOptions) => { return { name: DRIVER_NAME, options: opts, - instance: getContainerClient(), + getInstance: getContainerClient, async hasItem(key) { return await getContainerClient().getBlockBlobClient(key).exists(); }, diff --git a/src/drivers/azure-storage-table.ts b/src/drivers/azure-storage-table.ts index 8ac8eeba..21cfbe82 100644 --- a/src/drivers/azure-storage-table.ts +++ b/src/drivers/azure-storage-table.ts @@ -105,7 +105,7 @@ export default defineDriver((opts: AzureStorageTableOptions) => { return { name: DRIVER_NAME, options: opts, - instance: getClient(), + getInstance: getClient, async hasItem(key) { try { await getClient().getEntity(partitionKey, key); diff --git a/src/drivers/capacitor-preferences.ts b/src/drivers/capacitor-preferences.ts index 93fb97c3..b000aafc 100644 --- a/src/drivers/capacitor-preferences.ts +++ b/src/drivers/capacitor-preferences.ts @@ -8,46 +8,47 @@ export interface CapacitorPreferencesOptions { base?: string; } -export default defineDriver( - (opts) => { - const base = normalizeKey(opts?.base || ""); - const resolveKey = (key: string) => joinKeys(base, key); +export default defineDriver< + CapacitorPreferencesOptions, + () => typeof Preferences +>((opts) => { + const base = normalizeKey(opts?.base || ""); + const resolveKey = (key: string) => joinKeys(base, key); - return { - name: DRIVER_NAME, - options: opts, - instance: Preferences, - hasItem(key) { - return Preferences.keys().then((r) => r.keys.includes(resolveKey(key))); - }, - getItem(key) { - return Preferences.get({ key: resolveKey(key) }).then((r) => r.value); - }, - getItemRaw(key) { - return Preferences.get({ key: resolveKey(key) }).then((r) => r.value); - }, - setItem(key, value) { - return Preferences.set({ key: resolveKey(key), value }); - }, - setItemRaw(key, value) { - return Preferences.set({ key: resolveKey(key), value }); - }, - removeItem(key) { - return Preferences.remove({ key: resolveKey(key) }); - }, - async getKeys() { - const { keys } = await Preferences.keys(); - return keys.map((key) => key.slice(base.length)); - }, - async clear(prefix) { - const { keys } = await Preferences.keys(); - const _prefix = resolveKey(prefix || ""); - await Promise.all( - keys - .filter((key) => key.startsWith(_prefix)) - .map((key) => Preferences.remove({ key })) - ); - }, - }; - } -); + return { + name: DRIVER_NAME, + options: opts, + getInstance: () => Preferences, + hasItem(key) { + return Preferences.keys().then((r) => r.keys.includes(resolveKey(key))); + }, + getItem(key) { + return Preferences.get({ key: resolveKey(key) }).then((r) => r.value); + }, + getItemRaw(key) { + return Preferences.get({ key: resolveKey(key) }).then((r) => r.value); + }, + setItem(key, value) { + return Preferences.set({ key: resolveKey(key), value }); + }, + setItemRaw(key, value) { + return Preferences.set({ key: resolveKey(key), value }); + }, + removeItem(key) { + return Preferences.remove({ key: resolveKey(key) }); + }, + async getKeys() { + const { keys } = await Preferences.keys(); + return keys.map((key) => key.slice(base.length)); + }, + async clear(prefix) { + const { keys } = await Preferences.keys(); + const _prefix = resolveKey(prefix || ""); + await Promise.all( + keys + .filter((key) => key.startsWith(_prefix)) + .map((key) => Preferences.remove({ key })) + ); + }, + }; +}); diff --git a/src/drivers/cloudflare-kv-binding.ts b/src/drivers/cloudflare-kv-binding.ts index 7fde02de..23c4a043 100644 --- a/src/drivers/cloudflare-kv-binding.ts +++ b/src/drivers/cloudflare-kv-binding.ts @@ -25,7 +25,7 @@ export default defineDriver((opts: KVOptions) => { return { name: DRIVER_NAME, options: opts, - instance: getKVBinding(opts.binding), + getInstance: () => getKVBinding(opts.binding), async hasItem(key) { key = r(key); const binding = getKVBinding(opts.binding); diff --git a/src/drivers/cloudflare-kv-http.ts b/src/drivers/cloudflare-kv-http.ts index 966338c5..31bf8bf8 100644 --- a/src/drivers/cloudflare-kv-http.ts +++ b/src/drivers/cloudflare-kv-http.ts @@ -206,7 +206,7 @@ export default defineDriver((opts) => { return { name: DRIVER_NAME, options: opts, - instance: undefined, + getInstance: undefined, hasItem, getItem, setItem, diff --git a/src/drivers/cloudflare-r2-binding.ts b/src/drivers/cloudflare-r2-binding.ts index 973fd216..49934cc4 100644 --- a/src/drivers/cloudflare-r2-binding.ts +++ b/src/drivers/cloudflare-r2-binding.ts @@ -25,7 +25,7 @@ export default defineDriver((opts: CloudflareR2Options = {}) => { return { name: DRIVER_NAME, options: opts, - instance: getR2Binding(opts.binding), + getInstance: () => getR2Binding(opts.binding), async hasItem(key) { key = r(key); const binding = getR2Binding(opts.binding); diff --git a/src/drivers/fs-lite.ts b/src/drivers/fs-lite.ts index bd749597..163e54e6 100644 --- a/src/drivers/fs-lite.ts +++ b/src/drivers/fs-lite.ts @@ -40,7 +40,7 @@ export default defineDriver((opts: FSStorageOptions = {}) => { return { name: DRIVER_NAME, options: opts, - instance: undefined, + getInstance: undefined, hasItem(key) { return existsSync(r(key)); }, diff --git a/src/drivers/fs.ts b/src/drivers/fs.ts index c484ba9b..47be9db7 100644 --- a/src/drivers/fs.ts +++ b/src/drivers/fs.ts @@ -55,7 +55,7 @@ export default defineDriver((opts: FSStorageOptions = {}) => { return { name: DRIVER_NAME, options: opts, - instance: undefined, + getInstance: undefined, hasItem(key) { return existsSync(r(key)); }, diff --git a/src/drivers/github.ts b/src/drivers/github.ts index a1b7a8e6..5c77b408 100644 --- a/src/drivers/github.ts +++ b/src/drivers/github.ts @@ -84,7 +84,7 @@ export default defineDriver((_opts) => { return { name: DRIVER_NAME, options: opts, - instance: undefined, + getInstance: undefined, async getKeys() { await syncFiles(); return Object.keys(files); diff --git a/src/drivers/http.ts b/src/drivers/http.ts index 2b4063e3..b89a4ac3 100644 --- a/src/drivers/http.ts +++ b/src/drivers/http.ts @@ -25,7 +25,7 @@ export default defineDriver((opts: HTTPOptions) => { return { name: DRIVER_NAME, options: opts, - instance: undefined, + getInstance: undefined, hasItem(key, topts) { return _fetch(r(key), { method: "HEAD", diff --git a/src/drivers/indexedb.ts b/src/drivers/indexedb.ts index df762907..af8edd3e 100644 --- a/src/drivers/indexedb.ts +++ b/src/drivers/indexedb.ts @@ -24,7 +24,7 @@ export default defineDriver((opts: IDBKeyvalOptions = {}) => { return { name: DRIVER_NAME, options: opts, - instance: IdbKeyval, + getInstance: () => IdbKeyval, async hasItem(key) { const item = await get(makeKey(key), customStore); return item === undefined ? false : true; diff --git a/src/drivers/localstorage.ts b/src/drivers/localstorage.ts index be62d52d..5f1120a7 100644 --- a/src/drivers/localstorage.ts +++ b/src/drivers/localstorage.ts @@ -32,7 +32,7 @@ export default defineDriver((opts: LocalStorageOptions = {}) => { return { name: DRIVER_NAME, options: opts, - instance: opts.localStorage!, + getInstance: () => opts.localStorage!, hasItem(key) { return Object.prototype.hasOwnProperty.call(opts.localStorage!, r(key)); }, diff --git a/src/drivers/lru-cache.ts b/src/drivers/lru-cache.ts index b66d7a8b..294bea8a 100644 --- a/src/drivers/lru-cache.ts +++ b/src/drivers/lru-cache.ts @@ -25,7 +25,7 @@ export default defineDriver((opts: LRUDriverOptions = {}) => { return { name: DRIVER_NAME, options: opts, - instance: cache, + getInstance: () => cache, hasItem(key) { return cache.has(key); }, diff --git a/src/drivers/memory.ts b/src/drivers/memory.ts index edec5a5e..ea83b915 100644 --- a/src/drivers/memory.ts +++ b/src/drivers/memory.ts @@ -2,12 +2,12 @@ import { defineDriver } from "./utils"; const DRIVER_NAME = "memory"; -export default defineDriver>(() => { +export default defineDriver Map>(() => { const data = new Map(); return { name: DRIVER_NAME, - instance: data, + getInstance: () => data, options: {}, hasItem(key) { return data.has(key); diff --git a/src/drivers/mongodb.ts b/src/drivers/mongodb.ts index a0d19e3c..ae574648 100644 --- a/src/drivers/mongodb.ts +++ b/src/drivers/mongodb.ts @@ -39,7 +39,7 @@ export default defineDriver((opts: MongoDbOptions) => { return { name: DRIVER_NAME, options: opts, - instance: undefined, + getInstance: getMongoCollection, async hasItem(key) { const result = await getMongoCollection().findOne({ key }); return !!result; diff --git a/src/drivers/netlify-blobs.ts b/src/drivers/netlify-blobs.ts index 9d42badc..fe91a907 100644 --- a/src/drivers/netlify-blobs.ts +++ b/src/drivers/netlify-blobs.ts @@ -70,7 +70,7 @@ export default defineDriver( return { name: DRIVER_NAME, options: {}, - instance: getClient(), + getInstance: getClient, async hasItem(key) { return getClient().getMetadata(key).then(Boolean); }, diff --git a/src/drivers/overlay.ts b/src/drivers/overlay.ts index 4f7b4171..1bbd81e6 100644 --- a/src/drivers/overlay.ts +++ b/src/drivers/overlay.ts @@ -14,7 +14,7 @@ export default defineDriver((options: OverlayStorageOptions) => { return { name: DRIVER_NAME, options: options, - instance: undefined, + getInstance: undefined, async hasItem(key, opts) { for (const layer of options.layers) { if (await layer.hasItem(key, opts)) { diff --git a/src/drivers/planetscale.ts b/src/drivers/planetscale.ts index 90448db1..7f145db3 100644 --- a/src/drivers/planetscale.ts +++ b/src/drivers/planetscale.ts @@ -50,7 +50,7 @@ export default defineDriver((opts: PlanetscaleDriverOptions = {}) => { return { name: DRIVER_NAME, options: opts, - instance: getConnection(), + getInstance: getConnection, hasItem: async (key) => { const res = await getConnection().execute( `SELECT EXISTS (SELECT 1 FROM ${opts.table} WHERE id = :key) as value;`, diff --git a/src/drivers/redis.ts b/src/drivers/redis.ts index 6fdf609c..373429d2 100644 --- a/src/drivers/redis.ts +++ b/src/drivers/redis.ts @@ -35,7 +35,7 @@ export interface RedisOptions extends _RedisOptions { const DRIVER_NAME = "redis"; -export default defineDriver((opts) => { +export default defineDriver Redis | Cluster>((opts) => { let redisClient: Redis | Cluster; const getRedisClient = () => { if (redisClient) { @@ -58,7 +58,7 @@ export default defineDriver((opts) => { return { name: DRIVER_NAME, options: opts, - instance: getRedisClient(), + getInstance: getRedisClient, async hasItem(key) { return Boolean(await getRedisClient().exists(p(key))); }, diff --git a/src/drivers/session-storage.ts b/src/drivers/session-storage.ts index f511ab0b..b5adfd15 100644 --- a/src/drivers/session-storage.ts +++ b/src/drivers/session-storage.ts @@ -32,7 +32,7 @@ export default defineDriver((opts: SessionStorageOptions = {}) => { return { name: DRIVER_NAME, options: opts, - instance: opts.sessionStorage!, + getInstance: () => opts.sessionStorage!, hasItem(key) { return Object.prototype.hasOwnProperty.call(opts.sessionStorage, r(key)); }, diff --git a/src/drivers/utils/index.ts b/src/drivers/utils/index.ts index 9ea7856f..fa75a1f0 100644 --- a/src/drivers/utils/index.ts +++ b/src/drivers/utils/index.ts @@ -1,13 +1,15 @@ import type { Driver } from "../.."; -type DriverFactory = ( - opts: Opts -) => Driver; +type DriverFactory< + Opts, + Instance extends undefined | (() => any) = undefined, +> = (opts: Opts) => Driver; interface ErrorOptions {} -export function defineDriver( - factory: DriverFactory -): DriverFactory { +export function defineDriver< + Opts = any, + Instance extends undefined | (() => any) = undefined, +>(factory: DriverFactory): DriverFactory { return factory; } diff --git a/src/drivers/vercel-kv.ts b/src/drivers/vercel-kv.ts index fd7306ca..8a10422b 100644 --- a/src/drivers/vercel-kv.ts +++ b/src/drivers/vercel-kv.ts @@ -23,7 +23,7 @@ export interface VercelKVOptions extends Partial { const DRIVER_NAME = "vercel-kv"; -export default defineDriver((opts) => { +export default defineDriver VercelKV>((opts) => { const base = normalizeKey(opts?.base); const r = (...keys: string[]) => joinKeys(base, ...keys); @@ -63,7 +63,7 @@ export default defineDriver((opts) => { return { name: DRIVER_NAME, - instance: getClient(), + getInstance: getClient, hasItem(key) { return getClient().exists(r(key)).then(Boolean); }, diff --git a/src/storage.ts b/src/storage.ts index 3fcdd86e..94f1d0e2 100644 --- a/src/storage.ts +++ b/src/storage.ts @@ -20,13 +20,16 @@ interface StorageCTX { watchListeners: ((event: WatchEvent, key: string) => void)[]; } -export interface CreateStorageOptions { +export interface CreateStorageOptions< + Instance extends undefined | (() => any) = undefined, +> { driver?: Driver; } -export function createStorage( - options: CreateStorageOptions = {} -): Storage { +export function createStorage< + T extends StorageValue, + Instance extends undefined | (() => any) = undefined, +>(options: CreateStorageOptions = {}): Storage { const context: StorageCTX = { mounts: { "": options.driver || memory() }, mountpoints: [""], diff --git a/src/types.ts b/src/types.ts index 207930a6..47b1278d 100644 --- a/src/types.ts +++ b/src/types.ts @@ -16,10 +16,10 @@ export interface StorageMeta { export type TransactionOptions = Record; -export interface Driver { +export interface Driver any) = undefined> { name?: string; options?: any; - instance: T; + getInstance: T; hasItem: (key: string, opts: TransactionOptions) => MaybePromise; getItem: ( key: string, diff --git a/test/drivers/redis.test.ts b/test/drivers/redis.test.ts index fa27131f..6b563716 100644 --- a/test/drivers/redis.test.ts +++ b/test/drivers/redis.test.ts @@ -42,7 +42,7 @@ describe("drivers: redis", () => { }); it("exposes instance", () => { - expect(driver.instance).toBeInstanceOf(ioredis.default); + expect(driver.getInstance()).toBeInstanceOf(ioredis.default); }); }, }); From 1744ef50d4c8cdf20e984c07f61d5922815f8857 Mon Sep 17 00:00:00 2001 From: Ted Xu Date: Thu, 16 May 2024 18:09:18 +0800 Subject: [PATCH 06/13] chore: remove all unused getInstance properties in drivers + improve type --- src/drivers/cloudflare-kv-http.ts | 1 - src/drivers/fs-lite.ts | 1 - src/drivers/fs.ts | 1 - src/drivers/github.ts | 1 - src/drivers/http.ts | 1 - src/drivers/indexedb.ts | 14 +++++++++----- src/drivers/overlay.ts | 1 - src/drivers/utils/index.ts | 12 ++++-------- src/storage.ts | 11 ++++------- src/types.ts | 4 ++-- 10 files changed, 19 insertions(+), 28 deletions(-) diff --git a/src/drivers/cloudflare-kv-http.ts b/src/drivers/cloudflare-kv-http.ts index 31bf8bf8..7a54414b 100644 --- a/src/drivers/cloudflare-kv-http.ts +++ b/src/drivers/cloudflare-kv-http.ts @@ -206,7 +206,6 @@ export default defineDriver((opts) => { return { name: DRIVER_NAME, options: opts, - getInstance: undefined, hasItem, getItem, setItem, diff --git a/src/drivers/fs-lite.ts b/src/drivers/fs-lite.ts index 163e54e6..87e79171 100644 --- a/src/drivers/fs-lite.ts +++ b/src/drivers/fs-lite.ts @@ -40,7 +40,6 @@ export default defineDriver((opts: FSStorageOptions = {}) => { return { name: DRIVER_NAME, options: opts, - getInstance: undefined, hasItem(key) { return existsSync(r(key)); }, diff --git a/src/drivers/fs.ts b/src/drivers/fs.ts index 47be9db7..519e67c6 100644 --- a/src/drivers/fs.ts +++ b/src/drivers/fs.ts @@ -55,7 +55,6 @@ export default defineDriver((opts: FSStorageOptions = {}) => { return { name: DRIVER_NAME, options: opts, - getInstance: undefined, hasItem(key) { return existsSync(r(key)); }, diff --git a/src/drivers/github.ts b/src/drivers/github.ts index 5c77b408..b886afa8 100644 --- a/src/drivers/github.ts +++ b/src/drivers/github.ts @@ -84,7 +84,6 @@ export default defineDriver((_opts) => { return { name: DRIVER_NAME, options: opts, - getInstance: undefined, async getKeys() { await syncFiles(); return Object.keys(files); diff --git a/src/drivers/http.ts b/src/drivers/http.ts index b89a4ac3..8ede6986 100644 --- a/src/drivers/http.ts +++ b/src/drivers/http.ts @@ -25,7 +25,6 @@ export default defineDriver((opts: HTTPOptions) => { return { name: DRIVER_NAME, options: opts, - getInstance: undefined, hasItem(key, topts) { return _fetch(r(key), { method: "HEAD", diff --git a/src/drivers/indexedb.ts b/src/drivers/indexedb.ts index af8edd3e..70d74242 100644 --- a/src/drivers/indexedb.ts +++ b/src/drivers/indexedb.ts @@ -1,8 +1,13 @@ import { defineDriver } from "./utils"; -import * as IdbKeyval from "idb-keyval"; -import type { UseStore } from "idb-keyval"; - -const { get, set, clear, del, keys, createStore } = IdbKeyval; +import { + get, + set, + clear, + del, + keys, + createStore, + type UseStore, +} from "idb-keyval"; export interface IDBKeyvalOptions { base?: string; @@ -24,7 +29,6 @@ export default defineDriver((opts: IDBKeyvalOptions = {}) => { return { name: DRIVER_NAME, options: opts, - getInstance: () => IdbKeyval, async hasItem(key) { const item = await get(makeKey(key), customStore); return item === undefined ? false : true; diff --git a/src/drivers/overlay.ts b/src/drivers/overlay.ts index 1bbd81e6..84d522c5 100644 --- a/src/drivers/overlay.ts +++ b/src/drivers/overlay.ts @@ -14,7 +14,6 @@ export default defineDriver((options: OverlayStorageOptions) => { return { name: DRIVER_NAME, options: options, - getInstance: undefined, async hasItem(key, opts) { for (const layer of options.layers) { if (await layer.hasItem(key, opts)) { diff --git a/src/drivers/utils/index.ts b/src/drivers/utils/index.ts index fa75a1f0..ed3b39bb 100644 --- a/src/drivers/utils/index.ts +++ b/src/drivers/utils/index.ts @@ -1,15 +1,11 @@ import type { Driver } from "../.."; -type DriverFactory< - Opts, - Instance extends undefined | (() => any) = undefined, -> = (opts: Opts) => Driver; +type DriverFactory = (opts: Opts) => Driver; interface ErrorOptions {} -export function defineDriver< - Opts = any, - Instance extends undefined | (() => any) = undefined, ->(factory: DriverFactory): DriverFactory { +export function defineDriver( + factory: DriverFactory +): DriverFactory { return factory; } diff --git a/src/storage.ts b/src/storage.ts index 94f1d0e2..3fcdd86e 100644 --- a/src/storage.ts +++ b/src/storage.ts @@ -20,16 +20,13 @@ interface StorageCTX { watchListeners: ((event: WatchEvent, key: string) => void)[]; } -export interface CreateStorageOptions< - Instance extends undefined | (() => any) = undefined, -> { +export interface CreateStorageOptions { driver?: Driver; } -export function createStorage< - T extends StorageValue, - Instance extends undefined | (() => any) = undefined, ->(options: CreateStorageOptions = {}): Storage { +export function createStorage( + options: CreateStorageOptions = {} +): Storage { const context: StorageCTX = { mounts: { "": options.driver || memory() }, mountpoints: [""], diff --git a/src/types.ts b/src/types.ts index 47b1278d..31c54f50 100644 --- a/src/types.ts +++ b/src/types.ts @@ -16,10 +16,10 @@ export interface StorageMeta { export type TransactionOptions = Record; -export interface Driver any) = undefined> { +export interface Driver { name?: string; options?: any; - getInstance: T; + getInstance?: T; hasItem: (key: string, opts: TransactionOptions) => MaybePromise; getItem: ( key: string, From 0bd177b859f97893c8d994a308310c32367c27ac Mon Sep 17 00:00:00 2001 From: Hash Brown Date: Thu, 16 May 2024 19:50:07 +0800 Subject: [PATCH 07/13] Update test/drivers/utils.ts Co-authored-by: Pooya Parsa --- test/drivers/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/drivers/utils.ts b/test/drivers/utils.ts index 75a9df64..e4dafa2d 100644 --- a/test/drivers/utils.ts +++ b/test/drivers/utils.ts @@ -7,7 +7,7 @@ export interface TestContext { } export interface TestOptions { - driver: Driver; + driver: Driver; additionalTests?: (ctx: TestContext) => void; } From b6d98c47e0e1e4975fb08b0e33376d6201fcbad0 Mon Sep 17 00:00:00 2001 From: Ted Xu Date: Thu, 16 May 2024 19:53:59 +0800 Subject: [PATCH 08/13] chore: improve `Driver` type --- src/drivers/capacitor-preferences.ts | 85 +++++++++-------- src/drivers/memory.ts | 4 +- src/drivers/netlify-blobs.ts | 133 +++++++++++++-------------- src/drivers/redis.ts | 2 +- src/drivers/utils/index.ts | 10 +- src/drivers/vercel-kv.ts | 6 +- src/types.ts | 6 +- 7 files changed, 124 insertions(+), 122 deletions(-) diff --git a/src/drivers/capacitor-preferences.ts b/src/drivers/capacitor-preferences.ts index b000aafc..aade7a8c 100644 --- a/src/drivers/capacitor-preferences.ts +++ b/src/drivers/capacitor-preferences.ts @@ -8,47 +8,46 @@ export interface CapacitorPreferencesOptions { base?: string; } -export default defineDriver< - CapacitorPreferencesOptions, - () => typeof Preferences ->((opts) => { - const base = normalizeKey(opts?.base || ""); - const resolveKey = (key: string) => joinKeys(base, key); +export default defineDriver( + (opts) => { + const base = normalizeKey(opts?.base || ""); + const resolveKey = (key: string) => joinKeys(base, key); - return { - name: DRIVER_NAME, - options: opts, - getInstance: () => Preferences, - hasItem(key) { - return Preferences.keys().then((r) => r.keys.includes(resolveKey(key))); - }, - getItem(key) { - return Preferences.get({ key: resolveKey(key) }).then((r) => r.value); - }, - getItemRaw(key) { - return Preferences.get({ key: resolveKey(key) }).then((r) => r.value); - }, - setItem(key, value) { - return Preferences.set({ key: resolveKey(key), value }); - }, - setItemRaw(key, value) { - return Preferences.set({ key: resolveKey(key), value }); - }, - removeItem(key) { - return Preferences.remove({ key: resolveKey(key) }); - }, - async getKeys() { - const { keys } = await Preferences.keys(); - return keys.map((key) => key.slice(base.length)); - }, - async clear(prefix) { - const { keys } = await Preferences.keys(); - const _prefix = resolveKey(prefix || ""); - await Promise.all( - keys - .filter((key) => key.startsWith(_prefix)) - .map((key) => Preferences.remove({ key })) - ); - }, - }; -}); + return { + name: DRIVER_NAME, + options: opts, + getInstance: () => Preferences, + hasItem(key) { + return Preferences.keys().then((r) => r.keys.includes(resolveKey(key))); + }, + getItem(key) { + return Preferences.get({ key: resolveKey(key) }).then((r) => r.value); + }, + getItemRaw(key) { + return Preferences.get({ key: resolveKey(key) }).then((r) => r.value); + }, + setItem(key, value) { + return Preferences.set({ key: resolveKey(key), value }); + }, + setItemRaw(key, value) { + return Preferences.set({ key: resolveKey(key), value }); + }, + removeItem(key) { + return Preferences.remove({ key: resolveKey(key) }); + }, + async getKeys() { + const { keys } = await Preferences.keys(); + return keys.map((key) => key.slice(base.length)); + }, + async clear(prefix) { + const { keys } = await Preferences.keys(); + const _prefix = resolveKey(prefix || ""); + await Promise.all( + keys + .filter((key) => key.startsWith(_prefix)) + .map((key) => Preferences.remove({ key })) + ); + }, + }; + } +); diff --git a/src/drivers/memory.ts b/src/drivers/memory.ts index ea83b915..4f3e5863 100644 --- a/src/drivers/memory.ts +++ b/src/drivers/memory.ts @@ -2,13 +2,13 @@ import { defineDriver } from "./utils"; const DRIVER_NAME = "memory"; -export default defineDriver Map>(() => { +export default defineDriver>(() => { const data = new Map(); return { name: DRIVER_NAME, getInstance: () => data, - options: {}, + options: undefined, hasItem(key) { return data.has(key); }, diff --git a/src/drivers/netlify-blobs.ts b/src/drivers/netlify-blobs.ts index fe91a907..62d713ed 100644 --- a/src/drivers/netlify-blobs.ts +++ b/src/drivers/netlify-blobs.ts @@ -42,74 +42,73 @@ export type NetlifyStoreOptions = | NetlifyDeployStoreOptions | NetlifyNamedStoreOptions; -export default defineDriver( - ({ deployScoped, name, ...opts }: NetlifyStoreOptions) => { - let store: Store; +export default defineDriver((options: NetlifyStoreOptions) => { + const { deployScoped, name, ...opts } = options; + let store: Store; - const getClient = () => { - if (!store) { - if (deployScoped) { - if (name) { - throw createError( - DRIVER_NAME, - "deploy-scoped stores cannot have a name" - ); - } - store = getDeployStore({ fetch, ...opts }); - } else { - if (!name) { - throw createRequiredError(DRIVER_NAME, "name"); - } - // Ensures that reserved characters are encoded - store = getStore({ name: encodeURIComponent(name), fetch, ...opts }); + const getClient = () => { + if (!store) { + if (deployScoped) { + if (name) { + throw createError( + DRIVER_NAME, + "deploy-scoped stores cannot have a name" + ); } + store = getDeployStore({ fetch, ...options }); + } else { + if (!name) { + throw createRequiredError(DRIVER_NAME, "name"); + } + // Ensures that reserved characters are encoded + store = getStore({ name: encodeURIComponent(name), fetch, ...opts }); } - return store; - }; + } + return store; + }; - return { - name: DRIVER_NAME, - options: {}, - getInstance: getClient, - async hasItem(key) { - return getClient().getMetadata(key).then(Boolean); - }, - getItem: (key, tops?: GetOptions) => { - // @ts-expect-error has trouble with the overloaded types - return getClient().get(key, tops); - }, - getMeta(key) { - return getClient().getMetadata(key); - }, - getItemRaw(key, topts?: GetOptions) { - // @ts-expect-error has trouble with the overloaded types - return getClient().get(key, { type: topts?.type ?? "arrayBuffer" }); - }, - setItem(key, value, topts?: SetOptions) { - return getClient().set(key, value, topts); - }, - setItemRaw(key, value: string | ArrayBuffer | Blob, topts?: SetOptions) { - return getClient().set(key, value, topts); - }, - removeItem(key) { - return getClient().delete(key); - }, - async getKeys( - base?: string, - tops?: Omit - ) { - return (await getClient().list({ ...tops, prefix: base })).blobs.map( - (item) => item.key - ); - }, - async clear(base?: string) { - const client = getClient(); - return Promise.allSettled( - (await client.list({ prefix: base })).blobs.map((item) => - client.delete(item.key) - ) - ).then(() => {}); - }, - }; - } -); + return { + name: DRIVER_NAME, + options, + getInstance: getClient, + async hasItem(key) { + return getClient().getMetadata(key).then(Boolean); + }, + getItem: (key, tops?: GetOptions) => { + // @ts-expect-error has trouble with the overloaded types + return getClient().get(key, tops); + }, + getMeta(key) { + return getClient().getMetadata(key); + }, + getItemRaw(key, topts?: GetOptions) { + // @ts-expect-error has trouble with the overloaded types + return getClient().get(key, { type: topts?.type ?? "arrayBuffer" }); + }, + setItem(key, value, topts?: SetOptions) { + return getClient().set(key, value, topts); + }, + setItemRaw(key, value: string | ArrayBuffer | Blob, topts?: SetOptions) { + return getClient().set(key, value, topts); + }, + removeItem(key) { + return getClient().delete(key); + }, + async getKeys( + base?: string, + tops?: Omit + ) { + return (await getClient().list({ ...tops, prefix: base })).blobs.map( + (item) => item.key + ); + }, + async clear(base?: string) { + const client = getClient(); + return Promise.allSettled( + (await client.list({ prefix: base })).blobs.map((item) => + client.delete(item.key) + ) + ).then(() => {}); + }, + }; +}); diff --git a/src/drivers/redis.ts b/src/drivers/redis.ts index 373429d2..aee7444a 100644 --- a/src/drivers/redis.ts +++ b/src/drivers/redis.ts @@ -35,7 +35,7 @@ export interface RedisOptions extends _RedisOptions { const DRIVER_NAME = "redis"; -export default defineDriver Redis | Cluster>((opts) => { +export default defineDriver((opts: RedisOptions) => { let redisClient: Redis | Cluster; const getRedisClient = () => { if (redisClient) { diff --git a/src/drivers/utils/index.ts b/src/drivers/utils/index.ts index ed3b39bb..7cccdc2c 100644 --- a/src/drivers/utils/index.ts +++ b/src/drivers/utils/index.ts @@ -1,11 +1,13 @@ import type { Driver } from "../.."; -type DriverFactory = (opts: Opts) => Driver; +type DriverFactory = ( + opts: OptionsT +) => Driver; interface ErrorOptions {} -export function defineDriver( - factory: DriverFactory -): DriverFactory { +export function defineDriver( + factory: DriverFactory +): DriverFactory { return factory; } diff --git a/src/drivers/vercel-kv.ts b/src/drivers/vercel-kv.ts index 8a10422b..c151e5b7 100644 --- a/src/drivers/vercel-kv.ts +++ b/src/drivers/vercel-kv.ts @@ -23,7 +23,7 @@ export interface VercelKVOptions extends Partial { const DRIVER_NAME = "vercel-kv"; -export default defineDriver VercelKV>((opts) => { +export default defineDriver((opts) => { const base = normalizeKey(opts?.base); const r = (...keys: string[]) => joinKeys(base, ...keys); @@ -56,7 +56,9 @@ export default defineDriver VercelKV>((opts) => { ); } } - _client = createClient(opts as RedisConfigNodejs); + _client = createClient( + opts as VercelKVOptions & { url: string; token: string } + ); } return _client; }; diff --git a/src/types.ts b/src/types.ts index 31c54f50..b408bbd7 100644 --- a/src/types.ts +++ b/src/types.ts @@ -16,10 +16,10 @@ export interface StorageMeta { export type TransactionOptions = Record; -export interface Driver { +export interface Driver { name?: string; - options?: any; - getInstance?: T; + options?: OptionsT; + getInstance?: () => InstanceT; hasItem: (key: string, opts: TransactionOptions) => MaybePromise; getItem: ( key: string, From e3cb6845e4f76592f2fe386fed11782f833a82f6 Mon Sep 17 00:00:00 2001 From: Ted Xu Date: Thu, 16 May 2024 20:02:09 +0800 Subject: [PATCH 09/13] chore: revert changes to `src/storage.ts` --- src/storage.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/storage.ts b/src/storage.ts index 3fcdd86e..c82bf7ef 100644 --- a/src/storage.ts +++ b/src/storage.ts @@ -13,19 +13,19 @@ import { asyncCall, deserializeRaw, serializeRaw, stringify } from "./_utils"; import { normalizeKey, normalizeBaseKey, joinKeys } from "./utils"; interface StorageCTX { - mounts: Record>; + mounts: Record; mountpoints: string[]; watching: boolean; unwatch: Record; watchListeners: ((event: WatchEvent, key: string) => void)[]; } -export interface CreateStorageOptions { - driver?: Driver; +export interface CreateStorageOptions { + driver?: Driver; } -export function createStorage( - options: CreateStorageOptions = {} +export function createStorage( + options: CreateStorageOptions = {} ): Storage { const context: StorageCTX = { mounts: { "": options.driver || memory() }, From 96b2b12d8fbe889bd74ee00b3b92bd24dd4ff794 Mon Sep 17 00:00:00 2001 From: Hash Brown Date: Thu, 16 May 2024 20:23:54 +0800 Subject: [PATCH 10/13] Update src/drivers/utils/index.ts Co-authored-by: Pooya Parsa --- src/drivers/utils/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/drivers/utils/index.ts b/src/drivers/utils/index.ts index 7cccdc2c..0aa3a138 100644 --- a/src/drivers/utils/index.ts +++ b/src/drivers/utils/index.ts @@ -5,7 +5,7 @@ type DriverFactory = ( ) => Driver; interface ErrorOptions {} -export function defineDriver( +export function defineDriver( factory: DriverFactory ): DriverFactory { return factory; From ca9302897bac9d26e7f5e29b0a71a6193e86903c Mon Sep 17 00:00:00 2001 From: Hash Brown Date: Thu, 16 May 2024 20:24:03 +0800 Subject: [PATCH 11/13] Update src/types.ts Co-authored-by: Pooya Parsa --- src/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types.ts b/src/types.ts index b408bbd7..da2c9ebd 100644 --- a/src/types.ts +++ b/src/types.ts @@ -16,7 +16,7 @@ export interface StorageMeta { export type TransactionOptions = Record; -export interface Driver { +export interface Driver { name?: string; options?: OptionsT; getInstance?: () => InstanceT; From 256c1923653c5cc76ebc258b667e609503f867e4 Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Thu, 16 May 2024 14:34:12 +0200 Subject: [PATCH 12/13] fix type issue --- src/drivers/memory.ts | 1 - src/types.ts | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/drivers/memory.ts b/src/drivers/memory.ts index 4f3e5863..3f5601d0 100644 --- a/src/drivers/memory.ts +++ b/src/drivers/memory.ts @@ -8,7 +8,6 @@ export default defineDriver>(() => { return { name: DRIVER_NAME, getInstance: () => data, - options: undefined, hasItem(key) { return data.has(key); }, diff --git a/src/types.ts b/src/types.ts index da2c9ebd..b408bbd7 100644 --- a/src/types.ts +++ b/src/types.ts @@ -16,7 +16,7 @@ export interface StorageMeta { export type TransactionOptions = Record; -export interface Driver { +export interface Driver { name?: string; options?: OptionsT; getInstance?: () => InstanceT; From aa767f5567f3de1e3e68f50a7d1dc69231dba19e Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Thu, 16 May 2024 14:35:30 +0200 Subject: [PATCH 13/13] fix build issue --- build.config.ts | 1 + tsconfig.json | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/build.config.ts b/build.config.ts index e5110529..46ad68c7 100644 --- a/build.config.ts +++ b/build.config.ts @@ -21,4 +21,5 @@ export default defineBuildConfig({ declaration: false, }, ], + externals: ["mongodb"], }); diff --git a/tsconfig.json b/tsconfig.json index e9588d9f..50585e0e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,7 +4,8 @@ "module": "ESNext", "moduleResolution": "Node", "esModuleInterop": true, - "strict": true + "strict": true, + "skipLibCheck": true }, "include": ["src"] }