@itrocks/list 0.21.0 → 0.23.0
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/README.md +28 -0
- package/cjs/filter.js +72 -46
- package/cjs/filter.js.map +1 -1
- package/cjs/search-expression.d.ts +7 -0
- package/cjs/search-expression.js +93 -0
- package/cjs/search-expression.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -149,18 +149,46 @@ Without an explicit comparison operator, `*` and `?` request `LIKE` for any prop
|
|
|
149
149
|
and all `?` with `_`. The pattern is used as supplied without an extra trailing wildcard. Wildcards take precedence
|
|
150
150
|
over interval syntax, so `2000-20??` becomes the pattern `2000-20__`.
|
|
151
151
|
|
|
152
|
+
`empty` is an alias for `!?*`; `!empty`, `!=empty` and `<>empty` mean `?*` (a non-empty value).
|
|
153
|
+
The alias accepts the current language's translation through `trReverse()`, for example `vide` and `!vide` in French.
|
|
154
|
+
Alias matching ignores case and surrounding spaces. Use `=empty` or `=vide` to match the literal word.
|
|
155
|
+
For dates, these aliases use the existing empty (`!?`) and non-empty (`?`) date criteria.
|
|
156
|
+
|
|
152
157
|
Without an operator, wildcard or hyphen, text properties use prefix matching (`Alice` becomes `LIKE 'Alice%'`).
|
|
153
158
|
Other property types retain equality. The type of nested properties is resolved from the final property.
|
|
154
159
|
Any later hyphens in an interval remain part of the upper bound.
|
|
155
160
|
The original text stays in the input and session; feed requests reconstruct the same criterion from session state.
|
|
156
161
|
The data source converts the bounds according to the property's type.
|
|
157
162
|
|
|
163
|
+
### Logical expressions
|
|
164
|
+
|
|
165
|
+
Each column accepts several criteria separated by `,` or `|` for `OR`, and `&` or `+` for `AND`.
|
|
166
|
+
`AND` takes precedence over `OR`; parentheses override this order and can nest.
|
|
167
|
+
Every leaf retains the comparison, interval, date and wildcard rules above.
|
|
168
|
+
|
|
169
|
+
- `Alice, Bob` searches either text prefix.
|
|
170
|
+
- `>=2000 & <2010 | =1984` means `(>=2000 AND <2010) OR =1984`.
|
|
171
|
+
- `(Alice | Bob) & !*test*` requires either prefix and excludes the `test` pattern.
|
|
172
|
+
- `2020 | (2021-2022 & !06/2021)` combines date periods and exclusions.
|
|
173
|
+
|
|
174
|
+
Double quotes or a backslash protect logical separators and parentheses: `"Rock & Roll"`, `Paris\, Texas`
|
|
175
|
+
and `"Alien (Director's Cut)"` are single criteria. `\"` protects a double quote and `\\` protects a backslash.
|
|
176
|
+
Apostrophes remain ordinary characters. Quoting protects the expression grammar; use `=` for exact comparison,
|
|
177
|
+
for example `="Paris, Texas"`. Spaces around operators and parentheses are ignored; spaces within a criterion remain.
|
|
178
|
+
When constructing query URLs manually, encode the plus operator as `%2B` because an unencoded `+` means a space.
|
|
179
|
+
|
|
180
|
+
A missing criterion, unmatched parenthesis or unclosed quote matches no rows. The complete original input remains
|
|
181
|
+
in the field and session, including invalid expressions; subsequent feed requests rebuild the same query.
|
|
182
|
+
|
|
158
183
|
### Object filters
|
|
159
184
|
|
|
160
185
|
A filter on an object column searches every `representativeOf()` property of its target type with `OR`.
|
|
161
186
|
This applies to singular objects and collections. For example, `Movie.genres` with `Genre` represented by `name`
|
|
162
187
|
searches `genres.name`. Text representatives use the same prefix, comparison, interval and wildcard rules as direct
|
|
163
188
|
text columns. Nested object representatives are expanded recursively; cyclic representations reject.
|
|
189
|
+
An expression applies each leaf to the target's representatives, then combines those searches with its operators.
|
|
190
|
+
For example, `Comédie & Drame` on `Movie.genres` requires both genres, which may be different collection elements.
|
|
191
|
+
`(Comédie | Drame) & Action` requires Action and at least one of the first two genres.
|
|
164
192
|
Separate column filters remain combined with `AND`. Original input is retained in session.
|
|
165
193
|
Logical criteria retain mandatory application scopes and authorisation checks on every expanded property path.
|
|
166
194
|
|
package/cjs/filter.js
CHANGED
|
@@ -14,18 +14,59 @@ const sql_functions_8 = require("@itrocks/sql-functions");
|
|
|
14
14
|
const sql_functions_9 = require("@itrocks/sql-functions");
|
|
15
15
|
const sql_functions_10 = require("@itrocks/sql-functions");
|
|
16
16
|
const sql_functions_11 = require("@itrocks/sql-functions");
|
|
17
|
+
const sql_functions_12 = require("@itrocks/sql-functions");
|
|
18
|
+
const sql_functions_13 = require("@itrocks/sql-functions");
|
|
19
|
+
const translate_1 = require("@itrocks/translate");
|
|
17
20
|
const date_search_1 = require("./date-search");
|
|
18
21
|
const parameter_1 = require("./parameter");
|
|
22
|
+
const search_expression_1 = require("./search-expression");
|
|
19
23
|
const operators = {
|
|
20
|
-
'!':
|
|
21
|
-
'!=':
|
|
22
|
-
'<':
|
|
23
|
-
'<=':
|
|
24
|
-
'<>':
|
|
25
|
-
'=':
|
|
26
|
-
'>':
|
|
27
|
-
'>=':
|
|
24
|
+
'!': sql_functions_11.notEqual,
|
|
25
|
+
'!=': sql_functions_11.notEqual,
|
|
26
|
+
'<': sql_functions_8.less,
|
|
27
|
+
'<=': sql_functions_9.lessOrEqual,
|
|
28
|
+
'<>': sql_functions_11.notEqual,
|
|
29
|
+
'=': sql_functions_5.equal,
|
|
30
|
+
'>': sql_functions_6.greater,
|
|
31
|
+
'>=': sql_functions_7.greaterOrEqual
|
|
28
32
|
};
|
|
33
|
+
function searchValue(propertyType, expression) {
|
|
34
|
+
if (!('value' in expression)) {
|
|
35
|
+
const combine = (expression.operator === 'AND') ? sql_functions_3.and : sql_functions_13.or;
|
|
36
|
+
return combine(...expression.operands.map(operand => searchValue(propertyType, operand) ?? (0, sql_functions_13.or)()));
|
|
37
|
+
}
|
|
38
|
+
let value = expression.value;
|
|
39
|
+
const alias = value.trim().match(/^(!=|<>|!)?\s*(.+)$/s);
|
|
40
|
+
if (alias && ((0, translate_1.trReverse)(alias[2].toLowerCase()) === 'empty')) {
|
|
41
|
+
value = (alias[1] ? '' : '!') + ((propertyType === Date) ? '?' : '?*');
|
|
42
|
+
}
|
|
43
|
+
const comparison = value.match(/^(>=|<=|<>|!=|>|<|=|!)(.*)$/s);
|
|
44
|
+
const operator = comparison ? operators[comparison[1]] : undefined;
|
|
45
|
+
const operand = comparison ? comparison[2].trim() : value;
|
|
46
|
+
if (propertyType === Date) {
|
|
47
|
+
return (0, date_search_1.dateSearch)(operand, comparison?.[1]);
|
|
48
|
+
}
|
|
49
|
+
if (/[*?]/.test(operand) && (!operator || operator === sql_functions_11.notEqual)) {
|
|
50
|
+
const compare = operator ? sql_functions_12.notLike : sql_functions_10.like;
|
|
51
|
+
return compare(operand.replaceAll('*', '%').replaceAll('?', '_'));
|
|
52
|
+
}
|
|
53
|
+
if (operator) {
|
|
54
|
+
return operator(operand);
|
|
55
|
+
}
|
|
56
|
+
const separator = value.indexOf('-');
|
|
57
|
+
if (separator < 0) {
|
|
58
|
+
const text = (propertyType === String);
|
|
59
|
+
return (text ? (0, sql_functions_10.like)(value + '%') : value);
|
|
60
|
+
}
|
|
61
|
+
const lower = value.slice(0, separator).trim();
|
|
62
|
+
const upper = value.slice(separator + 1).trim();
|
|
63
|
+
if (lower && upper)
|
|
64
|
+
return (0, sql_functions_4.between)(lower, upper);
|
|
65
|
+
if (lower)
|
|
66
|
+
return (0, sql_functions_7.greaterOrEqual)(lower);
|
|
67
|
+
if (upper)
|
|
68
|
+
return (0, sql_functions_9.lessOrEqual)(upper);
|
|
69
|
+
}
|
|
29
70
|
class Filter extends parameter_1.Parameter {
|
|
30
71
|
columns;
|
|
31
72
|
search = {};
|
|
@@ -68,62 +109,47 @@ class Filter extends parameter_1.Parameter {
|
|
|
68
109
|
searchObject(type) {
|
|
69
110
|
const search = {};
|
|
70
111
|
const groups = [];
|
|
71
|
-
const expand = (property,
|
|
112
|
+
const expand = (property, expression, ancestors = []) => {
|
|
72
113
|
const resolved = (0, reflect_path_1.resolvePropertyPath)(type, property);
|
|
73
114
|
if (!resolved.target) {
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
115
|
+
const value = searchValue(resolved.property.type.type, expression);
|
|
116
|
+
return { [property]: value ?? (0, sql_functions_13.or)() };
|
|
117
|
+
}
|
|
118
|
+
if (!('value' in expression)) {
|
|
119
|
+
const operator = (expression.operator === 'AND') ? sql_functions_1.AND : sql_functions_2.OR;
|
|
120
|
+
return { [operator]: expression.operands.map(operand => expand(property, operand, ancestors)) };
|
|
77
121
|
}
|
|
78
122
|
if (ancestors.includes(resolved.target))
|
|
79
123
|
throw new Error(`Cyclic search representation: ${property}`);
|
|
80
124
|
const branch = [...ancestors, resolved.target];
|
|
81
125
|
return {
|
|
82
|
-
[sql_functions_2.OR]: (0, class_view_1.representativeOf)(resolved.target).map(name => expand(`${property}.${String(name)}`,
|
|
126
|
+
[sql_functions_2.OR]: (0, class_view_1.representativeOf)(resolved.target).map(name => expand(`${property}.${String(name)}`, expression, branch))
|
|
83
127
|
};
|
|
84
128
|
};
|
|
85
129
|
for (const [property, value] of Object.entries(this.search)) {
|
|
86
130
|
if (value === '')
|
|
87
131
|
continue;
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
}
|
|
92
|
-
const comparison = value.match(/^(>=|<=|<>|!=|>|<|=|!)(.*)$/s);
|
|
93
|
-
const operator = comparison ? operators[comparison[1]] : undefined;
|
|
94
|
-
const operand = comparison ? comparison[2].trim() : value;
|
|
95
|
-
const propertyType = (0, reflect_path_1.resolvePropertyPath)(type, property).property.type.type;
|
|
96
|
-
if (propertyType === Date) {
|
|
97
|
-
search[property] = (0, date_search_1.dateSearch)(operand, comparison?.[1]);
|
|
98
|
-
continue;
|
|
99
|
-
}
|
|
100
|
-
if (/[*?]/.test(operand) && (!operator || operator === sql_functions_10.notEqual)) {
|
|
101
|
-
const compare = operator ? sql_functions_11.notLike : sql_functions_9.like;
|
|
102
|
-
search[property] = compare(operand.replaceAll('*', '%').replaceAll('?', '_'));
|
|
103
|
-
continue;
|
|
132
|
+
let expression;
|
|
133
|
+
try {
|
|
134
|
+
expression = (0, search_expression_1.searchExpression)(value);
|
|
104
135
|
}
|
|
105
|
-
|
|
106
|
-
|
|
136
|
+
catch (error) {
|
|
137
|
+
if (!(error instanceof SyntaxError))
|
|
138
|
+
throw error;
|
|
139
|
+
search[property] = (0, sql_functions_13.or)();
|
|
107
140
|
continue;
|
|
108
141
|
}
|
|
109
|
-
const
|
|
110
|
-
if (
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
142
|
+
const resolved = (0, reflect_path_1.resolvePropertyPath)(type, property);
|
|
143
|
+
if (resolved.target)
|
|
144
|
+
groups.push(expand(property, expression));
|
|
145
|
+
else {
|
|
146
|
+
const criterion = searchValue(resolved.property.type.type, expression);
|
|
147
|
+
if (criterion !== undefined)
|
|
148
|
+
search[property] = criterion;
|
|
114
149
|
}
|
|
115
|
-
const lower = value.slice(0, separator).trim();
|
|
116
|
-
const upper = value.slice(separator + 1).trim();
|
|
117
|
-
if (lower && upper)
|
|
118
|
-
search[property] = (0, sql_functions_3.between)(lower, upper);
|
|
119
|
-
else if (lower)
|
|
120
|
-
search[property] = (0, sql_functions_6.greaterOrEqual)(lower);
|
|
121
|
-
else if (upper)
|
|
122
|
-
search[property] = (0, sql_functions_8.lessOrEqual)(upper);
|
|
123
150
|
}
|
|
124
|
-
if (groups.length)
|
|
151
|
+
if (groups.length)
|
|
125
152
|
search[sql_functions_1.AND] = groups;
|
|
126
|
-
}
|
|
127
153
|
return Object.setPrototypeOf(search, type.prototype);
|
|
128
154
|
}
|
|
129
155
|
serialize() {
|
package/cjs/filter.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filter.js","sourceRoot":"","sources":["../src/filter.ts"],"names":[],"mappings":";;;AACA,oDAAyD;AACzD,wDAA2D;AAE3D,0DAA4D;AAC5D,0DAA4D;AAC5D,0DAA4D;AAC5D,0DAA4D;AAC5D,0DAA4D;AAC5D,0DAA4D;AAC5D,0DAA4D;AAC5D,0DAA4D;AAC5D,0DAA4D;AAC5D,2DAA4D;AAC5D,2DAA4D;
|
|
1
|
+
{"version":3,"file":"filter.js","sourceRoot":"","sources":["../src/filter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.searchExpression = searchExpression;
|
|
4
|
+
function searchExpression(input) {
|
|
5
|
+
// Preserve ordinary input exactly, including spaces used by existing scalar criteria.
|
|
6
|
+
if (!/[,|&+()"\\]/.test(input))
|
|
7
|
+
return { value: input };
|
|
8
|
+
return new SearchParser(input).parse();
|
|
9
|
+
}
|
|
10
|
+
class SearchParser {
|
|
11
|
+
input;
|
|
12
|
+
position = 0;
|
|
13
|
+
constructor(input) {
|
|
14
|
+
this.input = input;
|
|
15
|
+
}
|
|
16
|
+
and() {
|
|
17
|
+
const operands = [this.primary()];
|
|
18
|
+
while (this.take('&+'))
|
|
19
|
+
operands.push(this.primary());
|
|
20
|
+
return (operands.length === 1) ? operands[0] : { operator: 'AND', operands };
|
|
21
|
+
}
|
|
22
|
+
fail(message) {
|
|
23
|
+
throw new SyntaxError(`${message} at position ${this.position + 1}`);
|
|
24
|
+
}
|
|
25
|
+
or() {
|
|
26
|
+
const operands = [this.and()];
|
|
27
|
+
while (this.take(',|'))
|
|
28
|
+
operands.push(this.and());
|
|
29
|
+
return (operands.length === 1) ? operands[0] : { operator: 'OR', operands };
|
|
30
|
+
}
|
|
31
|
+
parse() {
|
|
32
|
+
const expression = this.or();
|
|
33
|
+
this.space();
|
|
34
|
+
if (this.position !== this.input.length)
|
|
35
|
+
this.fail('Unexpected character');
|
|
36
|
+
return expression;
|
|
37
|
+
}
|
|
38
|
+
primary() {
|
|
39
|
+
if (this.take('(')) {
|
|
40
|
+
const expression = this.or();
|
|
41
|
+
if (!this.take(')')) {
|
|
42
|
+
this.fail('Missing closing parenthesis');
|
|
43
|
+
}
|
|
44
|
+
return expression;
|
|
45
|
+
}
|
|
46
|
+
let value = '';
|
|
47
|
+
let length = 0;
|
|
48
|
+
let quoted = false;
|
|
49
|
+
let seen = false;
|
|
50
|
+
while (this.position < this.input.length) {
|
|
51
|
+
const character = this.input[this.position];
|
|
52
|
+
if (!quoted && ',|&+()'.includes(character))
|
|
53
|
+
break;
|
|
54
|
+
this.position++;
|
|
55
|
+
if ((character === '\\')
|
|
56
|
+
&& (this.position < this.input.length)
|
|
57
|
+
&& ',|&+()"\\'.includes(this.input[this.position])) {
|
|
58
|
+
value += this.input[this.position++];
|
|
59
|
+
length = value.length;
|
|
60
|
+
seen = true;
|
|
61
|
+
}
|
|
62
|
+
else if (character === '"') {
|
|
63
|
+
quoted = !quoted;
|
|
64
|
+
seen = true;
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
value += character;
|
|
68
|
+
if (quoted || character.trim())
|
|
69
|
+
length = value.length;
|
|
70
|
+
seen ||= !!character.trim();
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (quoted)
|
|
74
|
+
this.fail('Unclosed quote');
|
|
75
|
+
if (!seen)
|
|
76
|
+
this.fail('Missing criterion');
|
|
77
|
+
return { value: value.slice(0, length) };
|
|
78
|
+
}
|
|
79
|
+
space() {
|
|
80
|
+
while ((this.position < this.input.length) && /\s/.test(this.input[this.position])) {
|
|
81
|
+
this.position++;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
take(characters) {
|
|
85
|
+
this.space();
|
|
86
|
+
if ((this.position === this.input.length) || !characters.includes(this.input[this.position])) {
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
this.position++;
|
|
90
|
+
return true;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=search-expression.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-expression.js","sourceRoot":"","sources":["../src/search-expression.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED