wrangler 0.0.0-e7a0cd5b → 0.0.0-e7cf0caa
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 +3 -3
- package/bin/wrangler.js +30 -10
- package/miniflare-dist/index.mjs +126 -74
- package/package.json +27 -19
- package/src/__tests__/api-dev.test.ts +65 -36
- package/src/__tests__/api-devregistry.test.ts +121 -0
- package/src/__tests__/api.test.ts +27 -5
- package/src/__tests__/configuration.test.ts +567 -86
- package/src/__tests__/d1/d1.test.ts +82 -0
- package/src/__tests__/d1/execute.test.ts +66 -0
- package/src/__tests__/d1/migrate.test.ts +157 -0
- package/src/__tests__/d1/splitter.test.ts +255 -0
- package/src/__tests__/delete.test.ts +91 -49
- package/src/__tests__/deployments.test.ts +330 -56
- package/src/__tests__/dev.test.tsx +198 -90
- package/src/__tests__/generate.test.ts +12 -10
- package/src/__tests__/guess-worker-format.test.ts +35 -0
- package/src/__tests__/helpers/end-event-loop.ts +6 -0
- package/src/__tests__/helpers/mock-auth-domain.ts +20 -0
- package/src/__tests__/helpers/mock-console.ts +6 -0
- package/src/__tests__/helpers/mock-dialogs.ts +71 -85
- package/src/__tests__/helpers/mock-get-pages-upload-token.ts +25 -0
- package/src/__tests__/helpers/mock-get-zone-from-host.ts +8 -5
- package/src/__tests__/helpers/mock-known-routes.ts +7 -2
- package/src/__tests__/helpers/mock-kv.ts +29 -16
- package/src/__tests__/helpers/mock-oauth-flow.ts +103 -92
- package/src/__tests__/helpers/mock-process.ts +8 -13
- package/src/__tests__/helpers/mock-set-timeout.ts +16 -0
- package/src/__tests__/helpers/msw/blob-worker.cjs +19 -0
- package/src/__tests__/helpers/msw/handlers/deployments.ts +128 -27
- package/src/__tests__/helpers/msw/handlers/namespaces.ts +18 -41
- package/src/__tests__/helpers/msw/handlers/oauth.ts +13 -18
- package/src/__tests__/helpers/msw/handlers/r2.ts +14 -34
- package/src/__tests__/helpers/msw/handlers/script.ts +9 -28
- package/src/__tests__/helpers/msw/handlers/user.ts +13 -24
- package/src/__tests__/helpers/msw/handlers/zones.ts +6 -8
- package/src/__tests__/helpers/msw/index.ts +32 -1
- package/src/__tests__/helpers/msw/read-file-sync.js +61 -0
- package/src/__tests__/helpers/string-dynamic-values-matcher.ts +28 -0
- package/src/__tests__/helpers/worker-scripts/parent-worker.js +4 -1
- package/src/__tests__/index.test.ts +90 -72
- package/src/__tests__/init.test.ts +927 -631
- package/src/__tests__/jest.setup.ts +19 -42
- package/src/__tests__/kv.test.ts +355 -231
- package/src/__tests__/logger.test.ts +68 -2
- package/src/__tests__/logout.test.ts +47 -0
- package/src/__tests__/metrics.test.ts +94 -51
- package/src/__tests__/middleware.scheduled.test.ts +42 -32
- package/src/__tests__/middleware.test.ts +212 -122
- package/src/__tests__/mtls-certificates.test.ts +588 -0
- package/src/__tests__/pages/deployment-list.test.ts +80 -0
- package/src/__tests__/pages/functions-build.test.ts +452 -0
- package/src/__tests__/pages/pages.test.ts +81 -0
- package/src/__tests__/pages/project-create.test.ts +63 -0
- package/src/__tests__/pages/project-list.test.ts +110 -0
- package/src/__tests__/pages/project-upload.test.ts +500 -0
- package/src/__tests__/pages/publish.test.ts +2864 -0
- package/src/__tests__/pages-deployment-tail.test.ts +955 -0
- package/src/__tests__/parse.test.ts +106 -0
- package/src/__tests__/publish.test.ts +1615 -852
- package/src/__tests__/pubsub.test.ts +226 -100
- package/src/__tests__/queues.test.ts +238 -77
- package/src/__tests__/r2.test.ts +55 -57
- package/src/__tests__/secret.test.ts +179 -130
- package/src/__tests__/tail.test.ts +267 -109
- package/src/__tests__/test-old-node-version.js +3 -3
- package/src/__tests__/traverse-module-graph.test.ts +220 -0
- package/src/__tests__/tsconfig-sanity.ts +12 -0
- package/src/__tests__/tsconfig.json +8 -0
- package/src/__tests__/tsconfig.tsbuildinfo +1 -0
- package/src/__tests__/type-generation.test.ts +43 -26
- package/src/__tests__/user.test.ts +35 -72
- package/src/__tests__/whoami.test.tsx +8 -114
- package/src/__tests__/worker-namespace.test.ts +83 -69
- package/src/api/dev.ts +168 -60
- package/src/api/index.ts +10 -1
- package/src/api/mtls-certificate.ts +148 -0
- package/src/api/pages/create-worker-bundle-contents.ts +76 -0
- package/src/api/pages/index.ts +5 -0
- package/src/api/pages/publish.tsx +355 -0
- package/src/bundle.ts +263 -140
- package/src/cfetch/index.ts +0 -2
- package/src/cfetch/internal.ts +16 -21
- package/src/cli.ts +4 -4
- package/src/config/config.ts +14 -7
- package/src/config/environment.ts +79 -24
- package/src/config/index.ts +99 -38
- package/src/config/validation-helpers.ts +1 -1
- package/src/config/validation.ts +248 -19
- package/src/create-worker-preview.ts +19 -8
- package/src/create-worker-upload-form.ts +60 -22
- package/src/d1/backups.tsx +43 -42
- package/src/d1/constants.ts +2 -0
- package/src/d1/create.tsx +44 -30
- package/src/d1/{delete.tsx → delete.ts} +11 -14
- package/src/d1/execute.tsx +209 -151
- package/src/d1/index.ts +31 -7
- package/src/d1/list.tsx +22 -10
- package/src/d1/migrations/apply.tsx +212 -0
- package/src/d1/migrations/create.tsx +79 -0
- package/src/d1/migrations/helpers.ts +172 -0
- package/src/d1/migrations/index.ts +3 -0
- package/src/d1/migrations/list.tsx +95 -0
- package/src/d1/migrations/options.ts +23 -0
- package/src/d1/options.ts +12 -2
- package/src/d1/splitter.ts +161 -0
- package/src/d1/{types.tsx → types.ts} +11 -0
- package/src/d1/utils.ts +12 -2
- package/src/delete.ts +8 -16
- package/src/deployments.ts +340 -46
- package/src/deprecated/index.ts +8 -302
- package/src/dev/dev.tsx +57 -44
- package/src/dev/local.tsx +294 -91
- package/src/dev/remote.tsx +32 -3
- package/src/dev/start-server.ts +89 -68
- package/src/dev/use-esbuild.ts +17 -18
- package/src/dev/validate-dev-props.ts +9 -0
- package/src/{dev-registry.tsx → dev-registry.ts} +2 -1
- package/src/dev.tsx +178 -118
- package/src/dialogs.ts +136 -0
- package/src/dispatch-namespace.ts +21 -17
- package/src/docs/index.ts +97 -0
- package/src/entry.ts +19 -11
- package/src/environment-variables/factory.ts +88 -0
- package/src/environment-variables/misc-variables.ts +30 -0
- package/src/generate/index.ts +298 -0
- package/src/git-client.ts +15 -4
- package/src/{index.tsx → index.ts} +137 -63
- package/src/init.ts +249 -187
- package/src/inspect.ts +16 -1
- package/src/jest.d.ts +4 -0
- package/src/kv/index.ts +15 -17
- package/src/logger.ts +32 -5
- package/src/metrics/metrics-config.ts +3 -3
- package/src/metrics/send-event.ts +6 -1
- package/src/miniflare-cli/assets.ts +64 -28
- package/src/miniflare-cli/index.ts +4 -7
- package/src/miniflare-cli/tsconfig.json +9 -0
- package/src/miniflare-cli/tsconfig.tsbuildinfo +1 -0
- package/src/miniflare-cli/types.ts +11 -0
- package/src/module-collection.ts +91 -25
- package/src/mtls-certificate/cli.ts +155 -0
- package/src/pages/build.ts +410 -0
- package/src/pages/buildFunctions.ts +140 -0
- package/src/pages/deployment-tails.ts +281 -0
- package/src/pages/deployments.tsx +11 -33
- package/src/pages/{dev.tsx → dev.ts} +147 -124
- package/src/pages/errors.ts +1 -0
- package/src/pages/functions/buildPlugin.ts +72 -69
- package/src/pages/functions/buildWorker.ts +249 -114
- package/src/pages/functions/tsconfig.json +8 -0
- package/src/pages/functions/tsconfig.tsbuildinfo +1 -0
- package/src/pages/{functions.tsx → functions.ts} +8 -4
- package/src/pages/{index.tsx → index.ts} +11 -3
- package/src/pages/projects.tsx +12 -22
- package/src/pages/prompt-select-project.tsx +31 -0
- package/src/pages/publish.tsx +45 -214
- package/src/pages/types.ts +6 -9
- package/src/pages/upload.tsx +58 -14
- package/src/pages/utils.ts +14 -3
- package/src/parse.ts +23 -1
- package/src/paths.ts +1 -1
- package/src/proxy.ts +5 -0
- package/src/publish/index.ts +20 -16
- package/src/publish/publish.ts +72 -47
- package/src/pubsub/{pubsub-commands.tsx → pubsub-commands.ts} +19 -20
- package/src/queues/cli/commands/consumer/add.ts +24 -24
- package/src/queues/cli/commands/consumer/index.ts +3 -6
- package/src/queues/cli/commands/consumer/remove.ts +11 -18
- package/src/queues/cli/commands/create.ts +8 -8
- package/src/queues/cli/commands/delete.ts +8 -8
- package/src/queues/cli/commands/index.ts +6 -4
- package/src/queues/cli/commands/list.ts +8 -8
- package/src/queues/client.ts +1 -0
- package/src/queues/utils.ts +18 -0
- package/src/r2/constants.ts +4 -0
- package/src/r2/helpers.ts +1 -0
- package/src/r2/index.ts +40 -28
- package/src/secret/index.ts +14 -17
- package/src/{sites.tsx → sites.ts} +1 -1
- package/src/tail/createTail.ts +94 -3
- package/src/tail/filters.ts +1 -1
- package/src/tail/index.ts +8 -11
- package/src/tail/printing.ts +15 -0
- package/src/traverse-module-graph.ts +53 -0
- package/src/tsconfig-sanity.ts +16 -0
- package/src/type-generation.ts +79 -57
- package/src/user/access.ts +0 -1
- package/src/user/auth-variables.ts +113 -0
- package/src/user/choose-account.tsx +1 -31
- package/src/user/index.ts +0 -1
- package/src/user/{user.tsx → user.ts} +123 -82
- package/src/utils/render.ts +93 -0
- package/src/{whoami.tsx → whoami.ts} +37 -71
- package/src/worker.ts +35 -3
- package/src/yargs-types.ts +22 -5
- package/templates/__tests__/tsconfig-sanity.ts +12 -0
- package/templates/__tests__/tsconfig.json +8 -0
- package/templates/__tests__/tsconfig.tsbuildinfo +1 -0
- package/templates/checked-fetch.js +9 -3
- package/templates/d1-beta-facade.js +95 -25
- package/templates/facade.d.ts +14 -0
- package/templates/first-party-worker-module-facade.ts +4 -3
- package/templates/format-dev-errors.ts +8 -6
- package/templates/gitignore +1 -0
- package/templates/init-tests/test-jest-new-worker.js +3 -5
- package/templates/init-tests/test-vitest-new-worker.js +3 -5
- package/templates/init-tests/test-vitest-new-worker.ts +25 -0
- package/templates/middleware/loader-modules.ts +2 -2
- package/templates/middleware/loader-sw.ts +51 -31
- package/templates/middleware/middleware-miniflare3-json-error.ts +32 -0
- package/templates/new-worker.ts +3 -0
- package/templates/pages-dev-pipeline.ts +4 -1
- package/templates/pages-shim.ts +4 -1
- package/templates/pages-template-plugin.ts +19 -10
- package/templates/serve-static-assets.ts +17 -14
- package/templates/service-bindings-module-facade.js +1 -0
- package/templates/tsconfig-sanity.ts +11 -0
- package/templates/tsconfig.init.json +105 -0
- package/templates/tsconfig.json +5 -103
- package/templates/tsconfig.tsbuildinfo +1 -0
- package/wrangler-dist/cli.d.ts +826 -77
- package/wrangler-dist/cli.js +130734 -140838
- package/wrangler-dist/wasm-sync.wasm +0 -0
- package/src/__tests__/api-devregistry.test.js +0 -57
- package/src/__tests__/d1.test.ts +0 -72
- package/src/__tests__/dialogs.test.tsx +0 -40
- package/src/__tests__/helpers/mock-cfetch.ts +0 -333
- package/src/__tests__/pages.test.ts +0 -2223
- package/src/dialogs.tsx +0 -163
- package/src/environment-variables.ts +0 -50
- package/src/pages/build.tsx +0 -238
- package/src/user/env-vars.ts +0 -46
- package/templates/experimental-local-cache-stubs.js +0 -27
- /package/src/{bundle-reporter.tsx → bundle-reporter.ts} +0 -0
- /package/src/dev/{get-local-persistence-path.tsx → get-local-persistence-path.ts} +0 -0
- /package/src/pages/{hash.tsx → hash.ts} +0 -0
|
@@ -4,11 +4,8 @@ import { mockConsoleMethods } from "./helpers/mock-console";
|
|
|
4
4
|
import { runInTempDir } from "./helpers/run-in-tmp";
|
|
5
5
|
import { runWrangler } from "./helpers/run-wrangler";
|
|
6
6
|
import type { Config } from "../config";
|
|
7
|
-
import type { CfWorkerInit } from "../worker";
|
|
8
7
|
|
|
9
|
-
const bindingsConfigMock:
|
|
10
|
-
rules: Config["rules"];
|
|
11
|
-
} = {
|
|
8
|
+
const bindingsConfigMock: Partial<Config> = {
|
|
12
9
|
kv_namespaces: [{ binding: "TEST_KV_NAMESPACE", id: "1234" }],
|
|
13
10
|
vars: {
|
|
14
11
|
SOMETHING: "asdasdfasdf",
|
|
@@ -19,6 +16,22 @@ const bindingsConfigMock: CfWorkerInit["bindings"] & {
|
|
|
19
16
|
captian: "Picard",
|
|
20
17
|
}, // We can assume the objects will be stringified
|
|
21
18
|
},
|
|
19
|
+
queues: {
|
|
20
|
+
producers: [
|
|
21
|
+
{
|
|
22
|
+
binding: "TEST_QUEUE_BINDING",
|
|
23
|
+
queue: "TEST_QUEUE",
|
|
24
|
+
},
|
|
25
|
+
],
|
|
26
|
+
consumers: [
|
|
27
|
+
{
|
|
28
|
+
queue: "my-queue",
|
|
29
|
+
max_batch_size: 10,
|
|
30
|
+
max_batch_timeout: 1,
|
|
31
|
+
max_retries: 3,
|
|
32
|
+
},
|
|
33
|
+
],
|
|
34
|
+
},
|
|
22
35
|
durable_objects: {
|
|
23
36
|
bindings: [
|
|
24
37
|
{ name: "DURABLE_TEST1", class_name: "Durability1" },
|
|
@@ -33,13 +46,18 @@ const bindingsConfigMock: CfWorkerInit["bindings"] & {
|
|
|
33
46
|
],
|
|
34
47
|
d1_databases: [
|
|
35
48
|
{
|
|
36
|
-
// @ts-expect-error This type is resolved in the function that handles creating BETA string
|
|
37
49
|
binding: "D1_TESTING_SOMETHING",
|
|
38
50
|
database_name: "D1_BINDING",
|
|
39
51
|
database_id: "1234",
|
|
40
52
|
},
|
|
41
53
|
],
|
|
42
54
|
services: [{ binding: "SERVICE_BINDING", service: "SERVICE_NAME" }],
|
|
55
|
+
analytics_engine_datasets: [
|
|
56
|
+
{
|
|
57
|
+
binding: "AE_DATASET_BINDING",
|
|
58
|
+
dataset: "AE_DATASET_TEST",
|
|
59
|
+
},
|
|
60
|
+
],
|
|
43
61
|
dispatch_namespaces: [
|
|
44
62
|
{ binding: "NAMESPACE_BINDING", namespace: "NAMESPACE_ID" },
|
|
45
63
|
],
|
|
@@ -56,12 +74,10 @@ const bindingsConfigMock: CfWorkerInit["bindings"] & {
|
|
|
56
74
|
SOME_TEXT_BLOB2: "SOME_TEXT_BLOB2.txt",
|
|
57
75
|
},
|
|
58
76
|
wasm_modules: { MODULE1: "module1.wasm", MODULE2: "module2.wasm" },
|
|
59
|
-
unsafe:
|
|
60
|
-
{
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
},
|
|
64
|
-
],
|
|
77
|
+
unsafe: {
|
|
78
|
+
bindings: [{ name: "testing_unsafe", type: "plain_text" }],
|
|
79
|
+
metadata: { some_key: "some_value" },
|
|
80
|
+
},
|
|
65
81
|
rules: [
|
|
66
82
|
{
|
|
67
83
|
type: "Text",
|
|
@@ -89,10 +105,9 @@ describe("generateTypes()", () => {
|
|
|
89
105
|
compatibility_date: "2022-01-12",
|
|
90
106
|
name: "test-name",
|
|
91
107
|
main: "./index.ts",
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
}),
|
|
108
|
+
...bindingsConfigMock,
|
|
109
|
+
unsafe: bindingsConfigMock.unsafe ?? {},
|
|
110
|
+
} as unknown as TOML.JsonMap),
|
|
96
111
|
"utf-8"
|
|
97
112
|
);
|
|
98
113
|
|
|
@@ -100,14 +115,15 @@ describe("generateTypes()", () => {
|
|
|
100
115
|
expect(std.out).toMatchInlineSnapshot(`
|
|
101
116
|
"interface Env {
|
|
102
117
|
TEST_KV_NAMESPACE: KVNamespace;
|
|
103
|
-
SOMETHING: asdasdfasdf;
|
|
104
|
-
ANOTHER: thing;
|
|
118
|
+
SOMETHING: \\"asdasdfasdf\\";
|
|
119
|
+
ANOTHER: \\"thing\\";
|
|
105
120
|
OBJECT_VAR: {\\"enterprise\\":\\"1701-D\\",\\"activeDuty\\":true,\\"captian\\":\\"Picard\\"};
|
|
106
121
|
DURABLE_TEST1: DurableObjectNamespace;
|
|
107
122
|
DURABLE_TEST2: DurableObjectNamespace;
|
|
108
123
|
R2_BUCKET_BINDING: R2Bucket;
|
|
109
124
|
D1_TESTING_SOMETHING: D1Database;
|
|
110
125
|
SERVICE_BINDING: Fetcher;
|
|
126
|
+
AE_DATASET_BINDING: AnalyticsEngineDataset;
|
|
111
127
|
NAMESPACE_BINDING: any;
|
|
112
128
|
LOGFWDR_SCHEMA: any;
|
|
113
129
|
SOME_DATA_BLOB1: ArrayBuffer;
|
|
@@ -115,6 +131,7 @@ describe("generateTypes()", () => {
|
|
|
115
131
|
SOME_TEXT_BLOB1: string;
|
|
116
132
|
SOME_TEXT_BLOB2: string;
|
|
117
133
|
testing_unsafe: any;
|
|
134
|
+
TEST_QUEUE_BINDING: Queue;
|
|
118
135
|
}
|
|
119
136
|
declare module \\"*.txt\\" {
|
|
120
137
|
const value: string;
|
|
@@ -139,9 +156,9 @@ describe("generateTypes()", () => {
|
|
|
139
156
|
compatibility_date: "2022-01-12",
|
|
140
157
|
name: "test-name",
|
|
141
158
|
main: "./index.ts",
|
|
142
|
-
// @ts-expect-error This type is out of sync with the actual bindingsConfig type
|
|
143
159
|
vars: bindingsConfigMock.vars,
|
|
144
|
-
|
|
160
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
161
|
+
} as any),
|
|
145
162
|
"utf-8"
|
|
146
163
|
);
|
|
147
164
|
await runWrangler("types");
|
|
@@ -159,6 +176,7 @@ describe("generateTypes()", () => {
|
|
|
159
176
|
}),
|
|
160
177
|
"utf-8"
|
|
161
178
|
);
|
|
179
|
+
|
|
162
180
|
await runWrangler("types");
|
|
163
181
|
expect(fs.existsSync("./worker-configuration.d.ts")).toBe(false);
|
|
164
182
|
expect(std.out).toMatchInlineSnapshot(`""`);
|
|
@@ -176,9 +194,8 @@ describe("generateTypes()", () => {
|
|
|
176
194
|
compatibility_date: "2022-01-12",
|
|
177
195
|
name: "test-name",
|
|
178
196
|
main: "./index.ts",
|
|
179
|
-
// @ts-expect-error This type is out of sync with the actual bindingsConfig type
|
|
180
197
|
vars: bindingsConfigMock.vars,
|
|
181
|
-
}),
|
|
198
|
+
} as TOML.JsonMap),
|
|
182
199
|
"utf-8"
|
|
183
200
|
);
|
|
184
201
|
|
|
@@ -200,16 +217,16 @@ describe("generateTypes()", () => {
|
|
|
200
217
|
compatibility_date: "2022-01-12",
|
|
201
218
|
name: "test-name",
|
|
202
219
|
main: "./index.ts",
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
}),
|
|
220
|
+
unsafe: bindingsConfigMock.unsafe ?? {},
|
|
221
|
+
} as TOML.JsonMap),
|
|
206
222
|
"utf-8"
|
|
207
223
|
);
|
|
208
224
|
|
|
209
225
|
await runWrangler("types");
|
|
210
226
|
expect(std.out).toMatchInlineSnapshot(`
|
|
211
|
-
"
|
|
212
|
-
|
|
227
|
+
"export {};
|
|
228
|
+
declare global {
|
|
229
|
+
const testing_unsafe: any;
|
|
213
230
|
}
|
|
214
231
|
"
|
|
215
232
|
`);
|
|
@@ -1,18 +1,22 @@
|
|
|
1
|
-
import
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import fetchMock from "jest-fetch-mock";
|
|
4
|
-
import { getGlobalWranglerConfigPath } from "../global-wrangler-config-path";
|
|
1
|
+
import { rest } from "msw";
|
|
5
2
|
import { CI } from "../is-ci";
|
|
6
3
|
import {
|
|
7
4
|
loginOrRefreshIfRequired,
|
|
8
5
|
readAuthConfigFile,
|
|
9
6
|
requireAuth,
|
|
10
|
-
USER_AUTH_CONFIG_FILE,
|
|
11
7
|
writeAuthConfigFile,
|
|
12
8
|
} from "../user";
|
|
13
9
|
import { mockConsoleMethods } from "./helpers/mock-console";
|
|
14
10
|
import { useMockIsTTY } from "./helpers/mock-istty";
|
|
15
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
mockExchangeRefreshTokenForAccessToken,
|
|
13
|
+
mockOAuthFlow,
|
|
14
|
+
} from "./helpers/mock-oauth-flow";
|
|
15
|
+
import {
|
|
16
|
+
msw,
|
|
17
|
+
mswSuccessOauthHandlers,
|
|
18
|
+
mswSuccessUserHandlers,
|
|
19
|
+
} from "./helpers/msw";
|
|
16
20
|
import { runInTempDir } from "./helpers/run-in-tmp";
|
|
17
21
|
import { runWrangler } from "./helpers/run-wrangler";
|
|
18
22
|
import type { Config } from "../config";
|
|
@@ -22,41 +26,43 @@ describe("User", () => {
|
|
|
22
26
|
let isCISpy: jest.SpyInstance;
|
|
23
27
|
runInTempDir();
|
|
24
28
|
const std = mockConsoleMethods();
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
mockGrantAccessToken,
|
|
28
|
-
mockGrantAuthorization,
|
|
29
|
-
mockRevokeAuthorization,
|
|
30
|
-
mockExchangeRefreshTokenForAccessToken,
|
|
31
|
-
} = mockOAuthFlow();
|
|
32
|
-
|
|
29
|
+
// TODO: Implement these two mocks with MSW
|
|
30
|
+
const { mockOAuthServerCallback } = mockOAuthFlow();
|
|
33
31
|
const { setIsTTY } = useMockIsTTY();
|
|
34
32
|
|
|
35
33
|
beforeEach(() => {
|
|
34
|
+
msw.use(...mswSuccessOauthHandlers, ...mswSuccessUserHandlers);
|
|
36
35
|
isCISpy = jest.spyOn(CI, "isCI").mockReturnValue(false);
|
|
37
36
|
});
|
|
38
37
|
|
|
39
38
|
describe("login", () => {
|
|
40
39
|
it("should login a user when `wrangler login` is run", async () => {
|
|
41
|
-
mockOAuthServerCallback();
|
|
42
|
-
|
|
43
|
-
|
|
40
|
+
mockOAuthServerCallback("success");
|
|
41
|
+
|
|
42
|
+
let counter = 0;
|
|
43
|
+
msw.use(
|
|
44
|
+
rest.post("*/oauth2/token", async (_, response, context) => {
|
|
45
|
+
counter += 1;
|
|
46
|
+
|
|
47
|
+
return response.once(
|
|
48
|
+
context.json({
|
|
49
|
+
access_token: "test-access-token",
|
|
50
|
+
expires_in: 100000,
|
|
51
|
+
refresh_token: "test-refresh-token",
|
|
52
|
+
scope: "account:read",
|
|
53
|
+
})
|
|
54
|
+
);
|
|
55
|
+
})
|
|
56
|
+
);
|
|
44
57
|
|
|
45
58
|
await runWrangler("login");
|
|
46
59
|
|
|
47
|
-
expect(
|
|
48
|
-
accessTokenRequest.expected.url
|
|
49
|
-
);
|
|
50
|
-
expect(accessTokenRequest.actual.method).toEqual(
|
|
51
|
-
accessTokenRequest.expected.method
|
|
52
|
-
);
|
|
53
|
-
|
|
60
|
+
expect(counter).toBe(1);
|
|
54
61
|
expect(std.out).toMatchInlineSnapshot(`
|
|
55
62
|
"Attempting to login via OAuth...
|
|
56
|
-
Opening a link in your default browser: https://dash.cloudflare.com/oauth2/auth?response_type=code&client_id=54d11594-84e4-41aa-b438-e81b8fa78ee7&redirect_uri=http%3A%2F%2Flocalhost%3A8976%2Foauth%2Fcallback&scope=account%3Aread%20user%3Aread%20workers%3Awrite%20workers_kv%3Awrite%20workers_routes%3Awrite%20workers_scripts%3Awrite%20workers_tail%3Aread%20d1%3Awrite%20pages%3Awrite%20zone%3Aread%20offline_access&state=MOCK_STATE_PARAM&code_challenge=MOCK_CODE_CHALLENGE&code_challenge_method=S256
|
|
63
|
+
Opening a link in your default browser: https://dash.cloudflare.com/oauth2/auth?response_type=code&client_id=54d11594-84e4-41aa-b438-e81b8fa78ee7&redirect_uri=http%3A%2F%2Flocalhost%3A8976%2Foauth%2Fcallback&scope=account%3Aread%20user%3Aread%20workers%3Awrite%20workers_kv%3Awrite%20workers_routes%3Awrite%20workers_scripts%3Awrite%20workers_tail%3Aread%20d1%3Awrite%20pages%3Awrite%20zone%3Aread%20ssl_certs%3Awrite%20offline_access&state=MOCK_STATE_PARAM&code_challenge=MOCK_CODE_CHALLENGE&code_challenge_method=S256
|
|
57
64
|
Successfully logged in."
|
|
58
65
|
`);
|
|
59
|
-
|
|
60
66
|
expect(readAuthConfigFile()).toEqual<UserAuthConfig>({
|
|
61
67
|
api_token: undefined,
|
|
62
68
|
oauth_token: "test-access-token",
|
|
@@ -67,71 +73,28 @@ describe("User", () => {
|
|
|
67
73
|
});
|
|
68
74
|
});
|
|
69
75
|
|
|
70
|
-
|
|
71
|
-
it("should exit with a message stating the user is not logged in", async () => {
|
|
72
|
-
await runWrangler("logout");
|
|
73
|
-
expect(std.out).toMatchInlineSnapshot(`"Not logged in, exiting..."`);
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
it("should logout user that has been properly logged in", async () => {
|
|
77
|
-
writeAuthConfigFile({
|
|
78
|
-
oauth_token: "some-oauth-tok",
|
|
79
|
-
refresh_token: "some-refresh-tok",
|
|
80
|
-
});
|
|
81
|
-
const outcome = mockRevokeAuthorization();
|
|
82
|
-
|
|
83
|
-
await runWrangler("logout");
|
|
84
|
-
|
|
85
|
-
expect(outcome.actual.url).toEqual(
|
|
86
|
-
"https://dash.cloudflare.com/oauth2/revoke"
|
|
87
|
-
);
|
|
88
|
-
expect(outcome.actual.method).toEqual("POST");
|
|
89
|
-
|
|
90
|
-
expect(std.out).toMatchInlineSnapshot(`"Successfully logged out."`);
|
|
91
|
-
|
|
92
|
-
// Make sure that we made the request to logout.
|
|
93
|
-
expect(fetchMock).toHaveBeenCalledTimes(1);
|
|
94
|
-
|
|
95
|
-
// Make sure that logout removed the config file containing the auth tokens.
|
|
96
|
-
const config = path.join(
|
|
97
|
-
getGlobalWranglerConfigPath(),
|
|
98
|
-
USER_AUTH_CONFIG_FILE
|
|
99
|
-
);
|
|
100
|
-
expect(fs.existsSync(config)).toBeFalsy();
|
|
101
|
-
});
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
// TODO: Improve OAuth mocking to handle `/token` endpoints from different calls
|
|
105
|
-
it("should handle errors for failed token refresh", async () => {
|
|
76
|
+
it("should handle errors for failed token refresh in a non-interactive environment", async () => {
|
|
106
77
|
setIsTTY(false);
|
|
107
78
|
writeAuthConfigFile({
|
|
108
79
|
oauth_token: "hunter2",
|
|
109
80
|
refresh_token: "Order 66",
|
|
110
81
|
});
|
|
111
|
-
mockExchangeRefreshTokenForAccessToken({
|
|
112
|
-
respondWith: "badResponse",
|
|
113
|
-
});
|
|
82
|
+
mockExchangeRefreshTokenForAccessToken({ respondWith: "refreshError" });
|
|
114
83
|
|
|
115
84
|
// Handles the requireAuth error throw from failed login that is unhandled due to directly calling it here
|
|
116
85
|
await expect(
|
|
117
86
|
requireAuth({} as Config)
|
|
118
87
|
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
119
|
-
`"In a non-interactive environment, it's necessary to set a CLOUDFLARE_API_TOKEN environment variable for wrangler to work. Please go to https://developers.cloudflare.com/api/
|
|
88
|
+
`"In a non-interactive environment, it's necessary to set a CLOUDFLARE_API_TOKEN environment variable for wrangler to work. Please go to https://developers.cloudflare.com/fundamentals/api/get-started/create-token/ for instructions on how to create an api token, and assign its value to CLOUDFLARE_API_TOKEN."`
|
|
120
89
|
);
|
|
121
90
|
});
|
|
122
91
|
|
|
123
92
|
it("should confirm no error message when refresh is successful", async () => {
|
|
124
93
|
setIsTTY(false);
|
|
125
|
-
mockOAuthServerCallback();
|
|
126
94
|
writeAuthConfigFile({
|
|
127
95
|
oauth_token: "hunter2",
|
|
128
96
|
refresh_token: "Order 66",
|
|
129
97
|
});
|
|
130
|
-
mockGrantAuthorization({ respondWith: "success" });
|
|
131
|
-
|
|
132
|
-
mockExchangeRefreshTokenForAccessToken({
|
|
133
|
-
respondWith: "refreshSuccess",
|
|
134
|
-
});
|
|
135
98
|
|
|
136
99
|
// Handles the requireAuth error throw from failed login that is unhandled due to directly calling it here
|
|
137
100
|
await expect(requireAuth({} as Config)).rejects.toThrowError();
|
|
@@ -1,17 +1,15 @@
|
|
|
1
|
-
import { render } from "ink-testing-library";
|
|
2
1
|
import { rest } from "msw";
|
|
3
|
-
import React from "react";
|
|
4
2
|
import { writeAuthConfigFile } from "../user";
|
|
5
|
-
import { getUserInfo
|
|
3
|
+
import { getUserInfo } from "../whoami";
|
|
6
4
|
import { mockConsoleMethods } from "./helpers/mock-console";
|
|
7
5
|
import { useMockIsTTY } from "./helpers/mock-istty";
|
|
8
6
|
import {
|
|
7
|
+
createFetchResult,
|
|
9
8
|
msw,
|
|
10
9
|
mswSuccessOauthHandlers,
|
|
11
10
|
mswSuccessUserHandlers,
|
|
12
11
|
} from "./helpers/msw";
|
|
13
12
|
import { runInTempDir } from "./helpers/run-in-tmp";
|
|
14
|
-
import type { UserInfo } from "../whoami";
|
|
15
13
|
|
|
16
14
|
describe("getUserInfo()", () => {
|
|
17
15
|
const ENV_COPY = process.env;
|
|
@@ -47,18 +45,14 @@ describe("getUserInfo()", () => {
|
|
|
47
45
|
msw.use(
|
|
48
46
|
rest.get("*/user", (_, res, ctx) => {
|
|
49
47
|
return res.once(
|
|
50
|
-
ctx.
|
|
51
|
-
|
|
52
|
-
success: false,
|
|
53
|
-
errors: [
|
|
48
|
+
ctx.json(
|
|
49
|
+
createFetchResult({}, false, [
|
|
54
50
|
{
|
|
55
51
|
code: 9109,
|
|
56
52
|
message: "Uauthorized to access requested resource",
|
|
57
53
|
},
|
|
58
|
-
]
|
|
59
|
-
|
|
60
|
-
result: {},
|
|
61
|
-
})
|
|
54
|
+
])
|
|
55
|
+
)
|
|
62
56
|
);
|
|
63
57
|
}),
|
|
64
58
|
rest.get("*/accounts", (request, res, ctx) => {
|
|
@@ -74,15 +68,7 @@ describe("getUserInfo()", () => {
|
|
|
74
68
|
"host": "api.cloudflare.com",
|
|
75
69
|
}
|
|
76
70
|
`);
|
|
77
|
-
return res.once(
|
|
78
|
-
ctx.status(200),
|
|
79
|
-
ctx.json({
|
|
80
|
-
success: true,
|
|
81
|
-
errors: [],
|
|
82
|
-
messages: [],
|
|
83
|
-
result: [],
|
|
84
|
-
})
|
|
85
|
-
);
|
|
71
|
+
return res.once(ctx.json(createFetchResult([])));
|
|
86
72
|
})
|
|
87
73
|
);
|
|
88
74
|
const userInfo = await getUserInfo();
|
|
@@ -174,7 +160,7 @@ describe("getUserInfo()", () => {
|
|
|
174
160
|
await getUserInfo();
|
|
175
161
|
|
|
176
162
|
expect(std.warn).toMatchInlineSnapshot(`
|
|
177
|
-
"[33m▲ [43;33m[[43;30mWARNING[43;33m][0m [1mIt looks like you have used Wrangler
|
|
163
|
+
"[33m▲ [43;33m[[43;30mWARNING[43;33m][0m [1mIt looks like you have used Wrangler v1's \`config\` command to login with an API token.[0m
|
|
178
164
|
|
|
179
165
|
This is no longer supported in the current version of Wrangler.
|
|
180
166
|
If you wish to authenticate via an API token then please set the \`CLOUDFLARE_API_TOKEN\`
|
|
@@ -184,95 +170,3 @@ describe("getUserInfo()", () => {
|
|
|
184
170
|
`);
|
|
185
171
|
});
|
|
186
172
|
});
|
|
187
|
-
|
|
188
|
-
describe("WhoAmI component", () => {
|
|
189
|
-
it("should return undefined if there is no user", async () => {
|
|
190
|
-
const { lastFrame } = render(<WhoAmI user={undefined}></WhoAmI>);
|
|
191
|
-
|
|
192
|
-
expect(lastFrame()).toMatchInlineSnapshot(
|
|
193
|
-
`"You are not authenticated. Please run \`wrangler login\`."`
|
|
194
|
-
);
|
|
195
|
-
});
|
|
196
|
-
|
|
197
|
-
it("should display the user's email, accounts and OAuth scopes", async () => {
|
|
198
|
-
const user: UserInfo = {
|
|
199
|
-
authType: "OAuth Token",
|
|
200
|
-
apiToken: "some-oauth-token",
|
|
201
|
-
email: "user@example.com",
|
|
202
|
-
tokenPermissions: ["scope1:read", "scope2:write", "scope3"],
|
|
203
|
-
accounts: [
|
|
204
|
-
{ name: "Account One", id: "account-1" },
|
|
205
|
-
{ name: "Account Two", id: "account-2" },
|
|
206
|
-
{ name: "Account Three", id: "account-3" },
|
|
207
|
-
],
|
|
208
|
-
};
|
|
209
|
-
|
|
210
|
-
const { lastFrame } = render(<WhoAmI user={user}></WhoAmI>);
|
|
211
|
-
|
|
212
|
-
expect(lastFrame()).toContain(
|
|
213
|
-
"You are logged in with an OAuth Token, associated with the email 'user@example.com'!"
|
|
214
|
-
);
|
|
215
|
-
expect(lastFrame()).toMatch(/Account Name .+ Account ID/);
|
|
216
|
-
expect(lastFrame()).toMatch(/Account One .+ account-1/);
|
|
217
|
-
expect(lastFrame()).toMatch(/Account Two .+ account-2/);
|
|
218
|
-
expect(lastFrame()).toMatch(/Account Three .+ account-3/);
|
|
219
|
-
expect(lastFrame()).toContain(
|
|
220
|
-
"Token Permissions: If scopes are missing, you may need to logout and re-login."
|
|
221
|
-
);
|
|
222
|
-
expect(lastFrame()).toContain("- scope1 (read)");
|
|
223
|
-
expect(lastFrame()).toContain("- scope2 (write)");
|
|
224
|
-
expect(lastFrame()).toContain("- scope3");
|
|
225
|
-
});
|
|
226
|
-
|
|
227
|
-
// For the case where the cache hasn't updated to include the scopes array
|
|
228
|
-
it("should display the user's email and accounts, but no OAuth scopes if none provided", async () => {
|
|
229
|
-
const user: UserInfo = {
|
|
230
|
-
authType: "OAuth Token",
|
|
231
|
-
apiToken: "some-oauth-token",
|
|
232
|
-
email: "user@example.com",
|
|
233
|
-
tokenPermissions: undefined,
|
|
234
|
-
accounts: [
|
|
235
|
-
{ name: "Account One", id: "account-1" },
|
|
236
|
-
{ name: "Account Two", id: "account-2" },
|
|
237
|
-
{ name: "Account Three", id: "account-3" },
|
|
238
|
-
],
|
|
239
|
-
};
|
|
240
|
-
|
|
241
|
-
const { lastFrame } = render(<WhoAmI user={user}></WhoAmI>);
|
|
242
|
-
|
|
243
|
-
expect(lastFrame()).toContain(
|
|
244
|
-
"You are logged in with an OAuth Token, associated with the email 'user@example.com'!"
|
|
245
|
-
);
|
|
246
|
-
expect(lastFrame()).toMatch(/Account Name .+ Account ID/);
|
|
247
|
-
expect(lastFrame()).toMatch(/Account One .+ account-1/);
|
|
248
|
-
expect(lastFrame()).toMatch(/Account Two .+ account-2/);
|
|
249
|
-
expect(lastFrame()).toMatch(/Account Three .+ account-3/);
|
|
250
|
-
});
|
|
251
|
-
|
|
252
|
-
it("should display the user's email, accounts and link to view token permissions for non-OAuth tokens", async () => {
|
|
253
|
-
const user: UserInfo = {
|
|
254
|
-
authType: "API Token",
|
|
255
|
-
apiToken: "some-api-token",
|
|
256
|
-
email: "user@example.com",
|
|
257
|
-
tokenPermissions: undefined,
|
|
258
|
-
accounts: [
|
|
259
|
-
{ name: "Account One", id: "account-1" },
|
|
260
|
-
{ name: "Account Two", id: "account-2" },
|
|
261
|
-
{ name: "Account Three", id: "account-3" },
|
|
262
|
-
],
|
|
263
|
-
};
|
|
264
|
-
|
|
265
|
-
const { lastFrame } = render(<WhoAmI user={user}></WhoAmI>);
|
|
266
|
-
|
|
267
|
-
expect(lastFrame()).toContain(
|
|
268
|
-
"You are logged in with an API Token, associated with the email 'user@example.com'!"
|
|
269
|
-
);
|
|
270
|
-
expect(lastFrame()).toMatch(/Account Name .+ Account ID/);
|
|
271
|
-
expect(lastFrame()).toMatch(/Account One .+ account-1/);
|
|
272
|
-
expect(lastFrame()).toMatch(/Account Two .+ account-2/);
|
|
273
|
-
expect(lastFrame()).toMatch(/Account Three .+ account-3/);
|
|
274
|
-
expect(lastFrame()).toContain(
|
|
275
|
-
"To see token permissions visit https://dash.cloudflare.com/profile/api-tokens"
|
|
276
|
-
);
|
|
277
|
-
});
|
|
278
|
-
});
|