wrangler 2.0.22 → 2.0.25
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 +643 -7
- package/package.json +17 -5
- package/src/__tests__/configuration.test.ts +89 -17
- package/src/__tests__/dev.test.tsx +121 -8
- 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 +5 -0
- package/src/__tests__/publish.test.ts +573 -254
- package/src/__tests__/r2.test.ts +173 -71
- package/src/__tests__/tail.test.ts +93 -39
- 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 +49 -9
- package/src/bundle.ts +298 -37
- package/src/cfetch/internal.ts +34 -2
- package/src/config/config.ts +15 -3
- package/src/config/environment.ts +40 -8
- package/src/config/index.ts +13 -0
- package/src/config/validation.ts +111 -9
- package/src/create-worker-preview.ts +3 -1
- package/src/create-worker-upload-form.ts +25 -0
- package/src/dev/dev.tsx +145 -31
- package/src/dev/local.tsx +116 -24
- package/src/dev/remote.tsx +39 -12
- package/src/dev/use-esbuild.ts +28 -0
- package/src/dev/validate-dev-props.ts +31 -0
- package/src/dev-registry.tsx +160 -0
- package/src/dev.tsx +148 -67
- package/src/generate.ts +112 -14
- package/src/index.tsx +252 -7
- package/src/inspect.ts +90 -5
- package/src/metrics/index.ts +1 -0
- 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 +546 -0
- package/src/miniflare-cli/index.ts +157 -6
- package/src/module-collection.ts +3 -3
- package/src/pages/build.tsx +36 -28
- package/src/pages/constants.ts +4 -0
- package/src/pages/deployments.tsx +10 -10
- package/src/pages/dev.tsx +155 -651
- package/src/pages/functions/buildPlugin.ts +4 -0
- package/src/pages/functions/buildWorker.ts +4 -0
- package/src/pages/functions/routes-consolidation.test.ts +66 -0
- package/src/pages/functions/routes-consolidation.ts +29 -0
- package/src/pages/functions/routes-transformation.test.ts +271 -0
- package/src/pages/functions/routes-transformation.ts +125 -0
- package/src/pages/projects.tsx +9 -3
- package/src/pages/publish.tsx +57 -15
- package/src/pages/types.ts +9 -0
- package/src/pages/upload.tsx +38 -21
- package/src/publish.ts +139 -112
- package/src/r2.ts +81 -0
- package/src/tail/index.ts +15 -2
- package/src/tail/printing.ts +41 -3
- 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 +38 -3
- package/wrangler-dist/cli.js +45244 -25199
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wrangler",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.25",
|
|
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",
|
|
@@ -26,7 +26,7 @@ describe("normalizeAndValidateConfig()", () => {
|
|
|
26
26
|
compatibility_flags: [],
|
|
27
27
|
configPath: undefined,
|
|
28
28
|
dev: {
|
|
29
|
-
ip: "
|
|
29
|
+
ip: "0.0.0.0",
|
|
30
30
|
local_protocol: "http",
|
|
31
31
|
port: undefined, // the default of 8787 is set at runtime
|
|
32
32
|
upstream_protocol: "https",
|
|
@@ -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
|
|
|
@@ -68,6 +68,28 @@ describe("wrangler dev", () => {
|
|
|
68
68
|
});
|
|
69
69
|
});
|
|
70
70
|
|
|
71
|
+
describe("usage-model", () => {
|
|
72
|
+
it("should read wrangler.toml's usage_model", async () => {
|
|
73
|
+
writeWranglerToml({
|
|
74
|
+
main: "index.js",
|
|
75
|
+
usage_model: "unbound",
|
|
76
|
+
});
|
|
77
|
+
fs.writeFileSync("index.js", `export default {};`);
|
|
78
|
+
await runWrangler("dev");
|
|
79
|
+
expect((Dev as jest.Mock).mock.calls[0][0].usageModel).toEqual("unbound");
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it("should read wrangler.toml's usage_model in local mode", async () => {
|
|
83
|
+
writeWranglerToml({
|
|
84
|
+
main: "index.js",
|
|
85
|
+
usage_model: "unbound",
|
|
86
|
+
});
|
|
87
|
+
fs.writeFileSync("index.js", `export default {};`);
|
|
88
|
+
await runWrangler("dev --local");
|
|
89
|
+
expect((Dev as jest.Mock).mock.calls[0][0].usageModel).toEqual("unbound");
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
|
|
71
93
|
describe("entry-points", () => {
|
|
72
94
|
it("should error if there is no entry-point specified", async () => {
|
|
73
95
|
writeWranglerToml();
|
|
@@ -525,9 +547,9 @@ describe("wrangler dev", () => {
|
|
|
525
547
|
|
|
526
548
|
await expect(runWrangler("dev")).rejects
|
|
527
549
|
.toThrowErrorMatchingInlineSnapshot(`
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
550
|
+
"The expected output file at \\"index.js\\" was not found after running custom build: node -e \\"console.log('custom build');\\".
|
|
551
|
+
The \`main\` property in wrangler.toml should point to the file generated by the custom build."
|
|
552
|
+
`);
|
|
531
553
|
expect(std.out).toMatchInlineSnapshot(`
|
|
532
554
|
"Running custom build: node -e \\"console.log('custom build');\\"
|
|
533
555
|
|
|
@@ -630,13 +652,13 @@ describe("wrangler dev", () => {
|
|
|
630
652
|
});
|
|
631
653
|
|
|
632
654
|
describe("ip", () => {
|
|
633
|
-
it("should default ip to
|
|
655
|
+
it("should default ip to 0.0.0.0", async () => {
|
|
634
656
|
writeWranglerToml({
|
|
635
657
|
main: "index.js",
|
|
636
658
|
});
|
|
637
659
|
fs.writeFileSync("index.js", `export default {};`);
|
|
638
660
|
await runWrangler("dev");
|
|
639
|
-
expect((Dev as jest.Mock).mock.calls[0][0].ip).toEqual("
|
|
661
|
+
expect((Dev as jest.Mock).mock.calls[0][0].ip).toEqual("0.0.0.0");
|
|
640
662
|
expect(std.out).toMatchInlineSnapshot(`""`);
|
|
641
663
|
expect(std.warn).toMatchInlineSnapshot(`""`);
|
|
642
664
|
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
@@ -673,6 +695,78 @@ describe("wrangler dev", () => {
|
|
|
673
695
|
});
|
|
674
696
|
});
|
|
675
697
|
|
|
698
|
+
describe("inspector port", () => {
|
|
699
|
+
it("should use 9229 as the default port", async () => {
|
|
700
|
+
writeWranglerToml({
|
|
701
|
+
main: "index.js",
|
|
702
|
+
});
|
|
703
|
+
fs.writeFileSync("index.js", `export default {};`);
|
|
704
|
+
await runWrangler("dev");
|
|
705
|
+
expect((Dev as jest.Mock).mock.calls[0][0].inspectorPort).toEqual(9229);
|
|
706
|
+
expect(std).toMatchInlineSnapshot(`
|
|
707
|
+
Object {
|
|
708
|
+
"debug": "",
|
|
709
|
+
"err": "",
|
|
710
|
+
"out": "",
|
|
711
|
+
"warn": "",
|
|
712
|
+
}
|
|
713
|
+
`);
|
|
714
|
+
});
|
|
715
|
+
|
|
716
|
+
it("should read --inspector-port", async () => {
|
|
717
|
+
writeWranglerToml({
|
|
718
|
+
main: "index.js",
|
|
719
|
+
});
|
|
720
|
+
fs.writeFileSync("index.js", `export default {};`);
|
|
721
|
+
await runWrangler("dev --inspector-port=9999");
|
|
722
|
+
expect((Dev as jest.Mock).mock.calls[0][0].inspectorPort).toEqual(9999);
|
|
723
|
+
expect(std).toMatchInlineSnapshot(`
|
|
724
|
+
Object {
|
|
725
|
+
"debug": "",
|
|
726
|
+
"err": "",
|
|
727
|
+
"out": "",
|
|
728
|
+
"warn": "",
|
|
729
|
+
}
|
|
730
|
+
`);
|
|
731
|
+
});
|
|
732
|
+
|
|
733
|
+
it("should read dev.inspector_port from wrangler.toml", async () => {
|
|
734
|
+
writeWranglerToml({
|
|
735
|
+
main: "index.js",
|
|
736
|
+
dev: {
|
|
737
|
+
inspector_port: 9999,
|
|
738
|
+
},
|
|
739
|
+
});
|
|
740
|
+
fs.writeFileSync("index.js", `export default {};`);
|
|
741
|
+
await runWrangler("dev");
|
|
742
|
+
expect((Dev as jest.Mock).mock.calls[0][0].inspectorPort).toEqual(9999);
|
|
743
|
+
expect(std).toMatchInlineSnapshot(`
|
|
744
|
+
Object {
|
|
745
|
+
"debug": "",
|
|
746
|
+
"err": "",
|
|
747
|
+
"out": "",
|
|
748
|
+
"warn": "",
|
|
749
|
+
}
|
|
750
|
+
`);
|
|
751
|
+
});
|
|
752
|
+
|
|
753
|
+
it("should error if a bad dev.inspector_port config is provided", async () => {
|
|
754
|
+
writeWranglerToml({
|
|
755
|
+
main: "index.js",
|
|
756
|
+
dev: {
|
|
757
|
+
// @ts-expect-error intentionally bad port
|
|
758
|
+
inspector_port: "some string",
|
|
759
|
+
},
|
|
760
|
+
});
|
|
761
|
+
fs.writeFileSync("index.js", `export default {};`);
|
|
762
|
+
await expect(runWrangler("dev")).rejects
|
|
763
|
+
.toThrowErrorMatchingInlineSnapshot(`
|
|
764
|
+
"Processing wrangler.toml configuration:
|
|
765
|
+
- Expected \\"dev.inspector_port\\" to be of type number but got \\"some string\\"."
|
|
766
|
+
`);
|
|
767
|
+
});
|
|
768
|
+
});
|
|
769
|
+
|
|
676
770
|
describe("port", () => {
|
|
677
771
|
it("should default port to 8787 if it is not in use", async () => {
|
|
678
772
|
writeWranglerToml({
|
|
@@ -686,7 +780,7 @@ describe("wrangler dev", () => {
|
|
|
686
780
|
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
687
781
|
});
|
|
688
782
|
|
|
689
|
-
it("should use
|
|
783
|
+
it("should use `port` from `wrangler.toml`, if available", async () => {
|
|
690
784
|
writeWranglerToml({
|
|
691
785
|
main: "index.js",
|
|
692
786
|
dev: {
|
|
@@ -704,6 +798,22 @@ describe("wrangler dev", () => {
|
|
|
704
798
|
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
705
799
|
});
|
|
706
800
|
|
|
801
|
+
it("should error if a bad dev.port config is provided", async () => {
|
|
802
|
+
writeWranglerToml({
|
|
803
|
+
main: "index.js",
|
|
804
|
+
dev: {
|
|
805
|
+
// @ts-expect-error intentionally bad port
|
|
806
|
+
port: "some string",
|
|
807
|
+
},
|
|
808
|
+
});
|
|
809
|
+
fs.writeFileSync("index.js", `export default {};`);
|
|
810
|
+
await expect(runWrangler("dev")).rejects
|
|
811
|
+
.toThrowErrorMatchingInlineSnapshot(`
|
|
812
|
+
"Processing wrangler.toml configuration:
|
|
813
|
+
- Expected \\"dev.port\\" to be of type number but got \\"some string\\"."
|
|
814
|
+
`);
|
|
815
|
+
});
|
|
816
|
+
|
|
707
817
|
it("should use --port command line arg, if provided", async () => {
|
|
708
818
|
writeWranglerToml({
|
|
709
819
|
main: "index.js",
|
|
@@ -761,7 +871,7 @@ describe("wrangler dev", () => {
|
|
|
761
871
|
});
|
|
762
872
|
fs.writeFileSync("index.js", `export default {};`);
|
|
763
873
|
await runWrangler("dev");
|
|
764
|
-
expect((Dev as jest.Mock).mock.calls[0][0].ip).toEqual("
|
|
874
|
+
expect((Dev as jest.Mock).mock.calls[0][0].ip).toEqual("0.0.0.0");
|
|
765
875
|
expect(std.out).toMatchInlineSnapshot(`
|
|
766
876
|
"Your worker has access to the following bindings:
|
|
767
877
|
- Durable Objects:
|
|
@@ -895,7 +1005,7 @@ describe("wrangler dev", () => {
|
|
|
895
1005
|
--compatibility-date Date to use for compatibility checks [string]
|
|
896
1006
|
--compatibility-flags, --compatibility-flag Flags to use for compatibility checks [array]
|
|
897
1007
|
--latest Use the latest version of the worker runtime [boolean] [default: true]
|
|
898
|
-
--ip IP address to listen on
|
|
1008
|
+
--ip IP address to listen on [string] [default: \\"0.0.0.0\\"]
|
|
899
1009
|
--port Port to listen on [number]
|
|
900
1010
|
--inspector-port Port for devtools to connect to [number]
|
|
901
1011
|
--routes, --route Routes to upload [array]
|
|
@@ -950,6 +1060,7 @@ describe("wrangler dev", () => {
|
|
|
950
1060
|
it("should error if config.assets and --site are used together", async () => {
|
|
951
1061
|
writeWranglerToml({
|
|
952
1062
|
main: "./index.js",
|
|
1063
|
+
// @ts-expect-error we allow string inputs here
|
|
953
1064
|
assets: "abc",
|
|
954
1065
|
});
|
|
955
1066
|
fs.writeFileSync("index.js", `export default {};`);
|
|
@@ -963,6 +1074,7 @@ describe("wrangler dev", () => {
|
|
|
963
1074
|
it("should error if config.assets and config.site are used together", async () => {
|
|
964
1075
|
writeWranglerToml({
|
|
965
1076
|
main: "./index.js",
|
|
1077
|
+
// @ts-expect-error we allow string inputs here
|
|
966
1078
|
assets: "abc",
|
|
967
1079
|
site: {
|
|
968
1080
|
bucket: "xyz",
|
|
@@ -1014,6 +1126,7 @@ describe("wrangler dev", () => {
|
|
|
1014
1126
|
it("should warn if config.assets is used", async () => {
|
|
1015
1127
|
writeWranglerToml({
|
|
1016
1128
|
main: "./index.js",
|
|
1129
|
+
// @ts-expect-error we allow string inputs here
|
|
1017
1130
|
assets: "./assets",
|
|
1018
1131
|
});
|
|
1019
1132
|
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" | "DELETE";
|
|
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 mock found for \`r2 object\` - ${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
|
}
|