wrangler 0.0.0-e7a0cd5b → 0.0.0-e87ad068

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 (255) hide show
  1. package/README.md +3 -3
  2. package/bin/wrangler.js +30 -10
  3. package/miniflare-dist/index.mjs +254 -128
  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 +797 -98
  9. package/src/__tests__/constellation.test.ts +371 -0
  10. package/src/__tests__/d1/d1.test.ts +82 -0
  11. package/src/__tests__/d1/execute.test.ts +66 -0
  12. package/src/__tests__/d1/migrate.test.ts +257 -0
  13. package/src/__tests__/d1/splitter.test.ts +255 -0
  14. package/src/__tests__/delete.test.ts +91 -49
  15. package/src/__tests__/deployments.test.ts +330 -56
  16. package/src/__tests__/dev.test.tsx +198 -90
  17. package/src/__tests__/generate.test.ts +12 -10
  18. package/src/__tests__/guess-worker-format.test.ts +35 -0
  19. package/src/__tests__/helpers/end-event-loop.ts +6 -0
  20. package/src/__tests__/helpers/mock-auth-domain.ts +20 -0
  21. package/src/__tests__/helpers/mock-console.ts +6 -0
  22. package/src/__tests__/helpers/mock-dialogs.ts +71 -85
  23. package/src/__tests__/helpers/mock-get-pages-upload-token.ts +25 -0
  24. package/src/__tests__/helpers/mock-get-zone-from-host.ts +8 -5
  25. package/src/__tests__/helpers/mock-known-routes.ts +7 -2
  26. package/src/__tests__/helpers/mock-kv.ts +29 -16
  27. package/src/__tests__/helpers/mock-oauth-flow.ts +103 -92
  28. package/src/__tests__/helpers/mock-process.ts +8 -13
  29. package/src/__tests__/helpers/mock-set-timeout.ts +16 -0
  30. package/src/__tests__/helpers/msw/blob-worker.cjs +19 -0
  31. package/src/__tests__/helpers/msw/handlers/deployments.ts +128 -27
  32. package/src/__tests__/helpers/msw/handlers/namespaces.ts +18 -41
  33. package/src/__tests__/helpers/msw/handlers/oauth.ts +13 -18
  34. package/src/__tests__/helpers/msw/handlers/r2.ts +14 -34
  35. package/src/__tests__/helpers/msw/handlers/script.ts +9 -28
  36. package/src/__tests__/helpers/msw/handlers/user.ts +13 -24
  37. package/src/__tests__/helpers/msw/handlers/zones.ts +6 -8
  38. package/src/__tests__/helpers/msw/index.ts +32 -1
  39. package/src/__tests__/helpers/msw/read-file-sync.js +61 -0
  40. package/src/__tests__/helpers/string-dynamic-values-matcher.ts +28 -0
  41. package/src/__tests__/helpers/worker-scripts/parent-worker.js +4 -1
  42. package/src/__tests__/index.test.ts +92 -72
  43. package/src/__tests__/init.test.ts +1033 -631
  44. package/src/__tests__/jest.setup.ts +19 -42
  45. package/src/__tests__/kv.test.ts +355 -231
  46. package/src/__tests__/logger.test.ts +68 -2
  47. package/src/__tests__/logout.test.ts +47 -0
  48. package/src/__tests__/metrics.test.ts +94 -51
  49. package/src/__tests__/middleware.scheduled.test.ts +42 -32
  50. package/src/__tests__/middleware.test.ts +212 -122
  51. package/src/__tests__/mtls-certificates.test.ts +589 -0
  52. package/src/__tests__/pages/deployment-list.test.ts +80 -0
  53. package/src/__tests__/pages/functions-build.test.ts +529 -0
  54. package/src/__tests__/pages/pages.test.ts +81 -0
  55. package/src/__tests__/pages/project-create.test.ts +63 -0
  56. package/src/__tests__/pages/project-list.test.ts +110 -0
  57. package/src/__tests__/pages/project-upload.test.ts +500 -0
  58. package/src/__tests__/pages/publish.test.ts +2864 -0
  59. package/src/__tests__/pages-deployment-tail.test.ts +957 -0
  60. package/src/__tests__/parse.test.ts +106 -0
  61. package/src/__tests__/publish.test.ts +2227 -1005
  62. package/src/__tests__/pubsub.test.ts +226 -100
  63. package/src/__tests__/queues.test.ts +238 -77
  64. package/src/__tests__/r2.test.ts +55 -57
  65. package/src/__tests__/secret.test.ts +179 -130
  66. package/src/__tests__/tail.test.ts +313 -113
  67. package/src/__tests__/test-old-node-version.js +3 -3
  68. package/src/__tests__/traverse-module-graph.test.ts +220 -0
  69. package/src/__tests__/tsconfig-sanity.ts +12 -0
  70. package/src/__tests__/tsconfig.json +8 -0
  71. package/src/__tests__/tsconfig.tsbuildinfo +1 -0
  72. package/src/__tests__/type-generation.test.ts +43 -26
  73. package/src/__tests__/unstableDev.test.ts +61 -0
  74. package/src/__tests__/user.test.ts +35 -72
  75. package/src/__tests__/whoami.test.tsx +8 -114
  76. package/src/__tests__/worker-namespace.test.ts +83 -69
  77. package/src/api/dev.ts +180 -60
  78. package/src/api/index.ts +10 -1
  79. package/src/api/mtls-certificate.ts +148 -0
  80. package/src/api/pages/create-worker-bundle-contents.ts +80 -0
  81. package/src/api/pages/index.ts +5 -0
  82. package/src/api/pages/publish.tsx +371 -0
  83. package/src/bundle.ts +315 -148
  84. package/src/cfetch/index.ts +0 -2
  85. package/src/cfetch/internal.ts +33 -33
  86. package/src/cli.ts +4 -4
  87. package/src/config/config.ts +14 -7
  88. package/src/config/environment.ts +120 -24
  89. package/src/config/index.ts +117 -35
  90. package/src/config/validation-helpers.ts +1 -1
  91. package/src/config/validation.ts +430 -19
  92. package/src/constellation/createProject.tsx +51 -0
  93. package/src/constellation/deleteProject.ts +51 -0
  94. package/src/constellation/deleteProjectModel.ts +76 -0
  95. package/src/constellation/index.ts +75 -0
  96. package/src/constellation/listCatalog.tsx +35 -0
  97. package/src/constellation/listModel.tsx +49 -0
  98. package/src/constellation/listProject.tsx +28 -0
  99. package/src/constellation/listRuntime.tsx +28 -0
  100. package/src/constellation/options.ts +17 -0
  101. package/src/constellation/types.ts +17 -0
  102. package/src/constellation/uploadModel.tsx +84 -0
  103. package/src/constellation/utils.ts +90 -0
  104. package/src/create-worker-preview.ts +19 -8
  105. package/src/create-worker-upload-form.ts +81 -18
  106. package/src/d1/backups.tsx +47 -46
  107. package/src/d1/constants.ts +5 -0
  108. package/src/d1/create.tsx +85 -37
  109. package/src/d1/{delete.tsx → delete.ts} +12 -15
  110. package/src/d1/execute.tsx +228 -156
  111. package/src/d1/index.ts +31 -7
  112. package/src/d1/list.tsx +27 -13
  113. package/src/d1/migrations/apply.tsx +235 -0
  114. package/src/d1/migrations/create.tsx +79 -0
  115. package/src/d1/migrations/helpers.ts +171 -0
  116. package/src/d1/migrations/index.ts +3 -0
  117. package/src/d1/migrations/list.tsx +95 -0
  118. package/src/d1/migrations/options.ts +23 -0
  119. package/src/d1/options.ts +12 -2
  120. package/src/d1/splitter.ts +161 -0
  121. package/src/d1/types.ts +32 -0
  122. package/src/d1/utils.ts +12 -2
  123. package/src/delete.ts +8 -16
  124. package/src/deployments.ts +340 -46
  125. package/src/deprecated/index.ts +8 -302
  126. package/src/dev/dev.tsx +66 -46
  127. package/src/dev/local.tsx +339 -104
  128. package/src/dev/remote.tsx +36 -3
  129. package/src/dev/start-server.ts +146 -101
  130. package/src/dev/use-esbuild.ts +82 -56
  131. package/src/dev/validate-dev-props.ts +9 -0
  132. package/src/{dev-registry.tsx → dev-registry.ts} +13 -1
  133. package/src/dev.tsx +202 -125
  134. package/src/dialogs.ts +136 -0
  135. package/src/dispatch-namespace.ts +21 -17
  136. package/src/docs/helpers.ts +50 -0
  137. package/src/docs/index.ts +54 -0
  138. package/src/entry.ts +26 -11
  139. package/src/environment-variables/factory.ts +89 -0
  140. package/src/environment-variables/misc-variables.ts +30 -0
  141. package/src/generate/index.ts +303 -0
  142. package/src/git-client.ts +15 -4
  143. package/src/{index.tsx → index.ts} +148 -63
  144. package/src/init.ts +301 -197
  145. package/src/inspect.ts +122 -6
  146. package/src/jest.d.ts +4 -0
  147. package/src/kv/helpers.ts +7 -4
  148. package/src/kv/index.ts +15 -17
  149. package/src/logger.ts +36 -5
  150. package/src/metrics/metrics-config.ts +3 -3
  151. package/src/metrics/send-event.ts +6 -1
  152. package/src/miniflare-cli/assets.ts +64 -28
  153. package/src/miniflare-cli/index.ts +6 -9
  154. package/src/miniflare-cli/tsconfig.json +9 -0
  155. package/src/miniflare-cli/tsconfig.tsbuildinfo +1 -0
  156. package/src/miniflare-cli/types.ts +11 -0
  157. package/src/module-collection.ts +92 -26
  158. package/src/mtls-certificate/cli.ts +155 -0
  159. package/src/pages/build.ts +423 -0
  160. package/src/pages/buildFunctions.ts +140 -0
  161. package/src/pages/deployment-tails.ts +281 -0
  162. package/src/pages/deployments.tsx +11 -33
  163. package/src/pages/{dev.tsx → dev.ts} +192 -126
  164. package/src/pages/errors.ts +1 -0
  165. package/src/pages/functions/buildPlugin.ts +73 -69
  166. package/src/pages/functions/buildWorker.ts +342 -117
  167. package/src/pages/functions/tsconfig.json +8 -0
  168. package/src/pages/functions/tsconfig.tsbuildinfo +1 -0
  169. package/src/pages/{functions.tsx → functions.ts} +8 -4
  170. package/src/pages/{index.tsx → index.ts} +11 -3
  171. package/src/pages/projects.tsx +12 -22
  172. package/src/pages/prompt-select-project.tsx +31 -0
  173. package/src/pages/publish.tsx +45 -214
  174. package/src/pages/types.ts +6 -9
  175. package/src/pages/upload.tsx +58 -14
  176. package/src/pages/utils.ts +14 -3
  177. package/src/parse.ts +23 -1
  178. package/src/paths.ts +1 -1
  179. package/src/proxy.ts +5 -0
  180. package/src/publish/index.ts +20 -16
  181. package/src/publish/publish.ts +81 -48
  182. package/src/pubsub/{pubsub-commands.tsx → pubsub-commands.ts} +19 -20
  183. package/src/queues/cli/commands/consumer/add.ts +24 -24
  184. package/src/queues/cli/commands/consumer/index.ts +3 -6
  185. package/src/queues/cli/commands/consumer/remove.ts +11 -18
  186. package/src/queues/cli/commands/create.ts +8 -8
  187. package/src/queues/cli/commands/delete.ts +8 -8
  188. package/src/queues/cli/commands/index.ts +6 -4
  189. package/src/queues/cli/commands/list.ts +8 -8
  190. package/src/queues/client.ts +1 -0
  191. package/src/queues/utils.ts +18 -0
  192. package/src/r2/constants.ts +4 -0
  193. package/src/r2/helpers.ts +1 -0
  194. package/src/r2/index.ts +40 -28
  195. package/src/secret/index.ts +18 -17
  196. package/src/{sites.tsx → sites.ts} +165 -53
  197. package/src/tail/createTail.ts +103 -3
  198. package/src/tail/filters.ts +1 -1
  199. package/src/tail/index.ts +8 -11
  200. package/src/tail/printing.ts +27 -0
  201. package/src/traverse-module-graph.ts +54 -0
  202. package/src/tsconfig-sanity.ts +16 -0
  203. package/src/type-generation.ts +85 -57
  204. package/src/user/access.ts +0 -1
  205. package/src/user/auth-variables.ts +113 -0
  206. package/src/user/choose-account.tsx +1 -31
  207. package/src/user/index.ts +0 -1
  208. package/src/user/{user.tsx → user.ts} +124 -82
  209. package/src/utils/render.ts +93 -0
  210. package/src/{whoami.tsx → whoami.ts} +37 -71
  211. package/src/worker.ts +61 -3
  212. package/src/yargs-types.ts +22 -5
  213. package/templates/__tests__/tsconfig-sanity.ts +12 -0
  214. package/templates/__tests__/tsconfig.json +8 -0
  215. package/templates/__tests__/tsconfig.tsbuildinfo +1 -0
  216. package/templates/checked-fetch.js +9 -3
  217. package/templates/d1-beta-facade.js +95 -25
  218. package/templates/facade.d.ts +14 -0
  219. package/templates/first-party-worker-module-facade.ts +4 -3
  220. package/templates/format-dev-errors.ts +8 -6
  221. package/templates/gitignore +1 -0
  222. package/templates/init-tests/test-jest-new-worker.js +3 -5
  223. package/templates/init-tests/test-vitest-new-worker.js +3 -5
  224. package/templates/init-tests/test-vitest-new-worker.ts +25 -0
  225. package/templates/middleware/loader-modules.ts +2 -2
  226. package/templates/middleware/loader-sw.ts +51 -31
  227. package/templates/middleware/middleware-miniflare3-json-error.ts +32 -0
  228. package/templates/new-worker.ts +3 -0
  229. package/templates/pages-dev-pipeline.ts +4 -1
  230. package/templates/pages-dev-util.ts +4 -1
  231. package/templates/pages-shim.ts +4 -1
  232. package/templates/pages-template-plugin.ts +19 -10
  233. package/templates/serve-static-assets.ts +17 -14
  234. package/templates/service-bindings-module-facade.js +1 -0
  235. package/templates/tsconfig-sanity.ts +11 -0
  236. package/templates/tsconfig.init.json +105 -0
  237. package/templates/tsconfig.json +5 -103
  238. package/templates/tsconfig.tsbuildinfo +1 -0
  239. package/wrangler-dist/cli.d.ts +902 -77
  240. package/wrangler-dist/cli.js +131685 -140615
  241. package/wrangler-dist/wasm-sync.wasm +0 -0
  242. package/src/__tests__/api-devregistry.test.js +0 -57
  243. package/src/__tests__/d1.test.ts +0 -72
  244. package/src/__tests__/dialogs.test.tsx +0 -40
  245. package/src/__tests__/helpers/mock-cfetch.ts +0 -333
  246. package/src/__tests__/pages.test.ts +0 -2223
  247. package/src/d1/types.tsx +0 -14
  248. package/src/dialogs.tsx +0 -163
  249. package/src/environment-variables.ts +0 -50
  250. package/src/pages/build.tsx +0 -238
  251. package/src/user/env-vars.ts +0 -46
  252. package/templates/experimental-local-cache-stubs.js +0 -27
  253. /package/src/{bundle-reporter.tsx → bundle-reporter.ts} +0 -0
  254. /package/src/dev/{get-local-persistence-path.tsx → get-local-persistence-path.ts} +0 -0
  255. /package/src/pages/{hash.tsx → hash.ts} +0 -0
