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