Skip to content

Commit

Permalink
feat!: use getPlatformProxy and provide more context fields (#6)
Browse files Browse the repository at this point in the history
  • Loading branch information
dario-piotrowicz authored Mar 8, 2024
1 parent 483955a commit ec53843
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 32 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Cloudflare Bindings for Nitro and Nuxt
# Cloudflare Platform for Nitro and Nuxt

This proof of concept module enables access to the Cloudflare runtime bindings in the development server of [Nitro](https://nitro.unjs.io) and [Nuxt](https://nuxt.com) using the [new `getBindingsProxy` API](https://github.com/cloudflare/workers-sdk/pull/4523) exposed by [wrangler](https://developers.cloudflare.com/workers/wrangler/) and [miniflare](https://miniflare.dev/)
This proof of concept module enables access to the Cloudflare runtime platform in the development server of [Nitro](https://nitro.unjs.io) and [Nuxt](https://nuxt.com) using the [new `getPlatformProxy` API](https://github.com/cloudflare/workers-sdk/pull/5002) exposed by [wrangler](https://developers.cloudflare.com/workers/wrangler/) and [miniflare](https://miniflare.dev/)

> [!NOTE]
> Nitro plans to introduce a new method to allow native dev presets, meaning you can natively run [miniflare](https://miniflare.dev/) as your development server without this module or a proxy in the future!
Expand Down
4 changes: 2 additions & 2 deletions examples/nitro/routes/counter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ export default eventHandler(async (event) => {
const { KV } = event.context.cloudflare.env;

let ctr = (await KV.get("counter")) || 0;
await KV.put("counter", ++ctr);
await KV.put("counter", ++ctr % 100);

return { counter: ctr };
return `counter: ${(await KV.get("counter")) || 0}`;
});
20 changes: 17 additions & 3 deletions examples/nitro/routes/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,18 @@
export default eventHandler(async () => {
const { counter } = (await $fetch("/counter")) as { counter: number };
return `<div>Counter: ${counter}</div>`;
export default eventHandler(async (event) => {
const cloudflare = await event.context.cloudflare;

const logs: string[] = [];
const log = (str: string) => logs.push(str);

log(`Keys of cloudflare: ${Object.keys(cloudflare).join(", ")}`);

log(`Keys of cloudflare.env: ${Object.keys(cloudflare.env).join(", ")}`);

log(`Colo: ${cloudflare.request.cf.colo}`);

log(
`typeof cloudflare.context.waitUntil: ${typeof cloudflare.context.waitUntil}`,
);

return `<div><ul><br>${logs.map((str) => `<li>${str}</li>`).join("\n<br>\n")}</ul></div>`;
});
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
"prettier": "^3.2.4",
"typescript": "^5.2.2",
"unbuild": "^2.0.0",
"wrangler": "^3.24.0"
"wrangler": "^3.28.2"
},
"packageManager": "[email protected]"
}
87 changes: 72 additions & 15 deletions pnpm-lock.yaml

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

64 changes: 55 additions & 9 deletions src/runtime/plugin.dev.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,52 @@
import type { NitroAppPlugin } from "nitropack";
// @ts-ignore
import { useRuntimeConfig } from "#imports";
import { useRuntimeConfig, getRequestURL } from "#imports";

export default <NitroAppPlugin>function (nitroApp) {
let _proxy: ReturnType<typeof getBindingsProxy>;
let _proxy: ReturnType<typeof getPlatformProxy>;

nitroApp.hooks.hook("request", async (event) => {
// Lazy initialize proxy when first request comes in
if (!_proxy) {
_proxy = getBindingsProxy().catch((error) => {
_proxy = getPlatformProxy().catch((error) => {
console.error("Failed to initialize wrangler bindings proxy", error);
return { bindings: {}, dispose: () => Promise.resolve() };
return {
env: {},
cf: {},
ctx: {
waitUntil() {},
passThroughOnException() {},
},
caches: {
open(): Promise<Cache> {
const result = Promise.resolve(new Cache());
return result;
},
get default(): Cache {
return new Cache();
},
},
dispose: () => Promise.resolve(),
} as unknown as ReturnType<typeof getPlatformProxy>;
});
}

// Inject proxy bindings to the request context
const proxy = await _proxy;

// Inject the various cf values from the proxy in event and event.context

event.waitUntil = proxy.ctx.waitUntil;
(event.context as any).cf = proxy.cf;
(event.context as any).waitUntil = proxy.ctx.waitUntil;

const request = new Request(getRequestURL(event));
(request as any).cf = proxy.cf;

event.context.cloudflare = {
...event.context.cloudflare,
env: (await _proxy).bindings,
request,
env: proxy.env,
context: proxy.ctx,
};
});

Expand All @@ -27,20 +56,37 @@ export default <NitroAppPlugin>function (nitroApp) {
});
};

async function getBindingsProxy() {
async function getPlatformProxy() {
const _pkg = "wrangler"; // Bypass bundling!
const { getBindingsProxy } = (await import(
const { getPlatformProxy } = (await import(
_pkg
)) as typeof import("wrangler");

const runtimeConfig: {
wrangler: { configPath: string; persistDir: string };
} = useRuntimeConfig();

const proxy = await getBindingsProxy({
const proxy = await getPlatformProxy({
configPath: runtimeConfig.wrangler.configPath,
persist: { path: runtimeConfig.wrangler.persistDir },
});

return proxy;
}

class Cache {
delete(): Promise<boolean> {
const result = Promise.resolve(false);
return result;
}

match() {
const result = Promise.resolve(undefined);
return result;
}

put(): Promise<void> {
const result = Promise.resolve();
return result;
}
}

0 comments on commit ec53843

Please sign in to comment.