@spectric/ui 0.0.20 → 0.0.22
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/components/Banner.d.ts +1 -1
- package/dist/components/dialog/dialog.d.ts +2 -1
- package/dist/components/pagination/pagination.d.ts +1 -1
- package/dist/components/query_bar/QueryBar.d.ts +31 -11
- package/dist/components/query_bar/dateTimePopup.d.ts +2 -0
- package/dist/components/query_bar/geojsonPopup.d.ts +2 -0
- package/dist/components/query_bar/querylanguage/kuery/functions/geospatial.d.ts +19 -0
- package/dist/components/query_bar/querylanguage/outputTypes/toCQL.d.ts +2 -1
- package/dist/components/query_bar/querylanguage/outputTypes/toMongo.d.ts +6 -1
- package/dist/components/symbols.d.ts +6 -0
- package/dist/components/table/cell.d.ts +2 -2
- package/dist/components/table/header.d.ts +2 -1
- package/dist/components/table/table.d.ts +14 -7
- package/dist/custom-elements.json +8 -8
- package/dist/index.d.ts +4 -0
- package/dist/index.es.js +4556 -2834
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +424 -248
- package/dist/index.umd.js.map +1 -1
- package/dist/style.css +1 -1
- package/package.json +6 -1
- package/src/components/Banner.ts +46 -31
- package/src/components/dialog/dialog.css.ts +29 -29
- package/src/components/dialog/dialog.ts +165 -135
- package/src/components/input.ts +49 -39
- package/src/components/pagination/pagination.ts +167 -113
- package/src/components/query_bar/QueryBar.ts +441 -185
- package/src/components/query_bar/dateTimePopup.ts +54 -0
- package/src/components/query_bar/geojsonPopup.ts +44 -0
- package/src/components/query_bar/querylanguage/kuery/ast/_generated_/kuery.js +1836 -2745
- package/src/components/query_bar/querylanguage/kuery/ast/ast.ts +15 -13
- package/src/components/query_bar/querylanguage/kuery/ast/kuery.peg +92 -126
- package/src/components/query_bar/querylanguage/kuery/functions/geospatial.ts +25 -0
- package/src/components/query_bar/querylanguage/kuery/functions/index.ts +9 -7
- package/src/components/query_bar/querylanguage/outputTypes/toCQL.ts +56 -34
- package/src/components/query_bar/querylanguage/outputTypes/toMongo.ts +46 -34
- package/src/components/symbols.ts +6 -0
- package/src/components/table/__tests__/table.spec.ts +143 -55
- package/src/components/table/cell.ts +188 -145
- package/src/components/table/header.ts +163 -152
- package/src/components/table/table.css +4 -2
- package/src/components/table/table.ts +415 -262
- package/src/components/table/virtualBody.ts +170 -115
- package/src/components/tooltip/popover.ts +263 -225
- package/src/stories/Dialog.stories.ts +59 -0
- package/src/stories/QueryBar.stories.ts +46 -37
- package/src/stories/fixtures/data.ts +195 -36
- package/src/stories/table.stories.ts +70 -22
|
@@ -28,22 +28,21 @@
|
|
|
28
28
|
* under the License.
|
|
29
29
|
*/
|
|
30
30
|
|
|
31
|
-
import { nodeTypes } from
|
|
32
|
-
import { DQLSyntaxError } from
|
|
33
|
-
import { KueryNode, DslQuery, KueryParseOptions } from
|
|
34
|
-
|
|
31
|
+
import { nodeTypes } from "../node_types/index";
|
|
32
|
+
import { DQLSyntaxError } from "../kuery_syntax_error";
|
|
33
|
+
import { KueryNode, DslQuery, KueryParseOptions } from "../types";
|
|
35
34
|
|
|
36
35
|
// @ts-ignore
|
|
37
|
-
import { parse as parseKuery } from
|
|
38
|
-
import { JsonObject, IIndexPattern, FieldTypes } from
|
|
36
|
+
import { parse as parseKuery } from "./_generated_/kuery";
|
|
37
|
+
import { JsonObject, IIndexPattern, FieldTypes } from "../../..";
|
|
39
38
|
|
|
40
39
|
const fromExpression = (
|
|
41
40
|
expression: string | DslQuery,
|
|
42
41
|
parseOptions: Partial<KueryParseOptions> = {},
|
|
43
42
|
parse: Function = parseKuery
|
|
44
43
|
): KueryNode => {
|
|
45
|
-
if (typeof expression ===
|
|
46
|
-
throw new Error(
|
|
44
|
+
if (typeof expression === "undefined") {
|
|
45
|
+
throw new Error("expression must be a string, got undefined instead");
|
|
47
46
|
}
|
|
48
47
|
|
|
49
48
|
return parse(expression, { ...parseOptions, helpers: { nodeTypes } });
|
|
@@ -57,7 +56,7 @@ export const fromLiteralExpression = (
|
|
|
57
56
|
expression,
|
|
58
57
|
{
|
|
59
58
|
...parseOptions,
|
|
60
|
-
startRule:
|
|
59
|
+
startRule: "Literal",
|
|
61
60
|
},
|
|
62
61
|
parseKuery
|
|
63
62
|
);
|
|
@@ -70,7 +69,7 @@ export const fromKueryExpression = (
|
|
|
70
69
|
try {
|
|
71
70
|
return fromExpression(expression, parseOptions, parseKuery);
|
|
72
71
|
} catch (error: any) {
|
|
73
|
-
if (error.name ===
|
|
72
|
+
if (error.name === "SyntaxError") {
|
|
74
73
|
throw new DQLSyntaxError(error, expression);
|
|
75
74
|
} else {
|
|
76
75
|
throw error;
|
|
@@ -85,7 +84,7 @@ export const doesKueryExpressionHaveLuceneSyntaxError = (
|
|
|
85
84
|
fromExpression(expression, { errorOnLuceneSyntax: true }, parseKuery);
|
|
86
85
|
return false;
|
|
87
86
|
} catch (e: any) {
|
|
88
|
-
return
|
|
87
|
+
return e.message.startsWith("Lucene");
|
|
89
88
|
}
|
|
90
89
|
};
|
|
91
90
|
|
|
@@ -104,10 +103,13 @@ export const toOpenSearchQuery = (
|
|
|
104
103
|
): JsonObject => {
|
|
105
104
|
indexPattern = undefined; //for now lets just set this to undefined until we can refactor to not need the rest of open search
|
|
106
105
|
if (!node || !node.type || !nodeTypes[node.type]) {
|
|
107
|
-
return toOpenSearchQuery(
|
|
106
|
+
return toOpenSearchQuery(
|
|
107
|
+
nodeTypes.function.buildNode("and", []),
|
|
108
|
+
indexPattern
|
|
109
|
+
);
|
|
108
110
|
}
|
|
109
111
|
|
|
110
|
-
const nodeType =
|
|
112
|
+
const nodeType = nodeTypes[node.type] as unknown as any;
|
|
111
113
|
|
|
112
114
|
return nodeType.toOpenSearchQuery(node, indexPattern, config, context);
|
|
113
115
|
};
|
|
@@ -18,7 +18,8 @@ start
|
|
|
18
18
|
if (trailing.type === 'cursor') {
|
|
19
19
|
return {
|
|
20
20
|
...trailing,
|
|
21
|
-
suggestionTypes: ['conjunction']
|
|
21
|
+
suggestionTypes: ['conjunction'],
|
|
22
|
+
rule:"start"
|
|
22
23
|
};
|
|
23
24
|
}
|
|
24
25
|
if (query !== null) return query;
|
|
@@ -26,8 +27,7 @@ start
|
|
|
26
27
|
}
|
|
27
28
|
|
|
28
29
|
OrQuery
|
|
29
|
-
=
|
|
30
|
-
/ left:AndQuery Or right:OrQuery {
|
|
30
|
+
= left:AndQuery Or right:OrQuery {
|
|
31
31
|
const cursor = [left, right].find(node => node.type === 'cursor');
|
|
32
32
|
if (cursor) return cursor;
|
|
33
33
|
return buildFunctionNode('or', [left, right]);
|
|
@@ -54,7 +54,8 @@ SubQuery
|
|
|
54
54
|
if (trailing.type === 'cursor') {
|
|
55
55
|
return {
|
|
56
56
|
...trailing,
|
|
57
|
-
suggestionTypes: ['conjunction']
|
|
57
|
+
suggestionTypes: ['conjunction'],
|
|
58
|
+
rule:"SubQuery"
|
|
58
59
|
};
|
|
59
60
|
}
|
|
60
61
|
return query;
|
|
@@ -81,19 +82,62 @@ NestedQuery
|
|
|
81
82
|
/ Expression
|
|
82
83
|
|
|
83
84
|
Expression
|
|
84
|
-
=
|
|
85
|
+
= FieldGeoSpatialExpression
|
|
86
|
+
/ FieldMultiGeoSpatialExpression
|
|
87
|
+
/ FieldRangeExpression
|
|
85
88
|
/ FieldValueExpression
|
|
86
89
|
/ ValueExpression
|
|
87
90
|
|
|
88
91
|
Field "fieldName"
|
|
89
92
|
= Literal
|
|
90
93
|
|
|
94
|
+
FieldGeoSpatialExpression
|
|
95
|
+
= field:Field Space* operator:GeoSpatialOperator Space* value:Literal {
|
|
96
|
+
if (value.type === 'cursor') {
|
|
97
|
+
return {
|
|
98
|
+
...value,
|
|
99
|
+
fieldName: field.value,
|
|
100
|
+
suggestionTypes: ['geo_value','conjunction'],
|
|
101
|
+
rule:"FieldGeoSpatialExpression"
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
return {
|
|
105
|
+
type: 'function',
|
|
106
|
+
function: 'geospatial',
|
|
107
|
+
arguments: [field,operator, value],
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
}
|
|
111
|
+
FieldMultiGeoSpatialExpression
|
|
112
|
+
= field:Field Space* operator:GeoSpatialOperator Space* partial:ListOfValues {
|
|
113
|
+
if (partial.type === 'cursor') {
|
|
114
|
+
return {
|
|
115
|
+
...partial,
|
|
116
|
+
fieldName: field.value,
|
|
117
|
+
suggestionTypes: ['geo_value', 'conjunction'],
|
|
118
|
+
rule:"FieldMultiGeoSpatialExpression"
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
const range = buildNamedArgNode(operator, partial(field))
|
|
122
|
+
const listItems = partial(field)
|
|
123
|
+
if(listItems.function == "is"){
|
|
124
|
+
//One Item in the list
|
|
125
|
+
return buildFunctionNode('geospatial', [field,operator, listItems.arguments[1]]);
|
|
126
|
+
}
|
|
127
|
+
return {...listItems,arguments:listItems.arguments.map(a=> buildFunctionNode('geospatial', {
|
|
128
|
+
type: 'function',
|
|
129
|
+
function: 'geospatial',
|
|
130
|
+
arguments: [field,operator, a.arguments[1]],
|
|
131
|
+
}))}
|
|
132
|
+
}
|
|
91
133
|
FieldRangeExpression
|
|
92
|
-
= field:Field Space* operator:RangeOperator Space* value:
|
|
134
|
+
= field:Field Space* operator:RangeOperator Space* value:NumberOrQuotedString {
|
|
93
135
|
if (value.type === 'cursor') {
|
|
94
136
|
return {
|
|
95
137
|
...value,
|
|
96
|
-
|
|
138
|
+
fieldName: field.value,
|
|
139
|
+
suggestionTypes: ['value','conjunction'],
|
|
140
|
+
rule:"FieldRangeExpression"
|
|
97
141
|
};
|
|
98
142
|
}
|
|
99
143
|
const range = buildNamedArgNode(operator, value);
|
|
@@ -103,10 +147,19 @@ FieldRangeExpression
|
|
|
103
147
|
FieldValueExpression
|
|
104
148
|
= field:Field Space* ':' Space* partial:ListOfValues {
|
|
105
149
|
if (partial.type === 'cursor') {
|
|
150
|
+
if(partial.prefix.includes(wildcardSymbol)){
|
|
151
|
+
return {
|
|
152
|
+
...partial,
|
|
153
|
+
fieldName: field.value,
|
|
154
|
+
suggestionTypes: ['conjunction'],
|
|
155
|
+
rule:"FieldValueExpression"
|
|
156
|
+
}
|
|
157
|
+
}
|
|
106
158
|
return {
|
|
107
159
|
...partial,
|
|
108
160
|
fieldName: field.value,
|
|
109
|
-
suggestionTypes: ['value', 'conjunction']
|
|
161
|
+
suggestionTypes: ['value', 'conjunction'],
|
|
162
|
+
rule:"FieldValueExpression"
|
|
110
163
|
};
|
|
111
164
|
}
|
|
112
165
|
return partial(field);
|
|
@@ -119,7 +172,8 @@ ValueExpression
|
|
|
119
172
|
return {
|
|
120
173
|
...partial,
|
|
121
174
|
fieldName,
|
|
122
|
-
suggestionTypes: ['field', 'operator', 'conjunction']
|
|
175
|
+
suggestionTypes: ['field', 'operator', 'conjunction'],
|
|
176
|
+
rule:"ValueExpression"
|
|
123
177
|
};
|
|
124
178
|
}
|
|
125
179
|
const field = buildLiteralNode(null);
|
|
@@ -131,7 +185,8 @@ ListOfValues
|
|
|
131
185
|
if (trailing.type === 'cursor') {
|
|
132
186
|
return {
|
|
133
187
|
...trailing,
|
|
134
|
-
suggestionTypes: ['conjunction']
|
|
188
|
+
suggestionTypes: ['conjunction'],
|
|
189
|
+
rule:"ListOfValues"
|
|
135
190
|
};
|
|
136
191
|
}
|
|
137
192
|
return partial;
|
|
@@ -144,7 +199,8 @@ OrListOfValues
|
|
|
144
199
|
if (cursor) {
|
|
145
200
|
return {
|
|
146
201
|
...cursor,
|
|
147
|
-
suggestionTypes: ['value']
|
|
202
|
+
suggestionTypes: ['value'],
|
|
203
|
+
rule:"OrListOfValues"
|
|
148
204
|
};
|
|
149
205
|
}
|
|
150
206
|
return (field) => buildFunctionNode('or', [partialLeft(field), partialRight(field)]);
|
|
@@ -157,7 +213,8 @@ AndListOfValues
|
|
|
157
213
|
if (cursor) {
|
|
158
214
|
return {
|
|
159
215
|
...cursor,
|
|
160
|
-
suggestionTypes: ['value']
|
|
216
|
+
suggestionTypes: ['value'],
|
|
217
|
+
rule:"AndListOfValues"
|
|
161
218
|
};
|
|
162
219
|
}
|
|
163
220
|
return (field) => buildFunctionNode('and', [partialLeft(field), partialRight(field)]);
|
|
@@ -169,7 +226,8 @@ NotListOfValues
|
|
|
169
226
|
if (partial.type === 'cursor') {
|
|
170
227
|
return {
|
|
171
228
|
...list,
|
|
172
|
-
suggestionTypes: ['value']
|
|
229
|
+
suggestionTypes: ['value'],
|
|
230
|
+
rule:"NotListOfValues"
|
|
173
231
|
};
|
|
174
232
|
}
|
|
175
233
|
return (field) => buildFunctionNode('not', [partial(field)]);
|
|
@@ -195,19 +253,25 @@ Value "value"
|
|
|
195
253
|
|
|
196
254
|
Or "OR"
|
|
197
255
|
= Space+ 'or'i Space+
|
|
198
|
-
|
|
256
|
+
|
|
199
257
|
|
|
200
258
|
And "AND"
|
|
201
259
|
= Space+ 'and'i Space+
|
|
202
|
-
|
|
260
|
+
|
|
203
261
|
|
|
204
262
|
Not "NOT"
|
|
205
263
|
= 'not'i Space+
|
|
206
|
-
/ &{ return errorOnLuceneSyntax; } LuceneNot
|
|
207
264
|
|
|
208
265
|
Literal "literal"
|
|
209
266
|
= QuotedString / UnquotedLiteral
|
|
210
267
|
|
|
268
|
+
|
|
269
|
+
Number = Float / Integer
|
|
270
|
+
|
|
271
|
+
Float = Integer "." [0-9]+ { return parseFloat(text()); }
|
|
272
|
+
|
|
273
|
+
Integer = [0-9]+ { return parseInt(text(), 10); }
|
|
274
|
+
|
|
211
275
|
QuotedString
|
|
212
276
|
= '"' prefix:QuotedCharacter* cursor:Cursor suffix:QuotedCharacter* '"' {
|
|
213
277
|
const { start, end } = location();
|
|
@@ -217,13 +281,14 @@ QuotedString
|
|
|
217
281
|
end: end.offset - cursor.length,
|
|
218
282
|
prefix: prefix.join(''),
|
|
219
283
|
suffix: suffix.join(''),
|
|
220
|
-
text: text().replace(cursor, '')
|
|
284
|
+
text: text().replace(cursor, ''),
|
|
285
|
+
rule:"QuotedString"
|
|
221
286
|
};
|
|
222
287
|
}
|
|
223
288
|
/ '"' chars:QuotedCharacter* '"' {
|
|
224
289
|
return buildLiteralNode(chars.join(''));
|
|
225
290
|
}
|
|
226
|
-
|
|
291
|
+
NumberOrQuotedString = Number/QuotedString/OptionalSpace
|
|
227
292
|
QuotedCharacter
|
|
228
293
|
= EscapedWhitespace
|
|
229
294
|
/ '\\' char:[\\"] { return char; }
|
|
@@ -238,7 +303,8 @@ UnquotedLiteral
|
|
|
238
303
|
end: end.offset - cursor.length,
|
|
239
304
|
prefix: prefix.join(''),
|
|
240
305
|
suffix: suffix.join(''),
|
|
241
|
-
text: text().replace(cursor, '')
|
|
306
|
+
text: text().replace(cursor, ''),
|
|
307
|
+
rule:"UnquotedLiteral"
|
|
242
308
|
};
|
|
243
309
|
}
|
|
244
310
|
/ chars:UnquotedCharacter+ {
|
|
@@ -276,7 +342,8 @@ OptionalSpace
|
|
|
276
342
|
end: end.offset - cursor.length,
|
|
277
343
|
prefix: prefix.join(''),
|
|
278
344
|
suffix: suffix.join(''),
|
|
279
|
-
text: text().replace(cursor, '')
|
|
345
|
+
text: text().replace(cursor, ''),
|
|
346
|
+
rule:"OptionalSpace"
|
|
280
347
|
};
|
|
281
348
|
}
|
|
282
349
|
/ Space*
|
|
@@ -298,120 +365,19 @@ Keyword
|
|
|
298
365
|
SpecialCharacter
|
|
299
366
|
= [\\():<>"*{}]
|
|
300
367
|
|
|
368
|
+
GeoSpatialOperator
|
|
369
|
+
= '<@' { return 'within'; }
|
|
370
|
+
|
|
301
371
|
RangeOperator
|
|
302
372
|
= '<=' { return 'lte'; }
|
|
303
373
|
/ '>=' { return 'gte'; }
|
|
304
374
|
/ '<' { return 'lt'; }
|
|
305
375
|
/ '>' { return 'gt'; }
|
|
306
376
|
|
|
377
|
+
|
|
307
378
|
Space "whitespace"
|
|
308
379
|
= [\ \t\r\n]
|
|
309
380
|
|
|
310
381
|
Cursor
|
|
311
|
-
= &{ return parseCursor; } '
|
|
312
|
-
|
|
313
|
-
// Temporary error rules (to help users transition from Lucene... should be removed at some point)
|
|
314
|
-
|
|
315
|
-
LuceneOr
|
|
316
|
-
= Space* '||' Space* {
|
|
317
|
-
error('LuceneOr');
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
LuceneAnd
|
|
321
|
-
= Space* '&&' Space* {
|
|
322
|
-
error('LuceneAnd');
|
|
323
|
-
}
|
|
324
|
-
/ '+' {
|
|
325
|
-
error('LuceneAnd');
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
LuceneNot
|
|
329
|
-
= '-' {
|
|
330
|
-
error('LuceneNot');
|
|
331
|
-
}
|
|
332
|
-
/ '!' {
|
|
333
|
-
error('LuceneNot');
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
LuceneQuery
|
|
337
|
-
= LuceneFieldQuery
|
|
338
|
-
/ LuceneValue
|
|
339
|
-
/ LuceneExists
|
|
340
|
-
|
|
341
|
-
LuceneFieldQuery
|
|
342
|
-
= LuceneLiteral Space* ':' Space* LuceneValue
|
|
343
|
-
|
|
344
|
-
LuceneValue
|
|
345
|
-
= LuceneRange
|
|
346
|
-
/ LuceneWildcard
|
|
347
|
-
/ LuceneRegex
|
|
348
|
-
/ LuceneFuzzy
|
|
349
|
-
/ LuceneProximity
|
|
350
|
-
/ LuceneBoost
|
|
351
|
-
|
|
352
|
-
LuceneExists
|
|
353
|
-
= '_exists_' Space* ':' Space* LuceneLiteral {
|
|
354
|
-
error('LuceneExists');
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
LuceneRange
|
|
358
|
-
= RangeOperator Space* LuceneLiteral {
|
|
359
|
-
error('LuceneRange');
|
|
360
|
-
}
|
|
361
|
-
/ LuceneRangeStart Space* LuceneLiteral LuceneTo LuceneLiteral LuceneRangeEnd {
|
|
362
|
-
error('LuceneRange');
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
LuceneWildcard
|
|
366
|
-
= (LuceneUnquotedCharacter / '*')* '?' LuceneWildcard* {
|
|
367
|
-
error('LuceneWildcard');
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
LuceneRegex
|
|
371
|
-
= '/' [^/]* '/' {
|
|
372
|
-
error('LuceneRegex');
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
LuceneFuzzy
|
|
376
|
-
= LuceneUnquotedLiteral '~' [0-9]* {
|
|
377
|
-
error('LuceneFuzzy');
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
LuceneProximity
|
|
381
|
-
= QuotedString '~' [0-9]* {
|
|
382
|
-
error('LuceneProximity');
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
LuceneBoost
|
|
386
|
-
= LuceneLiteral '^' [0-9]* {
|
|
387
|
-
error('LuceneBoost');
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
LuceneLiteral
|
|
391
|
-
= QuotedString / LuceneUnquotedLiteral
|
|
392
|
-
|
|
393
|
-
LuceneUnquotedLiteral
|
|
394
|
-
= LuceneUnquotedCharacter+
|
|
395
|
-
|
|
396
|
-
LuceneUnquotedCharacter
|
|
397
|
-
= EscapedWhitespace
|
|
398
|
-
/ EscapedLuceneSpecialCharacter
|
|
399
|
-
/ !LuceneSpecialCharacter !LuceneKeyword .
|
|
400
|
-
|
|
401
|
-
LuceneKeyword
|
|
402
|
-
= Or / And / LuceneOr / LuceneAnd / LuceneNot / LuceneTo
|
|
403
|
-
|
|
404
|
-
EscapedLuceneSpecialCharacter
|
|
405
|
-
= '\\' LuceneSpecialCharacter { return char; }
|
|
406
|
-
|
|
407
|
-
LuceneSpecialCharacter
|
|
408
|
-
= '+' / '-' / '=' / '>' / '<' / '!' / '(' / ')' / '{' / '}' / '[' / ']' / '^' / '"' / '~' / '*' / '?' / ':' / '\\' / '/'
|
|
409
|
-
|
|
410
|
-
LuceneTo
|
|
411
|
-
= Space+ 'TO' Space+
|
|
412
|
-
|
|
413
|
-
LuceneRangeStart
|
|
414
|
-
= '[' / '{'
|
|
382
|
+
= &{ return parseCursor; } '©kuery-cursor©' { return cursorSymbol; }
|
|
415
383
|
|
|
416
|
-
LuceneRangeEnd
|
|
417
|
-
= ']' / '}'
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { wktToGeoJSON } from "@terraformer/wkt";
|
|
2
|
+
import { KueryNode } from "../types";
|
|
3
|
+
export function toOpenSearchQuery(node: KueryNode) {
|
|
4
|
+
const [fieldNameArg, operator, value] = node.arguments;
|
|
5
|
+
|
|
6
|
+
return {
|
|
7
|
+
bool: {
|
|
8
|
+
must: [
|
|
9
|
+
{
|
|
10
|
+
exists: {
|
|
11
|
+
field: fieldNameArg.value,
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
geo_shape: {
|
|
16
|
+
[fieldNameArg.value]: {
|
|
17
|
+
relation: operator,
|
|
18
|
+
shape: wktToGeoJSON(value.value),
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
],
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
}
|
|
@@ -28,13 +28,14 @@
|
|
|
28
28
|
* under the License.
|
|
29
29
|
*/
|
|
30
30
|
|
|
31
|
-
import * as is from
|
|
32
|
-
import * as and from
|
|
33
|
-
import * as or from
|
|
34
|
-
import * as not from
|
|
35
|
-
import * as range from
|
|
36
|
-
import * as exists from
|
|
37
|
-
import * as nested from
|
|
31
|
+
import * as is from "./is";
|
|
32
|
+
import * as and from "./and";
|
|
33
|
+
import * as or from "./or";
|
|
34
|
+
import * as not from "./not";
|
|
35
|
+
import * as range from "./range";
|
|
36
|
+
import * as exists from "./exists";
|
|
37
|
+
import * as nested from "./nested";
|
|
38
|
+
import * as geospatial from "./geospatial";
|
|
38
39
|
|
|
39
40
|
export const functions: any = {
|
|
40
41
|
is,
|
|
@@ -44,4 +45,5 @@ export const functions: any = {
|
|
|
44
45
|
range,
|
|
45
46
|
exists,
|
|
46
47
|
nested,
|
|
48
|
+
geospatial,
|
|
47
49
|
};
|
|
@@ -1,36 +1,42 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import { wildcardSymbol } from '../kuery/node_types/wildcard';
|
|
1
|
+
import { FieldTypes, KueryNode } from "../..";
|
|
2
|
+
import { wildcardSymbol } from "../kuery/node_types/wildcard";
|
|
4
3
|
|
|
5
4
|
export const KQL_WILDCARD_SYMBOL = wildcardSymbol;
|
|
6
|
-
export const KQL_NODE_TYPE_WILDCARD =
|
|
7
|
-
export type FunctionName =
|
|
5
|
+
export const KQL_NODE_TYPE_WILDCARD = "wildcard";
|
|
6
|
+
export type FunctionName =
|
|
7
|
+
| "is"
|
|
8
|
+
| "and"
|
|
9
|
+
| "or"
|
|
10
|
+
| "not"
|
|
11
|
+
| "range"
|
|
12
|
+
| "exists"
|
|
13
|
+
| "nested";
|
|
8
14
|
const and = (node: KueryNode, fields?: FieldTypes[]) => {
|
|
9
15
|
const children = node.arguments || [];
|
|
10
16
|
return (
|
|
11
|
-
|
|
17
|
+
"(" +
|
|
12
18
|
children
|
|
13
19
|
.map((child: KueryNode) => {
|
|
14
20
|
return toCql(child, fields);
|
|
15
21
|
})
|
|
16
|
-
.join(
|
|
17
|
-
|
|
22
|
+
.join(" AND ") +
|
|
23
|
+
")"
|
|
18
24
|
);
|
|
19
25
|
};
|
|
20
26
|
const is = (node: KueryNode, fields?: FieldTypes[]) => {
|
|
21
27
|
var {
|
|
22
28
|
arguments: [fieldNameArg, valueArg, isValue],
|
|
23
29
|
} = node;
|
|
24
|
-
let operator =
|
|
25
|
-
if (valueArg.type ===
|
|
26
|
-
operator =
|
|
30
|
+
let operator = "=";
|
|
31
|
+
if (valueArg.type === "wildcard") {
|
|
32
|
+
operator = "";
|
|
27
33
|
}
|
|
28
34
|
let value = toCql(valueArg);
|
|
29
35
|
isValue = isValue.value || typeof value === "string";
|
|
30
|
-
if (valueArg.type ===
|
|
36
|
+
if (valueArg.type === "literal" && isValue) {
|
|
31
37
|
value = `'${value}'`; //should be quoted
|
|
32
38
|
}
|
|
33
|
-
if (valueArg.type ===
|
|
39
|
+
if (valueArg.type === "literal" && !isValue) {
|
|
34
40
|
value = `${value}`; //shouldn't be quoted
|
|
35
41
|
}
|
|
36
42
|
let fieldName = toCql(fieldNameArg);
|
|
@@ -38,12 +44,22 @@ const is = (node: KueryNode, fields?: FieldTypes[]) => {
|
|
|
38
44
|
//this isn't possible if we don't have the names of all the fields.
|
|
39
45
|
//if we have all the fields we can do a list of or statements (field ILIKE "%value%")
|
|
40
46
|
if (fields && isValue) {
|
|
41
|
-
return `(${fields
|
|
47
|
+
return `(${fields
|
|
48
|
+
.filter((f) => f.type === "string")
|
|
49
|
+
.map((field) => `${field.name} ILIKE '%${valueArg.value}%'`)
|
|
50
|
+
.join(" OR ")})`;
|
|
42
51
|
}
|
|
43
|
-
if (
|
|
44
|
-
|
|
52
|
+
if (
|
|
53
|
+
fields &&
|
|
54
|
+
!isValue &&
|
|
55
|
+
(valueArg.value === true || valueArg.value === false)
|
|
56
|
+
) {
|
|
57
|
+
return `(${fields
|
|
58
|
+
.filter((f) => f.type === "boolean")
|
|
59
|
+
.map((field) => `${field.name}=${valueArg.value}`)
|
|
60
|
+
.join(" OR ")})`;
|
|
45
61
|
}
|
|
46
|
-
return ""
|
|
62
|
+
return "";
|
|
47
63
|
}
|
|
48
64
|
return fieldName + operator + value;
|
|
49
65
|
};
|
|
@@ -51,34 +67,33 @@ const is = (node: KueryNode, fields?: FieldTypes[]) => {
|
|
|
51
67
|
const or = (node: KueryNode, fields?: FieldTypes[]) => {
|
|
52
68
|
const children = node.arguments || [];
|
|
53
69
|
return (
|
|
54
|
-
|
|
70
|
+
"(" +
|
|
55
71
|
children
|
|
56
72
|
.map((child: KueryNode) => {
|
|
57
73
|
return toCql(child, fields);
|
|
58
74
|
})
|
|
59
|
-
.join(
|
|
60
|
-
|
|
75
|
+
.join(" OR ") +
|
|
76
|
+
")"
|
|
61
77
|
);
|
|
62
78
|
};
|
|
63
79
|
const not = (node: KueryNode, fields?: FieldTypes[]) => {
|
|
64
80
|
const [argument] = node.arguments;
|
|
65
|
-
return
|
|
81
|
+
return "NOT (" + toCql(argument, fields) + ")";
|
|
66
82
|
};
|
|
67
83
|
|
|
68
84
|
const AST_TO_CQL = {
|
|
69
|
-
gt:
|
|
70
|
-
lt:
|
|
71
|
-
gte:
|
|
72
|
-
lte:
|
|
85
|
+
gt: ">",
|
|
86
|
+
lt: "<",
|
|
87
|
+
gte: ">=",
|
|
88
|
+
lte: "<=",
|
|
73
89
|
};
|
|
74
|
-
const range = (node: KueryNode
|
|
75
|
-
|
|
90
|
+
const range = (node: KueryNode) => {
|
|
76
91
|
const [fieldNameArg, operator] = node.arguments;
|
|
77
|
-
let valueArg = operator.value
|
|
92
|
+
let valueArg = operator.value;
|
|
78
93
|
// @ts-ignore
|
|
79
94
|
const opsign = AST_TO_CQL[operator.name];
|
|
80
95
|
let value = toCql(valueArg);
|
|
81
|
-
if (valueArg.type ===
|
|
96
|
+
if (valueArg.type === "literal") {
|
|
82
97
|
value = `${value}`;
|
|
83
98
|
}
|
|
84
99
|
return `${fieldNameArg.value} ${opsign} ${value}`;
|
|
@@ -89,9 +104,15 @@ const exists = (node: KueryNode) => {
|
|
|
89
104
|
};
|
|
90
105
|
const nested = (node: KueryNode) => {
|
|
91
106
|
//nested types don't exist in CQL
|
|
92
|
-
console.warn("Nested types dont exist in CQL", node)
|
|
93
|
-
return ""
|
|
94
|
-
}
|
|
107
|
+
console.warn("Nested types dont exist in CQL", node);
|
|
108
|
+
return "";
|
|
109
|
+
};
|
|
110
|
+
const geospatial = (node: KueryNode) => {
|
|
111
|
+
const [fieldName, operator, value] = node.arguments;
|
|
112
|
+
console.log(fieldName, operator, value);
|
|
113
|
+
if (operator === "within") return `WITHIN(${fieldName.value},${value.value})`;
|
|
114
|
+
throw Error(`Unsupported GEO Operator:${operator}`);
|
|
115
|
+
};
|
|
95
116
|
export const functions = {
|
|
96
117
|
is,
|
|
97
118
|
and,
|
|
@@ -99,7 +120,8 @@ export const functions = {
|
|
|
99
120
|
not,
|
|
100
121
|
range,
|
|
101
122
|
exists,
|
|
102
|
-
nested
|
|
123
|
+
nested,
|
|
124
|
+
geospatial,
|
|
103
125
|
};
|
|
104
126
|
const nodeTypes = {
|
|
105
127
|
function: (node: KueryNode, fields?: FieldTypes[]) => {
|
|
@@ -111,7 +133,7 @@ const nodeTypes = {
|
|
|
111
133
|
},
|
|
112
134
|
wildcard: (node: KueryNode) => {
|
|
113
135
|
const { value } = node;
|
|
114
|
-
return ` LIKE '${value.split(KQL_WILDCARD_SYMBOL).join(
|
|
136
|
+
return ` LIKE '${value.split(KQL_WILDCARD_SYMBOL).join("%")}'`;
|
|
115
137
|
},
|
|
116
138
|
};
|
|
117
139
|
|