Skip to content

Commit

Permalink
feat(cloudflare): Add KV Bindings
Browse files Browse the repository at this point in the history
  • Loading branch information
alexanderniebuhr committed Sep 26, 2023
1 parent eeb07e9 commit 8d3d083
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changeset/funny-cobras-accept.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@astrojs/cloudflare': minor
---

Introduce support for local KV bindings. Enhance development experience by allowing direct integration with `astro dev`.
1 change: 1 addition & 0 deletions packages/integrations/cloudflare/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ Currently supported bindings:

- [D1](https://developers.cloudflare.com/d1/)
- [R2](https://developers.cloudflare.com/r2/)
- [KV](https://developers.cloudflare.com/kv/)

### Access

Expand Down
9 changes: 8 additions & 1 deletion packages/integrations/cloudflare/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import glob from 'tiny-glob';
import { getAdapter } from './getAdapter.js';
import { deduplicatePatterns } from './utils/deduplicatePatterns.js';
import { getCFObject } from './utils/getCFObject.js';
import { getD1Bindings, getEnvVars, getR2Bindings } from './utils/parser.js';
import { getD1Bindings, getEnvVars, getKVBindings, getR2Bindings } from './utils/parser.js';
import { prependForwardSlash } from './utils/prependForwardSlash.js';
import { rewriteWasmImportPath } from './utils/rewriteWasmImportPath.js';
import { wasmModuleLoader } from './utils/wasm-module-loader.js';
Expand Down Expand Up @@ -126,6 +126,7 @@ export default function createIntegration(args?: Options): AstroIntegration {
const vars = await getEnvVars();
const D1Bindings = await getD1Bindings();
const R2Bindings = await getR2Bindings();
const KVBindings = await getKVBindings();

let bindingsEnv = new Object({});

Expand All @@ -143,6 +144,8 @@ export default function createIntegration(args?: Options): AstroIntegration {
d1Persist: true,
r2Buckets: R2Bindings,
r2Persist: true,
kvNamespaces: KVBindings,
kvPersist: true,
});
await _mf.ready;

Expand All @@ -154,6 +157,10 @@ export default function createIntegration(args?: Options): AstroIntegration {
const bucket = await _mf.getR2Bucket(R2Binding);
Reflect.set(bindingsEnv, R2Binding, bucket);
}
for (const KVBinding of KVBindings) {
const namespace = await _mf.getKVNamespace(KVBinding);
Reflect.set(bindingsEnv, KVBinding, namespace);
}

process.env.PWD = originalPWD;
const clientLocalsSymbol = Symbol.for('astro.locals');
Expand Down
10 changes: 10 additions & 0 deletions packages/integrations/cloudflare/src/utils/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,3 +158,13 @@ export async function getR2Bindings() {
);
return bindings;
}

export async function getKVBindings() {
const { rawConfig } = parseConfig();
if (!rawConfig) return [];
if (!rawConfig?.kv_namespaces) return [];
const bindings = (rawConfig?.kv_namespaces as []).map(
(binding: { binding: string }) => binding.binding
);
return bindings;
}
12 changes: 12 additions & 0 deletions packages/integrations/cloudflare/test/cf.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,4 +95,16 @@ describe('Astro Cloudflare Runtime', () => {
expect($('#hasPRODBUCKET').text()).to.equal('true');
expect($('#hasACCESS').text()).to.equal('true');
});

it('adds KV mocking', async () => {
expect(await fixture.pathExists('../.mf/kv')).to.be.true;

let res = await fixture.fetch('/kv');
expect(res.status).to.equal(200);
let html = await res.text();
let $ = cheerio.load(html);
expect($('#hasKV').text()).to.equal('true');
expect($('#hasPRODKV').text()).to.equal('true');
expect($('#hasACCESS').text()).to.equal('true');
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
const runtime = Astro.locals.runtime;
const kv = runtime.env?.KV;
await kv.put("test", "true");
const result = await kv.get("test")
---

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>KV</title>
</head>
<body>
<pre id="hasKV">{!!runtime.env?.KV}</pre>
<pre id="hasPRODKV">{!!runtime.env?.KV_PROD}</pre>
<pre id="hasACCESS">{!!result}</pre>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
name = "test"

kv_namespaces = [
{ binding = "KV", id = "<YOUR_ID>", preview_id = "<YOUR_ID>" },
{ binding = "KV_PROD", id = "<YOUR_ID>", preview_id = "<YOUR_ID>" }
]

[vars]
COOL = "ME"

Expand All @@ -22,3 +27,4 @@ bucket_name = '<YOUR_BUCKET_NAME>'
[[r2_buckets]]
binding = 'R2_PROD' # <~ valid JavaScript variable name
bucket_name = '<YOUR_BUCKET_NAME>'

0 comments on commit 8d3d083

Please sign in to comment.