wrangler 2.0.2 → 2.0.6
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.
- package/Cloudflare_CA.pem +18 -0
- package/bin/wrangler.js +23 -3
- package/package.json +4 -2
- package/pages/functions/buildWorker.ts +1 -1
- package/pages/functions/template-plugin.ts +3 -2
- package/src/__tests__/configuration.test.ts +205 -28
- package/src/__tests__/dev.test.tsx +137 -17
- package/src/__tests__/index.test.ts +55 -63
- package/src/__tests__/jest.setup.ts +8 -0
- package/src/__tests__/kv.test.ts +157 -130
- package/src/__tests__/pages.test.ts +34 -13
- package/src/__tests__/publish.test.ts +362 -14
- package/src/__tests__/r2.test.ts +55 -36
- package/src/__tests__/secret.test.ts +35 -0
- package/src/bundle.ts +32 -1
- package/src/cfetch/internal.ts +3 -0
- package/src/config/config.ts +1 -1
- package/src/config/environment.ts +40 -14
- package/src/config/validation.ts +103 -36
- package/src/create-worker-upload-form.ts +22 -8
- package/src/dev/dev.tsx +5 -2
- package/src/dev/local.tsx +6 -0
- package/src/entry.ts +64 -9
- package/src/index.tsx +119 -68
- package/src/kv.ts +55 -15
- package/src/pages.tsx +11 -5
- package/src/publish.ts +210 -21
- package/src/sites.tsx +13 -11
- package/src/user.tsx +11 -1
- package/src/worker.ts +8 -0
- package/wrangler-dist/cli.js +1430 -1004
|
@@ -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";
|
|
@@ -645,6 +646,136 @@ describe("publish", () => {
|
|
|
645
646
|
await runWrangler("publish ./index --env dev --legacy-env false");
|
|
646
647
|
});
|
|
647
648
|
|
|
649
|
+
describe("custom domains", () => {
|
|
650
|
+
it("should publish routes marked with 'custom_domain' as seperate custom domains", async () => {
|
|
651
|
+
writeWranglerToml({
|
|
652
|
+
routes: [{ pattern: "api.example.com", custom_domain: true }],
|
|
653
|
+
});
|
|
654
|
+
writeWorkerSource();
|
|
655
|
+
mockUpdateWorkerRequest({ enabled: false });
|
|
656
|
+
mockUploadWorkerRequest({ expectedType: "esm" });
|
|
657
|
+
mockPublishCustomDomainsRequest({
|
|
658
|
+
publishFlags: {
|
|
659
|
+
override_scope: true,
|
|
660
|
+
override_existing_origin: false,
|
|
661
|
+
override_existing_dns_record: false,
|
|
662
|
+
},
|
|
663
|
+
domains: [{ hostname: "api.example.com" }],
|
|
664
|
+
});
|
|
665
|
+
await runWrangler("publish ./index");
|
|
666
|
+
expect(std.out).toContain("api.example.com (custom domain)");
|
|
667
|
+
});
|
|
668
|
+
|
|
669
|
+
it("should allow retrying if publish fails with a conflicting custom domain error", async () => {
|
|
670
|
+
writeWranglerToml({
|
|
671
|
+
routes: [{ pattern: "api.example.com", custom_domain: true }],
|
|
672
|
+
});
|
|
673
|
+
writeWorkerSource();
|
|
674
|
+
mockUpdateWorkerRequest({ enabled: false });
|
|
675
|
+
mockUploadWorkerRequest({ expectedType: "esm" });
|
|
676
|
+
mockPublishCustomDomainsRequestConflictWithoutOverride({
|
|
677
|
+
originConflicts: true,
|
|
678
|
+
domains: [{ hostname: "api.example.com" }],
|
|
679
|
+
});
|
|
680
|
+
mockConfirm({
|
|
681
|
+
text: `Custom Domains already exist for these domains: "api.example.com"\nUpdate them to point to this script instead?`,
|
|
682
|
+
result: true,
|
|
683
|
+
});
|
|
684
|
+
await runWrangler("publish ./index");
|
|
685
|
+
expect(std.out).toContain("api.example.com (custom domain)");
|
|
686
|
+
});
|
|
687
|
+
|
|
688
|
+
it("should allow retrying if publish fails with a conflicting DNS record error", async () => {
|
|
689
|
+
writeWranglerToml({
|
|
690
|
+
routes: [{ pattern: "api.example.com", custom_domain: true }],
|
|
691
|
+
});
|
|
692
|
+
writeWorkerSource();
|
|
693
|
+
mockUpdateWorkerRequest({ enabled: false });
|
|
694
|
+
mockUploadWorkerRequest({ expectedType: "esm" });
|
|
695
|
+
mockPublishCustomDomainsRequestConflictWithoutOverride({
|
|
696
|
+
dnsRecordConflicts: true,
|
|
697
|
+
domains: [{ hostname: "api.example.com" }],
|
|
698
|
+
});
|
|
699
|
+
mockConfirm({
|
|
700
|
+
text: `You already have conflicting DNS records for these domains: "api.example.com"\nUpdate them to point to this script instead?`,
|
|
701
|
+
result: true,
|
|
702
|
+
});
|
|
703
|
+
await runWrangler("publish ./index");
|
|
704
|
+
expect(std.out).toContain("api.example.com (custom domain)");
|
|
705
|
+
});
|
|
706
|
+
|
|
707
|
+
it("should allow retrying for conflicting custom domains and then again for conflicting dns", async () => {
|
|
708
|
+
writeWranglerToml({
|
|
709
|
+
routes: [{ pattern: "api.example.com", custom_domain: true }],
|
|
710
|
+
});
|
|
711
|
+
writeWorkerSource();
|
|
712
|
+
mockUpdateWorkerRequest({ enabled: false });
|
|
713
|
+
mockUploadWorkerRequest({ expectedType: "esm" });
|
|
714
|
+
mockPublishCustomDomainsRequestConflictWithoutOverride({
|
|
715
|
+
originConflicts: true,
|
|
716
|
+
dnsRecordConflicts: true,
|
|
717
|
+
domains: [{ hostname: "api.example.com" }],
|
|
718
|
+
});
|
|
719
|
+
mockConfirm(
|
|
720
|
+
{
|
|
721
|
+
text: `Custom Domains already exist for these domains: "api.example.com"\nUpdate them to point to this script instead?`,
|
|
722
|
+
result: true,
|
|
723
|
+
},
|
|
724
|
+
{
|
|
725
|
+
text: `You already have conflicting DNS records for these domains: "api.example.com"\nUpdate them to point to this script instead?`,
|
|
726
|
+
result: true,
|
|
727
|
+
}
|
|
728
|
+
);
|
|
729
|
+
await runWrangler("publish ./index");
|
|
730
|
+
expect(std.out).toContain("api.example.com (custom domain)");
|
|
731
|
+
});
|
|
732
|
+
|
|
733
|
+
it("should throw if an invalid custom domain is requested", async () => {
|
|
734
|
+
writeWranglerToml({
|
|
735
|
+
routes: [{ pattern: "*.example.com", custom_domain: true }],
|
|
736
|
+
});
|
|
737
|
+
writeWorkerSource();
|
|
738
|
+
await expect(
|
|
739
|
+
runWrangler("publish ./index")
|
|
740
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
741
|
+
`"Cannot use \\"*.example.com\\" as a Custom Domain; wildcard operators (*) are not allowed"`
|
|
742
|
+
);
|
|
743
|
+
|
|
744
|
+
writeWranglerToml({
|
|
745
|
+
routes: [
|
|
746
|
+
{ pattern: "api.example.com/at/a/path", custom_domain: true },
|
|
747
|
+
],
|
|
748
|
+
});
|
|
749
|
+
writeWorkerSource();
|
|
750
|
+
await expect(
|
|
751
|
+
runWrangler("publish ./index")
|
|
752
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
753
|
+
`"Cannot use \\"api.example.com/at/a/path\\" as a Custom Domain; paths are not allowed"`
|
|
754
|
+
);
|
|
755
|
+
});
|
|
756
|
+
|
|
757
|
+
it("should not retry publish on error if user does not confirm", async () => {
|
|
758
|
+
writeWranglerToml({
|
|
759
|
+
routes: [{ pattern: "api.example.com", custom_domain: true }],
|
|
760
|
+
});
|
|
761
|
+
writeWorkerSource();
|
|
762
|
+
mockUpdateWorkerRequest({ enabled: false });
|
|
763
|
+
mockUploadWorkerRequest({ expectedType: "esm" });
|
|
764
|
+
mockPublishCustomDomainsRequestConflictWithoutOverride({
|
|
765
|
+
dnsRecordConflicts: true,
|
|
766
|
+
domains: [{ hostname: "api.example.com" }],
|
|
767
|
+
});
|
|
768
|
+
mockConfirm({
|
|
769
|
+
text: `You already have conflicting DNS records for these domains: "api.example.com"\nUpdate them to point to this script instead?`,
|
|
770
|
+
result: false,
|
|
771
|
+
});
|
|
772
|
+
await runWrangler("publish ./index");
|
|
773
|
+
expect(std.out).toContain(
|
|
774
|
+
'Publishing to Custom Domain "api.example.com" was skipped, fix conflict and try again'
|
|
775
|
+
);
|
|
776
|
+
});
|
|
777
|
+
});
|
|
778
|
+
|
|
648
779
|
it.todo("should error if it's a workers.dev route");
|
|
649
780
|
});
|
|
650
781
|
|
|
@@ -906,6 +1037,7 @@ export default {};`
|
|
|
906
1037
|
"default",
|
|
907
1038
|
]
|
|
908
1039
|
`);
|
|
1040
|
+
|
|
909
1041
|
expect(std).toMatchInlineSnapshot(`
|
|
910
1042
|
Object {
|
|
911
1043
|
"debug": "",
|
|
@@ -926,7 +1058,7 @@ export const def = "show me the money";
|
|
|
926
1058
|
addEventListener('fetch', event => {});`
|
|
927
1059
|
);
|
|
928
1060
|
|
|
929
|
-
await runWrangler("publish index.js --dry-run --outdir out
|
|
1061
|
+
await runWrangler("publish index.js --dry-run --outdir out");
|
|
930
1062
|
|
|
931
1063
|
expect(
|
|
932
1064
|
(
|
|
@@ -2548,18 +2680,66 @@ addEventListener('fetch', event => {});`
|
|
|
2548
2680
|
},
|
|
2549
2681
|
});
|
|
2550
2682
|
|
|
2551
|
-
await expect(
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2683
|
+
await expect(runWrangler("publish index.js")).rejects
|
|
2684
|
+
.toThrowErrorMatchingInlineSnapshot(`
|
|
2685
|
+
"The expected output file at \\"index.js\\" was not found after running custom build: node -e \\"console.log('custom build');\\".
|
|
2686
|
+
The \`main\` property in wrangler.toml should point to the file generated by the custom build."
|
|
2687
|
+
`);
|
|
2556
2688
|
expect(std.out).toMatchInlineSnapshot(`
|
|
2557
2689
|
"Running custom build: node -e \\"console.log('custom build');\\"
|
|
2558
2690
|
|
|
2559
2691
|
[32mIf you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new.[0m"
|
|
2560
2692
|
`);
|
|
2561
2693
|
expect(std.err).toMatchInlineSnapshot(`
|
|
2562
|
-
"[31mX [41;31m[[41;97mERROR[41;31m][0m [
|
|
2694
|
+
"[31mX [41;31m[[41;97mERROR[41;31m][0m [1mThe expected output file at \\"index.js\\" was not found after running custom build: node -e \\"console.log('custom build');\\".[0m
|
|
2695
|
+
|
|
2696
|
+
The \`main\` property in wrangler.toml should point to the file generated by the custom build.
|
|
2697
|
+
|
|
2698
|
+
"
|
|
2699
|
+
`);
|
|
2700
|
+
expect(std.warn).toMatchInlineSnapshot(`""`);
|
|
2701
|
+
});
|
|
2702
|
+
|
|
2703
|
+
it("should throw an error if the entry is a directory after the build finishes", async () => {
|
|
2704
|
+
writeWranglerToml({
|
|
2705
|
+
main: "./",
|
|
2706
|
+
build: {
|
|
2707
|
+
command: `node -e "console.log('custom build');"`,
|
|
2708
|
+
},
|
|
2709
|
+
});
|
|
2710
|
+
|
|
2711
|
+
fs.writeFileSync("./worker.js", "some content", "utf-8");
|
|
2712
|
+
fs.mkdirSync("./dist");
|
|
2713
|
+
fs.writeFileSync("./dist/index.ts", "some content", "utf-8");
|
|
2714
|
+
|
|
2715
|
+
await expect(runWrangler("publish")).rejects
|
|
2716
|
+
.toThrowErrorMatchingInlineSnapshot(`
|
|
2717
|
+
"The expected output file at \\".\\" was not found after running custom build: node -e \\"console.log('custom build');\\".
|
|
2718
|
+
The \`main\` property in wrangler.toml should point to the file generated by the custom build.
|
|
2719
|
+
The provided entry-point path, \\".\\", points to a directory, rather than a file.
|
|
2720
|
+
|
|
2721
|
+
Did you mean to set the main field to one of:
|
|
2722
|
+
\`\`\`
|
|
2723
|
+
main = \\"./worker.js\\"
|
|
2724
|
+
main = \\"./dist/index.ts\\"
|
|
2725
|
+
\`\`\`"
|
|
2726
|
+
`);
|
|
2727
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
2728
|
+
"Running custom build: node -e \\"console.log('custom build');\\"
|
|
2729
|
+
|
|
2730
|
+
[32mIf you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new.[0m"
|
|
2731
|
+
`);
|
|
2732
|
+
expect(std.err).toMatchInlineSnapshot(`
|
|
2733
|
+
"[31mX [41;31m[[41;97mERROR[41;31m][0m [1mThe expected output file at \\".\\" was not found after running custom build: node -e \\"console.log('custom build');\\".[0m
|
|
2734
|
+
|
|
2735
|
+
The \`main\` property in wrangler.toml should point to the file generated by the custom build.
|
|
2736
|
+
The provided entry-point path, \\".\\", points to a directory, rather than a file.
|
|
2737
|
+
|
|
2738
|
+
Did you mean to set the main field to one of:
|
|
2739
|
+
\`\`\`
|
|
2740
|
+
main = \\"./worker.js\\"
|
|
2741
|
+
main = \\"./dist/index.ts\\"
|
|
2742
|
+
\`\`\`
|
|
2563
2743
|
|
|
2564
2744
|
"
|
|
2565
2745
|
`);
|
|
@@ -3057,6 +3237,7 @@ addEventListener('fetch', event => {});`
|
|
|
3057
3237
|
name: "DURABLE_OBJECT_TWO",
|
|
3058
3238
|
class_name: "AnotherDurableObject",
|
|
3059
3239
|
script_name: "another-durable-object-worker",
|
|
3240
|
+
environment: "staging",
|
|
3060
3241
|
},
|
|
3061
3242
|
],
|
|
3062
3243
|
},
|
|
@@ -3115,6 +3296,12 @@ addEventListener('fetch', event => {});`
|
|
|
3115
3296
|
mockUploadWorkerRequest({
|
|
3116
3297
|
expectedType: "sw",
|
|
3117
3298
|
expectedBindings: [
|
|
3299
|
+
{ json: 123, name: "ENV_VAR_ONE", type: "json" },
|
|
3300
|
+
{
|
|
3301
|
+
name: "ENV_VAR_TWO",
|
|
3302
|
+
text: "Hello, I'm an environment variable",
|
|
3303
|
+
type: "plain_text",
|
|
3304
|
+
},
|
|
3118
3305
|
{
|
|
3119
3306
|
name: "KV_NAMESPACE_ONE",
|
|
3120
3307
|
namespace_id: "kv-ns-one-id",
|
|
@@ -3133,6 +3320,7 @@ addEventListener('fetch', event => {});`
|
|
|
3133
3320
|
},
|
|
3134
3321
|
{
|
|
3135
3322
|
class_name: "AnotherDurableObject",
|
|
3323
|
+
environment: "staging",
|
|
3136
3324
|
name: "DURABLE_OBJECT_TWO",
|
|
3137
3325
|
script_name: "another-durable-object-worker",
|
|
3138
3326
|
type: "durable_object_namespace",
|
|
@@ -3147,12 +3335,6 @@ addEventListener('fetch', event => {});`
|
|
|
3147
3335
|
name: "R2_BUCKET_TWO",
|
|
3148
3336
|
type: "r2_bucket",
|
|
3149
3337
|
},
|
|
3150
|
-
{ json: 123, name: "ENV_VAR_ONE", type: "json" },
|
|
3151
|
-
{
|
|
3152
|
-
name: "ENV_VAR_TWO",
|
|
3153
|
-
text: "Hello, I'm an environment variable",
|
|
3154
|
-
type: "plain_text",
|
|
3155
|
-
},
|
|
3156
3338
|
{
|
|
3157
3339
|
name: "WASM_MODULE_ONE",
|
|
3158
3340
|
part: "WASM_MODULE_ONE",
|
|
@@ -4074,6 +4256,47 @@ addEventListener('fetch', event => {});`
|
|
|
4074
4256
|
});
|
|
4075
4257
|
});
|
|
4076
4258
|
|
|
4259
|
+
describe("[services]", () => {
|
|
4260
|
+
it("should support service bindings", async () => {
|
|
4261
|
+
writeWranglerToml({
|
|
4262
|
+
services: [
|
|
4263
|
+
{
|
|
4264
|
+
binding: "FOO",
|
|
4265
|
+
service: "foo-service",
|
|
4266
|
+
environment: "production",
|
|
4267
|
+
},
|
|
4268
|
+
],
|
|
4269
|
+
});
|
|
4270
|
+
writeWorkerSource();
|
|
4271
|
+
mockSubDomainRequest();
|
|
4272
|
+
mockUploadWorkerRequest({
|
|
4273
|
+
expectedBindings: [
|
|
4274
|
+
{
|
|
4275
|
+
type: "service",
|
|
4276
|
+
name: "FOO",
|
|
4277
|
+
service: "foo-service",
|
|
4278
|
+
environment: "production",
|
|
4279
|
+
},
|
|
4280
|
+
],
|
|
4281
|
+
});
|
|
4282
|
+
|
|
4283
|
+
await runWrangler("publish index.js");
|
|
4284
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
4285
|
+
"Uploaded test-name (TIMINGS)
|
|
4286
|
+
Published test-name (TIMINGS)
|
|
4287
|
+
test-name.test-sub-domain.workers.dev"
|
|
4288
|
+
`);
|
|
4289
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
4290
|
+
expect(std.warn).toMatchInlineSnapshot(`
|
|
4291
|
+
"[33m▲ [43;33m[[43;30mWARNING[43;33m][0m [1mProcessing wrangler.toml configuration:[0m
|
|
4292
|
+
|
|
4293
|
+
- \\"services\\" fields are experimental and may change or break at any time.
|
|
4294
|
+
|
|
4295
|
+
"
|
|
4296
|
+
`);
|
|
4297
|
+
});
|
|
4298
|
+
});
|
|
4299
|
+
|
|
4077
4300
|
describe("[unsafe]", () => {
|
|
4078
4301
|
it("should warn if using unsafe bindings", async () => {
|
|
4079
4302
|
writeWranglerToml({
|
|
@@ -4576,8 +4799,16 @@ addEventListener('fetch', event => {});`
|
|
|
4576
4799
|
|
|
4577
4800
|
describe("--dry-run", () => {
|
|
4578
4801
|
it("should not publish the worker if --dry-run is specified", async () => {
|
|
4579
|
-
writeWranglerToml(
|
|
4802
|
+
writeWranglerToml({
|
|
4803
|
+
// add a durable object with migrations
|
|
4804
|
+
// to make sure we _don't_ fetch migration status
|
|
4805
|
+
durable_objects: {
|
|
4806
|
+
bindings: [{ name: "NAME", class_name: "SomeClass" }],
|
|
4807
|
+
},
|
|
4808
|
+
migrations: [{ tag: "v1", new_classes: ["SomeClass"] }],
|
|
4809
|
+
});
|
|
4580
4810
|
writeWorkerSource();
|
|
4811
|
+
process.env.CLOUDFLARE_ACCOUNT_ID = "";
|
|
4581
4812
|
await runWrangler("publish index.js --dry-run");
|
|
4582
4813
|
expect(std).toMatchInlineSnapshot(`
|
|
4583
4814
|
Object {
|
|
@@ -4607,6 +4838,27 @@ addEventListener('fetch', event => {});`
|
|
|
4607
4838
|
`);
|
|
4608
4839
|
});
|
|
4609
4840
|
|
|
4841
|
+
it("should recommend node compatibility mode when using node builtins and node-compat isn't enabled", async () => {
|
|
4842
|
+
writeWranglerToml();
|
|
4843
|
+
fs.writeFileSync(
|
|
4844
|
+
"index.js",
|
|
4845
|
+
`
|
|
4846
|
+
import path from 'path';
|
|
4847
|
+
console.log(path.join("some/path/to", "a/file.txt"));
|
|
4848
|
+
export default {}
|
|
4849
|
+
`
|
|
4850
|
+
);
|
|
4851
|
+
let err: Error | undefined;
|
|
4852
|
+
try {
|
|
4853
|
+
await runWrangler("publish index.js --dry-run"); // expecting this to throw, as node compatibility isn't enabled
|
|
4854
|
+
} catch (e) {
|
|
4855
|
+
err = e as Error;
|
|
4856
|
+
}
|
|
4857
|
+
expect(err?.message).toMatch(
|
|
4858
|
+
`Detected a Node builtin module import while Node compatibility is disabled.\nAdd node_compat = true to your wrangler.toml file to enable Node compatibility.`
|
|
4859
|
+
);
|
|
4860
|
+
});
|
|
4861
|
+
|
|
4610
4862
|
it("should polyfill node builtins when enabled", async () => {
|
|
4611
4863
|
writeWranglerToml();
|
|
4612
4864
|
fs.writeFileSync(
|
|
@@ -4801,6 +5053,102 @@ function mockPublishRoutesRequest({
|
|
|
4801
5053
|
);
|
|
4802
5054
|
}
|
|
4803
5055
|
|
|
5056
|
+
function mockPublishCustomDomainsRequest({
|
|
5057
|
+
publishFlags,
|
|
5058
|
+
domains = [],
|
|
5059
|
+
env = undefined,
|
|
5060
|
+
legacyEnv = false,
|
|
5061
|
+
}: {
|
|
5062
|
+
publishFlags: {
|
|
5063
|
+
override_scope: boolean;
|
|
5064
|
+
override_existing_origin: boolean;
|
|
5065
|
+
override_existing_dns_record: boolean;
|
|
5066
|
+
};
|
|
5067
|
+
domains: Array<
|
|
5068
|
+
{ hostname: string } & ({ zone_id?: string } | { zone_name?: string })
|
|
5069
|
+
>;
|
|
5070
|
+
env?: string | undefined;
|
|
5071
|
+
legacyEnv?: boolean | undefined;
|
|
5072
|
+
}) {
|
|
5073
|
+
const servicesOrScripts = env && !legacyEnv ? "services" : "scripts";
|
|
5074
|
+
const environment = env && !legacyEnv ? "/environments/:envName" : "";
|
|
5075
|
+
|
|
5076
|
+
setMockResponse(
|
|
5077
|
+
`/accounts/:accountId/workers/${servicesOrScripts}/:scriptName${environment}/domains`,
|
|
5078
|
+
"PUT",
|
|
5079
|
+
([_url, accountId, scriptName, envName], { body }) => {
|
|
5080
|
+
expect(accountId).toEqual("some-account-id");
|
|
5081
|
+
expect(scriptName).toEqual(
|
|
5082
|
+
legacyEnv && env ? `test-name-${env}` : "test-name"
|
|
5083
|
+
);
|
|
5084
|
+
if (!legacyEnv) {
|
|
5085
|
+
expect(envName).toEqual(env);
|
|
5086
|
+
}
|
|
5087
|
+
|
|
5088
|
+
expect(JSON.parse(body as string)).toEqual({
|
|
5089
|
+
...publishFlags,
|
|
5090
|
+
origins: domains,
|
|
5091
|
+
});
|
|
5092
|
+
|
|
5093
|
+
return null;
|
|
5094
|
+
}
|
|
5095
|
+
);
|
|
5096
|
+
}
|
|
5097
|
+
|
|
5098
|
+
function mockPublishCustomDomainsRequestConflictWithoutOverride({
|
|
5099
|
+
domains = [],
|
|
5100
|
+
originConflicts = false,
|
|
5101
|
+
dnsRecordConflicts = false,
|
|
5102
|
+
env = undefined,
|
|
5103
|
+
legacyEnv = false,
|
|
5104
|
+
}: {
|
|
5105
|
+
originConflicts?: boolean;
|
|
5106
|
+
dnsRecordConflicts?: boolean;
|
|
5107
|
+
domains: Array<
|
|
5108
|
+
{ hostname: string } & ({ zone_id?: string } | { zone_name?: string })
|
|
5109
|
+
>;
|
|
5110
|
+
env?: string | undefined;
|
|
5111
|
+
legacyEnv?: boolean | undefined;
|
|
5112
|
+
}) {
|
|
5113
|
+
const servicesOrScripts = env && !legacyEnv ? "services" : "scripts";
|
|
5114
|
+
const environment = env && !legacyEnv ? "/environments/:envName" : "";
|
|
5115
|
+
|
|
5116
|
+
setMockRawResponse(
|
|
5117
|
+
`/accounts/:accountId/workers/${servicesOrScripts}/:scriptName${environment}/domains`,
|
|
5118
|
+
"PUT",
|
|
5119
|
+
([_url, accountId, scriptName, envName], { body }) => {
|
|
5120
|
+
expect(accountId).toEqual("some-account-id");
|
|
5121
|
+
expect(scriptName).toEqual(
|
|
5122
|
+
legacyEnv && env ? `test-name-${env}` : "test-name"
|
|
5123
|
+
);
|
|
5124
|
+
if (!legacyEnv) {
|
|
5125
|
+
expect(envName).toEqual(env);
|
|
5126
|
+
}
|
|
5127
|
+
|
|
5128
|
+
const parsed = JSON.parse(body as string);
|
|
5129
|
+
expect(parsed.origins).toEqual(domains);
|
|
5130
|
+
|
|
5131
|
+
if (originConflicts && !parsed.override_existing_origin) {
|
|
5132
|
+
return createFetchResult(null, false, [
|
|
5133
|
+
{
|
|
5134
|
+
code: 100116,
|
|
5135
|
+
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`,
|
|
5136
|
+
},
|
|
5137
|
+
]);
|
|
5138
|
+
}
|
|
5139
|
+
if (dnsRecordConflicts && !parsed.override_existing_dns_record) {
|
|
5140
|
+
return createFetchResult(null, false, [
|
|
5141
|
+
{
|
|
5142
|
+
code: 100117,
|
|
5143
|
+
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`,
|
|
5144
|
+
},
|
|
5145
|
+
]);
|
|
5146
|
+
}
|
|
5147
|
+
return createFetchResult(null, true);
|
|
5148
|
+
}
|
|
5149
|
+
);
|
|
5150
|
+
}
|
|
5151
|
+
|
|
4804
5152
|
/** Create a mock handler for the request to get a list of all KV namespaces. */
|
|
4805
5153
|
function mockListKVNamespacesRequest(...namespaces: KVNamespaceInfo[]) {
|
|
4806
5154
|
setMockResponse(
|
package/src/__tests__/r2.test.ts
CHANGED
|
@@ -17,6 +17,33 @@ describe("wrangler", () => {
|
|
|
17
17
|
|
|
18
18
|
describe("r2", () => {
|
|
19
19
|
describe("bucket", () => {
|
|
20
|
+
it("should show the correct help when an invalid command is passed", async () => {
|
|
21
|
+
await expect(() =>
|
|
22
|
+
runWrangler("r2 bucket foo")
|
|
23
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(`"Unknown argument: foo"`);
|
|
24
|
+
expect(std.err).toMatchInlineSnapshot(`
|
|
25
|
+
"[31mX [41;31m[[41;97mERROR[41;31m][0m [1mUnknown argument: foo[0m
|
|
26
|
+
|
|
27
|
+
"
|
|
28
|
+
`);
|
|
29
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
30
|
+
"
|
|
31
|
+
wrangler r2 bucket
|
|
32
|
+
|
|
33
|
+
Manage R2 buckets
|
|
34
|
+
|
|
35
|
+
Commands:
|
|
36
|
+
wrangler r2 bucket create <name> Create a new R2 bucket
|
|
37
|
+
wrangler r2 bucket list List R2 buckets
|
|
38
|
+
wrangler r2 bucket delete <name> Delete an R2 bucket
|
|
39
|
+
|
|
40
|
+
Flags:
|
|
41
|
+
-c, --config Path to .toml configuration file [string]
|
|
42
|
+
-h, --help Show help [boolean]
|
|
43
|
+
-v, --version Show version number [boolean]"
|
|
44
|
+
`);
|
|
45
|
+
});
|
|
46
|
+
|
|
20
47
|
describe("list", () => {
|
|
21
48
|
function mockListRequest(buckets: R2BucketInfo[]) {
|
|
22
49
|
const requests = { count: 0 };
|
|
@@ -69,10 +96,7 @@ describe("wrangler", () => {
|
|
|
69
96
|
);
|
|
70
97
|
expect(std.out).toMatchInlineSnapshot(`
|
|
71
98
|
"
|
|
72
|
-
|
|
73
|
-
`);
|
|
74
|
-
expect(std.err).toMatchInlineSnapshot(`
|
|
75
|
-
"wrangler r2 bucket create <name>
|
|
99
|
+
wrangler r2 bucket create <name>
|
|
76
100
|
|
|
77
101
|
Create a new R2 bucket
|
|
78
102
|
|
|
@@ -80,11 +104,12 @@ describe("wrangler", () => {
|
|
|
80
104
|
name The name of the new bucket [string] [required]
|
|
81
105
|
|
|
82
106
|
Flags:
|
|
83
|
-
-c, --config
|
|
84
|
-
-h, --help
|
|
85
|
-
-v, --version
|
|
86
|
-
|
|
87
|
-
|
|
107
|
+
-c, --config Path to .toml configuration file [string]
|
|
108
|
+
-h, --help Show help [boolean]
|
|
109
|
+
-v, --version Show version number [boolean]"
|
|
110
|
+
`);
|
|
111
|
+
expect(std.err).toMatchInlineSnapshot(`
|
|
112
|
+
"[31mX [41;31m[[41;97mERROR[41;31m][0m [1mNot enough non-option arguments: got 0, need at least 1[0m
|
|
88
113
|
|
|
89
114
|
"
|
|
90
115
|
`);
|
|
@@ -98,10 +123,7 @@ describe("wrangler", () => {
|
|
|
98
123
|
);
|
|
99
124
|
expect(std.out).toMatchInlineSnapshot(`
|
|
100
125
|
"
|
|
101
|
-
|
|
102
|
-
`);
|
|
103
|
-
expect(std.err).toMatchInlineSnapshot(`
|
|
104
|
-
"wrangler r2 bucket create <name>
|
|
126
|
+
wrangler r2 bucket create <name>
|
|
105
127
|
|
|
106
128
|
Create a new R2 bucket
|
|
107
129
|
|
|
@@ -109,11 +131,12 @@ describe("wrangler", () => {
|
|
|
109
131
|
name The name of the new bucket [string] [required]
|
|
110
132
|
|
|
111
133
|
Flags:
|
|
112
|
-
-c, --config
|
|
113
|
-
-h, --help
|
|
114
|
-
-v, --version
|
|
115
|
-
|
|
116
|
-
|
|
134
|
+
-c, --config Path to .toml configuration file [string]
|
|
135
|
+
-h, --help Show help [boolean]
|
|
136
|
+
-v, --version Show version number [boolean]"
|
|
137
|
+
`);
|
|
138
|
+
expect(std.err).toMatchInlineSnapshot(`
|
|
139
|
+
"[31mX [41;31m[[41;97mERROR[41;31m][0m [1mUnknown arguments: def, ghi[0m
|
|
117
140
|
|
|
118
141
|
"
|
|
119
142
|
`);
|
|
@@ -153,10 +176,7 @@ describe("wrangler", () => {
|
|
|
153
176
|
);
|
|
154
177
|
expect(std.out).toMatchInlineSnapshot(`
|
|
155
178
|
"
|
|
156
|
-
|
|
157
|
-
`);
|
|
158
|
-
expect(std.err).toMatchInlineSnapshot(`
|
|
159
|
-
"wrangler r2 bucket delete <name>
|
|
179
|
+
wrangler r2 bucket delete <name>
|
|
160
180
|
|
|
161
181
|
Delete an R2 bucket
|
|
162
182
|
|
|
@@ -164,11 +184,12 @@ describe("wrangler", () => {
|
|
|
164
184
|
name The name of the bucket to delete [string] [required]
|
|
165
185
|
|
|
166
186
|
Flags:
|
|
167
|
-
-c, --config
|
|
168
|
-
-h, --help
|
|
169
|
-
-v, --version
|
|
170
|
-
|
|
171
|
-
|
|
187
|
+
-c, --config Path to .toml configuration file [string]
|
|
188
|
+
-h, --help Show help [boolean]
|
|
189
|
+
-v, --version Show version number [boolean]"
|
|
190
|
+
`);
|
|
191
|
+
expect(std.err).toMatchInlineSnapshot(`
|
|
192
|
+
"[31mX [41;31m[[41;97mERROR[41;31m][0m [1mNot enough non-option arguments: got 0, need at least 1[0m
|
|
172
193
|
|
|
173
194
|
"
|
|
174
195
|
`);
|
|
@@ -182,10 +203,7 @@ describe("wrangler", () => {
|
|
|
182
203
|
);
|
|
183
204
|
expect(std.out).toMatchInlineSnapshot(`
|
|
184
205
|
"
|
|
185
|
-
|
|
186
|
-
`);
|
|
187
|
-
expect(std.err).toMatchInlineSnapshot(`
|
|
188
|
-
"wrangler r2 bucket delete <name>
|
|
206
|
+
wrangler r2 bucket delete <name>
|
|
189
207
|
|
|
190
208
|
Delete an R2 bucket
|
|
191
209
|
|
|
@@ -193,11 +211,12 @@ describe("wrangler", () => {
|
|
|
193
211
|
name The name of the bucket to delete [string] [required]
|
|
194
212
|
|
|
195
213
|
Flags:
|
|
196
|
-
-c, --config
|
|
197
|
-
-h, --help
|
|
198
|
-
-v, --version
|
|
199
|
-
|
|
200
|
-
|
|
214
|
+
-c, --config Path to .toml configuration file [string]
|
|
215
|
+
-h, --help Show help [boolean]
|
|
216
|
+
-v, --version Show version number [boolean]"
|
|
217
|
+
`);
|
|
218
|
+
expect(std.err).toMatchInlineSnapshot(`
|
|
219
|
+
"[31mX [41;31m[[41;97mERROR[41;31m][0m [1mUnknown arguments: def, ghi[0m
|
|
201
220
|
|
|
202
221
|
"
|
|
203
222
|
`);
|
|
@@ -60,6 +60,22 @@ describe("wrangler secret", () => {
|
|
|
60
60
|
describe("interactive", () => {
|
|
61
61
|
useMockStdin({ isTTY: true });
|
|
62
62
|
|
|
63
|
+
it("should trim stdin secret value", async () => {
|
|
64
|
+
mockPrompt({
|
|
65
|
+
text: "Enter a secret value:",
|
|
66
|
+
type: "password",
|
|
67
|
+
result: `hunter2
|
|
68
|
+
`,
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
mockPutRequest({ name: `secret-name`, text: `hunter2` });
|
|
72
|
+
await runWrangler("secret put secret-name --name script-name");
|
|
73
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
74
|
+
"🌀 Creating the secret for script script-name
|
|
75
|
+
✨ Success! Uploaded secret secret-name"
|
|
76
|
+
`);
|
|
77
|
+
});
|
|
78
|
+
|
|
63
79
|
it("should create a secret", async () => {
|
|
64
80
|
mockPrompt({
|
|
65
81
|
text: "Enter a secret value:",
|
|
@@ -146,6 +162,25 @@ describe("wrangler secret", () => {
|
|
|
146
162
|
describe("non-interactive", () => {
|
|
147
163
|
const mockStdIn = useMockStdin({ isTTY: false });
|
|
148
164
|
|
|
165
|
+
it("should trim stdin secret value, from piped input", async () => {
|
|
166
|
+
mockPutRequest({ name: "the-key", text: "the-secret" });
|
|
167
|
+
// Pipe the secret in as three chunks to test that we reconstitute it correctly.
|
|
168
|
+
mockStdIn.send(
|
|
169
|
+
`the`,
|
|
170
|
+
`-`,
|
|
171
|
+
`secret
|
|
172
|
+
` // whitespace & newline being removed
|
|
173
|
+
);
|
|
174
|
+
await runWrangler("secret put the-key --name script-name");
|
|
175
|
+
|
|
176
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
177
|
+
"🌀 Creating the secret for script script-name
|
|
178
|
+
✨ Success! Uploaded secret the-key"
|
|
179
|
+
`);
|
|
180
|
+
expect(std.warn).toMatchInlineSnapshot(`""`);
|
|
181
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
182
|
+
});
|
|
183
|
+
|
|
149
184
|
it("should create a secret, from piped input", async () => {
|
|
150
185
|
mockPutRequest({ name: "the-key", text: "the-secret" });
|
|
151
186
|
// Pipe the secret in as three chunks to test that we reconstitute it correctly.
|