wrangler 2.0.5 → 2.0.8

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 (46) hide show
  1. package/README.md +1 -1
  2. package/bin/wrangler.js +16 -4
  3. package/package.json +6 -4
  4. package/pages/functions/buildPlugin.ts +13 -0
  5. package/pages/functions/buildWorker.ts +13 -0
  6. package/src/__tests__/configuration.test.ts +335 -86
  7. package/src/__tests__/dev.test.tsx +166 -15
  8. package/src/__tests__/helpers/mock-dialogs.ts +41 -1
  9. package/src/__tests__/index.test.ts +30 -16
  10. package/src/__tests__/init.test.ts +249 -131
  11. package/src/__tests__/kv.test.ts +101 -101
  12. package/src/__tests__/package-manager.test.ts +154 -7
  13. package/src/__tests__/pages.test.ts +369 -39
  14. package/src/__tests__/parse.test.ts +5 -1
  15. package/src/__tests__/publish.test.ts +556 -84
  16. package/src/__tests__/r2.test.ts +47 -24
  17. package/src/__tests__/secret.test.ts +39 -4
  18. package/src/abort.d.ts +3 -0
  19. package/src/bundle.ts +32 -1
  20. package/src/cfetch/index.ts +21 -4
  21. package/src/cfetch/internal.ts +14 -9
  22. package/src/config/environment.ts +40 -14
  23. package/src/config/index.ts +162 -0
  24. package/src/config/validation.ts +179 -64
  25. package/src/create-worker-preview.ts +17 -7
  26. package/src/create-worker-upload-form.ts +22 -8
  27. package/src/dev/dev.tsx +2 -4
  28. package/src/dev/local.tsx +6 -0
  29. package/src/dev/remote.tsx +15 -1
  30. package/src/dialogs.tsx +48 -0
  31. package/src/durable.ts +102 -0
  32. package/src/index.tsx +314 -144
  33. package/src/inspect.ts +39 -0
  34. package/src/kv.ts +77 -13
  35. package/src/open-in-browser.ts +5 -12
  36. package/src/package-manager.ts +50 -3
  37. package/src/pages.tsx +210 -65
  38. package/src/parse.ts +21 -4
  39. package/src/proxy.ts +38 -22
  40. package/src/publish.ts +227 -113
  41. package/src/sites.tsx +11 -9
  42. package/src/worker.ts +8 -0
  43. package/templates/new-worker-scheduled.js +17 -0
  44. package/templates/new-worker-scheduled.ts +32 -0
  45. package/templates/new-worker.ts +16 -1
  46. package/wrangler-dist/cli.js +35466 -22362
@@ -12,6 +12,7 @@ import {
12
12
  unsetMockFetchKVGetValues,
13
13
  } from "./helpers/mock-cfetch";
14
14
  import { mockConsoleMethods, normalizeSlashes } from "./helpers/mock-console";
15
+ import { mockConfirm } from "./helpers/mock-dialogs";
15
16
  import { useMockIsTTY } from "./helpers/mock-istty";
16
17
  import { mockKeyListRequest } from "./helpers/mock-kv";
17
18
  import { mockOAuthFlow } from "./helpers/mock-oauth-flow";
