From c3c957a467c44b311845b8a7e48b8def0c6b66fc Mon Sep 17 00:00:00 2001 From: Dominik Opyd Date: Thu, 24 Aug 2023 22:44:57 +0200 Subject: [PATCH 1/9] refactor: move `getBindings` to utils --- .../6.drivers/cloudflare-r2-binding.md | 11 ++++-- src/drivers/cloudflare-kv-binding.ts | 31 ++--------------- src/drivers/cloudflare-r2-binding.ts | 34 ++----------------- src/drivers/utils/index.ts | 29 ++++++++++++++++ 4 files changed, 42 insertions(+), 63 deletions(-) diff --git a/docs/content/6.drivers/cloudflare-r2-binding.md b/docs/content/6.drivers/cloudflare-r2-binding.md index 31dfc1fc..1126abfc 100644 --- a/docs/content/6.drivers/cloudflare-r2-binding.md +++ b/docs/content/6.drivers/cloudflare-r2-binding.md @@ -14,16 +14,21 @@ import cloudflareR2BindingDriver from "unstorage/drivers/cloudflare-r2-binding"; // Using binding name to be picked from globalThis const storage = createStorage({ - driver: cloudflareR2BindingDriver({ binding: "MY_BUCKET" }), + driver: cloudflareR2BindingDriver({ binding: "BUCKET" }), }); // Directly setting binding const storage = createStorage({ - driver: cloudflareR2BindingDriver({ binding: globalThis.MY_BUCKET }), + driver: cloudflareR2BindingDriver({ binding: globalThis.BUCKET }), +}); + +// Using from Durable Objects and Workers using Modules Syntax +const storage = createStorage({ + driver: cloudflareR2BindingDriver({ binding: this.env.BUCKET }), }); ``` **Options:** -- `binding`: Bucket binding or name. +- `binding`: Bucket binding or name. Default is `BUCKET`. - `base`: Prefix all keys with base. diff --git a/src/drivers/cloudflare-kv-binding.ts b/src/drivers/cloudflare-kv-binding.ts index de3b83c2..d4472e0c 100644 --- a/src/drivers/cloudflare-kv-binding.ts +++ b/src/drivers/cloudflare-kv-binding.ts @@ -1,5 +1,5 @@ /// -import { createError, defineDriver, joinKeys } from "./utils"; +import { createError, defineDriver, joinKeys, getBinding } from "./utils"; export interface KVOptions { binding?: string | KVNamespace; @@ -11,7 +11,7 @@ export interface KVOptions { const DRIVER_NAME = "cloudflare-kv-binding"; -export default defineDriver((opts: KVOptions = {}) => { +export default defineDriver((opts: KVOptions = { binding: 'STORAGE' }) => { const r = (key: string = "") => (opts.base ? joinKeys(opts.base, key) : key); async function getKeys(base: string = "") { @@ -57,30 +57,3 @@ export default defineDriver((opts: KVOptions = {}) => { }; }); -function getBinding(binding: KVNamespace | string = "STORAGE") { - let bindingName = "[binding]"; - - if (typeof binding === "string") { - bindingName = binding; - binding = ((globalThis as any)[bindingName] || - (globalThis as any).__env__?.[bindingName]) as KVNamespace; - } - - if (!binding) { - throw createError( - DRIVER_NAME, - `Invalid binding \`${bindingName}\`: \`${binding}\`` - ); - } - - for (const key of ["get", "put", "delete"]) { - if (!(key in binding)) { - throw createError( - DRIVER_NAME, - `Invalid binding \`${bindingName}\`: \`${key}\` key is missing` - ); - } - } - - return binding; -} diff --git a/src/drivers/cloudflare-r2-binding.ts b/src/drivers/cloudflare-r2-binding.ts index 1a87d514..2e74746d 100644 --- a/src/drivers/cloudflare-r2-binding.ts +++ b/src/drivers/cloudflare-r2-binding.ts @@ -1,5 +1,5 @@ /// -import { createError, defineDriver, joinKeys } from "./utils"; +import { createError, defineDriver, joinKeys, getBinding } from "./utils"; export interface CloudflareR2Options { binding: string | R2Bucket; @@ -10,7 +10,7 @@ export interface CloudflareR2Options { const DRIVER_NAME = "cloudflare-r2-binding"; -export default defineDriver((opts: CloudflareR2Options) => { +export default defineDriver((opts: CloudflareR2Options = { binding: 'BUCKET' }) => { const r = (key: string = "") => (opts.base ? joinKeys(opts.base, key) : key); const getKeys = async (base?: string) => { @@ -76,32 +76,4 @@ export default defineDriver((opts: CloudflareR2Options) => { await binding.delete(keys); }, }; -}); - -function getBinding(binding: R2Bucket | string) { - let bindingName = "[binding]"; - - if (typeof binding === "string") { - bindingName = binding; - binding = ((globalThis as any)[bindingName] || - (globalThis as any).__env__?.[bindingName]) as R2Bucket; - } - - if (!binding) { - throw createError( - DRIVER_NAME, - `Invalid binding \`${bindingName}\`: \`${binding}\`` - ); - } - - for (const key of ["get", "put", "delete"]) { - if (!(key in binding)) { - throw createError( - DRIVER_NAME, - `Invalid binding \`${bindingName}\`: \`${key}\` key is missing` - ); - } - } - - return binding; -} +}); \ No newline at end of file diff --git a/src/drivers/utils/index.ts b/src/drivers/utils/index.ts index 26e00038..66e66edd 100644 --- a/src/drivers/utils/index.ts +++ b/src/drivers/utils/index.ts @@ -1,3 +1,4 @@ +/// import type { Driver } from "../../types"; type DriverFactory = (opts: T) => Driver; @@ -39,3 +40,31 @@ export function createRequiredError(driver: string, name: string | string[]) { } return createError(driver, `Missing required option \`${name}\`.`); } + +export function getBinding(binding: KVNamespace | R2Bucket | string) { + let bindingName = "[binding]"; + + if (typeof binding === "string") { + bindingName = binding; + binding = ((globalThis as any)[bindingName] || + (globalThis as any).__env__?.[bindingName]) as KVNamespace | R2Bucket; + } + + if (!binding) { + throw createError( + 'Cloudflare', + `Invalid binding \`${bindingName}\`: \`${binding}\`` + ); + } + + for (const key of ["get", "put", "delete"]) { + if (!(key in binding)) { + throw createError( + 'Cloudflare', + `Invalid binding \`${bindingName}\`: \`${key}\` key is missing` + ); + } + } + + return binding; +} \ No newline at end of file From 16ebe9b47a218133ea3b0ba3a715f6dafdb413c3 Mon Sep 17 00:00:00 2001 From: Dominik Opyd Date: Thu, 24 Aug 2023 23:35:58 +0200 Subject: [PATCH 2/9] refactor: move to `utils/cloudflare.ts' --- src/drivers/cloudflare-kv-binding.ts | 4 +++- src/drivers/cloudflare-r2-binding.ts | 5 +++-- src/drivers/utils/cloudflare.ts | 30 ++++++++++++++++++++++++++++ src/drivers/utils/index.ts | 29 --------------------------- 4 files changed, 36 insertions(+), 32 deletions(-) create mode 100644 src/drivers/utils/cloudflare.ts diff --git a/src/drivers/cloudflare-kv-binding.ts b/src/drivers/cloudflare-kv-binding.ts index d4472e0c..8724d77f 100644 --- a/src/drivers/cloudflare-kv-binding.ts +++ b/src/drivers/cloudflare-kv-binding.ts @@ -1,5 +1,7 @@ /// -import { createError, defineDriver, joinKeys, getBinding } from "./utils"; +import { getBinding } from "./utils/cloudflare"; +import { defineDriver, joinKeys } from "./utils"; + export interface KVOptions { binding?: string | KVNamespace; diff --git a/src/drivers/cloudflare-r2-binding.ts b/src/drivers/cloudflare-r2-binding.ts index 2e74746d..61463187 100644 --- a/src/drivers/cloudflare-r2-binding.ts +++ b/src/drivers/cloudflare-r2-binding.ts @@ -1,8 +1,9 @@ /// -import { createError, defineDriver, joinKeys, getBinding } from "./utils"; +import { getBinding } from "./utils/cloudflare"; +import { defineDriver, joinKeys } from "./utils"; export interface CloudflareR2Options { - binding: string | R2Bucket; + binding?: string | R2Bucket; base?: string; } diff --git a/src/drivers/utils/cloudflare.ts b/src/drivers/utils/cloudflare.ts new file mode 100644 index 00000000..e75b5ee9 --- /dev/null +++ b/src/drivers/utils/cloudflare.ts @@ -0,0 +1,30 @@ +/// +import { createError } from '.' + +export function getBinding(binding: KVNamespace | R2Bucket | string) { + let bindingName = "[binding]"; + + if (typeof binding === "string") { + bindingName = binding; + binding = ((globalThis as any)[bindingName] || + (globalThis as any).__env__?.[bindingName]) as KVNamespace | R2Bucket; + } + + if (!binding) { + throw createError( + 'Cloudflare', + `Invalid binding \`${bindingName}\`: \`${binding}\`` + ); + } + + for (const key of ["get", "put", "delete"]) { + if (!(key in binding)) { + throw createError( + 'Cloudflare', + `Invalid binding \`${bindingName}\`: \`${key}\` key is missing` + ); + } + } + + return binding; +} \ No newline at end of file diff --git a/src/drivers/utils/index.ts b/src/drivers/utils/index.ts index 66e66edd..9afda364 100644 --- a/src/drivers/utils/index.ts +++ b/src/drivers/utils/index.ts @@ -1,4 +1,3 @@ -/// import type { Driver } from "../../types"; type DriverFactory = (opts: T) => Driver; @@ -39,32 +38,4 @@ export function createRequiredError(driver: string, name: string | string[]) { ); } return createError(driver, `Missing required option \`${name}\`.`); -} - -export function getBinding(binding: KVNamespace | R2Bucket | string) { - let bindingName = "[binding]"; - - if (typeof binding === "string") { - bindingName = binding; - binding = ((globalThis as any)[bindingName] || - (globalThis as any).__env__?.[bindingName]) as KVNamespace | R2Bucket; - } - - if (!binding) { - throw createError( - 'Cloudflare', - `Invalid binding \`${bindingName}\`: \`${binding}\`` - ); - } - - for (const key of ["get", "put", "delete"]) { - if (!(key in binding)) { - throw createError( - 'Cloudflare', - `Invalid binding \`${bindingName}\`: \`${key}\` key is missing` - ); - } - } - - return binding; } \ No newline at end of file From 6df382dfabdde60fcf30892fb667e6dce51c0196 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Fri, 12 Jan 2024 11:47:40 +0000 Subject: [PATCH 3/9] chore: apply automated lint fixes --- src/drivers/cloudflare-kv-binding.ts | 3 +- src/drivers/cloudflare-r2-binding.ts | 131 ++++++++++++++------------- src/drivers/utils/cloudflare.ts | 8 +- src/drivers/utils/index.ts | 2 +- 4 files changed, 73 insertions(+), 71 deletions(-) diff --git a/src/drivers/cloudflare-kv-binding.ts b/src/drivers/cloudflare-kv-binding.ts index 8724d77f..50471d10 100644 --- a/src/drivers/cloudflare-kv-binding.ts +++ b/src/drivers/cloudflare-kv-binding.ts @@ -13,7 +13,7 @@ export interface KVOptions { const DRIVER_NAME = "cloudflare-kv-binding"; -export default defineDriver((opts: KVOptions = { binding: 'STORAGE' }) => { +export default defineDriver((opts: KVOptions = { binding: "STORAGE" }) => { const r = (key: string = "") => (opts.base ? joinKeys(opts.base, key) : key); async function getKeys(base: string = "") { @@ -58,4 +58,3 @@ export default defineDriver((opts: KVOptions = { binding: 'STORAGE' }) => { }, }; }); - diff --git a/src/drivers/cloudflare-r2-binding.ts b/src/drivers/cloudflare-r2-binding.ts index 61463187..8f9f0117 100644 --- a/src/drivers/cloudflare-r2-binding.ts +++ b/src/drivers/cloudflare-r2-binding.ts @@ -11,70 +11,73 @@ export interface CloudflareR2Options { const DRIVER_NAME = "cloudflare-r2-binding"; -export default defineDriver((opts: CloudflareR2Options = { binding: 'BUCKET' }) => { - const r = (key: string = "") => (opts.base ? joinKeys(opts.base, key) : key); +export default defineDriver( + (opts: CloudflareR2Options = { binding: "BUCKET" }) => { + const r = (key: string = "") => + opts.base ? joinKeys(opts.base, key) : key; - const getKeys = async (base?: string) => { - const binding = getBinding(opts.binding); - const kvList = await binding.list( - base || opts.base ? { prefix: r(base) } : undefined - ); - return kvList.objects.map((obj) => obj.key); - }; - - return { - name: DRIVER_NAME, - options: opts, - async hasItem(key) { - key = r(key); - const binding = getBinding(opts.binding); - return (await binding.head(key)) !== null; - }, - async getMeta(key, topts) { - key = r(key); - const binding = getBinding(opts.binding); - const obj = await binding.head(key); - if (!obj) return null; - return { - mtime: obj.uploaded, - atime: obj.uploaded, - ...obj, - }; - }, - getItem(key, topts) { - key = r(key); - const binding = getBinding(opts.binding); - return binding.get(key, topts).then((r) => r?.text()); - }, - getItemRaw(key, topts) { - key = r(key); - const binding = getBinding(opts.binding); - return binding.get(key, topts).then((r) => r?.arrayBuffer()); - }, - async setItem(key, value, topts) { - key = r(key); + const getKeys = async (base?: string) => { const binding = getBinding(opts.binding); - await binding.put(key, value, topts); - }, - async setItemRaw(key, value, topts) { - key = r(key); - const binding = getBinding(opts.binding); - await binding.put(key, value, topts); - }, - async removeItem(key) { - key = r(key); - const binding = getBinding(opts.binding); - await binding.delete(key); - }, - getKeys(base) { - return getKeys(base).then((keys) => - opts.base ? keys.map((key) => key.slice(opts.base!.length)) : keys + const kvList = await binding.list( + base || opts.base ? { prefix: r(base) } : undefined ); - }, - async clear(base) { - const binding = getBinding(opts.binding); - const keys = await getKeys(base); - await binding.delete(keys); - }, - }; -}); \ No newline at end of file + return kvList.objects.map((obj) => obj.key); + }; + + return { + name: DRIVER_NAME, + options: opts, + async hasItem(key) { + key = r(key); + const binding = getBinding(opts.binding); + return (await binding.head(key)) !== null; + }, + async getMeta(key, topts) { + key = r(key); + const binding = getBinding(opts.binding); + const obj = await binding.head(key); + if (!obj) return null; + return { + mtime: obj.uploaded, + atime: obj.uploaded, + ...obj, + }; + }, + getItem(key, topts) { + key = r(key); + const binding = getBinding(opts.binding); + return binding.get(key, topts).then((r) => r?.text()); + }, + getItemRaw(key, topts) { + key = r(key); + const binding = getBinding(opts.binding); + return binding.get(key, topts).then((r) => r?.arrayBuffer()); + }, + async setItem(key, value, topts) { + key = r(key); + const binding = getBinding(opts.binding); + await binding.put(key, value, topts); + }, + async setItemRaw(key, value, topts) { + key = r(key); + const binding = getBinding(opts.binding); + await binding.put(key, value, topts); + }, + async removeItem(key) { + key = r(key); + const binding = getBinding(opts.binding); + await binding.delete(key); + }, + getKeys(base) { + return getKeys(base).then((keys) => + opts.base ? keys.map((key) => key.slice(opts.base!.length)) : keys + ); + }, + async clear(base) { + const binding = getBinding(opts.binding); + const keys = await getKeys(base); + await binding.delete(keys); + }, + }; + } +); diff --git a/src/drivers/utils/cloudflare.ts b/src/drivers/utils/cloudflare.ts index e75b5ee9..28e2286b 100644 --- a/src/drivers/utils/cloudflare.ts +++ b/src/drivers/utils/cloudflare.ts @@ -1,5 +1,5 @@ /// -import { createError } from '.' +import { createError } from "."; export function getBinding(binding: KVNamespace | R2Bucket | string) { let bindingName = "[binding]"; @@ -12,7 +12,7 @@ export function getBinding(binding: KVNamespace | R2Bucket | string) { if (!binding) { throw createError( - 'Cloudflare', + "Cloudflare", `Invalid binding \`${bindingName}\`: \`${binding}\`` ); } @@ -20,11 +20,11 @@ export function getBinding(binding: KVNamespace | R2Bucket | string) { for (const key of ["get", "put", "delete"]) { if (!(key in binding)) { throw createError( - 'Cloudflare', + "Cloudflare", `Invalid binding \`${bindingName}\`: \`${key}\` key is missing` ); } } return binding; -} \ No newline at end of file +} diff --git a/src/drivers/utils/index.ts b/src/drivers/utils/index.ts index 9afda364..26e00038 100644 --- a/src/drivers/utils/index.ts +++ b/src/drivers/utils/index.ts @@ -38,4 +38,4 @@ export function createRequiredError(driver: string, name: string | string[]) { ); } return createError(driver, `Missing required option \`${name}\`.`); -} \ No newline at end of file +} From 015bf1e0f754ef771c868958429038a813fc01cd Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Fri, 12 Jan 2024 13:00:49 +0100 Subject: [PATCH 4/9] refactor --- src/drivers/cloudflare-kv-binding.ts | 22 +++++++++++++--------- src/drivers/cloudflare-r2-binding.ts | 27 ++++++++++++++++----------- 2 files changed, 29 insertions(+), 20 deletions(-) diff --git a/src/drivers/cloudflare-kv-binding.ts b/src/drivers/cloudflare-kv-binding.ts index 50471d10..73a91251 100644 --- a/src/drivers/cloudflare-kv-binding.ts +++ b/src/drivers/cloudflare-kv-binding.ts @@ -1,7 +1,6 @@ /// +import { createError, defineDriver, joinKeys } from "./utils"; import { getBinding } from "./utils/cloudflare"; -import { defineDriver, joinKeys } from "./utils"; - export interface KVOptions { binding?: string | KVNamespace; @@ -13,12 +12,17 @@ export interface KVOptions { const DRIVER_NAME = "cloudflare-kv-binding"; -export default defineDriver((opts: KVOptions = { binding: "STORAGE" }) => { +export default defineDriver((_opts: KVOptions = {}) => { + const opts: KVOptions = { + binding: "STORAGE", + ..._opts, + }; + const r = (key: string = "") => (opts.base ? joinKeys(opts.base, key) : key); async function getKeys(base: string = "") { base = r(base); - const binding = getBinding(opts.binding); + const binding = getBinding(opts.binding!); const kvList = await binding.list(base ? { prefix: base } : undefined); return kvList.keys.map((key) => key.name); } @@ -28,22 +32,22 @@ export default defineDriver((opts: KVOptions = { binding: "STORAGE" }) => { options: opts, async hasItem(key) { key = r(key); - const binding = getBinding(opts.binding); + const binding = getBinding(opts.binding!); return (await binding.get(key)) !== null; }, getItem(key) { key = r(key); - const binding = getBinding(opts.binding); + const binding = getBinding(opts.binding!); return binding.get(key); }, setItem(key, value) { key = r(key); - const binding = getBinding(opts.binding); + const binding = getBinding(opts.binding!); return binding.put(key, value); }, removeItem(key) { key = r(key); - const binding = getBinding(opts.binding); + const binding = getBinding(opts.binding!); return binding.delete(key); }, getKeys() { @@ -52,7 +56,7 @@ export default defineDriver((opts: KVOptions = { binding: "STORAGE" }) => { ); }, async clear(base) { - const binding = getBinding(opts.binding); + const binding = getBinding(opts.binding!); const keys = await getKeys(base); await Promise.all(keys.map((key) => binding.delete(key))); }, diff --git a/src/drivers/cloudflare-r2-binding.ts b/src/drivers/cloudflare-r2-binding.ts index 8f9f0117..99b2cc89 100644 --- a/src/drivers/cloudflare-r2-binding.ts +++ b/src/drivers/cloudflare-r2-binding.ts @@ -1,6 +1,6 @@ /// +import { createError, defineDriver, joinKeys } from "./utils"; import { getBinding } from "./utils/cloudflare"; -import { defineDriver, joinKeys } from "./utils"; export interface CloudflareR2Options { binding?: string | R2Bucket; @@ -12,12 +12,17 @@ export interface CloudflareR2Options { const DRIVER_NAME = "cloudflare-r2-binding"; export default defineDriver( - (opts: CloudflareR2Options = { binding: "BUCKET" }) => { + (_opts: CloudflareR2Options = { binding: "BUCKET" }) => { + const opts: CloudflareR2Options = { + binding: "BUCKET", + ..._opts, + }; + const r = (key: string = "") => opts.base ? joinKeys(opts.base, key) : key; const getKeys = async (base?: string) => { - const binding = getBinding(opts.binding); + const binding = getBinding(opts.binding!); const kvList = await binding.list( base || opts.base ? { prefix: r(base) } : undefined ); @@ -29,12 +34,12 @@ export default defineDriver( options: opts, async hasItem(key) { key = r(key); - const binding = getBinding(opts.binding); + const binding = getBinding(opts.binding!); return (await binding.head(key)) !== null; }, async getMeta(key, topts) { key = r(key); - const binding = getBinding(opts.binding); + const binding = getBinding(opts.binding!); const obj = await binding.head(key); if (!obj) return null; return { @@ -45,27 +50,27 @@ export default defineDriver( }, getItem(key, topts) { key = r(key); - const binding = getBinding(opts.binding); + const binding = getBinding(opts.binding!); return binding.get(key, topts).then((r) => r?.text()); }, getItemRaw(key, topts) { key = r(key); - const binding = getBinding(opts.binding); + const binding = getBinding(opts.binding!); return binding.get(key, topts).then((r) => r?.arrayBuffer()); }, async setItem(key, value, topts) { key = r(key); - const binding = getBinding(opts.binding); + const binding = getBinding(opts.binding!); await binding.put(key, value, topts); }, async setItemRaw(key, value, topts) { key = r(key); - const binding = getBinding(opts.binding); + const binding = getBinding(opts.binding!); await binding.put(key, value, topts); }, async removeItem(key) { key = r(key); - const binding = getBinding(opts.binding); + const binding = getBinding(opts.binding!); await binding.delete(key); }, getKeys(base) { @@ -74,7 +79,7 @@ export default defineDriver( ); }, async clear(base) { - const binding = getBinding(opts.binding); + const binding = getBinding(opts.binding!); const keys = await getKeys(base); await binding.delete(keys); }, From 2287b3e31e467a99d242b71381c52e4d1f10d247 Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Fri, 12 Jan 2024 13:06:09 +0100 Subject: [PATCH 5/9] reduce diff --- src/drivers/cloudflare-r2-binding.ts | 139 +++++++++++++-------------- 1 file changed, 68 insertions(+), 71 deletions(-) diff --git a/src/drivers/cloudflare-r2-binding.ts b/src/drivers/cloudflare-r2-binding.ts index 99b2cc89..5cf347ea 100644 --- a/src/drivers/cloudflare-r2-binding.ts +++ b/src/drivers/cloudflare-r2-binding.ts @@ -11,78 +11,75 @@ export interface CloudflareR2Options { const DRIVER_NAME = "cloudflare-r2-binding"; -export default defineDriver( - (_opts: CloudflareR2Options = { binding: "BUCKET" }) => { - const opts: CloudflareR2Options = { - binding: "BUCKET", - ..._opts, - }; +export default defineDriver((_opts: CloudflareR2Options = {}) => { + const opts: CloudflareR2Options = { + binding: "BUCKET", + ..._opts, + }; - const r = (key: string = "") => - opts.base ? joinKeys(opts.base, key) : key; + const r = (key: string = "") => (opts.base ? joinKeys(opts.base, key) : key); - const getKeys = async (base?: string) => { + const getKeys = async (base?: string) => { + const binding = getBinding(opts.binding!); + const kvList = await binding.list( + base || opts.base ? { prefix: r(base) } : undefined + ); + return kvList.objects.map((obj) => obj.key); + }; + + return { + name: DRIVER_NAME, + options: opts, + async hasItem(key) { + key = r(key); + const binding = getBinding(opts.binding!); + return (await binding.head(key)) !== null; + }, + async getMeta(key, topts) { + key = r(key); + const binding = getBinding(opts.binding!); + const obj = await binding.head(key); + if (!obj) return null; + return { + mtime: obj.uploaded, + atime: obj.uploaded, + ...obj, + }; + }, + getItem(key, topts) { + key = r(key); + const binding = getBinding(opts.binding!); + return binding.get(key, topts).then((r) => r?.text()); + }, + getItemRaw(key, topts) { + key = r(key); + const binding = getBinding(opts.binding!); + return binding.get(key, topts).then((r) => r?.arrayBuffer()); + }, + async setItem(key, value, topts) { + key = r(key); const binding = getBinding(opts.binding!); - const kvList = await binding.list( - base || opts.base ? { prefix: r(base) } : undefined + await binding.put(key, value, topts); + }, + async setItemRaw(key, value, topts) { + key = r(key); + const binding = getBinding(opts.binding!); + await binding.put(key, value, topts); + }, + async removeItem(key) { + key = r(key); + const binding = getBinding(opts.binding!); + await binding.delete(key); + }, + getKeys(base) { + return getKeys(base).then((keys) => + opts.base ? keys.map((key) => key.slice(opts.base!.length)) : keys ); - return kvList.objects.map((obj) => obj.key); - }; - - return { - name: DRIVER_NAME, - options: opts, - async hasItem(key) { - key = r(key); - const binding = getBinding(opts.binding!); - return (await binding.head(key)) !== null; - }, - async getMeta(key, topts) { - key = r(key); - const binding = getBinding(opts.binding!); - const obj = await binding.head(key); - if (!obj) return null; - return { - mtime: obj.uploaded, - atime: obj.uploaded, - ...obj, - }; - }, - getItem(key, topts) { - key = r(key); - const binding = getBinding(opts.binding!); - return binding.get(key, topts).then((r) => r?.text()); - }, - getItemRaw(key, topts) { - key = r(key); - const binding = getBinding(opts.binding!); - return binding.get(key, topts).then((r) => r?.arrayBuffer()); - }, - async setItem(key, value, topts) { - key = r(key); - const binding = getBinding(opts.binding!); - await binding.put(key, value, topts); - }, - async setItemRaw(key, value, topts) { - key = r(key); - const binding = getBinding(opts.binding!); - await binding.put(key, value, topts); - }, - async removeItem(key) { - key = r(key); - const binding = getBinding(opts.binding!); - await binding.delete(key); - }, - getKeys(base) { - return getKeys(base).then((keys) => - opts.base ? keys.map((key) => key.slice(opts.base!.length)) : keys - ); - }, - async clear(base) { - const binding = getBinding(opts.binding!); - const keys = await getKeys(base); - await binding.delete(keys); - }, - }; - } -); + }, + async clear(base) { + const binding = getBinding(opts.binding!); + const keys = await getKeys(base); + await binding.delete(keys); + }, + }; +}); From 33877b6097b314ea3a4e04737696ada84eb5fd55 Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Fri, 12 Jan 2024 13:06:54 +0100 Subject: [PATCH 6/9] error case --- src/drivers/utils/cloudflare.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/drivers/utils/cloudflare.ts b/src/drivers/utils/cloudflare.ts index 28e2286b..3c48b4ea 100644 --- a/src/drivers/utils/cloudflare.ts +++ b/src/drivers/utils/cloudflare.ts @@ -12,7 +12,7 @@ export function getBinding(binding: KVNamespace | R2Bucket | string) { if (!binding) { throw createError( - "Cloudflare", + "cloudflare", `Invalid binding \`${bindingName}\`: \`${binding}\`` ); } @@ -20,7 +20,7 @@ export function getBinding(binding: KVNamespace | R2Bucket | string) { for (const key of ["get", "put", "delete"]) { if (!(key in binding)) { throw createError( - "Cloudflare", + "cloudflare", `Invalid binding \`${bindingName}\`: \`${key}\` key is missing` ); } From 1adc6c089b4b86c59c44c1eeaebbb25d7a85ae50 Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Fri, 12 Jan 2024 13:09:06 +0100 Subject: [PATCH 7/9] explicit import --- src/drivers/utils/cloudflare.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/drivers/utils/cloudflare.ts b/src/drivers/utils/cloudflare.ts index 3c48b4ea..92db384d 100644 --- a/src/drivers/utils/cloudflare.ts +++ b/src/drivers/utils/cloudflare.ts @@ -1,5 +1,5 @@ /// -import { createError } from "."; +import { createError } from "./index"; export function getBinding(binding: KVNamespace | R2Bucket | string) { let bindingName = "[binding]"; From 98c0a27f0fce68a36dc4c4e231af379405015754 Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Fri, 12 Jan 2024 13:12:15 +0100 Subject: [PATCH 8/9] refactor --- src/drivers/cloudflare-kv-binding.ts | 23 +++++++++-------------- src/drivers/cloudflare-r2-binding.ts | 22 +++++++++++----------- src/drivers/utils/cloudflare.ts | 8 ++++++++ 3 files changed, 28 insertions(+), 25 deletions(-) diff --git a/src/drivers/cloudflare-kv-binding.ts b/src/drivers/cloudflare-kv-binding.ts index 73a91251..e862973f 100644 --- a/src/drivers/cloudflare-kv-binding.ts +++ b/src/drivers/cloudflare-kv-binding.ts @@ -1,6 +1,6 @@ /// -import { createError, defineDriver, joinKeys } from "./utils"; -import { getBinding } from "./utils/cloudflare"; +import { defineDriver, joinKeys } from "./utils"; +import { getKVBinding } from "./utils/cloudflare"; export interface KVOptions { binding?: string | KVNamespace; @@ -12,17 +12,12 @@ export interface KVOptions { const DRIVER_NAME = "cloudflare-kv-binding"; -export default defineDriver((_opts: KVOptions = {}) => { - const opts: KVOptions = { - binding: "STORAGE", - ..._opts, - }; - +export default defineDriver((opts: KVOptions) => { const r = (key: string = "") => (opts.base ? joinKeys(opts.base, key) : key); async function getKeys(base: string = "") { base = r(base); - const binding = getBinding(opts.binding!); + const binding = getKVBinding(opts.binding); const kvList = await binding.list(base ? { prefix: base } : undefined); return kvList.keys.map((key) => key.name); } @@ -32,22 +27,22 @@ export default defineDriver((_opts: KVOptions = {}) => { options: opts, async hasItem(key) { key = r(key); - const binding = getBinding(opts.binding!); + const binding = getKVBinding(opts.binding); return (await binding.get(key)) !== null; }, getItem(key) { key = r(key); - const binding = getBinding(opts.binding!); + const binding = getKVBinding(opts.binding); return binding.get(key); }, setItem(key, value) { key = r(key); - const binding = getBinding(opts.binding!); + const binding = getKVBinding(opts.binding); return binding.put(key, value); }, removeItem(key) { key = r(key); - const binding = getBinding(opts.binding!); + const binding = getKVBinding(opts.binding); return binding.delete(key); }, getKeys() { @@ -56,7 +51,7 @@ export default defineDriver((_opts: KVOptions = {}) => { ); }, async clear(base) { - const binding = getBinding(opts.binding!); + const binding = getKVBinding(opts.binding); const keys = await getKeys(base); await Promise.all(keys.map((key) => binding.delete(key))); }, diff --git a/src/drivers/cloudflare-r2-binding.ts b/src/drivers/cloudflare-r2-binding.ts index 5cf347ea..87a24331 100644 --- a/src/drivers/cloudflare-r2-binding.ts +++ b/src/drivers/cloudflare-r2-binding.ts @@ -1,6 +1,6 @@ /// -import { createError, defineDriver, joinKeys } from "./utils"; -import { getBinding } from "./utils/cloudflare"; +import { defineDriver, joinKeys } from "./utils"; +import { getR2Binding } from "./utils/cloudflare"; export interface CloudflareR2Options { binding?: string | R2Bucket; @@ -20,7 +20,7 @@ export default defineDriver((_opts: CloudflareR2Options = {}) => { const r = (key: string = "") => (opts.base ? joinKeys(opts.base, key) : key); const getKeys = async (base?: string) => { - const binding = getBinding(opts.binding!); + const binding = getR2Binding(opts.binding); const kvList = await binding.list( base || opts.base ? { prefix: r(base) } : undefined ); @@ -32,12 +32,12 @@ export default defineDriver((_opts: CloudflareR2Options = {}) => { options: opts, async hasItem(key) { key = r(key); - const binding = getBinding(opts.binding!); + const binding = getR2Binding(opts.binding); return (await binding.head(key)) !== null; }, async getMeta(key, topts) { key = r(key); - const binding = getBinding(opts.binding!); + const binding = getR2Binding(opts.binding); const obj = await binding.head(key); if (!obj) return null; return { @@ -48,27 +48,27 @@ export default defineDriver((_opts: CloudflareR2Options = {}) => { }, getItem(key, topts) { key = r(key); - const binding = getBinding(opts.binding!); + const binding = getR2Binding(opts.binding); return binding.get(key, topts).then((r) => r?.text()); }, getItemRaw(key, topts) { key = r(key); - const binding = getBinding(opts.binding!); + const binding = getR2Binding(opts.binding); return binding.get(key, topts).then((r) => r?.arrayBuffer()); }, async setItem(key, value, topts) { key = r(key); - const binding = getBinding(opts.binding!); + const binding = getR2Binding(opts.binding); await binding.put(key, value, topts); }, async setItemRaw(key, value, topts) { key = r(key); - const binding = getBinding(opts.binding!); + const binding = getR2Binding(opts.binding); await binding.put(key, value, topts); }, async removeItem(key) { key = r(key); - const binding = getBinding(opts.binding!); + const binding = getR2Binding(opts.binding); await binding.delete(key); }, getKeys(base) { @@ -77,7 +77,7 @@ export default defineDriver((_opts: CloudflareR2Options = {}) => { ); }, async clear(base) { - const binding = getBinding(opts.binding!); + const binding = getR2Binding(opts.binding); const keys = await getKeys(base); await binding.delete(keys); }, diff --git a/src/drivers/utils/cloudflare.ts b/src/drivers/utils/cloudflare.ts index 92db384d..e789a949 100644 --- a/src/drivers/utils/cloudflare.ts +++ b/src/drivers/utils/cloudflare.ts @@ -28,3 +28,11 @@ export function getBinding(binding: KVNamespace | R2Bucket | string) { return binding; } + +export function getKVBinding(binding: KVNamespace | string = "STORAGE") { + return getBinding(binding) as KVNamespace; +} + +export function getR2Binding(binding: R2Bucket | string = "BUCKET") { + return getBinding(binding) as R2Bucket; +} From fa104f27912d15bb904ccfba62ffcbfec827022f Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Fri, 12 Jan 2024 13:13:16 +0100 Subject: [PATCH 9/9] reduce r2 changes --- src/drivers/cloudflare-r2-binding.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/drivers/cloudflare-r2-binding.ts b/src/drivers/cloudflare-r2-binding.ts index 87a24331..dd6913f8 100644 --- a/src/drivers/cloudflare-r2-binding.ts +++ b/src/drivers/cloudflare-r2-binding.ts @@ -11,12 +11,7 @@ export interface CloudflareR2Options { const DRIVER_NAME = "cloudflare-r2-binding"; -export default defineDriver((_opts: CloudflareR2Options = {}) => { - const opts: CloudflareR2Options = { - binding: "BUCKET", - ..._opts, - }; - +export default defineDriver((opts: CloudflareR2Options = {}) => { const r = (key: string = "") => (opts.base ? joinKeys(opts.base, key) : key); const getKeys = async (base?: string) => {