@aws-amplify/datastore
Version:
AppSyncLocal support for aws-amplify
750 lines (748 loc) • 33.2 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var api_graphql_1 = require("@aws-amplify/api-graphql");
var api_1 = require("@aws-amplify/api");
var core_1 = require("@aws-amplify/core");
var types_1 = require("../types");
var util_1 = require("../util");
var logger = new core_1.Logger('DataStore');
var GraphQLOperationType;
(function (GraphQLOperationType) {
GraphQLOperationType["LIST"] = "query";
GraphQLOperationType["CREATE"] = "mutation";
GraphQLOperationType["UPDATE"] = "mutation";
GraphQLOperationType["DELETE"] = "mutation";
GraphQLOperationType["GET"] = "query";
})(GraphQLOperationType || (GraphQLOperationType = {}));
var TransformerMutationType;
(function (TransformerMutationType) {
TransformerMutationType["CREATE"] = "Create";
TransformerMutationType["UPDATE"] = "Update";
TransformerMutationType["DELETE"] = "Delete";
TransformerMutationType["GET"] = "Get";
})(TransformerMutationType = exports.TransformerMutationType || (exports.TransformerMutationType = {}));
var dummyMetadata = {
_version: undefined,
_lastChangedAt: undefined,
_deleted: undefined,
};
var metadataFields = (Object.keys(dummyMetadata));
function getMetadataFields() {
return metadataFields;
}
exports.getMetadataFields = getMetadataFields;
function generateSelectionSet(namespace, modelDefinition) {
var scalarFields = getScalarFields(modelDefinition);
var nonModelFields = getNonModelFields(namespace, modelDefinition);
var implicitOwnerField = getImplicitOwnerField(modelDefinition, scalarFields);
var scalarAndMetadataFields = Object.values(scalarFields)
.map(function (_a) {
var name = _a.name;
return name;
})
.concat(implicitOwnerField)
.concat(nonModelFields);
if (types_1.isSchemaModel(modelDefinition)) {
scalarAndMetadataFields = scalarAndMetadataFields
.concat(getMetadataFields())
.concat(getConnectionFields(modelDefinition, namespace));
}
var result = scalarAndMetadataFields.join('\n');
return result;
}
exports.generateSelectionSet = generateSelectionSet;
function getImplicitOwnerField(modelDefinition, scalarFields) {
var ownerFields = getOwnerFields(modelDefinition);
if (!scalarFields.owner && ownerFields.includes('owner')) {
return ['owner'];
}
return [];
}
function getOwnerFields(modelDefinition) {
var ownerFields = [];
if (types_1.isSchemaModelWithAttributes(modelDefinition)) {
modelDefinition.attributes.forEach(function (attr) {
if (attr.properties && attr.properties.rules) {
var rule = attr.properties.rules.find(function (rule) { return rule.allow === 'owner'; });
if (rule && rule.ownerField) {
ownerFields.push(rule.ownerField);
}
}
});
}
return ownerFields;
}
function getScalarFields(modelDefinition) {
var fields = modelDefinition.fields;
var result = Object.values(fields)
.filter(function (field) {
if (types_1.isGraphQLScalarType(field.type) || types_1.isEnumFieldType(field.type)) {
return true;
}
return false;
})
.reduce(function (acc, field) {
acc[field.name] = field;
return acc;
}, {});
return result;
}
// Used for generating the selection set for queries and mutations
function getConnectionFields(modelDefinition, namespace) {
var result = [];
Object.values(modelDefinition.fields)
.filter(function (_a) {
var association = _a.association;
return association && Object.keys(association).length;
})
.forEach(function (_a) {
var name = _a.name, association = _a.association;
var connectionType = (association || {}).connectionType;
switch (connectionType) {
case 'HAS_ONE':
case 'HAS_MANY':
// Intentionally blank
break;
case 'BELONGS_TO':
if (types_1.isTargetNameAssociation(association)) {
// New codegen (CPK)
if (association.targetNames && association.targetNames.length > 0) {
// Need to retrieve relations in order to get connected model keys
var _b = tslib_1.__read(util_1.establishRelationAndKeys(namespace), 1), relations = _b[0];
var connectedModelName = modelDefinition.fields[name].type['model'];
var byPkIndex = relations[connectedModelName].indexes.find(function (_a) {
var _b = tslib_1.__read(_a, 1), name = _b[0];
return name === 'byPk';
});
var keyFields = byPkIndex && byPkIndex[1];
var keyFieldSelectionSet = keyFields === null || keyFields === void 0 ? void 0 : keyFields.join(' ');
// We rely on `_deleted` when we process the sync query (e.g. in batchSave in the adapters)
result.push(name + " { " + keyFieldSelectionSet + " _deleted }");
}
else {
// backwards-compatability for schema generated prior to custom primary key support
result.push(name + " { id _deleted }");
}
}
break;
default:
throw new Error("Invalid connection type " + connectionType);
}
});
return result;
}
function getNonModelFields(namespace, modelDefinition) {
var result = [];
Object.values(modelDefinition.fields).forEach(function (_a) {
var name = _a.name, type = _a.type;
if (types_1.isNonModelFieldType(type)) {
var typeDefinition = namespace.nonModels[type.nonModel];
var scalarFields = Object.values(getScalarFields(typeDefinition)).map(function (_a) {
var name = _a.name;
return name;
});
var nested_1 = [];
Object.values(typeDefinition.fields).forEach(function (field) {
var type = field.type, name = field.name;
if (types_1.isNonModelFieldType(type)) {
var typeDefinition_1 = namespace.nonModels[type.nonModel];
nested_1.push(name + " { " + generateSelectionSet(namespace, typeDefinition_1) + " }");
}
});
result.push(name + " { " + scalarFields.join(' ') + " " + nested_1.join(' ') + " }");
}
});
return result;
}
function getAuthorizationRules(modelDefinition) {
// Searching for owner authorization on attributes
var authConfig = []
.concat(modelDefinition.attributes || [])
.find(function (attr) { return attr && attr.type === 'auth'; });
var _a = (authConfig || {}).properties, _b = (_a === void 0 ? {} : _a).rules, rules = _b === void 0 ? [] : _b;
var resultRules = [];
// Multiple rules can be declared for allow: owner
rules.forEach(function (rule) {
// setting defaults for backwards compatibility with old cli
var _a = rule.identityClaim, identityClaim = _a === void 0 ? 'cognito:username' : _a, _b = rule.ownerField, ownerField = _b === void 0 ? 'owner' : _b, _c = rule.operations, operations = _c === void 0 ? ['create', 'update', 'delete', 'read'] : _c, _d = rule.provider, provider = _d === void 0 ? 'userPools' : _d, _e = rule.groupClaim, groupClaim = _e === void 0 ? 'cognito:groups' : _e, _f = rule.allow, authStrategy = _f === void 0 ? 'iam' : _f, _g = rule.groups, groups = _g === void 0 ? [] : _g, _h = rule.groupsField, groupsField = _h === void 0 ? '' : _h;
var isReadAuthorized = operations.includes('read');
var isOwnerAuth = authStrategy === 'owner';
if (!isReadAuthorized && !isOwnerAuth) {
return;
}
var authRule = {
identityClaim: identityClaim,
ownerField: ownerField,
provider: provider,
groupClaim: groupClaim,
authStrategy: authStrategy,
groups: groups,
groupsField: groupsField,
areSubscriptionsPublic: false,
};
if (isOwnerAuth) {
// look for the subscription level override
// only pay attention to the public level
var modelConfig = []
.concat(modelDefinition.attributes || [])
.find(function (attr) { return attr && attr.type === 'model'; });
// find the subscriptions level. ON is default
var _j = (modelConfig || {}).properties, _k = (_j === void 0 ? {} : _j).subscriptions, _l = (_k === void 0 ? {} : _k).level, level = _l === void 0 ? 'on' : _l;
// treat subscriptions as public for owner auth with unprotected reads
// when `read` is omitted from `operations`
authRule.areSubscriptionsPublic =
!operations.includes('read') || level === 'public';
}
if (isOwnerAuth) {
// owner rules has least priority
resultRules.push(authRule);
return;
}
resultRules.unshift(authRule);
});
return resultRules;
}
exports.getAuthorizationRules = getAuthorizationRules;
function buildSubscriptionGraphQLOperation(namespace, modelDefinition, transformerMutationType, isOwnerAuthorization, ownerField, filterArg) {
if (filterArg === void 0) { filterArg = false; }
var selectionSet = generateSelectionSet(namespace, modelDefinition);
var typeName = modelDefinition.name;
var opName = "on" + transformerMutationType + typeName;
var docArgs = [];
var opArgs = [];
if (filterArg) {
docArgs.push("$filter: ModelSubscription" + typeName + "FilterInput");
opArgs.push('filter: $filter');
}
if (isOwnerAuthorization) {
docArgs.push("$" + ownerField + ": String!");
opArgs.push(ownerField + ": $" + ownerField);
}
var docStr = docArgs.length ? "(" + docArgs.join(',') + ")" : '';
var opStr = opArgs.length ? "(" + opArgs.join(',') + ")" : '';
return [
transformerMutationType,
opName,
"subscription operation" + docStr + "{\n\t\t\t" + opName + opStr + "{\n\t\t\t\t" + selectionSet + "\n\t\t\t}\n\t\t}",
];
}
exports.buildSubscriptionGraphQLOperation = buildSubscriptionGraphQLOperation;
function buildGraphQLOperation(namespace, modelDefinition, graphQLOpType) {
var selectionSet = generateSelectionSet(namespace, modelDefinition);
var typeName = modelDefinition.name, pluralTypeName = modelDefinition.pluralName;
var operation;
var documentArgs;
var operationArgs;
var transformerMutationType;
switch (graphQLOpType) {
case 'LIST':
operation = "sync" + pluralTypeName;
documentArgs = "($limit: Int, $nextToken: String, $lastSync: AWSTimestamp, $filter: Model" + typeName + "FilterInput)";
operationArgs =
'(limit: $limit, nextToken: $nextToken, lastSync: $lastSync, filter: $filter)';
selectionSet = "items {\n\t\t\t\t\t\t\t" + selectionSet + "\n\t\t\t\t\t\t}\n\t\t\t\t\t\tnextToken\n\t\t\t\t\t\tstartedAt";
break;
case 'CREATE':
operation = "create" + typeName;
documentArgs = "($input: Create" + typeName + "Input!)";
operationArgs = '(input: $input)';
transformerMutationType = TransformerMutationType.CREATE;
break;
case 'UPDATE':
operation = "update" + typeName;
documentArgs = "($input: Update" + typeName + "Input!, $condition: Model" + typeName + "ConditionInput)";
operationArgs = '(input: $input, condition: $condition)';
transformerMutationType = TransformerMutationType.UPDATE;
break;
case 'DELETE':
operation = "delete" + typeName;
documentArgs = "($input: Delete" + typeName + "Input!, $condition: Model" + typeName + "ConditionInput)";
operationArgs = '(input: $input, condition: $condition)';
transformerMutationType = TransformerMutationType.DELETE;
break;
case 'GET':
operation = "get" + typeName;
documentArgs = "($id: ID!)";
operationArgs = '(id: $id)';
transformerMutationType = TransformerMutationType.GET;
break;
default:
throw new Error("Invalid graphQlOpType " + graphQLOpType);
}
return [
[
transformerMutationType,
operation,
GraphQLOperationType[graphQLOpType] + " operation" + documentArgs + "{\n\t\t" + operation + operationArgs + "{\n\t\t\t" + selectionSet + "\n\t\t}\n\t}",
],
];
}
exports.buildGraphQLOperation = buildGraphQLOperation;
function createMutationInstanceFromModelOperation(relationships, modelDefinition, opType, model, element, condition, MutationEventConstructor, modelInstanceCreator, id) {
var operation;
switch (opType) {
case types_1.OpType.INSERT:
operation = TransformerMutationType.CREATE;
break;
case types_1.OpType.UPDATE:
operation = TransformerMutationType.UPDATE;
break;
case types_1.OpType.DELETE:
operation = TransformerMutationType.DELETE;
break;
default:
throw new Error("Invalid opType " + opType);
}
// stringify nested objects of type AWSJSON
// this allows us to return parsed JSON to users (see `castInstanceType()` in datastore.ts),
// but still send the object correctly over the wire
var replacer = function (k, v) {
var isAWSJSON = k &&
v !== null &&
typeof v === 'object' &&
modelDefinition.fields[k] &&
modelDefinition.fields[k].type === 'AWSJSON';
if (isAWSJSON) {
return JSON.stringify(v);
}
return v;
};
var modelId = getIdentifierValue(modelDefinition, element);
var optionalId = types_1.OpType.INSERT && id ? { id: id } : {};
var mutationEvent = modelInstanceCreator(MutationEventConstructor, tslib_1.__assign(tslib_1.__assign({}, optionalId), { data: JSON.stringify(element, replacer), modelId: modelId, model: model.name, operation: operation, condition: JSON.stringify(condition) }));
return mutationEvent;
}
exports.createMutationInstanceFromModelOperation = createMutationInstanceFromModelOperation;
function predicateToGraphQLCondition(predicate, modelDefinition) {
var result = {};
if (!predicate || !Array.isArray(predicate.predicates)) {
return result;
}
// This is compatible with how the GQL Transform currently generates the Condition Input,
// i.e. any PK and SK fields are omitted and can't be used as conditions.
// However, I think this limits usability.
// What if we want to delete all records where SK > some value
// Or all records where PK = some value but SKs are different values
// TODO: if the Transform gets updated we'll need to modify this logic to only omit
// key fields from the predicate/condition when ALL of the keyFields are present and using `eq` operators
var keyFields = util_1.extractPrimaryKeyFieldNames(modelDefinition);
return predicateToGraphQLFilter(predicate, keyFields);
}
exports.predicateToGraphQLCondition = predicateToGraphQLCondition;
/**
* @param predicatesGroup - Predicate Group
@returns GQL Filter Expression from Predicate Group
@remarks Flattens redundant list predicates
@example
```js
{ and:[{ and:[{ username: { eq: 'bob' }}] }] }
```
Becomes
```js
{ and:[{ username: { eq: 'bob' }}] }
```
*/
function predicateToGraphQLFilter(predicatesGroup, fieldsToOmit, root) {
if (fieldsToOmit === void 0) { fieldsToOmit = []; }
if (root === void 0) { root = true; }
var result = {};
if (!predicatesGroup || !Array.isArray(predicatesGroup.predicates)) {
return result;
}
var type = predicatesGroup.type, predicates = predicatesGroup.predicates;
var isList = type === 'and' || type === 'or';
result[type] = isList ? [] : {};
var children = [];
predicates.forEach(function (predicate) {
var _a, _b;
if (types_1.isPredicateObj(predicate)) {
var field = predicate.field, operator = predicate.operator, operand = predicate.operand;
if (fieldsToOmit.includes(field))
return;
var gqlField = (_a = {},
_a[field] = (_b = {}, _b[operator] = operand, _b),
_a);
children.push(gqlField);
return;
}
var child = predicateToGraphQLFilter(predicate, fieldsToOmit, false);
if (Object.keys(child).length > 0) {
children.push(child);
}
});
// flatten redundant list predicates
if (children.length === 1) {
var _a = tslib_1.__read(children, 1), child = _a[0];
if (
// any nested list node
(isList && !root) ||
// root list node where the only child is also a list node
(isList && root && ('and' in child || 'or' in child))) {
delete result[type];
Object.assign(result, child);
return result;
}
}
children.forEach(function (child) {
if (isList) {
result[type].push(child);
}
else {
result[type] = child;
}
});
if (isList) {
if (result[type].length === 0)
return {};
}
else {
if (Object.keys(result[type]).length === 0)
return {};
}
return result;
}
exports.predicateToGraphQLFilter = predicateToGraphQLFilter;
/**
*
* @param group - selective sync predicate group
* @returns set of distinct field names in the filter group
*/
function filterFields(group) {
var fields = new Set();
if (!group || !Array.isArray(group.predicates))
return fields;
var predicates = group.predicates;
var stack = tslib_1.__spread(predicates);
while (stack.length > 0) {
var current = stack.pop();
if (types_1.isPredicateObj(current)) {
fields.add(current.field);
}
else if (types_1.isPredicateGroup(current)) {
stack.push.apply(stack, tslib_1.__spread(current.predicates));
}
}
return fields;
}
exports.filterFields = filterFields;
/**
*
* @param modelDefinition
* @returns set of field names used with dynamic auth modes configured for the provided model definition
*/
function dynamicAuthFields(modelDefinition) {
var e_1, _a;
var rules = getAuthorizationRules(modelDefinition);
var fields = new Set();
try {
for (var rules_1 = tslib_1.__values(rules), rules_1_1 = rules_1.next(); !rules_1_1.done; rules_1_1 = rules_1.next()) {
var rule = rules_1_1.value;
if (rule.groupsField && !rule.groups.length) {
// dynamic group rule will have no values in `rule.groups`
fields.add(rule.groupsField);
}
else if (rule.ownerField) {
fields.add(rule.ownerField);
}
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (rules_1_1 && !rules_1_1.done && (_a = rules_1.return)) _a.call(rules_1);
}
finally { if (e_1) throw e_1.error; }
}
return fields;
}
exports.dynamicAuthFields = dynamicAuthFields;
/**
*
* @param group - selective sync predicate group
* @returns the total number of OR'd predicates in the filter group
*
* @example returns 2
* ```js
* { type: "or", predicates: [
* { field: "username", operator: "beginsWith", operand: "a" },
* { field: "title", operator: "contains", operand: "abc" },
* ]}
* ```
*/
function countFilterCombinations(group) {
if (!group || !Array.isArray(group.predicates))
return 0;
var count = 0;
var stack = [group];
while (stack.length > 0) {
var current = stack.pop();
if (types_1.isPredicateGroup(current)) {
var predicates = current.predicates, type = current.type;
// ignore length = 1; groups with 1 predicate will get flattened when converted to gqlFilter
if (type === 'or' && predicates.length > 1) {
count += predicates.length;
}
stack.push.apply(stack, tslib_1.__spread(predicates));
}
}
// if we didn't encounter any OR groups, default to 1
return count || 1;
}
exports.countFilterCombinations = countFilterCombinations;
/**
*
* @param group - selective sync predicate group
* @returns name of repeated field | null
*
* @example returns "username"
* ```js
* { type: "and", predicates: [
* { field: "username", operator: "beginsWith", operand: "a" },
* { field: "username", operator: "contains", operand: "abc" },
* ] }
* ```
*/
function repeatedFieldInGroup(group) {
if (!group || !Array.isArray(group.predicates))
return null;
// convert to filter in order to flatten redundant groups
var gqlFilter = predicateToGraphQLFilter(group);
var stack = [gqlFilter];
var hasGroupRepeatedFields = function (fields) {
var e_2, _a;
var seen = {};
try {
for (var fields_1 = tslib_1.__values(fields), fields_1_1 = fields_1.next(); !fields_1_1.done; fields_1_1 = fields_1.next()) {
var f = fields_1_1.value;
var _b = tslib_1.__read(Object.keys(f), 1), fieldName = _b[0];
if (seen[fieldName]) {
return fieldName;
}
seen[fieldName] = true;
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (fields_1_1 && !fields_1_1.done && (_a = fields_1.return)) _a.call(fields_1);
}
finally { if (e_2) throw e_2.error; }
}
return null;
};
while (stack.length > 0) {
var current = stack.pop();
var _a = tslib_1.__read(Object.keys(current), 1), key = _a[0];
var values = current[key];
if (!Array.isArray(values)) {
return null;
}
// field value will be single object
var predicateObjects = values.filter(function (v) { return !Array.isArray(Object.values(v)[0]); });
// group value will be an array
var predicateGroups = values.filter(function (v) {
return Array.isArray(Object.values(v)[0]);
});
if (key === 'and') {
var repeatedField = hasGroupRepeatedFields(predicateObjects);
if (repeatedField) {
return repeatedField;
}
}
stack.push.apply(stack, tslib_1.__spread(predicateGroups));
}
return null;
}
exports.repeatedFieldInGroup = repeatedFieldInGroup;
var RTFError;
(function (RTFError) {
RTFError[RTFError["UnknownField"] = 0] = "UnknownField";
RTFError[RTFError["MaxAttributes"] = 1] = "MaxAttributes";
RTFError[RTFError["MaxCombinations"] = 2] = "MaxCombinations";
RTFError[RTFError["RepeatedFieldname"] = 3] = "RepeatedFieldname";
RTFError[RTFError["NotGroup"] = 4] = "NotGroup";
RTFError[RTFError["FieldNotInType"] = 5] = "FieldNotInType";
})(RTFError = exports.RTFError || (exports.RTFError = {}));
function generateRTFRemediation(errorType, modelDefinition, predicatesGroup) {
var selSyncFields = filterFields(predicatesGroup);
var selSyncFieldStr = tslib_1.__spread(selSyncFields).join(', ');
var dynamicAuthModeFields = dynamicAuthFields(modelDefinition);
var dynamicAuthFieldsStr = tslib_1.__spread(dynamicAuthModeFields).join(', ');
var filterCombinations = countFilterCombinations(predicatesGroup);
var repeatedField = repeatedFieldInGroup(predicatesGroup);
switch (errorType) {
case RTFError.UnknownField:
return ("Your API was generated with an older version of the CLI that doesn't support backend subscription filtering." +
'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`');
case RTFError.MaxAttributes: {
var message = "Your selective sync expression for " + modelDefinition.name + " contains " + selSyncFields.size + " different model fields: " + selSyncFieldStr + ".\n\n";
if (dynamicAuthModeFields.size > 0) {
message +=
"Note: the number of fields you can use with selective sync is affected by @auth rules configured on the model.\n\n" +
"Dynamic auth modes, such as owner auth and dynamic group auth each utilize 1 field.\n" +
("You currently have " + dynamicAuthModeFields.size + " dynamic auth mode(s) configured on this model: " + dynamicAuthFieldsStr + ".");
}
return message;
}
case RTFError.MaxCombinations: {
var message = "Your selective sync expression for " + modelDefinition.name + " contains " + filterCombinations + " field combinations (total number of predicates in an OR expression).\n\n";
if (dynamicAuthModeFields.size > 0) {
message +=
"Note: the number of fields you can use with selective sync is affected by @auth rules configured on the model.\n\n" +
"Dynamic auth modes, such as owner auth and dynamic group auth factor in to the number of combinations you're using.\n" +
("You currently have " + dynamicAuthModeFields.size + " dynamic auth mode(s) configured on this model: " + dynamicAuthFieldsStr + ".");
}
return message;
}
case RTFError.RepeatedFieldname:
return "Your selective sync expression for " + modelDefinition.name + " contains multiple entries for " + repeatedField + " in the same AND group.";
case RTFError.NotGroup:
return ("Your selective sync expression for " + modelDefinition.name + " uses a `not` group. If you'd like to filter subscriptions in the backend, " +
"rewrite your expression using `ne` or `notContains` operators.");
case RTFError.FieldNotInType:
// no remediation instructions. We'll surface the message directly
return '';
}
}
exports.generateRTFRemediation = generateRTFRemediation;
function getUserGroupsFromToken(token, rule) {
// validate token against groupClaim
var userGroups = token[rule.groupClaim] || [];
if (typeof userGroups === 'string') {
var parsedGroups = void 0;
try {
parsedGroups = JSON.parse(userGroups);
}
catch (e) {
parsedGroups = userGroups;
}
userGroups = [].concat(parsedGroups);
}
return userGroups;
}
exports.getUserGroupsFromToken = getUserGroupsFromToken;
function getModelAuthModes(_a) {
var authModeStrategy = _a.authModeStrategy, defaultAuthMode = _a.defaultAuthMode, modelName = _a.modelName, schema = _a.schema;
return tslib_1.__awaiter(this, void 0, void 0, function () {
var operations, modelAuthModes, error_1;
var _this = this;
return tslib_1.__generator(this, function (_b) {
switch (_b.label) {
case 0:
operations = Object.values(types_1.ModelOperation);
modelAuthModes = {
CREATE: [],
READ: [],
UPDATE: [],
DELETE: [],
};
_b.label = 1;
case 1:
_b.trys.push([1, 3, , 4]);
return [4 /*yield*/, Promise.all(operations.map(function (operation) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
var authModes;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, authModeStrategy({
schema: schema,
modelName: modelName,
operation: operation,
})];
case 1:
authModes = _a.sent();
if (typeof authModes === 'string') {
modelAuthModes[operation] = [authModes];
}
else if (Array.isArray(authModes) && authModes.length) {
modelAuthModes[operation] = authModes;
}
else {
// Use default auth mode if nothing is returned from authModeStrategy
modelAuthModes[operation] = [defaultAuthMode];
}
return [2 /*return*/];
}
});
}); }))];
case 2:
_b.sent();
return [3 /*break*/, 4];
case 3:
error_1 = _b.sent();
logger.debug("Error getting auth modes for model: " + modelName, error_1);
return [3 /*break*/, 4];
case 4: return [2 /*return*/, modelAuthModes];
}
});
});
}
exports.getModelAuthModes = getModelAuthModes;
function getForbiddenError(error) {
var forbiddenErrorMessages = [
'Request failed with status code 401',
'Request failed with status code 403',
];
var forbiddenError;
if (error && error.errors) {
forbiddenError = error.errors.find(function (err) {
return forbiddenErrorMessages.includes(err.message);
});
}
else if (error && error.message) {
forbiddenError = error;
}
if (forbiddenError) {
return forbiddenError.message;
}
return null;
}
exports.getForbiddenError = getForbiddenError;
function getClientSideAuthError(error) {
var clientSideAuthErrors = Object.values(api_1.GraphQLAuthError);
var clientSideError = error &&
error.message &&
clientSideAuthErrors.find(function (clientError) {
return error.message.includes(clientError);
});
return clientSideError || null;
}
exports.getClientSideAuthError = getClientSideAuthError;
function getTokenForCustomAuth(authMode, amplifyConfig) {
if (amplifyConfig === void 0) { amplifyConfig = {}; }
return tslib_1.__awaiter(this, void 0, void 0, function () {
var _a, functionAuthProvider, token, error_2;
return tslib_1.__generator(this, function (_b) {
switch (_b.label) {
case 0:
if (!(authMode === api_graphql_1.GRAPHQL_AUTH_MODE.AWS_LAMBDA)) return [3 /*break*/, 6];
_a = amplifyConfig.authProviders, functionAuthProvider = (_a === void 0 ? { functionAuthProvider: null } : _a).functionAuthProvider;
if (!(functionAuthProvider && typeof functionAuthProvider === 'function')) return [3 /*break*/, 5];
_b.label = 1;
case 1:
_b.trys.push([1, 3, , 4]);
return [4 /*yield*/, functionAuthProvider()];
case 2:
token = (_b.sent()).token;
return [2 /*return*/, token];
case 3:
error_2 = _b.sent();
throw new Error("Error retrieving token from `functionAuthProvider`: " + error_2);
case 4: return [3 /*break*/, 6];
case 5:
// TODO: add docs link once available
throw new Error("You must provide a `functionAuthProvider` function to `DataStore.configure` when using " + api_graphql_1.GRAPHQL_AUTH_MODE.AWS_LAMBDA);
case 6: return [2 /*return*/];
}
});
});
}
exports.getTokenForCustomAuth = getTokenForCustomAuth;
// Util that takes a modelDefinition and model and returns either the id value(s) or the custom primary key value(s)
function getIdentifierValue(modelDefinition, model) {
var pkFieldNames = util_1.extractPrimaryKeyFieldNames(modelDefinition);
var idOrPk = pkFieldNames.map(function (f) { return model[f]; }).join(util_1.IDENTIFIER_KEY_SEPARATOR);
return idOrPk;
}
exports.getIdentifierValue = getIdentifierValue;
//# sourceMappingURL=utils.js.map