GraphQL: DX Relational Where Query (#6255)
* DX Relational Where Query * Remove WherePointer & fix tests * Add have, haveNot, exists on Pointer/Relation where input * Merge branch 'master' into gql-relational-query * Enable inQueryKey * better descrption
This commit is contained in:
committed by
Antonio Davi Macedo Coelho de Castro
parent
afe49cb1f7
commit
5d76b2f354
@@ -26,9 +26,9 @@ const transformConstraintTypeToGraphQL = (
|
||||
case 'Pointer':
|
||||
if (
|
||||
parseClassTypes[targetClass] &&
|
||||
parseClassTypes[targetClass].classGraphQLConstraintType
|
||||
parseClassTypes[targetClass].classGraphQLRelationConstraintsType
|
||||
) {
|
||||
return parseClassTypes[targetClass].classGraphQLConstraintType;
|
||||
return parseClassTypes[targetClass].classGraphQLRelationConstraintsType;
|
||||
} else {
|
||||
return defaultGraphQLTypes.OBJECT;
|
||||
}
|
||||
@@ -43,6 +43,14 @@ const transformConstraintTypeToGraphQL = (
|
||||
case 'ACL':
|
||||
return defaultGraphQLTypes.OBJECT_WHERE_INPUT;
|
||||
case 'Relation':
|
||||
if (
|
||||
parseClassTypes[targetClass] &&
|
||||
parseClassTypes[targetClass].classGraphQLRelationConstraintsType
|
||||
) {
|
||||
return parseClassTypes[targetClass].classGraphQLRelationConstraintsType;
|
||||
} else {
|
||||
return defaultGraphQLTypes.OBJECT;
|
||||
}
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { fromGlobalId } from 'graphql-relay';
|
||||
|
||||
const parseQueryMap = {
|
||||
id: 'objectId',
|
||||
OR: '$or',
|
||||
AND: '$and',
|
||||
NOR: '$nor',
|
||||
@@ -47,13 +46,44 @@ const parseConstraintMap = {
|
||||
|
||||
const transformQueryConstraintInputToParse = (
|
||||
constraints,
|
||||
fields,
|
||||
parentFieldName,
|
||||
parentConstraints
|
||||
className,
|
||||
parentConstraints,
|
||||
parseClasses
|
||||
) => {
|
||||
const fields = parseClasses.find(
|
||||
parseClass => parseClass.className === className
|
||||
).fields;
|
||||
if (parentFieldName === 'id' && className) {
|
||||
Object.keys(constraints).forEach(constraintName => {
|
||||
const constraintValue = constraints[constraintName];
|
||||
if (typeof constraintValue === 'string') {
|
||||
const globalIdObject = fromGlobalId(constraintValue);
|
||||
|
||||
if (globalIdObject.type === className) {
|
||||
constraints[constraintName] = globalIdObject.id;
|
||||
}
|
||||
} else if (Array.isArray(constraintValue)) {
|
||||
constraints[constraintName] = constraintValue.map(value => {
|
||||
const globalIdObject = fromGlobalId(value);
|
||||
|
||||
if (globalIdObject.type === className) {
|
||||
return globalIdObject.id;
|
||||
}
|
||||
|
||||
return value;
|
||||
});
|
||||
}
|
||||
});
|
||||
parentConstraints.objectId = constraints;
|
||||
delete parentConstraints.id;
|
||||
}
|
||||
Object.keys(constraints).forEach(fieldName => {
|
||||
let fieldValue = constraints[fieldName];
|
||||
|
||||
if (parseConstraintMap[fieldName]) {
|
||||
constraints[parseConstraintMap[fieldName]] = constraints[fieldName];
|
||||
delete constraints[fieldName];
|
||||
}
|
||||
/**
|
||||
* If we have a key-value pair, we need to change the way the constraint is structured.
|
||||
*
|
||||
@@ -91,30 +121,65 @@ const transformQueryConstraintInputToParse = (
|
||||
...parentConstraints[`${parentFieldName}.${fieldValue.key}`],
|
||||
[parseConstraintMap[fieldName]]: fieldValue.value,
|
||||
};
|
||||
} else if (parseConstraintMap[fieldName]) {
|
||||
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];
|
||||
let objectId = fieldValue;
|
||||
const globalIdObject = fromGlobalId(objectId);
|
||||
if (globalIdObject.type === targetClass) {
|
||||
objectId = globalIdObject.id;
|
||||
} else if (
|
||||
fields[parentFieldName] &&
|
||||
(fields[parentFieldName].type === 'Pointer' ||
|
||||
fields[parentFieldName].type === 'Relation')
|
||||
) {
|
||||
const { targetClass } = fields[parentFieldName];
|
||||
if (fieldName === 'exists') {
|
||||
if (fields[parentFieldName].type === 'Relation') {
|
||||
const whereTarget = fieldValue ? 'where' : 'notWhere';
|
||||
if (constraints[whereTarget]) {
|
||||
if (constraints[whereTarget].objectId) {
|
||||
constraints[whereTarget].objectId = {
|
||||
...constraints[whereTarget].objectId,
|
||||
$exists: fieldValue,
|
||||
};
|
||||
} else {
|
||||
constraints[whereTarget].objectId = {
|
||||
$exists: fieldValue,
|
||||
};
|
||||
}
|
||||
} else {
|
||||
const parseWhereTarget = fieldValue ? '$inQuery' : '$notInQuery';
|
||||
parentConstraints[parentFieldName][parseWhereTarget] = {
|
||||
where: { objectId: { $exists: true } },
|
||||
className: targetClass,
|
||||
};
|
||||
}
|
||||
delete constraints.$exists;
|
||||
} else {
|
||||
parentConstraints[parentFieldName].$exists = fieldValue;
|
||||
}
|
||||
constraints[fieldName] = {
|
||||
__type: 'Pointer',
|
||||
className: targetClass,
|
||||
objectId,
|
||||
};
|
||||
return;
|
||||
}
|
||||
switch (fieldName) {
|
||||
case 'have':
|
||||
parentConstraints[parentFieldName].$inQuery = {
|
||||
where: fieldValue,
|
||||
className: targetClass,
|
||||
};
|
||||
transformQueryInputToParse(
|
||||
parentConstraints[parentFieldName].$inQuery.where,
|
||||
targetClass,
|
||||
parseClasses
|
||||
);
|
||||
break;
|
||||
case 'haveNot':
|
||||
parentConstraints[parentFieldName].$notInQuery = {
|
||||
where: fieldValue,
|
||||
className: targetClass,
|
||||
};
|
||||
transformQueryInputToParse(
|
||||
parentConstraints[parentFieldName].$notInQuery.where,
|
||||
targetClass,
|
||||
parseClasses
|
||||
);
|
||||
break;
|
||||
}
|
||||
delete constraints[fieldName];
|
||||
return;
|
||||
}
|
||||
switch (fieldName) {
|
||||
case '$point':
|
||||
@@ -170,20 +235,21 @@ const transformQueryConstraintInputToParse = (
|
||||
}
|
||||
if (typeof fieldValue === 'object') {
|
||||
if (fieldName === 'where') {
|
||||
transformQueryInputToParse(fieldValue);
|
||||
transformQueryInputToParse(fieldValue, className, parseClasses);
|
||||
} else {
|
||||
transformQueryConstraintInputToParse(
|
||||
fieldValue,
|
||||
fields,
|
||||
fieldName,
|
||||
constraints
|
||||
className,
|
||||
constraints,
|
||||
parseClasses
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const transformQueryInputToParse = (constraints, fields, className) => {
|
||||
const transformQueryInputToParse = (constraints, className, parseClasses) => {
|
||||
if (!constraints || typeof constraints !== 'object') {
|
||||
return;
|
||||
}
|
||||
@@ -195,42 +261,17 @@ const transformQueryInputToParse = (constraints, fields, className) => {
|
||||
delete constraints[fieldName];
|
||||
fieldName = parseQueryMap[fieldName];
|
||||
constraints[fieldName] = fieldValue;
|
||||
|
||||
if (fieldName !== 'objectId') {
|
||||
fieldValue.forEach(fieldValueItem => {
|
||||
transformQueryInputToParse(fieldValueItem, fields, className);
|
||||
});
|
||||
return;
|
||||
} else if (className) {
|
||||
Object.keys(fieldValue).forEach(constraintName => {
|
||||
const constraintValue = fieldValue[constraintName];
|
||||
if (typeof constraintValue === 'string') {
|
||||
const globalIdObject = fromGlobalId(constraintValue);
|
||||
|
||||
if (globalIdObject.type === className) {
|
||||
fieldValue[constraintName] = globalIdObject.id;
|
||||
}
|
||||
} else if (Array.isArray(constraintValue)) {
|
||||
fieldValue[constraintName] = constraintValue.map(value => {
|
||||
const globalIdObject = fromGlobalId(value);
|
||||
|
||||
if (globalIdObject.type === className) {
|
||||
return globalIdObject.id;
|
||||
}
|
||||
|
||||
return value;
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof fieldValue === 'object') {
|
||||
fieldValue.forEach(fieldValueItem => {
|
||||
transformQueryInputToParse(fieldValueItem, className, parseClasses);
|
||||
});
|
||||
return;
|
||||
} else {
|
||||
transformQueryConstraintInputToParse(
|
||||
fieldValue,
|
||||
fields,
|
||||
fieldName,
|
||||
constraints
|
||||
className,
|
||||
constraints,
|
||||
parseClasses
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user