wrangler 2.4.3 → 2.5.0

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/bin/wrangler.js CHANGED
@@ -62,15 +62,21 @@ Consider using a Node.js version manager such as https://volta.sh/ or https://gi
62
62
  ...process.argv.slice(2),
63
63
  ],
64
64
  {
65
- stdio: "inherit",
65
+ stdio: ["inherit", "inherit", "inherit", "ipc"],
66
66
  env: {
67
67
  ...process.env,
68
68
  NODE_EXTRA_CA_CERTS: pathToCACerts,
69
69
  },
70
70
  }
71
- ).on("exit", (code) =>
72
- process.exit(code === undefined || code === null ? 0 : code)
73
- );
71
+ )
72
+ .on("exit", (code) =>
73
+ process.exit(code === undefined || code === null ? 0 : code)
74
+ )
75
+ .on("message", (message) => {
76
+ if (process.send) {
77
+ process.send(message);
78
+ }
79
+ });
74
80
  }
75
81
 
76
82
  /**
@@ -95,11 +101,17 @@ function runDelegatedWrangler() {
95
101
  process.execPath,
96
102
  [resolvedBinaryPath, ...process.argv.slice(2)],
97
103
  {
98
- stdio: "inherit",
104
+ stdio: ["inherit", "inherit", "inherit", "ipc"],
99
105
  }
100
- ).on("exit", (code) =>
101
- process.exit(code === undefined || code === null ? 0 : code)
102
- );
106
+ )
107
+ .on("exit", (code) =>
108
+ process.exit(code === undefined || code === null ? 0 : code)
109
+ )
110
+ .on("message", (message) => {
111
+ if (process.send) {
112
+ process.send(message);
113
+ }
114
+ });
103
115
  }
104
116
 
105
117
  /**
@@ -5974,11 +5974,11 @@ function parseRedirects(input) {
5974
5974
 
5975
5975
  // src/miniflare-cli/assets.ts
5976
5976
  var import_mime = __toESM(require_mime());
5977
- import { fetch as miniflareFetch2 } from "@miniflare/core";
5978
5977
  import {
5979
5978
  Response as MiniflareResponse2,
5980
5979
  Request as MiniflareRequest2
5981
5980
  } from "@miniflare/core";
5981
+ import { upgradingFetch as miniflareFetch2 } from "@miniflare/web-sockets";
5982
5982
  import { watch } from "chokidar";
5983
5983
 
5984
5984
  // src/pages/hash.tsx
@@ -6000,7 +6000,12 @@ async function generateASSETSBinding(options) {
6000
6000
  try {
6001
6001
  const url = new URL(miniflareRequest.url);
6002
6002
  url.host = `localhost:${options.proxyPort}`;
6003
- return await miniflareFetch2(url, miniflareRequest);
6003
+ const proxyRequest = new MiniflareRequest2(url, miniflareRequest);
6004
+ if (proxyRequest.headers.get("Upgrade") === "websocket") {
6005
+ proxyRequest.headers.delete("Sec-WebSocket-Accept");
6006
+ proxyRequest.headers.delete("Sec-WebSocket-Key");
6007
+ }
6008
+ return await miniflareFetch2(proxyRequest);
6004
6009
  } catch (thrown) {
6005
6010
  options.log.error(new Error(`Could not proxy request: ${thrown}`));
6006
6011
  return new MiniflareResponse2(
@@ -6288,7 +6293,7 @@ async function main() {
6288
6293
  }
6289
6294
  process.send && process.send(
6290
6295
  JSON.stringify({
6291
- mfPort,
6296
+ port: mfPort,
6292
6297
  ready: true,
6293
6298
  durableObjectsPort: durableObjectsMfPort
6294
6299
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wrangler",
3
- "version": "2.4.3",
3
+ "version": "2.5.0",
4
4
  "description": "Command-line interface for all things Cloudflare Workers",
5
5
  "keywords": [
6
6
  "wrangler",
@@ -1,7 +1,8 @@
1
+ import { rest } from "msw";
1
2
  import { mockAccountId, mockApiToken } from "./helpers/mock-account-id";
2
- import { setMockResponse, unsetAllMocks } from "./helpers/mock-cfetch";
3
3
  import { mockConsoleMethods } from "./helpers/mock-console";
4
4
  import { mockConfirm } from "./helpers/mock-dialogs";
5
+ import { msw } from "./helpers/msw";
5
6
  import { runInTempDir } from "./helpers/run-in-tmp";
6
7
  import { runWrangler } from "./helpers/run-wrangler";
7
8
  import writeWranglerToml from "./helpers/write-wrangler-toml";
@@ -12,10 +13,6 @@ describe("delete", () => {
12
13
  mockApiToken();
13
14
  runInTempDir();
14
15
 
15
- afterEach(() => {
16
- unsetAllMocks();
17
- });
18
-
19
16
  const std = mockConsoleMethods();
20
17
 
21
18
  it("should delete an entire service by name", async () => {
@@ -107,14 +104,19 @@ describe("delete", () => {
107
104
  });
108
105
  mockListKVNamespacesRequest(...kvNamespaces);
109
106
  // 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
- }
107
+ msw.use(
108
+ rest.delete(
109
+ "*/accounts/:accountId/storage/kv/namespaces/id-for-my-script-site-ns",
110
+ (req, res, ctx) => {
111
+ expect(req.params.accountId).toEqual("some-account-id");
112
+ return res.once(
113
+ ctx.status(200),
114
+ ctx.json({ success: true, errors: [], messages: [], result: null })
115
+ );
116
+ }
117
+ )
117
118
  );
