@aws-amplify/datastore 4.7.6-api-v6-models.b3abc9b.0 → 5.0.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.
- package/README.md +4 -0
- package/lib/authModeStrategies/defaultAuthStrategy.js +3 -2
- package/lib/authModeStrategies/index.js +3 -3
- package/lib/authModeStrategies/multiAuthStrategy.js +38 -53
- package/lib/datastore/datastore.d.ts +4 -5
- package/lib/datastore/datastore.js +929 -1284
- package/lib/index.d.ts +1 -1
- package/lib/index.js +26 -13
- package/lib/predicates/index.js +54 -69
- package/lib/predicates/next.d.ts +2 -2
- package/lib/predicates/next.js +313 -462
- package/lib/predicates/sort.js +24 -28
- package/lib/ssr/index.js +2 -2
- package/lib/storage/adapter/AsyncStorageAdapter.js +120 -342
- package/lib/storage/adapter/AsyncStorageDatabase.js +217 -421
- package/lib/storage/adapter/InMemoryStore.js +28 -51
- package/lib/storage/adapter/InMemoryStore.native.js +5 -3
- package/lib/storage/adapter/IndexedDBAdapter.js +466 -871
- package/lib/storage/adapter/StorageAdapterBase.js +180 -330
- package/lib/storage/adapter/getDefaultAdapter/index.js +8 -10
- package/lib/storage/adapter/getDefaultAdapter/index.native.js +5 -4
- package/lib/storage/adapter/index.js +0 -1
- package/lib/storage/relationship.js +177 -253
- package/lib/storage/storage.d.ts +4 -4
- package/lib/storage/storage.js +255 -433
- package/lib/sync/datastoreConnectivity.d.ts +2 -2
- package/lib/sync/datastoreConnectivity.js +29 -39
- package/lib/sync/datastoreReachability/index.d.ts +1 -3
- package/lib/sync/datastoreReachability/index.js +3 -3
- package/lib/sync/datastoreReachability/index.native.d.ts +1 -3
- package/lib/sync/datastoreReachability/index.native.js +4 -5
- package/lib/sync/index.d.ts +2 -2
- package/lib/sync/index.js +522 -827
- package/lib/sync/merger.js +31 -63
- package/lib/sync/outbox.js +148 -232
- package/lib/sync/processors/errorMaps.d.ts +1 -1
- package/lib/sync/processors/errorMaps.js +30 -47
- package/lib/sync/processors/mutation.d.ts +2 -2
- package/lib/sync/processors/mutation.js +343 -502
- package/lib/sync/processors/subscription.d.ts +5 -2
- package/lib/sync/processors/subscription.js +283 -437
- package/lib/sync/processors/sync.d.ts +2 -2
- package/lib/sync/processors/sync.js +279 -404
- package/lib/sync/utils.d.ts +5 -4
- package/lib/sync/utils.js +267 -320
- package/lib/tsconfig.tsbuildinfo +1 -0
- package/lib/types.d.ts +138 -140
- package/lib/types.js +17 -24
- package/lib/util.d.ts +9 -17
- package/lib/util.js +387 -511
- package/lib-esm/authModeStrategies/defaultAuthStrategy.js +1 -2
- package/lib-esm/authModeStrategies/index.js +0 -1
- package/lib-esm/authModeStrategies/multiAuthStrategy.js +35 -52
- package/lib-esm/datastore/datastore.d.ts +4 -5
- package/lib-esm/datastore/datastore.js +888 -1247
- package/lib-esm/index.d.ts +1 -1
- package/lib-esm/index.js +6 -7
- package/lib-esm/predicates/index.js +53 -70
- package/lib-esm/predicates/next.d.ts +2 -2
- package/lib-esm/predicates/next.js +306 -459
- package/lib-esm/predicates/sort.js +23 -28
- package/lib-esm/ssr/index.js +1 -2
- package/lib-esm/storage/adapter/AsyncStorageAdapter.js +111 -338
- package/lib-esm/storage/adapter/AsyncStorageDatabase.js +212 -416
- package/lib-esm/storage/adapter/InMemoryStore.js +27 -52
- package/lib-esm/storage/adapter/InMemoryStore.native.js +0 -1
- package/lib-esm/storage/adapter/IndexedDBAdapter.js +438 -866
- package/lib-esm/storage/adapter/StorageAdapterBase.js +173 -325
- package/lib-esm/storage/adapter/getDefaultAdapter/index.js +2 -6
- package/lib-esm/storage/adapter/getDefaultAdapter/index.native.js +1 -2
- package/lib-esm/storage/adapter/index.js +1 -1
- package/lib-esm/storage/relationship.js +173 -251
- package/lib-esm/storage/storage.d.ts +4 -4
- package/lib-esm/storage/storage.js +242 -424
- package/lib-esm/sync/datastoreConnectivity.d.ts +2 -2
- package/lib-esm/sync/datastoreConnectivity.js +28 -39
- package/lib-esm/sync/datastoreReachability/index.d.ts +1 -3
- package/lib-esm/sync/datastoreReachability/index.js +2 -3
- package/lib-esm/sync/datastoreReachability/index.native.d.ts +1 -3
- package/lib-esm/sync/datastoreReachability/index.native.js +3 -4
- package/lib-esm/sync/index.d.ts +2 -2
- package/lib-esm/sync/index.js +502 -812
- package/lib-esm/sync/merger.js +28 -61
- package/lib-esm/sync/outbox.js +143 -228
- package/lib-esm/sync/processors/errorMaps.d.ts +1 -1
- package/lib-esm/sync/processors/errorMaps.js +32 -50
- package/lib-esm/sync/processors/mutation.d.ts +2 -2
- package/lib-esm/sync/processors/mutation.js +329 -490
- package/lib-esm/sync/processors/subscription.d.ts +5 -2
- package/lib-esm/sync/processors/subscription.js +266 -421
- package/lib-esm/sync/processors/sync.d.ts +2 -2
- package/lib-esm/sync/processors/sync.js +271 -397
- package/lib-esm/sync/utils.d.ts +5 -4
- package/lib-esm/sync/utils.js +252 -307
- package/lib-esm/tsconfig.tsbuildinfo +1 -0
- package/lib-esm/types.d.ts +138 -140
- package/lib-esm/types.js +16 -25
- package/lib-esm/util.d.ts +9 -17
- package/lib-esm/util.js +335 -497
- package/package.json +31 -26
- package/src/authModeStrategies/multiAuthStrategy.ts +15 -12
- package/src/datastore/datastore.ts +36 -35
- package/src/predicates/sort.ts +3 -1
- package/src/storage/adapter/InMemoryStore.ts +1 -1
- package/src/storage/adapter/IndexedDBAdapter.ts +2 -2
- package/src/storage/adapter/StorageAdapterBase.ts +2 -2
- package/src/storage/adapter/getDefaultAdapter/index.ts +1 -4
- package/src/storage/storage.ts +29 -24
- package/src/sync/datastoreConnectivity.ts +6 -6
- package/src/sync/datastoreReachability/index.native.ts +5 -3
- package/src/sync/datastoreReachability/index.ts +1 -1
- package/src/sync/index.ts +79 -89
- package/src/sync/processors/errorMaps.ts +7 -7
- package/src/sync/processors/mutation.ts +19 -13
- package/src/sync/processors/subscription.ts +221 -295
- package/src/sync/processors/sync.ts +11 -8
- package/src/sync/utils.ts +30 -15
- package/src/types.ts +4 -8
- package/src/util.ts +46 -9
- package/lib/.tsbuildinfo +0 -3
- package/lib/authModeStrategies/defaultAuthStrategy.js.map +0 -1
- package/lib/authModeStrategies/index.js.map +0 -1
- package/lib/authModeStrategies/multiAuthStrategy.js.map +0 -1
- package/lib/datastore/datastore.js.map +0 -1
- package/lib/index.js.map +0 -1
- package/lib/predicates/index.js.map +0 -1
- package/lib/predicates/next.js.map +0 -1
- package/lib/predicates/sort.js.map +0 -1
- package/lib/ssr/index.js.map +0 -1
- package/lib/storage/adapter/AsyncStorageAdapter.js.map +0 -1
- package/lib/storage/adapter/AsyncStorageDatabase.js.map +0 -1
- package/lib/storage/adapter/InMemoryStore.js.map +0 -1
- package/lib/storage/adapter/InMemoryStore.native.js.map +0 -1
- package/lib/storage/adapter/IndexedDBAdapter.js.map +0 -1
- package/lib/storage/adapter/StorageAdapterBase.js.map +0 -1
- package/lib/storage/adapter/getDefaultAdapter/index.js.map +0 -1
- package/lib/storage/adapter/getDefaultAdapter/index.native.js.map +0 -1
- package/lib/storage/adapter/index.js.map +0 -1
- package/lib/storage/relationship.js.map +0 -1
- package/lib/storage/storage.js.map +0 -1
- package/lib/sync/datastoreConnectivity.js.map +0 -1
- package/lib/sync/datastoreReachability/index.js.map +0 -1
- package/lib/sync/datastoreReachability/index.native.js.map +0 -1
- package/lib/sync/index.js.map +0 -1
- package/lib/sync/merger.js.map +0 -1
- package/lib/sync/outbox.js.map +0 -1
- package/lib/sync/processors/errorMaps.js.map +0 -1
- package/lib/sync/processors/mutation.js.map +0 -1
- package/lib/sync/processors/subscription.js.map +0 -1
- package/lib/sync/processors/sync.js.map +0 -1
- package/lib/sync/utils.js.map +0 -1
- package/lib/types.js.map +0 -1
- package/lib/util.js.map +0 -1
- package/lib-esm/.tsbuildinfo +0 -3
- package/lib-esm/authModeStrategies/defaultAuthStrategy.js.map +0 -1
- package/lib-esm/authModeStrategies/index.js.map +0 -1
- package/lib-esm/authModeStrategies/multiAuthStrategy.js.map +0 -1
- package/lib-esm/datastore/datastore.js.map +0 -1
- package/lib-esm/index.js.map +0 -1
- package/lib-esm/predicates/index.js.map +0 -1
- package/lib-esm/predicates/next.js.map +0 -1
- package/lib-esm/predicates/sort.js.map +0 -1
- package/lib-esm/ssr/index.js.map +0 -1
- package/lib-esm/storage/adapter/AsyncStorageAdapter.js.map +0 -1
- package/lib-esm/storage/adapter/AsyncStorageDatabase.js.map +0 -1
- package/lib-esm/storage/adapter/InMemoryStore.js.map +0 -1
- package/lib-esm/storage/adapter/InMemoryStore.native.js.map +0 -1
- package/lib-esm/storage/adapter/IndexedDBAdapter.js.map +0 -1
- package/lib-esm/storage/adapter/StorageAdapterBase.js.map +0 -1
- package/lib-esm/storage/adapter/getDefaultAdapter/index.js.map +0 -1
- package/lib-esm/storage/adapter/getDefaultAdapter/index.native.js.map +0 -1
- package/lib-esm/storage/adapter/index.js.map +0 -1
- package/lib-esm/storage/relationship.js.map +0 -1
- package/lib-esm/storage/storage.js.map +0 -1
- package/lib-esm/sync/datastoreConnectivity.js.map +0 -1
- package/lib-esm/sync/datastoreReachability/index.js.map +0 -1
- package/lib-esm/sync/datastoreReachability/index.native.js.map +0 -1
- package/lib-esm/sync/index.js.map +0 -1
- package/lib-esm/sync/merger.js.map +0 -1
- package/lib-esm/sync/outbox.js.map +0 -1
- package/lib-esm/sync/processors/errorMaps.js.map +0 -1
- package/lib-esm/sync/processors/mutation.js.map +0 -1
- package/lib-esm/sync/processors/subscription.js.map +0 -1
- package/lib-esm/sync/processors/sync.js.map +0 -1
- package/lib-esm/sync/utils.js.map +0 -1
- package/lib-esm/types.js.map +0 -1
- package/lib-esm/util.js.map +0 -1
|
@@ -1,16 +1,15 @@
|
|
|
1
|
-
import { __assign, __awaiter, __generator, __read, __rest, __values } from "tslib";
|
|
2
1
|
import { InternalAPI } from '@aws-amplify/api/internals';
|
|
3
|
-
import { Category,
|
|
4
|
-
import Observable from '
|
|
2
|
+
import { Category, DataStoreAction, jitteredBackoff, NonRetryableError, retry, BackgroundProcessManager, } from '@aws-amplify/core/internals/utils';
|
|
3
|
+
import { Observable } from 'rxjs';
|
|
5
4
|
import { DISCARD, isModelFieldType, isTargetNameAssociation, OpType, ProcessName, } from '../../types';
|
|
6
5
|
import { extractTargetNamesFromSrc, USER, ID } from '../../util';
|
|
7
6
|
import { buildGraphQLOperation, createMutationInstanceFromModelOperation, getModelAuthModes, TransformerMutationType, getTokenForCustomAuth, } from '../utils';
|
|
8
7
|
import { getMutationErrorType } from './errorMaps';
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
import { ConsoleLogger } from '@aws-amplify/core';
|
|
9
|
+
const MAX_ATTEMPTS = 10;
|
|
10
|
+
const logger = new ConsoleLogger('DataStore');
|
|
11
|
+
class MutationProcessor {
|
|
12
|
+
constructor(schema, storage, userClasses, outbox, modelInstanceCreator, MutationEvent, amplifyConfig = {}, authModeStrategy, errorHandler, conflictHandler, amplifyContext) {
|
|
14
13
|
this.schema = schema;
|
|
15
14
|
this.storage = storage;
|
|
16
15
|
this.userClasses = userClasses;
|
|
@@ -29,444 +28,299 @@ var MutationProcessor = /** @class */ (function () {
|
|
|
29
28
|
this.amplifyContext.InternalAPI || InternalAPI;
|
|
30
29
|
this.generateQueries();
|
|
31
30
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
Object.values(this.schema.namespaces).forEach(function (namespace) {
|
|
31
|
+
generateQueries() {
|
|
32
|
+
Object.values(this.schema.namespaces).forEach(namespace => {
|
|
35
33
|
Object.values(namespace.models)
|
|
36
|
-
.filter(
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
var _b = __read(buildGraphQLOperation(namespace, model, 'UPDATE'), 1), updateMutation = _b[0];
|
|
43
|
-
var _c = __read(buildGraphQLOperation(namespace, model, 'DELETE'), 1), deleteMutation = _c[0];
|
|
44
|
-
_this.typeQuery.set(model, [
|
|
34
|
+
.filter(({ syncable }) => syncable)
|
|
35
|
+
.forEach(model => {
|
|
36
|
+
const [createMutation] = buildGraphQLOperation(namespace, model, 'CREATE');
|
|
37
|
+
const [updateMutation] = buildGraphQLOperation(namespace, model, 'UPDATE');
|
|
38
|
+
const [deleteMutation] = buildGraphQLOperation(namespace, model, 'DELETE');
|
|
39
|
+
this.typeQuery.set(model, [
|
|
45
40
|
createMutation,
|
|
46
41
|
updateMutation,
|
|
47
42
|
deleteMutation,
|
|
48
43
|
]);
|
|
49
44
|
});
|
|
50
45
|
});
|
|
51
|
-
}
|
|
52
|
-
|
|
46
|
+
}
|
|
47
|
+
isReady() {
|
|
53
48
|
return this.observer !== undefined;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
var _this = this;
|
|
49
|
+
}
|
|
50
|
+
start() {
|
|
57
51
|
this.runningProcesses = new BackgroundProcessManager();
|
|
58
|
-
|
|
59
|
-
|
|
52
|
+
const observable = new Observable(observer => {
|
|
53
|
+
this.observer = observer;
|
|
60
54
|
try {
|
|
61
|
-
|
|
55
|
+
this.resume();
|
|
62
56
|
}
|
|
63
57
|
catch (error) {
|
|
64
58
|
logger.error('mutations processor start error', error);
|
|
65
59
|
throw error;
|
|
66
60
|
}
|
|
67
|
-
return
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
this.pause();
|
|
72
|
-
return [2 /*return*/];
|
|
73
|
-
});
|
|
74
|
-
}); });
|
|
75
|
-
});
|
|
76
|
-
return observable;
|
|
77
|
-
};
|
|
78
|
-
MutationProcessor.prototype.stop = function () {
|
|
79
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
80
|
-
return __generator(this, function (_a) {
|
|
81
|
-
switch (_a.label) {
|
|
82
|
-
case 0:
|
|
83
|
-
this.removeObserver();
|
|
84
|
-
return [4 /*yield*/, this.runningProcesses.close()];
|
|
85
|
-
case 1:
|
|
86
|
-
_a.sent();
|
|
87
|
-
return [4 /*yield*/, this.runningProcesses.open()];
|
|
88
|
-
case 2:
|
|
89
|
-
_a.sent();
|
|
90
|
-
return [2 /*return*/];
|
|
91
|
-
}
|
|
61
|
+
return this.runningProcesses.addCleaner(async () => {
|
|
62
|
+
// The observer has unsubscribed and/or `stop()` has been called.
|
|
63
|
+
this.removeObserver();
|
|
64
|
+
this.pause();
|
|
92
65
|
});
|
|
93
66
|
});
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
67
|
+
return observable;
|
|
68
|
+
}
|
|
69
|
+
async stop() {
|
|
70
|
+
this.removeObserver();
|
|
71
|
+
await this.runningProcesses.close();
|
|
72
|
+
await this.runningProcesses.open();
|
|
73
|
+
}
|
|
74
|
+
removeObserver() {
|
|
75
|
+
this.observer?.complete?.();
|
|
98
76
|
this.observer = undefined;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
var head, namespaceName, _loop_1, this_1, _a;
|
|
108
|
-
var _this = this;
|
|
109
|
-
var _b, _c;
|
|
110
|
-
return __generator(this, function (_d) {
|
|
111
|
-
switch (_d.label) {
|
|
112
|
-
case 0:
|
|
113
|
-
if (this.processing ||
|
|
114
|
-
!this.isReady() ||
|
|
115
|
-
!this.runningProcesses.isOpen) {
|
|
116
|
-
return [2 /*return*/];
|
|
117
|
-
}
|
|
118
|
-
this.processing = true;
|
|
119
|
-
namespaceName = USER;
|
|
120
|
-
_loop_1 = function () {
|
|
121
|
-
var model, operation, data, condition, modelConstructor, result, opName, modelDefinition, modelAuthModes, operationAuthModes_1, authModeAttempts_1, authModeRetry_1, error_1, record, hasMore;
|
|
122
|
-
var _a;
|
|
123
|
-
return __generator(this, function (_b) {
|
|
124
|
-
switch (_b.label) {
|
|
125
|
-
case 0:
|
|
126
|
-
model = head.model, operation = head.operation, data = head.data, condition = head.condition;
|
|
127
|
-
modelConstructor = this_1.userClasses[model];
|
|
128
|
-
result = undefined;
|
|
129
|
-
opName = undefined;
|
|
130
|
-
modelDefinition = undefined;
|
|
131
|
-
_b.label = 1;
|
|
132
|
-
case 1:
|
|
133
|
-
_b.trys.push([1, 4, , 5]);
|
|
134
|
-
return [4 /*yield*/, getModelAuthModes({
|
|
135
|
-
authModeStrategy: this_1.authModeStrategy,
|
|
136
|
-
defaultAuthMode: this_1.amplifyConfig.aws_appsync_authenticationType,
|
|
137
|
-
modelName: model,
|
|
138
|
-
schema: this_1.schema,
|
|
139
|
-
})];
|
|
140
|
-
case 2:
|
|
141
|
-
modelAuthModes = _b.sent();
|
|
142
|
-
operationAuthModes_1 = modelAuthModes[operation.toUpperCase()];
|
|
143
|
-
authModeAttempts_1 = 0;
|
|
144
|
-
authModeRetry_1 = function () { return __awaiter(_this, void 0, void 0, function () {
|
|
145
|
-
var response, error_2, e_1;
|
|
146
|
-
return __generator(this, function (_a) {
|
|
147
|
-
switch (_a.label) {
|
|
148
|
-
case 0:
|
|
149
|
-
_a.trys.push([0, 2, , 9]);
|
|
150
|
-
logger.debug("Attempting mutation with authMode: " + operationAuthModes_1[authModeAttempts_1]);
|
|
151
|
-
return [4 /*yield*/, this.jitteredRetry(namespaceName, model, operation, data, condition, modelConstructor, this.MutationEvent, head, operationAuthModes_1[authModeAttempts_1], onTerminate)];
|
|
152
|
-
case 1:
|
|
153
|
-
response = _a.sent();
|
|
154
|
-
logger.debug("Mutation sent successfully with authMode: " + operationAuthModes_1[authModeAttempts_1]);
|
|
155
|
-
return [2 /*return*/, response];
|
|
156
|
-
case 2:
|
|
157
|
-
error_2 = _a.sent();
|
|
158
|
-
authModeAttempts_1++;
|
|
159
|
-
if (!(authModeAttempts_1 >= operationAuthModes_1.length)) return [3 /*break*/, 7];
|
|
160
|
-
logger.debug("Mutation failed with authMode: " + operationAuthModes_1[authModeAttempts_1 - 1]);
|
|
161
|
-
_a.label = 3;
|
|
162
|
-
case 3:
|
|
163
|
-
_a.trys.push([3, 5, , 6]);
|
|
164
|
-
return [4 /*yield*/, this.errorHandler({
|
|
165
|
-
recoverySuggestion: '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',
|
|
166
|
-
localModel: null,
|
|
167
|
-
message: error_2.message,
|
|
168
|
-
model: modelConstructor.name,
|
|
169
|
-
operation: opName,
|
|
170
|
-
errorType: getMutationErrorType(error_2),
|
|
171
|
-
process: ProcessName.sync,
|
|
172
|
-
remoteModel: null,
|
|
173
|
-
cause: error_2,
|
|
174
|
-
})];
|
|
175
|
-
case 4:
|
|
176
|
-
_a.sent();
|
|
177
|
-
return [3 /*break*/, 6];
|
|
178
|
-
case 5:
|
|
179
|
-
e_1 = _a.sent();
|
|
180
|
-
logger.error('Mutation error handler failed with:', e_1);
|
|
181
|
-
return [3 /*break*/, 6];
|
|
182
|
-
case 6: throw error_2;
|
|
183
|
-
case 7:
|
|
184
|
-
logger.debug("Mutation failed with authMode: " + operationAuthModes_1[authModeAttempts_1 - 1] + ". Retrying with authMode: " + operationAuthModes_1[authModeAttempts_1]);
|
|
185
|
-
return [4 /*yield*/, authModeRetry_1()];
|
|
186
|
-
case 8: return [2 /*return*/, _a.sent()];
|
|
187
|
-
case 9: return [2 /*return*/];
|
|
188
|
-
}
|
|
189
|
-
});
|
|
190
|
-
}); };
|
|
191
|
-
return [4 /*yield*/, authModeRetry_1()];
|
|
192
|
-
case 3:
|
|
193
|
-
_a = __read.apply(void 0, [_b.sent(), 3]), result = _a[0], opName = _a[1], modelDefinition = _a[2];
|
|
194
|
-
return [3 /*break*/, 5];
|
|
195
|
-
case 4:
|
|
196
|
-
error_1 = _b.sent();
|
|
197
|
-
if (error_1.message === 'Offline' ||
|
|
198
|
-
error_1.message === 'RetryMutation') {
|
|
199
|
-
return [2 /*return*/, "continue"];
|
|
200
|
-
}
|
|
201
|
-
return [3 /*break*/, 5];
|
|
202
|
-
case 5:
|
|
203
|
-
if (!(result === undefined)) return [3 /*break*/, 7];
|
|
204
|
-
logger.debug('done retrying');
|
|
205
|
-
return [4 /*yield*/, this_1.storage.runExclusive(function (storage) { return __awaiter(_this, void 0, void 0, function () {
|
|
206
|
-
return __generator(this, function (_a) {
|
|
207
|
-
switch (_a.label) {
|
|
208
|
-
case 0: return [4 /*yield*/, this.outbox.dequeue(storage)];
|
|
209
|
-
case 1:
|
|
210
|
-
_a.sent();
|
|
211
|
-
return [2 /*return*/];
|
|
212
|
-
}
|
|
213
|
-
});
|
|
214
|
-
}); })];
|
|
215
|
-
case 6:
|
|
216
|
-
_b.sent();
|
|
217
|
-
return [2 /*return*/, "continue"];
|
|
218
|
-
case 7:
|
|
219
|
-
record = result.data[opName];
|
|
220
|
-
hasMore = false;
|
|
221
|
-
return [4 /*yield*/, this_1.storage.runExclusive(function (storage) { return __awaiter(_this, void 0, void 0, function () {
|
|
222
|
-
return __generator(this, function (_a) {
|
|
223
|
-
switch (_a.label) {
|
|
224
|
-
case 0:
|
|
225
|
-
// using runExclusive to prevent possible race condition
|
|
226
|
-
// when another record gets enqueued between dequeue and peek
|
|
227
|
-
return [4 /*yield*/, this.outbox.dequeue(storage, record, operation)];
|
|
228
|
-
case 1:
|
|
229
|
-
// using runExclusive to prevent possible race condition
|
|
230
|
-
// when another record gets enqueued between dequeue and peek
|
|
231
|
-
_a.sent();
|
|
232
|
-
return [4 /*yield*/, this.outbox.peek(storage)];
|
|
233
|
-
case 2:
|
|
234
|
-
hasMore = (_a.sent()) !== undefined;
|
|
235
|
-
return [2 /*return*/];
|
|
236
|
-
}
|
|
237
|
-
});
|
|
238
|
-
}); })];
|
|
239
|
-
case 8:
|
|
240
|
-
_b.sent();
|
|
241
|
-
(_c = (_b = this_1.observer) === null || _b === void 0 ? void 0 : _b.next) === null || _c === void 0 ? void 0 : _c.call(_b, {
|
|
242
|
-
operation: operation,
|
|
243
|
-
modelDefinition: modelDefinition,
|
|
244
|
-
model: record,
|
|
245
|
-
hasMore: hasMore,
|
|
246
|
-
});
|
|
247
|
-
return [2 /*return*/];
|
|
248
|
-
}
|
|
249
|
-
});
|
|
250
|
-
};
|
|
251
|
-
this_1 = this;
|
|
252
|
-
_d.label = 1;
|
|
253
|
-
case 1:
|
|
254
|
-
_a = this.processing &&
|
|
255
|
-
this.runningProcesses.isOpen;
|
|
256
|
-
if (!_a) return [3 /*break*/, 3];
|
|
257
|
-
return [4 /*yield*/, this.outbox.peek(this.storage)];
|
|
258
|
-
case 2:
|
|
259
|
-
_a = (head = _d.sent()) !== undefined;
|
|
260
|
-
_d.label = 3;
|
|
261
|
-
case 3:
|
|
262
|
-
if (!_a) return [3 /*break*/, 5];
|
|
263
|
-
return [5 /*yield**/, _loop_1()];
|
|
264
|
-
case 4:
|
|
265
|
-
_d.sent();
|
|
266
|
-
return [3 /*break*/, 1];
|
|
267
|
-
case 5:
|
|
268
|
-
// pauses itself
|
|
269
|
-
this.pause();
|
|
270
|
-
return [2 /*return*/];
|
|
271
|
-
}
|
|
272
|
-
});
|
|
273
|
-
}); }, 'mutation resume loop'))];
|
|
274
|
-
case 1:
|
|
275
|
-
_a.sent();
|
|
276
|
-
return [2 /*return*/];
|
|
77
|
+
}
|
|
78
|
+
async resume() {
|
|
79
|
+
if (this.runningProcesses.isOpen) {
|
|
80
|
+
await this.runningProcesses.add(async (onTerminate) => {
|
|
81
|
+
if (this.processing ||
|
|
82
|
+
!this.isReady() ||
|
|
83
|
+
!this.runningProcesses.isOpen) {
|
|
84
|
+
return;
|
|
277
85
|
}
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
) {
|
|
328
|
-
if (!this.processing) {
|
|
329
|
-
throw new NonRetryableError('Offline');
|
|
330
|
-
}
|
|
331
|
-
// TODO: Check errors on different env (react-native or other browsers)
|
|
332
|
-
throw new Error('Network Error');
|
|
333
|
-
}
|
|
334
|
-
if (!(error.errorType === 'ConflictUnhandled')) return [3 /*break*/, 13];
|
|
335
|
-
// TODO: add on ConflictConditionalCheck error query last from server
|
|
336
|
-
attempt++;
|
|
337
|
-
retryWith = void 0;
|
|
338
|
-
if (!(attempt > MAX_ATTEMPTS)) return [3 /*break*/, 5];
|
|
339
|
-
retryWith = DISCARD;
|
|
340
|
-
return [3 /*break*/, 8];
|
|
341
|
-
case 5:
|
|
342
|
-
_h.trys.push([5, 7, , 8]);
|
|
343
|
-
return [4 /*yield*/, this.conflictHandler({
|
|
344
|
-
modelConstructor: modelConstructor,
|
|
345
|
-
localModel: this.modelInstanceCreator(modelConstructor, variables.input),
|
|
346
|
-
remoteModel: this.modelInstanceCreator(modelConstructor, error.data),
|
|
347
|
-
operation: opType,
|
|
348
|
-
attempts: attempt,
|
|
349
|
-
})];
|
|
350
|
-
case 6:
|
|
351
|
-
retryWith = _h.sent();
|
|
352
|
-
return [3 /*break*/, 8];
|
|
353
|
-
case 7:
|
|
354
|
-
err_2 = _h.sent();
|
|
355
|
-
logger.warn('conflict trycatch', err_2);
|
|
356
|
-
return [3 /*break*/, 17];
|
|
357
|
-
case 8:
|
|
358
|
-
if (!(retryWith === DISCARD)) return [3 /*break*/, 11];
|
|
359
|
-
_e = __read(buildGraphQLOperation(this.schema.namespaces[namespaceName], modelDefinition, 'GET'), 1), _f = __read(_e[0], 3), opName_1 = _f[1], query_1 = _f[2];
|
|
360
|
-
return [4 /*yield*/, getTokenForCustomAuth(authMode, this.amplifyConfig)];
|
|
361
|
-
case 9:
|
|
362
|
-
authToken_1 = _h.sent();
|
|
363
|
-
return [4 /*yield*/, this.amplifyContext.InternalAPI.graphql({
|
|
364
|
-
query: query_1,
|
|
365
|
-
variables: { id: variables.input.id },
|
|
366
|
-
authMode: authMode,
|
|
367
|
-
authToken: authToken_1,
|
|
368
|
-
}, undefined, customUserAgentDetails)];
|
|
369
|
-
case 10:
|
|
370
|
-
serverData = _h.sent();
|
|
371
|
-
// onTerminate cancel graphql()
|
|
372
|
-
return [2 /*return*/, [serverData, opName_1, modelDefinition]];
|
|
373
|
-
case 11:
|
|
374
|
-
namespace = this.schema.namespaces[namespaceName];
|
|
375
|
-
updatedMutation = createMutationInstanceFromModelOperation(namespace.relationships, modelDefinition, opType, modelConstructor, retryWith, graphQLCondition, MutationEvent, this.modelInstanceCreator, mutationEvent.id);
|
|
376
|
-
return [4 /*yield*/, this.storage.save(updatedMutation)];
|
|
377
|
-
case 12:
|
|
378
|
-
_h.sent();
|
|
379
|
-
throw new NonRetryableError('RetryMutation');
|
|
380
|
-
case 13:
|
|
381
|
-
try {
|
|
382
|
-
this.errorHandler({
|
|
383
|
-
recoverySuggestion: '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',
|
|
384
|
-
localModel: variables.input,
|
|
385
|
-
message: error.message,
|
|
386
|
-
operation: operation,
|
|
387
|
-
errorType: getMutationErrorType(error),
|
|
388
|
-
errorInfo: error.errorInfo,
|
|
389
|
-
process: ProcessName.mutate,
|
|
390
|
-
cause: error,
|
|
391
|
-
remoteModel: error.data
|
|
392
|
-
? this.modelInstanceCreator(modelConstructor, error.data)
|
|
393
|
-
: null,
|
|
394
|
-
});
|
|
395
|
-
}
|
|
396
|
-
catch (err) {
|
|
397
|
-
logger.warn('Mutation error handler failed with:', err);
|
|
398
|
-
}
|
|
399
|
-
finally {
|
|
400
|
-
// Return empty tuple, dequeues the mutation
|
|
401
|
-
return [2 /*return*/, error.data
|
|
402
|
-
? [
|
|
403
|
-
{ data: (_g = {}, _g[opName] = error.data, _g) },
|
|
404
|
-
opName,
|
|
405
|
-
modelDefinition,
|
|
406
|
-
]
|
|
407
|
-
: []];
|
|
408
|
-
}
|
|
409
|
-
_h.label = 14;
|
|
410
|
-
case 14: return [3 /*break*/, 16];
|
|
411
|
-
case 15:
|
|
412
|
-
// Catch-all for client-side errors that don't come back in the `GraphQLError` format.
|
|
413
|
-
// These errors should not be retried.
|
|
414
|
-
throw new NonRetryableError(err_1);
|
|
415
|
-
case 16: return [3 /*break*/, 17];
|
|
416
|
-
case 17:
|
|
417
|
-
if (tryWith) return [3 /*break*/, 2];
|
|
418
|
-
_h.label = 18;
|
|
419
|
-
case 18: return [2 /*return*/];
|
|
86
|
+
this.processing = true;
|
|
87
|
+
let head;
|
|
88
|
+
const namespaceName = USER;
|
|
89
|
+
// start to drain outbox
|
|
90
|
+
while (this.processing &&
|
|
91
|
+
this.runningProcesses.isOpen &&
|
|
92
|
+
(head = await this.outbox.peek(this.storage)) !== undefined) {
|
|
93
|
+
const { model, operation, data, condition } = head;
|
|
94
|
+
const modelConstructor = this.userClasses[model];
|
|
95
|
+
let result = undefined;
|
|
96
|
+
let opName = undefined;
|
|
97
|
+
let modelDefinition = undefined;
|
|
98
|
+
try {
|
|
99
|
+
const modelAuthModes = await getModelAuthModes({
|
|
100
|
+
authModeStrategy: this.authModeStrategy,
|
|
101
|
+
defaultAuthMode: this.amplifyConfig.aws_appsync_authenticationType,
|
|
102
|
+
modelName: model,
|
|
103
|
+
schema: this.schema,
|
|
104
|
+
});
|
|
105
|
+
const operationAuthModes = modelAuthModes[operation.toUpperCase()];
|
|
106
|
+
let authModeAttempts = 0;
|
|
107
|
+
const authModeRetry = async () => {
|
|
108
|
+
try {
|
|
109
|
+
logger.debug(`Attempting mutation with authMode: ${operationAuthModes[authModeAttempts]}`);
|
|
110
|
+
const response = await this.jitteredRetry(namespaceName, model, operation, data, condition, modelConstructor, this.MutationEvent, head, operationAuthModes[authModeAttempts], onTerminate);
|
|
111
|
+
logger.debug(`Mutation sent successfully with authMode: ${operationAuthModes[authModeAttempts]}`);
|
|
112
|
+
return response;
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
authModeAttempts++;
|
|
116
|
+
if (authModeAttempts >= operationAuthModes.length) {
|
|
117
|
+
logger.debug(`Mutation failed with authMode: ${operationAuthModes[authModeAttempts - 1]}`);
|
|
118
|
+
try {
|
|
119
|
+
await this.errorHandler({
|
|
120
|
+
recoverySuggestion: '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',
|
|
121
|
+
localModel: null,
|
|
122
|
+
message: error.message,
|
|
123
|
+
model: modelConstructor.name,
|
|
124
|
+
operation: opName,
|
|
125
|
+
errorType: getMutationErrorType(error),
|
|
126
|
+
process: ProcessName.sync,
|
|
127
|
+
remoteModel: null,
|
|
128
|
+
cause: error,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
catch (e) {
|
|
132
|
+
logger.error('Mutation error handler failed with:', e);
|
|
133
|
+
}
|
|
134
|
+
throw error;
|
|
420
135
|
}
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
var pkField = primaryKey_1_1.value;
|
|
455
|
-
deleteInput[pkField] = parsedData[pkField];
|
|
136
|
+
logger.debug(`Mutation failed with authMode: ${operationAuthModes[authModeAttempts - 1]}. Retrying with authMode: ${operationAuthModes[authModeAttempts]}`);
|
|
137
|
+
return await authModeRetry();
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
[result, opName, modelDefinition] = await authModeRetry();
|
|
141
|
+
}
|
|
142
|
+
catch (error) {
|
|
143
|
+
if (error.message === 'Offline' ||
|
|
144
|
+
error.message === 'RetryMutation') {
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
if (result === undefined) {
|
|
149
|
+
logger.debug('done retrying');
|
|
150
|
+
await this.storage.runExclusive(async (storage) => {
|
|
151
|
+
await this.outbox.dequeue(storage);
|
|
152
|
+
});
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
const record = result.data[opName];
|
|
156
|
+
let hasMore = false;
|
|
157
|
+
await this.storage.runExclusive(async (storage) => {
|
|
158
|
+
// using runExclusive to prevent possible race condition
|
|
159
|
+
// when another record gets enqueued between dequeue and peek
|
|
160
|
+
await this.outbox.dequeue(storage, record, operation);
|
|
161
|
+
hasMore = (await this.outbox.peek(storage)) !== undefined;
|
|
162
|
+
});
|
|
163
|
+
this.observer?.next?.({
|
|
164
|
+
operation,
|
|
165
|
+
modelDefinition,
|
|
166
|
+
model: record,
|
|
167
|
+
hasMore,
|
|
168
|
+
});
|
|
456
169
|
}
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
170
|
+
// pauses itself
|
|
171
|
+
this.pause();
|
|
172
|
+
}, 'mutation resume loop');
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
async jitteredRetry(namespaceName, model, operation, data, condition, modelConstructor, MutationEvent, mutationEvent, authMode, onTerminate) {
|
|
176
|
+
return await retry(async (model, operation, data, condition, modelConstructor, MutationEvent, mutationEvent) => {
|
|
177
|
+
const [query, variables, graphQLCondition, opName, modelDefinition] = this.createQueryVariables(namespaceName, model, operation, data, condition);
|
|
178
|
+
const authToken = await getTokenForCustomAuth(authMode, this.amplifyConfig);
|
|
179
|
+
const tryWith = {
|
|
180
|
+
query,
|
|
181
|
+
variables,
|
|
182
|
+
authMode,
|
|
183
|
+
authToken,
|
|
184
|
+
};
|
|
185
|
+
let attempt = 0;
|
|
186
|
+
const opType = this.opTypeFromTransformerOperation(operation);
|
|
187
|
+
const customUserAgentDetails = {
|
|
188
|
+
category: Category.DataStore,
|
|
189
|
+
action: DataStoreAction.GraphQl,
|
|
190
|
+
};
|
|
191
|
+
do {
|
|
460
192
|
try {
|
|
461
|
-
|
|
193
|
+
const result = (await this.amplifyContext.InternalAPI.graphql(tryWith, undefined, customUserAgentDetails));
|
|
194
|
+
// Use `as any` because TypeScript doesn't seem to like passing tuples
|
|
195
|
+
// through generic params.
|
|
196
|
+
return [result, opName, modelDefinition];
|
|
197
|
+
}
|
|
198
|
+
catch (err) {
|
|
199
|
+
if (err.errors && err.errors.length > 0) {
|
|
200
|
+
const [error] = err.errors;
|
|
201
|
+
const { originalError: { code = null } = {} } = error;
|
|
202
|
+
if (error.errorType === 'Unauthorized') {
|
|
203
|
+
throw new NonRetryableError('Unauthorized');
|
|
204
|
+
}
|
|
205
|
+
if (error.message === 'Network Error' ||
|
|
206
|
+
code === 'ECONNABORTED' // refers to axios timeout error caused by device's bad network condition
|
|
207
|
+
) {
|
|
208
|
+
if (!this.processing) {
|
|
209
|
+
throw new NonRetryableError('Offline');
|
|
210
|
+
}
|
|
211
|
+
// TODO: Check errors on different env (react-native or other browsers)
|
|
212
|
+
throw new Error('Network Error');
|
|
213
|
+
}
|
|
214
|
+
if (error.errorType === 'ConflictUnhandled') {
|
|
215
|
+
// TODO: add on ConflictConditionalCheck error query last from server
|
|
216
|
+
attempt++;
|
|
217
|
+
let retryWith;
|
|
218
|
+
if (attempt > MAX_ATTEMPTS) {
|
|
219
|
+
retryWith = DISCARD;
|
|
220
|
+
}
|
|
221
|
+
else {
|
|
222
|
+
try {
|
|
223
|
+
retryWith = await this.conflictHandler({
|
|
224
|
+
modelConstructor,
|
|
225
|
+
localModel: this.modelInstanceCreator(modelConstructor, variables.input),
|
|
226
|
+
remoteModel: this.modelInstanceCreator(modelConstructor, error.data),
|
|
227
|
+
operation: opType,
|
|
228
|
+
attempts: attempt,
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
catch (err) {
|
|
232
|
+
logger.warn('conflict trycatch', err);
|
|
233
|
+
continue;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
if (retryWith === DISCARD) {
|
|
237
|
+
// Query latest from server and notify merger
|
|
238
|
+
const [[, opName, query]] = buildGraphQLOperation(this.schema.namespaces[namespaceName], modelDefinition, 'GET');
|
|
239
|
+
const authToken = await getTokenForCustomAuth(authMode, this.amplifyConfig);
|
|
240
|
+
const serverData = await this.amplifyContext.InternalAPI.graphql({
|
|
241
|
+
query,
|
|
242
|
+
variables: { id: variables.input.id },
|
|
243
|
+
authMode,
|
|
244
|
+
authToken,
|
|
245
|
+
}, undefined, customUserAgentDetails);
|
|
246
|
+
// onTerminate cancel graphql()
|
|
247
|
+
return [serverData, opName, modelDefinition];
|
|
248
|
+
}
|
|
249
|
+
const namespace = this.schema.namespaces[namespaceName];
|
|
250
|
+
// convert retry with to tryWith
|
|
251
|
+
const updatedMutation = createMutationInstanceFromModelOperation(namespace.relationships, modelDefinition, opType, modelConstructor, retryWith, graphQLCondition, MutationEvent, this.modelInstanceCreator, mutationEvent.id);
|
|
252
|
+
await this.storage.save(updatedMutation);
|
|
253
|
+
throw new NonRetryableError('RetryMutation');
|
|
254
|
+
}
|
|
255
|
+
else {
|
|
256
|
+
try {
|
|
257
|
+
this.errorHandler({
|
|
258
|
+
recoverySuggestion: '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',
|
|
259
|
+
localModel: variables.input,
|
|
260
|
+
message: error.message,
|
|
261
|
+
operation,
|
|
262
|
+
errorType: getMutationErrorType(error),
|
|
263
|
+
errorInfo: error.errorInfo,
|
|
264
|
+
process: ProcessName.mutate,
|
|
265
|
+
cause: error,
|
|
266
|
+
remoteModel: error.data
|
|
267
|
+
? this.modelInstanceCreator(modelConstructor, error.data)
|
|
268
|
+
: null,
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
catch (err) {
|
|
272
|
+
logger.warn('Mutation error handler failed with:', err);
|
|
273
|
+
}
|
|
274
|
+
finally {
|
|
275
|
+
// Return empty tuple, dequeues the mutation
|
|
276
|
+
return error.data
|
|
277
|
+
? [
|
|
278
|
+
{ data: { [opName]: error.data } },
|
|
279
|
+
opName,
|
|
280
|
+
modelDefinition,
|
|
281
|
+
]
|
|
282
|
+
: [];
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
// Catch-all for client-side errors that don't come back in the `GraphQLError` format.
|
|
288
|
+
// These errors should not be retried.
|
|
289
|
+
throw new NonRetryableError(err);
|
|
290
|
+
}
|
|
462
291
|
}
|
|
463
|
-
|
|
292
|
+
} while (tryWith);
|
|
293
|
+
}, [
|
|
294
|
+
model,
|
|
295
|
+
operation,
|
|
296
|
+
data,
|
|
297
|
+
condition,
|
|
298
|
+
modelConstructor,
|
|
299
|
+
MutationEvent,
|
|
300
|
+
mutationEvent,
|
|
301
|
+
], safeJitteredBackoff, onTerminate);
|
|
302
|
+
}
|
|
303
|
+
createQueryVariables(namespaceName, model, operation, data, condition) {
|
|
304
|
+
const modelDefinition = this.schema.namespaces[namespaceName].models[model];
|
|
305
|
+
const { primaryKey } = this.schema.namespaces[namespaceName].keys[model];
|
|
306
|
+
const auth = modelDefinition.attributes?.find(a => a.type === 'auth');
|
|
307
|
+
const ownerFields = auth?.properties?.rules
|
|
308
|
+
.map(rule => rule.ownerField)
|
|
309
|
+
.filter(f => f) || ['owner'];
|
|
310
|
+
const queriesTuples = this.typeQuery.get(modelDefinition);
|
|
311
|
+
const [, opName, query] = queriesTuples.find(([transformerMutationType]) => transformerMutationType === operation);
|
|
312
|
+
const { _version, ...parsedData } = JSON.parse(data);
|
|
313
|
+
// include all the fields that comprise a custom PK if one is specified
|
|
314
|
+
const deleteInput = {};
|
|
315
|
+
if (primaryKey && primaryKey.length) {
|
|
316
|
+
for (const pkField of primaryKey) {
|
|
317
|
+
deleteInput[pkField] = parsedData[pkField];
|
|
464
318
|
}
|
|
465
319
|
}
|
|
466
320
|
else {
|
|
467
321
|
deleteInput[ID] = parsedData.id;
|
|
468
322
|
}
|
|
469
|
-
|
|
323
|
+
let mutationInput;
|
|
470
324
|
if (operation === TransformerMutationType.DELETE) {
|
|
471
325
|
// For DELETE mutations, only the key(s) are included in the input
|
|
472
326
|
mutationInput = deleteInput;
|
|
@@ -474,75 +328,61 @@ var MutationProcessor = /** @class */ (function () {
|
|
|
474
328
|
else {
|
|
475
329
|
// Otherwise, we construct the mutation input with the following logic
|
|
476
330
|
mutationInput = {};
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
//
|
|
490
|
-
if (
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
// instead of including the connected model itself, we add its key(s) to the mutation input
|
|
498
|
-
for (var targetNames_1 = (e_4 = void 0, __values(targetNames)), targetNames_1_1 = targetNames_1.next(); !targetNames_1_1.done; targetNames_1_1 = targetNames_1.next()) {
|
|
499
|
-
var targetName = targetNames_1_1.value;
|
|
500
|
-
mutationInput[targetName] = parsedData[targetName];
|
|
501
|
-
}
|
|
502
|
-
}
|
|
503
|
-
catch (e_4_1) { e_4 = { error: e_4_1 }; }
|
|
504
|
-
finally {
|
|
505
|
-
try {
|
|
506
|
-
if (targetNames_1_1 && !targetNames_1_1.done && (_c = targetNames_1.return)) _c.call(targetNames_1);
|
|
507
|
-
}
|
|
508
|
-
finally { if (e_4) throw e_4.error; }
|
|
509
|
-
}
|
|
331
|
+
const modelFields = Object.values(modelDefinition.fields);
|
|
332
|
+
for (const { name, type, association, isReadOnly } of modelFields) {
|
|
333
|
+
// omit readonly fields. cloud storage doesn't need them and won't take them!
|
|
334
|
+
if (isReadOnly) {
|
|
335
|
+
continue;
|
|
336
|
+
}
|
|
337
|
+
// omit owner fields if it's `null`. cloud storage doesn't allow it.
|
|
338
|
+
if (ownerFields.includes(name) && parsedData[name] === null) {
|
|
339
|
+
continue;
|
|
340
|
+
}
|
|
341
|
+
// model fields should be stripped out from the input
|
|
342
|
+
if (isModelFieldType(type)) {
|
|
343
|
+
// except for belongs to relations - we need to replace them with the correct foreign key(s)
|
|
344
|
+
if (isTargetNameAssociation(association) &&
|
|
345
|
+
association.connectionType === 'BELONGS_TO') {
|
|
346
|
+
const targetNames = extractTargetNamesFromSrc(association);
|
|
347
|
+
if (targetNames) {
|
|
348
|
+
// instead of including the connected model itself, we add its key(s) to the mutation input
|
|
349
|
+
for (const targetName of targetNames) {
|
|
350
|
+
mutationInput[targetName] = parsedData[targetName];
|
|
510
351
|
}
|
|
511
352
|
}
|
|
512
|
-
continue;
|
|
513
353
|
}
|
|
514
|
-
|
|
515
|
-
if (operation === TransformerMutationType.UPDATE) {
|
|
516
|
-
if (!parsedData.hasOwnProperty(name_1)) {
|
|
517
|
-
// for update mutations - strip out a field if it's unchanged
|
|
518
|
-
continue;
|
|
519
|
-
}
|
|
520
|
-
}
|
|
521
|
-
// all other fields are added to the input object
|
|
522
|
-
mutationInput[name_1] = parsedData[name_1];
|
|
354
|
+
continue;
|
|
523
355
|
}
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
356
|
+
// scalar fields / non-model types
|
|
357
|
+
if (operation === TransformerMutationType.UPDATE) {
|
|
358
|
+
if (!parsedData.hasOwnProperty(name)) {
|
|
359
|
+
// for update mutations - strip out a field if it's unchanged
|
|
360
|
+
continue;
|
|
361
|
+
}
|
|
529
362
|
}
|
|
530
|
-
|
|
363
|
+
// all other fields are added to the input object
|
|
364
|
+
mutationInput[name] = parsedData[name];
|
|
531
365
|
}
|
|
532
366
|
}
|
|
533
367
|
// Build mutation variables input object
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
368
|
+
const input = {
|
|
369
|
+
...mutationInput,
|
|
370
|
+
_version,
|
|
371
|
+
};
|
|
372
|
+
const graphQLCondition = JSON.parse(condition);
|
|
373
|
+
const variables = {
|
|
374
|
+
input,
|
|
375
|
+
...(operation === TransformerMutationType.CREATE
|
|
376
|
+
? {}
|
|
377
|
+
: {
|
|
378
|
+
condition: Object.keys(graphQLCondition).length > 0
|
|
379
|
+
? graphQLCondition
|
|
380
|
+
: null,
|
|
381
|
+
}),
|
|
382
|
+
};
|
|
543
383
|
return [query, variables, graphQLCondition, opName, modelDefinition];
|
|
544
|
-
}
|
|
545
|
-
|
|
384
|
+
}
|
|
385
|
+
opTypeFromTransformerOperation(operation) {
|
|
546
386
|
switch (operation) {
|
|
547
387
|
case TransformerMutationType.CREATE:
|
|
548
388
|
return OpType.INSERT;
|
|
@@ -553,18 +393,17 @@ var MutationProcessor = /** @class */ (function () {
|
|
|
553
393
|
case TransformerMutationType.GET: // Intentionally blank
|
|
554
394
|
break;
|
|
555
395
|
default:
|
|
556
|
-
throw new Error(
|
|
396
|
+
throw new Error(`Invalid operation ${operation}`);
|
|
557
397
|
}
|
|
558
398
|
// because it makes TS happy ...
|
|
559
399
|
return undefined;
|
|
560
|
-
}
|
|
561
|
-
|
|
400
|
+
}
|
|
401
|
+
pause() {
|
|
562
402
|
this.processing = false;
|
|
563
|
-
}
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
var originalJitteredBackoff = jitteredBackoff(MAX_RETRY_DELAY_MS);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
const MAX_RETRY_DELAY_MS = 5 * 60 * 1000;
|
|
406
|
+
const originalJitteredBackoff = jitteredBackoff(MAX_RETRY_DELAY_MS);
|
|
568
407
|
/**
|
|
569
408
|
* @private
|
|
570
409
|
* Internal use of Amplify only.
|
|
@@ -580,13 +419,13 @@ var originalJitteredBackoff = jitteredBackoff(MAX_RETRY_DELAY_MS);
|
|
|
580
419
|
* @param error tested to see if `.message` is 'Network Error'
|
|
581
420
|
* @returns number | false :
|
|
582
421
|
*/
|
|
583
|
-
export
|
|
584
|
-
|
|
422
|
+
export const safeJitteredBackoff = (attempt, _args, error) => {
|
|
423
|
+
const attemptResult = originalJitteredBackoff(attempt);
|
|
585
424
|
// If this is the last attempt and it is a network error, we retry indefinitively every 5 minutes
|
|
586
|
-
if (attemptResult === false &&
|
|
425
|
+
if (attemptResult === false &&
|
|
426
|
+
(error || {}).message === 'Network Error') {
|
|
587
427
|
return MAX_RETRY_DELAY_MS;
|
|
588
428
|
}
|
|
589
429
|
return attemptResult;
|
|
590
430
|
};
|
|
591
431
|
export { MutationProcessor };
|
|
592
|
-
//# sourceMappingURL=mutation.js.map
|