Bladeren bron

增加eslint规范格式,同时修复格式

zhusiqing 3 jaren geleden
bovenliggende
commit
b9a539378b

+ 1 - 0
.eslintignore

@@ -0,0 +1 @@
+*.js

+ 29 - 0
.eslintrc.js

@@ -0,0 +1,29 @@
+/* eslint-disable no-undef */
+module.exports = {
+  env: {
+    node: true,
+    es6: true
+  },
+  parser: '@typescript-eslint/parser',
+  parserOptions: {
+    ecmaVersion: 2020,
+    project: ['./tsconfig.json'],
+    tsconfigRootDir: __dirname,
+    projectFolderIgnoreList: ['**/node_modules/**', './dist/**', './db/*', './logs/*'],
+    createDefaultProgram: true
+  },
+  plugins: ['@typescript-eslint'],
+  extends: [
+    'eslint:recommended',
+    'plugin:@typescript-eslint/recommended'
+  ],
+  rules: {
+    'no-var': 'error',
+    'no-extra-semi': 'off',
+    'quotes': [1, 'single'], // 必须使用单引号
+    'semi': [2, 'always'], //语句强制分号结尾
+    '@typescript-eslint/adjacent-overload-signatures': 'error', // 强制函数重载是连续的
+    '@typescript-eslint/no-empty-function': 'off', // 允许空函数
+    '@typescript-eslint/no-extra-semi': ['error'], // 多余分号去掉
+  }
+};

+ 2 - 1
README.md

@@ -44,7 +44,7 @@
 - [x] 本地缓存和本地嵌入式数据库插件
 - [x] 日志插件
 - [x] 开发环境热更新和生产环境pm2部署
-- [ ] eslint代码风格规范化
+- [x] eslint代码风格规范化
 - [ ] mysql插件
 - [ ] mongo插件
 - [ ] 邮件系统插件
@@ -53,6 +53,7 @@
 - [ ] 加密服务的完善(目前只有针对id的加解密,后续拓展MD5、hash等加密方式)
 - [ ] websocket服务完善
 - [ ] 项目结构和代码优化调整
+- [ ] docker化?
 
 ## 安装
 

+ 3 - 0
package.json

@@ -53,6 +53,9 @@
     "@types/node": "^14.11.2",
     "@types/redis": "^2.8.27",
     "@types/ws": "^7.4.6",
+    "@typescript-eslint/eslint-plugin": "^4.29.0",
+    "@typescript-eslint/parser": "^4.29.0",
+    "eslint": "^7.32.0",
     "ts-node": "^9.0.0",
     "tsconfig-paths": "^3.9.0",
     "typescript": "^4.0.3"

+ 8 - 8
src/app.ts

@@ -26,7 +26,7 @@ import localDbMiddleware from './middlewares/localDb';
 import server from '@utils/server';
 import Plugins from '@/plugins';
 
-const plugins =  Plugins()
+const plugins =  Plugins();
 
 const app = new Koa<DefaultState, Context>();
 
@@ -38,7 +38,7 @@ app.proxy = true;
 // 安全防护
 app.use(helmet());
 // 静态资源
-app.use(koaStatic(path.join(__dirname, config.staticPath)))
+app.use(koaStatic(path.join(__dirname, config.staticPath)));
 // 返回体格式
 app.use(responseMiddleware());
 // post params解析
@@ -47,7 +47,7 @@ app.use(bodyParser());
 app.use(logsMiddleware(plugins.logger.middleware));
 
 // 本地嵌入式数据库