@@ -470,7 +471,10 @@ describe("publish", () => {
470
471
  mockSubDomainRequest();
471
472
  await runWrangler("publish ./some-path/worker/index.js");
472
473
  expect(std.out).toMatchInlineSnapshot(`
473
- "Uploaded test-name (TIMINGS)
474
+ "Your worker has access to the following bindings:
475
+ - Vars:
476
+ - xyz: \\"123\\"
477
+ Uploaded test-name (TIMINGS)
474
478
  Published test-name (TIMINGS)
475
479
  test-name.test-sub-domain.workers.dev"
476
480
  `);
@@ -645,6 +649,136 @@ describe("publish", () => {
645
649
  await runWrangler("publish ./index --env dev --legacy-env false");
646
650
  });
647
651
 
652
+ describe("custom domains", () => {
653
+ it("should publish routes marked with 'custom_domain' as seperate custom domains", async () => {
654
+ writeWranglerToml({
655
+ routes: [{ pattern: "api.example.com", custom_domain: true }],
656
+ });
657
+ writeWorkerSource();
658
+ mockUpdateWorkerRequest({ enabled: false });
659
+ mockUploadWorkerRequest({ expectedType: "esm" });
660
+ mockPublishCustomDomainsRequest({
661
+ publishFlags: {
662
+ override_scope: true,
663
+ override_existing_origin: false,
664
+ override_existing_dns_record: false,
665
+ },
666
+ domains: [{ hostname: "api.example.com" }],
667
+ });
668
+ await runWrangler("publish ./index");
669
+ expect(std.out).toContain("api.example.com (custom domain)");
670
+ });
671
+
672
+ it("should allow retrying if publish fails with a conflicting custom domain error", async () => {
673
+ writeWranglerToml({
674
+ routes: [{ pattern: "api.example.com", custom_domain: true }],
675
+ });
676
+ writeWorkerSource();
677
+ mockUpdateWorkerRequest({ enabled: false });
678
+ mockUploadWorkerRequest({ expectedType: "esm" });
679
+ mockPublishCustomDomainsRequestConflictWithoutOverride({
680
+ originConflicts: true,
681
+ domains: [{ hostname: "api.example.com" }],
682
+ });
683
+ mockConfirm({
684
+ text: `Custom Domains already exist for these domains: "api.example.com"\nUpdate them to point to this script instead?`,
685
+ result: true,
686
+ });
687
+ await runWrangler("publish ./index");
688
+ expect(std.out).toContain("api.example.com (custom domain)");
689
+ });
690
+
691
+ it("should allow retrying if publish fails with a conflicting DNS record error", async () => {
692
+ writeWranglerToml({
693
+ routes: [{ pattern: "api.example.com", custom_domain: true }],
694
+ });
695
+ writeWorkerSource();
696
+ mockUpdateWorkerRequest({ enabled: false });
697
+ mockUploadWorkerRequest({ expectedType: "esm" });
698
+ mockPublishCustomDomainsRequestConflictWithoutOverride({
699
+ dnsRecordConflicts: true,
700
+ domains: [{ hostname: "api.example.com" }],
701
+ });
702
+ mockConfirm({
703
+ text: `You already have conflicting DNS records for these domains: "api.example.com"\nUpdate them to point to this script instead?`,
704
+ result: true,
705
+ });
706
+ await runWrangler("publish ./index");
707
+ expect(std.out).toContain("api.example.com (custom domain)");
708
+ });
709
+
710
+ it("should allow retrying for conflicting custom domains and then again for conflicting dns", async () => {
711
+ writeWranglerToml({
712
+ routes: [{ pattern: "api.example.com", custom_domain: true }],
713
+ });
714
+ writeWorkerSource();
715
+ mockUpdateWorkerRequest({ enabled: false });
716
+ mockUploadWorkerRequest({ expectedType: "esm" });
717
+ mockPublishCustomDomainsRequestConflictWithoutOverride({
718
+ originConflicts: true,
719
+ dnsRecordConflicts: true,
720
+ domains: [{ hostname: "api.example.com" }],
721
+ });
722
+ mockConfirm(
723
+ {
724
+ text: `Custom Domains already exist for these domains: "api.example.com"\nUpdate them to point to this script instead?`,
725
+ result: true,
726
+ },
727
+ {
728
+ text: `You already have conflicting DNS records for these domains: "api.example.com"\nUpdate them to point to this script instead?`,
729
+ result: true,
730
+ }
731
+ );
732
+ await runWrangler("publish ./index");
733
+ expect(std.out).toContain("api.example.com (custom domain)");
734
+ });
735
+
736
+ it("should throw if an invalid custom domain is requested", async () => {
737
+ writeWranglerToml({
738
+ routes: [{ pattern: "*.example.com", custom_domain: true }],
739
+ });
740
+ writeWorkerSource();
741
+ await expect(
742
+ runWrangler("publish ./index")
743
+ ).rejects.toThrowErrorMatchingInlineSnapshot(
744
+ `"Cannot use \\"*.example.com\\" as a Custom Domain; wildcard operators (*) are not allowed"`
745
+ );
746
+
747
+ writeWranglerToml({
748
+ routes: [
749
+ { pattern: "api.example.com/at/a/path", custom_domain: true },
750
+ ],
751
+ });
752
+ writeWorkerSource();
753
+ await expect(
754
+ runWrangler("publish ./index")
755
+ ).rejects.toThrowErrorMatchingInlineSnapshot(
756
+ `"Cannot use \\"api.example.com/at/a/path\\" as a Custom Domain; paths are not allowed"`
757
+ );
758
+ });
759
+
760
+ it("should not retry publish on error if user does not confirm", async () => {
761
+ writeWranglerToml({
762
+ routes: [{ pattern: "api.example.com", custom_domain: true }],
763
+ });
764
+ writeWorkerSource();
765
+ mockUpdateWorkerRequest({ enabled: false });
766
+ mockUploadWorkerRequest({ expectedType: "esm" });
767
+ mockPublishCustomDomainsRequestConflictWithoutOverride({
768
+ dnsRecordConflicts: true,
769
+ domains: [{ hostname: "api.example.com" }],
770
+ });
771
+ mockConfirm({
772
+ text: `You already have conflicting DNS records for these domains: "api.example.com"\nUpdate them to point to this script instead?`,
773
+ result: false,
774
+ });
775
+ await runWrangler("publish ./index");
776
+ expect(std.out).toContain(
777
+ 'Publishing to Custom Domain "api.example.com" was skipped, fix conflict and try again'
778
+ );
779
+ });
780
+ });
781
+
648
782
  it.todo("should error if it's a workers.dev route");
649
783
  });
650
784
 
@@ -987,7 +1121,7 @@ addEventListener('fetch', event => {});`
987
1121
 
988
1122
  expect(std.out).toMatchInlineSnapshot(`
989
1123
  "
990
- If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
1124
+ If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new/choose"
991
1125
  `);
992
1126
  expect(std.err).toMatchInlineSnapshot(`
993
1127
  "X [ERROR] Processing wrangler.toml configuration:
@@ -1145,7 +1279,7 @@ addEventListener('fetch', event => {});`
1145
1279
 
1146
1280
  expect(std.out).toMatchInlineSnapshot(`
1147
1281
  "
1148
- If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
1282
+ If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new/choose"
1149
1283
  `);
1150
1284
  expect(std.err).toMatchInlineSnapshot(`
1151
1285
  "X [ERROR] Missing entry-point: The entry-point should be specified via the command line (e.g. \`wrangler publish path/to/script\`) or the \`main\` config field.
@@ -1193,6 +1327,56 @@ addEventListener('fetch', event => {});`
1193
1327
  expect(std.err).toMatchInlineSnapshot(`""`);
1194
1328
  });
1195
1329
 
1330
+ it("should not contain backslash for assets with nested directories", async () => {
1331
+ const assets = [
1332
+ { filePath: "assets/subdir/file-1.txt", content: "Content of file-1" },
1333
+ { filePath: "assets/subdir/file-2.txt", content: "Content of file-2" },
1334
+ ];
1335
+ const kvNamespace = {
1336
+ title: "__test-name-workers_sites_assets",
1337
+ id: "__test-name-workers_sites_assets-id",
1338
+ };
1339
+ writeWranglerToml({
1340
+ main: "./index.js",
1341
+ site: {
1342
+ bucket: "assets",
1343
+ },
1344
+ });
1345
+ writeWorkerSource();
1346
+ writeAssets(assets);
1347
+ mockUploadWorkerRequest({
1348
+ expectedBindings: [
1349
+ {
1350
+ name: "__STATIC_CONTENT",
1351
+ namespace_id: "__test-name-workers_sites_assets-id",
1352
+ type: "kv_namespace",
1353
+ },
1354
+ ],
1355
+ expectedModules: {
1356
+ __STATIC_CONTENT_MANIFEST:
1357
+ '{"subdir/file-1.txt":"assets/subdir/file-1.2ca234f380.txt","subdir/file-2.txt":"assets/subdir/file-2.5938485188.txt"}',
1358
+ },
1359
+ });
1360
+ mockSubDomainRequest();
1361
+ mockListKVNamespacesRequest(kvNamespace);
1362
+ mockKeyListRequest(kvNamespace.id, []);
1363
+ mockUploadAssetsToKVRequest(kvNamespace.id, assets);
1364
+
1365
+ await runWrangler("publish");
1366
+
1367
+ expect(std.out).toMatchInlineSnapshot(`
1368
+ "Reading assets/subdir/file-1.txt...
1369
+ Uploading as assets/subdir/file-1.2ca234f380.txt...
1370
+ Reading assets/subdir/file-2.txt...
1371
+ Uploading as assets/subdir/file-2.5938485188.txt...
1372
+ ↗️ Done syncing assets
1373
+ Uploaded test-name (TIMINGS)
1374
+ Published test-name (TIMINGS)
1375
+ test-name.test-sub-domain.workers.dev"
1376
+ `);
1377
+ expect(std.err).toMatchInlineSnapshot(`""`);
1378
+ });
1379
+
1196
1380
  it("when using a service-worker type, it should add an asset manifest as a text_blob, and bind to a namespace", async () => {
1197
1381
  const assets = [
1198
1382
  { filePath: "assets/file-1.txt", content: "Content of file-1" },
@@ -1806,7 +1990,7 @@ addEventListener('fetch', event => {});`
1806
1990
  "Reading assets/large-file.txt...
