@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.
Files changed (70) hide show
  1. package/lib/authModeStrategies/defaultAuthStrategy.js +1 -1
  2. package/lib/authModeStrategies/multiAuthStrategy.js +29 -105
  3. package/lib/datastore/datastore.js +887 -1370
  4. package/lib/index.js +1 -1
  5. package/lib/predicates/index.js +53 -102
  6. package/lib/predicates/next.js +310 -557
  7. package/lib/predicates/sort.js +24 -27
  8. package/lib/ssr/index.js +1 -1
  9. package/lib/storage/adapter/AsyncStorageAdapter.js +115 -449
  10. package/lib/storage/adapter/AsyncStorageDatabase.js +215 -480
  11. package/lib/storage/adapter/InMemoryStore.js +27 -101
  12. package/lib/storage/adapter/InMemoryStore.native.js +1 -1
  13. package/lib/storage/adapter/IndexedDBAdapter.js +441 -1002
  14. package/lib/storage/adapter/StorageAdapterBase.js +177 -396
  15. package/lib/storage/adapter/getDefaultAdapter/index.js +5 -6
  16. package/lib/storage/adapter/getDefaultAdapter/index.native.js +2 -2
  17. package/lib/storage/relationship.js +174 -260
  18. package/lib/storage/storage.js +244 -507
  19. package/lib/sync/datastoreConnectivity.js +29 -84
  20. package/lib/sync/datastoreReachability/index.js +1 -1
  21. package/lib/sync/datastoreReachability/index.native.js +2 -2
  22. package/lib/sync/index.js +512 -885
  23. package/lib/sync/merger.js +30 -133
  24. package/lib/sync/outbox.js +147 -302
  25. package/lib/sync/processors/errorMaps.js +30 -80
  26. package/lib/sync/processors/mutation.js +331 -579
  27. package/lib/sync/processors/subscription.js +268 -428
  28. package/lib/sync/processors/sync.js +276 -464
  29. package/lib/sync/utils.js +248 -393
  30. package/lib/tsconfig.tsbuildinfo +1 -1
  31. package/lib/types.js +16 -58
  32. package/lib/util.js +335 -575
  33. package/lib-esm/authModeStrategies/defaultAuthStrategy.js +1 -1
  34. package/lib-esm/authModeStrategies/multiAuthStrategy.js +27 -103
  35. package/lib-esm/datastore/datastore.js +874 -1359
  36. package/lib-esm/index.js +6 -6
  37. package/lib-esm/predicates/index.js +54 -104
  38. package/lib-esm/predicates/next.js +306 -555
  39. package/lib-esm/predicates/sort.js +24 -27
  40. package/lib-esm/ssr/index.js +1 -1
  41. package/lib-esm/storage/adapter/AsyncStorageAdapter.js +111 -446
  42. package/lib-esm/storage/adapter/AsyncStorageDatabase.js +212 -477
  43. package/lib-esm/storage/adapter/InMemoryStore.js +27 -102
  44. package/lib-esm/storage/adapter/IndexedDBAdapter.js +436 -997
  45. package/lib-esm/storage/adapter/StorageAdapterBase.js +172 -392
  46. package/lib-esm/storage/adapter/getDefaultAdapter/index.js +2 -3
  47. package/lib-esm/storage/adapter/getDefaultAdapter/index.native.js +1 -1
  48. package/lib-esm/storage/relationship.js +173 -260
  49. package/lib-esm/storage/storage.js +236 -499
  50. package/lib-esm/sync/datastoreConnectivity.js +26 -82
  51. package/lib-esm/sync/datastoreReachability/index.js +1 -1
  52. package/lib-esm/sync/datastoreReachability/index.native.js +1 -1
  53. package/lib-esm/sync/index.js +498 -872
  54. package/lib-esm/sync/merger.js +28 -131
  55. package/lib-esm/sync/outbox.js +143 -298
  56. package/lib-esm/sync/processors/errorMaps.js +32 -82
  57. package/lib-esm/sync/processors/mutation.js +324 -572
  58. package/lib-esm/sync/processors/subscription.js +258 -418
  59. package/lib-esm/sync/processors/sync.js +269 -457
  60. package/lib-esm/sync/utils.js +245 -390
  61. package/lib-esm/tsconfig.tsbuildinfo +1 -1
  62. package/lib-esm/types.js +16 -59
  63. package/lib-esm/util.js +335 -577
  64. package/package.json +12 -12
  65. package/src/datastore/datastore.ts +4 -3
  66. package/src/storage/adapter/getDefaultAdapter/index.ts +1 -3
  67. package/src/sync/processors/mutation.ts +1 -1
  68. package/src/sync/processors/sync.ts +1 -1
  69. package/src/sync/utils.ts +1 -1
  70. package/src/util.ts +44 -6
@@ -1,89 +1,17 @@
1
1
  "use strict";
