express-ext 0.1.12 → 0.1.13

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/lib/index.js CHANGED
@@ -1,2 +1 @@
1
- "use strict";function __export(m){for(var p in m)if(!exports.hasOwnProperty(p))exports[p]=m[p]}
2
- Object.defineProperty(exports,"__esModule",{value:!0});var GenericController_1=require("./GenericController");exports.GenericHandler=GenericController_1.GenericController;var GenericSearchController_1=require("./GenericSearchController");exports.GenericSearchHandler=GenericSearchController_1.GenericSearchController;var HealthController_1=require("./HealthController");exports.HealthHandler=HealthController_1.HealthController;var LoadController_1=require("./LoadController");exports.LoadHandler=LoadController_1.LoadController;exports.ViewHandler=LoadController_1.LoadController;exports.ViewController=LoadController_1.LoadController;var LoadSearchController_1=require("./LoadSearchController");exports.LoadSearchHandler=LoadSearchController_1.LoadSearchController;var LowCodeController_1=require("./LowCodeController");exports.LowCodeHandler=LowCodeController_1.LowCodeController;exports.Handler=LowCodeController_1.LowCodeController;exports.Controller=LowCodeController_1.LowCodeController;var SearchController_1=require("./SearchController");exports.SearchHandler=SearchController_1.SearchController;var LogController_1=require("./LogController");exports.LogHandler=LogController_1.LogController;__export(require("./health"));__export(require("./HealthController"));__export(require("./LogController"));__export(require("./http"));__export(require("./view"));__export(require("./LoadController"));__export(require("./search_func"));__export(require("./search"));__export(require("./SearchController"));__export(require("./LoadSearchController"));__export(require("./resources"));__export(require("./edit"));__export(require("./GenericController"));__export(require("./GenericSearchController"));__export(require("./LowCodeController"))
1
+ "use strict";function __export(r){for(var e in r)exports.hasOwnProperty(e)||(exports[e]=r[e])}Object.defineProperty(exports,"__esModule",{value:!0});var GenericController_1=require("./GenericController");exports.GenericHandler=GenericController_1.GenericController;var GenericSearchController_1=require("./GenericSearchController");exports.GenericSearchHandler=GenericSearchController_1.GenericSearchController;var HealthController_1=require("./HealthController");exports.HealthHandler=HealthController_1.HealthController;var LoadController_1=require("./LoadController");exports.LoadHandler=LoadController_1.LoadController,exports.ViewHandler=LoadController_1.LoadController,exports.ViewController=LoadController_1.LoadController;var LoadSearchController_1=require("./LoadSearchController");exports.LoadSearchHandler=LoadSearchController_1.LoadSearchController;var LogController_1=require("./LogController");exports.LogHandler=LogController_1.LogController;var LowCodeController_1=require("./LowCodeController");exports.LowCodeHandler=LowCodeController_1.LowCodeController,exports.Handler=LowCodeController_1.LowCodeController,exports.Controller=LowCodeController_1.LowCodeController;var SearchController_1=require("./SearchController");exports.SearchHandler=SearchController_1.SearchController,__export(require("./health")),__export(require("./HealthController")),__export(require("./LogController")),__export(require("./log")),__export(require("./http")),__export(require("./view")),__export(require("./LoadController")),__export(require("./search_func")),__export(require("./search")),__export(require("./SearchController")),__export(require("./LoadSearchController")),__export(require("./resources")),__export(require("./edit")),__export(require("./GenericController")),__export(require("./GenericSearchController")),__export(require("./LowCodeController"));
package/lib/log.js ADDED
@@ -0,0 +1,143 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ var stream_1 = require("stream");
4
+ function createConfig(c) {
5
+ if (!c) {
6
+ return { skips: [], duration: 'duration', request: '', response: '', status: '', size: '' };
7
+ }
8
+ var l = {
9
+ log: c.log,
10
+ separate: c.separate,
11
+ skips: c.skips ? c.skips.split(',') : [],
12
+ duration: c.duration ? c.duration : 'duration',
13
+ request: c.request ? c.request : '',
14
+ response: c.response ? c.response : '',
15
+ status: c.status ? c.status : '',
16
+ size: c.size ? c.size : ''
17
+ };
18
+ return l;
19
+ }
20
+ exports.createConfig = createConfig;
21
+ function skip(skips, url) {
22
+ if (skips.length === 0) {
23
+ return false;
24
+ }
25
+ var u = removeUrlParams(url);
26
+ for (var _i = 0, skips_1 = skips; _i < skips_1.length; _i++) {
27
+ var s = skips_1[_i];
28
+ if (u.endsWith(s)) {
29
+ return true;
30
+ }
31
+ }
32
+ return false;
33
+ }
34
+ exports.skip = skip;
35
+ function removeUrlParams(url) {
36
+ var startParams = url.indexOf('?');
37
+ return startParams !== -1 ? url.substring(0, startParams) : url;
38
+ }
39
+ exports.removeUrlParams = removeUrlParams;
40
+ var Logger = (function () {
41
+ function Logger(write, conf, build) {
42
+ this.write = write;
43
+ this.build = build;
44
+ this.log = this.log.bind(this);
45
+ this.c = createConfig(conf);
46
+ }
47
+ Logger.prototype.log = function (req, res, next) {
48
+ var _this = this;
49
+ if (this.c.log && !skip(this.c.skips, req.originalUrl)) {
50
+ var start_1 = process.hrtime();
51
+ var m = req.method;
52
+ var x = this.c.request;
53
+ var r_1 = false;
54
+ if (m !== 'GET' && m !== 'DELETE') {
55
+ r_1 = true;
56
+ }
57
+ var msg_1 = m + " " + req.originalUrl;
58
+ if (this.c.separate && r_1) {
59
+ if (this.c.request.length > 0) {
60
+ var op = {};
61
+ op[x] = JSON.stringify(req.body);
62
+ if (this.build) {
63
+ var op2 = this.build(req, op);
64
+ this.write(msg_1, op2);
65
+ }
66
+ else {
67
+ this.write(msg_1, op);
68
+ }
69
+ }
70
+ }
71
+ var chunks_1 = [];
72
+ mapResponseBody(res, chunks_1);
73
+ res.on('finish', function () {
74
+ var duration = getDurationInMilliseconds(start_1);
75
+ var op = {};
76
+ op[_this.c.duration] = duration;
77
+ if (r_1 && !_this.c.separate && _this.c.request.length > 0) {
78
+ op[_this.c.request] = JSON.stringify(req.body);
79
+ }
80
+ if (_this.c.response.length > 0) {
81
+ var rsBody = Buffer.concat(chunks_1).toString();
82
+ op[_this.c.response] = rsBody;
83
+ }
84
+ if (_this.c.status.length > 0) {
85
+ op[_this.c.status] = res.statusCode;
86
+ }
87
+ if (_this.c.size.length > 0) {
88
+ if ('_contentLength' in res) {
89
+ op[_this.c.size] = res['_contentLength'];
90
+ }
91
+ else if (res.hasHeader('content-length')) {
92
+ var l = res.getHeader('content-length');
93
+ if (typeof l === 'number' || typeof l === 'string') {
94
+ op[_this.c.size] = l;
95
+ }
96
+ }
97
+ }
98
+ if (_this.build) {
99
+ var op2 = _this.build(req, op);
100
+ _this.write(msg_1, op2);
101
+ }
102
+ else {
103
+ _this.write(msg_1, op);
104
+ }
105
+ });
106
+ next();
107
+ }
108
+ else {
109
+ next();
110
+ }
111
+ };
112
+ return Logger;
113
+ }());
114
+ exports.Logger = Logger;
115
+ var mapResponseBody = function (res, chunks) {
116
+ var defaultWrite = res.write.bind(res);
117
+ var defaultEnd = res.end.bind(res);
118
+ var ps = new stream_1.PassThrough();
119
+ ps.on('data', function (data) { return chunks.push(data); });
120
+ res.write = function () {
121
+ var _a;
122
+ var args = [];
123
+ for (var _i = 0; _i < arguments.length; _i++) {
124
+ args[_i] = arguments[_i];
125
+ }
126
+ (_a = ps).write.apply(_a, args);
127
+ defaultWrite.apply(void 0, args);
128
+ };
129
+ res.end = function () {
130
+ var args = [];
131
+ for (var _i = 0; _i < arguments.length; _i++) {
132
+ args[_i] = arguments[_i];
133
+ }
134
+ ps.end.apply(ps, args);
135
+ defaultEnd.apply(void 0, args);
136
+ };
137
+ };
138
+ var NS_PER_SEC = 1e9;
139
+ var NS_TO_MS = 1e6;
140
+ var getDurationInMilliseconds = function (start) {
141
+ var diff = process.hrtime(start);
142
+ return (diff[0] * NS_PER_SEC + diff[1]) / NS_TO_MS;
143
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "express-ext",
3
- "version": "0.1.12",
3
+ "version": "0.1.13",
4
4
  "description": "express-ext",
5
5
  "main": "./lib/index.js",
6
6
  "types": "./src/index.ts",
@@ -1,6 +1,6 @@
1
1
  import {Request, Response} from 'express';
2
2
  import {checkId, create, initializeStatus, isTypeError, ResultInfo, StatusConfig, update} from './edit';
3
- import {handleError} from './http';
3
+ import {handleError, Log} from './http';
4
4
  import {LoadController} from './LoadController';
5
5
  import {Attribute, Attributes, ErrorMessage} from './metadata';
6
6
  import {resources} from './resources';
@@ -17,7 +17,7 @@ export interface GenericService<T, ID, R> {
17
17
  export class GenericController<T, ID> extends LoadController<T, ID> {
18
18
  status: StatusConfig;
19
19
  metadata?: Attributes;
20
- constructor(log: (msg: string) => void, public service: GenericService<T, ID, number|ResultInfo<T>>, status?: StatusConfig, public validate?: (obj: T, patch?: boolean) => Promise<ErrorMessage[]>) {
20
+ constructor(log: Log, public service: GenericService<T, ID, number|ResultInfo<T>>, status?: StatusConfig, public validate?: (obj: T, patch?: boolean) => Promise<ErrorMessage[]>) {
21
21
  super(log, service);
22
22
  this.status = initializeStatus(status);
23
23
  if (service.metadata) {
@@ -67,7 +67,7 @@ export class GenericController<T, ID> extends LoadController<T, ID> {
67
67
  }
68
68
  }
69
69
  }
70
- export function validateAndCreate<T>(req: Request, res: Response, status: StatusConfig, save: (obj: T, ctx?: any) => Promise<number|ResultInfo<T>>, log: (msg: string) => void, validate?: (obj: T, patch?: boolean) => Promise<ErrorMessage[]>): void {
70
+ export function validateAndCreate<T>(req: Request, res: Response, status: StatusConfig, save: (obj: T, ctx?: any) => Promise<number|ResultInfo<T>>, log: Log, validate?: (obj: T, patch?: boolean) => Promise<ErrorMessage[]>): void {
71
71
  const obj = req.body;
72
72
  if (!obj || obj === '') {
73
73
  return res.status(400).end('The request body cannot be empty.');
@@ -85,7 +85,7 @@ export function validateAndCreate<T>(req: Request, res: Response, status: Status
85
85
  create(res, status, obj, save, log);
86
86
  }
87
87
  }
88
- export function validateAndUpdate<T>(res: Response, status: StatusConfig, obj: T, isPatch: boolean, save: (obj: T, ctx?: any) => Promise<number|ResultInfo<T>>, log: (msg: string) => void, validate?: (obj: T, patch?: boolean) => Promise<ErrorMessage[]>): void {
88
+ export function validateAndUpdate<T>(res: Response, status: StatusConfig, obj: T, isPatch: boolean, save: (obj: T, ctx?: any) => Promise<number|ResultInfo<T>>, log: Log, validate?: (obj: T, patch?: boolean) => Promise<ErrorMessage[]>): void {
89
89
  if (validate) {
90
90
  validate(obj, isPatch).then(errors => {
91
91
  if (errors && errors.length > 0) {
@@ -1,7 +1,7 @@
1
1
  import {Request, Response} from 'express';
2
2
  import {ResultInfo, StatusConfig} from './edit';
3
3
  import {GenericController, GenericService} from './GenericController';
4
- import {handleError} from './http';
4
+ import {handleError, Log} from './http';
5
5
  import {ErrorMessage} from './metadata';
6
6
  import {Filter, format, fromRequest, getParameters, initializeConfig, jsonResult, SearchConfig, SearchResult} from './search';
7
7
  import {getMetadataFunc} from './search_func';
@@ -15,7 +15,7 @@ export class GenericSearchController<T, ID, S extends Filter> extends GenericCon
15
15
  numbers?: string[];
16
16
  fields?: string;
17
17
  excluding?: string;
18
- constructor(log: (msg: string) => void, public find: (s: S, limit?: number, skip?: number|string, fields?: string[]) => Promise<SearchResult<T>>, service: GenericService<T, ID, number|ResultInfo<T>>, config?: Config, validate?: (obj: T, patch?: boolean) => Promise<ErrorMessage[]>, dates?: string[], numbers?: string[]) {
18
+ constructor(log: Log, public find: (s: S, limit?: number, skip?: number|string, fields?: string[]) => Promise<SearchResult<T>>, service: GenericService<T, ID, number|ResultInfo<T>>, config?: Config, validate?: (obj: T, patch?: boolean) => Promise<ErrorMessage[]>, dates?: string[], numbers?: string[]) {
19
19
  super(log, service, config, validate);
20
20
  this.search = this.search.bind(this);
21
21
  this.config = initializeConfig(config);
@@ -1,5 +1,5 @@
1
1
  import {Request, Response} from 'express';
2
- import {attrs, handleError, respondModel} from './http';
2
+ import {attrs, handleError, Log, respondModel} from './http';
3
3
  import {Attribute, Attributes} from './metadata';
4
4
  import {buildAndCheckId, buildKeys} from './view';
5
5
 
@@ -39,7 +39,7 @@ function getKeysFunc<T, ID>(viewService: ViewService<T, ID> | ((id: ID, ctx?: an
39
39
  export class LoadController<T, ID> {
40
40
  protected keys?: Attribute[];
41
41
  protected view: (id: ID, ctx?: any) => Promise<T|null>;
42
- constructor(protected log: (msg: string) => void, viewService: ViewService<T, ID> | ((id: ID, ctx?: any) => Promise<T|null>), keys?: Attributes|Attribute[]|string[]) {
42
+ constructor(protected log: Log, viewService: ViewService<T, ID> | ((id: ID, ctx?: any) => Promise<T|null>), keys?: Attributes|Attribute[]|string[]) {
43
43
  this.load = this.load.bind(this);
44
44
  this.view = getViewFunc(viewService);
45
45
  this.keys = getKeysFunc(viewService, keys);
@@ -1,5 +1,5 @@
1
1
  import {Request, Response} from 'express';
2
- import {handleError} from './http';
2
+ import {handleError, Log} from './http';
3
3
  import {LoadController, ViewService} from './LoadController';
4
4
  import {Attribute, Attributes} from './metadata';
5
5
  import {Filter, format, fromRequest, getParameters, initializeConfig, jsonResult, SearchConfig, SearchResult} from './search';
@@ -12,7 +12,7 @@ export class LoadSearchController<T, ID, S extends Filter> extends LoadControlle
12
12
  numbers?: string[];
13
13
  fields?: string;
14
14
  excluding?: string;
15
- constructor(log: (msg: string) => void, public find: (s: S, limit?: number, skip?: number|string, fields?: string[]) => Promise<SearchResult<T>>, viewService: ViewService<T, ID> | ((id: ID, ctx?: any) => Promise<T>), keys?: Attributes|Attribute[]|string[], config?: SearchConfig|boolean, dates?: string[], numbers?: string[]) {
15
+ constructor(log: Log, public find: (s: S, limit?: number, skip?: number|string, fields?: string[]) => Promise<SearchResult<T>>, viewService: ViewService<T, ID> | ((id: ID, ctx?: any) => Promise<T>), keys?: Attributes|Attribute[]|string[], config?: SearchConfig|boolean, dates?: string[], numbers?: string[]) {
16
16
  super(log, viewService, keys);
17
17
  this.search = this.search.bind(this);
18
18
  if (config) {
@@ -3,7 +3,7 @@ import {Request, Response} from 'express';
3
3
  export interface NumberMap {
4
4
  [key: string]: number;
5
5
  }
6
- export interface LogConfig {
6
+ export interface LogConf {
7
7
  level?: string;
8
8
  map?: LogMapConfig;
9
9
  }
@@ -17,19 +17,19 @@ export interface LogMap {
17
17
  level: string;
18
18
  msg: string;
19
19
  }
20
- export interface Logger {
20
+ export interface LoggerConf {
21
21
  level: number;
22
22
  map: LogMap;
23
23
  }
24
24
 
25
25
  export class LogController {
26
26
  map?: NumberMap;
27
- constructor(public logger: Logger, mp?: NumberMap) {
27
+ constructor(public logger: LoggerConf, mp?: NumberMap) {
28
28
  this.map = mp;
29
29
  this.config = this.config.bind(this);
30
30
  }
31
31
  config(req: Request, res: Response) {
32
- const obj: LogConfig = req.body;
32
+ const obj: LogConf = req.body;
33
33
  if (!obj || obj === '') {
34
34
  return res.status(400).end('The request body cannot be empty');
35
35
  }
@@ -1,7 +1,7 @@
1
1
  import {Request, Response} from 'express';
2
2
  import {ResultInfo, StatusConfig} from './edit';
3
3
  import {GenericController, GenericService} from './GenericController';
4
- import {handleError} from './http';
4
+ import {handleError, Log} from './http';
5
5
  import {ErrorMessage} from './metadata';
6
6
  import {Filter, format, fromRequest, getParameters, initializeConfig, jsonResult, SearchConfig, SearchResult} from './search';
7
7
  import {getMetadataFunc} from './search_func';
@@ -18,7 +18,7 @@ export class LowCodeController<T, ID, S extends Filter> extends GenericControlle
18
18
  numbers?: string[];
19
19
  fields?: string;
20
20
  excluding?: string;
21
- constructor(log: (msg: string) => void, public lowCodeService: Service<T, ID, number|ResultInfo<T>, S>, config?: LowCodeConfig, validate?: (obj: T, patch?: boolean) => Promise<ErrorMessage[]>, dates?: string[], numbers?: string[]) {
21
+ constructor(log: Log, public lowCodeService: Service<T, ID, number|ResultInfo<T>, S>, config?: LowCodeConfig, validate?: (obj: T, patch?: boolean) => Promise<ErrorMessage[]>, dates?: string[], numbers?: string[]) {
22
22
  super(log, lowCodeService, config, validate);
23
23
  this.search = this.search.bind(this);
24
24
  this.config = initializeConfig(config);
@@ -1,5 +1,5 @@
1
1
  import {Request, Response} from 'express';
2
- import {handleError} from './http';
2
+ import {handleError, Log} from './http';
3
3
  import {Filter, format, fromRequest, getParameters, initializeConfig, jsonResult, SearchConfig, SearchResult} from './search';
4
4
 
5
5
  export class SearchController<T, S extends Filter> {
@@ -7,7 +7,7 @@ export class SearchController<T, S extends Filter> {
7
7
  csv?: boolean;
8
8
  fields?: string;
9
9
  excluding?: string;
10
- constructor(protected log: (msg: string) => void, public find: (s: S, limit?: number, skip?: number|string, fields?: string[]) => Promise<SearchResult<T>>, config?: SearchConfig|boolean, public dates?: string[], public numbers?: string[]) {
10
+ constructor(protected log: Log, public find: (s: S, limit?: number, skip?: number|string, fields?: string[]) => Promise<SearchResult<T>>, config?: SearchConfig|boolean, public dates?: string[], public numbers?: string[]) {
11
11
  this.search = this.search.bind(this);
12
12
  if (config) {
13
13
  if (typeof config === 'boolean') {
package/src/http.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  import {Request, Response} from 'express';
2
2
  import {Attribute} from './metadata';
3
3
 
4
+ export type Log = (msg: string) => void;
5
+ export type LogFunc = Log;
4
6
  export function handleError(err: any, res: Response, log?: (msg: string) => void) {
5
7
  if (log) {
6
8
  log(toString(err));
package/src/index.ts CHANGED
@@ -26,6 +26,7 @@ export {Service as LowCodeService};
26
26
  export * from './health';
27
27
  export * from './HealthController';
28
28
  export * from './LogController';
29
+ export * from './log';
29
30
  export * from './http';
30
31
  export * from './metadata';
31
32
  export * from './view';
package/src/log.ts ADDED
@@ -0,0 +1,150 @@
1
+ import { NextFunction } from 'express';
2
+ import { ParamsDictionary, Request, Response } from 'express-serve-static-core';
3
+ import { ParsedQs } from 'qs';
4
+ import { PassThrough } from 'stream';
5
+
6
+ export interface LogConfig {
7
+ log?: boolean;
8
+ separate?: boolean;
9
+ skips?: string;
10
+ request?: string;
11
+ response?: string;
12
+ duration?: string;
13
+ status?: string;
14
+ size?: string;
15
+ }
16
+ export interface MiddleLog {
17
+ log?: boolean;
18
+ separate?: boolean;
19
+ skips: string[];
20
+ duration: string;
21
+ request: string;
22
+ response: string;
23
+ status: string;
24
+ size: string;
25
+ }
26
+ interface SimpleMap {
27
+ [key: string]: string|number|boolean|Date;
28
+ }
29
+ export function createConfig(c?: LogConfig): MiddleLog {
30
+ if (!c) {
31
+ return {skips: [], duration: 'duration', request: '', response: '', status: '', size: ''};
32
+ }
33
+ const l: MiddleLog = {
34
+ log: c.log,
35
+ separate: c.separate,
36
+ skips: c.skips ? c.skips.split(',') : [],
37
+ duration: c.duration ? c.duration : 'duration',
38
+ request: c.request ? c.request : '',
39
+ response: c.response ? c.response : '',
40
+ status: c.status ? c.status : '',
41
+ size: c.size ? c.size : ''
42
+ };
43
+ return l;
44
+ }
45
+ export function skip(skips: string[], url: string): boolean {
46
+ if (skips.length === 0) {
47
+ return false;
48
+ }
49
+ const u = removeUrlParams(url);
50
+ for (const s of skips) {
51
+ if (u.endsWith(s)) {
52
+ return true;
53
+ }
54
+ }
55
+ return false;
56
+ }
57
+ export function removeUrlParams(url: string): string {
58
+ const startParams = url.indexOf('?');
59
+ return startParams !== -1 ? url.substring(0, startParams) : url;
60
+ }
61
+ export class Logger {
62
+ constructor(public write: (msg: string, m?: SimpleMap) => void, conf?: LogConfig, public build?: (req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>, m: SimpleMap) => SimpleMap) {
63
+ this.log = this.log.bind(this);
64
+ this.c = createConfig(conf);
65
+ }
66
+ c: MiddleLog;
67
+ log(req: Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>, number>, next: NextFunction) {
68
+ if (this.c.log && !skip(this.c.skips, req.originalUrl)) {
69
+ const start = process.hrtime();
70
+ const m = req.method;
71
+ const x = this.c.request;
72
+ let r = false;
73
+ if (m !== 'GET' && m !== 'DELETE') {
74
+ r = true;
75
+ }
76
+ const msg = `${m} ${req.originalUrl}`;
77
+ if (this.c.separate && r) {
78
+ if (this.c.request.length > 0) {
79
+ const op: SimpleMap = {};
80
+ op[x] = JSON.stringify(req.body);
81
+ if (this.build) {
82
+ const op2 = this.build(req, op);
83
+ this.write(msg, op2);
84
+ } else {
85
+ this.write(msg, op);
86
+ }
87
+ }
88
+ }
89
+ const chunks: Uint8Array[] = [];
90
+ mapResponseBody(res, chunks);
91
+ res.on('finish', () => {
92
+ const duration = getDurationInMilliseconds(start);
93
+ const op: SimpleMap = {};
94
+ op[this.c.duration] = duration;
95
+ if (r && !this.c.separate && this.c.request.length > 0) {
96
+ op[this.c.request] = JSON.stringify(req.body);
97
+ }
98
+ if (this.c.response.length > 0) {
99
+ const rsBody = Buffer.concat(chunks).toString();
100
+ op[this.c.response] = rsBody;
101
+ }
102
+ if (this.c.status.length > 0) {
103
+ op[this.c.status] = res.statusCode;
104
+ }
105
+ if (this.c.size.length > 0) {
106
+ if ('_contentLength' in res) {
107
+ op[this.c.size] = (res as any)['_contentLength'];
108
+ } else if (res.hasHeader('content-length')) {
109
+ const l = res.getHeader('content-length');
110
+ if (typeof l === 'number' || typeof l === 'string') {
111
+ op[this.c.size] = l;
112
+ }
113
+ }
114
+ }
115
+ if (this.build) {
116
+ const op2 = this.build(req, op);
117
+ this.write(msg, op2);
118
+ } else {
119
+ this.write(msg, op);
120
+ }
121
+ });
122
+ next();
123
+ } else {
124
+ next();
125
+ }
126
+ }
127
+ }
128
+ const mapResponseBody = (res: Response<any, Record<string, any>, number>, chunks: Uint8Array[]) => {
129
+ const defaultWrite = res.write.bind(res);
130
+ const defaultEnd = res.end.bind(res);
131
+ const ps = new PassThrough();
132
+
133
+ ps.on('data', (data: any) => chunks.push(data));
134
+
135
+ (res as any).write = (...args: any) => {
136
+ (ps as any).write(...args);
137
+ (defaultWrite as any)(...args);
138
+ };
139
+
140
+ (res as any).end = (...args: any) => {
141
+ ps.end(...args);
142
+ defaultEnd(...args);
143
+ };
144
+ };
145
+ const NS_PER_SEC = 1e9;
146
+ const NS_TO_MS = 1e6;
147
+ const getDurationInMilliseconds = (start: [number, number] | undefined) => {
148
+ const diff = process.hrtime(start);
149
+ return (diff[0] * NS_PER_SEC + diff[1]) / NS_TO_MS;
150
+ };