@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
package/src/types.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  import { ModelInstanceCreator } from './datastore/datastore';
2
2
  import {
3
- exhaustiveCheck,
4
3
  isAWSDate,
5
4
  isAWSTime,
6
5
  isAWSDateTime,
@@ -10,6 +9,7 @@ import {
10
9
  isAWSURL,
11
10
  isAWSPhone,
12
11
  isAWSIPAddress,
12
+ NAMESPACES,
13
13
  extractPrimaryKeyFieldNames,
14
14
  } from './util';
15
15
  import { PredicateAll } from './predicates';
@@ -19,9 +19,12 @@ import { API } from '@aws-amplify/api';
19
19
  import { Cache } from '@aws-amplify/cache';
20
20
  import { Adapter } from './storage/adapter';
21
21
 
22
+ export type Scalar<T> = T extends Array<infer InnerType> ? InnerType : T;
23
+
22
24
  //#region Schema types
23
25
  export type Schema = UserSchema & {
24
26
  version: string;
27
+ codegenVersion: string;
25
28
  };
26
29
  export type UserSchema = {
27
30
  models: SchemaModels;
@@ -34,6 +37,7 @@ export type UserSchema = {
34
37
  export type InternalSchema = {
35
38
  namespaces: SchemaNamespaces;
36
39
  version: string;
40
+ codegenVersion: string;
37
41
  };
38
42
  export type SchemaNamespaces = Record<string, SchemaNamespace>;
39
43
  export type SchemaNamespace = UserSchema & {
@@ -68,7 +72,11 @@ type SchemaEnum = {
68
72
  name: string;
69
73
  values: string[];
70
74
  };
71
-
75
+ export type ModelMeta<T extends PersistentModel> = {
76
+ builder: PersistentModelConstructor<T>;
77
+ schema: SchemaModel;
78
+ pkField: string[];
79
+ };
72
80
  export type ModelAssociation = AssociatedWith | TargetNameAssociation;
73
81
  type AssociatedWith = {
74
82
  connectionType: 'HAS_MANY' | 'HAS_ONE';
@@ -93,6 +101,16 @@ export function isTargetNameAssociation(
93
101
  return obj?.targetName || obj?.targetNames;
94
102
  }
95
103
 
104
+ type FieldAssociation = {
105
+ connectionType: 'HAS_ONE' | 'BELONGS_TO' | 'HAS_MANY';
106
+ };
107
+ export function isFieldAssociation(
108
+ obj: any,
109
+ fieldName: string
110
+ ): obj is FieldAssociation {
111
+ return obj?.fields[fieldName]?.association?.connectionType;
112
+ }
113
+
96
114
  export type ModelAttributes = ModelAttribute[];
97
115
  export type ModelAttribute = { type: string; properties?: Record<string, any> };
98
116
 
@@ -226,7 +244,7 @@ export namespace GraphQLScalarType {
226
244
  typeof GraphQLScalarType,
227
245
  'getJSType' | 'getValidationFunction'
228
246
  >
229
- ): 'string' | 'number' | 'boolean' | 'object' {
247
+ ) {
230
248
  switch (scalar) {
231
249
  case 'Boolean':
232
250
  return 'boolean';
@@ -247,7 +265,7 @@ export namespace GraphQLScalarType {
247
265
  case 'AWSJSON':
248
266
  return 'object';
249
267
  default:
250
- exhaustiveCheck(scalar as never);
268
+ throw new Error('Invalid scalar type');
251
269
  }
252
270
  }
253
271
 
@@ -256,7 +274,7 @@ export namespace GraphQLScalarType {
256
274
  typeof GraphQLScalarType,
257
275
  'getJSType' | 'getValidationFunction'
258
276
  >
259
- ): ((val: string | number) => boolean) | undefined {
277
+ ): ((val: string) => boolean) | ((val: number) => boolean) | undefined {
260
278
  switch (scalar) {
261
279
  case 'AWSDate':
262
280
  return isAWSDate;
@@ -301,8 +319,13 @@ export function isGraphQLScalarType(
301
319
  return obj && GraphQLScalarType[obj] !== undefined;
302
320
  }
303
321
 
304
- export type ModelFieldType = { model: string };
305
- export function isModelFieldType(obj: any): obj is ModelFieldType {
322
+ export type ModelFieldType = {
323
+ model: string;
324
+ modelConstructor?: ModelMeta<PersistentModel>;
325
+ };
326
+ export function isModelFieldType<T extends PersistentModel>(
327
+ obj: any
328
+ ): obj is ModelFieldType {
306
329
  const modelField: keyof ModelFieldType = 'model';
307
330
  if (obj && obj[modelField]) return true;
308
331
 
@@ -358,6 +381,24 @@ export type PersistentModelConstructor<T extends PersistentModel> = {
358
381
  ): T;
359
382
  };
360
383
 
384
+ /**
385
+ * @private
386
+ * Internal use of Amplify only.
387
+ *
388
+ * Indicates to use lazy models or eager models.
389
+ */
390
+ export declare class LazyLoadingDisabled {
391
+ disabled: true;
392
+ }
393
+
394
+ /**
395
+ * @private
396
+ * Internal use of Amplify only.
397
+ *
398
+ * Indicates to use lazy models or eager models.
399
+ */
400
+ export declare class LazyLoading {}
401
+
361
402
  export type TypeConstructorMap = Record<
362
403
  string,
363
404
  PersistentModelConstructor<any> | NonModelTypeConstructor<unknown>
@@ -439,6 +480,53 @@ export type PersistentModelMetaData<T> = {
439
480
  readOnlyFields?: string;
440
481
  };
441
482
 
483
+ export interface AsyncCollection<T> extends AsyncIterable<T> {
484
+ toArray(options?: { max?: number }): Promise<T[]>;
485
+ }
486
+
487
+ export type SettableFieldType<T> = T extends Promise<infer InnerPromiseType>
488
+ ? undefined extends InnerPromiseType
489
+ ? InnerPromiseType | null
490
+ : InnerPromiseType
491
+ : T extends AsyncCollection<infer InnerCollectionType>
492
+ ? InnerCollectionType[] | undefined
493
+ : undefined extends T
494
+ ? T | null
495
+ : T;
496
+
497
+ export type PredicateFieldType<T> = NonNullable<
498
+ Scalar<
499
+ T extends Promise<infer InnerPromiseType>
500
+ ? InnerPromiseType
501
+ : T extends AsyncCollection<infer InnerCollectionType>
502
+ ? InnerCollectionType
503
+ : T
504
+ >
505
+ >;
506
+
507
+ type KeysOfType<T, FilterType> = {
508
+ [P in keyof T]: T[P] extends FilterType ? P : never;
509
+ }[keyof T];
510
+
511
+ type KeysOfSuperType<T, FilterType> = {
512
+ [P in keyof T]: FilterType extends T[P] ? P : never;
513
+ }[keyof T];
514
+
515
+ type OptionalRelativesOf<T> =
516
+ | KeysOfType<T, AsyncCollection<any>>
517
+ | KeysOfSuperType<T, Promise<undefined>>;
518
+
519
+ type OmitOptionalRelatives<T> = Omit<T, OptionalRelativesOf<T>>;
520
+ type PickOptionalRelatives<T> = Pick<T, OptionalRelativesOf<T>>;
521
+ type OmitOptionalFields<T> = Omit<
522
+ T,
523
+ KeysOfSuperType<T, undefined> | OptionalRelativesOf<T>
524
+ >;
525
+ type PickOptionalFields<T> = Pick<
526
+ T,
527
+ KeysOfSuperType<T, undefined> | OptionalRelativesOf<T>
528
+ >;
529
+
442
530
  export type DefaultPersistentModelMetaData = {
443
531
  identifier: ManagedIdentifier<{ id: string }, 'id'>;
444
532
  readOnlyFields: never;
@@ -468,7 +556,7 @@ export type MetadataReadOnlyFields<
468
556
  // This type omits readOnlyFields in the constructor init object
469
557
  // This type requires some identifiers in the constructor init object (e.g. CustomIdentifier)
470
558
  // This type makes optional some identifiers in the constructor init object (e.g. OptionallyManagedIdentifier)
471
- export type ModelInit<
559
+ export type ModelInitBase<
472
560
  T extends PersistentModel,
473
561
  M extends PersistentModelMetaData<T> = {}
474
562
  > = Omit<
@@ -482,9 +570,26 @@ export type ModelInit<
482
570
  ? Partial<Pick<T, IdentifierFieldsForInit<T, M>>>
483
571
  : Required<Pick<T, IdentifierFieldsForInit<T, M>>>);
484
572
 
573
+ export type ModelInit<
574
+ T extends PersistentModel,
575
+ M extends PersistentModelMetaData<T> = {}
576
+ > = {
577
+ [P in keyof OmitOptionalRelatives<ModelInitBase<T, M>>]: SettableFieldType<
578
+ ModelInitBase<T, M>[P]
579
+ >;
580
+ } & {
581
+ [P in keyof PickOptionalRelatives<ModelInitBase<T, M>>]+?: SettableFieldType<
582
+ ModelInitBase<T, M>[P]
583
+ >;
584
+ };
585
+
485
586
  type DeepWritable<T> = {
486
587
  -readonly [P in keyof T]: T[P] extends TypeName<T[P]>
487
588
  ? T[P]
589
+ : T[P] extends Promise<infer InnerPromiseType>
590
+ ? InnerPromiseType
591
+ : T[P] extends AsyncCollection<infer InnerCollectionType>
592
+ ? InnerCollectionType[] | undefined
488
593
  : DeepWritable<T[P]>;
489
594
  };
490
595
 
@@ -753,10 +858,10 @@ export type SystemComponent = {
753
858
  namespaceResolver: NamespaceResolver,
754
859
  modelInstanceCreator: ModelInstanceCreator,
755
860
  getModelConstructorByModelName: (
756
- namsespaceName: string,
861
+ namsespaceName: NAMESPACES,
757
862
  modelName: string
758
863
  ) => PersistentModelConstructor<any>,
759
- appId: string
864
+ appId?: string
760
865
  ): Promise<void>;
761
866
  };
762
867
 
package/src/util.ts CHANGED
@@ -7,7 +7,6 @@ import {
7
7
  AllOperators,
8
8
  isPredicateGroup,
9
9
  isPredicateObj,
10
- ModelInstanceMetadata,
11
10
  PersistentModel,
12
11
  PersistentModelConstructor,
13
12
  PredicateGroups,
@@ -24,6 +23,7 @@ import {
24
23
  isModelAttributePrimaryKey,
25
24
  isModelAttributeCompositeKey,
26
25
  NonModelTypeConstructor,
26
+ PaginationInput,
27
27
  DeferredCallbackResolverOptions,
28
28
  LimitTimerRaceResolvedValues,
29
29
  SchemaModel,
@@ -32,6 +32,7 @@ import {
32
32
  ModelAssociation,
33
33
  } from './types';
34
34
  import { WordArray } from 'amazon-cognito-identity-js';
35
+ import { ModelSortPredicateCreator } from './predicates';
35
36
 
36
37
  export const ID = 'id';
37
38
 
@@ -110,7 +111,7 @@ export const validatePredicate = <T extends PersistentModel>(
110
111
  filterType = 'some';
111
112
  break;
112
113
  default:
113
- exhaustiveCheck(groupType);
114
+ throw new Error(`Invalid ${groupType}`);
114
115
  }
115
116
 
116
117
  const result: boolean = predicatesOrGroups[filterType](predicateOrGroup => {
@@ -169,7 +170,6 @@ export const validatePredicateField = <T>(
169
170
  (<string>(<unknown>value)).indexOf(<string>(<unknown>operand)) === -1
170
171
  );
171
172
  default:
172
- exhaustiveCheck(operator, false);
173
173
  return false;
174
174
  }
175
175
  };
@@ -202,155 +202,22 @@ export const traverseModel = <T extends PersistentModel>(
202
202
  namespace: SchemaNamespace,
203
203
  modelInstanceCreator: ModelInstanceCreator,
204
204
  getModelConstructorByModelName: (
205
- namsespaceName: string,
205
+ namsespaceName: NAMESPACES,
206
206
  modelName: string
207
207
  ) => PersistentModelConstructor<any>
208
208
  ) => {
209
- const relationships = namespace.relationships;
210
-
211
209
  const modelConstructor = getModelConstructorByModelName(
212
- namespace.name,
210
+ namespace.name as NAMESPACES,
213
211
  srcModelName
214
212
  );
215
213
 
216
- const relation = relationships[srcModelName];
217
-
218
214
  const result: {
219
215
  modelName: string;
220
216
  item: T;
221
217
  instance: T;
222
218
  }[] = [];
223
219
 
224
- const newInstance = modelConstructor.copyOf(instance, draftInstance => {
225
- relation.relationTypes.forEach((rItem: RelationType) => {
226
- const modelConstructor = getModelConstructorByModelName(
227
- namespace.name,
228
- rItem.modelName
229
- );
230
-
231
- switch (rItem.relationType) {
232
- case 'HAS_ONE':
233
- if (instance[rItem.fieldName]) {
234
- let modelInstance: T;
235
- try {
236
- modelInstance = modelInstanceCreator(
237
- modelConstructor,
238
- instance[rItem.fieldName]
239
- );
240
- } catch (error) {
241
- // Do nothing
242
- console.log(error);
243
- }
244
-
245
- result.push({
246
- modelName: rItem.modelName,
247
- item: instance[rItem.fieldName],
248
- instance: modelInstance,
249
- });
250
-
251
- const targetNames: string[] | undefined =
252
- extractTargetNamesFromSrc(rItem);
253
-
254
- // `targetName` will be defined for Has One if feature flag
255
- // https://docs.amplify.aws/cli/reference/feature-flags/#useAppsyncModelgenPlugin
256
- // is true (default as of 5/7/21)
257
- // Making this conditional for backward-compatibility
258
- if (targetNames) {
259
- targetNames.forEach((targetName, idx) => {
260
- // Get the connected record
261
- const relatedRecordInProxy = <PersistentModel>(
262
- draftInstance[rItem.fieldName]
263
- );
264
-
265
- // Previously, we used the hardcoded 'id' as they key,
266
- // now we need the value of the key to get the PK (and SK)
267
- // values from the related record
268
-
269
- const { primaryKey } = namespace.keys[modelConstructor.name];
270
- const keyField = primaryKey && primaryKey[idx];
271
-
272
- // Get the value
273
- const relatedRecordInProxyPkValue =
274
- relatedRecordInProxy[keyField];
275
-
276
- // Set the targetName value
277
- (<any>draftInstance)[targetName] = relatedRecordInProxyPkValue;
278
- });
279
- // Delete the instance from the proxy
280
- delete (<any>draftInstance)[rItem.fieldName];
281
- } else {
282
- (<any>draftInstance)[rItem.fieldName] = (<PersistentModel>(
283
- draftInstance[rItem.fieldName]
284
- )).id;
285
- }
286
- }
287
-
288
- break;
289
- case 'BELONGS_TO':
290
- if (instance[rItem.fieldName]) {
291
- let modelInstance: T;
292
- try {
293
- modelInstance = modelInstanceCreator(
294
- modelConstructor,
295
- instance[rItem.fieldName]
296
- );
297
- } catch (error) {
298
- // Do nothing
299
- }
300
-
301
- const isDeleted = (<ModelInstanceMetadata>(
302
- draftInstance[rItem.fieldName]
303
- ))._deleted;
304
-
305
- if (!isDeleted) {
306
- result.push({
307
- modelName: rItem.modelName,
308
- item: instance[rItem.fieldName],
309
- instance: modelInstance,
310
- });
311
- }
312
- }
313
-
314
- if (draftInstance[rItem.fieldName]) {
315
- const targetNames: string[] | undefined =
316
- extractTargetNamesFromSrc(rItem);
317
-
318
- if (targetNames) {
319
- targetNames.forEach((targetName, idx) => {
320
- // Get the connected record
321
- const relatedRecordInProxy = <PersistentModel>(
322
- draftInstance[rItem.fieldName]
323
- );
324
- // Previously, we used the hardcoded `id` for the key.
325
- // Now, we need the value of the key to get the PK (and SK)
326
- // values from the related record
327
- const { primaryKey } = namespace.keys[modelConstructor.name];
328
-
329
- // fall back to ID if
330
- const keyField = primaryKey && primaryKey[idx];
331
-
332
- // Get the value
333
- const relatedRecordInProxyPkValue =
334
- relatedRecordInProxy[keyField];
335
-
336
- // Set the targetName value
337
- (<any>draftInstance)[targetName] = relatedRecordInProxyPkValue;
338
- });
339
- // Delete the instance from the proxy
340
- delete (<any>draftInstance)[rItem.fieldName];
341
- }
342
- }
343
-
344
- break;
345
- case 'HAS_MANY':
346
- // Intentionally blank
347
- break;
348
- default:
349
- exhaustiveCheck(rItem.relationType);
350
- break;
351
- }
352
- });
353
- });
220
+ const newInstance = modelConstructor.copyOf(instance, () => {});
354
221
 
355
222
  result.unshift({
356
223
  modelName: srcModelName,
@@ -361,7 +228,7 @@ export const traverseModel = <T extends PersistentModel>(
361
228
  if (!topologicallySortedModels.has(namespace)) {
362
229
  topologicallySortedModels.set(
363
230
  namespace,
364
- Array.from(namespace.modelTopologicalOrdering.keys())
231
+ Array.from(namespace.modelTopologicalOrdering!.keys())
365
232
  );
366
233
  }
367
234
 
@@ -369,7 +236,7 @@ export const traverseModel = <T extends PersistentModel>(
369
236
 
370
237
  result.sort((a, b) => {
371
238
  return (
372
- sortedModels.indexOf(a.modelName) - sortedModels.indexOf(b.modelName)
239
+ sortedModels!.indexOf(a.modelName) - sortedModels!.indexOf(b.modelName)
373
240
  );
374
241
  });
375
242
 
@@ -618,8 +485,8 @@ export function valuesEqual(
618
485
  }
619
486
 
620
487
  if (a instanceof Map && b instanceof Map) {
621
- a = Object.fromEntries(a);
622
- b = Object.fromEntries(b);
488
+ a = (Object as any).fromEntries(a);
489
+ b = (Object as any).fromEntries(b);
623
490
  }
624
491
 
625
492
  const aKeys = Object.keys(a);
@@ -647,6 +514,97 @@ export function valuesEqual(
647
514
  return true;
648
515
  }
649
516
 
517
+ /**
518
+ * Statelessly extracts the specified page from an array.
519
+ *
520
+ * @param records - The source array to extract a page from.
521
+ * @param pagination - A definition of the page to extract.
522
+ * @returns This items from `records` matching the `pagination` definition.
523
+ */
524
+ export function inMemoryPagination<T extends PersistentModel>(
525
+ records: T[],
526
+ pagination?: PaginationInput<T>
527
+ ): T[] {
528
+ if (pagination && records.length > 1) {
529
+ if (pagination.sort) {
530
+ const sortPredicates = ModelSortPredicateCreator.getPredicates(
531
+ pagination.sort
532
+ );
533
+
534
+ if (sortPredicates.length) {
535
+ const compareFn = sortCompareFunction(sortPredicates);
536
+ records.sort(compareFn);
537
+ }
538
+ }
539
+ const { page = 0, limit = 0 } = pagination;
540
+ const start = Math.max(0, page * limit) || 0;
541
+
542
+ const end = limit > 0 ? start + limit : records.length;
543
+
544
+ return records.slice(start, end);
545
+ }
546
+ return records;
547
+ }
548
+
549
+ /**
550
+ * An `aysnc` implementation of `Array.some()`. Returns as soon as a match is found.
551
+ * @param items The items to check.
552
+ * @param matches The async matcher function, expected to
553
+ * return Promise<boolean>: `true` for a matching item, `false` otherwise.
554
+ * @returns A `Promise<boolean>`, `true` if "some" items match; `false` otherwise.
555
+ */
556
+ export async function asyncSome(
557
+ items: Record<string, any>[],
558
+ matches: (item: Record<string, any>) => Promise<boolean>
559
+ ): Promise<boolean> {
560
+ for (const item of items) {
561
+ if (await matches(item)) {
562
+ return true;
563
+ }
564
+ }
565
+ return false;
566
+ }
567
+
568
+ /**
569
+ * An `aysnc` implementation of `Array.every()`. Returns as soon as a non-match is found.
570
+ * @param items The items to check.
571
+ * @param matches The async matcher function, expected to
572
+ * return Promise<boolean>: `true` for a matching item, `false` otherwise.
573
+ * @returns A `Promise<boolean>`, `true` if every item matches; `false` otherwise.
574
+ */
575
+ export async function asyncEvery(
576
+ items: Record<string, any>[],
577
+ matches: (item: Record<string, any>) => Promise<boolean>
578
+ ): Promise<boolean> {
579
+ for (const item of items) {
580
+ if (!(await matches(item))) {
581
+ return false;
582
+ }
583
+ }
584
+ return true;
585
+ }
586
+
587
+ /**
588
+ * An `async` implementation of `Array.filter()`. Returns after all items have been filtered.
589
+ * TODO: Return AsyncIterable.
590
+ * @param items The items to filter.
591
+ * @param matches The `async` matcher function, expected to
592
+ * return Promise<boolean>: `true` for a matching item, `false` otherwise.
593
+ * @returns A `Promise<T>` of matching items.
594
+ */
595
+ export async function asyncFilter<T>(
596
+ items: T[],
597
+ matches: (item: T) => Promise<boolean>
598
+ ): Promise<T[]> {
599
+ const results: T[] = [];
600
+ for (const item of items) {
601
+ if (await matches(item)) {
602
+ results.push(item);
603
+ }
604
+ }
605
+ return results;
606
+ }
607
+
650
608
  export const isAWSDate = (val: string): boolean => {
651
609
  return !!/^\d{4}-\d{2}-\d{2}(Z|[+-]\d{2}:\d{2}($|:\d{2}))?$/.exec(val);
652
610
  };
@@ -761,7 +719,7 @@ export class DeferredCallbackResolver {
761
719
  this.raceInFlight = false;
762
720
  this.limitPromise = new DeferredPromise();
763
721
 
764
- return winner;
722
+ return winner!;
765
723
  }
766
724
  }
767
725
 
@@ -811,7 +769,7 @@ export function mergePatches<T>(
811
769
  patches = p;
812
770
  }
813
771
  );
814
- return patches;
772
+ return patches!;
815
773
  }
816
774
 
817
775
  export const getStorename = (namespace: string, modelName: string) => {
@@ -987,14 +945,14 @@ export const establishRelationAndKeys = (
987
945
  typeof fieldAttribute.type === 'object' &&
988
946
  'model' in fieldAttribute.type
989
947
  ) {
990
- const connectionType = fieldAttribute.association.connectionType;
948
+ const connectionType = fieldAttribute.association!.connectionType;
991
949
  relationship[mKey].relationTypes.push({
992
950
  fieldName: fieldAttribute.name,
993
951
  modelName: fieldAttribute.type.model,
994
952
  relationType: connectionType,
995
- targetName: fieldAttribute.association['targetName'],
996
- targetNames: fieldAttribute.association['targetNames'],
997
- associatedWith: fieldAttribute.association['associatedWith'],
953
+ targetName: fieldAttribute.association!['targetName'],
954
+ targetNames: fieldAttribute.association!['targetNames'],
955
+ associatedWith: fieldAttribute.association!['associatedWith'],
998
956
  });
999
957
 
1000
958
  if (connectionType === 'BELONGS_TO') {
@@ -1130,7 +1088,7 @@ export const getIndexKeys = (
1130
1088
  namespace: SchemaNamespace,
1131
1089
  modelName: string
1132
1090
  ): string[] => {
1133
- const keyPath = namespace?.keys[modelName]?.primaryKey;
1091
+ const keyPath = namespace?.keys?.[modelName]?.primaryKey;
1134
1092
 
1135
1093
  if (keyPath) {
1136
1094
  return keyPath;