@lensmcp/cluster 1.18.4 → 1.18.7
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/basic-ssl.js +1 -241
- package/build-scope-patterns.js +1 -40
- package/create-webpack-dev.js +1 -186
- package/create-webpack-prod.js +1 -169
- package/executors/build/build.impl.js +1 -98
- package/executors/gateway/gateway-errors.js +1 -43
- package/executors/gateway/gateway.impl.js +1 -53
- package/executors/gateway/gateway.lib.js +1 -29
- package/executors/gateway/health-check.js +1 -66
- package/executors/gateway/jwks-verify.js +1 -121
- package/executors/gateway/main.prod-gateway.js +2 -573
- package/executors/gateway/main.rollout.js +11 -117
- package/executors/gateway/manifest.js +1 -374
- package/executors/gateway/metrics.js +1 -56
- package/executors/gateway/otel-tracing.js +1 -74
- package/executors/gateway/prod-gateway.lib.js +1 -22
- package/executors/gateway/prod-runtime/access-log.js +1 -24
- package/executors/gateway/prod-runtime/app.js +1 -123
- package/executors/gateway/prod-runtime/auth.js +1 -51
- package/executors/gateway/prod-runtime/cors.js +1 -40
- package/executors/gateway/prod-runtime/edge.js +1 -65
- package/executors/gateway/prod-runtime/handler.js +1 -226
- package/executors/gateway/prod-runtime/hooks.js +1 -42
- package/executors/gateway/prod-runtime/observability.js +1 -125
- package/executors/gateway/prod-runtime/rollout.js +1 -103
- package/executors/gateway/prod-runtime/routing.js +1 -40
- package/executors/gateway/prod-runtime/server.js +1 -79
- package/executors/gateway/prod-runtime/trust.js +1 -32
- package/executors/gateway/prod-runtime/types.js +1 -2
- package/executors/gateway/prod-runtime/upgrade.js +4 -116
- package/executors/gateway/prod-runtime/upstream.js +1 -21
- package/executors/gateway/providers-prod.js +1 -232
- package/executors/gateway/rate-limit.js +2 -75
- package/executors/gateway/registry-source.js +1 -131
- package/executors/gateway/rollout-ops.js +2 -167
- package/executors/gateway/runtime/auth.js +1 -64
- package/executors/gateway/runtime/chooser.js +12 -45
- package/executors/gateway/runtime/control.js +1 -128
- package/executors/gateway/runtime/dev-auth.js +1 -108
- package/executors/gateway/runtime/discovery.js +1 -123
- package/executors/gateway/runtime/edge.js +1 -47
- package/executors/gateway/runtime/handler.js +1 -183
- package/executors/gateway/runtime/hooks.js +1 -55
- package/executors/gateway/runtime/lens-children.js +1 -651
- package/executors/gateway/runtime/lifecycle.js +3 -842
- package/executors/gateway/runtime/observability.js +2 -148
- package/executors/gateway/runtime/pod-env.js +2 -89
- package/executors/gateway/runtime/proxy.js +1 -457
- package/executors/gateway/runtime/route-registry.js +1 -72
- package/executors/gateway/runtime/scope.js +1 -117
- package/executors/gateway/runtime/server.js +3 -487
- package/executors/gateway/runtime/service-keys.js +1 -49
- package/executors/gateway/runtime/types.js +1 -151
- package/executors/gateway/runtime/upgrade.js +1 -71
- package/executors/gateway/runtime/workspace-registry.js +1 -99
- package/executors/gateway/ssrf-guard.js +1 -190
- package/executors/serve/serve.impl.js +1 -280
- package/executors/trust/trust.impl.js +4 -162
- package/gateway.js +1 -35
- package/index.js +1 -16
- package/main.devserver.js +10 -1117
- package/package.json +4 -3
- package/tsgo-check-plugin.js +4 -364
- package/typecheck-bus.js +4 -256
|
@@ -1,183 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createHandler = createHandler;
|
|
4
|
-
const manifest_1 = require("../manifest");
|
|
5
|
-
const gateway_errors_1 = require("../gateway-errors");
|
|
6
|
-
const discovery_1 = require("./discovery");
|
|
7
|
-
const edge_1 = require("./edge");
|
|
8
|
-
const observability_1 = require("./observability");
|
|
9
|
-
const chooser_1 = require("./chooser");
|
|
10
|
-
function createHandler(deps) {
|
|
11
|
-
const { rt, obs, auth, proxy, hooks } = deps;
|
|
12
|
-
const match = (req) => (0, manifest_1.matchRoute)(rt.routes, (req.headers.host || '').split(':')[0], req.url ?? '/');
|
|
13
|
-
// Host-root infra: when a host only has PATH-mounted services (pure
|
|
14
|
-
// microservices under api.<domain>/{prefix}), the gateway itself owns the
|
|
15
|
-
// root — CORS, health aggregation + service discovery, like a real edge.
|
|
16
|
-
const handleNoRoute = (req, res) => {
|
|
17
|
-
// gateway-owned endpoints are cross-origin by design (the app calls
|
|
18
|
-
// api.<domain>/health from app.<domain>) — answer CORS here; routed
|
|
19
|
-
// paths inherit CORS from the services themselves.
|
|
20
|
-
(0, edge_1.cors)(req, res);
|
|
21
|
-
if (req.method === 'OPTIONS') {
|
|
22
|
-
res.writeHead(204, {
|
|
23
|
-
'access-control-allow-methods': edge_1.PREFLIGHT_METHODS_NOROUTE,
|
|
24
|
-
'access-control-allow-headers': String(req.headers['access-control-request-headers'] ?? '*'),
|
|
25
|
-
});
|
|
26
|
-
res.end();
|
|
27
|
-
return;
|
|
28
|
-
}
|
|
29
|
-
const host = (req.headers.host || '').split(':')[0];
|
|
30
|
-
const mounted = rt.routes.filter((r) => r.host && (0, manifest_1.hostMatches)(r.host, host) && r.prefix);
|
|
31
|
-
const url = (req.url ?? '/').split('?')[0];
|
|
32
|
-
// The lens dashboard HOST ROOT → the multi-workspace chooser. The dashboard itself mounts at `/<key>`,
|
|
33
|
-
// so the bare `/` is unrouted and lands here; serve the landing page listing every known workspace.
|
|
34
|
-
if ((url === '/' || url === '/index.html' || url === '') &&
|
|
35
|
-
rt.routes.some((r) => r.host && (0, manifest_1.hostMatches)(r.host, host) && r.project === observability_1.LENS_DASHBOARD_PROJECT)) {
|
|
36
|
-
(0, chooser_1.serveChooser)(res, rt.wsKey);
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
if (mounted.length > 0 && (url === '/health' || url === '/healthz')) {
|
|
40
|
-
const services = mounted.map((r) => ({
|
|
41
|
-
project: r.project,
|
|
42
|
-
prefix: r.prefix,
|
|
43
|
-
pods: r.pool ? ((0, discovery_1.pickSock)(r.pool, 0), r.pool.socks.length) : undefined,
|
|
44
|
-
state: r.svc?.state ?? (r.target ? 'up' : 'unknown'),
|
|
45
|
-
}));
|
|
46
|
-
const ok = services.every((s) => s.state !== 'down' || true);
|
|
47
|
-
res.writeHead(ok ? 200 : 503, { 'content-type': 'application/json' });
|
|
48
|
-
res.end(JSON.stringify({ status: 'ok', host, services }, null, 2));
|
|
49
|
-
return;
|
|
50
|
-
}
|
|
51
|
-
if (mounted.length > 0 && url === '/.well-known/services') {
|
|
52
|
-
res.writeHead(200, { 'content-type': 'application/json' });
|
|
53
|
-
res.end(JSON.stringify({ host, services: mounted.map((r) => ({ prefix: r.prefix, project: r.project, internal: !!r.internal })) }, null, 2));
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
56
|
-
(0, edge_1.sendError)(res, req, 404, 'not_found', mounted.length > 0
|
|
57
|
-
? `No service mounted at ${url}. Mounted on ${host}: ${[...new Set(mounted.map((r) => r.prefix))].join(', ')} (+ /health, /.well-known/services)`
|
|
58
|
-
: 'No gateway route for this hostname.');
|
|
59
|
-
};
|
|
60
|
-
const runPipeline = async (req, res) => {
|
|
61
|
-
// 0. HTTP/2 carries the host in the `:authority` pseudo-header, NOT `host` — the
|
|
62
|
-
// http2 compat layer exposes it as `req.authority` and omits `host` from `req.headers`.
|
|
63
|
-
// Every downstream step (route match, trace, CORS) reads `req.headers.host`, so
|
|
64
|
-
// normalize it here before anything else. No-op for HTTP/1.1 (host is already set).
|
|
65
|
-
if (!req.headers.host) {
|
|
66
|
-
const authority = req.authority ?? req.headers[':authority'];
|
|
67
|
-
if (authority)
|
|
68
|
-
req.headers.host = authority;
|
|
69
|
-
}
|
|
70
|
-
// 1. STRIP client-supplied trust headers before anything else: the gateway is
|
|
71
|
-
// the ONLY party allowed to assert `x-internal-token` (came through me) and
|
|
72
|
-
// `x-api-key-id` (validated caller identity). Without this, a keyless/TCP route
|
|
73
|
-
// would leak a spoofed token and any public route would forward a spoofed caller
|
|
74
|
-
// id to downstream audit. The gateway re-stamps them below where earned.
|
|
75
|
-
for (const h of edge_1.GATEWAY_OWNED_HEADERS)
|
|
76
|
-
delete req.headers[h];
|
|
77
|
-
// 2. Mint a trace id for EVERY request (not just lens-traced ones): forwarded to the
|
|
78
|
-
// pod (adopted as its traceId) and returned on the response — any request is traceable.
|
|
79
|
-
(0, gateway_errors_1.ensureRequestId)(req);
|
|
80
|
-
const trace = obs.beginTrace(req);
|
|
81
|
-
if (trace) {
|
|
82
|
-
obs.traceStep(trace, 'received', { host: trace.host, method: trace.method, url: trace.url });
|
|
83
|
-
req.__lensmcpTrace = trace;
|
|
84
|
-
}
|
|
85
|
-
const ctx = hooks.httpContext(req, res, trace);
|
|
86
|
-
try {
|
|
87
|
-
// 3. onRequest (sees already-stripped headers; may short-circuit)
|
|
88
|
-
if (hooks.has('onRequest')) {
|
|
89
|
-
await hooks.run('onRequest', ctx);
|
|
90
|
-
if (ctx.responded())
|
|
91
|
-
return;
|
|
92
|
-
}
|
|
93
|
-
// 4. route match
|
|
94
|
-
const route = match(req);
|
|
95
|
-
if (!route) {
|
|
96
|
-
handleNoRoute(req, res);
|
|
97
|
-
return;
|
|
98
|
-
}
|
|
99
|
-
ctx.route = route;
|
|
100
|
-
obs.traceStep(trace, 'route-match', {
|
|
101
|
-
project: route.project,
|
|
102
|
-
...(route.prefix ? { prefix: route.prefix } : {}),
|
|
103
|
-
...(route.host ? { routeHost: route.host } : {}),
|
|
104
|
-
...(route.internal ? { internal: true } : {}),
|
|
105
|
-
});
|
|
106
|
-
// 7. CORS preflight on a ROUTED path: answer it HERE, BEFORE edge auth — an OPTIONS preflight
|
|
107
|
-
// carries no token by spec, so the JWT (or x-api-key) enforcement below would 401 it and the
|
|
108
|
-
// browser's CORS check fails. The matching real request still goes through auth normally.
|
|
109
|
-
if (req.method === 'OPTIONS') {
|
|
110
|
-
(0, edge_1.cors)(req, res);
|
|
111
|
-
res.writeHead(204, {
|
|
112
|
-
'access-control-allow-methods': edge_1.PREFLIGHT_METHODS_ROUTED,
|
|
113
|
-
'access-control-allow-headers': String(req.headers['access-control-request-headers'] ?? '*'),
|
|
114
|
-
});
|
|
115
|
-
res.end();
|
|
116
|
-
return;
|
|
117
|
-
}
|
|
118
|
-
// 8. CORS on EVERY routed response — including the 401/403/5xx the gateway generates ITSELF
|
|
119
|
-
// below. Without this a gateway-generated error short-circuits before the upstream (which
|
|
120
|
-
// carries CORS on success), so the browser sees the error WITHOUT an Access-Control-Allow-Origin
|
|
121
|
-
// and reports a CORS failure that MASKS the real status. On success the upstream's CORS header
|
|
122
|
-
// overwrites this one (http-proxy setHeader), so there's no duplicate.
|
|
123
|
-
(0, edge_1.cors)(req, res);
|
|
124
|
-
// 9. beforeAuth
|
|
125
|
-
if (hooks.has('beforeAuth')) {
|
|
126
|
-
await hooks.run('beforeAuth', ctx);
|
|
127
|
-
if (ctx.responded())
|
|
128
|
-
return;
|
|
129
|
-
}
|
|
130
|
-
// 10/11. auth + authz. internal.* validates the caller's api-key; public verifies the end-user
|
|
131
|
-
// JWT + enforces per-route rules. Custom middleware (afterAuth) runs AFTER core auth, public ONLY.
|
|
132
|
-
if (route.internal) {
|
|
133
|
-
const v = auth.internal(req, route, trace);
|
|
134
|
-
if (!v.ok) {
|
|
135
|
-
obs.finishTrace(trace, route.project, v.status);
|
|
136
|
-
(0, edge_1.sendError)(res, req, v.status, v.reason, v.detail);
|
|
137
|
-
return;
|
|
138
|
-
}
|
|
139
|
-
ctx.caller = v.caller;
|
|
140
|
-
}
|
|
141
|
-
else {
|
|
142
|
-
const v = auth.public(req, route, trace);
|
|
143
|
-
if (!v.ok) {
|
|
144
|
-
obs.finishTrace(trace, route.project, v.status);
|
|
145
|
-
(0, edge_1.sendError)(res, req, v.status, v.reason, v.detail);
|
|
146
|
-
return;
|
|
147
|
-
}
|
|
148
|
-
ctx.claims = v.claims;
|
|
149
|
-
if (hooks.has('afterAuth')) {
|
|
150
|
-
await hooks.run('afterAuth', ctx);
|
|
151
|
-
if (ctx.responded())
|
|
152
|
-
return;
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
// 12. inject the target service's key so pods trust the gateway (pool routes, both branches)
|
|
156
|
-
if (route.pool && rt.serviceKeys[route.project]) {
|
|
157
|
-
req.headers['x-internal-token'] = rt.serviceKeys[route.project];
|
|
158
|
-
}
|
|
159
|
-
// 13. beforeForward (last chance to mutate headers/url)
|
|
160
|
-
if (hooks.has('beforeForward')) {
|
|
161
|
-
await hooks.run('beforeForward', ctx);
|
|
162
|
-
if (ctx.responded())
|
|
163
|
-
return;
|
|
164
|
-
}
|
|
165
|
-
// 15. onResponse — fire user handlers once the response closes (the built-in
|
|
166
|
-
// recordEdge/finishTrace live in proxy.forward's own close handler).
|
|
167
|
-
if (hooks.has('onResponse')) {
|
|
168
|
-
res.on('close', () => { ctx.status = res.statusCode ?? 0; void hooks.run('onResponse', ctx); });
|
|
169
|
-
}
|
|
170
|
-
// 14. forward
|
|
171
|
-
void proxy.forward(route, req, res);
|
|
172
|
-
}
|
|
173
|
-
catch (e) {
|
|
174
|
-
// A hook (or the pipeline) threw — narrate via onError, then 500 if nobody responded.
|
|
175
|
-
ctx.error = e;
|
|
176
|
-
if (hooks.has('onError'))
|
|
177
|
-
await hooks.run('onError', ctx);
|
|
178
|
-
if (!ctx.responded())
|
|
179
|
-
(0, edge_1.sendError)(res, req, 500, 'internal', e.message);
|
|
180
|
-
}
|
|
181
|
-
};
|
|
182
|
-
return (req, res) => { void runPipeline(req, res); };
|
|
183
|
-
}
|
|
1
|
+
"use strict";var E=Object.defineProperty;var d=(l,i)=>E(l,"name",{value:i,configurable:!0});var v=Object.defineProperty,h=d((l,i)=>v(l,"name",{value:i,configurable:!0}),"h");Object.defineProperty(exports,"__esModule",{value:!0}),exports.createHandler=createHandler;const manifest_1=require("../manifest"),gateway_errors_1=require("../gateway-errors"),discovery_1=require("./discovery"),edge_1=require("./edge"),observability_1=require("./observability"),chooser_1=require("./chooser");function createHandler(l){const{rt:i,obs:u,auth:p,proxy:f,hooks:a}=l,w=h(e=>(0,manifest_1.matchRoute)(i.routes,(e.headers.host||"").split(":")[0],e.url??"/"),"match"),m=h((e,o)=>{if((0,edge_1.cors)(e,o),e.method==="OPTIONS"){o.writeHead(204,{"access-control-allow-methods":edge_1.PREFLIGHT_METHODS_NOROUTE,"access-control-allow-headers":String(e.headers["access-control-request-headers"]??"*")}),o.end();return}const n=(e.headers.host||"").split(":")[0],s=i.routes.filter(r=>r.host&&(0,manifest_1.hostMatches)(r.host,n)&&r.prefix),t=(e.url??"/").split("?")[0];if((t==="/"||t==="/index.html"||t==="")&&i.routes.some(r=>r.host&&(0,manifest_1.hostMatches)(r.host,n)&&r.project===observability_1.LENS_DASHBOARD_PROJECT)){(0,chooser_1.serveChooser)(o,i.wsKey);return}if(s.length>0&&(t==="/health"||t==="/healthz")){const r=s.map(c=>({project:c.project,prefix:c.prefix,pods:c.pool?((0,discovery_1.pickSock)(c.pool,0),c.pool.socks.length):void 0,state:c.svc?.state??(c.target?"up":"unknown")})),_=r.every(c=>c.state!=="down"||!0);o.writeHead(_?200:503,{"content-type":"application/json"}),o.end(JSON.stringify({status:"ok",host:n,services:r},null,2));return}if(s.length>0&&t==="/.well-known/services"){o.writeHead(200,{"content-type":"application/json"}),o.end(JSON.stringify({host:n,services:s.map(r=>({prefix:r.prefix,project:r.project,internal:!!r.internal}))},null,2));return}(0,edge_1.sendError)(o,e,404,"not_found",s.length>0?`No service mounted at ${t}. Mounted on ${n}: ${[...new Set(s.map(r=>r.prefix))].join(", ")} (+ /health, /.well-known/services)`:"No gateway route for this hostname.")},"handleNoRoute"),y=h(async(e,o)=>{if(!e.headers.host){const t=e.authority??e.headers[":authority"];t&&(e.headers.host=t)}for(const t of edge_1.GATEWAY_OWNED_HEADERS)delete e.headers[t];(0,gateway_errors_1.ensureRequestId)(e);const n=u.beginTrace(e);n&&(u.traceStep(n,"received",{host:n.host,method:n.method,url:n.url}),e.__lensmcpTrace=n);const s=a.httpContext(e,o,n);try{if(a.has("onRequest")&&(await a.run("onRequest",s),s.responded()))return;const t=w(e);if(!t){m(e,o);return}if(s.route=t,u.traceStep(n,"route-match",{project:t.project,...t.prefix?{prefix:t.prefix}:{},...t.host?{routeHost:t.host}:{},...t.internal?{internal:!0}:{}}),e.method==="OPTIONS"){(0,edge_1.cors)(e,o),o.writeHead(204,{"access-control-allow-methods":edge_1.PREFLIGHT_METHODS_ROUTED,"access-control-allow-headers":String(e.headers["access-control-request-headers"]??"*")}),o.end();return}if((0,edge_1.cors)(e,o),a.has("beforeAuth")&&(await a.run("beforeAuth",s),s.responded()))return;if(t.internal){const r=p.internal(e,t,n);if(!r.ok){u.finishTrace(n,t.project,r.status),(0,edge_1.sendError)(o,e,r.status,r.reason,r.detail);return}s.caller=r.caller}else{const r=p.public(e,t,n);if(!r.ok){u.finishTrace(n,t.project,r.status),(0,edge_1.sendError)(o,e,r.status,r.reason,r.detail);return}if(s.claims=r.claims,a.has("afterAuth")&&(await a.run("afterAuth",s),s.responded()))return}if(t.pool&&i.serviceKeys[t.project]&&(e.headers["x-internal-token"]=i.serviceKeys[t.project]),a.has("beforeForward")&&(await a.run("beforeForward",s),s.responded()))return;a.has("onResponse")&&o.on("close",()=>{s.status=o.statusCode??0,a.run("onResponse",s)}),f.forward(t,e,o)}catch(t){s.error=t,a.has("onError")&&await a.run("onError",s),s.responded()||(0,edge_1.sendError)(o,e,500,"internal",t.message)}},"runPipeline");return(e,o)=>{y(e,o)}}d(createHandler,"createHandler"),h(createHandler,"createHandler");
|
|
@@ -1,55 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createHooks = createHooks;
|
|
4
|
-
const edge_1 = require("./edge");
|
|
5
|
-
// Terminal phases observe a request whose response is ALREADY complete, so
|
|
6
|
-
// `responded()` is true by definition — they must run every handler regardless.
|
|
7
|
-
// The request-flow phases short-circuit the moment a handler responds.
|
|
8
|
-
const TERMINAL_PHASES = new Set(['onResponse', 'onError']);
|
|
9
|
-
function createHooks(hooks) {
|
|
10
|
-
const run = async (phase, ctx) => {
|
|
11
|
-
const list = hooks[phase];
|
|
12
|
-
if (!list || list.length === 0)
|
|
13
|
-
return;
|
|
14
|
-
const terminal = TERMINAL_PHASES.has(phase);
|
|
15
|
-
for (const h of list) {
|
|
16
|
-
if (!terminal && ctx.responded())
|
|
17
|
-
return; // a request-flow hook already responded → stop
|
|
18
|
-
await h(ctx);
|
|
19
|
-
}
|
|
20
|
-
};
|
|
21
|
-
const has = (phase) => (hooks[phase]?.length ?? 0) > 0;
|
|
22
|
-
const httpContext = (req, res, trace) => ({
|
|
23
|
-
req,
|
|
24
|
-
res,
|
|
25
|
-
socket: undefined,
|
|
26
|
-
trace,
|
|
27
|
-
route: undefined,
|
|
28
|
-
claims: undefined,
|
|
29
|
-
caller: undefined,
|
|
30
|
-
pod: undefined,
|
|
31
|
-
error: undefined,
|
|
32
|
-
status: undefined,
|
|
33
|
-
sendError: (status, reason, detail) => (0, edge_1.sendError)(res, req, status, reason, detail),
|
|
34
|
-
responded: () => res.writableEnded || res.headersSent,
|
|
35
|
-
});
|
|
36
|
-
const upgradeContext = (req, socket, trace) => ({
|
|
37
|
-
req,
|
|
38
|
-
res: undefined,
|
|
39
|
-
socket,
|
|
40
|
-
trace,
|
|
41
|
-
route: undefined,
|
|
42
|
-
claims: undefined,
|
|
43
|
-
caller: undefined,
|
|
44
|
-
pod: undefined,
|
|
45
|
-
error: undefined,
|
|
46
|
-
status: undefined,
|
|
47
|
-
// No HTTP response on an upgrade — short-circuiting means destroying the socket.
|
|
48
|
-
sendError: () => { try {
|
|
49
|
-
socket.destroy();
|
|
50
|
-
}
|
|
51
|
-
catch { /* already gone */ } },
|
|
52
|
-
responded: () => socket.destroyed,
|
|
53
|
-
});
|
|
54
|
-
return { run, has, httpContext, upgradeContext };
|
|
55
|
-
}
|
|
1
|
+
"use strict";var u=Object.defineProperty;var i=(t,e)=>u(t,"name",{value:e,configurable:!0});var a=Object.defineProperty,n=i((t,e)=>a(t,"name",{value:e,configurable:!0}),"n");Object.defineProperty(exports,"__esModule",{value:!0}),exports.createHooks=createHooks;const edge_1=require("./edge"),TERMINAL_PHASES=new Set(["onResponse","onError"]);function createHooks(t){return{run:n(async(e,r)=>{const o=t[e];if(!o||o.length===0)return;const d=TERMINAL_PHASES.has(e);for(const s of o){if(!d&&r.responded())return;await s(r)}},"run"),has:n(e=>(t[e]?.length??0)>0,"has"),httpContext:n((e,r,o)=>({req:e,res:r,socket:void 0,trace:o,route:void 0,claims:void 0,caller:void 0,pod:void 0,error:void 0,status:void 0,sendError:n((d,s,c)=>(0,edge_1.sendError)(r,e,d,s,c),"sendError"),responded:n(()=>r.writableEnded||r.headersSent,"responded")}),"httpContext"),upgradeContext:n((e,r,o)=>({req:e,res:void 0,socket:r,trace:o,route:void 0,claims:void 0,caller:void 0,pod:void 0,error:void 0,status:void 0,sendError:n(()=>{try{r.destroy()}catch{}},"sendError"),responded:n(()=>r.destroyed,"responded")}),"upgradeContext")}}i(createHooks,"createHooks"),n(createHooks,"createHooks");
|