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