diff --git a/.changeset/weak-tools-judge.md b/.changeset/weak-tools-judge.md new file mode 100644 index 000000000000..e9fc0c3a6d70 --- /dev/null +++ b/.changeset/weak-tools-judge.md @@ -0,0 +1,23 @@ +--- +"wrangler": patch +--- + +fix: make `wrangler types` always generate a `d.ts` file for module workers + +Currently if a config file doesn't define any binding nor module, running +`wrangler types` against such file would not produce a `d.ts` file. + +Producing a `d.ts` file can however still be beneficial as it would define a correct +env interface (even if empty) that can be expanded/referenced by user code (this can +be particularly convenient for scaffolding tools that may want to always generate an +env interface). + +Example: +Before `wrangler types --env-interface MyEnv` run with an empty `wrangler.toml` file +would not generate any file, after these change it would instead generate a file with +the following content: + +``` +interface MyEnv { +} +``` diff --git a/packages/wrangler/src/__tests__/type-generation.test.ts b/packages/wrangler/src/__tests__/type-generation.test.ts index f813ec2ceeb4..c29ff1ee8cd7 100644 --- a/packages/wrangler/src/__tests__/type-generation.test.ts +++ b/packages/wrangler/src/__tests__/type-generation.test.ts @@ -234,21 +234,49 @@ describe("generateTypes()", () => { expect(fs.existsSync("./worker-configuration.d.ts")).toBe(true); }); - it("should not create DTS file if there is nothing in the config to generate types from", async () => { - fs.writeFileSync("./index.ts", "export default { async fetch () {} };"); - fs.writeFileSync( - "./wrangler.toml", - TOML.stringify({ - compatibility_date: "2022-01-12", - name: "test-name", - main: "./index.ts", - }), - "utf-8" - ); + describe("when nothing was found", () => { + it("should not create DTS file for service syntax workers", async () => { + fs.writeFileSync( + "./index.ts", + 'addEventListener("fetch", event => { event.respondWith(() => new Response("")); })' + ); + fs.writeFileSync( + "./wrangler.toml", + TOML.stringify({ + compatibility_date: "2022-01-12", + name: "test-name", + main: "./index.ts", + }), + "utf-8" + ); - await runWrangler("types"); - expect(fs.existsSync("./worker-configuration.d.ts")).toBe(false); - expect(std.out).toMatchInlineSnapshot(`""`); + await runWrangler("types"); + expect(fs.existsSync("./worker-configuration.d.ts")).toBe(false); + expect(std.out).toMatchInlineSnapshot(`""`); + }); + + it("should create a DTS file with an empty env interface for module syntax workers", async () => { + fs.writeFileSync("./index.ts", "export default { async fetch () {} };"); + fs.writeFileSync( + "./wrangler.toml", + TOML.stringify({ + compatibility_date: "2022-01-12", + name: "test-name", + main: "./index.ts", + }), + "utf-8" + ); + + await runWrangler("types"); + expect(fs.readFileSync("./worker-configuration.d.ts", "utf-8")).toMatch( + /interface Env \{\s*\}/ + ); + expect(std.out).toMatchInlineSnapshot(` + "interface Env { + } + " + `); + }); }); it("should create a DTS file at the location that the command is executed from", async () => { diff --git a/packages/wrangler/src/type-generation.ts b/packages/wrangler/src/type-generation.ts index aae055461407..54b85228add7 100644 --- a/packages/wrangler/src/type-generation.ts +++ b/packages/wrangler/src/type-generation.ts @@ -305,9 +305,9 @@ function writeDTSFile({ let combinedTypeStrings = ""; if (formatType === "modules") { - combinedTypeStrings += `interface ${envInterface} {\n${envTypeStructure - .map((value) => `\t${value}`) - .join("\n")}\n}\n${modulesTypeStructure.join("\n")}`; + combinedTypeStrings += `interface ${envInterface} {${envTypeStructure + .map((value) => `\n\t${value}`) + .join("")}\n}\n${modulesTypeStructure.join("\n")}`; } else { combinedTypeStrings += `export {};\ndeclare global {\n${envTypeStructure .map((value) => `\tconst ${value}`) @@ -316,7 +316,10 @@ function writeDTSFile({ const wranglerCommandUsed = ["wrangler", ...process.argv.slice(2)].join(" "); - if (envTypeStructure.length || modulesTypeStructure.length) { + const typesHaveBeenFound = + envTypeStructure.length || modulesTypeStructure.length; + + if (formatType === "modules" || typesHaveBeenFound) { fs.writeFileSync( path, [