diff --git a/.changeset/sour-rules-matter.md b/.changeset/sour-rules-matter.md new file mode 100644 index 0000000000..543bc99cb4 --- /dev/null +++ b/.changeset/sour-rules-matter.md @@ -0,0 +1,7 @@ +--- +"wrangler": patch +--- + +Fix `wrangler types` resolution for env-qualified service entrypoints + +`wrangler types` now resolves named `services` entrypoints back to the secondary Worker's source module when the secondary config uses an environment-specific `name` override. This restores strongly typed `Service` output for multi-config type generation instead of falling back to an unresolved `Service` comment. diff --git a/packages/wrangler/src/__tests__/type-generation.test.ts b/packages/wrangler/src/__tests__/type-generation.test.ts index 272f665ee8..cd680af289 100644 --- a/packages/wrangler/src/__tests__/type-generation.test.ts +++ b/packages/wrangler/src/__tests__/type-generation.test.ts @@ -1234,6 +1234,99 @@ describe("generate types", () => { `); }); + it("should resolve named service entrypoints when env overrides the worker name", async ({ + expect, + }) => { + fs.mkdirSync("primary"); + fs.mkdirSync("secondary"); + + fs.writeFileSync( + "./secondary/index.ts", + `import { WorkerEntrypoint } from 'cloudflare:workers'; + export default { async fetch() {} }; + export class SomeEntrypoint extends WorkerEntrypoint {} + ` + ); + fs.writeFileSync( + "./secondary/wrangler.jsonc", + JSON.stringify({ + compatibility_date: "2022-01-12", + name: "secondary-worker", + main: "./index.ts", + env: { + staging: { + name: "secondary-worker-staging", + }, + }, + }), + "utf-8" + ); + + fs.writeFileSync( + "./primary/index.ts", + "export default { async fetch() {} };" + ); + fs.writeFileSync( + "./primary/wrangler.jsonc", + JSON.stringify({ + compatibility_date: "2022-01-12", + name: "primary-worker", + main: "./index.ts", + services: [ + { + binding: "SERVICE_A", + service: "secondary-worker", + entrypoint: "SomeEntrypoint", + }, + ], + env: { + staging: { + name: "primary-worker-staging", + services: [ + { + binding: "SERVICE_A", + service: "secondary-worker-staging", + entrypoint: "SomeEntrypoint", + }, + ], + }, + }, + }), + "utf-8" + ); + + await runWrangler( + "types --include-runtime=false -c primary/wrangler.jsonc -c secondary/wrangler.jsonc --path primary/worker-configuration.d.ts" + ); + + expect(std.out).toMatchInlineSnapshot(` + " + ⛅️ wrangler x.x.x + ────────────────── + - Found Worker 'secondary-worker' at 'secondary/index.ts' (secondary/wrangler.jsonc) + Generating project types... + + declare namespace Cloudflare { + interface GlobalProps { + mainModule: typeof import("./index"); + } + interface StagingEnv { + SERVICE_A: Service; + } + interface Env { + SERVICE_A: Service; + } + } + interface Env extends Cloudflare.Env {} + + ──────────────────────────────────────────────────────────── + ✨ Types written to primary/worker-configuration.d.ts + + 📣 Remember to rerun 'wrangler types' after you change your wrangler.jsonc file. + " + `); + }); + it("should create a DTS file at the location that the command is executed from", async ({ expect, }) => { diff --git a/packages/wrangler/src/type-generation/index.ts b/packages/wrangler/src/type-generation/index.ts index 71d09edd04..ef3a90b13f 100644 --- a/packages/wrangler/src/type-generation/index.ts +++ b/packages/wrangler/src/type-generation/index.ts @@ -209,9 +209,10 @@ export const typesCommand = createCommand({ config: secondaryConfig.configPath, env: envName, }); - const envKey = envConfig.name; + const envEntry = await getEntry({}, envConfig, "types"); + const envKey = envEntry.name; if (envKey && envKey !== key && !secondaryEntries.has(envKey)) { - secondaryEntries.set(envKey, serviceEntry); + secondaryEntries.set(envKey, envEntry); } } } else {