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

View File

@ -39,6 +39,7 @@
"graphql-tools": "^7.0.2", "graphql-tools": "^7.0.2",
"ioredis": "^4.25.0", "ioredis": "^4.25.0",
"js-yaml": "^4.0.0", "js-yaml": "^4.0.0",
"marked": "^2.1.3",
"nestjs-redis": "^1.2.8", "nestjs-redis": "^1.2.8",
"observable-to-async-generator": "^1.0.1-rc", "observable-to-async-generator": "^1.0.1-rc",
"pg": "^8.5.1", "pg": "^8.5.1",
@ -55,6 +56,7 @@
"@nestjs/testing": "^7.6.15", "@nestjs/testing": "^7.6.15",
"@types/express": "^4.17.8", "@types/express": "^4.17.8",
"@types/jest": "^26.0.22", "@types/jest": "^26.0.22",
"@types/marked": "^2.0.3",
"@types/node": "^14.14.41", "@types/node": "^14.14.41",
"@types/supertest": "^2.0.11", "@types/supertest": "^2.0.11",
"@typescript-eslint/eslint-plugin": "^4.22.0", "@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 { ArticlesService } from './articles.service';
import { Article } from './entities/article.entity'; import { Article } from './entities/article.entity';
import { CreateArticleInput } from './dto/create-article.input'; import { CreateArticleInput } from './dto/create-article.input';
import { UpdateArticleInput } from './dto/update-article.input'; import { UpdateArticleInput } from './dto/update-article.input';
import * as marked from 'marked';
@Resolver(() => Article) @Resolver(() => Article)
export class ArticlesResolver { export class ArticlesResolver {
@ -16,8 +25,8 @@ export class ArticlesResolver {
} }
@Query(() => [Article], { name: 'articles' }) @Query(() => [Article], { name: 'articles' })
findAll() { async findAll() {
return this.articlesService.findAll(); return await this.articlesService.findAll();
} }
@Query(() => Article, { name: 'article' }) @Query(() => Article, { name: 'article' })
@ -37,4 +46,19 @@ export class ArticlesResolver {
removeArticle(@Args('id', { type: () => String }) id: string) { removeArticle(@Args('id', { type: () => String }) id: string) {
return this.articlesService.remove(id); 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) {}