diff --git a/.changeset/slow-pumas-sleep.md b/.changeset/slow-pumas-sleep.md new file mode 100644 index 000000000000..6f881255131b --- /dev/null +++ b/.changeset/slow-pumas-sleep.md @@ -0,0 +1,9 @@ +--- +"wrangler": patch +--- + +feat: implement `[data_blobs]` + +This implements `[data_blobs]` support for service-worker workers, as well as enabling Data module support for service-worker workers. `data_blob` is a supported binding type, but we never implemented support for it in v1. This implements support, and utilises it for supporting Data modules in service worker format. Implementation wise, it's incredibly similar to how we implemented `text_blobs`, with relevant changes. + +Partial fix for https://github.com/cloudflare/wrangler2/issues/740 pending local mode support. diff --git a/packages/wrangler/src/__tests__/configuration.test.ts b/packages/wrangler/src/__tests__/configuration.test.ts index 4a2dec033220..06ca09e454f8 100644 --- a/packages/wrangler/src/__tests__/configuration.test.ts +++ b/packages/wrangler/src/__tests__/configuration.test.ts @@ -56,6 +56,7 @@ describe("normalizeAndValidateConfig()", () => { usage_model: undefined, vars: {}, wasm_modules: undefined, + data_blobs: undefined, workers_dev: undefined, zone_id: undefined, }); @@ -434,6 +435,59 @@ describe("normalizeAndValidateConfig()", () => { `); }); + it("should map `data_blobs` paths from relative to the config path to relative to the cwd", () => { + const expectedConfig: RawConfig = { + data_blobs: { + BLOB_1: "path/to/data1.bin", + BLOB_2: "data2.bin", + }, + }; + + const { config, diagnostics } = normalizeAndValidateConfig( + expectedConfig, + "project/wrangler.toml", + { env: undefined } + ); + + expect(config).toEqual( + expect.objectContaining({ + data_blobs: { + BLOB_1: path.normalize("project/path/to/data1.bin"), + BLOB_2: path.normalize("project/data2.bin"), + }, + }) + ); + expect(diagnostics.hasErrors()).toBe(false); + expect(diagnostics.hasWarnings()).toBe(false); + }); + + it("should error on invalid `data_blob` paths", () => { + const expectedConfig = { + data_blobs: { + MODULE_1: 111, + MODULE_2: 222, + }, + }; + + const { config, diagnostics } = normalizeAndValidateConfig( + expectedConfig as unknown as RawConfig, + "project/wrangler.toml", + { env: undefined } + ); + + expect(config).toEqual( + expect.objectContaining({ + data_blobs: {}, + }) + ); + expect(diagnostics.hasWarnings()).toBe(false); + expect(normalizePath(diagnostics.renderErrors())).toMatchInlineSnapshot(` + "Processing project/wrangler.toml configuration: + - Expected \\"data_blobs['MODULE_1']\\" to be of type string but got 111. + - Expected \\"data_blobs['MODULE_2']\\" to be of type string but got 222." + `); + }); + it("should resolve tsconfig relative to wrangler.toml", async () => { const expectedConfig: RawEnvironment = { tsconfig: "path/to/some-tsconfig.json", diff --git a/packages/wrangler/src/__tests__/publish.test.ts b/packages/wrangler/src/__tests__/publish.test.ts index 0f61fe9b16f8..87079fd3642f 100644 --- a/packages/wrangler/src/__tests__/publish.test.ts +++ b/packages/wrangler/src/__tests__/publish.test.ts @@ -2328,6 +2328,10 @@ export default{ WASM_MODULE_ONE: "./some_wasm.wasm", WASM_MODULE_TWO: "./more_wasm.wasm", }, + data_blobs: { + DATA_BLOB_ONE: "./some-data-blob.bin", + DATA_BLOB_TWO: "./more-data-blob.bin", + }, }); writeWorkerSource({ type: "sw" }); @@ -2339,6 +2343,9 @@ export default{ fs.writeFileSync("./some_wasm.wasm", "some wasm"); fs.writeFileSync("./more_wasm.wasm", "more wasm"); + fs.writeFileSync("./some-data-blob.bin", "some data"); + fs.writeFileSync("./more-data-blob.bin", "more data"); + mockUploadWorkerRequest({ expectedType: "sw", expectedBindings: [ @@ -2392,6 +2399,8 @@ export default{ }, { name: "TEXT_BLOB_ONE", part: "TEXT_BLOB_ONE", type: "text_blob" }, { name: "TEXT_BLOB_TWO", part: "TEXT_BLOB_TWO", type: "text_blob" }, + { name: "DATA_BLOB_ONE", part: "DATA_BLOB_ONE", type: "data_blob" }, + { name: "DATA_BLOB_TWO", part: "DATA_BLOB_TWO", type: "data_blob" }, { data: { some: { unsafe: "thing" } }, name: "UNSAFE_BINDING_ONE", @@ -2476,6 +2485,10 @@ export default{ WASM_MODULE_ONE: "./some_wasm.wasm", CONFLICTING_NAME_THREE: "./more_wasm.wasm", }, + data_blobs: { + DATA_BLOB_ONE: "./some_data.bin", + CONFLICTING_NAME_THREE: "./more_data.bin", + }, }); writeWorkerSource({ type: "sw" }); @@ -2492,7 +2505,7 @@ export default{ [Error: Processing wrangler.toml configuration: - CONFLICTING_NAME_ONE assigned to Durable Object, KV Namespace, and R2 Bucket bindings. - CONFLICTING_NAME_TWO assigned to Durable Object and KV Namespace bindings. - - CONFLICTING_NAME_THREE assigned to R2 Bucket, Text Blob, Unsafe, Environment Variable, and WASM Module bindings. + - CONFLICTING_NAME_THREE assigned to R2 Bucket, Text Blob, Unsafe, Environment Variable, WASM Module, and Data Blob bindings. - CONFLICTING_NAME_FOUR assigned to Text Blob and Unsafe bindings. - Bindings must have unique names, so that they can all be referenced in the worker. Please change your bindings to have unique names.] @@ -2502,7 +2515,7 @@ export default{ "Processing wrangler.toml configuration: - CONFLICTING_NAME_ONE assigned to Durable Object, KV Namespace, and R2 Bucket bindings. - CONFLICTING_NAME_TWO assigned to Durable Object and KV Namespace bindings. - - CONFLICTING_NAME_THREE assigned to R2 Bucket, Text Blob, Unsafe, Environment Variable, and WASM Module bindings. + - CONFLICTING_NAME_THREE assigned to R2 Bucket, Text Blob, Unsafe, Environment Variable, WASM Module, and Data Blob bindings. - CONFLICTING_NAME_FOUR assigned to Text Blob and Unsafe bindings. - Bindings must have unique names, so that they can all be referenced in the worker. Please change your bindings to have unique names. @@ -2559,7 +2572,7 @@ export default{ }, ], }, - // text_blobs, vars, and wasm_modules are fine because they're object literals, + // text_blobs, vars, wasm_modules and data_blobs are fine because they're object literals, // and by definition cannot have two keys of the same name // // text_blobs: { @@ -2688,6 +2701,10 @@ export default{ WASM_MODULE_ONE: "./some_wasm.wasm", CONFLICTING_NAME_THREE: "./more_wasm.wasm", }, + data_blobs: { + DATA_BLOB_ONE: "./some_data.bin", + CONFLICTING_NAME_THREE: "./more_data.bin", + }, }); writeWorkerSource({ type: "sw" }); @@ -2705,7 +2722,7 @@ export default{ - CONFLICTING_DURABLE_OBJECT_NAME assigned to multiple Durable Object bindings. - CONFLICTING_KV_NAMESPACE_NAME assigned to multiple KV Namespace bindings. - CONFLICTING_R2_BUCKET_NAME assigned to multiple R2 Bucket bindings. - - CONFLICTING_NAME_THREE assigned to R2 Bucket, Text Blob, Unsafe, Environment Variable, and WASM Module bindings. + - CONFLICTING_NAME_THREE assigned to R2 Bucket, Text Blob, Unsafe, Environment Variable, WASM Module, and Data Blob bindings. - CONFLICTING_NAME_FOUR assigned to R2 Bucket, Text Blob, and Unsafe bindings. - CONFLICTING_UNSAFE_NAME assigned to multiple Unsafe bindings. - Bindings must have unique names, so that they can all be referenced in the worker. @@ -2717,7 +2734,7 @@ export default{ - CONFLICTING_DURABLE_OBJECT_NAME assigned to multiple Durable Object bindings. - CONFLICTING_KV_NAMESPACE_NAME assigned to multiple KV Namespace bindings. - CONFLICTING_R2_BUCKET_NAME assigned to multiple R2 Bucket bindings. - - CONFLICTING_NAME_THREE assigned to R2 Bucket, Text Blob, Unsafe, Environment Variable, and WASM Module bindings. + - CONFLICTING_NAME_THREE assigned to R2 Bucket, Text Blob, Unsafe, Environment Variable, WASM Module, and Data Blob bindings. - CONFLICTING_NAME_FOUR assigned to R2 Bucket, Text Blob, and Unsafe bindings. - CONFLICTING_UNSAFE_NAME assigned to multiple Unsafe bindings. - Bindings must have unique names, so that they can all be referenced in the worker. @@ -2900,14 +2917,14 @@ export default{ await expect( runWrangler("publish index.js") ).rejects.toThrowErrorMatchingInlineSnapshot( - `"You cannot configure [text_blobs] with an ES module worker. Instead, import the file directly in your code, and optionally configure \`[build.upload.rules]\` in your wrangler.toml"` + `"You cannot configure [text_blobs] with an ES module worker. Instead, import the file directly in your code, and optionally configure \`[rules]\` in your wrangler.toml"` ); expect(std.out).toMatchInlineSnapshot(`""`); expect(std.err).toMatchInlineSnapshot(` - "You cannot configure [text_blobs] with an ES module worker. Instead, import the file directly in your code, and optionally configure \`[build.upload.rules]\` in your wrangler.toml + "You cannot configure [text_blobs] with an ES module worker. Instead, import the file directly in your code, and optionally configure \`[rules]\` in your wrangler.toml - %s If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new." - `); + %s If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new." + `); expect(std.warn).toMatchInlineSnapshot(`""`); }); @@ -2955,6 +2972,106 @@ export default{ }); }); + describe("[data_blobs]", () => { + it("should be able to define data blobs for service-worker format workers", async () => { + writeWranglerToml({ + data_blobs: { + TESTDATABLOBNAME: "./path/to/data.bin", + }, + }); + writeWorkerSource({ type: "sw" }); + fs.mkdirSync("./path/to", { recursive: true }); + fs.writeFileSync("./path/to/data.bin", "SOME DATA CONTENT"); + mockUploadWorkerRequest({ + expectedType: "sw", + expectedModules: { TESTDATABLOBNAME: "SOME DATA CONTENT" }, + expectedBindings: [ + { + name: "TESTDATABLOBNAME", + part: "TESTDATABLOBNAME", + type: "data_blob", + }, + ], + }); + mockSubDomainRequest(); + await runWrangler("publish index.js"); + expect(std.out).toMatchInlineSnapshot(` + "Uploaded test-name (TIMINGS) + Published test-name (TIMINGS) + test-name.test-sub-domain.workers.dev" + `); + expect(std.err).toMatchInlineSnapshot(`""`); + expect(std.warn).toMatchInlineSnapshot(`""`); + }); + + it("should error when defining data blobs for modules format workers", async () => { + writeWranglerToml({ + data_blobs: { + TESTDATABLOBNAME: "./path/to/data.bin", + }, + }); + writeWorkerSource({ type: "esm" }); + fs.mkdirSync("./path/to", { recursive: true }); + fs.writeFileSync("./path/to/data.bin", "SOME DATA CONTENT"); + + await expect( + runWrangler("publish index.js") + ).rejects.toThrowErrorMatchingInlineSnapshot( + `"You cannot configure [data_blobs] with an ES module worker. Instead, import the file directly in your code, and optionally configure \`[rules]\` in your wrangler.toml"` + ); + expect(std.out).toMatchInlineSnapshot(`""`); + expect(std.err).toMatchInlineSnapshot(` + "You cannot configure [data_blobs] with an ES module worker. Instead, import the file directly in your code, and optionally configure \`[rules]\` in your wrangler.toml + + %s If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new." + `); + expect(std.warn).toMatchInlineSnapshot(`""`); + }); + + it("should resolve data blobs relative to the wrangler.toml file", async () => { + fs.mkdirSync("./path/to/and/the/path/to/", { recursive: true }); + fs.writeFileSync( + "./path/to/wrangler.toml", + TOML.stringify({ + compatibility_date: "2022-01-12", + name: "test-name", + data_blobs: { + TESTDATABLOBNAME: "./and/the/path/to/data.bin", + }, + }), + + "utf-8" + ); + + writeWorkerSource({ type: "sw" }); + fs.writeFileSync( + "./path/to/and/the/path/to/data.bin", + "SOME DATA CONTENT" + ); + mockUploadWorkerRequest({ + expectedType: "sw", + expectedModules: { TESTDATABLOBNAME: "SOME DATA CONTENT" }, + expectedBindings: [ + { + name: "TESTDATABLOBNAME", + part: "TESTDATABLOBNAME", + type: "data_blob", + }, + ], + expectedCompatibilityDate: "2022-01-12", + }); + mockSubDomainRequest(); + await runWrangler("publish index.js --config ./path/to/wrangler.toml"); + expect(std.out).toMatchInlineSnapshot(` + "Uploaded test-name (TIMINGS) + Published test-name (TIMINGS) + test-name.test-sub-domain.workers.dev" + `); + expect(std.err).toMatchInlineSnapshot(`""`); + expect(std.warn).toMatchInlineSnapshot(`""`); + }); + }); + describe("[vars]", () => { it("should support json bindings", async () => { writeWranglerToml({ diff --git a/packages/wrangler/src/config/config.ts b/packages/wrangler/src/config/config.ts index 1f5d9c50781f..92d89847746a 100644 --- a/packages/wrangler/src/config/config.ts +++ b/packages/wrangler/src/config/config.ts @@ -135,6 +135,17 @@ export interface ConfigFields { [key: string]: string; } | undefined; + + /** + * A list of data files that your worker should be bound to. This is + * the "legacy" way of binding to a data file. ES module workers should + * do proper module imports. + */ + data_blobs: + | { + [key: string]: string; + } + | undefined; } export interface DevConfig { diff --git a/packages/wrangler/src/config/validation.ts b/packages/wrangler/src/config/validation.ts index ba20bdf42007..7663966bd9ee 100644 --- a/packages/wrangler/src/config/validation.ts +++ b/packages/wrangler/src/config/validation.ts @@ -182,6 +182,12 @@ export function normalizeAndValidateConfig( "text_blobs", rawConfig.text_blobs ), + data_blobs: normalizeAndValidateModulePaths( + diagnostics, + configPath, + "data_blobs", + rawConfig.data_blobs + ), }; validateBindingsHaveUniqueNames(diagnostics, config); @@ -427,12 +433,12 @@ function normalizeAndValidateSite( } /** - * Map the paths of the `wasm_modules` or `text_blobs` configuration to be relative to the current working directory. + * Map the paths of the `wasm_modules`, `text_blobs` or `data_blobs` configuration to be relative to the current working directory. */ function normalizeAndValidateModulePaths( diagnostics: Diagnostics, configPath: string | undefined, - field: "wasm_modules" | "text_blobs", + field: "wasm_modules" | "text_blobs" | "data_blobs", rawMapping: Record | undefined ): Record | undefined { if (rawMapping === undefined) { @@ -1153,6 +1159,7 @@ const validateBindingsHaveUniqueNames = ( unsafe, vars, wasm_modules, + data_blobs, }: Partial ): boolean => { let hasDuplicates = false; @@ -1165,6 +1172,7 @@ const validateBindingsHaveUniqueNames = ( Unsafe: getBindingNames(unsafe), "Environment Variable": getBindingNames(vars), "WASM Module": getBindingNames(wasm_modules), + "Data Blob": getBindingNames(data_blobs), } as Record; const bindingsGroupedByName: Record = {}; diff --git a/packages/wrangler/src/create-worker-upload-form.ts b/packages/wrangler/src/create-worker-upload-form.ts index 978c06200b01..ddc3f3929e85 100644 --- a/packages/wrangler/src/create-worker-upload-form.ts +++ b/packages/wrangler/src/create-worker-upload-form.ts @@ -38,6 +38,7 @@ export interface WorkerMetadata { | { type: "json"; name: string; json: unknown } | { type: "wasm_module"; name: string; part: string } | { type: "text_blob"; name: string; part: string } + | { type: "data_blob"; name: string; part: string } | { type: "durable_object_namespace"; name: string; @@ -133,6 +134,21 @@ export function createWorkerUploadForm(worker: CfWorkerInit): FormData { } } + for (const [name, filePath] of Object.entries(bindings.data_blobs || {})) { + metadataBindings.push({ + name, + type: "data_blob", + part: name, + }); + + formData.set( + name, + new File([readFileSync(filePath)], filePath, { + type: "application/octet-stream", + }) + ); + } + if (main.type === "commonjs") { // This is a service-worker format worker. for (const module of Object.values([...(modules || [])])) { @@ -146,8 +162,12 @@ export function createWorkerUploadForm(worker: CfWorkerInit): FormData { ); // And then remove it from the modules collection modules = modules?.filter((m) => m !== module); - } else if (module.type === "compiled-wasm" || module.type === "text") { - // Convert all wasm/text modules into `wasm_module`/`text_blob` bindings. + } else if ( + module.type === "compiled-wasm" || + module.type === "text" || + module.type === "buffer" + ) { + // Convert all wasm/text/data modules into `wasm_module`/`text_blob`/`data_blob` bindings. // The "name" of the module is a file path. We use it // to instead be a "part" of the body, and a reference // that we can use inside our source. This identifier has to be a valid @@ -156,7 +176,12 @@ export function createWorkerUploadForm(worker: CfWorkerInit): FormData { const name = module.name.replace(/[^a-zA-Z0-9_$]/g, "_"); metadataBindings.push({ name, - type: module.type === "compiled-wasm" ? "wasm_module" : "text_blob", + type: + module.type === "compiled-wasm" + ? "wasm_module" + : module.type === "text" + ? "text_blob" + : "data_blob", part: name, }); @@ -167,7 +192,9 @@ export function createWorkerUploadForm(worker: CfWorkerInit): FormData { type: module.type === "compiled-wasm" ? "application/wasm" - : "text/plain", + : module.type === "text" + ? "text/plain" + : "application/octet-stream", }) ); // And then remove it from the modules collection diff --git a/packages/wrangler/src/dev/dev.tsx b/packages/wrangler/src/dev/dev.tsx index 528266fdcd85..5667d19b2eba 100644 --- a/packages/wrangler/src/dev/dev.tsx +++ b/packages/wrangler/src/dev/dev.tsx @@ -77,7 +77,13 @@ export function DevImplementation(props: DevProps): JSX.Element { if (props.bindings.text_blobs && props.entry.format === "modules") { throw new Error( - "You cannot configure [text_blobs] with an ES module worker. Instead, import the file directly in your code, and optionally configure `[build.upload.rules]` in your wrangler.toml" + "You cannot configure [text_blobs] with an ES module worker. Instead, import the file directly in your code, and optionally configure `[rules]` in your wrangler.toml" + ); + } + + if (props.bindings.data_blobs && props.entry.format === "modules") { + throw new Error( + "You cannot configure [data_blobs] with an ES module worker. Instead, import the file directly in your code, and optionally configure `[rules]` in your wrangler.toml" ); } diff --git a/packages/wrangler/src/dev/local.tsx b/packages/wrangler/src/dev/local.tsx index 359bb3123bf7..32470b495ffa 100644 --- a/packages/wrangler/src/dev/local.tsx +++ b/packages/wrangler/src/dev/local.tsx @@ -83,6 +83,7 @@ function useLocalWorker({ const wasmBindings = { ...bindings.wasm_modules }; const textBlobBindings = { ...bindings.text_blobs }; + const dataBlobBindings = { ...bindings.data_blobs }; if (format === "service-worker") { for (const { type, name } of bundle.modules) { if (type === "compiled-wasm") { @@ -99,6 +100,13 @@ function useLocalWorker({ // characters with an underscore. const identifier = name.replace(/[^a-zA-Z0-9_$]/g, "_"); textBlobBindings[identifier] = name; + } else if (type === "buffer") { + // In service-worker format, data blobs are referenced by global identifiers, + // so we convert it here. + // This identifier has to be a valid JS identifier, so we replace all non alphanumeric + // characters with an underscore. + const identifier = name.replace(/[^a-zA-Z0-9_$]/g, "_"); + dataBlobBindings[identifier] = name; } } } @@ -139,6 +147,7 @@ function useLocalWorker({ bindings: bindings.vars, wasmBindings, textBlobBindings, + dataBlobBindings, sourceMap: true, logUnhandledRejections: true, }; @@ -237,6 +246,7 @@ function useLocalWorker({ rules, bindings.wasm_modules, bindings.text_blobs, + bindings.data_blobs, ]); return { inspectorUrl }; } diff --git a/packages/wrangler/src/index.tsx b/packages/wrangler/src/index.tsx index c70ff0db2326..fb8eacd90db9 100644 --- a/packages/wrangler/src/index.tsx +++ b/packages/wrangler/src/index.tsx @@ -922,6 +922,7 @@ export async function main(argv: string[]): Promise { vars: config.vars, wasm_modules: config.wasm_modules, text_blobs: config.text_blobs, + data_blobs: config.data_blobs, durable_objects: config.durable_objects, r2_buckets: config.r2_buckets, unsafe: config.unsafe?.bindings, @@ -1304,6 +1305,7 @@ export async function main(argv: string[]): Promise { vars: config.vars, wasm_modules: config.wasm_modules, text_blobs: config.text_blobs, + data_blobs: config.data_blobs, durable_objects: config.durable_objects, r2_buckets: config.r2_buckets, unsafe: config.unsafe?.bindings, @@ -1493,6 +1495,7 @@ export async function main(argv: string[]): Promise { r2_buckets: [], wasm_modules: {}, text_blobs: {}, + data_blobs: {}, unsafe: [], }, modules: [], diff --git a/packages/wrangler/src/module-collection.ts b/packages/wrangler/src/module-collection.ts index 491777df4c66..a97e221dafd4 100644 --- a/packages/wrangler/src/module-collection.ts +++ b/packages/wrangler/src/module-collection.ts @@ -218,18 +218,12 @@ export default function createModuleCollector(props: { build.onLoad( { filter: globToRegExp(glob) }, async (args: esbuild.OnLoadArgs) => { - if (rule.type === "Data") { - throw new Error( - "Data modules are not supported in the service-worker format" - ); - } return { // We replace the the module with an identifier // that we'll separately add to the form upload - // as part of [wasm_modules]/[text_blobs]. This identifier has to be a valid + // as part of [wasm_modules]/[text_blobs]/[data_blobs]. This identifier has to be a valid // JS identifier, so we replace all non alphanumeric characters // with an underscore. - // TODO: what of "Data"? contents: `export default ${args.path.replace( /[^a-zA-Z0-9_$]/g, "_" diff --git a/packages/wrangler/src/publish.ts b/packages/wrangler/src/publish.ts index 1e40cb50c5be..2655a5f41e49 100644 --- a/packages/wrangler/src/publish.ts +++ b/packages/wrangler/src/publish.ts @@ -86,7 +86,13 @@ export default async function publish(props: Props): Promise { if (config.text_blobs && format === "modules") { throw new Error( - "You cannot configure [text_blobs] with an ES module worker. Instead, import the file directly in your code, and optionally configure `[build.upload.rules]` in your wrangler.toml" + "You cannot configure [text_blobs] with an ES module worker. Instead, import the file directly in your code, and optionally configure `[rules]` in your wrangler.toml" + ); + } + + if (config.data_blobs && format === "modules") { + throw new Error( + "You cannot configure [data_blobs] with an ES module worker. Instead, import the file directly in your code, and optionally configure `[rules]` in your wrangler.toml" ); } @@ -199,6 +205,7 @@ export default async function publish(props: Props): Promise { __STATIC_CONTENT_MANIFEST: "__STATIC_CONTENT_MANIFEST", }), }, + data_blobs: config.data_blobs, durable_objects: config.durable_objects, r2_buckets: config.r2_buckets, unsafe: config.unsafe?.bindings, diff --git a/packages/wrangler/src/worker.ts b/packages/wrangler/src/worker.ts index 419708ee3734..dfe5a1087caa 100644 --- a/packages/wrangler/src/worker.ts +++ b/packages/wrangler/src/worker.ts @@ -90,6 +90,14 @@ interface CfTextBlobBindings { [key: string]: string; } +/** + * A binding to a data blob (in service-worker format) + */ + +interface CfDataBlobBindings { + [key: string]: string; +} + /** * A Durable Object. */ @@ -146,6 +154,7 @@ export interface CfWorkerInit { kv_namespaces: CfKvNamespace[] | undefined; wasm_modules: CfWasmModuleBindings | undefined; text_blobs: CfTextBlobBindings | undefined; + data_blobs: CfDataBlobBindings | undefined; durable_objects: { bindings: CfDurableObject[] } | undefined; r2_buckets: CfR2Bucket[] | undefined; unsafe: CfUnsafeBinding[] | undefined;