diff --git a/.changeset/tidy-doors-repeat.md b/.changeset/tidy-doors-repeat.md new file mode 100644 index 000000000000..ac711d43418a --- /dev/null +++ b/.changeset/tidy-doors-repeat.md @@ -0,0 +1,5 @@ +--- +"@cloudflare/vite-plugin": patch +--- + +Add a check to vite-plugin that ensures that the version of Wrangler being used internally is correct diff --git a/packages/vite-plugin-cloudflare/e2e/basic.test.ts b/packages/vite-plugin-cloudflare/e2e/basic.test.ts index ed048115cf44..2fbc76450707 100644 --- a/packages/vite-plugin-cloudflare/e2e/basic.test.ts +++ b/packages/vite-plugin-cloudflare/e2e/basic.test.ts @@ -13,7 +13,7 @@ const commands = ["dev", "buildAndPreview"] as const; describe("basic e2e tests", () => { describe.each(packageManagers)('with "%s" package manager', async (pm) => { - const projectPath = seed("basic", pm); + const projectPath = seed("basic", { pm }); describe.each(commands)('with "%s" command', (command) => { test.skipIf(isBuildAndPreviewOnWindows(command))( diff --git a/packages/vite-plugin-cloudflare/e2e/dynamic.test.ts b/packages/vite-plugin-cloudflare/e2e/dynamic.test.ts index 07b9cb5c603b..d13b1990ceab 100644 --- a/packages/vite-plugin-cloudflare/e2e/dynamic.test.ts +++ b/packages/vite-plugin-cloudflare/e2e/dynamic.test.ts @@ -5,7 +5,7 @@ const packageManagers = ["pnpm", "npm", "yarn"] as const; describe("prebundling Node.js compatibility", () => { describe.each(packageManagers)('with "%s" package manager', (pm) => { - const projectPath = seed("dynamic", pm); + const projectPath = seed("dynamic", { pm }); test("will not cause a reload on a dynamic import of a Node.js module", async ({ expect, diff --git a/packages/vite-plugin-cloudflare/e2e/fixtures/invalid-wrangler-version/package.json b/packages/vite-plugin-cloudflare/e2e/fixtures/invalid-wrangler-version/package.json new file mode 100644 index 000000000000..522302c00438 --- /dev/null +++ b/packages/vite-plugin-cloudflare/e2e/fixtures/invalid-wrangler-version/package.json @@ -0,0 +1,26 @@ +{ + "name": "@cloudflare/vite-plugin-e2e-invalid-wrangler-version", + "version": "0.0.0", + "private": true, + "type": "module", + "scripts": { + "build": "vite build", + "buildAndPreview": "vite build && vite preview", + "dev": "vite", + "lint": "eslint .", + "preview": "vite preview" + }, + "devDependencies": { + "@cloudflare/vite-plugin": "*", + "@cloudflare/workers-types": "^4.20250204.0", + "@eslint/js": "^9.19.0", + "eslint": "^9.19.0", + "eslint-plugin-react-hooks": "^5.0.0", + "eslint-plugin-react-refresh": "^0.4.18", + "globals": "^15.14.0", + "typescript": "~5.7.2", + "typescript-eslint": "^8.22.0", + "vite": "^6.1.0", + "wrangler": "4.20.0" + } +} diff --git a/packages/vite-plugin-cloudflare/e2e/fixtures/invalid-wrangler-version/src/index.ts b/packages/vite-plugin-cloudflare/e2e/fixtures/invalid-wrangler-version/src/index.ts new file mode 100644 index 000000000000..1cee2bb8eb12 --- /dev/null +++ b/packages/vite-plugin-cloudflare/e2e/fixtures/invalid-wrangler-version/src/index.ts @@ -0,0 +1,5 @@ +export default { + async fetch() { + return new Response("OK"); + }, +} satisfies ExportedHandler; diff --git a/packages/vite-plugin-cloudflare/e2e/fixtures/invalid-wrangler-version/tsconfig.json b/packages/vite-plugin-cloudflare/e2e/fixtures/invalid-wrangler-version/tsconfig.json new file mode 100644 index 000000000000..b52af703bdc2 --- /dev/null +++ b/packages/vite-plugin-cloudflare/e2e/fixtures/invalid-wrangler-version/tsconfig.json @@ -0,0 +1,7 @@ +{ + "files": [], + "references": [ + { "path": "./tsconfig.node.json" }, + { "path": "./tsconfig.worker.json" } + ] +} diff --git a/packages/vite-plugin-cloudflare/e2e/fixtures/invalid-wrangler-version/tsconfig.node.json b/packages/vite-plugin-cloudflare/e2e/fixtures/invalid-wrangler-version/tsconfig.node.json new file mode 100644 index 000000000000..50130b3a269b --- /dev/null +++ b/packages/vite-plugin-cloudflare/e2e/fixtures/invalid-wrangler-version/tsconfig.node.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", + "target": "ES2022", + "lib": ["ES2023"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "isolatedModules": true, + "moduleDetection": "force", + "noEmit": true, + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/packages/vite-plugin-cloudflare/e2e/fixtures/invalid-wrangler-version/tsconfig.worker.json b/packages/vite-plugin-cloudflare/e2e/fixtures/invalid-wrangler-version/tsconfig.worker.json new file mode 100644 index 000000000000..ff69f9652d65 --- /dev/null +++ b/packages/vite-plugin-cloudflare/e2e/fixtures/invalid-wrangler-version/tsconfig.worker.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.node.json", + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.worker.tsbuildinfo", + "types": ["@cloudflare/workers-types/2023-07-01", "vite/client"] + }, + "include": ["src"] +} diff --git a/packages/vite-plugin-cloudflare/e2e/fixtures/invalid-wrangler-version/vite.config.ts b/packages/vite-plugin-cloudflare/e2e/fixtures/invalid-wrangler-version/vite.config.ts new file mode 100644 index 000000000000..9c6b158cb564 --- /dev/null +++ b/packages/vite-plugin-cloudflare/e2e/fixtures/invalid-wrangler-version/vite.config.ts @@ -0,0 +1,6 @@ +import { cloudflare } from "@cloudflare/vite-plugin"; +import { defineConfig } from "vite"; + +export default defineConfig({ + plugins: [cloudflare({ inspectorPort: false, persistState: false })], +}); diff --git a/packages/vite-plugin-cloudflare/e2e/fixtures/invalid-wrangler-version/wrangler.jsonc b/packages/vite-plugin-cloudflare/e2e/fixtures/invalid-wrangler-version/wrangler.jsonc new file mode 100644 index 000000000000..a7d9be8cf3f1 --- /dev/null +++ b/packages/vite-plugin-cloudflare/e2e/fixtures/invalid-wrangler-version/wrangler.jsonc @@ -0,0 +1,6 @@ +{ + "name": "cloudflare-vite-e2e-invalid-wrangler-version", + "main": "./src/index.ts", + "compatibility_date": "2024-12-30", + "compatibility_flags": ["nodejs_compat"], +} diff --git a/packages/vite-plugin-cloudflare/e2e/helpers.ts b/packages/vite-plugin-cloudflare/e2e/helpers.ts index 3e21e49577b8..275da55cc929 100644 --- a/packages/vite-plugin-cloudflare/e2e/helpers.ts +++ b/packages/vite-plugin-cloudflare/e2e/helpers.ts @@ -40,8 +40,15 @@ const strictPeerDeps = { /** Seed a test project from a fixture. */ export function seed( fixture: string, - pm: "pnpm" | "yarn" | "npm", - replacements: Record = {} + { + pm, + replacements = {}, + useStrictPeerDeps = true, + }: { + pm: "pnpm" | "yarn" | "npm"; + replacements?: Record; + useStrictPeerDeps?: boolean; + } ) { const root = inject("root"); const projectPath = path.resolve(root, fixture, pm); @@ -56,9 +63,13 @@ export function seed( debuglog("Fixing up replacements in seeded files"); await fixupReplacements(projectPath, replacements); debuglog("Updated vite-plugin version in package.json"); - runCommand(`${pm} install ${strictPeerDeps[pm]}`, projectPath, { - attempts: 2, - }); + runCommand( + `${pm} install ${useStrictPeerDeps ? strictPeerDeps[pm] : ""}`, + projectPath, + { + attempts: 2, + } + ); debuglog("Installed node modules"); }, 200_000); diff --git a/packages/vite-plugin-cloudflare/e2e/invalid-worker-environment-options.test.ts b/packages/vite-plugin-cloudflare/e2e/invalid-worker-environment-options.test.ts index f8949d27f112..8e299cea272b 100644 --- a/packages/vite-plugin-cloudflare/e2e/invalid-worker-environment-options.test.ts +++ b/packages/vite-plugin-cloudflare/e2e/invalid-worker-environment-options.test.ts @@ -4,7 +4,9 @@ import { runLongLived, seed } from "./helpers"; // The test here just makes sure that the validation takes place. // Unit tests for the validation are in `src/__tests__/validate-worker-environment-options.spec.ts` describe("validate Worker environment options", () => { - const projectPath = seed("invalid-worker-environment-options", "pnpm"); + const projectPath = seed("invalid-worker-environment-options", { + pm: "pnpm", + }); test("throws an error for invalid environment options", async ({ expect, diff --git a/packages/vite-plugin-cloudflare/e2e/invalid-wrangler-version.test.ts b/packages/vite-plugin-cloudflare/e2e/invalid-wrangler-version.test.ts new file mode 100644 index 000000000000..949571066695 --- /dev/null +++ b/packages/vite-plugin-cloudflare/e2e/invalid-wrangler-version.test.ts @@ -0,0 +1,22 @@ +import { describe, test } from "vitest"; +import { runLongLived, seed } from "./helpers.js"; + +describe("invalid Wrangler version e2e tests", () => { + // Only test with pnpm; + // npm and yarn don't hoist peer dependencies in the same way as pnpm; + // so having a different peer Wrangler doesn't mess up the internal dependency + const projectPath = seed("invalid-wrangler-version", { + pm: "pnpm", + useStrictPeerDeps: false, + }); + + test("`vite dev` will error when peer installed wrangler version overrides the expected internal dependency", async ({ + expect, + }) => { + const proc = await runLongLived("pnpm", "dev", projectPath); + expect(await proc.exitCode).not.toBe(0); + expect(proc.stderr).toMatch( + /The installed version of Wrangler \(4\.20\.0\) is older than the version required by @cloudflare\/vite-plugin \(\d+\.\d+\.\d+\)/ + ); + }); +}); diff --git a/packages/vite-plugin-cloudflare/e2e/remote-bindings.test.ts b/packages/vite-plugin-cloudflare/e2e/remote-bindings.test.ts index 95d9d4e4a491..07f7f09c5db9 100644 --- a/packages/vite-plugin-cloudflare/e2e/remote-bindings.test.ts +++ b/packages/vite-plugin-cloudflare/e2e/remote-bindings.test.ts @@ -25,7 +25,7 @@ if (!process.env.CLOUDFLARE_ACCOUNT_ID || !process.env.CLOUDFLARE_API_TOKEN) { "<>": `preserve-e2e-vite-remote-alt`, }; - const projectPath = seed("remote-bindings", "pnpm", replacements); + const projectPath = seed("remote-bindings", { pm: "pnpm", replacements }); beforeAll(async () => { try { diff --git a/packages/vite-plugin-cloudflare/e2e/wrangler-configs-validation.test.ts b/packages/vite-plugin-cloudflare/e2e/wrangler-configs-validation.test.ts index 30aeea6c715e..cd45a554edd8 100644 --- a/packages/vite-plugin-cloudflare/e2e/wrangler-configs-validation.test.ts +++ b/packages/vite-plugin-cloudflare/e2e/wrangler-configs-validation.test.ts @@ -5,7 +5,9 @@ import { runLongLived, seed } from "./helpers"; // testing regarding the validation there are unit tests in src/__tests__/get-validated-wrangler-config-path.spec.ts describe("during development wrangler config files are validated", () => { - const noWranglerConfigProjectPath = seed("no-wrangler-config", "pnpm"); + const noWranglerConfigProjectPath = seed("no-wrangler-config", { + pm: "pnpm", + }); test("for the entry worker", async ({ expect }) => { const proc = await runLongLived("pnpm", "dev", noWranglerConfigProjectPath); expect(await proc.exitCode).not.toBe(0); @@ -16,7 +18,7 @@ describe("during development wrangler config files are validated", () => { const noWranglerConfigAuxProjectPath = seed( "no-wrangler-config-for-auxiliary-worker", - "pnpm" + { pm: "pnpm" } ); test("for auxiliary workers", async ({ expect }) => { const proc = await runLongLived( diff --git a/packages/vite-plugin-cloudflare/package.json b/packages/vite-plugin-cloudflare/package.json index c50b0c928ee4..429f28cfd6af 100644 --- a/packages/vite-plugin-cloudflare/package.json +++ b/packages/vite-plugin-cloudflare/package.json @@ -25,7 +25,8 @@ ".": { "types": "./dist/index.d.ts", "import": "./dist/index.js" - } + }, + "./package.json": "./package.json" }, "main": "./dist/index.js", "types": "./dist/index.d.ts", @@ -59,9 +60,11 @@ "@cloudflare/workers-tsconfig": "workspace:*", "@cloudflare/workers-types": "catalog:default", "@types/node": "catalog:vite-plugin", + "@types/semver": "^7.5.1", "@types/ws": "^8.5.13", "magic-string": "^0.30.12", "mlly": "^1.7.4", + "semver": "^7.7.1", "tsdown": "^0.15.4", "typescript": "catalog:default", "vite": "catalog:vite-plugin", diff --git a/packages/vite-plugin-cloudflare/src/assert-wrangler-version.ts b/packages/vite-plugin-cloudflare/src/assert-wrangler-version.ts new file mode 100644 index 000000000000..9051b53b22ec --- /dev/null +++ b/packages/vite-plugin-cloudflare/src/assert-wrangler-version.ts @@ -0,0 +1,40 @@ +import { createRequire } from "node:module"; +import { compare, Range, satisfies, SemVer } from "semver"; + +/** + * Asserts that the installed version of Wrangler that gets pulled in at runtime by the `@cloudflare/vite-plugin` + * matches the version that `@cloudflare/vite-plugin` actually depends upon. + * + * This can sometime be broken by package managers that deduplicate dependencies, such as `pnpm`. + */ +export function assertWranglerVersion() { + const require = createRequire(import.meta.url); + const installedVersion = new SemVer(require("wrangler/package.json").version); + const vitePackage = require("@cloudflare/vite-plugin/package.json"); + + if (vitePackage.dependencies.wrangler.startsWith("workspace:")) { + // We are running in the monorepo, so these deps are not yet computed to specific semver strings. + // We don't need to worry in this case and can skip the check. + return; + } + + const wranglerDependency = new SemVer(vitePackage.dependencies.wrangler); + const wranglerPeerDependency = new Range( + vitePackage.peerDependencies.wrangler + ); + + if (compare(installedVersion, wranglerDependency) < 0) { + throw new Error( + `The installed version of Wrangler (${installedVersion.format()}) is older than the version required by @cloudflare/vite-plugin (${wranglerDependency.format()}).\n` + + `Please install Wrangler version ${wranglerDependency} in your project.` + ); + } + + if (!satisfies(installedVersion, wranglerPeerDependency)) { + console.warn( + `The installed version of Wrangler (${installedVersion.format()}) does not satisfy the peer dependency required by @cloudflare/vite-plugin (${wranglerDependency.format()}).\n` + + `This may lead to unexpected issues when you come to deploy the application.\n` + + `Please install a version of Wrangler that satisfies the peer dependency: ${wranglerPeerDependency}.` + ); + } +} diff --git a/packages/vite-plugin-cloudflare/src/deploy-config.ts b/packages/vite-plugin-cloudflare/src/deploy-config.ts index c37affb171b0..288162c75f84 100644 --- a/packages/vite-plugin-cloudflare/src/deploy-config.ts +++ b/packages/vite-plugin-cloudflare/src/deploy-config.ts @@ -2,7 +2,7 @@ import assert from "node:assert"; import * as fs from "node:fs"; import * as path from "node:path"; import * as vite from "vite"; -import { unstable_readConfig } from "wrangler"; +import * as wrangler from "wrangler"; import type { AssetsOnlyResolvedConfig, WorkersResolvedConfig, @@ -31,7 +31,7 @@ export function getWorkerConfigs(root: string) { path.dirname(deployConfigPath), configPath ); - return unstable_readConfig({ config: resolvedConfigPath }); + return wrangler.unstable_readConfig({ config: resolvedConfigPath }); }); } diff --git a/packages/vite-plugin-cloudflare/src/dev-vars.ts b/packages/vite-plugin-cloudflare/src/dev-vars.ts index 0dd4e4cfaca2..37460037e1fa 100644 --- a/packages/vite-plugin-cloudflare/src/dev-vars.ts +++ b/packages/vite-plugin-cloudflare/src/dev-vars.ts @@ -1,5 +1,5 @@ import * as path from "node:path"; -import { unstable_getVarsForDev } from "wrangler"; +import * as wrangler from "wrangler"; import type { AssetsOnlyResolvedConfig, WorkersResolvedConfig, @@ -14,7 +14,7 @@ export function getLocalDevVarsForPreview( configPath: string | undefined, cloudflareEnv: string | undefined ): string | undefined { - const dotDevDotVars = unstable_getVarsForDev( + const dotDevDotVars = wrangler.unstable_getVarsForDev( configPath, undefined, // We don't currently support setting a list of custom `.env` files. {}, // Don't pass actual vars since these will be loaded from the wrangler.json. diff --git a/packages/vite-plugin-cloudflare/src/index.ts b/packages/vite-plugin-cloudflare/src/index.ts index d76c118ff002..eea64e4ce3f1 100644 --- a/packages/vite-plugin-cloudflare/src/index.ts +++ b/packages/vite-plugin-cloudflare/src/index.ts @@ -6,6 +6,7 @@ import { generateStaticRoutingRuleMatcher } from "@cloudflare/workers-shared/ass import { CoreHeaders, Miniflare } from "miniflare"; import colors from "picocolors"; import * as vite from "vite"; +import { assertWranglerVersion } from "./assert-wrangler-version"; import { hasAssetsConfigChanged } from "./asset-config"; import { createBuildApp } from "./build"; import { @@ -68,6 +69,8 @@ let workersConfigsWarningShown = false; let restartingServer = false; let miniflare: Miniflare | undefined; +await assertWranglerVersion(); + /** * Vite plugin that enables a full-featured integration between Vite and the Cloudflare Workers runtime. * diff --git a/packages/vite-plugin-cloudflare/src/miniflare-options.ts b/packages/vite-plugin-cloudflare/src/miniflare-options.ts index 45a1ef1b95e9..18d0d2b14db9 100644 --- a/packages/vite-plugin-cloudflare/src/miniflare-options.ts +++ b/packages/vite-plugin-cloudflare/src/miniflare-options.ts @@ -18,11 +18,7 @@ import { import colors from "picocolors"; import { globSync } from "tinyglobby"; import * as vite from "vite"; -import { - maybeStartOrUpdateRemoteProxySession, - unstable_convertConfigBindingsToStartWorkerBindings, - unstable_getMiniflareWorkerOptions, -} from "wrangler"; +import * as wrangler from "wrangler"; import { getAssetsConfig } from "./asset-config"; import { ASSET_WORKER_NAME, @@ -401,7 +397,7 @@ export async function getDevMiniflareOptions(config: { Object.entries(resolvedPluginConfig.workers).map( async ([environmentName, workerConfig]) => { const bindings = - unstable_convertConfigBindingsToStartWorkerBindings( + wrangler.unstable_convertConfigBindingsToStartWorkerBindings( workerConfig ); @@ -411,7 +407,7 @@ export async function getDevMiniflareOptions(config: { const remoteProxySessionData = resolvedPluginConfig.experimental.remoteBindings ?? true - ? await maybeStartOrUpdateRemoteProxySession( + ? await wrangler.maybeStartOrUpdateRemoteProxySession( { name: workerConfig.name, bindings: bindings ?? {}, @@ -447,21 +443,22 @@ export async function getDevMiniflareOptions(config: { } } - const miniflareWorkerOptions = unstable_getMiniflareWorkerOptions( - { - ...workerConfig, - assets: undefined, - }, - resolvedPluginConfig.cloudflareEnv, - { - remoteProxyConnectionString: - remoteProxySessionData?.session - ?.remoteProxyConnectionString, - remoteBindingsEnabled: - resolvedPluginConfig.experimental.remoteBindings ?? true, - containerBuildId, - } - ); + const miniflareWorkerOptions = + wrangler.unstable_getMiniflareWorkerOptions( + { + ...workerConfig, + assets: undefined, + }, + resolvedPluginConfig.cloudflareEnv, + { + remoteProxyConnectionString: + remoteProxySessionData?.session + ?.remoteProxyConnectionString, + remoteBindingsEnabled: + resolvedPluginConfig.experimental.remoteBindings ?? true, + containerBuildId, + } + ); const { externalWorkers } = miniflareWorkerOptions; @@ -763,7 +760,9 @@ export async function getPreviewMiniflareOptions(config: { await Promise.all( resolvedPluginConfig.workers.map(async (workerConfig, i) => { const bindings = - unstable_convertConfigBindingsToStartWorkerBindings(workerConfig); + wrangler.unstable_convertConfigBindingsToStartWorkerBindings( + workerConfig + ); const preExistingRemoteProxySessionData = workerConfig.configPath ? remoteProxySessionsDataMap.get(workerConfig.configPath) @@ -771,7 +770,7 @@ export async function getPreviewMiniflareOptions(config: { const remoteProxySessionData = resolvedPluginConfig.experimental.remoteBindings ?? true - ? await maybeStartOrUpdateRemoteProxySession( + ? await wrangler.maybeStartOrUpdateRemoteProxySession( { name: workerConfig.name, bindings: bindings ?? {}, @@ -806,17 +805,14 @@ export async function getPreviewMiniflareOptions(config: { } } - const miniflareWorkerOptions = unstable_getMiniflareWorkerOptions( - workerConfig, - undefined, - { + const miniflareWorkerOptions = + wrangler.unstable_getMiniflareWorkerOptions(workerConfig, undefined, { remoteProxyConnectionString: remoteProxySessionData?.session?.remoteProxyConnectionString, remoteBindingsEnabled: resolvedPluginConfig.experimental.remoteBindings ?? true, containerBuildId, - } - ); + }); const { externalWorkers } = miniflareWorkerOptions; diff --git a/packages/vite-plugin-cloudflare/src/workers-configs.ts b/packages/vite-plugin-cloudflare/src/workers-configs.ts index 3c8f7d717709..b09559faf8d9 100644 --- a/packages/vite-plugin-cloudflare/src/workers-configs.ts +++ b/packages/vite-plugin-cloudflare/src/workers-configs.ts @@ -1,7 +1,7 @@ import assert from "node:assert"; import * as fs from "node:fs"; import * as path from "node:path"; -import { unstable_readConfig } from "wrangler"; +import * as wrangler from "wrangler"; import type { AssetsOnlyConfig, WorkerConfig } from "./plugin-config"; import type { Optional } from "./utils"; import type { Unstable_Config as RawWorkerConfig } from "wrangler"; @@ -123,7 +123,7 @@ function readWorkerConfig( notRelevant: new Set(), }; const config: Optional = - unstable_readConfig( + wrangler.unstable_readConfig( { config: configPath, env }, // Preserve the original `main` value so that Vite can resolve it { preserveOriginalMain: true } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d13df5e6f1b8..2da13cab695d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2233,6 +2233,9 @@ importers: '@types/node': specifier: ^20.19.9 version: 20.19.9 + '@types/semver': + specifier: ^7.5.1 + version: 7.5.1 '@types/ws': specifier: ^8.5.13 version: 8.5.13 @@ -2242,6 +2245,9 @@ importers: mlly: specifier: ^1.7.4 version: 1.7.4 + semver: + specifier: ^7.7.1 + version: 7.7.2 tsdown: specifier: ^0.15.4 version: 0.15.4(typescript@5.8.3) @@ -14434,7 +14440,7 @@ snapshots: package-manager-detector: 0.2.9 picocolors: 1.1.1 resolve-from: 5.0.0 - semver: 7.7.1 + semver: 7.7.2 spawndamnit: 3.0.1 term-size: 2.2.1 @@ -14835,7 +14841,7 @@ snapshots: devalue: 4.3.3 esbuild: 0.17.19 miniflare: 3.20250310.0 - semver: 7.7.1 + semver: 7.7.2 vitest: 2.1.9(@types/node@20.19.9)(@vitest/ui@2.1.9)(lightningcss@1.29.2) wrangler: 3.114.1(@cloudflare/workers-types@4.20251011.0) zod: 3.22.3 @@ -15554,7 +15560,7 @@ snapshots: '@babel/traverse': 7.25.9 '@babel/types': 7.26.3 prettier: 3.2.5 - semver: 7.7.1 + semver: 7.7.2 optionalDependencies: '@vue/compiler-sfc': 3.3.4 transitivePeerDependencies: @@ -15712,7 +15718,7 @@ snapshots: '@jridgewell/gen-mapping@0.3.5': dependencies: '@jridgewell/set-array': 1.2.1 - '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/sourcemap-codec': 1.5.5 '@jridgewell/trace-mapping': 0.3.25 '@jridgewell/resolve-uri@3.1.0': {} @@ -15726,7 +15732,7 @@ snapshots: '@jridgewell/trace-mapping@0.3.25': dependencies: '@jridgewell/resolve-uri': 3.1.0 - '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/sourcemap-codec': 1.5.5 '@jridgewell/trace-mapping@0.3.31': dependencies: @@ -15748,7 +15754,7 @@ snapshots: parse-github-url: 1.0.2 picocolors: 1.1.1 sembear: 0.7.0 - semver: 7.7.1 + semver: 7.7.2 tinyexec: 0.3.2 validate-npm-package-name: 5.0.1