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: [
|
OR: [
|
||||||
{
|
{
|
||||||
pointerToUser: {
|
pointerToUser: {
|
||||||
equalTo: {
|
equalTo: user5.id,
|
||||||
__type: 'Pointer',
|
|
||||||
className: '_User',
|
|
||||||
objectId: user5.id,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -3413,6 +3409,40 @@ describe('ParseGraphQLServer', () => {
|
|||||||
).toEqual(['someValue1', 'someValue3']);
|
).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 () => {
|
it('should support OR operation', async () => {
|
||||||
await prepareData();
|
await prepareData();
|
||||||
|
|
||||||
@@ -3558,11 +3588,7 @@ describe('ParseGraphQLServer', () => {
|
|||||||
OR: [
|
OR: [
|
||||||
{
|
{
|
||||||
pointerToUser: {
|
pointerToUser: {
|
||||||
equalTo: {
|
equalTo: user5.id,
|
||||||
__type: 'Pointer',
|
|
||||||
className: '_User',
|
|
||||||
objectId: user5.id,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -3614,11 +3640,7 @@ describe('ParseGraphQLServer', () => {
|
|||||||
OR: [
|
OR: [
|
||||||
{
|
{
|
||||||
pointerToUser: {
|
pointerToUser: {
|
||||||
equalTo: {
|
equalTo: user5.id,
|
||||||
__type: 'Pointer',
|
|
||||||
className: '_User',
|
|
||||||
objectId: user5.id,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -62,12 +62,13 @@ const findObjects = async (
|
|||||||
config,
|
config,
|
||||||
auth,
|
auth,
|
||||||
info,
|
info,
|
||||||
selectedFields
|
selectedFields,
|
||||||
|
fields
|
||||||
) => {
|
) => {
|
||||||
if (!where) {
|
if (!where) {
|
||||||
where = {};
|
where = {};
|
||||||
}
|
}
|
||||||
transformQueryInputToParse(where);
|
transformQueryInputToParse(where, fields);
|
||||||
|
|
||||||
const options = {};
|
const options = {};
|
||||||
|
|
||||||
|
|||||||
@@ -120,7 +120,8 @@ const load = function(
|
|||||||
config,
|
config,
|
||||||
auth,
|
auth,
|
||||||
info,
|
info,
|
||||||
selectedFields.map(field => field.split('.', 1)[0])
|
selectedFields.map(field => field.split('.', 1)[0]),
|
||||||
|
parseClass.fields
|
||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
parseGraphQLSchema.handleError(e);
|
parseGraphQLSchema.handleError(e);
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
import {
|
import {
|
||||||
Kind,
|
|
||||||
GraphQLID,
|
GraphQLID,
|
||||||
GraphQLObjectType,
|
GraphQLObjectType,
|
||||||
GraphQLString,
|
GraphQLString,
|
||||||
GraphQLList,
|
GraphQLList,
|
||||||
GraphQLInputObjectType,
|
GraphQLInputObjectType,
|
||||||
GraphQLNonNull,
|
GraphQLNonNull,
|
||||||
GraphQLScalarType,
|
|
||||||
GraphQLEnumType,
|
GraphQLEnumType,
|
||||||
} from 'graphql';
|
} from 'graphql';
|
||||||
import getFieldNames from 'graphql-list-fields';
|
import getFieldNames from 'graphql-list-fields';
|
||||||
@@ -138,86 +136,6 @@ const load = (
|
|||||||
update: isUpdateEnabled = true,
|
update: isUpdateEnabled = true,
|
||||||
} = getParseClassMutationConfig(parseClassConfig);
|
} = 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`;
|
const classGraphQLCreateTypeName = `Create${graphQLClassName}FieldsInput`;
|
||||||
let classGraphQLCreateType = new GraphQLInputObjectType({
|
let classGraphQLCreateType = new GraphQLInputObjectType({
|
||||||
name: classGraphQLCreateTypeName,
|
name: classGraphQLCreateTypeName,
|
||||||
@@ -341,10 +259,10 @@ const load = (
|
|||||||
name: classGraphQLConstraintTypeName,
|
name: classGraphQLConstraintTypeName,
|
||||||
description: `The ${classGraphQLConstraintTypeName} input type is used in operations that involve filtering objects by a pointer field to ${graphQLClassName} class.`,
|
description: `The ${classGraphQLConstraintTypeName} input type is used in operations that involve filtering objects by a pointer field to ${graphQLClassName} class.`,
|
||||||
fields: {
|
fields: {
|
||||||
equalTo: defaultGraphQLTypes.equalTo(classGraphQLScalarType),
|
equalTo: defaultGraphQLTypes.equalTo(GraphQLID),
|
||||||
notEqualTo: defaultGraphQLTypes.notEqualTo(classGraphQLScalarType),
|
notEqualTo: defaultGraphQLTypes.notEqualTo(GraphQLID),
|
||||||
in: defaultGraphQLTypes.inOp(classGraphQLScalarType),
|
in: defaultGraphQLTypes.inOp(defaultGraphQLTypes.OBJECT_ID),
|
||||||
notIn: defaultGraphQLTypes.notIn(classGraphQLScalarType),
|
notIn: defaultGraphQLTypes.notIn(defaultGraphQLTypes.OBJECT_ID),
|
||||||
exists: defaultGraphQLTypes.exists,
|
exists: defaultGraphQLTypes.exists,
|
||||||
inQueryKey: defaultGraphQLTypes.inQueryKey,
|
inQueryKey: defaultGraphQLTypes.inQueryKey,
|
||||||
notInQueryKey: defaultGraphQLTypes.notInQueryKey,
|
notInQueryKey: defaultGraphQLTypes.notInQueryKey,
|
||||||
@@ -519,7 +437,8 @@ const load = (
|
|||||||
config,
|
config,
|
||||||
auth,
|
auth,
|
||||||
info,
|
info,
|
||||||
selectedFields.map(field => field.split('.', 1)[0])
|
selectedFields.map(field => field.split('.', 1)[0]),
|
||||||
|
parseClass.fields
|
||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
parseGraphQLSchema.handleError(e);
|
parseGraphQLSchema.handleError(e);
|
||||||
@@ -615,7 +534,6 @@ const load = (
|
|||||||
parseGraphQLSchema.parseClassTypes[className] = {
|
parseGraphQLSchema.parseClassTypes[className] = {
|
||||||
classGraphQLPointerType,
|
classGraphQLPointerType,
|
||||||
classGraphQLRelationType,
|
classGraphQLRelationType,
|
||||||
classGraphQLScalarType,
|
|
||||||
classGraphQLCreateType,
|
classGraphQLCreateType,
|
||||||
classGraphQLUpdateType,
|
classGraphQLUpdateType,
|
||||||
classGraphQLConstraintType,
|
classGraphQLConstraintType,
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ const parseConstraintMap = {
|
|||||||
|
|
||||||
const transformQueryConstraintInputToParse = (
|
const transformQueryConstraintInputToParse = (
|
||||||
constraints,
|
constraints,
|
||||||
|
fields,
|
||||||
parentFieldName,
|
parentFieldName,
|
||||||
parentConstraints
|
parentConstraints
|
||||||
) => {
|
) => {
|
||||||
@@ -92,6 +93,21 @@ const transformQueryConstraintInputToParse = (
|
|||||||
delete constraints[fieldName];
|
delete constraints[fieldName];
|
||||||
fieldName = parseConstraintMap[fieldName];
|
fieldName = parseConstraintMap[fieldName];
|
||||||
constraints[fieldName] = fieldValue;
|
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) {
|
switch (fieldName) {
|
||||||
case '$point':
|
case '$point':
|
||||||
@@ -151,6 +167,7 @@ const transformQueryConstraintInputToParse = (
|
|||||||
} else {
|
} else {
|
||||||
transformQueryConstraintInputToParse(
|
transformQueryConstraintInputToParse(
|
||||||
fieldValue,
|
fieldValue,
|
||||||
|
fields,
|
||||||
fieldName,
|
fieldName,
|
||||||
constraints
|
constraints
|
||||||
);
|
);
|
||||||
@@ -159,7 +176,7 @@ const transformQueryConstraintInputToParse = (
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const transformQueryInputToParse = constraints => {
|
const transformQueryInputToParse = (constraints, fields) => {
|
||||||
if (!constraints || typeof constraints !== 'object') {
|
if (!constraints || typeof constraints !== 'object') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -174,14 +191,14 @@ const transformQueryInputToParse = constraints => {
|
|||||||
|
|
||||||
if (fieldName !== 'objectId') {
|
if (fieldName !== 'objectId') {
|
||||||
fieldValue.forEach(fieldValueItem => {
|
fieldValue.forEach(fieldValueItem => {
|
||||||
transformQueryInputToParse(fieldValueItem);
|
transformQueryInputToParse(fieldValueItem, fields);
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof fieldValue === 'object') {
|
if (typeof fieldValue === 'object') {
|
||||||
transformQueryConstraintInputToParse(fieldValue, fieldName, constraints);
|
transformQueryConstraintInputToParse(fieldValue, fields, fieldName, constraints);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user