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 a3232441d267..88ec38601403 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"; @@ -18,6 +18,7 @@ import { dedent } from "../../../utils/dedent"; import { CacheStorage } from "./caches"; import { ExecutionContext } from "./executionContext"; import { getServiceBindings } from "./services"; +import type { AssetsOptions } from "../../../assets"; import type { Config, RawConfig, RawEnvironment } from "../../../config"; import type { IncomingRequestCfProperties } from "@cloudflare/workers-types/experimental"; import type { MiniflareOptions, ModuleRule, WorkerOptions } from "miniflare"; @@ -171,10 +172,28 @@ async function getMiniflareOptionsFromConfig( imagesLocalMode: false, }); - const persistOptions = getMiniflarePersistOptions(options.persist); + let processedAssetOptions: AssetsOptions | undefined; + + try { + processedAssetOptions = getAssetsOptions({ assets: undefined }, rawConfig); + } 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 serviceBindings = await getServiceBindings(bindings.services); + const persistOptions = getMiniflarePersistOptions(options.persist); + const miniflareOptions: MiniflareOptions = { workers: [ { @@ -186,6 +205,7 @@ async function getMiniflareOptionsFromConfig( ...serviceBindings, ...bindingOptions.serviceBindings, }, + ...assetOptions, }, ...externalWorkers, ], diff --git a/packages/wrangler/src/assets.ts b/packages/wrangler/src/assets.ts index 514d815272c2..565e06319e07 100644 --- a/packages/wrangler/src/assets.ts +++ b/packages/wrangler/src/assets.ts @@ -354,6 +354,8 @@ export type AssetsOptions = { _headers?: string; }; +export class NonExistentAssetsDirError extends UserError {} + export function getAssetsOptions( args: { assets: string | undefined; script?: string }, config: Config @@ -387,7 +389,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` + `${resolvedAssetsPath}`,