@aemforms/af-core 0.22.26 → 0.22.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/lib/cjs/index.cjs +345 -1886
  2. package/lib/esm/BaseNode-d78cc1b0.js +478 -0
  3. package/lib/esm/BaseNode.d.ts +1 -1
  4. package/lib/esm/BaseNode.js +26 -454
  5. package/lib/esm/Checkbox.js +37 -1
  6. package/lib/esm/CheckboxGroup.js +38 -1
  7. package/lib/esm/Container.d.ts +6 -1
  8. package/lib/esm/Container.js +108 -19
  9. package/lib/esm/DateField.js +38 -2
  10. package/lib/esm/Field.d.ts +2 -2
  11. package/lib/esm/Field.js +62 -26
  12. package/lib/esm/Fieldset.js +36 -3
  13. package/lib/esm/FileObject.js +23 -1
  14. package/lib/esm/FileUpload.js +34 -1
  15. package/lib/esm/Form.d.ts +1 -1
  16. package/lib/esm/Form.js +40 -8
  17. package/lib/esm/FormInstance.js +53 -5
  18. package/lib/esm/FormMetaData.js +26 -1
  19. package/lib/esm/InstanceManager.js +35 -8
  20. package/lib/esm/Node.js +25 -1
  21. package/lib/esm/Scriptable.js +29 -2
  22. package/lib/esm/controller/EventQueue.js +23 -1
  23. package/lib/esm/controller/Events.d.ts +1 -1
  24. package/lib/esm/controller/Events.js +41 -19
  25. package/lib/esm/controller/Logger.d.ts +2 -2
  26. package/lib/esm/controller/Logger.js +23 -1
  27. package/lib/esm/data/DataGroup.js +24 -1
  28. package/lib/esm/data/DataValue.js +23 -1
  29. package/lib/esm/data/EmptyDataValue.js +23 -1
  30. package/lib/esm/index.js +55 -21
  31. package/lib/esm/rules/FunctionRuntime.d.ts +3 -3
  32. package/lib/esm/rules/FunctionRuntime.js +31 -6
  33. package/lib/esm/rules/RuleEngine.js +30 -1
  34. package/lib/esm/types/Json.d.ts +16 -16
  35. package/lib/esm/types/Json.js +24 -2
  36. package/lib/esm/types/Model.d.ts +4 -4
  37. package/lib/esm/types/Model.js +23 -1
  38. package/lib/esm/types/index.js +22 -2
  39. package/lib/esm/utils/DataRefParser.d.ts +2 -2
  40. package/lib/esm/utils/DataRefParser.js +31 -6
  41. package/lib/esm/utils/Fetch.d.ts +1 -1
  42. package/lib/esm/utils/Fetch.js +24 -2
  43. package/lib/esm/utils/FormCreationUtils.js +40 -2
  44. package/lib/esm/utils/FormUtils.js +33 -8
  45. package/lib/esm/utils/JsonUtils.js +34 -11
  46. package/lib/esm/utils/LogUtils.js +23 -1
  47. package/lib/esm/utils/SchemaUtils.js +24 -2
  48. package/lib/esm/utils/TranslationUtils.d.ts +1 -1
  49. package/lib/esm/utils/TranslationUtils.js +32 -9
  50. package/lib/esm/utils/ValidationUtils.d.ts +4 -4
  51. package/lib/esm/utils/ValidationUtils.js +30 -4
  52. package/package.json +14 -2
  53. package/lib/browser/afb-events.js +0 -151
  54. package/lib/browser/afb-runtime.js +0 -3620
package/lib/cjs/index.cjs CHANGED
@@ -1,168 +1,24 @@
1
- 'use strict';
2
-
3
- const translationProps = ['description', 'placeholder', 'enum', 'enumNames', 'label.value', 'constraintMessages.accept',
4
- 'constraintMessages.enum', 'constraintMessages.exclusiveMinimum', 'constraintMessages.exclusiveMaximum', 'constraintMessages.format', 'constraintMessages.maxFileSize', 'constraintMessages.maxLength',
5
- 'constraintMessages.maximum', 'constraintMessages.maxItems', 'constraintMessages.minLength', 'constraintMessages.minimum', 'constraintMessages.minItems', 'constraintMessages.pattern', 'constraintMessages.required',
6
- 'constraintMessages.step', 'constraintMessages.type', 'constraintMessages.validationExpression'];
7
- const constraintProps = ['accept', 'enum', 'exclusiveMinimum', 'exclusiveMaximum',
8
- 'format', 'maxFileSize', 'maxLength', 'maximum', 'maxItems',
9
- 'minLength', 'minimum', 'minItems', 'pattern', 'required', 'step', 'validationExpression', 'enumNames'];
10
-
11
- class ValidationError {
12
- fieldName;
13
- errorMessages;
14
- constructor(fieldName = '', errorMessages = []) {
15
- this.errorMessages = errorMessages;
16
- this.fieldName = fieldName;
17
- }
18
- }
19
-
20
- const objToMap = (o) => new Map(Object.entries(o));
21
- const stringViewTypes = objToMap({ 'date': 'date-input', 'data-url': 'file-input', 'binary': 'file-input' });
22
- const typeToViewTypes = objToMap({
23
- 'number': 'number-input',
24
- 'boolean': 'checkbox',
25
- 'object': 'panel',
26
- 'array': 'panel',
27
- 'file': 'file-input',
28
- 'file[]': 'file-input'
29
- });
30
- const arrayTypes = ['string[]', 'boolean[]', 'number[]', 'array'];
31
- const defaultFieldTypes = (schema) => {
32
- const type = schema.type || 'string';
33
- if ('enum' in schema) {
34
- const enums = schema.enum;
35
- if (enums.length > 2 || arrayTypes.indexOf(type) > -1) {
36
- return 'drop-down';
37
- }
38
- else {
39
- return 'checkbox';
40
- }
41
- }
42
- if (type === 'string' || type === 'string[]') {
43
- return stringViewTypes.get(schema.format) || 'text-input';
44
- }
45
- return typeToViewTypes.get(type) || 'text-input';
46
- };
47
- const fieldSchema = (input) => {
48
- if ('items' in input) {
49
- const fieldset = input;
50
- const items = fieldset.items;
51
- if (fieldset.type === 'array') {
52
- return {
53
- type: 'array',
54
- items: fieldSchema(items[0]),
55
- minItems: fieldset?.minItems,
56
- maxItems: fieldset?.maxItems
57
- };
58
- }
59
- else {
60
- const iter = items.filter(x => x.name != null);
61
- return {
62
- type: 'object',
63
- properties: Object.fromEntries(iter.map(item => [item.name, fieldSchema(item)])),
64
- required: iter.filter(x => x.required).map(x => x.name)
65
- };
66
- }
67
- }
68
- else {
69
- const field = input;
70
- const schemaProps = ['type', 'maxLength', 'minLength', 'minimum', 'maximum', 'format', 'pattern', 'step', 'enum'];
71
- const schema = schemaProps.reduce((acc, prop) => {
72
- const p = prop;
73
- if (prop in field && field[p] != undefined) {
74
- acc[prop] = field[p];
75
- }
76
- return acc;
77
- }, {});
78
- if (field.dataRef === 'none' || Object.keys(schema).length == 0) {
79
- return undefined;
80
- }
81
- return {
82
- title: field.label?.value,
83
- description: field.description,
84
- ...schema
85
- };
86
- }
87
- };
88
- const exportDataSchema = (form) => {
89
- return fieldSchema(form);
90
- };
1
+ /*************************************************************************
2
+ * ADOBE CONFIDENTIAL
3
+ * ___________________
4
+ *
5
+ * Copyright 2022 Adobe
6
+ * All Rights Reserved.
7
+ *
8
+ * NOTICE: All information contained herein is, and remains
9
+ * the property of Adobe and its suppliers, if any. The intellectual
10
+ * and technical concepts contained herein are proprietary to Adobe
11
+ * and its suppliers and are protected by all applicable intellectual
12
+ * property laws, including trade secret and copyright laws.
13
+ * Dissemination of this information or reproduction of this material
14
+ * is strictly forbidden unless prior written permission is obtained
15
+ * from Adobe.
16
+
17
+ * Adobe permits you to use and modify this file solely in accordance with
18
+ * the terms of the Adobe license agreement accompanying it.
19
+ *************************************************************************/
91
20
 
92
- const getProperty = (data, key, def) => {
93
- if (key in data) {
94
- return data[key];
95
- }
96
- else if (!key.startsWith(':')) {
97
- const prefixedKey = `:${key}`;
98
- if (prefixedKey in data) {
99
- return data[prefixedKey];
100
- }
101
- }
102
- return def;
103
- };
104
- const isFile = function (item) {
105
- return (item?.type === 'file' || item?.type === 'file[]') ||
106
- ((item?.type === 'string' || item?.type === 'string[]') &&
107
- (item?.format === 'binary' || item?.format === 'data-url'));
108
- };
109
- const checkIfConstraintsArePresent = function (item) {
110
- return constraintProps.some(cp => item[cp] !== undefined);
111
- };
112
- const isCheckbox = function (item) {
113
- const fieldType = item?.fieldType || defaultFieldTypes(item);
114
- return fieldType === 'checkbox';
115
- };
116
- const isCheckboxGroup = function (item) {
117
- const fieldType = item?.fieldType || defaultFieldTypes(item);
118
- return fieldType === 'checkbox-group';
119
- };
120
- const isDateField = function (item) {
121
- const fieldType = item?.fieldType || defaultFieldTypes(item);
122
- return (fieldType === 'text-input' && item?.format === 'date') || fieldType === 'date-input';
123
- };
124
- function deepClone(obj, idGenerator) {
125
- let result;
126
- if (obj instanceof Array) {
127
- result = [];
128
- result = obj.map(x => deepClone(x, idGenerator));
129
- }
130
- else if (typeof obj === 'object' && obj !== null) {
131
- result = {};
132
- Object.entries(obj).forEach(([key, value]) => {
133
- result[key] = deepClone(value, idGenerator);
134
- });
135
- }
136
- else {
137
- result = obj;
138
- }
139
- if (idGenerator && result && result.id) {
140
- result.id = idGenerator();
141
- }
142
- return result;
143
- }
144
- function checkIfKeyAdded(currentObj, prevObj, objKey) {
145
- if (currentObj != null && prevObj != null) {
146
- const newPrvObj = { ...prevObj };
147
- newPrvObj[objKey] = currentObj[objKey];
148
- const newJsonStr = jsonString(currentObj).replace(jsonString(newPrvObj), '');
149
- return newJsonStr === '';
150
- }
151
- else {
152
- return false;
153
- }
154
- }
155
- const jsonString = (obj) => {
156
- return JSON.stringify(obj, null, 2);
157
- };
158
- const isRepeatable = (obj) => {
159
- return ((obj.repeatable &&
160
- ((obj.minOccur === undefined && obj.maxOccur === undefined) ||
161
- (obj.minOccur !== undefined && obj.maxOccur !== undefined && obj.maxOccur !== 0) ||
162
- (obj.minOccur !== undefined && obj.maxOccur !== undefined && obj.minOccur !== 0 && obj.maxOccur !== 0) ||
163
- (obj.minOccur !== undefined && obj.minOccur >= 0) ||
164
- (obj.maxOccur !== undefined && obj.maxOccur !== 0))) || false);
165
- };
21
+ 'use strict';
166
22
 
