taon 19.0.55 → 19.0.56

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 (105) hide show
  1. package/README.md +160 -160
  2. package/bin/start.js +279 -279
  3. package/bin/taon +6 -6
  4. package/bin/taon-debug +5 -5
  5. package/bin/taon-debug-brk +5 -5
  6. package/browser/README.md +24 -24
  7. package/browser/fesm2022/taon.mjs +268 -155
  8. package/browser/fesm2022/taon.mjs.map +1 -1
  9. package/browser/lib/config/controller-config.d.ts +22 -0
  10. package/{websql/lib/decorators/classes → browser/lib/config}/controller-options.d.ts +6 -1
  11. package/browser/lib/config/method-config.d.ts +39 -0
  12. package/browser/lib/config/param-config.d.ts +9 -0
  13. package/browser/lib/decorators/classes/controller-decorator.d.ts +1 -1
  14. package/browser/lib/decorators/http/http-methods-decorators.d.ts +14 -1
  15. package/browser/lib/endpoint-context.d.ts +3 -1
  16. package/browser/lib/helpers/class-helpers.d.ts +5 -2
  17. package/browser/lib/helpers/clone-obj.d.ts +2 -0
  18. package/browser/lib/helpers/taon-helpers.d.ts +5 -5
  19. package/browser/lib/models.d.ts +0 -31
  20. package/browser/lib/symbols.d.ts +0 -2
  21. package/browser/lib/validators.d.ts +2 -2
  22. package/browser/package.json +1 -1
  23. package/lib/base-classes/base-class.js +2 -16
  24. package/lib/base-classes/base-class.js.map +1 -1
  25. package/lib/base-classes/base-controller.js +4 -1
  26. package/lib/base-classes/base-controller.js.map +1 -1
  27. package/lib/build-info._auto-generated_.d.ts +1 -1
  28. package/lib/build-info._auto-generated_.js +1 -1
  29. package/lib/config/controller-config.d.ts +21 -0
  30. package/lib/config/controller-config.js +34 -0
  31. package/lib/config/controller-config.js.map +1 -0
  32. package/lib/{decorators/classes → config}/controller-options.d.ts +6 -1
  33. package/lib/config/controller-options.js +8 -0
  34. package/lib/config/controller-options.js.map +1 -0
  35. package/lib/config/method-config.d.ts +38 -0
  36. package/lib/config/method-config.js +12 -0
  37. package/lib/config/method-config.js.map +1 -0
  38. package/lib/config/param-config.d.ts +8 -0
  39. package/lib/config/param-config.js +8 -0
  40. package/lib/config/param-config.js.map +1 -0
  41. package/lib/decorators/classes/controller-decorator.d.ts +1 -1
  42. package/lib/decorators/classes/controller-decorator.js +6 -1
  43. package/lib/decorators/classes/controller-decorator.js.map +1 -1
  44. package/lib/decorators/classes/middleware-decorator.js.map +1 -1
  45. package/lib/decorators/classes/provider-decorator.js.map +1 -1
  46. package/lib/decorators/decorator-abstract-opt.js +0 -1
  47. package/lib/decorators/decorator-abstract-opt.js.map +1 -1
  48. package/lib/decorators/http/http-methods-decorators.d.ts +14 -1
  49. package/lib/decorators/http/http-methods-decorators.js +3 -10
  50. package/lib/decorators/http/http-methods-decorators.js.map +1 -1
  51. package/lib/decorators/http/http-params-decorators.js +10 -16
  52. package/lib/decorators/http/http-params-decorators.js.map +1 -1
  53. package/lib/endpoint-context.d.ts +3 -1
  54. package/lib/endpoint-context.js +241 -143
  55. package/lib/endpoint-context.js.map +1 -1
  56. package/lib/helpers/class-helpers.d.ts +5 -2
  57. package/lib/helpers/class-helpers.js +47 -35
  58. package/lib/helpers/class-helpers.js.map +1 -1
  59. package/lib/helpers/clone-obj.d.ts +1 -0
  60. package/lib/helpers/clone-obj.js +22 -0
  61. package/lib/helpers/clone-obj.js.map +1 -0
  62. package/lib/helpers/taon-helpers.d.ts +5 -5
  63. package/lib/helpers/taon-helpers.js.map +1 -1
  64. package/lib/models.d.ts +0 -31
  65. package/lib/models.js +0 -33
  66. package/lib/models.js.map +1 -1
  67. package/lib/symbols.d.ts +0 -2
  68. package/lib/symbols.js +5 -7
  69. package/lib/symbols.js.map +1 -1
  70. package/lib/ui/index.js +2 -2
  71. package/lib/ui/taon-admin-mode-configuration/index.js +2 -2
  72. package/lib/validators.d.ts +2 -2
  73. package/lib/validators.js.map +1 -1
  74. package/package.json +1 -1
  75. package/scss/vars.scss +6 -6
  76. package/websql/README.md +24 -24
  77. package/websql/fesm2022/taon.mjs +269 -156
  78. package/websql/fesm2022/taon.mjs.map +1 -1
  79. package/websql/lib/config/controller-config.d.ts +22 -0
  80. package/{browser/lib/decorators/classes → websql/lib/config}/controller-options.d.ts +6 -1
  81. package/websql/lib/config/method-config.d.ts +39 -0
  82. package/websql/lib/config/param-config.d.ts +9 -0
  83. package/websql/lib/decorators/classes/controller-decorator.d.ts +1 -1
  84. package/websql/lib/decorators/http/http-methods-decorators.d.ts +14 -1
  85. package/websql/lib/endpoint-context.d.ts +3 -1
  86. package/websql/lib/helpers/class-helpers.d.ts +5 -2
  87. package/websql/lib/helpers/clone-obj.d.ts +2 -0
  88. package/websql/lib/helpers/taon-helpers.d.ts +5 -5
  89. package/websql/lib/models.d.ts +0 -31
  90. package/websql/lib/symbols.d.ts +0 -2
  91. package/websql/lib/validators.d.ts +2 -2
  92. package/websql/package.json +1 -1
  93. package/browser/lib/decorators/classes/controller-config.d.ts +0 -10
  94. package/lib/decorators/classes/controller-config.d.ts +0 -9
  95. package/lib/decorators/classes/controller-config.js +0 -11
  96. package/lib/decorators/classes/controller-config.js.map +0 -1
  97. package/lib/decorators/classes/controller-options.js +0 -16
  98. package/lib/decorators/classes/controller-options.js.map +0 -1
  99. package/lib/env.d.ts +0 -2
  100. package/lib/env.js +0 -7
  101. package/lib/env.js.map +0 -1
  102. package/lib/storage.d.ts +0 -1
  103. package/lib/storage.js +0 -6
  104. package/lib/storage.js.map +0 -1
  105. package/websql/lib/decorators/classes/controller-config.d.ts +0 -10
