@aws-amplify/datastore 5.0.1-api-v6-models.c1977f8.0 → 5.0.1-api-v6-models.891fe0d.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/authModeStrategies/defaultAuthStrategy.js +1 -1
- package/lib/authModeStrategies/multiAuthStrategy.js +29 -105
- package/lib/datastore/datastore.js +887 -1370
- package/lib/index.js +1 -1
- package/lib/predicates/index.js +53 -102
- package/lib/predicates/next.js +310 -557
- package/lib/predicates/sort.js +24 -27
- package/lib/ssr/index.js +1 -1
- package/lib/storage/adapter/AsyncStorageAdapter.js +115 -449
- package/lib/storage/adapter/AsyncStorageDatabase.js +215 -480
- package/lib/storage/adapter/InMemoryStore.js +27 -101
- package/lib/storage/adapter/InMemoryStore.native.js +1 -1
- package/lib/storage/adapter/IndexedDBAdapter.js +441 -1002
- package/lib/storage/adapter/StorageAdapterBase.js +177 -396
- package/lib/storage/adapter/getDefaultAdapter/index.js +5 -6
- package/lib/storage/adapter/getDefaultAdapter/index.native.js +2 -2
- package/lib/storage/relationship.js +174 -260
- package/lib/storage/storage.js +244 -507
- package/lib/sync/datastoreConnectivity.js +29 -84
- package/lib/sync/datastoreReachability/index.js +1 -1
- package/lib/sync/datastoreReachability/index.native.js +2 -2
- package/lib/sync/index.js +512 -885
- package/lib/sync/merger.js +30 -133
- package/lib/sync/outbox.js +147 -302
- package/lib/sync/processors/errorMaps.js +30 -80
- package/lib/sync/processors/mutation.js +331 -579
- package/lib/sync/processors/subscription.js +268 -428
- package/lib/sync/processors/sync.js +276 -464
- package/lib/sync/utils.js +248 -393
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/lib/types.js +16 -58
- package/lib/util.js +335 -575
- package/lib-esm/authModeStrategies/defaultAuthStrategy.js +1 -1
- package/lib-esm/authModeStrategies/multiAuthStrategy.js +27 -103
- package/lib-esm/datastore/datastore.js +874 -1359
- package/lib-esm/index.js +6 -6
- package/lib-esm/predicates/index.js +54 -104
- package/lib-esm/predicates/next.js +306 -555
- package/lib-esm/predicates/sort.js +24 -27
- package/lib-esm/ssr/index.js +1 -1
- package/lib-esm/storage/adapter/AsyncStorageAdapter.js +111 -446
- package/lib-esm/storage/adapter/AsyncStorageDatabase.js +212 -477
- package/lib-esm/storage/adapter/InMemoryStore.js +27 -102
- package/lib-esm/storage/adapter/IndexedDBAdapter.js +436 -997
- package/lib-esm/storage/adapter/StorageAdapterBase.js +172 -392
- package/lib-esm/storage/adapter/getDefaultAdapter/index.js +2 -3
- package/lib-esm/storage/adapter/getDefaultAdapter/index.native.js +1 -1
- package/lib-esm/storage/relationship.js +173 -260
- package/lib-esm/storage/storage.js +236 -499
- package/lib-esm/sync/datastoreConnectivity.js +26 -82
- package/lib-esm/sync/datastoreReachability/index.js +1 -1
- package/lib-esm/sync/datastoreReachability/index.native.js +1 -1
- package/lib-esm/sync/index.js +498 -872
- package/lib-esm/sync/merger.js +28 -131
- package/lib-esm/sync/outbox.js +143 -298
- package/lib-esm/sync/processors/errorMaps.js +32 -82
- package/lib-esm/sync/processors/mutation.js +324 -572
- package/lib-esm/sync/processors/subscription.js +258 -418
- package/lib-esm/sync/processors/sync.js +269 -457
- package/lib-esm/sync/utils.js +245 -390
- package/lib-esm/tsconfig.tsbuildinfo +1 -1
- package/lib-esm/types.js +16 -59
- package/lib-esm/util.js +335 -577
- package/package.json +12 -12
- package/src/datastore/datastore.ts +4 -3
- package/src/storage/adapter/getDefaultAdapter/index.ts +1 -3
- package/src/sync/processors/mutation.ts +1 -1
- package/src/sync/processors/sync.ts +1 -1
- package/src/sync/utils.ts +1 -1
- package/src/util.ts +44 -6
|
@@ -1,101 +1,15 @@
|
|
|
1
|
-
var __assign = (this && this.__assign) || function () {
|
|
2
|
-
__assign = Object.assign || function(t) {
|
|
3
|
-
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
4
|
-
s = arguments[i];
|
|
5
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
6
|
-
t[p] = s[p];
|
|
7
|
-
}
|
|
8
|
-
return t;
|
|
9
|
-
};
|
|
10
|
-
return __assign.apply(this, arguments);
|
|
11
|
-
};
|
|
12
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
13
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
14
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
15
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
16
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
17
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
18
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
19
|
-
});
|
|
20
|
-
};
|
|
21
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
22
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
23
|
-
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
24
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
25
|
-
function step(op) {
|
|
26
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
27
|
-
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
28
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
29
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
30
|
-
switch (op[0]) {
|
|
31
|
-
case 0: case 1: t = op; break;
|
|
32
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
33
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
34
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
35
|
-
default:
|
|
36
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
37
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
38
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
39
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
40
|
-
if (t[2]) _.ops.pop();
|
|
41
|
-
_.trys.pop(); continue;
|
|
42
|
-
}
|
|
43
|
-
op = body.call(thisArg, _);
|
|
44
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
45
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
46
|
-
}
|
|
47
|
-
};
|
|
48
|
-
var __rest = (this && this.__rest) || function (s, e) {
|
|
49
|
-
var t = {};
|
|
50
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
51
|
-
t[p] = s[p];
|
|
52
|
-
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
53
|
-
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
54
|
-
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
55
|
-
t[p[i]] = s[p[i]];
|
|
56
|
-
}
|
|
57
|
-
return t;
|
|
58
|
-
};
|
|
59
|
-
var __read = (this && this.__read) || function (o, n) {
|
|
60
|
-
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
61
|
-
if (!m) return o;
|
|
62
|
-
var i = m.call(o), r, ar = [], e;
|
|
63
|
-
try {
|
|
64
|
-
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
|
65
|
-
}
|
|
66
|
-
catch (error) { e = { error: error }; }
|
|
67
|
-
finally {
|
|
68
|
-
try {
|
|
69
|
-
if (r && !r.done && (m = i["return"])) m.call(i);
|
|
70
|
-
}
|
|
71
|
-
finally { if (e) throw e.error; }
|
|
72
|
-
}
|
|
73
|
-
return ar;
|
|
74
|
-
};
|
|
75
|
-
var __values = (this && this.__values) || function(o) {
|
|
76
|
-
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
|
|
77
|
-
if (m) return m.call(o);
|
|
78
|
-
if (o && typeof o.length === "number") return {
|
|
79
|
-
next: function () {
|
|
80
|
-
if (o && i >= o.length) o = void 0;
|
|
81
|
-
return { value: o && o[i++], done: !o };
|
|
82
|
-
}
|
|
83
|
-
};
|
|
84
|
-
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
|
|
85
|
-
};
|
|
86
1
|
import { InternalAPI } from '@aws-amplify/api/internals';
|
|
87
2
|
import { Category, DataStoreAction, jitteredBackoff, NonRetryableError, retry, BackgroundProcessManager, } from '@aws-amplify/core/internals/utils';
|
|
88
|
-
import { ConsoleLogger } from '@aws-amplify/core';
|
|
89
3
|
import { Observable } from 'rxjs';
|
|
90
4
|
import { DISCARD, isModelFieldType, isTargetNameAssociation, OpType, ProcessName, } from '../../types';
|
|
91
5
|
import { extractTargetNamesFromSrc, USER, ID } from '../../util';
|
|
92
6
|
import { buildGraphQLOperation, createMutationInstanceFromModelOperation, getModelAuthModes, TransformerMutationType, getTokenForCustomAuth, } from '../utils';
|
|
93
7
|
import { getMutationErrorType } from './errorMaps';
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
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) {
|
|
99
13
|
this.schema = schema;
|
|
100
14
|
this.storage = storage;
|
|
101
15
|
this.userClasses = userClasses;
|
|
@@ -114,446 +28,299 @@ var MutationProcessor = /** @class */ (function () {
|
|
|
114
28
|
this.amplifyContext.InternalAPI || InternalAPI;
|
|
115
29
|
this.generateQueries();
|
|
116
30
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
Object.values(this.schema.namespaces).forEach(function (namespace) {
|
|
31
|
+
generateQueries() {
|
|
32
|
+
Object.values(this.schema.namespaces).forEach(namespace => {
|
|
120
33
|
Object.values(namespace.models)
|
|
121
|
-
.filter(
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
var _b = __read(buildGraphQLOperation(namespace, model, 'UPDATE'), 1), updateMutation = _b[0];
|
|
128
|
-
var _c = __read(buildGraphQLOperation(namespace, model, 'DELETE'), 1), deleteMutation = _c[0];
|
|
129
|
-
_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, [
|
|
130
40
|
createMutation,
|
|
131
41
|
updateMutation,
|
|
132
42
|
deleteMutation,
|
|
133
43
|
]);
|
|
134
44
|
});
|
|
135
45
|
});
|
|
136
|
-
}
|
|
137
|
-
|
|
46
|
+
}
|
|
47
|
+
isReady() {
|
|
138
48
|
return this.observer !== undefined;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
var _this = this;
|
|
49
|
+
}
|
|
50
|
+
start() {
|
|
142
51
|
this.runningProcesses = new BackgroundProcessManager();
|
|
143
|
-
|
|
144
|
-
|
|
52
|
+
const observable = new Observable(observer => {
|
|
53
|
+
this.observer = observer;
|
|
145
54
|
try {
|
|
146
|
-
|
|
55
|
+
this.resume();
|
|
147
56
|
}
|
|
148
57
|
catch (error) {
|
|
149
58
|
logger.error('mutations processor start error', error);
|
|
150
59
|
throw error;
|
|
151
60
|
}
|
|
152
|
-
return
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
this.pause();
|
|
157
|
-
return [2 /*return*/];
|
|
158
|
-
});
|
|
159
|
-
}); });
|
|
160
|
-
});
|
|
161
|
-
return observable;
|
|
162
|
-
};
|
|
163
|
-
MutationProcessor.prototype.stop = function () {
|
|
164
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
165
|
-
return __generator(this, function (_a) {
|
|
166
|
-
switch (_a.label) {
|
|
167
|
-
case 0:
|
|
168
|
-
this.removeObserver();
|
|
169
|
-
return [4 /*yield*/, this.runningProcesses.close()];
|
|
170
|
-
case 1:
|
|
171
|
-
_a.sent();
|
|
172
|
-
return [4 /*yield*/, this.runningProcesses.open()];
|
|
173
|
-
case 2:
|
|
174
|
-
_a.sent();
|
|
175
|
-
return [2 /*return*/];
|
|
176
|
-
}
|
|
61
|
+
return this.runningProcesses.addCleaner(async () => {
|
|
62
|
+
// The observer has unsubscribed and/or `stop()` has been called.
|
|
63
|
+
this.removeObserver();
|
|
64
|
+
this.pause();
|
|
177
65
|
});
|
|
178
66
|
});
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
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?.();
|
|
183
76
|
this.observer = undefined;
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
return [4 /*yield*/, this.jitteredRetry(namespaceName, model, operation, data, condition, modelConstructor, this.MutationEvent, head, operationAuthModes_1[authModeAttempts_1], onTerminate)];
|
|
238
|
-
case 1:
|
|
239
|
-
response = _a.sent();
|
|
240
|
-
logger.debug("Mutation sent successfully with authMode: ".concat(operationAuthModes_1[authModeAttempts_1]));
|
|
241
|
-
return [2 /*return*/, response];
|
|
242
|
-
case 2:
|
|
243
|
-
error_2 = _a.sent();
|
|
244
|
-
authModeAttempts_1++;
|
|
245
|
-
if (!(authModeAttempts_1 >= operationAuthModes_1.length)) return [3 /*break*/, 7];
|
|
246
|
-
logger.debug("Mutation failed with authMode: ".concat(operationAuthModes_1[authModeAttempts_1 - 1]));
|
|
247
|
-
_a.label = 3;
|
|
248
|
-
case 3:
|
|
249
|
-
_a.trys.push([3, 5, , 6]);
|
|
250
|
-
return [4 /*yield*/, this.errorHandler({
|
|
251
|
-
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',
|
|
252
|
-
localModel: null,
|
|
253
|
-
message: error_2.message,
|
|
254
|
-
model: modelConstructor.name,
|
|
255
|
-
operation: opName,
|
|
256
|
-
errorType: getMutationErrorType(error_2),
|
|
257
|
-
process: ProcessName.sync,
|
|
258
|
-
remoteModel: null,
|
|
259
|
-
cause: error_2,
|
|
260
|
-
})];
|
|
261
|
-
case 4:
|
|
262
|
-
_a.sent();
|
|
263
|
-
return [3 /*break*/, 6];
|
|
264
|
-
case 5:
|
|
265
|
-
e_1 = _a.sent();
|
|
266
|
-
logger.error('Mutation error handler failed with:', e_1);
|
|
267
|
-
return [3 /*break*/, 6];
|
|
268
|
-
case 6: throw error_2;
|
|
269
|
-
case 7:
|
|
270
|
-
logger.debug("Mutation failed with authMode: ".concat(operationAuthModes_1[authModeAttempts_1 - 1], ". Retrying with authMode: ").concat(operationAuthModes_1[authModeAttempts_1]));
|
|
271
|
-
return [4 /*yield*/, authModeRetry_1()];
|
|
272
|
-
case 8: return [2 /*return*/, _a.sent()];
|
|
273
|
-
case 9: return [2 /*return*/];
|
|
274
|
-
}
|
|
275
|
-
});
|
|
276
|
-
}); };
|
|
277
|
-
return [4 /*yield*/, authModeRetry_1()];
|
|
278
|
-
case 3:
|
|
279
|
-
_e = __read.apply(void 0, [_f.sent(), 3]), result = _e[0], opName = _e[1], modelDefinition = _e[2];
|
|
280
|
-
return [3 /*break*/, 5];
|
|
281
|
-
case 4:
|
|
282
|
-
error_1 = _f.sent();
|
|
283
|
-
if (error_1.message === 'Offline' ||
|
|
284
|
-
error_1.message === 'RetryMutation') {
|
|
285
|
-
return [2 /*return*/, "continue"];
|
|
286
|
-
}
|
|
287
|
-
return [3 /*break*/, 5];
|
|
288
|
-
case 5:
|
|
289
|
-
if (!(result === undefined)) return [3 /*break*/, 7];
|
|
290
|
-
logger.debug('done retrying');
|
|
291
|
-
return [4 /*yield*/, this_1.storage.runExclusive(function (storage) { return __awaiter(_this, void 0, void 0, function () {
|
|
292
|
-
return __generator(this, function (_a) {
|
|
293
|
-
switch (_a.label) {
|
|
294
|
-
case 0: return [4 /*yield*/, this.outbox.dequeue(storage)];
|
|
295
|
-
case 1:
|
|
296
|
-
_a.sent();
|
|
297
|
-
return [2 /*return*/];
|
|
298
|
-
}
|
|
299
|
-
});
|
|
300
|
-
}); })];
|
|
301
|
-
case 6:
|
|
302
|
-
_f.sent();
|
|
303
|
-
return [2 /*return*/, "continue"];
|
|
304
|
-
case 7:
|
|
305
|
-
record = result.data[opName];
|
|
306
|
-
hasMore = false;
|
|
307
|
-
return [4 /*yield*/, this_1.storage.runExclusive(function (storage) { return __awaiter(_this, void 0, void 0, function () {
|
|
308
|
-
return __generator(this, function (_a) {
|
|
309
|
-
switch (_a.label) {
|
|
310
|
-
case 0:
|
|
311
|
-
// using runExclusive to prevent possible race condition
|
|
312
|
-
// when another record gets enqueued between dequeue and peek
|
|
313
|
-
return [4 /*yield*/, this.outbox.dequeue(storage, record, operation)];
|
|
314
|
-
case 1:
|
|
315
|
-
// using runExclusive to prevent possible race condition
|
|
316
|
-
// when another record gets enqueued between dequeue and peek
|
|
317
|
-
_a.sent();
|
|
318
|
-
return [4 /*yield*/, this.outbox.peek(storage)];
|
|
319
|
-
case 2:
|
|
320
|
-
hasMore = (_a.sent()) !== undefined;
|
|
321
|
-
return [2 /*return*/];
|
|
322
|
-
}
|
|
323
|
-
});
|
|
324
|
-
}); })];
|
|
325
|
-
case 8:
|
|
326
|
-
_f.sent();
|
|
327
|
-
(_c = (_b = this_1.observer) === null || _b === void 0 ? void 0 : _b.next) === null || _c === void 0 ? void 0 : _c.call(_b, {
|
|
328
|
-
operation: operation,
|
|
329
|
-
modelDefinition: modelDefinition,
|
|
330
|
-
model: record,
|
|
331
|
-
hasMore: hasMore,
|
|
332
|
-
});
|
|
333
|
-
return [2 /*return*/];
|
|
334
|
-
}
|
|
335
|
-
});
|
|
336
|
-
};
|
|
337
|
-
this_1 = this;
|
|
338
|
-
_d.label = 1;
|
|
339
|
-
case 1:
|
|
340
|
-
_a = this.processing &&
|
|
341
|
-
this.runningProcesses.isOpen;
|
|
342
|
-
if (!_a) return [3 /*break*/, 3];
|
|
343
|
-
return [4 /*yield*/, this.outbox.peek(this.storage)];
|
|
344
|
-
case 2:
|
|
345
|
-
_a = (head = _d.sent()) !== undefined;
|
|
346
|
-
_d.label = 3;
|
|
347
|
-
case 3:
|
|
348
|
-
if (!_a) return [3 /*break*/, 5];
|
|
349
|
-
return [5 /*yield**/, _loop_1()];
|
|
350
|
-
case 4:
|
|
351
|
-
_d.sent();
|
|
352
|
-
return [3 /*break*/, 1];
|
|
353
|
-
case 5:
|
|
354
|
-
// pauses itself
|
|
355
|
-
this.pause();
|
|
356
|
-
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;
|
|
85
|
+
}
|
|
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
|
+
});
|
|
357
130
|
}
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
131
|
+
catch (e) {
|
|
132
|
+
logger.error('Mutation error handler failed with:', e);
|
|
133
|
+
}
|
|
134
|
+
throw error;
|
|
135
|
+
}
|
|
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
|
+
});
|
|
364
169
|
}
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
attempt
|
|
424
|
-
|
|
425
|
-
if (!(attempt > MAX_ATTEMPTS)) return [3 /*break*/, 5];
|
|
426
|
-
retryWith = DISCARD;
|
|
427
|
-
return [3 /*break*/, 8];
|
|
428
|
-
case 5:
|
|
429
|
-
_j.trys.push([5, 7, , 8]);
|
|
430
|
-
return [4 /*yield*/, this.conflictHandler({
|
|
431
|
-
modelConstructor: modelConstructor,
|
|
432
|
-
localModel: this.modelInstanceCreator(modelConstructor, variables.input),
|
|
433
|
-
remoteModel: this.modelInstanceCreator(modelConstructor, error.data),
|
|
434
|
-
operation: opType,
|
|
435
|
-
attempts: attempt,
|
|
436
|
-
})];
|
|
437
|
-
case 6:
|
|
438
|
-
retryWith = _j.sent();
|
|
439
|
-
return [3 /*break*/, 8];
|
|
440
|
-
case 7:
|
|
441
|
-
err_2 = _j.sent();
|
|
442
|
-
logger.warn('conflict trycatch', err_2);
|
|
443
|
-
return [3 /*break*/, 17];
|
|
444
|
-
case 8:
|
|
445
|
-
if (!(retryWith === DISCARD)) return [3 /*break*/, 11];
|
|
446
|
-
_f = __read(buildGraphQLOperation(this.schema.namespaces[namespaceName], modelDefinition, 'GET'), 1), _g = __read(_f[0], 3), opName_1 = _g[1], query_1 = _g[2];
|
|
447
|
-
return [4 /*yield*/, getTokenForCustomAuth(authMode, this.amplifyConfig)];
|
|
448
|
-
case 9:
|
|
449
|
-
authToken_1 = _j.sent();
|
|
450
|
-
return [4 /*yield*/, this.amplifyContext.InternalAPI.graphql({
|
|
451
|
-
query: query_1,
|
|
452
|
-
variables: { id: variables.input.id },
|
|
453
|
-
authMode: authMode,
|
|
454
|
-
authToken: authToken_1,
|
|
455
|
-
}, undefined, customUserAgentDetails)];
|
|
456
|
-
case 10:
|
|
457
|
-
serverData = _j.sent();
|
|
458
|
-
// onTerminate cancel graphql()
|
|
459
|
-
return [2 /*return*/, [serverData, opName_1, modelDefinition]];
|
|
460
|
-
case 11:
|
|
461
|
-
namespace = this.schema.namespaces[namespaceName];
|
|
462
|
-
updatedMutation = createMutationInstanceFromModelOperation(namespace.relationships, modelDefinition, opType, modelConstructor, retryWith, graphQLCondition, MutationEvent, this.modelInstanceCreator, mutationEvent.id);
|
|
463
|
-
return [4 /*yield*/, this.storage.save(updatedMutation)];
|
|
464
|
-
case 12:
|
|
465
|
-
_j.sent();
|
|
466
|
-
throw new NonRetryableError('RetryMutation');
|
|
467
|
-
case 13:
|
|
468
|
-
try {
|
|
469
|
-
this.errorHandler({
|
|
470
|
-
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',
|
|
471
|
-
localModel: variables.input,
|
|
472
|
-
message: error.message,
|
|
473
|
-
operation: operation,
|
|
474
|
-
errorType: getMutationErrorType(error),
|
|
475
|
-
errorInfo: error.errorInfo,
|
|
476
|
-
process: ProcessName.mutate,
|
|
477
|
-
cause: error,
|
|
478
|
-
remoteModel: error.data
|
|
479
|
-
? this.modelInstanceCreator(modelConstructor, error.data)
|
|
480
|
-
: null,
|
|
481
|
-
});
|
|
482
|
-
}
|
|
483
|
-
catch (err) {
|
|
484
|
-
logger.warn('Mutation error handler failed with:', err);
|
|
485
|
-
}
|
|
486
|
-
finally {
|
|
487
|
-
// Return empty tuple, dequeues the mutation
|
|
488
|
-
return [2 /*return*/, error.data
|
|
489
|
-
? [
|
|
490
|
-
{ data: (_h = {}, _h[opName] = error.data, _h) },
|
|
491
|
-
opName,
|
|
492
|
-
modelDefinition,
|
|
493
|
-
]
|
|
494
|
-
: []];
|
|
495
|
-
}
|
|
496
|
-
_j.label = 14;
|
|
497
|
-
case 14: return [3 /*break*/, 16];
|
|
498
|
-
case 15:
|
|
499
|
-
// Catch-all for client-side errors that don't come back in the `GraphQLError` format.
|
|
500
|
-
// These errors should not be retried.
|
|
501
|
-
throw new NonRetryableError(err_1);
|
|
502
|
-
case 16: return [3 /*break*/, 17];
|
|
503
|
-
case 17:
|
|
504
|
-
if (tryWith) return [3 /*break*/, 2];
|
|
505
|
-
_j.label = 18;
|
|
506
|
-
case 18: return [2 /*return*/];
|
|
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 {
|
|
192
|
+
try {
|
|
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
|
+
});
|
|
507
230
|
}
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
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
|
+
}
|
|
519
291
|
}
|
|
520
|
-
});
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
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);
|
|
536
313
|
// include all the fields that comprise a custom PK if one is specified
|
|
537
|
-
|
|
314
|
+
const deleteInput = {};
|
|
538
315
|
if (primaryKey && primaryKey.length) {
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
var pkField = primaryKey_1_1.value;
|
|
542
|
-
deleteInput[pkField] = parsedData[pkField];
|
|
543
|
-
}
|
|
544
|
-
}
|
|
545
|
-
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
546
|
-
finally {
|
|
547
|
-
try {
|
|
548
|
-
if (primaryKey_1_1 && !primaryKey_1_1.done && (_a = primaryKey_1.return)) _a.call(primaryKey_1);
|
|
549
|
-
}
|
|
550
|
-
finally { if (e_2) throw e_2.error; }
|
|
316
|
+
for (const pkField of primaryKey) {
|
|
317
|
+
deleteInput[pkField] = parsedData[pkField];
|
|
551
318
|
}
|
|
552
319
|
}
|
|
553
320
|
else {
|
|
554
321
|
deleteInput[ID] = parsedData.id;
|
|
555
322
|
}
|
|
556
|
-
|
|
323
|
+
let mutationInput;
|
|
557
324
|
if (operation === TransformerMutationType.DELETE) {
|
|
558
325
|
// For DELETE mutations, only the key(s) are included in the input
|
|
559
326
|
mutationInput = deleteInput;
|
|
@@ -561,75 +328,61 @@ var MutationProcessor = /** @class */ (function () {
|
|
|
561
328
|
else {
|
|
562
329
|
// Otherwise, we construct the mutation input with the following logic
|
|
563
330
|
mutationInput = {};
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
//
|
|
577
|
-
if (
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
// instead of including the connected model itself, we add its key(s) to the mutation input
|
|
585
|
-
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()) {
|
|
586
|
-
var targetName = targetNames_1_1.value;
|
|
587
|
-
mutationInput[targetName] = parsedData[targetName];
|
|
588
|
-
}
|
|
589
|
-
}
|
|
590
|
-
catch (e_4_1) { e_4 = { error: e_4_1 }; }
|
|
591
|
-
finally {
|
|
592
|
-
try {
|
|
593
|
-
if (targetNames_1_1 && !targetNames_1_1.done && (_c = targetNames_1.return)) _c.call(targetNames_1);
|
|
594
|
-
}
|
|
595
|
-
finally { if (e_4) throw e_4.error; }
|
|
596
|
-
}
|
|
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];
|
|
597
351
|
}
|
|
598
352
|
}
|
|
599
|
-
continue;
|
|
600
|
-
}
|
|
601
|
-
// scalar fields / non-model types
|
|
602
|
-
if (operation === TransformerMutationType.UPDATE) {
|
|
603
|
-
if (!parsedData.hasOwnProperty(name_1)) {
|
|
604
|
-
// for update mutations - strip out a field if it's unchanged
|
|
605
|
-
continue;
|
|
606
|
-
}
|
|
607
353
|
}
|
|
608
|
-
|
|
609
|
-
mutationInput[name_1] = parsedData[name_1];
|
|
354
|
+
continue;
|
|
610
355
|
}
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
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
|
+
}
|
|
616
362
|
}
|
|
617
|
-
|
|
363
|
+
// all other fields are added to the input object
|
|
364
|
+
mutationInput[name] = parsedData[name];
|
|
618
365
|
}
|
|
619
366
|
}
|
|
620
367
|
// Build mutation variables input object
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
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
|
+
};
|
|
630
383
|
return [query, variables, graphQLCondition, opName, modelDefinition];
|
|
631
|
-
}
|
|
632
|
-
|
|
384
|
+
}
|
|
385
|
+
opTypeFromTransformerOperation(operation) {
|
|
633
386
|
switch (operation) {
|
|
634
387
|
case TransformerMutationType.CREATE:
|
|
635
388
|
return OpType.INSERT;
|
|
@@ -640,18 +393,17 @@ var MutationProcessor = /** @class */ (function () {
|
|
|
640
393
|
case TransformerMutationType.GET: // Intentionally blank
|
|
641
394
|
break;
|
|
642
395
|
default:
|
|
643
|
-
throw new Error(
|
|
396
|
+
throw new Error(`Invalid operation ${operation}`);
|
|
644
397
|
}
|
|
645
398
|
// because it makes TS happy ...
|
|
646
399
|
return undefined;
|
|
647
|
-
}
|
|
648
|
-
|
|
400
|
+
}
|
|
401
|
+
pause() {
|
|
649
402
|
this.processing = false;
|
|
650
|
-
}
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
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);
|
|
655
407
|
/**
|
|
656
408
|
* @private
|
|
657
409
|
* Internal use of Amplify only.
|
|
@@ -667,8 +419,8 @@ var originalJitteredBackoff = jitteredBackoff(MAX_RETRY_DELAY_MS);
|
|
|
667
419
|
* @param error tested to see if `.message` is 'Network Error'
|
|
668
420
|
* @returns number | false :
|
|
669
421
|
*/
|
|
670
|
-
export
|
|
671
|
-
|
|
422
|
+
export const safeJitteredBackoff = (attempt, _args, error) => {
|
|
423
|
+
const attemptResult = originalJitteredBackoff(attempt);
|
|
672
424
|
// If this is the last attempt and it is a network error, we retry indefinitively every 5 minutes
|
|
673
425
|
if (attemptResult === false &&
|
|
674
426
|
(error || {}).message === 'Network Error') {
|