@syncfusion/ej2-form-renderer 34.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (214) hide show
  1. package/README.md +60 -0
  2. package/common.d.ts +4 -0
  3. package/common.js +4 -0
  4. package/dist/ej2-form-renderer.umd.min.js +11 -0
  5. package/dist/ej2-form-renderer.umd.min.js.map +1 -0
  6. package/dist/es6/ej2-form-renderer.es2015.js +6787 -0
  7. package/dist/es6/ej2-form-renderer.es2015.js.map +1 -0
  8. package/dist/es6/ej2-form-renderer.es5.js +7055 -0
  9. package/dist/es6/ej2-form-renderer.es5.js.map +1 -0
  10. package/dist/global/ej2-form-renderer.min.js +11 -0
  11. package/dist/global/ej2-form-renderer.min.js.map +1 -0
  12. package/dist/global/index.d.ts +14 -0
  13. package/form-renderer.d.ts +4 -0
  14. package/form-renderer.js +4 -0
  15. package/index.d.ts +4 -0
  16. package/index.js +4 -0
  17. package/license +10 -0
  18. package/package.json +41 -0
  19. package/src/common/checkbox-group.d.ts +55 -0
  20. package/src/common/checkbox-group.js +241 -0
  21. package/src/common/conditional-rule-engine.d.ts +241 -0
  22. package/src/common/conditional-rule-engine.js +505 -0
  23. package/src/common/custom-validation-engine.d.ts +57 -0
  24. package/src/common/custom-validation-engine.js +152 -0
  25. package/src/common/datagrid-component.d.ts +156 -0
  26. package/src/common/datagrid-component.js +410 -0
  27. package/src/common/expressions/dependency-tracker.d.ts +29 -0
  28. package/src/common/expressions/dependency-tracker.js +137 -0
  29. package/src/common/expressions/expression-engine.d.ts +94 -0
  30. package/src/common/expressions/expression-engine.js +514 -0
  31. package/src/common/expressions/expression-parser.d.ts +40 -0
  32. package/src/common/expressions/expression-parser.js +270 -0
  33. package/src/common/expressions/grid-expressions.d.ts +24 -0
  34. package/src/common/expressions/grid-expressions.js +92 -0
  35. package/src/common/expressions/index.d.ts +4 -0
  36. package/src/common/expressions/index.js +4 -0
  37. package/src/common/index.d.ts +10 -0
  38. package/src/common/index.js +10 -0
  39. package/src/common/json-converter.d.ts +945 -0
  40. package/src/common/json-converter.js +1110 -0
  41. package/src/common/minmax-rule-engine.d.ts +105 -0
  42. package/src/common/minmax-rule-engine.js +380 -0
  43. package/src/common/option-fetcher.d.ts +30 -0
  44. package/src/common/option-fetcher.js +139 -0
  45. package/src/common/parser.d.ts +98 -0
  46. package/src/common/parser.js +788 -0
  47. package/src/common/static-html-renderer.d.ts +45 -0
  48. package/src/common/static-html-renderer.js +77 -0
  49. package/src/common/utils.d.ts +116 -0
  50. package/src/common/utils.js +484 -0
  51. package/src/form-renderer/form-renderer-model.d.ts +65 -0
  52. package/src/form-renderer/form-renderer.d.ts +425 -0
  53. package/src/form-renderer/form-renderer.js +2277 -0
  54. package/src/form-renderer/index.d.ts +6 -0
  55. package/src/form-renderer/index.js +5 -0
  56. package/src/form-renderer/render-form-field.d.ts +31 -0
  57. package/src/form-renderer/render-form-field.js +816 -0
  58. package/src/form-renderer/types/form-schema.d.ts +452 -0
  59. package/src/form-renderer/types/form-schema.js +32 -0
  60. package/src/global.js +1 -0
  61. package/src/index.d.ts +4 -0
  62. package/src/index.js +4 -0
  63. package/styles/bds-lite.css +599 -0
  64. package/styles/bds-lite.scss +2 -0
  65. package/styles/bds.css +599 -0
  66. package/styles/bds.scss +2 -0
  67. package/styles/bootstrap-dark-lite.css +608 -0
  68. package/styles/bootstrap-dark-lite.scss +2 -0
  69. package/styles/bootstrap-dark.css +608 -0
  70. package/styles/bootstrap-dark.scss +2 -0
  71. package/styles/bootstrap-lite.css +595 -0
  72. package/styles/bootstrap-lite.scss +2 -0
  73. package/styles/bootstrap.css +595 -0
  74. package/styles/bootstrap.scss +2 -0
  75. package/styles/bootstrap4-lite.css +595 -0
  76. package/styles/bootstrap4-lite.scss +2 -0
  77. package/styles/bootstrap4.css +595 -0
  78. package/styles/bootstrap4.scss +2 -0
  79. package/styles/bootstrap5-dark-lite.css +595 -0
  80. package/styles/bootstrap5-dark-lite.scss +2 -0
  81. package/styles/bootstrap5-dark.css +595 -0
  82. package/styles/bootstrap5-dark.scss +2 -0
  83. package/styles/bootstrap5-lite.css +595 -0
  84. package/styles/bootstrap5-lite.scss +2 -0
  85. package/styles/bootstrap5.3-lite.css +679 -0
  86. package/styles/bootstrap5.3-lite.scss +2 -0
  87. package/styles/bootstrap5.3.css +679 -0
  88. package/styles/bootstrap5.3.scss +2 -0
  89. package/styles/bootstrap5.css +595 -0
  90. package/styles/bootstrap5.scss +2 -0
  91. package/styles/fabric-dark-lite.css +608 -0
  92. package/styles/fabric-dark-lite.scss +2 -0
  93. package/styles/fabric-dark.css +608 -0
  94. package/styles/fabric-dark.scss +2 -0
  95. package/styles/fabric-lite.css +595 -0
  96. package/styles/fabric-lite.scss +2 -0
  97. package/styles/fabric.css +595 -0
  98. package/styles/fabric.scss +2 -0
  99. package/styles/fluent-dark-lite.css +595 -0
  100. package/styles/fluent-dark-lite.scss +2 -0
  101. package/styles/fluent-dark.css +595 -0
  102. package/styles/fluent-dark.scss +2 -0
  103. package/styles/fluent-lite.css +595 -0
  104. package/styles/fluent-lite.scss +2 -0
  105. package/styles/fluent.css +595 -0
  106. package/styles/fluent.scss +2 -0
  107. package/styles/fluent2-lite.css +681 -0
  108. package/styles/fluent2-lite.scss +2 -0
  109. package/styles/fluent2.css +681 -0
  110. package/styles/fluent2.scss +2 -0
  111. package/styles/form-renderer/_all.scss +2 -0
  112. package/styles/form-renderer/_bds-definition.scss +8 -0
  113. package/styles/form-renderer/_bootstrap-dark-definition.scss +8 -0
  114. package/styles/form-renderer/_bootstrap-definition.scss +8 -0
  115. package/styles/form-renderer/_bootstrap4-definition.scss +8 -0
  116. package/styles/form-renderer/_bootstrap5-dark-definition.scss +8 -0
  117. package/styles/form-renderer/_bootstrap5-definition.scss +8 -0
  118. package/styles/form-renderer/_bootstrap5.3-definition.scss +8 -0
  119. package/styles/form-renderer/_fabric-dark-definition.scss +8 -0
  120. package/styles/form-renderer/_fabric-definition.scss +8 -0
  121. package/styles/form-renderer/_fluent-dark-definition.scss +8 -0
  122. package/styles/form-renderer/_fluent-definition.scss +8 -0
  123. package/styles/form-renderer/_fluent2-definition.scss +8 -0
  124. package/styles/form-renderer/_highcontrast-definition.scss +8 -0
  125. package/styles/form-renderer/_highcontrast-light-definition.scss +8 -0
  126. package/styles/form-renderer/_layout.scss +480 -0
  127. package/styles/form-renderer/_material-dark-definition.scss +8 -0
  128. package/styles/form-renderer/_material-definition.scss +8 -0
  129. package/styles/form-renderer/_material3-dark-definition.scss +8 -0
  130. package/styles/form-renderer/_material3-definition.scss +8 -0
  131. package/styles/form-renderer/_mixin.scss +26 -0
  132. package/styles/form-renderer/_tailwind-dark-definition.scss +8 -0
  133. package/styles/form-renderer/_tailwind-definition.scss +8 -0
  134. package/styles/form-renderer/_tailwind3-definition.scss +8 -0
  135. package/styles/form-renderer/_theme.scss +69 -0
  136. package/styles/form-renderer/_variables.scss +2 -0
  137. package/styles/form-renderer/bds.css +599 -0
  138. package/styles/form-renderer/bds.scss +2 -0
  139. package/styles/form-renderer/bootstrap-dark.css +608 -0
  140. package/styles/form-renderer/bootstrap-dark.scss +2 -0
  141. package/styles/form-renderer/bootstrap.css +595 -0
  142. package/styles/form-renderer/bootstrap.scss +2 -0
  143. package/styles/form-renderer/bootstrap4.css +595 -0
  144. package/styles/form-renderer/bootstrap4.scss +2 -0
  145. package/styles/form-renderer/bootstrap5-dark.css +595 -0
  146. package/styles/form-renderer/bootstrap5-dark.scss +2 -0
  147. package/styles/form-renderer/bootstrap5.3.css +679 -0
  148. package/styles/form-renderer/bootstrap5.3.scss +2 -0
  149. package/styles/form-renderer/bootstrap5.css +595 -0
  150. package/styles/form-renderer/bootstrap5.scss +2 -0
  151. package/styles/form-renderer/fabric-dark.css +608 -0
  152. package/styles/form-renderer/fabric-dark.scss +2 -0
  153. package/styles/form-renderer/fabric.css +595 -0
  154. package/styles/form-renderer/fabric.scss +2 -0
  155. package/styles/form-renderer/fluent-dark.css +595 -0
  156. package/styles/form-renderer/fluent-dark.scss +2 -0
  157. package/styles/form-renderer/fluent.css +595 -0
  158. package/styles/form-renderer/fluent.scss +2 -0
  159. package/styles/form-renderer/fluent2.css +681 -0
  160. package/styles/form-renderer/fluent2.scss +2 -0
  161. package/styles/form-renderer/highcontrast-light.css +595 -0
  162. package/styles/form-renderer/highcontrast-light.scss +2 -0
  163. package/styles/form-renderer/highcontrast.css +608 -0
  164. package/styles/form-renderer/highcontrast.scss +2 -0
  165. package/styles/form-renderer/material-dark.css +608 -0
  166. package/styles/form-renderer/material-dark.scss +2 -0
  167. package/styles/form-renderer/material.css +595 -0
  168. package/styles/form-renderer/material.scss +2 -0
  169. package/styles/form-renderer/material3-dark.css +677 -0
  170. package/styles/form-renderer/material3-dark.scss +2 -0
  171. package/styles/form-renderer/material3.css +679 -0
  172. package/styles/form-renderer/material3.scss +2 -0
  173. package/styles/form-renderer/tailwind-dark.css +595 -0
  174. package/styles/form-renderer/tailwind-dark.scss +2 -0
  175. package/styles/form-renderer/tailwind.css +595 -0
  176. package/styles/form-renderer/tailwind.scss +2 -0
  177. package/styles/form-renderer/tailwind3.css +669 -0
  178. package/styles/form-renderer/tailwind3.scss +2 -0
  179. package/styles/highcontrast-light-lite.css +595 -0
  180. package/styles/highcontrast-light-lite.scss +2 -0
  181. package/styles/highcontrast-light.css +595 -0
  182. package/styles/highcontrast-light.scss +2 -0
  183. package/styles/highcontrast-lite.css +608 -0
  184. package/styles/highcontrast-lite.scss +2 -0
  185. package/styles/highcontrast.css +608 -0
  186. package/styles/highcontrast.scss +2 -0
  187. package/styles/material-dark-lite.css +608 -0
  188. package/styles/material-dark-lite.scss +2 -0
  189. package/styles/material-dark.css +608 -0
  190. package/styles/material-dark.scss +2 -0
  191. package/styles/material-lite.css +595 -0
  192. package/styles/material-lite.scss +2 -0
  193. package/styles/material.css +595 -0
  194. package/styles/material.scss +2 -0
  195. package/styles/material3-dark-lite.css +677 -0
  196. package/styles/material3-dark-lite.scss +2 -0
  197. package/styles/material3-dark.css +677 -0
  198. package/styles/material3-dark.scss +2 -0
  199. package/styles/material3-lite.css +679 -0
  200. package/styles/material3-lite.scss +2 -0
  201. package/styles/material3.css +679 -0
  202. package/styles/material3.scss +2 -0
  203. package/styles/tailwind-dark-lite.css +595 -0
  204. package/styles/tailwind-dark-lite.scss +2 -0
  205. package/styles/tailwind-dark.css +595 -0
  206. package/styles/tailwind-dark.scss +2 -0
  207. package/styles/tailwind-lite.css +595 -0
  208. package/styles/tailwind-lite.scss +2 -0
  209. package/styles/tailwind.css +595 -0
  210. package/styles/tailwind.scss +2 -0
  211. package/styles/tailwind3-lite.css +669 -0
  212. package/styles/tailwind3-lite.scss +2 -0
  213. package/styles/tailwind3.css +669 -0
  214. package/styles/tailwind3.scss +2 -0
