blog-be/src/articles/articles.resolver.ts

85 lines
2.5 KiB
TypeScript

import {
Resolver,
Query,
Mutation,
Args,
Int,
ResolveField,
Parent,
} 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';
import * as marked from 'marked';
import highlight from 'highlight.js';
import { AccountRole, Roles } from '@nestjs-lib/auth';
@Resolver(() => Article)
export class ArticlesResolver {
constructor(private readonly articlesService: ArticlesService) {}
@Roles(AccountRole.admin, AccountRole.super)
@Mutation(() => Article)
createArticle(
@Args('createArticleInput') createArticleInput: CreateArticleInput,
) {
return this.articlesService.create(createArticleInput);
}
@Query(() => [Article], { name: 'articles' })
async findAll() {
return await this.articlesService.findAll();
}
@Query(() => Article, { name: 'article' })
findOne(@Args('id', { type: () => String }) id: string) {
return this.articlesService.findOne(id);
}
@Roles(AccountRole.admin, AccountRole.super)
@Mutation(() => Article)
async updateArticle(
@Args('updateArticleInput') updateArticleInput: UpdateArticleInput,
) {
const article = await this.articlesService.findOne(updateArticleInput.id);
return this.articlesService.update(article, updateArticleInput);
}
@Roles(AccountRole.admin, AccountRole.super)
@Mutation(() => Int)
removeArticle(@Args('id', { type: () => String }) id: string) {
return this.articlesService.remove(id);
}
@ResolveField(() => String)
async html(@Parent() article: Article) {
const tokens = marked.lexer(article.content);
const index = tokens.findIndex((token) => ['heading'].includes(token.type));
if (index !== -1) {
tokens.splice(index, 1);
}
return marked.parser(tokens, {
gfm: true,
smartLists: true,
smartypants: true,
langPrefix: 'hljs language-',
highlight: (code, language) => {
return highlight.highlight(code, {
language: highlight.getLanguage(language) ? language : 'plaintext',
}).value;
},
});
}
@ResolveField(() => String, { nullable: true })
async description(@Parent() article: Article) {
const tokens = marked.lexer(article.content);
const token = tokens.find((token) =>
['blockquote', 'paragraph'].includes(token.type),
) as { text: string };
return token?.text;
}
}