85 lines
2.5 KiB
TypeScript
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;
|
|
}
|
|
}
|