wrangler 0.0.0-eab9542 → 0.0.0-eaf71b86c
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 -13
- package/bin/wrangler.js +50 -88
- package/config-schema.json +3074 -0
- package/package.json +196 -157
- package/templates/__tests__/pages-dev-util.test.ts +128 -0
- package/templates/__tests__/tsconfig-sanity.ts +12 -0
- package/templates/__tests__/tsconfig.json +8 -0
- package/templates/checked-fetch.js +19 -6
- package/templates/facade.d.ts +19 -0
- package/templates/gitignore +2 -3
- package/templates/init-tests/test-jest-new-worker.js +23 -0
- package/templates/init-tests/test-vitest-new-worker.js +24 -0
- package/templates/init-tests/test-vitest-new-worker.ts +25 -0
- package/templates/middleware/common.ts +67 -0
- package/templates/middleware/loader-modules.ts +134 -0
- package/templates/middleware/loader-sw.ts +229 -0
- package/templates/middleware/middleware-ensure-req-body-drained.ts +18 -0
- package/templates/middleware/middleware-miniflare3-json-error.ts +32 -0
- package/templates/middleware/middleware-mock-analytics-engine.d.ts +3 -0
- package/templates/middleware/middleware-mock-analytics-engine.ts +30 -0
- package/templates/middleware/middleware-pretty-error.ts +40 -0
- package/templates/middleware/middleware-scheduled.ts +29 -0
- package/templates/middleware/middleware-serve-static-assets.d.ts +6 -0
- package/templates/middleware/middleware-serve-static-assets.ts +56 -0
- package/templates/modules-watch-stub.js +4 -0
- package/templates/new-worker-scheduled.ts +1 -1
- package/templates/new-worker.js +1 -1
- package/templates/new-worker.ts +4 -1
- package/templates/pages-dev-pipeline.ts +32 -0
- package/templates/pages-dev-util.ts +55 -0
- package/templates/pages-shim.ts +9 -0
- package/templates/pages-template-plugin.ts +53 -18
- package/templates/pages-template-worker.ts +49 -12
- package/templates/startDevWorker/InspectorProxyWorker.ts +664 -0
- package/templates/startDevWorker/ProxyWorker.ts +336 -0
- package/templates/tsconfig-sanity.ts +11 -0
- package/templates/tsconfig.init.json +22 -0
- package/templates/tsconfig.json +5 -102
- package/wrangler-dist/InspectorProxyWorker.js +464 -0
- package/wrangler-dist/InspectorProxyWorker.js.map +6 -0
- package/wrangler-dist/ProxyWorker.js +241 -0
- package/wrangler-dist/ProxyWorker.js.map +6 -0
- package/wrangler-dist/cli.d.ts +26465 -0
- package/wrangler-dist/cli.js +198587 -108581
- package/wrangler-dist/wasm-sync.wasm +0 -0
- package/Cloudflare_CA.pem +0 -18
- package/import_meta_url.js +0 -3
- package/miniflare-config-stubs/.env.empty +0 -0
- package/miniflare-config-stubs/package.empty.json +0 -1
- package/miniflare-config-stubs/wrangler.empty.toml +0 -0
- package/miniflare-dist/index.mjs +0 -4894
- package/src/__tests__/config-cache-without-cache-dir.test.ts +0 -38
- package/src/__tests__/config-cache.test.ts +0 -42
- package/src/__tests__/configuration.test.ts +0 -3946
- package/src/__tests__/dev.test.tsx +0 -1159
- package/src/__tests__/guess-worker-format.test.ts +0 -85
- package/src/__tests__/helpers/clipboardy-mock.js +0 -4
- package/src/__tests__/helpers/cmd-shim.d.ts +0 -11
- package/src/__tests__/helpers/faye-websocket.d.ts +0 -6
- package/src/__tests__/helpers/mock-account-id.ts +0 -48
- package/src/__tests__/helpers/mock-bin.ts +0 -36
- package/src/__tests__/helpers/mock-cfetch.ts +0 -211
- package/src/__tests__/helpers/mock-console.ts +0 -97
- package/src/__tests__/helpers/mock-dialogs.ts +0 -153
- package/src/__tests__/helpers/mock-http-server.ts +0 -46
- package/src/__tests__/helpers/mock-istty.ts +0 -74
- package/src/__tests__/helpers/mock-kv.ts +0 -33
- package/src/__tests__/helpers/mock-oauth-flow.ts +0 -250
- package/src/__tests__/helpers/mock-process.ts +0 -39
- package/src/__tests__/helpers/mock-stdin.ts +0 -108
- package/src/__tests__/helpers/mock-web-socket.ts +0 -29
- package/src/__tests__/helpers/run-in-tmp.ts +0 -39
- package/src/__tests__/helpers/run-wrangler.ts +0 -16
- package/src/__tests__/helpers/write-worker-source.ts +0 -31
- package/src/__tests__/helpers/write-wrangler-toml.ts +0 -17
- package/src/__tests__/https-options.test.ts +0 -130
- package/src/__tests__/index.test.ts +0 -262
- package/src/__tests__/init.test.ts +0 -1992
- package/src/__tests__/jest.setup.ts +0 -107
- package/src/__tests__/kv.test.ts +0 -1619
- package/src/__tests__/logger.test.ts +0 -141
- package/src/__tests__/package-manager.test.ts +0 -353
- package/src/__tests__/pages.test.ts +0 -1254
- package/src/__tests__/parse.test.ts +0 -330
- package/src/__tests__/publish.test.ts +0 -6569
- package/src/__tests__/pubsub.test.ts +0 -367
- package/src/__tests__/r2.test.ts +0 -233
- package/src/__tests__/route.test.ts +0 -45
- package/src/__tests__/secret.test.ts +0 -486
- package/src/__tests__/tail.test.ts +0 -690
- package/src/__tests__/user.test.ts +0 -143
- package/src/__tests__/whoami.test.tsx +0 -220
- package/src/__tests__/worker-namespace.test.ts +0 -327
- package/src/abort.d.ts +0 -3
- package/src/api/dev.ts +0 -52
- package/src/api/index.ts +0 -1
- package/src/bundle-reporter.tsx +0 -29
- package/src/bundle.ts +0 -212
- package/src/cfetch/index.ts +0 -121
- package/src/cfetch/internal.ts +0 -149
- package/src/cli.ts +0 -27
- package/src/config/README.md +0 -107
- package/src/config/config.ts +0 -243
- package/src/config/diagnostics.ts +0 -80
- package/src/config/environment.ts +0 -453
- package/src/config/index.ts +0 -238
- package/src/config/validation-helpers.ts +0 -584
- package/src/config/validation.ts +0 -1745
- package/src/config-cache.ts +0 -83
- package/src/create-worker-preview.ts +0 -255
- package/src/create-worker-upload-form.ts +0 -263
- package/src/dev/dev-vars.ts +0 -36
- package/src/dev/dev.tsx +0 -417
- package/src/dev/local.tsx +0 -352
- package/src/dev/remote.tsx +0 -382
- package/src/dev/use-esbuild.ts +0 -150
- package/src/dev.tsx +0 -538
- package/src/dialogs.tsx +0 -135
- package/src/durable.ts +0 -102
- package/src/entry.ts +0 -328
- package/src/environment-variables.ts +0 -35
- package/src/errors.ts +0 -11
- package/src/generate.ts +0 -33
- package/src/git-client.ts +0 -42
- package/src/https-options.ts +0 -123
- package/src/index.tsx +0 -1871
- package/src/init.ts +0 -549
- package/src/inspect.ts +0 -662
- package/src/intl-polyfill.d.ts +0 -139
- package/src/is-interactive.ts +0 -12
- package/src/kv.ts +0 -408
- package/src/logger.ts +0 -73
- package/src/miniflare-cli/README.md +0 -30
- package/src/miniflare-cli/enum-keys.ts +0 -17
- package/src/miniflare-cli/index.ts +0 -53
- package/src/miniflare-cli/request-context.ts +0 -40
- package/src/module-collection.ts +0 -258
- package/src/open-in-browser.ts +0 -17
- package/src/package-manager.ts +0 -174
- package/src/pages/build.tsx +0 -202
- package/src/pages/constants.ts +0 -7
- package/src/pages/deployments.tsx +0 -101
- package/src/pages/dev.tsx +0 -964
- package/src/pages/functions/buildPlugin.ts +0 -105
- package/src/pages/functions/buildWorker.ts +0 -151
- package/src/pages/functions/filepath-routing.test.ts +0 -234
- package/src/pages/functions/filepath-routing.ts +0 -189
- package/src/pages/functions/identifiers.ts +0 -78
- package/src/pages/functions/routes.ts +0 -151
- package/src/pages/index.tsx +0 -84
- package/src/pages/projects.tsx +0 -157
- package/src/pages/publish.tsx +0 -335
- package/src/pages/types.ts +0 -40
- package/src/pages/upload.tsx +0 -384
- package/src/pages/utils.ts +0 -12
- package/src/parse.ts +0 -286
- package/src/paths.ts +0 -26
- package/src/preview.ts +0 -31
- package/src/proxy.ts +0 -476
- package/src/publish.ts +0 -767
- package/src/pubsub/index.ts +0 -286
- package/src/pubsub/pubsub-commands.tsx +0 -577
- package/src/r2.ts +0 -50
- package/src/selfsigned.d.ts +0 -29
- package/src/sites.tsx +0 -372
- package/src/tail/filters.ts +0 -279
- package/src/tail/index.ts +0 -299
- package/src/tail/printing.ts +0 -67
- package/src/update-check.ts +0 -19
- package/src/user/choose-account.tsx +0 -60
- package/src/user/env-vars.ts +0 -46
- package/src/user/generate-auth-url.ts +0 -33
- package/src/user/generate-random-state.ts +0 -16
- package/src/user/index.ts +0 -3
- package/src/user/user.tsx +0 -1161
- package/src/whoami.tsx +0 -90
- package/src/worker-namespace.ts +0 -190
- package/src/worker.ts +0 -191
- package/src/zones.ts +0 -76
- package/templates/static-asset-facade.js +0 -43
package/templates/new-worker.js
CHANGED
package/templates/new-worker.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* - Run `wrangler dev src/index.ts` in your terminal to start a development server
|
|
5
5
|
* - Open a browser tab at http://localhost:8787/ to see your worker in action
|
|
6
|
-
* - Run `wrangler
|
|
6
|
+
* - Run `wrangler deploy src/index.ts --name my-worker` to deploy your worker
|
|
7
7
|
*
|
|
8
8
|
* Learn more at https://developers.cloudflare.com/workers/
|
|
9
9
|
*/
|
|
@@ -17,6 +17,9 @@ export interface Env {
|
|
|
17
17
|
//
|
|
18
18
|
// Example binding to R2. Learn more at https://developers.cloudflare.com/workers/runtime-apis/r2/
|
|
19
19
|
// MY_BUCKET: R2Bucket;
|
|
20
|
+
//
|
|
21
|
+
// Example binding to a Service. Learn more at https://developers.cloudflare.com/workers/runtime-apis/service-bindings/
|
|
22
|
+
// MY_SERVICE: Fetcher;
|
|
20
23
|
}
|
|
21
24
|
|
|
22
25
|
export default {
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// @ts-ignore entry point will get replaced
|
|
2
|
+
import worker from "__ENTRY_POINT__";
|
|
3
|
+
import { isRoutingRuleMatch } from "./pages-dev-util";
|
|
4
|
+
|
|
5
|
+
// @ts-ignore entry point will get replaced
|
|
6
|
+
export * from "__ENTRY_POINT__";
|
|
7
|
+
|
|
8
|
+
// @ts-ignore routes are injected
|
|
9
|
+
const routes = __ROUTES__;
|
|
10
|
+
|
|
11
|
+
export default <ExportedHandler<{ ASSETS: Fetcher }>>{
|
|
12
|
+
fetch(request, env, context) {
|
|
13
|
+
const { pathname } = new URL(request.url);
|
|
14
|
+
|
|
15
|
+
for (const exclude of routes.exclude) {
|
|
16
|
+
if (isRoutingRuleMatch(pathname, exclude)) {
|
|
17
|
+
return env.ASSETS.fetch(request);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
for (const include of routes.include) {
|
|
22
|
+
if (isRoutingRuleMatch(pathname, include)) {
|
|
23
|
+
if (worker.fetch === undefined) {
|
|
24
|
+
throw new TypeError("Entry point missing `fetch` handler");
|
|
25
|
+
}
|
|
26
|
+
return worker.fetch(request, env, context);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return env.ASSETS.fetch(request);
|
|
31
|
+
},
|
|
32
|
+
};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param pathname A pathname string, such as `/foo` or `/foo/bar`
|
|
3
|
+
* @param routingRule The routing rule, such as `/foo/*`
|
|
4
|
+
* @returns True if pathname matches the routing rule
|
|
5
|
+
*
|
|
6
|
+
* / -> /
|
|
7
|
+
* /* -> /*
|
|
8
|
+
* /foo -> /foo
|
|
9
|
+
* /foo* -> /foo, /foo-bar, /foo/*
|
|
10
|
+
* /foo/* -> /foo, /foo/bar
|
|
11
|
+
*/
|
|
12
|
+
export function isRoutingRuleMatch(
|
|
13
|
+
pathname: string,
|
|
14
|
+
routingRule: string
|
|
15
|
+
): boolean {
|
|
16
|
+
// sanity checks
|
|
17
|
+
if (!pathname) {
|
|
18
|
+
throw new Error("Pathname is undefined.");
|
|
19
|
+
}
|
|
20
|
+
if (!routingRule) {
|
|
21
|
+
throw new Error("Routing rule is undefined.");
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const ruleRegExp = transformRoutingRuleToRegExp(routingRule);
|
|
25
|
+
return pathname.match(ruleRegExp) !== null;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function transformRoutingRuleToRegExp(rule: string): RegExp {
|
|
29
|
+
let transformedRule;
|
|
30
|
+
|
|
31
|
+
if (rule === "/" || rule === "/*") {
|
|
32
|
+
transformedRule = rule;
|
|
33
|
+
} else if (rule.endsWith("/*")) {
|
|
34
|
+
// make `/*` an optional group so we can match both /foo/* and /foo
|
|
35
|
+
// /foo/* => /foo(/*)?
|
|
36
|
+
transformedRule = `${rule.substring(0, rule.length - 2)}(/*)?`;
|
|
37
|
+
} else if (rule.endsWith("/")) {
|
|
38
|
+
// make `/` an optional group so we can match both /foo/ and /foo
|
|
39
|
+
// /foo/ => /foo(/)?
|
|
40
|
+
transformedRule = `${rule.substring(0, rule.length - 1)}(/)?`;
|
|
41
|
+
} else if (rule.endsWith("*")) {
|
|
42
|
+
transformedRule = rule;
|
|
43
|
+
} else {
|
|
44
|
+
transformedRule = `${rule}(/)?`;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// /foo* => /foo.* => ^/foo.*$
|
|
48
|
+
// /*.* => /*\.* => /.*\..* => ^/.*\..*$
|
|
49
|
+
transformedRule = `^${transformedRule
|
|
50
|
+
.replaceAll(/\./g, "\\.")
|
|
51
|
+
.replaceAll(/\*/g, ".*")}$`;
|
|
52
|
+
|
|
53
|
+
// ^/foo.*$ => /^\/foo.*$/
|
|
54
|
+
return new RegExp(transformedRule);
|
|
55
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// This Worker is used as a default when no Pages Functions are present.
|
|
2
|
+
// It proxies the request directly on to the asset server binding.
|
|
3
|
+
|
|
4
|
+
export default <ExportedHandler<{ ASSETS: Fetcher }>>{
|
|
5
|
+
async fetch(request, env, context) {
|
|
6
|
+
const response = await env.ASSETS.fetch(request.url, request);
|
|
7
|
+
return new Response(response.body, response);
|
|
8
|
+
},
|
|
9
|
+
};
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { match } from "path-to-regexp";
|
|
2
2
|
|
|
3
|
+
//note: this explicitly does not include the * character, as pages requires this
|
|
4
|
+
const escapeRegex = /[.+?^${}()|[\]\\]/g;
|
|
5
|
+
|
|
3
6
|
type HTTPMethod =
|
|
4
7
|
| "HEAD"
|
|
5
8
|
| "OPTIONS"
|
|
@@ -16,6 +19,7 @@ type EventContext<Env, P extends string, Data> = {
|
|
|
16
19
|
request: Request;
|
|
17
20
|
functionPath: string;
|
|
18
21
|
waitUntil: (promise: Promise<unknown>) => void;
|
|
22
|
+
passThroughOnException: () => void;
|
|
19
23
|
next: (input?: Request | string, init?: RequestInit) => Promise<Response>;
|
|
20
24
|
env: Env & { ASSETS: { fetch: typeof fetch } };
|
|
21
25
|
params: Params<P>;
|
|
@@ -26,6 +30,7 @@ type EventPluginContext<Env, P extends string, Data, PluginArgs> = {
|
|
|
26
30
|
request: Request;
|
|
27
31
|
functionPath: string;
|
|
28
32
|
waitUntil: (promise: Promise<unknown>) => void;
|
|
33
|
+
passThroughOnException: () => void;
|
|
29
34
|
next: (input?: Request | string, init?: RequestInit) => Promise<Response>;
|
|
30
35
|
env: Env & { ASSETS: { fetch: typeof fetch } };
|
|
31
36
|
params: Params<P>;
|
|
@@ -36,14 +41,14 @@ type EventPluginContext<Env, P extends string, Data, PluginArgs> = {
|
|
|
36
41
|
declare type PagesFunction<
|
|
37
42
|
Env = unknown,
|
|
38
43
|
P extends string = string,
|
|
39
|
-
Data extends Record<string, unknown> = Record<string, unknown
|
|
44
|
+
Data extends Record<string, unknown> = Record<string, unknown>,
|
|
40
45
|
> = (context: EventContext<Env, P, Data>) => Response | Promise<Response>;
|
|
41
46
|
|
|
42
47
|
declare type PagesPluginFunction<
|
|
43
48
|
Env = unknown,
|
|
44
49
|
P extends string = string,
|
|
45
50
|
Data extends Record<string, unknown> = Record<string, unknown>,
|
|
46
|
-
PluginArgs = unknown
|
|
51
|
+
PluginArgs = unknown,
|
|
47
52
|
> = (
|
|
48
53
|
context: EventPluginContext<Env, P, Data, PluginArgs>
|
|
49
54
|
) => Response | Promise<Response>;
|
|
@@ -67,8 +72,13 @@ function* executeRequest(request: Request, relativePathname: string) {
|
|
|
67
72
|
continue;
|
|
68
73
|
}
|
|
69
74
|
|
|
70
|
-
|
|
71
|
-
const
|
|
75
|
+
// replaces with "\\$&", this prepends a backslash to the matched string, e.g. "[" becomes "\["
|
|
76
|
+
const routeMatcher = match(route.routePath.replace(escapeRegex, "\\$&"), {
|
|
77
|
+
end: false,
|
|
78
|
+
});
|
|
79
|
+
const mountMatcher = match(route.mountPath.replace(escapeRegex, "\\$&"), {
|
|
80
|
+
end: false,
|
|
81
|
+
});
|
|
72
82
|
const matchResult = routeMatcher(relativePathname);
|
|
73
83
|
const mountMatchResult = mountMatcher(relativePathname);
|
|
74
84
|
if (matchResult && mountMatchResult) {
|
|
@@ -88,8 +98,12 @@ function* executeRequest(request: Request, relativePathname: string) {
|
|
|
88
98
|
continue;
|
|
89
99
|
}
|
|
90
100
|
|
|
91
|
-
const routeMatcher = match(route.routePath, {
|
|
92
|
-
|
|
101
|
+
const routeMatcher = match(route.routePath.replace(escapeRegex, "\\$&"), {
|
|
102
|
+
end: true,
|
|
103
|
+
});
|
|
104
|
+
const mountMatcher = match(route.mountPath.replace(escapeRegex, "\\$&"), {
|
|
105
|
+
end: false,
|
|
106
|
+
});
|
|
93
107
|
const matchResult = routeMatcher(relativePathname);
|
|
94
108
|
const mountMatchResult = mountMatcher(relativePathname);
|
|
95
109
|
if (matchResult && mountMatchResult && route.modules.length) {
|
|
@@ -105,20 +119,26 @@ function* executeRequest(request: Request, relativePathname: string) {
|
|
|
105
119
|
}
|
|
106
120
|
}
|
|
107
121
|
|
|
108
|
-
export default function (pluginArgs) {
|
|
122
|
+
export default function (pluginArgs: unknown) {
|
|
109
123
|
const onRequest: PagesPluginFunction = async (workerContext) => {
|
|
110
124
|
let { request } = workerContext;
|
|
111
|
-
const { env, next
|
|
125
|
+
const { env, next } = workerContext;
|
|
126
|
+
let { data } = workerContext;
|
|
112
127
|
|
|
113
128
|
const url = new URL(request.url);
|
|
129
|
+
// TODO: Replace this with something actually legible.
|
|
114
130
|
const relativePathname = `/${
|
|
115
|
-
url.pathname.
|
|
131
|
+
url.pathname.replace(workerContext.functionPath, "") || ""
|
|
116
132
|
}`.replace(/^\/\//, "/");
|
|
117
133
|
|
|
118
134
|
const handlerIterator = executeRequest(request, relativePathname);
|
|
119
135
|
const pluginNext = async (input?: RequestInfo, init?: RequestInit) => {
|
|
120
136
|
if (input !== undefined) {
|
|
121
|
-
|
|
137
|
+
let url = input;
|
|
138
|
+
if (typeof input === "string") {
|
|
139
|
+
url = new URL(input, request.url).toString();
|
|
140
|
+
}
|
|
141
|
+
request = new Request(url, init);
|
|
122
142
|
}
|
|
123
143
|
|
|
124
144
|
const result = handlerIterator.next();
|
|
@@ -126,25 +146,32 @@ export default function (pluginArgs) {
|
|
|
126
146
|
if (result.done === false) {
|
|
127
147
|
const { handler, params, path } = result.value;
|
|
128
148
|
const context = {
|
|
129
|
-
request,
|
|
149
|
+
request: new Request(request.clone()),
|
|
130
150
|
functionPath: workerContext.functionPath + path,
|
|
131
151
|
next: pluginNext,
|
|
132
152
|
params,
|
|
133
|
-
data
|
|
153
|
+
get data() {
|
|
154
|
+
return data;
|
|
155
|
+
},
|
|
156
|
+
set data(value) {
|
|
157
|
+
if (typeof value !== "object" || value === null) {
|
|
158
|
+
throw new Error("context.data must be an object");
|
|
159
|
+
}
|
|
160
|
+
// user has overriden context.data, so we need to merge it with the existing data
|
|
161
|
+
data = value;
|
|
162
|
+
},
|
|
134
163
|
pluginArgs,
|
|
135
164
|
env,
|
|
136
165
|
waitUntil: workerContext.waitUntil.bind(workerContext),
|
|
166
|
+
passThroughOnException:
|
|
167
|
+
workerContext.passThroughOnException.bind(workerContext),
|
|
137
168
|
};
|
|
138
169
|
|
|
139
170
|
const response = await handler(context);
|
|
140
171
|
|
|
141
|
-
|
|
142
|
-
return new Response(
|
|
143
|
-
[101, 204, 205, 304].includes(response.status) ? null : response.body,
|
|
144
|
-
{ ...response, headers: new Headers(response.headers) }
|
|
145
|
-
);
|
|
172
|
+
return cloneResponse(response);
|
|
146
173
|
} else {
|
|
147
|
-
return next();
|
|
174
|
+
return next(request);
|
|
148
175
|
}
|
|
149
176
|
};
|
|
150
177
|
|
|
@@ -153,3 +180,11 @@ export default function (pluginArgs) {
|
|
|
153
180
|
|
|
154
181
|
return onRequest;
|
|
155
182
|
}
|
|
183
|
+
|
|
184
|
+
// This makes a Response mutable
|
|
185
|
+
const cloneResponse = (response: Response) =>
|
|
186
|
+
// https://fetch.spec.whatwg.org/#null-body-status
|
|
187
|
+
new Response(
|
|
188
|
+
[101, 204, 205, 304].includes(response.status) ? null : response.body,
|
|
189
|
+
response
|
|
190
|
+
);
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { match } from "path-to-regexp";
|
|
2
2
|
|
|
3
|
+
//note: this explicitly does not include the * character, as pages requires this
|
|
4
|
+
const escapeRegex = /[.+?^${}()|[\]\\]/g;
|
|
5
|
+
|
|
3
6
|
type HTTPMethod =
|
|
4
7
|
| "HEAD"
|
|
5
8
|
| "OPTIONS"
|
|
@@ -16,6 +19,7 @@ type EventContext<Env, P extends string, Data> = {
|
|
|
16
19
|
request: Request;
|
|
17
20
|
functionPath: string;
|
|
18
21
|
waitUntil: (promise: Promise<unknown>) => void;
|
|
22
|
+
passThroughOnException: () => void;
|
|
19
23
|
next: (input?: Request | string, init?: RequestInit) => Promise<Response>;
|
|
20
24
|
env: Env & { ASSETS: { fetch: typeof fetch } };
|
|
21
25
|
params: Params<P>;
|
|
@@ -25,7 +29,7 @@ type EventContext<Env, P extends string, Data> = {
|
|
|
25
29
|
declare type PagesFunction<
|
|
26
30
|
Env = unknown,
|
|
27
31
|
P extends string = string,
|
|
28
|
-
Data extends Record<string, unknown> = Record<string, unknown
|
|
32
|
+
Data extends Record<string, unknown> = Record<string, unknown>,
|
|
29
33
|
> = (context: EventContext<Env, P, Data>) => Response | Promise<Response>;
|
|
30
34
|
/* end @cloudflare/workers-types */
|
|
31
35
|
|
|
@@ -50,6 +54,7 @@ type FetchEnv = {
|
|
|
50
54
|
|
|
51
55
|
type WorkerContext = {
|
|
52
56
|
waitUntil: (promise: Promise<unknown>) => void;
|
|
57
|
+
passThroughOnException: () => void;
|
|
53
58
|
};
|
|
54
59
|
|
|
55
60
|
function* executeRequest(request: Request) {
|
|
@@ -61,8 +66,13 @@ function* executeRequest(request: Request) {
|
|
|
61
66
|
continue;
|
|
62
67
|
}
|
|
63
68
|
|
|
64
|
-
|
|
65
|
-
const
|
|
69
|
+
// replaces with "\\$&", this prepends a backslash to the matched string, e.g. "[" becomes "\["
|
|
70
|
+
const routeMatcher = match(route.routePath.replace(escapeRegex, "\\$&"), {
|
|
71
|
+
end: false,
|
|
72
|
+
});
|
|
73
|
+
const mountMatcher = match(route.mountPath.replace(escapeRegex, "\\$&"), {
|
|
74
|
+
end: false,
|
|
75
|
+
});
|
|
66
76
|
const matchResult = routeMatcher(requestPath);
|
|
67
77
|
const mountMatchResult = mountMatcher(requestPath);
|
|
68
78
|
if (matchResult && mountMatchResult) {
|
|
@@ -81,9 +91,12 @@ function* executeRequest(request: Request) {
|
|
|
81
91
|
if (route.method && route.method !== request.method) {
|
|
82
92
|
continue;
|
|
83
93
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
94
|
+
const routeMatcher = match(route.routePath.replace(escapeRegex, "\\$&"), {
|
|
95
|
+
end: true,
|
|
96
|
+
});
|
|
97
|
+
const mountMatcher = match(route.mountPath.replace(escapeRegex, "\\$&"), {
|
|
98
|
+
end: false,
|
|
99
|
+
});
|
|
87
100
|
const matchResult = routeMatcher(requestPath);
|
|
88
101
|
const mountMatchResult = mountMatcher(requestPath);
|
|
89
102
|
if (matchResult && mountMatchResult && route.modules.length) {
|
|
@@ -100,9 +113,16 @@ function* executeRequest(request: Request) {
|
|
|
100
113
|
}
|
|
101
114
|
|
|
102
115
|
export default {
|
|
103
|
-
async fetch(
|
|
116
|
+
async fetch(
|
|
117
|
+
originalRequest: Request,
|
|
118
|
+
env: FetchEnv,
|
|
119
|
+
workerContext: WorkerContext
|
|
120
|
+
) {
|
|
121
|
+
let request = originalRequest;
|
|
104
122
|
const handlerIterator = executeRequest(request);
|
|
105
|
-
|
|
123
|
+
let data = {}; // arbitrary data the user can set between functions
|
|
124
|
+
let isFailOpen = false;
|
|
125
|
+
|
|
106
126
|
const next = async (input?: RequestInfo, init?: RequestInit) => {
|
|
107
127
|
if (input !== undefined) {
|
|
108
128
|
let url = input;
|
|
@@ -121,9 +141,21 @@ export default {
|
|
|
121
141
|
functionPath: path,
|
|
122
142
|
next,
|
|
123
143
|
params,
|
|
124
|
-
data
|
|
144
|
+
get data() {
|
|
145
|
+
return data;
|
|
146
|
+
},
|
|
147
|
+
set data(value) {
|
|
148
|
+
if (typeof value !== "object" || value === null) {
|
|
149
|
+
throw new Error("context.data must be an object");
|
|
150
|
+
}
|
|
151
|
+
// user has overriden context.data, so we need to merge it with the existing data
|
|
152
|
+
data = value;
|
|
153
|
+
},
|
|
125
154
|
env,
|
|
126
155
|
waitUntil: workerContext.waitUntil.bind(workerContext),
|
|
156
|
+
passThroughOnException: () => {
|
|
157
|
+
isFailOpen = true;
|
|
158
|
+
},
|
|
127
159
|
};
|
|
128
160
|
|
|
129
161
|
const response = await handler(context);
|
|
@@ -145,9 +177,14 @@ export default {
|
|
|
145
177
|
};
|
|
146
178
|
|
|
147
179
|
try {
|
|
148
|
-
return next();
|
|
149
|
-
} catch (
|
|
150
|
-
|
|
180
|
+
return await next();
|
|
181
|
+
} catch (error) {
|
|
182
|
+
if (isFailOpen) {
|
|
183
|
+
const response = await env[__FALLBACK_SERVICE__].fetch(request);
|
|
184
|
+
return cloneResponse(response);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
throw error;
|
|
151
188
|
}
|
|
152
189
|
},
|
|
153
190
|
};
|