-app.use(localDbMiddleware(plugins.db))
+app.use(localDbMiddleware(plugins.db));
 // redis
 app.use(redisMiddleware({
   redis: plugins.redis,
@@ -56,14 +56,14 @@ app.use(redisMiddleware({
 // 限流
 app.use(limitMiddleware());
 // session
-app.use(sessionMiddleware(app))
+app.use(sessionMiddleware(app));
 // auth
 // app.use(authMiddleware())
 
 // 请求转发
-const { run, ...proxyOptions } = config.proxy
+const { run, ...proxyOptions } = config.proxy;
 if (run) {
-  app.use(koaProxy('/proxy', { ...proxyOptions }))
+  app.use(koaProxy('/proxy', { ...proxyOptions }));
 }
 
 app.on('error', (err, ctx: Context) => {
@@ -71,10 +71,10 @@ app.on('error', (err, ctx: Context) => {
   const errMsg: string = err.message || '服务出错';
   console.log(errMsg);
   console.log(ctx);
-  plugins.logger.middleware(ctx).error(errMsg)
+  plugins.logger.middleware(ctx).error(errMsg);
 });
 
 // 注册路由
 app.use(router.routes()).use(router.allowedMethods());
 
-server(app)
+server(app);

+ 1 - 1
src/config.ts

@@ -36,7 +36,7 @@ export default {
     target: 'https://demo.com',
     changeOrigin: true,
     logs: true,
-    rewrite: path => path.replace(/^\/proxy(\/|\/\w+)?$/, '/')
+    rewrite: (path: string): string => path.replace(/^\/proxy(\/|\/\w+)?$/, '/')
   },
   websocket: {
     run: false

+ 21 - 21
src/controllers/document.ts

@@ -11,19 +11,19 @@ export interface InterfaceDocument {
   responseSuccess?: string
   responseError?: string
   _id?: string,
-};
+}
 interface InterfaceRequestList {
   title: string
   type: string
   require: boolean
   defaultValue?: string
   content?: string
-};
+}
 
 export interface InterfacePage {
   page: number
   size: number
-};
+}
 
 export interface InterfaceTag {
   name: string
@@ -34,7 +34,7 @@ export interface InterfaceDocumentList {
   _id: string
 }
 
-const putDocument = async (ctx: Context) => {
+const putDocument = async (ctx: Context): Promise<void> => {
   const { method, title, url, requestList = [], tag }: InterfaceDocument = ctx.request.body;
   if (!method || !title || !url || !tag) {
     ctx.status = 400;
@@ -46,47 +46,47 @@ const putDocument = async (ctx: Context) => {
     ctx.status = 400;
     ctx.body = ctx.$response(null, '必填项参数缺失', false, CODE.MISS_PARAMS);
     return;
-  };
+  }
   const data = await services.document.putDocument(ctx, ctx.request.body);
   ctx.body = ctx.$response(data.data, data.message, data.success, data.code);
 };
 
-const getDocument = async (ctx:Context) => {
+const getDocument = async (ctx:Context): Promise<void> => {
   const { id } = ctx.params;
   if (!id) {
     ctx.status = 400;
     ctx.body = ctx.$response(null, '数据不存在', false, CODE.MISS_PARAMS);
     return;
-  };
+  }
   const data = await services.document.getDocument(ctx, id);
   ctx.body = ctx.$response(data.data, data.message, data.success, data.code);
 };
 
-const getDocumentList = async (ctx:Context) => {
+const getDocumentList = async (ctx:Context): Promise<void> => {
   const { _id } = ctx.query;
   const data = await services.document.getDocumentList(ctx, { _id });
   ctx.body = ctx.$response(data.data, data.message, data.success, data.code);
 };
 
-const deleteDocument = async (ctx:Context) => {
+const deleteDocument = async (ctx:Context): Promise<void> => {
   const { id } = ctx.params;
   if (!id) {
     ctx.status = 400;
     ctx.body = ctx.$response(null, '数据不存在', false, CODE.MISS_PARAMS);
     return;
-  };
+  }
   const data = await services.document.deleteDocument(ctx, id);
   ctx.body = ctx.$response(data.data, data.message, data.success, data.code);
 };
 
-const updateDocument = async (ctx:Context) => {
+const updateDocument = async (ctx:Context): Promise<void> => {
   const { id: _id } = ctx.params;
   const { method, title, url, requestList = [] }: InterfaceDocument = ctx.request.body;
   if (!_id) {
     ctx.status = 400;
     ctx.body = ctx.$response(null, '数据不存在', false, CODE.MISS_PARAMS);
     return;
-  };
+  }
 
   if (!method || !title || !url) {
     ctx.status = 400;
@@ -98,23 +98,23 @@ const updateDocument = async (ctx:Context) => {
     ctx.status = 400;
     ctx.body = ctx.$response(null, '必填项参数缺失', false, CODE.MISS_PARAMS);
     return;
-  };
+  }
   const data = await services.document.updateDocument(ctx, { _id, ...ctx.request.body });
   ctx.body = ctx.$response(data.data, data.message, data.success, data.code);
 };
 
-const putTag = async (ctx:Context) => {
+const putTag = async (ctx:Context): Promise<void> => {
   const { name }: InterfaceTag = ctx.request.body;
   if (!name) {
     ctx.status = 400;
     ctx.body = ctx.$response(null, '必填项参数缺失', false, CODE.MISS_PARAMS);
     return;
-  };
+  }
   const data = await services.document.putTag(ctx, ctx.request.body);
   ctx.body = ctx.$response(data.data, data.message, data.success, data.code);
 };
 
-const updateTag = async (ctx:Context) => {
+const updateTag = async (ctx:Context): Promise<void> => {
   const { id: _id } = ctx.params;
   const { name }: InterfaceTag = ctx.request.body;
   console.log(name, _id);
@@ -122,28 +122,28 @@ const updateTag = async (ctx:Context) => {
     ctx.status = 400;
     ctx.body = ctx.$response(null, '必填项参数缺失', false, CODE.MISS_PARAMS);
     return;
-  };
+  }
   const data = await services.document.updateTag(ctx, { _id, ...ctx.request.body });
   ctx.body = ctx.$response(data.data, data.message, data.success, data.code);
 };
 
-const getTagList = async (ctx:Context) => {
+const getTagList = async (ctx:Context): Promise<void> => {
   const { page, size } = ctx.query;
   const params = {
     page: page || 1,
     size: size || 10
-  }
+  };
   const data = await services.document.getTagList(ctx, params);
   ctx.body = ctx.$response(data.data, data.message, data.success, data.code);
 };
 
-const deleteTag = async (ctx:Context) => {
+const deleteTag = async (ctx:Context): Promise<void> => {
   const { id } = ctx.params;
   if (!id) {
     ctx.status = 400;
     ctx.body = ctx.$response(null, '数据不存在', false, CODE.MISS_PARAMS);
     return;
-  };
+  }
   const data = await services.document.deleteTag(ctx, id);
   ctx.body = ctx.$response(data.data, data.message, data.success, data.code);
 };

+ 19 - 20
src/controllers/index.ts

@@ -5,40 +5,39 @@ import services from '../services';
 import path from 'path';
 import { readFileSync } from 'fs';
 import http from 'http';
-
-const home = async (ctx: Context) => {
-  let a: string
+interface InterfaceParams {
+  phone?: string
+}
+const home = async (ctx: Context): Promise<void> => {
+  let a: string;
   await new Promise<void>((resolve) => {
     http.get('http://dev.ldy.client.qihoo.net/api/client/thirdapi/filedownload?id=1002&f_key=QEzedKKG9w3ljmtWYbwDaXz1d1hKgI6U_2019070310081642.zip&timestamp=1625652728&vulid=LDY-2021-00001795&token=515A016F0BEA3DBA5A7D9A0E5C776808', res => {
       res.on('data', d => {
-        a += d
-      })
+        a += d;
+      });
       res.on('end', () => {
         console.log(typeof a);
-        resolve()
+        resolve();
         // writeFileSync(path.resolve(__dirname, './test.zip'), a)
-      })
-    })
-  })
+      });
+    });
+  });
   ctx.body = 'home';
 };
 // TODO: ws 待开发状态
-const ws = async (ctx:Context) => {
-  ctx.body = readFileSync(path.resolve(__dirname, '../../example/ws.html')).toString()
-}
+const ws = async (ctx:Context): Promise<void> => {
+  ctx.body = readFileSync(path.resolve(__dirname, '../../example/ws.html')).toString();
+};
 
 // TODO: 读取验证码,待开发状态
-const code = async (ctx: Context) => {
-  interface params {
-    phone?: string
-  }
-  const params: params = {}
-  params.phone = ctx.query.phone
+const code = async (ctx: Context): Promise<void> => {
+  const params: InterfaceParams = {};
+  params.phone = ctx.query.phone;
   if (!params.phone) {
     ctx.status = 400;
     ctx.body = ctx.$response(null, 'phone参数缺失', false, 400000);
     return;
-  };
+  }
   const body = await services.code(ctx, params);
   ctx.body = ctx.$response(body);
 };
@@ -49,4 +48,4 @@ export default {
   user,
   document,
   ws
-}
+};

+ 32 - 32
src/controllers/user.ts

@@ -2,7 +2,7 @@ import { Context } from 'koa';
 import services from '../services';
 import CODE from '../utils/code';
 
-interface sessionInterface {
+interface InterfaceSession {
   user?: string
 }
 
@@ -11,61 +11,61 @@ export interface InterfaceRegisterParams {
   password: string
 }
 
-const register = async (ctx: Context) => {
-  const { username, password } = ctx.request.body
+const register = async (ctx: Context): Promise<void> => {
+  const { username, password } = ctx.request.body;
   if (!username) {
-    ctx.body = ctx.$response(null, '用户名不能为空', false, CODE.MISS_PARAMS)
-    return
+    ctx.body = ctx.$response(null, '用户名不能为空', false, CODE.MISS_PARAMS);
+    return;
   }
   if (!password) {
-    ctx.body = ctx.$response(null, '密码不能为空', false, CODE.MISS_PARAMS)
-    return
+    ctx.body = ctx.$response(null, '密码不能为空', false, CODE.MISS_PARAMS);
+    return;
   }
   const params: InterfaceRegisterParams = {
     username,
     password
-  }
-  const data = await services.user.register(ctx, params)
-  ctx.body = ctx.$response(data.data, data.message, data.success, data.code)
-}
+  };
+  const data = await services.user.register(ctx, params);
+  ctx.body = ctx.$response(data.data, data.message, data.success, data.code);
+};
 
-const login = async (ctx: Context) => {
-  const { username, password } = ctx.request.body
+const login = async (ctx: Context): Promise<void> => {
+  const { username, password } = ctx.request.body;
   if (!username) {
-    ctx.body = ctx.$response(null, '用户名不能为空', false, CODE.MISS_PARAMS)
-    return
+    ctx.body = ctx.$response(null, '用户名不能为空', false, CODE.MISS_PARAMS);
+    return;
   }
   if (!password) {
-    ctx.body = ctx.$response(null, '密码不能为空', false, CODE.MISS_PARAMS)
-    return
+    ctx.body = ctx.$response(null, '密码不能为空', false, CODE.MISS_PARAMS);
+    return;
   }
   const params: InterfaceRegisterParams = {
     username,
     password
-  }
-  const data = await services.user.login(ctx, params)
-  ctx.body = ctx.$response(data.data, data.message, data.success, data.code)
-}
+  };
+  const data = await services.user.login(ctx, params);
+  ctx.body = ctx.$response(data.data, data.message, data.success, data.code);
+};
 
