wrangler 2.0.21 → 2.0.24
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/README.md +20 -2
- package/bin/wrangler.js +1 -1
- package/miniflare-dist/index.mjs +527 -5
- package/package.json +18 -5
- package/src/__tests__/configuration.test.ts +88 -16
- package/src/__tests__/dev.test.tsx +95 -4
- package/src/__tests__/generate.test.ts +93 -0
- package/src/__tests__/helpers/mock-cfetch.ts +54 -2
- package/src/__tests__/index.test.ts +10 -27
- package/src/__tests__/jest.setup.ts +31 -1
- package/src/__tests__/kv.test.ts +82 -61
- package/src/__tests__/metrics.test.ts +35 -0
- package/src/__tests__/publish.test.ts +573 -254
- package/src/__tests__/r2.test.ts +155 -71
- package/src/__tests__/user.test.ts +1 -0
- package/src/__tests__/validate-dev-props.test.ts +56 -0
- package/src/__tests__/version.test.ts +35 -0
- package/src/__tests__/whoami.test.tsx +60 -1
- package/src/api/dev.ts +43 -9
- package/src/bundle.ts +297 -37
- package/src/cfetch/internal.ts +34 -2
- package/src/config/config.ts +14 -2
- package/src/config/environment.ts +40 -8
- package/src/config/index.ts +13 -0
- package/src/config/validation.ts +110 -8
- package/src/create-worker-preview.ts +3 -1
- package/src/create-worker-upload-form.ts +25 -0
- package/src/dev/dev.tsx +135 -31
- package/src/dev/local.tsx +48 -20
- package/src/dev/remote.tsx +39 -12
- package/src/dev/use-esbuild.ts +25 -0
- package/src/dev/validate-dev-props.ts +31 -0
- package/src/dev-registry.tsx +157 -0
- package/src/dev.tsx +137 -65
- package/src/generate.ts +112 -14
- package/src/index.tsx +222 -7
- package/src/inspect.ts +93 -5
- package/src/metrics/index.ts +1 -0
- package/src/metrics/is-ci.ts +14 -0
- package/src/metrics/metrics-config.ts +19 -2
- package/src/metrics/metrics-dispatcher.ts +1 -0
- package/src/metrics/metrics-usage-headers.ts +24 -0
- package/src/metrics/send-event.ts +2 -2
- package/src/miniflare-cli/assets.ts +543 -0
- package/src/miniflare-cli/index.ts +36 -4
- package/src/module-collection.ts +3 -3
- package/src/pages/constants.ts +1 -0
- package/src/pages/deployments.tsx +1 -1
- package/src/pages/dev.tsx +85 -639
- package/src/pages/publish.tsx +1 -1
- package/src/pages/upload.tsx +32 -13
- package/src/publish.ts +139 -112
- package/src/r2.ts +68 -0
- package/src/user/choose-account.tsx +20 -11
- package/src/user/user.tsx +20 -2
- package/src/whoami.tsx +79 -1
- package/src/worker.ts +12 -0
- package/templates/first-party-worker-module-facade.ts +18 -0
- package/templates/format-dev-errors.ts +32 -0
- package/templates/pages-shim.ts +9 -0
- package/templates/{static-asset-facade.js → serve-static-assets.ts} +21 -7
- package/templates/service-bindings-module-facade.js +51 -0
- package/templates/service-bindings-sw-facade.js +39 -0
- package/wrangler-dist/cli.d.ts +32 -3
- package/wrangler-dist/cli.js +45257 -25209
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wrangler",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.24",
|
|
4
4
|
"description": "Command-line interface for all things Cloudflare Workers",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"wrangler",
|
|
@@ -53,14 +53,21 @@
|
|
|
53
53
|
"bundle": "node -r esbuild-register scripts/bundle.ts",
|
|
54
54
|
"check:type": "tsc",
|
|
55
55
|
"clean": "rm -rf wrangler-dist miniflare-dist emitted-types",
|
|
56
|
-
"dev": "npm run clean && concurrently -c black,blue 'npm run bundle -- --watch' 'npm run check:type -- --watch --preserveWatchOutput'",
|
|
56
|
+
"dev": "npm run clean && concurrently -c black,blue --kill-others-on-fail false 'npm run bundle -- --watch' 'npm run check:type -- --watch --preserveWatchOutput'",
|
|
57
57
|
"emit-types": "tsc -p tsconfig.emit.json && node -r esbuild-register scripts/emit-types.ts",
|
|
58
58
|
"prepublishOnly": "SOURCEMAPS=false npm run build",
|
|
59
59
|
"start": "npm run bundle && NODE_OPTIONS=--enable-source-maps ./bin/wrangler.js",
|
|
60
60
|
"test": "jest --silent=false --verbose=true",
|
|
61
|
-
"test-watch": "npm run test -- --runInBand --testTimeout=50000 --watch"
|
|
61
|
+
"test-watch": "npm run test -- --runInBand --testTimeout=50000 --watch",
|
|
62
|
+
"test:ci": "npm run test -- --verbose=true --coverage"
|
|
62
63
|
},
|
|
63
64
|
"jest": {
|
|
65
|
+
"coverageReporters": [
|
|
66
|
+
"json",
|
|
67
|
+
"html",
|
|
68
|
+
"text",
|
|
69
|
+
"cobertura"
|
|
70
|
+
],
|
|
64
71
|
"moduleNameMapper": {
|
|
65
72
|
"clipboardy": "<rootDir>/src/__tests__/helpers/clipboardy-mock.js",
|
|
66
73
|
"miniflare/cli": "<rootDir>/../../node_modules/miniflare/dist/src/cli.js"
|
|
@@ -88,17 +95,20 @@
|
|
|
88
95
|
"@esbuild-plugins/node-globals-polyfill": "^0.1.1",
|
|
89
96
|
"@esbuild-plugins/node-modules-polyfill": "^0.1.4",
|
|
90
97
|
"blake3-wasm": "^2.1.5",
|
|
91
|
-
"
|
|
98
|
+
"chokidar": "^3.5.3",
|
|
99
|
+
"esbuild": "0.14.51",
|
|
92
100
|
"miniflare": "^2.6.0",
|
|
93
101
|
"nanoid": "^3.3.3",
|
|
94
102
|
"path-to-regexp": "^6.2.0",
|
|
95
103
|
"selfsigned": "^2.0.1",
|
|
104
|
+
"source-map": "^0.7.4",
|
|
96
105
|
"xxhash-wasm": "^1.0.1"
|
|
97
106
|
},
|
|
98
107
|
"devDependencies": {
|
|
99
108
|
"@iarna/toml": "^3.0.0",
|
|
100
109
|
"@microsoft/api-extractor": "^7.28.3",
|
|
101
110
|
"@types/command-exists": "^1.2.0",
|
|
111
|
+
"@types/express": "^4.17.13",
|
|
102
112
|
"@types/glob-to-regexp": "0.4.1",
|
|
103
113
|
"@types/mime": "^2.0.3",
|
|
104
114
|
"@types/prompts": "^2.0.14",
|
|
@@ -109,14 +119,16 @@
|
|
|
109
119
|
"@types/ws": "^8.5.3",
|
|
110
120
|
"@types/yargs": "^17.0.10",
|
|
111
121
|
"@webcontainer/env": "^1.0.1",
|
|
112
|
-
"
|
|
122
|
+
"body-parser": "^1.20.0",
|
|
113
123
|
"clipboardy": "^3.0.0",
|
|
114
124
|
"cmd-shim": "^4.1.0",
|
|
115
125
|
"command-exists": "^1.2.9",
|
|
116
126
|
"concurrently": "^7.2.2",
|
|
127
|
+
"create-cloudflare": "^1.0.0",
|
|
117
128
|
"devtools-protocol": "^0.0.955664",
|
|
118
129
|
"dotenv": "^16.0.0",
|
|
119
130
|
"execa": "^6.1.0",
|
|
131
|
+
"express": "^4.18.1",
|
|
120
132
|
"faye-websocket": "^0.11.4",
|
|
121
133
|
"finalhandler": "^1.2.0",
|
|
122
134
|
"find-up": "^6.3.0",
|
|
@@ -130,6 +142,7 @@
|
|
|
130
142
|
"ink-table": "^3.0.0",
|
|
131
143
|
"ink-testing-library": "^2.1.0",
|
|
132
144
|
"ink-text-input": "^4.0.3",
|
|
145
|
+
"is-ci": "^3.0.1",
|
|
133
146
|
"jest-fetch-mock": "^3.0.3",
|
|
134
147
|
"jest-websocket-mock": "^2.3.0",
|
|
135
148
|
"mime": "^3.0.0",
|
|
@@ -40,6 +40,10 @@ describe("normalizeAndValidateConfig()", () => {
|
|
|
40
40
|
tsconfig: undefined,
|
|
41
41
|
kv_namespaces: [],
|
|
42
42
|
legacy_env: true,
|
|
43
|
+
logfwdr: {
|
|
44
|
+
bindings: [],
|
|
45
|
+
schema: undefined,
|
|
46
|
+
},
|
|
43
47
|
send_metrics: undefined,
|
|
44
48
|
main: undefined,
|
|
45
49
|
migrations: [],
|
|
@@ -68,6 +72,7 @@ describe("normalizeAndValidateConfig()", () => {
|
|
|
68
72
|
no_bundle: undefined,
|
|
69
73
|
minify: undefined,
|
|
70
74
|
node_compat: undefined,
|
|
75
|
+
first_party_worker: undefined,
|
|
71
76
|
});
|
|
72
77
|
expect(diagnostics.hasErrors()).toBe(false);
|
|
73
78
|
expect(diagnostics.hasWarnings()).toBe(false);
|
|
@@ -463,6 +468,56 @@ describe("normalizeAndValidateConfig()", () => {
|
|
|
463
468
|
});
|
|
464
469
|
|
|
465
470
|
describe("[assets]", () => {
|
|
471
|
+
it("normalizes a string input to an object", () => {
|
|
472
|
+
const { config, diagnostics } = normalizeAndValidateConfig(
|
|
473
|
+
{
|
|
474
|
+
assets: "path/to/assets",
|
|
475
|
+
} as unknown as RawConfig,
|
|
476
|
+
undefined,
|
|
477
|
+
{ env: undefined }
|
|
478
|
+
);
|
|
479
|
+
|
|
480
|
+
expect(config.assets).toMatchInlineSnapshot(`
|
|
481
|
+
Object {
|
|
482
|
+
"browser_TTL": undefined,
|
|
483
|
+
"bucket": "path/to/assets",
|
|
484
|
+
"exclude": Array [],
|
|
485
|
+
"include": Array [],
|
|
486
|
+
"serve_single_page_app": false,
|
|
487
|
+
}
|
|
488
|
+
`);
|
|
489
|
+
expect(diagnostics.hasWarnings()).toBe(true);
|
|
490
|
+
expect(diagnostics.hasErrors()).toBe(false);
|
|
491
|
+
|
|
492
|
+
expect(diagnostics.renderWarnings()).toMatchInlineSnapshot(`
|
|
493
|
+
"Processing wrangler configuration:
|
|
494
|
+
- \\"assets\\" fields are experimental and may change or break at any time."
|
|
495
|
+
`);
|
|
496
|
+
});
|
|
497
|
+
|
|
498
|
+
it("errors when input is not a string or object", () => {
|
|
499
|
+
const { config, diagnostics } = normalizeAndValidateConfig(
|
|
500
|
+
{
|
|
501
|
+
assets: 123,
|
|
502
|
+
} as unknown as RawConfig,
|
|
503
|
+
undefined,
|
|
504
|
+
{ env: undefined }
|
|
505
|
+
);
|
|
506
|
+
|
|
507
|
+
expect(config.assets).toBeUndefined();
|
|
508
|
+
expect(diagnostics.hasWarnings()).toBe(true);
|
|
509
|
+
expect(diagnostics.hasErrors()).toBe(true);
|
|
510
|
+
|
|
511
|
+
expect(diagnostics.renderWarnings()).toMatchInlineSnapshot(`
|
|
512
|
+
"Processing wrangler configuration:
|
|
513
|
+
- \\"assets\\" fields are experimental and may change or break at any time."
|
|
514
|
+
`);
|
|
515
|
+
expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
|
|
516
|
+
"Processing wrangler configuration:
|
|
517
|
+
- Expected the \`assets\` field to be a string or an object, but got number."
|
|
518
|
+
`);
|
|
519
|
+
});
|
|
520
|
+
|
|
466
521
|
it("should error if `assets` config is missing `bucket`", () => {
|
|
467
522
|
const expectedConfig: RawConfig = {
|
|
468
523
|
// @ts-expect-error we're intentionally passing an invalid configuration here
|
|
@@ -478,7 +533,9 @@ describe("normalizeAndValidateConfig()", () => {
|
|
|
478
533
|
{ env: undefined }
|
|
479
534
|
);
|
|
480
535
|
|
|
481
|
-
expect(config).toEqual(
|
|
536
|
+
expect(config.assets).toEqual(
|
|
537
|
+
expect.objectContaining(expectedConfig.assets)
|
|
538
|
+
);
|
|
482
539
|
expect(diagnostics.hasWarnings()).toBe(true);
|
|
483
540
|
expect(diagnostics.hasErrors()).toBe(true);
|
|
484
541
|
|
|
@@ -498,6 +555,8 @@ describe("normalizeAndValidateConfig()", () => {
|
|
|
498
555
|
bucket: "BUCKET",
|
|
499
556
|
include: [222, 333],
|
|
500
557
|
exclude: [444, 555],
|
|
558
|
+
browser_TTL: "not valid",
|
|
559
|
+
serve_single_page_app: "INVALID",
|
|
501
560
|
},
|
|
502
561
|
};
|
|
503
562
|
|
|
@@ -514,12 +573,14 @@ describe("normalizeAndValidateConfig()", () => {
|
|
|
514
573
|
- \\"assets\\" fields are experimental and may change or break at any time."
|
|
515
574
|
`);
|
|
516
575
|
expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
576
|
+
"Processing wrangler configuration:
|
|
577
|
+
- Expected \\"assets.include.[0]\\" to be of type string but got 222.
|
|
578
|
+
- Expected \\"assets.include.[1]\\" to be of type string but got 333.
|
|
579
|
+
- Expected \\"assets.exclude.[0]\\" to be of type string but got 444.
|
|
580
|
+
- Expected \\"assets.exclude.[1]\\" to be of type string but got 555.
|
|
581
|
+
- Expected \\"assets.browser_TTL\\" to be of type number but got \\"not valid\\".
|
|
582
|
+
- Expected \\"assets.serve_single_page_app\\" to be of type boolean but got \\"INVALID\\"."
|
|
583
|
+
`);
|
|
523
584
|
});
|
|
524
585
|
});
|
|
525
586
|
|
|
@@ -858,6 +919,7 @@ describe("normalizeAndValidateConfig()", () => {
|
|
|
858
919
|
no_bundle: true,
|
|
859
920
|
minify: true,
|
|
860
921
|
node_compat: true,
|
|
922
|
+
first_party_worker: true,
|
|
861
923
|
};
|
|
862
924
|
|
|
863
925
|
const { config, diagnostics } = normalizeAndValidateConfig(
|
|
@@ -931,6 +993,7 @@ describe("normalizeAndValidateConfig()", () => {
|
|
|
931
993
|
no_bundle: "INVALID",
|
|
932
994
|
minify: "INVALID",
|
|
933
995
|
node_compat: "INVALID",
|
|
996
|
+
first_party_worker: "INVALID",
|
|
934
997
|
} as unknown as RawEnvironment;
|
|
935
998
|
|
|
936
999
|
const { config, diagnostics } = normalizeAndValidateConfig(
|
|
@@ -997,7 +1060,8 @@ describe("normalizeAndValidateConfig()", () => {
|
|
|
997
1060
|
- The field \\"define.DEF1\\" should be a string but got 1777.
|
|
998
1061
|
- Expected \\"no_bundle\\" to be of type boolean but got \\"INVALID\\".
|
|
999
1062
|
- Expected \\"minify\\" to be of type boolean but got \\"INVALID\\".
|
|
1000
|
-
- Expected \\"node_compat\\" to be of type boolean but got \\"INVALID\\".
|
|
1063
|
+
- Expected \\"node_compat\\" to be of type boolean but got \\"INVALID\\".
|
|
1064
|
+
- Expected \\"first_party_worker\\" to be of type boolean but got \\"INVALID\\"."
|
|
1001
1065
|
`);
|
|
1002
1066
|
});
|
|
1003
1067
|
|
|
@@ -2311,6 +2375,7 @@ describe("normalizeAndValidateConfig()", () => {
|
|
|
2311
2375
|
no_bundle: true,
|
|
2312
2376
|
minify: true,
|
|
2313
2377
|
node_compat: true,
|
|
2378
|
+
first_party_worker: true,
|
|
2314
2379
|
};
|
|
2315
2380
|
|
|
2316
2381
|
const { config, diagnostics } = normalizeAndValidateConfig(
|
|
@@ -2354,6 +2419,7 @@ describe("normalizeAndValidateConfig()", () => {
|
|
|
2354
2419
|
no_bundle: false,
|
|
2355
2420
|
minify: false,
|
|
2356
2421
|
node_compat: false,
|
|
2422
|
+
first_party_worker: false,
|
|
2357
2423
|
};
|
|
2358
2424
|
const rawConfig: RawConfig = {
|
|
2359
2425
|
name: "mock-name",
|
|
@@ -2376,6 +2442,7 @@ describe("normalizeAndValidateConfig()", () => {
|
|
|
2376
2442
|
no_bundle: true,
|
|
2377
2443
|
minify: true,
|
|
2378
2444
|
node_compat: true,
|
|
2445
|
+
first_party_worker: true,
|
|
2379
2446
|
env: {
|
|
2380
2447
|
ENV1: rawEnv,
|
|
2381
2448
|
},
|
|
@@ -2637,6 +2704,7 @@ describe("normalizeAndValidateConfig()", () => {
|
|
|
2637
2704
|
no_bundle: "INVALID",
|
|
2638
2705
|
minify: "INVALID",
|
|
2639
2706
|
node_compat: "INVALID",
|
|
2707
|
+
first_party_worker: "INVALID",
|
|
2640
2708
|
} as unknown as RawEnvironment;
|
|
2641
2709
|
|
|
2642
2710
|
const { config, diagnostics } = normalizeAndValidateConfig(
|
|
@@ -2672,7 +2740,8 @@ describe("normalizeAndValidateConfig()", () => {
|
|
|
2672
2740
|
- Expected \\"usage_model\\" field to be one of [\\"bundled\\",\\"unbound\\"] but got \\"INVALID\\".
|
|
2673
2741
|
- Expected \\"no_bundle\\" to be of type boolean but got \\"INVALID\\".
|
|
2674
2742
|
- Expected \\"minify\\" to be of type boolean but got \\"INVALID\\".
|
|
2675
|
-
- Expected \\"node_compat\\" to be of type boolean but got \\"INVALID\\".
|
|
2743
|
+
- Expected \\"node_compat\\" to be of type boolean but got \\"INVALID\\".
|
|
2744
|
+
- Expected \\"first_party_worker\\" to be of type boolean but got \\"INVALID\\"."
|
|
2676
2745
|
`);
|
|
2677
2746
|
});
|
|
2678
2747
|
|
|
@@ -3670,6 +3739,7 @@ describe("normalizeAndValidateConfig()", () => {
|
|
|
3670
3739
|
it("should remove and warn about deprecated properties", () => {
|
|
3671
3740
|
const environment: RawEnvironment = {
|
|
3672
3741
|
zone_id: "ZONE_ID",
|
|
3742
|
+
"kv-namespaces": "BAD_KV_NAMESPACE",
|
|
3673
3743
|
experimental_services: [
|
|
3674
3744
|
{
|
|
3675
3745
|
name: "mock-name",
|
|
@@ -3695,14 +3765,16 @@ describe("normalizeAndValidateConfig()", () => {
|
|
|
3695
3765
|
expect(diagnostics.hasErrors()).toBe(false);
|
|
3696
3766
|
expect(diagnostics.hasWarnings()).toBe(true);
|
|
3697
3767
|
expect(diagnostics.renderWarnings()).toMatchInlineSnapshot(`
|
|
3698
|
-
|
|
3768
|
+
"Processing wrangler configuration:
|
|
3699
3769
|
|
|
3700
|
-
|
|
3701
|
-
|
|
3702
|
-
|
|
3703
|
-
|
|
3704
|
-
|
|
3705
|
-
|
|
3770
|
+
- \\"env.ENV1\\" environment configuration
|
|
3771
|
+
- [1mDeprecation[0m: \\"kv-namespaces\\":
|
|
3772
|
+
The \\"kv-namespaces\\" field is no longer supported, please rename to \\"kv_namespaces\\"
|
|
3773
|
+
- [1mDeprecation[0m: \\"zone_id\\":
|
|
3774
|
+
This is unnecessary since we can deduce this from routes directly.
|
|
3775
|
+
- [1mDeprecation[0m: \\"experimental_services\\":
|
|
3776
|
+
The \\"experimental_services\\" field is no longer supported. Simply rename the [experimental_services] field to [services]."
|
|
3777
|
+
`);
|
|
3706
3778
|
});
|
|
3707
3779
|
});
|
|
3708
3780
|
|
|
@@ -525,9 +525,9 @@ describe("wrangler dev", () => {
|
|
|
525
525
|
|
|
526
526
|
await expect(runWrangler("dev")).rejects
|
|
527
527
|
.toThrowErrorMatchingInlineSnapshot(`
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
528
|
+
"The expected output file at \\"index.js\\" was not found after running custom build: node -e \\"console.log('custom build');\\".
|
|
529
|
+
The \`main\` property in wrangler.toml should point to the file generated by the custom build."
|
|
530
|
+
`);
|
|
531
531
|
expect(std.out).toMatchInlineSnapshot(`
|
|
532
532
|
"Running custom build: node -e \\"console.log('custom build');\\"
|
|
533
533
|
|
|
@@ -673,6 +673,78 @@ describe("wrangler dev", () => {
|
|
|
673
673
|
});
|
|
674
674
|
});
|
|
675
675
|
|
|
676
|
+
describe("inspector port", () => {
|
|
677
|
+
it("should use 9229 as the default port", async () => {
|
|
678
|
+
writeWranglerToml({
|
|
679
|
+
main: "index.js",
|
|
680
|
+
});
|
|
681
|
+
fs.writeFileSync("index.js", `export default {};`);
|
|
682
|
+
await runWrangler("dev");
|
|
683
|
+
expect((Dev as jest.Mock).mock.calls[0][0].inspectorPort).toEqual(9229);
|
|
684
|
+
expect(std).toMatchInlineSnapshot(`
|
|
685
|
+
Object {
|
|
686
|
+
"debug": "",
|
|
687
|
+
"err": "",
|
|
688
|
+
"out": "",
|
|
689
|
+
"warn": "",
|
|
690
|
+
}
|
|
691
|
+
`);
|
|
692
|
+
});
|
|
693
|
+
|
|
694
|
+
it("should read --inspector-port", async () => {
|
|
695
|
+
writeWranglerToml({
|
|
696
|
+
main: "index.js",
|
|
697
|
+
});
|
|
698
|
+
fs.writeFileSync("index.js", `export default {};`);
|
|
699
|
+
await runWrangler("dev --inspector-port=9999");
|
|
700
|
+
expect((Dev as jest.Mock).mock.calls[0][0].inspectorPort).toEqual(9999);
|
|
701
|
+
expect(std).toMatchInlineSnapshot(`
|
|
702
|
+
Object {
|
|
703
|
+
"debug": "",
|
|
704
|
+
"err": "",
|
|
705
|
+
"out": "",
|
|
706
|
+
"warn": "",
|
|
707
|
+
}
|
|
708
|
+
`);
|
|
709
|
+
});
|
|
710
|
+
|
|
711
|
+
it("should read dev.inspector_port from wrangler.toml", async () => {
|
|
712
|
+
writeWranglerToml({
|
|
713
|
+
main: "index.js",
|
|
714
|
+
dev: {
|
|
715
|
+
inspector_port: 9999,
|
|
716
|
+
},
|
|
717
|
+
});
|
|
718
|
+
fs.writeFileSync("index.js", `export default {};`);
|
|
719
|
+
await runWrangler("dev");
|
|
720
|
+
expect((Dev as jest.Mock).mock.calls[0][0].inspectorPort).toEqual(9999);
|
|
721
|
+
expect(std).toMatchInlineSnapshot(`
|
|
722
|
+
Object {
|
|
723
|
+
"debug": "",
|
|
724
|
+
"err": "",
|
|
725
|
+
"out": "",
|
|
726
|
+
"warn": "",
|
|
727
|
+
}
|
|
728
|
+
`);
|
|
729
|
+
});
|
|
730
|
+
|
|
731
|
+
it("should error if a bad dev.inspector_port config is provided", async () => {
|
|
732
|
+
writeWranglerToml({
|
|
733
|
+
main: "index.js",
|
|
734
|
+
dev: {
|
|
735
|
+
// @ts-expect-error intentionally bad port
|
|
736
|
+
inspector_port: "some string",
|
|
737
|
+
},
|
|
738
|
+
});
|
|
739
|
+
fs.writeFileSync("index.js", `export default {};`);
|
|
740
|
+
await expect(runWrangler("dev")).rejects
|
|
741
|
+
.toThrowErrorMatchingInlineSnapshot(`
|
|
742
|
+
"Processing wrangler.toml configuration:
|
|
743
|
+
- Expected \\"dev.inspector_port\\" to be of type number but got \\"some string\\"."
|
|
744
|
+
`);
|
|
745
|
+
});
|
|
746
|
+
});
|
|
747
|
+
|
|
676
748
|
describe("port", () => {
|
|
677
749
|
it("should default port to 8787 if it is not in use", async () => {
|
|
678
750
|
writeWranglerToml({
|
|
@@ -686,7 +758,7 @@ describe("wrangler dev", () => {
|
|
|
686
758
|
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
687
759
|
});
|
|
688
760
|
|
|
689
|
-
it("should use
|
|
761
|
+
it("should use `port` from `wrangler.toml`, if available", async () => {
|
|
690
762
|
writeWranglerToml({
|
|
691
763
|
main: "index.js",
|
|
692
764
|
dev: {
|
|
@@ -704,6 +776,22 @@ describe("wrangler dev", () => {
|
|
|
704
776
|
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
705
777
|
});
|
|
706
778
|
|
|
779
|
+
it("should error if a bad dev.port config is provided", async () => {
|
|
780
|
+
writeWranglerToml({
|
|
781
|
+
main: "index.js",
|
|
782
|
+
dev: {
|
|
783
|
+
// @ts-expect-error intentionally bad port
|
|
784
|
+
port: "some string",
|
|
785
|
+
},
|
|
786
|
+
});
|
|
787
|
+
fs.writeFileSync("index.js", `export default {};`);
|
|
788
|
+
await expect(runWrangler("dev")).rejects
|
|
789
|
+
.toThrowErrorMatchingInlineSnapshot(`
|
|
790
|
+
"Processing wrangler.toml configuration:
|
|
791
|
+
- Expected \\"dev.port\\" to be of type number but got \\"some string\\"."
|
|
792
|
+
`);
|
|
793
|
+
});
|
|
794
|
+
|
|
707
795
|
it("should use --port command line arg, if provided", async () => {
|
|
708
796
|
writeWranglerToml({
|
|
709
797
|
main: "index.js",
|
|
@@ -950,6 +1038,7 @@ describe("wrangler dev", () => {
|
|
|
950
1038
|
it("should error if config.assets and --site are used together", async () => {
|
|
951
1039
|
writeWranglerToml({
|
|
952
1040
|
main: "./index.js",
|
|
1041
|
+
// @ts-expect-error we allow string inputs here
|
|
953
1042
|
assets: "abc",
|
|
954
1043
|
});
|
|
955
1044
|
fs.writeFileSync("index.js", `export default {};`);
|
|
@@ -963,6 +1052,7 @@ describe("wrangler dev", () => {
|
|
|
963
1052
|
it("should error if config.assets and config.site are used together", async () => {
|
|
964
1053
|
writeWranglerToml({
|
|
965
1054
|
main: "./index.js",
|
|
1055
|
+
// @ts-expect-error we allow string inputs here
|
|
966
1056
|
assets: "abc",
|
|
967
1057
|
site: {
|
|
968
1058
|
bucket: "xyz",
|
|
@@ -1014,6 +1104,7 @@ describe("wrangler dev", () => {
|
|
|
1014
1104
|
it("should warn if config.assets is used", async () => {
|
|
1015
1105
|
writeWranglerToml({
|
|
1016
1106
|
main: "./index.js",
|
|
1107
|
+
// @ts-expect-error we allow string inputs here
|
|
1017
1108
|
assets: "./assets",
|
|
1018
1109
|
});
|
|
1019
1110
|
fs.writeFileSync("index.js", `export default {};`);
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import process from "node:process";
|
|
4
|
+
import { setup } from "create-cloudflare";
|
|
5
|
+
import { mockConsoleMethods } from "./helpers/mock-console";
|
|
6
|
+
import { mockConfirm, clearConfirmMocks } from "./helpers/mock-dialogs";
|
|
7
|
+
import { runInTempDir } from "./helpers/run-in-tmp";
|
|
8
|
+
import { runWrangler } from "./helpers/run-wrangler";
|
|
9
|
+
|
|
10
|
+
const createCloudflareMock = setup as jest.Mock;
|
|
11
|
+
|
|
12
|
+
describe("generate", () => {
|
|
13
|
+
runInTempDir();
|
|
14
|
+
const std = mockConsoleMethods();
|
|
15
|
+
|
|
16
|
+
afterEach(() => {
|
|
17
|
+
clearConfirmMocks();
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it("defers to `wrangler init` when no template is given", async () => {
|
|
21
|
+
mockConfirm(
|
|
22
|
+
{
|
|
23
|
+
text: "Would you like to use git to manage this Worker?",
|
|
24
|
+
result: false,
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
text: "No package.json found. Would you like to create one?",
|
|
28
|
+
result: false,
|
|
29
|
+
}
|
|
30
|
+
);
|
|
31
|
+
await runWrangler("generate no-template");
|
|
32
|
+
expect(std.out).toMatchInlineSnapshot(
|
|
33
|
+
`"✨ Created no-template/wrangler.toml"`
|
|
34
|
+
);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it("runs `create-cloudflare` when a template is given", async () => {
|
|
38
|
+
await expect(
|
|
39
|
+
runWrangler("generate my-worker some-template")
|
|
40
|
+
).resolves.toBeUndefined();
|
|
41
|
+
|
|
42
|
+
expect(createCloudflareMock).toBeCalled();
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it("complains when given the --type argument", async () => {
|
|
46
|
+
await expect(
|
|
47
|
+
runWrangler("generate worker-name worker-template --type rust")
|
|
48
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
49
|
+
`"The --type option is no longer supported."`
|
|
50
|
+
);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it("complains when given the --site argument", async () => {
|
|
54
|
+
await expect(runWrangler("generate worker-name worker-template --site"))
|
|
55
|
+
.rejects.toThrowErrorMatchingInlineSnapshot(`
|
|
56
|
+
"The --site option is no longer supported.
|
|
57
|
+
If you wish to create a brand new Worker Sites project then clone the \`worker-sites-template\` starter repository:
|
|
58
|
+
|
|
59
|
+
\`\`\`
|
|
60
|
+
git clone --depth=1 --branch=wrangler2 https://github.com/cloudflare/worker-sites-template worker-name
|
|
61
|
+
cd worker-name
|
|
62
|
+
\`\`\`
|
|
63
|
+
|
|
64
|
+
Find out more about how to create and maintain Sites projects at https://developers.cloudflare.com/workers/platform/sites.
|
|
65
|
+
Have you considered using Cloudflare Pages instead? See https://pages.cloudflare.com/."
|
|
66
|
+
`);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it("auto-increments the worker directory name", async () => {
|
|
70
|
+
fs.mkdirSync("my-worker");
|
|
71
|
+
await expect(
|
|
72
|
+
runWrangler("generate my-worker some-template")
|
|
73
|
+
).resolves.toBeUndefined();
|
|
74
|
+
|
|
75
|
+
expect(createCloudflareMock).lastCalledWith(
|
|
76
|
+
path.resolve(process.cwd(), "my-worker-1"),
|
|
77
|
+
"some-template",
|
|
78
|
+
{ debug: false, force: false, init: true }
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
fs.mkdirSync("my-worker-1");
|
|
82
|
+
|
|
83
|
+
await expect(
|
|
84
|
+
runWrangler("generate my-worker some-template")
|
|
85
|
+
).resolves.toBeUndefined();
|
|
86
|
+
|
|
87
|
+
expect(createCloudflareMock).lastCalledWith(
|
|
88
|
+
path.resolve(process.cwd(), "my-worker-2"),
|
|
89
|
+
"some-template",
|
|
90
|
+
{ debug: false, force: false, init: true }
|
|
91
|
+
);
|
|
92
|
+
});
|
|
93
|
+
});
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import { Readable } from "node:stream";
|
|
1
2
|
import { URL, URLSearchParams } from "node:url";
|
|
2
3
|
import { pathToRegexp } from "path-to-regexp";
|
|
4
|
+
import { Response } from "undici";
|
|
3
5
|
import { getCloudflareApiBaseUrl } from "../../cfetch";
|
|
4
6
|
import type { FetchResult, FetchError } from "../../cfetch";
|
|
5
|
-
import type { RequestInit } from "undici";
|
|
7
|
+
import type { RequestInit, BodyInit, HeadersInit } from "undici";
|
|
6
8
|
|
|
7
9
|
/**
|
|
8
10
|
* The signature of the function that will handle a mock request.
|
|
@@ -180,6 +182,7 @@ export function unsetAllMocks() {
|
|
|
180
182
|
*/
|
|
181
183
|
|
|
182
184
|
const kvGetMocks = new Map<string, string | Buffer>();
|
|
185
|
+
const r2GetMocks = new Map<string, string | undefined>();
|
|
183
186
|
|
|
184
187
|
/**
|
|
185
188
|
* @mocked typeof fetchKVGetValue
|
|
@@ -206,6 +209,55 @@ export function setMockFetchKVGetValue(
|
|
|
206
209
|
kvGetMocks.set(`${accountId}/${namespaceId}/${key}`, value);
|
|
207
210
|
}
|
|
208
211
|
|
|
209
|
-
|
|
212
|
+
/**
|
|
213
|
+
* @mocked typeof fetchR2Objects
|
|
214
|
+
*/
|
|
215
|
+
export async function mockFetchR2Objects(
|
|
216
|
+
resource: string,
|
|
217
|
+
bodyInit: {
|
|
218
|
+
body: BodyInit | Readable;
|
|
219
|
+
headers: HeadersInit | undefined;
|
|
220
|
+
method: "PUT" | "GET";
|
|
221
|
+
}
|
|
222
|
+
): Promise<Response> {
|
|
223
|
+
/**
|
|
224
|
+
* Here we destroy & removeListeners to "drain" the stream, for testing purposes
|
|
225
|
+
* mimicking the fetch request taking in the stream and draining it.
|
|
226
|
+
*/
|
|
227
|
+
if (bodyInit.body instanceof Readable) {
|
|
228
|
+
bodyInit.body.destroy();
|
|
229
|
+
bodyInit.body.removeAllListeners();
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
if (r2GetMocks.has(resource)) {
|
|
233
|
+
const value = r2GetMocks.get(resource);
|
|
234
|
+
|
|
235
|
+
return new Response(value);
|
|
236
|
+
}
|
|
237
|
+
throw new Error(`no expected mock found for \`r2 object get\` - ${resource}`);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Mock setter for usage within test blocks, companion helper to `mockFetchR2Objects`
|
|
242
|
+
*/
|
|
243
|
+
export function setMockFetchR2Objects({
|
|
244
|
+
accountId,
|
|
245
|
+
bucketName,
|
|
246
|
+
objectName,
|
|
247
|
+
mockResponse,
|
|
248
|
+
}: {
|
|
249
|
+
accountId: string;
|
|
250
|
+
bucketName: string;
|
|
251
|
+
objectName: string;
|
|
252
|
+
mockResponse?: string;
|
|
253
|
+
}) {
|
|
254
|
+
r2GetMocks.set(
|
|
255
|
+
`/accounts/${accountId}/r2/buckets/${bucketName}/objects/${objectName}`,
|
|
256
|
+
mockResponse
|
|
257
|
+
);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
export function unsetSpecialMockFns() {
|
|
210
261
|
kvGetMocks.clear();
|
|
262
|
+
r2GetMocks.clear();
|
|
211
263
|
}
|
|
@@ -203,36 +203,19 @@ describe("wrangler", () => {
|
|
|
203
203
|
await runWrangler("r2");
|
|
204
204
|
await endEventLoop();
|
|
205
205
|
expect(std.out).toMatchInlineSnapshot(`
|
|
206
|
-
|
|
206
|
+
"wrangler r2
|
|
207
207
|
|
|
208
|
-
|
|
208
|
+
📦 Interact with an R2 store
|
|
209
209
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
Flags:
|
|
214
|
-
-c, --config Path to .toml configuration file [string]
|
|
215
|
-
-h, --help Show help [boolean]
|
|
216
|
-
-v, --version Show version number [boolean]"
|
|
217
|
-
`);
|
|
218
|
-
});
|
|
219
|
-
});
|
|
210
|
+
Commands:
|
|
211
|
+
wrangler r2 object Manage R2 objects
|
|
212
|
+
wrangler r2 bucket Manage R2 buckets
|
|
220
213
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
\`wrangler generate\` has been deprecated.
|
|
227
|
-
Try running \`wrangler init\` to generate a basic Worker, or cloning the template repository instead:
|
|
228
|
-
|
|
229
|
-
\`\`\`
|
|
230
|
-
git clone https://github.com/cloudflare/worker-template
|
|
231
|
-
\`\`\`
|
|
232
|
-
|
|
233
|
-
Please refer to https://developers.cloudflare.com/workers/wrangler/deprecations/#generate for more information."
|
|
234
|
-
`);
|
|
235
|
-
});
|
|
214
|
+
Flags:
|
|
215
|
+
-c, --config Path to .toml configuration file [string]
|
|
216
|
+
-h, --help Show help [boolean]
|
|
217
|
+
-v, --version Show version number [boolean]"
|
|
218
|
+
`);
|
|
236
219
|
});
|
|
237
220
|
});
|
|
238
221
|
|