Skip to content

Commit c0ff68e

Browse files
Remove support for positional args in graphql/execute/subscribe func (#2904)
Closes #2301
1 parent 0d2bd54 commit c0ff68e

File tree

6 files changed

+38
-260
lines changed

6 files changed

+38
-260
lines changed

src/__tests__/starWarsQuery-test.js

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { expect } from 'chai';
22
import { describe, it } from 'mocha';
33

4-
import { graphql, graphqlSync } from '../graphql';
4+
import { graphql } from '../graphql';
55

66
import { StarWarsSchema as schema } from './starWarsSchema';
77

@@ -26,28 +26,6 @@ describe('Star Wars Query Tests', () => {
2626
});
2727
});
2828

29-
it('Accepts positional arguments to graphql()', async () => {
30-
const source = `
31-
query HeroNameQuery {
32-
hero {
33-
name
34-
}
35-
}
36-
`;
37-
38-
const result = await graphql(schema, source);
39-
expect(result).to.deep.equal({
40-
data: {
41-
hero: {
42-
name: 'R2-D2',
43-
},
44-
},
45-
});
46-
47-
const syncResult = graphqlSync(schema, source);
48-
expect(syncResult).to.deep.equal(result);
49-
});
50-
5129
it('Allows us to query for the ID and friends of R2-D2', async () => {
5230
const source = `
5331
query HeroNameAndFriendsQuery {

src/execution/__tests__/executor-test.js

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -69,30 +69,6 @@ describe('Execute: Handles basic execution tasks', () => {
6969
);
7070
});
7171

72-
it('accepts positional arguments', () => {
73-
const schema = new GraphQLSchema({
74-
query: new GraphQLObjectType({
75-
name: 'Type',
76-
fields: {
77-
a: {
78-
type: GraphQLString,
79-
resolve(rootValue) {
80-
return rootValue;
81-
},
82-
},
83-
},
84-
}),
85-
});
86-
87-
const document = parse('{ a }');
88-
const rootValue = 'rootValue';
89-
const result = execute(schema, document, rootValue);
90-
91-
expect(result).to.deep.equal({
92-
data: { a: 'rootValue' },
93-
});
94-
});
95-
9672
it('executes arbitrary code', async () => {
9773
const data = {
9874
a: () => 'Apple',

src/execution/execute.js

Lines changed: 17 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -146,67 +146,8 @@ export type ExecutionArgs = {|
146146
*
147147
* If the arguments to this function do not result in a legal execution context,
148148
* a GraphQLError will be thrown immediately explaining the invalid input.
149-
*
150-
* Accepts either an object with named arguments, or individual arguments.
151-
*/
152-
declare function execute(
153-
ExecutionArgs,
154-
..._: []
155-
): PromiseOrValue<ExecutionResult>;
156-
/* eslint-disable no-redeclare */
157-
declare function execute(
158-
schema: GraphQLSchema,
159-
document: DocumentNode,
160-
rootValue?: mixed,
161-
contextValue?: mixed,
162-
variableValues?: ?{ +[variable: string]: mixed, ... },
163-
operationName?: ?string,
164-
fieldResolver?: ?GraphQLFieldResolver<any, any>,
165-
typeResolver?: ?GraphQLTypeResolver<any, any>,
166-
): PromiseOrValue<ExecutionResult>;
167-
export function execute(
168-
argsOrSchema,
169-
document,
170-
rootValue,
171-
contextValue,
172-
variableValues,
173-
operationName,
174-
fieldResolver,
175-
typeResolver,
176-
) {
177-
/* eslint-enable no-redeclare */
178-
// Extract arguments from object args if provided.
179-
return arguments.length === 1
180-
? executeImpl(argsOrSchema)
181-
: executeImpl({
182-
schema: argsOrSchema,
183-
document,
184-
rootValue,
185-
contextValue,
186-
variableValues,
187-
operationName,
188-
fieldResolver,
189-
typeResolver,
190-
});
191-
}
192-
193-
/**
194-
* Also implements the "Evaluating requests" section of the GraphQL specification.
195-
* However, it guarantees to complete synchronously (or throw an error) assuming
196-
* that all field resolvers are also synchronous.
197149
*/
198-
export function executeSync(args: ExecutionArgs): ExecutionResult {
199-
const result = executeImpl(args);
200-
201-
// Assert that the execution was synchronous.
202-
if (isPromise(result)) {
203-
throw new Error('GraphQL execution failed to complete synchronously.');
204-
}
205-
206-
return result;
207-
}
208-
209-
function executeImpl(args: ExecutionArgs): PromiseOrValue<ExecutionResult> {
150+
export function execute(args: ExecutionArgs): PromiseOrValue<ExecutionResult> {
210151
const {
211152
schema,
212153
document,
@@ -250,6 +191,22 @@ function executeImpl(args: ExecutionArgs): PromiseOrValue<ExecutionResult> {
250191
return buildResponse(exeContext, data);
251192
}
252193

194+
/**
195+
* Also implements the "Evaluating requests" section of the GraphQL specification.
196+
* However, it guarantees to complete synchronously (or throw an error) assuming
197+
* that all field resolvers are also synchronous.
198+
*/
199+
export function executeSync(args: ExecutionArgs): ExecutionResult {
200+
const result = execute(args);
201+
202+
// Assert that the execution was synchronous.
203+
if (isPromise(result)) {
204+
throw new Error('GraphQL execution failed to complete synchronously.');
205+
}
206+
207+
return result;
208+
}
209+
253210
/**
254211
* Given a completed execution context and data, build the { errors, data }
255212
* response defined by the "Response" section of the GraphQL specification.

src/graphql.js

Lines changed: 5 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -65,47 +65,10 @@ export type GraphQLArgs = {|
6565
fieldResolver?: ?GraphQLFieldResolver<any, any>,
6666
typeResolver?: ?GraphQLTypeResolver<any, any>,
6767
|};
68-
declare function graphql(GraphQLArgs, ..._: []): Promise<ExecutionResult>;
69-
/* eslint-disable no-redeclare */
70-
declare function graphql(
71-
schema: GraphQLSchema,
72-
source: Source | string,
73-
rootValue?: mixed,
74-
contextValue?: mixed,
75-
variableValues?: ?{ +[variable: string]: mixed, ... },
76-
operationName?: ?string,
77-
fieldResolver?: ?GraphQLFieldResolver<any, any>,
78-
typeResolver?: ?GraphQLTypeResolver<any, any>,
79-
): Promise<ExecutionResult>;
80-
export function graphql(
81-
argsOrSchema,
82-
source,
83-
rootValue,
84-
contextValue,
85-
variableValues,
86-
operationName,
87-
fieldResolver,
88-
typeResolver,
89-
) {
90-
/* eslint-enable no-redeclare */
68+
69+
export function graphql(args: GraphQLArgs): Promise<ExecutionResult> {
9170
// Always return a Promise for a consistent API.
92-
return new Promise((resolve) =>
93-
resolve(
94-
// Extract arguments from object args if provided.
95-
arguments.length === 1
96-
? graphqlImpl(argsOrSchema)
97-
: graphqlImpl({
98-
schema: argsOrSchema,
99-
source,
100-
rootValue,
101-
contextValue,
102-
variableValues,
103-
operationName,
104-
fieldResolver,
105-
typeResolver,
106-
}),
107-
),
108-
);
71+
return new Promise((resolve) => resolve(graphqlImpl(args)));
10972
}
11073

11174
/**
@@ -114,43 +77,8 @@ export function graphql(
11477
* However, it guarantees to complete synchronously (or throw an error) assuming
11578
* that all field resolvers are also synchronous.
11679
*/
117-
declare function graphqlSync(GraphQLArgs, ..._: []): ExecutionResult;
118-
/* eslint-disable no-redeclare */
119-
declare function graphqlSync(
120-
schema: GraphQLSchema,
121-
source: Source | string,
122-
rootValue?: mixed,
123-
contextValue?: mixed,
124-
variableValues?: ?{ +[variable: string]: mixed, ... },
125-
operationName?: ?string,
126-
fieldResolver?: ?GraphQLFieldResolver<any, any>,
127-
typeResolver?: ?GraphQLTypeResolver<any, any>,
128-
): ExecutionResult;
129-
export function graphqlSync(
130-
argsOrSchema,
131-
source,
132-
rootValue,
133-
contextValue,
134-
variableValues,
135-
operationName,
136-
fieldResolver,
137-
typeResolver,
138-
) {
139-
/* eslint-enable no-redeclare */
140-
// Extract arguments from object args if provided.
141-
const result =
142-
arguments.length === 1
143-
? graphqlImpl(argsOrSchema)
144-
: graphqlImpl({
145-
schema: argsOrSchema,
146-
source,
147-
rootValue,
148-
contextValue,
149-
variableValues,
150-
operationName,
151-
fieldResolver,
152-
typeResolver,
153-
});
80+
export function graphqlSync(args: GraphQLArgs): ExecutionResult {
81+
const result = graphqlImpl(args);
15482

15583
// Assert that the execution was synchronous.
15684
if (isPromise(result)) {

src/subscription/__tests__/subscribe-test.js

Lines changed: 3 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -152,26 +152,6 @@ async function expectPromiseToThrow(
152152

153153
// Check all error cases when initializing the subscription.
154154
describe('Subscription Initialization Phase', () => {
155-
it('accepts positional arguments', async () => {
156-
const document = parse(`
157-
subscription {
158-
importantEmail
159-
}
160-
`);
161-
162-
async function* emptyAsyncIterator() {
163-
// Empty
164-
}
165-
166-
// $FlowFixMe[incompatible-call]
167-
const ai = await subscribe(emailSchema, document, {
168-
importantEmail: emptyAsyncIterator,
169-
});
170-
171-
ai.next();
172-
ai.return();
173-
});
174-
175155
it('accepts multiple subscription fields defined in schema', async () => {
176156
const pubsub = new SimplePubSub();
177157
const SubscriptionTypeMultiple = new GraphQLObjectType({
@@ -328,7 +308,7 @@ describe('Subscription Initialization Phase', () => {
328308
);
329309

330310
await expectPromiseToThrow(
331-
// $FlowExpectedError[incompatible-call]
311+
// $FlowExpectedError[prop-missing]
332312
() => subscribe({ document }),
333313
'Expected undefined to be a GraphQL schema.',
334314
);
@@ -342,7 +322,7 @@ describe('Subscription Initialization Phase', () => {
342322
);
343323

344324
await expectPromiseToThrow(
345-
// $FlowExpectedError[incompatible-call]
325+
// $FlowExpectedError[prop-missing]
346326
() => subscribe({ schema: emailSchema }),
347327
'Must provide document.',
348328
);
@@ -371,7 +351,7 @@ describe('Subscription Initialization Phase', () => {
371351
it('should pass through unexpected errors thrown in subscribe', async () => {
372352
let expectedError;
373353
try {
374-
// $FlowExpectedError[incompatible-call]
354+
// $FlowExpectedError[prop-missing]
375355
await subscribe({ schema: emailSchema, document: {} });
376356
} catch (error) {
377357
expectedError = error;

src/subscription/subscribe.js

Lines changed: 12 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -57,60 +57,7 @@ export type SubscriptionArgs = {|
5757
*
5858
* Accepts either an object with named arguments, or individual arguments.
5959
*/
60-
declare function subscribe(
61-
SubscriptionArgs,
62-
..._: []
63-
): Promise<AsyncGenerator<ExecutionResult, void, void> | ExecutionResult>;
64-
/* eslint-disable no-redeclare */
65-
declare function subscribe(
66-
schema: GraphQLSchema,
67-
document: DocumentNode,
68-
rootValue?: mixed,
69-
contextValue?: mixed,
70-
variableValues?: ?{ +[variable: string]: mixed, ... },
71-
operationName?: ?string,
72-
fieldResolver?: ?GraphQLFieldResolver<any, any>,
73-
subscribeFieldResolver?: ?GraphQLFieldResolver<any, any>,
74-
): Promise<AsyncIterator<ExecutionResult> | ExecutionResult>;
7560
export function subscribe(
76-
argsOrSchema,
77-
document,
78-
rootValue,
79-
contextValue,
80-
variableValues,
81-
operationName,
82-
fieldResolver,
83-
subscribeFieldResolver,
84-
) {
85-
/* eslint-enable no-redeclare */
86-
// Extract arguments from object args if provided.
87-
return arguments.length === 1
88-
? subscribeImpl(argsOrSchema)
89-
: subscribeImpl({
90-
schema: argsOrSchema,
91-
document,
92-
rootValue,
93-
contextValue,
94-
variableValues,
95-
operationName,
96-
fieldResolver,
97-
subscribeFieldResolver,
98-
});
99-
}
100-
101-
/**
102-
* This function checks if the error is a GraphQLError. If it is, report it as
103-
* an ExecutionResult, containing only errors and no data. Otherwise treat the
104-
* error as a system-class error and re-throw it.
105-
*/
106-
function reportGraphQLError(error: mixed): ExecutionResult {
107-
if (error instanceof GraphQLError) {
108-
return { errors: [error] };
109-
}
110-
throw error;
111-
}
112-
113-
function subscribeImpl(
11461
args: SubscriptionArgs,
11562
): Promise<AsyncGenerator<ExecutionResult, void, void> | ExecutionResult> {
11663
const {
@@ -165,6 +112,18 @@ function subscribeImpl(
165112
);
166113
}
167114

115+
/**
116+
* This function checks if the error is a GraphQLError. If it is, report it as
117+
* an ExecutionResult, containing only errors and no data. Otherwise treat the
118+
* error as a system-class error and re-throw it.
119+
*/
120+
function reportGraphQLError(error: mixed): ExecutionResult {
121+
if (error instanceof GraphQLError) {
122+
return { errors: [error] };
123+
}
124+
throw error;
125+
}
126+
168127
/**
169128
* Implements the "CreateSourceEventStream" algorithm described in the
170129
* GraphQL specification, resolving the subscription source event stream.

0 commit comments

Comments
 (0)