@aws-amplify/datastore 3.7.3 → 3.7.4-custom-pk.79
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +144 -17
- package/README.md +154 -0
- package/dist/aws-amplify-datastore.js +3344 -1405
- package/dist/aws-amplify-datastore.js.map +1 -1
- package/dist/aws-amplify-datastore.min.js +25 -95
- package/dist/aws-amplify-datastore.min.js.map +1 -1
- package/lib/authModeStrategies/multiAuthStrategy.d.ts +2 -2
- package/lib/authModeStrategies/multiAuthStrategy.js +32 -26
- package/lib/authModeStrategies/multiAuthStrategy.js.map +1 -1
- package/lib/datastore/datastore.d.ts +17 -16
- package/lib/datastore/datastore.js +250 -78
- package/lib/datastore/datastore.js.map +1 -1
- package/lib/index.d.ts +3 -19
- package/lib/predicates/index.d.ts +3 -2
- package/lib/predicates/index.js +12 -2
- package/lib/predicates/index.js.map +1 -1
- package/lib/storage/adapter/AsyncStorageAdapter.d.ts +6 -2
- package/lib/storage/adapter/AsyncStorageAdapter.js +140 -66
- package/lib/storage/adapter/AsyncStorageAdapter.js.map +1 -1
- package/lib/storage/adapter/AsyncStorageDatabase.d.ts +4 -4
- package/lib/storage/adapter/AsyncStorageDatabase.js +57 -27
- package/lib/storage/adapter/AsyncStorageDatabase.js.map +1 -1
- package/lib/storage/adapter/InMemoryStore.js +2 -2
- package/lib/storage/adapter/InMemoryStore.js.map +1 -1
- package/lib/storage/adapter/IndexedDBAdapter.d.ts +7 -2
- package/lib/storage/adapter/IndexedDBAdapter.js +460 -253
- package/lib/storage/adapter/IndexedDBAdapter.js.map +1 -1
- package/lib/storage/adapter/index.d.ts +1 -1
- package/lib/storage/storage.d.ts +3 -3
- package/lib/storage/storage.js +106 -28
- package/lib/storage/storage.js.map +1 -1
- package/lib/sync/index.d.ts +23 -7
- package/lib/sync/index.js +18 -17
- package/lib/sync/index.js.map +1 -1
- package/lib/sync/merger.d.ts +3 -3
- package/lib/sync/merger.js +8 -6
- package/lib/sync/merger.js.map +1 -1
- package/lib/sync/outbox.d.ts +2 -2
- package/lib/sync/outbox.js +12 -9
- package/lib/sync/outbox.js.map +1 -1
- package/lib/sync/processors/errorMaps.d.ts +17 -0
- package/lib/sync/processors/errorMaps.js +125 -0
- package/lib/sync/processors/errorMaps.js.map +1 -0
- package/lib/sync/processors/mutation.d.ts +22 -4
- package/lib/sync/processors/mutation.js +119 -51
- package/lib/sync/processors/mutation.js.map +1 -1
- package/lib/sync/processors/subscription.d.ts +4 -2
- package/lib/sync/processors/subscription.js +76 -41
- package/lib/sync/processors/subscription.js.map +1 -1
- package/lib/sync/processors/sync.d.ts +4 -2
- package/lib/sync/processors/sync.js +62 -27
- package/lib/sync/processors/sync.js.map +1 -1
- package/lib/sync/utils.d.ts +3 -2
- package/lib/sync/utils.js +54 -7
- package/lib/sync/utils.js.map +1 -1
- package/lib/types.d.ts +85 -33
- package/lib/types.js +31 -2
- package/lib/types.js.map +1 -1
- package/lib/util.d.ts +43 -33
- package/lib/util.js +161 -21
- package/lib/util.js.map +1 -1
- package/lib-esm/authModeStrategies/multiAuthStrategy.d.ts +2 -2
- package/lib-esm/authModeStrategies/multiAuthStrategy.js +32 -26
- package/lib-esm/authModeStrategies/multiAuthStrategy.js.map +1 -1
- package/lib-esm/datastore/datastore.d.ts +17 -16
- package/lib-esm/datastore/datastore.js +252 -80
- package/lib-esm/datastore/datastore.js.map +1 -1
- package/lib-esm/index.d.ts +3 -19
- package/lib-esm/predicates/index.d.ts +3 -2
- package/lib-esm/predicates/index.js +13 -3
- package/lib-esm/predicates/index.js.map +1 -1
- package/lib-esm/storage/adapter/AsyncStorageAdapter.d.ts +6 -2
- package/lib-esm/storage/adapter/AsyncStorageAdapter.js +140 -66
- package/lib-esm/storage/adapter/AsyncStorageAdapter.js.map +1 -1
- package/lib-esm/storage/adapter/AsyncStorageDatabase.d.ts +4 -4
- package/lib-esm/storage/adapter/AsyncStorageDatabase.js +57 -27
- package/lib-esm/storage/adapter/AsyncStorageDatabase.js.map +1 -1
- package/lib-esm/storage/adapter/InMemoryStore.js +2 -2
- package/lib-esm/storage/adapter/InMemoryStore.js.map +1 -1
- package/lib-esm/storage/adapter/IndexedDBAdapter.d.ts +7 -2
- package/lib-esm/storage/adapter/IndexedDBAdapter.js +460 -253
- package/lib-esm/storage/adapter/IndexedDBAdapter.js.map +1 -1
- package/lib-esm/storage/adapter/index.d.ts +1 -1
- package/lib-esm/storage/storage.d.ts +3 -3
- package/lib-esm/storage/storage.js +106 -28
- package/lib-esm/storage/storage.js.map +1 -1
- package/lib-esm/sync/index.d.ts +23 -7
- package/lib-esm/sync/index.js +20 -19
- package/lib-esm/sync/index.js.map +1 -1
- package/lib-esm/sync/merger.d.ts +3 -3
- package/lib-esm/sync/merger.js +8 -6
- package/lib-esm/sync/merger.js.map +1 -1
- package/lib-esm/sync/outbox.d.ts +2 -2
- package/lib-esm/sync/outbox.js +13 -10
- package/lib-esm/sync/outbox.js.map +1 -1
- package/lib-esm/sync/processors/errorMaps.d.ts +17 -0
- package/lib-esm/sync/processors/errorMaps.js +119 -0
- package/lib-esm/sync/processors/errorMaps.js.map +1 -0
- package/lib-esm/sync/processors/mutation.d.ts +22 -4
- package/lib-esm/sync/processors/mutation.js +122 -54
- package/lib-esm/sync/processors/mutation.js.map +1 -1
- package/lib-esm/sync/processors/subscription.d.ts +4 -2
- package/lib-esm/sync/processors/subscription.js +77 -42
- package/lib-esm/sync/processors/subscription.js.map +1 -1
- package/lib-esm/sync/processors/sync.d.ts +4 -2
- package/lib-esm/sync/processors/sync.js +62 -27
- package/lib-esm/sync/processors/sync.js.map +1 -1
- package/lib-esm/sync/utils.d.ts +3 -2
- package/lib-esm/sync/utils.js +54 -8
- package/lib-esm/sync/utils.js.map +1 -1
- package/lib-esm/types.d.ts +85 -33
- package/lib-esm/types.js +29 -3
- package/lib-esm/types.js.map +1 -1
- package/lib-esm/util.d.ts +43 -33
- package/lib-esm/util.js +151 -18
- package/lib-esm/util.js.map +1 -1
- package/package.json +10 -9
- package/src/authModeStrategies/multiAuthStrategy.ts +24 -21
- package/src/datastore/datastore.ts +396 -143
- package/src/predicates/index.ts +32 -10
- package/src/storage/adapter/AsyncStorageAdapter.ts +161 -61
- package/src/storage/adapter/AsyncStorageDatabase.ts +62 -25
- package/src/storage/adapter/InMemoryStore.ts +2 -2
- package/src/storage/adapter/IndexedDBAdapter.ts +355 -101
- package/src/storage/adapter/index.ts +1 -1
- package/src/storage/storage.ts +85 -24
- package/src/sync/index.ts +74 -58
- package/src/sync/merger.ts +16 -4
- package/src/sync/outbox.ts +22 -8
- package/src/sync/processors/errorMaps.ts +93 -0
- package/src/sync/processors/mutation.ts +143 -84
- package/src/sync/processors/subscription.ts +67 -36
- package/src/sync/processors/sync.ts +37 -12
- package/src/sync/utils.ts +63 -15
- package/src/types.ts +242 -49
- package/src/util.ts +212 -35
- package/ssr/package.json +1 -1
|
@@ -8,6 +8,9 @@ import {
|
|
|
8
8
|
PredicatesGroup,
|
|
9
9
|
GraphQLFilter,
|
|
10
10
|
AuthModeStrategy,
|
|
11
|
+
ErrorHandler,
|
|
12
|
+
ProcessName,
|
|
13
|
+
AmplifyContext,
|
|
11
14
|
} from '../../types';
|
|
12
15
|
import {
|
|
13
16
|
buildGraphQLOperation,
|
|
@@ -17,6 +20,7 @@ import {
|
|
|
17
20
|
predicateToGraphQLFilter,
|
|
18
21
|
getTokenForCustomAuth,
|
|
19
22
|
} from '../utils';
|
|
23
|
+
import { USER_AGENT_SUFFIX_DATASTORE } from '../../util';
|
|
20
24
|
import {
|
|
21
25
|
jitteredExponentialRetry,
|
|
22
26
|
ConsoleLogger as Logger,
|
|
@@ -24,7 +28,7 @@ import {
|
|
|
24
28
|
NonRetryableError,
|
|
25
29
|
} from '@aws-amplify/core';
|
|
26
30
|
import { ModelPredicateCreator } from '../../predicates';
|
|
27
|
-
|
|
31
|
+
import { getSyncErrorType } from './errorMaps';
|
|
28
32
|
const opResultDefaults = {
|
|
29
33
|
items: [],
|
|
30
34
|
nextToken: null,
|
|
@@ -40,8 +44,11 @@ class SyncProcessor {
|
|
|
40
44
|
private readonly schema: InternalSchema,
|
|
41
45
|
private readonly syncPredicates: WeakMap<SchemaModel, ModelPredicate<any>>,
|
|
42
46
|
private readonly amplifyConfig: Record<string, any> = {},
|
|
43
|
-
private readonly authModeStrategy: AuthModeStrategy
|
|
47
|
+
private readonly authModeStrategy: AuthModeStrategy,
|
|
48
|
+
private readonly errorHandler: ErrorHandler,
|
|
49
|
+
private readonly amplifyContext: AmplifyContext
|
|
44
50
|
) {
|
|
51
|
+
amplifyContext.API = amplifyContext.API || API;
|
|
45
52
|
this.generateQueries();
|
|
46
53
|
}
|
|
47
54
|
|
|
@@ -65,10 +72,11 @@ class SyncProcessor {
|
|
|
65
72
|
if (!this.syncPredicates) {
|
|
66
73
|
return null;
|
|
67
74
|
}
|
|
68
|
-
const predicatesGroup: PredicatesGroup<any> =
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
75
|
+
const predicatesGroup: PredicatesGroup<any> =
|
|
76
|
+
ModelPredicateCreator.getPredicates(
|
|
77
|
+
this.syncPredicates.get(model),
|
|
78
|
+
false
|
|
79
|
+
);
|
|
72
80
|
|
|
73
81
|
if (!predicatesGroup) {
|
|
74
82
|
return null;
|
|
@@ -77,9 +85,7 @@ class SyncProcessor {
|
|
|
77
85
|
return predicateToGraphQLFilter(predicatesGroup);
|
|
78
86
|
}
|
|
79
87
|
|
|
80
|
-
private async retrievePage<
|
|
81
|
-
T extends ModelInstanceMetadata = ModelInstanceMetadata
|
|
82
|
-
>(
|
|
88
|
+
private async retrievePage<T extends ModelInstanceMetadata>(
|
|
83
89
|
modelDefinition: SchemaModel,
|
|
84
90
|
lastSync: number,
|
|
85
91
|
nextToken: string,
|
|
@@ -202,11 +208,12 @@ class SyncProcessor {
|
|
|
202
208
|
this.amplifyConfig
|
|
203
209
|
);
|
|
204
210
|
|
|
205
|
-
return await API.graphql({
|
|
211
|
+
return await this.amplifyContext.API.graphql({
|
|
206
212
|
query,
|
|
207
213
|
variables,
|
|
208
214
|
authMode,
|
|
209
215
|
authToken,
|
|
216
|
+
userAgentSuffix: USER_AGENT_SUFFIX_DATASTORE,
|
|
210
217
|
});
|
|
211
218
|
} catch (error) {
|
|
212
219
|
// Catch client-side (GraphQLAuthError) & 401/403 errors here so that we don't continue to retry
|
|
@@ -222,15 +229,33 @@ class SyncProcessor {
|
|
|
222
229
|
error.data[opName] &&
|
|
223
230
|
error.data[opName].items
|
|
224
231
|
);
|
|
225
|
-
|
|
226
232
|
if (this.partialDataFeatureFlagEnabled()) {
|
|
227
233
|
if (hasItems) {
|
|
228
234
|
const result = error;
|
|
229
235
|
result.data[opName].items = result.data[opName].items.filter(
|
|
230
236
|
item => item !== null
|
|
231
237
|
);
|
|
232
|
-
|
|
233
238
|
if (error.errors) {
|
|
239
|
+
await Promise.all(
|
|
240
|
+
error.errors.map(async err => {
|
|
241
|
+
try {
|
|
242
|
+
await this.errorHandler({
|
|
243
|
+
recoverySuggestion:
|
|
244
|
+
'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',
|
|
245
|
+
localModel: null,
|
|
246
|
+
message: err.message,
|
|
247
|
+
model: modelDefinition.name,
|
|
248
|
+
operation: opName,
|
|
249
|
+
errorType: getSyncErrorType(err),
|
|
250
|
+
process: ProcessName.sync,
|
|
251
|
+
remoteModel: null,
|
|
252
|
+
cause: err,
|
|
253
|
+
});
|
|
254
|
+
} catch (e) {
|
|
255
|
+
logger.error('Sync error handler failed with:', e);
|
|
256
|
+
}
|
|
257
|
+
})
|
|
258
|
+
);
|
|
234
259
|
Hub.dispatch('datastore', {
|
|
235
260
|
event: 'syncQueriesPartialSyncError',
|
|
236
261
|
data: {
|
package/src/sync/utils.ts
CHANGED
|
@@ -27,7 +27,11 @@ import {
|
|
|
27
27
|
InternalSchema,
|
|
28
28
|
AuthModeStrategy,
|
|
29
29
|
} from '../types';
|
|
30
|
-
import {
|
|
30
|
+
import {
|
|
31
|
+
exhaustiveCheck,
|
|
32
|
+
extractPrimaryKeyFieldNames,
|
|
33
|
+
establishRelationAndKeys,
|
|
34
|
+
} from '../util';
|
|
31
35
|
import { MutationEvent } from './';
|
|
32
36
|
|
|
33
37
|
const logger = new Logger('DataStore');
|
|
@@ -47,7 +51,7 @@ export enum TransformerMutationType {
|
|
|
47
51
|
GET = 'Get',
|
|
48
52
|
}
|
|
49
53
|
|
|
50
|
-
const dummyMetadata:
|
|
54
|
+
const dummyMetadata: ModelInstanceMetadata = {
|
|
51
55
|
_version: undefined,
|
|
52
56
|
_lastChangedAt: undefined,
|
|
53
57
|
_deleted: undefined,
|
|
@@ -79,7 +83,7 @@ export function generateSelectionSet(
|
|
|
79
83
|
if (isSchemaModel(modelDefinition)) {
|
|
80
84
|
scalarAndMetadataFields = scalarAndMetadataFields
|
|
81
85
|
.concat(getMetadataFields())
|
|
82
|
-
.concat(getConnectionFields(modelDefinition));
|
|
86
|
+
.concat(getConnectionFields(modelDefinition, namespace));
|
|
83
87
|
}
|
|
84
88
|
|
|
85
89
|
const result = scalarAndMetadataFields.join('\n');
|
|
@@ -138,7 +142,11 @@ function getScalarFields(
|
|
|
138
142
|
return result;
|
|
139
143
|
}
|
|
140
144
|
|
|
141
|
-
|
|
145
|
+
// Used for generating the selection set for queries and mutations
|
|
146
|
+
function getConnectionFields(
|
|
147
|
+
modelDefinition: SchemaModel,
|
|
148
|
+
namespace: SchemaNamespace
|
|
149
|
+
): string[] {
|
|
142
150
|
const result = [];
|
|
143
151
|
|
|
144
152
|
Object.values(modelDefinition.fields)
|
|
@@ -153,7 +161,23 @@ function getConnectionFields(modelDefinition: SchemaModel): string[] {
|
|
|
153
161
|
break;
|
|
154
162
|
case 'BELONGS_TO':
|
|
155
163
|
if (isTargetNameAssociation(association)) {
|
|
156
|
-
|
|
164
|
+
// New codegen (CPK)
|
|
165
|
+
if (association.targetNames && association.targetNames.length > 0) {
|
|
166
|
+
// Need to retrieve relations in order to get connected model keys
|
|
167
|
+
const [relations] = establishRelationAndKeys(namespace);
|
|
168
|
+
|
|
169
|
+
const connectedModelName =
|
|
170
|
+
modelDefinition.fields[name].type['model'];
|
|
171
|
+
|
|
172
|
+
// keyFields are fields of the connected model
|
|
173
|
+
const keyFields = relations[connectedModelName].indexes;
|
|
174
|
+
|
|
175
|
+
// We rely on `_deleted` when we process the sync query (e.g. in batchSave in the adapters)
|
|
176
|
+
result.push(`${name} { ${keyFields} _deleted }`);
|
|
177
|
+
} else {
|
|
178
|
+
// backwards-compatability for schema generated prior to custom primary key support
|
|
179
|
+
result.push(`${name} { id _deleted }`);
|
|
180
|
+
}
|
|
157
181
|
}
|
|
158
182
|
break;
|
|
159
183
|
default:
|
|
@@ -412,10 +436,13 @@ export function createMutationInstanceFromModelOperation<
|
|
|
412
436
|
return v;
|
|
413
437
|
};
|
|
414
438
|
|
|
439
|
+
const modelId = getIdentifierValue(modelDefinition, element);
|
|
440
|
+
const optionalId = OpType.INSERT && id ? { id } : {};
|
|
441
|
+
|
|
415
442
|
const mutationEvent = modelInstanceCreator(MutationEventConstructor, {
|
|
416
|
-
...
|
|
443
|
+
...optionalId,
|
|
417
444
|
data: JSON.stringify(element, replacer),
|
|
418
|
-
modelId
|
|
445
|
+
modelId,
|
|
419
446
|
model: model.name,
|
|
420
447
|
operation,
|
|
421
448
|
condition: JSON.stringify(condition),
|
|
@@ -425,7 +452,8 @@ export function createMutationInstanceFromModelOperation<
|
|
|
425
452
|
}
|
|
426
453
|
|
|
427
454
|
export function predicateToGraphQLCondition(
|
|
428
|
-
predicate: PredicatesGroup<any
|
|
455
|
+
predicate: PredicatesGroup<any>,
|
|
456
|
+
modelDefinition: SchemaModel
|
|
429
457
|
): GraphQLCondition {
|
|
430
458
|
const result = {};
|
|
431
459
|
|
|
@@ -433,17 +461,27 @@ export function predicateToGraphQLCondition(
|
|
|
433
461
|
return result;
|
|
434
462
|
}
|
|
435
463
|
|
|
464
|
+
const keyFields = extractPrimaryKeyFieldNames(modelDefinition);
|
|
465
|
+
|
|
436
466
|
predicate.predicates.forEach(p => {
|
|
437
467
|
if (isPredicateObj(p)) {
|
|
438
468
|
const { field, operator, operand } = p;
|
|
439
469
|
|
|
440
|
-
|
|
470
|
+
// This is compatible with how the GQL Transform currently generates the Condition Input,
|
|
471
|
+
// i.e. any PK and SK fields are omitted and can't be used as conditions.
|
|
472
|
+
// However, I think this limits usability.
|
|
473
|
+
// What if we want to delete all records where SK > some value
|
|
474
|
+
// Or all records where PK = some value but SKs are different values
|
|
475
|
+
|
|
476
|
+
// TODO: if the Transform gets updated ^ we'll need to modify this logic to only omit
|
|
477
|
+
// key fields from the predicate/condition when ALL of the keyFields are present and using `eq` operators
|
|
478
|
+
if (keyFields.includes(field as string)) {
|
|
441
479
|
return;
|
|
442
480
|
}
|
|
443
481
|
|
|
444
482
|
result[field] = { [operator]: operand };
|
|
445
483
|
} else {
|
|
446
|
-
result[p.type] = predicateToGraphQLCondition(p);
|
|
484
|
+
result[p.type] = predicateToGraphQLCondition(p, modelDefinition);
|
|
447
485
|
}
|
|
448
486
|
});
|
|
449
487
|
|
|
@@ -515,11 +553,9 @@ export async function getModelAuthModes({
|
|
|
515
553
|
defaultAuthMode: GRAPHQL_AUTH_MODE;
|
|
516
554
|
modelName: string;
|
|
517
555
|
schema: InternalSchema;
|
|
518
|
-
}): Promise<
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
}
|
|
522
|
-
> {
|
|
556
|
+
}): Promise<{
|
|
557
|
+
[key in ModelOperation]: GRAPHQL_AUTH_MODE[];
|
|
558
|
+
}> {
|
|
523
559
|
const operations = Object.values(ModelOperation);
|
|
524
560
|
|
|
525
561
|
const modelAuthModes: {
|
|
@@ -612,3 +648,15 @@ export async function getTokenForCustomAuth(
|
|
|
612
648
|
}
|
|
613
649
|
}
|
|
614
650
|
}
|
|
651
|
+
|
|
652
|
+
// Util that takes a modelDefinition and model and returns either the id value(s) or the custom primary key value(s)
|
|
653
|
+
export function getIdentifierValue(
|
|
654
|
+
modelDefinition: SchemaModel,
|
|
655
|
+
model: ModelInstanceMetadata | PersistentModel
|
|
656
|
+
): string {
|
|
657
|
+
const pkFieldNames = extractPrimaryKeyFieldNames(modelDefinition);
|
|
658
|
+
|
|
659
|
+
const idOrPk = pkFieldNames.map(f => model[f]).join('-');
|
|
660
|
+
|
|
661
|
+
return idOrPk;
|
|
662
|
+
}
|