Skip to content

Commit

Permalink
expose no-op caches in getBindingsProxy
Browse files Browse the repository at this point in the history
  • Loading branch information
dario-piotrowicz committed Jan 29, 2024
1 parent 42ec8e2 commit 75b4184
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 7 deletions.
12 changes: 12 additions & 0 deletions .changeset/happy-pandas-sparkle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
"wrangler": minor
---

expose new (no-op) `caches` field in `getBindingsProxy` result

add a new `caches` field to the `getBindingsProxy` result, such field implements a
no operation (no-op) implementation of the runtime `caches`

Note: Miniflare exposes a proper `caches` mock, we will want to use that one in
the future but issues regarding it must be ironed out first, so for the
time being a no-op will have to do
3 changes: 3 additions & 0 deletions fixtures/get-bindings-proxy/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,8 @@
"@cloudflare/workers-tsconfig": "workspace:*",
"@cloudflare/workers-types": "^4.20221111.1",
"wrangler": "workspace:*"
},
"dependencies": {
"undici": "^5.28.2"
}
}
34 changes: 34 additions & 0 deletions fixtures/get-bindings-proxy/tests/get-bindings-proxy.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
Fetcher,
R2Bucket,
} from "@cloudflare/workers-types";
import { Request, Response } from "undici";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import {
getBindingsProxy as originalGetBindingsProxy,
Expand Down Expand Up @@ -227,6 +228,25 @@ describe("getBindingsProxy", () => {
await dispose();
}
});

describe("caches", () => {
(["default", "named"] as const).forEach((cacheType) =>
it(`correctly obtains a no-op ${cacheType} cache`, async () => {
const { caches, dispose } = await getBindingsProxy<Bindings>({
configPath: wranglerTomlFilePath,
});
try {
const cache =
cacheType === "default"
? caches.default
: await caches.open("my-cache");
testNoOpCache(cache);
} finally {
await dispose();
}
})
);
});
});

/**
Expand Down Expand Up @@ -263,3 +283,17 @@ async function testDoBinding(
const doRespText = await doResp.text();
expect(doRespText).toBe(expectedResponse);
}

async function testNoOpCache(
cache: Awaited<ReturnType<typeof getBindingsProxy>>["caches"]["default"]
) {
let match = await cache.match("http://0.0.0.0/test");
expect(match).toBeUndefined();

const req = new Request("http://0.0.0.0/test");
await cache.put(req, new Response("test"));
const resp = await cache.match(req);
expect(resp).toBeUndefined();
const deleted = await cache.delete(req);
expect(deleted).toBe(false);
}
53 changes: 53 additions & 0 deletions packages/wrangler/src/api/integrations/bindings/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ export type BindingsProxy<Bindings = Record<string, unknown>> = {
* Object containing the various proxies
*/
bindings: Bindings;
/**
* Caches object emulating the Workers Cache runtime API
*/
caches: CacheStorage;
/**
* Function used to dispose of the child process providing the bindings implementation
*/
Expand Down Expand Up @@ -83,6 +87,7 @@ export async function getBindingsProxy<Bindings = Record<string, unknown>>(
...vars,
...bindings,
},
caches: getNoopCaches(),
dispose: () => mf.dispose(),
};
}
Expand Down Expand Up @@ -162,3 +167,51 @@ function getMiniflarePersistOptions(
d1Persist: `${persistPath}/d1`,
};
}

// Note as to why we are re-implementing the Cache types here:
// The Request and Response types to be used with the caches come from miniflare itself, if we
// were to use the proper types users would need to provided to the utility objects typed with
// the actual miniflare types, which is actually what we don't want, so for now we just use
// `unknown`s and we can think of better types later when we actually make the `caches` non no-op
type CacheStorage = {
open(cacheName: string): Promise<Cache>;
readonly default: Cache;
};
type CacheRequest = unknown;
type CacheResponse = unknown;

type Cache = {
delete(request: CacheRequest, options?: CacheQueryOptions): Promise<boolean>;
match(
request: CacheRequest,
options?: CacheQueryOptions
): Promise<CacheResponse | undefined>;
put(request: CacheRequest, response: CacheResponse): Promise<void>;
};
type CacheQueryOptions = {
ignoreMethod?: boolean;
};

function getNoopCache(): Cache {
const noopCache: Cache = {
async delete() {
return false;

Check warning on line 198 in packages/wrangler/src/api/integrations/bindings/index.ts

View check run for this annotation

Codecov / codecov/patch

packages/wrangler/src/api/integrations/bindings/index.ts#L195-L198

Added lines #L195 - L198 were not covered by tests
},
async match() {
return undefined;

Check warning on line 201 in packages/wrangler/src/api/integrations/bindings/index.ts

View check run for this annotation

Codecov / codecov/patch

packages/wrangler/src/api/integrations/bindings/index.ts#L200-L201

Added lines #L200 - L201 were not covered by tests
},
async put() {},

Check warning on line 203 in packages/wrangler/src/api/integrations/bindings/index.ts

View check run for this annotation

Codecov / codecov/patch

packages/wrangler/src/api/integrations/bindings/index.ts#L203

Added line #L203 was not covered by tests
};
return noopCache;

Check warning on line 205 in packages/wrangler/src/api/integrations/bindings/index.ts

View check run for this annotation

Codecov / codecov/patch

packages/wrangler/src/api/integrations/bindings/index.ts#L205

Added line #L205 was not covered by tests
}

// We are not ready to expose miniflare's caches as those are problematic to use in a generic context
// (since they only accept instances of the miniflare Request class and return only instances of the
// miniflare Response class, making them tricky to use in generic node.js code), so we provide a no-op
// implementation here until we sort the above issue out
function getNoopCaches(): CacheStorage {
return {

Check warning on line 213 in packages/wrangler/src/api/integrations/bindings/index.ts

View check run for this annotation

Codecov / codecov/patch

packages/wrangler/src/api/integrations/bindings/index.ts#L212-L213

Added lines #L212 - L213 were not covered by tests
default: getNoopCache(),
open: () => Promise.resolve(getNoopCache()),

Check warning on line 215 in packages/wrangler/src/api/integrations/bindings/index.ts

View check run for this annotation

Codecov / codecov/patch

packages/wrangler/src/api/integrations/bindings/index.ts#L215

Added line #L215 was not covered by tests
};
}
18 changes: 11 additions & 7 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 75b4184

Please sign in to comment.