dx-server 0.5.0 → 0.5.2

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.
@@ -0,0 +1,113 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.writeRes = void 0;
7
+ const node_stream_1 = require("node:stream");
8
+ const jdefer_1 = __importDefault(require("jdefer"));
9
+ const node_util_1 = require("node:util");
10
+ const etag_js_1 = require("./etag.js");
11
+ async function writeRes(req, res, { type, data, charset, jsonBeautify, disableEtag }) {
12
+ const setContentType = (contentType) => {
13
+ if (res.headersSent || res.getHeader('content-type'))
14
+ return;
15
+ res.setHeader('content-type', `${contentType}${charset ? `; charset=${charset}` : ''}`);
16
+ };
17
+ let bufferOrStream;
18
+ switch (type) {
19
+ case 'text':
20
+ setContentType('text/plain');
21
+ case 'html':
22
+ setContentType('text/html');
23
+ // shared with text
24
+ bufferOrStream = Buffer.from(data, charset);
25
+ break;
26
+ case 'buffer':
27
+ setContentType('application/octet-stream');
28
+ bufferOrStream = data;
29
+ break;
30
+ case 'nodeStream':
31
+ setContentType('application/octet-stream');
32
+ bufferOrStream = data;
33
+ break;
34
+ case 'webStream':
35
+ setContentType('application/octet-stream');
36
+ bufferOrStream = node_stream_1.Readable.fromWeb(data);
37
+ break;
38
+ case 'json':
39
+ setContentType('application/json');
40
+ bufferOrStream = Buffer.from(jsonBeautify ? JSON.stringify(data, null, 2) : JSON.stringify(data), charset);
41
+ break;
42
+ case 'redirect':
43
+ res.setHeader('location', data);
44
+ bufferOrStream = Buffer.from('', charset);
45
+ break;
46
+ case undefined:
47
+ // skip response. Some middleware may handle it outside the chain. For example, express middleware
48
+ return;
49
+ default:
50
+ if (!res.getHeader('content-type'))
51
+ res.setHeader('content-type', 'text/plain');
52
+ throw new Error(`unsupported response type ${type}`);
53
+ }
54
+ if (res.headersSent) {
55
+ if (res.writableFinished) {
56
+ // skipped: response is already finished
57
+ }
58
+ else if (res.writableEnded) {
59
+ const defer = (0, jdefer_1.default)();
60
+ res.addListener('finish', defer.resolve);
61
+ await defer.promise;
62
+ // skipped: response is already ended
63
+ // chunk is not fully flushed yet
64
+ }
65
+ else
66
+ await (0, node_util_1.promisify)(res.end.bind(res))(undefined); // to be consistent, we end the response immediately
67
+ }
68
+ else {
69
+ // https://github.com/expressjs/express/blob/980d881e3b023db079de60477a2588a91f046ca5/lib/response.js#L210
70
+ if (res.statusCode === 204) { // No Content
71
+ res.removeHeader('content-type');
72
+ res.removeHeader('content-length');
73
+ res.removeHeader('transfer-encoding');
74
+ // write nothing
75
+ }
76
+ if (res.statusCode === 205) { // reset content. Tell client to clear the form, etc.
77
+ res.setHeader('content-length', 0);
78
+ res.removeHeader('transfer-encoding');
79
+ }
80
+ else if (req.method === 'HEAD') {
81
+ // write nothing
82
+ }
83
+ else {
84
+ if (Buffer.isBuffer(bufferOrStream)) {
85
+ // support: 304 (etag), zipping, file etag and last modified
86
+ res.setHeader('content-length', bufferOrStream.length);
87
+ if (!disableEtag) {
88
+ const etag = (0, etag_js_1.entityTag)(bufferOrStream);
89
+ const lastModified = res.getHeader('last-modified');
90
+ res.setHeader('ETag', etag);
91
+ if ((0, etag_js_1.isFreshETag)(req, etag)) {
92
+ res.removeHeader('content-type');
93
+ res.removeHeader('content-length');
94
+ res.removeHeader('transfer-encoding');
95
+ res.statusCode = 304;
96
+ // write nothing
97
+ }
98
+ else
99
+ res.write(bufferOrStream);
100
+ }
101
+ else
102
+ res.write(bufferOrStream);
103
+ }
104
+ else {
105
+ bufferOrStream.pipe(res);
106
+ }
107
+ // we do not support content-encoding (gzip, deflate, br) and leave it to reverse proxy or CDN
108
+ }
109
+ await (0, node_util_1.promisify)(res.end.bind(res))(undefined); // some express middleware, such as express-session, requires explicitly passing chunk
110
+ }
111
+ }
112
+ exports.writeRes = writeRes;
113
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHhIZWxwZXJzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2R4SGVscGVycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFDQSw2Q0FBb0M7QUFDcEMsb0RBQThCO0FBQzlCLHlDQUFtQztBQUNuQyx1Q0FBZ0Q7QUFvQ3pDLEtBQUssVUFBVSxRQUFRLENBQUMsR0FBb0IsRUFBRSxHQUFtQixFQUFFLEVBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsWUFBWSxFQUFFLFdBQVcsRUFBWTtJQUNwSSxNQUFNLGNBQWMsR0FBRyxDQUFDLFdBQW1CLEVBQUUsRUFBRTtRQUM5QyxJQUFJLEdBQUcsQ0FBQyxXQUFXLElBQUksR0FBRyxDQUFDLFNBQVMsQ0FBQyxjQUFjLENBQUM7WUFBRSxPQUFNO1FBQzVELEdBQUcsQ0FBQyxTQUFTLENBQUMsY0FBYyxFQUFFLEdBQUcsV0FBVyxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsYUFBYSxPQUFPLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQTtJQUN4RixDQUFDLENBQUE7SUFDRCxJQUFJLGNBQWMsQ0FBQTtJQUVsQixRQUFRLElBQUksRUFBRSxDQUFDO1FBQ2QsS0FBSyxNQUFNO1lBQ1YsY0FBYyxDQUFDLFlBQVksQ0FBQyxDQUFBO1FBQzdCLEtBQUssTUFBTTtZQUNWLGNBQWMsQ0FBQyxXQUFXLENBQUMsQ0FBQTtZQUMzQixtQkFBbUI7WUFDbkIsY0FBYyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQyxDQUFBO1lBQzNDLE1BQUs7UUFDTixLQUFLLFFBQVE7WUFDWixjQUFjLENBQUMsMEJBQTBCLENBQUMsQ0FBQTtZQUMxQyxjQUFjLEdBQUcsSUFBSSxDQUFBO1lBQ3JCLE1BQUs7UUFDTixLQUFLLFlBQVk7WUFDaEIsY0FBYyxDQUFDLDBCQUEwQixDQUFDLENBQUE7WUFDMUMsY0FBYyxHQUFHLElBQUksQ0FBQTtZ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
package/cjs/express.d.ts CHANGED
@@ -1,4 +1,3 @@
1
- import { type Express, type Request, type Response, type Router } from 'express';
2
- export declare const expressApp: (setup: (app: Express) => any) => Promise<(next: any) => Promise<void>>;
3
- export declare const expressRouter: (setup: (router: Router) => any) => Promise<(next: any) => Promise<void>>;
4
- export declare const expressMiddlewares: (...middlewares: Array<(req: Request, res: Response, next: () => any) => any>) => Promise<(next: any) => Promise<void>>;
1
+ import { type Express, type Router } from 'express';
2
+ export declare function expressApp(setup: (app: Express) => any): Promise<(next: any) => Promise<void>>;
3
+ export declare function expressRouter(setup: (router: Router) => any): Promise<(next: any) => Promise<void>>;
package/cjs/express.js CHANGED
@@ -3,11 +3,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.expressMiddlewares = exports.expressRouter = exports.expressApp = void 0;
6
+ exports.expressRouter = exports.expressApp = void 0;
7
7
  const express_1 = __importDefault(require("express"));
