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
@@ -358,6 +358,26 @@ function normalizeAndValidateMainField(
358
358
  }
359
359
  }
360
360
 
361
+ /**
362
+ * Validate the `base_dir` field and return the normalized values.
363
+ */
364
+ function normalizeAndValidateBaseDirField(
365
+ configPath: string | undefined,
366
+ rawDir: string | undefined
367
+ ): string | undefined {
368
+ const configDir = path.dirname(configPath ?? "wrangler.toml");
369
+ if (rawDir !== undefined) {
370
+ if (typeof rawDir === "string") {
371
+ const directory = path.resolve(configDir);
372
+ return path.resolve(directory, rawDir);
373
+ } else {
374
+ return rawDir;
375
+ }
376
+ } else {
377
+ return;
378
+ }
379
+ }
380
+
361
381
  /**
362
382
  * Validate the `dev` configuration and return the normalized values.
363
383
  */
@@ -741,7 +761,7 @@ function isValidRouteValue(item: unknown): boolean {
741
761
 
742
762
  /**
743
763
  * If account_id has been passed as an empty string, normalise it to undefined.
744
- * This is to workaround older wrangler1-era templates that have account_id = '',
764
+ * This is to workaround older Wrangler v1-era templates that have account_id = '',
745
765
  * which isn't a valid value anyway
746
766
  */
747
767
  function mutateEmptyStringAccountIDValue(
@@ -760,7 +780,7 @@ function mutateEmptyStringAccountIDValue(
760
780
 
761
781
  /**
762
782
  * Normalize empty string to `undefined` by mutating rawEnv.route value.
763
- * As part of backward compatibility with Wrangler1 converting empty string to `undefined`
783
+ * As part of backward compatibility with Wrangler v1 converting empty string to `undefined`
764
784
  */
765
785
  function mutateEmptyStringRouteValue(
766
786
  diagnostics: Diagnostics,
@@ -909,7 +929,6 @@ function normalizeAndValidateEnvironment(
909
929
 
910
930
  experimental(diagnostics, rawEnv, "unsafe");
911
931
  experimental(diagnostics, rawEnv, "services");
912
- experimental(diagnostics, rawEnv, "dispatch_namespaces");
913
932
 
914
933
  const route = normalizeAndValidateRoute(diagnostics, topLevelEnv, rawEnv);
915
934
 
@@ -1012,6 +1031,17 @@ function normalizeAndValidateEnvironment(
1012
1031
  ),
1013
1032
  deprecatedUpload
1014
1033
  ),
1034
+ base_dir: normalizeAndValidateBaseDirField(
1035
+ configPath,
1036
+ inheritable(
1037
+ diagnostics,
1038
+ topLevelEnv,
1039
+ rawEnv,
1040
+ "base_dir",
1041
+ isString,
1042
+ undefined
1043
+ )
1044
+ ),
1015
1045
  route,
1016
1046
  routes,
1017
1047
  triggers: inheritable(
@@ -1043,16 +1073,6 @@ function normalizeAndValidateEnvironment(
1043
1073
  validateVars(envName),
1044
1074
  {}
1045
1075
  ),
1046
- metadata_binding: notInheritable(
1047
- diagnostics,
1048
- topLevelEnv,
1049
- rawConfig,
1050
- rawEnv,
1051
- envName,
1052
- "metadata_binding",
1053
- isString,
1054
- undefined
1055
- ),
1056
1076
  define: notInheritable(
1057
1077
  diagnostics,
1058
1078
  topLevelEnv,
@@ -1085,6 +1105,16 @@ function normalizeAndValidateEnvironment(
1085
1105
  validateBindingArray(envName, validateKVBinding),
1086
1106
  []
1087
1107
  ),
1108
+ send_email: notInheritable(
1109
+ diagnostics,
1110
+ topLevelEnv,
1111
+ rawConfig,
1112
+ rawEnv,
1113
+ envName,
1114
+ "send_email",
1115
+ validateBindingArray(envName, validateSendEmailBinding),
1116
+ []
1117
+ ),
1088
1118
  queues: notInheritable(
1089
1119
  diagnostics,
1090
1120
  topLevelEnv,
@@ -1125,6 +1155,16 @@ function normalizeAndValidateEnvironment(
1125
1155
  validateBindingArray(envName, validateServiceBinding),
1126
1156
  []
1127
1157
  ),
1158
+ analytics_engine_datasets: notInheritable(
1159
+ diagnostics,
1160
+ topLevelEnv,
1161
+ rawConfig,
1162
+ rawEnv,
1163
+ envName,
1164
+ "analytics_engine_datasets",
1165
+ validateBindingArray(envName, validateAnalyticsEngineBinding),
1166
+ []
1167
+ ),
1128
1168
  dispatch_namespaces: notInheritable(
1129
1169
  diagnostics,
1130
1170
  topLevelEnv,
@@ -1135,6 +1175,16 @@ function normalizeAndValidateEnvironment(
1135
1175
  validateBindingArray(envName, validateWorkerNamespaceBinding),
1136
1176
  []
1137
1177
  ),
1178
+ mtls_certificates: notInheritable(
1179
+ diagnostics,
1180
+ topLevelEnv,
1181
+ rawConfig,
1182
+ rawEnv,
1183
+ envName,
1184
+ "mtls_certificates",
1185
+ validateBindingArray(envName, validateMTlsCertificateBinding),
1186
+ []
1187
+ ),
1138
1188
  logfwdr: inheritable(
1139
1189
  diagnostics,
1140
1190
  topLevelEnv,
@@ -1153,10 +1203,8 @@ function normalizeAndValidateEnvironment(
1153
1203
  rawEnv,
1154
1204
  envName,
1155
1205
  "unsafe",
1156
- validateBindingsProperty(envName, validateUnsafeBinding),
1157
- {
1158
- bindings: [],
1159
- }
1206
+ validateUnsafeSettings(envName),
1207
+ {}
1160
1208
  ),
1161
1209
  zone_id: rawEnv.zone_id,
1162
1210
  no_bundle: inheritable(
@@ -1486,6 +1534,62 @@ const validateBindingsProperty =
1486
1534
  return isValid;
1487
1535
  };
1488
1536
 
1537
+ const validateUnsafeSettings =
1538
+ (envName: string): ValidatorFn =>
1539
+ (diagnostics, field, value, config) => {
1540
+ const fieldPath =
1541
+ config === undefined ? `${field}` : `env.${envName}.${field}`;
1542
+
1543
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
1544
+ diagnostics.errors.push(
1545
+ `The field "${fieldPath}" should be an object but got ${JSON.stringify(
1546
+ value
1547
+ )}.`
1548
+ );
1549
+ return false;
1550
+ }
1551
+
1552
+ // At least one of bindings and metadata must exist
1553
+ if (!hasProperty(value, "bindings") && !hasProperty(value, "metadata")) {
1554
+ diagnostics.errors.push(
1555
+ `The field "${fieldPath}" should contain at least one of "bindings" or "metadata" properties but got ${JSON.stringify(
1556
+ value
1557
+ )}.`
1558
+ );
1559
+ return false;
1560
+ }
1561
+
1562
+ // unsafe.bindings
1563
+ if (hasProperty(value, "bindings") && value.bindings !== undefined) {
1564
+ const validateBindingsFn = validateBindingsProperty(
1565
+ envName,
1566
+ validateUnsafeBinding
1567
+ );
1568
+ const valid = validateBindingsFn(diagnostics, field, value, config);
1569
+ if (!valid) {
1570
+ return false;
1571
+ }
1572
+ }
1573
+
1574
+ // unsafe.metadata
1575
+ if (
1576
+ hasProperty(value, "metadata") &&
1577
+ value.metadata !== undefined &&
1578
+ (typeof value.metadata !== "object" ||
1579
+ value.metadata === null ||
1580
+ Array.isArray(value.metadata))
1581
+ ) {
1582
+ diagnostics.errors.push(
1583
+ `The field "${fieldPath}.metadata" should be an object but got ${JSON.stringify(
1584
+ value.metadata
1585
+ )}.`
1586
+ );
1587
+ return false;
1588
+ }
1589
+
1590
+ return true;
1591
+ };
1592
+
1489
1593
  /**
1490
1594
  * Check that the given field is a valid "durable_object" binding object.
1491
1595
  */
@@ -1591,6 +1695,7 @@ const validateUnsafeBinding: ValidatorFn = (diagnostics, field, value) => {
1591
1695
  "r2_bucket",
1592
1696
  "service",
1593
1697
  "logfwdr",
1698
+ "mtls_certificate",
1594
1699
  ];
1595
1700
 
1596
1701
  if (safeBindings.includes(value.type)) {
@@ -1701,6 +1806,53 @@ const validateKVBinding: ValidatorFn = (diagnostics, field, value) => {
1701
1806
  return isValid;
1702
1807
  };
1703
1808
 
1809
+ const validateSendEmailBinding: ValidatorFn = (diagnostics, field, value) => {
1810
+ if (typeof value !== "object" || value === null) {
1811
+ diagnostics.errors.push(
1812
+ `"send_email" bindings should be objects, but got ${JSON.stringify(
1813
+ value
1814
+ )}`
1815
+ );
1816
+ return false;
1817
+ }
1818
+ let isValid = true;
1819
+ // send email bindings must have a name.
1820
+ if (!isRequiredProperty(value, "name", "string")) {
1821
+ diagnostics.errors.push(
1822
+ `"${field}" bindings should have a string "name" field but got ${JSON.stringify(
1823
+ value
1824
+ )}.`
1825
+ );
1826
+ isValid = false;
1827
+ }
1828
+ if (!isOptionalProperty(value, "destination_address", "string")) {
1829
+ diagnostics.errors.push(
1830
+ `"${field}" bindings should, optionally, have a string "destination_address" field but got ${JSON.stringify(
1831
+ value
1832
+ )}.`
1833
+ );
1834
+ isValid = false;
1835
+ }
1836
+ if (!isOptionalProperty(value, "allowed_destination_addresses", "object")) {
1837
+ diagnostics.errors.push(
1838
+ `"${field}" bindings should, optionally, have a []string "allowed_destination_addresses" field but got ${JSON.stringify(
1839
+ value
1840
+ )}.`
1841
+ );
1842
+ isValid = false;
1843
+ }
1844
+ if (
1845
+ "destination_address" in value &&
1846
+ "allowed_destination_addresses" in value
1847
+ ) {
1848
+ diagnostics.errors.push(
1849
+ `"${field}" bindings should have either a "destination_address" or "allowed_destination_addresses" field, but not both.`
1850
+ );
1851
+ isValid = false;
1852
+ }
1853
+ return isValid;
1854
+ };
1855
+
1704
1856
  const validateQueueBinding: ValidatorFn = (diagnostics, field, value) => {
1705
1857
  if (typeof value !== "object" || value === null) {
1706
1858
  diagnostics.errors.push(
@@ -1824,7 +1976,7 @@ const validateD1Binding: ValidatorFn = (diagnostics, field, value) => {
1824
1976
  }
1825
1977
  if (isValid && !process.env.NO_D1_WARNING) {
1826
1978
  diagnostics.warnings.push(
1827
- `D1 Bindings are currently in beta to allow the API to evolve before general availability.\nPlease report any issues to https://github.com/cloudflare/wrangler2/issues/new/choose\nNote: set NO_D1_WARNING=true to hide this message`
1979
+ "D1 Bindings are currently in alpha to allow the API to evolve before general availability.\nPlease report any issues to https://github.com/cloudflare/workers-sdk/issues/new/choose\nNote: Run this command with the environment variable NO_D1_WARNING=true to hide this message\n\nFor example: `export NO_D1_WARNING=true && wrangler <YOUR COMMAND HERE>`"
1828
1980
  );
1829
1981
  }
1830
1982
  return isValid;
@@ -1844,6 +1996,7 @@ const validateBindingsHaveUniqueNames = (
1844
1996
  durable_objects,
1845
1997
  kv_namespaces,
1846
1998
  r2_buckets,
1999
+ analytics_engine_datasets,
1847
2000
  text_blobs,
1848
2001
  unsafe,
1849
2002
  vars,
@@ -1858,6 +2011,7 @@ const validateBindingsHaveUniqueNames = (
1858
2011
  "Durable Object": getBindingNames(durable_objects),
1859
2012
  "KV Namespace": getBindingNames(kv_namespaces),
1860
2013
  "R2 Bucket": getBindingNames(r2_buckets),
2014
+ "Analytics Engine Dataset": getBindingNames(analytics_engine_datasets),
1861
2015
  "Text Blob": getBindingNames(text_blobs),
1862
2016
  Unsafe: getBindingNames(unsafe),
1863
2017
  "Environment Variable": getBindingNames(vars),
@@ -1966,6 +2120,43 @@ const validateServiceBinding: ValidatorFn = (diagnostics, field, value) => {
1966
2120
  return isValid;
1967
2121
  };
1968
2122
 
2123
+ const validateAnalyticsEngineBinding: ValidatorFn = (
2124
+ diagnostics,
2125
+ field,
2126
+ value
2127
+ ) => {
2128
+ if (typeof value !== "object" || value === null) {
2129
+ diagnostics.errors.push(
2130
+ `"analytics_engine" bindings should be objects, but got ${JSON.stringify(
2131
+ value
2132
+ )}`
2133
+ );
2134
+ return false;
2135
+ }
2136
+ let isValid = true;
2137
+ // Service bindings must have a binding and optional dataset.
2138
+ if (!isRequiredProperty(value, "binding", "string")) {
2139
+ diagnostics.errors.push(
2140
+ `"${field}" bindings should have a string "binding" field but got ${JSON.stringify(
2141
+ value
2142
+ )}.`
2143
+ );
2144
+ isValid = false;
2145
+ }
2146
+ if (
2147
+ !isOptionalProperty(value, "dataset", "string") ||
2148
+ (value as { dataset: string }).dataset?.length === 0
2149
+ ) {
2150
+ diagnostics.errors.push(
2151
+ `"${field}" bindings should, optionally, have a string "dataset" field but got ${JSON.stringify(
2152
+ value
2153
+ )}.`
2154
+ );
2155
+ isValid = false;
2156
+ }
2157
+ return isValid;
2158
+ };
2159
+
1969
2160
  const validateWorkerNamespaceBinding: ValidatorFn = (
1970
2161
  diagnostics,
1971
2162
  field,
@@ -1998,6 +2189,42 @@ const validateWorkerNamespaceBinding: ValidatorFn = (
1998
2189
  return isValid;
1999
2190
  };
2000
2191
 
2192
+ const validateMTlsCertificateBinding: ValidatorFn = (
2193
+ diagnostics,
2194
+ field,
2195
+ value
2196
+ ) => {
2197
+ if (typeof value !== "object" || value === null) {
2198
+ diagnostics.errors.push(
2199
+ `"mtls_certificates" bindings should be objects, but got ${JSON.stringify(
2200
+ value
2201
+ )}`
2202
+ );
2203
+ return false;
2204
+ }
2205
+ let isValid = true;
2206
+ if (!isRequiredProperty(value, "binding", "string")) {
2207
+ diagnostics.errors.push(
2208
+ `"${field}" bindings should have a string "binding" field but got ${JSON.stringify(
2209
+ value
2210
+ )}.`
2211
+ );
2212
+ isValid = false;
2213
+ }
2214
+ if (
2215
+ !isRequiredProperty(value, "certificate_id", "string") ||
2216
+ (value as { certificate_id: string }).certificate_id.length === 0
2217
+ ) {
2218
+ diagnostics.errors.push(
2219
+ `"${field}" bindings should have a string "certificate_id" field but got ${JSON.stringify(
2220
+ value
2221
+ )}.`
2222
+ );
2223
+ isValid = false;
2224
+ }
2225
+ return isValid;
2226
+ };
2227
+
2001
2228
  function validateQueues(envName: string): ValidatorFn {
2002
2229
  return (diagnostics, field, value, config) => {
2003
2230
  const fieldPath =
@@ -2076,6 +2303,7 @@ const validateConsumer: ValidatorFn = (diagnostics, field, value, _config) => {
2076
2303
  "max_batch_timeout",
2077
2304
  "max_retries",
2078
2305
  "dead_letter_queue",
2306
+ "max_concurrency",
2079
2307
  ])
2080
2308
  ) {
2081
2309
  isValid = false;
@@ -2091,12 +2319,13 @@ const validateConsumer: ValidatorFn = (diagnostics, field, value, _config) => {
2091
2319
 
2092
2320
  const options: {
2093
2321
  key: string;
2094
- type: "number" | "string";
2322
+ type: "number" | "string" | "boolean";
2095
2323
  }[] = [
2096
2324
  { key: "max_batch_size", type: "number" },
2097
2325
  { key: "max_batch_timeout", type: "number" },
2098
2326
  { key: "max_retries", type: "number" },
2099
2327
  { key: "dead_letter_queue", type: "string" },
2328
+ { key: "max_concurrency", type: "number" },
2100
2329
  ];
2101
2330
  for (const optionalOpt of options) {
2102
2331
  if (!isOptionalProperty(value, optionalOpt.key, optionalOpt.type)) {
@@ -109,6 +109,14 @@ function randomId(): string {
109
109
  });
110
110
  }
111
111
 
112
+ // URLs are often relative to the zone. Sometimes the base zone
113
+ // will be grey-clouded, and so the host must be swapped out for
114
+ // the worker route host, which is more likely to be orange-clouded
115
+ function switchHost(originalUrl: string, host?: string): URL {
116
+ const url = new URL(originalUrl);
117
+ url.hostname = host ?? url.hostname;
118
+ return url;
119
+ }
112
120
  /**
113
121
  * Generates a preview session token.
114
122
  */
@@ -129,9 +137,13 @@ export async function createPreviewSession(
129
137
  abortSignal
130
138
  );
131
139
 
132
- logger.debug(`-- START EXCHANGE API REQUEST: GET ${exchange_url}`);
140
+ const switchedExchangeUrl = switchHost(exchange_url, ctx.host).toString();
141
+
142
+ logger.debug(`-- START EXCHANGE API REQUEST: GET ${switchedExchangeUrl}`);
133
143
  logger.debug("-- END EXCHANGE API REQUEST");
134
- const exchangeResponse = await fetch(exchange_url, { signal: abortSignal });
144
+ const exchangeResponse = await fetch(switchedExchangeUrl, {
145
+ signal: abortSignal,
146
+ });
135
147
  const bodyText = await exchangeResponse.text();
136
148
  logger.debug(
137
149
  "-- START EXCHANGE API RESPONSE:",
@@ -147,16 +159,15 @@ export async function createPreviewSession(
147
159
  token: string;
148
160
  prewarm: string;
149
161
  }>(bodyText);
150
-
151
- const { host } = new URL(inspector_websocket);
152
- const query = `cf_workers_preview_token=${token}`;
162
+ const inspector = new URL(inspector_websocket);
163
+ inspector.searchParams.append("cf_workers_preview_token", token);
153
164
 
154
165
  return {
155
166
  id: randomId(),
156
167
  value: token,
157
- host,
158
- inspectorUrl: new URL(`${inspector_websocket}?${query}`),
159
- prewarmUrl: new URL(prewarm),
168
+ host: ctx.host ?? inspector.host,
169
+ inspectorUrl: switchHost(inspector.href, ctx.host),
170
+ prewarmUrl: switchHost(prewarm, ctx.host),
160
171
  };
161
172
  }
162
173
 
@@ -23,7 +23,7 @@ export function toMimeType(type: CfModuleType): string {
23
23
  }
24
24
  }
25
25
 
26
- type WorkerMetadataBinding =
26
+ export type WorkerMetadataBinding =
27
27
  // If you add any new binding types here, also add it to safeBindings
28
28
  // under validateUnsafeBinding in config/validation.ts
29
29
  | { type: "plain_text"; name: string; text: string }
@@ -32,6 +32,12 @@ type WorkerMetadataBinding =
32
32
  | { type: "text_blob"; name: string; part: string }
33
33
  | { type: "data_blob"; name: string; part: string }
34
34
  | { type: "kv_namespace"; name: string; namespace_id: string }
35
+ | {
36
+ type: "send_email";
37
+ name: string;
38
+ destination_address?: string;
39
+ allowed_destination_addresses?: string[];
40
+ }
35
41
  | {
36
42
  type: "durable_object_namespace";
37
43
  name: string;
@@ -41,15 +47,16 @@ type WorkerMetadataBinding =
41
47
  }
42
48
  | { type: "queue"; name: string; queue_name: string }
43
49
  | { type: "r2_bucket"; name: string; bucket_name: string }
44
- | { type: "d1"; name: string; id: string }
50
+ | { type: "d1"; name: string; id: string; internalEnv?: string }
45
51
  | { type: "service"; name: string; service: string; environment?: string }
46
- | { type: "namespace"; name: string; namespace: string }
52
+ | { type: "analytics_engine"; name: string; dataset?: string }
53
+ | { type: "dispatch_namespace"; name: string; namespace: string }
54
+ | { type: "mtls_certificate"; name: string; certificate_id: string }
47
55
  | {
48
56
  type: "logfwdr";
49
57
  name: string;
50
58
  destination: string;
51
- }
52
- | { type: "metadata"; name: string };
59
+ };
53
60
 
54
61
  export interface WorkerMetadata {
55
62
  /** The name of the entry point module. Only exists when the worker is in the ES module format */
@@ -64,6 +71,8 @@ export interface WorkerMetadata {
64
71
  bindings: WorkerMetadataBinding[];
65
72
  keep_bindings?: WorkerMetadataBinding["type"][];
66
73
  logpush?: boolean;
74
+ // Allow unsafe.metadata to add arbitary properties at runtime
75
+ [key: string]: unknown;
67
76
  }
68
77
 
69
78
  /**
@@ -86,13 +95,6 @@ export function createWorkerUploadForm(worker: CfWorkerInit): FormData {
86
95
 
87
96
  const metadataBindings: WorkerMetadata["bindings"] = [];
88
97
 
89
- if (bindings.metadata_binding) {
90
- metadataBindings.push({
91
- name: bindings.metadata_binding,
92
- type: "metadata",
93
- });
94
- }
95
-
96
98
  Object.entries(bindings.vars || {})?.forEach(([key, value]) => {
97
99
  if (typeof value === "string") {
98
100
  metadataBindings.push({ name: key, type: "plain_text", text: value });
@@ -109,6 +111,17 @@ export function createWorkerUploadForm(worker: CfWorkerInit): FormData {
109
111
  });
110
112
  });
111
113
 
114
+ bindings.send_email?.forEach(
115
+ ({ name, destination_address, allowed_destination_addresses }) => {
116
+ metadataBindings.push({
117
+ name: name,
118
+ type: "send_email",
119
+ destination_address,
120
+ allowed_destination_addresses,
121
+ });
122
+ }
123
+ );
124
+
112
125
  bindings.durable_objects?.bindings.forEach(
113
126
  ({ name, class_name, script_name, environment }) => {
114
127
  metadataBindings.push({
@@ -137,13 +150,16 @@ export function createWorkerUploadForm(worker: CfWorkerInit): FormData {
137
150
  });
138
151
  });
139
152
 
140
- bindings.d1_databases?.forEach(({ binding, database_id }) => {
141
- metadataBindings.push({
142
- name: binding,
143
- type: "d1",
144
- id: database_id,
145
- });
146
- });
153
+ bindings.d1_databases?.forEach(
154
+ ({ binding, database_id, database_internal_env }) => {
155
+ metadataBindings.push({
156
+ name: binding,
157
+ type: "d1",
158
+ id: database_id,
159
+ internalEnv: database_internal_env,
160
+ });
161
+ }
162
+ );
147
163
 
148
164
  bindings.services?.forEach(({ binding, service, environment }) => {
149
165
  metadataBindings.push({
@@ -154,14 +170,30 @@ export function createWorkerUploadForm(worker: CfWorkerInit): FormData {
154
170
  });
155
171
  });
156
172
 
173
+ bindings.analytics_engine_datasets?.forEach(({ binding, dataset }) => {
174
+ metadataBindings.push({
175
+ name: binding,
176
+ type: "analytics_engine",
177
+ dataset,
178
+ });
179
+ });
180
+
157
181
  bindings.dispatch_namespaces?.forEach(({ binding, namespace }) => {
158
182
  metadataBindings.push({
159
183
  name: binding,
160
- type: "namespace",
184
+ type: "dispatch_namespace",
161
185
  namespace,
162
186
  });
163
187
  });
164
188
 
189
+ bindings.mtls_certificates?.forEach(({ binding, certificate_id }) => {
190
+ metadataBindings.push({
191
+ name: binding,
192
+ type: "mtls_certificate",
193
+ certificate_id,
194
+ });
195
+ });
196
+
165
197
  bindings.logfwdr?.bindings.forEach(({ name, destination }) => {
166
198
  metadataBindings.push({
167
199
  name: name,
@@ -271,9 +303,9 @@ export function createWorkerUploadForm(worker: CfWorkerInit): FormData {
271
303
  }
272
304
  }
273
305
 
274
- if (bindings.unsafe) {
306
+ if (bindings.unsafe?.bindings) {
275
307
  // @ts-expect-error unsafe bindings don't need to match a specific type here
276
- metadataBindings.push(...bindings.unsafe);
308
+ metadataBindings.push(...bindings.unsafe.bindings);
277
309
  }
278
310
 
279
311
  const metadata: WorkerMetadata = {
@@ -290,6 +322,12 @@ export function createWorkerUploadForm(worker: CfWorkerInit): FormData {
290
322
  ...(logpush !== undefined && { logpush }),
291
323
  };
292
324
 
325
+ if (bindings.unsafe?.metadata !== undefined) {
326
+ for (const key of Object.keys(bindings.unsafe.metadata)) {
327
+ metadata[key] = bindings.unsafe.metadata[key];
328
+ }
329
+ }
330
+
293
331
  formData.set("metadata", JSON.stringify(metadata));
294
332
 
295
333
  if (main.type === "commonjs" && modules && modules.length > 0) {