-const logout = async (ctx: Context) => {
+const logout = async (ctx: Context): Promise<void> => {
   if (ctx.session) {
-    ctx.session.user = null
+    ctx.session.user = null;
   }
-  ctx.body = ctx.$response(null, '退出成功')
-}
+  ctx.body = ctx.$response(null, '退出成功');
+};
 
-const userInfo = async (ctx: Context) => {
+const userInfo = async (ctx: Context): Promise<void> => {
   if (!ctx.session || !ctx.session.user ) {
-    ctx.body = ctx.$response(null, '未登录', false, CODE.NOT_LOGIN)
-    return
+    ctx.body = ctx.$response(null, '未登录', false, CODE.NOT_LOGIN);
+    return;
   }
-  const session: sessionInterface = ctx.session.toJSON()
-  ctx.body = ctx.$response(session.user)
-}
+  const session: InterfaceSession = ctx.session.toJSON();
+  ctx.body = ctx.$response(session.user);
+};
 
 export default {
   register,
   login,
   logout,
   userInfo
-}
+};

+ 14 - 14
src/middlewares/auth.ts

@@ -1,26 +1,26 @@
 import { Context, Next } from 'koa';
 import CODE from '@utils/code';
-interface sessionInterface {
+interface InterfaceSession {
   user?: string
 }
-const noAuths = ['/api/login', '/api/register']
+const noAuths = ['/api/login', '/api/register'];
 export default () => {
-  return async (ctx: Context, next: Next) => {
+  return async (ctx: Context, next: Next): Promise<void> => {
     if (noAuths.includes(ctx.url)) {
-      await next()
-      return
+      await next();
+      return;
     }
     if (ctx.session) {
-      const session: sessionInterface = ctx.session.toJSON()
+      const session: InterfaceSession = ctx.session.toJSON();
       if (!session.user) {
-        ctx.session.user = null
-        ctx.body = ctx.$response(null, '未登录', false, CODE.NOT_LOGIN)
-        return
+        ctx.session.user = null;
+        ctx.body = ctx.$response(null, '未登录', false, CODE.NOT_LOGIN);
+        return;
       }
-      await next()
+      await next();
     } else {
-      ctx.status = 500
-      ctx.throw(500, 'session获取失败')
+      ctx.status = 500;
+      ctx.throw(500, 'session获取失败');
     }
-  }
-}
+  };
+};

+ 9 - 9
src/middlewares/limit.ts