8
8
  const jdefer_1 = __importDefault(require("jdefer"));
9
9
  const dx_js_1 = require("./dx.js");
10
- const expressApp = async (setup) => {
10
+ async function expressApp(setup) {
11
11
  const symbol = Symbol('expressApp');
12
12
  const app = (0, express_1.default)();
13
13
  await setup(app);
@@ -20,9 +20,10 @@ const expressApp = async (setup) => {
20
20
  await defer.promise;
21
21
  await next();
22
22
  };
23
- };
23
+ }
24
24
  exports.expressApp = expressApp;
25
- const expressRouter = async (setup) => {
25
+ // can be used to chain existing Express app
26
+ async function expressRouter(setup) {
26
27
  const symbol = Symbol('expressRouter');
27
28
  const router = express_1.default.Router();
28
29
  await setup(router);
@@ -35,8 +36,6 @@ const expressRouter = async (setup) => {
35
36
  await defer.promise; // if express middleware handles the request, this will never resolve.
36
37
  await next();
37
38
  };
38
- };
39
+ }
39
40
  exports.expressRouter = expressRouter;
40
- const expressMiddlewares = (...middlewares) => (0, exports.expressRouter)(router => router.use(...middlewares));
41
- exports.expressMiddlewares = expressMiddlewares;
42
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhwcmVzcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9leHByZXNzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLHNEQUF1RjtBQUN2RixvREFBOEI7QUFDOUIsbUNBQXNDO0FBRS9CLE1BQU0sVUFBVSxHQUFHLEtBQUssRUFBRSxLQUE0QixFQUFFLEVBQUU7SUFDaEUsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFBO0lBRW5DLE1BQU0sR0FBRyxHQUFHLElBQUEsaUJBQU8sR0FBRSxDQUFBO0lBQ3JCLE1BQU0sS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFBO0lBQ2hCLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUE7SUFDcEQsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFBO0lBQzNELE9BQU8sS0FBSyxFQUFDLElBQUksRUFBQyxFQUFFO1FBQ25CLE1BQU0sS0FBSyxHQUFHLElBQUEsZ0JBQVMsR0FBRSxDQUFBO1FBQ3pCLElBQUEsY0FBTSxHQUFFLENBQUMsTUFBTSxDQUFDLEdBQUcsS0FBSyxDQUFBO1FBQ3hCLEdBQUcsQ0FBQyxJQUFBLGNBQU0sR0FBRSxFQUFFLElBQUEsY0FBTSxHQUFFLENBQUMsQ0FBQTtRQUN2QixNQUFNLEtBQUssQ0FBQyxPQUFPLENBQUE7UUFDbkIsTUFBTSxJQUFJLEVBQUUsQ0FBQTtJQUNiLENBQUMsQ0FBQTtBQUNGLENBQUMsQ0FBQTtBQWRZLFFBQUEsVUFBVSxjQWN0QjtBQUVNLE1BQU0sYUFBYSxHQUFHLEtBQUssRUFBRSxLQUE4QixFQUFFLEVBQUU7SUFDckUsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLGVBQWUsQ0FBQyxDQUFBO0lBRXRDLE1BQU0sTUFBTSxHQUFHLGlCQUFPLENBQUMsTUFBTSxFQUFFLENBQUE7SUFDL0IsTUFBTSxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUE7SUFDbkIsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQTtJQUN2RCxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUE7SUFDOUQsT0FBTyxLQUFLLEVBQUMsSUFBSSxFQUFDLEVBQUU7UUFDbkIsTUFBTSxLQUFLLEdBQUcsSUFBQSxnQkFBUyxHQUFFLENBQUE7UUFDekIsSUFBQSxjQUFNLEdBQUUsQ0FBQyxNQUFNLENBQUMsR0FBRyxLQUFLLENBQUE7UUFDeEIsTUFBTSxDQUFDLElBQUEsY0FBTSxHQUFFLEVBQUUsSUFBQSxjQUFNLEdBQUUsQ0FBQyxDQUFBO1FBQzFCLE1BQU0sS0FBSyxDQUFDLE9BQU8sQ0FBQSxDQUFDLHNFQUFzRTtRQUMxRixNQUFNLElBQUksRUFBRSxDQUFBO0lBQ2IsQ0FBQyxDQUFBO0FBQ0YsQ0FBQyxDQUFBO0FBZFksUUFBQSxhQUFhLGlCQWN6QjtBQUVNLE1BQU0sa0JBQWtCLEdBQUcsQ0FDakMsR0FBRyxXQUF5RSxFQUMzRSxFQUFFLENBQUMsSUFBQSxxQkFBYSxFQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLFdBQVcsQ0FBQyxDQUFDLENBQUE7QUFGM0MsUUFBQSxrQkFBa0Isc0JBRXlCIn0=
41
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhwcmVzcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9leHByZXNzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLHNEQUF1RjtBQUN2RixvREFBOEI7QUFDOUIsbUNBQXNDO0FBRS9CLEtBQUssVUFBVSxVQUFVLENBQUMsS0FBNEI7SUFDNUQsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFBO0lBRW5DLE1BQU0sR0FBRyxHQUFHLElBQUEsaUJBQU8sR0FBRSxDQUFBO0lBQ3JCLE1BQU0sS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFBO0lBQ2hCLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUE7SUFDcEQsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFBO0lBQzNELE9BQU8sS0FBSyxFQUFDLElBQUksRUFBQyxFQUFFO1FBQ25CLE1BQU0sS0FBSyxHQUFHLElBQUEsZ0JBQVMsR0FBRSxDQUFBO1FBQ3pCLElBQUEsY0FBTSxHQUFFLENBQUMsTUFBTSxDQUFDLEdBQUcsS0FBSyxDQUFBO1FBQ3hCLEdBQUcsQ0FBQyxJQUFBLGNBQU0sR0FBRSxFQUFFLElBQUEsY0FBTSxHQUFFLENBQUMsQ0FBQTtRQUN2QixNQUFNLEtBQUssQ0FBQyxPQUFPLENBQUE7UUFDbkIsTUFBTSxJQUFJLEVBQUUsQ0FBQTtJQUNiLENBQUMsQ0FBQTtBQUNGLENBQUM7QUFkRCxnQ0FjQztBQUVELDRDQUE0QztBQUNyQyxLQUFLLFVBQVUsYUFBYSxDQUFDLEtBQThCO0lBQ2pFLE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxlQUFlLENBQUMsQ0FBQTtJQUV0QyxNQUFNLE1BQU0sR0FBRyxpQkFBTyxDQUFDLE1BQU0sRUFBRSxDQUFBO0lBQy9CLE1BQU0sS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFBO0lBQ25CLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUE7SUFDdkQsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFBO0lBQzlELE9BQU8sS0FBSyxFQUFDLElBQUksRUFBQyxFQUFFO1FBQ25CLE1BQU0sS0FBSyxHQUFHLElBQUEsZ0JBQVMsR0FBRSxDQUFBO1FBQ3pCLElBQUEsY0FBTSxHQUFFLENBQUMsTUFBTSxDQUFDLEdBQUcsS0FBSyxDQUFBO1FBQ3hCLE1BQU0sQ0FBQyxJQUFBLGNBQU0sR0FBRSxFQUFFLElBQUEsY0FBTSxHQUFFLENBQUMsQ0FBQTtRQUMxQixNQUFNLEtBQUssQ0FBQyxPQUFPLENBQUEsQ0FBQyxzRUFBc0U7UUFDMUYsTUFBTSxJQUFJLEVBQUUsQ0FBQTtJQUNiLENBQUMsQ0FBQTtBQUNGLENBQUM7QUFkRCxzQ0FjQyJ9
@@ -0,0 +1,2 @@
1
+ export { writeRes } from './dxHelpers.js';
2
+ export { setBufferBodyDefaultOptions, bufferFromReq, jsonFromReq, rawFromReq, textFromReq, urlEncodedFromReq, queryFromReq, } from './bodyHelpers.js';
package/cjs/helpers.js ADDED
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.queryFromReq = exports.urlEncodedFromReq = exports.textFromReq = exports.rawFromReq = exports.jsonFromReq = exports.bufferFromReq = exports.setBufferBodyDefaultOptions = exports.writeRes = void 0;
4
+ var dxHelpers_js_1 = require("./dxHelpers.js");
5
+ Object.defineProperty(exports, "writeRes", { enumerable: true, get: function () { return dxHelpers_js_1.writeRes; } });
6
+ var bodyHelpers_js_1 = require("./bodyHelpers.js");
7
+ Object.defineProperty(exports, "setBufferBodyDefaultOptions", { enumerable: true, get: function () { return bodyHelpers_js_1.setBufferBodyDefaultOptions; } });
8
+ Object.defineProperty(exports, "bufferFromReq", { enumerable: true, get: function () { return bodyHelpers_js_1.bufferFromReq; } });
9
+ Object.defineProperty(exports, "jsonFromReq", { enumerable: true, get: function () { return bodyHelpers_js_1.jsonFromReq; } });
10
+ Object.defineProperty(exports, "rawFromReq", { enumerable: true, get: function () { return bodyHelpers_js_1.rawFromReq; } });
11
+ Object.defineProperty(exports, "textFromReq", { enumerable: true, get: function () { return bodyHelpers_js_1.textFromReq; } });
12
+ Object.defineProperty(exports, "urlEncodedFromReq", { enumerable: true, get: function () { return bodyHelpers_js_1.urlEncodedFromReq; } });
13
+ Object.defineProperty(exports, "queryFromReq", { enumerable: true, get: function () { return bodyHelpers_js_1.queryFromReq; } });
14
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGVscGVycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9oZWxwZXJzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLCtDQUF1QztBQUEvQix3R0FBQSxRQUFRLE9BQUE7QUFDaEIsbURBUXlCO0FBUHhCLDZIQUFBLDJCQUEyQixPQUFBO0FBQzNCLCtHQUFBLGFBQWEsT0FBQTtBQUNiLDZHQUFBLFdBQVcsT0FBQTtBQUNYLDRHQUFBLFVBQVUsT0FBQTtBQUNWLDZHQUFBLFdBQVcsT0FBQTtBQUNYLG1IQUFBLGlCQUFpQixPQUFBO0FBQ2pCLDhHQUFBLFlBQVksT0FBQSJ9
package/cjs/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export { getReq, getRes, setHtml, setNodeStream, setWebStream, setJson, setBuffer, setRedirect, setText } from './dx.js';
2
2
  import { dxServer } from './dx.js';
