envio 3.12.0 → 3.12.1
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/package.json +6 -6
- package/src/ChainFetching.res +7 -3
- package/src/ChainFetching.res.mjs +1 -1
- package/src/ChainState.res +12 -3
- package/src/ChainState.res.mjs +3 -3
- package/src/ChainState.resi +1 -1
- package/src/CrossChainState.res +1 -1
- package/src/CrossChainState.res.mjs +1 -1
- package/src/FetchState.res +51 -46
- package/src/FetchState.res.mjs +54 -36
- package/src/InMemoryTable.res +155 -67
- package/src/InMemoryTable.res.mjs +151 -60
- package/src/LoadLayer.res +57 -34
- package/src/LoadLayer.res.mjs +45 -62
- package/src/LoadLayer.resi +1 -1
- package/src/PgStorage.res +92 -62
- package/src/PgStorage.res.mjs +77 -50
- package/src/TestIndexer.res +9 -25
- package/src/TestIndexer.res.mjs +4 -3
- package/src/UserContext.res +13 -32
- package/src/UserContext.res.mjs +1 -7
- package/src/Utils.res +1 -4
- package/src/Utils.res.mjs +7 -16
- package/src/db/EntityFilter.res +487 -275
- package/src/db/EntityFilter.res.mjs +557 -309
- package/src/db/Table.res +21 -6
- package/src/db/Table.res.mjs +13 -4
- package/src/sources/BlockStore.res +7 -2
- package/src/sources/EvmHyperSyncSource.res +2 -0
- package/src/sources/EvmHyperSyncSource.res.mjs +2 -2
- package/src/sources/FuelHyperSyncSource.res +1 -0
- package/src/sources/FuelHyperSyncSource.res.mjs +1 -1
- package/src/sources/HyperSync.res +4 -0
- package/src/sources/HyperSync.res.mjs +4 -2
- package/src/sources/HyperSync.resi +1 -0
- package/src/sources/HyperSyncClient.res +3 -0
- package/src/sources/HyperSyncSSE.res +1 -1
- package/src/sources/HyperSyncSSE.res.mjs +4 -10
- package/src/sources/RpcSource.res +1 -0
- package/src/sources/RpcSource.res.mjs +1 -1
- package/src/sources/SimulateSource.res +1 -0
- package/src/sources/SimulateSource.res.mjs +1 -1
- package/src/sources/Source.res +7 -0
- package/src/sources/SourceManager.res +4 -3
- package/src/sources/SourceManager.res.mjs +2 -2
- package/src/sources/SvmHyperSyncClient.res +5 -0
- package/src/sources/SvmHyperSyncSource.res +3 -0
- package/src/sources/SvmHyperSyncSource.res.mjs +4 -2
|
@@ -2,104 +2,48 @@
|
|
|
2
2
|
|
|
3
3
|
import * as Table from "./Table.res.mjs";
|
|
4
4
|
import * as Utils from "../Utils.res.mjs";
|
|
5
|
-
import * as
|
|
5
|
+
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
6
6
|
import * as Stdlib_JsError from "@rescript/runtime/lib/es6/Stdlib_JsError.js";
|
|
7
7
|
import * as Primitive_object from "@rescript/runtime/lib/es6/Primitive_object.js";
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
if (Array.isArray(tNonOptional)) {
|
|
11
|
-
return `[` + tNonOptional.map(toString).join(",") + `]`;
|
|
12
|
-
}
|
|
13
|
-
switch (typeof tNonOptional) {
|
|
14
|
-
case "string" :
|
|
15
|
-
return tNonOptional;
|
|
16
|
-
case "bigint" :
|
|
17
|
-
case "number" :
|
|
18
|
-
return tNonOptional.toString();
|
|
19
|
-
case "object" :
|
|
20
|
-
return tNonOptional.toString();
|
|
21
|
-
case "boolean" :
|
|
22
|
-
if (tNonOptional) {
|
|
23
|
-
return "true";
|
|
24
|
-
} else {
|
|
25
|
-
return "false";
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
}
|
|
9
|
+
let nullish = (v => v === undefined || v === null);
|
|
29
10
|
|
|
30
|
-
function
|
|
31
|
-
return
|
|
11
|
+
function asArray(v) {
|
|
12
|
+
return v;
|
|
32
13
|
}
|
|
33
14
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
return
|
|
38
|
-
|
|
39
|
-
return
|
|
40
|
-
|
|
41
|
-
|
|
15
|
+
let encodeValueKey = (v => {
|
|
16
|
+
if (v === null) return "z"
|
|
17
|
+
switch (typeof v) {
|
|
18
|
+
case "string": return "s" + v.length + ":" + v
|
|
19
|
+
case "number": { const s = "" + v; return "n" + s.length + ":" + s }
|
|
20
|
+
case "bigint": { const s = "" + v; return "g" + s.length + ":" + s }
|
|
21
|
+
case "boolean": return v ? "t" : "f"
|
|
22
|
+
case "undefined": return "u"
|
|
23
|
+
default: { const s = JSON.stringify(v); return "o" + s.length + ":" + s }
|
|
42
24
|
}
|
|
43
|
-
}
|
|
25
|
+
});
|
|
44
26
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
51
|
-
if (typeof a === "object" && !Array.isArray(a) && typeof b === "object" && !Array.isArray(b)) {
|
|
52
|
-
return bigDecimal(a, b);
|
|
53
|
-
} else {
|
|
54
|
-
return fallback(a, b);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
27
|
+
let isKeyable = (function isKeyable(v) {
|
|
28
|
+
if (typeof v !== "object" || v === null) return true
|
|
29
|
+
if (Array.isArray(v)) return v.every(isKeyable)
|
|
30
|
+
try { JSON.stringify(v); return true } catch { return false }
|
|
31
|
+
});
|
|
57
32
|
|
|
58
|
-
function
|
|
59
|
-
return
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
function gt(a, b) {
|
|
63
|
-
return compareWith(a, b, (prim0, prim1) => prim0.isGreaterThan(prim1), order => order > 0, Primitive_object.greaterthan);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
function lt(a, b) {
|
|
67
|
-
return compareWith(a, b, (prim0, prim1) => prim0.isLessThan(prim1), order => order < 0, Primitive_object.lessthan);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
let FieldValue = {
|
|
71
|
-
asBytes: asBytes,
|
|
72
|
-
toString: toString$1,
|
|
73
|
-
compareWith: compareWith,
|
|
74
|
-
eq: eq,
|
|
75
|
-
gt: gt,
|
|
76
|
-
lt: lt
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
function toString$2(filter) {
|
|
80
|
-
switch (filter.operator) {
|
|
81
|
-
case "=" :
|
|
82
|
-
return filter.fieldName + `:Eq:` + toString$1(filter.fieldValue);
|
|
83
|
-
case ">" :
|
|
84
|
-
return filter.fieldName + `:Gt:` + toString$1(filter.fieldValue);
|
|
85
|
-
case "<" :
|
|
86
|
-
return filter.fieldName + `:Lt:` + toString$1(filter.fieldValue);
|
|
87
|
-
case "in" :
|
|
88
|
-
return filter.fieldName + `:In:[` + filter.fieldValue.map(toString$1).join(",") + `]`;
|
|
89
|
-
case "and" :
|
|
90
|
-
return `And(` + filter.filters.map(toString$2).join(",") + `)`;
|
|
91
|
-
}
|
|
33
|
+
function entries(filter) {
|
|
34
|
+
return filter;
|
|
92
35
|
}
|
|
93
36
|
|
|
94
37
|
function valuesCount(filter) {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
}
|
|
38
|
+
let count = {
|
|
39
|
+
contents: 0
|
|
40
|
+
};
|
|
41
|
+
Utils.Dict.forEachWithKey(filter, (operators, param) => Utils.Dict.forEachWithKey(operators, (fieldValue, operator) => {
|
|
42
|
+
count.contents = count.contents + (
|
|
43
|
+
operator === "_in" ? fieldValue.length : 1
|
|
44
|
+
) | 0;
|
|
45
|
+
}));
|
|
46
|
+
return count.contents;
|
|
103
47
|
}
|
|
104
48
|
|
|
105
49
|
let codegenHelpMessage = `Rerun 'pnpm dev' to update generated code after schema.graphql changes.`;
|
|
@@ -119,12 +63,69 @@ function throwUnsupportedGetWhereValue(valueName, entityName, filterDisplay, hin
|
|
|
119
63
|
return Stdlib_JsError.throwWithMessage(`Invalid ` + valueName + ` value passed to context.` + entityName + `.getWhere(` + filterDisplay + `). Filtering by null or undefined values is not supported in getWhere.` + hint);
|
|
120
64
|
}
|
|
121
65
|
|
|
122
|
-
|
|
66
|
+
let isDate = (v => v instanceof Date);
|
|
67
|
+
|
|
68
|
+
function expectedValueType(field) {
|
|
69
|
+
let match = field.fieldType;
|
|
70
|
+
if (typeof match === "object") {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
switch (match) {
|
|
74
|
+
case "Bytea" :
|
|
75
|
+
return field.isArray ? "an array of Uint8Array" : "a Uint8Array";
|
|
76
|
+
case "Date" :
|
|
77
|
+
return field.isArray ? "an array of Date" : "a Date";
|
|
78
|
+
default:
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function keyUsesSerializer(field) {
|
|
84
|
+
let match = field.fieldType;
|
|
85
|
+
if (typeof match === "object") {
|
|
86
|
+
return match.type !== "BigDecimal";
|
|
87
|
+
}
|
|
88
|
+
switch (match) {
|
|
89
|
+
case "Bytea" :
|
|
90
|
+
case "Date" :
|
|
91
|
+
return false;
|
|
92
|
+
default:
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function matchesFieldType(value, field) {
|
|
98
|
+
let matchesScalar = value => {
|
|
99
|
+
let match = field.fieldType;
|
|
100
|
+
if (typeof match === "object") {
|
|
101
|
+
return true;
|
|
102
|
+
}
|
|
103
|
+
switch (match) {
|
|
104
|
+
case "Bytea" :
|
|
105
|
+
return Stdlib_Option.isSome(Utils.Bytes.asUint8Array(value));
|
|
106
|
+
case "Date" :
|
|
107
|
+
return isDate(value);
|
|
108
|
+
default:
|
|
109
|
+
return true;
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
if (field.isArray) {
|
|
113
|
+
if (Array.isArray(value)) {
|
|
114
|
+
return value.every(matchesScalar);
|
|
115
|
+
} else {
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
} else {
|
|
119
|
+
return matchesScalar(value);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function parseOrThrow(filter, entityName, table) {
|
|
123
124
|
let filterKeys = Object.keys(filter);
|
|
124
125
|
if (filterKeys.length === 0) {
|
|
125
126
|
Stdlib_JsError.throwWithMessage(`Empty filter passed to context.` + entityName + `.getWhere(). Please provide a filter like { fieldName: { _eq: value } }.`);
|
|
126
127
|
}
|
|
127
|
-
|
|
128
|
+
filterKeys.forEach(apiFieldName => {
|
|
128
129
|
let operatorObj = filter[apiFieldName];
|
|
129
130
|
let valueName = getUndefinedOrNullName(operatorObj);
|
|
130
131
|
if (valueName !== undefined) {
|
|
@@ -137,7 +138,6 @@ function parseGetWhereOrThrow(filter, entityName, table) {
|
|
|
137
138
|
if (operatorKeys.length === 0) {
|
|
138
139
|
Stdlib_JsError.throwWithMessage(`Empty operator passed to context.` + entityName + `.getWhere({ ` + apiFieldName + `: {} }). Please provide an operator like { _eq: value }, { _gt: value }, { _lt: value }, { _gte: value }, { _lte: value }, or { _in: [values] }.`);
|
|
139
140
|
}
|
|
140
|
-
let throwInvalidOperator = operatorKey => Stdlib_JsError.throwWithMessage(`Invalid operator "` + operatorKey + `" in context.` + entityName + `.getWhere({ ` + apiFieldName + `: { ` + operatorKey + `: ... } }). Valid operators are _eq, _gt, _lt, _gte, _lte, _in.`);
|
|
141
141
|
operatorKeys.forEach(operatorKey => {
|
|
142
142
|
switch (operatorKey) {
|
|
143
143
|
case "_eq" :
|
|
@@ -148,167 +148,108 @@ function parseGetWhereOrThrow(filter, entityName, table) {
|
|
|
148
148
|
case "_lte" :
|
|
149
149
|
return;
|
|
150
150
|
default:
|
|
151
|
-
return
|
|
151
|
+
return Stdlib_JsError.throwWithMessage(`Invalid operator "` + operatorKey + `" in context.` + entityName + `.getWhere({ ` + apiFieldName + `: { ` + operatorKey + `: ... } }). Valid operators are _eq, _gt, _lt, _gte, _lte, _in.`);
|
|
152
152
|
}
|
|
153
153
|
});
|
|
154
154
|
let match = Table.getFieldByApiName(table, apiFieldName);
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
}
|
|
162
|
-
return operatorKeys.map(operatorKey => {
|
|
155
|
+
let field = match !== undefined ? (
|
|
156
|
+
match.TAG === "Field" ? match._0 : Stdlib_JsError.throwWithMessage(`The field "` + apiFieldName + `" on entity "` + entityName + `" is a derived field and cannot be used in getWhere(). Use the source entity's indexed field instead.`)
|
|
157
|
+
) : Stdlib_JsError.throwWithMessage(`Invalid field "` + apiFieldName + `" in context.` + entityName + `.getWhere(). The field doesn't exist. ` + codegenHelpMessage);
|
|
158
|
+
let expectedType = expectedValueType(field);
|
|
159
|
+
let checkKeyable = keyUsesSerializer(field);
|
|
160
|
+
operatorKeys.forEach(operatorKey => {
|
|
163
161
|
let fieldValue = operatorObj[operatorKey];
|
|
164
162
|
let valueName = getUndefinedOrNullName(fieldValue);
|
|
165
163
|
if (valueName !== undefined) {
|
|
166
164
|
throwUnsupportedGetWhereValue(valueName, entityName, `{ ` + apiFieldName + `: { ` + operatorKey + `: ` + valueName + ` } }`, undefined);
|
|
167
165
|
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
fieldName: apiFieldName,
|
|
179
|
-
fieldValue: fieldValue
|
|
180
|
-
}];
|
|
181
|
-
case "_gte" :
|
|
182
|
-
return [
|
|
183
|
-
{
|
|
184
|
-
operator: "=",
|
|
185
|
-
fieldName: apiFieldName,
|
|
186
|
-
fieldValue: fieldValue
|
|
187
|
-
},
|
|
188
|
-
{
|
|
189
|
-
operator: ">",
|
|
190
|
-
fieldName: apiFieldName,
|
|
191
|
-
fieldValue: fieldValue
|
|
192
|
-
}
|
|
193
|
-
];
|
|
194
|
-
case "_in" :
|
|
195
|
-
if (!Array.isArray(fieldValue)) {
|
|
196
|
-
Stdlib_JsError.throwWithMessage(`Invalid value passed to context.` + entityName + `.getWhere({ ` + apiFieldName + `: { _in: ... } }). The _in operator expects an array of values.`);
|
|
166
|
+
let throwUnexpectedType = (typeName, hint) => Stdlib_JsError.throwWithMessage(`Invalid value passed to context.` + entityName + `.getWhere({ ` + apiFieldName + `: { ` + operatorKey + `: ... } }). The field "` + apiFieldName + `" expects ` + typeName + `.` + hint);
|
|
167
|
+
let throwUnkeyable = hint => Stdlib_JsError.throwWithMessage(`Invalid value passed to context.` + entityName + `.getWhere({ ` + apiFieldName + `: { ` + operatorKey + `: ... } }). The value can't be serialized, so it can't be used as a filter. An object holding a bigint, or a circular reference, is not supported.` + hint);
|
|
168
|
+
if (operatorKey === "_in") {
|
|
169
|
+
if (!Array.isArray(fieldValue)) {
|
|
170
|
+
Stdlib_JsError.throwWithMessage(`Invalid value passed to context.` + entityName + `.getWhere({ ` + apiFieldName + `: { _in: ... } }). The _in operator expects an array of values.`);
|
|
171
|
+
}
|
|
172
|
+
fieldValue.forEach((fieldValue, index) => {
|
|
173
|
+
let valueName = getUndefinedOrNullName(fieldValue);
|
|
174
|
+
if (valueName !== undefined) {
|
|
175
|
+
throwUnsupportedGetWhereValue(valueName, entityName, `{ ` + apiFieldName + `: { _in: [...] } }`, ` The ` + valueName + ` value is at index ` + index.toString() + ` of the _in array.`);
|
|
197
176
|
}
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
fieldName: apiFieldName,
|
|
213
|
-
fieldValue: fieldValue
|
|
214
|
-
}];
|
|
215
|
-
case "_lte" :
|
|
216
|
-
return [
|
|
217
|
-
{
|
|
218
|
-
operator: "=",
|
|
219
|
-
fieldName: apiFieldName,
|
|
220
|
-
fieldValue: fieldValue
|
|
221
|
-
},
|
|
222
|
-
{
|
|
223
|
-
operator: "<",
|
|
224
|
-
fieldName: apiFieldName,
|
|
225
|
-
fieldValue: fieldValue
|
|
226
|
-
}
|
|
227
|
-
];
|
|
228
|
-
default:
|
|
229
|
-
return throwInvalidOperator(operatorKey);
|
|
177
|
+
if (expectedType !== undefined && !matchesFieldType(fieldValue, field)) {
|
|
178
|
+
throwUnexpectedType(expectedType, ` The value is at index ` + index.toString() + ` of the _in array.`);
|
|
179
|
+
}
|
|
180
|
+
if (checkKeyable && !isKeyable(fieldValue)) {
|
|
181
|
+
return throwUnkeyable(` The value is at index ` + index.toString() + ` of the _in array.`);
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
if (expectedType !== undefined && !matchesFieldType(fieldValue, field)) {
|
|
187
|
+
throwUnexpectedType(expectedType, "");
|
|
188
|
+
}
|
|
189
|
+
if (checkKeyable && !isKeyable(fieldValue)) {
|
|
190
|
+
return throwUnkeyable("");
|
|
230
191
|
}
|
|
231
192
|
});
|
|
232
193
|
});
|
|
233
|
-
return
|
|
234
|
-
if (filters.length !== 1) {
|
|
235
|
-
return {
|
|
236
|
-
operator: "and",
|
|
237
|
-
filters: filters
|
|
238
|
-
};
|
|
239
|
-
} else {
|
|
240
|
-
return filters[0];
|
|
241
|
-
}
|
|
242
|
-
});
|
|
194
|
+
return filter;
|
|
243
195
|
}
|
|
244
196
|
|
|
245
|
-
function
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
case ">" :
|
|
251
|
-
paramsCount.contents = paramsCount.contents + 1 | 0;
|
|
252
|
-
return filter.fieldName + `: {_gt: $` + paramsCount.contents.toString() + `}`;
|
|
253
|
-
case "<" :
|
|
254
|
-
paramsCount.contents = paramsCount.contents + 1 | 0;
|
|
255
|
-
return filter.fieldName + `: {_lt: $` + paramsCount.contents.toString() + `}`;
|
|
256
|
-
case "in" :
|
|
257
|
-
paramsCount.contents = paramsCount.contents + 1 | 0;
|
|
258
|
-
return filter.fieldName + `: {_in: $` + paramsCount.contents.toString() + `}`;
|
|
259
|
-
case "and" :
|
|
260
|
-
let filters = filter.filters;
|
|
261
|
-
let acc = "";
|
|
262
|
-
for (let idx = 0, idx_finish = filters.length; idx < idx_finish; ++idx) {
|
|
263
|
-
let part = printOperationFilter(filters[idx], paramsCount);
|
|
264
|
-
acc = acc === "" ? part : acc + `, ` + part;
|
|
197
|
+
function byIds(ids) {
|
|
198
|
+
return Object.fromEntries([[
|
|
199
|
+
Table.idFieldName,
|
|
200
|
+
{
|
|
201
|
+
_in: ids
|
|
265
202
|
}
|
|
266
|
-
|
|
267
|
-
}
|
|
203
|
+
]]);
|
|
268
204
|
}
|
|
269
205
|
|
|
270
|
-
function
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
return entityName + `.getWhere({` + filter.fieldName + `: {_lt: $1}})`;
|
|
278
|
-
case "in" :
|
|
279
|
-
return entityName + `.getWhere({` + filter.fieldName + `: {_in: $1}})`;
|
|
280
|
-
case "and" :
|
|
281
|
-
return entityName + `.getWhere({` + printOperationFilter(filter, {
|
|
282
|
-
contents: 0
|
|
283
|
-
}) + `})`;
|
|
206
|
+
function scoped(filter, table, scope) {
|
|
207
|
+
let match = Table.getChainIdField(table);
|
|
208
|
+
if (scope === "crossChain") {
|
|
209
|
+
return filter;
|
|
210
|
+
}
|
|
211
|
+
if (match === undefined) {
|
|
212
|
+
return filter;
|
|
284
213
|
}
|
|
214
|
+
let scoped$1 = Utils.Dict.shallowCopy(filter);
|
|
215
|
+
scoped$1[match.fieldName] = {
|
|
216
|
+
_eq: scope
|
|
217
|
+
};
|
|
218
|
+
return scoped$1;
|
|
285
219
|
}
|
|
286
220
|
|
|
287
221
|
function getParams(filter) {
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
default:
|
|
306
|
-
return [filter.fieldValue];
|
|
222
|
+
let params = [];
|
|
223
|
+
Utils.Dict.forEachWithKey(filter, (operators, param) => Utils.Dict.forEachWithKey(operators, (fieldValue, param) => {
|
|
224
|
+
params.push(fieldValue);
|
|
225
|
+
}));
|
|
226
|
+
return params;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function asSingleOperator(filter) {
|
|
230
|
+
let match = Object.keys(filter);
|
|
231
|
+
if (match.length !== 1) {
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
let fieldName = match[0];
|
|
235
|
+
let operators = filter[fieldName];
|
|
236
|
+
let match$1 = Object.keys(operators);
|
|
237
|
+
if (match$1.length !== 1) {
|
|
238
|
+
return;
|
|
307
239
|
}
|
|
240
|
+
let operator = match$1[0];
|
|
241
|
+
return [
|
|
242
|
+
fieldName,
|
|
243
|
+
operator,
|
|
244
|
+
operators[operator]
|
|
245
|
+
];
|
|
308
246
|
}
|
|
309
247
|
|
|
310
248
|
function throwUnmergeable(filter) {
|
|
311
|
-
|
|
249
|
+
let match = asSingleOperator(filter);
|
|
250
|
+
return Stdlib_JsError.throwWithMessage(`Unexpected ` + (
|
|
251
|
+
match !== undefined ? match[1] : "composite"
|
|
252
|
+
) + ` filter in a merged batch. Filters batched into a single query must use the same operator and field.`);
|
|
312
253
|
}
|
|
313
254
|
|
|
314
255
|
function merge(filters) {
|
|
@@ -319,110 +260,417 @@ function merge(filters) {
|
|
|
319
260
|
if (len === 0) {
|
|
320
261
|
return filters;
|
|
321
262
|
}
|
|
322
|
-
let match = filters[0];
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
return throwUnmergeable(filter);
|
|
333
|
-
}
|
|
334
|
-
})
|
|
335
|
-
}];
|
|
336
|
-
case "in" :
|
|
337
|
-
return [{
|
|
338
|
-
operator: "in",
|
|
339
|
-
fieldName: match.fieldName,
|
|
340
|
-
fieldValue: filters.map(filter => {
|
|
341
|
-
if (filter.operator === "in") {
|
|
342
|
-
return filter.fieldValue;
|
|
343
|
-
} else {
|
|
344
|
-
return throwUnmergeable(filter);
|
|
345
|
-
}
|
|
346
|
-
}).flat()
|
|
347
|
-
}];
|
|
263
|
+
let match = asSingleOperator(filters[0]);
|
|
264
|
+
if (match === undefined) {
|
|
265
|
+
return filters;
|
|
266
|
+
}
|
|
267
|
+
let operator = match[1];
|
|
268
|
+
let fieldName = match[0];
|
|
269
|
+
switch (operator) {
|
|
270
|
+
case "_eq" :
|
|
271
|
+
case "_in" :
|
|
272
|
+
break;
|
|
348
273
|
default:
|
|
349
274
|
return filters;
|
|
350
275
|
}
|
|
276
|
+
let values = [];
|
|
277
|
+
filters.forEach(filter => {
|
|
278
|
+
let match = asSingleOperator(filter);
|
|
279
|
+
if (match === undefined) {
|
|
280
|
+
return throwUnmergeable(filter);
|
|
281
|
+
}
|
|
282
|
+
if (match[0] !== fieldName || match[1] !== operator) {
|
|
283
|
+
return throwUnmergeable(filter);
|
|
284
|
+
}
|
|
285
|
+
let fieldValue = match[2];
|
|
286
|
+
if (operator === "_in") {
|
|
287
|
+
fieldValue.forEach(value => {
|
|
288
|
+
values.push(value);
|
|
289
|
+
});
|
|
290
|
+
} else {
|
|
291
|
+
values.push(fieldValue);
|
|
292
|
+
}
|
|
293
|
+
});
|
|
294
|
+
return [Object.fromEntries([[
|
|
295
|
+
fieldName,
|
|
296
|
+
{
|
|
297
|
+
_in: values
|
|
298
|
+
}
|
|
299
|
+
]])];
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
function nativeEq(a, b) {
|
|
303
|
+
return a === b;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
let nativeGt = ((a, b) => a != null && a > b);
|
|
307
|
+
|
|
308
|
+
let nativeLt = ((a, b) => a != null && a < b);
|
|
309
|
+
|
|
310
|
+
function identityKey(v) {
|
|
311
|
+
return v;
|
|
351
312
|
}
|
|
352
313
|
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
let filters = filter.filters;
|
|
366
|
-
if (filters.length !== 0) {
|
|
367
|
-
return filters.every(filter => matches(filter, entity));
|
|
314
|
+
let native = {
|
|
315
|
+
eq: nativeEq,
|
|
316
|
+
gt: nativeGt,
|
|
317
|
+
lt: nativeLt,
|
|
318
|
+
key: identityKey
|
|
319
|
+
};
|
|
320
|
+
|
|
321
|
+
function nullSafe(compare) {
|
|
322
|
+
return {
|
|
323
|
+
eq: (a, b) => {
|
|
324
|
+
if (nullish(a)) {
|
|
325
|
+
return false;
|
|
368
326
|
} else {
|
|
369
|
-
return
|
|
327
|
+
return compare.eq(a, b);
|
|
370
328
|
}
|
|
329
|
+
},
|
|
330
|
+
gt: (a, b) => {
|
|
331
|
+
if (nullish(a)) {
|
|
332
|
+
return false;
|
|
333
|
+
} else {
|
|
334
|
+
return compare.gt(a, b);
|
|
335
|
+
}
|
|
336
|
+
},
|
|
337
|
+
lt: (a, b) => {
|
|
338
|
+
if (nullish(a)) {
|
|
339
|
+
return false;
|
|
340
|
+
} else {
|
|
341
|
+
return compare.lt(a, b);
|
|
342
|
+
}
|
|
343
|
+
},
|
|
344
|
+
key: compare.key
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
function asBigDecimal(v) {
|
|
349
|
+
return v;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
let bigDecimal = nullSafe({
|
|
353
|
+
eq: (a, b) => a.isEqualTo(b),
|
|
354
|
+
gt: (a, b) => a.isGreaterThan(b),
|
|
355
|
+
lt: (a, b) => a.isLessThan(b),
|
|
356
|
+
key: v => v.toString()
|
|
357
|
+
});
|
|
358
|
+
|
|
359
|
+
function getTime(v) {
|
|
360
|
+
return v.getTime();
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
let date = nullSafe({
|
|
364
|
+
eq: (a, b) => a.getTime() === b.getTime(),
|
|
365
|
+
gt: (a, b) => a.getTime() > b.getTime(),
|
|
366
|
+
lt: (a, b) => a.getTime() < b.getTime(),
|
|
367
|
+
key: v => v.getTime()
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
let json = nullSafe({
|
|
371
|
+
eq: Primitive_object.equal,
|
|
372
|
+
gt: Primitive_object.greaterthan,
|
|
373
|
+
lt: Primitive_object.lessthan,
|
|
374
|
+
key: v => JSON.stringify(v)
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
function asBytes(v) {
|
|
378
|
+
return v;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
let bytes = nullSafe({
|
|
382
|
+
eq: (a, b) => Utils.Bytes.compare(a, b) === 0,
|
|
383
|
+
gt: (a, b) => Utils.Bytes.compare(a, b) > 0,
|
|
384
|
+
lt: (a, b) => Utils.Bytes.compare(a, b) < 0,
|
|
385
|
+
key: v => Utils.Bytes.toHex(v)
|
|
386
|
+
});
|
|
387
|
+
|
|
388
|
+
function enum_(config) {
|
|
389
|
+
let ranks = {};
|
|
390
|
+
config.variants.forEach((variant, rank) => {
|
|
391
|
+
ranks[variant] = rank;
|
|
392
|
+
});
|
|
393
|
+
return {
|
|
394
|
+
eq: nativeEq,
|
|
395
|
+
gt: (a, b) => {
|
|
396
|
+
if (nullish(a)) {
|
|
397
|
+
return false;
|
|
398
|
+
} else {
|
|
399
|
+
return ranks[a] > ranks[b];
|
|
400
|
+
}
|
|
401
|
+
},
|
|
402
|
+
lt: (a, b) => {
|
|
403
|
+
if (nullish(a)) {
|
|
404
|
+
return false;
|
|
405
|
+
} else {
|
|
406
|
+
return ranks[a] < ranks[b];
|
|
407
|
+
}
|
|
408
|
+
},
|
|
409
|
+
key: identityKey
|
|
410
|
+
};
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
function scalarCompare(fieldType) {
|
|
414
|
+
if (typeof fieldType !== "object") {
|
|
415
|
+
switch (fieldType) {
|
|
416
|
+
case "Bytea" :
|
|
417
|
+
return bytes;
|
|
418
|
+
case "Json" :
|
|
419
|
+
return json;
|
|
420
|
+
case "Date" :
|
|
421
|
+
return date;
|
|
422
|
+
default:
|
|
423
|
+
return native;
|
|
424
|
+
}
|
|
425
|
+
} else {
|
|
426
|
+
switch (fieldType.type) {
|
|
427
|
+
case "BigDecimal" :
|
|
428
|
+
return bigDecimal;
|
|
429
|
+
case "Enum" :
|
|
430
|
+
return enum_(fieldType.config);
|
|
431
|
+
default:
|
|
432
|
+
return native;
|
|
433
|
+
}
|
|
371
434
|
}
|
|
372
435
|
}
|
|
373
436
|
|
|
374
|
-
function
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
return
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
437
|
+
function arrayCompare(element) {
|
|
438
|
+
let eq = (a, b) => {
|
|
439
|
+
let len = a.length;
|
|
440
|
+
if (len !== b.length) {
|
|
441
|
+
return false;
|
|
442
|
+
}
|
|
443
|
+
let _i = 0;
|
|
444
|
+
while (true) {
|
|
445
|
+
let i = _i;
|
|
446
|
+
if (i >= len) {
|
|
447
|
+
return true;
|
|
448
|
+
}
|
|
449
|
+
if (!element.eq(a[i], b[i])) {
|
|
450
|
+
return false;
|
|
451
|
+
}
|
|
452
|
+
_i = i + 1 | 0;
|
|
453
|
+
continue;
|
|
454
|
+
};
|
|
455
|
+
};
|
|
456
|
+
let order = gt => ((a, b) => {
|
|
457
|
+
let la = a.length;
|
|
458
|
+
let lb = b.length;
|
|
459
|
+
let len = la < lb ? la : lb;
|
|
460
|
+
let _i = 0;
|
|
461
|
+
while (true) {
|
|
462
|
+
let i = _i;
|
|
463
|
+
if (i >= len) {
|
|
464
|
+
if (gt) {
|
|
465
|
+
return la > lb;
|
|
466
|
+
} else {
|
|
467
|
+
return la < lb;
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
let x = a[i];
|
|
471
|
+
let y = b[i];
|
|
472
|
+
if (!element.eq(x, y)) {
|
|
473
|
+
if (gt) {
|
|
474
|
+
return element.gt(x, y);
|
|
475
|
+
} else {
|
|
476
|
+
return element.lt(x, y);
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
_i = i + 1 | 0;
|
|
480
|
+
continue;
|
|
481
|
+
};
|
|
482
|
+
});
|
|
483
|
+
return nullSafe({
|
|
484
|
+
eq: eq,
|
|
485
|
+
gt: order(true),
|
|
486
|
+
lt: order(false),
|
|
487
|
+
key: v => {
|
|
488
|
+
let key = {
|
|
489
|
+
contents: ""
|
|
408
490
|
};
|
|
491
|
+
v.forEach(item => {
|
|
492
|
+
key.contents = key.contents + encodeValueKey(element.key(item));
|
|
493
|
+
});
|
|
494
|
+
return key.contents;
|
|
495
|
+
}
|
|
496
|
+
});
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
let comparesByField = Utils.$$WeakMap.memoize(table => {
|
|
500
|
+
let compares = {};
|
|
501
|
+
table.fields.forEach(field => {
|
|
502
|
+
if (field.TAG !== "Field") {
|
|
503
|
+
return;
|
|
504
|
+
}
|
|
505
|
+
let field$1 = field._0;
|
|
506
|
+
let element = scalarCompare(field$1.fieldType);
|
|
507
|
+
compares[Table.getApiFieldName(field$1)] = field$1.isArray ? arrayCompare(element) : element;
|
|
508
|
+
});
|
|
509
|
+
return compares;
|
|
510
|
+
});
|
|
511
|
+
|
|
512
|
+
function fieldCompare(table, fieldName) {
|
|
513
|
+
let compare = comparesByField(table)[fieldName];
|
|
514
|
+
if (compare !== undefined) {
|
|
515
|
+
return compare;
|
|
516
|
+
} else {
|
|
517
|
+
return Stdlib_JsError.throwWithMessage(`Internal error: no comparator for the field "` + fieldName + `" on the table "` + table.tableName + `". A filter is parsed against its table before it reaches the in-memory matcher.`);
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
function makeValueKey(table, fieldName) {
|
|
522
|
+
return fieldCompare(table, fieldName).key;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
function toString(filter, table) {
|
|
526
|
+
let key = {
|
|
527
|
+
contents: ""
|
|
528
|
+
};
|
|
529
|
+
Utils.Dict.forEachWithKey(filter, (operators, fieldName) => {
|
|
530
|
+
let keyOf = fieldCompare(table, fieldName).key;
|
|
531
|
+
Utils.Dict.forEachWithKey(operators, (fieldValue, operator) => {
|
|
532
|
+
key.contents = key.contents + fieldName + operator;
|
|
533
|
+
if (operator === "_in") {
|
|
534
|
+
fieldValue.forEach(value => {
|
|
535
|
+
key.contents = key.contents + encodeValueKey(keyOf(value));
|
|
536
|
+
});
|
|
537
|
+
} else {
|
|
538
|
+
key.contents = key.contents + encodeValueKey(keyOf(fieldValue));
|
|
539
|
+
}
|
|
540
|
+
key.contents = key.contents + ";";
|
|
541
|
+
});
|
|
542
|
+
});
|
|
543
|
+
return key.contents;
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
function toOperationKey(filter, entityName) {
|
|
547
|
+
let params = {
|
|
548
|
+
contents: 0
|
|
549
|
+
};
|
|
550
|
+
let printed = {
|
|
551
|
+
contents: ""
|
|
552
|
+
};
|
|
553
|
+
Utils.Dict.forEachWithKey(filter, (operators, fieldName) => {
|
|
554
|
+
let ops = {
|
|
555
|
+
contents: ""
|
|
556
|
+
};
|
|
557
|
+
let loneEq = {
|
|
558
|
+
contents: false
|
|
559
|
+
};
|
|
560
|
+
Utils.Dict.forEachWithKey(operators, (param, operator) => {
|
|
561
|
+
params.contents = params.contents + 1 | 0;
|
|
562
|
+
let part = operator + `: $` + params.contents.toString();
|
|
563
|
+
loneEq.contents = ops.contents === "" && operator === "_eq";
|
|
564
|
+
ops.contents = ops.contents === "" ? part : ops.contents + ", " + part;
|
|
565
|
+
});
|
|
566
|
+
let part = loneEq.contents ? fieldName + `: $` + params.contents.toString() : fieldName + `: {` + ops.contents + `}`;
|
|
567
|
+
printed.contents = printed.contents === "" ? part : printed.contents + ", " + part;
|
|
568
|
+
});
|
|
569
|
+
return entityName + `.getWhere({` + printed.contents + `})`;
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
function makeMatcher(filter, table) {
|
|
573
|
+
let checks = [];
|
|
574
|
+
Utils.Dict.forEachWithKey(filter, (operators, fieldName) => {
|
|
575
|
+
let compare = fieldCompare(table, fieldName);
|
|
576
|
+
Utils.Dict.forEachWithKey(operators, (fieldValue, operator) => {
|
|
577
|
+
let check;
|
|
578
|
+
switch (operator) {
|
|
579
|
+
case "_eq" :
|
|
580
|
+
check = entity => compare.eq(entity[fieldName], fieldValue);
|
|
581
|
+
break;
|
|
582
|
+
case "_gt" :
|
|
583
|
+
check = entity => compare.gt(entity[fieldName], fieldValue);
|
|
584
|
+
break;
|
|
585
|
+
case "_gte" :
|
|
586
|
+
check = entity => {
|
|
587
|
+
let entityFieldValue = entity[fieldName];
|
|
588
|
+
if (compare.eq(entityFieldValue, fieldValue)) {
|
|
589
|
+
return true;
|
|
590
|
+
} else {
|
|
591
|
+
return compare.gt(entityFieldValue, fieldValue);
|
|
592
|
+
}
|
|
593
|
+
};
|
|
594
|
+
break;
|
|
595
|
+
case "_in" :
|
|
596
|
+
if (compare.eq === nativeEq) {
|
|
597
|
+
let set = new Set(fieldValue);
|
|
598
|
+
check = entity => set.has(entity[fieldName]);
|
|
599
|
+
} else {
|
|
600
|
+
check = entity => {
|
|
601
|
+
let entityFieldValue = entity[fieldName];
|
|
602
|
+
return fieldValue.some(candidate => compare.eq(entityFieldValue, candidate));
|
|
603
|
+
};
|
|
604
|
+
}
|
|
605
|
+
break;
|
|
606
|
+
case "_lt" :
|
|
607
|
+
check = entity => compare.lt(entity[fieldName], fieldValue);
|
|
608
|
+
break;
|
|
609
|
+
case "_lte" :
|
|
610
|
+
check = entity => {
|
|
611
|
+
let entityFieldValue = entity[fieldName];
|
|
612
|
+
if (compare.eq(entityFieldValue, fieldValue)) {
|
|
613
|
+
return true;
|
|
614
|
+
} else {
|
|
615
|
+
return compare.lt(entityFieldValue, fieldValue);
|
|
616
|
+
}
|
|
617
|
+
};
|
|
618
|
+
break;
|
|
619
|
+
default:
|
|
620
|
+
check = Stdlib_JsError.throwWithMessage(`Invalid operator "` + operator + `" in a getWhere filter. Valid operators are _eq, _gt, _lt, _gte, _lte, _in.`);
|
|
621
|
+
}
|
|
622
|
+
checks.push(check);
|
|
623
|
+
});
|
|
624
|
+
});
|
|
625
|
+
if (checks.length !== 1) {
|
|
626
|
+
return entity => checks.every(check => check(entity));
|
|
627
|
+
} else {
|
|
628
|
+
return checks[0];
|
|
409
629
|
}
|
|
410
630
|
}
|
|
411
631
|
|
|
412
632
|
export {
|
|
413
|
-
|
|
414
|
-
|
|
633
|
+
nullish,
|
|
634
|
+
asArray,
|
|
635
|
+
encodeValueKey,
|
|
636
|
+
isKeyable,
|
|
637
|
+
entries,
|
|
415
638
|
valuesCount,
|
|
416
639
|
codegenHelpMessage,
|
|
417
640
|
getUndefinedOrNullName,
|
|
418
641
|
throwUnsupportedGetWhereValue,
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
642
|
+
isDate,
|
|
643
|
+
expectedValueType,
|
|
644
|
+
keyUsesSerializer,
|
|
645
|
+
matchesFieldType,
|
|
646
|
+
parseOrThrow,
|
|
647
|
+
byIds,
|
|
648
|
+
scoped,
|
|
422
649
|
getParams,
|
|
650
|
+
asSingleOperator,
|
|
423
651
|
throwUnmergeable,
|
|
424
652
|
merge,
|
|
425
|
-
|
|
426
|
-
|
|
653
|
+
nativeEq,
|
|
654
|
+
nativeGt,
|
|
655
|
+
nativeLt,
|
|
656
|
+
identityKey,
|
|
657
|
+
native,
|
|
658
|
+
nullSafe,
|
|
659
|
+
asBigDecimal,
|
|
660
|
+
bigDecimal,
|
|
661
|
+
getTime,
|
|
662
|
+
date,
|
|
663
|
+
json,
|
|
664
|
+
asBytes,
|
|
665
|
+
bytes,
|
|
666
|
+
enum_,
|
|
667
|
+
scalarCompare,
|
|
668
|
+
arrayCompare,
|
|
669
|
+
comparesByField,
|
|
670
|
+
fieldCompare,
|
|
671
|
+
makeValueKey,
|
|
672
|
+
toString,
|
|
673
|
+
toOperationKey,
|
|
674
|
+
makeMatcher,
|
|
427
675
|
}
|
|
428
|
-
/*
|
|
676
|
+
/* bigDecimal Not a pure module */
|