@@ -1,22 +1,22 @@
 import { Context, Next } from 'koa';
 import config from '@config';
 export default () => {
-  return async (ctx: Context, next: Next) => {
-    const host: string = ctx.host
-    const isMatch = config.checkHost.find(el => host.match(el))
+  return async (ctx: Context, next: Next): Promise<void> => {
+    const host: string = ctx.host;
+    const isMatch = config.checkHost.find(el => host.match(el));
     if (!isMatch) {
       // 域名不对
-      ctx.status = 403
-      ctx.throw(403, '请求出错')
+      ctx.status = 403;
+      ctx.throw(403, '请求出错');
     }
     const ip: string = ctx.ip;
-    const key: string = `client_ip_limit_${ip}`;
+    const key = `client_ip_limit_${ip}`;
     const limit: number = Number(await ctx.$redis.get(key)) || 0;
     if (limit > config.limit.times) {
-      ctx.status = 403
+      ctx.status = 403;
       ctx.throw(403, '请求频次过高');
-      return
-    };
+      return;
+    }
     ctx.$redis.setex(key, config.limit.time, String(limit + 1));
     await next();
   };

+ 2 - 1
src/middlewares/localDb.ts

@@ -1,7 +1,8 @@
 import { LocalDb } from '@/plugins';
+import { Context, Next } from 'koa';
 
 export default (db: LocalDb) => {
-  return async(ctx, next) => {
+  return async(ctx: Context, next: Next): Promise<void> => {
     ctx.$db = db;
     await next();
   };

+ 11 - 11
src/middlewares/logs.ts

@@ -1,39 +1,39 @@
 import { Context, Next } from 'koa';
-import { interfaceLogger, interfaceLogInfo, formatOutputHandle } from '@/plugins/logger';
+import { InterfaceLogger, InterfaceLogInfo, formatOutputHandle } from '@/plugins/logger';
 
-export default (logger: interfaceLogger) => {
+export default (logger: InterfaceLogger): (ctx: Context, next: Next) => Promise<void> => {
   const loggerMiddleware = async(ctx, next) => {
-    const $log = logger(ctx)
+    const $log = logger(ctx);
     ctx.$log = $log;
-    const a = Date.now()
+    const a = Date.now();
     await next();
-    const b = Date.now()
+    const b = Date.now();
     if (ctx.response && ctx.status < 400) {
-      const commonInfo: interfaceLogInfo = {
+      const commonInfo: InterfaceLogInfo = {
         ip: ctx.ip,
         time: b - a
       };
       if (ctx.request.body) {
         commonInfo.params = ctx.request.body;
-      };
-      $log.info(formatOutputHandle(ctx, null, commonInfo))
+      }
+      $log.info(formatOutputHandle(ctx, null, commonInfo));
     }
     else {
       ctx.throw(ctx.status, ctx.response);
     }
-  }
+  };
   return async(ctx: Context, next: Next) => {
     // 静态文件不处理
     const isApi = /^\/api/.test(ctx.url);
     if (!isApi) {
       await next();
       return;
-    };
+    }
     return loggerMiddleware(ctx, next).catch(error => {
       const { body, status = 500, message } = error;
       const errorText = `res: ${JSON.stringify({ status, message, body })}`;
       ctx.$log.error(errorText);
-      ctx.status = status
+      ctx.status = status;
     });
   };
 };

+ 5 - 4
src/middlewares/redis.ts

@@ -1,16 +1,17 @@
 import { Redis, MemoryCache } from '@/plugins';
+import { Context, Next } from 'koa';
 interface InterfaceCache {
   redis: Redis,
   memoryCache: MemoryCache
-};
+}
 
 export default (cache: InterfaceCache) => {
-  return async (ctx, next) => {
+  return async (ctx: Context, next: Next): Promise<void> => {
     if (cache.redis.isUseRedis) { // 如果redis连接失败,采用内存
       ctx.$redis = cache.redis;
     } else {
-      ctx.$redis =cache.memoryCache
-    };
+      ctx.$redis =cache.memoryCache;
+    }
     await next();
   };
 };

+ 2 - 1
src/middlewares/response.ts

@@ -1,6 +1,7 @@
 import response from '@utils/response';
+import { Context, Next } from 'koa';
 export default () => {
-  return async(ctx, next) => {
+  return async(ctx: Context, next: Next): Promise<void> => {
     ctx.$response = response;
     await next();
   };

+ 5 - 4
src/middlewares/session.ts

@@ -1,6 +1,7 @@
+import { Context, Next } from 'koa';
 import session from 'koa-session';
-export default (app) => {
-  app.keys = ['a1b2c3d4']
+export default (app): (ctx: Context, next: Next) => Promise<void> => {
+  app.keys = ['a1b2c3d4'];
   const config = {
     // maxAge: 8.6410e6,
     // overwrite: true,
@@ -10,5 +11,5 @@ export default (app) => {
     renew: false, // 是否在session快过期时刷新session有效期
     // secure: true
   };
-  return session(config, app)
-}
+  return session(config, app);
+};

+ 17 - 16
src/plugins/index.ts

@@ -3,31 +3,32 @@ import config from '@config';
 import RedisPlugin from '@/plugins/redis';
 import MemoryCachePlugin from '@/plugins/memoryCache';
 import LocalDbPlugin from '@/plugins/localDb';
-import MyLogger, { interfaceLog } from '@/plugins/logger';
+import MyLogger, { InterfaceLog } from '@/plugins/logger';
 
 export type Redis = RedisPlugin
 export type MemoryCache = MemoryCachePlugin
 export type LocalDb = LocalDbPlugin
-export type Log = interfaceLog
-const { redis: redisOpt, localDb: localDbOpt } = config
+export type Logger = MyLogger
+export type Log = InterfaceLog
+const { redis: redisOpt, localDb: localDbOpt } = config;
 const redisOption = {
   host: redisOpt.host,
   port: redisOpt.port,
   password: redisOpt.password,
   auth_pass: redisOpt.password,
   retry_strategy: function(this: RedisPlugin, opts: RetryStrategyOptions) {
-    if (opts.error && opts.error.code === "ECONNREFUSED") {
-      opts.error.code
+    if (opts.error && opts.error.code === 'ECONNREFUSED') {
+      opts.error.code;
       // redis连接失败时使用内存存储
-      this.isUseRedis = false
+      this.isUseRedis = false;
       // End reconnecting on a specific error and flush all commands with
       // a individual error
-      return new Error("The server refused the connection");
+      return new Error('The server refused the connection');
     }
     if (opts.total_retry_time > 1000 * 60 * 60) {
       // End reconnecting after a specific timeout and flush all commands
       // with a individual error
-      return new Error("Retry time exhausted");
+      return new Error('Retry time exhausted');
     }
     if (opts.attempt > 10) {
       // End reconnecting with built in error
@@ -36,17 +37,17 @@ const redisOption = {
     // reconnect after
     return Math.min(opts.attempt * 1000, 3000);
   }
-}
-const localDbOption = localDbOpt
+};
+const localDbOption = localDbOpt;
 export default () => {
-  const redis = new RedisPlugin(redisOption)
-  const memoryCache = new MemoryCachePlugin()
-  const localDb = new LocalDbPlugin(localDbOption)
-  const logger = new MyLogger()
+  const redis = new RedisPlugin(redisOption);
+  const memoryCache = new MemoryCachePlugin();
+  const localDb = new LocalDbPlugin(localDbOption);
+  const logger = new MyLogger();
   return {
     redis,
     memoryCache,
     db: localDb,
     logger
-  }
-}
+  };
+};

+ 15 - 13
src/plugins/localDb.ts

@@ -1,26 +1,28 @@
 import Nedb from 'nedb';
 import { resolve } from 'path';
-import config from '@config';
 
 export interface InterfaceDB {
   [key: string]: Nedb
-};
-
-const { localDb } = config;
-const filename = name => resolve(localDb._dir, name);
-
+}
+interface InterfaceLocalDb {
+  [key: string]: string
+}
 class LocalDb {
   db: InterfaceDB
-  constructor(options) {
-    const db: InterfaceDB = {}
-    const { _dir, ...opts } = options
+  constructor(options: InterfaceLocalDb) {
+    const db: InterfaceDB = {};
+    const { _dir, ...opts } = options;
+    if (!_dir) {
+      throw new Error('LocalDb options _dir is must have');
+    }
+    const filename = name => resolve(_dir, name);
     Object.entries(opts).forEach(([key, value]) => {
       db[key] = new Nedb({
         filename: filename(value),
         autoload: true
-      })
-    })
-    this.db = db
+      });
+    });
+    this.db = db;
   }
 }
