@stackone/expressions 0.14.0 → 0.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +11 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +274 -1
- package/dist/index.mjs +248 -0
- package/package.json +18 -3
- package/dist/index.es.mjs +0 -1
- package/dist/types/constants.d.ts +0 -1
- package/dist/types/evaluate.d.ts +0 -5
- package/dist/types/factory.d.ts +0 -39
- package/dist/types/index.d.ts +0 -3
- package/dist/types/types.d.ts +0 -8
- package/dist/types/utils.d.ts +0 -16
- package/dist/types/validate.d.ts +0 -1
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
//#region src/evaluate.d.ts
|
|
2
|
+
declare const evaluateExpression: (expression?: string | null, context?: unknown, options?: {
|
|
3
|
+
incrementalJsonPath?: boolean;
|
|
4
|
+
}) => unknown;
|
|
5
|
+
declare const safeEvaluateExpression: (expression?: string | null, context?: unknown) => unknown;
|
|
6
|
+
declare const safeEvaluateRecord: (record: Record<string, unknown>, context?: unknown) => Record<string, unknown>;
|
|
7
|
+
//#endregion
|
|
8
|
+
//#region src/validate.d.ts
|
|
9
|
+
declare const isValidExpression: (expression?: string | null) => boolean;
|
|
10
|
+
//#endregion
|
|
11
|
+
export { evaluateExpression as evaluate, isValidExpression, safeEvaluateExpression as safeEvaluate, safeEvaluateRecord };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
//#region src/evaluate.d.ts
|
|
2
|
+
declare const evaluateExpression: (expression?: string | null, context?: unknown, options?: {
|
|
3
|
+
incrementalJsonPath?: boolean;
|
|
4
|
+
}) => unknown;
|
|
5
|
+
declare const safeEvaluateExpression: (expression?: string | null, context?: unknown) => unknown;
|
|
6
|
+
declare const safeEvaluateRecord: (record: Record<string, unknown>, context?: unknown) => Record<string, unknown>;
|
|
7
|
+
//#endregion
|
|
8
|
+
//#region src/validate.d.ts
|
|
9
|
+
declare const isValidExpression: (expression?: string | null) => boolean;
|
|
10
|
+
//#endregion
|
|
11
|
+
export { evaluateExpression as evaluate, isValidExpression, safeEvaluateExpression as safeEvaluate, safeEvaluateRecord };
|
package/dist/index.js
CHANGED
|
@@ -1 +1,274 @@
|
|
|
1
|
-
|
|
1
|
+
//#region rolldown:runtime
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __copyProps = (to, from, except, desc) => {
|
|
9
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
10
|
+
key = keys[i];
|
|
11
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
12
|
+
get: ((k) => from[k]).bind(null, key),
|
|
13
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
19
|
+
value: mod,
|
|
20
|
+
enumerable: true
|
|
21
|
+
}) : target, mod));
|
|
22
|
+
|
|
23
|
+
//#endregion
|
|
24
|
+
const __stackone_utils = __toESM(require("@stackone/utils"));
|
|
25
|
+
const jexl = __toESM(require("jexl"));
|
|
26
|
+
const jsonpath_plus = __toESM(require("jsonpath-plus"));
|
|
27
|
+
const lodash_get = __toESM(require("lodash.get"));
|
|
28
|
+
|
|
29
|
+
//#region src/factory.ts
|
|
30
|
+
const createExpressionHandler = (instanceBuilder = () => new jexl.Jexl()) => {
|
|
31
|
+
const expressionHandler = instanceBuilder();
|
|
32
|
+
expressionHandler.addFunction("nextAnniversary", (initialDate, format) => (0, __stackone_utils.calculateNextAnniversary)({
|
|
33
|
+
initialDate,
|
|
34
|
+
format
|
|
35
|
+
}));
|
|
36
|
+
expressionHandler.addFunction("yearsElapsed", (startDate, format, endDate) => (0, __stackone_utils.calculateYearsElapsed)({
|
|
37
|
+
startDate,
|
|
38
|
+
endDate,
|
|
39
|
+
format
|
|
40
|
+
}));
|
|
41
|
+
expressionHandler.addFunction("hasPassed", (date, format, yearsToAdd) => (0, __stackone_utils.dateHasPassed)({
|
|
42
|
+
date,
|
|
43
|
+
yearsToAdd,
|
|
44
|
+
format
|
|
45
|
+
}));
|
|
46
|
+
expressionHandler.addFunction("now", () => (/* @__PURE__ */ new Date()).toISOString());
|
|
47
|
+
expressionHandler.addFunction("includes", (array, value) => {
|
|
48
|
+
if ((0, __stackone_utils.isMissing)(array) || !Array.isArray(array) || array.length === 0 || (0, __stackone_utils.isMissing)(value)) return false;
|
|
49
|
+
if (Array.isArray(value)) return value.every((val) => array.includes(val));
|
|
50
|
+
return array.includes(value);
|
|
51
|
+
});
|
|
52
|
+
expressionHandler.addFunction("includesSome", (array, value) => {
|
|
53
|
+
if ((0, __stackone_utils.isMissing)(array) || !Array.isArray(array) || array.length === 0 || (0, __stackone_utils.isMissing)(value)) return false;
|
|
54
|
+
if (Array.isArray(value)) return value.some((val) => array.includes(val));
|
|
55
|
+
return array.includes(value);
|
|
56
|
+
});
|
|
57
|
+
expressionHandler.addFunction("present", (value) => (0, __stackone_utils.notMissing)(value));
|
|
58
|
+
expressionHandler.addFunction("missing", (value) => (0, __stackone_utils.isMissing)(value));
|
|
59
|
+
expressionHandler.addFunction("keys", (value) => {
|
|
60
|
+
if ((0, __stackone_utils.isMissing)(value)) return [];
|
|
61
|
+
else if (typeof value === "object" && !Array.isArray(value)) return Object.keys(value);
|
|
62
|
+
else return [];
|
|
63
|
+
});
|
|
64
|
+
expressionHandler.addFunction("values", (value) => {
|
|
65
|
+
if ((0, __stackone_utils.isMissing)(value)) return [];
|
|
66
|
+
else if (typeof value === "object" && !Array.isArray(value)) return Object.values(value);
|
|
67
|
+
else return [];
|
|
68
|
+
});
|
|
69
|
+
expressionHandler.addBinaryOp("??", 0, (left, right) => {
|
|
70
|
+
if ((0, __stackone_utils.isMissing)(left)) return right;
|
|
71
|
+
else if ((0, __stackone_utils.isMissing)(right)) return left;
|
|
72
|
+
else return left ?? right;
|
|
73
|
+
});
|
|
74
|
+
return expressionHandler;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
//#endregion
|
|
78
|
+
//#region src/constants.ts
|
|
79
|
+
const INTERPOLATED_EXPRESSION_REGEX = /\${([^}]+)}/g;
|
|
80
|
+
|
|
81
|
+
//#endregion
|
|
82
|
+
//#region src/utils.ts
|
|
83
|
+
const cleanExpression = (expression) => {
|
|
84
|
+
return expression.replace(/\$\./g, "").trim();
|
|
85
|
+
};
|
|
86
|
+
const compileExpression = (expressionHandler, expression) => {
|
|
87
|
+
try {
|
|
88
|
+
const compiledExpression = expressionHandler.compile(expression);
|
|
89
|
+
return compiledExpression;
|
|
90
|
+
} catch {
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
const extractExpressionBetweenDoubleCurlyBraces = (expression) => {
|
|
95
|
+
if (expression.startsWith("{{") && expression.endsWith("}}")) return expression.slice(2, -2);
|
|
96
|
+
};
|
|
97
|
+
const evaluateJsonPath = (expression, context) => {
|
|
98
|
+
try {
|
|
99
|
+
if (!expression.startsWith("$")) throw new Error(`JSONPath expression must start with '$': ${expression}`);
|
|
100
|
+
if (expression.includes("$_") || expression.match(/\$[^.[]/g) || expression.includes("[") && !expression.includes("]") || expression.includes(" ") && !expression.includes("[")) throw new Error(`Invalid JSONPath expression: ${expression}`);
|
|
101
|
+
const result = (0, jsonpath_plus.JSONPath)({
|
|
102
|
+
path: expression,
|
|
103
|
+
json: context
|
|
104
|
+
});
|
|
105
|
+
if (result.length === 0) return void 0;
|
|
106
|
+
if (result.length === 1) return result[0];
|
|
107
|
+
return result;
|
|
108
|
+
} catch {
|
|
109
|
+
throw new Error(`Invalid JSONPath expression: ${expression}`);
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
const replaceInterpolation = (expression, toReplace, value) => expression.replace(toReplace, String(value));
|
|
113
|
+
const handleSingleInterpolation = (interpolation, expressionHandler, context, currentExpression) => {
|
|
114
|
+
const path = interpolation.path.trim();
|
|
115
|
+
if (!path) return currentExpression;
|
|
116
|
+
try {
|
|
117
|
+
const compiledExpression = compileExpression(expressionHandler, path);
|
|
118
|
+
if (compiledExpression) {
|
|
119
|
+
const value = compiledExpression.evalSync(context);
|
|
120
|
+
if (value !== void 0) return replaceInterpolation(currentExpression, interpolation.toReplace, value);
|
|
121
|
+
}
|
|
122
|
+
const pathValue = (0, lodash_get.default)(context, path);
|
|
123
|
+
return (0, __stackone_utils.notMissing)(pathValue) ? replaceInterpolation(currentExpression, interpolation.toReplace, pathValue) : currentExpression;
|
|
124
|
+
} catch {
|
|
125
|
+
return currentExpression;
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
const evaluateStringInterpolations = (expression, context, expressionHandler) => {
|
|
129
|
+
const matches = expression.match(INTERPOLATED_EXPRESSION_REGEX);
|
|
130
|
+
if (!matches) return void 0;
|
|
131
|
+
const len = matches.length;
|
|
132
|
+
const interpolations = new Array(len);
|
|
133
|
+
for (let i = 0; i < len; i++) interpolations[i] = {
|
|
134
|
+
toReplace: matches[i],
|
|
135
|
+
path: matches[i].slice(2, -1)
|
|
136
|
+
};
|
|
137
|
+
return interpolations.reduce((acc, interpolation) => handleSingleInterpolation(interpolation, expressionHandler, context, acc), String(expression));
|
|
138
|
+
};
|
|
139
|
+
const handleSegmentPathError = (err, parentVal, segment, parentPath) => {
|
|
140
|
+
if (Array.isArray(parentVal)) {
|
|
141
|
+
const parsedIndex = parseInt(segment, 10);
|
|
142
|
+
if (!isNaN(parsedIndex) && (parsedIndex < 0 || parsedIndex >= parentVal.length)) return {
|
|
143
|
+
value: void 0,
|
|
144
|
+
error: `Invalid array index '${segment}' at '${parentPath}'`,
|
|
145
|
+
availableKeys: parentVal.map((_, idx) => idx.toString())
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
if ((0, __stackone_utils.isObject)(parentVal)) return {
|
|
149
|
+
value: void 0,
|
|
150
|
+
error: `Key '${segment}' not found at '${parentPath}'`,
|
|
151
|
+
availableKeys: Object.keys(parentVal)
|
|
152
|
+
};
|
|
153
|
+
return {
|
|
154
|
+
value: void 0,
|
|
155
|
+
error: `${err} at '${parentPath}'`,
|
|
156
|
+
availableKeys: []
|
|
157
|
+
};
|
|
158
|
+
};
|
|
159
|
+
const handleJsonPathSegments = (segments, ctx) => {
|
|
160
|
+
if (segments[0] !== "$") return {
|
|
161
|
+
value: void 0,
|
|
162
|
+
error: "JSON path must start with $"
|
|
163
|
+
};
|
|
164
|
+
let currentValue = ctx;
|
|
165
|
+
let currentPath = "$";
|
|
166
|
+
for (let i = 1; i < segments.length; i++) {
|
|
167
|
+
const segment = segments[i];
|
|
168
|
+
const nextPath = segment.startsWith("[") ? `${currentPath}${segment}` : `${currentPath}.${segment}`;
|
|
169
|
+
if (Array.isArray(currentValue)) {
|
|
170
|
+
const idx = parseInt(segment, 10);
|
|
171
|
+
if (isNaN(idx) || idx < 0 || idx >= currentValue.length) return handleSegmentPathError("Invalid array index", currentValue, segment, currentPath);
|
|
172
|
+
currentValue = currentValue[idx];
|
|
173
|
+
currentPath = nextPath;
|
|
174
|
+
} else if ((0, __stackone_utils.isObject)(currentValue)) {
|
|
175
|
+
if (!Object.prototype.hasOwnProperty.call(currentValue, segment)) return handleSegmentPathError("Key not found", currentValue, segment, currentPath);
|
|
176
|
+
currentValue = currentValue[segment];
|
|
177
|
+
currentPath = nextPath;
|
|
178
|
+
} else return {
|
|
179
|
+
value: void 0,
|
|
180
|
+
error: `Cannot access '${segment}' at '${currentPath}' - parent is not an object`,
|
|
181
|
+
availableKeys: []
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
return { value: currentValue };
|
|
185
|
+
};
|
|
186
|
+
const evaluateJsonPathIncremental = (path, context) => {
|
|
187
|
+
const SPECIAL_JSONPATH_REGEX = /(\.\.)|(\[\*\])|(\[\?\()|(\[\d+:\d+\])/;
|
|
188
|
+
try {
|
|
189
|
+
if (SPECIAL_JSONPATH_REGEX.test(path)) {
|
|
190
|
+
const result = evaluateJsonPath(path, context);
|
|
191
|
+
if (result === void 0) return {
|
|
192
|
+
value: void 0,
|
|
193
|
+
error: `Invalid or empty JSONPath: '${path}'`
|
|
194
|
+
};
|
|
195
|
+
return { value: result };
|
|
196
|
+
}
|
|
197
|
+
const segments = path.match(/\$|(?:\['([^']+)'\])|(?:\["([^"]+)"\])|\[\d+\]|[^[\].]+/g) || [];
|
|
198
|
+
const cleanedSegments = segments.map((seg) => seg.replace(/^\['([^']+)'\]$/, "$1").replace(/^\["([^"]+)"\]$/, "$1").replace(/^\[(\d+)\]$/, "$1"));
|
|
199
|
+
return handleJsonPathSegments(cleanedSegments, context);
|
|
200
|
+
} catch (error) {
|
|
201
|
+
return {
|
|
202
|
+
value: void 0,
|
|
203
|
+
error: `Something went wrong with evaluation of JSON path: ${String(error)}`
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
//#endregion
|
|
209
|
+
//#region src/evaluate.ts
|
|
210
|
+
const handleIncrementalJsonPath = (expr, ctx) => {
|
|
211
|
+
const result = evaluateJsonPathIncremental(expr, ctx);
|
|
212
|
+
if (result.error) throw new Error(`${result.error}${result.availableKeys?.length ? `. Available keys: ${result.availableKeys.join(", ")}` : ""}`);
|
|
213
|
+
return result.value;
|
|
214
|
+
};
|
|
215
|
+
const handleNormalJsonPath = (expr, ctx) => {
|
|
216
|
+
try {
|
|
217
|
+
return evaluateJsonPath(expr, ctx);
|
|
218
|
+
} catch {
|
|
219
|
+
throw new Error(`Invalid JSON path: "${expr}"`);
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
const evaluateExpression = (expression, context, options) => {
|
|
223
|
+
const trimmedExpression = expression?.trim();
|
|
224
|
+
if (trimmedExpression === null || trimmedExpression === void 0 || trimmedExpression === "") throw new Error("Empty expression");
|
|
225
|
+
const expressionContext = (0, __stackone_utils.isObject)(context) ? context : {};
|
|
226
|
+
const expressionHandler = createExpressionHandler();
|
|
227
|
+
const expressionBetweenDoubleCurlyBraces = extractExpressionBetweenDoubleCurlyBraces(trimmedExpression);
|
|
228
|
+
const extractedExpression = expressionBetweenDoubleCurlyBraces ?? trimmedExpression;
|
|
229
|
+
const cleanedExpression = cleanExpression(extractedExpression);
|
|
230
|
+
const interpolatedExpression = evaluateStringInterpolations(cleanedExpression, expressionContext, expressionHandler);
|
|
231
|
+
if (interpolatedExpression) return interpolatedExpression;
|
|
232
|
+
if (!expressionBetweenDoubleCurlyBraces && trimmedExpression.startsWith("$")) return options?.incrementalJsonPath ? handleIncrementalJsonPath(trimmedExpression, expressionContext) : handleNormalJsonPath(trimmedExpression, expressionContext);
|
|
233
|
+
if (!interpolatedExpression && !expressionBetweenDoubleCurlyBraces) return expression;
|
|
234
|
+
const compiledExpression = compileExpression(expressionHandler, cleanedExpression);
|
|
235
|
+
if (!compiledExpression || cleanedExpression === ".") throw new Error(`Invalid expression: "${trimmedExpression}"`);
|
|
236
|
+
try {
|
|
237
|
+
return compiledExpression.evalSync(expressionContext);
|
|
238
|
+
} catch {
|
|
239
|
+
return void 0;
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
const safeEvaluateExpression = (expression, context) => {
|
|
243
|
+
try {
|
|
244
|
+
return evaluateExpression(expression, context);
|
|
245
|
+
} catch {
|
|
246
|
+
return null;
|
|
247
|
+
}
|
|
248
|
+
};
|
|
249
|
+
const safeEvaluateRecord = (record, context) => {
|
|
250
|
+
const evaluateValue = (value) => {
|
|
251
|
+
if (Array.isArray(value)) return value.map(evaluateValue);
|
|
252
|
+
else if (typeof value === "object" && value !== null) return safeEvaluateRecord(value, context);
|
|
253
|
+
else if (typeof value === "string") return safeEvaluateExpression(value, context);
|
|
254
|
+
return value;
|
|
255
|
+
};
|
|
256
|
+
return Object.fromEntries(Object.entries(record).map(([key, value]) => [key, evaluateValue(value)]));
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
//#endregion
|
|
260
|
+
//#region src/validate.ts
|
|
261
|
+
const isValidExpression = (expression) => {
|
|
262
|
+
try {
|
|
263
|
+
evaluateExpression(expression);
|
|
264
|
+
return true;
|
|
265
|
+
} catch {
|
|
266
|
+
return false;
|
|
267
|
+
}
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
//#endregion
|
|
271
|
+
exports.evaluate = evaluateExpression;
|
|
272
|
+
exports.isValidExpression = isValidExpression;
|
|
273
|
+
exports.safeEvaluate = safeEvaluateExpression;
|
|
274
|
+
exports.safeEvaluateRecord = safeEvaluateRecord;
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
import { calculateNextAnniversary, calculateYearsElapsed, dateHasPassed, isMissing, isObject, notMissing } from "@stackone/utils";
|
|
2
|
+
import * as jexl from "jexl";
|
|
3
|
+
import { JSONPath } from "jsonpath-plus";
|
|
4
|
+
import get from "lodash.get";
|
|
5
|
+
|
|
6
|
+
//#region src/factory.ts
|
|
7
|
+
const createExpressionHandler = (instanceBuilder = () => new jexl.Jexl()) => {
|
|
8
|
+
const expressionHandler = instanceBuilder();
|
|
9
|
+
expressionHandler.addFunction("nextAnniversary", (initialDate, format) => calculateNextAnniversary({
|
|
10
|
+
initialDate,
|
|
11
|
+
format
|
|
12
|
+
}));
|
|
13
|
+
expressionHandler.addFunction("yearsElapsed", (startDate, format, endDate) => calculateYearsElapsed({
|
|
14
|
+
startDate,
|
|
15
|
+
endDate,
|
|
16
|
+
format
|
|
17
|
+
}));
|
|
18
|
+
expressionHandler.addFunction("hasPassed", (date, format, yearsToAdd) => dateHasPassed({
|
|
19
|
+
date,
|
|
20
|
+
yearsToAdd,
|
|
21
|
+
format
|
|
22
|
+
}));
|
|
23
|
+
expressionHandler.addFunction("now", () => (/* @__PURE__ */ new Date()).toISOString());
|
|
24
|
+
expressionHandler.addFunction("includes", (array, value) => {
|
|
25
|
+
if (isMissing(array) || !Array.isArray(array) || array.length === 0 || isMissing(value)) return false;
|
|
26
|
+
if (Array.isArray(value)) return value.every((val) => array.includes(val));
|
|
27
|
+
return array.includes(value);
|
|
28
|
+
});
|
|
29
|
+
expressionHandler.addFunction("includesSome", (array, value) => {
|
|
30
|
+
if (isMissing(array) || !Array.isArray(array) || array.length === 0 || isMissing(value)) return false;
|
|
31
|
+
if (Array.isArray(value)) return value.some((val) => array.includes(val));
|
|
32
|
+
return array.includes(value);
|
|
33
|
+
});
|
|
34
|
+
expressionHandler.addFunction("present", (value) => notMissing(value));
|
|
35
|
+
expressionHandler.addFunction("missing", (value) => isMissing(value));
|
|
36
|
+
expressionHandler.addFunction("keys", (value) => {
|
|
37
|
+
if (isMissing(value)) return [];
|
|
38
|
+
else if (typeof value === "object" && !Array.isArray(value)) return Object.keys(value);
|
|
39
|
+
else return [];
|
|
40
|
+
});
|
|
41
|
+
expressionHandler.addFunction("values", (value) => {
|
|
42
|
+
if (isMissing(value)) return [];
|
|
43
|
+
else if (typeof value === "object" && !Array.isArray(value)) return Object.values(value);
|
|
44
|
+
else return [];
|
|
45
|
+
});
|
|
46
|
+
expressionHandler.addBinaryOp("??", 0, (left, right) => {
|
|
47
|
+
if (isMissing(left)) return right;
|
|
48
|
+
else if (isMissing(right)) return left;
|
|
49
|
+
else return left ?? right;
|
|
50
|
+
});
|
|
51
|
+
return expressionHandler;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
//#endregion
|
|
55
|
+
//#region src/constants.ts
|
|
56
|
+
const INTERPOLATED_EXPRESSION_REGEX = /\${([^}]+)}/g;
|
|
57
|
+
|
|
58
|
+
//#endregion
|
|
59
|
+
//#region src/utils.ts
|
|
60
|
+
const cleanExpression = (expression) => {
|
|
61
|
+
return expression.replace(/\$\./g, "").trim();
|
|
62
|
+
};
|
|
63
|
+
const compileExpression = (expressionHandler, expression) => {
|
|
64
|
+
try {
|
|
65
|
+
const compiledExpression = expressionHandler.compile(expression);
|
|
66
|
+
return compiledExpression;
|
|
67
|
+
} catch {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
const extractExpressionBetweenDoubleCurlyBraces = (expression) => {
|
|
72
|
+
if (expression.startsWith("{{") && expression.endsWith("}}")) return expression.slice(2, -2);
|
|
73
|
+
};
|
|
74
|
+
const evaluateJsonPath = (expression, context) => {
|
|
75
|
+
try {
|
|
76
|
+
if (!expression.startsWith("$")) throw new Error(`JSONPath expression must start with '$': ${expression}`);
|
|
77
|
+
if (expression.includes("$_") || expression.match(/\$[^.[]/g) || expression.includes("[") && !expression.includes("]") || expression.includes(" ") && !expression.includes("[")) throw new Error(`Invalid JSONPath expression: ${expression}`);
|
|
78
|
+
const result = JSONPath({
|
|
79
|
+
path: expression,
|
|
80
|
+
json: context
|
|
81
|
+
});
|
|
82
|
+
if (result.length === 0) return void 0;
|
|
83
|
+
if (result.length === 1) return result[0];
|
|
84
|
+
return result;
|
|
85
|
+
} catch {
|
|
86
|
+
throw new Error(`Invalid JSONPath expression: ${expression}`);
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
const replaceInterpolation = (expression, toReplace, value) => expression.replace(toReplace, String(value));
|
|
90
|
+
const handleSingleInterpolation = (interpolation, expressionHandler, context, currentExpression) => {
|
|
91
|
+
const path = interpolation.path.trim();
|
|
92
|
+
if (!path) return currentExpression;
|
|
93
|
+
try {
|
|
94
|
+
const compiledExpression = compileExpression(expressionHandler, path);
|
|
95
|
+
if (compiledExpression) {
|
|
96
|
+
const value = compiledExpression.evalSync(context);
|
|
97
|
+
if (value !== void 0) return replaceInterpolation(currentExpression, interpolation.toReplace, value);
|
|
98
|
+
}
|
|
99
|
+
const pathValue = get(context, path);
|
|
100
|
+
return notMissing(pathValue) ? replaceInterpolation(currentExpression, interpolation.toReplace, pathValue) : currentExpression;
|
|
101
|
+
} catch {
|
|
102
|
+
return currentExpression;
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
const evaluateStringInterpolations = (expression, context, expressionHandler) => {
|
|
106
|
+
const matches = expression.match(INTERPOLATED_EXPRESSION_REGEX);
|
|
107
|
+
if (!matches) return void 0;
|
|
108
|
+
const len = matches.length;
|
|
109
|
+
const interpolations = new Array(len);
|
|
110
|
+
for (let i = 0; i < len; i++) interpolations[i] = {
|
|
111
|
+
toReplace: matches[i],
|
|
112
|
+
path: matches[i].slice(2, -1)
|
|
113
|
+
};
|
|
114
|
+
return interpolations.reduce((acc, interpolation) => handleSingleInterpolation(interpolation, expressionHandler, context, acc), String(expression));
|
|
115
|
+
};
|
|
116
|
+
const handleSegmentPathError = (err, parentVal, segment, parentPath) => {
|
|
117
|
+
if (Array.isArray(parentVal)) {
|
|
118
|
+
const parsedIndex = parseInt(segment, 10);
|
|
119
|
+
if (!isNaN(parsedIndex) && (parsedIndex < 0 || parsedIndex >= parentVal.length)) return {
|
|
120
|
+
value: void 0,
|
|
121
|
+
error: `Invalid array index '${segment}' at '${parentPath}'`,
|
|
122
|
+
availableKeys: parentVal.map((_, idx) => idx.toString())
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
if (isObject(parentVal)) return {
|
|
126
|
+
value: void 0,
|
|
127
|
+
error: `Key '${segment}' not found at '${parentPath}'`,
|
|
128
|
+
availableKeys: Object.keys(parentVal)
|
|
129
|
+
};
|
|
130
|
+
return {
|
|
131
|
+
value: void 0,
|
|
132
|
+
error: `${err} at '${parentPath}'`,
|
|
133
|
+
availableKeys: []
|
|
134
|
+
};
|
|
135
|
+
};
|
|
136
|
+
const handleJsonPathSegments = (segments, ctx) => {
|
|
137
|
+
if (segments[0] !== "$") return {
|
|
138
|
+
value: void 0,
|
|
139
|
+
error: "JSON path must start with $"
|
|
140
|
+
};
|
|
141
|
+
let currentValue = ctx;
|
|
142
|
+
let currentPath = "$";
|
|
143
|
+
for (let i = 1; i < segments.length; i++) {
|
|
144
|
+
const segment = segments[i];
|
|
145
|
+
const nextPath = segment.startsWith("[") ? `${currentPath}${segment}` : `${currentPath}.${segment}`;
|
|
146
|
+
if (Array.isArray(currentValue)) {
|
|
147
|
+
const idx = parseInt(segment, 10);
|
|
148
|
+
if (isNaN(idx) || idx < 0 || idx >= currentValue.length) return handleSegmentPathError("Invalid array index", currentValue, segment, currentPath);
|
|
149
|
+
currentValue = currentValue[idx];
|
|
150
|
+
currentPath = nextPath;
|
|
151
|
+
} else if (isObject(currentValue)) {
|
|
152
|
+
if (!Object.prototype.hasOwnProperty.call(currentValue, segment)) return handleSegmentPathError("Key not found", currentValue, segment, currentPath);
|
|
153
|
+
currentValue = currentValue[segment];
|
|
154
|
+
currentPath = nextPath;
|
|
155
|
+
} else return {
|
|
156
|
+
value: void 0,
|
|
157
|
+
error: `Cannot access '${segment}' at '${currentPath}' - parent is not an object`,
|
|
158
|
+
availableKeys: []
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
return { value: currentValue };
|
|
162
|
+
};
|
|
163
|
+
const evaluateJsonPathIncremental = (path, context) => {
|
|
164
|
+
const SPECIAL_JSONPATH_REGEX = /(\.\.)|(\[\*\])|(\[\?\()|(\[\d+:\d+\])/;
|
|
165
|
+
try {
|
|
166
|
+
if (SPECIAL_JSONPATH_REGEX.test(path)) {
|
|
167
|
+
const result = evaluateJsonPath(path, context);
|
|
168
|
+
if (result === void 0) return {
|
|
169
|
+
value: void 0,
|
|
170
|
+
error: `Invalid or empty JSONPath: '${path}'`
|
|
171
|
+
};
|
|
172
|
+
return { value: result };
|
|
173
|
+
}
|
|
174
|
+
const segments = path.match(/\$|(?:\['([^']+)'\])|(?:\["([^"]+)"\])|\[\d+\]|[^[\].]+/g) || [];
|
|
175
|
+
const cleanedSegments = segments.map((seg) => seg.replace(/^\['([^']+)'\]$/, "$1").replace(/^\["([^"]+)"\]$/, "$1").replace(/^\[(\d+)\]$/, "$1"));
|
|
176
|
+
return handleJsonPathSegments(cleanedSegments, context);
|
|
177
|
+
} catch (error) {
|
|
178
|
+
return {
|
|
179
|
+
value: void 0,
|
|
180
|
+
error: `Something went wrong with evaluation of JSON path: ${String(error)}`
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
//#endregion
|
|
186
|
+
//#region src/evaluate.ts
|
|
187
|
+
const handleIncrementalJsonPath = (expr, ctx) => {
|
|
188
|
+
const result = evaluateJsonPathIncremental(expr, ctx);
|
|
189
|
+
if (result.error) throw new Error(`${result.error}${result.availableKeys?.length ? `. Available keys: ${result.availableKeys.join(", ")}` : ""}`);
|
|
190
|
+
return result.value;
|
|
191
|
+
};
|
|
192
|
+
const handleNormalJsonPath = (expr, ctx) => {
|
|
193
|
+
try {
|
|
194
|
+
return evaluateJsonPath(expr, ctx);
|
|
195
|
+
} catch {
|
|
196
|
+
throw new Error(`Invalid JSON path: "${expr}"`);
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
const evaluateExpression = (expression, context, options) => {
|
|
200
|
+
const trimmedExpression = expression?.trim();
|
|
201
|
+
if (trimmedExpression === null || trimmedExpression === void 0 || trimmedExpression === "") throw new Error("Empty expression");
|
|
202
|
+
const expressionContext = isObject(context) ? context : {};
|
|
203
|
+
const expressionHandler = createExpressionHandler();
|
|
204
|
+
const expressionBetweenDoubleCurlyBraces = extractExpressionBetweenDoubleCurlyBraces(trimmedExpression);
|
|
205
|
+
const extractedExpression = expressionBetweenDoubleCurlyBraces ?? trimmedExpression;
|
|
206
|
+
const cleanedExpression = cleanExpression(extractedExpression);
|
|
207
|
+
const interpolatedExpression = evaluateStringInterpolations(cleanedExpression, expressionContext, expressionHandler);
|
|
208
|
+
if (interpolatedExpression) return interpolatedExpression;
|
|
209
|
+
if (!expressionBetweenDoubleCurlyBraces && trimmedExpression.startsWith("$")) return options?.incrementalJsonPath ? handleIncrementalJsonPath(trimmedExpression, expressionContext) : handleNormalJsonPath(trimmedExpression, expressionContext);
|
|
210
|
+
if (!interpolatedExpression && !expressionBetweenDoubleCurlyBraces) return expression;
|
|
211
|
+
const compiledExpression = compileExpression(expressionHandler, cleanedExpression);
|
|
212
|
+
if (!compiledExpression || cleanedExpression === ".") throw new Error(`Invalid expression: "${trimmedExpression}"`);
|
|
213
|
+
try {
|
|
214
|
+
return compiledExpression.evalSync(expressionContext);
|
|
215
|
+
} catch {
|
|
216
|
+
return void 0;
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
const safeEvaluateExpression = (expression, context) => {
|
|
220
|
+
try {
|
|
221
|
+
return evaluateExpression(expression, context);
|
|
222
|
+
} catch {
|
|
223
|
+
return null;
|
|
224
|
+
}
|
|
225
|
+
};
|
|
226
|
+
const safeEvaluateRecord = (record, context) => {
|
|
227
|
+
const evaluateValue = (value) => {
|
|
228
|
+
if (Array.isArray(value)) return value.map(evaluateValue);
|
|
229
|
+
else if (typeof value === "object" && value !== null) return safeEvaluateRecord(value, context);
|
|
230
|
+
else if (typeof value === "string") return safeEvaluateExpression(value, context);
|
|
231
|
+
return value;
|
|
232
|
+
};
|
|
233
|
+
return Object.fromEntries(Object.entries(record).map(([key, value]) => [key, evaluateValue(value)]));
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
//#endregion
|
|
237
|
+
//#region src/validate.ts
|
|
238
|
+
const isValidExpression = (expression) => {
|
|
239
|
+
try {
|
|
240
|
+
evaluateExpression(expression);
|
|
241
|
+
return true;
|
|
242
|
+
} catch {
|
|
243
|
+
return false;
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
//#endregion
|
|
248
|
+
export { evaluateExpression as evaluate, isValidExpression, safeEvaluateExpression as safeEvaluate, safeEvaluateRecord };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stackone/expressions",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.1",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.es.mjs",
|
|
@@ -10,12 +10,20 @@
|
|
|
10
10
|
"package.json",
|
|
11
11
|
"README.md"
|
|
12
12
|
],
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"types": "./dist/types/index.d.ts",
|
|
16
|
+
"import": "./dist/index.es.mjs",
|
|
17
|
+
"require": "./dist/index.js"
|
|
18
|
+
},
|
|
19
|
+
"./package.json": "./package.json"
|
|
20
|
+
},
|
|
13
21
|
"scripts": {
|
|
14
22
|
"clean": "rimraf dist",
|
|
15
23
|
"prebuild": "npm run clean",
|
|
16
|
-
"build": "
|
|
24
|
+
"build": "tsdown --env.NODE_ENV=production",
|
|
17
25
|
"prebuild:dev": "npm run clean",
|
|
18
|
-
"build:dev": "
|
|
26
|
+
"build:dev": "tsdown --env.NODE_ENV=development",
|
|
19
27
|
"code:format": "biome format ./src ./*.mjs",
|
|
20
28
|
"code:format:fix": "biome format --write ./src ./*.mjs",
|
|
21
29
|
"code:lint": "biome lint --error-on-warnings ./src ./*.mjs",
|
|
@@ -40,5 +48,12 @@
|
|
|
40
48
|
"devDependencies": {
|
|
41
49
|
"@types/jexl": "^2.3.4",
|
|
42
50
|
"@types/lodash.get": "^4.4.9"
|
|
51
|
+
},
|
|
52
|
+
"tsdown": {
|
|
53
|
+
"dts": true,
|
|
54
|
+
"format": [
|
|
55
|
+
"esm",
|
|
56
|
+
"cjs"
|
|
57
|
+
]
|
|
43
58
|
}
|
|
44
59
|
}
|
package/dist/index.es.mjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{calculateNextAnniversary as r,calculateYearsElapsed as t,dateHasPassed as e,isMissing as n,notMissing as a,isObject as i}from"@stackone/utils";import*as o from"jexl";import{JSONPath as s}from"jsonpath-plus";import l from"lodash.get";const c=/\${([^}]+)}/g,u=(r,t)=>{try{return r.compile(t)}catch{return null}},d=(r,t)=>{try{if(!r.startsWith("$"))throw new Error(`JSONPath expression must start with '$': ${r}`);if(r.includes("$_")||r.match(/\$[^.\[]/g)||r.includes("[")&&!r.includes("]")||r.includes(" ")&&!r.includes("["))throw new Error(`Invalid JSONPath expression: ${r}`);const e=s({path:r,json:t});if(0===e.length)return;return 1===e.length?e[0]:e}catch{throw new Error(`Invalid JSONPath expression: ${r}`)}},y=(r,t,e)=>r.replace(t,String(e)),h=(r,t,e)=>{const n=r.match(c);if(!n)return;const i=n.length,o=new Array(i);for(let r=0;r<i;r++)o[r]={toReplace:n[r],path:n[r].slice(2,-1)};return o.reduce(((r,n)=>((r,t,e,n)=>{const i=r.path.trim();if(!i)return n;try{const o=u(t,i);if(o){const t=o.evalSync(e);if(void 0!==t)return y(n,r.toReplace,t)}const s=l(e,i);return a(s)?y(n,r.toReplace,s):n}catch{return n}})(n,e,t,r)),String(r))},p=(r,t,e,n)=>{if(Array.isArray(t)){const r=parseInt(e,10);if(!isNaN(r)&&(r<0||r>=t.length))return{value:void 0,error:`Invalid array index '${e}' at '${n}'`,availableKeys:t.map(((r,t)=>t.toString()))}}return i(t)?{value:void 0,error:`Key '${e}' not found at '${n}'`,availableKeys:Object.keys(t)}:{value:void 0,error:`${r} at '${n}'`,availableKeys:[]}},v=(r,t)=>{const e=/(\.\.)|(\[\*\])|(\[\?\()|(\[\d+:\d+\])/;try{if(e.test(r)){const e=d(r,t);return void 0===e?{value:void 0,error:`Invalid or empty JSONPath: '${r}'`}:{value:e}}const n=r.match(/\$|(?:\['([^']+)'\])|(?:\["([^"]+)"\])|\[\d+\]|[^[\].]+/g)||[];return((r,t)=>{if("$"!==r[0])return{value:void 0,error:"JSON path must start with $"};let e=t,n="$";for(let t=1;t<r.length;t++){const a=r[t],o=a.startsWith("[")?`${n}${a}`:`${n}.${a}`;if(Array.isArray(e)){const r=parseInt(a,10);if(isNaN(r)||r<0||r>=e.length)return p("Invalid array index",e,a,n);e=e[r],n=o}else{if(!i(e))return{value:void 0,error:`Cannot access '${a}' at '${n}' - parent is not an object`,availableKeys:[]};if(!Object.prototype.hasOwnProperty.call(e,a))return p("Key not found",e,a,n);e=e[a],n=o}}return{value:e}})(n.map((r=>r.replace(/^\['([^']+)'\]$/,"$1").replace(/^\["([^"]+)"\]$/,"$1").replace(/^\[(\d+)\]$/,"$1"))),t)}catch(r){return{value:void 0,error:`Something went wrong with evaluation of JSON path: ${String(r)}`}}},f=(s,l,c)=>{const y=s?.trim();if(null==y||""===y)throw new Error("Empty expression");const p=i(l)?l:{},f=((i=()=>new o.Jexl)=>{const s=i();return s.addFunction("nextAnniversary",((t,e)=>r({initialDate:t,format:e}))),s.addFunction("yearsElapsed",((r,e,n)=>t({startDate:r,endDate:n,format:e}))),s.addFunction("hasPassed",((r,t,n)=>e({date:r,yearsToAdd:n,format:t}))),s.addFunction("now",(()=>(new Date).toISOString())),s.addFunction("includes",((r,t)=>!(n(r)||!Array.isArray(r)||0===r.length||n(t))&&(Array.isArray(t)?t.every((t=>r.includes(t))):r.includes(t)))),s.addFunction("includesSome",((r,t)=>!(n(r)||!Array.isArray(r)||0===r.length||n(t))&&(Array.isArray(t)?t.some((t=>r.includes(t))):r.includes(t)))),s.addFunction("present",(r=>a(r))),s.addFunction("missing",(r=>n(r))),s.addFunction("keys",(r=>n(r)||"object"!=typeof r||Array.isArray(r)?[]:Object.keys(r))),s.addFunction("values",(r=>n(r)||"object"!=typeof r||Array.isArray(r)?[]:Object.values(r))),s.addBinaryOp("??",0,((r,t)=>n(r)?t:n(t)?r:r??t)),s})(),$=(r=>{if(r.startsWith("{{")&&r.endsWith("}}"))return r.slice(2,-2)})(y),m=(r=>r.replace(/\$\./g,"").trim())($??y),w=h(m,p,f);if(w)return w;if(!$&&y.startsWith("$"))return c?.incrementalJsonPath?((r,t)=>{const e=v(r,t);if(e.error)throw new Error(`${e.error}${e.availableKeys?.length?`. Available keys: ${e.availableKeys.join(", ")}`:""}`);return e.value})(y,p):((r,t)=>{try{return d(r,t)}catch{throw new Error(`Invalid JSON path: "${r}"`)}})(y,p);if(!w&&!$)return s;const g=u(f,m);if(!g||"."===m)throw new Error(`Invalid expression: "${y}"`);try{return g.evalSync(p)}catch{return}},$=(r,t)=>{try{return f(r,t)}catch{return null}},m=(r,t)=>{const e=r=>Array.isArray(r)?r.map(e):"object"==typeof r&&null!==r?m(r,t):"string"==typeof r?$(r,t):r;return Object.fromEntries(Object.entries(r).map((([r,t])=>[r,e(t)])))},w=r=>{try{return f(r),!0}catch{return!1}};export{f as evaluate,w as isValidExpression,$ as safeEvaluate,m as safeEvaluateRecord};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const INTERPOLATED_EXPRESSION_REGEX: RegExp;
|
package/dist/types/evaluate.d.ts
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
export declare const evaluateExpression: (expression?: string | null, context?: unknown, options?: {
|
|
2
|
-
incrementalJsonPath?: boolean;
|
|
3
|
-
}) => unknown;
|
|
4
|
-
export declare const safeEvaluateExpression: (expression?: string | null, context?: unknown) => unknown;
|
|
5
|
-
export declare const safeEvaluateRecord: (record: Record<string, unknown>, context?: unknown) => Record<string, unknown>;
|
package/dist/types/factory.d.ts
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
export declare const createExpressionHandler: (instanceBuilder?: () => {
|
|
2
|
-
addBinaryOp(operator: string, precedence: number, fn: (left: any, right: any) => any): void;
|
|
3
|
-
addUnaryOp(operator: string, fn: (right: any) => any): void;
|
|
4
|
-
addTransform(name: string, fn: (value: any, ...args: any[]) => any): void;
|
|
5
|
-
addTransforms(map: {
|
|
6
|
-
[key: string]: (value: any, ...args: any[]) => any;
|
|
7
|
-
}): void;
|
|
8
|
-
getTransform(name: string): (value: any, ...args: any[]) => any;
|
|
9
|
-
addFunction(name: string, fn: (value: any, ...args: any[]) => any): void;
|
|
10
|
-
addFunctions(map: {
|
|
11
|
-
[key: string]: (value: any, ...args: any[]) => any;
|
|
12
|
-
}): void;
|
|
13
|
-
getFunction(name: string): (value: any, ...args: any[]) => any;
|
|
14
|
-
eval(expression: string, context?: import("jexl/Expression").Context): Promise<any>;
|
|
15
|
-
evalSync(expression: string, context?: import("jexl/Expression").Context): any;
|
|
16
|
-
compile(expression: string): import("jexl/Expression").default;
|
|
17
|
-
createExpression(expression: string): import("jexl/Expression").default;
|
|
18
|
-
removeOp(operator: string): void;
|
|
19
|
-
_grammar: import("jexl/Grammar").default;
|
|
20
|
-
}) => {
|
|
21
|
-
addBinaryOp(operator: string, precedence: number, fn: (left: any, right: any) => any): void;
|
|
22
|
-
addUnaryOp(operator: string, fn: (right: any) => any): void;
|
|
23
|
-
addTransform(name: string, fn: (value: any, ...args: any[]) => any): void;
|
|
24
|
-
addTransforms(map: {
|
|
25
|
-
[key: string]: (value: any, ...args: any[]) => any;
|
|
26
|
-
}): void;
|
|
27
|
-
getTransform(name: string): (value: any, ...args: any[]) => any;
|
|
28
|
-
addFunction(name: string, fn: (value: any, ...args: any[]) => any): void;
|
|
29
|
-
addFunctions(map: {
|
|
30
|
-
[key: string]: (value: any, ...args: any[]) => any;
|
|
31
|
-
}): void;
|
|
32
|
-
getFunction(name: string): (value: any, ...args: any[]) => any;
|
|
33
|
-
eval(expression: string, context?: import("jexl/Expression").Context): Promise<any>;
|
|
34
|
-
evalSync(expression: string, context?: import("jexl/Expression").Context): any;
|
|
35
|
-
compile(expression: string): import("jexl/Expression").default;
|
|
36
|
-
createExpression(expression: string): import("jexl/Expression").default;
|
|
37
|
-
removeOp(operator: string): void;
|
|
38
|
-
_grammar: import("jexl/Grammar").default;
|
|
39
|
-
};
|
package/dist/types/index.d.ts
DELETED
package/dist/types/types.d.ts
DELETED
package/dist/types/utils.d.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import Expression from 'jexl/Expression';
|
|
2
|
-
import { ExpressionContext } from './types';
|
|
3
|
-
export declare const cleanExpression: (expression: string) => string;
|
|
4
|
-
export declare const compileExpression: (expressionHandler: {
|
|
5
|
-
compile: (expr: string) => Expression;
|
|
6
|
-
}, expression: string) => Expression | null;
|
|
7
|
-
export declare const extractExpressionBetweenDoubleCurlyBraces: (expression: string) => string | undefined;
|
|
8
|
-
export declare const evaluateJsonPath: (expression: string, context: unknown) => unknown;
|
|
9
|
-
export declare const evaluateStringInterpolations: (expression: string, context: ExpressionContext, expressionHandler: {
|
|
10
|
-
compile: (expr: string) => Expression;
|
|
11
|
-
}) => string | undefined;
|
|
12
|
-
export declare const evaluateJsonPathIncremental: (path: string, context: unknown) => {
|
|
13
|
-
value: unknown;
|
|
14
|
-
error?: string;
|
|
15
|
-
availableKeys?: string[];
|
|
16
|
-
};
|
package/dist/types/validate.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const isValidExpression: (expression?: string | null) => boolean;
|