167
23
  class ActionImpl {
168
24
  _metadata;
@@ -687,12 +543,12 @@ const resolveData = (data, input, create) => {
687
543
  return result;
688
544
  };
689
545
 
690
- var __decorate$3 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
546
+ function __decorate(decorators, target, key, desc) {
691
547
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
692
548
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
693
549
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
694
550
  return c > 3 && r && Object.defineProperty(target, key, r), r;
695
- };
551
+ }
696
552
  const editableProperties = [
697
553
  'value',
698
554
  'label',
@@ -919,7 +775,7 @@ class BaseNode {
919
775
  const isNonTransparent = this.parent?._jsonModel.type === 'array';
920
776
  return !this._jsonModel.name && !isNonTransparent;
921
777
  }
922
- getState() {
778
+ getState(isRepeatableChild = false) {
923
779
  return {
924
780
  ...this._jsonModel,
925
781
  properties: this.properties,
@@ -1123,22 +979,177 @@ class BaseNode {
1123
979
  }
1124
980
  }
1125
981
  }
1126
- __decorate$3([
982
+ __decorate([
1127
983
  dependencyTracked()
1128
984
  ], BaseNode.prototype, "index", null);
1129
- __decorate$3([
985
+ __decorate([
1130
986
  dependencyTracked()
1131
987
  ], BaseNode.prototype, "description", null);
1132
- __decorate$3([
988
+ __decorate([
1133
989
  dependencyTracked()
1134
990
  ], BaseNode.prototype, "visible", null);
1135
- __decorate$3([
991
+ __decorate([
1136
992
  dependencyTracked()
1137
993
  ], BaseNode.prototype, "label", null);
1138
- __decorate$3([
994
+ __decorate([
1139
995
  dependencyTracked()
1140
996
  ], BaseNode.prototype, "properties", null);
1141
997
 
998
+ const translationProps = ['description', 'placeholder', 'enum', 'enumNames', 'label.value', 'constraintMessages.accept',
999
+ 'constraintMessages.enum', 'constraintMessages.exclusiveMinimum', 'constraintMessages.exclusiveMaximum', 'constraintMessages.format', 'constraintMessages.maxFileSize', 'constraintMessages.maxLength',
1000
+ 'constraintMessages.maximum', 'constraintMessages.maxItems', 'constraintMessages.minLength', 'constraintMessages.minimum', 'constraintMessages.minItems', 'constraintMessages.pattern', 'constraintMessages.required',
1001
+ 'constraintMessages.step', 'constraintMessages.type', 'constraintMessages.validationExpression'];
1002
+ const constraintProps = ['accept', 'enum', 'exclusiveMinimum', 'exclusiveMaximum',
1003
+ 'format', 'maxFileSize', 'maxLength', 'maximum', 'maxItems',
1004
+ 'minLength', 'minimum', 'minItems', 'pattern', 'required', 'step', 'validationExpression', 'enumNames'];
1005
+
1006
+ const objToMap = (o) => new Map(Object.entries(o));
1007
+ const stringViewTypes = objToMap({ 'date': 'date-input', 'data-url': 'file-input', 'binary': 'file-input' });
1008
+ const typeToViewTypes = objToMap({
1009
+ 'number': 'number-input',
1010
+ 'boolean': 'checkbox',
1011
+ 'object': 'panel',
1012
+ 'array': 'panel',
1013
+ 'file': 'file-input',
1014
+ 'file[]': 'file-input'
1015
+ });
1016
+ const arrayTypes = ['string[]', 'boolean[]', 'number[]', 'array'];
1017
+ const defaultFieldTypes = (schema) => {
1018
+ const type = schema.type || 'string';
1019
+ if ('enum' in schema) {
1020
+ const enums = schema.enum;
1021
+ if (enums.length > 2 || arrayTypes.indexOf(type) > -1) {
1022
+ return 'drop-down';
1023
+ }
1024
+ else {
1025
+ return 'checkbox';
1026
+ }
1027
+ }
1028
+ if (type === 'string' || type === 'string[]') {
1029
+ return stringViewTypes.get(schema.format) || 'text-input';
1030
+ }
1031
+ return typeToViewTypes.get(type) || 'text-input';
1032
+ };
1033
+ const fieldSchema = (input) => {
1034
+ if ('items' in input) {
1035
+ const fieldset = input;
1036
+ const items = fieldset.items;
1037
+ if (fieldset.type === 'array') {
1038
+ return {
1039
+ type: 'array',
1040
+ items: fieldSchema(items[0]),
1041
+ minItems: fieldset?.minItems,
1042
+ maxItems: fieldset?.maxItems
1043
+ };
1044
+ }
1045
+ else {
1046
+ const iter = items.filter(x => x.name != null);
1047
+ return {
1048
+ type: 'object',
1049
+ properties: Object.fromEntries(iter.map(item => [item.name, fieldSchema(item)])),
1050
+ required: iter.filter(x => x.required).map(x => x.name)
1051
+ };
1052
+ }
1053
+ }
1054
+ else {
1055
+ const field = input;
1056
+ const schemaProps = ['type', 'maxLength', 'minLength', 'minimum', 'maximum', 'format', 'pattern', 'step', 'enum'];
1057
+ const schema = schemaProps.reduce((acc, prop) => {
1058
+ const p = prop;
1059
+ if (prop in field && field[p] != undefined) {
1060
+ acc[prop] = field[p];
1061
+ }
1062
+ return acc;
1063
+ }, {});
1064
+ if (field.dataRef === 'none' || Object.keys(schema).length == 0) {
1065
+ return undefined;
1066
+ }
1067
+ return {
1068
+ title: field.label?.value,
1069
+ description: field.description,
1070
+ ...schema
1071
+ };
1072
+ }
1073
+ };
1074
+ const exportDataSchema = (form) => {
1075
+ return fieldSchema(form);
1076
+ };
1077
+
1078
+ const getProperty = (data, key, def) => {
1079
+ if (key in data) {
1080
+ return data[key];
1081
+ }
1082
+ else if (!key.startsWith(':')) {
1083
+ const prefixedKey = `:${key}`;
1084
+ if (prefixedKey in data) {
1085
+ return data[prefixedKey];
1086
+ }
1087
+ }
1088
+ return def;
1089
+ };
1090
+ const isFile = function (item) {
1091
+ return (item?.type === 'file' || item?.type === 'file[]') ||
1092
+ ((item?.type === 'string' || item?.type === 'string[]') &&
1093
+ (item?.format === 'binary' || item?.format === 'data-url'));
1094
+ };
1095
+ const checkIfConstraintsArePresent = function (item) {
1096
+ return constraintProps.some(cp => item[cp] !== undefined);
1097
+ };
1098
+ const isCheckbox = function (item) {
1099
+ const fieldType = item?.fieldType || defaultFieldTypes(item);
1100
+ return fieldType === 'checkbox';
1101
+ };
1102
+ const isCheckboxGroup = function (item) {
1103
+ const fieldType = item?.fieldType || defaultFieldTypes(item);
1104
+ return fieldType === 'checkbox-group';
1105
+ };
1106
+ const isDateField = function (item) {
1107
+ const fieldType = item?.fieldType || defaultFieldTypes(item);
1108
+ return (fieldType === 'text-input' && item?.format === 'date') || fieldType === 'date-input';
1109
+ };
1110
+ function deepClone(obj, idGenerator) {
1111
+ let result;
1112
+ if (obj instanceof Array) {
1113
+ result = [];
1114
+ result = obj.map(x => deepClone(x, idGenerator));
1115
+ }
1116
+ else if (typeof obj === 'object' && obj !== null) {
1117
+ result = {};
1118
+ Object.entries(obj).forEach(([key, value]) => {
1119
+ result[key] = deepClone(value, idGenerator);
1120
+ });
1121
+ }
1122
+ else {
1123
+ result = obj;
1124
+ }
1125
+ if (idGenerator && result && result.id) {
1126
+ result.id = idGenerator();
1127
+ }
1128
+ return result;
1129
+ }
1130
+ function checkIfKeyAdded(currentObj, prevObj, objKey) {
1131
+ if (currentObj != null && prevObj != null) {
1132
+ const newPrvObj = { ...prevObj };
1133
+ newPrvObj[objKey] = currentObj[objKey];
1134
+ const newJsonStr = jsonString(currentObj).replace(jsonString(newPrvObj), '');
1135
+ return newJsonStr === '';
1136
+ }
1137
+ else {
1138
+ return false;
1139
+ }
1140
+ }
1141
+ const jsonString = (obj) => {
1142
+ return JSON.stringify(obj, null, 2);
1143
+ };
1144
+ const isRepeatable = (obj) => {
1145
+ return ((obj.repeatable &&
1146
+ ((obj.minOccur === undefined && obj.maxOccur === undefined) ||
1147
+ (obj.minOccur !== undefined && obj.maxOccur !== undefined && obj.maxOccur !== 0) ||
1148
+ (obj.minOccur !== undefined && obj.maxOccur !== undefined && obj.minOccur !== 0 && obj.maxOccur !== 0) ||
1149
+ (obj.minOccur !== undefined && obj.minOccur >= 0) ||
1150
+ (obj.maxOccur !== undefined && obj.maxOccur !== 0))) || false);
1151
+ };
1152
+
1142
1153
  class Scriptable extends BaseNode {
1143
1154
  _events = {};
1144
1155
  _rules = {};
@@ -1301,12 +1312,6 @@ class Scriptable extends BaseNode {
1301
1312
  }
1302
1313
  }
1303
1314
 
1304
- var __decorate$2 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
1305
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1306
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1307
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1308
- return c > 3 && r && Object.defineProperty(target, key, r), r;
1309
- };
1310
1315
  class Container extends Scriptable {
1311
1316
  _children = [];
1312
1317
  _childrenReference;
@@ -1349,12 +1354,39 @@ class Container extends Scriptable {
1349
1354
  return true;
1350
1355
  }
1351
1356
  _activeChild = null;
1352
- getState() {
1357
+ isSiteContainer(item) {
1358
+ return ':items' in item;
1359
+ }
1360
+ isAFormField(item) {
1361
+ return ('fieldType' in item || 'id' in item || 'name' in item || 'dataRef' in item || 'type' in item);
1362
+ }
1363
+ getItemsState(isRepeatableChild = false) {
1364
+ if (this._jsonModel.type === 'array' || isRepeatable(this._jsonModel) || isRepeatableChild) {
1365
+ return this._children.map(x => {
1366
+ return { ...x.getState(true) };
1367
+ });
1368
+ }
1369
+ else {
1370
+ return this._jsonModel.items.map(x => {
1371
+ if (this.isSiteContainer(x)) {
1372
+ return {
1373
+ ...x,
1374
+ ':items': this.walkSiteContainerItems(x)
1375
+ };
1376
+ }
1377
+ else if (this.isAFormField(x)) {
1378
+ return { ...this.form.getElement(x?.id).getState(isRepeatableChild) };
1379
+ }
1380
+ else {
1381
+ return x;
1382
+ }
1383
+ });
1384
+ }
1385
+ }
1386
+ getState(isRepeatableChild = false) {
1353
1387
  return {
1354
- ...super.getState(),
1355
- items: this._children.map(x => {
1356
- return { ...x.getState() };
1357
- })
1388
+ ...super.getState(isRepeatableChild),
1389
+ items: this.getItemsState(isRepeatableChild)
1358
1390
  };
1359
1391
  }
1360
1392
  _createChild(child, options) {
@@ -1364,6 +1396,19 @@ class Container extends Scriptable {
1364
1396
  parent
1365
1397
  });
1366
1398
  }
1399
+ walkSiteContainerItems(x) {
1400
+ return Object.fromEntries(Object.entries(x[':items']).map(([key, value]) => {
1401
+ if (this.isAFormField(value)) {
1402
+ return [key, this.form.getElement(value?.id).getState()];
1403
+ }
1404
+ else if (this.isSiteContainer(value)) {
1405
+ return this.walkSiteContainerItems(value);
1406
+ }
1407
+ else {
1408
+ return [key, value];
1409
+ }
1410
+ }));
1411
+ }
1367
1412
  _addChildToRuleNode(child, options) {
1368
1413
  const self = this;
1369
1414
  const { parent = this } = options;
@@ -1403,6 +1448,7 @@ class Container extends Scriptable {
1403
1448
  ...deepClone(itemJson, cloneIds ? () => { return form.getUniqueId(); } : undefined)
1404
1449
  };
1405
1450
  const retVal = this._createChild(itemTemplate, { parent: this, form: this.form });
1451
+ itemJson.id = retVal.id;
1406
1452
  this.form.fieldAdded(retVal);
1407
1453
  this._addChildToRuleNode(retVal, { parent: nonTransparentParent });
1408
1454
  if (index === this._children.length) {
@@ -1429,7 +1475,6 @@ class Container extends Scriptable {
1429
1475
  _initialize() {
1430
1476
  super._initialize();
1431
1477
  const items = this._jsonModel.items || [];
1432
- this._jsonModel.items = [];
1433
1478
  this._childrenReference = this._jsonModel.type == 'array' ? [] : {};
1434
1479
  if (this._jsonModel.type == 'array' && items.length === 1 && this.getDataNode() != null) {
1435
1480
  this._itemTemplate = deepClone(items[0]);
@@ -1443,14 +1488,23 @@ class Container extends Scriptable {
1443
1488
  this._jsonModel.initialItems = Math.max(1, this._jsonModel.minItems);
1444
1489
  }
1445
1490
  for (let i = 0; i < this._jsonModel.initialItems; i++) {
1446
- const child = this._addChild(this._itemTemplate);
1491
+ const child = this._addChild(this._itemTemplate, null, i > 0);
1492
+ items[0].id = child.id;
1447
1493
  child._initialize();
1448
1494
  }
1449
1495
  }
1450
1496
  else if (items.length > 0) {
1451
1497
  items.forEach((item) => {
1452
- const child = this._addChild(item);
1453
- child._initialize();
1498
+ if (this.isSiteContainer(item)) {
1499
+ this._initializeSiteContainer(item);
1500
+ }
1501
+ else if (this.isAFormField(item)) {
1502
+ const child = this._addChild(item);
1503
+ child._initialize();
1504
+ }
1505
+ else {
1506
+ this.form.logger.warn('A container item was not initialized.');
1507
+ }
1454
1508
  });
1455
1509
  this._jsonModel.minItems = this._children.length;
1456
1510
  this._jsonModel.maxItems = this._children.length;
@@ -1461,6 +1515,17 @@ class Container extends Scriptable {
1461
1515
  }
1462
1516
  this.setupRuleNode();
1463
1517
  }
1518
+ _initializeSiteContainer(item) {
1519
+ Object.entries(item[':items']).forEach(([key, value]) => {
1520
+ if (this.isAFormField(value)) {
1521
+ const child = this._addChild(value);
1522
+ child._initialize();
1523
+ }
1524
+ else if (this.isSiteContainer(value)) {
1525
+ return this._initializeSiteContainer(value);
1526
+ }
1527
+ });
1528
+ }
1464
1529
  addItem(action) {
1465
1530
  if ((action.type === 'addItem' || action.type == 'addInstance') && this._itemTemplate != null) {
1466
1531
  if ((this._jsonModel.maxItems === -1) || (this._children.length < this._jsonModel.maxItems)) {
@@ -1514,6 +1579,14 @@ class Container extends Scriptable {
1514
1579
  }
1515
1580
  }
1516
1581
  reset() {
1582
+ if (this.type === 'array' || isRepeatable(this._jsonModel)) {
1583
+ if (this.items.length > this._jsonModel.initialItems) {
1584
+ const itemsToBeRemoved = this.items.length - this._jsonModel.initialItems;
1585
+ for (let i = 0; i < itemsToBeRemoved; i++) {
1586
+ this.dispatch(new RemoveItem());
1587
+ }
1588
+ }
1589
+ }
1517
1590
  this.items.forEach(x => {
1518
1591
  x.reset();
1519
1592
  });
@@ -1576,13 +1649,13 @@ class Container extends Scriptable {
1576
1649
  }
1577
1650
  }
1578
1651
  }
1579
- __decorate$2([
1652
+ __decorate([
1580
1653
  dependencyTracked()
1581
1654
  ], Container.prototype, "maxItems", null);
1582
- __decorate$2([
1655
+ __decorate([
1583
1656
  dependencyTracked()
1584
1657
  ], Container.prototype, "minItems", null);
1585
- __decorate$2([
1658
+ __decorate([
1586
1659
  dependencyTracked()
1587
1660
  ], Container.prototype, "activeChild", null);
1588
1661
 
@@ -2448,17 +2521,16 @@ class Form extends Container {
2448
2521
  super.dispatch(action);
2449
2522
  }
2450
2523
  }
2451
- executeAction(action) {
2452
- if ((action.type !== 'submit') || this._invalidFields.length === 0) {
2453
- super.executeAction(action);
2454
- }
2455
- }
2456
2524
  submit(action, context) {
2457
2525
  if (this.validate().length === 0) {
2458
2526
  const payload = action?.payload || {};
2459
2527
  submit(context, payload?.success, payload?.error, payload?.submit_as, payload?.data);
2460
2528
  }
2461
2529
  }
2530
+ reset() {
2531
+ super.reset();
2532
+ this._invalidFields = [];
2533
+ }
2462
2534
  getElement(id) {
2463
2535
  if (id == this.id) {
2464
2536
  return this;
@@ -2485,7 +2557,6 @@ class Form extends Container {
2485
2557
  }
2486
2558
  }
2487
2559
 
2488
- // Type constants used to define functions.
2489
2560
  var dataTypes = {
2490
2561
  TYPE_NUMBER: 0,
2491
2562
  TYPE_ANY: 1,
@@ -2557,11 +2628,9 @@ const {
2557
2628
  TYPE_CLASS: TYPE_CLASS$1,
2558
2629
  TYPE_ARRAY_ARRAY,
2559
2630
  } = dataTypes;
2560
-
2561
2631
  const {
2562
2632
  TOK_EXPREF: TOK_EXPREF$3,
2563
2633
  } = tokenDefinitions;
2564
-
2565
2634
  const TYPE_NAME_TABLE = {
2566
2635
  [TYPE_NUMBER]: 'number',
2567
2636
  [TYPE_ANY$1]: 'any',
@@ -2576,13 +2645,10 @@ const TYPE_NAME_TABLE = {
2576
2645
  [TYPE_CLASS$1]: 'class',
2577
2646
  [TYPE_ARRAY_ARRAY]: 'Array<array>',
2578
2647
  };
2579
-
2580
2648
  function getTypeName(inputObj, useValueOf = true) {
2581
2649
  if (inputObj === null) return TYPE_NULL;
2582
2650
  let obj = inputObj;
2583
2651
  if (useValueOf) {
2584
- // check for the case where there's a child named 'valueOf' that's not a function
2585
- // if so, then it's an object...
2586
2652
  if (typeof inputObj.valueOf === 'function') obj = inputObj.valueOf.call(inputObj);
2587
2653
  else return TYPE_OBJECT;
2588
2654
  }
@@ -2598,8 +2664,6 @@ function getTypeName(inputObj, useValueOf = true) {
2598
2664
  case '[object Null]':
2599
2665
  return TYPE_NULL;
2600
2666
  case '[object Object]':
2601
- // Check if it's an expref. If it has, it's been
2602
- // tagged with a jmespathType attr of 'Expref';
2603
2667
  if (obj.jmespathType === TOK_EXPREF$3) {
2604
2668
  return TYPE_EXPREF;
2605
2669
  }
@@ -2608,23 +2672,17 @@ function getTypeName(inputObj, useValueOf = true) {
2608
2672
  return TYPE_OBJECT;
2609
2673
  }
2610
2674
  }
2611
-
2612
2675
  function getTypeNames(inputObj) {
2613
- // return the types with and without using valueOf
2614
- // needed for the cases where we really need an object passed to a function -- not it's value
2615
2676
  const type1 = getTypeName(inputObj);
2616
2677
  const type2 = getTypeName(inputObj, false);
2617
2678
  return [type1, type2];
2618
2679
  }
2619
-
2620
2680
  function matchType(actuals, expectedList, argValue, context, toNumber, toString) {
2621
2681
  const actual = actuals[0];
2622
2682
  if (expectedList.findIndex(
2623
2683
  type => type === TYPE_ANY$1 || actual === type,
2624
2684
  ) !== -1
2625
2685
  ) return argValue;
2626
- // Can't coerce Objects to any other type,
2627
- // and cannot coerce anything to a Class
2628
2686
  let wrongType = false;
2629
2687
  if (actual === TYPE_OBJECT || (expectedList.length === 1 && expectedList[0] === TYPE_CLASS$1)) {
2630
2688
  wrongType = true;
@@ -2644,11 +2702,9 @@ function matchType(actuals, expectedList, argValue, context, toNumber, toString)
2644
2702
  if (wrongType) {
2645
2703
  throw new Error(`TypeError: ${context} expected argument to be type ${TYPE_NAME_TABLE[expectedList[0]]} but received type ${TYPE_NAME_TABLE[actual]} instead.`);
2646
2704
  }
2647
- // no exact match in the list of possible types, see if we can coerce an array type
2648
2705
  let expected = -1;
2649
2706
  if (actual === TYPE_ARRAY$1) {
2650
2707
  if (expectedList.includes(TYPE_ARRAY_STRING$1) && expectedList.includes(TYPE_ARRAY_NUMBER)) {
2651
- // choose the array type based on the first element
2652
2708
  if (argValue.length > 0 && typeof argValue[0] === 'string') expected = TYPE_ARRAY_STRING$1;
2653
2709
  else expected = TYPE_ARRAY_NUMBER;
2654
2710
  }
@@ -2658,7 +2714,6 @@ function matchType(actuals, expectedList, argValue, context, toNumber, toString)
2658
2714
  e => [TYPE_ARRAY_STRING$1, TYPE_ARRAY_NUMBER, TYPE_ARRAY$1].includes(e),
2659
2715
  );
2660
2716
  }
2661
- // no match, just take the first type
2662
2717
  if (expected === -1) [expected] = expectedList;
2663
2718
  if (expected === TYPE_ANY$1) return argValue;
2664
2719
  if (expected === TYPE_ARRAY_STRING$1
@@ -2668,12 +2723,8 @@ function matchType(actuals, expectedList, argValue, context, toNumber, toString)
2668
2723
  if (actual === TYPE_ARRAY_NUMBER || actual === TYPE_ARRAY_STRING$1) return argValue;
2669
2724
  return argValue === null ? [] : [argValue];
2670
2725
  }
2671
- // The expected type can either just be array,
2672
- // or it can require a specific subtype (array of numbers).
2673
2726
  const subtype = expected === TYPE_ARRAY_NUMBER ? TYPE_NUMBER : TYPE_STRING$1;
2674
2727
  if (actual === TYPE_ARRAY$1) {
2675
- // Otherwise we need to check subtypes.
2676
- // We're going to modify the array, so take a copy
2677
2728
  const returnArray = argValue.slice();
2678
2729
  for (let i = 0; i < returnArray.length; i += 1) {
2679
2730
  const indexType = getTypeNames(returnArray[i]);
@@ -2694,7 +2745,6 @@ function matchType(actuals, expectedList, argValue, context, toNumber, toString)
2694
2745
  } else {
2695
2746
  if (expected === TYPE_NUMBER) {
2696
2747
  if ([TYPE_STRING$1, TYPE_BOOLEAN, TYPE_NULL].includes(actual)) return toNumber(argValue);
2697
- /* TYPE_ARRAY, TYPE_EXPREF, TYPE_OBJECT, TYPE_ARRAY, TYPE_ARRAY_NUMBER, TYPE_ARRAY_STRING */
2698
2748
  return 0;
2699
2749
  }
2700
2750
  if (expected === TYPE_STRING$1) {
@@ -2717,42 +2767,31 @@ function isArray(obj) {
2717
2767
  }
2718
2768
  return false;
2719
2769
  }
2720
-
2721
2770
  function isObject(obj) {
2722
2771
  if (obj !== null) {
2723
2772
  return Object.prototype.toString.call(obj) === '[object Object]';
2724
2773
  }
2725
2774
  return false;
2726
2775
  }
2727
-
2728
2776
  function getValueOf(a) {
2729
2777
  if (a === null || a === undefined) return a;
2730
2778
  if (isArray(a)) {
2731
2779
  return a.map(i => getValueOf(i));
2732
2780
  }
2733
- // if we have a child named 'valueOf' then we're an object,
2734
- // and just return the object.
2735
2781
  if (typeof (a.valueOf) !== 'function') return a;
2736
2782
  return a.valueOf();
2737
2783
  }
2738
-
2739
2784
  function strictDeepEqual(lhs, rhs) {
2740
2785
  const first = getValueOf(lhs);
2741
2786
  const second = getValueOf(rhs);
2742
- // Check the scalar case first.
2743
2787
  if (first === second) {
2744
2788
  return true;
2745
2789
  }
2746
-
2747
- // Check if they are the same type.
2748
2790
  const firstType = Object.prototype.toString.call(first);
2749
2791
  if (firstType !== Object.prototype.toString.call(second)) {
2750
2792
  return false;
2751
2793
  }
2752
- // We know that first and second have the same type so we can just check the
2753
- // first type from now on.
2754
2794
  if (isArray(first) === true) {
2755
- // Short circuit if they're not the same length;
2756
2795
  if (first.length !== second.length) {
2757
2796
  return false;
2758
2797
  }
@@ -2764,9 +2803,7 @@ function strictDeepEqual(lhs, rhs) {
2764
2803
  return true;
2765
2804
  }
2766
2805
  if (isObject(first) === true) {
2767
- // An object is equal if it has the same key/value pairs.
2768
2806
  const keysSeen = {};
2769
- // eslint-disable-next-line no-restricted-syntax
2770
2807
  for (const key in first) {
2771
2808
  if (hasOwnProperty.call(first, key)) {
2772
2809
  if (strictDeepEqual(first[key], second[key]) === false) {
@@ -2775,9 +2812,6 @@ function strictDeepEqual(lhs, rhs) {
2775
2812
  keysSeen[key] = true;
2776
2813
  }
2777
2814
  }
2778
- // Now check that there aren't any keys in second that weren't
2779
- // in first.
2780
- // eslint-disable-next-line no-restricted-syntax
2781
2815
  for (const key2 in second) {
2782
2816
  if (hasOwnProperty.call(second, key2)) {
2783
2817
  if (keysSeen[key2] !== true) {
@@ -2803,42 +2837,22 @@ const {
2803
2837
  TOK_NE: TOK_NE$2,
2804
2838
  TOK_FLATTEN: TOK_FLATTEN$2,
2805
2839
  } = tokenDefinitions;
2806
-
2807
2840
  const {
2808
2841
  TYPE_STRING,
2809
2842
  TYPE_ARRAY_STRING,
2810
2843
  TYPE_ARRAY,
2811
2844
  } = dataTypes;
2812
-
2813
2845
  function isFalse(value) {
2814
- // From the spec:
2815
- // A false value corresponds to the following values:
2816
- // Empty list
2817
- // Empty object
2818
- // Empty string
2819
- // False boolean
2820
- // null value
2821
- // (new) use JS truthy evaluation. This changes the spec behavior.
2822
- // Where in the past a zero (0) would be True, it's now false
2823
-
2824
- // First check the scalar values.
2825
2846
  if (value === null) return true;
2826
- // in case it's an object with a valueOf defined
2827
2847
  const obj = getValueOf(value);
2828
2848
  if (obj === '' || obj === false || obj === null) {
2829
2849
  return true;
2830
2850
  }
2831
2851
  if (isArray(obj) && obj.length === 0) {
2832
- // Check for an empty array.
2833
2852
  return true;
2834
2853
  }
2835
2854
  if (isObject(obj)) {
2836
- // Check for an empty object.
2837
- // eslint-disable-next-line no-restricted-syntax
2838
2855
  for (const key in obj) {
2839
- // If there are any keys, then
2840
- // the object is not empty so the object
2841
- // is not false.
2842
2856
  if (Object.prototype.hasOwnProperty.call(obj, key)) {
2843
2857
  return false;
2844
2858
  }
@@ -2847,11 +2861,9 @@ function isFalse(value) {
2847
2861
  }
2848
2862
  return !obj;
2849
2863
  }
2850
-
2851
2864
  function objValues(obj) {
2852
2865
  return Object.values(obj);
2853
2866
  }
2854
-
2855
2867
  class TreeInterpreter {
2856
2868
  constructor(runtime, globals, toNumber, toString, debug, language) {
2857
2869
  this.runtime = runtime;
@@ -2861,27 +2873,20 @@ class TreeInterpreter {
2861
2873
  this.debug = debug;
2862
2874
  this.language = language;
2863
2875
  }
2864
-
2865
2876
  search(node, value) {
2866
2877
  return this.visit(node, value);
2867
2878
  }
2868
-
2869
2879
  visit(n, v) {
2870
2880
  const visitFunctions = {
2871
2881
  Field: (node, value) => {
2872
- // we used to check isObject(value) here -- but it is possible for an array-based
2873
- // object to have properties. So we'll allow the child check on objects and arrays.
2874
2882
  if (value !== null && (isObject(value) || isArray(value))) {
2875
2883
  let field = value[node.name];
2876
- // fields can be objects with overridden methods. e.g. valueOf
2877
- // so don't resolve to a function...
2878
2884
  if (typeof field === 'function') field = undefined;
2879
2885
  if (field === undefined) {
2880
2886
  try {
2881
2887
  this.debug.push(`Failed to find: '${node.name}'`);
2882
2888
  const available = Object.keys(value).map(a => `'${a}'`).toString();
2883
2889
  if (available.length) this.debug.push(`Available fields: ${available}`);
2884
- // eslint-disable-next-line no-empty
2885
2890
  } catch (e) {}
2886
2891
  return null;
2887
2892
  }
@@ -2889,7 +2894,6 @@ class TreeInterpreter {
2889
2894
  }
2890
2895
  return null;
2891
2896
  },
2892
-
2893
2897
  Subexpression: (node, value) => {
2894
2898
  let result = this.visit(node.children[0], value);
2895
2899
  for (let i = 1; i < node.children.length; i += 1) {
@@ -2898,12 +2902,10 @@ class TreeInterpreter {
2898
2902
  }
2899
2903
  return result;
2900
2904
  },
2901
-
2902
2905
  IndexExpression: (node, value) => {
2903
2906
  const left = this.visit(node.children[0], value);
2904
2907
  return this.visit(node.children[1], left);
2905
2908
  },
2906
-
2907
2909
  Index: (node, value) => {
2908
2910
  if (isArray(value)) {
2909
2911
  let index = this.toNumber(this.visit(node.value, value));
@@ -2929,7 +2931,6 @@ class TreeInterpreter {
2929
2931
  this.debug.push(`left side of index expression ${value} is not an array or object.`);
2930
2932
  return null;
2931
2933
  },
2932
-
2933
2934
  Slice: (node, value) => {
2934
2935
  if (!isArray(value)) return null;
2935
2936
  const sliceParams = node.children.slice(0).map(
@@ -2949,9 +2950,7 @@ class TreeInterpreter {
2949
2950
  }
2950
2951
  return result;
2951
2952
  },
2952
-
2953
2953
  Projection: (node, value) => {
2954
- // Evaluate left child.
2955
2954
  const base = this.visit(node.children[0], value);
2956
2955
  if (!isArray(base)) return null;
2957
2956
  const collected = [];
@@ -2963,9 +2962,7 @@ class TreeInterpreter {
2963
2962
  });
2964
2963
  return collected;
2965
2964
  },
2966
-
2967
2965
  ValueProjection: (node, value) => {
2968
- // Evaluate left child.
2969
2966
  const projection = this.visit(node.children[0], value);
2970
2967
  if (!isObject(getValueOf(projection))) return null;
2971
2968
  const collected = [];
@@ -2976,7 +2973,6 @@ class TreeInterpreter {
2976
2973
  });
2977
2974
  return collected;
2978
2975
  },
2979
-
2980
2976
  FilterProjection: (node, value) => {
2981
2977
  const base = this.visit(node.children[0], value);
2982
2978
  if (!isArray(base)) return null;
@@ -2984,7 +2980,6 @@ class TreeInterpreter {
2984
2980
  const matched = this.visit(node.children[2], b);
2985
2981
  return !isFalse(matched);
2986
2982
  });
2987
-
2988
2983
  const finalResults = [];
2989
2984
  filtered.forEach(f => {
2990
2985
  const current = this.visit(node.children[1], f);
@@ -2992,11 +2987,9 @@ class TreeInterpreter {
2992
2987
  });
2993
2988
  return finalResults;
2994
2989
  },
2995
-
2996
2990
  Comparator: (node, value) => {
2997
2991
  const first = this.visit(node.children[0], value);
2998
2992
  const second = this.visit(node.children[1], value);
2999
-
3000
2993
  if (node.name === TOK_EQ$2) return strictDeepEqual(first, second);
3001
2994
  if (node.name === TOK_NE$2) return !strictDeepEqual(first, second);
3002
2995
  if (node.name === TOK_GT$2) return first > second;
@@ -3005,7 +2998,6 @@ class TreeInterpreter {
3005
2998
  if (node.name === TOK_LTE$2) return first <= second;
3006
2999
  throw new Error(`Unknown comparator: ${node.name}`);
3007
3000
  },
3008
-
3009
3001
  [TOK_FLATTEN$2]: (node, value) => {
3010
3002
  const original = this.visit(node.children[0], value);
3011
3003
  if (!isArray(original)) return null;
@@ -3019,14 +3011,11 @@ class TreeInterpreter {
3019
3011
  });
3020
3012
  return merged;
3021
3013
  },
3022
-
3023
3014
  Identity: (_node, value) => value,
3024
-
3025
3015
  MultiSelectList: (node, value) => {
3026
3016
  if (value === null) return null;
3027
3017
  return node.children.map(child => this.visit(child, value));
3028
3018
  },
3029
-
3030
3019
  MultiSelectHash: (node, value) => {
3031
3020
  if (value === null) return null;
3032
3021
  const collected = {};
@@ -3035,26 +3024,21 @@ class TreeInterpreter {
3035
3024
  });
3036
3025
  return collected;
3037
3026
  },
3038
-
3039
3027
  OrExpression: (node, value) => {
3040
3028
  let matched = this.visit(node.children[0], value);
3041
3029
  if (isFalse(matched)) matched = this.visit(node.children[1], value);
3042
3030
  return matched;
3043
3031
  },
3044
-
3045
3032
  AndExpression: (node, value) => {
3046
3033
  const first = this.visit(node.children[0], value);
3047
-
3048
3034
  if (isFalse(first) === true) return first;
3049
3035
  return this.visit(node.children[1], value);
3050
3036
  },
3051
-
3052
3037
  AddExpression: (node, value) => {
3053
3038
  const first = this.visit(node.children[0], value);
3054
3039
  const second = this.visit(node.children[1], value);
3055
3040
  return this.applyOperator(first, second, '+');
3056
3041
  },
3057
-
3058
3042
  ConcatenateExpression: (node, value) => {
3059
3043
  let first = this.visit(node.children[0], value);
3060
3044
  let second = this.visit(node.children[1], value);
@@ -3062,7 +3046,6 @@ class TreeInterpreter {
3062
3046
  second = matchType(getTypeNames(second), [TYPE_STRING, TYPE_ARRAY_STRING], second, 'concatenate', this.toNumber, this.toString);
3063
3047
  return this.applyOperator(first, second, '&');
3064
3048
  },
3065
-
3066
3049
  UnionExpression: (node, value) => {
3067
3050
  let first = this.visit(node.children[0], value);
3068
3051
  let second = this.visit(node.children[1], value);
@@ -3070,72 +3053,52 @@ class TreeInterpreter {
3070
3053
  second = matchType(getTypeNames(second), [TYPE_ARRAY], second, 'union', this.toNumber, this.toString);
3071
3054
  return first.concat(second);
3072
3055
  },
3073
-
3074
3056
  SubtractExpression: (node, value) => {
3075
3057
  const first = this.visit(node.children[0], value);
3076
3058
  const second = this.visit(node.children[1], value);
3077
3059
  return this.applyOperator(first, second, '-');
3078
3060
  },
3079
-
3080
3061
  MultiplyExpression: (node, value) => {
3081
3062
  const first = this.visit(node.children[0], value);
3082
3063
  const second = this.visit(node.children[1], value);
3083
3064
  return this.applyOperator(first, second, '*');
3084
3065
  },
3085
-
3086
3066
  DivideExpression: (node, value) => {
3087
3067
  const first = this.visit(node.children[0], value);
3088
3068
  const second = this.visit(node.children[1], value);
3089
3069
  return this.applyOperator(first, second, '/');
3090
3070
  },
3091
-
3092
3071
  PowerExpression: (node, value) => {
3093
3072
  const first = this.visit(node.children[0], value);
3094
3073
  const second = this.visit(node.children[1], value);
3095
3074
  return this.applyOperator(first, second, '^');
3096
3075
  },
3097
-
3098
3076
  NotExpression: (node, value) => {
3099
3077
  const first = this.visit(node.children[0], value);
3100
3078
  return isFalse(first);
3101
3079
  },
3102
-
3103
3080
  UnaryMinusExpression: (node, value) => {
3104
3081
  const first = this.visit(node.children[0], value);
3105
3082
  return first * -1;
3106
3083
  },
3107
-
3108
3084
  Literal: node => node.value,
3109
-
3110
3085
  Number: node => node.value,
3111
-
3112
3086
  [TOK_PIPE$2]: (node, value) => {
3113
3087
  const left = this.visit(node.children[0], value);
3114
3088
  return this.visit(node.children[1], left);
3115
3089
  },
3116
-
3117
3090
  [TOK_CURRENT$2]: (_node, value) => value,
3118
-
3119
3091
  [TOK_GLOBAL$2]: node => {
3120
3092
  const result = this.globals[node.name];
3121
3093
  return result === undefined ? null : result;
3122
3094
  },
3123
-
3124
3095
  Function: (node, value) => {
3125
- // Special case for if()
3126
- // we need to make sure the results are called only after the condition is evaluated
3127
- // Otherwise we end up with both results invoked -- which could include side effects
3128
- // For "if", the last parameter to callFunction is false (bResolved) to indicate there's
3129
- // no point in validating the argument type.
3130
3096
  if (node.name === 'if') return this.runtime.callFunction(node.name, node.children, value, this, false);
3131
3097
  const resolvedArgs = node.children.map(child => this.visit(child, value));
3132
3098
  return this.runtime.callFunction(node.name, resolvedArgs, value, this);
3133
3099
  },
3134
-
3135
3100
  ExpressionReference: node => {
3136
3101
  const [refNode] = node.children;
3137
- // Tag the node with a specific attribute so the type
3138
- // checker verify the type.
3139
3102
  refNode.jmespathType = TOK_EXPREF$2;
3140
3103
  return refNode;
3141
3104
  },
@@ -3144,8 +3107,6 @@ class TreeInterpreter {
3144
3107
  if (!fn) throw new Error(`Unknown/missing node type ${(n && n.type) || ''}`);
3145
3108
  return fn(n, v);
3146
3109
  }
3147
-
3148
- // eslint-disable-next-line class-methods-use-this
3149
3110
  computeSliceParams(arrayLength, sliceParams) {
3150
3111
  function capSliceRange(arrayLen, actual, stp) {
3151
3112
  let actualValue = actual;
@@ -3159,7 +3120,6 @@ class TreeInterpreter {
3159
3120
  }
3160
3121
  return actualValue;
3161
3122
  }
3162
-
3163
3123
  let [start, stop, step] = sliceParams;
3164
3124
  if (step === null) {
3165
3125
  step = 1;
@@ -3169,13 +3129,11 @@ class TreeInterpreter {
3169
3129
  throw error;
3170
3130
  }
3171
3131
  const stepValueNegative = step < 0;
3172
-
3173
3132
  if (start === null) {
3174
3133
  start = stepValueNegative ? arrayLength - 1 : 0;
3175
3134
  } else {
3176
3135
  start = capSliceRange(arrayLength, start, step);
3177
3136
  }
3178
-
3179
3137
  if (stop === null) {
3180
3138
  stop = stepValueNegative ? -1 : arrayLength;
3181
3139
  } else {
@@ -3183,10 +3141,8 @@ class TreeInterpreter {
3183
3141
  }
3184
3142
  return [start, stop, step];
3185
3143
  }
3186
-
3187
3144
  applyOperator(first, second, operator) {
3188
3145
  if (isArray(first) && isArray(second)) {
3189
- // balance the size of the arrays
3190
3146
  const shorter = first.length < second.length ? first : second;
3191
3147
  const diff = Math.abs(first.length - second.length);
3192
3148
  shorter.length += diff;
@@ -3197,10 +3153,8 @@ class TreeInterpreter {
3197
3153
  }
3198
3154
  return result;
3199
3155
  }
3200
-
3201
3156
  if (isArray(first)) return first.map(a => this.applyOperator(a, second, operator));
3202
3157
  if (isArray(second)) return second.map(a => this.applyOperator(first, a, operator));
3203
-
3204
3158
  if (operator === '*') return this.toNumber(first) * this.toNumber(second);
3205
3159
  if (operator === '&') return first + second;
3206
3160
  if (operator === '+') {
@@ -3218,8 +3172,6 @@ class TreeInterpreter {
3218
3172
  }
3219
3173
  }
3220
3174
 
3221
- /* eslint-disable no-underscore-dangle */
3222
-
3223
3175
  const {
3224
3176
  TOK_UNQUOTEDIDENTIFIER: TOK_UNQUOTEDIDENTIFIER$1,
3225
3177
  TOK_QUOTEDIDENTIFIER: TOK_QUOTEDIDENTIFIER$1,
@@ -3259,16 +3211,8 @@ const {
3259
3211
  TOK_LPAREN: TOK_LPAREN$1,
3260
3212
  TOK_LITERAL: TOK_LITERAL$1,
3261
3213
  } = tokenDefinitions;
3262
-
3263
- // The "&", "[", "<", ">" tokens
3264
- // are not in basicToken because
3265
- // there are two token variants
3266
- // ("&&", "[?", "<=", ">="). This is specially handled
3267
- // below.
3268
-
3269
3214
  const basicTokens = {
3270
3215
  '.': TOK_DOT$1,
3271
- // "*": TOK_STAR,
3272
3216
  ',': TOK_COMMA$1,
3273
3217
  ':': TOK_COLON$1,
3274
3218
  '{': TOK_LBRACE$1,
@@ -3278,7 +3222,6 @@ const basicTokens = {
3278
3222
  ')': TOK_RPAREN$1,
3279
3223
  '@': TOK_CURRENT$1,
3280
3224
  };
3281
-
3282
3225
  const globalStartToken = '$';
3283
3226
  const operatorStartToken = {
3284
3227
  '<': true,
@@ -3286,42 +3229,34 @@ const operatorStartToken = {
3286
3229
  '=': true,
3287
3230
  '!': true,
3288
3231
  };
3289
-
3290
3232
  const skipChars = {
3291
3233
  ' ': true,
3292
3234
  '\t': true,
3293
3235
  '\n': true,
3294
3236
  };
3295
-
3296
3237
  function isNum(ch) {
3297
3238
  return (ch >= '0' && ch <= '9') || (ch === '.');
3298
3239
  }
3299
-
3300
3240
  function isAlphaNum(ch) {
3301
3241
  return (ch >= 'a' && ch <= 'z')
3302
3242
  || (ch >= 'A' && ch <= 'Z')
3303
3243
  || (ch >= '0' && ch <= '9')
3304
3244
  || ch === '_';
3305
3245
  }
3306
-
3307
3246
  function isIdentifier(stream, pos) {
3308
3247
  const ch = stream[pos];
3309
- // $ is special -- it's allowed to be part of an identifier if it's the first character
3310
3248
  if (ch === '$') {
3311
3249
  return stream.length > pos && isAlphaNum(stream[pos + 1]);
3312
3250
  }
3313
- // return whether character 'isAlpha'
3314
3251
  return (ch >= 'a' && ch <= 'z')
3315
3252
  || (ch >= 'A' && ch <= 'Z')
3316
3253
  || ch === '_';
3317
3254
  }
3318
-
3319
3255
  class Lexer {
3320
3256
  constructor(allowedGlobalNames = [], debug = []) {
3321
3257
  this._allowedGlobalNames = allowedGlobalNames;
3322
3258
  this.debug = debug;
3323
3259
  }
3324
-
3325
3260
  tokenize(stream) {
3326
3261
  const tokens = [];
3327
3262
  this._current = 0;
@@ -3330,7 +3265,6 @@ class Lexer {
3330
3265
  let token;
3331
3266
  while (this._current < stream.length) {
3332
3267
  const prev = tokens.length ? tokens.slice(-1)[0].type : null;
3333
-
3334
3268
  if (this._isGlobal(prev, stream, this._current)) {
3335
3269
  tokens.push(this._consumeGlobal(stream));
3336
3270
  } else if (isIdentifier(stream, this._current)) {
@@ -3355,8 +3289,6 @@ class Lexer {
3355
3289
  token = this._consumeNumber(stream);
3356
3290
  tokens.push(token);
3357
3291
  } else if (stream[this._current] === '[') {
3358
- // No need to increment this._current. This happens
3359
- // in _consumeLBracket
3360
3292
  token = this._consumeLBracket(stream);
3361
3293
  tokens.push(token);
3362
3294
  } else if (stream[this._current] === '"') {
@@ -3386,7 +3318,6 @@ class Lexer {
3386
3318
  } else if (operatorStartToken[stream[this._current]] !== undefined) {
3387
3319
  tokens.push(this._consumeOperator(stream));
3388
3320
  } else if (skipChars[stream[this._current]] !== undefined) {
3389
- // Ignore whitespace.
3390
3321
  this._current += 1;
3391
3322
  } else if (stream[this._current] === '&') {
3392
3323
  start = this._current;
@@ -3395,9 +3326,6 @@ class Lexer {
3395
3326
  this._current += 1;
3396
3327
  tokens.push({ type: TOK_AND$1, value: '&&', start });
3397
3328
  } else if (prev === TOK_COMMA$1 || prev === TOK_LPAREN$1) {
3398
- // based on previous token we'll know if this & is a JMESPath expression-type
3399
- // or if it's a concatenation operator
3400
- // if we're a function arg then it's an expression-type
3401
3329
  tokens.push({ type: TOK_EXPREF$1, value: '&', start });
3402
3330
  } else {
3403
3331
  tokens.push({ type: TOK_CONCATENATE$1, value: '&', start });
@@ -3417,8 +3345,6 @@ class Lexer {
3417
3345
  } else if (stream[this._current] === '*') {
3418
3346
  start = this._current;
3419
3347
  this._current += 1;
3420
- // based on previous token we'll know if this asterix is a star -- not a multiply
3421
- // might be better to list the prev tokens that are valid for multiply?
3422
3348
  const prevToken = tokens.length && tokens.slice(-1)[0].type;
3423
3349
  if (tokens.length === 0 || [
3424
3350
  TOK_LBRACKET$1,
@@ -3458,7 +3384,6 @@ class Lexer {
3458
3384
  }
3459
3385
  return tokens;
3460
3386
  }
3461
-
3462
3387
  _consumeUnquotedIdentifier(stream) {
3463
3388
  const start = this._current;
3464
3389
  this._current += 1;
@@ -3467,14 +3392,12 @@ class Lexer {
3467
3392
  }
3468
3393
  return stream.slice(start, this._current);
3469
3394
  }
3470
-
3471
3395
  _consumeQuotedIdentifier(stream) {
3472
3396
  const start = this._current;
3473
3397
  this._current += 1;
3474
3398
  const maxLength = stream.length;
3475
3399
  let foundNonAlpha = !isIdentifier(stream, start + 1);
3476
3400
  while (stream[this._current] !== '"' && this._current < maxLength) {
3477
- // You can escape a double quote and you can escape an escape.
3478
3401
  let current = this._current;
3479
3402
  if (!isAlphaNum(stream[current])) foundNonAlpha = true;
3480
3403
  if (stream[current] === '\\' && (stream[current + 1] === '\\'
@@ -3487,26 +3410,19 @@ class Lexer {
3487
3410
  }
3488
3411
  this._current += 1;
3489
3412
  const val = stream.slice(start, this._current);
3490
- // Check for unnecessary double quotes.
3491
- // json-formula uses double quotes to escape characters that don't belong in names names.
3492
- // e.g. "purchase-order".address
3493
- // If we find a double-quoted entity with spaces or all legal characters, issue a warning
3494
3413
  try {
3495
3414
  if (!foundNonAlpha || val.includes(' ')) {
3496
3415
  this.debug.push(`Suspicious quotes: ${val}`);
3497
3416
  this.debug.push(`Did you intend a literal? '${val.replace(/"/g, '')}'?`);
3498
3417
  }
3499
- // eslint-disable-next-line no-empty
3500
3418
  } catch (e) {}
3501
3419
  return JSON.parse(val);
3502
3420
  }
3503
-
3504
3421
  _consumeRawStringLiteral(stream) {
3505
3422
  const start = this._current;
3506
3423
  this._current += 1;
3507
3424
  const maxLength = stream.length;
3508
3425
  while (stream[this._current] !== "'" && this._current < maxLength) {
3509
- // You can escape a single quote and you can escape an escape.
3510
3426
  let current = this._current;
3511
3427
  if (stream[current] === '\\' && (stream[current + 1] === '\\'
3512
3428
  || stream[current + 1] === "'")) {
@@ -3520,7 +3436,6 @@ class Lexer {
3520
3436
  const literal = stream.slice(start + 1, this._current - 1);
3521
3437
  return literal.replaceAll("\\'", "'");
3522
3438
  }
3523
-
3524
3439
  _consumeNumber(stream) {
3525
3440
  const start = this._current;
3526
3441
  this._current += 1;
@@ -3537,13 +3452,11 @@ class Lexer {
3537
3452
  }
3538
3453
  return { type: TOK_NUMBER$1, value, start };
3539
3454
  }
3540
-
3541
3455
  _consumeUnaryMinus() {
3542
3456
  const start = this._current;
3543
3457
  this._current += 1;
3544
3458
  return { type: TOK_UNARY_MINUS$1, value: '-', start };
3545
3459
  }
3546
-
3547
3460
  _consumeLBracket(stream) {
3548
3461
  const start = this._current;
3549
3462
  this._current += 1;
@@ -3557,28 +3470,22 @@ class Lexer {
3557
3470
  }
3558
3471
  return { type: TOK_LBRACKET$1, value: '[', start };
3559
3472
  }
3560
-
3561
3473
  _isGlobal(prev, stream, pos) {
3562
- // global tokens occur only at the start of an expression
3563
3474
  if (prev !== null && prev === TOK_DOT$1) return false;
3564
3475
  const ch = stream[pos];
3565
3476
  if (ch !== globalStartToken) return false;
3566
- // $ is special -- it's allowed to be part of an identifier if it's the first character
3567
3477
  let i = pos + 1;
3568
3478
  while (i < stream.length && isAlphaNum(stream[i])) i += 1;
3569
3479
  const global = stream.slice(pos, i);
3570
3480
  return this._allowedGlobalNames.includes(global);
3571
3481
  }
3572
-
3573
3482
  _consumeGlobal(stream) {
3574
3483
  const start = this._current;
3575
3484
  this._current += 1;
3576
3485
  while (this._current < stream.length && isAlphaNum(stream[this._current])) this._current += 1;
3577
3486
  const global = stream.slice(start, this._current);
3578
-
3579
3487
  return { type: TOK_GLOBAL$1, name: global, start };
3580
3488
  }
3581
-
3582
3489
  _consumeOperator(stream) {
3583
3490
  const start = this._current;
3584
3491
  const startingChar = stream[start];
@@ -3604,20 +3511,17 @@ class Lexer {
3604
3511
  }
3605
3512
  return { type: TOK_GT$1, value: '>', start };
3606
3513
  }
3607
- // startingChar is '='
3608
3514
  if (stream[this._current] === '=') {
3609
3515
  this._current += 1;
3610
3516
  return { type: TOK_EQ$1, value: '==', start };
3611
3517
  }
3612
3518
  return { type: TOK_EQ$1, value: '=', start };
3613
3519
  }
3614
-
3615
3520
  _consumeLiteral(stream) {
3616
3521
  function _looksLikeJSON(str) {
3617
3522
  if (str === '') return false;
3618
3523
  if ('[{"'.includes(str[0])) return true;
3619
3524
  if (['true', 'false', 'null'].includes(str)) return true;
3620
-
3621
3525
  if ('-0123456789'.includes(str[0])) {
3622
3526
  try {
3623
3527
  JSON.parse(str);
@@ -3629,7 +3533,6 @@ class Lexer {
3629
3533
  return false;
3630
3534
  }
3631
3535
  }
3632
-
3633
3536
  this._current += 1;
3634
3537
  const start = this._current;
3635
3538
  const maxLength = stream.length;
@@ -3637,14 +3540,12 @@ class Lexer {
3637
3540
  let inQuotes = false;
3638
3541
  while ((inQuotes || stream[this._current] !== '`') && this._current < maxLength) {
3639
3542
  let current = this._current;
3640
- // bypass escaped double quotes when we're inside quotes
3641
3543
  if (inQuotes && stream[current] === '\\' && stream[current + 1] === '"') current += 2;
3642
3544
  else {
3643
3545
  if (stream[current] === '"') inQuotes = !inQuotes;
3644
3546
  if (inQuotes && stream[current + 1] === '`') current += 2;
3645
3547
  else if (stream[current] === '\\' && (stream[current + 1] === '\\'
3646
3548
  || stream[current + 1] === '`')) {
3647
- // You can escape a literal char or you can escape the escape.
3648
3549
  current += 2;
3649
3550
  } else {
3650
3551
  current += 1;
@@ -3657,16 +3558,13 @@ class Lexer {
3657
3558
  if (_looksLikeJSON(literalString)) {
3658
3559
  literal = JSON.parse(literalString);
3659
3560
  } else {
3660
- // Try to JSON parse it as "<literal>"
3661
3561
  literal = JSON.parse(`"${literalString}"`);
3662
3562
  }
3663
- // +1 gets us to the ending "`", +1 to move on to the next char.
3664
3563
  this._current += 1;
3665
3564
  return literal;
3666
3565
  }
3667
3566
  }
3668
3567
 
3669
- /* eslint-disable no-underscore-dangle */
3670
3568
  const {
3671
3569
  TOK_LITERAL,
3672
3570
  TOK_COLON,
@@ -3708,7 +3606,6 @@ const {
3708
3606
  TOK_LBRACKET,
3709
3607
  TOK_LPAREN,
3710
3608
  } = tokenDefinitions;
3711
-
3712
3609
  const bindingPower = {
3713
3610
  [TOK_EOF]: 0,
3714
3611
  [TOK_UNQUOTEDIDENTIFIER]: 0,
@@ -3748,12 +3645,10 @@ const bindingPower = {
3748
3645
  [TOK_LBRACKET]: 55,
3749
3646
  [TOK_LPAREN]: 60,
3750
3647
  };
3751
-
3752
3648
  class Parser {
3753
3649
  constructor(allowedGlobalNames = []) {
3754
3650
  this._allowedGlobalNames = allowedGlobalNames;
3755
3651
  }
3756
-
3757
3652
  parse(expression, debug) {
3758
3653
  this._loadTokens(expression, debug);
3759
3654
  this.index = 0;
@@ -3768,14 +3663,12 @@ class Parser {
3768
3663
  }
3769
3664
  return ast;
3770
3665
  }
3771
-
3772
3666
  _loadTokens(expression, debug) {
3773
3667
  const lexer = new Lexer(this._allowedGlobalNames, debug);
3774
3668
  const tokens = lexer.tokenize(expression);
3775
3669
  tokens.push({ type: TOK_EOF, value: '', start: expression.length });
3776
3670
  this.tokens = tokens;
3777
3671
  }
3778
-
3779
3672
  expression(rbp) {
3780
3673
  const leftToken = this._lookaheadToken(0);
3781
3674
  this._advance();
@@ -3788,28 +3681,21 @@ class Parser {
3788
3681
  }
3789
3682
  return left;
3790
3683
  }
3791
-
3792
3684
  _lookahead(number) {
3793
3685
  return this.tokens[this.index + number].type;
3794
3686
  }
3795
-
3796
3687
  _lookaheadToken(number) {
3797
3688
  return this.tokens[this.index + number];
3798
3689
  }
3799
-
3800
3690
  _advance() {
3801
3691
  this.index += 1;
3802
3692
  }
3803
-
3804
3693
  _getIndex() {
3805
3694
  return this.index;
3806
3695
  }
3807
-
3808
3696
  _setIndex(index) {
3809
3697
  this.index = index;
3810
3698
  }
3811
-
3812
- // eslint-disable-next-line consistent-return
3813
3699
  nud(token) {
3814
3700
  let left;
3815
3701
  let right;
@@ -3838,8 +3724,6 @@ class Parser {
3838
3724
  case TOK_STAR:
3839
3725
  left = { type: 'Identity' };
3840
3726
  if (this._lookahead(0) === TOK_RBRACKET) {
3841
- // This can happen in a multiselect,
3842
- // [a, b, *]
3843
3727
  right = { type: 'Identity' };
3844
3728
  } else {
3845
3729
  right = this._parseProjectionRHS(bindingPower.Star);
@@ -3886,8 +3770,6 @@ class Parser {
3886
3770
  this._errorToken(token);
3887
3771
  }
3888
3772
  }
3889
-
3890
- // eslint-disable-next-line consistent-return
3891
3773
  led(tokenName, left) {
3892
3774
  let condition;
3893
3775
  let right;
@@ -3908,7 +3790,6 @@ class Parser {
3908
3790
  right = this._parseDotRHS(rbp);
3909
3791
  return { type: 'Subexpression', children: [left, right] };
3910
3792
  }
3911
- // Creating a projection.
3912
3793
  this._advance();
3913
3794
  right = this._parseProjectionRHS(rbp);
3914
3795
  return { type: 'ValueProjection', children: [left, right] };
@@ -3986,7 +3867,6 @@ class Parser {
3986
3867
  this._errorToken(this._lookaheadToken(0));
3987
3868
  }
3988
3869
  }
3989
-
3990
3870
  _match(tokenType) {
3991
3871
  if (this._lookahead(0) === tokenType) {
3992
3872
  this._advance();
@@ -3997,8 +3877,6 @@ class Parser {
3997
3877
  throw error;
3998
3878
  }
3999
3879
  }
4000
-
4001
- // eslint-disable-next-line class-methods-use-this
4002
3880
  _errorToken(token) {
4003
3881
  const error = new Error(`Invalid token (${
4004
3882
  token.type}): "${
@@ -4006,17 +3884,14 @@ class Parser {
4006
3884
  error.name = 'ParserError';
4007
3885
  throw error;
4008
3886
  }
4009
-
4010
3887
  _parseChainedIndexExpression() {
4011
3888
  const oldIndex = this._getIndex();
4012
3889
  if (this._lookahead(0) === TOK_COLON) {
4013
3890
  return this._parseSliceExpression();
4014
3891
  }
4015
- // look ahead of the first expression to determine the type
4016
3892
  const first = this.expression(0);
4017
3893
  const token = this._lookahead(0);
4018
3894
  if (token === TOK_COLON) {
4019
- // now that we know the type revert back to the old position and parse
4020
3895
  this._setIndex(oldIndex);
4021
3896
  return this._parseSliceExpression();
4022
3897
  }
@@ -4026,7 +3901,6 @@ class Parser {
4026
3901
  value: first,
4027
3902
  };
4028
3903
  }
4029
-
4030
3904
  _parseUnchainedIndexExpression() {
4031
3905
  const oldIndex = this._getIndex();
4032
3906
  const firstToken = this._lookahead(0);
@@ -4055,7 +3929,6 @@ class Parser {
4055
3929
  this._setIndex(oldIndex);
4056
3930
  return this._parseMultiselectList();
4057
3931
  }
4058
-
4059
3932
  _projectIfSlice(left, right) {
4060
3933
  const indexExpr = { type: 'IndexExpression', children: [left, right] };
4061
3934
  if (right.type === 'Slice') {
@@ -4066,20 +3939,16 @@ class Parser {
4066
3939
  }
4067
3940
  return indexExpr;
4068
3941
  }
4069
-
4070
3942
  _parseSliceExpression() {
4071
- // [start:end:step] where each part is optional, as well as the last
4072
- // colon.
4073
3943
  const parts = [null, null, null];
4074
3944
  let index = 0;
4075
3945
  let currentToken = this._lookahead(0);
4076
3946
  while (currentToken !== TOK_RBRACKET && index < 3) {
4077
- if (currentToken === TOK_COLON && index < 2) { // there can't be more than 2 colons
3947
+ if (currentToken === TOK_COLON && index < 2) {
4078
3948
  index += 1;
4079
3949
  this._advance();
4080
3950
  } else {
4081
3951
  parts[index] = this.expression(0);
4082
- // check next token to be either colon or rbracket
4083
3952
  const t = this._lookahead(0);
4084
3953
  if (t !== TOK_COLON && t !== TOK_RBRACKET) {
4085
3954
  const error = new Error(`Syntax error, unexpected token: ${
@@ -4096,13 +3965,10 @@ class Parser {
4096
3965
  children: parts,
4097
3966
  };
4098
3967
  }
4099
-
4100
3968
  _parseComparator(left, comparator) {
4101
3969
  const right = this.expression(bindingPower[comparator]);
4102
3970
  return { type: 'Comparator', name: comparator, children: [left, right] };
4103
3971
  }
4104
-
4105
- // eslint-disable-next-line consistent-return
4106
3972
  _parseDotRHS(rbp) {
4107
3973
  const lookahead = this._lookahead(0);
4108
3974
  const exprTokens = [TOK_UNQUOTEDIDENTIFIER, TOK_QUOTEDIDENTIFIER, TOK_STAR];
@@ -4118,7 +3984,6 @@ class Parser {
4118
3984
  return this._parseMultiselectHash();
4119
3985
  }
4120
3986
  }
4121
-
4122
3987
  _parseProjectionRHS(rbp) {
4123
3988
  let right;
4124
3989
  if (bindingPower[this._lookahead(0)] < 10) {
@@ -4139,7 +4004,6 @@ class Parser {
4139
4004
  }
4140
4005
  return right;
4141
4006
  }
4142
-
4143
4007
  _parseMultiselectList() {
4144
4008
  const expressions = [];
4145
4009
  while (this._lookahead(0) !== TOK_RBRACKET) {
@@ -4155,7 +4019,6 @@ class Parser {
4155
4019
  this._match(TOK_RBRACKET);
4156
4020
  return { type: 'MultiSelectList', children: expressions };
4157
4021
  }
4158
-
4159
4022
  _parseMultiselectHash() {
4160
4023
  const pairs = [];
4161
4024
  const identifierTypes = [TOK_UNQUOTEDIDENTIFIER, TOK_QUOTEDIDENTIFIER];
@@ -4188,20 +4051,6 @@ class Parser {
4188
4051
  }
4189
4052
  }
4190
4053
 
4191
- /*
4192
- Copyright 2021 Adobe. All rights reserved.
4193
- This file is licensed to you under the Apache License, Version 2.0 (the "License");
4194
- you may not use this file except in compliance with the License. You may obtain a copy
4195
- of the License at http://www.apache.org/licenses/LICENSE-2.0
4196
-
4197
- Unless required by applicable law or agreed to in writing, software distributed under
4198
- the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
4199
- OF ANY KIND, either express or implied. See the License for the specific language
4200
- governing permissions and limitations under the License.
4201
- */
4202
-
4203
- // get the offset in MS, given a date and timezone
4204
- // timezone is an IANA name. e.g. 'America/New_York'
4205
4054
  function offsetMS(dateObj, timeZone) {
4206
4055
  const tzOffset = new Intl.DateTimeFormat('en-US', { timeZone, timeZoneName: 'longOffset' }).format(dateObj);
4207
4056
  const offset = /GMT([+\-−])?(\d{1,2}):?(\d{0,2})?/.exec(tzOffset);
@@ -4210,16 +4059,11 @@ function offsetMS(dateObj, timeZone) {
4210
4059
  const result = (((hours || 0) * 60) + 1 * (minutes || 0)) * 60 * 1000;
4211
4060
  return sign === '-' ? result * -1 : result;
4212
4061
  }
4213
-
4214
4062
  function round(num, digits) {
4215
4063
  const precision = 10 ** digits;
4216
4064
  return Math.round(num * precision) / precision;
4217
4065
  }
4218
-
4219
4066
  const MS_IN_DAY = 24 * 60 * 60 * 1000;
4220
-
4221
- // If we create a non-UTC date, then we need to adjust from the default JavaScript timezone
4222
- // to the default timezone
4223
4067
  function adjustTimeZone(dateObj, timeZone) {
4224
4068
  if (dateObj === null) return null;
4225
4069
  let baseDate = Date.UTC(
@@ -4232,32 +4076,10 @@ function adjustTimeZone(dateObj, timeZone) {
4232
4076
  dateObj.getMilliseconds(),
4233
4077
  );
4234
4078
  baseDate += offsetMS(dateObj, timeZone);
4235
-
4236
- // get the offset for the default JS environment
4237
- // return days since the epoch
4238
4079
  return new Date(baseDate);
4239
4080
  }
4240
-
4241
4081
  function openFormulaFunctions(valueOf, toString, toNumber, debug = []) {
4242
4082
  return {
4243
- /**
4244
- * Returns the logical AND result of all parameters.
4245
- * If the parameters are not boolean they will be cast to boolean as per the following rules
4246
- * * null -> false
4247
- * * number -> false if the number is 0, true otherwise
4248
- * * string -> false if the string is empty, true otherwise. String "false" resolves to true
4249
- * * array -> true
4250
- * * object -> true
4251
- * @param {any} firstOperand logical expression
4252
- * @param {...any} [additionalOperands] any number of additional expressions
4253
- * @returns {boolean} The logical result of applying AND to all parameters
4254
- * @example
4255
- * and(10 > 8, length('foo') < 5) // returns true
4256
- * @example
4257
- * and(`null`, length('foo') < 5) // returns false
4258
- * @function
4259
- * @category openFormula
4260
- */
4261
4083
  and: {
4262
4084
  _func: resolvedArgs => {
4263
4085
  let result = !!valueOf(resolvedArgs[0]);
@@ -4268,17 +4090,6 @@ function openFormulaFunctions(valueOf, toString, toNumber, debug = []) {
4268
4090
  },
4269
4091
  _signature: [{ types: [dataTypes.TYPE_ANY], variadic: true }],
4270
4092
  },
4271
-
4272
- /**
4273
- * Returns a lower-case string of the `input` string using locale-specific mappings.
4274
- * e.g. Strings with German lowercase letter 'ß' can be compared to 'ss'
4275
- * @param {string} input string to casefold
4276
- * @returns {string} A new string converted to lower case
4277
- * @function casefold
4278
- * @example
4279
- * casefold('AbC') // returns 'abc'
4280
- * @category JSONFormula
4281
- */
4282
4093
  casefold: {
4283
4094
  _func: (args, _data, interpreter) => {
4284
4095
  const str = toString(args[0]);
@@ -4288,34 +4099,6 @@ function openFormulaFunctions(valueOf, toString, toNumber, debug = []) {
4288
4099
  { types: [dataTypes.TYPE_STRING] },
4289
4100
  ],
4290
4101
  },
4291
-
4292
- /**
4293
- * Return difference between two date values.
4294
- * @param {number} start_date The starting date.
4295
- * Dates should be entered by using the [datetime]{@link datetime} function
4296
- * @param {number} end_date The end date -- must be greater or equal to start_date.
4297
- * Dates should be entered by using the [datetime]{@link datetime} function
4298
- * @param {string} unit One of:
4299
- * * `y` the number of whole years between start_date and end_date
4300
- * * `m` the number of whole months between start_date and end_date.
4301
- * * `d` the number of days between start_date and end_date
4302
- * * `md` the number of days between start_date and end_date after subtracting whole months.
4303
- * * `ym` the number of whole months between start_date and end_date
4304
- * after subtracting whole years.
4305
- * * `yd` the number of days between start_date and end_date, assuming start_date
4306
- * and end_date were no more than one year apart
4307
- * @returns {integer} The number of days/months/years difference
4308
- * @function
4309
- * @category openFormula
4310
- * @example
4311
- * datedif(datetime(2001, 1, 1), datetime(2003, 1, 1), 'y') // returns 2
4312
- * @example
4313
- * datedif(datetime(2001, 6, 1), datetime(2003, 8, 15), 'D') // returns 440
4314
- * // 440 days between June 1, 2001, and August 15, 2002 (440)
4315
- * @example
4316
- * datedif(datetime(2001, 6, 1), datetime(2003, 8, 15), 'YD') // returns 440
4317
- * // 75 days between June 1 and August 15, ignoring the years of the dates (75)
4318
- */
4319
4102
  datedif: {
4320
4103
  _func: args => {
4321
4104
  const d1 = toNumber(args[0]);
@@ -4329,7 +4112,6 @@ function openFormulaFunctions(valueOf, toString, toNumber, debug = []) {
4329
4112
  const yearDiff = date2.getFullYear() - date1.getFullYear();
4330
4113
  let monthDiff = date2.getMonth() - date1.getMonth();
4331
4114
  const dayDiff = date2.getDate() - date1.getDate();
4332
-
4333
4115
  if (unit === 'y') {
4334
4116
  let y = yearDiff;
4335
4117
  if (monthDiff < 0) y -= 1;
@@ -4358,32 +4140,6 @@ function openFormulaFunctions(valueOf, toString, toNumber, debug = []) {
4358
4140
  { types: [dataTypes.TYPE_STRING] },
4359
4141
  ],
4360
4142
  },
4361
-
4362
- /**
4363
- * Return a date/time value.
4364
- * @param {integer} year Integer value representing the year.
4365
- * Values from 0 to 99 map to the years 1900 to 1999. All other values are the actual year
4366
- * @param {integer} month Integer value representing the month, beginning with 1 for
4367
- * January to 12 for December.
4368
- * @param {integer} day Integer value representing the day of the month.
4369
- * @param {integer} [hours] Integer value between 0 and 23 representing the hour of the day.
4370
- * Defaults to 0.
4371
- * @param {integer} [minutes] Integer value representing the minute segment of a time.
4372
- * The default is 0 minutes past the hour.
4373
- * @param {integer} [seconds] Integer value representing the second segment of a time.
4374
- * The default is 0 seconds past the minute.
4375
- * @param {integer} [milliseconds] Integer value representing the millisecond segment of a time.
4376
- * The default is 0 milliseconds past the second.
4377
- * @param {string} [timeZoneName] according to IANA time zone names. e.g. "America/Toronto"
4378
- * @returns {number} A date/time value represented by number of seconds since 1 January 1970.
4379
- * @kind function
4380
- * @function
4381
- * @category JSONFormula
4382
- * @example
4383
- * datetime(2010, 10, 10) // returns representation of October 10, 2010
4384
- * @example
4385
- * datetime(2010, 2, 28) // returns representation of February 28, 2010
4386
- */
4387
4143
  datetime: {
4388
4144
  _func: args => {
4389
4145
  const year = toNumber(args[0]);
@@ -4394,7 +4150,6 @@ function openFormulaFunctions(valueOf, toString, toNumber, debug = []) {
4394
4150
  const seconds = args.length > 5 ? toNumber(args[5]) : 0;
4395
4151
  const ms = args.length > 6 ? toNumber(args[6]) : 0;
4396
4152
  const tz = args.length > 7 ? toString(args[7]) : null;
4397
- // javascript months starts from 0
4398
4153
  let jsDate = new Date(year, month - 1, day, hours, minutes, seconds, ms);
4399
4154
  if (tz) {
4400
4155
  jsDate = adjustTimeZone(jsDate, tz);
@@ -4412,18 +4167,6 @@ function openFormulaFunctions(valueOf, toString, toNumber, debug = []) {
4412
4167
  { types: [dataTypes.TYPE_STRING], optional: true },
4413
4168
  ],
4414
4169
  },
4415
-
4416
- /**
4417
- * Returns the day of a date, represented by a serial number.
4418
- * The day is given as an integer ranging from 1 to 31.
4419
- * @param {number} The date of the day you are trying to find.
4420
- * Dates should be entered by using the [datetime]{@link datetime} function
4421
- * @return {number}
4422
- * @function day
4423
- * @category openFormula
4424
- * @example
4425
- * day(datetime(2008,5,23)) //returns 23
4426
- */
4427
4170
  day: {
4428
4171
  _func: args => {
4429
4172
  const date = toNumber(args[0]);
@@ -4434,19 +4177,6 @@ function openFormulaFunctions(valueOf, toString, toNumber, debug = []) {
4434
4177
  { types: [dataTypes.TYPE_NUMBER] },
4435
4178
  ],
4436
4179
  },
4437
-
4438
- /**
4439
- * Searches a nested hierarchy of objects to return an array of elements that match a `name`.
4440
- * The name can be either a key into a map or an array index.
4441
- * This is similar to the JSONPath deep scan operator (..)
4442
- * @param {object} object The starting object or array where we start the search
4443
- * @param {string} name The name (or index position) of the elements to find
4444
- * @returns {any}
4445
- * @function
4446
- * @category JSONFormula
4447
- * @example
4448
- * deepScan({a : {b1 : {c : 2}, b2 : {c : 3}}}, 'c') //returns [2, 3]
4449
- */
4450
4180
  deepScan: {
4451
4181
  _func: resolvedArgs => {
4452
4182
  const [source, n] = resolvedArgs;
@@ -4467,16 +4197,6 @@ function openFormulaFunctions(valueOf, toString, toNumber, debug = []) {
4467
4197
  { types: [dataTypes.TYPE_STRING, dataTypes.TYPE_NUMBER] },
4468
4198
  ],
4469
4199
  },
4470
-
4471
- /**
4472
- * returns an array of a given object's property `[key, value]` pairs.
4473
- * @param {object} obj Object whose `[key, value]` pairs need to be extracted
4474
- * @returns {any[]} an array of [key, value] pairs
4475
- * @function entries
4476
- * @category JSONFormula
4477
- * @example
4478
- * entries({a: 1, b: 2}) //returns [['a', 1], ['b', 2]]
4479
- */
4480
4200
  entries: {
4481
4201
  _func: args => {
4482
4202
  const obj = valueOf(args[0]);
@@ -4494,27 +4214,11 @@ function openFormulaFunctions(valueOf, toString, toNumber, debug = []) {
4494
4214
  },
4495
4215
  ],
4496
4216
  },
4497
-
4498
- /**
4499
- * Returns the serial number of the end of a month, given `startDate` plus `monthAdd` months
4500
- * @param {number} startDate The base date to start from.
4501
- * Dates should be entered by using the [datetime]{@link datetime} function
4502
- * @param {integer} monthAdd Number of months to add to start date
4503
- * @return {integer} the number of days in the computed month
4504
- * @function
4505
- * @category openFormula
4506
- * @example
4507
- * eomonth(datetime(2011, 1, 1), 1) //returns datetime(2011, 2, 28)
4508
- * @example
4509
- * eomonth(datetime(2011, 1, 1), -3) //returns datetime(2010, 10, 31)
4510
- */
4511
4217
  eomonth: {
4512
4218
  _func: args => {
4513
4219
  const date = toNumber(args[0]);
4514
4220
  const months = toNumber(args[1]);
4515
4221
  const jsDate = new Date(date * MS_IN_DAY);
4516
- // We can give the constructor a month value > 11 and it will increment the years
4517
- // Since day is 1-based, giving zero will yield the last day of the previous month
4518
4222
  const newDate = new Date(jsDate.getFullYear(), jsDate.getMonth() + months + 1, 0);
4519
4223
  return newDate.getTime() / MS_IN_DAY;
4520
4224
  },
@@ -4523,16 +4227,6 @@ function openFormulaFunctions(valueOf, toString, toNumber, debug = []) {
4523
4227
  { types: [dataTypes.TYPE_NUMBER] },
4524
4228
  ],
4525
4229
  },
4526
-
4527
- /**
4528
- * Returns e (the base of natural logarithms) raised to a power x. (i.e. e<sup>x</sup>)
4529
- * @param x {number} A numeric expression representing the power of e.
4530
- * @returns {number} e (the base of natural logarithms) raised to a power x
4531
- * @function exp
4532
- * @category openFormula
4533
- * @example
4534
- * exp(10) //returns e^10
4535
- */
4536
4230
  exp: {
4537
4231
  _func: args => {
4538
4232
  const value = toNumber(args[0]);
@@ -4542,37 +4236,10 @@ function openFormulaFunctions(valueOf, toString, toNumber, debug = []) {
4542
4236
  { types: [dataTypes.TYPE_NUMBER] },
4543
4237
  ],
4544
4238
  },
4545
-
4546
- /**
4547
- * Return constant boolean false value.
4548
- * Note that expressions may also use the JSON literal false: `` `false` ``
4549
- * @returns {boolean} constant boolean value `false`
4550
- * @function
4551
- * @category openFormula
4552
- */
4553
4239
  false: {
4554
4240
  _func: () => false,
4555
4241
  _signature: [],
4556
4242
  },
4557
-
4558
- /**
4559
- * finds and returns the index of query in text from a start position
4560
- * @param {string} query string to search
4561
- * @param {string} text text in which the query has to be searched
4562
- * @param {number} [start] starting position: defaults to 0
4563
- * @returns {number|null} the index of the query to be searched in the text. If not found
4564
- * returns null
4565
- * @function
4566
- * @category openFormula
4567
- * @example
4568
- * find('m', 'abm') //returns 2
4569
- * @example
4570
- * find('M', 'abMcdM', 3) //returns 2
4571
- * @example
4572
- * find('M', 'ab') //returns `null`
4573
- * @example
4574
- * find('M', 'abMcdM', 2) //returns 2
4575
- */
4576
4243
  find: {
4577
4244
  _func: args => {
4578
4245
  const query = toString(args[0]);
@@ -4590,16 +4257,6 @@ function openFormulaFunctions(valueOf, toString, toNumber, debug = []) {
4590
4257
  { types: [dataTypes.TYPE_NUMBER], optional: true },
4591
4258
  ],
4592
4259
  },
4593
-
4594
- /**
4595
- * returns an object by transforming a list of key-value `pairs` into an object.
4596
- * @param {any[]} pairs list of key-value pairs to create the object from
4597
- * @returns {object}
4598
- * @category JSONFormula
4599
- * @function fromEntries
4600
- * @example
4601
- * fromEntries([['a', 1], ['b', 2]]) //returns {a: 1, b: 2}
4602
- */
4603
4260
  fromEntries: {
4604
4261
  _func: args => {
4605
4262
  const array = args[0];
@@ -4609,51 +4266,19 @@ function openFormulaFunctions(valueOf, toString, toNumber, debug = []) {
4609
4266
  { types: [dataTypes.TYPE_ARRAY_ARRAY] },
4610
4267
  ],
4611
4268
  },
4612
-
4613
- /**
4614
- * Extract the hour (0 through 23) from a time/datetime representation
4615
- * @param {number} The datetime/time for which the hour is to be returned.
4616
- * Dates should be specified using the [datetime]{@link datetime} or [time]{@link time} function
4617
- * @return {number}
4618
- * @function hour
4619
- * @category openFormula
4620
- * @example
4621
- * hour(datetime(2008,5,23,12, 0, 0)) //returns 12
4622
- * hour(time(12, 0, 0)) //returns 12
4623
- */
4624
4269
  hour: {
4625
4270
  _func: args => {
4626
- // grab just the fraction part
4627
4271
  const time = toNumber(args[0]) % 1;
4628
4272
  if (time < 0) {
4629
4273
  return null;
4630
4274
  }
4631
- // Normally we'd round to 15 digits, but since we're also multiplying by 24,
4632
- // a reasonable precision is around 14 digits.
4633
-
4634
4275
  const hour = round(time * 24, 14);
4635
-
4636
4276
  return Math.floor(hour % 24);
4637
4277
  },
4638
4278
  _signature: [
4639
4279
  { types: [dataTypes.TYPE_NUMBER] },
4640
4280
  ],
4641
4281
  },
4642
-
4643
- /**
4644
- * Return one of two values `result1` or `result2`, depending on the `condition`
4645
- * @returns {boolean} True
4646
- * @param {any} condition logical expression to evaluate
4647
- * @param {any} result1 if logical condition is true
4648
- * @param {any} result2 if logical condition is false
4649
- * @return {any} either result1 or result2
4650
- * @function
4651
- * @category openFormula
4652
- * @example
4653
- * if(true(), 1, 2) // returns 1
4654
- * @example
4655
- * if(false(), 1, 2) // returns 2
4656
- */
4657
4282
  if: {
4658
4283
  _func: (unresolvedArgs, data, interpreter) => {
4659
4284
  const conditionNode = unresolvedArgs[0];
@@ -4670,22 +4295,6 @@ function openFormulaFunctions(valueOf, toString, toNumber, debug = []) {
4670
4295
  { types: [dataTypes.TYPE_ANY] },
4671
4296
  { types: [dataTypes.TYPE_ANY] }],
4672
4297
  },
4673
-
4674
- /**
4675
- * Return a selected number of text characters from the left or
4676
- * in case of array selected number of elements from the start
4677
- * @param {string|array} subject The text/array of characters/elements to extract.
4678
- * @param {number} [elements] number of elements to pick. Defaults to 1
4679
- * @return {string|array}
4680
- * @function left
4681
- * @category openFormula
4682
- * @example
4683
- * left('Sale Price', 4) //returns 'Sale'
4684
- * @example
4685
- * left('Sweden') // returns 'S'
4686
- * @example
4687
- * left([4, 5, 6], 2) // returns [4, 5]
4688
- */
4689
4298
  left: {
4690
4299
  _func: args => {
4691
4300
  const numEntries = args.length > 1 ? toNumber(args[1]) : 1;
@@ -4701,18 +4310,6 @@ function openFormulaFunctions(valueOf, toString, toNumber, debug = []) {
4701
4310
  { types: [dataTypes.TYPE_NUMBER], optional: true },
4702
4311
  ],
4703
4312
  },
4704
-
4705
- /**
4706
- * Converts all the alphabetic characters in a string to lowercase. If the value
4707
- * is not a string it will be converted into string
4708
- * using the default toString method
4709
- * @param {string} input input string
4710
- * @returns {string} the lower case value of the input string
4711
- * @function lower
4712
- * @category openFormula
4713
- * @example
4714
- * lower('E. E. Cummings') //returns e. e. cummings
4715
- */
4716
4313
  lower: {
4717
4314
  _func: args => {
4718
4315
  const value = toString(args[0]);
@@ -4722,27 +4319,6 @@ function openFormulaFunctions(valueOf, toString, toNumber, debug = []) {
4722
4319
  { types: [dataTypes.TYPE_STRING] },
4723
4320
  ],
4724
4321
  },
4725
-
4726
- /**
4727
- * Returns extracted text, given an original text, starting position, and length.
4728
- * or in case of array, extracts a subset of the array from start till the length
4729
- * number of elements.
4730
- * Returns null if the `startPos` is greater than the length of the array
4731
- * @param {string|array} subject the text string or array of characters or elements to extract.
4732
- * @param {number} startPos the position of the first character or element to extract.
4733
- * The position starts with 0
4734
- * @param {number} length The number of characters or elements to return from text. If it
4735
- * is greater then the length of `subject` the argument is set to the length of the subject.
4736
- * @return {string|array}
4737
- * @function mid
4738
- * @category openFormula
4739
- * @example
4740
- * mid("Fluid Flow",1,5) //returns 'Fluid'
4741
- * @example
4742
- * mid("Fluid Flow",7,20) //returns 'Flow'
4743
- * @example
4744
- * mid("Fluid Flow",20,5) //returns `null`
4745
- */
4746
4322
  mid: {
4747
4323
  _func: args => {
4748
4324
  const startPos = toNumber(args[1]);
@@ -4760,27 +4336,12 @@ function openFormulaFunctions(valueOf, toString, toNumber, debug = []) {
4760
4336
  { types: [dataTypes.TYPE_NUMBER] },
4761
4337
  ],
4762
4338
  },
4763
-
4764
- /**
4765
- * Extract the minute (0 through 59) from a time/datetime representation
4766
- * @param {number} The datetime/time for which the minute is to be returned.
4767
- * Dates should be specified using the [datetime]{@link datetime} or [time]{@link time} function
4768
- * @return {number}
4769
- * @function minute
4770
- * @category openFormula
4771
- * @example
4772
- * month(datetime(2008,5,23,12, 10, 0)) //returns 10
4773
- * month(time(12, 10, 0)) //returns 10
4774
- */
4775
4339
  minute: {
4776
4340
  _func: args => {
4777
4341
  const time = toNumber(args[0]) % 1;
4778
4342
  if (time < 0) {
4779
4343
  return null;
4780
4344
  }
4781
-
4782
- // Normally we'd round to 15 digits, but since we're also multiplying by 1440,
4783
- // a reasonable precision is around 10 digits.
4784
4345
  const minute = Math.round(time * 1440, 10);
4785
4346
  return Math.floor(minute % 60);
4786
4347
  },
@@ -4788,20 +4349,6 @@ function openFormulaFunctions(valueOf, toString, toNumber, debug = []) {
4788
4349
  { types: [dataTypes.TYPE_NUMBER] },
4789
4350
  ],
4790
4351
  },
4791
-
4792
- /**
4793
- * Return the remainder when one number is divided by another number.
4794
- * The sign is the same as divisor
4795
- * @param {number} dividend The number for which to find the remainder.
4796
- * @param {number} divisor The number by which to divide number.
4797
- * @return {number} Computes the remainder of `dividend`/`divisor`.
4798
- * @function mod
4799
- * @category openFormula
4800
- * @example
4801
- * mod(3, 2) //returns 1
4802
- * @example
4803
- * mod(-3, 2) //returns 1
4804
- */
4805
4352
  mod: {
4806
4353
  _func: args => {
4807
4354
  const p1 = toNumber(args[0]);
@@ -4813,97 +4360,28 @@ function openFormulaFunctions(valueOf, toString, toNumber, debug = []) {
4813
4360
  { types: [dataTypes.TYPE_NUMBER] },
4814
4361
  ],
4815
4362
  },
4816
-
4817
- /**
4818
- * Returns the month of a date represented by a serial number.
4819
- * The month is given as an integer, ranging from 1 (January) to 12 (December).
4820
- * @param {number} The date for which the month is to be returned.
4821
- * Dates should be entered by using the [datetime]{@link datetime} function
4822
- * @return {number}
4823
- * @function month
4824
- * @category openFormula
4825
- * @example
4826
- * month(datetime(2008,5,23)) //returns 5
4827
- */
4828
4363
  month: {
4829
4364
  _func: args => {
4830
4365
  const date = toNumber(args[0]);
4831
4366
  const jsDate = new Date(date * MS_IN_DAY);
4832
- // javascript months start from 0ß
4833
4367
  return jsDate.getMonth() + 1;
4834
4368
  },
4835
4369
  _signature: [
4836
4370
  { types: [dataTypes.TYPE_NUMBER] },
4837
4371
  ],
4838
4372
  },
4839
-
4840
- /**
4841
- * Compute logical NOT of a `value`. If the parameter is not boolean it will be cast to boolean
4842
- * as per the following rules
4843
- * * null -> false
4844
- * * number -> false if the number is 0, true otherwise
4845
- * * string -> false if the string is empty, true otherwise. String "false" resolves to true
4846
- * * array -> true
4847
- * * object -> true
4848
- * Note that it is also possible to use the logical and operator: `A && B`
4849
- * @param {any} value - any data type
4850
- * @returns {boolean} The logical NOT applied to the input parameter
4851
- * @example
4852
- * not(length('bar') > 0) // returns false
4853
- * @example
4854
- * not(false()) // returns true
4855
- * @example
4856
- * not('abcd') // returns false
4857
- * @example
4858
- * not('') // returns true
4859
- * @function
4860
- * @category openFormula
4861
- */
4862
4373
  not: {
4863
4374
  _func: resolveArgs => !valueOf(resolveArgs[0]),
4864
4375
  _signature: [{ types: [dataTypes.TYPE_ANY] }],
4865
4376
  },
4866
-
4867
- /**
4868
- * returns the time since epoch with days as exponent and time of day as fraction
4869
- * @return {number} representation of current time as a number
4870
- * @function now
4871
- * @category openFormula
4872
- */
4873
4377
  now: {
4874
4378
  _func: () => Date.now() / MS_IN_DAY,
4875
4379
  _signature: [],
4876
4380
  },
4877
-
4878
- /**
4879
- * Return constant null value.
4880
- * Note that expressions may also use the JSON literal null: `` `null` ``
4881
- * @returns {boolean} True
4882
- * @function
4883
- * @category JSONFormula
4884
- */
4885
4381
  null: {
4886
4382
  _func: () => null,
4887
4383
  _signature: [],
4888
4384
  },
4889
-
4890
- /**
4891
- * Returns the logical OR result of two parameters.
4892
- * If the parameters are not boolean they will be cast to boolean as per the following rules
4893
- * * null -> false
4894
- * * number -> false if the number is 0, true otherwise
4895
- * * string -> false if the string is empty, true otherwise. String "false" resolves to true
4896
- * * array -> true
4897
- * * object -> true
4898
- * @param {any} first logical expression
4899
- * @param {...any} [operand] any number of additional expressions
4900
- * @returns {boolean} The logical result of applying OR to all parameters
4901
- * @example
4902
- * or((x / 2) == y, (y * 2) == x)
4903
- * // true
4904
- * @function
4905
- * @category openFormula
4906
- */
4907
4385
  or: {
4908
4386
  _func: resolvedArgs => {
4909
4387
  let result = !!valueOf(resolvedArgs[0]);
@@ -4914,17 +4392,6 @@ function openFormulaFunctions(valueOf, toString, toNumber, debug = []) {
4914
4392
  },
4915
4393
  _signature: [{ types: [dataTypes.TYPE_ANY], variadic: true }],
4916
4394
  },
4917
-
4918
- /**
4919
- * Computes `a` raised to a power `x`. (a<sup>x</sup>)
4920
- * @param {number} a The base number. It can be any real number.
4921
- * @param {number} x The exponent to which the base number is raised.
4922
- * @return {number}
4923
- * @function power
4924
- * @category openFormula
4925
- * @example
4926
- * power(10, 2) //returns 100 (10 raised to power 2)
4927
- */
4928
4395
  power: {
4929
4396
  _func: args => {
4930
4397
  const base = toNumber(args[0]);
@@ -4936,21 +4403,6 @@ function openFormulaFunctions(valueOf, toString, toNumber, debug = []) {
4936
4403
  { types: [dataTypes.TYPE_NUMBER] },
4937
4404
  ],
4938
4405
  },
4939
-
4940
- /**
4941
- * Return the input string with the first letter of each word converted to an
4942
- * uppercase letter and the rest of the letters in the word converted to lowercase.
4943
- * @param {string} text the text to partially capitalize.
4944
- * @returns {string}
4945
- * @function proper
4946
- * @category openFormula
4947
- * @example
4948
- * proper('this is a TITLE') //returns 'This Is A Title'
4949
- * @example
4950
- * proper('2-way street') //returns '2-Way Street'
4951
- * @example
4952
- * proper('76BudGet') //returns '76Budget'
4953
- */
4954
4406
  proper: {
4955
4407
  _func: args => {
4956
4408
  const text = toString(args[0]);
@@ -4963,24 +4415,6 @@ function openFormulaFunctions(valueOf, toString, toNumber, debug = []) {
4963
4415
  { types: [dataTypes.TYPE_STRING] },
4964
4416
  ],
4965
4417
  },
4966
-
4967
- /**
4968
- * Returns text where an old text is substituted at a given start position and
4969
- * length, with a new text.
4970
- * @param {string} text original text
4971
- * @param {number} start index in the original text from where to begin the replacement.
4972
- * @param {number} length number of characters to be replaced
4973
- * @param {string} replacement string to replace at the start index
4974
- * @returns {string}
4975
- * @function replace
4976
- * @category openFormula
4977
- * @example
4978
- * replace('abcdefghijk', 6, 5, '*') //returns abcde*k
4979
- * @example
4980
- * replace('2009',3,2,'10') //returns 2010
4981
- * @example
4982
- * replace('123456',1,3,'@') //returns @456
4983
- */
4984
4418
  replace: {
4985
4419
  _func: args => {
4986
4420
  const oldText = toString(args[0]);
@@ -4990,7 +4424,6 @@ function openFormulaFunctions(valueOf, toString, toNumber, debug = []) {
4990
4424
  if (startNum < 0) {
4991
4425
  return null;
4992
4426
  }
4993
-
4994
4427
  const lhs = oldText.substr(0, startNum);
4995
4428
  const rhs = oldText.substr(startNum + numChars);
4996
4429
  return lhs + newText + rhs;
@@ -5002,17 +4435,6 @@ function openFormulaFunctions(valueOf, toString, toNumber, debug = []) {
5002
4435
  { types: [dataTypes.TYPE_STRING] },
5003
4436
  ],
5004
4437
  },
5005
-
5006
- /**
5007
- * Return text repeated Count times.
5008
- * @param {string} text text to repeat
5009
- * @param {number} count number of times to repeat the text
5010
- * @returns {string}
5011
- * @function rept
5012
- * @category openFormula
5013
- * @example
5014
- * rept('x', 5) //returns 'xxxxx'
5015
- */
5016
4438
  rept: {
5017
4439
  _func: args => {
5018
4440
  const text = toString(args[0]);
@@ -5027,23 +4449,6 @@ function openFormulaFunctions(valueOf, toString, toNumber, debug = []) {
5027
4449
  { types: [dataTypes.TYPE_NUMBER] },
5028
4450
  ],
5029
4451
  },
5030
-
5031
- /**
5032
- * Return a selected number of text characters from the right of a `subject` or
5033
- * in case of array selected number of elements from the end of `subject` array
5034
- * Returns null if the number of elements is less than 0
5035
- * @param {string|array} subject The text/array containing the characters/elements to extract.
5036
- * @param {number} [elements] number of elements to pick. Defaults to 1
5037
- * @return {string|array}
5038
- * @function right
5039
- * @category openFormula
5040
- * @example
5041
- * right('Sale Price', 4) //returns 'rice'
5042
- * @example
5043
- * left('Sweden') // returns 'n'
5044
- * @example
5045
- * left([4, 5, 6], 2) // returns [5, 6]
5046
- */
5047
4452
  right: {
5048
4453
  _func: args => {
5049
4454
  const numEntries = args.length > 1 ? toNumber(args[1]) : 1;
@@ -5061,29 +4466,6 @@ function openFormulaFunctions(valueOf, toString, toNumber, debug = []) {
5061
4466
  { types: [dataTypes.TYPE_NUMBER], optional: true },
5062
4467
  ],
5063
4468
  },
5064
-
5065
- /**
5066
- * Round a number to a specified `precision`.
5067
- * ### Remarks
5068
- * * If `precision` is greater than zero, round to the specified number of decimal places.
5069
- * * If `precision` is 0, round to the nearest integer.
5070
- * * If `precision` is less than 0, round to the left of the decimal point.
5071
- * @param {number} num number to round off
5072
- * @param {number} precision number is rounded to the specified precision.
5073
- * @returns {number}
5074
- * @function round
5075
- * @category openFormula
5076
- * @example
5077
- * round(2.15, 1) //returns 2.2
5078
- * @example
5079
- * round(626.3,-3) //returns 1000 (Rounds 626.3 to the nearest multiple of 1000)
5080
- * @example
5081
- * round(626.3, 0) //returns 626
5082
- * @example
5083
- * round(1.98,-1) //returns 0 (Rounds 1.98 to the nearest multiple of 10)
5084
- * @example
5085
- * round(-50.55,-2) // -100 (round -50.55 to the nearest multiple of 100)
5086
- */
5087
4469
  round: {
5088
4470
  _func: args => {
5089
4471
  const number = toNumber(args[0]);
@@ -5095,38 +4477,15 @@ function openFormulaFunctions(valueOf, toString, toNumber, debug = []) {
5095
4477
  { types: [dataTypes.TYPE_NUMBER] },
5096
4478
  ],
5097
4479
  },
5098
-
5099
- /**
5100
- * Perform a wildcard search. The search is case-sensitive and supports two forms of wildcards:
5101
- * "*" finds a a sequence of characters and "?" finds a single character.
5102
- * To use "*" or "?" as text values, precede them with a tilde ("~") character.
5103
- * Note that the wildcard search is not greedy.
5104
- * e.g. search('a*b', 'abb') will return [0, 'ab'] Not [0, 'abb']
5105
- * @param {string} findText the search string -- which may include wild cards.
5106
- * @param {string} withinText The string to search.
5107
- * @param {integer} startPos The zero-based position of withinText to start searching.
5108
- * Defaults to zero.
5109
- * @returns {array} returns an array with two values:
5110
- * The start position of the found text and the text string that was found.
5111
- * If a match was not found, an empty array is returned.
5112
- * @function search
5113
- * @category openFormula
5114
- * @example
5115
- * search('a?c', 'acabc') //returns [2, 'abc']
5116
- */
5117
4480
  search: {
5118
4481
  _func: args => {
5119
4482
  const findText = toString(args[0]);
5120
4483
  const withinText = toString(args[1]);
5121
4484
  const startPos = toNumber(args[2]);
5122
4485
  if (findText === null || withinText === null || withinText.length === 0) return [];
5123
- // escape all characters that would otherwise create a regular expression
5124
4486
  const reString = findText.replace(/([[.\\^$()+{])/g, '\\$1')
5125
- // add the single character wildcard
5126
4487
  .replace(/~?\?/g, match => match === '~?' ? '\\?' : '.')
5127
- // add the multi-character wildcard
5128
4488
  .replace(/~?\*/g, match => match === '~*' ? '\\*' : '.*?')
5129
- // get rid of the escape characters
5130
4489
  .replace(/~~/g, '~');
5131
4490
  const re = new RegExp(reString);
5132
4491
  const result = withinText.substring(startPos).match(re);
@@ -5138,28 +4497,13 @@ function openFormulaFunctions(valueOf, toString, toNumber, debug = []) {
5138
4497
  { types: [dataTypes.TYPE_STRING] },
5139
4498
  { types: [dataTypes.TYPE_NUMBER], optional: true },
5140
4499
  ],
5141
-
5142
4500
  },
5143
- /**
5144
- * Extract the second (0 through 59) from a time/datetime representation
5145
- * @param {number} The datetime/time for which the second is to be returned.
5146
- * Dates should be specified using the [datetime]{@link datetime} or [time]{@link time} function
5147
- * @return {number}
5148
- * @function second
5149
- * @category openFormula
5150
- * @example
5151
- * second(datetime(2008,5,23,12, 10, 53)) //returns 53
5152
- * second(time(12, 10, 53)) //returns 53
5153
- */
5154
4501
  second: {
5155
4502
  _func: args => {
5156
4503
  const time = toNumber(args[0]) % 1;
5157
4504
  if (time < 0) {
5158
4505
  return null;
5159
4506
  }
5160
-
5161
- // Normally we'd round to 15 digits, but since we're also multiplying by 86400,
5162
- // a reasonable precision is around 10 digits.
5163
4507
  const seconds = round(time * 86400, 10);
5164
4508
  return Math.floor(seconds % 60);
5165
4509
  },
@@ -5167,19 +4511,6 @@ function openFormulaFunctions(valueOf, toString, toNumber, debug = []) {
5167
4511
  { types: [dataTypes.TYPE_NUMBER] },
5168
4512
  ],
5169
4513
  },
5170
-
5171
- /**
5172
- * split a string into an array, given a separator
5173
- * @param {string} string string to split
5174
- * @param {string} separator separator where the split should occur
5175
- * @return {string[]}
5176
- * @function split
5177
- * @category openFormula
5178
- * @example
5179
- * split('abcdef', '') //returns ['a', 'b', 'c', 'd', 'e', 'f']
5180
- * @example
5181
- * split('abcdef', 'e') //returns ['abcd', 'f']
5182
- */
5183
4514
  split: {
5184
4515
  _func: args => {
5185
4516
  const str = toString(args[0]);
@@ -5191,16 +4522,6 @@ function openFormulaFunctions(valueOf, toString, toNumber, debug = []) {
5191
4522
  { types: [dataTypes.TYPE_STRING] },
5192
4523
  ],
5193
4524
  },
5194
-
5195
- /**
5196
- * Return the square root of a number
5197
- * @param {number} num number whose square root has to be calculated
5198
- * @return {number}
5199
- * @function sqrt
5200
- * @category openFormula
5201
- * @example
5202
- * sqrt(4) //returns 2
5203
- */
5204
4525
  sqrt: {
5205
4526
  _func: args => {
5206
4527
  const result = Math.sqrt(toNumber(args[0]));
@@ -5213,20 +4534,6 @@ function openFormulaFunctions(valueOf, toString, toNumber, debug = []) {
5213
4534
  { types: [dataTypes.TYPE_NUMBER] },
5214
4535
  ],
5215
4536
  },
5216
-
5217
- /**
5218
- * Estimates standard deviation based on a sample.
5219
- * `stdev` assumes that its arguments are a sample of the entire population.
5220
- * If your data represents a entire population,
5221
- * then compute the standard deviation using [stdevp]{@link stdevp}.
5222
- * @param {number[]} numbers The array of numbers comprising the population
5223
- * @returns {number}
5224
- * @category openFormula
5225
- * @function stdev
5226
- * @example
5227
- * stdev([1345, 1301, 1368]) //returns 34.044089061098404
5228
- * stdevp([1345, 1301, 1368]) //returns 27.797
5229
- */
5230
4537
  stdev: {
5231
4538
  _func: args => {
5232
4539
  const values = args[0] || [];
@@ -5238,7 +4545,6 @@ function openFormulaFunctions(valueOf, toString, toNumber, debug = []) {
5238
4545
  const sumSquare = coercedValues.reduce((a, b) => a + b * b, 0);
5239
4546
  const result = Math.sqrt((sumSquare - values.length * mean * mean) / (values.length - 1));
5240
4547
  if (Number.isNaN(result)) {
5241
- // this would never happen
5242
4548
  return null;
5243
4549
  }
5244
4550
  return result;
@@ -5247,20 +4553,6 @@ function openFormulaFunctions(valueOf, toString, toNumber, debug = []) {
5247
4553
  { types: [dataTypes.TYPE_ARRAY_NUMBER] },
5248
4554
  ],
5249
4555
  },
5250
-
5251
- /**
5252
- * Calculates standard deviation based on the entire population given as arguments.
5253
- * `stdevp` assumes that its arguments are the entire population.
5254
- * If your data represents a sample of the population,
5255
- * then compute the standard deviation using [stdev]{@link stdev}.
5256
- * @param {number[]} numbers The array of numbers comprising the population
5257
- * @returns {number}
5258
- * @category openFormula
5259
- * @function stdevp
5260
- * @example
5261
- * stdevp([1345, 1301, 1368]) //returns 27.797
5262
- * stdev([1345, 1301, 1368]) //returns 34.044
5263
- */
5264
4556
  stdevp: {
5265
4557
  _func: args => {
5266
4558
  const values = args[0] || [];
@@ -5272,7 +4564,6 @@ function openFormulaFunctions(valueOf, toString, toNumber, debug = []) {
5272
4564
  const meanSumSquare = coercedValues.reduce((a, b) => a + b * b, 0) / values.length;
5273
4565
  const result = Math.sqrt(meanSumSquare - mean * mean);
5274
4566
  if (Number.isNaN(result)) {
5275
- // this would never happen
5276
4567
  return null;
5277
4568
  }
5278
4569
  return result;
@@ -5281,43 +4572,18 @@ function openFormulaFunctions(valueOf, toString, toNumber, debug = []) {
5281
4572
  { types: [dataTypes.TYPE_ARRAY_NUMBER] },
5282
4573
  ],
5283
4574
  },
5284
-
5285
- /**
5286
- * Returns input `text`, with text `old` replaced by text `new` (when searching from the left).
5287
- * If `which` parameter is omitted, every occurrence of `old` is replaced with `new`;
5288
- * If `which` is provided, only that occurrence of `old` is replaced by `new`
5289
- * (starting the count from 1).
5290
- * If there is no match, or if `old` has length 0, `text` is returned unchanged.
5291
- * Note that `old` and `new` may have different lengths. If `which` < 1, return `text` unchanged
5292
- * @param {string} text The text for which to substitute characters.
5293
- * @param {string} old The text to replace.
5294
- * @param {string} new The text to replace `old` with.
5295
- * @param {integer} [which] The one-based occurrence of `old` text to replace with `new` text.
5296
- * @returns {string} replaced string
5297
- * @function
5298
- * @category openFormula
5299
- * @example
5300
- * substitute('Sales Data', 'Sales', 'Cost') //returns 'Cost Data'
5301
- * @example
5302
- * substitute('Quarter 1, 2008', '1', '2', 1) //returns 'Quarter 2, 2008'
5303
- * @example
5304
- * substitute('Quarter 1, 1008', '1', '2', 2) //returns 'Quarter 1, 2008'
5305
- */
5306
4575
  substitute: {
5307
4576
  _func: args => {
5308
4577
  const src = toString(args[0]);
5309
4578
  const old = toString(args[1]);
5310
4579
  const replacement = toString(args[2]);
5311
- // no third parameter? replace all instances
5312
4580
  if (args.length <= 3) return src.replaceAll(old, replacement);
5313
4581
  const whch = toNumber(args[3]);
5314
4582
  if (whch < 1) return src;
5315
- // find the instance to replace
5316
4583
  let pos = -1;
5317
4584
  for (let i = 0; i < whch; i += 1) {
5318
4585
  pos += 1;
5319
4586
  const nextFind = src.slice(pos).indexOf(old);
5320
- // no instance to match 'Which'
5321
4587
  if (nextFind === -1) return src;
5322
4588
  pos += nextFind;
5323
4589
  }
@@ -5330,21 +4596,6 @@ function openFormulaFunctions(valueOf, toString, toNumber, debug = []) {
5330
4596
  { types: [dataTypes.TYPE_NUMBER], optional: true },
5331
4597
  ],
5332
4598
  },
5333
-
5334
- /**
5335
- * Construct and returns time from hours, minutes, and seconds.
5336
- * @param {integer} hours Integer value between 0 and 23 representing the hour of the day.
5337
- * Defaults to 0.
5338
- * @param {integer} minutes Integer value representing the minute segment of a time.
5339
- * The default is 0 minutes past the hour.
5340
- * @param {integer} seconds Integer value representing the second segment of a time.
5341
- * The default is 0 seconds past the minute.
5342
- * @return {number} Returns the fraction of the day consumed by the given time
5343
- * @function time
5344
- * @category openFormula
5345
- * @example
5346
- * time(12, 0, 0) //returns 0.5 (half day)
5347
- */
5348
4599
  time: {
5349
4600
  _func: args => {
5350
4601
  const hours = toNumber(args[0]);
@@ -5362,65 +4613,23 @@ function openFormulaFunctions(valueOf, toString, toNumber, debug = []) {
5362
4613
  { types: [dataTypes.TYPE_NUMBER] },
5363
4614
  ],
5364
4615
  },
5365
-
5366
- /**
5367
- * returns the number of days since epoch
5368
- * @return number
5369
- * @function today
5370
- * @category openFormula
5371
- */
5372
4616
  today: {
5373
4617
  _func: () => Math.floor(Date.now() / MS_IN_DAY),
5374
4618
  _signature: [],
5375
4619
  },
5376
-
5377
- /**
5378
- * Remove leading and trailing spaces, and replace all internal multiple spaces
5379
- * with a single space.
5380
- * @param {string} text string to trim
5381
- * @return {string} removes all leading and trailing space.
5382
- * Any other sequence of 2 or more spaces is replaced with a single space.
5383
- * @function trim
5384
- * @category openFormula
5385
- * @example
5386
- * trim(' ab c ') //returns 'ab c'
5387
- */
5388
4620
  trim: {
5389
4621
  _func: args => {
5390
4622
  const text = toString(args[0]);
5391
- // only removes the space character
5392
- // other whitespace characters like \t \n left intact
5393
4623
  return text.split(' ').filter(x => x).join(' ');
5394
4624
  },
5395
4625
  _signature: [
5396
4626
  { types: [dataTypes.TYPE_STRING] },
5397
4627
  ],
5398
4628
  },
5399
-
5400
- /**
5401
- * Return constant boolean true value.
5402
- * Note that expressions may also use the JSON literal true: `` `true` ``
5403
- * @returns {boolean} True
5404
- * @function
5405
- * @category openFormula
5406
- */
5407
4629
  true: {
5408
4630
  _func: () => true,
5409
4631
  _signature: [],
5410
4632
  },
5411
-
5412
- /**
5413
- * Truncates a number to an integer by removing the fractional part of the number.
5414
- * @param {number} numA number to truncate
5415
- * @param {number} [numB] A number specifying the precision of the truncation. Default is 0
5416
- * @return {number}
5417
- * @function trunc
5418
- * @category openFormula
5419
- * @example
5420
- * trunc(8.9) //returns 8
5421
- * trunc(-8.9) //returns -8
5422
- * trunc(8.912, 2) //returns 8.91
5423
- */
5424
4633
  trunc: {
5425
4634
  _func: args => {
5426
4635
  const number = toNumber(args[0]);
@@ -5433,20 +4642,8 @@ function openFormulaFunctions(valueOf, toString, toNumber, debug = []) {
5433
4642
  { types: [dataTypes.TYPE_NUMBER], optional: true },
5434
4643
  ],
5435
4644
  },
5436
-
5437
- /**
5438
- * takes an array and returns unique elements within it
5439
- * @param {array} input input array
5440
- * @return {array} array with duplicate elements removed
5441
- * @function unique
5442
- * @category JSONFormula
5443
- * @example
5444
- * unique([1, 2, 3, 4, 1, 1, 2]) //returns [1, 2, 3, 4]
5445
- */
5446
4645
  unique: {
5447
4646
  _func: args => {
5448
- // create an array of values for searching. That way if the array elements are
5449
- // represented by objects with a valueOf(), then we'll locate them in the valueArray
5450
4647
  const valueArray = args[0].map(a => valueOf(a));
5451
4648
  return args[0].filter((v, index) => valueArray.indexOf(valueOf(v)) === index);
5452
4649
  },
@@ -5454,18 +4651,6 @@ function openFormulaFunctions(valueOf, toString, toNumber, debug = []) {
5454
4651
  { types: [dataTypes.TYPE_ARRAY] },
5455
4652
  ],
5456
4653
  },
5457
-
5458
- /**
5459
- * Converts all the alphabetic characters in a string to uppercase.
5460
- * If the value is not a string it will be converted into string
5461
- * using the default toString method
5462
- * @param {string} input input string
5463
- * @returns {string} the upper case value of the input string
5464
- * @function upper
5465
- * @category openFormula
5466
- * @example
5467
- * upper('abcd') //returns 'ABCD'
5468
- */
5469
4654
  upper: {
5470
4655
  _func: args => {
5471
4656
  const value = toString(args[0]);
@@ -5475,19 +4660,6 @@ function openFormulaFunctions(valueOf, toString, toNumber, debug = []) {
5475
4660
  { types: [dataTypes.TYPE_STRING] },
5476
4661
  ],
5477
4662
  },
5478
-
5479
- /**
5480
- * Perform an indexed lookup on a map or array
5481
- * @param {map | array} object on which to perform the lookup
5482
- * @param {string | integer} index: a named child for a map or an integer offset for an array
5483
- * @returns {any} the result of the lookup -- or `null` if not found.
5484
- * @function
5485
- * @category JSONFormula
5486
- * @example
5487
- * value({a: 1, b:2, c:3}, a) //returns 1
5488
- * @example
5489
- * value([1, 2, 3, 4], 2) //returns 3
5490
- */
5491
4663
  value: {
5492
4664
  _func: args => {
5493
4665
  const obj = args[0] || {};
@@ -5497,7 +4669,6 @@ function openFormulaFunctions(valueOf, toString, toNumber, debug = []) {
5497
4669
  debug.push(`Failed to find: '${index}'`);
5498
4670
  const available = Object.keys(obj).map(a => `'${a}'`).toString();
5499
4671
  if (available.length) debug.push(`Available fields: ${available}`);
5500
-
5501
4672
  return null;
5502
4673
  }
5503
4674
  return result;
@@ -5507,43 +4678,18 @@ function openFormulaFunctions(valueOf, toString, toNumber, debug = []) {
5507
4678
  { types: [dataTypes.TYPE_STRING, dataTypes.TYPE_NUMBER] },
5508
4679
  ],
5509
4680
  },
5510
-
5511
- /**
5512
- * Extract the day of the week from a date; if text, uses current locale to convert to a date.
5513
- * @param {number} The datetime for which the day of the week is to be returned.
5514
- * Dates should be entered by using the [datetime]{@link datetime} function
5515
- * @param {number} [returnType] A number that determines the
5516
- * numeral representation (a number from 0 to 7) of the
5517
- * day of week. Default is 1. Supports the following values
5518
- * * 1 : Sunday (1), Monday (2), ..., Saturday (7)
5519
- * * 2 : Monday (1), Tuesday (2), ..., Sunday(7)
5520
- * * 3 : Monday (0), Tuesday (2), ...., Sunday(6)
5521
- * @returns {number} day of the week
5522
- * @function weekday
5523
- * @category openFormula
5524
- * @example
5525
- * weekday(datetime(2006,5,21)) // 1
5526
- * @example
5527
- * weekday(datetime(2006,5,21), 2) // 7
5528
- * @example
5529
- * weekday(datetime(2006,5,21), 3) // 6
5530
- */
5531
4681
  weekday: {
5532
4682
  _func: args => {
5533
4683
  const date = toNumber(args[0]);
5534
4684
  const type = args.length > 1 ? toNumber(args[1]) : 1;
5535
4685
  const jsDate = new Date(date * MS_IN_DAY);
5536
4686
  const day = jsDate.getDay();
5537
- // day is in range [0-7) with 0 mapping to sunday
5538
4687
  switch (type) {
5539
4688
  case 1:
5540
- // range = [1, 7], sunday = 1
5541
4689
  return day + 1;
5542
4690
  case 2:
5543
- // range = [1, 7] sunday = 7
5544
4691
  return ((day + 6) % 7) + 1;
5545
4692
  case 3:
5546
- // range = [0, 6] sunday = 6
5547
4693
  return (day + 6) % 7;
5548
4694
  default:
5549
4695
  return null;
@@ -5554,17 +4700,6 @@ function openFormulaFunctions(valueOf, toString, toNumber, debug = []) {
5554
4700
  { types: [dataTypes.TYPE_NUMBER], optional: true },
5555
4701
  ],
5556
4702
  },
5557
-
5558
- /**
5559
- * Returns the year of a date represented by a serial number.
5560
- * @param {number} The date for which the year is to be returned.
5561
- * Dates should be entered by using the [datetime]{@link datetime} function
5562
- * @return {number}
5563
- * @function year
5564
- * @category openFormula
5565
- * @example
5566
- * year(datetime(2008,5,23)) //returns 2008
5567
- */
5568
4703
  year: {
5569
4704
  _func: args => {
5570
4705
  const date = toNumber(args[0]);
@@ -5575,7 +4710,6 @@ function openFormulaFunctions(valueOf, toString, toNumber, debug = []) {
5575
4710
  { types: [dataTypes.TYPE_NUMBER] },
5576
4711
  ],
5577
4712
  },
5578
-
5579
4713
  charCode: {
5580
4714
  _func: args => {
5581
4715
  const code = toNumber(args[0]);
@@ -5588,7 +4722,6 @@ function openFormulaFunctions(valueOf, toString, toNumber, debug = []) {
5588
4722
  { types: [dataTypes.TYPE_NUMBER] },
5589
4723
  ],
5590
4724
  },
5591
-
5592
4725
  codePoint: {
5593
4726
  _func: args => {
5594
4727
  const text = toString(args[0]);
@@ -5601,28 +4734,24 @@ function openFormulaFunctions(valueOf, toString, toNumber, debug = []) {
5601
4734
  { types: [dataTypes.TYPE_STRING] },
5602
4735
  ],
5603
4736
  },
5604
-
5605
4737
  encodeUrlComponent: {
5606
4738
  _func: args => encodeURIComponent(args[0]),
5607
4739
  _signature: [
5608
4740
  { types: [dataTypes.TYPE_STRING] },
5609
4741
  ],
5610
4742
  },
5611
-
5612
4743
  encodeUrl: {
5613
4744
  _func: args => encodeURI(args[0]),
5614
4745
  _signature: [
5615
4746
  { types: [dataTypes.TYPE_STRING] },
5616
4747
  ],
5617
4748
  },
5618
-
5619
4749
  decodeUrlComponent: {
5620
4750
  _func: args => decodeURIComponent(args[0]),
5621
4751
  _signature: [
5622
4752
  { types: [dataTypes.TYPE_STRING] },
5623
4753
  ],
5624
4754
  },
5625
-
5626
4755
  decodeUrl: {
5627
4756
  _func: args => decodeURI(args[0]),
5628
4757
  _signature: [
@@ -5632,27 +4761,6 @@ function openFormulaFunctions(valueOf, toString, toNumber, debug = []) {
5632
4761
  };
5633
4762
  }
5634
4763
 
5635
- /*
5636
- Copyright 2014 James Saryerwinnie
5637
-
5638
- Licensed under the Apache License, Version 2.0 (the "License");
5639
- you may not use this file except in compliance with the License.
5640
- You may obtain a copy of the License at
5641
-
5642
- http://www.apache.org/licenses/LICENSE-2.0
5643
-
5644
- Unless required by applicable law or agreed to in writing, software
5645
- distributed under the License is distributed on an "AS IS" BASIS,
5646
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5647
- See the License for the specific language governing permissions and
5648
- limitations under the License.
5649
-
5650
- NOTICE:
5651
- This file is substantially modified from the original source taken from:
5652
- https://github.com/jmespath/jmespath.js
5653
-
5654
- */
5655
-
5656
4764
  function functions(
5657
4765
  runtime,
5658
4766
  isObject,
@@ -5675,7 +4783,6 @@ function functions(
5675
4783
  TYPE_ARRAY_NUMBER,
5676
4784
  TYPE_ARRAY_STRING,
5677
4785
  } = dataTypes;
5678
-
5679
4786
  function createKeyFunction(exprefNode, allowedTypes) {
5680
4787
  return x => {
5681
4788
  const current = runtime.interpreter.visit(exprefNode, x);
@@ -5687,46 +4794,11 @@ function functions(
5687
4794
  return current;
5688
4795
  };
5689
4796
  }
5690
-
5691
4797
  const functionMap = {
5692
- // name: [function, <signature>]
5693
- // The <signature> can be:
5694
- //
5695
- // {
5696
- // args: [[type1, type2], [type1, type2]],
5697
- // variadic: true|false
5698
- // }
5699
- //
5700
- // Each arg in the arg list is a list of valid types
5701
- // (if the function is overloaded and supports multiple
5702
- // types. If the type is "any" then no type checking
5703
- // occurs on the argument. Variadic is optional
5704
- // and if not provided is assumed to be false.
5705
- /**
5706
- * Returns the absolute value of the provided argument `value`.
5707
- * @param {number} value argument whose absolute value has to be returned
5708
- * @return {number} returns the absolute value of the `value` argument
5709
- * @function abs
5710
- * @example
5711
- * abs(-1) //returns 1
5712
- * @category jmespath
5713
- */
5714
4798
  abs: {
5715
4799
  _func: resolvedArgs => Math.abs(resolvedArgs[0]),
5716
4800
  _signature: [{ types: [TYPE_NUMBER] }],
5717
4801
  },
5718
- /**
5719
- * Returns the average of the elements in the provided array.
5720
- * An empty array will produce a return value of `null`.
5721
- * @param {number[]} elements array of elements whose average has to be computed
5722
- * @return {number} average value
5723
- * @function avg
5724
- * @example
5725
- * avg([]) //returns null
5726
- * @example
5727
- * avg([1, 2, 3]) //returns 2
5728
- * @category jmespath
5729
- */
5730
4802
  avg: {
5731
4803
  _func: resolvedArgs => {
5732
4804
  let sum = 0;
@@ -5738,59 +4810,15 @@ function functions(
5738
4810
  },
5739
4811
  _signature: [{ types: [TYPE_ARRAY_NUMBER] }],
5740
4812
  },
5741
-
5742
- /**
5743
- * Returns the next highest integer value of the argument `num` by rounding up if necessary.
5744
- * @param {number} num number whose next highest integer value has to be computed
5745
- * @return {number}
5746
- * @function ceil
5747
- * @example
5748
- * ceil(10) //returns 10
5749
- * @example
5750
- * ceil(10.4) //return 11
5751
- * @category jmespath
5752
- */
5753
4813
  ceil: {
5754
4814
  _func: resolvedArgs => Math.ceil(resolvedArgs[0]),
5755
4815
  _signature: [{ types: [TYPE_NUMBER] }],
5756
4816
  },
5757
- /**
5758
- * Returns true if the given `subject` contains the provided `search` string.
5759
- * If `subject` is an array, this function returns true if one of the elements
5760
- * in the array is equal to the provided `search` value. If the provided `subject`
5761
- * is a string, this function returns true if the string contains the provided
5762
- * `search` argument.
5763
- * @param {array|string} subject the subject in which the element has to be searched
5764
- * @param {string|boolean|number|date} search element to search
5765
- * @return {boolean}
5766
- * @function contains
5767
- * @example
5768
- * contains([1, 2, 3, 4], 2) //returns true
5769
- * @example
5770
- * contains([1, 2, 3, 4], -1) //returns false
5771
- * @example
5772
- * contains('Abcd', 'd') //returns true
5773
- * @example
5774
- * contains('Abcd', 'x') //returns false
5775
- * @category jmespath
5776
- */
5777
4817
  contains: {
5778
4818
  _func: resolvedArgs => valueOf(resolvedArgs[0]).indexOf(valueOf(resolvedArgs[1])) >= 0,
5779
4819
  _signature: [{ types: [TYPE_STRING, TYPE_ARRAY] },
5780
4820
  { types: [TYPE_ANY] }],
5781
4821
  },
5782
- /**
5783
- * Returns true if the `subject` ends with the `suffix`, otherwise this function returns false.
5784
- * @param {string} subject subject in which the `suffix` is being searched for
5785
- * @param {string} suffix suffix to search in the subject
5786
- * @return {boolean}
5787
- * @function endsWith
5788
- * @example
5789
- * endsWith('Abcd', 'd') //returns true
5790
- * @example
5791
- * endsWith('Abcd', 'A') //returns false
5792
- * @category jmespath
5793
- */
5794
4822
  endsWith: {
5795
4823
  _func: resolvedArgs => {
5796
4824
  const searchStr = valueOf(resolvedArgs[0]);
@@ -5799,34 +4827,10 @@ function functions(
5799
4827
  },
5800
4828
  _signature: [{ types: [TYPE_STRING] }, { types: [TYPE_STRING] }],
5801
4829
  },
5802
-
5803
- /**
5804
- * Returns the next lowest integer value of the argument `num` by rounding down if necessary.
5805
- * @param {number} num number whose next lowest integer value has to be returned
5806
- * @return {number}
5807
- * @function floor
5808
- * @example
5809
- * floor(10.4) //returns 10
5810
- * @example
5811
- * floor(10) //returns 10
5812
- * @category jmespath
5813
- */
5814
4830
  floor: {
5815
4831
  _func: resolvedArgs => Math.floor(resolvedArgs[0]),
5816
4832
  _signature: [{ types: [TYPE_NUMBER] }],
5817
4833
  },
5818
-
5819
- /**
5820
- * Returns all the elements from the provided `stringsarray`
5821
- * array joined together using the `glue` argument as a separator between each.
5822
- * @param {string} glue
5823
- * @param {string[]} stringsarray
5824
- * @return {string}
5825
- * @function join
5826
- * @example
5827
- * join(',', ['a', 'b', 'c']) //returns 'a,b,c'
5828
- * @category jmespath
5829
- */
5830
4834
  join: {
5831
4835
  _func: resolvedArgs => {
5832
4836
  const joinChar = resolvedArgs[0];
@@ -5838,17 +4842,6 @@ function functions(
5838
4842
  { types: [TYPE_ARRAY_STRING] },
5839
4843
  ],
5840
4844
  },
5841
-
5842
- /**
5843
- * Returns an array containing the keys of the provided object `obj`. If the passed
5844
- * object is null, the value returned is an empty array
5845
- * @param {object} obj the object whose keys need to be extracted
5846
- * @return {array}
5847
- * @function keys
5848
- * @example
5849
- * keys({a : 3, b : 4}) //returns ['a', 'b']
5850
- * @category jmespath
5851
- */
5852
4845
  keys: {
5853
4846
  _func: resolvedArgs => {
5854
4847
  if (resolvedArgs[0] === null) return [];
@@ -5856,54 +4849,14 @@ function functions(
5856
4849
  },
5857
4850
  _signature: [{ types: [TYPE_ANY] }],
5858
4851
  },
5859
-
5860
- /**
5861
- * Returns the length of the given argument `subject` using the following types rules:
5862
- * * string: returns the number of code points in the string
5863
- * * array: returns the number of elements in the array
5864
- * * object: returns the number of key-value pairs in the object
5865
- * @param {string | array | object} subject subject whose length has to be calculated
5866
- * @return {number}
5867
- * @function length
5868
- * @example
5869
- * length([]) //returns 0
5870
- * @example
5871
- * length('') //returns 0
5872
- * @example
5873
- * length('abcd') //returns 4
5874
- * @example
5875
- * length([1, 2, 3, 4]) //returns 4
5876
- * @example
5877
- * length({}) // returns 0
5878
- * @example
5879
- * length({a : 3, b : 4}) //returns 2
5880
- * @category jmespath
5881
- */
5882
4852
  length: {
5883
4853
  _func: resolvedArgs => {
5884
4854
  const arg = valueOf(resolvedArgs[0]);
5885
4855
  if (isObject(arg)) return Object.keys(arg).length;
5886
-
5887
4856
  return isArray(arg) ? arg.length : toString(arg).length;
5888
4857
  },
5889
4858
  _signature: [{ types: [TYPE_STRING, TYPE_ARRAY, TYPE_OBJECT] }],
5890
4859
  },
5891
-
5892
- /**
5893
- * Apply the `expr` to every element in the `elements` array and return the array of results.
5894
- * An elements of length N will produce a return array of length N. Unlike a projection,
5895
- * `[*].bar`, `map()` will include the result of applying the `expr` for every element
5896
- * in the elements array, even if the result is `null`.
5897
- * @param {expression} expr expression to evaluate on each element
5898
- * @param {array} elements array of elements on which the expression will be evaluated
5899
- * @return {array}
5900
- * @function map
5901
- * @example
5902
- * map(&(@ + 1), [1, 2, 3, 4]) // returns [2, 3, 4, 5]
5903
- * @example
5904
- * map(&length(@), ['doe', 'nick', 'chris']) // returns [3,4, 5]
5905
- * @category jmespath
5906
- */
5907
4860
  map: {
5908
4861
  _func: resolvedArgs => {
5909
4862
  const exprefNode = resolvedArgs[0];
@@ -5911,35 +4864,15 @@ function functions(
5911
4864
  },
5912
4865
  _signature: [{ types: [TYPE_EXPREF] }, { types: [TYPE_ARRAY] }],
5913
4866
  },
5914
-
5915
- /**
5916
- * Returns the highest value in the provided `collection` arguments.
5917
- * If all collections are empty `null` is returned.
5918
- * max() can work on numbers or strings.
5919
- * If a mix of numbers and strings are provided, the type of the first value will be used.
5920
- * @param {number[]|string[]} collection array in which the maximum element is to be calculated
5921
- * @return {number}
5922
- * @function max
5923
- * @example
5924
- * max([1, 2, 3], [4, 5, 6], 7) //returns 7
5925
- * @example
5926
- * max([]) // returns null
5927
- * @example
5928
- * max(['a', 'a1', 'b']) // returns 'b'
5929
- * @category jmespath
5930
- */
5931
4867
  max: {
5932
4868
  _func: args => {
5933
- // flatten the args into a single array
5934
4869
  const array = args.reduce((prev, cur) => {
5935
4870
  if (Array.isArray(cur)) prev.push(...cur);
5936
4871
  else prev.push(cur);
5937
4872
  return prev;
5938
4873
  }, []);
5939
-
5940
4874
  const first = array.find(r => r !== null);
5941
4875
  if (array.length === 0 || first === undefined) return null;
5942
- // use the first value to determine the comparison type
5943
4876
  const isNumber = getTypeName(first, true) === TYPE_NUMBER;
5944
4877
  const compare = isNumber
5945
4878
  ? (prev, cur) => {
@@ -5950,25 +4883,10 @@ function functions(
5950
4883
  const current = toString(cur);
5951
4884
  return prev.localeCompare(current) === 1 ? prev : current;
5952
4885
  };
5953
-
5954
4886
  return array.reduce(compare, isNumber ? toNumber(first) : toString(first));
5955
4887
  },
5956
4888
  _signature: [{ types: [TYPE_ARRAY, TYPE_ARRAY_NUMBER, TYPE_ARRAY_STRING], variadic: true }],
5957
4889
  },
5958
-
5959
- /**
5960
- * Returns the maximum element in an array using the expression `expr` as the comparison key.
5961
- * The entire element is returned.
5962
- * @param {array} elements the array in which the maximum element is to be found
5963
- * @param {expression} expr the expr to use as the `comparison` key
5964
- * @return {any}
5965
- * @function maxBy
5966
- * @example
5967
- * maxBy(['abcd', 'e', 'def'], &length(@)) //returns 'abcd'
5968
- * @example
5969
- * maxBy([{year: 2010}, {year: 2020}, {year: 1910}], &year) //returns {year: 2020}
5970
- * @category jmespath
5971
- */
5972
4890
  maxBy: {
5973
4891
  _func: resolvedArgs => {
5974
4892
  const exprefNode = resolvedArgs[1];
@@ -5988,22 +4906,6 @@ function functions(
5988
4906
  },
5989
4907
  _signature: [{ types: [TYPE_ARRAY] }, { types: [TYPE_EXPREF] }],
5990
4908
  },
5991
-
5992
- /**
5993
- * Accepts 0 or more objects as arguments, and returns a single object with
5994
- * subsequent objects merged. Each subsequent object’s key/value pairs are
5995
- * added to the preceding object. This function is used to combine multiple
5996
- * objects into one. You can think of this as the first object being the base object,
5997
- * and each subsequent argument being overrides that are applied to the base object.
5998
- * @param {...object} args
5999
- * @return {object}
6000
- * @function merge
6001
- * @example
6002
- * merge({a: 1, b: 2}, {c : 3, d: 4}) // returns {a :1, b: 2, c: 3, d: 4}
6003
- * @example
6004
- * merge({a: 1, b: 2}, {a : 3, d: 4}) // returns {a :3, b: 2, d: 4}
6005
- * @category jmespath
6006
- */
6007
4909
  merge: {
6008
4910
  _func: resolvedArgs => {
6009
4911
  const merged = {};
@@ -6016,35 +4918,15 @@ function functions(
6016
4918
  },
6017
4919
  _signature: [{ types: [TYPE_OBJECT], variadic: true }],
6018
4920
  },
6019
-
6020
- /**
6021
- * Returns the lowest value in the provided `collection` arguments.
6022
- * If all collections are empty `null` is returned.
6023
- * min() can work on numbers or strings.
6024
- * If a mix of numbers and strings are provided, the type of the first value will be used.
6025
- * @param {number[]|string[]} collection array in which the minimum element is to be calculated
6026
- * @return {number}
6027
- * @function min
6028
- * @example
6029
- * min([1, 2, 3], [4, 5, 6], 7) //returns 1
6030
- * @example
6031
- * min([]) // returns null
6032
- * @example
6033
- * min(['a', 'a1', 'b']) // returns 'a'
6034
- * @category jmespath
6035
- */
6036
4921
  min: {
6037
4922
  _func: args => {
6038
- // flatten the args into a single array
6039
4923
  const array = args.reduce((prev, cur) => {
6040
4924
  if (Array.isArray(cur)) prev.push(...cur);
6041
4925
  else prev.push(cur);
6042
4926
  return prev;
6043
4927
  }, []);
6044
-
6045
4928
  const first = array.find(r => r !== null);
6046
4929
  if (array.length === 0 || first === undefined) return null;
6047
- // use the first value to determine the comparison type
6048
4930
  const isNumber = getTypeName(first, true) === TYPE_NUMBER;
6049
4931
  const compare = isNumber
6050
4932
  ? (prev, cur) => {
@@ -6055,25 +4937,10 @@ function functions(
6055
4937
  const current = toString(cur);
6056
4938
  return prev.localeCompare(current) === 1 ? current : prev;
6057
4939
  };
6058
-
6059
4940
  return array.reduce(compare, isNumber ? toNumber(first) : toString(first));
6060
4941
  },
6061
4942
  _signature: [{ types: [TYPE_ARRAY, TYPE_ARRAY_NUMBER, TYPE_ARRAY_STRING], variadic: true }],
6062
4943
  },
6063
-
6064
- /**
6065
- * Returns the minimum element in `elements` array using the expression `expr`
6066
- * as the comparison key.
6067
- * @param {array} elements
6068
- * @param {expression} expr expression that returns either a string or a number
6069
- * @return {any}
6070
- * @function minBy
6071
- * @example
6072
- * minBy(['abcd', 'e', 'def'], &length(@)) //returns 'e'
6073
- * @example
6074
- * minBy([{year: 2010}, {year: 2020}, {year: 1910}], &year) //returns {year: 1910}
6075
- * @category jmespath
6076
- */
6077
4944
  minBy: {
6078
4945
  _func: resolvedArgs => {
6079
4946
  const exprefNode = resolvedArgs[1];
@@ -6093,48 +4960,10 @@ function functions(
6093
4960
  },
6094
4961
  _signature: [{ types: [TYPE_ARRAY] }, { types: [TYPE_EXPREF] }],
6095
4962
  },
6096
-
6097
- /**
6098
- * Returns the first argument that does not resolve to `null`.
6099
- * This function accepts one or more arguments, and will evaluate
6100
- * them in order until a non null argument is encounted. If all
6101
- * arguments values resolve to null, then a value of null is returned.
6102
- * @param {...any} argument
6103
- * @return {any}
6104
- * @function notNull
6105
- * @example
6106
- * notNull(1, 2, 3, 4, `null`) //returns 1
6107
- * @example
6108
- * notNull(`null`, 2, 3, 4, `null`) //returns 2
6109
- * @category jmespath
6110
- */
6111
4963
  notNull: {
6112
4964
  _func: resolvedArgs => resolvedArgs.find(arg => getTypeName(arg) !== TYPE_NULL) || null,
6113
4965
  _signature: [{ types: [TYPE_ANY], variadic: true }],
6114
4966
  },
6115
-
6116
- /**
6117
- * executes a user-supplied reducer expression `expr` on each element of the
6118
- * array, in order, passing in the return value from the calculation on the preceding element.
6119
- * The final result of running the reducer across all elements of the `elements` array is a
6120
- * single value.
6121
- * The expression can access the following properties
6122
- * * accumulated: accumulated value based on the previous calculations. Initial value is `null`
6123
- * * current: current element to process
6124
- * * index: index of the `current` element in the array
6125
- * * array: original array
6126
- * @param {expression} expr reducer expr to be executed on each element
6127
- * @param {array} elements array of elements on which the expression will be evaluated
6128
- * @return {any}
6129
- * @function reduce
6130
- * @example
6131
- * reduce(&(accumulated + current), [1, 2, 3]) //returns 6
6132
- * @example
6133
- * reduce(&(accumulated - current), [3, 3, 3]) //returns -9
6134
- * @example
6135
- * reduce(&if(accumulated == `null`, current, accumulated * current), [3, 3, 3]) //returns 27
6136
- * @category jmespath
6137
- */
6138
4967
  reduce: {
6139
4968
  _func: resolvedArgs => {
6140
4969
  const exprefNode = resolvedArgs[0];
@@ -6151,23 +4980,10 @@ function functions(
6151
4980
  { types: [TYPE_ANY], optional: true },
6152
4981
  ],
6153
4982
  },
6154
-
6155
- /**
6156
- * Register a function to allow code re-use. The registered function may take one parameter.
6157
- * If more parameters are needed, combine them in an array or map.
6158
- * @param {string} functionName Name of the function to register
6159
- * @param {expression} expr Expression to execute with this function call
6160
- * @return {{}} returns an empty object
6161
- * @function register
6162
- * @example
6163
- * register('product', &@[0] * @[1]) // can now call: product([2,21]) => returns 42
6164
- * @category jmespath
6165
- */
6166
4983
  register: {
6167
4984
  _func: resolvedArgs => {
6168
4985
  const functionName = resolvedArgs[0];
6169
4986
  const exprefNode = resolvedArgs[1];
6170
-
6171
4987
  if (functionMap[functionName]) {
6172
4988
  debug.push(`Cannot re-register '${functionName}'`);
6173
4989
  return {};
@@ -6183,15 +4999,6 @@ function functions(
6183
4999
  { types: [TYPE_EXPREF] },
6184
5000
  ],
6185
5001
  },
6186
- /**
6187
- * Reverses the order of the `argument`.
6188
- * @param {string|array} argument
6189
- * @return {array}
6190
- * @function reverse
6191
- * @example
6192
- * reverse(['a', 'b', 'c']) //returns ['c', 'b', 'a']
6193
- * @category jmespath
6194
- */
6195
5002
  reverse: {
6196
5003
  _func: resolvedArgs => {
6197
5004
  const originalStr = valueOf(resolvedArgs[0]);
@@ -6209,18 +5016,6 @@ function functions(
6209
5016
  },
6210
5017
  _signature: [{ types: [TYPE_STRING, TYPE_ARRAY] }],
6211
5018
  },
6212
-
6213
- /**
6214
- * This function accepts an array `list` argument and returns the sorted elements of
6215
- * the `list` as an array. The array must be a list of strings or numbers.
6216
- * Sorting strings is based on code points. Locale is not taken into account.
6217
- * @param {number[]|string[]} list
6218
- * @return {number[]|string[]}
6219
- * @function sort
6220
- * @example
6221
- * sort([1, 2, 4, 3, 1]) // returns [1, 1, 2, 3, 4]
6222
- * @category jmespath
6223
- */
6224
5019
  sort: {
6225
5020
  _func: resolvedArgs => {
6226
5021
  const sortedArray = resolvedArgs[0].slice(0);
@@ -6238,24 +5033,6 @@ function functions(
6238
5033
  },
6239
5034
  _signature: [{ types: [TYPE_ARRAY, TYPE_ARRAY_STRING, TYPE_ARRAY_NUMBER] }],
6240
5035
  },
6241
-
6242
- /**
6243
- * Sort an array using an expression `expr` as the sort key. For each element
6244
- * in the array of elements, the `expr` expression is applied and the resulting
6245
- * value is used as the key used when sorting the elements. If the result of
6246
- * evaluating the `expr` against the current array element results in type
6247
- * other than a number or a string, a type error will occur.
6248
- * @param {array} elements
6249
- * @param {expression} expr
6250
- * @return {array}
6251
- * @function sortBy
6252
- * @example
6253
- * sortBy(['abcd', 'e', 'def'], &length(@)) //returns ['e', 'def', 'abcd']
6254
- * @example
6255
- * // returns [{year: 1910}, {year: 2010}, {year: 2020}]
6256
- * sortBy([{year: 2010}, {year: 2020}, {year: 1910}], &year)
6257
- * @category jmespath
6258
- */
6259
5036
  sortBy: {
6260
5037
  _func: resolvedArgs => {
6261
5038
  const sortedArray = resolvedArgs[0].slice(0);
@@ -6269,13 +5046,6 @@ function functions(
6269
5046
  if ([TYPE_NUMBER, TYPE_STRING].indexOf(requiredType) < 0) {
6270
5047
  throw new Error('TypeError');
6271
5048
  }
6272
- // In order to get a stable sort out of an unstable
6273
- // sort algorithm, we decorate/sort/undecorate (DSU)
6274
- // by creating a new list of [index, element] pairs.
6275
- // In the cmp function, if the evaluated elements are
6276
- // equal, then the index will be used as the tiebreaker.
6277
- // After the decorated list has been sorted, it will be
6278
- // undecorated to extract the original elements.
6279
5049
  const decorated = [];
6280
5050
  for (let i = 0; i < sortedArray.length; i += 1) {
6281
5051
  decorated.push([i, sortedArray[i]]);
@@ -6300,12 +5070,8 @@ function functions(
6300
5070
  if (exprA < exprB) {
6301
5071
  return -1;
6302
5072
  }
6303
- // If they're equal compare the items by their
6304
- // order to maintain relative order of equal keys
6305
- // (i.e. to get a stable sort).
6306
5073
  return a[0] - b[0];
6307
5074
  });
6308
- // Undecorate: extract out the original list elements.
6309
5075
  for (let j = 0; j < decorated.length; j += 1) {
6310
5076
  [, sortedArray[j]] = decorated[j];
6311
5077
  }
@@ -6313,32 +5079,10 @@ function functions(
6313
5079
  },
6314
5080
  _signature: [{ types: [TYPE_ARRAY] }, { types: [TYPE_EXPREF] }],
6315
5081
  },
6316
-
6317
- /**
6318
- * Returns true if the `subject` starts with the `prefix`, otherwise returns false.
6319
- * @param {string} subject subject in which the `prefix` is being searched for
6320
- * @param {string} prefix prefix to search in the subject
6321
- * @return {boolean}
6322
- * @function startsWith
6323
- * @example
6324
- * startsWith('jack is at home', 'jack') // returns true
6325
- * @category jmespath
6326
- */
6327
5082
  startsWith: {
6328
5083
  _func: resolvedArgs => valueOf(resolvedArgs[0]).startsWith(valueOf(resolvedArgs[1])),
6329
5084
  _signature: [{ types: [TYPE_STRING] }, { types: [TYPE_STRING] }],
6330
5085
  },
6331
-
6332
- /**
6333
- * Returns the sum of the provided `collection` array argument.
6334
- * An empty array will produce a return value of 0.
6335
- * @param {number[]} collection array whose element's sum has to be computed
6336
- * @return {number}
6337
- * @function sum
6338
- * @example
6339
- * sum([1, 2, 3]) //returns 6
6340
- * @category jmespath
6341
- */
6342
5086
  sum: {
6343
5087
  _func: resolvedArgs => {
6344
5088
  let sum = 0;
@@ -6349,20 +5093,6 @@ function functions(
6349
5093
  },
6350
5094
  _signature: [{ types: [TYPE_ARRAY_NUMBER] }],
6351
5095
  },
6352
-
6353
- /**
6354
- * converts the passed `arg` to an array. The conversion happens as per the following rules
6355
- * * array - Returns the passed in value.
6356
- * * number/string/object/boolean - Returns a one element array containing the argument.
6357
- * @param {any} arg
6358
- * @return {array}
6359
- * @function toArray
6360
- * @example
6361
- * toArray(1) // returns [1]
6362
- * @example
6363
- * toArray(null()) // returns [`null`]
6364
- * @category jmespath
6365
- */
6366
5096
  toArray: {
6367
5097
  _func: resolvedArgs => {
6368
5098
  if (getTypeName(resolvedArgs[0]) === TYPE_ARRAY) {
@@ -6370,31 +5100,8 @@ function functions(
6370
5100
  }
6371
5101
  return [resolvedArgs[0]];
6372
5102
  },
6373
-
6374
5103
  _signature: [{ types: [TYPE_ANY] }],
6375
5104
  },
6376
-
6377
- /**
6378
- * converts the passed arg to a number. The conversion happens as per the following rules
6379
- * * string - Returns the parsed number.
6380
- * * number - Returns the passed in value.
6381
- * * array - null
6382
- * * object - null
6383
- * * boolean - null
6384
- * * null - null
6385
- * @param {any} arg
6386
- * @return {number}
6387
- * @function toNumber
6388
- * @example
6389
- * toNumber(1) //returns 1
6390
- * @example
6391
- * toNumber('10') //returns 10
6392
- * @example
6393
- * toNumber({a: 1}) //returns null
6394
- * @example
6395
- * toNumber(true()) //returns null
6396
- * @category jmespath
6397
- */
6398
5105
  toNumber: {
6399
5106
  _func: resolvedArgs => {
6400
5107
  const typeName = getTypeName(resolvedArgs[0]);
@@ -6408,20 +5115,6 @@ function functions(
6408
5115
  },
6409
5116
  _signature: [{ types: [TYPE_ANY] }],
6410
5117
  },
6411
-
6412
- /**
6413
- * converts the passed `arg` to a string. The conversion happens as per the following rules
6414
- * * string - Returns the passed in value.
6415
- * * number/array/object/boolean - The JSON encoded value of the object.
6416
- * @param {any} arg
6417
- * @return {string}
6418
- * @function toString
6419
- * @example
6420
- * toString(1) //returns '1'
6421
- * @example
6422
- * toString(true()) //returns 'true'
6423
- * @category jmespath
6424
- */
6425
5118
  toString: {
6426
5119
  _func: resolvedArgs => {
6427
5120
  if (getTypeName(resolvedArgs[0]) === TYPE_STRING) {
@@ -6429,30 +5122,8 @@ function functions(
6429
5122
  }
6430
5123
  return JSON.stringify(resolvedArgs[0]);
6431
5124
  },
6432
-
6433
5125
  _signature: [{ types: [TYPE_ANY] }],
6434
5126
  },
6435
-
6436
- /**
6437
- * Returns the JavaScript type of the given `subject` argument as a string value.
6438
- *
6439
- * The return value MUST be one of the following:
6440
- * * number
6441
- * * string
6442
- * * boolean
6443
- * * array
6444
- * * object
6445
- * * null
6446
- * @param {any} subject
6447
- * @return {string}
6448
- *
6449
- * @function type
6450
- * @example
6451
- * type(1) //returns 'number'
6452
- * @example
6453
- * type('') //returns 'string'
6454
- * @category jmespath
6455
- */
6456
5127
  type: {
6457
5128
  _func: resolvedArgs => ({
6458
5129
  [TYPE_NUMBER]: 'number',
@@ -6465,18 +5136,6 @@ function functions(
6465
5136
  }[getTypeName(resolvedArgs[0])]),
6466
5137
  _signature: [{ types: [TYPE_ANY] }],
6467
5138
  },
6468
-
6469
- /**
6470
- * Returns the values of the provided object `obj`. Note that because JSON hashes are
6471
- * inherently unordered, the values associated with the provided object obj are
6472
- * inherently unordered.
6473
- * @param {object} obj
6474
- * @return {array}
6475
- * @function values
6476
- * @example
6477
- * values({a : 3, b : 4}) //returns [3, 4]
6478
- * @category jmespath
6479
- */
6480
5139
  values: {
6481
5140
  _func: resolvedArgs => {
6482
5141
  const arg = valueOf(resolvedArgs[0]);
@@ -6485,19 +5144,6 @@ function functions(
6485
5144
  },
6486
5145
  _signature: [{ types: [TYPE_ANY] }],
6487
5146
  },
6488
-
6489
- /**
6490
- * Returns a convolved (zipped) array containing grouped arrays of values from
6491
- * the array arguments from index 0, 1, 2, etc.
6492
- * This function accepts a variable number of arguments.
6493
- * The length of the returned array is equal to the length of the shortest array.
6494
- * @param {...array} arrays array of arrays to zip together
6495
- * @return {array} An array of arrays with elements zipped together
6496
- * @function zip
6497
- * @example
6498
- * zip([1, 2, 3], [4, 5, 6]) //returns [[1, 4], [2, 5], [3, 6]]
6499
- * @category jmespath
6500
- */
6501
5147
  zip: {
6502
5148
  _func: args => {
6503
5149
  const count = args.reduce((min, current) => Math.min(min, current.length), args[0].length);
@@ -6516,17 +5162,13 @@ function functions(
6516
5162
  return functionMap;
6517
5163
  }
6518
5164
 
6519
- /* eslint-disable max-classes-per-file */
6520
-
6521
- // Type constants used to define functions.
6522
5165
  const {
6523
5166
  TYPE_CLASS,
6524
5167
  TYPE_ANY,
6525
5168
  } = dataTypes;
6526
-
6527
5169
  function getToNumber(stringToNumber, debug = []) {
6528
5170
  return value => {
6529
- const n = getValueOf(value); // in case it's an object that implements valueOf()
5171
+ const n = getValueOf(value);
6530
5172
  if (n === null) return null;
6531
5173
  if (n instanceof Array) {
6532
5174
  debug.push('Converted array to zero');
@@ -6542,26 +5184,20 @@ function getToNumber(stringToNumber, debug = []) {
6542
5184
  }
6543
5185
  function toString(a) {
6544
5186
  if (a === null || a === undefined) return '';
6545
- // don't call a 'toString' method, since we could have a child named 'toString()'
6546
5187
  return a.toString();
6547
5188
  }
6548
-
6549
5189
  const defaultStringToNumber = (str => {
6550
5190
  const n = +str;
6551
5191
  return Number.isNaN(n) ? 0 : n;
6552
5192
  });
6553
-
6554
5193
  function isClass(obj) {
6555
5194
  if (obj === null) return false;
6556
5195
  if (Array.isArray(obj)) return false;
6557
5196
  return obj.constructor.name !== 'Object';
6558
5197
  }
6559
-
6560
5198
  function matchClass(arg, expectedList) {
6561
- // checking isClass() generates a dependency -- so call it only if necessary
6562
5199
  return expectedList.includes(TYPE_CLASS) && isClass(arg);
6563
5200
  }
6564
-
6565
5201
  class Runtime {
6566
5202
  constructor(debug, toNumber, customFunctions = {}) {
6567
5203
  this.strictDeepEqual = strictDeepEqual;
@@ -6576,25 +5212,16 @@ class Runtime {
6576
5212
  toString,
6577
5213
  debug,
6578
5214
  );
6579
-
6580
5215
  Object.entries(
6581
5216
  openFormulaFunctions(getValueOf, toString, toNumber, debug),
6582
5217
  ).forEach(([fname, func]) => {
6583
5218
  this.functionTable[fname] = func;
6584
5219
  });
6585
-
6586
5220
  Object.entries(customFunctions).forEach(([fname, func]) => {
6587
5221
  this.functionTable[fname] = func;
6588
5222
  });
6589
5223
  }
6590
-
6591
- // eslint-disable-next-line class-methods-use-this
6592
5224
  _validateArgs(argName, args, signature, bResolved) {
6593
- // Validating the args requires validating
6594
- // the correct arity and the correct type of each arg.
6595
- // If the last argument is declared as variadic, then we need
6596
- // a minimum number of args to be required. Otherwise it has to
6597
- // be an exact amount.
6598
5225
  if (signature.length === 0) {
6599
5226
  return;
6600
5227
  }
@@ -6613,39 +5240,31 @@ class Runtime {
6613
5240
  + `takes ${signature.length}${pluralized
6614
5241
  } but received ${args.length}`);
6615
5242
  }
6616
- // if the arguments are unresolved, there's no point in validating types
6617
5243
  if (!bResolved) return;
6618
5244
  let currentSpec;
6619
5245
  let actualType;
6620
5246
  const limit = Math.min(signature.length, args.length);
6621
5247
  for (let i = 0; i < limit; i += 1) {
6622
5248
  currentSpec = signature[i].types;
6623
- // Try to avoid checks that will introspect the object and generate dependencies
6624
5249
  if (!matchClass(args[i], currentSpec) && !currentSpec.includes(TYPE_ANY)) {
6625
5250
  actualType = getTypeNames(args[i]);
6626
- // eslint-disable-next-line no-param-reassign
6627
5251
  args[i] = matchType(actualType, currentSpec, args[i], argName, this.toNumber, toString);
6628
5252
  }
6629
5253
  }
6630
5254
  }
6631
-
6632
5255
  callFunction(name, resolvedArgs, data, interpreter, bResolved = true) {
6633
- // this check will weed out 'valueOf', 'toString' etc
6634
5256
  if (!Object.prototype.hasOwnProperty.call(this.functionTable, name)) throw new Error(`Unknown function: ${name}()`);
6635
-
6636
5257
  const functionEntry = this.functionTable[name];
6637
5258
  this._validateArgs(name, resolvedArgs, functionEntry._signature, bResolved);
6638
5259
  return functionEntry._func.call(this, resolvedArgs, data, interpreter);
6639
5260
  }
6640
5261
  }
6641
-
6642
5262
  class Formula {
6643
5263
  constructor(debug, customFunctions, stringToNumberFn) {
6644
5264
  this.debug = debug;
6645
5265
  this.toNumber = getToNumber(stringToNumberFn || defaultStringToNumber, debug);
6646
5266
  this.runtime = new Runtime(debug, this.toNumber, customFunctions);
6647
5267
  }
6648
-
6649
5268
  compile(stream, allowedGlobalNames = []) {
6650
5269
  let ast;
6651
5270
  try {
@@ -6657,11 +5276,7 @@ class Formula {
6657
5276
  }
6658
5277
  return ast;
6659
5278
  }
6660
-
6661
5279
  search(node, data, globals = {}, language = 'en-US') {
6662
- // This needs to be improved. Both the interpreter and runtime depend on
6663
- // each other. The runtime needs the interpreter to support exprefs.
6664
- // There's likely a clean way to avoid the cyclic dependency.
6665
5280
  this.runtime.interpreter = new TreeInterpreter(
6666
5281
  this.runtime,
6667
5282
  globals,
@@ -6670,7 +5285,6 @@ class Formula {
6670
5285
  this.debug,
6671
5286
  language,
6672
5287
  );
6673
-
6674
5288
  try {
6675
5289
  return this.runtime.interpreter.search(node, data);
6676
5290
  } catch (e) {
@@ -6680,33 +5294,7 @@ class Formula {
6680
5294
  }
6681
5295
  }
6682
5296
 
6683
- /*
6684
- Copyright 2021 Adobe. All rights reserved.
6685
- This file is licensed to you under the Apache License, Version 2.0 (the "License");
6686
- you may not use this file except in compliance with the License. You may obtain a copy
6687
- of the License at http://www.apache.org/licenses/LICENSE-2.0
6688
-
6689
- Unless required by applicable law or agreed to in writing, software distributed under
6690
- the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
6691
- OF ANY KIND, either express or implied. See the License for the specific language
6692
- governing permissions and limitations under the License.
6693
- */
6694
-
6695
- /**
6696
- * Returns an instance of JSON JsonFormula Expression that can be executed later on with
6697
- * multiple instances of JSON Data. The instance of the class has a single search
6698
- * function that can be used to evaluate the expression on a json payload. The advantage
6699
- * of using this over {jsonJsonFormula} function is that it can be performant if a single expression
6700
- * has to be used for multiple json data instances.
6701
- */
6702
5297
  class JsonFormula {
6703
- /**
6704
- * @param customFunctions {*} custom functions needed by a hosting application.
6705
- * @param stringToNumber {function} A function that converts string values to numbers.
6706
- * Can be used to convert currencies/dates to numbers
6707
- * @param language
6708
- * @param debug {array} will be populated with any errors/warnings
6709
- */
6710
5298
  constructor(
6711
5299
  customFunctions = {},
6712
5300
  stringToNumber = null,
@@ -6717,25 +5305,10 @@ class JsonFormula {
6717
5305
  this.debug = debug;
6718
5306
  this.formula = new Formula(debug, customFunctions, stringToNumber);
6719
5307
  }
6720
-
6721
- /**
6722
- * Evaluates the JsonFormula on a particular json payload and return the result
6723
- * @param json {object} the json data on which the expression needs to be evaluated
6724
- * @param globals {*} global objects that can be accessed via custom functions.
6725
- * @returns {*} the result of the expression being evaluated
6726
- */
6727
5308
  search(expression, json, globals = {}, language = 'en-US') {
6728
5309
  const ast = this.compile(expression, Object.keys(globals));
6729
5310
  return this.run(ast, json, language, globals);
6730
5311
  }
6731
-
6732
- /**
6733
- * Execute a previously compiled expression against a json object and return the result
6734
- * @param ast {object} The abstract syntax tree returned from compile()
6735
- * @param json {object} the json data on which the expression needs to be evaluated
6736
- * @param globals {*} set of objects available in global scope
6737
- * @returns {*} the result of the expression being evaluated
6738
- */
6739
5312
  run(ast, json, language, globals) {
6740
5313
  return this.formula.search(
6741
5314
  ast,
@@ -6744,14 +5317,6 @@ class JsonFormula {
6744
5317
  language,
6745
5318
  );
6746
5319
  }
6747
-
6748
- /*
6749
- * Creates a compiled expression that can be executed later on with some data.
6750
- * @param expression {string} the expression to evaluate
6751
- * @param allowedGlobalNames {string[]} A list of names of the global variables
6752
- * being used in the expression.
6753
- * @param debug {array} will be populated with any errors/warnings
6754
- */
6755
5320
  compile(expression, allowedGlobalNames = []) {
6756
5321
  this.debug.length = 0;
6757
5322
  return this.formula.compile(expression, allowedGlobalNames);
@@ -6804,7 +5369,8 @@ class RuleEngine {
6804
5369
  }
6805
5370
 
6806
5371
  const defaults = {
6807
- visible: true
5372
+ visible: true,
5373
+ enabled: true
6808
5374
  };
6809
5375
  class Fieldset extends Container {
6810
5376
  constructor(params, _options) {
@@ -6847,12 +5413,6 @@ class Fieldset extends Container {
6847
5413
  }
6848
5414
  }
6849
5415
 
6850
- var __decorate$1 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
6851
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
6852
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
6853
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6854
- return c > 3 && r && Object.defineProperty(target, key, r), r;
6855
- };
6856
5416
  class InstanceManager extends Fieldset {
6857
5417
  get maxOccur() {
6858
5418
  return this._jsonModel.maxItems;
@@ -6870,13 +5430,22 @@ class InstanceManager extends Fieldset {
6870
5430
  return this.removeItem(action);
6871
5431
  }
6872
5432
  }
6873
- __decorate$1([
5433
+ __decorate([
6874
5434
  dependencyTracked()
6875
5435
  ], InstanceManager.prototype, "maxOccur", null);
6876
- __decorate$1([
5436
+ __decorate([
6877
5437
  dependencyTracked()
6878
5438
  ], InstanceManager.prototype, "minOccur", null);
6879
5439
 
5440
+ class ValidationError {
5441
+ fieldName;
5442
+ errorMessages;
5443
+ constructor(fieldName = '', errorMessages = []) {
5444
+ this.errorMessages = errorMessages;
5445
+ this.fieldName = fieldName;
5446
+ }
5447
+ }
5448
+
6880
5449
  const dateRegex = /^(\d{4})-(\d{1,2})-(\d{1,2})$/;
6881
5450
  const days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
6882
5451
  const daysInMonth = (leapYear, month) => {
@@ -7150,33 +5719,9 @@ const Constraints = {
7150
5719
  }
7151
5720
  };
7152
5721
 
7153
- /*************************************************************************
7154
- * ADOBE CONFIDENTIAL
7155
- * ___________________
7156
- *
7157
- * Copyright 2022 Adobe
7158
- * All Rights Reserved.
7159
- *
7160
- * NOTICE: All information contained herein is, and remains
7161
- * the property of Adobe and its suppliers, if any. The intellectual
7162
- * and technical concepts contained herein are proprietary to Adobe
7163
- * and its suppliers and are protected by all applicable intellectual
7164
- * property laws, including trade secret and copyright laws.
7165
- * Dissemination of this information or reproduction of this material
7166
- * is strictly forbidden unless prior written permission is obtained
7167
- * from Adobe.
7168
- **************************************************************************/
7169
- /**
7170
- * https://unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table
7171
- * Credit: https://git.corp.adobe.com/dc/dfl/blob/master/src/patterns/parseDateTimeSkeleton.js
7172
- * Created a separate library to be used elsewhere as well.
7173
- */
7174
5722
  const DATE_TIME_REGEX =
7175
- // eslint-disable-next-line max-len
7176
5723
  /(?:[Eec]{1,6}|G{1,5}|[Qq]{1,5}|(?:[yYur]+|U{1,5})|[ML]{1,5}|d{1,2}|D{1,3}|F{1}|[abB]{1,5}|[hkHK]{1,2}|w{1,2}|W{1}|m{1,2}|s{1,2}|[zZOvV]{1,5}|[zZOvVxX]{1,3}|S{1,3}|'(?:[^']|'')*')|[^a-zA-Z']+/g;
7177
-
7178
5724
  const ShorthandStyles$1 = ["full", "long", "medium", "short"];
7179
-
7180
5725
  function getSkeleton(skeleton, language) {
7181
5726
  if (ShorthandStyles$1.find(type => skeleton.includes(type))) {
7182
5727
  const parsed = parseDateStyle(skeleton, language);
@@ -7197,24 +5742,13 @@ function getSkeleton(skeleton, language) {
7197
5742
  }
7198
5743
  return skeleton;
7199
5744
  }
7200
-
7201
- /**
7202
- *
7203
- * @param skeleton shorthand style for the date concatenated with shorthand style of time. The
7204
- * Shorthand style for both date and time is one of ['full', 'long', 'medium', 'short'].
7205
- * @param language {string} language to parse the date shorthand style
7206
- * @returns {[*,string][]}
7207
- */
7208
5745
  function parseDateStyle(skeleton, language) {
7209
5746
  const options = {};
7210
- // the skeleton could have two keywords -- one for date, one for time
7211
5747
  const styles = skeleton.split(/\s/).filter(s => s.length);
7212
5748
  options.dateStyle = styles[0];
7213
5749
  if (styles.length > 1) options.timeStyle = styles[1];
7214
-
7215
5750
  const testDate = new Date(2000, 2, 1, 2, 3, 4);
7216
5751
  const parts = new Intl.DateTimeFormat(language, options).formatToParts(testDate);
7217
- // oddly, the formatted month name can be different from the standalone month name
7218
5752
  const formattedMarch = parts.find(p => p.type === 'month').value;
7219
5753
  const longMarch = new Intl.DateTimeFormat(language, {month: 'long'}).formatToParts(testDate)[0].value;
7220
5754
  const shortMarch = new Intl.DateTimeFormat(language, {month: 'short'}).formatToParts(testDate)[0].value;
@@ -7238,11 +5772,6 @@ function parseDateStyle(skeleton, language) {
7238
5772
  });
7239
5773
  return result;
7240
5774
  }
7241
-
7242
- /**
7243
- * Parse Date time skeleton into Intl.DateTimeFormatOptions parts
7244
- * Ref: https://unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table
7245
- */
7246
5775
  function parseDateTimeSkeleton(skeleton, language) {
7247
5776
  if (ShorthandStyles$1.find(type => skeleton.includes(type))) {
7248
5777
  return parseDateStyle(skeleton, language);
@@ -7251,11 +5780,9 @@ function parseDateTimeSkeleton(skeleton, language) {
7251
5780
  skeleton.replace(DATE_TIME_REGEX, match => {
7252
5781
  const len = match.length;
7253
5782
  switch (match[0]) {
7254
- // Era
7255
5783
  case 'G':
7256
5784
  result.push(['era', len === 4 ? 'long' : len === 5 ? 'narrow' : 'short', len]);
7257
5785
  break;
7258
- // Year
7259
5786
  case 'y':
7260
5787
  result.push(['year', len === 2 ? '2-digit' : 'numeric', len]);
7261
5788
  break;
@@ -7266,16 +5793,13 @@ function parseDateTimeSkeleton(skeleton, language) {
7266
5793
  throw new RangeError(
7267
5794
  '`Y/u/U/r` (year) patterns are not supported, use `y` instead'
7268
5795
  );
7269
- // Quarter
7270
5796
  case 'q':
7271
5797
  case 'Q':
7272
5798
  throw new RangeError('`q/Q` (quarter) patterns are not supported');
7273
- // Month
7274
5799
  case 'M':
7275
5800
  case 'L':
7276
5801
  result.push(['month', ['numeric', '2-digit', 'short', 'long', 'narrow'][len - 1], len]);
7277
5802
  break;
7278
- // Week
7279
5803
  case 'w':
7280
5804
  case 'W':
7281
5805
  throw new RangeError('`w/W` (week) patterns are not supported');
@@ -7288,7 +5812,6 @@ function parseDateTimeSkeleton(skeleton, language) {
7288
5812
  throw new RangeError(
7289
5813
  '`D/F/g` (day) patterns are not supported, use `d` instead'
7290
5814
  );
7291
- // Weekday
7292
5815
  case 'E':
7293
5816
  result.push(['weekday', ['short', 'short', 'short', 'long', 'narrow', 'narrow'][len - 1], len]);
7294
5817
  break;
@@ -7304,16 +5827,14 @@ function parseDateTimeSkeleton(skeleton, language) {
7304
5827
  }
7305
5828
  result.push(['weekday', ['short', 'long', 'narrow', 'short'][len - 3], len]);
7306
5829
  break;
7307
- // Period
7308
- case 'a': // AM, PM
5830
+ case 'a':
7309
5831
  result.push(['hour12', true, 1]);
7310
5832
  break;
7311
- case 'b': // am, pm, noon, midnight
7312
- case 'B': // flexible day periods
5833
+ case 'b':
5834
+ case 'B':
7313
5835
  throw new RangeError(
7314
5836
  '`b/B` (period) patterns are not supported, use `a` instead'
7315
5837
  );
7316
- // Hour
7317
5838
  case 'h':
7318
5839
  result.push(['hourCycle', 'h12']);
7319
5840
  result.push(['hour', ['numeric', '2-digit'][len - 1], len]);
@@ -7336,11 +5857,9 @@ function parseDateTimeSkeleton(skeleton, language) {
7336
5857
  throw new RangeError(
7337
5858
  '`j/J/C` (hour) patterns are not supported, use `h/H/K/k` instead'
7338
5859
  );
7339
- // Minute
7340
5860
  case 'm':
7341
5861
  result.push(['minute', ['numeric', '2-digit'][len - 1], len]);
7342
5862
  break;
7343
- // Second
7344
5863
  case 's':
7345
5864
  result.push(['second', ['numeric', '2-digit'][len - 1], len]);
7346
5865
  break;
@@ -7351,23 +5870,19 @@ function parseDateTimeSkeleton(skeleton, language) {
7351
5870
  throw new RangeError(
7352
5871
  '`S/A` (millisecond) patterns are not supported, use `s` instead'
7353
5872
  );
7354
- // Zone
7355
- case 'O': // timeZone GMT-8 or GMT-08:00
5873
+ case 'O':
7356
5874
  result.push(['timeZoneName', len < 4 ? 'shortOffset' : 'longOffset', len]);
7357
5875
  result.push(['x-timeZoneName', len < 4 ? 'O' : 'OOOO', len]);
7358
5876
  break;
7359
- case 'X': // 1, 2, 3, 4: The ISO8601 varios formats
7360
- case 'x': // 1, 2, 3, 4: The ISO8601 varios formats
7361
- case 'Z': // 1..3, 4, 5: The ISO8601 varios formats
7362
- // Z, ZZ, ZZZ should produce -0800
7363
- // ZZZZ should produce GMT-08:00
7364
- // ZZZZZ should produce -8:00 or -07:52:58
5877
+ case 'X':
5878
+ case 'x':
5879
+ case 'Z':
7365
5880
  result.push(['timeZoneName', 'longOffset', 1]);
7366
5881
  result.push(['x-timeZoneName', match, 1]);
7367
5882
  break;
7368
- case 'z': // 1..3, 4: specific non-location format
7369
- case 'v': // 1, 4: generic non-location format
7370
- case 'V': // 1, 2, 3, 4: time zone ID or city
5883
+ case 'z':
5884
+ case 'v':
5885
+ case 'V':
7371
5886
  throw new RangeError(
7372
5887
  'z/v/V` (timeZone) patterns are not supported, use `X/x/Z/O` instead'
7373
5888
  );
@@ -7382,29 +5897,6 @@ function parseDateTimeSkeleton(skeleton, language) {
7382
5897
  return result;
7383
5898
  }
7384
5899
 
7385
- /*************************************************************************
7386
- * ADOBE CONFIDENTIAL
7387
- * ___________________
7388
- *
7389
- * Copyright 2022 Adobe
7390
- * All Rights Reserved.
7391
- *
7392
- * NOTICE: All information contained herein is, and remains
7393
- * the property of Adobe and its suppliers, if any. The intellectual
7394
- * and technical concepts contained herein are proprietary to Adobe
7395
- * and its suppliers and are protected by all applicable intellectual
7396
- * property laws, including trade secret and copyright laws.
7397
- * Dissemination of this information or reproduction of this material
7398
- * is strictly forbidden unless prior written permission is obtained
7399
- * from Adobe.
7400
- **************************************************************************/
7401
-
7402
- /**
7403
- * in some cases, DateTimeFormat doesn't respect the 'numeric' vs. '2-digit' setting
7404
- * for time values. The function corrects that
7405
- * @param formattedParts instance of Intl.DateTimeFormatPart[]
7406
- * @param parsed
7407
- */
7408
5900
  function fixDigits(formattedParts, parsed) {
7409
5901
  ['hour', 'minute', 'second'].forEach(type => {
7410
5902
  const defn = formattedParts.find(f => f.type === type);
@@ -7414,55 +5906,29 @@ function fixDigits(formattedParts, parsed) {
7414
5906
  if (fmt === 'numeric' && defn.value.length === 2 && defn.value.charAt(0) === '0') defn.value = defn.value.slice(1);
7415
5907
  });
7416
5908
  }
7417
-
7418
5909
  function fixYear(formattedParts, parsed) {
7419
- // two digit years are handled differently in DateTimeFormat. 00 becomes 1900
7420
- // providing a two digit year 0010 gets formatted to 10 and when parsed becomes 1910
7421
- // Hence we need to pad the year with 0 as required by the skeleton and mentioned in
7422
- // unicode. https://www.unicode.org/reports/tr35/tr35-dates.html#dfst-year
7423
5910
  const defn = formattedParts.find(f => f.type === 'year');
7424
5911
  if (!defn) return;
7425
- // eslint-disable-next-line no-unused-vars
7426
5912
  const chars = parsed.find(pair => pair[0] === 'year')[2];
7427
5913
  while(defn.value.length < chars) {
7428
5914
  defn.value = `0${defn.value}`;
7429
5915
  }
7430
5916
  }
7431
-
7432
- /**
7433
- *
7434
- * @param dateValue {Date}
7435
- * @param language {string}
7436
- * @param skeleton {string}
7437
- * @param timeZone {string}
7438
- * @returns {T}
7439
- */
7440
5917
  function formatDateToParts(dateValue, language, skeleton, timeZone) {
7441
- // DateTimeFormat renames some of the options in its formatted output
7442
- //@ts-ignore
7443
5918
  const mappings = key => ({
7444
5919
  hour12: 'dayPeriod',
7445
5920
  fractionalSecondDigits: 'fractionalSecond',
7446
5921
  })[key] || key;
7447
-
7448
- // produces an array of name/value pairs of skeleton parts
7449
5922
  const allParameters = parseDateTimeSkeleton(skeleton, language);
7450
5923
  allParameters.push(['timeZone', timeZone]);
7451
-
7452
5924
  const parsed = allParameters.filter(p => !p[0].startsWith('x-'));
7453
5925
  const nonStandard = allParameters.filter(p => p[0].startsWith('x-'));
7454
- // reduce to a set of options that can be used to format
7455
5926
  const options = Object.fromEntries(parsed);
7456
5927
  delete options.literal;
7457
-
7458
5928
  const df = new Intl.DateTimeFormat(language, options);
7459
- // formattedParts will have all the pieces we need for our date -- but not in the correct order
7460
5929
  const formattedParts = df.formatToParts(dateValue);
7461
-
7462
5930
  fixDigits(formattedParts, allParameters);
7463
5931
  fixYear(formattedParts, parsed);
7464
- // iterate through the original parsed components and use its ordering and literals,
7465
- // and add the formatted pieces
7466
5932
  return parsed.reduce((result, cur) => {
7467
5933
  if (cur[0] === 'literal') result.push(cur);
7468
5934
  else {
@@ -7472,37 +5938,25 @@ function formatDateToParts(dateValue, language, skeleton, timeZone) {
7472
5938
  const category = tz[0];
7473
5939
  if (category === 'Z') {
7474
5940
  if (tz.length < 4) {
7475
- // handle 'Z', 'ZZ', 'ZZZ' Time Zone: ISO8601 basic hms? / RFC 822
7476
5941
  v.value = v.value.replace(/(GMT|:)/g, '');
7477
5942
  if (v.value === '') v.value = '+0000';
7478
5943
  } else if (tz.length === 5) {
7479
- // 'ZZZZZ' Time Zone: ISO8601 extended hms?
7480
5944
  if (v.value === 'GMT') v.value = 'Z';
7481
5945
  else v.value = v.value.replace(/GMT/, '');
7482
5946
  }
7483
5947
  }
7484
5948
  if (category === 'X' || category === 'x') {
7485
5949
  if (tz.length === 1) {
7486
- // 'X' ISO8601 basic hm?, with Z for 0
7487
- // -08, +0530, Z
7488
- // 'x' ISO8601 basic hm?, without Z for 0
7489
5950
  v.value = v.value.replace(/(GMT|:(00)?)/g, '');
7490
5951
  }
7491
5952
  if (tz.length === 2) {
7492
- // 'XX' ISO8601 basic hm, with Z
7493
- // -0800, Z
7494
- // 'xx' ISO8601 basic hm, without Z
7495
5953
  v.value = v.value.replace(/(GMT|:)/g, '');
7496
5954
  }
7497
5955
  if (tz.length === 3) {
7498
- // 'XXX' ISO8601 extended hm, with Z
7499
- // -08:00, Z
7500
- // 'xxx' ISO8601 extended hm, without Z
7501
5956
  v.value = v.value.replace(/GMT/g, '');
7502
5957
  }
7503
5958
  if (category === 'X' && v.value === '') v.value = 'Z';
7504
5959
  } else if (tz === 'O') {
7505
- // eliminate 'GMT', leading and trailing zeros
7506
5960
  v.value = v.value.replace(/GMT/g, '').replace(/0(\d+):/, '$1:').replace(/:00/, '');
7507
5961
  if (v.value === '') v.value = '+0';
7508
5962
  }
@@ -7512,18 +5966,12 @@ function formatDateToParts(dateValue, language, skeleton, timeZone) {
7512
5966
  return result;
7513
5967
  }, []);
7514
5968
  }
7515
-
7516
- /**
7517
- *
7518
- * @param dateValue {Date}
7519
- * @param language {string}
7520
- * @param skeleton {string}
7521
- * @param timeZone {string}
7522
- */
7523
5969
  function formatDate(dateValue, language, skeleton, timeZone) {
5970
+ if (skeleton.startsWith('date|')) {
5971
+ skeleton = skeleton.split('|')[1];
5972
+ }
7524
5973
  if (ShorthandStyles$1.find(type => skeleton.includes(type))) {
7525
5974
  const options = {timeZone};
7526
- // the skeleton could have two keywords -- one for date, one for time
7527
5975
  const parts = skeleton.split(/\s/).filter(s => s.length);
7528
5976
  if (ShorthandStyles$1.indexOf(parts[0]) > -1) {
7529
5977
  options.dateStyle = parts[0];
@@ -7559,9 +6007,7 @@ const currencies = {
7559
6007
  'ru-RU': 'RUB',
7560
6008
  'tr-TR': 'TRY'
7561
6009
  };
7562
-
7563
6010
  const locales = Object.keys(currencies);
7564
-
7565
6011
  const getCurrency = function (locale) {
7566
6012
  if (locales.indexOf(locale) > -1) {
7567
6013
  return currencies[locale]
@@ -7575,8 +6021,7 @@ const getCurrency = function (locale) {
7575
6021
  };
7576
6022
 
7577
6023
  const NUMBER_REGEX =
7578
- // eslint-disable-next-line max-len
7579
- /(?:[#]+|[@]+(?:#+)?|[0]+|[,]|[.]|[-]|[+]|[%]|[¤]{1,4}(?:\/([a-zA-Z]{3}))?|[;]|[K]{1,2}|E{1,2}[+]?|'(?:[^']|'')*')|[^a-zA-Z']+/g;
6024
+ /(?:[#]+|[@]+(#+)?|[0]+|[,]|[.]|[-]|[+]|[%]|[¤]{1,4}(?:\/([a-zA-Z]{3}))?|[;]|[K]{1,2}|E{1,2}[+]?|'(?:[^']|'')*')|[^a-zA-Z']+/g;
7580
6025
  const supportedUnits = ['acre', 'bit', 'byte', 'celsius', 'centimeter', 'day',
7581
6026
  'degree', 'fahrenheit', 'fluid-ounce', 'foot', 'gallon', 'gigabit',
7582
6027
  'gigabyte', 'gram', 'hectare', 'hour', 'inch', 'kilobit', 'kilobyte',
@@ -7584,8 +6029,6 @@ const supportedUnits = ['acre', 'bit', 'byte', 'celsius', 'centimeter', 'day',
7584
6029
  'mile-scandinavian', 'milliliter', 'millimeter', 'millisecond', 'minute', 'month',
7585
6030
  'ounce', 'percent', 'petabyte', 'pound', 'second', 'stone', 'terabit', 'terabyte', 'week', 'yard', 'year'].join('|');
7586
6031
  const ShorthandStyles = [/^currency(?:\/([a-zA-Z]{3}))?$/, /^decimal$/, /^integer$/, /^percent$/, new RegExp(`^unit\/(${supportedUnits})$`)];
7587
-
7588
-
7589
6032
  function parseNumberSkeleton(skeleton, language) {
7590
6033
  const options = {};
7591
6034
  const order = [];
@@ -7614,6 +6057,7 @@ function parseNumberSkeleton(skeleton, language) {
7614
6057
  break;
7615
6058
  case 4:
7616
6059
  options.style = 'percent';
6060
+ options.maximumFractionDigits = 2;
7617
6061
  break;
7618
6062
  case 5:
7619
6063
  options.style = "unit";
@@ -7630,7 +6074,7 @@ function parseNumberSkeleton(skeleton, language) {
7630
6074
  options.minimumIntegerDigits = 1;
7631
6075
  options.maximumFractionDigits = 0;
7632
6076
  options.minimumFractionDigits = 0;
7633
- skeleton.replace(NUMBER_REGEX, (match, offset) => {
6077
+ skeleton.replace(NUMBER_REGEX, (match, maxSignificantDigits, currencySymbol, offset) => {
7634
6078
  const len = match.length;
7635
6079
  switch(match[0]) {
7636
6080
  case '#':
@@ -7643,10 +6087,10 @@ function parseNumberSkeleton(skeleton, language) {
7643
6087
  if (options?.minimumSignificantDigits) {
7644
6088
  throw "@ symbol should occur together"
7645
6089
  }
7646
- order.push(['@', len]);
7647
- options.minimumSignificantDigits = len;
7648
- const hashes = match.match(/#+/) || "";
7649
- options.maximumSignificantDigits = len + hashes.length;
6090
+ const hashes = maxSignificantDigits || "";
6091
+ order.push(['@', len - hashes.length]);
6092
+ options.minimumSignificantDigits = len - hashes.length;
6093
+ options.maximumSignificantDigits = len;
7650
6094
  order.push(['digit', hashes.length]);
7651
6095
  break;
7652
6096
  case ',':
@@ -7671,6 +6115,9 @@ function parseNumberSkeleton(skeleton, language) {
7671
6115
  }
7672
6116
  if (options?.decimal === true) {
7673
6117
  options.minimumFractionDigits = len;
6118
+ if (!options.maximumFractionDigits) {
6119
+ options.maximumFractionDigits = len;
6120
+ }
7674
6121
  } else {
7675
6122
  options.minimumIntegerDigits = len;
7676
6123
  }
@@ -7694,18 +6141,20 @@ function parseNumberSkeleton(skeleton, language) {
7694
6141
  case '¤':
7695
6142
  if (offset !== 0 && offset !== skeleton.length - 1) {
7696
6143
  console.error("currency display should be either in the beginning or at the end");
6144
+ } else {
6145
+ options.style = 'currency';
6146
+ options.currencyDisplay = ['symbol', 'code', 'name', 'narrowSymbol'][len - 1];
6147
+ options.currency = currencySymbol || getCurrency(language);
6148
+ order.push(['currency', len]);
7697
6149
  }
7698
- options.style = 'currency';
7699
- options.currencyDisplay = ['symbol', 'code', 'name', 'narrowSymbol'][len -1];
7700
- options.currency = getCurrency(language);
7701
- order.push(['currency', len]);
7702
6150
  break;
7703
6151
  case '%':
7704
6152
  if (offset !== 0 && offset !== skeleton.length - 1) {
7705
6153
  console.error("percent display should be either in the beginning or at the end");
6154
+ } else {
6155
+ order.push(['%', 1]);
6156
+ options.style = 'percent';
7706
6157
  }
7707
- order.push(['%', 1]);
7708
- options.style = 'percent';
7709
6158
  break;
7710
6159
  case 'E':
7711
6160
  order.push(['E', len]);
@@ -7722,6 +6171,9 @@ function parseNumberSkeleton(skeleton, language) {
7722
6171
  }
7723
6172
 
7724
6173
  function formatNumber(numberValue, language, skeletn) {
6174
+ if (skeletn.startsWith('num|')) {
6175
+ skeletn = skel.split('|')[1];
6176
+ }
7725
6177
  if (!skeletn) return numberValue
7726
6178
  language = language || "en";
7727
6179
  const {options, order} = parseNumberSkeleton(skeletn, language);
@@ -7732,7 +6184,6 @@ const getCategory = function (skeleton) {
7732
6184
  const chkCategory = skeleton?.match(/^(?:(num|date)\|)?(.+)/);
7733
6185
  return [chkCategory?.[1], chkCategory?.[2]]
7734
6186
  };
7735
-
7736
6187
  const format = function (value, locale, skeleton, timezone) {
7737
6188
  const [category, skelton] = getCategory(skeleton);
7738
6189
  switch (category) {
@@ -7748,12 +6199,6 @@ const format = function (value, locale, skeleton, timezone) {
7748
6199
  }
7749
6200
  };
7750
6201
 
7751
- var __decorate = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
7752
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
7753
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
7754
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
7755
- return c > 3 && r && Object.defineProperty(target, key, r), r;
7756
- };
7757
6202
  const validTypes = ['string', 'number', 'boolean', 'file', 'string[]', 'number[]', 'boolean[]', 'file[]', 'array', 'object'];
7758
6203
  class Field extends Scriptable {
7759
6204
  constructor(params, _options) {
@@ -7902,10 +6347,10 @@ class Field extends Scriptable {
7902
6347
  }
7903
6348
  }
7904
6349
  get editFormat() {
7905
- return this._jsonModel.editFormat;
6350
+ return this.withCategory(this._jsonModel.editFormat);
7906
6351
  }
7907
6352
  get displayFormat() {
7908
- return this._jsonModel.displayFormat;
6353
+ return this.withCategory(this._jsonModel.displayFormat);
7909
6354
  }
7910
6355
  get placeholder() {
7911
6356
  return this._jsonModel.placeholder;
@@ -7978,31 +6423,43 @@ class Field extends Scriptable {
7978
6423
  return this._jsonModel.value === undefined || this._jsonModel.value === null || this._jsonModel.value === '';
7979
6424
  }
7980
6425
  withCategory(df) {
7981
- const hasCategory = df?.match(/^(?:date|num)\|/);
7982
- if (hasCategory == null) {
7983
- if (this.format === 'date') {
7984
- df = `date|${df}`;
7985
- }
7986
- else if (this.type === 'number') {
7987
- df = `num|${df}`;
6426
+ if (df) {
6427
+ const hasCategory = df?.match(/^(?:date|num)\|/);
6428
+ if (hasCategory === null) {
6429
+ if (this.format === 'date') {
6430
+ df = `date|${df}`;
6431
+ }
6432
+ else if (this.type === 'number') {
6433
+ df = `num|${df}`;
6434
+ }
6435
+ return df;
7988
6436
  }
7989
- return df;
7990
6437
  }
7991
6438
  return df;
7992
6439
  }
7993
6440
  get editValue() {
7994
- const df = this.withCategory(this.editFormat);
6441
+ const df = this.editFormat;
7995
6442
  if (df && this.isNotEmpty(this.value) && this.valid !== false) {
7996
- return format(this.value, this.language, df);
6443
+ try {
6444
+ return format(this.value, this.language, df);
6445
+ }
6446
+ catch (e) {
6447
+ return this.value;
6448
+ }
7997
6449
  }
7998
6450
  else {
7999
6451
  return this.value;
8000
6452
  }
8001
6453
  }
8002
6454
  get displayValue() {
8003
- const df = this.withCategory(this.displayFormat);
6455
+ const df = this.displayFormat;
8004
6456
  if (df && this.isNotEmpty(this.value) && this.valid !== false) {
8005
- return format(this.value, this.language, df);
6457
+ try {
6458
+ return format(this.value, this.language, df);
6459
+ }
6460
+ catch (e) {
6461
+ return this.value;
6462
+ }
8006
6463
  }
8007
6464
  else {
8008
6465
  return this.value;
@@ -8142,7 +6599,7 @@ class Field extends Scriptable {
8142
6599
  const iv = this._jsonModel.minimum || this._jsonModel.default || 0;
8143
6600
  const fIVal = iv * factor;
8144
6601
  const qt = (fVal - fIVal) / fStep;
8145
- const valid = (fVal - fIVal) % fStep < .001;
6602
+ const valid = Math.abs(fVal - fIVal) % fStep < .001;
8146
6603
  let next, prev;
8147
6604
  if (!valid) {
8148
6605
  next = (Math.ceil(qt) * fStep + fIVal) / factor;
@@ -8345,6 +6802,8 @@ class Field extends Scriptable {
8345
6802
  getState() {
8346
6803
  return {
8347
6804
  ...super.getState(),
6805
+ editFormat: this.editFormat,
6806
+ displayFormat: this.displayFormat,
8348
6807
  editValue: this.editValue,
8349
6808
  displayValue: this.displayValue
8350
6809
  };