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.
Files changed (237) hide show
  1. package/README.md +3 -3
  2. package/bin/wrangler.js +30 -10
  3. package/miniflare-dist/index.mjs +126 -74
  4. package/package.json +27 -19
  5. package/src/__tests__/api-dev.test.ts +65 -36
  6. package/src/__tests__/api-devregistry.test.ts +121 -0
  7. package/src/__tests__/api.test.ts +27 -5
  8. package/src/__tests__/configuration.test.ts +567 -86
  9. package/src/__tests__/d1/d1.test.ts +82 -0
  10. package/src/__tests__/d1/execute.test.ts +66 -0
  11. package/src/__tests__/d1/migrate.test.ts +157 -0
  12. package/src/__tests__/d1/splitter.test.ts +255 -0
  13. package/src/__tests__/delete.test.ts +91 -49
  14. package/src/__tests__/deployments.test.ts +330 -56
  15. package/src/__tests__/dev.test.tsx +198 -90
  16. package/src/__tests__/generate.test.ts +12 -10
  17. package/src/__tests__/guess-worker-format.test.ts +35 -0
  18. package/src/__tests__/helpers/end-event-loop.ts +6 -0
  19. package/src/__tests__/helpers/mock-auth-domain.ts +20 -0
  20. package/src/__tests__/helpers/mock-console.ts +6 -0
  21. package/src/__tests__/helpers/mock-dialogs.ts +71 -85
  22. package/src/__tests__/helpers/mock-get-pages-upload-token.ts +25 -0
  23. package/src/__tests__/helpers/mock-get-zone-from-host.ts +8 -5
  24. package/src/__tests__/helpers/mock-known-routes.ts +7 -2
  25. package/src/__tests__/helpers/mock-kv.ts +29 -16
  26. package/src/__tests__/helpers/mock-oauth-flow.ts +103 -92
  27. package/src/__tests__/helpers/mock-process.ts +8 -13
  28. package/src/__tests__/helpers/mock-set-timeout.ts +16 -0
  29. package/src/__tests__/helpers/msw/blob-worker.cjs +19 -0
  30. package/src/__tests__/helpers/msw/handlers/deployments.ts +128 -27
  31. package/src/__tests__/helpers/msw/handlers/namespaces.ts +18 -41
  32. package/src/__tests__/helpers/msw/handlers/oauth.ts +13 -18
  33. package/src/__tests__/helpers/msw/handlers/r2.ts +14 -34
  34. package/src/__tests__/helpers/msw/handlers/script.ts +9 -28
  35. package/src/__tests__/helpers/msw/handlers/user.ts +13 -24
  36. package/src/__tests__/helpers/msw/handlers/zones.ts +6 -8
  37. package/src/__tests__/helpers/msw/index.ts +32 -1
  38. package/src/__tests__/helpers/msw/read-file-sync.js +61 -0
  39. package/src/__tests__/helpers/string-dynamic-values-matcher.ts +28 -0
  40. package/src/__tests__/helpers/worker-scripts/parent-worker.js +4 -1
  41. package/src/__tests__/index.test.ts +90 -72
  42. package/src/__tests__/init.test.ts +927 -631
  43. package/src/__tests__/jest.setup.ts +19 -42
  44. package/src/__tests__/kv.test.ts +355 -231
  45. package/src/__tests__/logger.test.ts +68 -2
  46. package/src/__tests__/logout.test.ts +47 -0
  47. package/src/__tests__/metrics.test.ts +94 -51
  48. package/src/__tests__/middleware.scheduled.test.ts +42 -32
  49. package/src/__tests__/middleware.test.ts +212 -122
  50. package/src/__tests__/mtls-certificates.test.ts +588 -0
  51. package/src/__tests__/pages/deployment-list.test.ts +80 -0
  52. package/src/__tests__/pages/functions-build.test.ts +452 -0
  53. package/src/__tests__/pages/pages.test.ts +81 -0
  54. package/src/__tests__/pages/project-create.test.ts +63 -0
  55. package/src/__tests__/pages/project-list.test.ts +110 -0
  56. package/src/__tests__/pages/project-upload.test.ts +500 -0
  57. package/src/__tests__/pages/publish.test.ts +2864 -0
  58. package/src/__tests__/pages-deployment-tail.test.ts +955 -0
  59. package/src/__tests__/parse.test.ts +106 -0
  60. package/src/__tests__/publish.test.ts +1615 -852
  61. package/src/__tests__/pubsub.test.ts +226 -100
  62. package/src/__tests__/queues.test.ts +238 -77
  63. package/src/__tests__/r2.test.ts +55 -57
  64. package/src/__tests__/secret.test.ts +179 -130
  65. package/src/__tests__/tail.test.ts +267 -109
  66. package/src/__tests__/test-old-node-version.js +3 -3
  67. package/src/__tests__/traverse-module-graph.test.ts +220 -0
  68. package/src/__tests__/tsconfig-sanity.ts +12 -0
  69. package/src/__tests__/tsconfig.json +8 -0
  70. package/src/__tests__/tsconfig.tsbuildinfo +1 -0
  71. package/src/__tests__/type-generation.test.ts +43 -26
  72. package/src/__tests__/user.test.ts +35 -72
  73. package/src/__tests__/whoami.test.tsx +8 -114
  74. package/src/__tests__/worker-namespace.test.ts +83 -69
  75. package/src/api/dev.ts +168 -60
  76. package/src/api/index.ts +10 -1
  77. package/src/api/mtls-certificate.ts +148 -0
  78. package/src/api/pages/create-worker-bundle-contents.ts +76 -0
  79. package/src/api/pages/index.ts +5 -0
  80. package/src/api/pages/publish.tsx +355 -0
  81. package/src/bundle.ts +263 -140
  82. package/src/cfetch/index.ts +0 -2
  83. package/src/cfetch/internal.ts +16 -21
  84. package/src/cli.ts +4 -4
  85. package/src/config/config.ts +14 -7
  86. package/src/config/environment.ts +79 -24
  87. package/src/config/index.ts +99 -38
  88. package/src/config/validation-helpers.ts +1 -1
  89. package/src/config/validation.ts +248 -19
  90. package/src/create-worker-preview.ts +19 -8
  91. package/src/create-worker-upload-form.ts +60 -22
  92. package/src/d1/backups.tsx +43 -42
  93. package/src/d1/constants.ts +2 -0
  94. package/src/d1/create.tsx +44 -30
  95. package/src/d1/{delete.tsx → delete.ts} +11 -14
  96. package/src/d1/execute.tsx +209 -151
  97. package/src/d1/index.ts +31 -7
  98. package/src/d1/list.tsx +22 -10
  99. package/src/d1/migrations/apply.tsx +212 -0
  100. package/src/d1/migrations/create.tsx +79 -0
  101. package/src/d1/migrations/helpers.ts +172 -0
  102. package/src/d1/migrations/index.ts +3 -0
  103. package/src/d1/migrations/list.tsx +95 -0
  104. package/src/d1/migrations/options.ts +23 -0
  105. package/src/d1/options.ts +12 -2
  106. package/src/d1/splitter.ts +161 -0
  107. package/src/d1/{types.tsx → types.ts} +11 -0
  108. package/src/d1/utils.ts +12 -2
  109. package/src/delete.ts +8 -16
  110. package/src/deployments.ts +340 -46
  111. package/src/deprecated/index.ts +8 -302
  112. package/src/dev/dev.tsx +57 -44
  113. package/src/dev/local.tsx +294 -91
  114. package/src/dev/remote.tsx +32 -3
  115. package/src/dev/start-server.ts +89 -68
  116. package/src/dev/use-esbuild.ts +17 -18
  117. package/src/dev/validate-dev-props.ts +9 -0
  118. package/src/{dev-registry.tsx → dev-registry.ts} +2 -1
  119. package/src/dev.tsx +178 -118
  120. package/src/dialogs.ts +136 -0
  121. package/src/dispatch-namespace.ts +21 -17
  122. package/src/docs/index.ts +97 -0
  123. package/src/entry.ts +19 -11
  124. package/src/environment-variables/factory.ts +88 -0
  125. package/src/environment-variables/misc-variables.ts +30 -0
  126. package/src/generate/index.ts +298 -0
  127. package/src/git-client.ts +15 -4
  128. package/src/{index.tsx → index.ts} +137 -63
  129. package/src/init.ts +249 -187
  130. package/src/inspect.ts +16 -1
  131. package/src/jest.d.ts +4 -0
  132. package/src/kv/index.ts +15 -17
  133. package/src/logger.ts +32 -5
  134. package/src/metrics/metrics-config.ts +3 -3
  135. package/src/metrics/send-event.ts +6 -1
  136. package/src/miniflare-cli/assets.ts +64 -28
  137. package/src/miniflare-cli/index.ts +4 -7
  138. package/src/miniflare-cli/tsconfig.json +9 -0
  139. package/src/miniflare-cli/tsconfig.tsbuildinfo +1 -0
  140. package/src/miniflare-cli/types.ts +11 -0
  141. package/src/module-collection.ts +91 -25
  142. package/src/mtls-certificate/cli.ts +155 -0
  143. package/src/pages/build.ts +410 -0
  144. package/src/pages/buildFunctions.ts +140 -0
  145. package/src/pages/deployment-tails.ts +281 -0
  146. package/src/pages/deployments.tsx +11 -33
  147. package/src/pages/{dev.tsx → dev.ts} +147 -124
  148. package/src/pages/errors.ts +1 -0
  149. package/src/pages/functions/buildPlugin.ts +72 -69
  150. package/src/pages/functions/buildWorker.ts +249 -114
  151. package/src/pages/functions/tsconfig.json +8 -0
  152. package/src/pages/functions/tsconfig.tsbuildinfo +1 -0
  153. package/src/pages/{functions.tsx → functions.ts} +8 -4
  154. package/src/pages/{index.tsx → index.ts} +11 -3
  155. package/src/pages/projects.tsx +12 -22
  156. package/src/pages/prompt-select-project.tsx +31 -0
  157. package/src/pages/publish.tsx +45 -214
  158. package/src/pages/types.ts +6 -9
  159. package/src/pages/upload.tsx +58 -14
  160. package/src/pages/utils.ts +14 -3
  161. package/src/parse.ts +23 -1
  162. package/src/paths.ts +1 -1
  163. package/src/proxy.ts +5 -0
  164. package/src/publish/index.ts +20 -16
  165. package/src/publish/publish.ts +72 -47
  166. package/src/pubsub/{pubsub-commands.tsx → pubsub-commands.ts} +19 -20
  167. package/src/queues/cli/commands/consumer/add.ts +24 -24
  168. package/src/queues/cli/commands/consumer/index.ts +3 -6
  169. package/src/queues/cli/commands/consumer/remove.ts +11 -18
  170. package/src/queues/cli/commands/create.ts +8 -8
  171. package/src/queues/cli/commands/delete.ts +8 -8
  172. package/src/queues/cli/commands/index.ts +6 -4
  173. package/src/queues/cli/commands/list.ts +8 -8
  174. package/src/queues/client.ts +1 -0
  175. package/src/queues/utils.ts +18 -0
  176. package/src/r2/constants.ts +4 -0
  177. package/src/r2/helpers.ts +1 -0
  178. package/src/r2/index.ts +40 -28
  179. package/src/secret/index.ts +14 -17
  180. package/src/{sites.tsx → sites.ts} +1 -1
  181. package/src/tail/createTail.ts +94 -3
  182. package/src/tail/filters.ts +1 -1
  183. package/src/tail/index.ts +8 -11
  184. package/src/tail/printing.ts +15 -0
  185. package/src/traverse-module-graph.ts +53 -0
  186. package/src/tsconfig-sanity.ts +16 -0
  187. package/src/type-generation.ts +79 -57
  188. package/src/user/access.ts +0 -1
  189. package/src/user/auth-variables.ts +113 -0
  190. package/src/user/choose-account.tsx +1 -31
  191. package/src/user/index.ts +0 -1
  192. package/src/user/{user.tsx → user.ts} +123 -82
  193. package/src/utils/render.ts +93 -0
  194. package/src/{whoami.tsx → whoami.ts} +37 -71
  195. package/src/worker.ts +35 -3
  196. package/src/yargs-types.ts +22 -5
  197. package/templates/__tests__/tsconfig-sanity.ts +12 -0
  198. package/templates/__tests__/tsconfig.json +8 -0
  199. package/templates/__tests__/tsconfig.tsbuildinfo +1 -0
  200. package/templates/checked-fetch.js +9 -3
  201. package/templates/d1-beta-facade.js +95 -25
  202. package/templates/facade.d.ts +14 -0
  203. package/templates/first-party-worker-module-facade.ts +4 -3
  204. package/templates/format-dev-errors.ts +8 -6
  205. package/templates/gitignore +1 -0
  206. package/templates/init-tests/test-jest-new-worker.js +3 -5
  207. package/templates/init-tests/test-vitest-new-worker.js +3 -5
  208. package/templates/init-tests/test-vitest-new-worker.ts +25 -0
  209. package/templates/middleware/loader-modules.ts +2 -2
  210. package/templates/middleware/loader-sw.ts +51 -31
  211. package/templates/middleware/middleware-miniflare3-json-error.ts +32 -0
  212. package/templates/new-worker.ts +3 -0
  213. package/templates/pages-dev-pipeline.ts +4 -1
  214. package/templates/pages-shim.ts +4 -1
  215. package/templates/pages-template-plugin.ts +19 -10
  216. package/templates/serve-static-assets.ts +17 -14
  217. package/templates/service-bindings-module-facade.js +1 -0
  218. package/templates/tsconfig-sanity.ts +11 -0
  219. package/templates/tsconfig.init.json +105 -0
  220. package/templates/tsconfig.json +5 -103
  221. package/templates/tsconfig.tsbuildinfo +1 -0
  222. package/wrangler-dist/cli.d.ts +826 -77
  223. package/wrangler-dist/cli.js +130734 -140838
  224. package/wrangler-dist/wasm-sync.wasm +0 -0
  225. package/src/__tests__/api-devregistry.test.js +0 -57
  226. package/src/__tests__/d1.test.ts +0 -72
  227. package/src/__tests__/dialogs.test.tsx +0 -40
  228. package/src/__tests__/helpers/mock-cfetch.ts +0 -333
  229. package/src/__tests__/pages.test.ts +0 -2223
  230. package/src/dialogs.tsx +0 -163
  231. package/src/environment-variables.ts +0 -50
  232. package/src/pages/build.tsx +0 -238
  233. package/src/user/env-vars.ts +0 -46
  234. package/templates/experimental-local-cache-stubs.js +0 -27
  235. /package/src/{bundle-reporter.tsx → bundle-reporter.ts} +0 -0
  236. /package/src/dev/{get-local-persistence-path.tsx → get-local-persistence-path.ts} +0 -0
  237. /package/src/pages/{hash.tsx → hash.ts} +0 -0
