8
8
SubjectMessageEnvelope ,
9
9
SubjectMessageHeader ,
10
10
SubjectMessageOptions ,
11
- toMeshBackendProvision
11
+ toMeshBackendProvision ,
12
12
} from '../../' ;
13
13
import * as express from 'express' ;
14
14
import * as bodyParser from 'body-parser' ;
@@ -17,61 +17,82 @@ import * as httplib from 'http';
17
17
import * as urllib from 'url' ;
18
18
import * as normalizeUrl from 'normalize-url' ;
19
19
20
- const log : debug . Debugger = debug ( 'meshage' )
21
- . extend ( 'http' ) ;
20
+ const log : debug . Debugger = debug ( 'meshage' ) . extend ( 'http' ) ;
22
21
23
22
interface PreparedHttpMessage {
24
- message : SubjectMessage ;
25
- headerData : SubjectMessageHeader ;
23
+ message : SubjectMessage ;
24
+ headerData : SubjectMessageHeader ;
26
25
}
27
26
28
27
class HttpMeshBackend extends MeshBackendBase {
28
+ private app : express . Express ;
29
+ private server : httplib . Server ;
29
30
30
- private app : express . Express ;
31
- private server : httplib . Server ;
32
-
33
- constructor ( private readonly meshPrivateInternal : MeshBackend , private readonly port : number ) {
31
+ constructor (
32
+ private readonly meshPrivateInternal : MeshBackend ,
33
+ private readonly port : number
34
+ ) {
34
35
super ( ) ;
35
36
// tslint:disable-next-line:no-unsafe-any
36
37
this . handlers = this . meshPrivateInternal [ 'handlers' ] ;
37
38
}
38
39
39
- private static processParameters ( reqParams : { [ key : string ] : string } = { } , reqBody : { } ) : { [ key : string ] : string } {
40
- return Object . keys ( reqParams )
41
- . reduce ( ( params : { [ key : string ] : string } , key : string ) => {
42
- params [ key ] = reqParams [ key ] . replace ( / { ( [ ^ } ] + ) } / g, ( m : string , token : string ) => {
43
- // tslint:disable-next-line:no-parameter-reassignment
44
- token = token . replace ( / ^ b o d y \. / , '' ) ;
45
- // tslint:disable-next-line:no-unsafe-any
46
- return reqBody [ token ] || token ;
47
- } ) ;
40
+ private static processParameters (
41
+ reqParams : { [ key : string ] : string } = { } ,
42
+ reqBody : { }
43
+ ) : { [ key : string ] : string } {
44
+ return Object . keys ( reqParams ) . reduce (
45
+ ( params : { [ key : string ] : string } , key : string ) => {
46
+ params [ key ] = reqParams [ key ] . replace (
47
+ / { ( [ ^ } ] + ) } / g,
48
+ ( m : string , token : string ) => {
49
+ // tslint:disable-next-line:no-parameter-reassignment
50
+ token = token . replace ( / ^ b o d y \. / , '' ) ;
51
+ // tslint:disable-next-line:no-unsafe-any
52
+ return reqBody [ token ] || token ;
53
+ }
54
+ ) ;
48
55
return params ;
49
- } , { } ) ;
56
+ } ,
57
+ { }
58
+ ) ;
50
59
}
51
60
52
- private static prepareHttpMessage < T > ( req : express . Request ) : PreparedHttpMessage {
61
+ private static prepareHttpMessage < T > (
62
+ req : express . Request
63
+ ) : PreparedHttpMessage {
53
64
// tslint:disable-next-line:no-any
54
- let reqUrl : string ;
65
+ let reqUrl : string ;
55
66
if ( process . env . PUBLIC_URL ) {
56
- reqUrl = normalizeUrl ( [ process . env . PUBLIC_URL , req . originalUrl ] . join ( '/' ) ) ;
67
+ reqUrl = normalizeUrl (
68
+ [ process . env . PUBLIC_URL , req . originalUrl ] . join ( '/' )
69
+ ) ;
57
70
} else {
58
71
reqUrl = urllib . format ( {
59
72
protocol : req . protocol ,
60
73
host : req . headers . host ,
61
- pathname : req . originalUrl
74
+ pathname : req . originalUrl ,
62
75
} ) ;
63
76
if ( req . originalUrl . search ( / \? / ) >= 0 ) {
64
77
reqUrl = reqUrl . replace ( / % 3 F / g, '?' ) ;
65
78
}
66
79
}
67
80
// tslint:disable-next-line:no-unsafe-any
68
- const params : { [ key : string ] : string } = this . processParameters ( req . params , req . body ) ;
81
+ const params : { [ key : string ] : string } = this . processParameters (
82
+ req . params ,
83
+ req . body
84
+ ) ;
69
85
// tslint:disable-next-line:no-unsafe-any no-any
70
- const query : { [ key : string ] : string } = this . processParameters ( req . query as any , req . body ) ;
86
+ const query : { [ key : string ] : string } = this . processParameters (
87
+ req . query as any ,
88
+ req . body
89
+ ) ;
71
90
// tslint:disable-next-line:no-unsafe-any
72
- const messageName : string = query . messageName ? `${ query . messageName } ` : req . body . name ;
91
+ const messageName : string = query . messageName
92
+ ? `${ query . messageName } `
93
+ : req . body . name ;
73
94
return {
74
- message : { ...req . body } ,
95
+ message : { ...req . body } ,
75
96
headerData : {
76
97
uid : '' , // replaced later,
77
98
subject : params . subject ,
@@ -82,14 +103,14 @@ class HttpMeshBackend extends MeshBackendBase {
82
103
url : req . url ,
83
104
publicUrl : reqUrl ,
84
105
params,
85
- query
86
- }
87
- }
106
+ query,
107
+ } ,
108
+ } ,
88
109
} ;
89
110
}
90
111
91
112
// tslint:disable-next-line:no-any
92
- private static prepareHttpResponse ( result : any , res : express . Response ) {
113
+ private static prepareHttpResponse ( result : any , res : express . Response ) {
93
114
let status = 200 ;
94
115
const resultToSend = result || { } ;
95
116
let body = resultToSend ;
@@ -117,15 +138,14 @@ class HttpMeshBackend extends MeshBackendBase {
117
138
log . extend ( 'prepareHttpResponse' ) ( 'Sending %o' , body ) ;
118
139
// tslint:disable-next-line:no-unsafe-any
119
140
delete resultToSend . http ;
120
- res . status ( status )
121
- . send ( body ) ;
141
+ res . status ( status ) . send ( body ) ;
122
142
}
123
143
124
- public get subscriptionIds ( ) : string [ ] {
144
+ public get subscriptionIds ( ) : string [ ] {
125
145
return this . meshPrivateInternal . subscriptionIds ;
126
146
}
127
147
128
- public async shutdown ( ) : Promise < void > {
148
+ public async shutdown ( ) : Promise < void > {
129
149
try {
130
150
await this . meshPrivateInternal . shutdown ( ) ;
131
151
} catch ( err ) {
@@ -134,8 +154,8 @@ class HttpMeshBackend extends MeshBackendBase {
134
154
if ( this . server ) {
135
155
try {
136
156
// tslint:disable-next-line:typedef
137
- await new Promise ( ( resolve , reject ) => {
138
- this . server . close ( ( err : Error ) => {
157
+ await new Promise < void > ( ( resolve , reject ) => {
158
+ this . server . close ( ( err : Error ) => {
139
159
if ( err ) {
140
160
reject ( err ) ;
141
161
} else {
@@ -149,72 +169,100 @@ class HttpMeshBackend extends MeshBackendBase {
149
169
}
150
170
}
151
171
152
- public unregister ( subject : string ) : Promise < void > {
172
+ public unregister ( subject : string ) : Promise < void > {
153
173
return this . meshPrivateInternal . unregister ( subject ) ;
154
174
}
155
175
156
- protected async doRegistrations ( ) : Promise < void > {
176
+ protected async doRegistrations ( ) : Promise < void > {
157
177
if ( ! this . app ) {
158
178
this . app = express ( ) ;
159
179
this . app . use ( bodyParser . json ( ) ) ;
160
- this . app . use ( bodyParser . urlencoded ( { extended : true } ) ) ;
180
+ this . app . use ( bodyParser . urlencoded ( { extended : true } ) ) ;
161
181
if ( process . env . JEST_WORKER_ID ) {
162
- this . app . use ( ( req : express . Request , res : express . Response , next : express . NextFunction ) => {
163
- res . set ( 'Connection' , 'close' ) ;
164
- next ( ) ;
165
- } ) ;
182
+ this . app . use (
183
+ (
184
+ req : express . Request ,
185
+ res : express . Response ,
186
+ next : express . NextFunction
187
+ ) => {
188
+ res . set ( 'Connection' , 'close' ) ;
189
+ next ( ) ;
190
+ }
191
+ ) ;
166
192
}
167
- this . app . post ( '/api/broadcast/:subject' ,
168
- async ( req : express . Request , res : express . Response ) => {
193
+ this . app . post (
194
+ '/api/broadcast/:subject' ,
195
+ async ( req : express . Request , res : express . Response ) => {
169
196
try {
170
- const httpMessage : PreparedHttpMessage = HttpMeshBackend . prepareHttpMessage ( req ) ;
197
+ const httpMessage : PreparedHttpMessage =
198
+ HttpMeshBackend . prepareHttpMessage ( req ) ;
171
199
if ( ! httpMessage . headerData . name ) {
172
- res . status ( 400 )
173
- . send ( { error : 'Missing message name' } ) ;
200
+ res . status ( 400 ) . send ( { error : 'Missing message name' } ) ;
174
201
} else {
175
- const result = await this . send ( httpMessage . headerData . subject ,
202
+ const result = await this . send (
203
+ httpMessage . headerData . subject ,
176
204
undefined ,
177
205
httpMessage . message ,
178
206
{
179
- wait : httpMessage . headerData . http . query . wait === 'true' || httpMessage . headerData . http . query . wait === undefined ,
180
- timeout : httpMessage . headerData . http . query . timeout === undefined ? undefined : parseInt ( `${ httpMessage . headerData . http . query . timeout } ` , 10 ) ,
181
- additionalHeaderData : httpMessage . headerData
182
- } , true ) ;
207
+ wait :
208
+ httpMessage . headerData . http . query . wait === 'true' ||
209
+ httpMessage . headerData . http . query . wait === undefined ,
210
+ timeout :
211
+ httpMessage . headerData . http . query . timeout === undefined
212
+ ? undefined
213
+ : parseInt (
214
+ `${ httpMessage . headerData . http . query . timeout } ` ,
215
+ 10
216
+ ) ,
217
+ additionalHeaderData : httpMessage . headerData ,
218
+ } ,
219
+ true
220
+ ) ;
183
221
HttpMeshBackend . prepareHttpResponse ( result , res ) ;
184
222
}
185
223
} catch ( err ) {
186
- res . status ( 500 )
187
- . send ( { error : ( err as Error ) . message } ) ;
224
+ res . status ( 500 ) . send ( { error : ( err as Error ) . message } ) ;
188
225
}
189
- } ) ;
190
- this . app . post ( '/api/:subject/:partitionKey?' ,
191
- async ( req : express . Request , res : express . Response ) => {
226
+ }
227
+ ) ;
228
+ this . app . post (
229
+ '/api/:subject/:partitionKey?' ,
230
+ async ( req : express . Request , res : express . Response ) => {
192
231
try {
193
- const httpMessage : PreparedHttpMessage = HttpMeshBackend . prepareHttpMessage ( req ) ;
232
+ const httpMessage : PreparedHttpMessage =
233
+ HttpMeshBackend . prepareHttpMessage ( req ) ;
194
234
if ( ! httpMessage . headerData . name ) {
195
- res . status ( 400 )
196
- . send ( { error : 'Missing message name' } ) ;
235
+ res . status ( 400 ) . send ( { error : 'Missing message name' } ) ;
197
236
} else {
198
237
const result = await this . send (
199
238
httpMessage . headerData . subject ,
200
239
httpMessage . headerData . partitionKey ,
201
240
httpMessage . message ,
202
241
{
203
- wait : httpMessage . headerData . http . query . wait === 'true' || httpMessage . headerData . http . query . wait === undefined ,
204
- timeout : httpMessage . headerData . http . query . timeout === undefined ? undefined : parseInt ( `${ httpMessage . headerData . http . query . timeout } ` , 10 ) ,
242
+ wait :
243
+ httpMessage . headerData . http . query . wait === 'true' ||
244
+ httpMessage . headerData . http . query . wait === undefined ,
245
+ timeout :
246
+ httpMessage . headerData . http . query . timeout === undefined
247
+ ? undefined
248
+ : parseInt (
249
+ `${ httpMessage . headerData . http . query . timeout } ` ,
250
+ 10
251
+ ) ,
205
252
keepSignals : true ,
206
- additionalHeaderData : httpMessage . headerData
253
+ additionalHeaderData : httpMessage . headerData ,
207
254
} ,
208
- false ) ;
255
+ false
256
+ ) ;
209
257
HttpMeshBackend . prepareHttpResponse ( result , res ) ;
210
258
}
211
259
} catch ( err ) {
212
- res . status ( 500 )
213
- . send ( { error : ( err as Error ) . message } ) ;
260
+ res . status ( 500 ) . send ( { error : ( err as Error ) . message } ) ;
214
261
}
215
- } ) ;
262
+ }
263
+ ) ;
216
264
// tslint:disable-next-line:typedef
217
- await new Promise ( ( resolve , reject ) => {
265
+ await new Promise < void > ( ( resolve , reject ) => {
218
266
try {
219
267
if ( this . server ) {
220
268
resolve ( ) ;
@@ -233,22 +281,31 @@ class HttpMeshBackend extends MeshBackendBase {
233
281
await this . meshPrivateInternal [ 'doRegistrations' ] ( ) ;
234
282
}
235
283
236
- protected doSend < T > ( address : string ,
237
- envelope : SubjectMessageEnvelope ,
238
- options : SubjectMessageOptions ,
239
- broadcast : boolean ) : Promise < T > {
284
+ protected doSend < T > (
285
+ address : string ,
286
+ envelope : SubjectMessageEnvelope ,
287
+ options : SubjectMessageOptions ,
288
+ broadcast : boolean
289
+ ) : Promise < T > {
240
290
// tslint:disable-next-line:no-unsafe-any
241
- return this . meshPrivateInternal [ 'doSend' ] ( address , envelope , options , broadcast ) ;
291
+ return this . meshPrivateInternal [ 'doSend' ] (
292
+ address ,
293
+ envelope ,
294
+ options ,
295
+ broadcast
296
+ ) ;
242
297
}
243
-
244
298
}
245
299
246
- export function http ( provider : MeshBackendProvider , port : number ) : MeshBackendProvider {
300
+ export function http (
301
+ provider : MeshBackendProvider ,
302
+ port : number
303
+ ) : MeshBackendProvider {
247
304
return ( ) => {
248
- const provision : MeshBackendProvision = toMeshBackendProvision ( provider ( ) ) ;
305
+ const provision : MeshBackendProvision = toMeshBackendProvision ( provider ( ) ) ;
249
306
return {
250
307
backend : new HttpMeshBackend ( provision . backend , port ) ,
251
- callback : provision . callback
308
+ callback : provision . callback ,
252
309
} ;
253
310
} ;
254
311
}
0 commit comments