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
9 changes: 9 additions & 0 deletions .changeset/ready-hotels-jump.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"miniflare": minor
---

Local explorer: add /query endpoint to introspect sqlite in DOs

This required adding a wrapper that extends user DO classes and adds in an extra method to access `ctx.storage.sql`. This _shouldn't_ have any impact on user code, but is gated by the env var `X_LOCAL_EXPLORER`.

This is for an experimental WIP feature.
27 changes: 27 additions & 0 deletions .changeset/shaggy-phones-stay.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
"wrangler": minor
---

Generate typed pipeline bindings from stream schemas

When running `wrangler types`, pipeline bindings now generate TypeScript types based on the stream's schema definition. This gives you full autocomplete and type checking when sending data to your pipelines.

```jsonc
// wrangler.json
{
"pipelines": [{ "binding": "ANALYTICS", "pipeline": "analytics-stream-id" }],
}
```

If your stream has a schema with fields like `user_id` (string) and `event_count` (int32), the generated types will be:

```typescript
declare namespace Cloudflare {
type AnalyticsStreamRecord = { user_id: string; event_count: number };
interface Env {
ANALYTICS: Pipeline<Cloudflare.AnalyticsStreamRecord>;
}
}
```

For unstructured streams or when not authenticated, bindings fall back to the generic `Pipeline<PipelineRecord>` type.
6 changes: 6 additions & 0 deletions .changeset/slick-bananas-doubt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"miniflare": patch
"wrangler": patch
---

