@wooksjs/event-http 0.4.9 → 0.4.11

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.
Files changed (3) hide show
  1. package/dist/index.cjs +1009 -1055
  2. package/dist/index.mjs +1009 -1055
  3. package/package.json +3 -3
package/dist/index.mjs CHANGED
@@ -4,1102 +4,1056 @@ import { Readable } from 'stream';
4
4
  import { WooksAdapterBase } from 'wooks';
5
5
  import http from 'http';
6
6
 
7
- function createHttpContext(data, options) {
8
- return createEventContext({
9
- event: Object.assign(Object.assign({}, data), { type: 'HTTP' }),
10
- options,
11
- });
12
- }
13
- /**
14
- * Wrapper on useEventContext with HTTP event types
15
- * @returns set of hooks { getCtx, restoreCtx, clearCtx, hookStore, getStore, setStore }
16
- */
17
- function useHttpContext() {
18
- return useEventContext('HTTP');
7
+ function createHttpContext(data, options) {
8
+ return createEventContext({
9
+ event: {
10
+ ...data,
11
+ type: 'HTTP',
12
+ },
13
+ options,
14
+ });
15
+ }
16
+ /**
17
+ * Wrapper on useEventContext with HTTP event types
18
+ * @returns set of hooks { getCtx, restoreCtx, clearCtx, hookStore, getStore, setStore }
19
+ */
20
+ function useHttpContext() {
21
+ return useEventContext('HTTP');
19
22
  }
20
23
 
21
- const xForwardedFor = 'x-forwarded-for';
22
- function useRequest() {
23
- const { store } = useHttpContext();
24
- const { init } = store('request');
25
- const event = store('event');
26
- const { req } = event.value;
27
- const rawBody = () => init('rawBody', () => {
28
- return new Promise((resolve, reject) => {
29
- let body = Buffer.from('');
30
- req.on('data', function (chunk) {
31
- body = Buffer.concat([body, chunk]);
32
- });
33
- req.on('error', function (err) {
34
- reject(err);
35
- });
36
- req.on('end', function () {
37
- resolve(body);
38
- });
39
- });
40
- });
41
- const reqId = useEventId().getId;
42
- const forwardedIp = () => init('forwardedIp', () => {
43
- var _a;
44
- if (typeof req.headers[xForwardedFor] === 'string' &&
45
- req.headers[xForwardedFor]) {
46
- return (_a = req.headers[xForwardedFor]
47
- .split(',')
48
- .shift()) === null || _a === void 0 ? void 0 : _a.trim();
49
- }
50
- else {
51
- return '';
52
- }
53
- });
54
- const remoteIp = () => init('remoteIp', () => { var _a, _b; return ((_a = req.socket) === null || _a === void 0 ? void 0 : _a.remoteAddress) || ((_b = req.connection) === null || _b === void 0 ? void 0 : _b.remoteAddress) || ''; });
55
- function getIp(options) {
56
- if (options === null || options === void 0 ? void 0 : options.trustProxy) {
57
- return forwardedIp() || getIp();
58
- }
59
- else {
60
- return remoteIp();
61
- }
62
- }
63
- const getIpList = () => init('ipList', () => {
64
- var _a, _b;
65
- return {
66
- remoteIp: ((_a = req.socket) === null || _a === void 0 ? void 0 : _a.remoteAddress) ||
67
- ((_b = req.connection) === null || _b === void 0 ? void 0 : _b.remoteAddress) ||
68
- '',
69
- forwarded: (req.headers[xForwardedFor] || '')
70
- .split(',')
71
- .map((s) => s.trim()),
72
- };
73
- });
74
- return {
75
- rawRequest: req,
76
- url: req.url,
77
- method: req.method,
78
- headers: req.headers,
79
- rawBody,
80
- reqId,
81
- getIp,
82
- getIpList,
83
- };
24
+ const xForwardedFor = 'x-forwarded-for';
25
+ function useRequest() {
26
+ const { store } = useHttpContext();
27
+ const { init } = store('request');
28
+ const event = store('event');
29
+ const { req } = event.value;
30
+ const rawBody = () => init('rawBody', () => {
31
+ return new Promise((resolve, reject) => {
32
+ let body = Buffer.from('');
33
+ req.on('data', function (chunk) {
34
+ body = Buffer.concat([body, chunk]);
35
+ });
36
+ req.on('error', function (err) {
37
+ reject(err);
38
+ });
39
+ req.on('end', function () {
40
+ resolve(body);
41
+ });
42
+ });
43
+ });
44
+ const reqId = useEventId().getId;
45
+ const forwardedIp = () => init('forwardedIp', () => {
46
+ if (typeof req.headers[xForwardedFor] === 'string' &&
47
+ req.headers[xForwardedFor]) {
48
+ return req.headers[xForwardedFor]
49
+ .split(',')
50
+ .shift()
51
+ ?.trim();
52
+ }
53
+ else {
54
+ return '';
55
+ }
56
+ });
57
+ const remoteIp = () => init('remoteIp', () => req.socket?.remoteAddress || req.connection?.remoteAddress || '');
58
+ function getIp(options) {
59
+ if (options?.trustProxy) {
60
+ return forwardedIp() || getIp();
61
+ }
62
+ else {
63
+ return remoteIp();
64
+ }
65
+ }
66
+ const getIpList = () => init('ipList', () => {
67
+ return {
68
+ remoteIp: req.socket?.remoteAddress ||
69
+ req.connection?.remoteAddress ||
70
+ '',
71
+ forwarded: (req.headers[xForwardedFor] || '')
72
+ .split(',')
73
+ .map((s) => s.trim()),
74
+ };
75
+ });
76
+ return {
77
+ rawRequest: req,
78
+ url: req.url,
79
+ method: req.method,
80
+ headers: req.headers,
81
+ rawBody,
82
+ reqId,
83
+ getIp,
84
+ getIpList,
85
+ };
84
86
  }
85
87
 
86
- function useHeaders() {
87
- return useRequest().headers;
88
- }
89
- function useSetHeaders() {
90
- const { store } = useHttpContext();
91
- const setHeaderStore = store('setHeader');
92
- function setHeader(name, value) {
93
- setHeaderStore.set(name, value.toString());
94
- }
95
- function setContentType(value) {
96
- setHeader('content-type', value);
97
- }
98
- function enableCors(origin = '*') {
99
- setHeader('access-control-allow-origin', origin);
100
- }
101
- return {
102
- setHeader,
103
- getHeader: setHeaderStore.get,
104
- removeHeader: setHeaderStore.del,
105
- setContentType,
106
- headers: () => setHeaderStore.value || {},
107
- enableCors,
108
- };
109
- }
110
- function useSetHeader(name) {
111
- const { store } = useHttpContext();
112
- const { hook } = store('setHeader');
113
- return hook(name);
88
+ function useHeaders() {
89
+ return useRequest().headers;
90
+ }
91
+ function useSetHeaders() {
92
+ const { store } = useHttpContext();
93
+ const setHeaderStore = store('setHeader');
94
+ function setHeader(name, value) {
95
+ setHeaderStore.set(name, value.toString());
96
+ }
97
+ function setContentType(value) {
98
+ setHeader('content-type', value);
99
+ }
100
+ function enableCors(origin = '*') {
101
+ setHeader('access-control-allow-origin', origin);
102
+ }
103
+ return {
104
+ setHeader,
105
+ getHeader: setHeaderStore.get,
106
+ removeHeader: setHeaderStore.del,
107
+ setContentType,
108
+ headers: () => setHeaderStore.value || {},
109
+ enableCors,
110
+ };
111
+ }
112
+ function useSetHeader(name) {
113
+ const { store } = useHttpContext();
114
+ const { hook } = store('setHeader');
115
+ return hook(name);
114
116
  }
115
117
 
116
- function useAccept() {
117
- const { store } = useHttpContext();
118
- const { accept } = useHeaders();
119
- const accepts = (mime) => {
120
- const { set, get, has } = store('accept');
121
- if (!has(mime)) {
122
- return set(mime, !!(accept && (accept === '*/*' || accept.indexOf(mime) >= 0)));
123
- }
124
- return get(mime);
125
- };
126
- return {
127
- accept,
128
- accepts,
129
- acceptsJson: () => accepts('application/json'),
130
- acceptsXml: () => accepts('application/xml'),
131
- acceptsText: () => accepts('text/plain'),
132
- acceptsHtml: () => accepts('text/html'),
133
- };
118
+ function useAccept() {
119
+ const { store } = useHttpContext();
120
+ const { accept } = useHeaders();
121
+ const accepts = (mime) => {
122
+ const { set, get, has } = store('accept');
123
+ if (!has(mime)) {
124
+ return set(mime, !!(accept && (accept === '*/*' || accept.indexOf(mime) >= 0)));
125
+ }
126
+ return get(mime);
127
+ };
128
+ return {
129
+ accept,
130
+ accepts,
131
+ acceptsJson: () => accepts('application/json'),
132
+ acceptsXml: () => accepts('application/xml'),
133
+ acceptsText: () => accepts('text/plain'),
134
+ acceptsHtml: () => accepts('text/html'),
135
+ };
134
136
  }
135
137
 
136
- function useAuthorization() {
137
- const { store } = useHttpContext();
138
- const { authorization } = useHeaders();
139
- const { init } = store('authorization');
140
- const authType = () => init('type', () => {
141
- if (authorization) {
142
- const space = authorization.indexOf(' ');
143
- return authorization.slice(0, space);
144
- }
145
- return null;
146
- });
147
- const authRawCredentials = () => init('credentials', () => {
148
- if (authorization) {
149
- const space = authorization.indexOf(' ');
150
- return authorization.slice(space + 1);
151
- }
152
- return null;
153
- });
154
- return {
155
- authorization,
156
- authType,
157
- authRawCredentials,
158
- isBasic: () => { var _a; return ((_a = authType()) === null || _a === void 0 ? void 0 : _a.toLocaleLowerCase()) === 'basic'; },
159
- isBearer: () => { var _a; return ((_a = authType()) === null || _a === void 0 ? void 0 : _a.toLocaleLowerCase()) === 'bearer'; },
160
- basicCredentials: () => init('basicCredentials', () => {
161
- if (authorization) {
162
- const type = authType();
163
- if ((type === null || type === void 0 ? void 0 : type.toLocaleLowerCase()) === 'basic') {
164
- const creds = Buffer.from(authRawCredentials() || '', 'base64').toString('ascii');
165
- const [username, password] = creds.split(':');
166
- return { username, password };
167
- }
168
- }
169
- return null;
170
- }),
171
- };
138
+ function useAuthorization() {
139
+ const { store } = useHttpContext();
140
+ const { authorization } = useHeaders();
141
+ const { init } = store('authorization');
142
+ const authType = () => init('type', () => {
143
+ if (authorization) {
144
+ const space = authorization.indexOf(' ');
145
+ return authorization.slice(0, space);
146
+ }
147
+ return null;
148
+ });
149
+ const authRawCredentials = () => init('credentials', () => {
150
+ if (authorization) {
151
+ const space = authorization.indexOf(' ');
152
+ return authorization.slice(space + 1);
153
+ }
154
+ return null;
155
+ });
156
+ return {
157
+ authorization,
158
+ authType,
159
+ authRawCredentials,
160
+ isBasic: () => authType()?.toLocaleLowerCase() === 'basic',
161
+ isBearer: () => authType()?.toLocaleLowerCase() === 'bearer',
162
+ basicCredentials: () => init('basicCredentials', () => {
163
+ if (authorization) {
164
+ const type = authType();
165
+ if (type?.toLocaleLowerCase() === 'basic') {
166
+ const creds = Buffer.from(authRawCredentials() || '', 'base64').toString('ascii');
167
+ const [username, password] = creds.split(':');
168
+ return { username, password };
169
+ }
170
+ }
171
+ return null;
172
+ }),
173
+ };
172
174
  }
173
175
 
174
- function convertTime(time, unit = 'ms') {
175
- if (typeof time === 'number')
176
- return time / units[unit];
177
- const rg = /(\d+)(\w+)/g;
178
- let t = 0;
179
- let r;
180
- while ((r = rg.exec(time))) {
181
- t += Number(r[1]) * (units[r[2]] || 0);
182
- }
183
- return t / units[unit];
184
- }
185
- const units = {
186
- ms: 1,
187
- s: 1000,
188
- m: 1000 * 60,
189
- h: 1000 * 60 * 60,
190
- d: 1000 * 60 * 60 * 24,
191
- w: 1000 * 60 * 60 * 24 * 7,
192
- M: 1000 * 60 * 60 * 24 * 30,
193
- Y: 1000 * 60 * 60 * 24 * 365,
176
+ function convertTime(time, unit = 'ms') {
177
+ if (typeof time === 'number')
178
+ return time / units[unit];
179
+ const rg = /(\d+)(\w+)/g;
180
+ let t = 0;
181
+ let r;
182
+ while ((r = rg.exec(time))) {
183
+ t += Number(r[1]) * (units[r[2]] || 0);
184
+ }
185
+ return t / units[unit];
186
+ }
187
+ const units = {
188
+ ms: 1,
189
+ s: 1000,
190
+ m: 1000 * 60,
191
+ h: 1000 * 60 * 60,
192
+ d: 1000 * 60 * 60 * 24,
193
+ w: 1000 * 60 * 60 * 24 * 7,
194
+ M: 1000 * 60 * 60 * 24 * 30,
195
+ Y: 1000 * 60 * 60 * 24 * 365,
194
196
  };
195
197
 
196
- function renderCacheControl(data) {
197
- let attrs = '';
198
- for (const [a, v] of Object.entries(data)) {
199
- if (typeof v === 'undefined')
200
- continue;
201
- const func = cacheControlFunc[a];
202
- if (typeof func === 'function') {
203
- const val = func(v);
204
- if (val) {
205
- attrs += attrs ? ', ' + val : val;
206
- }
207
- }
208
- else {
209
- throw new Error('Unknown Cache-Control attribute ' + a);
210
- }
211
- }
212
- return attrs;
213
- }
214
- // rfc7234#section-5.2.2
215
- const cacheControlFunc = {
216
- mustRevalidate: (v) => v ? 'must-revalidate' : '',
217
- noCache: (v) => v ? (typeof v === 'string' ? `no-cache="${v}"` : 'no-cache') : '',
218
- noStore: (v) => (v ? 'no-store' : ''),
219
- noTransform: (v) => (v ? 'no-transform' : ''),
220
- public: (v) => (v ? 'public' : ''),
221
- private: (v) => v ? (typeof v === 'string' ? `private="${v}"` : 'private') : '',
222
- proxyRevalidate: (v) => v ? 'proxy-revalidate' : '',
223
- maxAge: (v) => 'max-age=' + convertTime(v, 's').toString(),
224
- sMaxage: (v) => 's-maxage=' + convertTime(v, 's').toString(),
198
+ function renderCacheControl(data) {
199
+ let attrs = '';
200
+ for (const [a, v] of Object.entries(data)) {
201
+ if (typeof v === 'undefined')
202
+ continue;
203
+ const func = cacheControlFunc[a];
204
+ if (typeof func === 'function') {
205
+ const val = func(v);
206
+ if (val) {
207
+ attrs += attrs ? ', ' + val : val;
208
+ }
209
+ }
210
+ else {
211
+ throw new Error('Unknown Cache-Control attribute ' + a);
212
+ }
213
+ }
214
+ return attrs;
215
+ }
216
+ // rfc7234#section-5.2.2
217
+ const cacheControlFunc = {
218
+ mustRevalidate: (v) => v ? 'must-revalidate' : '',
219
+ noCache: (v) => v ? (typeof v === 'string' ? `no-cache="${v}"` : 'no-cache') : '',
220
+ noStore: (v) => (v ? 'no-store' : ''),
221
+ noTransform: (v) => (v ? 'no-transform' : ''),
222
+ public: (v) => (v ? 'public' : ''),
223
+ private: (v) => v ? (typeof v === 'string' ? `private="${v}"` : 'private') : '',
224
+ proxyRevalidate: (v) => v ? 'proxy-revalidate' : '',
225
+ maxAge: (v) => 'max-age=' + convertTime(v, 's').toString(),
226
+ sMaxage: (v) => 's-maxage=' + convertTime(v, 's').toString(),
225
227
  };
226
228
 
227
- const renderAge = (v) => convertTime(v, 's').toString();
228
- const renderExpires = (v) => typeof v === 'string' || typeof v === 'number'
229
- ? new Date(v).toUTCString()
230
- : v.toUTCString();
231
- const renderPragmaNoCache = (v) => (v ? 'no-cache' : '');
232
- // rfc7234#section-5.2.2
233
- function useSetCacheControl() {
234
- const { setHeader } = useSetHeaders();
235
- const setAge = (value) => {
236
- setHeader('age', renderAge(value));
237
- };
238
- const setExpires = (value) => {
239
- setHeader('expires', renderExpires(value));
240
- };
241
- const setPragmaNoCache = (value = true) => {
242
- setHeader('pragma', renderPragmaNoCache(value));
243
- };
244
- const setCacheControl = (data) => {
245
- setHeader('cache-control', renderCacheControl(data));
246
- };
247
- return {
248
- setExpires,
249
- setAge,
250
- setPragmaNoCache,
251
- setCacheControl,
252
- };
229
+ const renderAge = (v) => convertTime(v, 's').toString();
230
+ const renderExpires = (v) => typeof v === 'string' || typeof v === 'number'
231
+ ? new Date(v).toUTCString()
232
+ : v.toUTCString();
233
+ const renderPragmaNoCache = (v) => (v ? 'no-cache' : '');
234
+ // rfc7234#section-5.2.2
235
+ function useSetCacheControl() {
236
+ const { setHeader } = useSetHeaders();
237
+ const setAge = (value) => {
238
+ setHeader('age', renderAge(value));
239
+ };
240
+ const setExpires = (value) => {
241
+ setHeader('expires', renderExpires(value));
242
+ };
243
+ const setPragmaNoCache = (value = true) => {
244
+ setHeader('pragma', renderPragmaNoCache(value));
245
+ };
246
+ const setCacheControl = (data) => {
247
+ setHeader('cache-control', renderCacheControl(data));
248
+ };
249
+ return {
250
+ setExpires,
251
+ setAge,
252
+ setPragmaNoCache,
253
+ setCacheControl,
254
+ };
253
255
  }
254
256
 
255
- function useResponse() {
256
- const { store } = useHttpContext();
257
- const event = store('event');
258
- const { res } = event.value;
259
- const responded = store('response').hook('responded');
260
- const statusCode = store('status').hook('code');
261
- function status(code) {
262
- return (statusCode.value = code ? code : statusCode.value);
263
- }
264
- const rawResponse = (options) => {
265
- if (!options || !options.passthrough)
266
- responded.value = true;
267
- return res;
268
- };
269
- return {
270
- rawResponse,
271
- hasResponded: () => responded.value || !res.writable || res.writableEnded,
272
- status: attachHook(status, {
273
- get: () => statusCode.value,
274
- set: (code) => (statusCode.value = code),
275
- }),
276
- };
277
- }
278
- function useStatus() {
279
- const { store } = useHttpContext();
280
- return store('status').hook('code');
257
+ function useResponse() {
258
+ const { store } = useHttpContext();
259
+ const event = store('event');
260
+ const { res } = event.value;
261
+ const responded = store('response').hook('responded');
262
+ const statusCode = store('status').hook('code');
263
+ function status(code) {
264
+ return (statusCode.value = code ? code : statusCode.value);
265
+ }
266
+ const rawResponse = (options) => {
267
+ if (!options || !options.passthrough)
268
+ responded.value = true;
269
+ return res;
270
+ };
271
+ return {
272
+ rawResponse,
273
+ hasResponded: () => responded.value || !res.writable || res.writableEnded,
274
+ status: attachHook(status, {
275
+ get: () => statusCode.value,
276
+ set: (code) => (statusCode.value = code),
277
+ }),
278
+ };
279
+ }
280
+ function useStatus() {
281
+ const { store } = useHttpContext();
282
+ return store('status').hook('code');
281
283
  }
282
284
 
283
- function renderCookie(key, data) {
284
- let attrs = '';
285
- for (const [a, v] of Object.entries(data.attrs)) {
286
- const func = cookieAttrFunc[a];
287
- if (typeof func === 'function') {
288
- const val = func(v);
289
- attrs += val ? '; ' + val : '';
290
- }
291
- else {
292
- throw new Error('Unknown Set-Cookie attribute ' + a);
293
- }
294
- }
295
- return `${key}=${encodeURIComponent(data.value)}${attrs}`;
296
- }
297
- const cookieAttrFunc = {
298
- expires: (v) => 'Expires=' +
299
- (typeof v === 'string' || typeof v === 'number'
300
- ? new Date(v).toUTCString()
301
- : v.toUTCString()),
302
- maxAge: (v) => 'Max-Age=' + convertTime(v, 's').toString(),
303
- domain: (v) => 'Domain=' + v,
304
- path: (v) => 'Path=' + v,
305
- secure: (v) => (v ? 'Secure' : ''),
306
- httpOnly: (v) => (v ? 'HttpOnly' : ''),
307
- sameSite: (v) => v ? 'SameSite=' + (typeof v === 'string' ? v : 'Strict') : '',
285
+ function renderCookie(key, data) {
286
+ let attrs = '';
287
+ for (const [a, v] of Object.entries(data.attrs)) {
288
+ const func = cookieAttrFunc[a];
289
+ if (typeof func === 'function') {
290
+ const val = func(v);
291
+ attrs += val ? '; ' + val : '';
292
+ }
293
+ else {
294
+ throw new Error('Unknown Set-Cookie attribute ' + a);
295
+ }
296
+ }
297
+ return `${key}=${encodeURIComponent(data.value)}${attrs}`;
298
+ }
299
+ const cookieAttrFunc = {
300
+ expires: (v) => 'Expires=' +
301
+ (typeof v === 'string' || typeof v === 'number'
302
+ ? new Date(v).toUTCString()
303
+ : v.toUTCString()),
304
+ maxAge: (v) => 'Max-Age=' + convertTime(v, 's').toString(),
305
+ domain: (v) => 'Domain=' + v,
306
+ path: (v) => 'Path=' + v,
307
+ secure: (v) => (v ? 'Secure' : ''),
308
+ httpOnly: (v) => (v ? 'HttpOnly' : ''),
309
+ sameSite: (v) => v ? 'SameSite=' + (typeof v === 'string' ? v : 'Strict') : '',
308
310
  };
309
311
 
310
- function escapeRegex(s) {
311
- return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
312
- }
313
- function safeDecode(f, v) {
314
- try {
315
- return f(v);
316
- }
317
- catch (e) {
318
- return v;
319
- }
320
- }
321
- function safeDecodeURIComponent(uri) {
322
- if (uri.indexOf('%') < 0)
323
- return uri;
324
- return safeDecode(decodeURIComponent, uri);
312
+ function escapeRegex(s) {
313
+ return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
325
314
  }
326
-
327
- function useCookies() {
328
- const { store } = useHttpContext();
329
- const { cookie } = useHeaders();
330
- const { init } = store('cookies');
331
- const getCookie = (name) => init(name, () => {
332
- if (cookie) {
333
- const result = new RegExp(`(?:^|; )${escapeRegex(name)}=(.*?)(?:;?$|; )`, 'i').exec(cookie);
334
- return result && result[1]
335
- ? safeDecodeURIComponent(result[1])
336
- : null;
337
- }
338
- else {
339
- return null;
340
- }
341
- });
342
- return {
343
- rawCookies: cookie,
344
- getCookie,
345
- };
346
- }
347
- function useSetCookies() {
348
- const { store } = useHttpContext();
349
- const cookiesStore = store('setCookies');
350
- function setCookie(name, value, attrs) {
351
- cookiesStore.set(name, {
352
- value,
353
- attrs: attrs || {},
354
- });
355
- }
356
- function cookies() {
357
- return cookiesStore
358
- .entries()
359
- .filter((a) => !!a[1])
360
- .map(([key, value]) => renderCookie(key, value));
361
- }
362
- return {
363
- setCookie,
364
- getCookie: cookiesStore.get,
365
- removeCookie: cookiesStore.del,
366
- clearCookies: cookiesStore.clear,
367
- cookies,
368
- };
369
- }
370
- function useSetCookie(name) {
371
- const { setCookie, getCookie } = useSetCookies();
372
- const valueHook = attachHook({
373
- name,
374
- type: 'cookie',
375
- }, {
376
- get: () => { var _a; return (_a = getCookie(name)) === null || _a === void 0 ? void 0 : _a.value; },
377
- set: (value) => { var _a; return setCookie(name, value, (_a = getCookie(name)) === null || _a === void 0 ? void 0 : _a.attrs); },
378
- });
379
- return attachHook(valueHook, {
380
- get: () => { var _a; return (_a = getCookie(name)) === null || _a === void 0 ? void 0 : _a.attrs; },
381
- set: (attrs) => { var _a; return setCookie(name, ((_a = getCookie(name)) === null || _a === void 0 ? void 0 : _a.value) || '', attrs); },
382
- }, 'attrs');
315
+ function safeDecode(f, v) {
316
+ try {
317
+ return f(v);
318
+ }
319
+ catch (e) {
320
+ return v;
321
+ }
322
+ }
323
+ function safeDecodeURIComponent(uri) {
324
+ if (uri.indexOf('%') < 0)
325
+ return uri;
326
+ return safeDecode(decodeURIComponent, uri);
383
327
  }
384
328
 
385
- class WooksURLSearchParams extends URLSearchParams {
386
- toJson() {
387
- const json = {};
388
- for (const [key, value] of this.entries()) {
389
- if (isArrayParam(key)) {
390
- const a = (json[key] = (json[key] || []));
391
- a.push(value);
392
- }
393
- else {
394
- json[key] = value;
395
- }
396
- }
397
- return json;
398
- }
399
- }
400
- function isArrayParam(name) {
401
- return name.endsWith('[]');
329
+ function useCookies() {
330
+ const { store } = useHttpContext();
331
+ const { cookie } = useHeaders();
332
+ const { init } = store('cookies');
333
+ const getCookie = (name) => init(name, () => {
334
+ if (cookie) {
335
+ const result = new RegExp(`(?:^|; )${escapeRegex(name)}=(.*?)(?:;?$|; )`, 'i').exec(cookie);
336
+ return result && result[1]
337
+ ? safeDecodeURIComponent(result[1])
338
+ : null;
339
+ }
340
+ else {
341
+ return null;
342
+ }
343
+ });
344
+ return {
345
+ rawCookies: cookie,
346
+ getCookie,
347
+ };
348
+ }
349
+ function useSetCookies() {
350
+ const { store } = useHttpContext();
351
+ const cookiesStore = store('setCookies');
352
+ function setCookie(name, value, attrs) {
353
+ cookiesStore.set(name, {
354
+ value,
355
+ attrs: attrs || {},
356
+ });
357
+ }
358
+ function cookies() {
359
+ return cookiesStore
360
+ .entries()
361
+ .filter((a) => !!a[1])
362
+ .map(([key, value]) => renderCookie(key, value));
363
+ }
364
+ return {
365
+ setCookie,
366
+ getCookie: cookiesStore.get,
367
+ removeCookie: cookiesStore.del,
368
+ clearCookies: cookiesStore.clear,
369
+ cookies,
370
+ };
371
+ }
372
+ function useSetCookie(name) {
373
+ const { setCookie, getCookie } = useSetCookies();
374
+ const valueHook = attachHook({
375
+ name,
376
+ type: 'cookie',
377
+ }, {
378
+ get: () => getCookie(name)?.value,
379
+ set: (value) => setCookie(name, value, getCookie(name)?.attrs),
380
+ });
381
+ return attachHook(valueHook, {
382
+ get: () => getCookie(name)?.attrs,
383
+ set: (attrs) => setCookie(name, getCookie(name)?.value || '', attrs),
384
+ }, 'attrs');
402
385
  }
403
386
 
404
- function useSearchParams() {
405
- const { store } = useHttpContext();
406
- const url = useRequest().url || '';
407
- const { init } = store('searchParams');
408
- const rawSearchParams = () => init('raw', () => {
409
- const i = url.indexOf('?');
410
- return i >= 0 ? url.slice(i) : '';
411
- });
412
- const urlSearchParams = () => init('urlSearchParams', () => new WooksURLSearchParams(rawSearchParams()));
413
- return {
414
- rawSearchParams,
415
- urlSearchParams,
416
- jsonSearchParams: () => urlSearchParams().toJson(),
417
- };
387
+ class WooksURLSearchParams extends URLSearchParams {
388
+ toJson() {
389
+ const json = {};
390
+ for (const [key, value] of this.entries()) {
391
+ if (isArrayParam(key)) {
392
+ const a = (json[key] = (json[key] || []));
393
+ a.push(value);
394
+ }
395
+ else {
396
+ json[key] = value;
397
+ }
398
+ }
399
+ return json;
400
+ }
401
+ }
402
+ function isArrayParam(name) {
403
+ return name.endsWith('[]');
418
404
  }
419
405
 
420
- /******************************************************************************
421
- Copyright (c) Microsoft Corporation.
422
-
423
- Permission to use, copy, modify, and/or distribute this software for any
424
- purpose with or without fee is hereby granted.
425
-
426
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
427
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
428
- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
429
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
430
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
431
- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
432
- PERFORMANCE OF THIS SOFTWARE.
433
- ***************************************************************************** */
434
-
435
- function __awaiter(thisArg, _arguments, P, generator) {
436
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
437
- return new (P || (P = Promise))(function (resolve, reject) {
438
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
439
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
440
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
441
- step((generator = generator.apply(thisArg, _arguments || [])).next());
442
- });
443
- }
444
-
445
- function __values(o) {
446
- var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
447
- if (m) return m.call(o);
448
- if (o && typeof o.length === "number") return {
449
- next: function () {
450
- if (o && i >= o.length) o = void 0;
451
- return { value: o && o[i++], done: !o };
452
- }
453
- };
454
- throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
455
- }
456
-
457
- function __asyncValues(o) {
458
- if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
459
- var m = o[Symbol.asyncIterator], i;
460
- return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
461
- function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
462
- function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
406
+ function useSearchParams() {
407
+ const { store } = useHttpContext();
408
+ const url = useRequest().url || '';
409
+ const { init } = store('searchParams');
410
+ const rawSearchParams = () => init('raw', () => {
411
+ const i = url.indexOf('?');
412
+ return i >= 0 ? url.slice(i) : '';
413
+ });
414
+ const urlSearchParams = () => init('urlSearchParams', () => new WooksURLSearchParams(rawSearchParams()));
415
+ return {
416
+ rawSearchParams,
417
+ urlSearchParams,
418
+ jsonSearchParams: () => urlSearchParams().toJson(),
419
+ };
463
420
  }
464
421
 
465
- class BaseHttpResponseRenderer {
466
- render(response) {
467
- if (typeof response.body === 'string' ||
468
- typeof response.body === 'boolean' ||
469
- typeof response.body === 'number') {
470
- if (!response.getContentType())
471
- response.setContentType('text/plain');
472
- return response.body.toString();
473
- }
474
- if (typeof response.body === 'undefined') {
475
- return '';
476
- }
477
- if (response.body instanceof Uint8Array) {
478
- return response.body;
479
- }
480
- if (typeof response.body === 'object') {
481
- if (!response.getContentType())
482
- response.setContentType('application/json');
483
- return JSON.stringify(response.body);
484
- }
485
- throw new Error('Unsupported body format "' + typeof response.body + '"');
486
- }
422
+ class BaseHttpResponseRenderer {
423
+ render(response) {
424
+ if (typeof response.body === 'string' ||
425
+ typeof response.body === 'boolean' ||
426
+ typeof response.body === 'number') {
427
+ if (!response.getContentType())
428
+ response.setContentType('text/plain');
429
+ return response.body.toString();
430
+ }
431
+ if (typeof response.body === 'undefined') {
432
+ return '';
433
+ }
434
+ if (response.body instanceof Uint8Array) {
435
+ return response.body;
436
+ }
437
+ if (typeof response.body === 'object') {
438
+ if (!response.getContentType())
439
+ response.setContentType('application/json');
440
+ return JSON.stringify(response.body);
441
+ }
442
+ throw new Error('Unsupported body format "' + typeof response.body + '"');
443
+ }
487
444
  }
488
445
 
489
- const httpStatusCodes = {
490
- [100]: 'Continue',
491
- [101]: 'Switching protocols',
492
- [102]: 'Processing',
493
- [103]: 'Early Hints',
494
- [200]: 'OK',
495
- [201]: 'Created',
496
- [202]: 'Accepted',
497
- [203]: 'Non-Authoritative Information',
498
- [204]: 'No Content',
499
- [205]: 'Reset Content',
500
- [206]: 'Partial Content',
501
- [207]: 'Multi-Status',
502
- [208]: 'Already Reported',
503
- [226]: 'IM Used',
504
- [300]: 'Multiple Choices',
505
- [301]: 'Moved Permanently',
506
- [302]: 'Found (Previously "Moved Temporarily")',
507
- [303]: 'See Other',
508
- [304]: 'Not Modified',
509
- [305]: 'Use Proxy',
510
- [306]: 'Switch Proxy',
511
- [307]: 'Temporary Redirect',
512
- [308]: 'Permanent Redirect',
513
- [400]: 'Bad Request',
514
- [401]: 'Unauthorized',
515
- [402]: 'Payment Required',
516
- [403]: 'Forbidden',
517
- [404]: 'Not Found',
518
- [405]: 'Method Not Allowed',
519
- [406]: 'Not Acceptable',
520
- [407]: 'Proxy Authentication Required',
521
- [408]: 'Request Timeout',
522
- [409]: 'Conflict',
523
- [410]: 'Gone',
524
- [411]: 'Length Required',
525
- [412]: 'Precondition Failed',
526
- [413]: 'Payload Too Large',
527
- [414]: 'URI Too Long',
528
- [415]: 'Unsupported Media Type',
529
- [416]: 'Range Not Satisfiable',
530
- [417]: 'Expectation Failed',
531
- [418]: 'I\'m a Teapot',
532
- [421]: 'Misdirected Request',
533
- [422]: 'Unprocessable Entity',
534
- [423]: 'Locked',
535
- [424]: 'Failed Dependency',
536
- [425]: 'Too Early',
537
- [426]: 'Upgrade Required',
538
- [428]: 'Precondition Required',
539
- [429]: 'Too Many Requests',
540
- [431]: 'Request Header Fields Too Large',
541
- [451]: 'Unavailable For Legal Reasons',
542
- [500]: 'Internal Server Error',
543
- [501]: 'Not Implemented',
544
- [502]: 'Bad Gateway',
545
- [503]: 'Service Unavailable',
546
- [504]: 'Gateway Timeout',
547
- [505]: 'HTTP Version Not Supported',
548
- [506]: 'Variant Also Negotiates',
549
- [507]: 'Insufficient Storage',
550
- [508]: 'Loop Detected',
551
- [510]: 'Not Extended',
552
- [511]: 'Network Authentication Required',
553
- };
554
- var EHttpStatusCode;
555
- (function (EHttpStatusCode) {
556
- EHttpStatusCode[EHttpStatusCode["Continue"] = 100] = "Continue";
557
- EHttpStatusCode[EHttpStatusCode["SwitchingProtocols"] = 101] = "SwitchingProtocols";
558
- EHttpStatusCode[EHttpStatusCode["Processing"] = 102] = "Processing";
559
- EHttpStatusCode[EHttpStatusCode["EarlyHints"] = 103] = "EarlyHints";
560
- EHttpStatusCode[EHttpStatusCode["OK"] = 200] = "OK";
561
- EHttpStatusCode[EHttpStatusCode["Created"] = 201] = "Created";
562
- EHttpStatusCode[EHttpStatusCode["Accepted"] = 202] = "Accepted";
563
- EHttpStatusCode[EHttpStatusCode["NonAuthoritativeInformation"] = 203] = "NonAuthoritativeInformation";
564
- EHttpStatusCode[EHttpStatusCode["NoContent"] = 204] = "NoContent";
565
- EHttpStatusCode[EHttpStatusCode["ResetContent"] = 205] = "ResetContent";
566
- EHttpStatusCode[EHttpStatusCode["PartialContent"] = 206] = "PartialContent";
567
- EHttpStatusCode[EHttpStatusCode["MultiStatus"] = 207] = "MultiStatus";
568
- EHttpStatusCode[EHttpStatusCode["AlreadyReported"] = 208] = "AlreadyReported";
569
- EHttpStatusCode[EHttpStatusCode["IMUsed"] = 226] = "IMUsed";
570
- EHttpStatusCode[EHttpStatusCode["MultipleChoices"] = 300] = "MultipleChoices";
571
- EHttpStatusCode[EHttpStatusCode["MovedPermanently"] = 301] = "MovedPermanently";
572
- EHttpStatusCode[EHttpStatusCode["Found"] = 302] = "Found";
573
- EHttpStatusCode[EHttpStatusCode["SeeOther"] = 303] = "SeeOther";
574
- EHttpStatusCode[EHttpStatusCode["NotModified"] = 304] = "NotModified";
575
- EHttpStatusCode[EHttpStatusCode["UseProxy"] = 305] = "UseProxy";
576
- EHttpStatusCode[EHttpStatusCode["SwitchProxy"] = 306] = "SwitchProxy";
577
- EHttpStatusCode[EHttpStatusCode["TemporaryRedirect"] = 307] = "TemporaryRedirect";
578
- EHttpStatusCode[EHttpStatusCode["PermanentRedirect"] = 308] = "PermanentRedirect";
579
- EHttpStatusCode[EHttpStatusCode["BadRequest"] = 400] = "BadRequest";
580
- EHttpStatusCode[EHttpStatusCode["Unauthorized"] = 401] = "Unauthorized";
581
- EHttpStatusCode[EHttpStatusCode["PaymentRequired"] = 402] = "PaymentRequired";
582
- EHttpStatusCode[EHttpStatusCode["Forbidden"] = 403] = "Forbidden";
583
- EHttpStatusCode[EHttpStatusCode["NotFound"] = 404] = "NotFound";
584
- EHttpStatusCode[EHttpStatusCode["MethodNotAllowed"] = 405] = "MethodNotAllowed";
585
- EHttpStatusCode[EHttpStatusCode["NotAcceptable"] = 406] = "NotAcceptable";
586
- EHttpStatusCode[EHttpStatusCode["ProxyAuthenticationRequired"] = 407] = "ProxyAuthenticationRequired";
587
- EHttpStatusCode[EHttpStatusCode["RequestTimeout"] = 408] = "RequestTimeout";
588
- EHttpStatusCode[EHttpStatusCode["Conflict"] = 409] = "Conflict";
589
- EHttpStatusCode[EHttpStatusCode["Gone"] = 410] = "Gone";
590
- EHttpStatusCode[EHttpStatusCode["LengthRequired"] = 411] = "LengthRequired";
591
- EHttpStatusCode[EHttpStatusCode["PreconditionFailed"] = 412] = "PreconditionFailed";
592
- EHttpStatusCode[EHttpStatusCode["PayloadTooLarge"] = 413] = "PayloadTooLarge";
593
- EHttpStatusCode[EHttpStatusCode["URITooLong"] = 414] = "URITooLong";
594
- EHttpStatusCode[EHttpStatusCode["UnsupportedMediaType"] = 415] = "UnsupportedMediaType";
595
- EHttpStatusCode[EHttpStatusCode["RangeNotSatisfiable"] = 416] = "RangeNotSatisfiable";
596
- EHttpStatusCode[EHttpStatusCode["ExpectationFailed"] = 417] = "ExpectationFailed";
597
- EHttpStatusCode[EHttpStatusCode["ImATeapot"] = 418] = "ImATeapot";
598
- EHttpStatusCode[EHttpStatusCode["MisdirectedRequest"] = 421] = "MisdirectedRequest";
599
- EHttpStatusCode[EHttpStatusCode["UnprocessableEntity"] = 422] = "UnprocessableEntity";
600
- EHttpStatusCode[EHttpStatusCode["Locked"] = 423] = "Locked";
601
- EHttpStatusCode[EHttpStatusCode["FailedDependency"] = 424] = "FailedDependency";
602
- EHttpStatusCode[EHttpStatusCode["TooEarly"] = 425] = "TooEarly";
603
- EHttpStatusCode[EHttpStatusCode["UpgradeRequired"] = 426] = "UpgradeRequired";
604
- EHttpStatusCode[EHttpStatusCode["PreconditionRequired"] = 428] = "PreconditionRequired";
605
- EHttpStatusCode[EHttpStatusCode["TooManyRequests"] = 429] = "TooManyRequests";
606
- EHttpStatusCode[EHttpStatusCode["RequestHeaderFieldsTooLarge"] = 431] = "RequestHeaderFieldsTooLarge";
607
- EHttpStatusCode[EHttpStatusCode["UnavailableForLegalReasons"] = 451] = "UnavailableForLegalReasons";
608
- EHttpStatusCode[EHttpStatusCode["InternalServerError"] = 500] = "InternalServerError";
609
- EHttpStatusCode[EHttpStatusCode["NotImplemented"] = 501] = "NotImplemented";
610
- EHttpStatusCode[EHttpStatusCode["BadGateway"] = 502] = "BadGateway";
611
- EHttpStatusCode[EHttpStatusCode["ServiceUnavailable"] = 503] = "ServiceUnavailable";
612
- EHttpStatusCode[EHttpStatusCode["GatewayTimeout"] = 504] = "GatewayTimeout";
613
- EHttpStatusCode[EHttpStatusCode["HTTPVersionNotSupported"] = 505] = "HTTPVersionNotSupported";
614
- EHttpStatusCode[EHttpStatusCode["VariantAlsoNegotiates"] = 506] = "VariantAlsoNegotiates";
615
- EHttpStatusCode[EHttpStatusCode["InsufficientStorage"] = 507] = "InsufficientStorage";
616
- EHttpStatusCode[EHttpStatusCode["LoopDetected"] = 508] = "LoopDetected";
617
- EHttpStatusCode[EHttpStatusCode["NotExtended"] = 510] = "NotExtended";
618
- EHttpStatusCode[EHttpStatusCode["NetworkAuthenticationRequired"] = 511] = "NetworkAuthenticationRequired";
446
+ const httpStatusCodes = {
447
+ [100]: 'Continue',
448
+ [101]: 'Switching protocols',
449
+ [102]: 'Processing',
450
+ [103]: 'Early Hints',
451
+ [200]: 'OK',
452
+ [201]: 'Created',
453
+ [202]: 'Accepted',
454
+ [203]: 'Non-Authoritative Information',
455
+ [204]: 'No Content',
456
+ [205]: 'Reset Content',
457
+ [206]: 'Partial Content',
458
+ [207]: 'Multi-Status',
459
+ [208]: 'Already Reported',
460
+ [226]: 'IM Used',
461
+ [300]: 'Multiple Choices',
462
+ [301]: 'Moved Permanently',
463
+ [302]: 'Found (Previously "Moved Temporarily")',
464
+ [303]: 'See Other',
465
+ [304]: 'Not Modified',
466
+ [305]: 'Use Proxy',
467
+ [306]: 'Switch Proxy',
468
+ [307]: 'Temporary Redirect',
469
+ [308]: 'Permanent Redirect',
470
+ [400]: 'Bad Request',
471
+ [401]: 'Unauthorized',
472
+ [402]: 'Payment Required',
473
+ [403]: 'Forbidden',
474
+ [404]: 'Not Found',
475
+ [405]: 'Method Not Allowed',
476
+ [406]: 'Not Acceptable',
477
+ [407]: 'Proxy Authentication Required',
478
+ [408]: 'Request Timeout',
479
+ [409]: 'Conflict',
480
+ [410]: 'Gone',
481
+ [411]: 'Length Required',
482
+ [412]: 'Precondition Failed',
483
+ [413]: 'Payload Too Large',
484
+ [414]: 'URI Too Long',
485
+ [415]: 'Unsupported Media Type',
486
+ [416]: 'Range Not Satisfiable',
487
+ [417]: 'Expectation Failed',
488
+ [418]: 'I\'m a Teapot',
489
+ [421]: 'Misdirected Request',
490
+ [422]: 'Unprocessable Entity',
491
+ [423]: 'Locked',
492
+ [424]: 'Failed Dependency',
493
+ [425]: 'Too Early',
494
+ [426]: 'Upgrade Required',
495
+ [428]: 'Precondition Required',
496
+ [429]: 'Too Many Requests',
497
+ [431]: 'Request Header Fields Too Large',
498
+ [451]: 'Unavailable For Legal Reasons',
499
+ [500]: 'Internal Server Error',
500
+ [501]: 'Not Implemented',
501
+ [502]: 'Bad Gateway',
502
+ [503]: 'Service Unavailable',
503
+ [504]: 'Gateway Timeout',
504
+ [505]: 'HTTP Version Not Supported',
505
+ [506]: 'Variant Also Negotiates',
506
+ [507]: 'Insufficient Storage',
507
+ [508]: 'Loop Detected',
508
+ [510]: 'Not Extended',
509
+ [511]: 'Network Authentication Required',
510
+ };
511
+ var EHttpStatusCode;
512
+ (function (EHttpStatusCode) {
513
+ EHttpStatusCode[EHttpStatusCode["Continue"] = 100] = "Continue";
514
+ EHttpStatusCode[EHttpStatusCode["SwitchingProtocols"] = 101] = "SwitchingProtocols";
515
+ EHttpStatusCode[EHttpStatusCode["Processing"] = 102] = "Processing";
516
+ EHttpStatusCode[EHttpStatusCode["EarlyHints"] = 103] = "EarlyHints";
517
+ EHttpStatusCode[EHttpStatusCode["OK"] = 200] = "OK";
518
+ EHttpStatusCode[EHttpStatusCode["Created"] = 201] = "Created";
519
+ EHttpStatusCode[EHttpStatusCode["Accepted"] = 202] = "Accepted";
520
+ EHttpStatusCode[EHttpStatusCode["NonAuthoritativeInformation"] = 203] = "NonAuthoritativeInformation";
521
+ EHttpStatusCode[EHttpStatusCode["NoContent"] = 204] = "NoContent";
522
+ EHttpStatusCode[EHttpStatusCode["ResetContent"] = 205] = "ResetContent";
523
+ EHttpStatusCode[EHttpStatusCode["PartialContent"] = 206] = "PartialContent";
524
+ EHttpStatusCode[EHttpStatusCode["MultiStatus"] = 207] = "MultiStatus";
525
+ EHttpStatusCode[EHttpStatusCode["AlreadyReported"] = 208] = "AlreadyReported";
526
+ EHttpStatusCode[EHttpStatusCode["IMUsed"] = 226] = "IMUsed";
527
+ EHttpStatusCode[EHttpStatusCode["MultipleChoices"] = 300] = "MultipleChoices";
528
+ EHttpStatusCode[EHttpStatusCode["MovedPermanently"] = 301] = "MovedPermanently";
529
+ EHttpStatusCode[EHttpStatusCode["Found"] = 302] = "Found";
530
+ EHttpStatusCode[EHttpStatusCode["SeeOther"] = 303] = "SeeOther";
531
+ EHttpStatusCode[EHttpStatusCode["NotModified"] = 304] = "NotModified";
532
+ EHttpStatusCode[EHttpStatusCode["UseProxy"] = 305] = "UseProxy";
533
+ EHttpStatusCode[EHttpStatusCode["SwitchProxy"] = 306] = "SwitchProxy";
534
+ EHttpStatusCode[EHttpStatusCode["TemporaryRedirect"] = 307] = "TemporaryRedirect";
535
+ EHttpStatusCode[EHttpStatusCode["PermanentRedirect"] = 308] = "PermanentRedirect";
536
+ EHttpStatusCode[EHttpStatusCode["BadRequest"] = 400] = "BadRequest";
537
+ EHttpStatusCode[EHttpStatusCode["Unauthorized"] = 401] = "Unauthorized";
538
+ EHttpStatusCode[EHttpStatusCode["PaymentRequired"] = 402] = "PaymentRequired";
539
+ EHttpStatusCode[EHttpStatusCode["Forbidden"] = 403] = "Forbidden";
540
+ EHttpStatusCode[EHttpStatusCode["NotFound"] = 404] = "NotFound";
541
+ EHttpStatusCode[EHttpStatusCode["MethodNotAllowed"] = 405] = "MethodNotAllowed";
542
+ EHttpStatusCode[EHttpStatusCode["NotAcceptable"] = 406] = "NotAcceptable";
543
+ EHttpStatusCode[EHttpStatusCode["ProxyAuthenticationRequired"] = 407] = "ProxyAuthenticationRequired";
544
+ EHttpStatusCode[EHttpStatusCode["RequestTimeout"] = 408] = "RequestTimeout";
545
+ EHttpStatusCode[EHttpStatusCode["Conflict"] = 409] = "Conflict";
546
+ EHttpStatusCode[EHttpStatusCode["Gone"] = 410] = "Gone";
547
+ EHttpStatusCode[EHttpStatusCode["LengthRequired"] = 411] = "LengthRequired";
548
+ EHttpStatusCode[EHttpStatusCode["PreconditionFailed"] = 412] = "PreconditionFailed";
549
+ EHttpStatusCode[EHttpStatusCode["PayloadTooLarge"] = 413] = "PayloadTooLarge";
550
+ EHttpStatusCode[EHttpStatusCode["URITooLong"] = 414] = "URITooLong";
551
+ EHttpStatusCode[EHttpStatusCode["UnsupportedMediaType"] = 415] = "UnsupportedMediaType";
552
+ EHttpStatusCode[EHttpStatusCode["RangeNotSatisfiable"] = 416] = "RangeNotSatisfiable";
553
+ EHttpStatusCode[EHttpStatusCode["ExpectationFailed"] = 417] = "ExpectationFailed";
554
+ EHttpStatusCode[EHttpStatusCode["ImATeapot"] = 418] = "ImATeapot";
555
+ EHttpStatusCode[EHttpStatusCode["MisdirectedRequest"] = 421] = "MisdirectedRequest";
556
+ EHttpStatusCode[EHttpStatusCode["UnprocessableEntity"] = 422] = "UnprocessableEntity";
557
+ EHttpStatusCode[EHttpStatusCode["Locked"] = 423] = "Locked";
558
+ EHttpStatusCode[EHttpStatusCode["FailedDependency"] = 424] = "FailedDependency";
559
+ EHttpStatusCode[EHttpStatusCode["TooEarly"] = 425] = "TooEarly";
560
+ EHttpStatusCode[EHttpStatusCode["UpgradeRequired"] = 426] = "UpgradeRequired";
561
+ EHttpStatusCode[EHttpStatusCode["PreconditionRequired"] = 428] = "PreconditionRequired";
562
+ EHttpStatusCode[EHttpStatusCode["TooManyRequests"] = 429] = "TooManyRequests";
563
+ EHttpStatusCode[EHttpStatusCode["RequestHeaderFieldsTooLarge"] = 431] = "RequestHeaderFieldsTooLarge";
564
+ EHttpStatusCode[EHttpStatusCode["UnavailableForLegalReasons"] = 451] = "UnavailableForLegalReasons";
565
+ EHttpStatusCode[EHttpStatusCode["InternalServerError"] = 500] = "InternalServerError";
566
+ EHttpStatusCode[EHttpStatusCode["NotImplemented"] = 501] = "NotImplemented";
567
+ EHttpStatusCode[EHttpStatusCode["BadGateway"] = 502] = "BadGateway";
568
+ EHttpStatusCode[EHttpStatusCode["ServiceUnavailable"] = 503] = "ServiceUnavailable";
569
+ EHttpStatusCode[EHttpStatusCode["GatewayTimeout"] = 504] = "GatewayTimeout";
570
+ EHttpStatusCode[EHttpStatusCode["HTTPVersionNotSupported"] = 505] = "HTTPVersionNotSupported";
571
+ EHttpStatusCode[EHttpStatusCode["VariantAlsoNegotiates"] = 506] = "VariantAlsoNegotiates";
572
+ EHttpStatusCode[EHttpStatusCode["InsufficientStorage"] = 507] = "InsufficientStorage";
573
+ EHttpStatusCode[EHttpStatusCode["LoopDetected"] = 508] = "LoopDetected";
574
+ EHttpStatusCode[EHttpStatusCode["NotExtended"] = 510] = "NotExtended";
575
+ EHttpStatusCode[EHttpStatusCode["NetworkAuthenticationRequired"] = 511] = "NetworkAuthenticationRequired";
619
576
  })(EHttpStatusCode || (EHttpStatusCode = {}));
620
577
 
621
- const defaultStatus = {
622
- GET: EHttpStatusCode.OK,
623
- POST: EHttpStatusCode.Created,
624
- PUT: EHttpStatusCode.Created,
625
- PATCH: EHttpStatusCode.Accepted,
626
- DELETE: EHttpStatusCode.Accepted,
627
- };
628
- const baseRenderer = new BaseHttpResponseRenderer();
629
- class BaseHttpResponse {
630
- constructor(renderer = baseRenderer) {
631
- this.renderer = renderer;
632
- this._status = 0;
633
- this._headers = {};
634
- }
635
- get status() {
636
- return this._status;
637
- }
638
- set status(value) {
639
- this._status = value;
640
- }
641
- get body() {
642
- return this._body;
643
- }
644
- set body(value) {
645
- this._body = value;
646
- }
647
- setStatus(value) {
648
- this.status = value;
649
- return this;
650
- }
651
- setBody(value) {
652
- this.body = value;
653
- return this;
654
- }
655
- getContentType() {
656
- return this._headers['content-type'];
657
- }
658
- setContentType(value) {
659
- this._headers['content-type'] = value;
660
- return this;
661
- }
662
- enableCors(origin = '*') {
663
- this._headers['Access-Control-Allow-Origin'] = origin;
664
- return this;
665
- }
666
- setCookie(name, value, attrs) {
667
- const cookies = (this._headers['set-cookie'] = (this._headers['set-cookie'] || []));
668
- cookies.push(renderCookie(name, { value, attrs: attrs || {} }));
669
- return this;
670
- }
671
- setCacheControl(data) {
672
- this.setHeader('cache-control', renderCacheControl(data));
673
- }
674
- setCookieRaw(rawValue) {
675
- const cookies = (this._headers['set-cookie'] = (this._headers['set-cookie'] || []));
676
- cookies.push(rawValue);
677
- return this;
678
- }
679
- header(name, value) {
680
- this._headers[name] = value;
681
- return this;
682
- }
683
- setHeader(name, value) {
684
- return this.header(name, value);
685
- }
686
- getHeader(name) {
687
- return this._headers[name];
688
- }
689
- mergeHeaders() {
690
- const { headers } = useSetHeaders();
691
- const { cookies, removeCookie } = useSetCookies();
692
- const newCookies = this._headers['set-cookie'] || [];
693
- for (const cookie of newCookies) {
694
- removeCookie(cookie.slice(0, cookie.indexOf('=')));
695
- }
696
- this._headers = Object.assign(Object.assign({}, headers()), this._headers);
697
- const setCookie = [...newCookies, ...cookies()];
698
- if (setCookie && setCookie.length) {
699
- this._headers['set-cookie'] = setCookie;
700
- }
701
- return this;
702
- }
703
- mergeStatus(renderedBody) {
704
- this.status = this.status || useResponse().status();
705
- if (!this.status) {
706
- const { method } = useRequest();
707
- this.status = renderedBody
708
- ? defaultStatus[method] || EHttpStatusCode.OK
709
- : EHttpStatusCode.NoContent;
710
- }
711
- return this;
712
- }
713
- mergeFetchStatus(fetchStatus) {
714
- this.status = this.status || useResponse().status() || fetchStatus;
715
- }
716
- panic(text, logger) {
717
- const error = new Error(text);
718
- logger.error(error);
719
- throw error;
720
- }
721
- respond() {
722
- return __awaiter(this, void 0, void 0, function* () {
723
- const { rawResponse, hasResponded } = useResponse();
724
- const { method, rawRequest } = useRequest();
725
- const logger = useEventLogger('http-response');
726
- if (hasResponded()) {
727
- this.panic('The response was already sent.', logger);
728
- }
729
- this.mergeHeaders();
730
- const res = rawResponse();
731
- if (this.body instanceof Readable) {
732
- // responding with readable stream
733
- const stream = this.body;
734
- this.mergeStatus('ok');
735
- res.writeHead(this.status, Object.assign({}, this._headers));
736
- rawRequest.once('close', () => {
737
- stream.destroy();
738
- });
739
- if (method === 'HEAD') {
740
- stream.destroy();
741
- res.end();
742
- }
743
- else {
744
- return new Promise((resolve, reject) => {
745
- stream.on('error', (e) => {
746
- stream.destroy();
747
- res.end();
748
- reject(e);
749
- });
750
- stream.on('close', () => {
751
- stream.destroy();
752
- resolve(undefined);
753
- });
754
- stream.pipe(res);
755
- });
756
- }
757
- }
758
- else if (globalThis.Response &&
759
- this.body instanceof Response /* Fetch Response */) {
760
- this.mergeFetchStatus(this.body.status);
761
- if (method === 'HEAD') {
762
- res.end();
763
- }
764
- else {
765
- const additionalHeaders = {};
766
- if (this.body.headers.get('content-length')) {
767
- additionalHeaders['content-length'] = this.body.headers.get('content-length');
768
- }
769
- if (this.body.headers.get('content-type')) {
770
- additionalHeaders['content-type'] = this.body.headers.get('content-type');
771
- }
772
- res.writeHead(this.status, Object.assign(Object.assign({}, additionalHeaders), this._headers));
773
- yield respondWithFetch(this.body.body, res);
774
- }
775
- }
776
- else {
777
- const renderedBody = this.renderer.render(this);
778
- this.mergeStatus(renderedBody);
779
- res.writeHead(this.status, Object.assign({ 'content-length': Buffer.byteLength(renderedBody) }, this._headers)).end(method !== 'HEAD' ? renderedBody : '');
780
- }
781
- });
782
- }
783
- }
784
- function respondWithFetch(fetchBody, res) {
785
- var _a, e_1, _b, _c;
786
- return __awaiter(this, void 0, void 0, function* () {
787
- if (fetchBody) {
788
- try {
789
- try {
790
- for (var _d = true, _e = __asyncValues(fetchBody), _f; _f = yield _e.next(), _a = _f.done, !_a;) {
791
- _c = _f.value;
792
- _d = false;
793
- try {
794
- const chunk = _c;
795
- res.write(chunk);
796
- }
797
- finally {
798
- _d = true;
799
- }
800
- }
801
- }
802
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
803
- finally {
804
- try {
805
- if (!_d && !_a && (_b = _e.return)) yield _b.call(_e);
806
- }
807
- finally { if (e_1) throw e_1.error; }
808
- }
809
- }
810
- catch (e) {
811
- // ?
812
- }
813
- }
814
- res.end();
815
- });
578
+ const defaultStatus = {
579
+ GET: EHttpStatusCode.OK,
580
+ POST: EHttpStatusCode.Created,
581
+ PUT: EHttpStatusCode.Created,
582
+ PATCH: EHttpStatusCode.Accepted,
583
+ DELETE: EHttpStatusCode.Accepted,
584
+ };
585
+ const baseRenderer = new BaseHttpResponseRenderer();
586
+ class BaseHttpResponse {
587
+ constructor(renderer = baseRenderer) {
588
+ this.renderer = renderer;
589
+ this._status = 0;
590
+ this._headers = {};
591
+ }
592
+ get status() {
593
+ return this._status;
594
+ }
595
+ set status(value) {
596
+ this._status = value;
597
+ }
598
+ get body() {
599
+ return this._body;
600
+ }
601
+ set body(value) {
602
+ this._body = value;
603
+ }
604
+ setStatus(value) {
605
+ this.status = value;
606
+ return this;
607
+ }
608
+ setBody(value) {
609
+ this.body = value;
610
+ return this;
611
+ }
612
+ getContentType() {
613
+ return this._headers['content-type'];
614
+ }
615
+ setContentType(value) {
616
+ this._headers['content-type'] = value;
617
+ return this;
618
+ }
619
+ enableCors(origin = '*') {
620
+ this._headers['Access-Control-Allow-Origin'] = origin;
621
+ return this;
622
+ }
623
+ setCookie(name, value, attrs) {
624
+ const cookies = (this._headers['set-cookie'] = (this._headers['set-cookie'] || []));
625
+ cookies.push(renderCookie(name, { value, attrs: attrs || {} }));
626
+ return this;
627
+ }
628
+ setCacheControl(data) {
629
+ this.setHeader('cache-control', renderCacheControl(data));
630
+ }
631
+ setCookieRaw(rawValue) {
632
+ const cookies = (this._headers['set-cookie'] = (this._headers['set-cookie'] || []));
633
+ cookies.push(rawValue);
634
+ return this;
635
+ }
636
+ header(name, value) {
637
+ this._headers[name] = value;
638
+ return this;
639
+ }
640
+ setHeader(name, value) {
641
+ return this.header(name, value);
642
+ }
643
+ getHeader(name) {
644
+ return this._headers[name];
645
+ }
646
+ mergeHeaders() {
647
+ const { headers } = useSetHeaders();
648
+ const { cookies, removeCookie } = useSetCookies();
649
+ const newCookies = this._headers['set-cookie'] || [];
650
+ for (const cookie of newCookies) {
651
+ removeCookie(cookie.slice(0, cookie.indexOf('=')));
652
+ }
653
+ this._headers = {
654
+ ...headers(),
655
+ ...this._headers,
656
+ };
657
+ const setCookie = [...newCookies, ...cookies()];
658
+ if (setCookie && setCookie.length) {
659
+ this._headers['set-cookie'] = setCookie;
660
+ }
661
+ return this;
662
+ }
663
+ mergeStatus(renderedBody) {
664
+ this.status = this.status || useResponse().status();
665
+ if (!this.status) {
666
+ const { method } = useRequest();
667
+ this.status = renderedBody
668
+ ? defaultStatus[method] || EHttpStatusCode.OK
669
+ : EHttpStatusCode.NoContent;
670
+ }
671
+ return this;
672
+ }
673
+ mergeFetchStatus(fetchStatus) {
674
+ this.status = this.status || useResponse().status() || fetchStatus;
675
+ }
676
+ panic(text, logger) {
677
+ const error = new Error(text);
678
+ logger.error(error);
679
+ throw error;
680
+ }
681
+ async respond() {
682
+ const { rawResponse, hasResponded } = useResponse();
683
+ const { method, rawRequest } = useRequest();
684
+ const logger = useEventLogger('http-response');
685
+ if (hasResponded()) {
686
+ this.panic('The response was already sent.', logger);
687
+ }
688
+ this.mergeHeaders();
689
+ const res = rawResponse();
690
+ if (this.body instanceof Readable) {
691
+ // responding with readable stream
692
+ const stream = this.body;
693
+ this.mergeStatus('ok');
694
+ res.writeHead(this.status, {
695
+ ...this._headers,
696
+ });
697
+ rawRequest.once('close', () => {
698
+ stream.destroy();
699
+ });
700
+ if (method === 'HEAD') {
701
+ stream.destroy();
702
+ res.end();
703
+ }
704
+ else {
705
+ return new Promise((resolve, reject) => {
706
+ stream.on('error', (e) => {
707
+ stream.destroy();
708
+ res.end();
709
+ reject(e);
710
+ });
711
+ stream.on('close', () => {
712
+ stream.destroy();
713
+ resolve(undefined);
714
+ });
715
+ stream.pipe(res);
716
+ });
717
+ }
718
+ }
719
+ else if (globalThis.Response &&
720
+ this.body instanceof Response /* Fetch Response */) {
721
+ this.mergeFetchStatus(this.body.status);
722
+ if (method === 'HEAD') {
723
+ res.end();
724
+ }
725
+ else {
726
+ const additionalHeaders = {};
727
+ if (this.body.headers.get('content-length')) {
728
+ additionalHeaders['content-length'] = this.body.headers.get('content-length');
729
+ }
730
+ if (this.body.headers.get('content-type')) {
731
+ additionalHeaders['content-type'] = this.body.headers.get('content-type');
732
+ }
733
+ res.writeHead(this.status, {
734
+ ...additionalHeaders,
735
+ ...this._headers,
736
+ });
737
+ await respondWithFetch(this.body.body, res);
738
+ }
739
+ }
740
+ else {
741
+ const renderedBody = this.renderer.render(this);
742
+ this.mergeStatus(renderedBody);
743
+ res.writeHead(this.status, {
744
+ 'content-length': Buffer.byteLength(renderedBody),
745
+ ...this._headers,
746
+ }).end(method !== 'HEAD' ? renderedBody : '');
747
+ }
748
+ }
749
+ }
750
+ async function respondWithFetch(fetchBody, res) {
751
+ if (fetchBody) {
752
+ try {
753
+ for await (const chunk of fetchBody) {
754
+ res.write(chunk);
755
+ }
756
+ }
757
+ catch (e) {
758
+ // ?
759
+ }
760
+ }
761
+ res.end();
816
762
  }
817
763
 
818
- const preStyles = 'font-family: monospace;' +
819
- 'width: 100%;' +
820
- 'max-width: 900px;' +
821
- 'padding: 10px;' +
822
- 'margin: 20px auto;' +
823
- 'border-radius: 8px;' +
824
- 'background-color: #494949;' +
825
- 'box-shadow: 0px 0px 3px 2px rgb(255 255 255 / 20%);';
826
- class HttpErrorRenderer extends BaseHttpResponseRenderer {
827
- renderHtml(response) {
828
- const data = response.body || {};
829
- response.setContentType('text/html');
830
- const keys = Object.keys(data).filter((key) => !['statusCode', 'error', 'message'].includes(key));
831
- return ('<html style="background-color: #333; color: #bbb;">' +
832
- `<head><title>${data.statusCode} ${httpStatusCodes[data.statusCode]}</title></head>` +
833
- `<body><center><h1>${data.statusCode} ${httpStatusCodes[data.statusCode]}</h1></center>` +
834
- `<center><h4>${data.message}</h1></center><hr color="#666">` +
835
- `<center style="color: #666;"> Wooks v${"0.4.9"} </center>` +
836
- `${keys.length
837
- ? `<pre style="${preStyles}">${JSON.stringify(Object.assign(Object.assign({}, data), { statusCode: undefined, message: undefined, error: undefined }), null, ' ')}</pre>`
838
- : ''}` +
839
- '</body></html>');
840
- }
841
- renderText(response) {
842
- const data = response.body || {};
843
- response.setContentType('text/plain');
844
- const keys = Object.keys(data).filter((key) => !['statusCode', 'error', 'message'].includes(key));
845
- return (`${data.statusCode} ${httpStatusCodes[data.statusCode]}\n${data.message}` +
846
- `\n\n${keys.length
847
- ? `${JSON.stringify(Object.assign(Object.assign({}, data), { statusCode: undefined, message: undefined, error: undefined }), null, ' ')}`
848
- : ''}`);
849
- }
850
- renderJson(response) {
851
- const data = response.body || {};
852
- response.setContentType('application/json');
853
- const keys = Object.keys(data).filter((key) => !['statusCode', 'error', 'message'].includes(key));
854
- return (`{"statusCode":${escapeQuotes(data.statusCode)},` +
855
- `"error":"${escapeQuotes(data.error)}",` +
856
- `"message":"${escapeQuotes(data.message)}"` +
857
- `${keys.length
858
- ? ',' +
859
- keys
860
- .map((k) => `"${escapeQuotes(k)}":${JSON.stringify(data[k])}`)
861
- .join(',')
862
- : ''}}`);
863
- }
864
- render(response) {
865
- var _a;
866
- const { acceptsJson, acceptsText, acceptsHtml } = useAccept();
867
- response.status = ((_a = response.body) === null || _a === void 0 ? void 0 : _a.statusCode) || 500;
868
- if (acceptsJson()) {
869
- return this.renderJson(response);
870
- }
871
- else if (acceptsHtml()) {
872
- return this.renderHtml(response);
873
- }
874
- else if (acceptsText()) {
875
- return this.renderText(response);
876
- }
877
- else {
878
- return this.renderJson(response);
879
- }
880
- }
881
- }
882
- function escapeQuotes(s) {
883
- return (typeof s === 'number' ? s : s || '')
884
- .toString()
885
- .replace(/[\""]/g, '\\"');
764
+ const preStyles = 'font-family: monospace;' +
765
+ 'width: 100%;' +
766
+ 'max-width: 900px;' +
767
+ 'padding: 10px;' +
768
+ 'margin: 20px auto;' +
769
+ 'border-radius: 8px;' +
770
+ 'background-color: #494949;' +
771
+ 'box-shadow: 0px 0px 3px 2px rgb(255 255 255 / 20%);';
772
+ class HttpErrorRenderer extends BaseHttpResponseRenderer {
773
+ renderHtml(response) {
774
+ const data = response.body || {};
775
+ response.setContentType('text/html');
776
+ const keys = Object.keys(data).filter((key) => !['statusCode', 'error', 'message'].includes(key));
777
+ return ('<html style="background-color: #333; color: #bbb;">' +
778
+ `<head><title>${data.statusCode} ${httpStatusCodes[data.statusCode]}</title></head>` +
779
+ `<body><center><h1>${data.statusCode} ${httpStatusCodes[data.statusCode]}</h1></center>` +
780
+ `<center><h4>${data.message}</h1></center><hr color="#666">` +
781
+ `<center style="color: #666;"> Wooks v${"0.4.11"} </center>` +
782
+ `${keys.length
783
+ ? `<pre style="${preStyles}">${JSON.stringify({
784
+ ...data,
785
+ statusCode: undefined,
786
+ message: undefined,
787
+ error: undefined,
788
+ }, null, ' ')}</pre>`
789
+ : ''}` +
790
+ '</body></html>');
791
+ }
792
+ renderText(response) {
793
+ const data = response.body || {};
794
+ response.setContentType('text/plain');
795
+ const keys = Object.keys(data).filter((key) => !['statusCode', 'error', 'message'].includes(key));
796
+ return (`${data.statusCode} ${httpStatusCodes[data.statusCode]}\n${data.message}` +
797
+ `\n\n${keys.length
798
+ ? `${JSON.stringify({
799
+ ...data,
800
+ statusCode: undefined,
801
+ message: undefined,
802
+ error: undefined,
803
+ }, null, ' ')}`
804
+ : ''}`);
805
+ }
806
+ renderJson(response) {
807
+ const data = response.body || {};
808
+ response.setContentType('application/json');
809
+ const keys = Object.keys(data).filter((key) => !['statusCode', 'error', 'message'].includes(key));
810
+ return (`{"statusCode":${escapeQuotes(data.statusCode)},` +
811
+ `"error":"${escapeQuotes(data.error)}",` +
812
+ `"message":"${escapeQuotes(data.message)}"` +
813
+ `${keys.length
814
+ ? ',' +
815
+ keys
816
+ .map((k) => `"${escapeQuotes(k)}":${JSON.stringify(data[k])}`)
817
+ .join(',')
818
+ : ''}}`);
819
+ }
820
+ render(response) {
821
+ const { acceptsJson, acceptsText, acceptsHtml } = useAccept();
822
+ response.status = response.body?.statusCode || 500;
823
+ if (acceptsJson()) {
824
+ return this.renderJson(response);
825
+ }
826
+ else if (acceptsHtml()) {
827
+ return this.renderHtml(response);
828
+ }
829
+ else if (acceptsText()) {
830
+ return this.renderText(response);
831
+ }
832
+ else {
833
+ return this.renderJson(response);
834
+ }
835
+ }
836
+ }
837
+ function escapeQuotes(s) {
838
+ return (typeof s === 'number' ? s : s || '')
839
+ .toString()
840
+ .replace(/[\""]/g, '\\"');
886
841
  }
887
842
 
888
- class HttpError extends Error {
889
- constructor(code = 500, _body = '') {
890
- super(typeof _body === 'string' ? _body : _body.message);
891
- this.code = code;
892
- this._body = _body;
893
- }
894
- get body() {
895
- return typeof this._body === 'string'
896
- ? {
897
- statusCode: this.code,
898
- message: this.message,
899
- error: httpStatusCodes[this.code],
900
- }
901
- : Object.assign(Object.assign({}, this._body), { statusCode: this.code, message: this.message, error: httpStatusCodes[this.code] });
902
- }
903
- attachRenderer(renderer) {
904
- this.renderer = renderer;
905
- }
906
- getRenderer() {
907
- return this.renderer;
908
- }
843
+ class HttpError extends Error {
844
+ constructor(code = 500, _body = '') {
845
+ super(typeof _body === 'string' ? _body : _body.message);
846
+ this.code = code;
847
+ this._body = _body;
848
+ }
849
+ get body() {
850
+ return typeof this._body === 'string'
851
+ ? {
852
+ statusCode: this.code,
853
+ message: this.message,
854
+ error: httpStatusCodes[this.code],
855
+ }
856
+ : {
857
+ ...this._body,
858
+ statusCode: this.code,
859
+ message: this.message,
860
+ error: httpStatusCodes[this.code],
861
+ };
862
+ }
863
+ attachRenderer(renderer) {
864
+ this.renderer = renderer;
865
+ }
866
+ getRenderer() {
867
+ return this.renderer;
868
+ }
909
869
  }
910
870
 
911
- function createWooksResponder(
912
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
913
- renderer = new BaseHttpResponseRenderer(),
914
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
915
- errorRenderer = new HttpErrorRenderer()) {
916
- function createResponse(data) {
917
- const { hasResponded } = useResponse();
918
- if (hasResponded())
919
- return null;
920
- if (data instanceof Error) {
921
- const r = new BaseHttpResponse(errorRenderer);
922
- let httpError;
923
- if (data instanceof HttpError) {
924
- httpError = data;
925
- }
926
- else {
927
- httpError = new HttpError(500, data.message);
928
- }
929
- r.setBody(httpError.body);
930
- return r;
931
- }
932
- else if (data instanceof BaseHttpResponse) {
933
- return data;
934
- }
935
- else {
936
- return new BaseHttpResponse(renderer).setBody(data);
937
- }
938
- }
939
- return {
940
- createResponse,
941
- respond: (data) => { var _a; return (_a = createResponse(data)) === null || _a === void 0 ? void 0 : _a.respond(); },
942
- };
871
+ function createWooksResponder(
872
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
873
+ renderer = new BaseHttpResponseRenderer(),
874
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
875
+ errorRenderer = new HttpErrorRenderer()) {
876
+ function createResponse(data) {
877
+ const { hasResponded } = useResponse();
878
+ if (hasResponded())
879
+ return null;
880
+ if (data instanceof Error) {
881
+ const r = new BaseHttpResponse(errorRenderer);
882
+ let httpError;
883
+ if (data instanceof HttpError) {
884
+ httpError = data;
885
+ }
886
+ else {
887
+ httpError = new HttpError(500, data.message);
888
+ }
889
+ r.setBody(httpError.body);
890
+ return r;
891
+ }
892
+ else if (data instanceof BaseHttpResponse) {
893
+ return data;
894
+ }
895
+ else {
896
+ return new BaseHttpResponse(renderer).setBody(data);
897
+ }
898
+ }
899
+ return {
900
+ createResponse,
901
+ respond: (data) => createResponse(data)?.respond(),
902
+ };
943
903
  }
944
904
 
945
- class WooksHttp extends WooksAdapterBase {
946
- constructor(opts, wooks) {
947
- super(wooks, opts === null || opts === void 0 ? void 0 : opts.logger, opts === null || opts === void 0 ? void 0 : opts.router);
948
- this.opts = opts;
949
- this.responder = createWooksResponder();
950
- this.logger = (opts === null || opts === void 0 ? void 0 : opts.logger) || this.getLogger('wooks-http');
951
- }
952
- all(path, handler) {
953
- return this.on('*', path, handler);
954
- }
955
- get(path, handler) {
956
- return this.on('GET', path, handler);
957
- }
958
- post(path, handler) {
959
- return this.on('POST', path, handler);
960
- }
961
- put(path, handler) {
962
- return this.on('PUT', path, handler);
963
- }
964
- patch(path, handler) {
965
- return this.on('PATCH', path, handler);
966
- }
967
- delete(path, handler) {
968
- return this.on('DELETE', path, handler);
969
- }
970
- head(path, handler) {
971
- return this.on('HEAD', path, handler);
972
- }
973
- options(path, handler) {
974
- return this.on('OPTIONS', path, handler);
975
- }
976
- /**
977
- * Starts the http(s) server.
978
- *
979
- * Use this only if you rely on Wooks server.
980
- */
981
- listen(...args) {
982
- return __awaiter(this, void 0, void 0, function* () {
983
- const server = (this.server = http.createServer(this.getServerCb()));
984
- return new Promise((resolve, reject) => {
985
- server.once('listening', resolve);
986
- server.once('error', reject);
987
- server.listen(...args);
988
- });
989
- });
990
- }
991
- /**
992
- * Stops the server if it was attached or passed via argument
993
- * @param server
994
- */
995
- close(server) {
996
- const srv = server || this.server;
997
- return new Promise((resolve, reject) => {
998
- srv === null || srv === void 0 ? void 0 : srv.close((err) => {
999
- if (err)
1000
- return reject(err);
1001
- resolve(srv);
1002
- });
1003
- });
1004
- }
1005
- /**
1006
- * Returns http(s) server that was attached to Wooks
1007
- *
1008
- * See attachServer method docs
1009
- * @returns Server
1010
- */
1011
- getServer() {
1012
- return this.server;
1013
- }
1014
- /**
1015
- * Attaches http(s) server instance
1016
- * to Wooks.
1017
- *
1018
- * Use it only if you want to `close` method to stop the server.
1019
- * @param server Server
1020
- */
1021
- attachServer(server) {
1022
- this.server = server;
1023
- }
1024
- respond(data) {
1025
- var _a;
1026
- void ((_a = this.responder.respond(data)) === null || _a === void 0 ? void 0 : _a.catch((e) => {
1027
- this.logger.error('Uncought response exception', e);
1028
- }));
1029
- }
1030
- /**
1031
- * Returns server callback function
1032
- * that can be passed to any node server:
1033
- * ```js
1034
- * import { createHttpApp } from '@wooksjs/event-http'
1035
- * import http from 'http'
1036
- *
1037
- * const app = createHttpApp()
1038
- * const server = http.createServer(app.getServerCb())
1039
- * server.listen(3000)
1040
- * ```
1041
- */
1042
- getServerCb() {
1043
- return (req, res) => __awaiter(this, void 0, void 0, function* () {
1044
- var _a, _b, _c;
1045
- const { restoreCtx, clearCtx } = createHttpContext({ req, res }, this.mergeEventOptions((_a = this.opts) === null || _a === void 0 ? void 0 : _a.eventOptions));
1046
- const { handlers } = this.wooks.lookup(req.method, req.url);
1047
- if (handlers || ((_b = this.opts) === null || _b === void 0 ? void 0 : _b.onNotFound)) {
1048
- try {
1049
- yield this.processHandlers(handlers || [(_c = this.opts) === null || _c === void 0 ? void 0 : _c.onNotFound]);
1050
- }
1051
- catch (e) {
1052
- this.logger.error('Internal error, please report', e);
1053
- restoreCtx();
1054
- this.respond(e);
1055
- clearCtx();
1056
- }
1057
- }
1058
- else {
1059
- // not found
1060
- this.logger.debug(`404 Not found (${req.method})${req.url}`);
1061
- this.respond(new HttpError(404));
1062
- clearCtx();
1063
- }
1064
- });
1065
- }
1066
- processHandlers(handlers) {
1067
- return __awaiter(this, void 0, void 0, function* () {
1068
- const { restoreCtx, clearCtx, store } = useHttpContext();
1069
- for (const [i, handler] of handlers.entries()) {
1070
- const isLastHandler = handlers.length === i + 1;
1071
- try {
1072
- restoreCtx();
1073
- const promise = handler();
1074
- clearCtx();
1075
- const result = yield promise;
1076
- // even if the returned value is an Error instance
1077
- // we still want to process it as a response
1078
- restoreCtx();
1079
- this.respond(result);
1080
- clearCtx();
1081
- break;
1082
- }
1083
- catch (e) {
1084
- this.logger.error(`Uncought route handler exception: ${store('event').get('req').url || ''}`, e);
1085
- if (isLastHandler) {
1086
- restoreCtx();
1087
- this.respond(e);
1088
- clearCtx();
1089
- }
1090
- }
1091
- }
1092
- });
1093
- }
1094
- }
1095
- /**
1096
- * Factory for WooksHttp App
1097
- * @param opts TWooksHttpOptions
1098
- * @param wooks Wooks | WooksAdapterBase
1099
- * @returns WooksHttp
1100
- */
1101
- function createHttpApp(opts, wooks) {
1102
- return new WooksHttp(opts, wooks);
905
+ class WooksHttp extends WooksAdapterBase {
906
+ constructor(opts, wooks) {
907
+ super(wooks, opts?.logger, opts?.router);
908
+ this.opts = opts;
909
+ this.responder = createWooksResponder();
910
+ this.logger = opts?.logger || this.getLogger('wooks-http');
911
+ }
912
+ all(path, handler) {
913
+ return this.on('*', path, handler);
914
+ }
915
+ get(path, handler) {
916
+ return this.on('GET', path, handler);
917
+ }
918
+ post(path, handler) {
919
+ return this.on('POST', path, handler);
920
+ }
921
+ put(path, handler) {
922
+ return this.on('PUT', path, handler);
923
+ }
924
+ patch(path, handler) {
925
+ return this.on('PATCH', path, handler);
926
+ }
927
+ delete(path, handler) {
928
+ return this.on('DELETE', path, handler);
929
+ }
930
+ head(path, handler) {
931
+ return this.on('HEAD', path, handler);
932
+ }
933
+ options(path, handler) {
934
+ return this.on('OPTIONS', path, handler);
935
+ }
936
+ /**
937
+ * Starts the http(s) server.
938
+ *
939
+ * Use this only if you rely on Wooks server.
940
+ */
941
+ async listen(...args) {
942
+ const server = (this.server = http.createServer(this.getServerCb()));
943
+ return new Promise((resolve, reject) => {
944
+ server.once('listening', resolve);
945
+ server.once('error', reject);
946
+ server.listen(...args);
947
+ });
948
+ }
949
+ /**
950
+ * Stops the server if it was attached or passed via argument
951
+ * @param server
952
+ */
953
+ close(server) {
954
+ const srv = server || this.server;
955
+ return new Promise((resolve, reject) => {
956
+ srv?.close((err) => {
957
+ if (err)
958
+ return reject(err);
959
+ resolve(srv);
960
+ });
961
+ });
962
+ }
963
+ /**
964
+ * Returns http(s) server that was attached to Wooks
965
+ *
966
+ * See attachServer method docs
967
+ * @returns Server
968
+ */
969
+ getServer() {
970
+ return this.server;
971
+ }
972
+ /**
973
+ * Attaches http(s) server instance
974
+ * to Wooks.
975
+ *
976
+ * Use it only if you want to `close` method to stop the server.
977
+ * @param server Server
978
+ */
979
+ attachServer(server) {
980
+ this.server = server;
981
+ }
982
+ respond(data) {
983
+ void this.responder.respond(data)?.catch((e) => {
984
+ this.logger.error('Uncought response exception', e);
985
+ });
986
+ }
987
+ /**
988
+ * Returns server callback function
989
+ * that can be passed to any node server:
990
+ * ```js
991
+ * import { createHttpApp } from '@wooksjs/event-http'
992
+ * import http from 'http'
993
+ *
994
+ * const app = createHttpApp()
995
+ * const server = http.createServer(app.getServerCb())
996
+ * server.listen(3000)
997
+ * ```
998
+ */
999
+ getServerCb() {
1000
+ return async (req, res) => {
1001
+ const { restoreCtx, clearCtx } = createHttpContext({ req, res }, this.mergeEventOptions(this.opts?.eventOptions));
1002
+ const { handlers } = this.wooks.lookup(req.method, req.url);
1003
+ if (handlers || this.opts?.onNotFound) {
1004
+ try {
1005
+ await this.processHandlers(handlers || [this.opts?.onNotFound]);
1006
+ }
1007
+ catch (e) {
1008
+ this.logger.error('Internal error, please report', e);
1009
+ restoreCtx();
1010
+ this.respond(e);
1011
+ clearCtx();
1012
+ }
1013
+ }
1014
+ else {
1015
+ // not found
1016
+ this.logger.debug(`404 Not found (${req.method})${req.url}`);
1017
+ this.respond(new HttpError(404));
1018
+ clearCtx();
1019
+ }
1020
+ };
1021
+ }
1022
+ async processHandlers(handlers) {
1023
+ const { restoreCtx, clearCtx, store } = useHttpContext();
1024
+ for (const [i, handler] of handlers.entries()) {
1025
+ const isLastHandler = handlers.length === i + 1;
1026
+ try {
1027
+ restoreCtx();
1028
+ const promise = handler();
1029
+ clearCtx();
1030
+ const result = await promise;
1031
+ // even if the returned value is an Error instance
1032
+ // we still want to process it as a response
1033
+ restoreCtx();
1034
+ this.respond(result);
1035
+ clearCtx();
1036
+ break;
1037
+ }
1038
+ catch (e) {
1039
+ this.logger.error(`Uncought route handler exception: ${store('event').get('req').url || ''}`, e);
1040
+ if (isLastHandler) {
1041
+ restoreCtx();
1042
+ this.respond(e);
1043
+ clearCtx();
1044
+ }
1045
+ }
1046
+ }
1047
+ }
1048
+ }
1049
+ /**
1050
+ * Factory for WooksHttp App
1051
+ * @param opts TWooksHttpOptions
1052
+ * @param wooks Wooks | WooksAdapterBase
1053
+ * @returns WooksHttp
1054
+ */
1055
+ function createHttpApp(opts, wooks) {
1056
+ return new WooksHttp(opts, wooks);
1103
1057
  }
1104
1058
 
1105
1059
  export { BaseHttpResponse, BaseHttpResponseRenderer, EHttpStatusCode, HttpError, HttpErrorRenderer, WooksHttp, WooksURLSearchParams, createHttpApp, createHttpContext, createWooksResponder, httpStatusCodes, renderCacheControl, useAccept, useAuthorization, useCookies, useHeaders, useHttpContext, useRequest, useResponse, useSearchParams, useSetCacheControl, useSetCookie, useSetCookies, useSetHeader, useSetHeaders, useStatus };