@adaas/a-utils 0.0.8 → 0.1.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 (172) hide show
  1. package/.nvmrc +1 -1
  2. package/dist/index.d.ts +21 -14
  3. package/dist/index.js +53 -20
  4. package/dist/index.js.map +1 -1
  5. package/dist/src/constants/errors.constants.d.ts +0 -65
  6. package/dist/src/constants/errors.constants.js +0 -72
  7. package/dist/src/constants/errors.constants.js.map +1 -1
  8. package/dist/src/lib/A-Channel/A-Channel.component.d.ts +3 -0
  9. package/dist/src/lib/A-Channel/A-Channel.component.js +8 -0
  10. package/dist/src/lib/A-Channel/A-Channel.component.js.map +1 -0
  11. package/dist/src/lib/A-Channel/A-Channel.error.d.ts +3 -0
  12. package/dist/src/lib/A-Channel/A-Channel.error.js +8 -0
  13. package/dist/src/lib/A-Channel/A-Channel.error.js.map +1 -0
  14. package/dist/src/lib/A-Channel/A-Channel.types.d.ts +0 -0
  15. package/dist/src/lib/A-Channel/A-Channel.types.js +2 -0
  16. package/dist/src/lib/A-Channel/A-Channel.types.js.map +1 -0
  17. package/dist/src/lib/A-Command/A-Command.constants.d.ts +22 -0
  18. package/dist/src/lib/A-Command/A-Command.constants.js +28 -0
  19. package/dist/src/lib/A-Command/A-Command.constants.js.map +1 -0
  20. package/dist/src/lib/A-Command/A-Command.entity.d.ts +133 -0
  21. package/dist/src/lib/A-Command/A-Command.entity.js +273 -0
  22. package/dist/src/lib/A-Command/A-Command.entity.js.map +1 -0
  23. package/dist/src/lib/A-Command/A-Command.error.d.ts +3 -0
  24. package/dist/src/lib/A-Command/A-Command.error.js +8 -0
  25. package/dist/src/lib/A-Command/A-Command.error.js.map +1 -0
  26. package/dist/src/lib/A-Command/A-Command.types.d.ts +73 -0
  27. package/dist/src/lib/A-Command/A-Command.types.js +4 -0
  28. package/dist/src/lib/A-Command/A-Command.types.js.map +1 -0
  29. package/dist/src/lib/A-Config/A-Config.constants.d.ts +3 -0
  30. package/dist/src/lib/A-Config/A-Config.constants.js +6 -0
  31. package/dist/src/lib/A-Config/A-Config.constants.js.map +1 -0
  32. package/dist/src/lib/A-Config/A-Config.container.d.ts +8 -0
  33. package/dist/src/lib/A-Config/A-Config.container.js +75 -0
  34. package/dist/src/lib/A-Config/A-Config.container.js.map +1 -0
  35. package/dist/src/lib/A-Config/A-Config.context.d.ts +29 -0
  36. package/dist/src/lib/A-Config/A-Config.context.js +63 -0
  37. package/dist/src/lib/A-Config/A-Config.context.js.map +1 -0
  38. package/dist/src/lib/A-Config/A-Config.error.d.ts +4 -0
  39. package/dist/src/lib/A-Config/A-Config.error.js +9 -0
  40. package/dist/src/lib/A-Config/A-Config.error.js.map +1 -0
  41. package/dist/src/lib/A-Config/A-Config.types.d.ts +19 -0
  42. package/dist/src/lib/A-Config/A-Config.types.js +7 -0
  43. package/dist/src/lib/A-Config/A-Config.types.js.map +1 -0
  44. package/dist/src/lib/A-Config/components/ConfigReader.component.d.ts +30 -0
  45. package/dist/src/lib/A-Config/components/ConfigReader.component.js +85 -0
  46. package/dist/src/lib/A-Config/components/ConfigReader.component.js.map +1 -0
  47. package/dist/src/lib/A-Config/components/ENVConfigReader.component.d.ts +10 -0
  48. package/dist/src/lib/A-Config/components/ENVConfigReader.component.js +37 -0
  49. package/dist/src/lib/A-Config/components/ENVConfigReader.component.js.map +1 -0
  50. package/dist/src/lib/A-Config/components/FileConfigReader.component.d.ts +11 -0
  51. package/dist/src/lib/A-Config/components/FileConfigReader.component.js +47 -0
  52. package/dist/src/lib/A-Config/components/FileConfigReader.component.js.map +1 -0
  53. package/dist/src/lib/A-Logger/A-Logger.component.d.ts +29 -0
  54. package/dist/src/lib/A-Logger/A-Logger.component.js +152 -0
  55. package/dist/src/lib/A-Logger/A-Logger.component.js.map +1 -0
  56. package/dist/src/lib/A-Logger/A-Logger.types.d.ts +0 -0
  57. package/dist/src/lib/A-Logger/A-Logger.types.js +2 -0
  58. package/dist/src/lib/A-Logger/A-Logger.types.js.map +1 -0
  59. package/dist/src/lib/A-Memory/A-Memory.context.d.ts +64 -0
  60. package/dist/src/lib/A-Memory/A-Memory.context.js +105 -0
  61. package/dist/src/lib/A-Memory/A-Memory.context.js.map +1 -0
  62. package/dist/src/lib/A-Polyfill/A-Polyfill.component.d.ts +20 -0
  63. package/dist/src/lib/A-Polyfill/A-Polyfill.component.js +53 -0
  64. package/dist/src/lib/A-Polyfill/A-Polyfill.component.js.map +1 -0
  65. package/dist/src/{global/A_Polyfills.d.ts → lib/A-Polyfill/A-Polyfill.types.d.ts} +1 -13
  66. package/dist/src/lib/A-Polyfill/A-Polyfill.types.js +2 -0
  67. package/dist/src/lib/A-Polyfill/A-Polyfill.types.js.map +1 -0
  68. package/dist/src/lib/A-Polyfill/A-Polyfills.class.d.ts +10 -0
  69. package/dist/src/{global/A_Polyfills.js → lib/A-Polyfill/A-Polyfills.class.js} +4 -4
  70. package/dist/src/lib/A-Polyfill/A-Polyfills.class.js.map +1 -0
  71. package/dist/src/{global/A_Deferred.class.d.ts → lib/A-Schedule/A-Deferred.class.d.ts} +4 -0
  72. package/dist/src/{global/A_Deferred.class.js → lib/A-Schedule/A-Deferred.class.js} +5 -1
  73. package/dist/src/lib/A-Schedule/A-Deferred.class.js.map +1 -0
  74. package/dist/src/lib/A-Schedule/A-Schedule.component.d.ts +57 -0
  75. package/dist/src/lib/A-Schedule/A-Schedule.component.js +49 -0
  76. package/dist/src/lib/A-Schedule/A-Schedule.component.js.map +1 -0
  77. package/dist/src/{types/A_ScheduleObject.types.d.ts → lib/A-Schedule/A-Schedule.types.d.ts} +2 -1
  78. package/dist/src/{types/ASEID.types.js → lib/A-Schedule/A-Schedule.types.js} +1 -3
  79. package/dist/src/lib/A-Schedule/A-Schedule.types.js.map +1 -0
  80. package/dist/src/lib/A-Schedule/A-ScheduleObject.class.d.ts +29 -0
  81. package/dist/src/{global/A_ScheduleObject.class.js → lib/A-Schedule/A-ScheduleObject.class.js} +25 -5
  82. package/dist/src/lib/A-Schedule/A-ScheduleObject.class.js.map +1 -0
  83. package/index.ts +23 -47
  84. package/jest.config.ts +3 -3
  85. package/package.json +6 -6
  86. package/src/constants/errors.constants.ts +0 -78
  87. package/src/lib/A-Channel/A-Channel.component.ts +8 -0
  88. package/src/lib/A-Channel/A-Channel.error.ts +6 -0
  89. package/src/lib/A-Channel/A-Channel.types.ts +0 -0
  90. package/src/lib/A-Command/A-Command.constants.ts +31 -0
  91. package/src/lib/A-Command/A-Command.entity.ts +327 -0
  92. package/src/lib/A-Command/A-Command.error.ts +6 -0
  93. package/src/lib/A-Command/A-Command.types.ts +100 -0
  94. package/src/lib/A-Config/A-Config.constants.ts +13 -0
  95. package/src/lib/A-Config/A-Config.container.ts +63 -0
  96. package/src/lib/A-Config/A-Config.context.ts +117 -0
  97. package/src/lib/A-Config/A-Config.error.ts +7 -0
  98. package/src/lib/A-Config/A-Config.types.ts +26 -0
  99. package/src/lib/A-Config/components/ConfigReader.component.ts +67 -0
  100. package/src/lib/A-Config/components/ENVConfigReader.component.ts +31 -0
  101. package/src/lib/A-Config/components/FileConfigReader.component.ts +42 -0
  102. package/src/lib/A-Logger/A-Logger.component.ts +190 -0
  103. package/src/lib/A-Logger/A-Logger.types.ts +0 -0
  104. package/src/lib/A-Memory/A-Memory.context.ts +115 -0
  105. package/src/lib/A-Polyfill/A-Polyfill.component.ts +45 -0
  106. package/src/lib/A-Polyfill/A-Polyfill.types.ts +10 -0
  107. package/src/{global/A_Polyfills.ts → lib/A-Polyfill/A-Polyfills.class.ts} +2 -16
  108. package/src/{global/A_Deferred.class.ts → lib/A-Schedule/A-Deferred.class.ts} +4 -0
  109. package/src/lib/A-Schedule/A-Schedule.component.ts +89 -0
  110. package/src/{types/A_ScheduleObject.types.ts → lib/A-Schedule/A-Schedule.types.ts} +7 -2
  111. package/src/{global/A_ScheduleObject.class.ts → lib/A-Schedule/A-ScheduleObject.class.ts} +25 -7
  112. package/tests/A-Channel.test.ts +16 -0
  113. package/tests/A-Command.test.ts +133 -0
  114. package/tests/A-Config.test.ts +185 -0
  115. package/tests/A-Polyfill.test.ts +67 -0
  116. package/tests/A-Schedule.test.ts +84 -0
  117. package/tests/jest.setup.ts +35 -0
  118. package/tsconfig.build.json +56 -0
  119. package/tsconfig.json +2 -2
  120. package/dist/src/global/ASEID.class.d.ts +0 -77
  121. package/dist/src/global/ASEID.class.js +0 -129
  122. package/dist/src/global/ASEID.class.js.map +0 -1
  123. package/dist/src/global/A_Deferred.class.js.map +0 -1
  124. package/dist/src/global/A_Entity.class.d.ts +0 -49
  125. package/dist/src/global/A_Entity.class.js +0 -94
  126. package/dist/src/global/A_Entity.class.js.map +0 -1
  127. package/dist/src/global/A_Error.class.d.ts +0 -13
  128. package/dist/src/global/A_Error.class.js +0 -63
  129. package/dist/src/global/A_Error.class.js.map +0 -1
  130. package/dist/src/global/A_Polyfills.js.map +0 -1
  131. package/dist/src/global/A_ScheduleObject.class.d.ts +0 -9
  132. package/dist/src/global/A_ScheduleObject.class.js.map +0 -1
  133. package/dist/src/global/A_ServerError.class.d.ts +0 -13
  134. package/dist/src/global/A_ServerError.class.js +0 -57
  135. package/dist/src/global/A_ServerError.class.js.map +0 -1
  136. package/dist/src/helpers/A_Common.helper.d.ts +0 -42
  137. package/dist/src/helpers/A_Common.helper.js +0 -214
  138. package/dist/src/helpers/A_Common.helper.js.map +0 -1
  139. package/dist/src/helpers/A_Schedule.helper.d.ts +0 -6
  140. package/dist/src/helpers/A_Schedule.helper.js +0 -21
  141. package/dist/src/helpers/A_Schedule.helper.js.map +0 -1
  142. package/dist/src/types/ASEID.types.d.ts +0 -65
  143. package/dist/src/types/ASEID.types.js.map +0 -1
  144. package/dist/src/types/A_Common.types.d.ts +0 -59
  145. package/dist/src/types/A_Common.types.js +0 -3
  146. package/dist/src/types/A_Common.types.js.map +0 -1
  147. package/dist/src/types/A_Entity.types.d.ts +0 -13
  148. package/dist/src/types/A_Entity.types.js +0 -4
  149. package/dist/src/types/A_Entity.types.js.map +0 -1
  150. package/dist/src/types/A_Error.type.d.ts +0 -7
  151. package/dist/src/types/A_Error.type.js +0 -3
  152. package/dist/src/types/A_Error.type.js.map +0 -1
  153. package/dist/src/types/A_Error.types.d.ts +0 -7
  154. package/dist/src/types/A_Error.types.js +0 -3
  155. package/dist/src/types/A_Error.types.js.map +0 -1
  156. package/dist/src/types/A_ScheduleObject.types.js +0 -3
  157. package/dist/src/types/A_ScheduleObject.types.js.map +0 -1
  158. package/dist/src/types/A_ServerError.types.d.ts +0 -4
  159. package/dist/src/types/A_ServerError.types.js +0 -3
  160. package/dist/src/types/A_ServerError.types.js.map +0 -1
  161. package/src/global/ASEID.class.ts +0 -208
  162. package/src/global/A_Error.class.ts +0 -88
  163. package/src/global/A_ServerError.class.ts +0 -70
  164. package/src/helpers/A_Common.helper.ts +0 -265
  165. package/src/helpers/A_Schedule.helper.ts +0 -25
  166. package/src/types/ASEID.types.ts +0 -86
  167. package/src/types/A_Common.types.ts +0 -111
  168. package/src/types/A_Entity.types.ts +0 -17
  169. package/src/types/A_Error.types.ts +0 -10
  170. package/src/types/A_ServerError.types.ts +0 -7
  171. package/tests/default.test.ts +0 -160
  172. package/tests/polyfill.test.ts +0 -37
