Skip to content

Commit

Permalink
enable access to cloudflare runtime (withastro#5103)
Browse files Browse the repository at this point in the history
* enable access to cloudflare runtime

* added get runtime api
added context to the runtime in "advanced" mode

* added typings and adjusted some return vars

* added default types

* added usage description to changeset and readme

Co-authored-by: AirBorne04 <unknown>
Co-authored-by: AirBorne04 <>
  • Loading branch information
AirBorne04 committed Oct 26, 2022
1 parent 4efbfdd commit d151d9f
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 4 deletions.
6 changes: 6 additions & 0 deletions .changeset/poor-frogs-clean.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@astrojs/cloudflare': patch
---

enable access to cloudflare runtime [KV, R2, Durable Objects]
- access native cloudflare runtime through `import { getRuntime } from "@astrojs/cloudflare/runtime"` now you can call `getRuntime(Astro.request)` and get access to the runtime environment
12 changes: 12 additions & 0 deletions packages/integrations/cloudflare/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,18 @@ $ pnpm install wrangler --save-dev

It's then possible to update the preview script in your `package.json` to `"preview": "wrangler pages dev ./dist"`.This will allow you run your entire application locally with [Wrangler](https://github.com/cloudflare/wrangler2), which supports secrets, environment variables, KV namespaces, Durable Objects and [all other supported Cloudflare bindings](https://developers.cloudflare.com/pages/platform/functions/#adding-bindings).

## Access to the cloudflare runtime

You have the posibility to access all the cloudflare bindings and environment variables from your astro pages and api routes through the adapter API

```
import { getRuntime } from "@astrojs/cloudflare/runtime";
getRuntime(Astro.request);
```

Depending your adapter mode (advanced = worker, directory = pages) the runtime object will look a little different due to the difference in the cloudflare API.

## Streams

Some integrations such as [React](https://github.com/withastro/astro/tree/main/packages/integrations/react) rely on web streams. Currently Cloudflare Pages Functions require enabling a flag to support Streams.
Expand Down
3 changes: 2 additions & 1 deletion packages/integrations/cloudflare/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@astrojs/cloudflare",
"description": "Deploy your site to cloudflare pages functions",
"description": "Deploy your site to cloudflare workers or cloudflare pages",
"version": "3.1.0",
"type": "module",
"types": "./dist/index.d.ts",
Expand All @@ -19,6 +19,7 @@
"homepage": "https://docs.astro.build/en/guides/integrations-guide/cloudflare/",
"exports": {
".": "./dist/index.js",
"./runtime": "./dist/runtime.js",
"./server.advanced.js": "./dist/server.advanced.js",
"./server.directory.js": "./dist/server.directory.js",
"./package.json": "./package.json"
Expand Down
28 changes: 28 additions & 0 deletions packages/integrations/cloudflare/src/runtime.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
export type WorkerRuntime<T = unknown> = {
name: 'cloudflare';
env: T;
waitUntil(promise: Promise<any>): void;
passThroughOnException(): void;
};

export type PagesRuntime<T = unknown, U = unknown> = {
name: 'cloudflare';
env: T;
functionPath: string;
params: Record<string, string>;
data: U;
waitUntil(promise: Promise<any>): void;
next(request: Request): void;
};

export function getRuntime<T = unknown, U = unknown>(
request: Request
): WorkerRuntime<T> | PagesRuntime<T, U> {
if (!!request) {
return Reflect.get(request, Symbol.for('runtime'));
} else {
throw new Error(
'To retrieve the current cloudflare runtime you need to pass in the Astro request object'
);
}
}
4 changes: 3 additions & 1 deletion packages/integrations/cloudflare/src/server.advanced.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ import { App } from 'astro/app';

type Env = {
ASSETS: { fetch: (req: Request) => Promise<Response> };
name: string;
};

export function createExports(manifest: SSRManifest) {
const app = new App(manifest, false);

const fetch = async (request: Request, env: Env) => {
const fetch = async (request: Request, env: Env, context: any) => {
const { origin, pathname } = new URL(request.url);

// static assets
Expand All @@ -26,6 +27,7 @@ export function createExports(manifest: SSRManifest) {
Symbol.for('astro.clientAddress'),
request.headers.get('cf-connecting-ip')
);
Reflect.set(request, Symbol.for('runtime'), { env, name: 'cloudflare', ...context });
let response = await app.render(request, routeData);

if (app.setCookieHeaders) {
Expand Down
9 changes: 7 additions & 2 deletions packages/integrations/cloudflare/src/server.directory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ export function createExports(manifest: SSRManifest) {
const onRequest = async ({
request,
next,
...runtimeEnv
}: {
request: Request;
next: (request: Request) => void;
}) => {
} & Record<string, unknown>) => {
const { origin, pathname } = new URL(request.url);

// static assets
if (manifest.assets.has(pathname)) {
const assetRequest = new Request(`${origin}/static${pathname}`, request);
Expand All @@ -28,6 +28,11 @@ export function createExports(manifest: SSRManifest) {
Symbol.for('astro.clientAddress'),
request.headers.get('cf-connecting-ip')
);
Reflect.set(request, Symbol.for('runtime'), {
...runtimeEnv,
name: 'cloudflare',
next,
});
let response = await app.render(request, routeData);

if (app.setCookieHeaders) {
Expand Down

0 comments on commit d151d9f

Please sign in to comment.