wrangler 0.0.0-e22f9d7 → 0.0.0-e2a26a0

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.
Files changed (54) hide show
  1. package/bin/wrangler.js +2 -2
  2. package/package.json +15 -10
  3. package/pages/functions/buildWorker.ts +1 -1
  4. package/pages/functions/filepath-routing.test.ts +21 -13
  5. package/pages/functions/filepath-routing.ts +38 -28
  6. package/pages/functions/routes.ts +8 -6
  7. package/pages/functions/template-worker.ts +16 -24
  8. package/src/__tests__/dev.test.tsx +7 -3
  9. package/src/__tests__/{clipboardy-mock.js → helpers/clipboardy-mock.js} +0 -0
  10. package/src/__tests__/helpers/cmd-shim.d.ts +11 -0
  11. package/src/__tests__/helpers/mock-account-id.ts +30 -0
  12. package/src/__tests__/helpers/mock-bin.ts +33 -0
  13. package/src/__tests__/{mock-cfetch.ts → helpers/mock-cfetch.ts} +49 -13
  14. package/src/__tests__/helpers/mock-console.ts +56 -0
  15. package/src/__tests__/{mock-dialogs.ts → helpers/mock-dialogs.ts} +1 -1
  16. package/src/__tests__/helpers/mock-kv.ts +40 -0
  17. package/src/__tests__/helpers/mock-user.ts +27 -0
  18. package/src/__tests__/helpers/run-in-tmp.ts +29 -0
  19. package/src/__tests__/helpers/run-wrangler.ts +14 -0
  20. package/src/__tests__/index.test.ts +312 -56
  21. package/src/__tests__/jest.setup.ts +17 -2
  22. package/src/__tests__/kv.test.ts +344 -316
  23. package/src/__tests__/logout.test.ts +50 -0
  24. package/src/__tests__/package-manager.test.ts +206 -0
  25. package/src/__tests__/publish.test.ts +1222 -0
  26. package/src/__tests__/secret.test.ts +210 -0
  27. package/src/__tests__/whoami.test.tsx +86 -0
  28. package/src/api/form_data.ts +10 -7
  29. package/src/api/preview.ts +2 -2
  30. package/src/api/worker.ts +3 -3
  31. package/src/cfetch/index.ts +14 -14
  32. package/src/cfetch/internal.ts +40 -8
  33. package/src/config.ts +162 -8
  34. package/src/dev.tsx +103 -53
  35. package/src/dialogs.tsx +2 -2
  36. package/src/index.tsx +438 -311
  37. package/src/inspect.ts +80 -23
  38. package/src/kv.tsx +9 -1
  39. package/src/module-collection.ts +5 -6
  40. package/src/package-manager.ts +120 -0
  41. package/src/pages.tsx +41 -26
  42. package/src/paths.ts +26 -0
  43. package/src/proxy.ts +78 -10
  44. package/src/publish.ts +98 -52
  45. package/src/sites.tsx +175 -53
  46. package/src/user.tsx +51 -59
  47. package/src/whoami.tsx +69 -0
  48. package/templates/new-worker.js +15 -0
  49. package/templates/new-worker.ts +15 -0
  50. package/{static-asset-facade.js → templates/static-asset-facade.js} +0 -0
  51. package/wrangler-dist/cli.js +111479 -110187
  52. package/wrangler-dist/cli.js.map +3 -3
  53. package/src/__tests__/run-in-tmp.ts +0 -19
  54. package/src/__tests__/run-wrangler.ts +0 -32
package/src/user.tsx CHANGED
@@ -205,25 +205,25 @@
205
205
  limitations under the License.
206
206
  */
207
207
 
208
- import React from "react";
209
- import { render, Text } from "ink";
210
- import Table from "ink-table";
211
- import SelectInput from "ink-select-input";
212
- import fetch from "node-fetch";
208
+ import assert from "node:assert";
213
209
  import { webcrypto as crypto } from "node:crypto";
214
- import { TextEncoder } from "node:util";
215
- import open from "open";
216
- import url from "node:url";
217
- import http from "node:http";
218
210
  import { readFile, writeFile, rm, mkdir } from "node:fs/promises";
211
+ import http from "node:http";
212
+ import os from "node:os";
219
213
  import path from "node:path";
220
214
  import process from "node:process";
221
- import os from "node:os";
215
+ import url from "node:url";
216
+ import { TextEncoder } from "node:util";
222
217
  import TOML from "@iarna/toml";
223
- import assert from "node:assert";
224
- import type { ParsedUrlQuery } from "node:querystring";
218
+ import { render, Text } from "ink";
219
+ import SelectInput from "ink-select-input";
220
+ import Table from "ink-table";
221
+ import open from "open";
222
+ import React from "react";
223
+ import { fetch } from "undici";
225
224
  import { CF_API_BASE_URL } from "./cfetch";
