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

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 (131) hide show
  1. package/lib/authModeStrategies/multiAuthStrategy.js.map +1 -1
  2. package/lib/datastore/datastore.d.ts +59 -8
  3. package/lib/datastore/datastore.js +640 -143
  4. package/lib/datastore/datastore.js.map +1 -1
  5. package/lib/index.d.ts +3 -2
  6. package/lib/index.js +4 -0
  7. package/lib/index.js.map +1 -1
  8. package/lib/predicates/index.d.ts +16 -2
  9. package/lib/predicates/index.js +127 -6
  10. package/lib/predicates/index.js.map +1 -1
  11. package/lib/predicates/next.d.ts +342 -0
  12. package/lib/predicates/next.js +801 -0
  13. package/lib/predicates/next.js.map +1 -0
  14. package/lib/predicates/sort.js +10 -4
  15. package/lib/predicates/sort.js.map +1 -1
  16. package/lib/storage/adapter/AsyncStorageAdapter.d.ts +2 -1
  17. package/lib/storage/adapter/AsyncStorageAdapter.js +106 -293
  18. package/lib/storage/adapter/AsyncStorageAdapter.js.map +1 -1
  19. package/lib/storage/adapter/AsyncStorageDatabase.js +6 -5
  20. package/lib/storage/adapter/AsyncStorageDatabase.js.map +1 -1
  21. package/lib/storage/adapter/InMemoryStore.d.ts +1 -1
  22. package/lib/storage/adapter/InMemoryStore.js.map +1 -1
  23. package/lib/storage/adapter/IndexedDBAdapter.d.ts +4 -2
  24. package/lib/storage/adapter/IndexedDBAdapter.js +223 -289
  25. package/lib/storage/adapter/IndexedDBAdapter.js.map +1 -1
  26. package/lib/storage/adapter/getDefaultAdapter/index.js.map +1 -1
  27. package/lib/storage/relationship.d.ts +140 -0
  28. package/lib/storage/relationship.js +335 -0
  29. package/lib/storage/relationship.js.map +1 -0
  30. package/lib/storage/storage.d.ts +7 -6
  31. package/lib/storage/storage.js +32 -16
  32. package/lib/storage/storage.js.map +1 -1
  33. package/lib/sync/datastoreConnectivity.js.map +1 -1
  34. package/lib/sync/index.js +2 -8
  35. package/lib/sync/index.js.map +1 -1
  36. package/lib/sync/merger.js.map +1 -1
  37. package/lib/sync/outbox.js.map +1 -1
  38. package/lib/sync/processors/errorMaps.js +1 -1
  39. package/lib/sync/processors/errorMaps.js.map +1 -1
  40. package/lib/sync/processors/mutation.js +9 -6
  41. package/lib/sync/processors/mutation.js.map +1 -1
  42. package/lib/sync/processors/subscription.js +3 -0
  43. package/lib/sync/processors/subscription.js.map +1 -1
  44. package/lib/sync/processors/sync.js.map +1 -1
  45. package/lib/sync/utils.d.ts +1 -1
  46. package/lib/sync/utils.js +30 -31
  47. package/lib/sync/utils.js.map +1 -1
  48. package/lib/types.d.ts +58 -6
  49. package/lib/types.js +6 -1
  50. package/lib/types.js.map +1 -1
  51. package/lib/util.d.ts +39 -6
  52. package/lib/util.js +174 -104
  53. package/lib/util.js.map +1 -1
  54. package/lib-esm/authModeStrategies/multiAuthStrategy.js.map +1 -1
  55. package/lib-esm/datastore/datastore.d.ts +59 -8
  56. package/lib-esm/datastore/datastore.js +642 -146
  57. package/lib-esm/datastore/datastore.js.map +1 -1
  58. package/lib-esm/index.d.ts +3 -2
  59. package/lib-esm/index.js +2 -1
  60. package/lib-esm/index.js.map +1 -1
  61. package/lib-esm/predicates/index.d.ts +16 -2
  62. package/lib-esm/predicates/index.js +128 -7
  63. package/lib-esm/predicates/index.js.map +1 -1
  64. package/lib-esm/predicates/next.d.ts +342 -0
  65. package/lib-esm/predicates/next.js +797 -0
  66. package/lib-esm/predicates/next.js.map +1 -0
  67. package/lib-esm/predicates/sort.js +10 -4
  68. package/lib-esm/predicates/sort.js.map +1 -1
  69. package/lib-esm/storage/adapter/AsyncStorageAdapter.d.ts +2 -1
  70. package/lib-esm/storage/adapter/AsyncStorageAdapter.js +108 -295
  71. package/lib-esm/storage/adapter/AsyncStorageAdapter.js.map +1 -1
  72. package/lib-esm/storage/adapter/AsyncStorageDatabase.js +6 -5
  73. package/lib-esm/storage/adapter/AsyncStorageDatabase.js.map +1 -1
  74. package/lib-esm/storage/adapter/InMemoryStore.d.ts +1 -1
  75. package/lib-esm/storage/adapter/InMemoryStore.js.map +1 -1
  76. package/lib-esm/storage/adapter/IndexedDBAdapter.d.ts +4 -2
  77. package/lib-esm/storage/adapter/IndexedDBAdapter.js +226 -292
  78. package/lib-esm/storage/adapter/IndexedDBAdapter.js.map +1 -1
  79. package/lib-esm/storage/adapter/getDefaultAdapter/index.js.map +1 -1
  80. package/lib-esm/storage/relationship.d.ts +140 -0
  81. package/lib-esm/storage/relationship.js +333 -0
  82. package/lib-esm/storage/relationship.js.map +1 -0
  83. package/lib-esm/storage/storage.d.ts +7 -6
  84. package/lib-esm/storage/storage.js +32 -16
  85. package/lib-esm/storage/storage.js.map +1 -1
  86. package/lib-esm/sync/datastoreConnectivity.js.map +1 -1
  87. package/lib-esm/sync/index.js +3 -9
  88. package/lib-esm/sync/index.js.map +1 -1
  89. package/lib-esm/sync/merger.js.map +1 -1
  90. package/lib-esm/sync/outbox.js.map +1 -1
  91. package/lib-esm/sync/processors/errorMaps.js +1 -1
  92. package/lib-esm/sync/processors/errorMaps.js.map +1 -1
  93. package/lib-esm/sync/processors/mutation.js +10 -7
  94. package/lib-esm/sync/processors/mutation.js.map +1 -1
  95. package/lib-esm/sync/processors/subscription.js +3 -0
  96. package/lib-esm/sync/processors/subscription.js.map +1 -1
  97. package/lib-esm/sync/processors/sync.js.map +1 -1
  98. package/lib-esm/sync/utils.d.ts +1 -1
  99. package/lib-esm/sync/utils.js +31 -32
  100. package/lib-esm/sync/utils.js.map +1 -1
  101. package/lib-esm/types.d.ts +58 -6
  102. package/lib-esm/types.js +6 -2
  103. package/lib-esm/types.js.map +1 -1
  104. package/lib-esm/util.d.ts +39 -6
  105. package/lib-esm/util.js +170 -104
  106. package/lib-esm/util.js.map +1 -1
  107. package/package.json +11 -9
  108. package/src/authModeStrategies/multiAuthStrategy.ts +1 -1
  109. package/src/datastore/datastore.ts +679 -203
  110. package/src/index.ts +4 -0
  111. package/src/predicates/index.ts +143 -17
  112. package/src/predicates/next.ts +1016 -0
  113. package/src/predicates/sort.ts +8 -2
  114. package/src/storage/adapter/AsyncStorageAdapter.ts +56 -178
  115. package/src/storage/adapter/AsyncStorageDatabase.ts +16 -15
  116. package/src/storage/adapter/InMemoryStore.ts +5 -2
  117. package/src/storage/adapter/IndexedDBAdapter.ts +166 -191
  118. package/src/storage/adapter/getDefaultAdapter/index.ts +2 -2
  119. package/src/storage/relationship.ts +272 -0
  120. package/src/storage/storage.ts +56 -37
  121. package/src/sync/datastoreConnectivity.ts +4 -4
  122. package/src/sync/index.ts +22 -28
  123. package/src/sync/merger.ts +1 -1
  124. package/src/sync/outbox.ts +6 -6
  125. package/src/sync/processors/errorMaps.ts +1 -1
  126. package/src/sync/processors/mutation.ts +22 -17
  127. package/src/sync/processors/subscription.ts +18 -14
  128. package/src/sync/processors/sync.ts +16 -16
  129. package/src/sync/utils.ts +42 -48
  130. package/src/types.ts +115 -10
  131. package/src/util.ts +108 -150