1807
1991
  Uploading as assets/large-file.0ea0637a45.txt...
1808
1992
 
1809
- If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
1993
+ If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new/choose"
1810
1994
  `);
1811
1995
  expect(std.err).toMatchInlineSnapshot(`
1812
1996
  "X [ERROR] File assets/too-large-file.txt is too big, it should be under 25 MiB. See https://developers.cloudflare.com/workers/platform/limits#kv-limits
@@ -1846,7 +2030,7 @@ addEventListener('fetch', event => {});`
1846
2030
  expect(std.out).toMatchInlineSnapshot(`
1847
2031
  "Reading assets/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/file.txt...
1848
2032
 
1849
- If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
2033
+ If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new/choose"
1850
2034
  `);
1851
2035
  expect(std.err).toMatchInlineSnapshot(`
1852
2036
  "X [ERROR] The asset path key \\"assets/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/file.3da0d0cd12.txt\\" exceeds the maximum key size limit of 512. See https://developers.cloudflare.com/workers/platform/limits#kv-limits\\",
@@ -2557,7 +2741,7 @@ addEventListener('fetch', event => {});`
2557
2741
  expect(std.out).toMatchInlineSnapshot(`
2558
2742
  "Running custom build: node -e \\"console.log('custom build');\\"
2559
2743
 
2560
- If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
2744
+ If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new/choose"
2561
2745
  `);
2562
2746
  expect(std.err).toMatchInlineSnapshot(`
2563
2747
  "X [ERROR] The expected output file at \\"index.js\\" was not found after running custom build: node -e \\"console.log('custom build');\\".
@@ -2596,7 +2780,7 @@ addEventListener('fetch', event => {});`
2596
2780
  expect(std.out).toMatchInlineSnapshot(`
2597
2781
  "Running custom build: node -e \\"console.log('custom build');\\"
2598
2782
 
2599
- If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
2783
+ If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new/choose"
2600
2784
  `);
2601
2785
  expect(std.err).toMatchInlineSnapshot(`
2602
2786
  "X [ERROR] The expected output file at \\".\\" was not found after running custom build: node -e \\"console.log('custom build');\\".
@@ -2698,13 +2882,30 @@ addEventListener('fetch', event => {});`
2698
2882
  mockUploadWorkerRequest();
2699
2883
  await runWrangler("publish index.js");
2700
2884
  expect(std.out).toMatchInlineSnapshot(`
2701
- "Uploaded test-name (TIMINGS)
2885
+ "Your worker has access to the following bindings:
2886
+ - Durable Objects:
2887
+ - SOMENAME: SomeClass
2888
+ Uploaded test-name (TIMINGS)
2702
2889
  Published test-name (TIMINGS)
2703
2890
  test-name.test-sub-domain.workers.dev"
2704
2891
  `);
2705
2892
  expect(std.err).toMatchInlineSnapshot(`""`);
2706
2893
  expect(std.warn).toMatchInlineSnapshot(`
2707
- "▲ [WARNING] In wrangler.toml, you have configured [durable_objects] exported by this Worker (SomeClass), but no [migrations] for them. This may not work as expected until you add a [migrations] section to your wrangler.toml. Refer to https://developers.cloudflare.com/workers/learning/using-durable-objects/#durable-object-migrations-in-wranglertoml for more details.
2894
+ "▲ [WARNING] Processing wrangler.toml configuration:
2895
+
2896
+ - In wrangler.toml, you have configured [durable_objects] exported by this Worker (SomeClass),
2897
+ but no [migrations] for them. This may not work as expected until you add a [migrations] section
2898
+ to your wrangler.toml. Add this configuration to your wrangler.toml:
2899
+
2900
+ \`\`\`
2901
+ [[migrations]]
2902
+ tag = \\"v1\\" # Should be unique for each entry
2903
+ new_classes = [\\"SomeClass\\"]
2904
+ \`\`\`
2905
+
2906
+ Refer to
2907
+ https://developers.cloudflare.com/workers/learning/using-durable-objects/#durable-object-migrations-in-wranglertoml
2908
+ for more details.
2708
2909
 
2709
2910
  "
2710
2911
  `);
@@ -2730,7 +2931,10 @@ addEventListener('fetch', event => {});`
2730
2931
  mockUploadWorkerRequest();
2731
2932
  await runWrangler("publish index.js");
2732
2933
  expect(std.out).toMatchInlineSnapshot(`
2733
- "Uploaded test-name (TIMINGS)
2934
+ "Your worker has access to the following bindings:
2935
+ - Durable Objects:
2936
+ - SOMENAME: SomeClass (defined in some-script)
2937
+ Uploaded test-name (TIMINGS)
2734
2938
  Published test-name (TIMINGS)
2735
2939
  test-name.test-sub-domain.workers.dev"
2736
2940
  `);
@@ -2769,7 +2973,11 @@ addEventListener('fetch', event => {});`
2769
2973
 
2770
2974
  await runWrangler("publish index.js");
2771
2975
  expect(std.out).toMatchInlineSnapshot(`
2772
- "Uploaded test-name (TIMINGS)
2976
+ "Your worker has access to the following bindings:
2977
+ - Durable Objects:
2978
+ - SOMENAME: SomeClass
2979
+ - SOMEOTHERNAME: SomeOtherClass
2980
+ Uploaded test-name (TIMINGS)
2773
2981
  Published test-name (TIMINGS)
2774
2982
  test-name.test-sub-domain.workers.dev"
2775
2983
  `);