226
- import type { Response } from "node-fetch";
225
+ import type { ParsedUrlQuery } from "node:querystring";
226
+ import type { Response } from "undici";
227
227
 
228
228
  /**
229
229
  * An implementation of rfc6749#section-4.1 and rfc7636.
@@ -254,38 +254,37 @@ interface AccessToken {
254
254
  expiry: string;
255
255
  }
256
256
 
257
- type Scope =
258
- | "account:read"
259
- | "user:read"
260
- | "workers:write"
261
- | "workers_kv:write"
262
- | "workers_routes:write"
263
- | "workers_scripts:write"
264
- | "workers_tail:read"
265
- | "zone:read"
266
- | "offline_access"; // this should be included by default
267
-
268
- const Scopes: Scope[] = [
269
- "account:read",
270
- "user:read",
271
- "workers:write",
272
- "workers_kv:write",
273
- "workers_routes:write",
274
- "workers_scripts:write",
275
- "workers_tail:read",
276
- "zone:read",
277
- ];
278
-
279
- const ScopeDescriptions = [
280
- "See your account info such as account details, analytics, and memberships.",
281
- "See your user info such as name, email address, and account memberships.",
282
- "See and change Cloudflare Workers data such as zones, KV storage, namespaces, scripts, and routes.",
283
- "See and change Cloudflare Workers KV Storage data such as keys and namespaces.",
284
- "See and change Cloudflare Workers data such as filters and routes.",
285
- "See and change Cloudflare Workers scripts, durable objects, subdomains, triggers, and tail data.",
286
- "See Cloudflare Workers tail and script data.",
287
- "Grants read level access to account zone.",
288
- ];
257
+ const Scopes = {
258
+ "account:read":
259
+ "See your account info such as account details, analytics, and memberships.",
260
+ "user:read":
261
+ "See your user info such as name, email address, and account memberships.",
262
+ "workers:write":
263
+ "See and change Cloudflare Workers data such as zones, KV storage, namespaces, scripts, and routes.",
264
+ "workers_kv:write":
265
+ "See and change Cloudflare Workers KV Storage data such as keys and namespaces.",
266
+ "workers_routes:write":
267
+ "See and change Cloudflare Workers data such as filters and routes.",
268
+ "workers_scripts:write":
269
+ "See and change Cloudflare Workers scripts, durable objects, subdomains, triggers, and tail data.",
270
+ "workers_tail:read": "See Cloudflare Workers tail and script data.",
271
+ "zone:read": "Grants read level access to account zone.",
272
+ } as const;
273
+
274
+ /**
275
+ * The possible keys for a Scope.
276
+ *
277
+ * "offline_access" is automatically included.
278
+ */
279
+ type Scope = keyof typeof Scopes | "offline_access";
280
+
281
+ const ScopeKeys = Object.keys(Scopes) as Scope[];
282
+
283
+ export function validateScopeKeys(
284
+ scopes: string[]
285
+ ): scopes is typeof ScopeKeys {
286
+ return scopes.every((scope) => Scopes[scope]);
287
+ }
289
288
 
290
289
  const CLIENT_ID = "54d11594-84e4-41aa-b438-e81b8fa78ee7";
291
290
  const AUTH_URL = "https://dash.cloudflare.com/oauth2/auth";
@@ -344,15 +343,12 @@ function throwIfNotInitialised() {
344
343
  }
345
344
  }
346
345
 
