@react-querybuilder/core 8.14.4 → 8.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +114 -53
- package/dist/cjs/react-querybuilder_core.cjs.development.d.ts +288 -22
- package/dist/cjs/react-querybuilder_core.cjs.development.js +796 -77
- package/dist/cjs/react-querybuilder_core.cjs.development.js.map +1 -1
- package/dist/cjs/react-querybuilder_core.cjs.production.d.ts +288 -22
- package/dist/cjs/react-querybuilder_core.cjs.production.js +1 -1
- package/dist/cjs/react-querybuilder_core.cjs.production.js.map +1 -1
- package/dist/{convertQuery-CeJSNn37.mjs → convertQuery-BeJJH9BI.mjs} +2 -2
- package/dist/convertQuery-BeJJH9BI.mjs.map +1 -0
- package/dist/{convertQuery-J8LpTG-7.js → convertQuery-Lx2HQa0m.js} +2 -2
- package/dist/convertQuery-Lx2HQa0m.js.map +1 -0
- package/dist/formatQuery.d.mts +89 -2
- package/dist/formatQuery.d.ts +89 -2
- package/dist/formatQuery.js +775 -66
- package/dist/formatQuery.js.map +1 -1
- package/dist/formatQuery.mjs +768 -67
- package/dist/formatQuery.mjs.map +1 -1
- package/dist/{import-BwQqExpO.d.mts → import-BHlzBLM_.d.mts} +2 -2
- package/dist/{import-CrJf23Nf.d.ts → import-C6imciDf.d.ts} +2 -2
- package/dist/{index-CYT4Saz-.d.mts → index-Cjapnb-H.d.ts} +161 -10
- package/dist/{index-DBlQeLax.d.ts → index-D-Iej37L.d.mts} +161 -10
- package/dist/{objectUtils-ButT0Mng.js → objectUtils-Bzug_QfX.js} +2 -2
- package/dist/objectUtils-Bzug_QfX.js.map +1 -0
- package/dist/{objectUtils-C0WB-8ex.mjs → objectUtils-D96eEEzL.mjs} +2 -2
- package/dist/objectUtils-D96eEEzL.mjs.map +1 -0
- package/dist/parseCEL.d.mts +2 -2
- package/dist/parseCEL.d.ts +2 -2
- package/dist/parseCEL.js +35 -35
- package/dist/parseCEL.js.map +1 -1
- package/dist/parseCEL.mjs +35 -35
- package/dist/parseCEL.mjs.map +1 -1
- package/dist/parseCypher.d.mts +49 -0
- package/dist/parseCypher.d.ts +49 -0
- package/dist/parseCypher.js +578 -0
- package/dist/parseCypher.js.map +1 -0
- package/dist/parseCypher.mjs +575 -0
- package/dist/parseCypher.mjs.map +1 -0
- package/dist/parseGremlin.d.mts +35 -0
- package/dist/parseGremlin.d.ts +35 -0
- package/dist/parseGremlin.js +192 -0
- package/dist/parseGremlin.js.map +1 -0
- package/dist/parseGremlin.mjs +191 -0
- package/dist/parseGremlin.mjs.map +1 -0
- package/dist/parseJSONata.d.mts +2 -2
- package/dist/parseJSONata.d.ts +2 -2
- package/dist/parseJSONata.js +11 -11
- package/dist/parseJSONata.js.map +1 -1
- package/dist/parseJSONata.mjs +11 -11
- package/dist/parseJSONata.mjs.map +1 -1
- package/dist/parseJsonLogic.d.mts +2 -2
- package/dist/parseJsonLogic.d.ts +2 -2
- package/dist/parseJsonLogic.js +6 -6
- package/dist/parseJsonLogic.js.map +1 -1
- package/dist/parseJsonLogic.mjs +6 -6
- package/dist/parseJsonLogic.mjs.map +1 -1
- package/dist/parseMongoDB.d.mts +2 -2
- package/dist/parseMongoDB.d.ts +2 -2
- package/dist/parseMongoDB.js +6 -6
- package/dist/parseMongoDB.js.map +1 -1
- package/dist/parseMongoDB.mjs +6 -6
- package/dist/parseMongoDB.mjs.map +1 -1
- package/dist/parseSPARQL.d.mts +34 -0
- package/dist/parseSPARQL.d.ts +34 -0
- package/dist/parseSPARQL.js +253 -0
- package/dist/parseSPARQL.js.map +1 -0
- package/dist/parseSPARQL.mjs +251 -0
- package/dist/parseSPARQL.mjs.map +1 -0
- package/dist/parseSQL.d.mts +2 -2
- package/dist/parseSQL.d.ts +2 -2
- package/dist/parseSQL.js +16 -16
- package/dist/parseSQL.js.map +1 -1
- package/dist/parseSQL.mjs +16 -16
- package/dist/parseSQL.mjs.map +1 -1
- package/dist/parseSpEL.d.mts +2 -2
- package/dist/parseSpEL.d.ts +2 -2
- package/dist/parseSpEL.js +10 -10
- package/dist/parseSpEL.js.map +1 -1
- package/dist/parseSpEL.mjs +10 -10
- package/dist/parseSpEL.mjs.map +1 -1
- package/dist/{prepareQueryObjects-DO3qXriW.js → prepareQueryObjects-BoG5Rt8z.js} +6 -6
- package/dist/prepareQueryObjects-BoG5Rt8z.js.map +1 -0
- package/dist/{prepareQueryObjects-BfMlS4ql.mjs → prepareQueryObjects-uA10ZpZX.mjs} +6 -6
- package/dist/prepareQueryObjects-uA10ZpZX.mjs.map +1 -0
- package/dist/query-builder.css +1 -1
- package/dist/query-builder.css.map +1 -1
- package/dist/react-querybuilder_core.d.mts +288 -22
- package/dist/react-querybuilder_core.legacy-esm.d.ts +288 -22
- package/dist/react-querybuilder_core.legacy-esm.js +833 -108
- package/dist/react-querybuilder_core.legacy-esm.js.map +1 -1
- package/dist/react-querybuilder_core.mjs +788 -78
- package/dist/react-querybuilder_core.mjs.map +1 -1
- package/dist/react-querybuilder_core.production.d.mts +288 -22
- package/dist/react-querybuilder_core.production.mjs +1 -1
- package/dist/react-querybuilder_core.production.mjs.map +1 -1
- package/dist/styles/_main.scss +4 -0
- package/dist/transformQuery.d.mts +1 -1
- package/dist/transformQuery.d.ts +1 -1
- package/dist/transformQuery.js +1 -1
- package/dist/transformQuery.mjs +1 -1
- package/dist/{utils-BlMGIhvx.mjs → utils-ChLG90DP.mjs} +3 -3
- package/dist/utils-ChLG90DP.mjs.map +1 -0
- package/dist/{utils-CZRhzje-.js → utils-Qwkq2Q0F.js} +3 -3
- package/dist/utils-Qwkq2Q0F.js.map +1 -0
- package/formatQuery/package.json +1 -1
- package/package.json +53 -14
- package/parseCEL/package.json +1 -1
- package/parseCypher/package.json +4 -0
- package/parseGremlin/package.json +4 -0
- package/parseJSONata/package.json +1 -1
- package/parseJsonLogic/package.json +1 -1
- package/parseMongoDB/package.json +1 -1
- package/parseSPARQL/package.json +4 -0
- package/parseSQL/package.json +1 -1
- package/parseSpEL/package.json +1 -1
- package/transformQuery/package.json +1 -1
- package/dist/convertQuery-CeJSNn37.mjs.map +0 -1
- package/dist/convertQuery-J8LpTG-7.js.map +0 -1
- package/dist/objectUtils-ButT0Mng.js.map +0 -1
- package/dist/objectUtils-C0WB-8ex.mjs.map +0 -1
- package/dist/prepareQueryObjects-BfMlS4ql.mjs.map +0 -1
- package/dist/prepareQueryObjects-DO3qXriW.js.map +0 -1
- package/dist/utils-BlMGIhvx.mjs.map +0 -1
- package/dist/utils-CZRhzje-.js.map +0 -1
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { E as DefaultRuleGroupType, x as DefaultRuleGroupTypeIC } from "./index-Cjapnb-H.js";
|
|
2
|
+
|
|
3
|
+
//#region src/utils/parseGremlin/parseGremlin.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Options for {@link parseGremlin}.
|
|
6
|
+
*/
|
|
7
|
+
interface ParseGremlinOptions {
|
|
8
|
+
independentCombinators?: boolean;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Parses a Gremlin traversal string into a {@link DefaultRuleGroupType}.
|
|
12
|
+
*
|
|
13
|
+
* Accepts a full Gremlin traversal or a chain of `.has()` steps.
|
|
14
|
+
* Pattern steps (`.hasLabel()`, `.out()`, `.in()`, `.both()`, `.as()`) are
|
|
15
|
+
* consumed but discarded — only `.has()` filter predicates are returned.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```ts
|
|
19
|
+
* // Full traversal — extracts .has() conditions only
|
|
20
|
+
* parseGremlin("g.V().hasLabel('Person').has('age', gt(30))");
|
|
21
|
+
*
|
|
22
|
+
* // Bare .has() chain
|
|
23
|
+
* parseGremlin(".has('age', gt(30)).has('name', 'Alice')");
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
declare function parseGremlin(gremlin: string): DefaultRuleGroupType;
|
|
27
|
+
declare function parseGremlin(gremlin: string, options: Omit<ParseGremlinOptions, "independentCombinators"> & {
|
|
28
|
+
independentCombinators?: false;
|
|
29
|
+
}): DefaultRuleGroupType;
|
|
30
|
+
declare function parseGremlin(gremlin: string, options: Omit<ParseGremlinOptions, "independentCombinators"> & {
|
|
31
|
+
independentCombinators: true;
|
|
32
|
+
}): DefaultRuleGroupTypeIC;
|
|
33
|
+
//#endregion
|
|
34
|
+
export { type ParseGremlinOptions, parseGremlin };
|
|
35
|
+
//# sourceMappingURL=parseGremlin.d.ts.map
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
//#region src/utils/parseGremlin/parseGremlin.ts
|
|
3
|
+
function parseGremlin(gremlin, _options) {
|
|
4
|
+
const trimmed = gremlin.trim();
|
|
5
|
+
if (!trimmed) return {
|
|
6
|
+
combinator: "and",
|
|
7
|
+
rules: []
|
|
8
|
+
};
|
|
9
|
+
const rules = [];
|
|
10
|
+
const steps = tokenizeGremlinSteps(trimmed);
|
|
11
|
+
for (const step of steps) {
|
|
12
|
+
if (step.startsWith("hasLabel(")) continue;
|
|
13
|
+
if (step.startsWith("as(")) continue;
|
|
14
|
+
if (/^(out|in|both)\(/.test(step)) continue;
|
|
15
|
+
if (/^[VE]\(/.test(step)) continue;
|
|
16
|
+
const hasNotMatch = step.match(/^hasNot\('([^']+)'\)$/);
|
|
17
|
+
if (hasNotMatch) {
|
|
18
|
+
rules.push({
|
|
19
|
+
field: hasNotMatch[1],
|
|
20
|
+
operator: "null",
|
|
21
|
+
value: null
|
|
22
|
+
});
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
const hasExistsMatch = step.match(/^has\('([^']+)'\)$/);
|
|
26
|
+
if (hasExistsMatch) {
|
|
27
|
+
rules.push({
|
|
28
|
+
field: hasExistsMatch[1],
|
|
29
|
+
operator: "notNull",
|
|
30
|
+
value: null
|
|
31
|
+
});
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
const hasEqMatch = step.match(/^has\('([^']+)',\s*(.+)\)$/);
|
|
35
|
+
if (hasEqMatch) {
|
|
36
|
+
const [, prop, rawValue] = hasEqMatch;
|
|
37
|
+
const parsed = parseGremlinPredicate(prop, rawValue.trim());
|
|
38
|
+
if (parsed) rules.push(parsed);
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
combinator: "and",
|
|
44
|
+
rules
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
/** Tokenizes a Gremlin traversal string into individual step strings. */
|
|
48
|
+
const tokenizeGremlinSteps = (gremlin) => {
|
|
49
|
+
const steps = [];
|
|
50
|
+
let str = gremlin.trim();
|
|
51
|
+
const sourceMatch = str.match(/^\w+\.V\(\)\./);
|
|
52
|
+
if (sourceMatch) str = str.slice(sourceMatch[0].length);
|
|
53
|
+
else if (str.startsWith(".")) str = str.slice(1);
|
|
54
|
+
let depth = 0;
|
|
55
|
+
let current = "";
|
|
56
|
+
for (let i = 0; i < str.length; i++) {
|
|
57
|
+
const ch = str[i];
|
|
58
|
+
if (ch === "(") depth++;
|
|
59
|
+
else if (ch === ")") depth--;
|
|
60
|
+
if (ch === "." && depth === 0) {
|
|
61
|
+
if (current.trim()) steps.push(current.trim());
|
|
62
|
+
current = "";
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
current += ch;
|
|
66
|
+
}
|
|
67
|
+
if (current.trim()) steps.push(current.trim());
|
|
68
|
+
return steps;
|
|
69
|
+
};
|
|
70
|
+
/** Parses a Gremlin predicate (the second argument of `.has()`). */
|
|
71
|
+
const parseGremlinPredicate = (prop, rawValue) => {
|
|
72
|
+
const predicateMatch = rawValue.match(/^(\w+)\((.+)\)$/);
|
|
73
|
+
if (predicateMatch) {
|
|
74
|
+
const [, predName, args] = predicateMatch;
|
|
75
|
+
const parsedArgs = parseGremlinArgs(args);
|
|
76
|
+
switch (predName) {
|
|
77
|
+
case "gt": return {
|
|
78
|
+
field: prop,
|
|
79
|
+
operator: ">",
|
|
80
|
+
value: parsedArgs[0]
|
|
81
|
+
};
|
|
82
|
+
case "lt": return {
|
|
83
|
+
field: prop,
|
|
84
|
+
operator: "<",
|
|
85
|
+
value: parsedArgs[0]
|
|
86
|
+
};
|
|
87
|
+
case "gte": return {
|
|
88
|
+
field: prop,
|
|
89
|
+
operator: ">=",
|
|
90
|
+
value: parsedArgs[0]
|
|
91
|
+
};
|
|
92
|
+
case "lte": return {
|
|
93
|
+
field: prop,
|
|
94
|
+
operator: "<=",
|
|
95
|
+
value: parsedArgs[0]
|
|
96
|
+
};
|
|
97
|
+
case "neq": return {
|
|
98
|
+
field: prop,
|
|
99
|
+
operator: "!=",
|
|
100
|
+
value: parsedArgs[0]
|
|
101
|
+
};
|
|
102
|
+
case "within": return {
|
|
103
|
+
field: prop,
|
|
104
|
+
operator: "in",
|
|
105
|
+
value: parsedArgs
|
|
106
|
+
};
|
|
107
|
+
case "without": return {
|
|
108
|
+
field: prop,
|
|
109
|
+
operator: "notIn",
|
|
110
|
+
value: parsedArgs
|
|
111
|
+
};
|
|
112
|
+
case "between": return {
|
|
113
|
+
field: prop,
|
|
114
|
+
operator: "between",
|
|
115
|
+
value: parsedArgs.slice(0, 2)
|
|
116
|
+
};
|
|
117
|
+
case "outside": return {
|
|
118
|
+
field: prop,
|
|
119
|
+
operator: "notBetween",
|
|
120
|
+
value: parsedArgs.slice(0, 2)
|
|
121
|
+
};
|
|
122
|
+
case "containing": return {
|
|
123
|
+
field: prop,
|
|
124
|
+
operator: "contains",
|
|
125
|
+
value: parsedArgs[0]
|
|
126
|
+
};
|
|
127
|
+
case "notContaining": return {
|
|
128
|
+
field: prop,
|
|
129
|
+
operator: "doesNotContain",
|
|
130
|
+
value: parsedArgs[0]
|
|
131
|
+
};
|
|
132
|
+
case "startingWith": return {
|
|
133
|
+
field: prop,
|
|
134
|
+
operator: "beginsWith",
|
|
135
|
+
value: parsedArgs[0]
|
|
136
|
+
};
|
|
137
|
+
case "notStartingWith": return {
|
|
138
|
+
field: prop,
|
|
139
|
+
operator: "doesNotBeginWith",
|
|
140
|
+
value: parsedArgs[0]
|
|
141
|
+
};
|
|
142
|
+
case "endingWith": return {
|
|
143
|
+
field: prop,
|
|
144
|
+
operator: "endsWith",
|
|
145
|
+
value: parsedArgs[0]
|
|
146
|
+
};
|
|
147
|
+
case "notEndingWith": return {
|
|
148
|
+
field: prop,
|
|
149
|
+
operator: "doesNotEndWith",
|
|
150
|
+
value: parsedArgs[0]
|
|
151
|
+
};
|
|
152
|
+
default: return null;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return {
|
|
156
|
+
field: prop,
|
|
157
|
+
operator: "=",
|
|
158
|
+
value: parseGremlinLiteral(rawValue)
|
|
159
|
+
};
|
|
160
|
+
};
|
|
161
|
+
/** Parses a comma-separated argument list. */
|
|
162
|
+
const parseGremlinArgs = (args) => {
|
|
163
|
+
const result = [];
|
|
164
|
+
let depth = 0;
|
|
165
|
+
let current = "";
|
|
166
|
+
for (const ch of args) {
|
|
167
|
+
if (ch === "(") depth++;
|
|
168
|
+
else if (ch === ")") depth--;
|
|
169
|
+
if (ch === "," && depth === 0) {
|
|
170
|
+
result.push(parseGremlinLiteral(current.trim()));
|
|
171
|
+
current = "";
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
current += ch;
|
|
175
|
+
}
|
|
176
|
+
if (current.trim()) result.push(parseGremlinLiteral(current.trim()));
|
|
177
|
+
return result;
|
|
178
|
+
};
|
|
179
|
+
/** Parses a Gremlin literal value. */
|
|
180
|
+
const parseGremlinLiteral = (raw) => {
|
|
181
|
+
if (raw.startsWith("'") && raw.endsWith("'")) return raw.slice(1, -1).replace(/\\'/g, "'");
|
|
182
|
+
if (raw === "null") return null;
|
|
183
|
+
if (raw === "true") return true;
|
|
184
|
+
if (raw === "false") return false;
|
|
185
|
+
const num = Number(raw);
|
|
186
|
+
if (!Number.isNaN(num)) return num;
|
|
187
|
+
return raw;
|
|
188
|
+
};
|
|
189
|
+
//#endregion
|
|
190
|
+
exports.parseGremlin = parseGremlin;
|
|
191
|
+
|
|
192
|
+
//# sourceMappingURL=parseGremlin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parseGremlin.js","names":[],"sources":["../src/utils/parseGremlin/parseGremlin.ts"],"sourcesContent":["import type {\n DefaultRuleGroupType,\n DefaultRuleGroupTypeAny,\n DefaultRuleGroupTypeIC,\n DefaultRuleType,\n} from '../../types';\n\n/**\n * Options for {@link parseGremlin}.\n */\nexport interface ParseGremlinOptions {\n independentCombinators?: boolean;\n}\n\n/**\n * Parses a Gremlin traversal string into a {@link DefaultRuleGroupType}.\n *\n * Accepts a full Gremlin traversal or a chain of `.has()` steps.\n * Pattern steps (`.hasLabel()`, `.out()`, `.in()`, `.both()`, `.as()`) are\n * consumed but discarded — only `.has()` filter predicates are returned.\n *\n * @example\n * ```ts\n * // Full traversal — extracts .has() conditions only\n * parseGremlin(\"g.V().hasLabel('Person').has('age', gt(30))\");\n *\n * // Bare .has() chain\n * parseGremlin(\".has('age', gt(30)).has('name', 'Alice')\");\n * ```\n */\nexport function parseGremlin(gremlin: string): DefaultRuleGroupType;\nexport function parseGremlin(\n gremlin: string,\n options: Omit<ParseGremlinOptions, 'independentCombinators'> & {\n independentCombinators?: false;\n }\n): DefaultRuleGroupType;\nexport function parseGremlin(\n gremlin: string,\n options: Omit<ParseGremlinOptions, 'independentCombinators'> & {\n independentCombinators: true;\n }\n): DefaultRuleGroupTypeIC;\nexport function parseGremlin(\n gremlin: string,\n _options?: ParseGremlinOptions\n): DefaultRuleGroupTypeAny {\n const trimmed = gremlin.trim();\n if (!trimmed) return { combinator: 'and', rules: [] };\n\n const rules: (DefaultRuleType | DefaultRuleGroupType)[] = [];\n const steps = tokenizeGremlinSteps(trimmed);\n\n for (const step of steps) {\n // Skip pattern steps — only extract filter predicates\n // .hasLabel('Label') — pattern step, skip\n if (step.startsWith('hasLabel(')) continue;\n // .as('alias') — pattern step, skip\n if (step.startsWith('as(')) continue;\n // .out('edge'), .in('edge'), .both('edge') — pattern step, skip\n if (/^(out|in|both)\\(/.test(step)) continue;\n // .V(), .E() — traversal source, skip\n if (/^[VE]\\(/.test(step)) continue;\n\n // .hasNot('prop') — null check\n const hasNotMatch = step.match(/^hasNot\\('([^']+)'\\)$/);\n if (hasNotMatch) {\n rules.push({ field: hasNotMatch[1], operator: 'null', value: null } as DefaultRuleType);\n continue;\n }\n\n // .has('prop') — property exists\n const hasExistsMatch = step.match(/^has\\('([^']+)'\\)$/);\n if (hasExistsMatch) {\n rules.push({ field: hasExistsMatch[1], operator: 'notNull', value: null } as DefaultRuleType);\n continue;\n }\n\n // .has('prop', value) — equality or predicate\n const hasEqMatch = step.match(/^has\\('([^']+)',\\s*(.+)\\)$/);\n if (hasEqMatch) {\n const [, prop, rawValue] = hasEqMatch;\n const parsed = parseGremlinPredicate(prop, rawValue.trim());\n if (parsed) {\n rules.push(parsed);\n }\n continue;\n }\n }\n\n return { combinator: 'and', rules };\n}\n\n/** Tokenizes a Gremlin traversal string into individual step strings. */\nconst tokenizeGremlinSteps = (gremlin: string): string[] => {\n const steps: string[] = [];\n\n // Remove leading source (e.g., \"g.V().\")\n let str = gremlin.trim();\n const sourceMatch = str.match(/^\\w+\\.V\\(\\)\\./);\n if (sourceMatch) {\n str = str.slice(sourceMatch[0].length);\n } else if (str.startsWith('.')) {\n // Bare step chain starting with a dot\n str = str.slice(1);\n }\n\n // Split on top-level dots\n let depth = 0;\n let current = '';\n\n for (let i = 0; i < str.length; i++) {\n const ch = str[i];\n if (ch === '(') depth++;\n else if (ch === ')') depth--;\n\n if (ch === '.' && depth === 0) {\n if (current.trim()) steps.push(current.trim());\n current = '';\n continue;\n }\n current += ch;\n }\n if (current.trim()) steps.push(current.trim());\n\n return steps;\n};\n\n/** Parses a Gremlin predicate (the second argument of `.has()`). */\nconst parseGremlinPredicate = (prop: string, rawValue: string): DefaultRuleType | null => {\n // Predicate functions: gt(), lt(), gte(), lte(), neq(), within(), without(), between(), outside()\n const predicateMatch = rawValue.match(/^(\\w+)\\((.+)\\)$/);\n if (predicateMatch) {\n const [, predName, args] = predicateMatch;\n const parsedArgs = parseGremlinArgs(args);\n\n switch (predName) {\n case 'gt':\n return { field: prop, operator: '>', value: parsedArgs[0] } as DefaultRuleType;\n case 'lt':\n return { field: prop, operator: '<', value: parsedArgs[0] } as DefaultRuleType;\n case 'gte':\n return { field: prop, operator: '>=', value: parsedArgs[0] } as DefaultRuleType;\n case 'lte':\n return { field: prop, operator: '<=', value: parsedArgs[0] } as DefaultRuleType;\n case 'neq':\n return { field: prop, operator: '!=', value: parsedArgs[0] } as DefaultRuleType;\n case 'within':\n return { field: prop, operator: 'in', value: parsedArgs } as DefaultRuleType;\n case 'without':\n return { field: prop, operator: 'notIn', value: parsedArgs } as DefaultRuleType;\n case 'between':\n return {\n field: prop,\n operator: 'between',\n value: parsedArgs.slice(0, 2),\n } as DefaultRuleType;\n case 'outside':\n return {\n field: prop,\n operator: 'notBetween',\n value: parsedArgs.slice(0, 2),\n } as DefaultRuleType;\n case 'containing':\n return { field: prop, operator: 'contains', value: parsedArgs[0] } as DefaultRuleType;\n case 'notContaining':\n return { field: prop, operator: 'doesNotContain', value: parsedArgs[0] } as DefaultRuleType;\n case 'startingWith':\n return { field: prop, operator: 'beginsWith', value: parsedArgs[0] } as DefaultRuleType;\n case 'notStartingWith':\n return {\n field: prop,\n operator: 'doesNotBeginWith',\n value: parsedArgs[0],\n } as DefaultRuleType;\n case 'endingWith':\n return { field: prop, operator: 'endsWith', value: parsedArgs[0] } as DefaultRuleType;\n case 'notEndingWith':\n return { field: prop, operator: 'doesNotEndWith', value: parsedArgs[0] } as DefaultRuleType;\n default:\n return null;\n }\n }\n\n // Plain value — equality\n return { field: prop, operator: '=', value: parseGremlinLiteral(rawValue) } as DefaultRuleType;\n};\n\n/** Parses a comma-separated argument list. */\nconst parseGremlinArgs = (args: string): unknown[] => {\n const result: unknown[] = [];\n let depth = 0;\n let current = '';\n\n for (const ch of args) {\n if (ch === '(') depth++;\n else if (ch === ')') depth--;\n if (ch === ',' && depth === 0) {\n result.push(parseGremlinLiteral(current.trim()));\n current = '';\n continue;\n }\n current += ch;\n }\n if (current.trim()) result.push(parseGremlinLiteral(current.trim()));\n return result;\n};\n\n/** Parses a Gremlin literal value. */\nconst parseGremlinLiteral = (raw: string): unknown => {\n if (raw.startsWith(\"'\") && raw.endsWith(\"'\")) {\n return raw.slice(1, -1).replace(/\\\\'/g, \"'\");\n }\n if (raw === 'null') return null;\n if (raw === 'true') return true;\n if (raw === 'false') return false;\n const num = Number(raw);\n if (!Number.isNaN(num)) return num;\n return raw;\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
//#region src/utils/parseGremlin/parseGremlin.ts
|
|
2
|
+
function parseGremlin(gremlin, _options) {
|
|
3
|
+
const trimmed = gremlin.trim();
|
|
4
|
+
if (!trimmed) return {
|
|
5
|
+
combinator: "and",
|
|
6
|
+
rules: []
|
|
7
|
+
};
|
|
8
|
+
const rules = [];
|
|
9
|
+
const steps = tokenizeGremlinSteps(trimmed);
|
|
10
|
+
for (const step of steps) {
|
|
11
|
+
if (step.startsWith("hasLabel(")) continue;
|
|
12
|
+
if (step.startsWith("as(")) continue;
|
|
13
|
+
if (/^(out|in|both)\(/.test(step)) continue;
|
|
14
|
+
if (/^[VE]\(/.test(step)) continue;
|
|
15
|
+
const hasNotMatch = step.match(/^hasNot\('([^']+)'\)$/);
|
|
16
|
+
if (hasNotMatch) {
|
|
17
|
+
rules.push({
|
|
18
|
+
field: hasNotMatch[1],
|
|
19
|
+
operator: "null",
|
|
20
|
+
value: null
|
|
21
|
+
});
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
const hasExistsMatch = step.match(/^has\('([^']+)'\)$/);
|
|
25
|
+
if (hasExistsMatch) {
|
|
26
|
+
rules.push({
|
|
27
|
+
field: hasExistsMatch[1],
|
|
28
|
+
operator: "notNull",
|
|
29
|
+
value: null
|
|
30
|
+
});
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
const hasEqMatch = step.match(/^has\('([^']+)',\s*(.+)\)$/);
|
|
34
|
+
if (hasEqMatch) {
|
|
35
|
+
const [, prop, rawValue] = hasEqMatch;
|
|
36
|
+
const parsed = parseGremlinPredicate(prop, rawValue.trim());
|
|
37
|
+
if (parsed) rules.push(parsed);
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return {
|
|
42
|
+
combinator: "and",
|
|
43
|
+
rules
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/** Tokenizes a Gremlin traversal string into individual step strings. */
|
|
47
|
+
const tokenizeGremlinSteps = (gremlin) => {
|
|
48
|
+
const steps = [];
|
|
49
|
+
let str = gremlin.trim();
|
|
50
|
+
const sourceMatch = str.match(/^\w+\.V\(\)\./);
|
|
51
|
+
if (sourceMatch) str = str.slice(sourceMatch[0].length);
|
|
52
|
+
else if (str.startsWith(".")) str = str.slice(1);
|
|
53
|
+
let depth = 0;
|
|
54
|
+
let current = "";
|
|
55
|
+
for (let i = 0; i < str.length; i++) {
|
|
56
|
+
const ch = str[i];
|
|
57
|
+
if (ch === "(") depth++;
|
|
58
|
+
else if (ch === ")") depth--;
|
|
59
|
+
if (ch === "." && depth === 0) {
|
|
60
|
+
if (current.trim()) steps.push(current.trim());
|
|
61
|
+
current = "";
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
current += ch;
|
|
65
|
+
}
|
|
66
|
+
if (current.trim()) steps.push(current.trim());
|
|
67
|
+
return steps;
|
|
68
|
+
};
|
|
69
|
+
/** Parses a Gremlin predicate (the second argument of `.has()`). */
|
|
70
|
+
const parseGremlinPredicate = (prop, rawValue) => {
|
|
71
|
+
const predicateMatch = rawValue.match(/^(\w+)\((.+)\)$/);
|
|
72
|
+
if (predicateMatch) {
|
|
73
|
+
const [, predName, args] = predicateMatch;
|
|
74
|
+
const parsedArgs = parseGremlinArgs(args);
|
|
75
|
+
switch (predName) {
|
|
76
|
+
case "gt": return {
|
|
77
|
+
field: prop,
|
|
78
|
+
operator: ">",
|
|
79
|
+
value: parsedArgs[0]
|
|
80
|
+
};
|
|
81
|
+
case "lt": return {
|
|
82
|
+
field: prop,
|
|
83
|
+
operator: "<",
|
|
84
|
+
value: parsedArgs[0]
|
|
85
|
+
};
|
|
86
|
+
case "gte": return {
|
|
87
|
+
field: prop,
|
|
88
|
+
operator: ">=",
|
|
89
|
+
value: parsedArgs[0]
|
|
90
|
+
};
|
|
91
|
+
case "lte": return {
|
|
92
|
+
field: prop,
|
|
93
|
+
operator: "<=",
|
|
94
|
+
value: parsedArgs[0]
|
|
95
|
+
};
|
|
96
|
+
case "neq": return {
|
|
97
|
+
field: prop,
|
|
98
|
+
operator: "!=",
|
|
99
|
+
value: parsedArgs[0]
|
|
100
|
+
};
|
|
101
|
+
case "within": return {
|
|
102
|
+
field: prop,
|
|
103
|
+
operator: "in",
|
|
104
|
+
value: parsedArgs
|
|
105
|
+
};
|
|
106
|
+
case "without": return {
|
|
107
|
+
field: prop,
|
|
108
|
+
operator: "notIn",
|
|
109
|
+
value: parsedArgs
|
|
110
|
+
};
|
|
111
|
+
case "between": return {
|
|
112
|
+
field: prop,
|
|
113
|
+
operator: "between",
|
|
114
|
+
value: parsedArgs.slice(0, 2)
|
|
115
|
+
};
|
|
116
|
+
case "outside": return {
|
|
117
|
+
field: prop,
|
|
118
|
+
operator: "notBetween",
|
|
119
|
+
value: parsedArgs.slice(0, 2)
|
|
120
|
+
};
|
|
121
|
+
case "containing": return {
|
|
122
|
+
field: prop,
|
|
123
|
+
operator: "contains",
|
|
124
|
+
value: parsedArgs[0]
|
|
125
|
+
};
|
|
126
|
+
case "notContaining": return {
|
|
127
|
+
field: prop,
|
|
128
|
+
operator: "doesNotContain",
|
|
129
|
+
value: parsedArgs[0]
|
|
130
|
+
};
|
|
131
|
+
case "startingWith": return {
|
|
132
|
+
field: prop,
|
|
133
|
+
operator: "beginsWith",
|
|
134
|
+
value: parsedArgs[0]
|
|
135
|
+
};
|
|
136
|
+
case "notStartingWith": return {
|
|
137
|
+
field: prop,
|
|
138
|
+
operator: "doesNotBeginWith",
|
|
139
|
+
value: parsedArgs[0]
|
|
140
|
+
};
|
|
141
|
+
case "endingWith": return {
|
|
142
|
+
field: prop,
|
|
143
|
+
operator: "endsWith",
|
|
144
|
+
value: parsedArgs[0]
|
|
145
|
+
};
|
|
146
|
+
case "notEndingWith": return {
|
|
147
|
+
field: prop,
|
|
148
|
+
operator: "doesNotEndWith",
|
|
149
|
+
value: parsedArgs[0]
|
|
150
|
+
};
|
|
151
|
+
default: return null;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return {
|
|
155
|
+
field: prop,
|
|
156
|
+
operator: "=",
|
|
157
|
+
value: parseGremlinLiteral(rawValue)
|
|
158
|
+
};
|
|
159
|
+
};
|
|
160
|
+
/** Parses a comma-separated argument list. */
|
|
161
|
+
const parseGremlinArgs = (args) => {
|
|
162
|
+
const result = [];
|
|
163
|
+
let depth = 0;
|
|
164
|
+
let current = "";
|
|
165
|
+
for (const ch of args) {
|
|
166
|
+
if (ch === "(") depth++;
|
|
167
|
+
else if (ch === ")") depth--;
|
|
168
|
+
if (ch === "," && depth === 0) {
|
|
169
|
+
result.push(parseGremlinLiteral(current.trim()));
|
|
170
|
+
current = "";
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
current += ch;
|
|
174
|
+
}
|
|
175
|
+
if (current.trim()) result.push(parseGremlinLiteral(current.trim()));
|
|
176
|
+
return result;
|
|
177
|
+
};
|
|
178
|
+
/** Parses a Gremlin literal value. */
|
|
179
|
+
const parseGremlinLiteral = (raw) => {
|
|
180
|
+
if (raw.startsWith("'") && raw.endsWith("'")) return raw.slice(1, -1).replace(/\\'/g, "'");
|
|
181
|
+
if (raw === "null") return null;
|
|
182
|
+
if (raw === "true") return true;
|
|
183
|
+
if (raw === "false") return false;
|
|
184
|
+
const num = Number(raw);
|
|
185
|
+
if (!Number.isNaN(num)) return num;
|
|
186
|
+
return raw;
|
|
187
|
+
};
|
|
188
|
+
//#endregion
|
|
189
|
+
export { parseGremlin };
|
|
190
|
+
|
|
191
|
+
//# sourceMappingURL=parseGremlin.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parseGremlin.mjs","names":[],"sources":["../src/utils/parseGremlin/parseGremlin.ts"],"sourcesContent":["import type {\n DefaultRuleGroupType,\n DefaultRuleGroupTypeAny,\n DefaultRuleGroupTypeIC,\n DefaultRuleType,\n} from '../../types';\n\n/**\n * Options for {@link parseGremlin}.\n */\nexport interface ParseGremlinOptions {\n independentCombinators?: boolean;\n}\n\n/**\n * Parses a Gremlin traversal string into a {@link DefaultRuleGroupType}.\n *\n * Accepts a full Gremlin traversal or a chain of `.has()` steps.\n * Pattern steps (`.hasLabel()`, `.out()`, `.in()`, `.both()`, `.as()`) are\n * consumed but discarded — only `.has()` filter predicates are returned.\n *\n * @example\n * ```ts\n * // Full traversal — extracts .has() conditions only\n * parseGremlin(\"g.V().hasLabel('Person').has('age', gt(30))\");\n *\n * // Bare .has() chain\n * parseGremlin(\".has('age', gt(30)).has('name', 'Alice')\");\n * ```\n */\nexport function parseGremlin(gremlin: string): DefaultRuleGroupType;\nexport function parseGremlin(\n gremlin: string,\n options: Omit<ParseGremlinOptions, 'independentCombinators'> & {\n independentCombinators?: false;\n }\n): DefaultRuleGroupType;\nexport function parseGremlin(\n gremlin: string,\n options: Omit<ParseGremlinOptions, 'independentCombinators'> & {\n independentCombinators: true;\n }\n): DefaultRuleGroupTypeIC;\nexport function parseGremlin(\n gremlin: string,\n _options?: ParseGremlinOptions\n): DefaultRuleGroupTypeAny {\n const trimmed = gremlin.trim();\n if (!trimmed) return { combinator: 'and', rules: [] };\n\n const rules: (DefaultRuleType | DefaultRuleGroupType)[] = [];\n const steps = tokenizeGremlinSteps(trimmed);\n\n for (const step of steps) {\n // Skip pattern steps — only extract filter predicates\n // .hasLabel('Label') — pattern step, skip\n if (step.startsWith('hasLabel(')) continue;\n // .as('alias') — pattern step, skip\n if (step.startsWith('as(')) continue;\n // .out('edge'), .in('edge'), .both('edge') — pattern step, skip\n if (/^(out|in|both)\\(/.test(step)) continue;\n // .V(), .E() — traversal source, skip\n if (/^[VE]\\(/.test(step)) continue;\n\n // .hasNot('prop') — null check\n const hasNotMatch = step.match(/^hasNot\\('([^']+)'\\)$/);\n if (hasNotMatch) {\n rules.push({ field: hasNotMatch[1], operator: 'null', value: null } as DefaultRuleType);\n continue;\n }\n\n // .has('prop') — property exists\n const hasExistsMatch = step.match(/^has\\('([^']+)'\\)$/);\n if (hasExistsMatch) {\n rules.push({ field: hasExistsMatch[1], operator: 'notNull', value: null } as DefaultRuleType);\n continue;\n }\n\n // .has('prop', value) — equality or predicate\n const hasEqMatch = step.match(/^has\\('([^']+)',\\s*(.+)\\)$/);\n if (hasEqMatch) {\n const [, prop, rawValue] = hasEqMatch;\n const parsed = parseGremlinPredicate(prop, rawValue.trim());\n if (parsed) {\n rules.push(parsed);\n }\n continue;\n }\n }\n\n return { combinator: 'and', rules };\n}\n\n/** Tokenizes a Gremlin traversal string into individual step strings. */\nconst tokenizeGremlinSteps = (gremlin: string): string[] => {\n const steps: string[] = [];\n\n // Remove leading source (e.g., \"g.V().\")\n let str = gremlin.trim();\n const sourceMatch = str.match(/^\\w+\\.V\\(\\)\\./);\n if (sourceMatch) {\n str = str.slice(sourceMatch[0].length);\n } else if (str.startsWith('.')) {\n // Bare step chain starting with a dot\n str = str.slice(1);\n }\n\n // Split on top-level dots\n let depth = 0;\n let current = '';\n\n for (let i = 0; i < str.length; i++) {\n const ch = str[i];\n if (ch === '(') depth++;\n else if (ch === ')') depth--;\n\n if (ch === '.' && depth === 0) {\n if (current.trim()) steps.push(current.trim());\n current = '';\n continue;\n }\n current += ch;\n }\n if (current.trim()) steps.push(current.trim());\n\n return steps;\n};\n\n/** Parses a Gremlin predicate (the second argument of `.has()`). */\nconst parseGremlinPredicate = (prop: string, rawValue: string): DefaultRuleType | null => {\n // Predicate functions: gt(), lt(), gte(), lte(), neq(), within(), without(), between(), outside()\n const predicateMatch = rawValue.match(/^(\\w+)\\((.+)\\)$/);\n if (predicateMatch) {\n const [, predName, args] = predicateMatch;\n const parsedArgs = parseGremlinArgs(args);\n\n switch (predName) {\n case 'gt':\n return { field: prop, operator: '>', value: parsedArgs[0] } as DefaultRuleType;\n case 'lt':\n return { field: prop, operator: '<', value: parsedArgs[0] } as DefaultRuleType;\n case 'gte':\n return { field: prop, operator: '>=', value: parsedArgs[0] } as DefaultRuleType;\n case 'lte':\n return { field: prop, operator: '<=', value: parsedArgs[0] } as DefaultRuleType;\n case 'neq':\n return { field: prop, operator: '!=', value: parsedArgs[0] } as DefaultRuleType;\n case 'within':\n return { field: prop, operator: 'in', value: parsedArgs } as DefaultRuleType;\n case 'without':\n return { field: prop, operator: 'notIn', value: parsedArgs } as DefaultRuleType;\n case 'between':\n return {\n field: prop,\n operator: 'between',\n value: parsedArgs.slice(0, 2),\n } as DefaultRuleType;\n case 'outside':\n return {\n field: prop,\n operator: 'notBetween',\n value: parsedArgs.slice(0, 2),\n } as DefaultRuleType;\n case 'containing':\n return { field: prop, operator: 'contains', value: parsedArgs[0] } as DefaultRuleType;\n case 'notContaining':\n return { field: prop, operator: 'doesNotContain', value: parsedArgs[0] } as DefaultRuleType;\n case 'startingWith':\n return { field: prop, operator: 'beginsWith', value: parsedArgs[0] } as DefaultRuleType;\n case 'notStartingWith':\n return {\n field: prop,\n operator: 'doesNotBeginWith',\n value: parsedArgs[0],\n } as DefaultRuleType;\n case 'endingWith':\n return { field: prop, operator: 'endsWith', value: parsedArgs[0] } as DefaultRuleType;\n case 'notEndingWith':\n return { field: prop, operator: 'doesNotEndWith', value: parsedArgs[0] } as DefaultRuleType;\n default:\n return null;\n }\n }\n\n // Plain value — equality\n return { field: prop, operator: '=', value: parseGremlinLiteral(rawValue) } as DefaultRuleType;\n};\n\n/** Parses a comma-separated argument list. */\nconst parseGremlinArgs = (args: string): unknown[] => {\n const result: unknown[] = [];\n let depth = 0;\n let current = '';\n\n for (const ch of args) {\n if (ch === '(') depth++;\n else if (ch === ')') depth--;\n if (ch === ',' && depth === 0) {\n result.push(parseGremlinLiteral(current.trim()));\n current = '';\n continue;\n }\n current += ch;\n }\n if (current.trim()) result.push(parseGremlinLiteral(current.trim()));\n return result;\n};\n\n/** Parses a Gremlin literal value. */\nconst parseGremlinLiteral = (raw: string): unknown => {\n if (raw.startsWith(\"'\") && raw.endsWith(\"'\")) {\n return raw.slice(1, -1).replace(/\\\\'/g, \"'\");\n }\n if (raw === 'null') return null;\n if (raw === 'true') return true;\n if (raw === 'false') return false;\n const num = Number(raw);\n if (!Number.isNaN(num)) return num;\n return raw;\n};\n"],"mappings":"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"}
|
package/dist/parseJSONata.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t as ParserCommonOptions } from "./import-
|
|
1
|
+
import { E as DefaultRuleGroupType, j as Except, x as DefaultRuleGroupTypeIC } from "./index-D-Iej37L.mjs";
|
|
2
|
+
import { t as ParserCommonOptions } from "./import-BHlzBLM_.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/utils/parseJSONata/parseJSONata.d.ts
|
|
5
5
|
/**
|
package/dist/parseJSONata.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t as ParserCommonOptions } from "./import-
|
|
1
|
+
import { E as DefaultRuleGroupType, j as Except, x as DefaultRuleGroupTypeIC } from "./index-Cjapnb-H.js";
|
|
2
|
+
import { t as ParserCommonOptions } from "./import-C6imciDf.js";
|
|
3
3
|
|
|
4
4
|
//#region src/utils/parseJSONata/parseJSONata.d.ts
|
|
5
5
|
/**
|
package/dist/parseJSONata.js
CHANGED
|
@@ -21,8 +21,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
21
21
|
enumerable: true
|
|
22
22
|
}) : target, mod));
|
|
23
23
|
//#endregion
|
|
24
|
-
const require_objectUtils = require("./objectUtils-
|
|
25
|
-
const require_prepareQueryObjects = require("./prepareQueryObjects-
|
|
24
|
+
const require_objectUtils = require("./objectUtils-Bzug_QfX.js");
|
|
25
|
+
const require_prepareQueryObjects = require("./prepareQueryObjects-BoG5Rt8z.js");
|
|
26
26
|
let jsonata = require("jsonata");
|
|
27
27
|
jsonata = __toESM(jsonata);
|
|
28
28
|
//#region src/utils/parseJSONata/utils.ts
|
|
@@ -66,7 +66,7 @@ const getValidValue = (expr) => {
|
|
|
66
66
|
else if (isJSONataIdentifierList(expr)) return expr.expressions.map((v) => getFieldFromPath(v));
|
|
67
67
|
return expr.value;
|
|
68
68
|
};
|
|
69
|
-
const getFieldFromPath = (path) => isJSONataIdentifier(path) ? path.steps.map((s) => s.value).join(".") : "";
|
|
69
|
+
const getFieldFromPath = (path) => isJSONataIdentifier(path) ? path.steps.map((s) => s.value).join(".") : /* v8 ignore next -- @preserve */ "";
|
|
70
70
|
const normalizeOperator = (opType, flip) => {
|
|
71
71
|
if (flip) {
|
|
72
72
|
if (opType === "<") return ">";
|
|
@@ -82,7 +82,7 @@ const negatedLikeOperators = {
|
|
|
82
82
|
endsWith: "doesNotEndWith"
|
|
83
83
|
};
|
|
84
84
|
const generateFlatAndOrList = (expr) => {
|
|
85
|
-
//
|
|
85
|
+
// v8 ignore else
|
|
86
86
|
if (isJSONataAnd(expr) || isJSONataOr(expr)) {
|
|
87
87
|
const { lhs, rhs, value: combinator } = expr;
|
|
88
88
|
if (isJSONataAnd(lhs) || isJSONataOr(lhs)) return [
|
|
@@ -96,7 +96,7 @@ const generateFlatAndOrList = (expr) => {
|
|
|
96
96
|
rhs
|
|
97
97
|
];
|
|
98
98
|
}
|
|
99
|
-
//
|
|
99
|
+
// v8 ignore next
|
|
100
100
|
return [];
|
|
101
101
|
};
|
|
102
102
|
const generateMixedAndOrList = (expr) => {
|
|
@@ -144,7 +144,7 @@ function parseJSONata(jsonataInput, options = {}) {
|
|
|
144
144
|
if (isJSONataBlock(expr)) {
|
|
145
145
|
if (isJSONataAnd(expr.expressions[0]) || isJSONataOr(expr.expressions[0]) || isJSONataBlock(expr.expressions[0])) return parseJSONataAST(expr.expressions[0]);
|
|
146
146
|
const blockOfExpr = parseJSONataAST(expr.expressions[0]);
|
|
147
|
-
//
|
|
147
|
+
// v8 ignore else
|
|
148
148
|
if (blockOfExpr) return ic ? { rules: [blockOfExpr] } : {
|
|
149
149
|
combinator: "and",
|
|
150
150
|
rules: [blockOfExpr]
|
|
@@ -179,14 +179,14 @@ function parseJSONata(jsonataInput, options = {}) {
|
|
|
179
179
|
value: combinator === "and" && rules[0].operator === "<=" || combinator === "or" && rules[0].operator === ">" ? [rules[1].value, rules[0].value] : [rules[0].value, rules[1].value],
|
|
180
180
|
...rules[0].valueSource ? { valueSource: rules[0].valueSource } : null
|
|
181
181
|
};
|
|
182
|
-
//
|
|
182
|
+
// v8 ignore else
|
|
183
183
|
if (rules.length > 0) return {
|
|
184
184
|
combinator,
|
|
185
185
|
rules
|
|
186
186
|
};
|
|
187
187
|
} else if (isJSONataNot(expr)) {
|
|
188
188
|
const negatedExpr = parseJSONataAST(expr.arguments[0]);
|
|
189
|
-
//
|
|
189
|
+
// v8 ignore else
|
|
190
190
|
if (negatedExpr) {
|
|
191
191
|
if (!require_objectUtils.isRuleGroup(negatedExpr) && (negatedExpr.operator === "contains" || negatedExpr.operator === "beginsWith" || negatedExpr.operator === "endsWith")) return {
|
|
192
192
|
...negatedExpr,
|
|
@@ -206,7 +206,7 @@ function parseJSONata(jsonataInput, options = {}) {
|
|
|
206
206
|
let field = "";
|
|
207
207
|
let regex = "";
|
|
208
208
|
let valueSource = void 0;
|
|
209
|
-
//
|
|
209
|
+
// v8 ignore else
|
|
210
210
|
if (isJSONataIdentifier(arg1)) {
|
|
211
211
|
field = getFieldFromPath(arg1);
|
|
212
212
|
if (isJSONataIdentifier(arg2)) {
|
|
@@ -214,7 +214,7 @@ function parseJSONata(jsonataInput, options = {}) {
|
|
|
214
214
|
valueSource = "field";
|
|
215
215
|
} else if (isJSONataString(arg2) || isJSONataRegex(arg2)) regex = getValidValue(arg2);
|
|
216
216
|
}
|
|
217
|
-
//
|
|
217
|
+
// v8 ignore else
|
|
218
218
|
if (valueSource === "field" ? fieldIsValid(field, "contains", regex) : fieldIsValid(field, "contains")) return {
|
|
219
219
|
field,
|
|
220
220
|
operator: "contains",
|
|
@@ -227,7 +227,7 @@ function parseJSONata(jsonataInput, options = {}) {
|
|
|
227
227
|
if (isJSONataIdentifierList(expr.rhs)) valueSource = "field";
|
|
228
228
|
if (isJSONataValidValue(expr.rhs)) {
|
|
229
229
|
const value = getValidValue(expr.rhs);
|
|
230
|
-
//
|
|
230
|
+
// v8 ignore else
|
|
231
231
|
if (field && value.every((v) => fieldIsValid(field, "in", valueSource === "field" ? v : void 0))) return {
|
|
232
232
|
field,
|
|
233
233
|
operator: "in",
|