@@ -2815,7 +3023,11 @@ addEventListener('fetch', event => {});`
2815
3023
  Object {
2816
3024
  "debug": "",
2817
3025
  "err": "",
2818
- "out": "Uploaded test-name (TIMINGS)
3026
+ "out": "Your worker has access to the following bindings:
3027
+ - Durable Objects:
3028
+ - SOMENAME: SomeClass
3029
+ - SOMEOTHERNAME: SomeOtherClass
3030
+ Uploaded test-name (TIMINGS)
2819
3031
  Published test-name (TIMINGS)
2820
3032
  test-name.test-sub-domain.workers.dev",
2821
3033
  "warn": "",
@@ -2854,7 +3066,11 @@ addEventListener('fetch', event => {});`
2854
3066
  Object {
2855
3067
  "debug": "",
2856
3068
  "err": "",
2857
- "out": "Uploaded test-name (TIMINGS)
3069
+ "out": "Your worker has access to the following bindings:
3070
+ - Durable Objects:
3071
+ - SOMENAME: SomeClass
3072
+ - SOMEOTHERNAME: SomeOtherClass
3073
+ Uploaded test-name (TIMINGS)
2858
3074
  Published test-name (TIMINGS)
2859
3075
  test-name.test-sub-domain.workers.dev",
2860
3076
  "warn": "",
@@ -2895,7 +3111,11 @@ addEventListener('fetch', event => {});`
2895
3111
 
2896
3112
  await runWrangler("publish index.js --legacy-env false");
2897
3113
  expect(std.out).toMatchInlineSnapshot(`
2898
- "Uploaded test-name (TIMINGS)
3114
+ "Your worker has access to the following bindings:
3115
+ - Durable Objects:
3116
+ - SOMENAME: SomeClass
3117
+ - SOMEOTHERNAME: SomeOtherClass
3118
+ Uploaded test-name (TIMINGS)
2899
3119
  Published test-name (TIMINGS)
2900
3120
  test-name.test-sub-domain.workers.dev"
2901
3121
  `);
@@ -2953,7 +3173,11 @@ addEventListener('fetch', event => {});`
2953
3173
 
2954
3174
  await runWrangler("publish index.js --legacy-env false --env xyz");
2955
3175
  expect(std.out).toMatchInlineSnapshot(`
2956
- "Uploaded test-name (xyz) (TIMINGS)
3176
+ "Your worker has access to the following bindings:
3177
+ - Durable Objects:
3178
+ - SOMENAME: SomeClass
3179
+ - SOMEOTHERNAME: SomeOtherClass
3180
+ Uploaded test-name (xyz) (TIMINGS)
2957
3181
  Published test-name (xyz) (TIMINGS)
2958
3182
  xyz.test-name.test-sub-domain.workers.dev"
2959
3183
  `);
@@ -3007,7 +3231,11 @@ addEventListener('fetch', event => {});`
3007
3231
  Object {
3008
3232
  "debug": "",
3009
3233
  "err": "",
3010
- "out": "Uploaded test-name (TIMINGS)
3234
+ "out": "Your worker has access to the following bindings:
3235
+ - Durable Objects:
3236
+ - SOMENAME: SomeClass
3237
+ - SOMEOTHERNAME: SomeOtherClass
3238
+ Uploaded test-name (TIMINGS)
3011
3239
  Published test-name (TIMINGS)
3012
3240
  test-name.test-sub-domain.workers.dev",
3013
3241
  "warn": "▲ [WARNING] Processing wrangler.toml configuration:
@@ -3071,7 +3299,11 @@ addEventListener('fetch', event => {});`
3071
3299
  Object {
3072
3300
  "debug": "",
3073
3301
  "err": "",
3074
- "out": "Uploaded test-name (xyz) (TIMINGS)
3302
+ "out": "Your worker has access to the following bindings:
3303
+ - Durable Objects:
3304
+ - SOMENAME: SomeClass
3305
+ - SOMEOTHERNAME: SomeOtherClass
3306
+ Uploaded test-name (xyz) (TIMINGS)
3075
3307
  Published test-name (xyz) (TIMINGS)
3076
3308
  xyz.test-name.test-sub-domain.workers.dev",
3077
3309
  "warn": "▲ [WARNING] Processing wrangler.toml configuration:
@@ -3106,6 +3338,7 @@ addEventListener('fetch', event => {});`
3106
3338
  name: "DURABLE_OBJECT_TWO",
3107
3339
  class_name: "AnotherDurableObject",
3108
3340
  script_name: "another-durable-object-worker",
3341
+ environment: "staging",
3109
3342
  },
3110
3343
  ],
3111
3344
  },
@@ -3164,6 +3397,12 @@ addEventListener('fetch', event => {});`
3164
3397
  mockUploadWorkerRequest({
3165
3398
  expectedType: "sw",
3166
3399
  expectedBindings: [
3400
+ { json: 123, name: "ENV_VAR_ONE", type: "json" },
3401
+ {
3402
+ name: "ENV_VAR_TWO",
3403
+ text: "Hello, I'm an environment variable",
3404
+ type: "plain_text",
3405
+ },
3167
3406
  {
3168
3407
  name: "KV_NAMESPACE_ONE",
3169
3408
  namespace_id: "kv-ns-one-id",
@@ -3182,6 +3421,7 @@ addEventListener('fetch', event => {});`
3182
3421
  },
3183
3422
  {
3184
3423
  class_name: "AnotherDurableObject",
3424
+ environment: "staging",
3185
3425
  name: "DURABLE_OBJECT_TWO",
3186
3426
  script_name: "another-durable-object-worker",
3187
3427
  type: "durable_object_namespace",
@@ -3196,12 +3436,6 @@ addEventListener('fetch', event => {});`
3196
3436
  name: "R2_BUCKET_TWO",
3197
3437
  type: "r2_bucket",
3198
3438
  },
3199
- { json: 123, name: "ENV_VAR_ONE", type: "json" },
3200
- {
3201
- name: "ENV_VAR_TWO",
3202
- text: "Hello, I'm an environment variable",
3203
- type: "plain_text",
3204
- },
3205
3439
  {
3206
3440
  name: "WASM_MODULE_ONE",
3207
3441
  part: "WASM_MODULE_ONE",
@@ -3233,7 +3467,32 @@ addEventListener('fetch', event => {});`
3233
3467
 
3234
3468
  await expect(runWrangler("publish index.js")).resolves.toBeUndefined();
3235
3469
  expect(std.out).toMatchInlineSnapshot(`
3236
- "Uploaded test-name (TIMINGS)
3470
+ "Your worker has access to the following bindings:
3471
+ - Data Blobs:
3472
+ - DATA_BLOB_ONE: some-data-blob.bin
3473
+ - DATA_BLOB_TWO: more-data-blob.bin
3474
+ - Durable Objects:
3475
+ - DURABLE_OBJECT_ONE: SomeDurableObject (defined in some-durable-object-worker)
3476
+ - DURABLE_OBJECT_TWO: AnotherDurableObject (defined in another-durable-object-worker) - staging
3477
+ - KV Namespaces:
3478
+ - KV_NAMESPACE_ONE: kv-ns-one-id
3479
+ - KV_NAMESPACE_TWO: kv-ns-two-id
3480
+ - R2 Buckets:
3481
+ - R2_BUCKET_ONE: r2-bucket-one-name
3482
+ - R2_BUCKET_TWO: r2-bucket-two-name
3483
+ - Text Blobs:
3484
+ - TEXT_BLOB_ONE: my-entire-app-depends-on-this.cfg
3485
+ - TEXT_BLOB_TWO: the-entirety-of-human-knowledge.txt
3486
+ - Unsafe:
3487
+ - some unsafe thing: UNSAFE_BINDING_ONE
3488
+ - another unsafe thing: UNSAFE_BINDING_TWO
3489
+ - Vars:
3490
+ - ENV_VAR_ONE: \\"123\\"
3491
+ - ENV_VAR_TWO: \\"Hello, I'm an environment variable\\"
3492
+ - Wasm Modules:
3493
+ - WASM_MODULE_ONE: some_wasm.wasm
3494
+ - WASM_MODULE_TWO: more_wasm.wasm
3495
+ Uploaded test-name (TIMINGS)
3237
3496
  Published test-name (TIMINGS)
3238
3497
  test-name.test-sub-domain.workers.dev"
3239
3498
  `);
@@ -3330,7 +3589,7 @@ addEventListener('fetch', event => {});`
3330
3589
  `);
3331
3590
  expect(std.out).toMatchInlineSnapshot(`
3332
3591
  "
3333
- If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
3592
+ If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new/choose"
3334
3593
  `);
3335
3594
  expect(std.err).toMatchInlineSnapshot(`
3336
3595
  "X [ERROR] Processing wrangler.toml configuration:
@@ -3429,7 +3688,7 @@ addEventListener('fetch', event => {});`
3429
3688
  `);
3430
3689
  expect(std.out).toMatchInlineSnapshot(`
3431
3690
  "
3432
- If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
3691
+ If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new/choose"
3433
3692
  `);
3434
3693
  expect(std.err).toMatchInlineSnapshot(`
3435
3694
  "X [ERROR] Processing wrangler.toml configuration:
@@ -3563,7 +3822,7 @@ addEventListener('fetch', event => {});`
3563
3822
  `);
3564
3823
  expect(std.out).toMatchInlineSnapshot(`
3565
3824
  "
3566
- If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
3825
+ If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new/choose"
3567
3826
  `);
3568
3827
  expect(std.err).toMatchInlineSnapshot(`
3569
3828
  "X [ERROR] Processing wrangler.toml configuration:
@@ -3609,10 +3868,13 @@ addEventListener('fetch', event => {});`
3609
3868
  mockSubDomainRequest();
3610
3869
  await runWrangler("publish index.js");
3611
3870
  expect(std.out).toMatchInlineSnapshot(`
3612
- "Uploaded test-name (TIMINGS)
3613
- Published test-name (TIMINGS)
3614
- test-name.test-sub-domain.workers.dev"
3615
- `);
3871
+ "Your worker has access to the following bindings:
3872
+ - Wasm Modules:
3873
+ - TESTWASMNAME: path/to/test.wasm
3874
+ Uploaded test-name (TIMINGS)
3875
+ Published test-name (TIMINGS)
3876
+ test-name.test-sub-domain.workers.dev"
3877
+ `);
3616
3878
  expect(std.err).toMatchInlineSnapshot(`""`);
3617
3879
  expect(std.warn).toMatchInlineSnapshot(`""`);
3618
3880
  });
@@ -3634,7 +3896,7 @@ addEventListener('fetch', event => {});`
3634
3896
  );
3635
3897
  expect(std.out).toMatchInlineSnapshot(`
3636
3898
  "
3637
- If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
3899
+ If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new/choose"
3638
3900
  `);
3639
3901
  expect(std.err).toMatchInlineSnapshot(`
3640
3902
  "X [ERROR] You cannot configure [wasm_modules] with an ES module worker. Instead, import the .wasm module directly in your code
@@ -3675,10 +3937,13 @@ addEventListener('fetch', event => {});`
3675
3937
  mockSubDomainRequest();
3676
3938
  await runWrangler("publish index.js --config ./path/to/wrangler.toml");
3677
3939
  expect(std.out).toMatchInlineSnapshot(`
3678
- "Uploaded test-name (TIMINGS)
3679
- Published test-name (TIMINGS)
3680
- test-name.test-sub-domain.workers.dev"
3681
- `);
3940
+ "Your worker has access to the following bindings:
3941
+ - Wasm Modules:
3942
+ - TESTWASMNAME: path/to/and/the/path/to/test.wasm
3943
+ Uploaded test-name (TIMINGS)
3944
+ Published test-name (TIMINGS)
3945
+ test-name.test-sub-domain.workers.dev"
3946
+ `);
3682
3947
  expect(std.err).toMatchInlineSnapshot(`""`);
3683
3948
  expect(std.warn).toMatchInlineSnapshot(`""`);
3684
3949
  });
