【发布时间】:2020-12-26 19:16:57
【问题描述】:
对于 userPasswordChange 突变由于某种原因被称为 minGroup dirrective 而不是 idIsOwnerOrMinGroup。可能是什么问题?
export const typeDefs = gql`
directive @minGroup(requires: Group = ADMINS) on OBJECT | FIELD_DEFINITION
directive @idIsOwnerOrMinGroup(requires: Group = ADMINS) on OBJECT | FIELD_DEFINITION
type Mutation {
userPasswordChange(oldPassword: String, newPassword: String!, id: Int!): Boolean! @idIsOwnerOrMinGroup(requires: ADMINS)
}`
import { MinGroupDirective } from '../directives/minGroupDirective'
import { IdIsOwnerOrMinGroupDirective } from '../directives/IdIsOwnerOrMinGroupDirective'
export const schemaDirectives = {
minGroup: MinGroupDirective,
idIsOwnerOrMinGroup: IdIsOwnerOrMinGroupDirective,
} as any
export const schema = makeExecutableSchema({
typeDefs,
resolvers,
schemaDirectives,
})
type MinGroupRequired = { _minGroup?: AccessGroup }
type MinGroupAvoidRewrap = { _minGroupAvoidRewrap?: true }
export class MinGroupDirective extends SchemaDirectiveVisitor {
visitObject(type: GraphQLObjectType & MinGroupRequired): void {
this.ensureFieldsWrapped(type)
type._minGroup = this.args.requires
}
// Visitor methods for nested types like fields and arguments
// also receive a details object that provides information about
// the parent and grandparent types.
visitFieldDefinition(
field: GraphQLField<any, any> & MinGroupRequired,
details: {
field: GraphQLField<any, any>
objectType: GraphQLObjectType | GraphQLInterfaceType
}
): void {
this.ensureFieldsWrapped(details.objectType)
field._minGroup = this.args.requires
}
ensureFieldsWrapped(objectType: (GraphQLObjectType | GraphQLInterfaceType) & MinGroupRequired & MinGroupAvoidRewrap): any {
// Mark the GraphQLObjectType object to avoid re-wrapping:
if (objectType._minGroupAvoidRewrap) return
objectType._minGroupAvoidRewrap = true
const fields = objectType.getFields()
Object.keys(fields).forEach((fieldName) => {
const field = fields[fieldName] as GraphQLField<any, any, any> & MinGroupRequired
const { resolve = defaultFieldResolver } = field
field.resolve = async function (...args): Promise<any> {
// Get the required Group from the field first, falling back
// to the objectType if no Group is required by the field:
const requiredGroup = field._minGroup || objectType._minGroup
if (!requiredGroup) return resolve.apply(this, args)
const ctx: Ctx<CtxUserAny> = args[2]
if (minGroupCheck(ctx.user.access_group, requiredGroup)) return resolve.apply(this, args)
throw genGqlError('')
}
})
}
}
type MinGroupRequired = { _minGroup?: AccessGroup }
type MinGroupAvoidRewrap = { _minGroupAvoidRewrap?: true }
export class IdIsOwnerOrMinGroupDirective extends SchemaDirectiveVisitor {
visitObject(type: GraphQLObjectType & MinGroupRequired): void {
this.ensureFieldsWrapped(type)
type._minGroup = this.args.requires
}
// Visitor methods for nested types like fields and arguments
// also receive a details object that provides information about
// the parent and grandparent types.
visitFieldDefinition(
field: GraphQLField<any, any> & MinGroupRequired,
details: {
field: GraphQLField<any, any>
objectType: GraphQLObjectType | GraphQLInterfaceType
}
): void {
this.ensureFieldsWrapped(details.objectType)
field._minGroup = this.args.requires
}
ensureFieldsWrapped(objectType: (GraphQLObjectType | GraphQLInterfaceType) & MinGroupRequired & MinGroupAvoidRewrap): any {
// Mark the GraphQLObjectType object to avoid re-wrapping:
if (objectType._minGroupAvoidRewrap) return
objectType._minGroupAvoidRewrap = true
const fields = objectType.getFields()
Object.keys(fields).forEach((fieldName) => {
const field = fields[fieldName] as GraphQLField<any, any, any> & MinGroupRequired
const { resolve = defaultFieldResolver } = field
field.resolve = async function (...args): Promise<any> {
// Get the required Group from the field first, falling back
// to the objectType if no Group is required by the field:
const requiredGroup = field._minGroup || objectType._minGroup
if (!requiredGroup) return resolve.apply(this, args)
const ctx: Ctx<CtxUserAny> = args[2]
const { id }: { id: number } = args[1]
if (minGroupCheck(ctx.user.access_group, requiredGroup) || (id && id === (ctx.user as Ctx['user'])?.id))
return resolve.apply(this, args)
throw genGqlError('')
}
})
}
}
【问题讨论】: