Skip to content

Commit

Permalink
Added more types for IUseDynamicResolversParams
Browse files Browse the repository at this point in the history
Now the event functions will have `context` and `root` properties.
  • Loading branch information
incetarik committed Apr 28, 2022
1 parent 2d0dad5 commit 8aefb9c
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 18 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,16 @@ This file contains the changes made to the package.

The sections are in descending order of the change date.

## [0.1.9] - 2022-04-27
### Changed
- `IOnResolvingParams.context` property.
- `IOnResolvingParams.root` property.
- `IOnResolvedParams.fromDatabase` property.
- Now if a data is returned from `IUseDynamicResolversParams.onResolving` then
the returned data will be available in `IUseDynamicResolversParams.onResolved`
function. Previously, the `onResolved` function was not called if returned
from `onResolving`.

## [0.1.7] - 2022-04-27
### Changed
- Type improvements for `selectionMap` option.
Expand All @@ -21,6 +31,7 @@ object.
The initial version of the package.

[Unreleased]: https://github.com/incetarik/nestjs-prisma-dynamic-resolvers/compare/v1.0.0...HEAD
[0.1.9]: https://github.com/incetarik/nestjs-prisma-dynamic-resolvers/compare/0.1.7...0.1.9
[0.1.7]: https://github.com/incetarik/nestjs-prisma-dynamic-resolvers/compare/0.1.6...0.1.7
[0.1.6]: https://github.com/incetarik/nestjs-prisma-dynamic-resolvers/compare/0.1.5...0.1.6
[0.1.5]: https://github.com/incetarik/nestjs-prisma-dynamic-resolvers/releases/tag/0.1.5
82 changes: 64 additions & 18 deletions src/dynamic-resolvers.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { GraphQLResolveInfo } from 'graphql'

import { Inject, Type } from '@nestjs/common'
import { Info, Parent, ResolveField, Resolver } from '@nestjs/graphql'
import { Context, GraphQLExecutionContext, Info, Parent, ResolveField, Resolver, Root } from '@nestjs/graphql'

import { SYM_PRISMA_CLIENT } from './constants'
import { getNavigationMapsOf, INavigationMap, removeNavigationMapsOf } from './dynamic-navigations'
import { extractGraphQLSelectionPath, extractGraphQLSelections, toCamelCase } from './helpers'

let _resolverParams: IRegisterDynamicResolverParams[] | undefined

export interface IOnResolvingParams<P extends object = object> {
export interface IOnResolvingParams<P extends object = object, TRoot extends object = object> {
/**
* The parent object.
*
Expand All @@ -25,16 +25,43 @@ export interface IOnResolvingParams<P extends object = object> {
* @memberof IOnResolvingParams
*/
readonly resolveInfo: GraphQLResolveInfo

/**
* The execution context.
*
* @type {GraphQLExecutionContext}
* @memberof IOnResolvingParams
*/
readonly context: GraphQLExecutionContext

/**
* The root object.
*
* @type {TRoot}
* @memberof IOnResolvingParams
*/
readonly root: TRoot
}

export interface IOnResolvedParams<R = any, P extends object = object> extends IOnResolvingParams<P> {
export interface IOnResolvedParams<R = any, P extends object = object, TRoot extends object = object> extends IOnResolvingParams<P, TRoot> {
/**
* The data resolved by the resolver.
*
* @type {R}
* @memberof IOnResolvedParams
*/
data: R

/**
* Indicates if the {@link data} is resolved from the database or not.
*
* This property will be `false` if the {@link data} is got from the
* {@link IUseDynamicResolversParams.onResolving} method.
*
* @type {boolean}
* @memberof IOnResolvedParams
*/
readonly fromDatabase: boolean
}

/**
Expand Down Expand Up @@ -102,7 +129,7 @@ export interface IUseDynamicResolversParams {
*
* @memberof IUseDynamicResolversParams
*/
onResolving?<P extends object>(params: IOnResolvingParams<P>): any
onResolving?<P extends object = object, TRoot extends object = object>(params: IOnResolvingParams<P, TRoot>): any

/**
* An event function that will be triggered when the resolved is resolved the defined navigation.
Expand All @@ -117,7 +144,7 @@ export interface IUseDynamicResolversParams {
*
* @memberof IUseDynamicResolversParams
*/
onResolved?<P extends object = object>(params: IOnResolvedParams<any, P>): any
onResolved?<P extends object = object, TRoot extends object = object>(params: IOnResolvedParams<any, P, TRoot>): any
}

export interface IRegisterDynamicResolverParams extends IUseDynamicResolversParams {
Expand Down Expand Up @@ -267,34 +294,32 @@ function _makeDynamicResolver(params: IMakeDynamicResolverParams) {
constructor(@Inject(SYM_PRISMA_CLIENT) protected readonly prisma: any) {
super(prisma)
}
}

const {
source,
relation,
sourceProperty,
} = navigationMap

const isArray = relation.indexOf('*') >= 0
const handlerMethodDescriptor: PropertyDescriptor = {
async value(this: DynamicResolver, parent: { id: string }, info: GraphQLResolveInfo) {
protected async fireOnResolvingEvent(parent: { id: string }, root: any, info: GraphQLResolveInfo, context: GraphQLExecutionContext) {
if (typeof onResolving === 'function') {
const replaceValue = await onResolving({
root,
parent,
context,
resolveInfo: info,
})

if (typeof replaceValue === 'object') {
return replaceValue
return [ true, replaceValue ]
}
}

const data = await this.resolve(parent, primaryKeyName, info, navigationMap, selectionMap)
return [ false ]
}

protected async fireOnResolvedEvent(parent: { id: string }, root: any, info: GraphQLResolveInfo, data: any, context: GraphQLExecutionContext, fromDatabase: boolean) {
if (typeof onResolved === 'function') {
const replaceValue = await onResolved({
data,
root,
parent,
context,
fromDatabase,
resolveInfo: info,
})

Expand All @@ -307,10 +332,31 @@ function _makeDynamicResolver(params: IMakeDynamicResolverParams) {
}
}

const {
source,
relation,
sourceProperty,
} = navigationMap

const isArray = relation.indexOf('*') >= 0
const handlerMethodDescriptor: PropertyDescriptor = {
async value(this: DynamicResolver, parent: { id: string }, root: any, info: GraphQLResolveInfo, context: GraphQLExecutionContext) {
const [ shouldReturn, replaceValue ] = await this.fireOnResolvingEvent(parent, root, info, context)
if (shouldReturn) {
return this.fireOnResolvedEvent(parent, root, info, replaceValue, context, false)
}

const data = await this.resolve(parent, primaryKeyName, info, navigationMap, selectionMap)
return this.fireOnResolvedEvent(parent, root, info, data, context, true)
}
}

Object.defineProperty(DynamicResolver.prototype, sourceProperty, handlerMethodDescriptor)

Parent()(DynamicResolver.prototype, sourceProperty, 0)
Info()(DynamicResolver.prototype, sourceProperty, 1)
Root()(DynamicResolver.prototype, sourceProperty, 1)
Info()(DynamicResolver.prototype, sourceProperty, 2)
Context()(DynamicResolver.prototype, sourceProperty, 3)

const resolvedType = isArray ? [ target ] : target
ResolveField(() => resolvedType, {
Expand Down

0 comments on commit 8aefb9c

Please sign in to comment.