119
+
118
120
  mockDeleteWorkerRequest({ name: "my-script" });
119
121
  await runWrangler("delete --name my-script");
120
122
  expect(std).toMatchInlineSnapshot(`
@@ -155,22 +157,40 @@ describe("delete", () => {
155
157
  mockListKVNamespacesRequest(...kvNamespaces);
156
158
  // it should only try to delete the site namespace associated with this worker
157
159
 
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
- }
160
+ msw.use(
161
+ rest.delete(
162
+ "*/accounts/:accountId/storage/kv/namespaces/id-for-my-script-site-ns",
163
+ (req, res, ctx) => {
164
+ expect(req.params.accountId).toEqual("some-account-id");
165
+ return res.once(
166
+ ctx.status(200),
167
+ ctx.json({
168
+ success: true,
169
+ errors: [],
170
+ messages: [],
171
+ result: {},
172
+ })
173
+ );
174
+ }
175
+ )
165
176
  );
166
177
 
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
- }
178
+ msw.use(
179
+ rest.delete(
180
+ "*/accounts/:accountId/storage/kv/namespaces/id-for-my-script-site-preview-ns",
181
+ (req, res, ctx) => {
182
+ expect(req.params.accountId).toEqual("some-account-id");
183
+ return res.once(
184
+ ctx.status(200),
185
+ ctx.json({
186
+ success: true,
187
+ errors: [],
188
+ messages: [],
189
+ result: {},
190
+ })
191
+ );
192
+ }
193
+ )
174
194
  );
175
195
 
176
196
  mockDeleteWorkerRequest({ name: "my-script" });
@@ -197,34 +217,47 @@ function mockDeleteWorkerRequest(
197
217
  } = {}
198
218
  ) {
199
219
  const { env, legacyEnv, name } = options;
200
- setMockResponse(
201
- // there's no special handling for environments yet
202
- "/accounts/:accountId/workers/services/:scriptName",
203
- "DELETE",
204
- async ([_url, accountId, scriptName], { method }, queryParams) => {
205
- expect(accountId).toEqual("some-account-id");
206
- expect(method).toEqual("DELETE");
207
- expect(scriptName).toEqual(
208
- legacyEnv && env
209
- ? `${name || "test-name"}-${env}`
210
- : `${name || "test-name"}`
211
- );
220
+ msw.use(
221
+ rest.delete(
222
+ "*/accounts/:accountId/workers/services/:scriptName",
223
+ (req, res, ctx) => {
224
+ expect(req.params.accountId).toEqual("some-account-id");
225
+ expect(req.params.scriptName).toEqual(
226
+ legacyEnv && env
227
+ ? `${name ?? "test-name"}-${env}`
228
+ : `${name ?? "test-name"}`
229
+ );
212
230
 
213
- expect(queryParams.get("force")).toEqual("true");
231
+ expect(req.url.searchParams.get("force")).toEqual("true");
214
232
 
215
- return null;
216
- }
233
+ return res.once(
234
+ ctx.status(200),
235
+ ctx.json({
236
+ success: true,
237
+ errors: [],
238
+ messages: [],
239
+ result: null,
240
+ })
241
+ );
242
+ }
243
+ )
217
244
  );
218
245
  }
219
246
 
220
247
  /** Create a mock handler for the request to get a list of all KV namespaces. */
221
248
  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
- }
249
+ msw.use(
250
+ rest.get("*/accounts/:accountId/storage/kv/namespaces", (req, res, ctx) => {
251
+ expect(req.params.accountId).toEqual("some-account-id");
252
+ return res.once(
253
+ ctx.status(200),
254
+ ctx.json({
255
+ success: true,
256
+ errors: [],
257
+ messages: [],
258
+ result: namespaces,
259
+ })
260
+ );
261
+ })
229
262
  );
230
263
  }
@@ -792,7 +792,7 @@ describe("wrangler dev", () => {
792
792
  });
793
793
  fs.writeFileSync("index.js", `export default {};`);
794
794
  await runWrangler("dev");
795
- expect((Dev as jest.Mock).mock.calls[0][0].ip).toEqual("0.0.0.0");
795
+ expect((Dev as jest.Mock).mock.calls[0][0].initialIp).toEqual("0.0.0.0");
796
796
  expect(std.out).toMatchInlineSnapshot(`""`);
797
797
  expect(std.warn).toMatchInlineSnapshot(`""`);
798
798
  expect(std.err).toMatchInlineSnapshot(`""`);
@@ -807,7 +807,7 @@ describe("wrangler dev", () => {
807
807
  });
808
808
  fs.writeFileSync("index.js", `export default {};`);
809
809
  await runWrangler("dev");
810
- expect((Dev as jest.Mock).mock.calls[0][0].ip).toEqual("1.2.3.4");
810
+ expect((Dev as jest.Mock).mock.calls[0][0].initialIp).toEqual("1.2.3.4");
811
811
  expect(std.out).toMatchInlineSnapshot(`""`);
812
812
  expect(std.warn).toMatchInlineSnapshot(`""`);
813
813
  expect(std.err).toMatchInlineSnapshot(`""`);
@@ -822,7 +822,7 @@ describe("wrangler dev", () => {
822
822
  });
823
823
  fs.writeFileSync("index.js", `export default {};`);
824
824
  await runWrangler("dev --ip=5.6.7.8");
825
- expect((Dev as jest.Mock).mock.calls[0][0].ip).toEqual("5.6.7.8");
825
+ expect((Dev as jest.Mock).mock.calls[0][0].initialIp).toEqual("5.6.7.8");
826
826
  expect(std.out).toMatchInlineSnapshot(`""`);
827
827
  expect(std.warn).toMatchInlineSnapshot(`""`);
828
828
  expect(std.err).toMatchInlineSnapshot(`""`);
@@ -933,7 +933,7 @@ describe("wrangler dev", () => {
933
933
  });
934
934
  fs.writeFileSync("index.js", `export default {};`);
935
935
  await runWrangler("dev");
936
- expect((Dev as jest.Mock).mock.calls[0][0].port).toEqual(8787);
936
+ expect((Dev as jest.Mock).mock.calls[0][0].initialPort).toEqual(8787);
937
937
  expect(std.out).toMatchInlineSnapshot(`""`);
938
938
  expect(std.warn).toMatchInlineSnapshot(`""`);
939
939
  expect(std.err).toMatchInlineSnapshot(`""`);
@@ -951,7 +951,7 @@ describe("wrangler dev", () => {
951
951
  (getPort as jest.Mock).mockResolvedValue(98765);
952
952
 
953
953
  await runWrangler("dev");
954
- expect((Dev as jest.Mock).mock.calls[0][0].port).toEqual(8888);
954
+ expect((Dev as jest.Mock).mock.calls[0][0].initialPort).toEqual(8888);
955
955
  expect(std.out).toMatchInlineSnapshot(`""`);
956
956
  expect(std.warn).toMatchInlineSnapshot(`""`);
957
957
  expect(std.err).toMatchInlineSnapshot(`""`);
@@ -985,7 +985,7 @@ describe("wrangler dev", () => {
985
985
  (getPort as jest.Mock).mockResolvedValue(98765);
986
986
 
987
987
  await runWrangler("dev --port=9999");
988
- expect((Dev as jest.Mock).mock.calls[0][0].port).toEqual(9999);
988
+ expect((Dev as jest.Mock).mock.calls[0][0].initialPort).toEqual(9999);
989
989
  expect(std.out).toMatchInlineSnapshot(`""`);
990
990
  expect(std.warn).toMatchInlineSnapshot(`""`);
991
991
  expect(std.err).toMatchInlineSnapshot(`""`);
@@ -1000,7 +1000,7 @@ describe("wrangler dev", () => {
1000
1000
  (getPort as jest.Mock).mockResolvedValue(98765);
1001
1001
 
1002
1002
  await runWrangler("dev");
1003
- expect((Dev as jest.Mock).mock.calls[0][0].port).toEqual(98765);
1003
+ expect((Dev as jest.Mock).mock.calls[0][0].initialPort).toEqual(98765);
1004
1004
  expect(std.out).toMatchInlineSnapshot(`""`);
1005
1005
  expect(std.warn).toMatchInlineSnapshot(`""`);
1006
1006
  expect(std.err).toMatchInlineSnapshot(`""`);
@@ -1030,7 +1030,7 @@ describe("wrangler dev", () => {
1030
1030
  });
1031
1031
  fs.writeFileSync("index.js", `export default {};`);
1032
1032
  await runWrangler("dev");
1033
- expect((Dev as jest.Mock).mock.calls[0][0].ip).toEqual("0.0.0.0");
1033
+ expect((Dev as jest.Mock).mock.calls[0][0].initialIp).toEqual("0.0.0.0");
1034
1034
  expect(std.out).toMatchInlineSnapshot(`
1035
1035
  "Your worker has access to the following bindings:
1036
1036
  - Durable Objects:
@@ -42,10 +42,13 @@ export const mockOAuthFlow = () => {
42
42
  * at the OAuth URL, it will automatically trigger the callback URL on the mock HttpServer that
43
43
  * we have created as part of the call to `mockOAuthFlow()`.
44
44
  */
45
- const mockOAuthServerCallback = () => {
45
+ const mockOAuthServerCallback = (
46
+ respondWith?: "timeout" | "success" | "failure" | GrantResponseOptions
47
+ ) => {
46
48
  (
47
49
  openInBrowser as jest.MockedFunction<typeof openInBrowser>
48
50
  ).mockImplementation(async (url: string) => {
51
+ if (respondWith) mockGrantAuthorization({ respondWith });
49
52
  // We don't support the grant response timing out.
50
53
  if (oauthGrantResponse === "timeout") {
51
54
  throw "unimplemented";
@@ -68,6 +71,7 @@ export const mockOAuthFlow = () => {
68
71
  });
69
72
  };
70
73
 
74
+ //TODO: this can just handled in `mockOAuthServerCallback`
71
75
  const mockGrantAuthorization = ({
72
76
  respondWith,
73
77
  }: {
@@ -13,24 +13,19 @@ export const mswSuccessOauthHandlers = [
13
13
  );
14
14
  }),
15
15
  // revoke access token
16
- rest.post(
17
- "https://dash.cloudflare.com/oauth2/revoke",
18
- (_, response, context) =>
19
- response.once(context.status(200), context.text(""))
16
+ rest.post("*/oauth2/revoke", (_, response, context) =>
17
+ response.once(context.status(200), context.text(""))
20
18
  ),
21
19
  // exchange (auth code | refresh token) for access token
22
- rest.post(
23
- "https://dash.cloudflare.com/oauth2/token",
24
- (_, response, context) => {
25
- return response.once(
26
- context.status(200),
27
- context.json({
28
- access_token: "test-access-token",
29
- expires_in: 100000,
30
- refresh_token: "test-refresh-token",
31
- scope: "account:read",
32
- })
33
- );
34
- }
35
- ),
20
+ rest.post("*/oauth2/token", (_, response, context) => {
21
+ return response.once(
22
+ context.status(200),
23
+ context.json({
24
+ access_token: "test-access-token",
25
+ expires_in: 100000,
26
+ refresh_token: "test-refresh-token",
27
+ scope: "account:read",
28
+ })
29
+ );
30
+ }),
36
31
  ];
@@ -0,0 +1,47 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { rest } from "msw";
4
+ import { getGlobalWranglerConfigPath } from "../global-wrangler-config-path";
5
+ import { USER_AUTH_CONFIG_FILE, writeAuthConfigFile } from "../user";
6
+ import { mockConsoleMethods } from "./helpers/mock-console";
7
+ import { msw } from "./helpers/msw";
8
+ import { runInTempDir } from "./helpers/run-in-tmp";
9
+ import { runWrangler } from "./helpers/run-wrangler";
10
+
11
+ describe("logout", () => {
12
+ runInTempDir();
13
+ const std = mockConsoleMethods();
14
+
15
+ it("should exit with a message stating the user is not logged in", async () => {
16
+ await runWrangler("logout");
17
+ expect(std.out).toMatchInlineSnapshot(`"Not logged in, exiting..."`);
18
+ });
19
+
20
+ it("should logout user that has been properly logged in", async () => {
21
+ writeAuthConfigFile({
22
+ oauth_token: "some-oauth-tok",
23
+ refresh_token: "some-refresh-tok",
24
+ });
25
+ // Make sure that logout removed the config file containing the auth tokens.
26
+ const config = path.join(
27
+ getGlobalWranglerConfigPath(),
28
+ USER_AUTH_CONFIG_FILE
29
+ );
30
+ let counter = 0;
31
+ msw.use(
32
+ rest.post("*/oauth2/revoke", (_, response, context) => {
33
+ // Make sure that we made the request to logout.
34
+ counter += 1;
35
+ response.once(context.status(200), context.text(""));
36
+ })
37
+ );
38
+
39
+ expect(fs.existsSync(config)).toBeTruthy();
40
+
41
+ await runWrangler("logout");
42
+
43
+ expect(std.out).toMatchInlineSnapshot(`"Successfully logged out."`);
44
+ expect(fs.existsSync(config)).toBeFalsy();
45
+ expect(counter).toBe(1);
46
+ });
47
+ });