@aws-amplify/datastore 5.0.1-api-v6-models.c1977f8.0 → 5.0.1-api-v6-models.891fe0d.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.
Files changed (70) hide show
  1. package/lib/authModeStrategies/defaultAuthStrategy.js +1 -1
  2. package/lib/authModeStrategies/multiAuthStrategy.js +29 -105
  3. package/lib/datastore/datastore.js +887 -1370
  4. package/lib/index.js +1 -1
  5. package/lib/predicates/index.js +53 -102
  6. package/lib/predicates/next.js +310 -557
  7. package/lib/predicates/sort.js +24 -27
  8. package/lib/ssr/index.js +1 -1
  9. package/lib/storage/adapter/AsyncStorageAdapter.js +115 -449
  10. package/lib/storage/adapter/AsyncStorageDatabase.js +215 -480
  11. package/lib/storage/adapter/InMemoryStore.js +27 -101
  12. package/lib/storage/adapter/InMemoryStore.native.js +1 -1
  13. package/lib/storage/adapter/IndexedDBAdapter.js +441 -1002
  14. package/lib/storage/adapter/StorageAdapterBase.js +177 -396
  15. package/lib/storage/adapter/getDefaultAdapter/index.js +5 -6
  16. package/lib/storage/adapter/getDefaultAdapter/index.native.js +2 -2
  17. package/lib/storage/relationship.js +174 -260
  18. package/lib/storage/storage.js +244 -507
  19. package/lib/sync/datastoreConnectivity.js +29 -84
  20. package/lib/sync/datastoreReachability/index.js +1 -1
  21. package/lib/sync/datastoreReachability/index.native.js +2 -2
  22. package/lib/sync/index.js +512 -885
  23. package/lib/sync/merger.js +30 -133
  24. package/lib/sync/outbox.js +147 -302
  25. package/lib/sync/processors/errorMaps.js +30 -80
  26. package/lib/sync/processors/mutation.js +331 -579
  27. package/lib/sync/processors/subscription.js +268 -428
  28. package/lib/sync/processors/sync.js +276 -464
  29. package/lib/sync/utils.js +248 -393
  30. package/lib/tsconfig.tsbuildinfo +1 -1
  31. package/lib/types.js +16 -58
  32. package/lib/util.js +335 -575
  33. package/lib-esm/authModeStrategies/defaultAuthStrategy.js +1 -1
  34. package/lib-esm/authModeStrategies/multiAuthStrategy.js +27 -103
  35. package/lib-esm/datastore/datastore.js +874 -1359
  36. package/lib-esm/index.js +6 -6
  37. package/lib-esm/predicates/index.js +54 -104
  38. package/lib-esm/predicates/next.js +306 -555
  39. package/lib-esm/predicates/sort.js +24 -27
  40. package/lib-esm/ssr/index.js +1 -1
  41. package/lib-esm/storage/adapter/AsyncStorageAdapter.js +111 -446
  42. package/lib-esm/storage/adapter/AsyncStorageDatabase.js +212 -477
  43. package/lib-esm/storage/adapter/InMemoryStore.js +27 -102
  44. package/lib-esm/storage/adapter/IndexedDBAdapter.js +436 -997
  45. package/lib-esm/storage/adapter/StorageAdapterBase.js +172 -392
  46. package/lib-esm/storage/adapter/getDefaultAdapter/index.js +2 -3
  47. package/lib-esm/storage/adapter/getDefaultAdapter/index.native.js +1 -1
  48. package/lib-esm/storage/relationship.js +173 -260
  49. package/lib-esm/storage/storage.js +236 -499
  50. package/lib-esm/sync/datastoreConnectivity.js +26 -82
  51. package/lib-esm/sync/datastoreReachability/index.js +1 -1
  52. package/lib-esm/sync/datastoreReachability/index.native.js +1 -1
  53. package/lib-esm/sync/index.js +498 -872
  54. package/lib-esm/sync/merger.js +28 -131
  55. package/lib-esm/sync/outbox.js +143 -298
  56. package/lib-esm/sync/processors/errorMaps.js +32 -82
  57. package/lib-esm/sync/processors/mutation.js +324 -572
  58. package/lib-esm/sync/processors/subscription.js +258 -418
  59. package/lib-esm/sync/processors/sync.js +269 -457
  60. package/lib-esm/sync/utils.js +245 -390
  61. package/lib-esm/tsconfig.tsbuildinfo +1 -1
  62. package/lib-esm/types.js +16 -59
  63. package/lib-esm/util.js +335 -577
  64. package/package.json +12 -12
  65. package/src/datastore/datastore.ts +4 -3
  66. package/src/storage/adapter/getDefaultAdapter/index.ts +1 -3
  67. package/src/sync/processors/mutation.ts +1 -1
  68. package/src/sync/processors/sync.ts +1 -1
  69. package/src/sync/utils.ts +1 -1
  70. package/src/util.ts +44 -6
