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