Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/pullrequest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ jobs:
- name: Setup node
uses: actions/setup-node@v4
with:
node-version: 18
node-version: 22

- name: Install packages
run: |
Expand Down
1,677 changes: 1,197 additions & 480 deletions package-lock.json

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"dependencies": {
"@changesets/changelog-github": "^0.4.8",
"@changesets/cli": "^2.29.4",
"@cloudflare/workers-types": "^4.20240909.0"
"@cloudflare/workers-types": "^4.20250724.0"
},
"name": "workers-rs",
"version": "0.0.12",
Expand All @@ -15,11 +15,11 @@
"homepage": "https://github.com/cloudflare/workers-rs#readme",
"devDependencies": {
"@types/node": "^24.0.1",
"miniflare": "^3.20241230.0",
"miniflare": "^4.20250712.2",
"typescript": "^5.8.3",
"undici": "^5.29.0",
"undici": "^7.12.0",
"uuid": "^11.1.0",
"vitest": "^2.1.9"
"vitest": "^3.2.4"
},
"scripts": {
"install": "cargo install --path ./worker-build --force --debug",
Expand Down
1 change: 1 addition & 0 deletions worker-sandbox/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ mod queue;
mod r2;
mod request;
mod router;
mod secret_store;
mod service;
mod socket;
mod sql_counter;
Expand Down
6 changes: 4 additions & 2 deletions worker-sandbox/src/router.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::{
alarm, analytics_engine, assets, auto_response, cache, counter, d1, durable, fetch, form,
js_snippets, kv, put_raw, queue, r2, request, service, socket, sql_counter, sql_iterator, user,
ws, SomeSharedData, GLOBAL_STATE,
js_snippets, kv, put_raw, queue, r2, request, secret_store, service, socket, sql_counter,
sql_iterator, user, ws, SomeSharedData, GLOBAL_STATE,
};
#[cfg(feature = "http")]
use std::convert::TryInto;
Expand Down Expand Up @@ -220,6 +220,8 @@ macro_rules! add_routes (
add_route!($obj, get, "/js_snippets/log", js_snippets::console_log);
add_route!($obj, get, format_route!("/sql-counter/{}", "*path"), sql_counter::handle_sql_counter);
add_route!($obj, get, format_route!("/sql-iterator/{}", "*path"), sql_iterator::handle_sql_iterator);
add_route!($obj, get, "/get-from-secret-store", secret_store::get_from_secret_store);
add_route!($obj, get, "/get-from-secret-store-missing", secret_store::get_from_secret_store_missing);
});

#[cfg(feature = "http")]
Expand Down
32 changes: 32 additions & 0 deletions worker-sandbox/src/secret_store.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
use crate::SomeSharedData;
use worker::{Env, Request, Response, Result};

#[worker::send]
pub async fn get_from_secret_store(
_req: Request,
env: Env,
_data: SomeSharedData,
) -> Result<Response> {
let secrets = env.secret_store("SECRETS")?;
let secret_value = secrets.get().await?;

match secret_value {
Some(_value) => Response::ok("secret value"),
None => Response::error("Secret not found", 404),
}
}

#[worker::send]
pub async fn get_from_secret_store_missing(
_req: Request,
env: Env,
_data: SomeSharedData,
) -> Result<Response> {
let secrets = env.secret_store("MISSING_SECRET")?;
let secret_value = secrets.get().await?;

match secret_value {
Some(value) => Response::ok(value),
None => Response::error("Secret not found", 500),
}
}
4 changes: 2 additions & 2 deletions worker-sandbox/tests/analytics_engine.spec.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { describe, test, expect } from "vitest";
import { mf } from "./mf";
import { mf, mfUrl } from "./mf";

