wrangler 0.0.0-e98613f8 → 0.0.0-e9a45766c

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 (244) hide show
  1. package/README.md +10 -4
  2. package/bin/wrangler.js +10 -2
  3. package/miniflare-dist/index.mjs +257 -132
  4. package/package.json +26 -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 +575 -39
  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 +11 -2
  15. package/src/__tests__/deployments.test.ts +330 -52
  16. package/src/__tests__/dev.test.tsx +146 -82
  17. package/src/__tests__/generate.test.ts +10 -8
  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 +99 -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 +127 -26
  32. package/src/__tests__/helpers/msw/handlers/namespaces.ts +18 -41
  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 +92 -74
  42. package/src/__tests__/init.test.ts +909 -628
  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 +1 -1
  47. package/src/__tests__/metrics.test.ts +93 -50
  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 +589 -0
  51. package/src/__tests__/pages/deployment-list.test.ts +80 -0
  52. package/src/__tests__/pages/functions-build.test.ts +528 -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 +239 -102
  59. package/src/__tests__/parse.test.ts +106 -0
  60. package/src/__tests__/publish.test.ts +2218 -1002
  61. package/src/__tests__/pubsub.test.ts +226 -100
  62. package/src/__tests__/queues.test.ts +42 -32
  63. package/src/__tests__/r2.test.ts +37 -56
  64. package/src/__tests__/secret.test.ts +179 -130
  65. package/src/__tests__/tail.test.ts +113 -23
  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 +8 -0
  72. package/src/__tests__/user.test.ts +7 -18
  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 +172 -61
  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 +77 -0
  79. package/src/api/pages/index.ts +5 -0
  80. package/src/api/pages/publish.tsx +371 -0
  81. package/src/bundle.ts +139 -33
  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 +80 -16
  87. package/src/config/index.ts +99 -30
  88. package/src/config/validation-helpers.ts +1 -1
  89. package/src/config/validation.ts +275 -9
  90. package/src/constellation/createProject.tsx +51 -0
  91. package/src/constellation/deleteProject.ts +51 -0
  92. package/src/constellation/deleteProjectModel.ts +68 -0
  93. package/src/constellation/index.ts +75 -0
  94. package/src/constellation/listCatalog.tsx +35 -0
  95. package/src/constellation/listModel.tsx +41 -0
  96. package/src/constellation/listProject.tsx +28 -0
  97. package/src/constellation/listRuntime.tsx +28 -0
  98. package/src/constellation/options.ts +17 -0
  99. package/src/constellation/types.ts +17 -0
  100. package/src/constellation/uploadModel.tsx +64 -0
  101. package/src/constellation/utils.ts +90 -0
  102. package/src/create-worker-preview.ts +19 -8
  103. package/src/create-worker-upload-form.ts +52 -5
  104. package/src/d1/backups.tsx +40 -44
  105. package/src/d1/create.tsx +50 -43
  106. package/src/d1/{delete.tsx → delete.ts} +8 -11
  107. package/src/d1/execute.tsx +171 -166
  108. package/src/d1/index.ts +5 -6
  109. package/src/d1/list.tsx +27 -13
  110. package/src/d1/migrations/apply.tsx +92 -64
  111. package/src/d1/migrations/create.tsx +31 -29
  112. package/src/d1/migrations/helpers.ts +66 -44
  113. package/src/d1/migrations/list.tsx +47 -31
  114. package/src/d1/migrations/options.ts +7 -2
  115. package/src/d1/options.ts +3 -3
  116. package/src/d1/splitter.ts +161 -0
  117. package/src/d1/{types.tsx → types.ts} +1 -0
  118. package/src/d1/utils.ts +2 -1
  119. package/src/delete.ts +8 -16
  120. package/src/deployments.ts +333 -42
  121. package/src/deprecated/index.ts +8 -302
  122. package/src/dev/dev.tsx +13 -22
  123. package/src/dev/local.tsx +131 -69
  124. package/src/dev/remote.tsx +35 -3
  125. package/src/dev/start-server.ts +83 -77
  126. package/src/dev/use-esbuild.ts +63 -52
  127. package/src/dev/validate-dev-props.ts +9 -0
  128. package/src/{dev-registry.tsx → dev-registry.ts} +9 -8
  129. package/src/dev.tsx +131 -110
  130. package/src/dialogs.ts +136 -0
  131. package/src/dispatch-namespace.ts +21 -17
  132. package/src/docs/helpers.ts +50 -0
  133. package/src/docs/index.ts +54 -0
  134. package/src/entry.ts +26 -11
  135. package/src/environment-variables/factory.ts +89 -0
  136. package/src/environment-variables/misc-variables.ts +30 -0
  137. package/src/generate/index.ts +298 -0
  138. package/src/{index.tsx → index.ts} +137 -56
  139. package/src/init.ts +254 -187
  140. package/src/inspect.ts +170 -9
  141. package/src/jest.d.ts +4 -0
  142. package/src/kv/helpers.ts +7 -4
  143. package/src/kv/index.ts +15 -17
  144. package/src/logger.ts +36 -5
  145. package/src/metrics/metrics-config.ts +1 -1
  146. package/src/metrics/send-event.ts +4 -1
  147. package/src/miniflare-cli/assets.ts +66 -31
  148. package/src/miniflare-cli/index.ts +5 -8
  149. package/src/miniflare-cli/tsconfig.json +9 -0
  150. package/src/miniflare-cli/tsconfig.tsbuildinfo +1 -0
  151. package/src/miniflare-cli/types.ts +11 -0
  152. package/src/module-collection.ts +92 -26
  153. package/src/mtls-certificate/cli.ts +155 -0
  154. package/src/pages/build.ts +423 -0
  155. package/src/pages/buildFunctions.ts +140 -0
  156. package/src/pages/{deployment-tails.tsx → deployment-tails.ts} +7 -10
  157. package/src/pages/deployments.tsx +9 -9
  158. package/src/pages/{dev.tsx → dev.ts} +167 -139
  159. package/src/pages/errors.ts +1 -0
  160. package/src/pages/functions/buildPlugin.ts +61 -54
  161. package/src/pages/functions/buildWorker.ts +217 -33
  162. package/src/pages/functions/tsconfig.json +8 -0
  163. package/src/pages/functions/tsconfig.tsbuildinfo +1 -0
  164. package/src/pages/{functions.tsx → functions.ts} +8 -4
  165. package/src/pages/{index.tsx → index.ts} +3 -3
  166. package/src/pages/projects.tsx +12 -22
  167. package/src/pages/publish.tsx +43 -227
  168. package/src/pages/types.ts +5 -0
  169. package/src/pages/upload.tsx +57 -14
  170. package/src/pages/utils.ts +1 -1
  171. package/src/parse.ts +23 -1
  172. package/src/paths.ts +1 -1
  173. package/src/publish/index.ts +20 -16
  174. package/src/publish/publish.ts +76 -46
  175. package/src/pubsub/{pubsub-commands.tsx → pubsub-commands.ts} +19 -20
  176. package/src/queues/cli/commands/consumer/add.ts +24 -24
  177. package/src/queues/cli/commands/consumer/index.ts +3 -6
  178. package/src/queues/cli/commands/consumer/remove.ts +11 -18
  179. package/src/queues/cli/commands/create.ts +8 -8
  180. package/src/queues/cli/commands/delete.ts +8 -8
  181. package/src/queues/cli/commands/index.ts +3 -4
  182. package/src/queues/cli/commands/list.ts +8 -8
  183. package/src/queues/client.ts +1 -0
  184. package/src/r2/helpers.ts +1 -0
  185. package/src/r2/index.ts +28 -28
  186. package/src/secret/index.ts +15 -16
  187. package/src/{sites.tsx → sites.ts} +165 -53
  188. package/src/tail/createTail.ts +37 -1
  189. package/src/tail/filters.ts +1 -1
  190. package/src/tail/index.ts +8 -11
  191. package/src/tail/printing.ts +25 -0
  192. package/src/traverse-module-graph.ts +54 -0
  193. package/src/tsconfig-sanity.ts +16 -0
  194. package/src/type-generation.ts +11 -3
  195. package/src/user/access.ts +0 -1
  196. package/src/user/auth-variables.ts +113 -0
  197. package/src/user/choose-account.tsx +1 -31
  198. package/src/user/index.ts +0 -1
  199. package/src/user/{user.tsx → user.ts} +114 -77
  200. package/src/utils/render.ts +93 -0
  201. package/src/{whoami.tsx → whoami.ts} +37 -71
  202. package/src/worker.ts +35 -1
  203. package/src/yargs-types.ts +18 -5
  204. package/templates/__tests__/tsconfig-sanity.ts +12 -0
  205. package/templates/__tests__/tsconfig.json +8 -0
  206. package/templates/__tests__/tsconfig.tsbuildinfo +1 -0
  207. package/templates/checked-fetch.js +9 -3
  208. package/templates/d1-beta-facade.js +42 -3
  209. package/templates/facade.d.ts +14 -0
  210. package/templates/first-party-worker-module-facade.ts +4 -3
  211. package/templates/format-dev-errors.ts +8 -6
  212. package/templates/gitignore +1 -0
  213. package/templates/init-tests/test-jest-new-worker.js +3 -5
  214. package/templates/init-tests/test-vitest-new-worker.js +3 -5
  215. package/templates/init-tests/test-vitest-new-worker.ts +25 -0
  216. package/templates/middleware/loader-modules.ts +2 -2
  217. package/templates/middleware/loader-sw.ts +6 -0
  218. package/templates/middleware/middleware-miniflare3-json-error.ts +17 -5
  219. package/templates/new-worker.ts +3 -0
  220. package/templates/pages-dev-pipeline.ts +4 -1
  221. package/templates/pages-shim.ts +4 -1
  222. package/templates/pages-template-plugin.ts +19 -10
  223. package/templates/serve-static-assets.ts +17 -14
  224. package/templates/service-bindings-module-facade.js +1 -0
  225. package/templates/tsconfig-sanity.ts +11 -0
  226. package/templates/tsconfig.init.json +105 -0
  227. package/templates/tsconfig.json +5 -103
  228. package/templates/tsconfig.tsbuildinfo +1 -0
  229. package/wrangler-dist/cli.d.ts +871 -73
  230. package/wrangler-dist/cli.js +80512 -90686
  231. package/wrangler-dist/wasm-sync.wasm +0 -0
  232. package/src/__tests__/api-devregistry.test.js +0 -56
  233. package/src/__tests__/d1.test.ts +0 -80
  234. package/src/__tests__/dialogs.test.tsx +0 -40
  235. package/src/__tests__/helpers/mock-cfetch.ts +0 -333
  236. package/src/__tests__/pages.test.ts +0 -2442
  237. package/src/dialogs.tsx +0 -168
  238. package/src/environment-variables.ts +0 -50
  239. package/src/pages/build.tsx +0 -270
  240. package/src/user/env-vars.ts +0 -46
  241. /package/src/{bundle-reporter.tsx → bundle-reporter.ts} +0 -0
  242. /package/src/d1/migrations/{index.tsx → index.ts} +0 -0
  243. /package/src/dev/{get-local-persistence-path.tsx → get-local-persistence-path.ts} +0 -0
  244. /package/src/pages/{hash.tsx → hash.ts} +0 -0
