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