@adaas/a-utils 0.1.18 → 0.1.20

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 (50) hide show
  1. package/dist/index.cjs +45 -0
  2. package/dist/index.cjs.map +1 -0
  3. package/dist/index.d.mts +964 -354
  4. package/dist/index.d.ts +964 -354
  5. package/dist/index.mjs +44 -2372
  6. package/dist/index.mjs.map +1 -1
  7. package/examples/A-Channel-examples.ts +13 -11
  8. package/examples/A-Command-examples-2.ts +429 -0
  9. package/examples/A-Command-examples.ts +487 -202
  10. package/examples/A-StateMachine-examples.ts +609 -0
  11. package/package.json +3 -2
  12. package/src/index.ts +1 -2
  13. package/src/lib/A-Channel/A-Channel.component.ts +14 -74
  14. package/src/lib/A-Channel/A-Channel.error.ts +5 -5
  15. package/src/lib/A-Channel/A-Channel.types.ts +2 -10
  16. package/src/lib/A-Channel/A-ChannelRequest.context.ts +25 -74
  17. package/src/lib/A-Command/A-Command.constants.ts +78 -23
  18. package/src/lib/A-Command/A-Command.entity.ts +447 -119
  19. package/src/lib/A-Command/A-Command.error.ts +11 -0
  20. package/src/lib/A-Command/A-Command.types.ts +96 -20
  21. package/src/lib/A-Command/A-CommandExecution.context.ts +0 -0
  22. package/src/lib/A-Command/README.md +164 -68
  23. package/src/lib/A-Config/A-Config.container.ts +2 -2
  24. package/src/lib/A-Config/A-Config.context.ts +19 -5
  25. package/src/lib/A-Config/components/ConfigReader.component.ts +1 -1
  26. package/src/lib/A-Logger/A-Logger.component.ts +211 -35
  27. package/src/lib/A-Logger/A-Logger.constants.ts +50 -10
  28. package/src/lib/A-Logger/A-Logger.env.ts +17 -1
  29. package/src/lib/A-Memory/A-Memory.component.ts +440 -0
  30. package/src/lib/A-Memory/A-Memory.constants.ts +49 -0
  31. package/src/lib/A-Memory/A-Memory.context.ts +14 -118
  32. package/src/lib/A-Memory/A-Memory.error.ts +21 -0
  33. package/src/lib/A-Memory/A-Memory.types.ts +21 -0
  34. package/src/lib/A-Operation/A-Operation.context.ts +58 -0
  35. package/src/lib/A-Operation/A-Operation.types.ts +47 -0
  36. package/src/lib/A-StateMachine/A-StateMachine.component.ts +258 -0
  37. package/src/lib/A-StateMachine/A-StateMachine.constants.ts +18 -0
  38. package/src/lib/A-StateMachine/A-StateMachine.error.ts +10 -0
  39. package/src/lib/A-StateMachine/A-StateMachine.types.ts +20 -0
  40. package/src/lib/A-StateMachine/A-StateMachineTransition.context.ts +41 -0
  41. package/src/lib/A-StateMachine/README.md +391 -0
  42. package/tests/A-Channel.test.ts +17 -14
  43. package/tests/A-Command.test.ts +548 -460
  44. package/tests/A-Logger.test.ts +8 -4
  45. package/tests/A-Memory.test.ts +151 -115
  46. package/tests/A-Schedule.test.ts +2 -2
  47. package/tests/A-StateMachine.test.ts +760 -0
  48. package/tsup.config.ts +30 -13
  49. package/dist/index.js +0 -2398
  50. package/dist/index.js.map +0 -1
