wrangler 0.0.0-e30d1013 → 0.0.0-e311bbbf

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 (236) 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 +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 +567 -39
  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 -52
  15. package/src/__tests__/dev.test.tsx +198 -90
  16. package/src/__tests__/generate.test.ts +8 -5
  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 +127 -26
  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 +1620 -830
  61. package/src/__tests__/pubsub.test.ts +226 -100
  62. package/src/__tests__/queues.test.ts +237 -76
  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 +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 +11 -2
  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 +221 -128
  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 +73 -16
  87. package/src/config/index.ts +99 -30
  88. package/src/config/validation-helpers.ts +1 -1
  89. package/src/config/validation.ts +248 -9
  90. package/src/create-worker-preview.ts +19 -8
  91. package/src/create-worker-upload-form.ts +48 -5
  92. package/src/d1/backups.tsx +43 -42
  93. package/src/d1/create.tsx +26 -21
  94. package/src/d1/{delete.tsx → delete.ts} +11 -14
  95. package/src/d1/execute.tsx +183 -170
  96. package/src/d1/index.ts +7 -6
  97. package/src/d1/list.tsx +22 -10
  98. package/src/d1/migrations/apply.tsx +212 -0
  99. package/src/d1/migrations/create.tsx +79 -0
  100. package/src/d1/migrations/helpers.ts +172 -0
  101. package/src/d1/migrations/index.ts +3 -0
  102. package/src/d1/migrations/list.tsx +95 -0
  103. package/src/d1/migrations/options.ts +23 -0
  104. package/src/d1/options.ts +3 -3
  105. package/src/d1/splitter.ts +161 -0
  106. package/src/d1/{types.tsx → types.ts} +1 -0
  107. package/src/d1/utils.ts +2 -1
  108. package/src/delete.ts +8 -16
  109. package/src/deployments.ts +333 -42
  110. package/src/deprecated/index.ts +8 -302
  111. package/src/dev/dev.tsx +57 -44
  112. package/src/dev/local.tsx +248 -74
  113. package/src/dev/remote.tsx +32 -3
  114. package/src/dev/start-server.ts +81 -66
  115. package/src/dev/use-esbuild.ts +17 -18
  116. package/src/dev/validate-dev-props.ts +9 -0
  117. package/src/{dev-registry.tsx → dev-registry.ts} +2 -1
  118. package/src/dev.tsx +178 -117
  119. package/src/dialogs.ts +136 -0
  120. package/src/dispatch-namespace.ts +21 -17
  121. package/src/docs/index.ts +97 -0
  122. package/src/entry.ts +19 -11
  123. package/src/environment-variables/factory.ts +88 -0
  124. package/src/environment-variables/misc-variables.ts +30 -0
  125. package/src/generate/index.ts +298 -0
  126. package/src/git-client.ts +15 -4
  127. package/src/{index.tsx → index.ts} +134 -59
  128. package/src/init.ts +249 -187
  129. package/src/inspect.ts +16 -1
  130. package/src/jest.d.ts +4 -0
  131. package/src/kv/index.ts +15 -17
  132. package/src/logger.ts +32 -5
  133. package/src/metrics/metrics-config.ts +3 -3
  134. package/src/metrics/send-event.ts +6 -1
  135. package/src/miniflare-cli/assets.ts +64 -28
  136. package/src/miniflare-cli/index.ts +4 -7
  137. package/src/miniflare-cli/tsconfig.json +9 -0
  138. package/src/miniflare-cli/tsconfig.tsbuildinfo +1 -0
  139. package/src/miniflare-cli/types.ts +11 -0
  140. package/src/module-collection.ts +91 -25
  141. package/src/mtls-certificate/cli.ts +155 -0
  142. package/src/pages/build.ts +410 -0
  143. package/src/pages/buildFunctions.ts +140 -0
  144. package/src/pages/deployment-tails.ts +281 -0
  145. package/src/pages/deployments.tsx +11 -33
  146. package/src/pages/{dev.tsx → dev.ts} +147 -139
  147. package/src/pages/errors.ts +1 -0
  148. package/src/pages/functions/buildPlugin.ts +61 -54
  149. package/src/pages/functions/buildWorker.ts +159 -33
  150. package/src/pages/functions/tsconfig.json +8 -0
  151. package/src/pages/functions/tsconfig.tsbuildinfo +1 -0
  152. package/src/pages/{functions.tsx → functions.ts} +8 -4
  153. package/src/pages/{index.tsx → index.ts} +11 -3
  154. package/src/pages/projects.tsx +12 -22
  155. package/src/pages/prompt-select-project.tsx +31 -0
  156. package/src/pages/publish.tsx +46 -225
  157. package/src/pages/types.ts +6 -9
  158. package/src/pages/upload.tsx +58 -14
  159. package/src/pages/utils.ts +12 -1
  160. package/src/parse.ts +23 -1
  161. package/src/paths.ts +1 -1
  162. package/src/proxy.ts +5 -0
  163. package/src/publish/index.ts +20 -16
  164. package/src/publish/publish.ts +71 -46
  165. package/src/pubsub/{pubsub-commands.tsx → pubsub-commands.ts} +19 -20
  166. package/src/queues/cli/commands/consumer/add.ts +24 -24
  167. package/src/queues/cli/commands/consumer/index.ts +3 -6
  168. package/src/queues/cli/commands/consumer/remove.ts +11 -18
  169. package/src/queues/cli/commands/create.ts +8 -8
  170. package/src/queues/cli/commands/delete.ts +8 -8
  171. package/src/queues/cli/commands/index.ts +6 -4
  172. package/src/queues/cli/commands/list.ts +8 -8
  173. package/src/queues/client.ts +1 -0
  174. package/src/queues/utils.ts +18 -0
  175. package/src/r2/helpers.ts +1 -0
  176. package/src/r2/index.ts +28 -28
  177. package/src/secret/index.ts +14 -16
  178. package/src/{sites.tsx → sites.ts} +1 -1
  179. package/src/tail/createTail.ts +94 -3
  180. package/src/tail/filters.ts +1 -1
  181. package/src/tail/index.ts +8 -11
  182. package/src/tail/printing.ts +15 -0
  183. package/src/traverse-module-graph.ts +53 -0
  184. package/src/tsconfig-sanity.ts +16 -0
  185. package/src/type-generation.ts +28 -20
  186. package/src/user/access.ts +0 -1
  187. package/src/user/auth-variables.ts +113 -0
  188. package/src/user/choose-account.tsx +1 -31
  189. package/src/user/index.ts +0 -1
  190. package/src/user/{user.tsx → user.ts} +123 -82
  191. package/src/utils/render.ts +93 -0
  192. package/src/{whoami.tsx → whoami.ts} +37 -71
  193. package/src/worker.ts +30 -1
  194. package/src/yargs-types.ts +22 -5
  195. package/templates/__tests__/tsconfig-sanity.ts +12 -0
  196. package/templates/__tests__/tsconfig.json +8 -0
  197. package/templates/__tests__/tsconfig.tsbuildinfo +1 -0
  198. package/templates/checked-fetch.js +9 -3
  199. package/templates/d1-beta-facade.js +51 -3
  200. package/templates/facade.d.ts +14 -0
  201. package/templates/first-party-worker-module-facade.ts +4 -3
  202. package/templates/format-dev-errors.ts +8 -6
  203. package/templates/gitignore +1 -0
  204. package/templates/init-tests/test-jest-new-worker.js +3 -5
  205. package/templates/init-tests/test-vitest-new-worker.js +3 -5
  206. package/templates/init-tests/test-vitest-new-worker.ts +25 -0
  207. package/templates/middleware/loader-modules.ts +2 -2
  208. package/templates/middleware/loader-sw.ts +51 -31
  209. package/templates/middleware/middleware-miniflare3-json-error.ts +32 -0
  210. package/templates/new-worker.ts +3 -0
  211. package/templates/pages-dev-pipeline.ts +4 -1
  212. package/templates/pages-shim.ts +4 -1
  213. package/templates/pages-template-plugin.ts +19 -10
  214. package/templates/serve-static-assets.ts +17 -14
  215. package/templates/service-bindings-module-facade.js +1 -0
  216. package/templates/tsconfig-sanity.ts +11 -0
  217. package/templates/tsconfig.init.json +105 -0
  218. package/templates/tsconfig.json +5 -103
  219. package/templates/tsconfig.tsbuildinfo +1 -0
  220. package/wrangler-dist/cli.d.ts +820 -70
  221. package/wrangler-dist/cli.js +68161 -78780
  222. package/wrangler-dist/wasm-sync.wasm +0 -0
  223. package/src/__tests__/api-devregistry.test.js +0 -56
  224. package/src/__tests__/d1.test.ts +0 -74
  225. package/src/__tests__/dialogs.test.tsx +0 -40
  226. package/src/__tests__/helpers/mock-cfetch.ts +0 -333
  227. package/src/__tests__/pages.test.ts +0 -2387
  228. package/src/d1/migrations.tsx +0 -446
  229. package/src/dialogs.tsx +0 -169
  230. package/src/environment-variables.ts +0 -50
  231. package/src/pages/build.tsx +0 -270
  232. package/src/user/env-vars.ts +0 -46
  233. package/templates/experimental-local-cache-stubs.js +0 -27
  234. /package/src/{bundle-reporter.tsx → bundle-reporter.ts} +0 -0
  235. /package/src/dev/{get-local-persistence-path.tsx → get-local-persistence-path.ts} +0 -0
  236. /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: {},
