GraphQL: Optimize queries, fixes some null returns (on object), fix stitched GraphQLUpload (#6709)

* Optimize query, fixes some null returns, fix stitched GraphQLUpload

* Fix authData key selection

* Prefer Iso string since other GraphQL solutions use this format

* fix tests

Co-authored-by: Antonio Davi Macedo Coelho de Castro <adavimacedo@gmail.com>
This commit is contained in:
Antoine Cormouls
2020-10-02 00:19:26 +02:00
committed by GitHub
parent 929c4e1b0d
commit 62048260c9
32 changed files with 1533 additions and 1161 deletions

View File

@@ -5,8 +5,16 @@ const createObject = async (className, fields, config, auth, info) => {
fields = {};
}
return (await rest.create(config, auth, className, fields, info.clientSDK, info.context))
.response;
return (
await rest.create(
config,
auth,
className,
fields,
info.clientSDK,
info.context
)
).response;
};
const updateObject = async (
@@ -21,15 +29,17 @@ const updateObject = async (
fields = {};
}
return (await rest.update(
config,
auth,
className,
{ objectId },
fields,
info.clientSDK,
info.context
)).response;
return (
await rest.update(
config,
auth,
className,
{ objectId },
fields,
info.clientSDK,
info.context
)
).response;
};
const deleteObject = async (className, objectId, config, auth, info) => {

View File

@@ -7,7 +7,7 @@ import { transformQueryInputToParse } from '../transformers/query';
/* eslint-disable*/
const needToGetAllKeys = (fields, keys, parseClasses) =>
keys
? keys.split(',').some((keyName) => {
? keys.split(',').some(keyName => {
const key = keyName.split('.');
if (fields[key[0]]) {
if (fields[key[0]].type === 'Pointer') {
@@ -19,7 +19,11 @@ const needToGetAllKeys = (fields, keys, parseClasses) =>
// Current sub key is not custom
return false;
}
} else if (!key[1]) {
} else if (
!key[1] ||
fields[key[0]].type === 'Array' ||
fields[key[0]].type === 'Object'
) {
// current key is not custom
return false;
}
@@ -156,7 +160,7 @@ const findObjects = async (
if (
selectedFields.find(
(field) => field.startsWith('edges.') || field.startsWith('pageInfo.')
field => field.startsWith('edges.') || field.startsWith('pageInfo.')
)
) {
if (limit || limit === 0) {

View File

@@ -15,7 +15,7 @@ import {
GraphQLUnionType,
} from 'graphql';
import { toGlobalId } from 'graphql-relay';
import { GraphQLUpload } from 'graphql-upload';
import { GraphQLUpload } from '@graphql-tools/links';
class TypeValidationError extends Error {
constructor(value, type) {
@@ -162,7 +162,7 @@ const serializeDateIso = (value) => {
return value;
}
if (value instanceof Date) {
return value.toUTCString();
return value.toISOString();
}
throw new TypeValidationError(value, 'Date');

View File

@@ -1,6 +1,6 @@
import { GraphQLNonNull } from 'graphql';
import { mutationWithClientMutationId } from 'graphql-relay';
import { GraphQLUpload } from 'graphql-upload';
import { GraphQLUpload } from '@graphql-tools/links';
import Parse from 'parse/node';
import * as defaultGraphQLTypes from './defaultGraphQLTypes';
import logger from '../../logger';
@@ -14,7 +14,7 @@ const handleUpload = async (upload, config) => {
const chunks = [];
stream
.on('error', reject)
.on('data', chunk => chunks.push(chunk))
.on('data', (chunk) => chunks.push(chunk))
.on('end', () => resolve(Buffer.concat(chunks)));
});
}
@@ -52,7 +52,7 @@ const handleUpload = async (upload, config) => {
}
};
const load = parseGraphQLSchema => {
const load = (parseGraphQLSchema) => {
const createMutation = mutationWithClientMutationId({
name: 'CreateFile',
description:

View File

@@ -22,13 +22,12 @@ export function toGraphQLError(error) {
return new ApolloError(message, code);
}
export const extractKeysAndInclude = selectedFields => {
export const extractKeysAndInclude = (selectedFields) => {
selectedFields = selectedFields.filter(
field => !field.includes('__typename')
(field) => !field.includes('__typename')
);
// Handles "id" field for both current and included objects
selectedFields = selectedFields.map(field => {
selectedFields = selectedFields.map((field) => {
if (field === 'id') return 'objectId';
return field.endsWith('.id')
? `${field.substring(0, field.lastIndexOf('.id'))}.objectId`
@@ -36,25 +35,21 @@ export const extractKeysAndInclude = selectedFields => {
});
let keys = undefined;
let include = undefined;
if (selectedFields.length > 0) {
keys = selectedFields.join(',');
include = selectedFields
.reduce((fields, field) => {
fields = fields.slice();
let pointIndex = field.lastIndexOf('.');
while (pointIndex > 0) {
const lastField = field.slice(pointIndex + 1);
field = field.slice(0, pointIndex);
if (!fields.includes(field) && lastField !== 'objectId') {
fields.push(field);
}
pointIndex = field.lastIndexOf('.');
}
return fields;
}, [])
.join(',');
keys = [...new Set(selectedFields)].join(',');
// We can use this shortcut since optimization is handled
// later on RestQuery, avoid overhead here.
include = keys;
}
return { keys, include };
return {
// If authData is detected keys will not work properly
// since authData has a special storage behavior
// so we need to skip keys currently
keys: keys && keys.indexOf('authData') === -1 ? keys : undefined,
include,
};
};
export const getParseClassMutationConfig = function (parseClassConfig) {