@adaas/a-concept 0.0.60 → 0.0.62
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/dist/index.d.ts +4 -4
- package/dist/index.js +5 -5
- package/dist/index.js.map +1 -1
- package/dist/src/base/A-Config/A-Config.container.js +2 -2
- package/dist/src/base/A-Config/A-Config.container.js.map +1 -1
- package/dist/src/base/A-Config/A-Config.context.js +3 -3
- package/dist/src/base/A-Config/A-Config.context.js.map +1 -1
- package/dist/src/base/A-Config/components/ENVConfigReader.component.js +1 -5
- package/dist/src/base/A-Config/components/ENVConfigReader.component.js.map +1 -1
- package/dist/src/base/A-Config/components/FileConfigReader.component.js +2 -1
- package/dist/src/base/A-Config/components/FileConfigReader.component.js.map +1 -1
- package/dist/src/decorators/A-Feature/A-Feature-Define.decorator.d.ts +2 -1
- package/dist/src/decorators/A-Feature/A-Feature-Define.decorator.js +9 -2
- package/dist/src/decorators/A-Feature/A-Feature-Define.decorator.js.map +1 -1
- package/dist/src/{base/A-Command/A_Command.entity.d.ts → global/A-Command/A-Command.class.d.ts} +72 -10
- package/dist/src/{base/A-Command/A_Command.entity.js → global/A-Command/A-Command.class.js} +119 -46
- package/dist/src/global/A-Command/A-Command.class.js.map +1 -0
- package/dist/src/{base/A-Command/A_Command.constants.js → global/A-Command/A-Command.constants.js} +1 -1
- package/dist/src/global/A-Command/A-Command.constants.js.map +1 -0
- package/dist/src/global/A-Command/A-Command.meta.d.ts +11 -0
- package/dist/src/global/A-Command/A-Command.meta.js +18 -0
- package/dist/src/global/A-Command/A-Command.meta.js.map +1 -0
- package/dist/src/global/A-Command/A-Command.types.d.ts +43 -0
- package/dist/src/global/A-Command/A-Command.types.js +10 -0
- package/dist/src/global/A-Command/A-Command.types.js.map +1 -0
- package/dist/src/{base → global}/A-Command/context/A_Command.context.d.ts +1 -1
- package/dist/src/{base → global}/A-Command/context/A_Command.context.js +1 -1
- package/dist/src/global/A-Command/context/A_Command.context.js.map +1 -0
- package/dist/src/global/A-Concept/A_Concept.class.js +2 -0
- package/dist/src/global/A-Concept/A_Concept.class.js.map +1 -1
- package/dist/src/global/A-Concept/A_Concept.types.d.ts +10 -0
- package/dist/src/global/A-Concept/A_Concept.types.js.map +1 -1
- package/dist/src/global/A-Context/A-Context.class.d.ts +3 -1
- package/dist/src/global/A-Context/A-Context.class.js +16 -6
- package/dist/src/global/A-Context/A-Context.class.js.map +1 -1
- package/dist/src/global/A-Entity/A-Entity.class.js +1 -4
- package/dist/src/global/A-Entity/A-Entity.class.js.map +1 -1
- package/dist/src/global/A-Feature/A-FeatureCaller.class.d.ts +4 -3
- package/dist/src/global/A-Feature/A-FeatureCaller.class.js.map +1 -1
- package/dist/src/global/A-Scope/A-Scope.class.d.ts +15 -1
- package/dist/src/global/A-Scope/A-Scope.class.js +59 -5
- package/dist/src/global/A-Scope/A-Scope.class.js.map +1 -1
- package/dist/src/global/A-Scope/A-Scope.types.d.ts +7 -0
- package/dist/src/global/A-Stage/A-Stage.class.d.ts +1 -1
- package/index.ts +4 -4
- package/package.json +2 -2
- package/src/base/A-Config/A-Config.container.ts +2 -2
- package/src/base/A-Config/A-Config.context.ts +6 -3
- package/src/base/A-Config/components/ENVConfigReader.component.ts +1 -6
- package/src/base/A-Config/components/FileConfigReader.component.ts +2 -1
- package/src/decorators/A-Feature/A-Feature-Define.decorator.ts +13 -6
- package/src/{base/A-Command/A_Command.entity.ts → global/A-Command/A-Command.class.ts} +149 -35
- package/src/global/A-Command/A-Command.meta.ts +22 -0
- package/src/global/A-Command/A-Command.types.ts +71 -0
- package/src/global/A-Concept/A_Concept.class.ts +3 -0
- package/src/global/A-Concept/A_Concept.types.ts +10 -0
- package/src/global/A-Context/A-Context.class.ts +23 -5
- package/src/global/A-Entity/A-Entity.class.ts +1 -4
- package/src/global/A-Feature/A-FeatureCaller.class.ts +4 -3
- package/src/global/A-Scope/A-Scope.class.ts +77 -9
- package/src/global/A-Scope/A-Scope.types.ts +7 -0
- package/tests/A-Command.test.ts +16 -13
- package/tests/A-Component.test.ts +2 -0
- package/tests/A-Concept.test.ts +112 -0
- package/tests/A-Config.test.ts +72 -6
- package/tests/A-Entity.test.ts +2 -0
- package/tests/A-Feature.test.ts +2 -0
- package/tests/A-Scope.test.ts +47 -4
- package/tests/test.setup.ts +30 -0
- package/dist/src/base/A-Command/A_Command.constants.js.map +0 -1
- package/dist/src/base/A-Command/A_Command.entity.js.map +0 -1
- package/dist/src/base/A-Command/A_Command.types.d.ts +0 -15
- package/dist/src/base/A-Command/A_Command.types.js +0 -3
- package/dist/src/base/A-Command/A_Command.types.js.map +0 -1
- package/dist/src/base/A-Command/context/A_Command.context.js.map +0 -1
- package/src/base/A-Command/A_Command.types.ts +0 -34
- /package/dist/src/{base/A-Command/A_Command.constants.d.ts → global/A-Command/A-Command.constants.d.ts} +0 -0
- /package/src/{base/A-Command/A_Command.constants.ts → global/A-Command/A-Command.constants.ts} +0 -0
- /package/src/{base → global}/A-Command/context/A_Command.context.ts +0 -0
|
@@ -106,6 +106,9 @@ export class A_Concept<
|
|
|
106
106
|
if (props.entities && props.entities.length)
|
|
107
107
|
props.entities.forEach(entity => this.Scope.register(entity))
|
|
108
108
|
|
|
109
|
+
if (props.commands && props.commands.length)
|
|
110
|
+
props.commands.forEach(command => this.Scope.register(command))
|
|
111
|
+
|
|
109
112
|
this.containers = props.containers || [];
|
|
110
113
|
}
|
|
111
114
|
|
|
@@ -4,6 +4,7 @@ import { A_Fragment } from "../A-Fragment/A-Fragment.class";
|
|
|
4
4
|
import { A_Entity } from "../A-Entity/A-Entity.class";
|
|
5
5
|
import { A_Component } from "../A-Component/A-Component.class";
|
|
6
6
|
import { A_TYPES__A_ExtendDecorator_BehaviorConfig } from "@adaas/a-concept/decorators/A-Feature/A-Feature.decorator.types";
|
|
7
|
+
import { A_Command } from "../A-Command/A-Command.class";
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
export enum A_TYPES__ConceptStage {
|
|
@@ -68,6 +69,15 @@ export interface A_TYPES__IConceptConstructor<
|
|
|
68
69
|
* [!] Note that these components will be available in all containers and fragments in the concept.
|
|
69
70
|
*/
|
|
70
71
|
components?: Array<{ new(...args: any[]): A_Component }>
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* A set of Commands available for all containers and fragments in the concept.
|
|
76
|
+
* These commands will be registered in the root scope of the concept.
|
|
77
|
+
*
|
|
78
|
+
* [!] Note that these commands will be available in all containers and fragments in the concept.
|
|
79
|
+
*/
|
|
80
|
+
commands?: Array<{ new(...args: any[]): A_Command }>
|
|
71
81
|
}
|
|
72
82
|
|
|
73
83
|
|
|
@@ -22,6 +22,8 @@ import { A_TYPES__ComponentMetaKey } from "../A-Component/A-Component.types";
|
|
|
22
22
|
import { A_TYPES__ConceptStage } from "../A-Concept/A_Concept.types";
|
|
23
23
|
import { A_TYPES__A_DefineDecorator_Meta } from "@adaas/a-concept/decorators/A-Feature/A-Feature.decorator.types";
|
|
24
24
|
import { A_CONSTANTS__DEFAULT_ENV_VARIABLES } from "@adaas/a-concept/constants/env.constants";
|
|
25
|
+
import { A_Command } from "../A-Command/A-Command.class";
|
|
26
|
+
import { A_TYPES__CommandMetaKey } from "../A-Command/A-Command.types";
|
|
25
27
|
|
|
26
28
|
|
|
27
29
|
|
|
@@ -47,6 +49,9 @@ export class A_Context {
|
|
|
47
49
|
protected features: WeakMap<A_Feature, A_Scope> = new WeakMap();
|
|
48
50
|
|
|
49
51
|
|
|
52
|
+
protected commands: WeakMap<A_Command, A_Scope> = new WeakMap();
|
|
53
|
+
|
|
54
|
+
|
|
50
55
|
/**
|
|
51
56
|
* Uses to store the scope of every element in the program.
|
|
52
57
|
*/
|
|
@@ -164,6 +169,11 @@ export class A_Context {
|
|
|
164
169
|
|
|
165
170
|
break;
|
|
166
171
|
|
|
172
|
+
case param1 instanceof A_Command:
|
|
173
|
+
instance.commands.set(param1, newScope);
|
|
174
|
+
|
|
175
|
+
break;
|
|
176
|
+
|
|
167
177
|
default:
|
|
168
178
|
throw new Error(`[!] A-Concept Context: Unknown type of the parameter.`);
|
|
169
179
|
}
|
|
@@ -356,6 +366,9 @@ export class A_Context {
|
|
|
356
366
|
case param1 instanceof A_Fragment:
|
|
357
367
|
return instance.registry.get(param1);
|
|
358
368
|
|
|
369
|
+
case param1 instanceof A_Command:
|
|
370
|
+
return instance.commands.get(param1);
|
|
371
|
+
|
|
359
372
|
default:
|
|
360
373
|
throw new Error(`[!] A-Concept Context: Unknown type of the parameter.`);
|
|
361
374
|
}
|
|
@@ -444,10 +457,13 @@ export class A_Context {
|
|
|
444
457
|
case component instanceof A_Container:
|
|
445
458
|
metaKey = A_TYPES__ContainerMetaKey.FEATURES
|
|
446
459
|
break;
|
|
447
|
-
case component instanceof A_Component:
|
|
460
|
+
case component instanceof A_Component:
|
|
448
461
|
metaKey = A_TYPES__ComponentMetaKey.FEATURES
|
|
449
|
-
}
|
|
450
462
|
break;
|
|
463
|
+
case component instanceof A_Command:
|
|
464
|
+
metaKey = A_TYPES__CommandMetaKey.FEATURES
|
|
465
|
+
break;
|
|
466
|
+
|
|
451
467
|
default:
|
|
452
468
|
throw new Error(`A-Feature cannot be defined on the ${component} level`);
|
|
453
469
|
}
|
|
@@ -499,7 +515,7 @@ export class A_Context {
|
|
|
499
515
|
* @returns
|
|
500
516
|
*/
|
|
501
517
|
static abstractionDefinition(
|
|
502
|
-
component: A_Component | A_Container | A_Entity,
|
|
518
|
+
component: A_Component | A_Container | A_Entity | A_Command,
|
|
503
519
|
abstraction: A_TYPES__ConceptStage,
|
|
504
520
|
scope: A_Scope
|
|
505
521
|
): A_TYPES__FeatureConstructor {
|
|
@@ -516,9 +532,11 @@ export class A_Context {
|
|
|
516
532
|
case component instanceof A_Container:
|
|
517
533
|
metaKey = A_TYPES__ContainerMetaKey.ABSTRACTIONS
|
|
518
534
|
break;
|
|
519
|
-
case component instanceof A_Component:
|
|
535
|
+
case component instanceof A_Component:
|
|
520
536
|
metaKey = A_TYPES__ComponentMetaKey.ABSTRACTIONS
|
|
521
|
-
|
|
537
|
+
break;
|
|
538
|
+
case component instanceof A_Command:
|
|
539
|
+
metaKey = A_TYPES__CommandMetaKey.ABSTRACTIONS
|
|
522
540
|
break;
|
|
523
541
|
default:
|
|
524
542
|
throw new Error(`A-Feature cannot be defined on the ${component} level`);
|
|
@@ -36,10 +36,7 @@ export class A_Entity<
|
|
|
36
36
|
* Entity Identifier that corresponds to the class name
|
|
37
37
|
*/
|
|
38
38
|
static get entity(): string {
|
|
39
|
-
return A_CommonHelper
|
|
40
|
-
.toUpperSnakeCase(this.name)
|
|
41
|
-
.toLocaleLowerCase()
|
|
42
|
-
.replace(/_/g, '-');
|
|
39
|
+
return A_CommonHelper.toKebabCase(this.name);
|
|
43
40
|
}
|
|
44
41
|
|
|
45
42
|
/**
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { A_Command } from "../A-Command/A-Command.class";
|
|
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_Feature } from "./A-Feature.class";
|
|
@@ -15,10 +16,10 @@ import { A_Feature } from "./A-Feature.class";
|
|
|
15
16
|
export class A_FeatureCaller {
|
|
16
17
|
|
|
17
18
|
|
|
18
|
-
protected _component: A_Component | A_Feature | A_Container;
|
|
19
|
+
protected _component: A_Component | A_Feature | A_Container | A_Command;
|
|
19
20
|
|
|
20
21
|
constructor(
|
|
21
|
-
component: A_Component | A_Feature | A_Container
|
|
22
|
+
component: A_Component | A_Feature | A_Container | A_Command
|
|
22
23
|
) {
|
|
23
24
|
this._component = component;
|
|
24
25
|
}
|
|
@@ -29,7 +30,7 @@ export class A_FeatureCaller {
|
|
|
29
30
|
*
|
|
30
31
|
* @returns
|
|
31
32
|
*/
|
|
32
|
-
resolve(): A_Component | A_Feature | A_Container {
|
|
33
|
+
resolve(): A_Component | A_Feature | A_Container | A_Command {
|
|
33
34
|
return this._component;
|
|
34
35
|
}
|
|
35
36
|
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
A_TYPES__A_InjectDecorator_EntityInjectionQuery,
|
|
13
13
|
A_TYPES__A_InjectDecorator_Injectable
|
|
14
14
|
} from "@adaas/a-concept/decorators/A-Inject/A-Inject.decorator.types";
|
|
15
|
+
import { A_Command } from "../A-Command/A-Command.class";
|
|
15
16
|
|
|
16
17
|
|
|
17
18
|
/**
|
|
@@ -33,6 +34,7 @@ export class A_Scope {
|
|
|
33
34
|
|
|
34
35
|
private _components: WeakMap<typeof A_Component.constructor, any> = new WeakMap();
|
|
35
36
|
private _fragments: WeakMap<typeof A_Fragment.constructor, any> = new WeakMap();
|
|
37
|
+
private _commands: Map<string, A_Command> = new Map();
|
|
36
38
|
private _entities: Map<string, A_Entity> = new Map();
|
|
37
39
|
|
|
38
40
|
private _parent?: A_Scope;
|
|
@@ -52,6 +54,7 @@ export class A_Scope {
|
|
|
52
54
|
components: [],
|
|
53
55
|
fragments: [],
|
|
54
56
|
entities: [],
|
|
57
|
+
commands: [],
|
|
55
58
|
};
|
|
56
59
|
|
|
57
60
|
|
|
@@ -90,6 +93,10 @@ export class A_Scope {
|
|
|
90
93
|
return this.params.components || [];
|
|
91
94
|
}
|
|
92
95
|
|
|
96
|
+
get commands() {
|
|
97
|
+
return this.params.commands || [];
|
|
98
|
+
}
|
|
99
|
+
|
|
93
100
|
get fragments() {
|
|
94
101
|
return this.params.fragments || [];
|
|
95
102
|
}
|
|
@@ -189,7 +196,7 @@ export class A_Scope {
|
|
|
189
196
|
has(
|
|
190
197
|
constructor: string
|
|
191
198
|
): boolean
|
|
192
|
-
has<T extends A_Fragment | A_Component | A_Entity>(
|
|
199
|
+
has<T extends A_Fragment | A_Component | A_Entity | A_Command>(
|
|
193
200
|
entity: T | string | (new (...args: any[]) => T)
|
|
194
201
|
): boolean {
|
|
195
202
|
|
|
@@ -221,7 +228,7 @@ export class A_Scope {
|
|
|
221
228
|
|
|
222
229
|
case typeof entity === 'function'
|
|
223
230
|
&& A_CommonHelper.isInheritedFrom(entity, A_Component): {
|
|
224
|
-
const found = this.
|
|
231
|
+
const found = this.components.includes(entity as { new(...args: any[]): A_Component });
|
|
225
232
|
|
|
226
233
|
if (!found && !!this._parent) {
|
|
227
234
|
return this._parent.has(entity as any);
|
|
@@ -248,6 +255,16 @@ export class A_Scope {
|
|
|
248
255
|
|
|
249
256
|
return found;
|
|
250
257
|
}
|
|
258
|
+
case typeof entity === 'function'
|
|
259
|
+
&& A_CommonHelper.isInheritedFrom(entity, A_Command): {
|
|
260
|
+
const found = this.commands.includes(entity as { new(...args: any[]): A_Command });
|
|
261
|
+
|
|
262
|
+
if (!found && !!this._parent)
|
|
263
|
+
return this._parent.has(entity as any);
|
|
264
|
+
|
|
265
|
+
return found;
|
|
266
|
+
}
|
|
267
|
+
|
|
251
268
|
|
|
252
269
|
default: {
|
|
253
270
|
return false;
|
|
@@ -295,19 +312,33 @@ export class A_Scope {
|
|
|
295
312
|
/**
|
|
296
313
|
* Allows to retrieve the constructor of the component or entity by its name
|
|
297
314
|
*
|
|
315
|
+
* [!] Notes:
|
|
316
|
+
* - In case of search for A-Entity please ensure that provided string corresponds to the static entity property of the class. [!] By default it's the kebab-case of the class name
|
|
317
|
+
* - In case of search for A_Command please ensure that provided string corresponds to the static code property of the class. [!] By default it's the kebab-case of the class name
|
|
318
|
+
* - In case of search for A_Component please ensure that provided string corresponds to the class name in PascalCase
|
|
298
319
|
*
|
|
299
320
|
* @param name
|
|
300
321
|
* @returns
|
|
301
322
|
*/
|
|
302
323
|
resolveConstructor<T extends A_Component | A_Entity>(name: string): new (...args: any[]) => T {
|
|
303
324
|
// Check components
|
|
304
|
-
const component = this.params.components.find(c => c.name === name);
|
|
325
|
+
const component = this.params.components.find(c => c.name === A_CommonHelper.toPascalCase(name));
|
|
305
326
|
if (component) return component as any;
|
|
306
327
|
|
|
307
328
|
// Check entities
|
|
308
|
-
const entity = this.params.entities.find(e => e.constructor.
|
|
329
|
+
const entity = this.params.entities.find(e => (e.constructor as any).entity === name
|
|
330
|
+
|| (e.constructor as any).name === A_CommonHelper.toPascalCase(name)
|
|
331
|
+
|| (e.constructor as any).entity === A_CommonHelper.toKebabCase(name)
|
|
332
|
+
);
|
|
309
333
|
if (entity) return entity.constructor as any;
|
|
310
334
|
|
|
335
|
+
// Check commands
|
|
336
|
+
const command = this.params.commands.find(c => (c as any).code === name
|
|
337
|
+
|| (c as any).name === A_CommonHelper.toPascalCase(name)
|
|
338
|
+
|| (c as any).code === A_CommonHelper.toKebabCase(name)
|
|
339
|
+
);
|
|
340
|
+
if (command) return command as any;
|
|
341
|
+
|
|
311
342
|
// If not found in current scope, check parent scope
|
|
312
343
|
if (!!this._parent) {
|
|
313
344
|
return this._parent.resolveConstructor(name);
|
|
@@ -371,6 +402,10 @@ export class A_Scope {
|
|
|
371
402
|
const component = this.params.components.find(c => c.name === name);
|
|
372
403
|
if (component) return this.resolveComponent(component);
|
|
373
404
|
|
|
405
|
+
// Check commands
|
|
406
|
+
const command = this.params.commands.find(c => c.name === name);
|
|
407
|
+
if (command) return this.resolveComponent(command);
|
|
408
|
+
|
|
374
409
|
// Check fragments
|
|
375
410
|
const fragment = this.params.fragments.find(f => f.constructor.name === name);
|
|
376
411
|
if (fragment) return this.resolveFragment(fragment.constructor as any);
|
|
@@ -436,10 +471,8 @@ export class A_Scope {
|
|
|
436
471
|
|
|
437
472
|
switch (true) {
|
|
438
473
|
case !instructions: {
|
|
439
|
-
|
|
440
474
|
const entities = Array.from(this._entities.values());
|
|
441
475
|
|
|
442
|
-
|
|
443
476
|
const found = entities.find(e => e instanceof entity);
|
|
444
477
|
|
|
445
478
|
switch (true) {
|
|
@@ -593,6 +626,31 @@ export class A_Scope {
|
|
|
593
626
|
}
|
|
594
627
|
|
|
595
628
|
|
|
629
|
+
/**
|
|
630
|
+
* Should be similar to resolveEntity but for commands
|
|
631
|
+
*
|
|
632
|
+
* @param command
|
|
633
|
+
*/
|
|
634
|
+
private resolveCommand<T extends A_Command>(command: {
|
|
635
|
+
new(...args: any[]): T
|
|
636
|
+
}): T {
|
|
637
|
+
const commands = Array.from(this._commands.values());
|
|
638
|
+
|
|
639
|
+
const found = commands.find(e => e instanceof command);
|
|
640
|
+
|
|
641
|
+
switch (true) {
|
|
642
|
+
case !!found:
|
|
643
|
+
return found as T;
|
|
644
|
+
|
|
645
|
+
case !found && !!this._parent:
|
|
646
|
+
return this._parent.resolveCommand(command);
|
|
647
|
+
|
|
648
|
+
default:
|
|
649
|
+
throw new Error(`Command ${command.name} not found in the scope ${this.name}`);
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
|
|
596
654
|
|
|
597
655
|
/**
|
|
598
656
|
* This method is used to register the component in the scope
|
|
@@ -600,7 +658,8 @@ export class A_Scope {
|
|
|
600
658
|
* @param fragment
|
|
601
659
|
*/
|
|
602
660
|
register<T extends A_Component>(component: new (...args: any[]) => T): void
|
|
603
|
-
register<T extends A_Entity>(
|
|
661
|
+
register<T extends A_Entity>(entity: new (...args: any[]) => T): void
|
|
662
|
+
register<T extends A_Command>(command: new (...args: any[]) => T): void
|
|
604
663
|
register(entity: A_Entity): void
|
|
605
664
|
register(component: A_Component): void
|
|
606
665
|
register(fragment: A_Fragment): void
|
|
@@ -610,6 +669,7 @@ export class A_Scope {
|
|
|
610
669
|
| A_Entity
|
|
611
670
|
| (new (...args: any[]) => A_Component)
|
|
612
671
|
| (new (...args: any[]) => A_Entity)
|
|
672
|
+
| (new (...args: any[]) => A_Command)
|
|
613
673
|
): void {
|
|
614
674
|
switch (true) {
|
|
615
675
|
case param1 instanceof A_Component && !this._components.has(param1.constructor): {
|
|
@@ -664,13 +724,21 @@ export class A_Scope {
|
|
|
664
724
|
break;
|
|
665
725
|
}
|
|
666
726
|
case typeof param1 === 'function' && A_CommonHelper.isInheritedFrom(param1, A_Entity): {
|
|
667
|
-
const
|
|
727
|
+
const allowedEntity = this.params.entities.find(e => e.constructor === param1);
|
|
668
728
|
|
|
669
|
-
if (!
|
|
729
|
+
if (!allowedEntity) {
|
|
670
730
|
this.params.entities.push(new (param1 as any)());
|
|
671
731
|
}
|
|
672
732
|
break;
|
|
673
733
|
}
|
|
734
|
+
case typeof param1 === 'function' && A_CommonHelper.isInheritedFrom(param1, A_Command): {
|
|
735
|
+
const allowedCommand = this.commands.find(c => c === param1);
|
|
736
|
+
|
|
737
|
+
if (!allowedCommand) {
|
|
738
|
+
this.commands.push(param1 as any);
|
|
739
|
+
}
|
|
740
|
+
break;
|
|
741
|
+
}
|
|
674
742
|
|
|
675
743
|
default:
|
|
676
744
|
if (param1 instanceof A_Entity)
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { A_Command } from "../A-Command/A-Command.class"
|
|
1
2
|
import { A_Component } from "../A-Component/A-Component.class"
|
|
2
3
|
import { A_Entity } from "../A-Entity/A-Entity.class"
|
|
3
4
|
import { A_Fragment } from "../A-Fragment/A-Fragment.class"
|
|
@@ -25,6 +26,12 @@ export type A_TYPES__ScopeConstructor = {
|
|
|
25
26
|
*/
|
|
26
27
|
entities: Array<A_Entity>
|
|
27
28
|
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* A set of Commands available in the Scope
|
|
32
|
+
*/
|
|
33
|
+
commands: Array<{ new(...args: any[]): A_Command }>
|
|
34
|
+
|
|
28
35
|
/**
|
|
29
36
|
* A list of Features/Lifecycle Hooks available in the Scope
|
|
30
37
|
*/
|
package/tests/A-Command.test.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
+
import './test.setup';
|
|
1
2
|
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
import {
|
|
5
|
-
import { A_Command } from "@adaas/a-concept/base/A-Command/A_Command.entity";
|
|
6
|
-
import { A_CommandContext } from "@adaas/a-concept/base/A-Command/context/A_Command.context";
|
|
3
|
+
import { A_CONSTANTS__A_Command_Status, A_CONSTANTS_A_Command_Features } from "@adaas/a-concept/global/A-Command/A-Command.constants";
|
|
4
|
+
import { A_Command } from "@adaas/a-concept/global/A-Command/A-Command.class";
|
|
5
|
+
import { A_CommandContext } from "@adaas/a-concept/global/A-Command/context/A_Command.context";
|
|
7
6
|
import { A_Inject } from "@adaas/a-concept/decorators/A-Inject/A-Inject.decorator";
|
|
8
7
|
import { A_Component } from "@adaas/a-concept/global/A-Component/A-Component.class";
|
|
9
8
|
import { A_Feature } from "@adaas/a-concept/global/A-Feature/A-Feature.class";
|
|
10
9
|
import { A_Scope } from "@adaas/a-concept/global/A-Scope/A-Scope.class";
|
|
11
10
|
import { A_Error } from "@adaas/a-utils";
|
|
11
|
+
import { A_Context } from "@adaas/a-concept/global/A-Context/A-Context.class";
|
|
12
12
|
|
|
13
13
|
jest.retryTimes(0);
|
|
14
14
|
|
|
@@ -17,7 +17,7 @@ describe('A-Command tests', () => {
|
|
|
17
17
|
it('Should Allow to create a command', async () => {
|
|
18
18
|
const command = new A_Command({});
|
|
19
19
|
expect(command).toBeInstanceOf(A_Command);
|
|
20
|
-
expect(command.Code).toBe('
|
|
20
|
+
expect(command.Code).toBe('a-command');
|
|
21
21
|
expect(command.id).toBeDefined();
|
|
22
22
|
expect(command.aseid).toBeDefined();
|
|
23
23
|
expect(command.Status).toBe(A_CONSTANTS__A_Command_Status.INITIALIZED);
|
|
@@ -58,12 +58,15 @@ describe('A-Command tests', () => {
|
|
|
58
58
|
it('Should allow to execute a command with custom logic', async () => {
|
|
59
59
|
|
|
60
60
|
// 1) create a scope
|
|
61
|
-
|
|
61
|
+
A_Context.reset();
|
|
62
|
+
|
|
62
63
|
// 2) create a new command
|
|
63
64
|
type resultType = { bar: string };
|
|
64
65
|
type invokeType = { foo: string };
|
|
65
66
|
class MyCommand extends A_Command<invokeType, resultType> { }
|
|
66
67
|
|
|
68
|
+
A_Context.root.register(MyCommand);
|
|
69
|
+
|
|
67
70
|
// 3) create a custom component with custom logic
|
|
68
71
|
class MyComponent extends A_Component {
|
|
69
72
|
|
|
@@ -76,11 +79,10 @@ describe('A-Command tests', () => {
|
|
|
76
79
|
}
|
|
77
80
|
|
|
78
81
|
// 4) register component in the scope
|
|
79
|
-
|
|
82
|
+
A_Context.root.register(MyComponent);
|
|
80
83
|
|
|
81
84
|
// 5) create a new command instance within the scope
|
|
82
85
|
const command = new MyCommand({ foo: 'bar' });
|
|
83
|
-
scope.register(command);
|
|
84
86
|
|
|
85
87
|
// 6) execute the command
|
|
86
88
|
await command.execute();
|
|
@@ -91,14 +93,16 @@ describe('A-Command tests', () => {
|
|
|
91
93
|
expect(command.Result).toEqual({ bar: 'baz' });
|
|
92
94
|
})
|
|
93
95
|
it('Should allow to fail a command with custom logic', async () => {
|
|
96
|
+
// 1) reset context to have a clean scope
|
|
97
|
+
A_Context.reset();
|
|
94
98
|
|
|
95
|
-
// 1) create a scope
|
|
96
|
-
const scope = new A_Scope({ name: 'TestScope' });
|
|
97
99
|
// 2) create a new command
|
|
98
100
|
type resultType = { bar: string };
|
|
99
101
|
type invokeType = { foo: string };
|
|
100
102
|
class MyCommand extends A_Command<invokeType, resultType> { }
|
|
101
103
|
|
|
104
|
+
A_Context.root.register(MyCommand);
|
|
105
|
+
|
|
102
106
|
// 3) create a custom component with custom logic
|
|
103
107
|
class MyComponent extends A_Component {
|
|
104
108
|
|
|
@@ -113,10 +117,9 @@ describe('A-Command tests', () => {
|
|
|
113
117
|
}
|
|
114
118
|
|
|
115
119
|
// 4) register component in the scope
|
|
116
|
-
|
|
120
|
+
A_Context.root.register(MyComponent);
|
|
117
121
|
// 5) create a new command instance within the scope
|
|
118
122
|
const command = new MyCommand({ foo: 'bar' });
|
|
119
|
-
scope.register(command);
|
|
120
123
|
|
|
121
124
|
// 6) execute the command
|
|
122
125
|
await command.execute();
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import './test.setup';
|
|
2
|
+
|
|
3
|
+
import { A_Command } from "@adaas/a-concept/global/A-Command/A-Command.class";
|
|
4
|
+
import { A_Component } from "@adaas/a-concept/global/A-Component/A-Component.class";
|
|
5
|
+
import { A_Concept } from "@adaas/a-concept/global/A-Concept/A_Concept.class";
|
|
6
|
+
import { A_Container } from "@adaas/a-concept/global/A-Container/A-Container.class";
|
|
7
|
+
import { A_Context } from "@adaas/a-concept/global/A-Context/A-Context.class";
|
|
8
|
+
import { A_Entity } from "@adaas/a-concept/global/A-Entity/A-Entity.class";
|
|
9
|
+
import { A_Fragment } from "@adaas/a-concept/global/A-Fragment/A-Fragment.class";
|
|
10
|
+
import { A_Scope } from "@adaas/a-concept/global/A-Scope/A-Scope.class";
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
jest.retryTimes(0);
|
|
14
|
+
|
|
15
|
+
describe('A-Concept tests', () => {
|
|
16
|
+
|
|
17
|
+
it('Should Allow to create a concept', async () => {
|
|
18
|
+
const concept = new A_Concept({ name: 'TestConcept' });
|
|
19
|
+
expect(concept).toBeInstanceOf(A_Concept);
|
|
20
|
+
expect(concept.Scope).toBeDefined();
|
|
21
|
+
expect(concept.Scope).toBeInstanceOf(A_Scope);
|
|
22
|
+
});
|
|
23
|
+
it('Should allow to load a concept', async () => {
|
|
24
|
+
const concept = new A_Concept({ name: 'TestConcept' });
|
|
25
|
+
await concept.load();
|
|
26
|
+
});
|
|
27
|
+
it('Should allow to run concept abstractions', async () => {
|
|
28
|
+
const concept = new A_Concept({ name: 'TestConcept' });
|
|
29
|
+
await concept.load();
|
|
30
|
+
await concept.start();
|
|
31
|
+
await concept.deploy();
|
|
32
|
+
await concept.build();
|
|
33
|
+
await concept.publish();
|
|
34
|
+
await concept.stop();
|
|
35
|
+
});
|
|
36
|
+
it('Should allow to provide all base entities to the concept', async () => {
|
|
37
|
+
A_Context.reset();
|
|
38
|
+
|
|
39
|
+
class MyCommand extends A_Command { }
|
|
40
|
+
class MyEntity extends A_Entity { }
|
|
41
|
+
class MyComponent extends A_Component { }
|
|
42
|
+
class MyContainer extends A_Container { }
|
|
43
|
+
class MyContext extends A_Fragment { }
|
|
44
|
+
|
|
45
|
+
const concept = new A_Concept({
|
|
46
|
+
name: 'TestConcept',
|
|
47
|
+
commands: [MyCommand],
|
|
48
|
+
entities: [new MyEntity()],
|
|
49
|
+
components: [MyComponent],
|
|
50
|
+
containers: [new MyContainer({ name: 'test' })],
|
|
51
|
+
fragments: [new MyContext({ name: 'test' })]
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
expect(concept.Scope.resolveConstructor('MyCommand')).toBe(MyCommand);
|
|
56
|
+
expect(concept.Scope.resolve(MyEntity)).toBeInstanceOf(MyEntity);
|
|
57
|
+
expect(concept.Scope.resolve(MyComponent)).toBeInstanceOf(MyComponent);
|
|
58
|
+
expect(concept.Scope.resolve(MyContext)).toBeInstanceOf(MyContext);
|
|
59
|
+
});
|
|
60
|
+
it('Should allow to separate entities by containers', async () => {
|
|
61
|
+
A_Context.reset();
|
|
62
|
+
|
|
63
|
+
class MyCommandA extends A_Command { }
|
|
64
|
+
class MyCommandB extends A_Command { }
|
|
65
|
+
class MyComponentA extends A_Component { }
|
|
66
|
+
class MyComponentB extends A_Component { }
|
|
67
|
+
class MyContainer extends A_Container { }
|
|
68
|
+
class MyContext extends A_Fragment { }
|
|
69
|
+
|
|
70
|
+
const containerA = new MyContainer({
|
|
71
|
+
name: 'test',
|
|
72
|
+
commands: [MyCommandA],
|
|
73
|
+
components: [MyComponentA]
|
|
74
|
+
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
const containerB = new MyContainer({
|
|
78
|
+
name: 'test2',
|
|
79
|
+
commands: [MyCommandB],
|
|
80
|
+
components: [MyComponentB]
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
const sharedContext = new MyContext({ name: 'test' })
|
|
84
|
+
|
|
85
|
+
const concept = new A_Concept({
|
|
86
|
+
name: 'TestConcept',
|
|
87
|
+
containers: [
|
|
88
|
+
containerA,
|
|
89
|
+
containerB
|
|
90
|
+
|
|
91
|
+
],
|
|
92
|
+
fragments: [sharedContext]
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
const containerAScope = A_Context.scope(containerA)
|
|
96
|
+
const containerBScope = A_Context.scope(containerB)
|
|
97
|
+
|
|
98
|
+
expect(containerAScope.resolveConstructor('MyCommandA')).toBe(MyCommandA);
|
|
99
|
+
expect(() => {
|
|
100
|
+
containerAScope.resolveConstructor('MyCommandB');
|
|
101
|
+
}).toThrow();
|
|
102
|
+
|
|
103
|
+
expect(containerBScope.resolveConstructor('MyCommandB')).toBe(MyCommandB);
|
|
104
|
+
expect(() => {
|
|
105
|
+
containerBScope.resolveConstructor('MyCommandA');
|
|
106
|
+
}).toThrow();
|
|
107
|
+
|
|
108
|
+
expect(concept.Scope.resolve(MyContext)).toEqual(sharedContext);
|
|
109
|
+
expect(concept.Scope.resolve(MyContext)).toEqual(sharedContext);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
});
|