@@ -3740,10 +4005,13 @@ addEventListener('fetch', event => {});`
3740
4005
  mockSubDomainRequest();
3741
4006
  await runWrangler("publish index.js");
3742
4007
  expect(std.out).toMatchInlineSnapshot(`
3743
- "Uploaded test-name (TIMINGS)
3744
- Published test-name (TIMINGS)
3745
- test-name.test-sub-domain.workers.dev"
3746
- `);
4008
+ "Your worker has access to the following bindings:
4009
+ - Text Blobs:
4010
+ - TESTTEXTBLOBNAME: path/to/text.file
4011
+ Uploaded test-name (TIMINGS)
4012
+ Published test-name (TIMINGS)
4013
+ test-name.test-sub-domain.workers.dev"
4014
+ `);
3747
4015
  expect(std.err).toMatchInlineSnapshot(`""`);
3748
4016
  expect(std.warn).toMatchInlineSnapshot(`""`);
3749
4017
  });
@@ -3765,7 +4033,7 @@ addEventListener('fetch', event => {});`
3765
4033
  );
3766
4034
  expect(std.out).toMatchInlineSnapshot(`
3767
4035
  "
3768
- If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
4036
+ If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new/choose"
3769
4037
  `);
3770
4038
  expect(std.err).toMatchInlineSnapshot(`
