Skip to content

Commit

Permalink
feat: update gql dep
Browse files Browse the repository at this point in the history
  • Loading branch information
Moumouls committed May 4, 2022
1 parent b84acd5 commit 15c5631
Show file tree
Hide file tree
Showing 10 changed files with 349 additions and 1,079 deletions.
1,177 changes: 237 additions & 940 deletions package-lock.json

Large diffs are not rendered by default.

17 changes: 9 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,24 +21,24 @@
"dependencies": {
"@apollo/client": "3.5.10",
"@apollographql/graphql-playground-html": "1.6.29",
"@graphql-tools/links": "8.2.9",
"@graphql-tools/stitch": "6.2.4",
"@graphql-tools/utils": "6.2.4",
"@graphql-tools/links": "8.2.14",
"@graphql-tools/merge": "8.2.10",
"@graphql-tools/schema": "8.3.10",
"@graphql-tools/utils": "8.6.9",
"@parse/fs-files-adapter": "1.2.2",
"@parse/push-adapter": "4.1.2",
"apollo-server-express": "2.25.2",
"apollo-server-express": "3.6.7",
"bcryptjs": "2.4.3",
"body-parser": "1.20.0",
"commander": "5.1.0",
"cors": "2.8.5",
"deepcopy": "2.1.0",
"express": "4.17.2",
"follow-redirects": "1.14.9",
"graphql": "15.8.0",
"graphql": "16.4.0",
"graphql-list-fields": "2.0.2",
"graphql-relay": "0.7.0",
"graphql-tag": "2.12.6",
"graphql-upload": "11.0.0",
"graphql-relay": "0.10.0",
"graphql-upload": "13.0.0",
"intersect": "1.0.1",
"jsonwebtoken": "8.5.1",
"jwks-rsa": "2.0.5",
Expand All @@ -62,6 +62,7 @@
"ws": "8.2.3"
},
"devDependencies": {
"graphql-tag": "2.12.6",
"@actions/core": "1.2.6",
"@babel/cli": "7.10.0",
"@babel/core": "7.10.0",
Expand Down
45 changes: 24 additions & 21 deletions spec/ParseGraphQLServer.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const { getMainDefinition } = require('apollo-utilities');
const { createUploadLink } = require('apollo-upload-client');
const { SubscriptionClient } = require('subscriptions-transport-ws');
const { WebSocketLink } = require('@apollo/client/link/ws');
const { mergeSchemas } = require('@graphql-tools/schema');
const {
ApolloClient,
InMemoryCache,
Expand Down Expand Up @@ -133,28 +134,31 @@ describe('ParseGraphQLServer', () => {
});

describe('applyGraphQL', () => {
it('should require an Express.js app instance', () => {
expect(() => parseGraphQLServer.applyGraphQL()).toThrow(
it('should require an Express.js app instance', async () => {
await expectAsync(parseGraphQLServer.applyGraphQL()).toBeRejectedWith(
'You must provide an Express.js app instance!'
);
expect(() => parseGraphQLServer.applyGraphQL({})).toThrow(
await expectAsync(parseGraphQLServer.applyGraphQL({})).toBeRejectedWith(
'You must provide an Express.js app instance!'
);
expect(() => parseGraphQLServer.applyGraphQL(new express())).not.toThrow();
await expectAsync(parseGraphQLServer.applyGraphQL(new express())).toBeResolved();
});

it('should apply middlewares at config.graphQLPath', () => {
it('should apply middlewares at config.graphQLPath', async () => {
let useCount = 0;
expect(() =>
new ParseGraphQLServer(parseServer, {
graphQLPath: 'somepath',
}).applyGraphQL({
use: path => {
useCount++;
expect(path).toEqual('somepath');
},
})
).not.toThrow();
const gqlServer = new ParseGraphQLServer(parseServer, {
graphQLPath: 'somepath',
});
gqlServer.applyGraphQL({
use: server => {
useCount++;
if (typeof server === 'string') {
expect(server).toEqual('somepath');
} else {
expect(server.stack[1].regexp.toString()).toEqual('/^somepath\\/?(?=\\/|$)/i');
}
},
});
expect(useCount).toBeGreaterThan(0);
});
});
Expand Down Expand Up @@ -7697,8 +7701,8 @@ describe('ParseGraphQLServer', () => {
.map(call => call.args[0])
.sort()
).toEqual([
'Function 1NumberInTheBeggning could not be added to the auto schema because GraphQL names must match /^[_a-zA-Z][_a-zA-Z0-9]*$/.',
'Function double-barrelled could not be added to the auto schema because GraphQL names must match /^[_a-zA-Z][_a-zA-Z0-9]*$/.',
'Function 1NumberInTheBeggning could not be added to the auto schema because GraphQL names must match /^ [_a - zA - Z][_a - zA - Z0 - 9] * $ /.',
'Function double-barrelled could not be added to the auto schema because GraphQL names must match /^ [_a - zA - Z][_a - zA - Z0 - 9] * $ /.',
]);
} catch (e) {
handleError(e);
Expand Down Expand Up @@ -10381,7 +10385,7 @@ describe('ParseGraphQLServer', () => {
});

describe('Custom API', () => {
describe('GraphQL Schema Based', () => {
describe('SDL based', () => {
let httpServer;
const headers = {
'X-Parse-Application-Id': 'test',
Expand Down Expand Up @@ -10504,7 +10508,7 @@ describe('ParseGraphQLServer', () => {
});
});

describe('SDL Based', () => {
describe('GraphQL Schema Based', () => {
let httpServer;
const headers = {
'X-Parse-Application-Id': 'test',
Expand Down Expand Up @@ -10801,8 +10805,7 @@ describe('ParseGraphQLServer', () => {
httpServer = http.createServer(expressApp);
parseGraphQLServer = new ParseGraphQLServer(parseServer, {
graphQLPath: '/graphql',
graphQLCustomTypeDefs: ({ autoSchema, stitchSchemas }) =>
stitchSchemas({ subschemas: [autoSchema] }),
graphQLCustomTypeDefs: ({ autoSchema }) => mergeSchemas({ schemas: [autoSchema] }),
});

parseGraphQLServer.applyGraphQL(expressApp);
Expand Down
54 changes: 10 additions & 44 deletions src/GraphQL/ParseGraphQLSchema.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import Parse from 'parse/node';
import { GraphQLSchema, GraphQLObjectType, DocumentNode, GraphQLNamedType } from 'graphql';
import { stitchSchemas } from '@graphql-tools/stitch';
import { mergeSchemas } from '@graphql-tools/schema';
import { mergeTypeDefs } from '@graphql-tools/merge';
import { isDeepStrictEqual } from 'util';
import { SchemaDirectiveVisitor } from '@graphql-tools/utils';
import requiredParameter from '../requiredParameter';
import * as defaultGraphQLTypes from './loaders/defaultGraphQLTypes';
import * as parseClassTypes from './loaders/parseClassTypes';
Expand Down Expand Up @@ -198,7 +198,6 @@ class ParseGraphQLSchema {

if (this.graphQLCustomTypeDefs) {
schemaDirectives.load(this);

if (typeof this.graphQLCustomTypeDefs.getTypeMap === 'function') {
// In following code we use underscore attr to avoid js var un ref
const customGraphQLSchemaTypeMap = this.graphQLCustomTypeDefs._typeMap;
Expand Down Expand Up @@ -275,51 +274,18 @@ class ParseGraphQLSchema {
this.graphQLSchema = await this.graphQLCustomTypeDefs({
directivesDefinitionsSchema: this.graphQLSchemaDirectivesDefinitions,
autoSchema: this.graphQLAutoSchema,
stitchSchemas,
graphQLSchemaDirectives: this.graphQLSchemaDirectives,
});
} else {
this.graphQLSchema = stitchSchemas({
schemas: [
this.graphQLSchemaDirectivesDefinitions,
this.graphQLAutoSchema,
this.graphQLSchema = mergeSchemas({
schemas: [this.graphQLAutoSchema],
typeDefs: mergeTypeDefs([
this.graphQLCustomTypeDefs,
],
mergeDirectives: true,
this.graphQLSchemaDirectivesDefinitions,
]),
});
this.graphQLSchema = this.graphQLSchemaDirectives(this.graphQLSchema);
}

// Only merge directive when string schema provided
const graphQLSchemaTypeMap = this.graphQLSchema.getTypeMap();
Object.keys(graphQLSchemaTypeMap).forEach(graphQLSchemaTypeName => {
const graphQLSchemaType = graphQLSchemaTypeMap[graphQLSchemaTypeName];
if (
typeof graphQLSchemaType.getFields === 'function' &&
this.graphQLCustomTypeDefs.definitions
) {
const graphQLCustomTypeDef = this.graphQLCustomTypeDefs.definitions.find(
definition => definition.name.value === graphQLSchemaTypeName
);
if (graphQLCustomTypeDef) {
const graphQLSchemaTypeFieldMap = graphQLSchemaType.getFields();
Object.keys(graphQLSchemaTypeFieldMap).forEach(graphQLSchemaTypeFieldName => {
const graphQLSchemaTypeField = graphQLSchemaTypeFieldMap[graphQLSchemaTypeFieldName];
if (!graphQLSchemaTypeField.astNode) {
const astNode = graphQLCustomTypeDef.fields.find(
field => field.name.value === graphQLSchemaTypeFieldName
);
if (astNode) {
graphQLSchemaTypeField.astNode = astNode;
}
}
});
}
}
});

SchemaDirectiveVisitor.visitSchemaDirectives(
this.graphQLSchema,
this.graphQLSchemaDirectives
);
} else {
this.graphQLSchema = this.graphQLAutoSchema;
}
Expand Down Expand Up @@ -479,7 +445,7 @@ class ParseGraphQLSchema {
return true;
} else {
this.log.warn(
`Function ${functionName} could not be added to the auto schema because GraphQL names must match /^[_a-zA-Z][_a-zA-Z0-9]*$/.`
`Function ${functionName} could not be added to the auto schema because GraphQL names must match /^ [_a - zA - Z][_a - zA - Z0 - 9] * $ /.`
);
return false;
}
Expand Down
14 changes: 8 additions & 6 deletions src/GraphQL/ParseGraphQLServer.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import corsMiddleware from 'cors';
import bodyParser from 'body-parser';
import { graphqlUploadExpress } from 'graphql-upload';
import { graphqlExpress } from 'apollo-server-express/dist/expressApollo';
import { ApolloServer } from 'apollo-server-express';
import { renderPlaygroundPage } from '@apollographql/graphql-playground-html';
import { execute, subscribe } from 'graphql';
import { SubscriptionServer } from 'subscriptions-transport-ws';
Expand Down Expand Up @@ -65,7 +65,7 @@ class ParseGraphQLServer {
);
}

applyGraphQL(app) {
async applyGraphQL(app) {
if (!app || !app.use) {
requiredParameter('You must provide an Express.js app instance!');
}
Expand All @@ -82,10 +82,12 @@ class ParseGraphQLServer {
app.use(this.config.graphQLPath, bodyParser.json());
app.use(this.config.graphQLPath, handleParseHeaders);
app.use(this.config.graphQLPath, handleParseErrors);
app.use(
this.config.graphQLPath,
graphqlExpress(async req => await this._getGraphQLOptions(req))
);
const server = new ApolloServer({ typeDefs: 'type Query { tmp: Boolean }' });
server.createGraphQLServerOptions = req => {
return this._getGraphQLOptions(req);
};
await server.start();
app.use(server.getMiddleware({ path: this.config.graphQLPath }));
}

applyPlayground(app) {
Expand Down
2 changes: 1 addition & 1 deletion src/GraphQL/helpers/objectsQueries.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ const getObject = async (
options.keys = keys;
}
} catch (e) {
console.log(e);
console.error(e);
}
if (include) {
options.include = include;
Expand Down
6 changes: 3 additions & 3 deletions src/GraphQL/loaders/defaultGraphQLTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -1206,12 +1206,12 @@ const loadArrayResult = (parseGraphQLSchema, parseClasses) => {
resolveType: value => {
if (value.__type === 'Object' && value.className && value.objectId) {
if (parseGraphQLSchema.parseClassTypes[value.className]) {
return parseGraphQLSchema.parseClassTypes[value.className].classGraphQLOutputType;
return parseGraphQLSchema.parseClassTypes[value.className].classGraphQLOutputType.name;
} else {
return ELEMENT;
return ELEMENT.name;
}
} else {
return ELEMENT;
return ELEMENT.name;
}
},
});
Expand Down
2 changes: 1 addition & 1 deletion src/GraphQL/loaders/defaultRelaySchema.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ const load = parseGraphQLSchema => {
}
},
obj => {
return parseGraphQLSchema.parseClassTypes[obj.className].classGraphQLOutputType;
return parseGraphQLSchema.parseClassTypes[obj.className].classGraphQLOutputType.name;
}
);

Expand Down
85 changes: 43 additions & 42 deletions src/GraphQL/loaders/schemaDirectives.js
Original file line number Diff line number Diff line change
@@ -1,55 +1,56 @@
import gql from 'graphql-tag';
import { SchemaDirectiveVisitor } from '@graphql-tools/utils';
import { mapSchema, getDirective, MapperKind } from '@graphql-tools/utils';
import { FunctionsRouter } from '../../Routers/FunctionsRouter';

export const definitions = gql`
export const definitions = `
directive @resolve(to: String) on FIELD_DEFINITION
directive @mock(with: Any!) on FIELD_DEFINITION
`;

const load = parseGraphQLSchema => {
parseGraphQLSchema.graphQLSchemaDirectivesDefinitions = definitions;

class ResolveDirectiveVisitor extends SchemaDirectiveVisitor {
visitFieldDefinition(field) {
field.resolve = async (_source, args, context) => {
try {
const { config, auth, info } = context;

let functionName = field.name;
if (this.args.to) {
functionName = this.args.to;
}

return (
await FunctionsRouter.handleCloudFunction({
params: {
functionName,
},
config,
auth,
info,
body: args,
})
).response.result;
} catch (e) {
parseGraphQLSchema.handleError(e);
const resolveDirective = schema =>
mapSchema(schema, {
[MapperKind.OBJECT_FIELD]: fieldConfig => {
const directive = getDirective(schema, fieldConfig, 'resolve')?.[0];
if (directive) {
const { to: targetCloudFunction } = directive;
fieldConfig.resolve = async (_source, args, context, gqlInfo) => {
try {
const { config, auth, info } = context;
const functionName = targetCloudFunction || gqlInfo.fieldName;
return (
await FunctionsRouter.handleCloudFunction({
params: {
functionName,
},
config,
auth,
info,
body: args,
})
).response.result;
} catch (e) {
parseGraphQLSchema.handleError(e);
}
};
}
};
}
}

parseGraphQLSchema.graphQLSchemaDirectives.resolve = ResolveDirectiveVisitor;

class MockDirectiveVisitor extends SchemaDirectiveVisitor {
visitFieldDefinition(field) {
field.resolve = () => {
return this.args.with;
};
}
}
return fieldConfig;
},
});

const mockDirective = schema =>
mapSchema(schema, {
[MapperKind.OBJECT_FIELD]: fieldConfig => {
const directive = getDirective(schema, fieldConfig, 'mock')?.[0];
if (directive) {
const { with: mockValue } = directive;
fieldConfig.resolve = async () => mockValue;
}
return fieldConfig;
},
});

parseGraphQLSchema.graphQLSchemaDirectives.mock = MockDirectiveVisitor;
parseGraphQLSchema.graphQLSchemaDirectives = schema => mockDirective(resolveDirective(schema));
};

export { load };
Loading

0 comments on commit 15c5631

Please sign in to comment.