feat: tags module.
This commit is contained in:
parent
6f6018501b
commit
6cf4d1b748
@ -13,6 +13,7 @@ import { PubSubModule } from './commons/pub-sub/pub-sub.module';
|
|||||||
import { ArticlesModule } from './articles/articles.module';
|
import { ArticlesModule } from './articles/articles.module';
|
||||||
import { EtcdModule } from 'nestjs-etcd';
|
import { EtcdModule } from 'nestjs-etcd';
|
||||||
import { CommonsModule } from './commons/commons.module';
|
import { CommonsModule } from './commons/commons.module';
|
||||||
|
import { TagsModule } from './tags/tags.module';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
@ -84,6 +85,7 @@ import { CommonsModule } from './commons/commons.module';
|
|||||||
}),
|
}),
|
||||||
CommonsModule,
|
CommonsModule,
|
||||||
ArticlesModule,
|
ArticlesModule,
|
||||||
|
TagsModule,
|
||||||
],
|
],
|
||||||
controllers: [AppController],
|
controllers: [AppController],
|
||||||
providers: [AppService, AppResolver],
|
providers: [AppService, AppResolver],
|
||||||
|
9
src/tags/dto/create-tag.input.ts
Normal file
9
src/tags/dto/create-tag.input.ts
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import { InputType } from '@nestjs/graphql';
|
||||||
|
import { IsString, Length } from 'class-validator';
|
||||||
|
|
||||||
|
@InputType()
|
||||||
|
export class CreateTagInput {
|
||||||
|
@IsString()
|
||||||
|
@Length(1, 100)
|
||||||
|
name: string;
|
||||||
|
}
|
9
src/tags/dto/update-tag.input.ts
Normal file
9
src/tags/dto/update-tag.input.ts
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import { CreateTagInput } from './create-tag.input';
|
||||||
|
import { InputType, PartialType } from '@nestjs/graphql';
|
||||||
|
import { IsUUID } from 'class-validator';
|
||||||
|
|
||||||
|
@InputType()
|
||||||
|
export class UpdateTagInput extends PartialType(CreateTagInput) {
|
||||||
|
@IsUUID()
|
||||||
|
id: string;
|
||||||
|
}
|
11
src/tags/entities/tag.entity.ts
Normal file
11
src/tags/entities/tag.entity.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { AppBaseEntity } from './../../commons/entities/app-base-entity';
|
||||||
|
import { ObjectType } from '@nestjs/graphql';
|
||||||
|
import { Column, Index, Entity } from 'typeorm';
|
||||||
|
|
||||||
|
@Entity()
|
||||||
|
@ObjectType()
|
||||||
|
export class Tag extends AppBaseEntity {
|
||||||
|
@Index({ unique: true })
|
||||||
|
@Column({ length: 100 })
|
||||||
|
name: string;
|
||||||
|
}
|
12
src/tags/tags.module.ts
Normal file
12
src/tags/tags.module.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import { Tag } from './entities/tag.entity';
|
||||||
|
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||||
|
import { CommonsModule } from './../commons/commons.module';
|
||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
import { TagsService } from './tags.service';
|
||||||
|
import { TagsResolver } from './tags.resolver';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [CommonsModule, TypeOrmModule.forFeature([Tag])],
|
||||||
|
providers: [TagsResolver, TagsService],
|
||||||
|
})
|
||||||
|
export class TagsModule {}
|
25
src/tags/tags.resolver.spec.ts
Normal file
25
src/tags/tags.resolver.spec.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { Test, TestingModule } from '@nestjs/testing';
|
||||||
|
import { TagsResolver } from './tags.resolver';
|
||||||
|
import { TagsService } from './tags.service';
|
||||||
|
|
||||||
|
describe('TagsResolver', () => {
|
||||||
|
let resolver: TagsResolver;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
const module: TestingModule = await Test.createTestingModule({
|
||||||
|
providers: [
|
||||||
|
TagsResolver,
|
||||||
|
{
|
||||||
|
provide: TagsService,
|
||||||
|
useValue: {},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}).compile();
|
||||||
|
|
||||||
|
resolver = module.get<TagsResolver>(TagsResolver);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be defined', () => {
|
||||||
|
expect(resolver).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
36
src/tags/tags.resolver.ts
Normal file
36
src/tags/tags.resolver.ts
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import { Resolver, Query, Mutation, Args } from '@nestjs/graphql';
|
||||||
|
import { TagsService } from './tags.service';
|
||||||
|
import { Tag } from './entities/tag.entity';
|
||||||
|
import { CreateTagInput } from './dto/create-tag.input';
|
||||||
|
import { UpdateTagInput } from './dto/update-tag.input';
|
||||||
|
|
||||||
|
@Resolver(() => Tag)
|
||||||
|
export class TagsResolver {
|
||||||
|
constructor(private readonly tagsService: TagsService) {}
|
||||||
|
|
||||||
|
@Mutation(() => Tag)
|
||||||
|
createTag(@Args('createTagInput') createTagInput: CreateTagInput) {
|
||||||
|
return this.tagsService.create(createTagInput);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Query(() => [Tag], { name: 'tags' })
|
||||||
|
findAll() {
|
||||||
|
return this.tagsService.findAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Query(() => Tag, { name: 'tag' })
|
||||||
|
findOne(@Args('id', { type: () => String }) id: string) {
|
||||||
|
return this.tagsService.findOne(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Mutation(() => Tag)
|
||||||
|
async updateTag(@Args('updateTagInput') updateTagInput: UpdateTagInput) {
|
||||||
|
const tag = await this.tagsService.findOne(updateTagInput.id);
|
||||||
|
return this.tagsService.update(tag, updateTagInput);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Mutation(() => Tag)
|
||||||
|
removeTag(@Args('id', { type: () => String }) id: string) {
|
||||||
|
return this.tagsService.remove(id);
|
||||||
|
}
|
||||||
|
}
|
27
src/tags/tags.service.spec.ts
Normal file
27
src/tags/tags.service.spec.ts
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import { Tag } from './entities/tag.entity';
|
||||||
|
import { getRepositoryToken } from '@nestjs/typeorm';
|
||||||
|
import { Test, TestingModule } from '@nestjs/testing';
|
||||||
|
import { TagsService } from './tags.service';
|
||||||
|
import { Repository } from 'typeorm';
|
||||||
|
|
||||||
|
describe('TagsService', () => {
|
||||||
|
let service: TagsService;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
const module: TestingModule = await Test.createTestingModule({
|
||||||
|
providers: [
|
||||||
|
TagsService,
|
||||||
|
{
|
||||||
|
provide: getRepositoryToken(Tag),
|
||||||
|
useValue: new Repository(),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}).compile();
|
||||||
|
|
||||||
|
service = module.get<TagsService>(TagsService);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be defined', () => {
|
||||||
|
expect(service).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
45
src/tags/tags.service.ts
Normal file
45
src/tags/tags.service.ts
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
|
import { Repository } from 'typeorm';
|
||||||
|
import { BaseDbService } from './../commons/services/base-db.service';
|
||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { CreateTagInput } from './dto/create-tag.input';
|
||||||
|
import { UpdateTagInput } from './dto/update-tag.input';
|
||||||
|
import { Tag } from './entities/tag.entity';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class TagsService extends BaseDbService<Tag> {
|
||||||
|
readonly uniqueFields: Array<keyof Tag> = ['name'];
|
||||||
|
constructor(@InjectRepository(Tag) readonly repository: Repository<Tag>) {
|
||||||
|
super(repository);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create or recover a tag
|
||||||
|
*/
|
||||||
|
async create(createTagInput: CreateTagInput): Promise<Tag> {
|
||||||
|
const old = await this.repository.findOne({ name: createTagInput.name });
|
||||||
|
return this.repository.save(
|
||||||
|
old
|
||||||
|
? this.repository.merge(old, createTagInput)
|
||||||
|
: this.repository.create(createTagInput),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async findAll() {
|
||||||
|
return await this.repository.find({
|
||||||
|
order: { createdAt: 'DESC' },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async update(tag: Tag, updateTagInput: UpdateTagInput) {
|
||||||
|
await this.isDuplicateEntityForUpdate(tag.id, updateTagInput);
|
||||||
|
return await this.repository.save(
|
||||||
|
this.repository.merge(tag, updateTagInput),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async remove(id: string) {
|
||||||
|
await this.canRemove([id]);
|
||||||
|
return await this.repository.softDelete({ id }).then((d) => d.affected);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user