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: 2 additions & 0 deletions .changeset/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ The changelog uses h3 for section headers, so any headers in changeset content m

For new features or significant changes, consider including a brief usage example. Examples can be helpful for users to understand new functionality, but they are not mandatory—use your judgment based on how self-explanatory the change is.

When showing Wrangler configuration examples, use `wrangler.json` (with JSONC syntax for comments) rather than `wrangler.toml`.

## Multiple Changesets

If your PR makes multiple distinct user-facing changes, create separate changesets so each gets its own changelog entry. Don't lump unrelated changes together, and don't mix different types of changes (e.g., bug fix + new feature) in a single changeset.
Expand Down
9 changes: 9 additions & 0 deletions .changeset/brown-schools-fry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"wrangler": patch
---

Remove `--use-remote` option from `wrangler hyperdrive create` command

Hyperdrive does not support remote bindings during local development - it requires a `localConnectionString` to connect to a local database. This change removes the confusing "remote resource" prompt that was shown when creating a Hyperdrive config.

Fixes #11674
25 changes: 25 additions & 0 deletions .changeset/custom-inspector-ip.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
"wrangler": minor
"miniflare": minor
"@cloudflare/workers-utils": minor
---

Add support for customising the inspector IP address

Adds a new `--inspector-ip` CLI flag and `dev.inspector_ip` configuration option to allow customising the IP address that the inspector server listens on. Previously, the inspector was hardcoded to listen only on `127.0.0.1`.

Example usage:

```bash
# CLI flag
wrangler dev --inspector-ip 0.0.0.0
```

```jsonc
// wrangler.json
{
"dev": {
"inspector_ip": "0.0.0.0",
},
}
```
12 changes: 12 additions & 0 deletions .changeset/dependabot-update-12040.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
"miniflare": patch
"wrangler": patch
---

chore: update dependencies of "miniflare", "wrangler"

The following dependency versions have been updated:

| Dependency | From | To |
| ---------- | ------------ | ------------ |
| workerd | 1.20260120.0 | 1.20260122.0 |
7 changes: 7 additions & 0 deletions .changeset/eight-teeth-smoke.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"wrangler": patch
---

Fix `wrangler secret list` to error when the Worker is not found

Previously, running `wrangler secret list` against a non-existent Worker would silently return an empty array, making it difficult to diagnose issues like being logged into the wrong account. It now returns an error with suggestions for common causes.
8 changes: 8 additions & 0 deletions .changeset/polite-years-exist.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"@cloudflare/vite-plugin": minor
"@cloudflare/workers-utils": minor
"miniflare": minor
"wrangler": minor
---

Add a no-op local explorer worker, which is gated by the experimental flag `X_LOCAL_EXPLORER`.
4 changes: 2 additions & 2 deletions .github/workflows/vite-plugin-playgrounds.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ jobs:
include:
- os: ubuntu-latest
vite: "vite-6"
- os: ubuntu-latest
vite: vite-8-beta
# - os: ubuntu-latest
# vite: vite-8-beta
runs-on: ${{ matrix.os }}
steps:
- name: Checkout Repo
Expand Down
9 changes: 8 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,9 @@ This is the **Cloudflare Workers SDK** monorepo containing tools and libraries f

**Creating Pull Requests:**

