bare-script 2.2.18 → 2.3.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/lib/library.js +1392 -1030
- package/lib/parser.js +1 -1
- package/package.json +3 -3
package/lib/library.js
CHANGED
|
@@ -17,1049 +17,1411 @@ import {typeModel} from 'schema-markdown/lib/typeModel.js';
|
|
|
17
17
|
export const defaultMaxStatements = 1e9;
|
|
18
18
|
|
|
19
19
|
|
|
20
|
-
//
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
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
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
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
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
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
|
-
// $arg seconds: Optional (default is 0). The number of seconds.
|
|
344
|
-
// $arg milliseconds: Optional (default is 0). The number of milliseconds.
|
|
345
|
-
// $return: The new UTC datetime
|
|
346
|
-
'datetimeNewUTC': ([year, month, day, hours = 0, minutes = 0, seconds = 0, milliseconds = 0]) => (
|
|
347
|
-
new Date(Date.UTC(year, month - 1, day, hours, minutes, seconds, milliseconds))
|
|
348
|
-
),
|
|
349
|
-
|
|
350
|
-
// $function: datetimeNow
|
|
351
|
-
// $group: Datetime
|
|
352
|
-
// $doc: Get the current datetime
|
|
353
|
-
// $return: The current datetime
|
|
354
|
-
'datetimeNow': () => new Date(),
|
|
355
|
-
|
|
356
|
-
// $function: datetimeSecond
|
|
357
|
-
// $group: Datetime
|
|
358
|
-
// $doc: Get the number of seconds of a datetime
|
|
359
|
-
// $arg datetime: The datetime
|
|
360
|
-
// $arg utc: Optional (default is false). If true, return the UTC seconds.
|
|
361
|
-
// $return: The number of seconds
|
|
362
|
-
'datetimeSecond': ([datetime, utc = false]) => (
|
|
363
|
-
datetime instanceof Date ? (utc ? datetime.getUTCSeconds() : datetime.getSeconds()) : null
|
|
364
|
-
),
|
|
365
|
-
|
|
366
|
-
// $function: datetimeToday
|
|
367
|
-
// $group: Datetime
|
|
368
|
-
// $doc: Get today's datetime
|
|
369
|
-
// $return: Today's datetime
|
|
370
|
-
'datetimeToday': () => {
|
|
371
|
-
const now = new Date();
|
|
372
|
-
return new Date(now.getFullYear(), now.getMonth(), now.getDate());
|
|
373
|
-
},
|
|
374
|
-
|
|
375
|
-
// $function: datetimeYear
|
|
376
|
-
// $group: Datetime
|
|
377
|
-
// $doc: Get the full year of a datetime
|
|
378
|
-
// $arg datetime: The datetime
|
|
379
|
-
// $arg utc: Optional (default is false). If true, return the UTC year.
|
|
380
|
-
// $return: The full year
|
|
381
|
-
'datetimeYear': ([datetime, utc = false]) => (
|
|
382
|
-
datetime instanceof Date ? (utc ? datetime.getUTCFullYear() : datetime.getFullYear()) : null
|
|
383
|
-
),
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
//
|
|
387
|
-
// JSON functions
|
|
388
|
-
//
|
|
389
|
-
|
|
390
|
-
// $function: jsonParse
|
|
391
|
-
// $group: JSON
|
|
392
|
-
// $doc: Convert a JSON string to an object
|
|
393
|
-
// $arg string: The JSON string
|
|
394
|
-
// $return: The object
|
|
395
|
-
'jsonParse': ([string]) => JSON.parse(string),
|
|
396
|
-
|
|
397
|
-
// $function: jsonStringify
|
|
398
|
-
// $group: JSON
|
|
399
|
-
// $doc: Convert an object to a JSON string
|
|
400
|
-
// $arg value: The object
|
|
401
|
-
// $arg space: Optional (default is null). The indentation string or number.
|
|
402
|
-
// $return: The JSON string
|
|
403
|
-
'jsonStringify': ([value, space]) => jsonStringifySortKeys(value, space),
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
//
|
|
407
|
-
// Math functions
|
|
408
|
-
//
|
|
409
|
-
|
|
410
|
-
// $function: mathAbs
|
|
411
|
-
// $group: Math
|
|
412
|
-
// $doc: Compute the absolute value of a number
|
|
413
|
-
// $arg x: The number
|
|
414
|
-
// $return: The absolute value of the number
|
|
415
|
-
'mathAbs': ([x]) => Math.abs(x),
|
|
416
|
-
|
|
417
|
-
// $function: mathAcos
|
|
418
|
-
// $group: Math
|
|
419
|
-
// $doc: Compute the arccosine, in radians, of a number
|
|
420
|
-
// $arg x: The number
|
|
421
|
-
// $return: The arccosine, in radians, of the number
|
|
422
|
-
'mathAcos': ([x]) => Math.acos(x),
|
|
423
|
-
|
|
424
|
-
// $function: mathAsin
|
|
425
|
-
// $group: Math
|
|
426
|
-
// $doc: Compute the arcsine, in radians, of a number
|
|
427
|
-
// $arg x: The number
|
|
428
|
-
// $return: The arcsine, in radians, of the number
|
|
429
|
-
'mathAsin': ([x]) => Math.asin(x),
|
|
430
|
-
|
|
431
|
-
// $function: mathAtan
|
|
432
|
-
// $group: Math
|
|
433
|
-
// $doc: Compute the arctangent, in radians, of a number
|
|
434
|
-
// $arg x: The number
|
|
435
|
-
// $return: The arctangent, in radians, of the number
|
|
436
|
-
'mathAtan': ([x]) => Math.atan(x),
|
|
437
|
-
|
|
438
|
-
// $function: mathAtan2
|
|
439
|
-
// $group: Math
|
|
440
|
-
// $doc: Compute the angle, in radians, between (0, 0) and a point
|
|
441
|
-
// $arg y: The Y-coordinate of the point
|
|
442
|
-
// $arg x: The X-coordinate of the point
|
|
443
|
-
// $return: The angle, in radians
|
|
444
|
-
'mathAtan2': ([y, x]) => Math.atan2(y, x),
|
|
445
|
-
|
|
446
|
-
// $function: mathCeil
|
|
447
|
-
// $group: Math
|
|
448
|
-
// $doc: Compute the ceiling of a number (round up to the next highest integer)
|
|
449
|
-
// $arg x: The number
|
|
450
|
-
// $return: The ceiling of the number
|
|
451
|
-
'mathCeil': ([x]) => Math.ceil(x),
|
|
452
|
-
|
|
453
|
-
// $function: mathCos
|
|
454
|
-
// $group: Math
|
|
455
|
-
// $doc: Compute the cosine of an angle, in radians
|
|
456
|
-
// $arg x: The angle, in radians
|
|
457
|
-
// $return: The cosine of the angle
|
|
458
|
-
'mathCos': ([x]) => Math.cos(x),
|
|
459
|
-
|
|
460
|
-
// $function: mathFloor
|
|
461
|
-
// $group: Math
|
|
462
|
-
// $doc: Compute the floor of a number (round down to the next lowest integer)
|
|
463
|
-
// $arg x: The number
|
|
464
|
-
// $return: The floor of the number
|
|
465
|
-
'mathFloor': ([x]) => Math.floor(x),
|
|
466
|
-
|
|
467
|
-
// $function: mathLn
|
|
468
|
-
// $group: Math
|
|
469
|
-
// $doc: Compute the natural logarithm (base e) of a number
|
|
470
|
-
// $arg x: The number
|
|
471
|
-
// $return: The natural logarithm of the number
|
|
472
|
-
'mathLn': ([x]) => Math.log(x),
|
|
473
|
-
|
|
474
|
-
// $function: mathLog
|
|
475
|
-
// $group: Math
|
|
476
|
-
// $doc: Compute the logarithm (base 10) of a number
|
|
477
|
-
// $arg x: The number
|
|
478
|
-
// $arg base: Optional (default is 10). The logarithm base.
|
|
479
|
-
// $return: The logarithm of the number
|
|
480
|
-
'mathLog': ([x, base = 10]) => Math.log(x) / Math.log(base),
|
|
481
|
-
|
|
482
|
-
// $function: mathMax
|
|
483
|
-
// $group: Math
|
|
484
|
-
// $doc: Compute the maximum value
|
|
485
|
-
// $arg values...: The values
|
|
486
|
-
// $return: The maximum value
|
|
487
|
-
'mathMax': (values) => Math.max(...values),
|
|
488
|
-
|
|
489
|
-
// $function: mathMin
|
|
490
|
-
// $group: Math
|
|
491
|
-
// $doc: Compute the minimum value
|
|
492
|
-
// $arg values...: The values
|
|
493
|
-
// $return: The minimum value
|
|
494
|
-
'mathMin': (values) => Math.min(...values),
|
|
495
|
-
|
|
496
|
-
// $function: mathPi
|
|
497
|
-
// $group: Math
|
|
498
|
-
// $doc: Return the number pi
|
|
499
|
-
// $return: The number pi
|
|
500
|
-
'mathPi': () => Math.PI,
|
|
501
|
-
|
|
502
|
-
// $function: mathRandom
|
|
503
|
-
// $group: Math
|
|
504
|
-
// $doc: Compute a random number between 0 and 1, inclusive
|
|
505
|
-
// $return: A random number
|
|
506
|
-
'mathRandom': () => Math.random(),
|
|
507
|
-
|
|
508
|
-
// $function: mathRound
|
|
509
|
-
// $group: Math
|
|
510
|
-
// $doc: Round a number to a certain number of decimal places
|
|
511
|
-
// $arg x: The number
|
|
512
|
-
// $arg digits: Optional (default is 0). The number of decimal digits to round to.
|
|
513
|
-
// $return: The rounded number
|
|
514
|
-
'mathRound': ([x, digits = 0]) => {
|
|
515
|
-
const multiplier = 10 ** digits;
|
|
516
|
-
return Math.round(x * multiplier) / multiplier;
|
|
517
|
-
},
|
|
518
|
-
|
|
519
|
-
// $function: mathSign
|
|
520
|
-
// $group: Math
|
|
521
|
-
// $doc: Compute the sign of a number
|
|
522
|
-
// $arg x: The number
|
|
523
|
-
// $return: -1 for a negative number, 1 for a positive number, and 0 for zero
|
|
524
|
-
'mathSign': ([x]) => Math.sign(x),
|
|
525
|
-
|
|
526
|
-
// $function: mathSin
|
|
527
|
-
// $group: Math
|
|
528
|
-
// $doc: Compute the sine of an angle, in radians
|
|
529
|
-
// $arg x: The angle, in radians
|
|
530
|
-
// $return: The sine of the angle
|
|
531
|
-
'mathSin': ([x]) => Math.sin(x),
|
|
532
|
-
|
|
533
|
-
// $function: mathSqrt
|
|
534
|
-
// $group: Math
|
|
535
|
-
// $doc: Compute the square root of a number
|
|
536
|
-
// $arg x: The number
|
|
537
|
-
// $return: The square root of the number
|
|
538
|
-
'mathSqrt': ([x]) => Math.sqrt(x),
|
|
539
|
-
|
|
540
|
-
// $function: mathTan
|
|
541
|
-
// $group: Math
|
|
542
|
-
// $doc: Compute the tangent of an angle, in radians
|
|
543
|
-
// $arg x: The angle, in radians
|
|
544
|
-
// $return: The tangent of the angle
|
|
545
|
-
'mathTan': ([x]) => Math.tan(x),
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
//
|
|
549
|
-
// Number functions
|
|
550
|
-
//
|
|
551
|
-
|
|
552
|
-
// $function: numberParseFloat
|
|
553
|
-
// $group: Number
|
|
554
|
-
// $doc: Parse a string as a floating point number
|
|
555
|
-
// $arg string: The string
|
|
556
|
-
// $return: The number
|
|
557
|
-
'numberParseFloat': ([string]) => Number.parseFloat(string),
|
|
558
|
-
|
|
559
|
-
// $function: numberParseInt
|
|
560
|
-
// $group: Number
|
|
561
|
-
// $doc: Parse a string as an integer
|
|
562
|
-
// $arg string: The string
|
|
563
|
-
// $arg radix: Optional (default is 10). The number base.
|
|
564
|
-
// $return: The integer
|
|
565
|
-
'numberParseInt': ([string, radix = 10]) => Number.parseInt(string, radix),
|
|
566
|
-
|
|
567
|
-
// $function: numberToFixed
|
|
568
|
-
// $group: Number
|
|
569
|
-
// $doc: Format a number using fixed-point notation
|
|
570
|
-
// $arg x: The number
|
|
571
|
-
// $arg digits: Optional (default is 2). The number of digits to appear after the decimal point.
|
|
572
|
-
// $arg trim: Optional (default is false). If true, trim trailing zeroes and decimal point.
|
|
573
|
-
// $return: The fixed-point notation string
|
|
574
|
-
'numberToFixed': ([x, digits = 2, trim = false]) => {
|
|
575
|
-
let result = null;
|
|
576
|
-
if (typeof x === 'number') {
|
|
577
|
-
result = x.toFixed(digits);
|
|
578
|
-
if (trim) {
|
|
579
|
-
result = result.replace(rNumberCleanup, '');
|
|
580
|
-
}
|
|
581
|
-
}
|
|
582
|
-
return result;
|
|
583
|
-
},
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
//
|
|
587
|
-
// Object functions
|
|
588
|
-
//
|
|
589
|
-
|
|
590
|
-
// $function: objectAssign
|
|
591
|
-
// $group: Object
|
|
592
|
-
// $doc: Assign the keys/values of one object to another
|
|
593
|
-
// $arg object: The object to assign to
|
|
594
|
-
// $arg object2: The object to assign
|
|
595
|
-
// $return: The updated object
|
|
596
|
-
'objectAssign': ([object, object2]) => {
|
|
597
|
-
if (object !== null && typeof object === 'object' && !Array.isArray(object) &&
|
|
598
|
-
object2 !== null && typeof object2 === 'object' && !Array.isArray(object2)) {
|
|
599
|
-
Object.assign(object, object2);
|
|
600
|
-
}
|
|
601
|
-
return object;
|
|
602
|
-
},
|
|
603
|
-
|
|
604
|
-
// $function: objectCopy
|
|
605
|
-
// $group: Object
|
|
606
|
-
// $doc: Create a copy of an object
|
|
607
|
-
// $arg object: The object to copy
|
|
608
|
-
// $return: The object copy
|
|
609
|
-
'objectCopy': ([object]) => (object !== null && typeof object === 'object' && !Array.isArray(object) ? {...object} : {}),
|
|
610
|
-
|
|
611
|
-
// $function: objectDelete
|
|
612
|
-
// $group: Object
|
|
613
|
-
// $doc: Delete an object key
|
|
614
|
-
// $arg object: The object
|
|
615
|
-
// $arg key: The key to delete
|
|
616
|
-
'objectDelete': ([object, key]) => {
|
|
617
|
-
if (object !== null && typeof object === 'object' && !Array.isArray(object)) {
|
|
618
|
-
delete object[key];
|
|
619
|
-
}
|
|
620
|
-
},
|
|
621
|
-
|
|
622
|
-
// $function: objectGet
|
|
623
|
-
// $group: Object
|
|
624
|
-
// $doc: Get an object key's value
|
|
625
|
-
// $arg object: The object
|
|
626
|
-
// $arg key: The key
|
|
627
|
-
// $arg defaultValue: The default value (optional)
|
|
628
|
-
// $return: The value or null if the key does not exist
|
|
629
|
-
'objectGet': ([object, key, defaultValue = null]) => (
|
|
630
|
-
object !== null && typeof object === 'object' ? (Object.hasOwn(object, key) ? object[key] : defaultValue) : defaultValue
|
|
631
|
-
),
|
|
632
|
-
|
|
633
|
-
// $function: objectHas
|
|
634
|
-
// $group: Object
|
|
635
|
-
// $doc: Test if an object contains a key
|
|
636
|
-
// $arg object: The object
|
|
637
|
-
// $arg key: The key
|
|
638
|
-
// $return: true if the object contains the key, false otherwise
|
|
639
|
-
'objectHas': ([object, key]) => (object !== null && typeof object === 'object' && Object.hasOwn(object, key)),
|
|
640
|
-
|
|
641
|
-
// $function: objectKeys
|
|
642
|
-
// $group: Object
|
|
643
|
-
// $doc: Get an object's keys
|
|
644
|
-
// $arg object: The object
|
|
645
|
-
// $return: The array of keys; null if not an object
|
|
646
|
-
'objectKeys': ([object]) => (object !== null && typeof object === 'object' && !Array.isArray(object) ? Object.keys(object) : null),
|
|
647
|
-
|
|
648
|
-
// $function: objectNew
|
|
649
|
-
// $group: Object
|
|
650
|
-
// $doc: Create a new object
|
|
651
|
-
// $arg keyValues...: The object's initial key and value pairs
|
|
652
|
-
// $return: The new object
|
|
653
|
-
'objectNew': (keyValues) => {
|
|
654
|
-
const object = {};
|
|
655
|
-
for (let ix = 0; ix < keyValues.length; ix += 2) {
|
|
656
|
-
object[keyValues[ix]] = (ix + 1 < keyValues.length ? keyValues[ix + 1] : null);
|
|
20
|
+
//
|
|
21
|
+
// Array functions
|
|
22
|
+
//
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
// $function: arrayCopy
|
|
26
|
+
// $group: Array
|
|
27
|
+
// $doc: Create a copy of an array
|
|
28
|
+
// $arg array: The array to copy
|
|
29
|
+
// $return: The array copy
|
|
30
|
+
function arrayCopy([array]) {
|
|
31
|
+
return Array.isArray(array) ? [...array] : [];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
// $function: arrayExtend
|
|
36
|
+
// $group: Array
|
|
37
|
+
// $doc: Extend one array with another
|
|
38
|
+
// $arg array: The array to extend
|
|
39
|
+
// $arg array2: The array to extend with
|
|
40
|
+
// $return: The extended array
|
|
41
|
+
function arrayExtend([array, array2]) {
|
|
42
|
+
if (Array.isArray(array) && Array.isArray(array2)) {
|
|
43
|
+
array.push(...array2);
|
|
44
|
+
}
|
|
45
|
+
return array;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
// $function: arrayGet
|
|
50
|
+
// $group: Array
|
|
51
|
+
// $doc: Get an array element
|
|
52
|
+
// $arg array: The array
|
|
53
|
+
// $arg index: The array element's index
|
|
54
|
+
// $return: The array element
|
|
55
|
+
function arrayGet([array, index]) {
|
|
56
|
+
return Array.isArray(array) ? array[index] ?? null : null;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
// $function: arrayIndexOf
|
|
61
|
+
// $group: Array
|
|
62
|
+
// $doc: Find the index of a value in an array
|
|
63
|
+
// $arg array: The array
|
|
64
|
+
// $arg value: The value to find in the array
|
|
65
|
+
// $arg index: Optional (default is 0). The index at which to start the search.
|
|
66
|
+
// $return: The first index of the value in the array; -1 if not found.
|
|
67
|
+
function arrayIndexOf([array, value, index = 0]) {
|
|
68
|
+
return Array.isArray(array) ? array.indexOf(value, index) : -1;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
// $function: arrayJoin
|
|
73
|
+
// $group: Array
|
|
74
|
+
// $doc: Join an array with a separator string
|
|
75
|
+
// $arg array: The array
|
|
76
|
+
// $arg separator: The separator string
|
|
77
|
+
// $return: The joined string
|
|
78
|
+
function arrayJoin([array, separator]) {
|
|
79
|
+
return Array.isArray(array) ? array.join(separator) : '';
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
// $function: arrayLastIndexOf
|
|
84
|
+
// $group: Array
|
|
85
|
+
// $doc: Find the last index of a value in an array
|
|
86
|
+
// $arg array: The array
|
|
87
|
+
// $arg value: The value to find in the array
|
|
88
|
+
// $arg index: Optional (default is the end of the array). The index at which to start the search.
|
|
89
|
+
// $return: The last index of the value in the array; -1 if not found.
|
|
90
|
+
function arrayLastIndexOf([array, value, index = null]) {
|
|
91
|
+
return Array.isArray(array) ? (index === null ? array.lastIndexOf(value) : array.lastIndexOf(value, index)) : -1;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
// $function: arrayLength
|
|
96
|
+
// $group: Array
|
|
97
|
+
// $doc: Get the length of an array
|
|
98
|
+
// $arg array: The array
|
|
99
|
+
// $return: The array's length; null if not an array
|
|
100
|
+
function arrayLength([array]) {
|
|
101
|
+
return Array.isArray(array) ? array.length : null;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
// $function: arrayNew
|
|
106
|
+
// $group: Array
|
|
107
|
+
// $doc: Create a new array
|
|
108
|
+
// $arg values...: The new array's values
|
|
109
|
+
// $return: The new array
|
|
110
|
+
function arrayNew(values) {
|
|
111
|
+
return values;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
// $function: arrayNewSize
|
|
116
|
+
// $group: Array
|
|
117
|
+
// $doc: Create a new array of a specific size
|
|
118
|
+
// $arg size: Optional (default is 0). The new array's size.
|
|
119
|
+
// $arg value: Optional (default is 0). The value with which to fill the new array.
|
|
120
|
+
// $return: The new array
|
|
121
|
+
function arrayNewSize([size = 0, value = 0]) {
|
|
122
|
+
return new Array(size).fill(value);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
// $function: arrayPop
|
|
127
|
+
// $group: Array
|
|
128
|
+
// $doc: Remove the last element of the array and return it
|
|
129
|
+
// $arg array: The array
|
|
130
|
+
// $return: The last element of the array; null if the array is empty.
|
|
131
|
+
function arrayPop([array]) {
|
|
132
|
+
return Array.isArray(array) ? array.pop() ?? null : null;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
// $function: arrayPush
|
|
137
|
+
// $group: Array
|
|
138
|
+
// $doc: Add one or more values to the end of the array
|
|
139
|
+
// $arg array: The array
|
|
140
|
+
// $arg values...: The values to add to the end of the array
|
|
141
|
+
// $return: The array
|
|
142
|
+
function arrayPush([array, ...values]) {
|
|
143
|
+
if (Array.isArray(array)) {
|
|
144
|
+
array.push(...values);
|
|
145
|
+
}
|
|
146
|
+
return array;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
// $function: arraySet
|
|
151
|
+
// $group: Array
|
|
152
|
+
// $doc: Set an array element value
|
|
153
|
+
// $arg array: The array
|
|
154
|
+
// $arg index: The index of the element to set
|
|
155
|
+
// $arg value: The value to set
|
|
156
|
+
// $return: The value
|
|
157
|
+
function arraySet([array, index, value]) {
|
|
158
|
+
if (Array.isArray(array)) {
|
|
159
|
+
array[index] = value;
|
|
160
|
+
}
|
|
161
|
+
return value;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
// $function: arrayShift
|
|
166
|
+
// $group: Array
|
|
167
|
+
// $doc: Remove the first element of the array and return it
|
|
168
|
+
// $arg array: The array
|
|
169
|
+
// $return: The first element of the array; null if the array is empty.
|
|
170
|
+
function arrayShift([array]) {
|
|
171
|
+
return Array.isArray(array) ? array.shift() ?? null : null;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
// $function: arraySlice
|
|
176
|
+
// $group: Array
|
|
177
|
+
// $doc: Copy a portion of an array
|
|
178
|
+
// $arg array: The array
|
|
179
|
+
// $arg start: Optional (default is 0). The start index of the slice.
|
|
180
|
+
// $arg end: Optional (default is the end of the array). The end index of the slice.
|
|
181
|
+
// $return: The new array slice
|
|
182
|
+
function arraySlice([array, start, end]) {
|
|
183
|
+
return Array.isArray(array) ? array.slice(start, end) : null;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
// $function: arraySort
|
|
188
|
+
// $group: Array
|
|
189
|
+
// $doc: Sort an array
|
|
190
|
+
// $arg array: The array
|
|
191
|
+
// $arg compareFn: Optional (default is null). The comparison function.
|
|
192
|
+
// $return: The sorted array
|
|
193
|
+
function arraySort([array, compareFn = null], options) {
|
|
194
|
+
return Array.isArray(array) ? (compareFn === null ? array.sort() : array.sort((...args) => compareFn(args, options))) : null;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
//
|
|
199
|
+
// Data functions
|
|
200
|
+
//
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
// $function: dataAggregate
|
|
204
|
+
// $group: Data
|
|
205
|
+
// $doc: Aggregate a data array
|
|
206
|
+
// $arg data: The data array
|
|
207
|
+
// $arg aggregation: The [aggregation model](https://craigahobbs.github.io/bare-script/library/model.html#var.vName='Aggregation')
|
|
208
|
+
// $return: The aggregated data array
|
|
209
|
+
function dataAggregate([data, aggregation]) {
|
|
210
|
+
return aggregateData(data, validateAggregation(aggregation));
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
// $function: dataCalculatedField
|
|
215
|
+
// $group: Data
|
|
216
|
+
// $doc: Add a calculated field to a data array
|
|
217
|
+
// $arg data: The data array
|
|
218
|
+
// $arg fieldName: The calculated field name
|
|
219
|
+
// $arg expr: The calculated field expression
|
|
220
|
+
// $arg variables: Optional (default is null). A variables object the expression evaluation.
|
|
221
|
+
// $return: The updated data array
|
|
222
|
+
function dataCalculatedField([data, fieldName, expr, variables = null], options) {
|
|
223
|
+
return addCalculatedField(data, fieldName, expr, variables, options);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// $function: dataFilter
|
|
227
|
+
// $group: Data
|
|
228
|
+
// $doc: Filter a data array
|
|
229
|
+
// $arg data: The data array
|
|
230
|
+
// $arg expr: The filter expression
|
|
231
|
+
// $arg variables: Optional (default is null). A variables object the expression evaluation.
|
|
232
|
+
// $return: The filtered data array
|
|
233
|
+
function dataFilter([data, expr, variables = null], options) {
|
|
234
|
+
return filterData(data, expr, variables, options);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
// $function: dataJoin
|
|
239
|
+
// $group: Data
|
|
240
|
+
// $doc: Join two data arrays
|
|
241
|
+
// $arg leftData: The left data array
|
|
242
|
+
// $arg rightData: The right data array
|
|
243
|
+
// $arg joinExpr: The [join expression](https://craigahobbs.github.io/bare-script/language/#expressions)
|
|
244
|
+
// $arg rightExpr: Optional (default is null).
|
|
245
|
+
// $arg rightExpr: The right [join expression](https://craigahobbs.github.io/bare-script/language/#expressions)
|
|
246
|
+
// $arg isLeftJoin: Optional (default is false). If true, perform a left join (always include left row).
|
|
247
|
+
// $arg variables: Optional (default is null). A variables object for join expression evaluation.
|
|
248
|
+
// $return: The joined data array
|
|
249
|
+
function dataJoin([leftData, rightData, joinExpr, rightExpr = null, isLeftJoin = false, variables = null], options) {
|
|
250
|
+
return joinData(leftData, rightData, joinExpr, rightExpr, isLeftJoin, variables, options);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
// $function: dataParseCSV
|
|
255
|
+
// $group: Data
|
|
256
|
+
// $doc: Parse CSV text to a data array
|
|
257
|
+
// $arg text...: The CSV text
|
|
258
|
+
// $return: The data array
|
|
259
|
+
function dataParseCSV(text) {
|
|
260
|
+
const data = parseCSV(text);
|
|
261
|
+
validateData(data, true);
|
|
262
|
+
return data;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
// $function: dataSort
|
|
267
|
+
// $group: Data
|
|
268
|
+
// $doc: Sort a data array
|
|
269
|
+
// $arg data: The data array
|
|
270
|
+
// $arg sorts: The sort field-name/descending-sort tuples
|
|
271
|
+
// $return: The sorted data array
|
|
272
|
+
function dataSort([data, sorts]) {
|
|
273
|
+
return sortData(data, sorts);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
// $function: dataTop
|
|
278
|
+
// $group: Data
|
|
279
|
+
// $doc: Keep the top rows for each category
|
|
280
|
+
// $arg data: The data array
|
|
281
|
+
// $arg count: The number of rows to keep
|
|
282
|
+
// $arg categoryFields: Optional (default is null). The category fields.
|
|
283
|
+
// $return: The top data array
|
|
284
|
+
function dataTop([data, count, categoryFields = null]) {
|
|
285
|
+
return topData(data, count, categoryFields);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
// $function: dataValidate
|
|
290
|
+
// $group: Data
|
|
291
|
+
// $doc: Validate a data array
|
|
292
|
+
// $arg data: The data array
|
|
293
|
+
// $return: The validated data array
|
|
294
|
+
function dataValidate([data]) {
|
|
295
|
+
validateData(data);
|
|
296
|
+
return data;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
//
|
|
301
|
+
// Datetime functions
|
|
302
|
+
//
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
// $function: datetimeDay
|
|
306
|
+
// $group: Datetime
|
|
307
|
+
// $doc: Get the day of the month of a datetime
|
|
308
|
+
// $arg datetime: The datetime
|
|
309
|
+
// $arg utc: Optional (default is false). If true, return the UTC day of the month.
|
|
310
|
+
// $return: The day of the month
|
|
311
|
+
function datetimeDay([datetime, utc = false]) {
|
|
312
|
+
return datetime instanceof Date ? (utc ? datetime.getUTCDate() : datetime.getDate()) : null;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
// $function: datetimeHour
|
|
317
|
+
// $group: Datetime
|
|
318
|
+
// $doc: Get the hour of a datetime
|
|
319
|
+
// $arg datetime: The datetime
|
|
320
|
+
// $arg utc: Optional (default is false). If true, return the UTC hour.
|
|
321
|
+
// $return: The hour
|
|
322
|
+
function datetimeHour([datetime, utc = false]) {
|
|
323
|
+
return datetime instanceof Date ? (utc ? datetime.getUTCHours() : datetime.getHours()) : null;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
// $function: datetimeISOFormat
|
|
328
|
+
// $group: Datetime
|
|
329
|
+
// $doc: Format the datetime as an ISO date/time string
|
|
330
|
+
// $arg datetime: The datetime
|
|
331
|
+
// $arg isDate: If true, format the datetime as an ISO date
|
|
332
|
+
// $return: The formatted datetime string
|
|
333
|
+
function datetimeISOFormat([datetime, isDate = false]) {
|
|
334
|
+
let result = null;
|
|
335
|
+
if (datetime instanceof Date) {
|
|
336
|
+
if (isDate) {
|
|
337
|
+
const year = datetime.getFullYear();
|
|
338
|
+
const month = datetime.getMonth() + 1;
|
|
339
|
+
const day = datetime.getDate();
|
|
340
|
+
result = `${year}-${month < 10 ? '0' : ''}${month}-${day < 10 ? '0' : ''}${day}`;
|
|
341
|
+
} else {
|
|
342
|
+
result = datetime.toISOString();
|
|
657
343
|
}
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
344
|
+
}
|
|
345
|
+
return result;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
// $function: datetimeISOParse
|
|
350
|
+
// $group: Datetime
|
|
351
|
+
// $doc: Parse an ISO date/time string
|
|
352
|
+
// $arg str: The ISO date/time string
|
|
353
|
+
// $return: The datetime, or null if parsing fails
|
|
354
|
+
function datetimeISOParse([str]) {
|
|
355
|
+
return parseDatetime(str);
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
|
|
359
|
+
// $function: datetimeMinute
|
|
360
|
+
// $group: Datetime
|
|
361
|
+
// $doc: Get the number of minutes of a datetime
|
|
362
|
+
// $arg datetime: The datetime
|
|
363
|
+
// $arg utc: Optional (default is false). If true, return the UTC minutes.
|
|
364
|
+
// $return: The number of minutes
|
|
365
|
+
function datetimeMinute([datetime, utc = false]) {
|
|
366
|
+
return datetime instanceof Date ? (utc ? datetime.getUTCMinutes() : datetime.getMinutes()) : null;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
// $function: datetimeMonth
|
|
371
|
+
// $group: Datetime
|
|
372
|
+
// $doc: Get the number of the month (1-12) of a datetime
|
|
373
|
+
// $arg datetime: The datetime
|
|
374
|
+
// $arg utc: Optional (default is false). If true, return the UTC month.
|
|
375
|
+
// $return: The number of the month
|
|
376
|
+
function datetimeMonth([datetime, utc = false]) {
|
|
377
|
+
return datetime instanceof Date ? (utc ? datetime.getUTCMonth() + 1 : datetime.getMonth() + 1) : null;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
|
|
381
|
+
// $function: datetimeNew
|
|
382
|
+
// $group: Datetime
|
|
383
|
+
// $doc: Create a new datetime
|
|
384
|
+
// $arg year: The full year
|
|
385
|
+
// $arg month: The month (1-12)
|
|
386
|
+
// $arg day: The day of the month
|
|
387
|
+
// $arg hours: Optional (default is 0). The hour (0-23)
|
|
388
|
+
// $arg minutes: Optional (default is 0). The number of minutes.
|
|
389
|
+
// $arg seconds: Optional (default is 0). The number of seconds.
|
|
390
|
+
// $arg milliseconds: Optional (default is 0). The number of milliseconds.
|
|
391
|
+
// $return: The new datetime
|
|
392
|
+
function datetimeNew([year, month, day, hours = 0, minutes = 0, seconds = 0, milliseconds = 0]) {
|
|
393
|
+
return new Date(year, month - 1, day, hours, minutes, seconds, milliseconds);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
|
|
397
|
+
// $function: datetimeNewUTC
|
|
398
|
+
// $group: Datetime
|
|
399
|
+
// $doc: Create a new UTC datetime
|
|
400
|
+
// $arg year: The full year
|
|
401
|
+
// $arg month: The month (1-12)
|
|
402
|
+
// $arg day: The day of the month
|
|
403
|
+
// $arg hours: Optional (default is 0). The hour (0-23)
|
|
404
|
+
// $arg minutes: Optional (default is 0). The number of minutes.
|
|
405
|
+
// $arg seconds: Optional (default is 0). The number of seconds.
|
|
406
|
+
// $arg milliseconds: Optional (default is 0). The number of milliseconds.
|
|
407
|
+
// $return: The new UTC datetime
|
|
408
|
+
function datetimeNewUTC([year, month, day, hours = 0, minutes = 0, seconds = 0, milliseconds = 0]) {
|
|
409
|
+
return new Date(Date.UTC(year, month - 1, day, hours, minutes, seconds, milliseconds));
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
|
|
413
|
+
// $function: datetimeNow
|
|
414
|
+
// $group: Datetime
|
|
415
|
+
// $doc: Get the current datetime
|
|
416
|
+
// $return: The current datetime
|
|
417
|
+
function datetimeNow() {
|
|
418
|
+
return new Date();
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
|
|
422
|
+
// $function: datetimeSecond
|
|
423
|
+
// $group: Datetime
|
|
424
|
+
// $doc: Get the number of seconds of a datetime
|
|
425
|
+
// $arg datetime: The datetime
|
|
426
|
+
// $arg utc: Optional (default is false). If true, return the UTC seconds.
|
|
427
|
+
// $return: The number of seconds
|
|
428
|
+
function datetimeSecond([datetime, utc = false]) {
|
|
429
|
+
return datetime instanceof Date ? (utc ? datetime.getUTCSeconds() : datetime.getSeconds()) : null;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
|
|
433
|
+
// $function: datetimeToday
|
|
434
|
+
// $group: Datetime
|
|
435
|
+
// $doc: Get today's datetime
|
|
436
|
+
// $return: Today's datetime
|
|
437
|
+
function datetimeToday() {
|
|
438
|
+
const now = new Date();
|
|
439
|
+
return new Date(now.getFullYear(), now.getMonth(), now.getDate());
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
|
|
443
|
+
// $function: datetimeYear
|
|
444
|
+
// $group: Datetime
|
|
445
|
+
// $doc: Get the full year of a datetime
|
|
446
|
+
// $arg datetime: The datetime
|
|
447
|
+
// $arg utc: Optional (default is false). If true, return the UTC year.
|
|
448
|
+
// $return: The full year
|
|
449
|
+
function datetimeYear([datetime, utc = false]) {
|
|
450
|
+
return datetime instanceof Date ? (utc ? datetime.getUTCFullYear() : datetime.getFullYear()) : null;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
|
|
454
|
+
//
|
|
455
|
+
// JSON functions
|
|
456
|
+
//
|
|
457
|
+
|
|
458
|
+
// $function: jsonParse
|
|
459
|
+
// $group: JSON
|
|
460
|
+
// $doc: Convert a JSON string to an object
|
|
461
|
+
// $arg string: The JSON string
|
|
462
|
+
// $return: The object
|
|
463
|
+
function jsonParse([string]) {
|
|
464
|
+
return JSON.parse(string);
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
|
|
468
|
+
// $function: jsonStringify
|
|
469
|
+
// $group: JSON
|
|
470
|
+
// $doc: Convert an object to a JSON string
|
|
471
|
+
// $arg value: The object
|
|
472
|
+
// $arg space: Optional (default is null). The indentation string or number.
|
|
473
|
+
// $return: The JSON string
|
|
474
|
+
function jsonStringify([value, space]) {
|
|
475
|
+
return jsonStringifySortKeys(value, space);
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
|
|
479
|
+
//
|
|
480
|
+
// Math functions
|
|
481
|
+
//
|
|
482
|
+
|
|
483
|
+
// $function: mathAbs
|
|
484
|
+
// $group: Math
|
|
485
|
+
// $doc: Compute the absolute value of a number
|
|
486
|
+
// $arg x: The number
|
|
487
|
+
// $return: The absolute value of the number
|
|
488
|
+
function mathAbs([x]) {
|
|
489
|
+
return Math.abs(x);
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
|
|
493
|
+
// $function: mathAcos
|
|
494
|
+
// $group: Math
|
|
495
|
+
// $doc: Compute the arccosine, in radians, of a number
|
|
496
|
+
// $arg x: The number
|
|
497
|
+
// $return: The arccosine, in radians, of the number
|
|
498
|
+
function mathAcos([x]) {
|
|
499
|
+
return Math.acos(x);
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
|
|
503
|
+
// $function: mathAsin
|
|
504
|
+
// $group: Math
|
|
505
|
+
// $doc: Compute the arcsine, in radians, of a number
|
|
506
|
+
// $arg x: The number
|
|
507
|
+
// $return: The arcsine, in radians, of the number
|
|
508
|
+
function mathAsin([x]) {
|
|
509
|
+
return Math.asin(x);
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
|
|
513
|
+
// $function: mathAtan
|
|
514
|
+
// $group: Math
|
|
515
|
+
// $doc: Compute the arctangent, in radians, of a number
|
|
516
|
+
// $arg x: The number
|
|
517
|
+
// $return: The arctangent, in radians, of the number
|
|
518
|
+
function mathAtan([x]) {
|
|
519
|
+
return Math.atan(x);
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
|
|
523
|
+
// $function: mathAtan2
|
|
524
|
+
// $group: Math
|
|
525
|
+
// $doc: Compute the angle, in radians, between (0, 0) and a point
|
|
526
|
+
// $arg y: The Y-coordinate of the point
|
|
527
|
+
// $arg x: The X-coordinate of the point
|
|
528
|
+
// $return: The angle, in radians
|
|
529
|
+
function mathAtan2([y, x]) {
|
|
530
|
+
return Math.atan2(y, x);
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
|
|
534
|
+
// $function: mathCeil
|
|
535
|
+
// $group: Math
|
|
536
|
+
// $doc: Compute the ceiling of a number (round up to the next highest integer)
|
|
537
|
+
// $arg x: The number
|
|
538
|
+
// $return: The ceiling of the number
|
|
539
|
+
function mathCeil([x]) {
|
|
540
|
+
return Math.ceil(x);
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
|
|
544
|
+
// $function: mathCos
|
|
545
|
+
// $group: Math
|
|
546
|
+
// $doc: Compute the cosine of an angle, in radians
|
|
547
|
+
// $arg x: The angle, in radians
|
|
548
|
+
// $return: The cosine of the angle
|
|
549
|
+
function mathCos([x]) {
|
|
550
|
+
return Math.cos(x);
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
|
|
554
|
+
// $function: mathFloor
|
|
555
|
+
// $group: Math
|
|
556
|
+
// $doc: Compute the floor of a number (round down to the next lowest integer)
|
|
557
|
+
// $arg x: The number
|
|
558
|
+
// $return: The floor of the number
|
|
559
|
+
function mathFloor([x]) {
|
|
560
|
+
return Math.floor(x);
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
|
|
564
|
+
// $function: mathLn
|
|
565
|
+
// $group: Math
|
|
566
|
+
// $doc: Compute the natural logarithm (base e) of a number
|
|
567
|
+
// $arg x: The number
|
|
568
|
+
// $return: The natural logarithm of the number
|
|
569
|
+
function mathLn([x]) {
|
|
570
|
+
return Math.log(x);
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
|
|
574
|
+
// $function: mathLog
|
|
575
|
+
// $group: Math
|
|
576
|
+
// $doc: Compute the logarithm (base 10) of a number
|
|
577
|
+
// $arg x: The number
|
|
578
|
+
// $arg base: Optional (default is 10). The logarithm base.
|
|
579
|
+
// $return: The logarithm of the number
|
|
580
|
+
function mathLog([x, base = 10]) {
|
|
581
|
+
return Math.log(x) / Math.log(base);
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
|
|
585
|
+
// $function: mathMax
|
|
586
|
+
// $group: Math
|
|
587
|
+
// $doc: Compute the maximum value
|
|
588
|
+
// $arg values...: The values
|
|
589
|
+
// $return: The maximum value
|
|
590
|
+
function mathMax(values) {
|
|
591
|
+
return Math.max(...values);
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
|
|
595
|
+
// $function: mathMin
|
|
596
|
+
// $group: Math
|
|
597
|
+
// $doc: Compute the minimum value
|
|
598
|
+
// $arg values...: The values
|
|
599
|
+
// $return: The minimum value
|
|
600
|
+
function mathMin(values) {
|
|
601
|
+
return Math.min(...values);
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
|
|
605
|
+
// $function: mathPi
|
|
606
|
+
// $group: Math
|
|
607
|
+
// $doc: Return the number pi
|
|
608
|
+
// $return: The number pi
|
|
609
|
+
function mathPi() {
|
|
610
|
+
return Math.PI;
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
|
|
614
|
+
// $function: mathRandom
|
|
615
|
+
// $group: Math
|
|
616
|
+
// $doc: Compute a random number between 0 and 1, inclusive
|
|
617
|
+
// $return: A random number
|
|
618
|
+
function mathRandom() {
|
|
619
|
+
return Math.random();
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
|
|
623
|
+
// $function: mathRound
|
|
624
|
+
// $group: Math
|
|
625
|
+
// $doc: Round a number to a certain number of decimal places
|
|
626
|
+
// $arg x: The number
|
|
627
|
+
// $arg digits: Optional (default is 0). The number of decimal digits to round to.
|
|
628
|
+
// $return: The rounded number
|
|
629
|
+
function mathRound([x, digits = 0]) {
|
|
630
|
+
const multiplier = 10 ** digits;
|
|
631
|
+
return Math.round(x * multiplier) / multiplier;
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
|
|
635
|
+
// $function: mathSign
|
|
636
|
+
// $group: Math
|
|
637
|
+
// $doc: Compute the sign of a number
|
|
638
|
+
// $arg x: The number
|
|
639
|
+
// $return: -1 for a negative number, 1 for a positive number, and 0 for zero
|
|
640
|
+
function mathSign([x]) {
|
|
641
|
+
return Math.sign(x);
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
|
|
645
|
+
// $function: mathSin
|
|
646
|
+
// $group: Math
|
|
647
|
+
// $doc: Compute the sine of an angle, in radians
|
|
648
|
+
// $arg x: The angle, in radians
|
|
649
|
+
// $return: The sine of the angle
|
|
650
|
+
function mathSin([x]) {
|
|
651
|
+
return Math.sin(x);
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
|
|
655
|
+
// $function: mathSqrt
|
|
656
|
+
// $group: Math
|
|
657
|
+
// $doc: Compute the square root of a number
|
|
658
|
+
// $arg x: The number
|
|
659
|
+
// $return: The square root of the number
|
|
660
|
+
function mathSqrt([x]) {
|
|
661
|
+
return Math.sqrt(x);
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
|
|
665
|
+
// $function: mathTan
|
|
666
|
+
// $group: Math
|
|
667
|
+
// $doc: Compute the tangent of an angle, in radians
|
|
668
|
+
// $arg x: The angle, in radians
|
|
669
|
+
// $return: The tangent of the angle
|
|
670
|
+
function mathTan([x]) {
|
|
671
|
+
return Math.tan(x);
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
|
|
675
|
+
//
|
|
676
|
+
// Number functions
|
|
677
|
+
//
|
|
678
|
+
|
|
679
|
+
// $function: numberParseFloat
|
|
680
|
+
// $group: Number
|
|
681
|
+
// $doc: Parse a string as a floating point number
|
|
682
|
+
// $arg string: The string
|
|
683
|
+
// $return: The number
|
|
684
|
+
function numberParseFloat([string]) {
|
|
685
|
+
return Number.parseFloat(string);
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
|
|
689
|
+
// $function: numberParseInt
|
|
690
|
+
// $group: Number
|
|
691
|
+
// $doc: Parse a string as an integer
|
|
692
|
+
// $arg string: The string
|
|
693
|
+
// $arg radix: Optional (default is 10). The number base.
|
|
694
|
+
// $return: The integer
|
|
695
|
+
function numberParseInt([string, radix = 10]) {
|
|
696
|
+
return Number.parseInt(string, radix);
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
|
|
700
|
+
// $function: numberToFixed
|
|
701
|
+
// $group: Number
|
|
702
|
+
// $doc: Format a number using fixed-point notation
|
|
703
|
+
// $arg x: The number
|
|
704
|
+
// $arg digits: Optional (default is 2). The number of digits to appear after the decimal point.
|
|
705
|
+
// $arg trim: Optional (default is false). If true, trim trailing zeroes and decimal point.
|
|
706
|
+
// $return: The fixed-point notation string
|
|
707
|
+
function numberToFixed([x, digits = 2, trim = false]) {
|
|
708
|
+
let result = null;
|
|
709
|
+
if (typeof x === 'number') {
|
|
710
|
+
result = x.toFixed(digits);
|
|
711
|
+
if (trim) {
|
|
712
|
+
result = result.replace(rNumberCleanup, '');
|
|
671
713
|
}
|
|
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
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
714
|
+
}
|
|
715
|
+
return result;
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
const rNumberCleanup = /\.0*$/;
|
|
719
|
+
|
|
720
|
+
|
|
721
|
+
//
|
|
722
|
+
// Object functions
|
|
723
|
+
//
|
|
724
|
+
|
|
725
|
+
// $function: objectAssign
|
|
726
|
+
// $group: Object
|
|
727
|
+
// $doc: Assign the keys/values of one object to another
|
|
728
|
+
// $arg object: The object to assign to
|
|
729
|
+
// $arg object2: The object to assign
|
|
730
|
+
// $return: The updated object
|
|
731
|
+
function objectAssign([object, object2]) {
|
|
732
|
+
if (object !== null && typeof object === 'object' && !Array.isArray(object) &&
|
|
733
|
+
object2 !== null && typeof object2 === 'object' && !Array.isArray(object2)) {
|
|
734
|
+
Object.assign(object, object2);
|
|
735
|
+
}
|
|
736
|
+
return object;
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
|
|
740
|
+
// $function: objectCopy
|
|
741
|
+
// $group: Object
|
|
742
|
+
// $doc: Create a copy of an object
|
|
743
|
+
// $arg object: The object to copy
|
|
744
|
+
// $return: The object copy
|
|
745
|
+
function objectCopy([object]) {
|
|
746
|
+
return (object !== null && typeof object === 'object' && !Array.isArray(object) ? {...object} : {});
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
|
|
750
|
+
// $function: objectDelete
|
|
751
|
+
// $group: Object
|
|
752
|
+
// $doc: Delete an object key
|
|
753
|
+
// $arg object: The object
|
|
754
|
+
// $arg key: The key to delete
|
|
755
|
+
function objectDelete([object, key]) {
|
|
756
|
+
if (object !== null && typeof object === 'object' && !Array.isArray(object)) {
|
|
757
|
+
delete object[key];
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
|
|
762
|
+
// $function: objectGet
|
|
763
|
+
// $group: Object
|
|
764
|
+
// $doc: Get an object key's value
|
|
765
|
+
// $arg object: The object
|
|
766
|
+
// $arg key: The key
|
|
767
|
+
// $arg defaultValue: The default value (optional)
|
|
768
|
+
// $return: The value or null if the key does not exist
|
|
769
|
+
function objectGet([object, key, defaultValue = null]) {
|
|
770
|
+
return object !== null && typeof object === 'object' ? (Object.hasOwn(object, key) ? object[key] : defaultValue) : defaultValue;
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
|
|
774
|
+
// $function: objectHas
|
|
775
|
+
// $group: Object
|
|
776
|
+
// $doc: Test if an object contains a key
|
|
777
|
+
// $arg object: The object
|
|
778
|
+
// $arg key: The key
|
|
779
|
+
// $return: true if the object contains the key, false otherwise
|
|
780
|
+
function objectHas([object, key]) {
|
|
781
|
+
return object !== null && typeof object === 'object' && Object.hasOwn(object, key);
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
|
|
785
|
+
// $function: objectKeys
|
|
786
|
+
// $group: Object
|
|
787
|
+
// $doc: Get an object's keys
|
|
788
|
+
// $arg object: The object
|
|
789
|
+
// $return: The array of keys; null if not an object
|
|
790
|
+
function objectKeys([object]) {
|
|
791
|
+
return object !== null && typeof object === 'object' && !Array.isArray(object) ? Object.keys(object) : null;
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
|
|
795
|
+
// $function: objectNew
|
|
796
|
+
// $group: Object
|
|
797
|
+
// $doc: Create a new object
|
|
798
|
+
// $arg keyValues...: The object's initial key and value pairs
|
|
799
|
+
// $return: The new object
|
|
800
|
+
function objectNew(keyValues) {
|
|
801
|
+
const object = {};
|
|
802
|
+
for (let ix = 0; ix < keyValues.length; ix += 2) {
|
|
803
|
+
object[keyValues[ix]] = (ix + 1 < keyValues.length ? keyValues[ix + 1] : null);
|
|
804
|
+
}
|
|
805
|
+
return object;
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
|
|
809
|
+
// $function: objectSet
|
|
810
|
+
// $group: Object
|
|
811
|
+
// $doc: Set an object key's value
|
|
812
|
+
// $arg object: The object
|
|
813
|
+
// $arg key: The key
|
|
814
|
+
// $arg value: The value to set
|
|
815
|
+
// $return: The value to set
|
|
816
|
+
function objectSet([object, key, value]) {
|
|
817
|
+
if (object !== null && typeof object === 'object' && !Array.isArray(object)) {
|
|
818
|
+
object[key] = value;
|
|
819
|
+
}
|
|
820
|
+
return value;
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
|
|
824
|
+
//
|
|
825
|
+
// Regex functions
|
|
826
|
+
//
|
|
827
|
+
|
|
828
|
+
|
|
829
|
+
// $function: regexEscape
|
|
830
|
+
// $group: Regex
|
|
831
|
+
// $doc: Escape a string for use in a regular expression
|
|
832
|
+
// $arg string: The string to escape
|
|
833
|
+
// $return: The escaped string
|
|
834
|
+
function regexEscape([string]) {
|
|
835
|
+
return typeof string === 'string' ? string.replace(rRegexEscape, '\\$&') : null;
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
const rRegexEscape = /[.*+?^${}()|[\]\\]/g;
|
|
839
|
+
|
|
840
|
+
|
|
841
|
+
// $function: regexMatch
|
|
842
|
+
// $group: Regex
|
|
843
|
+
// $doc: Find the first match of a regular expression in a string
|
|
844
|
+
// $arg regex: The regular expression
|
|
845
|
+
// $arg string: The string
|
|
846
|
+
// $return: The [match object
|
|
847
|
+
// $return: ](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/match#return_value)
|
|
848
|
+
// $return: or null if no matches are found
|
|
849
|
+
function regexMatch([regex, string]) {
|
|
850
|
+
return typeof string === 'string' ? string.match(regex) : null;
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
|
|
854
|
+
// $function: regexMatchAll
|
|
855
|
+
// $group: Regex
|
|
856
|
+
// $doc: Find all matches of regular expression in a string
|
|
857
|
+
// $arg regex: The regular expression
|
|
858
|
+
// $arg string: The string
|
|
859
|
+
// $return: The [match object
|
|
860
|
+
// $return: ](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/match#return_value)
|
|
861
|
+
// $return: array or null if no matches are found
|
|
862
|
+
function regexMatchAll([regex, string]) {
|
|
863
|
+
return typeof string === 'string' ? Array.from(string.matchAll(regex)) : null;
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
|
|
867
|
+
// $function: regexNew
|
|
868
|
+
// $group: Regex
|
|
869
|
+
// $doc: Create a regular expression
|
|
870
|
+
// $arg pattern: The regular expression pattern string
|
|
871
|
+
// $arg flags: The [regular expression flags
|
|
872
|
+
// $arg flags: ](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#advanced_searching_with_flags)
|
|
873
|
+
// $return: The regular expression or null if the pattern is invalid
|
|
874
|
+
function regexNew([pattern, flags]) {
|
|
875
|
+
return new RegExp(pattern, flags);
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
|
|
879
|
+
// $function: regexReplace
|
|
880
|
+
// $group: Regex
|
|
881
|
+
// $doc: Replace regular expression matches with a string
|
|
882
|
+
// $arg regex: The replacement regular expression
|
|
883
|
+
// $arg string: The string
|
|
884
|
+
// $arg substr: The replacement string
|
|
885
|
+
// $return: The updated string
|
|
886
|
+
function regexReplace([regex, string, substr]) {
|
|
887
|
+
if (!(regex instanceof RegExp) || typeof string !== 'string' || typeof substr !== 'string') {
|
|
888
|
+
return null;
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
return string.replace(regex, substr);
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
|
|
895
|
+
// $function: regexSplit
|
|
896
|
+
// $group: Regex
|
|
897
|
+
// $doc: Split a string with a regular expression
|
|
898
|
+
// $arg regex: The regular expression
|
|
899
|
+
// $arg string: The string
|
|
900
|
+
// $return: The array of split parts
|
|
901
|
+
function regexSplit([regex, string]) {
|
|
902
|
+
if (!(regex instanceof RegExp) || typeof string !== 'string') {
|
|
903
|
+
return null;
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
return string.split(regex);
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
// $function: regexTest
|
|
910
|
+
// $group: Regex
|
|
911
|
+
// $doc: Test if a regular expression matches a string
|
|
912
|
+
// $arg regex: The regular expression
|
|
913
|
+
// $arg string: The string
|
|
914
|
+
// $return: true if the regular expression matches, false otherwise
|
|
915
|
+
function regexTest([regex, string]) {
|
|
916
|
+
return regex instanceof RegExp ? regex.test(string) : null;
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
|
|
920
|
+
//
|
|
921
|
+
// Schema functions
|
|
922
|
+
//
|
|
923
|
+
|
|
924
|
+
// $function: schemaParse
|
|
925
|
+
// $group: Schema
|
|
926
|
+
// $doc: Parse the [Schema Markdown](https://craigahobbs.github.io/schema-markdown-js/language/) text
|
|
927
|
+
// $arg lines...: The [Schema Markdown](https://craigahobbs.github.io/schema-markdown-js/language/)
|
|
928
|
+
// $arg lines...: text lines (may contain nested arrays of un-split lines)
|
|
929
|
+
// $return: The schema's [type model](https://craigahobbs.github.io/schema-markdown-doc/doc/#var.vName='Types')
|
|
930
|
+
function schemaParse(lines) {
|
|
931
|
+
return parseSchemaMarkdown(lines);
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
|
|
935
|
+
// $function: schemaParseEx
|
|
936
|
+
// $group: Schema
|
|
937
|
+
// $doc: Parse the [Schema Markdown](https://craigahobbs.github.io/schema-markdown-js/language/) text with options
|
|
938
|
+
// $arg lines: The array of [Schema Markdown](https://craigahobbs.github.io/schema-markdown-js/language/)
|
|
939
|
+
// $arg lines: text lines (may contain nested arrays of un-split lines)
|
|
940
|
+
// $arg types: Optional. The [type model](https://craigahobbs.github.io/schema-markdown-doc/doc/#var.vName='Types').
|
|
941
|
+
// $arg filename: Optional (default is ""). The file name.
|
|
942
|
+
// $return: The schema's [type model](https://craigahobbs.github.io/schema-markdown-doc/doc/#var.vName='Types')
|
|
943
|
+
function schemaParseEx([lines, types = {}, filename = '']) {
|
|
944
|
+
return parseSchemaMarkdown(lines, {types, filename});
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
|
|
948
|
+
// $function: schemaTypeModel
|
|
949
|
+
// $group: Schema
|
|
950
|
+
// $doc: Get the [Schema Markdown Type Model](https://craigahobbs.github.io/schema-markdown-doc/doc/#var.vName='Types')
|
|
951
|
+
// $return: The [Schema Markdown Type Model](https://craigahobbs.github.io/schema-markdown-doc/doc/#var.vName='Types')
|
|
952
|
+
function schemaTypeModel() {
|
|
953
|
+
return typeModel;
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
|
|
957
|
+
// $function: schemaValidate
|
|
958
|
+
// $group: Schema
|
|
959
|
+
// $doc: Validate an object to a schema type
|
|
960
|
+
// $arg types: The [type model](https://craigahobbs.github.io/schema-markdown-doc/doc/#var.vName='Types')
|
|
961
|
+
// $arg typeName: The type name
|
|
962
|
+
// $arg value: The object to validate
|
|
963
|
+
// $return: The validated object or null if validation fails
|
|
964
|
+
function schemaValidate([types, typeName, value]) {
|
|
965
|
+
return validateType(types, typeName, value);
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
|
|
969
|
+
// $function: schemaValidateTypeModel
|
|
970
|
+
// $group: Schema
|
|
971
|
+
// $doc: Validate a [Schema Markdown Type Model](https://craigahobbs.github.io/schema-markdown-doc/doc/#var.vName='Types')
|
|
972
|
+
// $arg types: The [type model](https://craigahobbs.github.io/schema-markdown-doc/doc/#var.vName='Types') to validate
|
|
973
|
+
// $return: The validated [type model](https://craigahobbs.github.io/schema-markdown-doc/doc/#var.vName='Types')
|
|
974
|
+
function schemaValidateTypeModel([types]) {
|
|
975
|
+
return validateTypeModel(types);
|
|
976
|
+
}
|
|
977
|
+
|
|
978
|
+
|
|
979
|
+
//
|
|
980
|
+
// String functions
|
|
981
|
+
//
|
|
982
|
+
|
|
983
|
+
|
|
984
|
+
// $function: stringCharCodeAt
|
|
985
|
+
// $group: String
|
|
986
|
+
// $doc: Get a string index's character code
|
|
987
|
+
// $arg string: The string
|
|
988
|
+
// $arg index: The character index
|
|
989
|
+
// $return: The character code
|
|
990
|
+
function stringCharCodeAt([string, index]) {
|
|
991
|
+
return typeof string === 'string' ? string.charCodeAt(index) : null;
|
|
992
|
+
}
|
|
993
|
+
|
|
994
|
+
|
|
995
|
+
// $function: stringEndsWith
|
|
996
|
+
// $group: String
|
|
997
|
+
// $doc: Determine if a string ends with a search string
|
|
998
|
+
// $arg string: The string
|
|
999
|
+
// $arg searchString: The search string
|
|
1000
|
+
// $return: true if the string ends with the search string, false otherwise
|
|
1001
|
+
function stringEndsWith([string, searchString]) {
|
|
1002
|
+
return typeof string === 'string' ? string.endsWith(searchString) : null;
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1005
|
+
|
|
1006
|
+
// $function: stringFromCharCode
|
|
1007
|
+
// $group: String
|
|
1008
|
+
// $doc: Create a string of characters from character codes
|
|
1009
|
+
// $arg charCodes...: The character codes
|
|
1010
|
+
// $return: The string of characters
|
|
1011
|
+
function stringFromCharCode(charCodes) {
|
|
1012
|
+
return String.fromCharCode(...charCodes);
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
|
|
1016
|
+
// $function: stringIndexOf
|
|
1017
|
+
// $group: String
|
|
1018
|
+
// $doc: Find the first index of a search string in a string
|
|
1019
|
+
// $arg string: The string
|
|
1020
|
+
// $arg searchString: The search string
|
|
1021
|
+
// $arg index: Optional (default is 0). The index at which to start the search.
|
|
1022
|
+
// $return: The first index of the search string; -1 if not found.
|
|
1023
|
+
function stringIndexOf([string, searchString, index]) {
|
|
1024
|
+
return typeof string === 'string' ? string.indexOf(searchString, index) : -1;
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
|
|
1028
|
+
// $function: stringLastIndexOf
|
|
1029
|
+
// $group: String
|
|
1030
|
+
// $doc: Find the last index of a search string in a string
|
|
1031
|
+
// $arg string: The string
|
|
1032
|
+
// $arg searchString: The search string
|
|
1033
|
+
// $arg index: Optional (default is the end of the string). The index at which to start the search.
|
|
1034
|
+
// $return: The last index of the search string; -1 if not found.
|
|
1035
|
+
function stringLastIndexOf([string, searchString, index]) {
|
|
1036
|
+
return typeof string === 'string' ? string.lastIndexOf(searchString, index) : -1;
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
|
|
1040
|
+
// $function: stringLength
|
|
1041
|
+
// $group: String
|
|
1042
|
+
// $doc: Get the length of a string
|
|
1043
|
+
// $arg string: The string
|
|
1044
|
+
// $return: The string's length; null if not a string
|
|
1045
|
+
function stringLength([string]) {
|
|
1046
|
+
return typeof string === 'string' ? string.length : null;
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1049
|
+
|
|
1050
|
+
// $function: stringLower
|
|
1051
|
+
// $group: String
|
|
1052
|
+
// $doc: Convert a string to lower-case
|
|
1053
|
+
// $arg string: The string
|
|
1054
|
+
// $return: The lower-case string
|
|
1055
|
+
function stringLower([string]) {
|
|
1056
|
+
return typeof string === 'string' ? string.toLowerCase() : null;
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
|
|
1060
|
+
// $function: stringNew
|
|
1061
|
+
// $group: String
|
|
1062
|
+
// $doc: Create a new string from a value
|
|
1063
|
+
// $arg value: The value
|
|
1064
|
+
// $return: The new string
|
|
1065
|
+
function stringNew([value]) {
|
|
1066
|
+
return `${value}`;
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1069
|
+
|
|
1070
|
+
// $function: stringRepeat
|
|
1071
|
+
// $group: String
|
|
1072
|
+
// $doc: Repeat a string
|
|
1073
|
+
// $arg string: The string to repeat
|
|
1074
|
+
// $arg count: The number of times to repeat the string
|
|
1075
|
+
// $return: The repeated string
|
|
1076
|
+
function stringRepeat([string, count]) {
|
|
1077
|
+
return typeof string === 'string' ? string.repeat(count) : null;
|
|
1078
|
+
}
|
|
1079
|
+
|
|
1080
|
+
|
|
1081
|
+
// $function: stringReplace
|
|
1082
|
+
// $group: String
|
|
1083
|
+
// $doc: Replace all instances of a string with another string
|
|
1084
|
+
// $arg string: The string to update
|
|
1085
|
+
// $arg substr: The string to replace
|
|
1086
|
+
// $arg newSubstr: The replacement string
|
|
1087
|
+
// $return: The updated string
|
|
1088
|
+
function stringReplace([string, substr, newSubstr], options) {
|
|
1089
|
+
if (typeof string !== 'string') {
|
|
1090
|
+
return null;
|
|
1091
|
+
}
|
|
1092
|
+
if (typeof newSubstr === 'function') {
|
|
1093
|
+
const replacerFunction = (...args) => newSubstr(args, options);
|
|
1094
|
+
return string.replaceAll(substr, replacerFunction);
|
|
1095
|
+
}
|
|
1096
|
+
return string.replaceAll(substr, newSubstr);
|
|
1097
|
+
}
|
|
1098
|
+
|
|
1099
|
+
|
|
1100
|
+
// $function: stringSlice
|
|
1101
|
+
// $group: String
|
|
1102
|
+
// $doc: Copy a portion of a string
|
|
1103
|
+
// $arg string: The string
|
|
1104
|
+
// $arg start: Optional (default is 0). The start index of the slice.
|
|
1105
|
+
// $arg end: Optional (default is the end of the string). The end index of the slice.
|
|
1106
|
+
// $return: The new string slice
|
|
1107
|
+
function stringSlice([string, beginIndex, endIndex]) {
|
|
1108
|
+
return typeof string === 'string' ? string.slice(beginIndex, endIndex) : null;
|
|
1109
|
+
}
|
|
1110
|
+
|
|
1111
|
+
|
|
1112
|
+
// $function: stringSplit
|
|
1113
|
+
// $group: String
|
|
1114
|
+
// $doc: Split a string
|
|
1115
|
+
// $arg string: The string to split
|
|
1116
|
+
// $arg separator: The separator string or regular expression
|
|
1117
|
+
// $arg limit: The maximum number of strings to split into
|
|
1118
|
+
// $return: The array of split-out strings
|
|
1119
|
+
function stringSplit([string, separator, limit]) {
|
|
1120
|
+
return typeof string === 'string' ? string.split(separator, limit) : null;
|
|
1121
|
+
}
|
|
1122
|
+
|
|
1123
|
+
|
|
1124
|
+
// $function: stringStartsWith
|
|
1125
|
+
// $group: String
|
|
1126
|
+
// $doc: Determine if a string starts with a search string
|
|
1127
|
+
// $arg string: The string
|
|
1128
|
+
// $arg searchString: The search string
|
|
1129
|
+
// $return: true if the string starts with the search string, false otherwise
|
|
1130
|
+
function stringStartsWith([string, searchString]) {
|
|
1131
|
+
return typeof string === 'string' ? string.startsWith(searchString) : null;
|
|
1132
|
+
}
|
|
1133
|
+
|
|
1134
|
+
|
|
1135
|
+
// $function: stringTrim
|
|
1136
|
+
// $group: String
|
|
1137
|
+
// $doc: Trim the whitespace from the beginning and end of a string
|
|
1138
|
+
// $arg string: The string
|
|
1139
|
+
// $return: The trimmed string
|
|
1140
|
+
function stringTrim([string]) {
|
|
1141
|
+
return typeof string === 'string' ? string.trim() : null;
|
|
1142
|
+
}
|
|
1143
|
+
|
|
1144
|
+
|
|
1145
|
+
// $function: stringUpper
|
|
1146
|
+
// $group: String
|
|
1147
|
+
// $doc: Convert a string to upper-case
|
|
1148
|
+
// $arg string: The string
|
|
1149
|
+
// $return: The upper-case string
|
|
1150
|
+
function stringUpper([string]) {
|
|
1151
|
+
return typeof string === 'string' ? string.toUpperCase() : null;
|
|
1152
|
+
}
|
|
1153
|
+
|
|
1154
|
+
|
|
1155
|
+
//
|
|
1156
|
+
// System functions
|
|
1157
|
+
//
|
|
1158
|
+
|
|
1159
|
+
|
|
1160
|
+
// $function: systemFetch
|
|
1161
|
+
// $group: System
|
|
1162
|
+
// $doc: Retrieve a remote JSON or text resource
|
|
1163
|
+
// $arg url: The resource URL or array of URLs
|
|
1164
|
+
// $arg options: Optional (default is null). The [fetch options](https://developer.mozilla.org/en-US/docs/Web/API/fetch#parameters).
|
|
1165
|
+
// $arg isText: Optional (default is false). If true, retrieve the resource as text.
|
|
1166
|
+
// $return: The resource object/string or array of objects/strings; null if an error occurred.
|
|
1167
|
+
async function systemFetch([url, fetchOptions = null, isText = false], options) {
|
|
1168
|
+
const isArray = Array.isArray(url);
|
|
1169
|
+
const urls = (isArray ? url : [url]).map((mURL) => (options !== null && 'urlFn' in options ? options.urlFn(mURL) : mURL));
|
|
1170
|
+
const responses = await Promise.all(urls.map(async (fURL) => {
|
|
1171
|
+
try {
|
|
1172
|
+
return 'fetchFn' in options ? await (fetchOptions ? options.fetchFn(fURL, fetchOptions) : options.fetchFn(fURL)) : null;
|
|
1173
|
+
} catch {
|
|
853
1174
|
return null;
|
|
854
1175
|
}
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
// $function: stringSlice
|
|
863
|
-
// $group: String
|
|
864
|
-
// $doc: Copy a portion of a string
|
|
865
|
-
// $arg string: The string
|
|
866
|
-
// $arg start: Optional (default is 0). The start index of the slice.
|
|
867
|
-
// $arg end: Optional (default is the end of the string). The end index of the slice.
|
|
868
|
-
// $return: The new string slice
|
|
869
|
-
'stringSlice': ([string, beginIndex, endIndex]) => (typeof string === 'string' ? string.slice(beginIndex, endIndex) : null),
|
|
870
|
-
|
|
871
|
-
// $function: stringSplit
|
|
872
|
-
// $group: String
|
|
873
|
-
// $doc: Split a string
|
|
874
|
-
// $arg string: The string to split
|
|
875
|
-
// $arg separator: The separator string or regular expression
|
|
876
|
-
// $arg limit: The maximum number of strings to split into
|
|
877
|
-
// $return: The array of split-out strings
|
|
878
|
-
'stringSplit': ([string, separator, limit]) => (typeof string === 'string' ? string.split(separator, limit) : null),
|
|
879
|
-
|
|
880
|
-
// $function: stringStartsWith
|
|
881
|
-
// $group: String
|
|
882
|
-
// $doc: Determine if a string starts with a search string
|
|
883
|
-
// $arg string: The string
|
|
884
|
-
// $arg searchString: The search string
|
|
885
|
-
// $return: true if the string starts with the search string, false otherwise
|
|
886
|
-
'stringStartsWith': ([string, searchString]) => (typeof string === 'string' ? string.startsWith(searchString) : null),
|
|
887
|
-
|
|
888
|
-
// $function: stringTrim
|
|
889
|
-
// $group: String
|
|
890
|
-
// $doc: Trim the whitespace from the beginning and end of a string
|
|
891
|
-
// $arg string: The string
|
|
892
|
-
// $return: The trimmed string
|
|
893
|
-
'stringTrim': ([string]) => (typeof string === 'string' ? string.trim() : null),
|
|
894
|
-
|
|
895
|
-
// $function: stringUpper
|
|
896
|
-
// $group: String
|
|
897
|
-
// $doc: Convert a string to upper-case
|
|
898
|
-
// $arg string: The string
|
|
899
|
-
// $return: The upper-case string
|
|
900
|
-
'stringUpper': ([string]) => (typeof string === 'string' ? string.toUpperCase() : null),
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
//
|
|
904
|
-
// System functions
|
|
905
|
-
//
|
|
906
|
-
|
|
907
|
-
// $function: systemFetch
|
|
908
|
-
// $group: System
|
|
909
|
-
// $doc: Retrieve a remote JSON or text resource
|
|
910
|
-
// $arg url: The resource URL or array of URLs
|
|
911
|
-
// $arg options: Optional (default is null). The [fetch options](https://developer.mozilla.org/en-US/docs/Web/API/fetch#parameters).
|
|
912
|
-
// $arg isText: Optional (default is false). If true, retrieve the resource as text.
|
|
913
|
-
// $return: The resource object/string or array of objects/strings; null if an error occurred.
|
|
914
|
-
'systemFetch': async ([url, fetchOptions = null, isText = false], options) => {
|
|
915
|
-
const isArray = Array.isArray(url);
|
|
916
|
-
const urls = (isArray ? url : [url]).map((mURL) => (options !== null && 'urlFn' in options ? options.urlFn(mURL) : mURL));
|
|
917
|
-
const responses = await Promise.all(urls.map(async (fURL) => {
|
|
918
|
-
try {
|
|
919
|
-
return 'fetchFn' in options ? await (fetchOptions ? options.fetchFn(fURL, fetchOptions) : options.fetchFn(fURL)) : null;
|
|
920
|
-
} catch {
|
|
921
|
-
return null;
|
|
922
|
-
}
|
|
923
|
-
}));
|
|
924
|
-
const values = await Promise.all(responses.map(async (response) => {
|
|
925
|
-
try {
|
|
926
|
-
return response !== null && response.ok ? await (isText ? response.text() : response.json()) : null;
|
|
927
|
-
} catch {
|
|
928
|
-
return null;
|
|
929
|
-
}
|
|
930
|
-
}));
|
|
931
|
-
|
|
932
|
-
// Log failures
|
|
933
|
-
for (const [ixValue, value] of values.entries()) {
|
|
934
|
-
if (value === null && options !== null && 'logFn' in options && options.debug) {
|
|
935
|
-
const errorURL = urls[ixValue];
|
|
936
|
-
options.logFn(`BareScript: Function "systemFetch" failed for ${isText ? 'text' : 'JSON'} resource "${errorURL}"`);
|
|
937
|
-
}
|
|
1176
|
+
}));
|
|
1177
|
+
const values = await Promise.all(responses.map(async (response) => {
|
|
1178
|
+
try {
|
|
1179
|
+
return response !== null && response.ok ? await (isText ? response.text() : response.json()) : null;
|
|
1180
|
+
} catch {
|
|
1181
|
+
return null;
|
|
938
1182
|
}
|
|
1183
|
+
}));
|
|
939
1184
|
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
// $doc: Get a global variable value
|
|
946
|
-
// $arg name: The global variable name
|
|
947
|
-
// $return: The global variable's value or null if it does not exist
|
|
948
|
-
'systemGlobalGet': ([name], options) => {
|
|
949
|
-
const globals = (options !== null ? (options.globals ?? null) : null);
|
|
950
|
-
return (globals !== null ? (globals[name] ?? null) : null);
|
|
951
|
-
},
|
|
952
|
-
|
|
953
|
-
// $function: systemGlobalSet
|
|
954
|
-
// $group: System
|
|
955
|
-
// $doc: Set a global variable value
|
|
956
|
-
// $arg name: The global variable name
|
|
957
|
-
// $arg value: The global variable's value
|
|
958
|
-
// $return: The global variable's value
|
|
959
|
-
'systemGlobalSet': ([name, value], options) => {
|
|
960
|
-
if (options !== null) {
|
|
961
|
-
const globals = options.globals ?? null;
|
|
962
|
-
if (globals !== null) {
|
|
963
|
-
globals[name] = value;
|
|
964
|
-
}
|
|
965
|
-
}
|
|
966
|
-
return value;
|
|
967
|
-
},
|
|
968
|
-
|
|
969
|
-
// $function: systemLog
|
|
970
|
-
// $group: System
|
|
971
|
-
// $doc: Log a message to the console
|
|
972
|
-
// $arg string: The message
|
|
973
|
-
'systemLog': ([string], options) => {
|
|
974
|
-
if (options !== null && 'logFn' in options) {
|
|
975
|
-
options.logFn(string);
|
|
976
|
-
}
|
|
977
|
-
},
|
|
978
|
-
|
|
979
|
-
// $function: systemLogDebug
|
|
980
|
-
// $group: System
|
|
981
|
-
// $doc: Log a message to the console, if in debug mode
|
|
982
|
-
// $arg string: The message
|
|
983
|
-
'systemLogDebug': ([string], options) => {
|
|
984
|
-
if (options !== null && 'logFn' in options && options.debug) {
|
|
985
|
-
options.logFn(string);
|
|
1185
|
+
// Log failures
|
|
1186
|
+
for (const [ixValue, value] of values.entries()) {
|
|
1187
|
+
if (value === null && options !== null && 'logFn' in options && options.debug) {
|
|
1188
|
+
const errorURL = urls[ixValue];
|
|
1189
|
+
options.logFn(`BareScript: Function "systemFetch" failed for ${isText ? 'text' : 'JSON'} resource "${errorURL}"`);
|
|
986
1190
|
}
|
|
987
|
-
}
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
}
|
|
1016
|
-
}
|
|
1017
|
-
return type;
|
|
1018
|
-
},
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
//
|
|
1022
|
-
// URL functions
|
|
1023
|
-
//
|
|
1024
|
-
|
|
1025
|
-
// $function: urlEncode
|
|
1026
|
-
// $group: URL
|
|
1027
|
-
// $doc: Encode a URL
|
|
1028
|
-
// $arg url: The URL string
|
|
1029
|
-
// $arg extra: Optional (default is true). If true, encode extra characters for wider compatibility.
|
|
1030
|
-
// $return: The encoded URL string
|
|
1031
|
-
'urlEncode': ([url, extra = true]) => {
|
|
1032
|
-
let urlEncoded = encodeURI(url);
|
|
1033
|
-
if (extra) {
|
|
1034
|
-
// Replace ')' with '%29' for Markdown links
|
|
1035
|
-
urlEncoded = urlEncoded.replaceAll(')', '%29');
|
|
1036
|
-
}
|
|
1037
|
-
return urlEncoded;
|
|
1038
|
-
},
|
|
1039
|
-
|
|
1040
|
-
// $function: urlEncodeComponent
|
|
1041
|
-
// $group: URL
|
|
1042
|
-
// $doc: Encode a URL component
|
|
1043
|
-
// $arg url: The URL component string
|
|
1044
|
-
// $arg extra: Optional (default is true). If true, encode extra characters for wider compatibility.
|
|
1045
|
-
// $return: The encoded URL component string
|
|
1046
|
-
'urlEncodeComponent': ([urlComponent, extra = true]) => {
|
|
1047
|
-
let urlComponentEncoded = encodeURIComponent(urlComponent);
|
|
1048
|
-
if (extra) {
|
|
1049
|
-
// Replace ')' with '%29' for Markdown links
|
|
1050
|
-
urlComponentEncoded = urlComponentEncoded.replaceAll(')', '%29');
|
|
1191
|
+
}
|
|
1192
|
+
|
|
1193
|
+
return isArray ? values : values[0];
|
|
1194
|
+
}
|
|
1195
|
+
|
|
1196
|
+
|
|
1197
|
+
// $function: systemGlobalGet
|
|
1198
|
+
// $group: System
|
|
1199
|
+
// $doc: Get a global variable value
|
|
1200
|
+
// $arg name: The global variable name
|
|
1201
|
+
// $return: The global variable's value or null if it does not exist
|
|
1202
|
+
function systemGlobalGet([name], options) {
|
|
1203
|
+
const globals = (options !== null ? (options.globals ?? null) : null);
|
|
1204
|
+
return (globals !== null ? (globals[name] ?? null) : null);
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1207
|
+
|
|
1208
|
+
// $function: systemGlobalSet
|
|
1209
|
+
// $group: System
|
|
1210
|
+
// $doc: Set a global variable value
|
|
1211
|
+
// $arg name: The global variable name
|
|
1212
|
+
// $arg value: The global variable's value
|
|
1213
|
+
// $return: The global variable's value
|
|
1214
|
+
function systemGlobalSet([name, value], options) {
|
|
1215
|
+
if (options !== null) {
|
|
1216
|
+
const globals = options.globals ?? null;
|
|
1217
|
+
if (globals !== null) {
|
|
1218
|
+
globals[name] = value;
|
|
1051
1219
|
}
|
|
1052
|
-
return urlComponentEncoded;
|
|
1053
1220
|
}
|
|
1054
|
-
|
|
1221
|
+
return value;
|
|
1222
|
+
}
|
|
1055
1223
|
|
|
1056
1224
|
|
|
1057
|
-
//
|
|
1058
|
-
|
|
1225
|
+
// $function: systemLog
|
|
1226
|
+
// $group: System
|
|
1227
|
+
// $doc: Log a message to the console
|
|
1228
|
+
// $arg string: The message
|
|
1229
|
+
function systemLog([string], options) {
|
|
1230
|
+
if (options !== null && 'logFn' in options) {
|
|
1231
|
+
options.logFn(string);
|
|
1232
|
+
}
|
|
1233
|
+
}
|
|
1059
1234
|
|
|
1060
1235
|
|
|
1061
|
-
//
|
|
1062
|
-
|
|
1236
|
+
// $function: systemLogDebug
|
|
1237
|
+
// $group: System
|
|
1238
|
+
// $doc: Log a message to the console, if in debug mode
|
|
1239
|
+
// $arg string: The message
|
|
1240
|
+
function systemLogDebug([string], options) {
|
|
1241
|
+
if (options !== null && 'logFn' in options && options.debug) {
|
|
1242
|
+
options.logFn(string);
|
|
1243
|
+
}
|
|
1244
|
+
}
|
|
1245
|
+
|
|
1246
|
+
|
|
1247
|
+
// $function: systemPartial
|
|
1248
|
+
// $group: System
|
|
1249
|
+
// $doc: Return a new function which behaves like "func" called with "args".
|
|
1250
|
+
// $doc: If additional arguments are passed to the returned function, they are appended to "args".
|
|
1251
|
+
// $arg func: The function
|
|
1252
|
+
// $arg args...: The function arguments
|
|
1253
|
+
// $return: The new function called with "args"
|
|
1254
|
+
function systemPartial([func, ...args]) {
|
|
1255
|
+
return (argsExtra, options) => func([...args, ...argsExtra], options);
|
|
1256
|
+
}
|
|
1257
|
+
|
|
1258
|
+
|
|
1259
|
+
// $function: systemType
|
|
1260
|
+
// $group: System
|
|
1261
|
+
// $doc: Get a value's type string
|
|
1262
|
+
// $arg value: The value
|
|
1263
|
+
// $return: The type string of the value.
|
|
1264
|
+
// $return: Valid values are: 'array', 'boolean', 'datetime', 'function', 'null', 'number', 'object', 'regex', 'string'.
|
|
1265
|
+
function systemType([value]) {
|
|
1266
|
+
const type = typeof value;
|
|
1267
|
+
if (type === 'object') {
|
|
1268
|
+
if (value === null) {
|
|
1269
|
+
return 'null';
|
|
1270
|
+
} else if (Array.isArray(value)) {
|
|
1271
|
+
return 'array';
|
|
1272
|
+
} else if (value instanceof Date) {
|
|
1273
|
+
return 'datetime';
|
|
1274
|
+
} else if (value instanceof RegExp) {
|
|
1275
|
+
return 'regex';
|
|
1276
|
+
}
|
|
1277
|
+
}
|
|
1278
|
+
return type;
|
|
1279
|
+
}
|
|
1280
|
+
|
|
1281
|
+
|
|
1282
|
+
//
|
|
1283
|
+
// URL functions
|
|
1284
|
+
//
|
|
1285
|
+
|
|
1286
|
+
|
|
1287
|
+
// $function: urlEncode
|
|
1288
|
+
// $group: URL
|
|
1289
|
+
// $doc: Encode a URL
|
|
1290
|
+
// $arg url: The URL string
|
|
1291
|
+
// $arg extra: Optional (default is true). If true, encode extra characters for wider compatibility.
|
|
1292
|
+
// $return: The encoded URL string
|
|
1293
|
+
function urlEncode([url, extra = true]) {
|
|
1294
|
+
let urlEncoded = encodeURI(url);
|
|
1295
|
+
if (extra) {
|
|
1296
|
+
// Replace ')' with '%29' for Markdown links
|
|
1297
|
+
urlEncoded = urlEncoded.replaceAll(')', '%29');
|
|
1298
|
+
}
|
|
1299
|
+
return urlEncoded;
|
|
1300
|
+
}
|
|
1301
|
+
|
|
1302
|
+
|
|
1303
|
+
// $function: urlEncodeComponent
|
|
1304
|
+
// $group: URL
|
|
1305
|
+
// $doc: Encode a URL component
|
|
1306
|
+
// $arg url: The URL component string
|
|
1307
|
+
// $arg extra: Optional (default is true). If true, encode extra characters for wider compatibility.
|
|
1308
|
+
// $return: The encoded URL component string
|
|
1309
|
+
function urlEncodeComponent([urlComponent, extra = true]) {
|
|
1310
|
+
let urlComponentEncoded = encodeURIComponent(urlComponent);
|
|
1311
|
+
if (extra) {
|
|
1312
|
+
// Replace ')' with '%29' for Markdown links
|
|
1313
|
+
urlComponentEncoded = urlComponentEncoded.replaceAll(')', '%29');
|
|
1314
|
+
}
|
|
1315
|
+
return urlComponentEncoded;
|
|
1316
|
+
}
|
|
1317
|
+
|
|
1318
|
+
|
|
1319
|
+
// The built-in script functions
|
|
1320
|
+
export const scriptFunctions = {
|
|
1321
|
+
arrayCopy,
|
|
1322
|
+
arrayExtend,
|
|
1323
|
+
arrayGet,
|
|
1324
|
+
arrayIndexOf,
|
|
1325
|
+
arrayJoin,
|
|
1326
|
+
arrayLastIndexOf,
|
|
1327
|
+
arrayLength,
|
|
1328
|
+
arrayNew,
|
|
1329
|
+
arrayNewSize,
|
|
1330
|
+
arrayPop,
|
|
1331
|
+
arrayPush,
|
|
1332
|
+
arraySet,
|
|
1333
|
+
arrayShift,
|
|
1334
|
+
arraySlice,
|
|
1335
|
+
arraySort,
|
|
1336
|
+
dataAggregate,
|
|
1337
|
+
dataCalculatedField,
|
|
1338
|
+
dataFilter,
|
|
1339
|
+
dataJoin,
|
|
1340
|
+
dataParseCSV,
|
|
1341
|
+
dataSort,
|
|
1342
|
+
dataTop,
|
|
1343
|
+
dataValidate,
|
|
1344
|
+
datetimeDay,
|
|
1345
|
+
datetimeHour,
|
|
1346
|
+
datetimeISOFormat,
|
|
1347
|
+
datetimeISOParse,
|
|
1348
|
+
datetimeMinute,
|
|
1349
|
+
datetimeMonth,
|
|
1350
|
+
datetimeNew,
|
|
1351
|
+
datetimeNewUTC,
|
|
1352
|
+
datetimeNow,
|
|
1353
|
+
datetimeSecond,
|
|
1354
|
+
datetimeToday,
|
|
1355
|
+
datetimeYear,
|
|
1356
|
+
jsonParse,
|
|
1357
|
+
jsonStringify,
|
|
1358
|
+
mathAbs,
|
|
1359
|
+
mathAcos,
|
|
1360
|
+
mathAsin,
|
|
1361
|
+
mathAtan,
|
|
1362
|
+
mathAtan2,
|
|
1363
|
+
mathCeil,
|
|
1364
|
+
mathCos,
|
|
1365
|
+
mathFloor,
|
|
1366
|
+
mathLn,
|
|
1367
|
+
mathLog,
|
|
1368
|
+
mathMax,
|
|
1369
|
+
mathMin,
|
|
1370
|
+
mathPi,
|
|
1371
|
+
mathRandom,
|
|
1372
|
+
mathRound,
|
|
1373
|
+
mathSign,
|
|
1374
|
+
mathSin,
|
|
1375
|
+
mathSqrt,
|
|
1376
|
+
mathTan,
|
|
1377
|
+
numberParseFloat,
|
|
1378
|
+
numberParseInt,
|
|
1379
|
+
numberToFixed,
|
|
1380
|
+
objectAssign,
|
|
1381
|
+
objectCopy,
|
|
1382
|
+
objectDelete,
|
|
1383
|
+
objectGet,
|
|
1384
|
+
objectHas,
|
|
1385
|
+
objectKeys,
|
|
1386
|
+
objectNew,
|
|
1387
|
+
objectSet,
|
|
1388
|
+
regexEscape,
|
|
1389
|
+
regexMatch,
|
|
1390
|
+
regexMatchAll,
|
|
1391
|
+
regexNew,
|
|
1392
|
+
regexReplace,
|
|
1393
|
+
regexSplit,
|
|
1394
|
+
regexTest,
|
|
1395
|
+
schemaParse,
|
|
1396
|
+
schemaParseEx,
|
|
1397
|
+
schemaTypeModel,
|
|
1398
|
+
schemaValidate,
|
|
1399
|
+
schemaValidateTypeModel,
|
|
1400
|
+
stringCharCodeAt,
|
|
1401
|
+
stringEndsWith,
|
|
1402
|
+
stringFromCharCode,
|
|
1403
|
+
stringIndexOf,
|
|
1404
|
+
stringLastIndexOf,
|
|
1405
|
+
stringLength,
|
|
1406
|
+
stringLower,
|
|
1407
|
+
stringNew,
|
|
1408
|
+
stringRepeat,
|
|
1409
|
+
stringReplace,
|
|
1410
|
+
stringSlice,
|
|
1411
|
+
stringSplit,
|
|
1412
|
+
stringStartsWith,
|
|
1413
|
+
stringTrim,
|
|
1414
|
+
stringUpper,
|
|
1415
|
+
systemFetch,
|
|
1416
|
+
systemGlobalGet,
|
|
1417
|
+
systemGlobalSet,
|
|
1418
|
+
systemLog,
|
|
1419
|
+
systemLogDebug,
|
|
1420
|
+
systemPartial,
|
|
1421
|
+
systemType,
|
|
1422
|
+
urlEncode,
|
|
1423
|
+
urlEncodeComponent,
|
|
1424
|
+
};
|
|
1063
1425
|
|
|
1064
1426
|
|
|
1065
1427
|
// The built-in expression function name script function name map
|