3771
4039
  "X [ERROR] You cannot configure [text_blobs] with an ES module worker. Instead, import the file directly in your code, and optionally configure \`[rules]\` in your wrangler.toml
@@ -3810,10 +4078,13 @@ addEventListener('fetch', event => {});`
3810
4078
  mockSubDomainRequest();
3811
4079
  await runWrangler("publish index.js --config ./path/to/wrangler.toml");
3812
4080
  expect(std.out).toMatchInlineSnapshot(`
3813
- "Uploaded test-name (TIMINGS)
3814
- Published test-name (TIMINGS)
3815
- test-name.test-sub-domain.workers.dev"
3816
- `);
4081
+ "Your worker has access to the following bindings:
4082
+ - Text Blobs:
4083
+ - TESTTEXTBLOBNAME: path/to/and/the/path/to/text.file
4084
+ Uploaded test-name (TIMINGS)
4085
+ Published test-name (TIMINGS)
4086
+ test-name.test-sub-domain.workers.dev"
4087
+ `);
3817
4088
  expect(std.err).toMatchInlineSnapshot(`""`);
3818
4089
  expect(std.warn).toMatchInlineSnapshot(`""`);
3819
4090
  });
@@ -3843,10 +4114,13 @@ addEventListener('fetch', event => {});`
3843
4114
  mockSubDomainRequest();
3844
4115
  await runWrangler("publish index.js");
3845
4116
  expect(std.out).toMatchInlineSnapshot(`
3846
- "Uploaded test-name (TIMINGS)
3847
- Published test-name (TIMINGS)
3848
- test-name.test-sub-domain.workers.dev"
3849
- `);
4117
+ "Your worker has access to the following bindings:
4118
+ - Data Blobs:
4119
+ - TESTDATABLOBNAME: path/to/data.bin
4120
+ Uploaded test-name (TIMINGS)
4121
+ Published test-name (TIMINGS)
4122
+ test-name.test-sub-domain.workers.dev"
4123
+ `);
3850
4124
  expect(std.err).toMatchInlineSnapshot(`""`);
3851
4125
  expect(std.warn).toMatchInlineSnapshot(`""`);
3852
4126
  });
@@ -3868,7 +4142,7 @@ addEventListener('fetch', event => {});`
3868
4142
  );
3869
4143
  expect(std.out).toMatchInlineSnapshot(`
3870
4144
  "
3871
- If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
4145
+ If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new/choose"
3872
4146
  `);
3873
4147
  expect(std.err).toMatchInlineSnapshot(`
3874
4148
  "X [ERROR] You cannot configure [data_blobs] with an ES module worker. Instead, import the file directly in your code, and optionally configure \`[rules]\` in your wrangler.toml
@@ -3913,10 +4187,13 @@ addEventListener('fetch', event => {});`
3913
4187
  mockSubDomainRequest();
3914
4188
  await runWrangler("publish index.js --config ./path/to/wrangler.toml");
3915
4189
  expect(std.out).toMatchInlineSnapshot(`
3916
- "Uploaded test-name (TIMINGS)
3917
- Published test-name (TIMINGS)
3918
- test-name.test-sub-domain.workers.dev"
3919
- `);
4190
+ "Your worker has access to the following bindings:
4191
+ - Data Blobs:
4192
+ - TESTDATABLOBNAME: path/to/and/the/path/to/data.bin
4193
+ Uploaded test-name (TIMINGS)
4194
+ Published test-name (TIMINGS)
4195
+ test-name.test-sub-domain.workers.dev"
4196
+ `);
3920
4197
  expect(std.err).toMatchInlineSnapshot(`""`);
3921
4198
  expect(std.warn).toMatchInlineSnapshot(`""`);
3922
4199
  });
@@ -3947,10 +4224,15 @@ addEventListener('fetch', event => {});`
3947
4224
 
3948
4225
  await runWrangler("publish index.js");
3949
4226
  expect(std.out).toMatchInlineSnapshot(`
3950
- "Uploaded test-name (TIMINGS)
3951
- Published test-name (TIMINGS)
3952
- test-name.test-sub-domain.workers.dev"
3953
- `);
4227
+ "Your worker has access to the following bindings:
4228
+ - Vars:
4229
+ - text: \\"plain ol' string\\"
4230
+ - count: \\"1\\"
4231
+ - complex: \\"[object Object]\\"
4232
+ Uploaded test-name (TIMINGS)
4233
+ Published test-name (TIMINGS)
4234
+ test-name.test-sub-domain.workers.dev"
4235
+ `);
3954
4236
  expect(std.err).toMatchInlineSnapshot(`""`);
3955
4237
  expect(std.warn).toMatchInlineSnapshot(`""`);
3956
4238
  });
@@ -3971,10 +4253,13 @@ addEventListener('fetch', event => {});`
3971
4253
 
3972
4254
  await runWrangler("publish index.js");
3973
4255
  expect(std.out).toMatchInlineSnapshot(`
3974
- "Uploaded test-name (TIMINGS)
3975
- Published test-name (TIMINGS)
3976
- test-name.test-sub-domain.workers.dev"
3977
- `);
4256
+ "Your worker has access to the following bindings:
4257
+ - R2 Buckets:
4258
+ - FOO: foo-bucket
4259
+ Uploaded test-name (TIMINGS)
4260
+ Published test-name (TIMINGS)
4261
+ test-name.test-sub-domain.workers.dev"
4262
+ `);
3978
4263
  expect(std.err).toMatchInlineSnapshot(`""`);
3979
4264
  expect(std.warn).toMatchInlineSnapshot(`""`);
3980
4265
  });
@@ -4013,10 +4298,13 @@ addEventListener('fetch', event => {});`
4013
4298
 
4014
4299
  await runWrangler("publish index.js");
4015
4300
  expect(std.out).toMatchInlineSnapshot(`
4016
- "Uploaded test-name (TIMINGS)
4017
- Published test-name (TIMINGS)
4018
- test-name.test-sub-domain.workers.dev"
4019
- `);
4301
+ "Your worker has access to the following bindings:
4302
+ - Durable Objects:
4303
+ - EXAMPLE_DO_BINDING: ExampleDurableObject
4304
+ Uploaded test-name (TIMINGS)
4305
+ Published test-name (TIMINGS)
4306
+ test-name.test-sub-domain.workers.dev"
4307
+ `);
4020
4308
  expect(std.err).toMatchInlineSnapshot(`""`);
