diff --git a/.changeset/thick-dots-sit.md b/.changeset/thick-dots-sit.md new file mode 100644 index 000000000000..9170ed557086 --- /dev/null +++ b/.changeset/thick-dots-sit.md @@ -0,0 +1,32 @@ +--- +"wrangler": patch +--- + +add support for assets bindings to `getPlatformProxy` + +this change makes sure that that `getPlatformProxy`, when the input configuration +file contains an assets field, correctly returns the appropriate asset binding proxy + +example: + +```jsonc +// wrangler.jsonc +{ + "name": "my-worker", + "assets": { + "directory": "./public/", + "binding": "ASSETS", + }, +} +``` + +```js +import { getPlatformProxy } from "wrangler"; + +const { env, dispose } = await getPlatformProxy(); + +const text = await (await env.ASSETS.fetch("http://0.0.0.0/file.txt")).text(); +console.log(text); // logs the content of file.txt + +await dispose(); +``` diff --git a/fixtures/get-platform-proxy/public/test.txt b/fixtures/get-platform-proxy/public/test.txt new file mode 100644 index 000000000000..2dd981b4d688 --- /dev/null +++ b/fixtures/get-platform-proxy/public/test.txt @@ -0,0 +1 @@ +this is a test text file! diff --git a/fixtures/get-platform-proxy/tests/get-platform-proxy.env.test.ts b/fixtures/get-platform-proxy/tests/get-platform-proxy.env.test.ts index 74f7f17646b0..2fc44412ffa4 100644 --- a/fixtures/get-platform-proxy/tests/get-platform-proxy.env.test.ts +++ b/fixtures/get-platform-proxy/tests/get-platform-proxy.env.test.ts @@ -10,7 +10,11 @@ import { vi, } from "vitest"; import { getPlatformProxy } from "./shared"; -import type { Hyperdrive, KVNamespace } from "@cloudflare/workers-types"; +import type { + Fetcher, + Hyperdrive, + KVNamespace, +} from "@cloudflare/workers-types"; import type { Unstable_DevWorker } from "wrangler"; type Env = { @@ -23,6 +27,7 @@ type Env = { MY_BUCKET: R2Bucket; MY_D1: D1Database; MY_HYPERDRIVE: Hyperdrive; + ASSETS: Fetcher; }; const wranglerConfigFilePath = path.join(__dirname, "..", "wrangler.jsonc"); @@ -123,6 +128,16 @@ describe("getPlatformProxy - env", () => { } }); + it("correctly obtains functioning ASSETS bindings", async () => { + const { env, dispose } = await getPlatformProxy({ + configPath: wranglerConfigFilePath, + }); + const res = await env.ASSETS.fetch("https://0.0.0.0/test.txt"); + const text = await res.text(); + expect(text).toEqual("this is a test text file!\n"); + await dispose(); + }); + it("correctly obtains functioning KV bindings", async () => { const { env, dispose } = await getPlatformProxy({ configPath: wranglerConfigFilePath, diff --git a/fixtures/get-platform-proxy/wrangler.jsonc b/fixtures/get-platform-proxy/wrangler.jsonc index 95f6f63b2427..545d04d6b578 100644 --- a/fixtures/get-platform-proxy/wrangler.jsonc +++ b/fixtures/get-platform-proxy/wrangler.jsonc @@ -2,6 +2,12 @@ "name": "get-bindings-proxy-fixture", "main": "src/index.ts", "compatibility_date": "2023-11-21", + "assets": { + "directory": "./public", + "binding": "ASSETS", + "html_handling": "auto-trailing-slash", + "not_found_handling": "none", + }, "vars": { "MY_VAR": "my-var-value", "MY_VAR_A": "my-var-a", diff --git a/packages/wrangler/src/api/integrations/platform/index.ts b/packages/wrangler/src/api/integrations/platform/index.ts index 1f4ef6f2da87..a9461fd40332 100644 --- a/packages/wrangler/src/api/integrations/platform/index.ts +++ b/packages/wrangler/src/api/integrations/platform/index.ts @@ -1,5 +1,5 @@ import { kCurrentWorker, Miniflare } from "miniflare"; -import { getAssetsOptions } from "../../../assets"; +import { getAssetsOptions, NonExistentAssetsDirError } from "../../../assets"; import { readConfig } from "../../../config"; import { partitionDurableObjectBindings } from "../../../deployment-bundle/entry"; import { DEFAULT_MODULE_RULES } from "../../../deployment-bundle/rules"; @@ -218,6 +218,24 @@ async function getMiniflareOptionsFromConfig(args: { remoteBindingsEnabled ); + let processedAssetOptions: AssetsOptions | undefined; + + try { + processedAssetOptions = getAssetsOptions({ assets: undefined }, config); + } catch (e) { + const isNonExistentError = e instanceof NonExistentAssetsDirError; + // we want to loosen up the assets directory existence restriction here, + // since `getPlatformProxy` can be run when the assets directory doesn't actual + // exist, but all other exceptions should still be thrown + if (!isNonExistentError) { + throw e; + } + } + + const assetOptions = processedAssetOptions + ? buildAssetOptions({ assets: processedAssetOptions }) + : {}; + const defaultPersistRoot = getMiniflarePersistRoot(options.persist); const serviceBindings = await getServiceBindings(bindings.services); @@ -233,6 +251,7 @@ async function getMiniflareOptionsFromConfig(args: { ...serviceBindings, ...bindingOptions.serviceBindings, }, + ...assetOptions, }, ...externalWorkers, ], diff --git a/packages/wrangler/src/assets.ts b/packages/wrangler/src/assets.ts index aaa0ae883b17..25f5931d5d24 100644 --- a/packages/wrangler/src/assets.ts +++ b/packages/wrangler/src/assets.ts @@ -393,6 +393,8 @@ export type AssetsOptions = { run_worker_first?: boolean | string[]; }; +export class NonExistentAssetsDirError extends UserError {} + export function getAssetsOptions( args: { assets: string | undefined; script?: string }, config: Config, @@ -429,7 +431,7 @@ export function getAssetsOptions( ? '"--assets" command line argument' : '"assets.directory" field in your configuration file'; - throw new UserError( + throw new NonExistentAssetsDirError( `The directory specified by the ${sourceOfTruthMessage} does not exist:\n` + `${directory}`,