@@ -1,5 +1,6 @@
1
1
  import path from "node:path";
2
2
  import TOML from "@iarna/toml";
3
+ import { getConstellationWarningFromEnv } from "../constellation/utils";
3
4
  import { Diagnostics } from "./diagnostics";
4
5
  import {
5
6
  deprecated,
@@ -32,6 +33,7 @@ import type {
32
33
  DeprecatedUpload,
33
34
  Environment,
34
35
  Rule,
36
+ TailConsumer,
35
37
  } from "./environment";
36
38
  import type { ValidatorFn } from "./validation-helpers";
37
39
 
@@ -358,6 +360,26 @@ function normalizeAndValidateMainField(
358
360
  }
359
361
  }
360
362
 
363
+ /**
364
+ * Validate the `base_dir` field and return the normalized values.
365
+ */
366
+ function normalizeAndValidateBaseDirField(
367
+ configPath: string | undefined,
368
+ rawDir: string | undefined
369
+ ): string | undefined {
370
+ const configDir = path.dirname(configPath ?? "wrangler.toml");
371
+ if (rawDir !== undefined) {
372
+ if (typeof rawDir === "string") {
373
+ const directory = path.resolve(configDir);
374
+ return path.resolve(directory, rawDir);
375
+ } else {
376
+ return rawDir;
377
+ }
378
+ } else {
379
+ return;
380
+ }
381
+ }
382
+
361
383
  /**
362
384
  * Validate the `dev` configuration and return the normalized values.
363
385
  */
