@apollo/federation
Version:
Apollo Federation Utilities
75 lines (63 loc) • 2.16 kB
text/typescript
import { visit, GraphQLError } from 'graphql';
import { ServiceDefinition } from '../../types';
import { logServiceAndType, errorWithCode } from '../../utils';
export const duplicateEnumValue = ({
name: serviceName,
typeDefs,
}: ServiceDefinition) => {
const errors: GraphQLError[] = [];
const enums: { [name: string]: string[] } = {};
visit(typeDefs, {
EnumTypeDefinition(definition) {
const name = definition.name.value;
const enumValues =
definition.values && definition.values.map(value => value.name.value);
if (!enumValues) return definition;
if (enums[name] && enums[name].length) {
enumValues.map(valueName => {
if (enums[name].includes(valueName)) {
errors.push(
errorWithCode(
'DUPLICATE_ENUM_VALUE',
logServiceAndType(serviceName, name, valueName) +
`The enum, \`${name}\` has multiple definitions of the \`${valueName}\` value.`,
definition,
),
);
return;
}
enums[name].push(valueName);
});
} else {
enums[name] = enumValues;
}
return definition;
},
EnumTypeExtension(definition) {
const name = definition.name.value;
const enumValues =
definition.values && definition.values.map(value => value.name.value);
if (!enumValues) return definition;
if (enums[name] && enums[name].length) {
enumValues.map(valueName => {
if (enums[name].includes(valueName)) {
errors.push(
errorWithCode(
'DUPLICATE_ENUM_VALUE',
logServiceAndType(serviceName, name, valueName) +
`The enum, \`${name}\` has multiple definitions of the \`${valueName}\` value.`,
definition.values?.find(enumValue => enumValue.name.value === valueName),
),
);
return;
}
enums[name].push(valueName);
});
} else {
enums[name] = enumValues;
}
return definition;
},
});
return errors;
};