@@ -900,6 +904,17 @@ describe("normalizeAndValidateConfig()", () => {
900
904
  preview_id: "KV_PREVIEW_1",
901
905
  },
902
906
  ],
907
+ send_email: [
908
+ { name: "SEB_TARGET", destination_address: "teste@example.com" },
909
+ { name: "SEB_UNRESTRICTED" },
910
+ {
911
+ name: "SEB_ALLOWLIST",
912
+ allowed_destination_addresses: [
913
+ "email1@example.com",
914
+ "email2@example.com",
915
+ ],
916
+ },
917
+ ],
903
918
  r2_buckets: [
904
919
  { binding: "R2_BINDING_1", bucket_name: "R2_BUCKET_1" },
905
920
  {
@@ -915,6 +930,15 @@ describe("normalizeAndValidateConfig()", () => {
915
930
  environment: "SERVICE_BINDING_ENVIRONMENT_1",
916
931
  },
917
932
  ],
933
+ analytics_engine_datasets: [
934
+ {
935
+ binding: "AE_BINDING_1",
936
+ dataset: "DATASET_1",
937
+ },
938
+ {
939
+ binding: "AE_BINDING_2",
940
+ },
941
+ ],
918
942
  unsafe: {
919
943
  bindings: [
920
944
  { name: "UNSAFE_BINDING_1", type: "UNSAFE_TYPE_1" },
@@ -924,6 +948,7 @@ describe("normalizeAndValidateConfig()", () => {
924
948
  extra: "UNSAFE_EXTRA_1",
925
949
  },
926
950
  ],
951
+ metadata: undefined,
927
952
  },
928
953
  no_bundle: true,
929
954
  minify: true,
@@ -1616,6 +1641,39 @@ describe("normalizeAndValidateConfig()", () => {
1616
1641
  });
1617
1642
  });
1618
1643
 
1644
+ it("should error if send_email.bindings are not valid", () => {
1645
+ const { diagnostics } = normalizeAndValidateConfig(
1646
+ {
1647
+ send_email: [
1648
+ {},
1649
+ { binding: "VALID" },
1650
+ { name: "SEB", destination_address: 123 },
1651
+ {
1652
+ name: "SEB2",
1653
+ allowed_destination_addresses: 123,
1654
+ },
1655
+ {
1656
+ name: "SEB3",
1657
+ destination_address: "email@example.com",
1658
+ allowed_destination_addresses: ["email@example.com"],
1659
+ },
1660
+ ],
1661
+ } as unknown as RawConfig,
1662
+ undefined,
1663
+ { env: undefined }
1664
+ );
1665
+
1666
+ expect(diagnostics.hasWarnings()).toBe(false);
1667
+ expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
1668
+ "Processing wrangler configuration:
1669
+ - \\"send_email[0]\\" bindings should have a string \\"name\\" field but got {}.
1670
+ - \\"send_email[1]\\" bindings should have a string \\"name\\" field but got {\\"binding\\":\\"VALID\\"}.
1671
+ - \\"send_email[2]\\" bindings should, optionally, have a string \\"destination_address\\" field but got {\\"name\\":\\"SEB\\",\\"destination_address\\":123}.
1672
+ - \\"send_email[3]\\" bindings should, optionally, have a []string \\"allowed_destination_addresses\\" field but got {\\"name\\":\\"SEB2\\",\\"allowed_destination_addresses\\":123}.
1673
+ - \\"send_email[4]\\" bindings should have either a \\"destination_address\\" or \\"allowed_destination_addresses\\" field, but not both."
1674
+ `);
1675
+ });
1676
+
1619
1677
  describe("[d1_databases]", () => {
1620
1678
  it("should error if d1_databases is an object", () => {
1621
1679
  const { diagnostics } = normalizeAndValidateConfig(
@@ -1778,6 +1836,7 @@ describe("normalizeAndValidateConfig()", () => {
1778
1836
  max_batch_timeout: null,
1779
1837
  max_retries: "hello",
1780
1838
  dead_letter_queue: 5,
1839
+ max_concurrency: "hello",
1781
1840
  },
1782
1841
  ],
1783
1842
  },
@@ -1793,20 +1852,21 @@ describe("normalizeAndValidateConfig()", () => {
1793
1852
  );
1794
1853
  expect(diagnostics.hasWarnings()).toBe(true);
1795
1854
  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
- `);
1855
+ "Processing wrangler configuration:
1856
+ - Unexpected fields found in queues field: \\"invalidField\\"
1857
+ - Unexpected fields found in queues.consumers[2] field: \\"invalidField\\""
1858
+ `);
1800
1859
 
1801
1860
  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
- `);
1861
+ "Processing wrangler configuration:
1862
+ - \\"queues.consumers[0]\\" should have a string \\"queue\\" field but got {}.
1863
+ - \\"queues.consumers[1]\\" should have a string \\"queue\\" field but got {\\"queue\\":22}.
1864
+ - \\"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\\"}.
1865
+ - \\"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\\"}.
1866
+ - \\"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\\"}.
1867
+ - \\"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\\"}.
1868
+ - \\"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\\"}."
1869
+ `);
1810
1870
  });
1811
1871
  });
1812
1872
 
@@ -2028,28 +2088,93 @@ describe("normalizeAndValidateConfig()", () => {
2028
2088
  });
2029
2089
  });
2030
2090
 
2031
- describe("[dispatch_namespaces]", () => {
2032
- it("should log an experimental warning when dispatch_namespaces is used", () => {
2091
+ describe("[analytics_engine_datasets]", () => {
2092
+ it("should error if analytics_engine_datasets is an object", () => {
2093
+ const { diagnostics } = normalizeAndValidateConfig(
2094
+ { analytics_engine_datasets: {} } as unknown as RawConfig,
2095
+ undefined,
2096
+ { env: undefined }
2097
+ );
2098
+
2099
+ expect(diagnostics.hasWarnings()).toBe(false);
2100
+ expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
2101
+ "Processing wrangler configuration:
2102
+ - The field \\"analytics_engine_datasets\\" should be an array but got {}."
2103
+ `);
2104
+ });
2105
+
2106
+ it("should error if analytics_engine_datasets is a string", () => {
2107
+ const { diagnostics } = normalizeAndValidateConfig(
2108
+ { analytics_engine_datasets: "BAD" } as unknown as RawConfig,
2109
+ undefined,
2110
+ { env: undefined }
2111
+ );
2112
+
2113
+ expect(diagnostics.hasWarnings()).toBe(false);
2114
+ expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
2115
+ "Processing wrangler configuration:
2116
+ - The field \\"analytics_engine_datasets\\" should be an array but got \\"BAD\\"."
2117
+ `);
2118
+ });
2119
+
2120
+ it("should error if analytics_engine_datasets is a number", () => {
2121
+ const { diagnostics } = normalizeAndValidateConfig(
2122
+ { analytics_engine_datasets: 999 } as unknown as RawConfig,
2123
+ undefined,
2124
+ { env: undefined }
2125
+ );
2126
+
2127
+ expect(diagnostics.hasWarnings()).toBe(false);
2128
+ expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
2129
+ "Processing wrangler configuration:
2130
+ - The field \\"analytics_engine_datasets\\" should be an array but got 999."
2131
+ `);
2132
+ });
2133
+
2134
+ it("should error if analytics_engine_datasets is null", () => {
2135
+ const { diagnostics } = normalizeAndValidateConfig(
2136
+ { analytics_engine_datasets: null } as unknown as RawConfig,
2137
+ undefined,
2138
+ { env: undefined }
2139
+ );
2140
+
2141
+ expect(diagnostics.hasWarnings()).toBe(false);
2142
+ expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
2143
+ "Processing wrangler configuration:
2144
+ - The field \\"analytics_engine_datasets\\" should be an array but got null."
2145
+ `);
2146
+ });
2147
+
2148
+ it("should error if analytics_engine_datasets.bindings are not valid", () => {
2033
2149
  const { diagnostics } = normalizeAndValidateConfig(
2034
2150
  {
2035
- dispatch_namespaces: [
2151
+ analytics_engine_datasets: [
2152
+ {},
2153
+ { binding: 2333, dataset: 2444 },
2036
2154
  {
2037
- binding: "BINDING_1",
2038
- namespace: "NAMESPACE_1",
2155
+ binding: "AE_BINDING_2",
2156
+ dataset: 2555,
2039
2157
  },
2158
+ { binding: "AE_BINDING_1", dataset: "" },
2040
2159
  ],
2041
2160
  } as unknown as RawConfig,
2042
2161
  undefined,
2043
2162
  { env: undefined }
2044
2163
  );
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
- `);
2164
+
2165
+ expect(diagnostics.hasWarnings()).toBe(false);
2166
+ expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
2167
+ "Processing wrangler configuration:
2168
+ - \\"analytics_engine_datasets[0]\\" bindings should have a string \\"binding\\" field but got {}.
2169
+ - \\"analytics_engine_datasets[1]\\" bindings should have a string \\"binding\\" field but got {\\"binding\\":2333,\\"dataset\\":2444}.
2170
+ - \\"analytics_engine_datasets[1]\\" bindings should, optionally, have a string \\"dataset\\" field but got {\\"binding\\":2333,\\"dataset\\":2444}.
2171
+ - \\"analytics_engine_datasets[2]\\" bindings should, optionally, have a string \\"dataset\\" field but got {\\"binding\\":\\"AE_BINDING_2\\",\\"dataset\\":2555}.
2172
+ - \\"analytics_engine_datasets[3]\\" bindings should, optionally, have a string \\"dataset\\" field but got {\\"binding\\":\\"AE_BINDING_1\\",\\"dataset\\":\\"\\"}."
2173
+ `);
2051
2174
  });
2175
+ });
2052
2176
 
2177
+ describe("[dispatch_namespaces]", () => {
2053
2178
  it("should error if dispatch_namespaces is not an array", () => {
2054
2179
  const { diagnostics } = normalizeAndValidateConfig(
2055
2180
  {
@@ -2059,12 +2184,8 @@ describe("normalizeAndValidateConfig()", () => {
2059
2184
  { env: undefined }
2060
2185
  );
2061
2186
 
2062
- expect(diagnostics.hasWarnings()).toBe(true);
2187
+ expect(diagnostics.hasWarnings()).toBe(false);
2063
2188
  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
2189
  expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
2069
2190
  "Processing wrangler configuration:
2070
2191
  - The field \\"dispatch_namespaces\\" should be an array but got \\"just a string\\"."
@@ -2103,12 +2224,8 @@ describe("normalizeAndValidateConfig()", () => {
2103
2224
  undefined,
2104
2225
  { env: undefined }
2105
2226
  );
2106
- expect(diagnostics.hasWarnings()).toBe(true);
2227
+ expect(diagnostics.hasWarnings()).toBe(false);
2107
2228
  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
2229
  expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
2113
2230
  "Processing wrangler configuration:
2114
2231
  - \\"dispatch_namespaces[0]\\" binding should be objects, but got \\"a string\\"
@@ -2123,6 +2240,75 @@ describe("normalizeAndValidateConfig()", () => {
2123
2240
  });
2124
2241
  });
2125
2242
 
2243
+ describe("[mtls_certificates]", () => {
2244
+ it("should error if mtls_certificates is not an array", () => {
2245
+ const { diagnostics } = normalizeAndValidateConfig(
2246
+ {
2247
+ mtls_certificates: "just a string",
2248
+ } as unknown as RawConfig,
2249
+ undefined,
2250
+ { env: undefined }
2251
+ );
2252
+
2253
+ expect(diagnostics.hasWarnings()).toBe(false);
2254
+ expect(diagnostics.hasErrors()).toBe(true);
2255
+ expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
2256
+ "Processing wrangler configuration:
2257
+ - The field \\"mtls_certificates\\" should be an array but got \\"just a string\\"."
2258
+ `);
2259
+ });
2260
+
2261
+ it("should error on non valid mtls_certificates", () => {
2262
+ const { diagnostics } = normalizeAndValidateConfig(
2263
+ {
2264
+ mtls_certificates: [
2265
+ "a string",
2266
+ 123,
2267
+ false,
2268
+ {
2269
+ binding: 123,
2270
+ namespace: 123,
2271
+ },
2272
+ {
2273
+ binding: "CERT_ONE",
2274
+ id: "1234",
2275
+ },
2276
+ {
2277
+ binding: "CERT_TWO",
2278
+ certificate_id: 1234,
2279
+ },
2280
+ // this one is valid
2281
+ {
2282
+ binding: "CERT_THREE",
2283
+ certificate_id: "1234",
2284
+ },
2285
+ {
2286
+ binding: true,
2287
+ service: "1234",
2288
+ },
2289
+ ],
2290
+ } as unknown as RawConfig,
2291
+ undefined,
2292
+ { env: undefined }
2293
+ );
2294
+
2295
+ expect(diagnostics.hasWarnings()).toBe(false);
2296
+ expect(diagnostics.hasErrors()).toBe(true);
2297
+ expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
2298
+ "Processing wrangler configuration:
2299
+ - \\"mtls_certificates\\" bindings should be objects, but got \\"a string\\"
2300
+ - \\"mtls_certificates\\" bindings should be objects, but got 123
2301
+ - \\"mtls_certificates\\" bindings should be objects, but got false
2302
+ - \\"mtls_certificates[3]\\" bindings should have a string \\"binding\\" field but got {\\"binding\\":123,\\"namespace\\":123}.
2303
+ - \\"mtls_certificates[3]\\" bindings should have a string \\"certificate_id\\" field but got {\\"binding\\":123,\\"namespace\\":123}.
2304
+ - \\"mtls_certificates[4]\\" bindings should have a string \\"certificate_id\\" field but got {\\"binding\\":\\"CERT_ONE\\",\\"id\\":\\"1234\\"}.
2305
+ - \\"mtls_certificates[5]\\" bindings should have a string \\"certificate_id\\" field but got {\\"binding\\":\\"CERT_TWO\\",\\"certificate_id\\":1234}.
2306
+ - \\"mtls_certificates[7]\\" bindings should have a string \\"binding\\" field but got {\\"binding\\":true,\\"service\\":\\"1234\\"}.
2307
+ - \\"mtls_certificates[7]\\" bindings should have a string \\"certificate_id\\" field but got {\\"binding\\":true,\\"service\\":\\"1234\\"}."
2308
+ `);
2309
+ });
2310
+ });
2311
+
2126
2312
  describe("[unsafe.bindings]", () => {
2127
2313
  it("should error if unsafe is an array", () => {
2128
2314
  const { diagnostics } = normalizeAndValidateConfig(
@@ -2192,7 +2378,7 @@ describe("normalizeAndValidateConfig()", () => {
2192
2378
  `);
2193
2379
  });
