Skip to content

Commit

Permalink
Added selectQueryOrMutationField option
Browse files Browse the repository at this point in the history
Signed-off-by: Tamas Geschitz <[email protected]>
  • Loading branch information
gtamas authored and Alan-Cha committed Dec 9, 2019
1 parent 4438587 commit ab3f87c
Show file tree
Hide file tree
Showing 20 changed files with 229 additions and 20 deletions.
2 changes: 2 additions & 0 deletions packages/openapi-to-graphql/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,8 @@ Schema options:

- `idFormats` (type: `string[]`): If a schema is of type string and has format UUID, it will be translated into a [GraphQL ID type](https://graphql.org/graphql-js/type/#graphqlid). To allow for more customzation, this option allows users to specify other formats that should be interpreted as ID types.

- `selectQueryOrMutationField` (type: `object`, default: `{}`): OpenAPI-to-GraphQL, by default, will make all GET operations into `Query` fields and all other operations into `Mutation` fields. This option allows users to manually override this process. The operation is identifed first by the [title](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#infoObject) of the OAS, then the [path](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#paths-object) of the operation, and lastly the [method](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#path-item-object) of the operation. The `selectQueryOrMutationField` object is thus a triply nested object where the outer key is the title, followed by the path, and finally the method, which points to an integer value of either `0`, or `1`, corresponding to `Query` or `Mutation` type respectively.

***

Resolver options:
Expand Down
1 change: 1 addition & 0 deletions packages/openapi-to-graphql/lib/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,4 @@ declare type Result = {
*/
export declare function createGraphQlSchema(spec: Oas3 | Oas2 | (Oas3 | Oas2)[], options?: Options): Promise<Result>;
export { sanitize } from './oas_3_tools';
export { GraphQLOperationType } from './types/graphql';
6 changes: 5 additions & 1 deletion packages/openapi-to-graphql/lib/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/openapi-to-graphql/lib/index.js.map

Large diffs are not rendered by default.

18 changes: 17 additions & 1 deletion packages/openapi-to-graphql/lib/preprocessor.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/openapi-to-graphql/lib/preprocessor.js.map

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions packages/openapi-to-graphql/lib/resolver_builder.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/openapi-to-graphql/lib/resolver_builder.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion packages/openapi-to-graphql/lib/schema_builder.js.map

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions packages/openapi-to-graphql/lib/types/graphql.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
* Custom type definitions for GraphQL.
*/
import { GraphQLObjectType, GraphQLScalarType, GraphQLInputObjectType, GraphQLList, GraphQLEnumType } from 'graphql';
export declare enum GraphQLOperationType {
Query = 0,
Mutation = 1
}
export declare type GraphQLType = GraphQLScalarType | GraphQLObjectType | GraphQLEnumType | GraphQLInputObjectType | GraphQLList<any>;
declare type Arg = {
type: any;
Expand Down
6 changes: 6 additions & 0 deletions packages/openapi-to-graphql/lib/types/graphql.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/openapi-to-graphql/lib/types/graphql.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 30 additions & 1 deletion packages/openapi-to-graphql/lib/types/options.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as NodeRequest from 'request';
import { ResolveFunction } from './graphql';
import { ResolveFunction, GraphQLOperationType } from './graphql';
/**
* Type definition of the options that users can pass to OpenAPI-to-GraphQL.
*/
Expand Down Expand Up @@ -58,6 +58,17 @@ export declare type Options = {
* users to specify other formats that should be interpreted as ID types.
*/
idFormats?: string[];
/**
* Allows to define the root operation type (Query or Mutation type) of any
* OAS operation explicitly.
*
* OtG will by default make all GET operations Query fields and all other
* operations into Mutation fields.
*
* The field is identifed first by the title of the OAS, then the path of the
* operation, and lastly the method of the operation.
*/
selectQueryOrMutationField?: selectQueryOrMutationFieldType;
/**
* Custom headers to send with every request made by a resolve function.
*/
Expand Down Expand Up @@ -184,6 +195,17 @@ export declare type InternalOptions = {
* users to specify other formats that should be interpreted as ID types.
*/
idFormats?: string[];
/**
* Allows to define the root operation type (Query or Mutation type) of any
* OAS operation explicitly.
*
* OtG will by default make all GET operations Query fields and all other
* operations into Mutation fields.
*
* The field is identifed first by the title of the OAS, then the path of the
* operation, and lastly the method of the operation.
*/
selectQueryOrMutationField?: selectQueryOrMutationFieldType;
/**
* Custom headers to send with every request made by a resolve function.
*/
Expand Down Expand Up @@ -265,3 +287,10 @@ export declare type InternalOptions = {
*/
equivalentToMessages: boolean;
};
export declare type selectQueryOrMutationFieldType = {
[title: string]: {
[path: string]: {
[method: string]: GraphQLOperationType;
};
};
};
6 changes: 5 additions & 1 deletion packages/openapi-to-graphql/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
import { Options, InternalOptions, Report } from './types/options'
import { Oas3 } from './types/oas3'
import { Oas2 } from './types/oas2'
import { Args, Field, GraphQLType } from './types/graphql'
import { Args, Field, GraphQLOperationType } from './types/graphql'
import { Operation } from './types/operation'
import { PreprocessingData } from './types/preprocessing_data'
import { GraphQLSchema, GraphQLObjectType } from 'graphql'
Expand Down Expand Up @@ -156,6 +156,7 @@ async function translateOpenApiToGraphQL(
fillEmptyResponses,
addLimitArgument,
idFormats,
selectQueryOrMutationField,

// Resolver options
headers,
Expand Down Expand Up @@ -190,6 +191,7 @@ async function translateOpenApiToGraphQL(
requestOptions,
baseUrl,
customResolvers,
selectQueryOrMutationField,

// Authentication options
viewer,
Expand Down Expand Up @@ -236,6 +238,7 @@ async function translateOpenApiToGraphQL(
requestOptions
)

// Check if the operation should be added as a Query or Mutation field
if (!operation.isMutation) {
let fieldName = Oas3Tools.uncapitalize(
operation.responseDefinition.otName
Expand Down Expand Up @@ -603,3 +606,4 @@ function preliminaryChecks(
}

export { sanitize } from './oas_3_tools'
export { GraphQLOperationType } from './types/graphql'
24 changes: 23 additions & 1 deletion packages/openapi-to-graphql/src/preprocessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import * as Oas3Tools from './oas_3_tools'
import * as deepEqual from 'deep-equal'
import debug from 'debug'
import { handleWarning, getCommonPropertyNames } from './utils'
import { GraphQLOperationType } from './types/graphql'

const preprocessingLog = debug('preprocessing')

Expand Down Expand Up @@ -174,7 +175,28 @@ export function preprocessOas(
const inViewer =
securityRequirements.length > 0 && data.options.viewer !== false

const isMutation = method.toLowerCase() !== 'get'
/**
* Whether the operation should be added as a Query or Mutation field.
* By default, all GET operations are Query fields and all other
* operations are Mutation fields.
*/
let isMutation = method.toLowerCase() !== 'get'

// Option selectQueryOrMutationField can override isMutation
if (
typeof options.selectQueryOrMutationField === 'object' &&
typeof options.selectQueryOrMutationField[oas.info.title] ===
'object' &&
typeof options.selectQueryOrMutationField[oas.info.title][path] ===
'object' &&
typeof options.selectQueryOrMutationField[oas.info.title][path][
method
] === 'number' // This is an TS enum, which is translated to have a integer value
) {
isMutation =
options.selectQueryOrMutationField[oas.info.title][path][method] ===
GraphQLOperationType.Mutation
}

// Store determined information for operation
const operation: Operation = {
Expand Down
6 changes: 3 additions & 3 deletions packages/openapi-to-graphql/src/resolver_builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ export function getResolver({
if (
root &&
typeof root === 'object' &&
typeof root['_openapiToGraphql'] == 'object'
typeof root['_openapiToGraphql'] === 'object'
) {
const { authHeaders, authQs, authCookie } = getAuthOptions(
operation,
Expand Down Expand Up @@ -425,7 +425,7 @@ export function getResolver({
if (
root &&
typeof root === 'object' &&
typeof root['_openapiToGraphql'] == 'object'
typeof root['_openapiToGraphql'] === 'object'
) {
Object.assign(
element['_openapiToGraphql'],
Expand All @@ -447,7 +447,7 @@ export function getResolver({
if (
root &&
typeof root === 'object' &&
typeof root['_openapiToGraphql'] == 'object'
typeof root['_openapiToGraphql'] === 'object'
) {
Object.assign(
saneData['_openapiToGraphql'],
Expand Down
6 changes: 6 additions & 0 deletions packages/openapi-to-graphql/src/types/graphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ import {
GraphQLEnumType
} from 'graphql'

export enum GraphQLOperationType {
Query,
Mutation
// TODO: Subscription
}

export type GraphQLType =
| GraphQLScalarType
| GraphQLObjectType
Expand Down
34 changes: 33 additions & 1 deletion packages/openapi-to-graphql/src/types/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

// Type imports:
import * as NodeRequest from 'request'
import { ResolveFunction } from './graphql'
import { ResolveFunction, GraphQLOperationType } from './graphql'

/**
* Type definition of the options that users can pass to OpenAPI-to-GraphQL.
Expand Down Expand Up @@ -74,6 +74,18 @@ export type Options = {
*/
idFormats?: string[]

/**
* Allows to define the root operation type (Query or Mutation type) of any
* OAS operation explicitly.
*
* OtG will by default make all GET operations Query fields and all other
* operations into Mutation fields.
*
* The field is identifed first by the title of the OAS, then the path of the
* operation, and lastly the method of the operation.
*/
selectQueryOrMutationField?: selectQueryOrMutationFieldType

// Resolver options

/**
Expand Down Expand Up @@ -216,6 +228,18 @@ export type InternalOptions = {
*/
idFormats?: string[]

/**
* Allows to define the root operation type (Query or Mutation type) of any
* OAS operation explicitly.
*
* OtG will by default make all GET operations Query fields and all other
* operations into Mutation fields.
*
* The field is identifed first by the title of the OAS, then the path of the
* operation, and lastly the method of the operation.
*/
selectQueryOrMutationField?: selectQueryOrMutationFieldType

// Resolver options

/**
Expand Down Expand Up @@ -304,3 +328,11 @@ export type InternalOptions = {
*/
equivalentToMessages: boolean
}

export type selectQueryOrMutationFieldType = {
[title: string]: {
[path: string]: {
[method: string]: GraphQLOperationType
}
}
}
Loading

0 comments on commit ab3f87c

Please sign in to comment.