The maximum allowed delivery and retry delays for Queues is now 24 hours
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -235,4 +235,4 @@ dist/**
.node-cache/

AGENTS.local.md
.opencode/plans/
.opencode/plans/
70 changes: 39 additions & 31 deletions fixtures/get-platform-proxy/tests/get-platform-proxy.env.test.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,7 @@
import path from "path";
import { D1Database, R2Bucket } from "@cloudflare/workers-types";
import { toMatchImageSnapshot } from "jest-image-snapshot";
/* eslint-disable workers-sdk/no-vitest-import-expect -- uses expect throughout tests */
import {
afterEach,
beforeEach,
describe,
expect,
it,
MockInstance,
vi,
} from "vitest";
/* eslint-enable workers-sdk/no-vitest-import-expect */
import { beforeEach, describe, it, MockInstance, vi } from "vitest";
import { getPlatformProxy } from "./shared";
import type {
Fetcher,
Expand All @@ -20,7 +10,6 @@ import type {
KVNamespace,
Workflow,
} from "@cloudflare/workers-types";
import type { Unstable_DevWorker } from "wrangler";

type Env = {
MY_VAR: string;
Expand All @@ -41,7 +30,6 @@ type Env = {
const wranglerConfigFilePath = path.join(__dirname, "..", "wrangler.jsonc");

describe("getPlatformProxy - env", () => {
let devWorkers: Unstable_DevWorker[];
let warn = {} as MockInstance<typeof console.warn>;

beforeEach(() => {
Expand All @@ -52,7 +40,9 @@ describe("getPlatformProxy - env", () => {
});

describe("var bindings", () => {
it("correctly obtains var bindings from both wrangler config and .dev.vars", async () => {
it("correctly obtains var bindings from both wrangler config and .dev.vars", async ({
expect,
}) => {
const { env, dispose } = await getPlatformProxy<Env>({
configPath: wranglerConfigFilePath,
});
Expand All @@ -68,7 +58,9 @@ describe("getPlatformProxy - env", () => {
}
});

it("correctly makes vars from .dev.vars override the ones in wrangler config", async () => {
it("correctly makes vars from .dev.vars override the ones in wrangler config", async ({
expect,
}) => {
const { env, dispose } = await getPlatformProxy<Env>({
configPath: wranglerConfigFilePath,
});
Expand All @@ -81,7 +73,9 @@ describe("getPlatformProxy - env", () => {
}
});

it("correctly makes vars from .dev.vars not override bindings of the same name from wrangler config", async () => {
it("correctly makes vars from .dev.vars not override bindings of the same name from wrangler config", async ({
expect,
}) => {
const { env, dispose } = await getPlatformProxy<Env>({
configPath: wranglerConfigFilePath,
});
Expand All @@ -99,7 +93,9 @@ describe("getPlatformProxy - env", () => {
}
});

it("correctly reads a toml from a custom path alongside with its .dev.vars", async () => {
it("correctly reads a toml from a custom path alongside with its .dev.vars", async ({
expect,
}) => {
const { env, dispose } = await getPlatformProxy<Env>({
configPath: path.join(
__dirname,
Expand All @@ -123,7 +119,7 @@ describe("getPlatformProxy - env", () => {
});
});

it("correctly reads a json config file", async () => {
it("correctly reads a json config file", async ({ expect }) => {
const { env, dispose } = await getPlatformProxy<Env>({
configPath: path.join(__dirname, "..", "wrangler.json"),
});
Expand All @@ -139,7 +135,7 @@ describe("getPlatformProxy - env", () => {
}
});

it("correctly obtains functioning ASSETS bindings", async () => {
it("correctly obtains functioning ASSETS bindings", async ({ expect }) => {
const { env, dispose } = await getPlatformProxy<Env>({
configPath: wranglerConfigFilePath,
});
Expand All @@ -149,7 +145,7 @@ describe("getPlatformProxy - env", () => {
await dispose();
});

it("correctly obtains functioning KV bindings", async () => {
it("correctly obtains functioning KV bindings", async ({ expect }) => {
const { env, dispose } = await getPlatformProxy<Env>({
configPath: wranglerConfigFilePath,
});
Expand All @@ -164,7 +160,7 @@ describe("getPlatformProxy - env", () => {
await dispose();
});

it("correctly obtains functioning R2 bindings", async () => {
it("correctly obtains functioning R2 bindings", async ({ expect }) => {
const { env, dispose } = await getPlatformProxy<Env>({
configPath: wranglerConfigFilePath,
});
Expand All @@ -182,7 +178,7 @@ describe("getPlatformProxy - env", () => {
}
});

it("correctly obtains functioning D1 bindings", async () => {
it("correctly obtains functioning D1 bindings", async ({ expect }) => {
const { env, dispose } = await getPlatformProxy<Env>({
configPath: wranglerConfigFilePath,
});
Expand Down Expand Up @@ -210,7 +206,7 @@ describe("getPlatformProxy - env", () => {
}
});

it("correctly obtains functioning Image bindings", async () => {
it("correctly obtains functioning Image bindings", async ({ expect }) => {
expect.extend({ toMatchImageSnapshot });

const { env, dispose } = await getPlatformProxy<Env>({
Expand Down Expand Up @@ -249,7 +245,9 @@ describe("getPlatformProxy - env", () => {

// Important: the hyperdrive values are passthrough ones since the workerd specific hyperdrive values only make sense inside
// workerd itself and would simply not work in a node.js process
it("correctly obtains passthrough Hyperdrive bindings", async () => {
it("correctly obtains passthrough Hyperdrive bindings", async ({
expect,
}) => {
const { env, dispose } = await getPlatformProxy<Env>({
configPath: wranglerConfigFilePath,
});
Expand All @@ -269,7 +267,7 @@ describe("getPlatformProxy - env", () => {
});

describe("DO warnings", () => {
it("warns about internal DOs and doesn't crash", async () => {
it("warns about internal DOs and doesn't crash", async ({ expect }) => {
await getPlatformProxy<Env>({
configPath: path.join(__dirname, "..", "wrangler_internal_do.jsonc"),
});
Expand All @@ -285,14 +283,16 @@ describe("getPlatformProxy - env", () => {
`);
});

it("doesn't warn about external DOs and doesn't crash", async () => {
it("doesn't warn about external DOs and doesn't crash", async ({
expect,
}) => {
await getPlatformProxy<Env>({
configPath: path.join(__dirname, "..", "wrangler_external_do.jsonc"),
});
expect(warn).not.toHaveBeenCalled();
});

it("warns about Workflows and doesn't crash", async () => {
it("warns about Workflows and doesn't crash", async ({ expect }) => {
await getPlatformProxy<Env>({
configPath: path.join(__dirname, "..", "wrangler_workflow.jsonc"),
});
Expand All @@ -308,7 +308,9 @@ describe("getPlatformProxy - env", () => {
});

describe("with a target environment", () => {
it("should provide bindings targeting a specified environment and also inherit top-level ones", async () => {
it("should provide bindings targeting a specified environment and also inherit top-level ones", async ({
expect,
}) => {
const { env, dispose } = await getPlatformProxy<Env>({
configPath: wranglerConfigFilePath,
environment: "production",
Expand All @@ -325,7 +327,9 @@ describe("getPlatformProxy - env", () => {
}
});

it("should not provide bindings targeting an environment when none was specified", async () => {
it("should not provide bindings targeting an environment when none was specified", async ({
expect,
}) => {
const { env, dispose } = await getPlatformProxy<Env>({
configPath: wranglerConfigFilePath,
});
Expand All @@ -341,7 +345,9 @@ describe("getPlatformProxy - env", () => {
}
});

it("should provide secrets targeting a specified environment", async () => {
it("should provide secrets targeting a specified environment", async ({
expect,
}) => {
const { env, dispose } = await getPlatformProxy<Env>({
configPath: wranglerConfigFilePath,
environment: "production",
Expand All @@ -355,7 +361,9 @@ describe("getPlatformProxy - env", () => {
}
});

it("should error if a non-existent environment is provided", async () => {
it("should error if a non-existent environment is provided", async ({
expect,
}) => {
await expect(
getPlatformProxy({
configPath: wranglerConfigFilePath,
Expand Down
28 changes: 12 additions & 16 deletions fixtures/local-mode-tests/tests/logging.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import path from "node:path";
import { setTimeout } from "node:timers/promises";
import util from "node:util";
import { afterEach, beforeEach, it, Mock, vi } from "vitest";
import { unstable_dev } from "wrangler";
import { unstable_startWorker } from "wrangler";

let output = "";
function spyOnConsoleMethod(name: keyof typeof console) {
Expand All @@ -25,21 +25,17 @@ afterEach(() => {
it("logs startup errors", async ({ expect }) => {
let caughtError: unknown;
try {
const worker = await unstable_dev(
path.resolve(__dirname, "..", "src", "nodejs-compat.ts"),
{
config: path.resolve(__dirname, "..", "wrangler.logging.jsonc"),
// Intentionally omitting `compatibilityFlags: ["nodejs_compat"]`
ip: "127.0.0.1",
experimental: {
disableExperimentalWarning: true,
disableDevRegistry: true,
devEnv: true,
},
}
);
await worker.stop();
expect.fail("Expected unstable_dev() to fail");
const worker = await unstable_startWorker({
entrypoint: path.resolve(__dirname, "../src/nodejs-compat.ts"),
config: path.resolve(__dirname, "../wrangler.logging.jsonc"),
// Intentionally omitting `compatibilityFlags: ["nodejs_compat"]`
dev: {
server: { hostname: "127.0.0.1", port: 0 },
inspector: false,
},
});
await worker.dispose();
expect.fail("Expected unstable_startWorker() to fail");
} catch (e) {
caughtError = e;
}
Expand Down
Loading
Loading