dx-server 0.0.7 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/cjs/index.js CHANGED
@@ -1,17 +1,17 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.chainExpressMiddlewares = exports.expressRouter = exports.expressApp = exports.router = exports.urlencodedBodyContext = exports.textBodyContext = exports.rawBodyContext = exports.queryContext = exports.jsonBodyContext = exports.bufferBodyContext = exports.setText = exports.setRedirect = exports.setBuffer = exports.setJson = exports.setHtml = exports.expressContext = exports.responseContext = exports.requestContext = exports.makeContext = void 0;
3
+ exports.router = exports.urlencodedBodyContext = exports.textBodyContext = exports.rawBodyContext = exports.queryContext = exports.jsonBodyContext = exports.bufferBodyContext = exports.setText = exports.setRedirect = exports.setBuffer = exports.setJson = exports.setHtml = exports.dxContext = exports.responseContext = exports.requestContext = exports.makeContext = void 0;
4
4
  var context_js_1 = require("./context.js");
5
5
  Object.defineProperty(exports, "makeContext", { enumerable: true, get: function () { return context_js_1.makeContext; } });
6
6
  Object.defineProperty(exports, "requestContext", { enumerable: true, get: function () { return context_js_1.requestContext; } });
7
7
  Object.defineProperty(exports, "responseContext", { enumerable: true, get: function () { return context_js_1.responseContext; } });
8
- var express_js_1 = require("./express.js");
9
- Object.defineProperty(exports, "expressContext", { enumerable: true, get: function () { return express_js_1.expressContext; } });
10
- Object.defineProperty(exports, "setHtml", { enumerable: true, get: function () { return express_js_1.setHtml; } });
11
- Object.defineProperty(exports, "setJson", { enumerable: true, get: function () { return express_js_1.setJson; } });
12
- Object.defineProperty(exports, "setBuffer", { enumerable: true, get: function () { return express_js_1.setBuffer; } });
13
- Object.defineProperty(exports, "setRedirect", { enumerable: true, get: function () { return express_js_1.setRedirect; } });
14
- Object.defineProperty(exports, "setText", { enumerable: true, get: function () { return express_js_1.setText; } });
8
+ var dx_js_1 = require("./dx.js");
9
+ Object.defineProperty(exports, "dxContext", { enumerable: true, get: function () { return dx_js_1.dxContext; } });
10
+ Object.defineProperty(exports, "setHtml", { enumerable: true, get: function () { return dx_js_1.setHtml; } });
11
+ Object.defineProperty(exports, "setJson", { enumerable: true, get: function () { return dx_js_1.setJson; } });
12
+ Object.defineProperty(exports, "setBuffer", { enumerable: true, get: function () { return dx_js_1.setBuffer; } });
13
+ Object.defineProperty(exports, "setRedirect", { enumerable: true, get: function () { return dx_js_1.setRedirect; } });
14
+ Object.defineProperty(exports, "setText", { enumerable: true, get: function () { return dx_js_1.setText; } });
15
15
  var body_js_1 = require("./body.js");
16
16
  Object.defineProperty(exports, "bufferBodyContext", { enumerable: true, get: function () { return body_js_1.bufferBodyContext; } });
17
17
  Object.defineProperty(exports, "jsonBodyContext", { enumerable: true, get: function () { return body_js_1.jsonBodyContext; } });