@@ -741,7 +763,7 @@ function isValidRouteValue(item: unknown): boolean {
741
763
 
742
764
  /**
743
765
  * 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 = '',
766
+ * This is to workaround older Wrangler v1-era templates that have account_id = '',
745
767
  * which isn't a valid value anyway
746
768
  */
747
769
  function mutateEmptyStringAccountIDValue(
@@ -760,7 +782,7 @@ function mutateEmptyStringAccountIDValue(
760
782
 
761
783
  /**
762
784
  * Normalize empty string to `undefined` by mutating rawEnv.route value.
763
- * As part of backward compatibility with Wrangler1 converting empty string to `undefined`
785
+ * As part of backward compatibility with Wrangler v1 converting empty string to `undefined`
764
786
  */
765
787
  function mutateEmptyStringRouteValue(
766
788
  diagnostics: Diagnostics,
@@ -853,6 +875,88 @@ function validateRoutes(
853
875
  );
854
876
  }
855
877
 
878
+ function normalizeAndValidatePlacement(
879
+ diagnostics: Diagnostics,
880
+ topLevelEnv: Environment | undefined,
881
+ rawEnv: RawEnvironment
882
+ ): Config["placement"] {
883
+ if (rawEnv.placement) {
884
+ validateRequiredProperty(
885
+ diagnostics,
886
+ "placement",
887
+ "mode",
888
+ rawEnv.placement.mode,
889
+ "string",
890
+ ["off", "smart"]
891
+ );
892
+ }
893
+
894
+ return inheritable(
895
+ diagnostics,
896
+ topLevelEnv,
897
+ rawEnv,
898
+ "placement",
899
+ () => true,
900
+ undefined
901
+ );
902
+ }
903
+
904
+ function validateTailConsumer(
905
+ diagnostics: Diagnostics,
906
+ field: string,
907
+ value: TailConsumer
908
+ ) {
909
+ if (typeof value !== "object" || value === null) {
910
+ diagnostics.errors.push(
911
+ `"${field}" should be an object but got ${JSON.stringify(value)}.`
912
+ );
913
+ return false;
914
+ }
915
+
916
+ let isValid = true;
917
+
918
+ isValid =
919
+ isValid &&
920
+ validateRequiredProperty(
921
+ diagnostics,
922
+ field,
923
+ "service",
924
+ value.service,
925
+ "string"
926
+ );
927
+ isValid =
928
+ isValid &&
929
+ validateOptionalProperty(
930
+ diagnostics,
931
+ field,
932
+ "environment",
933
+ value.environment,
934
+ "string"
935
+ );
936
+
937
+ return isValid;
938
+ }
939
+
940
+ const validateTailConsumers: ValidatorFn = (diagnostics, field, value) => {
941
+ if (!value) {
942
+ return true;
943
+ }
944
+ if (!Array.isArray(value)) {
945
+ diagnostics.errors.push(
946
+ `Expected "${field}" to be an array but got ${JSON.stringify(value)}.`
947
+ );
948
+ return false;
949
+ }
950
+
951
+ let isValid = true;
952
+ for (let i = 0; i < value.length; i++) {
953
+ isValid =
954
+ validateTailConsumer(diagnostics, `${field}[${i}]`, value[i]) && isValid;
955
+ }
956
+
957
+ return isValid;
958
+ };
959
+
856
960
  /**
857
961
  * Validate top-level environment configuration and return the normalized values.
858
962
  */
@@ -909,7 +1013,6 @@ function normalizeAndValidateEnvironment(
909
1013
 
910
1014
  experimental(diagnostics, rawEnv, "unsafe");
911
1015
  experimental(diagnostics, rawEnv, "services");
912
- experimental(diagnostics, rawEnv, "dispatch_namespaces");
913
1016
 
914
1017
  const route = normalizeAndValidateRoute(diagnostics, topLevelEnv, rawEnv);
915
1018
 
@@ -1012,6 +1115,17 @@ function normalizeAndValidateEnvironment(
1012
1115
  ),
1013
1116
  deprecatedUpload
1014
1117
  ),
1118
+ base_dir: normalizeAndValidateBaseDirField(
1119
+ configPath,
1120
+ inheritable(
1121
+ diagnostics,
1122
+ topLevelEnv,
1123
+ rawEnv,
1124
+ "base_dir",
1125
+ isString,
1126
+ undefined
1127
+ )
1128
+ ),
1015
1129
  route,
1016
1130
  routes,
1017
1131
  triggers: inheritable(
@@ -1030,6 +1144,7 @@ function normalizeAndValidateEnvironment(
1030
1144
  isOneOf("bundled", "unbound"),
1031
1145
  undefined
1032
1146
  ),
1147
+ placement: normalizeAndValidatePlacement(diagnostics, topLevelEnv, rawEnv),
1033
1148
  build,
1034
1149
  workers_dev,
1035
1150
  // Not inherited fields
@@ -1043,16 +1158,6 @@ function normalizeAndValidateEnvironment(
1043
1158
  validateVars(envName),
1044
1159
  {}
1045
1160
  ),
1046
- metadata_binding: notInheritable(
1047
- diagnostics,
1048
- topLevelEnv,
1049
- rawConfig,
1050
- rawEnv,
1051
- envName,
1052
- "metadata_binding",
1053
- isString,
1054
- undefined
1055
- ),
1056
1161
  define: notInheritable(
1057
1162
  diagnostics,
1058
1163
  topLevelEnv,
@@ -1085,6 +1190,16 @@ function normalizeAndValidateEnvironment(
1085
1190
  validateBindingArray(envName, validateKVBinding),
1086
1191
  []
1087
1192
  ),
1193
+ send_email: notInheritable(
1194
+ diagnostics,
1195
+ topLevelEnv,
1196
+ rawConfig,
1197
+ rawEnv,
1198
+ envName,
1199
+ "send_email",
1200
+ validateBindingArray(envName, validateSendEmailBinding),
1201
+ []
1202
+ ),
1088
1203
  queues: notInheritable(
1089
1204
  diagnostics,
1090
1205
  topLevelEnv,
@@ -1115,6 +1230,16 @@ function normalizeAndValidateEnvironment(
1115
1230
  validateBindingArray(envName, validateD1Binding),
1116
1231
  []
1117
1232
  ),
1233
+ constellation: notInheritable(
1234
+ diagnostics,
1235
+ topLevelEnv,
1236
+ rawConfig,
1237
+ rawEnv,
1238
+ envName,
1239
+ "constellation",
1240
+ validateBindingArray(envName, validateConstellationBinding),
1241
+ []
1242
+ ),
1118
1243
  services: notInheritable(
1119
1244
  diagnostics,
1120
1245
  topLevelEnv,
@@ -1125,6 +1250,16 @@ function normalizeAndValidateEnvironment(
1125
1250
  validateBindingArray(envName, validateServiceBinding),
1126
1251
  []
1127
1252
  ),
1253
+ analytics_engine_datasets: notInheritable(
1254
+ diagnostics,
1255
+ topLevelEnv,
1256
+ rawConfig,
1257
+ rawEnv,
1258
+ envName,
1259
+ "analytics_engine_datasets",
1260
+ validateBindingArray(envName, validateAnalyticsEngineBinding),
1261
+ []
1262
+ ),
1128
1263
  dispatch_namespaces: notInheritable(
1129
1264
  diagnostics,
1130
1265
  topLevelEnv,
@@ -1135,6 +1270,26 @@ function normalizeAndValidateEnvironment(
1135
1270
  validateBindingArray(envName, validateWorkerNamespaceBinding),
1136
1271
  []
1137
1272
  ),
1273
+ mtls_certificates: notInheritable(
1274
+ diagnostics,
1275
+ topLevelEnv,
1276
+ rawConfig,
1277
+ rawEnv,
1278
+ envName,
1279
+ "mtls_certificates",
1280
+ validateBindingArray(envName, validateMTlsCertificateBinding),
1281
+ []
1282
+ ),
1283
+ tail_consumers: notInheritable(
1284
+ diagnostics,
1285
+ topLevelEnv,
1286
+ rawConfig,
1287
+ rawEnv,
1288
+ envName,
1289
+ "tail_consumers",
1290
+ validateTailConsumers,
1291
+ undefined
1292
+ ),
1138
1293
  logfwdr: inheritable(
1139
1294
  diagnostics,
1140
1295
  topLevelEnv,
@@ -1153,10 +1308,18 @@ function normalizeAndValidateEnvironment(
1153
1308
  rawEnv,
1154
1309
  envName,
1155
1310
  "unsafe",
1156
- validateBindingsProperty(envName, validateUnsafeBinding),
1157
- {
1158
- bindings: [],
1159
- }
1311
+ validateUnsafeSettings(envName),
1312
+ {}
1313
+ ),
1314
+ browser: notInheritable(
1315
+ diagnostics,
1316
+ topLevelEnv,
1317
+ rawConfig,
1318
+ rawEnv,
1319
+ envName,
1320
+ "browser",
1321
+ validateBrowserBinding(envName),
1322
+ undefined
1160
1323
  ),
1161
1324
  zone_id: rawEnv.zone_id,
1162
1325
  no_bundle: inheritable(
@@ -1486,6 +1649,62 @@ const validateBindingsProperty =
1486
1649
  return isValid;
1487
1650
  };
1488
1651
 
1652
+ const validateUnsafeSettings =
1653
+ (envName: string): ValidatorFn =>
1654
+ (diagnostics, field, value, config) => {
1655
+ const fieldPath =
1656
+ config === undefined ? `${field}` : `env.${envName}.${field}`;
1657
+
1658
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
1659
+ diagnostics.errors.push(
1660
+ `The field "${fieldPath}" should be an object but got ${JSON.stringify(
1661
+ value
1662
+ )}.`
1663
+ );
1664
+ return false;
1665
+ }
1666
+
1667
+ // At least one of bindings and metadata must exist
1668
+ if (!hasProperty(value, "bindings") && !hasProperty(value, "metadata")) {
1669
+ diagnostics.errors.push(
1670
+ `The field "${fieldPath}" should contain at least one of "bindings" or "metadata" properties but got ${JSON.stringify(
1671
+ value
1672
+ )}.`
1673
+ );
1674
+ return false;
1675
+ }
1676
+
1677
+ // unsafe.bindings
1678
+ if (hasProperty(value, "bindings") && value.bindings !== undefined) {
1679
+ const validateBindingsFn = validateBindingsProperty(
1680
+ envName,
1681
+ validateUnsafeBinding
1682
+ );
1683
+ const valid = validateBindingsFn(diagnostics, field, value, config);
1684
+ if (!valid) {
1685
+ return false;
1686
+ }
1687
+ }
1688
+
1689
+ // unsafe.metadata
1690
+ if (
1691
+ hasProperty(value, "metadata") &&
1692
+ value.metadata !== undefined &&
1693
+ (typeof value.metadata !== "object" ||
1694
+ value.metadata === null ||
1695
+ Array.isArray(value.metadata))
1696
+ ) {
1697
+ diagnostics.errors.push(
1698
+ `The field "${fieldPath}.metadata" should be an object but got ${JSON.stringify(
1699
+ value.metadata
1700
+ )}.`
1701
+ );
1702
+ return false;
1703
+ }
1704
+
1705
+ return true;
1706
+ };
1707
+
1489
1708
  /**
1490
1709
  * Check that the given field is a valid "durable_object" binding object.
1491
1710
  */
@@ -1559,6 +1778,30 @@ const validateCflogfwdrBinding: ValidatorFn = (diagnostics, field, value) => {
1559
1778
  return isValid;
1560
1779
  };
1561
1780
 
1781
+ const validateBrowserBinding =
1782
+ (envName: string): ValidatorFn =>
1783
+ (diagnostics, field, value, config) => {
1784
+ const fieldPath =
1785
+ config === undefined ? `${field}` : `env.${envName}.${field}`;
1786
+
1787
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
1788
+ diagnostics.errors.push(
1789
+ `The field "${fieldPath}" should be an object but got ${JSON.stringify(
1790
+ value
1791
+ )}.`
1792
+ );
1793
+ return false;
1794
+ }
1795
+
1796
+ let isValid = true;
1797
+ if (!isRequiredProperty(value, "binding", "string")) {
1798
+ diagnostics.errors.push(`binding should have a string "binding" field.`);
1799
+ isValid = false;
1800
+ }
1801
+
1802
+ return isValid;
1803
+ };
1804
+
1562
1805
  /**
1563
1806
  * Check that the given field is a valid "unsafe" binding object.
1564
1807
  *
@@ -1585,12 +1828,15 @@ const validateUnsafeBinding: ValidatorFn = (diagnostics, field, value) => {
1585
1828
  "wasm_module",
1586
1829
  "data_blob",
1587
1830
  "text_blob",
1831
+ "browser",
1588
1832
  "kv_namespace",
1589
1833
  "durable_object_namespace",
1590
1834
  "d1_database",
1835
+ "constellation",
1591
1836
  "r2_bucket",
1592
1837
  "service",
1593
1838
  "logfwdr",
1839
+ "mtls_certificate",
1594
1840
  ];
1595
1841
 
1596
1842
  if (safeBindings.includes(value.type)) {
@@ -1701,6 +1947,53 @@ const validateKVBinding: ValidatorFn = (diagnostics, field, value) => {
1701
1947
  return isValid;
1702
1948
  };
1703
1949
 
1950
+ const validateSendEmailBinding: ValidatorFn = (diagnostics, field, value) => {
1951
+ if (typeof value !== "object" || value === null) {
1952
+ diagnostics.errors.push(
1953
+ `"send_email" bindings should be objects, but got ${JSON.stringify(
1954
+ value
1955
+ )}`
1956
+ );
1957
+ return false;
1958
+ }
1959
+ let isValid = true;
1960
+ // send email bindings must have a name.
1961
+ if (!isRequiredProperty(value, "name", "string")) {
1962
+ diagnostics.errors.push(
1963
+ `"${field}" bindings should have a string "name" field but got ${JSON.stringify(
1964
+ value
1965
+ )}.`
1966
+ );
1967
+ isValid = false;
1968
+ }
1969
+ if (!isOptionalProperty(value, "destination_address", "string")) {
1970
+ diagnostics.errors.push(
1971
+ `"${field}" bindings should, optionally, have a string "destination_address" field but got ${JSON.stringify(
1972
+ value
1973
+ )}.`
1974
+ );
1975
+ isValid = false;
1976
+ }
1977
+ if (!isOptionalProperty(value, "allowed_destination_addresses", "object")) {
1978
+ diagnostics.errors.push(
1979
+ `"${field}" bindings should, optionally, have a []string "allowed_destination_addresses" field but got ${JSON.stringify(
1980
+ value
1981
+ )}.`
1982
+ );
1983
+ isValid = false;
1984
+ }
1985
+ if (
1986
+ "destination_address" in value &&
1987
+ "allowed_destination_addresses" in value
1988
+ ) {
1989
+ diagnostics.errors.push(
1990
+ `"${field}" bindings should have either a "destination_address" or "allowed_destination_addresses" field, but not both.`
1991
+ );
1992
+ isValid = false;
1993
+ }
1994
+ return isValid;
1995
+ };
1996
+
1704
1997
  const validateQueueBinding: ValidatorFn = (diagnostics, field, value) => {
1705
1998
  if (typeof value !== "object" || value === null) {
1706
1999
  diagnostics.errors.push(
@@ -1824,7 +2117,46 @@ const validateD1Binding: ValidatorFn = (diagnostics, field, value) => {
1824
2117
  }
1825
2118
  if (isValid && !process.env.NO_D1_WARNING) {
1826
2119
  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`
2120
+ "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>`"
2121
+ );
2122
+ }
2123
+ return isValid;
2124
+ };
2125
+
2126
+ const validateConstellationBinding: ValidatorFn = (
2127
+ diagnostics,
2128
+ field,
2129
+ value
2130
+ ) => {
2131
+ if (typeof value !== "object" || value === null) {
2132
+ diagnostics.errors.push(
2133
+ `"constellation" bindings should be objects, but got ${JSON.stringify(
2134
+ value
2135
+ )}`
2136
+ );
2137
+ return false;
2138
+ }
2139
+ let isValid = true;
2140
+ // Constellation bindings must have a binding and a project.
2141
+ if (!isRequiredProperty(value, "binding", "string")) {
2142
+ diagnostics.errors.push(
2143
+ `"${field}" bindings should have a string "binding" field but got ${JSON.stringify(
2144
+ value
2145
+ )}.`
2146
+ );
2147
+ isValid = false;
2148
+ }
2149
+ if (!isRequiredProperty(value, "project_id", "string")) {
2150
+ diagnostics.errors.push(
2151
+ `"${field}" bindings must have a "project_id" field but got ${JSON.stringify(
2152
+ value
2153
+ )}.`
2154
+ );
2155
+ isValid = false;
2156
+ }
2157
+ if (isValid && getConstellationWarningFromEnv() === undefined) {
2158
+ diagnostics.warnings.push(
2159
+ "Constellation Bindings are currently in beta 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_CONSTELLATION_WARNING=true to hide this message\n\nFor example: `export NO_CONSTELLATION_WARNING=true && wrangler <YOUR COMMAND HERE>`"
1828
2160
  );
1829
2161
  }
1830
2162
  return isValid;
@@ -1844,7 +2176,9 @@ const validateBindingsHaveUniqueNames = (
1844
2176
  durable_objects,
1845
2177
  kv_namespaces,
1846
2178
  r2_buckets,
2179
+ analytics_engine_datasets,
1847
2180
  text_blobs,
2181
+ browser,
1848
2182
  unsafe,
1849
2183
  vars,
1850
2184
  define,
@@ -1858,7 +2192,9 @@ const validateBindingsHaveUniqueNames = (
1858
2192
  "Durable Object": getBindingNames(durable_objects),
1859
2193
  "KV Namespace": getBindingNames(kv_namespaces),
1860
2194
  "R2 Bucket": getBindingNames(r2_buckets),
2195
+ "Analytics Engine Dataset": getBindingNames(analytics_engine_datasets),
1861
2196
  "Text Blob": getBindingNames(text_blobs),
2197
+ Browser: getBindingNames(browser),
1862
2198
  Unsafe: getBindingNames(unsafe),
1863
2199
  "Environment Variable": getBindingNames(vars),
1864
2200
  Definition: getBindingNames(define),
@@ -1966,6 +2302,43 @@ const validateServiceBinding: ValidatorFn = (diagnostics, field, value) => {
1966
2302
  return isValid;
1967
2303
  };
1968
2304
 
2305
+ const validateAnalyticsEngineBinding: ValidatorFn = (
2306
+ diagnostics,
2307
+ field,
2308
+ value
2309
+ ) => {
2310
+ if (typeof value !== "object" || value === null) {
2311
+ diagnostics.errors.push(
2312
+ `"analytics_engine" bindings should be objects, but got ${JSON.stringify(
2313
+ value
2314
+ )}`
2315
+ );
2316
+ return false;
2317
+ }
2318
+ let isValid = true;
2319
+ // Service bindings must have a binding and optional dataset.
2320
+ if (!isRequiredProperty(value, "binding", "string")) {
2321
+ diagnostics.errors.push(
2322
+ `"${field}" bindings should have a string "binding" field but got ${JSON.stringify(
2323
+ value
2324
+ )}.`
2325
+ );
2326
+ isValid = false;
2327
+ }
2328
+ if (
2329
+ !isOptionalProperty(value, "dataset", "string") ||
2330
+ (value as { dataset: string }).dataset?.length === 0
2331
+ ) {
2332
+ diagnostics.errors.push(
2333
+ `"${field}" bindings should, optionally, have a string "dataset" field but got ${JSON.stringify(
2334
+ value
2335
+ )}.`
2336
+ );
2337
+ isValid = false;
2338
+ }
2339
+ return isValid;
2340
+ };
2341
+
1969
2342
  const validateWorkerNamespaceBinding: ValidatorFn = (
1970
2343
  diagnostics,
1971
2344
  field,
@@ -1998,6 +2371,42 @@ const validateWorkerNamespaceBinding: ValidatorFn = (
1998
2371
  return isValid;
1999
2372
  };
2000
2373
 
2374
+ const validateMTlsCertificateBinding: ValidatorFn = (
2375
+ diagnostics,
2376
+ field,
2377
+ value
2378
+ ) => {
2379
+ if (typeof value !== "object" || value === null) {
2380
+ diagnostics.errors.push(
2381
+ `"mtls_certificates" bindings should be objects, but got ${JSON.stringify(
2382
+ value
2383
+ )}`
2384
+ );
2385
+ return false;
2386
+ }
2387
+ let isValid = true;
2388
+ if (!isRequiredProperty(value, "binding", "string")) {
2389
+ diagnostics.errors.push(
2390
+ `"${field}" bindings should have a string "binding" field but got ${JSON.stringify(
2391
+ value
2392
+ )}.`
2393
+ );
2394
+ isValid = false;
2395
+ }
2396
+ if (
2397
+ !isRequiredProperty(value, "certificate_id", "string") ||
2398
+ (value as { certificate_id: string }).certificate_id.length === 0
2399
+ ) {
2400
+ diagnostics.errors.push(
2401
+ `"${field}" bindings should have a string "certificate_id" field but got ${JSON.stringify(
2402
+ value
2403
+ )}.`
2404
+ );
2405
+ isValid = false;
2406
+ }
2407
+ return isValid;
2408
+ };
2409
+
2001
2410
  function validateQueues(envName: string): ValidatorFn {
2002
2411
  return (diagnostics, field, value, config) => {
2003
2412
  const fieldPath =
@@ -2076,6 +2485,7 @@ const validateConsumer: ValidatorFn = (diagnostics, field, value, _config) => {
2076
2485
  "max_batch_timeout",
2077
2486
  "max_retries",
2078
2487
  "dead_letter_queue",
2488
+ "max_concurrency",
2079
2489
  ])
2080
2490
  ) {
2081
2491
  isValid = false;
@@ -2091,12 +2501,13 @@ const validateConsumer: ValidatorFn = (diagnostics, field, value, _config) => {
2091
2501
 
2092
2502
  const options: {
2093
2503
  key: string;
2094
- type: "number" | "string";
2504
+ type: "number" | "string" | "boolean";
2095
2505
  }[] = [
2096
2506
  { key: "max_batch_size", type: "number" },
2097
2507
  { key: "max_batch_timeout", type: "number" },
2098
2508
  { key: "max_retries", type: "number" },
2099
2509
  { key: "dead_letter_queue", type: "string" },
2510
+ { key: "max_concurrency", type: "number" },
2100
2511
  ];
2101
2512
  for (const optionalOpt of options) {
2102
2513
  if (!isOptionalProperty(value, optionalOpt.key, optionalOpt.type)) {
@@ -0,0 +1,51 @@
1
+ import { fetchResult } from "../cfetch";
2
+ import { withConfig } from "../config";
3
+ import { logger } from "../logger";
4
+ import { requireAuth } from "../user";
5
+ import { takeName } from "./options";
6
+ import { constellationBetaWarning } from "./utils";
7
+ import type {
8
+ CommonYargsArgv,
9
+ StrictYargsOptionsToInterface,
10
+ } from "../yargs-types";
11
+ import type { Project } from "./types";
12
+
13
+ export function options(yargs: CommonYargsArgv) {
14
+ return takeName(yargs)
15
+ .positional("runtime", {
16
+ describe: "The name of the runtime to use",
17
+ type: "string",
18
+ demandOption: true,
19
+ })
20
+ .epilogue(constellationBetaWarning);
21
+ }
22
+
23
+ type HandlerOptions = StrictYargsOptionsToInterface<typeof options>;
24
+ export const handler = withConfig<HandlerOptions>(
25
+ async ({ name, runtime, config }): Promise<void> => {
26
+ const accountId = await requireAuth(config);
27
+
28
+ logger.log(constellationBetaWarning);
29
+
30
+ let proj: Project;
31
+ try {
32
+ proj = await fetchResult(`/accounts/${accountId}/constellation/project`, {
33
+ method: "POST",
34
+ headers: {
35
+ "Content-Type": "application/json",
36
+ },
37
+ body: JSON.stringify({
38
+ name,
39
+ runtime,
40
+ }),
41
+ });
42
+ } catch (e) {
43
+ if ((e as { code: number }).code === 7409) {
44
+ throw new Error("A project with that name already exists");
45
+ }
46
+ throw e;
47
+ }
48
+
49
+ logger.log(`✅ Successfully created Project "${proj.name}"!`);
50
+ }
51
+ );