- Always use the PR template from `.github/pull_request_template.md`
- Always use the PR template from `.github/PULL_REQUEST_TEMPLATE.md` - do not replace it with your own format
- Fill in the template: replace the issue link placeholder, add description, check appropriate boxes
- Keep all checkboxes in the template (don't delete unchecked ones)
- PR title format: `[package name] description` (e.g. `[wrangler] Fix bug in dev command`)
- If the change doesn't require a changeset, add the `no-changeset-required` label

Expand All @@ -125,3 +127,8 @@ Run `pnpm check` before submitting changes to ensure all quality gates pass.
## Changesets

Every change to package code requires a changeset or it will not trigger a release. Read `.changeset/README.md` before creating changesets.

**Changeset Format:**

- Do not use conventional commit prefixes (e.g., `fix:`, `feat:`) in changeset descriptions
- Start with a capital letter and describe the change directly (e.g., "Remove unused option" not "fix: remove unused option")
21 changes: 21 additions & 0 deletions fixtures/worker-with-resources/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "@fixture/worker-with-resources",
"private": true,
"scripts": {
"cf-typegen": "wrangler types --no-include-runtime",
"deploy": "wrangler deploy",
"start": "wrangler dev",
"test:ci": "vitest run",
"test:watch": "vitest"
},
"devDependencies": {
"@cloudflare/workers-tsconfig": "workspace:^",
"@cloudflare/workers-types": "catalog:default",
"typescript": "catalog:default",
"vitest": "catalog:default",
"wrangler": "workspace:*"
},
"volta": {
"extends": "../../package.json"
}
}
50 changes: 50 additions & 0 deletions fixtures/worker-with-resources/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { DurableObject } from "cloudflare:workers";

export default {
async fetch(request: Request, env: Env): Promise<Response> {
const url = new URL(request.url);
switch (url.pathname) {
// KV routes
case "/kv/get": {
const keyToGet = url.searchParams.get("key") ?? "default";
const value = await env.KV.get(keyToGet);
return new Response(value || "null");
}
case "/kv/put": {
const keyToSet = url.searchParams.get("key") ?? "default";
const val = url.searchParams.get("value");
await env.KV.put(keyToSet, val);
return new Response("OK");
}

// D1 database route
case "/d1": {
await env.DB.exec(`
DROP TABLE IF EXISTS users;
CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT);
INSERT INTO users (id, name) VALUES (1, 'Alice'), (2, 'Bob');
`);
return new Response("OK");
}
// Durable Object SQLite routes
case "/do": {
const id = url.searchParams.get("id") || "default";
const doId = env.DO.idFromName(id);
const stub = env.DO.get(doId);
return stub.fetch(request);
}
}
return new Response("Hello World!");
},
};

export class MyDurableObject extends DurableObject<Env> {
async fetch(_request: Request): Promise<Response> {
this.ctx.storage.sql.exec(`
DROP TABLE IF EXISTS users;
CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT);
INSERT INTO users (id, name) VALUES (1, 'Alice'), (2, 'Bob');
`);
return new Response("OK");
}
}
64 changes: 64 additions & 0 deletions fixtures/worker-with-resources/tests/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { resolve } from "path";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { runWranglerDev } from "../../shared/src/run-wrangler-long-lived";

describe("local explorer", () => {
describe("with X_LOCAL_EXPLORER=true", () => {
let ip: string;
let port: number;
let stop: (() => Promise<unknown>) | undefined;

beforeAll(async () => {
({ ip, port, stop } = await runWranglerDev(
resolve(__dirname, ".."),
["--port=0", "--inspector-port=0"],
{ X_LOCAL_EXPLORER: "true" }
));
});

afterAll(async () => {
await stop?.();
});

it("returns local explorer API response for /cdn-cgi/explorer/api", async () => {
const response = await fetch(`http://${ip}:${port}/cdn-cgi/explorer/api`);
const text = await response.text();
expect(text).toBe("Hello from local explorer API");
});

it("returns worker response for normal requests", async () => {
const response = await fetch(`http://${ip}:${port}/`);
const text = await response.text();
expect(text).toBe("Hello World!");
});
});

describe("without X_LOCAL_EXPLORER (default)", () => {
let ip: string;
let port: number;
let stop: (() => Promise<unknown>) | undefined;

beforeAll(async () => {
({ ip, port, stop } = await runWranglerDev(resolve(__dirname, ".."), [
"--port=0",
"--inspector-port=0",
]));
});

afterAll(async () => {
await stop?.();
});

it("returns worker response for /cdn-cgi/explorer/api", async () => {
const response = await fetch(`http://${ip}:${port}/cdn-cgi/explorer/api`);
const text = await response.text();
expect(text).toBe("Hello World!");
});

it("returns worker response for normal requests", async () => {
const response = await fetch(`http://${ip}:${port}/`);
const text = await response.text();
expect(text).toBe("Hello World!");
});
});
});
17 changes: 17 additions & 0 deletions fixtures/worker-with-resources/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"compilerOptions": {
"types": [
"./worker-configuration.d.ts",
"@cloudflare/workers-types",
"node"
],
"target": "ES2020",
"esModuleInterop": true,
"module": "preserve",
"lib": ["ES2020"],
"skipLibCheck": true,
"moduleResolution": "node",
"noEmit": true
},
"include": ["tests"]
}
12 changes: 12 additions & 0 deletions fixtures/worker-with-resources/vitest.config.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { defineProject, mergeConfig } from "vitest/config";
import configShared from "../../vitest.shared";