package/dist/index.js DELETED
@@ -1,2398 +0,0 @@
1
- 'use strict';
2
-
3
- var aConcept = require('@adaas/a-concept');
4
-
5
- var __defProp = Object.defineProperty;
6
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
7
- var __decorateClass = (decorators, target, key, kind) => {
8
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
9
- for (var i = decorators.length - 1, decorator; i >= 0; i--)
10
- if (decorator = decorators[i])
11
- result = (kind ? decorator(target, key, result) : decorator(result)) || result;
12
- if (kind && result) __defProp(target, key, result);
13
- return result;
14
- };
15
- var __decorateParam = (index, decorator) => (target, key) => decorator(target, key, index);
16
-
17
- // src/lib/A-Channel/A-Channel.constants.ts
18
- var A_ChannelFeatures = /* @__PURE__ */ ((A_ChannelFeatures2) => {
19
- A_ChannelFeatures2["onTimeout"] = "onTimeout";
20
- A_ChannelFeatures2["onRetry"] = "onRetry";
21
- A_ChannelFeatures2["onCircuitBreakerOpen"] = "onCircuitBreakerOpen";
22
- A_ChannelFeatures2["onCache"] = "onCache";
23
- A_ChannelFeatures2["onConnect"] = "onConnect";
24
- A_ChannelFeatures2["onDisconnect"] = "onDisconnect";
25
- A_ChannelFeatures2["onBeforeRequest"] = "onBeforeRequest";
26
- A_ChannelFeatures2["onRequest"] = "onRequest";
27
- A_ChannelFeatures2["onAfterRequest"] = "onAfterRequest";
28
- A_ChannelFeatures2["onError"] = "onError";
29
- A_ChannelFeatures2["onSend"] = "onSend";
30
- A_ChannelFeatures2["onConsume"] = "onConsume";
31
- return A_ChannelFeatures2;
32
- })(A_ChannelFeatures || {});
33
- var A_ChannelRequestStatuses = /* @__PURE__ */ ((A_ChannelRequestStatuses2) => {
34
- A_ChannelRequestStatuses2["PENDING"] = "PENDING";
35
- A_ChannelRequestStatuses2["SUCCESS"] = "SUCCESS";
36
- A_ChannelRequestStatuses2["FAILED"] = "FAILED";
37
- return A_ChannelRequestStatuses2;
38
- })(A_ChannelRequestStatuses || {});
39
-
40
- // src/lib/A-Channel/A-ChannelRequest.context.ts
41
- var A_ChannelRequest = class extends aConcept.A_Fragment {
42
- constructor(params = {}) {
43
- super();
44
- this._errors = /* @__PURE__ */ new Set();
45
- this._status = "PENDING" /* PENDING */;
46
- this._params = params;
47
- }
48
- /**
49
- * Returns the status of the request
50
- */
51
- get status() {
52
- return this._status;
53
- }
54
- /**
55
- * Returns the parameters of the request
56
- */
57
- get failed() {
58
- return this._errors.size > 0;
59
- }
60
- /**
61
- * Returns the Params of the Request
62
- */
63
- get params() {
64
- return this._params;
65
- }
66
- /**
67
- * Returns the Result of the Request
68
- */
69
- get data() {
70
- return this._result;
71
- }
72
- get errors() {
73
- return this._errors.size > 0 ? this._errors : void 0;
74
- }
75
- // ==========================================================
76
- // ==================== Mutations ===========================
77
- // ==========================================================
78
- /**
79
- * Adds an error to the context
80
- *
81
- * @param error
82
- */
83
- fail(error) {
84
- this._status = "FAILED" /* FAILED */;
85
- this._errors.add(error);
86
- }
87
- /**
88
- * Sets the result of the request
89
- *
90
- * @param result
91
- */
92
- succeed(result) {
93
- this._status = "SUCCESS" /* SUCCESS */;
94
- this._result = result;
95
- }
96
- /**
97
- * Serializes the context to a JSON object
98
- *
99
- * @returns
100
- */
101
- toJSON() {
102
- return {
103
- params: this._params,
104
- result: this._result,
105
- status: this._status,
106
- errors: this.errors ? Array.from(this._errors).map((err) => err.toString()) : void 0
107
- };
108
- }
109
- };
110
-
111
- // src/lib/A-Channel/A-Channel.error.ts
112
- var A_ChannelError = class extends aConcept.A_Error {
113
- /**
114
- * Channel Error allows to keep track of errors within a channel if something goes wrong
115
- *
116
- *
117
- * @param originalError
118
- * @param context
119
- */
120
- constructor(originalError, context) {
121
- if (aConcept.A_TypeGuards.isString(context))
122
- super(originalError, context);
123
- else
124
- super(originalError);
125
- if (context instanceof A_ChannelRequest)
126
- this._context = context;
127
- }
128
- /***
129
- * Returns Context of the error
130
- */
131
- get context() {
132
- return this._context;
133
- }
134
- };
135
- // ==========================================================
136
- // ==================== Error Types =========================
137
- // ==========================================================
138
- A_ChannelError.MethodNotImplemented = "A-Channel Method Not Implemented";
139
-
140
- // src/lib/A-Config/A-Config.constants.ts
141
- var A_CONSTANTS__CONFIG_ENV_VARIABLES = {};
142
- var A_CONSTANTS__CONFIG_ENV_VARIABLES_ARRAY = [];
143
-
144
- // src/lib/A-Config/A-Config.context.ts
145
- var A_Config = class extends aConcept.A_Fragment {
146
- constructor(config) {
147
- super({
148
- name: "A_Config"
149
- });
150
- this.VARIABLES = /* @__PURE__ */ new Map();
151
- this.DEFAULT_ALLOWED_TO_READ_PROPERTIES = [
152
- ...aConcept.A_CONSTANTS__DEFAULT_ENV_VARIABLES_ARRAY,
153
- ...A_CONSTANTS__CONFIG_ENV_VARIABLES_ARRAY
154
- ];
155
- this.config = aConcept.A_CommonHelper.deepCloneAndMerge(config, {
156
- strict: false,
157
- defaults: {},
158
- variables: aConcept.A_CONSTANTS__DEFAULT_ENV_VARIABLES_ARRAY
159
- });
160
- this.CONFIG_PROPERTIES = this.config.variables ? this.config.variables : [];
161
- this.config.variables.forEach((variable) => {
162
- this.VARIABLES.set(
163
- aConcept.A_FormatterHelper.toUpperSnakeCase(variable),
164
- this.config.defaults[variable]
165
- );
166
- });
167
- }
168
- /**
169
- * This method is used to get the configuration property by name
170
- *
171
- * @param property
172
- * @returns
173
- */
174
- get(property) {
175
- if (this.CONFIG_PROPERTIES.includes(property) || this.DEFAULT_ALLOWED_TO_READ_PROPERTIES.includes(property) || !this.config.strict)
176
- return this.VARIABLES.get(aConcept.A_FormatterHelper.toUpperSnakeCase(property));
177
- throw new Error("Property not exists or not allowed to read");
178
- }
179
- set(property, value) {
180
- const array = Array.isArray(property) ? property : typeof property === "string" ? [{ property, value }] : Object.keys(property).map((key) => ({
181
- property: key,
182
- value: property[key]
183
- }));
184
- for (const { property: property2, value: value2 } of array) {
185
- let targetValue = value2 ? value2 : this.config?.defaults ? this.config.defaults[property2] : void 0;
186
- this.VARIABLES.set(aConcept.A_FormatterHelper.toUpperSnakeCase(property2), targetValue);
187
- }
188
- }
189
- };
190
-
191
- // src/lib/A-Logger/A-Logger.constants.ts
192
- var A_LOGGER_DEFAULT_SCOPE_LENGTH = 20;
193
- var A_LOGGER_COLORS = {
194
- green: "32",
195
- // Success, completion messages
196
- blue: "34",
197
- // Info, general messages
198
- red: "31",
199
- // Errors, critical issues
200
- yellow: "33",
201
- // Warnings, caution messages
202
- gray: "90",
203
- // Debug, less important info
204
- magenta: "35",
205
- // Special highlighting
206
- cyan: "36",
207
- // Headers, titles
208
- white: "37",
209
- // Default text
210
- pink: "95"
211
- // Custom highlighting
212
- };
213
- var A_LOGGER_ANSI = {
214
- RESET: "\x1B[0m",
215
- PREFIX: "\x1B[",
216
- SUFFIX: "m"
217
- };
218
- var A_LOGGER_TIME_FORMAT = {
219
- MINUTES_PAD: 2,
220
- SECONDS_PAD: 2,
221
- MILLISECONDS_PAD: 3,
222
- SEPARATOR: ":"
223
- };
224
- var A_LOGGER_FORMAT = {
225
- SCOPE_OPEN: "[",
226
- SCOPE_CLOSE: "]",
227
- TIME_OPEN: "|",
228
- TIME_CLOSE: "|",
229
- SEPARATOR: "-------------------------------",
230
- PIPE: "| "
231
- };
232
- var A_LOGGER_ENV_KEYS = {
233
- LOG_LEVEL: "A_LOGGER_LEVEL"
234
- };
235
-
236
- // src/lib/A-Logger/A-Logger.component.ts
237
- exports.A_Logger = class A_Logger extends aConcept.A_Component {
238
- // =============================================
239
- // Constructor and Initialization
240
- // =============================================
241
- /**
242
- * Initialize A_Logger with dependency injection
243
- *
244
- * @param scope - The current scope context for message prefixing
245
- * @param config - Optional configuration for log level filtering
246
- */
247
- constructor(scope, config) {
248
- super();
249
- this.scope = scope;
250
- this.config = config;
251
- this.COLORS = A_LOGGER_COLORS;
252
- this.STANDARD_SCOPE_LENGTH = config?.get("A_LOGGER_DEFAULT_SCOPE_LENGTH") || A_LOGGER_DEFAULT_SCOPE_LENGTH;
253
- }
254
- // =============================================
255
- // Scope and Formatting Utilities
256
- // =============================================
257
- /**
258
- * Get the formatted scope length for consistent message alignment
259
- * Uses a standard length to ensure all messages align properly regardless of scope name
260
- *
261
- * @returns The scope length to use for padding calculations
262
- */
263
- get scopeLength() {
264
- return Math.max(this.scope.name.length, this.STANDARD_SCOPE_LENGTH);
265
- }
266
- /**
267
- * Get the formatted scope name with proper padding
268
- * Ensures consistent width for all scope names in log output
269
- *
270
- * @returns Padded scope name for consistent formatting
271
- */
272
- get formattedScope() {
273
- return this.scope.name.padEnd(this.STANDARD_SCOPE_LENGTH);
274
- }
275
- // =============================================
276
- // Message Compilation and Formatting
277
- // =============================================
278
- /**
279
- * Compile log arguments into formatted console output with colors and proper alignment
280
- *
281
- * This method handles the core formatting logic for all log messages:
282
- * - Applies terminal color codes for visual distinction
283
- * - Formats scope names with consistent padding
284
- * - Handles different data types appropriately
285
- * - Maintains proper indentation for multi-line content
286
- *
287
- * @param color - The color key to apply to the message
288
- * @param args - Variable arguments to format and display
289
- * @returns Array of formatted strings ready for console output
290
- */
291
- compile(color, ...args) {
292
- const timeString = this.getTime();
293
- const scopePadding = " ".repeat(this.scopeLength + 3);
294
- const isMultiArg = args.length > 1;
295
- return [
296
- // Header with color, scope, and timestamp
297
- `${A_LOGGER_ANSI.PREFIX}${this.COLORS[color]}${A_LOGGER_ANSI.SUFFIX}${A_LOGGER_FORMAT.SCOPE_OPEN}${this.formattedScope}${A_LOGGER_FORMAT.SCOPE_CLOSE} ${A_LOGGER_FORMAT.TIME_OPEN}${timeString}${A_LOGGER_FORMAT.TIME_CLOSE}`,
298
- // Top separator for multi-argument messages
299
- isMultiArg ? `
300
- ${scopePadding}${A_LOGGER_FORMAT.TIME_OPEN}${A_LOGGER_FORMAT.SEPARATOR}` : "",
301
- // Process each argument with appropriate formatting
302
- ...args.map((arg, i) => {
303
- const shouldAddNewline = i > 0 || isMultiArg;
304
- switch (true) {
305
- case arg instanceof aConcept.A_Error:
306
- return this.compile_A_Error(arg);
307
- case arg instanceof Error:
308
- return this.compile_Error(arg);
309
- case (typeof arg === "object" && arg !== null):
310
- return this.formatObject(arg, shouldAddNewline, scopePadding);
311
- default:
312
- return this.formatString(String(arg), shouldAddNewline, scopePadding);
313
- }
314
- }),
315
- // Bottom separator and color reset
316
- isMultiArg ? `
317
- ${scopePadding}${A_LOGGER_FORMAT.TIME_OPEN}${A_LOGGER_FORMAT.SEPARATOR}${A_LOGGER_ANSI.RESET}` : A_LOGGER_ANSI.RESET
318
- ];
319
- }
320
- /**
321
- * Format an object for display with proper JSON indentation
322
- *
323
- * @param obj - The object to format
324
- * @param shouldAddNewline - Whether to add a newline prefix
325
- * @param scopePadding - The padding string for consistent alignment
326
- * @returns Formatted object string
327
- */
328
- formatObject(obj, shouldAddNewline, scopePadding) {
329
- let jsonString;
330
- try {
331
- jsonString = JSON.stringify(obj, null, 2);
332
- } catch (error) {
333
- const seen = /* @__PURE__ */ new WeakSet();
334
- jsonString = JSON.stringify(obj, (key, value) => {
335
- if (typeof value === "object" && value !== null) {
336
- if (seen.has(value)) {
337
- return "[Circular Reference]";
338
- }
339
- seen.add(value);
340
- }
341
- return value;
342
- }, 2);
343
- }
344
- const formatted = jsonString.replace(/\n/g, `
345
- ${scopePadding}${A_LOGGER_FORMAT.PIPE}`);
346
- return shouldAddNewline ? `
347
- ${scopePadding}${A_LOGGER_FORMAT.PIPE}` + formatted : formatted;
348
- }
349
- /**
350
- * Format a string for display with proper indentation
351
- *
352
- * @param str - The string to format
353
- * @param shouldAddNewline - Whether to add a newline prefix
354
- * @param scopePadding - The padding string for consistent alignment
355
- * @returns Formatted string
356
- */
357
- formatString(str, shouldAddNewline, scopePadding) {
358
- const prefix = shouldAddNewline ? "\n" : "";
359
- return (prefix + str).replace(/\n/g, `
360
- ${scopePadding}${A_LOGGER_FORMAT.PIPE}`);
361
- }
362
- // =============================================
363
- // Log Level Management
364
- // =============================================
365
- /**
366
- * Determine if a log message should be output based on configured log level
367
- *
368
- * Log level hierarchy:
369
- * - debug: Shows all messages
370
- * - info: Shows info, warning, and error messages
371
- * - warn: Shows warning and error messages only
372
- * - error: Shows error messages only
373
- * - all: Shows all messages (alias for debug)
374
- *
375
- * @param logMethod - The type of log method being called
376
- * @returns True if the message should be logged, false otherwise
377
- */
378
- shouldLog(logMethod) {
379
- const shouldLog = this.config?.get(A_LOGGER_ENV_KEYS.LOG_LEVEL) || "all";
380
- switch (shouldLog) {
381
- case "debug":
382
- return true;
383
- case "info":
384
- return logMethod === "log" || logMethod === "warning" || logMethod === "error";
385
- case "warn":
386
- return logMethod === "warning" || logMethod === "error";
387
- case "error":
388
- return logMethod === "error";
389
- case "all":
390
- return true;
391
- default:
392
- return false;
393
- }
394
- }
395
- log(param1, ...args) {
396
- if (!this.shouldLog("log")) return;
397
- if (typeof param1 === "string" && this.COLORS[param1]) {
398
- console.log(...this.compile(param1, ...args));
399
- } else {
400
- console.log(...this.compile("blue", param1, ...args));
401
- }
402
- }
403
- /**
404
- * Log warning messages with yellow color coding
405
- *
406
- * Use for non-critical issues that should be brought to attention
407
- * but don't prevent normal operation
408
- *
409
- * @param args - Arguments to log as warnings
410
- *
411
- * @example
412
- * ```typescript
413
- * logger.warning('Deprecated method used');
414
- * logger.warning('Rate limit approaching:', { current: 95, limit: 100 });
415
- * ```
416
- */
417
- warning(...args) {
418
- if (!this.shouldLog("warning")) return;
419
- console.log(...this.compile("yellow", ...args));
420
- }
421
- /**
422
- * Log error messages with red color coding
423
- *
424
- * Use for critical issues, exceptions, and failures that need immediate attention
425
- *
426
- * @param args - Arguments to log as errors
427
- * @returns void (for compatibility with console.log)
428
- *
429
- * @example
430
- * ```typescript
431
- * logger.error('Database connection failed');
432
- * logger.error(new Error('Validation failed'));
433
- * logger.error('Critical error:', error, { context: 'user-registration' });
434
- * ```
435
- */
436
- error(...args) {
437
- if (!this.shouldLog("error")) return;
438
- console.log(...this.compile("red", ...args));
439
- }
440
- // =============================================
441
- // Specialized Error Formatting
442
- // =============================================
443
- /**
444
- * Legacy method for A_Error logging (kept for backward compatibility)
445
- *
446
- * @deprecated Use error() method instead which handles A_Error automatically
447
- * @param error - The A_Error instance to log
448
- */
449
- log_A_Error(error) {
450
- const time = this.getTime();
451
- const scopePadding = " ".repeat(this.scopeLength + 3);
452
- console.log(`\x1B[31m[${this.formattedScope}] |${time}| ERROR ${error.code}
453
- ${scopePadding}| ${error.message}
454
- ${scopePadding}| ${error.description}
455
- ${scopePadding}|-------------------------------
456
- ${scopePadding}| ${error.stack?.split("\n").map((line, index) => index === 0 ? line : `${scopePadding}| ${line}`).join("\n") || "No stack trace"}
457
- ${scopePadding}|-------------------------------
458
- \x1B[0m` + (error.originalError ? `\x1B[31m${scopePadding}| Wrapped From ${error.originalError.message}
459
- ${scopePadding}|-------------------------------
460
- ${scopePadding}| ${error.originalError.stack?.split("\n").map((line, index) => index === 0 ? line : `${scopePadding}| ${line}`).join("\n") || "No stack trace"}
461
- ${scopePadding}|-------------------------------
462
- \x1B[0m` : "") + (error.link ? `\x1B[31m${scopePadding}| Read in docs: ${error.link}
463
- ${scopePadding}|-------------------------------
464
- \x1B[0m` : ""));
465
- }
466
- /**
467
- * Format A_Error instances for inline display within compiled messages
468
- *
469
- * Provides detailed formatting for A_Error objects including:
470
- * - Error code and message
471
- * - Description and stack trace
472
- * - Original error information (if wrapped)
473
- * - Documentation links (if available)
474
- *
475
- * @param error - The A_Error instance to format
476
- * @returns Formatted string ready for display
477
- */
478
- compile_A_Error(error) {
479
- const scopePadding = " ".repeat(this.scopeLength + 3);
480
- return `
481
- ${scopePadding}|-------------------------------
482
- ${scopePadding}| Error: | ${error.code}
483
- ${scopePadding}|-------------------------------
484
- ${scopePadding}|${" ".repeat(10)}| ${error.message}
485
- ${scopePadding}|${" ".repeat(10)}| ${error.description}
486
- ${scopePadding}|-------------------------------
487
- ${scopePadding}| ${error.stack?.split("\n").map((line, index) => index === 0 ? line : `${scopePadding}| ${line}`).join("\n") || "No stack trace"}
488
- ${scopePadding}|-------------------------------` + (error.originalError ? `${scopePadding}| Wrapped From ${error.originalError.message}
489
- ${scopePadding}|-------------------------------
490
- ${scopePadding}| ${error.originalError.stack?.split("\n").map((line, index) => index === 0 ? line : `${scopePadding}| ${line}`).join("\n") || "No stack trace"}
491
- ${scopePadding}|-------------------------------` : "") + (error.link ? `${scopePadding}| Read in docs: ${error.link}
492
- ${scopePadding}|-------------------------------` : "");
493
- }
494
- /**
495
- * Format standard Error instances for inline display within compiled messages
496
- *
497
- * Converts standard JavaScript Error objects into a readable JSON format
498
- * with proper indentation and stack trace formatting
499
- *
500
- * @param error - The Error instance to format
501
- * @returns Formatted string ready for display
502
- */
503
- compile_Error(error) {
504
- const scopePadding = " ".repeat(this.scopeLength + 3);
505
- return JSON.stringify({
506
- name: error.name,
507
- message: error.message,
508
- stack: error.stack?.split("\n").map((line, index) => index === 0 ? line : `${scopePadding}| ${line}`).join("\n")
509
- }, null, 2).replace(/\n/g, `
510
- ${scopePadding}| `).replace(/\\n/g, "\n");
511
- }
512
- // =============================================
513
- // Utility Methods
514
- // =============================================
515
- /**
516
- * Generate timestamp string for log messages
517
- *
518
- * Format: MM:SS:mmm (minutes:seconds:milliseconds)
519
- * This provides sufficient precision for debugging while remaining readable
520
- *
521
- * @returns Formatted timestamp string
522
- *
523
- * @example
524
- * Returns: "15:42:137" for 3:42:15 PM and 137 milliseconds
525
- */
526
- getTime() {
527
- const now = /* @__PURE__ */ new Date();
528
- const minutes = String(now.getMinutes()).padStart(A_LOGGER_TIME_FORMAT.MINUTES_PAD, "0");
529
- const seconds = String(now.getSeconds()).padStart(A_LOGGER_TIME_FORMAT.SECONDS_PAD, "0");
530
- const milliseconds = String(now.getMilliseconds()).padStart(A_LOGGER_TIME_FORMAT.MILLISECONDS_PAD, "0");
531
- return `${minutes}${A_LOGGER_TIME_FORMAT.SEPARATOR}${seconds}${A_LOGGER_TIME_FORMAT.SEPARATOR}${milliseconds}`;
532
- }
533
- };
534
- exports.A_Logger = __decorateClass([
535
- __decorateParam(0, aConcept.A_Inject(aConcept.A_Scope)),
536
- __decorateParam(1, aConcept.A_Inject(A_Config))
537
- ], exports.A_Logger);
538
-
539
- // src/lib/A-Channel/A-Channel.component.ts
540
- var A_Channel = class extends aConcept.A_Component {
541
- /**
542
- * Creates a new A_Channel instance.
543
- *
544
- * The channel must be registered with A_Context before use:
545
- * ```typescript
546
- * const channel = new A_Channel();
547
- * A_Context.root.register(channel);
548
- * ```
549
- */
550
- constructor() {
551
- super();
552
- /**
553
- * Indicates whether the channel is currently processing requests.
554
- * This flag is managed automatically during request/send operations.
555
- *
556
- * @readonly
557
- */
558
- this._processing = false;
559
- /**
560
- * Internal cache storage for channel-specific data.
561
- * Can be used by custom implementations for caching responses,
562
- * connection pools, or other channel-specific state.
563
- *
564
- * @protected
565
- */
566
- this._cache = /* @__PURE__ */ new Map();
567
- }
568
- /**
569
- * Indicates whether the channel is currently processing requests.
570
- *
571
- * @returns {boolean} True if channel is processing, false otherwise
572
- */
573
- get processing() {
574
- return this._processing;
575
- }
576
- /**
577
- * Promise that resolves when the channel is fully initialized.
578
- *
579
- * Automatically calls the onConnect lifecycle hook if not already called.
580
- * This ensures the channel is ready for communication operations.
581
- *
582
- * @returns {Promise<void>} Promise that resolves when initialization is complete
583
- */
584
- get initialize() {
585
- if (!this._initialized) {
586
- this._initialized = this.connect();
587
- }
588
- return this._initialized;
589
- }
590
- async onConnect(...args) {
591
- }
592
- async onDisconnect(...args) {
593
- }
594
- async onBeforeRequest(...args) {
595
- }
596
- async onRequest(...args) {
597
- }
598
- async onAfterRequest(...args) {
599
- }
600
- async onError(...args) {
601
- }
602
- async onSend(...args) {
603
- }
604
- // ==========================================================
605
- // ================= Public API Methods ===================
606
- // ==========================================================
607
- /**
608
- * Initializes the channel by calling the onConnect lifecycle hook.
609
- *
610
- * This method is called automatically when accessing the `initialize` property.
611
- * You can also call it manually if needed.
612
- *
613
- * @returns {Promise<void>} Promise that resolves when connection is established
614
- */
615
- async connect() {
616
- await this.call("onConnect" /* onConnect */);
617
- }
618
- /**
619
- * Disconnects the channel by calling the onDisconnect lifecycle hook.
620
- *
621
- * Use this method to properly cleanup resources when the channel is no longer needed.
622
- *
623
- * @returns {Promise<void>} Promise that resolves when cleanup is complete
624
- */
625
- async disconnect() {
626
- await this.call("onDisconnect" /* onDisconnect */);
627
- }
628
- /**
629
- * Sends a request and waits for a response (Request/Response pattern).
630
- *
631
- * This method follows the complete request lifecycle:
632
- * 1. Ensures channel is initialized
633
- * 2. Creates request scope and context
634
- * 3. Calls onBeforeRequest hook
635
- * 4. Calls onRequest hook (main processing)
636
- * 5. Calls onAfterRequest hook
637
- * 6. Returns the response context
638
- *
639
- * If any step fails, the onError hook is called and the error is captured
640
- * in the returned context.
641
- *
642
- * @template _ParamsType The type of request parameters
643
- * @template _ResultType The type of response data
644
- * @param params The request parameters
645
- * @returns {Promise<A_ChannelRequest<_ParamsType, _ResultType>>} Request context with response
646
- *
647
- * @example
648
- * ```typescript
649
- * // Basic usage
650
- * const response = await channel.request({ action: 'getData', id: 123 });
651
- *
652
- * // Typed usage
653
- * interface UserRequest { userId: string; }
654
- * interface UserResponse { name: string; email: string; }
655
- *
656
- * const userResponse = await channel.request<UserRequest, UserResponse>({
657
- * userId: 'user-123'
658
- * });
659
- *
660
- * if (!userResponse.failed) {
661
- * console.log('User:', userResponse.data.name);
662
- * }
663
- * ```
664
- */
665
- async request(params) {
666
- await this.initialize;
667
- this._processing = true;
668
- const requestScope = new aConcept.A_Scope({
669
- name: `a-channel@scope:request:${aConcept.A_IdentityHelper.generateTimeId()}`
670
- });
671
- const context = new A_ChannelRequest(params);
672
- try {
673
- requestScope.inherit(aConcept.A_Context.scope(this));
674
- requestScope.register(context);
675
- await this.call("onBeforeRequest" /* onBeforeRequest */, requestScope);
676
- await this.call("onRequest" /* onRequest */, requestScope);
677
- await this.call("onAfterRequest" /* onAfterRequest */, requestScope);
678
- this._processing = false;
679
- return context;
680
- } catch (error) {
681
- this._processing = false;
682
- const channelError = new A_ChannelError(error);
683
- context.fail(channelError);
684
- await this.call("onError" /* onError */, requestScope);
685
- return context;
686
- }
687
- }
688
- /**
689
- * Sends a fire-and-forget message (Send pattern).
690
- *
691
- * This method is used for one-way communication where no response is expected:
692
- * - Event broadcasting
693
- * - Notification sending
694
- * - Message queuing
695
- * - Logging operations
696
- *
697
- * The method follows this lifecycle:
698
- * 1. Ensures channel is initialized
699
- * 2. Creates send scope and context
700
- * 3. Calls onSend hook
701
- * 4. Completes without returning data
702
- *
703
- * If the operation fails, the onError hook is called but no error is thrown
704
- * to the caller (fire-and-forget semantics).
705
- *
706
- * @template _ParamsType The type of message parameters
707
- * @param message The message to send
708
- * @returns {Promise<void>} Promise that resolves when send is complete
709
- *
710
- * @example
711
- * ```typescript
712
- * // Send notification
713
- * await channel.send({
714
- * type: 'user.login',
715
- * userId: 'user-123',
716
- * timestamp: new Date().toISOString()
717
- * });
718
- *
719
- * // Send to message queue
720
- * await channel.send({
721
- * queue: 'email-queue',
722
- * payload: {
723
- * to: 'user@example.com',
724
- * subject: 'Welcome!',
725
- * body: 'Welcome to our service!'
726
- * }
727
- * });
728
- * ```
729
- */
730
- async send(message) {
731
- await this.initialize;
732
- this._processing = true;
733
- const requestScope = new aConcept.A_Scope({
734
- name: `a-channel@scope:send:${aConcept.A_IdentityHelper.generateTimeId()}`
735
- });
736
- const context = new A_ChannelRequest(message);
737
- try {
738
- requestScope.inherit(aConcept.A_Context.scope(this));
739
- requestScope.register(context);
740
- await this.call("onSend" /* onSend */, requestScope);
741
- this._processing = false;
742
- } catch (error) {
743
- this._processing = false;
744
- const channelError = new A_ChannelError(error);
745
- context.fail(channelError);
746
- await this.call("onError" /* onError */, requestScope);
747
- }
748
- }
749
- /**
750
- * @deprecated This method is deprecated and will be removed in future versions.
751
- * Use request() or send() methods instead depending on your communication pattern.
752
- *
753
- * For request/response pattern: Use request()
754
- * For fire-and-forget pattern: Use send()
755
- * For consumer patterns: Implement custom consumer logic using request() in a loop
756
- */
757
- async consume() {
758
- await this.initialize;
759
- this._processing = true;
760
- const requestScope = new aConcept.A_Scope({ name: `a-channel@scope:consume:${aConcept.A_IdentityHelper.generateTimeId()}` });
761
- const context = new A_ChannelRequest();
762
- try {
763
- requestScope.inherit(aConcept.A_Context.scope(this));
764
- requestScope.register(context);
765
- await this.call("onConsume" /* onConsume */, requestScope);
766
- this._processing = false;
767
- return context;
768
- } catch (error) {
769
- this._processing = false;
770
- const channelError = new A_ChannelError(error);
771
- context.fail(channelError);
772
- await this.call("onError" /* onError */, requestScope);
773
- return context;
774
- }
775
- }
776
- };
777
- __decorateClass([
778
- aConcept.A_Feature.Extend({
779
- name: "onConnect" /* onConnect */
780
- })
781
- ], A_Channel.prototype, "onConnect", 1);
782
- __decorateClass([
783
- aConcept.A_Feature.Extend({
784
- name: "onDisconnect" /* onDisconnect */
785
- })
786
- ], A_Channel.prototype, "onDisconnect", 1);
787
- __decorateClass([
788
- aConcept.A_Feature.Extend({
789
- name: "onBeforeRequest" /* onBeforeRequest */
790
- })
791
- ], A_Channel.prototype, "onBeforeRequest", 1);
792
- __decorateClass([
793
- aConcept.A_Feature.Extend({
794
- name: "onRequest" /* onRequest */
795
- })
796
- ], A_Channel.prototype, "onRequest", 1);
797
- __decorateClass([
798
- aConcept.A_Feature.Extend({
799
- name: "onAfterRequest" /* onAfterRequest */
800
- })
801
- ], A_Channel.prototype, "onAfterRequest", 1);
802
- __decorateClass([
803
- aConcept.A_Feature.Extend({
804
- name: "onError" /* onError */
805
- })
806
- ], A_Channel.prototype, "onError", 1);
807
- __decorateClass([
808
- aConcept.A_Feature.Extend({
809
- name: "onSend" /* onSend */
810
- })
811
- ], A_Channel.prototype, "onSend", 1);
812
- var HttpChannel = class extends A_Channel {
813
- };
814
- var PollyspotChannel = class extends HttpChannel {
815
- constructor() {
816
- super();
817
- this.baseUrl = "https://pollyspot.example.com";
818
- }
819
- };
820
- var GlobalErrorhandler = class extends aConcept.A_Component {
821
- async handleError(context, logger, config) {
822
- }
823
- async anotherError(context, logger, config) {
824
- }
825
- };
826
- __decorateClass([
827
- aConcept.A_Feature.Extend({
828
- name: "onError" /* onError */,
829
- scope: [PollyspotChannel]
830
- }),
831
- __decorateParam(0, aConcept.A_Inject(A_ChannelRequest)),
832
- __decorateParam(1, aConcept.A_Inject(exports.A_Logger)),
833
- __decorateParam(2, aConcept.A_Inject(A_Config))
834
- ], GlobalErrorhandler.prototype, "handleError", 1);
835
- __decorateClass([
836
- aConcept.A_Feature.Extend({
837
- name: "onError" /* onError */
838
- }),
839
- __decorateParam(0, aConcept.A_Inject(A_ChannelRequest)),
840
- __decorateParam(1, aConcept.A_Inject(exports.A_Logger)),
841
- __decorateParam(2, aConcept.A_Inject(A_Config))
842
- ], GlobalErrorhandler.prototype, "anotherError", 1);
843
-
844
- // src/lib/A-Command/A-Command.constants.ts
845
- var A_CONSTANTS__A_Command_Status = /* @__PURE__ */ ((A_CONSTANTS__A_Command_Status2) => {
846
- A_CONSTANTS__A_Command_Status2["CREATED"] = "CREATED";
847
- A_CONSTANTS__A_Command_Status2["INITIALIZATION"] = "INITIALIZATION";
848
- A_CONSTANTS__A_Command_Status2["INITIALIZED"] = "INITIALIZED";
849
- A_CONSTANTS__A_Command_Status2["COMPILATION"] = "COMPILATION";
850
- A_CONSTANTS__A_Command_Status2["COMPILED"] = "COMPILED";
851
- A_CONSTANTS__A_Command_Status2["IN_PROGRESS"] = "IN_PROGRESS";
852
- A_CONSTANTS__A_Command_Status2["COMPLETED"] = "COMPLETED";
853
- A_CONSTANTS__A_Command_Status2["FAILED"] = "FAILED";
854
- return A_CONSTANTS__A_Command_Status2;
855
- })(A_CONSTANTS__A_Command_Status || {});
856
- var A_CommandFeatures = /* @__PURE__ */ ((A_CommandFeatures2) => {
857
- A_CommandFeatures2["onInit"] = "onInit";
858
- A_CommandFeatures2["onCompile"] = "onCompile";
859
- A_CommandFeatures2["onExecute"] = "onExecute";
860
- A_CommandFeatures2["onComplete"] = "onComplete";
861
- A_CommandFeatures2["onFail"] = "onFail";
862
- return A_CommandFeatures2;
863
- })(A_CommandFeatures || {});
864
- var A_Memory = class extends aConcept.A_Fragment {
865
- /**
866
- * Memory object that allows to store intermediate values and errors
867
- *
868
- * @param initialValues
869
- */
870
- constructor(initialValues) {
871
- super();
872
- this._memory = new Map(Object.entries(initialValues || {}));
873
- this._errors = /* @__PURE__ */ new Set();
874
- }
875
- get Errors() {
876
- return this._errors.size > 0 ? this._errors : void 0;
877
- }
878
- /**
879
- * Verifies that all required keys are present in the proxy values
880
- *
881
- * @param requiredKeys
882
- * @returns
883
- */
884
- async prerequisites(requiredKeys) {
885
- return requiredKeys.every((key) => this._memory.has(key));
886
- }
887
- /**
888
- * Adds an error to the context
889
- *
890
- * @param error
891
- */
892
- async error(error) {
893
- this._errors.add(error);
894
- }
895
- /**
896
- * Retrieves a value from the context memory
897
- *
898
- * @param key
899
- * @returns
900
- */
901
- get(key) {
902
- return this._memory.get(key);
903
- }
904
- /**
905
- * Saves a value in the context memory
906
- *
907
- * @param key
908
- * @param value
909
- */
910
- async set(key, value) {
911
- this._memory.set(key, value);
912
- }
913
- /**
914
- * Removes a value from the context memory by key
915
- *
916
- * @param key
917
- */
918
- async drop(key) {
919
- this._memory.delete(key);
920
- }
921
- /**
922
- * Clears all stored values in the context memory
923
- */
924
- async clear() {
925
- this._memory.clear();
926
- }
927
- /**
928
- * Converts all stored values to a plain object
929
- *
930
- * [!] By default uses all saved in memory values
931
- *
932
- * @returns
933
- */
934
- toJSON() {
935
- const obj = {};
936
- this._memory.forEach((value, key) => {
937
- obj[key] = typeof value === "object" && value !== null && "toJSON" in value && typeof value.toJSON === "function" ? value.toJSON() : value;
938
- });
939
- return obj;
940
- }
941
- };
942
- var A_CommandError = class extends aConcept.A_Error {
943
- };
944
- A_CommandError.CommandScopeBindingError = "A-Command Scope Binding Error";
945
-
946
- // src/lib/A-Command/A-Command.entity.ts
947
- var A_Command = class extends aConcept.A_Entity {
948
- /**
949
- *
950
- * A-Command represents an executable command with a specific code and parameters.
951
- * It can be executed within a given scope and stores execution results and errors.
952
- *
953
- *
954
- * A-Command should be context independent and execution logic should be based on attached components
955
- *
956
- * @param code
957
- * @param params
958
- */
959
- constructor(params) {
960
- super(params);
961
- this._listeners = /* @__PURE__ */ new Map();
962
- }
963
- // ====================================================================
964
- // ================== Static A-Command Information ====================
965
- // ====================================================================
966
- /**
967
- * Command Identifier that corresponds to the class name
968
- */
969
- static get code() {
970
- return super.entity;
971
- }
972
- /**
973
- * Execution Duration in milliseconds
974
- */
975
- get duration() {
976
- return this._endTime && this._startTime ? this._endTime.getTime() - this._startTime.getTime() : this._startTime ? (/* @__PURE__ */ new Date()).getTime() - this._startTime.getTime() : void 0;
977
- }
978
- /**
979
- * A shared scope between all features of the command during its execution
980
- */
981
- get scope() {
982
- return this._executionScope;
983
- }
984
- /**
985
- * Unique code identifying the command type
986
- * Example: 'user.create', 'task.complete', etc.
987
- *
988
- */
989
- get code() {
990
- return this.constructor.code;
991
- }
992
- /**
993
- * Current status of the command
994
- */
995
- get status() {
996
- return this._status;
997
- }
998
- /**
999
- * Start time of the command execution
1000
- */
1001
- get startedAt() {
1002
- return this._startTime;
1003
- }
1004
- /**
1005
- * End time of the command execution
1006
- */
1007
- get endedAt() {
1008
- return this._endTime;
1009
- }
1010
- /**
1011
- * Result of the command execution stored in the context
1012
- */
1013
- get result() {
1014
- return this._result;
1015
- }
1016
- /**
1017
- * Errors encountered during the command execution stored in the context
1018
- */
1019
- get errors() {
1020
- return this._errors;
1021
- }
1022
- /**
1023
- * Parameters used to invoke the command
1024
- */
1025
- get params() {
1026
- return this._params;
1027
- }
1028
- /**
1029
- * Indicates if the command has failed
1030
- */
1031
- get isFailed() {
1032
- return this._status === "FAILED" /* FAILED */;
1033
- }
1034
- /**
1035
- * Indicates if the command has completed successfully
1036
- */
1037
- get isCompleted() {
1038
- return this._status === "COMPLETED" /* COMPLETED */;
1039
- }
1040
- // --------------------------------------------------------------------------
1041
- // A-Command Lifecycle Methods
1042
- // --------------------------------------------------------------------------
1043
- // should create a new Task in DB with basic records
1044
- async init() {
1045
- if (this._status !== "CREATED" /* CREATED */) {
1046
- return;
1047
- }
1048
- this._status = "INITIALIZATION" /* INITIALIZATION */;
1049
- this._startTime = /* @__PURE__ */ new Date();
1050
- this.emit("onInit" /* onInit */);
1051
- await this.call("onInit" /* onInit */, this.scope);
1052
- this._status = "INITIALIZED" /* INITIALIZED */;
1053
- }
1054
- // Should compile everything before execution
1055
- async compile() {
1056
- if (this._status !== "INITIALIZED" /* INITIALIZED */) {
1057
- return;
1058
- }
1059
- this.checkScopeInheritance();
1060
- this._status = "COMPILATION" /* COMPILATION */;
1061
- this.emit("onCompile" /* onCompile */);
1062
- await this.call("onCompile" /* onCompile */, this.scope);
1063
- this._status = "COMPILED" /* COMPILED */;
1064
- }
1065
- /**
1066
- * Processes the command execution
1067
- *
1068
- * @returns
1069
- */
1070
- async process() {
1071
- if (this._status !== "COMPILED" /* COMPILED */)
1072
- return;
1073
- this._status = "IN_PROGRESS" /* IN_PROGRESS */;
1074
- this.checkScopeInheritance();
1075
- this.emit("onExecute" /* onExecute */);
1076
- await this.call("onExecute" /* onExecute */, this.scope);
1077
- }
1078
- /**
1079
- * Executes the command logic.
1080
- */
1081
- async execute() {
1082
- this.checkScopeInheritance();
1083
- try {
1084
- await this.init();
1085
- await this.compile();
1086
- await this.process();
1087
- await this.complete();
1088
- } catch (error) {
1089
- await this.fail();
1090
- }
1091
- this._executionScope.destroy();
1092
- }
1093
- /**
1094
- * Marks the command as completed
1095
- */
1096
- async complete() {
1097
- this.checkScopeInheritance();
1098
- this._status = "COMPLETED" /* COMPLETED */;
1099
- this._endTime = /* @__PURE__ */ new Date();
1100
- this._result = this.scope.resolve(A_Memory).toJSON();
1101
- this.emit("onComplete" /* onComplete */);
1102
- await this.call("onComplete" /* onComplete */, this.scope);
1103
- }
1104
- /**
1105
- * Marks the command as failed
1106
- */
1107
- async fail() {
1108
- this.checkScopeInheritance();
1109
- this._status = "FAILED" /* FAILED */;
1110
- this._endTime = /* @__PURE__ */ new Date();
1111
- this._errors = this.scope.resolve(A_Memory).Errors;
1112
- this.emit("onFail" /* onFail */);
1113
- await this.call("onFail" /* onFail */, this.scope);
1114
- }
1115
- // --------------------------------------------------------------------------
1116
- // A-Command Event-Emitter methods
1117
- // --------------------------------------------------------------------------
1118
- /**
1119
- * Registers an event listener for a specific event
1120
- *
1121
- * @param event
1122
- * @param listener
1123
- */
1124
- on(event, listener) {
1125
- if (!this._listeners.has(event)) {
1126
- this._listeners.set(event, /* @__PURE__ */ new Set());
1127
- }
1128
- this._listeners.get(event).add(listener);
1129
- }
1130
- /**
1131
- * Removes an event listener for a specific event
1132
- *
1133
- * @param event
1134
- * @param listener
1135
- */
1136
- off(event, listener) {
1137
- this._listeners.get(event)?.delete(listener);
1138
- }
1139
- /**
1140
- * Emits an event to all registered listeners
1141
- *
1142
- * @param event
1143
- */
1144
- emit(event) {
1145
- this._listeners.get(event)?.forEach((listener) => {
1146
- listener(this);
1147
- });
1148
- }
1149
- // --------------------------------------------------------------------------
1150
- // A-Entity Base Class Overrides
1151
- // --------------------------------------------------------------------------
1152
- // Serialization / Deserialization
1153
- // -------------------------------------------------------------------------
1154
- /**
1155
- * Allows to create a Command instance from new data
1156
- *
1157
- * @param newEntity
1158
- */
1159
- fromNew(newEntity) {
1160
- super.fromNew(newEntity);
1161
- this._executionScope = new aConcept.A_Scope();
1162
- this._executionScope.register(new A_Memory());
1163
- this._params = newEntity;
1164
- this._status = "CREATED" /* CREATED */;
1165
- }
1166
- /**
1167
- * Allows to convert serialized data to Command instance
1168
- *
1169
- * [!] By default it omits params as they are not stored in the serialized data
1170
- *
1171
- * @param serialized
1172
- */
1173
- fromJSON(serialized) {
1174
- super.fromJSON(serialized);
1175
- this._executionScope = new aConcept.A_Scope();
1176
- const memory = new A_Memory();
1177
- this._executionScope.register(memory);
1178
- if (serialized.startedAt) this._startTime = new Date(serialized.startedAt);
1179
- if (serialized.endedAt) this._endTime = new Date(serialized.endedAt);
1180
- if (serialized.result) {
1181
- Object.entries(serialized.result).forEach(([key, value]) => {
1182
- memory.set(key, value);
1183
- });
1184
- }
1185
- if (serialized.errors) {
1186
- serialized.errors.forEach((err) => {
1187
- memory.error(new aConcept.A_Error(err));
1188
- });
1189
- }
1190
- this._params = serialized.params;
1191
- this._status = serialized.status || "CREATED" /* CREATED */;
1192
- }
1193
- /**
1194
- * Converts the Command instance to a plain object
1195
- *
1196
- * @returns
1197
- */
1198
- toJSON() {
1199
- return {
1200
- ...super.toJSON(),
1201
- code: this.code,
1202
- status: this._status,
1203
- params: this._params,
1204
- startedAt: this._startTime ? this._startTime.toISOString() : void 0,
1205
- endedAt: this._endTime ? this._endTime.toISOString() : void 0,
1206
- duration: this.duration,
1207
- result: this.result,
1208
- errors: this.errors ? Array.from(this.errors).map((err) => err.toJSON()) : void 0
1209
- };
1210
- }
1211
- checkScopeInheritance() {
1212
- let attachedScope;
1213
- try {
1214
- attachedScope = aConcept.A_Context.scope(this);
1215
- } catch (error) {
1216
- throw new A_CommandError({
1217
- title: A_CommandError.CommandScopeBindingError,
1218
- description: `Command ${this.code} is not bound to any context scope. Ensure the command is properly registered within a context before execution.`,
1219
- originalError: error
1220
- });
1221
- }
1222
- if (!this.scope.isInheritedFrom(aConcept.A_Context.scope(this))) {
1223
- this.scope.inherit(aConcept.A_Context.scope(this));
1224
- }
1225
- }
1226
- };
1227
- var A_FSPolyfillClass = class {
1228
- constructor(logger) {
1229
- this.logger = logger;
1230
- this._initialized = false;
1231
- }
1232
- get isInitialized() {
1233
- return this._initialized;
1234
- }
1235
- async get() {
1236
- if (!this._initialized) {
1237
- await this.init();
1238
- }
1239
- return this._fs;
1240
- }
1241
- async init() {
1242
- try {
1243
- if (aConcept.A_Context.environment === "server") {
1244
- await this.initServer();
1245
- } else {
1246
- this.initBrowser();
1247
- }
1248
- this._initialized = true;
1249
- } catch (error) {
1250
- this.initBrowser();
1251
- this._initialized = true;
1252
- }
1253
- }
1254
- async initServer() {
1255
- this._fs = await import('fs');
1256
- }
1257
- initBrowser() {
1258
- this._fs = {
1259
- readFileSync: (path, encoding) => {
1260
- this.logger.warning("fs.readFileSync not available in browser environment");
1261
- return "";
1262
- },
1263
- existsSync: (path) => {
1264
- this.logger.warning("fs.existsSync not available in browser environment");
1265
- return false;
1266
- },
1267
- createReadStream: (path) => {
1268
- this.logger.warning("fs.createReadStream not available in browser environment");
1269
- return null;
1270
- }
1271
- };
1272
- }
1273
- };
1274
- var A_CryptoPolyfillClass = class {
1275
- constructor(logger) {
1276
- this.logger = logger;
1277
- this._initialized = false;
1278
- }
1279
- get isInitialized() {
1280
- return this._initialized;
1281
- }
1282
- async get(fsPolyfill) {
1283
- if (!this._initialized) {
1284
- this._fsPolyfill = fsPolyfill;
1285
- await this.init();
1286
- }
1287
- return this._crypto;
1288
- }
1289
- async init() {
1290
- try {
1291
- if (aConcept.A_Context.environment === "server") {
1292
- await this.initServer();
1293
- } else {
1294
- this.initBrowser();
1295
- }
1296
- this._initialized = true;
1297
- } catch (error) {
1298
- this.initBrowser();
1299
- this._initialized = true;
1300
- }
1301
- }
1302
- async initServer() {
1303
- const crypto2 = await import('crypto');
1304
- this._crypto = {
1305
- createTextHash: (text, algorithm = "sha384") => Promise.resolve(
1306
- `${algorithm}-${crypto2.createHash(algorithm).update(text).digest("base64")}`
1307
- ),
1308
- createFileHash: (filePath, algorithm = "sha384") => new Promise(async (resolve, reject) => {
1309
- try {
1310
- if (!this._fsPolyfill) {
1311
- throw new Error("FS polyfill is required for file hashing");
1312
- }
1313
- const hash = crypto2.createHash(algorithm);
1314
- const fileStream = this._fsPolyfill.createReadStream(filePath);
1315
- fileStream.on("data", (data) => hash.update(data));
1316
- fileStream.on("end", () => resolve(`${algorithm}-${hash.digest("base64")}`));
1317
- fileStream.on("error", (err) => reject(err));
1318
- } catch (error) {
1319
- reject(error);
1320
- }
1321
- })
1322
- };
1323
- }
1324
- initBrowser() {
1325
- this._crypto = {
1326
- createFileHash: () => {
1327
- this.logger.warning("File hash not available in browser environment");
1328
- return Promise.resolve("");
1329
- },
1330
- createTextHash: (text, algorithm = "SHA-384") => new Promise(async (resolve, reject) => {
1331
- try {
1332
- if (!crypto.subtle) {
1333
- throw new Error("SubtleCrypto not available");
1334
- }
1335
- const encoder = new TextEncoder();
1336
- const data = encoder.encode(text);
1337
- const hashBuffer = await crypto.subtle.digest(algorithm, data);
1338
- const hashArray = Array.from(new Uint8Array(hashBuffer));
1339
- const hashBase64 = btoa(String.fromCharCode(...hashArray));
1340
- resolve(`${algorithm}-${hashBase64}`);
1341
- } catch (error) {
1342
- reject(error);
1343
- }
1344
- })
1345
- };
1346
- }
1347
- };
1348
- var A_HttpPolyfillClass = class {
1349
- constructor(logger) {
1350
- this.logger = logger;
1351
- this._initialized = false;
1352
- }
1353
- get isInitialized() {
1354
- return this._initialized;
1355
- }
1356
- async get() {
1357
- if (!this._initialized) {
1358
- await this.init();
1359
- }
1360
- return this._http;
1361
- }
1362
- async init() {
1363
- try {
1364
- if (aConcept.A_Context.environment === "server") {
1365
- await this.initServer();
1366
- } else {
1367
- this.initBrowser();
1368
- }
1369
- this._initialized = true;
1370
- } catch (error) {
1371
- this.initBrowser();
1372
- this._initialized = true;
1373
- }
1374
- }
1375
- async initServer() {
1376
- const httpModule = await import('http');
1377
- this._http = {
1378
- request: httpModule.request,
1379
- get: httpModule.get,
1380
- createServer: httpModule.createServer
1381
- };
1382
- }
1383
- initBrowser() {
1384
- this._http = {
1385
- request: (options, callback) => {
1386
- this.logger.warning("http.request not available in browser/test environment, use fetch instead");
1387
- return this.createMockRequest(options, callback, false);
1388
- },
1389
- get: (url, callback) => {
1390
- this.logger.warning("http.get not available in browser/test environment, use fetch instead");
1391
- return this.createMockRequest(typeof url === "string" ? { hostname: url } : url, callback, false);
1392
- },
1393
- createServer: () => {
1394
- this.logger.error("http.createServer not available in browser/test environment");
1395
- return null;
1396
- }
1397
- };
1398
- }
1399
- createMockRequest(options, callback, isHttps = false) {
1400
- const request = {
1401
- end: () => {
1402
- if (callback) {
1403
- const mockResponse = {
1404
- statusCode: 200,
1405
- headers: {},
1406
- on: (event, handler) => {
1407
- if (event === "data") {
1408
- setTimeout(() => handler("mock data"), 0);
1409
- } else if (event === "end") {
1410
- setTimeout(() => handler(), 0);
1411
- }
1412
- },
1413
- pipe: (dest) => {
1414
- if (dest.write) dest.write("mock data");
1415
- if (dest.end) dest.end();
1416
- }
1417
- };
1418
- setTimeout(() => callback(mockResponse), 0);
1419
- }
1420
- },
1421
- write: (data) => {
1422
- },
1423
- on: (event, handler) => {
1424
- }
1425
- };
1426
- return request;
1427
- }
1428
- };
1429
- var A_HttpsPolyfillClass = class {
1430
- constructor(logger) {
1431
- this.logger = logger;
1432
- this._initialized = false;
1433
- }
1434
- get isInitialized() {
1435
- return this._initialized;
1436
- }
1437
- async get() {
1438
- if (!this._initialized) {
1439
- await this.init();
1440
- }
1441
- return this._https;
1442
- }
1443
- async init() {
1444
- try {
1445
- if (aConcept.A_Context.environment === "server") {
1446
- await this.initServer();
1447
- } else {
1448
- this.initBrowser();
1449
- }
1450
- this._initialized = true;
1451
- } catch (error) {
1452
- this.initBrowser();
1453
- this._initialized = true;
1454
- }
1455
- }
1456
- async initServer() {
1457
- const httpsModule = await import('https');
1458
- this._https = {
1459
- request: httpsModule.request,
1460
- get: httpsModule.get,
1461
- createServer: httpsModule.createServer
1462
- };
1463
- }
1464
- initBrowser() {
1465
- this._https = {
1466
- request: (options, callback) => {
1467
- this.logger.warning("https.request not available in browser/test environment, use fetch instead");
1468
- return this.createMockRequest(options, callback, true);
1469
- },
1470
- get: (url, callback) => {
1471
- this.logger.warning("https.get not available in browser/test environment, use fetch instead");
1472
- return this.createMockRequest(typeof url === "string" ? { hostname: url } : url, callback, true);
1473
- },
1474
- createServer: () => {
1475
- this.logger.error("https.createServer not available in browser/test environment");
1476
- return null;
1477
- }
1478
- };
1479
- }
1480
- createMockRequest(options, callback, isHttps = true) {
1481
- const request = {
1482
- end: () => {
1483
- if (callback) {
1484
- const mockResponse = {
1485
- statusCode: 200,
1486
- headers: {},
1487
- on: (event, handler) => {
1488
- if (event === "data") {
1489
- setTimeout(() => handler("mock data"), 0);
1490
- } else if (event === "end") {
1491
- setTimeout(() => handler(), 0);
1492
- }
1493
- },
1494
- pipe: (dest) => {
1495
- if (dest.write) dest.write("mock data");
1496
- if (dest.end) dest.end();
1497
- }
1498
- };
1499
- setTimeout(() => callback(mockResponse), 0);
1500
- }
1501
- },
1502
- write: (data) => {
1503
- },
1504
- on: (event, handler) => {
1505
- }
1506
- };
1507
- return request;
1508
- }
1509
- };
1510
- var A_PathPolyfillClass = class {
1511
- constructor(logger) {
1512
- this.logger = logger;
1513
- this._initialized = false;
1514
- }
1515
- get isInitialized() {
1516
- return this._initialized;
1517
- }
1518
- async get() {
1519
- if (!this._initialized) {
1520
- await this.init();
1521
- }
1522
- return this._path;
1523
- }
1524
- async init() {
1525
- try {
1526
- if (aConcept.A_Context.environment === "server") {
1527
- await this.initServer();
1528
- } else {
1529
- this.initBrowser();
1530
- }
1531
- this._initialized = true;
1532
- } catch (error) {
1533
- this.initBrowser();
1534
- this._initialized = true;
1535
- }
1536
- }
1537
- async initServer() {
1538
- this._path = await import('path');
1539
- }
1540
- initBrowser() {
1541
- this._path = {
1542
- join: (...paths) => {
1543
- return paths.join("/").replace(/\/+/g, "/");
1544
- },
1545
- resolve: (...paths) => {
1546
- let resolvedPath = "";
1547
- for (const path of paths) {
1548
- if (path.startsWith("/")) {
1549
- resolvedPath = path;
1550
- } else {
1551
- resolvedPath = this._path.join(resolvedPath, path);
1552
- }
1553
- }
1554
- return resolvedPath || "/";
1555
- },
1556
- dirname: (path) => {
1557
- const parts = path.split("/");
1558
- return parts.slice(0, -1).join("/") || "/";
1559
- },
1560
- basename: (path, ext) => {
1561
- const base = path.split("/").pop() || "";
1562
- return ext && base.endsWith(ext) ? base.slice(0, -ext.length) : base;
1563
- },
1564
- extname: (path) => {
1565
- const parts = path.split(".");
1566
- return parts.length > 1 ? "." + parts.pop() : "";
1567
- },
1568
- relative: (from, to) => {
1569
- return to.replace(from, "").replace(/^\//, "");
1570
- },
1571
- normalize: (path) => {
1572
- return path.replace(/\/+/g, "/").replace(/\/$/, "") || "/";
1573
- },
1574
- isAbsolute: (path) => {
1575
- return path.startsWith("/") || /^[a-zA-Z]:/.test(path);
1576
- },
1577
- parse: (path) => {
1578
- const ext = this._path.extname(path);
1579
- const base = this._path.basename(path);
1580
- const name = this._path.basename(path, ext);
1581
- const dir = this._path.dirname(path);
1582
- return { root: "/", dir, base, ext, name };
1583
- },
1584
- format: (pathObject) => {
1585
- return this._path.join(pathObject.dir || "", pathObject.base || "");
1586
- },
1587
- sep: "/",
1588
- delimiter: ":"
1589
- };
1590
- }
1591
- };
1592
- var A_UrlPolyfillClass = class {
1593
- constructor(logger) {
1594
- this.logger = logger;
1595
- this._initialized = false;
1596
- }
1597
- get isInitialized() {
1598
- return this._initialized;
1599
- }
1600
- async get() {
1601
- if (!this._initialized) {
1602
- await this.init();
1603
- }
1604
- return this._url;
1605
- }
1606
- async init() {
1607
- try {
1608
- if (aConcept.A_Context.environment === "server") {
1609
- await this.initServer();
1610
- } else {
1611
- this.initBrowser();
1612
- }
1613
- this._initialized = true;
1614
- } catch (error) {
1615
- this.initBrowser();
1616
- this._initialized = true;
1617
- }
1618
- }
1619
- async initServer() {
1620
- const urlModule = await import('url');
1621
- this._url = {
1622
- parse: urlModule.parse,
1623
- format: urlModule.format,
1624
- resolve: urlModule.resolve,
1625
- URL: urlModule.URL || globalThis.URL,
1626
- URLSearchParams: urlModule.URLSearchParams || globalThis.URLSearchParams
1627
- };
1628
- }
1629
- initBrowser() {
1630
- this._url = {
1631
- parse: (urlString) => {
1632
- try {
1633
- const url = new URL(urlString);
1634
- return {
1635
- protocol: url.protocol,
1636
- hostname: url.hostname,
1637
- port: url.port,
1638
- pathname: url.pathname,
1639
- search: url.search,
1640
- hash: url.hash,
1641
- host: url.host,
1642
- href: url.href
1643
- };
1644
- } catch {
1645
- return {};
1646
- }
1647
- },
1648
- format: (urlObject) => {
1649
- try {
1650
- return new URL("", urlObject.href || `${urlObject.protocol}//${urlObject.host}${urlObject.pathname}${urlObject.search}${urlObject.hash}`).href;
1651
- } catch {
1652
- return "";
1653
- }
1654
- },
1655
- resolve: (from, to) => {
1656
- try {
1657
- return new URL(to, from).href;
1658
- } catch {
1659
- return to;
1660
- }
1661
- },
1662
- URL: globalThis.URL,
1663
- URLSearchParams: globalThis.URLSearchParams
1664
- };
1665
- }
1666
- };
1667
- var A_BufferPolyfillClass = class {
1668
- constructor(logger) {
1669
- this.logger = logger;
1670
- this._initialized = false;
1671
- }
1672
- get isInitialized() {
1673
- return this._initialized;
1674
- }
1675
- async get() {
1676
- if (!this._initialized) {
1677
- await this.init();
1678
- }
1679
- return this._buffer;
1680
- }
1681
- async init() {
1682
- try {
1683
- if (aConcept.A_Context.environment === "server") {
1684
- await this.initServer();
1685
- } else {
1686
- this.initBrowser();
1687
- }
1688
- this._initialized = true;
1689
- } catch (error) {
1690
- this.initBrowser();
1691
- this._initialized = true;
1692
- }
1693
- }
1694
- async initServer() {
1695
- const bufferModule = await import('buffer');
1696
- this._buffer = {
1697
- from: bufferModule.Buffer.from,
1698
- alloc: bufferModule.Buffer.alloc,
1699
- allocUnsafe: bufferModule.Buffer.allocUnsafe,
1700
- isBuffer: bufferModule.Buffer.isBuffer,
1701
- concat: bufferModule.Buffer.concat
1702
- };
1703
- }
1704
- initBrowser() {
1705
- this._buffer = {
1706
- from: (data, encoding) => {
1707
- if (typeof data === "string") {
1708
- return new TextEncoder().encode(data);
1709
- }
1710
- return new Uint8Array(data);
1711
- },
1712
- alloc: (size, fill) => {
1713
- const buffer = new Uint8Array(size);
1714
- if (fill !== void 0) {
1715
- buffer.fill(fill);
1716
- }
1717
- return buffer;
1718
- },
1719
- allocUnsafe: (size) => {
1720
- return new Uint8Array(size);
1721
- },
1722
- isBuffer: (obj) => {
1723
- return obj instanceof Uint8Array || obj instanceof ArrayBuffer;
1724
- },
1725
- concat: (list, totalLength) => {
1726
- const length = totalLength || list.reduce((sum, buf) => sum + buf.length, 0);
1727
- const result = new Uint8Array(length);
1728
- let offset = 0;
1729
- for (const buf of list) {
1730
- result.set(buf, offset);
1731
- offset += buf.length;
1732
- }
1733
- return result;
1734
- }
1735
- };
1736
- }
1737
- };
1738
- var A_ProcessPolyfillClass = class {
1739
- constructor(logger) {
1740
- this.logger = logger;
1741
- this._initialized = false;
1742
- }
1743
- get isInitialized() {
1744
- return this._initialized;
1745
- }
1746
- async get() {
1747
- if (!this._initialized) {
1748
- await this.init();
1749
- }
1750
- return this._process;
1751
- }
1752
- async init() {
1753
- try {
1754
- if (aConcept.A_Context.environment === "server") {
1755
- this.initServer();
1756
- } else {
1757
- this.initBrowser();
1758
- }
1759
- this._initialized = true;
1760
- } catch (error) {
1761
- this.initBrowser();
1762
- this._initialized = true;
1763
- }
1764
- }
1765
- initServer() {
1766
- this._process = {
1767
- env: process.env,
1768
- argv: process.argv,
1769
- platform: process.platform,
1770
- version: process.version,
1771
- versions: process.versions,
1772
- cwd: process.cwd,
1773
- exit: process.exit,
1774
- nextTick: process.nextTick
1775
- };
1776
- }
1777
- initBrowser() {
1778
- this._process = {
1779
- env: {
1780
- NODE_ENV: "browser",
1781
- ...globalThis.process?.env || {}
1782
- },
1783
- argv: ["browser"],
1784
- platform: "browser",
1785
- version: "browser",
1786
- versions: { node: "browser" },
1787
- cwd: () => "/",
1788
- exit: (code) => {
1789
- this.logger.warning("process.exit not available in browser");
1790
- throw new Error(`Process exit with code ${code}`);
1791
- },
1792
- nextTick: (callback, ...args) => {
1793
- setTimeout(() => callback(...args), 0);
1794
- }
1795
- };
1796
- }
1797
- };
1798
-
1799
- // src/lib/A-Polyfill/A-Polyfill.component.ts
1800
- exports.A_Polyfill = class A_Polyfill extends aConcept.A_Component {
1801
- constructor(logger) {
1802
- super();
1803
- this.logger = logger;
1804
- this._initializing = null;
1805
- }
1806
- /**
1807
- * Indicates whether the channel is connected
1808
- */
1809
- get ready() {
1810
- if (!this._initialized) {
1811
- this._initialized = this._loadInternal();
1812
- }
1813
- return this._initialized;
1814
- }
1815
- async load() {
1816
- await this.ready;
1817
- }
1818
- async attachToWindow() {
1819
- if (aConcept.A_Context.environment !== "browser") return;
1820
- globalThis.A_Polyfill = this;
1821
- globalThis.process = { env: { NODE_ENV: "production" }, cwd: () => "/" };
1822
- globalThis.__dirname = "/";
1823
- }
1824
- async _loadInternal() {
1825
- this._fsPolyfill = new A_FSPolyfillClass(this.logger);
1826
- this._cryptoPolyfill = new A_CryptoPolyfillClass(this.logger);
1827
- this._httpPolyfill = new A_HttpPolyfillClass(this.logger);
1828
- this._httpsPolyfill = new A_HttpsPolyfillClass(this.logger);
1829
- this._pathPolyfill = new A_PathPolyfillClass(this.logger);
1830
- this._urlPolyfill = new A_UrlPolyfillClass(this.logger);
1831
- this._bufferPolyfill = new A_BufferPolyfillClass(this.logger);
1832
- this._processPolyfill = new A_ProcessPolyfillClass(this.logger);
1833
- await this._fsPolyfill.get();
1834
- await this._cryptoPolyfill.get(await this._fsPolyfill.get());
1835
- await this._httpPolyfill.get();
1836
- await this._httpsPolyfill.get();
1837
- await this._pathPolyfill.get();
1838
- await this._urlPolyfill.get();
1839
- await this._bufferPolyfill.get();
1840
- await this._processPolyfill.get();
1841
- }
1842
- /**
1843
- * Allows to use the 'fs' polyfill methods regardless of the environment
1844
- * This method loads the 'fs' polyfill and returns its instance
1845
- *
1846
- * @returns
1847
- */
1848
- async fs() {
1849
- await this.ready;
1850
- return await this._fsPolyfill.get();
1851
- }
1852
- /**
1853
- * Allows to use the 'crypto' polyfill methods regardless of the environment
1854
- * This method loads the 'crypto' polyfill and returns its instance
1855
- *
1856
- * @returns
1857
- */
1858
- async crypto() {
1859
- await this.ready;
1860
- return await this._cryptoPolyfill.get();
1861
- }
1862
- /**
1863
- * Allows to use the 'http' polyfill methods regardless of the environment
1864
- * This method loads the 'http' polyfill and returns its instance
1865
- *
1866
- * @returns
1867
- */
1868
- async http() {
1869
- await this.ready;
1870
- return await this._httpPolyfill.get();
1871
- }
1872
- /**
1873
- * Allows to use the 'https' polyfill methods regardless of the environment
1874
- * This method loads the 'https' polyfill and returns its instance
1875
- *
1876
- * @returns
1877
- */
1878
- async https() {
1879
- await this.ready;
1880
- return await this._httpsPolyfill.get();
1881
- }
1882
- /**
1883
- * Allows to use the 'path' polyfill methods regardless of the environment
1884
- * This method loads the 'path' polyfill and returns its instance
1885
- *
1886
- * @returns
1887
- */
1888
- async path() {
1889
- await this.ready;
1890
- return await this._pathPolyfill.get();
1891
- }
1892
- /**
1893
- * Allows to use the 'url' polyfill methods regardless of the environment
1894
- * This method loads the 'url' polyfill and returns its instance
1895
- *
1896
- * @returns
1897
- */
1898
- async url() {
1899
- await this.ready;
1900
- return await this._urlPolyfill.get();
1901
- }
1902
- /**
1903
- * Allows to use the 'buffer' polyfill methods regardless of the environment
1904
- * This method loads the 'buffer' polyfill and returns its instance
1905
- *
1906
- * @returns
1907
- */
1908
- async buffer() {
1909
- await this.ready;
1910
- return await this._bufferPolyfill.get();
1911
- }
1912
- /**
1913
- * Allows to use the 'process' polyfill methods regardless of the environment
1914
- * This method loads the 'process' polyfill and returns its instance
1915
- *
1916
- * @returns
1917
- */
1918
- async process() {
1919
- await this.ready;
1920
- return await this._processPolyfill.get();
1921
- }
1922
- };
1923
- __decorateClass([
1924
- aConcept.A_Concept.Load()
1925
- ], exports.A_Polyfill.prototype, "load", 1);
1926
- __decorateClass([
1927
- aConcept.A_Concept.Load()
1928
- ], exports.A_Polyfill.prototype, "attachToWindow", 1);
1929
- exports.A_Polyfill = __decorateClass([
1930
- __decorateParam(0, aConcept.A_Inject(exports.A_Logger))
1931
- ], exports.A_Polyfill);
1932
- var A_ConfigError = class extends aConcept.A_Error {
1933
- };
1934
- A_ConfigError.InitializationError = "A-Config Initialization Error";
1935
- exports.ConfigReader = class ConfigReader extends aConcept.A_Component {
1936
- constructor(polyfill) {
1937
- super();
1938
- this.polyfill = polyfill;
1939
- }
1940
- async attachContext(container, feature, config) {
1941
- if (!config) {
1942
- config = new A_Config({
1943
- variables: [
1944
- ...aConcept.A_CONSTANTS__DEFAULT_ENV_VARIABLES_ARRAY,
1945
- ...A_CONSTANTS__CONFIG_ENV_VARIABLES_ARRAY
1946
- ],
1947
- defaults: {}
1948
- });
1949
- container.scope.register(config);
1950
- }
1951
- const rootDir = await this.getProjectRoot();
1952
- config.set("A_CONCEPT_ROOT_FOLDER", rootDir);
1953
- }
1954
- async initialize(config) {
1955
- const data = await this.read([
1956
- ...config.CONFIG_PROPERTIES,
1957
- ...aConcept.A_CONSTANTS__DEFAULT_ENV_VARIABLES_ARRAY,
1958
- ...A_CONSTANTS__CONFIG_ENV_VARIABLES_ARRAY
1959
- ]);
1960
- config.set(data);
1961
- }
1962
- /**
1963
- * Get the configuration property by Name
1964
- * @param property
1965
- */
1966
- resolve(property) {
1967
- return property;
1968
- }
1969
- /**
1970
- * This method reads the configuration and sets the values to the context
1971
- *
1972
- * @returns
1973
- */
1974
- async read(variables = []) {
1975
- return {};
1976
- }
1977
- /**
1978
- * Finds the root directory of the project by locating the folder containing package.json
1979
- *
1980
- * @param {string} startPath - The initial directory to start searching from (default is __dirname)
1981
- * @returns {string|null} - The path to the root directory or null if package.json is not found
1982
- */
1983
- async getProjectRoot(startPath = __dirname) {
1984
- return process.cwd();
1985
- }
1986
- };
1987
- __decorateClass([
1988
- aConcept.A_Concept.Load(),
1989
- __decorateParam(0, aConcept.A_Inject(aConcept.A_Container)),
1990
- __decorateParam(1, aConcept.A_Inject(aConcept.A_Feature)),
1991
- __decorateParam(2, aConcept.A_Inject(A_Config))
1992
- ], exports.ConfigReader.prototype, "attachContext", 1);
1993
- __decorateClass([
1994
- aConcept.A_Concept.Load(),
1995
- __decorateParam(0, aConcept.A_Inject(A_Config))
1996
- ], exports.ConfigReader.prototype, "initialize", 1);
1997
- exports.ConfigReader = __decorateClass([
1998
- __decorateParam(0, aConcept.A_Inject(exports.A_Polyfill))
1999
- ], exports.ConfigReader);
2000
-
2001
- // src/lib/A-Config/components/FileConfigReader.component.ts
2002
- var FileConfigReader = class extends exports.ConfigReader {
2003
- constructor() {
2004
- super(...arguments);
2005
- this.FileData = /* @__PURE__ */ new Map();
2006
- }
2007
- /**
2008
- * Get the configuration property Name
2009
- * @param property
2010
- */
2011
- getConfigurationProperty_File_Alias(property) {
2012
- return aConcept.A_FormatterHelper.toCamelCase(property);
2013
- }
2014
- resolve(property) {
2015
- return this.FileData.get(this.getConfigurationProperty_File_Alias(property));
2016
- }
2017
- async read(variables) {
2018
- const fs = await this.polyfill.fs();
2019
- try {
2020
- const data = fs.readFileSync(`${aConcept.A_Context.concept}.conf.json`, "utf8");
2021
- const config = JSON.parse(data);
2022
- this.FileData = new Map(Object.entries(config));
2023
- return config;
2024
- } catch (error) {
2025
- return {};
2026
- }
2027
- }
2028
- };
2029
- var ENVConfigReader = class extends exports.ConfigReader {
2030
- async readEnvFile(config, polyfill, feature) {
2031
- const fs = await polyfill.fs();
2032
- if (fs.existsSync(".env"))
2033
- fs.readFileSync(`${config.get("A_CONCEPT_ROOT_FOLDER")}/.env`, "utf-8").split("\n").forEach((line) => {
2034
- const [key, value] = line.split("=");
2035
- if (key && value) {
2036
- process.env[key.trim()] = value.trim();
2037
- }
2038
- });
2039
- }
2040
- /**
2041
- * Get the configuration property Name
2042
- * @param property
2043
- */
2044
- getConfigurationProperty_ENV_Alias(property) {
2045
- return aConcept.A_FormatterHelper.toUpperSnakeCase(property);
2046
- }
2047
- resolve(property) {
2048
- return process.env[this.getConfigurationProperty_ENV_Alias(property)];
2049
- }
2050
- async read(variables = []) {
2051
- const allVariables = [
2052
- ...variables,
2053
- ...Object.keys(process.env)
2054
- ];
2055
- const config = {};
2056
- allVariables.forEach((variable) => {
2057
- config[variable] = this.resolve(variable);
2058
- });
2059
- return config;
2060
- }
2061
- };
2062
- __decorateClass([
2063
- aConcept.A_Concept.Load({
2064
- before: ["ENVConfigReader.initialize"]
2065
- }),
2066
- __decorateParam(0, aConcept.A_Inject(A_Config)),
2067
- __decorateParam(1, aConcept.A_Inject(exports.A_Polyfill)),
2068
- __decorateParam(2, aConcept.A_Inject(aConcept.A_Feature))
2069
- ], ENVConfigReader.prototype, "readEnvFile", 1);
2070
-
2071
- // src/lib/A-Config/A-Config.container.ts
2072
- var A_ConfigLoader = class extends aConcept.A_Container {
2073
- async prepare(polyfill) {
2074
- if (!this.scope.has(A_Config)) {
2075
- const newConfig = new A_Config({
2076
- variables: [
2077
- ...aConcept.A_CONSTANTS__DEFAULT_ENV_VARIABLES_ARRAY,
2078
- ...A_CONSTANTS__CONFIG_ENV_VARIABLES_ARRAY
2079
- ],
2080
- defaults: {}
2081
- });
2082
- this.scope.register(newConfig);
2083
- }
2084
- const fs = await polyfill.fs();
2085
- try {
2086
- switch (true) {
2087
- case (aConcept.A_Context.environment === "server" && !!fs.existsSync(`${aConcept.A_Context.concept}.conf.json`)):
2088
- this.reader = this.scope.resolve(FileConfigReader);
2089
- break;
2090
- case (aConcept.A_Context.environment === "server" && !fs.existsSync(`${aConcept.A_Context.concept}.conf.json`)):
2091
- this.reader = this.scope.resolve(ENVConfigReader);
2092
- break;
2093
- case aConcept.A_Context.environment === "browser":
2094
- this.reader = this.scope.resolve(ENVConfigReader);
2095
- break;
2096
- default:
2097
- throw new A_ConfigError(
2098
- A_ConfigError.InitializationError,
2099
- `Environment ${aConcept.A_Context.environment} is not supported`
2100
- );
2101
- }
2102
- } catch (error) {
2103
- if (error instanceof aConcept.A_ScopeError) {
2104
- throw new A_ConfigError({
2105
- title: A_ConfigError.InitializationError,
2106
- description: `Failed to initialize A_ConfigLoader. Reader not found for environment ${aConcept.A_Context.environment}`,
2107
- originalError: error
2108
- });
2109
- }
2110
- }
2111
- }
2112
- };
2113
- __decorateClass([
2114
- aConcept.A_Concept.Load({
2115
- before: /.*/
2116
- }),
2117
- __decorateParam(0, aConcept.A_Inject(exports.A_Polyfill))
2118
- ], A_ConfigLoader.prototype, "prepare", 1);
2119
-
2120
- // src/lib/A-Config/A-Config.types.ts
2121
- var A_TYPES__ConfigFeature = /* @__PURE__ */ ((A_TYPES__ConfigFeature2) => {
2122
- return A_TYPES__ConfigFeature2;
2123
- })(A_TYPES__ConfigFeature || {});
2124
- var A_ManifestError = class extends aConcept.A_Error {
2125
- };
2126
- A_ManifestError.ManifestInitializationError = "A-Manifest Initialization Error";
2127
-
2128
- // src/lib/A-Manifest/classes/A-ManifestChecker.class.ts
2129
- var A_ManifestChecker = class {
2130
- constructor(manifest, component, method, checkExclusion = false) {
2131
- this.manifest = manifest;
2132
- this.component = component;
2133
- this.method = method;
2134
- this.checkExclusion = checkExclusion;
2135
- }
2136
- for(target) {
2137
- const result = this.manifest.internal_checkAccess({
2138
- component: this.component,
2139
- method: this.method,
2140
- target
2141
- });
2142
- return this.checkExclusion ? !result : result;
2143
- }
2144
- };
2145
-
2146
- // src/lib/A-Manifest/A-Manifest.context.ts
2147
- var A_Manifest = class extends aConcept.A_Fragment {
2148
- /**
2149
- * A-Manifest is a configuration set that allows to include or exclude component application for the particular methods.
2150
- *
2151
- * For example, if A-Scope provides polymorphic A-Component that applies for All A-Entities in it but you have another component that should be used for only One particular Entity, you can use A-Manifest to specify this behavior.
2152
- *
2153
- *
2154
- * By default if Component is provided in the scope - it applies for all entities in it. However, if you want to exclude some entities or include only some entities for the particular component - you can use A-Manifest to define this behavior.
2155
- *
2156
- * @param config - Array of component configurations
2157
- */
2158
- constructor(config = []) {
2159
- super({
2160
- name: "A-Manifest"
2161
- });
2162
- this.rules = [];
2163
- this.prepare(config);
2164
- }
2165
- /**
2166
- * Should convert received configuration into internal Regexp applicable for internal storage
2167
- */
2168
- prepare(config) {
2169
- if (!aConcept.A_TypeGuards.isArray(config))
2170
- throw new A_ManifestError(
2171
- A_ManifestError.ManifestInitializationError,
2172
- `A-Manifest configuration should be an array of configurations`
2173
- );
2174
- for (const item of config) {
2175
- this.processConfigItem(item);
2176
- }
2177
- }
2178
- /**
2179
- * Process a single configuration item and convert it to internal rules
2180
- */
2181
- processConfigItem(item) {
2182
- if (!aConcept.A_TypeGuards.isComponentConstructor(item.component))
2183
- throw new A_ManifestError(
2184
- A_ManifestError.ManifestInitializationError,
2185
- `A-Manifest configuration item should be a A-Component constructor`
2186
- );
2187
- const componentRegex = this.constructorToRegex(item.component);
2188
- if (item.apply || item.exclude) {
2189
- const methodRegex = /.*/;
2190
- this.rules.push({
2191
- componentRegex,
2192
- methodRegex,
2193
- applyRegex: item.apply ? this.allowedComponentsToRegex(item.apply) : void 0,
2194
- excludeRegex: item.exclude ? this.allowedComponentsToRegex(item.exclude) : void 0
2195
- });
2196
- }
2197
- if (item.methods && item.methods.length > 0) {
2198
- for (const methodConfig of item.methods) {
2199
- const methodRegex = this.methodToRegex(methodConfig.method);
2200
- this.rules.push({
2201
- componentRegex,
2202
- methodRegex,
2203
- applyRegex: methodConfig.apply ? this.allowedComponentsToRegex(methodConfig.apply) : void 0,
2204
- excludeRegex: methodConfig.exclude ? this.allowedComponentsToRegex(methodConfig.exclude) : void 0
2205
- });
2206
- }
2207
- }
2208
- }
2209
- /**
2210
- * Convert a constructor to a regex pattern
2211
- */
2212
- constructorToRegex(ctor) {
2213
- return new RegExp(`^${this.escapeRegex(ctor.name)}$`);
2214
- }
2215
- /**
2216
- * Convert a method name or regex to a regex pattern
2217
- */
2218
- methodToRegex(method) {
2219
- if (method instanceof RegExp) {
2220
- return method;
2221
- }
2222
- return new RegExp(`^${this.escapeRegex(method)}$`);
2223
- }
2224
- /**
2225
- * Convert allowed components array or regex to a single regex
2226
- */
2227
- allowedComponentsToRegex(components) {
2228
- if (components instanceof RegExp) {
2229
- return components;
2230
- }
2231
- const patterns = components.map((ctor) => this.escapeRegex(ctor.name));
2232
- return new RegExp(`^(${patterns.join("|")})$`);
2233
- }
2234
- /**
2235
- * Escape special regex characters in a string
2236
- */
2237
- escapeRegex(str) {
2238
- return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
2239
- }
2240
- configItemToRegexp(item) {
2241
- return this.constructorToRegex(item);
2242
- }
2243
- ID(component, method) {
2244
- return `${component.name}.${method}`;
2245
- }
2246
- /**
2247
- * Check if a component and method combination is allowed for a target
2248
- */
2249
- isAllowed(ctor, method) {
2250
- const componentCtor = typeof ctor === "function" ? ctor : ctor.constructor;
2251
- return new A_ManifestChecker(this, componentCtor, method);
2252
- }
2253
- /**
2254
- * Internal method to check if access is allowed
2255
- */
2256
- internal_checkAccess(query) {
2257
- const componentName = query.component.name;
2258
- const methodName = query.method;
2259
- const targetName = query.target.name;
2260
- const matchingRules = this.rules.filter(
2261
- (rule) => rule.componentRegex.test(componentName) && rule.methodRegex.test(methodName)
2262
- ).sort((a, b) => {
2263
- const aIsGeneral = a.methodRegex.source === ".*";
2264
- const bIsGeneral = b.methodRegex.source === ".*";
2265
- if (aIsGeneral && !bIsGeneral) return 1;
2266
- if (!aIsGeneral && bIsGeneral) return -1;
2267
- return 0;
2268
- });
2269
- if (matchingRules.length === 0) {
2270
- return true;
2271
- }
2272
- for (const rule of matchingRules) {
2273
- if (rule.excludeRegex && rule.excludeRegex.test(targetName)) {
2274
- return false;
2275
- }
2276
- if (rule.applyRegex) {
2277
- return rule.applyRegex.test(targetName);
2278
- }
2279
- }
2280
- return true;
2281
- }
2282
- isExcluded(ctor, method) {
2283
- const componentCtor = typeof ctor === "function" ? ctor : ctor.constructor;
2284
- return new A_ManifestChecker(this, componentCtor, method, true);
2285
- }
2286
- };
2287
-
2288
- // src/lib/A-Schedule/A-Deferred.class.ts
2289
- var A_Deferred = class {
2290
- /**
2291
- * Creates a deferred promise
2292
- * @returns A promise that can be resolved or rejected later
2293
- */
2294
- constructor() {
2295
- this.promise = new Promise((resolve, reject) => {
2296
- this.resolveFn = resolve;
2297
- this.rejectFn = reject;
2298
- });
2299
- }
2300
- resolve(value) {
2301
- this.resolveFn(value);
2302
- }
2303
- reject(reason) {
2304
- this.rejectFn(reason);
2305
- }
2306
- };
2307
- var A_ScheduleObject = class {
2308
- /**
2309
- * Creates a scheduled object that will execute the action after specified milliseconds
2310
- *
2311
- *
2312
- * @param ms - milliseconds to wait before executing the action
2313
- * @param action - the action to execute
2314
- * @param config - configuration options for the schedule object
2315
- */
2316
- constructor(ms, action, config) {
2317
- this.config = {
2318
- /**
2319
- * If the timeout is cleared, should the promise resolve or reject?
2320
- * BY Default it rejects
2321
- *
2322
- * !!!NOTE: If the property is set to true, the promise will resolve with undefined
2323
- */
2324
- resolveOnClear: false
2325
- };
2326
- if (config)
2327
- this.config = { ...this.config, ...config };
2328
- this.deferred = new A_Deferred();
2329
- this.timeout = setTimeout(
2330
- () => action().then((...args) => this.deferred.resolve(...args)).catch((...args) => this.deferred.reject(...args)),
2331
- ms
2332
- );
2333
- }
2334
- get promise() {
2335
- return this.deferred.promise;
2336
- }
2337
- clear() {
2338
- if (this.timeout) {
2339
- clearTimeout(this.timeout);
2340
- if (this.config.resolveOnClear)
2341
- this.deferred.resolve(void 0);
2342
- else
2343
- this.deferred.reject(new aConcept.A_Error("Timeout Cleared"));
2344
- }
2345
- }
2346
- };
2347
-
2348
- // src/lib/A-Schedule/A-Schedule.component.ts
2349
- var A_Schedule = class extends aConcept.A_Component {
2350
- async schedule(date, callback, config) {
2351
- const timestamp = aConcept.A_TypeGuards.isString(date) ? new Date(date).getTime() : date;
2352
- return new A_ScheduleObject(
2353
- timestamp - Date.now(),
2354
- callback,
2355
- config
2356
- );
2357
- }
2358
- /**
2359
- * Allows to execute callback after particular delay in milliseconds
2360
- * So the callback will be executed after the specified delay
2361
- *
2362
- * @param ms
2363
- */
2364
- async delay(ms, callback, config) {
2365
- return new A_ScheduleObject(
2366
- ms,
2367
- callback,
2368
- config
2369
- );
2370
- }
2371
- };
2372
-
2373
- exports.A_CONSTANTS__A_Command_Status = A_CONSTANTS__A_Command_Status;
2374
- exports.A_CONSTANTS__CONFIG_ENV_VARIABLES = A_CONSTANTS__CONFIG_ENV_VARIABLES;
2375
- exports.A_CONSTANTS__CONFIG_ENV_VARIABLES_ARRAY = A_CONSTANTS__CONFIG_ENV_VARIABLES_ARRAY;
2376
- exports.A_Channel = A_Channel;
2377
- exports.A_ChannelError = A_ChannelError;
2378
- exports.A_ChannelFeatures = A_ChannelFeatures;
2379
- exports.A_ChannelRequest = A_ChannelRequest;
2380
- exports.A_ChannelRequestStatuses = A_ChannelRequestStatuses;
2381
- exports.A_Command = A_Command;
2382
- exports.A_CommandError = A_CommandError;
2383
- exports.A_CommandFeatures = A_CommandFeatures;
2384
- exports.A_Config = A_Config;
2385
- exports.A_ConfigError = A_ConfigError;
2386
- exports.A_ConfigLoader = A_ConfigLoader;
2387
- exports.A_Deferred = A_Deferred;
2388
- exports.A_Manifest = A_Manifest;
2389
- exports.A_ManifestChecker = A_ManifestChecker;
2390
- exports.A_ManifestError = A_ManifestError;
2391
- exports.A_Memory = A_Memory;
2392
- exports.A_Schedule = A_Schedule;
2393
- exports.A_ScheduleObject = A_ScheduleObject;
2394
- exports.A_TYPES__ConfigFeature = A_TYPES__ConfigFeature;
2395
- exports.ENVConfigReader = ENVConfigReader;
2396
- exports.FileConfigReader = FileConfigReader;
2397
- //# sourceMappingURL=index.js.map
2398
- //# sourceMappingURL=index.js.map