@aws-amplify/datastore 3.12.6-next.36 → 3.12.6-next.44

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