3
- export { setBufferBodyDefaultOptions, getBuffer, getJson, getRaw, getText, getUrlEncoded, getQuery, } from './body.js';
3
+ export { getJson, getRaw, getText, getUrlEncoded, getQuery, } from './body.js';
4
4
  export { router } from './route.js';
5
+ export { connectMiddlewares } from './connect.js';
5
6
  export default dxServer;
package/cjs/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.router = exports.getQuery = exports.getUrlEncoded = exports.getText = exports.getRaw = exports.getJson = exports.getBuffer = exports.setBufferBodyDefaultOptions = exports.setText = exports.setRedirect = exports.setBuffer = exports.setJson = exports.setWebStream = exports.setNodeStream = exports.setHtml = exports.getRes = exports.getReq = void 0;
3
+ exports.connectMiddlewares = exports.router = exports.getQuery = exports.getUrlEncoded = exports.getText = exports.getRaw = exports.getJson = exports.setText = exports.setRedirect = exports.setBuffer = exports.setJson = exports.setWebStream = exports.setNodeStream = exports.setHtml = exports.getRes = exports.getReq = void 0;
4
4
  var dx_js_1 = require("./dx.js");
5
5
  Object.defineProperty(exports, "getReq", { enumerable: true, get: function () { return dx_js_1.getReq; } });
