wrangler 4.40.2 → 4.51.0
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/config-schema.json +146 -18
- package/package.json +26 -17
- package/templates/new-worker-scheduled.js +3 -3
- package/templates/new-worker-scheduled.ts +3 -3
- package/templates/remoteBindings/ProxyServerWorker.ts +40 -0
- package/templates/startDevWorker/ProxyWorker.ts +24 -19
- package/wrangler-dist/InspectorProxyWorker.js +4 -6
- package/wrangler-dist/ProxyServerWorker.js +24 -0
- package/wrangler-dist/ProxyWorker.js +15 -13
- package/wrangler-dist/cli.d.ts +190 -1902
- package/wrangler-dist/cli.js +216000 -190371
- package/wrangler-dist/metafile-cjs.json +1 -1
package/config-schema.json
CHANGED
|
@@ -248,6 +248,26 @@
|
|
|
248
248
|
],
|
|
249
249
|
"description": "Specify the compliance region mode of the Worker.\n\nAlthough if the user does not specify a compliance region, the default is `public`, it can be set to `undefined` in configuration to delegate to the CLOUDFLARE_COMPLIANCE_REGION environment variable."
|
|
250
250
|
},
|
|
251
|
+
"python_modules": {
|
|
252
|
+
"type": "object",
|
|
253
|
+
"properties": {
|
|
254
|
+
"exclude": {
|
|
255
|
+
"type": "array",
|
|
256
|
+
"items": {
|
|
257
|
+
"type": "string"
|
|
258
|
+
},
|
|
259
|
+
"description": "A list of glob patterns to exclude files from the python_modules directory when bundling.\n\nPatterns are relative to the python_modules directory and use glob syntax.",
|
|
260
|
+
"default": [
|
|
261
|
+
"***.pyc"
|
|
262
|
+
]
|
|
263
|
+
}
|
|
264
|
+
},
|
|
265
|
+
"required": [
|
|
266
|
+
"exclude"
|
|
267
|
+
],
|
|
268
|
+
"additionalProperties": false,
|
|
269
|
+
"description": "Configuration for Python modules."
|
|
270
|
+
},
|
|
251
271
|
"define": {
|
|
252
272
|
"type": "object",
|
|
253
273
|
"additionalProperties": {
|
|
@@ -720,6 +740,24 @@
|
|
|
720
740
|
"description": "Binding to Cloudflare Images\n\nNOTE: This field is not automatically inherited from the top level environment, and so must be specified in every named environment.\n\nFor reference, see https://developers.cloudflare.com/workers/wrangler/configuration/#images",
|
|
721
741
|
"default": {}
|
|
722
742
|
},
|
|
743
|
+
"media": {
|
|
744
|
+
"type": "object",
|
|
745
|
+
"properties": {
|
|
746
|
+
"binding": {
|
|
747
|
+
"type": "string"
|
|
748
|
+
},
|
|
749
|
+
"remote": {
|
|
750
|
+
"type": "boolean",
|
|
751
|
+
"description": "Whether the Media binding should be remote or not"
|
|
752
|
+
}
|
|
753
|
+
},
|
|
754
|
+
"required": [
|
|
755
|
+
"binding"
|
|
756
|
+
],
|
|
757
|
+
"additionalProperties": false,
|
|
758
|
+
"description": "Binding to Cloudflare Media Transformations\n\nNOTE: This field is not automatically inherited from the top level environment, and so must be specified in every named environment.",
|
|
759
|
+
"default": {}
|
|
760
|
+
},
|
|
723
761
|
"version_metadata": {
|
|
724
762
|
"type": "object",
|
|
725
763
|
"properties": {
|
|
@@ -877,6 +915,14 @@
|
|
|
877
915
|
"description": "Specifies a list of Tail Workers that are bound to this Worker environment\n\nNOTE: This field is not automatically inherited from the top level environment, and so must be specified in every named environment.",
|
|
878
916
|
"default": []
|
|
879
917
|
},
|
|
918
|
+
"streaming_tail_consumers": {
|
|
919
|
+
"type": "array",
|
|
920
|
+
"items": {
|
|
921
|
+
"$ref": "#/definitions/StreamingTailConsumer"
|
|
922
|
+
},
|
|
923
|
+
"description": "Specifies a list of Streaming Tail Workers that are bound to this Worker environment\n\nNOTE: This field is not automatically inherited from the top level environment, and so must be specified in every named environment.",
|
|
924
|
+
"default": []
|
|
925
|
+
},
|
|
880
926
|
"dispatch_namespaces": {
|
|
881
927
|
"type": "array",
|
|
882
928
|
"items": {
|
|
@@ -1397,6 +1443,26 @@
|
|
|
1397
1443
|
],
|
|
1398
1444
|
"description": "Specify the compliance region mode of the Worker.\n\nAlthough if the user does not specify a compliance region, the default is `public`, it can be set to `undefined` in configuration to delegate to the CLOUDFLARE_COMPLIANCE_REGION environment variable."
|
|
1399
1445
|
},
|
|
1446
|
+
"python_modules": {
|
|
1447
|
+
"type": "object",
|
|
1448
|
+
"properties": {
|
|
1449
|
+
"exclude": {
|
|
1450
|
+
"type": "array",
|
|
1451
|
+
"items": {
|
|
1452
|
+
"type": "string"
|
|
1453
|
+
},
|
|
1454
|
+
"description": "A list of glob patterns to exclude files from the python_modules directory when bundling.\n\nPatterns are relative to the python_modules directory and use glob syntax.",
|
|
1455
|
+
"default": [
|
|
1456
|
+
"***.pyc"
|
|
1457
|
+
]
|
|
1458
|
+
}
|
|
1459
|
+
},
|
|
1460
|
+
"required": [
|
|
1461
|
+
"exclude"
|
|
1462
|
+
],
|
|
1463
|
+
"additionalProperties": false,
|
|
1464
|
+
"description": "Configuration for Python modules."
|
|
1465
|
+
},
|
|
1400
1466
|
"define": {
|
|
1401
1467
|
"type": "object",
|
|
1402
1468
|
"additionalProperties": {
|
|
@@ -1869,6 +1935,24 @@
|
|
|
1869
1935
|
"description": "Binding to Cloudflare Images\n\nNOTE: This field is not automatically inherited from the top level environment, and so must be specified in every named environment.\n\nFor reference, see https://developers.cloudflare.com/workers/wrangler/configuration/#images",
|
|
1870
1936
|
"default": {}
|
|
1871
1937
|
},
|
|
1938
|
+
"media": {
|
|
1939
|
+
"type": "object",
|
|
1940
|
+
"properties": {
|
|
1941
|
+
"binding": {
|
|
1942
|
+
"type": "string"
|
|
1943
|
+
},
|
|
1944
|
+
"remote": {
|
|
1945
|
+
"type": "boolean",
|
|
1946
|
+
"description": "Whether the Media binding should be remote or not"
|
|
1947
|
+
}
|
|
1948
|
+
},
|
|
1949
|
+
"required": [
|
|
1950
|
+
"binding"
|
|
1951
|
+
],
|
|
1952
|
+
"additionalProperties": false,
|
|
1953
|
+
"description": "Binding to Cloudflare Media Transformations\n\nNOTE: This field is not automatically inherited from the top level environment, and so must be specified in every named environment.",
|
|
1954
|
+
"default": {}
|
|
1955
|
+
},
|
|
1872
1956
|
"version_metadata": {
|
|
1873
1957
|
"type": "object",
|
|
1874
1958
|
"properties": {
|
|
@@ -2026,6 +2110,14 @@
|
|
|
2026
2110
|
"description": "Specifies a list of Tail Workers that are bound to this Worker environment\n\nNOTE: This field is not automatically inherited from the top level environment, and so must be specified in every named environment.",
|
|
2027
2111
|
"default": []
|
|
2028
2112
|
},
|
|
2113
|
+
"streaming_tail_consumers": {
|
|
2114
|
+
"type": "array",
|
|
2115
|
+
"items": {
|
|
2116
|
+
"$ref": "#/definitions/StreamingTailConsumer"
|
|
2117
|
+
},
|
|
2118
|
+
"description": "Specifies a list of Streaming Tail Workers that are bound to this Worker environment\n\nNOTE: This field is not automatically inherited from the top level environment, and so must be specified in every named environment.",
|
|
2119
|
+
"default": []
|
|
2120
|
+
},
|
|
2029
2121
|
"dispatch_namespaces": {
|
|
2030
2122
|
"type": "array",
|
|
2031
2123
|
"items": {
|
|
@@ -2524,33 +2616,31 @@
|
|
|
2524
2616
|
"Json": {
|
|
2525
2617
|
"anyOf": [
|
|
2526
2618
|
{
|
|
2527
|
-
"
|
|
2619
|
+
"type": "string"
|
|
2528
2620
|
},
|
|
2529
2621
|
{
|
|
2530
|
-
"type": "
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2622
|
+
"type": "number"
|
|
2623
|
+
},
|
|
2624
|
+
{
|
|
2625
|
+
"type": "boolean"
|
|
2626
|
+
},
|
|
2627
|
+
{
|
|
2628
|
+
"type": "null"
|
|
2534
2629
|
},
|
|
2535
2630
|
{
|
|
2536
2631
|
"type": "array",
|
|
2537
2632
|
"items": {
|
|
2538
2633
|
"$ref": "#/definitions/Json"
|
|
2539
2634
|
}
|
|
2635
|
+
},
|
|
2636
|
+
{
|
|
2637
|
+
"type": "object",
|
|
2638
|
+
"additionalProperties": {
|
|
2639
|
+
"$ref": "#/definitions/Json"
|
|
2640
|
+
}
|
|
2540
2641
|
}
|
|
2541
2642
|
]
|
|
2542
2643
|
},
|
|
2543
|
-
"Literal": {
|
|
2544
|
-
"$ref": "#/definitions/TypeOf%3CZodUnion%3C%5Bdef-class-1315922706-6501-8772-1315922706-0-54395%2Cdef-class-1315922706-9299-10989-1315922706-0-54395%2Cdef-class-1315922706-12937-13365-1315922706-0-54395%2Cdef-class-1315922706-15083-15273-1315922706-0-54395%5D%3E%3E"
|
|
2545
|
-
},
|
|
2546
|
-
"TypeOf<ZodUnion<[def-class-1315922706-6501-8772-1315922706-0-54395,def-class-1315922706-9299-10989-1315922706-0-54395,def-class-1315922706-12937-13365-1315922706-0-54395,def-class-1315922706-15083-15273-1315922706-0-54395]>>": {
|
|
2547
|
-
"type": [
|
|
2548
|
-
"string",
|
|
2549
|
-
"number",
|
|
2550
|
-
"boolean",
|
|
2551
|
-
"null"
|
|
2552
|
-
]
|
|
2553
|
-
},
|
|
2554
2644
|
"DurableObjectBindings": {
|
|
2555
2645
|
"type": "array",
|
|
2556
2646
|
"items": {
|
|
@@ -2625,7 +2715,12 @@
|
|
|
2625
2715
|
"enum": [
|
|
2626
2716
|
"dev",
|
|
2627
2717
|
"basic",
|
|
2628
|
-
"standard"
|
|
2718
|
+
"standard",
|
|
2719
|
+
"lite",
|
|
2720
|
+
"standard-1",
|
|
2721
|
+
"standard-2",
|
|
2722
|
+
"standard-3",
|
|
2723
|
+
"standard-4"
|
|
2629
2724
|
]
|
|
2630
2725
|
},
|
|
2631
2726
|
"vcpu": {
|
|
@@ -2695,6 +2790,26 @@
|
|
|
2695
2790
|
"type": "string",
|
|
2696
2791
|
"const": "standard"
|
|
2697
2792
|
},
|
|
2793
|
+
{
|
|
2794
|
+
"type": "string",
|
|
2795
|
+
"const": "lite"
|
|
2796
|
+
},
|
|
2797
|
+
{
|
|
2798
|
+
"type": "string",
|
|
2799
|
+
"const": "standard-1"
|
|
2800
|
+
},
|
|
2801
|
+
{
|
|
2802
|
+
"type": "string",
|
|
2803
|
+
"const": "standard-2"
|
|
2804
|
+
},
|
|
2805
|
+
{
|
|
2806
|
+
"type": "string",
|
|
2807
|
+
"const": "standard-3"
|
|
2808
|
+
},
|
|
2809
|
+
{
|
|
2810
|
+
"type": "string",
|
|
2811
|
+
"const": "standard-4"
|
|
2812
|
+
},
|
|
2698
2813
|
{
|
|
2699
2814
|
"type": "object",
|
|
2700
2815
|
"properties": {
|
|
@@ -2711,7 +2826,7 @@
|
|
|
2711
2826
|
"additionalProperties": false
|
|
2712
2827
|
}
|
|
2713
2828
|
],
|
|
2714
|
-
"description": "The instance type to be used for the container. Select from one of the following named instance types: -
|
|
2829
|
+
"description": "The instance type to be used for the container. Select from one of the following named instance types: - lite: 1/16 vCPU, 256 MiB memory, and 2 GB disk - basic: 1/4 vCPU, 1 GiB memory, and 4 GB disk - standard-1: 1/2 vCPU, 4 GiB memory, and 8 GB disk - standard-2: 1 vCPU, 6 GiB memory, and 12 GB disk - standard-3: 2 vCPU, 8 GiB memory, and 16 GB disk - standard-4: 4 vCPU, 12 GiB memory, and 20 GB disk - dev: 1/16 vCPU, 256 MiB memory, and 2 GB disk (deprecated, use \"lite\" instead) - standard: 1 vCPU, 4 GiB memory, and 4 GB disk (deprecated, use \"standard-1\" instead)\n\nCustomers on an enterprise plan have the additional option to set custom limits.",
|
|
2715
2830
|
"default": "dev"
|
|
2716
2831
|
},
|
|
2717
2832
|
"rollout_step_percentage": {
|
|
@@ -2762,6 +2877,19 @@
|
|
|
2762
2877
|
],
|
|
2763
2878
|
"additionalProperties": false
|
|
2764
2879
|
},
|
|
2880
|
+
"StreamingTailConsumer": {
|
|
2881
|
+
"type": "object",
|
|
2882
|
+
"properties": {
|
|
2883
|
+
"service": {
|
|
2884
|
+
"type": "string",
|
|
2885
|
+
"description": "The name of the service streaming tail events will be forwarded to."
|
|
2886
|
+
}
|
|
2887
|
+
},
|
|
2888
|
+
"required": [
|
|
2889
|
+
"service"
|
|
2890
|
+
],
|
|
2891
|
+
"additionalProperties": false
|
|
2892
|
+
},
|
|
2765
2893
|
"DispatchNamespaceOutbound": {
|
|
2766
2894
|
"type": "object",
|
|
2767
2895
|
"properties": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wrangler",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.51.0",
|
|
4
4
|
"description": "Command-line interface for all things Cloudflare Workers",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"wrangler",
|
|
@@ -53,25 +53,27 @@
|
|
|
53
53
|
"blake3-wasm": "2.1.5",
|
|
54
54
|
"esbuild": "0.25.4",
|
|
55
55
|
"path-to-regexp": "6.3.0",
|
|
56
|
-
"unenv": "2.0.0-rc.
|
|
57
|
-
"workerd": "1.
|
|
58
|
-
"@cloudflare/kv-asset-handler": "0.4.
|
|
59
|
-
"
|
|
60
|
-
"
|
|
56
|
+
"unenv": "2.0.0-rc.24",
|
|
57
|
+
"workerd": "1.20251125.0",
|
|
58
|
+
"@cloudflare/kv-asset-handler": "0.4.1",
|
|
59
|
+
"@cloudflare/unenv-preset": "2.7.11",
|
|
60
|
+
"miniflare": "4.20251125.0"
|
|
61
61
|
},
|
|
62
62
|
"devDependencies": {
|
|
63
63
|
"@aws-sdk/client-s3": "^3.721.0",
|
|
64
64
|
"@cloudflare/types": "6.18.4",
|
|
65
|
-
"@cloudflare/workers-types": "^4.
|
|
65
|
+
"@cloudflare/workers-types": "^4.20251125.0",
|
|
66
66
|
"@cspotcode/source-map-support": "0.8.1",
|
|
67
|
-
"@
|
|
67
|
+
"@netlify/build-info": "^10.0.9",
|
|
68
68
|
"@sentry/node": "^7.86.0",
|
|
69
69
|
"@sentry/types": "^7.86.0",
|
|
70
70
|
"@sentry/utils": "^7.86.0",
|
|
71
71
|
"@types/command-exists": "^1.2.0",
|
|
72
|
+
"@types/cross-spawn": "^6.0.2",
|
|
72
73
|
"@types/glob-to-regexp": "^0.4.1",
|
|
73
74
|
"@types/is-ci": "^3.0.0",
|
|
74
75
|
"@types/javascript-time-ago": "^2.0.3",
|
|
76
|
+
"@types/json-diff": "^1.0.3",
|
|
75
77
|
"@types/mime": "^3.0.4",
|
|
76
78
|
"@types/minimatch": "^5.1.2",
|
|
77
79
|
"@types/node": "^20.19.9",
|
|
@@ -89,14 +91,16 @@
|
|
|
89
91
|
"chalk": "^5.2.0",
|
|
90
92
|
"chokidar": "^4.0.1",
|
|
91
93
|
"cli-table3": "^0.6.3",
|
|
92
|
-
"cloudflare": "^5.
|
|
94
|
+
"cloudflare": "^5.2.0",
|
|
93
95
|
"cmd-shim": "^4.1.0",
|
|
94
96
|
"command-exists": "^1.2.9",
|
|
95
97
|
"concurrently": "^8.2.2",
|
|
98
|
+
"cross-spawn": "^7.0.3",
|
|
96
99
|
"date-fns": "^4.1.0",
|
|
97
100
|
"devtools-protocol": "^0.0.1182435",
|
|
98
101
|
"dotenv": "^16.3.1",
|
|
99
102
|
"dotenv-expand": "^12.0.2",
|
|
103
|
+
"eslint": "^9.39.1",
|
|
100
104
|
"execa": "^6.1.0",
|
|
101
105
|
"find-up": "^6.3.0",
|
|
102
106
|
"get-port": "^7.0.0",
|
|
@@ -105,6 +109,8 @@
|
|
|
105
109
|
"is-ci": "^3.0.1",
|
|
106
110
|
"itty-time": "^1.0.6",
|
|
107
111
|
"javascript-time-ago": "^2.5.4",
|
|
112
|
+
"json-diff": "^1.0.6",
|
|
113
|
+
"jsonc-parser": "^3.2.0",
|
|
108
114
|
"md5-file": "5.0.0",
|
|
109
115
|
"mime": "^3.0.0",
|
|
110
116
|
"minimatch": "^5.1.0",
|
|
@@ -112,7 +118,7 @@
|
|
|
112
118
|
"msw": "2.4.3",
|
|
113
119
|
"node-forge": "^1.3.1",
|
|
114
120
|
"open": "^8.4.0",
|
|
115
|
-
"p-queue": "^
|
|
121
|
+
"p-queue": "^9.0.0",
|
|
116
122
|
"patch-console": "^1.0.0",
|
|
117
123
|
"pretty-bytes": "^6.0.0",
|
|
118
124
|
"prompts": "^2.4.2",
|
|
@@ -122,6 +128,7 @@
|
|
|
122
128
|
"semiver": "^1.1.0",
|
|
123
129
|
"shell-quote": "^1.8.1",
|
|
124
130
|
"signal-exit": "^3.0.7",
|
|
131
|
+
"smol-toml": "^1.5.2",
|
|
125
132
|
"source-map": "^0.6.1",
|
|
126
133
|
"strip-ansi": "^7.1.0",
|
|
127
134
|
"supports-color": "^9.2.2",
|
|
@@ -135,18 +142,20 @@
|
|
|
135
142
|
"vitest": "~3.2.0",
|
|
136
143
|
"vitest-websocket-mock": "^0.4.0",
|
|
137
144
|
"ws": "8.18.0",
|
|
138
|
-
"xdg-app-paths": "^8.3.0",
|
|
139
145
|
"xxhash-wasm": "^1.0.1",
|
|
146
|
+
"yaml": "^2.8.1",
|
|
140
147
|
"yargs": "^17.7.2",
|
|
141
|
-
"@cloudflare/cli": "1.1.
|
|
142
|
-
"@cloudflare/containers-shared": "0.
|
|
143
|
-
"@cloudflare/pages-shared": "^0.13.75",
|
|
148
|
+
"@cloudflare/cli": "1.1.3",
|
|
149
|
+
"@cloudflare/containers-shared": "0.3.0",
|
|
144
150
|
"@cloudflare/eslint-config-shared": "1.1.0",
|
|
151
|
+
"@cloudflare/pages-shared": "^0.13.89",
|
|
152
|
+
"@cloudflare/workers-shared": "0.18.8",
|
|
145
153
|
"@cloudflare/workers-tsconfig": "0.0.0",
|
|
146
|
-
"@cloudflare/workers-
|
|
154
|
+
"@cloudflare/workers-utils": "0.3.0",
|
|
155
|
+
"@cloudflare/workflows-shared": "0.3.8"
|
|
147
156
|
},
|
|
148
157
|
"peerDependencies": {
|
|
149
|
-
"@cloudflare/workers-types": "^4.
|
|
158
|
+
"@cloudflare/workers-types": "^4.20251125.0"
|
|
150
159
|
},
|
|
151
160
|
"peerDependenciesMeta": {
|
|
152
161
|
"@cloudflare/workers-types": {
|
|
@@ -157,7 +166,7 @@
|
|
|
157
166
|
"fsevents": "~2.3.2"
|
|
158
167
|
},
|
|
159
168
|
"engines": {
|
|
160
|
-
"node": ">=
|
|
169
|
+
"node": ">=20.0.0"
|
|
161
170
|
},
|
|
162
171
|
"volta": {
|
|
163
172
|
"extends": "../../package.json"
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Welcome to Cloudflare Workers! This is your first scheduled worker.
|
|
3
3
|
*
|
|
4
|
-
* - Run `wrangler dev
|
|
5
|
-
* - Run `curl "http://localhost:8787/cdn-cgi/
|
|
4
|
+
* - Run `wrangler dev` in your terminal to start a development server
|
|
5
|
+
* - Run `curl "http://localhost:8787/cdn-cgi/handler/scheduled"` to trigger the scheduled event
|
|
6
6
|
* - Go back to the console to see what your worker has logged
|
|
7
|
-
* - Update the Cron trigger in wrangler.toml (see https://developers.cloudflare.com/workers/
|
|
7
|
+
* - Update the Cron trigger in wrangler.toml (see https://developers.cloudflare.com/workers/configuration/cron-triggers/)
|
|
8
8
|
* - Run `wrangler publish --name my-worker` to publish your worker
|
|
9
9
|
*
|
|
10
10
|
* Learn more at https://developers.cloudflare.com/workers/runtime-apis/scheduled-event/
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Welcome to Cloudflare Workers! This is your first scheduled worker.
|
|
3
3
|
*
|
|
4
|
-
* - Run `wrangler dev
|
|
5
|
-
* - Run `curl "http://localhost:8787/cdn-cgi/
|
|
4
|
+
* - Run `wrangler dev` in your terminal to start a development server
|
|
5
|
+
* - Run `curl "http://localhost:8787/cdn-cgi/handler/scheduled"` to trigger the scheduled event
|
|
6
6
|
* - Go back to the console to see what your worker has logged
|
|
7
|
-
* - Update the Cron trigger in wrangler.toml (see https://developers.cloudflare.com/workers/
|
|
7
|
+
* - Update the Cron trigger in wrangler.toml (see https://developers.cloudflare.com/workers/configuration/cron-triggers/)
|
|
8
8
|
* - Run `wrangler deploy --name my-worker` to deploy your worker
|
|
9
9
|
*
|
|
10
10
|
* Learn more at https://developers.cloudflare.com/workers/runtime-apis/scheduled-event/
|
|
@@ -9,6 +9,39 @@ class BindingNotFoundError extends Error {
|
|
|
9
9
|
}
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
+
/**
|
|
13
|
+
* Here be dragons! capnweb does not currently support ReadableStreams, which Media
|
|
14
|
+
* bindings use for input. As such, Media Bindings cannot be directly used via capnweb,
|
|
15
|
+
* and need to be special cased.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
function isSpecialCaseMediaBindingRequest(headers: Headers): boolean {
|
|
19
|
+
return headers.has("x-cf-media-input-options");
|
|
20
|
+
}
|
|
21
|
+
async function evaluateMediaBinding(
|
|
22
|
+
headers: Headers,
|
|
23
|
+
stream: ReadableStream,
|
|
24
|
+
binding: MediaBinding
|
|
25
|
+
): Promise<Response> {
|
|
26
|
+
const inputOptions = JSON.parse(
|
|
27
|
+
headers.get("x-cf-media-input-options") as string
|
|
28
|
+
);
|
|
29
|
+
const outputOptions = JSON.parse(
|
|
30
|
+
headers.get("x-cf-media-output-options") as string
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
const result = await binding
|
|
34
|
+
.input(stream)
|
|
35
|
+
.transform(inputOptions)
|
|
36
|
+
.output(outputOptions);
|
|
37
|
+
|
|
38
|
+
return new Response(await result.media(), {
|
|
39
|
+
headers: {
|
|
40
|
+
"x-cf-media-content-type": await result.contentType(),
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
|
|
12
45
|
/**
|
|
13
46
|
* For most bindings, we expose them as
|
|
14
47
|
* - RPC stubs directly to capnweb, or
|
|
@@ -114,6 +147,13 @@ export default {
|
|
|
114
147
|
originalHeaders.set(name, value);
|
|
115
148
|
}
|
|
116
149
|
}
|
|
150
|
+
if (isSpecialCaseMediaBindingRequest(originalHeaders)) {
|
|
151
|
+
return evaluateMediaBinding(
|
|
152
|
+
originalHeaders,
|
|
153
|
+
request.body as ReadableStream,
|
|
154
|
+
fetcher as unknown as MediaBinding
|
|
155
|
+
);
|
|
156
|
+
}
|
|
117
157
|
|
|
118
158
|
return fetcher.fetch(
|
|
119
159
|
request.headers.get("MF-URL") ?? "http://example.com",
|
|
@@ -151,11 +151,12 @@ export class ProxyWorker implements DurableObject {
|
|
|
151
151
|
|
|
152
152
|
// explicitly NOT await-ing this promise, we are in a loop and want to process the whole queue quickly + synchronously
|
|
153
153
|
void fetch(userWorkerUrl, new Request(request, { headers }))
|
|
154
|
-
.then((res) => {
|
|
154
|
+
.then(async (res) => {
|
|
155
155
|
res = new Response(res.body, res);
|
|
156
156
|
rewriteUrlRelatedHeaders(res.headers, innerUrl, outerUrl);
|
|
157
157
|
|
|
158
158
|
if (isHtmlResponse(res)) {
|
|
159
|
+
await checkForPreviewTokenError(res, this.env, proxyData);
|
|
159
160
|
res = insertLiveReloadScript(request, res, this.env, proxyData);
|
|
160
161
|
}
|
|
161
162
|
|
|
@@ -242,6 +243,28 @@ function sendMessageToProxyController(
|
|
|
242
243
|
});
|
|
243
244
|
}
|
|
244
245
|
|
|
246
|
+
async function checkForPreviewTokenError(
|
|
247
|
+
response: Response,
|
|
248
|
+
env: Env,
|
|
249
|
+
proxyData: ProxyData
|
|
250
|
+
) {
|
|
251
|
+
if (response.status !== 400) {
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// At this point HTMLRewriter tries to parse the compressed stream,
|
|
256
|
+
// so we clone and read the text instead.
|
|
257
|
+
const clone = response.clone();
|
|
258
|
+
const text = await clone.text();
|
|
259
|
+
// Naive string match should be good enough when combined with status code check
|
|
260
|
+
if (text.includes("Invalid Workers Preview configuration")) {
|
|
261
|
+
void sendMessageToProxyController(env, {
|
|
262
|
+
type: "previewTokenExpired",
|
|
263
|
+
proxyData,
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
245
268
|
function insertLiveReloadScript(
|
|
246
269
|
request: Request,
|
|
247
270
|
response: Response,
|
|
@@ -250,26 +273,8 @@ function insertLiveReloadScript(
|
|
|
250
273
|
) {
|
|
251
274
|
const htmlRewriter = new HTMLRewriter();
|
|
252
275
|
|
|
253
|
-
// if preview-token-expired response, errorDetails will contain "Invalid Workers Preview configuration"
|
|
254
|
-
let errorDetails = "";
|
|
255
|
-
htmlRewriter.on("#cf-error-details", {
|
|
256
|
-
text(element) {
|
|
257
|
-
errorDetails += element.text;
|
|
258
|
-
},
|
|
259
|
-
});
|
|
260
|
-
|
|
261
276
|
htmlRewriter.onDocument({
|
|
262
277
|
end(end) {
|
|
263
|
-
if (
|
|
264
|
-
response.status === 400 &&
|
|
265
|
-
errorDetails.includes("Invalid Workers Preview configuration")
|
|
266
|
-
) {
|
|
267
|
-
void sendMessageToProxyController(env, {
|
|
268
|
-
type: "previewTokenExpired",
|
|
269
|
-
proxyData,
|
|
270
|
-
});
|
|
271
|
-
}
|
|
272
|
-
|
|
273
278
|
// if liveReload enabled, append a script tag
|
|
274
279
|
// TODO: compare to existing nodejs implementation
|
|
275
280
|
if (proxyData.liveReload) {
|
|
@@ -17,12 +17,6 @@ function serialiseError(e) {
|
|
|
17
17
|
|
|
18
18
|
// src/api/startDevWorker/utils.ts
|
|
19
19
|
import assert from "node:assert";
|
|
20
|
-
|
|
21
|
-
// src/utils/assert-never.ts
|
|
22
|
-
function assertNever(_value) {
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
// src/api/startDevWorker/utils.ts
|
|
26
20
|
function createDeferred(previousDeferred) {
|
|
27
21
|
let resolve, reject;
|
|
28
22
|
const newPromise = new Promise((_resolve, _reject) => {
|
|
@@ -44,6 +38,10 @@ function urlFromParts(parts, base = "http://localhost") {
|
|
|
44
38
|
return url;
|
|
45
39
|
}
|
|
46
40
|
|
|
41
|
+
// src/utils/assert-never.ts
|
|
42
|
+
function assertNever(_value) {
|
|
43
|
+
}
|
|
44
|
+
|
|
47
45
|
// templates/startDevWorker/InspectorProxyWorker.ts
|
|
48
46
|
var ALLOWED_HOST_HOSTNAMES = ["127.0.0.1", "[::1]", "localhost"];
|
|
49
47
|
var ALLOWED_ORIGIN_HOSTNAMES = [
|
|
@@ -2412,6 +2412,23 @@ var BindingNotFoundError = class extends Error {
|
|
|
2412
2412
|
super(`Binding ${name ? `"${name}"` : ""} not found`);
|
|
2413
2413
|
}
|
|
2414
2414
|
};
|
|
2415
|
+
function isSpecialCaseMediaBindingRequest(headers) {
|
|
2416
|
+
return headers.has("x-cf-media-input-options");
|
|
2417
|
+
}
|
|
2418
|
+
async function evaluateMediaBinding(headers, stream, binding) {
|
|
2419
|
+
const inputOptions = JSON.parse(
|
|
2420
|
+
headers.get("x-cf-media-input-options")
|
|
2421
|
+
);
|
|
2422
|
+
const outputOptions = JSON.parse(
|
|
2423
|
+
headers.get("x-cf-media-output-options")
|
|
2424
|
+
);
|
|
2425
|
+
const result = await binding.input(stream).transform(inputOptions).output(outputOptions);
|
|
2426
|
+
return new Response(await result.media(), {
|
|
2427
|
+
headers: {
|
|
2428
|
+
"x-cf-media-content-type": await result.contentType()
|
|
2429
|
+
}
|
|
2430
|
+
});
|
|
2431
|
+
}
|
|
2415
2432
|
function getExposedJSRPCBinding(request, env) {
|
|
2416
2433
|
const url = new URL(request.url);
|
|
2417
2434
|
const bindingName = url.searchParams.get("MF-Binding");
|
|
@@ -2478,6 +2495,13 @@ var ProxyServerWorker_default = {
|
|
|
2478
2495
|
originalHeaders.set(name, value);
|
|
2479
2496
|
}
|
|
2480
2497
|
}
|
|
2498
|
+
if (isSpecialCaseMediaBindingRequest(originalHeaders)) {
|
|
2499
|
+
return evaluateMediaBinding(
|
|
2500
|
+
originalHeaders,
|
|
2501
|
+
request.body,
|
|
2502
|
+
fetcher
|
|
2503
|
+
);
|
|
2504
|
+
}
|
|
2481
2505
|
return fetcher.fetch(
|
|
2482
2506
|
request.headers.get("MF-URL") ?? "http://example.com",
|
|
2483
2507
|
new Request(request, {
|
|
@@ -110,10 +110,11 @@ var ProxyWorker = class {
|
|
|
110
110
|
headers.set(key, value);
|
|
111
111
|
}
|
|
112
112
|
}
|
|
113
|
-
void fetch(userWorkerUrl, new Request(request, { headers })).then((res) => {
|
|
113
|
+
void fetch(userWorkerUrl, new Request(request, { headers })).then(async (res) => {
|
|
114
114
|
res = new Response(res.body, res);
|
|
115
115
|
rewriteUrlRelatedHeaders(res.headers, innerUrl, outerUrl);
|
|
116
116
|
if (isHtmlResponse(res)) {
|
|
117
|
+
await checkForPreviewTokenError(res, this.env, proxyData);
|
|
117
118
|
res = insertLiveReloadScript(request, res, this.env, proxyData);
|
|
118
119
|
}
|
|
119
120
|
deferredResponse.resolve(res);
|
|
@@ -164,22 +165,23 @@ function sendMessageToProxyController(env, message) {
|
|
|
164
165
|
body: JSON.stringify(message)
|
|
165
166
|
});
|
|
166
167
|
}
|
|
168
|
+
async function checkForPreviewTokenError(response, env, proxyData) {
|
|
169
|
+
if (response.status !== 400) {
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
const clone = response.clone();
|
|
173
|
+
const text = await clone.text();
|
|
174
|
+
if (text.includes("Invalid Workers Preview configuration")) {
|
|
175
|
+
void sendMessageToProxyController(env, {
|
|
176
|
+
type: "previewTokenExpired",
|
|
177
|
+
proxyData
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
}
|
|
167
181
|
function insertLiveReloadScript(request, response, env, proxyData) {
|
|
168
182
|
const htmlRewriter = new HTMLRewriter();
|
|
169
|
-
let errorDetails = "";
|
|
170
|
-
htmlRewriter.on("#cf-error-details", {
|
|
171
|
-
text(element) {
|
|
172
|
-
errorDetails += element.text;
|
|
173
|
-
}
|
|
174
|
-
});
|
|
175
183
|
htmlRewriter.onDocument({
|
|
176
184
|
end(end) {
|
|
177
|
-
if (response.status === 400 && errorDetails.includes("Invalid Workers Preview configuration")) {
|
|
178
|
-
void sendMessageToProxyController(env, {
|
|
179
|
-
type: "previewTokenExpired",
|
|
180
|
-
proxyData
|
|
181
|
-
});
|
|
182
|
-
}
|
|
183
185
|
if (proxyData.liveReload) {
|
|
184
186
|
const websocketUrl = new URL(request.url);
|
|
185
187
|
websocketUrl.protocol = websocketUrl.protocol === "http:" ? "ws:" : "wss:";
|