Skip to content

Commit 15c5631

Browse files
committed
feat: update gql dep
1 parent b84acd5 commit 15c5631

10 files changed

+349
-1079
lines changed

package-lock.json

+237-940
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+9-8
Original file line numberDiff line numberDiff line change
@@ -21,24 +21,24 @@
2121
"dependencies": {
2222
"@apollo/client": "3.5.10",
2323
"@apollographql/graphql-playground-html": "1.6.29",
24-
"@graphql-tools/links": "8.2.9",
25-
"@graphql-tools/stitch": "6.2.4",
26-
"@graphql-tools/utils": "6.2.4",
24+
"@graphql-tools/links": "8.2.14",
25+
"@graphql-tools/merge": "8.2.10",
26+
"@graphql-tools/schema": "8.3.10",
27+
"@graphql-tools/utils": "8.6.9",
2728
"@parse/fs-files-adapter": "1.2.2",
2829
"@parse/push-adapter": "4.1.2",
29-
"apollo-server-express": "2.25.2",
30+
"apollo-server-express": "3.6.7",
3031
"bcryptjs": "2.4.3",
3132
"body-parser": "1.20.0",
3233
"commander": "5.1.0",
3334
"cors": "2.8.5",
3435
"deepcopy": "2.1.0",
3536
"express": "4.17.2",
3637
"follow-redirects": "1.14.9",
37-
"graphql": "15.8.0",
38+
"graphql": "16.4.0",
3839
"graphql-list-fields": "2.0.2",
39-
"graphql-relay": "0.7.0",
40-
"graphql-tag": "2.12.6",
41-
"graphql-upload": "11.0.0",
40+
"graphql-relay": "0.10.0",
41+
"graphql-upload": "13.0.0",
4242
"intersect": "1.0.1",
4343
"jsonwebtoken": "8.5.1",
4444
"jwks-rsa": "2.0.5",
@@ -62,6 +62,7 @@
6262
"ws": "8.2.3"
6363
},
6464
"devDependencies": {
65+
"graphql-tag": "2.12.6",
6566
"@actions/core": "1.2.6",
6667
"@babel/cli": "7.10.0",
6768
"@babel/core": "7.10.0",

spec/ParseGraphQLServer.spec.js

+24-21
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const { getMainDefinition } = require('apollo-utilities');
1212
const { createUploadLink } = require('apollo-upload-client');
1313
const { SubscriptionClient } = require('subscriptions-transport-ws');
1414
const { WebSocketLink } = require('@apollo/client/link/ws');
15+
const { mergeSchemas } = require('@graphql-tools/schema');
1516
const {
1617
ApolloClient,
1718
InMemoryCache,
@@ -133,28 +134,31 @@ describe('ParseGraphQLServer', () => {
133134
});
134135

135136
describe('applyGraphQL', () => {
136-
it('should require an Express.js app instance', () => {
137-
expect(() => parseGraphQLServer.applyGraphQL()).toThrow(
137+
it('should require an Express.js app instance', async () => {
138+
await expectAsync(parseGraphQLServer.applyGraphQL()).toBeRejectedWith(
138139
'You must provide an Express.js app instance!'
139140
);
140-
expect(() => parseGraphQLServer.applyGraphQL({})).toThrow(
141+
await expectAsync(parseGraphQLServer.applyGraphQL({})).toBeRejectedWith(
141142
'You must provide an Express.js app instance!'
142143
);
143-
expect(() => parseGraphQLServer.applyGraphQL(new express())).not.toThrow();
144+
await expectAsync(parseGraphQLServer.applyGraphQL(new express())).toBeResolved();
144145
});
145146

146-
it('should apply middlewares at config.graphQLPath', () => {
147+
it('should apply middlewares at config.graphQLPath', async () => {
147148
let useCount = 0;
148-
expect(() =>
149-
new ParseGraphQLServer(parseServer, {
150-
graphQLPath: 'somepath',
151-
}).applyGraphQL({
152-
use: path => {
153-
useCount++;
154-
expect(path).toEqual('somepath');
155-
},
156-
})
157-
).not.toThrow();
149+
const gqlServer = new ParseGraphQLServer(parseServer, {
150+
graphQLPath: 'somepath',
151+
});
152+
gqlServer.applyGraphQL({
153+
use: server => {
154+
useCount++;
155+
if (typeof server === 'string') {
156+
expect(server).toEqual('somepath');
157+
} else {
158+
expect(server.stack[1].regexp.toString()).toEqual('/^somepath\\/?(?=\\/|$)/i');
159+
}
160+
},
161+
});
158162
expect(useCount).toBeGreaterThan(0);
159163
});
160164
});
@@ -7697,8 +7701,8 @@ describe('ParseGraphQLServer', () => {
76977701
.map(call => call.args[0])
76987702
.sort()
76997703
).toEqual([
7700-
'Function 1NumberInTheBeggning could not be added to the auto schema because GraphQL names must match /^[_a-zA-Z][_a-zA-Z0-9]*$/.',
7701-
'Function double-barrelled could not be added to the auto schema because GraphQL names must match /^[_a-zA-Z][_a-zA-Z0-9]*$/.',
7704+
'Function 1NumberInTheBeggning could not be added to the auto schema because GraphQL names must match /^ [_a - zA - Z][_a - zA - Z0 - 9] * $ /.',
7705+
'Function double-barrelled could not be added to the auto schema because GraphQL names must match /^ [_a - zA - Z][_a - zA - Z0 - 9] * $ /.',
77027706
]);
77037707
} catch (e) {
77047708
handleError(e);
@@ -10381,7 +10385,7 @@ describe('ParseGraphQLServer', () => {
1038110385
});
1038210386

1038310387
describe('Custom API', () => {
10384-
describe('GraphQL Schema Based', () => {
10388+
describe('SDL based', () => {
1038510389
let httpServer;
1038610390
const headers = {
1038710391
'X-Parse-Application-Id': 'test',
@@ -10504,7 +10508,7 @@ describe('ParseGraphQLServer', () => {
1050410508
});
1050510509
});
1050610510

10507-
describe('SDL Based', () => {
10511+
describe('GraphQL Schema Based', () => {
1050810512
let httpServer;
1050910513
const headers = {
1051010514
'X-Parse-Application-Id': 'test',
@@ -10801,8 +10805,7 @@ describe('ParseGraphQLServer', () => {
1080110805
httpServer = http.createServer(expressApp);
1080210806
parseGraphQLServer = new ParseGraphQLServer(parseServer, {
1080310807
graphQLPath: '/graphql',
10804-
graphQLCustomTypeDefs: ({ autoSchema, stitchSchemas }) =>
10805-
stitchSchemas({ subschemas: [autoSchema] }),
10808+
graphQLCustomTypeDefs: ({ autoSchema }) => mergeSchemas({ schemas: [autoSchema] }),
1080610809
});
1080710810

1080810811
parseGraphQLServer.applyGraphQL(expressApp);

src/GraphQL/ParseGraphQLSchema.js

+10-44
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import Parse from 'parse/node';
22
import { GraphQLSchema, GraphQLObjectType, DocumentNode, GraphQLNamedType } from 'graphql';
3-
import { stitchSchemas } from '@graphql-tools/stitch';
3+
import { mergeSchemas } from '@graphql-tools/schema';
4+
import { mergeTypeDefs } from '@graphql-tools/merge';
45
import { isDeepStrictEqual } from 'util';
5-
import { SchemaDirectiveVisitor } from '@graphql-tools/utils';
66
import requiredParameter from '../requiredParameter';
77
import * as defaultGraphQLTypes from './loaders/defaultGraphQLTypes';
88
import * as parseClassTypes from './loaders/parseClassTypes';
@@ -198,7 +198,6 @@ class ParseGraphQLSchema {
198198

199199
if (this.graphQLCustomTypeDefs) {
200200
schemaDirectives.load(this);
201-
202201
if (typeof this.graphQLCustomTypeDefs.getTypeMap === 'function') {
203202
// In following code we use underscore attr to avoid js var un ref
204203
const customGraphQLSchemaTypeMap = this.graphQLCustomTypeDefs._typeMap;
@@ -275,51 +274,18 @@ class ParseGraphQLSchema {
275274
this.graphQLSchema = await this.graphQLCustomTypeDefs({
276275
directivesDefinitionsSchema: this.graphQLSchemaDirectivesDefinitions,
277276
autoSchema: this.graphQLAutoSchema,
278-
stitchSchemas,
277+
graphQLSchemaDirectives: this.graphQLSchemaDirectives,
279278
});
280279
} else {
281-
this.graphQLSchema = stitchSchemas({
282-
schemas: [
283-
this.graphQLSchemaDirectivesDefinitions,
284-
this.graphQLAutoSchema,
280+
this.graphQLSchema = mergeSchemas({
281+
schemas: [this.graphQLAutoSchema],
282+
typeDefs: mergeTypeDefs([
285283
this.graphQLCustomTypeDefs,
286-
],
287-
mergeDirectives: true,
284+
this.graphQLSchemaDirectivesDefinitions,
285+
]),
288286
});
287+
this.graphQLSchema = this.graphQLSchemaDirectives(this.graphQLSchema);
289288
}
290-
291-
// Only merge directive when string schema provided
292-
const graphQLSchemaTypeMap = this.graphQLSchema.getTypeMap();
293-
Object.keys(graphQLSchemaTypeMap).forEach(graphQLSchemaTypeName => {
294-
const graphQLSchemaType = graphQLSchemaTypeMap[graphQLSchemaTypeName];
295-
if (
296-
typeof graphQLSchemaType.getFields === 'function' &&
297-
this.graphQLCustomTypeDefs.definitions
298-
) {
299-
const graphQLCustomTypeDef = this.graphQLCustomTypeDefs.definitions.find(
300-
definition => definition.name.value === graphQLSchemaTypeName
301-
);
302-
if (graphQLCustomTypeDef) {
303-
const graphQLSchemaTypeFieldMap = graphQLSchemaType.getFields();
304-
Object.keys(graphQLSchemaTypeFieldMap).forEach(graphQLSchemaTypeFieldName => {
305-
const graphQLSchemaTypeField = graphQLSchemaTypeFieldMap[graphQLSchemaTypeFieldName];
306-
if (!graphQLSchemaTypeField.astNode) {
307-
const astNode = graphQLCustomTypeDef.fields.find(
308-
field => field.name.value === graphQLSchemaTypeFieldName
309-
);
310-
if (astNode) {
311-
graphQLSchemaTypeField.astNode = astNode;
312-
}
313-
}
314-
});
315-
}
316-
}
317-
});
318-
319-
SchemaDirectiveVisitor.visitSchemaDirectives(
320-
this.graphQLSchema,
321-
this.graphQLSchemaDirectives
322-
);
323289
} else {
324290
this.graphQLSchema = this.graphQLAutoSchema;
325291
}
@@ -479,7 +445,7 @@ class ParseGraphQLSchema {
479445
return true;
480446
} else {
481447
this.log.warn(
482-
`Function ${functionName} could not be added to the auto schema because GraphQL names must match /^[_a-zA-Z][_a-zA-Z0-9]*$/.`
448+
`Function ${functionName} could not be added to the auto schema because GraphQL names must match /^ [_a - zA - Z][_a - zA - Z0 - 9] * $ /.`
483449
);
484450
return false;
485451
}

src/GraphQL/ParseGraphQLServer.js

+8-6
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import corsMiddleware from 'cors';
22
import bodyParser from 'body-parser';
33
import { graphqlUploadExpress } from 'graphql-upload';
4-
import { graphqlExpress } from 'apollo-server-express/dist/expressApollo';
4+
import { ApolloServer } from 'apollo-server-express';
55
import { renderPlaygroundPage } from '@apollographql/graphql-playground-html';
66
import { execute, subscribe } from 'graphql';
77
import { SubscriptionServer } from 'subscriptions-transport-ws';
@@ -65,7 +65,7 @@ class ParseGraphQLServer {
6565
);
6666
}
6767

68-
applyGraphQL(app) {
68+
async applyGraphQL(app) {
6969
if (!app || !app.use) {
7070
requiredParameter('You must provide an Express.js app instance!');
7171
}
@@ -82,10 +82,12 @@ class ParseGraphQLServer {
8282
app.use(this.config.graphQLPath, bodyParser.json());
8383
app.use(this.config.graphQLPath, handleParseHeaders);
8484
app.use(this.config.graphQLPath, handleParseErrors);
85-
app.use(
86-
this.config.graphQLPath,
87-
graphqlExpress(async req => await this._getGraphQLOptions(req))
88-
);
85+
const server = new ApolloServer({ typeDefs: 'type Query { tmp: Boolean }' });
86+
server.createGraphQLServerOptions = req => {
87+
return this._getGraphQLOptions(req);
88+
};
89+
await server.start();
90+
app.use(server.getMiddleware({ path: this.config.graphQLPath }));
8991
}
9092

9193
applyPlayground(app) {

src/GraphQL/helpers/objectsQueries.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ const getObject = async (
5858
options.keys = keys;
5959
}
6060
} catch (e) {
61-
console.log(e);
61+
console.error(e);
6262
}
6363
if (include) {
6464
options.include = include;

src/GraphQL/loaders/defaultGraphQLTypes.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -1206,12 +1206,12 @@ const loadArrayResult = (parseGraphQLSchema, parseClasses) => {
12061206
resolveType: value => {
12071207
if (value.__type === 'Object' && value.className && value.objectId) {
12081208
if (parseGraphQLSchema.parseClassTypes[value.className]) {
1209-
return parseGraphQLSchema.parseClassTypes[value.className].classGraphQLOutputType;
1209+
return parseGraphQLSchema.parseClassTypes[value.className].classGraphQLOutputType.name;
12101210
} else {
1211-
return ELEMENT;
1211+
return ELEMENT.name;
12121212
}
12131213
} else {
1214-
return ELEMENT;
1214+
return ELEMENT.name;
12151215
}
12161216
},
12171217
});

src/GraphQL/loaders/defaultRelaySchema.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ const load = parseGraphQLSchema => {
3939
}
4040
},
4141
obj => {
42-
return parseGraphQLSchema.parseClassTypes[obj.className].classGraphQLOutputType;
42+
return parseGraphQLSchema.parseClassTypes[obj.className].classGraphQLOutputType.name;
4343
}
4444
);
4545

+43-42
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,56 @@
1-
import gql from 'graphql-tag';
2-
import { SchemaDirectiveVisitor } from '@graphql-tools/utils';
1+
import { mapSchema, getDirective, MapperKind } from '@graphql-tools/utils';
32
import { FunctionsRouter } from '../../Routers/FunctionsRouter';
43

5-
export const definitions = gql`
4+
export const definitions = `
65
directive @resolve(to: String) on FIELD_DEFINITION
76
directive @mock(with: Any!) on FIELD_DEFINITION
87
`;
98

109
const load = parseGraphQLSchema => {
1110
parseGraphQLSchema.graphQLSchemaDirectivesDefinitions = definitions;
1211

13-
class ResolveDirectiveVisitor extends SchemaDirectiveVisitor {
14-
visitFieldDefinition(field) {
15-
field.resolve = async (_source, args, context) => {
16-
try {
17-
const { config, auth, info } = context;
18-
19-
let functionName = field.name;
20-
if (this.args.to) {
21-
functionName = this.args.to;
22-
}
23-
24-
return (
25-
await FunctionsRouter.handleCloudFunction({
26-
params: {
27-
functionName,
28-
},
29-
config,
30-
auth,
31-
info,
32-
body: args,
33-
})
34-
).response.result;
35-
} catch (e) {
36-
parseGraphQLSchema.handleError(e);
12+
const resolveDirective = schema =>
13+
mapSchema(schema, {
14+
[MapperKind.OBJECT_FIELD]: fieldConfig => {
15+
const directive = getDirective(schema, fieldConfig, 'resolve')?.[0];
16+
if (directive) {
17+
const { to: targetCloudFunction } = directive;
18+
fieldConfig.resolve = async (_source, args, context, gqlInfo) => {
19+
try {
20+
const { config, auth, info } = context;
21+
const functionName = targetCloudFunction || gqlInfo.fieldName;
22+
return (
23+
await FunctionsRouter.handleCloudFunction({
24+
params: {
25+
functionName,
26+
},
27+
config,
28+
auth,
29+
info,
30+
body: args,
31+
})
32+
).response.result;
33+
} catch (e) {
34+
parseGraphQLSchema.handleError(e);
35+
}
36+
};
3737
}
38-
};
39-
}
40-
}
41-
42-
parseGraphQLSchema.graphQLSchemaDirectives.resolve = ResolveDirectiveVisitor;
43-
44-
class MockDirectiveVisitor extends SchemaDirectiveVisitor {
45-
visitFieldDefinition(field) {
46-
field.resolve = () => {
47-
return this.args.with;
48-
};
49-
}
50-
}
38+
return fieldConfig;
39+
},
40+
});
41+
42+
const mockDirective = schema =>
43+
mapSchema(schema, {
44+
[MapperKind.OBJECT_FIELD]: fieldConfig => {
45+
const directive = getDirective(schema, fieldConfig, 'mock')?.[0];
46+
if (directive) {
47+
const { with: mockValue } = directive;
48+
fieldConfig.resolve = async () => mockValue;
49+
}
50+
return fieldConfig;
51+
},
52+
});
5153

52-
parseGraphQLSchema.graphQLSchemaDirectives.mock = MockDirectiveVisitor;
54+
parseGraphQLSchema.graphQLSchemaDirectives = schema => mockDirective(resolveDirective(schema));
5355
};
54-
5556
export { load };

0 commit comments

Comments
 (0)