Allow to resolve automatically Parse Type fields from Custom Schema (#6562)
* add package * Allow real GraphQL Schema via ParseServer.start * Allow resolve fields from auto graphQL Schema * Simple merge * fix + improve * Add tests
This commit is contained in:
@@ -200,7 +200,7 @@ class ParseGraphQLSchema {
|
||||
if (typeof this.graphQLCustomTypeDefs.getTypeMap === 'function') {
|
||||
const customGraphQLSchemaTypeMap = this.graphQLCustomTypeDefs.getTypeMap();
|
||||
Object.values(customGraphQLSchemaTypeMap).forEach(
|
||||
customGraphQLSchemaType => {
|
||||
(customGraphQLSchemaType) => {
|
||||
if (
|
||||
!customGraphQLSchemaType ||
|
||||
!customGraphQLSchemaType.name ||
|
||||
@@ -215,40 +215,45 @@ class ParseGraphQLSchema {
|
||||
autoGraphQLSchemaType &&
|
||||
typeof customGraphQLSchemaType.getFields === 'function'
|
||||
) {
|
||||
const findAndAddLastType = type => {
|
||||
if (type.name) {
|
||||
if (!this.graphQLAutoSchema.getType(type)) {
|
||||
// To avoid schema stitching (Unknow type) bug on variables
|
||||
// transfer the final type to the Auto Schema
|
||||
this.graphQLAutoSchema._typeMap[type.name] = type;
|
||||
const findAndReplaceLastType = (parent, key) => {
|
||||
if (parent[key].name) {
|
||||
if (
|
||||
this.graphQLAutoSchema.getType(parent[key].name) &&
|
||||
this.graphQLAutoSchema.getType(parent[key].name) !==
|
||||
parent[key]
|
||||
) {
|
||||
// To avoid unresolved field on overloaded schema
|
||||
// replace the final type with the auto schema one
|
||||
parent[key] = this.graphQLAutoSchema.getType(
|
||||
parent[key].name
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if (type.ofType) {
|
||||
findAndAddLastType(type.ofType);
|
||||
if (parent[key].ofType) {
|
||||
findAndReplaceLastType(parent[key], 'ofType');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Object.values(customGraphQLSchemaType.getFields()).forEach(
|
||||
field => {
|
||||
findAndAddLastType(field.type);
|
||||
if (field.args) {
|
||||
field.args.forEach(arg => {
|
||||
findAndAddLastType(arg.type);
|
||||
});
|
||||
}
|
||||
(field) => {
|
||||
findAndReplaceLastType(field, 'type');
|
||||
}
|
||||
);
|
||||
autoGraphQLSchemaType._fields = {
|
||||
...autoGraphQLSchemaType._fields,
|
||||
...customGraphQLSchemaType._fields,
|
||||
...autoGraphQLSchemaType.getFields(),
|
||||
...customGraphQLSchemaType.getFields(),
|
||||
};
|
||||
} else {
|
||||
this.graphQLAutoSchema._typeMap[
|
||||
customGraphQLSchemaType.name
|
||||
] = customGraphQLSchemaType;
|
||||
}
|
||||
}
|
||||
);
|
||||
this.graphQLSchema = mergeSchemas({
|
||||
schemas: [
|
||||
this.graphQLSchemaDirectivesDefinitions,
|
||||
this.graphQLCustomTypeDefs,
|
||||
this.graphQLAutoSchema,
|
||||
],
|
||||
mergeDirectives: true,
|
||||
@@ -271,24 +276,24 @@ class ParseGraphQLSchema {
|
||||
}
|
||||
|
||||
const graphQLSchemaTypeMap = this.graphQLSchema.getTypeMap();
|
||||
Object.keys(graphQLSchemaTypeMap).forEach(graphQLSchemaTypeName => {
|
||||
Object.keys(graphQLSchemaTypeMap).forEach((graphQLSchemaTypeName) => {
|
||||
const graphQLSchemaType = graphQLSchemaTypeMap[graphQLSchemaTypeName];
|
||||
if (
|
||||
typeof graphQLSchemaType.getFields === 'function' &&
|
||||
this.graphQLCustomTypeDefs.definitions
|
||||
) {
|
||||
const graphQLCustomTypeDef = this.graphQLCustomTypeDefs.definitions.find(
|
||||
definition => definition.name.value === graphQLSchemaTypeName
|
||||
(definition) => definition.name.value === graphQLSchemaTypeName
|
||||
);
|
||||
if (graphQLCustomTypeDef) {
|
||||
const graphQLSchemaTypeFieldMap = graphQLSchemaType.getFields();
|
||||
Object.keys(graphQLSchemaTypeFieldMap).forEach(
|
||||
graphQLSchemaTypeFieldName => {
|
||||
(graphQLSchemaTypeFieldName) => {
|
||||
const graphQLSchemaTypeField =
|
||||
graphQLSchemaTypeFieldMap[graphQLSchemaTypeFieldName];
|
||||
if (!graphQLSchemaTypeField.astNode) {
|
||||
const astNode = graphQLCustomTypeDef.fields.find(
|
||||
field => field.name.value === graphQLSchemaTypeFieldName
|
||||
(field) => field.name.value === graphQLSchemaTypeFieldName
|
||||
);
|
||||
if (astNode) {
|
||||
graphQLSchemaTypeField.astNode = astNode;
|
||||
@@ -319,7 +324,9 @@ class ParseGraphQLSchema {
|
||||
) {
|
||||
if (
|
||||
(!ignoreReserved && RESERVED_GRAPHQL_TYPE_NAMES.includes(type.name)) ||
|
||||
this.graphQLTypes.find(existingType => existingType.name === type.name) ||
|
||||
this.graphQLTypes.find(
|
||||
(existingType) => existingType.name === type.name
|
||||
) ||
|
||||
(!ignoreConnection && type.name.endsWith('Connection'))
|
||||
) {
|
||||
const message = `Type ${type.name} could not be added to the auto schema because it collided with an existing type.`;
|
||||
@@ -409,7 +416,7 @@ class ParseGraphQLSchema {
|
||||
if (Array.isArray(enabledForClasses) || Array.isArray(disabledForClasses)) {
|
||||
let includedClasses = allClasses;
|
||||
if (enabledForClasses) {
|
||||
includedClasses = allClasses.filter(clazz => {
|
||||
includedClasses = allClasses.filter((clazz) => {
|
||||
return enabledForClasses.includes(clazz.className);
|
||||
});
|
||||
}
|
||||
@@ -417,12 +424,12 @@ class ParseGraphQLSchema {
|
||||
// Classes included in `enabledForClasses` that
|
||||
// are also present in `disabledForClasses` will
|
||||
// still be filtered out
|
||||
includedClasses = includedClasses.filter(clazz => {
|
||||
includedClasses = includedClasses.filter((clazz) => {
|
||||
return !disabledForClasses.includes(clazz.className);
|
||||
});
|
||||
}
|
||||
|
||||
this.isUsersClassDisabled = !includedClasses.some(clazz => {
|
||||
this.isUsersClassDisabled = !includedClasses.some((clazz) => {
|
||||
return clazz.className === '_User';
|
||||
});
|
||||
|
||||
@@ -467,11 +474,11 @@ class ParseGraphQLSchema {
|
||||
}
|
||||
};
|
||||
|
||||
return parseClasses.sort(sortClasses).map(parseClass => {
|
||||
return parseClasses.sort(sortClasses).map((parseClass) => {
|
||||
let parseClassConfig;
|
||||
if (classConfigs) {
|
||||
parseClassConfig = classConfigs.find(
|
||||
c => c.className === parseClass.className
|
||||
(c) => c.className === parseClass.className
|
||||
);
|
||||
}
|
||||
return [parseClass, parseClassConfig];
|
||||
@@ -479,7 +486,7 @@ class ParseGraphQLSchema {
|
||||
}
|
||||
|
||||
async _getFunctionNames() {
|
||||
return await getFunctionNames(this.appId).filter(functionName => {
|
||||
return await getFunctionNames(this.appId).filter((functionName) => {
|
||||
if (/^[_a-zA-Z][_a-zA-Z0-9]*$/.test(functionName)) {
|
||||
return true;
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user