-
Notifications
You must be signed in to change notification settings - Fork 1
/
_worker.js
80 lines (65 loc) · 1.74 KB
/
_worker.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
import * as backends from "./backend/main.js";
/**
* A handler
*
* @callback Handler
* @param {Request} request
* @param {Object} env Environment variables.
* @returns {Response|Promise<Response>}
*/
/**
* Serves a bare remote, i.e., `/:memory:/path/to/file`
*
* All configuration must be passed as query parameters.
*
* @param {Request} request
* @param {Object} env
* @param {Object} params
* @param {string} params.remote
* @param {string} [params.path]
* @returns {Promise<Response}
*/
function remote(request, _env, params) {
let { remote, path = "/" } = params;
const backend = backends[remote];
if (!backend) {
return new Response("Remote not found.", { status: 404 });
}
if (!path) {
path = "/";
}
const url = new URL(request.url);
url.pathname = path;
request = new Request(url, request);
return backend.fetch(request);
}
const routes = {
"/\\::remote\\:/": remote,
"/\\::remote\\:/:path*": remote,
"/\\::remote\\:/:path*/": (request, env, params) => {
params.path += "/";
return remote(request, env, params);
},
};
/**
* Routes request to the appropriate handler.
* @param {Object} routes
* @returns {Handler}
*/
function router(routes = {}) {
return function (request, env) {
const url = new URL(request.url);
for (const [route, handler] of Object.entries(routes)) {
const [pathname, method] = route.split("@").reverse();
if (method && request.method !== method) continue;
const pattern = new URLPattern({ pathname });
if (!pattern.test(url)) continue;
const params = pattern.exec(url)?.pathname?.groups || {};
return handler(request, env, params);
}
return env.ASSETS.fetch(request);
};
}
export default {
fetch: router(routes),
};