@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.
Files changed (88) hide show
  1. package/.gitlab-ci.yml +28 -0
  2. package/.nvmrc +1 -0
  3. package/.storybook/analyze.sh +4 -0
  4. package/.storybook/main.ts +55 -0
  5. package/.storybook/preview.ts +42 -0
  6. package/.vscode/extensions.json +5 -0
  7. package/.vscode/settings.json +41 -0
  8. package/README.MD +50 -0
  9. package/html-include.png +0 -0
  10. package/package.json +33 -0
  11. package/src/classes/BitArray.ts +48 -0
  12. package/src/classes/DisposibleElement.ts +108 -0
  13. package/src/components/Banner.ts +102 -0
  14. package/src/components/Bitdisplay.ts +383 -0
  15. package/src/components/Button.ts +121 -0
  16. package/src/components/Header.ts +125 -0
  17. package/src/components/Page.ts +157 -0
  18. package/src/components/Panel.ts +56 -0
  19. package/src/components/ThemeProvider.ts +251 -0
  20. package/src/components/button.css.ts +160 -0
  21. package/src/components/configurations/classifications.ts +194 -0
  22. package/src/components/dialog/dialog.css.ts +50 -0
  23. package/src/components/dialog/dialog.ts +163 -0
  24. package/src/components/dialog/index.ts +1 -0
  25. package/src/components/header.css.ts +38 -0
  26. package/src/components/index.ts +10 -0
  27. package/src/components/input.css +75 -0
  28. package/src/components/input.ts +312 -0
  29. package/src/components/page.css.ts +158 -0
  30. package/src/components/panel.css.ts +44 -0
  31. package/src/components/query_bar/QueryBar.css +48 -0
  32. package/src/components/query_bar/QueryBar.ts +378 -0
  33. package/src/components/query_bar/index.ts +2 -0
  34. package/src/components/query_bar/querylanguage/kuery/ast/_generated_/kuery.js +3186 -0
  35. package/src/components/query_bar/querylanguage/kuery/ast/ast.ts +113 -0
  36. package/src/components/query_bar/querylanguage/kuery/ast/index.ts +31 -0
  37. package/src/components/query_bar/querylanguage/kuery/ast/kuery.peg +417 -0
  38. package/src/components/query_bar/querylanguage/kuery/functions/and.ts +55 -0
  39. package/src/components/query_bar/querylanguage/kuery/functions/exists.ts +62 -0
  40. package/src/components/query_bar/querylanguage/kuery/functions/index.ts +47 -0
  41. package/src/components/query_bar/querylanguage/kuery/functions/is.ts +211 -0
  42. package/src/components/query_bar/querylanguage/kuery/functions/nested.ts +63 -0
  43. package/src/components/query_bar/querylanguage/kuery/functions/not.ts +53 -0
  44. package/src/components/query_bar/querylanguage/kuery/functions/or.ts +56 -0
  45. package/src/components/query_bar/querylanguage/kuery/functions/range.ts +163 -0
  46. package/src/components/query_bar/querylanguage/kuery/functions/utils/get_fields.ts +49 -0
  47. package/src/components/query_bar/querylanguage/kuery/functions/utils/get_full_field_name_node.ts +87 -0
  48. package/src/components/query_bar/querylanguage/kuery/index.ts +38 -0
  49. package/src/components/query_bar/querylanguage/kuery/kuery_syntax_error.ts +76 -0
  50. package/src/components/query_bar/querylanguage/kuery/node_types/function.ts +75 -0
  51. package/src/components/query_bar/querylanguage/kuery/node_types/index.ts +46 -0
  52. package/src/components/query_bar/querylanguage/kuery/node_types/literal.ts +42 -0
  53. package/src/components/query_bar/querylanguage/kuery/node_types/named_arg.ts +47 -0
  54. package/src/components/query_bar/querylanguage/kuery/node_types/types.ts +108 -0
  55. package/src/components/query_bar/querylanguage/kuery/node_types/wildcard.ts +80 -0
  56. package/src/components/query_bar/querylanguage/kuery/types.ts +52 -0
  57. package/src/components/query_bar/querylanguage/outputTypes/toCQL.ts +122 -0
  58. package/src/components/query_bar/querylanguage/outputTypes/toMongo.ts +103 -0
  59. package/src/components/query_bar/querylanguage/utils.ts +35 -0
  60. package/src/components/query_bar/types.ts +59 -0
  61. package/src/components/splitview/index.ts +1 -0
  62. package/src/components/splitview/splitview.css.ts +66 -0
  63. package/src/components/splitview/splitview.ts +183 -0
  64. package/src/components/types.ts +35 -0
  65. package/src/index.ts +1 -0
  66. package/src/stories/Banner.stories.ts +46 -0
  67. package/src/stories/BitDisplay.stories.ts +68 -0
  68. package/src/stories/Button.stories.ts +138 -0
  69. package/src/stories/Header.stories.ts +55 -0
  70. package/src/stories/Page.stories.ts +108 -0
  71. package/src/stories/QueryBar.stories.ts +63 -0
  72. package/src/stories/Splitview.stories.ts +52 -0
  73. package/src/stories/fixtures/Bits.ts +15 -0
  74. package/src/stories/fixtures/ExampleContent.ts +102 -0
  75. package/src/stories/fixtures/data.ts +30 -0
  76. package/src/stories/fixtures/lorumipsum.ts +19 -0
  77. package/src/stories/input.stories.ts +77 -0
  78. package/src/stories/tsconfig.json +35 -0
  79. package/src/utils/debounce.ts +18 -0
  80. package/src/utils/spread.ts +71 -0
  81. package/src/vite-env.d.ts +1 -0
  82. package/test/__init__.py +9 -0
  83. package/test/elastic.py +9 -0
  84. package/test/interface.py +16 -0
  85. package/tsconfig.json +29 -0
  86. package/vite.config.js +34 -0
  87. package/vue-example.png +0 -0
  88. package/vue-include.png +0 -0
