@schukai/monster 3.92.3 → 3.94.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/package.json +1 -1
- package/source/components/datatable/datasource/rest.mjs +17 -0
- package/source/components/state/log/entry.mjs +4 -4
- package/source/components/state/log.mjs +195 -167
- package/source/components/state/style/log.pcss +31 -79
- package/source/components/state/stylesheet/log.mjs +7 -14
- package/source/data/transformer.mjs +806 -789
- package/source/i18n/time-ago.mjs +671 -0
- package/source/types/validate.mjs +1 -0
- package/test/cases/i18n/time-ago.mjs +33 -0
@@ -12,27 +12,28 @@
|
|
12
12
|
* SPDX-License-Identifier: AGPL-3.0
|
13
13
|
*/
|
14
14
|
|
15
|
-
import {
|
16
|
-
import {
|
17
|
-
import {
|
18
|
-
import {
|
19
|
-
import {
|
15
|
+
import {getLocaleOfDocument} from "../dom/locale.mjs";
|
16
|
+
import {Base} from "../types/base.mjs";
|
17
|
+
import {getGlobal, getGlobalObject} from "../types/global.mjs";
|
18
|
+
import {ID} from "../types/id.mjs";
|
19
|
+
import {isArray, isObject, isString, isPrimitive} from "../types/is.mjs";
|
20
20
|
import {
|
21
|
-
|
22
|
-
|
21
|
+
getDocumentTranslations,
|
22
|
+
Translations,
|
23
23
|
} from "../i18n/translations.mjs";
|
24
24
|
import {
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
25
|
+
validateFunction,
|
26
|
+
validateInteger,
|
27
|
+
validateObject,
|
28
|
+
validatePrimitive,
|
29
|
+
validateString,
|
30
|
+
validateBoolean,
|
31
31
|
} from "../types/validate.mjs";
|
32
|
-
import {
|
33
|
-
import {
|
32
|
+
import {clone} from "../util/clone.mjs";
|
33
|
+
import {Pathfinder} from "./pathfinder.mjs";
|
34
|
+
import {formatTimeAgo} from "../i18n/time-ago.mjs";
|
34
35
|
|
35
|
-
export {
|
36
|
+
export {Transformer};
|
36
37
|
|
37
38
|
/**
|
38
39
|
* The transformer class is a swiss army knife for manipulating values.
|
@@ -52,53 +53,53 @@ export { Transformer };
|
|
52
53
|
* @summary The transformer class is a swiss army knife for manipulating values. especially in combination with the pipe, processing chains can be built up.
|
53
54
|
*/
|
54
55
|
class Transformer extends Base {
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
56
|
+
/**
|
57
|
+
*
|
58
|
+
* @param {string} definition
|
59
|
+
*/
|
60
|
+
constructor(definition) {
|
61
|
+
super();
|
62
|
+
this.args = disassemble(definition);
|
63
|
+
this.command = this.args.shift();
|
64
|
+
this.callbacks = new Map();
|
65
|
+
}
|
66
|
+
|
67
|
+
/**
|
68
|
+
*
|
69
|
+
* @param {string} name
|
70
|
+
* @param {function} callback
|
71
|
+
* @param {object} context
|
72
|
+
* @return {Transformer}
|
73
|
+
* @throws {TypeError} value is not a string
|
74
|
+
* @throws {TypeError} value is not a function
|
75
|
+
*/
|
76
|
+
setCallback(name, callback, context) {
|
77
|
+
validateString(name);
|
78
|
+
validateFunction(callback);
|
79
|
+
|
80
|
+
if (context !== undefined) {
|
81
|
+
validateObject(context);
|
82
|
+
}
|
83
|
+
|
84
|
+
this.callbacks.set(name, {
|
85
|
+
callback: callback,
|
86
|
+
context: context,
|
87
|
+
});
|
88
|
+
|
89
|
+
return this;
|
90
|
+
}
|
91
|
+
|
92
|
+
/**
|
93
|
+
*
|
94
|
+
* @param {*} value
|
95
|
+
* @return {*}
|
96
|
+
* @throws {Error} unknown command
|
97
|
+
* @throws {TypeError} unsupported type
|
98
|
+
* @throws {Error} type not supported
|
99
|
+
*/
|
100
|
+
run(value) {
|
101
|
+
return transform.apply(this, [value]);
|
102
|
+
}
|
102
103
|
}
|
103
104
|
|
104
105
|
/**
|
@@ -108,41 +109,41 @@ class Transformer extends Base {
|
|
108
109
|
* @private
|
109
110
|
*/
|
110
111
|
function disassemble(command) {
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
112
|
+
validateString(command);
|
113
|
+
|
114
|
+
const placeholder = new Map();
|
115
|
+
const regex = /((?<pattern>\\(?<char>.)){1})/gim;
|
116
|
+
|
117
|
+
// The separator for args must be escaped
|
118
|
+
// undefined string which should not occur normally and is also not a regex
|
119
|
+
const result = command.matchAll(regex);
|
120
|
+
|
121
|
+
for (const m of result) {
|
122
|
+
const g = m?.["groups"];
|
123
|
+
if (!isObject(g)) {
|
124
|
+
continue;
|
125
|
+
}
|
126
|
+
|
127
|
+
const p = g?.["pattern"];
|
128
|
+
const c = g?.["char"];
|
129
|
+
|
130
|
+
if (p && c) {
|
131
|
+
const r = `__${new ID().toString()}__`;
|
132
|
+
placeholder.set(r, c);
|
133
|
+
command = command.replace(p, r);
|
134
|
+
}
|
135
|
+
}
|
136
|
+
let parts = command.split(":");
|
137
|
+
|
138
|
+
parts = parts.map(function (value) {
|
139
|
+
let v = value.trim();
|
140
|
+
for (const k of placeholder) {
|
141
|
+
v = v.replace(k[0], k[1]);
|
142
|
+
}
|
143
|
+
return v;
|
144
|
+
});
|
145
|
+
|
146
|
+
return parts;
|
146
147
|
}
|
147
148
|
|
148
149
|
/**
|
@@ -153,12 +154,12 @@ function disassemble(command) {
|
|
153
154
|
* @private
|
154
155
|
*/
|
155
156
|
function convertToString(value) {
|
156
|
-
|
157
|
-
|
158
|
-
|
157
|
+
if (isObject(value) && value.hasOwnProperty("toString")) {
|
158
|
+
value = value.toString();
|
159
|
+
}
|
159
160
|
|
160
|
-
|
161
|
-
|
161
|
+
validateString(value);
|
162
|
+
return value;
|
162
163
|
}
|
163
164
|
|
164
165
|
/**
|
@@ -172,667 +173,680 @@ function convertToString(value) {
|
|
172
173
|
* @throws {Error} missing key parameter
|
173
174
|
*/
|
174
175
|
function transform(value) {
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
|
756
|
-
|
757
|
-
|
758
|
-
|
759
|
-
|
760
|
-
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
|
771
|
-
|
772
|
-
|
773
|
-
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
|
826
|
-
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
|
176
|
+
const console = getGlobalObject("console");
|
177
|
+
|
178
|
+
const args = clone(this.args);
|
179
|
+
let key;
|
180
|
+
let defaultValue;
|
181
|
+
|
182
|
+
let translations;
|
183
|
+
let date;
|
184
|
+
let locale;
|
185
|
+
let timestamp;
|
186
|
+
let map;
|
187
|
+
let keyValue;
|
188
|
+
|
189
|
+
switch (this.command) {
|
190
|
+
case "static":
|
191
|
+
return this.args.join(":");
|
192
|
+
|
193
|
+
case "tolower":
|
194
|
+
case "strtolower":
|
195
|
+
case "tolowercase":
|
196
|
+
validateString(value);
|
197
|
+
return value.toLowerCase();
|
198
|
+
|
199
|
+
case "contains":
|
200
|
+
if (isString(value)) {
|
201
|
+
return value.includes(args[0]);
|
202
|
+
}
|
203
|
+
|
204
|
+
if (isArray(value)) {
|
205
|
+
return value.includes(args[0]);
|
206
|
+
}
|
207
|
+
|
208
|
+
if (isObject(value)) {
|
209
|
+
return value.hasOwnProperty(args[0]);
|
210
|
+
}
|
211
|
+
|
212
|
+
return false;
|
213
|
+
|
214
|
+
case "has-entries":
|
215
|
+
case "hasentries":
|
216
|
+
if (isObject(value)) {
|
217
|
+
return Object.keys(value).length > 0;
|
218
|
+
}
|
219
|
+
|
220
|
+
if (isArray(value)) {
|
221
|
+
return value.length > 0;
|
222
|
+
}
|
223
|
+
|
224
|
+
return false;
|
225
|
+
|
226
|
+
case "isundefined":
|
227
|
+
case "is-undefined":
|
228
|
+
return value === undefined;
|
229
|
+
|
230
|
+
case "isnull":
|
231
|
+
case "is-null":
|
232
|
+
return value === null;
|
233
|
+
|
234
|
+
case "isset":
|
235
|
+
case "is-set":
|
236
|
+
return value !== undefined && value !== null;
|
237
|
+
|
238
|
+
case "isnumber":
|
239
|
+
case "is-number":
|
240
|
+
return isPrimitive(value) && !isNaN(value);
|
241
|
+
|
242
|
+
case "isinteger":
|
243
|
+
case "is-integer":
|
244
|
+
return isPrimitive(value) && !isNaN(value) && value % 1 === 0;
|
245
|
+
|
246
|
+
case "isfloat":
|
247
|
+
case "is-float":
|
248
|
+
return isPrimitive(value) && !isNaN(value) && value % 1 !== 0;
|
249
|
+
|
250
|
+
case "isobject":
|
251
|
+
case "is-object":
|
252
|
+
return isObject(value);
|
253
|
+
|
254
|
+
case "isarray":
|
255
|
+
case "is-array":
|
256
|
+
return Array.isArray(value);
|
257
|
+
|
258
|
+
case "not":
|
259
|
+
validateBoolean(value);
|
260
|
+
return !value;
|
261
|
+
|
262
|
+
case "toupper":
|
263
|
+
case "strtoupper":
|
264
|
+
case "touppercase":
|
265
|
+
validateString(value);
|
266
|
+
return value.toUpperCase();
|
267
|
+
|
268
|
+
case "tostring":
|
269
|
+
return `${value}`;
|
270
|
+
|
271
|
+
case "tointeger":
|
272
|
+
const n = parseInt(value);
|
273
|
+
validateInteger(n);
|
274
|
+
return n;
|
275
|
+
|
276
|
+
case "to-json":
|
277
|
+
case "tojson":
|
278
|
+
return JSON.stringify(value);
|
279
|
+
|
280
|
+
case "from-json":
|
281
|
+
case "fromjson":
|
282
|
+
return JSON.parse(value);
|
283
|
+
|
284
|
+
case "trim":
|
285
|
+
validateString(value);
|
286
|
+
return value.trim();
|
287
|
+
|
288
|
+
case "rawurlencode":
|
289
|
+
validateString(value);
|
290
|
+
return encodeURIComponent(value)
|
291
|
+
.replace(/!/g, "%21")
|
292
|
+
.replace(/'/g, "%27")
|
293
|
+
.replace(/\(/g, "%28")
|
294
|
+
.replace(/\)/g, "%29")
|
295
|
+
.replace(/\*/g, "%2A");
|
296
|
+
|
297
|
+
case "call":
|
298
|
+
/**
|
299
|
+
* callback-definition
|
300
|
+
* function callback(value, ...args) {
|
301
|
+
* return value;
|
302
|
+
* }
|
303
|
+
*/
|
304
|
+
|
305
|
+
let callback;
|
306
|
+
const callbackName = args.shift();
|
307
|
+
let context = getGlobal();
|
308
|
+
|
309
|
+
if (isObject(value) && value.hasOwnProperty(callbackName)) {
|
310
|
+
callback = value[callbackName];
|
311
|
+
} else if (this.callbacks.has(callbackName)) {
|
312
|
+
const s = this.callbacks.get(callbackName);
|
313
|
+
callback = s?.["callback"];
|
314
|
+
context = s?.["context"];
|
315
|
+
} else if (
|
316
|
+
typeof window === "object" &&
|
317
|
+
window.hasOwnProperty(callbackName)
|
318
|
+
) {
|
319
|
+
callback = window[callbackName];
|
320
|
+
}
|
321
|
+
validateFunction(callback);
|
322
|
+
|
323
|
+
args.unshift(value);
|
324
|
+
return callback.call(context, ...args);
|
325
|
+
|
326
|
+
case "plain":
|
327
|
+
case "plaintext":
|
328
|
+
validateString(value);
|
329
|
+
const doc = new DOMParser().parseFromString(value, "text/html");
|
330
|
+
return doc.body.textContent || "";
|
331
|
+
|
332
|
+
case "if":
|
333
|
+
case "?":
|
334
|
+
validatePrimitive(value);
|
335
|
+
|
336
|
+
let trueStatement = args.shift() || undefined;
|
337
|
+
let falseStatement = args.shift() || undefined;
|
338
|
+
|
339
|
+
trueStatement = convertSpecialStrings(trueStatement, value);
|
340
|
+
falseStatement = convertSpecialStrings(falseStatement, value);
|
341
|
+
|
342
|
+
const condition = evaluateCondition(value);
|
343
|
+
return condition ? trueStatement : falseStatement;
|
344
|
+
|
345
|
+
case "ucfirst":
|
346
|
+
validateString(value);
|
347
|
+
|
348
|
+
const firstchar = value.charAt(0).toUpperCase();
|
349
|
+
return firstchar + value.substr(1);
|
350
|
+
case "ucwords":
|
351
|
+
validateString(value);
|
352
|
+
|
353
|
+
return value.replace(
|
354
|
+
/^([a-z\u00E0-\u00FC])|\s+([a-z\u00E0-\u00FC])/g,
|
355
|
+
function (v) {
|
356
|
+
return v.toUpperCase();
|
357
|
+
},
|
358
|
+
);
|
359
|
+
|
360
|
+
case "count":
|
361
|
+
case "length":
|
362
|
+
if (
|
363
|
+
(isString(value) || isObject(value) || isArray(value)) &&
|
364
|
+
value.hasOwnProperty("length")
|
365
|
+
) {
|
366
|
+
return value.length;
|
367
|
+
}
|
368
|
+
|
369
|
+
throw new TypeError(`unsupported type ${typeof value}`);
|
370
|
+
|
371
|
+
case "to-base64":
|
372
|
+
case "btoa":
|
373
|
+
case "base64":
|
374
|
+
return btoa(convertToString(value));
|
375
|
+
|
376
|
+
case "atob":
|
377
|
+
case "from-base64":
|
378
|
+
return atob(convertToString(value));
|
379
|
+
|
380
|
+
case "empty":
|
381
|
+
return "";
|
382
|
+
|
383
|
+
case "undefined":
|
384
|
+
return undefined;
|
385
|
+
|
386
|
+
case "debug":
|
387
|
+
if (isObject(console)) {
|
388
|
+
console.log(value);
|
389
|
+
}
|
390
|
+
|
391
|
+
return value;
|
392
|
+
|
393
|
+
case "prefix":
|
394
|
+
validateString(value);
|
395
|
+
const prefix = args?.[0];
|
396
|
+
return prefix + value;
|
397
|
+
|
398
|
+
case "suffix":
|
399
|
+
validateString(value);
|
400
|
+
const suffix = args?.[0];
|
401
|
+
return value + suffix;
|
402
|
+
|
403
|
+
case "uniqid":
|
404
|
+
return new ID().toString();
|
405
|
+
|
406
|
+
case "first-key":
|
407
|
+
case "last-key":
|
408
|
+
case "nth-last-key":
|
409
|
+
case "nth-key":
|
410
|
+
if (!isObject(value)) {
|
411
|
+
throw new Error("type not supported");
|
412
|
+
}
|
413
|
+
|
414
|
+
const keys = Object.keys(value).sort();
|
415
|
+
|
416
|
+
if (this.command === "first-key") {
|
417
|
+
key = 0;
|
418
|
+
} else if (this.command === "last-key") {
|
419
|
+
key = keys.length - 1;
|
420
|
+
} else {
|
421
|
+
key = validateInteger(parseInt(args.shift()));
|
422
|
+
|
423
|
+
if (this.command === "nth-last-key") {
|
424
|
+
key = keys.length - key - 1;
|
425
|
+
}
|
426
|
+
}
|
427
|
+
|
428
|
+
defaultValue = args.shift() || "";
|
429
|
+
|
430
|
+
const useKey = keys?.[key];
|
431
|
+
|
432
|
+
if (value?.[useKey]) {
|
433
|
+
return value?.[useKey];
|
434
|
+
}
|
435
|
+
|
436
|
+
return defaultValue;
|
437
|
+
|
438
|
+
case "key":
|
439
|
+
case "property":
|
440
|
+
case "index":
|
441
|
+
key = args.shift() || undefined;
|
442
|
+
|
443
|
+
if (key === undefined) {
|
444
|
+
throw new Error("missing key parameter");
|
445
|
+
}
|
446
|
+
|
447
|
+
defaultValue = args.shift() || undefined;
|
448
|
+
|
449
|
+
if (value instanceof Map) {
|
450
|
+
if (!value.has(key)) {
|
451
|
+
return defaultValue;
|
452
|
+
}
|
453
|
+
return value.get(key);
|
454
|
+
}
|
455
|
+
|
456
|
+
if (isObject(value) || isArray(value)) {
|
457
|
+
if (value?.[key]) {
|
458
|
+
return value?.[key];
|
459
|
+
}
|
460
|
+
|
461
|
+
return defaultValue;
|
462
|
+
}
|
463
|
+
|
464
|
+
throw new Error("type not supported");
|
465
|
+
|
466
|
+
case "path-exists":
|
467
|
+
key = args.shift();
|
468
|
+
if (key === undefined) {
|
469
|
+
throw new Error("missing key parameter");
|
470
|
+
}
|
471
|
+
|
472
|
+
return new Pathfinder(value).exists(key);
|
473
|
+
|
474
|
+
case "concat":
|
475
|
+
const pf2 = new Pathfinder(value);
|
476
|
+
let concat = "";
|
477
|
+
while (args.length > 0) {
|
478
|
+
key = args.shift();
|
479
|
+
if (key === undefined) {
|
480
|
+
throw new Error("missing key parameter");
|
481
|
+
}
|
482
|
+
|
483
|
+
// add empty strings
|
484
|
+
if (isString(key) && key.trim() === "") {
|
485
|
+
concat += key;
|
486
|
+
continue;
|
487
|
+
}
|
488
|
+
|
489
|
+
if (!pf2.exists(key)) {
|
490
|
+
concat += key;
|
491
|
+
continue;
|
492
|
+
}
|
493
|
+
const v = pf2.getVia(key);
|
494
|
+
if (!isPrimitive(v)) {
|
495
|
+
throw new Error("value is not primitive");
|
496
|
+
}
|
497
|
+
|
498
|
+
concat += v;
|
499
|
+
}
|
500
|
+
|
501
|
+
return concat;
|
502
|
+
case "path":
|
503
|
+
key = args.shift();
|
504
|
+
if (key === undefined) {
|
505
|
+
throw new Error("missing key parameter");
|
506
|
+
}
|
507
|
+
|
508
|
+
const pf = new Pathfinder(value);
|
509
|
+
|
510
|
+
if (!pf.exists(key)) {
|
511
|
+
return undefined;
|
512
|
+
}
|
513
|
+
|
514
|
+
return pf.getVia(key);
|
515
|
+
|
516
|
+
case "substring":
|
517
|
+
validateString(value);
|
518
|
+
|
519
|
+
const start = parseInt(args[0]) || 0;
|
520
|
+
const end = (parseInt(args[1]) || 0) + start;
|
521
|
+
|
522
|
+
return value.substring(start, end);
|
523
|
+
|
524
|
+
case "nop":
|
525
|
+
return value;
|
526
|
+
|
527
|
+
case "??":
|
528
|
+
case "default":
|
529
|
+
if (value !== undefined && value !== null) {
|
530
|
+
return value;
|
531
|
+
}
|
532
|
+
|
533
|
+
defaultValue = args.shift();
|
534
|
+
let defaultType = args.shift();
|
535
|
+
if (defaultType === undefined) {
|
536
|
+
defaultType = "string";
|
537
|
+
}
|
538
|
+
|
539
|
+
switch (defaultType) {
|
540
|
+
case "int":
|
541
|
+
case "integer":
|
542
|
+
return parseInt(defaultValue);
|
543
|
+
case "float":
|
544
|
+
return parseFloat(defaultValue);
|
545
|
+
case "undefined":
|
546
|
+
return undefined;
|
547
|
+
case "bool":
|
548
|
+
case "boolean":
|
549
|
+
defaultValue = defaultValue.toLowerCase();
|
550
|
+
return (
|
551
|
+
(defaultValue !== "undefined" &&
|
552
|
+
defaultValue !== "" &&
|
553
|
+
defaultValue !== "off" &&
|
554
|
+
defaultValue !== "false" &&
|
555
|
+
defaultValue !== "false") ||
|
556
|
+
defaultValue === "on" ||
|
557
|
+
defaultValue === "true" ||
|
558
|
+
defaultValue === "true"
|
559
|
+
);
|
560
|
+
case "string":
|
561
|
+
return `${defaultValue}`;
|
562
|
+
case "object":
|
563
|
+
return JSON.parse(atob(defaultValue));
|
564
|
+
}
|
565
|
+
|
566
|
+
throw new Error("type not supported");
|
567
|
+
|
568
|
+
case "map":
|
569
|
+
map = new Map();
|
570
|
+
while (args.length > 0) {
|
571
|
+
keyValue = args.shift();
|
572
|
+
if (keyValue === undefined) {
|
573
|
+
throw new Error("missing key parameter");
|
574
|
+
}
|
575
|
+
|
576
|
+
keyValue = keyValue.split("=");
|
577
|
+
map.set(keyValue[0], keyValue[1]);
|
578
|
+
}
|
579
|
+
|
580
|
+
return map.get(value);
|
581
|
+
|
582
|
+
case "equals":
|
583
|
+
if (args.length === 0) {
|
584
|
+
throw new Error("missing value parameter");
|
585
|
+
}
|
586
|
+
|
587
|
+
validatePrimitive(value);
|
588
|
+
|
589
|
+
const equalsValue = args.shift();
|
590
|
+
|
591
|
+
/**
|
592
|
+
* The history of “typeof null”
|
593
|
+
* https://2ality.com/2013/10/typeof-null.html
|
594
|
+
* In JavaScript, typeof null is 'object', which incorrectly suggests
|
595
|
+
* that null is an object.
|
596
|
+
*/
|
597
|
+
if (value === null) {
|
598
|
+
return equalsValue === "null";
|
599
|
+
}
|
600
|
+
|
601
|
+
const typeOfValue = typeof value;
|
602
|
+
|
603
|
+
switch (typeOfValue) {
|
604
|
+
case "string":
|
605
|
+
return value === equalsValue;
|
606
|
+
case "number":
|
607
|
+
return value === parseFloat(equalsValue);
|
608
|
+
case "boolean":
|
609
|
+
return value === (equalsValue === "true" || equalsValue === "on");
|
610
|
+
case "undefined":
|
611
|
+
return equalsValue === "undefined";
|
612
|
+
default:
|
613
|
+
throw new Error("type not supported");
|
614
|
+
}
|
615
|
+
|
616
|
+
case "money":
|
617
|
+
case "currency":
|
618
|
+
try {
|
619
|
+
locale = getLocaleOfDocument();
|
620
|
+
} catch (e) {
|
621
|
+
throw new Error(`unsupported locale or missing format (${e.message})`);
|
622
|
+
}
|
623
|
+
|
624
|
+
// Verwenden von RegExp, um Währung und Betrag zu extrahieren
|
625
|
+
const match = value.match(/^([A-Z]{3})[\s-]*(\d+(\.\d+)?)$/);
|
626
|
+
if (!match) {
|
627
|
+
throw new Error("invalid currency format");
|
628
|
+
}
|
629
|
+
|
630
|
+
const currency = match[1];
|
631
|
+
const amount = match[2];
|
632
|
+
|
633
|
+
const maximumFractionDigits = args?.[0] || 2;
|
634
|
+
const roundingIncrement = args?.[1] || 5;
|
635
|
+
|
636
|
+
const nf = new Intl.NumberFormat(locale.toString(), {
|
637
|
+
style: "currency",
|
638
|
+
currency: currency,
|
639
|
+
maximumFractionDigits: maximumFractionDigits,
|
640
|
+
roundingIncrement: roundingIncrement,
|
641
|
+
});
|
642
|
+
|
643
|
+
return nf.format(amount);
|
644
|
+
|
645
|
+
case "timestamp":
|
646
|
+
date = new Date(value);
|
647
|
+
timestamp = date.getTime();
|
648
|
+
if (isNaN(timestamp)) {
|
649
|
+
throw new Error("invalid date");
|
650
|
+
}
|
651
|
+
return timestamp;
|
652
|
+
|
653
|
+
case "time":
|
654
|
+
date = new Date(value);
|
655
|
+
if (isNaN(date.getTime())) {
|
656
|
+
throw new Error("invalid date");
|
657
|
+
}
|
658
|
+
|
659
|
+
try {
|
660
|
+
locale = getLocaleOfDocument();
|
661
|
+
return date.toLocaleTimeString(locale.toString(), {
|
662
|
+
hour12: false,
|
663
|
+
});
|
664
|
+
} catch (e) {
|
665
|
+
throw new Error(`unsupported locale or missing format (${e.message})`);
|
666
|
+
}
|
667
|
+
|
668
|
+
case "datetimeformat":
|
669
|
+
date = new Date(value);
|
670
|
+
if (isNaN(date.getTime())) {
|
671
|
+
throw new Error("invalid date");
|
672
|
+
}
|
673
|
+
|
674
|
+
const options = {
|
675
|
+
dateStyle: "medium",
|
676
|
+
timeStyle: "medium",
|
677
|
+
hour12: false,
|
678
|
+
};
|
679
|
+
|
680
|
+
if (args.length > 0) {
|
681
|
+
options.dateStyle = args.shift();
|
682
|
+
}
|
683
|
+
|
684
|
+
if (args.length > 0) {
|
685
|
+
options.timeStyle = args.shift();
|
686
|
+
}
|
687
|
+
|
688
|
+
try {
|
689
|
+
locale = getLocaleOfDocument().toString();
|
690
|
+
return new Intl.DateTimeFormat(locale, options).format(date);
|
691
|
+
} catch (e) {
|
692
|
+
throw new Error(`unsupported locale or missing format (${e.message})`);
|
693
|
+
}
|
694
|
+
|
695
|
+
case "datetime":
|
696
|
+
date = new Date(value);
|
697
|
+
if (isNaN(date.getTime())) {
|
698
|
+
throw new Error("invalid date");
|
699
|
+
}
|
700
|
+
|
701
|
+
try {
|
702
|
+
locale = getLocaleOfDocument();
|
703
|
+
return date.toLocaleString(locale.toString(), {
|
704
|
+
hour12: false,
|
705
|
+
});
|
706
|
+
} catch (e) {
|
707
|
+
throw new Error(`unsupported locale or missing format (${e.message})`);
|
708
|
+
}
|
709
|
+
|
710
|
+
case "date":
|
711
|
+
date = new Date(value);
|
712
|
+
if (isNaN(date.getTime())) {
|
713
|
+
throw new Error("invalid date");
|
714
|
+
}
|
715
|
+
|
716
|
+
try {
|
717
|
+
locale = getLocaleOfDocument();
|
718
|
+
return date.toLocaleDateString(locale.toString(), {
|
719
|
+
year: "numeric",
|
720
|
+
month: "2-digit",
|
721
|
+
day: "2-digit",
|
722
|
+
});
|
723
|
+
} catch (e) {
|
724
|
+
throw new Error(`unsupported locale or missing format (${e.message})`);
|
725
|
+
}
|
726
|
+
|
727
|
+
case "time-ago":
|
728
|
+
date = new Date(value);
|
729
|
+
if (isNaN(date.getTime())) {
|
730
|
+
throw new Error("invalid date");
|
731
|
+
}
|
732
|
+
|
733
|
+
try {
|
734
|
+
locale = getLocaleOfDocument();
|
735
|
+
return formatTimeAgo(date, locale.toString());
|
736
|
+
} catch (e) {
|
737
|
+
throw new Error(`unsupported locale or missing format (${e.message})`);
|
738
|
+
}
|
739
|
+
|
740
|
+
case "year":
|
741
|
+
date = new Date(value);
|
742
|
+
if (isNaN(date.getTime())) {
|
743
|
+
throw new Error("invalid date");
|
744
|
+
}
|
745
|
+
|
746
|
+
return date.getFullYear();
|
747
|
+
|
748
|
+
case "month":
|
749
|
+
date = new Date(value);
|
750
|
+
if (isNaN(date.getTime())) {
|
751
|
+
throw new Error("invalid date");
|
752
|
+
}
|
753
|
+
|
754
|
+
return date.getMonth() + 1;
|
755
|
+
|
756
|
+
case "day":
|
757
|
+
date = new Date(value);
|
758
|
+
if (isNaN(date.getTime())) {
|
759
|
+
throw new Error("invalid date");
|
760
|
+
}
|
761
|
+
|
762
|
+
return date.getDate();
|
763
|
+
|
764
|
+
case "weekday":
|
765
|
+
date = new Date(value);
|
766
|
+
if (isNaN(date.getTime())) {
|
767
|
+
throw new Error("invalid date");
|
768
|
+
}
|
769
|
+
|
770
|
+
return date.getDay();
|
771
|
+
|
772
|
+
case "hour":
|
773
|
+
case "hours":
|
774
|
+
date = new Date(value);
|
775
|
+
if (isNaN(date.getTime())) {
|
776
|
+
throw new Error("invalid date");
|
777
|
+
}
|
778
|
+
|
779
|
+
return date.getHours();
|
780
|
+
|
781
|
+
case "minute":
|
782
|
+
case "minutes":
|
783
|
+
date = new Date(value);
|
784
|
+
if (isNaN(date.getTime())) {
|
785
|
+
throw new Error("invalid date");
|
786
|
+
}
|
787
|
+
|
788
|
+
return date.getMinutes();
|
789
|
+
|
790
|
+
case "second":
|
791
|
+
case "seconds":
|
792
|
+
date = new Date(value);
|
793
|
+
if (isNaN(date.getTime())) {
|
794
|
+
throw new Error("invalid date");
|
795
|
+
}
|
796
|
+
|
797
|
+
return date.getSeconds();
|
798
|
+
|
799
|
+
case "i18n":
|
800
|
+
case "translation":
|
801
|
+
translations = getDocumentTranslations();
|
802
|
+
if (!(translations instanceof Translations)) {
|
803
|
+
throw new Error("missing translations");
|
804
|
+
}
|
805
|
+
|
806
|
+
key = args.shift() || undefined;
|
807
|
+
if (key === undefined) {
|
808
|
+
key = value;
|
809
|
+
}
|
810
|
+
|
811
|
+
defaultValue = args.shift() || undefined;
|
812
|
+
|
813
|
+
defaultValue = convertSpecialStrings(defaultValue, value);
|
814
|
+
|
815
|
+
return translations.getText(key, defaultValue);
|
816
|
+
|
817
|
+
case "set-toggle":
|
818
|
+
case "set-set":
|
819
|
+
case "set-remove":
|
820
|
+
const modifier = args.shift();
|
821
|
+
let delimiter = args.shift();
|
822
|
+
if (delimiter === undefined) {
|
823
|
+
delimiter = " ";
|
824
|
+
}
|
825
|
+
|
826
|
+
const set = new Set(value.split(delimiter));
|
827
|
+
const toggle = new Set(modifier.split(delimiter));
|
828
|
+
if (this.command === "set-toggle") {
|
829
|
+
for (const t of toggle) {
|
830
|
+
if (set.has(t)) {
|
831
|
+
set.delete(t);
|
832
|
+
} else {
|
833
|
+
set.add(t);
|
834
|
+
}
|
835
|
+
}
|
836
|
+
} else if (this.command === "set-set") {
|
837
|
+
for (const t of toggle) {
|
838
|
+
set.add(t);
|
839
|
+
}
|
840
|
+
} else if (this.command === "set-remove") {
|
841
|
+
for (const t of toggle) {
|
842
|
+
set.delete(t);
|
843
|
+
}
|
844
|
+
}
|
845
|
+
return Array.from(set).join(delimiter);
|
846
|
+
|
847
|
+
default:
|
848
|
+
throw new Error(`unknown command ${this.command}`);
|
849
|
+
}
|
836
850
|
}
|
837
851
|
|
838
852
|
/**
|
@@ -843,18 +857,18 @@ function transform(value) {
|
|
843
857
|
* @return {undefined|*|null|string}
|
844
858
|
*/
|
845
859
|
function convertSpecialStrings(input, value) {
|
846
|
-
|
847
|
-
|
848
|
-
|
849
|
-
|
850
|
-
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
|
855
|
-
|
856
|
-
|
857
|
-
|
860
|
+
switch (input) {
|
861
|
+
case "value":
|
862
|
+
return value;
|
863
|
+
case "\\value":
|
864
|
+
return "value";
|
865
|
+
case "\\undefined":
|
866
|
+
return undefined;
|
867
|
+
case "\\null":
|
868
|
+
return null;
|
869
|
+
default:
|
870
|
+
return input;
|
871
|
+
}
|
858
872
|
}
|
859
873
|
|
860
874
|
/**
|
@@ -863,17 +877,20 @@ function convertSpecialStrings(input, value) {
|
|
863
877
|
* @return {boolean}
|
864
878
|
*/
|
865
879
|
function evaluateCondition(value) {
|
866
|
-
|
867
|
-
|
868
|
-
|
869
|
-
|
870
|
-
|
871
|
-
|
872
|
-
|
873
|
-
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
|
878
|
-
|
880
|
+
const lowerValue = typeof value === "string" ? value.toLowerCase() : value;
|
881
|
+
|
882
|
+
return (
|
883
|
+
(value !== undefined &&
|
884
|
+
value !== null &&
|
885
|
+
value !== "" &&
|
886
|
+
lowerValue !== "off" &&
|
887
|
+
lowerValue !== "false" &&
|
888
|
+
value !== false) ||
|
889
|
+
lowerValue === "on" ||
|
890
|
+
lowerValue === "true" ||
|
891
|
+
value === true
|
892
|
+
);
|
879
893
|
}
|
894
|
+
|
895
|
+
|
896
|
+
|