moost 0.2.27 → 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 +7 -3
- package/dist/index.cjs +622 -205
- package/dist/index.d.ts +242 -16
- package/dist/index.mjs +599 -188
- package/package.json +3 -3
package/dist/index.mjs
CHANGED
|
@@ -18,6 +18,8 @@ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
|
18
18
|
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
19
19
|
PERFORMANCE OF THIS SOFTWARE.
|
|
20
20
|
***************************************************************************** */
|
|
21
|
+
/* global Reflect, Promise */
|
|
22
|
+
|
|
21
23
|
|
|
22
24
|
function __awaiter(thisArg, _arguments, P, generator) {
|
|
23
25
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
@@ -39,7 +41,7 @@ const moostMate = new Mate(METADATA_WORKSPACE, {
|
|
|
39
41
|
return !!(classMeta === null || classMeta === void 0 ? void 0 : classMeta.inherit);
|
|
40
42
|
}
|
|
41
43
|
if (level === 'PROP') {
|
|
42
|
-
return !!(targetMeta === null || targetMeta === void 0 ? void 0 : targetMeta.inherit) || !!((classMeta === null || classMeta === void 0 ? void 0 : classMeta.inherit) && !targetMeta);
|
|
44
|
+
return (!!(targetMeta === null || targetMeta === void 0 ? void 0 : targetMeta.inherit) || !!((classMeta === null || classMeta === void 0 ? void 0 : classMeta.inherit) && !targetMeta));
|
|
43
45
|
}
|
|
44
46
|
return !!(targetMeta === null || targetMeta === void 0 ? void 0 : targetMeta.inherit);
|
|
45
47
|
},
|
|
@@ -73,22 +75,32 @@ function getNewMoostInfact() {
|
|
|
73
75
|
constructorParams: (meta === null || meta === void 0 ? void 0 : meta.params) || [],
|
|
74
76
|
provide: meta === null || meta === void 0 ? void 0 : meta.provide,
|
|
75
77
|
properties: (meta === null || meta === void 0 ? void 0 : meta.properties) || [],
|
|
76
|
-
scopeId: (meta === null || meta === void 0 ? void 0 : meta.injectable) === 'FOR_EVENT'
|
|
78
|
+
scopeId: (meta === null || meta === void 0 ? void 0 : meta.injectable) === 'FOR_EVENT'
|
|
79
|
+
? useEventId().getId()
|
|
80
|
+
: undefined,
|
|
77
81
|
};
|
|
78
82
|
return infactMeta;
|
|
79
83
|
},
|
|
80
84
|
resolveParam({ paramMeta, classMeta, customData }) {
|
|
81
85
|
if (paramMeta && customData && customData.pipes) {
|
|
82
|
-
return runPipes(customData.pipes, undefined, {
|
|
86
|
+
return runPipes(customData.pipes, undefined, {
|
|
87
|
+
paramMeta,
|
|
88
|
+
classMeta: classMeta,
|
|
89
|
+
}, 'PARAM');
|
|
83
90
|
}
|
|
84
91
|
},
|
|
85
92
|
describeProp(classConstructor, key) {
|
|
86
93
|
const meta = getMoostMate().read(classConstructor, key);
|
|
87
94
|
return meta;
|
|
88
95
|
},
|
|
89
|
-
resolveProp({ instance, key, initialValue, propMeta, classMeta, customData }) {
|
|
96
|
+
resolveProp({ instance, key, initialValue, propMeta, classMeta, customData, }) {
|
|
90
97
|
if (propMeta && customData && customData.pipes) {
|
|
91
|
-
return runPipes(customData.pipes, initialValue, {
|
|
98
|
+
return runPipes(customData.pipes, initialValue, {
|
|
99
|
+
instance,
|
|
100
|
+
key,
|
|
101
|
+
propMeta,
|
|
102
|
+
classMeta: classMeta,
|
|
103
|
+
}, 'PROP');
|
|
92
104
|
}
|
|
93
105
|
},
|
|
94
106
|
storeProvideRegByInstance: true,
|
|
@@ -102,13 +114,19 @@ function getInstanceOwnMethods(instance) {
|
|
|
102
114
|
...getParentProps(getConstructor(instance)),
|
|
103
115
|
...Object.getOwnPropertyNames(proto),
|
|
104
116
|
...Object.getOwnPropertyNames(instance),
|
|
105
|
-
].filter(m => typeof instance[m] === 'function');
|
|
117
|
+
].filter((m) => typeof instance[m] === 'function');
|
|
106
118
|
}
|
|
107
119
|
const fnProto = Object.getPrototypeOf(Function);
|
|
108
120
|
function getParentProps(constructor) {
|
|
109
121
|
const parent = Object.getPrototypeOf(constructor);
|
|
110
|
-
if (typeof parent === 'function' &&
|
|
111
|
-
|
|
122
|
+
if (typeof parent === 'function' &&
|
|
123
|
+
parent !== fnProto &&
|
|
124
|
+
parent !== constructor &&
|
|
125
|
+
parent.prototype) {
|
|
126
|
+
return [
|
|
127
|
+
...getParentProps(parent),
|
|
128
|
+
...Object.getOwnPropertyNames(parent.prototype),
|
|
129
|
+
];
|
|
112
130
|
}
|
|
113
131
|
return [];
|
|
114
132
|
}
|
|
@@ -120,10 +138,14 @@ function getCallableFn(targetInstance, fn, restoreCtx, pipes, logger) {
|
|
|
120
138
|
if (meta === null || meta === void 0 ? void 0 : meta.injectable) {
|
|
121
139
|
const infact = getMoostInfact();
|
|
122
140
|
infact.silent(true);
|
|
123
|
-
const instance = yield infact.getForInstance(targetInstance, fn, {
|
|
124
|
-
syncContextFn: () => {
|
|
125
|
-
|
|
126
|
-
|
|
141
|
+
const instance = (yield infact.getForInstance(targetInstance, fn, {
|
|
142
|
+
syncContextFn: () => {
|
|
143
|
+
restoreCtx && restoreCtx();
|
|
144
|
+
},
|
|
145
|
+
customData: {
|
|
146
|
+
pipes: [...(pipes || []), ...(meta.pipes || [])].sort((a, b) => a.priority - b.priority),
|
|
147
|
+
},
|
|
148
|
+
}));
|
|
127
149
|
infact.silent(false);
|
|
128
150
|
return ((...args) => {
|
|
129
151
|
return instance.handler(...args);
|
|
@@ -155,7 +177,15 @@ class InterceptorHandler {
|
|
|
155
177
|
const { restoreCtx } = useEventContext();
|
|
156
178
|
for (const handler of this.handlers) {
|
|
157
179
|
restoreCtx();
|
|
158
|
-
|
|
180
|
+
const response = yield handler((fn) => {
|
|
181
|
+
this.before.push(fn);
|
|
182
|
+
}, (fn) => {
|
|
183
|
+
this.after.unshift(fn);
|
|
184
|
+
}, (fn) => {
|
|
185
|
+
this.onError.unshift(fn);
|
|
186
|
+
});
|
|
187
|
+
if (typeof response !== 'undefined')
|
|
188
|
+
return response;
|
|
159
189
|
}
|
|
160
190
|
});
|
|
161
191
|
}
|
|
@@ -193,6 +223,28 @@ class InterceptorHandler {
|
|
|
193
223
|
}
|
|
194
224
|
}
|
|
195
225
|
|
|
226
|
+
const mate = getMoostMate();
|
|
227
|
+
function getIterceptorHandlerFactory(interceptors, getTargetInstance, pipes, logger) {
|
|
228
|
+
return () => {
|
|
229
|
+
const interceptorHandlers = [];
|
|
230
|
+
for (const { handler } of interceptors) {
|
|
231
|
+
const interceptorMeta = mate.read(handler);
|
|
232
|
+
if (interceptorMeta === null || interceptorMeta === void 0 ? void 0 : interceptorMeta.injectable) {
|
|
233
|
+
interceptorHandlers.push((...args) => __awaiter(this, void 0, void 0, function* () {
|
|
234
|
+
const { restoreCtx } = useEventContext();
|
|
235
|
+
const targetInstance = yield getTargetInstance();
|
|
236
|
+
restoreCtx();
|
|
237
|
+
return (yield getCallableFn(targetInstance, handler, restoreCtx, pipes, logger))(...args);
|
|
238
|
+
}));
|
|
239
|
+
}
|
|
240
|
+
else {
|
|
241
|
+
interceptorHandlers.push(handler);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
return Promise.resolve(new InterceptorHandler(interceptorHandlers));
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
|
|
196
248
|
function bindControllerMethods(options) {
|
|
197
249
|
var _a;
|
|
198
250
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -207,7 +259,9 @@ function bindControllerMethods(options) {
|
|
|
207
259
|
const methods = getInstanceOwnMethods(fakeInstance);
|
|
208
260
|
const mate = getMoostMate();
|
|
209
261
|
const meta = mate.read(classConstructor) || {};
|
|
210
|
-
const ownPrefix = typeof opts.replaceOwnPrefix === 'string'
|
|
262
|
+
const ownPrefix = typeof opts.replaceOwnPrefix === 'string'
|
|
263
|
+
? opts.replaceOwnPrefix
|
|
264
|
+
: ((_a = meta.controller) === null || _a === void 0 ? void 0 : _a.prefix) || '';
|
|
211
265
|
const prefix = `${opts.globalPrefix}/${ownPrefix}`;
|
|
212
266
|
for (const method of methods) {
|
|
213
267
|
const methodMeta = getMoostMate().read(fakeInstance, method) || {};
|
|
@@ -215,25 +269,12 @@ function bindControllerMethods(options) {
|
|
|
215
269
|
continue;
|
|
216
270
|
const pipes = [...(opts.pipes || []), ...(methodMeta.pipes || [])].sort((a, b) => a.priority - b.priority);
|
|
217
271
|
// preparing interceptors
|
|
218
|
-
const interceptors = [
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
interceptorHandlers.push((...args) => __awaiter(this, void 0, void 0, function* () {
|
|
225
|
-
const { restoreCtx } = useEventContext();
|
|
226
|
-
const targetInstance = yield getInstance();
|
|
227
|
-
restoreCtx();
|
|
228
|
-
return (yield getCallableFn(targetInstance, handler, restoreCtx, pipes, options.logger))(...args);
|
|
229
|
-
}));
|
|
230
|
-
}
|
|
231
|
-
else {
|
|
232
|
-
interceptorHandlers.push(handler);
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
return Promise.resolve(new InterceptorHandler(interceptorHandlers));
|
|
236
|
-
};
|
|
272
|
+
const interceptors = [
|
|
273
|
+
...(opts.interceptors || []),
|
|
274
|
+
...(meta.interceptors || []),
|
|
275
|
+
...(methodMeta.interceptors || []),
|
|
276
|
+
].sort((a, b) => a.priority - b.priority);
|
|
277
|
+
const getIterceptorHandler = getIterceptorHandlerFactory(interceptors, getInstance, pipes, options.logger);
|
|
237
278
|
// preparing pipes
|
|
238
279
|
const argsPipes = [];
|
|
239
280
|
for (const p of methodMeta.params || []) {
|
|
@@ -262,11 +303,6 @@ function bindControllerMethods(options) {
|
|
|
262
303
|
prefix,
|
|
263
304
|
fakeInstance,
|
|
264
305
|
getInstance,
|
|
265
|
-
registerEventScope: (scopeId) => {
|
|
266
|
-
const infact = getMoostInfact();
|
|
267
|
-
infact.registerScope(scopeId);
|
|
268
|
-
return () => infact.unregisterScope(scopeId);
|
|
269
|
-
},
|
|
270
306
|
method,
|
|
271
307
|
handlers: methodMeta.handlers,
|
|
272
308
|
getIterceptorHandler,
|
|
@@ -278,21 +314,71 @@ function bindControllerMethods(options) {
|
|
|
278
314
|
});
|
|
279
315
|
}
|
|
280
316
|
|
|
317
|
+
/**
|
|
318
|
+
* ## Label
|
|
319
|
+
* ### @Decorator
|
|
320
|
+
* _Common purpose decorator that may be used by various adapters for various purposes_
|
|
321
|
+
*
|
|
322
|
+
* Stores Label metadata
|
|
323
|
+
*/
|
|
281
324
|
function Label(value) {
|
|
282
325
|
return getMoostMate().decorate('label', value);
|
|
283
326
|
}
|
|
327
|
+
/**
|
|
328
|
+
* ## Description
|
|
329
|
+
* ### @Decorator
|
|
330
|
+
* _Common purpose decorator that may be used by various adapters for various purposes_
|
|
331
|
+
*
|
|
332
|
+
* Stores Description metadata
|
|
333
|
+
*/
|
|
334
|
+
function Description(value) {
|
|
335
|
+
return getMoostMate().decorate('description', value);
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* ## Value
|
|
339
|
+
* ### @Decorator
|
|
340
|
+
* _Common purpose decorator that may be used by various adapters for various purposes_
|
|
341
|
+
*
|
|
342
|
+
* Stores Value metadata
|
|
343
|
+
*/
|
|
344
|
+
function Value(value) {
|
|
345
|
+
return getMoostMate().decorate('value', value);
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* ## Id
|
|
349
|
+
* ### @Decorator
|
|
350
|
+
* _Common purpose decorator that may be used by various adapters for various purposes_
|
|
351
|
+
*
|
|
352
|
+
* Stores Id metadata
|
|
353
|
+
*/
|
|
284
354
|
function Id(value) {
|
|
285
355
|
return getMoostMate().decorate('id', value);
|
|
286
356
|
}
|
|
357
|
+
/**
|
|
358
|
+
* ## Optional
|
|
359
|
+
* ### @Decorator
|
|
360
|
+
* _Common purpose decorator that may be used by various adapters for various purposes_
|
|
361
|
+
*
|
|
362
|
+
* Stores Optional metadata
|
|
363
|
+
*/
|
|
287
364
|
function Optional() {
|
|
288
365
|
return getMoostMate().decorate('optional', true);
|
|
289
366
|
}
|
|
367
|
+
/**
|
|
368
|
+
* ## Required
|
|
369
|
+
* ### @Decorator
|
|
370
|
+
* _Common purpose decorator that may be used by various adapters for various purposes_
|
|
371
|
+
*
|
|
372
|
+
* Stores Required metadata
|
|
373
|
+
*/
|
|
290
374
|
function Required() {
|
|
291
375
|
const mate = getMoostMate();
|
|
292
376
|
return mate.apply(mate.decorate('required', true),
|
|
293
377
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
|
294
378
|
mate.decorateClass((meta, level, key, index) => {
|
|
295
|
-
if (typeof index !== 'number' &&
|
|
379
|
+
if (typeof index !== 'number' &&
|
|
380
|
+
meta &&
|
|
381
|
+
['string', 'symbol'].includes(typeof key)) {
|
|
296
382
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
|
|
297
383
|
meta.requiredProps = meta.requiredProps || [];
|
|
298
384
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
|
@@ -323,7 +409,7 @@ function Resolve(resolver, label) {
|
|
|
323
409
|
* @paramType string
|
|
324
410
|
*/
|
|
325
411
|
function Param(name) {
|
|
326
|
-
return Resolve(() => useRouteParams().get(name), name);
|
|
412
|
+
return getMoostMate().apply(getMoostMate().decorate('isRouteParam', name), Resolve(() => useRouteParams().get(name), name));
|
|
327
413
|
}
|
|
328
414
|
/**
|
|
329
415
|
* Get Parsed Params from url parh
|
|
@@ -365,7 +451,9 @@ function fillLabel(target, key, index, name) {
|
|
|
365
451
|
if (name) {
|
|
366
452
|
const meta = getMoostMate().read(target, key);
|
|
367
453
|
if (typeof index === 'number') {
|
|
368
|
-
if (!(meta === null || meta === void 0 ? void 0 : meta.params) ||
|
|
454
|
+
if (!(meta === null || meta === void 0 ? void 0 : meta.params) ||
|
|
455
|
+
!(meta === null || meta === void 0 ? void 0 : meta.params[index]) ||
|
|
456
|
+
!(meta === null || meta === void 0 ? void 0 : meta.params[index].label)) {
|
|
369
457
|
Label(name)(target, key, index);
|
|
370
458
|
}
|
|
371
459
|
}
|
|
@@ -378,8 +466,9 @@ function fillLabel(target, key, index, name) {
|
|
|
378
466
|
}
|
|
379
467
|
|
|
380
468
|
/**
|
|
469
|
+
* ## Injectable
|
|
470
|
+
* ### @Decorator
|
|
381
471
|
* Mark the Class as Injectable to enable it to be used in dependency injection
|
|
382
|
-
* @decorator
|
|
383
472
|
* @param scope - Scope for injection ("FOR_EVENT" | "SINGLETON" | true)
|
|
384
473
|
* FOR_EVENT - will create a new instance for each incoming request
|
|
385
474
|
* SINGLETON | true - will create a new instance only once
|
|
@@ -395,8 +484,9 @@ const insureInjectable = getMoostMate().decorate((meta) => {
|
|
|
395
484
|
});
|
|
396
485
|
|
|
397
486
|
/**
|
|
487
|
+
* ## Controller
|
|
488
|
+
* ### @Decorator
|
|
398
489
|
* Set Class as a Controller
|
|
399
|
-
* @decorator
|
|
400
490
|
* @param prefix - define the prefix for all the paths of this controller
|
|
401
491
|
*/
|
|
402
492
|
function Controller(prefix) {
|
|
@@ -406,8 +496,12 @@ function Controller(prefix) {
|
|
|
406
496
|
function ImportController(prefix, controller, provide) {
|
|
407
497
|
return getMoostMate().decorate('importController', {
|
|
408
498
|
prefix: typeof prefix === 'string' ? prefix : undefined,
|
|
409
|
-
typeResolver: typeof prefix === 'string'
|
|
410
|
-
|
|
499
|
+
typeResolver: typeof prefix === 'string'
|
|
500
|
+
? controller
|
|
501
|
+
: prefix,
|
|
502
|
+
provide: typeof prefix === 'string'
|
|
503
|
+
? provide || undefined
|
|
504
|
+
: controller || undefined,
|
|
411
505
|
}, true);
|
|
412
506
|
}
|
|
413
507
|
|
|
@@ -425,26 +519,40 @@ var TInterceptorPriority;
|
|
|
425
519
|
TInterceptorPriority[TInterceptorPriority["CATCH_ERROR"] = 5] = "CATCH_ERROR";
|
|
426
520
|
TInterceptorPriority[TInterceptorPriority["AFTER_ALL"] = 6] = "AFTER_ALL";
|
|
427
521
|
})(TInterceptorPriority || (TInterceptorPriority = {}));
|
|
522
|
+
/**
|
|
523
|
+
* ## Intercept
|
|
524
|
+
* ### @Decorator
|
|
525
|
+
* Set interceptor
|
|
526
|
+
* @param handler interceptor fn (use defineInterceptorFn)
|
|
527
|
+
* @param priority interceptor priority
|
|
528
|
+
* @returns
|
|
529
|
+
*/
|
|
428
530
|
function Intercept(handler, priority) {
|
|
429
531
|
return getMoostMate().decorate('interceptors', {
|
|
430
532
|
handler,
|
|
431
|
-
priority: priority ||
|
|
533
|
+
priority: priority ||
|
|
534
|
+
handler.priority ||
|
|
535
|
+
TInterceptorPriority.INTERCEPTOR,
|
|
432
536
|
}, true);
|
|
433
537
|
}
|
|
434
538
|
|
|
435
539
|
/**
|
|
540
|
+
* ## Provide
|
|
541
|
+
* ### @Decorator
|
|
436
542
|
* Defines provide registry for class (and all the children)
|
|
437
543
|
* @param type - string or class constructor
|
|
438
544
|
* @param fn - factory function for provided value
|
|
439
545
|
*/
|
|
440
546
|
function Provide(type, fn) {
|
|
441
|
-
return getMoostMate().decorate(meta => {
|
|
547
|
+
return getMoostMate().decorate((meta) => {
|
|
442
548
|
meta.provide = meta.provide || {};
|
|
443
549
|
Object.assign(meta.provide, createProvideRegistry([type, fn]));
|
|
444
550
|
return meta;
|
|
445
551
|
});
|
|
446
552
|
}
|
|
447
553
|
/**
|
|
554
|
+
* ## Inject
|
|
555
|
+
* ### @Decorator
|
|
448
556
|
* Defines a key from provide registry to inject value
|
|
449
557
|
* (For optional values use with @Nullable())
|
|
450
558
|
* @param type - string or class constructor
|
|
@@ -453,6 +561,8 @@ function Inject(type) {
|
|
|
453
561
|
return getMoostMate().decorate('inject', type);
|
|
454
562
|
}
|
|
455
563
|
/**
|
|
564
|
+
* ## Nullable
|
|
565
|
+
* ### @Decorator
|
|
456
566
|
* Makes injectable value optional
|
|
457
567
|
* @param value default true
|
|
458
568
|
*/
|
|
@@ -494,6 +604,12 @@ function IsBoolean(...args) {
|
|
|
494
604
|
return Validate(validoIsBoolean(...args));
|
|
495
605
|
}
|
|
496
606
|
|
|
607
|
+
/**
|
|
608
|
+
* ## Inherit
|
|
609
|
+
* ### @Decorator
|
|
610
|
+
* Inherit metadata from super class
|
|
611
|
+
* @returns
|
|
612
|
+
*/
|
|
497
613
|
const Inherit = () => getMoostMate().decorate('inherit', true);
|
|
498
614
|
|
|
499
615
|
var TPipePriority;
|
|
@@ -509,7 +625,202 @@ var TPipePriority;
|
|
|
509
625
|
TPipePriority[TPipePriority["AFTER_VALIDATE"] = 8] = "AFTER_VALIDATE";
|
|
510
626
|
})(TPipePriority || (TPipePriority = {}));
|
|
511
627
|
|
|
512
|
-
const
|
|
628
|
+
const genericTypesCastPipe = (strict) => {
|
|
629
|
+
const handler = (value, { paramMeta: meta }) => {
|
|
630
|
+
if (meta === null || meta === void 0 ? void 0 : meta.type) {
|
|
631
|
+
if ((value === undefined ||
|
|
632
|
+
value === null ||
|
|
633
|
+
(meta.type !== String && value === '')) &&
|
|
634
|
+
meta.optional) {
|
|
635
|
+
return undefined;
|
|
636
|
+
}
|
|
637
|
+
switch (meta.type) {
|
|
638
|
+
case Date: {
|
|
639
|
+
let d;
|
|
640
|
+
if (typeof value === 'string') {
|
|
641
|
+
d = new Date(/^\d+$/.test(value) ? Number(value) : value);
|
|
642
|
+
}
|
|
643
|
+
else {
|
|
644
|
+
d = new Date(value);
|
|
645
|
+
}
|
|
646
|
+
if (strict && Number.isNaN(d.getTime())) {
|
|
647
|
+
typeError(value, 'Date', meta.label);
|
|
648
|
+
}
|
|
649
|
+
return Number.isNaN(d.getTime()) ? value : d;
|
|
650
|
+
}
|
|
651
|
+
case Boolean:
|
|
652
|
+
if ([
|
|
653
|
+
true,
|
|
654
|
+
'true',
|
|
655
|
+
'TRUE',
|
|
656
|
+
'True',
|
|
657
|
+
1,
|
|
658
|
+
'1',
|
|
659
|
+
'X',
|
|
660
|
+
'x',
|
|
661
|
+
].includes(value)) {
|
|
662
|
+
return true;
|
|
663
|
+
}
|
|
664
|
+
if ([
|
|
665
|
+
false,
|
|
666
|
+
'false',
|
|
667
|
+
'FALSE',
|
|
668
|
+
'False',
|
|
669
|
+
0,
|
|
670
|
+
'0',
|
|
671
|
+
'',
|
|
672
|
+
' ',
|
|
673
|
+
null,
|
|
674
|
+
undefined,
|
|
675
|
+
].includes(value)) {
|
|
676
|
+
return false;
|
|
677
|
+
}
|
|
678
|
+
if (strict) {
|
|
679
|
+
typeError(value, 'boolean', meta.label);
|
|
680
|
+
}
|
|
681
|
+
return value;
|
|
682
|
+
case Number: {
|
|
683
|
+
if (strict && !value && value !== 0) {
|
|
684
|
+
typeError(value, 'numeric', meta.label);
|
|
685
|
+
}
|
|
686
|
+
const n = typeof value === 'string' && value.length > 0
|
|
687
|
+
? Number(value)
|
|
688
|
+
: NaN;
|
|
689
|
+
if (strict && Number.isNaN(n)) {
|
|
690
|
+
typeError(value, 'numeric', meta.label);
|
|
691
|
+
}
|
|
692
|
+
return Number.isNaN(n) ? value : n;
|
|
693
|
+
}
|
|
694
|
+
case String:
|
|
695
|
+
if (strict &&
|
|
696
|
+
['object', 'function'].includes(typeof value)) {
|
|
697
|
+
typeError(value, 'string', meta.label);
|
|
698
|
+
}
|
|
699
|
+
return (value && String(value)) || value;
|
|
700
|
+
default:
|
|
701
|
+
return value;
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
};
|
|
705
|
+
handler.priority = TPipePriority.AFTER_TRANSFORM;
|
|
706
|
+
return handler;
|
|
707
|
+
};
|
|
708
|
+
function typeError(value, targetType, label) {
|
|
709
|
+
const prefix = label ? `Argument "${label}" with value ` : '';
|
|
710
|
+
throw new Error(`${prefix}${JSON.stringify(value)} is not a ${targetType} type`);
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
const valido = new Valido({
|
|
714
|
+
getDtoMeta(value, _type) {
|
|
715
|
+
let type = _type;
|
|
716
|
+
if (!type) {
|
|
717
|
+
type = getConstructor(value);
|
|
718
|
+
}
|
|
719
|
+
const mate = getMoostMate();
|
|
720
|
+
return mate.read(type);
|
|
721
|
+
},
|
|
722
|
+
getDtoParamMeta(value, type, key) {
|
|
723
|
+
const mate = getMoostMate();
|
|
724
|
+
return mate.read(type, key);
|
|
725
|
+
},
|
|
726
|
+
});
|
|
727
|
+
function getMoostValido() {
|
|
728
|
+
return valido;
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
const DEFAULT_ERROR_LIMIT = 10;
|
|
732
|
+
function firstString(errors) {
|
|
733
|
+
const keys = Object.keys(errors);
|
|
734
|
+
for (const key of keys) {
|
|
735
|
+
if (typeof errors[key] === 'string')
|
|
736
|
+
return errors[key];
|
|
737
|
+
return firstString(errors[key]);
|
|
738
|
+
}
|
|
739
|
+
return '';
|
|
740
|
+
}
|
|
741
|
+
const validatePipe = (opts) => {
|
|
742
|
+
const pipe = (_value, metas, level) => __awaiter(void 0, void 0, void 0, function* () {
|
|
743
|
+
const { restoreCtx } = useEventContext();
|
|
744
|
+
const valido = getMoostValido();
|
|
745
|
+
let meta = {};
|
|
746
|
+
if (level === 'PARAM') {
|
|
747
|
+
meta = metas.paramMeta || {};
|
|
748
|
+
}
|
|
749
|
+
else if (level === 'PROP') {
|
|
750
|
+
meta = metas.propMeta || {};
|
|
751
|
+
}
|
|
752
|
+
else if (level === 'METHOD') {
|
|
753
|
+
meta = metas.methodMeta || {};
|
|
754
|
+
}
|
|
755
|
+
else if (level === 'CLASS') {
|
|
756
|
+
meta = metas.classMeta || {};
|
|
757
|
+
}
|
|
758
|
+
const result = yield valido.validateParam(_value, meta, metas.key, undefined, metas.instance, undefined, 0, 0, (opts === null || opts === void 0 ? void 0 : opts.errorLimit) || DEFAULT_ERROR_LIMIT, restoreCtx);
|
|
759
|
+
if (result !== true) {
|
|
760
|
+
const message = typeof result === 'string' ? result : firstString(result);
|
|
761
|
+
if (opts === null || opts === void 0 ? void 0 : opts.errorCb) {
|
|
762
|
+
opts.errorCb(message, result);
|
|
763
|
+
}
|
|
764
|
+
else {
|
|
765
|
+
throw new Error('Validation error: ' + message);
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
return _value;
|
|
769
|
+
});
|
|
770
|
+
pipe.priority = TPipePriority.VALIDATE;
|
|
771
|
+
return pipe;
|
|
772
|
+
};
|
|
773
|
+
|
|
774
|
+
/**
|
|
775
|
+
* ### Define Interceptor Function
|
|
776
|
+
*
|
|
777
|
+
* ```ts
|
|
778
|
+
* defineInterceptorFn((before, after, onError) => {
|
|
779
|
+
* //init
|
|
780
|
+
* before(() => {
|
|
781
|
+
* // before handler
|
|
782
|
+
* })
|
|
783
|
+
* after((response, reply) => {
|
|
784
|
+
* // after handler
|
|
785
|
+
* })
|
|
786
|
+
* onError((error, reply) => {
|
|
787
|
+
* // when error occured
|
|
788
|
+
* })
|
|
789
|
+
* },
|
|
790
|
+
* TInterceptorPriority.INTERCEPTOR,
|
|
791
|
+
* )
|
|
792
|
+
* ```
|
|
793
|
+
*
|
|
794
|
+
* @param fn interceptor function
|
|
795
|
+
* @param priority priority of the interceptor where BEFORE_ALL = 0, BEFORE_GUARD = 1, GUARD = 2, AFTER_GUARD = 3, INTERCEPTOR = 4, CATCH_ERROR = 5, AFTER_ALL = 6
|
|
796
|
+
* @returns
|
|
797
|
+
*/
|
|
798
|
+
function defineInterceptorFn(fn, priority = TInterceptorPriority.INTERCEPTOR) {
|
|
799
|
+
fn.priority = priority;
|
|
800
|
+
return fn;
|
|
801
|
+
}
|
|
802
|
+
/**
|
|
803
|
+
* ### Define Pipe Function
|
|
804
|
+
*
|
|
805
|
+
* ```ts
|
|
806
|
+
* // example of a transform pipe
|
|
807
|
+
* const uppercaseTransformPipe = definePipeFn((value, metas, level) => {
|
|
808
|
+
* return typeof value === 'string' ? value.toUpperCase() : value
|
|
809
|
+
* },
|
|
810
|
+
* TPipePriority.TRANSFORM,
|
|
811
|
+
* )
|
|
812
|
+
* ```
|
|
813
|
+
*
|
|
814
|
+
* @param fn interceptor function
|
|
815
|
+
* @param priority priority of the pipe where BEFORE_RESOLVE = 0, RESOLVE = 1, AFTER_RESOLVE = 2, BEFORE_TRANSFORM = 3, TRANSFORM = 4, AFTER_TRANSFORM = 5, BEFORE_VALIDATE = 6, VALIDATE = 7, AFTER_VALIDATE = 8
|
|
816
|
+
* @returns
|
|
817
|
+
*/
|
|
818
|
+
function definePipeFn(fn, priority = TPipePriority.TRANSFORM) {
|
|
819
|
+
fn.priority = priority;
|
|
820
|
+
return fn;
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
const resolvePipe = definePipeFn((_value, metas, level) => {
|
|
513
824
|
var _a, _b, _c, _d;
|
|
514
825
|
let resolver;
|
|
515
826
|
if (level === 'PARAM') {
|
|
@@ -528,8 +839,7 @@ const resolvePipe = (_value, metas, level) => {
|
|
|
528
839
|
return resolver(metas, level);
|
|
529
840
|
}
|
|
530
841
|
return undefined;
|
|
531
|
-
};
|
|
532
|
-
resolvePipe.priority = TPipePriority.RESOLVE;
|
|
842
|
+
}, TPipePriority.RESOLVE);
|
|
533
843
|
|
|
534
844
|
const sharedPipes = [
|
|
535
845
|
{
|
|
@@ -538,24 +848,6 @@ const sharedPipes = [
|
|
|
538
848
|
},
|
|
539
849
|
];
|
|
540
850
|
|
|
541
|
-
const valido = new Valido({
|
|
542
|
-
getDtoMeta(value, _type) {
|
|
543
|
-
let type = _type;
|
|
544
|
-
if (!type) {
|
|
545
|
-
type = getConstructor(value);
|
|
546
|
-
}
|
|
547
|
-
const mate = getMoostMate();
|
|
548
|
-
return mate.read(type);
|
|
549
|
-
},
|
|
550
|
-
getDtoParamMeta(value, type, key) {
|
|
551
|
-
const mate = getMoostMate();
|
|
552
|
-
return mate.read(type, key);
|
|
553
|
-
},
|
|
554
|
-
});
|
|
555
|
-
function getMoostValido() {
|
|
556
|
-
return valido;
|
|
557
|
-
}
|
|
558
|
-
|
|
559
851
|
function getDefaultLogger(topic) {
|
|
560
852
|
return new ProstoLogger({
|
|
561
853
|
level: 4,
|
|
@@ -567,6 +859,56 @@ function getDefaultLogger(topic) {
|
|
|
567
859
|
}, topic);
|
|
568
860
|
}
|
|
569
861
|
|
|
862
|
+
/**
|
|
863
|
+
* ## Moost
|
|
864
|
+
* Main moostjs class that serves as a shell for Moost Adapters
|
|
865
|
+
*
|
|
866
|
+
* ### Usage with HTTP Adapter
|
|
867
|
+
* ```ts
|
|
868
|
+
* │ // HTTP server example
|
|
869
|
+
* │ import { MoostHttp, Get } from '@moostjs/event-http'
|
|
870
|
+
* │ import { Moost, Param } from 'moost'
|
|
871
|
+
* │
|
|
872
|
+
* │ class MyServer extends Moost {
|
|
873
|
+
* │ @Get('test/:name')
|
|
874
|
+
* │ test(@Param('name') name: string) {
|
|
875
|
+
* │ return { message: `Hello ${name}!` }
|
|
876
|
+
* │ }
|
|
877
|
+
* │ }
|
|
878
|
+
* │
|
|
879
|
+
* │ const app = new MyServer()
|
|
880
|
+
* │ const http = new MoostHttp()
|
|
881
|
+
* │ app.adapter(http).listen(3000, () => {
|
|
882
|
+
* │ app.getLogger('MyApp').log('Up on port 3000')
|
|
883
|
+
* │ })
|
|
884
|
+
* │ app.init()
|
|
885
|
+
* ```
|
|
886
|
+
* ### Usage with CLI Adapter
|
|
887
|
+
* ```ts
|
|
888
|
+
* │ // CLI example
|
|
889
|
+
* │ import { MoostCli, Cli, CliOption, cliHelpInterceptor } from '@moostjs/event-cli'
|
|
890
|
+
* │ import { Moost, Param } from 'moost'
|
|
891
|
+
* │
|
|
892
|
+
* │ class MyApp extends Moost {
|
|
893
|
+
* │ @Cli('command/:arg')
|
|
894
|
+
* │ command(
|
|
895
|
+
* │ @Param('arg')
|
|
896
|
+
* │ arg: string,
|
|
897
|
+
* │ @CliOption('test', 't')
|
|
898
|
+
* │ test: boolean,
|
|
899
|
+
* │ ) {
|
|
900
|
+
* │ return `command run with flag arg=${ arg }, test=${ test }`
|
|
901
|
+
* │ }
|
|
902
|
+
* │ }
|
|
903
|
+
* │
|
|
904
|
+
* │ const app = new MyApp()
|
|
905
|
+
* │ app.applyGlobalInterceptors(cliHelpInterceptor())
|
|
906
|
+
* │
|
|
907
|
+
* │ const cli = new MoostCli()
|
|
908
|
+
* │ app.adapter(cli)
|
|
909
|
+
* │ app.init()
|
|
910
|
+
* ```
|
|
911
|
+
*/
|
|
570
912
|
class Moost {
|
|
571
913
|
constructor(options) {
|
|
572
914
|
this.options = options;
|
|
@@ -580,6 +922,17 @@ class Moost {
|
|
|
580
922
|
const mate = getMoostMate();
|
|
581
923
|
Object.assign(mate, { logger: this.getLogger('mate') });
|
|
582
924
|
}
|
|
925
|
+
/**
|
|
926
|
+
* ### getLogger
|
|
927
|
+
* Provides application logger
|
|
928
|
+
* ```js
|
|
929
|
+
* // get logger with topic = "App"
|
|
930
|
+
* const logger = app.getLogger('App')
|
|
931
|
+
* logger.log('...')
|
|
932
|
+
* ```
|
|
933
|
+
* @param topic
|
|
934
|
+
* @returns
|
|
935
|
+
*/
|
|
583
936
|
getLogger(topic) {
|
|
584
937
|
if (this.logger instanceof ProstoLogger) {
|
|
585
938
|
return this.logger.createTopic(topic);
|
|
@@ -590,13 +943,20 @@ class Moost {
|
|
|
590
943
|
this.adapters.push(a);
|
|
591
944
|
return a;
|
|
592
945
|
}
|
|
946
|
+
/**
|
|
947
|
+
* ### init
|
|
948
|
+
* Ititializes adapter. Must be called after adapters are attached.
|
|
949
|
+
*/
|
|
593
950
|
init() {
|
|
594
951
|
return __awaiter(this, void 0, void 0, function* () {
|
|
595
952
|
this.setProvideRegistry(createProvideRegistry([Moost, () => this]));
|
|
596
953
|
for (const a of this.adapters) {
|
|
597
954
|
const constructor = getConstructor(a);
|
|
598
955
|
if (constructor) {
|
|
599
|
-
this.setProvideRegistry(createProvideRegistry([
|
|
956
|
+
this.setProvideRegistry(createProvideRegistry([
|
|
957
|
+
constructor,
|
|
958
|
+
() => a,
|
|
959
|
+
]));
|
|
600
960
|
}
|
|
601
961
|
if (typeof a.getProvideRegistry === 'function') {
|
|
602
962
|
this.setProvideRegistry(a.getProvideRegistry());
|
|
@@ -605,7 +965,7 @@ class Moost {
|
|
|
605
965
|
this.unregisteredControllers.unshift(this);
|
|
606
966
|
yield this.bindControllers();
|
|
607
967
|
for (const a of this.adapters) {
|
|
608
|
-
yield (a.onInit && a.onInit());
|
|
968
|
+
yield (a.onInit && a.onInit(this));
|
|
609
969
|
}
|
|
610
970
|
});
|
|
611
971
|
}
|
|
@@ -633,7 +993,9 @@ class Moost {
|
|
|
633
993
|
const pipes = [...this.pipes, ...((classMeta === null || classMeta === void 0 ? void 0 : classMeta.pipes) || [])].sort((a, b) => a.priority - b.priority);
|
|
634
994
|
let instance;
|
|
635
995
|
const infactOpts = { provide, customData: { pipes } };
|
|
636
|
-
if (isControllerConsructor &&
|
|
996
|
+
if (isControllerConsructor &&
|
|
997
|
+
((classMeta === null || classMeta === void 0 ? void 0 : classMeta.injectable) === 'SINGLETON' ||
|
|
998
|
+
(classMeta === null || classMeta === void 0 ? void 0 : classMeta.injectable) === true)) {
|
|
637
999
|
instance = (yield infact.get(controller, infactOpts));
|
|
638
1000
|
}
|
|
639
1001
|
else if (!isControllerConsructor) {
|
|
@@ -641,16 +1003,20 @@ class Moost {
|
|
|
641
1003
|
infact.setProvideRegByInstance(instance, provide);
|
|
642
1004
|
}
|
|
643
1005
|
// getInstance - instance factory for resolving SINGLETON and FOR_EVENT instance
|
|
644
|
-
const getInstance = instance
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
1006
|
+
const getInstance = instance
|
|
1007
|
+
? () => Promise.resolve(instance)
|
|
1008
|
+
: () => __awaiter(this, void 0, void 0, function* () {
|
|
1009
|
+
// if (!instance) {
|
|
1010
|
+
infact.silent(true);
|
|
1011
|
+
const { restoreCtx } = useEventContext();
|
|
1012
|
+
const instance = (yield infact.get(controller, Object.assign(Object.assign({}, infactOpts), { syncContextFn: restoreCtx })));
|
|
1013
|
+
infact.silent(false);
|
|
1014
|
+
// }
|
|
1015
|
+
return instance;
|
|
1016
|
+
});
|
|
1017
|
+
const classConstructor = isConstructor(controller)
|
|
1018
|
+
? controller
|
|
1019
|
+
: getConstructor(controller);
|
|
654
1020
|
yield bindControllerMethods({
|
|
655
1021
|
getInstance,
|
|
656
1022
|
classConstructor,
|
|
@@ -663,7 +1029,9 @@ class Moost {
|
|
|
663
1029
|
logger: this.logger,
|
|
664
1030
|
});
|
|
665
1031
|
if (classMeta && classMeta.importController) {
|
|
666
|
-
const prefix = typeof replaceOwnPrefix === 'string'
|
|
1032
|
+
const prefix = typeof replaceOwnPrefix === 'string'
|
|
1033
|
+
? replaceOwnPrefix
|
|
1034
|
+
: (_a = classMeta === null || classMeta === void 0 ? void 0 : classMeta.controller) === null || _a === void 0 ? void 0 : _a.prefix;
|
|
667
1035
|
const mergedProvide = Object.assign(Object.assign({}, provide), ((classMeta === null || classMeta === void 0 ? void 0 : classMeta.provide) || {}));
|
|
668
1036
|
for (const ic of classMeta.importController) {
|
|
669
1037
|
if (ic.typeResolver) {
|
|
@@ -671,7 +1039,12 @@ class Moost {
|
|
|
671
1039
|
const isFunc = typeof ic.typeResolver === 'function';
|
|
672
1040
|
yield this.bindController(
|
|
673
1041
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
674
|
-
isConstr
|
|
1042
|
+
isConstr
|
|
1043
|
+
? ic.typeResolver
|
|
1044
|
+
: isFunc
|
|
1045
|
+
? yield ic.typeResolver()
|
|
1046
|
+
: ic.typeResolver, ic.provide
|
|
1047
|
+
? Object.assign(Object.assign({}, mergedProvide), ic.provide) : mergedProvide, `${globalPrefix}/${prefix || ''}`, ic.prefix);
|
|
675
1048
|
}
|
|
676
1049
|
}
|
|
677
1050
|
}
|
|
@@ -682,7 +1055,9 @@ class Moost {
|
|
|
682
1055
|
if (typeof item === 'function') {
|
|
683
1056
|
this.pipes.push({
|
|
684
1057
|
handler: item,
|
|
685
|
-
priority: typeof item.priority === 'number'
|
|
1058
|
+
priority: typeof item.priority === 'number'
|
|
1059
|
+
? item.priority
|
|
1060
|
+
: TPipePriority.TRANSFORM,
|
|
686
1061
|
});
|
|
687
1062
|
}
|
|
688
1063
|
else {
|
|
@@ -692,14 +1067,35 @@ class Moost {
|
|
|
692
1067
|
});
|
|
693
1068
|
}
|
|
694
1069
|
}
|
|
1070
|
+
this.globalInterceptorHandler = undefined;
|
|
695
1071
|
return this;
|
|
696
1072
|
}
|
|
1073
|
+
/**
|
|
1074
|
+
* Provides InterceptorHandler with global interceptors and pipes.
|
|
1075
|
+
* Used to process interceptors when event handler was not found.
|
|
1076
|
+
*
|
|
1077
|
+
* @returns array of interceptors
|
|
1078
|
+
*/
|
|
1079
|
+
getGlobalInterceptorHandler() {
|
|
1080
|
+
if (!this.globalInterceptorHandler) {
|
|
1081
|
+
const mate = getMoostMate();
|
|
1082
|
+
const thisMeta = mate.read(this);
|
|
1083
|
+
const pipes = [...(this.pipes || []), ...((thisMeta === null || thisMeta === void 0 ? void 0 : thisMeta.pipes) || [])].sort((a, b) => a.priority - b.priority);
|
|
1084
|
+
const interceptors = [...this.interceptors, ...((thisMeta === null || thisMeta === void 0 ? void 0 : thisMeta.interceptors) || [])]
|
|
1085
|
+
.sort((a, b) => a.priority - b.priority);
|
|
1086
|
+
this.globalInterceptorHandler = getIterceptorHandlerFactory(interceptors, () => Promise.resolve(this), pipes, this.logger)();
|
|
1087
|
+
}
|
|
1088
|
+
return this.globalInterceptorHandler;
|
|
1089
|
+
}
|
|
697
1090
|
applyGlobalInterceptors(...items) {
|
|
698
1091
|
for (const item of items) {
|
|
699
1092
|
if (typeof item === 'function') {
|
|
700
1093
|
this.interceptors.push({
|
|
701
1094
|
handler: item,
|
|
702
|
-
priority: typeof item.priority === 'number'
|
|
1095
|
+
priority: typeof item.priority === 'number'
|
|
1096
|
+
? item
|
|
1097
|
+
.priority
|
|
1098
|
+
: TInterceptorPriority.INTERCEPTOR,
|
|
703
1099
|
});
|
|
704
1100
|
}
|
|
705
1101
|
else {
|
|
@@ -709,6 +1105,7 @@ class Moost {
|
|
|
709
1105
|
});
|
|
710
1106
|
}
|
|
711
1107
|
}
|
|
1108
|
+
this.globalInterceptorHandler = undefined;
|
|
712
1109
|
return this;
|
|
713
1110
|
}
|
|
714
1111
|
/**
|
|
@@ -731,108 +1128,6 @@ class Moost {
|
|
|
731
1128
|
}
|
|
732
1129
|
}
|
|
733
1130
|
|
|
734
|
-
const genericTypesCastPipe = (strict) => {
|
|
735
|
-
const handler = (value, { paramMeta: meta }) => {
|
|
736
|
-
if (meta === null || meta === void 0 ? void 0 : meta.type) {
|
|
737
|
-
if ((value === undefined || value === null || (meta.type !== String && value === '')) && meta.optional) {
|
|
738
|
-
return undefined;
|
|
739
|
-
}
|
|
740
|
-
switch (meta.type) {
|
|
741
|
-
case Date: {
|
|
742
|
-
let d;
|
|
743
|
-
if (typeof value === 'string') {
|
|
744
|
-
d = new Date(/^\d+$/.test(value) ? Number(value) : value);
|
|
745
|
-
}
|
|
746
|
-
else {
|
|
747
|
-
d = new Date(value);
|
|
748
|
-
}
|
|
749
|
-
if (strict && Number.isNaN(d.getTime())) {
|
|
750
|
-
typeError(value, 'Date', meta.label);
|
|
751
|
-
}
|
|
752
|
-
return Number.isNaN(d.getTime()) ? value : d;
|
|
753
|
-
}
|
|
754
|
-
case Boolean:
|
|
755
|
-
if ([true, 'true', 'TRUE', 'True', 1, '1', 'X', 'x'].includes(value)) {
|
|
756
|
-
return true;
|
|
757
|
-
}
|
|
758
|
-
if ([false, 'false', 'FALSE', 'False', 0, '0', '', ' ', null, undefined].includes(value)) {
|
|
759
|
-
return false;
|
|
760
|
-
}
|
|
761
|
-
if (strict) {
|
|
762
|
-
typeError(value, 'boolean', meta.label);
|
|
763
|
-
}
|
|
764
|
-
return value;
|
|
765
|
-
case Number: {
|
|
766
|
-
if (strict && !value && value !== 0) {
|
|
767
|
-
typeError(value, 'numeric', meta.label);
|
|
768
|
-
}
|
|
769
|
-
const n = typeof value === 'string' && value.length > 0 ? Number(value) : NaN;
|
|
770
|
-
if (strict && Number.isNaN(n)) {
|
|
771
|
-
typeError(value, 'numeric', meta.label);
|
|
772
|
-
}
|
|
773
|
-
return Number.isNaN(n) ? value : n;
|
|
774
|
-
}
|
|
775
|
-
case String:
|
|
776
|
-
if (strict && ['object', 'function'].includes(typeof value)) {
|
|
777
|
-
typeError(value, 'string', meta.label);
|
|
778
|
-
}
|
|
779
|
-
return value && String(value) || value;
|
|
780
|
-
default:
|
|
781
|
-
return value;
|
|
782
|
-
}
|
|
783
|
-
}
|
|
784
|
-
};
|
|
785
|
-
handler.priority = TPipePriority.AFTER_TRANSFORM;
|
|
786
|
-
return handler;
|
|
787
|
-
};
|
|
788
|
-
function typeError(value, targetType, label) {
|
|
789
|
-
const prefix = label ? `Argument "${label}" with value ` : '';
|
|
790
|
-
throw new Error(`${prefix}${JSON.stringify(value)} is not a ${targetType} type`);
|
|
791
|
-
}
|
|
792
|
-
|
|
793
|
-
const DEFAULT_ERROR_LIMIT = 10;
|
|
794
|
-
function firstString(errors) {
|
|
795
|
-
const keys = Object.keys(errors);
|
|
796
|
-
for (const key of keys) {
|
|
797
|
-
if (typeof errors[key] === 'string')
|
|
798
|
-
return errors[key];
|
|
799
|
-
return firstString(errors[key]);
|
|
800
|
-
}
|
|
801
|
-
return '';
|
|
802
|
-
}
|
|
803
|
-
const validatePipe = (opts) => {
|
|
804
|
-
const pipe = (_value, metas, level) => __awaiter(void 0, void 0, void 0, function* () {
|
|
805
|
-
const { restoreCtx } = useEventContext();
|
|
806
|
-
const valido = getMoostValido();
|
|
807
|
-
let meta = {};
|
|
808
|
-
if (level === 'PARAM') {
|
|
809
|
-
meta = metas.paramMeta || {};
|
|
810
|
-
}
|
|
811
|
-
else if (level === 'PROP') {
|
|
812
|
-
meta = metas.propMeta || {};
|
|
813
|
-
}
|
|
814
|
-
else if (level === 'METHOD') {
|
|
815
|
-
meta = metas.methodMeta || {};
|
|
816
|
-
}
|
|
817
|
-
else if (level === 'CLASS') {
|
|
818
|
-
meta = metas.classMeta || {};
|
|
819
|
-
}
|
|
820
|
-
const result = yield valido.validateParam(_value, meta, metas.key, undefined, metas.instance, undefined, 0, 0, (opts === null || opts === void 0 ? void 0 : opts.errorLimit) || DEFAULT_ERROR_LIMIT, restoreCtx);
|
|
821
|
-
if (result !== true) {
|
|
822
|
-
const message = typeof result === 'string' ? result : firstString(result);
|
|
823
|
-
if (opts === null || opts === void 0 ? void 0 : opts.errorCb) {
|
|
824
|
-
opts.errorCb(message, result);
|
|
825
|
-
}
|
|
826
|
-
else {
|
|
827
|
-
throw new Error('Validation error: ' + message);
|
|
828
|
-
}
|
|
829
|
-
}
|
|
830
|
-
return _value;
|
|
831
|
-
});
|
|
832
|
-
pipe.priority = TPipePriority.VALIDATE;
|
|
833
|
-
return pipe;
|
|
834
|
-
};
|
|
835
|
-
|
|
836
1131
|
function setControllerContext(controller, method) {
|
|
837
1132
|
const { store } = useEventContext();
|
|
838
1133
|
const { set } = store('controller');
|
|
@@ -844,7 +1139,9 @@ function useControllerContext() {
|
|
|
844
1139
|
const { get } = store('controller');
|
|
845
1140
|
const getController = () => get('instance');
|
|
846
1141
|
const getMethod = () => get('method');
|
|
1142
|
+
// todo: add generic types to getControllerMeta
|
|
847
1143
|
const getControllerMeta = () => getMoostMate().read(getController());
|
|
1144
|
+
// todo: add generic types to getMethodMeta
|
|
848
1145
|
const getMethodMeta = () => getMoostMate().read(getController(), getMethod());
|
|
849
1146
|
return {
|
|
850
1147
|
getController,
|
|
@@ -854,4 +1151,118 @@ function useControllerContext() {
|
|
|
854
1151
|
};
|
|
855
1152
|
}
|
|
856
1153
|
|
|
857
|
-
|
|
1154
|
+
const infact = getMoostInfact();
|
|
1155
|
+
function registerEventScope(scopeId) {
|
|
1156
|
+
infact.registerScope(scopeId);
|
|
1157
|
+
return () => infact.unregisterScope(scopeId);
|
|
1158
|
+
}
|
|
1159
|
+
function defineMoostEventHandler(options) {
|
|
1160
|
+
return () => __awaiter(this, void 0, void 0, function* () {
|
|
1161
|
+
var _a;
|
|
1162
|
+
const { restoreCtx } = useEventContext(options.contextType);
|
|
1163
|
+
const scopeId = useEventId().getId();
|
|
1164
|
+
const logger = useEventLogger(options.loggerTitle);
|
|
1165
|
+
const unscope = registerEventScope(scopeId);
|
|
1166
|
+
let response;
|
|
1167
|
+
const hookOptions = {
|
|
1168
|
+
restoreCtx,
|
|
1169
|
+
scopeId,
|
|
1170
|
+
logger,
|
|
1171
|
+
unscope,
|
|
1172
|
+
method: options.controllerMethod,
|
|
1173
|
+
getResponse: () => response,
|
|
1174
|
+
reply: (r) => response = r,
|
|
1175
|
+
};
|
|
1176
|
+
if ((_a = options.hooks) === null || _a === void 0 ? void 0 : _a.init) {
|
|
1177
|
+
yield options.hooks.init(hookOptions);
|
|
1178
|
+
restoreCtx();
|
|
1179
|
+
}
|
|
1180
|
+
const instance = yield options.getControllerInstance();
|
|
1181
|
+
restoreCtx();
|
|
1182
|
+
if (instance) {
|
|
1183
|
+
setControllerContext(instance, options.controllerMethod || '');
|
|
1184
|
+
}
|
|
1185
|
+
const interceptorHandler = yield options.getIterceptorHandler();
|
|
1186
|
+
if (interceptorHandler) {
|
|
1187
|
+
restoreCtx();
|
|
1188
|
+
try {
|
|
1189
|
+
response = yield interceptorHandler.init();
|
|
1190
|
+
if (typeof response !== 'undefined')
|
|
1191
|
+
return endWithResponse();
|
|
1192
|
+
}
|
|
1193
|
+
catch (e) {
|
|
1194
|
+
options.logErrors && logger.error(e);
|
|
1195
|
+
response = e;
|
|
1196
|
+
return endWithResponse();
|
|
1197
|
+
}
|
|
1198
|
+
}
|
|
1199
|
+
let args = [];
|
|
1200
|
+
if (options.resolveArgs) {
|
|
1201
|
+
// params
|
|
1202
|
+
restoreCtx();
|
|
1203
|
+
try {
|
|
1204
|
+
// logger.trace(`resolving method args for "${ opts.method as string }"`)
|
|
1205
|
+
args = yield options.resolveArgs();
|
|
1206
|
+
// logger.trace(`args for method "${ opts.method as string }" resolved (count ${String(args.length)})`)
|
|
1207
|
+
}
|
|
1208
|
+
catch (e) {
|
|
1209
|
+
options.logErrors && logger.error(e);
|
|
1210
|
+
response = e;
|
|
1211
|
+
return endWithResponse();
|
|
1212
|
+
}
|
|
1213
|
+
}
|
|
1214
|
+
if (interceptorHandler) {
|
|
1215
|
+
restoreCtx();
|
|
1216
|
+
response = yield interceptorHandler.fireBefore(response);
|
|
1217
|
+
if (typeof response !== 'undefined')
|
|
1218
|
+
return endWithResponse();
|
|
1219
|
+
}
|
|
1220
|
+
// fire request handler
|
|
1221
|
+
const callControllerMethod = () => {
|
|
1222
|
+
restoreCtx();
|
|
1223
|
+
if (options.callControllerMethod) {
|
|
1224
|
+
return options.callControllerMethod(args);
|
|
1225
|
+
}
|
|
1226
|
+
else if (instance && options.controllerMethod && typeof instance[options.controllerMethod] === 'function') {
|
|
1227
|
+
return instance[options.controllerMethod](...args);
|
|
1228
|
+
}
|
|
1229
|
+
};
|
|
1230
|
+
try {
|
|
1231
|
+
response = callControllerMethod();
|
|
1232
|
+
}
|
|
1233
|
+
catch (e) {
|
|
1234
|
+
options.logErrors && logger.error(e);
|
|
1235
|
+
response = e;
|
|
1236
|
+
}
|
|
1237
|
+
function endWithResponse() {
|
|
1238
|
+
var _a;
|
|
1239
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1240
|
+
// fire after interceptors
|
|
1241
|
+
if (interceptorHandler) {
|
|
1242
|
+
restoreCtx();
|
|
1243
|
+
try {
|
|
1244
|
+
// logger.trace('firing after interceptors')
|
|
1245
|
+
response = yield interceptorHandler.fireAfter(response);
|
|
1246
|
+
}
|
|
1247
|
+
catch (e) {
|
|
1248
|
+
options.logErrors && logger.error(e);
|
|
1249
|
+
if (!options.manualUnscope) {
|
|
1250
|
+
unscope();
|
|
1251
|
+
}
|
|
1252
|
+
throw e;
|
|
1253
|
+
}
|
|
1254
|
+
}
|
|
1255
|
+
if (!options.manualUnscope) {
|
|
1256
|
+
unscope();
|
|
1257
|
+
}
|
|
1258
|
+
if ((_a = options.hooks) === null || _a === void 0 ? void 0 : _a.end) {
|
|
1259
|
+
yield options.hooks.end(hookOptions);
|
|
1260
|
+
}
|
|
1261
|
+
return response;
|
|
1262
|
+
});
|
|
1263
|
+
}
|
|
1264
|
+
return yield endWithResponse();
|
|
1265
|
+
});
|
|
1266
|
+
}
|
|
1267
|
+
|
|
1268
|
+
export { Circular, Const, ConstFactory, Controller, Description, Dto, Id, ImportController, Inherit, Inject, InjectEventLogger, Injectable, Intercept, InterceptorHandler, IsArray, IsBoolean, IsNumber, IsString, IsTypeOf, Label, Moost, Nullable, Optional, Param, Params, Provide, Required, Resolve, TInterceptorPriority, TPipePriority, Validate, Value, defineInterceptorFn, defineMoostEventHandler, definePipeFn, genericTypesCastPipe, getMoostInfact, getMoostMate, getNewMoostInfact, registerEventScope, resolvePipe, setControllerContext, useControllerContext, validatePipe };
|