@jakuta-inc/worker-proxy 0.1.3 → 1.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 CHANGED
@@ -1,3 +1,3 @@
1
- export type { WorkerProxyConfig, ProxyRequestParams, ProxyOutcome } from "./same-origin-proxy.js";
2
- export { handleProxyRequest } from "./same-origin-proxy.js";
1
+ export type { WorkerProxyConfig, ProxyOutcome, ProxyHandler } from "./same-origin-proxy.js";
2
+ export { ADMIN_API_BASE, createProxyHandler } from "./same-origin-proxy.js";
3
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAClG,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC5F,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC"}
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- export { handleProxyRequest } from "./same-origin-proxy.js";
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,14 @@ export type ProxyOutcome = {
22
14
  readonly proxied: false;
23
15
  };
24
16
  /**
25
- * Evaluates an incoming request for proxy routing.
26
- *
27
- * /api/* requests proxy to the venture backend (path preserved).
28
- * /auth/* requests proxy to the jakuta-admin API (rewritten to /api/auth/*).
29
- * Everything else returns { proxied: false } so the caller can fall through
30
- * to OpenNext for frontend rendering.
31
- *
32
- * @param proxyRequest - The request and proxy config
33
- * @returns ProxyOutcome indicating whether the request was proxied
17
+ * @field handleRequest - Route an incoming worker request through the proxy, returning a proxied response or fall-through signal
18
+ */
19
+ export interface ProxyHandler {
20
+ handleRequest(workerRequest: Request): Promise<ProxyOutcome>;
21
+ }
22
+ /**
23
+ * @param proxyConfig - Backend origins to proxy to; bound once at Worker startup
24
+ * @returns ProxyHandler that routes /api/*, /auth/*, and /_proxy/health requests
34
25
  */