@@ -1,14 +1,12 @@
1
- import { type Argv } from "yargs";
2
1
  import { readConfig } from "../../../config";
3
2
  import { logger } from "../../../logger";
4
3
  import { createQueue } from "../../client";
4
+ import type {
5
+ CommonYargsArgv,
6
+ StrictYargsOptionsToInterface,
7
+ } from "../../../yargs-types";
5
8
 
6
- interface Args {
7
- config?: string;
8
- name: string;
9
- }
10
-
11
- export function options(yargs: Argv): Argv<Args> {
9
+ export function options(yargs: CommonYargsArgv) {
12
10
  return yargs.positional("name", {
13
11
  type: "string",
14
12
  demandOption: true,
@@ -16,7 +14,9 @@ export function options(yargs: Argv): Argv<Args> {
16
14
  });
17
15
  }
18
16
 
19
- export async function handler(args: Args) {
17
+ export async function handler(
18
+ args: StrictYargsOptionsToInterface<typeof options>
19
+ ) {
20
20
  const config = readConfig(args.config, args);
21
21
 
22
22
  logger.log(`Creating queue ${args.name}.`);
@@ -1,14 +1,12 @@
1
- import { type Argv } from "yargs";
2
1
  import { readConfig } from "../../../config";
3
2
  import { logger } from "../../../logger";
4
3
  import { deleteQueue } from "../../client";
4
+ import type {
5
+ CommonYargsArgv,
6
+ StrictYargsOptionsToInterface,
7
+ } from "../../../yargs-types";
5
8
 
6
- interface Args {
7
- config?: string;
8
- name: string;
9
- }
10
-
11
- export function options(yargs: Argv): Argv<Args> {
9
+ export function options(yargs: CommonYargsArgv) {
12
10
  // TODO(soon) --force option
13
11
  return yargs.positional("name", {
14
12
  type: "string",
@@ -17,7 +15,9 @@ export function options(yargs: Argv): Argv<Args> {
17
15
  });
18
16
  }
19
17
 
20
- export async function handler(args: Args) {
18
+ export async function handler(
19
+ args: StrictYargsOptionsToInterface<typeof options>
20
+ ) {
21
21
  const config = readConfig(args.config, args);
22
22
 
23
23
  logger.log(`Deleting queue ${args.name}.`);
@@ -1,12 +1,12 @@
1
- import { type BuilderCallback } from "yargs";
2
- import { type CommonYargsOptions } from "../../../yargs-types";
1
+ import { HandleUnauthorizedError } from "../../utils";
3
2
  import { consumers } from "./consumer";
4
3
 
5
4
  import { options as createOptions, handler as createHandler } from "./create";
6
5
  import { options as deleteOptions, handler as deleteHandler } from "./delete";
7
6
  import { options as listOptions, handler as listHandler } from "./list";
7
+ import type { CommonYargsArgv } from "../../../yargs-types";
8
8
 
9
- export const queues: BuilderCallback<CommonYargsOptions, unknown> = (yargs) => {
9
+ export function queues(yargs: CommonYargsArgv) {
10
10
  yargs.command("list", "List Queues", listOptions, listHandler);
11
11
 
12
12
  yargs.command(
@@ -30,4 +30,6 @@ export const queues: BuilderCallback<CommonYargsOptions, unknown> = (yargs) => {
30
30
  await consumers(consumersYargs);
31
31
  }
32
32
  );
33
- };
33
+
34
+ yargs.fail(HandleUnauthorizedError);
35
+ }
@@ -1,14 +1,12 @@
1
- import { type Argv } from "yargs";
2
1
  import { readConfig } from "../../../config";
3
2
  import { logger } from "../../../logger";
4
3
  import { listQueues } from "../../client";
4
+ import type {
5
+ CommonYargsArgv,
6
+ StrictYargsOptionsToInterface,
7
+ } from "../../../yargs-types";
5
8
 
6
- interface Args {
7
- config?: string;
8
- page?: number;
9
- }
10
-
11
- export function options(yargs: Argv): Argv<Args> {
9
+ export function options(yargs: CommonYargsArgv) {
12
10
  return yargs.options({
13
11
  page: {
14
12
  type: "number",
@@ -17,7 +15,9 @@ export function options(yargs: Argv): Argv<Args> {
17
15
  });
18
16
  }
19
17
 
20
- export async function handler(args: Args) {
18
+ export async function handler(
19
+ args: StrictYargsOptionsToInterface<typeof options>
20
+ ) {
21
21
  const config = readConfig(args.config, args);
22
22
 
23
23
  const queues = await listQueues(config, args.page);
@@ -90,6 +90,7 @@ export interface ConsumerSettings {
90
90
  batch_size?: number;
91
91
  max_retries?: number;
92
92
  max_wait_time_ms?: number;
93
+ max_concurrency?: number | null;
93
94
  }
94
95
 
95
96
  export interface ConsumerResponse extends PostConsumerBody {
@@ -0,0 +1,18 @@
1
+ import { logger } from "../logger";
2
+ import { type ParseError } from "../parse";
3
+ import { getAccountId } from "../user";
4
+
5
+ const isFetchError = (err: unknown): err is ParseError => err instanceof Error;
6
+
7
+ export const HandleUnauthorizedError = async (_msg: string, err: Error) => {
8
+ //@ts-expect-error non-standard property on Error
9
+ if (isFetchError(err) && err.code === 10023) {
10
+ const accountId = await getAccountId();
11
+ if (accountId) {
12
+ return logger.log(
13
+ `Queues is not currently enabled on this account. Go to https://dash.cloudflare.com/${accountId}/workers/queues to enable it.`
14
+ );
15
+ }
16
+ }
17
+ throw err;
18
+ };
@@ -0,0 +1,4 @@
1
+ /**
2
+ * The maximum file size we can upload using the V4 API.
3
+ */
4
+ export const MAX_UPLOAD_SIZE = 300 * 1024 * 1024;
package/src/r2/helpers.ts CHANGED
@@ -113,6 +113,7 @@ export async function putR2Object(
113
113
  body: object,
114
114
  headers,
115
115
  method: "PUT",
116
+ duplex: "half",
116
117
  }
117
118
  );
118
119
  }
package/src/r2/index.ts CHANGED
@@ -1,11 +1,14 @@
1
1
  import * as fs from "node:fs";
2
2
  import * as stream from "node:stream";
3
3
 
4
+ import prettyBytes from "pretty-bytes";
4
5
  import { readConfig } from "../config";
6
+ import { FatalError } from "../errors";
5
7
  import { CommandLineArgsError, printWranglerBanner } from "../index";
6
8
  import { logger } from "../logger";
7
9
  import * as metrics from "../metrics";
8
10
  import { requireAuth } from "../user";
11
+ import { MAX_UPLOAD_SIZE } from "./constants";
9
12
  import {
10
13
  bucketAndKeyFromObjectPath,
11
14
  createR2Bucket,
@@ -16,22 +19,23 @@ import {
16
19
  putR2Object,
17
20
  } from "./helpers";
18
21
 
19
- import type { ConfigPath } from "../index";
22
+ import type { CommonYargsArgv } from "../yargs-types";
20
23
  import type { Readable } from "node:stream";
21
- import type { BuilderCallback } from "yargs";
22
24
 
23
- export const r2: BuilderCallback<unknown, unknown> = (r2Yargs) => {
25
+ export function r2(r2Yargs: CommonYargsArgv) {
24
26
  return r2Yargs
25
27
  .command("object", "Manage R2 objects", (r2ObjectYargs) => {
26
28
  return r2ObjectYargs
27
29
  .command(
28
30
  "get <objectPath>",
29
31
  "Fetch an object from an R2 bucket",
30
- (Objectyargs) => {
31
- return Objectyargs.positional("objectPath", {
32
- describe: "The source object path in the form of {bucket}/{key}",
33
- type: "string",
34
- })
32
+ (objectArgs) => {
33
+ return objectArgs
34
+ .positional("objectPath", {
35
+ describe:
36
+ "The source object path in the form of {bucket}/{key}",
37
+ type: "string",
38
+ })
35
39
  .option("file", {
36
40
  describe: "The destination file to create",
37
41
  alias: "f",
@@ -48,10 +52,7 @@ export const r2: BuilderCallback<unknown, unknown> = (r2Yargs) => {
48
52
  });
49
53
  },
50
54
  async (objectGetYargs) => {
51
- const config = readConfig(
52
- objectGetYargs.config as ConfigPath,
53
- objectGetYargs
54
- );
55
+ const config = readConfig(objectGetYargs.config, objectGetYargs);
55
56
  const accountId = await requireAuth(config);
56
57
  const { objectPath, pipe } = objectGetYargs;
57
58
  const { bucket, key } = bucketAndKeyFromObjectPath(objectPath);
@@ -141,10 +142,7 @@ export const r2: BuilderCallback<unknown, unknown> = (r2Yargs) => {
141
142
  async (objectPutYargs) => {
142
143
  await printWranglerBanner();
143
144
 
144
- const config = readConfig(
145
- objectPutYargs.config as ConfigPath,
146
- objectPutYargs
147
- );
145
+ const config = readConfig(objectPutYargs.config, objectPutYargs);
148
146
  const accountId = await requireAuth(config);
149
147
  const { objectPath, file, pipe, ...options } = objectPutYargs;
150
148
  const { bucket, key } = bucketAndKeyFromObjectPath(objectPath);
@@ -176,6 +174,15 @@ export const r2: BuilderCallback<unknown, unknown> = (r2Yargs) => {
176
174
  objectSize = object.byteLength;
177
175
  }
178
176
 
177
+ if (objectSize > MAX_UPLOAD_SIZE) {
178
+ throw new FatalError(
179
+ `Error: Wrangler only supports uploading files up to ${prettyBytes(
180
+ MAX_UPLOAD_SIZE
181
+ )} in size\n${key} is ${prettyBytes(objectSize)} in size`,
182
+ 1
183
+ );
184
+ }
185
+
179
186
  logger.log(`Creating object "${key}" in bucket "${bucket}".`);
180
187
  await putR2Object(accountId, bucket, key, object, {
181
188
  ...options,
@@ -198,7 +205,7 @@ export const r2: BuilderCallback<unknown, unknown> = (r2Yargs) => {
198
205
  const { objectPath } = args;
199
206
  await printWranglerBanner();
200
207
 
201
- const config = readConfig(args.config as ConfigPath, args);
208
+ const config = readConfig(args.config, args);
202
209
  const accountId = await requireAuth(config);
203
210
  const { bucket, key } = bucketAndKeyFromObjectPath(objectPath);
204
211
  logger.log(`Deleting object "${key}" from bucket "${bucket}".`);
@@ -223,7 +230,7 @@ export const r2: BuilderCallback<unknown, unknown> = (r2Yargs) => {
223
230
  async (args) => {
224
231
  await printWranglerBanner();
225
232
 
226
- const config = readConfig(args.config as ConfigPath, args);
233
+ const config = readConfig(args.config, args);
227
234
 
228
235
  const accountId = await requireAuth(config);
229
236
 
@@ -236,16 +243,21 @@ export const r2: BuilderCallback<unknown, unknown> = (r2Yargs) => {
236
243
  }
237
244
  );
238
245
 
239
- r2BucketYargs.command("list", "List R2 buckets", {}, async (args) => {
240
- const config = readConfig(args.config as ConfigPath, args);
246
+ r2BucketYargs.command(
247
+ "list",
248
+ "List R2 buckets",
249
+ (listArgs) => listArgs,
250
+ async (args) => {
251
+ const config = readConfig(args.config, args);
241
252
 
242
- const accountId = await requireAuth(config);
253
+ const accountId = await requireAuth(config);
243
254
 
244
- logger.log(JSON.stringify(await listR2Buckets(accountId), null, 2));
245
- await metrics.sendMetricsEvent("list r2 buckets", {
246
- sendMetrics: config.send_metrics,
247
- });
248
- });
255
+ logger.log(JSON.stringify(await listR2Buckets(accountId), null, 2));
256
+ await metrics.sendMetricsEvent("list r2 buckets", {
257
+ sendMetrics: config.send_metrics,
258
+ });
259
+ }
260
+ );
249
261
 
250
262
  r2BucketYargs.command(
251
263
  "delete <name>",
@@ -260,7 +272,7 @@ export const r2: BuilderCallback<unknown, unknown> = (r2Yargs) => {
260
272
  async (args) => {
261
273
  await printWranglerBanner();
262
274
 
263
- const config = readConfig(args.config as ConfigPath, args);
275
+ const config = readConfig(args.config, args);
264
276
 
265
277
  const accountId = await requireAuth(config);
266
278
 
@@ -274,4 +286,4 @@ export const r2: BuilderCallback<unknown, unknown> = (r2Yargs) => {
274
286
  );
275
287
  return r2BucketYargs;
276
288
  });
277
- };
289
+ }
@@ -13,14 +13,12 @@ import * as metrics from "../metrics";
13
13
  import { parseJSON, readFileSync } from "../parse";
14
14
  import { requireAuth } from "../user";
15
15
 
16
- import type { ConfigPath } from "../index";
17
16
  import type {
18
- CommonYargsOptions,
19
- YargsOptionsToInterface,
17
+ CommonYargsArgv,
18
+ StrictYargsOptionsToInterface,
20
19
  } from "../yargs-types";
21
- import type { Argv } from "yargs";
22
20
 
23
- export const secret = (secretYargs: Argv<CommonYargsOptions>) => {
21
+ export const secret = (secretYargs: CommonYargsArgv) => {
24
22
  return secretYargs
25
23
  .option("legacy-env", {
26
24
  type: "boolean",
@@ -44,7 +42,7 @@ export const secret = (secretYargs: Argv<CommonYargsOptions>) => {
44
42
  },
45
43
  async (args) => {
46
44
  await printWranglerBanner();
47
- const config = readConfig(args.config as ConfigPath, args);
45
+ const config = readConfig(args.config, args);
48
46
 
49
47
  const scriptName = getLegacyScriptName(args, config);
50
48
  if (!scriptName) {
@@ -58,7 +56,7 @@ export const secret = (secretYargs: Argv<CommonYargsOptions>) => {
58
56
  const isInteractive = process.stdin.isTTY;
59
57
  const secretValue = trimTrailingWhitespace(
60
58
  isInteractive
61
- ? await prompt("Enter a secret value:", "password")
59
+ ? await prompt("Enter a secret value:", { isSecret: true })
62
60
  : await readFromStdin()
63
61
  );
64
62
 
@@ -102,19 +100,21 @@ export const secret = (secretYargs: Argv<CommonYargsOptions>) => {
102
100
  },
103
101
  bindings: {
104
102
  kv_namespaces: [],
103
+ send_email: [],
105
104
  vars: {},
106
- metadata_binding: undefined,
107
105
  durable_objects: { bindings: [] },
108
106
  queues: [],
109
107
  r2_buckets: [],
110
108
  d1_databases: [],
111
109
  services: [],
110
+ analytics_engine_datasets: [],
112
111
  wasm_modules: {},
113
112
  text_blobs: {},
114
113
  data_blobs: {},
115
114
  dispatch_namespaces: [],
115
+ mtls_certificates: [],
116
116
  logfwdr: { schema: undefined, bindings: [] },
117
- unsafe: [],
117
+ unsafe: { bindings: undefined, metadata: undefined },
118
118
  },
119
119
  modules: [],
120
120
  migrations: undefined,
@@ -172,7 +172,7 @@ export const secret = (secretYargs: Argv<CommonYargsOptions>) => {
172
172
  });
173
173
  },
174
174
  async (args) => {
175
- const config = readConfig(args.config as ConfigPath, args);
175
+ const config = readConfig(args.config, args);
176
176
 
177
177
  const scriptName = getLegacyScriptName(args, config);
178
178
  if (!scriptName) {
@@ -222,7 +222,7 @@ export const secret = (secretYargs: Argv<CommonYargsOptions>) => {
222
222
  });
223
223
  },
224
224
  async (args) => {
225
- const config = readConfig(args.config as ConfigPath, args);
225
+ const config = readConfig(args.config, args);
226
226
 
227
227
  const scriptName = getLegacyScriptName(args, config);
228
228
  if (!scriptName) {
@@ -246,7 +246,7 @@ export const secret = (secretYargs: Argv<CommonYargsOptions>) => {
246
246
  );
247
247
  };
248
248
 
249
- export const secretBulkOptions = (yargs: Argv<CommonYargsOptions>) => {
249
+ export const secretBulkOptions = (yargs: CommonYargsArgv) => {
250
250
  return yargs
251
251
  .positional("json", {
252
252
  describe: `The JSON file of key-value pairs to upload, in form {"key": value, ...}`,
@@ -301,14 +301,11 @@ function readFromStdin(): Promise<string> {
301
301
  });
302
302
  }
303
303
 
304
- type SecretBulkArgs = YargsOptionsToInterface<typeof secretBulkOptions>;
304
+ type SecretBulkArgs = StrictYargsOptionsToInterface<typeof secretBulkOptions>;
305
305
 
306
306
  export const secretBulkHandler = async (secretBulkArgs: SecretBulkArgs) => {
307
307
  await printWranglerBanner();
308
- const config = readConfig(
309
- secretBulkArgs.config as ConfigPath,
310
- secretBulkArgs
311
- );
308
+ const config = readConfig(secretBulkArgs.config, secretBulkArgs);
312
309
 
313
310
  const scriptName = getLegacyScriptName(secretBulkArgs, config);
314
311
  if (!scriptName) {
@@ -56,7 +56,7 @@ function hashFileContent(hasher: XXHashAPI, content: string): string {
56
56
  * Create a hashed asset key for the given asset.
57
57
  *
58
58
  * The key will change if the file path or content of the asset changes.
59
- * The algorithm used here matches that of Wrangler 1.
59
+ * The algorithm used here matches that of Wrangler v1.
60
60
  */
61
61
  function hashAsset(
62
62
  hasher: XXHashAPI,
@@ -7,6 +7,8 @@ export { translateCLICommandToFilterMessage } from "./filters";
7
7
  export { jsonPrintLogs, prettyPrintLogs } from "./printing";
8
8
  import type { Request } from "undici";
9
9
 
10
+ const TRACE_VERSION = "trace-v1";
11
+
10
12
  /**
11
13
  * When creating a Tail, the response from the API contains
12
14
  * - an ID used for identifying the tail
@@ -59,6 +61,68 @@ function makeDeleteTailUrl(
59
61
  : `/accounts/${accountId}/workers/scripts/${workerName}/tails/${tailId}`;
60
62
  }
61
63
 
64
+ interface CreatePagesTailOptions {
65
+ accountId: string;
66
+ projectName: string;
67
+ deploymentId: string;
68
+ filters: TailFilterMessage;
69
+ debug?: boolean;
70
+ }
71
+
72
+ /**
73
+ * Create and connect to a Pages Function Tail.
74
+ *
75
+ * Under the hood, this function
76
+ * - Registers a new Tail with the API
77
+ * - Connects to the tail worker
78
+ * - Sends any filters over the connection
79
+ *
80
+ * @returns a websocket connection, an expiration, and a function to call to delete the tail
81
+ */
82
+ export async function createPagesTail({
83
+ accountId,
84
+ projectName,
85
+ deploymentId,
86
+ filters,
87
+ debug = false,
88
+ }: CreatePagesTailOptions) {
89
+ const tailRecord = await fetchResult<TailCreationApiResponse>(
90
+ `/accounts/${accountId}/pages/projects/${projectName}/deployments/${deploymentId}/tails`,
91
+ {
92
+ method: "POST",
93
+ body: JSON.stringify(filters),
94
+ }
95
+ );
96
+
97
+ const deleteTail = async () =>
98
+ fetchResult(
99
+ `/accounts/${accountId}/pages/projects/${projectName}/deployments/${deploymentId}/tails/${tailRecord.id}`,
100
+ { method: "DELETE" }
101
+ );
102
+
103
+ const tail = new WebSocket(tailRecord.url, TRACE_VERSION, {
104
+ headers: {
105
+ "Sec-WebSocket-Protocol": TRACE_VERSION, // needs to be `trace-v1` to be accepted
106
+ "User-Agent": `wrangler-js/${packageVersion}`,
107
+ },
108
+ });
109
+
110
+ // send filters when we open up
111
+ tail.on("open", () => {
112
+ tail.send(
113
+ JSON.stringify({ debug: debug }),
114
+ { binary: false, compress: false, mask: false, fin: true },
115
+ (err) => {
116
+ if (err) {
117
+ throw err;
118
+ }
119
+ }
120
+ );
121
+ });
122
+
123
+ return { tail, deleteTail, expiration: tailRecord.expires_at };
124
+ }
125
+
62
126
  /**
63
127
  * Create and connect to a tail.
64
128
  *
@@ -102,9 +166,9 @@ export async function createTail(
102
166
  }
103
167
 
104
168
  // connect to the tail
105
- const tail = new WebSocket(websocketUrl, "trace-v1", {
169
+ const tail = new WebSocket(websocketUrl, TRACE_VERSION, {
106
170
  headers: {
107
- "Sec-WebSocket-Protocol": "trace-v1", // needs to be `trace-v1` to be accepted
171
+ "Sec-WebSocket-Protocol": TRACE_VERSION, // needs to be `trace-v1` to be accepted
108
172
  "User-Agent": `wrangler-js/${packageVersion}`,
109
173
  },
110
174
  });
@@ -178,11 +242,18 @@ export type TailEventMessage = {
178
242
  * The event that triggered the worker. In the case of an HTTP request,
179
243
  * this will be a RequestEvent. If it's a cron trigger, it'll be a
180
244
  * ScheduledEvent. If it's a durable object alarm, it's an AlarmEvent.
245
+ * If it's a email, it'a an EmailEvent
181
246
  *
182
247
  * Until workers-types exposes individual types for export, we'll have
183
248
  * to just re-define these types ourselves.
184
249
  */
185
- event: RequestEvent | ScheduledEvent | AlarmEvent | undefined | null;
250
+ event:
251
+ | RequestEvent
252
+ | ScheduledEvent
253
+ | AlarmEvent
254
+ | EmailEvent
255
+ | undefined
256
+ | null;
186
257
  };
187
258
 
188
259
  /**
@@ -313,3 +384,23 @@ export type AlarmEvent = {
313
384
  */
314
385
  scheduledTime: string;
315
386
  };
387
+
388
+ /**
389
+ * An event that was triggered from an email
390
+ */
391
+ export type EmailEvent = {
392
+ /**
393
+ * Who sent the email
394
+ */
395
+ mailFrom: string;
396
+
397
+ /**
398
+ * Who was the email sent to
399
+ */
400
+ rcptTo: string;
401
+
402
+ /**
403
+ * Size of the email in bytes
404
+ */
405
+ rawSize: number;
406
+ };
@@ -7,7 +7,7 @@
7
7
 
8
8
  /**
9
9
  * These are the filters we accept in the CLI. They
10
- * were copied directly from wrangler 1 in order to
10
+ * were copied directly from Wrangler v1 in order to
11
11
  * maintain compatability, so they aren't actually the exact
12
12
  * filters we need to send up to the tail worker. They generally map 1:1,
13
13
  * but often require some transformation or
package/src/tail/index.ts CHANGED
@@ -3,7 +3,7 @@ import onExit from "signal-exit";
3
3
 
4
4
  import { fetchResult, fetchScriptContent } from "../cfetch";
5
5
  import { readConfig } from "../config";
6
- import { tailDOLogPrompt } from "../dialogs";
6
+ import { confirm } from "../dialogs";
7
7
  import {
8
8
  isLegacyEnv,
9
9
  printWranglerBanner,
@@ -20,16 +20,14 @@ import {
20
20
  translateCLICommandToFilterMessage,
21
21
  } from "./createTail";
22
22
  import type { WorkerMetadata } from "../create-worker-upload-form";
23
- import type { ConfigPath } from "../index";
24
23
  import type {
25
- CommonYargsOptions,
26
- YargsOptionsToInterface,
24
+ CommonYargsArgv,
25
+ StrictYargsOptionsToInterface,
27
26
  } from "../yargs-types";
28
27
  import type { TailCLIFilters } from "./createTail";
29
28
  import type { RawData } from "ws";
30
- import type { Argv } from "yargs";
31
29
 
32
- export function tailOptions(yargs: Argv<CommonYargsOptions>) {
30
+ export function tailOptions(yargs: CommonYargsArgv) {
33
31
  return yargs
34
32
  .positional("worker", {
35
33
  describe: "Name or route of the worker to tail",
@@ -86,13 +84,13 @@ export function tailOptions(yargs: Argv<CommonYargsOptions>) {
86
84
  });
87
85
  }
88
86
 
89
- type TailArgs = YargsOptionsToInterface<typeof tailOptions>;
87
+ type TailArgs = StrictYargsOptionsToInterface<typeof tailOptions>;
90
88
 
91
89
  export async function tailHandler(args: TailArgs) {
92
90
  if (args.format === "pretty") {
93
91
  await printWranglerBanner();
94
92
  }
95
- const config = readConfig(args.config as ConfigPath, args);
93
+ const config = readConfig(args.config, args);
96
94
  await metrics.sendMetricsEvent("begin log stream", {
97
95
  sendMetrics: config.send_metrics,
98
96
  });
@@ -121,7 +119,7 @@ export async function tailHandler(args: TailArgs) {
121
119
  status: args.status as ("ok" | "error" | "canceled")[] | undefined,
122
120
  header: args.header,
123
121
  method: args.method,
124
- samplingRate: args["sampling-rate"],
122
+ samplingRate: args.samplingRate,
125
123
  search: args.search,
126
124
  clientIp: args.ip,
127
125
  };
@@ -144,8 +142,7 @@ export async function tailHandler(args: TailArgs) {
144
142
  `Beginning log collection requires restarting the Durable Objects associated with ${scriptName}. Any WebSocket connections or other non-persisted state will be lost as part of this restart.`
145
143
  );
146
144
 
147
- const shouldContinue = await tailDOLogPrompt();
148
- if (!shouldContinue) {
145
+ if (!(await confirm("Would you like to continue?"))) {
149
146
  return;
150
147
  }
151
148
  }
@@ -1,6 +1,7 @@
1
1
  import { logger } from "../logger";
2
2
  import type {
3
3
  AlarmEvent,
4
+ EmailEvent,
4
5
  RequestEvent,
5
6
  ScheduledEvent,
6
7
  TailEventMessage,
@@ -30,6 +31,16 @@ export function prettyPrintLogs(data: WebSocket.RawData): void {
30
31
  ? `${requestMethod} ${url} - ${outcome} @ ${datetime}`
31
32
  : `[missing request] - ${outcome} @ ${datetime}`
32
33
  );
34
+ } else if (isEmailEvent(eventMessage.event)) {
35
+ const outcome = prettifyOutcome(eventMessage.outcome);
36
+ const datetime = new Date(eventMessage.eventTimestamp).toLocaleString();
37
+ const mailFrom = eventMessage.event.mailFrom;
38
+ const rcptTo = eventMessage.event.rcptTo;
39
+ const rawSize = eventMessage.event.rawSize;
40
+
41
+ logger.log(
42
+ `Email from:${mailFrom} to:${rcptTo} size:${rawSize} @ ${datetime} - ${outcome}`
43
+ );
33
44
  } else if (isAlarmEvent(eventMessage.event)) {
34
45
  const outcome = prettifyOutcome(eventMessage.outcome);
35
46
  const datetime = new Date(
@@ -74,6 +85,10 @@ function isScheduledEvent(
74
85
  return Boolean(event && "cron" in event);
75
86
  }
76
87
 
88
+ function isEmailEvent(event: TailEventMessage["event"]): event is EmailEvent {
89
+ return Boolean(event && "mailFrom" in event);
90
+ }
91
+
77
92
  /**
78
93
  * Check to see if an event sent from a worker is an AlarmEvent.
79
94
  *