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