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..e862973f 100644 --- a/src/drivers/cloudflare-kv-binding.ts +++ b/src/drivers/cloudflare-kv-binding.ts @@ -1,5 +1,6 @@ /// -import { createError, defineDriver, joinKeys } from "./utils"; +import { defineDriver, joinKeys } from "./utils"; +import { getKVBinding } from "./utils/cloudflare"; export interface KVOptions { binding?: string | KVNamespace; @@ -11,12 +12,12 @@ export interface KVOptions { const DRIVER_NAME = "cloudflare-kv-binding"; -export default defineDriver((opts: KVOptions = {}) => { +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); } @@ -26,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() { @@ -50,37 +51,9 @@ 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))); }, }; }); - -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..dd6913f8 100644 --- a/src/drivers/cloudflare-r2-binding.ts +++ b/src/drivers/cloudflare-r2-binding.ts @@ -1,8 +1,9 @@ /// -import { createError, defineDriver, joinKeys } from "./utils"; +import { defineDriver, joinKeys } from "./utils"; +import { getR2Binding } from "./utils/cloudflare"; export interface CloudflareR2Options { - binding: string | R2Bucket; + binding?: string | R2Bucket; base?: string; } @@ -10,11 +11,11 @@ export interface CloudflareR2Options { const DRIVER_NAME = "cloudflare-r2-binding"; -export default defineDriver((opts: CloudflareR2Options) => { +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 ); @@ -26,12 +27,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 { @@ -42,27 +43,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) { @@ -71,37 +72,9 @@ 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); }, }; }); - -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; -} diff --git a/src/drivers/utils/cloudflare.ts b/src/drivers/utils/cloudflare.ts new file mode 100644 index 00000000..e789a949 --- /dev/null +++ b/src/drivers/utils/cloudflare.ts @@ -0,0 +1,38 @@ +/// +import { createError } from "./index"; + +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; +} + +export function getKVBinding(binding: KVNamespace | string = "STORAGE") { + return getBinding(binding) as KVNamespace; +} + +export function getR2Binding(binding: R2Bucket | string = "BUCKET") { + return getBinding(binding) as R2Bucket; +}