@aws-amplify/datastore 4.7.6-api-v6-models.b3abc9b.0 → 5.0.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 +4 -0
- package/lib/authModeStrategies/defaultAuthStrategy.js +3 -2
- package/lib/authModeStrategies/index.js +3 -3
- package/lib/authModeStrategies/multiAuthStrategy.js +38 -53
- package/lib/datastore/datastore.d.ts +4 -5
- package/lib/datastore/datastore.js +929 -1284
- package/lib/index.d.ts +1 -1
- package/lib/index.js +26 -13
- package/lib/predicates/index.js +54 -69
- package/lib/predicates/next.d.ts +2 -2
- package/lib/predicates/next.js +313 -462
- package/lib/predicates/sort.js +24 -28
- package/lib/ssr/index.js +2 -2
- package/lib/storage/adapter/AsyncStorageAdapter.js +120 -342
- package/lib/storage/adapter/AsyncStorageDatabase.js +217 -421
- package/lib/storage/adapter/InMemoryStore.js +28 -51
- package/lib/storage/adapter/InMemoryStore.native.js +5 -3
- package/lib/storage/adapter/IndexedDBAdapter.js +466 -871
- package/lib/storage/adapter/StorageAdapterBase.js +180 -330
- package/lib/storage/adapter/getDefaultAdapter/index.js +8 -10
- package/lib/storage/adapter/getDefaultAdapter/index.native.js +5 -4
- package/lib/storage/adapter/index.js +0 -1
- package/lib/storage/relationship.js +177 -253
- package/lib/storage/storage.d.ts +4 -4
- package/lib/storage/storage.js +255 -433
- package/lib/sync/datastoreConnectivity.d.ts +2 -2
- package/lib/sync/datastoreConnectivity.js +29 -39
- package/lib/sync/datastoreReachability/index.d.ts +1 -3
- package/lib/sync/datastoreReachability/index.js +3 -3
- package/lib/sync/datastoreReachability/index.native.d.ts +1 -3
- package/lib/sync/datastoreReachability/index.native.js +4 -5
- package/lib/sync/index.d.ts +2 -2
- package/lib/sync/index.js +522 -827
- package/lib/sync/merger.js +31 -63
- package/lib/sync/outbox.js +148 -232
- package/lib/sync/processors/errorMaps.d.ts +1 -1
- package/lib/sync/processors/errorMaps.js +30 -47
- package/lib/sync/processors/mutation.d.ts +2 -2
- package/lib/sync/processors/mutation.js +343 -502
- package/lib/sync/processors/subscription.d.ts +5 -2
- package/lib/sync/processors/subscription.js +283 -437
- package/lib/sync/processors/sync.d.ts +2 -2
- package/lib/sync/processors/sync.js +279 -404
- package/lib/sync/utils.d.ts +5 -4
- package/lib/sync/utils.js +267 -320
- package/lib/tsconfig.tsbuildinfo +1 -0
- package/lib/types.d.ts +138 -140
- package/lib/types.js +17 -24
- package/lib/util.d.ts +9 -17
- package/lib/util.js +387 -511
- package/lib-esm/authModeStrategies/defaultAuthStrategy.js +1 -2
- package/lib-esm/authModeStrategies/index.js +0 -1
- package/lib-esm/authModeStrategies/multiAuthStrategy.js +35 -52
- package/lib-esm/datastore/datastore.d.ts +4 -5
- package/lib-esm/datastore/datastore.js +888 -1247
- package/lib-esm/index.d.ts +1 -1
- package/lib-esm/index.js +6 -7
- package/lib-esm/predicates/index.js +53 -70
- package/lib-esm/predicates/next.d.ts +2 -2
- package/lib-esm/predicates/next.js +306 -459
- package/lib-esm/predicates/sort.js +23 -28
- package/lib-esm/ssr/index.js +1 -2
- package/lib-esm/storage/adapter/AsyncStorageAdapter.js +111 -338
- package/lib-esm/storage/adapter/AsyncStorageDatabase.js +212 -416
- package/lib-esm/storage/adapter/InMemoryStore.js +27 -52
- package/lib-esm/storage/adapter/InMemoryStore.native.js +0 -1
- package/lib-esm/storage/adapter/IndexedDBAdapter.js +438 -866
- package/lib-esm/storage/adapter/StorageAdapterBase.js +173 -325
- package/lib-esm/storage/adapter/getDefaultAdapter/index.js +2 -6
- package/lib-esm/storage/adapter/getDefaultAdapter/index.native.js +1 -2
- package/lib-esm/storage/adapter/index.js +1 -1
- package/lib-esm/storage/relationship.js +173 -251
- package/lib-esm/storage/storage.d.ts +4 -4
- package/lib-esm/storage/storage.js +242 -424
- package/lib-esm/sync/datastoreConnectivity.d.ts +2 -2
- package/lib-esm/sync/datastoreConnectivity.js +28 -39
- package/lib-esm/sync/datastoreReachability/index.d.ts +1 -3
- package/lib-esm/sync/datastoreReachability/index.js +2 -3
- package/lib-esm/sync/datastoreReachability/index.native.d.ts +1 -3
- package/lib-esm/sync/datastoreReachability/index.native.js +3 -4
- package/lib-esm/sync/index.d.ts +2 -2
- package/lib-esm/sync/index.js +502 -812
- package/lib-esm/sync/merger.js +28 -61
- package/lib-esm/sync/outbox.js +143 -228
- package/lib-esm/sync/processors/errorMaps.d.ts +1 -1
- package/lib-esm/sync/processors/errorMaps.js +32 -50
- package/lib-esm/sync/processors/mutation.d.ts +2 -2
- package/lib-esm/sync/processors/mutation.js +329 -490
- package/lib-esm/sync/processors/subscription.d.ts +5 -2
- package/lib-esm/sync/processors/subscription.js +266 -421
- package/lib-esm/sync/processors/sync.d.ts +2 -2
- package/lib-esm/sync/processors/sync.js +271 -397
- package/lib-esm/sync/utils.d.ts +5 -4
- package/lib-esm/sync/utils.js +252 -307
- package/lib-esm/tsconfig.tsbuildinfo +1 -0
- package/lib-esm/types.d.ts +138 -140
- package/lib-esm/types.js +16 -25
- package/lib-esm/util.d.ts +9 -17
- package/lib-esm/util.js +335 -497
- package/package.json +31 -26
- package/src/authModeStrategies/multiAuthStrategy.ts +15 -12
- package/src/datastore/datastore.ts +36 -35
- package/src/predicates/sort.ts +3 -1
- package/src/storage/adapter/InMemoryStore.ts +1 -1
- package/src/storage/adapter/IndexedDBAdapter.ts +2 -2
- package/src/storage/adapter/StorageAdapterBase.ts +2 -2
- package/src/storage/adapter/getDefaultAdapter/index.ts +1 -4
- package/src/storage/storage.ts +29 -24
- package/src/sync/datastoreConnectivity.ts +6 -6
- package/src/sync/datastoreReachability/index.native.ts +5 -3
- package/src/sync/datastoreReachability/index.ts +1 -1
- package/src/sync/index.ts +79 -89
- package/src/sync/processors/errorMaps.ts +7 -7
- package/src/sync/processors/mutation.ts +19 -13
- package/src/sync/processors/subscription.ts +221 -295
- package/src/sync/processors/sync.ts +11 -8
- package/src/sync/utils.ts +30 -15
- package/src/types.ts +4 -8
- package/src/util.ts +46 -9
- package/lib/.tsbuildinfo +0 -3
- package/lib/authModeStrategies/defaultAuthStrategy.js.map +0 -1
- package/lib/authModeStrategies/index.js.map +0 -1
- package/lib/authModeStrategies/multiAuthStrategy.js.map +0 -1
- package/lib/datastore/datastore.js.map +0 -1
- package/lib/index.js.map +0 -1
- package/lib/predicates/index.js.map +0 -1
- package/lib/predicates/next.js.map +0 -1
- package/lib/predicates/sort.js.map +0 -1
- package/lib/ssr/index.js.map +0 -1
- package/lib/storage/adapter/AsyncStorageAdapter.js.map +0 -1
- package/lib/storage/adapter/AsyncStorageDatabase.js.map +0 -1
- package/lib/storage/adapter/InMemoryStore.js.map +0 -1
- package/lib/storage/adapter/InMemoryStore.native.js.map +0 -1
- package/lib/storage/adapter/IndexedDBAdapter.js.map +0 -1
- package/lib/storage/adapter/StorageAdapterBase.js.map +0 -1
- package/lib/storage/adapter/getDefaultAdapter/index.js.map +0 -1
- package/lib/storage/adapter/getDefaultAdapter/index.native.js.map +0 -1
- package/lib/storage/adapter/index.js.map +0 -1
- package/lib/storage/relationship.js.map +0 -1
- package/lib/storage/storage.js.map +0 -1
- package/lib/sync/datastoreConnectivity.js.map +0 -1
- package/lib/sync/datastoreReachability/index.js.map +0 -1
- package/lib/sync/datastoreReachability/index.native.js.map +0 -1
- package/lib/sync/index.js.map +0 -1
- package/lib/sync/merger.js.map +0 -1
- package/lib/sync/outbox.js.map +0 -1
- package/lib/sync/processors/errorMaps.js.map +0 -1
- package/lib/sync/processors/mutation.js.map +0 -1
- package/lib/sync/processors/subscription.js.map +0 -1
- package/lib/sync/processors/sync.js.map +0 -1
- package/lib/sync/utils.js.map +0 -1
- package/lib/types.js.map +0 -1
- package/lib/util.js.map +0 -1
- package/lib-esm/.tsbuildinfo +0 -3
- package/lib-esm/authModeStrategies/defaultAuthStrategy.js.map +0 -1
- package/lib-esm/authModeStrategies/index.js.map +0 -1
- package/lib-esm/authModeStrategies/multiAuthStrategy.js.map +0 -1
- package/lib-esm/datastore/datastore.js.map +0 -1
- package/lib-esm/index.js.map +0 -1
- package/lib-esm/predicates/index.js.map +0 -1
- package/lib-esm/predicates/next.js.map +0 -1
- package/lib-esm/predicates/sort.js.map +0 -1
- package/lib-esm/ssr/index.js.map +0 -1
- package/lib-esm/storage/adapter/AsyncStorageAdapter.js.map +0 -1
- package/lib-esm/storage/adapter/AsyncStorageDatabase.js.map +0 -1
- package/lib-esm/storage/adapter/InMemoryStore.js.map +0 -1
- package/lib-esm/storage/adapter/InMemoryStore.native.js.map +0 -1
- package/lib-esm/storage/adapter/IndexedDBAdapter.js.map +0 -1
- package/lib-esm/storage/adapter/StorageAdapterBase.js.map +0 -1
- package/lib-esm/storage/adapter/getDefaultAdapter/index.js.map +0 -1
- package/lib-esm/storage/adapter/getDefaultAdapter/index.native.js.map +0 -1
- package/lib-esm/storage/adapter/index.js.map +0 -1
- package/lib-esm/storage/relationship.js.map +0 -1
- package/lib-esm/storage/storage.js.map +0 -1
- package/lib-esm/sync/datastoreConnectivity.js.map +0 -1
- package/lib-esm/sync/datastoreReachability/index.js.map +0 -1
- package/lib-esm/sync/datastoreReachability/index.native.js.map +0 -1
- package/lib-esm/sync/index.js.map +0 -1
- package/lib-esm/sync/merger.js.map +0 -1
- package/lib-esm/sync/outbox.js.map +0 -1
- package/lib-esm/sync/processors/errorMaps.js.map +0 -1
- package/lib-esm/sync/processors/mutation.js.map +0 -1
- package/lib-esm/sync/processors/subscription.js.map +0 -1
- package/lib-esm/sync/processors/sync.js.map +0 -1
- package/lib-esm/sync/utils.js.map +0 -1
- package/lib-esm/types.js.map +0 -1
- package/lib-esm/util.js.map +0 -1
package/lib/predicates/next.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
|
|
3
|
+
exports.predicateFor = exports.recursivePredicateFor = exports.GroupCondition = exports.FieldCondition = exports.internals = void 0;
|
|
4
4
|
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
5
5
|
// SPDX-License-Identifier: Apache-2.0
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
const types_1 = require("../types");
|
|
7
|
+
const index_1 = require("./index");
|
|
8
|
+
const relationship_1 = require("../storage/relationship");
|
|
9
|
+
const util_1 = require("../util");
|
|
10
|
+
const ops = [...index_1.comparisonKeys];
|
|
11
11
|
/**
|
|
12
12
|
* A map from keys (exposed to customers) to the internal predicate data
|
|
13
13
|
* structures invoking code should not muck with.
|
|
14
14
|
*/
|
|
15
|
-
|
|
15
|
+
const predicateInternalsMap = new Map();
|
|
16
16
|
/**
|
|
17
17
|
* Creates a link between a key (and generates a key if needed) and an internal
|
|
18
18
|
* `GroupCondition`, which allows us to return a key object instead of the gory
|
|
@@ -22,8 +22,8 @@ var predicateInternalsMap = new Map();
|
|
|
22
22
|
* @param key The object DataStore will use to find the internal condition.
|
|
23
23
|
* If no key is given, an empty one is created.
|
|
24
24
|
*/
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
const registerPredicateInternals = (condition, key) => {
|
|
26
|
+
const finalKey = key || new types_1.PredicateInternalsKey();
|
|
27
27
|
predicateInternalsMap.set(finalKey, condition);
|
|
28
28
|
return finalKey;
|
|
29
29
|
};
|
|
@@ -38,17 +38,18 @@ var registerPredicateInternals = function (condition, key) {
|
|
|
38
38
|
*
|
|
39
39
|
* @param key A key object previously returned by `registerPredicateInternals()`
|
|
40
40
|
*/
|
|
41
|
-
|
|
41
|
+
const internals = (key) => {
|
|
42
42
|
if (!predicateInternalsMap.has(key)) {
|
|
43
43
|
throw new Error("Invalid predicate. Terminate your predicate with a valid condition (e.g., `p => p.field.eq('value')`) or pass `Predicates.ALL`.");
|
|
44
44
|
}
|
|
45
45
|
return predicateInternalsMap.get(key);
|
|
46
46
|
};
|
|
47
|
+
exports.internals = internals;
|
|
47
48
|
/**
|
|
48
49
|
* Maps operators to negated operators.
|
|
49
50
|
* Used to facilitate propagation of negation down a tree of conditions.
|
|
50
51
|
*/
|
|
51
|
-
|
|
52
|
+
const negations = {
|
|
52
53
|
and: 'or',
|
|
53
54
|
or: 'and',
|
|
54
55
|
not: 'and',
|
|
@@ -67,8 +68,8 @@ var negations = {
|
|
|
67
68
|
* @member operator The equality or comparison operator to use.
|
|
68
69
|
* @member operands The operands for the equality/comparison check.
|
|
69
70
|
*/
|
|
70
|
-
|
|
71
|
-
|
|
71
|
+
class FieldCondition {
|
|
72
|
+
constructor(field, operator, operands) {
|
|
72
73
|
this.field = field;
|
|
73
74
|
this.operator = operator;
|
|
74
75
|
this.operands = operands;
|
|
@@ -79,12 +80,12 @@ var FieldCondition = /** @class */ (function () {
|
|
|
79
80
|
* @param extract Not used. Present only to fulfill the `UntypedCondition` interface.
|
|
80
81
|
* @returns A new, identitical `FieldCondition`.
|
|
81
82
|
*/
|
|
82
|
-
|
|
83
|
+
copy(extract) {
|
|
83
84
|
return [
|
|
84
|
-
new FieldCondition(this.field, this.operator,
|
|
85
|
+
new FieldCondition(this.field, this.operator, [...this.operands]),
|
|
85
86
|
undefined,
|
|
86
87
|
];
|
|
87
|
-
}
|
|
88
|
+
}
|
|
88
89
|
/**
|
|
89
90
|
* Produces a tree structure similar to a graphql condition. The returned
|
|
90
91
|
* structure is "dumb" and is intended for another query/condition
|
|
@@ -101,16 +102,15 @@ var FieldCondition = /** @class */ (function () {
|
|
|
101
102
|
* }
|
|
102
103
|
* ```
|
|
103
104
|
*/
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
_b[this.operator] = this.operator === 'between'
|
|
105
|
+
toAST() {
|
|
106
|
+
return {
|
|
107
|
+
[this.field]: {
|
|
108
|
+
[this.operator]: this.operator === 'between'
|
|
109
109
|
? [this.operands[0], this.operands[1]]
|
|
110
110
|
: this.operands[0],
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
}
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
114
|
/**
|
|
115
115
|
* Produces a new condition (`FieldCondition` or `GroupCondition`) that
|
|
116
116
|
* matches the opposite of this condition.
|
|
@@ -127,7 +127,7 @@ var FieldCondition = /** @class */ (function () {
|
|
|
127
127
|
* @param model The model meta to use when construction a new `GroupCondition`
|
|
128
128
|
* for cases where the negation requires multiple `FieldCondition`'s.
|
|
129
129
|
*/
|
|
130
|
-
|
|
130
|
+
negated(model) {
|
|
131
131
|
if (this.operator === 'between') {
|
|
132
132
|
return new GroupCondition(model, undefined, undefined, 'or', [
|
|
133
133
|
new FieldCondition(this.field, 'lt', [this.operands[0]]),
|
|
@@ -145,77 +145,65 @@ var FieldCondition = /** @class */ (function () {
|
|
|
145
145
|
else {
|
|
146
146
|
return new FieldCondition(this.field, negations[this.operator], this.operands);
|
|
147
147
|
}
|
|
148
|
-
}
|
|
148
|
+
}
|
|
149
149
|
/**
|
|
150
150
|
* Not implemented. Not needed. GroupCondition instead consumes FieldConditions and
|
|
151
151
|
* transforms them into legacy predicates. (*For now.*)
|
|
152
152
|
* @param storage N/A. If ever implemented, the storage adapter to query.
|
|
153
153
|
* @returns N/A. If ever implemented, return items from `storage` that match.
|
|
154
154
|
*/
|
|
155
|
-
|
|
156
|
-
return
|
|
157
|
-
|
|
158
|
-
return [2 /*return*/, Promise.reject('No implementation needed [yet].')];
|
|
159
|
-
});
|
|
160
|
-
});
|
|
161
|
-
};
|
|
155
|
+
async fetch(storage) {
|
|
156
|
+
return Promise.reject('No implementation needed [yet].');
|
|
157
|
+
}
|
|
162
158
|
/**
|
|
163
159
|
* Determins whether a given item matches the expressed condition.
|
|
164
160
|
* @param item The item to test.
|
|
165
161
|
* @returns `Promise<boolean>`, `true` if matches; `false` otherwise.
|
|
166
162
|
*/
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
else {
|
|
191
|
-
throw new Error("Invalid operator given: " + this.operator);
|
|
192
|
-
}
|
|
193
|
-
return [2 /*return*/];
|
|
194
|
-
});
|
|
195
|
-
});
|
|
196
|
-
};
|
|
163
|
+
async matches(item) {
|
|
164
|
+
const v = item[this.field];
|
|
165
|
+
const operations = {
|
|
166
|
+
eq: () => v === this.operands[0],
|
|
167
|
+
ne: () => v !== this.operands[0],
|
|
168
|
+
gt: () => v > this.operands[0],
|
|
169
|
+
ge: () => v >= this.operands[0],
|
|
170
|
+
lt: () => v < this.operands[0],
|
|
171
|
+
le: () => v <= this.operands[0],
|
|
172
|
+
contains: () => v?.indexOf(this.operands[0]) > -1,
|
|
173
|
+
notContains: () => (!v ? true : v.indexOf(this.operands[0]) === -1),
|
|
174
|
+
beginsWith: () => v?.startsWith(this.operands[0]),
|
|
175
|
+
between: () => v >= this.operands[0] && v <= this.operands[1],
|
|
176
|
+
};
|
|
177
|
+
const operation = operations[this.operator];
|
|
178
|
+
if (operation) {
|
|
179
|
+
const result = operation();
|
|
180
|
+
return result;
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
throw new Error(`Invalid operator given: ${this.operator}`);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
197
186
|
/**
|
|
198
187
|
* Checks `this.operands` for compatibility with `this.operator`.
|
|
199
188
|
*/
|
|
200
|
-
|
|
201
|
-
var _this = this;
|
|
189
|
+
validate() {
|
|
202
190
|
/**
|
|
203
191
|
* Creates a validator that checks for a particular `operands` count.
|
|
204
192
|
* Throws an exception if the `count` disagrees with `operands.length`.
|
|
205
193
|
* @param count The number of `operands` expected.
|
|
206
194
|
*/
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
return
|
|
210
|
-
if (
|
|
211
|
-
return
|
|
195
|
+
const argumentCount = count => {
|
|
196
|
+
const argsClause = count === 1 ? 'argument is' : 'arguments are';
|
|
197
|
+
return () => {
|
|
198
|
+
if (this.operands.length !== count) {
|
|
199
|
+
return `Exactly ${count} ${argsClause} required.`;
|
|
212
200
|
}
|
|
213
201
|
};
|
|
214
202
|
};
|
|
215
203
|
// NOTE: validations should return a message on failure.
|
|
216
204
|
// hence, they should be "joined" together with logical OR's
|
|
217
205
|
// as seen in the `between:` entry.
|
|
218
|
-
|
|
206
|
+
const validations = {
|
|
219
207
|
eq: argumentCount(1),
|
|
220
208
|
ne: argumentCount(1),
|
|
221
209
|
gt: argumentCount(1),
|
|
@@ -225,34 +213,31 @@ var FieldCondition = /** @class */ (function () {
|
|
|
225
213
|
contains: argumentCount(1),
|
|
226
214
|
notContains: argumentCount(1),
|
|
227
215
|
beginsWith: argumentCount(1),
|
|
228
|
-
between:
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
: null);
|
|
233
|
-
},
|
|
216
|
+
between: () => argumentCount(2)() ||
|
|
217
|
+
(this.operands[0] > this.operands[1]
|
|
218
|
+
? 'The first argument must be less than or equal to the second argument.'
|
|
219
|
+
: null),
|
|
234
220
|
};
|
|
235
|
-
|
|
221
|
+
const validate = validations[this.operator];
|
|
236
222
|
if (validate) {
|
|
237
|
-
|
|
223
|
+
const e = validate();
|
|
238
224
|
if (typeof e === 'string')
|
|
239
|
-
throw new Error(
|
|
225
|
+
throw new Error(`Incorrect usage of \`${this.operator}()\`: ${e}`);
|
|
240
226
|
}
|
|
241
227
|
else {
|
|
242
|
-
throw new Error(
|
|
228
|
+
throw new Error(`Non-existent operator: \`${this.operator}()\``);
|
|
243
229
|
}
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
}());
|
|
230
|
+
}
|
|
231
|
+
}
|
|
247
232
|
exports.FieldCondition = FieldCondition;
|
|
248
233
|
/**
|
|
249
234
|
* Small utility function to generate a monotonically increasing ID.
|
|
250
235
|
* Used by GroupCondition to help keep track of which group is doing what,
|
|
251
236
|
* when, and where during troubleshooting.
|
|
252
237
|
*/
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
return
|
|
238
|
+
const getGroupId = (() => {
|
|
239
|
+
let seed = 1;
|
|
240
|
+
return () => `group_${seed++}`;
|
|
256
241
|
})();
|
|
257
242
|
/**
|
|
258
243
|
* A set of sub-conditions to operate against a model, optionally scoped to
|
|
@@ -264,8 +249,8 @@ var getGroupId = (function () {
|
|
|
264
249
|
* @member operator How to group child conditions together.
|
|
265
250
|
* @member operands The child conditions.
|
|
266
251
|
*/
|
|
267
|
-
|
|
268
|
-
|
|
252
|
+
class GroupCondition {
|
|
253
|
+
constructor(
|
|
269
254
|
/**
|
|
270
255
|
* The `ModelMeta` of the model to query and/or filter against.
|
|
271
256
|
* Expected to contain:
|
|
@@ -309,8 +294,7 @@ var GroupCondition = /** @class */ (function () {
|
|
|
309
294
|
* This is used to guard against infinitely fetch -> optimize -> fetch
|
|
310
295
|
* recursion.
|
|
311
296
|
*/
|
|
312
|
-
isOptimized) {
|
|
313
|
-
if (isOptimized === void 0) { isOptimized = false; }
|
|
297
|
+
isOptimized = false) {
|
|
314
298
|
this.model = model;
|
|
315
299
|
this.field = field;
|
|
316
300
|
this.relationshipType = relationshipType;
|
|
@@ -327,16 +311,16 @@ var GroupCondition = /** @class */ (function () {
|
|
|
327
311
|
* @param extract A node of interest. Its copy will *also* be returned if the node exists.
|
|
328
312
|
* @returns [The full copy, the copy of `extract` | undefined]
|
|
329
313
|
*/
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
this.operands.forEach(
|
|
334
|
-
|
|
314
|
+
copy(extract) {
|
|
315
|
+
const copied = new GroupCondition(this.model, this.field, this.relationshipType, this.operator, []);
|
|
316
|
+
let extractedCopy = extract === this ? copied : undefined;
|
|
317
|
+
this.operands.forEach(o => {
|
|
318
|
+
const [operandCopy, extractedFromOperand] = o.copy(extract);
|
|
335
319
|
copied.operands.push(operandCopy);
|
|
336
320
|
extractedCopy = extractedCopy || extractedFromOperand;
|
|
337
321
|
});
|
|
338
322
|
return [copied, extractedCopy];
|
|
339
|
-
}
|
|
323
|
+
}
|
|
340
324
|
/**
|
|
341
325
|
* Creates a new `GroupCondition` that contains only the local field conditions,
|
|
342
326
|
* omitting related model conditions. That resulting `GroupCondition` can be
|
|
@@ -346,15 +330,12 @@ var GroupCondition = /** @class */ (function () {
|
|
|
346
330
|
* @param negate Whether the condition tree should be negated according
|
|
347
331
|
* to De Morgan's law.
|
|
348
332
|
*/
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
var negateChildren = negate !== (this.operator === 'not');
|
|
333
|
+
withFieldConditionsOnly(negate) {
|
|
334
|
+
const negateChildren = negate !== (this.operator === 'not');
|
|
352
335
|
return new GroupCondition(this.model, undefined, undefined, (negate ? negations[this.operator] : this.operator), this.operands
|
|
353
|
-
.filter(
|
|
354
|
-
.map(
|
|
355
|
-
|
|
356
|
-
}));
|
|
357
|
-
};
|
|
336
|
+
.filter(o => o instanceof FieldCondition)
|
|
337
|
+
.map(o => negateChildren ? o.negated(this.model) : o));
|
|
338
|
+
}
|
|
358
339
|
/**
|
|
359
340
|
* Returns a version of the predicate tree with unnecessary logical groups
|
|
360
341
|
* condensed and merged together. This is intended to create a dense tree
|
|
@@ -391,12 +372,8 @@ var GroupCondition = /** @class */ (function () {
|
|
|
391
372
|
* `not` groups. `not` groups will always have a single child, so there's nothing to
|
|
392
373
|
* optimize below a `not` (for now), and it makes the query logic simpler later.
|
|
393
374
|
*/
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
if (preserveNode === void 0) { preserveNode = true; }
|
|
397
|
-
var operands = this.operands.map(function (o) {
|
|
398
|
-
return o instanceof GroupCondition ? o.optimized(_this.operator === 'not') : o;
|
|
399
|
-
});
|
|
375
|
+
optimized(preserveNode = true) {
|
|
376
|
+
const operands = this.operands.map(o => o instanceof GroupCondition ? o.optimized(this.operator === 'not') : o);
|
|
400
377
|
// we're only collapsing and/or groups that contains a single child for now,
|
|
401
378
|
// because they're much more common and much more trivial to collapse. basically,
|
|
402
379
|
// an `and`/`or` that contains a single child doesn't require the layer of
|
|
@@ -405,7 +382,7 @@ var GroupCondition = /** @class */ (function () {
|
|
|
405
382
|
['and', 'or'].includes(this.operator) &&
|
|
406
383
|
!this.field &&
|
|
407
384
|
operands.length === 1) {
|
|
408
|
-
|
|
385
|
+
const operand = operands[0];
|
|
409
386
|
if (operand instanceof FieldCondition) {
|
|
410
387
|
// between conditions should NOT be passed up the chain. if they
|
|
411
388
|
// need to be *negated* later, it is important that they be properly
|
|
@@ -421,7 +398,7 @@ var GroupCondition = /** @class */ (function () {
|
|
|
421
398
|
}
|
|
422
399
|
}
|
|
423
400
|
return new GroupCondition(this.model, this.field, this.relationshipType, this.operator, operands, true);
|
|
424
|
-
}
|
|
401
|
+
}
|
|
425
402
|
/**
|
|
426
403
|
* Fetches matching records from a given storage adapter using legacy predicates (for now).
|
|
427
404
|
* @param storage The storage adapter this predicate will query against.
|
|
@@ -430,211 +407,134 @@ var GroupCondition = /** @class */ (function () {
|
|
|
430
407
|
* @param negate Whether to match on the `NOT` of `this`.
|
|
431
408
|
* @returns An `Promise` of `any[]` from `storage` matching the child conditions.
|
|
432
409
|
*/
|
|
433
|
-
|
|
434
|
-
if (
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
relative = relatives_1_1.value;
|
|
496
|
-
relativeConditions = [];
|
|
497
|
-
for (i = 0; i < relationship.localJoinFields.length; i++) {
|
|
498
|
-
relativeConditions.push((_l = {},
|
|
499
|
-
_l[relationship.localJoinFields[i]] = {
|
|
500
|
-
eq: relative[relationship.remoteJoinFields[i]],
|
|
501
|
-
},
|
|
502
|
-
_l));
|
|
503
|
-
}
|
|
504
|
-
allJoinConditions.push({ and: relativeConditions });
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
508
|
-
finally {
|
|
509
|
-
try {
|
|
510
|
-
if (relatives_1_1 && !relatives_1_1.done && (_k = relatives_1.return)) _k.call(relatives_1);
|
|
511
|
-
}
|
|
512
|
-
finally { if (e_2) throw e_2.error; }
|
|
513
|
-
}
|
|
514
|
-
predicate = index_1.ModelPredicateCreator.createFromAST(this.model.schema, {
|
|
515
|
-
or: allJoinConditions,
|
|
516
|
-
});
|
|
517
|
-
_b = (_a = resultGroups).push;
|
|
518
|
-
return [4 /*yield*/, storage.query(this.model.builder, predicate)];
|
|
519
|
-
case 4:
|
|
520
|
-
_b.apply(_a, [_r.sent()]);
|
|
521
|
-
return [3 /*break*/, 6];
|
|
522
|
-
case 5: throw new Error('Missing field metadata.');
|
|
523
|
-
case 6: return [3 /*break*/, 8];
|
|
524
|
-
case 7:
|
|
525
|
-
// relatives are not actually relatives. they're candidate results.
|
|
526
|
-
resultGroups.push(relatives);
|
|
527
|
-
_r.label = 8;
|
|
528
|
-
case 8:
|
|
529
|
-
groups_1_1 = groups_1.next();
|
|
530
|
-
return [3 /*break*/, 2];
|
|
531
|
-
case 9: return [3 /*break*/, 12];
|
|
532
|
-
case 10:
|
|
533
|
-
e_1_1 = _r.sent();
|
|
534
|
-
e_1 = { error: e_1_1 };
|
|
535
|
-
return [3 /*break*/, 12];
|
|
536
|
-
case 11:
|
|
537
|
-
try {
|
|
538
|
-
if (groups_1_1 && !groups_1_1.done && (_j = groups_1.return)) _j.call(groups_1);
|
|
539
|
-
}
|
|
540
|
-
finally { if (e_1) throw e_1.error; }
|
|
541
|
-
return [7 /*endfinally*/];
|
|
542
|
-
case 12:
|
|
543
|
-
if (!(conditions.length > 0)) return [3 /*break*/, 14];
|
|
544
|
-
predicate = this.withFieldConditionsOnly(negateChildren).toStoragePredicate();
|
|
545
|
-
_d = (_c = resultGroups).push;
|
|
546
|
-
return [4 /*yield*/, storage.query(this.model.builder, predicate)];
|
|
547
|
-
case 13:
|
|
548
|
-
_d.apply(_c, [_r.sent()]);
|
|
549
|
-
return [3 /*break*/, 16];
|
|
550
|
-
case 14:
|
|
551
|
-
if (!(conditions.length === 0 && resultGroups.length === 0)) return [3 /*break*/, 16];
|
|
552
|
-
_f = (_e = resultGroups).push;
|
|
553
|
-
return [4 /*yield*/, storage.query(this.model.builder)];
|
|
554
|
-
case 15:
|
|
555
|
-
_f.apply(_e, [_r.sent()]);
|
|
556
|
-
_r.label = 16;
|
|
557
|
-
case 16:
|
|
558
|
-
getPKValue = function (item) {
|
|
559
|
-
return JSON.stringify(_this.model.pkField.map(function (name) { return item[name]; }));
|
|
560
|
-
};
|
|
561
|
-
if (operator === 'and') {
|
|
562
|
-
if (resultGroups.length === 0) {
|
|
563
|
-
return [2 /*return*/, []];
|
|
564
|
-
}
|
|
565
|
-
try {
|
|
566
|
-
// for each group, we intersect, removing items from the result index
|
|
567
|
-
// that aren't present in each subsequent group.
|
|
568
|
-
for (resultGroups_1 = tslib_1.__values(resultGroups), resultGroups_1_1 = resultGroups_1.next(); !resultGroups_1_1.done; resultGroups_1_1 = resultGroups_1.next()) {
|
|
569
|
-
group = resultGroups_1_1.value;
|
|
570
|
-
if (resultIndex === undefined) {
|
|
571
|
-
resultIndex = new Map(group.map(function (item) { return [getPKValue(item), item]; }));
|
|
572
|
-
}
|
|
573
|
-
else {
|
|
574
|
-
intersectWith = new Map(group.map(function (item) { return [getPKValue(item), item]; }));
|
|
575
|
-
try {
|
|
576
|
-
for (_g = (e_4 = void 0, tslib_1.__values(resultIndex.keys())), _h = _g.next(); !_h.done; _h = _g.next()) {
|
|
577
|
-
k = _h.value;
|
|
578
|
-
if (!intersectWith.has(k)) {
|
|
579
|
-
resultIndex.delete(k);
|
|
580
|
-
}
|
|
581
|
-
}
|
|
582
|
-
}
|
|
583
|
-
catch (e_4_1) { e_4 = { error: e_4_1 }; }
|
|
584
|
-
finally {
|
|
585
|
-
try {
|
|
586
|
-
if (_h && !_h.done && (_o = _g.return)) _o.call(_g);
|
|
587
|
-
}
|
|
588
|
-
finally { if (e_4) throw e_4.error; }
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
|
-
}
|
|
592
|
-
}
|
|
593
|
-
catch (e_3_1) { e_3 = { error: e_3_1 }; }
|
|
594
|
-
finally {
|
|
595
|
-
try {
|
|
596
|
-
if (resultGroups_1_1 && !resultGroups_1_1.done && (_m = resultGroups_1.return)) _m.call(resultGroups_1);
|
|
597
|
-
}
|
|
598
|
-
finally { if (e_3) throw e_3.error; }
|
|
599
|
-
}
|
|
410
|
+
async fetch(storage, breadcrumb = [], negate = false) {
|
|
411
|
+
if (!this.isOptimized) {
|
|
412
|
+
return this.optimized().fetch(storage);
|
|
413
|
+
}
|
|
414
|
+
const resultGroups = [];
|
|
415
|
+
const operator = (negate ? negations[this.operator] : this.operator);
|
|
416
|
+
const negateChildren = negate !== (this.operator === 'not');
|
|
417
|
+
/**
|
|
418
|
+
* Conditions that must be branched out and used to generate a base, "candidate"
|
|
419
|
+
* result set.
|
|
420
|
+
*
|
|
421
|
+
* If `field` is populated, these groups select *related* records, and the base,
|
|
422
|
+
* candidate results are selected to match those.
|
|
423
|
+
*/
|
|
424
|
+
const groups = this.operands.filter(op => op instanceof GroupCondition);
|
|
425
|
+
/**
|
|
426
|
+
* Simple conditions that must match the target model of `this`.
|
|
427
|
+
*/
|
|
428
|
+
const conditions = this.operands.filter(op => op instanceof FieldCondition);
|
|
429
|
+
for (const g of groups) {
|
|
430
|
+
const relatives = await g.fetch(storage, [...breadcrumb, this.groupId], negateChildren);
|
|
431
|
+
// no relatives -> no need to attempt to perform a "join" query for
|
|
432
|
+
// candidate results:
|
|
433
|
+
//
|
|
434
|
+
// select a.* from a,b where b.id in EMPTY_SET ==> EMPTY_SET
|
|
435
|
+
//
|
|
436
|
+
// Additionally, the entire (sub)-query can be short-circuited if
|
|
437
|
+
// the operator is `AND`. Illustrated in SQL:
|
|
438
|
+
//
|
|
439
|
+
// select a.* from a where
|
|
440
|
+
// id in [a,b,c]
|
|
441
|
+
// AND <
|
|
442
|
+
// id in EMTPY_SET <<< Look!
|
|
443
|
+
// AND <
|
|
444
|
+
// id in [x,y,z]
|
|
445
|
+
//
|
|
446
|
+
// YIELDS: EMPTY_SET // <-- Easy peasy. Lemon squeezy.
|
|
447
|
+
//
|
|
448
|
+
if (relatives.length === 0) {
|
|
449
|
+
// aggressively short-circuit as soon as we know the group condition will fail
|
|
450
|
+
if (operator === 'and') {
|
|
451
|
+
return [];
|
|
452
|
+
}
|
|
453
|
+
// less aggressive short-circuit if we know the relatives will produce no
|
|
454
|
+
// candidate results; but aren't sure yet how this affects the group condition.
|
|
455
|
+
resultGroups.push([]);
|
|
456
|
+
continue;
|
|
457
|
+
}
|
|
458
|
+
if (g.field) {
|
|
459
|
+
// `relatives` are actual relatives. We'll skim them for FK query values.
|
|
460
|
+
// Use the relatives to add candidate result sets (`resultGroups`)
|
|
461
|
+
const relationship = relationship_1.ModelRelationship.from(this.model, g.field);
|
|
462
|
+
if (relationship) {
|
|
463
|
+
const allJoinConditions = [];
|
|
464
|
+
for (const relative of relatives) {
|
|
465
|
+
const relativeConditions = [];
|
|
466
|
+
for (let i = 0; i < relationship.localJoinFields.length; i++) {
|
|
467
|
+
relativeConditions.push({
|
|
468
|
+
[relationship.localJoinFields[i]]: {
|
|
469
|
+
eq: relative[relationship.remoteJoinFields[i]],
|
|
470
|
+
},
|
|
471
|
+
});
|
|
600
472
|
}
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
473
|
+
allJoinConditions.push({ and: relativeConditions });
|
|
474
|
+
}
|
|
475
|
+
const predicate = index_1.ModelPredicateCreator.createFromAST(this.model.schema, {
|
|
476
|
+
or: allJoinConditions,
|
|
477
|
+
});
|
|
478
|
+
resultGroups.push(await storage.query(this.model.builder, predicate));
|
|
479
|
+
}
|
|
480
|
+
else {
|
|
481
|
+
throw new Error('Missing field metadata.');
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
else {
|
|
485
|
+
// relatives are not actually relatives. they're candidate results.
|
|
486
|
+
resultGroups.push(relatives);
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
// if conditions is empty at this point, child predicates found no matches.
|
|
490
|
+
// i.e., we can stop looking and return empty.
|
|
491
|
+
if (conditions.length > 0) {
|
|
492
|
+
const predicate = this.withFieldConditionsOnly(negateChildren).toStoragePredicate();
|
|
493
|
+
resultGroups.push(await storage.query(this.model.builder, predicate));
|
|
494
|
+
}
|
|
495
|
+
else if (conditions.length === 0 && resultGroups.length === 0) {
|
|
496
|
+
resultGroups.push(await storage.query(this.model.builder));
|
|
497
|
+
}
|
|
498
|
+
// PK might be a single field, like `id`, or it might be several fields.
|
|
499
|
+
// so, we'll need to extract the list of PK fields from an object
|
|
500
|
+
// and stringify the list for easy comparison / merging.
|
|
501
|
+
const getPKValue = item => JSON.stringify(this.model.pkField.map(name => item[name]));
|
|
502
|
+
// will be used for intersecting or unioning results
|
|
503
|
+
let resultIndex;
|
|
504
|
+
if (operator === 'and') {
|
|
505
|
+
if (resultGroups.length === 0) {
|
|
506
|
+
return [];
|
|
507
|
+
}
|
|
508
|
+
// for each group, we intersect, removing items from the result index
|
|
509
|
+
// that aren't present in each subsequent group.
|
|
510
|
+
for (const group of resultGroups) {
|
|
511
|
+
if (resultIndex === undefined) {
|
|
512
|
+
resultIndex = new Map(group.map(item => [getPKValue(item), item]));
|
|
513
|
+
}
|
|
514
|
+
else {
|
|
515
|
+
const intersectWith = new Map(group.map(item => [getPKValue(item), item]));
|
|
516
|
+
for (const k of resultIndex.keys()) {
|
|
517
|
+
if (!intersectWith.has(k)) {
|
|
518
|
+
resultIndex.delete(k);
|
|
632
519
|
}
|
|
633
|
-
|
|
520
|
+
}
|
|
634
521
|
}
|
|
635
|
-
}
|
|
636
|
-
}
|
|
637
|
-
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
else if (operator === 'or' || operator === 'not') {
|
|
525
|
+
// it's OK to handle NOT here, because NOT must always only negate
|
|
526
|
+
// a single child predicate. NOT logic will have been distributed down
|
|
527
|
+
// to the leaf conditions already.
|
|
528
|
+
resultIndex = new Map();
|
|
529
|
+
// just merge the groups, performing DISTINCT-ification by ID.
|
|
530
|
+
for (const group of resultGroups) {
|
|
531
|
+
for (const item of group) {
|
|
532
|
+
resultIndex.set(getPKValue(item), item);
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
return Array.from(resultIndex?.values() || []);
|
|
537
|
+
}
|
|
638
538
|
/**
|
|
639
539
|
* Determines whether a single item matches the conditions of `this`.
|
|
640
540
|
* When checking the target `item`'s properties, each property will be `await`'d
|
|
@@ -644,111 +544,67 @@ var GroupCondition = /** @class */ (function () {
|
|
|
644
544
|
* (Used for iterating over children on HAS_MANY checks.)
|
|
645
545
|
* @returns A boolean (promise): `true` if matched, `false` otherwise.
|
|
646
546
|
*/
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
case 2:
|
|
661
|
-
_b = item;
|
|
662
|
-
_c.label = 3;
|
|
663
|
-
case 3:
|
|
664
|
-
itemToCheck = _b;
|
|
665
|
-
// if there is no item to check, we can stop recursing immediately.
|
|
666
|
-
// a condition cannot match against an item that does not exist. this
|
|
667
|
-
// can occur when `item.field` is optional in the schema.
|
|
668
|
-
if (!itemToCheck) {
|
|
669
|
-
return [2 /*return*/, false];
|
|
670
|
-
}
|
|
671
|
-
if (!(this.relationshipType === 'HAS_MANY' &&
|
|
672
|
-
typeof itemToCheck[Symbol.asyncIterator] === 'function')) return [3 /*break*/, 17];
|
|
673
|
-
_c.label = 4;
|
|
674
|
-
case 4:
|
|
675
|
-
_c.trys.push([4, 10, 11, 16]);
|
|
676
|
-
itemToCheck_1 = tslib_1.__asyncValues(itemToCheck);
|
|
677
|
-
_c.label = 5;
|
|
678
|
-
case 5: return [4 /*yield*/, itemToCheck_1.next()];
|
|
679
|
-
case 6:
|
|
680
|
-
if (!(itemToCheck_1_1 = _c.sent(), !itemToCheck_1_1.done)) return [3 /*break*/, 9];
|
|
681
|
-
singleItem = itemToCheck_1_1.value;
|
|
682
|
-
return [4 /*yield*/, this.matches(singleItem, true)];
|
|
683
|
-
case 7:
|
|
684
|
-
if (_c.sent()) {
|
|
685
|
-
return [2 /*return*/, true];
|
|
686
|
-
}
|
|
687
|
-
_c.label = 8;
|
|
688
|
-
case 8: return [3 /*break*/, 5];
|
|
689
|
-
case 9: return [3 /*break*/, 16];
|
|
690
|
-
case 10:
|
|
691
|
-
e_7_1 = _c.sent();
|
|
692
|
-
e_7 = { error: e_7_1 };
|
|
693
|
-
return [3 /*break*/, 16];
|
|
694
|
-
case 11:
|
|
695
|
-
_c.trys.push([11, , 14, 15]);
|
|
696
|
-
if (!(itemToCheck_1_1 && !itemToCheck_1_1.done && (_a = itemToCheck_1.return))) return [3 /*break*/, 13];
|
|
697
|
-
return [4 /*yield*/, _a.call(itemToCheck_1)];
|
|
698
|
-
case 12:
|
|
699
|
-
_c.sent();
|
|
700
|
-
_c.label = 13;
|
|
701
|
-
case 13: return [3 /*break*/, 15];
|
|
702
|
-
case 14:
|
|
703
|
-
if (e_7) throw e_7.error;
|
|
704
|
-
return [7 /*endfinally*/];
|
|
705
|
-
case 15: return [7 /*endfinally*/];
|
|
706
|
-
case 16: return [2 /*return*/, false];
|
|
707
|
-
case 17:
|
|
708
|
-
if (!(this.operator === 'or')) return [3 /*break*/, 18];
|
|
709
|
-
return [2 /*return*/, util_1.asyncSome(this.operands, function (c) { return c.matches(itemToCheck); })];
|
|
710
|
-
case 18:
|
|
711
|
-
if (!(this.operator === 'and')) return [3 /*break*/, 19];
|
|
712
|
-
return [2 /*return*/, util_1.asyncEvery(this.operands, function (c) { return c.matches(itemToCheck); })];
|
|
713
|
-
case 19:
|
|
714
|
-
if (!(this.operator === 'not')) return [3 /*break*/, 21];
|
|
715
|
-
if (this.operands.length !== 1) {
|
|
716
|
-
throw new Error('Invalid arguments! `not()` accepts exactly one predicate expression.');
|
|
717
|
-
}
|
|
718
|
-
return [4 /*yield*/, this.operands[0].matches(itemToCheck)];
|
|
719
|
-
case 20: return [2 /*return*/, !(_c.sent())];
|
|
720
|
-
case 21: throw new Error('Invalid group operator!');
|
|
547
|
+
async matches(item, ignoreFieldName = false) {
|
|
548
|
+
const itemToCheck = this.field && !ignoreFieldName ? await item[this.field] : item;
|
|
549
|
+
// if there is no item to check, we can stop recursing immediately.
|
|
550
|
+
// a condition cannot match against an item that does not exist. this
|
|
551
|
+
// can occur when `item.field` is optional in the schema.
|
|
552
|
+
if (!itemToCheck) {
|
|
553
|
+
return false;
|
|
554
|
+
}
|
|
555
|
+
if (this.relationshipType === 'HAS_MANY' &&
|
|
556
|
+
typeof itemToCheck[Symbol.asyncIterator] === 'function') {
|
|
557
|
+
for await (const singleItem of itemToCheck) {
|
|
558
|
+
if (await this.matches(singleItem, true)) {
|
|
559
|
+
return true;
|
|
721
560
|
}
|
|
722
|
-
}
|
|
723
|
-
|
|
724
|
-
|
|
561
|
+
}
|
|
562
|
+
return false;
|
|
563
|
+
}
|
|
564
|
+
if (this.operator === 'or') {
|
|
565
|
+
return (0, util_1.asyncSome)(this.operands, c => c.matches(itemToCheck));
|
|
566
|
+
}
|
|
567
|
+
else if (this.operator === 'and') {
|
|
568
|
+
return (0, util_1.asyncEvery)(this.operands, c => c.matches(itemToCheck));
|
|
569
|
+
}
|
|
570
|
+
else if (this.operator === 'not') {
|
|
571
|
+
if (this.operands.length !== 1) {
|
|
572
|
+
throw new Error('Invalid arguments! `not()` accepts exactly one predicate expression.');
|
|
573
|
+
}
|
|
574
|
+
return !(await this.operands[0].matches(itemToCheck));
|
|
575
|
+
}
|
|
576
|
+
else {
|
|
577
|
+
throw new Error('Invalid group operator!');
|
|
578
|
+
}
|
|
579
|
+
}
|
|
725
580
|
/**
|
|
726
581
|
* Tranfsorm to a AppSync GraphQL compatible AST.
|
|
727
582
|
* (Does not support filtering in nested types.)
|
|
728
583
|
*/
|
|
729
|
-
|
|
730
|
-
var _a;
|
|
584
|
+
toAST() {
|
|
731
585
|
if (this.field)
|
|
732
586
|
throw new Error('Nested type conditions are not supported!');
|
|
733
|
-
return
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
}
|
|
587
|
+
return {
|
|
588
|
+
[this.operator]: this.operands.map(operand => operand.toAST()),
|
|
589
|
+
};
|
|
590
|
+
}
|
|
737
591
|
/**
|
|
738
592
|
* Turn this predicate group into something a storage adapter
|
|
739
593
|
* understands how to use.
|
|
740
594
|
*/
|
|
741
|
-
|
|
595
|
+
toStoragePredicate() {
|
|
742
596
|
return index_1.ModelPredicateCreator.createFromAST(this.model.schema, this.toAST());
|
|
743
|
-
}
|
|
597
|
+
}
|
|
744
598
|
/**
|
|
745
599
|
* A JSON representation that's good for debugging.
|
|
746
600
|
*/
|
|
747
|
-
|
|
748
|
-
return
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
}
|
|
601
|
+
toJSON() {
|
|
602
|
+
return {
|
|
603
|
+
...this,
|
|
604
|
+
model: this.model.schema.name,
|
|
605
|
+
};
|
|
606
|
+
}
|
|
607
|
+
}
|
|
752
608
|
exports.GroupCondition = GroupCondition;
|
|
753
609
|
/**
|
|
754
610
|
* Creates a "seed" predicate that can be used to build an executable condition.
|
|
@@ -777,89 +633,91 @@ exports.GroupCondition = GroupCondition;
|
|
|
777
633
|
* @returns A ModelPredicate (builder) that customers can create queries with.
|
|
778
634
|
* (As shown in function description.)
|
|
779
635
|
*/
|
|
780
|
-
function recursivePredicateFor(ModelType, allowRecursion, field, query, tail) {
|
|
781
|
-
if (allowRecursion === void 0) { allowRecursion = true; }
|
|
636
|
+
function recursivePredicateFor(ModelType, allowRecursion = true, field, query, tail) {
|
|
782
637
|
// to be used if we don't have a base query or tail to build onto
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
638
|
+
const starter = new GroupCondition(ModelType, field, undefined, 'and', []);
|
|
639
|
+
const baseCondition = query && tail ? query : starter;
|
|
640
|
+
const tailCondition = query && tail ? tail : starter;
|
|
786
641
|
// our eventual return object, which can be built upon.
|
|
787
642
|
// next steps will be to add or(), and(), not(), and field.op() methods.
|
|
788
|
-
|
|
643
|
+
const link = {};
|
|
789
644
|
// so it can be looked up later with in the internals when processing conditions.
|
|
790
645
|
registerPredicateInternals(baseCondition, link);
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
return { query
|
|
646
|
+
const copyLink = () => {
|
|
647
|
+
const [query, newTail] = baseCondition.copy(tailCondition);
|
|
648
|
+
const newLink = recursivePredicateFor(ModelType, allowRecursion, undefined, query, newTail);
|
|
649
|
+
return { query, newTail, newLink };
|
|
795
650
|
};
|
|
796
651
|
// Adds .or() and .and() methods to the link.
|
|
797
652
|
// TODO: If revisiting this code, consider writing a Proxy instead.
|
|
798
|
-
['and', 'or'].forEach(
|
|
799
|
-
link[op] =
|
|
653
|
+
['and', 'or'].forEach(op => {
|
|
654
|
+
link[op] = (builder) => {
|
|
800
655
|
// or() and and() will return a copy of the original link
|
|
801
656
|
// to head off mutability concerns.
|
|
802
|
-
|
|
803
|
-
|
|
657
|
+
const { query, newTail } = copyLink();
|
|
658
|
+
const childConditions = builder(recursivePredicateFor(ModelType, allowRecursion));
|
|
804
659
|
if (!Array.isArray(childConditions)) {
|
|
805
|
-
throw new Error(
|
|
660
|
+
throw new Error(`Invalid predicate. \`${op}\` groups must return an array of child conditions.`);
|
|
806
661
|
}
|
|
807
662
|
// the customer will supply a child predicate, which apply to the `model.field`
|
|
808
663
|
// of the tail GroupCondition.
|
|
809
|
-
newTail
|
|
664
|
+
newTail?.operands.push(new GroupCondition(ModelType, field, undefined, op, childConditions.map(c => (0, exports.internals)(c))));
|
|
810
665
|
// FinalPredicate
|
|
811
666
|
return registerPredicateInternals(query);
|
|
812
667
|
};
|
|
813
668
|
});
|
|
814
669
|
// TODO: If revisiting this code, consider proxy.
|
|
815
|
-
link.not =
|
|
670
|
+
link.not = (builder) => {
|
|
816
671
|
// not() will return a copy of the original link
|
|
817
672
|
// to head off mutability concerns.
|
|
818
|
-
|
|
673
|
+
const { query, newTail } = copyLink();
|
|
819
674
|
// unlike and() and or(), the customer will supply a "singular" child predicate.
|
|
820
675
|
// the difference being: not() does not accept an array of predicate-like objects.
|
|
821
676
|
// it negates only a *single* predicate subtree.
|
|
822
|
-
newTail
|
|
823
|
-
exports.internals(builder(recursivePredicateFor(ModelType, allowRecursion))),
|
|
677
|
+
newTail?.operands.push(new GroupCondition(ModelType, field, undefined, 'not', [
|
|
678
|
+
(0, exports.internals)(builder(recursivePredicateFor(ModelType, allowRecursion))),
|
|
824
679
|
]));
|
|
825
680
|
// A `FinalModelPredicate`.
|
|
826
681
|
// Return a thing that can no longer be extended, but instead used to `async filter(items)`
|
|
827
682
|
// or query storage: `.__query.fetch(storage)`.
|
|
828
683
|
return registerPredicateInternals(query);
|
|
829
684
|
};
|
|
830
|
-
|
|
685
|
+
// For each field on the model schema, we want to add a getter
|
|
686
|
+
// that creates the appropriate new `link` in the query chain.
|
|
687
|
+
// TODO: If revisiting, consider a proxy.
|
|
688
|
+
for (const fieldName in ModelType.schema.allFields) {
|
|
831
689
|
Object.defineProperty(link, fieldName, {
|
|
832
690
|
enumerable: true,
|
|
833
|
-
get:
|
|
834
|
-
|
|
691
|
+
get: () => {
|
|
692
|
+
const def = ModelType.schema.allFields[fieldName];
|
|
835
693
|
if (!def.association) {
|
|
836
694
|
// we're looking at a value field. we need to return a
|
|
837
695
|
// "field matcher object", which contains all of the comparison
|
|
838
696
|
// functions ('eq', 'ne', 'gt', etc.), scoped to operate
|
|
839
697
|
// against the target field (fieldName).
|
|
840
|
-
return ops.reduce(
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
}
|
|
698
|
+
return ops.reduce((fieldMatcher, operator) => {
|
|
699
|
+
return {
|
|
700
|
+
...fieldMatcher,
|
|
701
|
+
// each operator on the fieldMatcher objcect is a function.
|
|
702
|
+
// when the customer calls the function, it returns a new link
|
|
703
|
+
// in the chain -- for now -- this is the "leaf" link that
|
|
704
|
+
// cannot be further extended.
|
|
705
|
+
[operator]: (...operands) => {
|
|
706
|
+
// build off a fresh copy of the existing `link`, just in case
|
|
707
|
+
// the same link is being used elsewhere by the customer.
|
|
708
|
+
const { query, newTail } = copyLink();
|
|
709
|
+
// normalize operands. if any of the values are `undefiend`, use
|
|
710
|
+
// `null` instead, because that's what will be stored cross-platform.
|
|
711
|
+
const normalizedOperands = operands.map(o => o === undefined ? null : o);
|
|
712
|
+
// add the given condition to the link's TAIL node.
|
|
713
|
+
// remember: the base link might go N nodes deep! e.g.,
|
|
714
|
+
newTail?.operands.push(new FieldCondition(fieldName, operator, normalizedOperands));
|
|
715
|
+
// A `FinalModelPredicate`.
|
|
716
|
+
// Return a thing that can no longer be extended, but instead used to `async filter(items)`
|
|
717
|
+
// or query storage: `.__query.fetch(storage)`.
|
|
718
|
+
return registerPredicateInternals(query);
|
|
719
|
+
},
|
|
720
|
+
};
|
|
863
721
|
}, {});
|
|
864
722
|
}
|
|
865
723
|
else {
|
|
@@ -871,20 +729,20 @@ function recursivePredicateFor(ModelType, allowRecursion, field, query, tail) {
|
|
|
871
729
|
def.association.connectionType === 'HAS_MANY') {
|
|
872
730
|
// the use has just typed '.someRelatedModel'. we need to given them
|
|
873
731
|
// back a predicate chain.
|
|
874
|
-
|
|
732
|
+
const relatedMeta = def.type.modelConstructor;
|
|
875
733
|
if (!relatedMeta) {
|
|
876
734
|
throw new Error('Related model metadata is missing. This is a bug! Please report it.');
|
|
877
735
|
}
|
|
878
736
|
// `Model.reletedModelField` returns a copy of the original link,
|
|
879
737
|
// and will contains copies of internal GroupConditions
|
|
880
738
|
// to head off mutability concerns.
|
|
881
|
-
|
|
882
|
-
|
|
739
|
+
const [newquery, oldtail] = baseCondition.copy(tailCondition);
|
|
740
|
+
const newtail = new GroupCondition(relatedMeta, fieldName, def.association.connectionType, 'and', []);
|
|
883
741
|
// `oldtail` here refers to the *copy* of the old tail.
|
|
884
742
|
// so, it's safe to modify at this point. and we need to modify
|
|
885
743
|
// it to push the *new* tail onto the end of it.
|
|
886
744
|
oldtail.operands.push(newtail);
|
|
887
|
-
|
|
745
|
+
const newlink = recursivePredicateFor(relatedMeta, allowRecursion, undefined, newquery, newtail);
|
|
888
746
|
return newlink;
|
|
889
747
|
}
|
|
890
748
|
else {
|
|
@@ -893,12 +751,6 @@ function recursivePredicateFor(ModelType, allowRecursion, field, query, tail) {
|
|
|
893
751
|
}
|
|
894
752
|
},
|
|
895
753
|
});
|
|
896
|
-
};
|
|
897
|
-
// For each field on the model schema, we want to add a getter
|
|
898
|
-
// that creates the appropriate new `link` in the query chain.
|
|
899
|
-
// TODO: If revisiting, consider a proxy.
|
|
900
|
-
for (var fieldName in ModelType.schema.allFields) {
|
|
901
|
-
_loop_1(fieldName);
|
|
902
754
|
}
|
|
903
755
|
return link;
|
|
904
756
|
}
|
|
@@ -909,4 +761,3 @@ function predicateFor(ModelType) {
|
|
|
909
761
|
return recursivePredicateFor(ModelType, false);
|
|
910
762
|
}
|
|
911
763
|
exports.predicateFor = predicateFor;
|
|
912
|
-
//# sourceMappingURL=next.js.map
|