@@ -21,8 +21,4 @@ Object.defineProperty(exports, "textBodyContext", { enumerable: true, get: funct
21
21
  Object.defineProperty(exports, "urlencodedBodyContext", { enumerable: true, get: function () { return body_js_1.urlencodedBodyContext; } });
22
22
  var route_js_1 = require("./route.js");
23
23
  Object.defineProperty(exports, "router", { enumerable: true, get: function () { return route_js_1.router; } });
24
- var expressApp_js_1 = require("./expressApp.js");
25
- Object.defineProperty(exports, "expressApp", { enumerable: true, get: function () { return expressApp_js_1.expressApp; } });
26
- Object.defineProperty(exports, "expressRouter", { enumerable: true, get: function () { return expressApp_js_1.expressRouter; } });
27
- Object.defineProperty(exports, "chainExpressMiddlewares", { enumerable: true, get: function () { return expressApp_js_1.chainExpressMiddlewares; } });
28
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsMkNBQXlFO0FBQWpFLHlHQUFBLFdBQVcsT0FBQTtBQUFFLDRHQUFBLGNBQWMsT0FBQTtBQUFFLDZHQUFBLGVBQWUsT0FBQTtBQUNwRCwyQ0FPcUI7QUFOcEIsNEdBQUEsY0FBYyxPQUFBO0FBQ2QscUdBQUEsT0FBTyxPQUFBO0FBQ1AscUdBQUEsT0FBTyxPQUFBO0FBQ1AsdUdBQUEsU0FBUyxPQUFBO0FBQ1QseUdBQUEsV0FBVyxPQUFBO0FBQ1gscUdBQUEsT0FBTyxPQUFBO0FBRVIscUNBT2tCO0FBTmpCLDRHQUFBLGlCQUFpQixPQUFBO0FBQ2pCLDBHQUFBLGVBQWUsT0FBQTtBQUNmLHVHQUFBLFlBQVksT0FBQTtBQUNaLHlHQUFBLGNBQWMsT0FBQTtBQUNkLDBHQUFBLGVBQWUsT0FBQTtBQUNmLGdIQUFBLHFCQUFxQixPQUFBO0FBRXRCLHVDQUFpQztBQUF6QixrR0FBQSxNQUFNLE9BQUE7QUFDZCxpREFBa0Y7QUFBMUUsMkdBQUEsVUFBVSxPQUFBO0FBQUUsOEdBQUEsYUFBYSxPQUFBO0FBQUUsd0hBQUEsdUJBQXVCLE9BQUEifQ==
24
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsMkNBQXlFO0FBQWpFLHlHQUFBLFdBQVcsT0FBQTtBQUFFLDRHQUFBLGNBQWMsT0FBQTtBQUFFLDZHQUFBLGVBQWUsT0FBQTtBQUNwRCxpQ0FPZ0I7QUFOZixrR0FBQSxTQUFTLE9BQUE7QUFDVCxnR0FBQSxPQUFPLE9BQUE7QUFDUCxnR0FBQSxPQUFPLE9BQUE7QUFDUCxrR0FBQSxTQUFTLE9BQUE7QUFDVCxvR0FBQSxXQUFXLE9BQUE7QUFDWCxnR0FBQSxPQUFPLE9BQUE7QUFFUixxQ0FPa0I7QUFOakIsNEdBQUEsaUJBQWlCLE9BQUE7QUFDakIsMEdBQUEsZUFBZSxPQUFBO0FBQ2YsdUdBQUEsWUFBWSxPQUFBO0FBQ1oseUdBQUEsY0FBYyxPQUFBO0FBQ2QsMEdBQUEsZUFBZSxPQUFBO0FBQ2YsZ0hBQUEscUJBQXFCLE9BQUE7QUFFdEIsdUNBQWlDO0FBQXpCLGtHQUFBLE1BQU0sT0FBQSJ9
package/esm/dx.d.ts ADDED
@@ -0,0 +1,81 @@
1
+ /// <reference types="node" resolution-mode="require"/>
2
+ /// <reference types="node" resolution-mode="require"/>
3
+ import { Readable } from 'node:stream';
4
+ export declare const dxContext: {
5
+ readonly value: {
6
+ charset?: BufferEncoding | undefined;
7
+ jsonBeautify?: boolean | undefined;
8
+ disableEtag?: boolean | undefined;
9
+ } & ({
10
+ type: 'text';
11
+ data: string;
12
+ } | {
13
+ type: 'html';
14
+ data: string;
15
+ } | {
16
+ type: 'buffer';
17
+ data: Buffer;
18
+ } | {
19
+ type: 'json';
20
+ data: any;
21
+ } | {
22
+ type: 'redirect';
23
+ data: string;
24
+ } | {
25
+ type: 'nodeStream';
26
+ data: Readable;
27
+ } | {
28
+ type: 'webStream';
29
+ data: ReadableStream;
30
+ });
31
+ chain(params_0?: {
32
+ jsonBeautify?: boolean | undefined;
33
+ disableEtag?: boolean | undefined;
34
+ } | undefined): <V>(next: () => V) => Promise<any>;
35
+ with(value: {
36
+ charset?: BufferEncoding | undefined;
37
+ jsonBeautify?: boolean | undefined;
38
+ disableEtag?: boolean | undefined;
39
+ } & ({
40
+ type: 'text';
41
+ data: string;
42
+ } | {
43
+ type: 'html';
44
+ data: string;
45
+ } | {
46
+ type: 'buffer';
47
+ data: Buffer;
48
+ } | {
49
+ type: 'json';
50
+ data: any;
51
+ } | {
52
+ type: 'redirect';
53
+ data: string;
54
+ } | {
55
+ type: 'nodeStream';
56
+ data: Readable;
57
+ } | {
58
+ type: 'webStream';
59
+ data: ReadableStream;
60
+ })): <V_1>(next: () => V_1) => Promise<any>;
61
+ };
62
+ export declare function setText(text: string, { status }?: {
63
+ status?: number;
64
+ }): void;
65
+ export declare function setHtml(html: string, opts?: {
66
+ status?: number;
67
+ }): void;
68
+ export declare function setBuffer(buffer: Buffer, { status }?: {
69
+ status?: number;
70
+ }): void;
71
+ export declare function setNodeStream(stream: Readable, { status }?: {
72
+ status?: number;
73
+ }): void;
74
+ export declare function setWebStream(stream: ReadableStream, { status }?: {
75
+ status?: number;
76
+ }): void;
77
+ export declare function setJson(json: any, { status, beautify }?: {
78
+ status?: number;
79
+ beautify?: boolean;
80
+ }): void;
81
+ export declare function setRedirect(url: string, status: 301 | 302): void;
package/esm/dx.js ADDED
@@ -0,0 +1,170 @@
1
+ import makeDefer from 'jdefer';
2
+ import { promisify } from 'node:util';
3
+ import { entityTag, isFreshETag } from './etag.js';
4
+ import { makeContext, requestContext, responseContext } from './context.js';
5
+ import { Readable } from 'node:stream';
6
+ export const dxContext = makeContext(async ({ jsonBeautify, disableEtag } = {}) => {
7
+ return {
8
+ jsonBeautify,
9
+ disableEtag,
10
+ };
11
+ }, async (ret, { type, data, charset, jsonBeautify, disableEtag }) => {
12
+ const res = responseContext.value;
13
+ const setContentType = (contentType) => {
14
+ if (res.headersSent || res.getHeader('content-type'))
15
+ return;
16
+ res.setHeader('content-type', `${contentType}${charset ? `; charset=${charset}` : ''}`);
17
+ };
18
+ let bufferOrStream;
19
+ switch (type) {
20
+ case 'text':
21
+ setContentType('text/plain');
22
+ case 'html':
23
+ setContentType('text/html');
24
+ // shared with text
25
+ bufferOrStream = Buffer.from(data, charset);
26
+ break;
27
+ case 'buffer':
28
+ setContentType('application/octet-stream');
29
+ bufferOrStream = data;
30
+ break;
31
+ case 'nodeStream':
32
+ setContentType('application/octet-stream');
33
+ bufferOrStream = data;
34
+ break;
35
+ case 'webStream':
36
+ setContentType('application/octet-stream');
37
+ bufferOrStream = Readable.fromWeb(data);
38
+ break;
39
+ case 'json':
40
+ setContentType('application/json');
41
+ bufferOrStream = Buffer.from(jsonBeautify ? JSON.stringify(data, null, 2) : JSON.stringify(data), charset);
42
+ break;
43
+ case 'redirect':
44
+ res.setHeader('location', data);
45
+ bufferOrStream = Buffer.from('', charset);
46
+ break;
47
+ case undefined:
48
+ // skip response. Some middleware may handle it outside the chain. For example, express middleware
49
+ return ret;
50
+ default:
51
+ if (!res.getHeader('content-type'))
52
+ res.setHeader('content-type', 'text/plain');
53
+ throw new Error(`unsupported response type ${type}`);
54
+ }
55
+ const req = requestContext.value;
56
+ if (res.headersSent) {
57
+ if (res.writableFinished) {
58
+ // skipped: response is already finished
59
+ }
60
+ else if (res.writableEnded) {
61
+ const defer = makeDefer();
62
+ res.addListener('finish', defer.resolve);
63
+ await defer.promise;
64
+ // skipped: response is already ended
65
+ // chunk is not fully flushed yet
66
+ }
67
+ else
68
+ await promisify(res.end.bind(res))(undefined); // to be consistent, we end the response immediately
69
+ }
70
+ else {
71
+ // https://github.com/expressjs/express/blob/980d881e3b023db079de60477a2588a91f046ca5/lib/response.js#L210
72
+ if (res.statusCode === 204) { // No Content
73
+ res.removeHeader('content-type');
74
+ res.removeHeader('content-length');
75
+ res.removeHeader('transfer-encoding');
76
+ // write nothing
77
+ }
78
+ if (res.statusCode === 205) { // reset content. Tell client to clear the form, etc.
79
+ res.setHeader('content-length', 0);
80
+ res.removeHeader('transfer-encoding');
81
+ }
82
+ else if (req.method === 'HEAD') {
83
+ // write nothing
84
+ }
85
+ else {
86
+ if (Buffer.isBuffer(bufferOrStream)) {
87
+ // support: 304 (etag), zipping, file etag and last modified
88
+ res.setHeader('content-length', bufferOrStream.length);
89
+ if (!disableEtag) {
90
+ const etag = entityTag(bufferOrStream);
91
+ const lastModified = res.getHeader('last-modified');
92
+ res.setHeader('ETag', etag);
93
+ if (isFreshETag(req, etag)) {
94
+ res.removeHeader('content-type');
95
+ res.removeHeader('content-length');
96
+ res.removeHeader('transfer-encoding');
97
+ res.statusCode = 304;
98
+ // write nothing
99
+ }
100
+ else
101
+ res.write(bufferOrStream);
102
+ }
103
+ else
104
+ res.write(bufferOrStream);
105
+ }
106
+ else {
107
+ bufferOrStream.pipe(res);
108
+ }
109
+ // fixme: not support content-encoding (gzip, deflate, br) for now
110
+ }
111
+ await promisify(res.end.bind(res))(undefined); // some express middleware, such as express-session, requires explicitly passing chunk
112
+ }
113
+ return ret;
114
+ });
115
+ // todo: support setFile (with stream or with buffer)
116
+ export function setText(text, { status } = {}) {
117
+ const response = responseContext.value;
118
+ const express = dxContext.value;
119
+ if (status)
120
+ response.statusCode = status;
121
+ express.data = text;
122
+ express.type = 'text';
123
+ }
124
+ export function setHtml(html, opts = {}) {
125
+ setText(html, opts);
126
+ const express = dxContext.value;
127
+ express.type = 'html';
128
+ }
129
+ export function setBuffer(buffer, { status } = {}) {
130
+ const response = responseContext.value;
131
+ const express = dxContext.value;
132
+ if (status)
133
+ response.statusCode = status;
134
+ express.data = buffer;
135
+ express.type = 'buffer';
136
+ }
137
+ export function setNodeStream(stream, { status } = {}) {
138
+ const response = responseContext.value;
139
+ const express = dxContext.value;
140
+ if (status)
141
+ response.statusCode = status;
142
+ express.data = stream;
143
+ express.type = 'nodeStream';
144
+ }
145
+ export function setWebStream(stream, { status } = {}) {
146
+ const response = responseContext.value;
147
+ const express = dxContext.value;
148
+ if (status)
149
+ response.statusCode = status;
150
+ express.data = stream;
151
+ express.type = 'webStream';
152
+ }
153
+ export function setJson(json, { status, beautify } = {}) {
154
+ const response = responseContext.value;
155
+ if (status)
156
+ response.statusCode = status;
157
+ const express = dxContext.value;
158
+ express.data = json;
159
+ express.type = 'json';
160
+ if (beautify !== undefined)
161
+ express.jsonBeautify = beautify;
162
+ }
163
+ export function setRedirect(url, status) {
164
+ const response = responseContext.value;
165
+ const express = dxContext.value;
166
+ response.statusCode = status;
167
+ express.data = url;
168
+ express.type = 'redirect';
169
+ }
170
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvZHgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxTQUFTLE1BQU0sUUFBUSxDQUFBO0FBQzlCLE9BQU8sRUFBQyxTQUFTLEVBQUMsTUFBTSxXQUFXLENBQUE7QUFDbkMsT0FBTyxFQUFDLFNBQVMsRUFBRSxXQUFXLEVBQUMsTUFBTSxXQUFXLENBQUE7QUFDaEQsT0FBTyxFQUFDLFdBQVcsRUFBRSxjQUFjLEVBQUUsZUFBZSxFQUFDLE1BQU0sY0FBYyxDQUFBO0FBQ3pFLE9BQU8sRUFBQyxRQUFRLEVBQUMsTUFBTSxhQUFhLENBQUE7QUFFcEMsTUFBTSxDQUFDLE1BQU0sU0FBUyxHQUFHLFdBQVcsQ0FBQyxLQUFLLEVBQ3pDLEVBQUMsWUFBWSxFQUFFLFdBQVcsS0FHdEIsRUFBRSxFQUNMLEVBQUU7SUFDSCxPQUFPO1FBQ04sWUFBWTtRQUNaLFdBQVc7S0FtQ1YsQ0FBQTtBQUNILENBQUMsRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFLEVBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsWUFBWSxFQUFFLFdBQVcsRUFBQyxFQUFFLEVBQUU7SUFDbEUsTUFBTSxHQUFHLEdBQUcsZUFBZSxDQUFDLEtBQUssQ0FBQTtJQUNqQyxNQUFNLGNBQWMsR0FBRyxDQUFDLFdBQW1CLEVBQUUsRUFBRTtRQUM5QyxJQUFJLEdBQUcsQ0FBQyxXQUFXLElBQUksR0FBRyxDQUFDLFNBQVMsQ0FBQyxjQUFjLENBQUM7WUFBRSxPQUFNO1FBQzVELEdBQUcsQ0FBQyxTQUFTLENBQUMsY0FBYyxFQUFFLEdBQUcsV0FBVyxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsYUFBYSxPQUFPLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQTtJQUN4RixDQUFDLENBQUE7SUFDRCxJQUFJLGNBQWMsQ0FBQTtJQUVsQixRQUFRLElBQUksRUFBRSxDQUFDO1FBQ2QsS0FBSyxN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
package/esm/express.d.ts CHANGED
@@ -1,81 +1,4 @@
1
- /// <reference types="node" resolution-mode="require"/>
2
- /// <reference types="node" resolution-mode="require"/>
3
- import { Readable } from 'node:stream';
4
- export declare const expressContext: {
5
- readonly value: {
6
- charset?: BufferEncoding | undefined;
7
- jsonBeautify?: boolean | undefined;
8
- disableEtag?: boolean | undefined;
9
- } & ({
10
- type: 'text';
11
- data: string;
12
- } | {
13
- type: 'html';
14
- data: string;
15
- } | {
16
- type: 'buffer';
17
- data: Buffer;
18
- } | {
19
- type: 'json';
20
- data: any;
21
- } | {
22
- type: 'redirect';
23
- data: string;
24
- } | {
25
- type: 'nodeStream';
26
- data: Readable;
27
- } | {
28
- type: 'webStream';
29
- data: ReadableStream;
30
- });
31
- chain(params_0?: {
32
- jsonBeautify?: boolean | undefined;
33
- disableEtag?: boolean | undefined;
34
- } | undefined): <V>(next: () => V) => Promise<any>;
35
- with(value: {
36
- charset?: BufferEncoding | undefined;
37
- jsonBeautify?: boolean | undefined;
38
- disableEtag?: boolean | undefined;
39
- } & ({
40
- type: 'text';
41
- data: string;
42
- } | {
43
- type: 'html';
44
- data: string;
45
- } | {
46
- type: 'buffer';
47
- data: Buffer;
48
- } | {
49
- type: 'json';
50
- data: any;
51
- } | {
52
- type: 'redirect';
53
- data: string;
54
- } | {
55
- type: 'nodeStream';
56
- data: Readable;
57
- } | {
58
- type: 'webStream';
59
- data: ReadableStream;
60
- })): <V_1>(next: () => V_1) => Promise<any>;
61
- };
62
- export declare function setText(text: string, { status }?: {
63
- status?: number;
64
- }): void;
65
- export declare function setHtml(html: string, opts?: {
66
- status?: number;
67
- }): void;
68
- export declare function setBuffer(buffer: Buffer, { status }?: {
69
- status?: number;
70
- }): void;
71
- export declare function setNodeStream(stream: Readable, { status }?: {
72
- status?: number;
73
- }): void;
74
- export declare function setWebStream(stream: ReadableStream, { status }?: {
75
- status?: number;
76
- }): void;
77
- export declare function setJson(json: any, { status, beautify }?: {
78
- status?: number;
79
- beautify?: boolean;
80
- }): void;
81
- export declare function setRedirect(url: string, status: 301 | 302): void;
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 chainExpressMiddlewares: (...middlewares: ((req: Request, res: Response, next: () => any) => any)[]) => Promise<(next: any) => Promise<void>>;
package/esm/express.js CHANGED
@@ -1,170 +1,35 @@
1
+ import express from 'express';
2
+ import { requestContext, responseContext } from './context.js';
1
3
  import makeDefer from 'jdefer';
2
- import { promisify } from 'node:util';
3
- import { entityTag, isFreshETag } from './etag.js';
4
- import { makeContext, requestContext, responseContext } from './context.js';
5
- import { Readable } from 'node:stream';
6
- export const expressContext = makeContext(async ({ jsonBeautify, disableEtag } = {}) => {
7
- return {
8
- jsonBeautify,
9
- disableEtag,
4
+ export const expressApp = async (setup) => {
5
+ const symbol = Symbol('expressApp');
6
+ const app = express();
7
+ await setup(app);
8
+ app.use((req, _res, _next) => req[symbol].resolve());
9
+ app.use((err, req, _res, _next) => req[symbol].reject(err));
10
+ return async (next) => {
11
+ const req = requestContext.value;
12
+ const defer = makeDefer();
13
+ req[symbol] = defer;
14
+ app(req, responseContext.value);
15
+ await defer.promise;
16
+ await next();
10
17
  };
11
- }, async (ret, { type, data, charset, jsonBeautify, disableEtag }) => {
12
- const res = responseContext.value;
13
- const setContentType = (contentType) => {
14
- if (res.headersSent || res.getHeader('content-type'))
15
- return;
16
- res.setHeader('content-type', `${contentType}${charset ? `; charset=${charset}` : ''}`);
18
+ };
19
+ export const expressRouter = async (setup) => {
20
+ const symbol = Symbol('expressRouter');
21
+ const router = express.Router();
22
+ await setup(router);
23
+ router.use((req, _res, _next) => req[symbol].resolve());
24
+ router.use((err, req, _res, _next) => req[symbol].reject(err));
25
+ return async (next) => {
26
+ const req = requestContext.value;
27
+ const defer = makeDefer();
28
+ req[symbol] = defer;
29
+ router(req, responseContext.value);
30
+ await defer.promise;
31
+ await next();
17
32
  };
18
- let bufferOrStream;
19
- switch (type) {
20
- case 'text':
21
- setContentType('text/plain');
22
- case 'html':
23
- setContentType('text/html');
24
- // shared with text
25
- bufferOrStream = Buffer.from(data, charset);
26
- break;
27
- case 'buffer':
28
- setContentType('application/octet-stream');
29
- bufferOrStream = data;
30
- break;
31
- case 'nodeStream':
32
- setContentType('application/octet-stream');
33
- bufferOrStream = data;
34
- break;
35
- case 'webStream':
36
- setContentType('application/octet-stream');
37
- bufferOrStream = Readable.fromWeb(data);
38
- break;
39
- case 'json':
40
- setContentType('application/json');
41
- bufferOrStream = Buffer.from(jsonBeautify ? JSON.stringify(data, null, 2) : JSON.stringify(data), charset);
42
- break;
43
- case 'redirect':
44
- res.setHeader('location', data);
45
- bufferOrStream = Buffer.from('', charset);
46
- break;
47
- case undefined:
48
- // skip response. Some middleware may handle it outside the chain. For example, express middleware
49
- return ret;
50
- default:
51
- if (!res.getHeader('content-type'))
52
- res.setHeader('content-type', 'text/plain');
53
- throw new Error(`unsupported response type ${type}`);
54
- }
55
- const req = requestContext.value;
56
- if (res.headersSent) {
57
- if (res.writableFinished) {
58
- // skipped: response is already finished
59
- }
60
- else if (res.writableEnded) {
61
- const defer = makeDefer();
62
- res.addListener('finish', defer.resolve);
63
- await defer.promise;
64
- // skipped: response is already ended
65
- // chunk is not fully flushed yet
66
- }
67
- else
68
- await promisify(res.end.bind(res))(undefined); // to be consistent, we end the response immediately
69
- }
70
- else {
71
- // https://github.com/expressjs/express/blob/980d881e3b023db079de60477a2588a91f046ca5/lib/response.js#L210
72
- if (res.statusCode === 204) { // No Content
73
- res.removeHeader('content-type');
74
- res.removeHeader('content-length');
75
- res.removeHeader('transfer-encoding');
76
- // write nothing
77
- }
78
- if (res.statusCode === 205) { // reset content. Tell client to clear the form, etc.
79
- res.setHeader('content-length', 0);
80
- res.removeHeader('transfer-encoding');
81
- }
82
- else if (req.method === 'HEAD') {
83
- // write nothing
84
- }
85
- else {
86
- if (Buffer.isBuffer(bufferOrStream)) {
87
- // support: 304 (etag), zipping, file etag and last modified
88
- res.setHeader('content-length', bufferOrStream.length);
89
- if (!disableEtag) {
90
- const etag = entityTag(bufferOrStream);
91
- const lastModified = res.getHeader('last-modified');
92
- res.setHeader('ETag', etag);
93
- if (isFreshETag(req, etag)) {
94
- res.removeHeader('content-type');
95
- res.removeHeader('content-length');
96
- res.removeHeader('transfer-encoding');
97
- res.statusCode = 304;
98
- // write nothing
99
- }
100
- else
101
- res.write(bufferOrStream);
102
- }
103
- else
104
- res.write(bufferOrStream);
105
- }
106
- else {
107
- bufferOrStream.pipe(res);
108
- }
109
- // fixme: not support content-encoding (gzip, deflate, br) for now
110
- }
111
- await promisify(res.end.bind(res))(undefined); // some express middleware, such as express-session, requires explicitly passing chunk
112
- }
113
- return ret;
114
- });
115
- // todo: support setFile (with stream or with buffer)
116
- export function setText(text, { status } = {}) {
117
- const response = responseContext.value;
118
- const express = expressContext.value;
119
- if (status)
120
- response.statusCode = status;
121
- express.data = text;
122
- express.type = 'text';
123
- }
124
- export function setHtml(html, opts = {}) {
125
- setText(html, opts);
126
- const express = expressContext.value;
127
- express.type = 'html';
128
- }
129
- export function setBuffer(buffer, { status } = {}) {
130
- const response = responseContext.value;
131
- const express = expressContext.value;
132
- if (status)
133
- response.statusCode = status;
134
- express.data = buffer;
135
- express.type = 'buffer';
136
- }
137
- export function setNodeStream(stream, { status } = {}) {
138
- const response = responseContext.value;
139
- const express = expressContext.value;
140
- if (status)
141
- response.statusCode = status;
142
- express.data = stream;
143
- express.type = 'nodeStream';
144
- }
145
- export function setWebStream(stream, { status } = {}) {
146
- const response = responseContext.value;
147
- const express = expressContext.value;
148
- if (status)
149
- response.statusCode = status;
150
- express.data = stream;
151
- express.type = 'webStream';
152
- }
153
- export function setJson(json, { status, beautify } = {}) {
154
- const response = responseContext.value;
155
- if (status)
156
- response.statusCode = status;
157
- const express = expressContext.value;
158
- express.data = json;
159
- express.type = 'json';
160
- if (beautify !== undefined)
161
- express.jsonBeautify = beautify;
162
- }
163
- export function setRedirect(url, status) {
164
- const response = responseContext.value;
165
- const express = expressContext.value;
166
- response.statusCode = status;
167
- express.data = url;
168
- express.type = 'redirect';
169
- }
170
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhwcmVzcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9leHByZXNzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sU0FBUyxNQUFNLFFBQVEsQ0FBQTtBQUM5QixPQUFPLEVBQUMsU0FBUyxFQUFDLE1BQU0sV0FBVyxDQUFBO0FBQ25DLE9BQU8sRUFBQyxTQUFTLEVBQUUsV0FBVyxFQUFDLE1BQU0sV0FBVyxDQUFBO0FBQ2hELE9BQU8sRUFBQyxXQUFXLEVBQUUsY0FBYyxFQUFFLGVBQWUsRUFBQyxNQUFNLGNBQWMsQ0FBQTtBQUN6RSxPQUFPLEVBQUMsUUFBUSxFQUFDLE1BQU0sYUFBYSxDQUFBO0FBRXBDLE1BQU0sQ0FBQyxNQUFNLGNBQWMsR0FBRyxXQUFXLENBQUMsS0FBSyxFQUM5QyxFQUFDLFlBQVksRUFBRSxXQUFXLEtBR3RCLEVBQUUsRUFDTCxFQUFFO0lBQ0gsT0FBTztRQUNOLFlBQVk7UUFDWixXQUFXO0tBbUNWLENBQUE7QUFDSCxDQUFDLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRSxFQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLFlBQVksRUFBRSxXQUFXLEVBQUMsRUFBRSxFQUFFO0lBQ2xFLE1BQU0sR0FBRyxHQUFHLGVBQWUsQ0FBQyxLQUFLLENBQUE7SUFDakMsTUFBTSxjQUFjLEdBQUcsQ0FBQyxXQUFtQixFQUFFLEVBQUU7UUFDOUMsSUFBSSxHQUFHLENBQUMsV0FBVyxJQUFJLEdBQUcsQ0FBQyxTQUFTLENBQUMsY0FBYyxDQUFDO1lBQUUsT0FBTTtRQUM1RCxHQUFHLENBQUMsU0FBUyxDQUFDLGNBQWMsRUFBRSxHQUFHLFdBQVcsR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLGFBQWEsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUE7SUFDeEYsQ0FBQyxDQUFBO0lBQ0QsSUFBSSxjQUFjLENBQUE7SUFFbEIsUUFBUSxJQUFJLEVBQUUsQ0FBQztR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
33
+ };
34
+ export const chainExpressMiddlewares = (...middlewares) => expressRouter(router => router.use(...middlewares));
35
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhwcmVzcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9leHByZXNzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sT0FBaUUsTUFBTSxTQUFTLENBQUE7QUFDdkYsT0FBTyxFQUFDLGNBQWMsRUFBRSxlQUFlLEVBQUMsTUFBTSxjQUFjLENBQUE7QUFDNUQsT0FBTyxTQUFTLE1BQU0sUUFBUSxDQUFBO0FBRTlCLE1BQU0sQ0FBQyxNQUFNLFVBQVUsR0FBRyxLQUFLLEVBQUUsS0FBNEIsRUFBRSxFQUFFO0lBQ2hFLE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQTtJQUVuQyxNQUFNLEdBQUcsR0FBRyxPQUFPLEVBQUUsQ0FBQTtJQUNyQixNQUFNLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQTtJQUNoQixHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFBO0lBQ3BELEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQTtJQUMzRCxPQUFPLEtBQUssRUFBQyxJQUFJLEVBQUMsRUFBRTtRQUNuQixNQUFNLEdBQUcsR0FBRyxjQUFjLENBQUMsS0FBSyxDQUFBO1FBQ2hDLE1BQU0sS0FBSyxHQUFHLFNBQVMsRUFBRSxDQUFBO1FBQ3pCLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxLQUFLLENBQUE7UUFDbkIsR0FBRyxDQUFDLEdBQUcsRUFBRSxlQUFlLENBQUMsS0FBSyxDQUFDLENBQUE7UUFDL0IsTUFBTSxLQUFLLENBQUMsT0FBTyxDQUFBO1FBQ25CLE1BQU0sSUFBSSxFQUFFLENBQUE7SUFDYixDQUFDLENBQUE7QUFDRixDQUFDLENBQUE7QUFFRCxNQUFNLENBQUMsTUFBTSxhQUFhLEdBQUcsS0FBSyxFQUFFLEtBQThCLEVBQUUsRUFBRTtJQUNyRSxNQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsZUFBZSxDQUFDLENBQUE7SUFFdEMsTUFBTSxNQUFNLEdBQUcsT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFBO0lBQy9CLE1BQU0sS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFBO0lBQ25CLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUE7SUFDdkQsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFBO0lBQzlELE9BQU8sS0FBSyxFQUFDLElBQUksRUFBQyxFQUFFO1FBQ25CLE1BQU0sR0FBRyxHQUFHLGNBQWMsQ0FBQyxLQUFLLENBQUE7UUFDaEMsTUFBTSxLQUFLLEdBQUcsU0FBUyxFQUFFLENBQUE7UUFDekIsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLEtBQUssQ0FBQTtRQUNuQixNQUFNLENBQUMsR0FBRyxFQUFFLGVBQWUsQ0FBQyxLQUFLLENBQUMsQ0FBQTtRQUNsQyxNQUFNLEtBQUssQ0FBQyxPQUFPLENBQUE7UUFDbkIsTUFBTSxJQUFJLEVBQUUsQ0FBQTtJQUNiLENBQUMsQ0FBQTtBQUNGLENBQUMsQ0FBQTtBQUVELE1BQU0sQ0FBQyxNQUFNLHVCQUF1QixHQUFHLENBQ3RDLEdBQUcsV0FBeUUsRUFDM0UsRUFBRSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxXQUFXLENBQUMsQ0FBQyxDQUFBIn0=
package/esm/index.d.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  export { makeContext, requestContext, responseContext } from './context.js';
2
- export { expressContext, setHtml, setJson, setBuffer, setRedirect, setText } from './express.js';
2
+ export { dxContext, setHtml, setJson, setBuffer, setRedirect, setText } from './dx.js';
3
3
  export { bufferBodyContext, jsonBodyContext, queryContext, rawBodyContext, textBodyContext, urlencodedBodyContext } from './body.js';
4
4
  export { router } from './route.js';
5
- export { expressApp, expressRouter, chainExpressMiddlewares } from './expressApp.js';
package/esm/index.js CHANGED
@@ -1,6 +1,5 @@
1
1
  export { makeContext, requestContext, responseContext } from './context.js';
2
- export { expressContext, setHtml, setJson, setBuffer, setRedirect, setText } from './express.js';
2
+ export { dxContext, setHtml, setJson, setBuffer, setRedirect, setText } from './dx.js';
3
3
  export { bufferBodyContext, jsonBodyContext, queryContext, rawBodyContext, textBodyContext, urlencodedBodyContext } from './body.js';
4
4
  export { router } from './route.js';
5
- export { expressApp, expressRouter, chainExpressMiddlewares } from './expressApp.js';
6
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFDLFdBQVcsRUFBRSxjQUFjLEVBQUUsZUFBZSxFQUFDLE1BQU0sY0FBYyxDQUFBO0FBQ3pFLE9BQU8sRUFDTixjQUFjLEVBQ2QsT0FBTyxFQUNQLE9BQU8sRUFDUCxTQUFTLEVBQ1QsV0FBVyxFQUNYLE9BQU8sRUFDUCxNQUFNLGNBQWMsQ0FBQTtBQUNyQixPQUFPLEVBQ04saUJBQWlCLEVBQ2pCLGVBQWUsRUFDZixZQUFZLEVBQ1osY0FBYyxFQUNkLGVBQWUsRUFDZixxQkFBcUIsRUFDckIsTUFBTSxXQUFXLENBQUE7QUFDbEIsT0FBTyxFQUFDLE1BQU0sRUFBQyxNQUFNLFlBQVksQ0FBQTtBQUNqQyxPQUFPLEVBQUMsVUFBVSxFQUFFLGFBQWEsRUFBRSx1QkFBdUIsRUFBQyxNQUFNLGlCQUFpQixDQUFBIn0=
5
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFDLFdBQVcsRUFBRSxjQUFjLEVBQUUsZUFBZSxFQUFDLE1BQU0sY0FBYyxDQUFBO0FBQ3pFLE9BQU8sRUFDTixTQUFTLEVBQ1QsT0FBTyxFQUNQLE9BQU8sRUFDUCxTQUFTLEVBQ1QsV0FBVyxFQUNYLE9BQU8sRUFDUCxNQUFNLFNBQVMsQ0FBQTtBQUNoQixPQUFPLEVBQ04saUJBQWlCLEVBQ2pCLGVBQWUsRUFDZixZQUFZLEVBQ1osY0FBYyxFQUNkLGVBQWUsRUFDZixxQkFBcUIsRUFDckIsTUFBTSxXQUFXLENBQUE7QUFDbEIsT0FBTyxFQUFDLE1BQU0sRUFBQyxNQUFNLFlBQVksQ0FBQSJ9
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dx-server",
3
- "version": "0.0.7",
3
+ "version": "0.1.0",
4
4
  "main": "./cjs/index.js",
5
5
  "repository": "https://github.com/tranvansang/dx-server",
6
6
  "author": "Sang Tran <t@sang.jp>",
@@ -12,6 +12,10 @@
12
12
  ".": {
13
13
  "import": "./esm/index.js",
14
14
  "require": "./cjs/index.js"
15
+ },
16
+ "express": {
17
+ "import": "./esm/express.js",
18
+ "require": "./cjs/express.js"
15
19
  }
16
20
  },
17
21
  "type": "module",
@@ -19,7 +23,7 @@
19
23
  "prepublish": "./compile.sh"
20
24
  },
21
25
  "license": "MIT",
22
- "packageManager": "yarn@3.6.1",
26
+ "packageManager": "yarn@4.1.1",
23
27
  "devDependencies": {
24
28
  "@types/node": "^20.10.5",
25
29
  "@types/path-to-regexp": "^1.7.0",