@adaas/a-concept 0.1.61 → 0.2.1

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 (47) hide show
  1. package/dist/index.cjs +2 -2
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.d.mts +1584 -1456
  4. package/dist/index.d.ts +1584 -1456
  5. package/dist/index.mjs +2 -2
  6. package/dist/index.mjs.map +1 -1
  7. package/package.json +1 -1
  8. package/src/global/A-Abstraction/A-Abstraction.types.ts +2 -3
  9. package/src/global/A-Caller/A_Caller.types.ts +2 -1
  10. package/src/global/A-Component/A-Component.types.ts +2 -1
  11. package/src/global/A-Concept/A-Concept.types.ts +2 -1
  12. package/src/global/A-Container/A-Container.types.ts +2 -1
  13. package/src/global/A-Context/A-Context.class.ts +56 -25
  14. package/src/global/A-Dependency/A-Dependency-All.decorator.ts +77 -0
  15. package/src/global/A-Dependency/A-Dependency-Default.decorator.ts +4 -4
  16. package/src/global/A-Dependency/A-Dependency-Flat.decorator.ts +3 -2
  17. package/src/global/A-Dependency/A-Dependency-Load.decorator.ts +9 -13
  18. package/src/global/A-Dependency/A-Dependency-Parent.decorator.ts +2 -3
  19. package/src/global/A-Dependency/A-Dependency-Require.decorator.ts +1 -2
  20. package/src/global/A-Dependency/A-Dependency.class.ts +144 -5
  21. package/src/global/A-Dependency/A-Dependency.error.ts +3 -0
  22. package/src/global/A-Dependency/A-Dependency.types.ts +124 -3
  23. package/src/global/A-Entity/A-Entity.types.ts +2 -1
  24. package/src/global/A-Error/A_Error.types.ts +2 -1
  25. package/src/global/A-Feature/A-Feature-Define.decorator.ts +0 -1
  26. package/src/global/A-Feature/A-Feature-Extend.decorator.ts +1 -5
  27. package/src/global/A-Feature/A-Feature.types.ts +3 -3
  28. package/src/global/A-Fragment/A-Fragment.types.ts +2 -1
  29. package/src/global/A-Inject/A-Inject.decorator.ts +70 -42
  30. package/src/global/A-Inject/A-Inject.types.ts +2 -42
  31. package/src/global/A-Meta/A-Meta.decorator.ts +2 -1
  32. package/src/global/A-Meta/A-Meta.types.ts +2 -1
  33. package/src/global/A-Scope/A-Scope.class.ts +409 -389
  34. package/src/global/A-Scope/A-Scope.error.ts +2 -0
  35. package/src/global/A-Scope/A-Scope.types.ts +4 -8
  36. package/src/global/A-Stage/A-Stage.class.ts +19 -86
  37. package/src/global/A-Stage/A-Stage.types.ts +3 -1
  38. package/src/global/A-StepManager/A-StepManager.class.ts +1 -1
  39. package/src/global/ASEID/ASEID.class.ts +20 -0
  40. package/src/helpers/A_Common.helper.ts +4 -0
  41. package/src/helpers/A_TypeGuards.helper.ts +28 -3
  42. package/src/types/A_Common.types.ts +4 -0
  43. package/tests/A-Abstraction.test.ts +2 -0
  44. package/tests/A-Dependency.test.ts +49 -5
  45. package/tests/A-Feature.test.ts +44 -19
  46. package/tests/A-Scope.test.ts +38 -9
  47. package/tests/A-StepManager.test.ts +40 -39
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adaas/a-concept",
3
- "version": "0.1.61",
3
+ "version": "0.2.1",
4
4
  "description": "A-Concept is a framework of the new generation that is tailored to use AI, enabling developers to create AI-powered applications with ease. It provides a structured approach to building, managing, and deploying AI-driven solutions.",
5
5
  "license": "Apache-2.0",
6
6
  "main": "./dist/index.cjs",
@@ -1,9 +1,8 @@
1
+ import { A_TYPES__Ctor } from "@adaas/a-concept/types/A_Common.types";
1
2
  import { A_Component } from "../A-Component/A-Component.class";
