Skip to content

Commit

Permalink
feat(schema): Added middleware validation step
Browse files Browse the repository at this point in the history
  • Loading branch information
maticzav committed May 13, 2018
1 parent 18af840 commit cf63955
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 3 deletions.
50 changes: 48 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,49 @@ function wrapResolverInMiddleware(
}
}

// Validation

function validateMiddleware(
schema: GraphQLSchema,
middleware: IMiddleware,
): IMiddleware {
if (isMiddlewareFunction(middleware)) {
return middleware
}

const types = schema.getTypeMap()

Object.keys(middleware).forEach(type => {
if (!Object.keys(types).includes(type)) {
throw new MiddlewareError(
`Type ${type} exists in middleware but is missing in Schema.`,
)
}

if (!isMiddlewareFunction(middleware[type])) {
const fields = (types[type] as
| GraphQLObjectType
| GraphQLInterfaceType).getFields()

Object.keys(middleware[type]).forEach(field => {
if (!Object.keys(fields).includes(field)) {
throw new MiddlewareError(
`Field ${type}.${field} exists in middleware but is missing in Schema.`,
)
}
})
}
})

return middleware
}

export class MiddlewareError extends Error {
constructor(...props) {
super(...props)
}
}

// Merge

function applyMiddlewareToField(
Expand Down Expand Up @@ -153,8 +196,11 @@ function addMiddlewareToSchema(
schema: GraphQLSchema,
middleware: IMiddleware,
): GraphQLSchema {
const resolvers = generateResolverFromSchemaAndMiddleware(schema, middleware)

const validMiddleware = validateMiddleware(schema, middleware)
const resolvers = generateResolverFromSchemaAndMiddleware(
schema,
validMiddleware,
)
addResolveFunctionsToSchema({ schema, resolvers })

return schema
Expand Down
46 changes: 45 additions & 1 deletion test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import test from 'ava'
import { graphql } from 'graphql'
import { makeExecutableSchema } from 'graphql-tools'
import { applyMiddleware } from './dist'
import { applyMiddleware, MiddlewareError } from './dist'

// Setup ---------------------------------------------------------------------

Expand Down Expand Up @@ -121,6 +121,18 @@ const schemaMiddlewareAfter = async (resolve, parent, args, context, info) => {
return 'changed'
}

// Wrong Middleware

const middlewareWithUndefinedType = {
Wrong: () => ({}),
}

const middlewareWithUndefinedField = {
Query: {
wrong: () => ({}),
},
}

// Test ----------------------------------------------------------------------

// Field
Expand Down Expand Up @@ -475,3 +487,35 @@ test('Schema, Field middleware - Mutation', async t => {
},
})
})

// Not found fields

test('Middleware Error - Schema undefined type', async t => {
const schema = getSchema()

const res = t.throws(() => {
applyMiddleware(schema, middlewareWithUndefinedType)
})

t.deepEqual(
res,
MiddlewareError(
`Type Wrong exists in middleware but is missing in Schema.`,
),
)
})

test('Middleware Error - Schema undefined field', async t => {
const schema = getSchema()

const res = t.throws(() => {
applyMiddleware(schema, middlewareWithUndefinedField)
})

t.deepEqual(
res,
MiddlewareError(
`Field Query.wrong exists in middleware but is missing in Schema.`,
),
)
})

0 comments on commit cf63955

Please sign in to comment.