wrangler 0.0.0-e57758f8 → 0.0.0-e5ae13ade
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 +29 -37
- package/bin/wrangler.js +3 -37
- package/config-schema.json +1782 -2290
- package/package.json +62 -98
- package/templates/checked-fetch.js +1 -1
- package/templates/facade.d.ts +2 -2
- package/templates/gitignore +3 -0
- package/templates/init-tests/test-vitest-new-worker.ts +2 -2
- package/templates/middleware/loader-modules.ts +14 -13
- package/templates/middleware/middleware-patch-console-prefix.d.ts +3 -0
- package/templates/middleware/middleware-patch-console-prefix.ts +21 -0
- package/templates/middleware/middleware-scheduled.ts +15 -1
- package/templates/mixedMode/proxyServerWorker/index.ts +40 -0
- package/templates/mixedMode/proxyServerWorker/wrangler.jsonc +4 -0
- package/templates/pages-dev-pipeline.ts +3 -2
- package/templates/pages-template-plugin.ts +2 -2
- package/templates/pages-template-worker.ts +1 -1
- package/templates/startDevWorker/InspectorProxyWorker.ts +19 -1
- package/templates/startDevWorker/ProxyWorker.ts +30 -25
- package/templates/strip-cf-connecting-ip-header.js +13 -0
- package/templates/tsconfig.init.json +4 -87
- package/templates/tsconfig.json +8 -1
- package/templates/tsconfig.tsbuildinfo +1 -0
- package/wrangler-dist/InspectorProxyWorker.js +15 -8
- package/wrangler-dist/InspectorProxyWorker.js.map +1 -1
- package/wrangler-dist/ProxyWorker.js +28 -30
- package/wrangler-dist/ProxyWorker.js.map +1 -1
- package/wrangler-dist/cli.d.ts +3783 -911
- package/wrangler-dist/cli.js +168505 -199177
- package/wrangler-dist/cli.js.map +7 -0
- package/Cloudflare_CA.pem +0 -18
- package/templates/middleware/middleware-serve-static-assets.d.ts +0 -6
- package/templates/middleware/middleware-serve-static-assets.ts +0 -56
- package/wrangler-dist/wasm-sync.wasm +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wrangler",
|
|
3
|
-
"version": "0.0.0-
|
|
3
|
+
"version": "0.0.0-e5ae13ade",
|
|
4
4
|
"description": "Command-line interface for all things Cloudflare Workers",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"wrangler",
|
|
@@ -47,152 +47,116 @@
|
|
|
47
47
|
"wrangler-dist",
|
|
48
48
|
"templates",
|
|
49
49
|
"kv-asset-handler.js",
|
|
50
|
-
"Cloudflare_CA.pem",
|
|
51
50
|
"config-schema.json"
|
|
52
51
|
],
|
|
53
|
-
"jest": {
|
|
54
|
-
"moduleNameMapper": {
|
|
55
|
-
"clipboardy": "<rootDir>/src/__tests__/helpers/clipboardy-mock.js",
|
|
56
|
-
"miniflare/cli": "<rootDir>/../../node_modules/miniflare/dist/src/cli.js"
|
|
57
|
-
},
|
|
58
|
-
"restoreMocks": true,
|
|
59
|
-
"setupFilesAfterEnv": [
|
|
60
|
-
"<rootDir>/src/__tests__/jest.setup.ts"
|
|
61
|
-
],
|
|
62
|
-
"testRegex": "src/__tests__/.*\\.(test|spec)\\.[jt]sx?$",
|
|
63
|
-
"testTimeout": 50000,
|
|
64
|
-
"transform": {
|
|
65
|
-
"^.+\\.c?(t|j)sx?$": [
|
|
66
|
-
"esbuild-jest",
|
|
67
|
-
{
|
|
68
|
-
"sourcemap": true
|
|
69
|
-
}
|
|
70
|
-
]
|
|
71
|
-
},
|
|
72
|
-
"transformIgnorePatterns": [
|
|
73
|
-
"node_modules/.pnpm/(?!find-up|locate-path|p-locate|p-limit|p-timeout|p-queue|yocto-queue|path-exists|execa|strip-final-newline|npm-run-path|path-key|onetime|mimic-fn|human-signals|is-stream|get-port|supports-color|pretty-bytes|strip-ansi|ansi-regex)"
|
|
74
|
-
],
|
|
75
|
-
"snapshotFormat": {
|
|
76
|
-
"escapeString": true,
|
|
77
|
-
"printBasicPrototype": true
|
|
78
|
-
}
|
|
79
|
-
},
|
|
80
52
|
"dependencies": {
|
|
81
|
-
"@
|
|
82
|
-
"
|
|
83
|
-
"
|
|
84
|
-
"
|
|
85
|
-
"
|
|
86
|
-
"
|
|
87
|
-
"
|
|
88
|
-
"
|
|
89
|
-
"resolve.exports": "^2.0.2",
|
|
90
|
-
"selfsigned": "^2.0.1",
|
|
91
|
-
"source-map": "0.6.1",
|
|
92
|
-
"xxhash-wasm": "^1.0.1",
|
|
93
|
-
"@cloudflare/kv-asset-handler": "0.3.2",
|
|
94
|
-
"miniflare": "3.20240419.0"
|
|
53
|
+
"@cloudflare/unenv-preset": "2.3.2",
|
|
54
|
+
"blake3-wasm": "2.1.5",
|
|
55
|
+
"esbuild": "0.25.4",
|
|
56
|
+
"path-to-regexp": "6.3.0",
|
|
57
|
+
"unenv": "2.0.0-rc.17",
|
|
58
|
+
"workerd": "1.20250508.0",
|
|
59
|
+
"@cloudflare/kv-asset-handler": "0.4.0",
|
|
60
|
+
"miniflare": "0.0.0-e5ae13ade"
|
|
95
61
|
},
|
|
96
62
|
"devDependencies": {
|
|
97
|
-
"@
|
|
98
|
-
"@cloudflare/types": "
|
|
99
|
-
"@cloudflare/workers-types": "^4.
|
|
63
|
+
"@aws-sdk/client-s3": "^3.721.0",
|
|
64
|
+
"@cloudflare/types": "6.18.4",
|
|
65
|
+
"@cloudflare/workers-types": "^4.20250508.0",
|
|
100
66
|
"@cspotcode/source-map-support": "0.8.1",
|
|
101
67
|
"@iarna/toml": "^3.0.0",
|
|
102
|
-
"@microsoft/api-extractor": "^7.
|
|
68
|
+
"@microsoft/api-extractor": "^7.47.0",
|
|
103
69
|
"@sentry/node": "^7.86.0",
|
|
104
70
|
"@sentry/types": "^7.86.0",
|
|
105
71
|
"@sentry/utils": "^7.86.0",
|
|
106
|
-
"@types/body-parser": "^1.19.2",
|
|
107
72
|
"@types/command-exists": "^1.2.0",
|
|
108
|
-
"@types/
|
|
109
|
-
"@types/glob-to-regexp": "0.4.1",
|
|
73
|
+
"@types/glob-to-regexp": "^0.4.1",
|
|
110
74
|
"@types/is-ci": "^3.0.0",
|
|
111
75
|
"@types/javascript-time-ago": "^2.0.3",
|
|
112
|
-
"@types/
|
|
113
|
-
"@types/mime": "^2.0.3",
|
|
76
|
+
"@types/mime": "^3.0.4",
|
|
114
77
|
"@types/minimatch": "^5.1.2",
|
|
78
|
+
"@types/node": "^20.17.32",
|
|
79
|
+
"@types/node-forge": "^1.3.11",
|
|
115
80
|
"@types/prompts": "^2.0.14",
|
|
116
|
-
"@types/react": "^17.0.37",
|
|
117
81
|
"@types/resolve": "^1.20.6",
|
|
118
|
-
"@types/serve-static": "^1.13.10",
|
|
119
82
|
"@types/shell-quote": "^1.7.2",
|
|
120
83
|
"@types/signal-exit": "^3.0.1",
|
|
121
84
|
"@types/supports-color": "^8.1.1",
|
|
122
|
-
"@types/ws": "^8.5.
|
|
123
|
-
"@types/yargs": "^17.0.
|
|
85
|
+
"@types/ws": "^8.5.7",
|
|
86
|
+
"@types/yargs": "^17.0.22",
|
|
87
|
+
"@vitest/ui": "~3.1.1",
|
|
124
88
|
"@webcontainer/env": "^1.1.0",
|
|
125
|
-
"
|
|
126
|
-
"
|
|
89
|
+
"chalk": "^5.2.0",
|
|
90
|
+
"chokidar": "^4.0.1",
|
|
127
91
|
"cli-table3": "^0.6.3",
|
|
128
|
-
"clipboardy": "^3.0.0",
|
|
129
92
|
"cmd-shim": "^4.1.0",
|
|
130
93
|
"command-exists": "^1.2.9",
|
|
131
|
-
"concurrently": "^
|
|
132
|
-
"
|
|
133
|
-
"
|
|
134
|
-
"
|
|
135
|
-
"esbuild-jest": "0.5.0",
|
|
94
|
+
"concurrently": "^8.2.2",
|
|
95
|
+
"date-fns": "^4.1.0",
|
|
96
|
+
"devtools-protocol": "^0.0.1182435",
|
|
97
|
+
"dotenv": "^16.3.1",
|
|
136
98
|
"execa": "^6.1.0",
|
|
137
|
-
"express": "^4.18.1",
|
|
138
99
|
"find-up": "^6.3.0",
|
|
139
|
-
"get-port": "^
|
|
140
|
-
"glob-to-regexp": "0.4.1",
|
|
141
|
-
"http-terminator": "^3.2.0",
|
|
100
|
+
"get-port": "^7.0.0",
|
|
101
|
+
"glob-to-regexp": "^0.4.1",
|
|
142
102
|
"https-proxy-agent": "7.0.2",
|
|
143
|
-
"ignore": "^5.2.0",
|
|
144
|
-
"ink": "^3.2.0",
|
|
145
|
-
"ink-select-input": "^4.2.1",
|
|
146
|
-
"ink-spinner": "^4.0.3",
|
|
147
|
-
"ink-table": "^3.0.0",
|
|
148
103
|
"is-ci": "^3.0.1",
|
|
104
|
+
"itty-time": "^1.0.6",
|
|
149
105
|
"javascript-time-ago": "^2.5.4",
|
|
150
|
-
"
|
|
151
|
-
"jest-fetch-mock": "^3.0.3",
|
|
152
|
-
"jest-websocket-mock": "^2.5.0",
|
|
106
|
+
"md5-file": "5.0.0",
|
|
153
107
|
"mime": "^3.0.0",
|
|
154
108
|
"minimatch": "^5.1.0",
|
|
155
|
-
"
|
|
109
|
+
"mock-socket": "^9.3.1",
|
|
110
|
+
"msw": "2.4.3",
|
|
111
|
+
"node-forge": "^1.3.1",
|
|
156
112
|
"open": "^8.4.0",
|
|
157
113
|
"p-queue": "^7.2.0",
|
|
158
114
|
"patch-console": "^1.0.0",
|
|
159
115
|
"pretty-bytes": "^6.0.0",
|
|
160
116
|
"prompts": "^2.4.2",
|
|
161
|
-
"
|
|
162
|
-
"
|
|
117
|
+
"resolve": "^1.22.8",
|
|
118
|
+
"rimraf": "^6.0.1",
|
|
119
|
+
"selfsigned": "^2.0.1",
|
|
163
120
|
"semiver": "^1.1.0",
|
|
164
|
-
"serve-static": "^1.15.0",
|
|
165
121
|
"shell-quote": "^1.8.1",
|
|
166
|
-
"shellac": "^0.8.0",
|
|
167
122
|
"signal-exit": "^3.0.7",
|
|
168
|
-
"
|
|
123
|
+
"source-map": "^0.6.1",
|
|
124
|
+
"strip-ansi": "^7.1.0",
|
|
169
125
|
"supports-color": "^9.2.2",
|
|
170
126
|
"timeago.js": "^4.0.2",
|
|
171
127
|
"ts-dedent": "^2.2.0",
|
|
172
128
|
"ts-json-schema-generator": "^1.5.0",
|
|
173
|
-
"
|
|
129
|
+
"typescript": "^5.7.2",
|
|
130
|
+
"undici": "^5.28.5",
|
|
174
131
|
"update-check": "^1.5.4",
|
|
175
|
-
"
|
|
132
|
+
"vitest": "~3.1.1",
|
|
133
|
+
"vitest-websocket-mock": "^0.4.0",
|
|
134
|
+
"ws": "8.18.0",
|
|
176
135
|
"xdg-app-paths": "^8.3.0",
|
|
136
|
+
"xxhash-wasm": "^1.0.1",
|
|
177
137
|
"yargs": "^17.7.2",
|
|
178
|
-
"yoga-layout": "file:../../vendor/yoga-layout-2.0.0-beta.1.tgz",
|
|
179
138
|
"@cloudflare/cli": "1.1.1",
|
|
180
|
-
"@cloudflare/
|
|
181
|
-
"@cloudflare/workers-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
"fsevents": "~2.3.2"
|
|
139
|
+
"@cloudflare/eslint-config-worker": "1.1.0",
|
|
140
|
+
"@cloudflare/workers-shared": "0.0.0-e5ae13ade",
|
|
141
|
+
"@cloudflare/workers-tsconfig": "0.0.0",
|
|
142
|
+
"@cloudflare/pages-shared": "^0.13.40"
|
|
185
143
|
},
|
|
186
144
|
"peerDependencies": {
|
|
187
|
-
"@cloudflare/workers-types": "^4.
|
|
145
|
+
"@cloudflare/workers-types": "^4.20250508.0"
|
|
188
146
|
},
|
|
189
147
|
"peerDependenciesMeta": {
|
|
190
148
|
"@cloudflare/workers-types": {
|
|
191
149
|
"optional": true
|
|
192
150
|
}
|
|
193
151
|
},
|
|
152
|
+
"optionalDependencies": {
|
|
153
|
+
"fsevents": "~2.3.2"
|
|
154
|
+
},
|
|
194
155
|
"engines": {
|
|
195
|
-
"node": ">=
|
|
156
|
+
"node": ">=18.0.0"
|
|
157
|
+
},
|
|
158
|
+
"volta": {
|
|
159
|
+
"extends": "../../package.json"
|
|
196
160
|
},
|
|
197
161
|
"workers-sdk": {
|
|
198
162
|
"prerelease": true
|
|
@@ -201,17 +165,17 @@
|
|
|
201
165
|
"assert-git-version": "node -r esbuild-register scripts/assert-git-version.ts",
|
|
202
166
|
"build": "pnpm run clean && pnpm run bundle && pnpm run emit-types && pnpm run generate-json-schema",
|
|
203
167
|
"bundle": "node -r esbuild-register scripts/bundle.ts",
|
|
204
|
-
"check:lint": "eslint .",
|
|
205
|
-
"check:type": "tsc",
|
|
168
|
+
"check:lint": "eslint . --max-warnings=0",
|
|
169
|
+
"check:type": "tsc -p ./tsconfig.json && tsc -p ./templates/tsconfig.json",
|
|
206
170
|
"clean": "rimraf wrangler-dist miniflare-dist emitted-types",
|
|
207
171
|
"dev": "pnpm run clean && concurrently -c black,blue --kill-others-on-fail false \"pnpm run bundle --watch\" \"pnpm run check:type --watch --preserveWatchOutput\"",
|
|
208
172
|
"emit-types": "tsc -p tsconfig.emit.json && node -r esbuild-register scripts/emit-types.ts",
|
|
209
|
-
"generate-json-schema": "
|
|
173
|
+
"generate-json-schema": "node -r esbuild-register scripts/generate-json-schema.ts",
|
|
210
174
|
"start": "pnpm run bundle && cross-env NODE_OPTIONS=--enable-source-maps ./bin/wrangler.js",
|
|
211
|
-
"test": "pnpm run assert-git-version &&
|
|
212
|
-
"test:ci": "pnpm run test",
|
|
175
|
+
"test": "dotenv -- pnpm run assert-git-version && dotenv -- vitest",
|
|
176
|
+
"test:ci": "pnpm run test run",
|
|
213
177
|
"test:debug": "pnpm run test --silent=false --verbose=true",
|
|
214
|
-
"test:e2e": "vitest -c ./e2e/vitest.config.
|
|
178
|
+
"test:e2e": "dotenv -- vitest run -c ./e2e/vitest.config.mts",
|
|
215
179
|
"test:watch": "pnpm run test --testTimeout=50000 --watch",
|
|
216
180
|
"type:tests": "tsc -p ./src/__tests__/tsconfig.json && tsc -p ./e2e/tsconfig.json"
|
|
217
181
|
}
|
package/templates/facade.d.ts
CHANGED
|
@@ -3,10 +3,10 @@ declare module "__ENTRY_POINT__" {
|
|
|
3
3
|
import { WorkerEntrypoint } from "cloudflare:workers";
|
|
4
4
|
|
|
5
5
|
export type WorkerEntrypointConstructor = typeof WorkerEntrypoint;
|
|
6
|
-
export type WithMiddleware<T> = T & { middleware?: Middleware[] };
|
|
7
6
|
|
|
8
|
-
const worker:
|
|
7
|
+
const worker: ExportedHandler | WorkerEntrypointConstructor;
|
|
9
8
|
export default worker;
|
|
9
|
+
export const __INTERNAL_WRANGLER_MIDDLEWARE__: Middleware[];
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
declare module "__KV_ASSET_HANDLER__" {
|
package/templates/gitignore
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { afterAll, beforeAll, describe, expect, it } from "vitest";
|
|
2
2
|
import { unstable_dev } from "wrangler";
|
|
3
|
-
import type {
|
|
3
|
+
import type { Unstable_DevWorker } from "wrangler";
|
|
4
4
|
|
|
5
5
|
describe("Worker", () => {
|
|
6
|
-
let worker:
|
|
6
|
+
let worker: Unstable_DevWorker;
|
|
7
7
|
|
|
8
8
|
beforeAll(async () => {
|
|
9
9
|
worker = await unstable_dev("src/index.ts", {
|
|
@@ -3,12 +3,9 @@
|
|
|
3
3
|
// export dynamically through wrangler, or we can potentially let users directly
|
|
4
4
|
// add them as a sort of "plugin" system.
|
|
5
5
|
|
|
6
|
-
import ENTRY from "__ENTRY_POINT__";
|
|
6
|
+
import ENTRY, { __INTERNAL_WRANGLER_MIDDLEWARE__ } from "__ENTRY_POINT__";
|
|
7
7
|
import { __facade_invoke__, __facade_register__, Dispatcher } from "./common";
|
|
8
|
-
import type {
|
|
9
|
-
WithMiddleware,
|
|
10
|
-
WorkerEntrypointConstructor,
|
|
11
|
-
} from "__ENTRY_POINT__";
|
|
8
|
+
import type { WorkerEntrypointConstructor } from "__ENTRY_POINT__";
|
|
12
9
|
|
|
13
10
|
// Preserve all the exports from the worker
|
|
14
11
|
export * from "__ENTRY_POINT__";
|
|
@@ -33,15 +30,16 @@ class __Facade_ScheduledController__ implements ScheduledController {
|
|
|
33
30
|
}
|
|
34
31
|
}
|
|
35
32
|
|
|
36
|
-
function wrapExportedHandler(
|
|
37
|
-
worker: WithMiddleware<ExportedHandler>
|
|
38
|
-
): ExportedHandler {
|
|
33
|
+
function wrapExportedHandler(worker: ExportedHandler): ExportedHandler {
|
|
39
34
|
// If we don't have any middleware defined, just return the handler as is
|
|
40
|
-
if (
|
|
35
|
+
if (
|
|
36
|
+
__INTERNAL_WRANGLER_MIDDLEWARE__ === undefined ||
|
|
37
|
+
__INTERNAL_WRANGLER_MIDDLEWARE__.length === 0
|
|
38
|
+
) {
|
|
41
39
|
return worker;
|
|
42
40
|
}
|
|
43
41
|
// Otherwise, register all middleware once
|
|
44
|
-
for (const middleware of
|
|
42
|
+
for (const middleware of __INTERNAL_WRANGLER_MIDDLEWARE__) {
|
|
45
43
|
__facade_register__(middleware);
|
|
46
44
|
}
|
|
47
45
|
|
|
@@ -75,14 +73,17 @@ function wrapExportedHandler(
|
|
|
75
73
|
}
|
|
76
74
|
|
|
77
75
|
function wrapWorkerEntrypoint(
|
|
78
|
-
klass:
|
|
76
|
+
klass: WorkerEntrypointConstructor
|
|
79
77
|
): WorkerEntrypointConstructor {
|
|
80
78
|
// If we don't have any middleware defined, just return the handler as is
|
|
81
|
-
if (
|
|
79
|
+
if (
|
|
80
|
+
__INTERNAL_WRANGLER_MIDDLEWARE__ === undefined ||
|
|
81
|
+
__INTERNAL_WRANGLER_MIDDLEWARE__.length === 0
|
|
82
|
+
) {
|
|
82
83
|
return klass;
|
|
83
84
|
}
|
|
84
85
|
// Otherwise, register all middleware once
|
|
85
|
-
for (const middleware of
|
|
86
|
+
for (const middleware of __INTERNAL_WRANGLER_MIDDLEWARE__) {
|
|
86
87
|
__facade_register__(middleware);
|
|
87
88
|
}
|
|
88
89
|
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/// <reference path="middleware-patch-console-prefix.d.ts"/>
|
|
2
|
+
|
|
3
|
+
import { prefix } from "config:middleware/patch-console-prefix";
|
|
4
|
+
import type { Middleware } from "./common";
|
|
5
|
+
|
|
6
|
+
// @ts-expect-error globalThis.console _does_ exist
|
|
7
|
+
globalThis.console = new Proxy(globalThis.console, {
|
|
8
|
+
get(target, p, receiver) {
|
|
9
|
+
if (p === "log" || p === "debug" || p === "info") {
|
|
10
|
+
return (...args: unknown[]) =>
|
|
11
|
+
Reflect.get(target, p, receiver)(prefix, ...args);
|
|
12
|
+
}
|
|
13
|
+
return Reflect.get(target, p, receiver);
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
const passthrough: Middleware = (request, env, _ctx, middlewareCtx) => {
|
|
18
|
+
return middlewareCtx.next(request, env);
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export default passthrough;
|
|
@@ -9,7 +9,21 @@ const scheduled: Middleware = async (request, env, _ctx, middlewareCtx) => {
|
|
|
9
9
|
|
|
10
10
|
return new Response("Ran scheduled event");
|
|
11
11
|
}
|
|
12
|
-
|
|
12
|
+
|
|
13
|
+
const resp = await middlewareCtx.next(request, env);
|
|
14
|
+
|
|
15
|
+
// If you open the `/__scheduled` page in a browser, the browser will automatically make a request to `/favicon.ico`.
|
|
16
|
+
// For scheduled Workers _without_ a fetch handler, this will result in a 500 response that clutters the log with unhelpful error messages.
|
|
17
|
+
// To avoid this, inject a 404 response to favicon.ico loads on the `/__scheduled` page
|
|
18
|
+
if (
|
|
19
|
+
request.headers.get("referer")?.endsWith("/__scheduled") &&
|
|
20
|
+
url.pathname === "/favicon.ico" &&
|
|
21
|
+
resp.status === 500
|
|
22
|
+
) {
|
|
23
|
+
return new Response(null, { status: 404 });
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return resp;
|
|
13
27
|
};
|
|
14
28
|
|
|
15
29
|
export default scheduled;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
async fetch(request, env) {
|
|
3
|
+
const targetBinding = request.headers.get("MF-Binding");
|
|
4
|
+
|
|
5
|
+
if (targetBinding) {
|
|
6
|
+
const originalHeaders = new Headers();
|
|
7
|
+
for (const [name, value] of request.headers) {
|
|
8
|
+
if (name.startsWith("mf-header-")) {
|
|
9
|
+
originalHeaders.set(name.slice("mf-header-".length), value);
|
|
10
|
+
} else if (name === "upgrade") {
|
|
11
|
+
// The `Upgrade` header needs to be special-cased to prevent:
|
|
12
|
+
// TypeError: Worker tried to return a WebSocket in a response to a request which did not contain the header "Upgrade: websocket"
|
|
13
|
+
originalHeaders.set(name, value);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
let fetcher = env[targetBinding];
|
|
17
|
+
|
|
18
|
+
// Special case the Dispatch Namespace binding because it has a top-level synchronous .get() call
|
|
19
|
+
const dispatchNamespaceOptions = originalHeaders.get(
|
|
20
|
+
"MF-Dispatch-Namespace-Options"
|
|
21
|
+
);
|
|
22
|
+
if (dispatchNamespaceOptions) {
|
|
23
|
+
const { name, args, options } = JSON.parse(dispatchNamespaceOptions);
|
|
24
|
+
fetcher = (env[targetBinding] as DispatchNamespace).get(
|
|
25
|
+
name,
|
|
26
|
+
args,
|
|
27
|
+
options
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
return (fetcher as Fetcher).fetch(
|
|
31
|
+
request.headers.get("MF-URL")!,
|
|
32
|
+
new Request(request, {
|
|
33
|
+
redirect: "manual",
|
|
34
|
+
headers: originalHeaders,
|
|
35
|
+
})
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
return new Response("Provide a binding", { status: 400 });
|
|
39
|
+
},
|
|
40
|
+
} satisfies ExportedHandler<Record<string, Fetcher | DispatchNamespace>>;
|
|
@@ -20,10 +20,11 @@ export default <ExportedHandler<{ ASSETS: Fetcher }>>{
|
|
|
20
20
|
|
|
21
21
|
for (const include of routes.include) {
|
|
22
22
|
if (isRoutingRuleMatch(pathname, include)) {
|
|
23
|
-
|
|
23
|
+
const workerAsHandler = worker as ExportedHandler;
|
|
24
|
+
if (workerAsHandler.fetch === undefined) {
|
|
24
25
|
throw new TypeError("Entry point missing `fetch` handler");
|
|
25
26
|
}
|
|
26
|
-
return
|
|
27
|
+
return workerAsHandler.fetch(request, env, context);
|
|
27
28
|
}
|
|
28
29
|
}
|
|
29
30
|
|
|
@@ -41,14 +41,14 @@ type EventPluginContext<Env, P extends string, Data, PluginArgs> = {
|
|
|
41
41
|
declare type PagesFunction<
|
|
42
42
|
Env = unknown,
|
|
43
43
|
P extends string = string,
|
|
44
|
-
Data extends Record<string, unknown> = Record<string, unknown
|
|
44
|
+
Data extends Record<string, unknown> = Record<string, unknown>,
|
|
45
45
|
> = (context: EventContext<Env, P, Data>) => Response | Promise<Response>;
|
|
46
46
|
|
|
47
47
|
declare type PagesPluginFunction<
|
|
48
48
|
Env = unknown,
|
|
49
49
|
P extends string = string,
|
|
50
50
|
Data extends Record<string, unknown> = Record<string, unknown>,
|
|
51
|
-
PluginArgs = unknown
|
|
51
|
+
PluginArgs = unknown,
|
|
52
52
|
> = (
|
|
53
53
|
context: EventPluginContext<Env, P, Data, PluginArgs>
|
|
54
54
|
) => Response | Promise<Response>;
|
|
@@ -29,7 +29,7 @@ type EventContext<Env, P extends string, Data> = {
|
|
|
29
29
|
declare type PagesFunction<
|
|
30
30
|
Env = unknown,
|
|
31
31
|
P extends string = string,
|
|
32
|
-
Data extends Record<string, unknown> = Record<string, unknown
|
|
32
|
+
Data extends Record<string, unknown> = Record<string, unknown>,
|
|
33
33
|
> = (context: EventContext<Env, P, Data>) => Response | Promise<Response>;
|
|
34
34
|
/* end @cloudflare/workers-types */
|
|
35
35
|
|
|
@@ -60,7 +60,10 @@ function isDevToolsEvent<Method extends DevToolsEvents["method"]>(
|
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
export class InspectorProxyWorker implements DurableObject {
|
|
63
|
-
constructor(
|
|
63
|
+
constructor(
|
|
64
|
+
_state: DurableObjectState,
|
|
65
|
+
readonly env: Env
|
|
66
|
+
) {}
|
|
64
67
|
|
|
65
68
|
websockets: {
|
|
66
69
|
proxyController?: WebSocket;
|
|
@@ -82,6 +85,9 @@ export class InspectorProxyWorker implements DurableObject {
|
|
|
82
85
|
proxyData?: ProxyData;
|
|
83
86
|
runtimeMessageBuffer: (DevToolsCommandResponses | DevToolsEvents)[] = [];
|
|
84
87
|
|
|
88
|
+
// Only allow a limited number of error-based reconnections, so as not to infinite loop
|
|
89
|
+
reconnectionsRemaining = 3;
|
|
90
|
+
|
|
85
91
|
async fetch(req: Request) {
|
|
86
92
|
if (
|
|
87
93
|
req.headers.get("Authorization") === this.env.PROXY_CONTROLLER_AUTH_SECRET
|
|
@@ -314,6 +320,17 @@ export class InspectorProxyWorker implements DurableObject {
|
|
|
314
320
|
`Failed to establish the WebSocket connection: expected server to reply with HTTP status code 101 (switching protocols), but received ${upgrade.status} instead.`
|
|
315
321
|
);
|
|
316
322
|
|
|
323
|
+
// Sometimes the backend will fail to connect the runtime websocket with a 502 error. These are usually transient, so try and reconnect
|
|
324
|
+
if (upgrade.status === 502 && this.reconnectionsRemaining >= 0) {
|
|
325
|
+
await scheduler.wait((3 - this.reconnectionsRemaining) * 1000);
|
|
326
|
+
this.sendDebugLog(
|
|
327
|
+
"RECONNECTING RUNTIME WEBSOCKET after 502. Reconnections remaining:",
|
|
328
|
+
this.reconnectionsRemaining
|
|
329
|
+
);
|
|
330
|
+
|
|
331
|
+
return this.reconnectRuntimeWebSocket();
|
|
332
|
+
}
|
|
333
|
+
|
|
317
334
|
this.websockets.runtimeDeferred.reject(error);
|
|
318
335
|
this.sendProxyControllerRequest({
|
|
319
336
|
type: "runtime-websocket-error",
|
|
@@ -374,6 +391,7 @@ export class InspectorProxyWorker implements DurableObject {
|
|
|
374
391
|
}
|
|
375
392
|
handleRuntimeWebSocketOpen(runtime: WebSocket) {
|
|
376
393
|
this.sendDebugLog("RUNTIME WEBSOCKET OPENED");
|
|
394
|
+
this.reconnectionsRemaining = 3;
|
|
377
395
|
|
|
378
396
|
this.sendRuntimeMessage(
|
|
379
397
|
{ method: "Runtime.enable", id: this.nextCounter() },
|
|
@@ -33,7 +33,10 @@ export default {
|
|
|
33
33
|
} as ExportedHandler<Env, unknown, ProxyWorkerIncomingRequestBody>;
|
|
34
34
|
|
|
35
35
|
export class ProxyWorker implements DurableObject {
|
|
36
|
-
constructor(
|
|
36
|
+
constructor(
|
|
37
|
+
readonly state: DurableObjectState,
|
|
38
|
+
readonly env: Env
|
|
39
|
+
) {}
|
|
37
40
|
|
|
38
41
|
proxyData?: ProxyData;
|
|
39
42
|
requestQueue = new Map<Request, DeferredPromise<Response>>();
|
|
@@ -121,8 +124,10 @@ export class ProxyWorker implements DurableObject {
|
|
|
121
124
|
Object.assign(userWorkerUrl, proxyData.userWorkerUrl);
|
|
122
125
|
|
|
123
126
|
// set request.url in the UserWorker
|
|
124
|
-
const innerUrl =
|
|
125
|
-
|
|
127
|
+
const innerUrl = urlFromParts(
|
|
128
|
+
proxyData.userWorkerInnerUrlOverrides ?? {},
|
|
129
|
+
request.url
|
|
130
|
+
);
|
|
126
131
|
headers.set("MF-Original-URL", innerUrl.href);
|
|
127
132
|
headers.set("MF-Disable-Pretty-Error", "true"); // disables the UserWorker miniflare instance from rendering the pretty error -- instead the ProxyWorker miniflare instance will intercept the json error response and render the pretty error page
|
|
128
133
|
|
|
@@ -273,28 +278,7 @@ function insertLiveReloadScript(
|
|
|
273
278
|
websocketUrl.protocol =
|
|
274
279
|
websocketUrl.protocol === "http:" ? "ws:" : "wss:";
|
|
275
280
|
|
|
276
|
-
end.append(
|
|
277
|
-
`
|
|
278
|
-
<script>
|
|
279
|
-
(function() {
|
|
280
|
-
var ws;
|
|
281
|
-
function recover() {
|
|
282
|
-
ws = null;
|
|
283
|
-
setTimeout(initLiveReload, 100);
|
|
284
|
-
}
|
|
285
|
-
function initLiveReload() {
|
|
286
|
-
if (ws) return;
|
|
287
|
-
var origin = (location.protocol === "http:" ? "ws://" : "wss://") + location.host;
|
|
288
|
-
ws = new WebSocket(origin + "/cdn-cgi/live-reload", "${LIVE_RELOAD_PROTOCOL}");
|
|
289
|
-
ws.onclose = recover;
|
|
290
|
-
ws.onerror = recover;
|
|
291
|
-
ws.onmessage = location.reload.bind(location);
|
|
292
|
-
}
|
|
293
|
-
})();
|
|
294
|
-
</script>
|
|
295
|
-
`,
|
|
296
|
-
{ html: true }
|
|
297
|
-
);
|
|
281
|
+
end.append(liveReloadScript, { html: true });
|
|
298
282
|
}
|
|
299
283
|
},
|
|
300
284
|
});
|
|
@@ -302,6 +286,27 @@ function insertLiveReloadScript(
|
|
|
302
286
|
return htmlRewriter.transform(response);
|
|
303
287
|
}
|
|
304
288
|
|
|
289
|
+
const liveReloadScript = `
|
|
290
|
+
<script defer type="application/javascript">
|
|
291
|
+
(function() {
|
|
292
|
+
var ws;
|
|
293
|
+
function recover() {
|
|
294
|
+
ws = null;
|
|
295
|
+
setTimeout(initLiveReload, 100);
|
|
296
|
+
}
|
|
297
|
+
function initLiveReload() {
|
|
298
|
+
if (ws) return;
|
|
299
|
+
var origin = (location.protocol === "http:" ? "ws://" : "wss://") + location.host;
|
|
300
|
+
ws = new WebSocket(origin + "/cdn-cgi/live-reload", "${LIVE_RELOAD_PROTOCOL}");
|
|
301
|
+
ws.onclose = recover;
|
|
302
|
+
ws.onerror = recover;
|
|
303
|
+
ws.onmessage = location.reload.bind(location);
|
|
304
|
+
}
|
|
305
|
+
initLiveReload();
|
|
306
|
+
})();
|
|
307
|
+
</script>
|
|
308
|
+
`;
|
|
309
|
+
|
|
305
310
|
/**
|
|
306
311
|
* Rewrite references to URLs in request/response headers.
|
|
307
312
|
*
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
function stripCfConnectingIPHeader(input, init) {
|
|
2
|
+
const request = new Request(input, init);
|
|
3
|
+
request.headers.delete("CF-Connecting-IP");
|
|
4
|
+
return request;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
globalThis.fetch = new Proxy(globalThis.fetch, {
|
|
8
|
+
apply(target, thisArg, argArray) {
|
|
9
|
+
return Reflect.apply(target, thisArg, [
|
|
10
|
+
stripCfConnectingIPHeader.apply(null, argArray),
|
|
11
|
+
]);
|
|
12
|
+
},
|
|
13
|
+
});
|