@spectric/ui 0.0.4
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/.gitlab-ci.yml +28 -0
- package/.nvmrc +1 -0
- package/.storybook/analyze.sh +4 -0
- package/.storybook/main.ts +55 -0
- package/.storybook/preview.ts +42 -0
- package/.vscode/extensions.json +5 -0
- package/.vscode/settings.json +41 -0
- package/README.MD +50 -0
- package/html-include.png +0 -0
- package/package.json +33 -0
- package/src/classes/BitArray.ts +48 -0
- package/src/classes/DisposibleElement.ts +108 -0
- package/src/components/Banner.ts +102 -0
- package/src/components/Bitdisplay.ts +383 -0
- package/src/components/Button.ts +121 -0
- package/src/components/Header.ts +125 -0
- package/src/components/Page.ts +157 -0
- package/src/components/Panel.ts +56 -0
- package/src/components/ThemeProvider.ts +251 -0
- package/src/components/button.css.ts +160 -0
- package/src/components/configurations/classifications.ts +194 -0
- package/src/components/dialog/dialog.css.ts +50 -0
- package/src/components/dialog/dialog.ts +163 -0
- package/src/components/dialog/index.ts +1 -0
- package/src/components/header.css.ts +38 -0
- package/src/components/index.ts +10 -0
- package/src/components/input.css +75 -0
- package/src/components/input.ts +312 -0
- package/src/components/page.css.ts +158 -0
- package/src/components/panel.css.ts +44 -0
- package/src/components/query_bar/QueryBar.css +48 -0
- package/src/components/query_bar/QueryBar.ts +378 -0
- package/src/components/query_bar/index.ts +2 -0
- package/src/components/query_bar/querylanguage/kuery/ast/_generated_/kuery.js +3186 -0
- package/src/components/query_bar/querylanguage/kuery/ast/ast.ts +113 -0
- package/src/components/query_bar/querylanguage/kuery/ast/index.ts +31 -0
- package/src/components/query_bar/querylanguage/kuery/ast/kuery.peg +417 -0
- package/src/components/query_bar/querylanguage/kuery/functions/and.ts +55 -0
- package/src/components/query_bar/querylanguage/kuery/functions/exists.ts +62 -0
- package/src/components/query_bar/querylanguage/kuery/functions/index.ts +47 -0
- package/src/components/query_bar/querylanguage/kuery/functions/is.ts +211 -0
- package/src/components/query_bar/querylanguage/kuery/functions/nested.ts +63 -0
- package/src/components/query_bar/querylanguage/kuery/functions/not.ts +53 -0
- package/src/components/query_bar/querylanguage/kuery/functions/or.ts +56 -0
- package/src/components/query_bar/querylanguage/kuery/functions/range.ts +163 -0
- package/src/components/query_bar/querylanguage/kuery/functions/utils/get_fields.ts +49 -0
- package/src/components/query_bar/querylanguage/kuery/functions/utils/get_full_field_name_node.ts +87 -0
- package/src/components/query_bar/querylanguage/kuery/index.ts +38 -0
- package/src/components/query_bar/querylanguage/kuery/kuery_syntax_error.ts +76 -0
- package/src/components/query_bar/querylanguage/kuery/node_types/function.ts +75 -0
- package/src/components/query_bar/querylanguage/kuery/node_types/index.ts +46 -0
- package/src/components/query_bar/querylanguage/kuery/node_types/literal.ts +42 -0
- package/src/components/query_bar/querylanguage/kuery/node_types/named_arg.ts +47 -0
- package/src/components/query_bar/querylanguage/kuery/node_types/types.ts +108 -0
- package/src/components/query_bar/querylanguage/kuery/node_types/wildcard.ts +80 -0
- package/src/components/query_bar/querylanguage/kuery/types.ts +52 -0
- package/src/components/query_bar/querylanguage/outputTypes/toCQL.ts +122 -0
- package/src/components/query_bar/querylanguage/outputTypes/toMongo.ts +103 -0
- package/src/components/query_bar/querylanguage/utils.ts +35 -0
- package/src/components/query_bar/types.ts +59 -0
- package/src/components/splitview/index.ts +1 -0
- package/src/components/splitview/splitview.css.ts +66 -0
- package/src/components/splitview/splitview.ts +183 -0
- package/src/components/types.ts +35 -0
- package/src/index.ts +1 -0
- package/src/stories/Banner.stories.ts +46 -0
- package/src/stories/BitDisplay.stories.ts +68 -0
- package/src/stories/Button.stories.ts +138 -0
- package/src/stories/Header.stories.ts +55 -0
- package/src/stories/Page.stories.ts +108 -0
- package/src/stories/QueryBar.stories.ts +63 -0
- package/src/stories/Splitview.stories.ts +52 -0
- package/src/stories/fixtures/Bits.ts +15 -0
- package/src/stories/fixtures/ExampleContent.ts +102 -0
- package/src/stories/fixtures/data.ts +30 -0
- package/src/stories/fixtures/lorumipsum.ts +19 -0
- package/src/stories/input.stories.ts +77 -0
- package/src/stories/tsconfig.json +35 -0
- package/src/utils/debounce.ts +18 -0
- package/src/utils/spread.ts +71 -0
- package/src/vite-env.d.ts +1 -0
- package/test/__init__.py +9 -0
- package/test/elastic.py +9 -0
- package/test/interface.py +16 -0
- package/tsconfig.json +29 -0
- package/vite.config.js +34 -0
- package/vue-example.png +0 -0
- package/vue-include.png +0 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
*
|
|
4
|
+
* The OpenSearch Contributors require contributions made to
|
|
5
|
+
* this file be licensed under the Apache-2.0 license or a
|
|
6
|
+
* compatible open source license.
|
|
7
|
+
*
|
|
8
|
+
* Any modifications Copyright OpenSearch Contributors. See
|
|
9
|
+
* GitHub history for details.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/*
|
|
13
|
+
* Licensed to Elasticsearch B.V. under one or more contributor
|
|
14
|
+
* license agreements. See the NOTICE file distributed with
|
|
15
|
+
* this work for additional information regarding copyright
|
|
16
|
+
* ownership. Elasticsearch B.V. licenses this file to you under
|
|
17
|
+
* the Apache License, Version 2.0 (the "License"); you may
|
|
18
|
+
* not use this file except in compliance with the License.
|
|
19
|
+
* You may obtain a copy of the License at
|
|
20
|
+
*
|
|
21
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
22
|
+
*
|
|
23
|
+
* Unless required by applicable law or agreed to in writing,
|
|
24
|
+
* software distributed under the License is distributed on an
|
|
25
|
+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
26
|
+
* KIND, either express or implied. See the License for the
|
|
27
|
+
* specific language governing permissions and limitations
|
|
28
|
+
* under the License.
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
import { nodeTypes } from '../node_types/index';
|
|
32
|
+
import { DQLSyntaxError } from '../kuery_syntax_error';
|
|
33
|
+
import { KueryNode, DslQuery, KueryParseOptions } from '../types';
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
// @ts-ignore
|
|
37
|
+
import { parse as parseKuery } from './_generated_/kuery';
|
|
38
|
+
import { JsonObject, IIndexPattern, FieldTypes } from '../../..';
|
|
39
|
+
|
|
40
|
+
const fromExpression = (
|
|
41
|
+
expression: string | DslQuery,
|
|
42
|
+
parseOptions: Partial<KueryParseOptions> = {},
|
|
43
|
+
parse: Function = parseKuery
|
|
44
|
+
): KueryNode => {
|
|
45
|
+
if (typeof expression === 'undefined') {
|
|
46
|
+
throw new Error('expression must be a string, got undefined instead');
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return parse(expression, { ...parseOptions, helpers: { nodeTypes } });
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export const fromLiteralExpression = (
|
|
53
|
+
expression: string | DslQuery,
|
|
54
|
+
parseOptions: Partial<KueryParseOptions> = {}
|
|
55
|
+
): KueryNode => {
|
|
56
|
+
return fromExpression(
|
|
57
|
+
expression,
|
|
58
|
+
{
|
|
59
|
+
...parseOptions,
|
|
60
|
+
startRule: 'Literal',
|
|
61
|
+
},
|
|
62
|
+
parseKuery
|
|
63
|
+
);
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export const fromKueryExpression = (
|
|
67
|
+
expression: string | DslQuery,
|
|
68
|
+
parseOptions: Partial<KueryParseOptions> = {}
|
|
69
|
+
): KueryNode => {
|
|
70
|
+
try {
|
|
71
|
+
return fromExpression(expression, parseOptions, parseKuery);
|
|
72
|
+
} catch (error: any) {
|
|
73
|
+
if (error.name === 'SyntaxError') {
|
|
74
|
+
throw new DQLSyntaxError(error, expression);
|
|
75
|
+
} else {
|
|
76
|
+
throw error;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
export const doesKueryExpressionHaveLuceneSyntaxError = (
|
|
82
|
+
expression: string | DslQuery
|
|
83
|
+
): boolean => {
|
|
84
|
+
try {
|
|
85
|
+
fromExpression(expression, { errorOnLuceneSyntax: true }, parseKuery);
|
|
86
|
+
return false;
|
|
87
|
+
} catch (e: any) {
|
|
88
|
+
return (e).message.startsWith('Lucene');
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* @params {String} indexPattern
|
|
94
|
+
* @params {Object} config - contains the dateFormatTZ
|
|
95
|
+
*
|
|
96
|
+
* IndexPattern isn't required, but if you pass one in, we can be more intelligent
|
|
97
|
+
* about how we craft the queries (e.g. scripted fields)
|
|
98
|
+
*/
|
|
99
|
+
export const toOpenSearchQuery = (
|
|
100
|
+
node: KueryNode,
|
|
101
|
+
indexPattern?: IIndexPattern | FieldTypes[],
|
|
102
|
+
config?: Record<string, any>,
|
|
103
|
+
context?: Record<string, any>
|
|
104
|
+
): JsonObject => {
|
|
105
|
+
indexPattern = undefined; //for now lets just set this to undefined until we can refactor to not need the rest of open search
|
|
106
|
+
if (!node || !node.type || !nodeTypes[node.type]) {
|
|
107
|
+
return toOpenSearchQuery(nodeTypes.function.buildNode('and', []), indexPattern);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const nodeType = (nodeTypes[node.type] as unknown) as any;
|
|
111
|
+
|
|
112
|
+
return nodeType.toOpenSearchQuery(node, indexPattern, config, context);
|
|
113
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
*
|
|
4
|
+
* The OpenSearch Contributors require contributions made to
|
|
5
|
+
* this file be licensed under the Apache-2.0 license or a
|
|
6
|
+
* compatible open source license.
|
|
7
|
+
*
|
|
8
|
+
* Any modifications Copyright OpenSearch Contributors. See
|
|
9
|
+
* GitHub history for details.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/*
|
|
13
|
+
* Licensed to Elasticsearch B.V. under one or more contributor
|
|
14
|
+
* license agreements. See the NOTICE file distributed with
|
|
15
|
+
* this work for additional information regarding copyright
|
|
16
|
+
* ownership. Elasticsearch B.V. licenses this file to you under
|
|
17
|
+
* the Apache License, Version 2.0 (the "License"); you may
|
|
18
|
+
* not use this file except in compliance with the License.
|
|
19
|
+
* You may obtain a copy of the License at
|
|
20
|
+
*
|
|
21
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
22
|
+
*
|
|
23
|
+
* Unless required by applicable law or agreed to in writing,
|
|
24
|
+
* software distributed under the License is distributed on an
|
|
25
|
+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
26
|
+
* KIND, either express or implied. See the License for the
|
|
27
|
+
* specific language governing permissions and limitations
|
|
28
|
+
* under the License.
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
export * from './ast';
|
|
@@ -0,0 +1,417 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* To generate the parsing module (kuery.js), run `grunt peg`
|
|
3
|
+
* To watch changes and generate on file change, run `grunt watch:peg`
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// Initialization block
|
|
7
|
+
{
|
|
8
|
+
const { errorOnLuceneSyntax, parseCursor, cursorSymbol, allowLeadingWildcards = true, helpers: { nodeTypes } } = options;
|
|
9
|
+
const buildFunctionNode = nodeTypes.function.buildNodeWithArgumentNodes;
|
|
10
|
+
const buildLiteralNode = nodeTypes.literal.buildNode;
|
|
11
|
+
const buildWildcardNode = nodeTypes.wildcard.buildNode;
|
|
12
|
+
const buildNamedArgNode = nodeTypes.namedArg.buildNode;
|
|
13
|
+
const { wildcardSymbol } = nodeTypes.wildcard;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
start
|
|
17
|
+
= Space* query:OrQuery? trailing:OptionalSpace {
|
|
18
|
+
if (trailing.type === 'cursor') {
|
|
19
|
+
return {
|
|
20
|
+
...trailing,
|
|
21
|
+
suggestionTypes: ['conjunction']
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
if (query !== null) return query;
|
|
25
|
+
return nodeTypes.function.buildNode('is', '*', '*');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
OrQuery
|
|
29
|
+
= &{ return errorOnLuceneSyntax; } LuceneQuery
|
|
30
|
+
/ left:AndQuery Or right:OrQuery {
|
|
31
|
+
const cursor = [left, right].find(node => node.type === 'cursor');
|
|
32
|
+
if (cursor) return cursor;
|
|
33
|
+
return buildFunctionNode('or', [left, right]);
|
|
34
|
+
}
|
|
35
|
+
/ AndQuery
|
|
36
|
+
|
|
37
|
+
AndQuery
|
|
38
|
+
= left:NotQuery And right:AndQuery {
|
|
39
|
+
const cursor = [left, right].find(node => node.type === 'cursor');
|
|
40
|
+
if (cursor) return cursor;
|
|
41
|
+
return buildFunctionNode('and', [left, right]);
|
|
42
|
+
}
|
|
43
|
+
/ NotQuery
|
|
44
|
+
|
|
45
|
+
NotQuery
|
|
46
|
+
= Not query:SubQuery {
|
|
47
|
+
if (query.type === 'cursor') return query;
|
|
48
|
+
return buildFunctionNode('not', [query]);
|
|
49
|
+
}
|
|
50
|
+
/ SubQuery
|
|
51
|
+
|
|
52
|
+
SubQuery
|
|
53
|
+
= '(' Space* query:OrQuery trailing:OptionalSpace ')' {
|
|
54
|
+
if (trailing.type === 'cursor') {
|
|
55
|
+
return {
|
|
56
|
+
...trailing,
|
|
57
|
+
suggestionTypes: ['conjunction']
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
return query;
|
|
61
|
+
}
|
|
62
|
+
/ NestedQuery
|
|
63
|
+
|
|
64
|
+
NestedQuery
|
|
65
|
+
= field:Field Space* ':' Space* '{' Space* query:OrQuery trailing:OptionalSpace '}' {
|
|
66
|
+
if (query.type === 'cursor') {
|
|
67
|
+
return {
|
|
68
|
+
...query,
|
|
69
|
+
nestedPath: query.nestedPath ? `${field.value}.${query.nestedPath}` : field.value,
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
if (trailing.type === 'cursor') {
|
|
74
|
+
return {
|
|
75
|
+
...trailing,
|
|
76
|
+
suggestionTypes: ['conjunction']
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
return buildFunctionNode('nested', [field, query]);
|
|
80
|
+
}
|
|
81
|
+
/ Expression
|
|
82
|
+
|
|
83
|
+
Expression
|
|
84
|
+
= FieldRangeExpression
|
|
85
|
+
/ FieldValueExpression
|
|
86
|
+
/ ValueExpression
|
|
87
|
+
|
|
88
|
+
Field "fieldName"
|
|
89
|
+
= Literal
|
|
90
|
+
|
|
91
|
+
FieldRangeExpression
|
|
92
|
+
= field:Field Space* operator:RangeOperator Space* value:Literal {
|
|
93
|
+
if (value.type === 'cursor') {
|
|
94
|
+
return {
|
|
95
|
+
...value,
|
|
96
|
+
suggestionTypes: ['conjunction']
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
const range = buildNamedArgNode(operator, value);
|
|
100
|
+
return buildFunctionNode('range', [field, range]);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
FieldValueExpression
|
|
104
|
+
= field:Field Space* ':' Space* partial:ListOfValues {
|
|
105
|
+
if (partial.type === 'cursor') {
|
|
106
|
+
return {
|
|
107
|
+
...partial,
|
|
108
|
+
fieldName: field.value,
|
|
109
|
+
suggestionTypes: ['value', 'conjunction']
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
return partial(field);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
ValueExpression
|
|
116
|
+
= partial:Value {
|
|
117
|
+
if (partial.type === 'cursor') {
|
|
118
|
+
const fieldName = `${partial.prefix}${partial.suffix}`.trim();
|
|
119
|
+
return {
|
|
120
|
+
...partial,
|
|
121
|
+
fieldName,
|
|
122
|
+
suggestionTypes: ['field', 'operator', 'conjunction']
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
const field = buildLiteralNode(null);
|
|
126
|
+
return partial(field);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
ListOfValues
|
|
130
|
+
= '(' Space* partial:OrListOfValues trailing:OptionalSpace ')' {
|
|
131
|
+
if (trailing.type === 'cursor') {
|
|
132
|
+
return {
|
|
133
|
+
...trailing,
|
|
134
|
+
suggestionTypes: ['conjunction']
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
return partial;
|
|
138
|
+
}
|
|
139
|
+
/ Value
|
|
140
|
+
|
|
141
|
+
OrListOfValues
|
|
142
|
+
= partialLeft:AndListOfValues Or partialRight:OrListOfValues {
|
|
143
|
+
const cursor = [partialLeft, partialRight].find(node => node.type === 'cursor');
|
|
144
|
+
if (cursor) {
|
|
145
|
+
return {
|
|
146
|
+
...cursor,
|
|
147
|
+
suggestionTypes: ['value']
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
return (field) => buildFunctionNode('or', [partialLeft(field), partialRight(field)]);
|
|
151
|
+
}
|
|
152
|
+
/ AndListOfValues
|
|
153
|
+
|
|
154
|
+
AndListOfValues
|
|
155
|
+
= partialLeft:NotListOfValues And partialRight:AndListOfValues {
|
|
156
|
+
const cursor = [partialLeft, partialRight].find(node => node.type === 'cursor');
|
|
157
|
+
if (cursor) {
|
|
158
|
+
return {
|
|
159
|
+
...cursor,
|
|
160
|
+
suggestionTypes: ['value']
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
return (field) => buildFunctionNode('and', [partialLeft(field), partialRight(field)]);
|
|
164
|
+
}
|
|
165
|
+
/ NotListOfValues
|
|
166
|
+
|
|
167
|
+
NotListOfValues
|
|
168
|
+
= Not partial:ListOfValues {
|
|
169
|
+
if (partial.type === 'cursor') {
|
|
170
|
+
return {
|
|
171
|
+
...list,
|
|
172
|
+
suggestionTypes: ['value']
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
return (field) => buildFunctionNode('not', [partial(field)]);
|
|
176
|
+
}
|
|
177
|
+
/ ListOfValues
|
|
178
|
+
|
|
179
|
+
Value "value"
|
|
180
|
+
= value:QuotedString {
|
|
181
|
+
if (value.type === 'cursor') return value;
|
|
182
|
+
const isPhrase = buildLiteralNode(true);
|
|
183
|
+
return (field) => buildFunctionNode('is', [field, value, isPhrase]);
|
|
184
|
+
}
|
|
185
|
+
/ value:UnquotedLiteral {
|
|
186
|
+
if (value.type === 'cursor') return value;
|
|
187
|
+
|
|
188
|
+
if (!allowLeadingWildcards && value.type === 'wildcard' && nodeTypes.wildcard.hasLeadingWildcard(value)) {
|
|
189
|
+
error('Leading wildcards are disabled. See query:allowLeadingWildcards in Advanced Settings.');
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
const isPhrase = buildLiteralNode(false);
|
|
193
|
+
return (field) => buildFunctionNode('is', [field, value, isPhrase]);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
Or "OR"
|
|
197
|
+
= Space+ 'or'i Space+
|
|
198
|
+
/ &{ return errorOnLuceneSyntax; } LuceneOr
|
|
199
|
+
|
|
200
|
+
And "AND"
|
|
201
|
+
= Space+ 'and'i Space+
|
|
202
|
+
/ &{ return errorOnLuceneSyntax; } LuceneAnd
|
|
203
|
+
|
|
204
|
+
Not "NOT"
|
|
205
|
+
= 'not'i Space+
|
|
206
|
+
/ &{ return errorOnLuceneSyntax; } LuceneNot
|
|
207
|
+
|
|
208
|
+
Literal "literal"
|
|
209
|
+
= QuotedString / UnquotedLiteral
|
|
210
|
+
|
|
211
|
+
QuotedString
|
|
212
|
+
= '"' prefix:QuotedCharacter* cursor:Cursor suffix:QuotedCharacter* '"' {
|
|
213
|
+
const { start, end } = location();
|
|
214
|
+
return {
|
|
215
|
+
type: 'cursor',
|
|
216
|
+
start: start.offset,
|
|
217
|
+
end: end.offset - cursor.length,
|
|
218
|
+
prefix: prefix.join(''),
|
|
219
|
+
suffix: suffix.join(''),
|
|
220
|
+
text: text().replace(cursor, '')
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
/ '"' chars:QuotedCharacter* '"' {
|
|
224
|
+
return buildLiteralNode(chars.join(''));
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
QuotedCharacter
|
|
228
|
+
= EscapedWhitespace
|
|
229
|
+
/ '\\' char:[\\"] { return char; }
|
|
230
|
+
/ !Cursor char:[^"] { return char; }
|
|
231
|
+
|
|
232
|
+
UnquotedLiteral
|
|
233
|
+
= prefix:UnquotedCharacter* cursor:Cursor suffix:UnquotedCharacter* {
|
|
234
|
+
const { start, end } = location();
|
|
235
|
+
return {
|
|
236
|
+
type: 'cursor',
|
|
237
|
+
start: start.offset,
|
|
238
|
+
end: end.offset - cursor.length,
|
|
239
|
+
prefix: prefix.join(''),
|
|
240
|
+
suffix: suffix.join(''),
|
|
241
|
+
text: text().replace(cursor, '')
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
/ chars:UnquotedCharacter+ {
|
|
245
|
+
const sequence = chars.join('').trim();
|
|
246
|
+
if (sequence === 'null') return buildLiteralNode(null);
|
|
247
|
+
if (sequence === 'true') return buildLiteralNode(true);
|
|
248
|
+
if (sequence === 'false') return buildLiteralNode(false);
|
|
249
|
+
if (chars.includes(wildcardSymbol)) return buildWildcardNode(sequence);
|
|
250
|
+
const isNumberPattern = /^(-?[1-9]+\d*([.]\d+)?)$|^(-?0[.]\d*[1-9]+)$|^0$|^0.0$|^[.]\d{1,}$/;
|
|
251
|
+
return buildLiteralNode(
|
|
252
|
+
isNumberPattern.test(sequence)
|
|
253
|
+
? isFinite(sequence) && (sequence > Number.MAX_SAFE_INTEGER || sequence < Number.MIN_SAFE_INTEGER)
|
|
254
|
+
? BigInt(sequence)
|
|
255
|
+
: Number(sequence)
|
|
256
|
+
: sequence
|
|
257
|
+
);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
UnquotedCharacter
|
|
261
|
+
= EscapedWhitespace
|
|
262
|
+
/ EscapedSpecialCharacter
|
|
263
|
+
/ EscapedKeyword
|
|
264
|
+
/ Wildcard
|
|
265
|
+
/ !SpecialCharacter !Keyword !Cursor char:. { return char; }
|
|
266
|
+
|
|
267
|
+
Wildcard
|
|
268
|
+
= '*' { return wildcardSymbol; }
|
|
269
|
+
|
|
270
|
+
OptionalSpace
|
|
271
|
+
= prefix:Space* cursor:Cursor suffix:Space* {
|
|
272
|
+
const { start, end } = location();
|
|
273
|
+
return {
|
|
274
|
+
type: 'cursor',
|
|
275
|
+
start: start.offset,
|
|
276
|
+
end: end.offset - cursor.length,
|
|
277
|
+
prefix: prefix.join(''),
|
|
278
|
+
suffix: suffix.join(''),
|
|
279
|
+
text: text().replace(cursor, '')
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
/ Space*
|
|
283
|
+
|
|
284
|
+
EscapedWhitespace
|
|
285
|
+
= '\\t' { return '\t'; }
|
|
286
|
+
/ '\\r' { return '\r'; }
|
|
287
|
+
/ '\\n' { return '\n'; }
|
|
288
|
+
|
|
289
|
+
EscapedSpecialCharacter
|
|
290
|
+
= '\\' char:SpecialCharacter { return char; }
|
|
291
|
+
|
|
292
|
+
EscapedKeyword
|
|
293
|
+
= '\\' keyword:('or'i / 'and'i / 'not'i) { return keyword; }
|
|
294
|
+
|
|
295
|
+
Keyword
|
|
296
|
+
= Or / And / Not
|
|
297
|
+
|
|
298
|
+
SpecialCharacter
|
|
299
|
+
= [\\():<>"*{}]
|
|
300
|
+
|
|
301
|
+
RangeOperator
|
|
302
|
+
= '<=' { return 'lte'; }
|
|
303
|
+
/ '>=' { return 'gte'; }
|
|
304
|
+
/ '<' { return 'lt'; }
|
|
305
|
+
/ '>' { return 'gt'; }
|
|
306
|
+
|
|
307
|
+
Space "whitespace"
|
|
308
|
+
= [\ \t\r\n]
|
|
309
|
+
|
|
310
|
+
Cursor
|
|
311
|
+
= &{ return parseCursor; } '@kuery-cursor@' { return cursorSymbol; }
|
|
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
|
+
= '[' / '{'
|
|
415
|
+
|
|
416
|
+
LuceneRangeEnd
|
|
417
|
+
= ']' / '}'
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
*
|
|
4
|
+
* The OpenSearch Contributors require contributions made to
|
|
5
|
+
* this file be licensed under the Apache-2.0 license or a
|
|
6
|
+
* compatible open source license.
|
|
7
|
+
*
|
|
8
|
+
* Any modifications Copyright OpenSearch Contributors. See
|
|
9
|
+
* GitHub history for details.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/*
|
|
13
|
+
* Licensed to Elasticsearch B.V. under one or more contributor
|
|
14
|
+
* license agreements. See the NOTICE file distributed with
|
|
15
|
+
* this work for additional information regarding copyright
|
|
16
|
+
* ownership. Elasticsearch B.V. licenses this file to you under
|
|
17
|
+
* the Apache License, Version 2.0 (the "License"); you may
|
|
18
|
+
* not use this file except in compliance with the License.
|
|
19
|
+
* You may obtain a copy of the License at
|
|
20
|
+
*
|
|
21
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
22
|
+
*
|
|
23
|
+
* Unless required by applicable law or agreed to in writing,
|
|
24
|
+
* software distributed under the License is distributed on an
|
|
25
|
+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
26
|
+
* KIND, either express or implied. See the License for the
|
|
27
|
+
* specific language governing permissions and limitations
|
|
28
|
+
* under the License.
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
import * as ast from '../ast';
|
|
32
|
+
import { IIndexPattern, KueryNode } from '../../..';
|
|
33
|
+
|
|
34
|
+
export function buildNodeParams(children: KueryNode[]) {
|
|
35
|
+
return {
|
|
36
|
+
arguments: children,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function toOpenSearchQuery(
|
|
41
|
+
node: KueryNode,
|
|
42
|
+
indexPattern?: IIndexPattern,
|
|
43
|
+
config: Record<string, any> = {},
|
|
44
|
+
context: Record<string, any> = {}
|
|
45
|
+
) {
|
|
46
|
+
const children = node.arguments || [];
|
|
47
|
+
|
|
48
|
+
return {
|
|
49
|
+
bool: {
|
|
50
|
+
filter: children.map((child: KueryNode) => {
|
|
51
|
+
return ast.toOpenSearchQuery(child, indexPattern, config, context);
|
|
52
|
+
}),
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
*
|
|
4
|
+
* The OpenSearch Contributors require contributions made to
|
|
5
|
+
* this file be licensed under the Apache-2.0 license or a
|
|
6
|
+
* compatible open source license.
|
|
7
|
+
*
|
|
8
|
+
* Any modifications Copyright OpenSearch Contributors. See
|
|
9
|
+
* GitHub history for details.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/*
|
|
13
|
+
* Licensed to Elasticsearch B.V. under one or more contributor
|
|
14
|
+
* license agreements. See the NOTICE file distributed with
|
|
15
|
+
* this work for additional information regarding copyright
|
|
16
|
+
* ownership. Elasticsearch B.V. licenses this file to you under
|
|
17
|
+
* the Apache License, Version 2.0 (the "License"); you may
|
|
18
|
+
* not use this file except in compliance with the License.
|
|
19
|
+
* You may obtain a copy of the License at
|
|
20
|
+
*
|
|
21
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
22
|
+
*
|
|
23
|
+
* Unless required by applicable law or agreed to in writing,
|
|
24
|
+
* software distributed under the License is distributed on an
|
|
25
|
+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
26
|
+
* KIND, either express or implied. See the License for the
|
|
27
|
+
* specific language governing permissions and limitations
|
|
28
|
+
* under the License.
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
import * as literal from '../node_types/literal';
|
|
32
|
+
import { IIndexPattern, KueryNode, IFieldType } from '../../../';
|
|
33
|
+
|
|
34
|
+
export function buildNodeParams(fieldName: string) {
|
|
35
|
+
return {
|
|
36
|
+
arguments: [literal.buildNode(fieldName)],
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function toOpenSearchQuery(
|
|
41
|
+
node: KueryNode,
|
|
42
|
+
indexPattern?: IIndexPattern,//@ts-ignore
|
|
43
|
+
config: Record<string, any> = {},
|
|
44
|
+
context: Record<string, any> = {}
|
|
45
|
+
) {
|
|
46
|
+
const {
|
|
47
|
+
arguments: [fieldNameArg],
|
|
48
|
+
} = node;
|
|
49
|
+
const fullFieldNameArg = {
|
|
50
|
+
...fieldNameArg,
|
|
51
|
+
value: context?.nested ? `${context.nested.path}.${fieldNameArg.value}` : fieldNameArg.value,
|
|
52
|
+
};
|
|
53
|
+
const fieldName = literal.toOpenSearchQuery(fullFieldNameArg);
|
|
54
|
+
const field = (indexPattern?.fields || []).find((fld: IFieldType) => fld.name === fieldName);
|
|
55
|
+
|
|
56
|
+
if (field && (field as IFieldType).scripted) {
|
|
57
|
+
throw new Error(`Exists query does not support scripted fields`);
|
|
58
|
+
}
|
|
59
|
+
return {
|
|
60
|
+
exists: { field: fieldName },
|
|
61
|
+
};
|
|
62
|
+
}
|