4021
4309
  expect(std.warn).toMatchInlineSnapshot(`""`);
4022
4310
  });
@@ -4049,10 +4337,13 @@ addEventListener('fetch', event => {});`
4049
4337
 
4050
4338
  await runWrangler("publish index.js");
4051
4339
  expect(std.out).toMatchInlineSnapshot(`
4052
- "Uploaded test-name (TIMINGS)
4053
- Published test-name (TIMINGS)
4054
- test-name.test-sub-domain.workers.dev"
4055
- `);
4340
+ "Your worker has access to the following bindings:
4341
+ - Durable Objects:
4342
+ - EXAMPLE_DO_BINDING: ExampleDurableObject (defined in example-do-binding-worker)
4343
+ Uploaded test-name (TIMINGS)
4344
+ Published test-name (TIMINGS)
4345
+ test-name.test-sub-domain.workers.dev"
4346
+ `);
4056
4347
  expect(std.err).toMatchInlineSnapshot(`""`);
4057
4348
  expect(std.warn).toMatchInlineSnapshot(`""`);
4058
4349
  });
@@ -4090,10 +4381,13 @@ addEventListener('fetch', event => {});`
4090
4381
 
4091
4382
  await runWrangler("publish index.js");
4092
4383
  expect(std.out).toMatchInlineSnapshot(`
4093
- "Uploaded test-name (TIMINGS)
4094
- Published test-name (TIMINGS)
4095
- test-name.test-sub-domain.workers.dev"
4096
- `);
4384
+ "Your worker has access to the following bindings:
4385
+ - Durable Objects:
4386
+ - EXAMPLE_DO_BINDING: ExampleDurableObject
4387
+ Uploaded test-name (TIMINGS)
4388
+ Published test-name (TIMINGS)
4389
+ test-name.test-sub-domain.workers.dev"
4390
+ `);
4097
4391
  expect(std.err).toMatchInlineSnapshot(`""`);
4098
4392
  expect(std.warn).toMatchInlineSnapshot(`""`);
4099
4393
  });
@@ -4123,6 +4417,50 @@ addEventListener('fetch', event => {});`
4123
4417
  });
4124
4418
  });
4125
4419
 
4420
+ describe("[services]", () => {
4421
+ it("should support service bindings", async () => {
4422
+ writeWranglerToml({
4423
+ services: [
4424
+ {
4425
+ binding: "FOO",
4426
+ service: "foo-service",
4427
+ environment: "production",
4428
+ },
4429
+ ],
4430
+ });
4431
+ writeWorkerSource();
4432
+ mockSubDomainRequest();
4433
+ mockUploadWorkerRequest({
4434
+ expectedBindings: [
4435
+ {
4436
+ type: "service",
4437
+ name: "FOO",
4438
+ service: "foo-service",
4439
+ environment: "production",
4440
+ },
4441
+ ],
4442
+ });
4443
+
4444
+ await runWrangler("publish index.js");
4445
+ expect(std.out).toMatchInlineSnapshot(`
4446
+ "Your worker has access to the following bindings:
4447
+ - Services:
4448
+ - FOO: foo-service - production
4449
+ Uploaded test-name (TIMINGS)
4450
+ Published test-name (TIMINGS)
4451
+ test-name.test-sub-domain.workers.dev"
4452
+ `);
4453
+ expect(std.err).toMatchInlineSnapshot(`""`);
4454
+ expect(std.warn).toMatchInlineSnapshot(`
4455
+ "▲ [WARNING] Processing wrangler.toml configuration:
4456
+
4457
+ - \\"services\\" fields are experimental and may change or break at any time.
4458
+
4459
+ "
4460
+ `);
4461
+ });
4462
+ });
4463
+
4126
4464
  describe("[unsafe]", () => {
4127
4465
  it("should warn if using unsafe bindings", async () => {
4128
4466
  writeWranglerToml({
@@ -4150,10 +4488,13 @@ addEventListener('fetch', event => {});`
4150
4488
 
4151
4489
  await runWrangler("publish index.js");
4152
4490
  expect(std.out).toMatchInlineSnapshot(`
4153
- "Uploaded test-name (TIMINGS)
4154
- Published test-name (TIMINGS)
4155
- test-name.test-sub-domain.workers.dev"
4156
- `);
4491
+ "Your worker has access to the following bindings:
4492
+ - Unsafe:
4493
+ - binding-type: my-binding
4494
+ Uploaded test-name (TIMINGS)
4495
+ Published test-name (TIMINGS)
4496
+ test-name.test-sub-domain.workers.dev"
4497
+ `);
4157
4498
  expect(std.err).toMatchInlineSnapshot(`""`);
4158
4499
  expect(std.warn).toMatchInlineSnapshot(`
4159
4500
  "▲ [WARNING] Processing wrangler.toml configuration:
@@ -4189,10 +4530,13 @@ addEventListener('fetch', event => {});`
4189
4530
 
4190
4531
  await runWrangler("publish index.js");
4191
4532
  expect(std.out).toMatchInlineSnapshot(`
4192
- "Uploaded test-name (TIMINGS)
4193
- Published test-name (TIMINGS)
4194
- test-name.test-sub-domain.workers.dev"
4195
- `);
4533
+ "Your worker has access to the following bindings:
4534
+ - Unsafe:
4535
+ - plain_text: my-binding
4536
+ Uploaded test-name (TIMINGS)
4537
+ Published test-name (TIMINGS)
4538
+ test-name.test-sub-domain.workers.dev"
4539
+ `);
4196
4540
  expect(std.err).toMatchInlineSnapshot(`""`);
