diff --git a/packages/tre/src/plugins/kv/index.ts b/packages/tre/src/plugins/kv/index.ts index a8f368ca4..b36c9cc64 100644 --- a/packages/tre/src/plugins/kv/index.ts +++ b/packages/tre/src/plugins/kv/index.ts @@ -9,6 +9,7 @@ import { Plugin, SCRIPT_PLUGIN_NAMESPACE_PERSIST, encodePersist, + namespaceEntries, } from "../shared"; import { KV_PLUGIN_NAME } from "./constants"; import { KVGateway } from "./gateway"; @@ -17,8 +18,7 @@ import { KVRouter } from "./router"; import { SitesOptions, getSitesBindings, getSitesService } from "./sites"; export const KVOptionsSchema = z.object({ - // TODO: also allow array like Miniflare 2 - kvNamespaces: z.record(z.string()).optional(), + kvNamespaces: z.union([z.record(z.string()), z.string().array()]).optional(), // Workers Sites sitePath: z.string().optional(), @@ -48,9 +48,8 @@ export const KV_PLUGIN: Plugin< options: KVOptionsSchema, sharedOptions: KVSharedOptionsSchema, async getBindings(options) { - const bindings = Object.entries( - options.kvNamespaces ?? {} - ).map(([name, id]) => ({ + const namespaces = namespaceEntries(options.kvNamespaces); + const bindings = namespaces.map(([name, id]) => ({ name, kvNamespace: { name: `${SERVICE_NAMESPACE_PREFIX}:${id}` }, })); @@ -63,24 +62,23 @@ export const KV_PLUGIN: Plugin< }, getServices({ options, sharedOptions }) { const persistBinding = encodePersist(sharedOptions.kvPersist); - const services = Object.entries(options.kvNamespaces ?? []).map( - ([_, id]) => ({ - name: `${SERVICE_NAMESPACE_PREFIX}:${id}`, - worker: { - serviceWorkerScript: SCRIPT_PLUGIN_NAMESPACE_PERSIST, - compatibilityDate: "2022-09-01", - bindings: [ - ...persistBinding, - { name: BINDING_TEXT_PLUGIN, text: KV_PLUGIN_NAME }, - { name: BINDING_TEXT_NAMESPACE, text: id }, - { - name: BINDING_SERVICE_LOOPBACK, - service: { name: SERVICE_LOOPBACK }, - }, - ], - }, - }) - ); + const namespaces = namespaceEntries(options.kvNamespaces); + const services = namespaces.map(([_, id]) => ({ + name: `${SERVICE_NAMESPACE_PREFIX}:${id}`, + worker: { + serviceWorkerScript: SCRIPT_PLUGIN_NAMESPACE_PERSIST, + compatibilityDate: "2022-09-01", + bindings: [ + ...persistBinding, + { name: BINDING_TEXT_PLUGIN, text: KV_PLUGIN_NAME }, + { name: BINDING_TEXT_NAMESPACE, text: id }, + { + name: BINDING_SERVICE_LOOPBACK, + service: { name: SERVICE_LOOPBACK }, + }, + ], + }, + })); if (isWorkersSitesEnabled(options)) { services.push(getSitesService(options)); diff --git a/packages/tre/src/plugins/r2/index.ts b/packages/tre/src/plugins/r2/index.ts index 2b3fe17d1..f2ded7243 100644 --- a/packages/tre/src/plugins/r2/index.ts +++ b/packages/tre/src/plugins/r2/index.ts @@ -9,12 +9,13 @@ import { Plugin, SCRIPT_PLUGIN_NAMESPACE_PERSIST, encodePersist, + namespaceEntries, } from "../shared"; import { R2Gateway } from "./gateway"; import { R2Router } from "./router"; export const R2OptionsSchema = z.object({ - r2Buckets: z.record(z.string()).optional(), + r2Buckets: z.union([z.record(z.string()), z.string().array()]).optional(), }); export const R2SharedOptionsSchema = z.object({ r2Persist: PersistenceSchema, @@ -31,14 +32,11 @@ export const R2_PLUGIN: Plugin< options: R2OptionsSchema, sharedOptions: R2SharedOptionsSchema, getBindings(options) { - const bindings = Object.entries( - options.r2Buckets ?? [] - ).map(([name, id]) => ({ + const buckets = namespaceEntries(options.r2Buckets); + return buckets.map(([name, id]) => ({ name, r2Bucket: { name: `${R2_PLUGIN_NAME}:${id}` }, })); - - return bindings; }, getServices({ options, sharedOptions }) { const persistBinding = encodePersist(sharedOptions.r2Persist); @@ -46,23 +44,20 @@ export const R2_PLUGIN: Plugin< name: BINDING_SERVICE_LOOPBACK, service: { name: SERVICE_LOOPBACK }, }; - const services = Object.entries(options.r2Buckets ?? []).map( - ([_, id]) => ({ - name: `${R2_PLUGIN_NAME}:${id}`, - worker: { - serviceWorkerScript: SCRIPT_PLUGIN_NAMESPACE_PERSIST, - bindings: [ - ...persistBinding, - { name: BINDING_TEXT_PLUGIN, text: R2_PLUGIN_NAME }, - { name: BINDING_TEXT_NAMESPACE, text: id }, - loopbackBinding, - ], - compatibilityDate: "2022-09-01", - }, - }) - ); - - return services; + const buckets = namespaceEntries(options.r2Buckets); + return buckets.map(([_, id]) => ({ + name: `${R2_PLUGIN_NAME}:${id}`, + worker: { + serviceWorkerScript: SCRIPT_PLUGIN_NAMESPACE_PERSIST, + bindings: [ + ...persistBinding, + { name: BINDING_TEXT_PLUGIN, text: R2_PLUGIN_NAME }, + { name: BINDING_TEXT_NAMESPACE, text: id }, + loopbackBinding, + ], + compatibilityDate: "2022-09-01", + }, + })); }, }; diff --git a/packages/tre/src/plugins/shared/index.ts b/packages/tre/src/plugins/shared/index.ts index 105242959..f6272bbd9 100644 --- a/packages/tre/src/plugins/shared/index.ts +++ b/packages/tre/src/plugins/shared/index.ts @@ -47,6 +47,18 @@ export type Plugin< remoteStorage?: RemoteStorageConstructor; }); +export function namespaceEntries( + namespaces?: Record | string[] +): [bindingName: string, id: string][] { + if (Array.isArray(namespaces)) { + return namespaces.map(([bindingName]) => [bindingName, bindingName]); + } else if (namespaces !== undefined) { + return Object.entries(namespaces); + } else { + return []; + } +} + export * from "./constants"; export * from "./gateway"; export * from "./router";