@jakuta-inc/worker-proxy 0.1.3 → 2.0.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/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/same-origin-proxy.d.ts +20 -19
- package/dist/same-origin-proxy.d.ts.map +1 -1
- package/dist/same-origin-proxy.js +93 -37
- package/dist/same-origin-proxy.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export type { WorkerProxyConfig,
|
|
2
|
-
export {
|
|
1
|
+
export type { WorkerProxyConfig, ProxyOutcome, ProxyHandler, ProxyError } from "./same-origin-proxy.js";
|
|
2
|
+
export { ADMIN_API_BASE, createProxyHandler } from "./same-origin-proxy.js";
|
|
3
3
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,iBAAiB,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACxG,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { ADMIN_API_BASE, createProxyHandler } from "./same-origin-proxy.js";
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export declare const ADMIN_API_BASE = "https://jakuta-admin-api.fly.dev";
|
|
1
2
|
/**
|
|
2
3
|
* @field ventureApiBase - Origin of the venture's Fly.io backend (e.g. "https://venoble-backend.fly.dev")
|
|
3
4
|
* @field adminApiBase - Origin of the jakuta-admin API on Fly.io (e.g. "https://jakuta-admin-api.fly.dev")
|
|
@@ -6,15 +7,6 @@ export interface WorkerProxyConfig {
|
|
|
6
7
|
ventureApiBase: string;
|
|
7
8
|
adminApiBase: string;
|
|
8
9
|
}
|
|
9
|
-
/**
|
|
10
|
-
* @field request - The incoming Cloudflare Worker request to evaluate for proxy routing
|
|
11
|
-
* @field proxyConfig - Backend origins to proxy to
|
|
12
|
-
*/
|
|
13
|
-
export interface ProxyRequestParams {
|
|
14
|
-
request: Request;
|
|
15
|
-
proxyConfig: WorkerProxyConfig;
|
|
16
|
-
}
|
|
17
|
-
/** Discriminated union: either the request was proxied or it should fall through to OpenNext. */
|
|
18
10
|
export type ProxyOutcome = {
|
|
19
11
|
readonly proxied: true;
|
|
20
12
|
readonly proxiedResponse: Response;
|
|
@@ -22,15 +14,24 @@ export type ProxyOutcome = {
|
|
|
22
14
|
readonly proxied: false;
|
|
23
15
|
};
|
|
24
16
|
/**
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
17
|
+
* @field kind - Discriminant tag for the error variant
|
|
18
|
+
* @field target - Full URL that the proxy attempted to reach
|
|
19
|
+
* @field backendName - Which backend was unreachable
|
|
20
|
+
*/
|
|
21
|
+
export type ProxyError = {
|
|
22
|
+
kind: "backend_unreachable";
|
|
23
|
+
target: string;
|
|
24
|
+
backendName: "venture" | "admin";
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* @field handleRequest - Route an incoming worker request through the proxy, returning a proxied response or fall-through signal
|
|
28
|
+
*/
|
|
29
|
+
export interface ProxyHandler {
|
|
30
|
+
handleRequest(workerRequest: Request): Promise<ProxyOutcome>;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* @param proxyConfig - Backend origins to proxy to; bound once at Worker startup
|
|
34
|
+
* @returns ProxyHandler that routes /api/*, /auth/*, and /_proxy/health requests
|
|
34
35
|
*/
|
|
35
|
-
export declare function
|
|
36
|
+
export declare function createProxyHandler(proxyConfig: WorkerProxyConfig): ProxyHandler;
|
|
36
37
|
//# sourceMappingURL=same-origin-proxy.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"same-origin-proxy.d.ts","sourceRoot":"","sources":["../src/same-origin-proxy.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED
|
|
1
|
+
{"version":3,"file":"same-origin-proxy.d.ts","sourceRoot":"","sources":["../src/same-origin-proxy.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc,qCAAqC,CAAC;AAEjE;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,MAAM,YAAY,GACpB;IAAE,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,eAAe,EAAE,QAAQ,CAAA;CAAE,GAC9D;IAAE,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAA;CAAE,CAAC;AAEhC;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,qBAAqB,CAAC;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,SAAS,GAAG,OAAO,CAAC;CAClC,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,aAAa,CAAC,aAAa,EAAE,OAAO,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;CAC9D;AAmFD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,iBAAiB,GAAG,YAAY,CAiD/E"}
|
|
@@ -1,44 +1,100 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
originalUrl: requestUrl,
|
|
18
|
-
targetBase: proxyRequest.proxyConfig.ventureApiBase,
|
|
19
|
-
targetPath: requestUrl.pathname,
|
|
1
|
+
export const ADMIN_API_BASE = "https://jakuta-admin-api.fly.dev";
|
|
2
|
+
const HEALTH_TIMEOUT_MS = 5000;
|
|
3
|
+
function stripTrailingSlash(originUrl) {
|
|
4
|
+
return originUrl.endsWith("/") ? originUrl.slice(0, -1) : originUrl;
|
|
5
|
+
}
|
|
6
|
+
function jsonErrorResponse(errorInput) {
|
|
7
|
+
return new Response(JSON.stringify(errorInput.errorBody), {
|
|
8
|
+
status: errorInput.httpStatus,
|
|
9
|
+
headers: { "content-type": "application/json" },
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
async function probeHealth(baseUrl) {
|
|
13
|
+
const probeUrl = new URL("/health", baseUrl).toString();
|
|
14
|
+
try {
|
|
15
|
+
const healthResponse = await fetch(probeUrl, {
|
|
16
|
+
signal: AbortSignal.timeout(HEALTH_TIMEOUT_MS),
|
|
20
17
|
});
|
|
21
|
-
return {
|
|
18
|
+
return { status: healthResponse.ok ? "ok" : "error", probeUrl };
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return { status: "error", probeUrl };
|
|
22
22
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
23
|
+
}
|
|
24
|
+
async function forwardToBackend(forwardInput) {
|
|
25
|
+
const targetUrl = new URL(forwardInput.targetPath + forwardInput.originalUrl.search, forwardInput.targetBase);
|
|
26
|
+
try {
|
|
27
|
+
return await fetch(new Request(targetUrl, {
|
|
28
|
+
method: forwardInput.originalRequest.method,
|
|
29
|
+
headers: forwardInput.originalRequest.headers,
|
|
30
|
+
body: forwardInput.originalRequest.body,
|
|
31
|
+
redirect: "manual",
|
|
32
|
+
}));
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
const proxyError = {
|
|
36
|
+
kind: "backend_unreachable",
|
|
37
|
+
target: targetUrl.toString(),
|
|
38
|
+
backendName: forwardInput.backendName,
|
|
39
|
+
};
|
|
40
|
+
return jsonErrorResponse({
|
|
41
|
+
httpStatus: 502,
|
|
42
|
+
errorBody: {
|
|
43
|
+
error: proxyError.kind,
|
|
44
|
+
target: proxyError.target,
|
|
45
|
+
backend: proxyError.backendName,
|
|
46
|
+
message: `Proxy couldn't reach the ${proxyError.backendName} backend at ${proxyError.target}. Check /_proxy/health to verify both backends are reachable.`,
|
|
47
|
+
},
|
|
30
48
|
});
|
|
31
|
-
return { proxied: true, proxiedResponse };
|
|
32
49
|
}
|
|
33
|
-
return { proxied: false };
|
|
34
50
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
51
|
+
/**
|
|
52
|
+
* @param proxyConfig - Backend origins to proxy to; bound once at Worker startup
|
|
53
|
+
* @returns ProxyHandler that routes /api/*, /auth/*, and /_proxy/health requests
|
|
54
|
+
*/
|
|
55
|
+
export function createProxyHandler(proxyConfig) {
|
|
56
|
+
const ventureBase = stripTrailingSlash(proxyConfig.ventureApiBase);
|
|
57
|
+
const adminBase = stripTrailingSlash(proxyConfig.adminApiBase);
|
|
58
|
+
return {
|
|
59
|
+
async handleRequest(workerRequest) {
|
|
60
|
+
const requestUrl = new URL(workerRequest.url);
|
|
61
|
+
const pathname = requestUrl.pathname;
|
|
62
|
+
if (pathname === "/_proxy/health") {
|
|
63
|
+
const [venture, admin] = await Promise.all([
|
|
64
|
+
probeHealth(ventureBase),
|
|
65
|
+
probeHealth(adminBase),
|
|
66
|
+
]);
|
|
67
|
+
const healthStatus = { venture, admin };
|
|
68
|
+
const allOk = venture.status === "ok" && admin.status === "ok";
|
|
69
|
+
const proxiedResponse = new Response(JSON.stringify(healthStatus), {
|
|
70
|
+
status: allOk ? 200 : 503,
|
|
71
|
+
headers: { "content-type": "application/json" },
|
|
72
|
+
});
|
|
73
|
+
return { proxied: true, proxiedResponse };
|
|
74
|
+
}
|
|
75
|
+
if (pathname === "/api" || pathname.startsWith("/api/")) {
|
|
76
|
+
const proxiedResponse = await forwardToBackend({
|
|
77
|
+
originalRequest: workerRequest,
|
|
78
|
+
originalUrl: requestUrl,
|
|
79
|
+
targetBase: ventureBase,
|
|
80
|
+
targetPath: pathname,
|
|
81
|
+
backendName: "venture",
|
|
82
|
+
});
|
|
83
|
+
return { proxied: true, proxiedResponse };
|
|
84
|
+
}
|
|
85
|
+
if (pathname === "/auth" || pathname.startsWith("/auth/")) {
|
|
86
|
+
const adminPath = "/api" + pathname;
|
|
87
|
+
const proxiedResponse = await forwardToBackend({
|
|
88
|
+
originalRequest: workerRequest,
|
|
89
|
+
originalUrl: requestUrl,
|
|
90
|
+
targetBase: adminBase,
|
|
91
|
+
targetPath: adminPath,
|
|
92
|
+
backendName: "admin",
|
|
93
|
+
});
|
|
94
|
+
return { proxied: true, proxiedResponse };
|
|
95
|
+
}
|
|
96
|
+
return { proxied: false };
|
|
97
|
+
},
|
|
98
|
+
};
|
|
43
99
|
}
|
|
44
100
|
//# sourceMappingURL=same-origin-proxy.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"same-origin-proxy.js","sourceRoot":"","sources":["../src/same-origin-proxy.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"same-origin-proxy.js","sourceRoot":"","sources":["../src/same-origin-proxy.ts"],"names":[],"mappings":"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"}
|