wrangler 2.6.1 → 2.7.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.
Files changed (130) hide show
  1. package/bin/wrangler.js +9 -1
  2. package/miniflare-dist/index.mjs +1 -1
  3. package/package.json +12 -10
  4. package/src/__tests__/api-dev.test.ts +65 -36
  5. package/src/__tests__/api-devregistry.test.js +14 -6
  6. package/src/__tests__/configuration.test.ts +2 -31
  7. package/src/__tests__/{d1.test.ts → d1/d1.test.ts} +48 -5
  8. package/src/__tests__/d1/splitter.test.ts +255 -0
  9. package/src/__tests__/delete.test.ts +5 -2
  10. package/src/__tests__/deployments.test.ts +20 -6
  11. package/src/__tests__/dev.test.tsx +52 -19
  12. package/src/__tests__/generate.test.ts +7 -4
  13. package/src/__tests__/helpers/mock-auth-domain.ts +20 -0
  14. package/src/__tests__/helpers/mock-cfetch.ts +2 -57
  15. package/src/__tests__/helpers/mock-dialogs.ts +70 -86
  16. package/src/__tests__/helpers/mock-oauth-flow.ts +64 -49
  17. package/src/__tests__/helpers/mock-process.ts +8 -13
  18. package/src/__tests__/helpers/msw/blob-worker.cjs +19 -0
  19. package/src/__tests__/helpers/msw/read-file-sync.js +61 -0
  20. package/src/__tests__/index.test.ts +46 -42
  21. package/src/__tests__/init.test.ts +782 -522
  22. package/src/__tests__/jest.setup.ts +20 -24
  23. package/src/__tests__/kv.test.ts +286 -173
  24. package/src/__tests__/logout.test.ts +1 -1
  25. package/src/__tests__/metrics.test.ts +5 -7
  26. package/src/__tests__/middleware.scheduled.test.ts +40 -30
  27. package/src/__tests__/middleware.test.ts +144 -120
  28. package/src/__tests__/pages.test.ts +1618 -1161
  29. package/src/__tests__/publish.test.ts +174 -125
  30. package/src/__tests__/r2.test.ts +2 -2
  31. package/src/__tests__/secret.test.ts +183 -126
  32. package/src/__tests__/tail.test.ts +6 -0
  33. package/src/__tests__/tsconfig-sanity.ts +12 -0
  34. package/src/__tests__/tsconfig.json +8 -0
  35. package/src/__tests__/tsconfig.tsbuildinfo +1 -0
  36. package/src/__tests__/whoami.test.tsx +1 -96
  37. package/src/api/dev.ts +78 -41
  38. package/src/api/index.ts +1 -1
  39. package/src/{bundle-reporter.tsx → bundle-reporter.ts} +0 -0
  40. package/src/cfetch/index.ts +0 -2
  41. package/src/cfetch/internal.ts +16 -18
  42. package/src/cli.ts +2 -2
  43. package/src/config/index.ts +2 -1
  44. package/src/config/validation.ts +1 -2
  45. package/src/create-worker-upload-form.ts +2 -2
  46. package/src/d1/{delete.tsx → delete.ts} +0 -0
  47. package/src/d1/execute.tsx +8 -37
  48. package/src/d1/migrations/apply.tsx +32 -19
  49. package/src/d1/migrations/{index.tsx → index.ts} +0 -0
  50. package/src/d1/splitter.ts +161 -0
  51. package/src/d1/{types.tsx → types.ts} +0 -0
  52. package/src/delete.ts +3 -8
  53. package/src/deployments.ts +6 -0
  54. package/src/deprecated/index.ts +2 -295
  55. package/src/dev/dev.tsx +2 -2
  56. package/src/dev/{get-local-persistence-path.tsx → get-local-persistence-path.ts} +0 -0
  57. package/src/dev/local.tsx +16 -4
  58. package/src/dev/remote.tsx +28 -1
  59. package/src/dev/start-server.ts +19 -11
  60. package/src/dev/use-esbuild.ts +1 -1
  61. package/src/{dev-registry.tsx → dev-registry.ts} +0 -0
  62. package/src/dev.tsx +35 -11
  63. package/src/dialogs.ts +136 -0
  64. package/src/dispatch-namespace.ts +1 -1
  65. package/src/docs/index.ts +97 -0
  66. package/src/environment-variables/factory.ts +88 -0
  67. package/src/environment-variables/misc-variables.ts +30 -0
  68. package/src/generate/index.ts +300 -0
  69. package/src/{index.tsx → index.ts} +16 -10
  70. package/src/init.ts +106 -60
  71. package/src/jest.d.ts +4 -0
  72. package/src/logger.ts +15 -3
  73. package/src/metrics/metrics-config.ts +1 -1
  74. package/src/metrics/send-event.ts +2 -1
  75. package/src/miniflare-cli/assets.ts +4 -0
  76. package/src/miniflare-cli/index.ts +1 -5
  77. package/src/miniflare-cli/tsconfig.json +9 -0
  78. package/src/miniflare-cli/tsconfig.tsbuildinfo +1 -0
  79. package/src/miniflare-cli/types.ts +11 -0
  80. package/src/pages/{build.tsx → build.ts} +0 -0
  81. package/src/pages/{deployment-tails.tsx → deployment-tails.ts} +0 -0
  82. package/src/pages/{dev.tsx → dev.ts} +53 -55
  83. package/src/pages/functions/buildWorker.ts +1 -1
  84. package/src/pages/functions/tsconfig.json +8 -0
  85. package/src/pages/functions/tsconfig.tsbuildinfo +1 -0
  86. package/src/pages/{functions.tsx → functions.ts} +0 -0
  87. package/src/pages/{hash.tsx → hash.ts} +0 -0
  88. package/src/pages/{index.tsx → index.ts} +0 -0
  89. package/src/pages/projects.tsx +3 -5
  90. package/src/pages/publish.tsx +16 -5
  91. package/src/pages/upload.tsx +27 -6
  92. package/src/publish/publish.ts +9 -7
  93. package/src/pubsub/{pubsub-commands.tsx → pubsub-commands.ts} +1 -1
  94. package/src/secret/index.ts +1 -1
  95. package/src/{sites.tsx → sites.ts} +0 -0
  96. package/src/tail/index.ts +2 -3
  97. package/src/tsconfig-sanity.ts +16 -0
  98. package/src/user/access.ts +0 -1
  99. package/src/user/auth-variables.ts +113 -0
  100. package/src/user/choose-account.tsx +1 -31
  101. package/src/user/index.ts +0 -1
  102. package/src/user/{user.tsx → user.ts} +107 -73
  103. package/src/{whoami.tsx → whoami.ts} +37 -71
  104. package/templates/__tests__/tsconfig-sanity.ts +12 -0
  105. package/templates/__tests__/tsconfig.json +8 -0
  106. package/templates/__tests__/tsconfig.tsbuildinfo +1 -0
  107. package/templates/d1-beta-facade.js +36 -0
  108. package/templates/facade.d.ts +14 -0
  109. package/templates/first-party-worker-module-facade.ts +4 -3
  110. package/templates/format-dev-errors.ts +7 -6
  111. package/templates/init-tests/test-jest-new-worker.js +3 -5
  112. package/templates/init-tests/test-vitest-new-worker.js +3 -5
  113. package/templates/init-tests/test-vitest-new-worker.ts +25 -0
  114. package/templates/middleware/loader-modules.ts +0 -2
  115. package/templates/middleware/loader-sw.ts +6 -0
  116. package/templates/pages-dev-pipeline.ts +4 -1
  117. package/templates/pages-shim.ts +4 -1
  118. package/templates/pages-template-plugin.ts +12 -7
  119. package/templates/serve-static-assets.ts +16 -14
  120. package/templates/tsconfig-sanity.ts +11 -0
  121. package/templates/tsconfig.init.json +106 -0
  122. package/templates/tsconfig.json +5 -103
  123. package/templates/tsconfig.tsbuildinfo +1 -0
  124. package/wrangler-dist/cli.d.ts +58 -60
  125. package/wrangler-dist/cli.js +34498 -55459
  126. package/wrangler-dist/wasm-sync.wasm +0 -0
  127. package/src/__tests__/dialogs.test.tsx +0 -40
  128. package/src/dialogs.tsx +0 -168
  129. package/src/environment-variables.ts +0 -50
  130. package/src/user/env-vars.ts +0 -46
