wrangler 2.1.13 → 2.1.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -82,7 +82,3 @@ For more commands and options, refer to the [documentation](https://developers.c
82
82
  ## Documentation
83
83
 
84
84
  For the latest Wrangler documentation, [click here](https://developers.cloudflare.com/workers/wrangler/).
85
-
86
- ```
87
-
88
- ```
@@ -746,10 +746,11 @@ import {
746
746
  DurableObjectStub
747
747
  } from "@miniflare/durable-objects";
748
748
  import {
749
- Log,
749
+ Log as MiniflareLog,
750
+ LogLevel as MiniflareLogLevel,
750
751
  Miniflare,
751
- Response as MiniflareResponse3,
752
- Request as MiniflareRequest3
752
+ Request as MiniflareRequest3,
753
+ Response as MiniflareResponse3
753
754
  } from "miniflare";
754
755
 
755
756
  // ../../node_modules/yargs/lib/platform-shims/esm.mjs
@@ -6145,7 +6146,7 @@ var getRequestContextCheckOptions = async () => {
6145
6146
  };
6146
6147
 
6147
6148
  // src/miniflare-cli/index.ts
6148
- var NoOpLog = class extends Log {
6149
+ var MiniflareNoOpLog = class extends MiniflareLog {
6149
6150
  log() {
6150
6151
  }
6151
6152
  error(message) {
@@ -6159,9 +6160,12 @@ async function main() {
6159
6160
  ...JSON.parse(args._[0] ?? "{}"),
6160
6161
  ...requestContextCheckOptions
6161
6162
  };
6162
- const logLevel = config.logLevel.toUpperCase();
6163
- config.log = config.logLevel === "none" ? new NoOpLog() : new Log(logLevel, config.logOptions);
6164
- if (logLevel === "DEBUG" || logLevel === "VERBOSE") {
6163
+ let logLevelString = config.logLevel.toUpperCase();
6164
+ if (logLevelString === "LOG")
6165
+ logLevelString = "INFO";
6166
+ const logLevel = MiniflareLogLevel[logLevelString];
6167
+ config.log = logLevel === MiniflareLogLevel.NONE ? new MiniflareNoOpLog() : new MiniflareLog(logLevel, config.logOptions);
6168
+ if (logLevel === MiniflareLogLevel.DEBUG) {
6165
6169
  console.log("MINIFLARE OPTIONS:\n", JSON.stringify(config, null, 2));
6166
6170
  }
6167
6171
  config.bindings = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wrangler",
3
- "version": "2.1.13",
3
+ "version": "2.1.14",
4
4
  "description": "Command-line interface for all things Cloudflare Workers",
5
5
  "keywords": [
6
6
  "wrangler",
@@ -5,6 +5,7 @@ import { mockConfirm } from "./helpers/mock-dialogs";
5
5
  import { runInTempDir } from "./helpers/run-in-tmp";
6
6
  import { runWrangler } from "./helpers/run-wrangler";
7
7
  import writeWranglerToml from "./helpers/write-wrangler-toml";
8
+ import type { KVNamespaceInfo } from "../kv/helpers";
8
9
 
9
10
  describe("delete", () => {
10
11
  mockAccountId();
@@ -22,6 +23,7 @@ describe("delete", () => {
22
23
  text: `Are you sure you want to delete my-script? This action cannot be undone.`,
23
24
  result: true,
24
25
  });
26
+ mockListKVNamespacesRequest();
25
27
  mockDeleteWorkerRequest({ name: "my-script" });
26
28
  await runWrangler("delete --name my-script");
27
29
 
@@ -41,6 +43,7 @@ describe("delete", () => {
41
43
  result: true,
42
44
  });
43
45
  writeWranglerToml();
46
+ mockListKVNamespacesRequest();
44
47
  mockDeleteWorkerRequest();
45
48
  await runWrangler("delete");
46
49
 
@@ -84,6 +87,105 @@ describe("delete", () => {
84
87
  }
85
88
  `);
86
89
  });
90
+
91
+ it("should delete a site namespace associated with a worker", async () => {
92
+ const kvNamespaces = [
93
+ {
94
+ title: "__my-script-workers_sites_assets",
95
+ id: "id-for-my-script-site-ns",
96
+ },
97
+ // this one isn't associated with the worker
98
+ {
99
+ title: "__test-name-workers_sites_assets",
100
+ id: "id-for-another-site-ns",
101
+ },
102
+ ];
103
+
104
+ mockConfirm({
105
+ text: `Are you sure you want to delete my-script? This action cannot be undone.`,
106
+ result: true,
107
+ });
108
+ mockListKVNamespacesRequest(...kvNamespaces);
109
+ // it should only try to delete the site namespace associated with this worker
110
+ setMockResponse(
111
+ "/accounts/:accountId/storage/kv/namespaces/id-for-my-script-site-ns",
112
+ "DELETE",
113
+ ([_url, accountId]) => {
114
+ expect(accountId).toEqual("some-account-id");
115
+ return null;
116
+ }
117
+ );
118
+ mockDeleteWorkerRequest({ name: "my-script" });
119
+ await runWrangler("delete --name my-script");
120
+ expect(std).toMatchInlineSnapshot(`
121
+ Object {
122
+ "debug": "",
123
+ "err": "",
124
+ "out": "🌀 Deleted asset namespace for Workers Site \\"__my-script-workers_sites_assets\\"
125
+ Successfully deleted my-script",
126
+ "warn": "",
127
+ }
128
+ `);
129
+ });
130
+
131
+ it("should delete a site namespace associated with a worker, including it's preview namespace", async () => {
132
+ // This is the same test as the previous one, but it includes a preview namespace
133
+ const kvNamespaces = [
134
+ {
135
+ title: "__my-script-workers_sites_assets",
136
+ id: "id-for-my-script-site-ns",
137
+ },
138
+ // this is the preview namespace
139
+ {
140
+ title: "__my-script-workers_sites_assets_preview",
141
+ id: "id-for-my-script-site-preview-ns",
142
+ },
143
+
144
+ // this one isn't associated with the worker
145
+ {
146
+ title: "__test-name-workers_sites_assets",
147
+ id: "id-for-another-site-ns",
148
+ },
149
+ ];
150
+
151
+ mockConfirm({
152
+ text: `Are you sure you want to delete my-script? This action cannot be undone.`,
153
+ result: true,
154
+ });
155
+ mockListKVNamespacesRequest(...kvNamespaces);
156
+ // it should only try to delete the site namespace associated with this worker
157
+
158
+ setMockResponse(
159
+ "/accounts/:accountId/storage/kv/namespaces/id-for-my-script-site-ns",
160
+ "DELETE",
161
+ ([_url, accountId]) => {
162
+ expect(accountId).toEqual("some-account-id");
163
+ return null;
164
+ }
165
+ );
166
+
167
+ setMockResponse(
168
+ "/accounts/:accountId/storage/kv/namespaces/id-for-my-script-site-preview-ns",
169
+ "DELETE",
170
+ ([_url, accountId]) => {
171
+ expect(accountId).toEqual("some-account-id");
172
+ return null;
173
+ }
174
+ );
175
+
176
+ mockDeleteWorkerRequest({ name: "my-script" });
177
+ await runWrangler("delete --name my-script");
178
+ expect(std).toMatchInlineSnapshot(`
179
+ Object {
180
+ "debug": "",
181
+ "err": "",
182
+ "out": "🌀 Deleted asset namespace for Workers Site \\"__my-script-workers_sites_assets\\"
183
+ 🌀 Deleted asset namespace for Workers Site \\"__my-script-workers_sites_assets_preview\\"
184
+ Successfully deleted my-script",
185
+ "warn": "",
186
+ }
187
+ `);
188
+ });
87
189
  });
88
190
 
89
191
  /** Create a mock handler for the request to upload a worker script. */
@@ -114,3 +216,15 @@ function mockDeleteWorkerRequest(
114
216
  }
115
217
  );
116
218
  }
219
+
220
+ /** Create a mock handler for the request to get a list of all KV namespaces. */
221
+ function mockListKVNamespacesRequest(...namespaces: KVNamespaceInfo[]) {
222
+ setMockResponse(
223
+ "/accounts/:accountId/storage/kv/namespaces",
224
+ "GET",
225
+ ([_url, accountId]) => {
226
+ expect(accountId).toEqual("some-account-id");
227
+ return namespaces;
228
+ }
229
+ );
230
+ }
@@ -0,0 +1,91 @@
1
+ // import * as fs from "fs";
2
+ // import * as TOML from "@iarna/toml";
3
+ import { rest } from "msw";
4
+ import { mockAccountId, mockApiToken } from "./helpers/mock-account-id";
5
+ import { mockConsoleMethods } from "./helpers/mock-console";
6
+ import {
7
+ msw,
8
+ mswSuccessOauthHandlers,
9
+ mswSuccessUserHandlers,
10
+ } from "./helpers/msw";
11
+ import { mswSuccessDeployments } from "./helpers/msw";
12
+ import { runInTempDir } from "./helpers/run-in-tmp";
13
+ import { runWrangler } from "./helpers/run-wrangler";
14
+
15
+ describe("deployments", () => {
16
+ const std = mockConsoleMethods();
17
+ runInTempDir();
18
+ mockAccountId();
19
+ mockApiToken();
20
+ runInTempDir();
21
+
22
+ beforeEach(() => {
23
+ msw.use(
24
+ ...mswSuccessDeployments,
25
+ ...mswSuccessOauthHandlers,
26
+ ...mswSuccessUserHandlers,
27
+ rest.get(
28
+ "*/accounts/:accountId/workers/services/:scriptName",
29
+ (request, response, context) => {
30
+ expect(["undefined", "somethingElse"]).toContain(
31
+ request.params.scriptName
32
+ );
33
+
34
+ return response.once(
35
+ context.status(200),
36
+ context.json({
37
+ success: true,
38
+ errors: [],
39
+ messages: [],
40
+ result: {
41
+ default_environment: {
42
+ script: {
43
+ tag: "MOCK-TAG",
44
+ },
45
+ },
46
+ },
47
+ })
48
+ );
49
+ }
50
+ )
51
+ );
52
+ });
53
+
54
+ it("should log deployments", async () => {
55
+ await runWrangler("deployments");
56
+ expect(std.out).toMatchInlineSnapshot(`
57
+ "
58
+ Version ID: Galaxy-Class
59
+ Version number: 1701-E
60
+ Created on: 2021-01-01T00:00:00.000000Z
61
+ Author email: Jean-Luc-Picard@federation.org
62
+ Latest deploy: true
63
+
64
+ Version ID: Intrepid-Class
65
+ Version number: NCC-74656
66
+ Created on: 2021-02-02T00:00:00.000000Z
67
+ Author email: Kathryn-Janeway@federation.org
68
+ Latest deploy: false
69
+ "
70
+ `);
71
+ });
72
+
73
+ it("should log deployments for script with passed in name option", async () => {
74
+ await runWrangler("deployments --name somethingElse");
75
+ expect(std.out).toMatchInlineSnapshot(`
76
+ "
77
+ Version ID: Galaxy-Class
78
+ Version number: 1701-E
79
+ Created on: 2021-01-01T00:00:00.000000Z
80
+ Author email: Jean-Luc-Picard@federation.org
81
+ Latest deploy: true
82
+
83
+ Version ID: Intrepid-Class
84
+ Version number: NCC-74656
85
+ Created on: 2021-02-02T00:00:00.000000Z
86
+ Author email: Kathryn-Janeway@federation.org
87
+ Latest deploy: false
88
+ "
89
+ `);
90
+ });
91
+ });
@@ -0,0 +1,80 @@
1
+ import { rest } from "msw";
2
+
3
+ export type DeploymentListRes = {
4
+ versions: {
5
+ version_id: string;
6
+ version_number: string;
7
+ metadata: {
8
+ author_id: string;
9
+ author_email: string;
10
+ source: "api" | "dash" | "wrangler" | "terraform" | "other";
11
+ created_on: string;
12
+ modified_on: string;
13
+ };
14
+ preview: {
15
+ active: boolean;
16
+ url: string;
17
+ };
18
+ resources: {
19
+ script: string;
20
+ bindings: unknown[];
21
+ };
22
+ }[];
23
+ };
24
+
25
+ export const mswSuccessDeployments = [
26
+ rest.get(
27
+ "*/accounts/:accountId/workers/versions/by-script/:scriptTag",
28
+ (_, response, context) =>
29
+ response.once(
30
+ context.status(200),
31
+ context.json({
32
+ success: true,
33
+ errors: [],
34
+ messages: [],
35
+ result: {
36
+ versions: [
37
+ {
38
+ version_id: "Galaxy-Class",
39
+ version_number: "1701-E",
40
+ metadata: {
41
+ author_id: "Picard-Gamma-6-0-7-3",
42
+ author_email: "Jean-Luc-Picard@federation.org",
43
+ source: "wrangler",
44
+ created_on: "2021-01-01T00:00:00.000000Z",
45
+ modified_on: "2021-01-01T00:00:00.000000Z",
46
+ },
47
+ preview: {
48
+ active: true,
49
+ url: "https://example.com",
50
+ },
51
+ resources: {
52
+ script: "script.js",
53
+ bindings: [],
54
+ },
55
+ },
56
+ {
57
+ version_id: "Intrepid-Class",
58
+ version_number: "NCC-74656",
59
+ metadata: {
60
+ author_id: "Kathryn-Jane-Gamma-6-0-7-3",
61
+ author_email: "Kathryn-Janeway@federation.org",
62
+ source: "wrangler",
63
+ created_on: "2021-02-02T00:00:00.000000Z",
64
+ modified_on: "2021-02-02T00:00:00.000000Z",
65
+ },
66
+ preview: {
67
+ active: true,
68
+ url: "https://example.com",
69
+ },
70
+ resources: {
71
+ script: "script.js",
72
+ bindings: [],
73
+ },
74
+ },
75
+ ],
76
+ },
77
+ })
78
+ )
79
+ ),
80
+ ];
@@ -1,8 +1,9 @@
1
1
  import { setupServer } from "msw/node";
2
+ import { mswSuccessDeployments } from "./handlers/deployments";
2
3
  import { mswSuccessNamespacesHandlers } from "./handlers/namespaces";
3
4
  import { mswSuccessOauthHandlers } from "./handlers/oauth";
4
5
  import { mswSuccessR2handlers } from "./handlers/r2";
5
- import { default as mswScriptHandlers } from "./handlers/script";
6
+ import { default as mswSucessScriptHandlers } from "./handlers/script";
6
7
  import { mswSuccessUserHandlers } from "./handlers/user";
7
8
  export const msw = setupServer();
8
9
 
@@ -11,5 +12,6 @@ export {
11
12
  mswSuccessR2handlers,
12
13
  mswSuccessOauthHandlers,
13
14
  mswSuccessNamespacesHandlers,
14
- mswScriptHandlers,
15
+ mswSucessScriptHandlers,
16
+ mswSuccessDeployments,
15
17
  };
@@ -34,7 +34,7 @@ describe("wrangler", () => {
34
34
  wrangler init [name] 📥 Create a wrangler.toml configuration file
35
35
  wrangler dev [script] 👂 Start a local server for developing your worker
36
36
  wrangler publish [script] 🆙 Publish your Worker to Cloudflare.
37
- wrangler delete [script] 🗑 Delete your Worker from Cloudflare.
37
+ wrangler delete [script] 🗑 Delete your Worker from Cloudflare.
38
38
  wrangler tail [worker] 🦚 Starts a log tailing session for a published Worker.
39
39
  wrangler secret 🤫 Generate a secret that can be referenced in a Worker
40
40
  wrangler secret:bulk <json> 🗄️ Bulk upload secrets for a Worker
@@ -49,6 +49,7 @@ describe("wrangler", () => {
49
49
  wrangler login 🔓 Login to Cloudflare
50
50
  wrangler logout 🚪 Logout from Cloudflare
51
51
  wrangler whoami 🕵️ Retrieve your user info and test your auth config
52
+ wrangler types 📝 Generate types from bindings & module rules in config
52
53
 
53
54
  Flags:
54
55
  -c, --config Path to .toml configuration file [string]
@@ -76,7 +77,7 @@ describe("wrangler", () => {
76
77
  wrangler init [name] 📥 Create a wrangler.toml configuration file
77
78
  wrangler dev [script] 👂 Start a local server for developing your worker
78
79
  wrangler publish [script] 🆙 Publish your Worker to Cloudflare.
79
- wrangler delete [script] 🗑 Delete your Worker from Cloudflare.
80
+ wrangler delete [script] 🗑 Delete your Worker from Cloudflare.
80
81
  wrangler tail [worker] 🦚 Starts a log tailing session for a published Worker.
81
82
  wrangler secret 🤫 Generate a secret that can be referenced in a Worker
82
83
  wrangler secret:bulk <json> 🗄️ Bulk upload secrets for a Worker
@@ -91,6 +92,7 @@ describe("wrangler", () => {
91
92
  wrangler login 🔓 Login to Cloudflare
92
93
  wrangler logout 🚪 Logout from Cloudflare
93
94
  wrangler whoami 🕵️ Retrieve your user info and test your auth config
95
+ wrangler types 📝 Generate types from bindings & module rules in config
94
96
 
95
97
  Flags:
96
98
  -c, --config Path to .toml configuration file [string]
@@ -1306,7 +1306,7 @@ describe("init", () => {
1306
1306
  contents: {
1307
1307
  config: {
1308
1308
  compilerOptions: expect.objectContaining({
1309
- types: ["@cloudflare/workers-types"],
1309
+ types: ["@cloudflare/workers-types", "jest"],
1310
1310
  }),
1311
1311
  },
1312
1312
  error: undefined,
@@ -6,7 +6,7 @@ import { mockConsoleMethods } from "./helpers/mock-console";
6
6
  import { mockGetZoneFromHostRequest } from "./helpers/mock-get-zone-from-host";
7
7
  import { useMockIsTTY } from "./helpers/mock-istty";
8
8
  import { mockCollectKnownRoutesRequest } from "./helpers/mock-known-routes";
9
- import { msw, mswScriptHandlers } from "./helpers/msw";
9
+ import { msw, mswSucessScriptHandlers } from "./helpers/msw";
10
10
  import { runInTempDir } from "./helpers/run-in-tmp";
11
11
  import { runWrangler } from "./helpers/run-wrangler";
12
12
  import type {
@@ -18,7 +18,7 @@ import type {
18
18
  import type { RequestInit } from "undici";
19
19
  import type WebSocket from "ws";
20
20
  describe("tail", () => {
21
- beforeEach(() => msw.use(...mswScriptHandlers));
21
+ beforeEach(() => msw.use(...mswSucessScriptHandlers));
22
22
  runInTempDir();
23
23
  mockAccountId();
24
24
  mockApiToken();
@@ -0,0 +1,217 @@
1
+ import * as fs from "fs";
2
+ import * as TOML from "@iarna/toml";
3
+ import { mockConsoleMethods } from "./helpers/mock-console";
4
+ import { runInTempDir } from "./helpers/run-in-tmp";
5
+ import { runWrangler } from "./helpers/run-wrangler";
6
+ import type { Config } from "../config";
7
+ import type { CfWorkerInit } from "../worker";
8
+
9
+ const bindingsConfigMock: CfWorkerInit["bindings"] & {
10
+ rules: Config["rules"];
11
+ } = {
12
+ kv_namespaces: [{ binding: "TEST_KV_NAMESPACE", id: "1234" }],
13
+ vars: {
14
+ SOMETHING: "asdasdfasdf",
15
+ ANOTHER: "thing",
16
+ OBJECT_VAR: {
17
+ enterprise: "1701-D",
18
+ activeDuty: true,
19
+ captian: "Picard",
20
+ }, // We can assume the objects will be stringified
21
+ },
22
+ durable_objects: {
23
+ bindings: [
24
+ { name: "DURABLE_TEST1", class_name: "Durability1" },
25
+ { name: "DURABLE_TEST2", class_name: "Durability2" },
26
+ ],
27
+ },
28
+ r2_buckets: [
29
+ {
30
+ binding: "R2_BUCKET_BINDING",
31
+ bucket_name: "R2BUCKET_NAME_TEST",
32
+ },
33
+ ],
34
+ d1_databases: [
35
+ {
36
+ // @ts-expect-error This type is resolved in the function that handles creating BETA string
37
+ binding: "D1_TESTING_SOMETHING",
38
+ database_name: "D1_BINDING",
39
+ database_id: "1234",
40
+ },
41
+ ],
42
+ services: [{ binding: "SERVICE_BINDING", service: "SERVICE_NAME" }],
43
+ dispatch_namespaces: [
44
+ { binding: "NAMESPACE_BINDING", namespace: "NAMESPACE_ID" },
45
+ ],
46
+ logfwdr: {
47
+ schema: "LOGFWDER_SCHEMA",
48
+ bindings: [{ name: "LOGFWDR_BINDING", destination: "LOGFWDR_DESTINATION" }],
49
+ },
50
+ data_blobs: {
51
+ SOME_DATA_BLOB1: "SOME_DATA_BLOB1.bin",
52
+ SOME_DATA_BLOB2: "SOME_DATA_BLOB2.bin",
53
+ },
54
+ text_blobs: {
55
+ SOME_TEXT_BLOB1: "SOME_TEXT_BLOB1.txt",
56
+ SOME_TEXT_BLOB2: "SOME_TEXT_BLOB2.txt",
57
+ },
58
+ wasm_modules: { MODULE1: "module1.wasm", MODULE2: "module2.wasm" },
59
+ unsafe: [
60
+ {
61
+ // @ts-expect-error Unsafe bindings type is somewhat different in different places
62
+ bindings: [{ name: "testing_unsafe", type: "plain_text" }],
63
+ },
64
+ ],
65
+ rules: [
66
+ {
67
+ type: "Text",
68
+ globs: ["**/*.txt"],
69
+ fallthrough: true,
70
+ },
71
+ {
72
+ type: "Data",
73
+ globs: ["**/*.webp"],
74
+ fallthrough: true,
75
+ },
76
+ { type: "CompiledWasm", globs: ["**/*.wasm"], fallthrough: true },
77
+ ],
78
+ };
79
+
80
+ describe("generateTypes()", () => {
81
+ const std = mockConsoleMethods();
82
+ runInTempDir();
83
+
84
+ it("should log the interface type generated and declare modules", async () => {
85
+ fs.writeFileSync("./index.ts", "export default { async fetch () {} };");
86
+ fs.writeFileSync(
87
+ "./wrangler.toml",
88
+ TOML.stringify({
89
+ compatibility_date: "2022-01-12",
90
+ name: "test-name",
91
+ main: "./index.ts",
92
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
93
+ ...(bindingsConfigMock as any),
94
+ unsafe: bindingsConfigMock.unsafe?.at(0) ?? {},
95
+ }),
96
+ "utf-8"
97
+ );
98
+
99
+ await runWrangler("types");
100
+ expect(std.out).toMatchInlineSnapshot(`
101
+ "interface Env {
102
+ TEST_KV_NAMESPACE: KVNamespace;
103
+ SOMETHING: asdasdfasdf;
104
+ ANOTHER: thing;
105
+ OBJECT_VAR: {\\"enterprise\\":\\"1701-D\\",\\"activeDuty\\":true,\\"captian\\":\\"Picard\\"};
106
+ DURABLE_TEST1: DurableObjectNamespace;
107
+ DURABLE_TEST2: DurableObjectNamespace;
108
+ R2_BUCKET_BINDING: R2Bucket;
109
+ D1_TESTING_SOMETHING: D1Database;
110
+ SERVICE_BINDING: Fetcher;
111
+ NAMESPACE_BINDING: any;
112
+ LOGFWDR_SCHEMA: any;
113
+ SOME_DATA_BLOB1: ArrayBuffer;
114
+ SOME_DATA_BLOB2: ArrayBuffer;
115
+ SOME_TEXT_BLOB1: string;
116
+ SOME_TEXT_BLOB2: string;
117
+ testing_unsafe: any;
118
+ }
119
+ declare module \\"*.txt\\" {
120
+ const value: string;
121
+ export default value;
122
+ }
123
+ declare module \\"*.webp\\" {
124
+ const value: ArrayBuffer;
125
+ export default value;
126
+ }
127
+ declare module \\"*.wasm\\" {
128
+ const value: WebAssembly.Module;
129
+ export default value;
130
+ }"
131
+ `);
132
+ });
133
+
134
+ it("should create a DTS file at the location that the command is executed from", async () => {
135
+ fs.writeFileSync("./index.ts", "export default { async fetch () {} };");
136
+ fs.writeFileSync(
137
+ "./wrangler.toml",
138
+ TOML.stringify({
139
+ compatibility_date: "2022-01-12",
140
+ name: "test-name",
141
+ main: "./index.ts",
142
+ // @ts-expect-error This type is out of sync with the actual bindingsConfig type
143
+ vars: bindingsConfigMock.vars,
144
+ }),
145
+ "utf-8"
146
+ );
147
+ await runWrangler("types");
148
+ expect(fs.existsSync("./worker-configuration.d.ts")).toBe(true);
149
+ });
150
+
151
+ it("should not create DTS file if there is nothing in the config to generate types from", async () => {
152
+ fs.writeFileSync("./index.ts", "export default { async fetch () {} };");
153
+ fs.writeFileSync(
154
+ "./wrangler.toml",
155
+ TOML.stringify({
156
+ compatibility_date: "2022-01-12",
157
+ name: "test-name",
158
+ main: "./index.ts",
159
+ }),
160
+ "utf-8"
161
+ );
162
+ await runWrangler("types");
163
+ expect(fs.existsSync("./worker-configuration.d.ts")).toBe(false);
164
+ expect(std.out).toMatchInlineSnapshot(`""`);
165
+ });
166
+
167
+ it("should create a DTS file at the location that the command is executed from", async () => {
168
+ fs.writeFileSync(
169
+ "./worker-configuration.d.ts",
170
+ "NOT THE CONTENTS OF THE GENERATED FILE"
171
+ );
172
+ fs.writeFileSync("./index.ts", "export default { async fetch () {} };");
173
+ fs.writeFileSync(
174
+ "./wrangler.toml",
175
+ TOML.stringify({
176
+ compatibility_date: "2022-01-12",
177
+ name: "test-name",
178
+ main: "./index.ts",
179
+ // @ts-expect-error This type is out of sync with the actual bindingsConfig type
180
+ vars: bindingsConfigMock.vars,
181
+ }),
182
+ "utf-8"
183
+ );
184
+
185
+ await expect(runWrangler("types")).rejects.toMatchInlineSnapshot(
186
+ `[Error: A non-wrangler worker-configuration.d.ts already exists, please rename and try again.]`
187
+ );
188
+ expect(fs.existsSync("./worker-configuration.d.ts")).toBe(true);
189
+ });
190
+
191
+ it("should log the declare global type generated and declare modules", async () => {
192
+ fs.writeFileSync(
193
+ "./index.ts",
194
+ `addEventListener('fetch', event => { event.respondWith(handleRequest(event.request));
195
+ }); async function handleRequest(request) { return new Response('Hello worker!', {headers: { 'content-type': 'text/plain' },});}`
196
+ );
197
+ fs.writeFileSync(
198
+ "./wrangler.toml",
199
+ TOML.stringify({
200
+ compatibility_date: "2022-01-12",
201
+ name: "test-name",
202
+ main: "./index.ts",
203
+ // @ts-expect-error This type is out of sync with the actual bindingsConfig type
204
+ unsafe: bindingsConfigMock.unsafe?.at(0) ?? {},
205
+ }),
206
+ "utf-8"
207
+ );
208
+
209
+ await runWrangler("types");
210
+ expect(std.out).toMatchInlineSnapshot(`
211
+ "declare global {
212
+ testing_unsafe: any;
213
+ }
214
+ "
215
+ `);
216
+ });
217
+ });