diff --git a/.eslintrc.js b/.eslintrc.js index eac5ab4..09095df 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,144 +1,138 @@ module.exports = { - parser: '@typescript-eslint/parser', - parserOptions: { - project: 'tsconfig.json', - tsconfigRootDir: __dirname, - ecmaVersion: 'latest', - sourceType: 'module', - }, - root: true, - env: { - node: true, - jest: true, - }, - plugins: [ - '@typescript-eslint', - 'jest', - 'prettier', - 'import', - 'unused-imports', - ], - extends: [ - // airbnb规范 - // https://github.com/airbnb/javascript/tree/master/packages/eslint-config-airbnb - 'airbnb-base', - // 兼容typescript的airbnb规范 - // https://github.com/iamturns/eslint-config-airbnb-typescript - 'airbnb-typescript/base', + parser: '@typescript-eslint/parser', + parserOptions: { + project: 'tsconfig.json', + tsconfigRootDir: __dirname, + ecmaVersion: 'latest', + sourceType: 'module', + }, + root: true, + env: { + node: true, + jest: true, + }, + plugins: ['@typescript-eslint', 'jest', 'prettier', 'import', 'unused-imports'], + extends: [ + // airbnb规范 + // https://github.com/airbnb/javascript/tree/master/packages/eslint-config-airbnb + 'airbnb-base', + // 兼容typescript的airbnb规范 + // https://github.com/iamturns/eslint-config-airbnb-typescript + 'airbnb-typescript/base', - // typescript的eslint插件 - // https://github.com/typescript-eslint/typescript-eslint/blob/master/docs/getting-started/linting/README.md - // https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/eslint-plugin - 'plugin:@typescript-eslint/recommended', - 'plugin:@typescript-eslint/recommended-requiring-type-checking', + // typescript的eslint插件 + // https://github.com/typescript-eslint/typescript-eslint/blob/master/docs/getting-started/linting/README.md + // https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/eslint-plugin + 'plugin:@typescript-eslint/recommended', + 'plugin:@typescript-eslint/recommended-requiring-type-checking', - // 支持jest - 'plugin:jest/recommended', - // 使用prettier格式化代码 - // https://github.com/prettier/eslint-config-prettier#readme - 'prettier', - // 整合typescript-eslint与prettier - // https://github.com/prettier/eslint-plugin-prettier - 'plugin:prettier/recommended', - ], - rules: { - /* ********************************** ES6+ ********************************** */ - 'no-console': 0, - 'no-var-requires': 0, - 'no-restricted-syntax': 0, - 'no-continue': 0, - 'no-await-in-loop': 0, - 'no-return-await': 0, - 'no-unused-vars': 0, - 'no-multi-assign': 0, - 'no-param-reassign': [2, { props: false }], - 'import/prefer-default-export': 0, - 'import/no-cycle': 0, - 'import/no-dynamic-require': 0, - 'max-classes-per-file': 0, - 'class-methods-use-this': 0, - 'guard-for-in': 0, - 'no-underscore-dangle': 0, - 'no-plusplus': 0, - 'no-lonely-if': 0, - 'no-bitwise': ['error', { allow: ['~'] }], + // 支持jest + 'plugin:jest/recommended', + // 使用prettier格式化代码 + // https://github.com/prettier/eslint-config-prettier#readme + 'prettier', + // 整合typescript-eslint与prettier + // https://github.com/prettier/eslint-plugin-prettier + 'plugin:prettier/recommended', + ], + rules: { + /* ********************************** ES6+ ********************************** */ + 'no-console': 0, + 'no-var-requires': 0, + 'no-restricted-syntax': 0, + 'no-continue': 0, + 'no-await-in-loop': 0, + 'no-return-await': 0, + 'no-unused-vars': 0, + 'no-multi-assign': 0, + 'no-param-reassign': [2, { props: false }], + 'import/prefer-default-export': 0, + 'import/no-cycle': 0, + 'import/no-dynamic-require': 0, + 'max-classes-per-file': 0, + 'class-methods-use-this': 0, + 'guard-for-in': 0, + 'no-underscore-dangle': 0, + 'no-plusplus': 0, + 'no-lonely-if': 0, + 'no-bitwise': ['error', { allow: ['~'] }], - /* ********************************** Module Import ********************************** */ + /* ********************************** Module Import ********************************** */ - 'import/no-absolute-path': 0, - 'import/extensions': 0, - 'import/no-named-default': 0, - 'no-restricted-exports': 0, + 'import/no-absolute-path': 0, + 'import/extensions': 0, + 'import/no-named-default': 0, + 'no-restricted-exports': 0, - // 一部分文件在导入devDependencies的依赖时不报错 - 'import/no-extraneous-dependencies': [ - 1, - { - devDependencies: [ - '**/*.test.{ts,js}', - '**/*.spec.{ts,js}', - './test/**.{ts,js}', - './scripts/**/*.{ts,js}', + // 一部分文件在导入devDependencies的依赖时不报错 + 'import/no-extraneous-dependencies': [ + 1, + { + devDependencies: [ + '**/*.test.{ts,js}', + '**/*.spec.{ts,js}', + './test/**.{ts,js}', + './scripts/**/*.{ts,js}', + ], + }, ], - }, - ], - // 模块导入顺序规则 - 'import/order': [ - 1, - { - pathGroups: [ - { - pattern: '@/**', - group: 'external', - position: 'after', - }, + // 模块导入顺序规则 + 'import/order': [ + 1, + { + pathGroups: [ + { + pattern: '@/**', + group: 'external', + position: 'after', + }, + ], + alphabetize: { order: 'asc', caseInsensitive: false }, + 'newlines-between': 'always-and-inside-groups', + warnOnUnassignedImports: true, + }, ], - alphabetize: { order: 'asc', caseInsensitive: false }, - 'newlines-between': 'always-and-inside-groups', - warnOnUnassignedImports: true, - }, - ], - // 自动删除未使用的导入 - // https://github.com/sweepline/eslint-plugin-unused-imports - 'unused-imports/no-unused-imports': 1, - 'unused-imports/no-unused-vars': [ - 'error', - { - vars: 'all', - args: 'none', - ignoreRestSiblings: true, - }, - ], - /* ********************************** Typescript ********************************** */ - '@typescript-eslint/no-unused-vars': 0, - '@typescript-eslint/no-empty-interface': 0, - '@typescript-eslint/no-this-alias': 0, - '@typescript-eslint/no-var-requires': 0, - '@typescript-eslint/no-use-before-define': 0, - '@typescript-eslint/explicit-member-accessibility': 0, - '@typescript-eslint/no-non-null-assertion': 0, - '@typescript-eslint/no-unnecessary-type-assertion': 0, - '@typescript-eslint/require-await': 0, - '@typescript-eslint/no-for-in-array': 0, - '@typescript-eslint/interface-name-prefix': 0, - '@typescript-eslint/explicit-function-return-type': 0, - '@typescript-eslint/no-explicit-any': 0, - '@typescript-eslint/explicit-module-boundary-types': 0, - '@typescript-eslint/no-floating-promises': 0, - '@typescript-eslint/restrict-template-expressions': 0, - '@typescript-eslint/no-unsafe-assignment': 0, - '@typescript-eslint/no-unsafe-return': 0, - '@typescript-eslint/no-unused-expressions': 0, - '@typescript-eslint/no-misused-promises': 0, - '@typescript-eslint/no-unsafe-member-access': 0, - '@typescript-eslint/no-unsafe-call': 0, - '@typescript-eslint/no-unsafe-argument': 0, - '@typescript-eslint/ban-ts-comment': 0, - '@typescript-eslint/lines-between-class-members': 0, - '@typescript-eslint/no-throw-literal': 0, - }, + // 自动删除未使用的导入 + // https://github.com/sweepline/eslint-plugin-unused-imports + 'unused-imports/no-unused-imports': 1, + 'unused-imports/no-unused-vars': [ + 'warn', + { + vars: 'all', + args: 'none', + ignoreRestSiblings: true, + }, + ], + /* ********************************** Typescript ********************************** */ + '@typescript-eslint/no-unused-vars': 0, + '@typescript-eslint/no-empty-interface': 0, + '@typescript-eslint/no-this-alias': 0, + '@typescript-eslint/no-var-requires': 0, + '@typescript-eslint/no-use-before-define': 0, + '@typescript-eslint/explicit-member-accessibility': 0, + '@typescript-eslint/no-non-null-assertion': 0, + '@typescript-eslint/no-unnecessary-type-assertion': 0, + '@typescript-eslint/require-await': 0, + '@typescript-eslint/no-for-in-array': 0, + '@typescript-eslint/interface-name-prefix': 0, + '@typescript-eslint/explicit-function-return-type': 0, + '@typescript-eslint/no-explicit-any': 0, + '@typescript-eslint/explicit-module-boundary-types': 0, + '@typescript-eslint/no-floating-promises': 0, + '@typescript-eslint/restrict-template-expressions': 0, + '@typescript-eslint/no-unsafe-assignment': 0, + '@typescript-eslint/no-unsafe-return': 0, + '@typescript-eslint/no-unused-expressions': 0, + '@typescript-eslint/no-misused-promises': 0, + '@typescript-eslint/no-unsafe-member-access': 0, + '@typescript-eslint/no-unsafe-call': 0, + '@typescript-eslint/no-unsafe-argument': 0, + '@typescript-eslint/ban-ts-comment': 0, + '@typescript-eslint/lines-between-class-members': 0, + '@typescript-eslint/no-throw-literal': 0, + }, - settings: { - extensions: ['.ts', '.d.ts', '.cts', '.mts', '.js', '.cjs', 'mjs', '.json'], - }, + settings: { + extensions: ['.ts', '.d.ts', '.cts', '.mts', '.js', '.cjs', 'mjs', '.json'], + }, }; diff --git a/src/main.ts b/src/main.ts index 2c3453a..0a1a17a 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,8 +1,9 @@ import { NestFactory } from '@nestjs/core'; -import { AppModule } from './app.module'; import { FastifyAdapter, NestFastifyApplication } from '@nestjs/platform-fastify'; +import { AppModule } from './app.module'; + async function bootstrap() { const app = await NestFactory.create(AppModule, new FastifyAdapter(), { cors: true, diff --git a/src/modules/content/controllers/post.controller.ts b/src/modules/content/controllers/post.controller.ts index 22ebbd7..d1f7fa6 100644 --- a/src/modules/content/controllers/post.controller.ts +++ b/src/modules/content/controllers/post.controller.ts @@ -1,8 +1,19 @@ -import { Controller, Get } from '@nestjs/common'; +import { + Body, + Controller, + Delete, + Get, + NotFoundException, + Param, + Patch, + Post, +} from '@nestjs/common'; + +import { isNil } from '@nestjs/common/utils/shared.utils'; import { PostEntity } from '../types'; -const posts: PostEntity[] = [ +let posts: PostEntity[] = [ { title: '第一篇文章标题', body: '第一篇文章内容' }, { title: '第二篇文章标题', body: '第二篇文章内容' }, { title: '第三篇文章标题', body: '第三篇文章内容' }, @@ -17,4 +28,45 @@ export class PostController { async index() { return posts; } + + @Get(':id') + async show(@Param('id') id: number) { + const post = posts.find((item) => item.id === Number(id)); + if (isNil(post)) { + throw new NotFoundException(`the post with id ${id} not exits!`); + } + return post; + } + + @Post() + async store(@Body() data: PostEntity) { + const newPost: PostEntity = { + id: Math.max(...posts.map(({ id }) => id + 1)), + ...data, + }; + posts.push(newPost); + return newPost; + } + + @Patch() + async update(@Body() data: PostEntity) { + let toUpdate = posts.find((item) => item.id === Number(data.id)); + if (isNil(toUpdate)) { + throw new NotFoundException(`the post with id ${data.id} not exits!`); + } + + toUpdate = { ...toUpdate, ...data }; + posts = posts.map((item) => (item.id === Number(data.id) ? toUpdate : item)); + return toUpdate; + } + + @Delete(':id') + async delete(@Param('id') id: number) { + const toDelete = posts.find((item) => item.id === Number(id)); + if (isNil(toDelete)) { + throw new NotFoundException(`the post with id ${id} not exits!`); + } + posts = posts.filter((item) => item.id !== Number(id)); + return toDelete; + } }