@aws-amplify/datastore 5.0.1-api-v6-models.c1977f8.0 → 5.0.1-api-v6-models.891fe0d.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/authModeStrategies/defaultAuthStrategy.js +1 -1
- package/lib/authModeStrategies/multiAuthStrategy.js +29 -105
- package/lib/datastore/datastore.js +887 -1370
- package/lib/index.js +1 -1
- package/lib/predicates/index.js +53 -102
- package/lib/predicates/next.js +310 -557
- package/lib/predicates/sort.js +24 -27
- package/lib/ssr/index.js +1 -1
- package/lib/storage/adapter/AsyncStorageAdapter.js +115 -449
- package/lib/storage/adapter/AsyncStorageDatabase.js +215 -480
- package/lib/storage/adapter/InMemoryStore.js +27 -101
- package/lib/storage/adapter/InMemoryStore.native.js +1 -1
- package/lib/storage/adapter/IndexedDBAdapter.js +441 -1002
- package/lib/storage/adapter/StorageAdapterBase.js +177 -396
- package/lib/storage/adapter/getDefaultAdapter/index.js +5 -6
- package/lib/storage/adapter/getDefaultAdapter/index.native.js +2 -2
- package/lib/storage/relationship.js +174 -260
- package/lib/storage/storage.js +244 -507
- package/lib/sync/datastoreConnectivity.js +29 -84
- package/lib/sync/datastoreReachability/index.js +1 -1
- package/lib/sync/datastoreReachability/index.native.js +2 -2
- package/lib/sync/index.js +512 -885
- package/lib/sync/merger.js +30 -133
- package/lib/sync/outbox.js +147 -302
- package/lib/sync/processors/errorMaps.js +30 -80
- package/lib/sync/processors/mutation.js +331 -579
- package/lib/sync/processors/subscription.js +268 -428
- package/lib/sync/processors/sync.js +276 -464
- package/lib/sync/utils.js +248 -393
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/lib/types.js +16 -58
- package/lib/util.js +335 -575
- package/lib-esm/authModeStrategies/defaultAuthStrategy.js +1 -1
- package/lib-esm/authModeStrategies/multiAuthStrategy.js +27 -103
- package/lib-esm/datastore/datastore.js +874 -1359
- package/lib-esm/index.js +6 -6
- package/lib-esm/predicates/index.js +54 -104
- package/lib-esm/predicates/next.js +306 -555
- package/lib-esm/predicates/sort.js +24 -27
- package/lib-esm/ssr/index.js +1 -1
- package/lib-esm/storage/adapter/AsyncStorageAdapter.js +111 -446
- package/lib-esm/storage/adapter/AsyncStorageDatabase.js +212 -477
- package/lib-esm/storage/adapter/InMemoryStore.js +27 -102
- package/lib-esm/storage/adapter/IndexedDBAdapter.js +436 -997
- package/lib-esm/storage/adapter/StorageAdapterBase.js +172 -392
- package/lib-esm/storage/adapter/getDefaultAdapter/index.js +2 -3
- package/lib-esm/storage/adapter/getDefaultAdapter/index.native.js +1 -1
- package/lib-esm/storage/relationship.js +173 -260
- package/lib-esm/storage/storage.js +236 -499
- package/lib-esm/sync/datastoreConnectivity.js +26 -82
- package/lib-esm/sync/datastoreReachability/index.js +1 -1
- package/lib-esm/sync/datastoreReachability/index.native.js +1 -1
- package/lib-esm/sync/index.js +498 -872
- package/lib-esm/sync/merger.js +28 -131
- package/lib-esm/sync/outbox.js +143 -298
- package/lib-esm/sync/processors/errorMaps.js +32 -82
- package/lib-esm/sync/processors/mutation.js +324 -572
- package/lib-esm/sync/processors/subscription.js +258 -418
- package/lib-esm/sync/processors/sync.js +269 -457
- package/lib-esm/sync/utils.js +245 -390
- package/lib-esm/tsconfig.tsbuildinfo +1 -1
- package/lib-esm/types.js +16 -59
- package/lib-esm/util.js +335 -577
- package/package.json +12 -12
- package/src/datastore/datastore.ts +4 -3
- package/src/storage/adapter/getDefaultAdapter/index.ts +1 -3
- package/src/sync/processors/mutation.ts +1 -1
- package/src/sync/processors/sync.ts +1 -1
- package/src/sync/utils.ts +1 -1
- package/src/util.ts +44 -6
package/lib/sync/utils.js
CHANGED
|
@@ -1,96 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __assign = (this && this.__assign) || function () {
|
|
3
|
-
__assign = Object.assign || function(t) {
|
|
4
|
-
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
-
s = arguments[i];
|
|
6
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
-
t[p] = s[p];
|
|
8
|
-
}
|
|
9
|
-
return t;
|
|
10
|
-
};
|
|
11
|
-
return __assign.apply(this, arguments);
|
|
12
|
-
};
|
|
13
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
14
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
15
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
16
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
17
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
18
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
19
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
20
|
-
});
|
|
21
|
-
};
|
|
22
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
23
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
24
|
-
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
25
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
26
|
-
function step(op) {
|
|
27
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
28
|
-
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
29
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
30
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
31
|
-
switch (op[0]) {
|
|
32
|
-
case 0: case 1: t = op; break;
|
|
33
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
34
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
35
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
36
|
-
default:
|
|
37
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
38
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
39
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
40
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
41
|
-
if (t[2]) _.ops.pop();
|
|
42
|
-
_.trys.pop(); continue;
|
|
43
|
-
}
|
|
44
|
-
op = body.call(thisArg, _);
|
|
45
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
46
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
var __read = (this && this.__read) || function (o, n) {
|
|
50
|
-
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
51
|
-
if (!m) return o;
|
|
52
|
-
var i = m.call(o), r, ar = [], e;
|
|
53
|
-
try {
|
|
54
|
-
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
|
55
|
-
}
|
|
56
|
-
catch (error) { e = { error: error }; }
|
|
57
|
-
finally {
|
|
58
|
-
try {
|
|
59
|
-
if (r && !r.done && (m = i["return"])) m.call(i);
|
|
60
|
-
}
|
|
61
|
-
finally { if (e) throw e.error; }
|
|
62
|
-
}
|
|
63
|
-
return ar;
|
|
64
|
-
};
|
|
65
|
-
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
66
|
-
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
67
|
-
if (ar || !(i in from)) {
|
|
68
|
-
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
69
|
-
ar[i] = from[i];
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
return to.concat(ar || Array.prototype.slice.call(from));
|
|
73
|
-
};
|
|
74
|
-
var __values = (this && this.__values) || function(o) {
|
|
75
|
-
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
|
|
76
|
-
if (m) return m.call(o);
|
|
77
|
-
if (o && typeof o.length === "number") return {
|
|
78
|
-
next: function () {
|
|
79
|
-
if (o && i >= o.length) o = void 0;
|
|
80
|
-
return { value: o && o[i++], done: !o };
|
|
81
|
-
}
|
|
82
|
-
};
|
|
83
|
-
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
|
|
84
|
-
};
|
|
85
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
86
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;
|
|
87
4
|
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
88
5
|
// SPDX-License-Identifier: Apache-2.0
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
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');
|
|
94
11
|
var GraphQLOperationType;
|
|
95
12
|
(function (GraphQLOperationType) {
|
|
96
13
|
GraphQLOperationType["LIST"] = "query";
|
|
@@ -106,25 +23,22 @@ var TransformerMutationType;
|
|
|
106
23
|
TransformerMutationType["DELETE"] = "Delete";
|
|
107
24
|
TransformerMutationType["GET"] = "Get";
|
|
108
25
|
})(TransformerMutationType = exports.TransformerMutationType || (exports.TransformerMutationType = {}));
|
|
109
|
-
|
|
26
|
+
const dummyMetadata = {
|
|
110
27
|
_version: undefined,
|
|
111
28
|
_lastChangedAt: undefined,
|
|
112
29
|
_deleted: undefined,
|
|
113
30
|
};
|
|
114
|
-
|
|
31
|
+
const metadataFields = (Object.keys(dummyMetadata));
|
|
115
32
|
function getMetadataFields() {
|
|
116
33
|
return metadataFields;
|
|
117
34
|
}
|
|
118
35
|
exports.getMetadataFields = getMetadataFields;
|
|
119
36
|
function generateSelectionSet(namespace, modelDefinition) {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
.map(
|
|
125
|
-
var name = _a.name;
|
|
126
|
-
return name;
|
|
127
|
-
})
|
|
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)
|
|
128
42
|
.concat(implicitOwnerField)
|
|
129
43
|
.concat(nonModelFields);
|
|
130
44
|
if ((0, types_1.isSchemaModel)(modelDefinition)) {
|
|
@@ -132,23 +46,23 @@ function generateSelectionSet(namespace, modelDefinition) {
|
|
|
132
46
|
.concat(getMetadataFields())
|
|
133
47
|
.concat(getConnectionFields(modelDefinition, namespace));
|
|
134
48
|
}
|
|
135
|
-
|
|
49
|
+
const result = scalarAndMetadataFields.join('\n');
|
|
136
50
|
return result;
|
|
137
51
|
}
|
|
138
52
|
exports.generateSelectionSet = generateSelectionSet;
|
|
139
53
|
function getImplicitOwnerField(modelDefinition, scalarFields) {
|
|
140
|
-
|
|
54
|
+
const ownerFields = getOwnerFields(modelDefinition);
|
|
141
55
|
if (!scalarFields.owner && ownerFields.includes('owner')) {
|
|
142
56
|
return ['owner'];
|
|
143
57
|
}
|
|
144
58
|
return [];
|
|
145
59
|
}
|
|
146
60
|
function getOwnerFields(modelDefinition) {
|
|
147
|
-
|
|
61
|
+
const ownerFields = [];
|
|
148
62
|
if ((0, types_1.isSchemaModelWithAttributes)(modelDefinition)) {
|
|
149
|
-
modelDefinition.attributes.forEach(
|
|
63
|
+
modelDefinition.attributes.forEach(attr => {
|
|
150
64
|
if (attr.properties && attr.properties.rules) {
|
|
151
|
-
|
|
65
|
+
const rule = attr.properties.rules.find(rule => rule.allow === 'owner');
|
|
152
66
|
if (rule && rule.ownerField) {
|
|
153
67
|
ownerFields.push(rule.ownerField);
|
|
154
68
|
}
|
|
@@ -158,15 +72,15 @@ function getOwnerFields(modelDefinition) {
|
|
|
158
72
|
return ownerFields;
|
|
159
73
|
}
|
|
160
74
|
function getScalarFields(modelDefinition) {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
.filter(
|
|
75
|
+
const { fields } = modelDefinition;
|
|
76
|
+
const result = Object.values(fields)
|
|
77
|
+
.filter(field => {
|
|
164
78
|
if ((0, types_1.isGraphQLScalarType)(field.type) || (0, types_1.isEnumFieldType)(field.type)) {
|
|
165
79
|
return true;
|
|
166
80
|
}
|
|
167
81
|
return false;
|
|
168
82
|
})
|
|
169
|
-
.reduce(
|
|
83
|
+
.reduce((acc, field) => {
|
|
170
84
|
acc[field.name] = field;
|
|
171
85
|
return acc;
|
|
172
86
|
}, {});
|
|
@@ -174,15 +88,11 @@ function getScalarFields(modelDefinition) {
|
|
|
174
88
|
}
|
|
175
89
|
// Used for generating the selection set for queries and mutations
|
|
176
90
|
function getConnectionFields(modelDefinition, namespace) {
|
|
177
|
-
|
|
91
|
+
const result = [];
|
|
178
92
|
Object.values(modelDefinition.fields)
|
|
179
|
-
.filter(
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
})
|
|
183
|
-
.forEach(function (_a) {
|
|
184
|
-
var name = _a.name, association = _a.association;
|
|
185
|
-
var connectionType = (association || {}).connectionType;
|
|
93
|
+
.filter(({ association }) => association && Object.keys(association).length)
|
|
94
|
+
.forEach(({ name, association }) => {
|
|
95
|
+
const { connectionType } = association || {};
|
|
186
96
|
switch (connectionType) {
|
|
187
97
|
case 'HAS_ONE':
|
|
188
98
|
case 'HAS_MANY':
|
|
@@ -193,86 +103,79 @@ function getConnectionFields(modelDefinition, namespace) {
|
|
|
193
103
|
// New codegen (CPK)
|
|
194
104
|
if (association.targetNames && association.targetNames.length > 0) {
|
|
195
105
|
// Need to retrieve relations in order to get connected model keys
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
});
|
|
202
|
-
var keyFields = byPkIndex && byPkIndex[1];
|
|
203
|
-
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(' ');
|
|
204
111
|
// We rely on `_deleted` when we process the sync query (e.g. in batchSave in the adapters)
|
|
205
|
-
result.push(
|
|
112
|
+
result.push(`${name} { ${keyFieldSelectionSet} _deleted }`);
|
|
206
113
|
}
|
|
207
114
|
else {
|
|
208
115
|
// backwards-compatability for schema generated prior to custom primary key support
|
|
209
|
-
result.push(
|
|
116
|
+
result.push(`${name} { id _deleted }`);
|
|
210
117
|
}
|
|
211
118
|
}
|
|
212
119
|
break;
|
|
213
120
|
default:
|
|
214
|
-
throw new Error(
|
|
121
|
+
throw new Error(`Invalid connection type ${connectionType}`);
|
|
215
122
|
}
|
|
216
123
|
});
|
|
217
124
|
return result;
|
|
218
125
|
}
|
|
219
126
|
function getNonModelFields(namespace, modelDefinition) {
|
|
220
|
-
|
|
221
|
-
Object.values(modelDefinition.fields).forEach(
|
|
222
|
-
var name = _a.name, type = _a.type;
|
|
127
|
+
const result = [];
|
|
128
|
+
Object.values(modelDefinition.fields).forEach(({ name, type }) => {
|
|
223
129
|
if ((0, types_1.isNonModelFieldType)(type)) {
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
var nested_1 = [];
|
|
230
|
-
Object.values(typeDefinition.fields).forEach(function (field) {
|
|
231
|
-
var type = field.type, name = field.name;
|
|
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;
|
|
232
135
|
if ((0, types_1.isNonModelFieldType)(type)) {
|
|
233
|
-
|
|
234
|
-
|
|
136
|
+
const typeDefinition = namespace.nonModels[type.nonModel];
|
|
137
|
+
nested.push(`${name} { ${generateSelectionSet(namespace, typeDefinition)} }`);
|
|
235
138
|
}
|
|
236
139
|
});
|
|
237
|
-
result.push(
|
|
140
|
+
result.push(`${name} { ${scalarFields.join(' ')} ${nested.join(' ')} }`);
|
|
238
141
|
}
|
|
239
142
|
});
|
|
240
143
|
return result;
|
|
241
144
|
}
|
|
242
145
|
function getAuthorizationRules(modelDefinition) {
|
|
243
146
|
// Searching for owner authorization on attributes
|
|
244
|
-
|
|
147
|
+
const authConfig = []
|
|
245
148
|
.concat(modelDefinition.attributes || [])
|
|
246
|
-
.find(
|
|
247
|
-
|
|
248
|
-
|
|
149
|
+
.find(attr => attr && attr.type === 'auth');
|
|
150
|
+
const { properties: { rules = [] } = {} } = authConfig || {};
|
|
151
|
+
const resultRules = [];
|
|
249
152
|
// Multiple rules can be declared for allow: owner
|
|
250
|
-
rules.forEach(
|
|
153
|
+
rules.forEach(rule => {
|
|
251
154
|
// setting defaults for backwards compatibility with old cli
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
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';
|
|
255
158
|
if (!isReadAuthorized && !isOwnerAuth) {
|
|
256
159
|
return;
|
|
257
160
|
}
|
|
258
|
-
|
|
259
|
-
identityClaim
|
|
260
|
-
ownerField
|
|
261
|
-
provider
|
|
262
|
-
groupClaim
|
|
263
|
-
authStrategy
|
|
264
|
-
groups
|
|
265
|
-
groupsField
|
|
161
|
+
const authRule = {
|
|
162
|
+
identityClaim,
|
|
163
|
+
ownerField,
|
|
164
|
+
provider,
|
|
165
|
+
groupClaim,
|
|
166
|
+
authStrategy,
|
|
167
|
+
groups,
|
|
168
|
+
groupsField,
|
|
266
169
|
areSubscriptionsPublic: false,
|
|
267
170
|
};
|
|
268
171
|
if (isOwnerAuth) {
|
|
269
172
|
// look for the subscription level override
|
|
270
173
|
// only pay attention to the public level
|
|
271
|
-
|
|
174
|
+
const modelConfig = []
|
|
272
175
|
.concat(modelDefinition.attributes || [])
|
|
273
|
-
.find(
|
|
176
|
+
.find(attr => attr && attr.type === 'model');
|
|
274
177
|
// find the subscriptions level. ON is default
|
|
275
|
-
|
|
178
|
+
const { properties: { subscriptions: { level = 'on' } = {} } = {} } = modelConfig || {};
|
|
276
179
|
// treat subscriptions as public for owner auth with unprotected reads
|
|
277
180
|
// when `read` is omitted from `operations`
|
|
278
181
|
authRule.areSubscriptionsPublic =
|
|
@@ -288,83 +191,94 @@ function getAuthorizationRules(modelDefinition) {
|
|
|
288
191
|
return resultRules;
|
|
289
192
|
}
|
|
290
193
|
exports.getAuthorizationRules = getAuthorizationRules;
|
|
291
|
-
function buildSubscriptionGraphQLOperation(namespace, modelDefinition, transformerMutationType, isOwnerAuthorization, ownerField, filterArg) {
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
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 = [];
|
|
298
200
|
if (filterArg) {
|
|
299
|
-
docArgs.push(
|
|
201
|
+
docArgs.push(`$filter: ModelSubscription${typeName}FilterInput`);
|
|
300
202
|
opArgs.push('filter: $filter');
|
|
301
203
|
}
|
|
302
204
|
if (isOwnerAuthorization) {
|
|
303
|
-
docArgs.push(
|
|
304
|
-
opArgs.push(
|
|
205
|
+
docArgs.push(`$${ownerField}: String!`);
|
|
206
|
+
opArgs.push(`${ownerField}: $${ownerField}`);
|
|
305
207
|
}
|
|
306
|
-
|
|
307
|
-
|
|
208
|
+
const docStr = docArgs.length ? `(${docArgs.join(',')})` : '';
|
|
209
|
+
const opStr = opArgs.length ? `(${opArgs.join(',')})` : '';
|
|
308
210
|
return [
|
|
309
211
|
transformerMutationType,
|
|
310
212
|
opName,
|
|
311
|
-
|
|
213
|
+
`subscription operation${docStr}{
|
|
214
|
+
${opName}${opStr}{
|
|
215
|
+
${selectionSet}
|
|
216
|
+
}
|
|
217
|
+
}`,
|
|
312
218
|
];
|
|
313
219
|
}
|
|
314
220
|
exports.buildSubscriptionGraphQLOperation = buildSubscriptionGraphQLOperation;
|
|
315
221
|
function buildGraphQLOperation(namespace, modelDefinition, graphQLOpType) {
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
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;
|
|
322
228
|
switch (graphQLOpType) {
|
|
323
229
|
case 'LIST':
|
|
324
|
-
operation =
|
|
325
|
-
documentArgs =
|
|
230
|
+
operation = `sync${pluralTypeName}`;
|
|
231
|
+
documentArgs = `($limit: Int, $nextToken: String, $lastSync: AWSTimestamp, $filter: Model${typeName}FilterInput)`;
|
|
326
232
|
operationArgs =
|
|
327
233
|
'(limit: $limit, nextToken: $nextToken, lastSync: $lastSync, filter: $filter)';
|
|
328
|
-
selectionSet =
|
|
234
|
+
selectionSet = `items {
|
|
235
|
+
${selectionSet}
|
|
236
|
+
}
|
|
237
|
+
nextToken
|
|
238
|
+
startedAt`;
|
|
329
239
|
break;
|
|
330
240
|
case 'CREATE':
|
|
331
|
-
operation =
|
|
332
|
-
documentArgs =
|
|
241
|
+
operation = `create${typeName}`;
|
|
242
|
+
documentArgs = `($input: Create${typeName}Input!)`;
|
|
333
243
|
operationArgs = '(input: $input)';
|
|
334
244
|
transformerMutationType = TransformerMutationType.CREATE;
|
|
335
245
|
break;
|
|
336
246
|
case 'UPDATE':
|
|
337
|
-
operation =
|
|
338
|
-
documentArgs =
|
|
247
|
+
operation = `update${typeName}`;
|
|
248
|
+
documentArgs = `($input: Update${typeName}Input!, $condition: Model${typeName}ConditionInput)`;
|
|
339
249
|
operationArgs = '(input: $input, condition: $condition)';
|
|
340
250
|
transformerMutationType = TransformerMutationType.UPDATE;
|
|
341
251
|
break;
|
|
342
252
|
case 'DELETE':
|
|
343
|
-
operation =
|
|
344
|
-
documentArgs =
|
|
253
|
+
operation = `delete${typeName}`;
|
|
254
|
+
documentArgs = `($input: Delete${typeName}Input!, $condition: Model${typeName}ConditionInput)`;
|
|
345
255
|
operationArgs = '(input: $input, condition: $condition)';
|
|
346
256
|
transformerMutationType = TransformerMutationType.DELETE;
|
|
347
257
|
break;
|
|
348
258
|
case 'GET':
|
|
349
|
-
operation =
|
|
350
|
-
documentArgs =
|
|
259
|
+
operation = `get${typeName}`;
|
|
260
|
+
documentArgs = `($id: ID!)`;
|
|
351
261
|
operationArgs = '(id: $id)';
|
|
352
262
|
transformerMutationType = TransformerMutationType.GET;
|
|
353
263
|
break;
|
|
354
264
|
default:
|
|
355
|
-
throw new Error(
|
|
265
|
+
throw new Error(`Invalid graphQlOpType ${graphQLOpType}`);
|
|
356
266
|
}
|
|
357
267
|
return [
|
|
358
268
|
[
|
|
359
269
|
transformerMutationType,
|
|
360
270
|
operation,
|
|
361
|
-
|
|
271
|
+
`${GraphQLOperationType[graphQLOpType]} operation${documentArgs}{
|
|
272
|
+
${operation}${operationArgs}{
|
|
273
|
+
${selectionSet}
|
|
274
|
+
}
|
|
275
|
+
}`,
|
|
362
276
|
],
|
|
363
277
|
];
|
|
364
278
|
}
|
|
365
279
|
exports.buildGraphQLOperation = buildGraphQLOperation;
|
|
366
280
|
function createMutationInstanceFromModelOperation(relationships, modelDefinition, opType, model, element, condition, MutationEventConstructor, modelInstanceCreator, id) {
|
|
367
|
-
|
|
281
|
+
let operation;
|
|
368
282
|
switch (opType) {
|
|
369
283
|
case types_1.OpType.INSERT:
|
|
370
284
|
operation = TransformerMutationType.CREATE;
|
|
@@ -376,13 +290,13 @@ function createMutationInstanceFromModelOperation(relationships, modelDefinition
|
|
|
376
290
|
operation = TransformerMutationType.DELETE;
|
|
377
291
|
break;
|
|
378
292
|
default:
|
|
379
|
-
throw new Error(
|
|
293
|
+
throw new Error(`Invalid opType ${opType}`);
|
|
380
294
|
}
|
|
381
295
|
// stringify nested objects of type AWSJSON
|
|
382
296
|
// this allows us to return parsed JSON to users (see `castInstanceType()` in datastore.ts),
|
|
383
297
|
// but still send the object correctly over the wire
|
|
384
|
-
|
|
385
|
-
|
|
298
|
+
const replacer = (k, v) => {
|
|
299
|
+
const isAWSJSON = k &&
|
|
386
300
|
v !== null &&
|
|
387
301
|
typeof v === 'object' &&
|
|
388
302
|
modelDefinition.fields[k] &&
|
|
@@ -392,14 +306,21 @@ function createMutationInstanceFromModelOperation(relationships, modelDefinition
|
|
|
392
306
|
}
|
|
393
307
|
return v;
|
|
394
308
|
};
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
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
|
+
});
|
|
398
319
|
return mutationEvent;
|
|
399
320
|
}
|
|
400
321
|
exports.createMutationInstanceFromModelOperation = createMutationInstanceFromModelOperation;
|
|
401
322
|
function predicateToGraphQLCondition(predicate, modelDefinition) {
|
|
402
|
-
|
|
323
|
+
const result = {};
|
|
403
324
|
if (!predicate || !Array.isArray(predicate.predicates)) {
|
|
404
325
|
return result;
|
|
405
326
|
}
|
|
@@ -410,7 +331,7 @@ function predicateToGraphQLCondition(predicate, modelDefinition) {
|
|
|
410
331
|
// Or all records where PK = some value but SKs are different values
|
|
411
332
|
// TODO: if the Transform gets updated we'll need to modify this logic to only omit
|
|
412
333
|
// key fields from the predicate/condition when ALL of the keyFields are present and using `eq` operators
|
|
413
|
-
|
|
334
|
+
const keyFields = (0, util_1.extractPrimaryKeyFieldNames)(modelDefinition);
|
|
414
335
|
return predicateToGraphQLFilter(predicate, keyFields);
|
|
415
336
|
}
|
|
416
337
|
exports.predicateToGraphQLCondition = predicateToGraphQLCondition;
|
|
@@ -429,37 +350,34 @@ exports.predicateToGraphQLCondition = predicateToGraphQLCondition;
|
|
|
429
350
|
{ and:[{ username: { eq: 'bob' }}] }
|
|
430
351
|
```
|
|
431
352
|
*/
|
|
432
|
-
function predicateToGraphQLFilter(predicatesGroup, fieldsToOmit, root) {
|
|
433
|
-
|
|
434
|
-
if (root === void 0) { root = true; }
|
|
435
|
-
var result = {};
|
|
353
|
+
function predicateToGraphQLFilter(predicatesGroup, fieldsToOmit = [], root = true) {
|
|
354
|
+
const result = {};
|
|
436
355
|
if (!predicatesGroup || !Array.isArray(predicatesGroup.predicates)) {
|
|
437
356
|
return result;
|
|
438
357
|
}
|
|
439
|
-
|
|
440
|
-
|
|
358
|
+
const { type, predicates } = predicatesGroup;
|
|
359
|
+
const isList = type === 'and' || type === 'or';
|
|
441
360
|
result[type] = isList ? [] : {};
|
|
442
|
-
|
|
443
|
-
predicates.forEach(
|
|
444
|
-
var _a, _b;
|
|
361
|
+
const children = [];
|
|
362
|
+
predicates.forEach(predicate => {
|
|
445
363
|
if ((0, types_1.isPredicateObj)(predicate)) {
|
|
446
|
-
|
|
364
|
+
const { field, operator, operand } = predicate;
|
|
447
365
|
if (fieldsToOmit.includes(field))
|
|
448
366
|
return;
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
367
|
+
const gqlField = {
|
|
368
|
+
[field]: { [operator]: operand },
|
|
369
|
+
};
|
|
452
370
|
children.push(gqlField);
|
|
453
371
|
return;
|
|
454
372
|
}
|
|
455
|
-
|
|
373
|
+
const child = predicateToGraphQLFilter(predicate, fieldsToOmit, false);
|
|
456
374
|
if (Object.keys(child).length > 0) {
|
|
457
375
|
children.push(child);
|
|
458
376
|
}
|
|
459
377
|
});
|
|
460
378
|
// flatten redundant list predicates
|
|
461
379
|
if (children.length === 1) {
|
|
462
|
-
|
|
380
|
+
const [child] = children;
|
|
463
381
|
if (
|
|
464
382
|
// any nested list node
|
|
465
383
|
(isList && !root) ||
|
|
@@ -470,7 +388,7 @@ function predicateToGraphQLFilter(predicatesGroup, fieldsToOmit, root) {
|
|
|
470
388
|
return result;
|
|
471
389
|
}
|
|
472
390
|
}
|
|
473
|
-
children.forEach(
|
|
391
|
+
children.forEach(child => {
|
|
474
392
|
if (isList) {
|
|
475
393
|
result[type].push(child);
|
|
476
394
|
}
|
|
@@ -495,18 +413,18 @@ exports.predicateToGraphQLFilter = predicateToGraphQLFilter;
|
|
|
495
413
|
* @returns set of distinct field names in the filter group
|
|
496
414
|
*/
|
|
497
415
|
function filterFields(group) {
|
|
498
|
-
|
|
416
|
+
const fields = new Set();
|
|
499
417
|
if (!group || !Array.isArray(group.predicates))
|
|
500
418
|
return fields;
|
|
501
|
-
|
|
502
|
-
|
|
419
|
+
const { predicates } = group;
|
|
420
|
+
const stack = [...predicates];
|
|
503
421
|
while (stack.length > 0) {
|
|
504
|
-
|
|
422
|
+
const current = stack.pop();
|
|
505
423
|
if ((0, types_1.isPredicateObj)(current)) {
|
|
506
424
|
fields.add(current.field);
|
|
507
425
|
}
|
|
508
426
|
else if ((0, types_1.isPredicateGroup)(current)) {
|
|
509
|
-
stack.push
|
|
427
|
+
stack.push(...current.predicates);
|
|
510
428
|
}
|
|
511
429
|
}
|
|
512
430
|
return fields;
|
|
@@ -518,27 +436,16 @@ exports.filterFields = filterFields;
|
|
|
518
436
|
* @returns set of field names used with dynamic auth modes configured for the provided model definition
|
|
519
437
|
*/
|
|
520
438
|
function dynamicAuthFields(modelDefinition) {
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
if (rule.groupsField && !rule.groups.length) {
|
|
528
|
-
// dynamic group rule will have no values in `rule.groups`
|
|
529
|
-
fields.add(rule.groupsField);
|
|
530
|
-
}
|
|
531
|
-
else if (rule.ownerField) {
|
|
532
|
-
fields.add(rule.ownerField);
|
|
533
|
-
}
|
|
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);
|
|
534
445
|
}
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
finally {
|
|
538
|
-
try {
|
|
539
|
-
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);
|
|
540
448
|
}
|
|
541
|
-
finally { if (e_1) throw e_1.error; }
|
|
542
449
|
}
|
|
543
450
|
return fields;
|
|
544
451
|
}
|
|
@@ -559,17 +466,17 @@ exports.dynamicAuthFields = dynamicAuthFields;
|
|
|
559
466
|
function countFilterCombinations(group) {
|
|
560
467
|
if (!group || !Array.isArray(group.predicates))
|
|
561
468
|
return 0;
|
|
562
|
-
|
|
563
|
-
|
|
469
|
+
let count = 0;
|
|
470
|
+
const stack = [group];
|
|
564
471
|
while (stack.length > 0) {
|
|
565
|
-
|
|
472
|
+
const current = stack.pop();
|
|
566
473
|
if ((0, types_1.isPredicateGroup)(current)) {
|
|
567
|
-
|
|
474
|
+
const { predicates, type } = current;
|
|
568
475
|
// ignore length = 1; groups with 1 predicate will get flattened when converted to gqlFilter
|
|
569
476
|
if (type === 'or' && predicates.length > 1) {
|
|
570
477
|
count += predicates.length;
|
|
571
478
|
}
|
|
572
|
-
stack.push
|
|
479
|
+
stack.push(...predicates);
|
|
573
480
|
}
|
|
574
481
|
}
|
|
575
482
|
// if we didn't encounter any OR groups, default to 1
|
|
@@ -593,50 +500,37 @@ function repeatedFieldInGroup(group) {
|
|
|
593
500
|
if (!group || !Array.isArray(group.predicates))
|
|
594
501
|
return null;
|
|
595
502
|
// convert to filter in order to flatten redundant groups
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
var _b = __read(Object.keys(f), 1), fieldName = _b[0];
|
|
605
|
-
if (seen[fieldName]) {
|
|
606
|
-
return fieldName;
|
|
607
|
-
}
|
|
608
|
-
seen[fieldName] = true;
|
|
609
|
-
}
|
|
610
|
-
}
|
|
611
|
-
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
612
|
-
finally {
|
|
613
|
-
try {
|
|
614
|
-
if (fields_1_1 && !fields_1_1.done && (_a = fields_1.return)) _a.call(fields_1);
|
|
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;
|
|
615
511
|
}
|
|
616
|
-
|
|
512
|
+
seen[fieldName] = true;
|
|
617
513
|
}
|
|
618
514
|
return null;
|
|
619
515
|
};
|
|
620
516
|
while (stack.length > 0) {
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
517
|
+
const current = stack.pop();
|
|
518
|
+
const [key] = Object.keys(current);
|
|
519
|
+
const values = current[key];
|
|
624
520
|
if (!Array.isArray(values)) {
|
|
625
521
|
return null;
|
|
626
522
|
}
|
|
627
523
|
// field value will be single object
|
|
628
|
-
|
|
524
|
+
const predicateObjects = values.filter(v => !Array.isArray(Object.values(v)[0]));
|
|
629
525
|
// group value will be an array
|
|
630
|
-
|
|
631
|
-
return Array.isArray(Object.values(v)[0]);
|
|
632
|
-
});
|
|
526
|
+
const predicateGroups = values.filter(v => Array.isArray(Object.values(v)[0]));
|
|
633
527
|
if (key === 'and') {
|
|
634
|
-
|
|
528
|
+
const repeatedField = hasGroupRepeatedFields(predicateObjects);
|
|
635
529
|
if (repeatedField) {
|
|
636
530
|
return repeatedField;
|
|
637
531
|
}
|
|
638
532
|
}
|
|
639
|
-
stack.push
|
|
533
|
+
stack.push(...predicateGroups);
|
|
640
534
|
}
|
|
641
535
|
return null;
|
|
642
536
|
}
|
|
@@ -651,41 +545,41 @@ var RTFError;
|
|
|
651
545
|
RTFError[RTFError["FieldNotInType"] = 5] = "FieldNotInType";
|
|
652
546
|
})(RTFError = exports.RTFError || (exports.RTFError = {}));
|
|
653
547
|
function generateRTFRemediation(errorType, modelDefinition, predicatesGroup) {
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
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);
|
|
660
554
|
switch (errorType) {
|
|
661
555
|
case RTFError.UnknownField:
|
|
662
|
-
return (
|
|
556
|
+
return (`Your API was generated with an older version of the CLI that doesn't support backend subscription filtering.` +
|
|
663
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`');
|
|
664
558
|
case RTFError.MaxAttributes: {
|
|
665
|
-
|
|
559
|
+
let message = `Your selective sync expression for ${modelDefinition.name} contains ${selSyncFields.size} different model fields: ${selSyncFieldStr}.\n\n`;
|
|
666
560
|
if (dynamicAuthModeFields.size > 0) {
|
|
667
561
|
message +=
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
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}.`;
|
|
671
565
|
}
|
|
672
566
|
return message;
|
|
673
567
|
}
|
|
674
568
|
case RTFError.MaxCombinations: {
|
|
675
|
-
|
|
569
|
+
let message = `Your selective sync expression for ${modelDefinition.name} contains ${filterCombinations} field combinations (total number of predicates in an OR expression).\n\n`;
|
|
676
570
|
if (dynamicAuthModeFields.size > 0) {
|
|
677
571
|
message +=
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
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}.`;
|
|
681
575
|
}
|
|
682
576
|
return message;
|
|
683
577
|
}
|
|
684
578
|
case RTFError.RepeatedFieldname:
|
|
685
|
-
return
|
|
579
|
+
return `Your selective sync expression for ${modelDefinition.name} contains multiple entries for ${repeatedField} in the same AND group.`;
|
|
686
580
|
case RTFError.NotGroup:
|
|
687
|
-
return (
|
|
688
|
-
|
|
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.`);
|
|
689
583
|
case RTFError.FieldNotInType:
|
|
690
584
|
// no remediation instructions. We'll surface the message directly
|
|
691
585
|
return '';
|
|
@@ -694,9 +588,9 @@ function generateRTFRemediation(errorType, modelDefinition, predicatesGroup) {
|
|
|
694
588
|
exports.generateRTFRemediation = generateRTFRemediation;
|
|
695
589
|
function getUserGroupsFromToken(token, rule) {
|
|
696
590
|
// validate token against groupClaim
|
|
697
|
-
|
|
591
|
+
let userGroups = token[rule.groupClaim] || [];
|
|
698
592
|
if (typeof userGroups === 'string') {
|
|
699
|
-
|
|
593
|
+
let parsedGroups;
|
|
700
594
|
try {
|
|
701
595
|
parsedGroups = JSON.parse(userGroups);
|
|
702
596
|
}
|
|
@@ -708,87 +602,61 @@ function getUserGroupsFromToken(token, rule) {
|
|
|
708
602
|
return userGroups;
|
|
709
603
|
}
|
|
710
604
|
exports.getUserGroupsFromToken = getUserGroupsFromToken;
|
|
711
|
-
function getModelAuthModes(
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
_b.trys.push([1, 3, , 4]);
|
|
729
|
-
return [4 /*yield*/, Promise.all(operations.map(function (operation) { return __awaiter(_this, void 0, void 0, function () {
|
|
730
|
-
var authModes;
|
|
731
|
-
return __generator(this, function (_a) {
|
|
732
|
-
switch (_a.label) {
|
|
733
|
-
case 0: return [4 /*yield*/, authModeStrategy({
|
|
734
|
-
schema: schema,
|
|
735
|
-
modelName: modelName,
|
|
736
|
-
operation: operation,
|
|
737
|
-
})];
|
|
738
|
-
case 1:
|
|
739
|
-
authModes = _a.sent();
|
|
740
|
-
if (typeof authModes === 'string') {
|
|
741
|
-
modelAuthModes[operation] = [authModes];
|
|
742
|
-
}
|
|
743
|
-
else if (Array.isArray(authModes) && authModes.length) {
|
|
744
|
-
modelAuthModes[operation] = authModes;
|
|
745
|
-
}
|
|
746
|
-
else {
|
|
747
|
-
// Use default auth mode if nothing is returned from authModeStrategy
|
|
748
|
-
modelAuthModes[operation] = [defaultAuthMode];
|
|
749
|
-
}
|
|
750
|
-
return [2 /*return*/];
|
|
751
|
-
}
|
|
752
|
-
});
|
|
753
|
-
}); }))];
|
|
754
|
-
case 2:
|
|
755
|
-
_b.sent();
|
|
756
|
-
return [3 /*break*/, 4];
|
|
757
|
-
case 3:
|
|
758
|
-
error_1 = _b.sent();
|
|
759
|
-
logger.debug("Error getting auth modes for model: ".concat(modelName), error_1);
|
|
760
|
-
return [3 /*break*/, 4];
|
|
761
|
-
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];
|
|
762
622
|
}
|
|
763
|
-
|
|
764
|
-
|
|
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;
|
|
765
636
|
}
|
|
766
637
|
exports.getModelAuthModes = getModelAuthModes;
|
|
767
638
|
function getForbiddenError(error) {
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
var forbiddenError;
|
|
639
|
+
const forbiddenErrorCodes = [401, 403];
|
|
640
|
+
let forbiddenError;
|
|
771
641
|
if (error && error.errors) {
|
|
772
|
-
forbiddenError = error.errors.find(
|
|
773
|
-
return forbiddenErrorCodes.includes(resolveServiceErrorStatusCode(err));
|
|
774
|
-
});
|
|
642
|
+
forbiddenError = error.errors.find(err => forbiddenErrorCodes.includes(resolveServiceErrorStatusCode(err)));
|
|
775
643
|
}
|
|
776
644
|
else if (error && error.message) {
|
|
777
645
|
forbiddenError = error;
|
|
778
646
|
}
|
|
779
647
|
if (forbiddenError) {
|
|
780
|
-
return (
|
|
648
|
+
return (forbiddenError.message ??
|
|
649
|
+
`Request failed with status code ${resolveServiceErrorStatusCode(forbiddenError)}`);
|
|
781
650
|
}
|
|
782
651
|
return null;
|
|
783
652
|
}
|
|
784
653
|
exports.getForbiddenError = getForbiddenError;
|
|
785
654
|
function resolveServiceErrorStatusCode(error) {
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
return Number((_b = error === null || error === void 0 ? void 0 : error['$metadata']) === null || _b === void 0 ? void 0 : _b['httpStatusCode']);
|
|
655
|
+
if (error?.['$metadata']?.['httpStatusCode']) {
|
|
656
|
+
return Number(error?.['$metadata']?.['httpStatusCode']);
|
|
789
657
|
}
|
|
790
|
-
else if (error
|
|
791
|
-
return resolveServiceErrorStatusCode(error
|
|
658
|
+
else if (error?.originalError) {
|
|
659
|
+
return resolveServiceErrorStatusCode(error?.originalError);
|
|
792
660
|
}
|
|
793
661
|
else {
|
|
794
662
|
return null;
|
|
@@ -796,49 +664,36 @@ function resolveServiceErrorStatusCode(error) {
|
|
|
796
664
|
}
|
|
797
665
|
exports.resolveServiceErrorStatusCode = resolveServiceErrorStatusCode;
|
|
798
666
|
function getClientSideAuthError(error) {
|
|
799
|
-
|
|
800
|
-
|
|
667
|
+
const clientSideAuthErrors = Object.values(api_1.GraphQLAuthError);
|
|
668
|
+
const clientSideError = error &&
|
|
801
669
|
error.message &&
|
|
802
|
-
clientSideAuthErrors.find(
|
|
803
|
-
return error.message.includes(clientError);
|
|
804
|
-
});
|
|
670
|
+
clientSideAuthErrors.find(clientError => error.message.includes(clientError));
|
|
805
671
|
return clientSideError || null;
|
|
806
672
|
}
|
|
807
673
|
exports.getClientSideAuthError = getClientSideAuthError;
|
|
808
|
-
function getTokenForCustomAuth(authMode, amplifyConfig) {
|
|
809
|
-
if (
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
if (!(authMode === 'lambda')) return [3 /*break*/, 6];
|
|
816
|
-
_a = amplifyConfig.authProviders, _b = _a === void 0 ? { functionAuthProvider: null } : _a, functionAuthProvider = _b.functionAuthProvider;
|
|
817
|
-
if (!(functionAuthProvider && typeof functionAuthProvider === 'function')) return [3 /*break*/, 5];
|
|
818
|
-
_c.label = 1;
|
|
819
|
-
case 1:
|
|
820
|
-
_c.trys.push([1, 3, , 4]);
|
|
821
|
-
return [4 /*yield*/, functionAuthProvider()];
|
|
822
|
-
case 2:
|
|
823
|
-
token = (_c.sent()).token;
|
|
824
|
-
return [2 /*return*/, token];
|
|
825
|
-
case 3:
|
|
826
|
-
error_2 = _c.sent();
|
|
827
|
-
throw new Error("Error retrieving token from `functionAuthProvider`: ".concat(error_2));
|
|
828
|
-
case 4: return [3 /*break*/, 6];
|
|
829
|
-
case 5:
|
|
830
|
-
// TODO: add docs link once available
|
|
831
|
-
throw new Error('You must provide a `functionAuthProvider` function to `DataStore.configure` when using lambda');
|
|
832
|
-
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;
|
|
833
681
|
}
|
|
834
|
-
|
|
835
|
-
|
|
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
|
+
}
|
|
836
691
|
}
|
|
837
692
|
exports.getTokenForCustomAuth = getTokenForCustomAuth;
|
|
838
693
|
// Util that takes a modelDefinition and model and returns either the id value(s) or the custom primary key value(s)
|
|
839
694
|
function getIdentifierValue(modelDefinition, model) {
|
|
840
|
-
|
|
841
|
-
|
|
695
|
+
const pkFieldNames = (0, util_1.extractPrimaryKeyFieldNames)(modelDefinition);
|
|
696
|
+
const idOrPk = pkFieldNames.map(f => model[f]).join(util_1.IDENTIFIER_KEY_SEPARATOR);
|
|
842
697
|
return idOrPk;
|
|
843
698
|
}
|
|
844
699
|
exports.getIdentifierValue = getIdentifierValue;
|