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.
Files changed (129) hide show
  1. package/README.md +14 -8
  2. package/dist/index.cjs +2093 -0
  3. package/dist/{moost.d.ts → index.d.ts} +43 -156
  4. package/dist/index.mjs +2063 -0
  5. package/package.json +13 -69
  6. package/LICENSE +0 -21
  7. package/dist/moost.cjs.prod.js +0 -922
  8. package/dist/moost.esm-bundler.js +0 -869
  9. package/dist/src/binding/bind-controller.d.ts +0 -13
  10. package/dist/src/binding/bind-controller.d.ts.map +0 -1
  11. package/dist/src/binding/bind-handler.d.ts +0 -18
  12. package/dist/src/binding/bind-handler.d.ts.map +0 -1
  13. package/dist/src/binding/index.d.ts +0 -3
  14. package/dist/src/binding/index.d.ts.map +0 -1
  15. package/dist/src/binding/tests/binding.spec.d.ts +0 -2
  16. package/dist/src/binding/tests/binding.spec.d.ts.map +0 -1
  17. package/dist/src/binding/utils.d.ts +0 -3
  18. package/dist/src/binding/utils.d.ts.map +0 -1
  19. package/dist/src/class-function/class-function.d.ts +0 -4
  20. package/dist/src/class-function/class-function.d.ts.map +0 -1
  21. package/dist/src/class-function/index.d.ts +0 -2
  22. package/dist/src/class-function/index.d.ts.map +0 -1
  23. package/dist/src/class-function/types.d.ts +0 -9
  24. package/dist/src/class-function/types.d.ts.map +0 -1
  25. package/dist/src/composables/controller-meta.d.ts +0 -13
  26. package/dist/src/composables/controller-meta.d.ts.map +0 -1
  27. package/dist/src/composables/index.d.ts +0 -2
  28. package/dist/src/composables/index.d.ts.map +0 -1
  29. package/dist/src/decorators/circular.decorator.d.ts +0 -3
  30. package/dist/src/decorators/circular.decorator.d.ts.map +0 -1
  31. package/dist/src/decorators/common.decorator.d.ts +0 -4
  32. package/dist/src/decorators/common.decorator.d.ts.map +0 -1
  33. package/dist/src/decorators/controller.decorator.d.ts +0 -24
  34. package/dist/src/decorators/controller.decorator.d.ts.map +0 -1
  35. package/dist/src/decorators/http-method.decorator.d.ts +0 -8
  36. package/dist/src/decorators/http-method.decorator.d.ts.map +0 -1
  37. package/dist/src/decorators/index.d.ts +0 -10
  38. package/dist/src/decorators/index.d.ts.map +0 -1
  39. package/dist/src/decorators/injectable.decorator.d.ts +0 -12
  40. package/dist/src/decorators/injectable.decorator.d.ts.map +0 -1
  41. package/dist/src/decorators/intercept.decorator.d.ts +0 -20
  42. package/dist/src/decorators/intercept.decorator.d.ts.map +0 -1
  43. package/dist/src/decorators/pipe.decorator.d.ts +0 -3
  44. package/dist/src/decorators/pipe.decorator.d.ts.map +0 -1
  45. package/dist/src/decorators/provide.decorator.d.ts +0 -5
  46. package/dist/src/decorators/provide.decorator.d.ts.map +0 -1
  47. package/dist/src/decorators/resolve.decorator.d.ts +0 -137
  48. package/dist/src/decorators/resolve.decorator.d.ts.map +0 -1
  49. package/dist/src/decorators/tests/circular.artifacts.d.ts +0 -7
  50. package/dist/src/decorators/tests/circular.artifacts.d.ts.map +0 -1
  51. package/dist/src/decorators/tests/circular.spec.d.ts +0 -2
  52. package/dist/src/decorators/tests/circular.spec.d.ts.map +0 -1
  53. package/dist/src/decorators/tests/common.artifacts.d.ts +0 -4
  54. package/dist/src/decorators/tests/common.artifacts.d.ts.map +0 -1
  55. package/dist/src/decorators/tests/common.spec.d.ts +0 -2
  56. package/dist/src/decorators/tests/common.spec.d.ts.map +0 -1
  57. package/dist/src/decorators/tests/controller.spec.d.ts +0 -2
  58. package/dist/src/decorators/tests/controller.spec.d.ts.map +0 -1
  59. package/dist/src/decorators/tests/http-method.artifacts.d.ts +0 -12
  60. package/dist/src/decorators/tests/http-method.artifacts.d.ts.map +0 -1
  61. package/dist/src/decorators/tests/http-method.spec.d.ts +0 -2
  62. package/dist/src/decorators/tests/http-method.spec.d.ts.map +0 -1
  63. package/dist/src/decorators/tests/injectable.spec.d.ts +0 -2
  64. package/dist/src/decorators/tests/injectable.spec.d.ts.map +0 -1
  65. package/dist/src/decorators/tests/intercept.spec.d.ts +0 -2
  66. package/dist/src/decorators/tests/intercept.spec.d.ts.map +0 -1
  67. package/dist/src/decorators/tests/pipe.artifacts.d.ts +0 -4
  68. package/dist/src/decorators/tests/pipe.artifacts.d.ts.map +0 -1
  69. package/dist/src/decorators/tests/pipe.spec.d.ts +0 -2
  70. package/dist/src/decorators/tests/pipe.spec.d.ts.map +0 -1
  71. package/dist/src/decorators/tests/provide.artifacts.d.ts +0 -9
  72. package/dist/src/decorators/tests/provide.artifacts.d.ts.map +0 -1
  73. package/dist/src/decorators/tests/provide.spec.d.ts +0 -2
  74. package/dist/src/decorators/tests/provide.spec.d.ts.map +0 -1
  75. package/dist/src/decorators/tests/resolve.artifacts.d.ts +0 -4
  76. package/dist/src/decorators/tests/resolve.artifacts.d.ts.map +0 -1
  77. package/dist/src/decorators/tests/resolve.spec.d.ts +0 -2
  78. package/dist/src/decorators/tests/resolve.spec.d.ts.map +0 -1
  79. package/dist/src/decorators/tests/validate.artifacts.d.ts +0 -21
  80. package/dist/src/decorators/tests/validate.artifacts.d.ts.map +0 -1
  81. package/dist/src/decorators/tests/validate.spec.d.ts +0 -2
  82. package/dist/src/decorators/tests/validate.spec.d.ts.map +0 -1
  83. package/dist/src/decorators/validate.decorator.d.ts +0 -10
  84. package/dist/src/decorators/validate.decorator.d.ts.map +0 -1
  85. package/dist/src/index.d.ts +0 -7
  86. package/dist/src/index.d.ts.map +0 -1
  87. package/dist/src/metadata/index.d.ts +0 -2
  88. package/dist/src/metadata/index.d.ts.map +0 -1
  89. package/dist/src/metadata/infact.d.ts +0 -7
  90. package/dist/src/metadata/infact.d.ts.map +0 -1
  91. package/dist/src/metadata/moost-metadata.d.ts +0 -62
  92. package/dist/src/metadata/moost-metadata.d.ts.map +0 -1
  93. package/dist/src/metadata/valido.d.ts +0 -3
  94. package/dist/src/metadata/valido.d.ts.map +0 -1
  95. package/dist/src/moost.d.ts +0 -44
  96. package/dist/src/moost.d.ts.map +0 -1
  97. package/dist/src/moost.spec.d.ts +0 -2
  98. package/dist/src/moost.spec.d.ts.map +0 -1
  99. package/dist/src/pipes/generic-types-cast.pipe.d.ts +0 -3
  100. package/dist/src/pipes/generic-types-cast.pipe.d.ts.map +0 -1
  101. package/dist/src/pipes/index.d.ts +0 -5
  102. package/dist/src/pipes/index.d.ts.map +0 -1
  103. package/dist/src/pipes/resolve.pipe.d.ts +0 -3
  104. package/dist/src/pipes/resolve.pipe.d.ts.map +0 -1
  105. package/dist/src/pipes/run-pipes.d.ts +0 -5
  106. package/dist/src/pipes/run-pipes.d.ts.map +0 -1
  107. package/dist/src/pipes/shared-pipes.d.ts +0 -3
  108. package/dist/src/pipes/shared-pipes.d.ts.map +0 -1
  109. package/dist/src/pipes/types.d.ts +0 -21
  110. package/dist/src/pipes/types.d.ts.map +0 -1
  111. package/dist/src/pipes/validate.pipe.d.ts +0 -7
  112. package/dist/src/pipes/validate.pipe.d.ts.map +0 -1
  113. package/dist/src/pipes/validation.spec.d.ts +0 -2
  114. package/dist/src/pipes/validation.spec.d.ts.map +0 -1
  115. package/dist/src/tests/e2e.artifacts.d.ts +0 -17
  116. package/dist/src/tests/e2e.artifacts.d.ts.map +0 -1
  117. package/dist/src/tests/e2e.spec.d.ts +0 -2
  118. package/dist/src/tests/e2e.spec.d.ts.map +0 -1
  119. package/dist/src/tests/request.artifacts.d.ts +0 -10
  120. package/dist/src/tests/request.artifacts.d.ts.map +0 -1
  121. package/dist/src/types.d.ts +0 -8
  122. package/dist/src/types.d.ts.map +0 -1
  123. package/dist/src/utils/banner.d.ts +0 -2
  124. package/dist/src/utils/banner.d.ts.map +0 -1
  125. package/dist/src/utils/log.d.ts +0 -5
  126. package/dist/src/utils/log.d.ts.map +0 -1
  127. package/dist/src/utils/panic.d.ts +0 -2
  128. package/dist/src/utils/panic.d.ts.map +0 -1
  129. 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('' + '' + banner() + text + '');
196
- }
197
- function logBright(text) {
198
- console.log('' + banner() + text + '');
199
- }
200
- function logError(error) {
201
- console.error('' + '' + banner() + error + '');
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}${''} ${targetPath} ${''}→ ${classConstructor.name}.${''}${method}${''}()`);
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 };