@@ -44,7 +44,7 @@ class ModelMerger {
44
44
  }
45
45
  }
46
46
 
47
- return result;
47
+ return result!;
48
48
  }
49
49
 
50
50
  public async mergePage(
@@ -19,7 +19,7 @@ import { getIdentifierValue, TransformerMutationType } from './utils';
19
19
  // TODO: Persist deleted ids
20
20
  // https://github.com/aws-amplify/amplify-js/blob/datastore-docs/packages/datastore/docs/sync-engine.md#outbox
21
21
  class MutationEventOutbox {
22
- private inProgressMutationEventId: string;
22
+ private inProgressMutationEventId!: string;
23
23
 
24
24
  constructor(
25
25
  private readonly schema: InternalSchema,
@@ -88,7 +88,7 @@ class MutationEventOutbox {
88
88
  await s.delete(this.MutationEvent, predicate);
89
89
  }
90
90
 
91
- merged = merged || mutationEvent;
91
+ merged = merged! || mutationEvent;
92
92
 
93
93
  // Enqueue new one
94
94
  await s.save(merged, undefined, this.ownSymbol);
@@ -104,11 +104,11 @@ class MutationEventOutbox {
104
104
  const head = await this.peek(storage);
105
105
 
106
106
  if (record) {
107
- await this.syncOutboxVersionsOnDequeue(storage, record, head, recordOp);
107
+ await this.syncOutboxVersionsOnDequeue(storage, record, head, recordOp!);
108
108
  }
109
109
 
110
110
  await storage.delete(head);
111
- this.inProgressMutationEventId = undefined;
111
+ this.inProgressMutationEventId = undefined!;
112
112
 
113
113
  return head;
114
114
  }
@@ -121,9 +121,9 @@ class MutationEventOutbox {
121
121
  public async peek(storage: StorageFacade): Promise<MutationEvent> {
122
122
  const head = await storage.queryOne(this.MutationEvent, QueryOne.FIRST);
123
123
 
124
- this.inProgressMutationEventId = head ? head.id : undefined;
124
+ this.inProgressMutationEventId = head ? head.id : undefined!;
125
125
 
126
- return head;
126
+ return head!;
127
127
  }
128
128
 
129
129
  public async getForModel<T extends PersistentModel>(
@@ -85,7 +85,7 @@ export function mapErrorToType(errorMap: ErrorMap, error: Error): ErrorType {
85
85
  const errorTypes = [...Object.keys(errorMap)] as ErrorType[];
86
86
  for (const errorType of errorTypes) {
87
87
  const matcher = errorMap[errorType];
88
- if (matcher(error)) {
88
+ if (matcher?.(error)) {
89
89
  return errorType;
90
90
  }
91
91
  }
@@ -29,7 +29,6 @@ import {
29
29
  AmplifyContext,
30
30
  } from '../../types';
31
31
  import {
32
- exhaustiveCheck,
33
32
  extractTargetNamesFromSrc,
34
33
  USER,
35
34
  USER_AGENT_SUFFIX_DATASTORE,
@@ -57,7 +56,7 @@ type MutationProcessorEvent = {
57
56
  };
58
57
 
59
58
  class MutationProcessor {
60
- private observer: ZenObservable.Observer<MutationProcessorEvent>;
59
+ private observer!: ZenObservable.Observer<MutationProcessorEvent>;
61
60
  private readonly typeQuery = new WeakMap<
62
61
  SchemaModel,
63
62
  [TransformerMutationType, string, string][]
@@ -118,6 +117,8 @@ class MutationProcessor {
118
117
  }
119
118
 
120
119
  public start(): Observable<MutationProcessorEvent> {
120
+ this.runningProcesses = new BackgroundProcessManager();
121
+
121
122
  const observable = new Observable<MutationProcessorEvent>(observer => {
122
123
  this.observer = observer;
123
124
 
@@ -166,9 +167,10 @@ class MutationProcessor {
166
167
  const modelConstructor = this.userClasses[
167
168
  model
168
169
  ] as PersistentModelConstructor<MutationEvent>;
169
- let result: GraphQLResult<Record<string, PersistentModel>>;
170
- let opName: string;
171
- let modelDefinition: SchemaModel;
170
+ let result: GraphQLResult<Record<string, PersistentModel>> =
171
+ undefined!;
172
+ let opName: string = undefined!;
173
+ let modelDefinition: SchemaModel = undefined!;
172
174
 
173
175
  try {
174
176
  const modelAuthModes = await getModelAuthModes({
@@ -193,7 +195,7 @@ class MutationProcessor {
193
195
  operation,
194
196
  data,
195
197
  condition,
196
- modelConstructor,
198
+ modelConstructor as any,
197
199
  this.MutationEvent,
198
200
  head,
199
201
  operationAuthModes[authModeAttempts],
@@ -244,7 +246,7 @@ class MutationProcessor {
244
246
  continue;
245
247
  }
246
248
 
247
- const record = result.data[opName];
249
+ const record = result.data![opName!];
248
250
  let hasMore = false;
249
251
 
250
252
  await this.storage.runExclusive(async storage => {
@@ -254,7 +256,7 @@ class MutationProcessor {
254
256
  hasMore = (await this.outbox.peek(storage)) !== undefined;
255
257
  });
256
258
 
257
- this.observer.next({
259
+ this.observer.next!({
258
260
  operation,
259
261
  modelDefinition,
260
262
  model: record,
@@ -322,8 +324,8 @@ class MutationProcessor {
322
324
  await this.amplifyContext.API.graphql(tryWith)
323
325
  );
324
326
 
325
- // `as any` because TypeScript doesn't seem to like passing tuples
326
- // through generic params???
327
+ // Use `as any` because TypeScript doesn't seem to like passing tuples
328
+ // through generic params.
327
329
  return [result, opName, modelDefinition] as any;
328
330
  } catch (err) {
329
331
  if (err.errors && err.errors.length > 0) {
@@ -354,7 +356,7 @@ class MutationProcessor {
354
356
  retryWith = DISCARD;
355
357
  } else {
356
358
  try {
357
- retryWith = await this.conflictHandler({
359
+ retryWith = await this.conflictHandler!({
358
360
  modelConstructor,
359
361
  localModel: this.modelInstanceCreator(
360
362
  modelConstructor,
@@ -407,7 +409,7 @@ class MutationProcessor {
407
409
  // convert retry with to tryWith
408
410
  const updatedMutation =
409
411
  createMutationInstanceFromModelOperation(
410
- namespace.relationships,
412
+ namespace.relationships!,
411
413
  modelDefinition,
412
414
  opType,
413
415
  modelConstructor,
@@ -435,7 +437,7 @@ class MutationProcessor {
435
437
  cause: error,
436
438
  remoteModel: error.data
437
439
  ? this.modelInstanceCreator(modelConstructor, error.data)
438
- : null,
440
+ : null!,
439
441
  });
440
442
  } catch (err) {
441
443
  logger.warn('Mutation error handler failed with:', err);
@@ -480,13 +482,13 @@ class MutationProcessor {
480
482
  condition: string
481
483
  ): [string, Record<string, any>, GraphQLCondition, string, SchemaModel] {
482
484
  const modelDefinition = this.schema.namespaces[namespaceName].models[model];
483
- const { primaryKey } = this.schema.namespaces[namespaceName].keys[model];
485
+ const { primaryKey } = this.schema.namespaces[namespaceName].keys![model];
484
486
 
485
487
  const queriesTuples = this.typeQuery.get(modelDefinition);
486
488
 
487
- const [, opName, query] = queriesTuples.find(
489
+ const [, opName, query] = queriesTuples!.find(
488
490
  ([transformerMutationType]) => transformerMutationType === operation
489
- );
491
+ )!;
490
492
 
491
493
  const { _version, ...parsedData } = <ModelInstanceMetadata>JSON.parse(data);
492
494
 
@@ -579,8 +581,11 @@ class MutationProcessor {
579
581
  case TransformerMutationType.GET: // Intentionally blank
580
582
  break;
581
583
  default:
582
- exhaustiveCheck(operation);
584
+ throw new Error(`Invalid operation ${operation}`);
583
585
  }
586
+
587
+ // because it makes TS happy ...
588
+ return undefined!;
584
589
  }
585
590
 
586
591
  public pause() {
@@ -59,7 +59,7 @@ class SubscriptionProcessor {
59
59
  >();
60
60
  private buffer: [TransformerMutationType, SchemaModel, PersistentModel][] =
61
61
  [];
62
- private dataObserver: ZenObservable.Observer<any>;
62
+ private dataObserver!: ZenObservable.Observer<any>;
63
63
 
64
64
  private runningProcesses = new BackgroundProcessManager();
65
65
 
@@ -105,7 +105,7 @@ class SubscriptionProcessor {
105
105
  model,
106
106
  transformerMutationType,
107
107
  isOwner,
108
- ownerField
108
+ ownerField!
109
109
  );
110
110
  return { authMode, opType, opName, query, isOwner, ownerField, ownerValue };
111
111
  }
@@ -128,7 +128,7 @@ class SubscriptionProcessor {
128
128
  );
129
129
 
130
130
  if (iamPrivateAuth && userCredentials === USER_CREDENTIALS.unauth) {
131
- return null;
131
+ return null!;
132
132
  }
133
133
 
134
134
  // Group auth should take precedence over owner auth, so we are checking
@@ -192,8 +192,8 @@ class SubscriptionProcessor {
192
192
  }
193
193
  });
194
194
 
195
- if (ownerAuthInfo) {
196
- return ownerAuthInfo;
195
+ if (ownerAuthInfo!) {
196
+ return ownerAuthInfo!;
197
197
  }
198
198
 
199
199
  // Owner auth needs additional values to be returned in order to create the subscription with
@@ -219,8 +219,8 @@ class SubscriptionProcessor {
219
219
  }
220
220
  });
221
221
 
222
- if (ownerAuthInfo) {
223
- return ownerAuthInfo;
222
+ if (ownerAuthInfo!) {
223
+ return ownerAuthInfo!;
224
224
  }
225
225
 
226
226
  // Fallback: return authMode or default auth type
@@ -244,6 +244,9 @@ class SubscriptionProcessor {
244
244
  Observable<CONTROL_MSG>,
245
245
  Observable<[TransformerMutationType, SchemaModel, PersistentModel]>
246
246
  ] {
247
+ this.runningProcesses =
248
+ this.runningProcesses || new BackgroundProcessManager();
249
+
247
250
  const ctlObservable = new Observable<CONTROL_MSG>(observer => {
248
251
  const promises: Promise<void>[] = [];
249
252
 
@@ -388,7 +391,7 @@ class SubscriptionProcessor {
388
391
  return;
389
392
  }
390
393
 
391
- variables[ownerField] = ownerValue;
394
+ variables[ownerField!] = ownerValue;
392
395
  }
393
396
 
394
397
  logger.debug(
@@ -443,10 +446,11 @@ class SubscriptionProcessor {
443
446
 
444
447
  const predicatesGroup =
445
448
  ModelPredicateCreator.getPredicates(
446
- this.syncPredicates.get(modelDefinition),
449
+ this.syncPredicates.get(modelDefinition)!,
447
450
  false
448
451
  );
449
452
 
453
+ // @ts-ignore
450
454
  const { [opName]: record } = data;
451
455
 
452
456
  // checking incoming subscription against syncPredicate.
@@ -456,7 +460,7 @@ class SubscriptionProcessor {
456
460
  if (
457
461
  this.passesPredicateValidation(
458
462
  record,
459
- predicatesGroup
463
+ predicatesGroup!
460
464
  )
461
465
  ) {
462
466
  this.pushToBuffer(
@@ -529,14 +533,14 @@ class SubscriptionProcessor {
529
533
  await this.errorHandler({
530
534
  recoverySuggestion:
531
535
  'Ensure app code is up to date, auth directives exist and are correct on each model, and that server-side data has not been invalidated by a schema change. If the problem persists, search for or create an issue: https://github.com/aws-amplify/amplify-js/issues',
532
- localModel: null,
536
+ localModel: null!,
533
537
  message,
534
538
  model: modelDefinition.name,
535
539
  operation,
536
540
  errorType:
537
541
  getSubscriptionErrorType(subscriptionError),
538
542
  process: ProcessName.subscribe,
539
- remoteModel: null,
543
+ remoteModel: null!,
540
544
  cause: subscriptionError,
541
545
  });
542
546
  } catch (e) {
@@ -617,7 +621,7 @@ class SubscriptionProcessor {
617
621
  this.drainBuffer();
618
622
 
619
623
  return this.runningProcesses.addCleaner(async () => {
620
- this.dataObserver = null;
624
+ this.dataObserver = null!;
621
625
  });
622
626
  });
623
627
 
@@ -652,7 +656,7 @@ class SubscriptionProcessor {
652
656
 
653
657
  private drainBuffer() {
654
658
  if (this.dataObserver) {
655
- this.buffer.forEach(data => this.dataObserver.next(data));
659
+ this.buffer.forEach(data => this.dataObserver.next!(data));
656
660
  this.buffer = [];
657
661
  }
658
662
  }
@@ -73,16 +73,16 @@ class SyncProcessor {
73
73
 
74
74
  private graphqlFilterFromPredicate(model: SchemaModel): GraphQLFilter {
75
75
  if (!this.syncPredicates) {
76
- return null;
76
+ return null!;
77
77
  }
78
78
  const predicatesGroup: PredicatesGroup<any> =
79
79
  ModelPredicateCreator.getPredicates(
80
- this.syncPredicates.get(model),
80
+ this.syncPredicates.get(model)!,
81
81
  false
82
- );
82
+ )!;
83
83
 
84
84
  if (!predicatesGroup) {
85
- return null;
85
+ return null!;
86
86
  }
87
87
 
88
88
  return predicateToGraphQLFilter(predicatesGroup);
@@ -92,11 +92,11 @@ class SyncProcessor {
92
92
  modelDefinition: SchemaModel,
93
93
  lastSync: number,
94
94
  nextToken: string,
95
- limit: number = null,
95
+ limit: number = null!,
96
96
  filter: GraphQLFilter,
97
97
  onTerminate: Promise<void>
98
98
  ): Promise<{ nextToken: string; startedAt: number; items: T[] }> {
99
- const [opName, query] = this.typeQuery.get(modelDefinition);
99
+ const [opName, query] = this.typeQuery.get(modelDefinition)!;
100
100
 
101
101
  const variables = {
102
102
  limit,
@@ -257,13 +257,13 @@ class SyncProcessor {
257
257
  await this.errorHandler({
258
258
  recoverySuggestion:
259
259
  'Ensure app code is up to date, auth directives exist and are correct on each model, and that server-side data has not been invalidated by a schema change. If the problem persists, search for or create an issue: https://github.com/aws-amplify/amplify-js/issues',
260
- localModel: null,
260
+ localModel: null!,
261
261
  message: err.message,
262
262
  model: modelDefinition.name,
263
263
  operation: opName,
264
264
  errorType: getSyncErrorType(err),
265
265
  process: ProcessName.sync,
266
- remoteModel: null,
266
+ remoteModel: null!,
267
267
  cause: err,
268
268
  });
269
269
  } catch (e) {
@@ -318,10 +318,10 @@ class SyncProcessor {
318
318
  const sortedTypesLastSyncs = Object.values(this.schema.namespaces).reduce(
319
319
  (map, namespace) => {
320
320
  for (const modelName of Array.from(
321
- namespace.modelTopologicalOrdering.keys()
321
+ namespace.modelTopologicalOrdering!.keys()
322
322
  )) {
323
323
  const typeLastSync = typesLastSync.get(namespace.models[modelName]);
324
- map.set(namespace.models[modelName], typeLastSync);
324
+ map.set(namespace.models[modelName], typeLastSync!);
325
325
  }
326
326
  return map;
327
327
  },
@@ -335,17 +335,17 @@ class SyncProcessor {
335
335
  this.runningProcesses.isOpen &&
336
336
  this.runningProcesses.add(async onTerminate => {
337
337
  let done = false;
338
- let nextToken: string = null;
339
- let startedAt: number = null;
340
- let items: ModelInstanceMetadata[] = null;
338
+ let nextToken: string = null!;
339
+ let startedAt: number = null!;
340
+ let items: ModelInstanceMetadata[] = null!;
341
341
 
342
342
  let recordsReceived = 0;
343
343
  const filter = this.graphqlFilterFromPredicate(modelDefinition);
344
344
 
345
345
  const parents = this.schema.namespaces[
346
346
  namespace
347
- ].modelTopologicalOrdering.get(modelDefinition.name);
348
- const promises = parents.map(parent =>
347
+ ].modelTopologicalOrdering!.get(modelDefinition.name);
348
+ const promises = parents!.map(parent =>
349
349
  parentPromises.get(`${namespace}_${parent}`)
350
350
  );
351
351
 
@@ -398,7 +398,7 @@ class SyncProcessor {
398
398
  }, `adding model ${modelDefinition.name}`)
399
399
  );
400
400
 
401
- Promise.all(allModelsReady).then(() => {
401
+ Promise.all(allModelsReady as Promise<any>[]).then(() => {
402
402
  observer.complete();
403
403
  });
404
404
  });
package/src/sync/utils.ts CHANGED
@@ -27,9 +27,9 @@ import {
27
27
  ModelOperation,
28
28
  InternalSchema,
29
29
  AuthModeStrategy,
30
+ ModelAttributes,
30
31
  } from '../types';
31
32
  import {
32
- exhaustiveCheck,
33
33
  extractPrimaryKeyFieldNames,
34
34
  establishRelationAndKeys,
35
35
  IDENTIFIER_KEY_SEPARATOR,
@@ -54,9 +54,9 @@ export enum TransformerMutationType {
54
54
  }
55
55
 
56
56
  const dummyMetadata: ModelInstanceMetadata = {
57
- _version: undefined,
58
- _lastChangedAt: undefined,
59
- _deleted: undefined,
57
+ _version: undefined!,
58
+ _lastChangedAt: undefined!,
59
+ _deleted: undefined!,
60
60
  };
61
61
 
62
62
  const metadataFields = <(keyof ModelInstanceMetadata)[]>(
@@ -110,7 +110,7 @@ function getOwnerFields(
110
110
  ): string[] {
111
111
  const ownerFields: string[] = [];
112
112
  if (isSchemaModelWithAttributes(modelDefinition)) {
113
- modelDefinition.attributes.forEach(attr => {
113
+ modelDefinition.attributes!.forEach(attr => {
114
114
  if (attr.properties && attr.properties.rules) {
115
115
  const rule = attr.properties.rules.find(rule => rule.allow === 'owner');
116
116
  if (rule && rule.ownerField) {
@@ -154,7 +154,7 @@ function getConnectionFields(
154
154
  Object.values(modelDefinition.fields)
155
155
  .filter(({ association }) => association && Object.keys(association).length)
156
156
  .forEach(({ name, association }) => {
157
- const { connectionType } = association;
157
+ const { connectionType } = association || {};
158
158
 
159
159
  switch (connectionType) {
160
160
  case 'HAS_ONE':
@@ -186,7 +186,7 @@ function getConnectionFields(
186
186
  }
187
187
  break;
188
188
  default:
189
- exhaustiveCheck(connectionType);
189
+ throw new Error(`Invalid connection type ${connectionType}`);
190
190
  }
191
191
  });
192
192
 
@@ -197,7 +197,7 @@ function getNonModelFields(
197
197
  namespace: SchemaNamespace,
198
198
  modelDefinition: SchemaModel | SchemaNonModel
199
199
  ): string[] {
200
- const result = [];
200
+ const result: string[] = [];
201
201
 
202
202
  Object.values(modelDefinition.fields).forEach(({ name, type }) => {
203
203
  if (isNonModelFieldType(type)) {
@@ -206,13 +206,12 @@ function getNonModelFields(
206
206
  ({ name }) => name
207
207
  );
208
208
 
209
- const nested = [];
209
+ const nested: string[] = [];
210
210
  Object.values(typeDefinition.fields).forEach(field => {
211
211
  const { type, name } = field;
212
212
 
213
213
  if (isNonModelFieldType(type)) {
214
214
  const typeDefinition = namespace.nonModels![type.nonModel];
215
-
216
215
  nested.push(
217
216
  `${name} { ${generateSelectionSet(namespace, typeDefinition)} }`
218
217
  );
@@ -230,8 +229,8 @@ export function getAuthorizationRules(
230
229
  modelDefinition: SchemaModel
231
230
  ): AuthorizationRule[] {
232
231
  // Searching for owner authorization on attributes
233
- const authConfig = []
234
- .concat(modelDefinition.attributes)
232
+ const authConfig = ([] as ModelAttributes)
233
+ .concat(modelDefinition.attributes || [])
235
234
  .find(attr => attr && attr.type === 'auth');
236
235
 
237
236
  const { properties: { rules = [] } = {} } = authConfig || {};
@@ -270,8 +269,8 @@ export function getAuthorizationRules(
270
269
  if (isOwnerAuth) {
271
270
  // look for the subscription level override
272
271
  // only pay attention to the public level
273
- const modelConfig = (<typeof modelDefinition.attributes>[])
274
- .concat(modelDefinition.attributes)
272
+ const modelConfig = ([] as ModelAttributes)
273
+ .concat(modelDefinition.attributes || [])
275
274
  .find(attr => attr && attr.type === 'model');
276
275
 
277
276
  // find the subscriptions level. ON is default
@@ -337,8 +336,8 @@ export function buildGraphQLOperation(
337
336
  const { name: typeName, pluralName: pluralTypeName } = modelDefinition;
338
337
 
339
338
  let operation: string;
340
- let documentArgs: string = ' ';
341
- let operationArgs: string = ' ';
339
+ let documentArgs: string;
340
+ let operationArgs: string;
342
341
  let transformerMutationType: TransformerMutationType;
343
342
 
344
343
  switch (graphQLOpType) {
@@ -377,17 +376,16 @@ export function buildGraphQLOperation(
377
376
  operationArgs = '(id: $id)';
378
377
  transformerMutationType = TransformerMutationType.GET;
379
378
  break;
380
-
381
379
  default:
382
- exhaustiveCheck(graphQLOpType);
380
+ throw new Error(`Invalid graphQlOpType ${graphQLOpType}`);
383
381
  }
384
382
 
385
383
  return [
386
384
  [
387
- transformerMutationType,
388
- operation,
385
+ transformerMutationType!,
386
+ operation!,
389
387
  `${GraphQLOperationType[graphQLOpType]} operation${documentArgs}{
390
- ${operation}${operationArgs}{
388
+ ${operation!}${operationArgs}{
391
389
  ${selectionSet}
392
390
  }
393
391
  }`,
@@ -421,7 +419,7 @@ export function createMutationInstanceFromModelOperation<
421
419
  operation = TransformerMutationType.DELETE;
422
420
  break;
423
421
  default:
424
- exhaustiveCheck(opType);
422
+ throw new Error(`Invalid opType ${opType}`);
425
423
  }
426
424
 
427
425
  // stringify nested objects of type AWSJSON
@@ -449,7 +447,7 @@ export function createMutationInstanceFromModelOperation<
449
447
  data: JSON.stringify(element, replacer),
450
448
  modelId,
451
449
  model: model.name,
452
- operation,
450
+ operation: operation!,
453
451
  condition: JSON.stringify(condition),
454
452
  });
455
453
 
@@ -466,35 +464,22 @@ export function predicateToGraphQLCondition(
466
464
  return result;
467
465
  }
468
466
 
469
- const keyFields = extractPrimaryKeyFieldNames(modelDefinition);
470
-
471
- predicate.predicates.forEach(p => {
472
- if (isPredicateObj(p)) {
473
- const { field, operator, operand } = p;
474
-
475
- // This is compatible with how the GQL Transform currently generates the Condition Input,
476
- // i.e. any PK and SK fields are omitted and can't be used as conditions.
477
- // However, I think this limits usability.
478
- // What if we want to delete all records where SK > some value
479
- // Or all records where PK = some value but SKs are different values
480
-
481
- // TODO: if the Transform gets updated ^ we'll need to modify this logic to only omit
482
- // key fields from the predicate/condition when ALL of the keyFields are present and using `eq` operators
483
- if (keyFields.includes(field as string)) {
484
- return;
485
- }
467
+ // This is compatible with how the GQL Transform currently generates the Condition Input,
468
+ // i.e. any PK and SK fields are omitted and can't be used as conditions.
469
+ // However, I think this limits usability.
470
+ // What if we want to delete all records where SK > some value
471
+ // Or all records where PK = some value but SKs are different values
486
472
 
487
- result[field] = { [operator]: operand };
488
- } else {
489
- result[p.type] = predicateToGraphQLCondition(p, modelDefinition);
490
- }
491
- });
473
+ // TODO: if the Transform gets updated we'll need to modify this logic to only omit
474
+ // key fields from the predicate/condition when ALL of the keyFields are present and using `eq` operators
492
475
 
493
- return result;
476
+ const keyFields = extractPrimaryKeyFieldNames(modelDefinition);
477
+ return predicateToGraphQLFilter(predicate, keyFields) as GraphQLCondition;
494
478
  }
495
479
 
496
480
  export function predicateToGraphQLFilter(
497
- predicatesGroup: PredicatesGroup<any>
481
+ predicatesGroup: PredicatesGroup<any>,
482
+ fieldsToOmit: string[] = []
498
483
  ): GraphQLFilter {
499
484
  const result: GraphQLFilter = {};
500
485
 
@@ -514,6 +499,8 @@ export function predicateToGraphQLFilter(
514
499
  if (isPredicateObj(predicate)) {
515
500
  const { field, operator, operand } = predicate;
516
501
 
502
+ if (fieldsToOmit.includes(field as string)) return;
503
+
517
504
  const gqlField: GraphQLField = {
518
505
  [field]: { [operator]: operand },
519
506
  };
@@ -522,9 +509,16 @@ export function predicateToGraphQLFilter(
522
509
  return;
523
510
  }
524
511
 
525
- appendToFilter(predicateToGraphQLFilter(predicate));
512
+ const child = predicateToGraphQLFilter(predicate, fieldsToOmit);
513
+ Object.keys(child).length > 0 && appendToFilter(child);
526
514
  });
527
515
 
516
+ if (isList) {
517
+ if (result[type].length === 0) return {};
518
+ } else {
519
+ if (Object.keys(result[type]).length === 0) return {};
520
+ }
521
+
528
522
  return result;
529
523
  }
530
524