taon 19.0.55 → 19.0.58

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 (140) 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 +299 -201
  8. package/browser/fesm2022/taon.mjs.map +1 -1
  9. package/browser/lib/base-classes/base-angular-service.d.ts +16 -0
  10. package/browser/lib/base-classes/base-context.d.ts +0 -9
  11. package/browser/lib/base-classes/base-controller.d.ts +1 -1
  12. package/browser/lib/base-classes/base-file-upload.middleware.d.ts +2 -2
  13. package/browser/lib/base-classes/base-middleware.d.ts +3 -3
  14. package/browser/lib/base-classes/base.d.ts +0 -9
  15. package/browser/lib/config/controller-config.d.ts +22 -0
  16. package/browser/lib/{decorators/classes → config}/controller-options.d.ts +6 -1
  17. package/browser/lib/config/method-config.d.ts +39 -0
  18. package/browser/lib/config/param-config.d.ts +9 -0
  19. package/browser/lib/constants.d.ts +2 -1
  20. package/browser/lib/create-context.d.ts +2 -20
  21. package/browser/lib/decorators/classes/controller-decorator.d.ts +1 -1
  22. package/browser/lib/decorators/http/http-methods-decorators.d.ts +14 -1
  23. package/browser/lib/endpoint-context.d.ts +3 -1
  24. package/browser/lib/helpers/class-helpers.d.ts +5 -2
  25. package/browser/lib/helpers/clone-obj.d.ts +2 -0
  26. package/browser/lib/helpers/taon-helpers.d.ts +5 -5
  27. package/browser/lib/index.d.ts +1 -28
  28. package/browser/lib/models.d.ts +0 -31
  29. package/browser/lib/symbols.d.ts +0 -2
  30. package/browser/lib/validators.d.ts +2 -2
  31. package/browser/package.json +1 -1
  32. package/lib/base-classes/base-angular-service.d.ts +16 -0
  33. package/lib/base-classes/base-angular-service.js +32 -0
  34. package/lib/base-classes/base-angular-service.js.map +1 -1
  35. package/lib/base-classes/base-class.js +2 -16
  36. package/lib/base-classes/base-class.js.map +1 -1
  37. package/lib/base-classes/base-context.d.ts +0 -9
  38. package/lib/base-classes/base-controller.d.ts +1 -1
  39. package/lib/base-classes/base-controller.js +4 -1
  40. package/lib/base-classes/base-controller.js.map +1 -1
  41. package/lib/base-classes/base-file-upload.middleware.d.ts +2 -2
  42. package/lib/base-classes/base-file-upload.middleware.js.map +1 -1
  43. package/lib/base-classes/base-middleware.d.ts +3 -3
  44. package/lib/base-classes/base.d.ts +0 -9
  45. package/lib/build-info._auto-generated_.d.ts +1 -1
  46. package/lib/build-info._auto-generated_.js +1 -1
  47. package/lib/config/controller-config.d.ts +21 -0
  48. package/lib/config/controller-config.js +34 -0
  49. package/lib/config/controller-config.js.map +1 -0
  50. package/lib/config/controller-options.d.ts +16 -0
  51. package/lib/config/controller-options.js +8 -0
  52. package/lib/config/controller-options.js.map +1 -0
  53. package/lib/config/method-config.d.ts +38 -0
  54. package/lib/config/method-config.js +12 -0
  55. package/lib/config/method-config.js.map +1 -0
  56. package/lib/config/param-config.d.ts +8 -0
  57. package/lib/config/param-config.js +8 -0
  58. package/lib/config/param-config.js.map +1 -0
  59. package/lib/constants.d.ts +2 -1
  60. package/lib/constants.js +6 -1
  61. package/lib/constants.js.map +1 -1
  62. package/lib/create-context.d.ts +2 -20
  63. package/lib/create-context.js +1 -44
  64. package/lib/create-context.js.map +1 -1
  65. package/lib/decorators/classes/controller-config.d.ts +11 -0
  66. package/lib/decorators/classes/controller-config.js +10 -0
  67. package/lib/decorators/classes/controller-config.js.map +1 -1
  68. package/lib/decorators/classes/controller-decorator.d.ts +1 -1
  69. package/lib/decorators/classes/controller-decorator.js +6 -1
  70. package/lib/decorators/classes/controller-decorator.js.map +1 -1
  71. package/lib/decorators/classes/controller-options.d.ts +5 -0
  72. package/lib/decorators/classes/controller-options.js +4 -0
  73. package/lib/decorators/classes/controller-options.js.map +1 -1
  74. package/lib/decorators/classes/middleware-decorator.js.map +1 -1
  75. package/lib/decorators/classes/provider-decorator.js.map +1 -1
  76. package/lib/decorators/decorator-abstract-opt.js +0 -1
  77. package/lib/decorators/decorator-abstract-opt.js.map +1 -1
  78. package/lib/decorators/http/http-methods-decorators.d.ts +14 -1
  79. package/lib/decorators/http/http-methods-decorators.js +3 -10
  80. package/lib/decorators/http/http-methods-decorators.js.map +1 -1
  81. package/lib/decorators/http/http-params-decorators.js +10 -16
  82. package/lib/decorators/http/http-params-decorators.js.map +1 -1
  83. package/lib/endpoint-context.d.ts +3 -1
  84. package/lib/endpoint-context.js +241 -143
  85. package/lib/endpoint-context.js.map +1 -1
  86. package/lib/helpers/class-helpers.d.ts +5 -2
  87. package/lib/helpers/class-helpers.js +47 -35
  88. package/lib/helpers/class-helpers.js.map +1 -1
  89. package/lib/helpers/clone-obj.d.ts +1 -0
  90. package/lib/helpers/clone-obj.js +22 -0
  91. package/lib/helpers/clone-obj.js.map +1 -0
  92. package/lib/helpers/taon-helpers.d.ts +5 -5
  93. package/lib/helpers/taon-helpers.js.map +1 -1
  94. package/lib/index.d.ts +1 -28
  95. package/lib/models.d.ts +0 -31
  96. package/lib/models.js +0 -33
  97. package/lib/models.js.map +1 -1
  98. package/lib/symbols.d.ts +0 -2
  99. package/lib/symbols.js +5 -7
  100. package/lib/symbols.js.map +1 -1
  101. package/lib/ui/index.js +2 -2
  102. package/lib/ui/taon-admin-mode-configuration/index.js +2 -2
  103. package/lib/validators.d.ts +2 -2
  104. package/lib/validators.js.map +1 -1
  105. package/package.json +1 -1
  106. package/scss/vars.scss +6 -6
  107. package/websql/README.md +24 -24
  108. package/websql/fesm2022/taon.mjs +300 -202
  109. package/websql/fesm2022/taon.mjs.map +1 -1
  110. package/websql/lib/base-classes/base-angular-service.d.ts +16 -0
  111. package/websql/lib/base-classes/base-context.d.ts +0 -9
  112. package/websql/lib/base-classes/base-controller.d.ts +1 -1
  113. package/websql/lib/base-classes/base-file-upload.middleware.d.ts +2 -2
  114. package/websql/lib/base-classes/base-middleware.d.ts +3 -3
  115. package/websql/lib/base-classes/base.d.ts +0 -9
  116. package/websql/lib/config/controller-config.d.ts +22 -0
  117. package/websql/lib/{decorators/classes → config}/controller-options.d.ts +6 -1
  118. package/websql/lib/config/method-config.d.ts +39 -0
  119. package/websql/lib/config/param-config.d.ts +9 -0
  120. package/websql/lib/constants.d.ts +2 -1
  121. package/websql/lib/create-context.d.ts +2 -20
  122. package/websql/lib/decorators/classes/controller-decorator.d.ts +1 -1
  123. package/websql/lib/decorators/http/http-methods-decorators.d.ts +14 -1
  124. package/websql/lib/endpoint-context.d.ts +3 -1
  125. package/websql/lib/helpers/class-helpers.d.ts +5 -2
  126. package/websql/lib/helpers/clone-obj.d.ts +2 -0
  127. package/websql/lib/helpers/taon-helpers.d.ts +5 -5
  128. package/websql/lib/index.d.ts +1 -28
  129. package/websql/lib/models.d.ts +0 -31
  130. package/websql/lib/symbols.d.ts +0 -2
  131. package/websql/lib/validators.d.ts +2 -2
  132. package/websql/package.json +1 -1
  133. package/browser/lib/decorators/classes/controller-config.d.ts +0 -10
  134. package/lib/env.d.ts +0 -2
  135. package/lib/env.js +0 -7
  136. package/lib/env.js.map +0 -1
  137. package/lib/storage.d.ts +0 -1
  138. package/lib/storage.js +0 -6
  139. package/lib/storage.js.map +0 -1
  140. 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
 