-export default LocalDb
+export default LocalDb;

+ 31 - 30
src/plugins/logger.ts

@@ -2,32 +2,32 @@ import log4js, { DateFileAppender, ConsoleAppender, Logger } from 'log4js';
 import path from 'path';
 import { Context } from 'koa';
 import config from '@config';
-export interface interfaceLogInfo {
+export interface InterfaceLogInfo {
   ip: string,
-  params?: any,
+  params?: unknown,
   time?: number
 }
-export interface interfaceLogger {
-  (ctx: Context): interfaceLog
+export interface InterfaceLogger {
+  (ctx: Context): InterfaceLog
 }
-export interface interfaceLog {
-  trace: interfaceLogFn
-  debug: interfaceLogFn
-  info: interfaceLogFn
-  warn: interfaceLogFn
-  error: interfaceLogFn
-  fatal: interfaceLogFn
-  mark: interfaceLogFn
+export interface InterfaceLog {
+  trace: InterfaceLogFn
+  debug: InterfaceLogFn
+  info: InterfaceLogFn
+  warn: InterfaceLogFn
+  error: InterfaceLogFn
+  fatal: InterfaceLogFn
+  mark: InterfaceLogFn
 }
-interface interfaceLogFn {
-  (message: any): void;
+interface InterfaceLogFn {
+  (message: string): void;
 }
-interface interfaceAppenders {
+interface InterfaceAppenders {
   [key: string]: DateFileAppender | ConsoleAppender
 }
 
 // 输出格式化配置
-export const formatOutputHandle = (ctx, message: string | null | undefined , commonInfo: interfaceLogInfo) => {
+export const formatOutputHandle = (ctx: Context, message: string | null | undefined , commonInfo: InterfaceLogInfo): string => {
   const {
     method, // 请求方式
     headers, // 请求headers
@@ -37,7 +37,7 @@ export const formatOutputHandle = (ctx, message: string | null | undefined , com
   const {
     time,
     ...newCommonInfo
-   } = commonInfo
+   } = commonInfo;
   interface client {
     originalUrl: string,
     userAgent: string,
@@ -49,17 +49,17 @@ export const formatOutputHandle = (ctx, message: string | null | undefined , com
   };
   if (ctx.querystring) {
     client.query = ctx.querystring;
-  };
+  }
   let text = `[${method}] ${ctx.status} [${origin}${originalUrl}] ${time ? time + 'ms' : ''}
 req: ${JSON.stringify(Object.assign(client, newCommonInfo))}`;
 
   if (['[object Object]', '[object Array]', '[object Error]'].includes(Object.prototype.toString.call(message))) {
     message = JSON.stringify(message);
-  };
+  }
 
   if (message) {
     text += '\n' + String(message);
-  };
+  }
   return text;
 };
 
@@ -77,16 +77,17 @@ export default class MyLogger {
   // log配置
   logConfig = Object.assign({}, defaultConfig, config.logs);
   // 记录日志的方式
-  appenders: interfaceAppenders = {}
+  appenders: InterfaceAppenders = {}
   // 记录日志的类型
   categories
   // 是否是开发环境
-  isDev: boolean = false
+  isDev = false
   // log4js实例
   logger: Logger = {} as Logger
   constructor() {
+    this.init();
   }
-  init() {
+  init(): void {
     const { env, appLogLevel, dir } = this.logConfig;
     /**
      * 记录日志的方式
@@ -104,7 +105,7 @@ export default class MyLogger {
     //     layout: object
     //   }
     // }
-    const appenders: interfaceAppenders = {
+    const appenders: InterfaceAppenders = {
       log: {
         // 按日期进行输出log
         type: 'dateFile',
@@ -129,9 +130,9 @@ export default class MyLogger {
           pattern: '%[[%d{yyyy-MM-dd hh:mm:ss}] [%p] %c%] %m%n'
         }
       };
-    };
-    this.isDev = isDev
-    this.appenders = appenders
+    }
+    this.isDev = isDev;
+    this.appenders = appenders;
     /**
      * 指定日志的默认配置项
      * 如果 log4js.getLogger 中没有指定,默认为 appenders中的日志配置项, 数组
@@ -143,7 +144,7 @@ export default class MyLogger {
         level: appLogLevel
       }
     };
-    this.categories = categories
+    this.categories = categories;
     // log4js配置
     log4js.configure({
       appenders,
@@ -154,8 +155,8 @@ export default class MyLogger {
     // 初始化log4js
     this.logger = log4js.getLogger('log');
   }
-  middleware(ctx: Context): interfaceLog {
-    const $log: interfaceLog = {
+  middleware(ctx: Context): InterfaceLog {
+    const $log: InterfaceLog = {
       trace: () => {},
       debug: () => {},
       info: () => {},

+ 10 - 10
src/plugins/memoryCache.ts

@@ -4,28 +4,28 @@ class MemoryCache {
   _cache: NodeCacheLegacyCallbacks
   constructor(options?: Options) {
     // 内存存储实例化
-    this._cache = new nodeCache(options)
+    this._cache = new nodeCache(options);
   }
   // 内存存储promise化,为了和redis使用方法保持一致
   get = (key: string): Promise<string|undefined> => {
     console.log(key);
     return new Promise(resolve => {
-      resolve(this._cache.get(key))
-    })
+      resolve(this._cache.get(key));
+    });
   }
-  set = (key: string, ttl: number = 0, value: string): Promise<boolean> => {
+  set = (key: string, ttl = 0, value: string): Promise<boolean> => {
     return new Promise((resolve, reject) => {
-      const success = this._cache.set(key, value, ttl)
+      const success = this._cache.set(key, value, ttl);
       if (success) {
-        resolve(success)
+        resolve(success);
       } else {
-        reject(success)
+        reject(success);
       }
-    })
+    });
   }
-  setex = (key: string, ttl: number, value: string, ) => this.set(key, ttl, value)
+  setex = (key: string, ttl: number, value: string): Promise<boolean> => this.set(key, ttl, value)
 }
 
 
 
-export default MemoryCache
+export default MemoryCache;

+ 16 - 16
src/plugins/redis.ts

@@ -8,26 +8,26 @@ const promisify = util.promisify;
 class Redis {
   _options: ClientOpts = {};
   // 是否使用redis
-  isUseRedis: boolean = false;
+  isUseRedis = false;
   client: RedisClient | null;
   constructor(options: ClientOpts) {
-    this._options = options
-    const client = this.initClient(options)
-    this.client = client
+    this._options = options;
+    const client = this.initClient(options);
+    this.client = client;
   }
-  initClient(options: ClientOpts) {
+  initClient(options: ClientOpts): RedisClient {
     // 创建redis连接
-    const client = redis.createClient(options)
+    const client = redis.createClient(options);
     client.on('error', err => {
       consola.error(err);
     });
     client.on('ready', () => {
       consola.success('redis is ready');
-      this.init(client)
+      this.init(client);
     });
     client.on('connect', () => {
       consola.success('redis is connected');
-      this.isUseRedis = true
+      this.isUseRedis = true;
     });
     client.on('reconnecting', () => {
       consola.warn('redis is reconnecting...');
@@ -35,18 +35,18 @@ class Redis {
     client.on('end', () => {
       consola.warn('redis is closed');
     });
-    return client
+    return client;
   }
-  get = (key) => this.client?.get &&  promisify(this.client.get).bind(this.client)(key)
-  set = (key, value) =>this.client?.set && promisify(this.client.set).bind(this.client)(key, value)
-  setex = (key, ttl, value) => this.client?.setex && promisify(this.client.setex).bind(this.client)(key, ttl, value)
-  init(client) {
+  get = (key: string): Promise<string | null> | undefined => this.client?.get && promisify(this.client.get).bind(this.client)(key)
+  set = (key: string, value: string): Promise<unknown> | undefined => this.client?.set && promisify(this.client.set).bind(this.client)(key, value)
+  setex = (key: string, ttl: number, value: string): Promise<unknown> | undefined => this.client?.setex && promisify(this.client.setex).bind(this.client)(key, ttl, value)
+  init(client: redis.RedisClient): void {
     // redis查询和设置await/async化
     this.get = (key) => promisify(client.get).bind(this.client)(key);
-    this.set = (key, value) => promisify(client.set).bind(this.client)(key, value)
-    this.setex = (key, ttl, value) => promisify(client.setex).bind(this.client)(key, ttl, value)
+    this.set = (key, value) => promisify(client.set).bind(this.client)(key, value);
+    this.setex = (key, ttl, value) => promisify(client.setex).bind(this.client)(key, ttl, value);
   }
 
 }
 
-export default Redis
+export default Redis;

+ 24 - 24
src/services/document.ts

@@ -17,33 +17,33 @@ const putDocument = async (ctx: Context, params: InterfaceDocument) :Promise<Int
         ctx.status = 500;
         resolve(reData);
         return;
-      };
+      }
       if (findDoc) {
         reData.message = 'url已存在';
         reData.code = CODE.EXIST_PARAMS;
         resolve(reData);
         return;
-      };
+      }
       ctx.$db.tag.findOne({ _id: params.tag }, (err, findTag) => {
         if (err) {
           ctx.$log.error(err);
           ctx.status = 500;
           resolve(reData);
           return;
-        };
+        }
         if (!findTag) {
           reData.message = '版本不存在';
           reData.code = CODE.ERR_PARAMS;
           resolve(reData);
           return;
-        };
+        }
         ctx.$db.doc.insert(params, (err, saveDoc) => {
           if (err) {
             ctx.$log.error(err);
             ctx.status = 500;
             resolve(reData);
             return;
-          };
+          }
           reData.data = saveDoc;
           reData.message = '保存成功';
           reData.success = true;
@@ -70,7 +70,7 @@ const getDocument = async (ctx: Context, id: string) :Promise<InterfaceResponseD
         ctx.status = 500;
         resolve(reData);
         return;
-      };
+      }
       findDoc._id = id;
       findDoc.method_des = MapDocMethod[findDoc.method];
       reData.data = findDoc;
@@ -96,7 +96,7 @@ const getDocumentList = async (ctx: Context, params: InterfaceDocumentList) :Pro
           ctx.status = 500;
           resolve(reData);
           return;
-        };
+        }
         docs.forEach(el => {
           el._id = cipher(el._id);
           el.method_des = MapDocMethod[el.method];
@@ -112,7 +112,7 @@ const getDocumentList = async (ctx: Context, params: InterfaceDocumentList) :Pro
             ctx.status = 500;
             resolve(reData);
             return;
-          };
+          }
           reData.data.total = count;
           resolve(reData);
         });
@@ -135,7 +135,7 @@ const deleteDocument = async (ctx: Context, id: string) :Promise<InterfaceRespon
         ctx.status = 500;
         resolve(reData);
         return;
-      };
+      }
       reData.data = null;
       reData.message = '删除成功';
       reData.success = true;
@@ -160,20 +160,20 @@ const updateDocument = async (ctx:Context, { _id, tag, ...params }: InterfaceDoc
         ctx.status = 500;
         resolve(reData);
         return;
-      };
+      }
       if (!findTag) {
         reData.message = '版本不存在';
         reData.code = CODE.ERR_PARAMS;
         resolve(reData);
         return;
-      };
+      }
       ctx.$db.doc.update({ _id: decodeId }, { $set: { ...params }}, {}, err => {
         if (err) {
           ctx.$log.error(err);
           ctx.status = 500;
           resolve(reData);
           return;
-        };
+        }
           reData.data = null;
           reData.message = '更新成功';
           reData.success = true;
@@ -194,25 +194,25 @@ const putTag = async (ctx:Context, params: InterfaceTag) :Promise<InterfaceRespo
   return new Promise(resolve => {
     ctx.$db.tag.findOne({ name: params.name }, (err, findTag) => {
       if (err) {
-        ctx.$log.error(err)
+        ctx.$log.error(err);
         ctx.status = 500;
         resolve(reData);
         return;
-      };
+      }
       if (findTag) {
         reData.message = '版本已经存在';
         reData.code = CODE.EXIST_PARAMS;
         reData.success = false;
         resolve(reData);
         return;
-      };
+      }
       ctx.$db.tag.insert(params, (err, saveTag) => {
         if (err) {
           ctx.$log.error(err);
           ctx.status = 500;
           resolve(reData);
           return;
-        };
+        }
         reData.data = saveTag;
         reData.message = '保存成功';
         reData.success = true;
@@ -237,14 +237,14 @@ const updateTag = async (ctx:Context, { _id, ...params }: InterfaceTag) :Promise
         ctx.status = 500;
         resolve(reData);
         return;
-      };
+      }
       if (!findTag) {
         reData.message = '数据不存在';
         reData.code = CODE.ERR_PARAMS;
         reData.success = false;
         resolve(reData);
         return;
-      };
+      }
       ctx.$db.tag.findOne({ name: params.name }, (err, findTagName) => {
         if (err) {
           ctx.$log.error(err);
@@ -265,13 +265,13 @@ const updateTag = async (ctx:Context, { _id, ...params }: InterfaceTag) :Promise
             ctx.status = 500;
             resolve(reData);
             return;
-          };
+          }
           reData.message = '保存成功';
           reData.success = true;
           reData.code = CODE.SUCCESS;
           resolve(reData);
         });
-      })
+      });
 
     });
   });
@@ -291,7 +291,7 @@ const getTagList = async (ctx: Context, params: InterfacePage) :Promise<Interfac
           ctx.status = 500;
           resolve(reData);
           return;
-        };
+        }
         reData.data = {
           list: tags,
           page: params.page,
@@ -306,7 +306,7 @@ const getTagList = async (ctx: Context, params: InterfacePage) :Promise<Interfac
             ctx.status = 500;
             resolve(reData);
             return;
-          };
+          }
           reData.data.total = count;
           resolve(reData);
         });
@@ -328,7 +328,7 @@ const deleteTag = async (ctx: Context, id: string) :Promise<InterfaceResponseDat
         ctx.status = 500;
         resolve(reData);
         return;
-      };
+      }
       reData.data = null;
       reData.message = '删除成功';
       reData.success = true;
@@ -348,4 +348,4 @@ export default {
   updateTag,
   getTagList,
   deleteTag
-}
+};

+ 5 - 2
src/services/index.ts

@@ -1,7 +1,10 @@
 import { Context } from 'koa';
 import user from './user';
 import document from './document';
-const code = async (ctx: Context, params) => {
+interface InterfaceParams {
+  phone?: string
+}
+const code = async (ctx: Context, params: InterfaceParams): Promise<string> => {
   const code = await ctx.$redis.get(`send_sms_verify_code_sms_${params.phone}`);
   return code || 'no code';
 };
@@ -10,4 +13,4 @@ export default {
   code,
   user,
   document
-}
+};

+ 36 - 36
src/services/user.ts

@@ -9,39 +9,39 @@ const register = async (ctx: Context, params: InterfaceRegisterParams) :Promise<
     message: '',
     success: false,
     code: 400000
-  }
+  };
   return new Promise(resolve => {
     ctx.$db.user.findOne({ username: params.username }, (err, findUser) => {
       if (err) {
-        ctx.$log.error(err)
-        ctx.status = 500
+        ctx.$log.error(err);
+        ctx.status = 500;
         resolve(reData);
-        return
+        return;
       }
       if (findUser) {
-        reData.message = '用户名已存在'
-        reData.code = CODE.EXIST_PARAMS
-        resolve(reData)
-        return
+        reData.message = '用户名已存在';
+        reData.code = CODE.EXIST_PARAMS;
+        resolve(reData);
+        return;
       }
       ctx.$db.user.insert(params, (err, saveUser) => {
         if (err) {
-          ctx.$log.error(err)
-          ctx.status = 500
+          ctx.$log.error(err);
+          ctx.status = 500;
           resolve(reData);
-          return
+          return;
         }
         reData.data = saveUser;
-        reData.message = '注册成功'
-        reData.success = true
-        reData.code = CODE.SUCCESS
+        reData.message = '注册成功';
+        reData.success = true;
+        reData.code = CODE.SUCCESS;
         if (ctx.session) {
-          ctx.session.user = saveUser
+          ctx.session.user = saveUser;
         }
-        resolve(reData)
-      })
-    })
-  })
+        resolve(reData);
+      });
+    });
+  });
 };
 
 const login = async (ctx: Context, params: InterfaceRegisterParams) :Promise<InterfaceResponseData> => {
@@ -50,40 +50,40 @@ const login = async (ctx: Context, params: InterfaceRegisterParams) :Promise<Int
     message: '',
     success: false,
     code: 400000
-  }
+  };
   return new Promise(resolve => {
     ctx.$db.user.findOne({ username: params.username }, (err, findUser) => {
       if (err) {
         ctx.$log.error(err);
         ctx.status = 500;
         resolve(reData);
-        return
+        return;
       }
       if (!findUser) {
-        reData.message = '用户名或密码错误'
-        reData.code = CODE.MISS_PARAMS
-        resolve(reData)
-        return
+        reData.message = '用户名或密码错误';
+        reData.code = CODE.MISS_PARAMS;
+        resolve(reData);
+        return;
       }
       if (params.password === findUser.password) {
         if (ctx.session) {
-          ctx.session.user = findUser
+          ctx.session.user = findUser;
         }
         reData.data = findUser;
-        reData.message = '登录成功'
-        reData.success = true
-        reData.code = CODE.SUCCESS
-        resolve(reData)
+        reData.message = '登录成功';
+        reData.success = true;
+        reData.code = CODE.SUCCESS;
+        resolve(reData);
       } else {
-        reData.message = '用户名或密码错误'
-        reData.code = CODE.MISS_PARAMS
-        resolve(reData)
+        reData.message = '用户名或密码错误';
+        reData.code = CODE.MISS_PARAMS;
+        resolve(reData);
       }
-    })
-  })
+    });
+  });
 };
 
 export default {
   register,
   login
-}
+};

+ 2 - 5
src/typings/index.d.ts

@@ -1,13 +1,10 @@
-import { Application, Context, DefaultContext } from 'koa';
-import { IMiddleware } from 'koa-router';
-import { RedisClient } from 'redis';
 import { responseHandle } from '@utils/response';
 import { InterfaceDB } from '../middlewares/localDb';
-import { Redis, Log } from '@/plugins';
+import { Redis, Log, MemoryCache } from '@/plugins';
 
 declare module 'koa' {
   export interface Context extends DefaultContext {
-    $redis: Redis
+    $redis: Redis | MemoryCache
     $response: responseHandle
     $log: Log
     $db: InterfaceDB

+ 2 - 2
src/utils/cipher.ts

@@ -6,14 +6,14 @@ const salt = '123';
 const key = scryptSync(config.secrestKey, salt, 24);
 const iv = Buffer.alloc(16, '11');
 // 加密
-export const cipher = (data: string) => {
+export const cipher = (data: string): string => {
   const cipher = createCipheriv(algorithm, key, iv);
   let enc = cipher.update(data, 'utf8', 'hex');
   enc += cipher.final('hex');
   return enc;
 };
 // 解密
-export const decipher = (data: string) => {
+export const decipher = (data: string): string => {
   const decipher = createDecipheriv(algorithm, key, iv);
   let dec = decipher.update(data, 'hex', 'utf8');
   dec += decipher.final('utf8');

+ 7 - 7
src/utils/getLocalIp.ts

@@ -1,13 +1,13 @@
 import { networkInterfaces } from 'os';
 
-export function getLocalIp() {
-  const ips = networkInterfaces()
-  let ip
+export function getLocalIp(): string {
+  const ips = networkInterfaces();
+  let ip;
   Object.values(ips).forEach(el => {
-    const matchIp = el?.find(element => element.family === 'IPv4')
+    const matchIp = el?.find(element => element.family === 'IPv4');
     if (matchIp && matchIp.address !== '127.0.0.1') {
-      ip = matchIp.address
+      ip = matchIp.address;
     }
-  })
-  return ip
+  });
+  return ip;
 }

+ 26 - 24
src/utils/observer.ts

@@ -1,68 +1,70 @@
-const objToString = (param: any) => Object.prototype.toString.call(param);
-
+const objToString = (param: unknown) => Object.prototype.toString.call(param);
+interface InterfaceCallback {
+  (...p): void
+}
 export class Observer {
-  private handle: Map<string, [Function?]>
+  private handle: Map<string, [InterfaceCallback?]>
   constructor() {
-    this.handle = new Map()
-  };
+    this.handle = new Map();
+  }
   // 注册监听的事件
-  on(type = '', callback: Function) {
+  on(type = '', callback: InterfaceCallback): void {
     // 校验参数
     if (typeof type !== 'string') {
       const msg = `on type must is string, now is ${objToString(type)}`;
       throw new Error(msg);
-    };
+    }
     if (typeof callback !== 'function') {
       const msg = `callback must is function, now is ${objToString(callback)}`;
       throw new Error(msg);
-    };
+    }
     // 添加监听的事件,同一个事件可以多个函数监听
     if (!this.handle.has(type)) {
       this.handle.set(type, []);
-    };
+    }
     this.handle.get(type)?.push(callback);
-  };
+  }
   // 触发
-  emit (type = '', ...params) {
+  emit (type = '', ...params: unknown[]): void {
     if (typeof type !== 'string') {
       const msg = `emit type must is string, now is ${objToString(type)}`;
       throw new Error(msg);
-    };
+    }
     if (!this.handle.get(type)?.length) {
       const msg = `${type} is not exist`;
       throw new Error(msg);
-    };
-    const forHandle = (el: Function | undefined) => {
+    }
+    const forHandle = (el: InterfaceCallback | undefined) => {
       if (objToString(el) === '[object Function]') {
         el && el(...params);
       } else {
         throw new Error(`${type} is not function`);
-      };
-    }
+      }
+    };
     this.handle.get(type)?.forEach(forHandle.bind(this));
   }
   // 销毁监听的事件
-  destory(type = '') {
+  destory(type = ''): void {
     if (typeof type !== 'string') {
       const msg = `emit type must is string, now is ${objToString(type)}`;
       throw new Error(msg);
-    };
+    }
     if (!this.handle.get(type)?.length) {
       throw new Error(`${type} is not register`);
-    };
+    }
     this.handle.delete(type);
   }
   // 查询是否注册
-  list(type = '') {
+  list(type = ''): [(InterfaceCallback | undefined)?] | unknown {
     if (!type) {
       throw new Error('type is not exist');
-    };
+    }
     if (this.handle.has(type)) {
       return this.handle.get(type);
-    };
+    }
     return null;
-  };
-};
+  }
+}
 
 export const observer = new Observer();
 

+ 18 - 17
src/utils/server.ts

@@ -3,24 +3,25 @@ import WebSocket from 'ws';
 import consola from 'consola';
 import config from '@config';
 import { getLocalIp } from '@utils/getLocalIp';
+import { HttpBase } from 'http';
 
-export default (app: Koa<DefaultState, Context>) => {
+export default (app: Koa<DefaultState, Context>): HttpBase => {
   const port = config.port;
-  const ip = getLocalIp()
+  const ip = getLocalIp();
   const server = app.listen(port, () => {
-    consola.success(`server is started at: http://localhost:${port}`)
-    consola.success(`server is started at: http://${ip}:${port}`)
+    consola.success(`server is started at: http://localhost:${port}`);
+    consola.success(`server is started at: http://${ip}:${port}`);
   });
   if (config.websocket.run) {
     const wsServer = new WebSocket.Server({ server }, () => {
-      consola.success(`websocket server is started at: ws://localhost:${port}`)
-      consola.success(`websocket server is started at: ws://${ip}:${port}`)
-    })
+      consola.success(`websocket server is started at: ws://localhost:${port}`);
+      consola.success(`websocket server is started at: ws://${ip}:${port}`);
+    });
     wsServer.on('error', (err) => {
-      consola.error('websocket error >>>', err)
+      consola.error('websocket error >>>', err);
     }).on('close', () => {
-      consola.info('websocket is closed')
-    })
+      consola.info('websocket is closed');
+    });
     wsServer.on('connection', ws => {
       console.log('ws is connectioned');
       ws.on('message', msg => {
@@ -28,15 +29,15 @@ export default (app: Koa<DefaultState, Context>) => {
         const obj = {
           msg,
           code: 200
-        }
+        };
         ws.send(JSON.stringify(obj), err => {
           if (err) {
-            consola.error('websocket send >>>', err)
+            consola.error('websocket send >>>', err);
           }
-        })
-      })
+        });
+      });
 
-    })
+    });
   }
-  return server
-}
+  return server;
+};

+ 1 - 1
tsconfig.json

@@ -2,7 +2,7 @@
   "compileOnSave": true,
   "compilerOptions": {
     "outDir": "./dist",
-    "target": "es2017",
+    "target": "es2020",
     "module": "commonjs", // 采用commonjs的模块风格
     "strict": true, // 启用所有严格类型检查选项
     "noImplicitAny": false, // 隐式any检查

File diff suppressed because it is too large
+ 638 - 7
yarn.lock


Some files were not shown because too many files changed in this diff