Files
kami-parse-server/src/GraphQL/transformers/mutation.js

185 lines
5.0 KiB
JavaScript
Raw Normal View History

import * as defaultGraphQLTypes from '../loaders/defaultGraphQLTypes';
GraphQL schema operations (#5993) * Remove nested operations * Improve error log * Fix bug schema to load * Fix ParseGraphQLSchema tests * Fix tests * Fix failing tests * First verstion not complete of create class mutation * Fix bug caused by circular dependency * Renaming files * Schema types should be loaded before parse classes * Fix tests * Create class mutation boilerplate * Improve CreateClassSchemaInput fields names * Remove fields * Pointer and relation fields * Improve pointer default type * Class type * Create class mutation resolver * Schema field transformers * Class types transformations * First test * Numbers test * Boolean tests * Date test * Fix some get tests * Test for created at and updated at * File tests * Test for objects * Renaming reducerFabric to reducerGenerator * Changing get tests for file and object * Object composed queries test * Array test * Null field test * Bytes test * Geo Point test * Polygons tests * Remove create generic mutation * Fix tests * Create class test - isRequired and defaultValue will be added back later * Enforce master key * Fix tests * Duplicated field test * updateClass mutation * Remove update generic mutation tests * Remove update generic mutation * deleteClass mutation * Remove delete generic mutation tests * Remove delete generic mutation * class query * Classes query * Remove get generic query from tests * Remove remaining generic operations and fix tests * Fix last test * Try to fix redis tests * Fix postgres tests * Update objectsMutations and objectsQueries files locations * Rename classSchema files to schema files * Rename ClassObject to ParseObject * Fix names and paths * Still some wrong names
2019-09-01 22:11:03 -07:00
import * as objectsMutations from '../helpers/objectsMutations';
const transformTypes = async (
inputType: 'create' | 'update',
fields,
{ className, parseGraphQLSchema, req }
) => {
const {
classGraphQLCreateType,
classGraphQLUpdateType,
config: { isCreateEnabled, isUpdateEnabled },
} = parseGraphQLSchema.parseClassTypes[className];
const parseClass = parseGraphQLSchema.parseClasses.find(
clazz => clazz.className === className
);
if (fields) {
const classGraphQLCreateTypeFields =
isCreateEnabled && classGraphQLCreateType
? classGraphQLCreateType.getFields()
: null;
const classGraphQLUpdateTypeFields =
isUpdateEnabled && classGraphQLUpdateType
? classGraphQLUpdateType.getFields()
: null;
const promises = Object.keys(fields).map(async field => {
let inputTypeField;
if (inputType === 'create' && classGraphQLCreateTypeFields) {
inputTypeField = classGraphQLCreateTypeFields[field];
} else if (classGraphQLUpdateTypeFields) {
inputTypeField = classGraphQLUpdateTypeFields[field];
}
if (inputTypeField) {
switch (true) {
case inputTypeField.type === defaultGraphQLTypes.GEO_POINT_INPUT:
fields[field] = transformers.geoPoint(fields[field]);
break;
case inputTypeField.type === defaultGraphQLTypes.POLYGON_INPUT:
fields[field] = transformers.polygon(fields[field]);
break;
case parseClass.fields[field].type === 'Relation':
fields[field] = await transformers.relation(
parseClass.fields[field].targetClass,
field,
fields[field],
parseGraphQLSchema,
req
);
break;
case parseClass.fields[field].type === 'Pointer':
fields[field] = await transformers.pointer(
parseClass.fields[field].targetClass,
field,
fields[field],
parseGraphQLSchema,
req
);
break;
}
}
});
await Promise.all(promises);
}
return fields;
};
const transformers = {
polygon: value => ({
__type: 'Polygon',
coordinates: value.map(geoPoint => [geoPoint.latitude, geoPoint.longitude]),
}),
geoPoint: value => ({
...value,
__type: 'GeoPoint',
}),
relation: async (
targetClass,
field,
value,
parseGraphQLSchema,
{ 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}`
);
const op = {
__op: 'Batch',
ops: [],
};
let nestedObjectsToAdd = [];
if (value.createAndAdd) {
nestedObjectsToAdd = (await Promise.all(
value.createAndAdd.map(async input => {
const parseFields = await transformTypes('create', input, {
className: targetClass,
parseGraphQLSchema,
req: { config, auth, info },
});
return objectsMutations.createObject(
targetClass,
parseFields,
config,
auth,
info
);
})
)).map(object => ({
__type: 'Pointer',
className: targetClass,
objectId: object.objectId,
}));
}
if (value.add || nestedObjectsToAdd.length > 0) {
if (!value.add) value.add = [];
value.add = value.add.map(input => ({
__type: 'Pointer',
className: targetClass,
objectId: input,
}));
op.ops.push({
__op: 'AddRelation',
objects: [...value.add, ...nestedObjectsToAdd],
});
}
if (value.remove) {
op.ops.push({
__op: 'RemoveRelation',
objects: value.remove.map(input => ({
__type: 'Pointer',
className: targetClass,
objectId: input,
})),
});
}
return op;
},
pointer: async (
targetClass,
field,
value,
parseGraphQLSchema,
{ config, auth, info }
) => {
if (Object.keys(value) > 1 || Object.keys(value) === 0)
throw new Error(
`You need to provide link OR createLink on the pointer mutation of field ${field}`
);
let nestedObjectToAdd;
if (value.createAndLink) {
const parseFields = await transformTypes('create', value.createAndLink, {
className: targetClass,
parseGraphQLSchema,
req: { config, auth, info },
});
nestedObjectToAdd = await objectsMutations.createObject(
targetClass,
parseFields,
config,
auth,
info
);
return {
__type: 'Pointer',
className: targetClass,
objectId: nestedObjectToAdd.objectId,
};
}
if (value.link) {
return {
__type: 'Pointer',
className: targetClass,
objectId: value.link,
};
}
},
};
export { transformTypes };