@moostjs/event-http 0.2.26 → 0.2.28
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 -89
- package/dist/index.d.ts +29 -0
- package/dist/index.mjs +115 -92
- 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,83 +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
|
-
const interceptorHandler = yield opts.getIterceptorHandler();
|
|
87
|
-
restoreCtx();
|
|
88
|
-
try {
|
|
89
|
-
// logger.trace('initializing interceptors')
|
|
90
|
-
yield interceptorHandler.init();
|
|
91
|
-
}
|
|
92
|
-
catch (e) {
|
|
93
|
-
logger.error(e);
|
|
94
|
-
response = e;
|
|
95
|
-
}
|
|
96
|
-
let args = [];
|
|
97
|
-
if (!response) {
|
|
98
|
-
// params
|
|
99
|
-
restoreCtx();
|
|
100
|
-
try {
|
|
101
|
-
// logger.trace(`resolving method args for "${ opts.method as string }"`)
|
|
102
|
-
args = yield opts.resolveArgs();
|
|
103
|
-
// logger.trace(`args for method "${ opts.method as string }" resolved (count ${String(args.length)})`)
|
|
104
|
-
}
|
|
105
|
-
catch (e) {
|
|
106
|
-
logger.error(e);
|
|
107
|
-
response = e;
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
if (!response) {
|
|
111
|
-
restoreCtx();
|
|
112
|
-
// fire before interceptors
|
|
113
|
-
// logger.trace('firing before interceptors')
|
|
114
|
-
response = yield interceptorHandler.fireBefore(response);
|
|
115
|
-
// fire request handler
|
|
116
|
-
if (!interceptorHandler.responseOverwritten) {
|
|
117
|
-
try {
|
|
118
|
-
restoreCtx();
|
|
119
|
-
// logger.trace(`firing method "${ opts.method as string }"`)
|
|
120
|
-
response = yield instance[opts.method](...args);
|
|
121
|
-
}
|
|
122
|
-
catch (e) {
|
|
123
|
-
logger.error(e);
|
|
124
|
-
response = e;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
// fire after interceptors
|
|
129
|
-
restoreCtx();
|
|
130
|
-
try {
|
|
131
|
-
// logger.trace('firing after interceptors')
|
|
132
|
-
response = yield interceptorHandler.fireAfter(response);
|
|
133
|
-
}
|
|
134
|
-
catch (e) {
|
|
135
|
-
logger.error(e);
|
|
136
|
-
throw e;
|
|
137
|
-
}
|
|
138
|
-
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
|
+
},
|
|
139
144
|
});
|
|
140
145
|
}
|
|
141
|
-
const pathBuilder = this.httpApp.on(handler.method, targetPath, fn);
|
|
142
|
-
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
|
+
{};
|
|
143
149
|
const id = (methodMeta.id || opts.method);
|
|
144
150
|
if (id) {
|
|
145
|
-
const methods = this.pathBuilders[id] =
|
|
151
|
+
const methods = (this.pathBuilders[id] =
|
|
152
|
+
this.pathBuilders[id] || {});
|
|
146
153
|
if (handler.method === '*') {
|
|
147
154
|
methods.GET = pathBuilder;
|
|
148
155
|
methods.PUT = pathBuilder;
|
|
@@ -183,6 +190,8 @@ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
|
183
190
|
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
184
191
|
PERFORMANCE OF THIS SOFTWARE.
|
|
185
192
|
***************************************************************************** */
|
|
193
|
+
/* global Reflect, Promise */
|
|
194
|
+
|
|
186
195
|
|
|
187
196
|
function __awaiter(thisArg, _arguments, P, generator) {
|
|
188
197
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
@@ -196,8 +205,8 @@ function __awaiter(thisArg, _arguments, P, generator) {
|
|
|
196
205
|
|
|
197
206
|
const compressors = {
|
|
198
207
|
identity: {
|
|
199
|
-
compress: v => v,
|
|
200
|
-
uncompress: v => v,
|
|
208
|
+
compress: (v) => v,
|
|
209
|
+
uncompress: (v) => v,
|
|
201
210
|
},
|
|
202
211
|
};
|
|
203
212
|
function uncompressBody(encodings, body) {
|
|
@@ -236,7 +245,10 @@ function useBody() {
|
|
|
236
245
|
}
|
|
237
246
|
return false;
|
|
238
247
|
});
|
|
239
|
-
const contentEncodings = () => init('contentEncodings', () => (contentEncoding || '')
|
|
248
|
+
const contentEncodings = () => init('contentEncodings', () => (contentEncoding || '')
|
|
249
|
+
.split(',')
|
|
250
|
+
.map((p) => p.trim())
|
|
251
|
+
.filter((p) => !!p));
|
|
240
252
|
const parseBody = () => init('parsed', () => __awaiter(this, void 0, void 0, function* () {
|
|
241
253
|
const body = yield uncompressBody(contentEncodings(), (yield rawBody()).toString());
|
|
242
254
|
if (isJson())
|
|
@@ -262,7 +274,8 @@ function useBody() {
|
|
|
262
274
|
return v;
|
|
263
275
|
}
|
|
264
276
|
function formDataParser(v) {
|
|
265
|
-
const boundary = '--' +
|
|
277
|
+
const boundary = '--' +
|
|
278
|
+
(/boundary=([^;]+)(?:;|$)/.exec(contentType || '') || [, ''])[1];
|
|
266
279
|
if (!boundary)
|
|
267
280
|
throw new eventHttp.HttpError(eventHttp.EHttpStatusCode.BadRequest, 'form-data boundary not recognized');
|
|
268
281
|
const parts = v.trim().split(boundary);
|
|
@@ -274,7 +287,10 @@ function useBody() {
|
|
|
274
287
|
key = '';
|
|
275
288
|
partContentType = 'text/plain';
|
|
276
289
|
let valueMode = false;
|
|
277
|
-
const lines = part
|
|
290
|
+
const lines = part
|
|
291
|
+
.trim()
|
|
292
|
+
.split(/\n/g)
|
|
293
|
+
.map((s) => s.trim());
|
|
278
294
|
for (const line of lines) {
|
|
279
295
|
if (valueMode) {
|
|
280
296
|
if (!result[key]) {
|
|
@@ -292,7 +308,9 @@ function useBody() {
|
|
|
292
308
|
}
|
|
293
309
|
continue;
|
|
294
310
|
}
|
|
295
|
-
if (line
|
|
311
|
+
if (line
|
|
312
|
+
.toLowerCase()
|
|
313
|
+
.startsWith('content-disposition: form-data;')) {
|
|
296
314
|
key = (/name=([^;]+)/.exec(line) || [])[1];
|
|
297
315
|
if (!key)
|
|
298
316
|
throw new eventHttp.HttpError(eventHttp.EHttpStatusCode.BadRequest, 'Could not read multipart name: ' + line);
|
|
@@ -349,7 +367,7 @@ const StatusHook = () => moost.Resolve((metas, level) => {
|
|
|
349
367
|
const initialValue = metas.instance[metas.key];
|
|
350
368
|
eventCore.attachHook(metas.instance, {
|
|
351
369
|
get: () => hook.value,
|
|
352
|
-
set: (v) => hook.value = v,
|
|
370
|
+
set: (v) => (hook.value = v),
|
|
353
371
|
}, metas.key);
|
|
354
372
|
return typeof initialValue === 'number' ? initialValue : 200;
|
|
355
373
|
}
|
|
@@ -369,7 +387,7 @@ const HeaderHook = (name) => moost.Resolve((metas, level) => {
|
|
|
369
387
|
const initialValue = metas.instance[metas.key];
|
|
370
388
|
eventCore.attachHook(metas.instance, {
|
|
371
389
|
get: () => hook.value,
|
|
372
|
-
set: (v) => hook.value = v,
|
|
390
|
+
set: (v) => (hook.value = v),
|
|
373
391
|
}, metas.key);
|
|
374
392
|
return typeof initialValue === 'string' ? initialValue : '';
|
|
375
393
|
}
|
|
@@ -389,7 +407,7 @@ const CookieHook = (name) => moost.Resolve((metas, level) => {
|
|
|
389
407
|
const initialValue = metas.instance[metas.key];
|
|
390
408
|
eventCore.attachHook(metas.instance, {
|
|
391
409
|
get: () => hook.value,
|
|
392
|
-
set: (v) => hook.value = v,
|
|
410
|
+
set: (v) => (hook.value = v),
|
|
393
411
|
}, metas.key);
|
|
394
412
|
return typeof initialValue === 'string' ? initialValue : '';
|
|
395
413
|
}
|
|
@@ -405,14 +423,14 @@ const CookieAttrsHook = (name) => moost.Resolve((metas, level) => {
|
|
|
405
423
|
if (level === 'PARAM') {
|
|
406
424
|
return eventCore.attachHook({}, {
|
|
407
425
|
get: () => hook.attrs,
|
|
408
|
-
set: (v) => hook.attrs = v,
|
|
426
|
+
set: (v) => (hook.attrs = v),
|
|
409
427
|
});
|
|
410
428
|
}
|
|
411
429
|
if (level === 'PROP' && metas.instance && metas.key) {
|
|
412
430
|
const initialValue = metas.instance[metas.key];
|
|
413
431
|
eventCore.attachHook(metas.instance, {
|
|
414
432
|
get: () => hook.attrs,
|
|
415
|
-
set: (v) => hook.attrs = v,
|
|
433
|
+
set: (v) => (hook.attrs = v),
|
|
416
434
|
}, metas.key);
|
|
417
435
|
return typeof initialValue === 'object' ? initialValue : {};
|
|
418
436
|
}
|
|
@@ -429,9 +447,13 @@ function Authorization(name) {
|
|
|
429
447
|
const auth = eventHttp.useAuthorization();
|
|
430
448
|
switch (name) {
|
|
431
449
|
case 'username':
|
|
432
|
-
return auth.isBasic()
|
|
450
|
+
return auth.isBasic()
|
|
451
|
+
? (_a = auth.basicCredentials()) === null || _a === void 0 ? void 0 : _a.username
|
|
452
|
+
: undefined;
|
|
433
453
|
case 'password':
|
|
434
|
-
return auth.isBasic()
|
|
454
|
+
return auth.isBasic()
|
|
455
|
+
? (_b = auth.basicCredentials()) === null || _b === void 0 ? void 0 : _b.password
|
|
456
|
+
: undefined;
|
|
435
457
|
case 'bearer':
|
|
436
458
|
return auth.isBearer() ? auth.authorization : undefined;
|
|
437
459
|
case 'raw':
|
|
@@ -474,7 +496,7 @@ function Query(name) {
|
|
|
474
496
|
if (name) {
|
|
475
497
|
const p = urlSearchParams();
|
|
476
498
|
const value = p.get(name);
|
|
477
|
-
return value === '' && p.has(name) || value;
|
|
499
|
+
return (value === '' && p.has(name)) || value;
|
|
478
500
|
}
|
|
479
501
|
const json = jsonSearchParams();
|
|
480
502
|
return Object.keys(json).length ? json : null;
|
|
@@ -559,7 +581,8 @@ const setHeaderInterceptor = (name, value, opts) => {
|
|
|
559
581
|
const h = eventHttp.useSetHeader(name);
|
|
560
582
|
const status = eventHttp.useStatus();
|
|
561
583
|
after(() => {
|
|
562
|
-
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)) {
|
|
563
586
|
h.value = value;
|
|
564
587
|
}
|
|
565
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 { getMoostMate, Resolve, Intercept, TInterceptorPriority, validatePipe } from 'moost';
|
|
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,83 +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
|
-
const interceptorHandler = yield opts.getIterceptorHandler();
|
|
85
|
-
restoreCtx();
|
|
86
|
-
try {
|
|
87
|
-
// logger.trace('initializing interceptors')
|
|
88
|
-
yield interceptorHandler.init();
|
|
89
|
-
}
|
|
90
|
-
catch (e) {
|
|
91
|
-
logger.error(e);
|
|
92
|
-
response = e;
|
|
93
|
-
}
|
|
94
|
-
let args = [];
|
|
95
|
-
if (!response) {
|
|
96
|
-
// params
|
|
97
|
-
restoreCtx();
|
|
98
|
-
try {
|
|
99
|
-
// logger.trace(`resolving method args for "${ opts.method as string }"`)
|
|
100
|
-
args = yield opts.resolveArgs();
|
|
101
|
-
// logger.trace(`args for method "${ opts.method as string }" resolved (count ${String(args.length)})`)
|
|
102
|
-
}
|
|
103
|
-
catch (e) {
|
|
104
|
-
logger.error(e);
|
|
105
|
-
response = e;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
if (!response) {
|
|
109
|
-
restoreCtx();
|
|
110
|
-
// fire before interceptors
|
|
111
|
-
// logger.trace('firing before interceptors')
|
|
112
|
-
response = yield interceptorHandler.fireBefore(response);
|
|
113
|
-
// fire request handler
|
|
114
|
-
if (!interceptorHandler.responseOverwritten) {
|
|
115
|
-
try {
|
|
116
|
-
restoreCtx();
|
|
117
|
-
// logger.trace(`firing method "${ opts.method as string }"`)
|
|
118
|
-
response = yield instance[opts.method](...args);
|
|
119
|
-
}
|
|
120
|
-
catch (e) {
|
|
121
|
-
logger.error(e);
|
|
122
|
-
response = e;
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
// fire after interceptors
|
|
127
|
-
restoreCtx();
|
|
128
|
-
try {
|
|
129
|
-
// logger.trace('firing after interceptors')
|
|
130
|
-
response = yield interceptorHandler.fireAfter(response);
|
|
131
|
-
}
|
|
132
|
-
catch (e) {
|
|
133
|
-
logger.error(e);
|
|
134
|
-
throw e;
|
|
135
|
-
}
|
|
136
|
-
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
|
+
},
|
|
137
142
|
});
|
|
138
143
|
}
|
|
139
|
-
const pathBuilder = this.httpApp.on(handler.method, targetPath, fn);
|
|
140
|
-
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
|
+
{};
|
|
141
147
|
const id = (methodMeta.id || opts.method);
|
|
142
148
|
if (id) {
|
|
143
|
-
const methods = this.pathBuilders[id] =
|
|
149
|
+
const methods = (this.pathBuilders[id] =
|
|
150
|
+
this.pathBuilders[id] || {});
|
|
144
151
|
if (handler.method === '*') {
|
|
145
152
|
methods.GET = pathBuilder;
|
|
146
153
|
methods.PUT = pathBuilder;
|
|
@@ -181,6 +188,8 @@ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
|
181
188
|
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
182
189
|
PERFORMANCE OF THIS SOFTWARE.
|
|
183
190
|
***************************************************************************** */
|
|
191
|
+
/* global Reflect, Promise */
|
|
192
|
+
|
|
184
193
|
|
|
185
194
|
function __awaiter(thisArg, _arguments, P, generator) {
|
|
186
195
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
@@ -194,8 +203,8 @@ function __awaiter(thisArg, _arguments, P, generator) {
|
|
|
194
203
|
|
|
195
204
|
const compressors = {
|
|
196
205
|
identity: {
|
|
197
|
-
compress: v => v,
|
|
198
|
-
uncompress: v => v,
|
|
206
|
+
compress: (v) => v,
|
|
207
|
+
uncompress: (v) => v,
|
|
199
208
|
},
|
|
200
209
|
};
|
|
201
210
|
function uncompressBody(encodings, body) {
|
|
@@ -234,7 +243,10 @@ function useBody() {
|
|
|
234
243
|
}
|
|
235
244
|
return false;
|
|
236
245
|
});
|
|
237
|
-
const contentEncodings = () => init('contentEncodings', () => (contentEncoding || '')
|
|
246
|
+
const contentEncodings = () => init('contentEncodings', () => (contentEncoding || '')
|
|
247
|
+
.split(',')
|
|
248
|
+
.map((p) => p.trim())
|
|
249
|
+
.filter((p) => !!p));
|
|
238
250
|
const parseBody = () => init('parsed', () => __awaiter(this, void 0, void 0, function* () {
|
|
239
251
|
const body = yield uncompressBody(contentEncodings(), (yield rawBody()).toString());
|
|
240
252
|
if (isJson())
|
|
@@ -260,7 +272,8 @@ function useBody() {
|
|
|
260
272
|
return v;
|
|
261
273
|
}
|
|
262
274
|
function formDataParser(v) {
|
|
263
|
-
const boundary = '--' +
|
|
275
|
+
const boundary = '--' +
|
|
276
|
+
(/boundary=([^;]+)(?:;|$)/.exec(contentType || '') || [, ''])[1];
|
|
264
277
|
if (!boundary)
|
|
265
278
|
throw new HttpError(EHttpStatusCode.BadRequest, 'form-data boundary not recognized');
|
|
266
279
|
const parts = v.trim().split(boundary);
|
|
@@ -272,7 +285,10 @@ function useBody() {
|
|
|
272
285
|
key = '';
|
|
273
286
|
partContentType = 'text/plain';
|
|
274
287
|
let valueMode = false;
|
|
275
|
-
const lines = part
|
|
288
|
+
const lines = part
|
|
289
|
+
.trim()
|
|
290
|
+
.split(/\n/g)
|
|
291
|
+
.map((s) => s.trim());
|
|
276
292
|
for (const line of lines) {
|
|
277
293
|
if (valueMode) {
|
|
278
294
|
if (!result[key]) {
|
|
@@ -290,7 +306,9 @@ function useBody() {
|
|
|
290
306
|
}
|
|
291
307
|
continue;
|
|
292
308
|
}
|
|
293
|
-
if (line
|
|
309
|
+
if (line
|
|
310
|
+
.toLowerCase()
|
|
311
|
+
.startsWith('content-disposition: form-data;')) {
|
|
294
312
|
key = (/name=([^;]+)/.exec(line) || [])[1];
|
|
295
313
|
if (!key)
|
|
296
314
|
throw new HttpError(EHttpStatusCode.BadRequest, 'Could not read multipart name: ' + line);
|
|
@@ -347,7 +365,7 @@ const StatusHook = () => Resolve((metas, level) => {
|
|
|
347
365
|
const initialValue = metas.instance[metas.key];
|
|
348
366
|
attachHook(metas.instance, {
|
|
349
367
|
get: () => hook.value,
|
|
350
|
-
set: (v) => hook.value = v,
|
|
368
|
+
set: (v) => (hook.value = v),
|
|
351
369
|
}, metas.key);
|
|
352
370
|
return typeof initialValue === 'number' ? initialValue : 200;
|
|
353
371
|
}
|
|
@@ -367,7 +385,7 @@ const HeaderHook = (name) => Resolve((metas, level) => {
|
|
|
367
385
|
const initialValue = metas.instance[metas.key];
|
|
368
386
|
attachHook(metas.instance, {
|
|
369
387
|
get: () => hook.value,
|
|
370
|
-
set: (v) => hook.value = v,
|
|
388
|
+
set: (v) => (hook.value = v),
|
|
371
389
|
}, metas.key);
|
|
372
390
|
return typeof initialValue === 'string' ? initialValue : '';
|
|
373
391
|
}
|
|
@@ -387,7 +405,7 @@ const CookieHook = (name) => Resolve((metas, level) => {
|
|
|
387
405
|
const initialValue = metas.instance[metas.key];
|
|
388
406
|
attachHook(metas.instance, {
|
|
389
407
|
get: () => hook.value,
|
|
390
|
-
set: (v) => hook.value = v,
|
|
408
|
+
set: (v) => (hook.value = v),
|
|
391
409
|
}, metas.key);
|
|
392
410
|
return typeof initialValue === 'string' ? initialValue : '';
|
|
393
411
|
}
|
|
@@ -403,14 +421,14 @@ const CookieAttrsHook = (name) => Resolve((metas, level) => {
|
|
|
403
421
|
if (level === 'PARAM') {
|
|
404
422
|
return attachHook({}, {
|
|
405
423
|
get: () => hook.attrs,
|
|
406
|
-
set: (v) => hook.attrs = v,
|
|
424
|
+
set: (v) => (hook.attrs = v),
|
|
407
425
|
});
|
|
408
426
|
}
|
|
409
427
|
if (level === 'PROP' && metas.instance && metas.key) {
|
|
410
428
|
const initialValue = metas.instance[metas.key];
|
|
411
429
|
attachHook(metas.instance, {
|
|
412
430
|
get: () => hook.attrs,
|
|
413
|
-
set: (v) => hook.attrs = v,
|
|
431
|
+
set: (v) => (hook.attrs = v),
|
|
414
432
|
}, metas.key);
|
|
415
433
|
return typeof initialValue === 'object' ? initialValue : {};
|
|
416
434
|
}
|
|
@@ -427,9 +445,13 @@ function Authorization(name) {
|
|
|
427
445
|
const auth = useAuthorization();
|
|
428
446
|
switch (name) {
|
|
429
447
|
case 'username':
|
|
430
|
-
return auth.isBasic()
|
|
448
|
+
return auth.isBasic()
|
|
449
|
+
? (_a = auth.basicCredentials()) === null || _a === void 0 ? void 0 : _a.username
|
|
450
|
+
: undefined;
|
|
431
451
|
case 'password':
|
|
432
|
-
return auth.isBasic()
|
|
452
|
+
return auth.isBasic()
|
|
453
|
+
? (_b = auth.basicCredentials()) === null || _b === void 0 ? void 0 : _b.password
|
|
454
|
+
: undefined;
|
|
433
455
|
case 'bearer':
|
|
434
456
|
return auth.isBearer() ? auth.authorization : undefined;
|
|
435
457
|
case 'raw':
|
|
@@ -472,7 +494,7 @@ function Query(name) {
|
|
|
472
494
|
if (name) {
|
|
473
495
|
const p = urlSearchParams();
|
|
474
496
|
const value = p.get(name);
|
|
475
|
-
return value === '' && p.has(name) || value;
|
|
497
|
+
return (value === '' && p.has(name)) || value;
|
|
476
498
|
}
|
|
477
499
|
const json = jsonSearchParams();
|
|
478
500
|
return Object.keys(json).length ? json : null;
|
|
@@ -557,7 +579,8 @@ const setHeaderInterceptor = (name, value, opts) => {
|
|
|
557
579
|
const h = useSetHeader(name);
|
|
558
580
|
const status = useStatus();
|
|
559
581
|
after(() => {
|
|
560
|
-
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)) {
|
|
561
584
|
h.value = value;
|
|
562
585
|
}
|
|
563
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.28",
|
|
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.28",
|
|
33
|
+
"@wooksjs/event-core": "^0.2.22",
|
|
34
|
+
"@wooksjs/event-http": "^0.2.22",
|
|
35
35
|
"@prostojs/infact": "^0.1.11",
|
|
36
|
-
"@prostojs/router": "^0.0
|
|
36
|
+
"@prostojs/router": "^0.1.0"
|
|
37
37
|
}
|
|
38
38
|
}
|