-
Notifications
You must be signed in to change notification settings - Fork 5
/
rsql-filter-expression.ts
126 lines (121 loc) · 3.95 KB
/
rsql-filter-expression.ts
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import { isBoolean, isNumber, isString } from 'util';
import { Operators } from './rsql-filter-operators';
export class RSQLFilterExpression {
public field: string;
public operator: Operators;
public value: string | Array<string | number | boolean> | Date | number | boolean | undefined;
constructor(
field: string,
operator: Operators,
value: string | Array<string | number | boolean> | Date | number | boolean | undefined
) {
this.field = field;
this.operator = operator;
this.value = value;
}
/**
* Builds the individual filter expression into the proper format.
*/
public build(): string {
let filterString = '';
let shouldQuote = false;
// convert the value into an appropriate string.
let valueString: string = '';
if (isString(this.value)) {
valueString = this.value;
valueString = valueString.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
shouldQuote = true;
}
if (isNumber(this.value)) {
valueString = this.value.toString();
}
if (isBoolean(this.value)) {
valueString = this.value ? 'true' : 'false';
}
if (this.value instanceof Array) {
let quotedValues = this.value.filter(i => i !== undefined).map(i => {
if (isNumber(i)) {
return i;
} else if (isString(i)) {
let val = i.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
return encodeURIComponent(this.quote(val));
} else {
return encodeURIComponent(this.quote(i));
}
});
valueString = quotedValues.join(',');
}
if (this.value instanceof Date) {
valueString = [
this.value.getFullYear(),
this.value.getMonth() + 1,
this.value.getDate()
].join('-');
shouldQuote = true;
}
if (this.value === null) {
valueString = 'null';
}
// construct the filter string
filterString += this.field;
switch (this.operator) {
case Operators.Equal:
filterString +=
'=in=' + encodeURIComponent(shouldQuote ? this.quote(valueString) : valueString);
break;
case Operators.NotEqual:
filterString +=
'!=' + encodeURIComponent(shouldQuote ? this.quote(valueString) : valueString);
break;
case Operators.Like:
filterString += '==' + encodeURIComponent(this.quote(valueString));
break;
case Operators.GreaterThan:
filterString += encodeURIComponent('>') + valueString;
break;
case Operators.GreaterThanEqualTo:
filterString += encodeURIComponent('>=') + valueString;
break;
case Operators.LessThan:
filterString += encodeURIComponent('<') + valueString;
break;
case Operators.LessThanEqualTo:
filterString += encodeURIComponent('<=') + valueString;
break;
case Operators.StartsWith:
filterString += '==' + encodeURIComponent(this.quote(`${valueString}*`));
break;
case Operators.EndsWith:
filterString += '==' + encodeURIComponent(this.quote(`*${valueString}`));
break;
case Operators.Contains:
filterString += '==' + encodeURIComponent(this.quote(`*${valueString}*`));
break;
case Operators.DoesNotContain:
filterString += '!=' + encodeURIComponent(this.quote(`*${valueString}*`));
break;
case Operators.In:
filterString += '=in=(' + valueString + ')';
break;
case Operators.NotIn:
filterString += '=out=(' + valueString + ')';
break;
case Operators.IsEmpty:
filterString += '==' + encodeURIComponent('""');
break;
case Operators.IsNotEmpty:
filterString += '!=' + encodeURIComponent('""');
break;
case Operators.IsNull:
filterString += '==null';
break;
case Operators.IsNotNull:
filterString += '!=null';
break;
}
return filterString;
}
private quote(value: string | boolean): string {
return `"${value}"`;
}
}