Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: cloudflare/workers-sdk
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: wrangler@4.4.1
Choose a base ref
...
head repository: cloudflare/workers-sdk
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: wrangler@4.5.0
Choose a head ref
  • 5 commits
  • 35 files changed
  • 7 contributors

Commits on Mar 26, 2025

  1. feat(wrangler): Add Bulk Key Get command to KV (#8620)

    * feat(wrangler): Add Bulk Key Get command to KV
    
    * chore(wrangler): Add unit tests for bulk get command in KV
    
    * chore(wrangler): Add e2e tests for bulk get command in KV
    
    * chore(wrangler): Add changeset
    
    * chore(wrangler): Removed refactoring of bulk get file.
    
    * chore(wrangler): Remove sendMetrics call from get bulk
    
    * chore(wrangler): Change binding arg description for KV commands
    
    * ˇ
    
    * Update packages/wrangler/src/kv/index.ts
    
    Co-authored-by: Carmen Popoviciu <cpopoviciu@cloudflare.com>
    
    * Update packages/wrangler/src/__tests__/kv.test.ts
    
    Co-authored-by: Carmen Popoviciu <cpopoviciu@cloudflare.com>
    
    * Update packages/wrangler/src/__tests__/kv.test.ts
    
    Co-authored-by: Carmen Popoviciu <cpopoviciu@cloudflare.com>
    
    * Update packages/wrangler/src/__tests__/kv.test.ts
    
    Co-authored-by: Carmen Popoviciu <cpopoviciu@cloudflare.com>
    
    * Update packages/wrangler/src/__tests__/kv.test.ts
    
    Co-authored-by: Carmen Popoviciu <cpopoviciu@cloudflare.com>
    
    * Update packages/wrangler/src/__tests__/kv.test.ts
    
    Co-authored-by: Carmen Popoviciu <cpopoviciu@cloudflare.com>
    
    * Update packages/wrangler/src/__tests__/kv.test.ts
    
    Co-authored-by: Carmen Popoviciu <cpopoviciu@cloudflare.com>
    
    ---------
    
    Co-authored-by: Carmen Popoviciu <cpopoviciu@cloudflare.com>
    pmiguel and CarmenPopoviciu authored Mar 26, 2025

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    14602d9 View commit details
  2. Fix dev server crashing on config changes (#8652)

    * Added config-changes playground
    
    * Moved miniflare.dispose into createServer and added tests
    
    * Revered vitest config
    
    * Simplified tests
    
    * Added changeset
    
    * Fix workers-types version
    
    * Increase waitFor timeout
    
    * Skip config errors test
    
    * Use path.resolve
    
    * Log in tests
    
    * Normalize Worker config paths to support Windows
    
    * Use path.resolve in handleHotUpdate hook
    
    * Add tailwindcss to playground to reproduce error
    
    * Use hotUpdate and miniflare.setOptions
    
    * Filter logs
    
    * Remove inspectorPort in playground
    
    * Set unique Workflows IDs
    
    * Remove unnecessary async
    
    * Assert Miniflare
    jamesopstad authored Mar 26, 2025
    Copy the full SHA
    a18155f View commit details
  3. Bump @cloudflare/unenv-preset to 2.3.1 (#8675)

    Co-authored-by: Carmen Popoviciu <cpopoviciu@cloudflare.com>
    vicb and CarmenPopoviciu authored Mar 26, 2025
    Copy the full SHA
    f043b74 View commit details
  4. fix: include asset binding when printing binding summary (#8435)

    emily-shen authored Mar 26, 2025
    Copy the full SHA
    8e3688f View commit details
  5. Version Packages (#8679)

    Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
    workers-devprod and github-actions[bot] authored Mar 26, 2025
    Copy the full SHA
    2529848 View commit details
Showing with 1,051 additions and 184 deletions.
  1. +9 −1 fixtures/nodejs-hybrid-app/src/index.ts
  2. +10 −0 packages/vite-plugin-cloudflare/CHANGELOG.md
  3. +1 −1 packages/vite-plugin-cloudflare/package.json
  4. +84 −0 packages/vite-plugin-cloudflare/playground/config-changes/__tests__/config-changes.spec.ts
  5. +19 −0 packages/vite-plugin-cloudflare/playground/config-changes/package.json
  6. +9 −0 packages/vite-plugin-cloudflare/playground/config-changes/src/index.ts
  7. +7 −0 packages/vite-plugin-cloudflare/playground/config-changes/tsconfig.json
  8. +4 −0 packages/vite-plugin-cloudflare/playground/config-changes/tsconfig.node.json
  9. +4 −0 packages/vite-plugin-cloudflare/playground/config-changes/tsconfig.worker.json
  10. +9 −0 packages/vite-plugin-cloudflare/playground/config-changes/turbo.json
  11. +7 −0 packages/vite-plugin-cloudflare/playground/config-changes/vite.config.ts
  12. +7 −0 packages/vite-plugin-cloudflare/playground/config-changes/wrangler.json
  13. +1 −1 packages/vite-plugin-cloudflare/playground/external-workflows/__tests__/workflows.spec.ts
  14. +2 −0 packages/vite-plugin-cloudflare/playground/partyserver/package.json
  15. +1 −0 packages/vite-plugin-cloudflare/playground/partyserver/src/App.tsx
  16. +1 −0 packages/vite-plugin-cloudflare/playground/partyserver/src/tailwind.css
  17. +6 −1 packages/vite-plugin-cloudflare/playground/partyserver/vite.config.ts
  18. +1 −1 packages/vite-plugin-cloudflare/playground/workflows/__tests__/workflows.spec.ts
  19. +32 −17 packages/vite-plugin-cloudflare/src/index.ts
  20. +7 −2 packages/vite-plugin-cloudflare/src/miniflare-options.ts
  21. +2 −0 packages/vite-plugin-cloudflare/src/utils.ts
  22. +3 −1 packages/vite-plugin-cloudflare/src/websockets.ts
  23. +7 −0 packages/vitest-pool-workers/CHANGELOG.md
  24. +1 −1 packages/vitest-pool-workers/package.json
  25. +14 −0 packages/wrangler/CHANGELOG.md
  26. +8 −7 packages/wrangler/e2e/deployments.test.ts
  27. +2 −2 packages/wrangler/package.json
  28. +1 −0 packages/wrangler/src/__tests__/index.test.ts
  29. +55 −0 packages/wrangler/src/__tests__/kv.local.test.ts
  30. +145 −9 packages/wrangler/src/__tests__/kv.test.ts
  31. +2 −0 packages/wrangler/src/index.ts
  32. +26 −0 packages/wrangler/src/kv/helpers.ts
  33. +127 −7 packages/wrangler/src/kv/index.ts
  34. +8 −0 packages/wrangler/src/utils/print-bindings.ts
  35. +429 −133 pnpm-lock.yaml
10 changes: 9 additions & 1 deletion fixtures/nodejs-hybrid-app/src/index.ts
Original file line number Diff line number Diff line change
@@ -208,8 +208,16 @@ async function testTls() {
assert.strictEqual(typeof tls.connect, "function");
assert.strictEqual(typeof tls.TLSSocket, "function");
assert.strictEqual(typeof tls.checkServerIdentity, "function");
assert.strictEqual(typeof tls.createSecureContext, "function");
assert.strictEqual(
tls.checkServerIdentity("a.com", { subject: { CN: "a.com" } }),
undefined
);
assert.strictEqual(typeof tls.SecureContext, "function");
assert.strictEqual(typeof tls.createSecureContext, "function");
assert.strictEqual(
tls.createSecureContext({}) instanceof tls.SecureContext,
true
);

return new Response("OK");
}
10 changes: 10 additions & 0 deletions packages/vite-plugin-cloudflare/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# @cloudflare/vite-plugin

## 0.1.17

### Patch Changes

- [#8652](https://github.com/cloudflare/workers-sdk/pull/8652) [`a18155f`](https://github.com/cloudflare/workers-sdk/commit/a18155fb81f0399528a40f843736ff6565dc5579) Thanks [@jamesopstad](https://github.com/jamesopstad)! - Fix a bug where updating config files would crash the dev server. This occurred because the previous Miniflare instance was not disposed before creating a new one. This would lead to a port collision because of the `inspectorPort` introduced by the new debugging features.

- Updated dependencies [[`8e3688f`](https://github.com/cloudflare/workers-sdk/commit/8e3688f27209edeac6241bf240ee5eec62d7ddb2), [`f043b74`](https://github.com/cloudflare/workers-sdk/commit/f043b74c715ebd7ca1e3f62139ad43e57cec8f05), [`14602d9`](https://github.com/cloudflare/workers-sdk/commit/14602d9f39f3fb1df7303dab5c91a77fa21e46f9)]:
- wrangler@4.5.0
- @cloudflare/unenv-preset@2.3.1

## 0.1.16

### Patch Changes
2 changes: 1 addition & 1 deletion packages/vite-plugin-cloudflare/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@cloudflare/vite-plugin",
"version": "0.1.16",
"version": "0.1.17",
"description": "Cloudflare plugin for Vite",
"keywords": [
"cloudflare",
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import * as fs from "node:fs";
import * as path from "node:path";
import { expect, test, vi } from "vitest";
import { getTextResponse, isBuild, serverLogs } from "../../__test-utils__";

test.runIf(!isBuild)(
"successfully updates when a var is updated in the Worker config",
async ({ onTestFinished }) => {
const workerConfigPath = path.join(__dirname, "../wrangler.json");
const originalWorkerConfig = fs.readFileSync(workerConfigPath, "utf-8");

onTestFinished(async () => {
fs.writeFileSync(workerConfigPath, originalWorkerConfig);
// We need to ensure that the original config is restored before the next test runs
await vi.waitFor(
async () => {
const revertedResponse = await getTextResponse();
expect(revertedResponse).toBe('The value of MY_VAR is "one"');
},
{ timeout: 5000 }
);
});

const originalResponse = await getTextResponse();
expect(originalResponse).toBe('The value of MY_VAR is "one"');

const updatedWorkerConfig = JSON.stringify({
...JSON.parse(originalWorkerConfig),
vars: {
MY_VAR: "two",
},
});
fs.writeFileSync(workerConfigPath, updatedWorkerConfig);
await vi.waitFor(
async () => {
const updatedResponse = await getTextResponse();
expect(updatedResponse).toBe('The value of MY_VAR is "two"');
},
{ timeout: 5000 }
);
}
);

test.runIf(!isBuild)(
"reports errors in updates to the Worker config",
async ({ onTestFinished }) => {
const workerConfigPath = path.join(__dirname, "../wrangler.json");
const originalWorkerConfig = fs.readFileSync(workerConfigPath, "utf-8");

onTestFinished(async () => {
fs.writeFileSync(workerConfigPath, originalWorkerConfig);
// We need to ensure that the original config is restored before the next test runs
await vi.waitFor(
async () => {
const revertedResponse = await getTextResponse();
expect(revertedResponse).toBe('The value of MY_VAR is "one"');
},
{ timeout: 5000 }
);
});

const originalResponse = await getTextResponse();
expect(originalResponse).toBe('The value of MY_VAR is "one"');

const updatedWorkerConfig = JSON.stringify({
...JSON.parse(originalWorkerConfig),
main: "./src/non-existing-file.ts",
vars: {
MY_VAR: "two",
},
});
fs.writeFileSync(workerConfigPath, updatedWorkerConfig);
await vi.waitFor(
async () => {
const newResponse = await getTextResponse();
expect(serverLogs.errors.join()).toMatch(
/.*The provided Wrangler config main field .+? doesn't point to an existing file.*/
);
expect(newResponse).toBe('The value of MY_VAR is "one"');
},
{ timeout: 5000 }
);
}
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "@playground/config-changes",
"private": true,
"type": "module",
"scripts": {
"build": "vite build --app",
"check:types": "tsc --build",
"dev": "vite dev",
"preview": "vite preview"
},
"devDependencies": {
"@cloudflare/vite-plugin": "workspace:*",
"@cloudflare/workers-tsconfig": "workspace:*",
"@cloudflare/workers-types": "^4.20250321.0",
"typescript": "catalog:default",
"vite": "catalog:vite-plugin",
"wrangler": "workspace:*"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
interface Env {
MY_VAR: string;
}

export default {
async fetch(_, env) {
return new Response(`The value of MY_VAR is "${env.MY_VAR}"`);
},
} satisfies ExportedHandler<Env>;
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"files": [],
"references": [
{ "path": "./tsconfig.node.json" },
{ "path": "./tsconfig.worker.json" }
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"extends": ["@cloudflare/workers-tsconfig/base.json"],
"include": ["vite.config.ts", "__tests__"]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"extends": ["@cloudflare/workers-tsconfig/worker.json"],
"include": ["src"]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"$schema": "http://turbo.build/schema.json",
"extends": ["//"],
"tasks": {
"build": {
"outputs": ["dist/**"]
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { cloudflare } from "@cloudflare/vite-plugin";
import { defineConfig } from "vite";

export default defineConfig({
// We should enable `inspectorPort` in this playground when it's possible to do so to verify that there are no port collisions on server restarts
plugins: [cloudflare({ inspectorPort: false, persistState: false })],
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "worker",
"compatibility_date": "2024-12-30",
"main": "./src/index.ts",
"vars": { "MY_VAR": "one" }
}
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@ import { expect, test, vi } from "vitest";
import { getJsonResponse } from "../../__test-utils__";

test("creates a Workflow with an ID", async () => {
const instanceId = "test-id";
const instanceId = "external-workflows-test-id";

expect(await getJsonResponse(`/create?id=${instanceId}`)).toEqual({
id: instanceId,
Original file line number Diff line number Diff line change
@@ -18,9 +18,11 @@
"@cloudflare/vite-plugin": "workspace:*",
"@cloudflare/workers-tsconfig": "workspace:*",
"@cloudflare/workers-types": "^4.20250321.0",
"@tailwindcss/vite": "^4.0.15",
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0",
"@vitejs/plugin-react": "^4.3.4",
"tailwindcss": "^4.0.15",
"typescript": "catalog:default",
"vite": "catalog:vite-plugin",
"wrangler": "workspace:*"
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { usePartySocket } from "partysocket/react";
import { useState } from "react";
import "./tailwind.css";

function App() {
const [message, setMessage] = useState();
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@import "tailwindcss";
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { cloudflare } from "@cloudflare/vite-plugin";
import tailwindcss from "@tailwindcss/vite";
import react from "@vitejs/plugin-react";
import { defineConfig } from "vite";

export default defineConfig({
plugins: [react(), cloudflare({ inspectorPort: false, persistState: false })],
plugins: [
react(),
cloudflare({ inspectorPort: false, persistState: false }),
tailwindcss(),
],
});
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@ import { expect, test, vi } from "vitest";
import { getJsonResponse } from "../../__test-utils__";

test("creates a Workflow with an ID", async () => {
const instanceId = "test-id";
const instanceId = "workflows-test-id";

expect(await getJsonResponse(`/create?id=${instanceId}`)).toEqual({
id: instanceId,
49 changes: 32 additions & 17 deletions packages/vite-plugin-cloudflare/src/index.ts
Original file line number Diff line number Diff line change
@@ -46,10 +46,12 @@ import { getWarningForWorkersConfigs } from "./workers-configs";
import type { PluginConfig, ResolvedPluginConfig } from "./plugin-config";
import type { Unstable_RawConfig } from "wrangler";

export type { PluginConfig } from "./plugin-config";

// this flag is used to show the workers configs warning only once
let workersConfigsWarningShown = false;

export type { PluginConfig } from "./plugin-config";
let miniflare: Miniflare | undefined;

/**
* Vite plugin that enables a full-featured integration between Vite and the Cloudflare Workers runtime.
@@ -61,7 +63,6 @@ export type { PluginConfig } from "./plugin-config";
export function cloudflare(pluginConfig: PluginConfig = {}): vite.Plugin[] {
let resolvedPluginConfig: ResolvedPluginConfig;
let resolvedViteConfig: vite.ResolvedConfig;
let miniflare: Miniflare | undefined;

const additionalModulePaths = new Set<string>();

@@ -284,22 +285,19 @@ export function cloudflare(pluginConfig: PluginConfig = {}): vite.Plugin[] {
writeDeployConfig(resolvedPluginConfig, resolvedViteConfig);
}
},
handleHotUpdate(options) {
hotUpdate(options) {
if (
resolvedPluginConfig.configPaths.has(options.file) ||
// Vite normalizes `options.file` so we use `path.resolve` for Windows compatibility
resolvedPluginConfig.configPaths.has(path.resolve(options.file)) ||
hasAssetsConfigChanged(
resolvedPluginConfig,
resolvedViteConfig,
options.file
)
) {
// It's OK for this to be called multiple times as Vite prevents concurrent execution
options.server.restart();
}
},
async buildEnd() {
if (miniflare) {
await miniflare.dispose();
miniflare = undefined;
return [];
}
},
async configureServer(viteDevServer) {
@@ -308,23 +306,36 @@ export function cloudflare(pluginConfig: PluginConfig = {}): vite.Plugin[] {
"Unexpected error: No Vite HTTP server"
);

miniflare = new Miniflare(
getDevMiniflareOptions(resolvedPluginConfig, viteDevServer)
);
if (miniflare) {
await miniflare.setOptions(
getDevMiniflareOptions(resolvedPluginConfig, viteDevServer)
);
} else {
miniflare = new Miniflare(
getDevMiniflareOptions(resolvedPluginConfig, viteDevServer)
);
}

await initRunners(resolvedPluginConfig, viteDevServer, miniflare);
const routerWorker = await getRouterWorker(miniflare);

const middleware = createMiddleware(
({ request }) => {
async ({ request }) => {
assert(miniflare, `Miniflare not defined`);
const routerWorker = await getRouterWorker(miniflare);

return routerWorker.fetch(toMiniflareRequest(request), {
redirect: "manual",
}) as any;
},
{ alwaysCallNext: false }
);

handleWebSocket(viteDevServer.httpServer, routerWorker.fetch);
handleWebSocket(viteDevServer.httpServer, async () => {
assert(miniflare, `Miniflare not defined`);
const routerWorker = await getRouterWorker(miniflare);

return routerWorker.fetch;
});

return () => {
viteDevServer.middlewares.use((req, res, next) => {
@@ -353,7 +364,10 @@ export function cloudflare(pluginConfig: PluginConfig = {}): vite.Plugin[] {
{ alwaysCallNext: false }
);

handleWebSocket(vitePreviewServer.httpServer, miniflare.dispatchFetch);
handleWebSocket(
vitePreviewServer.httpServer,
() => miniflare.dispatchFetch
);

// In preview mode we put our middleware at the front of the chain so that all assets are handled in Miniflare
vitePreviewServer.middlewares.use((req, res, next) => {
@@ -421,6 +435,7 @@ export function cloudflare(pluginConfig: PluginConfig = {}): vite.Plugin[] {
hotUpdate(options) {
if (additionalModulePaths.has(options.file)) {
options.server.restart();
return [];
}
},
async renderChunk(code, chunk) {
9 changes: 7 additions & 2 deletions packages/vite-plugin-cloudflare/src/miniflare-options.ts
Original file line number Diff line number Diff line change
@@ -572,6 +572,8 @@ export function getPreviewMiniflareOptions(
};
}

const removedMessages = [/^Ready on http/, /^Updated and ready on http/];

/**
* A Miniflare logger that forwards messages onto a Vite logger.
*/
@@ -583,9 +585,12 @@ class ViteMiniflareLogger extends Log {
}

override logWithLevel(level: LogLevel, message: string) {
if (/^Ready on http/.test(message)) {
level = LogLevel.DEBUG;
for (const removedMessage of removedMessages) {
if (removedMessage.test(message)) {
return;
}
}

switch (level) {
case LogLevel.ERROR:
return this.logger.error(message);
2 changes: 2 additions & 0 deletions packages/vite-plugin-cloudflare/src/utils.ts
Original file line number Diff line number Diff line change
@@ -59,3 +59,5 @@ export function cleanUrl(url: string): string {
}

export type Optional<T, K extends keyof T> = Omit<T, K> & Pick<Partial<T>, K>;

export type MaybePromise<T> = Promise<T> | T;
Loading