analogger 1.17.2 → 1.18.2

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.
@@ -0,0 +1,1472 @@
1
+ /**
2
+ * DO NOT EDIT THIS FILE DIRECTLY.
3
+ * This file is generated following the conversion of
4
+ * @see [./src/ana-logger.cjs]{@link ./src/ana-logger.cjs}
5
+ *
6
+ **/
7
+ import toAnsi from "../../node_modules/to-ansi/index.mjs";
8
+ import {COLOR_TABLE, SYSTEM, MAX_CHILDREN_DOM_ANALOGGER, CLASS_REMOVED_NOTIF, ADD_TYPE, CONSOLE_AREA_CLASSNAME,
9
+ PREDEFINED_FORMATS, ANALOGGER_NAME, LINE_CLASSNAME
10
+ } from "./constants.mjs";
11
+ import {stringify} from "../../node_modules/flatted/esm/index.js";
12
+ let _terminalSize = {};
13
+
14
+
15
+
16
+ _terminalSize = {}
17
+
18
+
19
+
20
+
21
+ const PREDEFINED_CONTEXT_NAMES = {
22
+ "DEFAULT": "DEFAULT",
23
+ // "LOG" : "LOG",
24
+ // "INFO" : "INFO",
25
+ // "WARN" : "WARN",
26
+ // "ATTENTION": "ATTENTION",
27
+ "ERROR": "ERROR"
28
+ };
29
+
30
+
31
+
32
+ const EOL = `
33
+ `;
34
+
35
+ const symbolNames = {
36
+ airplane : "✈",
37
+ anchor : "⚓",
38
+ arrow_backward : "◀",
39
+ arrow_double_up : "⏫",
40
+ arrow_double_down : "⏬",
41
+ arrow_forward : "▶",
42
+ arrow_lower_right : "↘",
43
+ arrow_lower_left : "↙",
44
+ arrow_right_hook : "↪",
45
+ arrow_up_down : "↕",
46
+ arrow_upper_left : "↖",
47
+ arrow_upper_right : "↗",
48
+ ballot_box_with_check : "☑",
49
+ biohazard : "☣",
50
+ black_circle : "⏺",
51
+ black_medium_small_square : "◾",
52
+ black_medium_square : "◼",
53
+ black_nib : "✒",
54
+ black_small_square : "▪",
55
+ black_square : "⏹",
56
+ chains : "⛓",
57
+ check : "✔",
58
+ chess_pawn : "♟",
59
+ cloud_and_rain : "⛈",
60
+ clubs : "♣",
61
+ coffee : "☕",
62
+ copyright : "©",
63
+ cross : "❌",
64
+ diamonds : "♦",
65
+ divisions_ign : "➗",
66
+ double_triangle_right : "⏭",
67
+ double_triangle_left : "⏮",
68
+ email : "✉",
69
+ eject : "⏏",
70
+ exclamation_mark : "❗",
71
+ fast_forward : "⏩",
72
+ female_sign : "♀",
73
+ fist : "✊",
74
+ fuel_pump : "⛽",
75
+ gear : "⚙",
76
+ hammer_and_pick : "⚒",
77
+ hand : "✋",
78
+ hearts : "♥",
79
+ infinity : "♾",
80
+ information : "ℹ",
81
+ left_right_arrow : "↔",
82
+ leftwards_arrow_with_hook : "↩",
83
+ male_sign : "♂",
84
+ minus_sign : "➖",
85
+ no_entry : "⛔",
86
+ partly_sunny : "⛅",
87
+ pencil : "✏",
88
+ phone : "☎",
89
+ plus_sign : "➕",
90
+ question : "❔",
91
+ radioactive : "☢",
92
+ raised_hand : "✋",
93
+ recycle : "♻",
94
+ registered : "®",
95
+ relaxed : "☺",
96
+ rewind : "⏪",
97
+ scissors : "✂",
98
+ snowman : "☃",
99
+ spades : "♠",
100
+ sparkles : "✨",
101
+ star : "⭐",
102
+ sunny : "☀",
103
+ tent : "⛺",
104
+ trademark : "™",
105
+ triangle_with_vertical_bar: "⏯",
106
+ umbrella : "☔",
107
+ vertical_bars : "⏸",
108
+ watch : "⌚",
109
+ white_frowning_face : "☹",
110
+ white_medium_square : "◻",
111
+ white_medium_small_square : "◽",
112
+ white_small_square : "▫",
113
+ wheelchair : "♿",
114
+ white_circle : "⚪",
115
+ writing_hand : "✍",
116
+ };
117
+
118
+ class ____AnaLogger
119
+ {
120
+ system = "";
121
+
122
+ instanceId = "";
123
+ instanceName = "";
124
+
125
+ logIndex = 0;
126
+ logCounter = 0;
127
+ contexts = [];
128
+ targets = {};
129
+
130
+ activeTarget = null;
131
+
132
+ indexColor = 0;
133
+
134
+ format = "";
135
+
136
+ keepLog = false;
137
+ logHistory = [];
138
+
139
+ $containers = null;
140
+
141
+ options = {
142
+ hideHookMessage: false
143
+ };
144
+
145
+ #realConsoleLog = console.log;
146
+ #realConsoleInfo = console.info;
147
+ #realConsoleWarn = console.warn;
148
+ #realConsoleError = console.error;
149
+
150
+ isBrowser0 = null;
151
+
152
+ static ALIGN = {
153
+ LEFT : "LEFT",
154
+ RIGHT: "RIGHT"
155
+ };
156
+
157
+ static ENVIRONMENT_TYPE = {
158
+ BROWSER: "BROWSER",
159
+ NODE : "NODE",
160
+ OTHER : "OTHER"
161
+ };
162
+
163
+ static instanceCount = 0;
164
+
165
+ originalFormatFunction;
166
+
167
+ constructor({name = "default"} = {})
168
+ {
169
+ this.system = (typeof process === "object") ? SYSTEM.NODE : SYSTEM.BROWSER;
170
+ this.format = this.onBuildLog.bind(this);
171
+ this.originalFormatFunction = this.format;
172
+
173
+ this.instanceName = name;
174
+ ++____AnaLogger.instanceCount;
175
+ this.instanceId = ____AnaLogger.instanceCount + "-" + Date.now();
176
+
177
+ this.errorTargetHandler = this.onError.bind(this);
178
+ this.errorUserTargetHandler = this.onErrorForUserTarget.bind(this);
179
+
180
+ this.setOptions(this.options);
181
+
182
+ this.rawLog = this.#realConsoleLog;
183
+ this.rawInfo = this.#realConsoleInfo;
184
+ this.rawWarn = this.#realConsoleWarn;
185
+ this.rawError = this.#realConsoleError;
186
+
187
+ console.rawLog = this.#realConsoleLog;
188
+ console.raw = this.#realConsoleLog;
189
+
190
+ console.rawInfo = this.#realConsoleInfo;
191
+ console.rawWarn = this.#realConsoleWarn;
192
+ console.rawError = this.#realConsoleError;
193
+
194
+ console.keepLogHistory = this.keepLogHistory;
195
+ console.getLogHistory = this.getLogHistory;
196
+
197
+ console.table = this.table;
198
+ console.buildTable = this.buildTable;
199
+ console.isNode = this.isNode;
200
+ console.isBrowser = this.isBrowser;
201
+ console.truncateMessage = this.truncateMessage;
202
+ console.rawLog = this.rawLog;
203
+ console.rawInfo = this.rawInfo;
204
+ console.rawWarn = this.rawWarn;
205
+ console.rawError = this.rawError;
206
+ console.isBrowser0 = this.system === SYSTEM.BROWSER;
207
+
208
+ this.ALIGN = ____AnaLogger.ALIGN;
209
+ this.ENVIRONMENT_TYPE = ____AnaLogger.ENVIRONMENT_TYPE;
210
+
211
+ this.resetLogHistory();
212
+ }
213
+
214
+ getName()
215
+ {
216
+ return this.instanceName;
217
+ }
218
+
219
+ getId()
220
+ {
221
+ return this.instanceId;
222
+ }
223
+
224
+ keepLogHistory()
225
+ {
226
+ this.keepLog = true;
227
+ }
228
+
229
+ releaseLogHistory()
230
+ {
231
+ this.keepLog = false;
232
+ }
233
+
234
+ resetLogHistory()
235
+ {
236
+ this.logHistory = [];
237
+ }
238
+
239
+ getLogHistory(join = true, symbol = EOL)
240
+ {
241
+ const historyLog = this.logHistory;
242
+ if (!historyLog)
243
+ {
244
+ return "";
245
+ }
246
+ const logs = this.logHistory.slice(0);
247
+ const history = JSON.parse(JSON.stringify(logs));
248
+ if (!join)
249
+ {
250
+ return history;
251
+ }
252
+ return history.join(symbol);
253
+ }
254
+
255
+ /**
256
+ * Tell whether we are in a Node environment
257
+ * @returns {boolean}
258
+ */
259
+ isNode()
260
+ {
261
+ return this.system === SYSTEM.NODE;
262
+ }
263
+
264
+ /**
265
+ * Tell whether the logger runs from a browser
266
+ * @returns {boolean}
267
+ */
268
+ isBrowser()
269
+ {
270
+ return !this.isNode();
271
+ }
272
+
273
+ resetLogger()
274
+ {
275
+ this.options = {};
276
+ this.options.timeLenMax = 10;
277
+ this.options.contextLenMax = 10;
278
+ this.options.idLenMax = 5;
279
+ this.options.lidLenMax = 6;
280
+ this.options.messageLenMax = undefined;
281
+ this.options.symbolLenMax = 60;
282
+ this.options.hideHookMessage = undefined;
283
+ this.options.hidePassingTests = undefined;
284
+ this.options.hideLog = undefined;
285
+ this.options.hideError = undefined;
286
+ this.options.oneConsolePerContext = true;
287
+ this.options.logToDom = undefined;
288
+ this.options.logToFile = undefined;
289
+ this.options.logToDomlogToFile = undefined;
290
+ }
291
+
292
+ resetOptions()
293
+ {
294
+ this.resetLogger();
295
+ }
296
+
297
+ setOptions({
298
+ contextLenMax = 10,
299
+ idLenMax = 5,
300
+ lidLenMax = 6,
301
+ symbolLenMax = 2,
302
+ messageLenMax = undefined,
303
+ hideLog = undefined,
304
+ hideError = undefined,
305
+ hideHookMessage = undefined,
306
+ hidePassingTests = undefined,
307
+ logToDom = undefined,
308
+ logToFile = undefined,
309
+ oneConsolePerContext = undefined,
310
+ silent = undefined
311
+ } = null)
312
+ {
313
+ this.options.contextLenMax = contextLenMax;
314
+ this.options.idLenMax = idLenMax;
315
+ this.options.lidLenMax = lidLenMax;
316
+ this.options.messageLenMax = messageLenMax;
317
+ this.options.symbolLenMax = symbolLenMax;
318
+
319
+ if (hidePassingTests !== undefined)
320
+ {
321
+ this.options.hidePassingTests = !!hidePassingTests;
322
+ }
323
+
324
+ if (hideHookMessage !== undefined)
325
+ {
326
+ this.options.hideHookMessage = !!hideHookMessage;
327
+ }
328
+
329
+ // TODO: Make one of silent or hideToLog options obsolete
330
+ let solveSilent = undefined;
331
+ if (silent !== undefined)
332
+ {
333
+ solveSilent = !!silent;
334
+ }
335
+ else if (hideLog !== undefined)
336
+ {
337
+ solveSilent = !!hideLog;
338
+ }
339
+
340
+ if (solveSilent)
341
+ {
342
+ this.options.hideLog = !!solveSilent;
343
+ }
344
+
345
+ if (hideError !== undefined)
346
+ {
347
+ this.options.hideError = !!hideError;
348
+ }
349
+
350
+ if (oneConsolePerContext !== undefined)
351
+ {
352
+ this.options.oneConsolePerContext = !!oneConsolePerContext;
353
+ }
354
+
355
+ if (logToDom !== undefined)
356
+ {
357
+ this.options.logToDom = logToDom || "#analogger";
358
+ }
359
+
360
+ if (logToFile === false)
361
+ {
362
+ this.options.logToFile = false;
363
+ }
364
+ else if (logToFile !== undefined)
365
+ {
366
+ if (!this.isBrowser())
367
+ {
368
+ this.options.logToFile = logToFile || "./analogger.log";
369
+
370
+
371
+ }
372
+
373
+ this.#realConsoleLog("LogToFile is not supported in this environment. ")
374
+
375
+ }
376
+
377
+ }
378
+
379
+ getOptions()
380
+ {
381
+ return this.options;
382
+ }
383
+
384
+ truncateMessage(input = "", {fit = 0, align = ____AnaLogger.ALIGN.LEFT, ellipsis = "..."} = {})
385
+ {
386
+ input = "" + input;
387
+ if (fit && input.length > fit)
388
+ {
389
+ input = input.substring(0, fit - ellipsis.length) + ellipsis;
390
+ }
391
+
392
+ input = align === ____AnaLogger.ALIGN.LEFT ? input.padEnd(fit, " ") : input.padStart(fit, " ");
393
+ return input;
394
+ }
395
+
396
+ /**
397
+ * Display data
398
+ * @param {any[]} table
399
+ * @param objList
400
+ * @param ellipsis
401
+ * @param ColumnMinChars
402
+ * @param columnMaxChars
403
+ * @param verticalSeparator
404
+ * @param horizontalSeparator
405
+ * @param availableLength
406
+ * @param onCompleteHeaders
407
+ * @param onCompleteSeparators
408
+ * @param onCompleteLines
409
+ */
410
+ buildTable(objList, {
411
+ ellipsis = "...",
412
+ ColumnMinChars = 6,
413
+ columnMaxChars = 0,
414
+ verticalSeparator = " │ ",
415
+ horizontalSeparator = "─",
416
+ availableLength = 0,
417
+ onCompleteHeaders = null,
418
+ onCompleteSeparators = null,
419
+ onCompleteLines = null
420
+ } = {})
421
+ {
422
+ let text = "";
423
+
424
+ const isArray = Array.isArray(objList);
425
+ if (!isArray)
426
+ {
427
+ objList = Object.values(Object.values(objList));
428
+ }
429
+
430
+ if (!objList || !objList.length)
431
+ {
432
+ return "";
433
+ }
434
+
435
+ let table = objList.map(a => Object.assign({}, a));
436
+
437
+ const firstLine = table[0];
438
+ const titles = Object.keys(firstLine);
439
+ table.unshift(titles);
440
+
441
+ horizontalSeparator = horizontalSeparator.repeat(100);
442
+
443
+ const fits = {};
444
+ for (let i = 1; i < table.length; ++i)
445
+ {
446
+ const line = table[i];
447
+ for (let ii = 0; ii < titles.length; ++ii)
448
+ {
449
+ const colName = titles[ii];
450
+ const colContent = line[colName];
451
+
452
+ fits[colName] = fits[colName] || 0;
453
+ let colLength;
454
+ try
455
+ {
456
+ colLength = JSON.stringify(colContent).length;
457
+ }
458
+ catch (e)
459
+ {
460
+ }
461
+
462
+ colLength = colLength || ColumnMinChars;
463
+ fits[colName] = Math.max(fits[colName], colLength, colName.length);
464
+ }
465
+ }
466
+
467
+ if (!this.isBrowser0)
468
+ {
469
+ _terminalSize = _terminalSize || {};
470
+
471
+ if (!availableLength)
472
+ {
473
+ availableLength = _terminalSize.width || process.stdout.columns || 120 - verticalSeparator.length - 1 - 5;
474
+ }
475
+ }
476
+
477
+ availableLength = availableLength - 4;
478
+
479
+ let totalLength = Object.values(fits).reduce((a, b) => a + b, 0);
480
+
481
+ /* istanbul ignore next */
482
+ if (availableLength < totalLength)
483
+ {
484
+ const ratio = (availableLength) / totalLength;
485
+ for (let key in fits)
486
+ {
487
+ fits[key] = Math.floor(fits[key] * ratio) - 1;
488
+ if (ColumnMinChars && fits[key] < ColumnMinChars)
489
+ {
490
+ fits[key] = ColumnMinChars;
491
+ }
492
+
493
+ if (columnMaxChars && fits[key] > columnMaxChars)
494
+ {
495
+ fits[key] = columnMaxChars;
496
+ }
497
+
498
+ fits[key] = fits[key];
499
+ }
500
+
501
+ }
502
+
503
+ let strLine;
504
+
505
+ // Headers
506
+ strLine = "";
507
+ for (let i = 0; i < titles.length; ++i)
508
+ {
509
+ const colName = titles[i];
510
+ const fit = fits[colName];
511
+ strLine += this.truncateMessage(colName, {fit, ellipsis});
512
+ strLine += verticalSeparator;
513
+ }
514
+
515
+ if (onCompleteHeaders)
516
+ {
517
+ strLine = onCompleteHeaders(strLine, titles);
518
+ }
519
+ text += this.truncateMessage(strLine, {fit: availableLength});
520
+ text += EOL;
521
+
522
+
523
+ // Separators
524
+ strLine = "";
525
+ const colContent = horizontalSeparator;
526
+ for (let i = 0; i < titles.length; ++i)
527
+ {
528
+ const colName = titles[i];
529
+ const fit = fits[colName];
530
+ strLine += this.truncateMessage(colContent, {fit, ellipsis: ""});
531
+ strLine += verticalSeparator;
532
+ }
533
+
534
+ if (onCompleteSeparators)
535
+ {
536
+ strLine = onCompleteSeparators(strLine, titles);
537
+ }
538
+
539
+ text += this.truncateMessage(strLine, {fit: availableLength});
540
+ text += EOL;
541
+
542
+ // Content
543
+ for (let i = 1; i < table.length; ++i)
544
+ {
545
+ strLine = "";
546
+ const line = table[i];
547
+ for (let ii = 0; ii < titles.length; ++ii)
548
+ {
549
+ const colName = titles[ii];
550
+ const colContent = line[colName];
551
+ const fit = fits[colName];
552
+
553
+ strLine += this.truncateMessage(colContent, {fit, ellipsis});
554
+ strLine += verticalSeparator;
555
+ }
556
+
557
+ if (onCompleteLines)
558
+ {
559
+ strLine = onCompleteLines(strLine, line);
560
+ }
561
+
562
+ text += this.truncateMessage(strLine, {fit: availableLength});
563
+ text += EOL;
564
+ }
565
+
566
+ this.rawLog(text);
567
+
568
+ return text;
569
+ }
570
+
571
+ /**
572
+ * Format inputs
573
+ * @see Override {@link setLogFormat}
574
+ * @param contextName
575
+ * @param id
576
+ * @param message
577
+ * @param lid
578
+ * @param symbol
579
+ * @returns {string}
580
+ */
581
+ onBuildLog({contextName, message = "", lid = "", symbol = ""} = {})
582
+ {
583
+ // Time
584
+ const date = new Date();
585
+ let time = ("0" + date.getHours()).slice(-2) + ":" + ("0" + date.getMinutes()).slice(-2) + ":" + ("0" + date.getSeconds()).slice(-2);
586
+
587
+ // Display content in columns
588
+ time = this.truncateMessage(time, {fit: this.options.timeLenMax});
589
+ contextName = this.truncateMessage(contextName, {
590
+ fit : this.options.contextLenMax,
591
+ align: ____AnaLogger.ALIGN.RIGHT
592
+ });
593
+ lid = this.truncateMessage(lid, {fit: this.options.lidLenMax});
594
+
595
+ if (this.options.messageLenMax !== undefined)
596
+ {
597
+ message = this.truncateMessage(message, {fit: this.options.messageLenMax});
598
+ }
599
+
600
+ symbol = this.truncateMessage(symbol, {fit: this.options.symbolLenMax});
601
+
602
+ return `[${time}] ${contextName}: (${lid}) ${symbol} ${message}`;
603
+ }
604
+
605
+ onErrorForUserTarget(context, ...args)
606
+ {
607
+ this.errorUserTargetHandler(context, ...args);
608
+ }
609
+
610
+ onError(context, ...args)
611
+ {
612
+ if (context.target === this.targets.USER)
613
+ {
614
+ this.onErrorForUserTarget(context, ...args);
615
+ }
616
+ }
617
+
618
+ /**
619
+ * Forward input to real console log
620
+ * @param args
621
+ */
622
+ onDisplayLog(...args)
623
+ {
624
+ this.log(...args);
625
+ }
626
+
627
+ assistStask(error)
628
+ {
629
+ try
630
+ {
631
+ const lines = error.stack.split("\n");
632
+ const stack = [];
633
+
634
+ for (let i = 0; i < lines.length; ++i)
635
+ {
636
+ const line = lines[i];
637
+ stack.push(line);
638
+ }
639
+
640
+ return stack;
641
+ }
642
+ catch (e)
643
+ {
644
+ console.rawError(e.message);
645
+ }
646
+
647
+ return error.message;
648
+ }
649
+
650
+ /**
651
+ * Forward input to real console log
652
+ * @param args
653
+ */
654
+ onDisplayError(...args)
655
+ {
656
+ try
657
+ {
658
+ let mainIndex = -1
659
+ let extracted = null;
660
+ for (let i = 0; i < args.length; ++i)
661
+ {
662
+ const arg = args[i];
663
+ if (arg instanceof Error)
664
+ {
665
+ if (arg.stack)
666
+ {
667
+ mainIndex = i;
668
+ extracted = this.assistStask(arg) || []
669
+ break;
670
+ }
671
+ }
672
+ }
673
+
674
+ if (!extracted)
675
+ {
676
+ this.error(...args);
677
+ return
678
+ }
679
+
680
+ for (let i = 0; i < extracted.length; ++i)
681
+ {
682
+ args[mainIndex] = extracted[i];
683
+ this.error(...args);
684
+ }
685
+
686
+ }
687
+ catch (e)
688
+ {
689
+ console.rawError(e);
690
+ }
691
+
692
+ }
693
+
694
+ /**
695
+ * Set log template
696
+ * @param format
697
+ */
698
+ setLogFormat(format)
699
+ {
700
+ if (typeof format !== "function")
701
+ {
702
+ console.error("Invalid parameter for setFormat. It is expecting a function or method.");
703
+ return false;
704
+ }
705
+ this.format = format.bind(this);
706
+ }
707
+
708
+ resetLogFormatter()
709
+ {
710
+ this.format = this.originalFormatFunction;
711
+ }
712
+
713
+ setErrorHandler(handler)
714
+ {
715
+ this.errorTargetHandler = handler.bind(this);
716
+ }
717
+
718
+ setErrorHandlerForUserTarget(handler)
719
+ {
720
+ this.errorUserTargetHandler = handler.bind(this);
721
+ }
722
+
723
+ // ------------------------------------------------
724
+ // Color
725
+ // ------------------------------------------------
726
+
727
+ // ------------------------------------------------
728
+ // Log Contexts
729
+ // ------------------------------------------------
730
+ isContextValid(context)
731
+ {
732
+ if (
733
+ !(typeof context === "object" &&
734
+ !Array.isArray(context) &&
735
+ context !== null)
736
+ )
737
+ {
738
+ return false;
739
+ }
740
+ return (context.hasOwnProperty("contextName") && context.hasOwnProperty("target"));
741
+ }
742
+
743
+ setContext(contextName, context)
744
+ {
745
+ this.contexts[contextName] = context;
746
+ }
747
+
748
+ setDefaultContext(context)
749
+ {
750
+ this.setContext(PREDEFINED_CONTEXT_NAMES.DEFAULT, context);
751
+ }
752
+
753
+ generateDefaultContext()
754
+ {
755
+ let defaultContext = this.contexts[PREDEFINED_CONTEXT_NAMES.DEFAULT] || {};
756
+ defaultContext = Object.assign({},
757
+ {
758
+ name : PREDEFINED_CONTEXT_NAMES.DEFAULT,
759
+ contextName: PREDEFINED_CONTEXT_NAMES.DEFAULT,
760
+ target : "ALL",
761
+ symbol : "⚡",
762
+ color : COLOR_TABLE[1]
763
+ }, defaultContext);
764
+
765
+ defaultContext.id = this.logIndex++;
766
+ return defaultContext;
767
+ }
768
+
769
+ generateNewContext()
770
+ {
771
+ const newContext = this.generateDefaultContext();
772
+ newContext.color = COLOR_TABLE[(this.indexColor++) % (COLOR_TABLE.length - 3) + 2];
773
+ newContext.symbol = "";
774
+ return newContext;
775
+ }
776
+
777
+ generateErrorContext()
778
+ {
779
+ const errorContext = this.generateDefaultContext();
780
+ errorContext.name = PREDEFINED_CONTEXT_NAMES.ERROR;
781
+ errorContext.contextName = PREDEFINED_CONTEXT_NAMES.ERROR;
782
+ errorContext.color = COLOR_TABLE[0];
783
+ errorContext.symbol = "❌";
784
+ errorContext.error = true;
785
+ return errorContext;
786
+ }
787
+
788
+ // TODO: Need testing before activating
789
+ // generateCustomContext(contextName, {symbol = "", error = false, color = "gray"} = {})
790
+ // {
791
+ // const customContext = this.generateDefaultContext();
792
+ // customContext.name = contextName;
793
+ // customContext.contextName = contextName;
794
+ // customContext.color = color;
795
+ // customContext.symbol = symbol;
796
+ // customContext.error = error;
797
+ // return customContext;
798
+ // }
799
+
800
+ #allegeProperties(entry)
801
+ {
802
+ let converted = entry;
803
+
804
+ const defaultContext = this.generateNewContext();
805
+
806
+ converted = Object.assign({}, defaultContext, converted);
807
+
808
+ if (converted.color.toLowerCase().indexOf("rgb") > -1)
809
+ {
810
+ converted.color = toAnsi.rgbStringToHex(converted.color);
811
+ }
812
+ else if (converted.color.indexOf("#") === -1)
813
+ {
814
+ converted.color = toAnsi.colorNameToHex(converted.color);
815
+ }
816
+
817
+ return converted;
818
+ }
819
+
820
+ /**
821
+ * Load the context names that should be available to the environment.
822
+ * They are defined by the user.
823
+ * @see Context definitions {@link ./example/more/contexts-def.cjs}
824
+ * @param contextTable
825
+ */
826
+ setContexts(contextTable)
827
+ {
828
+ const arr = Object.keys(contextTable);
829
+ contextTable[PREDEFINED_CONTEXT_NAMES.DEFAULT] = this.contexts[PREDEFINED_CONTEXT_NAMES.DEFAULT] = this.generateDefaultContext();
830
+ contextTable[PREDEFINED_CONTEXT_NAMES.ERROR] = this.contexts[PREDEFINED_CONTEXT_NAMES.ERROR] = this.generateErrorContext();
831
+ // contextTable[PREDEFINED_CONTEXT_NAMES.LOG] = this.contexts[PREDEFINED_CONTEXT_NAMES.LOG] =
832
+ // this.generateCustomContext("LOG", {}); contextTable[PREDEFINED_CONTEXT_NAMES.INFO] =
833
+ // this.contexts[PREDEFINED_CONTEXT_NAMES.INFO] = this.generateCustomContext("INFO", { symbol:
834
+ // symbolNames.information, color : "orange" }); contextTable[PREDEFINED_CONTEXT_NAMES.WARN] =
835
+ // this.contexts[PREDEFINED_CONTEXT_NAMES.WARN] = this.generateCustomContext("WARN", { symbol:
836
+ // symbolNames.hand, color : "orange" });
837
+ arr.forEach((key) =>
838
+ {
839
+ const contextPassed = contextTable[key] || {};
840
+ contextPassed.contextName = key;
841
+ contextPassed.name = key;
842
+ this.contexts[key] = this.#allegeProperties(contextPassed);
843
+ contextTable[key] = this.contexts[key];
844
+ });
845
+ }
846
+
847
+ setTargets(targetTable = {})
848
+ {
849
+ this.targets = Object.assign({}, targetTable, {ALL: "ALL", USER: "USER"});
850
+ }
851
+
852
+ setActiveTarget(target)
853
+ {
854
+ this.activeTarget = target;
855
+ }
856
+
857
+ isTargetAllowed(target)
858
+ {
859
+ if (!target || !this.activeTarget)
860
+ {
861
+ return true;
862
+ }
863
+
864
+ if (target === this.targets.ALL)
865
+ {
866
+ return true;
867
+ }
868
+
869
+ return this.activeTarget === target;
870
+ }
871
+
872
+
873
+ // ------------------------------------------------
874
+ // Logging methods
875
+ // ------------------------------------------------
876
+ setColumns($line, context, text)
877
+ {
878
+ let index = 0;
879
+ for (let columnName in context)
880
+ {
881
+ if (!["contextName", "symbol", "lid", "text"].includes(columnName))
882
+ {
883
+ continue;
884
+ }
885
+
886
+ const colContent = context[columnName];
887
+ const $col = document.createElement("span");
888
+ $col.classList.add("analogger-col", `analogger-col-${columnName}`, `analogger-col-${index}`);
889
+ ++index;
890
+ $col.textContent = colContent;
891
+ $line.append($col);
892
+ }
893
+
894
+ const $col = document.createElement("span");
895
+ $col.classList.add("analogger-col", "analogger-col-text", `analogger-col-${index}`);
896
+ $col.textContent = text;
897
+ $line.append($col);
898
+ }
899
+
900
+ /**
901
+ * Check that the div has not too many entries
902
+ * @param $view
903
+ */
904
+ removeDomOldEntries = ($view) =>
905
+ {
906
+ const nbChildren = $view.childElementCount;
907
+ if (nbChildren > MAX_CHILDREN_DOM_ANALOGGER)
908
+ {
909
+ const n = Math.ceil(MAX_CHILDREN_DOM_ANALOGGER / 10);
910
+ for (let i = 0; i < n; ++i)
911
+ {
912
+ $view.removeChild($view.firstChild);
913
+ }
914
+ return n;
915
+ }
916
+
917
+ return 0;
918
+ };
919
+
920
+ /**
921
+ * Scroll to bottom if div is already at the bottom
922
+ * @param $view
923
+ */
924
+ scrollDivToBottom = ($view) =>
925
+ {
926
+ const scrollBottom = $view.scrollHeight - ($view.clientHeight + $view.scrollTop);
927
+ const divHeight = $view.clientHeight || $view.offsetHeight;
928
+ if (scrollBottom > divHeight / 2)
929
+ {
930
+ /* istanbul ignore next */
931
+ return;
932
+ }
933
+
934
+ $view.scrollTop = $view.scrollHeight;
935
+ };
936
+
937
+ /**
938
+ * Add a line to the Analogger div.
939
+ * Remove older lines if exceeding limit.
940
+ * @param $view
941
+ * @param $line
942
+ * @param context
943
+ * @param addType
944
+ */
945
+ addLineToDom($view, $line, {context, addType})
946
+ {
947
+ if (addType === ADD_TYPE.BOTTOM)
948
+ {
949
+ $view.append($line);
950
+ }
951
+ else
952
+ {
953
+ $view.insertBefore($line, $view.firstChild);
954
+ }
955
+
956
+ let nbRemoved = this.removeDomOldEntries($view);
957
+ if (nbRemoved)
958
+ {
959
+ if ($view.getElementsByClassName(CLASS_REMOVED_NOTIF).length)
960
+ {
961
+ return;
962
+ }
963
+
964
+ context.contextName = ANALOGGER_NAME;
965
+ context.symbol = "🗑";
966
+ context.color = "orange";
967
+ context.className = CLASS_REMOVED_NOTIF;
968
+
969
+ clearTimeout(this.timerAddLineToDomID);
970
+ this.timerAddLineToDomID = setTimeout(()=>
971
+ {
972
+ this.timerAddLineToDomID = null;
973
+ /* istanbul ignore next */
974
+ this.writeLogToDom(context, "", {addType: ADD_TYPE.TOP, message: `Oldest entries removed`});
975
+ }, 500);
976
+ return;
977
+ }
978
+
979
+ this.scrollDivToBottom($view);
980
+
981
+ }
982
+
983
+ writeLogToDom(context, fullText, {addType = ADD_TYPE.BOTTOM, message = ""} = {})
984
+ {
985
+ this.$containers = this.$containers || document.querySelectorAll(this.options.logToDom);
986
+ fullText = message || fullText;
987
+
988
+ for (let i = 0; i < this.$containers.length; ++i)
989
+ {
990
+ const $container = this.$containers[i];
991
+
992
+ let $view = $container.querySelector("." + CONSOLE_AREA_CLASSNAME);
993
+ if (!$view)
994
+ {
995
+ $view = document.createElement("div");
996
+ $view.classList.add(CONSOLE_AREA_CLASSNAME);
997
+ $container.append($view);
998
+ }
999
+
1000
+ const $line = document.createElement("div");
1001
+ $line.classList.add(LINE_CLASSNAME);
1002
+ if (context.className)
1003
+ {
1004
+ $line.classList.add(context.className);
1005
+ }
1006
+ $line.style.color = context.color;
1007
+
1008
+ this.setColumns($line, context, fullText);
1009
+
1010
+ // Prevent the application to be stuck when many logs are entered at once
1011
+ /* istanbul ignore next */
1012
+ setTimeout(/* istanbul ignore next */function($view, $line, {addType, context})
1013
+ {
1014
+ /* istanbul ignore next */
1015
+ this.addLineToDom($view, $line, {addType, context});
1016
+ }.bind(this, $view, $line, {addType, context}), 0);
1017
+
1018
+ }
1019
+ }
1020
+
1021
+ writeLogToFile(text)
1022
+ {
1023
+ try
1024
+ {
1025
+ fs.appendFileSync(this.options.logToFilePath, text + this.EOL);
1026
+ }
1027
+ catch (e)
1028
+ {
1029
+ /* istanbul ignore next */
1030
+ console.rawError("LOG_TO_FILE_FAILURE: ", e.message);
1031
+ }
1032
+ }
1033
+
1034
+ convertArgumentsToText(args)
1035
+ {
1036
+ const strs = [];
1037
+ let text;
1038
+ const n = args.length;
1039
+ for (let i = 0; i < n; ++i)
1040
+ {
1041
+ let str;
1042
+ let arg = args[i];
1043
+
1044
+ try
1045
+ {
1046
+ str = JSON.stringify(arg);
1047
+ }
1048
+ catch (e)
1049
+ {
1050
+
1051
+ }
1052
+
1053
+ if (!str)
1054
+ {
1055
+ try
1056
+ {
1057
+ str = stringify(arg);
1058
+ }
1059
+ catch (e)
1060
+ {
1061
+
1062
+ }
1063
+ }
1064
+
1065
+ strs.push(str);
1066
+ }
1067
+
1068
+ text = strs.join("•");
1069
+ return text;
1070
+ }
1071
+
1072
+ /**
1073
+ * Display log following template
1074
+ * @param context
1075
+ */
1076
+ processOutput(context = {})
1077
+ {
1078
+ try
1079
+ {
1080
+ let message = "";
1081
+
1082
+ if (!this.isTargetAllowed(context.target))
1083
+ {
1084
+ return;
1085
+ }
1086
+
1087
+ let args = Array.prototype.slice.call(arguments);
1088
+ args.shift();
1089
+
1090
+ message = this.convertArgumentsToText(args);
1091
+
1092
+ let output = "";
1093
+ let text = "";
1094
+ text = this.format({...context, message});
1095
+
1096
+ ++this.logCounter;
1097
+
1098
+ /* istanbul ignore next */
1099
+ if (this.isBrowser())
1100
+ {
1101
+ context.environnment = ____AnaLogger.ENVIRONMENT_TYPE.BROWSER;
1102
+ /* istanbul ignore next */
1103
+ if (this.options.logToDom)
1104
+ {
1105
+ /* istanbul ignore next */
1106
+ this.writeLogToDom(context, text, {message});
1107
+ }
1108
+
1109
+ output = `%c${text}`;
1110
+ }
1111
+ else
1112
+ {
1113
+ context.environnment = ____AnaLogger.ENVIRONMENT_TYPE.NODE;
1114
+ output = toAnsi.getTextFromColor(text, {
1115
+ fg : context.color,
1116
+ bg : context.bgColor,
1117
+ isBold : context.bold,
1118
+ isUnderline: context.underline,
1119
+ isReversed : context.reversed
1120
+ });
1121
+
1122
+ if (this.options.logToFile)
1123
+ {
1124
+ this.writeLogToFile(text);
1125
+ }
1126
+ }
1127
+
1128
+ if (this.keepLog)
1129
+ {
1130
+ this.logHistory.push(output);
1131
+ }
1132
+
1133
+ if (this.options.hideLog)
1134
+ {
1135
+ return;
1136
+ }
1137
+
1138
+ if (this.isBrowser())
1139
+ {
1140
+ this.#realConsoleLog(output, `color: ${context.color}`);
1141
+ }
1142
+ else
1143
+ {
1144
+ this.#realConsoleLog(output);
1145
+ }
1146
+
1147
+ this.errorTargetHandler(context, args);
1148
+ }
1149
+ catch (e)
1150
+ {
1151
+ /* istanbul ignore next */
1152
+ console.rawError("AnaLogger:", e.message);
1153
+ }
1154
+ }
1155
+
1156
+ /**
1157
+ * Check that a parameter uses the expected AnaLogger format.
1158
+ * For this, the first parameter should be an object that contains at least
1159
+ * a logging id (lid), a target, a contextName, etc
1160
+ * @param options
1161
+ * @returns {boolean}
1162
+ */
1163
+ isExtendedOptionsPassed(options)
1164
+ {
1165
+ if (typeof options !== "object")
1166
+ {
1167
+ return false;
1168
+ }
1169
+
1170
+ return options.hasOwnProperty("context") ||
1171
+ options.hasOwnProperty("target") ||
1172
+ options.hasOwnProperty("color") ||
1173
+ options.hasOwnProperty("contextName") ||
1174
+ options.hasOwnProperty("lid");
1175
+ }
1176
+
1177
+ listSymbols()
1178
+ {
1179
+ for (let key in symbolNames)
1180
+ {
1181
+ console.rawLog(symbolNames[key] + ` ${key} `);
1182
+ }
1183
+ }
1184
+
1185
+ applySymbolByName(context)
1186
+ {
1187
+ try
1188
+ {
1189
+ if (context.symbol && symbolNames[context.symbol])
1190
+ {
1191
+ context.symbol = symbolNames[context.symbol];
1192
+ }
1193
+ }
1194
+ catch (e)
1195
+ {
1196
+
1197
+ }
1198
+ }
1199
+
1200
+ convertToContext(options, defaultContext)
1201
+ {
1202
+ defaultContext = defaultContext || this.generateDefaultContext();
1203
+ options = options || defaultContext;
1204
+ let context = options;
1205
+ if (options.context && typeof options.context === "object")
1206
+ {
1207
+ const moreOptions = Object.assign({}, options);
1208
+ delete moreOptions.context;
1209
+ context = Object.assign({}, options.context, moreOptions);
1210
+ }
1211
+
1212
+ context = Object.assign({}, defaultContext, context);
1213
+ delete context.context;
1214
+
1215
+ this.applySymbolByName(context);
1216
+
1217
+ return context;
1218
+ }
1219
+
1220
+ /**
1221
+ * console.log with options set on the first parameter to dictate console log behaviours
1222
+ * @param options
1223
+ * @param args
1224
+ */
1225
+ log(options, ...args)
1226
+ {
1227
+ if (!this.isExtendedOptionsPassed(options))
1228
+ {
1229
+ const defaultContext = this.generateDefaultContext();
1230
+ this.processOutput.apply(this, [defaultContext, options, ...args]);
1231
+ return;
1232
+ }
1233
+
1234
+ let context = this.convertToContext(options);
1235
+
1236
+ this.processOutput.apply(this, [context, ...args]);
1237
+ }
1238
+
1239
+ error(options, ...args)
1240
+ {
1241
+ if (this.options.hideError)
1242
+ {
1243
+ return;
1244
+ }
1245
+
1246
+ if (!this.isExtendedOptionsPassed(options))
1247
+ {
1248
+ const defaultContext = this.generateErrorContext();
1249
+ this.processOutput.apply(this, [defaultContext, options, ...args]);
1250
+ return;
1251
+ }
1252
+
1253
+ const errorContext = this.generateErrorContext();
1254
+ let context = this.convertToContext(options, errorContext);
1255
+
1256
+ let args0 = Array.prototype.slice.call(arguments, 1);
1257
+ this.log(context, ...args0);
1258
+ }
1259
+
1260
+ overrideError()
1261
+ {
1262
+ if (!this.options.hideHookMessage)
1263
+ {
1264
+ this.#realConsoleLog("AnaLogger: Hook placed on console.error");
1265
+ }
1266
+ console.error = this.onDisplayError.bind(this);
1267
+ }
1268
+
1269
+ overrideConsole({log = true, info = true, warn = true, error = false} = {})
1270
+ {
1271
+ if (!this.options.hideHookMessage)
1272
+ {
1273
+ this.#realConsoleLog("AnaLogger: Hook placed on console.log");
1274
+ }
1275
+
1276
+ if (log)
1277
+ {
1278
+ console.log = this.onDisplayLog.bind(this);
1279
+ }
1280
+
1281
+ if (info)
1282
+ {
1283
+ console.info = this.onDisplayLog.bind(this);
1284
+ }
1285
+
1286
+ if (warn)
1287
+ {
1288
+ console.warn = this.onDisplayLog.bind(this);
1289
+ }
1290
+
1291
+ if (error)
1292
+ {
1293
+ this.overrideError();
1294
+ }
1295
+ }
1296
+
1297
+ removeOverrideError()
1298
+ {
1299
+ console.warn = this.#realConsoleError;
1300
+ }
1301
+
1302
+ removeOverride({log = true, info = true, warn = true, error = false} = {})
1303
+ {
1304
+ if (log)
1305
+ {
1306
+ console.log = this.#realConsoleLog;
1307
+ }
1308
+
1309
+ if (info)
1310
+ {
1311
+ console.info = this.#realConsoleInfo;
1312
+ }
1313
+
1314
+ if (warn)
1315
+ {
1316
+ console.warn = this.#realConsoleWarn;
1317
+ }
1318
+
1319
+ if (error)
1320
+ {
1321
+ this.removeOverrideError();
1322
+ }
1323
+
1324
+ }
1325
+
1326
+ info(...args)
1327
+ {
1328
+ return this.log(...args);
1329
+ }
1330
+
1331
+ warn(...args)
1332
+ {
1333
+ return this.log(...args);
1334
+ }
1335
+
1336
+ table(...args)
1337
+ {
1338
+ return this.buildTable(...args);
1339
+ }
1340
+
1341
+ alert(...args)
1342
+ {
1343
+ if (this.isNode())
1344
+ {
1345
+ return this.log(...args);
1346
+ }
1347
+
1348
+ const message = args.join(" | ");
1349
+
1350
+ alert(message);
1351
+ }
1352
+
1353
+ assert(condition, expected = true, ...args)
1354
+ {
1355
+ let result;
1356
+
1357
+ try
1358
+ {
1359
+ if (typeof condition === "function")
1360
+ {
1361
+ result = condition(...args);
1362
+ if (result !== expected)
1363
+ {
1364
+ this.error("Asset failed");
1365
+ return false;
1366
+ }
1367
+
1368
+ if (!this.options.hidePassingTests)
1369
+ {
1370
+ this.log("SUCCESS: Assert passed");
1371
+ }
1372
+ return true;
1373
+ }
1374
+
1375
+ if (condition !== expected)
1376
+ {
1377
+ this.error("Assert failed");
1378
+ return false;
1379
+ }
1380
+
1381
+ if (!this.options.hidePassingTests)
1382
+ {
1383
+ this.log("SUCCESS: Assert passed");
1384
+ }
1385
+ return true;
1386
+ }
1387
+ catch (e)
1388
+ {
1389
+ this.error("Unexpected error in assert");
1390
+ }
1391
+
1392
+ return false;
1393
+ }
1394
+
1395
+ /**
1396
+ * Set standard Analogger format
1397
+ * @example
1398
+ * // Output Example
1399
+ * // [14:01:06] DEFAULT: (1060) ⚡ " ✔ My log ..."
1400
+ * @param activeTarget
1401
+ * @param override
1402
+ * @returns {boolean}
1403
+ */
1404
+ applyAnalogFormatting({activeTarget = "", override = false} = {})
1405
+ {
1406
+ try
1407
+ {
1408
+ const lidLenMax = 4;
1409
+
1410
+ const LOG_CONTEXTS = {
1411
+ STANDARD: null,
1412
+ TEST : {color: "#B18904", symbol: "diamonds"},
1413
+ C1 : null,
1414
+ C2 : null,
1415
+ C3 : null,
1416
+ DEFAULT : {}
1417
+ };
1418
+
1419
+ const DEV = (typeof process === "object") ? process.env.DEVELOPER : "DEV";
1420
+ const DEV1 = (typeof process === "object") ? process.env.DEVELOPER : "DEV1";
1421
+
1422
+ const LOG_TARGETS = {
1423
+ ALL : "ALL",
1424
+ DEBUG: "DEBUG",
1425
+ DEV,
1426
+ DEV1,
1427
+ USER : "USER"
1428
+ };
1429
+
1430
+ this.setDefaultContext(LOG_CONTEXTS.DEFAULT);
1431
+ this.setTargets(LOG_TARGETS);
1432
+
1433
+ activeTarget && this.setActiveTarget(activeTarget);
1434
+
1435
+ this.setOptions({silent: false, hideError: false, hideHookMessage: true, lidLenMax});
1436
+ if (override)
1437
+ {
1438
+ this.overrideConsole();
1439
+ this.overrideError();
1440
+ }
1441
+
1442
+ return true;
1443
+ }
1444
+ catch (e)
1445
+ {
1446
+ /* istanbul ignore next */
1447
+ console.error({lid: 3249}, e.message);
1448
+ }
1449
+
1450
+ /* istanbul ignore next */
1451
+ return false;
1452
+ }
1453
+
1454
+ applyPredefinedFormat(name = PREDEFINED_FORMATS.DEFAULT_FORMAT, {activeTarget = "", override = false} = {})
1455
+ {
1456
+ if (name === PREDEFINED_FORMATS.DEFAULT_FORMAT)
1457
+ {
1458
+ return this.applyAnalogFormatting({activeTarget, override});
1459
+ }
1460
+ }
1461
+
1462
+ }
1463
+
1464
+ export const AnaLogger = ____AnaLogger;
1465
+
1466
+
1467
+ const __AnaLogger = ____AnaLogger;
1468
+ export default __AnaLogger;
1469
+
1470
+ export const anaLogger = new ____AnaLogger();
1471
+
1472
+