@aws-amplify/datastore 3.14.4 → 3.14.5-unstable.2
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/CHANGELOG.md +0 -8
- package/lib/authModeStrategies/defaultAuthStrategy.d.ts +2 -0
- package/lib/authModeStrategies/index.d.ts +2 -0
- package/lib/authModeStrategies/multiAuthStrategy.d.ts +13 -0
- package/lib/authModeStrategies/multiAuthStrategy.js +6 -64
- package/lib/authModeStrategies/multiAuthStrategy.js.map +1 -1
- package/lib/datastore/datastore.d.ts +207 -0
- package/lib/datastore/datastore.js +703 -297
- package/lib/datastore/datastore.js.map +1 -1
- package/lib/index.d.ts +16 -0
- package/lib/index.js +6 -4
- package/lib/index.js.map +1 -1
- package/lib/predicates/index.d.ts +30 -0
- package/lib/predicates/index.js +127 -6
- package/lib/predicates/index.js.map +1 -1
- package/lib/predicates/next.d.ts +301 -0
- package/lib/predicates/next.js +816 -0
- package/lib/predicates/next.js.map +1 -0
- package/lib/predicates/sort.d.ts +8 -0
- package/lib/predicates/sort.js +10 -4
- package/lib/predicates/sort.js.map +1 -1
- package/lib/ssr/index.d.ts +3 -0
- package/lib/storage/adapter/AsyncStorageAdapter.d.ts +42 -0
- package/lib/storage/adapter/AsyncStorageAdapter.js +141 -382
- package/lib/storage/adapter/AsyncStorageAdapter.js.map +1 -1
- package/lib/storage/adapter/AsyncStorageDatabase.d.ts +39 -0
- package/lib/storage/adapter/AsyncStorageDatabase.js +37 -98
- package/lib/storage/adapter/AsyncStorageDatabase.js.map +1 -1
- package/lib/storage/adapter/InMemoryStore.d.ts +11 -0
- package/lib/storage/adapter/InMemoryStore.js +16 -67
- package/lib/storage/adapter/InMemoryStore.js.map +1 -1
- package/lib/storage/adapter/InMemoryStore.native.d.ts +1 -0
- package/lib/storage/adapter/InMemoryStore.native.js +2 -4
- package/lib/storage/adapter/InMemoryStore.native.js.map +1 -1
- package/lib/storage/adapter/IndexedDBAdapter.d.ts +61 -0
- package/lib/storage/adapter/IndexedDBAdapter.js +275 -419
- package/lib/storage/adapter/IndexedDBAdapter.js.map +1 -1
- package/lib/storage/adapter/getDefaultAdapter/index.d.ts +3 -0
- package/lib/storage/adapter/getDefaultAdapter/index.js +3 -5
- package/lib/storage/adapter/getDefaultAdapter/index.js.map +1 -1
- package/lib/storage/adapter/getDefaultAdapter/index.native.d.ts +3 -0
- package/lib/storage/adapter/getDefaultAdapter/index.native.js +2 -4
- package/lib/storage/adapter/getDefaultAdapter/index.native.js.map +1 -1
- package/lib/storage/adapter/index.d.ts +9 -0
- package/lib/storage/relationship.d.ts +140 -0
- package/lib/storage/relationship.js +335 -0
- package/lib/storage/relationship.js.map +1 -0
- package/lib/storage/storage.d.ts +50 -0
- package/lib/storage/storage.js +72 -143
- package/lib/storage/storage.js.map +1 -1
- package/lib/sync/datastoreConnectivity.d.ts +16 -0
- package/lib/sync/datastoreConnectivity.js +6 -55
- package/lib/sync/datastoreConnectivity.js.map +1 -1
- package/lib/sync/datastoreReachability/index.d.ts +3 -0
- package/lib/sync/datastoreReachability/index.native.d.ts +3 -0
- package/lib/sync/datastoreReachability/index.native.js +2 -4
- package/lib/sync/datastoreReachability/index.native.js.map +1 -1
- package/lib/sync/index.d.ts +89 -0
- package/lib/sync/index.js +49 -124
- package/lib/sync/index.js.map +1 -1
- package/lib/sync/merger.d.ts +17 -0
- package/lib/sync/merger.js +8 -74
- package/lib/sync/merger.js.map +1 -1
- package/lib/sync/outbox.d.ts +27 -0
- package/lib/sync/outbox.js +24 -97
- package/lib/sync/outbox.js.map +1 -1
- package/lib/sync/processors/errorMaps.d.ts +17 -0
- package/lib/sync/processors/errorMaps.js +5 -35
- package/lib/sync/processors/errorMaps.js.map +1 -1
- package/lib/sync/processors/mutation.d.ts +58 -0
- package/lib/sync/processors/mutation.js +47 -131
- package/lib/sync/processors/mutation.js.map +1 -1
- package/lib/sync/processors/subscription.d.ts +33 -0
- package/lib/sync/processors/subscription.js +29 -102
- package/lib/sync/processors/subscription.js.map +1 -1
- package/lib/sync/processors/sync.d.ts +28 -0
- package/lib/sync/processors/sync.js +26 -102
- package/lib/sync/processors/sync.js.map +1 -1
- package/lib/sync/utils.d.ts +42 -0
- package/lib/sync/utils.js +40 -103
- package/lib/sync/utils.js.map +1 -1
- package/lib/types.d.ts +554 -0
- package/lib/types.js +9 -39
- package/lib/types.js.map +1 -1
- package/lib/util.d.ts +189 -0
- package/lib/util.js +192 -188
- package/lib/util.js.map +1 -1
- package/lib-esm/authModeStrategies/multiAuthStrategy.js +2 -57
- package/lib-esm/authModeStrategies/multiAuthStrategy.js.map +1 -1
- package/lib-esm/datastore/datastore.d.ts +59 -8
- package/lib-esm/datastore/datastore.js +642 -234
- package/lib-esm/datastore/datastore.js.map +1 -1
- package/lib-esm/index.d.ts +3 -2
- package/lib-esm/index.js +2 -1
- package/lib-esm/index.js.map +1 -1
- package/lib-esm/predicates/index.d.ts +16 -2
- package/lib-esm/predicates/index.js +128 -7
- package/lib-esm/predicates/index.js.map +1 -1
- package/lib-esm/predicates/next.d.ts +301 -0
- package/lib-esm/predicates/next.js +812 -0
- package/lib-esm/predicates/next.js.map +1 -0
- package/lib-esm/predicates/sort.js +10 -4
- package/lib-esm/predicates/sort.js.map +1 -1
- package/lib-esm/storage/adapter/AsyncStorageAdapter.d.ts +2 -1
- package/lib-esm/storage/adapter/AsyncStorageAdapter.js +112 -350
- package/lib-esm/storage/adapter/AsyncStorageAdapter.js.map +1 -1
- package/lib-esm/storage/adapter/AsyncStorageDatabase.js +7 -68
- package/lib-esm/storage/adapter/AsyncStorageDatabase.js.map +1 -1
- package/lib-esm/storage/adapter/InMemoryStore.d.ts +1 -1
- package/lib-esm/storage/adapter/InMemoryStore.js +1 -52
- package/lib-esm/storage/adapter/InMemoryStore.js.map +1 -1
- package/lib-esm/storage/adapter/IndexedDBAdapter.d.ts +4 -2
- package/lib-esm/storage/adapter/IndexedDBAdapter.js +230 -367
- package/lib-esm/storage/adapter/IndexedDBAdapter.js.map +1 -1
- package/lib-esm/storage/adapter/getDefaultAdapter/index.js.map +1 -1
- package/lib-esm/storage/relationship.d.ts +140 -0
- package/lib-esm/storage/relationship.js +333 -0
- package/lib-esm/storage/relationship.js.map +1 -0
- package/lib-esm/storage/storage.d.ts +7 -6
- package/lib-esm/storage/storage.js +33 -101
- package/lib-esm/storage/storage.js.map +1 -1
- package/lib-esm/sync/datastoreConnectivity.js +1 -47
- package/lib-esm/sync/datastoreConnectivity.js.map +1 -1
- package/lib-esm/sync/index.js +4 -76
- package/lib-esm/sync/index.js.map +1 -1
- package/lib-esm/sync/merger.js +1 -67
- package/lib-esm/sync/merger.js.map +1 -1
- package/lib-esm/sync/outbox.js +1 -74
- package/lib-esm/sync/outbox.js.map +1 -1
- package/lib-esm/sync/processors/errorMaps.js +2 -32
- package/lib-esm/sync/processors/errorMaps.js.map +1 -1
- package/lib-esm/sync/processors/mutation.js +12 -93
- package/lib-esm/sync/processors/mutation.js.map +1 -1
- package/lib-esm/sync/processors/subscription.js +6 -69
- package/lib-esm/sync/processors/subscription.js.map +1 -1
- package/lib-esm/sync/processors/sync.js +2 -75
- package/lib-esm/sync/processors/sync.js.map +1 -1
- package/lib-esm/sync/utils.d.ts +1 -1
- package/lib-esm/sync/utils.js +32 -95
- package/lib-esm/sync/utils.js.map +1 -1
- package/lib-esm/types.d.ts +63 -10
- package/lib-esm/types.js +7 -38
- package/lib-esm/types.js.map +1 -1
- package/lib-esm/util.d.ts +39 -6
- package/lib-esm/util.js +171 -171
- package/lib-esm/util.js.map +1 -1
- package/package.json +21 -14
- package/src/authModeStrategies/multiAuthStrategy.ts +2 -2
- package/src/datastore/datastore.ts +699 -206
- package/src/index.ts +4 -0
- package/src/predicates/index.ts +143 -17
- package/src/predicates/next.ts +967 -0
- package/src/predicates/sort.ts +8 -2
- package/src/storage/adapter/AsyncStorageAdapter.ts +59 -181
- package/src/storage/adapter/AsyncStorageDatabase.ts +16 -15
- package/src/storage/adapter/InMemoryStore.ts +5 -2
- package/src/storage/adapter/IndexedDBAdapter.ts +169 -192
- package/src/storage/adapter/getDefaultAdapter/index.ts +2 -2
- package/src/storage/relationship.ts +272 -0
- package/src/storage/storage.ts +56 -37
- package/src/sync/datastoreConnectivity.ts +4 -4
- package/src/sync/index.ts +22 -28
- package/src/sync/merger.ts +1 -1
- package/src/sync/outbox.ts +6 -6
- package/src/sync/processors/errorMaps.ts +1 -1
- package/src/sync/processors/mutation.ts +23 -19
- package/src/sync/processors/subscription.ts +20 -16
- package/src/sync/processors/sync.ts +17 -17
- package/src/sync/utils.ts +42 -48
- package/src/types.ts +128 -16
- package/src/util.ts +108 -150
- package/build.js +0 -5
- package/dist/aws-amplify-datastore.js +0 -92787
- package/dist/aws-amplify-datastore.js.map +0 -1
- package/dist/aws-amplify-datastore.min.js +0 -66
- package/dist/aws-amplify-datastore.min.js.map +0 -1
- package/index.js +0 -7
- package/webpack.config.dev.js +0 -6
|
@@ -0,0 +1,816 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
var tslib_1 = require("tslib");
|
|
4
|
+
var index_1 = require("./index");
|
|
5
|
+
var relationship_1 = require("../storage/relationship");
|
|
6
|
+
var util_1 = require("../util");
|
|
7
|
+
var ops = tslib_1.__spread(index_1.comparisonKeys);
|
|
8
|
+
/**
|
|
9
|
+
* A pointer used by DataStore internally to lookup predicate details
|
|
10
|
+
* that should not be exposed on public customer interfaces.
|
|
11
|
+
*/
|
|
12
|
+
var PredicateInternalsKey = /** @class */ (function () {
|
|
13
|
+
function PredicateInternalsKey() {
|
|
14
|
+
this.__isPredicateInternalsKeySentinel = true;
|
|
15
|
+
}
|
|
16
|
+
return PredicateInternalsKey;
|
|
17
|
+
}());
|
|
18
|
+
exports.PredicateInternalsKey = PredicateInternalsKey;
|
|
19
|
+
/**
|
|
20
|
+
* A map from keys (exposed to customers) to the internal predicate data
|
|
21
|
+
* structures invoking code should not muck with.
|
|
22
|
+
*/
|
|
23
|
+
var predicateInternalsMap = new Map();
|
|
24
|
+
/**
|
|
25
|
+
* Creates a link between a key (and generates a key if needed) and an internal
|
|
26
|
+
* `GroupCondition`, which allows us to return a key object instead of the gory
|
|
27
|
+
* conditions details to customers/invoking code.
|
|
28
|
+
*
|
|
29
|
+
* @param condition The internal condition to keep hidden.
|
|
30
|
+
* @param key The object DataStore will use to find the internal condition.
|
|
31
|
+
* If no key is given, an empty one is created.
|
|
32
|
+
*/
|
|
33
|
+
var registerPredicateInternals = function (condition, key) {
|
|
34
|
+
var finalKey = key || new PredicateInternalsKey();
|
|
35
|
+
predicateInternalsMap.set(finalKey, condition);
|
|
36
|
+
return finalKey;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Takes a key object from `registerPredicateInternals()` to fetch an internal
|
|
40
|
+
* `GroupCondition` object, which can then be used to query storage or
|
|
41
|
+
* test/match objects.
|
|
42
|
+
*
|
|
43
|
+
* This indirection exists to hide `GroupCondition` from public interfaces, since
|
|
44
|
+
* `GroupCondition` contains extra methods and properties that public callers
|
|
45
|
+
* should not use.
|
|
46
|
+
*
|
|
47
|
+
* @param key A key object previously returned by `registerPredicateInternals()`
|
|
48
|
+
*/
|
|
49
|
+
exports.internals = function (key) {
|
|
50
|
+
if (!predicateInternalsMap.has(key)) {
|
|
51
|
+
throw new Error("Invalid predicate. Terminate your predicate with a valid condition (e.g., `p => p.field.eq('value')`) or pass `Predicates.ALL`.");
|
|
52
|
+
}
|
|
53
|
+
return predicateInternalsMap.get(key);
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Maps operators to negated operators.
|
|
57
|
+
* Used to facilitate propagation of negation down a tree of conditions.
|
|
58
|
+
*/
|
|
59
|
+
var negations = {
|
|
60
|
+
and: 'or',
|
|
61
|
+
or: 'and',
|
|
62
|
+
not: 'and',
|
|
63
|
+
eq: 'ne',
|
|
64
|
+
ne: 'eq',
|
|
65
|
+
gt: 'le',
|
|
66
|
+
ge: 'lt',
|
|
67
|
+
lt: 'ge',
|
|
68
|
+
le: 'gt',
|
|
69
|
+
contains: 'notContains',
|
|
70
|
+
notContains: 'contains',
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* Given a V1 predicate "seed", applies a list of V2 field-level conditions
|
|
74
|
+
* to the predicate, returning a new/final V1 predicate chain link.
|
|
75
|
+
* @param predicate The base/seed V1 predicate to build on
|
|
76
|
+
* @param conditions The V2 conditions to add to the predicate chain.
|
|
77
|
+
* @param negateChildren Whether the conditions should be negated first.
|
|
78
|
+
* @returns A V1 predicate, with conditions incorporated.
|
|
79
|
+
*/
|
|
80
|
+
function applyConditionsToV1Predicate(predicate, conditions, negateChildren) {
|
|
81
|
+
var e_1, _a, e_2, _b;
|
|
82
|
+
var p = predicate;
|
|
83
|
+
var finalConditions = [];
|
|
84
|
+
try {
|
|
85
|
+
for (var conditions_1 = tslib_1.__values(conditions), conditions_1_1 = conditions_1.next(); !conditions_1_1.done; conditions_1_1 = conditions_1.next()) {
|
|
86
|
+
var c = conditions_1_1.value;
|
|
87
|
+
if (negateChildren) {
|
|
88
|
+
if (c.operator === 'between') {
|
|
89
|
+
finalConditions.push(new FieldCondition(c.field, 'lt', [c.operands[0]]), new FieldCondition(c.field, 'gt', [c.operands[1]]));
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
finalConditions.push(new FieldCondition(c.field, negations[c.operator], c.operands));
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
finalConditions.push(c);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
101
|
+
finally {
|
|
102
|
+
try {
|
|
103
|
+
if (conditions_1_1 && !conditions_1_1.done && (_a = conditions_1.return)) _a.call(conditions_1);
|
|
104
|
+
}
|
|
105
|
+
finally { if (e_1) throw e_1.error; }
|
|
106
|
+
}
|
|
107
|
+
try {
|
|
108
|
+
for (var finalConditions_1 = tslib_1.__values(finalConditions), finalConditions_1_1 = finalConditions_1.next(); !finalConditions_1_1.done; finalConditions_1_1 = finalConditions_1.next()) {
|
|
109
|
+
var c = finalConditions_1_1.value;
|
|
110
|
+
p = p[c.field](c.operator, (c.operator === 'between' ? c.operands : c.operands[0]));
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
114
|
+
finally {
|
|
115
|
+
try {
|
|
116
|
+
if (finalConditions_1_1 && !finalConditions_1_1.done && (_b = finalConditions_1.return)) _b.call(finalConditions_1);
|
|
117
|
+
}
|
|
118
|
+
finally { if (e_2) throw e_2.error; }
|
|
119
|
+
}
|
|
120
|
+
return p;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* A condition that can operate against a single "primitive" field of a model or item.
|
|
124
|
+
* @member field The field of *some record* to test against.
|
|
125
|
+
* @member operator The equality or comparison operator to use.
|
|
126
|
+
* @member operands The operands for the equality/comparison check.
|
|
127
|
+
*/
|
|
128
|
+
var FieldCondition = /** @class */ (function () {
|
|
129
|
+
function FieldCondition(field, operator, operands) {
|
|
130
|
+
this.field = field;
|
|
131
|
+
this.operator = operator;
|
|
132
|
+
this.operands = operands;
|
|
133
|
+
this.validate();
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Creates a copy of self.
|
|
137
|
+
* @param extract Not used. Present only to fulfill the `UntypedCondition` interface.
|
|
138
|
+
* @returns A new, identitical `FieldCondition`.
|
|
139
|
+
*/
|
|
140
|
+
FieldCondition.prototype.copy = function (extract) {
|
|
141
|
+
return [
|
|
142
|
+
new FieldCondition(this.field, this.operator, tslib_1.__spread(this.operands)),
|
|
143
|
+
undefined,
|
|
144
|
+
];
|
|
145
|
+
};
|
|
146
|
+
FieldCondition.prototype.toAST = function () {
|
|
147
|
+
var _a, _b;
|
|
148
|
+
return _a = {},
|
|
149
|
+
_a[this.field] = (_b = {},
|
|
150
|
+
_b[this.operator] = this.operator === 'between'
|
|
151
|
+
? [this.operands[0], this.operands[1]]
|
|
152
|
+
: this.operands[0],
|
|
153
|
+
_b),
|
|
154
|
+
_a;
|
|
155
|
+
};
|
|
156
|
+
/**
|
|
157
|
+
* Not implemented. Not needed. GroupCondition instead consumes FieldConditions and
|
|
158
|
+
* transforms them into legacy predicates. (*For now.*)
|
|
159
|
+
* @param storage N/A. If ever implemented, the storage adapter to query.
|
|
160
|
+
* @returns N/A. If ever implemented, return items from `storage` that match.
|
|
161
|
+
*/
|
|
162
|
+
FieldCondition.prototype.fetch = function (storage) {
|
|
163
|
+
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
164
|
+
return tslib_1.__generator(this, function (_a) {
|
|
165
|
+
return [2 /*return*/, Promise.reject('No implementation needed [yet].')];
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
};
|
|
169
|
+
/**
|
|
170
|
+
* Determins whether a given item matches the expressed condition.
|
|
171
|
+
* @param item The item to test.
|
|
172
|
+
* @returns `Promise<boolean>`, `true` if matches; `false` otherwise.
|
|
173
|
+
*/
|
|
174
|
+
FieldCondition.prototype.matches = function (item) {
|
|
175
|
+
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
176
|
+
var v, operations, operation;
|
|
177
|
+
var _this = this;
|
|
178
|
+
return tslib_1.__generator(this, function (_a) {
|
|
179
|
+
v = String(item[this.field]);
|
|
180
|
+
operations = {
|
|
181
|
+
eq: function () { return v === _this.operands[0]; },
|
|
182
|
+
ne: function () { return v !== _this.operands[0]; },
|
|
183
|
+
gt: function () { return v > _this.operands[0]; },
|
|
184
|
+
ge: function () { return v >= _this.operands[0]; },
|
|
185
|
+
lt: function () { return v < _this.operands[0]; },
|
|
186
|
+
le: function () { return v <= _this.operands[0]; },
|
|
187
|
+
contains: function () { return v.indexOf(_this.operands[0]) > -1; },
|
|
188
|
+
notContains: function () { return v.indexOf(_this.operands[0]) === -1; },
|
|
189
|
+
beginsWith: function () { return v.startsWith(_this.operands[0]); },
|
|
190
|
+
between: function () { return v >= _this.operands[0] && v <= _this.operands[1]; },
|
|
191
|
+
};
|
|
192
|
+
operation = operations[this.operator];
|
|
193
|
+
if (operation) {
|
|
194
|
+
return [2 /*return*/, operation()];
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
throw new Error("Invalid operator given: " + this.operator);
|
|
198
|
+
}
|
|
199
|
+
return [2 /*return*/];
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
};
|
|
203
|
+
/**
|
|
204
|
+
* Checks `this.operands` for compatibility with `this.operator`.
|
|
205
|
+
*/
|
|
206
|
+
FieldCondition.prototype.validate = function () {
|
|
207
|
+
var _this = this;
|
|
208
|
+
/**
|
|
209
|
+
* Creates a validator that checks for a particular `operands` count.
|
|
210
|
+
* Throws an exception if the `count` disagrees with `operands.length`.
|
|
211
|
+
* @param count The number of `operands` expected.
|
|
212
|
+
*/
|
|
213
|
+
var argumentCount = function (count) {
|
|
214
|
+
var argsClause = count === 1 ? 'argument is' : 'arguments are';
|
|
215
|
+
return function () {
|
|
216
|
+
if (_this.operands.length !== count) {
|
|
217
|
+
return "Exactly " + count + " " + argsClause + " required.";
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
};
|
|
221
|
+
// NOTE: validations should return a message on failure.
|
|
222
|
+
// hence, they should be "joined" together with logical OR's
|
|
223
|
+
// as seen in the `between:` entry.
|
|
224
|
+
var validations = {
|
|
225
|
+
eq: argumentCount(1),
|
|
226
|
+
ne: argumentCount(1),
|
|
227
|
+
gt: argumentCount(1),
|
|
228
|
+
ge: argumentCount(1),
|
|
229
|
+
lt: argumentCount(1),
|
|
230
|
+
le: argumentCount(1),
|
|
231
|
+
contains: argumentCount(1),
|
|
232
|
+
notContains: argumentCount(1),
|
|
233
|
+
beginsWith: argumentCount(1),
|
|
234
|
+
between: function () {
|
|
235
|
+
return argumentCount(2)() ||
|
|
236
|
+
(_this.operands[0] > _this.operands[1]
|
|
237
|
+
? 'The first argument must be less than or equal to the second argument.'
|
|
238
|
+
: null);
|
|
239
|
+
},
|
|
240
|
+
};
|
|
241
|
+
var validate = validations[this.operator];
|
|
242
|
+
if (validate) {
|
|
243
|
+
var e = validate();
|
|
244
|
+
if (typeof e === 'string')
|
|
245
|
+
throw new Error("Incorrect usage of `" + this.operator + "()`: " + e);
|
|
246
|
+
}
|
|
247
|
+
else {
|
|
248
|
+
throw new Error("Non-existent operator: `" + this.operator + "()`");
|
|
249
|
+
}
|
|
250
|
+
};
|
|
251
|
+
return FieldCondition;
|
|
252
|
+
}());
|
|
253
|
+
exports.FieldCondition = FieldCondition;
|
|
254
|
+
/**
|
|
255
|
+
* Small utility function to generate a monotonically increasing ID.
|
|
256
|
+
* Used by GroupCondition to help keep track of which group is doing what,
|
|
257
|
+
* when, and where during troubleshooting.
|
|
258
|
+
*/
|
|
259
|
+
var getGroupId = (function () {
|
|
260
|
+
var seed = 1;
|
|
261
|
+
return function () { return "group_" + seed++; };
|
|
262
|
+
})();
|
|
263
|
+
/**
|
|
264
|
+
* A set of sub-conditions to operate against a model, optionally scoped to
|
|
265
|
+
* a specific field, combined with the given operator (one of `and`, `or`, or `not`).
|
|
266
|
+
* @member groupId Used to distinguish between GroupCondition instances for
|
|
267
|
+
* debugging and troublehsooting.
|
|
268
|
+
* @member model A metadata object that tells GroupCondition what to query and how.
|
|
269
|
+
* @member field The field on the model that the sub-conditions apply to.
|
|
270
|
+
* @member operator How to group child conditions together.
|
|
271
|
+
* @member operands The child conditions.
|
|
272
|
+
*/
|
|
273
|
+
var GroupCondition = /** @class */ (function () {
|
|
274
|
+
function GroupCondition(
|
|
275
|
+
/**
|
|
276
|
+
* The `ModelMeta` of the model to query and/or filter against.
|
|
277
|
+
* Expected to contain:
|
|
278
|
+
*
|
|
279
|
+
* ```js
|
|
280
|
+
* {
|
|
281
|
+
* builder: ModelConstructor,
|
|
282
|
+
* schema: SchemaModel,
|
|
283
|
+
* pkField: string[]
|
|
284
|
+
* }
|
|
285
|
+
* ```
|
|
286
|
+
*/
|
|
287
|
+
model,
|
|
288
|
+
/**
|
|
289
|
+
* If populated, this group specifices a condition on a relationship.
|
|
290
|
+
*
|
|
291
|
+
* If `field` does *not* point to a related model, that's an error. It
|
|
292
|
+
* could indicate that the `GroupCondition` was instantiated with bad
|
|
293
|
+
* data, or that the model metadata is incorrect.
|
|
294
|
+
*/
|
|
295
|
+
field,
|
|
296
|
+
/**
|
|
297
|
+
* If a `field` is given, whether the relationship is a `HAS_ONE`,
|
|
298
|
+
* 'HAS_MANY`, or `BELONGS_TO`.
|
|
299
|
+
*
|
|
300
|
+
* TODO: Remove this and replace with derivation using
|
|
301
|
+
* `ModelRelationship.from(this.model, this.field).relationship`;
|
|
302
|
+
*/
|
|
303
|
+
relationshipType,
|
|
304
|
+
/**
|
|
305
|
+
*
|
|
306
|
+
*/
|
|
307
|
+
operator,
|
|
308
|
+
/**
|
|
309
|
+
*
|
|
310
|
+
*/
|
|
311
|
+
operands) {
|
|
312
|
+
this.model = model;
|
|
313
|
+
this.field = field;
|
|
314
|
+
this.relationshipType = relationshipType;
|
|
315
|
+
this.operator = operator;
|
|
316
|
+
this.operands = operands;
|
|
317
|
+
// `groupId` was used for development/debugging.
|
|
318
|
+
// Should we leave this in for future troubleshooting?
|
|
319
|
+
this.groupId = getGroupId();
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Returns a copy of a GroupCondition, which also returns the copy of a
|
|
323
|
+
* given reference node to "extract".
|
|
324
|
+
* @param extract A node of interest. Its copy will *also* be returned if the node exists.
|
|
325
|
+
* @returns [The full copy, the copy of `extract` | undefined]
|
|
326
|
+
*/
|
|
327
|
+
GroupCondition.prototype.copy = function (extract) {
|
|
328
|
+
var copied = new GroupCondition(this.model, this.field, this.relationshipType, this.operator, []);
|
|
329
|
+
var extractedCopy = extract === this ? copied : undefined;
|
|
330
|
+
this.operands.forEach(function (o) {
|
|
331
|
+
var _a = tslib_1.__read(o.copy(extract), 2), operandCopy = _a[0], extractedFromOperand = _a[1];
|
|
332
|
+
copied.operands.push(operandCopy);
|
|
333
|
+
extractedCopy = extractedCopy || extractedFromOperand;
|
|
334
|
+
});
|
|
335
|
+
return [copied, extractedCopy];
|
|
336
|
+
};
|
|
337
|
+
/**
|
|
338
|
+
* Fetches matching records from a given storage adapter using legacy predicates (for now).
|
|
339
|
+
* @param storage The storage adapter this predicate will query against.
|
|
340
|
+
* @param breadcrumb For debugging/troubleshooting. A list of the `groupId`'s this
|
|
341
|
+
* GroupdCondition.fetch is nested within.
|
|
342
|
+
* @param negate Whether to match on the `NOT` of `this`.
|
|
343
|
+
* @returns An `Promise` of `any[]` from `storage` matching the child conditions.
|
|
344
|
+
*/
|
|
345
|
+
GroupCondition.prototype.fetch = function (storage, breadcrumb, negate) {
|
|
346
|
+
if (breadcrumb === void 0) { breadcrumb = []; }
|
|
347
|
+
if (negate === void 0) { negate = false; }
|
|
348
|
+
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
349
|
+
var resultGroups, operator, negateChildren, groups, conditions, groups_1, groups_1_1, g, relatives, relationship, relativesPredicates, _loop_1, relatives_1, relatives_1_1, relative, predicate, _a, _b, e_3_1, predicate, _c, _d, _e, _f, getPKValue, resultIndex, resultGroups_1, resultGroups_1_1, group, intersectWith, _g, _h, k, resultGroups_2, resultGroups_2_1, group, group_1, group_1_1, item;
|
|
350
|
+
var e_3, _j, e_4, _k, e_5, _l, e_6, _m, e_7, _o, e_8, _p;
|
|
351
|
+
var _this = this;
|
|
352
|
+
return tslib_1.__generator(this, function (_q) {
|
|
353
|
+
switch (_q.label) {
|
|
354
|
+
case 0:
|
|
355
|
+
resultGroups = [];
|
|
356
|
+
operator = (negate ? negations[this.operator] : this.operator);
|
|
357
|
+
negateChildren = negate !== (this.operator === 'not');
|
|
358
|
+
groups = this.operands.filter(function (op) { return op instanceof GroupCondition; });
|
|
359
|
+
conditions = this.operands.filter(function (op) { return op instanceof FieldCondition; });
|
|
360
|
+
_q.label = 1;
|
|
361
|
+
case 1:
|
|
362
|
+
_q.trys.push([1, 10, 11, 12]);
|
|
363
|
+
groups_1 = tslib_1.__values(groups), groups_1_1 = groups_1.next();
|
|
364
|
+
_q.label = 2;
|
|
365
|
+
case 2:
|
|
366
|
+
if (!!groups_1_1.done) return [3 /*break*/, 9];
|
|
367
|
+
g = groups_1_1.value;
|
|
368
|
+
return [4 /*yield*/, g.fetch(storage, tslib_1.__spread(breadcrumb, [this.groupId]), negateChildren)];
|
|
369
|
+
case 3:
|
|
370
|
+
relatives = _q.sent();
|
|
371
|
+
// no relatives -> no need to attempt to perform a "join" query for
|
|
372
|
+
// candidate results:
|
|
373
|
+
//
|
|
374
|
+
// select a.* from a,b where b.id in EMPTY_SET ==> EMPTY_SET
|
|
375
|
+
//
|
|
376
|
+
// Additionally, the entire (sub)-query can be short-circuited if
|
|
377
|
+
// the operator is `AND`. Illustrated in SQL:
|
|
378
|
+
//
|
|
379
|
+
// select a.* from a where
|
|
380
|
+
// id in [a,b,c]
|
|
381
|
+
// AND <
|
|
382
|
+
// id in EMTPY_SET <<< Look!
|
|
383
|
+
// AND <
|
|
384
|
+
// id in [x,y,z]
|
|
385
|
+
//
|
|
386
|
+
// YIELDS: EMPTY_SET // <-- Easy peasy. Lemon squeezy.
|
|
387
|
+
//
|
|
388
|
+
if (relatives.length === 0) {
|
|
389
|
+
// aggressively short-circuit as soon as we know the group condition will fail
|
|
390
|
+
if (operator === 'and') {
|
|
391
|
+
return [2 /*return*/, []];
|
|
392
|
+
}
|
|
393
|
+
// less aggressive short-circuit if we know the relatives will produce no
|
|
394
|
+
// candidate results; but aren't sure yet how this affects the group condition.
|
|
395
|
+
resultGroups.push([]);
|
|
396
|
+
return [3 /*break*/, 8];
|
|
397
|
+
}
|
|
398
|
+
if (!g.field) return [3 /*break*/, 7];
|
|
399
|
+
relationship = relationship_1.ModelRelationship.from(this.model, g.field);
|
|
400
|
+
if (!relationship) return [3 /*break*/, 5];
|
|
401
|
+
relativesPredicates = [];
|
|
402
|
+
_loop_1 = function (relative) {
|
|
403
|
+
var individualRowJoinConditions = [];
|
|
404
|
+
for (var i = 0; i < relationship.localJoinFields.length; i++) {
|
|
405
|
+
// rightHandValue
|
|
406
|
+
individualRowJoinConditions.push(new FieldCondition(relationship.localJoinFields[i], 'eq', [
|
|
407
|
+
relative[relationship.remoteJoinFields[i]],
|
|
408
|
+
]));
|
|
409
|
+
}
|
|
410
|
+
var predicate_1 = function (p) {
|
|
411
|
+
return applyConditionsToV1Predicate(p, individualRowJoinConditions, false);
|
|
412
|
+
};
|
|
413
|
+
relativesPredicates.push(predicate_1);
|
|
414
|
+
};
|
|
415
|
+
try {
|
|
416
|
+
for (relatives_1 = (e_4 = void 0, tslib_1.__values(relatives)), relatives_1_1 = relatives_1.next(); !relatives_1_1.done; relatives_1_1 = relatives_1.next()) {
|
|
417
|
+
relative = relatives_1_1.value;
|
|
418
|
+
_loop_1(relative);
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
catch (e_4_1) { e_4 = { error: e_4_1 }; }
|
|
422
|
+
finally {
|
|
423
|
+
try {
|
|
424
|
+
if (relatives_1_1 && !relatives_1_1.done && (_k = relatives_1.return)) _k.call(relatives_1);
|
|
425
|
+
}
|
|
426
|
+
finally { if (e_4) throw e_4.error; }
|
|
427
|
+
}
|
|
428
|
+
predicate = index_1.ModelPredicateCreator.createGroupFromExisting(this.model.schema, 'or', relativesPredicates);
|
|
429
|
+
_b = (_a = resultGroups).push;
|
|
430
|
+
return [4 /*yield*/, storage.query(this.model.builder, predicate)];
|
|
431
|
+
case 4:
|
|
432
|
+
_b.apply(_a, [_q.sent()]);
|
|
433
|
+
return [3 /*break*/, 6];
|
|
434
|
+
case 5: throw new Error('Missing field metadata.');
|
|
435
|
+
case 6: return [3 /*break*/, 8];
|
|
436
|
+
case 7:
|
|
437
|
+
// relatives are not actually relatives. they're candidate results.
|
|
438
|
+
resultGroups.push(relatives);
|
|
439
|
+
_q.label = 8;
|
|
440
|
+
case 8:
|
|
441
|
+
groups_1_1 = groups_1.next();
|
|
442
|
+
return [3 /*break*/, 2];
|
|
443
|
+
case 9: return [3 /*break*/, 12];
|
|
444
|
+
case 10:
|
|
445
|
+
e_3_1 = _q.sent();
|
|
446
|
+
e_3 = { error: e_3_1 };
|
|
447
|
+
return [3 /*break*/, 12];
|
|
448
|
+
case 11:
|
|
449
|
+
try {
|
|
450
|
+
if (groups_1_1 && !groups_1_1.done && (_j = groups_1.return)) _j.call(groups_1);
|
|
451
|
+
}
|
|
452
|
+
finally { if (e_3) throw e_3.error; }
|
|
453
|
+
return [7 /*endfinally*/];
|
|
454
|
+
case 12:
|
|
455
|
+
if (!(conditions.length > 0)) return [3 /*break*/, 14];
|
|
456
|
+
predicate = index_1.ModelPredicateCreator.createFromExisting(this.model.schema, function (p) {
|
|
457
|
+
return p[operator](function (c) {
|
|
458
|
+
return applyConditionsToV1Predicate(c, conditions, negateChildren);
|
|
459
|
+
});
|
|
460
|
+
});
|
|
461
|
+
_d = (_c = resultGroups).push;
|
|
462
|
+
return [4 /*yield*/, storage.query(this.model.builder, predicate)];
|
|
463
|
+
case 13:
|
|
464
|
+
_d.apply(_c, [_q.sent()]);
|
|
465
|
+
return [3 /*break*/, 16];
|
|
466
|
+
case 14:
|
|
467
|
+
if (!(conditions.length === 0 && resultGroups.length === 0)) return [3 /*break*/, 16];
|
|
468
|
+
_f = (_e = resultGroups).push;
|
|
469
|
+
return [4 /*yield*/, storage.query(this.model.builder)];
|
|
470
|
+
case 15:
|
|
471
|
+
_f.apply(_e, [_q.sent()]);
|
|
472
|
+
_q.label = 16;
|
|
473
|
+
case 16:
|
|
474
|
+
getPKValue = function (item) {
|
|
475
|
+
return JSON.stringify(_this.model.pkField.map(function (name) { return item[name]; }));
|
|
476
|
+
};
|
|
477
|
+
if (operator === 'and') {
|
|
478
|
+
if (resultGroups.length === 0) {
|
|
479
|
+
return [2 /*return*/, []];
|
|
480
|
+
}
|
|
481
|
+
try {
|
|
482
|
+
// for each group, we intersect, removing items from the result index
|
|
483
|
+
// that aren't present in each subsequent group.
|
|
484
|
+
for (resultGroups_1 = tslib_1.__values(resultGroups), resultGroups_1_1 = resultGroups_1.next(); !resultGroups_1_1.done; resultGroups_1_1 = resultGroups_1.next()) {
|
|
485
|
+
group = resultGroups_1_1.value;
|
|
486
|
+
if (resultIndex === undefined) {
|
|
487
|
+
resultIndex = new Map(group.map(function (item) { return [getPKValue(item), item]; }));
|
|
488
|
+
}
|
|
489
|
+
else {
|
|
490
|
+
intersectWith = new Map(group.map(function (item) { return [getPKValue(item), item]; }));
|
|
491
|
+
try {
|
|
492
|
+
for (_g = (e_6 = void 0, tslib_1.__values(resultIndex.keys())), _h = _g.next(); !_h.done; _h = _g.next()) {
|
|
493
|
+
k = _h.value;
|
|
494
|
+
if (!intersectWith.has(k)) {
|
|
495
|
+
resultIndex.delete(k);
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
catch (e_6_1) { e_6 = { error: e_6_1 }; }
|
|
500
|
+
finally {
|
|
501
|
+
try {
|
|
502
|
+
if (_h && !_h.done && (_m = _g.return)) _m.call(_g);
|
|
503
|
+
}
|
|
504
|
+
finally { if (e_6) throw e_6.error; }
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
catch (e_5_1) { e_5 = { error: e_5_1 }; }
|
|
510
|
+
finally {
|
|
511
|
+
try {
|
|
512
|
+
if (resultGroups_1_1 && !resultGroups_1_1.done && (_l = resultGroups_1.return)) _l.call(resultGroups_1);
|
|
513
|
+
}
|
|
514
|
+
finally { if (e_5) throw e_5.error; }
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
else if (operator === 'or' || operator === 'not') {
|
|
518
|
+
// it's OK to handle NOT here, because NOT must always only negate
|
|
519
|
+
// a single child predicate. NOT logic will have been distributed down
|
|
520
|
+
// to the leaf conditions already.
|
|
521
|
+
resultIndex = new Map();
|
|
522
|
+
try {
|
|
523
|
+
// just merge the groups, performing DISTINCT-ification by ID.
|
|
524
|
+
for (resultGroups_2 = tslib_1.__values(resultGroups), resultGroups_2_1 = resultGroups_2.next(); !resultGroups_2_1.done; resultGroups_2_1 = resultGroups_2.next()) {
|
|
525
|
+
group = resultGroups_2_1.value;
|
|
526
|
+
try {
|
|
527
|
+
for (group_1 = (e_8 = void 0, tslib_1.__values(group)), group_1_1 = group_1.next(); !group_1_1.done; group_1_1 = group_1.next()) {
|
|
528
|
+
item = group_1_1.value;
|
|
529
|
+
resultIndex.set(getPKValue(item), item);
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
catch (e_8_1) { e_8 = { error: e_8_1 }; }
|
|
533
|
+
finally {
|
|
534
|
+
try {
|
|
535
|
+
if (group_1_1 && !group_1_1.done && (_p = group_1.return)) _p.call(group_1);
|
|
536
|
+
}
|
|
537
|
+
finally { if (e_8) throw e_8.error; }
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
catch (e_7_1) { e_7 = { error: e_7_1 }; }
|
|
542
|
+
finally {
|
|
543
|
+
try {
|
|
544
|
+
if (resultGroups_2_1 && !resultGroups_2_1.done && (_o = resultGroups_2.return)) _o.call(resultGroups_2);
|
|
545
|
+
}
|
|
546
|
+
finally { if (e_7) throw e_7.error; }
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
return [2 /*return*/, Array.from((resultIndex === null || resultIndex === void 0 ? void 0 : resultIndex.values()) || [])];
|
|
550
|
+
}
|
|
551
|
+
});
|
|
552
|
+
});
|
|
553
|
+
};
|
|
554
|
+
/**
|
|
555
|
+
* Determines whether a single item matches the conditions of `this`.
|
|
556
|
+
* When checking the target `item`'s properties, each property will be `await`'d
|
|
557
|
+
* to ensure lazy-loading is respected where applicable.
|
|
558
|
+
* @param item The item to match against.
|
|
559
|
+
* @param ignoreFieldName Tells `match()` that the field name has already been dereferenced.
|
|
560
|
+
* (Used for iterating over children on HAS_MANY checks.)
|
|
561
|
+
* @returns A boolean (promise): `true` if matched, `false` otherwise.
|
|
562
|
+
*/
|
|
563
|
+
GroupCondition.prototype.matches = function (item, ignoreFieldName) {
|
|
564
|
+
if (ignoreFieldName === void 0) { ignoreFieldName = false; }
|
|
565
|
+
var e_9, _a;
|
|
566
|
+
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
567
|
+
var itemToCheck, _b, itemToCheck_1, itemToCheck_1_1, singleItem, e_9_1;
|
|
568
|
+
return tslib_1.__generator(this, function (_c) {
|
|
569
|
+
switch (_c.label) {
|
|
570
|
+
case 0:
|
|
571
|
+
if (!(this.field && !ignoreFieldName)) return [3 /*break*/, 2];
|
|
572
|
+
return [4 /*yield*/, item[this.field]];
|
|
573
|
+
case 1:
|
|
574
|
+
_b = _c.sent();
|
|
575
|
+
return [3 /*break*/, 3];
|
|
576
|
+
case 2:
|
|
577
|
+
_b = item;
|
|
578
|
+
_c.label = 3;
|
|
579
|
+
case 3:
|
|
580
|
+
itemToCheck = _b;
|
|
581
|
+
// if there is no item to check, we can stop recursing immediately.
|
|
582
|
+
// a condition cannot match against an item that does not exist. this
|
|
583
|
+
// can occur when `item.field` is optional in the schema.
|
|
584
|
+
if (!itemToCheck) {
|
|
585
|
+
return [2 /*return*/, false];
|
|
586
|
+
}
|
|
587
|
+
if (!(this.relationshipType === 'HAS_MANY' &&
|
|
588
|
+
typeof itemToCheck[Symbol.asyncIterator] === 'function')) return [3 /*break*/, 17];
|
|
589
|
+
_c.label = 4;
|
|
590
|
+
case 4:
|
|
591
|
+
_c.trys.push([4, 10, 11, 16]);
|
|
592
|
+
itemToCheck_1 = tslib_1.__asyncValues(itemToCheck);
|
|
593
|
+
_c.label = 5;
|
|
594
|
+
case 5: return [4 /*yield*/, itemToCheck_1.next()];
|
|
595
|
+
case 6:
|
|
596
|
+
if (!(itemToCheck_1_1 = _c.sent(), !itemToCheck_1_1.done)) return [3 /*break*/, 9];
|
|
597
|
+
singleItem = itemToCheck_1_1.value;
|
|
598
|
+
return [4 /*yield*/, this.matches(singleItem, true)];
|
|
599
|
+
case 7:
|
|
600
|
+
if (_c.sent()) {
|
|
601
|
+
return [2 /*return*/, true];
|
|
602
|
+
}
|
|
603
|
+
_c.label = 8;
|
|
604
|
+
case 8: return [3 /*break*/, 5];
|
|
605
|
+
case 9: return [3 /*break*/, 16];
|
|
606
|
+
case 10:
|
|
607
|
+
e_9_1 = _c.sent();
|
|
608
|
+
e_9 = { error: e_9_1 };
|
|
609
|
+
return [3 /*break*/, 16];
|
|
610
|
+
case 11:
|
|
611
|
+
_c.trys.push([11, , 14, 15]);
|
|
612
|
+
if (!(itemToCheck_1_1 && !itemToCheck_1_1.done && (_a = itemToCheck_1.return))) return [3 /*break*/, 13];
|
|
613
|
+
return [4 /*yield*/, _a.call(itemToCheck_1)];
|
|
614
|
+
case 12:
|
|
615
|
+
_c.sent();
|
|
616
|
+
_c.label = 13;
|
|
617
|
+
case 13: return [3 /*break*/, 15];
|
|
618
|
+
case 14:
|
|
619
|
+
if (e_9) throw e_9.error;
|
|
620
|
+
return [7 /*endfinally*/];
|
|
621
|
+
case 15: return [7 /*endfinally*/];
|
|
622
|
+
case 16: return [2 /*return*/, false];
|
|
623
|
+
case 17:
|
|
624
|
+
if (!(this.operator === 'or')) return [3 /*break*/, 18];
|
|
625
|
+
return [2 /*return*/, util_1.asyncSome(this.operands, function (c) { return c.matches(itemToCheck); })];
|
|
626
|
+
case 18:
|
|
627
|
+
if (!(this.operator === 'and')) return [3 /*break*/, 19];
|
|
628
|
+
return [2 /*return*/, util_1.asyncEvery(this.operands, function (c) { return c.matches(itemToCheck); })];
|
|
629
|
+
case 19:
|
|
630
|
+
if (!(this.operator === 'not')) return [3 /*break*/, 21];
|
|
631
|
+
if (this.operands.length !== 1) {
|
|
632
|
+
throw new Error('Invalid arguments! `not()` accepts exactly one predicate expression.');
|
|
633
|
+
}
|
|
634
|
+
return [4 /*yield*/, this.operands[0].matches(itemToCheck)];
|
|
635
|
+
case 20: return [2 /*return*/, !(_c.sent())];
|
|
636
|
+
case 21: throw new Error('Invalid group operator!');
|
|
637
|
+
}
|
|
638
|
+
});
|
|
639
|
+
});
|
|
640
|
+
};
|
|
641
|
+
/**
|
|
642
|
+
* Tranfsorm to a AppSync GraphQL compatible AST.
|
|
643
|
+
* (Does not support filtering in nested types.)
|
|
644
|
+
*/
|
|
645
|
+
GroupCondition.prototype.toAST = function () {
|
|
646
|
+
var _a;
|
|
647
|
+
if (this.field)
|
|
648
|
+
throw new Error('Nested type conditions are not supported!');
|
|
649
|
+
return _a = {},
|
|
650
|
+
_a[this.operator] = this.operands.map(function (operand) { return operand.toAST(); }),
|
|
651
|
+
_a;
|
|
652
|
+
};
|
|
653
|
+
GroupCondition.prototype.toStoragePredicate = function (baseCondition) {
|
|
654
|
+
return index_1.ModelPredicateCreator.createFromAST(this.model.schema, this.toAST());
|
|
655
|
+
};
|
|
656
|
+
return GroupCondition;
|
|
657
|
+
}());
|
|
658
|
+
exports.GroupCondition = GroupCondition;
|
|
659
|
+
/**
|
|
660
|
+
* Creates a "seed" predicate that can be used to build an executable condition.
|
|
661
|
+
* This is used in `query()`, for example, to seed customer- E.g.,
|
|
662
|
+
*
|
|
663
|
+
* ```
|
|
664
|
+
* const p = predicateFor({builder: modelConstructor, schema: modelSchema, pkField: string[]});
|
|
665
|
+
* p.and(child => [
|
|
666
|
+
* child.field.eq('whatever'),
|
|
667
|
+
* child.childModel.childField.eq('whatever else'),
|
|
668
|
+
* child.childModel.or(child => [
|
|
669
|
+
* child.otherField.contains('x'),
|
|
670
|
+
* child.otherField.contains('y'),
|
|
671
|
+
* child.otherField.contains('z'),
|
|
672
|
+
* ])
|
|
673
|
+
* ])
|
|
674
|
+
* ```
|
|
675
|
+
*
|
|
676
|
+
* `predicateFor()` returns objecst with recursive getters. To facilitate this,
|
|
677
|
+
* a `query` and `tail` can be provided to "accumulate" nested conditions.
|
|
678
|
+
*
|
|
679
|
+
* TODO: the sortof-immutable algorithm was originally done to support legacy style
|
|
680
|
+
* predicate branching (`p => p.x.eq(value).y.eq(value)`). i'm not sure this is
|
|
681
|
+
* necessary or beneficial at this point, since we decided that each field condition
|
|
682
|
+
* must flly terminate a branch. is the strong mutation barrier between chain links
|
|
683
|
+
* still necessary or helpful?
|
|
684
|
+
*
|
|
685
|
+
* @param ModelType The ModelMeta used to build child properties.
|
|
686
|
+
* @param field Scopes the query branch to a field.
|
|
687
|
+
* @param query A base query to build on. Omit to start a new query.
|
|
688
|
+
* @param tail The point in an existing `query` to attach new conditions to.
|
|
689
|
+
* @returns A ModelPredicate (builder) that customers can create queries with.
|
|
690
|
+
* (As shown in function description.)
|
|
691
|
+
*/
|
|
692
|
+
function recursivePredicateFor(ModelType, allowRecursion, field, query, tail) {
|
|
693
|
+
if (allowRecursion === void 0) { allowRecursion = true; }
|
|
694
|
+
// to be used if we don't have a base query or tail to build onto
|
|
695
|
+
var starter = new GroupCondition(ModelType, field, undefined, 'and', []);
|
|
696
|
+
var baseCondition = query && tail ? query : starter;
|
|
697
|
+
var tailCondition = query && tail ? tail : starter;
|
|
698
|
+
// our eventual return object, which can be built upon.
|
|
699
|
+
// next steps will be to add or(), and(), not(), and field.op() methods.
|
|
700
|
+
var link = {};
|
|
701
|
+
registerPredicateInternals(baseCondition, link);
|
|
702
|
+
var copyLink = function () {
|
|
703
|
+
var _a = tslib_1.__read(baseCondition.copy(tailCondition), 2), query = _a[0], newTail = _a[1];
|
|
704
|
+
var newLink = recursivePredicateFor(ModelType, allowRecursion, undefined, query, newTail);
|
|
705
|
+
return { query: query, newTail: newTail, newLink: newLink };
|
|
706
|
+
};
|
|
707
|
+
// Adds .or() and .and() methods to the link.
|
|
708
|
+
// TODO: If revisiting this code, consider writing a Proxy instead.
|
|
709
|
+
['and', 'or'].forEach(function (op) {
|
|
710
|
+
link[op] = function (builder) {
|
|
711
|
+
// or() and and() will return a copy of the original link
|
|
712
|
+
// to head off mutability concerns.
|
|
713
|
+
var _a = copyLink(), query = _a.query, newTail = _a.newTail;
|
|
714
|
+
var childConditions = builder(recursivePredicateFor(ModelType, allowRecursion));
|
|
715
|
+
if (!Array.isArray(childConditions)) {
|
|
716
|
+
throw new Error("Invalid predicate. `" + op + "` groups must return an array of child conditions.");
|
|
717
|
+
}
|
|
718
|
+
// the customer will supply a child predicate, which apply to the `model.field`
|
|
719
|
+
// of the tail GroupCondition.
|
|
720
|
+
newTail === null || newTail === void 0 ? void 0 : newTail.operands.push(new GroupCondition(ModelType, field, undefined, op, childConditions.map(function (c) { return exports.internals(c); })));
|
|
721
|
+
// FinalPredicate
|
|
722
|
+
return registerPredicateInternals(query);
|
|
723
|
+
};
|
|
724
|
+
});
|
|
725
|
+
// TODO: If revisiting this code, consider proxy.
|
|
726
|
+
link.not = function (builder) {
|
|
727
|
+
// not() will return a copy of the original link
|
|
728
|
+
// to head off mutability concerns.
|
|
729
|
+
var _a = copyLink(), query = _a.query, newTail = _a.newTail;
|
|
730
|
+
// unlike and() and or(), the customer will supply a "singular" child predicate.
|
|
731
|
+
// the difference being: not() does not accept an array of predicate-like objects.
|
|
732
|
+
// it negates only a *single* predicate subtree.
|
|
733
|
+
newTail === null || newTail === void 0 ? void 0 : newTail.operands.push(new GroupCondition(ModelType, field, undefined, 'not', [
|
|
734
|
+
exports.internals(builder(recursivePredicateFor(ModelType, allowRecursion))),
|
|
735
|
+
]));
|
|
736
|
+
// A `FinalModelPredicate`.
|
|
737
|
+
// Return a thing that can no longer be extended, but instead used to `async filter(items)`
|
|
738
|
+
// or query storage: `.__query.fetch(storage)`.
|
|
739
|
+
return registerPredicateInternals(query);
|
|
740
|
+
};
|
|
741
|
+
var _loop_2 = function (fieldName) {
|
|
742
|
+
Object.defineProperty(link, fieldName, {
|
|
743
|
+
enumerable: true,
|
|
744
|
+
get: function () {
|
|
745
|
+
var def = ModelType.schema.fields[fieldName];
|
|
746
|
+
if (!def.association) {
|
|
747
|
+
// we're looking at a value field. we need to return a
|
|
748
|
+
// "field matcher object", which contains all of the comparison
|
|
749
|
+
// functions ('eq', 'ne', 'gt', etc.), scoped to operate
|
|
750
|
+
// against the target field (fieldName).
|
|
751
|
+
return ops.reduce(function (fieldMatcher, operator) {
|
|
752
|
+
var _a;
|
|
753
|
+
return tslib_1.__assign(tslib_1.__assign({}, fieldMatcher), (_a = {}, _a[operator] = function () {
|
|
754
|
+
var operands = [];
|
|
755
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
|
756
|
+
operands[_i] = arguments[_i];
|
|
757
|
+
}
|
|
758
|
+
// build off a fresh copy of the existing `link`, just in case
|
|
759
|
+
// the same link is being used elsewhere by the customer.
|
|
760
|
+
var _a = copyLink(), query = _a.query, newTail = _a.newTail;
|
|
761
|
+
// add the given condition to the link's TAIL node.
|
|
762
|
+
// remember: the base link might go N nodes deep! e.g.,
|
|
763
|
+
newTail === null || newTail === void 0 ? void 0 : newTail.operands.push(new FieldCondition(fieldName, operator, operands));
|
|
764
|
+
// A `FinalModelPredicate`.
|
|
765
|
+
// Return a thing that can no longer be extended, but instead used to `async filter(items)`
|
|
766
|
+
// or query storage: `.__query.fetch(storage)`.
|
|
767
|
+
return registerPredicateInternals(query);
|
|
768
|
+
}, _a));
|
|
769
|
+
}, {});
|
|
770
|
+
}
|
|
771
|
+
else {
|
|
772
|
+
if (!allowRecursion) {
|
|
773
|
+
throw new Error('Predication on releated models is not supported in this context.');
|
|
774
|
+
}
|
|
775
|
+
else if (def.association.connectionType === 'BELONGS_TO' ||
|
|
776
|
+
def.association.connectionType === 'HAS_ONE' ||
|
|
777
|
+
def.association.connectionType === 'HAS_MANY') {
|
|
778
|
+
// the use has just typed '.someRelatedModel'. we need to given them
|
|
779
|
+
// back a predicate chain.
|
|
780
|
+
var relatedMeta = def.type.modelConstructor;
|
|
781
|
+
if (!relatedMeta) {
|
|
782
|
+
throw new Error('Related model metadata is missing. This is a bug! Please report it.');
|
|
783
|
+
}
|
|
784
|
+
// `Model.reletedModelField` returns a copy of the original link,
|
|
785
|
+
// and will contains copies of internal GroupConditions
|
|
786
|
+
// to head off mutability concerns.
|
|
787
|
+
var _a = tslib_1.__read(baseCondition.copy(tailCondition), 2), newquery = _a[0], oldtail = _a[1];
|
|
788
|
+
var newtail = new GroupCondition(relatedMeta, fieldName, def.association.connectionType, 'and', []);
|
|
789
|
+
// `oldtail` here refers to the *copy* of the old tail.
|
|
790
|
+
// so, it's safe to modify at this point. and we need to modify
|
|
791
|
+
// it to push the *new* tail onto the end of it.
|
|
792
|
+
oldtail.operands.push(newtail);
|
|
793
|
+
var newlink = recursivePredicateFor(relatedMeta, allowRecursion, undefined, newquery, newtail);
|
|
794
|
+
return newlink;
|
|
795
|
+
}
|
|
796
|
+
else {
|
|
797
|
+
throw new Error("Related model definition doesn't have a typedef. This is a bug! Please report it.");
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
},
|
|
801
|
+
});
|
|
802
|
+
};
|
|
803
|
+
// For each field on the model schema, we want to add a getter
|
|
804
|
+
// that creates the appropriate new `link` in the query chain.
|
|
805
|
+
// TODO: If revisiting, consider a proxy.
|
|
806
|
+
for (var fieldName in ModelType.schema.fields) {
|
|
807
|
+
_loop_2(fieldName);
|
|
808
|
+
}
|
|
809
|
+
return link;
|
|
810
|
+
}
|
|
811
|
+
exports.recursivePredicateFor = recursivePredicateFor;
|
|
812
|
+
function predicateFor(ModelType) {
|
|
813
|
+
return recursivePredicateFor(ModelType, false);
|
|
814
|
+
}
|
|
815
|
+
exports.predicateFor = predicateFor;
|
|
816
|
+
//# sourceMappingURL=next.js.map
|