-
Notifications
You must be signed in to change notification settings - Fork 45
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(graphql,core): Add support for custom services and assemblers
- Loading branch information
1 parent
d129487
commit 85e8658
Showing
13 changed files
with
230 additions
and
43 deletions.
There are no files selected for viewing
28 changes: 28 additions & 0 deletions
28
packages/core/__tests__/decorators/inject-assembler-query-service.decorator.spec.ts
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import * as nestjsCommon from '@nestjs/common'; | ||
import { QueryService, InjectAssemblerQueryService, DefaultAssembler } from '../../src'; | ||
import { getAssemblerQueryServiceToken } from '../../src/decorators/helpers'; | ||
|
||
describe('@InjectAssemblerQueryService', () => { | ||
const injectSpy = jest.spyOn(nestjsCommon, 'Inject'); | ||
|
||
class Foo { | ||
str!: string; | ||
} | ||
|
||
class Bar { | ||
num!: string; | ||
} | ||
|
||
// eslint-disable-next-line @typescript-eslint/ban-types | ||
class TestAssembler extends DefaultAssembler<Foo, Bar> {} | ||
|
||
it('call inject with the correct key', () => { | ||
// @ts-ignore | ||
// eslint-disable-next-line @typescript-eslint/no-unused-vars | ||
class Test { | ||
constructor(@InjectAssemblerQueryService(TestAssembler) readonly service: QueryService<Foo>) {} | ||
} | ||
expect(injectSpy).toBeCalledTimes(1); | ||
expect(injectSpy).toBeCalledWith(getAssemblerQueryServiceToken(TestAssembler)); | ||
}); | ||
}); |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,12 @@ | ||
import { Assembler } from '../assemblers'; | ||
import { Class } from '../common'; | ||
|
||
export function getQueryServiceToken<DTO>(DTOClass: Class<DTO>): string { | ||
return `${DTOClass.name}QueryService`; | ||
} | ||
|
||
export function getAssemblerQueryServiceToken<DTO, Entity = unknown>( | ||
AssemblerClass: Class<Assembler<DTO, Entity>>, | ||
): string { | ||
return `${AssemblerClass.name}QueryService`; | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
export { getQueryServiceToken } from './helpers'; | ||
export { InjectQueryService } from './inject-query-service.decorator'; | ||
export { InjectAssemblerQueryService } from './inject-assembler-query-service.decorator'; |
8 changes: 8 additions & 0 deletions
8
packages/core/src/decorators/inject-assembler-query-service.decorator.ts
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import { Inject } from '@nestjs/common'; | ||
import { Assembler } from '../assemblers'; | ||
import { Class } from '../common'; | ||
import { getAssemblerQueryServiceToken } from './helpers'; | ||
|
||
export const InjectAssemblerQueryService = <DTO, Entity>( | ||
AssemblerClass: Class<Assembler<DTO, Entity>>, | ||
): ParameterDecorator => Inject(getAssemblerQueryServiceToken(AssemblerClass)); |
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { DynamicModule, ForwardReference } from '@nestjs/common'; | ||
import { Assembler } from './assemblers'; | ||
import { Class } from './common'; | ||
import { createServices } from './providers'; | ||
|
||
export interface NestjsQueryCoreModuleOpts { | ||
imports?: Array<Class<any> | DynamicModule | Promise<DynamicModule> | ForwardReference>; | ||
assemblers?: Class<Assembler<any, any>>[]; | ||
} | ||
|
||
export class NestjsQueryCoreModule { | ||
static forFeature(opts: NestjsQueryCoreModuleOpts): DynamicModule { | ||
const { imports = [], assemblers = [] } = opts; | ||
const assemblerServiceProviders = createServices(assemblers); | ||
return { | ||
module: NestjsQueryCoreModule, | ||
imports: [...imports], | ||
providers: [...assemblers, ...assemblerServiceProviders], | ||
exports: [...imports, ...assemblers, ...assemblerServiceProviders], | ||
}; | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import { Provider } from '@nestjs/common'; | ||
import { Assembler } from './assemblers'; | ||
import { Class } from './common'; | ||
import { getQueryServiceToken } from './decorators'; | ||
import { getAssemblerQueryServiceToken } from './decorators/helpers'; | ||
import { getCoreMetadataStorage } from './metadata'; | ||
import { AssemblerQueryService, QueryService } from './services'; | ||
|
||
function createServiceProvider<DTO, Entity>(AssemblerClass: Class<Assembler<DTO, Entity>>): Provider { | ||
const classes = getCoreMetadataStorage().getAssemblerClasses(AssemblerClass); | ||
if (!classes) { | ||
throw new Error( | ||
`unable to determine DTO and Entity classes for ${AssemblerClass.name}. Did you decorate your class with @Assembler`, | ||
); | ||
} | ||
const { EntityClass } = classes; | ||
return { | ||
provide: getAssemblerQueryServiceToken(AssemblerClass), | ||
useFactory(assembler: Assembler<DTO, Entity>, entityService: QueryService<Entity>) { | ||
return new AssemblerQueryService(assembler, entityService); | ||
}, | ||
inject: [AssemblerClass, getQueryServiceToken(EntityClass)], | ||
}; | ||
} | ||
|
||
export const createServices = (opts: Class<Assembler<unknown, unknown>>[]): Provider[] => { | ||
return opts.map((opt) => createServiceProvider(opt)); | ||
}; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
export { QueryService } from './query.service'; | ||
export { AssemblerQueryService } from './assembler-query.service'; | ||
export { RelationQueryService, QueryServiceRelation } from './relation-query.service'; | ||
export { NoOpQueryService } from './noop-query.service'; |
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,28 @@ | ||
import { Class } from '@nestjs-query/core'; | ||
import { Assembler, NestjsQueryCoreModule, Class } from '@nestjs-query/core'; | ||
import { DynamicModule, ForwardReference, Provider } from '@nestjs/common'; | ||
import { AutoResolverOpts, createResolvers } from './providers'; | ||
|
||
export interface NestjsQueryGraphqlModuleOpts { | ||
imports: Array<Class<any> | DynamicModule | Promise<DynamicModule> | ForwardReference>; | ||
services?: Provider[]; | ||
assemblers?: Class<Assembler<any, any>>[]; | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
resolvers: AutoResolverOpts<any, any, unknown, unknown>[]; | ||
} | ||
|
||
export class NestjsQueryGraphQLModule { | ||
static forFeature(opts: NestjsQueryGraphqlModuleOpts): DynamicModule { | ||
const coreModule = NestjsQueryCoreModule.forFeature({ | ||
assemblers: opts.assemblers, | ||
imports: opts.imports, | ||
}); | ||
const services = opts.services || []; | ||
const resolverProviders = createResolvers(opts.resolvers); | ||
return { | ||
module: NestjsQueryGraphQLModule, | ||
imports: [...opts.imports], | ||
providers: [...(opts.services || []), ...resolverProviders], | ||
exports: [...resolverProviders, ...opts.imports], | ||
imports: [...opts.imports, coreModule], | ||
providers: [...services, ...resolverProviders], | ||
exports: [...resolverProviders, ...services, ...opts.imports, coreModule], | ||
}; | ||
} | ||
} |
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