6
6
  Object.defineProperty(exports, "getRes", { enumerable: true, get: function () { return dx_js_1.getRes; } });
@@ -13,8 +13,6 @@ Object.defineProperty(exports, "setRedirect", { enumerable: true, get: function
13
13
  Object.defineProperty(exports, "setText", { enumerable: true, get: function () { return dx_js_1.setText; } });
14
14
  const dx_js_2 = require("./dx.js");
15
15
  var body_js_1 = require("./body.js");
16
- Object.defineProperty(exports, "setBufferBodyDefaultOptions", { enumerable: true, get: function () { return body_js_1.setBufferBodyDefaultOptions; } });
17
- Object.defineProperty(exports, "getBuffer", { enumerable: true, get: function () { return body_js_1.getBuffer; } });
18
16
  Object.defineProperty(exports, "getJson", { enumerable: true, get: function () { return body_js_1.getJson; } });
19
17
  Object.defineProperty(exports, "getRaw", { enumerable: true, get: function () { return body_js_1.getRaw; } });
20
18
  Object.defineProperty(exports, "getText", { enumerable: true, get: function () { return body_js_1.getText; } });
@@ -22,5 +20,7 @@ Object.defineProperty(exports, "getUrlEncoded", { enumerable: true, get: functio
22
20
  Object.defineProperty(exports, "getQuery", { enumerable: true, get: function () { return body_js_1.getQuery; } });
23
21
  var route_js_1 = require("./route.js");
24
22
  Object.defineProperty(exports, "router", { enumerable: true, get: function () { return route_js_1.router; } });
23
+ var connect_js_1 = require("./connect.js");
24
+ Object.defineProperty(exports, "connectMiddlewares", { enumerable: true, get: function () { return connect_js_1.connectMiddlewares; } });
25
25
  exports.default = dx_js_2.dxServer;
26
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsaUNBVWdCO0FBVGYsK0ZBQUEsTUFBTSxPQUFBO0FBQ04sK0ZBQUEsTUFBTSxPQUFBO0FBQ04sZ0dBQUEsT0FBTyxPQUFBO0FBQ1Asc0dBQUEsYUFBYSxPQUFBO0FBQ2IscUdBQUEsWUFBWSxPQUFBO0FBQ1osZ0dBQUEsT0FBTyxPQUFBO0FBQ1Asa0dBQUEsU0FBUyxPQUFBO0FBQ1Qsb0dBQUEsV0FBVyxPQUFBO0FBQ1gsZ0dBQUEsT0FBTyxPQUFBO0FBRVIsbUNBQWdDO0FBQ2hDLHFDQVFrQjtBQVBqQixzSEFBQSwyQkFBMkIsT0FBQTtBQUMzQixvR0FBQSxTQUFTLE9BQUE7QUFDVCxrR0FBQSxPQUFPLE9BQUE7QUFDUCxpR0FBQSxNQUFNLE9BQUE7QUFDTixrR0FBQSxPQUFPLE9BQUE7QUFDUCx3R0FBQSxhQUFhLE9BQUE7QUFDYixtR0FBQSxRQUFRLE9BQUE7QUFFVCx1Q0FBaUM7QUFBekIsa0dBQUEsTUFBTSxPQUFBO0FBRWQsa0JBQWUsZ0JBQVEsQ0FBQSJ9
26
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsaUNBVWdCO0FBVGYsK0ZBQUEsTUFBTSxPQUFBO0FBQ04sK0ZBQUEsTUFBTSxPQUFBO0FBQ04sZ0dBQUEsT0FBTyxPQUFBO0FBQ1Asc0dBQUEsYUFBYSxPQUFBO0FBQ2IscUdBQUEsWUFBWSxPQUFBO0FBQ1osZ0dBQUEsT0FBTyxPQUFBO0FBQ1Asa0dBQUEsU0FBUyxPQUFBO0FBQ1Qsb0dBQUEsV0FBVyxPQUFBO0FBQ1gsZ0dBQUEsT0FBTyxPQUFBO0FBRVIsbUNBQWdDO0FBQ2hDLHFDQU1rQjtBQUxqQixrR0FBQSxPQUFPLE9BQUE7QUFDUCxpR0FBQSxNQUFNLE9BQUE7QUFDTixrR0FBQSxPQUFPLE9BQUE7QUFDUCx3R0FBQSxhQUFhLE9BQUE7QUFDYixtR0FBQSxRQUFRLE9BQUE7QUFFVCx1Q0FBaUM7QUFBekIsa0dBQUEsTUFBTSxPQUFBO0FBQ2QsMkNBQStDO0FBQXZDLGdIQUFBLGtCQUFrQixPQUFBO0FBRTFCLGtCQUFlLGdCQUFRLENBQUEifQ==
package/esm/body.d.ts CHANGED
@@ -1,15 +1,8 @@
1
- interface BufferBodyOptions {
2
- limit: number;
3
- }
4
- export declare function setBufferBodyDefaultOptions(options: Partial<BufferBodyOptions>): void;
5
- export declare function getBuffer(options?: Partial<BufferBodyOptions>): Promise<any>;
1
+ import { BufferBodyOptions } from './bodyHelpers.js';
6
2
  export declare function getJson(options?: Partial<BufferBodyOptions>): Promise<any>;
7
3
  export declare function getRaw(options?: Partial<BufferBodyOptions>): Promise<any>;
8
4
  export declare function getText(options?: Partial<BufferBodyOptions>): Promise<any>;
9
- export declare function getUrlEncoded({ simplify, ...options }?: Partial<BufferBodyOptions> & {
10
- simplify?: boolean;
11
- }): Promise<any>;
5
+ export declare function getUrlEncoded(options: Partial<BufferBodyOptions>): Promise<any>;
12
6
  export declare function getQuery({ simplify, ...options }?: Partial<BufferBodyOptions> & {
13
7
  simplify?: boolean;
14
8
  }): Promise<any>;
15
- export {};
package/esm/body.js CHANGED
@@ -1,114 +1,27 @@
1
- import { getContentStream, readStream } from './stream.js';
2
- import { parse } from 'qs';
3
- import { parseContentType } from './contentType.js';
4
1
  import { getReq } from './dx.js';
5
- let bufferBodyDefaultOptions = { limit: 100 << 10 }; // 100kb
6
- export function setBufferBodyDefaultOptions(options) {
7
- bufferBodyDefaultOptions = { ...bufferBodyDefaultOptions, ...options };
8
- }
2
+ import { bufferFromReq, jsonFromReq, queryFromReq, rawFromReq, textFromReq, urlEncodedFromReq } from './bodyHelpers.js';
9
3
  const bufferBodySymbol = Symbol('bufferBody');
10
- export async function getBuffer(options) {
11
- const { limit } = { ...bufferBodyDefaultOptions, ...options };
12
- const req = getReq();
13
- return req[bufferBodySymbol] ??= (async () => {
14
- /**
15
- * Check if a request has a request body.
16
- * A request with a body __must__ either have `transfer-encoding`
17
- * or `content-length` headers set.
18
- * http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.3
19
- */
20
- // https://github.com/jshttp/type-is/blob/cdcfe23e9833872e425b0aaf71ca0311373b6116/index.js#L92
21
- const contentLengthParsed = parseInt(req.headers['content-length'] ?? '', 10);
22
- if (req.headers['transfer-encoding'] === undefined
23
- && isNaN(contentLengthParsed))
24
- return;
25
- const contentLength = isNaN(contentLengthParsed) ? undefined : contentLengthParsed;
26
- // read
27
- const encoding = (req.headers['content-encoding'] ?? 'identity').toLowerCase();
28
- const stream = getContentStream(req, encoding);
29
- return await readStream(stream, {
30
- length: encoding === 'identity' ? contentLength : undefined,
31
- limit,
32
- });
33
- })();
34
- }
35
- // if content-type is not as expected, return undefined
36
- function forceGetContentTypeParams(expected) {
37
- const req = getReq();
38
- const contentTypeRaw = req.headers['content-type'];
39
- if (!contentTypeRaw)
40
- return;
41
- const { mediaType, parameters } = parseContentType(contentTypeRaw);
42
- if (mediaType !== expected)
43
- return;
44
- return parameters;
45
- }
46
- function forceGetCharset(expected) {
47
- const parameters = forceGetContentTypeParams(expected);
48
- if (!parameters)
49
- return;
50
- // assert charset per RFC 7159 sec 8.1
51
- const charset = parameters.charset?.toLowerCase() || 'utf-8';
52
- if (!charset.startsWith('utf-'))
53
- throw new Error(`unsupported charset "${charset.toUpperCase()}"`);
54
- return charset;
4
+ async function getBuffer(options) {
5
+ return getReq()[bufferBodySymbol] ??= bufferFromReq(getReq(), options);
55
6
  }
56
7
  const jsonBodySymbol = Symbol('jsonBody');
57
8
  export async function getJson(options) {
58
- return getReq()[jsonBodySymbol] ??= (async () => {
59
- const charset = forceGetCharset('application/json');
60
- if (!charset)
61
- return;
62
- const buffer = await getBuffer(options);
63
- if (buffer) {
64
- const str = buffer.toString(charset);
65
- return str ? JSON.parse(str) : undefined;
66
- }
67
- })();
9
+ return getReq()[jsonBodySymbol] ??= jsonFromReq(getReq(), options);
68
10
  }
69
11
  const rawBodySymbol = Symbol('rawBody');
70
12
  export async function getRaw(options) {
71
- return getReq()[rawBodySymbol] ??= (async () => {
72
- if (!forceGetContentTypeParams('application/octet-stream'))
73
- return;
74
- return await getBuffer(options);
75
- })();
13
+ return getReq()[rawBodySymbol] ??= rawFromReq(getReq(), options);
76
14
  }
77
15
  const textBodySymbol = Symbol('textBody');
78
16
  export async function getText(options) {
79
- return getReq()[textBodySymbol] ??= (async () => {
80
- const charset = forceGetCharset('text/plain');
81
- if (!charset)
82
- return;
83
- const buffer = await getBuffer(options);
84
- if (buffer)
85
- return buffer.toString(charset);
86
- })();
17
+ return getReq()[textBodySymbol] ??= textFromReq(getReq(), options);
87
18
  }
88
19
  const urlEncodedBodySymbol = Symbol('urlencodedBody');
89
- export async function getUrlEncoded({ simplify, ...options } = {}) {
90
- return getReq()[urlEncodedBodySymbol] ??= (async () => {
91
- const charset = forceGetCharset('application/x-www-form-urlencoded');
92
- if (!charset)
93
- return;
94
- const buffer = await getBuffer(options);
95
- if (buffer) {
96
- const str = buffer.toString(charset);
97
- return simplify
98
- ? Object.fromEntries(new URLSearchParams(str))
99
- : parse(str);
100
- }
101
- })();
20
+ export async function getUrlEncoded(options) {
21
+ return getReq()[urlEncodedBodySymbol] ??= urlEncodedFromReq(getReq(), options);
102
22
  }
103
23
  const querySymbol = Symbol('query');
104
24
  export async function getQuery({ simplify, ...options } = {}) {
105
- return getReq()[querySymbol] ??= (async () => {
106
- const query = getReq().url?.split('?', 2)?.[1];
107
- return query
108
- ? simplify
109
- ? Object.fromEntries(new URLSearchParams(query))
110
- : parse(query)
111
- : {};
112
- })();
25
+ return getReq()[querySymbol] ??= queryFromReq(getReq(), options);
113
26
  }
114
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYm9keS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9ib2R5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBQyxnQkFBZ0IsRUFBRSxVQUFVLEVBQUMsTUFBTSxhQUFhLENBQUE7QUFDeEQsT0FBTyxFQUFDLEtBQUssRUFBQyxNQUFNLElBQUksQ0FBQTtBQUN4QixPQUFPLEVBQUMsZ0JBQWdCLEVBQUMsTUFBTSxrQkFBa0IsQ0FBQTtBQUNqRCxPQUFPLEVBQUMsTUFBTSxFQUFDLE1BQU0sU0FBUyxDQUFBO0FBSzlCLElBQUksd0JBQXdCLEdBQXNCLEVBQUMsS0FBSyxFQUFFLEdBQUcsSUFBSSxFQUFFLEVBQUMsQ0FBQSxDQUFDLFFBQVE7QUFDN0UsTUFBTSxVQUFVLDJCQUEyQixDQUFDLE9BQW1DO0lBQzlFLHdCQUF3QixHQUFHLEVBQUMsR0FBRyx3QkFBd0IsRUFBRSxHQUFHLE9BQU8sRUFBQyxDQUFBO0FBQ3JFLENBQUM7QUFDRCxNQUFNLGdCQUFnQixHQUFHLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQTtBQUM3QyxNQUFNLENBQUMsS0FBSyxVQUFVLFNBQVMsQ0FBQyxPQUFvQztJQUNuRSxNQUFNLEVBQUMsS0FBSyxFQUFDLEdBQUcsRUFBQyxHQUFHLHdCQUF3QixFQUFFLEdBQUcsT0FBTyxFQUFDLENBQUE7SUFDekQsTUFBTSxHQUFHLEdBQUcsTUFBTSxFQUFFLENBQUE7SUFDcEIsT0FBTyxHQUFHLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxDQUFDLEtBQUssSUFBSSxFQUFFO1FBQzVDOzs7OztXQUtHO1FBQ0YsK0ZBQStGO1FBQ2hHLE1BQU0sbUJBQW1CLEdBQUcsUUFBUSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUE7UUFDN0UsSUFDQyxHQUFHLENBQUMsT0FBTyxDQUFDLG1CQUFtQixDQUFDLEtBQUssU0FBUztlQUMzQyxLQUFLLENB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
27
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYm9keS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9ib2R5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBQyxNQUFNLEVBQUMsTUFBTSxTQUFTLENBQUE7QUFDOUIsT0FBTyxFQUVOLGFBQWEsRUFDYixXQUFXLEVBQ1gsWUFBWSxFQUNaLFVBQVUsRUFDVixXQUFXLEVBQ1gsaUJBQWlCLEVBQ2pCLE1BQU0sa0JBQWtCLENBQUE7QUFFekIsTUFBTSxnQkFBZ0IsR0FBRyxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUE7QUFDN0MsS0FBSyxVQUFVLFNBQVMsQ0FBQyxPQUFvQztJQUM1RCxPQUFPLE1BQU0sRUFBRSxDQUFDLGdCQUFnQixDQUFDLEtBQUssYUFBYSxDQUFDLE1BQU0sRUFBRSxFQUFFLE9BQU8sQ0FBQyxDQUFBO0FBQ3ZFLENBQUM7QUFFRCxNQUFNLGNBQWMsR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUE7QUFDekMsTUFBTSxDQUFDLEtBQUssVUFBVSxPQUFPLENBQUMsT0FBb0M7SUFDakUsT0FBTyxNQUFNLEVBQUUsQ0FBQyxjQUFjLENBQUMsS0FBSyxXQUFXLENBQUMsTUFBTSxFQUFFLEVBQUUsT0FBTyxDQUFDLENBQUE7QUFDbkUsQ0FBQztBQUVELE1BQU0sYUFBYSxHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQTtBQUN2QyxNQUFNLENBQUMsS0FBSyxVQUFVLE1BQU0sQ0FBQyxPQUFvQztJQUNoRSxPQUFPLE1BQU0sRUFBRSxDQUFDLGFBQWEsQ0FBQyxLQUFLLFVBQVUsQ0FBQyxNQUFNLEVBQUUsRUFBRSxPQUFPLENBQUMsQ0FBQTtBQUNqRSxDQUFDO0FBRUQsTUFBTSxjQUFjLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFBO0FBQ3pDLE1BQU0sQ0FBQyxLQUFLLFVBQVUsT0FBTyxDQUFDLE9BQW9DO0lBQ2pFLE9BQU8sTUFBTSxFQUFFLENBQUMsY0FBYyxDQUFDLEtBQUssV0FBVyxDQUFDLE1BQU0sRUFBRSxFQUFFLE9BQU8sQ0FBQyxDQUFBO0FBQ25FLENBQUM7QUFFRCxNQUFNLG9CQUFvQixHQUFHLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFBO0FBQ3JELE1BQU0sQ0FBQyxLQUFLLFVBQVUsYUFBYSxDQUFDLE9BQW1DO0lBQ3RFLE9BQU8sTUFBTSxFQUFFLENBQUMsb0JBQW9CLENBQUMsS0FBSyxpQkFBaUIsQ0FBQyxNQUFNLEVBQUUsRUFBRSxPQUFPLENBQUMsQ0FBQTtBQUMvRSxDQUFDO0FBRUQsTUFBTSxXQUFXLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFBO0FBQ25DLE1BQU0sQ0FBQyxLQUFLLFVBQVUsUUFBUSxDQUFDLEVBQUMsUUFBUSxFQUFFLEdBQUcsT0FBTyxLQUF1RCxFQUFFO0lBQzVHLE9BQU8sTUFBTSxFQUFFLENBQUMsV0FBVyxDQUFDLEtBQUssWUFBWSxDQUFDLE1BQU0sRUFBRSxFQUFFLE9BQU8sQ0FBQyxDQUFBO0FBQ2pFLENBQUMifQ==
@@ -0,0 +1,16 @@
1
+ /// <reference types="node" resolution-mode="require"/>
2
+ /// <reference types="node" resolution-mode="require"/>
3
+ import { IncomingMessage } from 'node:http';
4
+ import qs from 'qs';
5
+ export interface BufferBodyOptions {
6
+ bodyLimit: number;
7
+ simplifyUrlEncodedBody?: boolean;
8
+ simplifyQuery?: boolean;
9
+ }
10
+ export declare function setBufferBodyDefaultOptions(options: Partial<BufferBodyOptions>): void;
11
+ export declare function bufferFromReq(req: IncomingMessage, options?: Partial<BufferBodyOptions>): Promise<Buffer | undefined>;
12
+ export declare function jsonFromReq(req: IncomingMessage, options?: Partial<BufferBodyOptions>): Promise<any>;
13
+ export declare function rawFromReq(req: IncomingMessage, options?: Partial<BufferBodyOptions>): Promise<Buffer | undefined>;
14
+ export declare function textFromReq(req: IncomingMessage, options?: Partial<BufferBodyOptions>): Promise<string | undefined>;
15
+ export declare function urlEncodedFromReq(req: IncomingMessage, options?: Partial<BufferBodyOptions>): Promise<qs.ParsedQs | undefined>;
16
+ export declare function queryFromReq(req: IncomingMessage, options?: Partial<BufferBodyOptions>): Promise<qs.ParsedQs>;
@@ -0,0 +1,89 @@
1
+ import { getContentStream, readStream } from './stream.js';
2
+ import { parseContentType } from './contentType.js';
3
+ import qs from 'qs';
4
+ let bodyDefaultOptions = { bodyLimit: 100 << 10 }; // 100kb
5
+ export function setBufferBodyDefaultOptions(options) {
6
+ bodyDefaultOptions = { ...bodyDefaultOptions, ...options };
7
+ }
8
+ export async function bufferFromReq(req, options) {
9
+ const { bodyLimit } = { ...bodyDefaultOptions, ...options };
10
+ /**
11
+ * Check if a request has a request body.
12
+ * A request with a body __must__ either have `transfer-encoding`
13
+ * or `content-length` headers set.
14
+ * http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.3
15
+ */
16
+ // https://github.com/jshttp/type-is/blob/cdcfe23e9833872e425b0aaf71ca0311373b6116/index.js#L92
17
+ const contentLengthParsed = parseInt(req.headers['content-length'] ?? '', 10);
18
+ if (req.headers['transfer-encoding'] === undefined
19
+ && isNaN(contentLengthParsed))
20
+ return;
21
+ const contentLength = isNaN(contentLengthParsed) ? undefined : contentLengthParsed;
22
+ // read
23
+ const encoding = (req.headers['content-encoding'] ?? 'identity').toLowerCase();
24
+ const stream = getContentStream(req, encoding);
25
+ return await readStream(stream, {
26
+ length: encoding === 'identity' ? contentLength : undefined,
27
+ limit: bodyLimit,
28
+ });
29
+ }
30
+ // if content-type is not as expected, return undefined
31
+ function forceGetContentTypeParams(req, expected) {
32
+ const contentTypeRaw = req.headers['content-type'];
33
+ if (!contentTypeRaw)
34
+ return;
35
+ const { mediaType, parameters } = parseContentType(contentTypeRaw);
36
+ if (mediaType !== expected)
37
+ return;
38
+ return parameters;
39
+ }
40
+ function forceGetCharset(req, expected) {
41
+ const parameters = forceGetContentTypeParams(req, expected);
42
+ if (!parameters)
43
+ return;
44
+ // assert charset per RFC 7159 sec 8.1
45
+ const charset = parameters.charset?.toLowerCase() || 'utf-8';
46
+ if (!charset.startsWith('utf-'))
47
+ throw new Error(`unsupported charset "${charset.toUpperCase()}"`);
48
+ return charset;
49
+ }
50
+ export async function jsonFromReq(req, options) {
51
+ const charset = forceGetCharset(req, 'application/json');
52
+ if (!charset)
53
+ return;
54
+ const buffer = await bufferFromReq(req, options);
55
+ if (buffer) {
56
+ const str = buffer.toString(charset);
57
+ return str ? JSON.parse(str) : undefined;
58
+ }
59
+ }
60
+ export async function rawFromReq(req, options) {
61
+ if (!forceGetContentTypeParams(req, 'application/octet-stream'))
62
+ return;
63
+ return await bufferFromReq(req, options);
64
+ }
65
+ export async function textFromReq(req, options) {
66
+ const charset = forceGetCharset(req, 'text/plain');
67
+ if (!charset)
68
+ return;
69
+ const buffer = await bufferFromReq(req, options);
70
+ if (buffer)
71
+ return buffer.toString(charset);
72
+ }
73
+ export async function urlEncodedFromReq(req, options) {
74
+ const charset = forceGetCharset(req, 'application/x-www-form-urlencoded');
75
+ if (!charset)
76
+ return;
77
+ const buffer = await bufferFromReq(req, options);
78
+ if (buffer) {
79
+ const str = buffer.toString(charset);
80
+ const { simplifyUrlEncodedBody } = { ...bodyDefaultOptions, ...options };
81
+ return simplifyUrlEncodedBody ? Object.fromEntries(new URLSearchParams(str)) : qs.parse(str);
82
+ }
83
+ }
84
+ export async function queryFromReq(req, options) {
85
+ const query = new URL(req.url ?? '', 'https://example.com').searchParams.toString();
86
+ const { simplifyQuery } = { ...bodyDefaultOptions, ...options };
87
+ return simplifyQuery ? Object.fromEntries(new URLSearchParams(query)) : qs.parse(query);
88
+ }
89
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYm9keUhlbHBlcnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvYm9keUhlbHBlcnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFDLGdCQUFnQixFQUFFLFVBQVUsRUFBQyxNQUFNLGFBQWEsQ0FBQTtBQUN4RCxPQUFPLEVBQUMsZ0JBQWdCLEVBQUMsTUFBTSxrQkFBa0IsQ0FBQTtBQUNqRCxPQUFPLEVBQUUsTUFBTSxJQUFJLENBQUE7QUFRbkIsSUFBSSxrQkFBa0IsR0FBc0IsRUFBQyxTQUFTLEVBQUUsR0FBRyxJQUFJLEVBQUUsRUFBQyxDQUFBLENBQUMsUUFBUTtBQUMzRSxNQUFNLFVBQVUsMkJBQTJCLENBQUMsT0FBbUM7SUFDOUUsa0JBQWtCLEdBQUcsRUFBQyxHQUFHLGtCQUFrQixFQUFFLEdBQUcsT0FBTyxFQUFDLENBQUE7QUFDekQsQ0FBQztBQUVELE1BQU0sQ0FBQyxLQUFLLFVBQVUsYUFBYSxDQUFDLEdBQW9CLEVBQUUsT0FBb0M7SUFDN0YsTUFBTSxFQUFDLFNBQVMsRUFBQyxHQUFHLEVBQUMsR0FBRyxrQkFBa0IsRUFBRSxHQUFHLE9BQU8sRUFBQyxDQUFBO0lBQ3ZEOzs7OztPQUtHO0lBQ0YsK0ZBQStGO0lBQ2hHLE1BQU0sbUJBQW1CLEdBQUcsUUFBUSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUE7SUFDN0UsSUFDQyxHQUFHLENBQUMsT0FBTyxDQUFDLG1CQUFtQixDQUFDLEtBQUssU0FBUztXQUMzQyxLQUFLLENBQUMsbUJBQW1CLENBQUM7UUFDNUIsT0FBTTtJQUNSLE1BQU0sYUFBYSxHQUFHLEtBQUssQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLG1CQUFtQixDQUFBO0lBRWxGLE9BQU87SUFDUCxNQUFNLFFBQVEsR0FBRyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENB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
@@ -0,0 +1,4 @@
1
+ /// <reference types="node" resolution-mode="require"/>
2
+ import type { IncomingMessage, ServerResponse } from 'node:http';
3
+ import { Chainable } from './dx.js';
4
+ export declare function connectMiddlewares(...middlewares: Array<(req: IncomingMessage, res: ServerResponse, next: () => any) => any>): Chainable;
package/esm/connect.js ADDED
@@ -0,0 +1,40 @@
1
+ import { getReq, getRes } from './dx.js';
2
+ import makeDefer from 'jdefer';
3
+ // support async middleware
4
+ // do not support error middleware (the one with 4 arguments)
5
+ export function connectMiddlewares(...middlewares) {
6
+ return next => {
7
+ const req = getReq();
8
+ const res = getRes();
9
+ const defer = makeDefer();
10
+ // because middleware usually not return next() or await to next(),
11
+ // the next passed to the middleware must be resilient to error (never throw or reject)
12
+ middlewares.reduceRight((connectNext, middleware) => async (error) => {
13
+ // this function must not throw or reject
14
+ if (error !== undefined && error !== null)
15
+ return defer.reject(error);
16
+ try {
17
+ return await middleware(req, res, connectNext);
18
+ }
19
+ catch (err) {
20
+ return defer.reject(err);
21
+ }
22
+ }, async () => {
23
+ // next might throw error synchronously and be swallowed by some async middleware unless we wrap it here
24
+ try {
25
+ return defer.resolve(await next());
26
+ }
27
+ catch (err) {
28
+ return defer.reject(err);
29
+ }
30
+ })(); // no need to await result from this call because it will never reject
31
+ return defer.promise;
32
+ // let i = 0
33
+ // const run = async () => {
34
+ // if (i === middlewares.length) return next()
35
+ // await middlewares[i++](req, res, run)
36
+ // }
37
+ // await run()
38
+ };
39
+ }
40
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29ubmVjdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9jb25uZWN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFBWSxNQUFNLEVBQUUsTUFBTSxFQUFDLE1BQU0sU0FBUyxDQUFBO0FBQ2pELE9BQU8sU0FBUyxNQUFNLFFBQVEsQ0FBQTtBQUU5QiwyQkFBMkI7QUFDM0IsNkRBQTZEO0FBQzdELE1BQU0sVUFBVSxrQkFBa0IsQ0FDakMsR0FBRyxXQUF1RjtJQUUxRixPQUFPLElBQUksQ0FBQyxFQUFFO1FBQ2IsTUFBTSxHQUFHLEdBQUcsTUFBTSxFQUFFLENBQUE7UUFDcEIsTUFBTSxHQUFHLEdBQUcsTUFBTSxFQUFFLENBQUE7UUFDcEIsTUFBTSxLQUFLLEdBQUcsU0FBUyxFQUFFLENBQUE7UUFDekIsbUVBQW1FO1FBQ25FLHVGQUF1RjtRQUN2RixXQUFXLENBQUMsV0FBVyxDQUN0QixDQUFDLFdBQVcsRUFBRSxVQUFVLEVBQUUsRUFBRSxDQUFDLEtBQUssRUFBRSxLQUFXLEVBQUUsRUFBRTtZQUNsRCx5Q0FBeUM7WUFDekMsSUFBSSxLQUFLLEtBQUssU0FBUyxJQUFJLEtBQUssS0FBSyxJQUFJO2dCQUFFLE9BQU8sS0FBSyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQTtZQUNyRSxJQUFJLENBQUM7Z0JBQUEsT0FBTyxNQUFNLFVBQVUsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLFdBQVcsQ0FBQyxDQUFBO1lBQUEsQ0FBQztZQUNwRCxPQUFPLEdBQUcsRUFBRSxDQUFDO2dCQUFBLE9BQU8sS0FBSyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQTtZQUFBLENBQUM7UUFDdkMsQ0FBQyxFQUNELEtBQUssSUFBSSxFQUFFO1lBQ1Ysd0dBQXdHO1lBQ3hHLElBQUksQ0FBQztnQkFDSixPQUFPLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxJQUFJLEVBQUUsQ0FBQyxDQUFBO1lBQ25DLENBQUM7WUFBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO2dCQUNkLE9BQU8sS0FBSyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQTtZQUN6QixDQUFDO1FBQ0YsQ0FBQyxDQUNELEVBQUUsQ0FBQSxDQUFDLHNFQUFzRTtRQUMxRSxPQUFPLEtBQUssQ0FBQyxPQUFPLENBQUE7UUFDcEIsWUFBWTtRQUNaLDRCQUE0QjtRQUM1QiwrQ0FBK0M7UUFDL0MseUNBQXlDO1FBQ3pDLElBQUk7UUFDSixjQUFjO0lBQ2YsQ0FBQyxDQUFBO0FBQ0YsQ0FBQyJ9
package/esm/dx.d.ts CHANGED
@@ -3,7 +3,7 @@
3
3
  /// <reference types="node" resolution-mode="require"/>
4
4
  import { Readable } from 'node:stream';
5
5
  import type { IncomingMessage, ServerResponse } from 'node:http';
6
- interface Chainable<P extends any[] = any[], R = any, Next = (...np: any[]) => any> {
6
+ export interface Chainable<P extends any[] = any[], R = any, Next = (...np: any[]) => any> {
7
7
  (next: Next, ...p: P): R;
8
8
  }
9
9
  export declare function dxServer(req: IncomingMessage, res: ServerResponse, options?: {
@@ -27,9 +27,7 @@ export declare function setNodeStream(stream: Readable, { status }?: {
27
27
  export declare function setWebStream(stream: ReadableStream, { status }?: {
28
28
  status?: number;
29
29
  }): void;
30
- export declare function setJson(json: any, { status, beautify }?: {
30
+ export declare function setJson(json: any, { status }?: {
31
31
  status?: number;
32
- beautify?: boolean;
33
32
  }): void;
34
33
  export declare function setRedirect(url: string, status: 301 | 302): void;
35
- export {};