GraphQL: Renaming Types/Inputs (#5883)
* Renaming GraphQL Types/Inputs * Add Native Type to avoid collision * Use pluralize for renaming * Fixing tests * Improve name collision management - tests passsing * Renaming few more default types * Rename file input * Reverting fields types to not collide with the relay spec types Improver users mutations * Adding ArrayResult to the reserved list * Fixing tests * Add more unit tests to ParseGraphQLSchema * Test transformClassNameToGraphQL * Name collision tests
This commit is contained in:
committed by
Antonio Davi Macedo Coelho de Castro
parent
cf6e79ee75
commit
59b0221fec
@@ -15,6 +15,29 @@ import DatabaseController from '../Controllers/DatabaseController';
|
||||
import { toGraphQLError } from './parseGraphQLUtils';
|
||||
import * as schemaDirectives from './loaders/schemaDirectives';
|
||||
|
||||
const RESERVED_GRAPHQL_TYPE_NAMES = [
|
||||
'String',
|
||||
'Boolean',
|
||||
'Int',
|
||||
'Float',
|
||||
'ID',
|
||||
'ArrayResult',
|
||||
'Query',
|
||||
'Mutation',
|
||||
'Subscription',
|
||||
'ObjectsQuery',
|
||||
'UsersQuery',
|
||||
'ObjectsMutation',
|
||||
'FilesMutation',
|
||||
'UsersMutation',
|
||||
'FunctionsMutation',
|
||||
'Viewer',
|
||||
'SignUpFieldsInput',
|
||||
'LogInFieldsInput',
|
||||
];
|
||||
const RESERVED_GRAPHQL_OBJECT_QUERY_NAMES = ['get', 'find'];
|
||||
const RESERVED_GRAPHQL_OBJECT_MUTATION_NAMES = ['create', 'update', 'delete'];
|
||||
|
||||
class ParseGraphQLSchema {
|
||||
databaseController: DatabaseController;
|
||||
parseGraphQLController: ParseGraphQLController;
|
||||
@@ -60,7 +83,7 @@ class ParseGraphQLSchema {
|
||||
this.parseClassesString = parseClassesString;
|
||||
this.parseGraphQLConfig = parseGraphQLConfig;
|
||||
this.parseClassTypes = {};
|
||||
this.meType = null;
|
||||
this.viewerType = null;
|
||||
this.graphQLAutoSchema = null;
|
||||
this.graphQLSchema = null;
|
||||
this.graphQLTypes = [];
|
||||
@@ -92,7 +115,7 @@ class ParseGraphQLSchema {
|
||||
description: 'Query is the top level type for queries.',
|
||||
fields: this.graphQLQueries,
|
||||
});
|
||||
this.graphQLTypes.push(graphQLQuery);
|
||||
this.addGraphQLType(graphQLQuery, true, true);
|
||||
}
|
||||
|
||||
let graphQLMutation = undefined;
|
||||
@@ -102,7 +125,7 @@ class ParseGraphQLSchema {
|
||||
description: 'Mutation is the top level type for mutations.',
|
||||
fields: this.graphQLMutations,
|
||||
});
|
||||
this.graphQLTypes.push(graphQLMutation);
|
||||
this.addGraphQLType(graphQLMutation, true, true);
|
||||
}
|
||||
|
||||
let graphQLSubscription = undefined;
|
||||
@@ -112,7 +135,7 @@ class ParseGraphQLSchema {
|
||||
description: 'Subscription is the top level type for subscriptions.',
|
||||
fields: this.graphQLSubscriptions,
|
||||
});
|
||||
this.graphQLTypes.push(graphQLSubscription);
|
||||
this.addGraphQLType(graphQLSubscription, true, true);
|
||||
}
|
||||
|
||||
this.graphQLAutoSchema = new GraphQLSchema({
|
||||
@@ -172,6 +195,66 @@ class ParseGraphQLSchema {
|
||||
return this.graphQLSchema;
|
||||
}
|
||||
|
||||
addGraphQLType(type, throwError = false, ignoreReserved = false) {
|
||||
if (
|
||||
(!ignoreReserved && RESERVED_GRAPHQL_TYPE_NAMES.includes(type.name)) ||
|
||||
this.graphQLTypes.find(existingType => existingType.name === type.name)
|
||||
) {
|
||||
const message = `Type ${type.name} could not be added to the auto schema because it collided with an existing type.`;
|
||||
if (throwError) {
|
||||
throw new Error(message);
|
||||
}
|
||||
this.log.warn(message);
|
||||
return undefined;
|
||||
}
|
||||
this.graphQLTypes.push(type);
|
||||
return type;
|
||||
}
|
||||
|
||||
addGraphQLObjectQuery(
|
||||
fieldName,
|
||||
field,
|
||||
throwError = false,
|
||||
ignoreReserved = false
|
||||
) {
|
||||
if (
|
||||
(!ignoreReserved &&
|
||||
RESERVED_GRAPHQL_OBJECT_QUERY_NAMES.includes(fieldName)) ||
|
||||
this.graphQLObjectsQueries[fieldName]
|
||||
) {
|
||||
const message = `Object query ${fieldName} could not be added to the auto schema because it collided with an existing field.`;
|
||||
if (throwError) {
|
||||
throw new Error(message);
|
||||
}
|
||||
this.log.warn(message);
|
||||
return undefined;
|
||||
}
|
||||
this.graphQLObjectsQueries[fieldName] = field;
|
||||
return field;
|
||||
}
|
||||
|
||||
addGraphQLObjectMutation(
|
||||
fieldName,
|
||||
field,
|
||||
throwError = false,
|
||||
ignoreReserved = false
|
||||
) {
|
||||
if (
|
||||
(!ignoreReserved &&
|
||||
RESERVED_GRAPHQL_OBJECT_MUTATION_NAMES.includes(fieldName)) ||
|
||||
this.graphQLObjectsMutations[fieldName]
|
||||
) {
|
||||
const message = `Object mutation ${fieldName} could not be added to the auto schema because it collided with an existing field.`;
|
||||
if (throwError) {
|
||||
throw new Error(message);
|
||||
}
|
||||
this.log.warn(message);
|
||||
return undefined;
|
||||
}
|
||||
this.graphQLObjectsMutations[fieldName] = field;
|
||||
return field;
|
||||
}
|
||||
|
||||
handleError(error) {
|
||||
if (error instanceof Parse.Error) {
|
||||
this.log.error('Parse error: ', error);
|
||||
@@ -238,7 +321,32 @@ class ParseGraphQLSchema {
|
||||
parseGraphQLConfig: ParseGraphQLConfig
|
||||
) {
|
||||
const { classConfigs } = parseGraphQLConfig;
|
||||
return parseClasses.map(parseClass => {
|
||||
|
||||
// Make sures that the default classes and classes that
|
||||
// starts with capitalized letter will be generated first.
|
||||
const sortClasses = (a, b) => {
|
||||
a = a.className;
|
||||
b = b.className;
|
||||
if (a[0] === '_') {
|
||||
if (b[0] !== '_') {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (b[0] === '_') {
|
||||
if (a[0] !== '_') {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (a === b) {
|
||||
return 0;
|
||||
} else if (a < b) {
|
||||
return -1;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
return parseClasses.sort(sortClasses).map(parseClass => {
|
||||
let parseClassConfig;
|
||||
if (classConfigs) {
|
||||
parseClassConfig = classConfigs.find(
|
||||
|
||||
Reference in New Issue
Block a user