This commit is contained in:
Ivan Li
2021-04-24 14:47:45 +08:00
parent 7b715e807f
commit fba867e0b5
24 changed files with 627 additions and 393 deletions

View File

@ -0,0 +1,11 @@
import { Module } from '@nestjs/common';
import { ArticlesService } from './articles.service';
import { ArticlesResolver } from './articles.resolver';
import { TypeOrmModule } from '@nestjs/typeorm';
import { Article } from './entities/article.entity';
@Module({
imports: [TypeOrmModule.forFeature([Article])],
providers: [ArticlesResolver, ArticlesService],
})
export class ArticlesModule {}

View File

@ -0,0 +1,25 @@
import { Test, TestingModule } from '@nestjs/testing';
import { ArticlesResolver } from './articles.resolver';
import { ArticlesService } from './articles.service';
describe('ArticlesResolver', () => {
let resolver: ArticlesResolver;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
ArticlesResolver,
{
provide: ArticlesService,
useValue: {},
},
],
}).compile();
resolver = module.get<ArticlesResolver>(ArticlesResolver);
});
it('should be defined', () => {
expect(resolver).toBeDefined();
});
});

View File

@ -0,0 +1,42 @@
import { Resolver, Query, Mutation, Args, Int } from '@nestjs/graphql';
import { ArticlesService } from './articles.service';
import { Article } from './entities/article.entity';
import { CreateArticleInput } from './dto/create-article.input';
import { UpdateArticleInput } from './dto/update-article.input';
@Resolver(() => Article)
export class ArticlesResolver {
constructor(private readonly articlesService: ArticlesService) {}
@Mutation(() => Article)
createArticle(
@Args('createArticleInput') createArticleInput: CreateArticleInput,
) {
return this.articlesService.create(createArticleInput);
}
@Query(() => [Article], { name: 'articles' })
findAll() {
return this.articlesService.findAll();
}
@Query(() => Article, { name: 'article' })
findOne(@Args('id', { type: () => String }) id: string) {
return this.articlesService.findOne(id);
}
@Mutation(() => Article)
updateArticle(
@Args('updateArticleInput') updateArticleInput: UpdateArticleInput,
) {
return this.articlesService.update(
updateArticleInput.id,
updateArticleInput,
);
}
@Mutation(() => Article)
removeArticle(@Args('id', { type: () => String }) id: string) {
return this.articlesService.remove(id);
}
}

View File

@ -0,0 +1,27 @@
import { Test, TestingModule } from '@nestjs/testing';
import { getRepositoryToken } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { ArticlesService } from './articles.service';
import { Article } from './entities/article.entity';
describe('ArticlesService', () => {
let service: ArticlesService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
ArticlesService,
{
provide: getRepositoryToken(Article),
useValue: new Repository(),
},
],
}).compile();
service = module.get<ArticlesService>(ArticlesService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});

View File

@ -0,0 +1,38 @@
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { BaseDbService } from '../commons/services/base-db.service';
import { CreateArticleInput } from './dto/create-article.input';
import { UpdateArticleInput } from './dto/update-article.input';
import { Article } from './entities/article.entity';
@Injectable()
export class ArticlesService extends BaseDbService<Article> {
readonly uniqueFields: Array<keyof Article> = ['title'];
constructor(
@InjectRepository(Article)
readonly repository: Repository<Article>,
) {
super(repository);
}
async create(createArticleInput: CreateArticleInput) {
await this.isDuplicateEntity(createArticleInput);
return await this.repository.save(
this.repository.create(createArticleInput),
);
}
async findAll() {
return await this.repository.find();
}
async update(id: string, updateArticleInput: UpdateArticleInput) {
await this.isDuplicateEntityForUpdate(id, updateArticleInput);
return await this.repository.update(id, updateArticleInput);
}
async remove(id: string) {
await this.canRemove([id]);
return await this.repository.softDelete({ id });
}
}

View File

@ -0,0 +1,20 @@
import { InputType } from '@nestjs/graphql';
import { IsDate, IsOptional, IsString, Length } from 'class-validator';
@InputType()
export class CreateArticleInput {
@IsString()
@Length(1, 100)
title: string;
@IsString()
@Length(2, 100000)
content: string;
@IsOptional()
@IsDate()
publishedAt?: Date;
@IsString({ each: true })
tags: string[];
}

View File

@ -0,0 +1,8 @@
import { CreateArticleInput } from './create-article.input';
import { InputType, Field, Int, PartialType } from '@nestjs/graphql';
@InputType()
export class UpdateArticleInput extends PartialType(CreateArticleInput) {
@Field(() => Int)
id: string;
}

View File

@ -0,0 +1,20 @@
import { ObjectType } from '@nestjs/graphql';
import { Column, Entity, Index } from 'typeorm';
import { AppBaseEntity } from '../../commons/entities/app-base-entity';
@Entity()
@ObjectType()
export class Article extends AppBaseEntity {
@Column()
title: string;
@Column({ type: 'text' })
content: string;
@Index()
@Column({ nullable: true })
publishedAt?: Date;
@Column({ type: 'varchar', array: true })
tags: string[];
}