2
- var __assign = (this && this.__assign) || function () {
3
- __assign = Object.assign || function(t) {
4
- for (var s, i = 1, n = arguments.length; i < n; i++) {
5
- s = arguments[i];
6
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
- t[p] = s[p];
8
- }
9
- return t;
10
- };
11
- return __assign.apply(this, arguments);
12
- };
13
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
14
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
15
- return new (P || (P = Promise))(function (resolve, reject) {
16
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
17
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
18
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
19
- step((generator = generator.apply(thisArg, _arguments || [])).next());
20
- });
21
- };
22
- var __generator = (this && this.__generator) || function (thisArg, body) {
23
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
24
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
25
- function verb(n) { return function (v) { return step([n, v]); }; }
26
- function step(op) {
27
- if (f) throw new TypeError("Generator is already executing.");
28
- while (g && (g = 0, op[0] && (_ = 0)), _) try {
29
- 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;
30
- if (y = 0, t) op = [op[0] & 2, t.value];
31
- switch (op[0]) {
32
- case 0: case 1: t = op; break;
33
- case 4: _.label++; return { value: op[1], done: false };
34
- case 5: _.label++; y = op[1]; op = [0]; continue;
35
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
36
- default:
37
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
38
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
39
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
40
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
41
- if (t[2]) _.ops.pop();
42
- _.trys.pop(); continue;
43
- }
44
- op = body.call(thisArg, _);
45
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
46
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
47
- }
48
- };
49
- var __read = (this && this.__read) || function (o, n) {
50
- var m = typeof Symbol === "function" && o[Symbol.iterator];
51
- if (!m) return o;
52
- var i = m.call(o), r, ar = [], e;
53
- try {
54
- while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
55
- }
56
- catch (error) { e = { error: error }; }
57
- finally {
58
- try {
59
- if (r && !r.done && (m = i["return"])) m.call(i);
60
- }
61
- finally { if (e) throw e.error; }
62
- }
63
- return ar;
64
- };
65
- var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
66
- if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
67
- if (ar || !(i in from)) {
68
- if (!ar) ar = Array.prototype.slice.call(from, 0, i);
69
- ar[i] = from[i];
70
- }
71
- }
72
- return to.concat(ar || Array.prototype.slice.call(from));
73
- };
74
2
  Object.defineProperty(exports, "__esModule", { value: true });
75
3
  exports.SubscriptionProcessor = exports.USER_CREDENTIALS = exports.CONTROL_MSG = void 0;
76
- var internals_1 = require("@aws-amplify/api/internals");
77
- var core_1 = require("@aws-amplify/core");
78
- var utils_1 = require("@aws-amplify/core/internals/utils");
79
- var rxjs_1 = require("rxjs");
80
- var types_1 = require("../../types");
81
- var utils_2 = require("../utils");
82
- var predicates_1 = require("../../predicates");
83
- var util_1 = require("../../util");
84
- var errorMaps_1 = require("./errorMaps");
85
- var api_graphql_1 = require("@aws-amplify/api-graphql");
86
- var logger = new core_1.ConsoleLogger('DataStore');
4
+ const internals_1 = require("@aws-amplify/api/internals");
5
+ const core_1 = require("@aws-amplify/core");
6
+ const utils_1 = require("@aws-amplify/core/internals/utils");
7
+ const rxjs_1 = require("rxjs");
8
+ const types_1 = require("../../types");
9
+ const utils_2 = require("../utils");
10
+ const predicates_1 = require("../../predicates");
11
+ const util_1 = require("../../util");
12
+ const errorMaps_1 = require("./errorMaps");
13
+ const api_graphql_1 = require("@aws-amplify/api-graphql");
14
+ const logger = new core_1.ConsoleLogger('DataStore');
87
15
  var CONTROL_MSG;
88
16
  (function (CONTROL_MSG) {
89
17
  CONTROL_MSG["CONNECTED"] = "CONNECTED";
@@ -94,12 +22,10 @@ var USER_CREDENTIALS;
94
22
  USER_CREDENTIALS[USER_CREDENTIALS["unauth"] = 1] = "unauth";
95
23
  USER_CREDENTIALS[USER_CREDENTIALS["auth"] = 2] = "auth";
96
24
  })(USER_CREDENTIALS = exports.USER_CREDENTIALS || (exports.USER_CREDENTIALS = {}));
