summaryrefslogtreecommitdiff
path: root/cli
diff options
context:
space:
mode:
authorHeyang Zhou <zhy20000919@hotmail.com>2023-08-22 13:56:00 +0800
committerGitHub <noreply@github.com>2023-08-22 13:56:00 +0800
commit6d4a005e4108a5dd762b339a02bc4d802755ba0d (patch)
tree69679038bfbd3127f6c1e1b85dbc347c8c52e36e /cli
parent5834d282d4de5d0b5cacb9bf068f3896bef0a48a (diff)
feat(ext/kv): connect to remote database (#20178)
This patch adds a `remote` backend for `ext/kv`. This supports connection to Deno Deploy and potentially other services compatible with the KV Connect protocol.
Diffstat (limited to 'cli')
-rw-r--r--cli/Cargo.toml2
-rw-r--r--cli/schemas/kv-metadata-exchange-response.v1.json54
-rw-r--r--cli/tests/unit/kv_test.ts74
3 files changed, 129 insertions, 1 deletions
diff --git a/cli/Cargo.toml b/cli/Cargo.toml
index dec23e6a5..b8a22b293 100644
--- a/cli/Cargo.toml
+++ b/cli/Cargo.toml
@@ -66,7 +66,7 @@ base32 = "=0.4.0"
base64.workspace = true
bincode = "=1.3.3"
cache_control.workspace = true
-chrono = { version = "=0.4.26", default-features = false, features = ["std"] }
+chrono.workspace = true
clap = { version = "=4.3.3", features = ["string"] }
clap_complete = "=4.3.1"
clap_complete_fig = "=4.3.1"
diff --git a/cli/schemas/kv-metadata-exchange-response.v1.json b/cli/schemas/kv-metadata-exchange-response.v1.json
new file mode 100644
index 000000000..aa29242fb
--- /dev/null
+++ b/cli/schemas/kv-metadata-exchange-response.v1.json
@@ -0,0 +1,54 @@
+{
+ "$id": "https://deno.land/x/deno/cli/schemas/kv-metadata-exchange-response.v1.json",
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "definitions": {
+ "Uuid": {
+ "type": "string",
+ "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
+ },
+ "DateTime": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "EndpointInfo": {
+ "type": "object",
+ "properties": {
+ "url": {
+ "type": "string"
+ },
+ "consistency": {
+ "type": "string"
+ }
+ },
+ "required": ["url", "consistency"],
+ "additionalProperties": false
+ },
+ "DatabaseMetadata": {
+ "type": "object",
+ "properties": {
+ "version": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "databaseId": {
+ "$ref": "#/definitions/Uuid"
+ },
+ "endpoints": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/EndpointInfo"
+ }
+ },
+ "token": {
+ "type": "string"
+ },
+ "expiresAt": {
+ "$ref": "#/definitions/DateTime"
+ }
+ },
+ "required": ["version", "databaseId", "endpoints", "token", "expiresAt"],
+ "additionalProperties": false
+ }
+ },
+ "$ref": "#/definitions/DatabaseMetadata"
+}
diff --git a/cli/tests/unit/kv_test.ts b/cli/tests/unit/kv_test.ts
index 438ebd7ee..acda9a0e2 100644
--- a/cli/tests/unit/kv_test.ts
+++ b/cli/tests/unit/kv_test.ts
@@ -20,6 +20,9 @@ try {
isCI = true;
}
+// Defined in test_util/src/lib.rs
+Deno.env.set("DENO_KV_ACCESS_TOKEN", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
+
Deno.test({
name: "openKv :memory: no permissions",
permissions: {},
@@ -1932,3 +1935,74 @@ Deno.test({
}
},
});
+
+Deno.test({
+ name: "remote backend",
+ async fn() {
+ const db = await Deno.openKv("http://localhost:4545/kv_remote_authorize");
+ try {
+ await db.set(["some-key"], 1);
+ const entry = await db.get(["some-key"]);
+ assertEquals(entry.value, null);
+ assertEquals(entry.versionstamp, null);
+ } finally {
+ db.close();
+ }
+ },
+});
+
+Deno.test({
+ name: "remote backend invalid format",
+ async fn() {
+ const db = await Deno.openKv(
+ "http://localhost:4545/kv_remote_authorize_invalid_format",
+ );
+ let ok = false;
+ try {
+ await db.set(["some-key"], 1);
+ } catch (e) {
+ if (
+ e.name === "TypeError" &&
+ e.message.startsWith("Metadata error: Failed to decode metadata: ")
+ ) {
+ ok = true;
+ } else {
+ throw e;
+ }
+ } finally {
+ db.close();
+ }
+
+ if (!ok) {
+ throw new Error("did not get expected error");
+ }
+ },
+});
+
+Deno.test({
+ name: "remote backend invalid version",
+ async fn() {
+ const db = await Deno.openKv(
+ "http://localhost:4545/kv_remote_authorize_invalid_version",
+ );
+ let ok = false;
+ try {
+ await db.set(["some-key"], 1);
+ } catch (e) {
+ if (
+ e.name === "TypeError" &&
+ e.message === "Metadata error: Unsupported metadata version: 2"
+ ) {
+ ok = true;
+ } else {
+ throw e;
+ }
+ } finally {
+ db.close();
+ }
+
+ if (!ok) {
+ throw new Error("did not get expected error");
+ }
+ },
+});