diff --git a/.changeset/viteplus-worker-starters.md b/.changeset/viteplus-worker-starters.md new file mode 100644 index 0000000000..810d1a79df --- /dev/null +++ b/.changeset/viteplus-worker-starters.md @@ -0,0 +1,7 @@ +--- +"cf": minor +--- + +Initialize Workers with Vite+ checks, formatting, and Workers-runtime tests. Align Vite and Vitest across supported package managers while keeping cf responsible for development, builds, and deployment. + +Use the project-local `vp` executable for Vite+ development and builds. This avoids downloading a separate Vite with npm or failing to find a `vite` executable with pnpm. diff --git a/docs/architecture.md b/docs/architecture.md index 8f01123202..f4884e4506 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -553,7 +553,7 @@ merely because a spec happens to be thin. Generalising the runtime-schema pattern into a forge annotation is deliberately deferred until there are four or more such examples. That threshold does not combine unrelated Build Output or migration workflows. -`cf init [directory]` is the single explicit setup entry point; there is no separate `cf setup` or `cf workers setup`. It currently behaves exactly like `cf init workers [directory]`, the first product initializer, which `cf init --help` lists as `[default]`; other products can later add `cf init ` subcommands, and bare `cf init` is expected to become a selection menu of what to create. When the directory is omitted, cf asks for it (defaulting to the current directory); non-interactive runs must pass one, such as `.`. cf shows the absolute target directory (hidden by `--quiet`) before the package-manager choice or autoconfig, and every successful run ends with a `Next steps` list led by `cf dev` (`npx cf dev` when cf itself ran through `npx` or `pnpm dlx`). A missing directory, an empty directory, or one containing only `.git` receives the hello-world Worker scaffold (`cloudflare.config.ts` with a `WORLD` text binding, `vite.config.ts`, `src/index.ts`, `tsconfig.json`, `package.json`, `.gitignore`) built on the `@cloudflare/vite-plugin` v2 beta without Wrangler; dependencies are installed by default with a prompted or `--package-manager` choice. After a successful install, cf generates `.cloudflare/types/index.d.ts` through `commands/workers/types/generate.ts`, the generator behind `cf workers types`; a failure there is a warning, not an error. The template's `typecheck` script runs `cf workers types && tsc`, and its `tsconfig.json` includes `.cloudflare/types`. Any other non-empty directory is handed to autoconfig after cf changes into it, because autoconfig's package installs use the process working directory. `cf dev` and `cf build` still run autoconfig implicitly. Tunnel log streaming is the process-backed `cf tunnels tail` command; the generated tail-create API command only creates a tail descriptor. +`cf init [directory]` is the single explicit setup entry point; there is no separate `cf setup` or `cf workers setup`. It currently behaves exactly like `cf init workers [directory]`, the first product initializer, which `cf init --help` lists as `[default]`; other products can later add `cf init ` subcommands, and bare `cf init` is expected to become a selection menu of what to create. When the directory is omitted, cf asks for it (defaulting to the current directory); non-interactive runs must pass one, such as `.`. cf shows the absolute target directory (hidden by `--quiet`) before the package-manager choice or autoconfig, and every successful run ends with a `Next steps` list led by `cf dev` (`npx cf dev` when cf itself ran through `npx` or `pnpm dlx`). A missing directory, an empty directory, or one containing only `.git` receives the hello-world Worker scaffold (`cloudflare.config.ts` with a `WORLD` text binding, `vite.config.ts`, `vitest.config.ts`, `src/index.ts`, `test/index.test.ts`, `tsconfig.json`, `package.json`, `.gitignore`, plus `pnpm-workspace.yaml` for pnpm or `.yarnrc.yml` for Yarn) built on the `@cloudflare/vite-plugin` v2 beta without Wrangler; dependencies are installed by default with a prompted or `--package-manager` choice. After a successful install, cf generates `.cloudflare/types/index.d.ts` through `commands/workers/types/generate.ts`, the generator behind `cf workers types`; a failure there is a warning, not an error. The template's `typecheck` script runs `cf workers types && vp check --no-fmt --no-lint`, and its `tsconfig.json` includes `.cloudflare/types`. Any other non-empty directory is handed to autoconfig after cf changes into it, because autoconfig's package installs use the process working directory. `cf dev` and `cf build` still run autoconfig implicitly. Tunnel log streaming is the process-backed `cf tunnels tail` command; the generated tail-create API command only creates a tail descriptor. Hand-written commands with no generated parent (`auth/`, `build/`, `cli/`, `completions/`, `dev/`, `deploy/`, `init/`, `previews/`, plus top-level diff --git a/packages/cli/README.md b/packages/cli/README.md index a4e7a4887d..8561ebabb4 100644 --- a/packages/cli/README.md +++ b/packages/cli/README.md @@ -49,7 +49,7 @@ encrypted credentials, so affected profiles must authenticate again. ## Projects -`cf init [directory]` starts a project. If you leave out the directory, cf asks for one (use `cf init .` for the current directory in scripts). In a new or empty directory (only `.git` is allowed), it creates a hello-world Worker with `cloudflare.config.ts`, `vite.config.ts`, `src/index.ts`, `tsconfig.json`, `package.json`, and `.gitignore`, then installs dependencies with the package manager you choose (`--package-manager`, or `--no-install` to skip) and, once they are installed, generates Worker types in `.cloudflare/types/index.d.ts`. With `--no-install`, the types are generated later by `cf dev` or the project's `typecheck` script, which runs `cf workers types` and then `tsc`. In a directory that already contains files, it configures the existing project with autoconfig instead. Either way, it finishes with the next steps to run. `cf init workers [directory]` is the default initializer and currently does the same thing. +`cf init [directory]` starts a project. If you leave out the directory, cf asks for one (use `cf init .` for the current directory in scripts). In a new or empty directory (only `.git` is allowed), it creates a hello-world Worker with `cloudflare.config.ts`, `vite.config.ts`, `vitest.config.ts`, `src/index.ts`, `test/index.test.ts`, `tsconfig.json`, `package.json`, and `.gitignore` (plus `pnpm-workspace.yaml` for pnpm or `.yarnrc.yml` for Yarn), then installs dependencies with the package manager you choose (`--package-manager`, or `--no-install` to skip) and, once they are installed, generates Worker types in `.cloudflare/types/index.d.ts`. With `--no-install`, the types are generated later by `cf dev` or the project's `typecheck` script, which runs `cf workers types && vp check --no-fmt --no-lint`. In a directory that already contains files, it configures the existing project with autoconfig instead. Either way, it finishes with the next steps to run. `cf init workers [directory]` is the default initializer and currently does the same thing. ```sh cf init my-worker diff --git a/packages/cli/package.json b/packages/cli/package.json index fc96332004..3f8d072b8b 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -80,7 +80,7 @@ "@bytecodealliance/jco": "1.39.0", "@clack/core": "1.5.1", "@clack/prompts": "^1.8.1", - "@cloudflare/autoconfig": "0.8.2", + "@cloudflare/autoconfig": "https://pkg.pr.new/cloudflare/workers-sdk/@cloudflare/autoconfig@147a75ae1bc58b81206dee52d4c795ff2a5686cd", "@cloudflare/cli-shared-helpers": "0.2.10", "@cloudflare/codemods": "0.7.0", "@cloudflare/containers-shared": "0.23.4", diff --git a/packages/cli/src/__tests__/commands/init.test.ts b/packages/cli/src/__tests__/commands/init.test.ts index b370ba138e..ad46c4ecfa 100644 --- a/packages/cli/src/__tests__/commands/init.test.ts +++ b/packages/cli/src/__tests__/commands/init.test.ts @@ -33,8 +33,10 @@ const TEMPLATE_FILES = [ "cloudflare.config.ts", "package.json", "src", + "test", "tsconfig.json", "vite.config.ts", + "vitest.config.ts", ]; const PNPM_USER_AGENT = "pnpm/10.27.0 npm/? node/v24.15.0 darwin arm64"; @@ -94,18 +96,23 @@ describe("cf init", () => { name: "my-app", private: true, type: "module", + engines: { node: "^22.23.0 || ^24.22.0 || ^26.12.0" }, scripts: { dev: "cf dev", build: "cf build", deploy: "cf deploy", - typecheck: "cf workers types && tsc", + check: "cf workers types && vp check", + format: "vp fmt", + test: "vp test", + typecheck: "cf workers types && vp check --no-fmt --no-lint", }, devDependencies: { - "@cloudflare/vite-plugin": - WORKER_TEMPLATE_DEV_DEPENDENCIES["@cloudflare/vite-plugin"], + ...WORKER_TEMPLATE_DEV_DEPENDENCIES, cf: `^${VERSION}`, - typescript: WORKER_TEMPLATE_DEV_DEPENDENCIES.typescript, + }, + overrides: { vite: WORKER_TEMPLATE_DEV_DEPENDENCIES.vite, + vitest: WORKER_TEMPLATE_DEV_DEPENDENCIES.vitest, }, }); const config = readFileSync("my-app/cloudflare.config.ts", "utf8"); @@ -126,6 +133,7 @@ describe("cf init", () => { ); expect(readJson("my-app/tsconfig.json").include).toEqual([ "src", + "test", "cloudflare.config.ts", ".cloudflare/types", ]); @@ -144,6 +152,50 @@ describe("cf init", () => { expect(stderr()).not.toContain("npm run dev"); }); + it.each(["npm", "pnpm", "yarn", "bun"])( + "aligns plugin dependencies with Vite+ for %s", + async (packageManager) => { + await runCf([ + "init", + "my-app", + "--no-install", + "--package-manager", + packageManager, + ]); + const pkg = readJson("my-app/package.json"); + const versions = { + vite: WORKER_TEMPLATE_DEV_DEPENDENCIES.vite, + vitest: WORKER_TEMPLATE_DEV_DEPENDENCIES.vitest, + }; + if (packageManager === "pnpm") { + const workspace = readFileSync("my-app/pnpm-workspace.yaml", "utf8"); + for (const [name, version] of Object.entries(versions)) { + expect(workspace).toContain(`${name}: ${JSON.stringify(version)}`); + } + } else { + expect( + pkg[packageManager === "yarn" ? "resolutions" : "overrides"] + ).toEqual(versions); + } + if (packageManager === "yarn") { + expect(readFileSync("my-app/.yarnrc.yml", "utf8")).toBe( + "nodeLinker: node-modules\n" + ); + } else { + expect(existsSync("my-app/.yarnrc.yml")).toBe(false); + } + expect(readFileSync("my-app/vitest.config.ts", "utf8")).toContain( + "experimental: { newConfig: true }" + ); + expect(readFileSync("my-app/vite.config.ts", "utf8")).toContain( + "typeAware: true, typeCheck: true" + ); + expect(readFileSync("my-app/test/index.test.ts", "utf8")).toContain( + "SELF.fetch" + ); + } + ); + it("uses the Vite plugin beta dist-tag without Wrangler", async () => { await runCf(["init", "my-app", "--no-install"]); @@ -296,9 +348,8 @@ describe("cf init", () => { describe("dependency installation", () => { it("installs with the package manager that launched cf", async () => { vi.mocked(runProjectCommand).mockImplementationOnce(async () => { - expect(readFileSync("my-app/pnpm-workspace.yaml", "utf8")).toBe( - "# Approve build scripts needed by the generated Worker's dependencies.\n" + - "allowBuilds:\n esbuild: true\n workerd: true\n" + expect(readFileSync("my-app/pnpm-workspace.yaml", "utf8")).toContain( + "allowBuilds:\n esbuild: true\n workerd: true\n" ); return { exitCode: 0 }; }); diff --git a/packages/cli/src/__tests__/lib/autoconfig-vite-plus.test.ts b/packages/cli/src/__tests__/lib/autoconfig-vite-plus.test.ts new file mode 100644 index 0000000000..fe695c75de --- /dev/null +++ b/packages/cli/src/__tests__/lib/autoconfig-vite-plus.test.ts @@ -0,0 +1,52 @@ +import { runInTempDir, seed } from "@cloudflare/workers-utils/test-helpers"; +import { expect, it } from "vite-plus/test"; +import { renderWorkerTemplate } from "../../commands/init/template.js"; +import { analyzeProject } from "../../lib/autoconfig.js"; + +runInTempDir(); + +it("detects Vite+ commands using the installed autoconfig dependency", async () => { + await seed({ + ...renderWorkerTemplate({ + name: "my-worker", + compatibilityDate: "2026-10-29", + cfVersion: "0.1.0", + packageManager: "npm", + }), + "package-lock.json": "{}", + }); + const details = await analyzeProject(process.cwd(), { output: "silent" }); + expect(details).toMatchObject({ + configured: true, + devCommand: "npx vp dev", + buildCommand: "npx vp build", + }); +}); + +it.each([false, true])( + "detects vinext commands with Vite+ enabled: %s", + async (vitePlus) => { + await seed({ + "package.json": JSON.stringify({ + dependencies: { next: "^16.0.0", vinext: "^0.0.1" }, + ...(vitePlus && { devDependencies: { "vite-plus": "1.4.0" } }), + }), + "package-lock.json": "{}", + "node_modules/next/package.json": JSON.stringify({ + name: "next", + version: "16.0.0", + }), + "node_modules/vinext/package.json": JSON.stringify({ + name: "vinext", + version: "0.0.1", + }), + }); + const details = await analyzeProject(process.cwd(), { output: "silent" }); + const command = vitePlus ? "vp" : "vite"; + expect(details).toMatchObject({ + configured: true, + devCommand: `npx ${command} dev`, + buildCommand: `npx ${command} build`, + }); + } +); diff --git a/packages/cli/src/commands/init/template.ts b/packages/cli/src/commands/init/template.ts index e47c08beac..ef01192c0b 100644 --- a/packages/cli/src/commands/init/template.ts +++ b/packages/cli/src/commands/init/template.ts @@ -2,8 +2,11 @@ import type { PackageManager } from "./workers.js"; export const WORKER_TEMPLATE_DEV_DEPENDENCIES = { "@cloudflare/vite-plugin": "beta", + "@cloudflare/vitest-plugin": "^1.4.10", typescript: "^7.0.2", - vite: "^8.3.0", + vite: "npm:@voidzero-dev/vite-plus-core@1.4.0", + "vite-plus": "1.4.0", + vitest: "5.0.5", } as const; export interface WorkerTemplateOptions { @@ -23,14 +26,27 @@ export function renderWorkerTemplate( ...(options.packageManager === "pnpm" ? { "pnpm-workspace.yaml": renderPnpmWorkspace() } : {}), + ...(options.packageManager === "yarn" + ? { ".yarnrc.yml": "nodeLinker: node-modules\n" } + : {}), "src/index.ts": renderEntrypoint(), + "test/index.test.ts": renderTest(), "tsconfig.json": renderTsconfig(), "vite.config.ts": renderViteConfig(), + "vitest.config.ts": renderVitestConfig(), }; } function renderPnpmWorkspace(): string { - return `# Approve build scripts needed by the generated Worker's dependencies. + return `packages: + - "." + +# Keep the toolchain used by plugins aligned with Vite+. +overrides: + vite: ${JSON.stringify(WORKER_TEMPLATE_DEV_DEPENDENCIES.vite)} + vitest: ${JSON.stringify(WORKER_TEMPLATE_DEV_DEPENDENCIES.vitest)} + +# Approve build scripts needed by the generated Worker's dependencies. allowBuilds: esbuild: true workerd: true @@ -62,10 +78,36 @@ export default defineConfig({ function renderViteConfig(): string { return `import { cloudflare } from "@cloudflare/vite-plugin"; -import { defineConfig } from "vite"; +import { defineConfig } from "vite-plus"; export default defineConfig({ plugins: [cloudflare()], + fmt: { useTabs: true }, + lint: { + options: { typeAware: true, typeCheck: true }, + }, +}); +`; +} + +function renderVitestConfig(): string { + return `import { cloudflareTest } from "@cloudflare/vitest-plugin"; +import { defineConfig } from "vite-plus"; + +export default defineConfig({ + plugins: [cloudflareTest({ experimental: { newConfig: true } })], +}); +`; +} + +function renderTest(): string { + return `import { SELF } from "cloudflare:test"; +import { expect, it } from "vite-plus/test"; + +it("responds using the configured Worker binding", async () => { + const response = await SELF.fetch("https://example.com/"); + expect(response.status).toBe(200); + expect(await response.text()).toBe("Hello World!"); }); `; } @@ -90,37 +132,53 @@ function renderPackageJson(options: WorkerTemplateOptions): string { dev: "cf dev", build: "cf build", deploy: "cf deploy", - typecheck: "cf workers types && tsc", + check: "cf workers types && vp check", + format: "vp fmt", + test: "vp test", + typecheck: "cf workers types && vp check --no-fmt --no-lint", }, devDependencies: { "@cloudflare/vite-plugin": WORKER_TEMPLATE_DEV_DEPENDENCIES["@cloudflare/vite-plugin"], + "@cloudflare/vitest-plugin": + WORKER_TEMPLATE_DEV_DEPENDENCIES["@cloudflare/vitest-plugin"], cf: cfDependencyRange(options.cfVersion), typescript: WORKER_TEMPLATE_DEV_DEPENDENCIES.typescript, vite: WORKER_TEMPLATE_DEV_DEPENDENCIES.vite, + "vite-plus": WORKER_TEMPLATE_DEV_DEPENDENCIES["vite-plus"], + vitest: WORKER_TEMPLATE_DEV_DEPENDENCIES.vitest, }, + ...(options.packageManager === "pnpm" + ? {} + : { + [options.packageManager === "yarn" ? "resolutions" : "overrides"]: { + vite: WORKER_TEMPLATE_DEV_DEPENDENCIES.vite, + vitest: WORKER_TEMPLATE_DEV_DEPENDENCIES.vitest, + }, + }), + engines: { node: "^22.23.0 || ^24.22.0 || ^26.12.0" }, }; return `${JSON.stringify(packageJson, null, "\t")}\n`; } function renderTsconfig(): string { - const tsconfig = { - compilerOptions: { - target: "es2024", - lib: ["es2024"], - module: "preserve", - moduleResolution: "bundler", - types: [], - strict: true, - noEmit: true, - allowImportingTsExtensions: true, - isolatedModules: true, - verbatimModuleSyntax: true, - skipLibCheck: true, - }, - include: ["src", "cloudflare.config.ts", ".cloudflare/types"], - }; - return `${JSON.stringify(tsconfig, null, "\t")}\n`; + return `{ + "compilerOptions": { + "target": "es2024", + "lib": ["es2024"], + "module": "preserve", + "moduleResolution": "bundler", + "types": ["@cloudflare/vitest-plugin/types"], + "strict": true, + "noEmit": true, + "allowImportingTsExtensions": true, + "isolatedModules": true, + "verbatimModuleSyntax": true, + "skipLibCheck": true + }, + "include": ["src", "test", "cloudflare.config.ts", ".cloudflare/types"] +} +`; } function renderGitignore(): string { diff --git a/packages/cli/src/lib/vinext.ts b/packages/cli/src/lib/vinext.ts index eda28e8790..3e6a29819b 100644 --- a/packages/cli/src/lib/vinext.ts +++ b/packages/cli/src/lib/vinext.ts @@ -49,5 +49,10 @@ function getVinextCommand( details: AutoConfigDetails, command: "dev" | "build" ): string { - return `${details.packageManager.npx} vite ${command}`; + const vite = + details.packageJson?.dependencies?.["vite-plus"] || + details.packageJson?.devDependencies?.["vite-plus"] + ? "vp" + : "vite"; + return `${details.packageManager.npx} ${vite} ${command}`; } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 193ad3f4d6..b7e4b190a6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -172,6 +172,8 @@ catalogs: version: 1.4.0 overrides: + '@cloudflare/autoconfig>@cloudflare/config': 0.29.0 + '@cloudflare/autoconfig>@cloudflare/workers-utils': 0.50.0 vite@*: npm:@voidzero-dev/vite-plus-core@1.4.0 vitest@*: 5.0.5 @@ -279,8 +281,8 @@ importers: specifier: ^1.8.1 version: 1.8.1 '@cloudflare/autoconfig': - specifier: 0.8.2 - version: 0.8.2(vitest@5.0.5) + specifier: https://pkg.pr.new/cloudflare/workers-sdk/@cloudflare/autoconfig@147a75ae1bc58b81206dee52d4c795ff2a5686cd + version: https://pkg.pr.new/cloudflare/workers-sdk/@cloudflare/autoconfig@147a75ae1bc58b81206dee52d4c795ff2a5686cd(vitest@5.0.5) '@cloudflare/cli-shared-helpers': specifier: 0.2.10 version: 0.2.10(vitest@5.0.5) @@ -697,8 +699,9 @@ packages: resolution: {integrity: sha512-dlT1m5e/0yUL0kRNcQn7yGLVThkgbB0Ga/1AmfDDC/8ik6AIiSf2QLQO2zPYvefsHP0aFgxO93cVLCCfDp7kzQ==} engines: {node: '>= 20.12.0'} - '@cloudflare/autoconfig@0.8.2': - resolution: {integrity: sha512-F/Z5nX6VJgfnjbmLzYR+AhI7dLZDjCQWURYIai2kd2kBaTkmnDb2e34gb/QcOM4hHnUlAhnKaQc/LigOm+GnYA==} + '@cloudflare/autoconfig@https://pkg.pr.new/cloudflare/workers-sdk/@cloudflare/autoconfig@147a75ae1bc58b81206dee52d4c795ff2a5686cd': + resolution: {integrity: sha512-mW+Hq0BaEB8Bpb7y1PqZFaAK3dXzDXrmNdjCbcWEKcM7vxRYtCVAe079kzviw3/HtVOyO4xi2nAz9Q991M0SWQ==, tarball: https://pkg.pr.new/cloudflare/workers-sdk/@cloudflare/autoconfig@147a75ae1bc58b81206dee52d4c795ff2a5686cd} + version: 0.8.3 '@cloudflare/build-output-utils@0.9.6': resolution: {integrity: sha512-JjNSJPctyGbQn4XDXzsqy1/M/xdNAh3XRPj0c/4KY1BYCUWA/ejcrnj3nuTHyoN8Zl+RmVIThIj+am29jTV+kQ==} @@ -706,6 +709,9 @@ packages: '@cloudflare/cli-shared-helpers@0.2.10': resolution: {integrity: sha512-glYLuQlNaXcu440+mSWofXBKKtvFwqNbUIrQqRfERDrCqlLA9Om3vRe+AAgdtGgLVbhbJTB6sIH5mjwceufAuA==} + '@cloudflare/cli-shared-helpers@0.3.0': + resolution: {integrity: sha512-AoA3hckTXlVQCdUpdFS9SvHHdEVc9spOKxiOMgO5OykepFU7dJDj/lygQ+5f5GFFJvRcyoHtDmWouY4U+9uLbw==} + '@cloudflare/codemods@0.7.0': resolution: {integrity: sha512-WQ4Uenqb3MPAisrrBAnr8Oik6moFgtRXBsA9MB5gJcq9nkqYplyNa2bIdp/CRYt0leJW9hKDQL4jtC1hfDn+5A==} hasBin: true @@ -805,6 +811,14 @@ packages: vitest: optional: true + '@cloudflare/workers-utils@0.50.1': + resolution: {integrity: sha512-b2sKwfyafHkXNp6lfsG7ZPKR5XQqI4i2qqXP5YzoiZV559I4kI+Dq0hXoj2jeq2Cxr88//IWDv0eKEZGN9iVSw==} + peerDependencies: + vitest: 5.0.5 + peerDependenciesMeta: + vitest: + optional: true + '@cspotcode/source-map-support@0.8.1': resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} engines: {node: '>=12'} @@ -4222,9 +4236,9 @@ snapshots: fast-wrap-ansi: 0.2.2 sisteransi: 1.0.5 - '@cloudflare/autoconfig@0.8.2(vitest@5.0.5)': + '@cloudflare/autoconfig@https://pkg.pr.new/cloudflare/workers-sdk/@cloudflare/autoconfig@147a75ae1bc58b81206dee52d4c795ff2a5686cd(vitest@5.0.5)': dependencies: - '@cloudflare/cli-shared-helpers': 0.2.10(vitest@5.0.5) + '@cloudflare/cli-shared-helpers': 0.3.0(vitest@5.0.5) '@cloudflare/config': 0.29.0 '@cloudflare/workers-utils': 0.50.0(vitest@5.0.5) transitivePeerDependencies: @@ -4245,6 +4259,17 @@ snapshots: transitivePeerDependencies: - vitest + '@cloudflare/cli-shared-helpers@0.3.0(vitest@5.0.5)': + dependencies: + '@clack/core': 1.2.0 + '@cloudflare/workers-utils': 0.50.1(vitest@5.0.5) + chalk: 5.3.0 + ci-info: 4.4.0 + cross-spawn: 7.0.6 + log-update: 5.0.1 + transitivePeerDependencies: + - vitest + '@cloudflare/codemods@0.7.0': {} '@cloudflare/config@0.29.0': @@ -4352,6 +4377,14 @@ snapshots: optionalDependencies: vitest: 5.0.5(@types/node@25.9.9)(@vitest/browser-preview@5.0.5)(@vitest/ui@5.0.5)(@voidzero-dev/vite-plus-core@1.4.0(@types/node@25.9.9)(esbuild@0.28.2)(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.39)(yaml@2.9.0))(esbuild@0.28.2)(msw@3.0.3(@types/node@25.9.9)(esbuild@0.28.2)(graphql@16.14.2)(supports-color@10.2.2)(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.39)(yaml@2.9.0))(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.39)(yaml@2.9.0) + '@cloudflare/workers-utils@0.50.1(vitest@5.0.5)': + dependencies: + chalk: 5.3.0 + dotenv: 16.3.1 + undici: 7.30.1 + optionalDependencies: + vitest: 5.0.5(@types/node@25.9.9)(@vitest/browser-preview@5.0.5)(@vitest/ui@5.0.5)(@voidzero-dev/vite-plus-core@1.4.0(@types/node@25.9.9)(esbuild@0.28.2)(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.39)(yaml@2.9.0))(esbuild@0.28.2)(msw@3.0.3(@types/node@25.9.9)(esbuild@0.28.2)(graphql@16.14.2)(supports-color@10.2.2)(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.39)(yaml@2.9.0))(tsx@4.21.0)(typescript@6.0.3)(unrun@0.2.39)(yaml@2.9.0) + '@cspotcode/source-map-support@0.8.1': dependencies: '@jridgewell/trace-mapping': 0.3.9 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 04429522d9..4b8eeeeba9 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -34,6 +34,9 @@ catalog: vite: npm:@voidzero-dev/vite-plus-core@1.4.0 vite-plus: 1.4.0 overrides: + # Use the published shared packages with the commit-pinned autoconfig preview. + "@cloudflare/autoconfig>@cloudflare/config": 0.29.0 + "@cloudflare/autoconfig>@cloudflare/workers-utils": 0.50.0 vite@*: "catalog:" vitest@*: 5.0.5 peerDependencyRules: