@wooksjs/event-http 0.6.2 → 0.6.3
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 +24 -0
- package/dist/index.cjs +132 -25
- package/dist/index.d.ts +110 -12
- package/dist/index.mjs +132 -25
- package/package.json +45 -37
- package/scripts/setup-skills.js +70 -0
- package/skills/wooksjs-event-http/SKILL.md +37 -0
- package/skills/wooksjs-event-http/addons.md +307 -0
- package/skills/wooksjs-event-http/core.md +297 -0
- package/skills/wooksjs-event-http/error-handling.md +253 -0
- package/skills/wooksjs-event-http/event-core.md +562 -0
- package/skills/wooksjs-event-http/request.md +220 -0
- package/skills/wooksjs-event-http/response.md +336 -0
- package/skills/wooksjs-event-http/routing.md +412 -0
package/README.md
CHANGED
|
@@ -51,6 +51,30 @@ app.listen(3000, () => {
|
|
|
51
51
|
})
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
+
## AI Agent Skills
|
|
55
|
+
|
|
56
|
+
This package ships with structured skill files for AI coding agents (Claude Code, Cursor, Windsurf, Codex, etc.).
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
# Project-local (recommended — version-locked, commits with your repo)
|
|
60
|
+
npx @wooksjs/event-http setup-skills
|
|
61
|
+
|
|
62
|
+
# Global (available across all your projects)
|
|
63
|
+
npx @wooksjs/event-http setup-skills --global
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
To keep skills automatically up-to-date, add a postinstall script to your `package.json`:
|
|
67
|
+
|
|
68
|
+
```json
|
|
69
|
+
{
|
|
70
|
+
"scripts": {
|
|
71
|
+
"postinstall": "npx @wooksjs/event-http setup-skills --postinstall"
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
This ensures the skill files are refreshed whenever dependencies are installed, without needing a separate command.
|
|
77
|
+
|
|
54
78
|
## Documentation
|
|
55
79
|
|
|
56
80
|
To check out docs, visit [wooks.moost.org](https://wooks.moost.org/webapp/).
|
package/dist/index.cjs
CHANGED
|
@@ -32,6 +32,7 @@ const wooks = __toESM(require("wooks"));
|
|
|
32
32
|
const stream = __toESM(require("stream"));
|
|
33
33
|
|
|
34
34
|
//#region packages/event-http/src/event-http.ts
|
|
35
|
+
/** Creates an async event context for an incoming HTTP request/response pair. */
|
|
35
36
|
function createHttpContext(data, options) {
|
|
36
37
|
return (0, __wooksjs_event_core.createAsyncEventContext)({
|
|
37
38
|
event: {
|
|
@@ -57,7 +58,7 @@ function escapeRegex(s) {
|
|
|
57
58
|
function safeDecode(f, v) {
|
|
58
59
|
try {
|
|
59
60
|
return f(v);
|
|
60
|
-
} catch
|
|
61
|
+
} catch {
|
|
61
62
|
return v;
|
|
62
63
|
}
|
|
63
64
|
}
|
|
@@ -89,7 +90,12 @@ const units = {
|
|
|
89
90
|
|
|
90
91
|
//#endregion
|
|
91
92
|
//#region packages/event-http/src/utils/set-cookie.ts
|
|
93
|
+
const COOKIE_NAME_RE = /^[\w!#$%&'*+\-.^`|~]+$/;
|
|
94
|
+
function sanitizeCookieAttrValue(v) {
|
|
95
|
+
return v.replace(/[;\r\n]/g, "");
|
|
96
|
+
}
|
|
92
97
|
function renderCookie(key, data) {
|
|
98
|
+
if (!COOKIE_NAME_RE.test(key)) throw new TypeError(`Invalid cookie name "${key}"`);
|
|
93
99
|
let attrs = "";
|
|
94
100
|
for (const [a, v] of Object.entries(data.attrs)) {
|
|
95
101
|
const func = cookieAttrFunc[a];
|
|
@@ -103,8 +109,8 @@ function renderCookie(key, data) {
|
|
|
103
109
|
const cookieAttrFunc = {
|
|
104
110
|
expires: (v) => `Expires=${typeof v === "string" || typeof v === "number" ? new Date(v).toUTCString() : v.toUTCString()}`,
|
|
105
111
|
maxAge: (v) => `Max-Age=${convertTime(v, "s").toString()}`,
|
|
106
|
-
domain: (v) => `Domain=${v}`,
|
|
107
|
-
path: (v) => `Path=${v}`,
|
|
112
|
+
domain: (v) => `Domain=${sanitizeCookieAttrValue(String(v))}`,
|
|
113
|
+
path: (v) => `Path=${sanitizeCookieAttrValue(String(v))}`,
|
|
108
114
|
secure: (v) => v ? "Secure" : "",
|
|
109
115
|
httpOnly: (v) => v ? "HttpOnly" : "",
|
|
110
116
|
sameSite: (v) => v ? `SameSite=${typeof v === "string" ? v : "Strict"}` : ""
|
|
@@ -125,7 +131,7 @@ function encodingSupportsStream(encodings) {
|
|
|
125
131
|
}
|
|
126
132
|
async function uncompressBody(encodings, compressed) {
|
|
127
133
|
let buf = compressed;
|
|
128
|
-
for (const enc of encodings.slice().
|
|
134
|
+
for (const enc of encodings.slice().toReversed()) {
|
|
129
135
|
const c = compressors[enc];
|
|
130
136
|
if (!c) throw new Error(`Unsupported compression type "${enc}".`);
|
|
131
137
|
buf = await c.uncompress(buf);
|
|
@@ -135,7 +141,7 @@ async function uncompressBody(encodings, compressed) {
|
|
|
135
141
|
async function uncompressBodyStream(encodings, src) {
|
|
136
142
|
if (!encodingSupportsStream(encodings)) throw new Error("Some encodings lack a streaming decompressor");
|
|
137
143
|
let out = src;
|
|
138
|
-
for (const enc of Array.from(encodings).
|
|
144
|
+
for (const enc of Array.from(encodings).toReversed()) out = await compressors[enc].stream.uncompress(out);
|
|
139
145
|
return out;
|
|
140
146
|
}
|
|
141
147
|
|
|
@@ -455,8 +461,9 @@ function error_tl_default(ctx) {
|
|
|
455
461
|
<title>${statusCode} ${statusMessage}</title>
|
|
456
462
|
<style>
|
|
457
463
|
body {
|
|
458
|
-
font-family:
|
|
459
|
-
|
|
464
|
+
font-family:
|
|
465
|
+
-apple-system, BlinkMacMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell,
|
|
466
|
+
'Open Sans', 'Helvetica Neue', sans-serif;
|
|
460
467
|
display: flex;
|
|
461
468
|
justify-content: center;
|
|
462
469
|
align-items: flex-start;
|
|
@@ -690,11 +697,12 @@ function error_tl_default(ctx) {
|
|
|
690
697
|
//#endregion
|
|
691
698
|
//#region packages/event-http/src/errors/error-renderer.ts
|
|
692
699
|
let framework = {
|
|
693
|
-
version: "0.6.
|
|
700
|
+
version: "0.6.2",
|
|
694
701
|
poweredBy: `wooksjs`,
|
|
695
702
|
link: `https://wooks.moost.org/`,
|
|
696
703
|
image: `https://wooks.moost.org/wooks-full-logo.png`
|
|
697
704
|
};
|
|
705
|
+
/** Renders HTTP error responses in HTML, JSON, or plain text based on the Accept header. */
|
|
698
706
|
var HttpErrorRenderer = class extends BaseHttpResponseRenderer {
|
|
699
707
|
constructor(opts) {
|
|
700
708
|
super();
|
|
@@ -766,6 +774,7 @@ function escapeQuotes(s) {
|
|
|
766
774
|
|
|
767
775
|
//#endregion
|
|
768
776
|
//#region packages/event-http/src/errors/http-error.ts
|
|
777
|
+
/** Represents an HTTP error with a status code and optional structured body. */
|
|
769
778
|
var HttpError = class extends Error {
|
|
770
779
|
name = "HttpError";
|
|
771
780
|
constructor(code = 500, _body = "") {
|
|
@@ -797,15 +806,24 @@ var HttpError = class extends Error {
|
|
|
797
806
|
//#endregion
|
|
798
807
|
//#region packages/event-http/src/composables/request.ts
|
|
799
808
|
const xForwardedFor = "x-forwarded-for";
|
|
809
|
+
/** Default safety limits for request body reading (size, ratio, timeout). */
|
|
800
810
|
const DEFAULT_LIMITS = {
|
|
801
811
|
maxCompressed: 1 * 1024 * 1024,
|
|
802
812
|
maxInflated: 10 * 1024 * 1024,
|
|
803
813
|
maxRatio: 100,
|
|
804
814
|
readTimeoutMs: 1e4
|
|
805
815
|
};
|
|
816
|
+
/**
|
|
817
|
+
* Provides access to the incoming HTTP request (method, url, headers, body, IP).
|
|
818
|
+
* @example
|
|
819
|
+
* ```ts
|
|
820
|
+
* const { method, url, rawBody, getIp } = useRequest()
|
|
821
|
+
* const body = await rawBody()
|
|
822
|
+
* ```
|
|
823
|
+
*/
|
|
806
824
|
function useRequest() {
|
|
807
825
|
const { store } = useHttpContext();
|
|
808
|
-
const { init
|
|
826
|
+
const { init } = store("request");
|
|
809
827
|
const event = store("event");
|
|
810
828
|
const req = event.get("req");
|
|
811
829
|
const contentEncoding = req.headers["content-encoding"];
|
|
@@ -819,18 +837,33 @@ function useRequest() {
|
|
|
819
837
|
].includes(p)) return true;
|
|
820
838
|
return false;
|
|
821
839
|
});
|
|
822
|
-
const
|
|
823
|
-
const
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
840
|
+
const limits = () => event.get("requestLimits");
|
|
841
|
+
const setLimit = (key, value) => {
|
|
842
|
+
let obj = limits();
|
|
843
|
+
if (!obj?.perRequest) {
|
|
844
|
+
obj = {
|
|
845
|
+
...obj,
|
|
846
|
+
perRequest: true
|
|
847
|
+
};
|
|
848
|
+
event.set("requestLimits", obj);
|
|
849
|
+
}
|
|
850
|
+
obj[key] = value;
|
|
851
|
+
};
|
|
852
|
+
const getMaxCompressed = () => limits()?.maxCompressed ?? DEFAULT_LIMITS.maxCompressed;
|
|
853
|
+
const setMaxCompressed = (limit) => setLimit("maxCompressed", limit);
|
|
854
|
+
const getMaxInflated = () => limits()?.maxInflated ?? DEFAULT_LIMITS.maxInflated;
|
|
855
|
+
const setMaxInflated = (limit) => setLimit("maxInflated", limit);
|
|
856
|
+
const getMaxRatio = () => limits()?.maxRatio ?? DEFAULT_LIMITS.maxRatio;
|
|
857
|
+
const setMaxRatio = (limit) => setLimit("maxRatio", limit);
|
|
858
|
+
const getReadTimeoutMs = () => limits()?.readTimeoutMs ?? DEFAULT_LIMITS.readTimeoutMs;
|
|
859
|
+
const setReadTimeoutMs = (limit) => setLimit("readTimeoutMs", limit);
|
|
828
860
|
const rawBody = () => init("rawBody", async () => {
|
|
829
861
|
const encs = contentEncodings();
|
|
830
862
|
const isZip = isCompressed();
|
|
831
863
|
const streamable = isZip && encodingSupportsStream(encs);
|
|
832
864
|
const maxCompressed = getMaxCompressed();
|
|
833
865
|
const maxInflated = getMaxInflated();
|
|
866
|
+
const maxRatio = getMaxRatio();
|
|
834
867
|
const timeoutMs = getReadTimeoutMs();
|
|
835
868
|
const cl = Number(req.headers["content-length"] ?? 0);
|
|
836
869
|
const upfrontLimit = isZip ? maxCompressed : maxInflated;
|
|
@@ -888,6 +921,7 @@ function useRequest() {
|
|
|
888
921
|
inflatedBytes = body.byteLength;
|
|
889
922
|
if (inflatedBytes > maxInflated) throw new HttpError(413, "Inflated body too large");
|
|
890
923
|
}
|
|
924
|
+
if (isZip && rawBytes > 0 && inflatedBytes / rawBytes > maxRatio) throw new HttpError(413, "Compression ratio too high");
|
|
891
925
|
return body;
|
|
892
926
|
});
|
|
893
927
|
const reqId = (0, __wooksjs_event_core.useEventId)().getId;
|
|
@@ -919,15 +953,32 @@ function useRequest() {
|
|
|
919
953
|
getReadTimeoutMs,
|
|
920
954
|
setReadTimeoutMs,
|
|
921
955
|
getMaxInflated,
|
|
922
|
-
setMaxInflated
|
|
956
|
+
setMaxInflated,
|
|
957
|
+
getMaxRatio,
|
|
958
|
+
setMaxRatio
|
|
923
959
|
};
|
|
924
960
|
}
|
|
925
961
|
|
|
926
962
|
//#endregion
|
|
927
963
|
//#region packages/event-http/src/composables/headers.ts
|
|
964
|
+
/**
|
|
965
|
+
* Returns the incoming request headers.
|
|
966
|
+
* @example
|
|
967
|
+
* ```ts
|
|
968
|
+
* const { host, authorization } = useHeaders()
|
|
969
|
+
* ```
|
|
970
|
+
*/
|
|
928
971
|
function useHeaders() {
|
|
929
972
|
return useRequest().headers;
|
|
930
973
|
}
|
|
974
|
+
/**
|
|
975
|
+
* Provides methods to set, get, and remove outgoing response headers.
|
|
976
|
+
* @example
|
|
977
|
+
* ```ts
|
|
978
|
+
* const { setHeader, setContentType, enableCors } = useSetHeaders()
|
|
979
|
+
* setHeader('x-request-id', '123')
|
|
980
|
+
* ```
|
|
981
|
+
*/
|
|
931
982
|
function useSetHeaders() {
|
|
932
983
|
const { store } = useHttpContext();
|
|
933
984
|
const setHeaderStore = store("setHeader");
|
|
@@ -949,6 +1000,7 @@ function useSetHeaders() {
|
|
|
949
1000
|
enableCors
|
|
950
1001
|
};
|
|
951
1002
|
}
|
|
1003
|
+
/** Returns a hookable accessor for a single outgoing response header by name. */
|
|
952
1004
|
function useSetHeader(name) {
|
|
953
1005
|
const { store } = useHttpContext();
|
|
954
1006
|
const { hook } = store("setHeader");
|
|
@@ -957,6 +1009,14 @@ function useSetHeader(name) {
|
|
|
957
1009
|
|
|
958
1010
|
//#endregion
|
|
959
1011
|
//#region packages/event-http/src/composables/cookies.ts
|
|
1012
|
+
/**
|
|
1013
|
+
* Provides access to parsed request cookies.
|
|
1014
|
+
* @example
|
|
1015
|
+
* ```ts
|
|
1016
|
+
* const { getCookie, rawCookies } = useCookies()
|
|
1017
|
+
* const sessionId = getCookie('session_id')
|
|
1018
|
+
* ```
|
|
1019
|
+
*/
|
|
960
1020
|
function useCookies() {
|
|
961
1021
|
const { store } = useHttpContext();
|
|
962
1022
|
const { cookie } = useHeaders();
|
|
@@ -972,6 +1032,7 @@ function useCookies() {
|
|
|
972
1032
|
getCookie
|
|
973
1033
|
};
|
|
974
1034
|
}
|
|
1035
|
+
/** Provides methods to set, get, remove, and clear outgoing response cookies. */
|
|
975
1036
|
function useSetCookies() {
|
|
976
1037
|
const { store } = useHttpContext();
|
|
977
1038
|
const cookiesStore = store("setCookies");
|
|
@@ -992,6 +1053,7 @@ function useSetCookies() {
|
|
|
992
1053
|
cookies
|
|
993
1054
|
};
|
|
994
1055
|
}
|
|
1056
|
+
/** Returns a hookable accessor for a single outgoing cookie by name. */
|
|
995
1057
|
function useSetCookie(name) {
|
|
996
1058
|
const { setCookie, getCookie } = useSetCookies();
|
|
997
1059
|
const valueHook = (0, __wooksjs_event_core.attachHook)({
|
|
@@ -1013,6 +1075,7 @@ function useSetCookie(name) {
|
|
|
1013
1075
|
|
|
1014
1076
|
//#endregion
|
|
1015
1077
|
//#region packages/event-http/src/composables/header-accept.ts
|
|
1078
|
+
/** Provides helpers to check the request's Accept header for supported MIME types. */
|
|
1016
1079
|
function useAccept() {
|
|
1017
1080
|
const { store } = useHttpContext();
|
|
1018
1081
|
const { accept } = useHeaders();
|
|
@@ -1033,6 +1096,14 @@ function useAccept() {
|
|
|
1033
1096
|
|
|
1034
1097
|
//#endregion
|
|
1035
1098
|
//#region packages/event-http/src/composables/header-authorization.ts
|
|
1099
|
+
/**
|
|
1100
|
+
* Provides parsed access to the Authorization header (type, credentials, Basic decoding).
|
|
1101
|
+
* @example
|
|
1102
|
+
* ```ts
|
|
1103
|
+
* const { isBearer, authRawCredentials, basicCredentials } = useAuthorization()
|
|
1104
|
+
* if (isBearer()) { const token = authRawCredentials() }
|
|
1105
|
+
* ```
|
|
1106
|
+
*/
|
|
1036
1107
|
function useAuthorization() {
|
|
1037
1108
|
const { store } = useHttpContext();
|
|
1038
1109
|
const { authorization } = useHeaders();
|
|
@@ -1105,6 +1176,7 @@ const cacheControlFunc = {
|
|
|
1105
1176
|
const renderAge = (v) => convertTime(v, "s").toString();
|
|
1106
1177
|
const renderExpires = (v) => typeof v === "string" || typeof v === "number" ? new Date(v).toUTCString() : v.toUTCString();
|
|
1107
1178
|
const renderPragmaNoCache = (v) => v ? "no-cache" : "";
|
|
1179
|
+
/** Provides helpers to set cache-related response headers (Cache-Control, Expires, Age, Pragma). */
|
|
1108
1180
|
function useSetCacheControl() {
|
|
1109
1181
|
const { setHeader } = useSetHeaders();
|
|
1110
1182
|
const setAge = (value) => {
|
|
@@ -1129,6 +1201,14 @@ function useSetCacheControl() {
|
|
|
1129
1201
|
|
|
1130
1202
|
//#endregion
|
|
1131
1203
|
//#region packages/event-http/src/composables/response.ts
|
|
1204
|
+
/**
|
|
1205
|
+
* Provides access to the raw HTTP response and status code management.
|
|
1206
|
+
* @example
|
|
1207
|
+
* ```ts
|
|
1208
|
+
* const { status, rawResponse, hasResponded } = useResponse()
|
|
1209
|
+
* status(200)
|
|
1210
|
+
* ```
|
|
1211
|
+
*/
|
|
1132
1212
|
function useResponse() {
|
|
1133
1213
|
const { store } = useHttpContext();
|
|
1134
1214
|
const event = store("event");
|
|
@@ -1151,6 +1231,7 @@ function useResponse() {
|
|
|
1151
1231
|
})
|
|
1152
1232
|
};
|
|
1153
1233
|
}
|
|
1234
|
+
/** Returns a hookable accessor for the response status code. */
|
|
1154
1235
|
function useStatus() {
|
|
1155
1236
|
const { store } = useHttpContext();
|
|
1156
1237
|
return store("status").hook("code");
|
|
@@ -1158,6 +1239,11 @@ function useStatus() {
|
|
|
1158
1239
|
|
|
1159
1240
|
//#endregion
|
|
1160
1241
|
//#region packages/event-http/src/utils/url-search-params.ts
|
|
1242
|
+
const ILLEGAL_KEYS = new Set([
|
|
1243
|
+
"__proto__",
|
|
1244
|
+
"constructor",
|
|
1245
|
+
"prototype"
|
|
1246
|
+
]);
|
|
1161
1247
|
var WooksURLSearchParams = class extends url.URLSearchParams {
|
|
1162
1248
|
toJson() {
|
|
1163
1249
|
const json = Object.create(null);
|
|
@@ -1165,7 +1251,7 @@ var WooksURLSearchParams = class extends url.URLSearchParams {
|
|
|
1165
1251
|
const a = json[key] = json[key] || [];
|
|
1166
1252
|
a.push(value);
|
|
1167
1253
|
} else {
|
|
1168
|
-
if (key
|
|
1254
|
+
if (ILLEGAL_KEYS.has(key)) throw new HttpError(400, `Illegal key name "${key}"`);
|
|
1169
1255
|
if (key in json) throw new HttpError(400, `Duplicate key "${key}"`);
|
|
1170
1256
|
json[key] = value;
|
|
1171
1257
|
}
|
|
@@ -1178,6 +1264,14 @@ function isArrayParam(name) {
|
|
|
1178
1264
|
|
|
1179
1265
|
//#endregion
|
|
1180
1266
|
//#region packages/event-http/src/composables/search-params.ts
|
|
1267
|
+
/**
|
|
1268
|
+
* Provides access to URL search (query) parameters from the request.
|
|
1269
|
+
* @example
|
|
1270
|
+
* ```ts
|
|
1271
|
+
* const { urlSearchParams, jsonSearchParams } = useSearchParams()
|
|
1272
|
+
* const page = urlSearchParams().get('page')
|
|
1273
|
+
* ```
|
|
1274
|
+
*/
|
|
1181
1275
|
function useSearchParams() {
|
|
1182
1276
|
const { store } = useHttpContext();
|
|
1183
1277
|
const url$1 = useRequest().url || "";
|
|
@@ -1352,7 +1446,7 @@ var BaseHttpResponse = class {
|
|
|
1352
1446
|
async function respondWithFetch(fetchBody, res) {
|
|
1353
1447
|
if (fetchBody) try {
|
|
1354
1448
|
for await (const chunk of fetchBody) res.write(chunk);
|
|
1355
|
-
} catch
|
|
1449
|
+
} catch {}
|
|
1356
1450
|
res.end();
|
|
1357
1451
|
}
|
|
1358
1452
|
|
|
@@ -1380,6 +1474,7 @@ function createWooksResponder(renderer = new BaseHttpResponseRenderer(), errorRe
|
|
|
1380
1474
|
|
|
1381
1475
|
//#endregion
|
|
1382
1476
|
//#region packages/event-http/src/http-adapter.ts
|
|
1477
|
+
/** HTTP adapter for Wooks that provides route registration, server lifecycle, and request handling. */
|
|
1383
1478
|
var WooksHttp = class extends wooks.WooksAdapterBase {
|
|
1384
1479
|
logger;
|
|
1385
1480
|
constructor(opts, wooks$1) {
|
|
@@ -1387,27 +1482,35 @@ var WooksHttp = class extends wooks.WooksAdapterBase {
|
|
|
1387
1482
|
this.opts = opts;
|
|
1388
1483
|
this.logger = opts?.logger || this.getLogger(`[96m[wooks-http]`);
|
|
1389
1484
|
}
|
|
1485
|
+
/** Registers a handler for all HTTP methods on the given path. */
|
|
1390
1486
|
all(path, handler) {
|
|
1391
1487
|
return this.on("*", path, handler);
|
|
1392
1488
|
}
|
|
1489
|
+
/** Registers a GET route handler. */
|
|
1393
1490
|
get(path, handler) {
|
|
1394
1491
|
return this.on("GET", path, handler);
|
|
1395
1492
|
}
|
|
1493
|
+
/** Registers a POST route handler. */
|
|
1396
1494
|
post(path, handler) {
|
|
1397
1495
|
return this.on("POST", path, handler);
|
|
1398
1496
|
}
|
|
1497
|
+
/** Registers a PUT route handler. */
|
|
1399
1498
|
put(path, handler) {
|
|
1400
1499
|
return this.on("PUT", path, handler);
|
|
1401
1500
|
}
|
|
1501
|
+
/** Registers a PATCH route handler. */
|
|
1402
1502
|
patch(path, handler) {
|
|
1403
1503
|
return this.on("PATCH", path, handler);
|
|
1404
1504
|
}
|
|
1505
|
+
/** Registers a DELETE route handler. */
|
|
1405
1506
|
delete(path, handler) {
|
|
1406
1507
|
return this.on("DELETE", path, handler);
|
|
1407
1508
|
}
|
|
1509
|
+
/** Registers a HEAD route handler. */
|
|
1408
1510
|
head(path, handler) {
|
|
1409
1511
|
return this.on("HEAD", path, handler);
|
|
1410
1512
|
}
|
|
1513
|
+
/** Registers an OPTIONS route handler. */
|
|
1411
1514
|
options(path, handler) {
|
|
1412
1515
|
return this.on("OPTIONS", path, handler);
|
|
1413
1516
|
}
|
|
@@ -1465,8 +1568,8 @@ var WooksHttp = class extends wooks.WooksAdapterBase {
|
|
|
1465
1568
|
}
|
|
1466
1569
|
responder = createWooksResponder();
|
|
1467
1570
|
respond(data) {
|
|
1468
|
-
this.responder.respond(data)?.catch((
|
|
1469
|
-
this.logger.error("Uncaught response exception",
|
|
1571
|
+
this.responder.respond(data)?.catch((error) => {
|
|
1572
|
+
this.logger.error("Uncaught response exception", error);
|
|
1470
1573
|
});
|
|
1471
1574
|
}
|
|
1472
1575
|
/**
|
|
@@ -1485,7 +1588,8 @@ var WooksHttp = class extends wooks.WooksAdapterBase {
|
|
|
1485
1588
|
return (req, res) => {
|
|
1486
1589
|
const runInContext = createHttpContext({
|
|
1487
1590
|
req,
|
|
1488
|
-
res
|
|
1591
|
+
res,
|
|
1592
|
+
requestLimits: this.opts?.requestLimits
|
|
1489
1593
|
}, this.mergeEventOptions(this.opts?.eventOptions));
|
|
1490
1594
|
runInContext(async () => {
|
|
1491
1595
|
const { handlers } = this.wooks.lookup(req.method, req.url);
|
|
@@ -1525,10 +1629,13 @@ var WooksHttp = class extends wooks.WooksAdapterBase {
|
|
|
1525
1629
|
}
|
|
1526
1630
|
};
|
|
1527
1631
|
/**
|
|
1528
|
-
*
|
|
1529
|
-
* @
|
|
1530
|
-
*
|
|
1531
|
-
*
|
|
1632
|
+
* Creates a new WooksHttp application instance.
|
|
1633
|
+
* @example
|
|
1634
|
+
* ```ts
|
|
1635
|
+
* const app = createHttpApp()
|
|
1636
|
+
* app.get('/hello', () => 'Hello World!')
|
|
1637
|
+
* app.listen(3000)
|
|
1638
|
+
* ```
|
|
1532
1639
|
*/
|
|
1533
1640
|
function createHttpApp(opts, wooks$1) {
|
|
1534
1641
|
return new WooksHttp(opts, wooks$1);
|