2
3
  import { A_TYPES__ConceptAbstractions } from "../A-Concept/A-Concept.constants";
3
4
  import { A_Container } from "../A-Container/A-Container.class";
4
- import { A_Feature } from "../A-Feature/A-Feature.class";
5
5
  import { A_TYPES__FeatureExtendDecoratorConfig } from "../A-Feature/A-Feature.types";
6
- import { A_Scope } from "../A-Scope/A-Scope.class";
7
6
  import { A_Abstraction } from "./A-Abstraction.class";
8
7
 
9
8
 
@@ -14,7 +13,7 @@ import { A_Abstraction } from "./A-Abstraction.class";
14
13
  * Abstraction constructor type
15
14
  * Uses the generic type T to specify the type of the abstraction
16
15
  */
17
- export type A_TYPES__Abstraction_Constructor<T = A_Abstraction> = new (...args: any[]) => T;
16
+ export type A_TYPES__Abstraction_Constructor<T = A_Abstraction> = A_TYPES__Ctor<T>;
18
17
  /**
19
18
  * Abstraction initialization type
20
19
  */
@@ -1,3 +1,4 @@
1
+ import { A_TYPES__Ctor } from "@adaas/a-concept/types/A_Common.types";
1
2
  import { A_Component } from "../A-Component/A-Component.class";
2
3
  import { A_Container } from "../A-Container/A-Container.class";
3
4
  import { A_Entity } from "../A-Entity/A-Entity.class";
@@ -14,7 +15,7 @@ export type A_TYPES__CallerComponent = A_Container | A_Component | A_Entity;
14
15
  * Caller constructor type
15
16
  * Uses the generic type T to specify the type of the caller component
16
17
  */
17
- export type A_TYPES__Caller_Constructor<T = A_Caller> = new (...args: any[]) => T;
18
+ export type A_TYPES__Caller_Constructor<T = A_Caller> = A_TYPES__Ctor<T>;
18
19
  /**
19
20
  * Caller initialization type
20
21
  */
@@ -4,6 +4,7 @@ import { A_TYPES__ConceptAbstraction } from "../A-Concept/A-Concept.types"
4
4
  import { A_Component } from "./A-Component.class"
5
5
  import { A_TYPES__ComponentMetaKey } from "./A-Component.constants"
6
6
  import { A_TYPES__FeatureDefineDecoratorMeta, A_TYPES__FeatureExtendDecoratorMeta } from "../A-Feature/A-Feature.types"
7
+ import { A_TYPES__Ctor } from "@adaas/a-concept/types/A_Common.types"
7
8
 
8
9
 
9
10
 