@@ -2,15 +2,16 @@ import 'reflect-metadata';
2
2
  import * as coreHelpers from 'tnp-core/browser';
3
3
  import { _, Utils, Helpers, UtilsOs, crossPlatformPath } from 'tnp-core/browser';
4
4
  import { __decorate, __metadata, __param } from 'tslib';
5
- import { walk } from 'lodash-walk-object/browser';
6
5
  import { SYMBOL, CLASS } from 'typescript-class-helpers/browser';
7
6
  import { OrignalClassKey, Table } from 'taon-typeorm/browser';
7
+ import { walk } from 'lodash-walk-object/browser';
8
8
  import * as i0 from '@angular/core';
9
9
  import { InjectionToken, inject as inject$1, Injectable } from '@angular/core';
10
10
  import axios from 'axios';
11
11
  import { JSON10 } from 'json10/browser';
12
12
  import { Models as Models$1, Resource, RestHeaders, Mapping } from 'ng2-rest/browser';
13
13
  import { Observable, from, Subject } from 'rxjs';
14
+ import { config } from 'tnp-config/browser';
14
15
  import * as JSON5 from 'json5';
15
16
  import { io } from 'socket.io-client';
16
17
 
@@ -20,12 +21,33 @@ class DecoratorAbstractOpt {
20
21
  class TaonControllerOptions extends DecoratorAbstractOpt {
21
22
  }
22
23
 
24
+ // import { cloneObj } from '../helpers/clone-obj';
25
+ // import { ParamConfig } from './param-config';
23
26
  class ControllerConfig extends TaonControllerOptions {
24
- constructor() {
25
- super(...arguments);
26
- this.methods = {};
27
- }
28
27
  }
28
+ const controllerConfigFrom = (partial) => {
29
+ const newObj = partial || {};
30
+ newObj.methods = newObj.methods || {};
31
+ for (const methodName in newObj.methods) {
32
+ if (newObj.methods.hasOwnProperty(methodName)) {
33
+ // newObj.methods[methodName] = new MethodConfig().clone(
34
+ // newObj.methods[methodName],
35
+ // );
36
+ newObj.methods[methodName] = newObj.methods[methodName] || {};
37
+ const params = newObj.methods[methodName].parameters || {};
38
+ newObj.methods[methodName].parameters = params
39
+ ? params
40
+ : {};
41
+ for (const paramName in params) {
42
+ if (params.hasOwnProperty(paramName)) {
43
+ params[paramName] = params[paramName] || {};
44
+ // params[paramName] = new ParamConfig().clone(params[paramName]);
45
+ }
46
+ }
47
+ }
48
+ }
49
+ return newObj;
50
+ };
29
51
 
30
52
  var Symbols;
31
53
  (function (Symbols) {
@@ -101,9 +123,7 @@ var Symbols;
101
123
  Symbols.metadata = {
102
124
  className: `class:realname`,
103
125
  options: {
104
- runtimeController: `runtime:controller:options`,
105
126
  controller: `controller:options`,
106
- controllerMethod: `controller:method:options`,
107
127
  entity: `entity:options`,
108
128
  repository: `repository:options`,
109
129
  provider: `provider:options`,
@@ -279,7 +299,7 @@ var ClassHelpers;
279
299
  const classFn = _.isFunction(classFnOrObject)
280
300
  ? classFnOrObject
281
301
  : classFnOrObject.constructor;
282
- const config = Reflect.getMetadata(Symbols.metadata.options.controller, classFn);
302
+ const config = Reflect.getMetadata(Symbols.metadata.options.entity, classFn);
283
303
  return config.uniqueKeyProp;
284
304
  };
285
305
  //#endregion
@@ -321,23 +341,6 @@ var ClassHelpers;
321
341
  return ClassHelpers.hasParentClassWithName(targetProto, className, targets);
322
342
  };
323
343
  //#endregion
324
- //#region get all metadata for controller
325
- ClassHelpers.getControllerConfig = (target) => {
326
- const classMetadataOptions = Reflect.getMetadata(Symbols.metadata.options.controller, target);
327
- const classMetadata = _.merge(new ControllerConfig(), classMetadataOptions);
328
- // Iterate over all methods of the class
329
- const methodNames = ClassHelpers.getMethodsNames(target); // Object.getOwnPropertyNames(target.prototype);
330
- // console.log(`methodNames for ${ClassHelpers.getName(target)} `, methodNames)
331
- for (const methodName of methodNames) {
332
- const methodMetadata = Reflect.getMetadata(Symbols.metadata.options.controllerMethod, target, methodName);
333
- // console.log('methodMetadata for ' + methodName, methodMetadata)
334
- if (methodMetadata) {
335
- classMetadata.methods[methodName] = methodMetadata;
336
- }
337
- }
338
- return classMetadata;
339
- };
340
- //#endregion
341
344
  //#region get methods name
342
345
  //#region not allowed as method name
343
346
  const notAllowedAsMethodName = [
@@ -400,37 +403,81 @@ var ClassHelpers;
400
403
  //#region get controller configs
401
404
  ClassHelpers.getControllerConfigs = (target, configs = [], callerTarget) => {
402
405
  if (!_.isFunction(target)) {
403
- throw `[typescript-class-helper][getClassConfig] Cannot get class config from: ${target}`;
406
+ throw `[typescript-class-helper][getControllerConfigs] Cannot get class config from: ${target}`;
404
407
  }
405
408
  let config;
406
409
  const parentClass = Object.getPrototypeOf(target);
407
410
  const parentName = parentClass ? ClassHelpers.getName(parentClass) : void 0;
408
411
  const isValidParent = _.isFunction(parentClass) && parentName !== '';
409
- config = ClassHelpers.getControllerConfig(target);
412
+ config = controllerConfigFrom(ClassHelpers.getClassConfig(target));
410
413
  configs.push(config);
411
414
  return isValidParent
412
415
  ? ClassHelpers.getControllerConfigs(parentClass, configs, target)
413
416
  : configs;
414
417
  };
415
418
  //#endregion
416
- //#region get path for
417
- // export const getCalculatedPathFor = (target: Function) => {
418
- // const configs = getControllerConfigs(target);
419
- // const parentscalculatedPath = _.slice(configs, 1)
420
- // .reverse()
421
- // .map(bc => {
422
- // if (TaonHelpers.isGoodPath(bc.path)) {
423
- // return bc.path;
424
- // }
425
- // return bc.className;
426
- // })
427
- // .join('/');
428
- // return `/${parentscalculatedPath}/${ClassHelpers.getName(target)}`;
429
- // };
419
+ //#region ensure configs
420
+ // Ensure ClassConfig on constructor, clone parent if needed
421
+ ClassHelpers.ensureClassConfig = (target) => {
422
+ let cfg = Reflect.getOwnMetadata(Symbols.metadata.options.controller, // META_KEYS.class,
423
+ target);
424
+ if (!cfg) {
425
+ cfg = { methods: {} };
426
+ const parent = Object.getPrototypeOf(target);
427
+ if (parent && parent !== Function.prototype) {
428
+ const parentCfg = Reflect.getMetadata(Symbols.metadata.options.controller, // META_KEYS.class,
429
+ parent);
430
+ if (parentCfg) {
431
+ // Deep copy each method config so child gets its own objects
432
+ const clonedMethods = {};
433
+ for (const [k, v] of Object.entries(parentCfg.methods)) {
434
+ clonedMethods[k] = {
435
+ ...v,
436
+ parameters: { ...v.parameters }, // shallow clone parameters too
437
+ };
438
+ }
439
+ cfg = {
440
+ ...parentCfg,
441
+ methods: clonedMethods,
442
+ };
443
+ }
444
+ }
445
+ Reflect.defineMetadata(Symbols.metadata.options.controller, cfg, target);
446
+ }
447
+ return cfg;
448
+ };
449
+ // Ensure MethodConfig inside ClassConfig
450
+ ClassHelpers.ensureMethodConfig = (target, propertyKey) => {
451
+ const classCfg = ClassHelpers.ensureClassConfig(target.constructor);
452
+ let methodCfg = classCfg.methods[propertyKey?.toString()];
453
+ if (!methodCfg) {
454
+ methodCfg = { methodName: propertyKey?.toString(), parameters: {} };
455
+ classCfg.methods[propertyKey?.toString()] = methodCfg;
456
+ }
457
+ return methodCfg;
458
+ };
459
+ ClassHelpers.getClassConfig = (constructor) => {
460
+ return Reflect.getMetadata(Symbols.metadata.options.controller, constructor);
461
+ };
430
462
  //#endregion
431
463
  })(ClassHelpers || (ClassHelpers = {}));
432
464
 
433
- //#region imports
465
+ const cloneObj = (override, classFn) => {
466
+ const result = _.merge(new classFn(), _.cloneDeep(this));
467
+ walk.Object(override || {}, (value, lodashPath) => {
468
+ if (_.isNil(value) || _.isFunction(value) || _.isObject(value)) {
469
+ // skipping
470
+ }
471
+ else {
472
+ _.set(result, lodashPath, value);
473
+ }
474
+ }, {
475
+ walkGetters: false,
476
+ });
477
+ // console.log({result})
478
+ return result;
479
+ };
480
+
434
481
  //#endregion
435
482
  class BaseClass {
436
483
  //#region class initialization hook
@@ -443,19 +490,7 @@ class BaseClass {
443
490
  //#region clone
444
491
  clone(override) {
445
492
  const classFn = ClassHelpers.getClassFnFromObject(this);
446
- const result = _.merge(new classFn(), _.cloneDeep(this));
447
- walk.Object(override || {}, (value, lodashPath) => {
448
- if (_.isNil(value) || _.isFunction(value) || _.isObject(value)) {
449
- // skipping
450
- }
451
- else {
452
- _.set(result, lodashPath, value);
453
- }
454
- }, {
455
- walkGetters: false,
456
- });
457
- // console.log({result})
458
- return result;
493
+ return cloneObj(override, classFn);
459
494
  }
460
495
  }
461
496
 
@@ -1344,22 +1379,6 @@ var Models;
1344
1379
  }
1345
1380
  Models.DatabaseConfig = DatabaseConfig;
1346
1381
  //#endregion
1347
- //#region models / param config
1348
- class ParamConfig {
1349
- }
1350
- Models.ParamConfig = ParamConfig;
1351
- //#endregion
1352
- //#region models / method config
1353
- /**
1354
- * @link './decorators/http/http-methods-decorators.ts' TaonHttpDecoratorOptions
1355
- */
1356
- class MethodConfig {
1357
- constructor() {
1358
- this.parameters = {};
1359
- }
1360
- }
1361
- Models.MethodConfig = MethodConfig;
1362
- //#endregion
1363
1382
  //#region models / http
1364
1383
  let Http;
1365
1384
  (function (Http) {
@@ -3124,6 +3143,8 @@ class EndpointContext {
3124
3143
  /* */
3125
3144
  /* */
3126
3145
  /* */
3146
+ /* */
3147
+ /* */
3127
3148
  await this.initCustomClientMiddlewares();
3128
3149
  }
3129
3150
  //#endregion
@@ -3657,15 +3678,12 @@ class EndpointContext {
3657
3678
  return url;
3658
3679
  }
3659
3680
  //#endregion
3660
- get uriPort() {
3661
- if (!this.uri?.origin?.includes('localhost')) {
3662
- return this.config?.hostPortNumber?.toString();
3663
- }
3664
- return this.uri?.port;
3665
- }
3681
+ //#region methods & getters / host uri protocol
3666
3682
  get uriProtocol() {
3667
3683
  return this.uri?.protocol;
3668
3684
  }
3685
+ //#endregion
3686
+ //#region methods & getters / host uri origin
3669
3687
  /**
3670
3688
  * Examples
3671
3689
  * http://localhost:3000
@@ -3674,6 +3692,8 @@ class EndpointContext {
3674
3692
  get uriOrigin() {
3675
3693
  return this.uri?.origin;
3676
3694
  }
3695
+ //#endregion
3696
+ //#region methods & getters / host uri pathname
3677
3697
  /**
3678
3698
  * Exampels
3679
3699
  * http://localhost:3000/path/to/somewhere
@@ -3687,6 +3707,8 @@ class EndpointContext {
3687
3707
  get uriPathname() {
3688
3708
  return this.uri?.pathname;
3689
3709
  }
3710
+ //#endregion
3711
+ //#region methods & getters / uri pathname or nothing if root
3690
3712
  /**
3691
3713
  * Examples
3692
3714
  * http://localhost:3000/path/to/somewhere -> '/path/to/somewhere'
@@ -3697,6 +3719,15 @@ class EndpointContext {
3697
3719
  const isNonRootProperPathName = this.uri?.pathname && this.uri.pathname !== '/';
3698
3720
  return isNonRootProperPathName ? this.uri.pathname.replace(/\/$/, '') : '';
3699
3721
  }
3722
+ //#endregion
3723
+ //#region port from uri
3724
+ get uriPort() {
3725
+ if (!this.uri?.origin?.includes('localhost')) {
3726
+ return this.config?.hostPortNumber?.toString();
3727
+ }
3728
+ return this.uri?.port;
3729
+ }
3730
+ // TODO do i need 2 getters for port?
3700
3731
  /**
3701
3732
  * Port from uri as number
3702
3733
  * @returns {Number | undefined}
@@ -3704,6 +3735,7 @@ class EndpointContext {
3704
3735
  get port() {
3705
3736
  return this.uri?.port ? Number(this.uriPort) : undefined;
3706
3737
  }
3738
+ //#endregion
3707
3739
  //#region methods & getters / is https server
3708
3740
  get isHttpServer() {
3709
3741
  return this.uriProtocol === 'https:';
@@ -3717,15 +3749,21 @@ class EndpointContext {
3717
3749
  return this.config.contextName;
3718
3750
  }
3719
3751
  //#endregion
3752
+ //#region methods & getters / current working directory
3720
3753
  get cwd() {
3721
3754
  return this.config.cwd || process.cwd();
3722
3755
  }
3756
+ //#endregion
3757
+ //#region methods & getters / active context
3723
3758
  get activeContext() {
3724
3759
  return this.config.activeContext || null;
3725
3760
  }
3761
+ //#endregion
3762
+ //#region methods & getters / app id
3726
3763
  get appId() {
3727
3764
  return this.config.appId;
3728
3765
  }
3766
+ //#endregion
3729
3767
  //#region methods & getters / public assets
3730
3768
  get publicAssets() {
3731
3769
  return this.config?.publicAssets || [];
@@ -3944,66 +3982,124 @@ class EndpointContext {
3944
3982
  }
3945
3983
  //#endregion
3946
3984
  //#region methods & getters / initialize metadata
3985
+ //#region methods & getters / update class calculate path
3986
+ updateCalculatedPathsForControllers(rawConfigs, classConfig, controllerClassFn) {
3987
+ const parentsCalculatedPath = _.slice(rawConfigs, 1)
3988
+ .reverse()
3989
+ .map(bc => {
3990
+ if (TaonHelpers.isGoodPath(bc.path)) {
3991
+ return bc.path;
3992
+ }
3993
+ return bc.className;
3994
+ })
3995
+ .join('/');
3996
+ if (TaonHelpers.isGoodPath(classConfig.path)) {
3997
+ classConfig.calculatedPath = classConfig.path;
3998
+ }
3999
+ else {
4000
+ classConfig.calculatedPath = (`${this.uriPathnameOrNothingIfRoot}` +
4001
+ `/${apiPrefix}/${this.contextName}/tcp${parentsCalculatedPath}/` +
4002
+ `${ClassHelpers.getName(controllerClassFn)}`)
4003
+ .replace(/\/\//g, '/')
4004
+ .split('/')
4005
+ .reduce((acc, bc) => {
4006
+ return _.last(acc) === bc ? acc : [...acc, bc];
4007
+ }, [])
4008
+ .join('/');
4009
+ }
4010
+ // console.log('calculatedPath', classConfig.calculatedPath);
4011
+ }
4012
+ //#endregion
4013
+ //#region methods & getters / dedupe class configs
4014
+ mergeControllerMethodsConfigs(rawConfigs, classConfig, controllerClassFn) {
4015
+ const currentControllerMethodsConfig = classConfig.methods;
4016
+ _.slice(rawConfigs, 1).forEach(bc => {
4017
+ const parentControllerMethods = _.cloneDeep(bc.methods);
4018
+ for (const methodsName in parentControllerMethods) {
4019
+ if (parentControllerMethods.hasOwnProperty(methodsName)) {
4020
+ if (!currentControllerMethodsConfig[methodsName]) {
4021
+ //#region add non existed method
4022
+ const methodConfig = parentControllerMethods[methodsName];
4023
+ currentControllerMethodsConfig[methodsName] = methodConfig;
4024
+ //#endregion
4025
+ }
4026
+ }
4027
+ }
4028
+ });
4029
+ }
4030
+ //#endregion
3947
4031
  async initControllers() {
3948
4032
  if (this.isRunOrRevertOnlyMigrationAppStart) {
3949
4033
  return;
3950
4034
  }
3951
4035
  const allControllers = this.getClassFunByArr(Models.ClassType.CONTROLLER);
4036
+ // debugger
3952
4037
  // console.log('allControllers', allControllers);
3953
4038
  for (const controllerClassFn of allControllers) {
4039
+ // console.log(ClassHelpers.getClassConfig(controllerClassFn));
4040
+ // const controllerName = ClassHelpers.getName(controllerClassFn);
4041
+ // console.log(
4042
+ // `for ${controllerName}`,
4043
+ // ClassHelpers.getClassConfig(controllerClassFn),
4044
+ // );
3954
4045
  controllerClassFn[Symbols.classMethodsNames] =
3955
4046
  ClassHelpers.getMethodsNames(controllerClassFn);
3956
- const configs = ClassHelpers.getControllerConfigs(controllerClassFn);
4047
+ const rawConfigs = ClassHelpers.getControllerConfigs(controllerClassFn);
4048
+ // console.log(controllerName, { rawConfigs });
3957
4049
  // console.log(`Class config for ${ClassHelpers.getName(controllerClassFn)}`, configs)
3958
- const classConfig = configs[0];
3959
- //#region update class calculate path
3960
- const parentscalculatedPath = _.slice(configs, 1)
3961
- .reverse()
3962
- .map(bc => {
3963
- if (TaonHelpers.isGoodPath(bc.path)) {
3964
- return bc.path;
3965
- }
3966
- return bc.className;
3967
- })
3968
- .join('/');
3969
- if (TaonHelpers.isGoodPath(classConfig.path)) {
3970
- classConfig.calculatedPath = classConfig.path;
3971
- }
3972
- else {
3973
- classConfig.calculatedPath = (`${this.uriPathnameOrNothingIfRoot}` +
3974
- `/${apiPrefix}/${this.contextName}/tcp${parentscalculatedPath}/` +
3975
- `${ClassHelpers.getName(controllerClassFn)}`)
3976
- .replace(/\/\//g, '/')
3977
- .split('/')
3978
- .reduce((acc, bc) => {
3979
- return _.last(acc) === bc ? acc : [...acc, bc];
3980
- }, [])
3981
- .join('/');
3982
- }
3983
- //#endregion
3984
- // console.log('calculatedPath', classConfig.calculatedPath);
3985
- _.slice(configs, 1).forEach(bc => {
3986
- const alreadyIs = classConfig.methods;
3987
- const toMerge = _.cloneDeep(bc.methods);
3988
- for (const key in toMerge) {
3989
- if (toMerge.hasOwnProperty(key) && !alreadyIs[key]) {
3990
- const element = toMerge[key];
3991
- alreadyIs[key] = element;
3992
- }
4050
+ const classConfig = rawConfigs[0];
4051
+ this.updateCalculatedPathsForControllers(rawConfigs, classConfig, controllerClassFn);
4052
+ this.mergeControllerMethodsConfigs(rawConfigs, classConfig, controllerClassFn);
4053
+ //#region combine middlewares from controllers
4054
+ classConfig.calculatedMiddlewaresControllerObj = {};
4055
+ [...rawConfigs].reverse().forEach(rc => {
4056
+ if (_.isFunction(rc.middlewares)) {
4057
+ classConfig.calculatedMiddlewaresControllerObj = rc.middlewares({
4058
+ parentMiddlewares: classConfig.calculatedMiddlewaresControllerObj,
4059
+ className(middlewareClass) {
4060
+ return ClassHelpers.getName(controllerClassFn);
4061
+ },
4062
+ });
3993
4063
  }
3994
4064
  });
4065
+ //#endregion
4066
+ //#region group start
3995
4067
  /* */
3996
4068
  /* */
3997
4069
  this.logHttp &&
3998
4070
  console.groupCollapsed(`[taon][express-server] routes [${classConfig.className}]`);
3999
4071
  /* */
4000
4072
  /* */
4001
- // console.log('methods', classConfig.methods);
4073
+ //#endregion
4074
+ //#region init client or server methods
4002
4075
  const methodNames = Object.keys(classConfig.methods);
4003
4076
  for (const methodName of methodNames) {
4004
4077
  const methodConfig = classConfig.methods[methodName];
4005
- // debugger
4006
- const type = methodConfig.type;
4078
+ //#region combine all class methods middlewares
4079
+ let calculatedMiddlewaresMethodObj = {};
4080
+ [...rawConfigs].reverse().forEach(rc => {
4081
+ if (rc.methods[methodName]) {
4082
+ const parentMethodConfig = rc.methods[methodName];
4083
+ if (_.isFunction(parentMethodConfig.middlewares)) {
4084
+ calculatedMiddlewaresMethodObj = parentMethodConfig.middlewares({
4085
+ parentMiddlewares: calculatedMiddlewaresMethodObj,
4086
+ className(middlewareClass) {
4087
+ return ClassHelpers.getName(controllerClassFn);
4088
+ },
4089
+ });
4090
+ }
4091
+ }
4092
+ });
4093
+ // add class middlewares to method middlewares
4094
+ methodConfig.calculatedMiddlewaresMethodObj = {
4095
+ ...calculatedMiddlewaresMethodObj,
4096
+ ...classConfig.calculatedMiddlewaresControllerObj,
4097
+ };
4098
+ methodConfig.calculatedMiddlewares = Object.values(methodConfig.calculatedMiddlewaresMethodObj || {});
4099
+ //#endregion
4100
+ // methodConfig.calculatedMiddlewares = TODO
4101
+ //#region initialized method express path
4102
+ const httpMethodType = methodConfig.type;
4007
4103
  // this is quick fix - in docker global path should not be used
4008
4104
  const globalPathPart = this.isRunningInsideDocker ||
4009
4105
  !this.frontendHostUri?.origin?.includes('localhost') // fe with domain -> is in docker
@@ -4012,6 +4108,8 @@ class EndpointContext {
4012
4108
  const expressPath = methodConfig.global
4013
4109
  ? `${globalPathPart}/${methodConfig.path?.replace(/\/$/, '')}`.replace(/\/\//, '/')
4014
4110
  : TaonHelpers.getExpressPath(classConfig, methodConfig);
4111
+ //#endregion
4112
+ //#region init server
4015
4113
  // console.log({ expressPath });
4016
4114
  if (Helpers.isNode || Helpers.isWebSQL) {
4017
4115
  /* */
@@ -4029,6 +4127,8 @@ class EndpointContext {
4029
4127
  /* */
4030
4128
  /* */
4031
4129
  }
4130
+ //#endregion
4131
+ //#region init client
4032
4132
  const shouldInitClient = Helpers.isBrowser || this.remoteHost || Helpers.isWebSQL;
4033
4133
  // console.log('shouldInitClient', shouldInitClient);
4034
4134
  if (shouldInitClient) {
@@ -4039,14 +4139,18 @@ class EndpointContext {
4039
4139
  // methodConfig,
4040
4140
  // expressPath,
4041
4141
  // );
4042
- await this.initClient(controllerClassFn, type, methodConfig, expressPath);
4142
+ await this.initClient(controllerClassFn, httpMethodType, methodConfig, expressPath);
4043
4143
  }
4144
+ //#endregion
4044
4145
  }
4146
+ //#endregion
4147
+ //#region group end
4045
4148
  /* */
4046
4149
  /* */
4047
4150
  this.logHttp && console.groupEnd();
4048
4151
  /* */
4049
4152
  /* */
4153
+ //#endregion
4050
4154
  }
4051
4155
  }
4052
4156
  //#endregion
@@ -4108,15 +4212,15 @@ class EndpointContext {
4108
4212
  const middlewares = this.getClassesInstancesArrBy(Models.ClassType.MIDDLEWARE)
4109
4213
  .map(f => f)
4110
4214
  .filter(f => _.isFunction(f.interceptClient));
4111
- middlewares.forEach(instance => {
4215
+ middlewares.forEach(middlewareInstanceName => {
4112
4216
  const contextName = this.contextName;
4113
- const interceptorName = `${contextName}-${ClassHelpers.getName(instance)}`;
4217
+ const interceptorName = `${contextName}-${ClassHelpers.getName(middlewareInstanceName)}`;
4114
4218
  Resource.request.interceptors.set(interceptorName, {
4115
4219
  intercept: ({ req, next }) => {
4116
4220
  const url = new URL(req.url);
4117
4221
  if (url.pathname.startsWith(`${this.uriPathnameOrNothingIfRoot}/${apiPrefix}/${contextName}/`)) {
4118
4222
  // console.log('intercepting', url.pathname, req);
4119
- return instance.interceptClient({
4223
+ return middlewareInstanceName.interceptClient({
4120
4224
  req,
4121
4225
  next,
4122
4226
  });
@@ -4274,10 +4378,10 @@ class EndpointContext {
4274
4378
  //#region parameters
4275
4379
  httpMethodType, methodConfig, classConfig, expressPath, target) {
4276
4380
  //#region resolve variables
4277
- const middlewareHandlers = (Array.isArray(methodConfig.middlewares) &&
4278
- methodConfig.middlewares?.length > 0
4279
- ? methodConfig.middlewares
4280
- : [])
4381
+ // console.log(
4382
+ // `CLIENT: expressPath: "${expressPath}" interceptor for method: ${methodConfig.calculatedMiddlewares.length}`,
4383
+ // );
4384
+ const middlewareHandlers = methodConfig.calculatedMiddlewares
4281
4385
  .map(middlewareClassFun => {
4282
4386
  const middlewareInstance = this.getInstanceBy(middlewareClassFun);
4283
4387
  if (middlewareInstance &&
@@ -4565,7 +4669,6 @@ class EndpointContext {
4565
4669
  /* */
4566
4670
  /* */
4567
4671
  /* */
4568
- /* */
4569
4672
  }
4570
4673
  return {
4571
4674
  expressPath: expressPath,
@@ -4577,17 +4680,22 @@ class EndpointContext {
4577
4680
  /**
4578
4681
  * client can be browser or nodejs (when remote host)
4579
4682
  */
4580
- async initClient(
4581
- //#region parameters
4582
- target, httpRequestType, methodConfig, // Models.Http.Rest.MethodConfig,
4683
+ async initClient(target, httpRequestType, methodConfig, // Models.Http.Rest.MethodConfig,
4583
4684
  expressPath) {
4584
4685
  const ctx = this;
4686
+ // console.log(
4687
+ // `CLIENT: expressPath: "${expressPath}" interceptor for method: ${methodConfig.calculatedMiddlewares?.length} `,
4688
+ // );
4585
4689
  //#region init middlewares
4586
- const middlewares = methodConfig.middlewares
4690
+ const middlewares = methodConfig.calculatedMiddlewares;
4691
+ const middlewaresInstances = middlewares
4587
4692
  .map(f => this.getInstanceBy(f))
4588
4693
  .filter(f => _.isFunction(f.interceptClientMethod));
4589
- middlewares.forEach(instance => {
4590
- Resource.request.methodsInterceptors.set(`${methodConfig.type?.toUpperCase()}-${expressPath}`, {
4694
+ middlewaresInstances.forEach(instance => {
4695
+ const middlewareName = ClassHelpers.getName(instance);
4696
+ // middlewareName - only needed for inheritace and uniqness of interceptors
4697
+ const interceptorKey = `${middlewareName}-${methodConfig.type?.toUpperCase()}-${expressPath}`;
4698
+ Resource.request.methodsInterceptors.set(interceptorKey, {
4591
4699
  intercept: ({ req, next }) => {
4592
4700
  return instance.interceptClientMethod({
4593
4701
  req,
@@ -4857,6 +4965,14 @@ class EndpointContext {
4857
4965
  break;
4858
4966
  }
4859
4967
  }
4968
+ if (!currentParam) {
4969
+ const errorMessage = `[${config.frameworkName}] Unable to resolve parameter` +
4970
+ ` at index ${i} for method ${methodConfig.methodName} at path ${expressPath}.`;
4971
+ /* */
4972
+ /* */
4973
+ /* */
4974
+ throw new Error(errorMessage);
4975
+ }
4860
4976
  if (currentParam.paramType === 'Path') {
4861
4977
  pathPrams[currentParam.paramName] = param;
4862
4978
  }
@@ -6146,12 +6262,18 @@ var baseContext = /*#__PURE__*/Object.freeze({
6146
6262
  function TaonController(options) {
6147
6263
  return function (constructor) {
6148
6264
  ClassHelpers.setName(constructor, options?.className);
6149
- Reflect.defineMetadata(Symbols.metadata.options.controller, options, constructor);
6150
6265
  Reflect.defineMetadata(Symbols.metadata.className, options?.className || constructor.name, constructor);
6266
+ const cfg = ClassHelpers.ensureClassConfig(constructor);
6267
+ options = options || {};
6268
+ cfg.className = options.className || constructor.name;
6269
+ cfg.path = options.path || '';
6270
+ cfg.realtime = options.realtime;
6271
+ cfg.middlewares = options.middlewares;
6151
6272
  };
6152
6273
  }
6153
6274
 
6154
6275
  const metaReq = (method, path, target, propertyKey, descriptor, pathOrOptions, pathIsGlobal) => {
6276
+ const methodConfig = ClassHelpers.ensureMethodConfig(target, propertyKey);
6155
6277
  let options;
6156
6278
  if (typeof pathOrOptions === 'object') {
6157
6279
  options = pathOrOptions;
@@ -6163,13 +6285,8 @@ const metaReq = (method, path, target, propertyKey, descriptor, pathOrOptions, p
6163
6285
  options = { pathOrOptions, pathIsGlobal };
6164
6286
  }
6165
6287
  const { overrideContentType, overrideResponseType, middlewares } = options;
6166
- let methodConfig = Reflect.getMetadata(Symbols.metadata.options.controllerMethod, target.constructor, propertyKey);
6167
- if (!methodConfig) {
6168
- methodConfig = new Models.MethodConfig();
6169
- Reflect.defineMetadata(Symbols.metadata.options.controllerMethod, methodConfig, target.constructor, propertyKey);
6170
- }
6171
6288
  methodConfig.methodName = propertyKey;
6172
- methodConfig.middlewares = middlewares || [];
6289
+ methodConfig.middlewares = middlewares;
6173
6290
  methodConfig.type = method;
6174
6291
  if (!path) {
6175
6292
  let paramsPathConcatedPath = '';
@@ -6192,8 +6309,6 @@ const metaReq = (method, path, target, propertyKey, descriptor, pathOrOptions, p
6192
6309
  methodConfig.global = pathIsGlobal;
6193
6310
  methodConfig.contentType = overrideContentType;
6194
6311
  methodConfig.responseType = overrideResponseType;
6195
- Reflect.defineMetadata(Symbols.metadata.options.controllerMethod, methodConfig, target.constructor, propertyKey);
6196
- // console.log('methods updated', methodConfig);
6197
6312
  };
6198
6313
  function GET(pathOrOptions, pathIsGlobal = false) {
6199
6314
  return function (target, propertyKey, descriptor) {
@@ -6227,21 +6342,16 @@ function DELETE(pathOrOptions, pathIsGlobal = false) {
6227
6342
  }
6228
6343
 
6229
6344
  function metaParam(param, name, expire, defaultValue = undefined, target, propertyKey, parameterIndex) {
6230
- let methodConfig = Reflect.getMetadata(Symbols.metadata.options.controllerMethod, target.constructor, propertyKey);
6231
- if (!methodConfig) {
6232
- methodConfig = new Models.MethodConfig();
6233
- Reflect.defineMetadata(Symbols.metadata.options.controllerMethod, methodConfig, target.constructor, propertyKey);
6234
- }
6345
+ const methodCfg = ClassHelpers.ensureMethodConfig(target, propertyKey);
6235
6346
  const nameKey = name ? name : param;
6236
- const p = (methodConfig.parameters[nameKey] = !methodConfig.parameters[nameKey]
6237
- ? new Models.ParamConfig()
6238
- : methodConfig.parameters[nameKey]);
6239
- p.index = parameterIndex;
6240
- p.paramName = name;
6241
- p.paramType = param;
6242
- p.defaultType = defaultValue;
6243
- p.expireInSeconds = expire;
6244
- Reflect.defineMetadata(Symbols.metadata.options.controllerMethod, methodConfig, target.constructor, propertyKey);
6347
+ // const key = name || `${param}_${parameterIndex}`;
6348
+ methodCfg.parameters[nameKey] = {
6349
+ index: parameterIndex,
6350
+ paramName: name,
6351
+ paramType: param,
6352
+ defaultType: defaultValue,
6353
+ expireInSeconds: expire,
6354
+ };
6245
6355
  // console.log('params updated', methodConfig);
6246
6356
  }
6247
6357
  function Path(name) {
@@ -6319,7 +6429,10 @@ let BaseController = class BaseController extends BaseInjector {
6319
6429
  __decorate([
6320
6430
  POST({
6321
6431
  overrideContentType: 'multipart/form-data',
6322
- middlewares: [BaseFileUploadMiddleware],
6432
+ middlewares: ({ parentMiddlewares }) => ({
6433
+ ...parentMiddlewares,
6434
+ BaseFileUploadMiddleware,
6435
+ }),
6323
6436
  }),
6324
6437
  __param(0, Body()),
6325
6438
  __metadata("design:type", Function),