@aws-amplify/graphql-model-transformer
Version:
Amplify graphql @model transformer
321 lines • 16.4 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.propagateDirectivesToNestedTypes = exports.makeModelSortDirectionEnumObject = exports.extendTypeWithDirectives = exports.addDirectivesToOperation = exports.addDirectivesToField = exports.makeEnumFilterInput = exports.makeSizeInputType = exports.makeSubscriptionField = exports.makeAttributeTypeEnum = exports.makeModelScalarFilterInputObject = exports.createEnumModelFilters = exports.generateModelScalarFilterInputName = exports.addModelConditionInputs = exports.removeSubscriptionFilterInputAttribute = exports.getSubscriptionFilterInputName = exports.makeSubscriptionFilterInput = exports.makeConditionFilterInput = void 0;
const graphql_1 = require("graphql");
const graphql_transformer_common_1 = require("graphql-transformer-common");
const graphql_transformer_core_1 = require("@aws-amplify/graphql-transformer-core");
const definitions_1 = require("../definitions");
const makeConditionFilterInput = (ctx, name, object) => {
const input = graphql_transformer_core_1.InputObjectDefinitionWrapper.create(name);
addSimpleFieldsConditionsForListing(input, object, ctx);
addListTypeConditions(input, name);
addNonListTypeConditions(input, name);
addDatastoreConditions(input, ctx);
return input;
};
exports.makeConditionFilterInput = makeConditionFilterInput;
const makeSubscriptionFilterInput = (ctx, name, object) => {
const supportsConditions = true;
const input = graphql_transformer_core_1.InputObjectDefinitionWrapper.create(name);
const wrappedObject = new graphql_transformer_core_1.ObjectDefinitionWrapper(object);
for (const field of wrappedObject.fields) {
const fieldType = ctx.output.getType(field.getTypeName());
const isEnumType = fieldType && fieldType.kind === graphql_1.Kind.ENUM_TYPE_DEFINITION;
if (field.isScalar() || isEnumType) {
const conditionTypeName = graphql_transformer_common_1.ModelResourceIDs.ModelFilterScalarInputTypeName(isEnumType ? 'String' : field.getTypeName(), !supportsConditions, true);
const inputField = graphql_transformer_core_1.InputFieldWrapper.create(field.name, conditionTypeName, true);
input.addField(inputField);
}
}
addListTypeConditions(input, name);
addDatastoreConditions(input, ctx);
return input;
};
exports.makeSubscriptionFilterInput = makeSubscriptionFilterInput;
const addSimpleFieldsConditionsForListing = (input, object, ctx) => {
const supportsConditions = true;
const wrappedObject = new graphql_transformer_core_1.ObjectDefinitionWrapper(object);
for (const field of wrappedObject.fields) {
const fieldType = ctx.output.getType(field.getTypeName());
const isEnumType = fieldType && fieldType.kind === graphql_1.Kind.ENUM_TYPE_DEFINITION;
if (field.isScalar() || isEnumType) {
const conditionTypeName = isEnumType && field.isList()
? graphql_transformer_common_1.ModelResourceIDs.ModelFilterListInputTypeName(field.getTypeName(), !supportsConditions)
: graphql_transformer_common_1.ModelResourceIDs.ModelFilterScalarInputTypeName(field.getTypeName(), !supportsConditions);
const inputField = graphql_transformer_core_1.InputFieldWrapper.create(field.name, conditionTypeName, true);
input.addField(inputField);
}
}
};
const addNonListTypeConditions = (input, name) => {
for (const additionalField of ['not']) {
const inputField = graphql_transformer_core_1.InputFieldWrapper.create(additionalField, name, true, false);
input.addField(inputField);
}
};
const addListTypeConditions = (input, name) => {
for (const additionalField of ['and', 'or']) {
const inputField = graphql_transformer_core_1.InputFieldWrapper.create(additionalField, name, true, true);
input.addField(inputField);
}
};
const addDatastoreConditions = (input, ctx) => {
if (ctx.isProjectUsingDataStore()) {
const datastoreFields = [{ fieldName: '_deleted', typeName: graphql_transformer_common_1.STANDARD_SCALARS.Boolean }];
for (const { fieldName, typeName } of datastoreFields) {
const type = graphql_transformer_common_1.ModelResourceIDs.ModelScalarFilterInputTypeName(typeName, false);
const inputField = graphql_transformer_core_1.InputFieldWrapper.create(fieldName, type, true, false);
input.addField(inputField);
}
}
};
const getSubscriptionFilterInputName = (name) => (0, graphql_transformer_common_1.toPascalCase)(['ModelSubscription', name, 'FilterInput']);
exports.getSubscriptionFilterInputName = getSubscriptionFilterInputName;
const removeSubscriptionFilterInputAttribute = (ctx, typeName, fieldName) => {
var _a;
const filterTypeName = (0, exports.getSubscriptionFilterInputName)(typeName);
const filterType = ctx.output.getType(filterTypeName);
if (!filterType) {
return;
}
const newFilterType = {
...filterType,
fields: (_a = filterType.fields) === null || _a === void 0 ? void 0 : _a.filter((field) => field.name.value !== fieldName),
};
ctx.output.putType(newFilterType);
};
exports.removeSubscriptionFilterInputAttribute = removeSubscriptionFilterInputAttribute;
const addModelConditionInputs = (ctx) => {
const conditionsInput = ['String', 'Int', 'Float', 'Boolean', 'ID'].map((scalarName) => makeModelScalarFilterInputObject(scalarName, true));
['String', 'Int', 'Float', 'Boolean', 'ID'].map((scalarName) => conditionsInput.push(makeModelScalarFilterInputObject(scalarName, true, true)));
conditionsInput.push(makeAttributeTypeEnum());
conditionsInput.push(makeSizeInputType());
conditionsInput.forEach((input) => {
const inputName = input.name.value;
if (!ctx.output.getType(inputName)) {
ctx.output.addType(input);
}
});
};
exports.addModelConditionInputs = addModelConditionInputs;
function generateModelScalarFilterInputName(typeName, includeFilter, isSubscriptionFilter = false) {
const nameOverride = graphql_transformer_common_1.DEFAULT_SCALARS[typeName];
if (nameOverride) {
return `Model${isSubscriptionFilter ? 'Subscription' : ''}${nameOverride}${includeFilter ? 'Filter' : ''}Input`;
}
return `Model${isSubscriptionFilter ? 'Subscription' : ''}${typeName}${includeFilter ? 'Filter' : ''}Input`;
}
exports.generateModelScalarFilterInputName = generateModelScalarFilterInputName;
const createEnumModelFilters = (ctx, type) => {
const typeWrapper = new graphql_transformer_core_1.ObjectDefinitionWrapper(type);
const enumFields = typeWrapper.fields.filter((field) => {
const typeName = field.getTypeName();
const typeObj = ctx.output.getType(typeName);
return typeObj && typeObj.kind === 'EnumTypeDefinition';
});
return enumFields.map((field) => makeEnumFilterInput(field));
};
exports.createEnumModelFilters = createEnumModelFilters;
function makeModelScalarFilterInputObject(type, supportsConditions, isSubscriptionFilter = false) {
const name = generateModelScalarFilterInputName(type, !supportsConditions, isSubscriptionFilter);
const conditions = isSubscriptionFilter ? getSubscriptionScalarConditions(type) : getScalarConditions(type);
const scalarConditionInput = graphql_transformer_core_1.InputObjectDefinitionWrapper.create(name);
for (const condition of conditions) {
let typeName;
switch (condition) {
case 'and':
case 'or':
typeName = name;
break;
default:
typeName = type;
}
const field = graphql_transformer_core_1.InputFieldWrapper.create(condition, typeName, true);
if (condition === 'between' || condition === 'in' || condition === 'notIn') {
field.wrapListType();
}
scalarConditionInput.addField(field);
}
if (!isSubscriptionFilter) {
makeFunctionInputFields(type).map((f) => scalarConditionInput.addField(f));
}
return scalarConditionInput.serialize();
}
exports.makeModelScalarFilterInputObject = makeModelScalarFilterInputObject;
function getScalarConditions(type) {
switch (type) {
case 'String':
return definitions_1.STRING_CONDITIONS;
case 'ID':
return definitions_1.ID_CONDITIONS;
case 'Int':
return definitions_1.INT_CONDITIONS;
case 'Float':
return definitions_1.FLOAT_CONDITIONS;
case 'Boolean':
return definitions_1.BOOLEAN_CONDITIONS;
default:
throw new Error('Valid types are String, ID, Int, Float, Boolean');
}
}
function getSubscriptionScalarConditions(type) {
switch (type) {
case 'String':
return definitions_1.SUBSCRIPTION_STRING_CONDITIONS;
case 'ID':
return definitions_1.SUBSCRIPTION_ID_CONDITIONS;
case 'Int':
return definitions_1.SUBSCRIPTION_INT_CONDITIONS;
case 'Float':
return definitions_1.SUBSCRIPTION_FLOAT_CONDITIONS;
case 'Boolean':
return definitions_1.SUBSCRIPTION_BOOLEAN_CONDITIONS;
default:
throw new Error('Valid types are String, ID, Int, Float, Boolean');
}
}
function getFunctionListForType(typeName) {
switch (typeName) {
case 'String':
return definitions_1.STRING_FUNCTIONS;
case 'ID':
return definitions_1.ID_FUNCTIONS;
case 'Int':
return definitions_1.INT_FUNCTIONS;
case 'Float':
return definitions_1.FLOAT_FUNCTIONS;
case 'Boolean':
return definitions_1.BOOLEAN_FUNCTIONS;
default:
throw new Error('Valid types are String, ID, Int, Float, Boolean');
}
}
function makeFunctionInputFields(typeName) {
const functions = getFunctionListForType(typeName);
const fields = new Array();
if (functions.has('attributeExists')) {
fields.push(graphql_transformer_core_1.InputFieldWrapper.create('attributeExists', 'Boolean', true));
}
if (functions.has('attributeType')) {
fields.push(graphql_transformer_core_1.InputFieldWrapper.create('attributeType', 'ModelAttributeTypes', true));
}
if (functions.has('size')) {
fields.push(graphql_transformer_core_1.InputFieldWrapper.create('size', 'ModelSizeInput', true));
}
return fields;
}
function makeAttributeTypeEnum() {
return graphql_transformer_core_1.EnumWrapper.create('ModelAttributeTypes', definitions_1.ATTRIBUTE_TYPES).serialize();
}
exports.makeAttributeTypeEnum = makeAttributeTypeEnum;
function makeSubscriptionField(fieldName, returnTypeName, mutations) {
return (0, graphql_transformer_common_1.makeField)(fieldName, [], (0, graphql_transformer_common_1.makeNamedType)(returnTypeName), [
(0, graphql_transformer_common_1.makeDirective)('aws_subscribe', [(0, graphql_transformer_common_1.makeArgument)('mutations', (0, graphql_transformer_common_1.makeValueNode)(mutations))]),
]);
}
exports.makeSubscriptionField = makeSubscriptionField;
function makeSizeInputType() {
const name = 'ModelSizeInput';
const input = graphql_transformer_core_1.InputObjectDefinitionWrapper.create(name);
for (const condition of definitions_1.SIZE_CONDITIONS) {
const field = graphql_transformer_core_1.InputFieldWrapper.create(condition, 'Int', true);
if (condition === 'between')
field.wrapListType();
input.addField(field);
}
return input.serialize();
}
exports.makeSizeInputType = makeSizeInputType;
function makeEnumFilterInput(fieldWrapper) {
const supportsConditions = true;
const conditionTypeName = fieldWrapper.isList()
? graphql_transformer_common_1.ModelResourceIDs.ModelFilterListInputTypeName(fieldWrapper.getTypeName(), !supportsConditions)
: graphql_transformer_common_1.ModelResourceIDs.ModelFilterScalarInputTypeName(fieldWrapper.getTypeName(), !supportsConditions);
const input = graphql_transformer_core_1.InputObjectDefinitionWrapper.create(conditionTypeName);
['eq', 'ne'].forEach((fieldName) => {
const field = graphql_transformer_core_1.InputFieldWrapper.create(fieldName, fieldWrapper.getTypeName(), true, fieldWrapper.isList());
input.addField(field);
});
if (fieldWrapper.isList()) {
['contains', 'notContains'].forEach((fieldName) => {
const field = graphql_transformer_core_1.InputFieldWrapper.create(fieldName, fieldWrapper.getTypeName(), true);
input.addField(field);
});
}
return input.serialize();
}
exports.makeEnumFilterInput = makeEnumFilterInput;
const addDirectivesToField = (ctx, typeName, fieldName, directives) => {
var _a;
const type = ctx.output.getType(typeName);
if (type) {
const field = (_a = type.fields) === null || _a === void 0 ? void 0 : _a.find((f) => f.name.value === fieldName);
if (field) {
const newFields = [...type.fields.filter((f) => f.name.value !== field.name.value), (0, graphql_transformer_common_1.extendFieldWithDirectives)(field, directives)];
const newType = {
...type,
fields: newFields,
};
ctx.output.putType(newType);
}
}
};
exports.addDirectivesToField = addDirectivesToField;
const addDirectivesToOperation = (ctx, typeName, operationName, directives) => {
(0, exports.addDirectivesToField)(ctx, typeName, operationName, directives);
const type = ctx.output.getType(typeName);
if (type) {
const field = type.fields.find((f) => f.name.value === operationName);
if (field) {
const returnFieldType = field.type;
if (returnFieldType.name) {
const returnTypeName = returnFieldType.name.value;
(0, exports.extendTypeWithDirectives)(ctx, returnTypeName, directives);
}
}
}
};
exports.addDirectivesToOperation = addDirectivesToOperation;
const extendTypeWithDirectives = (ctx, typeName, directives) => {
let objectTypeExtension = (0, graphql_transformer_common_1.blankObjectExtension)(typeName);
objectTypeExtension = (0, graphql_transformer_common_1.extensionWithDirectives)(objectTypeExtension, directives);
ctx.output.addObjectExtension(objectTypeExtension);
};
exports.extendTypeWithDirectives = extendTypeWithDirectives;
const makeModelSortDirectionEnumObject = () => {
const name = 'ModelSortDirection';
return graphql_transformer_core_1.EnumWrapper.create(name, ['ASC', 'DESC']).serialize();
};
exports.makeModelSortDirectionEnumObject = makeModelSortDirectionEnumObject;
const propagateDirectivesToNestedTypes = (ctx, def, seenNonModelTypes, serviceDirectives) => {
var _a, _b;
const nonModelTypePredicate = (fieldType) => {
if (fieldType) {
if (fieldType.kind !== 'ObjectTypeDefinition') {
return undefined;
}
const typeModel = fieldType.directives.find((dir) => dir.name.value === 'model');
return typeModel !== undefined ? undefined : fieldType;
}
return fieldType;
};
const nonModelFieldTypes = def
.fields.map((f) => ctx.output.getType((0, graphql_transformer_common_1.getBaseType)(f.type)))
.filter(nonModelTypePredicate);
for (const nonModelFieldType of nonModelFieldTypes) {
const nonModelName = nonModelFieldType.name.value;
const hasSeenType = seenNonModelTypes.has(nonModelName);
if (!hasSeenType) {
for (const serviceDirective of serviceDirectives) {
const hasDirective = (_b = (_a = nonModelFieldType.directives) === null || _a === void 0 ? void 0 : _a.some((dir) => dir.name.value === serviceDirective.name.value)) !== null && _b !== void 0 ? _b : false;
if (!hasDirective) {
(0, exports.extendTypeWithDirectives)(ctx, nonModelName, [serviceDirective]);
}
}
seenNonModelTypes.add(nonModelName);
(0, exports.propagateDirectivesToNestedTypes)(ctx, nonModelFieldType, seenNonModelTypes, serviceDirectives);
}
}
};
exports.propagateDirectivesToNestedTypes = propagateDirectivesToNestedTypes;
//# sourceMappingURL=common.js.map