bare-script 3.0.4 → 3.0.6
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/data.js +1 -1
- package/lib/library.js +672 -466
- package/lib/runtime.js +4 -1
- package/lib/runtimeAsync.js +4 -1
- package/lib/value.js +223 -0
- package/package.json +1 -1
package/lib/library.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
// Licensed under the MIT License
|
|
2
2
|
// https://github.com/craigahobbs/bare-script/blob/main/LICENSE
|
|
3
3
|
|
|
4
|
+
import {
|
|
5
|
+
ValueArgsError, valueArgsModel, valueArgsValidate, valueBoolean, valueCompare, valueIs, valueJSON,
|
|
6
|
+
valueParseDatetime, valueParseInteger, valueParseNumber, valueRoundNumber, valueString, valueType
|
|
7
|
+
} from './value.js';
|
|
4
8
|
import {
|
|
5
9
|
addCalculatedField, aggregateData, filterData, joinData, parseCSV, sortData, topData, validateData
|
|
6
10
|
} from './data.js';
|
|
7
11
|
import {validateType, validateTypeModel} from 'schema-markdown/lib/schema.js';
|
|
8
|
-
import {
|
|
9
|
-
valueBoolean, valueCompare, valueIs, valueJSON, valueParseDatetime, valueParseInteger, valueParseNumber, valueString, valueType
|
|
10
|
-
} from './value.js';
|
|
11
12
|
import {parseSchemaMarkdown} from 'schema-markdown/lib/parser.js';
|
|
12
13
|
import {typeModel} from 'schema-markdown/lib/typeModel.js';
|
|
13
14
|
|
|
@@ -29,14 +30,15 @@ export const defaultMaxStatements = 1e9;
|
|
|
29
30
|
// $doc: Create a copy of an array
|
|
30
31
|
// $arg array: The array to copy
|
|
31
32
|
// $return: The array copy
|
|
32
|
-
function arrayCopy(
|
|
33
|
-
|
|
34
|
-
return null;
|
|
35
|
-
}
|
|
36
|
-
|
|
33
|
+
function arrayCopy(args) {
|
|
34
|
+
const [array] = valueArgsValidate(arrayCopyArgs, args);
|
|
37
35
|
return [...array];
|
|
38
36
|
}
|
|
39
37
|
|
|
38
|
+
const arrayCopyArgs = valueArgsModel([
|
|
39
|
+
{'name': 'array', 'type': 'array'}
|
|
40
|
+
]);
|
|
41
|
+
|
|
40
42
|
|
|
41
43
|
// $function: arrayExtend
|
|
42
44
|
// $group: Array
|
|
@@ -44,15 +46,17 @@ function arrayCopy([array = null]) {
|
|
|
44
46
|
// $arg array: The array to extend
|
|
45
47
|
// $arg array2: The array to extend with
|
|
46
48
|
// $return: The extended array
|
|
47
|
-
function arrayExtend(
|
|
48
|
-
|
|
49
|
-
return null;
|
|
50
|
-
}
|
|
51
|
-
|
|
49
|
+
function arrayExtend(args) {
|
|
50
|
+
const [array, array2] = valueArgsValidate(arrayExtendArgs, args);
|
|
52
51
|
array.push(...array2);
|
|
53
52
|
return array;
|
|
54
53
|
}
|
|
55
54
|
|
|
55
|
+
const arrayExtendArgs = valueArgsModel([
|
|
56
|
+
{'name': 'array', 'type': 'array'},
|
|
57
|
+
{'name': 'array2', 'type': 'array'}
|
|
58
|
+
]);
|
|
59
|
+
|
|
56
60
|
|
|
57
61
|
// $function: arrayGet
|
|
58
62
|
// $group: Array
|
|
@@ -60,15 +64,20 @@ function arrayExtend([array = null, array2 = null]) {
|
|
|
60
64
|
// $arg array: The array
|
|
61
65
|
// $arg index: The array element's index
|
|
62
66
|
// $return: The array element
|
|
63
|
-
function arrayGet(
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
+
function arrayGet(args) {
|
|
68
|
+
const [array, index] = valueArgsValidate(arrayGetArgs, args);
|
|
69
|
+
if (index >= array.length) {
|
|
70
|
+
throw new ValueArgsError('index', index);
|
|
67
71
|
}
|
|
68
72
|
|
|
69
73
|
return array[index];
|
|
70
74
|
}
|
|
71
75
|
|
|
76
|
+
const arrayGetArgs = valueArgsModel([
|
|
77
|
+
{'name': 'array', 'type': 'array'},
|
|
78
|
+
{'name': 'index', 'type': 'number', 'integer': true, 'gte': 0}
|
|
79
|
+
]);
|
|
80
|
+
|
|
72
81
|
|
|
73
82
|
// $function: arrayIndexOf
|
|
74
83
|
// $group: Array
|
|
@@ -77,23 +86,31 @@ function arrayGet([array = null, index = null]) {
|
|
|
77
86
|
// $arg value: The value to find in the array, or a match function, f(value) -> bool
|
|
78
87
|
// $arg index: Optional (default is 0). The index at which to start the search.
|
|
79
88
|
// $return: The first index of the value in the array; -1 if not found.
|
|
80
|
-
function arrayIndexOf(
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
89
|
+
function arrayIndexOf(args, options) {
|
|
90
|
+
const [array, value, index] = valueArgsValidate(arrayIndexOfArgs, args, -1);
|
|
91
|
+
if (index >= array.length) {
|
|
92
|
+
throw new ValueArgsError('index', index, -1);
|
|
84
93
|
}
|
|
85
94
|
|
|
95
|
+
// Value function?
|
|
86
96
|
if (valueType(value) === 'function') {
|
|
87
97
|
for (let ix = index; ix < array.length; ix += 1) {
|
|
88
98
|
if (valueBoolean(value([array[ix]], options))) {
|
|
89
99
|
return ix;
|
|
90
100
|
}
|
|
91
101
|
}
|
|
102
|
+
return -1;
|
|
92
103
|
}
|
|
93
104
|
|
|
94
105
|
return array.indexOf(value, index);
|
|
95
106
|
}
|
|
96
107
|
|
|
108
|
+
const arrayIndexOfArgs = valueArgsModel([
|
|
109
|
+
{'name': 'array', 'type': 'array'},
|
|
110
|
+
{'name': 'value'},
|
|
111
|
+
{'name': 'index', 'type': 'number', 'default': 0, 'integer': true, 'gte': 0}
|
|
112
|
+
]);
|
|
113
|
+
|
|
97
114
|
|
|
98
115
|
// $function: arrayJoin
|
|
99
116
|
// $group: Array
|
|
@@ -101,14 +118,16 @@ function arrayIndexOf([array = null, value = null, index = 0], options) {
|
|
|
101
118
|
// $arg array: The array
|
|
102
119
|
// $arg separator: The separator string
|
|
103
120
|
// $return: The joined string
|
|
104
|
-
function arrayJoin(
|
|
105
|
-
|
|
106
|
-
return null;
|
|
107
|
-
}
|
|
108
|
-
|
|
121
|
+
function arrayJoin(args) {
|
|
122
|
+
const [array , separator] = valueArgsValidate(arrayJoinArgs, args);
|
|
109
123
|
return array.map((value) => valueString(value)).join(separator);
|
|
110
124
|
}
|
|
111
125
|
|
|
126
|
+
const arrayJoinArgs = valueArgsModel([
|
|
127
|
+
{'name': 'array', 'type': 'array'},
|
|
128
|
+
{'name': 'separator', 'type': 'string'}
|
|
129
|
+
]);
|
|
130
|
+
|
|
112
131
|
|
|
113
132
|
// $function: arrayLastIndexOf
|
|
114
133
|
// $group: Array
|
|
@@ -117,41 +136,50 @@ function arrayJoin([array = null, separator = null]) {
|
|
|
117
136
|
// $arg value: The value to find in the array, or a match function, f(value) -> bool
|
|
118
137
|
// $arg index: Optional (default is the end of the array). The index at which to start the search.
|
|
119
138
|
// $return: The last index of the value in the array; -1 if not found.
|
|
120
|
-
function arrayLastIndexOf(
|
|
139
|
+
function arrayLastIndexOf(args, options) {
|
|
140
|
+
const [array, value, indexArg] = valueArgsValidate(arrayLastIndexOfArgs, args, -1);
|
|
121
141
|
let index = indexArg;
|
|
122
|
-
if (
|
|
142
|
+
if (index === null) {
|
|
123
143
|
index = array.length - 1;
|
|
124
144
|
}
|
|
125
|
-
if (
|
|
126
|
-
|
|
127
|
-
return -1;
|
|
145
|
+
if (index >= array.length) {
|
|
146
|
+
throw new ValueArgsError('index', index, -1);
|
|
128
147
|
}
|
|
129
148
|
|
|
149
|
+
// Value function?
|
|
130
150
|
if (valueType(value) === 'function') {
|
|
131
151
|
for (let ix = index; ix >= 0; ix -= 1) {
|
|
132
152
|
if (valueBoolean(value([array[ix]], options))) {
|
|
133
153
|
return ix;
|
|
134
154
|
}
|
|
135
155
|
}
|
|
156
|
+
return -1;
|
|
136
157
|
}
|
|
137
158
|
|
|
138
159
|
return array.lastIndexOf(value, index);
|
|
139
160
|
}
|
|
140
161
|
|
|
162
|
+
const arrayLastIndexOfArgs = valueArgsModel([
|
|
163
|
+
{'name': 'array', 'type': 'array'},
|
|
164
|
+
{'name': 'value'},
|
|
165
|
+
{'name': 'index', 'type': 'number', 'nullable': true, 'integer': true, 'gte': 0}
|
|
166
|
+
]);
|
|
167
|
+
|
|
141
168
|
|
|
142
169
|
// $function: arrayLength
|
|
143
170
|
// $group: Array
|
|
144
171
|
// $doc: Get the length of an array
|
|
145
172
|
// $arg array: The array
|
|
146
173
|
// $return: The array's length; zero if not an array
|
|
147
|
-
function arrayLength(
|
|
148
|
-
|
|
149
|
-
return 0;
|
|
150
|
-
}
|
|
151
|
-
|
|
174
|
+
function arrayLength(args) {
|
|
175
|
+
const [array] = valueArgsValidate(arrayLengthArgs, args, 0);
|
|
152
176
|
return array.length;
|
|
153
177
|
}
|
|
154
178
|
|
|
179
|
+
const arrayLengthArgs = valueArgsModel([
|
|
180
|
+
{'name': 'array', 'type': 'array'}
|
|
181
|
+
]);
|
|
182
|
+
|
|
155
183
|
|
|
156
184
|
// $function: arrayNew
|
|
157
185
|
// $group: Array
|
|
@@ -169,28 +197,34 @@ function arrayNew(values) {
|
|
|
169
197
|
// $arg size: Optional (default is 0). The new array's size.
|
|
170
198
|
// $arg value: Optional (default is 0). The value with which to fill the new array.
|
|
171
199
|
// $return: The new array
|
|
172
|
-
function arrayNewSize(
|
|
173
|
-
|
|
174
|
-
return null;
|
|
175
|
-
}
|
|
176
|
-
|
|
200
|
+
function arrayNewSize(args) {
|
|
201
|
+
const [size, value] = valueArgsValidate(arrayNewSizeArgs, args);
|
|
177
202
|
return new Array(size).fill(value);
|
|
178
203
|
}
|
|
179
204
|
|
|
205
|
+
const arrayNewSizeArgs = valueArgsModel([
|
|
206
|
+
{'name': 'size', 'type': 'number', 'default': 0, 'integer': true, 'gte': 0},
|
|
207
|
+
{'name': 'value', 'default': 0}
|
|
208
|
+
]);
|
|
209
|
+
|
|
180
210
|
|
|
181
211
|
// $function: arrayPop
|
|
182
212
|
// $group: Array
|
|
183
213
|
// $doc: Remove the last element of the array and return it
|
|
184
214
|
// $arg array: The array
|
|
185
215
|
// $return: The last element of the array; null if the array is empty.
|
|
186
|
-
function arrayPop(
|
|
187
|
-
|
|
188
|
-
|
|
216
|
+
function arrayPop(args) {
|
|
217
|
+
const [array] = valueArgsValidate(arrayPopArgs, args);
|
|
218
|
+
if (array.length === 0) {
|
|
219
|
+
throw new ValueArgsError('array', array);
|
|
189
220
|
}
|
|
190
|
-
|
|
191
221
|
return array.pop();
|
|
192
222
|
}
|
|
193
223
|
|
|
224
|
+
const arrayPopArgs = valueArgsModel([
|
|
225
|
+
{'name': 'array', 'type': 'array'}
|
|
226
|
+
]);
|
|
227
|
+
|
|
194
228
|
|
|
195
229
|
// $function: arrayPush
|
|
196
230
|
// $group: Array
|
|
@@ -198,15 +232,17 @@ function arrayPop([array = null]) {
|
|
|
198
232
|
// $arg array: The array
|
|
199
233
|
// $arg values...: The values to add to the end of the array
|
|
200
234
|
// $return: The array
|
|
201
|
-
function arrayPush(
|
|
202
|
-
|
|
203
|
-
return null;
|
|
204
|
-
}
|
|
205
|
-
|
|
235
|
+
function arrayPush(args) {
|
|
236
|
+
const [array, values] = valueArgsValidate(arrayPushArgs, args);
|
|
206
237
|
array.push(...values);
|
|
207
238
|
return array;
|
|
208
239
|
}
|
|
209
240
|
|
|
241
|
+
const arrayPushArgs = valueArgsModel([
|
|
242
|
+
{'name': 'array', 'type': 'array'},
|
|
243
|
+
{'name': 'values', 'lastArgArray': true}
|
|
244
|
+
]);
|
|
245
|
+
|
|
210
246
|
|
|
211
247
|
// $function: arraySet
|
|
212
248
|
// $group: Array
|
|
@@ -215,30 +251,40 @@ function arrayPush([array = null, ...values]) {
|
|
|
215
251
|
// $arg index: The index of the element to set
|
|
216
252
|
// $arg value: The value to set
|
|
217
253
|
// $return: The value
|
|
218
|
-
function arraySet(
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
254
|
+
function arraySet(args) {
|
|
255
|
+
const [array, index, value] = valueArgsValidate(arraySetArgs, args);
|
|
256
|
+
if (index >= array.length) {
|
|
257
|
+
throw new ValueArgsError('index', index);
|
|
222
258
|
}
|
|
223
259
|
|
|
224
260
|
array[index] = value;
|
|
225
261
|
return value;
|
|
226
262
|
}
|
|
227
263
|
|
|
264
|
+
const arraySetArgs = valueArgsModel([
|
|
265
|
+
{'name': 'array', 'type': 'array'},
|
|
266
|
+
{'name': 'index', 'type': 'number', 'integer': true, 'gte': 0},
|
|
267
|
+
{'name': 'value'}
|
|
268
|
+
]);
|
|
269
|
+
|
|
228
270
|
|
|
229
271
|
// $function: arrayShift
|
|
230
272
|
// $group: Array
|
|
231
273
|
// $doc: Remove the first element of the array and return it
|
|
232
274
|
// $arg array: The array
|
|
233
275
|
// $return: The first element of the array; null if the array is empty.
|
|
234
|
-
function arrayShift(
|
|
235
|
-
|
|
236
|
-
|
|
276
|
+
function arrayShift(args) {
|
|
277
|
+
const [array] = valueArgsValidate(arrayShiftArgs, args);
|
|
278
|
+
if (array.length === 0) {
|
|
279
|
+
throw new ValueArgsError('array', array);
|
|
237
280
|
}
|
|
238
|
-
|
|
239
281
|
return array.shift();
|
|
240
282
|
}
|
|
241
283
|
|
|
284
|
+
const arrayShiftArgs = valueArgsModel([
|
|
285
|
+
{'name': 'array', 'type': 'array'}
|
|
286
|
+
]);
|
|
287
|
+
|
|
242
288
|
|
|
243
289
|
// $function: arraySlice
|
|
244
290
|
// $group: Array
|
|
@@ -247,20 +293,25 @@ function arrayShift([array = null]) {
|
|
|
247
293
|
// $arg start: Optional (default is 0). The start index of the slice.
|
|
248
294
|
// $arg end: Optional (default is the end of the array). The end index of the slice.
|
|
249
295
|
// $return: The new array slice
|
|
250
|
-
function arraySlice(
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
296
|
+
function arraySlice(args) {
|
|
297
|
+
const [array, start, endArg] = valueArgsValidate(arraySliceArgs, args);
|
|
298
|
+
const end = endArg !== null ? endArg : array.length;
|
|
299
|
+
if (start > array.length) {
|
|
300
|
+
throw new ValueArgsError('start', start);
|
|
254
301
|
}
|
|
255
|
-
if (
|
|
256
|
-
|
|
257
|
-
valueType(end) !== 'number' || Math.floor(end) !== end || end < 0 || end > array.length) {
|
|
258
|
-
return null;
|
|
302
|
+
if (end > array.length) {
|
|
303
|
+
throw new ValueArgsError('end', end);
|
|
259
304
|
}
|
|
260
305
|
|
|
261
306
|
return array.slice(start, end);
|
|
262
307
|
}
|
|
263
308
|
|
|
309
|
+
const arraySliceArgs = valueArgsModel([
|
|
310
|
+
{'name': 'array', 'type': 'array'},
|
|
311
|
+
{'name': 'start', 'type': 'number', 'default': 0, 'integer': true, 'gte': 0},
|
|
312
|
+
{'name': 'end', 'type': 'number', 'nullable': true, 'integer': true, 'gte': 0}
|
|
313
|
+
]);
|
|
314
|
+
|
|
264
315
|
|
|
265
316
|
// $function: arraySort
|
|
266
317
|
// $group: Array
|
|
@@ -268,17 +319,19 @@ function arraySlice([array = null, start = 0, endArg = null]) {
|
|
|
268
319
|
// $arg array: The array
|
|
269
320
|
// $arg compareFn: Optional (default is null). The comparison function.
|
|
270
321
|
// $return: The sorted array
|
|
271
|
-
function arraySort(
|
|
272
|
-
|
|
273
|
-
return null;
|
|
274
|
-
}
|
|
275
|
-
|
|
322
|
+
function arraySort(args, options) {
|
|
323
|
+
const [array, compareFn] = valueArgsValidate(arraySortArgs, args);
|
|
276
324
|
if (compareFn === null) {
|
|
277
325
|
return array.sort(valueCompare);
|
|
278
326
|
}
|
|
279
|
-
return array.sort((...
|
|
327
|
+
return array.sort((...sortArgs) => compareFn(sortArgs, options));
|
|
280
328
|
}
|
|
281
329
|
|
|
330
|
+
const arraySortArgs = valueArgsModel([
|
|
331
|
+
{'name': 'array', 'type': 'array'},
|
|
332
|
+
{'name': 'compareFn', 'type': 'function', 'nullable': true}
|
|
333
|
+
]);
|
|
334
|
+
|
|
282
335
|
|
|
283
336
|
//
|
|
284
337
|
// Data functions
|
|
@@ -291,14 +344,16 @@ function arraySort([array = null, compareFn = null], options) {
|
|
|
291
344
|
// $arg data: The data array
|
|
292
345
|
// $arg aggregation: The [aggregation model](model.html#var.vName='Aggregation')
|
|
293
346
|
// $return: The aggregated data array
|
|
294
|
-
function dataAggregate(
|
|
295
|
-
|
|
296
|
-
return null;
|
|
297
|
-
}
|
|
298
|
-
|
|
347
|
+
function dataAggregate(args) {
|
|
348
|
+
const [data, aggregation] = valueArgsValidate(dataAggregateArgs, args);
|
|
299
349
|
return aggregateData(data, aggregation);
|
|
300
350
|
}
|
|
301
351
|
|
|
352
|
+
const dataAggregateArgs = valueArgsModel([
|
|
353
|
+
{'name': 'data', 'type': 'array'},
|
|
354
|
+
{'name': 'aggregation', 'type': 'object'}
|
|
355
|
+
]);
|
|
356
|
+
|
|
302
357
|
|
|
303
358
|
// $function: dataCalculatedField
|
|
304
359
|
// $group: Data
|
|
@@ -308,15 +363,19 @@ function dataAggregate([data = null, aggregation = null]) {
|
|
|
308
363
|
// $arg expr: The calculated field expression
|
|
309
364
|
// $arg variables: Optional (default is null). A variables object the expression evaluation.
|
|
310
365
|
// $return: The updated data array
|
|
311
|
-
function dataCalculatedField(
|
|
312
|
-
|
|
313
|
-
(variables !== null && valueType(variables) !== 'object')) {
|
|
314
|
-
return null;
|
|
315
|
-
}
|
|
316
|
-
|
|
366
|
+
function dataCalculatedField(args, options) {
|
|
367
|
+
const [data, fieldName, expr, variables] = valueArgsValidate(dataCalculatedFieldArgs, args);
|
|
317
368
|
return addCalculatedField(data, fieldName, expr, variables, options);
|
|
318
369
|
}
|
|
319
370
|
|
|
371
|
+
const dataCalculatedFieldArgs = valueArgsModel([
|
|
372
|
+
{'name': 'data', 'type': 'array'},
|
|
373
|
+
{'name': 'fieldName', 'type': 'string'},
|
|
374
|
+
{'name': 'expr', 'type': 'string'},
|
|
375
|
+
{'name': 'variables', 'type': 'object', 'nullable': true}
|
|
376
|
+
]);
|
|
377
|
+
|
|
378
|
+
|
|
320
379
|
// $function: dataFilter
|
|
321
380
|
// $group: Data
|
|
322
381
|
// $doc: Filter a data array
|
|
@@ -324,14 +383,17 @@ function dataCalculatedField([data = null, fieldName = null, expr = null, variab
|
|
|
324
383
|
// $arg expr: The filter expression
|
|
325
384
|
// $arg variables: Optional (default is null). A variables object the expression evaluation.
|
|
326
385
|
// $return: The filtered data array
|
|
327
|
-
function dataFilter(
|
|
328
|
-
|
|
329
|
-
return null;
|
|
330
|
-
}
|
|
331
|
-
|
|
386
|
+
function dataFilter(args, options) {
|
|
387
|
+
const [data, expr, variables] = valueArgsValidate(dataFilterArgs, args);
|
|
332
388
|
return filterData(data, expr, variables, options);
|
|
333
389
|
}
|
|
334
390
|
|
|
391
|
+
const dataFilterArgs = valueArgsModel([
|
|
392
|
+
{'name': 'data', 'type': 'array'},
|
|
393
|
+
{'name': 'expr', 'type': 'string'},
|
|
394
|
+
{'name': 'variables', 'type': 'object', 'nullable': true}
|
|
395
|
+
]);
|
|
396
|
+
|
|
335
397
|
|
|
336
398
|
// $function: dataJoin
|
|
337
399
|
// $group: Data
|
|
@@ -344,15 +406,20 @@ function dataFilter([data = null, expr = null, variables = null], options) {
|
|
|
344
406
|
// $arg isLeftJoin: Optional (default is false). If true, perform a left join (always include left row).
|
|
345
407
|
// $arg variables: Optional (default is null). A variables object for join expression evaluation.
|
|
346
408
|
// $return: The joined data array
|
|
347
|
-
function dataJoin(
|
|
348
|
-
|
|
349
|
-
(rightExpr !== null && valueType(rightExpr) !== 'string') || (variables !== null && valueType(variables) !== 'object')) {
|
|
350
|
-
return null;
|
|
351
|
-
}
|
|
352
|
-
|
|
409
|
+
function dataJoin(args, options) {
|
|
410
|
+
const [leftData, rightData, joinExpr, rightExpr, isLeftJoin, variables] = valueArgsValidate(dataJoinArgs, args);
|
|
353
411
|
return joinData(leftData, rightData, joinExpr, rightExpr, isLeftJoin, variables, options);
|
|
354
412
|
}
|
|
355
413
|
|
|
414
|
+
const dataJoinArgs = valueArgsModel([
|
|
415
|
+
{'name': 'leftData', 'type': 'array'},
|
|
416
|
+
{'name': 'rightData', 'type': 'array'},
|
|
417
|
+
{'name': 'joinExpr', 'type': 'string'},
|
|
418
|
+
{'name': 'rightExpr', 'type': 'string', 'nullable': true},
|
|
419
|
+
{'name': 'isLeftJoin', 'type': 'boolean', 'default': false},
|
|
420
|
+
{'name': 'variables', 'type': 'object', 'nullable': true}
|
|
421
|
+
]);
|
|
422
|
+
|
|
356
423
|
|
|
357
424
|
// $function: dataParseCSV
|
|
358
425
|
// $group: Data
|
|
@@ -367,7 +434,7 @@ function dataParseCSV(args) {
|
|
|
367
434
|
continue;
|
|
368
435
|
}
|
|
369
436
|
if (valueType(arg) !== 'string') {
|
|
370
|
-
|
|
437
|
+
throw new ValueArgsError('text', arg);
|
|
371
438
|
}
|
|
372
439
|
lines.push(arg);
|
|
373
440
|
}
|
|
@@ -384,14 +451,16 @@ function dataParseCSV(args) {
|
|
|
384
451
|
// $arg data: The data array
|
|
385
452
|
// $arg sorts: The sort field-name/descending-sort tuples
|
|
386
453
|
// $return: The sorted data array
|
|
387
|
-
function dataSort(
|
|
388
|
-
|
|
389
|
-
return null;
|
|
390
|
-
}
|
|
391
|
-
|
|
454
|
+
function dataSort(args) {
|
|
455
|
+
const [data, sorts] = valueArgsValidate(dataSortArgs, args);
|
|
392
456
|
return sortData(data, sorts);
|
|
393
457
|
}
|
|
394
458
|
|
|
459
|
+
const dataSortArgs = valueArgsModel([
|
|
460
|
+
{'name': 'data', 'type': 'array'},
|
|
461
|
+
{'name': 'sorts', 'type': 'array'}
|
|
462
|
+
]);
|
|
463
|
+
|
|
395
464
|
|
|
396
465
|
// $function: dataTop
|
|
397
466
|
// $group: Data
|
|
@@ -400,16 +469,17 @@ function dataSort([data = null, sorts = null]) {
|
|
|
400
469
|
// $arg count: The number of rows to keep (default is 1)
|
|
401
470
|
// $arg categoryFields: Optional (default is null). The category fields.
|
|
402
471
|
// $return: The top data array
|
|
403
|
-
function dataTop(
|
|
404
|
-
|
|
405
|
-
valueType(count) !== 'number' || Math.floor(count) !== count || count < 1 ||
|
|
406
|
-
(categoryFields !== null && valueType(categoryFields) !== 'array')) {
|
|
407
|
-
return null;
|
|
408
|
-
}
|
|
409
|
-
|
|
472
|
+
function dataTop(args) {
|
|
473
|
+
const [data, count, categoryFields] = valueArgsValidate(dataTopArgs, args);
|
|
410
474
|
return topData(data, count, categoryFields);
|
|
411
475
|
}
|
|
412
476
|
|
|
477
|
+
const dataTopArgs = valueArgsModel([
|
|
478
|
+
{'name': 'data', 'type': 'array'},
|
|
479
|
+
{'name': 'count', 'type': 'number', 'integer': true, 'gte': 1},
|
|
480
|
+
{'name': 'categoryFields', 'type': 'array', 'nullable': true}
|
|
481
|
+
]);
|
|
482
|
+
|
|
413
483
|
|
|
414
484
|
// $function: dataValidate
|
|
415
485
|
// $group: Data
|
|
@@ -417,15 +487,17 @@ function dataTop([data = null, count = null, categoryFields = null]) {
|
|
|
417
487
|
// $arg data: The data array
|
|
418
488
|
// $arg csv: Optional (default is false). If true, parse value strings.
|
|
419
489
|
// $return: The validated data array
|
|
420
|
-
function dataValidate(
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
validateData(data, valueBoolean(csv));
|
|
490
|
+
function dataValidate(args) {
|
|
491
|
+
const [data, csv] = valueArgsValidate(dataValidateArgs, args);
|
|
492
|
+
validateData(data, csv);
|
|
426
493
|
return data;
|
|
427
494
|
}
|
|
428
495
|
|
|
496
|
+
const dataValidateArgs = valueArgsModel([
|
|
497
|
+
{'name': 'data', 'type': 'array'},
|
|
498
|
+
{'name': 'csv', 'type': 'boolean', 'default': false}
|
|
499
|
+
]);
|
|
500
|
+
|
|
429
501
|
|
|
430
502
|
//
|
|
431
503
|
// Datetime functions
|
|
@@ -437,28 +509,30 @@ function dataValidate([data = null, csv = false]) {
|
|
|
437
509
|
// $doc: Get the day of the month of a datetime
|
|
438
510
|
// $arg datetime: The datetime
|
|
439
511
|
// $return: The day of the month
|
|
440
|
-
function datetimeDay(
|
|
441
|
-
|
|
442
|
-
return null;
|
|
443
|
-
}
|
|
444
|
-
|
|
512
|
+
function datetimeDay(args) {
|
|
513
|
+
const [datetime] = valueArgsValidate(datetimeDayArgs, args);
|
|
445
514
|
return datetime.getDate();
|
|
446
515
|
}
|
|
447
516
|
|
|
517
|
+
const datetimeDayArgs = valueArgsModel([
|
|
518
|
+
{'name': 'datetime', 'type': 'datetime'}
|
|
519
|
+
]);
|
|
520
|
+
|
|
448
521
|
|
|
449
522
|
// $function: datetimeHour
|
|
450
523
|
// $group: Datetime
|
|
451
524
|
// $doc: Get the hour of a datetime
|
|
452
525
|
// $arg datetime: The datetime
|
|
453
526
|
// $return: The hour
|
|
454
|
-
function datetimeHour(
|
|
455
|
-
|
|
456
|
-
return null;
|
|
457
|
-
}
|
|
458
|
-
|
|
527
|
+
function datetimeHour(args) {
|
|
528
|
+
const [datetime] = valueArgsValidate(datetimeHourArgs, args);
|
|
459
529
|
return datetime.getHours();
|
|
460
530
|
}
|
|
461
531
|
|
|
532
|
+
const datetimeHourArgs = valueArgsModel([
|
|
533
|
+
{'name': 'datetime', 'type': 'datetime'}
|
|
534
|
+
]);
|
|
535
|
+
|
|
462
536
|
|
|
463
537
|
// $function: datetimeISOFormat
|
|
464
538
|
// $group: Datetime
|
|
@@ -466,12 +540,10 @@ function datetimeHour([datetime = null]) {
|
|
|
466
540
|
// $arg datetime: The datetime
|
|
467
541
|
// $arg isDate: If true, format the datetime as an ISO date
|
|
468
542
|
// $return: The formatted datetime string
|
|
469
|
-
function datetimeISOFormat(
|
|
470
|
-
|
|
471
|
-
return null;
|
|
472
|
-
}
|
|
543
|
+
function datetimeISOFormat(args) {
|
|
544
|
+
const [datetime, isDate] = valueArgsValidate(datetimeISOFormatArgs, args);
|
|
473
545
|
|
|
474
|
-
if (
|
|
546
|
+
if (isDate) {
|
|
475
547
|
const year = String(datetime.getFullYear()).padStart(4, '0');
|
|
476
548
|
const month = String(datetime.getMonth() + 1).padStart(2, '0');
|
|
477
549
|
const day = String(datetime.getDate()).padStart(2, '0');
|
|
@@ -481,62 +553,71 @@ function datetimeISOFormat([datetime = null, isDate = false]) {
|
|
|
481
553
|
return valueString(datetime);
|
|
482
554
|
}
|
|
483
555
|
|
|
556
|
+
const datetimeISOFormatArgs = valueArgsModel([
|
|
557
|
+
{'name': 'datetime', 'type': 'datetime'},
|
|
558
|
+
{'name': 'isDate', 'type': 'boolean', 'default': false}
|
|
559
|
+
]);
|
|
560
|
+
|
|
484
561
|
|
|
485
562
|
// $function: datetimeISOParse
|
|
486
563
|
// $group: Datetime
|
|
487
564
|
// $doc: Parse an ISO date/time string
|
|
488
565
|
// $arg string: The ISO date/time string
|
|
489
566
|
// $return: The datetime, or null if parsing fails
|
|
490
|
-
function datetimeISOParse(
|
|
491
|
-
|
|
492
|
-
return null;
|
|
493
|
-
}
|
|
494
|
-
|
|
567
|
+
function datetimeISOParse(args) {
|
|
568
|
+
const [string] = valueArgsValidate(datetimeISOParseArgs, args);
|
|
495
569
|
return valueParseDatetime(string);
|
|
496
570
|
}
|
|
497
571
|
|
|
572
|
+
const datetimeISOParseArgs = valueArgsModel([
|
|
573
|
+
{'name': 'string', 'type': 'string'}
|
|
574
|
+
]);
|
|
575
|
+
|
|
498
576
|
|
|
499
577
|
// $function: datetimeMillisecond
|
|
500
578
|
// $group: Datetime
|
|
501
579
|
// $doc: Get the millisecond of a datetime
|
|
502
580
|
// $arg datetime: The datetime
|
|
503
581
|
// $return: The millisecond
|
|
504
|
-
function datetimeMillisecond(
|
|
505
|
-
|
|
506
|
-
return null;
|
|
507
|
-
}
|
|
508
|
-
|
|
582
|
+
function datetimeMillisecond(args) {
|
|
583
|
+
const [datetime] = valueArgsValidate(datetimeMillisecondArgs, args);
|
|
509
584
|
return datetime.getMilliseconds();
|
|
510
585
|
}
|
|
511
586
|
|
|
587
|
+
const datetimeMillisecondArgs = valueArgsModel([
|
|
588
|
+
{'name': 'datetime', 'type': 'datetime'}
|
|
589
|
+
]);
|
|
590
|
+
|
|
512
591
|
|
|
513
592
|
// $function: datetimeMinute
|
|
514
593
|
// $group: Datetime
|
|
515
594
|
// $doc: Get the minute of a datetime
|
|
516
595
|
// $arg datetime: The datetime
|
|
517
596
|
// $return: The minute
|
|
518
|
-
function datetimeMinute(
|
|
519
|
-
|
|
520
|
-
return null;
|
|
521
|
-
}
|
|
522
|
-
|
|
597
|
+
function datetimeMinute(args) {
|
|
598
|
+
const [datetime] = valueArgsValidate(datetimeMinuteArgs, args);
|
|
523
599
|
return datetime.getMinutes();
|
|
524
600
|
}
|
|
525
601
|
|
|
602
|
+
const datetimeMinuteArgs = valueArgsModel([
|
|
603
|
+
{'name': 'datetime', 'type': 'datetime'}
|
|
604
|
+
]);
|
|
605
|
+
|
|
526
606
|
|
|
527
607
|
// $function: datetimeMonth
|
|
528
608
|
// $group: Datetime
|
|
529
609
|
// $doc: Get the month (1-12) of a datetime
|
|
530
610
|
// $arg datetime: The datetime
|
|
531
611
|
// $return: The month
|
|
532
|
-
function datetimeMonth(
|
|
533
|
-
|
|
534
|
-
return null;
|
|
535
|
-
}
|
|
536
|
-
|
|
612
|
+
function datetimeMonth(args) {
|
|
613
|
+
const [datetime] = valueArgsValidate(datetimeMonthArgs, args);
|
|
537
614
|
return datetime.getMonth() + 1;
|
|
538
615
|
}
|
|
539
616
|
|
|
617
|
+
const datetimeMonthArgs = valueArgsModel([
|
|
618
|
+
{'name': 'datetime', 'type': 'datetime'}
|
|
619
|
+
]);
|
|
620
|
+
|
|
540
621
|
|
|
541
622
|
// $function: datetimeNew
|
|
542
623
|
// $group: Datetime
|
|
@@ -549,20 +630,21 @@ function datetimeMonth([datetime = null]) {
|
|
|
549
630
|
// $arg second: Optional (default is 0). The second.
|
|
550
631
|
// $arg millisecond: Optional (default is 0). The millisecond.
|
|
551
632
|
// $return: The new datetime
|
|
552
|
-
function datetimeNew(
|
|
553
|
-
|
|
554
|
-
valueType(month) !== 'number' || Math.floor(month) !== month ||
|
|
555
|
-
valueType(day) !== 'number' || Math.floor(day) !== day || day < -10000 || day > 10000 ||
|
|
556
|
-
valueType(hour) !== 'number' || Math.floor(hour) !== hour ||
|
|
557
|
-
valueType(minute) !== 'number' || Math.floor(minute) !== minute ||
|
|
558
|
-
valueType(second) !== 'number' || Math.floor(second) !== second ||
|
|
559
|
-
valueType(millisecond) !== 'number' || Math.floor(millisecond) !== millisecond) {
|
|
560
|
-
return null;
|
|
561
|
-
}
|
|
562
|
-
|
|
633
|
+
function datetimeNew(args) {
|
|
634
|
+
const [year, month, day, hour, minute, second, millisecond] = valueArgsValidate(datetimeNewArgs, args);
|
|
563
635
|
return new Date(year, month - 1, day, hour, minute, second, millisecond);
|
|
564
636
|
}
|
|
565
637
|
|
|
638
|
+
const datetimeNewArgs = valueArgsModel([
|
|
639
|
+
{'name': 'year', 'type': 'number', 'integer': true, 'gte': 100},
|
|
640
|
+
{'name': 'month', 'type': 'number', 'integer': true},
|
|
641
|
+
{'name': 'day', 'type': 'number', 'integer': true, 'gte': -10000, 'lte': 10000},
|
|
642
|
+
{'name': 'hour', 'type': 'number', 'default': 0, 'integer': true},
|
|
643
|
+
{'name': 'minute', 'type': 'number', 'default': 0, 'integer': true},
|
|
644
|
+
{'name': 'second', 'type': 'number', 'default': 0, 'integer': true},
|
|
645
|
+
{'name': 'millisecond', 'type': 'number', 'default': 0, 'integer': true}
|
|
646
|
+
]);
|
|
647
|
+
|
|
566
648
|
|
|
567
649
|
// $function: datetimeNow
|
|
568
650
|
// $group: Datetime
|
|
@@ -578,14 +660,15 @@ function datetimeNow() {
|
|
|
578
660
|
// $doc: Get the second of a datetime
|
|
579
661
|
// $arg datetime: The datetime
|
|
580
662
|
// $return: The second
|
|
581
|
-
function datetimeSecond(
|
|
582
|
-
|
|
583
|
-
return null;
|
|
584
|
-
}
|
|
585
|
-
|
|
663
|
+
function datetimeSecond(args) {
|
|
664
|
+
const [datetime] = valueArgsValidate(datetimeSecondArgs, args);
|
|
586
665
|
return datetime.getSeconds();
|
|
587
666
|
}
|
|
588
667
|
|
|
668
|
+
const datetimeSecondArgs = valueArgsModel([
|
|
669
|
+
{'name': 'datetime', 'type': 'datetime'}
|
|
670
|
+
]);
|
|
671
|
+
|
|
589
672
|
|
|
590
673
|
// $function: datetimeToday
|
|
591
674
|
// $group: Datetime
|
|
@@ -602,14 +685,15 @@ function datetimeToday() {
|
|
|
602
685
|
// $doc: Get the full year of a datetime
|
|
603
686
|
// $arg datetime: The datetime
|
|
604
687
|
// $return: The full year
|
|
605
|
-
function datetimeYear(
|
|
606
|
-
|
|
607
|
-
return null;
|
|
608
|
-
}
|
|
609
|
-
|
|
688
|
+
function datetimeYear(args) {
|
|
689
|
+
const [datetime] = valueArgsValidate(datetimeYearArgs, args);
|
|
610
690
|
return datetime.getFullYear();
|
|
611
691
|
}
|
|
612
692
|
|
|
693
|
+
const datetimeYearArgs = valueArgsModel([
|
|
694
|
+
{'name': 'datetime', 'type': 'datetime'}
|
|
695
|
+
]);
|
|
696
|
+
|
|
613
697
|
|
|
614
698
|
//
|
|
615
699
|
// JSON functions
|
|
@@ -621,14 +705,15 @@ function datetimeYear([datetime = null]) {
|
|
|
621
705
|
// $doc: Convert a JSON string to an object
|
|
622
706
|
// $arg string: The JSON string
|
|
623
707
|
// $return: The object
|
|
624
|
-
function jsonParse(
|
|
625
|
-
|
|
626
|
-
return null;
|
|
627
|
-
}
|
|
628
|
-
|
|
708
|
+
function jsonParse(args) {
|
|
709
|
+
const [string] = valueArgsValidate(jsonParseArgs, args);
|
|
629
710
|
return JSON.parse(string);
|
|
630
711
|
}
|
|
631
712
|
|
|
713
|
+
const jsonParseArgs = valueArgsModel([
|
|
714
|
+
{'name': 'string', 'type': 'string'}
|
|
715
|
+
]);
|
|
716
|
+
|
|
632
717
|
|
|
633
718
|
// $function: jsonStringify
|
|
634
719
|
// $group: JSON
|
|
@@ -636,74 +721,81 @@ function jsonParse([string = null]) {
|
|
|
636
721
|
// $arg value: The object
|
|
637
722
|
// $arg indent: Optional (default is null). The indentation number.
|
|
638
723
|
// $return: The JSON string
|
|
639
|
-
function jsonStringify(
|
|
640
|
-
|
|
641
|
-
return null;
|
|
642
|
-
}
|
|
643
|
-
|
|
724
|
+
function jsonStringify(args) {
|
|
725
|
+
const [value, indent] = valueArgsValidate(jsonStringifyArgs, args);
|
|
644
726
|
return valueJSON(value, indent);
|
|
645
727
|
}
|
|
646
728
|
|
|
729
|
+
const jsonStringifyArgs = valueArgsModel([
|
|
730
|
+
{'name': 'value'},
|
|
731
|
+
{'name': 'indent', 'type': 'number', 'nullable': true, 'integer': true, 'gte': 1}
|
|
732
|
+
]);
|
|
733
|
+
|
|
647
734
|
|
|
648
735
|
//
|
|
649
736
|
// Math functions
|
|
650
737
|
//
|
|
651
738
|
|
|
739
|
+
|
|
652
740
|
// $function: mathAbs
|
|
653
741
|
// $group: Math
|
|
654
742
|
// $doc: Compute the absolute value of a number
|
|
655
743
|
// $arg x: The number
|
|
656
744
|
// $return: The absolute value of the number
|
|
657
|
-
function mathAbs(
|
|
658
|
-
|
|
659
|
-
return null;
|
|
660
|
-
}
|
|
661
|
-
|
|
745
|
+
function mathAbs(args) {
|
|
746
|
+
const [x] = valueArgsValidate(mathAbsArgs, args);
|
|
662
747
|
return Math.abs(x);
|
|
663
748
|
}
|
|
664
749
|
|
|
750
|
+
const mathAbsArgs = valueArgsModel([
|
|
751
|
+
{'name': 'x', 'type': 'number'}
|
|
752
|
+
]);
|
|
753
|
+
|
|
665
754
|
|
|
666
755
|
// $function: mathAcos
|
|
667
756
|
// $group: Math
|
|
668
757
|
// $doc: Compute the arccosine, in radians, of a number
|
|
669
758
|
// $arg x: The number
|
|
670
759
|
// $return: The arccosine, in radians, of the number
|
|
671
|
-
function mathAcos(
|
|
672
|
-
|
|
673
|
-
return null;
|
|
674
|
-
}
|
|
675
|
-
|
|
760
|
+
function mathAcos(args) {
|
|
761
|
+
const [x] = valueArgsValidate(mathAcosArgs, args);
|
|
676
762
|
return Math.acos(x);
|
|
677
763
|
}
|
|
678
764
|
|
|
765
|
+
const mathAcosArgs = valueArgsModel([
|
|
766
|
+
{'name': 'x', 'type': 'number'}
|
|
767
|
+
]);
|
|
768
|
+
|
|
679
769
|
|
|
680
770
|
// $function: mathAsin
|
|
681
771
|
// $group: Math
|
|
682
772
|
// $doc: Compute the arcsine, in radians, of a number
|
|
683
773
|
// $arg x: The number
|
|
684
774
|
// $return: The arcsine, in radians, of the number
|
|
685
|
-
function mathAsin(
|
|
686
|
-
|
|
687
|
-
return null;
|
|
688
|
-
}
|
|
689
|
-
|
|
775
|
+
function mathAsin(args) {
|
|
776
|
+
const [x] = valueArgsValidate(mathAsinArgs, args);
|
|
690
777
|
return Math.asin(x);
|
|
691
778
|
}
|
|
692
779
|
|
|
780
|
+
const mathAsinArgs = valueArgsModel([
|
|
781
|
+
{'name': 'x', 'type': 'number'}
|
|
782
|
+
]);
|
|
783
|
+
|
|
693
784
|
|
|
694
785
|
// $function: mathAtan
|
|
695
786
|
// $group: Math
|
|
696
787
|
// $doc: Compute the arctangent, in radians, of a number
|
|
697
788
|
// $arg x: The number
|
|
698
789
|
// $return: The arctangent, in radians, of the number
|
|
699
|
-
function mathAtan(
|
|
700
|
-
|
|
701
|
-
return null;
|
|
702
|
-
}
|
|
703
|
-
|
|
790
|
+
function mathAtan(args) {
|
|
791
|
+
const [x] = valueArgsValidate(mathAtanArgs, args);
|
|
704
792
|
return Math.atan(x);
|
|
705
793
|
}
|
|
706
794
|
|
|
795
|
+
const mathAtanArgs = valueArgsModel([
|
|
796
|
+
{'name': 'x', 'type': 'number'}
|
|
797
|
+
]);
|
|
798
|
+
|
|
707
799
|
|
|
708
800
|
// $function: mathAtan2
|
|
709
801
|
// $group: Math
|
|
@@ -711,70 +803,76 @@ function mathAtan([x = null]) {
|
|
|
711
803
|
// $arg y: The Y-coordinate of the point
|
|
712
804
|
// $arg x: The X-coordinate of the point
|
|
713
805
|
// $return: The angle, in radians
|
|
714
|
-
function mathAtan2(
|
|
715
|
-
|
|
716
|
-
return null;
|
|
717
|
-
}
|
|
718
|
-
|
|
806
|
+
function mathAtan2(args) {
|
|
807
|
+
const [y, x] = valueArgsValidate(mathAtan2Args, args);
|
|
719
808
|
return Math.atan2(y, x);
|
|
720
809
|
}
|
|
721
810
|
|
|
811
|
+
const mathAtan2Args = valueArgsModel([
|
|
812
|
+
{'name': 'y', 'type': 'number'},
|
|
813
|
+
{'name': 'x', 'type': 'number'}
|
|
814
|
+
]);
|
|
815
|
+
|
|
722
816
|
|
|
723
817
|
// $function: mathCeil
|
|
724
818
|
// $group: Math
|
|
725
819
|
// $doc: Compute the ceiling of a number (round up to the next highest integer)
|
|
726
820
|
// $arg x: The number
|
|
727
821
|
// $return: The ceiling of the number
|
|
728
|
-
function mathCeil(
|
|
729
|
-
|
|
730
|
-
return null;
|
|
731
|
-
}
|
|
732
|
-
|
|
822
|
+
function mathCeil(args) {
|
|
823
|
+
const [x] = valueArgsValidate(mathCeilArgs, args);
|
|
733
824
|
return Math.ceil(x);
|
|
734
825
|
}
|
|
735
826
|
|
|
827
|
+
const mathCeilArgs = valueArgsModel([
|
|
828
|
+
{'name': 'x', 'type': 'number'}
|
|
829
|
+
]);
|
|
830
|
+
|
|
736
831
|
|
|
737
832
|
// $function: mathCos
|
|
738
833
|
// $group: Math
|
|
739
834
|
// $doc: Compute the cosine of an angle, in radians
|
|
740
835
|
// $arg x: The angle, in radians
|
|
741
836
|
// $return: The cosine of the angle
|
|
742
|
-
function mathCos(
|
|
743
|
-
|
|
744
|
-
return null;
|
|
745
|
-
}
|
|
746
|
-
|
|
837
|
+
function mathCos(args) {
|
|
838
|
+
const [x] = valueArgsValidate(mathCosArgs, args);
|
|
747
839
|
return Math.cos(x);
|
|
748
840
|
}
|
|
749
841
|
|
|
842
|
+
const mathCosArgs = valueArgsModel([
|
|
843
|
+
{'name': 'x', 'type': 'number'}
|
|
844
|
+
]);
|
|
845
|
+
|
|
750
846
|
|
|
751
847
|
// $function: mathFloor
|
|
752
848
|
// $group: Math
|
|
753
849
|
// $doc: Compute the floor of a number (round down to the next lowest integer)
|
|
754
850
|
// $arg x: The number
|
|
755
851
|
// $return: The floor of the number
|
|
756
|
-
function mathFloor(
|
|
757
|
-
|
|
758
|
-
return null;
|
|
759
|
-
}
|
|
760
|
-
|
|
852
|
+
function mathFloor(args) {
|
|
853
|
+
const [x] = valueArgsValidate(mathFloorArgs, args);
|
|
761
854
|
return Math.floor(x);
|
|
762
855
|
}
|
|
763
856
|
|
|
857
|
+
const mathFloorArgs = valueArgsModel([
|
|
858
|
+
{'name': 'x', 'type': 'number'}
|
|
859
|
+
]);
|
|
860
|
+
|
|
764
861
|
|
|
765
862
|
// $function: mathLn
|
|
766
863
|
// $group: Math
|
|
767
864
|
// $doc: Compute the natural logarithm (base e) of a number
|
|
768
865
|
// $arg x: The number
|
|
769
866
|
// $return: The natural logarithm of the number
|
|
770
|
-
function mathLn(
|
|
771
|
-
|
|
772
|
-
return null;
|
|
773
|
-
}
|
|
774
|
-
|
|
867
|
+
function mathLn(args) {
|
|
868
|
+
const [x] = valueArgsValidate(mathLnArgs, args);
|
|
775
869
|
return Math.log(x);
|
|
776
870
|
}
|
|
777
871
|
|
|
872
|
+
const mathLnArgs = valueArgsModel([
|
|
873
|
+
{'name': 'x', 'type': 'number', 'gt': 0}
|
|
874
|
+
]);
|
|
875
|
+
|
|
778
876
|
|
|
779
877
|
// $function: mathLog
|
|
780
878
|
// $group: Math
|
|
@@ -782,14 +880,20 @@ function mathLn([x = null]) {
|
|
|
782
880
|
// $arg x: The number
|
|
783
881
|
// $arg base: Optional (default is 10). The logarithm base.
|
|
784
882
|
// $return: The logarithm of the number
|
|
785
|
-
function mathLog(
|
|
786
|
-
|
|
787
|
-
|
|
883
|
+
function mathLog(args) {
|
|
884
|
+
const [x, base] = valueArgsValidate(mathLogArgs, args);
|
|
885
|
+
if (base === 1) {
|
|
886
|
+
throw new ValueArgsError('base', base);
|
|
788
887
|
}
|
|
789
888
|
|
|
790
889
|
return Math.log(x) / Math.log(base);
|
|
791
890
|
}
|
|
792
891
|
|
|
892
|
+
const mathLogArgs = valueArgsModel([
|
|
893
|
+
{'name': 'x', 'type': 'number', 'gt': 0},
|
|
894
|
+
{'name': 'base', 'type': 'number', 'default': 10, 'gt': 0}
|
|
895
|
+
]);
|
|
896
|
+
|
|
793
897
|
|
|
794
898
|
// $function: mathMax
|
|
795
899
|
// $group: Math
|
|
@@ -797,11 +901,13 @@ function mathLog([x = null, base = 10]) {
|
|
|
797
901
|
// $arg values...: The values
|
|
798
902
|
// $return: The maximum value
|
|
799
903
|
function mathMax(values) {
|
|
800
|
-
|
|
801
|
-
|
|
904
|
+
let result;
|
|
905
|
+
for (const value of values) {
|
|
906
|
+
if (typeof result === 'undefined' || valueCompare(value, result) > 0) {
|
|
907
|
+
result = value;
|
|
908
|
+
}
|
|
802
909
|
}
|
|
803
|
-
|
|
804
|
-
return Math.max(...values);
|
|
910
|
+
return result ?? null;
|
|
805
911
|
}
|
|
806
912
|
|
|
807
913
|
|
|
@@ -811,11 +917,13 @@ function mathMax(values) {
|
|
|
811
917
|
// $arg values...: The values
|
|
812
918
|
// $return: The minimum value
|
|
813
919
|
function mathMin(values) {
|
|
814
|
-
|
|
815
|
-
|
|
920
|
+
let result;
|
|
921
|
+
for (const value of values) {
|
|
922
|
+
if (typeof result === 'undefined' || valueCompare(value, result) < 0) {
|
|
923
|
+
result = value;
|
|
924
|
+
}
|
|
816
925
|
}
|
|
817
|
-
|
|
818
|
-
return Math.min(...values);
|
|
926
|
+
return result ?? null;
|
|
819
927
|
}
|
|
820
928
|
|
|
821
929
|
|
|
@@ -843,71 +951,76 @@ function mathRandom() {
|
|
|
843
951
|
// $arg x: The number
|
|
844
952
|
// $arg digits: Optional (default is 0). The number of decimal digits to round to.
|
|
845
953
|
// $return: The rounded number
|
|
846
|
-
function mathRound(
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
}
|
|
850
|
-
|
|
851
|
-
const multiplier = 10 ** digits;
|
|
852
|
-
return Math.round(x * multiplier) / multiplier;
|
|
954
|
+
function mathRound(args) {
|
|
955
|
+
const [x, digits] = valueArgsValidate(mathRoundArgs, args);
|
|
956
|
+
return valueRoundNumber(x, digits);
|
|
853
957
|
}
|
|
854
958
|
|
|
959
|
+
const mathRoundArgs = valueArgsModel([
|
|
960
|
+
{'name': 'x', 'type': 'number'},
|
|
961
|
+
{'name': 'digits', 'type': 'number', 'default': 0, 'integer': true, 'gte': 0}
|
|
962
|
+
]);
|
|
963
|
+
|
|
855
964
|
|
|
856
965
|
// $function: mathSign
|
|
857
966
|
// $group: Math
|
|
858
967
|
// $doc: Compute the sign of a number
|
|
859
968
|
// $arg x: The number
|
|
860
969
|
// $return: -1 for a negative number, 1 for a positive number, and 0 for zero
|
|
861
|
-
function mathSign(
|
|
862
|
-
|
|
863
|
-
return null;
|
|
864
|
-
}
|
|
865
|
-
|
|
970
|
+
function mathSign(args) {
|
|
971
|
+
const [x] = valueArgsValidate(mathSignArgs, args);
|
|
866
972
|
return Math.sign(x);
|
|
867
973
|
}
|
|
868
974
|
|
|
975
|
+
const mathSignArgs = valueArgsModel([
|
|
976
|
+
{'name': 'x', 'type': 'number'}
|
|
977
|
+
]);
|
|
978
|
+
|
|
869
979
|
|
|
870
980
|
// $function: mathSin
|
|
871
981
|
// $group: Math
|
|
872
982
|
// $doc: Compute the sine of an angle, in radians
|
|
873
983
|
// $arg x: The angle, in radians
|
|
874
984
|
// $return: The sine of the angle
|
|
875
|
-
function mathSin(
|
|
876
|
-
|
|
877
|
-
return null;
|
|
878
|
-
}
|
|
879
|
-
|
|
985
|
+
function mathSin(args) {
|
|
986
|
+
const [x] = valueArgsValidate(mathSinArgs, args);
|
|
880
987
|
return Math.sin(x);
|
|
881
988
|
}
|
|
882
989
|
|
|
990
|
+
const mathSinArgs = valueArgsModel([
|
|
991
|
+
{'name': 'x', 'type': 'number'}
|
|
992
|
+
]);
|
|
993
|
+
|
|
883
994
|
|
|
884
995
|
// $function: mathSqrt
|
|
885
996
|
// $group: Math
|
|
886
997
|
// $doc: Compute the square root of a number
|
|
887
998
|
// $arg x: The number
|
|
888
999
|
// $return: The square root of the number
|
|
889
|
-
function mathSqrt(
|
|
890
|
-
|
|
891
|
-
return null;
|
|
892
|
-
}
|
|
893
|
-
|
|
1000
|
+
function mathSqrt(args) {
|
|
1001
|
+
const [x] = valueArgsValidate(mathSqrtArgs, args);
|
|
894
1002
|
return Math.sqrt(x);
|
|
895
1003
|
}
|
|
896
1004
|
|
|
1005
|
+
const mathSqrtArgs = valueArgsModel([
|
|
1006
|
+
{'name': 'x', 'type': 'number', 'gte': 0}
|
|
1007
|
+
]);
|
|
1008
|
+
|
|
897
1009
|
|
|
898
1010
|
// $function: mathTan
|
|
899
1011
|
// $group: Math
|
|
900
1012
|
// $doc: Compute the tangent of an angle, in radians
|
|
901
1013
|
// $arg x: The angle, in radians
|
|
902
1014
|
// $return: The tangent of the angle
|
|
903
|
-
function mathTan(
|
|
904
|
-
|
|
905
|
-
return null;
|
|
906
|
-
}
|
|
907
|
-
|
|
1015
|
+
function mathTan(args) {
|
|
1016
|
+
const [x] = valueArgsValidate(mathTanArgs, args);
|
|
908
1017
|
return Math.tan(x);
|
|
909
1018
|
}
|
|
910
1019
|
|
|
1020
|
+
const mathTanArgs = valueArgsModel([
|
|
1021
|
+
{'name': 'x', 'type': 'number'}
|
|
1022
|
+
]);
|
|
1023
|
+
|
|
911
1024
|
|
|
912
1025
|
//
|
|
913
1026
|
// Number functions
|
|
@@ -919,14 +1032,15 @@ function mathTan([x = null]) {
|
|
|
919
1032
|
// $doc: Parse a string as a floating point number
|
|
920
1033
|
// $arg string: The string
|
|
921
1034
|
// $return: The number
|
|
922
|
-
function numberParseFloat(
|
|
923
|
-
|
|
924
|
-
return null;
|
|
925
|
-
}
|
|
926
|
-
|
|
1035
|
+
function numberParseFloat(args) {
|
|
1036
|
+
const [string] = valueArgsValidate(numberParseFloatArgs, args);
|
|
927
1037
|
return valueParseNumber(string);
|
|
928
1038
|
}
|
|
929
1039
|
|
|
1040
|
+
const numberParseFloatArgs = valueArgsModel([
|
|
1041
|
+
{'name': 'string', 'type': 'string'}
|
|
1042
|
+
]);
|
|
1043
|
+
|
|
930
1044
|
|
|
931
1045
|
// $function: numberParseInt
|
|
932
1046
|
// $group: Number
|
|
@@ -934,14 +1048,16 @@ function numberParseFloat([string = null]) {
|
|
|
934
1048
|
// $arg string: The string
|
|
935
1049
|
// $arg radix: Optional (default is 10). The number base.
|
|
936
1050
|
// $return: The integer
|
|
937
|
-
function numberParseInt(
|
|
938
|
-
|
|
939
|
-
return null;
|
|
940
|
-
}
|
|
941
|
-
|
|
1051
|
+
function numberParseInt(args) {
|
|
1052
|
+
const [string, radix] = valueArgsValidate(numberParseIntArgs, args);
|
|
942
1053
|
return valueParseInteger(string, radix);
|
|
943
1054
|
}
|
|
944
1055
|
|
|
1056
|
+
const numberParseIntArgs = valueArgsModel([
|
|
1057
|
+
{'name': 'string', 'type': 'string'},
|
|
1058
|
+
{'name': 'radix', 'type': 'number', 'default': 10, 'integer': true, 'gte': 2, 'lte': 36}
|
|
1059
|
+
]);
|
|
1060
|
+
|
|
945
1061
|
|
|
946
1062
|
// $function: numberToFixed
|
|
947
1063
|
// $group: Number
|
|
@@ -950,18 +1066,21 @@ function numberParseInt([string = null, radix = 10]) {
|
|
|
950
1066
|
// $arg digits: Optional (default is 2). The number of digits to appear after the decimal point.
|
|
951
1067
|
// $arg trim: Optional (default is false). If true, trim trailing zeroes and decimal point.
|
|
952
1068
|
// $return: The fixed-point notation string
|
|
953
|
-
function numberToFixed(
|
|
954
|
-
|
|
955
|
-
return null;
|
|
956
|
-
}
|
|
957
|
-
|
|
1069
|
+
function numberToFixed(args) {
|
|
1070
|
+
const [x, digits, trim] = valueArgsValidate(numberToFixedArgs, args);
|
|
958
1071
|
let result = x.toFixed(digits);
|
|
959
|
-
if (
|
|
1072
|
+
if (trim) {
|
|
960
1073
|
result = result.replace(rNumberCleanup, '');
|
|
961
1074
|
}
|
|
962
1075
|
return result;
|
|
963
1076
|
}
|
|
964
1077
|
|
|
1078
|
+
const numberToFixedArgs = valueArgsModel([
|
|
1079
|
+
{'name': 'x', 'type': 'number'},
|
|
1080
|
+
{'name': 'digits', 'type': 'number', 'default': 2, 'integer': true, 'gte': 0},
|
|
1081
|
+
{'name': 'trim', 'type': 'boolean', 'default': false}
|
|
1082
|
+
]);
|
|
1083
|
+
|
|
965
1084
|
const rNumberCleanup = /\.0*$/;
|
|
966
1085
|
|
|
967
1086
|
|
|
@@ -976,44 +1095,48 @@ const rNumberCleanup = /\.0*$/;
|
|
|
976
1095
|
// $arg object: The object to assign to
|
|
977
1096
|
// $arg object2: The object to assign
|
|
978
1097
|
// $return: The updated object
|
|
979
|
-
function objectAssign(
|
|
980
|
-
|
|
981
|
-
return null;
|
|
982
|
-
}
|
|
983
|
-
|
|
1098
|
+
function objectAssign(args) {
|
|
1099
|
+
const [object, object2] = valueArgsValidate(objectAssignArgs, args);
|
|
984
1100
|
Object.assign(object, object2);
|
|
985
1101
|
return object;
|
|
986
1102
|
}
|
|
987
1103
|
|
|
1104
|
+
const objectAssignArgs = valueArgsModel([
|
|
1105
|
+
{'name': 'object', 'type': 'object'},
|
|
1106
|
+
{'name': 'object2', 'type': 'object'}
|
|
1107
|
+
]);
|
|
1108
|
+
|
|
988
1109
|
|
|
989
1110
|
// $function: objectCopy
|
|
990
1111
|
// $group: Object
|
|
991
1112
|
// $doc: Create a copy of an object
|
|
992
1113
|
// $arg object: The object to copy
|
|
993
1114
|
// $return: The object copy
|
|
994
|
-
function objectCopy(
|
|
995
|
-
|
|
996
|
-
return null;
|
|
997
|
-
}
|
|
998
|
-
|
|
1115
|
+
function objectCopy(args) {
|
|
1116
|
+
const [object] = valueArgsValidate(objectCopyArgs, args);
|
|
999
1117
|
return {...object};
|
|
1000
1118
|
}
|
|
1001
1119
|
|
|
1120
|
+
const objectCopyArgs = valueArgsModel([
|
|
1121
|
+
{'name': 'object', 'type': 'object'}
|
|
1122
|
+
]);
|
|
1123
|
+
|
|
1002
1124
|
|
|
1003
1125
|
// $function: objectDelete
|
|
1004
1126
|
// $group: Object
|
|
1005
1127
|
// $doc: Delete an object key
|
|
1006
1128
|
// $arg object: The object
|
|
1007
1129
|
// $arg key: The key to delete
|
|
1008
|
-
function objectDelete(
|
|
1009
|
-
|
|
1010
|
-
return null;
|
|
1011
|
-
}
|
|
1012
|
-
|
|
1130
|
+
function objectDelete(args) {
|
|
1131
|
+
const [object, key] = valueArgsValidate(objectDeleteArgs, args);
|
|
1013
1132
|
delete object[key];
|
|
1014
|
-
return null;
|
|
1015
1133
|
}
|
|
1016
1134
|
|
|
1135
|
+
const objectDeleteArgs = valueArgsModel([
|
|
1136
|
+
{'name': 'object', 'type': 'object'},
|
|
1137
|
+
{'name': 'key', 'type': 'string'}
|
|
1138
|
+
]);
|
|
1139
|
+
|
|
1017
1140
|
|
|
1018
1141
|
// $function: objectGet
|
|
1019
1142
|
// $group: Object
|
|
@@ -1022,14 +1145,18 @@ function objectDelete([object = null, key = null]) {
|
|
|
1022
1145
|
// $arg key: The key
|
|
1023
1146
|
// $arg defaultValue: The default value (optional)
|
|
1024
1147
|
// $return: The value or null if the key does not exist
|
|
1025
|
-
function objectGet(
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
}
|
|
1029
|
-
|
|
1148
|
+
function objectGet(args) {
|
|
1149
|
+
const [,,defaultValueArg = null] = args;
|
|
1150
|
+
const [object, key, defaultValue] = valueArgsValidate(objectGetArgs, args, defaultValueArg);
|
|
1030
1151
|
return object[key] ?? defaultValue;
|
|
1031
1152
|
}
|
|
1032
1153
|
|
|
1154
|
+
const objectGetArgs = valueArgsModel([
|
|
1155
|
+
{'name': 'object', 'type': 'object'},
|
|
1156
|
+
{'name': 'key', 'type': 'string'},
|
|
1157
|
+
{'name': 'defaultValue'}
|
|
1158
|
+
]);
|
|
1159
|
+
|
|
1033
1160
|
|
|
1034
1161
|
// $function: objectHas
|
|
1035
1162
|
// $group: Object
|
|
@@ -1037,41 +1164,44 @@ function objectGet([object = null, key = null, defaultValue = null]) {
|
|
|
1037
1164
|
// $arg object: The object
|
|
1038
1165
|
// $arg key: The key
|
|
1039
1166
|
// $return: true if the object contains the key, false otherwise
|
|
1040
|
-
function objectHas(
|
|
1041
|
-
|
|
1042
|
-
return false;
|
|
1043
|
-
}
|
|
1044
|
-
|
|
1167
|
+
function objectHas(args) {
|
|
1168
|
+
const [object, key] = valueArgsValidate(objectHasArgs, args, false);
|
|
1045
1169
|
return key in object;
|
|
1046
1170
|
}
|
|
1047
1171
|
|
|
1172
|
+
const objectHasArgs = valueArgsModel([
|
|
1173
|
+
{'name': 'object', 'type': 'object'},
|
|
1174
|
+
{'name': 'key', 'type': 'string'}
|
|
1175
|
+
]);
|
|
1176
|
+
|
|
1048
1177
|
|
|
1049
1178
|
// $function: objectKeys
|
|
1050
1179
|
// $group: Object
|
|
1051
1180
|
// $doc: Get an object's keys
|
|
1052
1181
|
// $arg object: The object
|
|
1053
1182
|
// $return: The array of keys
|
|
1054
|
-
function objectKeys(
|
|
1055
|
-
|
|
1056
|
-
return null;
|
|
1057
|
-
}
|
|
1058
|
-
|
|
1183
|
+
function objectKeys(args) {
|
|
1184
|
+
const [object] = valueArgsValidate(objectKeysArgs, args);
|
|
1059
1185
|
return Object.keys(object);
|
|
1060
1186
|
}
|
|
1061
1187
|
|
|
1188
|
+
const objectKeysArgs = valueArgsModel([
|
|
1189
|
+
{'name': 'object', 'type': 'object'}
|
|
1190
|
+
]);
|
|
1191
|
+
|
|
1062
1192
|
|
|
1063
1193
|
// $function: objectNew
|
|
1064
1194
|
// $group: Object
|
|
1065
1195
|
// $doc: Create a new object
|
|
1066
1196
|
// $arg keyValues...: The object's initial key and value pairs
|
|
1067
1197
|
// $return: The new object
|
|
1068
|
-
function objectNew(keyValues
|
|
1198
|
+
function objectNew(keyValues) {
|
|
1069
1199
|
const object = {};
|
|
1070
1200
|
for (let ix = 0; ix < keyValues.length; ix += 2) {
|
|
1071
1201
|
const key = keyValues[ix];
|
|
1072
1202
|
const value = ix + 1 < keyValues.length ? keyValues[ix + 1] : null;
|
|
1073
1203
|
if (valueType(key) !== 'string') {
|
|
1074
|
-
|
|
1204
|
+
throw new ValueArgsError('keyValues', key);
|
|
1075
1205
|
}
|
|
1076
1206
|
object[key] = value;
|
|
1077
1207
|
}
|
|
@@ -1086,15 +1216,18 @@ function objectNew(keyValues = null) {
|
|
|
1086
1216
|
// $arg key: The key
|
|
1087
1217
|
// $arg value: The value to set
|
|
1088
1218
|
// $return: The value to set
|
|
1089
|
-
function objectSet(
|
|
1090
|
-
|
|
1091
|
-
return null;
|
|
1092
|
-
}
|
|
1093
|
-
|
|
1219
|
+
function objectSet(args) {
|
|
1220
|
+
const [object, key, value] = valueArgsValidate(objectSetArgs, args);
|
|
1094
1221
|
object[key] = value;
|
|
1095
1222
|
return value;
|
|
1096
1223
|
}
|
|
1097
1224
|
|
|
1225
|
+
const objectSetArgs = valueArgsModel([
|
|
1226
|
+
{'name': 'object', 'type': 'object'},
|
|
1227
|
+
{'name': 'key', 'type': 'string'},
|
|
1228
|
+
{'name': 'value'}
|
|
1229
|
+
]);
|
|
1230
|
+
|
|
1098
1231
|
|
|
1099
1232
|
//
|
|
1100
1233
|
// Regex functions
|
|
@@ -1106,14 +1239,15 @@ function objectSet([object = null, key = null, value = null]) {
|
|
|
1106
1239
|
// $doc: Escape a string for use in a regular expression
|
|
1107
1240
|
// $arg string: The string to escape
|
|
1108
1241
|
// $return: The escaped string
|
|
1109
|
-
function regexEscape(
|
|
1110
|
-
|
|
1111
|
-
return null;
|
|
1112
|
-
}
|
|
1113
|
-
|
|
1242
|
+
function regexEscape(args) {
|
|
1243
|
+
const [string] = valueArgsValidate(regexEscapeArgs, args);
|
|
1114
1244
|
return string.replace(rRegexEscape, '\\$&');
|
|
1115
1245
|
}
|
|
1116
1246
|
|
|
1247
|
+
const regexEscapeArgs = valueArgsModel([
|
|
1248
|
+
{'name': 'string', 'type': 'string'}
|
|
1249
|
+
]);
|
|
1250
|
+
|
|
1117
1251
|
const rRegexEscape = /[.*+?^${}()|[\]\\]/g;
|
|
1118
1252
|
|
|
1119
1253
|
|
|
@@ -1123,20 +1257,17 @@ const rRegexEscape = /[.*+?^${}()|[\]\\]/g;
|
|
|
1123
1257
|
// $arg regex: The regular expression
|
|
1124
1258
|
// $arg string: The string
|
|
1125
1259
|
// $return: The [match object](model.html#var.vName='RegexMatch'), or null if no matches are found
|
|
1126
|
-
function regexMatch(
|
|
1127
|
-
|
|
1128
|
-
return null;
|
|
1129
|
-
}
|
|
1130
|
-
|
|
1131
|
-
// Match?
|
|
1260
|
+
function regexMatch(args) {
|
|
1261
|
+
const [regex, string] = valueArgsValidate(regexMatchArgs, args);
|
|
1132
1262
|
const match = string.match(regex);
|
|
1133
|
-
|
|
1134
|
-
return null;
|
|
1135
|
-
}
|
|
1136
|
-
|
|
1137
|
-
return regexMatchGroups(match);
|
|
1263
|
+
return match !== null ? regexMatchGroups(match) : null;
|
|
1138
1264
|
}
|
|
1139
1265
|
|
|
1266
|
+
const regexMatchArgs = valueArgsModel([
|
|
1267
|
+
{'name': 'regex', 'type': 'regex'},
|
|
1268
|
+
{'name': 'string', 'type': 'string'}
|
|
1269
|
+
]);
|
|
1270
|
+
|
|
1140
1271
|
|
|
1141
1272
|
// $function: regexMatchAll
|
|
1142
1273
|
// $group: Regex
|
|
@@ -1144,10 +1275,8 @@ function regexMatch([regex = null, string = null]) {
|
|
|
1144
1275
|
// $arg regex: The regular expression
|
|
1145
1276
|
// $arg string: The string
|
|
1146
1277
|
// $return: The array of [match objects](model.html#var.vName='RegexMatch')
|
|
1147
|
-
function regexMatchAll(
|
|
1148
|
-
|
|
1149
|
-
return null;
|
|
1150
|
-
}
|
|
1278
|
+
function regexMatchAll(args) {
|
|
1279
|
+
const [regex, string] = valueArgsValidate(regexMatchAllArgs, args);
|
|
1151
1280
|
|
|
1152
1281
|
// Re-compile the regex with the "g" flag, if necessary
|
|
1153
1282
|
const regexGlobal = (regex.flags.indexOf('g') !== -1 ? regex : new RegExp(regex.source, `${regex.flags}g`));
|
|
@@ -1155,6 +1284,11 @@ function regexMatchAll([regex = null, string = null]) {
|
|
|
1155
1284
|
return Array.from(string.matchAll(regexGlobal)).map((match) => regexMatchGroups(match));
|
|
1156
1285
|
}
|
|
1157
1286
|
|
|
1287
|
+
const regexMatchAllArgs = valueArgsModel([
|
|
1288
|
+
{'name': 'regex', 'type': 'regex'},
|
|
1289
|
+
{'name': 'string', 'type': 'string'}
|
|
1290
|
+
]);
|
|
1291
|
+
|
|
1158
1292
|
|
|
1159
1293
|
// Helper function to create a match model from a metch object
|
|
1160
1294
|
function regexMatchGroups(match) {
|
|
@@ -1204,10 +1338,8 @@ struct RegexMatch
|
|
|
1204
1338
|
// $arg flags: - **m** - multi-line search - "^" and "$" matches next to newline characters
|
|
1205
1339
|
// $arg flags: - **s** - "." matches newline characters
|
|
1206
1340
|
// $return: The regular expression or null if the pattern is invalid
|
|
1207
|
-
function regexNew(
|
|
1208
|
-
|
|
1209
|
-
return null;
|
|
1210
|
-
}
|
|
1341
|
+
function regexNew(args) {
|
|
1342
|
+
const [pattern, flags] = valueArgsValidate(regexNewArgs, args);
|
|
1211
1343
|
|
|
1212
1344
|
// Valid flags mask?
|
|
1213
1345
|
if (flags !== null) {
|
|
@@ -1221,6 +1353,11 @@ function regexNew([pattern = null, flags = null]) {
|
|
|
1221
1353
|
return flags !== null ? new RegExp(pattern, flags) : new RegExp(pattern);
|
|
1222
1354
|
}
|
|
1223
1355
|
|
|
1356
|
+
const regexNewArgs = valueArgsModel([
|
|
1357
|
+
{'name': 'pattern', 'type': 'string'},
|
|
1358
|
+
{'name': 'flags', 'type': 'string', 'nullable': true}
|
|
1359
|
+
]);
|
|
1360
|
+
|
|
1224
1361
|
|
|
1225
1362
|
// $function: regexReplace
|
|
1226
1363
|
// $group: Regex
|
|
@@ -1229,10 +1366,8 @@ function regexNew([pattern = null, flags = null]) {
|
|
|
1229
1366
|
// $arg string: The string
|
|
1230
1367
|
// $arg substr: The replacement string
|
|
1231
1368
|
// $return: The updated string
|
|
1232
|
-
function regexReplace(
|
|
1233
|
-
|
|
1234
|
-
return null;
|
|
1235
|
-
}
|
|
1369
|
+
function regexReplace(args) {
|
|
1370
|
+
const [regex, string, substr] = valueArgsValidate(regexReplaceArgs, args);
|
|
1236
1371
|
|
|
1237
1372
|
// Re-compile the regex with the "g" flag, if necessary
|
|
1238
1373
|
const regexGlobal = (regex.flags.indexOf('g') !== -1 ? regex : new RegExp(regex.source, `${regex.flags}g`));
|
|
@@ -1240,6 +1375,12 @@ function regexReplace([regex = null, string = null, substr = null]) {
|
|
|
1240
1375
|
return string.replaceAll(regexGlobal, substr);
|
|
1241
1376
|
}
|
|
1242
1377
|
|
|
1378
|
+
const regexReplaceArgs = valueArgsModel([
|
|
1379
|
+
{'name': 'regex', 'type': 'regex'},
|
|
1380
|
+
{'name': 'string', 'type': 'string'},
|
|
1381
|
+
{'name': 'substr', 'type': 'string'}
|
|
1382
|
+
]);
|
|
1383
|
+
|
|
1243
1384
|
|
|
1244
1385
|
// $function: regexSplit
|
|
1245
1386
|
// $group: Regex
|
|
@@ -1247,14 +1388,16 @@ function regexReplace([regex = null, string = null, substr = null]) {
|
|
|
1247
1388
|
// $arg regex: The regular expression
|
|
1248
1389
|
// $arg string: The string
|
|
1249
1390
|
// $return: The array of split parts
|
|
1250
|
-
function regexSplit(
|
|
1251
|
-
|
|
1252
|
-
return null;
|
|
1253
|
-
}
|
|
1254
|
-
|
|
1391
|
+
function regexSplit(args) {
|
|
1392
|
+
const [regex, string] = valueArgsValidate(regexSplitArgs, args);
|
|
1255
1393
|
return string.split(regex);
|
|
1256
1394
|
}
|
|
1257
1395
|
|
|
1396
|
+
const regexSplitArgs = valueArgsModel([
|
|
1397
|
+
{'name': 'regex', 'type': 'regex'},
|
|
1398
|
+
{'name': 'string', 'type': 'string'}
|
|
1399
|
+
]);
|
|
1400
|
+
|
|
1258
1401
|
|
|
1259
1402
|
//
|
|
1260
1403
|
// Schema functions
|
|
@@ -1280,15 +1423,23 @@ function schemaParse(lines) {
|
|
|
1280
1423
|
// $arg types: Optional. The [type model](https://craigahobbs.github.io/schema-markdown-doc/doc/#var.vName='Types').
|
|
1281
1424
|
// $arg filename: Optional (default is ""). The file name.
|
|
1282
1425
|
// $return: The schema's [type model](https://craigahobbs.github.io/schema-markdown-doc/doc/#var.vName='Types')
|
|
1283
|
-
function schemaParseEx(
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1426
|
+
function schemaParseEx(args) {
|
|
1427
|
+
const [lines, typesArg, filename] = valueArgsValidate(schemaParseExArgs, args);
|
|
1428
|
+
const linesType = valueType(lines);
|
|
1429
|
+
const types = typesArg !== null ? typesArg : {};
|
|
1430
|
+
if (linesType !== 'array' && linesType !== 'string') {
|
|
1431
|
+
throw new ValueArgsError('lines', lines);
|
|
1287
1432
|
}
|
|
1288
1433
|
|
|
1289
1434
|
return parseSchemaMarkdown(lines, {types, filename});
|
|
1290
1435
|
}
|
|
1291
1436
|
|
|
1437
|
+
const schemaParseExArgs = valueArgsModel([
|
|
1438
|
+
{'name': 'lines'},
|
|
1439
|
+
{'name': 'types', 'type': 'object', 'nullable': true},
|
|
1440
|
+
{'name': 'filename', 'type': 'string', 'default': ''}
|
|
1441
|
+
]);
|
|
1442
|
+
|
|
1292
1443
|
|
|
1293
1444
|
// $function: schemaTypeModel
|
|
1294
1445
|
// $group: Schema
|
|
@@ -1306,29 +1457,33 @@ function schemaTypeModel() {
|
|
|
1306
1457
|
// $arg typeName: The type name
|
|
1307
1458
|
// $arg value: The object to validate
|
|
1308
1459
|
// $return: The validated object or null if validation fails
|
|
1309
|
-
function schemaValidate(
|
|
1310
|
-
|
|
1311
|
-
return null;
|
|
1312
|
-
}
|
|
1313
|
-
|
|
1460
|
+
function schemaValidate(args) {
|
|
1461
|
+
const [types, typeName, value] = valueArgsValidate(schemaValidateArgs, args);
|
|
1314
1462
|
validateTypeModel(types);
|
|
1315
1463
|
return validateType(types, typeName, value);
|
|
1316
1464
|
}
|
|
1317
1465
|
|
|
1466
|
+
const schemaValidateArgs = valueArgsModel([
|
|
1467
|
+
{'name': 'types', 'type': 'object'},
|
|
1468
|
+
{'name': 'typeName', 'type': 'string'},
|
|
1469
|
+
{'name': 'value'}
|
|
1470
|
+
]);
|
|
1471
|
+
|
|
1318
1472
|
|
|
1319
1473
|
// $function: schemaValidateTypeModel
|
|
1320
1474
|
// $group: Schema
|
|
1321
1475
|
// $doc: Validate a [Schema Markdown Type Model](https://craigahobbs.github.io/schema-markdown-doc/doc/#var.vName='Types')
|
|
1322
1476
|
// $arg types: The [type model](https://craigahobbs.github.io/schema-markdown-doc/doc/#var.vName='Types') to validate
|
|
1323
1477
|
// $return: The validated [type model](https://craigahobbs.github.io/schema-markdown-doc/doc/#var.vName='Types')
|
|
1324
|
-
function schemaValidateTypeModel(
|
|
1325
|
-
|
|
1326
|
-
return null;
|
|
1327
|
-
}
|
|
1328
|
-
|
|
1478
|
+
function schemaValidateTypeModel(args) {
|
|
1479
|
+
const [types] = valueArgsValidate(schemaValidateTypeModelArgs, args);
|
|
1329
1480
|
return validateTypeModel(types);
|
|
1330
1481
|
}
|
|
1331
1482
|
|
|
1483
|
+
const schemaValidateTypeModelArgs = valueArgsModel([
|
|
1484
|
+
{'name': 'types', 'type': 'object'}
|
|
1485
|
+
]);
|
|
1486
|
+
|
|
1332
1487
|
|
|
1333
1488
|
//
|
|
1334
1489
|
// String functions
|
|
@@ -1341,15 +1496,20 @@ function schemaValidateTypeModel([types = null]) {
|
|
|
1341
1496
|
// $arg string: The string
|
|
1342
1497
|
// $arg index: The character index
|
|
1343
1498
|
// $return: The character code
|
|
1344
|
-
function stringCharCodeAt(
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1499
|
+
function stringCharCodeAt(args) {
|
|
1500
|
+
const [string, index] = valueArgsValidate(stringCharCodeAtArgs, args);
|
|
1501
|
+
if (index >= string.length) {
|
|
1502
|
+
throw new ValueArgsError('index', index);
|
|
1348
1503
|
}
|
|
1349
1504
|
|
|
1350
1505
|
return string.charCodeAt(index);
|
|
1351
1506
|
}
|
|
1352
1507
|
|
|
1508
|
+
const stringCharCodeAtArgs = valueArgsModel([
|
|
1509
|
+
{'name': 'string', 'type': 'string'},
|
|
1510
|
+
{'name': 'index', 'type': 'number', 'integer': true, 'gte': 0}
|
|
1511
|
+
]);
|
|
1512
|
+
|
|
1353
1513
|
|
|
1354
1514
|
// $function: stringEndsWith
|
|
1355
1515
|
// $group: String
|
|
@@ -1357,23 +1517,27 @@ function stringCharCodeAt([string = null, index = null]) {
|
|
|
1357
1517
|
// $arg string: The string
|
|
1358
1518
|
// $arg search: The search string
|
|
1359
1519
|
// $return: true if the string ends with the search string, false otherwise
|
|
1360
|
-
function stringEndsWith(
|
|
1361
|
-
|
|
1362
|
-
return null;
|
|
1363
|
-
}
|
|
1364
|
-
|
|
1520
|
+
function stringEndsWith(args) {
|
|
1521
|
+
const [string, search] = valueArgsValidate(stringEndsWithArgs, args);
|
|
1365
1522
|
return string.endsWith(search);
|
|
1366
1523
|
}
|
|
1367
1524
|
|
|
1525
|
+
const stringEndsWithArgs = valueArgsModel([
|
|
1526
|
+
{'name': 'string', 'type': 'string'},
|
|
1527
|
+
{'name': 'search', 'type': 'string'}
|
|
1528
|
+
]);
|
|
1529
|
+
|
|
1368
1530
|
|
|
1369
1531
|
// $function: stringFromCharCode
|
|
1370
1532
|
// $group: String
|
|
1371
1533
|
// $doc: Create a string of characters from character codes
|
|
1372
1534
|
// $arg charCodes...: The character codes
|
|
1373
1535
|
// $return: The string of characters
|
|
1374
|
-
function stringFromCharCode(charCodes
|
|
1375
|
-
|
|
1376
|
-
|
|
1536
|
+
function stringFromCharCode(charCodes) {
|
|
1537
|
+
for (const code of charCodes) {
|
|
1538
|
+
if (valueType(code) !== 'number' || Math.floor(code) !== code || code < 0) {
|
|
1539
|
+
throw new ValueArgsError('charCodes', code);
|
|
1540
|
+
}
|
|
1377
1541
|
}
|
|
1378
1542
|
|
|
1379
1543
|
return String.fromCharCode(...charCodes);
|
|
@@ -1387,15 +1551,21 @@ function stringFromCharCode(charCodes = null) {
|
|
|
1387
1551
|
// $arg search: The search string
|
|
1388
1552
|
// $arg index: Optional (default is 0). The index at which to start the search.
|
|
1389
1553
|
// $return: The first index of the search string; -1 if not found.
|
|
1390
|
-
function stringIndexOf(
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1554
|
+
function stringIndexOf(args) {
|
|
1555
|
+
const [string, search, index] = valueArgsValidate(stringIndexOfArgs, args, -1);
|
|
1556
|
+
if (index >= string.length) {
|
|
1557
|
+
throw new ValueArgsError('index', index, -1);
|
|
1394
1558
|
}
|
|
1395
1559
|
|
|
1396
1560
|
return string.indexOf(search, index);
|
|
1397
1561
|
}
|
|
1398
1562
|
|
|
1563
|
+
const stringIndexOfArgs = valueArgsModel([
|
|
1564
|
+
{'name': 'string', 'type': 'string'},
|
|
1565
|
+
{'name': 'search', 'type': 'string'},
|
|
1566
|
+
{'name': 'index', 'type': 'number', 'default': 0, 'integer': true, 'gte': 0}
|
|
1567
|
+
]);
|
|
1568
|
+
|
|
1399
1569
|
|
|
1400
1570
|
// $function: stringLastIndexOf
|
|
1401
1571
|
// $group: String
|
|
@@ -1404,47 +1574,52 @@ function stringIndexOf([string = null, search = null, index = 0]) {
|
|
|
1404
1574
|
// $arg search: The search string
|
|
1405
1575
|
// $arg index: Optional (default is the end of the string). The index at which to start the search.
|
|
1406
1576
|
// $return: The last index of the search string; -1 if not found.
|
|
1407
|
-
function stringLastIndexOf(
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
if (valueType(string) !== 'string' || valueType(search) !== 'string' ||
|
|
1413
|
-
valueType(index) !== 'number' || Math.floor(index) !== index || index < 0 || index >= string.length) {
|
|
1414
|
-
return -1;
|
|
1577
|
+
function stringLastIndexOf(args) {
|
|
1578
|
+
const [string, search, indexArg] = valueArgsValidate(stringLastIndexOfArgs, args, -1);
|
|
1579
|
+
const index = indexArg !== null ? indexArg : string.length - 1;
|
|
1580
|
+
if (index >= string.length) {
|
|
1581
|
+
throw new ValueArgsError('index', index, -1);
|
|
1415
1582
|
}
|
|
1416
1583
|
|
|
1417
1584
|
return string.lastIndexOf(search, index);
|
|
1418
1585
|
}
|
|
1419
1586
|
|
|
1587
|
+
const stringLastIndexOfArgs = valueArgsModel([
|
|
1588
|
+
{'name': 'string', 'type': 'string'},
|
|
1589
|
+
{'name': 'search', 'type': 'string'},
|
|
1590
|
+
{'name': 'index', 'type': 'number', 'nullable': true, 'integer': true, 'gte': 0}
|
|
1591
|
+
]);
|
|
1592
|
+
|
|
1420
1593
|
|
|
1421
1594
|
// $function: stringLength
|
|
1422
1595
|
// $group: String
|
|
1423
1596
|
// $doc: Get the length of a string
|
|
1424
1597
|
// $arg string: The string
|
|
1425
1598
|
// $return: The string's length; zero if not a string
|
|
1426
|
-
function stringLength(
|
|
1427
|
-
|
|
1428
|
-
return 0;
|
|
1429
|
-
}
|
|
1430
|
-
|
|
1599
|
+
function stringLength(args) {
|
|
1600
|
+
const [string] = valueArgsValidate(stringLengthArgs, args, 0);
|
|
1431
1601
|
return string.length;
|
|
1432
1602
|
}
|
|
1433
1603
|
|
|
1604
|
+
const stringLengthArgs = valueArgsModel([
|
|
1605
|
+
{'name': 'string', 'type': 'string'}
|
|
1606
|
+
]);
|
|
1607
|
+
|
|
1434
1608
|
|
|
1435
1609
|
// $function: stringLower
|
|
1436
1610
|
// $group: String
|
|
1437
1611
|
// $doc: Convert a string to lower-case
|
|
1438
1612
|
// $arg string: The string
|
|
1439
1613
|
// $return: The lower-case string
|
|
1440
|
-
function stringLower(
|
|
1441
|
-
|
|
1442
|
-
return null;
|
|
1443
|
-
}
|
|
1444
|
-
|
|
1614
|
+
function stringLower(args) {
|
|
1615
|
+
const [string] = valueArgsValidate(stringLowerArgs, args);
|
|
1445
1616
|
return string.toLowerCase();
|
|
1446
1617
|
}
|
|
1447
1618
|
|
|
1619
|
+
const stringLowerArgs = valueArgsModel([
|
|
1620
|
+
{'name': 'string', 'type': 'string'}
|
|
1621
|
+
]);
|
|
1622
|
+
|
|
1448
1623
|
|
|
1449
1624
|
// $function: stringNew
|
|
1450
1625
|
// $group: String
|
|
@@ -1462,14 +1637,16 @@ function stringNew([value = null]) {
|
|
|
1462
1637
|
// $arg string: The string to repeat
|
|
1463
1638
|
// $arg count: The number of times to repeat the string
|
|
1464
1639
|
// $return: The repeated string
|
|
1465
|
-
function stringRepeat(
|
|
1466
|
-
|
|
1467
|
-
return null;
|
|
1468
|
-
}
|
|
1469
|
-
|
|
1640
|
+
function stringRepeat(args) {
|
|
1641
|
+
const [string, count] = valueArgsValidate(stringRepeatArgs, args);
|
|
1470
1642
|
return string.repeat(count);
|
|
1471
1643
|
}
|
|
1472
1644
|
|
|
1645
|
+
const stringRepeatArgs = valueArgsModel([
|
|
1646
|
+
{'name': 'string', 'type': 'string'},
|
|
1647
|
+
{'name': 'count', 'type': 'number', 'integer': true, 'gte': 0}
|
|
1648
|
+
]);
|
|
1649
|
+
|
|
1473
1650
|
|
|
1474
1651
|
// $function: stringReplace
|
|
1475
1652
|
// $group: String
|
|
@@ -1478,14 +1655,17 @@ function stringRepeat([string = null, count = null]) {
|
|
|
1478
1655
|
// $arg substr: The string to replace
|
|
1479
1656
|
// $arg newSubstr: The replacement string
|
|
1480
1657
|
// $return: The updated string
|
|
1481
|
-
function stringReplace(
|
|
1482
|
-
|
|
1483
|
-
return null;
|
|
1484
|
-
}
|
|
1485
|
-
|
|
1658
|
+
function stringReplace(args) {
|
|
1659
|
+
const [string, substr, newSubstr] = valueArgsValidate(stringReplaceArgs, args);
|
|
1486
1660
|
return string.replaceAll(substr, newSubstr);
|
|
1487
1661
|
}
|
|
1488
1662
|
|
|
1663
|
+
const stringReplaceArgs = valueArgsModel([
|
|
1664
|
+
{'name': 'string', 'type': 'string'},
|
|
1665
|
+
{'name': 'substr', 'type': 'string'},
|
|
1666
|
+
{'name': 'newSubstr', 'type': 'string'}
|
|
1667
|
+
]);
|
|
1668
|
+
|
|
1489
1669
|
|
|
1490
1670
|
// $function: stringSlice
|
|
1491
1671
|
// $group: String
|
|
@@ -1494,20 +1674,25 @@ function stringReplace([string = null, substr = null, newSubstr = null]) {
|
|
|
1494
1674
|
// $arg start: The start index of the slice
|
|
1495
1675
|
// $arg end: Optional (default is the end of the string). The end index of the slice.
|
|
1496
1676
|
// $return: The new string slice
|
|
1497
|
-
function stringSlice(
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1677
|
+
function stringSlice(args) {
|
|
1678
|
+
const [string, start, endArg] = valueArgsValidate(stringSliceArgs, args);
|
|
1679
|
+
const end = endArg !== null ? endArg : string.length;
|
|
1680
|
+
if (start > string.length) {
|
|
1681
|
+
throw new ValueArgsError('start', start);
|
|
1501
1682
|
}
|
|
1502
|
-
if (
|
|
1503
|
-
|
|
1504
|
-
valueType(end) !== 'number' || Math.floor(end) !== end || end < 0 || end > string.length) {
|
|
1505
|
-
return null;
|
|
1683
|
+
if (end > string.length) {
|
|
1684
|
+
throw new ValueArgsError('end', end);
|
|
1506
1685
|
}
|
|
1507
1686
|
|
|
1508
|
-
return string.slice(
|
|
1687
|
+
return string.slice(start, end);
|
|
1509
1688
|
}
|
|
1510
1689
|
|
|
1690
|
+
const stringSliceArgs = valueArgsModel([
|
|
1691
|
+
{'name': 'string', 'type': 'string'},
|
|
1692
|
+
{'name': 'start', 'type': 'number', 'integer': true, 'gte': 0},
|
|
1693
|
+
{'name': 'end', 'type': 'number', 'nullable': true, 'integer': true, 'gte': 0}
|
|
1694
|
+
]);
|
|
1695
|
+
|
|
1511
1696
|
|
|
1512
1697
|
// $function: stringSplit
|
|
1513
1698
|
// $group: String
|
|
@@ -1515,14 +1700,16 @@ function stringSlice([string = null, begin = null, endArg = null]) {
|
|
|
1515
1700
|
// $arg string: The string to split
|
|
1516
1701
|
// $arg separator: The separator string
|
|
1517
1702
|
// $return: The array of split-out strings
|
|
1518
|
-
function stringSplit(
|
|
1519
|
-
|
|
1520
|
-
return null;
|
|
1521
|
-
}
|
|
1522
|
-
|
|
1703
|
+
function stringSplit(args) {
|
|
1704
|
+
const [string, separator] = valueArgsValidate(stringSplitArgs, args);
|
|
1523
1705
|
return string.split(separator);
|
|
1524
1706
|
}
|
|
1525
1707
|
|
|
1708
|
+
const stringSplitArgs = valueArgsModel([
|
|
1709
|
+
{'name': 'string', 'type': 'string'},
|
|
1710
|
+
{'name': 'separator', 'type': 'string'}
|
|
1711
|
+
]);
|
|
1712
|
+
|
|
1526
1713
|
|
|
1527
1714
|
// $function: stringStartsWith
|
|
1528
1715
|
// $group: String
|
|
@@ -1530,42 +1717,46 @@ function stringSplit([string = null, separator = null]) {
|
|
|
1530
1717
|
// $arg string: The string
|
|
1531
1718
|
// $arg search: The search string
|
|
1532
1719
|
// $return: true if the string starts with the search string, false otherwise
|
|
1533
|
-
function stringStartsWith(
|
|
1534
|
-
|
|
1535
|
-
return null;
|
|
1536
|
-
}
|
|
1537
|
-
|
|
1720
|
+
function stringStartsWith(args) {
|
|
1721
|
+
const [string, search] = valueArgsValidate(stringStartsWithArgs, args);
|
|
1538
1722
|
return string.startsWith(search);
|
|
1539
1723
|
}
|
|
1540
1724
|
|
|
1725
|
+
const stringStartsWithArgs = valueArgsModel([
|
|
1726
|
+
{'name': 'string', 'type': 'string'},
|
|
1727
|
+
{'name': 'search', 'type': 'string'}
|
|
1728
|
+
]);
|
|
1729
|
+
|
|
1541
1730
|
|
|
1542
1731
|
// $function: stringTrim
|
|
1543
1732
|
// $group: String
|
|
1544
1733
|
// $doc: Trim the whitespace from the beginning and end of a string
|
|
1545
1734
|
// $arg string: The string
|
|
1546
1735
|
// $return: The trimmed string
|
|
1547
|
-
function stringTrim(
|
|
1548
|
-
|
|
1549
|
-
return null;
|
|
1550
|
-
}
|
|
1551
|
-
|
|
1736
|
+
function stringTrim(args) {
|
|
1737
|
+
const [string] = valueArgsValidate(stringTrimArgs, args);
|
|
1552
1738
|
return string.trim();
|
|
1553
1739
|
}
|
|
1554
1740
|
|
|
1741
|
+
const stringTrimArgs = valueArgsModel([
|
|
1742
|
+
{'name': 'string', 'type': 'string'}
|
|
1743
|
+
]);
|
|
1744
|
+
|
|
1555
1745
|
|
|
1556
1746
|
// $function: stringUpper
|
|
1557
1747
|
// $group: String
|
|
1558
1748
|
// $doc: Convert a string to upper-case
|
|
1559
1749
|
// $arg string: The string
|
|
1560
1750
|
// $return: The upper-case string
|
|
1561
|
-
function stringUpper(
|
|
1562
|
-
|
|
1563
|
-
return null;
|
|
1564
|
-
}
|
|
1565
|
-
|
|
1751
|
+
function stringUpper(args) {
|
|
1752
|
+
const [string] = valueArgsValidate(stringUpperArgs, args);
|
|
1566
1753
|
return string.toUpperCase();
|
|
1567
1754
|
}
|
|
1568
1755
|
|
|
1756
|
+
const stringUpperArgs = valueArgsModel([
|
|
1757
|
+
{'name': 'string', 'type': 'string'}
|
|
1758
|
+
]);
|
|
1759
|
+
|
|
1569
1760
|
|
|
1570
1761
|
//
|
|
1571
1762
|
// System functions
|
|
@@ -1608,11 +1799,12 @@ async function systemFetch([url = null], options) {
|
|
|
1608
1799
|
// Validate the URL argument
|
|
1609
1800
|
const requests = [];
|
|
1610
1801
|
let isResponseArray = false;
|
|
1611
|
-
|
|
1802
|
+
const urlType = valueType(url);
|
|
1803
|
+
if (urlType === 'string') {
|
|
1612
1804
|
requests.push({'url': url});
|
|
1613
|
-
} else if (
|
|
1805
|
+
} else if (urlType === 'object') {
|
|
1614
1806
|
requests.push(validateType(systemFetchTypes, 'SystemFetchRequest', url));
|
|
1615
|
-
} else if (
|
|
1807
|
+
} else if (urlType === 'array') {
|
|
1616
1808
|
isResponseArray = true;
|
|
1617
1809
|
for (const urlItem of url) {
|
|
1618
1810
|
if (valueType(urlItem) === 'string') {
|
|
@@ -1622,7 +1814,7 @@ async function systemFetch([url = null], options) {
|
|
|
1622
1814
|
}
|
|
1623
1815
|
}
|
|
1624
1816
|
} else {
|
|
1625
|
-
|
|
1817
|
+
throw new ValueArgsError('url', url);
|
|
1626
1818
|
}
|
|
1627
1819
|
|
|
1628
1820
|
// Fetch in parallel
|
|
@@ -1687,15 +1879,17 @@ struct SystemFetchRequest
|
|
|
1687
1879
|
// $arg name: The global variable name
|
|
1688
1880
|
// $arg defaultValue: The default value (optional)
|
|
1689
1881
|
// $return: The global variable's value or null if it does not exist
|
|
1690
|
-
function systemGlobalGet(
|
|
1691
|
-
|
|
1692
|
-
return defaultValue;
|
|
1693
|
-
}
|
|
1694
|
-
|
|
1882
|
+
function systemGlobalGet(args, options) {
|
|
1883
|
+
const [name, defaultValue] = valueArgsValidate(systemGlobalGetArgs, args);
|
|
1695
1884
|
const globals = (options !== null ? (options.globals ?? null) : null);
|
|
1696
1885
|
return globals !== null ? (globals[name] ?? defaultValue) : defaultValue;
|
|
1697
1886
|
}
|
|
1698
1887
|
|
|
1888
|
+
const systemGlobalGetArgs = valueArgsModel([
|
|
1889
|
+
{'name': 'name', 'type': 'string'},
|
|
1890
|
+
{'name': 'defaultValue'}
|
|
1891
|
+
]);
|
|
1892
|
+
|
|
1699
1893
|
|
|
1700
1894
|
// $function: systemGlobalSet
|
|
1701
1895
|
// $group: System
|
|
@@ -1703,11 +1897,8 @@ function systemGlobalGet([name = null, defaultValue = null], options) {
|
|
|
1703
1897
|
// $arg name: The global variable name
|
|
1704
1898
|
// $arg value: The global variable's value
|
|
1705
1899
|
// $return: The global variable's value
|
|
1706
|
-
function systemGlobalSet(
|
|
1707
|
-
|
|
1708
|
-
return null;
|
|
1709
|
-
}
|
|
1710
|
-
|
|
1900
|
+
function systemGlobalSet(args, options) {
|
|
1901
|
+
const [name, value] = valueArgsValidate(systemGlobalSetArgs, args);
|
|
1711
1902
|
const globals = (options !== null ? (options.globals ?? null) : null);
|
|
1712
1903
|
if (globals !== null) {
|
|
1713
1904
|
globals[name] = value;
|
|
@@ -1715,6 +1906,11 @@ function systemGlobalSet([name = null, value = null], options) {
|
|
|
1715
1906
|
return value;
|
|
1716
1907
|
}
|
|
1717
1908
|
|
|
1909
|
+
const systemGlobalSetArgs = valueArgsModel([
|
|
1910
|
+
{'name': 'name', 'type': 'string'},
|
|
1911
|
+
{'name': 'value'}
|
|
1912
|
+
]);
|
|
1913
|
+
|
|
1718
1914
|
|
|
1719
1915
|
// $function: systemIs
|
|
1720
1916
|
// $group: System
|
|
@@ -1756,14 +1952,20 @@ function systemLogDebug([message = null], options) {
|
|
|
1756
1952
|
// $arg func: The function
|
|
1757
1953
|
// $arg args...: The function arguments
|
|
1758
1954
|
// $return: The new function called with "args"
|
|
1759
|
-
function systemPartial(
|
|
1760
|
-
|
|
1761
|
-
|
|
1955
|
+
function systemPartial(args) {
|
|
1956
|
+
const [func, funcArgs] = valueArgsValidate(systemPartialArgs, args);
|
|
1957
|
+
if (funcArgs.length < 1) {
|
|
1958
|
+
throw new ValueArgsError('args', funcArgs);
|
|
1762
1959
|
}
|
|
1763
1960
|
|
|
1764
|
-
return (argsExtra, options) => func([...
|
|
1961
|
+
return (argsExtra, options) => func([...funcArgs, ...argsExtra], options);
|
|
1765
1962
|
}
|
|
1766
1963
|
|
|
1964
|
+
const systemPartialArgs = valueArgsModel([
|
|
1965
|
+
{'name': 'func', 'type': 'function'},
|
|
1966
|
+
{'name': 'args', 'lastArgArray': true}
|
|
1967
|
+
]);
|
|
1968
|
+
|
|
1767
1969
|
|
|
1768
1970
|
// $function: systemType
|
|
1769
1971
|
// $group: System
|
|
@@ -1787,19 +1989,21 @@ function systemType([value = null]) {
|
|
|
1787
1989
|
// $arg url: The URL string
|
|
1788
1990
|
// $arg extra: Optional (default is true). If true, encode extra characters for wider compatibility.
|
|
1789
1991
|
// $return: The encoded URL string
|
|
1790
|
-
function urlEncode(
|
|
1791
|
-
|
|
1792
|
-
return null;
|
|
1793
|
-
}
|
|
1794
|
-
|
|
1992
|
+
function urlEncode(args) {
|
|
1993
|
+
const [url, extra] = valueArgsValidate(urlEncodeArgs, args);
|
|
1795
1994
|
let urlEncoded = encodeURI(url);
|
|
1796
|
-
if (
|
|
1995
|
+
if (extra) {
|
|
1797
1996
|
// Replace ')' with '%29' for Markdown links
|
|
1798
1997
|
urlEncoded = urlEncoded.replaceAll(')', '%29');
|
|
1799
1998
|
}
|
|
1800
1999
|
return urlEncoded;
|
|
1801
2000
|
}
|
|
1802
2001
|
|
|
2002
|
+
const urlEncodeArgs = valueArgsModel([
|
|
2003
|
+
{'name': 'url', 'type': 'string'},
|
|
2004
|
+
{'name': 'extra', 'type': 'boolean', 'default': true}
|
|
2005
|
+
]);
|
|
2006
|
+
|
|
1803
2007
|
|
|
1804
2008
|
// $function: urlEncodeComponent
|
|
1805
2009
|
// $group: URL
|
|
@@ -1807,19 +2011,21 @@ function urlEncode([url = null, extra = true]) {
|
|
|
1807
2011
|
// $arg url: The URL component string
|
|
1808
2012
|
// $arg extra: Optional (default is true). If true, encode extra characters for wider compatibility.
|
|
1809
2013
|
// $return: The encoded URL component string
|
|
1810
|
-
function urlEncodeComponent(
|
|
1811
|
-
|
|
1812
|
-
return null;
|
|
1813
|
-
}
|
|
1814
|
-
|
|
2014
|
+
function urlEncodeComponent(args) {
|
|
2015
|
+
const [url, extra] = valueArgsValidate(urlEncodeComponentArgs, args);
|
|
1815
2016
|
let urlEncoded = encodeURIComponent(url);
|
|
1816
|
-
if (
|
|
2017
|
+
if (extra) {
|
|
1817
2018
|
// Replace ')' with '%29' for Markdown links
|
|
1818
2019
|
urlEncoded = urlEncoded.replaceAll(')', '%29');
|
|
1819
2020
|
}
|
|
1820
2021
|
return urlEncoded;
|
|
1821
2022
|
}
|
|
1822
2023
|
|
|
2024
|
+
const urlEncodeComponentArgs = valueArgsModel([
|
|
2025
|
+
{'name': 'url', 'type': 'string'},
|
|
2026
|
+
{'name': 'extra', 'type': 'boolean', 'default': true}
|
|
2027
|
+
]);
|
|
2028
|
+
|
|
1823
2029
|
|
|
1824
2030
|
// The built-in script functions
|
|
1825
2031
|
export const scriptFunctions = {
|