@@ -1,105 +1,15 @@
1
- var __assign = (this && this.__assign) || function () {
2
- __assign = Object.assign || function(t) {
3
- for (var s, i = 1, n = arguments.length; i < n; i++) {
4
- s = arguments[i];
5
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
- t[p] = s[p];
7
- }
8
- return t;
9
- };
10
- return __assign.apply(this, arguments);
11
- };
12
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
13
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
14
- return new (P || (P = Promise))(function (resolve, reject) {
15
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
16
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
17
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
18
- step((generator = generator.apply(thisArg, _arguments || [])).next());
19
- });
20
- };
21
- var __generator = (this && this.__generator) || function (thisArg, body) {
22
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
23
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
24
- function verb(n) { return function (v) { return step([n, v]); }; }
25
- function step(op) {
26
- if (f) throw new TypeError("Generator is already executing.");
27
- while (g && (g = 0, op[0] && (_ = 0)), _) try {
28
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
29
- if (y = 0, t) op = [op[0] & 2, t.value];
30
- switch (op[0]) {
31
- case 0: case 1: t = op; break;
32
- case 4: _.label++; return { value: op[1], done: false };
33
- case 5: _.label++; y = op[1]; op = [0]; continue;
34
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
35
- default:
36
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
37
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
38
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
39
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
40
- if (t[2]) _.ops.pop();
41
- _.trys.pop(); continue;
42
- }
43
- op = body.call(thisArg, _);
44
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
45
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
46
- }
47
- };
48
- var __asyncValues = (this && this.__asyncValues) || function (o) {
49
- if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
50
- var m = o[Symbol.asyncIterator], i;
51
- return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
52
- function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
53
- function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
54
- };
55
- var __read = (this && this.__read) || function (o, n) {
56
- var m = typeof Symbol === "function" && o[Symbol.iterator];
57
- if (!m) return o;
58
- var i = m.call(o), r, ar = [], e;
59
- try {
60
- while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
61
- }
62
- catch (error) { e = { error: error }; }
63
- finally {
64
- try {
65
- if (r && !r.done && (m = i["return"])) m.call(i);
66
- }
67
- finally { if (e) throw e.error; }
68
- }
69
- return ar;
70
- };
71
- var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
72
- if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
73
- if (ar || !(i in from)) {
74
- if (!ar) ar = Array.prototype.slice.call(from, 0, i);
75
- ar[i] = from[i];
76
- }
77
- }
78
- return to.concat(ar || Array.prototype.slice.call(from));
79
- };
80
- var __values = (this && this.__values) || function(o) {
81
- var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
82
- if (m) return m.call(o);
83
- if (o && typeof o.length === "number") return {
84
- next: function () {
85
- if (o && i >= o.length) o = void 0;
86
- return { value: o && o[i++], done: !o };
87
- }
88
- };
89
- throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
90
- };
91
1
  // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
92
2
  // SPDX-License-Identifier: Apache-2.0
93
3
  import { PredicateInternalsKey, } from '../types';
94
4
  import { ModelPredicateCreator as FlatModelPredicateCreator, comparisonKeys, } from './index';
95
5
  import { ModelRelationship } from '../storage/relationship';
96
6
  import { asyncSome, asyncEvery } from '../util';
97
- var ops = __spreadArray([], __read(comparisonKeys), false);
7
+ const ops = [...comparisonKeys];
98
8
  /**
99
9
  * A map from keys (exposed to customers) to the internal predicate data
100
10
  * structures invoking code should not muck with.
101
11
  */
102
- var predicateInternalsMap = new Map();
12
+ const predicateInternalsMap = new Map();
103
13
  /**
104
14
  * Creates a link between a key (and generates a key if needed) and an internal
105
15
  * `GroupCondition`, which allows us to return a key object instead of the gory
@@ -109,8 +19,8 @@ var predicateInternalsMap = new Map();
109
19
  * @param key The object DataStore will use to find the internal condition.
110
20
  * If no key is given, an empty one is created.
111
21
  */