@@ -17,7 +18,7 @@ import { A_TYPES__FeatureDefineDecoratorMeta, A_TYPES__FeatureExtendDecoratorMe
17
18
  * Component constructor type
18
19
  * Uses the generic type T to specify the type of the component
19
20
  */
20
- export type A_TYPES__Component_Constructor<T = A_Component> = new (...args: any[]) => T;
21
+ export type A_TYPES__Component_Constructor<T = A_Component> = A_TYPES__Ctor<T>;
21
22
  /**
22
23
  * Component initialization type
23
24
  */
@@ -5,6 +5,7 @@ import { A_TYPES__Component_Constructor } from "../A-Component/A-Component.types
5
5
  import { A_TYPES__Fragment_Constructor } from "../A-Fragment/A-Fragment.types";
6
6
  import { A_TYPES__Entity_Constructor } from "../A-Entity/A-Entity.types";
7
7
  import { A_TYPES__A_InjectDecorator_Meta } from "../A-Inject/A-Inject.types";
8
+ import { A_TYPES__Ctor } from "@adaas/a-concept/types/A_Common.types";
8
9
 
9
10
 
10
11
  // ============================================================================
@@ -14,7 +15,7 @@ import { A_TYPES__A_InjectDecorator_Meta } from "../A-Inject/A-Inject.types";
14
15
  * Concept constructor type
15
16
  * Uses the generic type T to specify the type of the concept
16
17
  */
17
- export type A_TYPES__Concept_Constructor<T = A_Concept> = new (...args: any[]) => T;
18
+ export type A_TYPES__Concept_Constructor<T = A_Concept> = A_TYPES__Ctor<T>;
18
19
  /**
19
20
  * Concept initialization type
20
21
  * Uses the generic type T to specify the type of containers that the concept will use
@@ -5,6 +5,7 @@ import { A_TYPES__Scope_Init } from "../A-Scope/A-Scope.types";
5
5
  import { A_TYPES__ContainerMetaKey } from "./A-Container.constants";
6
6
  import { A_Container } from "./A-Container.class";
7
7
  import { A_TYPES__FeatureDefineDecoratorMeta, A_TYPES__FeatureExtendDecoratorMeta } from "../A-Feature/A-Feature.types";
8
+ import { A_TYPES__Ctor } from "@adaas/a-concept/types/A_Common.types";
8
9
 
9
10
 
10
11
  // ============================================================================
@@ -14,7 +15,7 @@ import { A_TYPES__FeatureDefineDecoratorMeta, A_TYPES__FeatureExtendDecoratorMe
14
15
  * Container constructor type
15
16
  * Uses the generic type T to specify the type of the container
16
17
  */
17
- export type A_TYPES__Container_Constructor<T = A_Container> = new (...args: any[]) => T;
18
+ export type A_TYPES__Container_Constructor<T = A_Container> = A_TYPES__Ctor<T>;
18
19
  /**
19
20
  * Container initialization type
20
21
  */
@@ -38,6 +38,8 @@ import { A_TYPES__InjectableTargets } from "../A-Inject/A-Inject.types";
38
38
  import { A_TYPES__ConceptAbstractions } from "../A-Concept/A-Concept.constants";
39
39
  import { A_CommonHelper } from "@adaas/a-concept/helpers/A_Common.helper";
40
40
  import { A_TYPES__Fragment_Constructor } from "../A-Fragment/A-Fragment.types";
41
+ import { A_Dependency } from "../A-Dependency/A-Dependency.class";
42
+ import { A_TYPES__Ctor } from "@adaas/a-concept/types/A_Common.types";
41
43
 
42
44
 
43
45
 
@@ -414,13 +416,13 @@ export class A_Context {
414
416
  /**
415
417
  * Get meta for the specific class or instance
416
418
  */
417
- constructor: new (...args: any[]) => any
419
+ constructor: A_TYPES__Ctor<any>
418
420
  ): T
419
421
  static meta<T extends Record<string, any>>(
420
422
  /**
421
423
  * Get meta for the specific class or instance
422
424
  */
423
- constructor: new (...args: any[]) => any
425
+ constructor: A_TYPES__Ctor<any>
424
426
  ): A_Meta<T>
425
427
 
426
428
  static meta<T extends Record<string, any>>(
@@ -531,8 +533,25 @@ export class A_Context {
531
533
 
532
534
  // Check if the meta already exists for the property, if not create a new one
533
535
  if (!instance._metaStorage.has(property)) {
534
- const inheritMeta = instance._metaStorage.get(Object.getPrototypeOf(property)) || new metaType();
535
- instance._metaStorage.set(property, new metaType().from(inheritMeta as any));
536
+
537
+ let inheritedMeta: A_Meta<any> | undefined = undefined;
538
+ let currentProperty: any = property;
539
+
540
+ // go up to the prototype chain and find if there is any meta to inherit from
541
+ while (!inheritedMeta) {
542
+ const parent = Object.getPrototypeOf(currentProperty);
543
+
544
+ if (!parent) {
545
+ break;
546
+ }
547
+ inheritedMeta = instance._metaStorage.get(parent);
548
+ currentProperty = parent;
549
+ }
550
+
551
+ if (!inheritedMeta)
552
+ inheritedMeta = new metaType();
553
+
554
+ instance._metaStorage.set(property, new metaType().from(inheritedMeta as any));
536
555
  }
537
556
 
538
557
  // Return the meta for the property
@@ -791,12 +810,12 @@ export class A_Context {
791
810
  .filter(c => c !== A_Component && c !== A_Container && c !== A_Entity)
792
811
  .map(c => `${c.name}.${name}`);
793
812
 
794
-
795
-
796
- // const callNames = [`${component.constructor.name}.${name}`];
813
+ // const callNames = [`${A_CommonHelper.getComponentName(component)}.${name}`];
797
814
  // const callNames = [`BaseComponent.testFeature`];
798
815
 
799
- const steps: A_TYPES__A_StageStep[] = [];
816
+ const steps: Map<string, A_TYPES__A_StageStep> = new Map();
817
+
818
+ const allowedComponents: Set<A_TYPES__MetaLinkedComponentConstructors> = new Set();
800
819
 
801
820
  for (const callName of callNames) {
802
821
  // We need to get all components that has extensions for the feature in component
@@ -804,14 +823,22 @@ export class A_Context {
804
823
  // Just try to make sure that component not only Indexed but also presented in scope
805
824
  if (scope.has(cmp) && (
806
825
  A_TypeGuards.isComponentMetaInstance(meta)
807
- || A_TypeGuards.isContainerMetaInstance(meta)
826
+ ||
827
+ A_TypeGuards.isContainerMetaInstance(meta)
808
828
  )) {
829
+ allowedComponents.add(cmp);
809
830
  // Get all extensions for the feature
810
831
  meta
811
832
  .extensions(callName)
812
833
  .forEach((declaration) => {
813
- steps.push({
814
- component: cmp,
834
+ const inherited = Array.from(allowedComponents).reverse().find(c => A_CommonHelper.isInheritedFrom(cmp, c) && c !== cmp);
835
+
836
+ if (inherited) {
837
+ steps.delete(`${A_CommonHelper.getComponentName(inherited)}.${declaration.handler}`);
838
+ }
839
+
840
+ steps.set(`${A_CommonHelper.getComponentName(cmp)}.${declaration.handler}`, {
841
+ dependency: new A_Dependency(cmp),
815
842
  ...declaration
816
843
  });
817
844
  });
@@ -819,7 +846,7 @@ export class A_Context {
819
846
  }
820
847
  }
821
848
 
822
- return instance.filterToMostDerived(scope, steps);
849
+ return instance.filterToMostDerived(scope, Array.from(steps.values()));
823
850
  }
824
851
 
825
852
 
@@ -834,21 +861,16 @@ export class A_Context {
834
861
  scope: A_Scope,
835
862
  items: A_TYPES__A_StageStep[]): Array<A_TYPES__A_StageStep> {
836
863
  return items.filter(item => {
837
- const currentClass = typeof item.component === 'string'
838
- ? scope.resolveConstructor(item.component)
839
- : A_TypeGuards.isContainerInstance(item.component)
840
- ? item.component.constructor : item.component;
864
+ // const currentClass = scope.resolveConstructor(item.dependency.name)
865
+ const currentClass = scope.resolveConstructor(item.dependency.name)
841
866
 
842
867
  // Check if this class is parent of any other in the list
843
868
  const isParentOfAnother = items.some(other => {
844
869
  if (other === item) return false;
845
870
 
846
- const otherClass = typeof other.component === 'string'
847
- ? scope.resolveConstructor(other.component)
848
- : A_TypeGuards.isContainerInstance(other.component)
849
- ? other.component.constructor
850
- : other.component;
871
+ const otherClass = scope.resolveConstructor(other.dependency.name);
851
872
 
873
+ if (!currentClass || !otherClass) return false;
852
874
 
853
875
  return currentClass.prototype.isPrototypeOf(otherClass.prototype);
854
876
  });
@@ -997,30 +1019,39 @@ export class A_Context {
997
1019
  `Unable to get feature template. Component of type ${componentName} is not allowed for feature definition.`
998
1020
  );
999
1021
 
1000
- const steps: A_TYPES__A_StageStep[] = [];
1022
+ const steps: Map<string, A_TYPES__A_StageStep> = new Map();
1001
1023
 
1002
1024
  const scope = this.scope(component);
1003
1025
 
1004
1026
  // We need to get all components that has extensions for the feature in component
1027
+ const allowedComponents: Set<A_TYPES__MetaLinkedComponentConstructors> = new Set();
1028
+
1005
1029
  for (const [cmp, meta] of instance._metaStorage) {
1006
1030
  // Just try to make sure that component not only Indexed but also presented in scope
1007
1031
  if (scope.has(cmp) && (
1008
1032
  A_TypeGuards.isComponentMetaInstance(meta)
1009
1033
  || A_TypeGuards.isContainerMetaInstance(meta)
1010
1034
  )) {
1035
+ allowedComponents.add(cmp);
1011
1036
  // Get all extensions for the feature
1012
1037
  meta
1013
1038
  .abstractions(abstraction)
1014
1039
  .forEach((declaration) => {
1015
- steps.push({
1016
- component: cmp,
1040
+ const inherited = Array.from(allowedComponents).reverse().find(c => A_CommonHelper.isInheritedFrom(cmp, c) && c !== cmp);
1041
+
1042
+ if (inherited) {
1043
+ steps.delete(`${A_CommonHelper.getComponentName(inherited)}.${declaration.handler}`);
1044
+ }
1045
+
1046
+ steps.set(`${A_CommonHelper.getComponentName(cmp)}.${declaration.handler}`, {
1047
+ dependency: new A_Dependency(cmp),
1017
1048
  ...declaration
1018
1049
  });
1019
1050
  });
1020
1051
  }
1021
1052
  }
1022
1053
 
1023
- return instance.filterToMostDerived(scope, steps);
1054
+ return instance.filterToMostDerived(scope, Array.from(steps.values()));
1024
1055
  }
1025
1056
 
1026
1057
 
@@ -0,0 +1,77 @@
1
+
2
+ import { A_Context } from "@adaas/a-concept/global/A-Context/A-Context.class";
3
+ import { A_Meta } from "@adaas/a-concept/global/A-Meta/A-Meta.class";
4
+ import { A_TYPES__ComponentMetaKey } from "@adaas/a-concept/global/A-Component/A-Component.constants";
5
+ import { A_TYPES__ContainerMetaKey } from "@adaas/a-concept/global/A-Container/A-Container.constants";
6
+ import { A_TypeGuards } from "@adaas/a-concept/helpers/A_TypeGuards.helper";
7
+ import { A_TYPES__A_InjectDecorator_Meta, A_TYPES__InjectableTargets } from "../A-Inject/A-Inject.types";
8
+ import { A_TYPES__A_Dependency_AllDecoratorReturn } from "./A-Dependency.types";
9
+ import { A_DependencyError } from "./A-Dependency.error";
10
+ import { A_CommonHelper } from "@adaas/a-concept/helpers/A_Common.helper";
11
+ import { A_Entity } from "../A-Entity/A-Entity.class";
12
+ import { A_TYPES__Entity_Constructor } from "../A-Entity/A-Entity.types";
13
+
14
+
15
+ /**
16
+ * Should indicate which All is required
17
+ */
18
+ export function A_Dependency_All<T extends A_Entity>(
19
+ /**
20
+ * Constructor Parameters that will be used to create the default instance
21
+ */
22
+ entity: A_TYPES__Entity_Constructor<T>
23
+ ): A_TYPES__A_Dependency_AllDecoratorReturn {
24
+
25
+ return function (
26
+ target: A_TYPES__InjectableTargets,
27
+ methodName: string | symbol | undefined,
28
+ parameterIndex: number
29
+ ) {
30
+ // for Error handling purposes
31
+ const componentName = A_CommonHelper.getComponentName(target)
32
+
33
+ if (!A_TypeGuards.isTargetAvailableForInjection(target)) {
34
+ throw new A_DependencyError(
35
+ A_DependencyError.InvalidDependencyTarget,
36
+ `A-All cannot be used on the target of type ${typeof target} (${componentName})`
37
+ );
38
+ }
39
+
40
+ // determine the method name or 'constructor' for constructor injections
41
+ const method = methodName ? String(methodName) : 'constructor';
42
+ let metaKey;
43
+
44
+ switch (true) {
45
+ case A_TypeGuards.isComponentConstructor(target) || A_TypeGuards.isComponentInstance(target):
46
+ metaKey = A_TYPES__ComponentMetaKey.INJECTIONS;
47
+ break;
48
+
49
+ case A_TypeGuards.isContainerInstance(target):
50
+ metaKey = A_TYPES__ContainerMetaKey.INJECTIONS;
51
+ break;
52
+ }
53
+
54
+ // get existing meta or create a new one
55
+ const existedMeta = A_Context.meta(target).get(metaKey) || new A_Meta();
56
+ // get existing injections for the method or create a new array
57
+ const paramsArray: A_TYPES__A_InjectDecorator_Meta = existedMeta.get(method) || [];
58
+
59
+ // set the parameter injection info
60
+ paramsArray[parameterIndex].resolutionStrategy = {
61
+ pagination: {
62
+ ...paramsArray[parameterIndex].resolutionStrategy.pagination,
63
+ count: -1
64
+ }
65
+ }
66
+ // save back the updated injections array
67
+ existedMeta.set(method, paramsArray);
68
+
69
+ // save back the updated meta info
70
+ A_Context
71
+ .meta(target)
72
+ .set(
73
+ metaKey,
74
+ existedMeta
75
+ );
76
+ }
77
+ }
@@ -56,11 +56,11 @@ export function A_Dependency_Default(
56
56
  const paramsArray: A_TYPES__A_InjectDecorator_Meta = existedMeta.get(method) || [];
57
57
 
58
58
  // set the parameter injection info
59
- paramsArray[parameterIndex] = {
60
- ...(paramsArray[parameterIndex] || {}),
61
- defaultArgs: args,
62
- create: true
59
+ paramsArray[parameterIndex].resolutionStrategy = {
60
+ create: true,
61
+ args: args
63
62
  }
63
+
64
64
  // save back the updated injections array
65
65
  existedMeta.set(method, paramsArray);
66
66
 
@@ -49,11 +49,12 @@ export function A_Dependency_Flat(): A_TYPES__A_Dependency_FlatDecoratorReturn {
49
49
  // get existing injections for the method or create a new array
50
50
  const paramsArray: A_TYPES__A_InjectDecorator_Meta = existedMeta.get(method) || [];
51
51
 
52
+
52
53
  // set the parameter injection info
53
- paramsArray[parameterIndex] = {
54
- ...(paramsArray[parameterIndex] || {}),
54
+ paramsArray[parameterIndex].resolutionStrategy = {
55
55
  flat: true,
56
56
  }
57
+
57
58
  // save back the updated injections array
58
59
  existedMeta.set(method, paramsArray);
59
60
 
@@ -14,18 +14,15 @@ import { A_CommonHelper } from "@adaas/a-concept/helpers/A_Common.helper";
14
14
  * Should indicate which Load is required
15
15
  */
16
16
  export function A_Dependency_Load(
17
- /**
18
- * Path to load the dependency from
19
- */
20
- path: string
17
+
21
18
  ): A_TYPES__A_Dependency_LoadDecoratorReturn {
22
19
 
23
- if (!path || typeof path !== 'string') {
24
- throw new A_DependencyError(
25
- A_DependencyError.InvalidLoadPath,
26
- `A-Load decorator requires a valid path string to the dependency`
27
- );
28
- }
20
+ // if (!path || typeof path !== 'string') {
21
+ // throw new A_DependencyError(
22
+ // A_DependencyError.InvalidLoadPath,
23
+ // `A-Load decorator requires a valid path string to the dependency`
24
+ // );
25
+ // }
29
26
 
30
27
  return function (
31
28
  target: A_TYPES__InjectableTargets,
@@ -62,9 +59,8 @@ export function A_Dependency_Load(
62
59
  const paramsArray: A_TYPES__A_InjectDecorator_Meta = existedMeta.get(method) || [];
63
60
 
64
61
  // set the parameter injection info
65
- paramsArray[parameterIndex] = {
66
- ...(paramsArray[parameterIndex] || {}),
67
- load: path
62
+ paramsArray[parameterIndex].resolutionStrategy = {
63
+ load: true
68
64
  }
69
65
  // save back the updated injections array
70
66
  existedMeta.set(method, paramsArray);
@@ -57,9 +57,8 @@ export function A_Dependency_Parent(
57
57
  const paramsArray: A_TYPES__A_InjectDecorator_Meta = existedMeta.get(method) || [];
58
58
 
59
59
  // set the parameter injection info
60
- paramsArray[parameterIndex] = {
61
- ...(paramsArray[parameterIndex] || {}),
62
- parent: { layerOffset }
60
+ paramsArray[parameterIndex].resolutionStrategy = {
61
+ parent: layerOffset
63
62
  }
64
63
  // save back the updated injections array
65
64
  existedMeta.set(method, paramsArray);
@@ -50,8 +50,7 @@ export function A_Dependency_Require(): A_TYPES__A_Dependency_RequireDecoratorRe
50
50
  const paramsArray: A_TYPES__A_InjectDecorator_Meta = existedMeta.get(method) || [];
51
51
 
52
52
  // set the parameter injection info
53
- paramsArray[parameterIndex] = {
54
- ...(paramsArray[parameterIndex] || {}),
53
+ paramsArray[parameterIndex].resolutionStrategy = {
55
54
  require: true
56
55
  }
57
56
  // save back the updated injections array
@@ -1,11 +1,18 @@
1
+ import { A_CommonHelper } from "@adaas/a-concept/helpers/A_Common.helper";
1
2
  import { A_Dependency_Default } from "./A-Dependency-Default.decorator";
2
3
  import { A_Dependency_Flat } from "./A-Dependency-Flat.decorator";
3
4
  import { A_Dependency_Load } from "./A-Dependency-Load.decorator";
4
5
  import { A_Dependency_Parent } from "./A-Dependency-Parent.decorator";
5
6
  import { A_Dependency_Require } from "./A-Dependency-Require.decorator";
7
+ import { A_DependencyError } from "./A-Dependency.error";
8
+ import { A_TYPES__A_Dependency_EntityInjectionPagination, A_TYPES__A_Dependency_EntityInjectionQuery, A_TYPES__A_Dependency_Serialized, A_TYPES__A_DependencyInjectable, A_TYPES__A_DependencyResolutionStrategy, A_TYPES__A_DependencyResolutionType } from "./A-Dependency.types";
9
+ import { A_Entity } from "../A-Entity/A-Entity.class";
10
+ import { A_TYPES__Ctor } from "@adaas/a-concept/types/A_Common.types";
6
11
 
7
12
 
8
- export class A_Dependency {
13
+ export class A_Dependency<
14
+ T extends A_TYPES__A_DependencyInjectable = A_TYPES__A_DependencyInjectable
15
+ > {
9
16
  /**
10
17
  * Allows to indicate which Injected parameter is required
11
18
  *
@@ -53,16 +60,74 @@ export class A_Dependency {
53
60
  }
54
61
 
55
62
  protected _name: string;
63
+ protected _target?: A_TYPES__Ctor<T>;
64
+ protected _resolutionStrategy!: A_TYPES__A_DependencyResolutionStrategy;
65
+
66
+ protected _defaultPagination: A_TYPES__A_DependencyResolutionStrategy['pagination'] = {
67
+ count: 1,
68
+ from: 'start',
69
+ };
70
+ protected _defaultResolutionStrategy: A_TYPES__A_DependencyResolutionStrategy = {
71
+ require: false,
72
+ load: false,
73
+ parent: 0,
74
+ flat: false,
75
+ create: false,
76
+ args: [],
77
+ query: {},
78
+ pagination: this._defaultPagination,
79
+ };
80
+
81
+ get flat(): boolean {
82
+ return this._resolutionStrategy.flat;
83
+ }
84
+ get require(): boolean {
85
+ return this._resolutionStrategy.require;
86
+ }
87
+ get load(): boolean {
88
+ return this._resolutionStrategy.load;
89
+ }
90
+ /**
91
+ * Indicates cases when it's necessary to search across all instances
92
+ */
93
+ get all(): boolean {
94
+ return this._resolutionStrategy.pagination.count !== 1 || Object.keys(this._resolutionStrategy.query).length > 0
95
+ }
96
+ get parent(): number {
97
+ return this._resolutionStrategy.parent;
98
+ }
99
+ get create(): any {
100
+ return this._resolutionStrategy.create;
101
+ }
102
+ get args(): any[] {
103
+ return this._resolutionStrategy.args;
104
+ }
105
+ get query(): Partial<A_TYPES__A_Dependency_EntityInjectionQuery<T extends A_Entity ? T : A_Entity>> {
106
+ return this._resolutionStrategy.query;
107
+ }
108
+ get pagination(): A_TYPES__A_Dependency_EntityInjectionPagination {
109
+ return this._resolutionStrategy.pagination;
110
+ }
111
+
112
+
113
+
56
114
 
57
115
  /**
58
- * Class instances allows to indentify dependencies by name and use them for better type checking
116
+ * Class instances allows to identify dependencies by name and use them for better type checking
59
117
  *
60
118
  * @param name
61
119
  */
62
120
  constructor(
63
- name: string
121
+ name: string | A_TYPES__Ctor<T>,
122
+ resolutionStrategy?: Partial<Omit<A_TYPES__A_DependencyResolutionStrategy<T extends A_Entity ? T : A_Entity>, 'pagination'> & { pagination: Partial<A_TYPES__A_Dependency_EntityInjectionPagination> }>
64
123
  ) {
65
- this._name = name;
124
+ this._name = typeof name === 'string' ? name : A_CommonHelper.getComponentName(name);
125
+
126
+ this._target = typeof name === 'string' ? undefined : name;
127
+
128
+ this.resolutionStrategy = resolutionStrategy || {};
129
+
130
+ this.initCheck();
66
131
  }
67
132
 
68
133
  /**
@@ -75,4 +140,78 @@ export class A_Dependency {
75
140
  get name(): string {
76
141
  return this._name;
77
142
  }
78
- }
143
+
144
+ /**
145
+ * Returns the original class of the dependency if provided
146
+ *
147
+ */
148
+ get target(): A_TYPES__Ctor<T> | undefined {
149
+ return this._target;
150
+ }
151
+
152
+ /**
153
+ * Gets the dependency resolution strategy
154
+ */
155
+ get resolutionStrategy(): A_TYPES__A_DependencyResolutionStrategy<T extends A_Entity ? T : A_Entity> {
156
+ return this._resolutionStrategy!;
157
+ }
158
+
159
+ /**
160
+ * Sets the dependency resolution strategy
161
+ */
162
+ set resolutionStrategy(strategy: Partial<Omit<A_TYPES__A_DependencyResolutionStrategy<T extends A_Entity ? T : A_Entity>, 'pagination'> & { pagination: Partial<A_TYPES__A_Dependency_EntityInjectionPagination> }>) {
163
+ this._resolutionStrategy = {
164
+ ...this._defaultResolutionStrategy,
165
+ ...this._resolutionStrategy,
166
+ ...strategy,
167
+ pagination: {
168
+ ...this._defaultPagination,
169
+ ...(strategy.pagination || {})
170
+ },
171
+ };
172
+ }
173
+
174
+
175
+ /**
176
+ * Method for the parameters check and all input data before usage
177
+ *
178
+ * @returns
179
+ */
180
+ private initCheck(
181
+ ): this {
182
+ if (!this._resolutionStrategy) {
183
+ throw new A_DependencyError(
184
+ A_DependencyError.ResolutionParametersError,
185
+ `Resolution strategy parameters are not provided for dependency: ${this._name}`
186
+ );
187
+ }
188
+
189
+
190
+
191
+ return this;
192
+ }
193
+
194
+
195
+ /**
196
+ * Serializes the dependency to a JSON object
197
+ *
198
+ * @returns
199
+ */
200
+ toJSON(): A_TYPES__A_Dependency_Serialized {
201
+ return {
202
+ name: this._name,
203
+ all: this.all,
204
+ require: this.require,
205
+ load: this.load,
206
+ parent: this.parent,
207
+ flat: this.flat,
208
+ create: this.create,
209
+ args: this.args,
210
+ query: this.query,
211
+ pagination: this.pagination,
212
+ }
213
+ }
214
+ }
215
+
216
+
217
+
@@ -10,4 +10,7 @@ export class A_DependencyError extends A_Error {
10
10
 
11
11
 
12
12
  static readonly InvalidDefaultTarget = 'Invalid Default Target';
13
+
14
+
15
+ static readonly ResolutionParametersError = 'Dependency Resolution Parameters Error';
13
16
  }