@@ -0,0 +1,327 @@
1
+ import {
2
+ A_TYPES__Command_Init,
3
+ A_TYPES__Command_Listener,
4
+ A_TYPES__Command_Serialized
5
+ } from "./A-Command.types";
6
+ import {
7
+ A_CONSTANTS__A_Command_Event,
8
+ A_CONSTANTS__A_Command_Status
9
+ } from "./A-Command.constants";
10
+ import { A_Context, A_Entity, A_Error, A_Scope } from "@adaas/a-concept";
11
+ import { A_Memory } from "../A-Memory/A-Memory.context";
12
+
13
+
14
+ export class A_Command<
15
+ InvokeType extends A_TYPES__Command_Init = A_TYPES__Command_Init,
16
+ ResultType extends Record<string, any> = Record<string, any>,
17
+ LifecycleEvents extends string = A_CONSTANTS__A_Command_Event
18
+ > extends A_Entity<InvokeType, A_TYPES__Command_Serialized<ResultType>> {
19
+
20
+ // ====================================================================
21
+ // ================== Static A-Command Information ====================
22
+ // ====================================================================
23
+
24
+ /**
25
+ * Command Identifier that corresponds to the class name
26
+ */
27
+ static get code(): string {
28
+ return super.entity;
29
+ }
30
+
31
+ // ====================================================================
32
+ // ================ Instance A-Command Information ====================
33
+ // ====================================================================
34
+ protected _result?: ResultType;
35
+ protected _executionScope!: A_Scope;
36
+ protected _errors?: Set<A_Error>;
37
+
38
+ protected _params!: InvokeType;
39
+ protected _status!: A_CONSTANTS__A_Command_Status
40
+
41
+ protected _listeners: Map<
42
+ // the name of the event
43
+ LifecycleEvents | A_CONSTANTS__A_Command_Event,
44
+ // the listeners for the event
45
+ Set<A_TYPES__Command_Listener<InvokeType, ResultType, LifecycleEvents>>
46
+ > = new Map();
47
+
48
+ protected _startTime?: Date;
49
+ protected _endTime?: Date
50
+
51
+ /**
52
+ * Execution Duration in milliseconds
53
+ */
54
+ get duration() {
55
+ return this._endTime && this._startTime
56
+ ? this._endTime.getTime() - this._startTime.getTime()
57
+ : this._startTime
58
+ ? new Date().getTime() - this._startTime.getTime()
59
+ : undefined;
60
+ }
61
+ /**
62
+ * A shared scope between all features of the command during its execution
63
+ */
64
+ get scope(): A_Scope {
65
+ return this._executionScope;
66
+ }
67
+ /**
68
+ * Unique code identifying the command type
69
+ * Example: 'user.create', 'task.complete', etc.
70
+ *
71
+ */
72
+ get code(): string {
73
+ return (this.constructor as typeof A_Command).code;
74
+ }
75
+ /**
76
+ * Current status of the command
77
+ */
78
+ get status(): A_CONSTANTS__A_Command_Status {
79
+ return this._status;
80
+ }
81
+ /**
82
+ * Start time of the command execution
83
+ */
84
+ get startedAt(): Date | undefined {
85
+ return this._startTime;
86
+ }
87
+ /**
88
+ * End time of the command execution
89
+ */
90
+ get endedAt(): Date | undefined {
91
+ return this._endTime;
92
+ }
93
+ /**
94
+ * Result of the command execution stored in the context
95
+ */
96
+ get result(): ResultType | undefined {
97
+ return this._result;
98
+ }
99
+ /**
100
+ * Errors encountered during the command execution stored in the context
101
+ */
102
+ get errors(): Set<A_Error> | undefined {
103
+ return this._errors;
104
+ }
105
+ /**
106
+ * Parameters used to invoke the command
107
+ */
108
+ get params(): InvokeType {
109
+ return this._params;
110
+ }
111
+ /**
112
+ * Indicates if the command has failed
113
+ */
114
+ get isFailed(): boolean {
115
+ return this._status === A_CONSTANTS__A_Command_Status.FAILED;
116
+ }
117
+ /**
118
+ * Indicates if the command has completed successfully
119
+ */
120
+ get isCompleted(): boolean {
121
+ return this._status === A_CONSTANTS__A_Command_Status.COMPLETED;
122
+ }
123
+
124
+ /**
125
+ *
126
+ * A-Command represents an executable command with a specific code and parameters.
127
+ * It can be executed within a given scope and stores execution results and errors.
128
+ *
129
+ *
130
+ * A-Command should be context independent and execution logic should be based on attached components
131
+ *
132
+ * @param code
133
+ * @param params
134
+ */
135
+ constructor(
136
+ /**
137
+ * Command invocation parameters
138
+ */
139
+ params: InvokeType | A_TYPES__Command_Serialized<ResultType> | string
140
+ ) {
141
+ super(params as any)
142
+ }
143
+
144
+
145
+ // --------------------------------------------------------------------------
146
+ // A-Command Lifecycle Methods
147
+ // --------------------------------------------------------------------------
148
+
149
+ // should create a new Task in DB with basic records
150
+ async init(): Promise<void> {
151
+ this._status = A_CONSTANTS__A_Command_Status.IN_PROGRESS;
152
+ this._startTime = new Date();
153
+ if (!this.scope.isInheritedFrom(A_Context.scope(this))) {
154
+ this.scope.inherit(A_Context.scope(this));
155
+ }
156
+
157
+
158
+ this.emit('init');
159
+ return await this.call('init', this.scope);
160
+ }
161
+
162
+ // Should compile everything before execution
163
+ async compile() {
164
+ this.emit('compile');
165
+ return await this.call('compile', this.scope);
166
+ }
167
+
168
+ /**
169
+ * Executes the command logic.
170
+ */
171
+ async execute(): Promise<any> {
172
+ try {
173
+ await this.init();
174
+ await this.compile();
175
+ this.emit('execute');
176
+ await this.call('execute', this.scope);
177
+ await this.complete();
178
+
179
+ } catch (error) {
180
+ await this.fail();
181
+ }
182
+ }
183
+
184
+ /**
185
+ * Marks the command as completed
186
+ */
187
+ async complete() {
188
+ this._status = A_CONSTANTS__A_Command_Status.COMPLETED;
189
+ this._endTime = new Date();
190
+ this._result = this.scope.resolve(A_Memory).toJSON() as ResultType;
191
+
192
+ this.emit('complete');
193
+ return await this.call('complete', this.scope);
194
+ }
195
+
196
+
197
+ /**
198
+ * Marks the command as failed
199
+ */
200
+ async fail() {
201
+ this._status = A_CONSTANTS__A_Command_Status.FAILED;
202
+ this._endTime = new Date();
203
+ this._errors = this.scope.resolve(A_Memory).Errors;
204
+
205
+ this.emit('fail');
206
+ return await this.call('fail', this.scope);
207
+ }
208
+
209
+
210
+ // --------------------------------------------------------------------------
211
+ // A-Command Event-Emitter methods
212
+ // --------------------------------------------------------------------------
213
+
214
+ /**
215
+ * Registers an event listener for a specific event
216
+ *
217
+ * @param event
218
+ * @param listener
219
+ */
220
+ on(event: LifecycleEvents | A_CONSTANTS__A_Command_Event, listener: A_TYPES__Command_Listener<InvokeType, ResultType, LifecycleEvents>) {
221
+ if (!this._listeners.has(event)) {
222
+ this._listeners.set(event, new Set());
223
+ }
224
+ this._listeners.get(event)!.add(listener);
225
+ }
226
+ /**
227
+ * Removes an event listener for a specific event
228
+ *
229
+ * @param event
230
+ * @param listener
231
+ */
232
+ off(event: LifecycleEvents | A_CONSTANTS__A_Command_Event, listener: A_TYPES__Command_Listener<InvokeType, ResultType, LifecycleEvents>) {
233
+ this._listeners.get(event)?.delete(listener);
234
+ }
235
+ /**
236
+ * Emits an event to all registered listeners
237
+ *
238
+ * @param event
239
+ */
240
+ emit(event: LifecycleEvents | A_CONSTANTS__A_Command_Event) {
241
+ this._listeners.get(event)?.forEach(listener => {
242
+ listener(this);
243
+ });
244
+ }
245
+
246
+
247
+ // --------------------------------------------------------------------------
248
+ // A-Entity Base Class Overrides
249
+ // --------------------------------------------------------------------------
250
+ // Serialization / Deserialization
251
+ // -------------------------------------------------------------------------
252
+
253
+
254
+ /**
255
+ * Allows to create a Command instance from new data
256
+ *
257
+ * @param newEntity
258
+ */
259
+ fromNew(newEntity: InvokeType): void {
260
+ super.fromNew(newEntity);
261
+
262
+ this._executionScope = new A_Scope();
263
+
264
+ this._executionScope.register(new A_Memory<ResultType>());
265
+
266
+ this._params = newEntity;
267
+
268
+ this._status = A_CONSTANTS__A_Command_Status.INITIALIZED;
269
+ }
270
+
271
+
272
+
273
+ /**
274
+ * Allows to convert serialized data to Command instance
275
+ *
276
+ * [!] By default it omits params as they are not stored in the serialized data
277
+ *
278
+ * @param serialized
279
+ */
280
+ fromJSON(serialized: A_TYPES__Command_Serialized<ResultType>): void {
281
+ super.fromJSON(serialized);
282
+
283
+ this._executionScope = new A_Scope();
284
+
285
+ const memory = new A_Memory<ResultType>();
286
+
287
+ this._executionScope.register(memory);
288
+
289
+ if (serialized.startedAt) this._startTime = new Date(serialized.startedAt);
290
+ if (serialized.endedAt) this._endTime = new Date(serialized.endedAt);
291
+
292
+
293
+ // Restore result and errors in the memory
294
+ if (serialized.result) {
295
+ Object.entries(serialized.result).forEach(([key, value]) => {
296
+ memory.set(key, value);
297
+ });
298
+ }
299
+
300
+ if (serialized.errors) {
301
+ serialized.errors.forEach(err => {
302
+ memory.error(new A_Error(err));
303
+ });
304
+ }
305
+
306
+ this._status = serialized.status || A_CONSTANTS__A_Command_Status.INITIALIZED;
307
+ }
308
+
309
+
310
+ /**
311
+ * Converts the Command instance to a plain object
312
+ *
313
+ * @returns
314
+ */
315
+ toJSON(): A_TYPES__Command_Serialized<ResultType> {
316
+ return {
317
+ ...super.toJSON(),
318
+ code: this.code,
319
+ status: this._status,
320
+ startedAt: this._startTime ? this._startTime.toISOString() : undefined,
321
+ endedAt: this._endTime ? this._endTime.toISOString() : undefined,
322
+ duration: this.duration,
323
+ result: this.result,
324
+ errors: this.errors ? Array.from(this.errors).map(err => err.toJSON()) : undefined
325
+ }
326
+ };
327
+ }
@@ -0,0 +1,6 @@
1
+ import { A_Error } from "@adaas/a-concept";
2
+
3
+
4
+ export class A_CommandError extends A_Error {
5
+
6
+ }
@@ -0,0 +1,100 @@
1
+ import { A_Command } from "./A-Command.entity";
2
+ import { A_CONSTANTS__A_Command_Event, A_CONSTANTS__A_Command_Status, A_TYPES__CommandMetaKey } from "./A-Command.constants";
3
+ import { A_Meta, A_TYPES__Entity_Serialized, A_TYPES__Error_Serialized, A_TYPES__FeatureDefineDecoratorMeta, A_TYPES__FeatureExtendDecoratorMeta } from "@adaas/a-concept";
4
+
5
+
6
+
7
+ // ============================================================================
8
+ // --------------------------- Primary Types ----------------------------------
9
+ // ============================================================================
10
+ /**
11
+ * Command constructor type
12
+ * Uses the generic type T to specify the type of the entity
13
+ */
14
+ export type A_TYPES__Command_Constructor<T = A_Command> = new (...args: any[]) => T;
15
+ /**
16
+ * Command initialization type
17
+ */
18
+ export type A_TYPES__Command_Init = any;
19
+ /**
20
+ * Command serialized type
21
+ */
22
+ export type A_TYPES__Command_Serialized<
23
+ ResultType extends Record<string, any> = Record<string, any>
24
+ > = {
25
+ /**
26
+ * Unique code of the command
27
+ */
28
+ code: string;
29
+ /**
30
+ * Current status of the command
31
+ */
32
+ status: A_CONSTANTS__A_Command_Status;
33
+ // --------------------------------------------------
34
+ /**
35
+ * The time when the command was created
36
+ */
37
+ startedAt?: string;
38
+ /**
39
+ * The time when the command execution ended
40
+ */
41
+ endedAt?: string;
42
+ /**
43
+ * Duration of the command execution in milliseconds
44
+ */
45
+ duration?: number;
46
+ // --------------------------------------------------
47
+ /**
48
+ * Result of the command execution
49
+ */
50
+ result?: ResultType;
51
+ /**
52
+ * List of errors occurred during the command execution
53
+ */
54
+ errors?: Array<A_TYPES__Error_Serialized>;
55
+ } & A_TYPES__Entity_Serialized
56
+
57
+ // ============================================================================
58
+ // ---------------------------- Common Types ----------------------------------
59
+ // ============================================================================
60
+ /**
61
+ * Command listener type
62
+ */
63
+ export type A_TYPES__Command_Listener<
64
+ InvokeType extends A_TYPES__Command_Init = A_TYPES__Command_Init,
65
+ ResultType extends Record<string, any> = Record<string, any>,
66
+ LifecycleEvents extends string = A_CONSTANTS__A_Command_Event
67
+ > = (command?: A_Command<InvokeType, ResultType, LifecycleEvents>) => void;
68
+
69
+
70
+ // ============================================================================
71
+ // --------------------------- Meta Types -------------------------------------
72
+ // ============================================================================
73
+ /**
74
+ * Command meta type
75
+ */
76
+ export type A_TYPES__CommandMeta = {
77
+ [A_TYPES__CommandMetaKey.EXTENSIONS]: A_Meta<{
78
+
79
+ /**
80
+ * Where Key the regexp for what to apply the extension
81
+ * A set of container names or a wildcard, or a regexp
82
+ *
83
+ *
84
+ * Where value is the extension instructions
85
+ */
86
+ [Key: string]: A_TYPES__FeatureExtendDecoratorMeta[]
87
+
88
+ }>, case
89
+
90
+
91
+ [A_TYPES__CommandMetaKey.FEATURES]: A_Meta<{
92
+ /**
93
+ * Where Key is the name of the feature
94
+ *
95
+ * Where value is the list of features
96
+ */
97
+ [Key: string]: A_TYPES__FeatureDefineDecoratorMeta
98
+ }>
99
+ }
100
+
@@ -0,0 +1,13 @@
1
+ export const A_CONSTANTS__CONFIG_ENV_VARIABLES = {
2
+
3
+ } as const
4
+
5
+
6
+ //should be an array
7
+ export type A_TYPES__ConfigENVVariables = (typeof A_CONSTANTS__CONFIG_ENV_VARIABLES)[keyof typeof A_CONSTANTS__CONFIG_ENV_VARIABLES][];
8
+
9
+
10
+ export const A_CONSTANTS__CONFIG_ENV_VARIABLES_ARRAY = [
11
+
12
+ ] as const;
13
+
@@ -0,0 +1,63 @@
1
+ import { A_Concept, A_Container, A_Context, A_Inject, A_ScopeError } from "@adaas/a-concept";
2
+ import { ConfigReader } from "./components/ConfigReader.component";
3
+ import { A_Config } from "./A-Config.context";
4
+ import { A_Polyfill } from "../A-Polyfill/A-Polyfill.component";
5
+ import { A_ConfigError } from "./A-Config.error";
6
+ import { FileConfigReader } from "./components/FileConfigReader.component";
7
+ import { ENVConfigReader } from "./components/ENVConfigReader.component";
8
+
9
+
10
+ export class A_ConfigLoader extends A_Container {
11
+
12
+ private reader!: ConfigReader
13
+
14
+
15
+ @A_Concept.Load()
16
+ async prepare(
17
+ @A_Inject(A_Polyfill) polyfill: A_Polyfill,
18
+ ) {
19
+ const fs = await polyfill.fs();
20
+
21
+ try {
22
+ switch (true) {
23
+
24
+ case A_Context.environment === 'server' && !!fs.existsSync(`${A_Context.concept}.conf.json`):
25
+ this.reader = this.scope.resolve<ConfigReader>(FileConfigReader);
26
+ break;
27
+
28
+ case A_Context.environment === 'server' && !fs.existsSync(`${A_Context.concept}.conf.json`):
29
+ this.reader = this.scope.resolve<ConfigReader>(ENVConfigReader);
30
+ break;
31
+
32
+ case A_Context.environment === 'browser':
33
+ this.reader = this.scope.resolve<ConfigReader>(ENVConfigReader);
34
+ break;
35
+
36
+ default:
37
+ throw new A_ConfigError(
38
+ A_ConfigError.InitializationError,
39
+ `Environment ${A_Context.environment} is not supported`
40
+ );
41
+ }
42
+ } catch (error) {
43
+ if (error instanceof A_ScopeError) {
44
+ throw new A_ConfigError({
45
+ title: A_ConfigError.InitializationError,
46
+ description: `Failed to initialize A_ConfigLoader. Reader not found for environment ${A_Context.environment}`,
47
+ originalError: error,
48
+ })
49
+ }
50
+ }
51
+
52
+ }
53
+
54
+
55
+ @A_Concept.Load({
56
+ after: ['A_ConfigLoader.prepare']
57
+ })
58
+ async readVariables(
59
+ @A_Inject(A_Config) config: A_Config,
60
+ ) {
61
+ await this.reader.inject(config);
62
+ }
63
+ }
@@ -0,0 +1,117 @@
1
+ import { A_CommonHelper, A_CONSTANTS__DEFAULT_ENV_VARIABLES_ARRAY, A_FormatterHelper, A_Fragment, A_TYPES__ConceptENVVariables } from "@adaas/a-concept";
2
+ import { A_TYPES__ConfigContainerConstructor } from "./A-Config.types";
3
+ import { A_CONSTANTS__CONFIG_ENV_VARIABLES_ARRAY } from "./A-Config.constants";
4
+
5
+
6
+ export class A_Config<
7
+ T extends Array<string | A_TYPES__ConceptENVVariables[number]> = any[]
8
+ > extends A_Fragment {
9
+
10
+ config: A_TYPES__ConfigContainerConstructor<T>;
11
+
12
+
13
+ private VARIABLES: Map<T[number], any> = new Map<T[number], any>();
14
+
15
+ CONFIG_PROPERTIES!: T;
16
+
17
+ protected DEFAULT_ALLOWED_TO_READ_PROPERTIES = [
18
+ ...A_CONSTANTS__DEFAULT_ENV_VARIABLES_ARRAY,
19
+ ...A_CONSTANTS__CONFIG_ENV_VARIABLES_ARRAY
20
+ ];
21
+
22
+
23
+ constructor(
24
+ config: Partial<A_TYPES__ConfigContainerConstructor<T>>
25
+ ) {
26
+ super({
27
+ name: 'A_Config'
28
+ });
29
+
30
+ this.config = A_CommonHelper.deepCloneAndMerge<A_TYPES__ConfigContainerConstructor<T>>(config as any, {
31
+ strict: false,
32
+ defaults: {},
33
+ variables: A_CONSTANTS__DEFAULT_ENV_VARIABLES_ARRAY as any as T
34
+ } as any);
35
+
36
+ this.CONFIG_PROPERTIES = this.config.variables ? this.config.variables : [] as any as T;
37
+
38
+ this.config.variables.forEach((variable) => {
39
+ this.VARIABLES.set(
40
+ A_FormatterHelper.toUpperSnakeCase(variable),
41
+ this.config.defaults[variable]
42
+ );
43
+ });
44
+ }
45
+
46
+
47
+ /**
48
+ * This method is used to get the configuration property by name
49
+ *
50
+ * @param property
51
+ * @returns
52
+ */
53
+ get<_OutType = any>(
54
+ property: T[number] | typeof this.DEFAULT_ALLOWED_TO_READ_PROPERTIES[number]
55
+ ): _OutType {
56
+ if (this.CONFIG_PROPERTIES.includes(property as any)
57
+ || this.DEFAULT_ALLOWED_TO_READ_PROPERTIES.includes(property as any)
58
+ || !(this.config.strict)
59
+ )
60
+ return this.VARIABLES.get(A_FormatterHelper.toUpperSnakeCase(property)) as _OutType;
61
+
62
+ throw new Error('Property not exists or not allowed to read') as never;
63
+ // return this.concept.Errors.throw(A_SDK_CONSTANTS__ERROR_CODES.CONFIGURATION_PROPERTY_NOT_EXISTS_OR_NOT_ALLOWED_TO_READ) as never;
64
+ }
65
+
66
+
67
+
68
+ /**
69
+ *
70
+ * This method is used to set the configuration property by name
71
+ * OR set multiple properties at once by passing an array of objects
72
+ *
73
+ * @param variables
74
+ */
75
+ set(
76
+ variables: Array<{
77
+ property: T[number] | A_TYPES__ConceptENVVariables[number],
78
+ value: any
79
+ }>
80
+ )
81
+ set(
82
+ variables: Partial<Record<T[number] | A_TYPES__ConceptENVVariables[number], any>>
83
+ )
84
+ set(
85
+ property: T[number] | A_TYPES__ConceptENVVariables[number],
86
+ value: any
87
+ )
88
+ set(
89
+ property: T[number] | A_TYPES__ConceptENVVariables[number] | Array<{
90
+ property: T[number] | A_TYPES__ConceptENVVariables[number],
91
+ value: any
92
+ }> | Partial<Record<T[number] | A_TYPES__ConceptENVVariables[number], any>>,
93
+ value?: any
94
+ ) {
95
+ const array = Array.isArray(property)
96
+ ? property
97
+ : typeof property === 'string'
98
+ ? [{ property, value }]
99
+ : Object
100
+ .keys(property)
101
+ .map((key) => ({
102
+ property: key,
103
+ value: property[key]
104
+ }));
105
+
106
+ for (const { property, value } of array) {
107
+
108
+ let targetValue = value
109
+ ? value
110
+ : this.config?.defaults
111
+ ? this.config.defaults[property as T[number]]
112
+ : undefined;
113
+
114
+ this.VARIABLES.set(A_FormatterHelper.toUpperSnakeCase(property), targetValue);
115
+ }
116
+ }
117
+ }
@@ -0,0 +1,7 @@
1
+ import { A_Error } from "@adaas/a-concept";
2
+
3
+
4
+ export class A_ConfigError extends A_Error {
5
+
6
+ static readonly InitializationError = 'A-Config Initialization Error';
7
+ }
@@ -0,0 +1,26 @@
1
+ import { A_TYPES__ConceptENVVariables, A_TYPES__Fragment_Constructor } from "@adaas/a-concept";
2
+
3
+ export enum A_TYPES__ConfigFeature {
4
+
5
+ }
6
+
7
+
8
+ export type A_TYPES__ConfigContainerConstructor<T extends Array<string | A_TYPES__ConceptENVVariables[number]>> = {
9
+
10
+ /**
11
+ * If set to true, the SDK will throw an error if the variable is not defined OR not presented in the defaults
12
+ */
13
+ strict: boolean
14
+
15
+ /**
16
+ * Allows to define the names of variable to be loaded
17
+ */
18
+ variables: T
19
+
20
+ /**
21
+ * Allows to set the default values for the variables
22
+ */
23
+ defaults: {
24
+ [key in T[number]]?: any
25
+ }
26
+ } & A_TYPES__Fragment_Constructor;