@@ -0,0 +1,270 @@
1
+ /**
2
+ * ExpressionParser - Parse and compile expressions
3
+ *
4
+ * Converts string expressions into safe, compiled functions
5
+ * Supports field references, operators, functions, and conditionals
6
+ * @private
7
+ */
8
+ var ExpressionParser = /** @class */ (function () {
9
+ function ExpressionParser() {
10
+ this.supportedFunctions = [
11
+ 'SUM', 'AVG', 'MIN', 'MAX', 'COUNT',
12
+ 'ROUND', 'FLOOR', 'CEIL', 'ABS', 'SQRT',
13
+ 'UPPER', 'LOWER', 'CONCAT', 'LENGTH', 'TRIM', 'SUBSTRING',
14
+ 'TODAY', 'AGE', 'DATEFORMAT', 'DATEDIFF', 'ADDDAYS', 'SUBDAYS', 'INCLUDES', 'CONTAINS', 'ISNAN', 'SUPPORTEDVALUESOF', 'TOSTRING', 'DATE', 'GETTIME',
15
+ 'EVERY', 'SOME'
16
+ ];
17
+ this.availableFields = new Map();
18
+ }
19
+ /**
20
+ * Initialize parser with available fields for type validation
21
+ */
22
+ ExpressionParser.prototype.setAvailableFields = function (fields) {
23
+ var _this = this;
24
+ this.availableFields.clear();
25
+ fields.forEach(function (field) {
26
+ _this.availableFields.set(field.name, field);
27
+ });
28
+ };
29
+ ExpressionParser.prototype.validateFieldOperations = function (expression) {
30
+ var errors = [];
31
+ // Skip if no fields available
32
+ if (this.availableFields.size === 0) {
33
+ return errors;
34
+ }
35
+ // Invalid operators for string fields (allow only + for concatenation)
36
+ var stringInvalidOps = ['-', '*', '/', '%', '^'];
37
+ // All operators invalid for date fields
38
+ var dateInvalidOps = ['-', '*', '/', '%', '^', '+'];
39
+ // Track reported operator positions to avoid duplicates
40
+ var reportedOperators = new Set();
41
+ // Extract all field references and their surrounding operators
42
+ var fieldRefPattern = /(\{[^}]+\})/g;
43
+ var match;
44
+ while ((match = fieldRefPattern.exec(expression)) !== null) {
45
+ var fieldRef = match[0];
46
+ var fieldName = fieldRef.slice(1, -1); // Remove { }
47
+ var field = this.availableFields.get(fieldName);
48
+ if (!field)
49
+ continue; // Field not found in available fields, skip validation
50
+ var fieldIndex = match.index;
51
+ var fieldEndIndex = fieldIndex + fieldRef.length;
52
+ // Get context around field reference (including spaces)
53
+ var textBefore = expression.substring(Math.max(0, fieldIndex - 10), fieldIndex);
54
+ var textAfter = expression.substring(fieldEndIndex, Math.min(expression.length, fieldEndIndex + 10));
55
+ // Extract the operator if present (skip spaces)
56
+ var operatorBefore = textBefore.replace(/\s+$/, '').slice(-1);
57
+ var operatorAfter = textAfter.replace(/^\s+/, '').charAt(0);
58
+ // Calculate actual position of operators in the original expression
59
+ var textBeforeTrimmed = textBefore.replace(/\s+$/, '');
60
+ var textAfterTrimmed = textAfter.replace(/^\s+/, '');
61
+ var operatorBeforePos = fieldIndex - (textBefore.length - textBeforeTrimmed.length) - 1;
62
+ var operatorAfterPos = fieldEndIndex + (textAfter.length - textAfterTrimmed.length);
63
+ // For STRING fields: reject all operators except +
64
+ if (field.type === 'string' && !field.format) {
65
+ if (operatorBefore && stringInvalidOps.indexOf(operatorBefore) !== -1) {
66
+ var key = operatorBeforePos + ":" + operatorBefore;
67
+ if (!reportedOperators.has(key)) {
68
+ errors.push("Cannot perform '" + operatorBefore + "' operation on string field '{" + fieldName + "}'");
69
+ reportedOperators.add(key);
70
+ }
71
+ }
72
+ if (operatorAfter && stringInvalidOps.indexOf(operatorAfter) !== -1) {
73
+ var key = operatorAfterPos + ":" + operatorAfter;
74
+ if (!reportedOperators.has(key)) {
75
+ errors.push("Cannot perform '" + operatorAfter + "' operation on string field '{" + fieldName + "}'");
76
+ reportedOperators.add(key);
77
+ }
78
+ }
79
+ }
80
+ // For DATE fields: reject ALL operators including +
81
+ if (field.format === 'date' || field.format === 'date-time' || field.format === 'time') {
82
+ if (operatorBefore && dateInvalidOps.indexOf(operatorBefore) !== -1) {
83
+ var key = operatorBeforePos + ":" + operatorBefore;
84
+ if (!reportedOperators.has(key)) {
85
+ errors.push("Cannot perform '" + operatorBefore + "' operation on date field '{" + fieldName + "}'");
86
+ reportedOperators.add(key);
87
+ }
88
+ }
89
+ if (operatorAfter && dateInvalidOps.indexOf(operatorAfter) !== -1) {
90
+ var key = operatorAfterPos + ":" + operatorAfter;
91
+ if (!reportedOperators.has(key)) {
92
+ errors.push("Cannot perform '" + operatorAfter + "' operation on date field '{" + fieldName + "}'");
93
+ reportedOperators.add(key);
94
+ }
95
+ }
96
+ }
97
+ }
98
+ return errors;
99
+ };
100
+ /**
101
+ * Validate expression syntax
102
+ */
103
+ ExpressionParser.prototype.validate = function (expression) {
104
+ var errors = [];
105
+ if (!expression || expression.trim() === '') {
106
+ return { valid: true, errors: [] };
107
+ }
108
+ // Check for unbalanced braces
109
+ var openBraces = (expression.match(/\{/g) || []).length;
110
+ var closeBraces = (expression.match(/\}/g) || []).length;
111
+ if (openBraces !== closeBraces) {
112
+ errors.push('Unbalanced braces in expression');
113
+ }
114
+ // Check for unbalanced parentheses
115
+ var openParens = (expression.match(/\(/g) || []).length;
116
+ var closeParens = (expression.match(/\)/g) || []).length;
117
+ if (openParens !== closeParens) {
118
+ errors.push('Unbalanced parentheses in expression');
119
+ }
120
+ // Check for invalid function calls
121
+ var funcPattern = /(\w+)\s*\(/g;
122
+ var match;
123
+ while ((match = funcPattern.exec(expression)) !== null) {
124
+ var funcName = match[1].toUpperCase();
125
+ // Only validate uppercase-named functions
126
+ if (funcName === funcName.toUpperCase() && this.supportedFunctions.indexOf(funcName) === -1) {
127
+ errors.push("Unknown function: " + funcName);
128
+ }
129
+ }
130
+ // Validate field operations based on field types
131
+ var fieldOpErrors = this.validateFieldOperations(expression);
132
+ errors.push.apply(errors, fieldOpErrors);
133
+ return {
134
+ valid: errors.length === 0,
135
+ errors: errors
136
+ };
137
+ };
138
+ /**
139
+ * Compile expression to executable function
140
+ */
141
+ ExpressionParser.prototype.compile = function (expression, options) {
142
+ if (options === void 0) { options = {}; }
143
+ try {
144
+ // Set available fields for validation if provided
145
+ if (options.availableFields && Array.isArray(options.availableFields)) {
146
+ this.setAvailableFields(options.availableFields);
147
+ }
148
+ // Validate expression before compiling
149
+ var validation = this.validate(expression);
150
+ if (!validation.valid) {
151
+ return function () { return null; };
152
+ }
153
+ // Replace field references with context lookups
154
+ var compiled_1 = expression;
155
+ // Handle field references FIRST (this includes refs inside ${...})
156
+ compiled_1 = this.compileFieldReferences(compiled_1);
157
+ compiled_1 = options.isCustomValidation ? this.compileInputReferences(compiled_1) : compiled_1;
158
+ // Handle bare function calls SECOND (e.g., SUM([...]) without braces)
159
+ compiled_1 = this.compileBareFunctionCalls(compiled_1);
160
+ // Handle math expressions THIRD (now ${} and {} contain already-replaced refs)
161
+ compiled_1 = this.compileMatrixExpressions(compiled_1);
162
+ return function (context) {
163
+ try {
164
+ // This uses Function constructor with controlled context binding
165
+ // which is safer than eval() but still allows expressions
166
+ // Note: compiled expression already uses context['field'] syntax
167
+ var func = new Function('context', "\n try {\n return " + compiled_1 + ";\n } catch (e) {\n return null;\n }\n ");
168
+ return func(context);
169
+ }
170
+ catch (e) {
171
+ return null;
172
+ }
173
+ };
174
+ }
175
+ catch (error) {
176
+ return function () { return null; };
177
+ }
178
+ };
179
+ // Private helpers
180
+ ExpressionParser.prototype.compileMatrixExpressions = function (expression) {
181
+ var compiled = expression;
182
+ var constants = ['PI', 'TRUE', 'FALSE', 'NULL', 'UNDEFINED', 'Math'];
183
+ var functions = [
184
+ 'SUM', 'AVG', 'MIN', 'MAX', 'COUNT',
185
+ 'ROUND', 'FLOOR', 'CEIL', 'ABS', 'SQRT',
186
+ 'UPPER', 'LOWER', 'CONCAT', 'LENGTH', 'TRIM', 'SUBSTRING',
187
+ 'TODAY', 'AGE', 'DATEFORMAT', 'DATEDIFF', 'ADDDAYS', 'SUBDAYS'
188
+ ];
189
+ // Create fresh regex each time to avoid lastIndex issues with g flag
190
+ var mathExprPattern = /\$?\{([^}]+)\}/g;
191
+ // Process ${...} and {...} blocks: replace bare identifiers with context lookups
192
+ compiled = compiled.replace(mathExprPattern, function (_match, content) {
193
+ var transformed = content;
194
+ // STEP 1: Handle function calls first
195
+ // Match function names followed by ( and prefix with context.
196
+ // Use negative lookbehind to avoid double-replacing (e.g., context.SUM)
197
+ functions.forEach(function (fn) {
198
+ // eslint-disable-next-line security/detect-non-literal-regexp
199
+ var funcCallRegex = new RegExp("(?<!context\\.)\\b" + fn + "\\b(?=\\s*\\()", 'g');
200
+ transformed = transformed.replace(funcCallRegex, "context." + fn);
201
+ });
202
+ constants.forEach(function (constant) {
203
+ // eslint-disable-next-line security/detect-non-literal-regexp
204
+ var constantRegex = new RegExp("\\b" + constant + "\\b", 'g');
205
+ transformed = transformed.replace(constantRegex, "context." + constant);
206
+ });
207
+ // Return as parenthesized expression
208
+ return "(" + transformed + ")";
209
+ });
210
+ return compiled;
211
+ };
212
+ ExpressionParser.prototype.compileBareFunctionCalls = function (expression) {
213
+ var compiled = expression;
214
+ var functions = [
215
+ 'SUM', 'AVG', 'MIN', 'MAX', 'COUNT',
216
+ 'ROUND', 'FLOOR', 'CEIL', 'ABS', 'SQRT',
217
+ 'UPPER', 'LOWER', 'CONCAT', 'LENGTH', 'TRIM', 'SUBSTRING',
218
+ 'TODAY', 'AGE', 'DATEFORMAT', 'DATEDIFF', 'ADDDAYS', 'SUBDAYS'
219
+ ];
220
+ // Handle bare function calls like SUM([...]) that are not inside ${...} or {...}
221
+ // Use negative lookbehind to avoid matching if already preceded by context.
222
+ functions.forEach(function (fn) {
223
+ // eslint-disable-next-line security/detect-non-literal-regexp
224
+ var funcCallRegex = new RegExp("(?<!context\\.)\\b" + fn + "\\b(?=\\s*\\()", 'g');
225
+ compiled = compiled.replace(funcCallRegex, "context." + fn);
226
+ });
227
+ return compiled;
228
+ };
229
+ ExpressionParser.prototype.compileFieldReferences = function (expression) {
230
+ var compiled = expression;
231
+ // Create fresh regex each time to avoid lastIndex issues with g flag
232
+ var fieldRefPattern = /\{([^{}]+)\}/g;
233
+ // Replace {fieldName} with context['fieldName'] or field access
234
+ compiled = compiled.replace(fieldRefPattern, function (match, ref) {
235
+ // Handle escaped braces
236
+ if (ref.startsWith('\\') && ref.endsWith('\\')) {
237
+ return match; // Keep as is
238
+ }
239
+ // Handle nested paths like {customer.name}
240
+ return "context['" + ref.replace(/\./g, '\'].[') + "']";
241
+ });
242
+ return compiled;
243
+ };
244
+ ExpressionParser.prototype.compileInputReferences = function (expression) {
245
+ var compiled = expression;
246
+ // First, protect string literals to avoid replacing 'input' inside strings
247
+ var strings = [];
248
+ var stringProtected = compiled;
249
+ // eslint-disable-next-line security/detect-unsafe-regex
250
+ stringProtected = stringProtected.replace(/(['"`])(?:(?=(\\?))\2.)*?\1/g, function (match) {
251
+ strings.push(match);
252
+ return "__STRING_" + (strings.length - 1) + "__";
253
+ });
254
+ // Case 1: Replace input.property with context['input'].property
255
+ var inputPropertyPattern = /(?<!context\[')\binput\./g;
256
+ stringProtected = stringProtected.replace(inputPropertyPattern, 'context[\'input\'].');
257
+ // Case 2: Replace bare 'input' with context['input']
258
+ // Use negative lookbehind to avoid replacing if already preceded by context.'
259
+ var inputPattern = /(?<!context\[')\binput\b(?!\s*[(\.])/g;
260
+ stringProtected = stringProtected.replace(inputPattern, 'context[\'input\']');
261
+ // Restore string literals
262
+ var result = stringProtected;
263
+ strings.forEach(function (str, idx) {
264
+ result = result.replace("__STRING_" + idx + "__", str);
265
+ });
266
+ return result;
267
+ };
268
+ return ExpressionParser;
269
+ }());
270
+ export { ExpressionParser };
@@ -0,0 +1,24 @@
1
+ import { ExpressionEngine } from './expression-engine';
2
+ /**
3
+ * @private
4
+ */
5
+ export declare class GridExpressions {
6
+ private engine;
7
+ constructor();
8
+ /**
9
+ * Convert a column value to the proper JS type for expression evaluation.
10
+ * Form inputs return strings; numeric/boolean values must be coerced.
11
+ */
12
+ parseColumnValue(value: any, columnType?: string): any;
13
+ /**
14
+ * Evaluate all expression-bearing columns for a single row.
15
+ * Returns a new row object with calculated values merged in.
16
+ */
17
+ evaluateRowExpressions(row: Record<string, any>, columns: any[]): Record<string, any>;
18
+ /**
19
+ * Extract the subset of columns that carry a non-empty `expression`.
20
+ */
21
+ extractCalculatedColumns(columns: any[]): any[];
22
+ getEngine(): ExpressionEngine;
23
+ }
24
+ export default GridExpressions;
@@ -0,0 +1,92 @@
1
+ var __assign = (this && this.__assign) || function () {
2
+ __assign = Object.assign || function(t) {
3
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4
+ s = arguments[i];
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
+ t[p] = s[p];
7
+ }
8
+ return t;
9
+ };
10
+ return __assign.apply(this, arguments);
11
+ };
12
+ import { ExpressionEngine } from './expression-engine';
13
+ /**
14
+ * @private
15
+ */
16
+ var GridExpressions = /** @class */ (function () {
17
+ function GridExpressions() {
18
+ this.engine = new ExpressionEngine();
19
+ }
20
+ /**
21
+ * Convert a column value to the proper JS type for expression evaluation.
22
+ * Form inputs return strings; numeric/boolean values must be coerced.
23
+ */
24
+ GridExpressions.prototype.parseColumnValue = function (value, columnType) {
25
+ // Handle null/undefined/empty
26
+ if (value === null || value === undefined || value === '') {
27
+ return value;
28
+ }
29
+ // Parse number types
30
+ if (columnType === 'number') {
31
+ var parsed = parseFloat(String(value));
32
+ return isNaN(parsed) ? 0 : parsed;
33
+ }
34
+ // Parse boolean types
35
+ if (columnType === 'boolean') {
36
+ if (typeof value === 'boolean') {
37
+ return value;
38
+ }
39
+ return value === 'true' || value === '1' || value === 1 || value === true;
40
+ }
41
+ // Return as-is for string and other types
42
+ return value;
43
+ };
44
+ /**
45
+ * Evaluate all expression-bearing columns for a single row.
46
+ * Returns a new row object with calculated values merged in.
47
+ */
48
+ GridExpressions.prototype.evaluateRowExpressions = function (row, columns) {
49
+ var _this = this;
50
+ var calculatedRow = __assign({}, row);
51
+ // Find all columns with expressions
52
+ var calculatedColumns = columns.filter(function (col) { return col.expression && col.expression.toString().trim(); });
53
+ var _loop_1 = function (column) {
54
+ if (!column.expression) {
55
+ return "continue";
56
+ }
57
+ try {
58
+ // Prepare row values with proper type conversion
59
+ var typedRow_1 = {};
60
+ columns.forEach(function (col) {
61
+ var value = calculatedRow[col.field];
62
+ typedRow_1[col.field] = _this.parseColumnValue(value, col.type);
63
+ });
64
+ // Evaluate expression with current row as context
65
+ var result = this_1.engine.evaluate(column.expression, typedRow_1, {
66
+ throwOnError: false
67
+ });
68
+ // Update row with calculated value
69
+ calculatedRow[column.field] = result;
70
+ }
71
+ catch (error) {
72
+ calculatedRow[column.field] = null;
73
+ }
74
+ };
75
+ var this_1 = this;
76
+ for (var _i = 0, calculatedColumns_1 = calculatedColumns; _i < calculatedColumns_1.length; _i++) {
77
+ var column = calculatedColumns_1[_i];
78
+ _loop_1(column);
79
+ }
80
+ return calculatedRow;
81
+ };
82
+ /**
83
+ * Extract the subset of columns that carry a non-empty `expression`.
84
+ */
85
+ GridExpressions.prototype.extractCalculatedColumns = function (columns) {
86
+ return columns.filter(function (col) { return col.expression && col.expression.toString().trim(); });
87
+ };
88
+ GridExpressions.prototype.getEngine = function () { return this.engine; };
89
+ return GridExpressions;
90
+ }());
91
+ export { GridExpressions };
92
+ export default GridExpressions;
@@ -0,0 +1,4 @@
1
+ export * from './dependency-tracker';
2
+ export * from './expression-engine';
3
+ export * from './expression-parser';
4
+ export * from './grid-expressions';
@@ -0,0 +1,4 @@
1
+ export * from './dependency-tracker';
2
+ export * from './expression-engine';
3
+ export * from './expression-parser';
4
+ export * from './grid-expressions';
@@ -0,0 +1,10 @@
1
+ export * from './checkbox-group';
2
+ export * from './conditional-rule-engine';
3
+ export * from './custom-validation-engine';
4
+ export * from './datagrid-component';
5
+ export * from './json-converter';
6
+ export * from './minmax-rule-engine';
7
+ export * from './option-fetcher';
8
+ export * from './parser';
9
+ export * from './static-html-renderer';
10
+ export * from './utils';
@@ -0,0 +1,10 @@
1
+ export * from './checkbox-group';
2
+ export * from './conditional-rule-engine';
3
+ export * from './custom-validation-engine';
4
+ export * from './datagrid-component';
5
+ export * from './json-converter';
6
+ export * from './minmax-rule-engine';
7
+ export * from './option-fetcher';
8
+ export * from './parser';
9
+ export * from './static-html-renderer';
10
+ export * from './utils';