refactor(GraphQL): Pointer constraint input type as ID (#6020)
* refactor(GraphQL): Pointer constraint input type as ID Redefines the Pointer constraint input type from a custom scalar to a simple ID. * fix: PR review requested changes
This commit is contained in:
committed by
Antonio Davi Macedo Coelho de Castro
parent
34f1bf384d
commit
f9b77c1bc7
@@ -3384,11 +3384,7 @@ describe('ParseGraphQLServer', () => {
|
||||
OR: [
|
||||
{
|
||||
pointerToUser: {
|
||||
equalTo: {
|
||||
__type: 'Pointer',
|
||||
className: '_User',
|
||||
objectId: user5.id,
|
||||
},
|
||||
equalTo: user5.id,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -3413,6 +3409,40 @@ describe('ParseGraphQLServer', () => {
|
||||
).toEqual(['someValue1', 'someValue3']);
|
||||
});
|
||||
|
||||
it('should support in pointer operator using class specific query', async () => {
|
||||
await prepareData();
|
||||
|
||||
await parseGraphQLServer.parseGraphQLSchema.databaseController.schemaCache.clear();
|
||||
|
||||
const result = await apolloClient.query({
|
||||
query: gql`
|
||||
query FindSomeObjects($where: GraphQLClassWhereInput) {
|
||||
graphQLClasses(where: $where) {
|
||||
results {
|
||||
someField
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
variables: {
|
||||
where: {
|
||||
pointerToUser: {
|
||||
in: [user5.id],
|
||||
},
|
||||
},
|
||||
},
|
||||
context: {
|
||||
headers: {
|
||||
'X-Parse-Master-Key': 'test',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const { results } = result.data.graphQLClasses;
|
||||
expect(results.length).toBe(1);
|
||||
expect(results[0].someField).toEqual('someValue3');
|
||||
});
|
||||
|
||||
it('should support OR operation', async () => {
|
||||
await prepareData();
|
||||
|
||||
@@ -3558,11 +3588,7 @@ describe('ParseGraphQLServer', () => {
|
||||
OR: [
|
||||
{
|
||||
pointerToUser: {
|
||||
equalTo: {
|
||||
__type: 'Pointer',
|
||||
className: '_User',
|
||||
objectId: user5.id,
|
||||
},
|
||||
equalTo: user5.id,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -3614,11 +3640,7 @@ describe('ParseGraphQLServer', () => {
|
||||
OR: [
|
||||
{
|
||||
pointerToUser: {
|
||||
equalTo: {
|
||||
__type: 'Pointer',
|
||||
className: '_User',
|
||||
objectId: user5.id,
|
||||
},
|
||||
equalTo: user5.id,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -62,12 +62,13 @@ const findObjects = async (
|
||||
config,
|
||||
auth,
|
||||
info,
|
||||
selectedFields
|
||||
selectedFields,
|
||||
fields
|
||||
) => {
|
||||
if (!where) {
|
||||
where = {};
|
||||
}
|
||||
transformQueryInputToParse(where);
|
||||
transformQueryInputToParse(where, fields);
|
||||
|
||||
const options = {};
|
||||
|
||||
|
||||
@@ -120,7 +120,8 @@ const load = function(
|
||||
config,
|
||||
auth,
|
||||
info,
|
||||
selectedFields.map(field => field.split('.', 1)[0])
|
||||
selectedFields.map(field => field.split('.', 1)[0]),
|
||||
parseClass.fields
|
||||
);
|
||||
} catch (e) {
|
||||
parseGraphQLSchema.handleError(e);
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
import {
|
||||
Kind,
|
||||
GraphQLID,
|
||||
GraphQLObjectType,
|
||||
GraphQLString,
|
||||
GraphQLList,
|
||||
GraphQLInputObjectType,
|
||||
GraphQLNonNull,
|
||||
GraphQLScalarType,
|
||||
GraphQLEnumType,
|
||||
} from 'graphql';
|
||||
import getFieldNames from 'graphql-list-fields';
|
||||
@@ -138,86 +136,6 @@ const load = (
|
||||
update: isUpdateEnabled = true,
|
||||
} = getParseClassMutationConfig(parseClassConfig);
|
||||
|
||||
const classGraphQLScalarTypeName = `${graphQLClassName}Pointer`;
|
||||
const parseScalarValue = value => {
|
||||
if (typeof value === 'string') {
|
||||
return {
|
||||
__type: 'Pointer',
|
||||
className: className,
|
||||
objectId: value,
|
||||
};
|
||||
} else if (
|
||||
typeof value === 'object' &&
|
||||
value.__type === 'Pointer' &&
|
||||
value.className === className &&
|
||||
typeof value.objectId === 'string'
|
||||
) {
|
||||
return { ...value, className };
|
||||
}
|
||||
|
||||
throw new defaultGraphQLTypes.TypeValidationError(
|
||||
value,
|
||||
classGraphQLScalarTypeName
|
||||
);
|
||||
};
|
||||
let classGraphQLScalarType = new GraphQLScalarType({
|
||||
name: classGraphQLScalarTypeName,
|
||||
description: `The ${classGraphQLScalarTypeName} is used in operations that involve ${graphQLClassName} pointers.`,
|
||||
parseValue: parseScalarValue,
|
||||
serialize(value) {
|
||||
if (typeof value === 'string') {
|
||||
return value;
|
||||
} else if (
|
||||
typeof value === 'object' &&
|
||||
value.__type === 'Pointer' &&
|
||||
value.className === className &&
|
||||
typeof value.objectId === 'string'
|
||||
) {
|
||||
return value.objectId;
|
||||
}
|
||||
|
||||
throw new defaultGraphQLTypes.TypeValidationError(
|
||||
value,
|
||||
classGraphQLScalarTypeName
|
||||
);
|
||||
},
|
||||
parseLiteral(ast) {
|
||||
if (ast.kind === Kind.STRING) {
|
||||
return parseScalarValue(ast.value);
|
||||
} else if (ast.kind === Kind.OBJECT) {
|
||||
const __type = ast.fields.find(field => field.name.value === '__type');
|
||||
const className = ast.fields.find(
|
||||
field => field.name.value === 'className'
|
||||
);
|
||||
const objectId = ast.fields.find(
|
||||
field => field.name.value === 'objectId'
|
||||
);
|
||||
if (
|
||||
__type &&
|
||||
__type.value &&
|
||||
className &&
|
||||
className.value &&
|
||||
objectId &&
|
||||
objectId.value
|
||||
) {
|
||||
return parseScalarValue({
|
||||
__type: __type.value.value,
|
||||
className: className.value.value,
|
||||
objectId: objectId.value.value,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
throw new defaultGraphQLTypes.TypeValidationError(
|
||||
ast.kind,
|
||||
classGraphQLScalarTypeName
|
||||
);
|
||||
},
|
||||
});
|
||||
classGraphQLScalarType =
|
||||
parseGraphQLSchema.addGraphQLType(classGraphQLScalarType) ||
|
||||
defaultGraphQLTypes.OBJECT;
|
||||
|
||||
const classGraphQLCreateTypeName = `Create${graphQLClassName}FieldsInput`;
|
||||
let classGraphQLCreateType = new GraphQLInputObjectType({
|
||||
name: classGraphQLCreateTypeName,
|
||||
@@ -341,10 +259,10 @@ const load = (
|
||||
name: classGraphQLConstraintTypeName,
|
||||
description: `The ${classGraphQLConstraintTypeName} input type is used in operations that involve filtering objects by a pointer field to ${graphQLClassName} class.`,
|
||||
fields: {
|
||||
equalTo: defaultGraphQLTypes.equalTo(classGraphQLScalarType),
|
||||
notEqualTo: defaultGraphQLTypes.notEqualTo(classGraphQLScalarType),
|
||||
in: defaultGraphQLTypes.inOp(classGraphQLScalarType),
|
||||
notIn: defaultGraphQLTypes.notIn(classGraphQLScalarType),
|
||||
equalTo: defaultGraphQLTypes.equalTo(GraphQLID),
|
||||
notEqualTo: defaultGraphQLTypes.notEqualTo(GraphQLID),
|
||||
in: defaultGraphQLTypes.inOp(defaultGraphQLTypes.OBJECT_ID),
|
||||
notIn: defaultGraphQLTypes.notIn(defaultGraphQLTypes.OBJECT_ID),
|
||||
exists: defaultGraphQLTypes.exists,
|
||||
inQueryKey: defaultGraphQLTypes.inQueryKey,
|
||||
notInQueryKey: defaultGraphQLTypes.notInQueryKey,
|
||||
@@ -519,7 +437,8 @@ const load = (
|
||||
config,
|
||||
auth,
|
||||
info,
|
||||
selectedFields.map(field => field.split('.', 1)[0])
|
||||
selectedFields.map(field => field.split('.', 1)[0]),
|
||||
parseClass.fields
|
||||
);
|
||||
} catch (e) {
|
||||
parseGraphQLSchema.handleError(e);
|
||||
@@ -615,7 +534,6 @@ const load = (
|
||||
parseGraphQLSchema.parseClassTypes[className] = {
|
||||
classGraphQLPointerType,
|
||||
classGraphQLRelationType,
|
||||
classGraphQLScalarType,
|
||||
classGraphQLCreateType,
|
||||
classGraphQLUpdateType,
|
||||
classGraphQLConstraintType,
|
||||
|
||||
@@ -45,6 +45,7 @@ const parseConstraintMap = {
|
||||
|
||||
const transformQueryConstraintInputToParse = (
|
||||
constraints,
|
||||
fields,
|
||||
parentFieldName,
|
||||
parentConstraints
|
||||
) => {
|
||||
@@ -92,6 +93,21 @@ const transformQueryConstraintInputToParse = (
|
||||
delete constraints[fieldName];
|
||||
fieldName = parseConstraintMap[fieldName];
|
||||
constraints[fieldName] = fieldValue;
|
||||
|
||||
// If parent field type is Pointer, changes constraint value to format expected
|
||||
// by Parse.
|
||||
if (
|
||||
fields[parentFieldName] &&
|
||||
fields[parentFieldName].type === 'Pointer' &&
|
||||
typeof fieldValue === 'string'
|
||||
) {
|
||||
const { targetClass } = fields[parentFieldName];
|
||||
constraints[fieldName] = {
|
||||
__type: 'Pointer',
|
||||
className: targetClass,
|
||||
objectId: fieldValue,
|
||||
};
|
||||
}
|
||||
}
|
||||
switch (fieldName) {
|
||||
case '$point':
|
||||
@@ -151,6 +167,7 @@ const transformQueryConstraintInputToParse = (
|
||||
} else {
|
||||
transformQueryConstraintInputToParse(
|
||||
fieldValue,
|
||||
fields,
|
||||
fieldName,
|
||||
constraints
|
||||
);
|
||||
@@ -159,7 +176,7 @@ const transformQueryConstraintInputToParse = (
|
||||
});
|
||||
};
|
||||
|
||||
const transformQueryInputToParse = constraints => {
|
||||
const transformQueryInputToParse = (constraints, fields) => {
|
||||
if (!constraints || typeof constraints !== 'object') {
|
||||
return;
|
||||
}
|
||||
@@ -174,14 +191,14 @@ const transformQueryInputToParse = constraints => {
|
||||
|
||||
if (fieldName !== 'objectId') {
|
||||
fieldValue.forEach(fieldValueItem => {
|
||||
transformQueryInputToParse(fieldValueItem);
|
||||
transformQueryInputToParse(fieldValueItem, fields);
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof fieldValue === 'object') {
|
||||
transformQueryConstraintInputToParse(fieldValue, fieldName, constraints);
|
||||
transformQueryConstraintInputToParse(fieldValue, fields, fieldName, constraints);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user