@@ -152,7 +152,7 @@ export function useEsbuild({
152
152
  });
153
153
 
154
154
  stopWatching = () => {
155
- watcher.close();
155
+ void watcher.close();
156
156
  };
157
157
  }
158
158
  setBundle({
File without changes
package/src/dev.tsx CHANGED
@@ -30,7 +30,7 @@ import {
30
30
  } from "./index";
31
31
  import type { Config, Environment } from "./config";
32
32
  import type { Route } from "./config/environment";
33
- import type { EnablePagesAssetsServiceBindingOptions } from "./miniflare-cli";
33
+ import type { EnablePagesAssetsServiceBindingOptions } from "./miniflare-cli/types";
34
34
  import type { CfWorkerInit } from "./worker";
35
35
  import type { CommonYargsOptions } from "./yargs-types";
36
36
  import type { Argv, ArgumentsCamelCase } from "yargs";
@@ -328,7 +328,7 @@ export function devOptions(yargs: Argv<CommonYargsOptions>): Argv<DevArgs> {
328
328
  }
329
329
 
330
330
  export async function devHandler(args: ArgumentsCamelCase<DevArgs>) {
331
- if (!args.local) {
331
+ if (!(args.local || args.experimentalLocal)) {
332
332
  const isLoggedIn = await loginOrRefreshIfRequired();
333
333
  if (!isLoggedIn) {
334
334
  throw new Error(
@@ -376,6 +376,7 @@ type StartDevOptions = ArgumentsCamelCase<DevArgs> &
376
376
  // They aren't exposed as CLI arguments.
377
377
  AdditionalDevProps & {
378
378
  forceLocal?: boolean;
379
+ disableDevRegistry?: boolean;
379
380
  enablePagesAssetsServiceBinding?: EnablePagesAssetsServiceBindingOptions;
380
381
  };
381
382
 
@@ -442,7 +443,7 @@ export async function startDev(args: StartDevOptions) {
442
443
 
443
444
  // eslint-disable-next-line no-inner-declarations
444
445
  async function getDevReactElement(configParam: Config) {
445
- const { assetPaths, bindings } = await getBindingsAndAssetPaths(
446
+ const { assetPaths, bindings } = getBindingsAndAssetPaths(
446
447
  args,
447
448
  configParam
448
449
  );
@@ -512,11 +513,28 @@ export async function startDev(args: StartDevOptions) {
512
513
  );
513
514
  }
514
515
  const devReactElement = render(await getDevReactElement(config));
516
+
517
+ // In the bootstrapper script `bin/wrangler.js`, we open an IPC channel, so
518
+ // IPC messages from this process are propagated through the bootstrapper.
519
+ // Normally, Node's SIGINT handler would close this for us, but interactive
520
+ // mode enables raw mode on stdin which disables the built-in handler. The
521
+ // following line disconnects from the IPC channel when we press `x` or
522
+ // CTRL-C in interactive mode, ensuring no open handles, and allowing for a
523
+ // clean exit. Note, if we called `stop()` using the dev API, we don't want
524
+ // to disconnect here, as the user may still need IPC. We also don't want
525
+ // to disconnect if this file was imported in Jest (not the case with E2E
526
+ // tests), as that would stop communication with the test runner.
527
+ let apiStopped = false;
528
+ void devReactElement.waitUntilExit().then(() => {
529
+ if (!apiStopped && typeof jest === "undefined") process.disconnect?.();
530
+ });
531
+
515
532
  rerender = devReactElement.rerender;
516
533
  return {
517
534
  devReactElement,
518
535
  watcher,
519
536
  stop: async () => {
537
+ apiStopped = true;
520
538
  devReactElement.unmount();
521
539
  await watcher?.close();
522
540
  },
@@ -559,7 +577,7 @@ export async function startApiDev(args: StartDevOptions) {
559
577
 
560
578
  // eslint-disable-next-line no-inner-declarations
561
579
  async function getDevServer(configParam: Config) {
562
- const { assetPaths, bindings } = await getBindingsAndAssetPaths(
580
+ const { assetPaths, bindings } = getBindingsAndAssetPaths(
563
581
  args,
564
582
  configParam
565
583
  );
@@ -627,6 +645,7 @@ export async function startApiDev(args: StartDevOptions) {
627
645
  testScheduled: args.testScheduled,
628
646
  experimentalLocal: args.experimentalLocal,
629
647
  experimentalLocalRemoteKv: args.experimentalLocalRemoteKv,
648
+ disableDevRegistry: args.disableDevRegistry ?? false,
630
649
  });
631
650
  }
632
651
 
@@ -798,14 +817,11 @@ async function validateDevServerSettings(
798
817
  };
799
818
  }
800
819
 
801
- async function getBindingsAndAssetPaths(
802
- args: StartDevOptions,
803
- configParam: Config
804
- ) {
820
+ function getBindingsAndAssetPaths(args: StartDevOptions, configParam: Config) {
805
821
  const cliVars = collectKeyValues(args.var);
806
822
 
807
823
  // now log all available bindings into the terminal
808
- const bindings = await getBindings(configParam, args.env, {
824
+ const bindings = getBindings(configParam, args.env, args.local ?? false, {
809
825
  kv: args.kv,
810
826
  vars: { ...args.vars, ...cliVars },
811
827
  durableObjects: args.durableObjects,
@@ -832,11 +848,12 @@ async function getBindingsAndAssetPaths(
832
848
  return { assetPaths, bindings };
833
849
  }
834
850
 
835
- async function getBindings(
851
+ function getBindings(
836
852
  configParam: Config,
837
853
  env: string | undefined,
854
+ local: boolean,
838
855
  args: AdditionalDevProps
839
- ): Promise<CfWorkerInit["bindings"]> {
856
+ ): CfWorkerInit["bindings"] {
840
857
  const bindings = {
841
858
  kv_namespaces: [
842
859
  ...(configParam.kv_namespaces || []).map(
@@ -906,6 +923,13 @@ async function getBindings(
906
923
  logfwdr: configParam.logfwdr,
907
924
  d1_databases: identifyD1BindingsAsBeta([
908
925
  ...(configParam.d1_databases ?? []).map((d1Db) => {
926
+ //in local dev, bindings don't matter
927
+ if (local) {
928
+ return {
929
+ ...d1Db,
930
+ database_id: "local",
931
+ };
932
+ }
909
933
  if (!d1Db.preview_database_id) {
910
934
  throw new Error(
911
935
  `In development, you should use a separate D1 database than the one you'd use in production. Please create a new D1 database with "wrangler d1 create <name>" and add its id as preview_database_id to the d1_database "${d1Db.binding}" in your wrangler.toml`
package/src/dialogs.ts ADDED
@@ -0,0 +1,136 @@
1
+ import chalk from "chalk";
2
+ import prompts from "prompts";
3
+ import { CI } from "./is-ci";
4
+ import isInteractive from "./is-interactive";
5
+ import { logger } from "./logger";
6
+
7
+ // TODO: Use this function across the codebase.
8
+ function isNonInteractiveOrCI(): boolean {
9
+ return !isInteractive() || CI.isCI();
10
+ }
11
+
12
+ export class NoDefaultValueProvided extends Error {
13
+ constructor() {
14
+ // This is user-facing, so make the message something understandable
15
+ // It _should_ always be caught and replaced with a more descriptive error
16
+ // but this is fine as a fallback.
17
+ super("This command cannot be run in a non-interactive context");
18
+ Object.setPrototypeOf(this, new.target.prototype);
19
+ }
20
+ }
21
+
22
+ interface ConfirmOptions {
23
+ defaultValue?: boolean;
24
+ }
25
+
26
+ export async function confirm(
27
+ text: string,
28
+ { defaultValue = true }: ConfirmOptions = {}
29
+ ): Promise<boolean> {
30
+ if (isNonInteractiveOrCI()) {
31
+ logger.log(`? ${text}`);
32
+ logger.log(
33
+ `🤖 ${chalk.dim(
34
+ "Using default value in non-interactive context:"
35
+ )} ${chalk.white.bold(defaultValue ? "yes" : "no")}`
36
+ );
37
+ return defaultValue;
38
+ }
39
+ const { value } = await prompts({
40
+ type: "confirm",
41
+ name: "value",
42
+ message: text,
43
+ initial: defaultValue,
44
+ onState: (state) => {
45
+ if (state.aborted) {
46
+ process.nextTick(() => {
47
+ process.exit(1);
48
+ });
49
+ }
50
+ },
51
+ });
52
+ return value;
53
+ }
54
+
55
+ interface PromptOptions {
56
+ defaultValue?: string;
57
+ isSecret?: boolean;
58
+ }
59
+
60
+ export async function prompt(
61
+ text: string,
62
+ options: PromptOptions = {}
63
+ ): Promise<string> {
64
+ if (isNonInteractiveOrCI()) {
65
+ if (options?.defaultValue === undefined) {
66
+ throw new NoDefaultValueProvided();
67
+ }
68
+ logger.log(`? ${text}`);
69
+ logger.log(
70
+ `🤖 ${chalk.dim(
71
+ "Using default value in non-interactive context:"
72
+ )} ${chalk.white.bold(options.defaultValue)}`
73
+ );
74
+ return options.defaultValue;
75
+ }
76
+ const { value } = await prompts({
77
+ type: "text",
78
+ name: "value",
79
+ message: text,
80
+ initial: options?.defaultValue,
81
+ style: options?.isSecret ? "password" : "default",
82
+ onState: (state) => {
83
+ if (state.aborted) {
84
+ process.nextTick(() => {
85
+ process.exit(1);
86
+ });
87
+ }
88
+ },
89
+ });
90
+ return value;
91
+ }
92
+
93
+ interface SelectOptions<Values> {
94
+ choices: SelectOption<Values>[];
95
+ defaultOption?: number;
96
+ }
97
+
98
+ interface SelectOption<Values> {
99
+ title: string;
100
+ description?: string;
101
+ value: Values;
102
+ }
103
+
104
+ export async function select<Values extends string>(
105
+ text: string,
106
+ options: SelectOptions<Values>
107
+ ): Promise<Values> {
108
+ if (isNonInteractiveOrCI()) {
109
+ if (options?.defaultOption === undefined) {
110
+ throw new NoDefaultValueProvided();
111
+ }
112
+ logger.log(`? ${text}`);
113
+ logger.log(
114
+ `🤖 ${chalk.dim(
115
+ "Using default value in non-interactive context:"
116
+ )} ${chalk.white.bold(options.choices[options.defaultOption].title)}`
117
+ );
118
+ return options.choices[options.defaultOption].value;
119
+ }
120
+
121
+ const { value } = await prompts({
122
+ type: "select",
123
+ name: "value",
124
+ message: text,
125
+ choices: options.choices,
126
+ initial: options.defaultOption,
127
+ onState: (state) => {
128
+ if (state.aborted) {
129
+ process.nextTick(() => {
130
+ process.exit(1);
131
+ });
132
+ }
133
+ },
134
+ });
135
+ return value;
136
+ }
@@ -90,7 +90,7 @@ async function renameWorkerNamespace(
90
90
  oldName: string,
91
91
  newName: string
92
92
  ) {
93
- printWranglerBanner();
93
+ void printWranglerBanner();
94
94
 
95
95
  await fetchResult(
96
96
  `/accounts/${accountId}/workers/dispatch/namespaces/${oldName}`,
@@ -0,0 +1,97 @@
1
+ import { printWranglerBanner } from "..";
2
+ import { readConfig } from "../config";
3
+ import { logger } from "../logger";
4
+ import * as metrics from "../metrics";
5
+ import openInBrowser from "../open-in-browser";
6
+
7
+ import type {
8
+ CommonYargsOptions,
9
+ YargsOptionsToInterface,
10
+ } from "../yargs-types";
11
+ import type { ArgumentsCamelCase, Argv } from "yargs";
12
+
13
+ const argToUrlHash = {
14
+ docs: "docs",
15
+ init: "init",
16
+ generate: "generate",
17
+ dev: "dev",
18
+ publish: "publish",
19
+ delete: "delete",
20
+ "kv:namespace": "kvnamespace",
21
+ "kv:key": "kvkey",
22
+ "kv:bulk": "kvbulk",
23
+ "r2 bucket": "r2-bucket",
24
+ "r2 object": "r2-object",
25
+ secret: "secret",
26
+ "secret:bulk": "secretbulk",
27
+ tail: "tail",
28
+ pages: "pages",
29
+ login: "login",
30
+ logout: "logout",
31
+ whoami: "whoami",
32
+ types: "types",
33
+ deployments: "deployments",
34
+ };
35
+
36
+ export function docsOptions(yargs: Argv<CommonYargsOptions>) {
37
+ return yargs.positional("command", {
38
+ describe: "Enter the wrangler command you want to know more about",
39
+ type: "string",
40
+ // requiresArg: true,
41
+ choices: [
42
+ "docs",
43
+ "init",
44
+ "generate",
45
+ "dev",
46
+ "publish",
47
+ "delete",
48
+ "tail",
49
+ "secret",
50
+ "secret:bulk",
51
+ "kv:namespace",
52
+ "kv:key",
53
+ "kv:bulk",
54
+ "pages",
55
+ // "queues", //TODO: Undocumented
56
+ "r2 object",
57
+ "r2 bucket",
58
+ // "dispatch-namespace", // TODO: Undocumented - Workers for Platforms
59
+ // "d1", //TODO: Undocumented
60
+ // "pubsub", //TODO: Undocumented
61
+ "login",
62
+ "logout",
63
+ "whoami",
64
+ "types",
65
+ "deployments",
66
+ "api",
67
+ ],
68
+ });
69
+ }
70
+
71
+ type DocsArgs = YargsOptionsToInterface<typeof docsOptions>;
72
+
73
+ function isValidParam(k: string): k is keyof typeof argToUrlHash {
74
+ return k in argToUrlHash;
75
+ }
76
+
77
+ export async function docsHandler(args: ArgumentsCamelCase<DocsArgs>) {
78
+ let urlToOpen =
79
+ "https://developers.cloudflare.com/workers/wrangler/commands/";
80
+
81
+ if (args.command === "api") {
82
+ //if api, take them to the API docs
83
+ urlToOpen = "https://developers.cloudflare.com/workers/wrangler/api/";
84
+ } else if (args.command && isValidParam(args.command)) {
85
+ //otherwise, they get the wrangler commands page
86
+ urlToOpen += `#${argToUrlHash[args.command]}`;
87
+ }
88
+
89
+ await printWranglerBanner();
90
+
91
+ logger.log(`Opening a link in your default browser: ${urlToOpen}`);
92
+ await openInBrowser(urlToOpen);
93
+ const config = readConfig(undefined, {});
94
+ await metrics.sendMetricsEvent("view docs", {
95
+ sendMetrics: config.send_metrics,
96
+ });
97
+ }
@@ -0,0 +1,88 @@
1
+ import { logger } from "../logger";
2
+
3
+ type VariableNames =
4
+ | "CLOUDFLARE_ACCOUNT_ID"
5
+ | "CLOUDFLARE_API_TOKEN"
6
+ | "CLOUDFLARE_API_KEY"
7
+ | "CLOUDFLARE_EMAIL"
8
+ | "WRANGLER_SEND_METRICS"
9
+ | "CLOUDFLARE_API_BASE_URL"
10
+ | "WRANGLER_LOG"
11
+ | "WRANGLER_API_ENVIRONMENT"
12
+ | "WRANGLER_CLIENT_ID"
13
+ | "WRANGLER_AUTH_DOMAIN"
14
+ | "WRANGLER_AUTH_URL"
15
+ | "WRANGLER_TOKEN_URL"
16
+ | "WRANGLER_REVOKE_URL"
17
+ | "WRANGLER_CF_AUTHORIZATION_TOKEN";
18
+
19
+ type DeprecatedNames =
20
+ | "CF_ACCOUNT_ID"
21
+ | "CF_API_TOKEN"
22
+ | "CF_API_KEY"
23
+ | "CF_EMAIL"
24
+ | "CF_API_BASE_URL";
25
+
26
+ /**
27
+ * Create a function used to access an environment variable.
28
+ *
29
+ * This is not memoized to allow us to change the value at runtime, such as in testing.
30
+ * A warning is shown if the client is using a deprecated version - but only once.
31
+ */
32
+ export function getEnvironmentVariableFactory({
33
+ variableName,
34
+ deprecatedName,
35
+ }: {
36
+ variableName: VariableNames;
37
+ deprecatedName?: DeprecatedNames;
38
+ }): () => string | undefined;
39
+
40
+ /**
41
+ * Create a function used to access an environment variable, with a default value.
42
+ *
43
+ * This is not memoized to allow us to change the value at runtime, such as in testing.
44
+ * A warning is shown if the client is using a deprecated version - but only once.
45
+ */
46
+ export function getEnvironmentVariableFactory({
47
+ variableName,
48
+ deprecatedName,
49
+ defaultValue,
50
+ }: {
51
+ variableName: VariableNames;
52
+ deprecatedName?: DeprecatedNames;
53
+ defaultValue: () => string;
54
+ }): () => string;
55
+
56
+ /**
57
+ * Create a function used to access an environment variable.
58
+ *
59
+ * This is not memoized to allow us to change the value at runtime, such as in testing.
60
+ * A warning is shown if the client is using a deprecated version - but only once.
61
+ */
62
+ export function getEnvironmentVariableFactory({
63
+ variableName,
64
+ deprecatedName,
65
+ defaultValue,
66
+ }: {
67
+ variableName: VariableNames;
68
+ deprecatedName?: DeprecatedNames;
69
+ defaultValue?: () => string;
70
+ }): () => string | undefined {
71
+ let hasWarned = false;
72
+ return () => {
73
+ if (process.env[variableName]) {
74
+ return process.env[variableName];
75
+ } else if (deprecatedName && process.env[deprecatedName]) {
76
+ if (!hasWarned) {
77
+ // Only show the warning once.
78
+ hasWarned = true;
79
+ logger.warn(
80
+ `Using "${deprecatedName}" environment variable. This is deprecated. Please use "${variableName}", instead.`
81
+ );
82
+ }
83
+ return process.env[deprecatedName];
84
+ } else {
85
+ return defaultValue?.();
86
+ }
87
+ };
88
+ }
@@ -0,0 +1,30 @@
1
+ import { getEnvironmentVariableFactory } from "./factory";
2
+
3
+ /**
4
+ * `WRANGLER_SEND_METRICS` can override whether we attempt to send metrics information to Sparrow.
5
+ */
6
+ export const getWranglerSendMetricsFromEnv = getEnvironmentVariableFactory({
7
+ variableName: "WRANGLER_SEND_METRICS",
8
+ });
9
+
10
+ /**
11
+ * Set `WRANGLER_API_ENVIRONMENT` environment variable to "staging" to tell Wrangler to hit the staging APIs rather than production.
12
+ */
13
+ export const getCloudflareApiEnvironmentFromEnv = getEnvironmentVariableFactory(
14
+ {
15
+ variableName: "WRANGLER_API_ENVIRONMENT",
16
+ defaultValue: () => "production",
17
+ }
18
+ );
19
+
20
+ /**
21
+ * `CLOUDFLARE_API_BASE_URL` specifies the URL to the Cloudflare API.
22
+ */
23
+ export const getCloudflareApiBaseUrl = getEnvironmentVariableFactory({
24
+ variableName: "CLOUDFLARE_API_BASE_URL",
25
+ deprecatedName: "CF_API_BASE_URL",
26
+ defaultValue: () =>
27
+ getCloudflareApiEnvironmentFromEnv() === "staging"
28
+ ? "https://api.staging.cloudflare.com/client/v4"
29
+ : "https://api.cloudflare.com/client/v4",
30
+ });