@moostjs/event-http 0.2.27 → 0.2.29
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/README.md +5 -3
- package/dist/index.cjs +112 -85
- package/dist/index.d.ts +29 -0
- package/dist/index.mjs +115 -88
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -20,13 +20,15 @@ import { Moost, Param } from 'moost'
|
|
|
20
20
|
class MyServer extends Moost {
|
|
21
21
|
@Get('test/:name')
|
|
22
22
|
test(@Param('name') name: string) {
|
|
23
|
-
return { message: `Hello ${
|
|
23
|
+
return { message: `Hello ${name}!` }
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
const app = new MyServer()
|
|
28
28
|
const http = new MoostHttp()
|
|
29
|
-
app.adapter(http).listen(3000, () => {
|
|
29
|
+
app.adapter(http).listen(3000, () => {
|
|
30
|
+
app.getLogger('MyApp').log('Up on port 3000')
|
|
31
|
+
})
|
|
30
32
|
app.init()
|
|
31
33
|
// curl http://localhost:3000/test/World
|
|
32
34
|
// {"message":"Hello World!"}
|
|
@@ -34,4 +36,4 @@ app.init()
|
|
|
34
36
|
|
|
35
37
|
## Install
|
|
36
38
|
|
|
37
|
-
`npm install moost @moostjs/event-http`
|
|
39
|
+
`npm install moost @moostjs/event-http`
|
package/dist/index.cjs
CHANGED
|
@@ -21,6 +21,8 @@ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
|
21
21
|
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
22
22
|
PERFORMANCE OF THIS SOFTWARE.
|
|
23
23
|
***************************************************************************** */
|
|
24
|
+
/* global Reflect, Promise */
|
|
25
|
+
|
|
24
26
|
|
|
25
27
|
function __awaiter$1(thisArg, _arguments, P, generator) {
|
|
26
28
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
@@ -32,6 +34,33 @@ function __awaiter$1(thisArg, _arguments, P, generator) {
|
|
|
32
34
|
});
|
|
33
35
|
}
|
|
34
36
|
|
|
37
|
+
const LOGGER_TITLE = 'moost-http';
|
|
38
|
+
const CONTEXT_TYPE = 'HTTP';
|
|
39
|
+
/**
|
|
40
|
+
* ## Moost HTTP Adapter
|
|
41
|
+
*
|
|
42
|
+
* Moost Adapter for HTTP events
|
|
43
|
+
*
|
|
44
|
+
* ```ts
|
|
45
|
+
* │ // HTTP server example
|
|
46
|
+
* │ import { MoostHttp, Get } from '@moostjs/event-http'
|
|
47
|
+
* │ import { Moost, Param } from 'moost'
|
|
48
|
+
* │
|
|
49
|
+
* │ class MyServer extends Moost {
|
|
50
|
+
* │ @Get('test/:name')
|
|
51
|
+
* │ test(@Param('name') name: string) {
|
|
52
|
+
* │ return { message: `Hello ${name}!` }
|
|
53
|
+
* │ }
|
|
54
|
+
* │ }
|
|
55
|
+
* │
|
|
56
|
+
* │ const app = new MyServer()
|
|
57
|
+
* │ const http = new MoostHttp()
|
|
58
|
+
* │ app.adapter(http).listen(3000, () => {
|
|
59
|
+
* │ app.getLogger('MyApp').log('Up on port 3000')
|
|
60
|
+
* │ })
|
|
61
|
+
* │ app.init()
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
35
64
|
class MoostHttp {
|
|
36
65
|
constructor(httpApp) {
|
|
37
66
|
this.pathBuilders = {};
|
|
@@ -39,10 +68,12 @@ class MoostHttp {
|
|
|
39
68
|
this.httpApp = httpApp;
|
|
40
69
|
}
|
|
41
70
|
else if (httpApp) {
|
|
42
|
-
this.httpApp = eventHttp.createHttpApp(httpApp);
|
|
71
|
+
this.httpApp = eventHttp.createHttpApp(Object.assign(Object.assign({}, httpApp), { onNotFound: this.onNotFound.bind(this) }));
|
|
43
72
|
}
|
|
44
73
|
else {
|
|
45
|
-
this.httpApp = eventHttp.createHttpApp(
|
|
74
|
+
this.httpApp = eventHttp.createHttpApp({
|
|
75
|
+
onNotFound: this.onNotFound.bind(this),
|
|
76
|
+
});
|
|
46
77
|
}
|
|
47
78
|
}
|
|
48
79
|
getHttpApp() {
|
|
@@ -54,8 +85,31 @@ class MoostHttp {
|
|
|
54
85
|
listen(...args) {
|
|
55
86
|
return this.httpApp.listen(...args);
|
|
56
87
|
}
|
|
88
|
+
onNotFound() {
|
|
89
|
+
return __awaiter$1(this, void 0, void 0, function* () {
|
|
90
|
+
const response = yield moost.defineMoostEventHandler({
|
|
91
|
+
loggerTitle: LOGGER_TITLE,
|
|
92
|
+
getIterceptorHandler: () => { var _a; return (_a = this.moost) === null || _a === void 0 ? void 0 : _a.getGlobalInterceptorHandler(); },
|
|
93
|
+
getControllerInstance: () => this.moost,
|
|
94
|
+
callControllerMethod: () => undefined,
|
|
95
|
+
})();
|
|
96
|
+
if (!response) {
|
|
97
|
+
throw new eventHttp.HttpError(404, 'Resource Not Found');
|
|
98
|
+
}
|
|
99
|
+
return response;
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
onInit(moost) {
|
|
103
|
+
this.moost = moost;
|
|
104
|
+
}
|
|
57
105
|
getProvideRegistry() {
|
|
58
|
-
return infact.createProvideRegistry([eventHttp.WooksHttp, () => this.getHttpApp()], ['WooksHttp', () => this.getHttpApp()], [
|
|
106
|
+
return infact.createProvideRegistry([eventHttp.WooksHttp, () => this.getHttpApp()], ['WooksHttp', () => this.getHttpApp()], [
|
|
107
|
+
http.Server,
|
|
108
|
+
() => this.getHttpApp().getServer(),
|
|
109
|
+
], [
|
|
110
|
+
https.Server,
|
|
111
|
+
() => this.getHttpApp().getServer(),
|
|
112
|
+
]);
|
|
59
113
|
}
|
|
60
114
|
getLogger() {
|
|
61
115
|
return this.getHttpApp().getLogger('moost-http');
|
|
@@ -66,79 +120,36 @@ class MoostHttp {
|
|
|
66
120
|
if (handler.type !== 'HTTP')
|
|
67
121
|
continue;
|
|
68
122
|
const httpPath = handler.path;
|
|
69
|
-
const path = typeof httpPath === 'string'
|
|
123
|
+
const path = typeof httpPath === 'string'
|
|
124
|
+
? httpPath
|
|
125
|
+
: typeof opts.method === 'string'
|
|
126
|
+
? opts.method
|
|
127
|
+
: '';
|
|
70
128
|
const targetPath = `${opts.prefix || ''}/${path}`.replace(/\/\/+/g, '/');
|
|
71
129
|
if (!fn) {
|
|
72
|
-
fn = (
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
yield interceptorHandler.init();
|
|
87
|
-
}
|
|
88
|
-
catch (e) {
|
|
89
|
-
logger.error(e);
|
|
90
|
-
response = e;
|
|
91
|
-
}
|
|
92
|
-
let args = [];
|
|
93
|
-
if (!response) {
|
|
94
|
-
// params
|
|
95
|
-
restoreCtx();
|
|
96
|
-
try {
|
|
97
|
-
// logger.trace(`resolving method args for "${ opts.method as string }"`)
|
|
98
|
-
args = yield opts.resolveArgs();
|
|
99
|
-
// logger.trace(`args for method "${ opts.method as string }" resolved (count ${String(args.length)})`)
|
|
100
|
-
}
|
|
101
|
-
catch (e) {
|
|
102
|
-
logger.error(e);
|
|
103
|
-
response = e;
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
if (!response) {
|
|
107
|
-
restoreCtx();
|
|
108
|
-
// fire before interceptors
|
|
109
|
-
// logger.trace('firing before interceptors')
|
|
110
|
-
response = yield interceptorHandler.fireBefore(response);
|
|
111
|
-
// fire request handler
|
|
112
|
-
if (!interceptorHandler.responseOverwritten) {
|
|
113
|
-
try {
|
|
114
|
-
restoreCtx();
|
|
115
|
-
// logger.trace(`firing method "${ opts.method as string }"`)
|
|
116
|
-
response = yield instance[opts.method](...args);
|
|
117
|
-
}
|
|
118
|
-
catch (e) {
|
|
119
|
-
logger.error(e);
|
|
120
|
-
response = e;
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
// fire after interceptors
|
|
125
|
-
restoreCtx();
|
|
126
|
-
try {
|
|
127
|
-
// logger.trace('firing after interceptors')
|
|
128
|
-
response = yield interceptorHandler.fireAfter(response);
|
|
129
|
-
}
|
|
130
|
-
catch (e) {
|
|
131
|
-
logger.error(e);
|
|
132
|
-
throw e;
|
|
133
|
-
}
|
|
134
|
-
return response;
|
|
130
|
+
fn = moost.defineMoostEventHandler({
|
|
131
|
+
contextType: CONTEXT_TYPE,
|
|
132
|
+
loggerTitle: LOGGER_TITLE,
|
|
133
|
+
getIterceptorHandler: opts.getIterceptorHandler,
|
|
134
|
+
getControllerInstance: opts.getInstance,
|
|
135
|
+
controllerMethod: opts.method,
|
|
136
|
+
resolveArgs: opts.resolveArgs,
|
|
137
|
+
manualUnscope: true,
|
|
138
|
+
hooks: {
|
|
139
|
+
init: ({ unscope }) => {
|
|
140
|
+
const { rawRequest } = eventHttp.useRequest();
|
|
141
|
+
rawRequest.on('end', unscope); // will unscope on request end
|
|
142
|
+
},
|
|
143
|
+
},
|
|
135
144
|
});
|
|
136
145
|
}
|
|
137
|
-
const pathBuilder = this.httpApp.on(handler.method, targetPath, fn);
|
|
138
|
-
const methodMeta = moost.getMoostMate().read(opts.fakeInstance, opts.method) ||
|
|
146
|
+
const { getPath: pathBuilder } = this.httpApp.on(handler.method, targetPath, fn);
|
|
147
|
+
const methodMeta = moost.getMoostMate().read(opts.fakeInstance, opts.method) ||
|
|
148
|
+
{};
|
|
139
149
|
const id = (methodMeta.id || opts.method);
|
|
140
150
|
if (id) {
|
|
141
|
-
const methods = this.pathBuilders[id] =
|
|
151
|
+
const methods = (this.pathBuilders[id] =
|
|
152
|
+
this.pathBuilders[id] || {});
|
|
142
153
|
if (handler.method === '*') {
|
|
143
154
|
methods.GET = pathBuilder;
|
|
144
155
|
methods.PUT = pathBuilder;
|
|
@@ -179,6 +190,8 @@ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
|
179
190
|
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
180
191
|
PERFORMANCE OF THIS SOFTWARE.
|
|
181
192
|
***************************************************************************** */
|
|
193
|
+
/* global Reflect, Promise */
|
|
194
|
+
|
|
182
195
|
|
|
183
196
|
function __awaiter(thisArg, _arguments, P, generator) {
|
|
184
197
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
@@ -192,8 +205,8 @@ function __awaiter(thisArg, _arguments, P, generator) {
|
|
|
192
205
|
|
|
193
206
|
const compressors = {
|
|
194
207
|
identity: {
|
|
195
|
-
compress: v => v,
|
|
196
|
-
uncompress: v => v,
|
|
208
|
+
compress: (v) => v,
|
|
209
|
+
uncompress: (v) => v,
|
|
197
210
|
},
|
|
198
211
|
};
|
|
199
212
|
function uncompressBody(encodings, body) {
|
|
@@ -232,7 +245,10 @@ function useBody() {
|
|
|
232
245
|
}
|
|
233
246
|
return false;
|
|
234
247
|
});
|
|
235
|
-
const contentEncodings = () => init('contentEncodings', () => (contentEncoding || '')
|
|
248
|
+
const contentEncodings = () => init('contentEncodings', () => (contentEncoding || '')
|
|
249
|
+
.split(',')
|
|
250
|
+
.map((p) => p.trim())
|
|
251
|
+
.filter((p) => !!p));
|
|
236
252
|
const parseBody = () => init('parsed', () => __awaiter(this, void 0, void 0, function* () {
|
|
237
253
|
const body = yield uncompressBody(contentEncodings(), (yield rawBody()).toString());
|
|
238
254
|
if (isJson())
|
|
@@ -258,7 +274,8 @@ function useBody() {
|
|
|
258
274
|
return v;
|
|
259
275
|
}
|
|
260
276
|
function formDataParser(v) {
|
|
261
|
-
const boundary = '--' +
|
|
277
|
+
const boundary = '--' +
|
|
278
|
+
(/boundary=([^;]+)(?:;|$)/.exec(contentType || '') || [, ''])[1];
|
|
262
279
|
if (!boundary)
|
|
263
280
|
throw new eventHttp.HttpError(eventHttp.EHttpStatusCode.BadRequest, 'form-data boundary not recognized');
|
|
264
281
|
const parts = v.trim().split(boundary);
|
|
@@ -270,7 +287,10 @@ function useBody() {
|
|
|
270
287
|
key = '';
|
|
271
288
|
partContentType = 'text/plain';
|
|
272
289
|
let valueMode = false;
|
|
273
|
-
const lines = part
|
|
290
|
+
const lines = part
|
|
291
|
+
.trim()
|
|
292
|
+
.split(/\n/g)
|
|
293
|
+
.map((s) => s.trim());
|
|
274
294
|
for (const line of lines) {
|
|
275
295
|
if (valueMode) {
|
|
276
296
|
if (!result[key]) {
|
|
@@ -288,7 +308,9 @@ function useBody() {
|
|
|
288
308
|
}
|
|
289
309
|
continue;
|
|
290
310
|
}
|
|
291
|
-
if (line
|
|
311
|
+
if (line
|
|
312
|
+
.toLowerCase()
|
|
313
|
+
.startsWith('content-disposition: form-data;')) {
|
|
292
314
|
key = (/name=([^;]+)/.exec(line) || [])[1];
|
|
293
315
|
if (!key)
|
|
294
316
|
throw new eventHttp.HttpError(eventHttp.EHttpStatusCode.BadRequest, 'Could not read multipart name: ' + line);
|
|
@@ -345,7 +367,7 @@ const StatusHook = () => moost.Resolve((metas, level) => {
|
|
|
345
367
|
const initialValue = metas.instance[metas.key];
|
|
346
368
|
eventCore.attachHook(metas.instance, {
|
|
347
369
|
get: () => hook.value,
|
|
348
|
-
set: (v) => hook.value = v,
|
|
370
|
+
set: (v) => (hook.value = v),
|
|
349
371
|
}, metas.key);
|
|
350
372
|
return typeof initialValue === 'number' ? initialValue : 200;
|
|
351
373
|
}
|
|
@@ -365,7 +387,7 @@ const HeaderHook = (name) => moost.Resolve((metas, level) => {
|
|
|
365
387
|
const initialValue = metas.instance[metas.key];
|
|
366
388
|
eventCore.attachHook(metas.instance, {
|
|
367
389
|
get: () => hook.value,
|
|
368
|
-
set: (v) => hook.value = v,
|
|
390
|
+
set: (v) => (hook.value = v),
|
|
369
391
|
}, metas.key);
|
|
370
392
|
return typeof initialValue === 'string' ? initialValue : '';
|
|
371
393
|
}
|
|
@@ -385,7 +407,7 @@ const CookieHook = (name) => moost.Resolve((metas, level) => {
|
|
|
385
407
|
const initialValue = metas.instance[metas.key];
|
|
386
408
|
eventCore.attachHook(metas.instance, {
|
|
387
409
|
get: () => hook.value,
|
|
388
|
-
set: (v) => hook.value = v,
|
|
410
|
+
set: (v) => (hook.value = v),
|
|
389
411
|
}, metas.key);
|
|
390
412
|
return typeof initialValue === 'string' ? initialValue : '';
|
|
391
413
|
}
|
|
@@ -401,14 +423,14 @@ const CookieAttrsHook = (name) => moost.Resolve((metas, level) => {
|
|
|
401
423
|
if (level === 'PARAM') {
|
|
402
424
|
return eventCore.attachHook({}, {
|
|
403
425
|
get: () => hook.attrs,
|
|
404
|
-
set: (v) => hook.attrs = v,
|
|
426
|
+
set: (v) => (hook.attrs = v),
|
|
405
427
|
});
|
|
406
428
|
}
|
|
407
429
|
if (level === 'PROP' && metas.instance && metas.key) {
|
|
408
430
|
const initialValue = metas.instance[metas.key];
|
|
409
431
|
eventCore.attachHook(metas.instance, {
|
|
410
432
|
get: () => hook.attrs,
|
|
411
|
-
set: (v) => hook.attrs = v,
|
|
433
|
+
set: (v) => (hook.attrs = v),
|
|
412
434
|
}, metas.key);
|
|
413
435
|
return typeof initialValue === 'object' ? initialValue : {};
|
|
414
436
|
}
|
|
@@ -425,9 +447,13 @@ function Authorization(name) {
|
|
|
425
447
|
const auth = eventHttp.useAuthorization();
|
|
426
448
|
switch (name) {
|
|
427
449
|
case 'username':
|
|
428
|
-
return auth.isBasic()
|
|
450
|
+
return auth.isBasic()
|
|
451
|
+
? (_a = auth.basicCredentials()) === null || _a === void 0 ? void 0 : _a.username
|
|
452
|
+
: undefined;
|
|
429
453
|
case 'password':
|
|
430
|
-
return auth.isBasic()
|
|
454
|
+
return auth.isBasic()
|
|
455
|
+
? (_b = auth.basicCredentials()) === null || _b === void 0 ? void 0 : _b.password
|
|
456
|
+
: undefined;
|
|
431
457
|
case 'bearer':
|
|
432
458
|
return auth.isBearer() ? auth.authorization : undefined;
|
|
433
459
|
case 'raw':
|
|
@@ -470,7 +496,7 @@ function Query(name) {
|
|
|
470
496
|
if (name) {
|
|
471
497
|
const p = urlSearchParams();
|
|
472
498
|
const value = p.get(name);
|
|
473
|
-
return value === '' && p.has(name) || value;
|
|
499
|
+
return (value === '' && p.has(name)) || value;
|
|
474
500
|
}
|
|
475
501
|
const json = jsonSearchParams();
|
|
476
502
|
return Object.keys(json).length ? json : null;
|
|
@@ -555,7 +581,8 @@ const setHeaderInterceptor = (name, value, opts) => {
|
|
|
555
581
|
const h = eventHttp.useSetHeader(name);
|
|
556
582
|
const status = eventHttp.useStatus();
|
|
557
583
|
after(() => {
|
|
558
|
-
if ((!h.value || (opts === null || opts === void 0 ? void 0 : opts.force)) &&
|
|
584
|
+
if ((!h.value || (opts === null || opts === void 0 ? void 0 : opts.force)) &&
|
|
585
|
+
(!(opts === null || opts === void 0 ? void 0 : opts.status) || opts.status === status.value)) {
|
|
559
586
|
h.value = value;
|
|
560
587
|
}
|
|
561
588
|
});
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
|
|
3
3
|
import { IncomingMessage } from 'http';
|
|
4
|
+
import { Moost } from 'moost';
|
|
4
5
|
import { ServerResponse } from 'http';
|
|
5
6
|
import { TConsoleBase } from '@prostojs/logger';
|
|
6
7
|
import { TCookieAttributesInput } from '@wooksjs/event-http';
|
|
@@ -104,6 +105,31 @@ export declare function IpList(): ParameterDecorator & PropertyDecorator;
|
|
|
104
105
|
*/
|
|
105
106
|
export declare function Method(): ParameterDecorator & PropertyDecorator;
|
|
106
107
|
|
|
108
|
+
/**
|
|
109
|
+
* ## Moost HTTP Adapter
|
|
110
|
+
*
|
|
111
|
+
* Moost Adapter for HTTP events
|
|
112
|
+
*
|
|
113
|
+
* ```ts
|
|
114
|
+
* │ // HTTP server example
|
|
115
|
+
* │ import { MoostHttp, Get } from '@moostjs/event-http'
|
|
116
|
+
* │ import { Moost, Param } from 'moost'
|
|
117
|
+
* │
|
|
118
|
+
* │ class MyServer extends Moost {
|
|
119
|
+
* │ @Get('test/:name')
|
|
120
|
+
* │ test(@Param('name') name: string) {
|
|
121
|
+
* │ return { message: `Hello ${name}!` }
|
|
122
|
+
* │ }
|
|
123
|
+
* │ }
|
|
124
|
+
* │
|
|
125
|
+
* │ const app = new MyServer()
|
|
126
|
+
* │ const http = new MoostHttp()
|
|
127
|
+
* │ app.adapter(http).listen(3000, () => {
|
|
128
|
+
* │ app.getLogger('MyApp').log('Up on port 3000')
|
|
129
|
+
* │ })
|
|
130
|
+
* │ app.init()
|
|
131
|
+
* ```
|
|
132
|
+
*/
|
|
107
133
|
export declare class MoostHttp implements TMoostAdapter<THttpHandlerMeta> {
|
|
108
134
|
protected httpApp: WooksHttp;
|
|
109
135
|
constructor(httpApp?: WooksHttp | TWooksHttpOptions);
|
|
@@ -119,6 +145,9 @@ export declare class MoostHttp implements TMoostAdapter<THttpHandlerMeta> {
|
|
|
119
145
|
DELETE?: TProstoRouterPathBuilder<Record<string, string | string[]>>;
|
|
120
146
|
};
|
|
121
147
|
};
|
|
148
|
+
onNotFound(): Promise<{}>;
|
|
149
|
+
protected moost?: Moost;
|
|
150
|
+
onInit(moost: Moost): void;
|
|
122
151
|
getProvideRegistry(): TProvideRegistry;
|
|
123
152
|
getLogger(): TConsoleBase;
|
|
124
153
|
bindHandler<T extends object = object>(opts: TMoostAdapterOptions<THttpHandlerMeta, T>): void | Promise<void>;
|
package/dist/index.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { WooksHttp, createHttpApp,
|
|
2
|
-
import {
|
|
1
|
+
import { WooksHttp, createHttpApp, useRequest, HttpError, useHttpContext, useHeaders, EHttpStatusCode, WooksURLSearchParams, useStatus, useSetHeader, useSetCookie, useAuthorization, useCookies, useSearchParams, useResponse, useSetCookies } from '@wooksjs/event-http';
|
|
2
|
+
import { defineMoostEventHandler, getMoostMate, Resolve, Intercept, TInterceptorPriority, validatePipe } from 'moost';
|
|
3
3
|
import { createProvideRegistry } from '@prostojs/infact';
|
|
4
4
|
import { Server } from 'http';
|
|
5
5
|
import { Server as Server$1 } from 'https';
|
|
6
|
-
import {
|
|
6
|
+
import { attachHook } from '@wooksjs/event-core';
|
|
7
7
|
|
|
8
8
|
/******************************************************************************
|
|
9
9
|
Copyright (c) Microsoft Corporation.
|
|
@@ -19,6 +19,8 @@ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
|
19
19
|
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
20
20
|
PERFORMANCE OF THIS SOFTWARE.
|
|
21
21
|
***************************************************************************** */
|
|
22
|
+
/* global Reflect, Promise */
|
|
23
|
+
|
|
22
24
|
|
|
23
25
|
function __awaiter$1(thisArg, _arguments, P, generator) {
|
|
24
26
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
@@ -30,6 +32,33 @@ function __awaiter$1(thisArg, _arguments, P, generator) {
|
|
|
30
32
|
});
|
|
31
33
|
}
|
|
32
34
|
|
|
35
|
+
const LOGGER_TITLE = 'moost-http';
|
|
36
|
+
const CONTEXT_TYPE = 'HTTP';
|
|
37
|
+
/**
|
|
38
|
+
* ## Moost HTTP Adapter
|
|
39
|
+
*
|
|
40
|
+
* Moost Adapter for HTTP events
|
|
41
|
+
*
|
|
42
|
+
* ```ts
|
|
43
|
+
* │ // HTTP server example
|
|
44
|
+
* │ import { MoostHttp, Get } from '@moostjs/event-http'
|
|
45
|
+
* │ import { Moost, Param } from 'moost'
|
|
46
|
+
* │
|
|
47
|
+
* │ class MyServer extends Moost {
|
|
48
|
+
* │ @Get('test/:name')
|
|
49
|
+
* │ test(@Param('name') name: string) {
|
|
50
|
+
* │ return { message: `Hello ${name}!` }
|
|
51
|
+
* │ }
|
|
52
|
+
* │ }
|
|
53
|
+
* │
|
|
54
|
+
* │ const app = new MyServer()
|
|
55
|
+
* │ const http = new MoostHttp()
|
|
56
|
+
* │ app.adapter(http).listen(3000, () => {
|
|
57
|
+
* │ app.getLogger('MyApp').log('Up on port 3000')
|
|
58
|
+
* │ })
|
|
59
|
+
* │ app.init()
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
33
62
|
class MoostHttp {
|
|
34
63
|
constructor(httpApp) {
|
|
35
64
|
this.pathBuilders = {};
|
|
@@ -37,10 +66,12 @@ class MoostHttp {
|
|
|
37
66
|
this.httpApp = httpApp;
|
|
38
67
|
}
|
|
39
68
|
else if (httpApp) {
|
|
40
|
-
this.httpApp = createHttpApp(httpApp);
|
|
69
|
+
this.httpApp = createHttpApp(Object.assign(Object.assign({}, httpApp), { onNotFound: this.onNotFound.bind(this) }));
|
|
41
70
|
}
|
|
42
71
|
else {
|
|
43
|
-
this.httpApp = createHttpApp(
|
|
72
|
+
this.httpApp = createHttpApp({
|
|
73
|
+
onNotFound: this.onNotFound.bind(this),
|
|
74
|
+
});
|
|
44
75
|
}
|
|
45
76
|
}
|
|
46
77
|
getHttpApp() {
|
|
@@ -52,8 +83,31 @@ class MoostHttp {
|
|
|
52
83
|
listen(...args) {
|
|
53
84
|
return this.httpApp.listen(...args);
|
|
54
85
|
}
|
|
86
|
+
onNotFound() {
|
|
87
|
+
return __awaiter$1(this, void 0, void 0, function* () {
|
|
88
|
+
const response = yield defineMoostEventHandler({
|
|
89
|
+
loggerTitle: LOGGER_TITLE,
|
|
90
|
+
getIterceptorHandler: () => { var _a; return (_a = this.moost) === null || _a === void 0 ? void 0 : _a.getGlobalInterceptorHandler(); },
|
|
91
|
+
getControllerInstance: () => this.moost,
|
|
92
|
+
callControllerMethod: () => undefined,
|
|
93
|
+
})();
|
|
94
|
+
if (!response) {
|
|
95
|
+
throw new HttpError(404, 'Resource Not Found');
|
|
96
|
+
}
|
|
97
|
+
return response;
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
onInit(moost) {
|
|
101
|
+
this.moost = moost;
|
|
102
|
+
}
|
|
55
103
|
getProvideRegistry() {
|
|
56
|
-
return createProvideRegistry([WooksHttp, () => this.getHttpApp()], ['WooksHttp', () => this.getHttpApp()], [
|
|
104
|
+
return createProvideRegistry([WooksHttp, () => this.getHttpApp()], ['WooksHttp', () => this.getHttpApp()], [
|
|
105
|
+
Server,
|
|
106
|
+
() => this.getHttpApp().getServer(),
|
|
107
|
+
], [
|
|
108
|
+
Server$1,
|
|
109
|
+
() => this.getHttpApp().getServer(),
|
|
110
|
+
]);
|
|
57
111
|
}
|
|
58
112
|
getLogger() {
|
|
59
113
|
return this.getHttpApp().getLogger('moost-http');
|
|
@@ -64,79 +118,36 @@ class MoostHttp {
|
|
|
64
118
|
if (handler.type !== 'HTTP')
|
|
65
119
|
continue;
|
|
66
120
|
const httpPath = handler.path;
|
|
67
|
-
const path = typeof httpPath === 'string'
|
|
121
|
+
const path = typeof httpPath === 'string'
|
|
122
|
+
? httpPath
|
|
123
|
+
: typeof opts.method === 'string'
|
|
124
|
+
? opts.method
|
|
125
|
+
: '';
|
|
68
126
|
const targetPath = `${opts.prefix || ''}/${path}`.replace(/\/\/+/g, '/');
|
|
69
127
|
if (!fn) {
|
|
70
|
-
fn = (
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
yield interceptorHandler.init();
|
|
85
|
-
}
|
|
86
|
-
catch (e) {
|
|
87
|
-
logger.error(e);
|
|
88
|
-
response = e;
|
|
89
|
-
}
|
|
90
|
-
let args = [];
|
|
91
|
-
if (!response) {
|
|
92
|
-
// params
|
|
93
|
-
restoreCtx();
|
|
94
|
-
try {
|
|
95
|
-
// logger.trace(`resolving method args for "${ opts.method as string }"`)
|
|
96
|
-
args = yield opts.resolveArgs();
|
|
97
|
-
// logger.trace(`args for method "${ opts.method as string }" resolved (count ${String(args.length)})`)
|
|
98
|
-
}
|
|
99
|
-
catch (e) {
|
|
100
|
-
logger.error(e);
|
|
101
|
-
response = e;
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
if (!response) {
|
|
105
|
-
restoreCtx();
|
|
106
|
-
// fire before interceptors
|
|
107
|
-
// logger.trace('firing before interceptors')
|
|
108
|
-
response = yield interceptorHandler.fireBefore(response);
|
|
109
|
-
// fire request handler
|
|
110
|
-
if (!interceptorHandler.responseOverwritten) {
|
|
111
|
-
try {
|
|
112
|
-
restoreCtx();
|
|
113
|
-
// logger.trace(`firing method "${ opts.method as string }"`)
|
|
114
|
-
response = yield instance[opts.method](...args);
|
|
115
|
-
}
|
|
116
|
-
catch (e) {
|
|
117
|
-
logger.error(e);
|
|
118
|
-
response = e;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
// fire after interceptors
|
|
123
|
-
restoreCtx();
|
|
124
|
-
try {
|
|
125
|
-
// logger.trace('firing after interceptors')
|
|
126
|
-
response = yield interceptorHandler.fireAfter(response);
|
|
127
|
-
}
|
|
128
|
-
catch (e) {
|
|
129
|
-
logger.error(e);
|
|
130
|
-
throw e;
|
|
131
|
-
}
|
|
132
|
-
return response;
|
|
128
|
+
fn = defineMoostEventHandler({
|
|
129
|
+
contextType: CONTEXT_TYPE,
|
|
130
|
+
loggerTitle: LOGGER_TITLE,
|
|
131
|
+
getIterceptorHandler: opts.getIterceptorHandler,
|
|
132
|
+
getControllerInstance: opts.getInstance,
|
|
133
|
+
controllerMethod: opts.method,
|
|
134
|
+
resolveArgs: opts.resolveArgs,
|
|
135
|
+
manualUnscope: true,
|
|
136
|
+
hooks: {
|
|
137
|
+
init: ({ unscope }) => {
|
|
138
|
+
const { rawRequest } = useRequest();
|
|
139
|
+
rawRequest.on('end', unscope); // will unscope on request end
|
|
140
|
+
},
|
|
141
|
+
},
|
|
133
142
|
});
|
|
134
143
|
}
|
|
135
|
-
const pathBuilder = this.httpApp.on(handler.method, targetPath, fn);
|
|
136
|
-
const methodMeta = getMoostMate().read(opts.fakeInstance, opts.method) ||
|
|
144
|
+
const { getPath: pathBuilder } = this.httpApp.on(handler.method, targetPath, fn);
|
|
145
|
+
const methodMeta = getMoostMate().read(opts.fakeInstance, opts.method) ||
|
|
146
|
+
{};
|
|
137
147
|
const id = (methodMeta.id || opts.method);
|
|
138
148
|
if (id) {
|
|
139
|
-
const methods = this.pathBuilders[id] =
|
|
149
|
+
const methods = (this.pathBuilders[id] =
|
|
150
|
+
this.pathBuilders[id] || {});
|
|
140
151
|
if (handler.method === '*') {
|
|
141
152
|
methods.GET = pathBuilder;
|
|
142
153
|
methods.PUT = pathBuilder;
|
|
@@ -177,6 +188,8 @@ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
|
177
188
|
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
178
189
|
PERFORMANCE OF THIS SOFTWARE.
|
|
179
190
|
***************************************************************************** */
|
|
191
|
+
/* global Reflect, Promise */
|
|
192
|
+
|
|
180
193
|
|
|
181
194
|
function __awaiter(thisArg, _arguments, P, generator) {
|
|
182
195
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
@@ -190,8 +203,8 @@ function __awaiter(thisArg, _arguments, P, generator) {
|
|
|
190
203
|
|
|
191
204
|
const compressors = {
|
|
192
205
|
identity: {
|
|
193
|
-
compress: v => v,
|
|
194
|
-
uncompress: v => v,
|
|
206
|
+
compress: (v) => v,
|
|
207
|
+
uncompress: (v) => v,
|
|
195
208
|
},
|
|
196
209
|
};
|
|
197
210
|
function uncompressBody(encodings, body) {
|
|
@@ -230,7 +243,10 @@ function useBody() {
|
|
|
230
243
|
}
|
|
231
244
|
return false;
|
|
232
245
|
});
|
|
233
|
-
const contentEncodings = () => init('contentEncodings', () => (contentEncoding || '')
|
|
246
|
+
const contentEncodings = () => init('contentEncodings', () => (contentEncoding || '')
|
|
247
|
+
.split(',')
|
|
248
|
+
.map((p) => p.trim())
|
|
249
|
+
.filter((p) => !!p));
|
|
234
250
|
const parseBody = () => init('parsed', () => __awaiter(this, void 0, void 0, function* () {
|
|
235
251
|
const body = yield uncompressBody(contentEncodings(), (yield rawBody()).toString());
|
|
236
252
|
if (isJson())
|
|
@@ -256,7 +272,8 @@ function useBody() {
|
|
|
256
272
|
return v;
|
|
257
273
|
}
|
|
258
274
|
function formDataParser(v) {
|
|
259
|
-
const boundary = '--' +
|
|
275
|
+
const boundary = '--' +
|
|
276
|
+
(/boundary=([^;]+)(?:;|$)/.exec(contentType || '') || [, ''])[1];
|
|
260
277
|
if (!boundary)
|
|
261
278
|
throw new HttpError(EHttpStatusCode.BadRequest, 'form-data boundary not recognized');
|
|
262
279
|
const parts = v.trim().split(boundary);
|
|
@@ -268,7 +285,10 @@ function useBody() {
|
|
|
268
285
|
key = '';
|
|
269
286
|
partContentType = 'text/plain';
|
|
270
287
|
let valueMode = false;
|
|
271
|
-
const lines = part
|
|
288
|
+
const lines = part
|
|
289
|
+
.trim()
|
|
290
|
+
.split(/\n/g)
|
|
291
|
+
.map((s) => s.trim());
|
|
272
292
|
for (const line of lines) {
|
|
273
293
|
if (valueMode) {
|
|
274
294
|
if (!result[key]) {
|
|
@@ -286,7 +306,9 @@ function useBody() {
|
|
|
286
306
|
}
|
|
287
307
|
continue;
|
|
288
308
|
}
|
|
289
|
-
if (line
|
|
309
|
+
if (line
|
|
310
|
+
.toLowerCase()
|
|
311
|
+
.startsWith('content-disposition: form-data;')) {
|
|
290
312
|
key = (/name=([^;]+)/.exec(line) || [])[1];
|
|
291
313
|
if (!key)
|
|
292
314
|
throw new HttpError(EHttpStatusCode.BadRequest, 'Could not read multipart name: ' + line);
|
|
@@ -343,7 +365,7 @@ const StatusHook = () => Resolve((metas, level) => {
|
|
|
343
365
|
const initialValue = metas.instance[metas.key];
|
|
344
366
|
attachHook(metas.instance, {
|
|
345
367
|
get: () => hook.value,
|
|
346
|
-
set: (v) => hook.value = v,
|
|
368
|
+
set: (v) => (hook.value = v),
|
|
347
369
|
}, metas.key);
|
|
348
370
|
return typeof initialValue === 'number' ? initialValue : 200;
|
|
349
371
|
}
|
|
@@ -363,7 +385,7 @@ const HeaderHook = (name) => Resolve((metas, level) => {
|
|
|
363
385
|
const initialValue = metas.instance[metas.key];
|
|
364
386
|
attachHook(metas.instance, {
|
|
365
387
|
get: () => hook.value,
|
|
366
|
-
set: (v) => hook.value = v,
|
|
388
|
+
set: (v) => (hook.value = v),
|
|
367
389
|
}, metas.key);
|
|
368
390
|
return typeof initialValue === 'string' ? initialValue : '';
|
|
369
391
|
}
|
|
@@ -383,7 +405,7 @@ const CookieHook = (name) => Resolve((metas, level) => {
|
|
|
383
405
|
const initialValue = metas.instance[metas.key];
|
|
384
406
|
attachHook(metas.instance, {
|
|
385
407
|
get: () => hook.value,
|
|
386
|
-
set: (v) => hook.value = v,
|
|
408
|
+
set: (v) => (hook.value = v),
|
|
387
409
|
}, metas.key);
|
|
388
410
|
return typeof initialValue === 'string' ? initialValue : '';
|
|
389
411
|
}
|
|
@@ -399,14 +421,14 @@ const CookieAttrsHook = (name) => Resolve((metas, level) => {
|
|
|
399
421
|
if (level === 'PARAM') {
|
|
400
422
|
return attachHook({}, {
|
|
401
423
|
get: () => hook.attrs,
|
|
402
|
-
set: (v) => hook.attrs = v,
|
|
424
|
+
set: (v) => (hook.attrs = v),
|
|
403
425
|
});
|
|
404
426
|
}
|
|
405
427
|
if (level === 'PROP' && metas.instance && metas.key) {
|
|
406
428
|
const initialValue = metas.instance[metas.key];
|
|
407
429
|
attachHook(metas.instance, {
|
|
408
430
|
get: () => hook.attrs,
|
|
409
|
-
set: (v) => hook.attrs = v,
|
|
431
|
+
set: (v) => (hook.attrs = v),
|
|
410
432
|
}, metas.key);
|
|
411
433
|
return typeof initialValue === 'object' ? initialValue : {};
|
|
412
434
|
}
|
|
@@ -423,9 +445,13 @@ function Authorization(name) {
|
|
|
423
445
|
const auth = useAuthorization();
|
|
424
446
|
switch (name) {
|
|
425
447
|
case 'username':
|
|
426
|
-
return auth.isBasic()
|
|
448
|
+
return auth.isBasic()
|
|
449
|
+
? (_a = auth.basicCredentials()) === null || _a === void 0 ? void 0 : _a.username
|
|
450
|
+
: undefined;
|
|
427
451
|
case 'password':
|
|
428
|
-
return auth.isBasic()
|
|
452
|
+
return auth.isBasic()
|
|
453
|
+
? (_b = auth.basicCredentials()) === null || _b === void 0 ? void 0 : _b.password
|
|
454
|
+
: undefined;
|
|
429
455
|
case 'bearer':
|
|
430
456
|
return auth.isBearer() ? auth.authorization : undefined;
|
|
431
457
|
case 'raw':
|
|
@@ -468,7 +494,7 @@ function Query(name) {
|
|
|
468
494
|
if (name) {
|
|
469
495
|
const p = urlSearchParams();
|
|
470
496
|
const value = p.get(name);
|
|
471
|
-
return value === '' && p.has(name) || value;
|
|
497
|
+
return (value === '' && p.has(name)) || value;
|
|
472
498
|
}
|
|
473
499
|
const json = jsonSearchParams();
|
|
474
500
|
return Object.keys(json).length ? json : null;
|
|
@@ -553,7 +579,8 @@ const setHeaderInterceptor = (name, value, opts) => {
|
|
|
553
579
|
const h = useSetHeader(name);
|
|
554
580
|
const status = useStatus();
|
|
555
581
|
after(() => {
|
|
556
|
-
if ((!h.value || (opts === null || opts === void 0 ? void 0 : opts.force)) &&
|
|
582
|
+
if ((!h.value || (opts === null || opts === void 0 ? void 0 : opts.force)) &&
|
|
583
|
+
(!(opts === null || opts === void 0 ? void 0 : opts.status) || opts.status === status.value)) {
|
|
557
584
|
h.value = value;
|
|
558
585
|
}
|
|
559
586
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@moostjs/event-http",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.29",
|
|
4
4
|
"description": "@moostjs/event-http",
|
|
5
5
|
"main": "dist/index.cjs",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -29,10 +29,10 @@
|
|
|
29
29
|
"homepage": "https://github.com/moostjs/moostjs/tree/main/packages/event-http#readme",
|
|
30
30
|
"peerDependencies": {},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"moost": "0.2.
|
|
33
|
-
"@wooksjs/event-core": "^0.2.
|
|
34
|
-
"@wooksjs/event-http": "^0.2.
|
|
32
|
+
"moost": "0.2.29",
|
|
33
|
+
"@wooksjs/event-core": "^0.2.23",
|
|
34
|
+
"@wooksjs/event-http": "^0.2.23",
|
|
35
35
|
"@prostojs/infact": "^0.1.11",
|
|
36
|
-
"@prostojs/router": "^0.0
|
|
36
|
+
"@prostojs/router": "^0.1.0"
|
|
37
37
|
}
|
|
38
38
|
}
|