@@ -0,0 +1,47 @@
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 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
+
39
+ export const functions: any = {
40
+ is,
41
+ and,
42
+ or,
43
+ not,
44
+ range,
45
+ exists,
46
+ nested,
47
+ };
@@ -0,0 +1,211 @@
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 { getFields } from './utils/get_fields';
32
+ import { getTimeZoneFromSettings } from '../../utils';
33
+ import { getFullFieldNameNode } from './utils/get_full_field_name_node';
34
+ import { IIndexPattern, KueryNode, IFieldType } from '../../..';
35
+
36
+ import * as ast from '../ast';
37
+
38
+ import * as literal from '../node_types/literal';
39
+ import * as wildcard from '../node_types/wildcard';
40
+
41
+ export function buildNodeParams(fieldName: string, value: any, isPhrase: boolean = false) {
42
+ if (fieldName === undefined) {
43
+ throw new Error('fieldName is a required argument');
44
+ }
45
+ if (value === undefined) {
46
+ throw new Error('value is a required argument');
47
+ }
48
+ const fieldNode =
49
+ typeof fieldName === 'string'
50
+ ? ast.fromLiteralExpression(fieldName)
51
+ : literal.buildNode(fieldName);
52
+ const valueNode =
53
+ typeof value === 'string' ? ast.fromLiteralExpression(value) : literal.buildNode(value);
54
+ const isPhraseNode = literal.buildNode(isPhrase);
55
+ return {
56
+ arguments: [fieldNode, valueNode, isPhraseNode],
57
+ };
58
+ }
59
+
60
+ export function toOpenSearchQuery(
61
+ node: KueryNode,
62
+ indexPattern?: IIndexPattern,
63
+ config: Record<string, any> = {},
64
+ context: Record<string, any> = {}
65
+ ) {
66
+ const {
67
+ arguments: [fieldNameArg, valueArg, isPhraseArg],
68
+ } = node;
69
+ const fullFieldNameArg = getFullFieldNameNode(
70
+ fieldNameArg,
71
+ indexPattern,
72
+ context?.nested ? context.nested.path : undefined
73
+ );
74
+ const fieldName = ast.toOpenSearchQuery(fullFieldNameArg);
75
+ const value = !(valueArg === undefined) ? ast.toOpenSearchQuery(valueArg) : valueArg;
76
+ const type = isPhraseArg.value ? 'phrase' : 'best_fields';
77
+ if (fullFieldNameArg.value === null) {
78
+ if (valueArg.type === 'wildcard') {
79
+ return {
80
+ query_string: {
81
+ query: wildcard.toQueryStringQuery(valueArg),
82
+ },
83
+ };
84
+ }
85
+
86
+ return {
87
+ multi_match: {
88
+ type,
89
+ query: value,
90
+ lenient: true,
91
+ },
92
+ };
93
+ }
94
+
95
+ const fields = indexPattern ? getFields(fullFieldNameArg, indexPattern) : [];
96
+ // If no fields are found in the index pattern we send through the given field name as-is. We do this to preserve
97
+ // the behaviour of lucene on dashboards where there are panels based on different index patterns that have different
98
+ // fields. If a user queries on a field that exists in one pattern but not the other, the index pattern without the
99
+ // field should return no results. It's debatable whether this is desirable, but it's been that way forever, so we'll
100
+ // keep things familiar for now.
101
+ if (fields && fields.length === 0) {
102
+ fields.push({
103
+ name: (ast.toOpenSearchQuery(fullFieldNameArg) as unknown) as string,
104
+ scripted: false,
105
+ type: '',
106
+ });
107
+ }
108
+
109
+ const isExistsQuery = valueArg.type === 'wildcard' && (value as any) === '*';
110
+ const isAllFieldsQuery =
111
+ (fullFieldNameArg.type === 'wildcard' && ((fieldName as unknown) as string) === '*') ||
112
+ (fields && indexPattern && fields.length === indexPattern.fields.length);
113
+ const isMatchAllQuery = isExistsQuery && isAllFieldsQuery;
114
+
115
+ if (isMatchAllQuery) {
116
+ return { match_all: {} };
117
+ }
118
+
119
+ const queries = fields!.reduce((accumulator: any, field: IFieldType) => {
120
+ const wrapWithNestedQuery = (query: any) => {
121
+ // Wildcards can easily include nested and non-nested fields. There isn't a good way to let
122
+ // users handle this themselves so we automatically add nested queries in this scenario.
123
+ if (
124
+ !(fullFieldNameArg.type === 'wildcard') ||
125
+ !field.subType?.nested ||
126
+ context?.nested
127
+ ) {
128
+ return query;
129
+ } else {
130
+ return {
131
+ nested: {
132
+ path: field.subType!.nested!.path,
133
+ query,
134
+ score_mode: 'none',
135
+ },
136
+ };
137
+ }
138
+ };
139
+
140
+ if (field.scripted) {
141
+ return [] //don't support
142
+ // // Exists queries don't make sense for scripted fields
143
+ // if (!isExistsQuery) {
144
+ // return [
145
+ // ...accumulator,
146
+ // {
147
+ // script: {
148
+ // ...getPhraseScript(field, value as any),
149
+ // },
150
+ // },
151
+ // ];
152
+ // }
153
+ } else if (isExistsQuery) {
154
+ return [
155
+ ...accumulator,
156
+ wrapWithNestedQuery({
157
+ exists: {
158
+ field: field.name,
159
+ },
160
+ }),
161
+ ];
162
+ } else if (valueArg.type === 'wildcard') {
163
+ return [
164
+ ...accumulator,
165
+ wrapWithNestedQuery({
166
+ query_string: {
167
+ fields: [field.name],
168
+ query: wildcard.toQueryStringQuery(valueArg),
169
+ },
170
+ }),
171
+ ];
172
+ } else if (field.type === 'date') {
173
+ /*
174
+ If we detect that it's a date field and the user wants an exact date, we need to convert the query to both >= and <= the value provided to force a range query. This is because match and match_phrase queries do not accept a timezone parameter.
175
+ dateFormatTZ can have the value of 'Browser', in which case we guess the timezone using moment.tz.guess.
176
+ */
177
+ const timeZoneParam = config.dateFormatTZ
178
+ ? { time_zone: getTimeZoneFromSettings(config!.dateFormatTZ) }
179
+ : {};
180
+ return [
181
+ ...accumulator,
182
+ wrapWithNestedQuery({
183
+ range: {
184
+ [field.name]: {
185
+ gte: value,
186
+ lte: value,
187
+ ...timeZoneParam,
188
+ },
189
+ },
190
+ }),
191
+ ];
192
+ } else {
193
+ const queryType = type === 'phrase' ? 'match_phrase' : 'match';
194
+ return [
195
+ ...accumulator,
196
+ wrapWithNestedQuery({
197
+ [queryType]: {
198
+ [field.name]: value,
199
+ },
200
+ }),
201
+ ];
202
+ }
203
+ }, []);
204
+
205
+ return {
206
+ bool: {
207
+ should: queries || [],
208
+ minimum_should_match: 1,
209
+ },
210
+ };
211
+ }
@@ -0,0 +1,63 @@
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 * as literal from '../node_types/literal';
33
+ import { IIndexPattern, KueryNode } from '../../..';
34
+
35
+ export function buildNodeParams(path: any, child: any) {
36
+ const pathNode =
37
+ typeof path === 'string' ? ast.fromLiteralExpression(path) : literal.buildNode(path);
38
+ return {
39
+ arguments: [pathNode, child],
40
+ };
41
+ }
42
+
43
+ export function toOpenSearchQuery(
44
+ node: KueryNode,
45
+ indexPattern?: IIndexPattern,
46
+ config: Record<string, any> = {},
47
+ context: Record<string, any> = {}
48
+ ) {
49
+ const [path, child] = node.arguments;
50
+ const stringPath = ast.toOpenSearchQuery(path);
51
+ const fullPath = context?.nested?.path ? `${context.nested.path}.${stringPath}` : stringPath;
52
+
53
+ return {
54
+ nested: {
55
+ path: fullPath,
56
+ query: ast.toOpenSearchQuery(child, indexPattern, config, {
57
+ ...context,
58
+ nested: { path: fullPath },
59
+ }),
60
+ score_mode: 'none',
61
+ },
62
+ };
63
+ }
@@ -0,0 +1,53 @@
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(child: KueryNode) {
35
+ return {
36
+ arguments: [child],
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 [argument] = node.arguments;
47
+
48
+ return {
49
+ bool: {
50
+ must_not: ast.toOpenSearchQuery(argument, indexPattern, config, context),
51
+ },
52
+ };
53
+ }
@@ -0,0 +1,56 @@
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
+ should: children.map((child: KueryNode) => {
51
+ return ast.toOpenSearchQuery(child, indexPattern, config, context);
52
+ }),
53
+ minimum_should_match: 1,
54
+ },
55
+ };
56
+ }
@@ -0,0 +1,163 @@
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
+
32
+ import { nodeTypes } from '../node_types';
33
+ import * as ast from '../ast';
34
+
35
+ import { getFields } from './utils/get_fields';
36
+ import { getTimeZoneFromSettings } from '../../utils';
37
+ import { getFullFieldNameNode } from './utils/get_full_field_name_node';
38
+ import { IIndexPattern, KueryNode, IFieldType } from '../../..';
39
+
40
+ function pick(object: Record<string, any>, ...options: string[]) {
41
+ let out: Record<string, any> = {}
42
+ for (let op of options) {
43
+ out[op] = object[op]
44
+ }
45
+ return out
46
+ }
47
+ export function buildNodeParams(fieldName: string, params: any) {
48
+ const paramsToMap = pick(params, 'gt', 'lt', 'gte', 'lte', 'format');
49
+ const fieldNameArg =
50
+ typeof fieldName === 'string'
51
+ ? ast.fromLiteralExpression(fieldName)
52
+ : nodeTypes.literal.buildNode(fieldName);
53
+
54
+ const args = Object.entries(paramsToMap).map((input) => {
55
+ let [key, value]: [string, number | string] = input
56
+ return nodeTypes.namedArg.buildNode(key, value);
57
+ });
58
+
59
+ return {
60
+ arguments: [fieldNameArg, ...args],
61
+ };
62
+ }
63
+
64
+ export function toOpenSearchQuery(
65
+ node: KueryNode,
66
+ indexPattern?: IIndexPattern,
67
+ config: Record<string, any> = {},
68
+ context: Record<string, any> = {}
69
+ ) {
70
+ const [fieldNameArg, ...args] = node.arguments;
71
+ const fullFieldNameArg = getFullFieldNameNode(
72
+ fieldNameArg,
73
+ indexPattern,
74
+ context?.nested ? context.nested.path : undefined
75
+ );
76
+ const fields = indexPattern ? getFields(fullFieldNameArg, indexPattern) : [];
77
+ const namedArgs = extractArguments(args);
78
+ const queryParams = Object.fromEntries(Object.entries(namedArgs).map(([key, arg]) => {
79
+ return [key, ast.toOpenSearchQuery(arg as KueryNode)];
80
+ }));
81
+
82
+ // If no fields are found in the index pattern we send through the given field name as-is. We do this to preserve
83
+ // the behaviour of lucene on dashboards where there are panels based on different index patterns that have different
84
+ // fields. If a user queries on a field that exists in one pattern but not the other, the index pattern without the
85
+ // field should return no results. It's debatable whether this is desirable, but it's been that way forever, so we'll
86
+ // keep things familiar for now.
87
+ if (fields && fields.length === 0) {
88
+ fields.push({
89
+ name: (ast.toOpenSearchQuery(fullFieldNameArg) as unknown) as string,
90
+ scripted: false,
91
+ type: '',
92
+ });
93
+ }
94
+
95
+ const queries = fields!.map((field: IFieldType) => {
96
+ const wrapWithNestedQuery = (query: any) => {
97
+ // Wildcards can easily include nested and non-nested fields. There isn't a good way to let
98
+ // users handle this themselves so we automatically add nested queries in this scenario.
99
+ if (
100
+ !(fullFieldNameArg.type === 'wildcard') ||
101
+ !field.subType?.nested ||
102
+ context!.nested
103
+ ) {
104
+ return query;
105
+ } else {
106
+ return {
107
+ nested: {
108
+ path: field.subType!.nested!.path,
109
+ query,
110
+ score_mode: 'none',
111
+ },
112
+ };
113
+ }
114
+ };
115
+
116
+ if (field.scripted) {
117
+ return {} //Don't support this
118
+
119
+ } else if (field.type === 'date') {
120
+ const timeZoneParam = config.dateFormatTZ
121
+ ? { time_zone: getTimeZoneFromSettings(config!.dateFormatTZ) }
122
+ : {};
123
+ return wrapWithNestedQuery({
124
+ range: {
125
+ [field.name]: {
126
+ ...queryParams,
127
+ ...timeZoneParam,
128
+ },
129
+ },
130
+ });
131
+ }
132
+ return wrapWithNestedQuery({
133
+ range: {
134
+ [field.name]: queryParams,
135
+ },
136
+ });
137
+ });
138
+
139
+ return {
140
+ bool: {
141
+ should: queries,
142
+ minimum_should_match: 1,
143
+ },
144
+ };
145
+ }
146
+
147
+ function extractArguments(args: any) {
148
+ if ((args.gt && args.gte) || (args.lt && args.lte)) {
149
+ throw new Error('range ends cannot be both inclusive and exclusive');
150
+ }
151
+
152
+ const unnamedArgOrder = ['gte', 'lte', 'format'];
153
+
154
+ return args.reduce((acc: any, arg: any, index: number) => {
155
+ if (arg.type === 'namedArg') {
156
+ acc[arg.name] = arg.value;
157
+ } else {
158
+ acc[unnamedArgOrder[index]] = arg;
159
+ }
160
+
161
+ return acc;
162
+ }, {});
163
+ }
@@ -0,0 +1,49 @@
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 * as wildcard from '../../node_types/wildcard';
33
+ import { KueryNode, IIndexPattern } from '../../../..';
34
+ import { LiteralTypeBuildNode } from '../../node_types/types';
35
+
36
+ export function getFields(node: KueryNode, indexPattern?: IIndexPattern) {
37
+ if (!indexPattern) return [];
38
+ if (node.type === 'literal') {
39
+ const fieldName = literal.toOpenSearchQuery(node as LiteralTypeBuildNode);
40
+ const field = indexPattern.fields.find((fld) => fld.name === fieldName);
41
+ if (!field) {
42
+ return [];
43
+ }
44
+ return [field];
45
+ } else if (node.type === 'wildcard') {
46
+ const fields = indexPattern.fields.filter((fld) => wildcard.test(node, fld.name));
47
+ return fields;
48
+ }
49
+ }