Skip to content
This repository has been archived by the owner on Dec 8, 2021. It is now read-only.

Interface and union resolvers #149

Merged
merged 21 commits into from
Jan 20, 2019
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 39 additions & 5 deletions packages/graphqlgen/src/generators/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import * as os from 'os'

import {
GraphQLTypeObject,
GraphQLType,
GraphQLTypeField,
getGraphQLEnumValues,
GraphQLTypeDefinition,
} from '../source-helper'
import { ModelMap, ContextDefinition, GenerateArgs, Model } from '../types'
import { flatten, uniq } from '../utils'
Expand All @@ -30,6 +30,14 @@ export interface TypeToInputTypeAssociation {
[objectTypeName: string]: string[]
}

export interface InterfacesMap {
[interfaceName: string]: GraphQLTypeDefinition[]
}

export interface UnionsMap {
[unionName: string]: GraphQLTypeDefinition[]
}

export function fieldsFromModelDefinition(
modelDef: TypeDefinition,
): FieldDefinition[] {
Expand Down Expand Up @@ -116,7 +124,7 @@ export function getContextName(context?: ContextDefinition) {
}

export function getModelName(
type: GraphQLType,
type: GraphQLTypeDefinition,
modelMap: ModelMap,
emptyType: string = '{}',
): string {
Expand Down Expand Up @@ -192,6 +200,8 @@ export function shouldScaffoldFieldResolver(
export function printFieldLikeType(
field: GraphQLTypeField,
modelMap: ModelMap,
interfacesMap: InterfacesMap,
unionsMap: UnionsMap,
) {
if (field.type.isScalar) {
return `${getTypeFromGraphQLType(field.type.name)}${
Expand All @@ -205,6 +215,28 @@ export function printFieldLikeType(
}`
}

if (field.type.isInterface) {
let types = interfacesMap[field.type.name]
.map(type => getModelName(type, modelMap))
.filter(uniq)
.join(' | ')
if (field.type.isArray) {
types = `Array<${types}>`
}
return `${types}${!field.type.isRequired ? '| null' : ''}`
jasonkuhrt marked this conversation as resolved.
Show resolved Hide resolved
}

if (field.type.isUnion) {
let types = unionsMap[field.type.name]
.map(type => getModelName(type, modelMap))
.filter(uniq)
.join(' | ')
if (field.type.isArray) {
types = `Array<${types}>`
jasonkuhrt marked this conversation as resolved.
Show resolved Hide resolved
}
return `${types}${!field.type.isRequired ? '| null' : ''}`
}

return `${getModelName(field.type, modelMap)}${
field.type.isArray ? '[]' : ''
}${!field.type.isRequired ? '| null' : ''}`
Expand Down Expand Up @@ -274,11 +306,13 @@ export function isParentType(name: string) {

export function groupModelsNameByImportPath(models: Model[]) {
return models.reduce<{ [importPath: string]: string[] }>((acc, model) => {
if (acc[model.importPathRelativeToOutput] === undefined) {
acc[model.importPathRelativeToOutput] = []
const fileModels = acc[model.importPathRelativeToOutput] || []

if (fileModels.indexOf(model.definition.name) === -1) {
fileModels.push(model.definition.name)
}

acc[model.importPathRelativeToOutput].push(model.definition.name)
acc[model.importPathRelativeToOutput] = fileModels

return acc
}, {})
Expand Down
135 changes: 120 additions & 15 deletions packages/graphqlgen/src/generators/flow-generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import {
renderDefaultResolvers,
renderEnums,
TypeToInputTypeAssociation,
InterfacesMap,
UnionsMap,
} from './common'

export function format(code: string, options: prettier.Options = {}) {
Expand Down Expand Up @@ -65,12 +67,35 @@ export function generate(args: GenerateArgs): string {
}
}, {})

const interfacesMap: InterfacesMap = args.interfaces.reduce(
(interfaces, int) => {
return {
...interfaces,
[int.name]: int.types,
}
},
{},
)

const unionsMap: InterfacesMap = args.unions.reduce((interfaces, int) => {
jasonkuhrt marked this conversation as resolved.
Show resolved Hide resolved
return {
...interfaces,
[int.name]: int.types,
}
}, {})

return `\
${renderHeader(args)}

${renderEnums(args)}

${renderNamespaces(args, typeToInputTypeAssociation, inputTypesMap)}
${renderNamespaces(
args,
interfacesMap,
unionsMap,
typeToInputTypeAssociation,
inputTypesMap,
)}

${renderResolvers(args)}

Expand Down Expand Up @@ -111,19 +136,30 @@ function renderContext(context?: ContextDefinition) {

function renderNamespaces(
args: GenerateArgs,
interfacesMap: InterfacesMap,
unionsMap: UnionsMap,
typeToInputTypeAssociation: TypeToInputTypeAssociation,
inputTypesMap: InputTypesMap,
): string {
return args.types
.filter(type => type.type.isObject)
.map(type =>
renderNamespace(type, typeToInputTypeAssociation, inputTypesMap, args),
renderNamespace(
type,
interfacesMap,
unionsMap,
typeToInputTypeAssociation,
inputTypesMap,
args,
),
)
.join(os.EOL)
}

function renderNamespace(
type: GraphQLTypeObject,
interfacesMap: InterfacesMap,
unionsMap: UnionsMap,
typeToInputTypeAssociation: TypeToInputTypeAssociation,
inputTypesMap: InputTypesMap,
args: GenerateArgs,
Expand All @@ -137,15 +173,29 @@ function renderNamespace(
${renderInputTypeInterfaces(
type,
args.modelMap,
interfacesMap,
unionsMap,
typeToInputTypeAssociation,
inputTypesMap,
)}

${renderInputArgInterfaces(type, args.modelMap)}
${renderInputArgInterfaces(type, args.modelMap, interfacesMap, unionsMap)}

${renderResolverFunctionInterfaces(type, args.modelMap, args.context)}
${renderResolverFunctionInterfaces(
type,
args.modelMap,
interfacesMap,
unionsMap,
args.context,
)}

${renderResolverTypeInterface(type, args.modelMap, args.context)}
${renderResolverTypeInterface(
type,
args.modelMap,
interfacesMap,
unionsMap,
args.context,
)}

${/* TODO renderResolverClass(type, modelMap) */ ''}
`
Expand All @@ -154,6 +204,8 @@ function renderNamespace(
function renderInputTypeInterfaces(
type: GraphQLTypeObject,
modelMap: ModelMap,
interfacesMap: InterfacesMap,
unionsMap: UnionsMap,
typeToInputTypeAssociation: TypeToInputTypeAssociation,
inputTypesMap: InputTypesMap,
) {
Expand All @@ -167,7 +219,13 @@ function renderInputTypeInterfaces(
inputTypesMap[typeAssociation].name,
)} {
${inputTypesMap[typeAssociation].fields.map(
field => `${field.name}: ${printFieldLikeType(field, modelMap)}`,
field =>
`${field.name}: ${printFieldLikeType(
field,
modelMap,
interfacesMap,
unionsMap,
)}`,
)}
}`
})
Expand All @@ -177,16 +235,22 @@ function renderInputTypeInterfaces(
function renderInputArgInterfaces(
type: GraphQLTypeObject,
modelMap: ModelMap,
interfacesMap: InterfacesMap,
unionsMap: UnionsMap,
): string {
return type.fields
.map(field => renderInputArgInterface(type, field, modelMap))
.map(field =>
renderInputArgInterface(type, field, modelMap, interfacesMap, unionsMap),
)
.join(os.EOL)
}

function renderInputArgInterface(
type: GraphQLTypeObject,
field: GraphQLTypeField,
modelMap: ModelMap,
interfacesMap: InterfacesMap,
unionsMap: UnionsMap,
): string {
if (field.arguments.length === 0) {
return ''
Expand All @@ -200,6 +264,8 @@ function renderInputArgInterface(
`${arg.name}: ${printFieldLikeType(
arg as GraphQLTypeField,
modelMap,
interfacesMap,
unionsMap,
)}`,
)
.join(',' + os.EOL)}
Expand All @@ -210,11 +276,20 @@ function renderInputArgInterface(
function renderResolverFunctionInterfaces(
type: GraphQLTypeObject,
modelMap: ModelMap,
interfacesMap: InterfacesMap,
unionsMap: UnionsMap,
context?: ContextDefinition,
): string {
return type.fields
.map(field =>
renderResolverFunctionInterface(field, type, modelMap, context),
renderResolverFunctionInterface(
field,
type,
modelMap,
interfacesMap,
unionsMap,
context,
),
)
.join(os.EOL)
}
Expand All @@ -223,6 +298,8 @@ function renderResolverFunctionInterface(
field: GraphQLTypeField,
type: GraphQLTypeObject,
modelMap: ModelMap,
interfacesMap: InterfacesMap,
unionsMap: UnionsMap,
context?: ContextDefinition,
): string {
const resolverName = `${upperFirst(type.name)}_${upperFirst(
Expand All @@ -236,7 +313,12 @@ function renderResolverFunctionInterface(
info: GraphQLResolveInfo,
)
`
const returnType = printFieldLikeType(field, modelMap)
const returnType = printFieldLikeType(
field,
modelMap,
interfacesMap,
unionsMap,
)

if (type.name === 'Subscription') {
return `
Expand All @@ -255,13 +337,22 @@ function renderResolverFunctionInterface(
function renderResolverTypeInterface(
type: GraphQLTypeObject,
modelMap: ModelMap,
interfacesMap: InterfacesMap,
unionsMap: UnionsMap,
context?: ContextDefinition,
): string {
return `
export interface ${upperFirst(type.name)}_Resolvers {
${type.fields
.map(field =>
renderResolverTypeInterfaceFunction(field, type, modelMap, context),
renderResolverTypeInterfaceFunction(
field,
type,
modelMap,
interfacesMap,
unionsMap,
context,
),
)
.join(os.EOL)}
}
Expand All @@ -272,6 +363,8 @@ function renderResolverTypeInterfaceFunction(
field: GraphQLTypeField,
type: GraphQLTypeObject,
modelMap: ModelMap,
interfacesMap: InterfacesMap,
unionsMap: UnionsMap,
context?: ContextDefinition,
): string {
const resolverDefinition = `
Expand All @@ -281,7 +374,12 @@ function renderResolverTypeInterfaceFunction(
ctx: ${getContextName(context)},
info: GraphQLResolveInfo,
)`
const returnType = printFieldLikeType(field, modelMap)
const returnType = printFieldLikeType(
field,
modelMap,
interfacesMap,
unionsMap,
)

if (type.name === 'Subscription') {
return `
Expand All @@ -301,10 +399,17 @@ function renderResolverTypeInterfaceFunction(
function renderResolvers(args: GenerateArgs): string {
return `
export interface Resolvers {
${args.types
.filter(type => type.type.isObject)
.map(type => `${type.name}: ${upperFirst(type.name)}_Resolvers`)
.join(',' + os.EOL)}
${[
...args.types
.filter(type => type.type.isObject)
.map(type => `${type.name}: ${upperFirst(type.name)}_Resolvers`),
...args.interfaces.map(
type => `${type.name}?: ${upperFirst(type.name)}_Resolvers`,
),
...args.unions.map(
type => `${type.name}?: ${upperFirst(type.name)}_Resolvers`,
),
].join(`,${os.EOL}`)}
}
`
}
Expand Down
Loading