wrangler 2.0.26 → 2.0.27
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/package.json +1 -1
- package/src/__tests__/configuration.test.ts +6 -2
- package/src/__tests__/generate.test.ts +2 -4
- package/src/__tests__/jest.setup.ts +4 -0
- package/src/__tests__/metrics.test.ts +1 -1
- package/src/__tests__/r2.test.ts +4 -3
- package/src/__tests__/user.test.ts +11 -0
- package/src/cfetch/internal.ts +17 -0
- package/src/config/validation-helpers.ts +19 -6
- package/src/config/validation.ts +8 -2
- package/src/config-cache.ts +2 -1
- package/src/generate.ts +1 -1
- package/src/{metrics/is-ci.ts → is-ci.ts} +0 -0
- package/src/metrics/metrics-config.ts +1 -1
- package/src/pages/dev.tsx +7 -13
- package/src/proxy.ts +10 -0
- package/src/r2.ts +4 -4
- package/src/user/user.tsx +6 -4
- package/src/whoami.tsx +5 -5
- package/wrangler-dist/cli.js +353 -355
package/package.json
CHANGED
|
@@ -1635,6 +1635,7 @@ describe("normalizeAndValidateConfig()", () => {
|
|
|
1635
1635
|
id: "KV_ID_2",
|
|
1636
1636
|
preview_id: 2222,
|
|
1637
1637
|
},
|
|
1638
|
+
{ binding: "VALID", id: "" },
|
|
1638
1639
|
],
|
|
1639
1640
|
} as unknown as RawConfig,
|
|
1640
1641
|
undefined,
|
|
@@ -1654,7 +1655,8 @@ describe("normalizeAndValidateConfig()", () => {
|
|
|
1654
1655
|
- \\"kv_namespaces[1]\\" bindings should have a string \\"id\\" field but got {\\"binding\\":\\"VALID\\"}.
|
|
1655
1656
|
- \\"kv_namespaces[2]\\" bindings should have a string \\"binding\\" field but got {\\"binding\\":2000,\\"id\\":2111}.
|
|
1656
1657
|
- \\"kv_namespaces[2]\\" bindings should have a string \\"id\\" field but got {\\"binding\\":2000,\\"id\\":2111}.
|
|
1657
|
-
- \\"kv_namespaces[3]\\" bindings should, optionally, have a string \\"preview_id\\" field but got {\\"binding\\":\\"KV_BINDING_2\\",\\"id\\":\\"KV_ID_2\\",\\"preview_id\\":2222}.
|
|
1658
|
+
- \\"kv_namespaces[3]\\" bindings should, optionally, have a string \\"preview_id\\" field but got {\\"binding\\":\\"KV_BINDING_2\\",\\"id\\":\\"KV_ID_2\\",\\"preview_id\\":2222}.
|
|
1659
|
+
- \\"kv_namespaces[4]\\" bindings should have a string \\"id\\" field but got {\\"binding\\":\\"VALID\\",\\"id\\":\\"\\"}."
|
|
1658
1660
|
`);
|
|
1659
1661
|
});
|
|
1660
1662
|
});
|
|
@@ -1740,6 +1742,7 @@ describe("normalizeAndValidateConfig()", () => {
|
|
|
1740
1742
|
bucket_name: "R2_BUCKET_2",
|
|
1741
1743
|
preview_bucket_name: 2555,
|
|
1742
1744
|
},
|
|
1745
|
+
{ binding: "R2_BINDING_1", bucket_name: "" },
|
|
1743
1746
|
],
|
|
1744
1747
|
} as unknown as RawConfig,
|
|
1745
1748
|
undefined,
|
|
@@ -1759,7 +1762,8 @@ describe("normalizeAndValidateConfig()", () => {
|
|
|
1759
1762
|
- \\"r2_buckets[1]\\" bindings should have a string \\"bucket_name\\" field but got {\\"binding\\":\\"R2_BINDING_1\\"}.
|
|
1760
1763
|
- \\"r2_buckets[2]\\" bindings should have a string \\"binding\\" field but got {\\"binding\\":2333,\\"bucket_name\\":2444}.
|
|
1761
1764
|
- \\"r2_buckets[2]\\" bindings should have a string \\"bucket_name\\" field but got {\\"binding\\":2333,\\"bucket_name\\":2444}.
|
|
1762
|
-
- \\"r2_buckets[3]\\" bindings should, optionally, have a string \\"preview_bucket_name\\" field but got {\\"binding\\":\\"R2_BINDING_2\\",\\"bucket_name\\":\\"R2_BUCKET_2\\",\\"preview_bucket_name\\":2555}.
|
|
1765
|
+
- \\"r2_buckets[3]\\" bindings should, optionally, have a string \\"preview_bucket_name\\" field but got {\\"binding\\":\\"R2_BINDING_2\\",\\"bucket_name\\":\\"R2_BUCKET_2\\",\\"preview_bucket_name\\":2555}.
|
|
1766
|
+
- \\"r2_buckets[4]\\" bindings should have a string \\"bucket_name\\" field but got {\\"binding\\":\\"R2_BINDING_1\\",\\"bucket_name\\":\\"\\"}."
|
|
1763
1767
|
`);
|
|
1764
1768
|
});
|
|
1765
1769
|
});
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import process from "node:process";
|
|
4
2
|
import { setup } from "create-cloudflare";
|
|
5
3
|
import { mockConsoleMethods } from "./helpers/mock-console";
|
|
6
4
|
import { mockConfirm, clearConfirmMocks } from "./helpers/mock-dialogs";
|
|
@@ -73,7 +71,7 @@ describe("generate", () => {
|
|
|
73
71
|
).resolves.toBeUndefined();
|
|
74
72
|
|
|
75
73
|
expect(createCloudflareMock).lastCalledWith(
|
|
76
|
-
|
|
74
|
+
"my-worker-1",
|
|
77
75
|
"some-template",
|
|
78
76
|
{ debug: false, force: false, init: true }
|
|
79
77
|
);
|
|
@@ -85,7 +83,7 @@ describe("generate", () => {
|
|
|
85
83
|
).resolves.toBeUndefined();
|
|
86
84
|
|
|
87
85
|
expect(createCloudflareMock).lastCalledWith(
|
|
88
|
-
|
|
86
|
+
"my-worker-2",
|
|
89
87
|
"some-template",
|
|
90
88
|
{ debug: false, force: false, init: true }
|
|
91
89
|
);
|
|
@@ -109,6 +109,10 @@ jest.mock("../user/generate-auth-url", () => {
|
|
|
109
109
|
};
|
|
110
110
|
});
|
|
111
111
|
|
|
112
|
+
jest.mock("../is-ci", () => {
|
|
113
|
+
return { CI: { isCI: jest.fn().mockImplementation(() => false) } };
|
|
114
|
+
});
|
|
115
|
+
|
|
112
116
|
jest.mock("../user/generate-random-state", () => {
|
|
113
117
|
return {
|
|
114
118
|
generateRandomState: jest.fn().mockImplementation(() => "MOCK_STATE_PARAM"),
|
|
@@ -2,9 +2,9 @@ import { mkdirSync } from "node:fs";
|
|
|
2
2
|
import fetchMock from "jest-fetch-mock";
|
|
3
3
|
import { version as wranglerVersion } from "../../package.json";
|
|
4
4
|
import { purgeConfigCaches, saveToConfigCache } from "../config-cache";
|
|
5
|
+
import { CI } from "../is-ci";
|
|
5
6
|
import { logger } from "../logger";
|
|
6
7
|
import { getMetricsDispatcher, getMetricsConfig } from "../metrics";
|
|
7
|
-
import { CI } from "../metrics/is-ci";
|
|
8
8
|
import {
|
|
9
9
|
CURRENT_METRICS_DATE,
|
|
10
10
|
readMetricsConfig,
|
package/src/__tests__/r2.test.ts
CHANGED
|
@@ -82,10 +82,11 @@ describe("wrangler", () => {
|
|
|
82
82
|
function mockCreateRequest(expectedBucketName: string) {
|
|
83
83
|
const requests = { count: 0 };
|
|
84
84
|
setMockResponse(
|
|
85
|
-
"/accounts/:accountId/r2/buckets
|
|
86
|
-
"
|
|
87
|
-
([_url, accountId,
|
|
85
|
+
"/accounts/:accountId/r2/buckets",
|
|
86
|
+
"POST",
|
|
87
|
+
([_url, accountId], { body }) => {
|
|
88
88
|
expect(accountId).toEqual("some-account-id");
|
|
89
|
+
const bucketName = JSON.parse(body as string).name;
|
|
89
90
|
expect(bucketName).toEqual(expectedBucketName);
|
|
90
91
|
requests.count += 1;
|
|
91
92
|
}
|
|
@@ -2,6 +2,7 @@ import fs from "node:fs";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import fetchMock from "jest-fetch-mock";
|
|
4
4
|
import { getGlobalWranglerConfigPath } from "../global-wrangler-config-path";
|
|
5
|
+
import { CI } from "../is-ci";
|
|
5
6
|
import {
|
|
6
7
|
loginOrRefreshIfRequired,
|
|
7
8
|
readAuthConfigFile,
|
|
@@ -18,6 +19,7 @@ import type { Config } from "../config";
|
|
|
18
19
|
import type { UserAuthConfig } from "../user";
|
|
19
20
|
|
|
20
21
|
describe("User", () => {
|
|
22
|
+
let isCISpy: jest.SpyInstance;
|
|
21
23
|
runInTempDir();
|
|
22
24
|
const std = mockConsoleMethods();
|
|
23
25
|
const {
|
|
@@ -30,6 +32,10 @@ describe("User", () => {
|
|
|
30
32
|
|
|
31
33
|
const { setIsTTY } = useMockIsTTY();
|
|
32
34
|
|
|
35
|
+
beforeEach(() => {
|
|
36
|
+
isCISpy = jest.spyOn(CI, "isCI").mockReturnValue(false);
|
|
37
|
+
});
|
|
38
|
+
|
|
33
39
|
describe("login", () => {
|
|
34
40
|
it("should login a user when `wrangler login` is run", async () => {
|
|
35
41
|
mockOAuthServerCallback();
|
|
@@ -132,6 +138,11 @@ describe("User", () => {
|
|
|
132
138
|
expect(std.err).toContain("");
|
|
133
139
|
});
|
|
134
140
|
|
|
141
|
+
it("should revert to non-interactive mode if in CI", async () => {
|
|
142
|
+
isCISpy.mockReturnValue(true);
|
|
143
|
+
await expect(loginOrRefreshIfRequired()).resolves.toEqual(false);
|
|
144
|
+
});
|
|
145
|
+
|
|
135
146
|
it("should revert to non-interactive mode if isTTY throws an error", async () => {
|
|
136
147
|
setIsTTY({
|
|
137
148
|
stdin() {
|
package/src/cfetch/internal.ts
CHANGED
|
@@ -2,6 +2,7 @@ import assert from "node:assert";
|
|
|
2
2
|
import { fetch, Headers } from "undici";
|
|
3
3
|
import { version as wranglerVersion } from "../../package.json";
|
|
4
4
|
import { getEnvironmentVariableFactory } from "../environment-variables";
|
|
5
|
+
import { logger } from "../logger";
|
|
5
6
|
import { ParseError, parseJSON } from "../parse";
|
|
6
7
|
import { loginOrRefreshIfRequired, requireApiToken } from "../user";
|
|
7
8
|
import type { ApiCredentials } from "../user";
|
|
@@ -44,6 +45,13 @@ export async function fetchInternal<ResponseType>(
|
|
|
44
45
|
|
|
45
46
|
const queryString = queryParams ? `?${queryParams.toString()}` : "";
|
|
46
47
|
const method = init.method ?? "GET";
|
|
48
|
+
|
|
49
|
+
logger.debug(
|
|
50
|
+
`-- START CF API REQUEST: ${method} ${getCloudflareAPIBaseURL()}${resource}${queryString}`
|
|
51
|
+
);
|
|
52
|
+
logger.debug("HEADERS:", JSON.stringify(headers, null, 2));
|
|
53
|
+
logger.debug("INIT:", JSON.stringify(init, null, 2));
|
|
54
|
+
logger.debug("-- END CF API REQUEST");
|
|
47
55
|
const response = await fetch(
|
|
48
56
|
`${getCloudflareAPIBaseURL()}${resource}${queryString}`,
|
|
49
57
|
{
|
|
@@ -54,6 +62,15 @@ export async function fetchInternal<ResponseType>(
|
|
|
54
62
|
}
|
|
55
63
|
);
|
|
56
64
|
const jsonText = await response.text();
|
|
65
|
+
logger.debug(
|
|
66
|
+
"-- START CF API RESPONSE:",
|
|
67
|
+
response.statusText,
|
|
68
|
+
response.status
|
|
69
|
+
);
|
|
70
|
+
logger.debug("HEADERS:", JSON.stringify(response.headers, null, 2));
|
|
71
|
+
logger.debug("RESPONSE:", jsonText);
|
|
72
|
+
logger.debug("-- END CF API RESPONSE");
|
|
73
|
+
|
|
57
74
|
try {
|
|
58
75
|
return parseJSON<ResponseType>(jsonText);
|
|
59
76
|
} catch (err) {
|
|
@@ -383,7 +383,7 @@ export const validateRequiredProperty = (
|
|
|
383
383
|
container: string,
|
|
384
384
|
key: string,
|
|
385
385
|
value: unknown,
|
|
386
|
-
type:
|
|
386
|
+
type: TypeofType,
|
|
387
387
|
choices?: unknown[]
|
|
388
388
|
): boolean => {
|
|
389
389
|
if (container) {
|
|
@@ -417,7 +417,7 @@ export const validateOptionalProperty = (
|
|
|
417
417
|
container: string,
|
|
418
418
|
key: string,
|
|
419
419
|
value: unknown,
|
|
420
|
-
type:
|
|
420
|
+
type: TypeofType,
|
|
421
421
|
choices?: unknown[]
|
|
422
422
|
): boolean => {
|
|
423
423
|
if (value !== undefined) {
|
|
@@ -440,7 +440,7 @@ export const validateTypedArray = (
|
|
|
440
440
|
diagnostics: Diagnostics,
|
|
441
441
|
container: string,
|
|
442
442
|
value: unknown,
|
|
443
|
-
type:
|
|
443
|
+
type: TypeofType
|
|
444
444
|
): boolean => {
|
|
445
445
|
let isValid = true;
|
|
446
446
|
if (!Array.isArray(value)) {
|
|
@@ -472,7 +472,7 @@ export const validateOptionalTypedArray = (
|
|
|
472
472
|
diagnostics: Diagnostics,
|
|
473
473
|
container: string,
|
|
474
474
|
value: unknown,
|
|
475
|
-
type:
|
|
475
|
+
type: TypeofType
|
|
476
476
|
) => {
|
|
477
477
|
if (value !== undefined) {
|
|
478
478
|
return validateTypedArray(diagnostics, container, value, type);
|
|
@@ -486,7 +486,7 @@ export const validateOptionalTypedArray = (
|
|
|
486
486
|
export const isRequiredProperty = <T extends object>(
|
|
487
487
|
obj: object,
|
|
488
488
|
prop: keyof T,
|
|
489
|
-
type:
|
|
489
|
+
type: TypeofType,
|
|
490
490
|
choices?: unknown[]
|
|
491
491
|
): obj is T =>
|
|
492
492
|
hasProperty<T>(obj, prop) &&
|
|
@@ -499,7 +499,7 @@ export const isRequiredProperty = <T extends object>(
|
|
|
499
499
|
export const isOptionalProperty = <T extends object>(
|
|
500
500
|
obj: object,
|
|
501
501
|
prop: keyof T,
|
|
502
|
-
type:
|
|
502
|
+
type: TypeofType
|
|
503
503
|
): obj is T => !hasProperty<T>(obj, prop) || typeof obj[prop] === type;
|
|
504
504
|
|
|
505
505
|
/**
|
|
@@ -582,3 +582,16 @@ const isRecord = (
|
|
|
582
582
|
value: unknown
|
|
583
583
|
): value is Record<string | number | symbol, unknown> =>
|
|
584
584
|
typeof value === "object" && value !== null && !Array.isArray(value);
|
|
585
|
+
|
|
586
|
+
/**
|
|
587
|
+
* JavaScript `typeof` operator return values.
|
|
588
|
+
*/
|
|
589
|
+
type TypeofType =
|
|
590
|
+
| "string"
|
|
591
|
+
| "number"
|
|
592
|
+
| "bigint"
|
|
593
|
+
| "boolean"
|
|
594
|
+
| "symbol"
|
|
595
|
+
| "undefined"
|
|
596
|
+
| "object"
|
|
597
|
+
| "function";
|
package/src/config/validation.ts
CHANGED
|
@@ -1630,7 +1630,10 @@ const validateKVBinding: ValidatorFn = (diagnostics, field, value) => {
|
|
|
1630
1630
|
);
|
|
1631
1631
|
isValid = false;
|
|
1632
1632
|
}
|
|
1633
|
-
if (
|
|
1633
|
+
if (
|
|
1634
|
+
!isRequiredProperty(value, "id", "string") ||
|
|
1635
|
+
(value as { id: string }).id.length === 0
|
|
1636
|
+
) {
|
|
1634
1637
|
diagnostics.errors.push(
|
|
1635
1638
|
`"${field}" bindings should have a string "id" field but got ${JSON.stringify(
|
|
1636
1639
|
value
|
|
@@ -1668,7 +1671,10 @@ const validateR2Binding: ValidatorFn = (diagnostics, field, value) => {
|
|
|
1668
1671
|
);
|
|
1669
1672
|
isValid = false;
|
|
1670
1673
|
}
|
|
1671
|
-
if (
|
|
1674
|
+
if (
|
|
1675
|
+
!isRequiredProperty(value, "bucket_name", "string") ||
|
|
1676
|
+
(value as { bucket_name: string }).bucket_name.length === 0
|
|
1677
|
+
) {
|
|
1672
1678
|
diagnostics.errors.push(
|
|
1673
1679
|
`"${field}" bindings should have a string "bucket_name" field but got ${JSON.stringify(
|
|
1674
1680
|
value
|
package/src/config-cache.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { mkdirSync, readFileSync, rmSync, writeFileSync } from "fs";
|
|
2
2
|
import * as path from "path";
|
|
3
3
|
import { findUpSync } from "find-up";
|
|
4
|
+
import { CI } from "./is-ci";
|
|
4
5
|
import isInteractive from "./is-interactive";
|
|
5
6
|
import { logger } from "./logger";
|
|
6
7
|
|
|
@@ -29,7 +30,7 @@ const arrayFormatter = new Intl.ListFormat("en", {
|
|
|
29
30
|
});
|
|
30
31
|
|
|
31
32
|
function showCacheMessage(fields: string[], folder: string) {
|
|
32
|
-
if (!cacheMessageShown && isInteractive()) {
|
|
33
|
+
if (!cacheMessageShown && isInteractive() && !CI.isCI()) {
|
|
33
34
|
if (fields.length > 0) {
|
|
34
35
|
logger.log(
|
|
35
36
|
`Retrieving cached values for ${arrayFormatter.format(
|
package/src/generate.ts
CHANGED
|
@@ -88,7 +88,7 @@ export async function generateHandler({
|
|
|
88
88
|
`Creating a worker in ${path.basename(creationDirectory)} from ${template}`
|
|
89
89
|
);
|
|
90
90
|
|
|
91
|
-
await createCloudflare(creationDirectory, template, {
|
|
91
|
+
await createCloudflare(path.basename(creationDirectory), template, {
|
|
92
92
|
init: true, // initialize a git repository
|
|
93
93
|
debug: logger.loggerLevel === "debug",
|
|
94
94
|
force: false, // do not overwrite an existing directory
|
|
File without changes
|
|
@@ -6,10 +6,10 @@ import { fetchResult } from "../cfetch";
|
|
|
6
6
|
import { getConfigCache, saveToConfigCache } from "../config-cache";
|
|
7
7
|
import { confirm } from "../dialogs";
|
|
8
8
|
import { getEnvironmentVariableFactory } from "../environment-variables";
|
|
9
|
+
import { CI } from "../is-ci";
|
|
9
10
|
import isInteractive from "../is-interactive";
|
|
10
11
|
import { logger } from "../logger";
|
|
11
12
|
import { getAPIToken } from "../user";
|
|
12
|
-
import { CI } from "./is-ci";
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* The date that the metrics being gathered was last updated in a way that would require
|
package/src/pages/dev.tsx
CHANGED
|
@@ -367,24 +367,16 @@ export const Handler = async ({
|
|
|
367
367
|
);
|
|
368
368
|
await metrics.sendMetricsEvent("run pages dev");
|
|
369
369
|
|
|
370
|
+
CLEANUP_CALLBACKS.push(stop);
|
|
371
|
+
|
|
370
372
|
waitUntilExit().then(() => {
|
|
371
373
|
CLEANUP();
|
|
372
|
-
stop();
|
|
373
374
|
process.exit(0);
|
|
374
375
|
});
|
|
375
376
|
|
|
376
|
-
process.on("exit",
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
});
|
|
380
|
-
process.on("SIGINT", () => {
|
|
381
|
-
CLEANUP();
|
|
382
|
-
stop();
|
|
383
|
-
});
|
|
384
|
-
process.on("SIGTERM", () => {
|
|
385
|
-
CLEANUP();
|
|
386
|
-
stop();
|
|
387
|
-
});
|
|
377
|
+
process.on("exit", CLEANUP);
|
|
378
|
+
process.on("SIGINT", CLEANUP);
|
|
379
|
+
process.on("SIGTERM", CLEANUP);
|
|
388
380
|
};
|
|
389
381
|
|
|
390
382
|
function isWindows() {
|
|
@@ -491,6 +483,8 @@ async function spawnProxyProcess({
|
|
|
491
483
|
|
|
492
484
|
proxy.on("close", (code) => {
|
|
493
485
|
logger.error(`Proxy exited with status ${code}.`);
|
|
486
|
+
CLEANUP();
|
|
487
|
+
process.exitCode = code ?? 0;
|
|
494
488
|
});
|
|
495
489
|
|
|
496
490
|
// Wait for proxy process to start...
|
package/src/proxy.ts
CHANGED
|
@@ -177,6 +177,7 @@ export function usePreviewServer({
|
|
|
177
177
|
const cleanupListeners: (() => void)[] = [];
|
|
178
178
|
|
|
179
179
|
// create a ClientHttp2Session
|
|
180
|
+
logger.debug("PREVIEW URL:", `https://${previewToken.host}`);
|
|
180
181
|
const remote = connect(`https://${previewToken.host}`);
|
|
181
182
|
cleanupListeners.push(() => remote.destroy());
|
|
182
183
|
|
|
@@ -221,6 +222,15 @@ export function usePreviewServer({
|
|
|
221
222
|
}
|
|
222
223
|
}
|
|
223
224
|
const request = message.pipe(remote.request(headers));
|
|
225
|
+
logger.debug(
|
|
226
|
+
"WORKER REQUEST",
|
|
227
|
+
new Date().toLocaleTimeString(),
|
|
228
|
+
method,
|
|
229
|
+
url
|
|
230
|
+
);
|
|
231
|
+
logger.debug("HEADERS", JSON.stringify(headers, null, 2));
|
|
232
|
+
logger.debug("PREVIEW TOKEN", previewToken);
|
|
233
|
+
|
|
224
234
|
request.on("response", (responseHeaders) => {
|
|
225
235
|
const status = responseHeaders[":status"] ?? 500;
|
|
226
236
|
|
package/src/r2.ts
CHANGED
|
@@ -33,10 +33,10 @@ export async function createR2Bucket(
|
|
|
33
33
|
accountId: string,
|
|
34
34
|
bucketName: string
|
|
35
35
|
): Promise<void> {
|
|
36
|
-
return await fetchResult<void>(
|
|
37
|
-
|
|
38
|
-
{
|
|
39
|
-
);
|
|
36
|
+
return await fetchResult<void>(`/accounts/${accountId}/r2/buckets`, {
|
|
37
|
+
method: "POST",
|
|
38
|
+
body: JSON.stringify({ name: bucketName }),
|
|
39
|
+
});
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
/**
|
package/src/user/user.tsx
CHANGED
|
@@ -224,6 +224,7 @@ import {
|
|
|
224
224
|
saveToConfigCache,
|
|
225
225
|
} from "../config-cache";
|
|
226
226
|
import { getGlobalWranglerConfigPath } from "../global-wrangler-config-path";
|
|
227
|
+
import { CI } from "../is-ci";
|
|
227
228
|
import isInteractive from "../is-interactive";
|
|
228
229
|
import { logger } from "../logger";
|
|
229
230
|
import openInBrowser from "../open-in-browser";
|
|
@@ -878,10 +879,11 @@ type LoginProps = {
|
|
|
878
879
|
export async function loginOrRefreshIfRequired(): Promise<boolean> {
|
|
879
880
|
// TODO: if there already is a token, then try refreshing
|
|
880
881
|
// TODO: ask permission before opening browser
|
|
882
|
+
const { isCI } = CI;
|
|
881
883
|
if (!getAPIToken()) {
|
|
882
884
|
// Not logged in.
|
|
883
885
|
// If we are not interactive, we cannot ask the user to login
|
|
884
|
-
return isInteractive() && (await login());
|
|
886
|
+
return isInteractive() && !isCI() && (await login());
|
|
885
887
|
} else if (isAccessTokenExpired()) {
|
|
886
888
|
// We're logged in, but the refresh token seems to have expired,
|
|
887
889
|
// so let's try to refresh it
|
|
@@ -891,7 +893,7 @@ export async function loginOrRefreshIfRequired(): Promise<boolean> {
|
|
|
891
893
|
return true;
|
|
892
894
|
} else {
|
|
893
895
|
// If the refresh token isn't valid, then we ask the user to login again
|
|
894
|
-
return isInteractive() && (await login());
|
|
896
|
+
return isInteractive() && !isCI() && (await login());
|
|
895
897
|
}
|
|
896
898
|
} else {
|
|
897
899
|
return true;
|
|
@@ -1088,7 +1090,7 @@ export async function getAccountId(): Promise<string | undefined> {
|
|
|
1088
1090
|
return accounts[0].id;
|
|
1089
1091
|
}
|
|
1090
1092
|
|
|
1091
|
-
if (isInteractive()) {
|
|
1093
|
+
if (isInteractive() && !CI.isCI()) {
|
|
1092
1094
|
const account = await new Promise<{ id: string; name: string }>(
|
|
1093
1095
|
(resolve, reject) => {
|
|
1094
1096
|
const { unmount } = render(
|
|
@@ -1128,7 +1130,7 @@ export async function requireAuth(config: {
|
|
|
1128
1130
|
}): Promise<string> {
|
|
1129
1131
|
const loggedIn = await loginOrRefreshIfRequired();
|
|
1130
1132
|
if (!loggedIn) {
|
|
1131
|
-
if (!isInteractive()) {
|
|
1133
|
+
if (!isInteractive() || CI.isCI()) {
|
|
1132
1134
|
throw new Error(
|
|
1133
1135
|
"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/tokens/create/ for instructions on how to create an api token, and assign its value to CLOUDFLARE_API_TOKEN."
|
|
1134
1136
|
);
|
package/src/whoami.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Text, render } from "ink";
|
|
2
2
|
import Table from "ink-table";
|
|
3
|
-
import React from "react";
|
|
3
|
+
import React, { Fragment } from "react";
|
|
4
4
|
import { fetchListResult, fetchResult } from "./cfetch";
|
|
5
5
|
import { logger } from "./logger";
|
|
6
6
|
import { getAPIToken, getAuthFromEnv, getScopes } from "./user";
|
|
@@ -64,12 +64,12 @@ function Permissions(props: {
|
|
|
64
64
|
and re-login.
|
|
65
65
|
</Text>
|
|
66
66
|
<Text>Scope (Access)</Text>
|
|
67
|
-
{permissions.map(([
|
|
68
|
-
|
|
67
|
+
{permissions.map(([scope, access], index) => (
|
|
68
|
+
<Fragment key={`${scope}${index}`}>
|
|
69
69
|
<Text>
|
|
70
|
-
- {
|
|
70
|
+
- {scope} {access && `(${access})`}
|
|
71
71
|
</Text>
|
|
72
|
-
|
|
72
|
+
</Fragment>
|
|
73
73
|
))}
|
|
74
74
|
</>
|
|
75
75
|
) : null
|