export default mergeConfig(
configShared,
defineProject({
test: {
maxConcurrency: 1,
fileParallelism: false,
},
})
);
13 changes: 13 additions & 0 deletions fixtures/worker-with-resources/worker-configuration.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/* eslint-disable */
// Generated by Wrangler by running `wrangler types --no-include-runtime` (hash: b2cbbf416df3649267950e8534e79347)
declare namespace Cloudflare {
interface GlobalProps {
mainModule: typeof import("./src/index");
}
interface Env {
KV: KVNamespace;
DO: DurableObjectNamespace<import("./src/index").MyDurableObject>;
DB: D1Database;
}
}
interface Env extends Cloudflare.Env {}
24 changes: 24 additions & 0 deletions fixtures/worker-with-resources/wrangler.jsonc
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "worker-w-resources",
"main": "src/index.ts",
"compatibility_date": "2023-05-04",
"kv_namespaces": [
{
"binding": "KV",
},
],
"d1_databases": [
{
"binding": "DB",
},
],
"durable_objects": {
"bindings": [
{
"name": "DO",
"class_name": "MyDurableObject",
},
],
},
}
63 changes: 63 additions & 0 deletions packages/create-cloudflare/src/__tests__/templates.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,69 @@ describe("downloadRemoteTemplate", () => {

expect(cloneMock).toHaveBeenCalledWith("/path/to/clone");
});

test("should transform GitHub URL without path to degit format", async () => {
await downloadRemoteTemplate(
"https://github.com/cloudflare/workers-graphql-server",
);

expect(degit).toHaveBeenCalledWith(
"github:cloudflare/workers-graphql-server",
expect.anything(),
);
});

test("should transform GitHub URL with trailing slash to degit format", async () => {
await downloadRemoteTemplate("https://github.com/cloudflare/workers-sdk/");

expect(degit).toHaveBeenCalledWith(
"github:cloudflare/workers-sdk",
expect.anything(),
);
});

test("should transform GitHub URL with subdirectory to degit format", async () => {
await downloadRemoteTemplate(
"https://github.com/cloudflare/workers-sdk/templates/worker-r2",
);

expect(degit).toHaveBeenCalledWith(
"github:cloudflare/workers-sdk/templates/worker-r2",
expect.anything(),
);
});

test("should transform GitHub URL with tree/main to degit format", async () => {
await downloadRemoteTemplate(
"https://github.com/cloudflare/workers-sdk/tree/main",
);

expect(degit).toHaveBeenCalledWith(
"github:cloudflare/workers-sdk#main",
expect.anything(),
);
});

test("should transform GitHub URL with tree/main/subdirectory to degit format", async () => {
await downloadRemoteTemplate(
"https://github.com/cloudflare/workers-sdk/tree/main/templates",
);

expect(degit).toHaveBeenCalledWith(
"github:cloudflare/workers-sdk/templates#main",
expect.anything(),
);
});

test("should throw error when using a branch other than main", async () => {
await expect(
downloadRemoteTemplate(
"https://github.com/cloudflare/workers-sdk/tree/dev",
),
).rejects.toThrow(
"Failed to clone remote template: https://github.com/cloudflare/workers-sdk/tree/dev\nUse the format \"github:<owner>/<repo>/sub/directory[#<branch>]\" to clone a specific branch other than 'main'",
);
});
});

describe("deriveCorrelatedArgs", () => {
Expand Down
Loading
Loading