@@ -40,6 +40,7 @@ describe("normalizeAndValidateConfig()", () => {
40
40
  jsx_fragment: "React.Fragment",
41
41
  tsconfig: undefined,
42
42
  kv_namespaces: [],
43
+ send_email: [],
43
44
  legacy_env: true,
44
45
  logfwdr: {
45
46
  bindings: [],
@@ -55,6 +56,7 @@ describe("normalizeAndValidateConfig()", () => {
55
56
  },
56
57
  r2_buckets: [],
57
58
  services: [],
59
+ analytics_engine_datasets: [],
58
60
  route: undefined,
59
61
  routes: undefined,
60
62
  rules: [],
@@ -64,9 +66,11 @@ describe("normalizeAndValidateConfig()", () => {
64
66
  crons: [],
65
67
  },
66
68
  unsafe: {
67
- bindings: [],
69
+ bindings: undefined,
70
+ metadata: undefined,
68
71
  },
69
72
  dispatch_namespaces: [],
73
+ mtls_certificates: [],
70
74
  usage_model: undefined,
71
75
  vars: {},
72
76
  define: {},
@@ -80,6 +84,7 @@ describe("normalizeAndValidateConfig()", () => {
80
84
  first_party_worker: undefined,
81
85
  keep_vars: undefined,
82
86
  logpush: undefined,
87
+ placement: undefined,
83
88
  });
84
89
  expect(diagnostics.hasErrors()).toBe(false);
85
90
  expect(diagnostics.hasWarnings()).toBe(false);
@@ -900,6 +905,17 @@ describe("normalizeAndValidateConfig()", () => {
900
905
  preview_id: "KV_PREVIEW_1",
901
906
  },
902
907
  ],
908
+ send_email: [
909
+ { name: "SEB_TARGET", destination_address: "teste@example.com" },
910
+ { name: "SEB_UNRESTRICTED" },
911
+ {
912
+ name: "SEB_ALLOWLIST",
913
+ allowed_destination_addresses: [
914
+ "email1@example.com",
915
+ "email2@example.com",
916
+ ],
917
+ },
918
+ ],
903
919
  r2_buckets: [
904
920
  { binding: "R2_BINDING_1", bucket_name: "R2_BUCKET_1" },
905
921
  {
@@ -915,6 +931,15 @@ describe("normalizeAndValidateConfig()", () => {
915
931
  environment: "SERVICE_BINDING_ENVIRONMENT_1",
916
932
  },
917
933
  ],
934
+ analytics_engine_datasets: [
935
+ {
936
+ binding: "AE_BINDING_1",
937
+ dataset: "DATASET_1",
938
+ },
939
+ {
940
+ binding: "AE_BINDING_2",
941
+ },
942
+ ],
918
943
  unsafe: {
919
944
  bindings: [
920
945
  { name: "UNSAFE_BINDING_1", type: "UNSAFE_TYPE_1" },
@@ -924,12 +949,16 @@ describe("normalizeAndValidateConfig()", () => {
924
949
  extra: "UNSAFE_EXTRA_1",
925
950
  },
926
951
  ],
952
+ metadata: undefined,
927
953
  },
928
954
  no_bundle: true,
929
955
  minify: true,
930
956
  node_compat: true,
931
957
  first_party_worker: true,
932
958
  logpush: true,
959
+ placement: {
960
+ mode: "smart",
961
+ },
933
962
  };
934
963
 
935
964
  const { config, diagnostics } = normalizeAndValidateConfig(
@@ -1005,6 +1034,9 @@ describe("normalizeAndValidateConfig()", () => {
1005
1034
  node_compat: "INVALID",
1006
1035
  first_party_worker: "INVALID",
1007
1036
  logpush: "INVALID",
1037
+ placement: {
1038
+ mode: "INVALID",
1039
+ },
1008
1040
  } as unknown as RawEnvironment;
1009
1041
 
1010
1042
  const { config, diagnostics } = normalizeAndValidateConfig(
@@ -1068,6 +1100,7 @@ describe("normalizeAndValidateConfig()", () => {
1068
1100
  - Expected \\"name\\" to be of type string, alphanumeric and lowercase with dashes only but got 111.
1069
1101
  - Expected \\"main\\" to be of type string but got 1333.
1070
1102
  - Expected \\"usage_model\\" field to be one of [\\"bundled\\",\\"unbound\\"] but got \\"INVALID\\".
1103
+ - Expected \\"placement.mode\\" field to be one of [\\"off\\",\\"smart\\"] but got \\"INVALID\\".
1071
1104
  - The field \\"define.DEF1\\" should be a string but got 1777.
1072
1105
  - Expected \\"no_bundle\\" to be of type boolean but got \\"INVALID\\".
1073
1106
  - Expected \\"minify\\" to be of type boolean but got \\"INVALID\\".
@@ -1616,6 +1649,39 @@ describe("normalizeAndValidateConfig()", () => {
1616
1649
  });
1617
1650
  });
1618
1651
 
1652
+ it("should error if send_email.bindings are not valid", () => {
1653
+ const { diagnostics } = normalizeAndValidateConfig(
1654
+ {
1655
+ send_email: [
1656
+ {},
1657
+ { binding: "VALID" },
1658
+ { name: "SEB", destination_address: 123 },
1659
+ {
1660
+ name: "SEB2",
1661
+ allowed_destination_addresses: 123,
1662
+ },
1663
+ {
1664
+ name: "SEB3",
1665
+ destination_address: "email@example.com",
1666
+ allowed_destination_addresses: ["email@example.com"],
1667
+ },
1668
+ ],
1669
+ } as unknown as RawConfig,
1670
+ undefined,
1671
+ { env: undefined }
1672
+ );
1673
+
1674
+ expect(diagnostics.hasWarnings()).toBe(false);
1675
+ expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
1676
+ "Processing wrangler configuration:
1677
+ - \\"send_email[0]\\" bindings should have a string \\"name\\" field but got {}.
1678
+ - \\"send_email[1]\\" bindings should have a string \\"name\\" field but got {\\"binding\\":\\"VALID\\"}.
1679
+ - \\"send_email[2]\\" bindings should, optionally, have a string \\"destination_address\\" field but got {\\"name\\":\\"SEB\\",\\"destination_address\\":123}.
1680
+ - \\"send_email[3]\\" bindings should, optionally, have a []string \\"allowed_destination_addresses\\" field but got {\\"name\\":\\"SEB2\\",\\"allowed_destination_addresses\\":123}.
1681
+ - \\"send_email[4]\\" bindings should have either a \\"destination_address\\" or \\"allowed_destination_addresses\\" field, but not both."
1682
+ `);
1683
+ });
1684
+
1619
1685
  describe("[d1_databases]", () => {
1620
1686
  it("should error if d1_databases is an object", () => {
1621
1687
  const { diagnostics } = normalizeAndValidateConfig(
@@ -1778,6 +1844,7 @@ describe("normalizeAndValidateConfig()", () => {
1778
1844
  max_batch_timeout: null,
1779
1845
  max_retries: "hello",
1780
1846
  dead_letter_queue: 5,
1847
+ max_concurrency: "hello",
1781
1848
  },
1782
1849
  ],
1783
1850
  },
@@ -1793,20 +1860,21 @@ describe("normalizeAndValidateConfig()", () => {
1793
1860
  );
1794
1861
  expect(diagnostics.hasWarnings()).toBe(true);
1795
1862
  expect(diagnostics.renderWarnings()).toMatchInlineSnapshot(`
1796
- "Processing wrangler configuration:
1797
- - Unexpected fields found in queues field: \\"invalidField\\"
1798
- - Unexpected fields found in queues.consumers[2] field: \\"invalidField\\""
1799
- `);
1863
+ "Processing wrangler configuration:
1864
+ - Unexpected fields found in queues field: \\"invalidField\\"
1865
+ - Unexpected fields found in queues.consumers[2] field: \\"invalidField\\""
1866
+ `);
1800
1867
 
1801
1868
  expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
1802
- "Processing wrangler configuration:
1803
- - \\"queues.consumers[0]\\" should have a string \\"queue\\" field but got {}.
1804
- - \\"queues.consumers[1]\\" should have a string \\"queue\\" field but got {\\"queue\\":22}.
1805
- - \\"queues.consumers[3]\\" should, optionally, have a number \\"max_batch_size\\" field but got {\\"queue\\":\\"myQueue\\",\\"max_batch_size\\":\\"3\\",\\"max_batch_timeout\\":null,\\"max_retries\\":\\"hello\\",\\"dead_letter_queue\\":5}.
1806
- - \\"queues.consumers[3]\\" should, optionally, have a number \\"max_batch_timeout\\" field but got {\\"queue\\":\\"myQueue\\",\\"max_batch_size\\":\\"3\\",\\"max_batch_timeout\\":null,\\"max_retries\\":\\"hello\\",\\"dead_letter_queue\\":5}.
1807
- - \\"queues.consumers[3]\\" should, optionally, have a number \\"max_retries\\" field but got {\\"queue\\":\\"myQueue\\",\\"max_batch_size\\":\\"3\\",\\"max_batch_timeout\\":null,\\"max_retries\\":\\"hello\\",\\"dead_letter_queue\\":5}.
1808
- - \\"queues.consumers[3]\\" should, optionally, have a string \\"dead_letter_queue\\" field but got {\\"queue\\":\\"myQueue\\",\\"max_batch_size\\":\\"3\\",\\"max_batch_timeout\\":null,\\"max_retries\\":\\"hello\\",\\"dead_letter_queue\\":5}."
1809
- `);
1869
+ "Processing wrangler configuration:
1870
+ - \\"queues.consumers[0]\\" should have a string \\"queue\\" field but got {}.
1871
+ - \\"queues.consumers[1]\\" should have a string \\"queue\\" field but got {\\"queue\\":22}.
1872
+ - \\"queues.consumers[3]\\" should, optionally, have a number \\"max_batch_size\\" field but got {\\"queue\\":\\"myQueue\\",\\"max_batch_size\\":\\"3\\",\\"max_batch_timeout\\":null,\\"max_retries\\":\\"hello\\",\\"dead_letter_queue\\":5,\\"max_concurrency\\":\\"hello\\"}.
1873
+ - \\"queues.consumers[3]\\" should, optionally, have a number \\"max_batch_timeout\\" field but got {\\"queue\\":\\"myQueue\\",\\"max_batch_size\\":\\"3\\",\\"max_batch_timeout\\":null,\\"max_retries\\":\\"hello\\",\\"dead_letter_queue\\":5,\\"max_concurrency\\":\\"hello\\"}.
1874
+ - \\"queues.consumers[3]\\" should, optionally, have a number \\"max_retries\\" field but got {\\"queue\\":\\"myQueue\\",\\"max_batch_size\\":\\"3\\",\\"max_batch_timeout\\":null,\\"max_retries\\":\\"hello\\",\\"dead_letter_queue\\":5,\\"max_concurrency\\":\\"hello\\"}.
1875
+ - \\"queues.consumers[3]\\" should, optionally, have a string \\"dead_letter_queue\\" field but got {\\"queue\\":\\"myQueue\\",\\"max_batch_size\\":\\"3\\",\\"max_batch_timeout\\":null,\\"max_retries\\":\\"hello\\",\\"dead_letter_queue\\":5,\\"max_concurrency\\":\\"hello\\"}.
1876
+ - \\"queues.consumers[3]\\" should, optionally, have a number \\"max_concurrency\\" field but got {\\"queue\\":\\"myQueue\\",\\"max_batch_size\\":\\"3\\",\\"max_batch_timeout\\":null,\\"max_retries\\":\\"hello\\",\\"dead_letter_queue\\":5,\\"max_concurrency\\":\\"hello\\"}."
1877
+ `);
1810
1878
  });
1811
1879
  });
1812
1880
 
@@ -2028,28 +2096,93 @@ describe("normalizeAndValidateConfig()", () => {
2028
2096
  });
2029
2097
  });
2030
2098
 
2031
- describe("[dispatch_namespaces]", () => {
2032
- it("should log an experimental warning when dispatch_namespaces is used", () => {
2099
+ describe("[analytics_engine_datasets]", () => {
2100
+ it("should error if analytics_engine_datasets is an object", () => {
2101
+ const { diagnostics } = normalizeAndValidateConfig(
2102
+ { analytics_engine_datasets: {} } as unknown as RawConfig,
2103
+ undefined,
2104
+ { env: undefined }
2105
+ );
2106
+
2107
+ expect(diagnostics.hasWarnings()).toBe(false);
2108
+ expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
2109
+ "Processing wrangler configuration:
2110
+ - The field \\"analytics_engine_datasets\\" should be an array but got {}."
2111
+ `);
2112
+ });
2113
+
2114
+ it("should error if analytics_engine_datasets is a string", () => {
2115
+ const { diagnostics } = normalizeAndValidateConfig(
2116
+ { analytics_engine_datasets: "BAD" } as unknown as RawConfig,
2117
+ undefined,
2118
+ { env: undefined }
2119
+ );
2120
+
2121
+ expect(diagnostics.hasWarnings()).toBe(false);
2122
+ expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
2123
+ "Processing wrangler configuration:
2124
+ - The field \\"analytics_engine_datasets\\" should be an array but got \\"BAD\\"."
2125
+ `);
2126
+ });
2127
+
2128
+ it("should error if analytics_engine_datasets is a number", () => {
2129
+ const { diagnostics } = normalizeAndValidateConfig(
2130
+ { analytics_engine_datasets: 999 } as unknown as RawConfig,
2131
+ undefined,
2132
+ { env: undefined }
2133
+ );
2134
+
2135
+ expect(diagnostics.hasWarnings()).toBe(false);
2136
+ expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
2137
+ "Processing wrangler configuration:
2138
+ - The field \\"analytics_engine_datasets\\" should be an array but got 999."
2139
+ `);
2140
+ });
2141
+
2142
+ it("should error if analytics_engine_datasets is null", () => {
2143
+ const { diagnostics } = normalizeAndValidateConfig(
2144
+ { analytics_engine_datasets: null } as unknown as RawConfig,
2145
+ undefined,
2146
+ { env: undefined }
2147
+ );
2148
+
2149
+ expect(diagnostics.hasWarnings()).toBe(false);
2150
+ expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
2151
+ "Processing wrangler configuration:
2152
+ - The field \\"analytics_engine_datasets\\" should be an array but got null."
2153
+ `);
2154
+ });
2155
+
2156
+ it("should error if analytics_engine_datasets.bindings are not valid", () => {
2033
2157
  const { diagnostics } = normalizeAndValidateConfig(
2034
2158
  {
2035
- dispatch_namespaces: [
2159
+ analytics_engine_datasets: [
2160
+ {},
2161
+ { binding: 2333, dataset: 2444 },
2036
2162
  {
2037
- binding: "BINDING_1",
2038
- namespace: "NAMESPACE_1",
2163
+ binding: "AE_BINDING_2",
2164
+ dataset: 2555,
2039
2165
  },
2166
+ { binding: "AE_BINDING_1", dataset: "" },
2040
2167
  ],
2041
2168
  } as unknown as RawConfig,
2042
2169
  undefined,
2043
2170
  { env: undefined }
2044
2171
  );
2045
- expect(diagnostics.hasWarnings()).toBe(true);
2046
- expect(diagnostics.hasErrors()).toBe(false);
2047
- expect(diagnostics.renderWarnings()).toMatchInlineSnapshot(`
2048
- "Processing wrangler configuration:
2049
- - \\"dispatch_namespaces\\" fields are experimental and may change or break at any time."
2050
- `);
2172
+
2173
+ expect(diagnostics.hasWarnings()).toBe(false);
2174
+ expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
2175
+ "Processing wrangler configuration:
2176
+ - \\"analytics_engine_datasets[0]\\" bindings should have a string \\"binding\\" field but got {}.
2177
+ - \\"analytics_engine_datasets[1]\\" bindings should have a string \\"binding\\" field but got {\\"binding\\":2333,\\"dataset\\":2444}.
2178
+ - \\"analytics_engine_datasets[1]\\" bindings should, optionally, have a string \\"dataset\\" field but got {\\"binding\\":2333,\\"dataset\\":2444}.
2179
+ - \\"analytics_engine_datasets[2]\\" bindings should, optionally, have a string \\"dataset\\" field but got {\\"binding\\":\\"AE_BINDING_2\\",\\"dataset\\":2555}.
2180
+ - \\"analytics_engine_datasets[3]\\" bindings should, optionally, have a string \\"dataset\\" field but got {\\"binding\\":\\"AE_BINDING_1\\",\\"dataset\\":\\"\\"}."
2181
+ `);
2051
2182
  });
2183
+ });
2052
2184
 
2185
+ describe("[dispatch_namespaces]", () => {
2053
2186
  it("should error if dispatch_namespaces is not an array", () => {
2054
2187
  const { diagnostics } = normalizeAndValidateConfig(
2055
2188
  {
@@ -2059,12 +2192,8 @@ describe("normalizeAndValidateConfig()", () => {
2059
2192
  { env: undefined }
2060
2193
  );
2061
2194
 
2062
- expect(diagnostics.hasWarnings()).toBe(true);
2195
+ expect(diagnostics.hasWarnings()).toBe(false);
2063
2196
  expect(diagnostics.hasErrors()).toBe(true);
2064
- expect(diagnostics.renderWarnings()).toMatchInlineSnapshot(`
2065
- "Processing wrangler configuration:
2066
- - \\"dispatch_namespaces\\" fields are experimental and may change or break at any time."
2067
- `);
2068
2197
  expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
2069
2198
  "Processing wrangler configuration:
2070
2199
  - The field \\"dispatch_namespaces\\" should be an array but got \\"just a string\\"."
@@ -2103,12 +2232,8 @@ describe("normalizeAndValidateConfig()", () => {
2103
2232
  undefined,
2104
2233
  { env: undefined }
2105
2234
  );
2106
- expect(diagnostics.hasWarnings()).toBe(true);
2235
+ expect(diagnostics.hasWarnings()).toBe(false);
2107
2236
  expect(diagnostics.hasErrors()).toBe(true);
2108
- expect(diagnostics.renderWarnings()).toMatchInlineSnapshot(`
2109
- "Processing wrangler configuration:
2110
- - \\"dispatch_namespaces\\" fields are experimental and may change or break at any time."
2111
- `);
2112
2237
  expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
2113
2238
  "Processing wrangler configuration:
2114
2239
  - \\"dispatch_namespaces[0]\\" binding should be objects, but got \\"a string\\"
@@ -2123,6 +2248,75 @@ describe("normalizeAndValidateConfig()", () => {
2123
2248
  });
2124
2249
  });
2125
2250
 
2251
+ describe("[mtls_certificates]", () => {
2252
+ it("should error if mtls_certificates is not an array", () => {
2253
+ const { diagnostics } = normalizeAndValidateConfig(
2254
+ {
2255
+ mtls_certificates: "just a string",
2256
+ } as unknown as RawConfig,
2257
+ undefined,
2258
+ { env: undefined }
2259
+ );
2260
+
2261
+ expect(diagnostics.hasWarnings()).toBe(false);
2262
+ expect(diagnostics.hasErrors()).toBe(true);
2263
+ expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
2264
+ "Processing wrangler configuration:
2265
+ - The field \\"mtls_certificates\\" should be an array but got \\"just a string\\"."
2266
+ `);
2267
+ });
2268
+
2269
+ it("should error on non valid mtls_certificates", () => {
2270
+ const { diagnostics } = normalizeAndValidateConfig(
2271
+ {
2272
+ mtls_certificates: [
2273
+ "a string",
2274
+ 123,
2275
+ false,
2276
+ {
2277
+ binding: 123,
2278
+ namespace: 123,
2279
+ },
2280
+ {
2281
+ binding: "CERT_ONE",
2282
+ id: "1234",
2283
+ },
2284
+ {
2285
+ binding: "CERT_TWO",
2286
+ certificate_id: 1234,
2287
+ },
2288
+ // this one is valid
2289
+ {
2290
+ binding: "CERT_THREE",
2291
+ certificate_id: "1234",
2292
+ },
2293
+ {
2294
+ binding: true,
2295
+ service: "1234",
2296
+ },
2297
+ ],
2298
+ } as unknown as RawConfig,
2299
+ undefined,
2300
+ { env: undefined }
2301
+ );
2302
+
2303
+ expect(diagnostics.hasWarnings()).toBe(false);
2304
+ expect(diagnostics.hasErrors()).toBe(true);
2305
+ expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
2306
+ "Processing wrangler configuration:
2307
+ - \\"mtls_certificates\\" bindings should be objects, but got \\"a string\\"
2308
+ - \\"mtls_certificates\\" bindings should be objects, but got 123
2309
+ - \\"mtls_certificates\\" bindings should be objects, but got false
2310
+ - \\"mtls_certificates[3]\\" bindings should have a string \\"binding\\" field but got {\\"binding\\":123,\\"namespace\\":123}.
2311
+ - \\"mtls_certificates[3]\\" bindings should have a string \\"certificate_id\\" field but got {\\"binding\\":123,\\"namespace\\":123}.
2312
+ - \\"mtls_certificates[4]\\" bindings should have a string \\"certificate_id\\" field but got {\\"binding\\":\\"CERT_ONE\\",\\"id\\":\\"1234\\"}.
2313
+ - \\"mtls_certificates[5]\\" bindings should have a string \\"certificate_id\\" field but got {\\"binding\\":\\"CERT_TWO\\",\\"certificate_id\\":1234}.
2314
+ - \\"mtls_certificates[7]\\" bindings should have a string \\"binding\\" field but got {\\"binding\\":true,\\"service\\":\\"1234\\"}.
2315
+ - \\"mtls_certificates[7]\\" bindings should have a string \\"certificate_id\\" field but got {\\"binding\\":true,\\"service\\":\\"1234\\"}."
2316
+ `);
2317
+ });
2318
+ });
2319
+
2126
2320
  describe("[unsafe.bindings]", () => {
2127
2321
  it("should error if unsafe is an array", () => {
2128
2322
  const { diagnostics } = normalizeAndValidateConfig(
@@ -2192,7 +2386,7 @@ describe("normalizeAndValidateConfig()", () => {
2192
2386
  `);
2193
2387
  });
2194
2388
 
2195
- it("should error if unsafe.bindings is not defined", () => {
2389
+ it("should error if neither unsafe.bindings nor unsafe.metadata are defined", () => {
2196
2390
  const { diagnostics } = normalizeAndValidateConfig(
2197
2391
  { unsafe: {} } as unknown as RawConfig,
2198
2392
  undefined,
@@ -2204,9 +2398,37 @@ describe("normalizeAndValidateConfig()", () => {
2204
2398
  - \\"unsafe\\" fields are experimental and may change or break at any time."
2205
2399
  `);
2206
2400
  expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
2401
+ "Processing wrangler configuration:
2402
+ - The field \\"unsafe\\" should contain at least one of \\"bindings\\" or \\"metadata\\" properties but got {}."
2403
+ `);
2404
+ });
2405
+
2406
+ it("should not error if at least unsafe.bindings is defined", () => {
2407
+ const { diagnostics } = normalizeAndValidateConfig(
2408
+ { unsafe: { bindings: [] } } as unknown as RawConfig,
2409
+ undefined,
2410
+ { env: undefined }
2411
+ );
2412
+
2413
+ expect(diagnostics.renderWarnings()).toMatchInlineSnapshot(`
2414
+ "Processing wrangler configuration:
2415
+ - \\"unsafe\\" fields are experimental and may change or break at any time."
2416
+ `);
2417
+ expect(diagnostics.hasErrors()).toBe(false);
2418
+ });
2419
+
2420
+ it("should not error if at least unsafe.metadata is defined", () => {
2421
+ const { diagnostics } = normalizeAndValidateConfig(
2422
+ { unsafe: { metadata: {} } } as unknown as RawConfig,
2423
+ undefined,
2424
+ { env: undefined }
2425
+ );
2426
+
2427
+ expect(diagnostics.renderWarnings()).toMatchInlineSnapshot(`
2207
2428
  "Processing wrangler configuration:
2208
- - The field \\"unsafe\\" is missing the required \\"bindings\\" property."
2429
+ - \\"unsafe\\" fields are experimental and may change or break at any time."
2209
2430
  `);
2431
+ expect(diagnostics.hasErrors()).toBe(false);
2210
2432
  });
2211
2433
 
2212
2434
  it("should error if unsafe.bindings is an object", () => {
@@ -2316,6 +2538,74 @@ describe("normalizeAndValidateConfig()", () => {
2316
2538
  - binding should have a string \\"type\\" field."
2317
2539
  `);
2318
2540
  });
2541
+
2542
+ it("should error if unsafe.metadata is an array", () => {
2543
+ const { diagnostics } = normalizeAndValidateConfig(
2544
+ { unsafe: { metadata: [] } } as unknown as RawConfig,
2545
+ undefined,
2546
+ { env: undefined }
2547
+ );
2548
+
2549
+ expect(diagnostics.renderWarnings()).toMatchInlineSnapshot(`
2550
+ "Processing wrangler configuration:
2551
+ - \\"unsafe\\" fields are experimental and may change or break at any time."
2552
+ `);
2553
+ expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
2554
+ "Processing wrangler configuration:
2555
+ - The field \\"unsafe.metadata\\" should be an object but got []."
2556
+ `);
2557
+ });
2558
+
2559
+ it("should error if unsafe.metadata is a string", () => {
2560
+ const { diagnostics } = normalizeAndValidateConfig(
2561
+ { unsafe: { metadata: "BAD" } } as unknown as RawConfig,
2562
+ undefined,
2563
+ { env: undefined }
2564
+ );
2565
+
2566
+ expect(diagnostics.renderWarnings()).toMatchInlineSnapshot(`
2567
+ "Processing wrangler configuration:
2568
+ - \\"unsafe\\" fields are experimental and may change or break at any time."
2569
+ `);
2570
+ expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
2571
+ "Processing wrangler configuration:
2572
+ - The field \\"unsafe.metadata\\" should be an object but got \\"BAD\\"."
2573
+ `);
2574
+ });
2575
+
2576
+ it("should error if unsafe.metadata is a number", () => {
2577
+ const { diagnostics } = normalizeAndValidateConfig(
2578
+ { unsafe: { metadata: 999 } } as unknown as RawConfig,
2579
+ undefined,
2580
+ { env: undefined }
2581
+ );
2582
+
2583
+ expect(diagnostics.renderWarnings()).toMatchInlineSnapshot(`
2584
+ "Processing wrangler configuration:
2585
+ - \\"unsafe\\" fields are experimental and may change or break at any time."
2586
+ `);
2587
+ expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
2588
+ "Processing wrangler configuration:
2589
+ - The field \\"unsafe.metadata\\" should be an object but got 999."
2590
+ `);
2591
+ });
2592
+
2593
+ it("should error if unsafe.metadata is null", () => {
2594
+ const { diagnostics } = normalizeAndValidateConfig(
2595
+ { unsafe: { metadata: null } } as unknown as RawConfig,
2596
+ undefined,
2597
+ { env: undefined }
2598
+ );
2599
+
2600
+ expect(diagnostics.renderWarnings()).toMatchInlineSnapshot(`
2601
+ "Processing wrangler configuration:
2602
+ - \\"unsafe\\" fields are experimental and may change or break at any time."
2603
+ `);
2604
+ expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
2605
+ "Processing wrangler configuration:
2606
+ - The field \\"unsafe.metadata\\" should be an object but got null."
2607
+ `);
2608
+ });
2319
2609
  });
2320
2610
 
2321
2611
  describe("(deprecated)", () => {
@@ -2697,13 +2987,19 @@ describe("normalizeAndValidateConfig()", () => {
2697
2987
  };
2698
2988
  const kv_namespaces: RawConfig["kv_namespaces"] = [];
2699
2989
  const r2_buckets: RawConfig["r2_buckets"] = [];
2700
- const unsafe: RawConfig["unsafe"] = { bindings: [] };
2990
+ const analytics_engine_datasets: RawConfig["analytics_engine_datasets"] =
2991
+ [];
2992
+ const unsafe: RawConfig["unsafe"] = {
2993
+ bindings: undefined,
2994
+ metadata: undefined,
2995
+ };
2701
2996
  const rawConfig: RawConfig = {
2702
2997
  define,
2703
2998
  vars,
2704
2999
  durable_objects,
2705
3000
  kv_namespaces,
2706
3001
  r2_buckets,
3002
+ analytics_engine_datasets,
2707
3003
  unsafe,
2708
3004
  env: {
2709
3005
  ENV1: {},
@@ -2723,6 +3019,7 @@ describe("normalizeAndValidateConfig()", () => {
2723
3019
  durable_objects,
2724
3020
  kv_namespaces,
2725
3021
  r2_buckets,
3022
+ analytics_engine_datasets,
2726
3023
  unsafe,
2727
3024
  })
2728
3025
  );
@@ -2746,6 +3043,9 @@ describe("normalizeAndValidateConfig()", () => {
2746
3043
  - \\"r2_buckets\\" exists at the top level, but not on \\"env.ENV1\\".
2747
3044
  This is not what you probably want, since \\"r2_buckets\\" is not inherited by environments.
2748
3045
  Please add \\"r2_buckets\\" to \\"env.ENV1\\".
3046
+ - \\"analytics_engine_datasets\\" exists at the top level, but not on \\"env.ENV1\\".
3047
+ This is not what you probably want, since \\"analytics_engine_datasets\\" is not inherited by environments.
3048
+ Please add \\"analytics_engine_datasets\\" to \\"env.ENV1\\".
2749
3049
  - \\"unsafe\\" exists at the top level, but not on \\"env.ENV1\\".
2750
3050
  This is not what you probably want, since \\"unsafe\\" is not inherited by environments.
2751
3051
  Please add \\"unsafe\\" to \\"env.ENV1\\"."
@@ -3447,6 +3747,114 @@ describe("normalizeAndValidateConfig()", () => {
3447
3747
  });
3448
3748
  });
3449
3749
 
3750
+ describe("[analytics_engine_datasets]", () => {
3751
+ it("should error if analytics_engine_datasets is an object", () => {
3752
+ const { diagnostics } = normalizeAndValidateConfig(
3753
+ {
3754
+ env: { ENV1: { analytics_engine_datasets: {} } },
3755
+ } as unknown as RawConfig,
3756
+ undefined,
3757
+ { env: "ENV1" }
3758
+ );
3759
+
3760
+ expect(diagnostics.hasWarnings()).toBe(false);
3761
+ expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
3762
+ "Processing wrangler configuration:
3763
+
3764
+ - \\"env.ENV1\\" environment configuration
3765
+ - The field \\"env.ENV1.analytics_engine_datasets\\" should be an array but got {}."
3766
+ `);
3767
+ });
3768
+
3769
+ it("should error if analytics_engine_datasets is a string", () => {
3770
+ const { diagnostics } = normalizeAndValidateConfig(
3771
+ {
3772
+ env: { ENV1: { analytics_engine_datasets: "BAD" } },
3773
+ } as unknown as RawConfig,
3774
+ undefined,
3775
+ { env: "ENV1" }
3776
+ );
3777
+
3778
+ expect(diagnostics.hasWarnings()).toBe(false);
3779
+ expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
3780
+ "Processing wrangler configuration:
3781
+
3782
+ - \\"env.ENV1\\" environment configuration
3783
+ - The field \\"env.ENV1.analytics_engine_datasets\\" should be an array but got \\"BAD\\"."
3784
+ `);
3785
+ });
3786
+
3787
+ it("should error if analytics_engine_datasets is a number", () => {
3788
+ const { diagnostics } = normalizeAndValidateConfig(
3789
+ {
3790
+ env: { ENV1: { analytics_engine_datasets: 999 } },
3791
+ } as unknown as RawConfig,
3792
+ undefined,
3793
+ { env: "ENV1" }
3794
+ );
3795
+
3796
+ expect(diagnostics.hasWarnings()).toBe(false);
3797
+ expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
3798
+ "Processing wrangler configuration:
3799
+
3800
+ - \\"env.ENV1\\" environment configuration
3801
+ - The field \\"env.ENV1.analytics_engine_datasets\\" should be an array but got 999."
3802
+ `);
3803
+ });
3804
+
3805
+ it("should error if analytics_engine_datasets is null", () => {
3806
+ const { diagnostics } = normalizeAndValidateConfig(
3807
+ {
3808
+ env: { ENV1: { analytics_engine_datasets: null } },
3809
+ } as unknown as RawConfig,
3810
+ undefined,
3811
+ { env: "ENV1" }
3812
+ );
3813
+
3814
+ expect(diagnostics.hasWarnings()).toBe(false);
3815
+ expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
3816
+ "Processing wrangler configuration:
3817
+
3818
+ - \\"env.ENV1\\" environment configuration
3819
+ - The field \\"env.ENV1.analytics_engine_datasets\\" should be an array but got null."
3820
+ `);
3821
+ });
3822
+
3823
+ it("should error if analytics_engine_datasets.bindings are not valid", () => {
3824
+ const { diagnostics } = normalizeAndValidateConfig(
3825
+ {
3826
+ env: {
3827
+ ENV1: {
3828
+ analytics_engine_datasets: [
3829
+ {},
3830
+ { binding: 2333, dataset: 2444 },
3831
+ {
3832
+ binding: "AE_BINDING_2",
3833
+ dataset: 2555,
3834
+ },
3835
+ { binding: "AE_BINDING_1", dataset: "" },
3836
+ ],
3837
+ },
3838
+ },
3839
+ } as unknown as RawConfig,
3840
+ undefined,
3841
+ { env: "ENV1" }
3842
+ );
3843
+
3844
+ expect(diagnostics.hasWarnings()).toBe(false);
3845
+ expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
3846
+ "Processing wrangler configuration:
3847
+
3848
+ - \\"env.ENV1\\" environment configuration
3849
+ - \\"env.ENV1.analytics_engine_datasets[0]\\" bindings should have a string \\"binding\\" field but got {}.
3850
+ - \\"env.ENV1.analytics_engine_datasets[1]\\" bindings should have a string \\"binding\\" field but got {\\"binding\\":2333,\\"dataset\\":2444}.
3851
+ - \\"env.ENV1.analytics_engine_datasets[1]\\" bindings should, optionally, have a string \\"dataset\\" field but got {\\"binding\\":2333,\\"dataset\\":2444}.
3852
+ - \\"env.ENV1.analytics_engine_datasets[2]\\" bindings should, optionally, have a string \\"dataset\\" field but got {\\"binding\\":\\"AE_BINDING_2\\",\\"dataset\\":2555}.
3853
+ - \\"env.ENV1.analytics_engine_datasets[3]\\" bindings should, optionally, have a string \\"dataset\\" field but got {\\"binding\\":\\"AE_BINDING_1\\",\\"dataset\\":\\"\\"}."
3854
+ `);
3855
+ });
3856
+ });
3857
+
3450
3858
  describe("[unsafe.bindings]", () => {
3451
3859
  it("should error if unsafe is an array", () => {
3452
3860
  const { diagnostics } = normalizeAndValidateConfig(
@@ -3532,7 +3940,7 @@ describe("normalizeAndValidateConfig()", () => {
3532
3940
  `);
3533
3941
  });
3534
3942
 
3535
- it("should error if unsafe.bindings is not defined", () => {
3943
+ it("should error if neither unsafe.bindings nor unsafe.metadata are defined", () => {
3536
3944
  const { diagnostics } = normalizeAndValidateConfig(
3537
3945
  { env: { ENV1: { unsafe: {} } } } as unknown as RawConfig,
3538
3946
  undefined,
@@ -3546,11 +3954,47 @@ describe("normalizeAndValidateConfig()", () => {
3546
3954
  - \\"unsafe\\" fields are experimental and may change or break at any time."
3547
3955
  `);
3548
3956
  expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
3957
+ "Processing wrangler configuration:
3958
+
3959
+ - \\"env.ENV1\\" environment configuration
3960
+ - The field \\"env.ENV1.unsafe\\" should contain at least one of \\"bindings\\" or \\"metadata\\" properties but got {}."
3961
+ `);
3962
+ });
3963
+
3964
+ it("should not error if at least unsafe.bindings is undefined", () => {
3965
+ const { diagnostics } = normalizeAndValidateConfig(
3966
+ {
3967
+ env: { ENV1: { unsafe: { bindings: [] } } },
3968
+ } as unknown as RawConfig,
3969
+ undefined,
3970
+ { env: "ENV1" }
3971
+ );
3972
+
3973
+ expect(diagnostics.renderWarnings()).toMatchInlineSnapshot(`
3549
3974
  "Processing wrangler configuration:
3550
3975
 
3551
3976
  - \\"env.ENV1\\" environment configuration
3552
- - The field \\"env.ENV1.unsafe\\" is missing the required \\"bindings\\" property."
3977
+ - \\"unsafe\\" fields are experimental and may change or break at any time."
3553
3978
  `);
3979
+ expect(diagnostics.hasErrors()).toBe(false);
3980
+ });
3981
+
3982
+ it("should not error if at least unsafe.metadata is undefined", () => {
3983
+ const { diagnostics } = normalizeAndValidateConfig(
3984
+ {
3985
+ env: { ENV1: { unsafe: { metadata: {} } } },
3986
+ } as unknown as RawConfig,
3987
+ undefined,
3988
+ { env: "ENV1" }
3989
+ );
3990
+
3991
+ expect(diagnostics.renderWarnings()).toMatchInlineSnapshot(`
3992
+ "Processing wrangler configuration:
3993
+
3994
+ - \\"env.ENV1\\" environment configuration
3995
+ - \\"unsafe\\" fields are experimental and may change or break at any time."
3996
+ `);
3997
+ expect(diagnostics.hasErrors()).toBe(false);
3554
3998
  });
3555
3999
 
3556
4000
  it("should error if unsafe.bindings is an object", () => {
@@ -3692,6 +4136,98 @@ describe("normalizeAndValidateConfig()", () => {
3692
4136
  - binding should have a string \\"type\\" field."
3693
4137
  `);
3694
4138
  });
4139
+
4140
+ it("should error if unsafe.metadata is an array", () => {
4141
+ const { diagnostics } = normalizeAndValidateConfig(
4142
+ {
4143
+ env: { ENV1: { unsafe: { metadata: [] } } },
4144
+ } as unknown as RawConfig,
4145
+ undefined,
4146
+ { env: "ENV1" }
4147
+ );
4148
+
4149
+ expect(diagnostics.renderWarnings()).toMatchInlineSnapshot(`
4150
+ "Processing wrangler configuration:
4151
+
4152
+ - \\"env.ENV1\\" environment configuration
4153
+ - \\"unsafe\\" fields are experimental and may change or break at any time."
4154
+ `);
4155
+ expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
4156
+ "Processing wrangler configuration:
4157
+
4158
+ - \\"env.ENV1\\" environment configuration
4159
+ - The field \\"env.ENV1.unsafe.metadata\\" should be an object but got []."
4160
+ `);
4161
+ });
4162
+
4163
+ it("should error if unsafe.metadata is a string", () => {
4164
+ const { diagnostics } = normalizeAndValidateConfig(
4165
+ {
4166
+ env: { ENV1: { unsafe: { metadata: "BAD" } } },
4167
+ } as unknown as RawConfig,
4168
+ undefined,
4169
+ { env: "ENV1" }
4170
+ );
4171
+
4172
+ expect(diagnostics.renderWarnings()).toMatchInlineSnapshot(`
4173
+ "Processing wrangler configuration:
4174
+
4175
+ - \\"env.ENV1\\" environment configuration
4176
+ - \\"unsafe\\" fields are experimental and may change or break at any time."
4177
+ `);
4178
+ expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
4179
+ "Processing wrangler configuration:
4180
+
4181
+ - \\"env.ENV1\\" environment configuration
4182
+ - The field \\"env.ENV1.unsafe.metadata\\" should be an object but got \\"BAD\\"."
4183
+ `);
4184
+ });
4185
+
4186
+ it("should error if unsafe.metadata is a number", () => {
4187
+ const { diagnostics } = normalizeAndValidateConfig(
4188
+ {
4189
+ env: { ENV1: { unsafe: { metadata: 999 } } },
4190
+ } as unknown as RawConfig,
4191
+ undefined,
4192
+ { env: "ENV1" }
4193
+ );
4194
+
4195
+ expect(diagnostics.renderWarnings()).toMatchInlineSnapshot(`
4196
+ "Processing wrangler configuration:
4197
+
4198
+ - \\"env.ENV1\\" environment configuration
4199
+ - \\"unsafe\\" fields are experimental and may change or break at any time."
4200
+ `);
4201
+ expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
4202
+ "Processing wrangler configuration:
4203
+
4204
+ - \\"env.ENV1\\" environment configuration
4205
+ - The field \\"env.ENV1.unsafe.metadata\\" should be an object but got 999."
4206
+ `);
4207
+ });
4208
+
4209
+ it("should error if unsafe.metadata is null", () => {
4210
+ const { diagnostics } = normalizeAndValidateConfig(
4211
+ {
4212
+ env: { ENV1: { unsafe: { metadata: null } } },
4213
+ } as unknown as RawConfig,
4214
+ undefined,
4215
+ { env: "ENV1" }
4216
+ );
4217
+
4218
+ expect(diagnostics.renderWarnings()).toMatchInlineSnapshot(`
4219
+ "Processing wrangler configuration:
4220
+
4221
+ - \\"env.ENV1\\" environment configuration
4222
+ - \\"unsafe\\" fields are experimental and may change or break at any time."
4223
+ `);
4224
+ expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
4225
+ "Processing wrangler configuration:
4226
+
4227
+ - \\"env.ENV1\\" environment configuration
4228
+ - The field \\"env.ENV1.unsafe.metadata\\" should be an object but got null."
4229
+ `);
4230
+ });
3695
4231
  });
3696
4232
 
3697
4233
  describe("(deprecated)", () => {