1- import { existsSync } from "node:fs" ;
2- import { readFile , writeFile } from "node:fs/promises" ;
1+ import { readFileSync } from "node:fs" ;
2+ import { writeFile } from "node:fs/promises" ;
33import path from "node:path" ;
44import { describe , expect , it } from "vitest" ;
55import { dedent } from "../src/utils/dedent" ;
@@ -11,6 +11,8 @@ const seed = {
1111 main = "src/index.ts"
1212 compatibility_date = "2023-01-01"
1313 compatibility_flags = ["nodejs_compat", "no_global_navigator"]
14+ [vars]
15+ MY_VAR = "my-var-value"
1416 ` ,
1517 "src/index.ts" : dedent `
1618 export default {
@@ -29,159 +31,156 @@ const seed = {
2931} ;
3032
3133describe ( "types" , ( ) => {
32- it ( "should not generate runtime types without flag" , async ( ) => {
34+ it ( "should generate runtime types without a flag" , async ( ) => {
3335 const helper = new WranglerE2ETestHelper ( ) ;
3436 await helper . seed ( seed ) ;
3537 const output = await helper . run ( `wrangler types` ) ;
3638
37- expect ( output . stdout ) . not . toContain ( `Generating runtime types...` ) ;
39+ expect ( output . stdout ) . toContain ( "Generating runtime types..." ) ;
40+ expect ( output . stdout ) . toContain ( "Runtime types generated." ) ;
41+ expect ( output . stdout ) . toContain (
42+ "✨ Types written to worker-configuration.d.ts"
43+ ) ;
44+ expect ( output . stdout ) . toContain ( "📖 Read about runtime types" ) ;
3845 } ) ;
3946
40- it ( "should generate runtime types at the default path" , async ( ) => {
47+ it ( "should generate runtime types and env types in one file at the default path" , async ( ) => {
4148 const helper = new WranglerE2ETestHelper ( ) ;
4249 await helper . seed ( seed ) ;
43- const output = await helper . run ( `wrangler types --x-include-runtime` ) ;
44-
45- const fileExists = existsSync (
46- path . join ( helper . tmpPath , "./.wrangler/types/runtime.d.ts" )
47- ) ;
48-
49- expect ( fileExists ) . toEqual ( true ) ;
50- expect ( output . stdout ) . toContain ( `Generating runtime types...` ) ;
51- expect ( output . stdout ) . toContain ( `Generating project types...` ) ;
52- expect ( output . stdout ) . toContain (
53- `✨ Runtime types written to ./.wrangler/types/runtime.d.ts`
54- ) ;
55- expect ( output . stdout ) . toContain (
56- `"types": ["./.wrangler/types/runtime.d.ts"]`
57- ) ;
50+ const output = await helper . run ( `wrangler types` ) ;
51+ expect ( output . stdout ) . toContain ( "Generating project types..." ) ;
52+ expect ( output . stdout ) . toContain ( "interface Env {" ) ;
53+ expect ( output . stdout ) . toContain ( "Generating runtime types..." ) ;
54+ expect ( output . stdout ) . toContain ( "Runtime types generated." ) ;
5855 expect ( output . stdout ) . toContain (
59- `📣 Since you have Node.js compatibility mode enabled, you should consider adding Node.js for TypeScript by running "npm i --save-dev @types/[email protected] ". Please see the docs for more details: https://developers.cloudflare.com/workers/languages/typescript/#transitive-loading-of-typesnode-overrides-cloudflareworkers-types` 56+ "✨ Types written to worker-configuration.d.ts"
6057 ) ;
61- expect ( output . stdout ) . toContain (
62- `Remember to run 'wrangler types --x-include-runtime' again if you change 'compatibility_date' or 'compatibility_flags' in your wrangler.toml file.`
58+ const file = readFileSync (
59+ path . join ( helper . tmpPath , "./worker-configuration.d.ts" ) ,
60+ "utf8"
6361 ) ;
62+ expect ( file ) . contains ( 'declare module "cloudflare:workers"' ) ;
63+ expect ( file ) . contains ( "interface Env" ) ;
6464 } ) ;
6565
66- it ( "should generate runtime types at the provided path " , async ( ) => {
66+ it ( "should be able to generate an Env type only " , async ( ) => {
6767 const helper = new WranglerE2ETestHelper ( ) ;
6868 await helper . seed ( seed ) ;
69- const output = await helper . run (
70- `wrangler types --x-include-runtime="./types.d.ts"`
69+ const output = await helper . run ( `wrangler types --include-runtime=false` ) ;
70+ expect ( output . stdout ) . not . toContain ( "Generating runtime types..." ) ;
71+ const file = readFileSync (
72+ path . join ( helper . tmpPath , "./worker-configuration.d.ts" ) ,
73+ "utf8"
7174 ) ;
72-
73- const fileExists = existsSync ( path . join ( helper . tmpPath , "./types.d.ts" ) ) ;
74-
75- expect ( fileExists ) . toEqual ( true ) ;
76- expect ( output . stdout ) . toContain ( `✨ Runtime types written to ./types.d.ts` ) ;
77- expect ( output . stdout ) . toContain ( `"types": ["./types.d.ts"]` ) ;
75+ expect ( file ) . toMatchInlineSnapshot ( `
76+ "// Generated by Wrangler by running \`wrangler types --include-runtime=false\` (hash: 7fbca0b39560512499078acfe5f450c0)
77+ interface Env {
78+ MY_VAR: "my-var-value";
79+ }
80+ "
81+ ` ) ;
7882 } ) ;
7983
80- it ( "should generate types" , async ( ) => {
84+ it ( "should include header with version information in the generated types" , async ( ) => {
8185 const helper = new WranglerE2ETestHelper ( ) ;
8286 await helper . seed ( seed ) ;
83- await helper . run ( `wrangler types --x-include-runtime= "./types.d.ts"` ) ;
87+ await helper . run ( `wrangler types "./types.d.ts" ` ) ;
8488
85- const file = (
86- await readFile ( path . join ( helper . tmpPath , "./types.d.ts" ) )
87- ) . toString ( ) ;
89+ const lines = readFileSync (
90+ path . join ( helper . tmpPath , "./types.d.ts" ) ,
91+ "utf8"
92+ ) . split ( "\n" ) ;
8893
89- expect ( file ) . contains ( 'declare module "cloudflare:workers"' ) ;
94+ expect ( lines [ 0 ] ) . toMatchInlineSnapshot (
95+ `"// Generated by Wrangler by running \`wrangler types ./types.d.ts\` (hash: 7fbca0b39560512499078acfe5f450c0)"`
96+ ) ;
97+ expect ( lines [ 1 ] ) . match (
98+ / \/ \/ R u n t i m e t y p e s g e n e r a t e d w i t h w o r k e r d @ 1 \. \d { 8 } \. \d \d { 4 } - \d { 2 } - \d { 2 } ( [ a - z _ ] + , ? ) * /
99+ ) ;
90100 } ) ;
91101
92- it ( "should recommend to uninstall @cloudflare/workers-types " , async ( ) => {
102+ it ( "should include header with wrangler command that generated it " , async ( ) => {
93103 const helper = new WranglerE2ETestHelper ( ) ;
94104 await helper . seed ( {
95105 ...seed ,
96- "tsconfig.json" : dedent `
97- {
98- "compilerOptions": {
99- "types": ["@cloudflare/workers-types"]
100- }
101- }
102- ` ,
106+ "wranglerA.toml" : dedent `
107+ name = "test-worker"
108+ main = "src/index.ts"
109+ compatibility_date = "2023-01-01"
110+ ` ,
103111 } ) ;
104- const output = await helper . run (
105- ` wrangler types --x-include-runtime="./types .d.ts"`
112+ await helper . run (
113+ " wrangler types -c wranglerA.toml --env-interface MyCloudflareEnv ./cflare-env .d.ts"
106114 ) ;
107115
108- expect ( output . stdout ) . toContain (
109- `📣 You can now uninstall "@cloudflare/workers-types".`
116+ const lines = readFileSync (
117+ path . join ( helper . tmpPath , "./cflare-env.d.ts" ) ,
118+ "utf8"
119+ ) . split ( "\n" ) ;
120+
121+ expect ( lines [ 0 ] ) . toMatchInlineSnapshot (
122+ `"// Generated by Wrangler by running \`wrangler types -c wranglerA.toml --env-interface MyCloudflareEnv ./cflare-env.d.ts\` (hash: 8fcf1ed67a52a2d34d6d34c3068e89b8)"`
123+ ) ;
124+ expect ( lines [ 1 ] ) . match (
125+ / \/ \/ R u n t i m e t y p e s g e n e r a t e d w i t h w o r k e r d @ 1 \. \d { 8 } \. \d \d { 4 } - \d { 2 } - \d { 2 } ( [ a - z _ ] + , ? ) * /
110126 ) ;
111127 } ) ;
112128
113- it ( "should not recommend to install @ types/node if 'node' exists in types array " , async ( ) => {
129+ it ( "should not regenerate runtime types if the header matches, but should regenerate env types " , async ( ) => {
114130 const helper = new WranglerE2ETestHelper ( ) ;
115- await helper . seed ( {
116- ...seed ,
117- "tsconfig.json" : dedent `
118- {
119- "compilerOptions": {
120- "types": ["node"]
121- }
122- }
123- ` ,
124- } ) ;
125- const output = await helper . run (
126- `wrangler types --x-include-runtime="./types.d.ts"`
131+ await helper . seed ( seed ) ;
132+ await helper . run ( `wrangler types` ) ;
133+
134+ const typesPath = path . join ( helper . tmpPath , "worker-configuration.d.ts" ) ;
135+ const file = readFileSync ( typesPath , "utf8" ) . split ( "\n" ) ;
136+
137+ await writeFile (
138+ typesPath ,
139+ [
140+ file [ 0 ] ,
141+ file [ 1 ] ,
142+ "FAKE ENV" ,
143+ "// Begin runtime types" ,
144+ "FAKE RUNTIME" ,
145+ ] . join ( "\n" )
127146 ) ;
128147
129- expect ( output . stdout ) . not . toContain (
130- `📣 Since you have Node.js compatibility mode enabled, you should consider adding Node.js for TypeScript by running "npm i --save-dev @types/[email protected] ". Please see the docs for more details: https://developers.cloudflare.com/workers/languages/typescript/#transitive-loading-of-typesnode-overrides-cloudflareworkers-types` 131- ) ;
148+ await helper . run ( `wrangler types` ) ;
149+
150+ const file2 = readFileSync ( typesPath , "utf8" ) ;
151+
152+ // regenerates env types
153+ expect ( file2 ) . toContain ( "interface Env {" ) ;
154+ // uses cached runtime types
155+ expect ( file2 ) . toContain ( "// Begin runtime types" ) ;
156+ expect ( file2 ) . toContain ( "FAKE RUNTIME" ) ;
132157 } ) ;
133158
134- it ( "should not error with nodejs_compat flags " , async ( ) => {
159+ it ( "should prompt you to update types if they've been changed " , async ( ) => {
135160 const helper = new WranglerE2ETestHelper ( ) ;
136- await helper . seed ( {
137- ... seed ,
138- "wrangler.toml" : dedent `
161+ await helper . seed ( seed ) ;
162+ await helper . run ( `wrangler types` ) ;
163+ seed [ "wrangler.toml" ] = dedent `
139164 name = "test-worker"
140165 main = "src/index.ts"
141166 compatibility_date = "2023-01-01"
142- compatibility_flags = ["nodejs_compat", "experimental:nodejs_compat_v2"]
143- ` ,
144- } ) ;
145-
146- const output = await helper . run (
147- `wrangler types --x-include-runtime="./types.d.ts"`
148- ) ;
149-
150- expect ( output . stderr ) . toBe ( "" ) ;
151- expect ( output . status ) . toBe ( 0 ) ;
152- } ) ;
153- it ( "should include header with version information in the generated types" , async ( ) => {
154- const helper = new WranglerE2ETestHelper ( ) ;
167+ compatibility_flags = ["nodejs_compat", "no_global_navigator"]
168+ [vars]
169+ BEEP = "BOOP"
170+ ` ;
155171 await helper . seed ( seed ) ;
156- await helper . run ( `wrangler types --x-include-runtime="./types.d.ts"` ) ;
157-
158- const file = (
159- await readFile ( path . join ( helper . tmpPath , "./types.d.ts" ) )
160- ) . toString ( ) ;
161-
162- expect ( file . split ( "\n" ) [ 0 ] ) . match (
163- / \/ \/ R u n t i m e t y p e s g e n e r a t e d w i t h w o r k e r d @ 1 \. \d + \. \d \d \d \d \d - \d \d - \d \d ( [ a - z _ ] + , ? ) * /
164- ) ;
165- } ) ;
166- it ( "should not regenerate types if the header matches" , async ( ) => {
167- const helper = new WranglerE2ETestHelper ( ) ;
172+ const worker = helper . runLongLived ( "wrangler dev" ) ;
173+ await worker . readUntil ( / ❓ I t l o o k s l i k e y o u r t y p e s m i g h t b e o u t o f d a t e ./ ) ;
174+ seed [ "wrangler.toml" ] = dedent `
175+ name = "test-worker"
176+ main = "src/index.ts"
177+ compatibility_date = "2023-01-01"
178+ compatibility_flags = ["nodejs_compat"]
179+ [vars]
180+ BEEP = "BOOP"
181+ ASDf = "ADSfadsf"
182+ ` ;
168183 await helper . seed ( seed ) ;
169- await helper . run ( `wrangler types --x-include-runtime` ) ;
170-
171- const runtimeTypesFile = path . join (
172- helper . tmpPath ,
173- "./.wrangler/types/runtime.d.ts"
174- ) ;
175- const file = ( await readFile ( runtimeTypesFile ) ) . toString ( ) ;
176-
177- const header = file . split ( "\n" ) [ 0 ] ;
178-
179- await writeFile ( runtimeTypesFile , header + "\n" + "SOME_RANDOM_DATA" ) ;
180-
181- await helper . run ( `wrangler types --x-include-runtime` ) ;
182-
183- const file2 = ( await readFile ( runtimeTypesFile ) ) . toString ( ) ;
184-
185- expect ( file2 . split ( "\n" ) [ 1 ] ) . toBe ( "SOME_RANDOM_DATA" ) ;
184+ await worker . readUntil ( / ❓ I t l o o k s l i k e y o u r t y p e s m i g h t b e o u t o f d a t e ./ ) ;
186185 } ) ;
187186} ) ;
0 commit comments