Remove nested operations from GraphQL API (#5931)
* Remove nested operations * Improve error log * Fix bug schema to load * Fix ParseGraphQLSchema tests * Fix tests * Fix failing tests * Rename call to callCloudCode
This commit is contained in:
committed by
Antoine Cormouls
parent
47d1a74ac0
commit
ee5aeeaff5
@@ -211,7 +211,7 @@ describe('ParseGraphQLSchema', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('addGraphQLObjectQuery', () => {
|
describe('addGraphQLQuery', () => {
|
||||||
it('should not load and warn duplicated queries', async () => {
|
it('should not load and warn duplicated queries', async () => {
|
||||||
let logged = false;
|
let logged = false;
|
||||||
const parseGraphQLSchema = new ParseGraphQLSchema({
|
const parseGraphQLSchema = new ParseGraphQLSchema({
|
||||||
@@ -221,21 +221,19 @@ describe('ParseGraphQLSchema', () => {
|
|||||||
warn: message => {
|
warn: message => {
|
||||||
logged = true;
|
logged = true;
|
||||||
expect(message).toEqual(
|
expect(message).toEqual(
|
||||||
'Object query someClasses could not be added to the auto schema because it collided with an existing field.'
|
'Query someClasses could not be added to the auto schema because it collided with an existing field.'
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
await parseGraphQLSchema.load();
|
await parseGraphQLSchema.load();
|
||||||
const field = {};
|
const field = {};
|
||||||
expect(
|
expect(parseGraphQLSchema.addGraphQLQuery('someClasses', field)).toBe(
|
||||||
parseGraphQLSchema.addGraphQLObjectQuery('someClasses', field)
|
|
||||||
).toBe(field);
|
|
||||||
expect(parseGraphQLSchema.graphQLObjectsQueries['someClasses']).toBe(
|
|
||||||
field
|
field
|
||||||
);
|
);
|
||||||
|
expect(parseGraphQLSchema.graphQLQueries['someClasses']).toBe(field);
|
||||||
expect(
|
expect(
|
||||||
parseGraphQLSchema.addGraphQLObjectQuery('someClasses', {})
|
parseGraphQLSchema.addGraphQLQuery('someClasses', {})
|
||||||
).toBeUndefined();
|
).toBeUndefined();
|
||||||
expect(logged).toBeTruthy();
|
expect(logged).toBeTruthy();
|
||||||
});
|
});
|
||||||
@@ -252,16 +250,14 @@ describe('ParseGraphQLSchema', () => {
|
|||||||
});
|
});
|
||||||
await parseGraphQLSchema.load();
|
await parseGraphQLSchema.load();
|
||||||
const field = {};
|
const field = {};
|
||||||
expect(
|
expect(parseGraphQLSchema.addGraphQLQuery('someClasses', field)).toBe(
|
||||||
parseGraphQLSchema.addGraphQLObjectQuery('someClasses', field)
|
|
||||||
).toBe(field);
|
|
||||||
expect(parseGraphQLSchema.graphQLObjectsQueries['someClasses']).toBe(
|
|
||||||
field
|
field
|
||||||
);
|
);
|
||||||
|
expect(parseGraphQLSchema.graphQLQueries['someClasses']).toBe(field);
|
||||||
expect(() =>
|
expect(() =>
|
||||||
parseGraphQLSchema.addGraphQLObjectQuery('someClasses', {}, true)
|
parseGraphQLSchema.addGraphQLQuery('someClasses', {}, true)
|
||||||
).toThrowError(
|
).toThrowError(
|
||||||
'Object query someClasses could not be added to the auto schema because it collided with an existing field.'
|
'Query someClasses could not be added to the auto schema because it collided with an existing field.'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -274,15 +270,13 @@ describe('ParseGraphQLSchema', () => {
|
|||||||
warn: message => {
|
warn: message => {
|
||||||
logged = true;
|
logged = true;
|
||||||
expect(message).toEqual(
|
expect(message).toEqual(
|
||||||
'Object query get could not be added to the auto schema because it collided with an existing field.'
|
'Query get could not be added to the auto schema because it collided with an existing field.'
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
await parseGraphQLSchema.load();
|
await parseGraphQLSchema.load();
|
||||||
expect(
|
expect(parseGraphQLSchema.addGraphQLQuery('get', {})).toBeUndefined();
|
||||||
parseGraphQLSchema.addGraphQLObjectQuery('get', {})
|
|
||||||
).toBeUndefined();
|
|
||||||
expect(logged).toBeTruthy();
|
expect(logged).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -297,16 +291,16 @@ describe('ParseGraphQLSchema', () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
await parseGraphQLSchema.load();
|
await parseGraphQLSchema.load();
|
||||||
delete parseGraphQLSchema.graphQLObjectsQueries.get;
|
delete parseGraphQLSchema.graphQLQueries.get;
|
||||||
const field = {};
|
const field = {};
|
||||||
expect(
|
expect(parseGraphQLSchema.addGraphQLQuery('get', field, true, true)).toBe(
|
||||||
parseGraphQLSchema.addGraphQLObjectQuery('get', field, true, true)
|
field
|
||||||
).toBe(field);
|
);
|
||||||
expect(parseGraphQLSchema.graphQLObjectsQueries['get']).toBe(field);
|
expect(parseGraphQLSchema.graphQLQueries['get']).toBe(field);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('addGraphQLObjectMutation', () => {
|
describe('addGraphQLMutation', () => {
|
||||||
it('should not load and warn duplicated mutations', async () => {
|
it('should not load and warn duplicated mutations', async () => {
|
||||||
let logged = false;
|
let logged = false;
|
||||||
const parseGraphQLSchema = new ParseGraphQLSchema({
|
const parseGraphQLSchema = new ParseGraphQLSchema({
|
||||||
@@ -316,7 +310,7 @@ describe('ParseGraphQLSchema', () => {
|
|||||||
warn: message => {
|
warn: message => {
|
||||||
logged = true;
|
logged = true;
|
||||||
expect(message).toEqual(
|
expect(message).toEqual(
|
||||||
'Object mutation createSomeClass could not be added to the auto schema because it collided with an existing field.'
|
'Mutation createSomeClass could not be added to the auto schema because it collided with an existing field.'
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -324,13 +318,13 @@ describe('ParseGraphQLSchema', () => {
|
|||||||
await parseGraphQLSchema.load();
|
await parseGraphQLSchema.load();
|
||||||
const field = {};
|
const field = {};
|
||||||
expect(
|
expect(
|
||||||
parseGraphQLSchema.addGraphQLObjectMutation('createSomeClass', field)
|
parseGraphQLSchema.addGraphQLMutation('createSomeClass', field)
|
||||||
).toBe(field);
|
).toBe(field);
|
||||||
|
expect(parseGraphQLSchema.graphQLMutations['createSomeClass']).toBe(
|
||||||
|
field
|
||||||
|
);
|
||||||
expect(
|
expect(
|
||||||
parseGraphQLSchema.graphQLObjectsMutations['createSomeClass']
|
parseGraphQLSchema.addGraphQLMutation('createSomeClass', {})
|
||||||
).toBe(field);
|
|
||||||
expect(
|
|
||||||
parseGraphQLSchema.addGraphQLObjectMutation('createSomeClass', {})
|
|
||||||
).toBeUndefined();
|
).toBeUndefined();
|
||||||
expect(logged).toBeTruthy();
|
expect(logged).toBeTruthy();
|
||||||
});
|
});
|
||||||
@@ -348,15 +342,15 @@ describe('ParseGraphQLSchema', () => {
|
|||||||
await parseGraphQLSchema.load();
|
await parseGraphQLSchema.load();
|
||||||
const field = {};
|
const field = {};
|
||||||
expect(
|
expect(
|
||||||
parseGraphQLSchema.addGraphQLObjectMutation('createSomeClass', field)
|
parseGraphQLSchema.addGraphQLMutation('createSomeClass', field)
|
||||||
).toBe(field);
|
|
||||||
expect(
|
|
||||||
parseGraphQLSchema.graphQLObjectsMutations['createSomeClass']
|
|
||||||
).toBe(field);
|
).toBe(field);
|
||||||
|
expect(parseGraphQLSchema.graphQLMutations['createSomeClass']).toBe(
|
||||||
|
field
|
||||||
|
);
|
||||||
expect(() =>
|
expect(() =>
|
||||||
parseGraphQLSchema.addGraphQLObjectMutation('createSomeClass', {}, true)
|
parseGraphQLSchema.addGraphQLMutation('createSomeClass', {}, true)
|
||||||
).toThrowError(
|
).toThrowError(
|
||||||
'Object mutation createSomeClass could not be added to the auto schema because it collided with an existing field.'
|
'Mutation createSomeClass could not be added to the auto schema because it collided with an existing field.'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -369,14 +363,14 @@ describe('ParseGraphQLSchema', () => {
|
|||||||
warn: message => {
|
warn: message => {
|
||||||
logged = true;
|
logged = true;
|
||||||
expect(message).toEqual(
|
expect(message).toEqual(
|
||||||
'Object mutation create could not be added to the auto schema because it collided with an existing field.'
|
'Mutation create could not be added to the auto schema because it collided with an existing field.'
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
await parseGraphQLSchema.load();
|
await parseGraphQLSchema.load();
|
||||||
expect(
|
expect(
|
||||||
parseGraphQLSchema.addGraphQLObjectMutation('create', {})
|
parseGraphQLSchema.addGraphQLMutation('create', {})
|
||||||
).toBeUndefined();
|
).toBeUndefined();
|
||||||
expect(logged).toBeTruthy();
|
expect(logged).toBeTruthy();
|
||||||
});
|
});
|
||||||
@@ -392,12 +386,12 @@ describe('ParseGraphQLSchema', () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
await parseGraphQLSchema.load();
|
await parseGraphQLSchema.load();
|
||||||
delete parseGraphQLSchema.graphQLObjectsMutations.create;
|
delete parseGraphQLSchema.graphQLMutations.create;
|
||||||
const field = {};
|
const field = {};
|
||||||
expect(
|
expect(
|
||||||
parseGraphQLSchema.addGraphQLObjectMutation('create', field, true, true)
|
parseGraphQLSchema.addGraphQLMutation('create', field, true, true)
|
||||||
).toBe(field);
|
).toBe(field);
|
||||||
expect(parseGraphQLSchema.graphQLObjectsMutations['create']).toBe(field);
|
expect(parseGraphQLSchema.graphQLMutations['create']).toBe(field);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -453,27 +447,27 @@ describe('ParseGraphQLSchema', () => {
|
|||||||
await parseGraphQLSchema.databaseController.schemaCache.clear();
|
await parseGraphQLSchema.databaseController.schemaCache.clear();
|
||||||
const schema1 = await parseGraphQLSchema.load();
|
const schema1 = await parseGraphQLSchema.load();
|
||||||
const types1 = parseGraphQLSchema.graphQLTypes;
|
const types1 = parseGraphQLSchema.graphQLTypes;
|
||||||
const objectQueries1 = parseGraphQLSchema.graphQLObjectsQueries;
|
const queries1 = parseGraphQLSchema.graphQLQueries;
|
||||||
const objectMutations1 = parseGraphQLSchema.graphQLObjectsMutations;
|
const mutations1 = parseGraphQLSchema.graphQLMutations;
|
||||||
const user = new Parse.Object('User');
|
const user = new Parse.Object('User');
|
||||||
await user.save();
|
await user.save();
|
||||||
await parseGraphQLSchema.databaseController.schemaCache.clear();
|
await parseGraphQLSchema.databaseController.schemaCache.clear();
|
||||||
const schema2 = await parseGraphQLSchema.load();
|
const schema2 = await parseGraphQLSchema.load();
|
||||||
const types2 = parseGraphQLSchema.graphQLTypes;
|
const types2 = parseGraphQLSchema.graphQLTypes;
|
||||||
const objectQueries2 = parseGraphQLSchema.graphQLObjectsQueries;
|
const queries2 = parseGraphQLSchema.graphQLQueries;
|
||||||
const objectMutations2 = parseGraphQLSchema.graphQLObjectsMutations;
|
const mutations2 = parseGraphQLSchema.graphQLMutations;
|
||||||
expect(schema1).not.toBe(schema2);
|
expect(schema1).not.toBe(schema2);
|
||||||
expect(types1).not.toBe(types2);
|
expect(types1).not.toBe(types2);
|
||||||
expect(types1.map(type => type.name).sort()).toEqual(
|
expect(types1.map(type => type.name).sort()).toEqual(
|
||||||
types2.map(type => type.name).sort()
|
types2.map(type => type.name).sort()
|
||||||
);
|
);
|
||||||
expect(objectQueries1).not.toBe(objectQueries2);
|
expect(queries1).not.toBe(queries2);
|
||||||
expect(Object.keys(objectQueries1).sort()).toEqual(
|
expect(Object.keys(queries1).sort()).toEqual(
|
||||||
Object.keys(objectQueries2).sort()
|
Object.keys(queries2).sort()
|
||||||
);
|
);
|
||||||
expect(objectMutations1).not.toBe(objectMutations2);
|
expect(mutations1).not.toBe(mutations2);
|
||||||
expect(Object.keys(objectMutations1).sort()).toEqual(
|
expect(Object.keys(mutations1).sort()).toEqual(
|
||||||
Object.keys(objectMutations2).sort()
|
Object.keys(mutations2).sort()
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -488,27 +482,27 @@ describe('ParseGraphQLSchema', () => {
|
|||||||
await parseGraphQLSchema.databaseController.schemaCache.clear();
|
await parseGraphQLSchema.databaseController.schemaCache.clear();
|
||||||
const schema1 = await parseGraphQLSchema.load();
|
const schema1 = await parseGraphQLSchema.load();
|
||||||
const types1 = parseGraphQLSchema.graphQLTypes;
|
const types1 = parseGraphQLSchema.graphQLTypes;
|
||||||
const objectQueries1 = parseGraphQLSchema.graphQLObjectsQueries;
|
const queries1 = parseGraphQLSchema.graphQLQueries;
|
||||||
const objectMutations1 = parseGraphQLSchema.graphQLObjectsMutations;
|
const mutations1 = parseGraphQLSchema.graphQLMutations;
|
||||||
const car2 = new Parse.Object('car');
|
const car2 = new Parse.Object('car');
|
||||||
await car2.save();
|
await car2.save();
|
||||||
await parseGraphQLSchema.databaseController.schemaCache.clear();
|
await parseGraphQLSchema.databaseController.schemaCache.clear();
|
||||||
const schema2 = await parseGraphQLSchema.load();
|
const schema2 = await parseGraphQLSchema.load();
|
||||||
const types2 = parseGraphQLSchema.graphQLTypes;
|
const types2 = parseGraphQLSchema.graphQLTypes;
|
||||||
const objectQueries2 = parseGraphQLSchema.graphQLObjectsQueries;
|
const queries2 = parseGraphQLSchema.graphQLQueries;
|
||||||
const objectMutations2 = parseGraphQLSchema.graphQLObjectsMutations;
|
const mutations2 = parseGraphQLSchema.graphQLMutations;
|
||||||
expect(schema1).not.toBe(schema2);
|
expect(schema1).not.toBe(schema2);
|
||||||
expect(types1).not.toBe(types2);
|
expect(types1).not.toBe(types2);
|
||||||
expect(types1.map(type => type.name).sort()).toEqual(
|
expect(types1.map(type => type.name).sort()).toEqual(
|
||||||
types2.map(type => type.name).sort()
|
types2.map(type => type.name).sort()
|
||||||
);
|
);
|
||||||
expect(objectQueries1).not.toBe(objectQueries2);
|
expect(queries1).not.toBe(queries2);
|
||||||
expect(Object.keys(objectQueries1).sort()).toEqual(
|
expect(Object.keys(queries1).sort()).toEqual(
|
||||||
Object.keys(objectQueries2).sort()
|
Object.keys(queries2).sort()
|
||||||
);
|
);
|
||||||
expect(objectMutations1).not.toBe(objectMutations2);
|
expect(mutations1).not.toBe(mutations2);
|
||||||
expect(Object.keys(objectMutations1).sort()).toEqual(
|
expect(Object.keys(mutations1).sort()).toEqual(
|
||||||
Object.keys(objectMutations2).sort()
|
Object.keys(mutations2).sort()
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -522,25 +516,25 @@ describe('ParseGraphQLSchema', () => {
|
|||||||
await car.save();
|
await car.save();
|
||||||
await parseGraphQLSchema.databaseController.schemaCache.clear();
|
await parseGraphQLSchema.databaseController.schemaCache.clear();
|
||||||
const schema1 = await parseGraphQLSchema.load();
|
const schema1 = await parseGraphQLSchema.load();
|
||||||
const objectQueries1 = parseGraphQLSchema.graphQLObjectsQueries;
|
const queries1 = parseGraphQLSchema.graphQLQueries;
|
||||||
const objectMutations1 = parseGraphQLSchema.graphQLObjectsMutations;
|
const mutations1 = parseGraphQLSchema.graphQLMutations;
|
||||||
const cars = new Parse.Object('cars');
|
const cars = new Parse.Object('cars');
|
||||||
await cars.save();
|
await cars.save();
|
||||||
await parseGraphQLSchema.databaseController.schemaCache.clear();
|
await parseGraphQLSchema.databaseController.schemaCache.clear();
|
||||||
const schema2 = await parseGraphQLSchema.load();
|
const schema2 = await parseGraphQLSchema.load();
|
||||||
const objectQueries2 = parseGraphQLSchema.graphQLObjectsQueries;
|
const queries2 = parseGraphQLSchema.graphQLQueries;
|
||||||
const objectMutations2 = parseGraphQLSchema.graphQLObjectsMutations;
|
const mutations2 = parseGraphQLSchema.graphQLMutations;
|
||||||
expect(schema1).not.toBe(schema2);
|
expect(schema1).not.toBe(schema2);
|
||||||
expect(objectQueries1).not.toBe(objectQueries2);
|
expect(queries1).not.toBe(queries2);
|
||||||
expect(Object.keys(objectQueries1).sort()).toEqual(
|
expect(Object.keys(queries1).sort()).toEqual(
|
||||||
Object.keys(objectQueries2).sort()
|
Object.keys(queries2).sort()
|
||||||
);
|
);
|
||||||
expect(objectMutations1).not.toBe(objectMutations2);
|
expect(mutations1).not.toBe(mutations2);
|
||||||
expect(
|
expect(
|
||||||
Object.keys(objectMutations1)
|
Object.keys(mutations1)
|
||||||
.concat('createCars', 'updateCars', 'deleteCars')
|
.concat('createCars', 'updateCars', 'deleteCars')
|
||||||
.sort()
|
.sort()
|
||||||
).toEqual(Object.keys(objectMutations2).sort());
|
).toEqual(Object.keys(mutations2).sort());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -25,18 +25,21 @@ const RESERVED_GRAPHQL_TYPE_NAMES = [
|
|||||||
'Query',
|
'Query',
|
||||||
'Mutation',
|
'Mutation',
|
||||||
'Subscription',
|
'Subscription',
|
||||||
'ObjectsQuery',
|
|
||||||
'UsersQuery',
|
|
||||||
'ObjectsMutation',
|
|
||||||
'FilesMutation',
|
|
||||||
'UsersMutation',
|
|
||||||
'FunctionsMutation',
|
|
||||||
'Viewer',
|
'Viewer',
|
||||||
'SignUpFieldsInput',
|
'SignUpFieldsInput',
|
||||||
'LogInFieldsInput',
|
'LogInFieldsInput',
|
||||||
];
|
];
|
||||||
const RESERVED_GRAPHQL_OBJECT_QUERY_NAMES = ['get', 'find'];
|
const RESERVED_GRAPHQL_QUERY_NAMES = ['health', 'viewer', 'get', 'find'];
|
||||||
const RESERVED_GRAPHQL_OBJECT_MUTATION_NAMES = ['create', 'update', 'delete'];
|
const RESERVED_GRAPHQL_MUTATION_NAMES = [
|
||||||
|
'signUp',
|
||||||
|
'logIn',
|
||||||
|
'logOut',
|
||||||
|
'createFile',
|
||||||
|
'callCloudCode',
|
||||||
|
'create',
|
||||||
|
'update',
|
||||||
|
'delete',
|
||||||
|
];
|
||||||
|
|
||||||
class ParseGraphQLSchema {
|
class ParseGraphQLSchema {
|
||||||
databaseController: DatabaseController;
|
databaseController: DatabaseController;
|
||||||
@@ -87,9 +90,7 @@ class ParseGraphQLSchema {
|
|||||||
this.graphQLAutoSchema = null;
|
this.graphQLAutoSchema = null;
|
||||||
this.graphQLSchema = null;
|
this.graphQLSchema = null;
|
||||||
this.graphQLTypes = [];
|
this.graphQLTypes = [];
|
||||||
this.graphQLObjectsQueries = {};
|
|
||||||
this.graphQLQueries = {};
|
this.graphQLQueries = {};
|
||||||
this.graphQLObjectsMutations = {};
|
|
||||||
this.graphQLMutations = {};
|
this.graphQLMutations = {};
|
||||||
this.graphQLSubscriptions = {};
|
this.graphQLSubscriptions = {};
|
||||||
this.graphQLSchemaDirectivesDefinitions = null;
|
this.graphQLSchemaDirectivesDefinitions = null;
|
||||||
@@ -104,6 +105,7 @@ class ParseGraphQLSchema {
|
|||||||
parseClassMutations.load(this, parseClass, parseClassConfig);
|
parseClassMutations.load(this, parseClass, parseClassConfig);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
defaultGraphQLTypes.loadArrayResult(this, parseClasses);
|
defaultGraphQLTypes.loadArrayResult(this, parseClasses);
|
||||||
defaultGraphQLQueries.load(this);
|
defaultGraphQLQueries.load(this);
|
||||||
defaultGraphQLMutations.load(this);
|
defaultGraphQLMutations.load(this);
|
||||||
@@ -211,29 +213,28 @@ class ParseGraphQLSchema {
|
|||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
addGraphQLObjectQuery(
|
addGraphQLQuery(
|
||||||
fieldName,
|
fieldName,
|
||||||
field,
|
field,
|
||||||
throwError = false,
|
throwError = false,
|
||||||
ignoreReserved = false
|
ignoreReserved = false
|
||||||
) {
|
) {
|
||||||
if (
|
if (
|
||||||
(!ignoreReserved &&
|
(!ignoreReserved && RESERVED_GRAPHQL_QUERY_NAMES.includes(fieldName)) ||
|
||||||
RESERVED_GRAPHQL_OBJECT_QUERY_NAMES.includes(fieldName)) ||
|
this.graphQLQueries[fieldName]
|
||||||
this.graphQLObjectsQueries[fieldName]
|
|
||||||
) {
|
) {
|
||||||
const message = `Object query ${fieldName} could not be added to the auto schema because it collided with an existing field.`;
|
const message = `Query ${fieldName} could not be added to the auto schema because it collided with an existing field.`;
|
||||||
if (throwError) {
|
if (throwError) {
|
||||||
throw new Error(message);
|
throw new Error(message);
|
||||||
}
|
}
|
||||||
this.log.warn(message);
|
this.log.warn(message);
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
this.graphQLObjectsQueries[fieldName] = field;
|
this.graphQLQueries[fieldName] = field;
|
||||||
return field;
|
return field;
|
||||||
}
|
}
|
||||||
|
|
||||||
addGraphQLObjectMutation(
|
addGraphQLMutation(
|
||||||
fieldName,
|
fieldName,
|
||||||
field,
|
field,
|
||||||
throwError = false,
|
throwError = false,
|
||||||
@@ -241,17 +242,17 @@ class ParseGraphQLSchema {
|
|||||||
) {
|
) {
|
||||||
if (
|
if (
|
||||||
(!ignoreReserved &&
|
(!ignoreReserved &&
|
||||||
RESERVED_GRAPHQL_OBJECT_MUTATION_NAMES.includes(fieldName)) ||
|
RESERVED_GRAPHQL_MUTATION_NAMES.includes(fieldName)) ||
|
||||||
this.graphQLObjectsMutations[fieldName]
|
this.graphQLMutations[fieldName]
|
||||||
) {
|
) {
|
||||||
const message = `Object mutation ${fieldName} could not be added to the auto schema because it collided with an existing field.`;
|
const message = `Mutation ${fieldName} could not be added to the auto schema because it collided with an existing field.`;
|
||||||
if (throwError) {
|
if (throwError) {
|
||||||
throw new Error(message);
|
throw new Error(message);
|
||||||
}
|
}
|
||||||
this.log.warn(message);
|
this.log.warn(message);
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
this.graphQLObjectsMutations[fieldName] = field;
|
this.graphQLMutations[fieldName] = field;
|
||||||
return field;
|
return field;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,9 @@ class ParseGraphQLServer {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.log.error(e);
|
this.log.error(
|
||||||
|
e.stack || (typeof e.toString === 'function' && e.toString()) || e
|
||||||
|
);
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,12 +3,17 @@ import * as objectsQueries from './objectsQueries';
|
|||||||
import * as usersQueries from './usersQueries';
|
import * as usersQueries from './usersQueries';
|
||||||
|
|
||||||
const load = parseGraphQLSchema => {
|
const load = parseGraphQLSchema => {
|
||||||
parseGraphQLSchema.graphQLQueries.health = {
|
parseGraphQLSchema.addGraphQLQuery(
|
||||||
description:
|
'health',
|
||||||
'The health query can be used to check if the server is up and running.',
|
{
|
||||||
type: new GraphQLNonNull(GraphQLBoolean),
|
description:
|
||||||
resolve: () => true,
|
'The health query can be used to check if the server is up and running.',
|
||||||
};
|
type: new GraphQLNonNull(GraphQLBoolean),
|
||||||
|
resolve: () => true,
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
objectsQueries.load(parseGraphQLSchema);
|
objectsQueries.load(parseGraphQLSchema);
|
||||||
usersQueries.load(parseGraphQLSchema);
|
usersQueries.load(parseGraphQLSchema);
|
||||||
|
|||||||
@@ -1,93 +1,83 @@
|
|||||||
import { GraphQLObjectType, GraphQLNonNull } from 'graphql';
|
import { GraphQLNonNull } from 'graphql';
|
||||||
import { GraphQLUpload } from 'graphql-upload';
|
import { GraphQLUpload } from 'graphql-upload';
|
||||||
import Parse from 'parse/node';
|
import Parse from 'parse/node';
|
||||||
import * as defaultGraphQLTypes from './defaultGraphQLTypes';
|
import * as defaultGraphQLTypes from './defaultGraphQLTypes';
|
||||||
import logger from '../../logger';
|
import logger from '../../logger';
|
||||||
|
|
||||||
const load = parseGraphQLSchema => {
|
const load = parseGraphQLSchema => {
|
||||||
const fields = {};
|
parseGraphQLSchema.addGraphQLMutation(
|
||||||
|
'createFile',
|
||||||
|
{
|
||||||
|
description:
|
||||||
|
'The create mutation can be used to create and upload a new file.',
|
||||||
|
args: {
|
||||||
|
upload: {
|
||||||
|
description: 'This is the new file to be created and uploaded',
|
||||||
|
type: new GraphQLNonNull(GraphQLUpload),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
type: new GraphQLNonNull(defaultGraphQLTypes.FILE_INFO),
|
||||||
|
async resolve(_source, args, context) {
|
||||||
|
try {
|
||||||
|
const { upload } = args;
|
||||||
|
const { config } = context;
|
||||||
|
|
||||||
fields.create = {
|
const { createReadStream, filename, mimetype } = await upload;
|
||||||
description:
|
let data = null;
|
||||||
'The create mutation can be used to create and upload a new file.',
|
if (createReadStream) {
|
||||||
args: {
|
const stream = createReadStream();
|
||||||
upload: {
|
data = await new Promise((resolve, reject) => {
|
||||||
description: 'This is the new file to be created and uploaded',
|
let data = '';
|
||||||
type: new GraphQLNonNull(GraphQLUpload),
|
stream
|
||||||
|
.on('error', reject)
|
||||||
|
.on('data', chunk => (data += chunk))
|
||||||
|
.on('end', () => resolve(data));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!data || !data.length) {
|
||||||
|
throw new Parse.Error(
|
||||||
|
Parse.Error.FILE_SAVE_ERROR,
|
||||||
|
'Invalid file upload.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filename.length > 128) {
|
||||||
|
throw new Parse.Error(
|
||||||
|
Parse.Error.INVALID_FILE_NAME,
|
||||||
|
'Filename too long.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!filename.match(/^[_a-zA-Z0-9][a-zA-Z0-9@\.\ ~_-]*$/)) {
|
||||||
|
throw new Parse.Error(
|
||||||
|
Parse.Error.INVALID_FILE_NAME,
|
||||||
|
'Filename contains invalid characters.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return await config.filesController.createFile(
|
||||||
|
config,
|
||||||
|
filename,
|
||||||
|
data,
|
||||||
|
mimetype
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
logger.error('Error creating a file: ', e);
|
||||||
|
throw new Parse.Error(
|
||||||
|
Parse.Error.FILE_SAVE_ERROR,
|
||||||
|
`Could not store file: ${filename}.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
parseGraphQLSchema.handleError(e);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
type: new GraphQLNonNull(defaultGraphQLTypes.FILE_INFO),
|
true,
|
||||||
async resolve(_source, args, context) {
|
true
|
||||||
try {
|
);
|
||||||
const { upload } = args;
|
|
||||||
const { config } = context;
|
|
||||||
|
|
||||||
const { createReadStream, filename, mimetype } = await upload;
|
|
||||||
let data = null;
|
|
||||||
if (createReadStream) {
|
|
||||||
const stream = createReadStream();
|
|
||||||
data = await new Promise((resolve, reject) => {
|
|
||||||
let data = '';
|
|
||||||
stream
|
|
||||||
.on('error', reject)
|
|
||||||
.on('data', chunk => (data += chunk))
|
|
||||||
.on('end', () => resolve(data));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!data || !data.length) {
|
|
||||||
throw new Parse.Error(
|
|
||||||
Parse.Error.FILE_SAVE_ERROR,
|
|
||||||
'Invalid file upload.'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (filename.length > 128) {
|
|
||||||
throw new Parse.Error(
|
|
||||||
Parse.Error.INVALID_FILE_NAME,
|
|
||||||
'Filename too long.'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!filename.match(/^[_a-zA-Z0-9][a-zA-Z0-9@\.\ ~_-]*$/)) {
|
|
||||||
throw new Parse.Error(
|
|
||||||
Parse.Error.INVALID_FILE_NAME,
|
|
||||||
'Filename contains invalid characters.'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
return await config.filesController.createFile(
|
|
||||||
config,
|
|
||||||
filename,
|
|
||||||
data,
|
|
||||||
mimetype
|
|
||||||
);
|
|
||||||
} catch (e) {
|
|
||||||
logger.error('Error creating a file: ', e);
|
|
||||||
throw new Parse.Error(
|
|
||||||
Parse.Error.FILE_SAVE_ERROR,
|
|
||||||
`Could not store file: ${filename}.`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
parseGraphQLSchema.handleError(e);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const filesMutation = new GraphQLObjectType({
|
|
||||||
name: 'FilesMutation',
|
|
||||||
description: 'FilesMutation is the top level type for files mutations.',
|
|
||||||
fields,
|
|
||||||
});
|
|
||||||
parseGraphQLSchema.addGraphQLType(filesMutation, true, true);
|
|
||||||
|
|
||||||
parseGraphQLSchema.graphQLMutations.files = {
|
|
||||||
description: 'This is the top level for files mutations.',
|
|
||||||
type: filesMutation,
|
|
||||||
resolve: () => new Object(),
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export { load };
|
export { load };
|
||||||
|
|||||||
@@ -1,57 +1,46 @@
|
|||||||
import { GraphQLObjectType, GraphQLNonNull, GraphQLString } from 'graphql';
|
import { GraphQLNonNull, GraphQLString } from 'graphql';
|
||||||
import { FunctionsRouter } from '../../Routers/FunctionsRouter';
|
import { FunctionsRouter } from '../../Routers/FunctionsRouter';
|
||||||
import * as defaultGraphQLTypes from './defaultGraphQLTypes';
|
import * as defaultGraphQLTypes from './defaultGraphQLTypes';
|
||||||
|
|
||||||
const load = parseGraphQLSchema => {
|
const load = parseGraphQLSchema => {
|
||||||
const fields = {};
|
parseGraphQLSchema.addGraphQLMutation(
|
||||||
|
'callCloudCode',
|
||||||
fields.call = {
|
{
|
||||||
description:
|
description:
|
||||||
'The call mutation can be used to invoke a cloud code function.',
|
'The call mutation can be used to invoke a cloud code function.',
|
||||||
args: {
|
args: {
|
||||||
functionName: {
|
functionName: {
|
||||||
description: 'This is the name of the function to be called.',
|
description: 'This is the name of the function to be called.',
|
||||||
type: new GraphQLNonNull(GraphQLString),
|
type: new GraphQLNonNull(GraphQLString),
|
||||||
|
},
|
||||||
|
params: {
|
||||||
|
description: 'These are the params to be passed to the function.',
|
||||||
|
type: defaultGraphQLTypes.OBJECT,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
params: {
|
type: defaultGraphQLTypes.ANY,
|
||||||
description: 'These are the params to be passed to the function.',
|
async resolve(_source, args, context) {
|
||||||
type: defaultGraphQLTypes.OBJECT,
|
try {
|
||||||
|
const { functionName, params } = args;
|
||||||
|
const { config, auth, info } = context;
|
||||||
|
|
||||||
|
return (await FunctionsRouter.handleCloudFunction({
|
||||||
|
params: {
|
||||||
|
functionName,
|
||||||
|
},
|
||||||
|
config,
|
||||||
|
auth,
|
||||||
|
info,
|
||||||
|
body: params,
|
||||||
|
})).response.result;
|
||||||
|
} catch (e) {
|
||||||
|
parseGraphQLSchema.handleError(e);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
type: defaultGraphQLTypes.ANY,
|
true,
|
||||||
async resolve(_source, args, context) {
|
true
|
||||||
try {
|
);
|
||||||
const { functionName, params } = args;
|
|
||||||
const { config, auth, info } = context;
|
|
||||||
|
|
||||||
return (await FunctionsRouter.handleCloudFunction({
|
|
||||||
params: {
|
|
||||||
functionName,
|
|
||||||
},
|
|
||||||
config,
|
|
||||||
auth,
|
|
||||||
info,
|
|
||||||
body: params,
|
|
||||||
})).response.result;
|
|
||||||
} catch (e) {
|
|
||||||
parseGraphQLSchema.handleError(e);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const functionsMutation = new GraphQLObjectType({
|
|
||||||
name: 'FunctionsMutation',
|
|
||||||
description:
|
|
||||||
'FunctionsMutation is the top level type for functions mutations.',
|
|
||||||
fields,
|
|
||||||
});
|
|
||||||
parseGraphQLSchema.addGraphQLType(functionsMutation, true, true);
|
|
||||||
|
|
||||||
parseGraphQLSchema.graphQLMutations.functions = {
|
|
||||||
description: 'This is the top level for functions mutations.',
|
|
||||||
type: functionsMutation,
|
|
||||||
resolve: () => new Object(),
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export { load };
|
export { load };
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { GraphQLNonNull, GraphQLBoolean, GraphQLObjectType } from 'graphql';
|
import { GraphQLNonNull, GraphQLBoolean } from 'graphql';
|
||||||
import * as defaultGraphQLTypes from './defaultGraphQLTypes';
|
import * as defaultGraphQLTypes from './defaultGraphQLTypes';
|
||||||
import rest from '../../rest';
|
import rest from '../../rest';
|
||||||
import { transformMutationInputToParse } from '../transformers/mutation';
|
import { transformMutationInputToParse } from '../transformers/mutation';
|
||||||
@@ -44,7 +44,7 @@ const deleteObject = async (className, objectId, config, auth, info) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const load = parseGraphQLSchema => {
|
const load = parseGraphQLSchema => {
|
||||||
parseGraphQLSchema.addGraphQLObjectMutation(
|
parseGraphQLSchema.addGraphQLMutation(
|
||||||
'create',
|
'create',
|
||||||
{
|
{
|
||||||
description:
|
description:
|
||||||
@@ -69,7 +69,7 @@ const load = parseGraphQLSchema => {
|
|||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
parseGraphQLSchema.addGraphQLObjectMutation(
|
parseGraphQLSchema.addGraphQLMutation(
|
||||||
'update',
|
'update',
|
||||||
{
|
{
|
||||||
description:
|
description:
|
||||||
@@ -102,7 +102,7 @@ const load = parseGraphQLSchema => {
|
|||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
parseGraphQLSchema.addGraphQLObjectMutation(
|
parseGraphQLSchema.addGraphQLMutation(
|
||||||
'delete',
|
'delete',
|
||||||
{
|
{
|
||||||
description:
|
description:
|
||||||
@@ -126,19 +126,6 @@ const load = parseGraphQLSchema => {
|
|||||||
true,
|
true,
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
const objectsMutation = new GraphQLObjectType({
|
|
||||||
name: 'ObjectsMutation',
|
|
||||||
description: 'ObjectsMutation is the top level type for objects mutations.',
|
|
||||||
fields: parseGraphQLSchema.graphQLObjectsMutations,
|
|
||||||
});
|
|
||||||
parseGraphQLSchema.addGraphQLType(objectsMutation, true, true);
|
|
||||||
|
|
||||||
parseGraphQLSchema.graphQLMutations.objects = {
|
|
||||||
description: 'This is the top level for objects mutations.',
|
|
||||||
type: objectsMutation,
|
|
||||||
resolve: () => new Object(),
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export { createObject, updateObject, deleteObject, load };
|
export { createObject, updateObject, deleteObject, load };
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
import {
|
import { GraphQLNonNull, GraphQLBoolean, GraphQLString } from 'graphql';
|
||||||
GraphQLNonNull,
|
|
||||||
GraphQLBoolean,
|
|
||||||
GraphQLString,
|
|
||||||
GraphQLObjectType,
|
|
||||||
} from 'graphql';
|
|
||||||
import getFieldNames from 'graphql-list-fields';
|
import getFieldNames from 'graphql-list-fields';
|
||||||
import Parse from 'parse/node';
|
import Parse from 'parse/node';
|
||||||
import * as defaultGraphQLTypes from './defaultGraphQLTypes';
|
import * as defaultGraphQLTypes from './defaultGraphQLTypes';
|
||||||
@@ -134,7 +129,7 @@ const findObjects = async (
|
|||||||
};
|
};
|
||||||
|
|
||||||
const load = parseGraphQLSchema => {
|
const load = parseGraphQLSchema => {
|
||||||
parseGraphQLSchema.addGraphQLObjectQuery(
|
parseGraphQLSchema.addGraphQLQuery(
|
||||||
'get',
|
'get',
|
||||||
{
|
{
|
||||||
description:
|
description:
|
||||||
@@ -181,7 +176,7 @@ const load = parseGraphQLSchema => {
|
|||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
parseGraphQLSchema.addGraphQLObjectQuery(
|
parseGraphQLSchema.addGraphQLQuery(
|
||||||
'find',
|
'find',
|
||||||
{
|
{
|
||||||
description:
|
description:
|
||||||
@@ -252,19 +247,6 @@ const load = parseGraphQLSchema => {
|
|||||||
true,
|
true,
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
const objectsQuery = new GraphQLObjectType({
|
|
||||||
name: 'ObjectsQuery',
|
|
||||||
description: 'ObjectsQuery is the top level type for objects queries.',
|
|
||||||
fields: parseGraphQLSchema.graphQLObjectsQueries,
|
|
||||||
});
|
|
||||||
parseGraphQLSchema.addGraphQLType(objectsQuery, true, true);
|
|
||||||
|
|
||||||
parseGraphQLSchema.graphQLQueries.objects = {
|
|
||||||
description: 'This is the top level for objects queries.',
|
|
||||||
type: objectsQuery,
|
|
||||||
resolve: () => new Object(),
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export { getObject, findObjects, load };
|
export { getObject, findObjects, load };
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ const load = function(
|
|||||||
|
|
||||||
if (isCreateEnabled) {
|
if (isCreateEnabled) {
|
||||||
const createGraphQLMutationName = `create${graphQLClassName}`;
|
const createGraphQLMutationName = `create${graphQLClassName}`;
|
||||||
parseGraphQLSchema.addGraphQLObjectMutation(createGraphQLMutationName, {
|
parseGraphQLSchema.addGraphQLMutation(createGraphQLMutationName, {
|
||||||
description: `The ${createGraphQLMutationName} mutation can be used to create a new object of the ${graphQLClassName} class.`,
|
description: `The ${createGraphQLMutationName} mutation can be used to create a new object of the ${graphQLClassName} class.`,
|
||||||
args: {
|
args: {
|
||||||
fields: {
|
fields: {
|
||||||
@@ -155,7 +155,7 @@ const load = function(
|
|||||||
|
|
||||||
if (isUpdateEnabled) {
|
if (isUpdateEnabled) {
|
||||||
const updateGraphQLMutationName = `update${graphQLClassName}`;
|
const updateGraphQLMutationName = `update${graphQLClassName}`;
|
||||||
parseGraphQLSchema.addGraphQLObjectMutation(updateGraphQLMutationName, {
|
parseGraphQLSchema.addGraphQLMutation(updateGraphQLMutationName, {
|
||||||
description: `The ${updateGraphQLMutationName} mutation can be used to update an object of the ${graphQLClassName} class.`,
|
description: `The ${updateGraphQLMutationName} mutation can be used to update an object of the ${graphQLClassName} class.`,
|
||||||
args: {
|
args: {
|
||||||
objectId: defaultGraphQLTypes.OBJECT_ID_ATT,
|
objectId: defaultGraphQLTypes.OBJECT_ID_ATT,
|
||||||
@@ -215,7 +215,7 @@ const load = function(
|
|||||||
|
|
||||||
if (isDestroyEnabled) {
|
if (isDestroyEnabled) {
|
||||||
const deleteGraphQLMutationName = `delete${graphQLClassName}`;
|
const deleteGraphQLMutationName = `delete${graphQLClassName}`;
|
||||||
parseGraphQLSchema.addGraphQLObjectMutation(deleteGraphQLMutationName, {
|
parseGraphQLSchema.addGraphQLMutation(deleteGraphQLMutationName, {
|
||||||
description: `The ${deleteGraphQLMutationName} mutation can be used to delete an object of the ${graphQLClassName} class.`,
|
description: `The ${deleteGraphQLMutationName} mutation can be used to delete an object of the ${graphQLClassName} class.`,
|
||||||
args: {
|
args: {
|
||||||
objectId: defaultGraphQLTypes.OBJECT_ID_ATT,
|
objectId: defaultGraphQLTypes.OBJECT_ID_ATT,
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ const load = function(
|
|||||||
if (isGetEnabled) {
|
if (isGetEnabled) {
|
||||||
const getGraphQLQueryName =
|
const getGraphQLQueryName =
|
||||||
graphQLClassName.charAt(0).toLowerCase() + graphQLClassName.slice(1);
|
graphQLClassName.charAt(0).toLowerCase() + graphQLClassName.slice(1);
|
||||||
parseGraphQLSchema.addGraphQLObjectQuery(getGraphQLQueryName, {
|
parseGraphQLSchema.addGraphQLQuery(getGraphQLQueryName, {
|
||||||
description: `The ${getGraphQLQueryName} query can be used to get an object of the ${graphQLClassName} class by its id.`,
|
description: `The ${getGraphQLQueryName} query can be used to get an object of the ${graphQLClassName} class by its id.`,
|
||||||
args: {
|
args: {
|
||||||
objectId: defaultGraphQLTypes.OBJECT_ID_ATT,
|
objectId: defaultGraphQLTypes.OBJECT_ID_ATT,
|
||||||
@@ -78,7 +78,7 @@ const load = function(
|
|||||||
const findGraphQLQueryName = pluralize(
|
const findGraphQLQueryName = pluralize(
|
||||||
graphQLClassName.charAt(0).toLowerCase() + graphQLClassName.slice(1)
|
graphQLClassName.charAt(0).toLowerCase() + graphQLClassName.slice(1)
|
||||||
);
|
);
|
||||||
parseGraphQLSchema.addGraphQLObjectQuery(findGraphQLQueryName, {
|
parseGraphQLSchema.addGraphQLQuery(findGraphQLQueryName, {
|
||||||
description: `The ${findGraphQLQueryName} query can be used to find objects of the ${graphQLClassName} class.`,
|
description: `The ${findGraphQLQueryName} query can be used to find objects of the ${graphQLClassName} class.`,
|
||||||
args: classGraphQLFindArgs,
|
args: classGraphQLFindArgs,
|
||||||
type: new GraphQLNonNull(
|
type: new GraphQLNonNull(
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import { SchemaDirectiveVisitor } from 'graphql-tools';
|
|||||||
import { FunctionsRouter } from '../../Routers/FunctionsRouter';
|
import { FunctionsRouter } from '../../Routers/FunctionsRouter';
|
||||||
|
|
||||||
export const definitions = gql`
|
export const definitions = gql`
|
||||||
directive @namespace on FIELD_DEFINITION
|
|
||||||
directive @resolve(to: String) on FIELD_DEFINITION
|
directive @resolve(to: String) on FIELD_DEFINITION
|
||||||
directive @mock(with: Any!) on FIELD_DEFINITION
|
directive @mock(with: Any!) on FIELD_DEFINITION
|
||||||
`;
|
`;
|
||||||
@@ -11,14 +10,6 @@ export const definitions = gql`
|
|||||||
const load = parseGraphQLSchema => {
|
const load = parseGraphQLSchema => {
|
||||||
parseGraphQLSchema.graphQLSchemaDirectivesDefinitions = definitions;
|
parseGraphQLSchema.graphQLSchemaDirectivesDefinitions = definitions;
|
||||||
|
|
||||||
class NamespaceDirectiveVisitor extends SchemaDirectiveVisitor {
|
|
||||||
visitFieldDefinition(field) {
|
|
||||||
field.resolve = () => ({});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
parseGraphQLSchema.graphQLSchemaDirectives.namespace = NamespaceDirectiveVisitor;
|
|
||||||
|
|
||||||
class ResolveDirectiveVisitor extends SchemaDirectiveVisitor {
|
class ResolveDirectiveVisitor extends SchemaDirectiveVisitor {
|
||||||
visitFieldDefinition(field) {
|
visitFieldDefinition(field) {
|
||||||
field.resolve = async (_source, args, context) => {
|
field.resolve = async (_source, args, context) => {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { GraphQLNonNull, GraphQLObjectType } from 'graphql';
|
import { GraphQLNonNull } from 'graphql';
|
||||||
import UsersRouter from '../../Routers/UsersRouter';
|
import UsersRouter from '../../Routers/UsersRouter';
|
||||||
import * as objectsMutations from './objectsMutations';
|
import * as objectsMutations from './objectsMutations';
|
||||||
import { getUserFromSessionToken } from './usersQueries';
|
import { getUserFromSessionToken } from './usersQueries';
|
||||||
@@ -9,110 +9,111 @@ const load = parseGraphQLSchema => {
|
|||||||
if (parseGraphQLSchema.isUsersClassDisabled) {
|
if (parseGraphQLSchema.isUsersClassDisabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const fields = {};
|
|
||||||
|
|
||||||
fields.signUp = {
|
parseGraphQLSchema.addGraphQLMutation(
|
||||||
description: 'The signUp mutation can be used to sign the user up.',
|
'signUp',
|
||||||
args: {
|
{
|
||||||
fields: {
|
description: 'The signUp mutation can be used to sign the user up.',
|
||||||
descriptions: 'These are the fields of the user.',
|
args: {
|
||||||
type: parseGraphQLSchema.parseClassTypes['_User'].signUpInputType,
|
fields: {
|
||||||
|
descriptions: 'These are the fields of the user.',
|
||||||
|
type: parseGraphQLSchema.parseClassTypes['_User'].signUpInputType,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
type: new GraphQLNonNull(parseGraphQLSchema.viewerType),
|
||||||
|
async resolve(_source, args, context, mutationInfo) {
|
||||||
|
try {
|
||||||
|
const { fields } = args;
|
||||||
|
|
||||||
|
const { config, auth, info } = context;
|
||||||
|
|
||||||
|
const { sessionToken } = await objectsMutations.createObject(
|
||||||
|
'_User',
|
||||||
|
fields,
|
||||||
|
config,
|
||||||
|
auth,
|
||||||
|
info
|
||||||
|
);
|
||||||
|
|
||||||
|
info.sessionToken = sessionToken;
|
||||||
|
|
||||||
|
return await getUserFromSessionToken(config, info, mutationInfo);
|
||||||
|
} catch (e) {
|
||||||
|
parseGraphQLSchema.handleError(e);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
type: new GraphQLNonNull(parseGraphQLSchema.viewerType),
|
true,
|
||||||
async resolve(_source, args, context, mutationInfo) {
|
true
|
||||||
try {
|
);
|
||||||
const { fields } = args;
|
|
||||||
|
|
||||||
const { config, auth, info } = context;
|
parseGraphQLSchema.addGraphQLMutation(
|
||||||
|
'logIn',
|
||||||
|
{
|
||||||
|
description: 'The logIn mutation can be used to log the user in.',
|
||||||
|
args: {
|
||||||
|
fields: {
|
||||||
|
description: 'This is data needed to login',
|
||||||
|
type: parseGraphQLSchema.parseClassTypes['_User'].logInInputType,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
type: new GraphQLNonNull(parseGraphQLSchema.viewerType),
|
||||||
|
async resolve(_source, args, context) {
|
||||||
|
try {
|
||||||
|
const {
|
||||||
|
fields: { username, password },
|
||||||
|
} = args;
|
||||||
|
const { config, auth, info } = context;
|
||||||
|
|
||||||
const { sessionToken } = await objectsMutations.createObject(
|
return (await usersRouter.handleLogIn({
|
||||||
'_User',
|
body: {
|
||||||
fields,
|
username,
|
||||||
config,
|
password,
|
||||||
auth,
|
},
|
||||||
info
|
query: {},
|
||||||
);
|
config,
|
||||||
|
auth,
|
||||||
info.sessionToken = sessionToken;
|
info,
|
||||||
|
})).response;
|
||||||
return await getUserFromSessionToken(config, info, mutationInfo);
|
} catch (e) {
|
||||||
} catch (e) {
|
parseGraphQLSchema.handleError(e);
|
||||||
parseGraphQLSchema.handleError(e);
|
}
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
fields.logIn = {
|
|
||||||
description: 'The logIn mutation can be used to log the user in.',
|
|
||||||
args: {
|
|
||||||
fields: {
|
|
||||||
description: 'This is data needed to login',
|
|
||||||
type: parseGraphQLSchema.parseClassTypes['_User'].logInInputType,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
type: new GraphQLNonNull(parseGraphQLSchema.viewerType),
|
true,
|
||||||
async resolve(_source, args, context) {
|
true
|
||||||
try {
|
);
|
||||||
const {
|
|
||||||
fields: { username, password },
|
|
||||||
} = args;
|
|
||||||
const { config, auth, info } = context;
|
|
||||||
|
|
||||||
return (await usersRouter.handleLogIn({
|
parseGraphQLSchema.addGraphQLMutation(
|
||||||
body: {
|
'logOut',
|
||||||
username,
|
{
|
||||||
password,
|
description: 'The logOut mutation can be used to log the user out.',
|
||||||
},
|
type: new GraphQLNonNull(parseGraphQLSchema.viewerType),
|
||||||
query: {},
|
async resolve(_source, _args, context, mutationInfo) {
|
||||||
config,
|
try {
|
||||||
auth,
|
const { config, auth, info } = context;
|
||||||
info,
|
|
||||||
})).response;
|
const viewer = await getUserFromSessionToken(
|
||||||
} catch (e) {
|
config,
|
||||||
parseGraphQLSchema.handleError(e);
|
info,
|
||||||
}
|
mutationInfo
|
||||||
|
);
|
||||||
|
|
||||||
|
await usersRouter.handleLogOut({
|
||||||
|
config,
|
||||||
|
auth,
|
||||||
|
info,
|
||||||
|
});
|
||||||
|
|
||||||
|
return viewer;
|
||||||
|
} catch (e) {
|
||||||
|
parseGraphQLSchema.handleError(e);
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
true,
|
||||||
|
true
|
||||||
fields.logOut = {
|
);
|
||||||
description: 'The logOut mutation can be used to log the user out.',
|
|
||||||
type: new GraphQLNonNull(parseGraphQLSchema.viewerType),
|
|
||||||
async resolve(_source, _args, context, mutationInfo) {
|
|
||||||
try {
|
|
||||||
const { config, auth, info } = context;
|
|
||||||
|
|
||||||
const viewer = await getUserFromSessionToken(
|
|
||||||
config,
|
|
||||||
info,
|
|
||||||
mutationInfo
|
|
||||||
);
|
|
||||||
|
|
||||||
await usersRouter.handleLogOut({
|
|
||||||
config,
|
|
||||||
auth,
|
|
||||||
info,
|
|
||||||
});
|
|
||||||
|
|
||||||
return viewer;
|
|
||||||
} catch (e) {
|
|
||||||
parseGraphQLSchema.handleError(e);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const usersMutation = new GraphQLObjectType({
|
|
||||||
name: 'UsersMutation',
|
|
||||||
description: 'UsersMutation is the top level type for files mutations.',
|
|
||||||
fields,
|
|
||||||
});
|
|
||||||
parseGraphQLSchema.addGraphQLType(usersMutation, true, true);
|
|
||||||
|
|
||||||
parseGraphQLSchema.graphQLMutations.users = {
|
|
||||||
description: 'This is the top level for users mutations.',
|
|
||||||
type: usersMutation,
|
|
||||||
resolve: () => new Object(),
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export { load };
|
export { load };
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { GraphQLNonNull, GraphQLObjectType } from 'graphql';
|
import { GraphQLNonNull } from 'graphql';
|
||||||
import getFieldNames from 'graphql-list-fields';
|
import getFieldNames from 'graphql-list-fields';
|
||||||
import Parse from 'parse/node';
|
import Parse from 'parse/node';
|
||||||
import rest from '../../rest';
|
import rest from '../../rest';
|
||||||
@@ -49,34 +49,25 @@ const load = parseGraphQLSchema => {
|
|||||||
if (parseGraphQLSchema.isUsersClassDisabled) {
|
if (parseGraphQLSchema.isUsersClassDisabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const fields = {};
|
|
||||||
|
|
||||||
fields.viewer = {
|
parseGraphQLSchema.addGraphQLQuery(
|
||||||
description:
|
'viewer',
|
||||||
'The viewer query can be used to return the current user data.',
|
{
|
||||||
type: new GraphQLNonNull(parseGraphQLSchema.viewerType),
|
description:
|
||||||
async resolve(_source, _args, context, queryInfo) {
|
'The viewer query can be used to return the current user data.',
|
||||||
try {
|
type: new GraphQLNonNull(parseGraphQLSchema.viewerType),
|
||||||
const { config, info } = context;
|
async resolve(_source, _args, context, queryInfo) {
|
||||||
return await getUserFromSessionToken(config, info, queryInfo);
|
try {
|
||||||
} catch (e) {
|
const { config, info } = context;
|
||||||
parseGraphQLSchema.handleError(e);
|
return await getUserFromSessionToken(config, info, queryInfo);
|
||||||
}
|
} catch (e) {
|
||||||
|
parseGraphQLSchema.handleError(e);
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
true,
|
||||||
|
true
|
||||||
const usersQuery = new GraphQLObjectType({
|
);
|
||||||
name: 'UsersQuery',
|
|
||||||
description: 'UsersQuery is the top level type for users queries.',
|
|
||||||
fields,
|
|
||||||
});
|
|
||||||
parseGraphQLSchema.addGraphQLType(usersQuery, true, true);
|
|
||||||
|
|
||||||
parseGraphQLSchema.graphQLQueries.users = {
|
|
||||||
description: 'This is the top level for users queries.',
|
|
||||||
type: usersQuery,
|
|
||||||
resolve: () => new Object(),
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export { load, getUserFromSessionToken };
|
export { load, getUserFromSessionToken };
|
||||||
|
|||||||
Reference in New Issue
Block a user