diff --git a/.vscode/settings.json b/.vscode/settings.json index 7756bd5..40fe44c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -8,6 +8,7 @@ "metatype", "pmessage", "psubscribe", + "QLJSON", "Repos", "rpop", "rpush" diff --git a/package-lock.json b/package-lock.json index 434f4c9..0fc4a3b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,6 +26,7 @@ "debug": "^4.3.2", "graphql": "^15.6.1", "graphql-tools": "^8.2.0", + "graphql-type-json": "^0.3.2", "highlight.js": "^11.3.1", "ioredis": "^4.28.0", "js-yaml": "^4.1.0", @@ -7204,6 +7205,15 @@ "node": ">=12" } }, + "node_modules/graphql-type-json": { + "version": "0.3.2", + "resolved": "https://npm.ivanli.cc/graphql-type-json/-/graphql-type-json-0.3.2.tgz", + "integrity": "sha512-J+vjof74oMlCWXSvt0DOf2APEdZOCdubEvGDUAlqH//VBYcOYsGgRW7Xzorr44LvkjiuvecWc8fChxuZZbChtg==", + "license": "MIT", + "peerDependencies": { + "graphql": ">=0.8.0" + } + }, "node_modules/graphql-ws": { "version": "5.5.1", "resolved": "https://npm.ivanli.cc/graphql-ws/-/graphql-ws-5.5.1.tgz", @@ -18373,6 +18383,12 @@ } } }, + "graphql-type-json": { + "version": "0.3.2", + "resolved": "https://npm.ivanli.cc/graphql-type-json/-/graphql-type-json-0.3.2.tgz", + "integrity": "sha512-J+vjof74oMlCWXSvt0DOf2APEdZOCdubEvGDUAlqH//VBYcOYsGgRW7Xzorr44LvkjiuvecWc8fChxuZZbChtg==", + "requires": {} + }, "graphql-ws": { "version": "5.5.1", "resolved": "https://npm.ivanli.cc/graphql-ws/-/graphql-ws-5.5.1.tgz", diff --git a/package.json b/package.json index c055dfe..ca55101 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "debug": "^4.3.2", "graphql": "^15.6.1", "graphql-tools": "^8.2.0", + "graphql-type-json": "^0.3.2", "highlight.js": "^11.3.1", "ioredis": "^4.28.0", "js-yaml": "^4.1.0", diff --git a/src/articles/articles.resolver.ts b/src/articles/articles.resolver.ts index 1d625ff..8993ea2 100644 --- a/src/articles/articles.resolver.ts +++ b/src/articles/articles.resolver.ts @@ -14,6 +14,7 @@ import { UpdateArticleInput } from './dto/update-article.input'; import * as marked from 'marked'; import highlight from 'highlight.js'; import { AccountRole, Roles } from '@nestjs-lib/auth'; +import { ArticleHistory } from './models/article-history.model'; @Resolver(() => Article) export class ArticlesResolver { @@ -81,4 +82,9 @@ export class ArticlesResolver { return token?.text; } + + @ResolveField(() => [ArticleHistory]) + async histories(@Parent() article: Article) { + return article.histories; + } } diff --git a/src/articles/entities/article.entity.ts b/src/articles/entities/article.entity.ts index ffcf4c3..53ef8be 100644 --- a/src/articles/entities/article.entity.ts +++ b/src/articles/entities/article.entity.ts @@ -1,4 +1,5 @@ -import { ObjectType } from '@nestjs/graphql'; +import { ArticleHistory } from './../models/article-history.model'; +import { HideField, ObjectType } from '@nestjs/graphql'; import { Column, Entity, Index } from 'typeorm'; import { AppBaseEntity } from '../../commons/entities/app-base-entity'; @@ -17,4 +18,8 @@ export class Article extends AppBaseEntity { @Column({ type: 'varchar', array: true }) tags: string[]; + + @HideField() + @Column({ type: 'jsonb', default: [] }) + histories: ArticleHistory[]; } diff --git a/src/articles/models/article-history.model.ts b/src/articles/models/article-history.model.ts new file mode 100644 index 0000000..a52f095 --- /dev/null +++ b/src/articles/models/article-history.model.ts @@ -0,0 +1,15 @@ +import { Column } from 'typeorm'; +import { ObjectType, Field } from '@nestjs/graphql'; +import { Article } from '../entities/article.entity'; + +@ObjectType() +export class ArticleHistory { + @Field(() => Object) + payload: Partial
; + + updatedAt: Date; + + automatic: boolean; + + published: boolean; +} diff --git a/src/commons/commons.module.ts b/src/commons/commons.module.ts index 1e701bb..2a8e183 100644 --- a/src/commons/commons.module.ts +++ b/src/commons/commons.module.ts @@ -1,3 +1,4 @@ +import { ObjectScalar } from './scalars/object.scalar'; import { Module } from '@nestjs/common'; import { PasswordConverter } from './services/password-converter'; import { PubSubModule } from './pub-sub/pub-sub.module'; @@ -5,7 +6,7 @@ import { AuthModule } from '@nestjs-lib/auth'; @Module({ imports: [PubSubModule, AuthModule], - providers: [PasswordConverter], + providers: [PasswordConverter, ObjectScalar], exports: [PasswordConverter, AuthModule], }) export class CommonsModule {} diff --git a/src/commons/entities/app-base-entity.ts b/src/commons/entities/app-base-entity.ts index 2a6d639..c710c3f 100644 --- a/src/commons/entities/app-base-entity.ts +++ b/src/commons/entities/app-base-entity.ts @@ -12,7 +12,7 @@ export class AppBaseEntity { @PrimaryGeneratedColumn('uuid') id: string; - @CreateDateColumn() + @CreateDateColumn({ select: false }) createdAt: Date; @UpdateDateColumn({ select: false }) diff --git a/src/commons/scalars/object.scalar.ts b/src/commons/scalars/object.scalar.ts new file mode 100644 index 0000000..75bc000 --- /dev/null +++ b/src/commons/scalars/object.scalar.ts @@ -0,0 +1,13 @@ +import { Scalar, CustomScalar } from '@nestjs/graphql'; +import { GraphQLJSONObject } from 'graphql-type-json'; + +@Scalar('Object', (type) => Object) +export class ObjectScalar implements CustomScalar { + description = GraphQLJSONObject.description; + + parseValue = GraphQLJSONObject.parseValue; + + serialize = GraphQLJSONObject.serialize; + + parseLiteral = GraphQLJSONObject.parseLiteral; +}