@adaas/a-concept 0.1.52 → 0.1.53

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adaas/a-concept",
3
- "version": "0.1.52",
3
+ "version": "0.1.53",
4
4
  "description": "A-Concept is a framework to build new Applications within or outside the ADAAS ecosystem. This framework is designed to be modular structure regardless environment and program goal.",
5
5
  "license": "Apache-2.0",
6
6
  "main": "./dist/index.cjs",
@@ -709,26 +709,33 @@ export class A_Context {
709
709
  if (!A_TypeGuards.isAllowedForFeatureDefinition(component))
710
710
  throw new A_ContextError(A_ContextError.InvalidFeatureExtensionParameterError, `Unable to get feature template. Component of type ${componentName} is not allowed for feature definition.`);
711
711
 
712
- const callName = `${component.constructor.name}.${name}`;
712
+
713
+ const callNames = A_CommonHelper.getClassInheritanceChain(component)
714
+ .filter(c => c !== A_Component && c !== A_Container && c !== A_Entity)
715
+ .map(c => `${c.name}.${name}`);
716
+
717
+ // const callName = `${component.constructor.name}.${name}`;
713
718
 
714
719
  const steps: A_TYPES__A_StageStep[] = [];
715
720
 
716
- // We need to get all components that has extensions for the feature in component
717
- for (const [cmp, meta] of instance._metaStorage) {
718
- // Just try to make sure that component not only Indexed but also presented in scope
719
- if (scope.has(cmp) && (
720
- A_TypeGuards.isComponentMetaInstance(meta)
721
- || A_TypeGuards.isContainerMetaInstance(meta)
722
- )) {
723
- // Get all extensions for the feature
724
- meta
725
- .extensions(callName)
726
- .forEach((declaration) => {
727
- steps.push({
728
- component: cmp,
729
- ...declaration
721
+ for (const callName of callNames) {
722
+ // We need to get all components that has extensions for the feature in component
723
+ for (const [cmp, meta] of instance._metaStorage) {
724
+ // Just try to make sure that component not only Indexed but also presented in scope
725
+ if (scope.has(cmp) && (
726
+ A_TypeGuards.isComponentMetaInstance(meta)
727
+ || A_TypeGuards.isContainerMetaInstance(meta)
728
+ )) {
729
+ // Get all extensions for the feature
730
+ meta
731
+ .extensions(callName)
732
+ .forEach((declaration) => {
733
+ steps.push({
734
+ component: cmp,
735
+ ...declaration
736
+ });
730
737
  });
731
- });
738
+ }
732
739
  }
733
740
  }
734
741
 
@@ -30,6 +30,68 @@ export class A_CommonHelper {
30
30
  return false;
31
31
  }
32
32
 
33
+
34
+ /**
35
+ * Get all parent classes of a given class
36
+ *
37
+ * @param childClass
38
+ * @returns
39
+ */
40
+ static getParentClasses(childClass: any): any[] {
41
+
42
+ // first we need to check is that a constructor or instance
43
+ let current = typeof childClass === 'function'
44
+ ? Object.getPrototypeOf(childClass)
45
+ : Object.getPrototypeOf(childClass.constructor);
46
+
47
+ const parents = [] as any[];
48
+
49
+ // Traverse the prototype chain
50
+ while (current && current !== Function.prototype) {
51
+ parents.push(current);
52
+ current = Object.getPrototypeOf(current);
53
+ }
54
+ return parents;
55
+
56
+ }
57
+
58
+ /**
59
+ * Get the class inheritance chain as an array of class names
60
+ *
61
+ * @param childClass
62
+ * @returns
63
+ */
64
+ static getClassInheritanceChain(childClass: any): any[] {
65
+
66
+ // first we need to check is that a constructor or instance
67
+ let current = typeof childClass === 'function'
68
+ ? Object.getPrototypeOf(childClass)
69
+ : Object.getPrototypeOf(childClass.constructor);
70
+
71
+ // then if input is instance we have to include its own class name
72
+ const chain = typeof childClass === 'function'
73
+ ? [childClass]
74
+ : [childClass.constructor];
75
+
76
+
77
+ // Traverse the prototype chain
78
+ while (current && current !== Function.prototype) {
79
+ chain.push(current);
80
+ current = Object.getPrototypeOf(current);
81
+ }
82
+ return chain;
83
+ }
84
+
85
+ /**
86
+ * Get the parent class of a given class
87
+ *
88
+ * @param childClass
89
+ * @returns
90
+ */
91
+ static getParentClass(childClass: any): any {
92
+ return Object.getPrototypeOf(childClass);
93
+ }
94
+
33
95
  /**
34
96
  * Omit properties from an object or array with nested objects
35
97
  *
@@ -5,7 +5,7 @@ import { A_Scope } from "@adaas/a-concept/global/A-Scope/A-Scope.class";
5
5
  import { A_Caller } from '@adaas/a-concept/global/A-Caller/A_Caller.class';
6
6
  import { A_Context } from '@adaas/a-concept/global/A-Context/A-Context.class';
7
7
  import { A_TYPES__ComponentMetaKey } from '@adaas/a-concept/global/A-Component/A-Component.constants';
8
- import { A_Error, A_TYPES__FeatureState } from "../src";
8
+ import { A_Entity, A_Error, A_TYPES__FeatureState } from "../src";
9
9
 
10
10
  jest.retryTimes(0);
11
11
 
@@ -582,4 +582,47 @@ describe('A-Feature tests', () => {
582
582
  });
583
583
 
584
584
  }, 5000);
585
+ it('Should allow to use extension if only parent class provided', async () => {
586
+ const executionResults: string[] = [];
587
+
588
+ class BaseEntity extends A_Entity {
589
+ async test() {
590
+ await this.call('myFeature');
591
+ }
592
+
593
+ }
594
+
595
+ class MyComponent extends A_Component {
596
+
597
+ @A_Feature.Extend({
598
+ name: 'myFeature',
599
+ scope: [BaseEntity]
600
+ })
601
+ testMethod() {
602
+ executionResults.push('testMethod');
603
+ }
604
+ }
605
+
606
+ class My_Entity extends BaseEntity {
607
+
608
+ }
609
+
610
+ const scope = new A_Scope({ name: 'TestScope', components: [MyComponent] });
611
+
612
+
613
+ const myEntity = new My_Entity({ name: 'MyEntityInstance' });
614
+ const baseEntity = new BaseEntity({ name: 'BaseEntityInstance' });
615
+
616
+
617
+ scope.register(myEntity);
618
+ scope.register(baseEntity);
619
+
620
+ await baseEntity.test();
621
+
622
+ expect(executionResults).toEqual(['testMethod']);
623
+
624
+ await myEntity.test();
625
+
626
+ expect(executionResults).toEqual(['testMethod', 'testMethod']);
627
+ });
585
628
  });