35
- export declare function handleProxyRequest(proxyRequest: ProxyRequestParams): Promise<ProxyOutcome>;
26
+ export declare function createProxyHandler(proxyConfig: WorkerProxyConfig): ProxyHandler;
36
27
  //# 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;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,iBAAiB,CAAC;CAChC;AAED,iGAAiG;AACjG,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;;;;;;;;;;GAUG;AACH,wBAAsB,kBAAkB,CACtC,YAAY,EAAE,kBAAkB,GAC/B,OAAO,CAAC,YAAY,CAAC,CAyBvB"}
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;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,aAAa,CAAC,aAAa,EAAE,OAAO,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;CAC9D;AAsED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,iBAAiB,GAAG,YAAY,CA+C/E"}
@@ -1,44 +1,91 @@
1
- /**
2
- * Evaluates an incoming request for proxy routing.
3
- *
4
- * /api/* requests proxy to the venture backend (path preserved).
5
- * /auth/* requests proxy to the jakuta-admin API (rewritten to /api/auth/*).
6
- * Everything else returns { proxied: false } so the caller can fall through
7
- * to OpenNext for frontend rendering.
8
- *
9
- * @param proxyRequest - The request and proxy config
10
- * @returns ProxyOutcome indicating whether the request was proxied
11
- */
12
- export async function handleProxyRequest(proxyRequest) {
13
- const requestUrl = new URL(proxyRequest.request.url);
14
- if (requestUrl.pathname.startsWith("/api/")) {
15
- const proxiedResponse = await forwardToBackend({
16
- originalRequest: proxyRequest.request,
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
+ try {
14
+ const healthResponse = await fetch(new URL("/health", baseUrl), {
15
+ signal: AbortSignal.timeout(HEALTH_TIMEOUT_MS),
20
16
  });
21
- return { proxied: true, proxiedResponse };
17
+ return healthResponse.ok ? "ok" : "error";
18
+ }
19
+ catch {
20
+ return "error";
22
21
  }
23
- if (requestUrl.pathname.startsWith("/auth/")) {
24
- const adminPath = "/api" + requestUrl.pathname;
25
- const proxiedResponse = await forwardToBackend({
26
- originalRequest: proxyRequest.request,
27
- originalUrl: requestUrl,
28
- targetBase: proxyRequest.proxyConfig.adminApiBase,
29
- targetPath: adminPath,
22
+ }
23
+ async function forwardToBackend(forwardInput) {
24
+ const targetUrl = new URL(forwardInput.targetPath + forwardInput.originalUrl.search, forwardInput.targetBase);
25
+ try {
26
+ return await fetch(new Request(targetUrl, {
27
+ method: forwardInput.originalRequest.method,
28
+ headers: forwardInput.originalRequest.headers,
29
+ body: forwardInput.originalRequest.body,
30
+ redirect: "manual",
31
+ }));
32
+ }
33
+ catch {
34
+ return jsonErrorResponse({
35
+ httpStatus: 502,
36
+ errorBody: {
37
+ error: "proxy_error",
38
+ message: "Backend unreachable",
39
+ target: targetUrl.toString(),
40
+ },
30
41
  });
31
- return { proxied: true, proxiedResponse };
32
42
  }
33
- return { proxied: false };
34
43
  }
35
- async function forwardToBackend(forwardParams) {
36
- const targetUrl = new URL(forwardParams.targetPath + forwardParams.originalUrl.search, forwardParams.targetBase);
37
- return fetch(new Request(targetUrl, {
38
- method: forwardParams.originalRequest.method,
39
- headers: forwardParams.originalRequest.headers,
40
- body: forwardParams.originalRequest.body,
41
- redirect: "manual",
42
- }));
44
+ /**
45
+ * @param proxyConfig - Backend origins to proxy to; bound once at Worker startup
46
+ * @returns ProxyHandler that routes /api/*, /auth/*, and /_proxy/health requests
47
+ */
48
+ export function createProxyHandler(proxyConfig) {
49
+ const ventureBase = stripTrailingSlash(proxyConfig.ventureApiBase);
50
+ const adminBase = stripTrailingSlash(proxyConfig.adminApiBase);
51
+ return {
52
+ async handleRequest(workerRequest) {
53
+ const requestUrl = new URL(workerRequest.url);
54
+ const pathname = requestUrl.pathname;
55
+ if (pathname === "/_proxy/health") {
56
+ const [venture, admin] = await Promise.all([
57
+ probeHealth(ventureBase),
58
+ probeHealth(adminBase),
59
+ ]);
60
+ const healthStatus = { venture, admin };
61
+ const allOk = venture === "ok" && admin === "ok";
62
+ const proxiedResponse = new Response(JSON.stringify(healthStatus), {
63
+ status: allOk ? 200 : 503,
64
+ headers: { "content-type": "application/json" },
65
+ });
66
+ return { proxied: true, proxiedResponse };
67
+ }
68
+ if (pathname === "/api" || pathname.startsWith("/api/")) {
69
+ const proxiedResponse = await forwardToBackend({
70
+ originalRequest: workerRequest,
71
+ originalUrl: requestUrl,
72
+ targetBase: ventureBase,
73
+ targetPath: pathname,
74
+ });
75
+ return { proxied: true, proxiedResponse };
76
+ }
77
+ if (pathname === "/auth" || pathname.startsWith("/auth/")) {
78
+ const adminPath = "/api" + pathname;
79
+ const proxiedResponse = await forwardToBackend({
80
+ originalRequest: workerRequest,
81
+ originalUrl: requestUrl,
82
+ targetBase: adminBase,
83
+ targetPath: adminPath,
84
+ });
85
+ return { proxied: true, proxiedResponse };
86
+ }
87
+ return { proxied: false };
88
+ },
89
+ };
43
90
  }
44
91
  //# 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":"AAuBA;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,YAAgC;IAEhC,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAErD,IAAI,UAAU,CAAC,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5C,MAAM,eAAe,GAAG,MAAM,gBAAgB,CAAC;YAC7C,eAAe,EAAE,YAAY,CAAC,OAAO;YACrC,WAAW,EAAE,UAAU;YACvB,UAAU,EAAE,YAAY,CAAC,WAAW,CAAC,cAAc;YACnD,UAAU,EAAE,UAAU,CAAC,QAAQ;SAChC,CAAC,CAAC;QACH,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC;IAC5C,CAAC;IAED,IAAI,UAAU,CAAC,QAAQ,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7C,MAAM,SAAS,GAAG,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC;QAC/C,MAAM,eAAe,GAAG,MAAM,gBAAgB,CAAC;YAC7C,eAAe,EAAE,YAAY,CAAC,OAAO;YACrC,WAAW,EAAE,UAAU;YACvB,UAAU,EAAE,YAAY,CAAC,WAAW,CAAC,YAAY;YACjD,UAAU,EAAE,SAAS;SACtB,CAAC,CAAC;QACH,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC;IAC5C,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AAC5B,CAAC;AASD,KAAK,UAAU,gBAAgB,CAAC,aAA4B;IAC1D,MAAM,SAAS,GAAG,IAAI,GAAG,CACvB,aAAa,CAAC,UAAU,GAAG,aAAa,CAAC,WAAW,CAAC,MAAM,EAC3D,aAAa,CAAC,UAAU,CACzB,CAAC;IAEF,OAAO,KAAK,CACV,IAAI,OAAO,CAAC,SAAS,EAAE;QACrB,MAAM,EAAE,aAAa,CAAC,eAAe,CAAC,MAAM;QAC5C,OAAO,EAAE,aAAa,CAAC,eAAe,CAAC,OAAO;QAC9C,IAAI,EAAE,aAAa,CAAC,eAAe,CAAC,IAAI;QACxC,QAAQ,EAAE,QAAQ;KACnB,CAAC,CACH,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"same-origin-proxy.js","sourceRoot":"","sources":["../src/same-origin-proxy.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jakuta-inc/worker-proxy",
3
- "version": "0.1.3",
3
+ "version": "1.0.0",
4
4
  "description": "Same-origin reverse proxy for Jakuta admin panel Cloudflare Workers",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",