4197
4541
  expect(std.warn).toMatchInlineSnapshot(`
4198
4542
  "▲ [WARNING] Processing wrangler.toml configuration:
@@ -4625,14 +4969,25 @@ addEventListener('fetch', event => {});`
4625
4969
 
4626
4970
  describe("--dry-run", () => {
4627
4971
  it("should not publish the worker if --dry-run is specified", async () => {
4628
- writeWranglerToml();
4972
+ writeWranglerToml({
4973
+ // add a durable object with migrations
4974
+ // to make sure we _don't_ fetch migration status
4975
+ durable_objects: {
4976
+ bindings: [{ name: "NAME", class_name: "SomeClass" }],
4977
+ },
4978
+ migrations: [{ tag: "v1", new_classes: ["SomeClass"] }],
4979
+ });
4629
4980
  writeWorkerSource();
4981
+ process.env.CLOUDFLARE_ACCOUNT_ID = "";
4630
4982
  await runWrangler("publish index.js --dry-run");
4631
4983
  expect(std).toMatchInlineSnapshot(`
4632
4984
  Object {
4633
4985
  "debug": "",
4634
4986
  "err": "",
4635
- "out": "--dry-run: exiting now.",
4987
+ "out": "Your worker has access to the following bindings:
4988
+ - Durable Objects:
4989
+ - NAME: SomeClass
4990
+ --dry-run: exiting now.",
4636
4991
  "warn": "",
4637
4992
  }
4638
4993
  `);
@@ -4656,6 +5011,27 @@ addEventListener('fetch', event => {});`
4656
5011
  `);
4657
5012
  });
4658
5013
 
5014
+ it("should recommend node compatibility mode when using node builtins and node-compat isn't enabled", async () => {
5015
+ writeWranglerToml();
5016
+ fs.writeFileSync(
5017
+ "index.js",
5018
+ `
5019
+ import path from 'path';
5020
+ console.log(path.join("some/path/to", "a/file.txt"));
5021
+ export default {}
5022
+ `
5023
+ );
5024
+ let err: Error | undefined;
5025
+ try {
5026
+ await runWrangler("publish index.js --dry-run"); // expecting this to throw, as node compatibility isn't enabled
5027
+ } catch (e) {
5028
+ err = e as Error;
5029
+ }
5030
+ expect(err?.message).toMatch(
5031
+ `Detected a Node builtin module import while Node compatibility is disabled.\nAdd node_compat = true to your wrangler.toml file to enable Node compatibility.`
5032
+ );
5033
+ });
5034
+
4659
5035
  it("should polyfill node builtins when enabled", async () => {
4660
5036
  writeWranglerToml();
4661
5037
  fs.writeFileSync(
@@ -4850,6 +5226,102 @@ function mockPublishRoutesRequest({
4850
5226
  );
4851
5227
  }
4852
5228
 
5229
+ function mockPublishCustomDomainsRequest({
5230
+ publishFlags,
5231
+ domains = [],
5232
+ env = undefined,
5233
+ legacyEnv = false,
5234
+ }: {
5235
+ publishFlags: {
5236
+ override_scope: boolean;
5237
+ override_existing_origin: boolean;
5238
+ override_existing_dns_record: boolean;
5239
+ };
5240
+ domains: Array<
5241
+ { hostname: string } & ({ zone_id?: string } | { zone_name?: string })
5242
+ >;
5243
+ env?: string | undefined;
5244
+ legacyEnv?: boolean | undefined;
5245
+ }) {
5246
+ const servicesOrScripts = env && !legacyEnv ? "services" : "scripts";
5247
+ const environment = env && !legacyEnv ? "/environments/:envName" : "";
5248
+
5249
+ setMockResponse(
5250
+ `/accounts/:accountId/workers/${servicesOrScripts}/:scriptName${environment}/domains`,
5251
+ "PUT",
5252
+ ([_url, accountId, scriptName, envName], { body }) => {
5253
+ expect(accountId).toEqual("some-account-id");
5254
+ expect(scriptName).toEqual(
5255
+ legacyEnv && env ? `test-name-${env}` : "test-name"
5256
+ );
5257
+ if (!legacyEnv) {
5258
+ expect(envName).toEqual(env);
5259
+ }
5260
+
5261
+ expect(JSON.parse(body as string)).toEqual({
5262
+ ...publishFlags,
5263
+ origins: domains,
5264
+ });
5265
+
5266
+ return null;
5267
+ }
5268
+ );
5269
+ }
5270
+
5271
+ function mockPublishCustomDomainsRequestConflictWithoutOverride({
5272
+ domains = [],
5273
+ originConflicts = false,
5274
+ dnsRecordConflicts = false,
5275
+ env = undefined,
5276
+ legacyEnv = false,
5277
+ }: {
5278
+ originConflicts?: boolean;
5279
+ dnsRecordConflicts?: boolean;
5280
+ domains: Array<
5281
+ { hostname: string } & ({ zone_id?: string } | { zone_name?: string })
5282
+ >;
5283
+ env?: string | undefined;
5284
+ legacyEnv?: boolean | undefined;
5285
+ }) {
5286
+ const servicesOrScripts = env && !legacyEnv ? "services" : "scripts";
5287
+ const environment = env && !legacyEnv ? "/environments/:envName" : "";
5288
+
5289
+ setMockRawResponse(
5290
+ `/accounts/:accountId/workers/${servicesOrScripts}/:scriptName${environment}/domains`,
5291
+ "PUT",
5292
+ ([_url, accountId, scriptName, envName], { body }) => {
5293
+ expect(accountId).toEqual("some-account-id");
5294
+ expect(scriptName).toEqual(
5295
+ legacyEnv && env ? `test-name-${env}` : "test-name"
5296
+ );
5297
+ if (!legacyEnv) {
5298
+ expect(envName).toEqual(env);
5299
+ }
5300
+
5301
+ const parsed = JSON.parse(body as string);
5302
+ expect(parsed.origins).toEqual(domains);
5303
+
5304
+ if (originConflicts && !parsed.override_existing_origin) {
5305
+ return createFetchResult(null, false, [
5306
+ {
5307
+ code: 100116,
5308
+ message: `Cannot create Custom Domain "${domains[0].hostname}": Custom Domain already exists and points to a different script; retry and use option "override_existing_origin" to override`,
5309
+ },
5310
+ ]);
5311
+ }
5312
+ if (dnsRecordConflicts && !parsed.override_existing_dns_record) {
5313
+ return createFetchResult(null, false, [
5314
+ {
5315
+ code: 100117,
5316
+ message: `Cannot create Custom Domain "${domains[0].hostname}": a DNS record already exists for this origin; retry and use option "override_existing_dns_record" to override`,
5317
+ },
5318
+ ]);
5319
+ }
5320
+ return createFetchResult(null, true);
5321
+ }
5322
+ );
5323
+ }
5324
+
4853
5325
  /** Create a mock handler for the request to get a list of all KV namespaces. */
4854
5326
  function mockListKVNamespacesRequest(...namespaces: KVNamespaceInfo[]) {
4855
5327
  setMockResponse(