describe("analytics engine", () => {
test("write data point", async () => {
const resp = await mf.dispatchFetch(
`https://fake.host/analytics-engine`,
`${mfUrl}analytics-engine`,
);
console.log(await resp.text())
expect(resp.status).toBe(200);
Expand Down
6 changes: 3 additions & 3 deletions worker-sandbox/tests/assets.spec.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { describe, test, expect } from "vitest";
import { mf } from "./mf";
import { mf, mfUrl } from "./mf";

describe("assets", () => {
test("assets example", async () => {
const resp = await mf.dispatchFetch("https://fake.host/test.txt");
const resp = await mf.dispatchFetch(`${mfUrl}asset/test.txt`);
const body = await resp.text();
expect(body).toBe("TEST");
});
})
});
4 changes: 2 additions & 2 deletions worker-sandbox/tests/auto_response.spec.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { describe, test, expect } from "vitest";
import { mf } from "./mf";
import { mf, mfUrl } from "./mf";

describe("durable object websocket auto-response", () => {
test("set and get auto-response pair", async () => {
const resp = await mf.dispatchFetch("http://fake.host/durable/auto-response");
const resp = await mf.dispatchFetch(`${mfUrl}durable/auto-response`);
const text = await resp.text();
expect(text).toBe("ping:pong");
});
Expand Down
16 changes: 8 additions & 8 deletions worker-sandbox/tests/cache.spec.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
import { describe, test, expect } from "vitest";
import { mf } from "./mf";
import { mf, mfUrl } from "./mf";

describe("cache", () => {
test("cache example", async () => {
const resp = await mf.dispatchFetch("https://fake.host/cache-example");
const resp = await mf.dispatchFetch(`${mfUrl}cache-example`);
const { timestamp } = (await resp.json()) as { timestamp: unknown };

for (let i = 0; i < 5; i++) {
const resp = await mf.dispatchFetch("https://fake.host/cache-example");
const resp = await mf.dispatchFetch(`${mfUrl}cache-example`);
const data = (await resp.json()) as { timestamp: unknown };

expect(data.timestamp).toBe(timestamp);
}
});

test("cache stream", async () => {
const resp = await mf.dispatchFetch("https://fake.host/cache-stream");
const resp = await mf.dispatchFetch(`${mfUrl}cache-stream`);
const body = await resp.text();

for (let i = 0; i < 5; i++) {
const resp = await mf.dispatchFetch("https://fake.host/cache-stream");
const resp = await mf.dispatchFetch(`${mfUrl}cache-stream`);
const cachedBody = await resp.text();

expect(cachedBody).toBe(body);
Expand All @@ -28,9 +28,9 @@ describe("cache", () => {

test("cache api", async () => {
const key = "example.org";
const getEndpoint = `https://fake.host/cache-api/get/${key}`;
const putEndpoint = `https://fake.host/cache-api/put/${key}`;
const deleteEndpoint = `https://fake.host/cache-api/delete/${key}`;
const getEndpoint = `${mfUrl}cache-api/get/${key}`;
const putEndpoint = `${mfUrl}cache-api/put/${key}`;
const deleteEndpoint = `${mfUrl}cache-api/delete/${key}`;

// First time should result in cache miss
let resp = await mf.dispatchFetch(getEndpoint);
Expand Down
10 changes: 5 additions & 5 deletions worker-sandbox/tests/clone.spec.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
import { describe, test, expect } from "vitest";
import { mf } from "./mf";
import { mf, mfUrl } from "./mf";

describe("cache", () => {
test("cloned", async () => {
const resp = await mf.dispatchFetch("https://fake.host/cloned");
const resp = await mf.dispatchFetch(`${mfUrl}cloned`);
expect(await resp.text()).toBe("true");
});

test("cloned stream", async () => {
const resp = await mf.dispatchFetch("https://fake.host/cloned-stream");
const resp = await mf.dispatchFetch(`${mfUrl}cloned-stream`);
expect(await resp.text()).toBe("true");
});

test("cloned fetch", async () => {
const resp = await mf.dispatchFetch("https://fake.host/cloned-fetch");
const resp = await mf.dispatchFetch(`${mfUrl}cloned-fetch`);
expect(await resp.text()).toBe("true");
});

test("cloned response", async () => {
const resp = await mf.dispatchFetch("https://fake.host/cloned-response");
const resp = await mf.dispatchFetch(`${mfUrl}cloned-response`);
expect(await resp.text()).toBe("true");
});
});
28 changes: 14 additions & 14 deletions worker-sandbox/tests/d1.spec.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { describe, test, expect } from "vitest";
import { mf } from "./mf";
import { mf, mfUrl } from "./mf";

async function exec(query: string): Promise<number> {
const resp = await mf.dispatchFetch("http://fake.host/d1/exec", {
const resp = await mf.dispatchFetch(`${mfUrl}d1/exec`, {
method: "POST",
body: query.split("\n").join(""),
});
Expand Down Expand Up @@ -46,17 +46,17 @@ describe("d1", () => {
});

test("prepared statement", async () => {
const resp = await mf.dispatchFetch("http://fake.host/d1/prepared");
const resp = await mf.dispatchFetch(`${mfUrl}d1/prepared`);
expect(resp.status).toBe(200);
});

test("batch", async () => {
const resp = await mf.dispatchFetch("http://fake.host/d1/batch");
const resp = await mf.dispatchFetch(`${mfUrl}d1/batch`);
expect(resp.status).toBe(200);
});

test("error", async () => {
const resp = await mf.dispatchFetch("http://fake.host/d1/error");
const resp = await mf.dispatchFetch(`${mfUrl}d1/error`);
expect(resp.status).toBe(200);
});

Expand All @@ -79,55 +79,55 @@ describe("d1", () => {
});

test("jsvalue_null_is_null", async () => {
const resp = await mf.dispatchFetch("http://fake.host/d1/jsvalue_null_is_null");
const resp = await mf.dispatchFetch(`${mfUrl}d1/jsvalue_null_is_null`);
expect(await resp.text()).toBe("ok");
expect(resp.status).toBe(200);
});

test("serialize_optional_none", async () => {
const resp = await mf.dispatchFetch("http://fake.host/d1/serialize_optional_none");
const resp = await mf.dispatchFetch(`${mfUrl}d1/serialize_optional_none`);
expect(await resp.text()).toBe("ok");
expect(resp.status).toBe(200);
});

test("serialize_optional_some", async () => {
const resp = await mf.dispatchFetch("http://fake.host/d1/serialize_optional_some");
const resp = await mf.dispatchFetch(`${mfUrl}d1/serialize_optional_some`);
expect(await resp.text()).toBe("ok");
expect(resp.status).toBe(200);
});

test("deserialize_optional_none", async () => {
const resp = await mf.dispatchFetch("http://fake.host/d1/deserialize_optional_none");
const resp = await mf.dispatchFetch(`${mfUrl}d1/deserialize_optional_none`);
expect(await resp.text()).toBe("ok");
expect(resp.status).toBe(200);
});

test("insert_and_retrieve_optional_none", async () => {
const resp = await mf.dispatchFetch("http://fake.host/d1/insert_and_retrieve_optional_none");
const resp = await mf.dispatchFetch(`${mfUrl}d1/insert_and_retrieve_optional_none`);
expect(await resp.text()).toBe("ok");
expect(resp.status).toBe(200);
});

test("insert_and_retrieve_optional_some", async () => {
const resp = await mf.dispatchFetch("http://fake.host/d1/insert_and_retrieve_optional_some");
const resp = await mf.dispatchFetch(`${mfUrl}d1/insert_and_retrieve_optional_some`);
expect(await resp.text()).toBe("ok");
expect(resp.status).toBe(200);
});

test("retrieve_optional_none", async () => {
const resp = await mf.dispatchFetch("http://fake.host/d1/retrieve_optional_none");
const resp = await mf.dispatchFetch(`${mfUrl}d1/retrieve_optional_none`);
expect(await resp.text()).toBe("ok");
expect(resp.status).toBe(200);
});

test("retrieve_optional_some", async () => {
const resp = await mf.dispatchFetch("http://fake.host/d1/retrieve_optional_some");
const resp = await mf.dispatchFetch(`${mfUrl}d1/retrieve_optional_some`);
expect(await resp.text()).toBe("ok");
expect(resp.status).toBe(200);
});

test("retrive_first_none", async () => {
const resp = await mf.dispatchFetch("http://fake.host/d1/retrive_first_none");
const resp = await mf.dispatchFetch(`${mfUrl}d1/retrive_first_none`);
expect(await resp.text()).toBe("ok");
expect(resp.status).toBe(200);
});
Expand Down
37 changes: 19 additions & 18 deletions worker-sandbox/tests/durable.spec.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import {describe, test, expect, vi} from "vitest";
import { mf } from "./mf";
import {describe, test, expect} from "vitest";
import { mf, mfUrl } from "./mf";
import {MessageEvent} from "miniflare";

describe("durable", () => {
test("put-raw", async () => {
const resp = await mf.dispatchFetch("https://fake.host/durable/put-raw");
const resp = await mf.dispatchFetch(`${mfUrl}durable/put-raw`);
expect(await resp.text()).toBe("ok");
});

test("websocket-to-durable", async () => {
const resp = await mf.dispatchFetch("http://fake.host/durable/websocket", {
const resp = await mf.dispatchFetch(`${mfUrl}durable/websocket`, {
headers: {
upgrade: "websocket",
},
Expand All @@ -19,27 +19,28 @@ describe("durable", () => {
const socket = resp.webSocket!;
socket.accept();

const handlers = {
messageHandler: (event: MessageEvent) => {
expect(event.data).toMatch(/^10|20|30$/);
},
close(event: CloseEvent) {},
};

const messageHandlerWrapper = vi.spyOn(handlers, "messageHandler");
const closeHandlerWrapper = vi.spyOn(handlers, "messageHandler");
socket.addEventListener("message", handlers.messageHandler);
socket.addEventListener("close", handlers.close);
let cnt = 0;
socket.addEventListener("message", function (event: MessageEvent) {
cnt++;
expect(event.data).toMatch(/^10|20|30$/);
});
let calledClose = false;
socket.addEventListener("close", function (event: CloseEvent) {
calledClose = true;
});

socket.send("hi, can you ++?");
await new Promise((resolve) => setTimeout(resolve, 500));
expect(messageHandlerWrapper).toHaveBeenCalledTimes(1);
expect(cnt).toBe(1);

socket.send("hi again, more ++?");
await new Promise((resolve) => setTimeout(resolve, 500));
expect(messageHandlerWrapper).toHaveBeenCalledTimes(2);
expect(cnt).toBe(2);

socket.close();
expect(closeHandlerWrapper).toBeCalled();

// TODO: Investigate why this is not passing
// await new Promise(resolve => setTimeout(resolve, 1000));
// expect(calledClose).toBe(true);
});
});
2 changes: 1 addition & 1 deletion worker-sandbox/tests/kv.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { describe, test, expect } from "vitest";
import { mf } from "./mf";
import { mf, mfUrl } from "./mf";

const CASES = [
"get",
Expand Down
2 changes: 2 additions & 0 deletions worker-sandbox/tests/mf-socket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,5 @@ export const mf = new Miniflare({
network: { allow: ["local"] }
}
});

export const mfUrl = await mf.ready;
Loading