@opra/common 1.0.1 → 1.0.3
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/browser/index.cjs +4 -4
- package/browser/index.mjs +4 -4
- package/cjs/filter/filter-rules.js +50 -21
- package/cjs/polifils/array-find-last.js +24 -0
- package/esm/filter/filter-rules.js +50 -21
- package/esm/polifils/array-find-last.js +23 -0
- package/package.json +1 -1
- package/types/filter/filter-rules.d.ts +2 -1
- package/types/polifils/array-find-last.d.ts +8 -0
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.FilterRules = void 0;
|
|
4
|
+
require("../polifils/array-find-last.js");
|
|
5
|
+
const valgen_1 = require("valgen");
|
|
4
6
|
const index_js_1 = require("../exception/index.js");
|
|
5
7
|
const index_js_2 = require("../helpers/index.js");
|
|
6
8
|
const index_js_3 = require("../i18n/index.js");
|
|
@@ -31,11 +33,12 @@ class FilterRules {
|
|
|
31
33
|
}
|
|
32
34
|
normalizeFilter(filter, currentType) {
|
|
33
35
|
const ast = typeof filter === 'string' ? (0, parse_js_1.parse)(filter) : filter;
|
|
34
|
-
return this.normalizeFilterAst(ast, currentType);
|
|
36
|
+
return this.normalizeFilterAst(ast, [], currentType);
|
|
35
37
|
}
|
|
36
|
-
normalizeFilterAst(ast,
|
|
38
|
+
normalizeFilterAst(ast, stack, currentType) {
|
|
37
39
|
if (ast instanceof index_js_4.ComparisonExpression) {
|
|
38
|
-
|
|
40
|
+
stack.push(ast);
|
|
41
|
+
this.normalizeFilterAst(ast.left, stack, currentType);
|
|
39
42
|
if (!(ast.left instanceof index_js_4.QualifiedIdentifier && ast.left.field)) {
|
|
40
43
|
throw new TypeError(`Invalid filter query. Left side should be a data field.`);
|
|
41
44
|
}
|
|
@@ -62,44 +65,70 @@ class FilterRules {
|
|
|
62
65
|
},
|
|
63
66
|
});
|
|
64
67
|
}
|
|
65
|
-
this.normalizeFilterAst(ast.right,
|
|
68
|
+
this.normalizeFilterAst(ast.right, stack, currentType);
|
|
69
|
+
stack.pop();
|
|
66
70
|
return ast;
|
|
67
71
|
}
|
|
68
72
|
if (ast instanceof index_js_4.LogicalExpression) {
|
|
69
|
-
|
|
73
|
+
stack.push(ast);
|
|
74
|
+
ast.items.forEach(item => this.normalizeFilterAst(item, stack, currentType));
|
|
75
|
+
stack.pop();
|
|
70
76
|
return ast;
|
|
71
77
|
}
|
|
72
78
|
if (ast instanceof index_js_4.ArithmeticExpression) {
|
|
73
|
-
|
|
79
|
+
stack.push(ast);
|
|
80
|
+
ast.items.forEach(item => this.normalizeFilterAst(item.expression, stack, currentType));
|
|
81
|
+
stack.pop();
|
|
74
82
|
return ast;
|
|
75
83
|
}
|
|
76
84
|
if (ast instanceof index_js_4.ArrayExpression) {
|
|
77
|
-
|
|
85
|
+
stack.push(ast);
|
|
86
|
+
ast.items.forEach(item => this.normalizeFilterAst(item, stack, currentType));
|
|
87
|
+
stack.pop();
|
|
78
88
|
return ast;
|
|
79
89
|
}
|
|
80
90
|
if (ast instanceof index_js_4.ParenthesizedExpression) {
|
|
81
|
-
|
|
91
|
+
stack.push(ast);
|
|
92
|
+
this.normalizeFilterAst(ast.expression, stack, currentType);
|
|
93
|
+
stack.pop();
|
|
82
94
|
return ast;
|
|
83
95
|
}
|
|
84
96
|
if (ast instanceof index_js_4.QualifiedIdentifier && currentType) {
|
|
85
97
|
ast.value = currentType.normalizeFieldPath(ast.value);
|
|
86
98
|
ast.field = currentType.getField(ast.value);
|
|
87
99
|
ast.dataType = ast.field.type;
|
|
100
|
+
return ast;
|
|
88
101
|
}
|
|
89
|
-
if (ast instanceof index_js_4.Literal
|
|
90
|
-
if
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
102
|
+
if (ast instanceof index_js_4.Literal) {
|
|
103
|
+
/** Check if comparison expression has in stack */
|
|
104
|
+
const compIdx = stack.findLastIndex(x => x instanceof index_js_4.ComparisonExpression);
|
|
105
|
+
if (compIdx >= 0) {
|
|
106
|
+
const comp = stack[compIdx];
|
|
107
|
+
/** If calling for right side of comparison */
|
|
108
|
+
if (ast === comp.right || stack[compIdx + 1] === comp.right) {
|
|
109
|
+
/** Check if comparison expression left side is a field */
|
|
110
|
+
if (comp && comp.left instanceof index_js_4.QualifiedIdentifier && comp.left.field) {
|
|
111
|
+
if (ast.value == null && !comp.left.field.required)
|
|
112
|
+
return ast.value;
|
|
113
|
+
let decoder;
|
|
114
|
+
if (comp.op === 'like' || comp.op === '!like' || comp.op === 'ilike' || comp.op === '!ilike') {
|
|
115
|
+
decoder = valgen_1.isString;
|
|
116
|
+
}
|
|
117
|
+
else
|
|
118
|
+
decoder = this._decoderCache.get(comp.left.field);
|
|
119
|
+
if (!decoder) {
|
|
120
|
+
decoder = comp.left.field.type.generateCodec('decode', {
|
|
121
|
+
projection: '*',
|
|
122
|
+
ignoreWriteonlyFields: true,
|
|
123
|
+
ignoreHiddenFields: true,
|
|
124
|
+
coerce: true,
|
|
125
|
+
});
|
|
126
|
+
this._decoderCache.set(comp.left.field, decoder);
|
|
127
|
+
}
|
|
128
|
+
ast.value = decoder(ast.value);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
101
131
|
}
|
|
102
|
-
ast.value = decoder(ast.value);
|
|
103
132
|
}
|
|
104
133
|
return ast;
|
|
105
134
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
if (!Array.prototype.findLast) {
|
|
4
|
+
// eslint-disable-next-line no-extend-native
|
|
5
|
+
Array.prototype.findLast = function (predicate, thisArg) {
|
|
6
|
+
const i = this.findLastIndex(predicate, thisArg);
|
|
7
|
+
return i >= 0 ? this[i] : undefined;
|
|
8
|
+
};
|
|
9
|
+
// eslint-disable-next-line no-extend-native
|
|
10
|
+
Array.prototype.findLastIndex = function (predicate, thisArg) {
|
|
11
|
+
if (this == null) {
|
|
12
|
+
throw new TypeError('this is null or not defined');
|
|
13
|
+
}
|
|
14
|
+
const arr = Object(this);
|
|
15
|
+
const len = this.length;
|
|
16
|
+
thisArg = thisArg || this;
|
|
17
|
+
for (let i = len - 1; i >= 0; i--) {
|
|
18
|
+
if (predicate.call(thisArg, arr[i], i, arr)) {
|
|
19
|
+
return i;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return -1;
|
|
23
|
+
};
|
|
24
|
+
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import '../polifils/array-find-last.js';
|
|
2
|
+
import { isString } from 'valgen';
|
|
1
3
|
import { OpraException } from '../exception/index.js';
|
|
2
4
|
import { omitUndefined, ResponsiveMap } from '../helpers/index.js';
|
|
3
5
|
import { translate } from '../i18n/index.js';
|
|
@@ -28,11 +30,12 @@ export class FilterRules {
|
|
|
28
30
|
}
|
|
29
31
|
normalizeFilter(filter, currentType) {
|
|
30
32
|
const ast = typeof filter === 'string' ? parse(filter) : filter;
|
|
31
|
-
return this.normalizeFilterAst(ast, currentType);
|
|
33
|
+
return this.normalizeFilterAst(ast, [], currentType);
|
|
32
34
|
}
|
|
33
|
-
normalizeFilterAst(ast,
|
|
35
|
+
normalizeFilterAst(ast, stack, currentType) {
|
|
34
36
|
if (ast instanceof ComparisonExpression) {
|
|
35
|
-
|
|
37
|
+
stack.push(ast);
|
|
38
|
+
this.normalizeFilterAst(ast.left, stack, currentType);
|
|
36
39
|
if (!(ast.left instanceof QualifiedIdentifier && ast.left.field)) {
|
|
37
40
|
throw new TypeError(`Invalid filter query. Left side should be a data field.`);
|
|
38
41
|
}
|
|
@@ -59,44 +62,70 @@ export class FilterRules {
|
|
|
59
62
|
},
|
|
60
63
|
});
|
|
61
64
|
}
|
|
62
|
-
this.normalizeFilterAst(ast.right,
|
|
65
|
+
this.normalizeFilterAst(ast.right, stack, currentType);
|
|
66
|
+
stack.pop();
|
|
63
67
|
return ast;
|
|
64
68
|
}
|
|
65
69
|
if (ast instanceof LogicalExpression) {
|
|
66
|
-
|
|
70
|
+
stack.push(ast);
|
|
71
|
+
ast.items.forEach(item => this.normalizeFilterAst(item, stack, currentType));
|
|
72
|
+
stack.pop();
|
|
67
73
|
return ast;
|
|
68
74
|
}
|
|
69
75
|
if (ast instanceof ArithmeticExpression) {
|
|
70
|
-
|
|
76
|
+
stack.push(ast);
|
|
77
|
+
ast.items.forEach(item => this.normalizeFilterAst(item.expression, stack, currentType));
|
|
78
|
+
stack.pop();
|
|
71
79
|
return ast;
|
|
72
80
|
}
|
|
73
81
|
if (ast instanceof ArrayExpression) {
|
|
74
|
-
|
|
82
|
+
stack.push(ast);
|
|
83
|
+
ast.items.forEach(item => this.normalizeFilterAst(item, stack, currentType));
|
|
84
|
+
stack.pop();
|
|
75
85
|
return ast;
|
|
76
86
|
}
|
|
77
87
|
if (ast instanceof ParenthesizedExpression) {
|
|
78
|
-
|
|
88
|
+
stack.push(ast);
|
|
89
|
+
this.normalizeFilterAst(ast.expression, stack, currentType);
|
|
90
|
+
stack.pop();
|
|
79
91
|
return ast;
|
|
80
92
|
}
|
|
81
93
|
if (ast instanceof QualifiedIdentifier && currentType) {
|
|
82
94
|
ast.value = currentType.normalizeFieldPath(ast.value);
|
|
83
95
|
ast.field = currentType.getField(ast.value);
|
|
84
96
|
ast.dataType = ast.field.type;
|
|
97
|
+
return ast;
|
|
85
98
|
}
|
|
86
|
-
if (ast instanceof Literal
|
|
87
|
-
if
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
99
|
+
if (ast instanceof Literal) {
|
|
100
|
+
/** Check if comparison expression has in stack */
|
|
101
|
+
const compIdx = stack.findLastIndex(x => x instanceof ComparisonExpression);
|
|
102
|
+
if (compIdx >= 0) {
|
|
103
|
+
const comp = stack[compIdx];
|
|
104
|
+
/** If calling for right side of comparison */
|
|
105
|
+
if (ast === comp.right || stack[compIdx + 1] === comp.right) {
|
|
106
|
+
/** Check if comparison expression left side is a field */
|
|
107
|
+
if (comp && comp.left instanceof QualifiedIdentifier && comp.left.field) {
|
|
108
|
+
if (ast.value == null && !comp.left.field.required)
|
|
109
|
+
return ast.value;
|
|
110
|
+
let decoder;
|
|
111
|
+
if (comp.op === 'like' || comp.op === '!like' || comp.op === 'ilike' || comp.op === '!ilike') {
|
|
112
|
+
decoder = isString;
|
|
113
|
+
}
|
|
114
|
+
else
|
|
115
|
+
decoder = this._decoderCache.get(comp.left.field);
|
|
116
|
+
if (!decoder) {
|
|
117
|
+
decoder = comp.left.field.type.generateCodec('decode', {
|
|
118
|
+
projection: '*',
|
|
119
|
+
ignoreWriteonlyFields: true,
|
|
120
|
+
ignoreHiddenFields: true,
|
|
121
|
+
coerce: true,
|
|
122
|
+
});
|
|
123
|
+
this._decoderCache.set(comp.left.field, decoder);
|
|
124
|
+
}
|
|
125
|
+
ast.value = decoder(ast.value);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
98
128
|
}
|
|
99
|
-
ast.value = decoder(ast.value);
|
|
100
129
|
}
|
|
101
130
|
return ast;
|
|
102
131
|
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
if (!Array.prototype.findLast) {
|
|
2
|
+
// eslint-disable-next-line no-extend-native
|
|
3
|
+
Array.prototype.findLast = function (predicate, thisArg) {
|
|
4
|
+
const i = this.findLastIndex(predicate, thisArg);
|
|
5
|
+
return i >= 0 ? this[i] : undefined;
|
|
6
|
+
};
|
|
7
|
+
// eslint-disable-next-line no-extend-native
|
|
8
|
+
Array.prototype.findLastIndex = function (predicate, thisArg) {
|
|
9
|
+
if (this == null) {
|
|
10
|
+
throw new TypeError('this is null or not defined');
|
|
11
|
+
}
|
|
12
|
+
const arr = Object(this);
|
|
13
|
+
const len = this.length;
|
|
14
|
+
thisArg = thisArg || this;
|
|
15
|
+
for (let i = len - 1; i >= 0; i--) {
|
|
16
|
+
if (predicate.call(thisArg, arr[i], i, arr)) {
|
|
17
|
+
return i;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return -1;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import '../polifils/array-find-last.js';
|
|
1
2
|
import type { StrictOmit } from 'ts-gems';
|
|
2
3
|
import { Validator } from 'valgen';
|
|
3
4
|
import type { ComplexType } from '../document/index.js';
|
|
@@ -21,7 +22,7 @@ export declare class FilterRules {
|
|
|
21
22
|
operators?: ComparisonOperator[] | string;
|
|
22
23
|
}): void;
|
|
23
24
|
normalizeFilter(filter: OpraSchema.Field.QualifiedName | Expression, currentType?: ComplexType): Expression | undefined;
|
|
24
|
-
protected normalizeFilterAst(ast: Expression,
|
|
25
|
+
protected normalizeFilterAst(ast: Expression, stack: Expression[], currentType?: ComplexType): Expression | undefined;
|
|
25
26
|
toJSON(): Record<string, FilterRules.Rule>;
|
|
26
27
|
[Symbol.iterator](): IterableIterator<[string, FilterRules.Rule]>;
|
|
27
28
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export {};
|
|
2
|
+
declare global {
|
|
3
|
+
interface Array<T> {
|
|
4
|
+
findLast<S extends T>(predicate: (value: T, index: number, obj: T[]) => value is S, thisArg?: any): S | undefined;
|
|
5
|
+
findLast(predicate: (value: T, index: number, obj: T[]) => unknown, thisArg?: any): T | undefined;
|
|
6
|
+
findLastIndex(predicate: (value: T, index: number, obj: T[]) => unknown, thisArg?: any): number;
|
|
7
|
+
}
|
|
8
|
+
}
|