2194
2380
 
2195
- it("should error if unsafe.bindings is not defined", () => {
2381
+ it("should error if neither unsafe.bindings nor unsafe.metadata are defined", () => {
2196
2382
  const { diagnostics } = normalizeAndValidateConfig(
2197
2383
  { unsafe: {} } as unknown as RawConfig,
2198
2384
  undefined,
@@ -2204,9 +2390,37 @@ describe("normalizeAndValidateConfig()", () => {
2204
2390
  - \\"unsafe\\" fields are experimental and may change or break at any time."
2205
2391
  `);
2206
2392
  expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
2393
+ "Processing wrangler configuration:
2394
+ - The field \\"unsafe\\" should contain at least one of \\"bindings\\" or \\"metadata\\" properties but got {}."
2395
+ `);
2396
+ });
2397
+
2398
+ it("should not error if at least unsafe.bindings is defined", () => {
2399
+ const { diagnostics } = normalizeAndValidateConfig(
2400
+ { unsafe: { bindings: [] } } as unknown as RawConfig,
2401
+ undefined,
2402
+ { env: undefined }
2403
+ );
2404
+
2405
+ expect(diagnostics.renderWarnings()).toMatchInlineSnapshot(`
2406
+ "Processing wrangler configuration:
2407
+ - \\"unsafe\\" fields are experimental and may change or break at any time."
2408
+ `);
2409
+ expect(diagnostics.hasErrors()).toBe(false);
2410
+ });
2411
+
2412
+ it("should not error if at least unsafe.metadata is defined", () => {
2413
+ const { diagnostics } = normalizeAndValidateConfig(
2414
+ { unsafe: { metadata: {} } } as unknown as RawConfig,
2415
+ undefined,
2416
+ { env: undefined }
2417
+ );
2418
+
2419
+ expect(diagnostics.renderWarnings()).toMatchInlineSnapshot(`
2207
2420
  "Processing wrangler configuration:
2208
- - The field \\"unsafe\\" is missing the required \\"bindings\\" property."
2421
+ - \\"unsafe\\" fields are experimental and may change or break at any time."
2209
2422
  `);
2423
+ expect(diagnostics.hasErrors()).toBe(false);
2210
2424
  });
2211
2425
 
2212
2426
  it("should error if unsafe.bindings is an object", () => {
@@ -2316,6 +2530,74 @@ describe("normalizeAndValidateConfig()", () => {
2316
2530
  - binding should have a string \\"type\\" field."
2317
2531
  `);
2318
2532
  });
2533
+
2534
+ it("should error if unsafe.metadata is an array", () => {
2535
+ const { diagnostics } = normalizeAndValidateConfig(
2536
+ { unsafe: { metadata: [] } } as unknown as RawConfig,
2537
+ undefined,
2538
+ { env: undefined }
2539
+ );
2540
+
2541
+ expect(diagnostics.renderWarnings()).toMatchInlineSnapshot(`
2542
+ "Processing wrangler configuration:
2543
+ - \\"unsafe\\" fields are experimental and may change or break at any time."
2544
+ `);
2545
+ expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
2546
+ "Processing wrangler configuration:
2547
+ - The field \\"unsafe.metadata\\" should be an object but got []."
2548
+ `);
2549
+ });
2550
+
2551
+ it("should error if unsafe.metadata is a string", () => {
2552
+ const { diagnostics } = normalizeAndValidateConfig(
2553
+ { unsafe: { metadata: "BAD" } } as unknown as RawConfig,
2554
+ undefined,
2555
+ { env: undefined }
2556
+ );
2557
+
2558
+ expect(diagnostics.renderWarnings()).toMatchInlineSnapshot(`
2559
+ "Processing wrangler configuration:
2560
+ - \\"unsafe\\" fields are experimental and may change or break at any time."
2561
+ `);
2562
+ expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
2563
+ "Processing wrangler configuration:
2564
+ - The field \\"unsafe.metadata\\" should be an object but got \\"BAD\\"."
2565
+ `);
2566
+ });
2567
+
2568
+ it("should error if unsafe.metadata is a number", () => {
2569
+ const { diagnostics } = normalizeAndValidateConfig(
2570
+ { unsafe: { metadata: 999 } } as unknown as RawConfig,
2571
+ undefined,
2572
+ { env: undefined }
2573
+ );
2574
+
2575
+ expect(diagnostics.renderWarnings()).toMatchInlineSnapshot(`
2576
+ "Processing wrangler configuration:
2577
+ - \\"unsafe\\" fields are experimental and may change or break at any time."
2578
+ `);
2579
+ expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
2580
+ "Processing wrangler configuration:
2581
+ - The field \\"unsafe.metadata\\" should be an object but got 999."
2582
+ `);
2583
+ });
2584
+
2585
+ it("should error if unsafe.metadata is null", () => {
2586
+ const { diagnostics } = normalizeAndValidateConfig(
2587
+ { unsafe: { metadata: null } } as unknown as RawConfig,
2588
+ undefined,
2589
+ { env: undefined }
2590
+ );
2591
+
2592
+ expect(diagnostics.renderWarnings()).toMatchInlineSnapshot(`
2593
+ "Processing wrangler configuration:
2594
+ - \\"unsafe\\" fields are experimental and may change or break at any time."
2595
+ `);
2596
+ expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
2597
+ "Processing wrangler configuration:
2598
+ - The field \\"unsafe.metadata\\" should be an object but got null."
2599
+ `);
2600
+ });
2319
2601
  });
2320
2602
 
2321
2603
  describe("(deprecated)", () => {
@@ -2697,13 +2979,19 @@ describe("normalizeAndValidateConfig()", () => {
2697
2979
  };
2698
2980
  const kv_namespaces: RawConfig["kv_namespaces"] = [];
2699
2981
  const r2_buckets: RawConfig["r2_buckets"] = [];
2700
- const unsafe: RawConfig["unsafe"] = { bindings: [] };
2982
+ const analytics_engine_datasets: RawConfig["analytics_engine_datasets"] =
2983
+ [];
2984
+ const unsafe: RawConfig["unsafe"] = {
2985
+ bindings: undefined,
2986
+ metadata: undefined,
2987
+ };
2701
2988
  const rawConfig: RawConfig = {
2702
2989
  define,
2703
2990
  vars,
2704
2991
  durable_objects,
2705
2992
  kv_namespaces,
2706
2993
  r2_buckets,
2994
+ analytics_engine_datasets,
2707
2995
  unsafe,
2708
2996
  env: {
2709
2997
  ENV1: {},
@@ -2723,6 +3011,7 @@ describe("normalizeAndValidateConfig()", () => {
2723
3011
  durable_objects,
2724
3012
  kv_namespaces,
2725
3013
  r2_buckets,
3014
+ analytics_engine_datasets,
2726
3015
  unsafe,
2727
3016
  })
2728
3017
  );
@@ -2746,6 +3035,9 @@ describe("normalizeAndValidateConfig()", () => {
2746
3035
  - \\"r2_buckets\\" exists at the top level, but not on \\"env.ENV1\\".
2747
3036
  This is not what you probably want, since \\"r2_buckets\\" is not inherited by environments.
2748
3037
  Please add \\"r2_buckets\\" to \\"env.ENV1\\".
3038
+ - \\"analytics_engine_datasets\\" exists at the top level, but not on \\"env.ENV1\\".
3039
+ This is not what you probably want, since \\"analytics_engine_datasets\\" is not inherited by environments.
3040
+ Please add \\"analytics_engine_datasets\\" to \\"env.ENV1\\".
2749
3041
  - \\"unsafe\\" exists at the top level, but not on \\"env.ENV1\\".
2750
3042
  This is not what you probably want, since \\"unsafe\\" is not inherited by environments.
2751
3043
  Please add \\"unsafe\\" to \\"env.ENV1\\"."
@@ -3447,6 +3739,114 @@ describe("normalizeAndValidateConfig()", () => {
3447
3739
  });
3448
3740
  });
3449
3741
 
3742
+ describe("[analytics_engine_datasets]", () => {
3743
+ it("should error if analytics_engine_datasets is an object", () => {
3744
+ const { diagnostics } = normalizeAndValidateConfig(
3745
+ {
3746
+ env: { ENV1: { analytics_engine_datasets: {} } },
3747
+ } as unknown as RawConfig,
3748
+ undefined,
3749
+ { env: "ENV1" }
3750
+ );
3751
+
3752
+ expect(diagnostics.hasWarnings()).toBe(false);
3753
+ expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
3754
+ "Processing wrangler configuration:
3755
+
3756
+ - \\"env.ENV1\\" environment configuration
3757
+ - The field \\"env.ENV1.analytics_engine_datasets\\" should be an array but got {}."
3758
+ `);
3759
+ });
3760
+
3761
+ it("should error if analytics_engine_datasets is a string", () => {
3762
+ const { diagnostics } = normalizeAndValidateConfig(
3763
+ {
3764
+ env: { ENV1: { analytics_engine_datasets: "BAD" } },
3765
+ } as unknown as RawConfig,
3766
+ undefined,
3767
+ { env: "ENV1" }
3768
+ );
3769
+
3770
+ expect(diagnostics.hasWarnings()).toBe(false);
3771
+ expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
3772
+ "Processing wrangler configuration:
3773
+
3774
+ - \\"env.ENV1\\" environment configuration
3775
+ - The field \\"env.ENV1.analytics_engine_datasets\\" should be an array but got \\"BAD\\"."
3776
+ `);
3777
+ });
3778
+
3779
+ it("should error if analytics_engine_datasets is a number", () => {
3780
+ const { diagnostics } = normalizeAndValidateConfig(
3781
+ {
3782
+ env: { ENV1: { analytics_engine_datasets: 999 } },
3783
+ } as unknown as RawConfig,
3784
+ undefined,
3785
+ { env: "ENV1" }
3786
+ );
3787
+
3788
+ expect(diagnostics.hasWarnings()).toBe(false);
3789
+ expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
3790
+ "Processing wrangler configuration:
3791
+
3792
+ - \\"env.ENV1\\" environment configuration
3793
+ - The field \\"env.ENV1.analytics_engine_datasets\\" should be an array but got 999."
3794
+ `);
3795
+ });
3796
+
3797
+ it("should error if analytics_engine_datasets is null", () => {
3798
+ const { diagnostics } = normalizeAndValidateConfig(
3799
+ {
3800
+ env: { ENV1: { analytics_engine_datasets: null } },
3801
+ } as unknown as RawConfig,
3802
+ undefined,
3803
+ { env: "ENV1" }
3804
+ );
3805
+
3806
+ expect(diagnostics.hasWarnings()).toBe(false);
3807
+ expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
3808
+ "Processing wrangler configuration:
3809
+
3810
+ - \\"env.ENV1\\" environment configuration
3811
+ - The field \\"env.ENV1.analytics_engine_datasets\\" should be an array but got null."
3812
+ `);
3813
+ });
3814
+
3815
+ it("should error if analytics_engine_datasets.bindings are not valid", () => {
3816
+ const { diagnostics } = normalizeAndValidateConfig(
3817
+ {
3818
+ env: {
3819
+ ENV1: {
3820
+ analytics_engine_datasets: [
3821
+ {},
3822
+ { binding: 2333, dataset: 2444 },
3823
+ {
3824
+ binding: "AE_BINDING_2",
3825
+ dataset: 2555,
3826
+ },
3827
+ { binding: "AE_BINDING_1", dataset: "" },
3828
+ ],
3829
+ },
3830
+ },
3831
+ } as unknown as RawConfig,
3832
+ undefined,
3833
+ { env: "ENV1" }
3834
+ );
3835
+
3836
+ expect(diagnostics.hasWarnings()).toBe(false);
3837
+ expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
3838
+ "Processing wrangler configuration:
3839
+
3840
+ - \\"env.ENV1\\" environment configuration
3841
+ - \\"env.ENV1.analytics_engine_datasets[0]\\" bindings should have a string \\"binding\\" field but got {}.
3842
+ - \\"env.ENV1.analytics_engine_datasets[1]\\" bindings should have a string \\"binding\\" field but got {\\"binding\\":2333,\\"dataset\\":2444}.
3843
+ - \\"env.ENV1.analytics_engine_datasets[1]\\" bindings should, optionally, have a string \\"dataset\\" field but got {\\"binding\\":2333,\\"dataset\\":2444}.
3844
+ - \\"env.ENV1.analytics_engine_datasets[2]\\" bindings should, optionally, have a string \\"dataset\\" field but got {\\"binding\\":\\"AE_BINDING_2\\",\\"dataset\\":2555}.
3845
+ - \\"env.ENV1.analytics_engine_datasets[3]\\" bindings should, optionally, have a string \\"dataset\\" field but got {\\"binding\\":\\"AE_BINDING_1\\",\\"dataset\\":\\"\\"}."
3846
+ `);
3847
+ });
3848
+ });
3849
+
3450
3850
  describe("[unsafe.bindings]", () => {
3451
3851
  it("should error if unsafe is an array", () => {
3452
3852
  const { diagnostics } = normalizeAndValidateConfig(
@@ -3532,7 +3932,7 @@ describe("normalizeAndValidateConfig()", () => {
3532
3932
  `);
3533
3933
  });
3534
3934
 
3535
- it("should error if unsafe.bindings is not defined", () => {
3935
+ it("should error if neither unsafe.bindings nor unsafe.metadata are defined", () => {
3536
3936
  const { diagnostics } = normalizeAndValidateConfig(
3537
3937
  { env: { ENV1: { unsafe: {} } } } as unknown as RawConfig,
3538
3938
  undefined,
@@ -3546,11 +3946,47 @@ describe("normalizeAndValidateConfig()", () => {
3546
3946
  - \\"unsafe\\" fields are experimental and may change or break at any time."
3547
3947
  `);
3548
3948
  expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
3949
+ "Processing wrangler configuration:
3950
+
3951
+ - \\"env.ENV1\\" environment configuration
3952
+ - The field \\"env.ENV1.unsafe\\" should contain at least one of \\"bindings\\" or \\"metadata\\" properties but got {}."
3953
+ `);
3954
+ });
3955
+
3956
+ it("should not error if at least unsafe.bindings is undefined", () => {
3957
+ const { diagnostics } = normalizeAndValidateConfig(
3958
+ {
3959
+ env: { ENV1: { unsafe: { bindings: [] } } },
3960
+ } as unknown as RawConfig,
3961
+ undefined,
3962
+ { env: "ENV1" }
3963
+ );
3964
+
3965
+ expect(diagnostics.renderWarnings()).toMatchInlineSnapshot(`
3549
3966
  "Processing wrangler configuration:
3550
3967
 
3551
3968
  - \\"env.ENV1\\" environment configuration
3552
- - The field \\"env.ENV1.unsafe\\" is missing the required \\"bindings\\" property."
3969
+ - \\"unsafe\\" fields are experimental and may change or break at any time."
3553
3970
  `);
3971
+ expect(diagnostics.hasErrors()).toBe(false);
3972
+ });
3973
+
3974
+ it("should not error if at least unsafe.metadata is undefined", () => {
3975
+ const { diagnostics } = normalizeAndValidateConfig(
3976
+ {
3977
+ env: { ENV1: { unsafe: { metadata: {} } } },
3978
+ } as unknown as RawConfig,
3979
+ undefined,
3980
+ { env: "ENV1" }
3981
+ );
3982
+
3983
+ expect(diagnostics.renderWarnings()).toMatchInlineSnapshot(`
3984
+ "Processing wrangler configuration:
3985
+
3986
+ - \\"env.ENV1\\" environment configuration
3987
+ - \\"unsafe\\" fields are experimental and may change or break at any time."
3988
+ `);
3989
+ expect(diagnostics.hasErrors()).toBe(false);
3554
3990
  });
3555
3991
 
3556
3992
  it("should error if unsafe.bindings is an object", () => {
@@ -3692,6 +4128,98 @@ describe("normalizeAndValidateConfig()", () => {
3692
4128
  - binding should have a string \\"type\\" field."
3693
4129
  `);
3694
4130
  });
4131
+
4132
+ it("should error if unsafe.metadata is an array", () => {
4133
+ const { diagnostics } = normalizeAndValidateConfig(
4134
+ {
4135
+ env: { ENV1: { unsafe: { metadata: [] } } },
4136
+ } as unknown as RawConfig,
4137
+ undefined,
4138
+ { env: "ENV1" }
4139
+ );
4140
+
4141
+ expect(diagnostics.renderWarnings()).toMatchInlineSnapshot(`
4142
+ "Processing wrangler configuration:
4143
+
4144
+ - \\"env.ENV1\\" environment configuration
4145
+ - \\"unsafe\\" fields are experimental and may change or break at any time."
4146
+ `);
4147
+ expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
4148
+ "Processing wrangler configuration:
4149
+
4150
+ - \\"env.ENV1\\" environment configuration
4151
+ - The field \\"env.ENV1.unsafe.metadata\\" should be an object but got []."
4152
+ `);
4153
+ });
4154
+
4155
+ it("should error if unsafe.metadata is a string", () => {
4156
+ const { diagnostics } = normalizeAndValidateConfig(
4157
+ {
4158
+ env: { ENV1: { unsafe: { metadata: "BAD" } } },
4159
+ } as unknown as RawConfig,
4160
+ undefined,
4161
+ { env: "ENV1" }
4162
+ );
4163
+
4164
+ expect(diagnostics.renderWarnings()).toMatchInlineSnapshot(`
4165
+ "Processing wrangler configuration:
4166
+
4167
+ - \\"env.ENV1\\" environment configuration
4168
+ - \\"unsafe\\" fields are experimental and may change or break at any time."
4169
+ `);
4170
+ expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
4171
+ "Processing wrangler configuration:
4172
+
4173
+ - \\"env.ENV1\\" environment configuration
4174
+ - The field \\"env.ENV1.unsafe.metadata\\" should be an object but got \\"BAD\\"."
4175
+ `);
4176
+ });
4177
+
4178
+ it("should error if unsafe.metadata is a number", () => {
4179
+ const { diagnostics } = normalizeAndValidateConfig(
4180
+ {
4181
+ env: { ENV1: { unsafe: { metadata: 999 } } },
4182
+ } as unknown as RawConfig,
4183
+ undefined,
4184
+ { env: "ENV1" }
4185
+ );
4186
+
4187
+ expect(diagnostics.renderWarnings()).toMatchInlineSnapshot(`
4188
+ "Processing wrangler configuration:
4189
+
4190
+ - \\"env.ENV1\\" environment configuration
4191
+ - \\"unsafe\\" fields are experimental and may change or break at any time."
4192
+ `);
4193
+ expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
4194
+ "Processing wrangler configuration:
4195
+
4196
+ - \\"env.ENV1\\" environment configuration
4197
+ - The field \\"env.ENV1.unsafe.metadata\\" should be an object but got 999."
4198
+ `);
4199
+ });
4200
+
4201
+ it("should error if unsafe.metadata is null", () => {
4202
+ const { diagnostics } = normalizeAndValidateConfig(
4203
+ {
4204
+ env: { ENV1: { unsafe: { metadata: null } } },
4205
+ } as unknown as RawConfig,
4206
+ undefined,
4207
+ { env: "ENV1" }
4208
+ );
4209
+
4210
+ expect(diagnostics.renderWarnings()).toMatchInlineSnapshot(`
4211
+ "Processing wrangler configuration:
4212
+
4213
+ - \\"env.ENV1\\" environment configuration
4214
+ - \\"unsafe\\" fields are experimental and may change or break at any time."
4215
+ `);
4216
+ expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
4217
+ "Processing wrangler configuration:
4218
+
4219
+ - \\"env.ENV1\\" environment configuration
4220
+ - The field \\"env.ENV1.unsafe.metadata\\" should be an object but got null."
4221
+ `);
4222
+ });
3695
4223
  });
3696
4224
 
3697
4225
  describe("(deprecated)", () => {