forked from guardian/grid
-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathsyntax.ts
More file actions
98 lines (86 loc) · 2.71 KB
/
syntax.ts
File metadata and controls
98 lines (86 loc) · 2.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import { CqlBinary, CqlExpr, CqlField, CqlQuery, CqlStr } from "@guardian/cql";
import {
FilterType,
StructuredQuery
} from "../../search/structured-query/syntax";
export const cqlParserSettings = {
operators: false,
groups: false,
shortcuts: {
"#": "label",
"~": "collection"
}
};
export const structureCqlQuery = (query: CqlQuery): StructuredQuery => {
if (!query.content) {
return [];
}
return combineConsecutiveTextFields(structuredQueryFromBinary(query.content));
};
const structuredQueryFromExpr = (expr: CqlExpr): StructuredQuery => {
const filterType = expr.polarity === "NEGATIVE" ? "exclusion" : "inclusion";
switch (expr.content.type) {
case "CqlStr":
return structuredQueryFromStr(expr.content, filterType);
case "CqlBinary":
return structuredQueryFromBinary(expr.content);
case "CqlGroup":
return []; // No groups in Grid queries ... yet
case "CqlField":
return structuredQueryFromField(expr.content, filterType);
}
};
const structuredQueryFromBinary = (binary: CqlBinary): StructuredQuery => {
const left = structuredQueryFromExpr(binary.left);
const right = binary.right
? structuredQueryFromBinary(binary.right.binary)
: [];
return left.concat(right);
};
const structuredQueryFromStr = (
str: CqlStr,
filterType: FilterType,
): StructuredQuery => {
return [
{
type: "text",
// Take the lexeme, rather than the literal, as if the string
// is quoted we must preserve the quotes: this what Grid expects
value: str.token.lexeme,
filterType
}
];
};
const structuredQueryFromField = (
{ key: { literal }, value }: CqlField,
filterType: FilterType,
): StructuredQuery => {
if (!literal) {
return [];
}
const type = literal === "collection" ? "static-filter" : "filter";
return [
{
type,
filterType,
key: literal,
value: value?.literal ?? ""
}
];
};
const combineConsecutiveTextFields = (
query: StructuredQuery,
): StructuredQuery =>
query.reduce((previousFields, structuredField) => {
//const previousField = previousFields.at(-1);
const previousField = previousFields[previousFields.length - 1];
const joinedFieldsContainExclusion = structuredField.filterType === "exclusion" || previousField?.filterType === "exclusion";
const joinedFieldsAreBothText = structuredField.type === "text" && previousField?.type === "text";
if (!joinedFieldsAreBothText || joinedFieldsContainExclusion) {
return previousFields.concat(structuredField);
}
return previousFields.slice(0, previousFields.length - 1).concat({
...structuredField,
value: `${previousField.value} ${structuredField.value}`
});
}, [] as StructuredQuery);