diff --git a/.changeset/add-miniflare-purge-cache.md b/.changeset/add-miniflare-purge-cache.md new file mode 100644 index 000000000000..1c235c9d0eb0 --- /dev/null +++ b/.changeset/add-miniflare-purge-cache.md @@ -0,0 +1,21 @@ +--- +"miniflare": minor +--- + +Add `Miniflare#purgeCache()` method to clear cache entries programmatically + +This allows developers to clear cached data during local development without +restarting the Miniflare instance. Useful when working with Workers Sites +or any application that uses the Cache API. + +```typescript +const mf = new Miniflare({ + /* options */ +}); + +// Purge the default cache +await mf.purgeCache(); + +// Purge a specific named cache +await mf.purgeCache("my-named-cache"); +``` diff --git a/.changeset/c3-frameworks-update-12564.md b/.changeset/c3-frameworks-update-12564.md deleted file mode 100644 index d7790aef4eeb..000000000000 --- a/.changeset/c3-frameworks-update-12564.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -"create-cloudflare": patch ---- - -Update dependencies of "create-cloudflare" - -The following dependency versions have been updated: - -| Dependency | From | To | -| ---------- | ------ | ------ | -| gatsby | 5.16.0 | 5.16.1 | diff --git a/.changeset/c3-frameworks-update-12565.md b/.changeset/c3-frameworks-update-12565.md deleted file mode 100644 index 7c53c5d425e9..000000000000 --- a/.changeset/c3-frameworks-update-12565.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -"create-cloudflare": patch ---- - -Update dependencies of "create-cloudflare" - -The following dependency versions have been updated: - -| Dependency | From | To | -| --------------- | ------ | ------ | -| @angular/create | 21.1.2 | 21.1.4 | diff --git a/.changeset/c3-frameworks-update-12566.md b/.changeset/c3-frameworks-update-12566.md deleted file mode 100644 index ce18550bd0ee..000000000000 --- a/.changeset/c3-frameworks-update-12566.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -"create-cloudflare": patch ---- - -Update dependencies of "create-cloudflare" - -The following dependency versions have been updated: - -| Dependency | From | To | -| ---------------------- | ------- | ------ | -| @tanstack/create-start | 0.48.10 | 0.59.3 | diff --git a/.changeset/chatty-rivers-punch.md b/.changeset/chatty-rivers-punch.md deleted file mode 100644 index dc99daf496f0..000000000000 --- a/.changeset/chatty-rivers-punch.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"miniflare": minor -"wrangler": minor ---- - -Add support for AI Search RPC method diff --git a/.changeset/chilly-pans-follow.md b/.changeset/chilly-pans-follow.md deleted file mode 100644 index c157dc44d560..000000000000 --- a/.changeset/chilly-pans-follow.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -"@cloudflare/local-explorer-ui": minor ---- - -Implemented initial data studio driver support. - -This provides the initial plumbing needed to add the complete data studio component to the local explorer in a later PR. D1 databases will now appear in the sidebar alongside KV namespaces when running the local explorer. - -This is an experimental WIP feature. diff --git a/.changeset/configurable-temp-dir.md b/.changeset/configurable-temp-dir.md deleted file mode 100644 index c50e8c235897..000000000000 --- a/.changeset/configurable-temp-dir.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -"wrangler": minor -"@cloudflare/workers-utils": minor ---- - -Add `WRANGLER_CACHE_DIR` environment variable and smart cache directory detection - -Wrangler now intelligently detects where to store cache files: - -1. Use `WRANGLER_CACHE_DIR` env var if set -2. Use existing cache directory if found (`node_modules/.cache/wrangler` or `.wrangler/cache`) -3. Create cache in `node_modules/.cache/wrangler` if `node_modules` exists -4. Otherwise use `.wrangler/cache` - -This improves compatibility with Yarn PnP, pnpm, and other package managers that don't use traditional `node_modules` directories, without requiring any configuration. diff --git a/.changeset/dependabot-update-12552.md b/.changeset/dependabot-update-12552.md deleted file mode 100644 index 637a79d8665b..000000000000 --- a/.changeset/dependabot-update-12552.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -"miniflare": patch -"wrangler": patch ---- - -Update dependencies of "miniflare", "wrangler" - -The following dependency versions have been updated: - -| Dependency | From | To | -| ---------- | ------------ | ------------ | -| workerd | 1.20260212.0 | 1.20260213.0 | diff --git a/.changeset/dependabot-update-12568.md b/.changeset/dependabot-update-12568.md deleted file mode 100644 index 40b518560297..000000000000 --- a/.changeset/dependabot-update-12568.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -"miniflare": patch -"wrangler": patch ---- - -Update dependencies of "miniflare", "wrangler" - -The following dependency versions have been updated: - -| Dependency | From | To | -| ---------- | ------------ | ------------ | -| workerd | 1.20260213.0 | 1.20260214.0 | diff --git a/.changeset/exclude-wrangler-from-pages-upload.md b/.changeset/exclude-wrangler-from-pages-upload.md deleted file mode 100644 index 097e4f3568a0..000000000000 --- a/.changeset/exclude-wrangler-from-pages-upload.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"wrangler": patch ---- - -fix: exclude `.wrangler` directory from Pages uploads - -The `.wrangler` directory contains local cache and state files that should never be deployed. This aligns Pages upload behavior with Workers Assets, which already excludes `.wrangler` via `.assetsignore`. diff --git a/.changeset/fix-getport-host-mismatch.md b/.changeset/fix-getport-host-mismatch.md deleted file mode 100644 index 8a7ae7a87f29..000000000000 --- a/.changeset/fix-getport-host-mismatch.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"wrangler": patch ---- - -Fix port availability check probing the wrong host when host changes - -`memoizeGetPort` correctly invalidated its cached port when called with a different host, but then still probed the original host for port availability. This could return a port that was free on the original host but already in use on the requested one, leading to bind failures at startup. diff --git a/.changeset/fruity-views-flow.md b/.changeset/fruity-views-flow.md deleted file mode 100644 index fcac19c3cb29..000000000000 --- a/.changeset/fruity-views-flow.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -"wrangler": minor ---- - -Ensure the `nodejs_compat` flag is always applied in autoconfig - -Previously, the autoconfig feature relied on individual framework configurations to specify Node.js compatibility flags, some could set `nodejs_compat` while others `nodejs_als`. - -Now instead `nodejs_compat` is always included as a compatibility flag, this is generally beneficial and the user can always remove the flag afterwards if they want to. diff --git a/.changeset/function-vite-config.md b/.changeset/function-vite-config.md deleted file mode 100644 index 4fdd11853cee..000000000000 --- a/.changeset/function-vite-config.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -"wrangler": patch ---- - -Support function-based Vite configs in autoconfig setup - -`wrangler setup` and `wrangler deploy --x-autoconfig` can now automatically add the Cloudflare Vite plugin to projects that use function-based `defineConfig()` patterns. Previously, autoconfig would fail with "Cannot modify Vite config: expected an object literal but found ArrowFunctionExpression" for configs like: - -```ts -export default defineConfig(({ isSsrBuild }) => ({ - plugins: [reactRouter(), tsconfigPaths()], -})); -``` - -This pattern is used by several official framework templates, including React Router's `node-postgres` and `node-custom-server` templates. The following `defineConfig()` patterns are now supported: - -- `defineConfig({ ... })` (object literal, already worked) -- `defineConfig(() => ({ ... }))` (arrow function with expression body) -- `defineConfig(({ isSsrBuild }) => ({ ... }))` (arrow function with destructured params) -- `defineConfig(() => { return { ... }; })` (arrow function with block body) -- `defineConfig(function() { return { ... }; })` (function expression) diff --git a/.changeset/hot-walls-act.md b/.changeset/hot-walls-act.md deleted file mode 100644 index fb92589c2350..000000000000 --- a/.changeset/hot-walls-act.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"wrangler": patch ---- - -Fix `.assetsignore` formatting when autoconfig creates a new file - -Previously, when `wrangler setup` or `wrangler deploy --x-autoconfig` created a new `.assetsignore` file via autoconfig, it would add unnecessary leading empty lines before the wrangler-specific entries. Empty separator lines should only be added when appending to an existing `.assetsignore` file. This fix ensures newly created `.assetsignore` files start cleanly without leading blank lines. diff --git a/.changeset/lemon-dots-bathe.md b/.changeset/lemon-dots-bathe.md deleted file mode 100644 index 1af49287dfee..000000000000 --- a/.changeset/lemon-dots-bathe.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -"@cloudflare/local-explorer-ui": minor ---- - -Add database table selection dropdown. - -As part of the ongoing work to implement the data studio into the local explorer, this change allows you to view and select which table for a database you want to inspect. - -This is an experimental WIP feature. diff --git a/.changeset/miniflare-cache-dir.md b/.changeset/miniflare-cache-dir.md deleted file mode 100644 index 2701fb93421b..000000000000 --- a/.changeset/miniflare-cache-dir.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -"miniflare": patch ---- - -Add `MINIFLARE_CACHE_DIR` environment variable and smart cache directory detection - -Miniflare now intelligently detects where to store its cf.json cache file: - -1. Use `MINIFLARE_CACHE_DIR` env var if set -2. Use existing cache directory if found (`node_modules/.mf` or `.wrangler/cache`) -3. Create cache in `node_modules/.mf` if `node_modules` exists -4. Otherwise use `.wrangler/cache` - -This improves compatibility with Yarn PnP, pnpm, and other package managers that don't use traditional `node_modules` directories, without requiring any configuration. diff --git a/.changeset/native-child-process-module.md b/.changeset/native-child-process-module.md deleted file mode 100644 index e89296cf8884..000000000000 --- a/.changeset/native-child-process-module.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@cloudflare/unenv-preset": minor ---- - -Add support for native `node:child_process` module from workerd when the `enable_nodejs_child_process_module` compatibility flag is enabled. - -This feature is currently experimental and requires both the `enable_nodejs_child_process_module` and `experimental` compatibility flags to be set. diff --git a/.changeset/native-node-tty.md b/.changeset/native-node-tty.md deleted file mode 100644 index 2f46751984b9..000000000000 --- a/.changeset/native-node-tty.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@cloudflare/unenv-preset": minor ---- - -Add support for native `node:tty` module from workerd when the `enable_nodejs_tty_module` compatibility flag is enabled. - -This feature is currently experimental and requires `nodejs_compat`, `experimental`, and `enable_nodejs_tty_module` compatibility flags to be set. diff --git a/.changeset/native-node-v8-module.md b/.changeset/native-node-v8-module.md deleted file mode 100644 index 64d37b3ff386..000000000000 --- a/.changeset/native-node-v8-module.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@cloudflare/unenv-preset": patch ---- - -Add support for the native `node:v8` module from workerd when the `enable_nodejs_v8_module` and `experimental` compatibility flags are enabled - -This feature is currently experimental and requires `nodejs_compat`, `experimental`, and `enable_nodejs_v8_module` compatibility flags to be set. diff --git a/.changeset/pink-rockets-wish.md b/.changeset/pink-rockets-wish.md new file mode 100644 index 000000000000..f472b1bb50c0 --- /dev/null +++ b/.changeset/pink-rockets-wish.md @@ -0,0 +1,9 @@ +--- +"@cloudflare/local-explorer-ui": minor +--- + +Add the initial plumbing for data studio components. + +This serves as another stepping stone for adding the complete data studio to the local explorer. + +This is a WIP experimental feature. diff --git a/.changeset/plain-trains-marry.md b/.changeset/plain-trains-marry.md deleted file mode 100644 index 0a1efd8bc701..000000000000 --- a/.changeset/plain-trains-marry.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"miniflare": minor ---- - -Local explorer: add endpoints to list DO namespaces and objects - -This is part of an experimental, WIP feature. diff --git a/.changeset/salty-mirrors-turn.md b/.changeset/salty-mirrors-turn.md deleted file mode 100644 index eeb8893e1479..000000000000 --- a/.changeset/salty-mirrors-turn.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -"wrangler": minor ---- - -Support `--tag` and `--message` flags on `wrangler deploy` - -They have the same behavior that they do as during `wrangler versions upload`, as both -are set on the version. - -The message is also reused for the deployment as well, with the same behavior as used -during `wrangler versions deploy`. diff --git a/.changeset/sandbox-eperm-bind-error.md b/.changeset/sandbox-eperm-bind-error.md deleted file mode 100644 index c3b952d4bd7f..000000000000 --- a/.changeset/sandbox-eperm-bind-error.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"wrangler": patch ---- - -Improve error message when port binding is blocked by a sandbox or security policy - -When running `wrangler dev` inside a restricted environment (such as an AI coding agent sandbox or locked-down container), the port availability check would fail with a raw `EPERM` error. This now provides a clear message explaining that a sandbox or security policy is blocking network access, rather than the generic permission error that previously pointed at the file system. diff --git a/.changeset/smart-frameworks-detect.md b/.changeset/smart-frameworks-detect.md deleted file mode 100644 index cd70ceb5292f..000000000000 --- a/.changeset/smart-frameworks-detect.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"wrangler": patch ---- - -Improve framework detection when multiple frameworks are found - -When autoconfig detects multiple frameworks in a project, Wrangler now applies smarter logic to select the most appropriate one. Selecting the wrong one is acceptable locally where the user can change the detected framework, in CI an error is instead thrown. diff --git a/.changeset/spicy-eggs-fail.md b/.changeset/spicy-eggs-fail.md deleted file mode 100644 index aeb177a2ac61..000000000000 --- a/.changeset/spicy-eggs-fail.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"wrangler": patch ---- - -Add trailing newline to generated `package.json` and `wrangler.jsonc` files diff --git a/.changeset/thin-ears-sip.md b/.changeset/thin-ears-sip.md deleted file mode 100644 index 585e8ef83c31..000000000000 --- a/.changeset/thin-ears-sip.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"wrangler": patch ---- - -Fix `.gitignore` formatting when autoconfig creates a new file - -Previously, when `wrangler setup` or `wrangler deploy` created a new `.gitignore` file via autoconfig, it would add unnecessary leading empty lines before the wrangler-specific entries. Empty separator lines should only be added when appending to an existing `.gitignore` file. This fix ensures newly created `.gitignore` files start cleanly without leading blank lines. diff --git a/.changeset/workspace-root-error.md b/.changeset/workspace-root-error.md deleted file mode 100644 index 6640828a560d..000000000000 --- a/.changeset/workspace-root-error.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"wrangler": patch ---- - -Throw actionable error when autoconfig is run in the root of a workspace - -When running Wrangler commands that trigger auto-configuration (like `wrangler dev` or `wrangler deploy`) in the root directory of a monorepo workspace, a helpful error is now shown directing users to run the command in a specific project's directory instead. diff --git a/packages/create-cloudflare/CHANGELOG.md b/packages/create-cloudflare/CHANGELOG.md index 45aa746f8b32..3624ca3f3e4f 100644 --- a/packages/create-cloudflare/CHANGELOG.md +++ b/packages/create-cloudflare/CHANGELOG.md @@ -1,5 +1,33 @@ # create-cloudflare +## 2.64.2 + +### Patch Changes + +- [#12564](https://github.com/cloudflare/workers-sdk/pull/12564) [`98e2627`](https://github.com/cloudflare/workers-sdk/commit/98e2627f340c33eb321222bfa32fb0d28e03c5b5) Thanks [@dependabot](https://github.com/apps/dependabot)! - Update dependencies of "create-cloudflare" + + The following dependency versions have been updated: + + | Dependency | From | To | + | ---------- | ------ | ------ | + | gatsby | 5.16.0 | 5.16.1 | + +- [#12565](https://github.com/cloudflare/workers-sdk/pull/12565) [`aefb2a0`](https://github.com/cloudflare/workers-sdk/commit/aefb2a0422068ef47920f01b5028b41faf416317) Thanks [@dependabot](https://github.com/apps/dependabot)! - Update dependencies of "create-cloudflare" + + The following dependency versions have been updated: + + | Dependency | From | To | + | --------------- | ------ | ------ | + | @angular/create | 21.1.2 | 21.1.4 | + +- [#12566](https://github.com/cloudflare/workers-sdk/pull/12566) [`3cd9d21`](https://github.com/cloudflare/workers-sdk/commit/3cd9d21206e42c6b88a71be76cbc69a24c212cd6) Thanks [@dependabot](https://github.com/apps/dependabot)! - Update dependencies of "create-cloudflare" + + The following dependency versions have been updated: + + | Dependency | From | To | + | ---------------------- | ------- | ------ | + | @tanstack/create-start | 0.48.10 | 0.59.3 | + ## 2.64.1 ### Patch Changes diff --git a/packages/create-cloudflare/package.json b/packages/create-cloudflare/package.json index 6123c87e7e73..265ff6d67281 100644 --- a/packages/create-cloudflare/package.json +++ b/packages/create-cloudflare/package.json @@ -1,6 +1,6 @@ { "name": "create-cloudflare", - "version": "2.64.1", + "version": "2.64.2", "description": "A CLI for creating and deploying new applications to Cloudflare.", "keywords": [ "cloudflare", diff --git a/packages/local-explorer-ui/CHANGELOG.md b/packages/local-explorer-ui/CHANGELOG.md index d8897a8b84d6..66e8a9e85d72 100644 --- a/packages/local-explorer-ui/CHANGELOG.md +++ b/packages/local-explorer-ui/CHANGELOG.md @@ -1,5 +1,21 @@ # @cloudflare/local-explorer-ui +## 0.4.0 + +### Minor Changes + +- [#12518](https://github.com/cloudflare/workers-sdk/pull/12518) [`323f14e`](https://github.com/cloudflare/workers-sdk/commit/323f14e19605f3f0eb732992fa6d765657cb93ba) Thanks [@NuroDev](https://github.com/NuroDev)! - Implemented initial data studio driver support. + + This provides the initial plumbing needed to add the complete data studio component to the local explorer in a later PR. D1 databases will now appear in the sidebar alongside KV namespaces when running the local explorer. + + This is an experimental WIP feature. + +- [#12555](https://github.com/cloudflare/workers-sdk/pull/12555) [`2eeefeb`](https://github.com/cloudflare/workers-sdk/commit/2eeefeb01ddb6d44b99e3ea93a1b9faada925cb3) Thanks [@NuroDev](https://github.com/NuroDev)! - Add database table selection dropdown. + + As part of the ongoing work to implement the data studio into the local explorer, this change allows you to view and select which table for a database you want to inspect. + + This is an experimental WIP feature. + ## 0.3.0 ### Minor Changes diff --git a/packages/local-explorer-ui/package.json b/packages/local-explorer-ui/package.json index d1eab1f745d8..898778cdef33 100644 --- a/packages/local-explorer-ui/package.json +++ b/packages/local-explorer-ui/package.json @@ -1,6 +1,6 @@ { "name": "@cloudflare/local-explorer-ui", - "version": "0.3.0", + "version": "0.4.0", "private": true, "type": "module", "scripts": { diff --git a/packages/local-explorer-ui/src/components/Sidebar.tsx b/packages/local-explorer-ui/src/components/Sidebar.tsx index 0a449b4690b0..3141d0f1dd0c 100644 --- a/packages/local-explorer-ui/src/components/Sidebar.tsx +++ b/packages/local-explorer-ui/src/components/Sidebar.tsx @@ -36,7 +36,7 @@ function SidebarItemGroup({ }: SidebarItemGroupProps): JSX.Element { return ( - + {title} diff --git a/packages/local-explorer-ui/src/components/studio/Context.tsx b/packages/local-explorer-ui/src/components/studio/Context.tsx new file mode 100644 index 000000000000..f39e5ea1b3f8 --- /dev/null +++ b/packages/local-explorer-ui/src/components/studio/Context.tsx @@ -0,0 +1,58 @@ +import { createContext, useContext } from "react"; +import type { + IStudioDriver, + StudioResource, + StudioSchemas, +} from "../../types/studio"; +import type { StudioTabDefinitionMetadata } from "./TabRegister"; +import type { StudioWindowTabItem } from "./WindowTab/types"; +import type { PropsWithChildren } from "react"; + +export interface StudioContextValue { + driver: IStudioDriver; + loadingSchema: boolean; + refreshSchema: () => void; + resource: StudioResource; + schemas: StudioSchemas | null; + + // Tab manipulation context + selectedTabKey: string; + setSelectedTabKey: React.Dispatch>; + setStudioTabs: React.Dispatch>; + tabs: StudioWindowTabItem[]; + + // Tab management + closeStudioTab: (identifier: string) => void; + openStudioTab: (data: StudioTabDefinitionMetadata, isTemp?: boolean) => void; + replaceStudioTab: ( + identifier: string, + replaced: StudioTabDefinitionMetadata, + options?: { withoutReplaceComponent?: boolean; isTemp?: boolean } + ) => void; + updateStudioTabStatus: ( + identifier: string | StudioTabDefinitionMetadata, + status: { isDirty?: boolean; isTemp?: boolean } + ) => void; +} + +const StudioContext = createContext(null); + +export function useStudioContext() { + const context = useContext(StudioContext); + if (!context) { + throw new Error( + "useStudioContext must be used within a StudioContextProvider" + ); + } + + return context; +} + +export function StudioContextProvider({ + children, + value, +}: PropsWithChildren<{ value: StudioContextValue }>) { + return ( + {children} + ); +} diff --git a/packages/local-explorer-ui/src/components/studio/ContextMenu.tsx b/packages/local-explorer-ui/src/components/studio/ContextMenu.tsx new file mode 100644 index 000000000000..c85a9570f874 --- /dev/null +++ b/packages/local-explorer-ui/src/components/studio/ContextMenu.tsx @@ -0,0 +1,102 @@ +import { DropdownMenu } from "@cloudflare/kumo"; +import { + createContext, + useCallback, + useContext, + useMemo, + useRef, + useState, +} from "react"; +import type { ComponentProps, PropsWithChildren } from "react"; + +type DropdownItemBuilderProps = ComponentProps; + +type OnOpenChangeHandler = (open: boolean) => void; + +type OpenContextMenuHandler = ( + mouseEvent: React.MouseEvent, + menuItems: DropdownItemBuilderProps[], + onOpenChange?: OnOpenChangeHandler +) => void; + +export const StudioContextMenu = createContext<{ + openContextMenu: OpenContextMenuHandler; +} | null>(null); + +export function useStudioContextMenu() { + const context = useContext(StudioContextMenu); + if (!context) { + throw new Error( + "Cannot use useStudioContextMenu outside StudioContextMenuProvider" + ); + } + + return context; +} + +interface Position { + x: number; + y: number; +} + +type StudioContextMenuProvider = PropsWithChildren; + +export function StudioContextMenuProvider({ + children, +}: StudioContextMenuProvider) { + const [position, setPosition] = useState({ x: 0, y: 0 }); + const [open, setOpen] = useState(false); + const [_menuItems, setMenuItems] = useState([]); + const onOpenChange = useRef(null); + + const openContextMenu = useCallback( + ( + mouseEvent: React.MouseEvent, + items: DropdownItemBuilderProps[], + _onOpenChange?: OnOpenChangeHandler + ) => { + setOpen(true); + setMenuItems(items); + setPosition({ + x: mouseEvent.clientX, + y: mouseEvent.clientY, + }); + onOpenChange.current = _onOpenChange ?? null; + }, + [] + ); + + const value = useMemo(() => ({ openContextMenu }), [openContextMenu]); + + return ( + + { + setOpen(isOpen); + onOpenChange.current?.(isOpen); + }} + open={open} + > + + } + /> + + + {/* TODO: Add stub implementation of this dropdown using the new Kumo components */} + {/* */} + + + + {children} + + ); +} diff --git a/packages/local-explorer-ui/src/components/studio/Modal.tsx b/packages/local-explorer-ui/src/components/studio/Modal.tsx new file mode 100644 index 000000000000..afe6def6a4c6 --- /dev/null +++ b/packages/local-explorer-ui/src/components/studio/Modal.tsx @@ -0,0 +1,154 @@ +import { createContext, useCallback, useContext, useState } from "react"; +import type { ComponentType, PropsWithChildren } from "react"; + +export type ModalInjectedProps = { + closeModal: () => void; + isOpen?: boolean; +}; + +export type ModalOwnProps = Omit & { + onClose?: () => void; +}; + +/** + * Internal type-erased modal entry for heterogeneous storage. + * The public API remains fully generic via `openModal(...)`. + */ +interface IModalEntry { + id: string; + ModalComponent: ComponentType; + props?: Record; +} + +// Modal system requires flexible typing for heterogeneous component storage +interface ModalContextValue { + openModal: ( + ModalComponent: ComponentType, + props?: Omit & { onClose?: () => void } + ) => void; + closeModal: (ModalComponent?: ComponentType) => void; +} + +const ModalContext = createContext(null); + +export function useModal() { + const context = useContext(ModalContext); + if (!context) { + throw new Error("useModal must be used within a ModalProvider"); + } + + return context; +} + +export function useModalContext() { + const context = useContext(ModalContext); + if (!context) { + throw new Error("useModalContext must be used within a ModalProvider"); + } + + return context; +} + +/** + * Simple modal provider for the portable Studio component + */ +export function ModalProvider({ children }: PropsWithChildren) { + const [modals, setModals] = useState>([]); + + const handleOpenModal = useCallback( + ( + ModalComponent: ComponentType, + props?: Omit & { onClose?: () => void } + ) => { + const id = crypto.randomUUID(); + setModals((prev) => [ + ...prev, + { + id, + ModalComponent: + ModalComponent as unknown as ComponentType, + props: props as unknown as Record, + }, + ]); + }, + [] + ); + + const handleCloseModal = useCallback( + (ModalComponent?: ComponentType) => { + setModals((prev) => { + if (ModalComponent) { + return prev.filter( + (m) => (m.ModalComponent as unknown) !== (ModalComponent as unknown) + ); + } + // Close the last modal if no component specified + return prev.slice(0, -1); + }); + }, + [] + ); + + return ( + + {children} + {modals.map(({ id, ModalComponent, props = {} }) => { + const onClose = () => { + const onCloseProp = props.onClose; + if (typeof onCloseProp === "function") { + (onCloseProp as () => void)(); + } + handleCloseModal(ModalComponent); + }; + + return ( + + ); + })} + + ); +} + +/** + * Action creator for opening modals (for compatibility) + * + * NOTE: Modal system requires flexible typing + */ +export function createOpenModalAction( + ModalComponent: ComponentType, + props?: Omit & { onClose?: () => void } +) { + // This is a placeholder - in the original code this returns a Redux action + // In the portable version, use the useModal hook instead + console.warn( + "openModal action called outside of ModalProvider context. Use useModal hook instead." + ); + return { + payload: { + ModalComponent, + props, + }, + type: "MODAL_OPEN", + }; +} + +export function createCloseModalAction( + ModalComponent?: ComponentType +) { + console.warn( + "closeModal action called outside of ModalProvider context. Use useModal hook instead." + ); + return { + payload: { + ModalComponent, + }, + type: "MODAL_CLOSE", + }; +} diff --git a/packages/local-explorer-ui/src/components/studio/TabRegister.tsx b/packages/local-explorer-ui/src/components/studio/TabRegister.tsx new file mode 100644 index 000000000000..3f105c1c32dc --- /dev/null +++ b/packages/local-explorer-ui/src/components/studio/TabRegister.tsx @@ -0,0 +1,38 @@ +import type { Icon } from "@phosphor-icons/react"; +import type { ReactElement } from "react"; + +const RegisteredTabDefinition = [ + // TODO: Add query, table, edit table and new table tab definitions +] as Array< + TabDefinition<{ + id?: string; + schemaName?: string; + tableName?: string; + type: string; + }> +>; + +export interface TabDefinition { + icon: Icon; + makeComponent: (data: T) => ReactElement; + makeIdentifier: (data: T) => string; + makeTitle: (data: T) => string; + type: T["type"]; +} + +type ExtractGeneric = T extends TabDefinition ? U : never; + +export type StudioTabDefinitionMetadata = ExtractGeneric< + (typeof RegisteredTabDefinition)[number] +>; + +export const StudioTabDefinitionList = RegisteredTabDefinition.reduce( + (a, b) => { + a[b.type] = b as TabDefinition; + return a; + }, + {} as Record< + StudioTabDefinitionMetadata["type"], + TabDefinition + > +); diff --git a/packages/local-explorer-ui/src/components/studio/WindowTab/ContentWrapper.tsx b/packages/local-explorer-ui/src/components/studio/WindowTab/ContentWrapper.tsx new file mode 100644 index 000000000000..f90ea8ec545c --- /dev/null +++ b/packages/local-explorer-ui/src/components/studio/WindowTab/ContentWrapper.tsx @@ -0,0 +1,81 @@ +import { cn } from "@cloudflare/kumo"; +import { useCallback } from "react"; +import { StudioCurrentWindowTabContext } from "./Context"; +import type { BeforeTabClosingHandler, StudioWindowTabItem } from "./types"; + +interface StudioTabContentWrapperProps { + beforeClosingHandlersRef: React.RefObject< + Map + >; + onTabsChange?: React.Dispatch>; + selectedTabKey?: string; + tab: StudioWindowTabItem; +} + +// Provide per-tab context (dirty state, close handler) to the tab content. +// Only render the content if the tab is selected. +export function StudioTabContentWrapper({ + beforeClosingHandlersRef, + onTabsChange, + selectedTabKey, + tab, +}: StudioTabContentWrapperProps): JSX.Element { + const tabKey = tab.key; + + /** + * Registers a {@link BeforeTabClosingHandler} callback for this tab. + */ + const setBeforeTabClosingHandler = useCallback( + (handler: BeforeTabClosingHandler): void => { + beforeClosingHandlersRef.current.set(tabKey, handler); + }, + [beforeClosingHandlersRef, tabKey] + ); + + /** + * Update the dirty state for this tab, only if it changes. + */ + const setDirtyState = useCallback( + (newDirtyState: boolean): void => { + if (!onTabsChange) { + return; + } + + const prevDirtyState = !!tab.isDirty; // Convert it to boolean + if (newDirtyState !== prevDirtyState) { + onTabsChange((prevTabs) => { + return prevTabs.map((prevTab) => { + if (prevTab.key !== tab.key) { + return prevTab; + } + + return { + ...prevTab, + isDirty: newDirtyState, + }; + }); + }); + } + }, + [tab, onTabsChange] + ); + + return ( + +
+ {tab.component} +
+
+ ); +} diff --git a/packages/local-explorer-ui/src/components/studio/WindowTab/Context.tsx b/packages/local-explorer-ui/src/components/studio/WindowTab/Context.tsx new file mode 100644 index 000000000000..4fa055a7d6bc --- /dev/null +++ b/packages/local-explorer-ui/src/components/studio/WindowTab/Context.tsx @@ -0,0 +1,21 @@ +import { createContext, useContext } from "react"; +import type { BeforeTabClosingHandler } from "./types"; + +export interface IStudioCurrentWindowTabContext { + identifier: string; + isTabActive: boolean; + setBeforeTabClosingHandler: (handler: BeforeTabClosingHandler) => void; + setDirtyState: (dirtyState: boolean) => void; +} + +export const StudioCurrentWindowTabContext = + createContext(null); + +export function useStudioCurrentWindowTab(): IStudioCurrentWindowTabContext { + const context = useContext(StudioCurrentWindowTabContext); + if (!context) { + throw new Error("Cannot useStudioCurrentWindowTab outside StudioWindowTab"); + } + + return context; +} diff --git a/packages/local-explorer-ui/src/components/studio/WindowTab/ItemRenderer.tsx b/packages/local-explorer-ui/src/components/studio/WindowTab/ItemRenderer.tsx new file mode 100644 index 000000000000..6b26b5cd2c5c --- /dev/null +++ b/packages/local-explorer-ui/src/components/studio/WindowTab/ItemRenderer.tsx @@ -0,0 +1,75 @@ +import { cn } from "@cloudflare/kumo"; +import { CircleIcon, XIcon } from "@phosphor-icons/react"; +import { useState } from "react"; +import type { StudioWindowTabItem } from "./types"; + +interface StudioWindowTabItemRendererProps { + index: number; + onClick: () => void; + onClose?: () => void; + onDoubleClick?: () => void; + selected?: boolean; + tab: StudioWindowTabItem; +} + +export function StudioWindowTabItemRenderer({ + onClick, + onClose, + onDoubleClick, + selected, + tab, +}: StudioWindowTabItemRendererProps): JSX.Element { + const isDirty = tab.isDirty; + const isTemp = tab.isTemp; + + const [isHovered, setIsHovered] = useState(false); + const [isCloseHovered, setIsCloseHovered] = useState(false); + + const shouldShowDirtyIcon = !isCloseHovered && isDirty; + const shouldShowCloseIcon = !shouldShowDirtyIcon && (selected || isHovered); + + return ( +
setIsHovered(true)} + onMouseLeave={() => setIsHovered(false)} + > + + +
{tab.title}
+ + {onClose && ( +
{ + e.stopPropagation(); + onClose?.(); + }} + onMouseEnter={() => setIsCloseHovered(true)} + onMouseLeave={() => setIsCloseHovered(false)} + > + {shouldShowCloseIcon && ( + + )} + {shouldShowDirtyIcon && ( + + )} +
+ )} +
+ ); +} diff --git a/packages/local-explorer-ui/src/components/studio/WindowTab/MenuProps.tsx b/packages/local-explorer-ui/src/components/studio/WindowTab/MenuProps.tsx new file mode 100644 index 000000000000..61715786ffc1 --- /dev/null +++ b/packages/local-explorer-ui/src/components/studio/WindowTab/MenuProps.tsx @@ -0,0 +1,21 @@ +import { PlusIcon } from "@phosphor-icons/react"; + +interface StudioWindowTabMenuProps { + onClick: () => void; +} + +export function StudioWindowTabMenu({ + onClick, +}: StudioWindowTabMenuProps): JSX.Element { + return ( + + ); +} diff --git a/packages/local-explorer-ui/src/components/studio/WindowTab/Pane.tsx b/packages/local-explorer-ui/src/components/studio/WindowTab/Pane.tsx new file mode 100644 index 000000000000..bd13277b81c4 --- /dev/null +++ b/packages/local-explorer-ui/src/components/studio/WindowTab/Pane.tsx @@ -0,0 +1,42 @@ +import { useCallback } from "react"; +import { useStudioContext } from "../Context"; +import { StudioWindowTab } from "."; +import type { StudioWindowTabItem } from "./types"; + +export function StudioWindowTabPane(): JSX.Element { + const { + openStudioTab, + selectedTabKey, + setSelectedTabKey, + setStudioTabs, + tabs, + updateStudioTabStatus, + } = useStudioContext(); + + const onNewQuery = useCallback(() => { + openStudioTab({ + id: window.crypto.randomUUID(), + type: "query", + }); + }, [openStudioTab]); + + const onDoubleClick = useCallback( + (tab: StudioWindowTabItem) => { + updateStudioTabStatus(tab.identifier, { + isTemp: false, + }); + }, + [updateStudioTabStatus] + ); + + return ( + + ); +} diff --git a/packages/local-explorer-ui/src/components/studio/WindowTab/index.tsx b/packages/local-explorer-ui/src/components/studio/WindowTab/index.tsx new file mode 100644 index 000000000000..f39499a949ad --- /dev/null +++ b/packages/local-explorer-ui/src/components/studio/WindowTab/index.tsx @@ -0,0 +1,113 @@ +import { useRef } from "react"; +import { StudioTabContentWrapper } from "./ContentWrapper"; +import { StudioWindowTabItemRenderer } from "./ItemRenderer"; +import { StudioWindowTabMenu } from "./MenuProps"; +import type { BeforeTabClosingHandler, StudioWindowTabItem } from "./types"; + +export interface StudioWindowTabProps { + onDoubleClick?: (tab: StudioWindowTabItem) => void; + onNewClicked?: () => void; + /** + * Called when a different tab is selected by the user. + */ + onSelectedTabChange: (newSelectedKey: string) => void; + /** + * Called when the tab list changes — either due to closing a tab or reordering tabs via drag-and-drop. + */ + onTabsChange?: React.Dispatch>; + /** + * The key of the currently selected (active) tab. + */ + selectedTabKey?: string; + tabs: StudioWindowTabItem[]; +} + +/** + * A window tab component that allows users to switch between tabs without unmounting, + * preserving each tab’s interactive state. Supports tab closing and drag-to-reorder functionality. + */ +export function StudioWindowTab({ + onDoubleClick, + onNewClicked, + onSelectedTabChange, + onTabsChange, + selectedTabKey, + tabs, +}: StudioWindowTabProps): JSX.Element { + const beforeClosingHandlersRef = useRef( + new Map() + ); + + return ( +
+
+ {tabs.map((tab, tabIndex) => { + // Handles tab closure. If the closed tab is the currently active one, + // automatically select the nearest remaining tab to preserve continuity. + const handleTabClose = () => { + if (!onTabsChange) { + return; + } + + // Run any registered "before close" handler (e.g., unsaved changes check) + const beforeClosingHandler = beforeClosingHandlersRef.current.get( + tab.key + ); + if (beforeClosingHandler) { + const canClose = beforeClosingHandler(tab); + if (!canClose) { + return; + } + } + + // Clean up the handler since the tab is being removed + beforeClosingHandlersRef.current.delete(tab.key); + + const foundIndex = tabs.findIndex((t) => t.key === tab.key); + const newTabs = tabs.filter((t) => t.key !== tab.key); + + onTabsChange(newTabs); + + if (selectedTabKey === tab.key && newTabs.length > 0) { + const newSelectedIndex = Math.min(newTabs.length - 1, foundIndex); + const newSelectedTab = newTabs[newSelectedIndex]; + if (newSelectedTab) { + onSelectedTabChange(newSelectedTab.key); + } + } + }; + + return ( + onSelectedTabChange(tab.key)} + onClose={onTabsChange ? handleTabClose : undefined} + onDoubleClick={(): void => { + onDoubleClick?.(tab); + }} + selected={tab.key === selectedTabKey} + tab={tab} + /> + ); + })} + + {onNewClicked && } + +
+
+ +
+ {tabs.map((tab) => ( + + ))} +
+
+ ); +} diff --git a/packages/local-explorer-ui/src/components/studio/WindowTab/types.ts b/packages/local-explorer-ui/src/components/studio/WindowTab/types.ts new file mode 100644 index 000000000000..43dda244d84a --- /dev/null +++ b/packages/local-explorer-ui/src/components/studio/WindowTab/types.ts @@ -0,0 +1,14 @@ +import type { Icon } from "@phosphor-icons/react"; + +export interface StudioWindowTabItem { + component: JSX.Element; + icon: Icon; + identifier: string; + isDirty?: boolean; + isTemp?: boolean; + key: string; + title: React.ReactNode; + type?: string; +} + +export type BeforeTabClosingHandler = (tab: StudioWindowTabItem) => boolean; diff --git a/packages/local-explorer-ui/src/components/studio/index.tsx b/packages/local-explorer-ui/src/components/studio/index.tsx new file mode 100644 index 000000000000..9a7c4066e7bf --- /dev/null +++ b/packages/local-explorer-ui/src/components/studio/index.tsx @@ -0,0 +1,351 @@ +import { useCallback, useEffect, useMemo, useRef, useState } from "react"; +import { useLeaveGuard } from "../../hooks/leave-guard"; +import { StudioContextProvider } from "./Context"; +import { StudioContextMenuProvider } from "./ContextMenu"; +import { ModalProvider } from "./Modal"; +import { StudioTabDefinitionList } from "./TabRegister"; +import { StudioWindowTabPane } from "./WindowTab/Pane"; +import type { + IStudioDriver, + StudioResource, + StudioSchemas, +} from "../../types/studio"; +import type { StudioContextValue } from "./Context"; +import type { StudioTabDefinitionMetadata, TabDefinition } from "./TabRegister"; +import type { StudioWindowTabItem } from "./WindowTab/types"; + +/** + * Default schema name for SQLite/D1 databases + */ +const DEFAULT_SCHEMA_NAME = "main"; + +interface StudioProps { + /** + * The studio driver used to make requests to the database. + */ + driver: IStudioDriver; + /** + * Table name to open initially (assumes 'main' schema) + */ + initialTable?: string; + /** + * Metadata about the current studio resource. + */ + resource: StudioResource; +} + +export function Studio({ + driver, + initialTable, + resource, +}: StudioProps): JSX.Element { + // Track whether we've already opened the initial table + const hasOpenedInitialTable = useRef(false); + + const [schemas, setSchemas] = useState(null); + const [loadingSchema, setLoadingSchema] = useState(true); + const [tabs, setTabs] = useState(() => [ + // TODO: Re-add `StudioQueryTab` default tab + ]); + + const [selectedTabKey, setSelectedTabKey] = useState( + // Automatically select the first tab + () => tabs[0]?.key ?? "" + ); + + const selectedTabKeyRef = useRef(selectedTabKey); + selectedTabKeyRef.current = selectedTabKey; + + const refreshSchema = useCallback(async () => { + setLoadingSchema(true); + + try { + const driverSchemas = await driver.schemas(); + setSchemas(driverSchemas); + } catch (error) { + console.error(error); + } finally { + setLoadingSchema(false); + } + }, [driver]); + + useEffect((): void => { + void refreshSchema(); + }, [refreshSchema]); + + /** + * Utility to close a tab given its identifier + */ + const closeStudioTab = useCallback((tabIdentifier: string) => { + setTabs((previousTabs) => { + // Find the index of the tab matching the identifier + const matchedTabIndex = previousTabs.findIndex( + (tab) => tab.identifier === tabIdentifier + ); + + const matchedTab = previousTabs[matchedTabIndex]; + if (!matchedTab) { + return previousTabs; + } + + // Remove the matched tab from the list + const filteredTabs = previousTabs.filter((tab) => tab !== matchedTab); + + // If the closed tab was the selected one, update selection + if ( + selectedTabKeyRef.current === matchedTab.key && + filteredTabs.length > 0 + ) { + const newSelectedIndex = Math.min( + filteredTabs.length - 1, + matchedTabIndex + ); + + const newSelectedTab = filteredTabs[newSelectedIndex]; + if (newSelectedTab) { + setSelectedTabKey(newSelectedTab.key); + } + } + + return filteredTabs; + }); + }, []); + + /** + * Utility to open a tab given its identifier + */ + const openStudioTab = useCallback( + (data: StudioTabDefinitionMetadata, isTemporary?: boolean) => { + setTabs((prevTabs) => { + // Getting tab setting + const tabTypeDefinition = StudioTabDefinitionList[data.type]; + if (!tabTypeDefinition) { + console.error("Trying to open unknown tab type", data); + return prevTabs; + } + + const identifier = tabTypeDefinition.makeIdentifier(data); + + // Open existing tab if exist + const foundMatchedTab = prevTabs.find( + (tab) => tab.identifier === identifier + ); + if (foundMatchedTab) { + setSelectedTabKey(foundMatchedTab.key); + return prevTabs; + } + + const newTabKey = window.crypto.randomUUID(); + setSelectedTabKey(newTabKey); + + // Check if there is any temporary, we will replace instead of adding new tab + const tempTab = prevTabs.find((tab) => tab.isTemp && !tab.isDirty); + if (tempTab) { + return prevTabs.map((tab) => { + if (tab === tempTab) { + return { + ...tab, + key: newTabKey, + identifier, + component: tabTypeDefinition.makeComponent(data), + icon: tabTypeDefinition.icon, + title: tabTypeDefinition.makeTitle(data), + isTemp: isTemporary, + } as StudioWindowTabItem; + } + + return tab; + }); + } + + return [ + ...prevTabs, + { + component: tabTypeDefinition.makeComponent(data), + icon: tabTypeDefinition.icon, + identifier, + isTemp: isTemporary, + key: newTabKey, + title: tabTypeDefinition.makeTitle(data), + } satisfies StudioWindowTabItem, + ]; + }); + }, + [setSelectedTabKey] + ); + + /** + * Updates the status properties (e.g. `isDirty`, `isTemp`) of an existing studio tab. + */ + const updateStudioTabStatus = useCallback< + StudioContextValue["updateStudioTabStatus"] + >((identifierParam, status) => { + setTabs((prev) => { + const identifier = + typeof identifierParam === "string" + ? identifierParam + : StudioTabDefinitionList[identifierParam.type]?.makeIdentifier( + identifierParam + ); + + if (!identifier) { + console.error("Unable to resolve tab identifier", identifierParam); + return prev; + } + + return prev.map((tab) => + tab.identifier === identifier ? { ...tab, ...status } : tab + ); + }); + }, []); + + // Open initial table from URL param after schemas load (only once) + useEffect((): void => { + if ( + hasOpenedInitialTable.current || + !initialTable || + !schemas || + loadingSchema + ) { + return; + } + + // Check if the table exists in the main schema + const mainSchema = schemas[DEFAULT_SCHEMA_NAME]; + const tableExists = mainSchema?.some( + (i) => i.type === "table" && i.name === initialTable + ); + if (tableExists) { + openStudioTab({ + schemaName: DEFAULT_SCHEMA_NAME, + tableName: initialTable, + type: "table", + }); + hasOpenedInitialTable.current = true; + return; + } + + console.warn( + `Table "${initialTable}" not found in schema "${DEFAULT_SCHEMA_NAME}"` + ); + hasOpenedInitialTable.current = true; + }, [initialTable, loadingSchema, openStudioTab, schemas]); + + /** + * Replaces an existing studio tab with a new one built from the provided + * `StudioTabDefinitionMetadata`. + * + * The target tab is located by its string `identifier`. If no matching tab + * is found, the tab list is unchanged. + */ + const replaceStudioTab = useCallback( + ( + identifier: string, + data: StudioTabDefinitionMetadata, + options?: { withoutReplaceComponent?: boolean; isTemp?: boolean } + ) => { + setTabs((prev) => { + const targetTab = prev.find((tab) => tab.identifier === identifier); + if (!targetTab) { + return prev; + } + + // Getting tab setting + // TODO: Remove assertion once tab definitions are registered + const tabTypeDefinition = StudioTabDefinitionList[ + data.type + ] as TabDefinition; + const newIdentifier = tabTypeDefinition.makeIdentifier(data); + const newKey = window.crypto.randomUUID(); + + const newTabValue = options?.withoutReplaceComponent + ? { + component: targetTab.component, + icon: tabTypeDefinition.icon, + identifier: newIdentifier, + isTemp: options?.isTemp, + key: targetTab.key, + title: tabTypeDefinition.makeTitle(data), + } + : { + component: tabTypeDefinition.makeComponent(data), + icon: tabTypeDefinition.icon, + identifier: newIdentifier, + isTemp: options?.isTemp, + key: newKey, + title: tabTypeDefinition.makeTitle(data), + }; + + if (!options?.withoutReplaceComponent) { + setSelectedTabKey(newKey); + } + + return prev.map((tab) => { + if (tab === targetTab) { + return newTabValue; + } + + return tab; + }); + }); + }, + [setSelectedTabKey] + ); + + /** + * Prevent the user from accidentally leaving the page if there + * are any tabs with unsaved changes. + */ + const hasDirtyState = tabs.some((tab) => tab.isDirty); + + useLeaveGuard({ + enabled: hasDirtyState, + onBeforeLeave: () => + "You have unsaved changes. Are you sure you want to leave?", + }); + + const contextValues = useMemo( + () => ({ + closeStudioTab, + driver, + loadingSchema, + openStudioTab, + refreshSchema, + replaceStudioTab, + resource, + schemas, + selectedTabKey, + setSelectedTabKey, + setStudioTabs: setTabs, + tabs, + updateStudioTabStatus, + }), + [ + closeStudioTab, + driver, + loadingSchema, + openStudioTab, + refreshSchema, + replaceStudioTab, + resource, + schemas, + selectedTabKey, + setSelectedTabKey, + setTabs, + tabs, + updateStudioTabStatus, + ] + ); + + return ( + + + +
+ +
+
+
+
+ ); +} diff --git a/packages/local-explorer-ui/src/hooks/leave-guard.ts b/packages/local-explorer-ui/src/hooks/leave-guard.ts new file mode 100644 index 000000000000..f92448cfec8b --- /dev/null +++ b/packages/local-explorer-ui/src/hooks/leave-guard.ts @@ -0,0 +1,72 @@ +import { useCallback, useEffect } from "react"; + +type LeaveEvent = "navigation" | "unload"; + +interface UseLeaveGuardOptions { + /** + * List of reactive dependencies used inside `onBeforeLeave`. + * Similar to a `useCallback` dependency array. + */ + dependencies?: React.DependencyList; + + /** + * Enable or disable the leave guard. When false, no blocking is applied. + */ + enabled: boolean; + + /** + * Optional fallback message when `onBeforeLeave` returns void. + */ + fallbackMessage?: string; + + /** + * Handle user attempting to leave. + * + * - Return a `string` to show a confirmation message. + * - Return `true` to block without a prompt. + * - Return `false` or nothing to allow the leave. + */ + onBeforeLeave: (event: LeaveEvent) => string | boolean | void; +} + +/** + * useLeaveGuard adds an unload guard to the current page. + * Useful for warning users before they leave a page with unsaved changes. + * + * Note: This simplified version only handles browser unload events. + * In-app navigation blocking requires integration with your router. + */ +export function useLeaveGuard({ + dependencies = [], + enabled, + fallbackMessage = "You have unsaved changes. Are you sure you want to leave?", + onBeforeLeave, +}: UseLeaveGuardOptions): void { + // eslint-disable-next-line react-hooks/exhaustive-deps + const handlerCallback = useCallback(onBeforeLeave, dependencies); + + // Block tab close or refresh + useEffect(() => { + const handleBeforeUnload = (e: BeforeUnloadEvent) => { + if (!enabled) { + return; + } + + const result = handlerCallback("unload"); + + if (typeof result === "string") { + e.preventDefault(); + e.returnValue = result; + return; + } + + if (result === true || result === undefined) { + e.preventDefault(); + e.returnValue = fallbackMessage; + } + }; + + window.addEventListener("beforeunload", handleBeforeUnload); + return () => window.removeEventListener("beforeunload", handleBeforeUnload); + }, [enabled, handlerCallback, fallbackMessage]); +} diff --git a/packages/local-explorer-ui/src/routes/d1/$databaseId.tsx b/packages/local-explorer-ui/src/routes/d1/$databaseId.tsx index 0769534faa07..3039efeef1ce 100644 --- a/packages/local-explorer-ui/src/routes/d1/$databaseId.tsx +++ b/packages/local-explorer-ui/src/routes/d1/$databaseId.tsx @@ -3,11 +3,14 @@ import { CaretUpDownIcon, CheckIcon, DatabaseIcon, + TableIcon, } from "@phosphor-icons/react"; import { createFileRoute, Link, useNavigate } from "@tanstack/react-router"; -import { useCallback } from "react"; +import { useCallback, useMemo } from "react"; import { Breadcrumbs } from "../../components/Breadcrumbs"; +import { Studio } from "../../components/studio"; import { LocalD1Driver } from "../../drivers/d1"; +import type { StudioResource } from "../../types/studio"; export const Route = createFileRoute("/d1/$databaseId")({ component: DatabaseView, @@ -31,6 +34,20 @@ export const Route = createFileRoute("/d1/$databaseId")({ function DatabaseView(): JSX.Element { const params = Route.useParams(); + const searchParams = Route.useSearch(); + + const driver = useMemo( + () => new LocalD1Driver(params.databaseId), + [params.databaseId] + ); + + const resource = useMemo( + () => ({ + databaseId: params.databaseId, + type: "d1", + }), + [params.databaseId] + ); return (
@@ -52,7 +69,12 @@ function DatabaseView(): JSX.Element { />
- {/* TODO: Add `` component */} +
); @@ -107,18 +129,23 @@ function TableSelect(): JSX.Element { > - {data.tables.map((table) => ( - - - - - {table.label} - - ))} + {data.tables.map((table) => { + const Icon = + searchParams.table === table.value ? CheckIcon : TableIcon; + + return ( + + + + + {table.label} + + ); + })} diff --git a/packages/miniflare/CHANGELOG.md b/packages/miniflare/CHANGELOG.md index 4d037c2b514d..6004179e5f11 100644 --- a/packages/miniflare/CHANGELOG.md +++ b/packages/miniflare/CHANGELOG.md @@ -1,5 +1,54 @@ # miniflare +## 4.20260217.0 + +### Minor Changes + +- [#12546](https://github.com/cloudflare/workers-sdk/pull/12546) [`43c462a`](https://github.com/cloudflare/workers-sdk/commit/43c462af9684980b8332a8e3a31a9bd9f08777f5) Thanks [@emily-shen](https://github.com/emily-shen)! - Local explorer: add endpoints to list DO namespaces and objects + + This is part of an experimental, WIP feature. + +### Patch Changes + +- [#12543](https://github.com/cloudflare/workers-sdk/pull/12543) [`5a868a0`](https://github.com/cloudflare/workers-sdk/commit/5a868a0c0b305548e4ad60a50f20ab4cd8900741) Thanks [@G4brym](https://github.com/G4brym)! - Fix AI Search binding failing in local dev + + Using AI Search bindings with `wrangler dev` would fail with "RPC stub points at a non-serializable type". AI Search bindings now work correctly in local development. + +- [#12552](https://github.com/cloudflare/workers-sdk/pull/12552) [`c58e81b`](https://github.com/cloudflare/workers-sdk/commit/c58e81b85e1ff1285ac024508739c997ec04984e) Thanks [@dependabot](https://github.com/apps/dependabot)! - Update dependencies of "miniflare", "wrangler" + + The following dependency versions have been updated: + + | Dependency | From | To | + | ---------- | ------------ | ------------ | + | workerd | 1.20260212.0 | 1.20260213.0 | + +- [#12568](https://github.com/cloudflare/workers-sdk/pull/12568) [`33a9a8f`](https://github.com/cloudflare/workers-sdk/commit/33a9a8f97e61c45507865eb8c5c9cace7ab27e64) Thanks [@dependabot](https://github.com/apps/dependabot)! - Update dependencies of "miniflare", "wrangler" + + The following dependency versions have been updated: + + | Dependency | From | To | + | ---------- | ------------ | ------------ | + | workerd | 1.20260213.0 | 1.20260214.0 | + +- [#12576](https://github.com/cloudflare/workers-sdk/pull/12576) [`8077c14`](https://github.com/cloudflare/workers-sdk/commit/8077c14a84e4b50015d356349a330a970693533f) Thanks [@dependabot](https://github.com/apps/dependabot)! - Update dependencies of "miniflare", "wrangler" + + The following dependency versions have been updated: + + | Dependency | From | To | + | ---------- | ------------ | ------------ | + | workerd | 1.20260214.0 | 1.20260217.0 | + +- [#12466](https://github.com/cloudflare/workers-sdk/pull/12466) [`caf9b11`](https://github.com/cloudflare/workers-sdk/commit/caf9b114391d7708b38e8d37bca6dae6f2b4927e) Thanks [@petebacondarwin](https://github.com/petebacondarwin)! - Add `MINIFLARE_CACHE_DIR` environment variable and smart cache directory detection + + Miniflare now intelligently detects where to store its cf.json cache file: + + 1. Use `MINIFLARE_CACHE_DIR` env var if set + 2. Use existing cache directory if found (`node_modules/.mf` or `.wrangler/cache`) + 3. Create cache in `node_modules/.mf` if `node_modules` exists + 4. Otherwise use `.wrangler/cache` + + This improves compatibility with Yarn PnP, pnpm, and other package managers that don't use traditional `node_modules` directories, without requiring any configuration. + ## 4.20260212.0 ### Minor Changes diff --git a/packages/miniflare/package.json b/packages/miniflare/package.json index 8fcec3914fc0..3a55bd641a84 100644 --- a/packages/miniflare/package.json +++ b/packages/miniflare/package.json @@ -1,6 +1,6 @@ { "name": "miniflare", - "version": "4.20260212.0", + "version": "4.20260217.0", "description": "Fun, full-featured, fully-local simulator for Cloudflare Workers", "keywords": [ "cloudflare", @@ -50,7 +50,7 @@ "@cspotcode/source-map-support": "0.8.1", "sharp": "^0.34.5", "undici": "catalog:default", - "workerd": "1.20260214.0", + "workerd": "1.20260217.0", "ws": "catalog:default", "youch": "4.1.0-beta.10" }, diff --git a/packages/miniflare/src/index.ts b/packages/miniflare/src/index.ts index 1742d65f5b6f..8c5589b12076 100644 --- a/packages/miniflare/src/index.ts +++ b/packages/miniflare/src/index.ts @@ -127,6 +127,7 @@ import { } from "./shared/external-service"; import { isCompressedByCloudflareFL } from "./shared/mime-types"; import { + CacheHeaders, CoreBindings, CoreHeaders, LogLevel, @@ -2635,6 +2636,45 @@ export class Miniflare { return proxyClient.global .caches as unknown as ReplaceWorkersTypes; } + /** + * Purges all entries from the cache. + * + * This is useful during development when cached assets need to be cleared + * without restarting the Miniflare instance. + * + * @param cacheName - Optional name of specific cache to purge. If not provided, + * purges the default cache. + * @returns A promise that resolves with the number of entries purged. + */ + async purgeCache(cacheName?: string): Promise { + await this.ready; + + const proxyClient = await this._getProxyClient(); + + // Get the cache service binding from proxy env. This is a Fetcher to + // the cache-entry worker which properly sets cf.miniflare.name before + // forwarding to the CacheObject Durable Object. + const cacheService = proxyClient.env[CoreBindings.SERVICE_CACHE] as Fetcher; + + // Build the request with the cache namespace header if specified + const headers: Record = {}; + if (cacheName !== undefined) { + headers[CacheHeaders.NAMESPACE] = cacheName; + } + + // Call the cache-entry worker's /purge-all endpoint + const response = await cacheService.fetch("http://localhost/purge-all", { + method: "DELETE", + headers, + }); + + if (!response.ok) { + throw new Error(`Failed to purge cache: ${response.statusText}`); + } + + const result = (await response.json()) as { deleted: number }; + return result.deleted; + } getD1Database(bindingName: string, workerName?: string): Promise { return this.#getProxy(D1_PLUGIN_NAME, bindingName, workerName); } diff --git a/packages/miniflare/src/plugins/core/index.ts b/packages/miniflare/src/plugins/core/index.ts index 6fd57e0d236b..d02e91b67b6a 100644 --- a/packages/miniflare/src/plugins/core/index.ts +++ b/packages/miniflare/src/plugins/core/index.ts @@ -1019,6 +1019,11 @@ export function getGlobalServices({ }, // Add `proxyBindings` here, they'll be added to the `ProxyServer` `env` ...proxyBindings, + // Add cache service binding for purgeCache() API + { + name: CoreBindings.SERVICE_CACHE, + service: { name: getCacheServiceName(0) }, + }, ]; if (sharedOptions.unsafeLocalExplorer) { serviceEntryBindings.push({ diff --git a/packages/miniflare/src/workers/cache/cache.worker.ts b/packages/miniflare/src/workers/cache/cache.worker.ts index 202059f55e0c..608b2d75acb3 100644 --- a/packages/miniflare/src/workers/cache/cache.worker.ts +++ b/packages/miniflare/src/workers/cache/cache.worker.ts @@ -3,6 +3,7 @@ import { Buffer } from "node:buffer"; import CachePolicy from "http-cache-semantics"; import { DeferredPromise, + DELETE, GET, InclusiveRange, KeyValueStorage, @@ -391,4 +392,10 @@ export class CacheObject extends MiniflareDurableObject { if (!deleted) throw new PurgeFailure(); return new Response(null); }; + + @DELETE("/purge-all") + purgeAll: CacheRouteHandler = async () => { + const deletedCount = this.storage.deleteAll(); + return Response.json({ deleted: deletedCount }); + }; } diff --git a/packages/miniflare/src/workers/core/constants.ts b/packages/miniflare/src/workers/core/constants.ts index 4f4a8ff8180c..cb2d057c44ab 100644 --- a/packages/miniflare/src/workers/core/constants.ts +++ b/packages/miniflare/src/workers/core/constants.ts @@ -47,6 +47,7 @@ export const CoreBindings = { SERVICE_LOCAL_EXPLORER: "MINIFLARE_LOCAL_EXPLORER", EXPLORER_DISK: "MINIFLARE_EXPLORER_DISK", JSON_LOCAL_EXPLORER_BINDING_MAP: "LOCAL_EXPLORER_BINDING_MAP", + SERVICE_CACHE: "MINIFLARE_CACHE", } as const; export const ProxyOps = { diff --git a/packages/miniflare/src/workers/shared/keyvalue.worker.ts b/packages/miniflare/src/workers/shared/keyvalue.worker.ts index 32835f56f8c0..a25231ff4129 100644 --- a/packages/miniflare/src/workers/shared/keyvalue.worker.ts +++ b/packages/miniflare/src/workers/shared/keyvalue.worker.ts @@ -8,7 +8,7 @@ import { import { base64Decode, base64Encode } from "./data"; import { MiniflareDurableObject } from "./object.worker"; import { InclusiveRange } from "./range"; -import { drain, get, TypedSql } from "./sql.worker"; +import { all, drain, get, TypedSql } from "./sql.worker"; import { Timers } from "./timers.worker"; import { Awaitable } from "./types"; @@ -60,6 +60,7 @@ function sqlStmts(db: TypedSql) { ); return { + db, getByKey: db.prepare<[key_1: string], Row>( "SELECT key, blob_id, expiration, metadata FROM _mf_entries WHERE key = ?1" ), @@ -78,6 +79,9 @@ function sqlStmts(db: TypedSql) { // `expiration` may be `NULL`, but `NULL < ...` should be falsy "DELETE FROM _mf_entries WHERE expiration < :now RETURNING blob_id" ), + deleteAll: db.prepare<[], Pick>( + "DELETE FROM _mf_entries RETURNING blob_id" + ), list: db.stmt< { now: number; @@ -230,6 +234,18 @@ export class KeyValueStorage { return !this.#hasExpired(row); } + deleteAll(): number { + // Get all blob IDs and delete all entries in one statement + const rows = all(this.#stmts.deleteAll()); + + // Garbage collect all blobs in the background + for (const { blob_id } of rows) { + this.#backgroundDelete(blob_id); + } + + return rows.length; + } + async list(opts: KeyEntriesQuery): Promise> { // Find non-expired entries matching query after cursor const now = this.#timers.now(); diff --git a/packages/miniflare/test/plugins/cache/index.spec.ts b/packages/miniflare/test/plugins/cache/index.spec.ts index 58a5be516ed6..4b5691bdff80 100644 --- a/packages/miniflare/test/plugins/cache/index.spec.ts +++ b/packages/miniflare/test/plugins/cache/index.spec.ts @@ -527,3 +527,65 @@ test("default and named caches are disjoint", async () => { expect(deleted1).toBe(true); expect(deleted2).toBe(true); }); + +test("purgeCache clears all default cache entries", async () => { + const cache = ctx.caches.default; + const headers = { "Cache-Control": "max-age=3600" }; + + // Add multiple items to cache with unique keys for this test + await cache.put( + "http://localhost/purge-test-key1", + new Response("body1", { headers }) + ); + await cache.put( + "http://localhost/purge-test-key2", + new Response("body2", { headers }) + ); + await cache.put( + "http://localhost/purge-test-key3", + new Response("body3", { headers }) + ); + + // Verify items are cached + expect(await cache.match("http://localhost/purge-test-key1")).toBeDefined(); + expect(await cache.match("http://localhost/purge-test-key2")).toBeDefined(); + expect(await cache.match("http://localhost/purge-test-key3")).toBeDefined(); + + // Purge cache - there may be entries from previous tests as well + const result = await ctx.mf.purgeCache(); + expect(result).toBeGreaterThanOrEqual(3); + + // Verify our test entries are gone + expect(await cache.match("http://localhost/purge-test-key1")).toBeUndefined(); + expect(await cache.match("http://localhost/purge-test-key2")).toBeUndefined(); + expect(await cache.match("http://localhost/purge-test-key3")).toBeUndefined(); +}); + +test("purgeCache clears specific named cache", async () => { + const defaultCache = ctx.caches.default; + const namedCache = await ctx.caches.open("my-cache"); + const headers = { "Cache-Control": "max-age=3600" }; + + await defaultCache.put( + "http://localhost/default", + new Response("default", { headers }) + ); + await namedCache.put( + "http://localhost/named", + new Response("named", { headers }) + ); + + // Purge only the named cache + await ctx.mf.purgeCache("my-cache"); + + // Default cache should be intact + expect(await defaultCache.match("http://localhost/default")).toBeDefined(); + // Named cache should be cleared + expect(await namedCache.match("http://localhost/named")).toBeUndefined(); +}); + +test("purgeCache returns 0 when cache is already empty", async () => { + // Use a unique named cache that hasn't been used by other tests + const result = await ctx.mf.purgeCache("empty-test-cache"); + expect(result).toBe(0); +}); diff --git a/packages/pages-shared/CHANGELOG.md b/packages/pages-shared/CHANGELOG.md index 97d7b3720213..f208a50385be 100644 --- a/packages/pages-shared/CHANGELOG.md +++ b/packages/pages-shared/CHANGELOG.md @@ -1,5 +1,12 @@ # @cloudflare/pages-shared +## 0.13.108 + +### Patch Changes + +- Updated dependencies [[`5a868a0`](https://github.com/cloudflare/workers-sdk/commit/5a868a0c0b305548e4ad60a50f20ab4cd8900741), [`c58e81b`](https://github.com/cloudflare/workers-sdk/commit/c58e81b85e1ff1285ac024508739c997ec04984e), [`33a9a8f`](https://github.com/cloudflare/workers-sdk/commit/33a9a8f97e61c45507865eb8c5c9cace7ab27e64), [`8077c14`](https://github.com/cloudflare/workers-sdk/commit/8077c14a84e4b50015d356349a330a970693533f), [`caf9b11`](https://github.com/cloudflare/workers-sdk/commit/caf9b114391d7708b38e8d37bca6dae6f2b4927e), [`43c462a`](https://github.com/cloudflare/workers-sdk/commit/43c462af9684980b8332a8e3a31a9bd9f08777f5)]: + - miniflare@4.20260217.0 + ## 0.13.107 ### Patch Changes diff --git a/packages/pages-shared/package.json b/packages/pages-shared/package.json index 2d5202fc3151..cdb6402ad2fb 100644 --- a/packages/pages-shared/package.json +++ b/packages/pages-shared/package.json @@ -1,6 +1,6 @@ { "name": "@cloudflare/pages-shared", - "version": "0.13.107", + "version": "0.13.108", "repository": { "type": "git", "url": "https://github.com/cloudflare/workers-sdk.git", diff --git a/packages/unenv-preset/CHANGELOG.md b/packages/unenv-preset/CHANGELOG.md index 1fb6902eb8f9..4a417bb55604 100644 --- a/packages/unenv-preset/CHANGELOG.md +++ b/packages/unenv-preset/CHANGELOG.md @@ -1,5 +1,21 @@ # @cloudflare/unenv-preset +## 2.13.0 + +### Minor Changes + +- [#12573](https://github.com/cloudflare/workers-sdk/pull/12573) [`9a565d5`](https://github.com/cloudflare/workers-sdk/commit/9a565d526224ac510a8d581e32db98545c1b3368) Thanks [@petebacondarwin](https://github.com/petebacondarwin)! - Add support for native `node:child_process` module from workerd when the `enable_nodejs_child_process_module` compatibility flag is enabled. + + This feature is currently experimental and requires both the `enable_nodejs_child_process_module` and `experimental` compatibility flags to be set. + +- [#12023](https://github.com/cloudflare/workers-sdk/pull/12023) [`7f18183`](https://github.com/cloudflare/workers-sdk/commit/7f181839513a1cac441e0956a59130ba1f4ef6d4) Thanks [@petebacondarwin](https://github.com/petebacondarwin)! - Add support for native `node:tty` module from workerd when the `enable_nodejs_tty_module` compatibility flag is enabled. + + This feature is currently experimental and requires `nodejs_compat`, `experimental`, and `enable_nodejs_tty_module` compatibility flags to be set. + +- [#12363](https://github.com/cloudflare/workers-sdk/pull/12363) [`39491f9`](https://github.com/cloudflare/workers-sdk/commit/39491f9d92153f679fd2f9e81a5d58122946a0af) Thanks [@petebacondarwin](https://github.com/petebacondarwin)! - Add support for the native `node:v8` module from workerd when the `enable_nodejs_v8_module` and `experimental` compatibility flags are enabled + + This feature is currently experimental and requires `nodejs_compat`, `experimental`, and `enable_nodejs_v8_module` compatibility flags to be set. + ## 2.12.1 ### Patch Changes diff --git a/packages/unenv-preset/package.json b/packages/unenv-preset/package.json index 5a9cadc3ff1a..7f1f211aaf2c 100644 --- a/packages/unenv-preset/package.json +++ b/packages/unenv-preset/package.json @@ -1,6 +1,6 @@ { "name": "@cloudflare/unenv-preset", - "version": "2.12.1", + "version": "2.13.0", "description": "cloudflare preset for unenv", "keywords": [ "cloudflare", diff --git a/packages/vite-plugin-cloudflare/CHANGELOG.md b/packages/vite-plugin-cloudflare/CHANGELOG.md index 7569edb6aa10..0f6a40f7d002 100644 --- a/packages/vite-plugin-cloudflare/CHANGELOG.md +++ b/packages/vite-plugin-cloudflare/CHANGELOG.md @@ -1,5 +1,14 @@ # @cloudflare/vite-plugin +## 1.25.1 + +### Patch Changes + +- Updated dependencies [[`5a868a0`](https://github.com/cloudflare/workers-sdk/commit/5a868a0c0b305548e4ad60a50f20ab4cd8900741), [`caf9b11`](https://github.com/cloudflare/workers-sdk/commit/caf9b114391d7708b38e8d37bca6dae6f2b4927e), [`c58e81b`](https://github.com/cloudflare/workers-sdk/commit/c58e81b85e1ff1285ac024508739c997ec04984e), [`33a9a8f`](https://github.com/cloudflare/workers-sdk/commit/33a9a8f97e61c45507865eb8c5c9cace7ab27e64), [`8077c14`](https://github.com/cloudflare/workers-sdk/commit/8077c14a84e4b50015d356349a330a970693533f), [`caf9b11`](https://github.com/cloudflare/workers-sdk/commit/caf9b114391d7708b38e8d37bca6dae6f2b4927e), [`7d2355e`](https://github.com/cloudflare/workers-sdk/commit/7d2355ea146365391f3cd8b0e5a80057e6013151), [`936187d`](https://github.com/cloudflare/workers-sdk/commit/936187d4be8686a7849278ff57f7f927062e2cce), [`7ea69af`](https://github.com/cloudflare/workers-sdk/commit/7ea69af67f0427c621eb8fa0b31ebaa4c6537870), [`5cc7158`](https://github.com/cloudflare/workers-sdk/commit/5cc7158b39a247e3c33f158327a1cee99dd5e719), [`caf9b11`](https://github.com/cloudflare/workers-sdk/commit/caf9b114391d7708b38e8d37bca6dae6f2b4927e), [`9a565d5`](https://github.com/cloudflare/workers-sdk/commit/9a565d526224ac510a8d581e32db98545c1b3368), [`7f18183`](https://github.com/cloudflare/workers-sdk/commit/7f181839513a1cac441e0956a59130ba1f4ef6d4), [`39491f9`](https://github.com/cloudflare/workers-sdk/commit/39491f9d92153f679fd2f9e81a5d58122946a0af), [`43c462a`](https://github.com/cloudflare/workers-sdk/commit/43c462af9684980b8332a8e3a31a9bd9f08777f5), [`c4c86f8`](https://github.com/cloudflare/workers-sdk/commit/c4c86f813d9ce406d8b36da7148665b805d0676b), [`7d2355e`](https://github.com/cloudflare/workers-sdk/commit/7d2355ea146365391f3cd8b0e5a80057e6013151), [`c9d0f9d`](https://github.com/cloudflare/workers-sdk/commit/c9d0f9d6d5f2f3d322ac6ba9ccb0d05a5c96bbe6), [`5cc7158`](https://github.com/cloudflare/workers-sdk/commit/5cc7158b39a247e3c33f158327a1cee99dd5e719), [`5cc7158`](https://github.com/cloudflare/workers-sdk/commit/5cc7158b39a247e3c33f158327a1cee99dd5e719), [`c9d0f9d`](https://github.com/cloudflare/workers-sdk/commit/c9d0f9d6d5f2f3d322ac6ba9ccb0d05a5c96bbe6)]: + - miniflare@4.20260217.0 + - wrangler@4.66.0 + - @cloudflare/unenv-preset@2.13.0 + ## 1.25.0 ### Minor Changes diff --git a/packages/vite-plugin-cloudflare/package.json b/packages/vite-plugin-cloudflare/package.json index e958c8fef454..61985a692e64 100644 --- a/packages/vite-plugin-cloudflare/package.json +++ b/packages/vite-plugin-cloudflare/package.json @@ -1,6 +1,6 @@ { "name": "@cloudflare/vite-plugin", - "version": "1.25.0", + "version": "1.25.1", "description": "Cloudflare plugin for Vite", "keywords": [ "cloudflare", diff --git a/packages/vitest-pool-workers/CHANGELOG.md b/packages/vitest-pool-workers/CHANGELOG.md index 30e49a2c31db..b76649aff2f7 100644 --- a/packages/vitest-pool-workers/CHANGELOG.md +++ b/packages/vitest-pool-workers/CHANGELOG.md @@ -1,5 +1,13 @@ # @cloudflare/vitest-pool-workers +## 0.12.13 + +### Patch Changes + +- Updated dependencies [[`5a868a0`](https://github.com/cloudflare/workers-sdk/commit/5a868a0c0b305548e4ad60a50f20ab4cd8900741), [`caf9b11`](https://github.com/cloudflare/workers-sdk/commit/caf9b114391d7708b38e8d37bca6dae6f2b4927e), [`c58e81b`](https://github.com/cloudflare/workers-sdk/commit/c58e81b85e1ff1285ac024508739c997ec04984e), [`33a9a8f`](https://github.com/cloudflare/workers-sdk/commit/33a9a8f97e61c45507865eb8c5c9cace7ab27e64), [`8077c14`](https://github.com/cloudflare/workers-sdk/commit/8077c14a84e4b50015d356349a330a970693533f), [`caf9b11`](https://github.com/cloudflare/workers-sdk/commit/caf9b114391d7708b38e8d37bca6dae6f2b4927e), [`7d2355e`](https://github.com/cloudflare/workers-sdk/commit/7d2355ea146365391f3cd8b0e5a80057e6013151), [`936187d`](https://github.com/cloudflare/workers-sdk/commit/936187d4be8686a7849278ff57f7f927062e2cce), [`7ea69af`](https://github.com/cloudflare/workers-sdk/commit/7ea69af67f0427c621eb8fa0b31ebaa4c6537870), [`5cc7158`](https://github.com/cloudflare/workers-sdk/commit/5cc7158b39a247e3c33f158327a1cee99dd5e719), [`caf9b11`](https://github.com/cloudflare/workers-sdk/commit/caf9b114391d7708b38e8d37bca6dae6f2b4927e), [`43c462a`](https://github.com/cloudflare/workers-sdk/commit/43c462af9684980b8332a8e3a31a9bd9f08777f5), [`c4c86f8`](https://github.com/cloudflare/workers-sdk/commit/c4c86f813d9ce406d8b36da7148665b805d0676b), [`7d2355e`](https://github.com/cloudflare/workers-sdk/commit/7d2355ea146365391f3cd8b0e5a80057e6013151), [`c9d0f9d`](https://github.com/cloudflare/workers-sdk/commit/c9d0f9d6d5f2f3d322ac6ba9ccb0d05a5c96bbe6), [`5cc7158`](https://github.com/cloudflare/workers-sdk/commit/5cc7158b39a247e3c33f158327a1cee99dd5e719), [`5cc7158`](https://github.com/cloudflare/workers-sdk/commit/5cc7158b39a247e3c33f158327a1cee99dd5e719), [`c9d0f9d`](https://github.com/cloudflare/workers-sdk/commit/c9d0f9d6d5f2f3d322ac6ba9ccb0d05a5c96bbe6)]: + - miniflare@4.20260217.0 + - wrangler@4.66.0 + ## 0.12.12 ### Patch Changes diff --git a/packages/vitest-pool-workers/package.json b/packages/vitest-pool-workers/package.json index c48498685716..2cf8f2635f4f 100644 --- a/packages/vitest-pool-workers/package.json +++ b/packages/vitest-pool-workers/package.json @@ -1,6 +1,6 @@ { "name": "@cloudflare/vitest-pool-workers", - "version": "0.12.12", + "version": "0.12.13", "description": "Workers Vitest integration for writing Vitest unit and integration tests that run inside the Workers runtime", "keywords": [ "cloudflare", diff --git a/packages/workers-utils/CHANGELOG.md b/packages/workers-utils/CHANGELOG.md index 91365df6114d..a5f05a96d7e6 100644 --- a/packages/workers-utils/CHANGELOG.md +++ b/packages/workers-utils/CHANGELOG.md @@ -1,5 +1,20 @@ # @cloudflare/workers-utils +## 0.11.0 + +### Minor Changes + +- [#12466](https://github.com/cloudflare/workers-sdk/pull/12466) [`caf9b11`](https://github.com/cloudflare/workers-sdk/commit/caf9b114391d7708b38e8d37bca6dae6f2b4927e) Thanks [@petebacondarwin](https://github.com/petebacondarwin)! - Add `WRANGLER_CACHE_DIR` environment variable and smart cache directory detection + + Wrangler now intelligently detects where to store cache files: + + 1. Use `WRANGLER_CACHE_DIR` env var if set + 2. Use existing cache directory if found (`node_modules/.cache/wrangler` or `.wrangler/cache`) + 3. Create cache in `node_modules/.cache/wrangler` if `node_modules` exists + 4. Otherwise use `.wrangler/cache` + + This improves compatibility with Yarn PnP, pnpm, and other package managers that don't use traditional `node_modules` directories, without requiring any configuration. + ## 0.10.0 ### Minor Changes diff --git a/packages/workers-utils/package.json b/packages/workers-utils/package.json index 7e01bf9a4839..cddd8e342d07 100644 --- a/packages/workers-utils/package.json +++ b/packages/workers-utils/package.json @@ -1,6 +1,6 @@ { "name": "@cloudflare/workers-utils", - "version": "0.10.0", + "version": "0.11.0", "description": "Utility package for common Worker operations", "homepage": "https://github.com/cloudflare/workers-sdk#readme", "bugs": { diff --git a/packages/wrangler/CHANGELOG.md b/packages/wrangler/CHANGELOG.md index c46ae08c31d1..6e2a36fa6cdd 100644 --- a/packages/wrangler/CHANGELOG.md +++ b/packages/wrangler/CHANGELOG.md @@ -1,5 +1,116 @@ # wrangler +## 4.66.0 + +### Minor Changes + +- [#12466](https://github.com/cloudflare/workers-sdk/pull/12466) [`caf9b11`](https://github.com/cloudflare/workers-sdk/commit/caf9b114391d7708b38e8d37bca6dae6f2b4927e) Thanks [@petebacondarwin](https://github.com/petebacondarwin)! - Add `WRANGLER_CACHE_DIR` environment variable and smart cache directory detection + + Wrangler now intelligently detects where to store cache files: + + 1. Use `WRANGLER_CACHE_DIR` env var if set + 2. Use existing cache directory if found (`node_modules/.cache/wrangler` or `.wrangler/cache`) + 3. Create cache in `node_modules/.cache/wrangler` if `node_modules` exists + 4. Otherwise use `.wrangler/cache` + + This improves compatibility with Yarn PnP, pnpm, and other package managers that don't use traditional `node_modules` directories, without requiring any configuration. + +- [#12572](https://github.com/cloudflare/workers-sdk/pull/12572) [`936187d`](https://github.com/cloudflare/workers-sdk/commit/936187d4be8686a7849278ff57f7f927062e2cce) Thanks [@dario-piotrowicz](https://github.com/dario-piotrowicz)! - Ensure the `nodejs_compat` flag is always applied in autoconfig + + Previously, the autoconfig feature relied on individual framework configurations to specify Node.js compatibility flags, some could set `nodejs_compat` while others `nodejs_als`. + + Now instead `nodejs_compat` is always included as a compatibility flag, this is generally beneficial and the user can always remove the flag afterwards if they want to. + +- [#12560](https://github.com/cloudflare/workers-sdk/pull/12560) [`c4c86f8`](https://github.com/cloudflare/workers-sdk/commit/c4c86f813d9ce406d8b36da7148665b805d0676b) Thanks [@taylorlee](https://github.com/taylorlee)! - Support `--tag` and `--message` flags on `wrangler deploy` + + They have the same behavior that they do as during `wrangler versions upload`, as both + are set on the version. + + The message is also reused for the deployment as well, with the same behavior as used + during `wrangler versions deploy`. + +### Patch Changes + +- [#12543](https://github.com/cloudflare/workers-sdk/pull/12543) [`5a868a0`](https://github.com/cloudflare/workers-sdk/commit/5a868a0c0b305548e4ad60a50f20ab4cd8900741) Thanks [@G4brym](https://github.com/G4brym)! - Fix AI Search binding failing in local dev + + Using AI Search bindings with `wrangler dev` would fail with "RPC stub points at a non-serializable type". AI Search bindings now work correctly in local development. + +- [#12552](https://github.com/cloudflare/workers-sdk/pull/12552) [`c58e81b`](https://github.com/cloudflare/workers-sdk/commit/c58e81b85e1ff1285ac024508739c997ec04984e) Thanks [@dependabot](https://github.com/apps/dependabot)! - Update dependencies of "miniflare", "wrangler" + + The following dependency versions have been updated: + + | Dependency | From | To | + | ---------- | ------------ | ------------ | + | workerd | 1.20260212.0 | 1.20260213.0 | + +- [#12568](https://github.com/cloudflare/workers-sdk/pull/12568) [`33a9a8f`](https://github.com/cloudflare/workers-sdk/commit/33a9a8f97e61c45507865eb8c5c9cace7ab27e64) Thanks [@dependabot](https://github.com/apps/dependabot)! - Update dependencies of "miniflare", "wrangler" + + The following dependency versions have been updated: + + | Dependency | From | To | + | ---------- | ------------ | ------------ | + | workerd | 1.20260213.0 | 1.20260214.0 | + +- [#12576](https://github.com/cloudflare/workers-sdk/pull/12576) [`8077c14`](https://github.com/cloudflare/workers-sdk/commit/8077c14a84e4b50015d356349a330a970693533f) Thanks [@dependabot](https://github.com/apps/dependabot)! - Update dependencies of "miniflare", "wrangler" + + The following dependency versions have been updated: + + | Dependency | From | To | + | ---------- | ------------ | ------------ | + | workerd | 1.20260214.0 | 1.20260217.0 | + +- [#12466](https://github.com/cloudflare/workers-sdk/pull/12466) [`caf9b11`](https://github.com/cloudflare/workers-sdk/commit/caf9b114391d7708b38e8d37bca6dae6f2b4927e) Thanks [@petebacondarwin](https://github.com/petebacondarwin)! - fix: exclude `.wrangler` directory from Pages uploads + + The `.wrangler` directory contains local cache and state files that should never be deployed. This aligns Pages upload behavior with Workers Assets, which already excludes `.wrangler` via `.assetsignore`. + +- [#12556](https://github.com/cloudflare/workers-sdk/pull/12556) [`7d2355e`](https://github.com/cloudflare/workers-sdk/commit/7d2355ea146365391f3cd8b0e5a80057e6013151) Thanks [@ascorbic](https://github.com/ascorbic)! - Fix port availability check probing the wrong host when host changes + + `memoizeGetPort` correctly invalidated its cached port when called with a different host, but then still probed the original host for port availability. This could return a port that was free on the original host but already in use on the requested one, leading to bind failures at startup. + +- [#12562](https://github.com/cloudflare/workers-sdk/pull/12562) [`7ea69af`](https://github.com/cloudflare/workers-sdk/commit/7ea69af67f0427c621eb8fa0b31ebaa4c6537870) Thanks [@MattieTK](https://github.com/MattieTK)! - Support function-based Vite configs in autoconfig setup + + `wrangler setup` and `wrangler deploy --x-autoconfig` can now automatically add the Cloudflare Vite plugin to projects that use function-based `defineConfig()` patterns. Previously, autoconfig would fail with "Cannot modify Vite config: expected an object literal but found ArrowFunctionExpression" for configs like: + + ```ts + export default defineConfig(({ isSsrBuild }) => ({ + plugins: [reactRouter(), tsconfigPaths()], + })); + ``` + + This pattern is used by several official framework templates, including React Router's `node-postgres` and `node-custom-server` templates. The following `defineConfig()` patterns are now supported: + + - `defineConfig({ ... })` (object literal, already worked) + - `defineConfig(() => ({ ... }))` (arrow function with expression body) + - `defineConfig(({ isSsrBuild }) => ({ ... }))` (arrow function with destructured params) + - `defineConfig(() => { return { ... }; })` (arrow function with block body) + - `defineConfig(function() { return { ... }; })` (function expression) + +- [#12548](https://github.com/cloudflare/workers-sdk/pull/12548) [`5cc7158`](https://github.com/cloudflare/workers-sdk/commit/5cc7158b39a247e3c33f158327a1cee99dd5e719) Thanks [@dario-piotrowicz](https://github.com/dario-piotrowicz)! - Fix `.assetsignore` formatting when autoconfig creates a new file + + Previously, when `wrangler setup` or `wrangler deploy --x-autoconfig` created a new `.assetsignore` file via autoconfig, it would add unnecessary leading empty lines before the wrangler-specific entries. Empty separator lines should only be added when appending to an existing `.assetsignore` file. This fix ensures newly created `.assetsignore` files start cleanly without leading blank lines. + +- [#12556](https://github.com/cloudflare/workers-sdk/pull/12556) [`7d2355e`](https://github.com/cloudflare/workers-sdk/commit/7d2355ea146365391f3cd8b0e5a80057e6013151) Thanks [@ascorbic](https://github.com/ascorbic)! - Improve error message when port binding is blocked by a sandbox or security policy + + When running `wrangler dev` inside a restricted environment (such as an AI coding agent sandbox or locked-down container), the port availability check would fail with a raw `EPERM` error. This now provides a clear message explaining that a sandbox or security policy is blocking network access, rather than the generic permission error that previously pointed at the file system. + +- [#12545](https://github.com/cloudflare/workers-sdk/pull/12545) [`c9d0f9d`](https://github.com/cloudflare/workers-sdk/commit/c9d0f9d6d5f2f3d322ac6ba9ccb0d05a5c96bbe6) Thanks [@dario-piotrowicz](https://github.com/dario-piotrowicz)! - Improve framework detection when multiple frameworks are found + + When autoconfig detects multiple frameworks in a project, Wrangler now applies smarter logic to select the most appropriate one. Selecting the wrong one is acceptable locally where the user can change the detected framework, in CI an error is instead thrown. + +- [#12548](https://github.com/cloudflare/workers-sdk/pull/12548) [`5cc7158`](https://github.com/cloudflare/workers-sdk/commit/5cc7158b39a247e3c33f158327a1cee99dd5e719) Thanks [@dario-piotrowicz](https://github.com/dario-piotrowicz)! - Add trailing newline to generated `package.json` and `wrangler.jsonc` files + +- [#12548](https://github.com/cloudflare/workers-sdk/pull/12548) [`5cc7158`](https://github.com/cloudflare/workers-sdk/commit/5cc7158b39a247e3c33f158327a1cee99dd5e719) Thanks [@dario-piotrowicz](https://github.com/dario-piotrowicz)! - Fix `.gitignore` formatting when autoconfig creates a new file + + Previously, when `wrangler setup` or `wrangler deploy` created a new `.gitignore` file via autoconfig, it would add unnecessary leading empty lines before the wrangler-specific entries. Empty separator lines should only be added when appending to an existing `.gitignore` file. This fix ensures newly created `.gitignore` files start cleanly without leading blank lines. + +- [#12545](https://github.com/cloudflare/workers-sdk/pull/12545) [`c9d0f9d`](https://github.com/cloudflare/workers-sdk/commit/c9d0f9d6d5f2f3d322ac6ba9ccb0d05a5c96bbe6) Thanks [@dario-piotrowicz](https://github.com/dario-piotrowicz)! - Throw actionable error when autoconfig is run in the root of a workspace + + When running Wrangler commands that trigger auto-configuration (like `wrangler dev` or `wrangler deploy`) in the root directory of a monorepo workspace, a helpful error is now shown directing users to run the command in a specific project's directory instead. + +- Updated dependencies [[`5a868a0`](https://github.com/cloudflare/workers-sdk/commit/5a868a0c0b305548e4ad60a50f20ab4cd8900741), [`c58e81b`](https://github.com/cloudflare/workers-sdk/commit/c58e81b85e1ff1285ac024508739c997ec04984e), [`33a9a8f`](https://github.com/cloudflare/workers-sdk/commit/33a9a8f97e61c45507865eb8c5c9cace7ab27e64), [`8077c14`](https://github.com/cloudflare/workers-sdk/commit/8077c14a84e4b50015d356349a330a970693533f), [`caf9b11`](https://github.com/cloudflare/workers-sdk/commit/caf9b114391d7708b38e8d37bca6dae6f2b4927e), [`9a565d5`](https://github.com/cloudflare/workers-sdk/commit/9a565d526224ac510a8d581e32db98545c1b3368), [`7f18183`](https://github.com/cloudflare/workers-sdk/commit/7f181839513a1cac441e0956a59130ba1f4ef6d4), [`39491f9`](https://github.com/cloudflare/workers-sdk/commit/39491f9d92153f679fd2f9e81a5d58122946a0af), [`43c462a`](https://github.com/cloudflare/workers-sdk/commit/43c462af9684980b8332a8e3a31a9bd9f08777f5)]: + - miniflare@4.20260217.0 + - @cloudflare/unenv-preset@2.13.0 + ## 4.65.0 ### Minor Changes diff --git a/packages/wrangler/package.json b/packages/wrangler/package.json index 6d913d4d6bdd..a974543045f8 100644 --- a/packages/wrangler/package.json +++ b/packages/wrangler/package.json @@ -1,6 +1,6 @@ { "name": "wrangler", - "version": "4.65.0", + "version": "4.66.0", "description": "Command-line interface for all things Cloudflare Workers", "keywords": [ "wrangler", @@ -73,7 +73,7 @@ "miniflare": "workspace:*", "path-to-regexp": "6.3.0", "unenv": "2.0.0-rc.24", - "workerd": "1.20260214.0" + "workerd": "1.20260217.0" }, "devDependencies": { "@aws-sdk/client-s3": "^3.721.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2758780c8859..34626df02752 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10,8 +10,8 @@ catalogs: specifier: ^0.10.11 version: 0.10.15 '@cloudflare/workers-types': - specifier: ^4.20260214.0 - version: 4.20260214.0 + specifier: ^4.20260217.0 + version: 4.20260217.0 '@typescript-eslint/eslint-plugin': specifier: ^8.35.1 version: 8.46.3 @@ -169,7 +169,7 @@ importers: version: link:../../packages/workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 typescript: specifier: catalog:default version: 5.8.3 @@ -217,7 +217,7 @@ importers: version: link:../../packages/workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 ts-dedent: specifier: ^2.2.0 version: 2.2.0 @@ -238,7 +238,7 @@ importers: version: link:../../packages/workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 typescript: specifier: catalog:default version: 5.8.3 @@ -262,7 +262,7 @@ importers: version: link:../../packages/workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 typescript: specifier: catalog:default version: 5.8.3 @@ -289,7 +289,7 @@ importers: version: link:../../packages/workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 typescript: specifier: catalog:default version: 5.8.3 @@ -331,7 +331,7 @@ importers: version: link:../../packages/workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 undici: specifier: catalog:default version: 7.18.2 @@ -346,7 +346,7 @@ importers: devDependencies: '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 '@types/mimetext': specifier: ^2.0.4 version: 2.0.4 @@ -391,7 +391,7 @@ importers: version: link:../../packages/workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 '@types/jest-image-snapshot': specifier: ^6.4.0 version: 6.4.0 @@ -421,7 +421,7 @@ importers: version: link:../../packages/workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 miniflare: specifier: workspace:* version: link:../../packages/miniflare @@ -497,7 +497,7 @@ importers: version: link:../../packages/workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 '@types/node': specifier: ^20.19.9 version: 20.19.9 @@ -521,7 +521,7 @@ importers: version: link:../../packages/workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 '@types/is-even': specifier: ^1.0.2 version: 1.0.2 @@ -564,7 +564,7 @@ importers: version: link:../../packages/workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 typescript: specifier: catalog:default version: 5.8.3 @@ -595,7 +595,7 @@ importers: version: link:../../packages/workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 '@types/node': specifier: ^20.19.9 version: 20.19.9 @@ -628,7 +628,7 @@ importers: version: link:../../packages/workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 undici: specifier: catalog:default version: 7.18.2 @@ -649,7 +649,7 @@ importers: version: link:../../packages/workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 '@types/debug': specifier: 4.1.12 version: 4.1.12 @@ -685,7 +685,7 @@ importers: version: link:../../packages/workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 typescript: specifier: catalog:default version: 5.8.3 @@ -709,7 +709,7 @@ importers: version: link:../../packages/workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 typescript: specifier: catalog:default version: 5.8.3 @@ -737,7 +737,7 @@ importers: version: link:../../packages/workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 '@fixture/pages-plugin': specifier: workspace:* version: link:../pages-plugin-example @@ -764,7 +764,7 @@ importers: version: link:../../packages/workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 typescript: specifier: catalog:default version: 5.8.3 @@ -809,7 +809,7 @@ importers: version: link:../../packages/workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 typescript: specifier: catalog:default version: 5.8.3 @@ -833,7 +833,7 @@ importers: version: link:../../packages/workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 typescript: specifier: catalog:default version: 5.8.3 @@ -857,7 +857,7 @@ importers: version: link:../../packages/workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 typescript: specifier: catalog:default version: 5.8.3 @@ -875,7 +875,7 @@ importers: devDependencies: '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 is-odd: specifier: ^3.0.1 version: 3.0.1 @@ -897,7 +897,7 @@ importers: version: link:../../packages/workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 '@fixture/pages-plugin': specifier: workspace:* version: link:../pages-plugin-example @@ -966,7 +966,7 @@ importers: version: link:../../packages/workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 typescript: specifier: catalog:default version: 5.8.3 @@ -990,7 +990,7 @@ importers: version: link:../../packages/workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 typescript: specifier: catalog:default version: 5.8.3 @@ -1194,19 +1194,19 @@ importers: devDependencies: '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 fixtures/rules-app: devDependencies: '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 fixtures/secrets-store: devDependencies: '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 wrangler: specifier: workspace:* version: link:../../packages/wrangler @@ -1230,7 +1230,7 @@ importers: version: link:../../packages/workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 '@types/is-even': specifier: ^1.0.2 version: 1.0.2 @@ -1257,7 +1257,7 @@ importers: version: link:../../packages/workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 vitest: specifier: catalog:default version: 3.2.3(@types/debug@4.1.12)(@types/node@20.19.9)(@vitest/ui@3.2.3)(jiti@2.6.1)(lightningcss@1.30.2)(msw@2.12.0(@types/node@20.19.9)(typescript@5.9.3))(tsx@4.21.0)(yaml@2.8.1) @@ -1272,7 +1272,7 @@ importers: version: link:../../packages/workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 esbuild: specifier: catalog:default version: 0.27.3 @@ -1305,7 +1305,7 @@ importers: version: link:../../packages/vitest-pool-workers '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 '@microlabs/otel-cf-workers': specifier: 1.0.0-rc.45 version: 1.0.0-rc.45(@opentelemetry/api@1.7.0) @@ -1379,7 +1379,7 @@ importers: version: link:../../packages/workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 undici: specifier: catalog:default version: 7.18.2 @@ -1437,7 +1437,7 @@ importers: devDependencies: '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 wrangler: specifier: workspace:* version: link:../../packages/wrangler @@ -1452,7 +1452,7 @@ importers: version: link:../../packages/workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 miniflare: specifier: workspace:* version: link:../../packages/miniflare @@ -1506,7 +1506,7 @@ importers: version: link:../../packages/workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 run-script-os: specifier: ^1.1.6 version: 1.1.6 @@ -1533,7 +1533,7 @@ importers: version: link:../../packages/workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 typescript: specifier: catalog:default version: 5.8.3 @@ -1557,7 +1557,7 @@ importers: version: link:../../packages/workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 typescript: specifier: catalog:default version: 5.8.3 @@ -1581,7 +1581,7 @@ importers: version: link:../../packages/workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 typescript: specifier: catalog:default version: 5.8.3 @@ -1605,7 +1605,7 @@ importers: version: link:../../packages/workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 typescript: specifier: catalog:default version: 5.8.3 @@ -1629,7 +1629,7 @@ importers: version: link:../../packages/workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 '@types/jest-image-snapshot': specifier: ^6.4.0 version: 6.4.0 @@ -1665,7 +1665,7 @@ importers: version: link:../../packages/workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 playwright-chromium: specifier: catalog:default version: 1.56.1 @@ -1692,7 +1692,7 @@ importers: version: link:../../packages/workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 typescript: specifier: catalog:default version: 5.8.3 @@ -1713,7 +1713,7 @@ importers: version: link:../../packages/eslint-config-shared '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 typescript: specifier: catalog:default version: 5.8.3 @@ -1813,7 +1813,7 @@ importers: version: link:../workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 '@cloudflare/workers-utils': specifier: workspace:* version: link:../workers-utils @@ -1954,7 +1954,7 @@ importers: version: link:../eslint-config-shared '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 '@octokit/types': specifier: ^13.8.0 version: 13.8.0 @@ -1978,7 +1978,7 @@ importers: version: link:../eslint-config-shared '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 '@types/cookie': specifier: ^0.6.0 version: 0.6.0 @@ -2044,7 +2044,7 @@ importers: version: link:../eslint-config-shared '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 eslint: specifier: catalog:default version: 9.39.1(jiti@2.6.1) @@ -2074,10 +2074,10 @@ importers: version: link:../eslint-config-shared '@cloudflare/vitest-pool-workers': specifier: catalog:default - version: 0.10.15(@cloudflare/workers-types@4.20260214.0)(@vitest/runner@3.2.3)(@vitest/snapshot@3.2.3)(vitest@2.1.9) + version: 0.10.15(@cloudflare/workers-types@4.20260217.0)(@vitest/runner@3.2.3)(@vitest/snapshot@3.2.3)(vitest@2.1.9) '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 '@types/mime': specifier: ^3.0.4 version: 3.0.4 @@ -2176,8 +2176,8 @@ importers: specifier: catalog:default version: 7.18.2 workerd: - specifier: 1.20260214.0 - version: 1.20260214.0 + specifier: 1.20260217.0 + version: 1.20260217.0 ws: specifier: catalog:default version: 8.18.0 @@ -2205,7 +2205,7 @@ importers: version: link:../workers-shared '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 '@cloudflare/workflows-shared': specifier: workspace:* version: link:../workflows-shared @@ -2380,7 +2380,7 @@ importers: version: link:../eslint-config-shared '@cloudflare/vitest-pool-workers': specifier: catalog:default - version: 0.10.15(@cloudflare/workers-types@4.20260214.0)(@vitest/runner@3.2.3)(@vitest/snapshot@3.2.3)(vitest@3.2.3) + version: 0.10.15(@cloudflare/workers-types@4.20260217.0)(@vitest/runner@3.2.3)(@vitest/snapshot@3.2.3)(vitest@3.2.3) '@cloudflare/workers-shared': specifier: workspace:* version: link:../workers-shared @@ -2389,7 +2389,7 @@ importers: version: link:../workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 concurrently: specifier: ^8.2.2 version: 8.2.2 @@ -2426,7 +2426,7 @@ importers: version: link:../eslint-config-shared '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 '@types/cookie': specifier: ^0.6.0 version: 0.6.0 @@ -2466,7 +2466,7 @@ importers: version: link:../workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 '@types/node': specifier: ^20.19.9 version: 20.19.9 @@ -2496,7 +2496,7 @@ importers: version: link:../workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 esbuild: specifier: catalog:default version: 0.27.3 @@ -2585,7 +2585,7 @@ importers: version: link:../workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 '@cloudflare/workers-utils': specifier: workspace:* version: link:../workers-utils @@ -2669,7 +2669,7 @@ importers: version: link:../../../workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 typescript: specifier: catalog:default version: 5.8.3 @@ -2690,7 +2690,7 @@ importers: version: link:../../../workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 typescript: specifier: catalog:default version: 5.8.3 @@ -2711,7 +2711,7 @@ importers: version: link:../../../workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 typescript: specifier: catalog:default version: 5.8.3 @@ -2732,7 +2732,7 @@ importers: version: link:../../../workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 typescript: specifier: catalog:default version: 5.8.3 @@ -2753,7 +2753,7 @@ importers: version: link:../../../workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 typescript: specifier: catalog:default version: 5.8.3 @@ -2774,7 +2774,7 @@ importers: version: link:../../../workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 typescript: specifier: catalog:default version: 5.8.3 @@ -2795,7 +2795,7 @@ importers: version: link:../../../workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 typescript: specifier: catalog:default version: 5.8.3 @@ -2816,7 +2816,7 @@ importers: version: link:../../../workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 typescript: specifier: catalog:default version: 5.8.3 @@ -2837,7 +2837,7 @@ importers: version: link:../../../workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 typescript: specifier: catalog:default version: 5.8.3 @@ -2858,7 +2858,7 @@ importers: version: link:../../../workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 typescript: specifier: catalog:default version: 5.8.3 @@ -2879,7 +2879,7 @@ importers: version: link:../../../workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 typescript: specifier: catalog:default version: 5.8.3 @@ -2900,7 +2900,7 @@ importers: version: link:../../../workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 typescript: specifier: catalog:default version: 5.8.3 @@ -2921,7 +2921,7 @@ importers: version: link:../../../workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 typescript: specifier: catalog:default version: 5.8.3 @@ -2942,7 +2942,7 @@ importers: version: link:../../../workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 typescript: specifier: catalog:default version: 5.8.3 @@ -2963,7 +2963,7 @@ importers: version: link:../../../workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 typescript: specifier: catalog:default version: 5.8.3 @@ -2984,7 +2984,7 @@ importers: version: link:../../../workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 typescript: specifier: catalog:default version: 5.8.3 @@ -3005,7 +3005,7 @@ importers: version: link:../../../workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 '@types/mimetext': specifier: ^2.0.4 version: 2.0.4 @@ -3038,7 +3038,7 @@ importers: version: link:../../../workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 typescript: specifier: catalog:default version: 5.8.3 @@ -3059,7 +3059,7 @@ importers: version: link:../../../workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 typescript: specifier: catalog:default version: 5.8.3 @@ -3080,7 +3080,7 @@ importers: version: link:../../../workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 typescript: specifier: catalog:default version: 5.8.3 @@ -3101,7 +3101,7 @@ importers: version: link:../../../workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 typescript: specifier: catalog:default version: 5.8.3 @@ -3122,7 +3122,7 @@ importers: version: link:../../../workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 typescript: specifier: catalog:default version: 5.8.3 @@ -3143,7 +3143,7 @@ importers: version: link:../../../workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 typescript: specifier: catalog:default version: 5.8.3 @@ -3164,7 +3164,7 @@ importers: version: link:../../../workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 '@playground/main-resolution-package': specifier: file:./package version: file:packages/vite-plugin-cloudflare/playground/main-resolution/package @@ -3188,7 +3188,7 @@ importers: version: link:../../../workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 '@types/express': specifier: ^5.0.1 version: 5.0.1 @@ -3215,7 +3215,7 @@ importers: version: link:../../../workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 '@playground/module-resolution-excludes': specifier: file:./packages/excludes version: file:packages/vite-plugin-cloudflare/playground/module-resolution/packages/excludes @@ -3227,7 +3227,7 @@ importers: version: file:packages/vite-plugin-cloudflare/playground/module-resolution/packages/requires '@remix-run/cloudflare': specifier: 2.12.0 - version: 2.12.0(@cloudflare/workers-types@4.20260214.0)(typescript@5.8.3) + version: 2.12.0(@cloudflare/workers-types@4.20260217.0)(typescript@5.8.3) '@types/react': specifier: ^18.3.11 version: 18.3.18 @@ -3260,7 +3260,7 @@ importers: version: link:../../../workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 typescript: specifier: catalog:default version: 5.8.3 @@ -3281,7 +3281,7 @@ importers: version: link:../../../workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 '@types/debug': specifier: ^4.1.12 version: 4.1.12 @@ -3330,7 +3330,7 @@ importers: version: link:../../../workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 '@types/react': specifier: 19.1.0 version: 19.1.0 @@ -3351,7 +3351,7 @@ importers: dependencies: partyserver: specifier: ^0.0.64 - version: 0.0.64(@cloudflare/workers-types@4.20260214.0) + version: 0.0.64(@cloudflare/workers-types@4.20260217.0) partysocket: specifier: ^1.0.3 version: 1.0.3 @@ -3370,7 +3370,7 @@ importers: version: link:../../../workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 '@tailwindcss/vite': specifier: ^4.0.15 version: 4.0.15(vite@7.1.12(@types/node@20.19.9)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.1)) @@ -3406,7 +3406,7 @@ importers: version: link:../../../workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 typescript: specifier: catalog:default version: 5.8.3 @@ -3427,7 +3427,7 @@ importers: version: link:../../../workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 '@prisma/adapter-d1': specifier: ^7.0.0 version: 7.0.1 @@ -3464,7 +3464,7 @@ importers: version: link:../../../workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 '@types/react': specifier: 19.1.0 version: 19.1.0 @@ -3494,7 +3494,7 @@ importers: version: link:../../../workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 typescript: specifier: catalog:default version: 5.8.3 @@ -3515,7 +3515,7 @@ importers: version: link:../../../workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 typescript: specifier: catalog:default version: 5.8.3 @@ -3543,7 +3543,7 @@ importers: version: link:../../../workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 '@types/react': specifier: 19.1.0 version: 19.1.0 @@ -3576,7 +3576,7 @@ importers: version: link:../../../workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 typescript: specifier: catalog:default version: 5.8.3 @@ -3597,7 +3597,7 @@ importers: version: link:../../../workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 typescript: specifier: catalog:default version: 5.8.3 @@ -3618,7 +3618,7 @@ importers: version: link:../../../workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 '@vitejs/plugin-basic-ssl': specifier: ^2.0.0 version: 2.0.0(vite@7.1.12(@types/node@20.19.9)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.1)) @@ -3642,7 +3642,7 @@ importers: version: link:../../../workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 typescript: specifier: catalog:default version: 5.8.3 @@ -3663,7 +3663,7 @@ importers: version: link:../../../workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 typescript: specifier: catalog:default version: 5.8.3 @@ -3684,7 +3684,7 @@ importers: version: link:../../../workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 typescript: specifier: catalog:default version: 5.8.3 @@ -3705,7 +3705,7 @@ importers: version: link:../../../workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 typescript: specifier: catalog:default version: 5.8.3 @@ -3742,7 +3742,7 @@ importers: version: link:../workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 '@cloudflare/workflows-shared': specifier: workspace:* version: link:../workflows-shared @@ -3966,13 +3966,13 @@ importers: version: link:../eslint-config-shared '@cloudflare/vitest-pool-workers': specifier: catalog:default - version: 0.10.15(@cloudflare/workers-types@4.20260214.0)(@vitest/runner@3.2.3)(@vitest/snapshot@3.2.3)(vitest@2.1.9) + version: 0.10.15(@cloudflare/workers-types@4.20260217.0)(@vitest/runner@3.2.3)(@vitest/snapshot@3.2.3)(vitest@2.1.9) '@cloudflare/workers-tsconfig': specifier: workspace:* version: link:../workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 '@sentry/cli': specifier: ^2.37.0 version: 2.41.1(encoding@0.1.13) @@ -4083,13 +4083,13 @@ importers: version: link:../eslint-config-shared '@cloudflare/vitest-pool-workers': specifier: catalog:default - version: 0.10.15(@cloudflare/workers-types@4.20260214.0)(@vitest/runner@3.2.3)(@vitest/snapshot@3.2.3)(vitest@3.2.3) + version: 0.10.15(@cloudflare/workers-types@4.20260217.0)(@vitest/runner@3.2.3)(@vitest/snapshot@3.2.3)(vitest@3.2.3) '@cloudflare/workers-tsconfig': specifier: workspace:* version: link:../workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 '@types/mime': specifier: ^3.0.4 version: 3.0.4 @@ -4130,8 +4130,8 @@ importers: specifier: 2.0.0-rc.24 version: 2.0.0-rc.24 workerd: - specifier: 1.20260214.0 - version: 1.20260214.0 + specifier: 1.20260217.0 + version: 1.20260217.0 optionalDependencies: fsevents: specifier: ~2.3.2 @@ -4166,7 +4166,7 @@ importers: version: link:../workers-tsconfig '@cloudflare/workers-types': specifier: catalog:default - version: 4.20260214.0 + version: 4.20260217.0 '@cloudflare/workers-utils': specifier: workspace:* version: link:../workers-utils @@ -5227,8 +5227,8 @@ packages: cpu: [x64] os: [darwin] - '@cloudflare/workerd-darwin-64@1.20260214.0': - resolution: {integrity: sha512-XOh1yDGqMR5GOKKIIfvWHipCVb+ujSWILqiDWyy+C9MiR7PB9D9nlJsrtPyh3QeUT673FHhOF2AUkTMHBzD2XQ==} + '@cloudflare/workerd-darwin-64@1.20260217.0': + resolution: {integrity: sha512-t1KRT0j4gwLntixMoNujv/UaS89Q7+MPRhkklaSup5tNhl3zBZOIlasBUSir69eXetqLZu8sypx3i7zE395XXA==} engines: {node: '>=16'} cpu: [x64] os: [darwin] @@ -5245,8 +5245,8 @@ packages: cpu: [arm64] os: [darwin] - '@cloudflare/workerd-darwin-arm64@1.20260214.0': - resolution: {integrity: sha512-HIA7FyOuZk+p1pBrJl4PW9LrK85kIZ7vTqBezQsK8Q18+lRKAL/XLjPBLLOSIAZmUL0K5EIH6BUQFZ+NvvzTCQ==} + '@cloudflare/workerd-darwin-arm64@1.20260217.0': + resolution: {integrity: sha512-9pEZ15BmELt0Opy79LTxUvbo55QAI4GnsnsvmgBxaQlc4P0dC8iycBGxbOpegkXnRx/LFj51l2zunfTo0EdATg==} engines: {node: '>=16'} cpu: [arm64] os: [darwin] @@ -5263,8 +5263,8 @@ packages: cpu: [x64] os: [linux] - '@cloudflare/workerd-linux-64@1.20260214.0': - resolution: {integrity: sha512-vtijwdxRSrOwWD1Pw/2zfqOYpbPrPUZEbrIly6g9gD8KnFV8wXQpJSOECaRfcqF2XlTsz/DsnugJdg9+rxfzsA==} + '@cloudflare/workerd-linux-64@1.20260217.0': + resolution: {integrity: sha512-IrZfxQ4b/4/RDQCJsyoxKrCR+cEqKl81yZOirMOKoRrDOmTjn4evYXaHoLBh2PjUKY1Imly7ZiC6G1p0xNIOwg==} engines: {node: '>=16'} cpu: [x64] os: [linux] @@ -5281,8 +5281,8 @@ packages: cpu: [arm64] os: [linux] - '@cloudflare/workerd-linux-arm64@1.20260214.0': - resolution: {integrity: sha512-uegxV508w+qExLal4JEEkhZiAHrdD623faINNShDHcrPCAKF/kDSTUUeQ+LUrzzg8UjVSYqQAod1S8X+1r5OZg==} + '@cloudflare/workerd-linux-arm64@1.20260217.0': + resolution: {integrity: sha512-RGU1wq69ym4sFBVWhQeddZrRrG0hJM/SlZ5DwVDga/zBJ3WXxcDsFAgg1dToDfildTde5ySXN7jAasSmWko9rg==} engines: {node: '>=16'} cpu: [arm64] os: [linux] @@ -5299,14 +5299,14 @@ packages: cpu: [x64] os: [win32] - '@cloudflare/workerd-windows-64@1.20260214.0': - resolution: {integrity: sha512-1jF1sh11WML+RBhrK40US4OEiL7vMr83b+QGBgLXsXSk6o5jerv0KcvJ7pyPv9sgR/16zFVyZaSBZy7q5tFvqQ==} + '@cloudflare/workerd-windows-64@1.20260217.0': + resolution: {integrity: sha512-4T65u1321z1Zet9n7liQsSW7g3EXM5SWIT7kJ/uqkEtkPnIzZBIowMQgkvL5W9SpGZks9t3mTQj7hiUia8Gq9Q==} engines: {node: '>=16'} cpu: [x64] os: [win32] - '@cloudflare/workers-types@4.20260214.0': - resolution: {integrity: sha512-qb8rgbAdJR4BAPXolXhFL/wuGtecHLh1veOyZ1mK6QqWuCdI3vK1biKC0i3lzmzdLR/DZvsN3mNtpUE8zpWGEg==} + '@cloudflare/workers-types@4.20260217.0': + resolution: {integrity: sha512-R5s8h/zj91g6HSB/qndpXGS5Xc8t8Ik3BwY6qwe7XXV6r3Gey1gdthFSK4A2IrPQEmTsc7wEXbs9KpBLNttlqg==} '@colors/colors@1.5.0': resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} @@ -14824,8 +14824,8 @@ packages: engines: {node: '>=16'} hasBin: true - workerd@1.20260214.0: - resolution: {integrity: sha512-KuicRN0kfqRE1EzvQG3lgI8QEX0QpEBOvNtgvmgXrP6TLQQ/P3H+Ypd8mEN+1CUYMffZpLV01zdSCE5yzPOmFA==} + workerd@1.20260217.0: + resolution: {integrity: sha512-6jVisS6wB6KbF+F9DVoDUy9p7MON8qZCFSaL8OcDUioMwknsUPFojUISu3/c30ZOZ24D4h7oqaahFc5C6huilw==} engines: {node: '>=16'} hasBin: true @@ -16310,7 +16310,7 @@ snapshots: lodash.memoize: 4.1.2 marked: 0.3.19 - '@cloudflare/vitest-pool-workers@0.10.15(@cloudflare/workers-types@4.20260214.0)(@vitest/runner@3.2.3)(@vitest/snapshot@3.2.3)(vitest@2.1.9)': + '@cloudflare/vitest-pool-workers@0.10.15(@cloudflare/workers-types@4.20260217.0)(@vitest/runner@3.2.3)(@vitest/snapshot@3.2.3)(vitest@2.1.9)': dependencies: '@vitest/runner': 3.2.3 '@vitest/snapshot': 3.2.3 @@ -16320,14 +16320,14 @@ snapshots: miniflare: 4.20251210.0 semver: 7.7.3 vitest: 2.1.9(@types/node@20.19.9)(@vitest/ui@2.1.9)(lightningcss@1.30.2)(msw@2.12.0(@types/node@20.19.9)(typescript@5.9.3)) - wrangler: 4.54.0(@cloudflare/workers-types@4.20260214.0) + wrangler: 4.54.0(@cloudflare/workers-types@4.20260217.0) zod: 3.25.76 transitivePeerDependencies: - '@cloudflare/workers-types' - bufferutil - utf-8-validate - '@cloudflare/vitest-pool-workers@0.10.15(@cloudflare/workers-types@4.20260214.0)(@vitest/runner@3.2.3)(@vitest/snapshot@3.2.3)(vitest@3.2.3)': + '@cloudflare/vitest-pool-workers@0.10.15(@cloudflare/workers-types@4.20260217.0)(@vitest/runner@3.2.3)(@vitest/snapshot@3.2.3)(vitest@3.2.3)': dependencies: '@vitest/runner': 3.2.3 '@vitest/snapshot': 3.2.3 @@ -16337,7 +16337,7 @@ snapshots: miniflare: 4.20251210.0 semver: 7.7.3 vitest: 3.2.3(@types/debug@4.1.12)(@types/node@20.19.9)(@vitest/ui@3.2.3)(jiti@2.6.1)(lightningcss@1.30.2)(msw@2.12.0(@types/node@20.19.9)(typescript@5.8.3))(supports-color@9.2.2)(tsx@4.21.0)(yaml@2.8.1) - wrangler: 4.54.0(@cloudflare/workers-types@4.20260214.0) + wrangler: 4.54.0(@cloudflare/workers-types@4.20260217.0) zod: 3.25.76 transitivePeerDependencies: - '@cloudflare/workers-types' @@ -16350,7 +16350,7 @@ snapshots: '@cloudflare/workerd-darwin-64@1.20260213.0': optional: true - '@cloudflare/workerd-darwin-64@1.20260214.0': + '@cloudflare/workerd-darwin-64@1.20260217.0': optional: true '@cloudflare/workerd-darwin-arm64@1.20251210.0': @@ -16359,7 +16359,7 @@ snapshots: '@cloudflare/workerd-darwin-arm64@1.20260213.0': optional: true - '@cloudflare/workerd-darwin-arm64@1.20260214.0': + '@cloudflare/workerd-darwin-arm64@1.20260217.0': optional: true '@cloudflare/workerd-linux-64@1.20251210.0': @@ -16368,7 +16368,7 @@ snapshots: '@cloudflare/workerd-linux-64@1.20260213.0': optional: true - '@cloudflare/workerd-linux-64@1.20260214.0': + '@cloudflare/workerd-linux-64@1.20260217.0': optional: true '@cloudflare/workerd-linux-arm64@1.20251210.0': @@ -16377,7 +16377,7 @@ snapshots: '@cloudflare/workerd-linux-arm64@1.20260213.0': optional: true - '@cloudflare/workerd-linux-arm64@1.20260214.0': + '@cloudflare/workerd-linux-arm64@1.20260217.0': optional: true '@cloudflare/workerd-windows-64@1.20251210.0': @@ -16386,10 +16386,10 @@ snapshots: '@cloudflare/workerd-windows-64@1.20260213.0': optional: true - '@cloudflare/workerd-windows-64@1.20260214.0': + '@cloudflare/workerd-windows-64@1.20260217.0': optional: true - '@cloudflare/workers-types@4.20260214.0': {} + '@cloudflare/workers-types@4.20260217.0': {} '@colors/colors@1.5.0': optional: true @@ -17812,7 +17812,7 @@ snapshots: '@prisma/adapter-d1@7.0.1': dependencies: - '@cloudflare/workers-types': 4.20260214.0 + '@cloudflare/workers-types': 4.20260217.0 '@prisma/driver-adapter-utils': 7.0.1 ky: 1.7.5 @@ -18039,10 +18039,10 @@ snapshots: optionalDependencies: '@types/react': 18.3.3 - '@remix-run/cloudflare@2.12.0(@cloudflare/workers-types@4.20260214.0)(typescript@5.8.3)': + '@remix-run/cloudflare@2.12.0(@cloudflare/workers-types@4.20260217.0)(typescript@5.8.3)': dependencies: '@cloudflare/kv-asset-handler': 0.1.3 - '@cloudflare/workers-types': 4.20260214.0 + '@cloudflare/workers-types': 4.20260217.0 '@remix-run/server-runtime': 2.12.0(typescript@5.8.3) optionalDependencies: typescript: 5.8.3 @@ -23870,9 +23870,9 @@ snapshots: parseurl@1.3.3: {} - partyserver@0.0.64(@cloudflare/workers-types@4.20260214.0): + partyserver@0.0.64(@cloudflare/workers-types@4.20260217.0): dependencies: - '@cloudflare/workers-types': 4.20260214.0 + '@cloudflare/workers-types': 4.20260217.0 nanoid: 5.1.0 partysocket@1.0.3: @@ -26772,15 +26772,15 @@ snapshots: '@cloudflare/workerd-linux-arm64': 1.20260213.0 '@cloudflare/workerd-windows-64': 1.20260213.0 - workerd@1.20260214.0: + workerd@1.20260217.0: optionalDependencies: - '@cloudflare/workerd-darwin-64': 1.20260214.0 - '@cloudflare/workerd-darwin-arm64': 1.20260214.0 - '@cloudflare/workerd-linux-64': 1.20260214.0 - '@cloudflare/workerd-linux-arm64': 1.20260214.0 - '@cloudflare/workerd-windows-64': 1.20260214.0 + '@cloudflare/workerd-darwin-64': 1.20260217.0 + '@cloudflare/workerd-darwin-arm64': 1.20260217.0 + '@cloudflare/workerd-linux-64': 1.20260217.0 + '@cloudflare/workerd-linux-arm64': 1.20260217.0 + '@cloudflare/workerd-windows-64': 1.20260217.0 - wrangler@4.54.0(@cloudflare/workers-types@4.20260214.0): + wrangler@4.54.0(@cloudflare/workers-types@4.20260217.0): dependencies: '@cloudflare/kv-asset-handler': 0.4.1 '@cloudflare/unenv-preset': 2.7.13(unenv@2.0.0-rc.24)(workerd@1.20251210.0) @@ -26791,7 +26791,7 @@ snapshots: unenv: 2.0.0-rc.24 workerd: 1.20251210.0 optionalDependencies: - '@cloudflare/workers-types': 4.20260214.0 + '@cloudflare/workers-types': 4.20260217.0 fsevents: 2.3.3 transitivePeerDependencies: - bufferutil diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 10b7f445add5..ab8684cd7d64 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -32,8 +32,8 @@ catalog: "ws": "8.18.0" esbuild: "0.27.3" playwright-chromium: "^1.56.1" - "@cloudflare/workers-types": "^4.20260214.0" - workerd: "1.20260214.0" + "@cloudflare/workers-types": "^4.20260217.0" + workerd: "1.20260217.0" eslint: "^9.39.1" jsonc-parser: "^3.2.0" smol-toml: "^1.5.2"