@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
package/lib/sync/utils.js
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
|
|
3
|
+
exports.getIdentifierValue = exports.getTokenForCustomAuth = exports.getClientSideAuthError = exports.resolveServiceErrorStatusCode = exports.getForbiddenError = exports.getModelAuthModes = exports.getUserGroupsFromToken = exports.generateRTFRemediation = exports.RTFError = exports.repeatedFieldInGroup = exports.countFilterCombinations = exports.dynamicAuthFields = exports.filterFields = exports.predicateToGraphQLFilter = exports.predicateToGraphQLCondition = exports.createMutationInstanceFromModelOperation = exports.buildGraphQLOperation = exports.buildSubscriptionGraphQLOperation = exports.getAuthorizationRules = exports.generateSelectionSet = exports.getMetadataFields = exports.TransformerMutationType = void 0;
|
|
4
4
|
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
5
5
|
// SPDX-License-Identifier: Apache-2.0
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
var logger = new core_1.Logger('DataStore');
|
|
6
|
+
const api_1 = require("@aws-amplify/api");
|
|
7
|
+
const types_1 = require("../types");
|
|
8
|
+
const util_1 = require("../util");
|
|
9
|
+
const core_1 = require("@aws-amplify/core");
|
|
10
|
+
const logger = new core_1.ConsoleLogger('DataStore');
|
|
12
11
|
var GraphQLOperationType;
|
|
13
12
|
(function (GraphQLOperationType) {
|
|
14
13
|
GraphQLOperationType["LIST"] = "query";
|
|
@@ -24,49 +23,46 @@ var TransformerMutationType;
|
|
|
24
23
|
TransformerMutationType["DELETE"] = "Delete";
|
|
25
24
|
TransformerMutationType["GET"] = "Get";
|
|
26
25
|
})(TransformerMutationType = exports.TransformerMutationType || (exports.TransformerMutationType = {}));
|
|
27
|
-
|
|
26
|
+
const dummyMetadata = {
|
|
28
27
|
_version: undefined,
|
|
29
28
|
_lastChangedAt: undefined,
|
|
30
29
|
_deleted: undefined,
|
|
31
30
|
};
|
|
32
|
-
|
|
31
|
+
const metadataFields = (Object.keys(dummyMetadata));
|
|
33
32
|
function getMetadataFields() {
|
|
34
33
|
return metadataFields;
|
|
35
34
|
}
|
|
36
35
|
exports.getMetadataFields = getMetadataFields;
|
|
37
36
|
function generateSelectionSet(namespace, modelDefinition) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
.map(
|
|
43
|
-
var name = _a.name;
|
|
44
|
-
return name;
|
|
45
|
-
})
|
|
37
|
+
const scalarFields = getScalarFields(modelDefinition);
|
|
38
|
+
const nonModelFields = getNonModelFields(namespace, modelDefinition);
|
|
39
|
+
const implicitOwnerField = getImplicitOwnerField(modelDefinition, scalarFields);
|
|
40
|
+
let scalarAndMetadataFields = Object.values(scalarFields)
|
|
41
|
+
.map(({ name }) => name)
|
|
46
42
|
.concat(implicitOwnerField)
|
|
47
43
|
.concat(nonModelFields);
|
|
48
|
-
if (types_1.isSchemaModel(modelDefinition)) {
|
|
44
|
+
if ((0, types_1.isSchemaModel)(modelDefinition)) {
|
|
49
45
|
scalarAndMetadataFields = scalarAndMetadataFields
|
|
50
46
|
.concat(getMetadataFields())
|
|
51
47
|
.concat(getConnectionFields(modelDefinition, namespace));
|
|
52
48
|
}
|
|
53
|
-
|
|
49
|
+
const result = scalarAndMetadataFields.join('\n');
|
|
54
50
|
return result;
|
|
55
51
|
}
|
|
56
52
|
exports.generateSelectionSet = generateSelectionSet;
|
|
57
53
|
function getImplicitOwnerField(modelDefinition, scalarFields) {
|
|
58
|
-
|
|
54
|
+
const ownerFields = getOwnerFields(modelDefinition);
|
|
59
55
|
if (!scalarFields.owner && ownerFields.includes('owner')) {
|
|
60
56
|
return ['owner'];
|
|
61
57
|
}
|
|
62
58
|
return [];
|
|
63
59
|
}
|
|
64
60
|
function getOwnerFields(modelDefinition) {
|
|
65
|
-
|
|
66
|
-
if (types_1.isSchemaModelWithAttributes(modelDefinition)) {
|
|
67
|
-
modelDefinition.attributes.forEach(
|
|
61
|
+
const ownerFields = [];
|
|
62
|
+
if ((0, types_1.isSchemaModelWithAttributes)(modelDefinition)) {
|
|
63
|
+
modelDefinition.attributes.forEach(attr => {
|
|
68
64
|
if (attr.properties && attr.properties.rules) {
|
|
69
|
-
|
|
65
|
+
const rule = attr.properties.rules.find(rule => rule.allow === 'owner');
|
|
70
66
|
if (rule && rule.ownerField) {
|
|
71
67
|
ownerFields.push(rule.ownerField);
|
|
72
68
|
}
|
|
@@ -76,15 +72,15 @@ function getOwnerFields(modelDefinition) {
|
|
|
76
72
|
return ownerFields;
|
|
77
73
|
}
|
|
78
74
|
function getScalarFields(modelDefinition) {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
.filter(
|
|
82
|
-
if (types_1.isGraphQLScalarType(field.type) || types_1.isEnumFieldType(field.type)) {
|
|
75
|
+
const { fields } = modelDefinition;
|
|
76
|
+
const result = Object.values(fields)
|
|
77
|
+
.filter(field => {
|
|
78
|
+
if ((0, types_1.isGraphQLScalarType)(field.type) || (0, types_1.isEnumFieldType)(field.type)) {
|
|
83
79
|
return true;
|
|
84
80
|
}
|
|
85
81
|
return false;
|
|
86
82
|
})
|
|
87
|
-
.reduce(
|
|
83
|
+
.reduce((acc, field) => {
|
|
88
84
|
acc[field.name] = field;
|
|
89
85
|
return acc;
|
|
90
86
|
}, {});
|
|
@@ -92,105 +88,94 @@ function getScalarFields(modelDefinition) {
|
|
|
92
88
|
}
|
|
93
89
|
// Used for generating the selection set for queries and mutations
|
|
94
90
|
function getConnectionFields(modelDefinition, namespace) {
|
|
95
|
-
|
|
91
|
+
const result = [];
|
|
96
92
|
Object.values(modelDefinition.fields)
|
|
97
|
-
.filter(
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
})
|
|
101
|
-
.forEach(function (_a) {
|
|
102
|
-
var name = _a.name, association = _a.association;
|
|
103
|
-
var connectionType = (association || {}).connectionType;
|
|
93
|
+
.filter(({ association }) => association && Object.keys(association).length)
|
|
94
|
+
.forEach(({ name, association }) => {
|
|
95
|
+
const { connectionType } = association || {};
|
|
104
96
|
switch (connectionType) {
|
|
105
97
|
case 'HAS_ONE':
|
|
106
98
|
case 'HAS_MANY':
|
|
107
99
|
// Intentionally blank
|
|
108
100
|
break;
|
|
109
101
|
case 'BELONGS_TO':
|
|
110
|
-
if (types_1.isTargetNameAssociation(association)) {
|
|
102
|
+
if ((0, types_1.isTargetNameAssociation)(association)) {
|
|
111
103
|
// New codegen (CPK)
|
|
112
104
|
if (association.targetNames && association.targetNames.length > 0) {
|
|
113
105
|
// Need to retrieve relations in order to get connected model keys
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
});
|
|
120
|
-
var keyFields = byPkIndex && byPkIndex[1];
|
|
121
|
-
var keyFieldSelectionSet = keyFields === null || keyFields === void 0 ? void 0 : keyFields.join(' ');
|
|
106
|
+
const [relations] = (0, util_1.establishRelationAndKeys)(namespace);
|
|
107
|
+
const connectedModelName = modelDefinition.fields[name].type['model'];
|
|
108
|
+
const byPkIndex = relations[connectedModelName].indexes.find(([name]) => name === 'byPk');
|
|
109
|
+
const keyFields = byPkIndex && byPkIndex[1];
|
|
110
|
+
const keyFieldSelectionSet = keyFields?.join(' ');
|
|
122
111
|
// We rely on `_deleted` when we process the sync query (e.g. in batchSave in the adapters)
|
|
123
|
-
result.push(name
|
|
112
|
+
result.push(`${name} { ${keyFieldSelectionSet} _deleted }`);
|
|
124
113
|
}
|
|
125
114
|
else {
|
|
126
115
|
// backwards-compatability for schema generated prior to custom primary key support
|
|
127
|
-
result.push(name
|
|
116
|
+
result.push(`${name} { id _deleted }`);
|
|
128
117
|
}
|
|
129
118
|
}
|
|
130
119
|
break;
|
|
131
120
|
default:
|
|
132
|
-
throw new Error(
|
|
121
|
+
throw new Error(`Invalid connection type ${connectionType}`);
|
|
133
122
|
}
|
|
134
123
|
});
|
|
135
124
|
return result;
|
|
136
125
|
}
|
|
137
126
|
function getNonModelFields(namespace, modelDefinition) {
|
|
138
|
-
|
|
139
|
-
Object.values(modelDefinition.fields).forEach(
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
var type = field.type, name = field.name;
|
|
150
|
-
if (types_1.isNonModelFieldType(type)) {
|
|
151
|
-
var typeDefinition_1 = namespace.nonModels[type.nonModel];
|
|
152
|
-
nested_1.push(name + " { " + generateSelectionSet(namespace, typeDefinition_1) + " }");
|
|
127
|
+
const result = [];
|
|
128
|
+
Object.values(modelDefinition.fields).forEach(({ name, type }) => {
|
|
129
|
+
if ((0, types_1.isNonModelFieldType)(type)) {
|
|
130
|
+
const typeDefinition = namespace.nonModels[type.nonModel];
|
|
131
|
+
const scalarFields = Object.values(getScalarFields(typeDefinition)).map(({ name }) => name);
|
|
132
|
+
const nested = [];
|
|
133
|
+
Object.values(typeDefinition.fields).forEach(field => {
|
|
134
|
+
const { type, name } = field;
|
|
135
|
+
if ((0, types_1.isNonModelFieldType)(type)) {
|
|
136
|
+
const typeDefinition = namespace.nonModels[type.nonModel];
|
|
137
|
+
nested.push(`${name} { ${generateSelectionSet(namespace, typeDefinition)} }`);
|
|
153
138
|
}
|
|
154
139
|
});
|
|
155
|
-
result.push(name
|
|
140
|
+
result.push(`${name} { ${scalarFields.join(' ')} ${nested.join(' ')} }`);
|
|
156
141
|
}
|
|
157
142
|
});
|
|
158
143
|
return result;
|
|
159
144
|
}
|
|
160
145
|
function getAuthorizationRules(modelDefinition) {
|
|
161
146
|
// Searching for owner authorization on attributes
|
|
162
|
-
|
|
147
|
+
const authConfig = []
|
|
163
148
|
.concat(modelDefinition.attributes || [])
|
|
164
|
-
.find(
|
|
165
|
-
|
|
166
|
-
|
|
149
|
+
.find(attr => attr && attr.type === 'auth');
|
|
150
|
+
const { properties: { rules = [] } = {} } = authConfig || {};
|
|
151
|
+
const resultRules = [];
|
|
167
152
|
// Multiple rules can be declared for allow: owner
|
|
168
|
-
rules.forEach(
|
|
153
|
+
rules.forEach(rule => {
|
|
169
154
|
// setting defaults for backwards compatibility with old cli
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
155
|
+
const { identityClaim = 'cognito:username', ownerField = 'owner', operations = ['create', 'update', 'delete', 'read'], provider = 'userPools', groupClaim = 'cognito:groups', allow: authStrategy = 'iam', groups = [], groupsField = '', } = rule;
|
|
156
|
+
const isReadAuthorized = operations.includes('read');
|
|
157
|
+
const isOwnerAuth = authStrategy === 'owner';
|
|
173
158
|
if (!isReadAuthorized && !isOwnerAuth) {
|
|
174
159
|
return;
|
|
175
160
|
}
|
|
176
|
-
|
|
177
|
-
identityClaim
|
|
178
|
-
ownerField
|
|
179
|
-
provider
|
|
180
|
-
groupClaim
|
|
181
|
-
authStrategy
|
|
182
|
-
groups
|
|
183
|
-
groupsField
|
|
161
|
+
const authRule = {
|
|
162
|
+
identityClaim,
|
|
163
|
+
ownerField,
|
|
164
|
+
provider,
|
|
165
|
+
groupClaim,
|
|
166
|
+
authStrategy,
|
|
167
|
+
groups,
|
|
168
|
+
groupsField,
|
|
184
169
|
areSubscriptionsPublic: false,
|
|
185
170
|
};
|
|
186
171
|
if (isOwnerAuth) {
|
|
187
172
|
// look for the subscription level override
|
|
188
173
|
// only pay attention to the public level
|
|
189
|
-
|
|
174
|
+
const modelConfig = []
|
|
190
175
|
.concat(modelDefinition.attributes || [])
|
|
191
|
-
.find(
|
|
176
|
+
.find(attr => attr && attr.type === 'model');
|
|
192
177
|
// find the subscriptions level. ON is default
|
|
193
|
-
|
|
178
|
+
const { properties: { subscriptions: { level = 'on' } = {} } = {} } = modelConfig || {};
|
|
194
179
|
// treat subscriptions as public for owner auth with unprotected reads
|
|
195
180
|
// when `read` is omitted from `operations`
|
|
196
181
|
authRule.areSubscriptionsPublic =
|
|
@@ -206,83 +191,94 @@ function getAuthorizationRules(modelDefinition) {
|
|
|
206
191
|
return resultRules;
|
|
207
192
|
}
|
|
208
193
|
exports.getAuthorizationRules = getAuthorizationRules;
|
|
209
|
-
function buildSubscriptionGraphQLOperation(namespace, modelDefinition, transformerMutationType, isOwnerAuthorization, ownerField, filterArg) {
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
var opArgs = [];
|
|
194
|
+
function buildSubscriptionGraphQLOperation(namespace, modelDefinition, transformerMutationType, isOwnerAuthorization, ownerField, filterArg = false) {
|
|
195
|
+
const selectionSet = generateSelectionSet(namespace, modelDefinition);
|
|
196
|
+
const { name: typeName } = modelDefinition;
|
|
197
|
+
const opName = `on${transformerMutationType}${typeName}`;
|
|
198
|
+
const docArgs = [];
|
|
199
|
+
const opArgs = [];
|
|
216
200
|
if (filterArg) {
|
|
217
|
-
docArgs.push(
|
|
201
|
+
docArgs.push(`$filter: ModelSubscription${typeName}FilterInput`);
|
|
218
202
|
opArgs.push('filter: $filter');
|
|
219
203
|
}
|
|
220
204
|
if (isOwnerAuthorization) {
|
|
221
|
-
docArgs.push(
|
|
222
|
-
opArgs.push(ownerField
|
|
205
|
+
docArgs.push(`$${ownerField}: String!`);
|
|
206
|
+
opArgs.push(`${ownerField}: $${ownerField}`);
|
|
223
207
|
}
|
|
224
|
-
|
|
225
|
-
|
|
208
|
+
const docStr = docArgs.length ? `(${docArgs.join(',')})` : '';
|
|
209
|
+
const opStr = opArgs.length ? `(${opArgs.join(',')})` : '';
|
|
226
210
|
return [
|
|
227
211
|
transformerMutationType,
|
|
228
212
|
opName,
|
|
229
|
-
|
|
213
|
+
`subscription operation${docStr}{
|
|
214
|
+
${opName}${opStr}{
|
|
215
|
+
${selectionSet}
|
|
216
|
+
}
|
|
217
|
+
}`,
|
|
230
218
|
];
|
|
231
219
|
}
|
|
232
220
|
exports.buildSubscriptionGraphQLOperation = buildSubscriptionGraphQLOperation;
|
|
233
221
|
function buildGraphQLOperation(namespace, modelDefinition, graphQLOpType) {
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
222
|
+
let selectionSet = generateSelectionSet(namespace, modelDefinition);
|
|
223
|
+
const { name: typeName, pluralName: pluralTypeName } = modelDefinition;
|
|
224
|
+
let operation;
|
|
225
|
+
let documentArgs;
|
|
226
|
+
let operationArgs;
|
|
227
|
+
let transformerMutationType;
|
|
240
228
|
switch (graphQLOpType) {
|
|
241
229
|
case 'LIST':
|
|
242
|
-
operation =
|
|
243
|
-
documentArgs =
|
|
230
|
+
operation = `sync${pluralTypeName}`;
|
|
231
|
+
documentArgs = `($limit: Int, $nextToken: String, $lastSync: AWSTimestamp, $filter: Model${typeName}FilterInput)`;
|
|
244
232
|
operationArgs =
|
|
245
233
|
'(limit: $limit, nextToken: $nextToken, lastSync: $lastSync, filter: $filter)';
|
|
246
|
-
selectionSet =
|
|
234
|
+
selectionSet = `items {
|
|
235
|
+
${selectionSet}
|
|
236
|
+
}
|
|
237
|
+
nextToken
|
|
238
|
+
startedAt`;
|
|
247
239
|
break;
|
|
248
240
|
case 'CREATE':
|
|
249
|
-
operation =
|
|
250
|
-
documentArgs =
|
|
241
|
+
operation = `create${typeName}`;
|
|
242
|
+
documentArgs = `($input: Create${typeName}Input!)`;
|
|
251
243
|
operationArgs = '(input: $input)';
|
|
252
244
|
transformerMutationType = TransformerMutationType.CREATE;
|
|
253
245
|
break;
|
|
254
246
|
case 'UPDATE':
|
|
255
|
-
operation =
|
|
256
|
-
documentArgs =
|
|
247
|
+
operation = `update${typeName}`;
|
|
248
|
+
documentArgs = `($input: Update${typeName}Input!, $condition: Model${typeName}ConditionInput)`;
|
|
257
249
|
operationArgs = '(input: $input, condition: $condition)';
|
|
258
250
|
transformerMutationType = TransformerMutationType.UPDATE;
|
|
259
251
|
break;
|
|
260
252
|
case 'DELETE':
|
|
261
|
-
operation =
|
|
262
|
-
documentArgs =
|
|
253
|
+
operation = `delete${typeName}`;
|
|
254
|
+
documentArgs = `($input: Delete${typeName}Input!, $condition: Model${typeName}ConditionInput)`;
|
|
263
255
|
operationArgs = '(input: $input, condition: $condition)';
|
|
264
256
|
transformerMutationType = TransformerMutationType.DELETE;
|
|
265
257
|
break;
|
|
266
258
|
case 'GET':
|
|
267
|
-
operation =
|
|
268
|
-
documentArgs =
|
|
259
|
+
operation = `get${typeName}`;
|
|
260
|
+
documentArgs = `($id: ID!)`;
|
|
269
261
|
operationArgs = '(id: $id)';
|
|
270
262
|
transformerMutationType = TransformerMutationType.GET;
|
|
271
263
|
break;
|
|
272
264
|
default:
|
|
273
|
-
throw new Error(
|
|
265
|
+
throw new Error(`Invalid graphQlOpType ${graphQLOpType}`);
|
|
274
266
|
}
|
|
275
267
|
return [
|
|
276
268
|
[
|
|
277
269
|
transformerMutationType,
|
|
278
270
|
operation,
|
|
279
|
-
GraphQLOperationType[graphQLOpType]
|
|
271
|
+
`${GraphQLOperationType[graphQLOpType]} operation${documentArgs}{
|
|
272
|
+
${operation}${operationArgs}{
|
|
273
|
+
${selectionSet}
|
|
274
|
+
}
|
|
275
|
+
}`,
|
|
280
276
|
],
|
|
281
277
|
];
|
|
282
278
|
}
|
|
283
279
|
exports.buildGraphQLOperation = buildGraphQLOperation;
|
|
284
280
|
function createMutationInstanceFromModelOperation(relationships, modelDefinition, opType, model, element, condition, MutationEventConstructor, modelInstanceCreator, id) {
|
|
285
|
-
|
|
281
|
+
let operation;
|
|
286
282
|
switch (opType) {
|
|
287
283
|
case types_1.OpType.INSERT:
|
|
288
284
|
operation = TransformerMutationType.CREATE;
|
|
@@ -294,13 +290,13 @@ function createMutationInstanceFromModelOperation(relationships, modelDefinition
|
|
|
294
290
|
operation = TransformerMutationType.DELETE;
|
|
295
291
|
break;
|
|
296
292
|
default:
|
|
297
|
-
throw new Error(
|
|
293
|
+
throw new Error(`Invalid opType ${opType}`);
|
|
298
294
|
}
|
|
299
295
|
// stringify nested objects of type AWSJSON
|
|
300
296
|
// this allows us to return parsed JSON to users (see `castInstanceType()` in datastore.ts),
|
|
301
297
|
// but still send the object correctly over the wire
|
|
302
|
-
|
|
303
|
-
|
|
298
|
+
const replacer = (k, v) => {
|
|
299
|
+
const isAWSJSON = k &&
|
|
304
300
|
v !== null &&
|
|
305
301
|
typeof v === 'object' &&
|
|
306
302
|
modelDefinition.fields[k] &&
|
|
@@ -310,14 +306,21 @@ function createMutationInstanceFromModelOperation(relationships, modelDefinition
|
|
|
310
306
|
}
|
|
311
307
|
return v;
|
|
312
308
|
};
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
309
|
+
const modelId = getIdentifierValue(modelDefinition, element);
|
|
310
|
+
const optionalId = types_1.OpType.INSERT && id ? { id } : {};
|
|
311
|
+
const mutationEvent = modelInstanceCreator(MutationEventConstructor, {
|
|
312
|
+
...optionalId,
|
|
313
|
+
data: JSON.stringify(element, replacer),
|
|
314
|
+
modelId,
|
|
315
|
+
model: model.name,
|
|
316
|
+
operation: operation,
|
|
317
|
+
condition: JSON.stringify(condition),
|
|
318
|
+
});
|
|
316
319
|
return mutationEvent;
|
|
317
320
|
}
|
|
318
321
|
exports.createMutationInstanceFromModelOperation = createMutationInstanceFromModelOperation;
|
|
319
322
|
function predicateToGraphQLCondition(predicate, modelDefinition) {
|
|
320
|
-
|
|
323
|
+
const result = {};
|
|
321
324
|
if (!predicate || !Array.isArray(predicate.predicates)) {
|
|
322
325
|
return result;
|
|
323
326
|
}
|
|
@@ -328,7 +331,7 @@ function predicateToGraphQLCondition(predicate, modelDefinition) {
|
|
|
328
331
|
// Or all records where PK = some value but SKs are different values
|
|
329
332
|
// TODO: if the Transform gets updated we'll need to modify this logic to only omit
|
|
330
333
|
// key fields from the predicate/condition when ALL of the keyFields are present and using `eq` operators
|
|
331
|
-
|
|
334
|
+
const keyFields = (0, util_1.extractPrimaryKeyFieldNames)(modelDefinition);
|
|
332
335
|
return predicateToGraphQLFilter(predicate, keyFields);
|
|
333
336
|
}
|
|
334
337
|
exports.predicateToGraphQLCondition = predicateToGraphQLCondition;
|
|
@@ -347,37 +350,34 @@ exports.predicateToGraphQLCondition = predicateToGraphQLCondition;
|
|
|
347
350
|
{ and:[{ username: { eq: 'bob' }}] }
|
|
348
351
|
```
|
|
349
352
|
*/
|
|
350
|
-
function predicateToGraphQLFilter(predicatesGroup, fieldsToOmit, root) {
|
|
351
|
-
|
|
352
|
-
if (root === void 0) { root = true; }
|
|
353
|
-
var result = {};
|
|
353
|
+
function predicateToGraphQLFilter(predicatesGroup, fieldsToOmit = [], root = true) {
|
|
354
|
+
const result = {};
|
|
354
355
|
if (!predicatesGroup || !Array.isArray(predicatesGroup.predicates)) {
|
|
355
356
|
return result;
|
|
356
357
|
}
|
|
357
|
-
|
|
358
|
-
|
|
358
|
+
const { type, predicates } = predicatesGroup;
|
|
359
|
+
const isList = type === 'and' || type === 'or';
|
|
359
360
|
result[type] = isList ? [] : {};
|
|
360
|
-
|
|
361
|
-
predicates.forEach(
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
var field = predicate.field, operator = predicate.operator, operand = predicate.operand;
|
|
361
|
+
const children = [];
|
|
362
|
+
predicates.forEach(predicate => {
|
|
363
|
+
if ((0, types_1.isPredicateObj)(predicate)) {
|
|
364
|
+
const { field, operator, operand } = predicate;
|
|
365
365
|
if (fieldsToOmit.includes(field))
|
|
366
366
|
return;
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
367
|
+
const gqlField = {
|
|
368
|
+
[field]: { [operator]: operand },
|
|
369
|
+
};
|
|
370
370
|
children.push(gqlField);
|
|
371
371
|
return;
|
|
372
372
|
}
|
|
373
|
-
|
|
373
|
+
const child = predicateToGraphQLFilter(predicate, fieldsToOmit, false);
|
|
374
374
|
if (Object.keys(child).length > 0) {
|
|
375
375
|
children.push(child);
|
|
376
376
|
}
|
|
377
377
|
});
|
|
378
378
|
// flatten redundant list predicates
|
|
379
379
|
if (children.length === 1) {
|
|
380
|
-
|
|
380
|
+
const [child] = children;
|
|
381
381
|
if (
|
|
382
382
|
// any nested list node
|
|
383
383
|
(isList && !root) ||
|
|
@@ -388,7 +388,7 @@ function predicateToGraphQLFilter(predicatesGroup, fieldsToOmit, root) {
|
|
|
388
388
|
return result;
|
|
389
389
|
}
|
|
390
390
|
}
|
|
391
|
-
children.forEach(
|
|
391
|
+
children.forEach(child => {
|
|
392
392
|
if (isList) {
|
|
393
393
|
result[type].push(child);
|
|
394
394
|
}
|
|
@@ -413,18 +413,18 @@ exports.predicateToGraphQLFilter = predicateToGraphQLFilter;
|
|
|
413
413
|
* @returns set of distinct field names in the filter group
|
|
414
414
|
*/
|
|
415
415
|
function filterFields(group) {
|
|
416
|
-
|
|
416
|
+
const fields = new Set();
|
|
417
417
|
if (!group || !Array.isArray(group.predicates))
|
|
418
418
|
return fields;
|
|
419
|
-
|
|
420
|
-
|
|
419
|
+
const { predicates } = group;
|
|
420
|
+
const stack = [...predicates];
|
|
421
421
|
while (stack.length > 0) {
|
|
422
|
-
|
|
423
|
-
if (types_1.isPredicateObj(current)) {
|
|
422
|
+
const current = stack.pop();
|
|
423
|
+
if ((0, types_1.isPredicateObj)(current)) {
|
|
424
424
|
fields.add(current.field);
|
|
425
425
|
}
|
|
426
|
-
else if (types_1.isPredicateGroup(current)) {
|
|
427
|
-
stack.push
|
|
426
|
+
else if ((0, types_1.isPredicateGroup)(current)) {
|
|
427
|
+
stack.push(...current.predicates);
|
|
428
428
|
}
|
|
429
429
|
}
|
|
430
430
|
return fields;
|
|
@@ -436,27 +436,16 @@ exports.filterFields = filterFields;
|
|
|
436
436
|
* @returns set of field names used with dynamic auth modes configured for the provided model definition
|
|
437
437
|
*/
|
|
438
438
|
function dynamicAuthFields(modelDefinition) {
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
if (rule.groupsField && !rule.groups.length) {
|
|
446
|
-
// dynamic group rule will have no values in `rule.groups`
|
|
447
|
-
fields.add(rule.groupsField);
|
|
448
|
-
}
|
|
449
|
-
else if (rule.ownerField) {
|
|
450
|
-
fields.add(rule.ownerField);
|
|
451
|
-
}
|
|
439
|
+
const rules = getAuthorizationRules(modelDefinition);
|
|
440
|
+
const fields = new Set();
|
|
441
|
+
for (const rule of rules) {
|
|
442
|
+
if (rule.groupsField && !rule.groups.length) {
|
|
443
|
+
// dynamic group rule will have no values in `rule.groups`
|
|
444
|
+
fields.add(rule.groupsField);
|
|
452
445
|
}
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
finally {
|
|
456
|
-
try {
|
|
457
|
-
if (rules_1_1 && !rules_1_1.done && (_a = rules_1.return)) _a.call(rules_1);
|
|
446
|
+
else if (rule.ownerField) {
|
|
447
|
+
fields.add(rule.ownerField);
|
|
458
448
|
}
|
|
459
|
-
finally { if (e_1) throw e_1.error; }
|
|
460
449
|
}
|
|
461
450
|
return fields;
|
|
462
451
|
}
|
|
@@ -477,17 +466,17 @@ exports.dynamicAuthFields = dynamicAuthFields;
|
|
|
477
466
|
function countFilterCombinations(group) {
|
|
478
467
|
if (!group || !Array.isArray(group.predicates))
|
|
479
468
|
return 0;
|
|
480
|
-
|
|
481
|
-
|
|
469
|
+
let count = 0;
|
|
470
|
+
const stack = [group];
|
|
482
471
|
while (stack.length > 0) {
|
|
483
|
-
|
|
484
|
-
if (types_1.isPredicateGroup(current)) {
|
|
485
|
-
|
|
472
|
+
const current = stack.pop();
|
|
473
|
+
if ((0, types_1.isPredicateGroup)(current)) {
|
|
474
|
+
const { predicates, type } = current;
|
|
486
475
|
// ignore length = 1; groups with 1 predicate will get flattened when converted to gqlFilter
|
|
487
476
|
if (type === 'or' && predicates.length > 1) {
|
|
488
477
|
count += predicates.length;
|
|
489
478
|
}
|
|
490
|
-
stack.push
|
|
479
|
+
stack.push(...predicates);
|
|
491
480
|
}
|
|
492
481
|
}
|
|
493
482
|
// if we didn't encounter any OR groups, default to 1
|
|
@@ -511,50 +500,37 @@ function repeatedFieldInGroup(group) {
|
|
|
511
500
|
if (!group || !Array.isArray(group.predicates))
|
|
512
501
|
return null;
|
|
513
502
|
// convert to filter in order to flatten redundant groups
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
var _b = tslib_1.__read(Object.keys(f), 1), fieldName = _b[0];
|
|
523
|
-
if (seen[fieldName]) {
|
|
524
|
-
return fieldName;
|
|
525
|
-
}
|
|
526
|
-
seen[fieldName] = true;
|
|
503
|
+
const gqlFilter = predicateToGraphQLFilter(group);
|
|
504
|
+
const stack = [gqlFilter];
|
|
505
|
+
const hasGroupRepeatedFields = (fields) => {
|
|
506
|
+
const seen = {};
|
|
507
|
+
for (const f of fields) {
|
|
508
|
+
const [fieldName] = Object.keys(f);
|
|
509
|
+
if (seen[fieldName]) {
|
|
510
|
+
return fieldName;
|
|
527
511
|
}
|
|
528
|
-
|
|
529
|
-
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
530
|
-
finally {
|
|
531
|
-
try {
|
|
532
|
-
if (fields_1_1 && !fields_1_1.done && (_a = fields_1.return)) _a.call(fields_1);
|
|
533
|
-
}
|
|
534
|
-
finally { if (e_2) throw e_2.error; }
|
|
512
|
+
seen[fieldName] = true;
|
|
535
513
|
}
|
|
536
514
|
return null;
|
|
537
515
|
};
|
|
538
516
|
while (stack.length > 0) {
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
517
|
+
const current = stack.pop();
|
|
518
|
+
const [key] = Object.keys(current);
|
|
519
|
+
const values = current[key];
|
|
542
520
|
if (!Array.isArray(values)) {
|
|
543
521
|
return null;
|
|
544
522
|
}
|
|
545
523
|
// field value will be single object
|
|
546
|
-
|
|
524
|
+
const predicateObjects = values.filter(v => !Array.isArray(Object.values(v)[0]));
|
|
547
525
|
// group value will be an array
|
|
548
|
-
|
|
549
|
-
return Array.isArray(Object.values(v)[0]);
|
|
550
|
-
});
|
|
526
|
+
const predicateGroups = values.filter(v => Array.isArray(Object.values(v)[0]));
|
|
551
527
|
if (key === 'and') {
|
|
552
|
-
|
|
528
|
+
const repeatedField = hasGroupRepeatedFields(predicateObjects);
|
|
553
529
|
if (repeatedField) {
|
|
554
530
|
return repeatedField;
|
|
555
531
|
}
|
|
556
532
|
}
|
|
557
|
-
stack.push
|
|
533
|
+
stack.push(...predicateGroups);
|
|
558
534
|
}
|
|
559
535
|
return null;
|
|
560
536
|
}
|
|
@@ -569,41 +545,41 @@ var RTFError;
|
|
|
569
545
|
RTFError[RTFError["FieldNotInType"] = 5] = "FieldNotInType";
|
|
570
546
|
})(RTFError = exports.RTFError || (exports.RTFError = {}));
|
|
571
547
|
function generateRTFRemediation(errorType, modelDefinition, predicatesGroup) {
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
548
|
+
const selSyncFields = filterFields(predicatesGroup);
|
|
549
|
+
const selSyncFieldStr = [...selSyncFields].join(', ');
|
|
550
|
+
const dynamicAuthModeFields = dynamicAuthFields(modelDefinition);
|
|
551
|
+
const dynamicAuthFieldsStr = [...dynamicAuthModeFields].join(', ');
|
|
552
|
+
const filterCombinations = countFilterCombinations(predicatesGroup);
|
|
553
|
+
const repeatedField = repeatedFieldInGroup(predicatesGroup);
|
|
578
554
|
switch (errorType) {
|
|
579
555
|
case RTFError.UnknownField:
|
|
580
|
-
return (
|
|
556
|
+
return (`Your API was generated with an older version of the CLI that doesn't support backend subscription filtering.` +
|
|
581
557
|
'To enable backend subscription filtering, upgrade your Amplify CLI to the latest version and push your app by running `amplify upgrade` followed by `amplify push`');
|
|
582
558
|
case RTFError.MaxAttributes: {
|
|
583
|
-
|
|
559
|
+
let message = `Your selective sync expression for ${modelDefinition.name} contains ${selSyncFields.size} different model fields: ${selSyncFieldStr}.\n\n`;
|
|
584
560
|
if (dynamicAuthModeFields.size > 0) {
|
|
585
561
|
message +=
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
562
|
+
`Note: the number of fields you can use with selective sync is affected by @auth rules configured on the model.\n\n` +
|
|
563
|
+
`Dynamic auth modes, such as owner auth and dynamic group auth each utilize 1 field.\n` +
|
|
564
|
+
`You currently have ${dynamicAuthModeFields.size} dynamic auth mode(s) configured on this model: ${dynamicAuthFieldsStr}.`;
|
|
589
565
|
}
|
|
590
566
|
return message;
|
|
591
567
|
}
|
|
592
568
|
case RTFError.MaxCombinations: {
|
|
593
|
-
|
|
569
|
+
let message = `Your selective sync expression for ${modelDefinition.name} contains ${filterCombinations} field combinations (total number of predicates in an OR expression).\n\n`;
|
|
594
570
|
if (dynamicAuthModeFields.size > 0) {
|
|
595
571
|
message +=
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
572
|
+
`Note: the number of fields you can use with selective sync is affected by @auth rules configured on the model.\n\n` +
|
|
573
|
+
`Dynamic auth modes, such as owner auth and dynamic group auth factor in to the number of combinations you're using.\n` +
|
|
574
|
+
`You currently have ${dynamicAuthModeFields.size} dynamic auth mode(s) configured on this model: ${dynamicAuthFieldsStr}.`;
|
|
599
575
|
}
|
|
600
576
|
return message;
|
|
601
577
|
}
|
|
602
578
|
case RTFError.RepeatedFieldname:
|
|
603
|
-
return
|
|
579
|
+
return `Your selective sync expression for ${modelDefinition.name} contains multiple entries for ${repeatedField} in the same AND group.`;
|
|
604
580
|
case RTFError.NotGroup:
|
|
605
|
-
return (
|
|
606
|
-
|
|
581
|
+
return (`Your selective sync expression for ${modelDefinition.name} uses a \`not\` group. If you'd like to filter subscriptions in the backend, ` +
|
|
582
|
+
`rewrite your expression using \`ne\` or \`notContains\` operators.`);
|
|
607
583
|
case RTFError.FieldNotInType:
|
|
608
584
|
// no remediation instructions. We'll surface the message directly
|
|
609
585
|
return '';
|
|
@@ -612,9 +588,9 @@ function generateRTFRemediation(errorType, modelDefinition, predicatesGroup) {
|
|
|
612
588
|
exports.generateRTFRemediation = generateRTFRemediation;
|
|
613
589
|
function getUserGroupsFromToken(token, rule) {
|
|
614
590
|
// validate token against groupClaim
|
|
615
|
-
|
|
591
|
+
let userGroups = token[rule.groupClaim] || [];
|
|
616
592
|
if (typeof userGroups === 'string') {
|
|
617
|
-
|
|
593
|
+
let parsedGroups;
|
|
618
594
|
try {
|
|
619
595
|
parsedGroups = JSON.parse(userGroups);
|
|
620
596
|
}
|
|
@@ -626,127 +602,98 @@ function getUserGroupsFromToken(token, rule) {
|
|
|
626
602
|
return userGroups;
|
|
627
603
|
}
|
|
628
604
|
exports.getUserGroupsFromToken = getUserGroupsFromToken;
|
|
629
|
-
function getModelAuthModes(
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
_b.trys.push([1, 3, , 4]);
|
|
647
|
-
return [4 /*yield*/, Promise.all(operations.map(function (operation) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
648
|
-
var authModes;
|
|
649
|
-
return tslib_1.__generator(this, function (_a) {
|
|
650
|
-
switch (_a.label) {
|
|
651
|
-
case 0: return [4 /*yield*/, authModeStrategy({
|
|
652
|
-
schema: schema,
|
|
653
|
-
modelName: modelName,
|
|
654
|
-
operation: operation,
|
|
655
|
-
})];
|
|
656
|
-
case 1:
|
|
657
|
-
authModes = _a.sent();
|
|
658
|
-
if (typeof authModes === 'string') {
|
|
659
|
-
modelAuthModes[operation] = [authModes];
|
|
660
|
-
}
|
|
661
|
-
else if (Array.isArray(authModes) && authModes.length) {
|
|
662
|
-
modelAuthModes[operation] = authModes;
|
|
663
|
-
}
|
|
664
|
-
else {
|
|
665
|
-
// Use default auth mode if nothing is returned from authModeStrategy
|
|
666
|
-
modelAuthModes[operation] = [defaultAuthMode];
|
|
667
|
-
}
|
|
668
|
-
return [2 /*return*/];
|
|
669
|
-
}
|
|
670
|
-
});
|
|
671
|
-
}); }))];
|
|
672
|
-
case 2:
|
|
673
|
-
_b.sent();
|
|
674
|
-
return [3 /*break*/, 4];
|
|
675
|
-
case 3:
|
|
676
|
-
error_1 = _b.sent();
|
|
677
|
-
logger.debug("Error getting auth modes for model: " + modelName, error_1);
|
|
678
|
-
return [3 /*break*/, 4];
|
|
679
|
-
case 4: return [2 /*return*/, modelAuthModes];
|
|
605
|
+
async function getModelAuthModes({ authModeStrategy, defaultAuthMode, modelName, schema, }) {
|
|
606
|
+
const operations = Object.values(types_1.ModelOperation);
|
|
607
|
+
const modelAuthModes = {
|
|
608
|
+
CREATE: [],
|
|
609
|
+
READ: [],
|
|
610
|
+
UPDATE: [],
|
|
611
|
+
DELETE: [],
|
|
612
|
+
};
|
|
613
|
+
try {
|
|
614
|
+
await Promise.all(operations.map(async (operation) => {
|
|
615
|
+
const authModes = await authModeStrategy({
|
|
616
|
+
schema,
|
|
617
|
+
modelName,
|
|
618
|
+
operation,
|
|
619
|
+
});
|
|
620
|
+
if (typeof authModes === 'string') {
|
|
621
|
+
modelAuthModes[operation] = [authModes];
|
|
680
622
|
}
|
|
681
|
-
|
|
682
|
-
|
|
623
|
+
else if (Array.isArray(authModes) && authModes.length) {
|
|
624
|
+
modelAuthModes[operation] = authModes;
|
|
625
|
+
}
|
|
626
|
+
else {
|
|
627
|
+
// Use default auth mode if nothing is returned from authModeStrategy
|
|
628
|
+
modelAuthModes[operation] = [defaultAuthMode];
|
|
629
|
+
}
|
|
630
|
+
}));
|
|
631
|
+
}
|
|
632
|
+
catch (error) {
|
|
633
|
+
logger.debug(`Error getting auth modes for model: ${modelName}`, error);
|
|
634
|
+
}
|
|
635
|
+
return modelAuthModes;
|
|
683
636
|
}
|
|
684
637
|
exports.getModelAuthModes = getModelAuthModes;
|
|
685
638
|
function getForbiddenError(error) {
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
'Request failed with status code 403',
|
|
689
|
-
];
|
|
690
|
-
var forbiddenError;
|
|
639
|
+
const forbiddenErrorCodes = [401, 403];
|
|
640
|
+
let forbiddenError;
|
|
691
641
|
if (error && error.errors) {
|
|
692
|
-
forbiddenError = error.errors.find(
|
|
693
|
-
return forbiddenErrorMessages.includes(err.message);
|
|
694
|
-
});
|
|
642
|
+
forbiddenError = error.errors.find(err => forbiddenErrorCodes.includes(resolveServiceErrorStatusCode(err)));
|
|
695
643
|
}
|
|
696
644
|
else if (error && error.message) {
|
|
697
645
|
forbiddenError = error;
|
|
698
646
|
}
|
|
699
647
|
if (forbiddenError) {
|
|
700
|
-
return forbiddenError.message
|
|
648
|
+
return (forbiddenError.message ??
|
|
649
|
+
`Request failed with status code ${resolveServiceErrorStatusCode(forbiddenError)}`);
|
|
701
650
|
}
|
|
702
651
|
return null;
|
|
703
652
|
}
|
|
704
653
|
exports.getForbiddenError = getForbiddenError;
|
|
654
|
+
function resolveServiceErrorStatusCode(error) {
|
|
655
|
+
if (error?.['$metadata']?.['httpStatusCode']) {
|
|
656
|
+
return Number(error?.['$metadata']?.['httpStatusCode']);
|
|
657
|
+
}
|
|
658
|
+
else if (error?.originalError) {
|
|
659
|
+
return resolveServiceErrorStatusCode(error?.originalError);
|
|
660
|
+
}
|
|
661
|
+
else {
|
|
662
|
+
return null;
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
exports.resolveServiceErrorStatusCode = resolveServiceErrorStatusCode;
|
|
705
666
|
function getClientSideAuthError(error) {
|
|
706
|
-
|
|
707
|
-
|
|
667
|
+
const clientSideAuthErrors = Object.values(api_1.GraphQLAuthError);
|
|
668
|
+
const clientSideError = error &&
|
|
708
669
|
error.message &&
|
|
709
|
-
clientSideAuthErrors.find(
|
|
710
|
-
return error.message.includes(clientError);
|
|
711
|
-
});
|
|
670
|
+
clientSideAuthErrors.find(clientError => error.message.includes(clientError));
|
|
712
671
|
return clientSideError || null;
|
|
713
672
|
}
|
|
714
673
|
exports.getClientSideAuthError = getClientSideAuthError;
|
|
715
|
-
function getTokenForCustomAuth(authMode, amplifyConfig) {
|
|
716
|
-
if (
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
if (!(authMode === api_graphql_1.GRAPHQL_AUTH_MODE.AWS_LAMBDA)) return [3 /*break*/, 6];
|
|
723
|
-
_a = amplifyConfig.authProviders, functionAuthProvider = (_a === void 0 ? { functionAuthProvider: null } : _a).functionAuthProvider;
|
|
724
|
-
if (!(functionAuthProvider && typeof functionAuthProvider === 'function')) return [3 /*break*/, 5];
|
|
725
|
-
_b.label = 1;
|
|
726
|
-
case 1:
|
|
727
|
-
_b.trys.push([1, 3, , 4]);
|
|
728
|
-
return [4 /*yield*/, functionAuthProvider()];
|
|
729
|
-
case 2:
|
|
730
|
-
token = (_b.sent()).token;
|
|
731
|
-
return [2 /*return*/, token];
|
|
732
|
-
case 3:
|
|
733
|
-
error_2 = _b.sent();
|
|
734
|
-
throw new Error("Error retrieving token from `functionAuthProvider`: " + error_2);
|
|
735
|
-
case 4: return [3 /*break*/, 6];
|
|
736
|
-
case 5:
|
|
737
|
-
// TODO: add docs link once available
|
|
738
|
-
throw new Error("You must provide a `functionAuthProvider` function to `DataStore.configure` when using " + api_graphql_1.GRAPHQL_AUTH_MODE.AWS_LAMBDA);
|
|
739
|
-
case 6: return [2 /*return*/];
|
|
674
|
+
async function getTokenForCustomAuth(authMode, amplifyConfig = {}) {
|
|
675
|
+
if (authMode === 'lambda') {
|
|
676
|
+
const { authProviders: { functionAuthProvider } = { functionAuthProvider: null }, } = amplifyConfig;
|
|
677
|
+
if (functionAuthProvider && typeof functionAuthProvider === 'function') {
|
|
678
|
+
try {
|
|
679
|
+
const { token } = await functionAuthProvider();
|
|
680
|
+
return token;
|
|
740
681
|
}
|
|
741
|
-
|
|
742
|
-
|
|
682
|
+
catch (error) {
|
|
683
|
+
throw new Error(`Error retrieving token from \`functionAuthProvider\`: ${error}`);
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
else {
|
|
687
|
+
// TODO: add docs link once available
|
|
688
|
+
throw new Error('You must provide a `functionAuthProvider` function to `DataStore.configure` when using lambda');
|
|
689
|
+
}
|
|
690
|
+
}
|
|
743
691
|
}
|
|
744
692
|
exports.getTokenForCustomAuth = getTokenForCustomAuth;
|
|
745
693
|
// Util that takes a modelDefinition and model and returns either the id value(s) or the custom primary key value(s)
|
|
746
694
|
function getIdentifierValue(modelDefinition, model) {
|
|
747
|
-
|
|
748
|
-
|
|
695
|
+
const pkFieldNames = (0, util_1.extractPrimaryKeyFieldNames)(modelDefinition);
|
|
696
|
+
const idOrPk = pkFieldNames.map(f => model[f]).join(util_1.IDENTIFIER_KEY_SEPARATOR);
|
|
749
697
|
return idOrPk;
|
|
750
698
|
}
|
|
751
699
|
exports.getIdentifierValue = getIdentifierValue;
|
|
752
|
-
//# sourceMappingURL=utils.js.map
|