Relay Spec (#6089)
* Install graphql-relay * Add relayNodeInterface to ParseGraphQLSchema * Add support to global id * Add support to global id in other operations * Fix sort by glboal id * Fix where by global id * Introduce IdWhereInput * Add Relay object identification tests * Client mutation id on createFile mutation * Client mutation id on callCloudCode mutation * Client mutation id on signUp mutation * Client mutation id on logIn mutation * Client mutation id on logOut mutation * Client mutation id on createClass mutation * Client mutation id on updateClass mutation * Client mutation id on deleteClass mutation * Client mutation id on create object mutation * Improve Viewer type * Client mutation id on update object mutation * Client mutation id on delete object mutation * Introducing connections * Fix tests * Add pagination test * Fix file location * Fix postgres tests * Add comments * Tests to calculateSkipAndLimit
This commit is contained in:
committed by
GitHub
parent
67e3c33ffe
commit
a9066e20dc
@@ -3,8 +3,13 @@ import * as defaultGraphQLTypes from '../loaders/defaultGraphQLTypes';
|
||||
const transformConstraintTypeToGraphQL = (
|
||||
parseType,
|
||||
targetClass,
|
||||
parseClassTypes
|
||||
parseClassTypes,
|
||||
fieldName
|
||||
) => {
|
||||
if (fieldName === 'id' || fieldName === 'objectId') {
|
||||
return defaultGraphQLTypes.ID_WHERE_INPUT;
|
||||
}
|
||||
|
||||
switch (parseType) {
|
||||
case 'String':
|
||||
return defaultGraphQLTypes.STRING_WHERE_INPUT;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import Parse from 'parse/node';
|
||||
import { fromGlobalId } from 'graphql-relay';
|
||||
import * as defaultGraphQLTypes from '../loaders/defaultGraphQLTypes';
|
||||
import * as objectsMutations from '../helpers/objectsMutations';
|
||||
|
||||
@@ -108,8 +110,9 @@ const transformers = {
|
||||
{ config, auth, info }
|
||||
) => {
|
||||
if (Object.keys(value) === 0)
|
||||
throw new Error(
|
||||
`You need to provide atleast one operation on the relation mutation of field ${field}`
|
||||
throw new Parse.Error(
|
||||
Parse.Error.INVALID_POINTER,
|
||||
`You need to provide at least one operation on the relation mutation of field ${field}`
|
||||
);
|
||||
|
||||
const op = {
|
||||
@@ -143,11 +146,17 @@ const transformers = {
|
||||
|
||||
if (value.add || nestedObjectsToAdd.length > 0) {
|
||||
if (!value.add) value.add = [];
|
||||
value.add = value.add.map(input => ({
|
||||
__type: 'Pointer',
|
||||
className: targetClass,
|
||||
objectId: input,
|
||||
}));
|
||||
value.add = value.add.map(input => {
|
||||
const globalIdObject = fromGlobalId(input);
|
||||
if (globalIdObject.type === targetClass) {
|
||||
input = globalIdObject.id;
|
||||
}
|
||||
return {
|
||||
__type: 'Pointer',
|
||||
className: targetClass,
|
||||
objectId: input,
|
||||
};
|
||||
});
|
||||
op.ops.push({
|
||||
__op: 'AddRelation',
|
||||
objects: [...value.add, ...nestedObjectsToAdd],
|
||||
@@ -157,11 +166,17 @@ const transformers = {
|
||||
if (value.remove) {
|
||||
op.ops.push({
|
||||
__op: 'RemoveRelation',
|
||||
objects: value.remove.map(input => ({
|
||||
__type: 'Pointer',
|
||||
className: targetClass,
|
||||
objectId: input,
|
||||
})),
|
||||
objects: value.remove.map(input => {
|
||||
const globalIdObject = fromGlobalId(input);
|
||||
if (globalIdObject.type === targetClass) {
|
||||
input = globalIdObject.id;
|
||||
}
|
||||
return {
|
||||
__type: 'Pointer',
|
||||
className: targetClass,
|
||||
objectId: input,
|
||||
};
|
||||
}),
|
||||
});
|
||||
}
|
||||
return op;
|
||||
@@ -174,7 +189,8 @@ const transformers = {
|
||||
{ config, auth, info }
|
||||
) => {
|
||||
if (Object.keys(value) > 1 || Object.keys(value) === 0)
|
||||
throw new Error(
|
||||
throw new Parse.Error(
|
||||
Parse.Error.INVALID_POINTER,
|
||||
`You need to provide link OR createLink on the pointer mutation of field ${field}`
|
||||
);
|
||||
|
||||
@@ -199,10 +215,15 @@ const transformers = {
|
||||
};
|
||||
}
|
||||
if (value.link) {
|
||||
let objectId = value.link;
|
||||
const globalIdObject = fromGlobalId(objectId);
|
||||
if (globalIdObject.type === targetClass) {
|
||||
objectId = globalIdObject.id;
|
||||
}
|
||||
return {
|
||||
__type: 'Pointer',
|
||||
className: targetClass,
|
||||
objectId: value.link,
|
||||
objectId,
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
@@ -45,7 +45,7 @@ const transformOutputTypeToGraphQL = (
|
||||
parseClassTypes[targetClass].classGraphQLFindResultType
|
||||
);
|
||||
} else {
|
||||
return new GraphQLNonNull(defaultGraphQLTypes.FIND_RESULT);
|
||||
return new GraphQLNonNull(defaultGraphQLTypes.OBJECT);
|
||||
}
|
||||
case 'File':
|
||||
return defaultGraphQLTypes.FILE_INFO;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { fromGlobalId } from 'graphql-relay';
|
||||
|
||||
const parseQueryMap = {
|
||||
id: 'objectId',
|
||||
OR: '$or',
|
||||
@@ -102,10 +104,15 @@ const transformQueryConstraintInputToParse = (
|
||||
typeof fieldValue === 'string'
|
||||
) {
|
||||
const { targetClass } = fields[parentFieldName];
|
||||
let objectId = fieldValue;
|
||||
const globalIdObject = fromGlobalId(objectId);
|
||||
if (globalIdObject.type === targetClass) {
|
||||
objectId = globalIdObject.id;
|
||||
}
|
||||
constraints[fieldName] = {
|
||||
__type: 'Pointer',
|
||||
className: targetClass,
|
||||
objectId: fieldValue,
|
||||
objectId,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -176,7 +183,7 @@ const transformQueryConstraintInputToParse = (
|
||||
});
|
||||
};
|
||||
|
||||
const transformQueryInputToParse = (constraints, fields) => {
|
||||
const transformQueryInputToParse = (constraints, fields, className) => {
|
||||
if (!constraints || typeof constraints !== 'object') {
|
||||
return;
|
||||
}
|
||||
@@ -191,9 +198,30 @@ const transformQueryInputToParse = (constraints, fields) => {
|
||||
|
||||
if (fieldName !== 'objectId') {
|
||||
fieldValue.forEach(fieldValueItem => {
|
||||
transformQueryInputToParse(fieldValueItem, fields);
|
||||
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;
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user