@@ -521,6 +556,10 @@ TAON_CONTEXT = new InjectionToken('TAON_CONTEXT');
521
556
  let CURRENT_HOST_BACKEND_PORT;
522
557
  //#region @browser
523
558
  CURRENT_HOST_BACKEND_PORT = new InjectionToken('CURRENT_HOST_BACKEND_PORT');
559
+ //#endregion
560
+ let CURRENT_HOST_URL;
561
+ //#region @browser
562
+ CURRENT_HOST_URL = new InjectionToken('CURRENT_HOST_URL');
524
563
  const apiPrefix = 'api';
525
564
 
526
565
  const inject = (entity) => {
@@ -623,6 +662,28 @@ class BaseAngularsService {
623
662
  constructor() {
624
663
  //#region @browser
625
664
  this.currentContext = inject$1(TAON_CONTEXT);
665
+ //#region @browser
666
+ this.CURRENT_HOST_BACKEND_PORT = inject$1(CURRENT_HOST_BACKEND_PORT, {
667
+ optional: true,
668
+ });
669
+ this.CURRENT_HOST_URL = inject$1(CURRENT_HOST_URL, {
670
+ optional: true,
671
+ });
672
+ // #endregion
673
+ }
674
+ /**
675
+ * @deprecated
676
+ * Returns the host URL for the backend service
677
+ * that is running on localhost (normal NodeJS/ExpressJS mode).
678
+ */
679
+ get host() {
680
+ //#region @browser
681
+ if (this.CURRENT_HOST_URL) {
682
+ return this.CURRENT_HOST_URL;
683
+ }
684
+ return `http://localhost:${this.CURRENT_HOST_BACKEND_PORT}`;
685
+ //#endregion
686
+ return void 0;
626
687
  }
627
688
  injectController(ctor,
628
689
  /**
@@ -632,7 +693,9 @@ class BaseAngularsService {
632
693
  return inject(() => {
633
694
  let currentContext;
634
695
  //#region @browser
635
- currentContext = overrideCurrentContext ? overrideCurrentContext : this.currentContext;
696
+ currentContext = overrideCurrentContext
697
+ ? overrideCurrentContext
698
+ : this.currentContext;
636
699
  //#endregion
637
700
  if (!currentContext) {
638
701
  throw new Error('No context available. Make sure to initialize the context before injecting controllers.');
@@ -1344,22 +1407,6 @@ var Models;
1344
1407
  }
1345
1408
  Models.DatabaseConfig = DatabaseConfig;
1346
1409
  //#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
1410
  //#region models / http
1364
1411
  let Http;
1365
1412
  (function (Http) {
@@ -3124,6 +3171,8 @@ class EndpointContext {
3124
3171
  /* */
3125
3172
  /* */
3126
3173
  /* */
3174
+ /* */
3175
+ /* */
3127
3176
  await this.initCustomClientMiddlewares();
3128
3177
  }
3129
3178
  //#endregion
@@ -3657,15 +3706,12 @@ class EndpointContext {
3657
3706
  return url;
3658
3707
  }
3659
3708
  //#endregion
3660
- get uriPort() {
3661
- if (!this.uri?.origin?.includes('localhost')) {
3662
- return this.config?.hostPortNumber?.toString();
3663
- }
3664
- return this.uri?.port;
3665
- }
3709
+ //#region methods & getters / host uri protocol
3666
3710
  get uriProtocol() {
3667
3711
  return this.uri?.protocol;
3668
3712
  }
3713
+ //#endregion
3714
+ //#region methods & getters / host uri origin
3669
3715
  /**
3670
3716
  * Examples
3671
3717
  * http://localhost:3000
@@ -3674,6 +3720,8 @@ class EndpointContext {
3674
3720
  get uriOrigin() {
3675
3721
  return this.uri?.origin;
3676
3722
  }
3723
+ //#endregion
3724
+ //#region methods & getters / host uri pathname
3677
3725
  /**
3678
3726
  * Exampels
3679
3727
  * http://localhost:3000/path/to/somewhere
@@ -3687,6 +3735,8 @@ class EndpointContext {
3687
3735
  get uriPathname() {
3688
3736
  return this.uri?.pathname;
3689
3737
  }
3738
+ //#endregion
3739
+ //#region methods & getters / uri pathname or nothing if root
3690
3740
  /**
3691
3741
  * Examples
3692
3742
  * http://localhost:3000/path/to/somewhere -> '/path/to/somewhere'
@@ -3697,6 +3747,15 @@ class EndpointContext {
3697
3747
  const isNonRootProperPathName = this.uri?.pathname && this.uri.pathname !== '/';
3698
3748
  return isNonRootProperPathName ? this.uri.pathname.replace(/\/$/, '') : '';
3699
3749
  }
3750
+ //#endregion
3751
+ //#region port from uri
3752
+ get uriPort() {
3753
+ if (!this.uri?.origin?.includes('localhost')) {
3754
+ return this.config?.hostPortNumber?.toString();
3755
+ }
3756
+ return this.uri?.port;
3757
+ }
3758
+ // TODO do i need 2 getters for port?
3700
3759
  /**
3701
3760
  * Port from uri as number
3702
3761
  * @returns {Number | undefined}
@@ -3704,6 +3763,7 @@ class EndpointContext {
3704
3763
  get port() {
3705
3764
  return this.uri?.port ? Number(this.uriPort) : undefined;
3706
3765
  }
3766
+ //#endregion
3707
3767
  //#region methods & getters / is https server
3708
3768
  get isHttpServer() {
3709
3769
  return this.uriProtocol === 'https:';
@@ -3717,15 +3777,21 @@ class EndpointContext {
3717
3777
  return this.config.contextName;
3718
3778
  }
3719
3779
  //#endregion
3780
+ //#region methods & getters / current working directory
3720
3781
  get cwd() {
3721
3782
  return this.config.cwd || process.cwd();
3722
3783
  }
3784
+ //#endregion
3785
+ //#region methods & getters / active context
3723
3786
  get activeContext() {
3724
3787
  return this.config.activeContext || null;
3725
3788
  }
3789
+ //#endregion
3790
+ //#region methods & getters / app id
3726
3791
  get appId() {
3727
3792
  return this.config.appId;
3728
3793
  }
3794
+ //#endregion
3729
3795
  //#region methods & getters / public assets
3730
3796
  get publicAssets() {
3731
3797
  return this.config?.publicAssets || [];
@@ -3944,66 +4010,124 @@ class EndpointContext {
3944
4010
  }
3945
4011
  //#endregion
3946
4012
  //#region methods & getters / initialize metadata
4013
+ //#region methods & getters / update class calculate path
4014
+ updateCalculatedPathsForControllers(rawConfigs, classConfig, controllerClassFn) {
4015
+ const parentsCalculatedPath = _.slice(rawConfigs, 1)
4016
+ .reverse()
4017
+ .map(bc => {
4018
+ if (TaonHelpers.isGoodPath(bc.path)) {
4019
+ return bc.path;
4020
+ }
4021
+ return bc.className;
4022
+ })
4023
+ .join('/');
4024
+ if (TaonHelpers.isGoodPath(classConfig.path)) {
4025
+ classConfig.calculatedPath = classConfig.path;
4026
+ }
4027
+ else {
4028
+ classConfig.calculatedPath = (`${this.uriPathnameOrNothingIfRoot}` +
4029
+ `/${apiPrefix}/${this.contextName}/tcp${parentsCalculatedPath}/` +
4030
+ `${ClassHelpers.getName(controllerClassFn)}`)
4031
+ .replace(/\/\//g, '/')
4032
+ .split('/')
4033
+ .reduce((acc, bc) => {
4034
+ return _.last(acc) === bc ? acc : [...acc, bc];
4035
+ }, [])
4036
+ .join('/');
4037
+ }
4038
+ // console.log('calculatedPath', classConfig.calculatedPath);
4039
+ }
4040
+ //#endregion
4041
+ //#region methods & getters / dedupe class configs
4042
+ mergeControllerMethodsConfigs(rawConfigs, classConfig, controllerClassFn) {
4043
+ const currentControllerMethodsConfig = classConfig.methods;
4044
+ _.slice(rawConfigs, 1).forEach(bc => {
4045
+ const parentControllerMethods = _.cloneDeep(bc.methods);
4046
+ for (const methodsName in parentControllerMethods) {
4047
+ if (parentControllerMethods.hasOwnProperty(methodsName)) {
4048
+ if (!currentControllerMethodsConfig[methodsName]) {
4049
+ //#region add non existed method
4050
+ const methodConfig = parentControllerMethods[methodsName];
4051
+ currentControllerMethodsConfig[methodsName] = methodConfig;
4052
+ //#endregion
4053
+ }
4054
+ }
4055
+ }
4056
+ });
4057
+ }
4058
+ //#endregion
3947
4059
  async initControllers() {
3948
4060
  if (this.isRunOrRevertOnlyMigrationAppStart) {
3949
4061
  return;
3950
4062
  }
3951
4063
  const allControllers = this.getClassFunByArr(Models.ClassType.CONTROLLER);
4064
+ // debugger
3952
4065
  // console.log('allControllers', allControllers);
3953
4066
  for (const controllerClassFn of allControllers) {
4067
+ // console.log(ClassHelpers.getClassConfig(controllerClassFn));
4068
+ // const controllerName = ClassHelpers.getName(controllerClassFn);
4069
+ // console.log(
4070
+ // `for ${controllerName}`,
4071
+ // ClassHelpers.getClassConfig(controllerClassFn),
4072
+ // );
3954
4073
  controllerClassFn[Symbols.classMethodsNames] =
3955
4074
  ClassHelpers.getMethodsNames(controllerClassFn);
3956
- const configs = ClassHelpers.getControllerConfigs(controllerClassFn);
4075
+ const rawConfigs = ClassHelpers.getControllerConfigs(controllerClassFn);
4076
+ // console.log(controllerName, { rawConfigs });
3957
4077
  // 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
- }
4078
+ const classConfig = rawConfigs[0];
4079
+ this.updateCalculatedPathsForControllers(rawConfigs, classConfig, controllerClassFn);
4080
+ this.mergeControllerMethodsConfigs(rawConfigs, classConfig, controllerClassFn);
4081
+ //#region combine middlewares from controllers
4082
+ classConfig.calculatedMiddlewaresControllerObj = {};
4083
+ [...rawConfigs].reverse().forEach(rc => {
4084
+ if (_.isFunction(rc.middlewares)) {
4085
+ classConfig.calculatedMiddlewaresControllerObj = rc.middlewares({
4086
+ parentMiddlewares: classConfig.calculatedMiddlewaresControllerObj,
4087
+ className(middlewareClass) {
4088
+ return ClassHelpers.getName(controllerClassFn);
4089
+ },
4090
+ });
3993
4091
  }
3994
4092
  });
4093
+ //#endregion
4094
+ //#region group start
3995
4095
  /* */
3996
4096
  /* */
3997
4097
  this.logHttp &&
3998
4098
  console.groupCollapsed(`[taon][express-server] routes [${classConfig.className}]`);
3999
4099
  /* */
4000
4100
  /* */
4001
- // console.log('methods', classConfig.methods);
4101
+ //#endregion
4102
+ //#region init client or server methods
4002
4103
  const methodNames = Object.keys(classConfig.methods);
4003
4104
  for (const methodName of methodNames) {
4004
4105
  const methodConfig = classConfig.methods[methodName];
4005
- // debugger
4006
- const type = methodConfig.type;
4106
+ //#region combine all class methods middlewares
4107
+ let calculatedMiddlewaresMethodObj = {};
4108
+ [...rawConfigs].reverse().forEach(rc => {
4109
+ if (rc.methods[methodName]) {
4110
+ const parentMethodConfig = rc.methods[methodName];
4111
+ if (_.isFunction(parentMethodConfig.middlewares)) {
4112
+ calculatedMiddlewaresMethodObj = parentMethodConfig.middlewares({
4113
+ parentMiddlewares: calculatedMiddlewaresMethodObj,
4114
+ className(middlewareClass) {
4115
+ return ClassHelpers.getName(controllerClassFn);
4116
+ },
4117
+ });
4118
+ }
4119
+ }
4120
+ });
4121
+ // add class middlewares to method middlewares
4122
+ methodConfig.calculatedMiddlewaresMethodObj = {
4123
+ ...calculatedMiddlewaresMethodObj,
4124
+ ...classConfig.calculatedMiddlewaresControllerObj,
4125
+ };
4126
+ methodConfig.calculatedMiddlewares = Object.values(methodConfig.calculatedMiddlewaresMethodObj || {});
4127
+ //#endregion
4128
+ // methodConfig.calculatedMiddlewares = TODO
4129
+ //#region initialized method express path
4130
+ const httpMethodType = methodConfig.type;
4007
4131
  // this is quick fix - in docker global path should not be used
4008
4132
  const globalPathPart = this.isRunningInsideDocker ||
4009
4133
  !this.frontendHostUri?.origin?.includes('localhost') // fe with domain -> is in docker
@@ -4012,6 +4136,8 @@ class EndpointContext {
4012
4136
  const expressPath = methodConfig.global
4013
4137
  ? `${globalPathPart}/${methodConfig.path?.replace(/\/$/, '')}`.replace(/\/\//, '/')
4014
4138
  : TaonHelpers.getExpressPath(classConfig, methodConfig);
4139
+ //#endregion
4140
+ //#region init server
4015
4141
  // console.log({ expressPath });
4016
4142
  if (Helpers.isNode || Helpers.isWebSQL) {
4017
4143
  /* */
@@ -4029,6 +4155,8 @@ class EndpointContext {
4029
4155
  /* */
4030
4156
  /* */
4031
4157
  }
4158
+ //#endregion
4159
+ //#region init client
4032
4160
  const shouldInitClient = Helpers.isBrowser || this.remoteHost || Helpers.isWebSQL;
4033
4161
  // console.log('shouldInitClient', shouldInitClient);
4034
4162
  if (shouldInitClient) {
@@ -4039,14 +4167,18 @@ class EndpointContext {
4039
4167
  // methodConfig,
4040
4168
  // expressPath,
4041
4169
  // );
4042
- await this.initClient(controllerClassFn, type, methodConfig, expressPath);
4170
+ await this.initClient(controllerClassFn, httpMethodType, methodConfig, expressPath);
4043
4171
  }
4172
+ //#endregion
4044
4173
  }
4174
+ //#endregion
4175
+ //#region group end
4045
4176
  /* */
4046
4177
  /* */
4047
4178
  this.logHttp && console.groupEnd();
4048
4179
  /* */
4049
4180
  /* */
4181
+ //#endregion
4050
4182
  }
4051
4183
  }
4052
4184
  //#endregion
@@ -4108,15 +4240,15 @@ class EndpointContext {
4108
4240
  const middlewares = this.getClassesInstancesArrBy(Models.ClassType.MIDDLEWARE)
4109
4241
  .map(f => f)
4110
4242
  .filter(f => _.isFunction(f.interceptClient));
4111
- middlewares.forEach(instance => {
4243
+ middlewares.forEach(middlewareInstanceName => {
4112
4244
  const contextName = this.contextName;
4113
- const interceptorName = `${contextName}-${ClassHelpers.getName(instance)}`;
4245
+ const interceptorName = `${contextName}-${ClassHelpers.getName(middlewareInstanceName)}`;
4114
4246
  Resource.request.interceptors.set(interceptorName, {
4115
4247
  intercept: ({ req, next }) => {
4116
4248
  const url = new URL(req.url);
4117
4249
  if (url.pathname.startsWith(`${this.uriPathnameOrNothingIfRoot}/${apiPrefix}/${contextName}/`)) {
4118
4250
  // console.log('intercepting', url.pathname, req);
4119
- return instance.interceptClient({
4251
+ return middlewareInstanceName.interceptClient({
4120
4252
  req,
4121
4253
  next,
4122
4254
  });
@@ -4274,10 +4406,10 @@ class EndpointContext {
4274
4406
  //#region parameters
4275
4407
  httpMethodType, methodConfig, classConfig, expressPath, target) {
4276
4408
  //#region resolve variables
4277
- const middlewareHandlers = (Array.isArray(methodConfig.middlewares) &&
4278
- methodConfig.middlewares?.length > 0
4279
- ? methodConfig.middlewares
4280
- : [])
4409
+ // console.log(
4410
+ // `CLIENT: expressPath: "${expressPath}" interceptor for method: ${methodConfig.calculatedMiddlewares.length}`,
4411
+ // );
4412
+ const middlewareHandlers = methodConfig.calculatedMiddlewares
4281
4413
  .map(middlewareClassFun => {
4282
4414
  const middlewareInstance = this.getInstanceBy(middlewareClassFun);
4283
4415
  if (middlewareInstance &&
@@ -4565,7 +4697,6 @@ class EndpointContext {
4565
4697
  /* */
4566
4698
  /* */
4567
4699
  /* */
4568
- /* */
4569
4700
  }
4570
4701
  return {
4571
4702
  expressPath: expressPath,
@@ -4577,17 +4708,22 @@ class EndpointContext {
4577
4708
  /**
4578
4709
  * client can be browser or nodejs (when remote host)
4579
4710
  */
4580
- async initClient(
4581
- //#region parameters
4582
- target, httpRequestType, methodConfig, // Models.Http.Rest.MethodConfig,
4711
+ async initClient(target, httpRequestType, methodConfig, // Models.Http.Rest.MethodConfig,
4583
4712
  expressPath) {
4584
4713
  const ctx = this;
4714
+ // console.log(
4715
+ // `CLIENT: expressPath: "${expressPath}" interceptor for method: ${methodConfig.calculatedMiddlewares?.length} `,
4716
+ // );
4585
4717
  //#region init middlewares
4586
- const middlewares = methodConfig.middlewares
4718
+ const middlewares = methodConfig.calculatedMiddlewares;
4719
+ const middlewaresInstances = middlewares
4587
4720
  .map(f => this.getInstanceBy(f))
4588
4721
  .filter(f => _.isFunction(f.interceptClientMethod));
4589
- middlewares.forEach(instance => {
4590
- Resource.request.methodsInterceptors.set(`${methodConfig.type?.toUpperCase()}-${expressPath}`, {
4722
+ middlewaresInstances.forEach(instance => {
4723
+ const middlewareName = ClassHelpers.getName(instance);
4724
+ // middlewareName - only needed for inheritace and uniqness of interceptors
4725
+ const interceptorKey = `${middlewareName}-${methodConfig.type?.toUpperCase()}-${expressPath}`;
4726
+ Resource.request.methodsInterceptors.set(interceptorKey, {
4591
4727
  intercept: ({ req, next }) => {
4592
4728
  return instance.interceptClientMethod({
4593
4729
  req,
@@ -4857,6 +4993,14 @@ class EndpointContext {
4857
4993
  break;
4858
4994
  }
4859
4995
  }
4996
+ if (!currentParam) {
4997
+ const errorMessage = `[${config.frameworkName}] Unable to resolve parameter` +
4998
+ ` at index ${i} for method ${methodConfig.methodName} at path ${expressPath}.`;
4999
+ /* */
5000
+ /* */
5001
+ /* */
5002
+ throw new Error(errorMessage);
5003
+ }
4860
5004
  if (currentParam.paramType === 'Path') {
4861
5005
  pathPrams[currentParam.paramName] = param;
4862
5006
  }
@@ -5027,50 +5171,7 @@ const createContext = (configFn) => {
5027
5171
  // );
5028
5172
  const endpointContextRef = new EndpointContext(config, configFn);
5029
5173
  const res = {
5030
- //#region types
5031
- types: {
5032
- //#region entites for
5033
- // get entities() {
5034
- // return config.entities;
5035
- // },
5036
- // entitiesFor(classInstace: BaseInjector) {
5037
- // const ctx = classInstace.__endpoint_context__;
5038
- // if (!entitiesCache[ctx.contextName]) {
5039
- // entitiesCache[ctx.contextName] = {};
5040
- // for (const entityClassName of Object.keys(config.entities)) {
5041
- // entitiesCache[ctx.contextName][entityClassName] =
5042
- // config.entities[entityClassName][
5043
- // Taon.symbols.orignalClassClonesObj
5044
- // ][ctx.contextName];
5045
- // }
5046
- // }
5047
- // return entitiesCache[ctx.contextName] as typeof config.entities;
5048
- // },
5049
- //#endregion
5050
- get controllers() {
5051
- return config.controllers; // TODO QUICK_FIX new typescript generated wrong types
5052
- },
5053
- get repositories() {
5054
- return config.repositories; // TODO QUICK_FIX new typescript generated wrong types
5055
- },
5056
- get providers() {
5057
- return config.providers; // TODO QUICK_FIX new typescript generated wrong types
5058
- },
5059
- get subscribers() {
5060
- return config.subscribers; // TODO QUICK_FIX new typescript generated wrong types
5061
- },
5062
- get migrations() {
5063
- return config.migrations; // TODO QUICK_FIX new typescript generated wrong types
5064
- },
5065
- get middlewares() {
5066
- return config.middlewares; // TODO QUICK_FIX new typescript generated wrong types
5067
- },
5068
- },
5069
- //#endregion
5070
5174
  //#region contexts
5071
- get contexts() {
5072
- return config.contexts; // TODO QUICK_FIX new typescript generated wrong types
5073
- },
5074
5175
  get contextName() {
5075
5176
  return config.contextName;
5076
5177
  },
@@ -5204,7 +5305,7 @@ const createContext = (configFn) => {
5204
5305
  },
5205
5306
  /**
5206
5307
  * realtime communication with server
5207
- * Udp socket.io (or ipc) based.
5308
+ * TCP(upgrade) socket.io (or ipc) based.
5208
5309
  */
5209
5310
  get realtime() {
5210
5311
  return {
@@ -6146,12 +6247,18 @@ var baseContext = /*#__PURE__*/Object.freeze({
6146
6247
  function TaonController(options) {
6147
6248
  return function (constructor) {
6148
6249
  ClassHelpers.setName(constructor, options?.className);
6149
- Reflect.defineMetadata(Symbols.metadata.options.controller, options, constructor);
6150
6250
  Reflect.defineMetadata(Symbols.metadata.className, options?.className || constructor.name, constructor);
6251
+ const cfg = ClassHelpers.ensureClassConfig(constructor);
6252
+ options = options || {};
6253
+ cfg.className = options.className || constructor.name;
6254
+ cfg.path = options.path || '';
6255
+ cfg.realtime = options.realtime;
6256
+ cfg.middlewares = options.middlewares;
6151
6257
  };
6152
6258
  }
6153
6259
 
6154
6260
  const metaReq = (method, path, target, propertyKey, descriptor, pathOrOptions, pathIsGlobal) => {
6261
+ const methodConfig = ClassHelpers.ensureMethodConfig(target, propertyKey);
6155
6262
  let options;
6156
6263
  if (typeof pathOrOptions === 'object') {
6157
6264
  options = pathOrOptions;
@@ -6163,13 +6270,8 @@ const metaReq = (method, path, target, propertyKey, descriptor, pathOrOptions, p
6163
6270
  options = { pathOrOptions, pathIsGlobal };
6164
6271
  }
6165
6272
  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
6273
  methodConfig.methodName = propertyKey;
6172
- methodConfig.middlewares = middlewares || [];
6274
+ methodConfig.middlewares = middlewares;
6173
6275
  methodConfig.type = method;
6174
6276
  if (!path) {
6175
6277
  let paramsPathConcatedPath = '';
@@ -6192,8 +6294,6 @@ const metaReq = (method, path, target, propertyKey, descriptor, pathOrOptions, p
6192
6294
  methodConfig.global = pathIsGlobal;
6193
6295
  methodConfig.contentType = overrideContentType;
6194
6296
  methodConfig.responseType = overrideResponseType;
6195
- Reflect.defineMetadata(Symbols.metadata.options.controllerMethod, methodConfig, target.constructor, propertyKey);
6196
- // console.log('methods updated', methodConfig);
6197
6297
  };
6198
6298
  function GET(pathOrOptions, pathIsGlobal = false) {
6199
6299
  return function (target, propertyKey, descriptor) {
@@ -6227,21 +6327,16 @@ function DELETE(pathOrOptions, pathIsGlobal = false) {
6227
6327
  }
6228
6328
 
6229
6329
  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
- }
6330
+ const methodCfg = ClassHelpers.ensureMethodConfig(target, propertyKey);
6235
6331
  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);
6332
+ // const key = name || `${param}_${parameterIndex}`;
6333
+ methodCfg.parameters[nameKey] = {
6334
+ index: parameterIndex,
6335
+ paramName: name,
6336
+ paramType: param,
6337
+ defaultType: defaultValue,
6338
+ expireInSeconds: expire,
6339
+ };
6245
6340
  // console.log('params updated', methodConfig);
6246
6341
  }
6247
6342
  function Path(name) {
@@ -6319,7 +6414,10 @@ let BaseController = class BaseController extends BaseInjector {
6319
6414
  __decorate([
6320
6415
  POST({
6321
6416
  overrideContentType: 'multipart/form-data',
6322
- middlewares: [BaseFileUploadMiddleware],
6417
+ middlewares: ({ parentMiddlewares }) => ({
6418
+ ...parentMiddlewares,
6419
+ BaseFileUploadMiddleware,
6420
+ }),
6323
6421
  }),
6324
6422
  __param(0, Body()),
6325
6423
  __metadata("design:type", Function),
@@ -6936,5 +7034,5 @@ var Taon;
6936
7034
  * Generated bundle index. Do not edit.
6937
7035
  */
6938
7036
 
6939
- export { BaseContext, BaseController, BaseCustomRepository, BaseEntity, BaseMigration, BaseProvider, BaseRepository, CURRENT_HOST_BACKEND_PORT, ClassHelpers, EndpointContext, Models, TAON_CONTEXT, Taon, TaonAdminService, TaonEntityKeysToOmitArr, apiPrefix, createContext, inject };
7037
+ export { BaseContext, BaseController, BaseCustomRepository, BaseEntity, BaseMigration, BaseProvider, BaseRepository, CURRENT_HOST_BACKEND_PORT, CURRENT_HOST_URL, ClassHelpers, EndpointContext, Models, TAON_CONTEXT, Taon, TaonAdminService, TaonEntityKeysToOmitArr, apiPrefix, createContext, inject };
6940
7038
  //# sourceMappingURL=taon.mjs.map