diff --git a/spec/ParseGraphQLSchema.spec.js b/spec/ParseGraphQLSchema.spec.js index 6d99dce68e..82391e06e5 100644 --- a/spec/ParseGraphQLSchema.spec.js +++ b/spec/ParseGraphQLSchema.spec.js @@ -564,4 +564,102 @@ describe('ParseGraphQLSchema', () => { ).toEqual(Object.keys(mutations2).sort()); }); }); + + describe('query alias', () => { + it('Should be able to define alias for find query', async () => { + const parseGraphQLSchema = new ParseGraphQLSchema({ + databaseController, + parseGraphQLController, + log: defaultLogger, + appId, + }); + + await parseGraphQLSchema.parseGraphQLController.updateGraphQLConfig({ + classConfigs: [ + { + className: 'Data', + query: { + get: true, + getAlias: 'precious_data', + find: true, + findAlias: 'data_results', + }, + }, + ], + }); + + const data = new Parse.Object('Data'); + + await data.save(); + + await parseGraphQLSchema.databaseController.schemaCache.clear(); + await parseGraphQLSchema.load(); + + const queries1 = parseGraphQLSchema.graphQLQueries; + + expect(Object.keys(queries1)).toContain('data_results'); + expect(Object.keys(queries1)).toContain('precious_data'); + }); + + it('should fail if query alias is not a string', async () => { + const parseGraphQLSchema = new ParseGraphQLSchema({ + databaseController, + parseGraphQLController, + log: defaultLogger, + appId, + }); + + const classConfigsBoolFindAlias = { + classConfigs: [ + { + className: 'Data', + query: { + get: true, + getAlias: 'valid', + find: true, + findAlias: true, + }, + }, + ], + }; + + const classConfigsNumberGetAlias = { + classConfigs: [ + { + className: 'Pants', + query: { + get: true, + getAlias: 1, + find: true, + findAlias: 'valid', + }, + }, + ], + }; + + let className; + + className = classConfigsBoolFindAlias.classConfigs[0].className; + try { + await parseGraphQLSchema.parseGraphQLController.updateGraphQLConfig( + classConfigsBoolFindAlias + ); + } catch (e) { + expect(e).toMatch( + `Invalid graphQLConfig: classConfig:${className} is invalid because "query.findAlias" must be a string` + ); + } + + className = classConfigsNumberGetAlias.classConfigs[0].className; + try { + await parseGraphQLSchema.parseGraphQLController.updateGraphQLConfig( + classConfigsNumberGetAlias + ); + } catch (e) { + expect(e).toMatch( + `Invalid graphQLConfig: classConfig:${className} is invalid because "query.getAlias" must be a string` + ); + } + }); + }); }); diff --git a/src/Controllers/ParseGraphQLController.js b/src/Controllers/ParseGraphQLController.js index 6194ad5687..a348dc9b37 100644 --- a/src/Controllers/ParseGraphQLController.js +++ b/src/Controllers/ParseGraphQLController.js @@ -266,7 +266,13 @@ class ParseGraphQLController { } if (query !== null) { if (isValidSimpleObject(query)) { - const { find = null, get = null, ...invalidKeys } = query; + const { + find = null, + get = null, + findAlias = null, + getAlias = null, + ...invalidKeys + } = query; if (Object.keys(invalidKeys).length) { return `"query" contains invalid keys, [${Object.keys( invalidKeys @@ -275,6 +281,10 @@ class ParseGraphQLController { return `"query.find" must be a boolean`; } else if (get !== null && typeof get !== 'boolean') { return `"query.get" must be a boolean`; + } else if (findAlias !== null && typeof findAlias !== 'string') { + return `"query.findAlias" must be a string`; + } else if (getAlias !== null && typeof getAlias !== 'string') { + return `"query.getAlias" must be a string`; } } else { return `"query" must be a valid object`; @@ -361,6 +371,8 @@ export interface ParseGraphQLClassConfig { query: ?{ get: ?boolean, find: ?boolean, + findAlias: ?String, + getAlias: ?String, }; /* The `mutation` object contains options for which class mutations are generated */ mutation: ?{ diff --git a/src/GraphQL/loaders/parseClassQueries.js b/src/GraphQL/loaders/parseClassQueries.js index 63041ad94d..b4687113ed 100644 --- a/src/GraphQL/loaders/parseClassQueries.js +++ b/src/GraphQL/loaders/parseClassQueries.js @@ -44,6 +44,8 @@ const load = function( const { get: isGetEnabled = true, find: isFindEnabled = true, + getAlias: getAlias = '', + findAlias: findAlias = '', } = getParseClassQueryConfig(parseClassConfig); const { @@ -53,8 +55,11 @@ const load = function( } = parseGraphQLSchema.parseClassTypes[className]; if (isGetEnabled) { - const getGraphQLQueryName = + const lowerCaseClassName = graphQLClassName.charAt(0).toLowerCase() + graphQLClassName.slice(1); + + const getGraphQLQueryName = getAlias || lowerCaseClassName; + parseGraphQLSchema.addGraphQLQuery(getGraphQLQueryName, { description: `The ${getGraphQLQueryName} query can be used to get an object of the ${graphQLClassName} class by its id.`, args: { @@ -75,9 +80,11 @@ const load = function( } if (isFindEnabled) { - const findGraphQLQueryName = pluralize( - graphQLClassName.charAt(0).toLowerCase() + graphQLClassName.slice(1) - ); + const lowerCaseClassName = + graphQLClassName.charAt(0).toLowerCase() + graphQLClassName.slice(1); + + const findGraphQLQueryName = findAlias || pluralize(lowerCaseClassName); + parseGraphQLSchema.addGraphQLQuery(findGraphQLQueryName, { description: `The ${findGraphQLQueryName} query can be used to find objects of the ${graphQLClassName} class.`, args: classGraphQLFindArgs,