-
Notifications
You must be signed in to change notification settings - Fork 382
/
delegates-explorer.service.ts
60 lines (56 loc) 路 2.03 KB
/
delegates-explorer.service.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import { Inject, Injectable } from '@nestjs/common';
import { ModulesContainer } from '@nestjs/core/injector/modules-container';
import { MetadataScanner } from '@nestjs/core/metadata-scanner';
import { MergeInfo } from 'graphql-tools/dist/Interfaces';
import { mapValues } from 'lodash';
import { GRAPHQL_MODULE_OPTIONS } from '../graphql.constants';
import { GqlModuleOptions } from '../interfaces/gql-module-options.interface';
import { ResolverMetadata } from '../interfaces/resolver-metadata.interface';
import { extractMetadata } from '../utils/extract-metadata.util';
import { BaseExplorerService } from './base-explorer.service';
@Injectable()
export class DelegatesExplorerService extends BaseExplorerService {
constructor(
private readonly modulesContainer: ModulesContainer,
private readonly metadataScanner: MetadataScanner,
@Inject(GRAPHQL_MODULE_OPTIONS)
private readonly gqlOptions: GqlModuleOptions,
) {
super();
}
explore() {
const modules = this.getModules(
this.modulesContainer,
this.gqlOptions.include || [],
);
const delegates = this.flatMap(modules, instance =>
this.filterDelegates(instance),
);
return this.curryDelegates(this.groupMetadata(delegates));
}
filterDelegates(instance: Object): ResolverMetadata[] {
if (!instance) {
return undefined;
}
const prototype = Object.getPrototypeOf(instance);
const predicate = (resolverType, isDelegated) => !isDelegated;
const resolvers = this.metadataScanner.scanFromPrototype(
instance,
prototype,
name => extractMetadata(instance, prototype, name, predicate),
);
return resolvers.filter(resolver => !!resolver).map(resolver => {
const callback = instance[resolver.methodName].bind(instance);
return {
...resolver,
callback,
};
});
}
curryDelegates(delegates): (mergeInfo: MergeInfo) => any {
return mergeInfo =>
mapValues(delegates, parent =>
mapValues(parent, (propertyFn, key) => propertyFn()(mergeInfo)),
);
}
}