moost 0.0.1-beta.5 → 0.2.0
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 +14 -8
- package/dist/index.cjs +2093 -0
- package/dist/{moost.d.ts → index.d.ts} +43 -156
- package/dist/index.mjs +2063 -0
- package/package.json +13 -69
- package/LICENSE +0 -21
- package/dist/moost.cjs.prod.js +0 -922
- package/dist/moost.esm-bundler.js +0 -869
- package/dist/src/binding/bind-controller.d.ts +0 -13
- package/dist/src/binding/bind-controller.d.ts.map +0 -1
- package/dist/src/binding/bind-handler.d.ts +0 -18
- package/dist/src/binding/bind-handler.d.ts.map +0 -1
- package/dist/src/binding/index.d.ts +0 -3
- package/dist/src/binding/index.d.ts.map +0 -1
- package/dist/src/binding/tests/binding.spec.d.ts +0 -2
- package/dist/src/binding/tests/binding.spec.d.ts.map +0 -1
- package/dist/src/binding/utils.d.ts +0 -3
- package/dist/src/binding/utils.d.ts.map +0 -1
- package/dist/src/class-function/class-function.d.ts +0 -4
- package/dist/src/class-function/class-function.d.ts.map +0 -1
- package/dist/src/class-function/index.d.ts +0 -2
- package/dist/src/class-function/index.d.ts.map +0 -1
- package/dist/src/class-function/types.d.ts +0 -9
- package/dist/src/class-function/types.d.ts.map +0 -1
- package/dist/src/composables/controller-meta.d.ts +0 -13
- package/dist/src/composables/controller-meta.d.ts.map +0 -1
- package/dist/src/composables/index.d.ts +0 -2
- package/dist/src/composables/index.d.ts.map +0 -1
- package/dist/src/decorators/circular.decorator.d.ts +0 -3
- package/dist/src/decorators/circular.decorator.d.ts.map +0 -1
- package/dist/src/decorators/common.decorator.d.ts +0 -4
- package/dist/src/decorators/common.decorator.d.ts.map +0 -1
- package/dist/src/decorators/controller.decorator.d.ts +0 -24
- package/dist/src/decorators/controller.decorator.d.ts.map +0 -1
- package/dist/src/decorators/http-method.decorator.d.ts +0 -8
- package/dist/src/decorators/http-method.decorator.d.ts.map +0 -1
- package/dist/src/decorators/index.d.ts +0 -10
- package/dist/src/decorators/index.d.ts.map +0 -1
- package/dist/src/decorators/injectable.decorator.d.ts +0 -12
- package/dist/src/decorators/injectable.decorator.d.ts.map +0 -1
- package/dist/src/decorators/intercept.decorator.d.ts +0 -20
- package/dist/src/decorators/intercept.decorator.d.ts.map +0 -1
- package/dist/src/decorators/pipe.decorator.d.ts +0 -3
- package/dist/src/decorators/pipe.decorator.d.ts.map +0 -1
- package/dist/src/decorators/provide.decorator.d.ts +0 -5
- package/dist/src/decorators/provide.decorator.d.ts.map +0 -1
- package/dist/src/decorators/resolve.decorator.d.ts +0 -137
- package/dist/src/decorators/resolve.decorator.d.ts.map +0 -1
- package/dist/src/decorators/tests/circular.artifacts.d.ts +0 -7
- package/dist/src/decorators/tests/circular.artifacts.d.ts.map +0 -1
- package/dist/src/decorators/tests/circular.spec.d.ts +0 -2
- package/dist/src/decorators/tests/circular.spec.d.ts.map +0 -1
- package/dist/src/decorators/tests/common.artifacts.d.ts +0 -4
- package/dist/src/decorators/tests/common.artifacts.d.ts.map +0 -1
- package/dist/src/decorators/tests/common.spec.d.ts +0 -2
- package/dist/src/decorators/tests/common.spec.d.ts.map +0 -1
- package/dist/src/decorators/tests/controller.spec.d.ts +0 -2
- package/dist/src/decorators/tests/controller.spec.d.ts.map +0 -1
- package/dist/src/decorators/tests/http-method.artifacts.d.ts +0 -12
- package/dist/src/decorators/tests/http-method.artifacts.d.ts.map +0 -1
- package/dist/src/decorators/tests/http-method.spec.d.ts +0 -2
- package/dist/src/decorators/tests/http-method.spec.d.ts.map +0 -1
- package/dist/src/decorators/tests/injectable.spec.d.ts +0 -2
- package/dist/src/decorators/tests/injectable.spec.d.ts.map +0 -1
- package/dist/src/decorators/tests/intercept.spec.d.ts +0 -2
- package/dist/src/decorators/tests/intercept.spec.d.ts.map +0 -1
- package/dist/src/decorators/tests/pipe.artifacts.d.ts +0 -4
- package/dist/src/decorators/tests/pipe.artifacts.d.ts.map +0 -1
- package/dist/src/decorators/tests/pipe.spec.d.ts +0 -2
- package/dist/src/decorators/tests/pipe.spec.d.ts.map +0 -1
- package/dist/src/decorators/tests/provide.artifacts.d.ts +0 -9
- package/dist/src/decorators/tests/provide.artifacts.d.ts.map +0 -1
- package/dist/src/decorators/tests/provide.spec.d.ts +0 -2
- package/dist/src/decorators/tests/provide.spec.d.ts.map +0 -1
- package/dist/src/decorators/tests/resolve.artifacts.d.ts +0 -4
- package/dist/src/decorators/tests/resolve.artifacts.d.ts.map +0 -1
- package/dist/src/decorators/tests/resolve.spec.d.ts +0 -2
- package/dist/src/decorators/tests/resolve.spec.d.ts.map +0 -1
- package/dist/src/decorators/tests/validate.artifacts.d.ts +0 -21
- package/dist/src/decorators/tests/validate.artifacts.d.ts.map +0 -1
- package/dist/src/decorators/tests/validate.spec.d.ts +0 -2
- package/dist/src/decorators/tests/validate.spec.d.ts.map +0 -1
- package/dist/src/decorators/validate.decorator.d.ts +0 -10
- package/dist/src/decorators/validate.decorator.d.ts.map +0 -1
- package/dist/src/index.d.ts +0 -7
- package/dist/src/index.d.ts.map +0 -1
- package/dist/src/metadata/index.d.ts +0 -2
- package/dist/src/metadata/index.d.ts.map +0 -1
- package/dist/src/metadata/infact.d.ts +0 -7
- package/dist/src/metadata/infact.d.ts.map +0 -1
- package/dist/src/metadata/moost-metadata.d.ts +0 -62
- package/dist/src/metadata/moost-metadata.d.ts.map +0 -1
- package/dist/src/metadata/valido.d.ts +0 -3
- package/dist/src/metadata/valido.d.ts.map +0 -1
- package/dist/src/moost.d.ts +0 -44
- package/dist/src/moost.d.ts.map +0 -1
- package/dist/src/moost.spec.d.ts +0 -2
- package/dist/src/moost.spec.d.ts.map +0 -1
- package/dist/src/pipes/generic-types-cast.pipe.d.ts +0 -3
- package/dist/src/pipes/generic-types-cast.pipe.d.ts.map +0 -1
- package/dist/src/pipes/index.d.ts +0 -5
- package/dist/src/pipes/index.d.ts.map +0 -1
- package/dist/src/pipes/resolve.pipe.d.ts +0 -3
- package/dist/src/pipes/resolve.pipe.d.ts.map +0 -1
- package/dist/src/pipes/run-pipes.d.ts +0 -5
- package/dist/src/pipes/run-pipes.d.ts.map +0 -1
- package/dist/src/pipes/shared-pipes.d.ts +0 -3
- package/dist/src/pipes/shared-pipes.d.ts.map +0 -1
- package/dist/src/pipes/types.d.ts +0 -21
- package/dist/src/pipes/types.d.ts.map +0 -1
- package/dist/src/pipes/validate.pipe.d.ts +0 -7
- package/dist/src/pipes/validate.pipe.d.ts.map +0 -1
- package/dist/src/pipes/validation.spec.d.ts +0 -2
- package/dist/src/pipes/validation.spec.d.ts.map +0 -1
- package/dist/src/tests/e2e.artifacts.d.ts +0 -17
- package/dist/src/tests/e2e.artifacts.d.ts.map +0 -1
- package/dist/src/tests/e2e.spec.d.ts +0 -2
- package/dist/src/tests/e2e.spec.d.ts.map +0 -1
- package/dist/src/tests/request.artifacts.d.ts +0 -10
- package/dist/src/tests/request.artifacts.d.ts.map +0 -1
- package/dist/src/types.d.ts +0 -8
- package/dist/src/types.d.ts.map +0 -1
- package/dist/src/utils/banner.d.ts +0 -2
- package/dist/src/utils/banner.d.ts.map +0 -1
- package/dist/src/utils/log.d.ts +0 -5
- package/dist/src/utils/log.d.ts.map +0 -1
- package/dist/src/utils/panic.d.ts +0 -2
- package/dist/src/utils/panic.d.ts.map +0 -1
- package/index.js +0 -2
|
@@ -1,869 +0,0 @@
|
|
|
1
|
-
import { Wooks } from 'wooks';
|
|
2
|
-
import { useCacheStore, useRequest, useWooksCtx, useStatus, useSetHeader, useSetCookie, useAuthorization, useHeaders, useCookies, useRouteParams, useSearchParams, useResponse, WooksError } from '@wooksjs/composables';
|
|
3
|
-
import { Mate, getConstructor, isConstructor } from '@prostojs/mate';
|
|
4
|
-
import { Infact, createProvideRegistry } from '@prostojs/infact';
|
|
5
|
-
import { validoIsTypeOf, validoIsString, validoIsNumber, validoIsBoolean, Valido } from '@prostojs/valido';
|
|
6
|
-
import { useBody } from '@wooksjs/body';
|
|
7
|
-
|
|
8
|
-
const METADATA_WORKSPACE = 'moost';
|
|
9
|
-
const moostMate = new Mate(METADATA_WORKSPACE, {
|
|
10
|
-
readType: true,
|
|
11
|
-
readReturnType: true,
|
|
12
|
-
});
|
|
13
|
-
function getMoostMate() {
|
|
14
|
-
return moostMate;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const STORE = Symbol('__moost__');
|
|
18
|
-
function useControllerMeta() {
|
|
19
|
-
const { get } = useMoostStore();
|
|
20
|
-
return {
|
|
21
|
-
getClassMeta: () => getMoostMate().read(get('controller')),
|
|
22
|
-
getMethodMeta: () => getMoostMate().read(get('controller'), get('method')),
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
function setComposableControllerContext(data) {
|
|
26
|
-
const { set } = useMoostStore();
|
|
27
|
-
set('controller', data.controller);
|
|
28
|
-
set('method', data.method);
|
|
29
|
-
set('pathBuilder', data.pathBuilder);
|
|
30
|
-
}
|
|
31
|
-
function useMoostStore() {
|
|
32
|
-
return useCacheStore(STORE);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
async function runPipes(pipes, meta, restoreCtx) {
|
|
36
|
-
let v = undefined;
|
|
37
|
-
for (const pipe of pipes) {
|
|
38
|
-
restoreCtx && restoreCtx();
|
|
39
|
-
v = await pipe.handler(v, meta);
|
|
40
|
-
}
|
|
41
|
-
return v;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
var TPipePriority;
|
|
45
|
-
(function (TPipePriority) {
|
|
46
|
-
TPipePriority[TPipePriority["BEFORE_RESOLVE"] = 0] = "BEFORE_RESOLVE";
|
|
47
|
-
TPipePriority[TPipePriority["RESOLVE"] = 1] = "RESOLVE";
|
|
48
|
-
TPipePriority[TPipePriority["AFTER_RESOLVE"] = 2] = "AFTER_RESOLVE";
|
|
49
|
-
TPipePriority[TPipePriority["BEFORE_TRANSFORM"] = 3] = "BEFORE_TRANSFORM";
|
|
50
|
-
TPipePriority[TPipePriority["TRANSFORM"] = 4] = "TRANSFORM";
|
|
51
|
-
TPipePriority[TPipePriority["AFTER_TRANSFORM"] = 5] = "AFTER_TRANSFORM";
|
|
52
|
-
TPipePriority[TPipePriority["BEFORE_VALIDATE"] = 6] = "BEFORE_VALIDATE";
|
|
53
|
-
TPipePriority[TPipePriority["VALIDATE"] = 7] = "VALIDATE";
|
|
54
|
-
TPipePriority[TPipePriority["AFTER_VALIDATE"] = 8] = "AFTER_VALIDATE";
|
|
55
|
-
})(TPipePriority || (TPipePriority = {}));
|
|
56
|
-
|
|
57
|
-
const resolvePipe = (_value, meta) => {
|
|
58
|
-
if (meta?.resolver) {
|
|
59
|
-
return meta.resolver();
|
|
60
|
-
}
|
|
61
|
-
return undefined;
|
|
62
|
-
};
|
|
63
|
-
resolvePipe.priority = TPipePriority.RESOLVE;
|
|
64
|
-
|
|
65
|
-
const sharedPipes = [
|
|
66
|
-
{
|
|
67
|
-
handler: resolvePipe,
|
|
68
|
-
priority: TPipePriority.RESOLVE,
|
|
69
|
-
},
|
|
70
|
-
];
|
|
71
|
-
|
|
72
|
-
const sharedMoostInfact = getNewMoostInfact();
|
|
73
|
-
function getMoostInfact() {
|
|
74
|
-
return sharedMoostInfact;
|
|
75
|
-
}
|
|
76
|
-
function getNewMoostInfact() {
|
|
77
|
-
return new Infact({
|
|
78
|
-
describeClass(classConstructor) {
|
|
79
|
-
const meta = getMoostMate().read(classConstructor);
|
|
80
|
-
const infactMeta = {
|
|
81
|
-
injectable: !!meta?.injectable,
|
|
82
|
-
global: false,
|
|
83
|
-
constructorParams: meta?.params || [],
|
|
84
|
-
provide: meta?.provide,
|
|
85
|
-
scopeId: meta?.injectable === 'FOR_REQUEST' ? useRequest().reqId() : undefined,
|
|
86
|
-
};
|
|
87
|
-
return infactMeta;
|
|
88
|
-
},
|
|
89
|
-
resolveParam(paramMeta) {
|
|
90
|
-
if (paramMeta.resolver) {
|
|
91
|
-
return runPipes(sharedPipes, paramMeta);
|
|
92
|
-
}
|
|
93
|
-
},
|
|
94
|
-
storeProvideRegByInstance: true,
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
function bindHandler(getInstance, method, wooksApp, options) {
|
|
99
|
-
const pathBuilder = wooksApp.on(options.httpMethod, options.path, async () => {
|
|
100
|
-
const { restoreCtx } = useWooksCtx();
|
|
101
|
-
const { reqId, rawRequest } = useRequest();
|
|
102
|
-
const infact = getMoostInfact();
|
|
103
|
-
const scopeId = reqId();
|
|
104
|
-
infact.registerScope(scopeId);
|
|
105
|
-
rawRequest.on('end', () => infact.unregisterScope(scopeId));
|
|
106
|
-
const instance = await getInstance();
|
|
107
|
-
restoreCtx();
|
|
108
|
-
setComposableControllerContext({
|
|
109
|
-
controller: instance,
|
|
110
|
-
method: method,
|
|
111
|
-
pathBuilder: pathBuilder,
|
|
112
|
-
});
|
|
113
|
-
let response;
|
|
114
|
-
let responseOverwritten = false;
|
|
115
|
-
const before = [];
|
|
116
|
-
const after = [];
|
|
117
|
-
const onError = [];
|
|
118
|
-
function replyFn(reply) {
|
|
119
|
-
response = reply;
|
|
120
|
-
responseOverwritten = true;
|
|
121
|
-
}
|
|
122
|
-
// init interceptors
|
|
123
|
-
for (const handler of options.interceptorHandlers) {
|
|
124
|
-
restoreCtx();
|
|
125
|
-
await handler((fn) => { before.push(fn); }, (fn) => { after.unshift(fn); }, (fn) => { onError.unshift(fn); });
|
|
126
|
-
}
|
|
127
|
-
// params
|
|
128
|
-
let args = [];
|
|
129
|
-
try {
|
|
130
|
-
restoreCtx();
|
|
131
|
-
args = await applyPipesToArgs(options.argsPipes);
|
|
132
|
-
}
|
|
133
|
-
catch (e) {
|
|
134
|
-
response = e;
|
|
135
|
-
}
|
|
136
|
-
if (!response) {
|
|
137
|
-
// fire before interceptors
|
|
138
|
-
for (const handler of before) {
|
|
139
|
-
restoreCtx();
|
|
140
|
-
await handler(replyFn);
|
|
141
|
-
if (responseOverwritten)
|
|
142
|
-
break;
|
|
143
|
-
}
|
|
144
|
-
// fire request handler
|
|
145
|
-
if (!responseOverwritten) {
|
|
146
|
-
try {
|
|
147
|
-
restoreCtx();
|
|
148
|
-
response = await instance[method](...args);
|
|
149
|
-
}
|
|
150
|
-
catch (e) {
|
|
151
|
-
response = e;
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
// fire after interceptors
|
|
156
|
-
if (response instanceof Error) {
|
|
157
|
-
for (const handler of onError) {
|
|
158
|
-
restoreCtx();
|
|
159
|
-
await handler(response, replyFn);
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
else {
|
|
163
|
-
for (const handler of after) {
|
|
164
|
-
restoreCtx();
|
|
165
|
-
await handler(response, replyFn);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
return response;
|
|
169
|
-
});
|
|
170
|
-
}
|
|
171
|
-
async function applyPipesToArgs(argsPipes) {
|
|
172
|
-
const args = [];
|
|
173
|
-
const { restoreCtx } = useWooksCtx();
|
|
174
|
-
for (let i = 0; i < argsPipes.length; i++) {
|
|
175
|
-
const { pipes, meta } = argsPipes[i];
|
|
176
|
-
args[i] = await runPipes(pipes, meta, restoreCtx);
|
|
177
|
-
}
|
|
178
|
-
return args;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
function getInstanceOwnMethods(instance) {
|
|
182
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
183
|
-
const proto = Object.getPrototypeOf(instance);
|
|
184
|
-
return [
|
|
185
|
-
...Object.getOwnPropertyNames(proto),
|
|
186
|
-
...Object.getOwnPropertyNames(instance),
|
|
187
|
-
].filter(m => typeof instance[m] === 'function');
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
/* istanbul ignore file */
|
|
191
|
-
const banner = () => `[moost][${new Date().toISOString().replace('T', ' ').replace(/\.\d{3}z$/i, '')}] `;
|
|
192
|
-
|
|
193
|
-
/* istanbul ignore file */
|
|
194
|
-
function log(text) {
|
|
195
|
-
console.log('[32m' + '[2m' + banner() + text + '[0m');
|
|
196
|
-
}
|
|
197
|
-
function logBright(text) {
|
|
198
|
-
console.log('[32m' + banner() + text + '[0m');
|
|
199
|
-
}
|
|
200
|
-
function logError(error) {
|
|
201
|
-
console.error('[91m' + '[1m' + banner() + error + '[0m');
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
/* istanbul ignore file */
|
|
205
|
-
function panic(error) {
|
|
206
|
-
logError(error);
|
|
207
|
-
return new Error(error);
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
async function getCallableFn(targetInstance, fn, restoreCtx) {
|
|
211
|
-
const mate = getMoostMate();
|
|
212
|
-
const meta = mate.read(fn);
|
|
213
|
-
if (meta?.injectable) {
|
|
214
|
-
const infact = getMoostInfact();
|
|
215
|
-
infact.silent(meta.injectable === 'FOR_REQUEST');
|
|
216
|
-
const instance = await infact.getForInstance(targetInstance, fn, [], () => { restoreCtx && restoreCtx(); });
|
|
217
|
-
infact.silent(false);
|
|
218
|
-
return ((...args) => {
|
|
219
|
-
return instance.handler(...args);
|
|
220
|
-
});
|
|
221
|
-
}
|
|
222
|
-
if (typeof fn === 'function') {
|
|
223
|
-
return fn;
|
|
224
|
-
}
|
|
225
|
-
throw panic(`getCallableFn failed for "${getConstructor(targetInstance).name}" because the passed arg is not a Function nor TClassFunction`);
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
function bindControllerMethods(getInstance, classConstructor, wooksApp, options) {
|
|
229
|
-
const opts = options || {};
|
|
230
|
-
opts.globalPrefix = opts.globalPrefix || '';
|
|
231
|
-
opts.provide = opts.provide || {};
|
|
232
|
-
const fakeInstance = Object.create(classConstructor.prototype);
|
|
233
|
-
const methods = getInstanceOwnMethods(fakeInstance);
|
|
234
|
-
const mate = getMoostMate();
|
|
235
|
-
const meta = mate.read(classConstructor) || {};
|
|
236
|
-
const ownPrefix = typeof opts.replaceOwnPrefix === 'string' ? opts.replaceOwnPrefix : (meta.controller?.prefix || '');
|
|
237
|
-
const prefix = `${opts.globalPrefix}/${ownPrefix}`;
|
|
238
|
-
for (const method of methods) {
|
|
239
|
-
const methodMeta = getMoostMate().read(fakeInstance, method) || {};
|
|
240
|
-
if (!methodMeta.httpHandler || !methodMeta.httpHandler.length)
|
|
241
|
-
continue;
|
|
242
|
-
// preparing interceptors
|
|
243
|
-
const interceptors = [...(opts.interceptors || []), ...(meta.interceptors || []), ...(methodMeta.interceptors || [])].sort((a, b) => a.priority - b.priority);
|
|
244
|
-
const interceptorHandlers = [];
|
|
245
|
-
for (const { handler } of interceptors) {
|
|
246
|
-
const interceptorMeta = mate.read(handler);
|
|
247
|
-
if (interceptorMeta?.injectable) {
|
|
248
|
-
interceptorHandlers.push(async (...args) => {
|
|
249
|
-
const { restoreCtx } = useWooksCtx();
|
|
250
|
-
const targetInstance = await getInstance();
|
|
251
|
-
restoreCtx();
|
|
252
|
-
return (await getCallableFn(targetInstance, handler, restoreCtx))(...args);
|
|
253
|
-
});
|
|
254
|
-
}
|
|
255
|
-
else {
|
|
256
|
-
interceptorHandlers.push(handler);
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
// preparing pipes
|
|
260
|
-
const pipes = [...(opts.pipes || []), ...(meta.pipes || []), ...(methodMeta.pipes || [])];
|
|
261
|
-
const argsPipes = [];
|
|
262
|
-
for (const p of methodMeta.params || []) {
|
|
263
|
-
argsPipes.push({
|
|
264
|
-
meta: p,
|
|
265
|
-
pipes: [...pipes, ...(p.pipes || [])].sort((a, b) => a.priority - b.priority),
|
|
266
|
-
});
|
|
267
|
-
}
|
|
268
|
-
// preparing provide
|
|
269
|
-
const provide = { ...(opts.provide || {}), ...(meta.provide || {}) };
|
|
270
|
-
for (const { method: httpMethod, path: httpPath } of methodMeta.httpHandler) {
|
|
271
|
-
const path = typeof httpPath === 'string' ? httpPath : typeof method === 'string' ? method : '';
|
|
272
|
-
const targetPath = `${prefix || ''}/${path}`.replace(/\/\/+/g, '/');
|
|
273
|
-
bindHandler(getInstance, method, wooksApp, {
|
|
274
|
-
path: targetPath,
|
|
275
|
-
httpMethod,
|
|
276
|
-
interceptorHandlers,
|
|
277
|
-
provide,
|
|
278
|
-
argsMeta: methodMeta.params,
|
|
279
|
-
argsPipes,
|
|
280
|
-
});
|
|
281
|
-
log(`• ${httpMethod}${'[36m'} ${targetPath} ${'[32m'}→ ${classConstructor.name}.${'[36m'}${method}${'[32m'}()`);
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
function HttpMethod(method, path) {
|
|
287
|
-
return getMoostMate().decorate('httpHandler', { method, path }, true);
|
|
288
|
-
}
|
|
289
|
-
const All = (path) => HttpMethod('*', path);
|
|
290
|
-
const Get = (path) => HttpMethod('GET', path);
|
|
291
|
-
const Post = (path) => HttpMethod('POST', path);
|
|
292
|
-
const Put = (path) => HttpMethod('PUT', path);
|
|
293
|
-
const Delete = (path) => HttpMethod('DELETE', path);
|
|
294
|
-
const Patch = (path) => HttpMethod('PATCH', path);
|
|
295
|
-
|
|
296
|
-
function Label(value) {
|
|
297
|
-
return getMoostMate().decorate('label', value);
|
|
298
|
-
}
|
|
299
|
-
function Optional() {
|
|
300
|
-
return getMoostMate().decorate('optional', true);
|
|
301
|
-
}
|
|
302
|
-
function Required() {
|
|
303
|
-
const mate = getMoostMate();
|
|
304
|
-
return mate.apply(mate.decorate('required', true),
|
|
305
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
|
306
|
-
mate.decorateClass((meta, key, index) => {
|
|
307
|
-
if (typeof index !== 'number' && meta && ['string', 'symbol'].includes(typeof key)) {
|
|
308
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
|
|
309
|
-
meta.requiredProps = meta.requiredProps || [];
|
|
310
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
|
311
|
-
meta.requiredProps.push(key);
|
|
312
|
-
}
|
|
313
|
-
return meta;
|
|
314
|
-
}));
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
/**
|
|
318
|
-
* Hook to the Response Status
|
|
319
|
-
* @decorator
|
|
320
|
-
* @param resolver - resolver function
|
|
321
|
-
* @param label - field label
|
|
322
|
-
* @paramType unknown
|
|
323
|
-
*/
|
|
324
|
-
function Resolve(resolver, label) {
|
|
325
|
-
return (target, key, index) => {
|
|
326
|
-
fillLabel(target, key, index, label);
|
|
327
|
-
getMoostMate().decorate('resolver', resolver)(target, key, index);
|
|
328
|
-
};
|
|
329
|
-
}
|
|
330
|
-
/**
|
|
331
|
-
* Hook to the Response Status
|
|
332
|
-
* @decorator
|
|
333
|
-
* @paramType TStatusHook
|
|
334
|
-
*/
|
|
335
|
-
const StatusHook = Resolve(() => useStatus(), 'status');
|
|
336
|
-
/**
|
|
337
|
-
* Hook to the Response Header
|
|
338
|
-
* @decorator
|
|
339
|
-
* @param name - header name
|
|
340
|
-
* @paramType THeaderHook
|
|
341
|
-
*/
|
|
342
|
-
const HeaderHook = (name) => Resolve(() => useSetHeader(name), name);
|
|
343
|
-
/**
|
|
344
|
-
* Hook to the Response Cookie
|
|
345
|
-
* @decorator
|
|
346
|
-
* @param name - header name
|
|
347
|
-
* @paramType TCookieHook
|
|
348
|
-
*/
|
|
349
|
-
const CookieHook = (name) => Resolve(() => useSetCookie(name), name);
|
|
350
|
-
/**
|
|
351
|
-
* Parse Authorisation Header
|
|
352
|
-
* @decorator
|
|
353
|
-
* @param name - define what to take from the Auth header
|
|
354
|
-
* @paramType string
|
|
355
|
-
*/
|
|
356
|
-
function Authorization(name) {
|
|
357
|
-
return Resolve(() => {
|
|
358
|
-
const auth = useAuthorization();
|
|
359
|
-
switch (name) {
|
|
360
|
-
case 'username':
|
|
361
|
-
return auth.isBasic() ? auth.basicCredentials()?.username : undefined;
|
|
362
|
-
case 'password':
|
|
363
|
-
return auth.isBasic() ? auth.basicCredentials()?.password : undefined;
|
|
364
|
-
case 'bearer':
|
|
365
|
-
return auth.isBearer() ? auth.authorization : undefined;
|
|
366
|
-
case 'raw':
|
|
367
|
-
return auth.authRawCredentials();
|
|
368
|
-
case 'type':
|
|
369
|
-
return auth.authType();
|
|
370
|
-
}
|
|
371
|
-
}, 'authorization');
|
|
372
|
-
}
|
|
373
|
-
/**
|
|
374
|
-
* Get Request Header Value
|
|
375
|
-
* @decorator
|
|
376
|
-
* @param name - header name
|
|
377
|
-
* @paramType string
|
|
378
|
-
*/
|
|
379
|
-
function Header(name) {
|
|
380
|
-
return Resolve(() => {
|
|
381
|
-
const headers = useHeaders();
|
|
382
|
-
return headers[name];
|
|
383
|
-
}, 'header: ' + name);
|
|
384
|
-
}
|
|
385
|
-
/**
|
|
386
|
-
* Get Request Cookie Value
|
|
387
|
-
* @decorator
|
|
388
|
-
* @param name - cookie name
|
|
389
|
-
* @paramType string
|
|
390
|
-
*/
|
|
391
|
-
function Cookie(name) {
|
|
392
|
-
return Resolve(() => useCookies().getCookie(name), 'cookie: ' + name);
|
|
393
|
-
}
|
|
394
|
-
/**
|
|
395
|
-
* Get Param Value from url parh
|
|
396
|
-
* @decorator
|
|
397
|
-
* @param name - param name
|
|
398
|
-
* @paramType string
|
|
399
|
-
*/
|
|
400
|
-
function Param(name) {
|
|
401
|
-
return Resolve(() => useRouteParams().getRouteParam(name), name);
|
|
402
|
-
}
|
|
403
|
-
/**
|
|
404
|
-
* Get Parsed Params from url parh
|
|
405
|
-
* @decorator
|
|
406
|
-
* @paramType object
|
|
407
|
-
*/
|
|
408
|
-
function Params() {
|
|
409
|
-
return Resolve(() => useRouteParams().routeParams, 'params');
|
|
410
|
-
}
|
|
411
|
-
/**
|
|
412
|
-
* Get Query Item value or the whole parsed Query as an object
|
|
413
|
-
* @decorator
|
|
414
|
-
* @param name - query item name (optional)
|
|
415
|
-
* @paramType string | object
|
|
416
|
-
*/
|
|
417
|
-
function Query(name) {
|
|
418
|
-
return Resolve(() => {
|
|
419
|
-
const { jsonSearchParams, urlSearchParams } = useSearchParams();
|
|
420
|
-
if (name) {
|
|
421
|
-
const p = urlSearchParams();
|
|
422
|
-
const value = p.get(name);
|
|
423
|
-
console.log(name + ' = ', value);
|
|
424
|
-
return value === '' && p.has(name) || value;
|
|
425
|
-
}
|
|
426
|
-
const json = jsonSearchParams();
|
|
427
|
-
return Object.keys(json).length ? json : undefined;
|
|
428
|
-
}, name || 'Query');
|
|
429
|
-
}
|
|
430
|
-
/**
|
|
431
|
-
* Get Requested URL
|
|
432
|
-
* @decorator
|
|
433
|
-
* @paramType string
|
|
434
|
-
*/
|
|
435
|
-
function Url() {
|
|
436
|
-
return Resolve(() => useRequest().url, 'url');
|
|
437
|
-
}
|
|
438
|
-
/**
|
|
439
|
-
* Get Requested HTTP Method
|
|
440
|
-
* @decorator
|
|
441
|
-
* @paramType string
|
|
442
|
-
*/
|
|
443
|
-
function Method() {
|
|
444
|
-
return Resolve(() => useRequest().method, 'http_method');
|
|
445
|
-
}
|
|
446
|
-
/**
|
|
447
|
-
* Get Raw Request Instance
|
|
448
|
-
* @decorator
|
|
449
|
-
* @paramType IncomingMessage
|
|
450
|
-
*/
|
|
451
|
-
function Req() {
|
|
452
|
-
return Resolve(() => useRequest().rawRequest, 'request');
|
|
453
|
-
}
|
|
454
|
-
/**
|
|
455
|
-
* Get Request Unique Identificator (UUID)
|
|
456
|
-
* @decorator
|
|
457
|
-
* @paramType string
|
|
458
|
-
*/
|
|
459
|
-
function ReqId() {
|
|
460
|
-
return Resolve(() => useRequest().reqId(), 'reqId');
|
|
461
|
-
}
|
|
462
|
-
/**
|
|
463
|
-
* Get Request IP Address
|
|
464
|
-
* @decorator
|
|
465
|
-
* @paramType string
|
|
466
|
-
*/
|
|
467
|
-
function Ip(opts) {
|
|
468
|
-
return Resolve(() => useRequest().getIp(opts), 'ip');
|
|
469
|
-
}
|
|
470
|
-
/**
|
|
471
|
-
* Get Request IP Address list
|
|
472
|
-
* @decorator
|
|
473
|
-
* @paramType string[]
|
|
474
|
-
*/
|
|
475
|
-
function IpList() {
|
|
476
|
-
return Resolve(() => useRequest().getIpList(), 'ipList');
|
|
477
|
-
}
|
|
478
|
-
/**
|
|
479
|
-
* Get Raw Response Object
|
|
480
|
-
* @decorator
|
|
481
|
-
* @param options - passthrough options
|
|
482
|
-
* @paramType string
|
|
483
|
-
*/
|
|
484
|
-
function Res(options) {
|
|
485
|
-
return Resolve(() => useResponse().rawResponse(options), 'response');
|
|
486
|
-
}
|
|
487
|
-
/**
|
|
488
|
-
* Provide Const Value
|
|
489
|
-
* @decorator
|
|
490
|
-
* @param value - provided value
|
|
491
|
-
* @param label - label of the field
|
|
492
|
-
* @paramType unknown
|
|
493
|
-
*/
|
|
494
|
-
function Const(value, label) {
|
|
495
|
-
return Resolve(() => value, label);
|
|
496
|
-
}
|
|
497
|
-
/**
|
|
498
|
-
* Get Parsed Request Body
|
|
499
|
-
* @decorator
|
|
500
|
-
* @paramType object | string | unknown
|
|
501
|
-
*/
|
|
502
|
-
function Body() {
|
|
503
|
-
return Resolve(() => useBody().parseBody(), 'body');
|
|
504
|
-
}
|
|
505
|
-
/**
|
|
506
|
-
* Get Raw Request Body Buffer
|
|
507
|
-
* @decorator
|
|
508
|
-
* @paramType Promise<Buffer>
|
|
509
|
-
*/
|
|
510
|
-
function RawBody() {
|
|
511
|
-
return Resolve(() => useBody().rawBody(), 'body');
|
|
512
|
-
}
|
|
513
|
-
function fillLabel(target, key, index, name) {
|
|
514
|
-
if (name) {
|
|
515
|
-
const meta = getMoostMate().read(target, key);
|
|
516
|
-
if (!meta?.params || !meta?.params[index].label) {
|
|
517
|
-
Label(name)(target, key, index);
|
|
518
|
-
}
|
|
519
|
-
}
|
|
520
|
-
}
|
|
521
|
-
|
|
522
|
-
/**
|
|
523
|
-
* Mark the Class as Injectable to enable it to be used in dependency injection
|
|
524
|
-
* @decorator
|
|
525
|
-
* @param scope - Scope for injection ("FOR_REQUEST" | "SINGLETON" | true)
|
|
526
|
-
* FOR_REQUEST - will create a new instance for each incoming request
|
|
527
|
-
* SINGLETON | true - will create a new instance only once
|
|
528
|
-
* @param label - field label
|
|
529
|
-
*/
|
|
530
|
-
function Injectable(scope = true) {
|
|
531
|
-
return getMoostMate().decorate('injectable', scope);
|
|
532
|
-
}
|
|
533
|
-
const insureInjectable = getMoostMate().decorate((meta) => {
|
|
534
|
-
if (!meta.injectable)
|
|
535
|
-
meta.injectable = true;
|
|
536
|
-
return meta;
|
|
537
|
-
});
|
|
538
|
-
|
|
539
|
-
/**
|
|
540
|
-
* Set Class as a Controller
|
|
541
|
-
* @decorator
|
|
542
|
-
* @param prefix - define the prefix for all the paths of this controller
|
|
543
|
-
*/
|
|
544
|
-
function Controller(prefix) {
|
|
545
|
-
const mate = getMoostMate();
|
|
546
|
-
return mate.apply(insureInjectable, mate.decorate('controller', { prefix: prefix || '' }));
|
|
547
|
-
}
|
|
548
|
-
function ImportController(prefix, controller, provide) {
|
|
549
|
-
return getMoostMate().decorate('importController', {
|
|
550
|
-
prefix: typeof prefix === 'string' ? prefix : undefined,
|
|
551
|
-
typeResolver: typeof prefix === 'string' ? controller : prefix,
|
|
552
|
-
provide: typeof prefix === 'string' ? provide || undefined : controller || undefined,
|
|
553
|
-
}, true);
|
|
554
|
-
}
|
|
555
|
-
|
|
556
|
-
function Circular(resolver) {
|
|
557
|
-
return getMoostMate().decorate('circular', resolver);
|
|
558
|
-
}
|
|
559
|
-
|
|
560
|
-
var TInterceptorPriority;
|
|
561
|
-
(function (TInterceptorPriority) {
|
|
562
|
-
TInterceptorPriority[TInterceptorPriority["BEFORE_ALL"] = 0] = "BEFORE_ALL";
|
|
563
|
-
TInterceptorPriority[TInterceptorPriority["BEFORE_GUARD"] = 1] = "BEFORE_GUARD";
|
|
564
|
-
TInterceptorPriority[TInterceptorPriority["GUARD"] = 2] = "GUARD";
|
|
565
|
-
TInterceptorPriority[TInterceptorPriority["AFTER_GUARD"] = 3] = "AFTER_GUARD";
|
|
566
|
-
TInterceptorPriority[TInterceptorPriority["INTERCEPTOR"] = 4] = "INTERCEPTOR";
|
|
567
|
-
TInterceptorPriority[TInterceptorPriority["CATCH_ERROR"] = 5] = "CATCH_ERROR";
|
|
568
|
-
TInterceptorPriority[TInterceptorPriority["AFTER_ALL"] = 6] = "AFTER_ALL";
|
|
569
|
-
})(TInterceptorPriority || (TInterceptorPriority = {}));
|
|
570
|
-
function Intercept(handler, priority) {
|
|
571
|
-
return getMoostMate().decorate('interceptors', {
|
|
572
|
-
handler,
|
|
573
|
-
priority: priority || handler.priority || TInterceptorPriority.INTERCEPTOR,
|
|
574
|
-
}, true);
|
|
575
|
-
}
|
|
576
|
-
|
|
577
|
-
function Provide(type, fn) {
|
|
578
|
-
return getMoostMate().decorate(meta => {
|
|
579
|
-
meta.provide = meta.provide || {};
|
|
580
|
-
Object.assign(meta.provide, createProvideRegistry([type, fn]));
|
|
581
|
-
return meta;
|
|
582
|
-
});
|
|
583
|
-
}
|
|
584
|
-
function Inject(type) {
|
|
585
|
-
return getMoostMate().decorate('inject', type);
|
|
586
|
-
}
|
|
587
|
-
|
|
588
|
-
function Dto(dtoOptions = {}) {
|
|
589
|
-
return getMoostMate().decorate('dto', dtoOptions || {});
|
|
590
|
-
}
|
|
591
|
-
let isArrayItemValidator = false;
|
|
592
|
-
function Validate(validator) {
|
|
593
|
-
return getMoostMate().decorate(isArrayItemValidator ? 'validatorsOfItem' : 'validators', validator, true);
|
|
594
|
-
}
|
|
595
|
-
function IsArray(opts) {
|
|
596
|
-
const mate = getMoostMate();
|
|
597
|
-
const decorators = [mate.decorate('arrayType', opts || true)];
|
|
598
|
-
if (opts?.itemValidators && !isArrayItemValidator) {
|
|
599
|
-
isArrayItemValidator = true;
|
|
600
|
-
decorators.push(...opts.itemValidators());
|
|
601
|
-
isArrayItemValidator = false;
|
|
602
|
-
}
|
|
603
|
-
else if (opts?.itemValidators && isArrayItemValidator) {
|
|
604
|
-
throw new Error('IsArray validator is not supported inside of array type');
|
|
605
|
-
}
|
|
606
|
-
const decorator = mate.apply(...decorators);
|
|
607
|
-
return decorator;
|
|
608
|
-
}
|
|
609
|
-
function IsTypeOf(type, errorText) {
|
|
610
|
-
return Validate(validoIsTypeOf(type, errorText));
|
|
611
|
-
}
|
|
612
|
-
function IsString(...args) {
|
|
613
|
-
return Validate(validoIsString(...args));
|
|
614
|
-
}
|
|
615
|
-
function IsNumber(...args) {
|
|
616
|
-
return Validate(validoIsNumber(...args));
|
|
617
|
-
}
|
|
618
|
-
function IsBoolean(...args) {
|
|
619
|
-
return Validate(validoIsBoolean(...args));
|
|
620
|
-
}
|
|
621
|
-
|
|
622
|
-
const valido = new Valido({
|
|
623
|
-
getDtoMeta(value, _type) {
|
|
624
|
-
let type = _type;
|
|
625
|
-
if (!type) {
|
|
626
|
-
type = getConstructor(value);
|
|
627
|
-
}
|
|
628
|
-
const mate = getMoostMate();
|
|
629
|
-
return mate.read(type);
|
|
630
|
-
},
|
|
631
|
-
getDtoParamMeta(value, type, key) {
|
|
632
|
-
const mate = getMoostMate();
|
|
633
|
-
return mate.read(type, key);
|
|
634
|
-
},
|
|
635
|
-
});
|
|
636
|
-
function getMoostValido() {
|
|
637
|
-
return valido;
|
|
638
|
-
}
|
|
639
|
-
|
|
640
|
-
class Moost {
|
|
641
|
-
options;
|
|
642
|
-
pipes = [...sharedPipes];
|
|
643
|
-
interceptors = [];
|
|
644
|
-
provide = createProvideRegistry([Infact, getMoostInfact], [Mate, getMoostMate], [Valido, getMoostValido]);
|
|
645
|
-
constructor(options) {
|
|
646
|
-
this.options = options;
|
|
647
|
-
}
|
|
648
|
-
wooksApp;
|
|
649
|
-
unregisteredControllers = [];
|
|
650
|
-
async listen(port, hostname, cb) {
|
|
651
|
-
this.wooksApp = new Wooks(this.options?.wooksOptions);
|
|
652
|
-
this.setProvideRegistry(createProvideRegistry([Wooks, () => this.wooksApp], [Moost, () => this]));
|
|
653
|
-
const _port = Number(this.options?.port || port);
|
|
654
|
-
const _hostname = this.options?.hostname || hostname;
|
|
655
|
-
if (!_port) {
|
|
656
|
-
throw panic('Port is not specified for "listen" method');
|
|
657
|
-
}
|
|
658
|
-
await this.init();
|
|
659
|
-
await this.wooksApp.listen(_port, _hostname, cb);
|
|
660
|
-
logBright(`🚀 ${getConstructor(this).name} is up and running on port ${_port}`);
|
|
661
|
-
return this.wooksApp;
|
|
662
|
-
}
|
|
663
|
-
close() {
|
|
664
|
-
return this.wooksApp?.close();
|
|
665
|
-
}
|
|
666
|
-
async init() {
|
|
667
|
-
if (this.wooksApp) {
|
|
668
|
-
this.unregisteredControllers.unshift(this);
|
|
669
|
-
await this.bindControllers();
|
|
670
|
-
}
|
|
671
|
-
}
|
|
672
|
-
async bindControllers() {
|
|
673
|
-
if (this.wooksApp) {
|
|
674
|
-
const meta = getMoostMate();
|
|
675
|
-
const thisMeta = meta.read(this);
|
|
676
|
-
const provide = { ...(thisMeta?.provide || {}), ...this.provide };
|
|
677
|
-
for (const controller of this.unregisteredControllers) {
|
|
678
|
-
await this.bindController(controller, provide, this.options?.globalPrefix || '');
|
|
679
|
-
}
|
|
680
|
-
this.unregisteredControllers = [];
|
|
681
|
-
}
|
|
682
|
-
}
|
|
683
|
-
async bindController(controller, provide, globalPrefix, replaceOwnPrefix) {
|
|
684
|
-
if (this.wooksApp) {
|
|
685
|
-
const meta = getMoostMate();
|
|
686
|
-
const classMeta = meta.read(controller);
|
|
687
|
-
const infact = getMoostInfact();
|
|
688
|
-
const isControllerConsructor = isConstructor(controller);
|
|
689
|
-
let instance;
|
|
690
|
-
if (isControllerConsructor && classMeta?.injectable === 'SINGLETON') {
|
|
691
|
-
instance = await infact.get(controller, provide);
|
|
692
|
-
}
|
|
693
|
-
else if (!isControllerConsructor) {
|
|
694
|
-
instance = controller;
|
|
695
|
-
infact.setProvideRegByInstance(instance, provide);
|
|
696
|
-
}
|
|
697
|
-
// getInstance - instance factory for resolving SINGLETON and FOR_REQUEST instance
|
|
698
|
-
const getInstance = instance ? () => Promise.resolve(instance) : async () => {
|
|
699
|
-
// if (!instance) {
|
|
700
|
-
infact.silent();
|
|
701
|
-
const instance = await infact.get(controller, provide);
|
|
702
|
-
infact.silent(false);
|
|
703
|
-
// }
|
|
704
|
-
return instance;
|
|
705
|
-
};
|
|
706
|
-
const classConstructor = isConstructor(controller) ? controller : getConstructor(controller);
|
|
707
|
-
bindControllerMethods(getInstance, classConstructor, this.wooksApp, {
|
|
708
|
-
globalPrefix,
|
|
709
|
-
replaceOwnPrefix,
|
|
710
|
-
interceptors: [...this.interceptors],
|
|
711
|
-
pipes: [...this.pipes],
|
|
712
|
-
provide: classMeta?.provide || {},
|
|
713
|
-
});
|
|
714
|
-
if (classMeta && classMeta.importController) {
|
|
715
|
-
const prefix = typeof replaceOwnPrefix === 'string' ? replaceOwnPrefix : classMeta?.controller?.prefix;
|
|
716
|
-
const mergedProvide = { ...provide, ...(classMeta?.provide || {}) };
|
|
717
|
-
for (const ic of classMeta.importController) {
|
|
718
|
-
if (ic.typeResolver) {
|
|
719
|
-
const isConstr = isConstructor(ic.typeResolver);
|
|
720
|
-
const isFunc = typeof ic.typeResolver === 'function';
|
|
721
|
-
await this.bindController(isConstr ? ic.typeResolver : isFunc ? await ic.typeResolver() : ic.typeResolver, ic.provide ? { ...mergedProvide, ...ic.provide } : mergedProvide, `${globalPrefix}/${(prefix || '')}`, ic.prefix);
|
|
722
|
-
}
|
|
723
|
-
}
|
|
724
|
-
}
|
|
725
|
-
}
|
|
726
|
-
}
|
|
727
|
-
applyGlobalPipes(...items) {
|
|
728
|
-
for (const item of items) {
|
|
729
|
-
if (typeof item === 'function') {
|
|
730
|
-
this.pipes.push({
|
|
731
|
-
handler: item,
|
|
732
|
-
priority: typeof item.priority === 'number' ? item.priority : TPipePriority.TRANSFORM,
|
|
733
|
-
});
|
|
734
|
-
}
|
|
735
|
-
else {
|
|
736
|
-
this.pipes.push({
|
|
737
|
-
handler: item.handler,
|
|
738
|
-
priority: item.priority,
|
|
739
|
-
});
|
|
740
|
-
}
|
|
741
|
-
}
|
|
742
|
-
return this;
|
|
743
|
-
}
|
|
744
|
-
applyGlobalInterceptors(...items) {
|
|
745
|
-
for (const item of items) {
|
|
746
|
-
if (typeof item === 'function') {
|
|
747
|
-
this.interceptors.push({
|
|
748
|
-
handler: item,
|
|
749
|
-
priority: typeof item.priority === 'number' ? item.priority : TInterceptorPriority.INTERCEPTOR,
|
|
750
|
-
});
|
|
751
|
-
}
|
|
752
|
-
else {
|
|
753
|
-
this.interceptors.push({
|
|
754
|
-
handler: item.handler,
|
|
755
|
-
priority: item.priority,
|
|
756
|
-
});
|
|
757
|
-
}
|
|
758
|
-
}
|
|
759
|
-
return this;
|
|
760
|
-
}
|
|
761
|
-
/**
|
|
762
|
-
* Register new entried to provide as dependency injections
|
|
763
|
-
* @param provide - Provide Registry (use createProvideRegistry from '\@prostojs/infact')
|
|
764
|
-
* @returns
|
|
765
|
-
*/
|
|
766
|
-
setProvideRegistry(provide) {
|
|
767
|
-
this.provide = { ...this.provide, ...provide };
|
|
768
|
-
return this;
|
|
769
|
-
}
|
|
770
|
-
/**
|
|
771
|
-
* Register controllers (similar to @ImportController decorator)
|
|
772
|
-
* @param controllers - list of target controllers (instances)
|
|
773
|
-
* @returns
|
|
774
|
-
*/
|
|
775
|
-
registerControllers(...controllers) {
|
|
776
|
-
this.unregisteredControllers.push(...controllers);
|
|
777
|
-
return this;
|
|
778
|
-
}
|
|
779
|
-
}
|
|
780
|
-
|
|
781
|
-
const genericTypesCastPipe = (strict) => {
|
|
782
|
-
const handler = (value, meta) => {
|
|
783
|
-
if (meta?.type) {
|
|
784
|
-
if ((value === undefined || value === null || (meta.type !== String && value === '')) && meta.optional) {
|
|
785
|
-
return undefined;
|
|
786
|
-
}
|
|
787
|
-
switch (meta.type) {
|
|
788
|
-
case Date: {
|
|
789
|
-
let d;
|
|
790
|
-
if (typeof value === 'string') {
|
|
791
|
-
d = new Date(/^\d+$/.test(value) ? Number(value) : value);
|
|
792
|
-
}
|
|
793
|
-
else {
|
|
794
|
-
d = new Date(value);
|
|
795
|
-
}
|
|
796
|
-
if (strict && Number.isNaN(d.getTime())) {
|
|
797
|
-
typeError(value, 'Date', meta.label);
|
|
798
|
-
}
|
|
799
|
-
return Number.isNaN(d.getTime()) ? value : d;
|
|
800
|
-
}
|
|
801
|
-
case Boolean:
|
|
802
|
-
if ([true, 'true', 'TRUE', 'True', 1, '1', 'X', 'x'].includes(value)) {
|
|
803
|
-
return true;
|
|
804
|
-
}
|
|
805
|
-
if ([false, 'false', 'FALSE', 'False', 0, '0', '', ' ', null, undefined].includes(value)) {
|
|
806
|
-
return false;
|
|
807
|
-
}
|
|
808
|
-
if (strict) {
|
|
809
|
-
typeError(value, 'boolean', meta.label);
|
|
810
|
-
}
|
|
811
|
-
return value;
|
|
812
|
-
case Number: {
|
|
813
|
-
if (strict && !value && value !== 0) {
|
|
814
|
-
typeError(value, 'numeric', meta.label);
|
|
815
|
-
}
|
|
816
|
-
const n = typeof value === 'string' && value.length > 0 ? Number(value) : NaN;
|
|
817
|
-
if (strict && Number.isNaN(n)) {
|
|
818
|
-
typeError(value, 'numeric', meta.label);
|
|
819
|
-
}
|
|
820
|
-
return Number.isNaN(n) ? value : n;
|
|
821
|
-
}
|
|
822
|
-
case String:
|
|
823
|
-
if (strict && ['object', 'function'].includes(typeof value)) {
|
|
824
|
-
typeError(value, 'string', meta.label);
|
|
825
|
-
}
|
|
826
|
-
return value && String(value) || value;
|
|
827
|
-
default:
|
|
828
|
-
return value;
|
|
829
|
-
}
|
|
830
|
-
}
|
|
831
|
-
};
|
|
832
|
-
handler.priority = TPipePriority.AFTER_TRANSFORM;
|
|
833
|
-
return handler;
|
|
834
|
-
};
|
|
835
|
-
function typeError(value, targetType, label) {
|
|
836
|
-
const prefix = label ? `Argument "${label}" with value ` : '';
|
|
837
|
-
throw new WooksError(400, `${prefix}${JSON.stringify(value)} is not a ${targetType} type`);
|
|
838
|
-
}
|
|
839
|
-
|
|
840
|
-
const DEFAULT_ERROR_LIMIT = 10;
|
|
841
|
-
function firstString(errors) {
|
|
842
|
-
const keys = Object.keys(errors);
|
|
843
|
-
for (const key of keys) {
|
|
844
|
-
if (typeof errors[key] === 'string')
|
|
845
|
-
return errors[key];
|
|
846
|
-
return firstString(errors[key]);
|
|
847
|
-
}
|
|
848
|
-
return '';
|
|
849
|
-
}
|
|
850
|
-
const validatePipe = (opts) => {
|
|
851
|
-
const pipe = async (_value, meta) => {
|
|
852
|
-
const { restoreCtx } = useWooksCtx();
|
|
853
|
-
const valido = getMoostValido();
|
|
854
|
-
const result = await valido.validateParam(_value, meta, undefined, undefined, undefined, undefined, 0, 0, opts?.errorLimit || DEFAULT_ERROR_LIMIT, restoreCtx);
|
|
855
|
-
if (result !== true) {
|
|
856
|
-
throw new WooksError(400, {
|
|
857
|
-
statusCode: 400,
|
|
858
|
-
message: typeof result === 'string' ? result : firstString(result),
|
|
859
|
-
error: 'Validation Error',
|
|
860
|
-
details: result,
|
|
861
|
-
});
|
|
862
|
-
}
|
|
863
|
-
return _value;
|
|
864
|
-
};
|
|
865
|
-
pipe.priority = TPipePriority.VALIDATE;
|
|
866
|
-
return pipe;
|
|
867
|
-
};
|
|
868
|
-
|
|
869
|
-
export { All, Authorization, Body, Circular, Const, Controller, Cookie, CookieHook, Delete, Dto, Get, Header, HeaderHook, HttpMethod, ImportController, Inject, Injectable, Intercept, Ip, IpList, IsArray, IsBoolean, IsNumber, IsString, IsTypeOf, Label, Method, Moost, Optional, Param, Params, Patch, Post, Provide, Put, Query, RawBody, Req, ReqId, Required, Res, Resolve, StatusHook, TInterceptorPriority, TPipePriority, Url, Validate, genericTypesCastPipe, getMoostMate, resolvePipe, useControllerMeta, validatePipe };
|