112
- var registerPredicateInternals = function (condition, key) {
113
- var finalKey = key || new PredicateInternalsKey();
22
+ const registerPredicateInternals = (condition, key) => {
23
+ const finalKey = key || new PredicateInternalsKey();
114
24
  predicateInternalsMap.set(finalKey, condition);
115
25
  return finalKey;
116
26
  };
@@ -125,7 +35,7 @@ var registerPredicateInternals = function (condition, key) {
125
35
  *
126
36
  * @param key A key object previously returned by `registerPredicateInternals()`
127
37
  */
128
- export var internals = function (key) {
38
+ export const internals = (key) => {
129
39
  if (!predicateInternalsMap.has(key)) {
130
40
  throw new Error("Invalid predicate. Terminate your predicate with a valid condition (e.g., `p => p.field.eq('value')`) or pass `Predicates.ALL`.");
131
41
  }
@@ -135,7 +45,7 @@ export var internals = function (key) {
135
45
  * Maps operators to negated operators.
136
46
  * Used to facilitate propagation of negation down a tree of conditions.
137
47
  */
138
- var negations = {
48
+ const negations = {
139
49
  and: 'or',
140
50
  or: 'and',
141
51
  not: 'and',
@@ -154,8 +64,8 @@ var negations = {
154
64
  * @member operator The equality or comparison operator to use.
155
65
  * @member operands The operands for the equality/comparison check.
156
66
  */
157
- var FieldCondition = /** @class */ (function () {
158
- function FieldCondition(field, operator, operands) {
67
+ export class FieldCondition {
68
+ constructor(field, operator, operands) {
159
69
  this.field = field;
160
70
  this.operator = operator;
161
71
  this.operands = operands;
@@ -166,12 +76,12 @@ var FieldCondition = /** @class */ (function () {
166
76
  * @param extract Not used. Present only to fulfill the `UntypedCondition` interface.
167
77
  * @returns A new, identitical `FieldCondition`.
168
78
  */
169
- FieldCondition.prototype.copy = function (extract) {
79
+ copy(extract) {
170
80
  return [
171
- new FieldCondition(this.field, this.operator, __spreadArray([], __read(this.operands), false)),
81
+ new FieldCondition(this.field, this.operator, [...this.operands]),
172
82
  undefined,
173
83
  ];
174
- };
84
+ }
175
85
  /**
176
86
  * Produces a tree structure similar to a graphql condition. The returned
177
87
  * structure is "dumb" and is intended for another query/condition
@@ -188,16 +98,15 @@ var FieldCondition = /** @class */ (function () {
188
98
  * }
189
99
  * ```
190
100
  */
191
- FieldCondition.prototype.toAST = function () {
192
- var _a, _b;
193
- return _a = {},
194
- _a[this.field] = (_b = {},
195
- _b[this.operator] = this.operator === 'between'
101
+ toAST() {
102
+ return {
103
+ [this.field]: {
104
+ [this.operator]: this.operator === 'between'
196
105
  ? [this.operands[0], this.operands[1]]
197
106
  : this.operands[0],
198
- _b),
199
- _a;
200
- };
107
+ },
108
+ };
109
+ }
201
110
  /**
202
111
  * Produces a new condition (`FieldCondition` or `GroupCondition`) that
203
112
  * matches the opposite of this condition.
@@ -214,7 +123,7 @@ var FieldCondition = /** @class */ (function () {
214
123
  * @param model The model meta to use when construction a new `GroupCondition`
215
124
  * for cases where the negation requires multiple `FieldCondition`'s.
216
125
  */
217
- FieldCondition.prototype.negated = function (model) {
126
+ negated(model) {
218
127
  if (this.operator === 'between') {
219
128
  return new GroupCondition(model, undefined, undefined, 'or', [
220
129
  new FieldCondition(this.field, 'lt', [this.operands[0]]),
@@ -232,77 +141,65 @@ var FieldCondition = /** @class */ (function () {
232
141
  else {
233
142
  return new FieldCondition(this.field, negations[this.operator], this.operands);
234
143
  }
235
- };
144
+ }
236
145
  /**
237
146
  * Not implemented. Not needed. GroupCondition instead consumes FieldConditions and
238
147
  * transforms them into legacy predicates. (*For now.*)
239
148
  * @param storage N/A. If ever implemented, the storage adapter to query.
240
149
  * @returns N/A. If ever implemented, return items from `storage` that match.
241
150
  */
242
- FieldCondition.prototype.fetch = function (storage) {
243
- return __awaiter(this, void 0, void 0, function () {
244
- return __generator(this, function (_a) {
245
- return [2 /*return*/, Promise.reject('No implementation needed [yet].')];
246
- });
247
- });
248
- };
151
+ async fetch(storage) {
152
+ return Promise.reject('No implementation needed [yet].');
153
+ }
249
154
  /**
250
155
  * Determins whether a given item matches the expressed condition.
251
156
  * @param item The item to test.
252
157
  * @returns `Promise<boolean>`, `true` if matches; `false` otherwise.
253
158
  */
254
- FieldCondition.prototype.matches = function (item) {
255
- return __awaiter(this, void 0, void 0, function () {
256
- var v, operations, operation, result;
257
- var _this = this;
258
- return __generator(this, function (_a) {
259
- v = item[this.field];
260
- operations = {
261
- eq: function () { return v === _this.operands[0]; },
262
- ne: function () { return v !== _this.operands[0]; },
263
- gt: function () { return v > _this.operands[0]; },
264
- ge: function () { return v >= _this.operands[0]; },
265
- lt: function () { return v < _this.operands[0]; },
266
- le: function () { return v <= _this.operands[0]; },
267
- contains: function () { return (v === null || v === void 0 ? void 0 : v.indexOf(_this.operands[0])) > -1; },
268
- notContains: function () { return (!v ? true : v.indexOf(_this.operands[0]) === -1); },
269
- beginsWith: function () { return v === null || v === void 0 ? void 0 : v.startsWith(_this.operands[0]); },
270
- between: function () { return v >= _this.operands[0] && v <= _this.operands[1]; },
271
- };
272
- operation = operations[this.operator];
273
- if (operation) {
274
- result = operation();
275
- return [2 /*return*/, result];
276
- }
277
- else {
278
- throw new Error("Invalid operator given: ".concat(this.operator));
279
- }
280
- return [2 /*return*/];
281
- });
282
- });
283
- };
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
+ }
284
182
  /**
285
183
  * Checks `this.operands` for compatibility with `this.operator`.
286
184
  */
287
- FieldCondition.prototype.validate = function () {
288
- var _this = this;
185
+ validate() {
289
186
  /**
290
187
  * Creates a validator that checks for a particular `operands` count.
291
188
  * Throws an exception if the `count` disagrees with `operands.length`.
292
189
  * @param count The number of `operands` expected.
293
190
  */
294
- var argumentCount = function (count) {
295
- var argsClause = count === 1 ? 'argument is' : 'arguments are';
296
- return function () {
297
- if (_this.operands.length !== count) {
298
- return "Exactly ".concat(count, " ").concat(argsClause, " required.");
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.`;
299
196
  }
300
197
  };
301
198
  };
302
199
  // NOTE: validations should return a message on failure.
303
200
  // hence, they should be "joined" together with logical OR's
304
201
  // as seen in the `between:` entry.
305
- var validations = {
202
+ const validations = {
306
203
  eq: argumentCount(1),
307
204
  ne: argumentCount(1),
308
205
  gt: argumentCount(1),
@@ -312,34 +209,30 @@ var FieldCondition = /** @class */ (function () {
312
209
  contains: argumentCount(1),
313
210
  notContains: argumentCount(1),
314
211
  beginsWith: argumentCount(1),
315
- between: function () {
316
- return argumentCount(2)() ||
317
- (_this.operands[0] > _this.operands[1]
318
- ? 'The first argument must be less than or equal to the second argument.'
319
- : null);
320
- },
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),
321
216
  };
322
- var validate = validations[this.operator];
217
+ const validate = validations[this.operator];
323
218
  if (validate) {
324
- var e = validate();
219
+ const e = validate();
325
220
  if (typeof e === 'string')
326
- throw new Error("Incorrect usage of `".concat(this.operator, "()`: ").concat(e));
221
+ throw new Error(`Incorrect usage of \`${this.operator}()\`: ${e}`);
327
222
  }
328
223
  else {
329
- throw new Error("Non-existent operator: `".concat(this.operator, "()`"));
224
+ throw new Error(`Non-existent operator: \`${this.operator}()\``);
330
225
  }
331
- };
332
- return FieldCondition;
333
- }());
334
- export { FieldCondition };
226
+ }
227
+ }
335
228
  /**
336
229
  * Small utility function to generate a monotonically increasing ID.
337
230
  * Used by GroupCondition to help keep track of which group is doing what,
338
231
  * when, and where during troubleshooting.
339
232
  */
340
- var getGroupId = (function () {
341
- var seed = 1;
342
- return function () { return "group_".concat(seed++); };
233
+ const getGroupId = (() => {
234
+ let seed = 1;
235
+ return () => `group_${seed++}`;
343
236
  })();
344
237
  /**
345
238
  * A set of sub-conditions to operate against a model, optionally scoped to
@@ -351,8 +244,8 @@ var getGroupId = (function () {
351
244
  * @member operator How to group child conditions together.
352
245
  * @member operands The child conditions.
353
246
  */
354
- var GroupCondition = /** @class */ (function () {
355
- function GroupCondition(
247
+ export class GroupCondition {
248
+ constructor(
356
249
  /**
357
250
  * The `ModelMeta` of the model to query and/or filter against.
358
251
  * Expected to contain:
@@ -396,8 +289,7 @@ var GroupCondition = /** @class */ (function () {
396
289
  * This is used to guard against infinitely fetch -> optimize -> fetch
397
290
  * recursion.
398
291
  */
399
- isOptimized) {
400
- if (isOptimized === void 0) { isOptimized = false; }
292
+ isOptimized = false) {
401
293
  this.model = model;
402
294
  this.field = field;
403
295
  this.relationshipType = relationshipType;
@@ -414,16 +306,16 @@ var GroupCondition = /** @class */ (function () {
414
306
  * @param extract A node of interest. Its copy will *also* be returned if the node exists.
415
307
  * @returns [The full copy, the copy of `extract` | undefined]
416
308
  */
417
- GroupCondition.prototype.copy = function (extract) {
418
- var copied = new GroupCondition(this.model, this.field, this.relationshipType, this.operator, []);
419
- var extractedCopy = extract === this ? copied : undefined;
420
- this.operands.forEach(function (o) {
421
- var _a = __read(o.copy(extract), 2), operandCopy = _a[0], extractedFromOperand = _a[1];
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);
422
314
  copied.operands.push(operandCopy);
423
315
  extractedCopy = extractedCopy || extractedFromOperand;
424
316
  });
425
317
  return [copied, extractedCopy];
426
- };
318
+ }
427
319
  /**
428
320
  * Creates a new `GroupCondition` that contains only the local field conditions,
429
321
  * omitting related model conditions. That resulting `GroupCondition` can be
@@ -433,15 +325,12 @@ var GroupCondition = /** @class */ (function () {
433
325
  * @param negate Whether the condition tree should be negated according
434
326
  * to De Morgan's law.
435
327
  */
436
- GroupCondition.prototype.withFieldConditionsOnly = function (negate) {
437
- var _this = this;
438
- var negateChildren = negate !== (this.operator === 'not');
328
+ withFieldConditionsOnly(negate) {
329
+ const negateChildren = negate !== (this.operator === 'not');
439
330
  return new GroupCondition(this.model, undefined, undefined, (negate ? negations[this.operator] : this.operator), this.operands
440
- .filter(function (o) { return o instanceof FieldCondition; })
441
- .map(function (o) {
442
- return negateChildren ? o.negated(_this.model) : o;
443
- }));
444
- };
331
+ .filter(o => o instanceof FieldCondition)
332
+ .map(o => negateChildren ? o.negated(this.model) : o));
333
+ }
445
334
  /**
446
335
  * Returns a version of the predicate tree with unnecessary logical groups
447
336
  * condensed and merged together. This is intended to create a dense tree
@@ -478,12 +367,8 @@ var GroupCondition = /** @class */ (function () {
478
367
  * `not` groups. `not` groups will always have a single child, so there's nothing to
479
368
  * optimize below a `not` (for now), and it makes the query logic simpler later.
480
369
  */
481
- GroupCondition.prototype.optimized = function (preserveNode) {
482
- var _this = this;
483
- if (preserveNode === void 0) { preserveNode = true; }
484
- var operands = this.operands.map(function (o) {
485
- return o instanceof GroupCondition ? o.optimized(_this.operator === 'not') : o;
486
- });
370
+ optimized(preserveNode = true) {
371
+ const operands = this.operands.map(o => o instanceof GroupCondition ? o.optimized(this.operator === 'not') : o);
487
372
  // we're only collapsing and/or groups that contains a single child for now,
488
373
  // because they're much more common and much more trivial to collapse. basically,
489
374
  // an `and`/`or` that contains a single child doesn't require the layer of
@@ -492,7 +377,7 @@ var GroupCondition = /** @class */ (function () {
492
377
  ['and', 'or'].includes(this.operator) &&
493
378
  !this.field &&
494
379
  operands.length === 1) {
495
- var operand = operands[0];
380
+ const operand = operands[0];
496
381
  if (operand instanceof FieldCondition) {
497
382
  // between conditions should NOT be passed up the chain. if they
498
383
  // need to be *negated* later, it is important that they be properly
@@ -508,7 +393,7 @@ var GroupCondition = /** @class */ (function () {
508
393
  }
509
394
  }
510
395
  return new GroupCondition(this.model, this.field, this.relationshipType, this.operator, operands, true);
511
- };
396
+ }
512
397
  /**
513
398
  * Fetches matching records from a given storage adapter using legacy predicates (for now).
514
399
  * @param storage The storage adapter this predicate will query against.
@@ -517,211 +402,134 @@ var GroupCondition = /** @class */ (function () {
517
402
  * @param negate Whether to match on the `NOT` of `this`.
518
403
  * @returns An `Promise` of `any[]` from `storage` matching the child conditions.
519
404
  */
520
- GroupCondition.prototype.fetch = function (storage, breadcrumb, negate) {
521
- if (breadcrumb === void 0) { breadcrumb = []; }
522
- if (negate === void 0) { negate = false; }
523
- return __awaiter(this, void 0, void 0, function () {
524
- var resultGroups, operator, negateChildren, groups, conditions, groups_1, groups_1_1, g, relatives, relationship, allJoinConditions, relatives_1, relatives_1_1, relative, relativeConditions, i, predicate, _a, _b, e_1_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;
525
- var e_1, _j, e_2, _k, _l, e_3, _m, e_4, _o, e_5, _p, e_6, _q;
526
- var _this = this;
527
- return __generator(this, function (_r) {
528
- switch (_r.label) {
529
- case 0:
530
- if (!this.isOptimized) {
531
- return [2 /*return*/, this.optimized().fetch(storage)];
532
- }
533
- resultGroups = [];
534
- operator = (negate ? negations[this.operator] : this.operator);
535
- negateChildren = negate !== (this.operator === 'not');
536
- groups = this.operands.filter(function (op) { return op instanceof GroupCondition; });
537
- conditions = this.operands.filter(function (op) { return op instanceof FieldCondition; });
538
- _r.label = 1;
539
- case 1:
540
- _r.trys.push([1, 10, 11, 12]);
541
- groups_1 = __values(groups), groups_1_1 = groups_1.next();
542
- _r.label = 2;
543
- case 2:
544
- if (!!groups_1_1.done) return [3 /*break*/, 9];
545
- g = groups_1_1.value;
546
- return [4 /*yield*/, g.fetch(storage, __spreadArray(__spreadArray([], __read(breadcrumb), false), [this.groupId], false), negateChildren)];
547
- case 3:
548
- relatives = _r.sent();
549
- // no relatives -> no need to attempt to perform a "join" query for
550
- // candidate results:
551
- //
552
- // select a.* from a,b where b.id in EMPTY_SET ==> EMPTY_SET
553
- //
554
- // Additionally, the entire (sub)-query can be short-circuited if
555
- // the operator is `AND`. Illustrated in SQL:
556
- //
557
- // select a.* from a where
558
- // id in [a,b,c]
559
- // AND <
560
- // id in EMTPY_SET <<< Look!
561
- // AND <
562
- // id in [x,y,z]
563
- //
564
- // YIELDS: EMPTY_SET // <-- Easy peasy. Lemon squeezy.
565
- //
566
- if (relatives.length === 0) {
567
- // aggressively short-circuit as soon as we know the group condition will fail
568
- if (operator === 'and') {
569
- return [2 /*return*/, []];
570
- }
571
- // less aggressive short-circuit if we know the relatives will produce no
572
- // candidate results; but aren't sure yet how this affects the group condition.
573
- resultGroups.push([]);
574
- return [3 /*break*/, 8];
575
- }
576
- if (!g.field) return [3 /*break*/, 7];
577
- relationship = ModelRelationship.from(this.model, g.field);
578
- if (!relationship) return [3 /*break*/, 5];
579
- allJoinConditions = [];
580
- try {
581
- for (relatives_1 = (e_2 = void 0, __values(relatives)), relatives_1_1 = relatives_1.next(); !relatives_1_1.done; relatives_1_1 = relatives_1.next()) {
582
- relative = relatives_1_1.value;
583
- relativeConditions = [];
584
- for (i = 0; i < relationship.localJoinFields.length; i++) {
585
- relativeConditions.push((_l = {},
586
- _l[relationship.localJoinFields[i]] = {
587
- eq: relative[relationship.remoteJoinFields[i]],
588
- },
589
- _l));
590
- }
591
- allJoinConditions.push({ and: relativeConditions });
592
- }
593
- }
594
- catch (e_2_1) { e_2 = { error: e_2_1 }; }
595
- finally {
596
- try {
597
- if (relatives_1_1 && !relatives_1_1.done && (_k = relatives_1.return)) _k.call(relatives_1);
598
- }
599
- finally { if (e_2) throw e_2.error; }
600
- }
601
- predicate = FlatModelPredicateCreator.createFromAST(this.model.schema, {
602
- or: allJoinConditions,
603
- });
604
- _b = (_a = resultGroups).push;
605
- return [4 /*yield*/, storage.query(this.model.builder, predicate)];
606
- case 4:
607
- _b.apply(_a, [_r.sent()]);
608
- return [3 /*break*/, 6];
609
- case 5: throw new Error('Missing field metadata.');
610
- case 6: return [3 /*break*/, 8];
611
- case 7:
612
- // relatives are not actually relatives. they're candidate results.
613
- resultGroups.push(relatives);
614
- _r.label = 8;
615
- case 8:
616
- groups_1_1 = groups_1.next();
617
- return [3 /*break*/, 2];
618
- case 9: return [3 /*break*/, 12];
619
- case 10:
620
- e_1_1 = _r.sent();
621
- e_1 = { error: e_1_1 };
622
- return [3 /*break*/, 12];
623
- case 11:
624
- try {
625
- if (groups_1_1 && !groups_1_1.done && (_j = groups_1.return)) _j.call(groups_1);
626
- }
627
- finally { if (e_1) throw e_1.error; }
628
- return [7 /*endfinally*/];
629
- case 12:
630
- if (!(conditions.length > 0)) return [3 /*break*/, 14];
631
- predicate = this.withFieldConditionsOnly(negateChildren).toStoragePredicate();
632
- _d = (_c = resultGroups).push;
633
- return [4 /*yield*/, storage.query(this.model.builder, predicate)];
634
- case 13:
635
- _d.apply(_c, [_r.sent()]);
636
- return [3 /*break*/, 16];
637
- case 14:
638
- if (!(conditions.length === 0 && resultGroups.length === 0)) return [3 /*break*/, 16];
639
- _f = (_e = resultGroups).push;
640
- return [4 /*yield*/, storage.query(this.model.builder)];
641
- case 15:
642
- _f.apply(_e, [_r.sent()]);
643
- _r.label = 16;
644
- case 16:
645
- getPKValue = function (item) {
646
- return JSON.stringify(_this.model.pkField.map(function (name) { return item[name]; }));
647
- };
648
- if (operator === 'and') {
649
- if (resultGroups.length === 0) {
650
- return [2 /*return*/, []];
651
- }
652
- try {
653
- // for each group, we intersect, removing items from the result index
654
- // that aren't present in each subsequent group.
655
- for (resultGroups_1 = __values(resultGroups), resultGroups_1_1 = resultGroups_1.next(); !resultGroups_1_1.done; resultGroups_1_1 = resultGroups_1.next()) {
656
- group = resultGroups_1_1.value;
657
- if (resultIndex === undefined) {
658
- resultIndex = new Map(group.map(function (item) { return [getPKValue(item), item]; }));
659
- }
660
- else {
661
- intersectWith = new Map(group.map(function (item) { return [getPKValue(item), item]; }));
662
- try {
663
- for (_g = (e_4 = void 0, __values(resultIndex.keys())), _h = _g.next(); !_h.done; _h = _g.next()) {
664
- k = _h.value;
665
- if (!intersectWith.has(k)) {
666
- resultIndex.delete(k);
667
- }
668
- }
669
- }
670
- catch (e_4_1) { e_4 = { error: e_4_1 }; }
671
- finally {
672
- try {
673
- if (_h && !_h.done && (_o = _g.return)) _o.call(_g);
674
- }
675
- finally { if (e_4) throw e_4.error; }
676
- }
677
- }
678
- }
679
- }
680
- catch (e_3_1) { e_3 = { error: e_3_1 }; }
681
- finally {
682
- try {
683
- if (resultGroups_1_1 && !resultGroups_1_1.done && (_m = resultGroups_1.return)) _m.call(resultGroups_1);
684
- }
685
- finally { if (e_3) throw e_3.error; }
686
- }
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
+ });
687
467
  }
688
- else if (operator === 'or' || operator === 'not') {
689
- // it's OK to handle NOT here, because NOT must always only negate
690
- // a single child predicate. NOT logic will have been distributed down
691
- // to the leaf conditions already.
692
- resultIndex = new Map();
693
- try {
694
- // just merge the groups, performing DISTINCT-ification by ID.
695
- for (resultGroups_2 = __values(resultGroups), resultGroups_2_1 = resultGroups_2.next(); !resultGroups_2_1.done; resultGroups_2_1 = resultGroups_2.next()) {
696
- group = resultGroups_2_1.value;
697
- try {
698
- for (group_1 = (e_6 = void 0, __values(group)), group_1_1 = group_1.next(); !group_1_1.done; group_1_1 = group_1.next()) {
699
- item = group_1_1.value;
700
- resultIndex.set(getPKValue(item), item);
701
- }
702
- }
703
- catch (e_6_1) { e_6 = { error: e_6_1 }; }
704
- finally {
705
- try {
706
- if (group_1_1 && !group_1_1.done && (_q = group_1.return)) _q.call(group_1);
707
- }
708
- finally { if (e_6) throw e_6.error; }
709
- }
710
- }
711
- }
712
- catch (e_5_1) { e_5 = { error: e_5_1 }; }
713
- finally {
714
- try {
715
- if (resultGroups_2_1 && !resultGroups_2_1.done && (_p = resultGroups_2.return)) _p.call(resultGroups_2);
716
- }
717
- finally { if (e_5) throw e_5.error; }
718
- }
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);
719
514
  }
720
- return [2 /*return*/, Array.from((resultIndex === null || resultIndex === void 0 ? void 0 : resultIndex.values()) || [])];
515
+ }
721
516
  }
722
- });
723
- });
724
- };
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
+ }
725
533
  /**
726
534
  * Determines whether a single item matches the conditions of `this`.
727
535
  * When checking the target `item`'s properties, each property will be `await`'d
@@ -731,120 +539,67 @@ var GroupCondition = /** @class */ (function () {
731
539
  * (Used for iterating over children on HAS_MANY checks.)
732
540
  * @returns A boolean (promise): `true` if matched, `false` otherwise.
733
541
  */
734
- GroupCondition.prototype.matches = function (item, ignoreFieldName) {
735
- var _a, e_7, _b, _c;
736
- if (ignoreFieldName === void 0) { ignoreFieldName = false; }
737
- return __awaiter(this, void 0, void 0, function () {
738
- var itemToCheck, _d, _e, itemToCheck_1, itemToCheck_1_1, singleItem, e_7_1;
739
- return __generator(this, function (_f) {
740
- switch (_f.label) {
741
- case 0:
742
- if (!(this.field && !ignoreFieldName)) return [3 /*break*/, 2];
743
- return [4 /*yield*/, item[this.field]];
744
- case 1:
745
- _d = _f.sent();
746
- return [3 /*break*/, 3];
747
- case 2:
748
- _d = item;
749
- _f.label = 3;
750
- case 3:
751
- itemToCheck = _d;
752
- // if there is no item to check, we can stop recursing immediately.
753
- // a condition cannot match against an item that does not exist. this
754
- // can occur when `item.field` is optional in the schema.
755
- if (!itemToCheck) {
756
- return [2 /*return*/, false];
757
- }
758
- if (!(this.relationshipType === 'HAS_MANY' &&
759
- typeof itemToCheck[Symbol.asyncIterator] === 'function')) return [3 /*break*/, 19];
760
- _f.label = 4;
761
- case 4:
762
- _f.trys.push([4, 12, 13, 18]);
763
- _e = true, itemToCheck_1 = __asyncValues(itemToCheck);
764
- _f.label = 5;
765
- case 5: return [4 /*yield*/, itemToCheck_1.next()];
766
- case 6:
767
- if (!(itemToCheck_1_1 = _f.sent(), _a = itemToCheck_1_1.done, !_a)) return [3 /*break*/, 11];
768
- _c = itemToCheck_1_1.value;
769
- _e = false;
770
- _f.label = 7;
771
- case 7:
772
- _f.trys.push([7, , 9, 10]);
773
- singleItem = _c;
774
- return [4 /*yield*/, this.matches(singleItem, true)];
775
- case 8:
776
- if (_f.sent()) {
777
- return [2 /*return*/, true];
778
- }
779
- return [3 /*break*/, 10];
780
- case 9:
781
- _e = true;
782
- return [7 /*endfinally*/];
783
- case 10: return [3 /*break*/, 5];
784
- case 11: return [3 /*break*/, 18];
785
- case 12:
786
- e_7_1 = _f.sent();
787
- e_7 = { error: e_7_1 };
788
- return [3 /*break*/, 18];
789
- case 13:
790
- _f.trys.push([13, , 16, 17]);
791
- if (!(!_e && !_a && (_b = itemToCheck_1.return))) return [3 /*break*/, 15];
792
- return [4 /*yield*/, _b.call(itemToCheck_1)];
793
- case 14:
794
- _f.sent();
795
- _f.label = 15;
796
- case 15: return [3 /*break*/, 17];
797
- case 16:
798
- if (e_7) throw e_7.error;
799
- return [7 /*endfinally*/];
800
- case 17: return [7 /*endfinally*/];
801
- case 18: return [2 /*return*/, false];
802
- case 19:
803
- if (!(this.operator === 'or')) return [3 /*break*/, 20];
804
- return [2 /*return*/, asyncSome(this.operands, function (c) { return c.matches(itemToCheck); })];
805
- case 20:
806
- if (!(this.operator === 'and')) return [3 /*break*/, 21];
807
- return [2 /*return*/, asyncEvery(this.operands, function (c) { return c.matches(itemToCheck); })];
808
- case 21:
809
- if (!(this.operator === 'not')) return [3 /*break*/, 23];
810
- if (this.operands.length !== 1) {
811
- throw new Error('Invalid arguments! `not()` accepts exactly one predicate expression.');
812
- }
813
- return [4 /*yield*/, this.operands[0].matches(itemToCheck)];
814
- case 22: return [2 /*return*/, !(_f.sent())];
815
- case 23: 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;
816
555
  }
817
- });
818
- });
819
- };
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
+ }
820
575
  /**
821
576
  * Tranfsorm to a AppSync GraphQL compatible AST.
822
577
  * (Does not support filtering in nested types.)
823
578
  */
824
- GroupCondition.prototype.toAST = function () {
825
- var _a;
579
+ toAST() {
826
580
  if (this.field)
827
581
  throw new Error('Nested type conditions are not supported!');
828
- return _a = {},
829
- _a[this.operator] = this.operands.map(function (operand) { return operand.toAST(); }),
830
- _a;
831
- };
582
+ return {
583
+ [this.operator]: this.operands.map(operand => operand.toAST()),
584
+ };
585
+ }
832
586
  /**
833
587
  * Turn this predicate group into something a storage adapter
834
588
  * understands how to use.
835
589
  */
836
- GroupCondition.prototype.toStoragePredicate = function () {
590
+ toStoragePredicate() {
837
591
  return FlatModelPredicateCreator.createFromAST(this.model.schema, this.toAST());
838
- };
592
+ }
839
593
  /**
840
594
  * A JSON representation that's good for debugging.
841
595
  */
842
- GroupCondition.prototype.toJSON = function () {
843
- return __assign(__assign({}, this), { model: this.model.schema.name });
844
- };
845
- return GroupCondition;
846
- }());
847
- export { GroupCondition };
596
+ toJSON() {
597
+ return {
598
+ ...this,
599
+ model: this.model.schema.name,
600
+ };
601
+ }
602
+ }
848
603
  /**
849
604
  * Creates a "seed" predicate that can be used to build an executable condition.
850
605
  * This is used in `query()`, for example, to seed customer- E.g.,
@@ -872,49 +627,48 @@ export { GroupCondition };
872
627
  * @returns A ModelPredicate (builder) that customers can create queries with.
873
628
  * (As shown in function description.)
874
629
  */
875
- export function recursivePredicateFor(ModelType, allowRecursion, field, query, tail) {
876
- if (allowRecursion === void 0) { allowRecursion = true; }
630
+ export function recursivePredicateFor(ModelType, allowRecursion = true, field, query, tail) {
877
631
  // to be used if we don't have a base query or tail to build onto
878
- var starter = new GroupCondition(ModelType, field, undefined, 'and', []);
879
- var baseCondition = query && tail ? query : starter;
880
- var tailCondition = query && tail ? tail : starter;
632
+ const starter = new GroupCondition(ModelType, field, undefined, 'and', []);
633
+ const baseCondition = query && tail ? query : starter;
634
+ const tailCondition = query && tail ? tail : starter;
881
635
  // our eventual return object, which can be built upon.
882
636
  // next steps will be to add or(), and(), not(), and field.op() methods.
883
- var link = {};
637
+ const link = {};
884
638
  // so it can be looked up later with in the internals when processing conditions.
885
639
  registerPredicateInternals(baseCondition, link);
886
- var copyLink = function () {
887
- var _a = __read(baseCondition.copy(tailCondition), 2), query = _a[0], newTail = _a[1];
888
- var newLink = recursivePredicateFor(ModelType, allowRecursion, undefined, query, newTail);
889
- return { query: query, newTail: newTail, newLink: newLink };
640
+ const copyLink = () => {
641
+ const [query, newTail] = baseCondition.copy(tailCondition);
642
+ const newLink = recursivePredicateFor(ModelType, allowRecursion, undefined, query, newTail);
643
+ return { query, newTail, newLink };
890
644
  };
891
645
  // Adds .or() and .and() methods to the link.
892
646
  // TODO: If revisiting this code, consider writing a Proxy instead.
893
- ['and', 'or'].forEach(function (op) {
894
- link[op] = function (builder) {
647
+ ['and', 'or'].forEach(op => {
648
+ link[op] = (builder) => {
895
649
  // or() and and() will return a copy of the original link
896
650
  // to head off mutability concerns.
897
- var _a = copyLink(), query = _a.query, newTail = _a.newTail;
898
- var childConditions = builder(recursivePredicateFor(ModelType, allowRecursion));
651
+ const { query, newTail } = copyLink();
652
+ const childConditions = builder(recursivePredicateFor(ModelType, allowRecursion));
899
653
  if (!Array.isArray(childConditions)) {
900
- throw new Error("Invalid predicate. `".concat(op, "` groups must return an array of child conditions."));
654
+ throw new Error(`Invalid predicate. \`${op}\` groups must return an array of child conditions.`);
901
655
  }
902
656
  // the customer will supply a child predicate, which apply to the `model.field`
903
657
  // of the tail GroupCondition.
904
- newTail === null || newTail === void 0 ? void 0 : newTail.operands.push(new GroupCondition(ModelType, field, undefined, op, childConditions.map(function (c) { return internals(c); })));
658
+ newTail?.operands.push(new GroupCondition(ModelType, field, undefined, op, childConditions.map(c => internals(c))));
905
659
  // FinalPredicate
906
660
  return registerPredicateInternals(query);
907
661
  };
908
662
  });
909
663
  // TODO: If revisiting this code, consider proxy.
910
- link.not = function (builder) {
664
+ link.not = (builder) => {
911
665
  // not() will return a copy of the original link
912
666
  // to head off mutability concerns.
913
- var _a = copyLink(), query = _a.query, newTail = _a.newTail;
667
+ const { query, newTail } = copyLink();
914
668
  // unlike and() and or(), the customer will supply a "singular" child predicate.
915
669
  // the difference being: not() does not accept an array of predicate-like objects.
916
670
  // it negates only a *single* predicate subtree.
917
- newTail === null || newTail === void 0 ? void 0 : newTail.operands.push(new GroupCondition(ModelType, field, undefined, 'not', [
671
+ newTail?.operands.push(new GroupCondition(ModelType, field, undefined, 'not', [
918
672
  internals(builder(recursivePredicateFor(ModelType, allowRecursion))),
919
673
  ]));
920
674
  // A `FinalModelPredicate`.
@@ -922,39 +676,42 @@ export function recursivePredicateFor(ModelType, allowRecursion, field, query, t
922
676
  // or query storage: `.__query.fetch(storage)`.
923
677
  return registerPredicateInternals(query);
924
678
  };
925
- var _loop_1 = function (fieldName) {
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) {
926
683
  Object.defineProperty(link, fieldName, {
927
684
  enumerable: true,
928
- get: function () {
929
- var def = ModelType.schema.allFields[fieldName];
685
+ get: () => {
686
+ const def = ModelType.schema.allFields[fieldName];
930
687
  if (!def.association) {
931
688
  // we're looking at a value field. we need to return a
932
689
  // "field matcher object", which contains all of the comparison
933
690
  // functions ('eq', 'ne', 'gt', etc.), scoped to operate
934
691
  // against the target field (fieldName).
935
- return ops.reduce(function (fieldMatcher, operator) {
936
- var _a;
937
- return __assign(__assign({}, fieldMatcher), (_a = {}, _a[operator] = function () {
938
- var operands = [];
939
- for (var _i = 0; _i < arguments.length; _i++) {
940
- operands[_i] = arguments[_i];
941
- }
942
- // build off a fresh copy of the existing `link`, just in case
943
- // the same link is being used elsewhere by the customer.
944
- var _a = copyLink(), query = _a.query, newTail = _a.newTail;
945
- // normalize operands. if any of the values are `undefiend`, use
946
- // `null` instead, because that's what will be stored cross-platform.
947
- var normalizedOperands = operands.map(function (o) {
948
- return o === undefined ? null : o;
949
- });
950
- // add the given condition to the link's TAIL node.
951
- // remember: the base link might go N nodes deep! e.g.,
952
- newTail === null || newTail === void 0 ? void 0 : newTail.operands.push(new FieldCondition(fieldName, operator, normalizedOperands));
953
- // A `FinalModelPredicate`.
954
- // Return a thing that can no longer be extended, but instead used to `async filter(items)`
955
- // or query storage: `.__query.fetch(storage)`.
956
- return registerPredicateInternals(query);
957
- }, _a));
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
+ };
958
715
  }, {});
959
716
  }
960
717
  else {
@@ -966,20 +723,20 @@ export function recursivePredicateFor(ModelType, allowRecursion, field, query, t
966
723
  def.association.connectionType === 'HAS_MANY') {
967
724
  // the use has just typed '.someRelatedModel'. we need to given them
968
725
  // back a predicate chain.
969
- var relatedMeta = def.type.modelConstructor;
726
+ const relatedMeta = def.type.modelConstructor;
970
727
  if (!relatedMeta) {
971
728
  throw new Error('Related model metadata is missing. This is a bug! Please report it.');
972
729
  }
973
730
  // `Model.reletedModelField` returns a copy of the original link,
974
731
  // and will contains copies of internal GroupConditions
975
732
  // to head off mutability concerns.
976
- var _a = __read(baseCondition.copy(tailCondition), 2), newquery = _a[0], oldtail = _a[1];
977
- var newtail = new GroupCondition(relatedMeta, fieldName, def.association.connectionType, 'and', []);
733
+ const [newquery, oldtail] = baseCondition.copy(tailCondition);
734
+ const newtail = new GroupCondition(relatedMeta, fieldName, def.association.connectionType, 'and', []);
978
735
  // `oldtail` here refers to the *copy* of the old tail.
979
736
  // so, it's safe to modify at this point. and we need to modify
980
737
  // it to push the *new* tail onto the end of it.
981
738
  oldtail.operands.push(newtail);
982
- var newlink = recursivePredicateFor(relatedMeta, allowRecursion, undefined, newquery, newtail);
739
+ const newlink = recursivePredicateFor(relatedMeta, allowRecursion, undefined, newquery, newtail);
983
740
  return newlink;
984
741
  }
985
742
  else {
@@ -988,12 +745,6 @@ export function recursivePredicateFor(ModelType, allowRecursion, field, query, t
988
745
  }
989
746
  },
990
747
  });
991
- };
992
- // For each field on the model schema, we want to add a getter
993
- // that creates the appropriate new `link` in the query chain.
994
- // TODO: If revisiting, consider a proxy.
995
- for (var fieldName in ModelType.schema.allFields) {
996
- _loop_1(fieldName);
997
748
  }
998
749
  return link;
999
750
  }