feat: markdown to html

This commit is contained in:
Ivan 2021-07-02 15:16:27 +08:00
parent 2b7e344931
commit 76862b738d
4 changed files with 67 additions and 5 deletions

33
package-lock.json generated
View File

@ -1,11 +1,10 @@
{
"name": "fennec-be",
"name": "blog-be",
"version": "0.0.1",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "fennec-be",
"version": "0.0.1",
"license": "UNLICENSED",
"dependencies": {
@ -27,6 +26,7 @@
"graphql-tools": "^7.0.2",
"ioredis": "^4.25.0",
"js-yaml": "^4.0.0",
"marked": "^2.1.3",
"nestjs-redis": "^1.2.8",
"observable-to-async-generator": "^1.0.1-rc",
"pg": "^8.5.1",
@ -43,6 +43,7 @@
"@nestjs/testing": "^7.6.15",
"@types/express": "^4.17.8",
"@types/jest": "^26.0.22",
"@types/marked": "^2.0.3",
"@types/node": "^14.14.41",
"@types/supertest": "^2.0.11",
"@typescript-eslint/eslint-plugin": "^4.22.0",
@ -3392,6 +3393,12 @@
"resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz",
"integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w=="
},
"node_modules/@types/marked": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@types/marked/-/marked-2.0.3.tgz",
"integrity": "sha512-lbhSN1rht/tQ+dSWxawCzGgTfxe9DB31iLgiT1ZVT5lshpam/nyOA1m3tKHRoNPctB2ukSL22JZI5Fr+WI/zYg==",
"dev": true
},
"node_modules/@types/mime": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz",
@ -10298,6 +10305,17 @@
"node": ">=0.10.0"
}
},
"node_modules/marked": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/marked/-/marked-2.1.3.tgz",
"integrity": "sha512-/Q+7MGzaETqifOMWYEA7HVMaZb4XbcRfaOzcSsHZEith83KGlvaSG33u0SKu89Mj5h+T8V2hM+8O45Qc5XTgwA==",
"bin": {
"marked": "bin/marked"
},
"engines": {
"node": ">= 10"
}
},
"node_modules/media-typer": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
@ -18277,6 +18295,12 @@
"resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz",
"integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w=="
},
"@types/marked": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@types/marked/-/marked-2.0.3.tgz",
"integrity": "sha512-lbhSN1rht/tQ+dSWxawCzGgTfxe9DB31iLgiT1ZVT5lshpam/nyOA1m3tKHRoNPctB2ukSL22JZI5Fr+WI/zYg==",
"dev": true
},
"@types/mime": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz",
@ -23610,6 +23634,11 @@
"object-visit": "^1.0.0"
}
},
"marked": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/marked/-/marked-2.1.3.tgz",
"integrity": "sha512-/Q+7MGzaETqifOMWYEA7HVMaZb4XbcRfaOzcSsHZEith83KGlvaSG33u0SKu89Mj5h+T8V2hM+8O45Qc5XTgwA=="
},
"media-typer": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",

View File

@ -39,6 +39,7 @@
"graphql-tools": "^7.0.2",
"ioredis": "^4.25.0",
"js-yaml": "^4.0.0",
"marked": "^2.1.3",
"nestjs-redis": "^1.2.8",
"observable-to-async-generator": "^1.0.1-rc",
"pg": "^8.5.1",
@ -55,6 +56,7 @@
"@nestjs/testing": "^7.6.15",
"@types/express": "^4.17.8",
"@types/jest": "^26.0.22",
"@types/marked": "^2.0.3",
"@types/node": "^14.14.41",
"@types/supertest": "^2.0.11",
"@typescript-eslint/eslint-plugin": "^4.22.0",

View File

@ -1,8 +1,17 @@
import { Resolver, Query, Mutation, Args, Int } from '@nestjs/graphql';
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';
@Resolver(() => Article)
export class ArticlesResolver {
@ -16,8 +25,8 @@ export class ArticlesResolver {
}
@Query(() => [Article], { name: 'articles' })
findAll() {
return this.articlesService.findAll();
async findAll() {
return await this.articlesService.findAll();
}
@Query(() => Article, { name: 'article' })
@ -37,4 +46,19 @@ export class ArticlesResolver {
removeArticle(@Args('id', { type: () => String }) id: string) {
return this.articlesService.remove(id);
}
@ResolveField(() => String)
async html(@Parent() article: Article) {
return marked(article.content);
}
@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;
}
}

View File

@ -0,0 +1,7 @@
import { ObjectType, OmitType } from '@nestjs/graphql';
import { Article } from '../entities/article.entity';
@ObjectType()
export class ArticleListItemDto extends OmitType(Article, [
'content',
] as const) {}