97
- var SubscriptionProcessor = /** @class */ (function () {
98
- function SubscriptionProcessor(schema, syncPredicates, amplifyConfig, authModeStrategy, errorHandler, amplifyContext) {
99
- if (amplifyConfig === void 0) { amplifyConfig = {}; }
100
- if (amplifyContext === void 0) { amplifyContext = {
101
- InternalAPI: internals_1.InternalAPI,
102
- }; }
25
+ class SubscriptionProcessor {
26
+ constructor(schema, syncPredicates, amplifyConfig = {}, authModeStrategy, errorHandler, amplifyContext = {
27
+ InternalAPI: internals_1.InternalAPI,
28
+ }) {
103
29
  this.schema = schema;
104
30
  this.syncPredicates = syncPredicates;
105
31
  this.amplifyConfig = amplifyConfig;
@@ -110,18 +36,17 @@ var SubscriptionProcessor = /** @class */ (function () {
110
36
  this.buffer = [];
111
37
  this.runningProcesses = new utils_1.BackgroundProcessManager();
112
38
  }
113
- SubscriptionProcessor.prototype.buildSubscription = function (namespace, model, transformerMutationType, userCredentials, oidcTokenPayload, authMode, filterArg) {
114
- if (filterArg === void 0) { filterArg = false; }
115
- var aws_appsync_authenticationType = this.amplifyConfig.aws_appsync_authenticationType;
116
- var _a = this.getAuthorizationInfo(model, userCredentials, aws_appsync_authenticationType, oidcTokenPayload, authMode) || {}, isOwner = _a.isOwner, ownerField = _a.ownerField, ownerValue = _a.ownerValue;
117
- var _b = __read((0, utils_2.buildSubscriptionGraphQLOperation)(namespace, model, transformerMutationType, isOwner, ownerField, filterArg), 3), opType = _b[0], opName = _b[1], query = _b[2];
118
- return { authMode: authMode, opType: opType, opName: opName, query: query, isOwner: isOwner, ownerField: ownerField, ownerValue: ownerValue };
119
- };
120
- SubscriptionProcessor.prototype.getAuthorizationInfo = function (model, userCredentials, defaultAuthType, oidcTokenPayload, authMode) {
121
- var rules = (0, utils_2.getAuthorizationRules)(model);
39
+ buildSubscription(namespace, model, transformerMutationType, userCredentials, oidcTokenPayload, authMode, filterArg = false) {
40
+ const { aws_appsync_authenticationType } = this.amplifyConfig;
41
+ const { isOwner, ownerField, ownerValue } = this.getAuthorizationInfo(model, userCredentials, aws_appsync_authenticationType, oidcTokenPayload, authMode) || {};
42
+ const [opType, opName, query] = (0, utils_2.buildSubscriptionGraphQLOperation)(namespace, model, transformerMutationType, isOwner, ownerField, filterArg);
43
+ return { authMode, opType, opName, query, isOwner, ownerField, ownerValue };
44
+ }
45
+ getAuthorizationInfo(model, userCredentials, defaultAuthType, oidcTokenPayload, authMode) {
46
+ const rules = (0, utils_2.getAuthorizationRules)(model);
122
47
  // Return null if user doesn't have proper credentials for private API with IAM auth
123
- var iamPrivateAuth = authMode === 'iam' &&
124
- rules.find(function (rule) { return rule.authStrategy === 'private' && rule.provider === 'iam'; });
48
+ const iamPrivateAuth = authMode === 'iam' &&
49
+ rules.find(rule => rule.authStrategy === 'private' && rule.provider === 'iam');
125
50
  if (iamPrivateAuth && userCredentials === USER_CREDENTIALS.unauth) {
126
51
  return null;
127
52
  }
@@ -129,47 +54,42 @@ var SubscriptionProcessor = /** @class */ (function () {
129
54
  // if rule(s) have group authorization as well as if either the Cognito or
130
55
  // OIDC token has a groupClaim. If so, we are returning auth info before
131
56
  // any further owner-based auth checks.
132
- var groupAuthRules = rules.filter(function (rule) {
133
- return rule.authStrategy === 'groups' &&
134
- ['userPools', 'oidc'].includes(rule.provider);
135
- });
136
- var validGroup = (authMode === 'oidc' || authMode === 'userPool') &&
137
- groupAuthRules.find(function (groupAuthRule) {
57
+ const groupAuthRules = rules.filter(rule => rule.authStrategy === 'groups' &&
58
+ ['userPools', 'oidc'].includes(rule.provider));
59
+ const validGroup = (authMode === 'oidc' || authMode === 'userPool') &&
60
+ groupAuthRules.find(groupAuthRule => {
138
61
  // validate token against groupClaim
139
62
  if (oidcTokenPayload) {
140
- var oidcUserGroups = (0, utils_2.getUserGroupsFromToken)(oidcTokenPayload, groupAuthRule);
141
- return __spreadArray([], __read(oidcUserGroups), false).find(function (userGroup) {
142
- return groupAuthRule.groups.find(function (group) { return group === userGroup; });
63
+ const oidcUserGroups = (0, utils_2.getUserGroupsFromToken)(oidcTokenPayload, groupAuthRule);
64
+ return [...oidcUserGroups].find(userGroup => {
65
+ return groupAuthRule.groups.find(group => group === userGroup);
143
66
  });
144
67
  }
145
68
  });
146
69
  if (validGroup) {
147
70
  return {
148
- authMode: authMode,
71
+ authMode,
149
72
  isOwner: false,
150
73
  };
151
74
  }
152
- var ownerAuthInfo;
75
+ let ownerAuthInfo;
153
76
  if (ownerAuthInfo) {
154
77
  return ownerAuthInfo;
155
78
  }
156
79
  // Owner auth needs additional values to be returned in order to create the subscription with
157
80
  // the correct parameters so we are getting the owner value from the OIDC token via the
158
81
  // identityClaim from the auth rule.
159
- var oidcOwnerAuthRules = authMode === 'oidc' || authMode === 'userPool'
160
- ? rules.filter(function (rule) {
161
- return rule.authStrategy === 'owner' &&
162
- (rule.provider === 'oidc' || rule.provider === 'userPools');
163
- })
82
+ const oidcOwnerAuthRules = authMode === 'oidc' || authMode === 'userPool'
83
+ ? rules.filter(rule => rule.authStrategy === 'owner' &&
84
+ (rule.provider === 'oidc' || rule.provider === 'userPools'))
164
85
  : [];
165
- oidcOwnerAuthRules.forEach(function (ownerAuthRule) {
166
- var _a;
167
- var ownerValue = oidcTokenPayload[ownerAuthRule.identityClaim];
168
- var singleOwner = ((_a = model.fields[ownerAuthRule.ownerField]) === null || _a === void 0 ? void 0 : _a.isArray) !== true;
169
- var isOwnerArgRequired = singleOwner && !ownerAuthRule.areSubscriptionsPublic;
86
+ oidcOwnerAuthRules.forEach(ownerAuthRule => {
87
+ const ownerValue = oidcTokenPayload[ownerAuthRule.identityClaim];
88
+ const singleOwner = model.fields[ownerAuthRule.ownerField]?.isArray !== true;
89
+ const isOwnerArgRequired = singleOwner && !ownerAuthRule.areSubscriptionsPublic;
170
90
  if (ownerValue) {
171
91
  ownerAuthInfo = {
172
- authMode: authMode,
92
+ authMode,
173
93
  isOwner: isOwnerArgRequired,
174
94
  ownerField: ownerAuthRule.ownerField,
175
95
  ownerValue: String(ownerValue),
@@ -184,331 +104,255 @@ var SubscriptionProcessor = /** @class */ (function () {
184
104
  authMode: authMode || defaultAuthType,
185
105
  isOwner: false,
186
106
  };
187
- };
188
- SubscriptionProcessor.prototype.hubQueryCompletionListener = function (completed, capsule) {
189
- var event = capsule.payload.event;
107
+ }
108
+ hubQueryCompletionListener(completed, capsule) {
109
+ const { payload: { event }, } = capsule;
190
110
  if (event === api_graphql_1.CONTROL_MSG.SUBSCRIPTION_ACK) {
191
111
  completed();
192
112
  }
193
- };
194
- SubscriptionProcessor.prototype.start = function () {
195
- var _this = this;
113
+ }
114
+ start() {
196
115
  this.runningProcesses =
197
116
  this.runningProcesses || new utils_1.BackgroundProcessManager();
198
- var ctlObservable = new rxjs_1.Observable(function (observer) {
199
- var promises = [];
117
+ const ctlObservable = new rxjs_1.Observable(observer => {
118
+ const promises = [];
200
119
  // Creating subs for each model/operation combo so they can be unsubscribed
201
120
  // independently, since the auth retry behavior is asynchronous.
202
- var subscriptions = {};
203
- var oidcTokenPayload;
204
- var userCredentials = USER_CREDENTIALS.none;
205
- _this.runningProcesses.add(function () { return __awaiter(_this, void 0, void 0, function () {
206
- var credentials, err_1, session, err_2;
207
- var _this = this;
208
- var _a, _b, _c;
209
- return __generator(this, function (_d) {
210
- switch (_d.label) {
211
- case 0:
212
- _d.trys.push([0, 2, , 3]);
213
- return [4 /*yield*/, (0, core_1.fetchAuthSession)()];
214
- case 1:
215
- credentials = (_a = (_d.sent()).tokens) === null || _a === void 0 ? void 0 : _a.accessToken;
216
- userCredentials = credentials
217
- ? USER_CREDENTIALS.auth
218
- : USER_CREDENTIALS.unauth;
219
- return [3 /*break*/, 3];
220
- case 2:
221
- err_1 = _d.sent();
222
- return [3 /*break*/, 3];
223
- case 3:
224
- _d.trys.push([3, 6, , 7]);
225
- return [4 /*yield*/, (0, core_1.fetchAuthSession)()];
226
- case 4: return [4 /*yield*/, _d.sent()];
227
- case 5:
228
- session = _d.sent();
229
- oidcTokenPayload = (_c = (_b = session.tokens) === null || _b === void 0 ? void 0 : _b.idToken) === null || _c === void 0 ? void 0 : _c.payload;
230
- return [3 /*break*/, 7];
231
- case 6:
232
- err_2 = _d.sent();
233
- return [3 /*break*/, 7];
234
- case 7:
235
- Object.values(this.schema.namespaces).forEach(function (namespace) {
236
- Object.values(namespace.models)
237
- .filter(function (_a) {
238
- var syncable = _a.syncable;
239
- return syncable;
240
- })
241
- .forEach(function (modelDefinition) {
242
- return _this.runningProcesses.isOpen &&
243
- _this.runningProcesses.add(function () { return __awaiter(_this, void 0, void 0, function () {
244
- var modelAuthModes, readAuthModes, operations, operationAuthModeAttempts, predicatesGroup, addFilterArg, subscriptionRetry;
245
- var _a, _b, _c;
246
- var _this = this;
247
- return __generator(this, function (_d) {
248
- switch (_d.label) {
249
- case 0: return [4 /*yield*/, (0, utils_2.getModelAuthModes)({
250
- authModeStrategy: this.authModeStrategy,
251
- defaultAuthMode: this.amplifyConfig.aws_appsync_authenticationType,
252
- modelName: modelDefinition.name,
253
- schema: this.schema,
254
- })];
255
- case 1:
256
- modelAuthModes = _d.sent();
257
- readAuthModes = modelAuthModes.READ;
258
- subscriptions = __assign(__assign({}, subscriptions), (_a = {}, _a[modelDefinition.name] = (_b = {},
259
- _b[utils_2.TransformerMutationType.CREATE] = [],
260
- _b[utils_2.TransformerMutationType.UPDATE] = [],
261
- _b[utils_2.TransformerMutationType.DELETE] = [],
262
- _b), _a));
263
- operations = [
264
- utils_2.TransformerMutationType.CREATE,
265
- utils_2.TransformerMutationType.UPDATE,
266
- utils_2.TransformerMutationType.DELETE,
267
- ];
268
- operationAuthModeAttempts = (_c = {},
269
- _c[utils_2.TransformerMutationType.CREATE] = 0,
270
- _c[utils_2.TransformerMutationType.UPDATE] = 0,
271
- _c[utils_2.TransformerMutationType.DELETE] = 0,
272
- _c);
273
- predicatesGroup = predicates_1.ModelPredicateCreator.getPredicates(this.syncPredicates.get(modelDefinition), false);
274
- addFilterArg = predicatesGroup !== undefined;
275
- subscriptionRetry = function (operation, addFilter) {
276
- if (addFilter === void 0) { addFilter = addFilterArg; }
277
- return __awaiter(_this, void 0, void 0, function () {
278
- var _a, transformerMutationType, opName, query, isOwner, ownerField, ownerValue, authMode, authToken, variables, customUserAgentDetails, queryObservable, subscriptionReadyCallback;
279
- var _this = this;
280
- return __generator(this, function (_b) {
281
- switch (_b.label) {
282
- case 0:
283
- _a = this.buildSubscription(namespace, modelDefinition, operation, userCredentials, oidcTokenPayload, readAuthModes[operationAuthModeAttempts[operation]], addFilter), transformerMutationType = _a.opType, opName = _a.opName, query = _a.query, isOwner = _a.isOwner, ownerField = _a.ownerField, ownerValue = _a.ownerValue, authMode = _a.authMode;
284
- return [4 /*yield*/, (0, utils_2.getTokenForCustomAuth)(authMode, this.amplifyConfig)];
285
- case 1:
286
- authToken = _b.sent();
287
- variables = {};
288
- customUserAgentDetails = {
289
- category: utils_1.Category.DataStore,
290
- action: utils_1.DataStoreAction.Subscribe,
291
- };
292
- if (addFilter && predicatesGroup) {
293
- variables['filter'] =
294
- (0, utils_2.predicateToGraphQLFilter)(predicatesGroup);
295
- }
296
- if (isOwner) {
297
- if (!ownerValue) {
298
- observer.error('Owner field required, sign in is needed in order to perform this operation');
299
- return [2 /*return*/];
300
- }
301
- variables[ownerField] = ownerValue;
302
- }
303
- logger.debug("Attempting ".concat(operation, " subscription with authMode: ").concat(readAuthModes[operationAuthModeAttempts[operation]]));
304
- queryObservable = this.amplifyContext.InternalAPI.graphql(__assign(__assign({ query: query, variables: variables }, { authMode: authMode }), { authToken: authToken }), undefined, customUserAgentDetails);
305
- // TODO: consider onTerminate.then(() => API.cancel(...))
306
- subscriptions[modelDefinition.name][transformerMutationType].push(queryObservable.subscribe({
307
- next: function (result) {
308
- var data = result.data, errors = result.errors;
309
- if (Array.isArray(errors) && errors.length > 0) {
310
- var messages = errors.map(function (_a) {
311
- var message = _a.message;
312
- return message;
313
- });
314
- logger.warn("Skipping incoming subscription. Messages: ".concat(messages.join('\n')));
315
- _this.drainBuffer();
316
- return;
317
- }
318
- var predicatesGroup = predicates_1.ModelPredicateCreator.getPredicates(_this.syncPredicates.get(modelDefinition), false);
319
- // @ts-ignore
320
- var _a = data, _b = opName, record = _a[_b];
321
- // checking incoming subscription against syncPredicate.
322
- // once AppSync implements filters on subscriptions, we'll be
323
- // able to set these when establishing the subscription instead.
324
- // Until then, we'll need to filter inbound
325
- if (_this.passesPredicateValidation(record, predicatesGroup)) {
326
- _this.pushToBuffer(transformerMutationType, modelDefinition, record);
327
- }
328
- _this.drainBuffer();
329
- },
330
- error: function (subscriptionError) { return __awaiter(_this, void 0, void 0, function () {
331
- var _a, _b, _c, _d, message, isRTFError, e_1;
332
- var _e;
333
- return __generator(this, function (_f) {
334
- switch (_f.label) {
335
- case 0:
336
- _a = __read((_e = __read(subscriptionError.errors, 0), subscriptionError).errors, 1), _b = _a[0], _c = _b === void 0 ? {} : _b, _d = _c.message, message = _d === void 0 ? '' : _d;
337
- isRTFError =
338
- // only attempt catch if a filter variable was added to the subscription query
339
- addFilter &&
340
- this.catchRTFError(message, modelDefinition, predicatesGroup);
341
- // Catch RTF errors
342
- if (isRTFError) {
343
- // Unsubscribe and clear subscription array for model/operation
344
- subscriptions[modelDefinition.name][transformerMutationType].forEach(function (subscription) {
345
- return subscription.unsubscribe();
346
- });
347
- subscriptions[modelDefinition.name][transformerMutationType] = [];
348
- // retry subscription connection without filter
349
- subscriptionRetry(operation, false);
350
- return [2 /*return*/];
351
- }
352
- if (message.includes(api_graphql_1.CONTROL_MSG.REALTIME_SUBSCRIPTION_INIT_ERROR) ||
353
- message.includes(api_graphql_1.CONTROL_MSG.CONNECTION_FAILED)) {
354
- // Unsubscribe and clear subscription array for model/operation
355
- subscriptions[modelDefinition.name][transformerMutationType].forEach(function (subscription) {
356
- return subscription.unsubscribe();
357
- });
358
- subscriptions[modelDefinition.name][transformerMutationType] = [];
359
- operationAuthModeAttempts[operation]++;
360
- if (operationAuthModeAttempts[operation] >=
361
- readAuthModes.length) {
362
- // last auth mode retry. Continue with error
363
- logger.debug("".concat(operation, " subscription failed with authMode: ").concat(readAuthModes[operationAuthModeAttempts[operation] - 1]));
364
- }
365
- else {
366
- // retry with different auth mode. Do not trigger
367
- // observer error or error handler
368
- logger.debug("".concat(operation, " subscription failed with authMode: ").concat(readAuthModes[operationAuthModeAttempts[operation] - 1], ". Retrying with authMode: ").concat(readAuthModes[operationAuthModeAttempts[operation]]));
369
- subscriptionRetry(operation);
370
- return [2 /*return*/];
371
- }
372
- }
373
- logger.warn('subscriptionError', message);
374
- _f.label = 1;
375
- case 1:
376
- _f.trys.push([1, 3, , 4]);
377
- return [4 /*yield*/, this.errorHandler({
378
- 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',
379
- localModel: null,
380
- message: message,
381
- model: modelDefinition.name,
382
- operation: operation,
383
- errorType: (0, errorMaps_1.getSubscriptionErrorType)(subscriptionError),
384
- process: types_1.ProcessName.subscribe,
385
- remoteModel: null,
386
- cause: subscriptionError,
387
- })];
388
- case 2:
389
- _f.sent();
390
- return [3 /*break*/, 4];
391
- case 3:
392
- e_1 = _f.sent();
393
- logger.error('Subscription error handler failed with:', e_1);
394
- return [3 /*break*/, 4];
395
- case 4:
396
- if (typeof subscriptionReadyCallback === 'function') {
397
- subscriptionReadyCallback();
398
- }
399
- if (message.includes('"errorType":"Unauthorized"') ||
400
- message.includes('"errorType":"OperationDisabled"')) {
401
- return [2 /*return*/];
402
- }
403
- observer.error(message);
404
- return [2 /*return*/];
405
- }
406
- });
407
- }); },
408
- }));
409
- promises.push((function () { return __awaiter(_this, void 0, void 0, function () {
410
- var boundFunction, removeBoundFunctionListener;
411
- var _this = this;
412
- return __generator(this, function (_a) {
413
- switch (_a.label) {
414
- case 0: return [4 /*yield*/, new Promise(function (res) {
415
- subscriptionReadyCallback = res;
416
- boundFunction = _this.hubQueryCompletionListener.bind(_this, res);
417
- removeBoundFunctionListener = core_1.Hub.listen('api', boundFunction);
418
- })];
419
- case 1:
420
- _a.sent();
421
- removeBoundFunctionListener();
422
- return [2 /*return*/];
423
- }
424
- });
425
- }); })());
426
- return [2 /*return*/];
427
- }
428
- });
429
- });
430
- };
431
- operations.forEach(function (op) { return subscriptionRetry(op); });
432
- return [2 /*return*/];
433
- }
434
- });
435
- }); });
436
- });
121
+ let subscriptions = {};
122
+ let oidcTokenPayload;
123
+ let userCredentials = USER_CREDENTIALS.none;
124
+ this.runningProcesses.add(async () => {
125
+ try {
126
+ // retrieving current AWS Credentials
127
+ const credentials = (await (0, core_1.fetchAuthSession)()).tokens?.accessToken;
128
+ userCredentials = credentials
129
+ ? USER_CREDENTIALS.auth
130
+ : USER_CREDENTIALS.unauth;
131
+ }
132
+ catch (err) {
133
+ // best effort to get AWS credentials
134
+ }
135
+ try {
136
+ // retrieving current token info from Cognito UserPools
137
+ const session = await await (0, core_1.fetchAuthSession)();
138
+ oidcTokenPayload = session.tokens?.idToken?.payload;
139
+ }
140
+ catch (err) {
141
+ // best effort to get jwt from Cognito
142
+ }
143
+ Object.values(this.schema.namespaces).forEach(namespace => {
144
+ Object.values(namespace.models)
145
+ .filter(({ syncable }) => syncable)
146
+ .forEach(modelDefinition => this.runningProcesses.isOpen &&
147
+ this.runningProcesses.add(async () => {
148
+ const modelAuthModes = await (0, utils_2.getModelAuthModes)({
149
+ authModeStrategy: this.authModeStrategy,
150
+ defaultAuthMode: this.amplifyConfig.aws_appsync_authenticationType,
151
+ modelName: modelDefinition.name,
152
+ schema: this.schema,
437
153
  });
438
- this.runningProcesses.isOpen &&
439
- this.runningProcesses.add(function () {
440
- return Promise.all(promises).then(function () {
441
- observer.next(CONTROL_MSG.CONNECTED);
154
+ // subscriptions are created only based on the READ auth mode(s)
155
+ const readAuthModes = modelAuthModes.READ;
156
+ subscriptions = {
157
+ ...subscriptions,
158
+ [modelDefinition.name]: {
159
+ [utils_2.TransformerMutationType.CREATE]: [],
160
+ [utils_2.TransformerMutationType.UPDATE]: [],
161
+ [utils_2.TransformerMutationType.DELETE]: [],
162
+ },
163
+ };
164
+ const operations = [
165
+ utils_2.TransformerMutationType.CREATE,
166
+ utils_2.TransformerMutationType.UPDATE,
167
+ utils_2.TransformerMutationType.DELETE,
168
+ ];
169
+ const operationAuthModeAttempts = {
170
+ [utils_2.TransformerMutationType.CREATE]: 0,
171
+ [utils_2.TransformerMutationType.UPDATE]: 0,
172
+ [utils_2.TransformerMutationType.DELETE]: 0,
173
+ };
174
+ const predicatesGroup = predicates_1.ModelPredicateCreator.getPredicates(this.syncPredicates.get(modelDefinition), false);
175
+ const addFilterArg = predicatesGroup !== undefined;
176
+ // Retry subscriptions that failed for one of the following reasons:
177
+ // 1. unauthorized - retry with next auth mode (if available)
178
+ // 2. RTF error - retry without sending filter arg. (filtering will fall back to clientside)
179
+ const subscriptionRetry = async (operation, addFilter = addFilterArg) => {
180
+ const { opType: transformerMutationType, opName, query, isOwner, ownerField, ownerValue, authMode, } = this.buildSubscription(namespace, modelDefinition, operation, userCredentials, oidcTokenPayload, readAuthModes[operationAuthModeAttempts[operation]], addFilter);
181
+ const authToken = await (0, utils_2.getTokenForCustomAuth)(authMode, this.amplifyConfig);
182
+ const variables = {};
183
+ const customUserAgentDetails = {
184
+ category: utils_1.Category.DataStore,
185
+ action: utils_1.DataStoreAction.Subscribe,
186
+ };
187
+ if (addFilter && predicatesGroup) {
188
+ variables['filter'] =
189
+ (0, utils_2.predicateToGraphQLFilter)(predicatesGroup);
190
+ }
191
+ if (isOwner) {
192
+ if (!ownerValue) {
193
+ observer.error('Owner field required, sign in is needed in order to perform this operation');
194
+ return;
195
+ }
196
+ variables[ownerField] = ownerValue;
197
+ }
198
+ logger.debug(`Attempting ${operation} subscription with authMode: ${readAuthModes[operationAuthModeAttempts[operation]]}`);
199
+ const queryObservable = this.amplifyContext.InternalAPI.graphql({
200
+ query,
201
+ variables,
202
+ ...{ authMode },
203
+ authToken,
204
+ }, undefined, customUserAgentDetails);
205
+ let subscriptionReadyCallback;
206
+ // TODO: consider onTerminate.then(() => API.cancel(...))
207
+ subscriptions[modelDefinition.name][transformerMutationType].push(queryObservable.subscribe({
208
+ next: result => {
209
+ const { data, errors } = result;
210
+ if (Array.isArray(errors) && errors.length > 0) {
211
+ const messages = errors.map(({ message }) => message);
212
+ logger.warn(`Skipping incoming subscription. Messages: ${messages.join('\n')}`);
213
+ this.drainBuffer();
214
+ return;
215
+ }
216
+ const predicatesGroup = predicates_1.ModelPredicateCreator.getPredicates(this.syncPredicates.get(modelDefinition), false);
217
+ // @ts-ignore
218
+ const { [opName]: record } = data;
219
+ // checking incoming subscription against syncPredicate.
220
+ // once AppSync implements filters on subscriptions, we'll be
221
+ // able to set these when establishing the subscription instead.
222
+ // Until then, we'll need to filter inbound
223
+ if (this.passesPredicateValidation(record, predicatesGroup)) {
224
+ this.pushToBuffer(transformerMutationType, modelDefinition, record);
225
+ }
226
+ this.drainBuffer();
227
+ },
228
+ error: async (subscriptionError) => {
229
+ const { errors: [{ message = '' } = {}], } = ({
230
+ errors: [],
231
+ } = subscriptionError);
232
+ const isRTFError =
233
+ // only attempt catch if a filter variable was added to the subscription query
234
+ addFilter &&
235
+ this.catchRTFError(message, modelDefinition, predicatesGroup);
236
+ // Catch RTF errors
237
+ if (isRTFError) {
238
+ // Unsubscribe and clear subscription array for model/operation
239
+ subscriptions[modelDefinition.name][transformerMutationType].forEach(subscription => subscription.unsubscribe());
240
+ subscriptions[modelDefinition.name][transformerMutationType] = [];
241
+ // retry subscription connection without filter
242
+ subscriptionRetry(operation, false);
243
+ return;
244
+ }
245
+ if (message.includes(api_graphql_1.CONTROL_MSG.REALTIME_SUBSCRIPTION_INIT_ERROR) ||
246
+ message.includes(api_graphql_1.CONTROL_MSG.CONNECTION_FAILED)) {
247
+ // Unsubscribe and clear subscription array for model/operation
248
+ subscriptions[modelDefinition.name][transformerMutationType].forEach(subscription => subscription.unsubscribe());
249
+ subscriptions[modelDefinition.name][transformerMutationType] = [];
250
+ operationAuthModeAttempts[operation]++;
251
+ if (operationAuthModeAttempts[operation] >=
252
+ readAuthModes.length) {
253
+ // last auth mode retry. Continue with error
254
+ logger.debug(`${operation} subscription failed with authMode: ${readAuthModes[operationAuthModeAttempts[operation] - 1]}`);
255
+ }
256
+ else {
257
+ // retry with different auth mode. Do not trigger
258
+ // observer error or error handler
259
+ logger.debug(`${operation} subscription failed with authMode: ${readAuthModes[operationAuthModeAttempts[operation] - 1]}. Retrying with authMode: ${readAuthModes[operationAuthModeAttempts[operation]]}`);
260
+ subscriptionRetry(operation);
261
+ return;
262
+ }
263
+ }
264
+ logger.warn('subscriptionError', message);
265
+ try {
266
+ await this.errorHandler({
267
+ 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',
268
+ localModel: null,
269
+ message,
270
+ model: modelDefinition.name,
271
+ operation,
272
+ errorType: (0, errorMaps_1.getSubscriptionErrorType)(subscriptionError),
273
+ process: types_1.ProcessName.subscribe,
274
+ remoteModel: null,
275
+ cause: subscriptionError,
276
+ });
277
+ }
278
+ catch (e) {
279
+ logger.error('Subscription error handler failed with:', e);
280
+ }
281
+ if (typeof subscriptionReadyCallback === 'function') {
282
+ subscriptionReadyCallback();
283
+ }
284
+ if (message.includes('"errorType":"Unauthorized"') ||
285
+ message.includes('"errorType":"OperationDisabled"')) {
286
+ return;
287
+ }
288
+ observer.error(message);
289
+ },
290
+ }));
291
+ promises.push((async () => {
292
+ let boundFunction;
293
+ let removeBoundFunctionListener;
294
+ await new Promise(res => {
295
+ subscriptionReadyCallback = res;
296
+ boundFunction = this.hubQueryCompletionListener.bind(this, res);
297
+ removeBoundFunctionListener = core_1.Hub.listen('api', boundFunction);
442
298
  });
443
- });
444
- return [2 /*return*/];
445
- }
446
- });
447
- }); }, 'subscription processor new subscriber');
448
- return _this.runningProcesses.addCleaner(function () { return __awaiter(_this, void 0, void 0, function () {
449
- return __generator(this, function (_a) {
450
- Object.keys(subscriptions).forEach(function (modelName) {
451
- subscriptions[modelName][utils_2.TransformerMutationType.CREATE].forEach(function (subscription) { return subscription.unsubscribe(); });
452
- subscriptions[modelName][utils_2.TransformerMutationType.UPDATE].forEach(function (subscription) { return subscription.unsubscribe(); });
453
- subscriptions[modelName][utils_2.TransformerMutationType.DELETE].forEach(function (subscription) { return subscription.unsubscribe(); });
454
- });
455
- return [2 /*return*/];
299
+ removeBoundFunctionListener();
300
+ })());
301
+ };
302
+ operations.forEach(op => subscriptionRetry(op));
303
+ }));
456
304
  });
457
- }); });
458
- });
459
- var dataObservable = new rxjs_1.Observable(function (observer) {
460
- _this.dataObserver = observer;
461
- _this.drainBuffer();
462
- return _this.runningProcesses.addCleaner(function () { return __awaiter(_this, void 0, void 0, function () {
463
- return __generator(this, function (_a) {
464
- this.dataObserver = null;
465
- return [2 /*return*/];
305
+ this.runningProcesses.isOpen &&
306
+ this.runningProcesses.add(() => Promise.all(promises).then(() => {
307
+ observer.next(CONTROL_MSG.CONNECTED);
308
+ }));
309
+ }, 'subscription processor new subscriber');
310
+ return this.runningProcesses.addCleaner(async () => {
311
+ Object.keys(subscriptions).forEach(modelName => {
312
+ subscriptions[modelName][utils_2.TransformerMutationType.CREATE].forEach(subscription => subscription.unsubscribe());
313
+ subscriptions[modelName][utils_2.TransformerMutationType.UPDATE].forEach(subscription => subscription.unsubscribe());
314
+ subscriptions[modelName][utils_2.TransformerMutationType.DELETE].forEach(subscription => subscription.unsubscribe());
466
315
  });
467
- }); });
316
+ });
468
317
  });
469
- return [ctlObservable, dataObservable];
470
- };
471
- SubscriptionProcessor.prototype.stop = function () {
472
- return __awaiter(this, void 0, void 0, function () {
473
- return __generator(this, function (_a) {
474
- switch (_a.label) {
475
- case 0: return [4 /*yield*/, this.runningProcesses.close()];
476
- case 1:
477
- _a.sent();
478
- return [4 /*yield*/, this.runningProcesses.open()];
479
- case 2:
480
- _a.sent();
481
- return [2 /*return*/];
482
- }
318
+ const dataObservable = new rxjs_1.Observable(observer => {
319
+ this.dataObserver = observer;
320
+ this.drainBuffer();
321
+ return this.runningProcesses.addCleaner(async () => {
322
+ this.dataObserver = null;
483
323
  });
484
324
  });
485
- };
486
- SubscriptionProcessor.prototype.passesPredicateValidation = function (record, predicatesGroup) {
325
+ return [ctlObservable, dataObservable];
326
+ }
327
+ async stop() {
328
+ await this.runningProcesses.close();
329
+ await this.runningProcesses.open();
330
+ }
331
+ passesPredicateValidation(record, predicatesGroup) {
487
332
  if (!predicatesGroup) {
488
333
  return true;
489
334
  }
490
- var predicates = predicatesGroup.predicates, type = predicatesGroup.type;
335
+ const { predicates, type } = predicatesGroup;
491
336
  return (0, util_1.validatePredicate)(record, type, predicates);
492
- };
493
- SubscriptionProcessor.prototype.pushToBuffer = function (transformerMutationType, modelDefinition, data) {
337
+ }
338
+ pushToBuffer(transformerMutationType, modelDefinition, data) {
494
339
  this.buffer.push([transformerMutationType, modelDefinition, data]);
495
- };
496
- SubscriptionProcessor.prototype.drainBuffer = function () {
497
- var _this = this;
340
+ }
341
+ drainBuffer() {
498
342
  if (this.dataObserver) {
499
- this.buffer.forEach(function (data) { return _this.dataObserver.next(data); });
343
+ this.buffer.forEach(data => this.dataObserver.next(data));
500
344
  this.buffer = [];
501
345
  }
502
- };
346
+ }
503
347
  /**
504
348
  * @returns true if the service returned an RTF subscription error
505
349
  * @remarks logs a warning with remediation instructions
506
350
  *
507
351
  */
508
- SubscriptionProcessor.prototype.catchRTFError = function (message, modelDefinition, predicatesGroup) {
509
- var header = 'Backend subscriptions filtering error.\n' +
352
+ catchRTFError(message, modelDefinition, predicatesGroup) {
353
+ const header = 'Backend subscriptions filtering error.\n' +
510
354
  'Subscriptions filtering will be applied clientside.\n';
511
- var messageErrorTypeMap = {
355
+ const messageErrorTypeMap = {
512
356
  'UnknownArgument: Unknown field argument filter': utils_2.RTFError.UnknownField,
513
357
  'Filters exceed maximum attributes limit': utils_2.RTFError.MaxAttributes,
514
358
  'Filters combination exceed maximum limit': utils_2.RTFError.MaxCombinations,
@@ -516,17 +360,13 @@ var SubscriptionProcessor = /** @class */ (function () {
516
360
  "The variables input contains a field name 'not'": utils_2.RTFError.NotGroup,
517
361
  'The variables input contains a field that is not defined for input object type': utils_2.RTFError.FieldNotInType,
518
362
  };
519
- var _a = __read(Object.entries(messageErrorTypeMap).find(function (_a) {
520
- var _b = __read(_a, 1), errorMsg = _b[0];
521
- return message.includes(errorMsg);
522
- }) || [], 2), _errorMsg = _a[0], errorType = _a[1];
363
+ const [_errorMsg, errorType] = Object.entries(messageErrorTypeMap).find(([errorMsg]) => message.includes(errorMsg)) || [];
523
364
  if (errorType !== undefined) {
524
- var remediationMessage = (0, utils_2.generateRTFRemediation)(errorType, modelDefinition, predicatesGroup);
525
- logger.warn("".concat(header, "\n").concat(message, "\n").concat(remediationMessage));
365
+ const remediationMessage = (0, utils_2.generateRTFRemediation)(errorType, modelDefinition, predicatesGroup);
366
+ logger.warn(`${header}\n${message}\n${remediationMessage}`);
526
367
  return true;
527
368
  }
528
369
  return false;
529
- };
530
- return SubscriptionProcessor;
531
- }());
370
+ }
371
+ }
532
372
  exports.SubscriptionProcessor = SubscriptionProcessor;