From 07f4f19a86832f0e13808279f3844183e7c050c4 Mon Sep 17 00:00:00 2001 From: Innei Date: Mon, 6 Sep 2021 14:22:51 +0800 Subject: [PATCH] feat: init category module --- .gitignore | 1 + bin/patch.js | 36 + package.json | 13 +- patch/bootstrap.ts | 39 + patch/global.d.ts | 11 + patch/index.ts | 1 + patch/tsconfig.json | 34 + patch/v2.0.0-alpha.1.ts | 17 + pnpm-lock.yaml | 44 +- src/modules/category/category.controller.ts | 54 ++ src/modules/category/category.dto.ts | 86 +++ src/modules/category/category.module.ts | 6 +- src/modules/category/category.service.ts | 23 +- src/modules/comment/block-keywords.json | 758 +------------------- src/modules/init/init.service.ts | 2 +- src/modules/post/post.module.ts | 4 +- src/modules/post/post.service.spec.ts | 4 +- test/app.e2e-spec.ts | 4 +- 18 files changed, 329 insertions(+), 808 deletions(-) create mode 100644 bin/patch.js create mode 100644 patch/bootstrap.ts create mode 100644 patch/global.d.ts create mode 100644 patch/index.ts create mode 100644 patch/tsconfig.json create mode 100644 patch/v2.0.0-alpha.1.ts create mode 100644 src/modules/category/category.controller.ts create mode 100644 src/modules/category/category.dto.ts diff --git a/.gitignore b/.gitignore index 62da1894..ec7a92b6 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,4 @@ lerna-debug.log* !.vscode/launch.json !.vscode/extensions.json +patch/dist diff --git a/bin/patch.js b/bin/patch.js new file mode 100644 index 00000000..62dd6b53 --- /dev/null +++ b/bin/patch.js @@ -0,0 +1,36 @@ +// @ts-check +const inquirer = require('inquirer') +const chalk = require('chalk') +const prompt = inquirer.createPromptModule() +const package = require('../package.json') +const { execSync } = require('child_process') +const { resolve } = require('path') +const { readdirSync } = require('fs') +const PATCH_DIR = resolve(process.cwd(), './patch') + +async function bootstarp() { + console.log(chalk.yellowBright('mx-space server patch center')) + + console.log(chalk.yellow(`current version: ${package.version}`)) + + const patchFiles = readdirSync(PATCH_DIR).filter( + (file) => file.startsWith('v') && file.endsWith('.ts'), + ) + + prompt({ + type: 'list', + name: 'version', + message: 'Select version you want to patch.', + choices: patchFiles.map((f) => f.replace(/\.ts$/, '')), + }).then(({ version }) => { + execSync('yarn run build', { + encoding: 'utf-8', + }) + + const patchPath = resolve('dist/patch/', version + '.js') + console.log(chalk.green('starting patch... ' + patchPath)) + execSync(`node ${patchPath}`, { encoding: 'utf8' }) + }) +} + +bootstarp() diff --git a/package.json b/package.json index 8b536389..33702915 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,8 @@ "test:watch": "jest --watch", "test:cov": "jest --coverage", "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", - "test:e2e": "jest --config ./test/jest-e2e.json" + "test:e2e": "jest --config ./test/jest-e2e.json", + "patch": "node bin/patch.js" }, "dependencies": { "@nestjs/common": "^8.0.6", @@ -54,15 +55,16 @@ "bcrypt": "^5.0.1", "cache-manager": "3.4.4", "cache-manager-ioredis": "^2.1.0", - "chalk": "^4.1.2", + "chalk": "*", "class-transformer": "^0.4.0", "class-validator": "^0.13.1", "dayjs": "^1.10.6", "ejs": "^3.1.6", "fastify-swagger": "^4.9.0", "image-size": "^1.0.0", - "lodash": "^4.17.21", - "mongoose": "^5.13.7", + "lodash": "*", + "mongoose": "*", + "dotenv": "*", "mongoose-lean-virtuals": "^0.8.0", "mongoose-paginate-v2": "^1.4.2", "nanoid": "^3.1.25", @@ -74,7 +76,8 @@ "redis": "3.1.2", "reflect-metadata": "^0.1.13", "rxjs": "^7.3.0", - "snakecase-keys": "^4.0.2" + "snakecase-keys": "^4.0.2", + "inquirer": "*" }, "devDependencies": { "@innei-util/eslint-config-ts": "^0.2.3", diff --git a/patch/bootstrap.ts b/patch/bootstrap.ts new file mode 100644 index 00000000..73c52e68 --- /dev/null +++ b/patch/bootstrap.ts @@ -0,0 +1,39 @@ +import { getModelForClass, mongoose } from '@typegoose/typegoose' +import { config } from 'dotenv' +import { ConnectionBase } from 'mongoose' +import * as APP from '../src/app.config' +import { CategoryModel } from '../src/modules/category/category.model' +import { NoteModel } from '../src/modules/note/note.model' +import { PostModel } from '../src/modules/post/post.model' +const env = config().parsed || {} +const url = APP.MONGO_DB.uri + +const opt = { + useCreateIndex: true, + useFindAndModify: false, + useNewUrlParser: true, + useUnifiedTopology: true, + autoIndex: true, +} +mongoose.connect(url, opt) +const post = getModelForClass(PostModel) +const note = getModelForClass(NoteModel) +const category = getModelForClass(CategoryModel) + +const Config = { + env, + db: (mongoose.connection as any).client.db('mx-space-next') as ConnectionBase, + models: { + post, + note, + category, + }, +} +async function bootstrap(cb: (config: typeof Config) => any) { + await cb.call(this, Config) + + mongoose.disconnect() + process.exit() +} + +export { bootstrap as patch } diff --git a/patch/global.d.ts b/patch/global.d.ts new file mode 100644 index 00000000..1a13b8ae --- /dev/null +++ b/patch/global.d.ts @@ -0,0 +1,11 @@ +import { ModelType } from '@typegoose/typegoose/lib/types' +import { Document, PaginateModel } from 'mongoose' +/// +declare global { + export type KV = Record + + // @ts-ignore + export type MongooseModel = ModelType & PaginateModel +} + +export {} diff --git a/patch/index.ts b/patch/index.ts new file mode 100644 index 00000000..fc4f6543 --- /dev/null +++ b/patch/index.ts @@ -0,0 +1 @@ +import './bootstrap' diff --git a/patch/tsconfig.json b/patch/tsconfig.json new file mode 100644 index 00000000..b68010be --- /dev/null +++ b/patch/tsconfig.json @@ -0,0 +1,34 @@ +{ + "compilerOptions": { + "module": "CommonJS", + "declaration": false, + "removeComments": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "target": "es2017", + "sourceMap": false, + "outDir": "./dist", + "baseUrl": ".", + "noImplicitAny": false, + "incremental": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "paths": { + "~": [ + "../src" + ], + "~/*": [ + "../src/*" + ] + }, + }, + "include": [ + "*.ts", + "../src" + ], + "exclude": [ + "dist" + ] +} \ No newline at end of file diff --git a/patch/v2.0.0-alpha.1.ts b/patch/v2.0.0-alpha.1.ts new file mode 100644 index 00000000..ad867756 --- /dev/null +++ b/patch/v2.0.0-alpha.1.ts @@ -0,0 +1,17 @@ +// patch for version lower than v2.0.0-alpha.1 + +import { patch } from './bootstrap' + +patch(async ({ models: { note, post, category } }) => { + await Promise.all([ + [note, post].map((model) => { + return model.updateMany( + {}, + { + $unset: ['options'], + }, + ) + }), + category.aggregate([{ $unset: 'count' }]), + ]) +}) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 852b05c6..45ce7803 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -34,22 +34,24 @@ specifiers: bcrypt: ^5.0.1 cache-manager: 3.4.4 cache-manager-ioredis: ^2.1.0 - chalk: ^4.1.2 + chalk: '*' class-transformer: ^0.4.0 class-validator: ^0.13.1 cross-env: ^7.0.3 dayjs: ^1.10.6 + dotenv: '*' ejs: ^3.1.6 eslint: ^7.32.0 fastify: '*' fastify-swagger: ^4.9.0 husky: ^7.0.1 image-size: ^1.0.0 + inquirer: '*' ioredis: '*' jest: 27.1.0 lint-staged: ^11.1.2 - lodash: ^4.17.21 - mongoose: ^5.13.7 + lodash: '*' + mongoose: '*' mongoose-lean-virtuals: ^0.8.0 mongoose-paginate-v2: ^1.4.2 nanoid: ^3.1.25 @@ -96,9 +98,11 @@ dependencies: class-transformer: 0.4.0 class-validator: 0.13.1 dayjs: 1.10.6 + dotenv: 10.0.0 ejs: 3.1.6 fastify-swagger: 4.9.1 image-size: 1.0.0 + inquirer: 8.1.1 lodash: 4.17.21 mongoose: 5.13.8 mongoose-lean-virtuals: 0.8.0_mongoose@5.13.8 @@ -2068,7 +2072,6 @@ packages: engines: {node: '>=8'} dependencies: type-fest: 0.21.3 - dev: true /ansi-regex/2.1.1: resolution: {integrity: sha1-w7M6te42DYbg5ijwRorn7yfWVN8=} @@ -2083,7 +2086,6 @@ packages: /ansi-regex/5.0.0: resolution: {integrity: sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==} engines: {node: '>=8'} - dev: true /ansi-styles/3.2.1: resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} @@ -2325,7 +2327,6 @@ packages: buffer: 5.7.1 inherits: 2.0.4 readable-stream: 3.6.0 - dev: true /bluebird/3.5.1: resolution: {integrity: sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==} @@ -2473,7 +2474,6 @@ packages: /chardet/0.7.0: resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} - dev: true /chokidar/3.5.2: resolution: {integrity: sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==} @@ -2530,12 +2530,10 @@ packages: engines: {node: '>=8'} dependencies: restore-cursor: 3.1.0 - dev: true /cli-spinners/2.6.0: resolution: {integrity: sha512-t+4/y50K/+4xcCRosKkA7W4gTr1MySvLV0q+PxmG7FJ5g+66ChKurYjxBCjHggHH3HA5Hh9cy+lcUGWDqVH+4Q==} engines: {node: '>=6'} - dev: true /cli-table3/0.5.1: resolution: {integrity: sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw==} @@ -2558,7 +2556,6 @@ packages: /cli-width/3.0.0: resolution: {integrity: sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==} engines: {node: '>= 10'} - dev: true /cliui/7.0.4: resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} @@ -2571,7 +2568,6 @@ packages: /clone/1.0.4: resolution: {integrity: sha1-2jCcwmPfFZlMaIypAheco8fNfH4=} engines: {node: '>=0.8'} - dev: true /cluster-key-slot/1.1.0: resolution: {integrity: sha512-2Nii8p3RwAPiFwsnZvukotvow2rIHM+yQ6ZcBXGHdniadkYGZYiGmkHJIbZPIV9nfv7m/U1IPMVVcAhoWFeklw==} @@ -2799,7 +2795,6 @@ packages: resolution: {integrity: sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=} dependencies: clone: 1.0.4 - dev: true /define-properties/1.1.3: resolution: {integrity: sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==} @@ -2921,7 +2916,6 @@ packages: /emoji-regex/8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - dev: true /encodeurl/1.0.2: resolution: {integrity: sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=} @@ -3259,7 +3253,6 @@ packages: chardet: 0.7.0 iconv-lite: 0.4.24 tmp: 0.0.33 - dev: true /fast-decode-uri-component/1.0.1: resolution: {integrity: sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==} @@ -3385,7 +3378,6 @@ packages: engines: {node: '>=8'} dependencies: escape-string-regexp: 1.0.5 - dev: true /file-entry-cache/6.0.1: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} @@ -3752,7 +3744,6 @@ packages: engines: {node: '>=0.10.0'} dependencies: safer-buffer: 2.1.2 - dev: true /ieee754/1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} @@ -3853,7 +3844,6 @@ packages: string-width: 4.2.2 strip-ansi: 6.0.0 through: 2.3.8 - dev: true /internal-slot/1.0.3: resolution: {integrity: sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==} @@ -3965,7 +3955,6 @@ packages: /is-fullwidth-code-point/3.0.0: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} - dev: true /is-function/1.0.2: resolution: {integrity: sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==} @@ -3986,7 +3975,6 @@ packages: /is-interactive/1.0.0: resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} engines: {node: '>=8'} - dev: true /is-negative-zero/2.0.1: resolution: {integrity: sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==} @@ -4053,7 +4041,6 @@ packages: /is-unicode-supported/0.1.0: resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} engines: {node: '>=10'} - dev: true /isarray/1.0.0: resolution: {integrity: sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=} @@ -4939,7 +4926,6 @@ packages: dependencies: chalk: 4.1.2 is-unicode-supported: 0.1.0 - dev: true /log-update/4.0.0: resolution: {integrity: sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==} @@ -5068,7 +5054,6 @@ packages: /mimic-fn/2.1.0: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} - dev: true /min-document/2.19.0: resolution: {integrity: sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=} @@ -5232,7 +5217,6 @@ packages: /mute-stream/0.0.8: resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==} - dev: true /nanoid/3.1.25: resolution: {integrity: sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q==} @@ -5407,7 +5391,6 @@ packages: engines: {node: '>=6'} dependencies: mimic-fn: 2.1.0 - dev: true /openapi-types/9.3.0: resolution: {integrity: sha512-sR23YjmuwDSMsQVZDHbV9mPgi0RyniQlqR0AQxTC2/F3cpSjRFMH3CFPjoWvNqhC4OxPkDYNb2l8Mc1Me6D/KQ==} @@ -5474,7 +5457,6 @@ packages: log-symbols: 4.1.0 strip-ansi: 6.0.0 wcwidth: 1.0.1 - dev: true /os-name/4.0.1: resolution: {integrity: sha512-xl9MAoU97MH1Xt5K9ERft2YfCAoaO6msy1OBA0ozxEC0x0TmIoE6K3QvgJMMZA9yKGLmHXNY/YZoDbiGDj4zYw==} @@ -5487,7 +5469,6 @@ packages: /os-tmpdir/1.0.2: resolution: {integrity: sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=} engines: {node: '>=0.10.0'} - dev: true /p-each-series/2.2.0: resolution: {integrity: sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA==} @@ -5950,7 +5931,6 @@ packages: dependencies: onetime: 5.1.2 signal-exit: 3.0.3 - dev: true /ret/0.2.2: resolution: {integrity: sha512-M0b3YWQs7R3Z917WRQy1HHA7Ba7D8hvZg6UE5mLykJxQVE2ju0IXbGlaHPPlkY+WN7wFP+wUMXmBFA0aV6vYGQ==} @@ -5972,7 +5952,6 @@ packages: /run-async/2.4.1: resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} engines: {node: '>=0.12.0'} - dev: true /run-parallel/1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} @@ -5990,7 +5969,6 @@ packages: engines: {npm: '>=2.0.0'} dependencies: tslib: 1.14.1 - dev: true /rxjs/7.3.0: resolution: {integrity: sha512-p2yuGIg9S1epc3vrjKf6iVb3RCaAYjYskkO+jHIaV0IjOPlJop4UnodOoFb2xeNwlguqLYvGw1b1McillYb5Gw==} @@ -6011,7 +5989,6 @@ packages: /safer-buffer/2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - dev: true /saslprep/1.0.3: resolution: {integrity: sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==} @@ -6335,7 +6312,6 @@ packages: emoji-regex: 8.0.0 is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.0 - dev: true /string.prototype.trimend/1.0.4: resolution: {integrity: sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==} @@ -6390,7 +6366,6 @@ packages: engines: {node: '>=8'} dependencies: ansi-regex: 5.0.0 - dev: true /strip-bom/3.0.0: resolution: {integrity: sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=} @@ -6578,7 +6553,6 @@ packages: /through/2.3.8: resolution: {integrity: sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=} - dev: true /timm/1.7.1: resolution: {integrity: sha512-IjZc9KIotudix8bMaBW6QvMuq64BrJWFs1+4V0lXwWGQZwH+LnX87doAYhem4caOEusRP9/g6jVDQmZ8XOk1nw==} @@ -6597,7 +6571,6 @@ packages: engines: {node: '>=0.6.0'} dependencies: os-tmpdir: 1.0.2 - dev: true /tmpl/1.0.4: resolution: {integrity: sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=} @@ -6745,7 +6718,6 @@ packages: /tslib/1.14.1: resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} - dev: true /tslib/2.1.0: resolution: {integrity: sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==} @@ -6795,7 +6767,6 @@ packages: /type-fest/0.21.3: resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} engines: {node: '>=10'} - dev: true /typedarray-to-buffer/3.1.5: resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==} @@ -6913,7 +6884,6 @@ packages: resolution: {integrity: sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=} dependencies: defaults: 1.0.3 - dev: true /webidl-conversions/5.0.0: resolution: {integrity: sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==} diff --git a/src/modules/category/category.controller.ts b/src/modules/category/category.controller.ts new file mode 100644 index 00000000..7f959eaa --- /dev/null +++ b/src/modules/category/category.controller.ts @@ -0,0 +1,54 @@ +import { Controller, forwardRef, Get, Inject, Query } from '@nestjs/common' +import { ApiName } from '~/common/decorator/openapi.decorator' +import { PostService } from '../post/post.service' +import { CategoryType, MultiCategoriesQueryDto } from './category.dto' +import { CategoryService } from './category.service' + +@Controller({ path: 'categories' }) +@ApiName +export class CategoryController { + constructor( + private readonly categoryService: CategoryService, + @Inject(forwardRef(() => PostService)) + private readonly postService: PostService, + ) {} + + @Get('/') + async getCategories(@Query() query: MultiCategoriesQueryDto) { + const { ids, joint, type = CategoryType.Category } = query // categories is category's mongo id + if (ids) { + return joint + ? await Promise.all( + ids.map(async (id) => { + return await this.postService.model.find( + { categoryId: id }, + { + select: 'title slug _id categoryId created modified', + sort: { created: -1 }, + }, + ) + }), + ) + : await Promise.all( + ids.map(async (id) => { + const posts = await this.postService.model.find( + { categoryId: id }, + { + select: 'title slug _id created modified', + sort: { created: -1 }, + }, + ) + const category = await this.categoryService.model + .findById(id) + .lean() + return { + category: { ...category, children: posts }, + } + }), + ) + } + return type === CategoryType.Category + ? await this.categoryService.model.find({ type }).lean() + : await this.categoryService.getPostTagsSum() + } +} diff --git a/src/modules/category/category.dto.ts b/src/modules/category/category.dto.ts new file mode 100644 index 00000000..4b56a278 --- /dev/null +++ b/src/modules/category/category.dto.ts @@ -0,0 +1,86 @@ +import { UnprocessableEntityException } from '@nestjs/common' +import { ApiProperty } from '@nestjs/swagger' +import { Transform } from 'class-transformer' +import { + IsBoolean, + IsEnum, + IsMongoId, + IsNotEmpty, + IsOptional, + IsString, +} from 'class-validator' +import { uniq } from 'lodash' +import { IsBooleanOrString } from '~/utils/validator/isBooleanOrString' + +export enum CategoryType { + Category, + Tag, +} + +export class CategoryDto { + @IsString() + @IsNotEmpty() + @ApiProperty() + name: string + + @IsEnum(CategoryType) + @IsOptional() + @ApiProperty({ enum: [0, 1] }) + type?: CategoryType + + @IsString() + @IsNotEmpty() + @IsOptional() + slug?: string +} + +export class SlugOrIdDto { + @IsString() + @IsNotEmpty() + @ApiProperty() + query?: string +} + +export class MultiQueryTagAndCategoryDto { + @IsOptional() + @Transform(({ value: val }) => { + if (val === '1' || val === 'true') { + return true + } else { + return val + } + }) + @IsBooleanOrString() + tag?: boolean | string +} +export class MultiCategoriesQueryDto { + @IsOptional() + @IsMongoId({ + each: true, + message: '多分类查询使用逗号分隔, 应为 mongoID', + }) + @Transform(({ value: v }) => uniq(v.split(','))) + ids?: Array + + @IsOptional() + @IsBoolean() + @Transform((b) => Boolean(b)) + @ApiProperty({ enum: [1, 0] }) + joint?: boolean + + @IsOptional() + @Transform(({ value: v }: { value: string }) => { + if (typeof v !== 'string') { + throw new UnprocessableEntityException('type must be a string') + } + switch (v.toLowerCase()) { + case 'category': + return CategoryType.Category + case 'tag': + return CategoryType.Tag + default: + return CategoryType.Category + } + }) + type: CategoryType +} diff --git a/src/modules/category/category.module.ts b/src/modules/category/category.module.ts index 53059195..502c3824 100644 --- a/src/modules/category/category.module.ts +++ b/src/modules/category/category.module.ts @@ -1,8 +1,12 @@ -import { Module } from '@nestjs/common' +import { forwardRef, Module } from '@nestjs/common' +import { PostModule } from '../post/post.module' +import { CategoryController } from './category.controller' import { CategoryService } from './category.service' @Module({ providers: [CategoryService], exports: [CategoryService], + controllers: [CategoryController], + imports: [forwardRef(() => PostModule)], }) export class CategoryModule {} diff --git a/src/modules/category/category.service.ts b/src/modules/category/category.service.ts index 3017807d..52ced48d 100644 --- a/src/modules/category/category.service.ts +++ b/src/modules/category/category.service.ts @@ -1,6 +1,7 @@ -import { Injectable } from '@nestjs/common' +import { forwardRef, Inject, Injectable } from '@nestjs/common' import { ReturnModelType } from '@typegoose/typegoose' import { InjectModel } from 'nestjs-typegoose' +import { PostService } from '../post/post.service' import { CategoryModel } from './category.model' @Injectable() @@ -8,6 +9,8 @@ export class CategoryService { constructor( @InjectModel(CategoryModel) private readonly categoryModel: ReturnModelType, + @Inject(forwardRef(() => PostService)) + private readonly postService: PostService, ) {} findCategoryById(categoryId: string) { @@ -17,4 +20,22 @@ export class CategoryService { get model() { return this.categoryModel } + + async getPostTagsSum() { + const data = await this.postService.model.aggregate([ + { $project: { tags: 1 } }, + { + $unwind: '$tags', + }, + { $group: { _id: '$tags', count: { $sum: 1 } } }, + { + $project: { + _id: 0, + name: '$_id', + count: 1, + }, + }, + ]) + return data + } } diff --git a/src/modules/comment/block-keywords.json b/src/modules/comment/block-keywords.json index 092a0a30..e1f13a8f 100644 --- a/src/modules/comment/block-keywords.json +++ b/src/modules/comment/block-keywords.json @@ -1,757 +1 @@ -[ - "刷单", - "快递代发", - "淘宝", - "代发", - "兼职", - "招聘", - "网络", - "招聘", - "有意者", - "到货", - "本店", - "代购", - "扣扣", - "客服", - "微店", - "兼职", - "兼值", - "淘宝", - "小姐", - "妓女", - "包夜", - "3P", - "LY", - "狼友", - "技师", - "推油", - "胸推", - "BT", - "毒龙", - "口爆", - "兼职", - "楼凤", - "足交", - "口暴", - "口交", - "全套", - "SM", - "桑拿", - "吞精", - "咪咪", - "婊子", - "乳方", - "操逼", - "全职", - "性伴侣", - "网购", - "网络工作", - "代理", - "专业代理", - "帮忙点一下", - "帮忙点下", - "请点击进入", - "详情请进入", - "私人侦探", - "私家侦探", - "针孔摄象", - "调查婚外情", - "信用卡提现", - "无抵押贷款", - "广告代理", - "原音铃声", - "借腹生子", - "找个妈妈", - "找个爸爸", - "代孕妈妈", - "代生孩子", - "代开发票", - "腾讯客服电话", - "销售热线", - "免费订购热线", - "低价出售", - "款到发货", - "回复可见", - "连锁加盟", - "加盟连锁", - "免费二级域名", - "免费使用", - "免费索取", - "蚁力神", - "婴儿汤", - "售肾", - "刻章办", - "买小车", - "套牌车", - "玛雅网", - "电脑传讯", - "视频来源", - "下载速度", - "高清在线", - "全集在线", - "在线播放", - "txt下载", - "六位qq", - "6位qq", - "位的qq", - "个qb", - "送qb", - "用刀横向切腹", - "完全自杀手册", - "四海帮", - "足球投注", - "地下钱庄", - "中国复兴党", - "阿波罗网", - "曾道人", - "六合彩", - "改卷内幕", - "替考试", - "隐形耳机", - "出售答案", - "考中答案", - "答an", - "da案", - "资金周转", - "救市", - "股市圈钱", - "崩盘", - "资金短缺", - "证监会", - "质押贷款", - "小额贷款", - "周小川", - "刘明康", - "尚福林", - "孔丹", - "爱液", - "按摩棒", - "拔出来", - "爆草", - "包二奶", - "暴干", - "暴奸", - "暴乳", - "爆乳", - "暴淫", - "被操", - "被插", - "被干", - "逼奸", - "仓井空", - "插暴", - "操逼", - "操黑", - "操烂", - "肏你", - "肏死", - "操死", - "操我", - "厕奴", - "插比", - "插b", - "插逼", - "插进", - "插你", - "插我", - "插阴", - "潮吹", - "潮喷", - "成人电影", - "成人论坛", - "成人色情", - "成人网站", - "成人文学", - "成人小说", - "艳情小说", - "成人游戏", - "吃精", - "抽插", - "春药", - "大波", - "大力抽送", - "大乳", - "荡妇", - "荡女", - "盗撮", - "发浪", - "放尿", - "肥逼", - "粉穴", - "风月大陆", - "干死你", - "干穴", - "肛交", - "肛门", - "龟头", - "裹本", - "国产av", - "好嫩", - "豪乳", - "黑逼", - "后庭", - "后穴", - "虎骑", - "换妻俱乐部", - "黄片", - "几吧", - "鸡吧", - "鸡巴", - "鸡奸", - "妓女", - "奸情", - "叫床", - "脚交", - "精液", - "就去日", - "巨屌", - "菊花洞", - "菊门", - "巨奶", - "巨乳", - "菊穴", - "开苞", - "口爆", - "口活", - "口交", - "口射", - "口淫", - "裤袜", - "狂操", - "狂插", - "浪逼", - "浪妇", - "浪叫", - "浪女", - "狼友", - "聊性", - "凌辱", - "漏乳", - "露b", - "乱交", - "乱伦", - "轮暴", - "轮操", - "轮奸", - "裸陪", - "买春", - "美逼", - "美少妇", - "美乳", - "美腿", - "美穴", - "美幼", - "秘唇", - "迷奸", - "密穴", - "蜜穴", - "蜜液", - "摸奶", - "摸胸", - "母奸", - "奈美", - "奶子", - "男奴", - "内射", - "嫩逼", - "嫩女", - "嫩穴", - "捏弄", - "女优", - "炮友", - "砲友", - "喷精", - "屁眼", - "前凸后翘", - "强jian", - "强暴", - "强奸处女", - "情趣用品", - "情色", - "拳交", - "全裸", - "群交", - "人妻", - "人兽", - "日逼", - "日烂", - "肉棒", - "肉逼", - "肉唇", - "肉洞", - "肉缝", - "肉棍", - "肉茎", - "肉具", - "揉乳", - "肉穴", - "肉欲", - "乳爆", - "乳房", - "乳沟", - "乳交", - "乳头", - "骚逼", - "骚比", - "骚女", - "骚水", - "骚穴", - "色逼", - "色界", - "色猫", - "色盟", - "色情网站", - "色区", - "色色", - "色诱", - "色欲", - "色b", - "少年阿宾", - "射爽", - "射颜", - "食精", - "释欲", - "兽奸", - "兽交", - "手淫", - "兽欲", - "熟妇", - "熟母", - "熟女", - "爽片", - "双臀", - "死逼", - "丝袜", - "丝诱", - "松岛枫", - "酥痒", - "汤加丽", - "套弄", - "体奸", - "体位", - "舔脚", - "舔阴", - "调教", - "偷欢", - "推油", - "脱内裤", - "文做", - "舞女", - "无修正", - "吸精", - "夏川纯", - "相奸", - "小逼", - "校鸡", - "小穴", - "小xue", - "性感妖娆", - "性感诱惑", - "性虎", - "性饥渴", - "性技巧", - "性交", - "性奴", - "性虐", - "性息", - "性欲", - "胸推", - "穴口", - "穴图", - "亚情", - "颜射", - "阳具", - "杨思敏", - "要射了", - "夜勤病栋", - "一本道", - "一夜欢", - "一夜情", - "一ye情", - "阴部", - "淫虫", - "阴唇", - "淫荡", - "阴道", - "淫电影", - "阴阜", - "淫妇", - "淫河", - "阴核", - "阴户", - "淫贱", - "淫叫", - "淫教师", - "阴茎", - "阴精", - "淫浪", - "淫媚", - "淫糜", - "淫魔", - "淫母", - "淫女", - "淫虐", - "淫妻", - "淫情", - "淫色", - "淫声浪语", - "淫兽学园", - "淫书", - "淫术炼金士", - "淫水", - "淫娃", - "淫威", - "淫亵", - "淫样", - "淫液", - "淫照", - "阴b", - "应召", - "幼交", - "欲火", - "欲女", - "玉乳", - "玉穴", - "援交", - "原味内衣", - "援助交际", - "招鸡", - "招妓", - "抓胸", - "自慰", - "作爱", - "a片", - "fuck", - "gay片", - "g点", - "h动画", - "h动漫", - "失身粉", - "淫荡自慰器", - "习近平", - "平近习", - "xjp", - "习太子", - "习明泽", - "老习", - "温家宝", - "温加宝", - "温x", - "温jia宝", - "温宝宝", - "温加饱", - "温加保", - "张培莉", - "温云松", - "温如春", - "温jb", - "胡温", - "胡x", - "胡jt", - "胡boss", - "胡总", - "胡王八", - "hujintao", - "胡jintao", - "胡j涛", - "胡惊涛", - "胡景涛", - "胡紧掏", - "湖紧掏", - "胡紧套", - "锦涛", - "hjt", - "胡派", - "胡主席", - "刘永清", - "胡海峰", - "胡海清", - "江泽民", - "民泽江", - "江胡", - "江哥", - "江主席", - "江书记", - "江浙闽", - "江沢民", - "江浙民", - "择民", - "则民", - "茳泽民", - "zemin", - "ze民", - "老江", - "老j", - "江core", - "江x", - "江派", - "江zm", - "jzm", - "江戏子", - "江蛤蟆", - "江某某", - "江贼", - "江猪", - "江氏集团", - "江绵恒", - "江绵康", - "王冶坪", - "江泽慧", - "邓小平", - "平小邓", - "xiao平", - "邓xp", - "邓晓平", - "邓朴方", - "邓榕", - "邓质方", - "毛泽东", - "猫泽东", - "猫则东", - "猫贼洞", - "毛zd", - "毛zx", - "z东", - "ze东", - "泽d", - "zedong", - "毛太祖", - "毛相", - "主席画像", - "改革历程", - "朱镕基", - "朱容基", - "朱镕鸡", - "朱容鸡", - "朱云来", - "李鹏", - "李peng", - "里鹏", - "李月月鸟", - "李小鹏", - "李小琳", - "华主席", - "华国", - "国锋", - "国峰", - "锋同志", - "白春礼", - "薄熙来", - "薄一波", - "蔡赴朝", - "蔡武", - "曹刚川", - "常万全", - "陈炳德", - "陈德铭", - "陈建国", - "陈良宇", - "陈绍基", - "陈同海", - "陈至立", - "戴秉国", - "丁一平", - "董建华", - "杜德印", - "杜世成", - "傅锐", - "郭伯雄", - "郭金龙", - "贺国强", - "胡春华", - "耀邦", - "华建敏", - "黄华华", - "黄丽满", - "黄兴国", - "回良玉", - "贾庆林", - "贾廷安", - "靖志远", - "李长春", - "李春城", - "李建国", - "李克强", - "李岚清", - "李沛瑶", - "李荣融", - "李瑞环", - "李铁映", - "李先念", - "李学举", - "李源潮", - "栗智", - "梁光烈", - "廖锡龙", - "林树森", - "林炎志", - "林左鸣", - "令计划", - "柳斌杰", - "刘奇葆", - "刘少奇", - "刘延东", - "刘云山", - "刘志军", - "龙新民", - "路甬祥", - "罗箭", - "吕祖善", - "马飚", - "马恺", - "孟建柱", - "欧广源", - "强卫", - "沈跃跃", - "宋平顺", - "粟戎生", - "苏树林", - "孙家正", - "铁凝", - "屠光绍", - "王东明", - "汪东兴", - "王鸿举", - "王沪宁", - "王乐泉", - "王洛林", - "王岐山", - "王胜俊", - "王太华", - "王学军", - "王兆国", - "王振华", - "吴邦国", - "吴定富", - "吴官正", - "无官正", - "吴胜利", - "吴仪", - "奚国华", - "习仲勋", - "徐才厚", - "许其亮", - "徐绍史", - "杨洁篪", - "叶剑英", - "由喜贵", - "于幼军", - "俞正声", - "袁纯清", - "曾培炎", - "曾庆红", - "曾宪梓", - "曾荫权", - "张德江", - "张定发", - "张高丽", - "张立昌", - "张荣坤", - "张志国", - "赵洪祝", - "紫阳", - "周生贤", - "周永康", - "朱海仑", - "中南海", - "大陆当局", - "中国当局", - "北京当局", - "共产党", - "党产共", - "共贪党", - "阿共", - "产党共", - "公产党", - "工产党", - "共c党", - "共x党", - "共铲", - "供产", - "共惨", - "供铲党", - "供铲谠", - "供铲裆", - "共残党", - "共残主义", - "共产主义的幽灵", - "拱铲", - "老共", - "中共", - "中珙", - "中gong", - "gc党", - "贡挡", - "gong党", - "g产", - "狗产蛋", - "共残裆", - "恶党", - "邪党", - "共产专制", - "共产王朝", - "裆中央", - "土共", - "土g", - "共狗", - "g匪", - "共匪", - "仇共", - "政府", - "症腐", - "政腐", - "政付", - "正府", - "政俯", - "政f", - "zhengfu", - "政zhi", - "挡中央", - "档中央", - "中央领导", - "中国zf", - "中央zf", - "国wu院", - "中华帝国", - "gong和", - "大陆官方", - "北京政权", - "江泽民", - "胡锦涛", - "温家宝", - "习近平", - "习仲勋", - "贺国强", - "贺子珍", - "周永康", - "李长春", - "李德生", - "王岐山", - "姚依林", - "回良玉", - "李源潮", - "李干成", - "戴秉国", - "黄镇", - "刘延东", - "刘瑞龙", - "俞正声", - "黄敬", - "薄熙", - "薄一波", - "周小川", - "周建南", - "温云松", - "徐明", - "江泽慧", - "江绵恒", - "江绵康", - "李小鹏", - "李鹏", - "李小琳", - "朱云来", - "朱容基", - "法轮功", - "李洪志", - "新疆骚乱" -] \ No newline at end of file +[ "刷单", "快递代发", "淘宝", "代发", "兼职", "招聘", "网络", "招聘", "有意者", "到货", "本店", "代购", "扣扣", "客服", "微店", "兼职", "兼值", "淘宝", "小姐", "妓女", "包夜", "3P", "LY", "狼友", "技师", "推油", "胸推", "BT", "毒龙", "口爆", "兼职", "楼凤", "足交", "口暴", "口交", "全套", "SM", "桑拿", "吞精", "咪咪", "婊子", "乳方", "操逼", "全职", "性伴侣", "网购", "网络工作", "代理", "专业代理", "帮忙点一下", "帮忙点下", "请点击进入", "详情请进入", "私人侦探", "私家侦探", "针孔摄象", "调查婚外情", "信用卡提现", "无抵押贷款", "广告代理", "原音铃声", "借腹生子", "找个妈妈", "找个爸爸", "代孕妈妈", "代生孩子", "代开发票", "腾讯客服电话", "销售热线", "免费订购热线", "低价出售", "款到发货", "回复可见", "连锁加盟", "加盟连锁", "免费二级域名", "免费使用", "免费索取", "蚁力神", "婴儿汤", "售肾", "刻章办", "买小车", "套牌车", "玛雅网", "电脑传讯", "视频来源", "下载速度", "高清在线", "全集在线", "在线播放", "txt下载", "六位qq", "6位qq", "位的qq", "个qb", "送qb", "用刀横向切腹", "完全自杀手册", "四海帮", "足球投注", "地下钱庄", "中国复兴党", "阿波罗网", "曾道人", "六合彩", "改卷内幕", "替考试", "隐形耳机", "出售答案", "考中答案", "答an", "da案", "资金周转", "救市", "股市圈钱", "崩盘", "资金短缺", "证监会", "质押贷款", "小额贷款", "周小川", "刘明康", "尚福林", "孔丹", "爱液", "按摩棒", "拔出来", "爆草", "包二奶", "暴干", "暴奸", "暴乳", "爆乳", "暴淫", "被操", "被插", "被干", "逼奸", "仓井空", "插暴", "操逼", "操黑", "操烂", "肏你", "肏死", "操死", "操我", "厕奴", "插比", "插b", "插逼", "插进", "插你", "插我", "插阴", "潮吹", "潮喷", "成人电影", "成人论坛", "成人色情", "成人网站", "成人文学", "成人小说", "艳情小说", "成人游戏", "吃精", "抽插", "春药", "大波", "大力抽送", "大乳", "荡妇", "荡女", "盗撮", "发浪", "放尿", "肥逼", "粉穴", "风月大陆", "干死你", "干穴", "肛交", "肛门", "龟头", "裹本", "国产av", "好嫩", "豪乳", "黑逼", "后庭", "后穴", "虎骑", "换妻俱乐部", "黄片", "几吧", "鸡吧", "鸡巴", "鸡奸", "妓女", "奸情", "叫床", "脚交", "精液", "就去日", "巨屌", "菊花洞", "菊门", "巨奶", "巨乳", "菊穴", "开苞", "口爆", "口活", "口交", "口射", "口淫", "裤袜", "狂操", "狂插", "浪逼", "浪妇", "浪叫", "浪女", "狼友", "聊性", "凌辱", "漏乳", "露b", "乱交", "乱伦", "轮暴", "轮操", "轮奸", "裸陪", "买春", "美逼", "美少妇", "美乳", "美腿", "美穴", "美幼", "秘唇", "迷奸", "密穴", "蜜穴", "蜜液", "摸奶", "摸胸", "母奸", "奈美", "奶子", "男奴", "内射", "嫩逼", "嫩女", "嫩穴", "捏弄", "女优", "炮友", "砲友", "喷精", "屁眼", "前凸后翘", "强jian", "强暴", "强奸处女", "情趣用品", "情色", "拳交", "全裸", "群交", "人妻", "人兽", "日逼", "日烂", "肉棒", "肉逼", "肉唇", "肉洞", "肉缝", "肉棍", "肉茎", "肉具", "揉乳", "肉穴", "肉欲", "乳爆", "乳房", "乳沟", "乳交", "乳头", "骚逼", "骚比", "骚女", "骚水", "骚穴", "色逼", "色界", "色猫", "色盟", "色情网站", "色区", "色色", "色诱", "色欲", "色b", "少年阿宾", "射爽", "射颜", "食精", "释欲", "兽奸", "兽交", "手淫", "兽欲", "熟妇", "熟母", "熟女", "爽片", "双臀", "死逼", "丝袜", "丝诱", "松岛枫", "酥痒", "汤加丽", "套弄", "体奸", "体位", "舔脚", "舔阴", "调教", "偷欢", "推油", "脱内裤", "文做", "舞女", "无修正", "吸精", "夏川纯", "相奸", "小逼", "校鸡", "小穴", "小xue", "性感妖娆", "性感诱惑", "性虎", "性饥渴", "性技巧", "性交", "性奴", "性虐", "性息", "性欲", "胸推", "穴口", "穴图", "亚情", "颜射", "阳具", "杨思敏", "要射了", "夜勤病栋", "一本道", "一夜欢", "一夜情", "一ye情", "阴部", "淫虫", "阴唇", "淫荡", "阴道", "淫电影", "阴阜", "淫妇", "淫河", "阴核", "阴户", "淫贱", "淫叫", "淫教师", "阴茎", "阴精", "淫浪", "淫媚", "淫糜", "淫魔", "淫母", "淫女", "淫虐", "淫妻", "淫情", "淫色", "淫声浪语", "淫兽学园", "淫书", "淫术炼金士", "淫水", "淫娃", "淫威", "淫亵", "淫样", "淫液", "淫照", "阴b", "应召", "幼交", "欲火", "欲女", "玉乳", "玉穴", "援交", "原味内衣", "援助交际", "招鸡", "招妓", "抓胸", "自慰", "作爱", "a片", "fuck", "gay片", "g点", "h动画", "h动漫", "失身粉", "淫荡自慰器", "习近平", "平近习", "xjp", "习太子", "习明泽", "老习", "温家宝", "温加宝", "温x", "温jia宝", "温宝宝", "温加饱", "温加保", "张培莉", "温云松", "温如春", "温jb", "胡温", "胡x", "胡jt", "胡boss", "胡总", "胡王八", "hujintao", "胡jintao", "胡j涛", "胡惊涛", "胡景涛", "胡紧掏", "湖紧掏", "胡紧套", "锦涛", "hjt", "胡派", "胡主席", "刘永清", "胡海峰", "胡海清", "江泽民", "民泽江", "江胡", "江哥", "江主席", "江书记", "江浙闽", "江沢民", "江浙民", "择民", "则民", "茳泽民", "zemin", "ze民", "老江", "老j", "江core", "江x", "江派", "江zm", "jzm", "江戏子", "江蛤蟆", "江某某", "江贼", "江猪", "江氏集团", "江绵恒", "江绵康", "王冶坪", "江泽慧", "邓小平", "平小邓", "xiao平", "邓xp", "邓晓平", "邓朴方", "邓榕", "邓质方", "毛泽东", "猫泽东", "猫则东", "猫贼洞", "毛zd", "毛zx", "z东", "ze东", "泽d", "zedong", "毛太祖", "毛相", "主席画像", "改革历程", "朱镕基", "朱容基", "朱镕鸡", "朱容鸡", "朱云来", "李鹏", "李peng", "里鹏", "李月月鸟", "李小鹏", "李小琳", "华主席", "华国", "国锋", "国峰", "锋同志", "白春礼", "薄熙来", "薄一波", "蔡赴朝", "蔡武", "曹刚川", "常万全", "陈炳德", "陈德铭", "陈建国", "陈良宇", "陈绍基", "陈同海", "陈至立", "戴秉国", "丁一平", "董建华", "杜德印", "杜世成", "傅锐", "郭伯雄", "郭金龙", "贺国强", "胡春华", "耀邦", "华建敏", "黄华华", "黄丽满", "黄兴国", "回良玉", "贾庆林", "贾廷安", "靖志远", "李长春", "李春城", "李建国", "李克强", "李岚清", "李沛瑶", "李荣融", "李瑞环", "李铁映", "李先念", "李学举", "李源潮", "栗智", "梁光烈", "廖锡龙", "林树森", "林炎志", "林左鸣", "令计划", "柳斌杰", "刘奇葆", "刘少奇", "刘延东", "刘云山", "刘志军", "龙新民", "路甬祥", "罗箭", "吕祖善", "马飚", "马恺", "孟建柱", "欧广源", "强卫", "沈跃跃", "宋平顺", "粟戎生", "苏树林", "孙家正", "铁凝", "屠光绍", "王东明", "汪东兴", "王鸿举", "王沪宁", "王乐泉", "王洛林", "王岐山", "王胜俊", "王太华", "王学军", "王兆国", "王振华", "吴邦国", "吴定富", "吴官正", "无官正", "吴胜利", "吴仪", "奚国华", "习仲勋", "徐才厚", "许其亮", "徐绍史", "杨洁篪", "叶剑英", "由喜贵", "于幼军", "俞正声", "袁纯清", "曾培炎", "曾庆红", "曾宪梓", "曾荫权", "张德江", "张定发", "张高丽", "张立昌", "张荣坤", "张志国", "赵洪祝", "紫阳", "周生贤", "周永康", "朱海仑", "中南海", "大陆当局", "中国当局", "北京当局", "共产党", "党产共", "共贪党", "阿共", "产党共", "公产党", "工产党", "共c党", "共x党", "共铲", "供产", "共惨", "供铲党", "供铲谠", "供铲裆", "共残党", "共残主义", "共产主义的幽灵", "拱铲", "老共", "中共", "中珙", "中gong", "gc党", "贡挡", "gong党", "g产", "狗产蛋", "共残裆", "恶党", "邪党", "共产专制", "共产王朝", "裆中央", "土共", "土g", "共狗", "g匪", "共匪", "仇共", "政府", "症腐", "政腐", "政付", "正府", "政俯", "政f", "zhengfu", "政zhi", "挡中央", "档中央", "中央领导", "中国zf", "中央zf", "国wu院", "中华帝国", "gong和", "大陆官方", "北京政权", "江泽民", "胡锦涛", "温家宝", "习近平", "习仲勋", "贺国强", "贺子珍", "周永康", "李长春", "李德生", "王岐山", "姚依林", "回良玉", "李源潮", "李干成", "戴秉国", "黄镇", "刘延东", "刘瑞龙", "俞正声", "黄敬", "薄熙", "薄一波", "周小川", "周建南", "温云松", "徐明", "江泽慧", "江绵恒", "江绵康", "李小鹏", "李鹏", "李小琳", "朱云来", "朱容基", "法轮功", "李洪志", "新疆骚乱" ] \ No newline at end of file diff --git a/src/modules/init/init.service.ts b/src/modules/init/init.service.ts index 5615983b..e6ba3b30 100644 --- a/src/modules/init/init.service.ts +++ b/src/modules/init/init.service.ts @@ -1,7 +1,7 @@ import { Injectable, Logger } from '@nestjs/common' import chalk from 'chalk' import { mkdirSync } from 'fs' -import { DATA_DIR, LOGGER_DIR, TEMP_DIR } from 'src/constants/path.constant' +import { DATA_DIR, LOGGER_DIR, TEMP_DIR } from '~/constants/path.constant' @Injectable() export class InitService { diff --git a/src/modules/post/post.module.ts b/src/modules/post/post.module.ts index 1c469c49..56655c94 100644 --- a/src/modules/post/post.module.ts +++ b/src/modules/post/post.module.ts @@ -1,10 +1,10 @@ -import { Module } from '@nestjs/common' +import { forwardRef, Module } from '@nestjs/common' import { CategoryModule } from '../category/category.module' import { PostController } from './post.controller' import { PostService } from './post.service' @Module({ - imports: [CategoryModule], + imports: [forwardRef(() => CategoryModule)], controllers: [PostController], providers: [PostService], exports: [PostService], diff --git a/src/modules/post/post.service.spec.ts b/src/modules/post/post.service.spec.ts index e7b6b3b4..a4f4bc5d 100644 --- a/src/modules/post/post.service.spec.ts +++ b/src/modules/post/post.service.spec.ts @@ -1,7 +1,7 @@ import { Test, TestingModule } from '@nestjs/testing' -import { getFakeCategoryModel } from 'test/db-model.mock' -import { CategoryService } from '../category/category.service' +import { getFakeCategoryModel } from '~/../test/db-model.mock' import { DbModule } from '../../processors/database/database.module' +import { CategoryService } from '../category/category.service' import { PostService } from './post.service' describe('PostService', () => { diff --git a/test/app.e2e-spec.ts b/test/app.e2e-spec.ts index bbdc0289..f46d53e8 100644 --- a/test/app.e2e-spec.ts +++ b/test/app.e2e-spec.ts @@ -1,6 +1,6 @@ -import { Test, TestingModule } from '@nestjs/testing' import { INestApplication } from '@nestjs/common' -import * as request from 'supertest' +import { Test, TestingModule } from '@nestjs/testing' +import request from 'supertest' import { AppModule } from './../src/app.module' describe('AppController (e2e)', () => {