347
- export function getAPIToken(): string {
346
+ export function getAPIToken(): string | undefined {
348
347
  if (process.env.CF_API_TOKEN) {
349
348
  return process.env.CF_API_TOKEN;
350
349
  }
351
-
352
350
  throwIfNotInitialised();
353
- // `throwIfNotInitialised()` ensures that the accessToken is guaranteed to be defined.
354
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
355
- return LocalState.accessToken!.value;
351
+ return LocalState.accessToken?.value;
356
352
  }
357
353
 
358
354
  interface AccessContext {
@@ -550,7 +546,7 @@ function isReturningFromAuthServer(query: ParsedUrlQuery): boolean {
550
546
  return true;
551
547
  }
552
548
 
553
- export async function getAuthURL(scopes?: string[]): Promise<string> {
549
+ export async function getAuthURL(scopes = ScopeKeys): Promise<string> {
554
550
  const { codeChallenge, codeVerifier } = await generatePKCECodes();
555
551
  const stateQueryParam = generateRandomState(RECOMMENDED_STATE_LENGTH);
556
552
 
@@ -560,16 +556,12 @@ export async function getAuthURL(scopes?: string[]): Promise<string> {
560
556
  stateQueryParam,
561
557
  });
562
558
 
563
- // TODO: verify that the scopes passed are legit
564
-
565
559
  return (
566
560
  AUTH_URL +
567
561
  `?response_type=code&` +
568
562
  `client_id=${encodeURIComponent(CLIENT_ID)}&` +
569
563
  `redirect_uri=${encodeURIComponent(CALLBACK_URL)}&` +
570
- `scope=${encodeURIComponent(
571
- (scopes || Scopes).concat("offline_access").join(" ")
572
- )}&` +
564
+ `scope=${encodeURIComponent(scopes.concat("offline_access").join(" "))}&` +
573
565
  `state=${stateQueryParam}&` +
574
566
  `code_challenge=${encodeURIComponent(codeChallenge)}&` +
575
567
  `code_challenge_method=S256`
@@ -794,7 +786,7 @@ expiration_time = "${tokenData.token?.expiry}"
794
786
  }
795
787
 
796
788
  type LoginProps = {
797
- scopes?: string[];
789
+ scopes?: Scope[];
798
790
  };
799
791
 
800
792
  export async function loginOrRefreshIfRequired(): Promise<boolean> {
@@ -947,9 +939,9 @@ export async function logout(): Promise<void> {
947
939
  export function listScopes(): void {
948
940
  throwIfNotInitialised();
949
941
  console.log("💁 Available scopes:");
950
- const data = Scopes.map((scope, index) => ({
942
+ const data = ScopeKeys.map((scope) => ({
951
943
  Scope: scope,
952
- Description: ScopeDescriptions[index],
944
+ Description: Scopes[scope],
953
945
  }));
954
946
  render(<Table data={data} />);
955
947
  // TODO: maybe a good idea to show usage here
package/src/whoami.tsx ADDED
@@ -0,0 +1,69 @@
1
+ import { Text, render } from "ink";
2
+ import Table from "ink-table";
3
+ import React from "react";
4
+ import { fetchListResult, fetchResult } from "./cfetch";
5
+ import { getAPIToken } from "./user";
6
+
7
+ export async function whoami() {
8
+ console.log("Getting User settings...");
9
+ const user = await getUserInfo();
10
+ render(<WhoAmI user={user}></WhoAmI>);
11
+ }
12
+
13
+ export function WhoAmI({ user }: { user: UserInfo | undefined }) {
14
+ return user ? (
15
+ <>
16
+ <Email tokenType={user.authType} email={user.email}></Email>
17
+ <Accounts accounts={user.accounts}></Accounts>
18
+ </>
19
+ ) : (
20
+ <Text>You are not authenticated. Please run `wrangler login`.</Text>
21
+ );
22
+ }
23
+
24
+ function Email(props: { tokenType: string; email: string }) {
25
+ return (
26
+ <Text>
27
+ 👋 You are logged in with an {props.tokenType} Token, associated with the
28
+ email &apos;{props.email}&apos;!
29
+ </Text>
30
+ );
31
+ }
32
+
33
+ function Accounts(props: { accounts: AccountInfo[] }) {
34
+ const accounts = props.accounts.map((account) => ({
35
+ "Account Name": account.name,
36
+ "Account ID": account.id,
37
+ }));
38
+ return <Table data={accounts}></Table>;
39
+ }
40
+
41
+ export interface UserInfo {
42
+ apiToken: string;
43
+ authType: string;
44
+ email: string;
45
+ accounts: AccountInfo[];
46
+ }
47
+
48
+ export async function getUserInfo(): Promise<UserInfo | undefined> {
49
+ const apiToken = getAPIToken();
50
+ return apiToken
51
+ ? {
52
+ apiToken,
53
+ authType: "OAuth",
54
+ email: await getEmail(),
55
+ accounts: await getAccounts(),
56
+ }
57
+ : undefined;
58
+ }
59
+
60
+ async function getEmail(): Promise<string> {
61
+ const { email } = await fetchResult<{ email: string }>("/user");
62
+ return email;
63
+ }
64
+
65
+ type AccountInfo = { name: string; id: string };
66
+
67
+ async function getAccounts(): Promise<AccountInfo[]> {
68
+ return await fetchListResult<AccountInfo>("/accounts");
69
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Welcome to Cloudflare Workers! This is your first worker.
3
+ *
4
+ * - Run `npx wrangler dev src/index.js` in your terminal to start a development server
5
+ * - Open a browser tab at http://localhost:8787/ to see your worker in action
6
+ * - Run `npx wrangler publish src/index.js --name my-worker` to deploy your worker
7
+ *
8
+ * Learn more at https://developers.cloudflare.com/workers/
9
+ */
10
+
11
+ export default {
12
+ async fetch(request) {
13
+ return new Response("Hello World!");
14
+ },
15
+ };
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Welcome to Cloudflare Workers! This is your first worker.
3
+ *
4
+ * - Run `wrangler dev src/index.ts` in your terminal to start a development server
5
+ * - Open a browser tab at http://localhost:8787/ to see your worker in action
6
+ * - Run `wrangler publish src/index.ts --name my-worker` to deploy your worker
7
+ *
8
+ * Learn more at https://developers.cloudflare.com/workers/
9
+ */
10
+
11
+ export default {
12
+ async fetch(request: Request): Promise<Response> {
13
+ return new Response("Hello World!");
14
+ },
15
+ };