1
- import { DiscoveryService } from '@golevelup/nestjs-discovery' ;
2
- import { Injectable , SetMetadata } from '@nestjs/common' ;
1
+ import { Injectable } from '@nestjs/common' ;
3
2
import { GraphQLSchemaHost } from '@nestjs/graphql' ;
4
- import { asNonEmptyArray } from '@seedcompany/common' ;
3
+ import { asNonEmptyArray , setOf } from '@seedcompany/common' ;
4
+ import { createMetadataDecorator } from '@seedcompany/nest' ;
5
5
import { GraphQLObjectType } from 'graphql' ;
6
6
import type { ValueOf } from 'type-fest' ;
7
7
import {
@@ -11,16 +11,12 @@ import {
11
11
type ObjectView ,
12
12
ServerException ,
13
13
} from '~/common' ;
14
+ import { MetadataDiscovery } from '~/core/discovery' ;
14
15
import { type BaseNode } from '../database/results' ;
15
16
import { ILogger , Logger } from '../logger' ;
16
17
import { type ResourceMap } from './map' ;
17
18
import { ResourcesHost } from './resources.host' ;
18
19
19
- const RESOLVE_BY_ID = 'RESOLVE_BY_ID' ;
20
- interface Shape {
21
- type : ReadonlyArray < keyof ResourceMap > ;
22
- }
23
-
24
20
type SomeResource = ValueOf < ResourceMap > ;
25
21
26
22
/**
@@ -33,10 +29,12 @@ type SomeResource = ValueOf<ResourceMap>;
33
29
*
34
30
* {@link ResourceResolver} can be used to invoke this function.
35
31
*/
36
- export const HandleIdLookup = ( type : Many < SomeResource > ) =>
37
- SetMetadata < string , Shape > ( RESOLVE_BY_ID , {
38
- type : many ( type ) . map ( ( cls ) => cls . name as keyof ResourceMap ) ,
39
- } ) ;
32
+ export const HandleIdLookup = createMetadataDecorator ( {
33
+ setter : ( type : Many < SomeResource > ) => ( {
34
+ types : setOf ( many ( type ) . map ( ( cls ) => cls . name as keyof ResourceMap ) ) ,
35
+ } ) ,
36
+ types : [ 'method' ] ,
37
+ } ) ;
40
38
41
39
/**
42
40
* Allows looking up GraphQL objects from DB Nodes.
@@ -55,7 +53,7 @@ export class ResourceResolver {
55
53
private readonly typeCache = new Map < string , keyof ResourceMap | Error > ( ) ;
56
54
57
55
constructor (
58
- private readonly discover : DiscoveryService ,
56
+ private readonly discovery : MetadataDiscovery ,
59
57
private readonly resourcesHost : ResourcesHost ,
60
58
private readonly schemaHost : GraphQLSchemaHost ,
61
59
@Logger ( 'resource-resolver' ) private readonly logger : ILogger ,
@@ -94,28 +92,23 @@ export class ResourceResolver {
94
92
view ?: ObjectView ,
95
93
) : Promise < SomeResource [ 'prototype' ] & { __typename : string } > {
96
94
const type = this . resolveType ( possibleTypes ) ;
97
- const discovered = await this . discover . providerMethodsWithMetaAtKey < Shape > (
98
- RESOLVE_BY_ID ,
99
- ) ;
95
+ const discovered = this . discovery
96
+ . discover ( HandleIdLookup )
97
+ . methods <
98
+ ( id : ID , view ?: ObjectView ) => Promise < SomeResource [ 'prototype' ] >
99
+ > ( ) ;
100
100
const filtered = asNonEmptyArray (
101
- discovered . filter ( ( f ) => f . meta . type . includes ( type ) ) ,
101
+ discovered . filter ( ( f ) => f . meta . types . has ( type ) ) ,
102
102
) ;
103
103
if ( ! filtered ) {
104
104
throw new ServerException ( `Could find resolver for type: ${ type } ` ) ;
105
105
}
106
106
if ( filtered . length > 1 ) {
107
107
this . logger . warning ( `Found more than one resolver for ${ type } ` ) ;
108
108
}
109
- const method = filtered [ 0 ] . discoveredMethod ;
110
- const result = await method . handler . call (
111
- method . parentClass . instance ,
112
- id ,
113
- view ,
114
- ) ;
115
- return {
116
- __typename : type ,
117
- ...result ,
118
- } ;
109
+ const { method } = filtered [ 0 ] ;
110
+ const result = await method ( id , view ) ;
111
+ return Object . assign ( { __typename : type } , result ) ;
119
112
}
120
113
121
114
resolveTypeByBaseNode ( node : BaseNode ) {
0 commit comments