Last active
March 28, 2020 20:52
-
-
Save rafaelcorreiapoli/8f13c097c2f8f1557b4ae8dd08098c09 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
interface IArgDescription { | |
name: string; | |
type: () => any; | |
} | |
interface IResolverDescription { | |
name: string; | |
resolver: Function; | |
decorator: MethodDecorator; | |
methodArgs: IArgDescription[]; | |
} | |
export const GraphQLCrud = <T>({ | |
name, | |
classType, | |
updateInputClassType, | |
}: { | |
name: string; | |
classType: Type<T>; | |
updateInputClassType: Type<any>; | |
}): ClassDecorator => target => { | |
Resolver(classType)(target); | |
const instanceName = 'instance'; | |
const getOneMethodName = `single${name}`; | |
const getManyMethodName = `all${name}s`; | |
const deleteMethodName = `delete${name}`; | |
const updateMethodName = `update${name}`; | |
const findOneResolver = (id: number) => { | |
// TODO: How can I access the Service here? | |
}; | |
const findManyResolver = () => { | |
// TODO: How can I access the Service here? | |
}; | |
const deleteOneResolver = (id: number) => { | |
// TODO: How can I access the Service here? | |
}; | |
const updateResolver = (id: number, payload: typeof updateInputClassType) => { | |
// TODO: How can I access the Service here? | |
}; | |
@ObjectType(`Update${name}Payload`, { | |
isAbstract: true, | |
}) | |
class UpdatePayload { | |
@Field(() => classType, { name: name.toLowerCase() }) | |
[instanceName]: typeof classType; | |
} | |
const resolvers: IResolverDescription[] = [ | |
{ | |
decorator: Query(() => classType), | |
name: getOneMethodName, | |
resolver: findOneResolver, | |
methodArgs: [ | |
{ | |
name: 'id', | |
type: () => Int, | |
}, | |
], | |
}, | |
{ | |
decorator: Query(() => [classType]), | |
name: getManyMethodName, | |
resolver: findManyResolver, | |
methodArgs: [], | |
}, | |
{ | |
decorator: Mutation(() => DeletePayload), | |
name: deleteMethodName, | |
resolver: deleteOneResolver, | |
methodArgs: [ | |
{ | |
name: 'id', | |
type: () => Int, | |
}, | |
], | |
}, | |
{ | |
decorator: Mutation(() => UpdatePayload), | |
name: updateMethodName, | |
resolver: updateResolver, | |
methodArgs: [ | |
{ | |
name: 'id', | |
type: () => Int, | |
}, | |
{ | |
name: 'payload', | |
type: () => updateInputClassType, | |
}, | |
], | |
}, | |
]; | |
const getDescriptorForMethod = (method: string) => | |
Object.getOwnPropertyDescriptor(target.prototype, method); | |
const registerMethodOnPrototype = (key: string, fn: Function) => { | |
Object.defineProperty(target.prototype, key, { | |
value: fn, | |
configurable: true, | |
enumerable: true, | |
writable: true, | |
}); | |
}; | |
const registerMethodArgs = (resolverDescription: IResolverDescription) => { | |
for (const [ | |
i, | |
{ name, type }, | |
] of resolverDescription.methodArgs.entries()) { | |
Args({ | |
name, | |
type, | |
})(target.prototype, resolverDescription.name, i); | |
} | |
}; | |
const registerResolver = (resolverDescription: IResolverDescription) => { | |
registerMethodOnPrototype( | |
resolverDescription.name, | |
resolverDescription.resolver, | |
); | |
resolverDescription.decorator( | |
target.prototype, | |
resolverDescription.name, | |
getDescriptorForMethod(resolverDescription.name), | |
); | |
registerMethodArgs(resolverDescription); | |
}; | |
for (const resolver of resolvers) { | |
registerResolver(resolver); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment