* add parse-graph-ql configuration for class schema customisation Not yet tested - essentially an RFC * refactor and add graphql router, controller and config cache * fix(GraphQLController): add missing check isEnabled * chore(GraphQLController): remove awaits from cache put * chore(GraphQLController): remove check for if its enabled * refactor(GraphQLController): only use cache if mounted * chore(GraphQLController): group all validation errors and throw at once * chore(GraphQLSchema): move transformations into controller validation * refactor(GraphQL): improve ctrl validation and fix schema usage of config * refactor(GraphQLSchema): remove code related to additional schema This code has been moved into a separate feature branch. * fix(GraphQLSchema): fix incorrect default return type for class configs * refactor(GraphQLSchema): update staleness check code to account for config * fix(GraphQLServer): fix regressed tests due to internal schema changes This will be followed up with a backwards compatability fix for the `ClassFields` issue to avoid breakages for our users * refactor: rename to ParseGraphQLController for consistency * fix(ParseGraphQLCtrl): numerous fixes for validity checking Also includes some minor code refactoring * chore(GraphQL): minor syntax cleanup * fix(SchemaController): add _GraphQLConfig to volatile classes * refactor(ParseGraphQLServer): return update config value in setGraphQLConfig * testing(ParseGraphQL): add test cases for new graphQLConfig * fix(GraphQLController): fix issue where config with multiple items was not being mapped to the db * fix(postgres): add _GraphQLConfig default schema on load fixes failing postgres tests * GraphQL @mock directive (#5836) * Add mock directive * Include tests for @mock directive * Fix existing tests due to the change from ClassFields to ClassCreateFields * fix(parseClassMutations): safer type transformation based on input type * fix(parseClassMutations): only define necessary input fields * fix(GraphQL): fix incorrect import paths
122 lines
3.7 KiB
JavaScript
122 lines
3.7 KiB
JavaScript
import { GraphQLNonNull } from 'graphql';
|
|
import getFieldNames from 'graphql-list-fields';
|
|
import * as defaultGraphQLTypes from './defaultGraphQLTypes';
|
|
import * as objectsQueries from './objectsQueries';
|
|
import * as parseClassTypes from './parseClassTypes';
|
|
import { ParseGraphQLClassConfig } from '../../Controllers/ParseGraphQLController';
|
|
|
|
const getParseClassQueryConfig = function(
|
|
parseClassConfig: ?ParseGraphQLClassConfig
|
|
) {
|
|
return (parseClassConfig && parseClassConfig.query) || {};
|
|
};
|
|
|
|
const load = function(
|
|
parseGraphQLSchema,
|
|
parseClass,
|
|
parseClassConfig: ?ParseGraphQLClassConfig
|
|
) {
|
|
const { className } = parseClass;
|
|
const {
|
|
get: isGetEnabled = true,
|
|
find: isFindEnabled = true,
|
|
} = getParseClassQueryConfig(parseClassConfig);
|
|
|
|
const {
|
|
classGraphQLOutputType,
|
|
classGraphQLFindArgs,
|
|
classGraphQLFindResultType,
|
|
} = parseGraphQLSchema.parseClassTypes[className];
|
|
|
|
if (isGetEnabled) {
|
|
const getGraphQLQueryName = `get${className}`;
|
|
parseGraphQLSchema.graphQLObjectsQueries[getGraphQLQueryName] = {
|
|
description: `The ${getGraphQLQueryName} query can be used to get an object of the ${className} class by its id.`,
|
|
args: {
|
|
objectId: defaultGraphQLTypes.OBJECT_ID_ATT,
|
|
readPreference: defaultGraphQLTypes.READ_PREFERENCE_ATT,
|
|
includeReadPreference: defaultGraphQLTypes.INCLUDE_READ_PREFERENCE_ATT,
|
|
},
|
|
type: new GraphQLNonNull(classGraphQLOutputType),
|
|
async resolve(_source, args, context, queryInfo) {
|
|
try {
|
|
const { objectId, readPreference, includeReadPreference } = args;
|
|
const { config, auth, info } = context;
|
|
const selectedFields = getFieldNames(queryInfo);
|
|
|
|
const { keys, include } = parseClassTypes.extractKeysAndInclude(
|
|
selectedFields
|
|
);
|
|
|
|
return await objectsQueries.getObject(
|
|
className,
|
|
objectId,
|
|
keys,
|
|
include,
|
|
readPreference,
|
|
includeReadPreference,
|
|
config,
|
|
auth,
|
|
info
|
|
);
|
|
} catch (e) {
|
|
parseGraphQLSchema.handleError(e);
|
|
}
|
|
},
|
|
};
|
|
}
|
|
|
|
if (isFindEnabled) {
|
|
const findGraphQLQueryName = `find${className}`;
|
|
parseGraphQLSchema.graphQLObjectsQueries[findGraphQLQueryName] = {
|
|
description: `The ${findGraphQLQueryName} query can be used to find objects of the ${className} class.`,
|
|
args: classGraphQLFindArgs,
|
|
type: new GraphQLNonNull(classGraphQLFindResultType),
|
|
async resolve(_source, args, context, queryInfo) {
|
|
try {
|
|
const {
|
|
where,
|
|
order,
|
|
skip,
|
|
limit,
|
|
readPreference,
|
|
includeReadPreference,
|
|
subqueryReadPreference,
|
|
} = args;
|
|
const { config, auth, info } = context;
|
|
const selectedFields = getFieldNames(queryInfo);
|
|
|
|
const { keys, include } = parseClassTypes.extractKeysAndInclude(
|
|
selectedFields
|
|
.filter(field => field.includes('.'))
|
|
.map(field => field.slice(field.indexOf('.') + 1))
|
|
);
|
|
const parseOrder = order && order.join(',');
|
|
|
|
return await objectsQueries.findObjects(
|
|
className,
|
|
where,
|
|
parseOrder,
|
|
skip,
|
|
limit,
|
|
keys,
|
|
include,
|
|
false,
|
|
readPreference,
|
|
includeReadPreference,
|
|
subqueryReadPreference,
|
|
config,
|
|
auth,
|
|
info,
|
|
selectedFields.map(field => field.split('.', 1)[0])
|
|
);
|
|
} catch (e) {
|
|
parseGraphQLSchema.handleError(e);
|
|
}
|
|
},
|
|
};
|
|
}
|
|
};
|
|
|
|
export { load };
|