GraphQL: Inline Fragment on Array Fields (#5908)
* Inline Fragment Spec * Inline Fragment on Arrays * Fix Test * Only select the root field * Requested Changes * Lazy Loaded ArrayResult
This commit is contained in:
committed by
Antonio Davi Macedo Coelho de Castro
parent
45dabbbcda
commit
4bffdce047
@@ -539,6 +539,19 @@ describe('ParseGraphQLServer', () => {
|
|||||||
expect(dateType.kind).toEqual('SCALAR');
|
expect(dateType.kind).toEqual('SCALAR');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should have ArrayResult type', async () => {
|
||||||
|
const arrayResultType = (await apolloClient.query({
|
||||||
|
query: gql`
|
||||||
|
query ArrayResultType {
|
||||||
|
__type(name: "ArrayResult") {
|
||||||
|
kind
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
})).data['__type'];
|
||||||
|
expect(arrayResultType.kind).toEqual('UNION');
|
||||||
|
});
|
||||||
|
|
||||||
it('should have File object type', async () => {
|
it('should have File object type', async () => {
|
||||||
const fileType = (await apolloClient.query({
|
const fileType = (await apolloClient.query({
|
||||||
query: gql`
|
query: gql`
|
||||||
@@ -746,6 +759,25 @@ describe('ParseGraphQLServer', () => {
|
|||||||
).toBeTruthy(JSON.stringify(schemaTypes));
|
).toBeTruthy(JSON.stringify(schemaTypes));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should ArrayResult contains all types', async () => {
|
||||||
|
const objectType = (await apolloClient.query({
|
||||||
|
query: gql`
|
||||||
|
query ObjectType {
|
||||||
|
__type(name: "ArrayResult") {
|
||||||
|
kind
|
||||||
|
possibleTypes {
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
})).data['__type'];
|
||||||
|
const possibleTypes = objectType.possibleTypes.map(o => o.name);
|
||||||
|
expect(possibleTypes).toContain('_UserClass');
|
||||||
|
expect(possibleTypes).toContain('_RoleClass');
|
||||||
|
expect(possibleTypes).toContain('Element');
|
||||||
|
});
|
||||||
|
|
||||||
it('should update schema when it changes', async () => {
|
it('should update schema when it changes', async () => {
|
||||||
const schemaController = await parseServer.config.databaseController.loadSchema();
|
const schemaController = await parseServer.config.databaseController.loadSchema();
|
||||||
await schemaController.updateClass('_User', {
|
await schemaController.updateClass('_User', {
|
||||||
@@ -1661,6 +1693,84 @@ describe('ParseGraphQLServer', () => {
|
|||||||
expect(new Date(result.updatedAt)).toEqual(obj.updatedAt);
|
expect(new Date(result.updatedAt)).toEqual(obj.updatedAt);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it_only_db('mongo')(
|
||||||
|
'should return child objects in array fields',
|
||||||
|
async () => {
|
||||||
|
const obj1 = new Parse.Object('Customer');
|
||||||
|
const obj2 = new Parse.Object('SomeClass');
|
||||||
|
const obj3 = new Parse.Object('Customer');
|
||||||
|
|
||||||
|
obj1.set('someCustomerField', 'imCustomerOne');
|
||||||
|
const arrayField = [42.42, 42, 'string', true];
|
||||||
|
obj1.set('arrayField', arrayField);
|
||||||
|
await obj1.save();
|
||||||
|
|
||||||
|
obj2.set('someClassField', 'imSomeClassTwo');
|
||||||
|
await obj2.save();
|
||||||
|
|
||||||
|
//const obj3Relation = obj3.relation('manyRelations')
|
||||||
|
obj3.set('manyRelations', [obj1, obj2]);
|
||||||
|
await obj3.save();
|
||||||
|
|
||||||
|
await parseGraphQLServer.parseGraphQLSchema.databaseController.schemaCache.clear();
|
||||||
|
|
||||||
|
const result = (await apolloClient.query({
|
||||||
|
query: gql`
|
||||||
|
query GetCustomer($objectId: ID!) {
|
||||||
|
objects {
|
||||||
|
getCustomer(objectId: $objectId) {
|
||||||
|
objectId
|
||||||
|
manyRelations {
|
||||||
|
... on CustomerClass {
|
||||||
|
objectId
|
||||||
|
someCustomerField
|
||||||
|
arrayField {
|
||||||
|
... on Element {
|
||||||
|
value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
... on SomeClassClass {
|
||||||
|
objectId
|
||||||
|
someClassField
|
||||||
|
}
|
||||||
|
}
|
||||||
|
createdAt
|
||||||
|
updatedAt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
variables: {
|
||||||
|
objectId: obj3.id,
|
||||||
|
},
|
||||||
|
})).data.objects.getCustomer;
|
||||||
|
|
||||||
|
expect(result.objectId).toEqual(obj3.id);
|
||||||
|
expect(result.manyRelations.length).toEqual(2);
|
||||||
|
|
||||||
|
const customerSubObject = result.manyRelations.find(
|
||||||
|
o => o.objectId === obj1.id
|
||||||
|
);
|
||||||
|
const someClassSubObject = result.manyRelations.find(
|
||||||
|
o => o.objectId === obj2.id
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(customerSubObject).toBeDefined();
|
||||||
|
expect(someClassSubObject).toBeDefined();
|
||||||
|
expect(customerSubObject.someCustomerField).toEqual(
|
||||||
|
'imCustomerOne'
|
||||||
|
);
|
||||||
|
const formatedArrayField = customerSubObject.arrayField.map(
|
||||||
|
elem => elem.value
|
||||||
|
);
|
||||||
|
expect(formatedArrayField).toEqual(arrayField);
|
||||||
|
expect(someClassSubObject.someClassField).toEqual(
|
||||||
|
'imSomeClassTwo'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
it('should respect level permissions', async () => {
|
it('should respect level permissions', async () => {
|
||||||
await prepareData();
|
await prepareData();
|
||||||
|
|
||||||
@@ -5609,7 +5719,11 @@ describe('ParseGraphQLServer', () => {
|
|||||||
findSomeClass(where: { someField: { _exists: true } }) {
|
findSomeClass(where: { someField: { _exists: true } }) {
|
||||||
results {
|
results {
|
||||||
objectId
|
objectId
|
||||||
someField
|
someField {
|
||||||
|
... on Element {
|
||||||
|
value
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ class ParseGraphQLSchema {
|
|||||||
parseClassMutations.load(this, parseClass, parseClassConfig);
|
parseClassMutations.load(this, parseClass, parseClassConfig);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
defaultGraphQLTypes.loadArrayResult(this, parseClasses);
|
||||||
defaultGraphQLQueries.load(this);
|
defaultGraphQLQueries.load(this);
|
||||||
defaultGraphQLMutations.load(this);
|
defaultGraphQLMutations.load(this);
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import {
|
|||||||
GraphQLList,
|
GraphQLList,
|
||||||
GraphQLInputObjectType,
|
GraphQLInputObjectType,
|
||||||
GraphQLBoolean,
|
GraphQLBoolean,
|
||||||
|
GraphQLUnionType,
|
||||||
} from 'graphql';
|
} from 'graphql';
|
||||||
import { GraphQLUpload } from 'graphql-upload';
|
import { GraphQLUpload } from 'graphql-upload';
|
||||||
|
|
||||||
@@ -1020,6 +1021,55 @@ const SIGN_UP_RESULT = new GraphQLObjectType({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const ELEMENT = new GraphQLObjectType({
|
||||||
|
name: 'Element',
|
||||||
|
description:
|
||||||
|
'The SignUpResult object type is used in the users sign up mutation to return the data of the recent created user.',
|
||||||
|
fields: {
|
||||||
|
value: {
|
||||||
|
description: 'Return the value of the element in the array',
|
||||||
|
type: new GraphQLNonNull(ANY),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Default static union type, we update types and resolveType function later
|
||||||
|
let ARRAY_RESULT;
|
||||||
|
|
||||||
|
const loadArrayResult = (parseGraphQLSchema, parseClasses) => {
|
||||||
|
const classTypes = parseClasses
|
||||||
|
.filter(parseClass =>
|
||||||
|
parseGraphQLSchema.parseClassTypes[parseClass.className]
|
||||||
|
.classGraphQLOutputType
|
||||||
|
? true
|
||||||
|
: false
|
||||||
|
)
|
||||||
|
.map(
|
||||||
|
parseClass =>
|
||||||
|
parseGraphQLSchema.parseClassTypes[parseClass.className]
|
||||||
|
.classGraphQLOutputType
|
||||||
|
);
|
||||||
|
ARRAY_RESULT = new GraphQLUnionType({
|
||||||
|
name: 'ArrayResult',
|
||||||
|
description:
|
||||||
|
'Use Inline Fragment on Array to get results: https://graphql.org/learn/queries/#inline-fragments',
|
||||||
|
types: () => [ELEMENT, ...classTypes],
|
||||||
|
resolveType: value => {
|
||||||
|
if (value.__type === 'Object' && value.className && value.objectId) {
|
||||||
|
if (parseGraphQLSchema.parseClassTypes[value.className]) {
|
||||||
|
return parseGraphQLSchema.parseClassTypes[value.className]
|
||||||
|
.classGraphQLOutputType;
|
||||||
|
} else {
|
||||||
|
return ELEMENT;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return ELEMENT;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
parseGraphQLSchema.graphQLTypes.push(ARRAY_RESULT);
|
||||||
|
};
|
||||||
|
|
||||||
const load = parseGraphQLSchema => {
|
const load = parseGraphQLSchema => {
|
||||||
parseGraphQLSchema.graphQLTypes.push(GraphQLUpload);
|
parseGraphQLSchema.graphQLTypes.push(GraphQLUpload);
|
||||||
parseGraphQLSchema.graphQLTypes.push(ANY);
|
parseGraphQLSchema.graphQLTypes.push(ANY);
|
||||||
@@ -1056,6 +1106,7 @@ const load = parseGraphQLSchema => {
|
|||||||
parseGraphQLSchema.graphQLTypes.push(POLYGON_CONSTRAINT);
|
parseGraphQLSchema.graphQLTypes.push(POLYGON_CONSTRAINT);
|
||||||
parseGraphQLSchema.graphQLTypes.push(FIND_RESULT);
|
parseGraphQLSchema.graphQLTypes.push(FIND_RESULT);
|
||||||
parseGraphQLSchema.graphQLTypes.push(SIGN_UP_RESULT);
|
parseGraphQLSchema.graphQLTypes.push(SIGN_UP_RESULT);
|
||||||
|
parseGraphQLSchema.graphQLTypes.push(ELEMENT);
|
||||||
};
|
};
|
||||||
|
|
||||||
export {
|
export {
|
||||||
@@ -1140,5 +1191,8 @@ export {
|
|||||||
POLYGON_CONSTRAINT,
|
POLYGON_CONSTRAINT,
|
||||||
FIND_RESULT,
|
FIND_RESULT,
|
||||||
SIGN_UP_RESULT,
|
SIGN_UP_RESULT,
|
||||||
|
ARRAY_RESULT,
|
||||||
|
ELEMENT,
|
||||||
load,
|
load,
|
||||||
|
loadArrayResult,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { GraphQLNonNull } from 'graphql';
|
import { GraphQLNonNull } from 'graphql';
|
||||||
import getFieldNames from 'graphql-list-fields';
|
import getFieldNames from 'graphql-list-fields';
|
||||||
import * as defaultGraphQLTypes from './defaultGraphQLTypes';
|
import * as defaultGraphQLTypes from './defaultGraphQLTypes';
|
||||||
import * as parseClassTypes from './parseClassTypes';
|
import { extractKeysAndInclude } from '../parseGraphQLUtils';
|
||||||
import * as objectsMutations from './objectsMutations';
|
import * as objectsMutations from './objectsMutations';
|
||||||
import * as objectsQueries from './objectsQueries';
|
import * as objectsQueries from './objectsQueries';
|
||||||
import { ParseGraphQLClassConfig } from '../../Controllers/ParseGraphQLController';
|
import { ParseGraphQLClassConfig } from '../../Controllers/ParseGraphQLController';
|
||||||
@@ -119,9 +119,7 @@ const load = function(
|
|||||||
info
|
info
|
||||||
);
|
);
|
||||||
const selectedFields = getFieldNames(mutationInfo);
|
const selectedFields = getFieldNames(mutationInfo);
|
||||||
const { keys, include } = parseClassTypes.extractKeysAndInclude(
|
const { keys, include } = extractKeysAndInclude(selectedFields);
|
||||||
selectedFields
|
|
||||||
);
|
|
||||||
const { keys: requiredKeys, needGet } = getOnlyRequiredFields(
|
const { keys: requiredKeys, needGet } = getOnlyRequiredFields(
|
||||||
fields,
|
fields,
|
||||||
keys,
|
keys,
|
||||||
@@ -180,9 +178,7 @@ const load = function(
|
|||||||
info
|
info
|
||||||
);
|
);
|
||||||
const selectedFields = getFieldNames(mutationInfo);
|
const selectedFields = getFieldNames(mutationInfo);
|
||||||
const { keys, include } = parseClassTypes.extractKeysAndInclude(
|
const { keys, include } = extractKeysAndInclude(selectedFields);
|
||||||
selectedFields
|
|
||||||
);
|
|
||||||
|
|
||||||
const { keys: requiredKeys, needGet } = getOnlyRequiredFields(
|
const { keys: requiredKeys, needGet } = getOnlyRequiredFields(
|
||||||
fields,
|
fields,
|
||||||
@@ -225,9 +221,7 @@ const load = function(
|
|||||||
const { objectId } = args;
|
const { objectId } = args;
|
||||||
const { config, auth, info } = context;
|
const { config, auth, info } = context;
|
||||||
const selectedFields = getFieldNames(mutationInfo);
|
const selectedFields = getFieldNames(mutationInfo);
|
||||||
const { keys, include } = parseClassTypes.extractKeysAndInclude(
|
const { keys, include } = extractKeysAndInclude(selectedFields);
|
||||||
selectedFields
|
|
||||||
);
|
|
||||||
|
|
||||||
let optimizedObject = {};
|
let optimizedObject = {};
|
||||||
const splitedKeys = keys.split(',');
|
const splitedKeys = keys.split(',');
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ import { GraphQLNonNull } from 'graphql';
|
|||||||
import getFieldNames from 'graphql-list-fields';
|
import getFieldNames from 'graphql-list-fields';
|
||||||
import * as defaultGraphQLTypes from './defaultGraphQLTypes';
|
import * as defaultGraphQLTypes from './defaultGraphQLTypes';
|
||||||
import * as objectsQueries from './objectsQueries';
|
import * as objectsQueries from './objectsQueries';
|
||||||
import * as parseClassTypes from './parseClassTypes';
|
|
||||||
import { ParseGraphQLClassConfig } from '../../Controllers/ParseGraphQLController';
|
import { ParseGraphQLClassConfig } from '../../Controllers/ParseGraphQLController';
|
||||||
|
import { extractKeysAndInclude } from '../parseGraphQLUtils';
|
||||||
|
|
||||||
const getParseClassQueryConfig = function(
|
const getParseClassQueryConfig = function(
|
||||||
parseClassConfig: ?ParseGraphQLClassConfig
|
parseClassConfig: ?ParseGraphQLClassConfig
|
||||||
@@ -11,6 +11,26 @@ const getParseClassQueryConfig = function(
|
|||||||
return (parseClassConfig && parseClassConfig.query) || {};
|
return (parseClassConfig && parseClassConfig.query) || {};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getQuery = async (className, _source, args, context, queryInfo) => {
|
||||||
|
const { objectId, readPreference, includeReadPreference } = args;
|
||||||
|
const { config, auth, info } = context;
|
||||||
|
const selectedFields = getFieldNames(queryInfo);
|
||||||
|
|
||||||
|
const { keys, include } = extractKeysAndInclude(selectedFields);
|
||||||
|
|
||||||
|
return await objectsQueries.getObject(
|
||||||
|
className,
|
||||||
|
objectId,
|
||||||
|
keys,
|
||||||
|
include,
|
||||||
|
readPreference,
|
||||||
|
includeReadPreference,
|
||||||
|
config,
|
||||||
|
auth,
|
||||||
|
info
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const load = function(
|
const load = function(
|
||||||
parseGraphQLSchema,
|
parseGraphQLSchema,
|
||||||
parseClass,
|
parseClass,
|
||||||
@@ -40,25 +60,7 @@ const load = function(
|
|||||||
type: new GraphQLNonNull(classGraphQLOutputType),
|
type: new GraphQLNonNull(classGraphQLOutputType),
|
||||||
async resolve(_source, args, context, queryInfo) {
|
async resolve(_source, args, context, queryInfo) {
|
||||||
try {
|
try {
|
||||||
const { objectId, readPreference, includeReadPreference } = args;
|
return await getQuery(className, _source, args, context, queryInfo);
|
||||||
const { config, auth, info } = context;
|
|
||||||
const selectedFields = getFieldNames(queryInfo);
|
|
||||||
|
|
||||||
const { keys, include } = parseClassTypes.extractKeysAndInclude(
|
|
||||||
selectedFields
|
|
||||||
);
|
|
||||||
|
|
||||||
return await objectsQueries.getObject(
|
|
||||||
className,
|
|
||||||
objectId,
|
|
||||||
keys,
|
|
||||||
include,
|
|
||||||
readPreference,
|
|
||||||
includeReadPreference,
|
|
||||||
config,
|
|
||||||
auth,
|
|
||||||
info
|
|
||||||
);
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
parseGraphQLSchema.handleError(e);
|
parseGraphQLSchema.handleError(e);
|
||||||
}
|
}
|
||||||
@@ -86,7 +88,7 @@ const load = function(
|
|||||||
const { config, auth, info } = context;
|
const { config, auth, info } = context;
|
||||||
const selectedFields = getFieldNames(queryInfo);
|
const selectedFields = getFieldNames(queryInfo);
|
||||||
|
|
||||||
const { keys, include } = parseClassTypes.extractKeysAndInclude(
|
const { keys, include } = extractKeysAndInclude(
|
||||||
selectedFields
|
selectedFields
|
||||||
.filter(field => field.includes('.'))
|
.filter(field => field.includes('.'))
|
||||||
.map(field => field.slice(field.indexOf('.') + 1))
|
.map(field => field.slice(field.indexOf('.') + 1))
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import getFieldNames from 'graphql-list-fields';
|
|||||||
import * as defaultGraphQLTypes from './defaultGraphQLTypes';
|
import * as defaultGraphQLTypes from './defaultGraphQLTypes';
|
||||||
import * as objectsQueries from './objectsQueries';
|
import * as objectsQueries from './objectsQueries';
|
||||||
import { ParseGraphQLClassConfig } from '../../Controllers/ParseGraphQLController';
|
import { ParseGraphQLClassConfig } from '../../Controllers/ParseGraphQLController';
|
||||||
|
import { extractKeysAndInclude } from '../parseGraphQLUtils';
|
||||||
|
|
||||||
const mapInputType = (parseType, targetClass, parseClassTypes) => {
|
const mapInputType = (parseType, targetClass, parseClassTypes) => {
|
||||||
switch (parseType) {
|
switch (parseType) {
|
||||||
@@ -65,7 +66,7 @@ const mapOutputType = (parseType, targetClass, parseClassTypes) => {
|
|||||||
case 'Boolean':
|
case 'Boolean':
|
||||||
return GraphQLBoolean;
|
return GraphQLBoolean;
|
||||||
case 'Array':
|
case 'Array':
|
||||||
return new GraphQLList(defaultGraphQLTypes.ANY);
|
return new GraphQLList(defaultGraphQLTypes.ARRAY_RESULT);
|
||||||
case 'Object':
|
case 'Object':
|
||||||
return defaultGraphQLTypes.OBJECT;
|
return defaultGraphQLTypes.OBJECT;
|
||||||
case 'Date':
|
case 'Date':
|
||||||
@@ -135,33 +136,6 @@ const mapConstraintType = (parseType, targetClass, parseClassTypes) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const extractKeysAndInclude = selectedFields => {
|
|
||||||
selectedFields = selectedFields.filter(
|
|
||||||
field => !field.includes('__typename')
|
|
||||||
);
|
|
||||||
let keys = undefined;
|
|
||||||
let include = undefined;
|
|
||||||
if (selectedFields && 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(',');
|
|
||||||
}
|
|
||||||
return { keys, include };
|
|
||||||
};
|
|
||||||
|
|
||||||
const getParseClassTypeConfig = function(
|
const getParseClassTypeConfig = function(
|
||||||
parseClassConfig: ?ParseGraphQLClassConfig
|
parseClassConfig: ?ParseGraphQLClassConfig
|
||||||
) {
|
) {
|
||||||
@@ -626,6 +600,27 @@ const load = (
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
} else if (parseClass.fields[field].type === 'Array') {
|
||||||
|
return {
|
||||||
|
...fields,
|
||||||
|
[field]: {
|
||||||
|
description: `Use Inline Fragment on Array to get results: https://graphql.org/learn/queries/#inline-fragments`,
|
||||||
|
type,
|
||||||
|
async resolve(source) {
|
||||||
|
return source[field].map(async elem => {
|
||||||
|
if (
|
||||||
|
elem.className &&
|
||||||
|
elem.objectId &&
|
||||||
|
elem.__type === 'Object'
|
||||||
|
) {
|
||||||
|
return elem;
|
||||||
|
} else {
|
||||||
|
return { value: elem };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
} else if (type) {
|
} else if (type) {
|
||||||
return {
|
return {
|
||||||
...fields,
|
...fields,
|
||||||
|
|||||||
@@ -12,3 +12,30 @@ export function toGraphQLError(error) {
|
|||||||
}
|
}
|
||||||
return new ApolloError(message, code);
|
return new ApolloError(message, code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const extractKeysAndInclude = selectedFields => {
|
||||||
|
selectedFields = selectedFields.filter(
|
||||||
|
field => !field.includes('__typename')
|
||||||
|
);
|
||||||
|
let keys = undefined;
|
||||||
|
let include = undefined;
|
||||||
|
if (selectedFields && 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(',');
|
||||||
|
}
|
||||||
|
return { keys, include };
|
||||||
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user