@grest-ts/http 0.0.46 → 0.0.48
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 +125 -0
- package/dist/src/_dedupCheck.js +1 -1
- package/dist/src/client/GGHttpSchema.createClient.d.ts +8 -0
- package/dist/src/client/GGHttpSchema.createClient.d.ts.map +1 -1
- package/dist/src/client/GGHttpSchema.createClient.js +2 -1
- package/dist/src/client/GGHttpSchema.createClient.js.map +1 -1
- package/dist/src/index-browser.d.ts +2 -0
- package/dist/src/index-browser.d.ts.map +1 -1
- package/dist/src/index-browser.js +2 -0
- package/dist/src/index-browser.js.map +1 -1
- package/dist/src/index-node.d.ts +3 -0
- package/dist/src/index-node.d.ts.map +1 -1
- package/dist/src/index-node.js +3 -0
- package/dist/src/index-node.js.map +1 -1
- package/dist/src/rpc/GGHttpRouteRPC.d.ts +4 -0
- package/dist/src/rpc/GGHttpRouteRPC.d.ts.map +1 -1
- package/dist/src/rpc/GGHttpRouteRPC.js +6 -0
- package/dist/src/rpc/GGHttpRouteRPC.js.map +1 -1
- package/dist/src/rpc/RpcResponse/GGRpcResponseBuilder.d.ts +1 -0
- package/dist/src/rpc/RpcResponse/GGRpcResponseBuilder.d.ts.map +1 -1
- package/dist/src/rpc/RpcResponse/GGRpcResponseBuilder.js +4 -0
- package/dist/src/rpc/RpcResponse/GGRpcResponseBuilder.js.map +1 -1
- package/dist/src/schema/GGHttpSchema.d.ts +13 -0
- package/dist/src/schema/GGHttpSchema.d.ts.map +1 -1
- package/dist/src/schema/GGHttpSchema.js.map +1 -1
- package/dist/src/schema/cookieMiddleware.d.ts +71 -0
- package/dist/src/schema/cookieMiddleware.d.ts.map +1 -0
- package/dist/src/schema/cookieMiddleware.js +126 -0
- package/dist/src/schema/cookieMiddleware.js.map +1 -0
- package/dist/src/schema/headerBinding.d.ts +35 -0
- package/dist/src/schema/headerBinding.d.ts.map +1 -0
- package/dist/src/schema/headerBinding.js +49 -0
- package/dist/src/schema/headerBinding.js.map +1 -0
- package/dist/src/schema/httpSchema.d.ts +0 -2
- package/dist/src/schema/httpSchema.d.ts.map +1 -1
- package/dist/src/schema/httpSchema.js +0 -48
- package/dist/src/schema/httpSchema.js.map +1 -1
- package/dist/src/server/GGHttpSchema.startServer.d.ts.map +1 -1
- package/dist/src/server/GGHttpSchema.startServer.js +4 -1
- package/dist/src/server/GGHttpSchema.startServer.js.map +1 -1
- package/dist/src/server/GGHttpServer.d.ts +29 -0
- package/dist/src/server/GGHttpServer.d.ts.map +1 -1
- package/dist/src/server/GGHttpServer.js +35 -8
- package/dist/src/server/GGHttpServer.js.map +1 -1
- package/dist/src/server/applyResponseMiddleware.d.ts +12 -0
- package/dist/src/server/applyResponseMiddleware.d.ts.map +1 -0
- package/dist/src/server/applyResponseMiddleware.js +25 -0
- package/dist/src/server/applyResponseMiddleware.js.map +1 -0
- package/dist/tsconfig.publish.tsbuildinfo +1 -1
- package/package.json +10 -10
- package/src/_dedupCheck.ts +1 -1
- package/src/client/GGHttpSchema.createClient.ts +10 -1
- package/src/index-browser.ts +2 -0
- package/src/index-node.ts +3 -0
- package/src/rpc/GGHttpRouteRPC.ts +8 -0
- package/src/rpc/RpcResponse/GGRpcResponseBuilder.ts +5 -1
- package/src/schema/GGHttpSchema.ts +15 -0
- package/src/schema/cookieMiddleware.ts +164 -0
- package/src/schema/headerBinding.ts +65 -0
- package/src/schema/httpSchema.ts +2 -55
- package/src/server/GGHttpSchema.startServer.ts +4 -1
- package/src/server/GGHttpServer.ts +57 -8
- package/src/server/applyResponseMiddleware.ts +27 -0
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { GGContextKey } from "@grest-ts/context";
|
|
2
|
+
import { IsAny, IsString, SERVER_ERROR } from "@grest-ts/schema";
|
|
3
|
+
/**
|
|
4
|
+
* Per-request set of context-key names the current route is permitted to write a cookie
|
|
5
|
+
* for (declared via GGRpc.*(...).updatesCookie(key)). Populated by the server route
|
|
6
|
+
* handler; read by setCookie() to reject undeclared cookie writes.
|
|
7
|
+
*/
|
|
8
|
+
export const GG_COOKIE_WRITES = new GGContextKey("cookie:writes", IsAny);
|
|
9
|
+
const SAFE_DEFAULTS = { httpOnly: true, secure: true, sameSite: "lax", path: "/" };
|
|
10
|
+
/**
|
|
11
|
+
* Per-request Set-Cookie writes scheduled via setCookie()/clearCookie(), keyed by the
|
|
12
|
+
* context key's name. Flushed onto the response by the matching cookie() binding.
|
|
13
|
+
*/
|
|
14
|
+
const GG_COOKIE_PENDING = new GGContextKey("cookie:pending", IsAny);
|
|
15
|
+
// Reject anything that could break out of the Set-Cookie line / inject attributes.
|
|
16
|
+
function assertCookieSafe(label, value) {
|
|
17
|
+
if (/[\x00-\x1f;]/.test(value)) {
|
|
18
|
+
throw new Error(`Cookie ${label} contains illegal characters (control chars or ';'): ${JSON.stringify(value)}`);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Read a single named cookie out of a raw `Cookie` header value. Shared by the HTTP
|
|
23
|
+
* binding (parseRequest) and the WebSocket binding (parseHandshake). A malformed
|
|
24
|
+
* percent-encoding (e.g. "sid=%") must not crash — fall back to the raw value.
|
|
25
|
+
*/
|
|
26
|
+
export function readCookie(rawCookieHeader, name) {
|
|
27
|
+
if (typeof rawCookieHeader !== "string")
|
|
28
|
+
return undefined;
|
|
29
|
+
for (const part of rawCookieHeader.split(";")) {
|
|
30
|
+
const eq = part.indexOf("=");
|
|
31
|
+
if (eq === -1)
|
|
32
|
+
continue;
|
|
33
|
+
if (part.slice(0, eq).trim() === name) {
|
|
34
|
+
const rawValue = part.slice(eq + 1).trim();
|
|
35
|
+
try {
|
|
36
|
+
return decodeURIComponent(rawValue);
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return rawValue;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
function serializeSetCookie(name, value, options) {
|
|
46
|
+
const o = { ...SAFE_DEFAULTS, ...options };
|
|
47
|
+
const secure = o.sameSite === "none" ? true : o.secure;
|
|
48
|
+
const sameSite = `${o.sameSite.charAt(0).toUpperCase()}${o.sameSite.slice(1)}`;
|
|
49
|
+
const attrs = `; Path=${o.path}${o.domain ? `; Domain=${o.domain}` : ""}; SameSite=${sameSite}${secure ? "; Secure" : ""}${o.httpOnly ? "; HttpOnly" : ""}`;
|
|
50
|
+
return value
|
|
51
|
+
? `${name}=${encodeURIComponent(value)}${o.maxAgeSec !== undefined ? `; Max-Age=${Math.trunc(o.maxAgeSec)}` : ""}${attrs}`
|
|
52
|
+
: `${name}=; Max-Age=0${attrs}`;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Bind a context key to a cookie, read-only on the wire. Reads ONLY the named cookie —
|
|
56
|
+
* never a header — from the incoming HTTP Cookie (parseRequest) or the real WS upgrade
|
|
57
|
+
* Cookie (parseHandshake), into key.get(). The cookie's wire name defaults to the key's
|
|
58
|
+
* name. To write the cookie, call setCookie(key, …) from a route that declared
|
|
59
|
+
* .updatesCookie(key); the matching binding flushes it as Set-Cookie (HTTP only — a
|
|
60
|
+
* WebSocket has no response to set a cookie on).
|
|
61
|
+
*/
|
|
62
|
+
export function cookie(key, opts) {
|
|
63
|
+
const cookieName = opts?.name ?? key.name;
|
|
64
|
+
assertCookieSafe("name", cookieName);
|
|
65
|
+
return {
|
|
66
|
+
headers: {},
|
|
67
|
+
responseHeaders: {},
|
|
68
|
+
cookieParams: { [cookieName]: opts?.schema ?? IsString.orUndefined },
|
|
69
|
+
parseRequest(req) {
|
|
70
|
+
const raw = req.headers?.["cookie"];
|
|
71
|
+
const value = readCookie(typeof raw === "string" ? raw : undefined, cookieName);
|
|
72
|
+
if (value !== undefined)
|
|
73
|
+
key.set(value);
|
|
74
|
+
},
|
|
75
|
+
updateResponse(res) {
|
|
76
|
+
const pending = GG_COOKIE_PENDING.get()?.get(key.name);
|
|
77
|
+
if (pending === undefined)
|
|
78
|
+
return;
|
|
79
|
+
const line = serializeSetCookie(cookieName, pending.value, pending.options);
|
|
80
|
+
const existing = res.headers["set-cookie"];
|
|
81
|
+
const arr = existing === undefined ? [] : Array.isArray(existing) ? existing : [existing];
|
|
82
|
+
arr.push(line);
|
|
83
|
+
res.headers["set-cookie"] = arr;
|
|
84
|
+
},
|
|
85
|
+
parseHandshake(ctx) {
|
|
86
|
+
const value = readCookie(ctx.upgradeHeaders?.["cookie"], cookieName);
|
|
87
|
+
if (value !== undefined)
|
|
88
|
+
key.set(value);
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Schedule a Set-Cookie on the response (HTTP only). The value never touches key.get() —
|
|
94
|
+
* inbound reads stay set-once. The route must declare .updatesCookie(key); an undeclared
|
|
95
|
+
* call is invalid usage and throws SERVER_ERROR. The matching cookie() binding serializes
|
|
96
|
+
* the pending write with these options (HttpOnly/Secure/SameSite/Path/Domain/Max-Age).
|
|
97
|
+
*/
|
|
98
|
+
export function setCookie(key, value, options) {
|
|
99
|
+
if (options) {
|
|
100
|
+
if (options.maxAgeSec !== undefined && !Number.isFinite(options.maxAgeSec)) {
|
|
101
|
+
throw new Error(`setCookie("${key.name}"): maxAgeSec must be a finite number, got ${options.maxAgeSec}.`);
|
|
102
|
+
}
|
|
103
|
+
if (options.path !== undefined)
|
|
104
|
+
assertCookieSafe("path", options.path);
|
|
105
|
+
if (options.domain !== undefined)
|
|
106
|
+
assertCookieSafe("domain", options.domain);
|
|
107
|
+
}
|
|
108
|
+
if (!GG_COOKIE_WRITES.get()?.has(key.name)) {
|
|
109
|
+
throw new SERVER_ERROR({ debugMessage: `setCookie("${key.name}") was called, but this route did not declare .updatesCookie(<key>). Only routes that declare it may set or clear the cookie.` });
|
|
110
|
+
}
|
|
111
|
+
let pending = GG_COOKIE_PENDING.get();
|
|
112
|
+
if (pending === undefined) {
|
|
113
|
+
pending = new Map();
|
|
114
|
+
GG_COOKIE_PENDING.set(pending);
|
|
115
|
+
}
|
|
116
|
+
pending.set(key.name, { value, options });
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Clear the cookie — schedules a Set-Cookie with Max-Age=0. Pass path/domain to match a
|
|
120
|
+
* scoped cookie (deletion only works when path+domain match what was set). Equivalent to
|
|
121
|
+
* setCookie(key, undefined, options), but reads clearer at logout-style call sites.
|
|
122
|
+
*/
|
|
123
|
+
export function clearCookie(key, options) {
|
|
124
|
+
setCookie(key, undefined, options);
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=cookieMiddleware.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cookieMiddleware.js","sourceRoot":"","sources":["../../../src/schema/cookieMiddleware.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { GGContextKey } from "@grest-ts/context";
|
|
2
|
+
import { type GGSchema } from "@grest-ts/schema";
|
|
3
|
+
import type { GGHttpTransportMiddleware } from "./GGHttpSchema";
|
|
4
|
+
/**
|
|
5
|
+
* Local structural copy of GGWebSocketHandshakeContext (defined in @grest-ts/websocket).
|
|
6
|
+
* http must not import websocket; header()'s WS half is typed against this shape and
|
|
7
|
+
* matches GGWebSocketMiddleware structurally at the webSocketSchema.use() call site.
|
|
8
|
+
* `headers` is the in-band handshake bag (client-set, spoofable — same trust level as an
|
|
9
|
+
* HTTP request header).
|
|
10
|
+
*/
|
|
11
|
+
interface WsHandshakeContextLike {
|
|
12
|
+
headers: Record<string, string>;
|
|
13
|
+
upgradeHeaders?: Record<string, string>;
|
|
14
|
+
queryArgs: Record<string, string>;
|
|
15
|
+
}
|
|
16
|
+
export interface GGHeaderBinding extends GGHttpTransportMiddleware {
|
|
17
|
+
parseHandshake(ctx: WsHandshakeContextLike): void;
|
|
18
|
+
updateHandshake(ctx: WsHandshakeContextLike): void;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Bind a context key to a single named header, on both transports. Reads ONLY that header
|
|
22
|
+
* — never a cookie — from the HTTP request (parseRequest) or the in-band WS handshake
|
|
23
|
+
* (parseHandshake) into key.get(), and writes it from key.get() on the client (HTTP
|
|
24
|
+
* updateRequest / WS updateHandshake). `scheme: "bearer"` strips/adds the `Bearer ` prefix;
|
|
25
|
+
* default is verbatim. The wire name defaults to the key's name (lowercased — HTTP headers
|
|
26
|
+
* are case-insensitive). Client-attachable, so it is the service-to-service variant (a
|
|
27
|
+
* Node client can carry it; a browser cookie cannot).
|
|
28
|
+
*/
|
|
29
|
+
export declare function header(key: GGContextKey<string | undefined>, opts?: {
|
|
30
|
+
name?: string;
|
|
31
|
+
scheme?: "bearer";
|
|
32
|
+
schema?: GGSchema<string | undefined>;
|
|
33
|
+
}): GGHeaderBinding;
|
|
34
|
+
export {};
|
|
35
|
+
//# sourceMappingURL=headerBinding.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"headerBinding.d.ts","sourceRoot":"","sources":["../../../src/schema/headerBinding.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAC,MAAM,mBAAmB,CAAA;AAC9C,OAAO,EAAW,KAAK,QAAQ,EAAC,MAAM,kBAAkB,CAAA;AACxD,OAAO,KAAK,EAAgB,yBAAyB,EAAC,MAAM,gBAAgB,CAAA;AAE5E;;;;;;GAMG;AACH,UAAU,sBAAsB;IAC5B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/B,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACvC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACpC;AAED,MAAM,WAAW,eAAgB,SAAQ,yBAAyB;IAC9D,cAAc,CAAC,GAAG,EAAE,sBAAsB,GAAG,IAAI,CAAA;IACjD,eAAe,CAAC,GAAG,EAAE,sBAAsB,GAAG,IAAI,CAAA;CACrD;AAID;;;;;;;;GAQG;AACH,wBAAgB,MAAM,CAAC,GAAG,EAAE,YAAY,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,IAAI,CAAC,EAAE;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,QAAQ,CAAC;IAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;CAAC,GAAG,eAAe,CA+B/J"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { IsString } from "@grest-ts/schema";
|
|
2
|
+
const BEARER = "Bearer ";
|
|
3
|
+
/**
|
|
4
|
+
* Bind a context key to a single named header, on both transports. Reads ONLY that header
|
|
5
|
+
* — never a cookie — from the HTTP request (parseRequest) or the in-band WS handshake
|
|
6
|
+
* (parseHandshake) into key.get(), and writes it from key.get() on the client (HTTP
|
|
7
|
+
* updateRequest / WS updateHandshake). `scheme: "bearer"` strips/adds the `Bearer ` prefix;
|
|
8
|
+
* default is verbatim. The wire name defaults to the key's name (lowercased — HTTP headers
|
|
9
|
+
* are case-insensitive). Client-attachable, so it is the service-to-service variant (a
|
|
10
|
+
* Node client can carry it; a browser cookie cannot).
|
|
11
|
+
*/
|
|
12
|
+
export function header(key, opts) {
|
|
13
|
+
const name = (opts?.name ?? key.name).toLowerCase();
|
|
14
|
+
const bearer = opts?.scheme === "bearer";
|
|
15
|
+
const unwrap = (raw) => {
|
|
16
|
+
if (raw === undefined)
|
|
17
|
+
return undefined;
|
|
18
|
+
return bearer && raw.startsWith(BEARER) ? raw.slice(BEARER.length) : raw;
|
|
19
|
+
};
|
|
20
|
+
const wrap = (value) => bearer ? `${BEARER}${value}` : value;
|
|
21
|
+
return {
|
|
22
|
+
headers: { [name]: opts?.schema ?? IsString.orUndefined },
|
|
23
|
+
responseHeaders: {},
|
|
24
|
+
parseRequest(req) {
|
|
25
|
+
const raw = req.headers?.[name];
|
|
26
|
+
const value = unwrap(typeof raw === "string" ? raw : Array.isArray(raw) ? raw[0] : undefined);
|
|
27
|
+
if (value !== undefined)
|
|
28
|
+
key.set(value);
|
|
29
|
+
},
|
|
30
|
+
updateRequest(req) {
|
|
31
|
+
const value = key.get();
|
|
32
|
+
if (value === undefined)
|
|
33
|
+
return;
|
|
34
|
+
req.headers = req.headers ?? {};
|
|
35
|
+
req.headers[name] = wrap(value);
|
|
36
|
+
},
|
|
37
|
+
parseHandshake(ctx) {
|
|
38
|
+
const value = unwrap(ctx.headers?.[name]);
|
|
39
|
+
if (value !== undefined)
|
|
40
|
+
key.set(value);
|
|
41
|
+
},
|
|
42
|
+
updateHandshake(ctx) {
|
|
43
|
+
const value = key.get();
|
|
44
|
+
if (value !== undefined)
|
|
45
|
+
ctx.headers[name] = wrap(value);
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=headerBinding.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"headerBinding.js","sourceRoot":"","sources":["../../../src/schema/headerBinding.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,QAAQ,EAAgB,MAAM,kBAAkB,CAAA;AAqBxD,MAAM,MAAM,GAAG,SAAS,CAAA;AAExB;;;;;;;;GAQG;AACH,MAAM,UAAU,MAAM,CAAC,GAAqC,EAAE,IAAgF;IAC1I,MAAM,IAAI,GAAG,CAAC,IAAI,EAAE,IAAI,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAA;IACnD,MAAM,MAAM,GAAG,IAAI,EAAE,MAAM,KAAK,QAAQ,CAAA;IACxC,MAAM,MAAM,GAAG,CAAC,GAAuB,EAAsB,EAAE;QAC3D,IAAI,GAAG,KAAK,SAAS;YAAE,OAAO,SAAS,CAAA;QACvC,OAAO,MAAM,IAAI,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAA;IAC5E,CAAC,CAAA;IACD,MAAM,IAAI,GAAG,CAAC,KAAa,EAAU,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAA;IAC5E,OAAO;QACH,OAAO,EAAE,EAAC,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,IAAI,QAAQ,CAAC,WAAW,EAAC;QACvD,eAAe,EAAE,EAAE;QACnB,YAAY,CAAC,GAAkB;YAC3B,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAA;YAC/B,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;YAC7F,IAAI,KAAK,KAAK,SAAS;gBAAE,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;QAC3C,CAAC;QACD,aAAa,CAAC,GAAkB;YAC5B,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,EAAE,CAAA;YACvB,IAAI,KAAK,KAAK,SAAS;gBAAE,OAAM;YAC/B,GAAG,CAAC,OAAO,GAAG,GAAG,CAAC,OAAO,IAAI,EAAE,CAAA;YAC/B,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAA;QACnC,CAAC;QACD,cAAc,CAAC,GAA2B;YACtC,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,CAAA;YACzC,IAAI,KAAK,KAAK,SAAS;gBAAE,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;QAC3C,CAAC;QACD,eAAe,CAAC,GAA2B;YACvC,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,EAAE,CAAA;YACvB,IAAI,KAAK,KAAK,SAAS;gBAAE,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAA;QAC5D,CAAC;KACJ,CAAA;AACL,CAAC"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { GGHttpCodec, GGHttpSchema } from "./GGHttpSchema";
|
|
2
2
|
import { GGHttpTransportMiddleware } from "./GGHttpSchema";
|
|
3
3
|
import { GGContractApiDefinition, GGContractClass } from "@grest-ts/schema";
|
|
4
|
-
import { GGContextKey } from "@grest-ts/context";
|
|
5
4
|
/**
|
|
6
5
|
* Create an HTTP API schema builder from a contract.
|
|
7
6
|
*
|
|
@@ -34,7 +33,6 @@ declare class GGHttpSchemaBuilder<TContract extends GGContractApiDefinition, TCo
|
|
|
34
33
|
constructor(contract: GGContractClass<TContract>);
|
|
35
34
|
pathPrefix(prefix: string): this;
|
|
36
35
|
use<M extends GGHttpTransportMiddleware>(middleware: M): GGHttpSchemaBuilder<TContract, TContext | M>;
|
|
37
|
-
useHeader<Input>(contextKey: GGContextKey<Input>): GGHttpSchemaBuilder<TContract, TContext | Input>;
|
|
38
36
|
routes(mapping: {
|
|
39
37
|
[K in keyof TContract]: GGHttpCodec;
|
|
40
38
|
}): GGHttpSchema<TContract, TContext>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"httpSchema.d.ts","sourceRoot":"","sources":["../../../src/schema/httpSchema.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"httpSchema.d.ts","sourceRoot":"","sources":["../../../src/schema/httpSchema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAE,YAAY,EAAC,MAAM,gBAAgB,CAAC;AACzD,OAAO,EAAC,yBAAyB,EAAC,MAAM,gBAAgB,CAAC;AACzD,OAAO,EAAC,uBAAuB,EAAE,eAAe,EAAC,MAAM,kBAAkB,CAAC;AAE1E;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,UAAU,CAAC,SAAS,SAAS,uBAAuB,EAChE,QAAQ,EAAE,eAAe,CAAC,SAAS,CAAC,GACrC,mBAAmB,CAAC,SAAS,CAAC,CAEhC;AAED,cAAM,mBAAmB,CAAC,SAAS,SAAS,uBAAuB,EAAE,QAAQ,GAAG,SAAS;IAErF,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA4B;IACtD,OAAO,CAAC,WAAW,CAAa;IAChC,OAAO,CAAC,YAAY,CAAkC;gBAE1C,QAAQ,EAAE,eAAe,CAAC,SAAS,CAAC;IAIhD,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAKhC,GAAG,CAAC,CAAC,SAAS,yBAAyB,EAAE,UAAU,EAAE,CAAC,GAAG,mBAAmB,CAAC,SAAS,EAAE,QAAQ,GAAG,CAAC,CAAC;IAKrG,MAAM,CAAC,OAAO,EAAE;SAAG,CAAC,IAAI,MAAM,SAAS,GAAG,WAAW;KAAE,GAAG,YAAY,CAAC,SAAS,EAAE,QAAQ,CAAC;CAG9F"}
|
|
@@ -41,54 +41,6 @@ class GGHttpSchemaBuilder {
|
|
|
41
41
|
this._middlewares.push(middleware);
|
|
42
42
|
return this;
|
|
43
43
|
}
|
|
44
|
-
useHeader(contextKey) {
|
|
45
|
-
const codec = contextKey.getCodec("http");
|
|
46
|
-
if (!codec) {
|
|
47
|
-
throw new Error(`Context key '${contextKey.name}' does not have an 'http-header' codec registered.`);
|
|
48
|
-
}
|
|
49
|
-
// Build the typed header map from codec.inputSchema — the IsObject({headerName: schema})
|
|
50
|
-
// that describes which headers this codec reads and what format each value has.
|
|
51
|
-
const inputSchema = codec.inputSchema;
|
|
52
|
-
const headers = {};
|
|
53
|
-
if (inputSchema) {
|
|
54
|
-
const desc = inputSchema.toSchemaDescription();
|
|
55
|
-
if (desc.node.kind === 'object') {
|
|
56
|
-
for (const [k, fieldDesc] of Object.entries(desc.node.properties)) {
|
|
57
|
-
headers[k] = fieldDesc.schema;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
const middleware = {
|
|
62
|
-
headers,
|
|
63
|
-
responseHeaders: {},
|
|
64
|
-
updateRequest(req) {
|
|
65
|
-
const contextValue = contextKey.get();
|
|
66
|
-
if (contextValue !== undefined) {
|
|
67
|
-
const result = codec.decode(contextValue);
|
|
68
|
-
if (result.success) {
|
|
69
|
-
Object.assign(req.headers, result.value);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
else {
|
|
73
|
-
const emptyResult = codec.decode({});
|
|
74
|
-
if (emptyResult.success) {
|
|
75
|
-
for (const key of Object.keys(emptyResult.value)) {
|
|
76
|
-
delete req.headers[key];
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
},
|
|
81
|
-
parseRequest(req) {
|
|
82
|
-
const headers = req.headers;
|
|
83
|
-
const result = codec.encode(headers);
|
|
84
|
-
if (result.success) {
|
|
85
|
-
contextKey.set(result.value);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
};
|
|
89
|
-
this._middlewares.push(middleware);
|
|
90
|
-
return this;
|
|
91
|
-
}
|
|
92
44
|
routes(mapping) {
|
|
93
45
|
return new GGHttpSchema(this._pathPrefix, this._contract, mapping, this._middlewares);
|
|
94
46
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"httpSchema.js","sourceRoot":"","sources":["../../../src/schema/httpSchema.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"httpSchema.js","sourceRoot":"","sources":["../../../src/schema/httpSchema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,YAAY,EAAC,MAAM,gBAAgB,CAAC;AAIzD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,UAAU,UAAU,CACtB,QAAoC;IAEpC,OAAO,IAAI,mBAAmB,CAAC,QAAQ,CAAC,CAAA;AAC5C,CAAC;AAED,MAAM,mBAAmB;IAEJ,SAAS,CAA4B;IAC9C,WAAW,GAAW,EAAE,CAAA;IACxB,YAAY,GAAgC,EAAE,CAAA;IAEtD,YAAY,QAAoC;QAC5C,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;IAC9B,CAAC;IAED,UAAU,CAAC,MAAc;QACrB,IAAI,CAAC,WAAW,GAAG,MAAM,CAAA;QACzB,OAAO,IAAI,CAAA;IACf,CAAC;IAED,GAAG,CAAsC,UAAa;QAClD,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;QAClC,OAAO,IAA+D,CAAA;IAC1E,CAAC;IAED,MAAM,CAAC,OAAgD;QACnD,OAAO,IAAI,YAAY,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,CAAA;IACzF,CAAC;CACJ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GGHttpSchema.startServer.d.ts","sourceRoot":"","sources":["../../../src/server/GGHttpSchema.startServer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAA0D,uBAAuB,EAAE,wBAAwB,EAAqF,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"GGHttpSchema.startServer.d.ts","sourceRoot":"","sources":["../../../src/server/GGHttpSchema.startServer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAA0D,uBAAuB,EAAE,wBAAwB,EAAqF,MAAM,kBAAkB,CAAC;AAUhO,OAAO,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAC;AAG5C,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,UAAU,CAAC;AAE9C,MAAM,WAAW,kBAAkB;IAC/B;;OAEG;IACH,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB;;OAEG;IACH,WAAW,CAAC,EAAE,sBAAsB,EAAE,CAAC;IACvC;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,eAAe,CAAC;CACxC;AAED,MAAM,WAAW,sBAAsB;IACnC,OAAO,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CAC5B;AAED,OAAO,QAAQ,wBAAwB,CAAC;IACpC,UAAU,YAAY,CAAC,SAAS,SAAS,uBAAuB;QAC5D;;;;WAIG;QACH,QAAQ,CAAC,cAAc,EAAE,wBAAwB,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAAA;KACnG;CACJ"}
|
|
@@ -9,6 +9,7 @@ import { GG_DISCOVERY } from "@grest-ts/discovery";
|
|
|
9
9
|
import { GGContext, GGContextStore } from "@grest-ts/context";
|
|
10
10
|
import { GG_TRACE } from "@grest-ts/trace";
|
|
11
11
|
import { GG_HTTP_REQUEST } from "./GG_HTTP_REQUEST.js";
|
|
12
|
+
import { GG_COOKIE_WRITES } from "../schema/cookieMiddleware.js";
|
|
12
13
|
import { GG_METRICS } from "@grest-ts/metrics";
|
|
13
14
|
import { GGHttpMetrics } from "./GGHttpMetrics.js";
|
|
14
15
|
import { GG_HTTP_SERVER } from "./GG_HTTP_SERVER.js";
|
|
@@ -77,11 +78,13 @@ function setupRoutes(httpSchema, implementation, config) {
|
|
|
77
78
|
apiMiddlewares: apiMiddlewares,
|
|
78
79
|
serverMiddlewares: config.middlewares
|
|
79
80
|
});
|
|
81
|
+
const cookieWriteNames = new Set((codec.updatesCookies ?? []).map(k => k.name));
|
|
80
82
|
server.registerRoute(codec.method, pathPrefix + codec.path, async (req, res) => {
|
|
81
83
|
scope.ensureEntered();
|
|
82
|
-
return new GGContext("REQ", parentContext).run(async () => {
|
|
84
|
+
return new GGContext("REQ", parentContext, true).run(async () => {
|
|
83
85
|
GG_TRACE.init();
|
|
84
86
|
GG_HTTP_REQUEST.set({ port: server.port, method: req.method, path: req.url });
|
|
87
|
+
GG_COOKIE_WRITES.set(cookieWriteNames);
|
|
85
88
|
const startTime = performance.now();
|
|
86
89
|
let rpcResult;
|
|
87
90
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GGHttpSchema.startServer.js","sourceRoot":"","sources":["../../../src/server/GGHttpSchema.startServer.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"GGHttpSchema.startServer.js","sourceRoot":"","sources":["../../../src/server/GGHttpSchema.startServer.ts"],"names":[],"mappings":"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"}
|
|
@@ -14,9 +14,30 @@ type AnyWebSocketSchema = {
|
|
|
14
14
|
middlewares: readonly unknown[];
|
|
15
15
|
connectPermission?: GGPermission;
|
|
16
16
|
};
|
|
17
|
+
export interface GGCorsConfig {
|
|
18
|
+
/**
|
|
19
|
+
* Allowed cross-origin origins. Either an exact-match list or a predicate.
|
|
20
|
+
* Only a matching Origin is echoed back — an arbitrary origin is never
|
|
21
|
+
* reflected (that would be a credential-leak / CSRF hole with credentials on).
|
|
22
|
+
*/
|
|
23
|
+
origins: string[] | ((origin: string) => boolean);
|
|
24
|
+
/**
|
|
25
|
+
* When true, adds Access-Control-Allow-Credentials: true so the browser will
|
|
26
|
+
* send/store cross-origin cookies. Requires an exact-origin echo (never `*`),
|
|
27
|
+
* which this enforces by construction.
|
|
28
|
+
*/
|
|
29
|
+
credentials?: boolean;
|
|
30
|
+
}
|
|
17
31
|
export interface GGHttpServerAdapterConfig {
|
|
18
32
|
key?: GGLocatorKey<GGHttpServer>;
|
|
19
33
|
port?: number;
|
|
34
|
+
/**
|
|
35
|
+
* Cross-origin policy. Omitted (default) keeps the permissive
|
|
36
|
+
* `Access-Control-Allow-Origin: *` with no credentials — backward compatible.
|
|
37
|
+
* When set, switches to allowlisted mode: only an Origin in `origins` is echoed
|
|
38
|
+
* (never `*`), and `credentials: true` enables cross-origin cookies.
|
|
39
|
+
*/
|
|
40
|
+
cors?: GGCorsConfig;
|
|
20
41
|
/**
|
|
21
42
|
* If provided, the server listens over HTTPS using this cert+key. Both
|
|
22
43
|
* must be PEM-encoded strings or Buffers. Leaving undefined keeps the
|
|
@@ -36,6 +57,7 @@ export declare class GGHttpServer {
|
|
|
36
57
|
protected readonly scope: GGLocatorScope;
|
|
37
58
|
protected readonly runtimeName: string;
|
|
38
59
|
private readonly configuredPort;
|
|
60
|
+
private readonly cors?;
|
|
39
61
|
private readonly _onStart;
|
|
40
62
|
private readonly _onTeardown;
|
|
41
63
|
/**
|
|
@@ -93,5 +115,12 @@ export declare class GGHttpServer {
|
|
|
93
115
|
onTeardown(callback: () => Promise<void> | void): this;
|
|
94
116
|
}
|
|
95
117
|
export type GGHttpRequestCallback = (req: http.IncomingMessage, res: http.ServerResponse) => Promise<void>;
|
|
118
|
+
/**
|
|
119
|
+
* Computes CORS response headers for a request Origin. Pure (no req/res) so it is
|
|
120
|
+
* unit-testable. Default (no config) = permissive `*`, no credentials. With config =
|
|
121
|
+
* allowlisted: only a matching Origin is echoed (never `*`), `credentials` adds
|
|
122
|
+
* Allow-Credentials, and Vary: Origin is always set so caches key on the origin.
|
|
123
|
+
*/
|
|
124
|
+
export declare function corsResponseHeaders(origin: string | undefined, cors: GGCorsConfig | undefined, allowHeaders: string, exposeHeaders: string): Record<string, string>;
|
|
96
125
|
export {};
|
|
97
126
|
//# sourceMappingURL=GGHttpServer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GGHttpServer.d.ts","sourceRoot":"","sources":["../../../src/server/GGHttpServer.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,EAAC,UAAU,EAAiB,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAY,YAAY,EAAE,cAAc,EAAuB,MAAM,mBAAmB,CAAC;AAIhG,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAwC,gBAAgB,EAAE,YAAY,EAAC,MAAM,kBAAkB,CAAC;AAGvG,KAAK,kBAAkB,GAAG;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE;QAAC,cAAc,EAAE;YAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAA;SAAC,CAAA;KAAC,CAAC;IACxE,WAAW,EAAE,SAAS,OAAO,EAAE,CAAC;IAChC,iBAAiB,CAAC,EAAE,YAAY,CAAC;CACpC,CAAC;AAEF,MAAM,WAAW,yBAAyB;IACtC,GAAG,CAAC,EAAE,YAAY,CAAC,YAAY,CAAC,CAAC;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;;;OAOG;IACH,GAAG,CAAC,EAAE;QACF,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;QACtB,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;KACxB,CAAC;CACL;AAED,qBAAa,YAAY;IAErB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,SAAS,CAAC,eAAe,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC;IACrD,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC;IACzC,SAAS,CAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IACvC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;
|
|
1
|
+
{"version":3,"file":"GGHttpServer.d.ts","sourceRoot":"","sources":["../../../src/server/GGHttpServer.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,6 +12,7 @@ export class GGHttpServer {
|
|
|
12
12
|
scope;
|
|
13
13
|
runtimeName;
|
|
14
14
|
configuredPort;
|
|
15
|
+
cors;
|
|
15
16
|
_onStart = [];
|
|
16
17
|
_onTeardown = [];
|
|
17
18
|
/**
|
|
@@ -38,6 +39,7 @@ export class GGHttpServer {
|
|
|
38
39
|
this.runtimeName = GGLocator.getScope().serviceName;
|
|
39
40
|
this.scope = GGLocator.getScope();
|
|
40
41
|
this.configuredPort = config?.port ?? (process.env.PORT ? Number(process.env.PORT) : 0);
|
|
42
|
+
this.cors = config?.cors;
|
|
41
43
|
GGLocator.getScope().setWithLifecycle(config?.key ?? GG_HTTP_SERVER, this, {
|
|
42
44
|
type: GGLocatorServiceType.HTTP,
|
|
43
45
|
start: this.start.bind(this),
|
|
@@ -51,14 +53,9 @@ export class GGHttpServer {
|
|
|
51
53
|
}
|
|
52
54
|
this.activeRequests++;
|
|
53
55
|
try {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
res.setHeader(
|
|
57
|
-
res.setHeader('Access-Control-Allow-Headers', this._corsHeadersCache);
|
|
58
|
-
if (this._corsExposeHeadersCache) {
|
|
59
|
-
res.setHeader('Access-Control-Expose-Headers', this._corsExposeHeadersCache);
|
|
60
|
-
}
|
|
61
|
-
}
|
|
56
|
+
const cors = corsResponseHeaders(req.headers.origin, this.cors, this._corsHeadersCache, this._corsExposeHeadersCache);
|
|
57
|
+
for (const name in cors)
|
|
58
|
+
res.setHeader(name, cors[name]);
|
|
62
59
|
if (req.method === 'OPTIONS') {
|
|
63
60
|
res.writeHead(204);
|
|
64
61
|
res.end();
|
|
@@ -253,4 +250,34 @@ export class GGHttpServer {
|
|
|
253
250
|
return this;
|
|
254
251
|
}
|
|
255
252
|
}
|
|
253
|
+
/**
|
|
254
|
+
* Computes CORS response headers for a request Origin. Pure (no req/res) so it is
|
|
255
|
+
* unit-testable. Default (no config) = permissive `*`, no credentials. With config =
|
|
256
|
+
* allowlisted: only a matching Origin is echoed (never `*`), `credentials` adds
|
|
257
|
+
* Allow-Credentials, and Vary: Origin is always set so caches key on the origin.
|
|
258
|
+
*/
|
|
259
|
+
export function corsResponseHeaders(origin, cors, allowHeaders, exposeHeaders) {
|
|
260
|
+
if (!origin)
|
|
261
|
+
return {};
|
|
262
|
+
const headers = {};
|
|
263
|
+
if (cors) {
|
|
264
|
+
// Never reflect the literal "null" origin (sandboxed iframe / file:// / opaque
|
|
265
|
+
// origins) with credentials — the classic null-origin credential-leak footgun.
|
|
266
|
+
const allowed = origin !== "null" && (Array.isArray(cors.origins) ? cors.origins.includes(origin) : cors.origins(origin));
|
|
267
|
+
headers['Vary'] = 'Origin';
|
|
268
|
+
if (!allowed)
|
|
269
|
+
return headers;
|
|
270
|
+
headers['Access-Control-Allow-Origin'] = origin;
|
|
271
|
+
if (cors.credentials)
|
|
272
|
+
headers['Access-Control-Allow-Credentials'] = 'true';
|
|
273
|
+
}
|
|
274
|
+
else {
|
|
275
|
+
headers['Access-Control-Allow-Origin'] = '*';
|
|
276
|
+
}
|
|
277
|
+
headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, PATCH, DELETE, OPTIONS';
|
|
278
|
+
headers['Access-Control-Allow-Headers'] = allowHeaders;
|
|
279
|
+
if (exposeHeaders)
|
|
280
|
+
headers['Access-Control-Expose-Headers'] = exposeHeaders;
|
|
281
|
+
return headers;
|
|
282
|
+
}
|
|
256
283
|
//# sourceMappingURL=GGHttpServer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GGHttpServer.js","sourceRoot":"","sources":["../../../src/server/GGHttpServer.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAa,cAAc,EAAC,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAC,SAAS,EAAgC,oBAAoB,EAAC,MAAM,mBAAmB,CAAC;AAChG,OAAO,EAAC,cAAc,EAAC,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAC,KAAK,EAAC,MAAM,kBAAkB,CAAC;AACvC,OAAO,SAAuB,MAAM,aAAa,CAAC;AAElD,OAAO,EAAC,kBAAkB,EAAE,iBAAiB,EAAiC,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"GGHttpServer.js","sourceRoot":"","sources":["../../../src/server/GGHttpServer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type http from "http";
|
|
2
|
+
import type { GGHttpTransportMiddleware } from "../schema/GGHttpSchema";
|
|
3
|
+
/**
|
|
4
|
+
* Runs the transport chain's server-side response hook and writes the collected
|
|
5
|
+
* headers onto the Node response. Applied via setHeader (not writeHead) so a
|
|
6
|
+
* string[] value emits one header line per element — the only way to send
|
|
7
|
+
* multiple Set-Cookie headers — and so the codec's later writeHead(Content-*)
|
|
8
|
+
* merges rather than clobbers. Must run inside the request GGContext so a
|
|
9
|
+
* middleware can read per-request staged state.
|
|
10
|
+
*/
|
|
11
|
+
export declare function applyResponseMiddleware(res: http.ServerResponse, middlewares: readonly GGHttpTransportMiddleware[] | undefined): void;
|
|
12
|
+
//# sourceMappingURL=applyResponseMiddleware.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"applyResponseMiddleware.d.ts","sourceRoot":"","sources":["../../../src/server/applyResponseMiddleware.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,KAAK,EAAiB,yBAAyB,EAAC,MAAM,wBAAwB,CAAC;AAEtF;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CACnC,GAAG,EAAE,IAAI,CAAC,cAAc,EACxB,WAAW,EAAE,SAAS,yBAAyB,EAAE,GAAG,SAAS,GAC9D,IAAI,CAYN"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runs the transport chain's server-side response hook and writes the collected
|
|
3
|
+
* headers onto the Node response. Applied via setHeader (not writeHead) so a
|
|
4
|
+
* string[] value emits one header line per element — the only way to send
|
|
5
|
+
* multiple Set-Cookie headers — and so the codec's later writeHead(Content-*)
|
|
6
|
+
* merges rather than clobbers. Must run inside the request GGContext so a
|
|
7
|
+
* middleware can read per-request staged state.
|
|
8
|
+
*/
|
|
9
|
+
export function applyResponseMiddleware(res, middlewares) {
|
|
10
|
+
if (!middlewares?.length || res.headersSent)
|
|
11
|
+
return;
|
|
12
|
+
let response;
|
|
13
|
+
for (const mw of middlewares) {
|
|
14
|
+
if (!mw.updateResponse)
|
|
15
|
+
continue;
|
|
16
|
+
response ??= { headers: {} };
|
|
17
|
+
mw.updateResponse(response);
|
|
18
|
+
}
|
|
19
|
+
if (!response)
|
|
20
|
+
return;
|
|
21
|
+
for (const name in response.headers) {
|
|
22
|
+
res.setHeader(name, response.headers[name]);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=applyResponseMiddleware.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"applyResponseMiddleware.js","sourceRoot":"","sources":["../../../src/server/applyResponseMiddleware.ts"],"names":[],"mappings":"AAGA;;;;;;;GAOG;AACH,MAAM,UAAU,uBAAuB,CACnC,GAAwB,EACxB,WAA6D;IAE7D,IAAI,CAAC,WAAW,EAAE,MAAM,IAAI,GAAG,CAAC,WAAW;QAAE,OAAO;IACpD,IAAI,QAAoC,CAAC;IACzC,KAAK,MAAM,EAAE,IAAI,WAAW,EAAE,CAAC;QAC3B,IAAI,CAAC,EAAE,CAAC,cAAc;YAAE,SAAS;QACjC,QAAQ,KAAK,EAAC,OAAO,EAAE,EAAE,EAAC,CAAC;QAC3B,EAAE,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;IAChC,CAAC;IACD,IAAI,CAAC,QAAQ;QAAE,OAAO;IACtB,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;QAClC,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IAChD,CAAC;AACL,CAAC"}
|