@adaas/a-concept 0.0.55 → 0.0.57
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/.nvmrc +1 -1
- package/dist/src/base/A-Command/A_Command.constants.d.ts +12 -0
- package/dist/src/base/A-Command/A_Command.constants.js +17 -0
- package/dist/src/base/A-Command/A_Command.constants.js.map +1 -0
- package/dist/src/base/A-Command/A_Command.entity.d.ts +123 -0
- package/dist/src/base/A-Command/A_Command.entity.js +259 -0
- package/dist/src/base/A-Command/A_Command.entity.js.map +1 -0
- package/dist/src/base/A-Command/A_Command.types.d.ts +15 -0
- package/dist/src/base/A-Command/A_Command.types.js +3 -0
- package/dist/src/base/A-Command/A_Command.types.js.map +1 -0
- package/dist/src/base/A-Command/context/A_Command.context.d.ts +64 -0
- package/dist/src/base/A-Command/context/A_Command.context.js +85 -0
- package/dist/src/base/A-Command/context/A_Command.context.js.map +1 -0
- package/dist/src/base/A-Command/context/A_CommandFactory.context.js +2 -0
- package/dist/src/base/A-Command/context/A_CommandFactory.context.js.map +1 -0
- package/dist/src/base/A-Config/A-Config.context.d.ts +7 -6
- package/dist/src/base/A-Config/A-Config.context.js +2 -6
- package/dist/src/base/A-Config/A-Config.context.js.map +1 -1
- package/dist/src/base/A-Config/components/ConfigReader.component.js +2 -12
- package/dist/src/base/A-Config/components/ConfigReader.component.js.map +1 -1
- package/dist/src/constants/env.constants.d.ts +26 -0
- package/dist/src/constants/env.constants.js +40 -0
- package/dist/src/constants/env.constants.js.map +1 -0
- package/dist/src/decorators/A-Inject/A-Inject.decorator.d.ts +3 -3
- package/dist/src/decorators/A-Inject/A-Inject.decorator.types.d.ts +9 -10
- package/dist/src/global/A-Channel/A-Channel.class.d.ts +2 -0
- package/dist/src/global/A-Channel/A-Channel.class.js +2 -0
- package/dist/src/global/A-Channel/A-Channel.class.js.map +1 -1
- package/dist/src/global/A-Concept/A_Concept.class.d.ts +5 -3
- package/dist/src/global/A-Concept/A_Concept.class.js +32 -27
- package/dist/src/global/A-Concept/A_Concept.class.js.map +1 -1
- package/dist/src/global/A-Concept/A_Concept.meta.d.ts +1 -8
- package/dist/src/global/A-Concept/A_Concept.meta.js +1 -25
- package/dist/src/global/A-Concept/A_Concept.meta.js.map +1 -1
- package/dist/src/global/A-Concept/A_Concept.types.d.ts +10 -1
- package/dist/src/global/A-Container/A-Container.class.d.ts +5 -0
- package/dist/src/global/A-Container/A-Container.class.js +5 -0
- package/dist/src/global/A-Container/A-Container.class.js.map +1 -1
- package/dist/src/global/A-Context/A-Context.class.d.ts +19 -1
- package/dist/src/global/A-Context/A-Context.class.js +20 -0
- package/dist/src/global/A-Context/A-Context.class.js.map +1 -1
- package/dist/src/global/A-Entity/A-Entity.class.d.ts +124 -23
- package/dist/src/global/A-Entity/A-Entity.class.js +159 -49
- package/dist/src/global/A-Entity/A-Entity.class.js.map +1 -1
- package/dist/src/global/A-Scope/A-Scope.class.d.ts +7 -6
- package/dist/src/global/A-Scope/A-Scope.class.js +57 -21
- package/dist/src/global/A-Scope/A-Scope.class.js.map +1 -1
- package/dist/src/global/A-Stage/A-Stage.class.d.ts +3 -2
- package/dist/src/global/A-Stage/A-Stage.class.js +9 -6
- package/dist/src/global/A-Stage/A-Stage.class.js.map +1 -1
- package/dist/src/global/A-Stage/A-Stage.types.d.ts +1 -1
- package/dist/src/helpers/StepsManager.class.js +1 -1
- package/dist/src/helpers/StepsManager.class.js.map +1 -1
- package/examples/simple/components/A.component.ts +9 -2
- package/examples/simple/concept.ts +6 -0
- package/examples/simple/entities/EntityA.entity.ts +18 -0
- package/jest.config.ts +1 -1
- package/package.json +3 -3
- package/src/base/A-Command/A_Command.constants.ts +20 -0
- package/src/base/A-Command/A_Command.entity.ts +287 -0
- package/src/base/A-Command/A_Command.types.ts +34 -0
- package/src/base/A-Command/context/A_Command.context.ts +114 -0
- package/src/base/A-Command/context/A_CommandFactory.context.ts +0 -0
- package/src/base/A-Config/A-Config.context.ts +13 -17
- package/src/base/A-Config/components/ConfigReader.component.ts +2 -15
- package/src/constants/env.constants.ts +47 -0
- package/src/decorators/A-Inject/A-Inject.decorator.ts +3 -3
- package/src/decorators/A-Inject/A-Inject.decorator.types.ts +10 -9
- package/src/global/A-Channel/A-Channel.class.ts +2 -0
- package/src/global/A-Concept/A_Concept.class.ts +49 -32
- package/src/global/A-Concept/A_Concept.meta.ts +3 -41
- package/src/global/A-Concept/A_Concept.types.ts +6 -4
- package/src/global/A-Container/A-Container.class.ts +5 -2
- package/src/global/A-Context/A-Context.class.ts +44 -7
- package/src/global/A-Entity/A-Entity.class.ts +203 -73
- package/src/global/A-Scope/A-Scope.class.ts +86 -43
- package/src/global/A-Stage/A-Stage.class.ts +11 -7
- package/src/global/A-Stage/A-Stage.types.ts +1 -1
- package/src/helpers/StepsManager.class.ts +2 -2
- package/tests/A-Command.test.ts +130 -0
- package/tests/A-Component.test.ts +25 -0
- package/tests/A-Entity.test.ts +186 -0
- package/tests/A-Feature.test.ts +131 -0
- package/tests/A-Scope.test.ts +163 -0
- package/dist/src/constants/A_ConceptLifecycle.constants.js +0 -11
- package/dist/src/constants/A_ConceptLifecycle.constants.js.map +0 -1
- package/src/constants/A_ConceptLifecycle.constants.ts +0 -12
- package/tests/channel.ts +0 -213
- package/tests/context.test.ts +0 -124
- package/tests/default.test.ts +0 -159
- package/tests/log.ts +0 -102
- package/tests/polyfill.test.ts +0 -37
- /package/dist/src/{constants/A_ConceptLifecycle.constants.d.ts → base/A-Command/context/A_CommandFactory.context.d.ts} +0 -0
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
import { A_Entity } from "@adaas/a-concept/global/A-Entity/A-Entity.class";
|
|
2
|
+
import { A_TYPES__Command_Constructor, A_TYPES__Command_Listener, A_TYPES__Command_Serialized } from "./A_Command.types";
|
|
3
|
+
import { A_Error } from "@adaas/a-utils";
|
|
4
|
+
import { A_Scope } from "@adaas/a-concept/global/A-Scope/A-Scope.class";
|
|
5
|
+
import { A_Feature } from "@adaas/a-concept/global/A-Feature/A-Feature.class";
|
|
6
|
+
import { A_CommandContext } from "./context/A_Command.context";
|
|
7
|
+
import { A_CONSTANTS__A_Command_Event, A_CONSTANTS__A_Command_Status, A_CONSTANTS_A_Command_Features } from "./A_Command.constants";
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
export class A_Command<
|
|
11
|
+
InvokeType extends A_TYPES__Command_Constructor = A_TYPES__Command_Constructor,
|
|
12
|
+
ResultType extends Record<string, any> = Record<string, any>
|
|
13
|
+
> extends A_Entity<
|
|
14
|
+
InvokeType,
|
|
15
|
+
A_TYPES__Command_Serialized<ResultType>
|
|
16
|
+
> {
|
|
17
|
+
|
|
18
|
+
protected _scope!: A_Scope;
|
|
19
|
+
protected _result?: ResultType;
|
|
20
|
+
protected _errors?: Set<A_Error>;
|
|
21
|
+
|
|
22
|
+
protected _params!: InvokeType;
|
|
23
|
+
protected _status!: A_CONSTANTS__A_Command_Status
|
|
24
|
+
|
|
25
|
+
protected _listeners: Map<A_CONSTANTS__A_Command_Event, Set<A_TYPES__Command_Listener<ResultType>>> = new Map();
|
|
26
|
+
|
|
27
|
+
protected _startTime?: Date;
|
|
28
|
+
protected _endTime?: Date
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Execution Duration in milliseconds
|
|
32
|
+
*/
|
|
33
|
+
get Duration() {
|
|
34
|
+
return this._endTime && this._startTime
|
|
35
|
+
? this._endTime.getTime() - this._startTime.getTime()
|
|
36
|
+
: this._startTime
|
|
37
|
+
? new Date().getTime() - this._startTime.getTime()
|
|
38
|
+
: undefined;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Command Execution A-Scope that inherits from scope where command was created
|
|
44
|
+
*
|
|
45
|
+
* Command execution context is stored in A_CommandContext fragment within this scope
|
|
46
|
+
*/
|
|
47
|
+
get Scope(): A_Scope {
|
|
48
|
+
return this._scope;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Unique code identifying the command type
|
|
53
|
+
* Example: 'user.create', 'task.complete', etc.
|
|
54
|
+
*
|
|
55
|
+
*/
|
|
56
|
+
get Code(): string {
|
|
57
|
+
return (this.constructor as typeof A_Command).name;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Current status of the command
|
|
61
|
+
*/
|
|
62
|
+
get Status(): A_CONSTANTS__A_Command_Status {
|
|
63
|
+
return this._status;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Start time of the command execution
|
|
67
|
+
*/
|
|
68
|
+
get StartedAt(): Date | undefined {
|
|
69
|
+
return this._startTime;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* End time of the command execution
|
|
73
|
+
*/
|
|
74
|
+
get EndedAt(): Date | undefined {
|
|
75
|
+
return this._endTime;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Result of the command execution stored in the context
|
|
79
|
+
*/
|
|
80
|
+
get Result(): ResultType | undefined {
|
|
81
|
+
return this._result;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Errors encountered during the command execution stored in the context
|
|
85
|
+
*/
|
|
86
|
+
get Errors(): Set<A_Error> | undefined {
|
|
87
|
+
return this._errors;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Parameters used to invoke the command
|
|
91
|
+
*/
|
|
92
|
+
get Params(): InvokeType {
|
|
93
|
+
return this._params;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
*
|
|
99
|
+
* A-Command represents an executable command with a specific code and parameters.
|
|
100
|
+
* It can be executed within a given scope and stores execution results and errors.
|
|
101
|
+
*
|
|
102
|
+
*
|
|
103
|
+
* A-Command should be context independent and execution logic should be based on attached components
|
|
104
|
+
*
|
|
105
|
+
* @param code
|
|
106
|
+
* @param params
|
|
107
|
+
*/
|
|
108
|
+
constructor(
|
|
109
|
+
/**
|
|
110
|
+
* Command invocation parameters
|
|
111
|
+
*/
|
|
112
|
+
params: InvokeType | A_TYPES__Command_Serialized<ResultType>
|
|
113
|
+
) {
|
|
114
|
+
super(params as any);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
// --------------------------------------------------------------------------
|
|
119
|
+
// A-Command Core Features
|
|
120
|
+
// --------------------------------------------------------------------------
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Executes the command logic.
|
|
125
|
+
*/
|
|
126
|
+
@A_Feature.Define()
|
|
127
|
+
async [A_CONSTANTS_A_Command_Features.EXECUTE](): Promise<any> {
|
|
128
|
+
this._status = A_CONSTANTS__A_Command_Status.IN_PROGRESS;
|
|
129
|
+
this._startTime = new Date();
|
|
130
|
+
try {
|
|
131
|
+
await this.call('execute', this._scope);
|
|
132
|
+
await this.complete();
|
|
133
|
+
} catch (error) {
|
|
134
|
+
await this.fail();
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Marks the command as completed
|
|
140
|
+
*/
|
|
141
|
+
@A_Feature.Define()
|
|
142
|
+
async [A_CONSTANTS_A_Command_Features.COMPLETE]() {
|
|
143
|
+
this._status = A_CONSTANTS__A_Command_Status.COMPLETED;
|
|
144
|
+
this._endTime = new Date();
|
|
145
|
+
this._result = this.Scope.resolve(A_CommandContext).toJSON() as ResultType;
|
|
146
|
+
|
|
147
|
+
this.call('complete', this._scope);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Marks the command as failed
|
|
153
|
+
*/
|
|
154
|
+
@A_Feature.Define()
|
|
155
|
+
async [A_CONSTANTS_A_Command_Features.FAIL]() {
|
|
156
|
+
this._status = A_CONSTANTS__A_Command_Status.FAILED;
|
|
157
|
+
this._endTime = new Date();
|
|
158
|
+
this._errors = this.Scope.resolve(A_CommandContext).Errors;
|
|
159
|
+
|
|
160
|
+
this.call('fail', this._scope);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
// --------------------------------------------------------------------------
|
|
165
|
+
// A-Command Event-Emitter methods
|
|
166
|
+
// --------------------------------------------------------------------------
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Registers an event listener for a specific event
|
|
170
|
+
*
|
|
171
|
+
* @param event
|
|
172
|
+
* @param listener
|
|
173
|
+
*/
|
|
174
|
+
on(event: A_CONSTANTS__A_Command_Event, listener: A_TYPES__Command_Listener<ResultType>) {
|
|
175
|
+
if (!this._listeners.has(event)) {
|
|
176
|
+
this._listeners.set(event, new Set());
|
|
177
|
+
}
|
|
178
|
+
this._listeners.get(event)!.add(listener);
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Removes an event listener for a specific event
|
|
182
|
+
*
|
|
183
|
+
* @param event
|
|
184
|
+
* @param listener
|
|
185
|
+
*/
|
|
186
|
+
off(event: A_CONSTANTS__A_Command_Event, listener: A_TYPES__Command_Listener<ResultType>) {
|
|
187
|
+
this._listeners.get(event)?.delete(listener);
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Emits an event to all registered listeners
|
|
191
|
+
*
|
|
192
|
+
* @param event
|
|
193
|
+
*/
|
|
194
|
+
emit(event: A_CONSTANTS__A_Command_Event) {
|
|
195
|
+
this._listeners.get(event)?.forEach(listener => {
|
|
196
|
+
listener(this);
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
// --------------------------------------------------------------------------
|
|
202
|
+
// A-Entity Base Class Overrides
|
|
203
|
+
// --------------------------------------------------------------------------
|
|
204
|
+
// Serialization / Deserialization
|
|
205
|
+
// -------------------------------------------------------------------------
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Allows to create a Command instance from new data
|
|
210
|
+
*
|
|
211
|
+
* @param newEntity
|
|
212
|
+
*/
|
|
213
|
+
fromNew(newEntity: InvokeType): void {
|
|
214
|
+
super.fromNew(newEntity);
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
this._params = newEntity;
|
|
218
|
+
|
|
219
|
+
this._status = A_CONSTANTS__A_Command_Status.INITIALIZED;
|
|
220
|
+
|
|
221
|
+
this._scope = new A_Scope({
|
|
222
|
+
name: `a-command-scope::${this.id}`,
|
|
223
|
+
fragments: [
|
|
224
|
+
new A_CommandContext<ResultType>()
|
|
225
|
+
]
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Allows to convert serialized data to Command instance
|
|
233
|
+
*
|
|
234
|
+
* [!] By default it omits params as they are not stored in the serialized data
|
|
235
|
+
*
|
|
236
|
+
* @param serialized
|
|
237
|
+
*/
|
|
238
|
+
fromJSON(serialized: A_TYPES__Command_Serialized<ResultType>): void {
|
|
239
|
+
super.fromJSON(serialized);
|
|
240
|
+
if (serialized.startedAt) this._startTime = new Date(serialized.startedAt);
|
|
241
|
+
if (serialized.endedAt) this._endTime = new Date(serialized.endedAt);
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
const context = new A_CommandContext<ResultType>();
|
|
245
|
+
|
|
246
|
+
this._scope = new A_Scope({
|
|
247
|
+
name: `a-command-scope::${this.id}`,
|
|
248
|
+
fragments: [
|
|
249
|
+
context
|
|
250
|
+
]
|
|
251
|
+
})
|
|
252
|
+
// Restore result and errors in the context
|
|
253
|
+
if (serialized.result) {
|
|
254
|
+
Object.entries(serialized.result).forEach(([key, value]) => {
|
|
255
|
+
context.save(key, value);
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
if (serialized.errors) {
|
|
260
|
+
serialized.errors.forEach(err => {
|
|
261
|
+
context.error(new A_Error(err));
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
this._status = serialized.status || A_CONSTANTS__A_Command_Status.INITIALIZED;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Converts the Command instance to a plain object
|
|
271
|
+
*
|
|
272
|
+
* @returns
|
|
273
|
+
*/
|
|
274
|
+
toJSON(): A_TYPES__Command_Serialized<ResultType> {
|
|
275
|
+
return {
|
|
276
|
+
...super.toJSON(),
|
|
277
|
+
code: this.Code,
|
|
278
|
+
status: this._status,
|
|
279
|
+
startedAt: this._startTime ? this._startTime.toISOString() : undefined,
|
|
280
|
+
endedAt: this._endTime ? this._endTime.toISOString() : undefined,
|
|
281
|
+
duration: this.Duration,
|
|
282
|
+
result: this.Result,
|
|
283
|
+
errors: this.Errors ? Array.from(this.Errors).map(err => err.toJSON()) : undefined
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { A_TYPES__Entity_JSON } from "@adaas/a-concept/global/A-Entity/A-Entity.types";
|
|
2
|
+
import { A_CommandContext } from "./context/A_Command.context";
|
|
3
|
+
import { A_Command } from "./A_Command.entity";
|
|
4
|
+
import { A_CONSTANTS__A_Command_Status } from "./A_Command.constants";
|
|
5
|
+
import { A_Error, A_TYPES__Error } from "@adaas/a-utils";
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
export type A_TYPES__Command_Constructor = {
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
export type A_TYPES__Command_Serialized<
|
|
15
|
+
ResultType extends Record<string, any> = Record<string, any>
|
|
16
|
+
> = {
|
|
17
|
+
code: string;
|
|
18
|
+
status: A_CONSTANTS__A_Command_Status;
|
|
19
|
+
|
|
20
|
+
startedAt?: string;
|
|
21
|
+
endedAt?: string;
|
|
22
|
+
duration?: number;
|
|
23
|
+
|
|
24
|
+
result?: ResultType;
|
|
25
|
+
errors?: Array<A_TYPES__Error>;
|
|
26
|
+
|
|
27
|
+
} & A_TYPES__Entity_JSON
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
export type A_TYPES__Command_Listener<
|
|
33
|
+
T extends Record<string, any> = Record<string, any>
|
|
34
|
+
> = (command?: A_Command<any, T>) => void;
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { A_Fragment } from "@adaas/a-concept/global/A-Fragment/A-Fragment.class";
|
|
2
|
+
import { A_Error } from "@adaas/a-utils";
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
export class A_CommandContext<
|
|
6
|
+
T extends Record<string, any> = Record<string, any>
|
|
7
|
+
> extends A_Fragment {
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Internal storage of all intermediate values
|
|
12
|
+
*/
|
|
13
|
+
protected _memory: Map<keyof T, T[keyof T]>;
|
|
14
|
+
/**
|
|
15
|
+
* Errors encountered during the execution
|
|
16
|
+
*/
|
|
17
|
+
protected _errors: Set<A_Error>;
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* ExecutionContext for the A-Command
|
|
23
|
+
*
|
|
24
|
+
*/
|
|
25
|
+
constructor(initialValues: T = {} as T) {
|
|
26
|
+
super();
|
|
27
|
+
this._memory = new Map(Object.entries(initialValues));
|
|
28
|
+
this._errors = new Set();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
get Errors(): Set<A_Error> | undefined {
|
|
33
|
+
return this._errors.size > 0 ? this._errors : undefined;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Verifies that all required keys are present in the proxy values
|
|
39
|
+
*
|
|
40
|
+
* @param requiredKeys
|
|
41
|
+
* @returns
|
|
42
|
+
*/
|
|
43
|
+
verifyPrerequisites(
|
|
44
|
+
requiredKeys: Array<keyof T>
|
|
45
|
+
): boolean {
|
|
46
|
+
return requiredKeys.every(key => this._memory.has(key));
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Adds an error to the context
|
|
51
|
+
*
|
|
52
|
+
* @param error
|
|
53
|
+
*/
|
|
54
|
+
error(error: A_Error): void {
|
|
55
|
+
this._errors.add(error);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Saves a value in the context memory
|
|
60
|
+
*
|
|
61
|
+
* @param key
|
|
62
|
+
* @param value
|
|
63
|
+
*/
|
|
64
|
+
save<K extends keyof T>(
|
|
65
|
+
/**
|
|
66
|
+
* Key to save the value under
|
|
67
|
+
*/
|
|
68
|
+
key: K,
|
|
69
|
+
/**
|
|
70
|
+
* Value to save
|
|
71
|
+
*/
|
|
72
|
+
value: T[K]
|
|
73
|
+
): void {
|
|
74
|
+
this._memory.set(key, value);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Removes a value from the context memory by key
|
|
80
|
+
*
|
|
81
|
+
* @param key
|
|
82
|
+
*/
|
|
83
|
+
drop(key: keyof T): void {
|
|
84
|
+
this._memory.delete(key);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Clears all stored values in the context memory
|
|
89
|
+
*/
|
|
90
|
+
clear(): void {
|
|
91
|
+
this._memory.clear();
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Converts all stored values to a plain object
|
|
97
|
+
*
|
|
98
|
+
* [!] By default uses all saved in memory values
|
|
99
|
+
*
|
|
100
|
+
* @returns
|
|
101
|
+
*/
|
|
102
|
+
toJSON(): Record<string, any> {
|
|
103
|
+
const obj: Record<string, any> = {};
|
|
104
|
+
|
|
105
|
+
this._memory.forEach((value, key) => {
|
|
106
|
+
obj[key as string] =
|
|
107
|
+
typeof value === 'object' && value !== null && 'toJSON' in value && typeof value.toJSON === 'function'
|
|
108
|
+
? value.toJSON()
|
|
109
|
+
: value;
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
return obj;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
File without changes
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { A_CommonHelper, A_TYPES__Required } from "@adaas/a-utils";
|
|
2
2
|
import { A_TYPES__ConfigContainerConstructor } from "./A-Config.types";
|
|
3
3
|
import { A_Fragment } from "@adaas/a-concept/global/A-Fragment/A-Fragment.class";
|
|
4
|
+
import { A_CONSTANTS__DEFAULT_ENV_VARIABLES_ARRAY, A_TYPES__ConceptENVVariables } from "@adaas/a-concept/constants/env.constants";
|
|
4
5
|
|
|
5
6
|
|
|
6
7
|
export class A_Config<
|
|
7
|
-
T extends string =
|
|
8
|
+
T extends string = A_TYPES__ConceptENVVariables
|
|
8
9
|
> extends A_Fragment {
|
|
9
10
|
|
|
10
11
|
config: A_TYPES__ConfigContainerConstructor<T>;
|
|
@@ -14,12 +15,7 @@ export class A_Config<
|
|
|
14
15
|
|
|
15
16
|
CONFIG_PROPERTIES: T[] = [];
|
|
16
17
|
|
|
17
|
-
protected DEFAULT_ALLOWED_TO_READ_PROPERTIES =
|
|
18
|
-
'CONFIG_SDK_VALIDATION',
|
|
19
|
-
'CONFIG_VERBOSE',
|
|
20
|
-
'CONFIG_IGNORE_ERRORS',
|
|
21
|
-
'CONCEPT_ROOT_FOLDER',
|
|
22
|
-
] as const;
|
|
18
|
+
protected DEFAULT_ALLOWED_TO_READ_PROPERTIES = A_CONSTANTS__DEFAULT_ENV_VARIABLES_ARRAY;
|
|
23
19
|
|
|
24
20
|
|
|
25
21
|
constructor(
|
|
@@ -72,24 +68,24 @@ export class A_Config<
|
|
|
72
68
|
*
|
|
73
69
|
* @param variables
|
|
74
70
|
*/
|
|
75
|
-
set
|
|
71
|
+
set(
|
|
76
72
|
variables: Array<{
|
|
77
|
-
property:
|
|
73
|
+
property: T | typeof A_CONSTANTS__DEFAULT_ENV_VARIABLES_ARRAY[number],
|
|
78
74
|
value: any
|
|
79
75
|
}>
|
|
80
76
|
)
|
|
81
|
-
set
|
|
82
|
-
variables: Record<
|
|
77
|
+
set(
|
|
78
|
+
variables: Partial<Record<T | typeof A_CONSTANTS__DEFAULT_ENV_VARIABLES_ARRAY[number], any>>
|
|
83
79
|
)
|
|
84
|
-
set
|
|
85
|
-
property:
|
|
80
|
+
set(
|
|
81
|
+
property: T | typeof A_CONSTANTS__DEFAULT_ENV_VARIABLES_ARRAY[number],
|
|
86
82
|
value: any
|
|
87
83
|
)
|
|
88
|
-
set
|
|
89
|
-
property:
|
|
90
|
-
property:
|
|
84
|
+
set(
|
|
85
|
+
property: T | typeof A_CONSTANTS__DEFAULT_ENV_VARIABLES_ARRAY[number] | Array<{
|
|
86
|
+
property: T | typeof A_CONSTANTS__DEFAULT_ENV_VARIABLES_ARRAY[number],
|
|
91
87
|
value: any
|
|
92
|
-
}> | Record<
|
|
88
|
+
}> | Partial<Record<T | typeof A_CONSTANTS__DEFAULT_ENV_VARIABLES_ARRAY[number], any>>,
|
|
93
89
|
value?: any
|
|
94
90
|
) {
|
|
95
91
|
const array = Array.isArray(property)
|
|
@@ -22,13 +22,13 @@ export class ConfigReader extends A_Component {
|
|
|
22
22
|
@A_Inject(A_Config) config: A_Config,
|
|
23
23
|
) {
|
|
24
24
|
|
|
25
|
-
const data = this.read(config.CONFIG_PROPERTIES);
|
|
25
|
+
const data = await this.read(config.CONFIG_PROPERTIES);
|
|
26
26
|
|
|
27
27
|
config.set(data);
|
|
28
28
|
|
|
29
29
|
const rootDir = await this.getProjectRoot();
|
|
30
30
|
|
|
31
|
-
config.set('
|
|
31
|
+
config.set('A_CONCEPT_ROOT_FOLDER', rootDir);
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
|
|
@@ -59,19 +59,6 @@ export class ConfigReader extends A_Component {
|
|
|
59
59
|
* @returns {string|null} - The path to the root directory or null if package.json is not found
|
|
60
60
|
*/
|
|
61
61
|
protected async getProjectRoot(startPath = __dirname) {
|
|
62
|
-
// let currentPath = startPath;
|
|
63
|
-
|
|
64
|
-
// const fs = await A_Polyfills.fs();
|
|
65
|
-
|
|
66
|
-
// while (!fs.existsSync(`${currentPath}/package.json`)) {
|
|
67
|
-
// const parentPath = currentPath.substring(0, currentPath.lastIndexOf('/'));
|
|
68
|
-
// if (parentPath === currentPath || parentPath === '') {
|
|
69
|
-
// // Reached the root of the filesystem without finding package.json
|
|
70
|
-
// return null;
|
|
71
|
-
// }
|
|
72
|
-
// currentPath = parentPath;
|
|
73
|
-
// }
|
|
74
|
-
|
|
75
62
|
return process.cwd();
|
|
76
63
|
}
|
|
77
64
|
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export const A_CONSTANTS__DEFAULT_ENV_VARIABLES = {
|
|
2
|
+
// ----------------------------------------------------------
|
|
3
|
+
// A-Concept Core Environment Variables
|
|
4
|
+
// ----------------------------------------------------------
|
|
5
|
+
// These environment variables are used by A-Concept core to configure the application
|
|
6
|
+
// ----------------------------------------------------------
|
|
7
|
+
/**
|
|
8
|
+
* Namespace of the application
|
|
9
|
+
* [!] Provided name will be used for all aseids in the application by default
|
|
10
|
+
*/
|
|
11
|
+
A_CONCEPT_NAMESPACE: 'A_CONCEPT_NAMESPACE',
|
|
12
|
+
/**
|
|
13
|
+
* Default scope of the application
|
|
14
|
+
* [!] Provided name will be used for all aseids in the application by default
|
|
15
|
+
*/
|
|
16
|
+
A_CONCEPT_DEFAULT_SCOPE: 'A_CONCEPT_DEFAULT_SCOPE',
|
|
17
|
+
/**
|
|
18
|
+
* Environment of the application e.g. development, production, staging
|
|
19
|
+
*/
|
|
20
|
+
A_CONCEPT_ENVIRONMENT: 'A_CONCEPT_ENVIRONMENT',
|
|
21
|
+
/**
|
|
22
|
+
* Root folder of the application
|
|
23
|
+
* [!] Automatically set by A-Concept when the application starts
|
|
24
|
+
*/
|
|
25
|
+
A_CONCEPT_ROOT_FOLDER: 'A_CONCEPT_ROOT_FOLDER',
|
|
26
|
+
|
|
27
|
+
CONFIG_SDK_VALIDATION: 'CONFIG_SDK_VALIDATION',
|
|
28
|
+
CONFIG_VERBOSE: 'CONFIG_VERBOSE',
|
|
29
|
+
CONFIG_IGNORE_ERRORS: 'CONFIG_IGNORE_ERRORS',
|
|
30
|
+
} as const
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
export type A_TYPES__ConceptENVVariables = (typeof A_CONSTANTS__DEFAULT_ENV_VARIABLES)[keyof typeof A_CONSTANTS__DEFAULT_ENV_VARIABLES];
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
export const A_CONSTANTS__DEFAULT_ENV_VARIABLES_ARRAY = [
|
|
38
|
+
A_CONSTANTS__DEFAULT_ENV_VARIABLES.A_CONCEPT_NAMESPACE,
|
|
39
|
+
A_CONSTANTS__DEFAULT_ENV_VARIABLES.A_CONCEPT_ENVIRONMENT,
|
|
40
|
+
A_CONSTANTS__DEFAULT_ENV_VARIABLES.A_CONCEPT_ROOT_FOLDER,
|
|
41
|
+
A_CONSTANTS__DEFAULT_ENV_VARIABLES.CONFIG_VERBOSE,
|
|
42
|
+
A_CONSTANTS__DEFAULT_ENV_VARIABLES.CONFIG_IGNORE_ERRORS,
|
|
43
|
+
] as const;
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
|
|
@@ -46,9 +46,9 @@ export function A_Inject(
|
|
|
46
46
|
fragment: { new(...args: any[]): A_Fragment }
|
|
47
47
|
): A_TYPES__A_InjectDecoratorReturn
|
|
48
48
|
|
|
49
|
-
export function A_Inject(
|
|
50
|
-
entity: { new(...args: any[]):
|
|
51
|
-
config: Partial<A_TYPES__A_InjectDecorator_EntityInjectionInstructions
|
|
49
|
+
export function A_Inject<T extends A_Entity>(
|
|
50
|
+
entity: { new(...args: any[]): T },
|
|
51
|
+
config: Partial<A_TYPES__A_InjectDecorator_EntityInjectionInstructions<T>>
|
|
52
52
|
): A_TYPES__A_InjectDecoratorReturn
|
|
53
53
|
|
|
54
54
|
// ====================== BASE FUNCTION ======================
|
|
@@ -2,6 +2,7 @@ import { A_Component } from "@adaas/a-concept/global/A-Component/A-Component.cla
|
|
|
2
2
|
import { A_Container } from "@adaas/a-concept/global/A-Container/A-Container.class";
|
|
3
3
|
import { A_Entity } from "@adaas/a-concept/global/A-Entity/A-Entity.class";
|
|
4
4
|
import { A_Feature } from "@adaas/a-concept/global/A-Feature/A-Feature.class";
|
|
5
|
+
import { A_FeatureCaller } from "@adaas/a-concept/global/A-Feature/A-FeatureCaller.class";
|
|
5
6
|
import { A_Fragment } from "@adaas/a-concept/global/A-Fragment/A-Fragment.class";
|
|
6
7
|
import { A_Scope } from "@adaas/a-concept/global/A-Scope/A-Scope.class";
|
|
7
8
|
import { ASEID } from "@adaas/a-utils";
|
|
@@ -60,21 +61,21 @@ export type A_TYPES__A_InjectDecorator_Injectable =
|
|
|
60
61
|
| { new(...args: any[]): A_Container }
|
|
61
62
|
| { new(...args: any[]): A_Scope }
|
|
62
63
|
| { new(...args: any[]): A_Feature }
|
|
63
|
-
| { new(...args: any[]): A_Entity }
|
|
64
|
+
| { new(...args: any[]): A_Entity }
|
|
65
|
+
| { new(...args: any[]): A_FeatureCaller };
|
|
64
66
|
|
|
65
67
|
|
|
66
|
-
export type A_TYPES__A_InjectDecorator_EntityInjectionInstructions = {
|
|
67
|
-
query: Partial<A_TYPES__A_InjectDecorator_EntityInjectionQuery
|
|
68
|
+
export type A_TYPES__A_InjectDecorator_EntityInjectionInstructions<T extends A_Entity = A_Entity> = {
|
|
69
|
+
query: Partial<A_TYPES__A_InjectDecorator_EntityInjectionQuery<T>>,
|
|
68
70
|
pagination: Partial<A_TYPES__A_InjectDecorator_EntityInjectionPagination>
|
|
69
71
|
}
|
|
70
72
|
|
|
71
73
|
|
|
72
|
-
export type A_TYPES__A_InjectDecorator_EntityInjectionQuery = {
|
|
73
|
-
aseid: string
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
}
|
|
74
|
+
export type A_TYPES__A_InjectDecorator_EntityInjectionQuery<T extends A_Entity = A_Entity> = {
|
|
75
|
+
aseid: string,
|
|
76
|
+
} & {
|
|
77
|
+
[key in keyof T]?: any
|
|
78
|
+
};
|
|
78
79
|
|
|
79
80
|
|
|
80
81
|
export type A_TYPES__A_InjectDecorator_EntityInjectionPagination = {
|
|
@@ -4,6 +4,8 @@ import { A_TYPES__A_ChannelAggregated, A_TYPES__A_ChannelAggregateMethods, A_TYP
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
+
* [!] DEPRECATED - use simply A_Component instead
|
|
8
|
+
*
|
|
7
9
|
* A_Channel is an abstraction over any Communication Type from event emitters to message queues, HTTP requests, etc.
|
|
8
10
|
*
|
|
9
11
|
* A_Channel uses to connect Containers between each other. When
|