From 12eeeee0df28b47557327e822921efdeaca66942 Mon Sep 17 00:00:00 2001 From: cool Date: Thu, 28 Sep 2023 14:08:24 +0800 Subject: [PATCH] release 7.x --- .dockerignore => .dockerignore | 0 package.json | 61 +- packages/README.md | 3 + packages/cloud/.editorconfig | 11 - packages/cloud/.eslintrc.json | 20 - packages/cloud/.gitignore | 15 - packages/cloud/.prettierrc.js | 3 - packages/cloud/LICENSE | 21 - packages/cloud/index.d.ts | 10 - packages/cloud/jest.config.js | 7 - packages/cloud/jest.setup.js | 1 - packages/cloud/package.json | 47 -- packages/cloud/src/LICENSE | 21 - packages/cloud/src/config/config.default.ts | 4 - packages/cloud/src/configuration.ts | 22 - packages/cloud/src/db/index.ts | 123 ---- packages/cloud/src/db/source.ts | 10 - packages/cloud/src/func/crud.ts | 525 ---------------- packages/cloud/src/func/index.ts | 17 - packages/cloud/src/index.ts | 10 - packages/cloud/src/interface.ts | 11 - packages/cloud/src/package.json | 42 -- packages/cloud/src/util.ts | 1 - packages/cloud/test/index.test.ts | 14 - packages/cloud/tsconfig.json | 25 - packages/core/LICENSE | 21 - packages/core/README.md | 3 - packages/core/_.editorconfig | 11 - packages/core/_.eslintrc.json | 7 - packages/core/_.gitignore | 15 - packages/core/_.prettierrc.js | 3 - packages/core/index.d.ts | 10 - packages/core/jest.config.js | 7 - packages/core/jest.setup.js | 1 - packages/core/package.json | 56 -- packages/core/src/LICENSE | 21 - packages/core/src/config/config.default.ts | 18 - packages/core/src/configuration.ts | 82 --- packages/core/src/constant/global.ts | 50 -- packages/core/src/controller/base.ts | 203 ------- packages/core/src/decorator/cache.ts | 8 - packages/core/src/decorator/controller.ts | 208 ------- packages/core/src/decorator/event.ts | 42 -- packages/core/src/decorator/index.ts | 103 ---- packages/core/src/decorator/tag.ts | 27 - packages/core/src/decorator/transaction.ts | 19 - packages/core/src/entity/base.ts | 27 - packages/core/src/entity/mongo.ts | 25 - packages/core/src/entity/typeorm.ts | 3 - packages/core/src/event/index.ts | 43 -- packages/core/src/exception/base.ts | 13 - packages/core/src/exception/comm.ts | 15 - packages/core/src/exception/core.ts | 15 - packages/core/src/exception/filter.ts | 20 - packages/core/src/exception/validate.ts | 15 - packages/core/src/index.ts | 45 -- packages/core/src/interface.ts | 387 ------------ packages/core/src/module/config.ts | 100 --- packages/core/src/module/import.ts | 150 ----- packages/core/src/package.json | 55 -- packages/core/src/rest/eps.ts | 124 ---- packages/core/src/service/base.ts | 526 ---------------- packages/core/src/tag/data.ts | 47 -- packages/core/src/util/func.ts | 27 - packages/core/src/util/location.ts | 95 --- packages/core/test/index.test.ts | 14 - packages/core/tsconfig.json | 25 - packages/es/.editorconfig | 11 - packages/es/.eslintrc.json | 28 - packages/es/.gitignore | 15 - packages/es/.prettierrc.js | 3 - packages/es/README.md | 3 - packages/es/index.d.ts | 10 - packages/es/jest.config.js | 7 - packages/es/jest.setup.js | 1 - packages/es/package.json | 44 -- packages/es/src/base.ts | 569 ------------------ packages/es/src/config/config.default.ts | 4 - packages/es/src/configuration.ts | 19 - packages/es/src/decorator/elasticsearch.ts | 41 -- packages/es/src/elasticsearch.ts | 154 ----- packages/es/src/index.ts | 15 - packages/es/src/package.json | 42 -- packages/es/test/index.test.ts | 14 - packages/es/tsconfig.json | 24 - packages/file/.editorconfig | 11 - packages/file/.eslintrc.json | 20 - packages/file/.gitignore | 15 - packages/file/.prettierrc.js | 3 - packages/file/LICENSE | 21 - packages/file/index.d.ts | 10 - packages/file/jest.config.js | 7 - packages/file/jest.setup.js | 1 - packages/file/package.json | 53 -- packages/file/src/config/config.default.ts | 16 - packages/file/src/configuration.ts | 21 - packages/file/src/file.ts | 476 --------------- packages/file/src/index.ts | 5 - packages/file/src/interface.ts | 105 ---- packages/file/src/package.json | 53 -- packages/file/test/index.test.ts | 14 - packages/file/tsconfig.json | 25 - packages/iot/.editorconfig | 11 - packages/iot/.eslintrc.json | 28 - packages/iot/.gitignore | 15 - packages/iot/.prettierrc.js | 3 - packages/iot/README.md | 3 - packages/iot/index.d.ts | 10 - packages/iot/jest.config.js | 7 - packages/iot/jest.setup.js | 1 - packages/iot/package.json | 53 -- packages/iot/src/config/config.default.ts | 13 - packages/iot/src/configuration.ts | 18 - packages/iot/src/decorator/mqtt.ts | 42 -- packages/iot/src/index.ts | 7 - packages/iot/src/interface.ts | 34 -- packages/iot/src/mqtt.ts | 163 ----- packages/iot/src/package.json | 53 -- packages/iot/test/index.test.ts | 14 - packages/iot/tsconfig.json | 24 - packages/other/cache-manager-fs-hash/LICENSE | 21 - .../other/cache-manager-fs-hash/README.md | 81 --- packages/other/cache-manager-fs-hash/index.js | 1 - .../other/cache-manager-fs-hash/package.json | 38 -- .../other/cache-manager-fs-hash/src/index.js | 261 -------- .../src/json-file-store.js | 118 ---- .../src/wrap-callback.js | 21 - .../mqemitter-redis/.github/dependabot.yml | 7 - .../mqemitter-redis/.github/workflows/ci.yml | 35 -- packages/other/mqemitter-redis/.gitignore | 33 - packages/other/mqemitter-redis/.travis.yml | 9 - packages/other/mqemitter-redis/LICENSE | 21 - packages/other/mqemitter-redis/README.md | 76 --- .../other/mqemitter-redis/mqemitter-redis.js | 250 -------- packages/other/mqemitter-redis/package.json | 46 -- packages/other/mqemitter-redis/test.js | 116 ---- .../other/mqemitter-redis/types/index.d.ts | 37 -- .../mqemitter-redis/types/index.test-d.ts | 42 -- packages/pay/.editorconfig | 11 - packages/pay/.eslintrc.json | 28 - packages/pay/.gitignore | 15 - packages/pay/.prettierrc.js | 3 - packages/pay/index.d.ts | 10 - packages/pay/jest.config.js | 7 - packages/pay/jest.setup.js | 1 - packages/pay/package.json | 50 -- packages/pay/src/ali.ts | 56 -- packages/pay/src/config/config.default.ts | 4 - packages/pay/src/configuration.ts | 21 - packages/pay/src/index.ts | 7 - packages/pay/src/interface.ts | 77 --- packages/pay/src/package.json | 50 -- packages/pay/src/wx.ts | 68 --- packages/pay/test/index.test.ts | 14 - packages/pay/tsconfig.json | 24 - packages/rpc/.editorconfig | 11 - packages/rpc/.eslintrc.json | 29 - packages/rpc/.gitignore | 15 - packages/rpc/.prettierrc.js | 3 - packages/rpc/index.d.ts | 10 - packages/rpc/jest.config.js | 7 - packages/rpc/jest.setup.js | 1 - packages/rpc/package.json | 48 -- packages/rpc/src/config/config.default.ts | 6 - packages/rpc/src/configuration.ts | 26 - packages/rpc/src/decorator/event/event.ts | 19 - packages/rpc/src/decorator/event/handler.ts | 23 - packages/rpc/src/decorator/index.ts | 101 ---- packages/rpc/src/decorator/rpc.ts | 84 --- packages/rpc/src/decorator/transaction.ts | 22 - packages/rpc/src/index.ts | 25 - packages/rpc/src/package.json | 48 -- packages/rpc/src/rpc.ts | 275 --------- packages/rpc/src/service/base.ts | 406 ------------- packages/rpc/src/test.ts | 25 - packages/rpc/src/transaction/event.ts | 40 -- packages/rpc/test/index.test.ts | 14 - packages/rpc/tsconfig.json | 24 - packages/sms/.editorconfig | 11 - packages/sms/.eslintrc.json | 28 - packages/sms/.gitignore | 15 - packages/sms/.prettierrc.js | 3 - packages/sms/index.d.ts | 10 - packages/sms/jest.config.js | 7 - packages/sms/jest.setup.js | 1 - packages/sms/package.json | 49 -- packages/sms/src/ali.ts | 64 -- packages/sms/src/config/config.default.ts | 5 - packages/sms/src/configuration.ts | 17 - packages/sms/src/index.ts | 9 - packages/sms/src/interface.ts | 80 --- packages/sms/src/package.json | 49 -- packages/sms/src/sms.ts | 83 --- packages/sms/src/tx.ts | 70 --- packages/sms/src/yp.ts | 86 --- packages/sms/test/index.test.ts | 14 - packages/sms/tsconfig.json | 24 - packages/task/.editorconfig | 11 - packages/task/.eslintrc.json | 28 - packages/task/.gitignore | 15 - packages/task/.prettierrc.js | 3 - packages/task/README.md | 3 - packages/task/index.d.ts | 10 - packages/task/jest.config.js | 7 - packages/task/jest.setup.js | 1 - packages/task/package.json | 51 -- packages/task/src/base.ts | 118 ---- packages/task/src/config/config.default.ts | 6 - packages/task/src/configuration.ts | 19 - packages/task/src/decorator/queue.ts | 26 - packages/task/src/index.ts | 7 - packages/task/src/package.json | 51 -- packages/task/src/queue.ts | 142 ----- packages/task/test/index.test.ts | 14 - packages/task/tsconfig.json | 24 - public/css/welcome.css | 25 + src/config/config.local.ts | 4 +- src/configuration.ts | 21 +- src/modules/base/config.ts | 2 +- src/modules/base/controller/admin/comm.ts | 11 +- src/modules/base/controller/admin/open.ts | 7 +- src/modules/base/controller/admin/sys/menu.ts | 11 + src/modules/base/controller/app/comm.ts | 18 +- src/modules/base/event/app.ts | 41 ++ src/modules/base/event/menu.ts | 25 + src/modules/base/service/sys/menu.ts | 114 +++- src/modules/base/service/sys/user.ts | 4 + .../demo/controller/{app => open}/cache.ts | 2 +- .../demo/controller/{app => open}/event.ts | 0 .../demo/controller/{app => open}/goods.ts | 0 .../demo/controller/{app => open}/pay.ts | 0 .../demo/controller/{app => open}/queue.ts | 0 .../demo/controller/{app => open}/rpc.ts | 0 .../controller/{app => open}/transaction.ts | 2 +- src/modules/dict/controller/app/info.ts | 7 +- src/modules/dict/entity/info.ts | 3 + src/modules/dict/service/info.ts | 9 +- src/modules/task/event/app.ts | 2 +- src/modules/task/service/info.ts | 5 +- src/modules/user/config.ts | 2 +- src/modules/user/controller/app/comm.ts | 7 +- src/modules/user/controller/app/login.ts | 12 +- src/modules/user/event/app.ts | 41 ++ src/modules/user/service/login.ts | 2 +- src/welcome.ts | 2 +- test/README.md | 12 + test/controller/api.test.ts | 20 - test/controller/home.test.ts | 21 - typings/app/index.d.ts | 6 - typings/config/index.d.ts | 35 -- typings/config/plugin.d.ts | 35 -- view/welcome.html | 9 + 252 files changed, 366 insertions(+), 10302 deletions(-) rename .dockerignore => .dockerignore (100%) create mode 100644 packages/README.md delete mode 100644 packages/cloud/.editorconfig delete mode 100644 packages/cloud/.eslintrc.json delete mode 100644 packages/cloud/.gitignore delete mode 100644 packages/cloud/.prettierrc.js delete mode 100644 packages/cloud/LICENSE delete mode 100644 packages/cloud/index.d.ts delete mode 100644 packages/cloud/jest.config.js delete mode 100644 packages/cloud/jest.setup.js delete mode 100644 packages/cloud/package.json delete mode 100644 packages/cloud/src/LICENSE delete mode 100644 packages/cloud/src/config/config.default.ts delete mode 100644 packages/cloud/src/configuration.ts delete mode 100644 packages/cloud/src/db/index.ts delete mode 100644 packages/cloud/src/db/source.ts delete mode 100644 packages/cloud/src/func/crud.ts delete mode 100644 packages/cloud/src/func/index.ts delete mode 100644 packages/cloud/src/index.ts delete mode 100644 packages/cloud/src/interface.ts delete mode 100644 packages/cloud/src/package.json delete mode 100644 packages/cloud/src/util.ts delete mode 100644 packages/cloud/test/index.test.ts delete mode 100644 packages/cloud/tsconfig.json delete mode 100644 packages/core/LICENSE delete mode 100644 packages/core/README.md delete mode 100644 packages/core/_.editorconfig delete mode 100644 packages/core/_.eslintrc.json delete mode 100644 packages/core/_.gitignore delete mode 100644 packages/core/_.prettierrc.js delete mode 100644 packages/core/index.d.ts delete mode 100644 packages/core/jest.config.js delete mode 100644 packages/core/jest.setup.js delete mode 100644 packages/core/package.json delete mode 100644 packages/core/src/LICENSE delete mode 100644 packages/core/src/config/config.default.ts delete mode 100644 packages/core/src/configuration.ts delete mode 100644 packages/core/src/constant/global.ts delete mode 100644 packages/core/src/controller/base.ts delete mode 100644 packages/core/src/decorator/cache.ts delete mode 100644 packages/core/src/decorator/controller.ts delete mode 100644 packages/core/src/decorator/event.ts delete mode 100644 packages/core/src/decorator/index.ts delete mode 100644 packages/core/src/decorator/tag.ts delete mode 100644 packages/core/src/decorator/transaction.ts delete mode 100644 packages/core/src/entity/base.ts delete mode 100644 packages/core/src/entity/mongo.ts delete mode 100644 packages/core/src/entity/typeorm.ts delete mode 100644 packages/core/src/event/index.ts delete mode 100644 packages/core/src/exception/base.ts delete mode 100644 packages/core/src/exception/comm.ts delete mode 100644 packages/core/src/exception/core.ts delete mode 100644 packages/core/src/exception/filter.ts delete mode 100644 packages/core/src/exception/validate.ts delete mode 100644 packages/core/src/index.ts delete mode 100644 packages/core/src/interface.ts delete mode 100644 packages/core/src/module/config.ts delete mode 100644 packages/core/src/module/import.ts delete mode 100644 packages/core/src/package.json delete mode 100644 packages/core/src/rest/eps.ts delete mode 100644 packages/core/src/service/base.ts delete mode 100644 packages/core/src/tag/data.ts delete mode 100644 packages/core/src/util/func.ts delete mode 100644 packages/core/src/util/location.ts delete mode 100644 packages/core/test/index.test.ts delete mode 100644 packages/core/tsconfig.json delete mode 100644 packages/es/.editorconfig delete mode 100644 packages/es/.eslintrc.json delete mode 100644 packages/es/.gitignore delete mode 100644 packages/es/.prettierrc.js delete mode 100644 packages/es/README.md delete mode 100644 packages/es/index.d.ts delete mode 100644 packages/es/jest.config.js delete mode 100644 packages/es/jest.setup.js delete mode 100644 packages/es/package.json delete mode 100644 packages/es/src/base.ts delete mode 100644 packages/es/src/config/config.default.ts delete mode 100644 packages/es/src/configuration.ts delete mode 100644 packages/es/src/decorator/elasticsearch.ts delete mode 100644 packages/es/src/elasticsearch.ts delete mode 100644 packages/es/src/index.ts delete mode 100644 packages/es/src/package.json delete mode 100644 packages/es/test/index.test.ts delete mode 100644 packages/es/tsconfig.json delete mode 100644 packages/file/.editorconfig delete mode 100644 packages/file/.eslintrc.json delete mode 100644 packages/file/.gitignore delete mode 100644 packages/file/.prettierrc.js delete mode 100644 packages/file/LICENSE delete mode 100644 packages/file/index.d.ts delete mode 100644 packages/file/jest.config.js delete mode 100644 packages/file/jest.setup.js delete mode 100644 packages/file/package.json delete mode 100644 packages/file/src/config/config.default.ts delete mode 100644 packages/file/src/configuration.ts delete mode 100644 packages/file/src/file.ts delete mode 100644 packages/file/src/index.ts delete mode 100644 packages/file/src/interface.ts delete mode 100644 packages/file/src/package.json delete mode 100644 packages/file/test/index.test.ts delete mode 100644 packages/file/tsconfig.json delete mode 100644 packages/iot/.editorconfig delete mode 100644 packages/iot/.eslintrc.json delete mode 100644 packages/iot/.gitignore delete mode 100644 packages/iot/.prettierrc.js delete mode 100644 packages/iot/README.md delete mode 100644 packages/iot/index.d.ts delete mode 100644 packages/iot/jest.config.js delete mode 100644 packages/iot/jest.setup.js delete mode 100644 packages/iot/package.json delete mode 100644 packages/iot/src/config/config.default.ts delete mode 100644 packages/iot/src/configuration.ts delete mode 100644 packages/iot/src/decorator/mqtt.ts delete mode 100644 packages/iot/src/index.ts delete mode 100644 packages/iot/src/interface.ts delete mode 100644 packages/iot/src/mqtt.ts delete mode 100644 packages/iot/src/package.json delete mode 100644 packages/iot/test/index.test.ts delete mode 100644 packages/iot/tsconfig.json delete mode 100644 packages/other/cache-manager-fs-hash/LICENSE delete mode 100644 packages/other/cache-manager-fs-hash/README.md delete mode 100644 packages/other/cache-manager-fs-hash/index.js delete mode 100644 packages/other/cache-manager-fs-hash/package.json delete mode 100644 packages/other/cache-manager-fs-hash/src/index.js delete mode 100644 packages/other/cache-manager-fs-hash/src/json-file-store.js delete mode 100644 packages/other/cache-manager-fs-hash/src/wrap-callback.js delete mode 100644 packages/other/mqemitter-redis/.github/dependabot.yml delete mode 100644 packages/other/mqemitter-redis/.github/workflows/ci.yml delete mode 100644 packages/other/mqemitter-redis/.gitignore delete mode 100644 packages/other/mqemitter-redis/.travis.yml delete mode 100644 packages/other/mqemitter-redis/LICENSE delete mode 100644 packages/other/mqemitter-redis/README.md delete mode 100644 packages/other/mqemitter-redis/mqemitter-redis.js delete mode 100644 packages/other/mqemitter-redis/package.json delete mode 100644 packages/other/mqemitter-redis/test.js delete mode 100644 packages/other/mqemitter-redis/types/index.d.ts delete mode 100644 packages/other/mqemitter-redis/types/index.test-d.ts delete mode 100644 packages/pay/.editorconfig delete mode 100644 packages/pay/.eslintrc.json delete mode 100644 packages/pay/.gitignore delete mode 100644 packages/pay/.prettierrc.js delete mode 100644 packages/pay/index.d.ts delete mode 100644 packages/pay/jest.config.js delete mode 100644 packages/pay/jest.setup.js delete mode 100644 packages/pay/package.json delete mode 100644 packages/pay/src/ali.ts delete mode 100644 packages/pay/src/config/config.default.ts delete mode 100644 packages/pay/src/configuration.ts delete mode 100644 packages/pay/src/index.ts delete mode 100644 packages/pay/src/interface.ts delete mode 100644 packages/pay/src/package.json delete mode 100644 packages/pay/src/wx.ts delete mode 100644 packages/pay/test/index.test.ts delete mode 100644 packages/pay/tsconfig.json delete mode 100644 packages/rpc/.editorconfig delete mode 100644 packages/rpc/.eslintrc.json delete mode 100644 packages/rpc/.gitignore delete mode 100644 packages/rpc/.prettierrc.js delete mode 100644 packages/rpc/index.d.ts delete mode 100644 packages/rpc/jest.config.js delete mode 100644 packages/rpc/jest.setup.js delete mode 100644 packages/rpc/package.json delete mode 100644 packages/rpc/src/config/config.default.ts delete mode 100644 packages/rpc/src/configuration.ts delete mode 100644 packages/rpc/src/decorator/event/event.ts delete mode 100644 packages/rpc/src/decorator/event/handler.ts delete mode 100644 packages/rpc/src/decorator/index.ts delete mode 100644 packages/rpc/src/decorator/rpc.ts delete mode 100644 packages/rpc/src/decorator/transaction.ts delete mode 100644 packages/rpc/src/index.ts delete mode 100644 packages/rpc/src/package.json delete mode 100644 packages/rpc/src/rpc.ts delete mode 100644 packages/rpc/src/service/base.ts delete mode 100644 packages/rpc/src/test.ts delete mode 100644 packages/rpc/src/transaction/event.ts delete mode 100644 packages/rpc/test/index.test.ts delete mode 100644 packages/rpc/tsconfig.json delete mode 100644 packages/sms/.editorconfig delete mode 100644 packages/sms/.eslintrc.json delete mode 100644 packages/sms/.gitignore delete mode 100644 packages/sms/.prettierrc.js delete mode 100644 packages/sms/index.d.ts delete mode 100644 packages/sms/jest.config.js delete mode 100644 packages/sms/jest.setup.js delete mode 100644 packages/sms/package.json delete mode 100644 packages/sms/src/ali.ts delete mode 100644 packages/sms/src/config/config.default.ts delete mode 100644 packages/sms/src/configuration.ts delete mode 100644 packages/sms/src/index.ts delete mode 100644 packages/sms/src/interface.ts delete mode 100644 packages/sms/src/package.json delete mode 100644 packages/sms/src/sms.ts delete mode 100644 packages/sms/src/tx.ts delete mode 100644 packages/sms/src/yp.ts delete mode 100644 packages/sms/test/index.test.ts delete mode 100644 packages/sms/tsconfig.json delete mode 100644 packages/task/.editorconfig delete mode 100644 packages/task/.eslintrc.json delete mode 100644 packages/task/.gitignore delete mode 100644 packages/task/.prettierrc.js delete mode 100644 packages/task/README.md delete mode 100644 packages/task/index.d.ts delete mode 100644 packages/task/jest.config.js delete mode 100644 packages/task/jest.setup.js delete mode 100644 packages/task/package.json delete mode 100644 packages/task/src/base.ts delete mode 100644 packages/task/src/config/config.default.ts delete mode 100644 packages/task/src/configuration.ts delete mode 100644 packages/task/src/decorator/queue.ts delete mode 100644 packages/task/src/index.ts delete mode 100644 packages/task/src/package.json delete mode 100644 packages/task/src/queue.ts delete mode 100644 packages/task/test/index.test.ts delete mode 100644 packages/task/tsconfig.json create mode 100644 src/modules/base/event/app.ts create mode 100644 src/modules/base/event/menu.ts rename src/modules/demo/controller/{app => open}/cache.ts (93%) rename src/modules/demo/controller/{app => open}/event.ts (100%) rename src/modules/demo/controller/{app => open}/goods.ts (100%) rename src/modules/demo/controller/{app => open}/pay.ts (100%) rename src/modules/demo/controller/{app => open}/queue.ts (100%) rename src/modules/demo/controller/{app => open}/rpc.ts (100%) rename src/modules/demo/controller/{app => open}/transaction.ts (88%) create mode 100644 src/modules/user/event/app.ts create mode 100644 test/README.md delete mode 100644 test/controller/api.test.ts delete mode 100644 test/controller/home.test.ts delete mode 100644 typings/app/index.d.ts delete mode 100644 typings/config/index.d.ts delete mode 100644 typings/config/plugin.d.ts diff --git a/ .dockerignore b/.dockerignore similarity index 100% rename from .dockerignore rename to .dockerignore diff --git a/package.json b/package.json index 7c99ec1..2bea9da 100644 --- a/package.json +++ b/package.json @@ -1,55 +1,55 @@ { "name": "cool-admin", - "version": "6.0.0", + "version": "7.0.0", "description": "一个项目用COOL就够了", "private": true, "dependencies": { - "@cool-midway/cache-manager-fs-hash": "^6.0.0", - "@cool-midway/cloud": "^6.0.0", - "@cool-midway/core": "^6.0.9", - "@cool-midway/file": "^6.0.3", - "@cool-midway/iot": "^6.0.0", - "@cool-midway/pay": "^6.0.0", - "@cool-midway/rpc": "^6.0.1", - "@cool-midway/sms": "^6.0.1", - "@cool-midway/task": "^6.0.0", - "@midwayjs/bootstrap": "^3.12.1", - "@midwayjs/cache": "^3.12.1", - "@midwayjs/core": "^3.12.1", - "@midwayjs/cross-domain": "^3.12.1", - "@midwayjs/decorator": "^3.12.1", - "@midwayjs/info": "^3.12.1", - "@midwayjs/koa": "^3.12.1", - "@midwayjs/logger": "^2.17.0", - "@midwayjs/static-file": "^3.12.1", + "@cool-midway/cache-manager-fs-hash": "7.0.0-beta1", + "@cool-midway/cloud": "7.0.0-beta1", + "@cool-midway/core": "7.0.0-beta3", + "@cool-midway/file": "7.0.0-beta2", + "@cool-midway/iot": "7.0.0-beta1", + "@cool-midway/pay": "7.0.0-beta1", + "@cool-midway/rpc": "7.0.0-beta1", + "@cool-midway/sms": "7.0.0-beta1", + "@cool-midway/task": "7.0.0-beta1", + "@midwayjs/bootstrap": "^3.12.3", + "@midwayjs/cache": "^3.12.3", + "@midwayjs/core": "^3.12.3", + "@midwayjs/cross-domain": "^3.12.3", + "@midwayjs/decorator": "^3.12.3", + "@midwayjs/info": "^3.12.3", + "@midwayjs/koa": "^3.12.3", + "@midwayjs/logger": "^2.18.0", + "@midwayjs/static-file": "^3.12.3", "@midwayjs/task": "^3.6.0", - "@midwayjs/typeorm": "^3.12.1", - "@midwayjs/validate": "^3.12.1", - "@midwayjs/view-ejs": "^3.12.1", - "axios": "^1.4.0", + "@midwayjs/typeorm": "^3.12.3", + "@midwayjs/validate": "^3.12.3", + "@midwayjs/view-ejs": "^3.12.3", + "axios": "^1.5.0", "ipip-ipdb": "^0.6.0", - "jsonwebtoken": "^9.0.1", + "jsonwebtoken": "^9.0.2", "lodash": "^4.17.21", "md5": "^2.3.0", "mini-svg-data-uri": "^1.4.4", "moment": "^2.29.4", - "mysql2": "^3.6.0", + "mysql2": "^3.6.1", "svg-captcha": "^1.4.0", "svg2png-wasm": "^1.4.0", "typeorm": "^0.3.17", - "uuid": "^9.0.0" + "uuid": "^9.0.1" }, "devDependencies": { "@midwayjs/cli": "^2.1.1", - "@midwayjs/mock": "^3.12.1", - "@types/jest": "^29.5.3", + "@midwayjs/mock": "^3.12.3", + "@types/jest": "^29.5.4", "@types/koa": "^2.13.8", "@types/node": "20", "cross-env": "^7.0.3", - "jest": "^29.6.2", + "jest": "^29.7.0", "mwts": "^1.3.0", "ts-jest": "^29.1.1", - "typescript": "~4.9.5" + "typescript": "~5.2.2" }, "engines": { "node": ">=12.0.0" @@ -57,7 +57,6 @@ "scripts": { "start": "NODE_ENV=production node ./bootstrap.js", "dev": "cross-env && cross-env NODE_ENV=local TS_NODE_TYPE_CHECK=false TS_NODE_TRANSPILE_ONLY=true midway-bin dev --ts", - "test": "midway-bin test --ts", "cov": "midway-bin cov --ts", "lint": "mwts check", "lint:fix": "mwts fix", diff --git a/packages/README.md b/packages/README.md new file mode 100644 index 0000000..c795a47 --- /dev/null +++ b/packages/README.md @@ -0,0 +1,3 @@ +核心包单独项目 + +请转到:https://github.com/cool-team-official/cool-admin-midway-packages 查看 \ No newline at end of file diff --git a/packages/cloud/.editorconfig b/packages/cloud/.editorconfig deleted file mode 100644 index 4c7f8a8..0000000 --- a/packages/cloud/.editorconfig +++ /dev/null @@ -1,11 +0,0 @@ -# 🎨 editorconfig.org - -root = true - -[*] -charset = utf-8 -end_of_line = lf -indent_style = space -indent_size = 2 -trim_trailing_whitespace = true -insert_final_newline = true \ No newline at end of file diff --git a/packages/cloud/.eslintrc.json b/packages/cloud/.eslintrc.json deleted file mode 100644 index 93e32bd..0000000 --- a/packages/cloud/.eslintrc.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "extends": "./node_modules/mwts/", - "ignorePatterns": ["node_modules", "dist", "test", "jest.config.js", "typings"], - "env": { - "jest": true - }, - "rules": { - "@typescript-eslint/explicit-module-boundary-types": "off", - "@typescript-eslint/no-unused-vars": "off", - "@typescript-eslint/ban-ts-comment": "off", - "node/no-extraneous-import": "off", - "no-empty": "off", - "node/no-extraneous-require": "off", - "eqeqeq": "off", - "node/no-unsupported-features/node-builtins": "off", - "@typescript-eslint/ban-types": "off", - "no-control-regex": "off", - "prefer-const": "off" - } -} diff --git a/packages/cloud/.gitignore b/packages/cloud/.gitignore deleted file mode 100644 index 13bc3a6..0000000 --- a/packages/cloud/.gitignore +++ /dev/null @@ -1,15 +0,0 @@ -logs/ -npm-debug.log -yarn-error.log -node_modules/ -package-lock.json -yarn.lock -coverage/ -dist/ -.idea/ -run/ -.DS_Store -*.sw* -*.un~ -.tsbuildinfo -.tsbuildinfo.* diff --git a/packages/cloud/.prettierrc.js b/packages/cloud/.prettierrc.js deleted file mode 100644 index b964930..0000000 --- a/packages/cloud/.prettierrc.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - ...require('mwts/.prettierrc.json') -} diff --git a/packages/cloud/LICENSE b/packages/cloud/LICENSE deleted file mode 100644 index 5a739ee..0000000 --- a/packages/cloud/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2013 - Now midwayjs - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/packages/cloud/index.d.ts b/packages/cloud/index.d.ts deleted file mode 100644 index e0065de..0000000 --- a/packages/cloud/index.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -export * from './dist/index'; - -declare module '@midwayjs/core/dist/interface' { - interface MidwayConfig { - book?: PowerPartial<{ - a: number; - b: string; - }>; - } -} diff --git a/packages/cloud/jest.config.js b/packages/cloud/jest.config.js deleted file mode 100644 index 82a8b85..0000000 --- a/packages/cloud/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - preset: 'ts-jest', - testEnvironment: 'node', - testPathIgnorePatterns: ['/test/fixtures'], - coveragePathIgnorePatterns: ['/test/'], - setupFilesAfterEnv: ['./jest.setup.js'] -}; diff --git a/packages/cloud/jest.setup.js b/packages/cloud/jest.setup.js deleted file mode 100644 index 1399c91..0000000 --- a/packages/cloud/jest.setup.js +++ /dev/null @@ -1 +0,0 @@ -jest.setTimeout(30000); diff --git a/packages/cloud/package.json b/packages/cloud/package.json deleted file mode 100644 index 60ff564..0000000 --- a/packages/cloud/package.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "name": "@cool-midway/cloud", - "version": "6.0.0", - "description": "", - "main": "dist/index.js", - "typings": "index.d.ts", - "scripts": { - "build": "cross-env midway-bin build -c", - "test": "cross-env midway-bin test --ts", - "cov": "cross-env midway-bin cov --ts", - "lint": "mwts check", - "lint:fix": "mwts fix" - }, - "keywords": [ - "cool", - "cool-admin", - "cooljs" - ], - "author": "COOL", - "files": [ - "dist/**/*.js", - "dist/**/*.d.ts", - "index.d.ts" - ], - "license": "MIT", - "repository": { - "type": "git", - "url": "https://cool-js.com" - }, - "devDependencies": { - "@cool-midway/core": "^6.0.0", - "@midwayjs/cli": "^2.0.0", - "@midwayjs/core": "^3.9.0", - "@midwayjs/decorator": "^3.9.0", - "@midwayjs/mock": "^3.9.0", - "@midwayjs/typeorm": "^3.9.0", - "@types/jest": "^29.2.4", - "@types/node": "^18.11.15", - "cross-env": "^7.0.3", - "jest": "^29.3.1", - "lodash": "^4.17.21", - "mwts": "^1.3.0", - "ts-jest": "^29.0.3", - "typeorm": "^0.3.11", - "typescript": "^4.9.4" - } -} diff --git a/packages/cloud/src/LICENSE b/packages/cloud/src/LICENSE deleted file mode 100644 index 5a739ee..0000000 --- a/packages/cloud/src/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2013 - Now midwayjs - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/packages/cloud/src/config/config.default.ts b/packages/cloud/src/config/config.default.ts deleted file mode 100644 index 03ef2cd..0000000 --- a/packages/cloud/src/config/config.default.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** - * cool的配置 - */ -export default {}; diff --git a/packages/cloud/src/configuration.ts b/packages/cloud/src/configuration.ts deleted file mode 100644 index ee7447f..0000000 --- a/packages/cloud/src/configuration.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { ILifeCycle, ILogger, IMidwayContainer, Logger } from '@midwayjs/core'; -import { Configuration } from '@midwayjs/decorator'; -import * as DefaultConfig from './config/config.default'; -import { CoolCloudDb } from './db'; - -@Configuration({ - namespace: 'cloud', - importConfigs: [ - { - default: DefaultConfig, - }, - ], -}) -export class CoolCloudConfiguration implements ILifeCycle { - @Logger() - coreLogger: ILogger; - - async onReady(container: IMidwayContainer) { - await container.getAsync(CoolCloudDb); - this.coreLogger.info('\x1B[36m [cool:cloud] ready \x1B[0m'); - } -} diff --git a/packages/cloud/src/db/index.ts b/packages/cloud/src/db/index.ts deleted file mode 100644 index ae6ec7a..0000000 --- a/packages/cloud/src/db/index.ts +++ /dev/null @@ -1,123 +0,0 @@ -import { CoolCommException } from '@cool-midway/core'; -import { CoolDataSource } from './source'; -import { - ALL, - Config, - ILogger, - Init, - Logger, - Provide, - Scope, - ScopeEnum, -} from '@midwayjs/core'; -import { Repository } from 'typeorm'; -import * as ts from 'typescript'; -import * as _ from 'lodash'; -/** - * 数据库 - */ -@Provide() -@Scope(ScopeEnum.Singleton) -export class CoolCloudDb { - @Logger() - coreLogger: ILogger; - - coolDataSource: CoolDataSource; - - @Config(ALL) - config; - - @Init() - async init() { - const config = this.config.typeorm.dataSource.default; - if (!config) { - throw new CoolCommException('未配置数据库default信息'); - } - this.coolDataSource = new CoolDataSource({ - ...this.config.typeorm.dataSource.default, - entities: [], - }); - // 连接数据库 - await this.coolDataSource.initialize(); - } - - /** - * 获得数据库操作实例 - * @param tableClass 表类 - * @param appId 应用ID - * @returns - */ - getRepository(tableClass: string, appId = 'CLOUD'): Repository { - return this.coolDataSource.getRepository(`${tableClass}${appId}`); - } - - /** - * 创建表 - * @param table 表结构,元函数,字符串 - * @param appId 应用ID,确保每个应用的数据隔离 - * @param synchronize 是否同步表结构 - */ - async createTable(table: string, synchronize = false, appId = 'CLOUD') { - if (!table || !appId) { - throw new CoolCommException('table、appId不能为空'); - } - const { newCode, className } = this.parseCode(table, appId); - const entities = this.coolDataSource.options.entities; - // @ts-ignore - this.coolDataSource.options.entities = _.dropWhile(entities, { - name: className, - }); - const code = ts.transpile( - `${newCode} - this.coolDataSource.options.entities.push(${className}) - - this.coolDataSource.buildMetadatas().then(() => { - if(synchronize){ - this.coolDataSource.synchronize(); - } - }); - `, - { - emitDecoratorMetadata: true, - module: ts.ModuleKind.CommonJS, - target: ts.ScriptTarget.ES2018, - removeComments: true, - } - ); - eval(code); - } - - /** - * 根据字符串查找并生成一个跟appId相关的类名 - * @param code 代码 - * @param appId - */ - parseCode(code: string, appId = 'CLOUD') { - try { - const oldClassName = code - .match('class(.*)extends')[1] - .replace(/\s*/g, ''); - const oldTableStart = code.indexOf('@Entity('); - const oldTableEnd = code.indexOf(')'); - - const oldTableName = code - .substring(oldTableStart + 9, oldTableEnd - 1) - .replace(/\s*/g, '') - // eslint-disable-next-line no-useless-escape - .replace(/\"/g, '') - // eslint-disable-next-line no-useless-escape - .replace(/\'/g, ''); - const className = `${oldClassName}${appId}`; - return { - newCode: code - .replace(oldClassName, className) - .replace(oldTableName, `func_${oldTableName}`), - className, - tableName: `func_${oldTableName}`, - }; - } catch (err) { - this.coreLogger.error(err); - throw new CoolCommException('代码结构不正确,请检查'); - } - } -} diff --git a/packages/cloud/src/db/source.ts b/packages/cloud/src/db/source.ts deleted file mode 100644 index f5c13af..0000000 --- a/packages/cloud/src/db/source.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { DataSource } from 'typeorm'; - -export class CoolDataSource extends DataSource { - /** - * 重新构造元数据 - */ - async buildMetadatas() { - await super.buildMetadatas(); - } -} diff --git a/packages/cloud/src/func/crud.ts b/packages/cloud/src/func/crud.ts deleted file mode 100644 index 842c4cd..0000000 --- a/packages/cloud/src/func/crud.ts +++ /dev/null @@ -1,525 +0,0 @@ -import { CloudReq } from './../interface'; -import { IMidwayApplication } from '@midwayjs/core'; -import { - CoolConfig, - CoolEventManager, - CoolValidateException, - CurdOption, - ERRINFO, - EVENT, -} from '@cool-midway/core'; -import { Brackets, In, Repository, SelectQueryBuilder } from 'typeorm'; -import { CoolCloudDb } from '../db'; -import * as _ from 'lodash'; -import * as SqlString from 'sqlstring'; - -export abstract class CloudCrud { - ctx; - - curdOption: CurdOption; - - coolCloudDb: CoolCloudDb; - - coolConfig: CoolConfig; - - entity: Repository; - - app: IMidwayApplication; - - req: CloudReq; - - coolEventManager: CoolEventManager; - - protected sqlParams; - - setCurdOption(curdOption: CurdOption) { - this.curdOption = curdOption; - } - - /** - * 设置实体 - * @param entityModel - */ - async setEntity() { - this.entity = this.coolCloudDb.getRepository( - this.curdOption.entity, - 'CLOUD' - ); - } - - abstract main(req: CloudReq): Promise; - - async init(req: CloudReq) { - this.sqlParams = []; - // 执行主函数 - await this.main(req); - // 操作之前 - await this.before(); - // // 设置实体 - await this.setEntity(); - } - - /** - * 参数安全性检查 - * @param params - */ - async paramSafetyCheck(params) { - const lp = params.toLowerCase(); - return !( - lp.indexOf('update ') > -1 || - lp.indexOf('select ') > -1 || - lp.indexOf('delete ') > -1 || - lp.indexOf('insert ') > -1 - ); - } - - /** - * 非分页查询 - * @param query 查询条件 - * @param option 查询配置 - */ - async list(query): Promise { - if (!this.entity) throw new CoolValidateException(ERRINFO.NOENTITY); - const sql = await this.getOptionFind(query, this.curdOption.listQueryOp); - return this.nativeQuery(sql, []); - } - - /** - * 执行SQL并获得分页数据 - * @param sql 执行的sql语句 - * @param query 分页查询条件 - * @param autoSort 是否自动排序 - */ - async sqlRenderPage(sql, query, autoSort = true) { - const { - size = this.coolConfig.crud.pageSize, - page = 1, - order = 'createTime', - sort = 'desc', - isExport = false, - maxExportLimit, - } = query; - if (order && sort && autoSort) { - if (!(await this.paramSafetyCheck(order + sort))) { - throw new CoolValidateException('非法传参~'); - } - sql += ` ORDER BY ${SqlString.escapeId(order)} ${this.checkSort(sort)}`; - } - if (isExport && maxExportLimit > 0) { - this.sqlParams.push(parseInt(maxExportLimit)); - sql += ' LIMIT ? '; - } - if (!isExport) { - this.sqlParams.push((page - 1) * size); - this.sqlParams.push(parseInt(size)); - sql += ' LIMIT ?,? '; - } - - let params = []; - params = params.concat(this.sqlParams); - const result = await this.nativeQuery(sql, params); - const countResult = await this.nativeQuery(this.getCountSql(sql), params); - return { - list: result, - pagination: { - page: parseInt(page), - size: parseInt(size), - total: parseInt(countResult[0] ? countResult[0].count : 0), - }, - }; - } - - /** - * 分页查询 - * @param connectionName 连接名 - */ - async page(query) { - if (!this.entity) throw new CoolValidateException(ERRINFO.NOENTITY); - const sql = await this.getOptionFind(query, this.curdOption.pageQueryOp); - return this.sqlRenderPage(sql, query, false); - } - - /** - * 获得查询个数的SQL - * @param sql - */ - getCountSql(sql) { - sql = sql - .replace(new RegExp('LIMIT', 'gm'), 'limit ') - .replace(new RegExp('\n', 'gm'), ' '); - if (sql.includes('limit')) { - const sqlArr = sql.split('limit '); - sqlArr.pop(); - sql = sqlArr.join('limit '); - } - return `select count(*) as count from (${sql}) a`; - } - - /** - * 操作entity获得分页数据,不用写sql - * @param find QueryBuilder - * @param query - * @param autoSort - * @param connectionName - */ - async entityRenderPage( - find: SelectQueryBuilder, - query, - autoSort = true - ) { - const { - size = this.coolConfig.crud.pageSize, - page = 1, - order = 'createTime', - sort = 'desc', - isExport = false, - maxExportLimit, - } = query; - const count = await find.getCount(); - let dataFind: SelectQueryBuilder; - if (isExport && maxExportLimit > 0) { - dataFind = find.limit(maxExportLimit); - } else { - dataFind = find.offset((page - 1) * size).limit(size); - } - if (autoSort) { - find.addOrderBy(order, sort.toUpperCase()); - } - return { - list: await dataFind.getRawMany(), - pagination: { - page: parseInt(page), - size: parseInt(size), - total: count, - }, - }; - } - - /** - * 检查排序 - * @param sort 排序 - * @returns - */ - private checkSort(sort) { - if (!['desc', 'asc'].includes(sort.toLowerCase())) { - throw new CoolValidateException('sort 非法传参~'); - } - return sort; - } - - /** - * 原生查询 - * @param sql - * @param params - */ - async nativeQuery(sql, params?) { - if (_.isEmpty(params)) { - params = this.sqlParams; - } - let newParams = []; - newParams = newParams.concat(params); - this.sqlParams = []; - for (const param of newParams) { - SqlString.escape(param); - } - return await this.getOrmManager().query(sql, newParams || []); - } - - /** - * 获得ORM管理 - * @param connectionName 连接名称 - */ - getOrmManager() { - return this.coolCloudDb.coolDataSource; - } - - private async before() { - if (!this.curdOption?.before) { - return; - } - await this.curdOption.before(this.ctx, this.app); - } - - /** - * 插入参数值 - * @param curdOption 配置 - */ - private async insertParam(param) { - if (!this.curdOption?.insertParam) { - return param; - } - return { - ...param, - ...(await this.curdOption.insertParam(this.ctx, this.app)), - }; - } - - /** - * 新增|修改|删除 之后的操作 - * @param data 对应数据 - */ - async modifyAfter( - data: any, - type: 'delete' | 'update' | 'add' - ): Promise {} - - /** - * 新增|修改|删除 之前的操作 - * @param data 对应数据 - */ - async modifyBefore( - data: any, - type: 'delete' | 'update' | 'add' - ): Promise {} - - /** - * 新增 - * @param param - * @returns - */ - async add(param) { - param = await this.insertParam(param); - if (!this.entity) throw new CoolValidateException(ERRINFO.NOENTITY); - await this.modifyBefore(param, 'add'); - await this.addOrUpdate(param); - await this.modifyAfter(param, 'add'); - return { - id: - param instanceof Array - ? param.map(e => { - return e.id ? e.id : e._id; - }) - : param.id - ? param.id - : param._id, - }; - } - - /** - * 新增|修改 - * @param param 数据 - */ - async addOrUpdate(param: any | any[]) { - if (!this.entity) throw new CoolValidateException(ERRINFO.NOENTITY); - delete param.createTime; - if (param.id) { - param.updateTime = new Date(); - await this.entity.update(param.id, param); - } else { - param.createTime = new Date(); - param.updateTime = new Date(); - await this.entity.insert(param); - } - } - - /** - * 删除 - * @param ids 删除的ID集合 如:[1,2,3] 或者 1,2,3 - */ - async delete(ids: any) { - if (!this.entity) throw new CoolValidateException(ERRINFO.NOENTITY); - await this.modifyBefore(ids, 'delete'); - if (ids instanceof String) { - ids = ids.split(','); - } - if (this.coolConfig.crud?.softDelete) { - this.softDelete(ids); - } - await this.entity.delete(ids); - await this.modifyAfter(ids, 'delete'); - } - - /** - * 软删除 - * @param ids 删除的ID数组 - * @param entity 实体 - */ - async softDelete(ids: string[], entity?: Repository, userId?: string) { - const data = await this.entity.find({ - where: { - id: In(ids), - }, - }); - if (_.isEmpty(data)) return; - const _entity = entity ? entity : this.entity; - const params = { - data, - ctx: this.ctx, - entity: _entity, - }; - if (data.length > 0) { - this.coolEventManager.emit(EVENT.SOFT_DELETE, params); - } - } - - /** - * 修改 - * @param param 数据 - */ - async update(param: any) { - if (!this.entity) throw new CoolValidateException(ERRINFO.NOENTITY); - await this.modifyBefore(param, 'update'); - if (!param.id && !(param instanceof Array)) - throw new CoolValidateException(ERRINFO.NOID); - await this.addOrUpdate(param); - await this.modifyAfter(param, 'update'); - } - - /** - * 获得单个ID - * @param id ID - */ - async info(id: any): Promise { - if (!this.entity) throw new CoolValidateException(ERRINFO.NOENTITY); - if (!id) { - throw new CoolValidateException(ERRINFO.NOID); - } - const info = await this.entity.findBy({ id }); - if (info && this.curdOption?.infoIgnoreProperty) { - for (const property of this.curdOption?.infoIgnoreProperty) { - delete info[property]; - } - } - return info; - } - - /** - * 构建查询配置 - * @param query 前端查询 - * @param option - */ - private async getOptionFind(query, option) { - let { order = 'createTime', sort = 'desc', keyWord = '' } = query; - const sqlArr = ['SELECT']; - const selects = ['a.*']; - const find = this.entity.createQueryBuilder('a'); - if (option) { - if (typeof option == 'function') { - // @ts-ignore - option = await option(this.baseCtx, this.baseApp); - } - // 判断是否有关联查询,有的话取个别名 - if (!_.isEmpty(option.join)) { - for (const item of option.join) { - selects.push(`${item.alias}.*`); - find[item.type || 'leftJoin']( - item.entity, - item.alias, - item.condition - ); - } - } - // 默认条件 - if (option.where) { - const wheres = - typeof option.where == 'function' - ? await option.where(this.ctx, this.app) - : option.where; - if (!_.isEmpty(wheres)) { - for (const item of wheres) { - if ( - item.length == 2 || - (item.length == 3 && - (item[2] || (item[2] === 0 && item[2] != ''))) - ) { - for (const key in item[1]) { - this.sqlParams.push(item[1][key]); - } - find.andWhere(item[0], item[1]); - } - } - } - } - // 附加排序 - if (!_.isEmpty(option.addOrderBy)) { - for (const key in option.addOrderBy) { - if (order && order == key) { - sort = option.addOrderBy[key].toUpperCase(); - } - find.addOrderBy( - SqlString.escapeId(key), - this.checkSort(option.addOrderBy[key].toUpperCase()) - ); - } - } - // 关键字模糊搜索 - if (keyWord || (keyWord == 0 && keyWord != '')) { - keyWord = `%${keyWord}%`; - find.andWhere( - new Brackets(qb => { - const keyWordLikeFields = option.keyWordLikeFields; - for (let i = 0; i < option.keyWordLikeFields?.length || 0; i++) { - qb.orWhere(`${keyWordLikeFields[i]} like :keyWord`, { - keyWord, - }); - this.sqlParams.push(keyWord); - } - }) - ); - } - // 筛选字段 - if (!_.isEmpty(option.select)) { - sqlArr.push(option.select.join(',')); - find.select(option.select); - } else { - sqlArr.push(selects.join(',')); - } - // 字段全匹配 - if (!_.isEmpty(option.fieldEq)) { - for (const key of option.fieldEq) { - const c = {}; - // 单表字段无别名的情况下操作 - if (typeof key === 'string') { - if (query[key] || (query[key] == 0 && query[key] == '')) { - c[key] = query[key]; - const eq = query[key] instanceof Array ? 'in' : '='; - if (eq === 'in') { - find.andWhere(`${key} ${eq} (:${key})`, c); - } else { - find.andWhere(`${key} ${eq} :${key}`, c); - } - this.sqlParams.push(query[key]); - } - } else { - if ( - query[key.requestParam] || - (query[key.requestParam] == 0 && query[key.requestParam] !== '') - ) { - c[key.column] = query[key.requestParam]; - const eq = query[key.requestParam] instanceof Array ? 'in' : '='; - if (eq === 'in') { - find.andWhere(`${key.column} ${eq} (:${key.column})`, c); - } else { - find.andWhere(`${key.column} ${eq} :${key.column}`, c); - } - this.sqlParams.push(query[key.requestParam]); - } - } - } - } - } else { - sqlArr.push(selects.join(',')); - } - // 接口请求的排序 - if (sort && order) { - const sorts = sort.toUpperCase().split(','); - const orders = order.split(','); - if (sorts.length != orders.length) { - throw new CoolValidateException(ERRINFO.SORTFIELD); - } - for (const i in sorts) { - find.addOrderBy( - SqlString.escapeId(orders[i]), - this.checkSort(sorts[i]) - ); - } - } - if (option?.extend) { - await option?.extend(find, this.ctx, this.app); - } - const sqls = find.getSql().split('FROM'); - sqlArr.push('FROM'); - sqlArr.push(sqls[1]); - return sqlArr.join(' '); - } -} diff --git a/packages/cloud/src/func/index.ts b/packages/cloud/src/func/index.ts deleted file mode 100644 index 94da053..0000000 --- a/packages/cloud/src/func/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { Provide, Scope, ScopeEnum } from '@midwayjs/core'; - -/** - * 云函数 - */ -@Provide() -@Scope(ScopeEnum.Singleton) -export class CoolCloudFunc { - /** - * 获得类名 - * @param code - * @returns - */ - getClassName(code: string) { - return code.match('class(.*)extends')[1].replace(/\s*/g, ''); - } -} diff --git a/packages/cloud/src/index.ts b/packages/cloud/src/index.ts deleted file mode 100644 index b95e149..0000000 --- a/packages/cloud/src/index.ts +++ /dev/null @@ -1,10 +0,0 @@ -export { CoolCloudConfiguration as Configuration } from './configuration'; - -export * from './interface'; - -// 云数据库 -export * from './db/index'; - -// 云函数 -export * from './func/index'; -export * from './func/crud'; diff --git a/packages/cloud/src/interface.ts b/packages/cloud/src/interface.ts deleted file mode 100644 index 3c36af0..0000000 --- a/packages/cloud/src/interface.ts +++ /dev/null @@ -1,11 +0,0 @@ -/** - * 云函数请求 - */ -export interface CloudReq { - // 云函数名称 - name: string; - // 请求参数 - params: any; - // 调用方法 - method: string; -} diff --git a/packages/cloud/src/package.json b/packages/cloud/src/package.json deleted file mode 100644 index bf99ff5..0000000 --- a/packages/cloud/src/package.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "name": "@cool-midway/cloud", - "version": "6.0.0", - "description": "", - "main": "index.js", - "typings": "index.d.ts", - "scripts": { - "build": "cross-env midway-bin build -c", - "test": "cross-env midway-bin test --ts", - "cov": "cross-env midway-bin cov --ts", - "lint": "mwts check", - "lint:fix": "mwts fix" - }, - "keywords": ["cool","cool-admin","cooljs"], - "author": "COOL", - "files": [ - "**/*.js", - "**/*.d.ts", - "index.d.ts" - ], - "license": "MIT", - "repository": { - "type": "git", - "url": "https://cool-js.com" - }, - "devDependencies": { - "@cool-midway/core": "^6.0.0", - "@midwayjs/cli": "^2.0.0", - "@midwayjs/core": "^3.0.0", - "@midwayjs/decorator": "^3.0.0", - "@midwayjs/mock": "^3.0.0", - "@midwayjs/typeorm": "^3.8.3", - "@types/jest": "^29.2.0", - "@types/node": "^16.11.22", - "cross-env": "^6.0.0", - "jest": "^29.2.2", - "mwts": "^1.0.5", - "ts-jest": "^29.0.3", - "typeorm": "^0.3.11", - "typescript": "^4.9.4" - } -} diff --git a/packages/cloud/src/util.ts b/packages/cloud/src/util.ts deleted file mode 100644 index f98361e..0000000 --- a/packages/cloud/src/util.ts +++ /dev/null @@ -1 +0,0 @@ -export class CoolCloudUtil {} diff --git a/packages/cloud/test/index.test.ts b/packages/cloud/test/index.test.ts deleted file mode 100644 index a6c75a1..0000000 --- a/packages/cloud/test/index.test.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { createLightApp } from '@midwayjs/mock'; -import * as custom from '../src'; - -describe('/test/index.test.ts', () => { - it('test component', async () => { - const app = await createLightApp('', { - imports: [ - custom - ] - }); - const bookService = await app.getApplicationContext().getAsync(custom.BookService); - expect(await bookService.getBookById()).toEqual('hello world'); - }); -}); diff --git a/packages/cloud/tsconfig.json b/packages/cloud/tsconfig.json deleted file mode 100644 index 9bb4ab7..0000000 --- a/packages/cloud/tsconfig.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "compileOnSave": true, - "compilerOptions": { - "target": "es2018", - "module": "commonjs", - "moduleResolution": "node", - "experimentalDecorators": true, - "emitDecoratorMetadata": true, - "inlineSourceMap":false, - "noImplicitThis": true, - "noUnusedLocals": true, - "stripInternal": true, - "skipLibCheck": true, - "noImplicitReturns": false, - "pretty": true, - "declaration": true, - "forceConsistentCasingInFileNames": true, - "outDir": "dist" - }, - "exclude": [ - "dist", - "node_modules", - "test" - ] -} diff --git a/packages/core/LICENSE b/packages/core/LICENSE deleted file mode 100644 index 5a739ee..0000000 --- a/packages/core/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2013 - Now midwayjs - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/packages/core/README.md b/packages/core/README.md deleted file mode 100644 index 610c3db..0000000 --- a/packages/core/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# cool-admin - -https://cool-js.com diff --git a/packages/core/_.editorconfig b/packages/core/_.editorconfig deleted file mode 100644 index 4c7f8a8..0000000 --- a/packages/core/_.editorconfig +++ /dev/null @@ -1,11 +0,0 @@ -# 🎨 editorconfig.org - -root = true - -[*] -charset = utf-8 -end_of_line = lf -indent_style = space -indent_size = 2 -trim_trailing_whitespace = true -insert_final_newline = true \ No newline at end of file diff --git a/packages/core/_.eslintrc.json b/packages/core/_.eslintrc.json deleted file mode 100644 index 8d20e22..0000000 --- a/packages/core/_.eslintrc.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "extends": "./node_modules/mwts/", - "ignorePatterns": ["node_modules", "dist", "test", "jest.config.js", "typings"], - "env": { - "jest": true - } -} diff --git a/packages/core/_.gitignore b/packages/core/_.gitignore deleted file mode 100644 index 13bc3a6..0000000 --- a/packages/core/_.gitignore +++ /dev/null @@ -1,15 +0,0 @@ -logs/ -npm-debug.log -yarn-error.log -node_modules/ -package-lock.json -yarn.lock -coverage/ -dist/ -.idea/ -run/ -.DS_Store -*.sw* -*.un~ -.tsbuildinfo -.tsbuildinfo.* diff --git a/packages/core/_.prettierrc.js b/packages/core/_.prettierrc.js deleted file mode 100644 index b964930..0000000 --- a/packages/core/_.prettierrc.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - ...require('mwts/.prettierrc.json') -} diff --git a/packages/core/index.d.ts b/packages/core/index.d.ts deleted file mode 100644 index e0065de..0000000 --- a/packages/core/index.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -export * from './dist/index'; - -declare module '@midwayjs/core/dist/interface' { - interface MidwayConfig { - book?: PowerPartial<{ - a: number; - b: string; - }>; - } -} diff --git a/packages/core/jest.config.js b/packages/core/jest.config.js deleted file mode 100644 index 82a8b85..0000000 --- a/packages/core/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - preset: 'ts-jest', - testEnvironment: 'node', - testPathIgnorePatterns: ['/test/fixtures'], - coveragePathIgnorePatterns: ['/test/'], - setupFilesAfterEnv: ['./jest.setup.js'] -}; diff --git a/packages/core/jest.setup.js b/packages/core/jest.setup.js deleted file mode 100644 index 1399c91..0000000 --- a/packages/core/jest.setup.js +++ /dev/null @@ -1 +0,0 @@ -jest.setTimeout(30000); diff --git a/packages/core/package.json b/packages/core/package.json deleted file mode 100644 index fbbc76d..0000000 --- a/packages/core/package.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "name": "@cool-midway/core", - "version": "6.0.7", - "description": "", - "main": "dist/index.js", - "typings": "index.d.ts", - "scripts": { - "build": "cross-env midway-bin build -c", - "test": "cross-env midway-bin test --ts", - "cov": "cross-env midway-bin cov --ts", - "lint": "mwts check", - "lint:fix": "mwts fix" - }, - "keywords": [ - "cool", - "cool-admin", - "cooljs" - ], - "author": "COOL", - "files": [ - "dist/**/*.js", - "dist/**/*.d.ts", - "index.d.ts" - ], - "readme": "README.md", - "license": "MIT", - "repository": { - "type": "git", - "url": "https://cool-js.com" - }, - "devDependencies": { - "@midwayjs/cli": "1.3.21", - "@midwayjs/core": "^3.9.0", - "@midwayjs/decorator": "^3.9.0", - "@midwayjs/koa": "^3.9.0", - "@midwayjs/mock": "^3.9.0", - "@midwayjs/typeorm": "^3.9.0", - "@types/jest": "^29.2.4", - "@types/node": "^18.11.15", - "aedes": "^0.48.1", - "cross-env": "^7.0.3", - "jest": "^29.3.1", - "mwts": "^1.3.0", - "ts-jest": "^29.0.3", - "typeorm": "^0.3.11", - "typescript": "~4.9.4" - }, - "dependencies": { - "@midwayjs/cache": "^3.9.0", - "lodash": "^4.17.21", - "md5": "^2.3.0", - "moment": "^2.29.4", - "mysql2-import": "^5.0.22", - "sqlstring": "^2.3.3" - } -} diff --git a/packages/core/src/LICENSE b/packages/core/src/LICENSE deleted file mode 100644 index 5a739ee..0000000 --- a/packages/core/src/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2013 - Now midwayjs - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/packages/core/src/config/config.default.ts b/packages/core/src/config/config.default.ts deleted file mode 100644 index f93645e..0000000 --- a/packages/core/src/config/config.default.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { CoolConfig } from "../interface"; - -/** - * cool的配置 - */ -export default { - cool: { - // 是否自动导入数据库 - initDB: false, - // crud配置 - crud: { - // 软删除 - softDelete: true, - // 分页查询每页条数 - pageSize: 15, - }, - } as CoolConfig, -}; diff --git a/packages/core/src/configuration.ts b/packages/core/src/configuration.ts deleted file mode 100644 index 4204797..0000000 --- a/packages/core/src/configuration.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { - App, - Context, - ILifeCycle, - ILogger, - IMidwayBaseApplication, - IMidwayContainer, - Inject, - Logger, -} from "@midwayjs/core"; -import { Configuration } from "@midwayjs/decorator"; -import * as DefaultConfig from "./config/config.default"; -import { CoolExceptionFilter } from "./exception/filter"; -import { FuncUtil } from "./util/func"; -import location from "./util/location"; -import * as koa from "@midwayjs/koa"; -import { CoolModuleConfig } from "./module/config"; -import { CoolModuleImport } from "./module/import"; -import { CoolEventManager } from "./event"; -import { CoolEps } from "./rest/eps"; -import { CacheManager } from "@midwayjs/cache"; -import * as cache from "@midwayjs/cache"; -import { CoolDecorator } from "./decorator"; - -@Configuration({ - namespace: "cool", - imports: [cache], - importConfigs: [ - { - default: DefaultConfig, - }, - ], -}) -export class CoolConfiguration implements ILifeCycle { - @Logger() - coreLogger: ILogger; - - @App() - app: koa.Application; - - @Inject() - coolEventManager: CoolEventManager; - - async onReady(container: IMidwayContainer) { - this.coolEventManager.emit("onReady"); - // 处理模块配置 - await container.getAsync(CoolModuleConfig); - // 导入模块数据 - await container.getAsync(CoolModuleImport); - // 常用函数处理 - await container.getAsync(FuncUtil); - // 事件 - await container.getAsync(CoolEventManager); - // 异常处理 - this.app.useFilter([CoolExceptionFilter]); - // 装饰器 - await container.getAsync(CoolDecorator); - - if (this.app.getEnv() == "local") { - // 实体与路径 - const eps: CoolEps = await container.getAsync(CoolEps); - eps.init(); - } - // 缓存设置为全局 - global["COOL-CACHE"] = await container.getAsync(CacheManager); - // 清除 location - setTimeout(() => { - location.clean(); - this.coreLogger.info("\x1B[36m [cool:core] location clean \x1B[0m"); - }, 10000); - } - - async onConfigLoad( - container: IMidwayContainer, - mainApp?: IMidwayBaseApplication - ) {} - - async onServerReady() { - this.coolEventManager.emit("onServerReady"); - location.clean(); - } -} diff --git a/packages/core/src/constant/global.ts b/packages/core/src/constant/global.ts deleted file mode 100644 index 3cf5a9e..0000000 --- a/packages/core/src/constant/global.ts +++ /dev/null @@ -1,50 +0,0 @@ -/** - * 返回码 - */ -export enum RESCODE { - // 成功 - SUCCESS = 1000, - // 失败 - COMMFAIL = 1001, - // 参数验证失败 - VALIDATEFAIL = 1002, - // 参数验证失败 - COREFAIL = 1003, -} - -/** - * 返回信息 - */ -export enum RESMESSAGE { - // 成功 - SUCCESS = "success", - // 失败 - COMMFAIL = "comm fail", - // 参数验证失败 - VALIDATEFAIL = "validate fail", - // 核心异常 - COREFAIL = "core fail", -} - -/** - * 错误提示 - */ -export enum ERRINFO { - NOENTITY = "未设置操作实体", - NOID = "查询参数[id]不存在", - SORTFIELD = "排序参数不正确", -} - -/** - * 事件 - */ -export enum EVENT { - // 软删除 - SOFT_DELETE = "onSoftDelete", - // 服务成功启动 - SERVER_READY = "onServerReady", - // 服务就绪 - READY = "onReady", - // ES 数据改变 - ES_DATA_CHANGE = "esDataChange", -} diff --git a/packages/core/src/controller/base.ts b/packages/core/src/controller/base.ts deleted file mode 100644 index 24d5f90..0000000 --- a/packages/core/src/controller/base.ts +++ /dev/null @@ -1,203 +0,0 @@ -import { - App, - CONTROLLER_KEY, - getClassMetadata, - Init, - Inject, - Provide, -} from "@midwayjs/decorator"; -import { RESCODE, RESMESSAGE } from "../constant/global"; -import { ControllerOption, CurdOption } from "../decorator/controller"; -import { BaseService } from "../service/base"; -import { IMidwayApplication } from "@midwayjs/core"; -import { Context } from "@midwayjs/koa"; -import { TypeORMDataSourceManager } from "@midwayjs/typeorm"; - -/** - * 控制器基类 - */ -@Provide() -export abstract class BaseController { - @Inject("ctx") - baseCtx: Context; - - @Inject() - service: BaseService; - - @App() - baseApp: IMidwayApplication; - - curdOption: CurdOption; - - @Inject() - typeORMDataSourceManager: TypeORMDataSourceManager; - - connectionName; - - @Init() - async init() { - const option: ControllerOption = getClassMetadata(CONTROLLER_KEY, this); - const curdOption: CurdOption = option.curdOption; - this.curdOption = curdOption; - if (!this.curdOption) { - return; - } - // 操作之前 - await this.before(curdOption); - // 设置service - await this.setService(curdOption); - // 设置实体 - await this.setEntity(curdOption); - } - - private async before(curdOption: CurdOption) { - if (!curdOption?.before) { - return; - } - await curdOption.before(this.baseCtx, this.baseApp); - } - - /** - * 插入参数值 - * @param curdOption 配置 - */ - private async insertParam(curdOption: CurdOption) { - if (!curdOption?.insertParam) { - return; - } - this.baseCtx.request.body = { - // @ts-ignore - ...this.baseCtx.request.body, - ...(await curdOption.insertParam(this.baseCtx, this.baseApp)), - }; - } - - /** - * 设置实体 - * @param curdOption 配置 - */ - private async setEntity(curdOption: CurdOption) { - const entity = curdOption?.entity; - if (entity) { - const dataSourceName = - this.typeORMDataSourceManager.getDataSourceNameByModel(entity); - let entityModel = this.typeORMDataSourceManager - .getDataSource(dataSourceName) - .getRepository(entity); - this.service.setEntity(entityModel); - } - } - - /** - * 设置service - * @param curdOption - */ - private async setService(curdOption: CurdOption) { - if (curdOption.service) { - this.service = await this.baseCtx.requestContext.getAsync( - curdOption.service - ); - } - } - - /** - * 新增 - * @returns - */ - async add() { - // 插入参数 - await this.insertParam(this.curdOption); - const { body } = this.baseCtx.request; - return this.ok(await this.service.add(body)); - } - - /** - * 删除 - * @returns - */ - async delete() { - // @ts-ignore - const { ids } = this.baseCtx.request.body; - return this.ok(await this.service.delete(ids)); - } - - /** - * 更新 - * @returns - */ - async update() { - const { body } = this.baseCtx.request; - return this.ok(await this.service.update(body)); - } - - /** - * 分页查询 - * @returns - */ - async page() { - const { body } = this.baseCtx.request; - return this.ok( - await this.service.page( - body, - this.curdOption.pageQueryOp, - this.connectionName - ) - ); - } - - /** - * 列表查询 - * @returns - */ - async list() { - const { body } = this.baseCtx.request; - return this.ok( - await this.service.list( - body, - this.curdOption.listQueryOp, - this.connectionName - ) - ); - } - - /** - * 根据ID查询信息 - * @returns - */ - async info() { - const { id } = this.baseCtx.query; - return this.ok( - await this.service.info(id, this.curdOption.infoIgnoreProperty) - ); - } - - /** - * 成功返回 - * @param data 返回数据 - */ - ok(data?: any) { - const res = { - code: RESCODE.SUCCESS, - message: RESMESSAGE.SUCCESS, - }; - if (data || data == 0) { - res["data"] = data; - } - return res; - } - - /** - * 失败返回 - * @param message - */ - fail(message?: string, code?: RESCODE) { - return { - code: code ? code : RESCODE.COMMFAIL, - message: message - ? message - : code == RESCODE.VALIDATEFAIL - ? RESMESSAGE.VALIDATEFAIL - : RESMESSAGE.COMMFAIL, - }; - } -} diff --git a/packages/core/src/decorator/cache.ts b/packages/core/src/decorator/cache.ts deleted file mode 100644 index f8195f0..0000000 --- a/packages/core/src/decorator/cache.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { createCustomMethodDecorator } from "@midwayjs/decorator"; - -// 装饰器内部的唯一 id -export const COOL_CACHE = "decorator:cool_cache"; - -export function CoolCache(ttl?: number): MethodDecorator { - return createCustomMethodDecorator(COOL_CACHE, ttl); -} diff --git a/packages/core/src/decorator/controller.ts b/packages/core/src/decorator/controller.ts deleted file mode 100644 index 98c863b..0000000 --- a/packages/core/src/decorator/controller.ts +++ /dev/null @@ -1,208 +0,0 @@ -import { ModuleConfig } from "./../interface"; -import { - Scope, - ScopeEnum, - saveClassMetadata, - saveModule, - CONTROLLER_KEY, - MiddlewareParamArray, - WEB_ROUTER_KEY, - attachClassMetadata, -} from "@midwayjs/decorator"; -import * as fs from "fs"; -import * as _ from "lodash"; -import * as os from "os"; -import location from "../util/location"; - -export type ApiTypes = "add" | "delete" | "update" | "page" | "info" | "list"; -// Crud配置 - -export interface CurdOption { - // 路由前缀,不配置默认是按Controller下的文件夹路径 - prefix?: string; - // curd api接口 - api: ApiTypes[]; - // 分页查询配置 - pageQueryOp?: QueryOp | Function; - // 非分页查询配置 - listQueryOp?: QueryOp | Function; - // 插入参数 - insertParam?: Function; - // 操作之前 - before?: Function; - // info 忽略返回属性 - infoIgnoreProperty?: string[]; - // 实体 - entity: any; - // 服务 - service?: any; - // api标签 - urlTag?: { - name: "ignoreToken" | string; - url: ApiTypes[]; - }; -} -export interface JoinOp { - // 实体 - entity: any; - // 别名 - alias: string; - // 关联条件 - condition: string; - // 关联类型 - type?: "innerJoin" | "leftJoin"; -} - -// 字段匹配 -export interface FieldEq { - // 字段 - column: string; - // 请求参数 - requestParam: string; -} -// 查询配置 -export interface QueryOp { - // 需要模糊查询的字段 - keyWordLikeFields?: string[]; - // 查询条件 - where?: Function; - // 查询字段 - select?: string[]; - // 字段相等 - fieldEq?: string[] | FieldEq[]; - // 添加排序条件 - addOrderBy?: {}; - // 关联配置 - join?: JoinOp[]; - // 其他条件 - extend?: Function; -} - -// Controller 配置 -export interface ControllerOption { - // crud配置 如果是字符串则为路由前缀,不配置默认是按Controller下的文件夹路径 - curdOption?: CurdOption & string; - // 路由配置 - routerOptions?: { - // 是否敏感 - sensitive?: boolean; - // 路由中间件 - middleware?: MiddlewareParamArray; - // 别名 - alias?: string[]; - // 描述 - description?: string; - // 标签名称 - tagName?: string; - }; -} - -// COOL的装饰器 -export function CoolController( - curdOption?: CurdOption | string, - routerOptions: { - sensitive?: boolean; - middleware?: MiddlewareParamArray; - description?: string; - tagName?: string; - ignoreGlobalPrefix?: boolean; - } = { middleware: [], sensitive: true } -): ClassDecorator { - return (target: any) => { - // 将装饰的类,绑定到该装饰器,用于后续能获取到 class - saveModule(CONTROLLER_KEY, target); - let prefix; - if (typeof curdOption === "string") { - prefix = curdOption; - } else { - prefix = curdOption?.prefix || ""; - } - // 如果不存在路由前缀,那么自动根据当前文件夹路径 - location.scriptPath(target).then(async (res: any) => { - const pathSps = res.path.split("."); - const paths = pathSps[pathSps.length - 2].split("/"); - const pathArr = []; - let module = null; - for (const path of paths.reverse()) { - if (path != "controller" && !module) { - pathArr.push(path); - } - if (path == "controller" && !paths.includes("modules")) { - break; - } - if (path == "controller" && paths.includes("modules")) { - module = "ready"; - } - if (module && path != "controller") { - module = `${path}`; - break; - } - } - if (module) { - pathArr.reverse(); - pathArr.splice(1, 0, module); - // 追加模块中间件 - let path = `${ - res.path.split(`modules/${module}`)[0] - }modules/${module}/config.${_.endsWith(res.path, "ts") ? "ts" : "js"}`; - if (os.type() == "Windows_NT") { - path = path.substr(1); - } - if (fs.existsSync(path)) { - const config: ModuleConfig = require(path).default(); - routerOptions.middleware = (config.middlewares || []).concat( - routerOptions.middleware || [] - ); - } - } - if (!prefix) { - prefix = `/${pathArr.join("/")}`; - } - saveMetadata(prefix, routerOptions, target, curdOption, module); - }); - }; -} - -export const apiDesc = { - add: "新增", - delete: "删除", - update: "修改", - page: "分页查询", - list: "列表查询", - info: "单个信息", -}; - -// 保存一些元数据信息,任意你希望存的东西 -function saveMetadata(prefix, routerOptions, target, curdOption, module) { - if (module && !routerOptions.tagName) { - routerOptions = routerOptions || {}; - routerOptions.tagName = module; - } - saveClassMetadata( - CONTROLLER_KEY, - { - prefix, - routerOptions, - curdOption, - module, - } as ControllerOption, - target - ); - // 追加CRUD路由 - if (!_.isEmpty(curdOption?.api)) { - curdOption?.api.forEach((path) => { - attachClassMetadata( - WEB_ROUTER_KEY, - { - path: `/${path}`, - requestMethod: path == "info" ? "get" : "post", - method: path, - summary: apiDesc[path], - description: "", - }, - target - ); - }); - Scope(ScopeEnum.Request)(target); - } -} diff --git a/packages/core/src/decorator/event.ts b/packages/core/src/decorator/event.ts deleted file mode 100644 index e21b9db..0000000 --- a/packages/core/src/decorator/event.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { - Scope, - ScopeEnum, - saveClassMetadata, - saveModule, - attachClassMetadata, -} from "@midwayjs/decorator"; - -export const COOL_CLS_EVENT_KEY = "decorator:cool:cls:event"; - -export function CoolEvent(): ClassDecorator { - return (target: any) => { - // 将装饰的类,绑定到该装饰器,用于后续能获取到 class - saveModule(COOL_CLS_EVENT_KEY, target); - // 保存一些元数据信息,任意你希望存的东西 - saveClassMetadata(COOL_CLS_EVENT_KEY, {}, target); - // 指定 IoC 容器创建实例的作用域,这里注册为请求作用域,这样能取到 ctx - Scope(ScopeEnum.Singleton)(target); - }; -} - -export const COOL_EVENT_KEY = "decorator:cool:event"; - -/** - * 事件 - * @param eventName - * @returns - */ -export function Event(eventName?: string): MethodDecorator { - return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => { - // 将装饰的类,绑定到该装饰器,用于后续能获取到 class - attachClassMetadata( - COOL_EVENT_KEY, - { - eventName, - propertyKey, - descriptor, - }, - target - ); - }; -} diff --git a/packages/core/src/decorator/index.ts b/packages/core/src/decorator/index.ts deleted file mode 100644 index db51685..0000000 --- a/packages/core/src/decorator/index.ts +++ /dev/null @@ -1,103 +0,0 @@ -import { COOL_CACHE } from "./cache"; -import { CacheManager } from "@midwayjs/cache"; -import { - Init, - Inject, - JoinPoint, - MidwayDecoratorService, - Provide, - Scope, - ScopeEnum, -} from "@midwayjs/core"; -import { TypeORMDataSourceManager } from "@midwayjs/typeorm"; -import { CoolCommException } from "../exception/comm"; -import { COOL_TRANSACTION, TransactionOptions } from "./transaction"; -import * as md5 from "md5"; - -/** - * 装饰器 - */ -@Provide() -@Scope(ScopeEnum.Singleton) -export class CoolDecorator { - @Inject() - typeORMDataSourceManager: TypeORMDataSourceManager; - - @Inject() - decoratorService: MidwayDecoratorService; - - @Inject() - cacheManager: CacheManager; - - @Init() - async init() { - // 事务 - await this.transaction(); - // 缓存 - await this.cache(); - } - - /** - * 缓存 - */ - async cache() { - this.decoratorService.registerMethodHandler(COOL_CACHE, (options) => { - return { - around: async (joinPoint: JoinPoint) => { - const key = md5( - joinPoint.target.constructor.name + - joinPoint.methodName + - JSON.stringify(joinPoint.args) - ); - // 缓存有数据就返回 - let data: any = await this.cacheManager.get(key); - if (data) { - return JSON.parse(data); - } else { - // 执行原始方法 - data = await joinPoint.proceed(...joinPoint.args); - await this.cacheManager.set(key, JSON.stringify(data), { - ttl: options.metadata, - }); - } - return data; - }, - }; - }); - } - - /** - * 事务 - */ - async transaction() { - this.decoratorService.registerMethodHandler(COOL_TRANSACTION, (options) => { - return { - around: async (joinPoint: JoinPoint) => { - const option: TransactionOptions = options.metadata; - const dataSource = this.typeORMDataSourceManager.getDataSource( - option?.connectionName || "default" - ); - const queryRunner = dataSource.createQueryRunner(); - await queryRunner.connect(); - if (option && option.isolation) { - await queryRunner.startTransaction(option.isolation); - } else { - await queryRunner.startTransaction(); - } - let data; - try { - joinPoint.args.push(queryRunner); - data = await joinPoint.proceed(...joinPoint.args); - await queryRunner.commitTransaction(); - } catch (error) { - await queryRunner.rollbackTransaction(); - throw new CoolCommException(error.message); - } finally { - await queryRunner.release(); - } - return data; - }, - }; - }); - } -} diff --git a/packages/core/src/decorator/tag.ts b/packages/core/src/decorator/tag.ts deleted file mode 100644 index 69d1357..0000000 --- a/packages/core/src/decorator/tag.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { saveClassMetadata, saveModule } from "@midwayjs/decorator"; - -export const COOL_URL_TAG_KEY = "decorator:cool:url:tag"; - -export enum TagTypes { - IGNORE_TOKEN = "ignoreToken", - IGNORE_SIGN = "ignoreSign", -} - -export interface CoolUrlTagConfig { - key: TagTypes | string; - value: string[]; -} - -/** - * 打标记 - * @param data - * @returns - */ -export function CoolUrlTag(data: CoolUrlTagConfig): ClassDecorator { - return (target: any) => { - // 将装饰的类,绑定到该装饰器,用于后续能获取到 class - saveModule(COOL_URL_TAG_KEY, target); - // 保存一些元数据信息,任意你希望存的东西 - saveClassMetadata(COOL_URL_TAG_KEY, data, target); - }; -} diff --git a/packages/core/src/decorator/transaction.ts b/packages/core/src/decorator/transaction.ts deleted file mode 100644 index 5922dc3..0000000 --- a/packages/core/src/decorator/transaction.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { createCustomMethodDecorator } from "@midwayjs/decorator"; - -type IsolationLevel = - | "READ UNCOMMITTED" - | "READ COMMITTED" - | "REPEATABLE READ" - | "SERIALIZABLE"; - -export interface TransactionOptions { - connectionName?: string; - isolation?: IsolationLevel; -} - -// 装饰器内部的唯一 id -export const COOL_TRANSACTION = "decorator:cool_transaction"; - -export function CoolTransaction(option?: TransactionOptions): MethodDecorator { - return createCustomMethodDecorator(COOL_TRANSACTION, option); -} diff --git a/packages/core/src/entity/base.ts b/packages/core/src/entity/base.ts deleted file mode 100644 index 8a40e4c..0000000 --- a/packages/core/src/entity/base.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { - Index, - UpdateDateColumn, - CreateDateColumn, - PrimaryGeneratedColumn, -} from "typeorm"; -import { CoolBaseEntity } from "./typeorm"; - -/** - * 模型基类 - */ -export abstract class BaseEntity extends CoolBaseEntity { - // 默认自增 - @PrimaryGeneratedColumn("increment", { - comment: "ID", - // type: "bigint", - }) - id: number; - - @Index() - @CreateDateColumn({ comment: "创建时间" }) - createTime: Date; - - @Index() - @UpdateDateColumn({ comment: "更新时间" }) - updateTime: Date; -} diff --git a/packages/core/src/entity/mongo.ts b/packages/core/src/entity/mongo.ts deleted file mode 100644 index f17dec5..0000000 --- a/packages/core/src/entity/mongo.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { - Index, - UpdateDateColumn, - CreateDateColumn, - // @ts-ignore - ObjectID, - ObjectIdColumn, -} from "typeorm"; -import { CoolBaseEntity } from "./typeorm"; - -/** - * 模型基类 - */ -export abstract class BaseMongoEntity extends CoolBaseEntity { - @ObjectIdColumn({ comment: "id" }) - id: ObjectID; - - @Index() - @CreateDateColumn({ comment: "创建时间" }) - createTime: Date; - - @Index() - @UpdateDateColumn({ comment: "更新时间" }) - updateTime: Date; -} diff --git a/packages/core/src/entity/typeorm.ts b/packages/core/src/entity/typeorm.ts deleted file mode 100644 index f9c1c8b..0000000 --- a/packages/core/src/entity/typeorm.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { BaseEntity } from "typeorm"; - -export abstract class CoolBaseEntity extends BaseEntity {} diff --git a/packages/core/src/event/index.ts b/packages/core/src/event/index.ts deleted file mode 100644 index 02ae835..0000000 --- a/packages/core/src/event/index.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { - App, - getClassMetadata, - Init, - listModule, - Provide, - Scope, - ScopeEnum, -} from "@midwayjs/decorator"; -import * as Events from "events"; -import { IMidwayApplication } from "@midwayjs/core"; -import { COOL_CLS_EVENT_KEY, COOL_EVENT_KEY } from "../decorator/event"; - -/** - * 事件 - */ -@Provide() -@Scope(ScopeEnum.Singleton) -export class CoolEventManager extends Events { - @App() - app: IMidwayApplication; - - @Init() - async init() { - const eventModules = listModule(COOL_CLS_EVENT_KEY); - for (const module of eventModules) { - this.handlerEvent(module); - } - } - - async handlerEvent(module) { - const events = getClassMetadata(COOL_EVENT_KEY, module); - for (const event of events) { - const method = event.eventName ? event.eventName : event.propertyKey; - this.on(method, async (...args) => { - const moduleInstance = await this.app - .getApplicationContext() - .getAsync(module); - moduleInstance[event.propertyKey](...args); - }); - } - } -} diff --git a/packages/core/src/exception/base.ts b/packages/core/src/exception/base.ts deleted file mode 100644 index 177b46b..0000000 --- a/packages/core/src/exception/base.ts +++ /dev/null @@ -1,13 +0,0 @@ -/** - * 异常基类 - */ -export class BaseException extends Error { - status: number; - - constructor(name: string, code: number, message: string) { - super(message); - - this.name = name; - this.status = code; - } -} diff --git a/packages/core/src/exception/comm.ts b/packages/core/src/exception/comm.ts deleted file mode 100644 index 693a7a9..0000000 --- a/packages/core/src/exception/comm.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { RESCODE, RESMESSAGE } from '../constant/global'; -import { BaseException } from './base'; - -/** - * 通用异常 - */ -export class CoolCommException extends BaseException { - constructor(message: string) { - super( - 'CoolCommException', - RESCODE.COMMFAIL, - message ? message : RESMESSAGE.COMMFAIL - ); - } -} diff --git a/packages/core/src/exception/core.ts b/packages/core/src/exception/core.ts deleted file mode 100644 index 8c279de..0000000 --- a/packages/core/src/exception/core.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { RESCODE, RESMESSAGE } from '../constant/global'; -import { BaseException } from './base'; - -/** - * 核心异常 - */ -export class CoolCoreException extends BaseException { - constructor(message: string) { - super( - 'CoolCoreException', - RESCODE.COREFAIL, - message ? message : RESMESSAGE.COREFAIL - ); - } -} diff --git a/packages/core/src/exception/filter.ts b/packages/core/src/exception/filter.ts deleted file mode 100644 index fb894ac..0000000 --- a/packages/core/src/exception/filter.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { RESCODE } from './../constant/global'; -import { ILogger } from '@midwayjs/core'; -import { Catch, Logger } from '@midwayjs/decorator'; - -/** - * 全局异常处理 - */ -@Catch() -export class CoolExceptionFilter { - @Logger() - coreLogger: ILogger; - - async catch(err) { - this.coreLogger.error(err); - return { - code: err.status || RESCODE.COMMFAIL, - message: err.message, - }; - } -} diff --git a/packages/core/src/exception/validate.ts b/packages/core/src/exception/validate.ts deleted file mode 100644 index 6f374e6..0000000 --- a/packages/core/src/exception/validate.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { RESCODE, RESMESSAGE } from '../constant/global'; -import { BaseException } from './base'; - -/** - * 校验异常 - */ -export class CoolValidateException extends BaseException { - constructor(message: string) { - super( - 'CoolValidateException', - RESCODE.VALIDATEFAIL, - message ? message : RESMESSAGE.VALIDATEFAIL - ); - } -} diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts deleted file mode 100644 index 8f1bbac..0000000 --- a/packages/core/src/index.ts +++ /dev/null @@ -1,45 +0,0 @@ -export { CoolConfiguration as Configuration } from "./configuration"; - -// 异常处理 -export * from "./exception/filter"; -export * from "./exception/core"; -export * from "./exception/base"; -export * from "./exception/comm"; -export * from "./exception/validate"; - -// entity -export * from "./entity/base"; -export * from "./entity/typeorm"; -export * from "./entity/mongo"; - -// service -export * from "./service/base"; - -// controller -export * from "./controller/base"; - -// 事件 -export * from "./event/index"; - -// 装饰器 -export * from "./decorator/controller"; -export * from "./decorator/cache"; -export * from "./decorator/event"; -export * from "./decorator/transaction"; -export * from "./decorator/tag"; -export * from "./decorator/index"; - -// rest -export * from "./rest/eps"; - -// tag -export * from "./tag/data"; - -// 模块 -export * from "./module/config"; -export * from "./module/import"; - -// 其他 -export * from "./interface"; -export * from "./util/func"; -export * from "./constant/global"; diff --git a/packages/core/src/interface.ts b/packages/core/src/interface.ts deleted file mode 100644 index 2f2e205..0000000 --- a/packages/core/src/interface.ts +++ /dev/null @@ -1,387 +0,0 @@ -import { MiddlewareParamArray } from "@midwayjs/core"; -import { AedesOptions } from "aedes"; -import { PublishPacket } from "packet"; - -/** - * 模块配置 - */ -export interface ModuleConfig { - /** 名称 */ - name: string; - /** 描述 */ - description: string; - /** 模块中间件 */ - middlewares?: MiddlewareParamArray; - /** 全局中间件 */ - globalMiddlewares?: MiddlewareParamArray; - /** 模块加载顺序,默认为0,值越大越优先加载 */ - order?: number; -} - -export interface CoolConfig { - /** 短信 */ - sms: CoolSmsConfig, - /** 是否自动导入数据库 */ - initDB?: boolean; - // 实体配置 - // entity?: { - // primaryType: "uuid" | "increment" | "rowid" | "identity"; - // }; - /** crud配置 */ - crud?: { - /** 软删除 */ - softDelete: boolean; - /** 分页查询每页条数 */ - pageSize: number; - // 多租户 - // tenant: boolean; - }; - /** elasticsearch配置 */ - es?: { - nodes: string[]; - }; - /** pay */ - pay?: { - /** 微信支付 */ - wx?: CoolWxPayConfig; - /** 支付宝支付 */ - ali?: CoolAliPayConfig; - }; - /** rpc */ - rpc?: CoolRpcConfig; - /** redis */ - redis?: RedisConfig | RedisConfig[]; - /** 文件上传 */ - file?: { - /** 上传模式 */ - mode: MODETYPE; - /** 本地上传 文件地址前缀 */ - domain?: string; - /** oss */ - oss?: OSSConfig; - /** cos */ - cos?: COSConfig; - /** qiniu */ - qiniu?: QINIUConfig; - }; - /** IOT 配置 */ - iot?: CoolIotConfig; -} - -export interface CoolRpcConfig { - /** 服务名称 */ - name: string; - /** redis */ - redis: RedisConfig & RedisConfig[] & unknown; -} - -export interface RedisConfig { - /** host */ - host: string; - /** password */ - password: string; - /** port */ - port: number; - /** db */ - db: number; -} - -// 模式 -export enum MODETYPE { - /** 本地 */ - LOCAL = "local", - /** 云存储 */ - CLOUD = "cloud", - /** 其他 */ - OTHER = "other", -} - -export enum CLOUDTYPE { - /** 阿里云存储 */ - OSS = "oss", - /** 腾讯云存储 */ - COS = "cos", - /** 七牛云存储 */ - QINIU = "qiniu", -} - -/** - * 上传模式 - */ -export interface Mode { - /** 模式 */ - mode: MODETYPE; - /** 类型 */ - type: string; -} - -/** - * 模块配置 - */ -export interface CoolFileConfig { - /** 上传模式 */ - mode: MODETYPE; - /** 阿里云oss 配置 */ - oss: OSSConfig; - /** 腾讯云 cos配置 */ - cos: COSConfig; - /** 七牛云 配置 */ - qiniu: QINIUConfig; - /** 文件前缀 */ - domain: string; -} - -/** - * OSS 配置 - */ -export interface OSSConfig { - /** 阿里云accessKeyId */ - accessKeyId: string; - /** 阿里云accessKeySecret */ - accessKeySecret: string; - /** 阿里云oss的bucket */ - bucket: string; - /** 阿里云oss的endpoint */ - endpoint: string; - /** 阿里云oss的timeout */ - timeout: string; - /** 签名失效时间,毫秒 */ - expAfter?: number; - /** 文件最大的 size */ - maxSize?: number; - // host - host?: string; -} - -/** - * COS 配置 - */ -export interface COSConfig { - /** 腾讯云accessKeyId */ - accessKeyId: string; - /** 腾讯云accessKeySecret */ - accessKeySecret: string; - /** 腾讯云cos的bucket */ - bucket: string; - /** 腾讯云cos的区域 */ - region: string; - /** 腾讯云cos的公网访问地址 */ - publicDomain: string; - /** 上传持续时间 */ - durationSeconds?: number; - /** 允许操作(上传)的对象前缀 */ - allowPrefix?: string; - /** 密钥的权限列表 */ - allowActions?: string[]; -} - -export interface QINIUConfig { - /** 七牛云accessKeyId */ - accessKeyId: string; - /** 七牛云accessKeySecret */ - accessKeySecret: string; - /** 七牛云cos的bucket */ - bucket: string; - /** 七牛云cos的区域 */ - region: string; - /** 七牛云cos的公网访问地址 */ - publicDomain: string; - /** 上传地址 */ - uploadUrl?: string; - /** 上传fileKey */ - fileKey?: string; -} - -/** - * 微信支付配置 - */ -export interface CoolWxPayConfig { - /** 直连商户申请的公众号或移动应用appid。 */ - appid: string; - /** 商户号 */ - mchid: string; - /** 可选参数 证书序列号 */ - serial_no?: string; - /** 回调链接 */ - notify_url: string; - /** 公钥 */ - publicKey: Buffer; - /** 私钥 */ - privateKey: Buffer; - /** 可选参数 认证类型,目前为WECHATPAY2-SHA256-RSA2048 */ - authType?: string; - /** 可选参数 User-Agent */ - userAgent?: string; - /** 可选参数 APIv3密钥 */ - key?: string; -} - -/** - * 支付宝支付配置 - */ -export interface CoolAliPayConfig { - /** 支付回调地址 */ - notifyUrl: string; - /** 应用ID */ - appId: string; - /** - * 应用私钥字符串 - * RSA签名验签工具:https://docs.open.alipay.com/291/106097) - * 密钥格式一栏请选择 “PKCS1(非JAVA适用)” - */ - privateKey: string; - /** 签名类型 */ - signType?: "RSA2" | "RSA"; - /** 支付宝公钥(需要对返回值做验签时候必填) */ - alipayPublicKey?: string; - /** 网关 */ - gateway?: string; - /** 网关超时时间(单位毫秒,默认 5s) */ - timeout?: number; - /** 是否把网关返回的下划线 key 转换为驼峰写法 */ - camelcase?: boolean; - /** 编码(只支持 utf-8) */ - charset?: "utf-8"; - /** api版本 */ - version?: "1.0"; - urllib?: any; - /** 指定private key类型, 默认: PKCS1, PKCS8: PRIVATE KEY, PKCS1: RSA PRIVATE KEY */ - keyType?: "PKCS1" | "PKCS8"; - /** 应用公钥证书文件路径 */ - appCertPath?: string; - /** 应用公钥证书文件内容 */ - appCertContent?: string | Buffer; - /** 应用公钥证书sn */ - appCertSn?: string; - /** 支付宝根证书文件路径 */ - alipayRootCertPath?: string; - /** 支付宝根证书文件内容 */ - alipayRootCertContent?: string | Buffer; - /** 支付宝根证书sn */ - alipayRootCertSn?: string; - /** 支付宝公钥证书文件路径 */ - alipayPublicCertPath?: string; - /** 支付宝公钥证书文件内容 */ - alipayPublicCertContent?: string | Buffer; - /** 支付宝公钥证书sn */ - alipayCertSn?: string; - /** AES密钥,调用AES加解密相关接口时需要 */ - encryptKey?: string; - /** 服务器地址 */ - wsServiceUrl?: string; -} - -/** - * IOT配置 - */ -export interface CoolIotConfig { - /** MQTT服务端口 */ - port: number; - /** MQTT Websocket服务端口 */ - wsPort: number; - /** redis 配置 mqtt cluster下必须要配置 */ - redis?: { - /** host */ - host: string; - /** port */ - port: number; - /** password */ - password: string; - /** db */ - db: number; - }; - /** 发布消息配置 */ - publish?: PublishPacket; - /** 认证 */ - auth?: { - /** 用户 */ - username: string; - /** 密码 */ - password: string; - }; - /** 服务配置 */ - serve?: AedesOptions; -} - - -export interface CoolSmsConfig { - /** - * 阿里云短信配置 - */ - ali: CoolSmsAliConfig; - /** - * 腾讯云短信配置 - */ - tx: CoolTxConfig; - /** - * 云片短信配置 - */ - yp: CoolYpConfig; -} - -/** - * 阿里云配置 - */ -export interface CoolSmsAliConfig { - /** - * 阿里云accessKeyId - */ - accessKeyId: string; - /** - * 阿里云accessKeySecret - */ - accessKeySecret: string; - /** - * 签名,非必填,调用时可以传入 - */ - signName?: string; - /** - * 模板,非必填,调用时可以传入 - */ - template?: string; -} - -/** - * 腾讯云配置 - */ -export interface CoolTxConfig { - /** - * 应用ID - */ - appId: string; - /** - * 腾讯云secretId - */ - secretId: string; - /** - * 腾讯云secretKey - */ - secretKey: string; - /** - * 签名,非必填,调用时可以传入 - */ - signName?: string; - /** - * 模板,非必填,调用时可以传入 - */ - template?: string; -} - -/** - * 云片短信配置 - */ -export interface CoolYpConfig { - /** - * 云片apikey - */ - apikey: string; - /** - * 签名,非必填,调用时可以传入 - */ - signName?: string; - /** - * 模板,非必填,调用时可以传入 - */ - template?: string; -} - diff --git a/packages/core/src/module/config.ts b/packages/core/src/module/config.ts deleted file mode 100644 index d3b510a..0000000 --- a/packages/core/src/module/config.ts +++ /dev/null @@ -1,100 +0,0 @@ -import { IMidwayApplication } from '@midwayjs/core'; -import { - ALL, - App, - Config, - Init, - Provide, - Scope, - ScopeEnum, -} from '@midwayjs/decorator'; -import * as fs from 'fs'; -import { CoolCoreException } from '../exception/core'; -import { ModuleConfig } from '../interface'; -import * as _ from 'lodash'; - -/** - * 模块配置 - */ -@Provide() -@Scope(ScopeEnum.Singleton) -export class CoolModuleConfig { - @App() - app: IMidwayApplication; - - @Config(ALL) - allConfig; - - modules; - - @Init() - async init() { - let modules = []; - // 模块路径 - const moduleBasePath = `${this.app.getBaseDir()}/modules/`; - if (!fs.existsSync(moduleBasePath)) { - return; - } - if (!this.allConfig['module']) { - this.allConfig['module'] = {}; - } - // 全局中间件 - const globalMiddlewareArr = []; - for (const module of fs.readdirSync(moduleBasePath)) { - const modulePath = `${moduleBasePath}/${module}`; - const dirStats = fs.statSync(modulePath); - if (dirStats.isDirectory()) { - const configPath = `${modulePath}/config.${ - this.app.getEnv() == 'local' ? 'ts' : 'js' - }`; - if (fs.existsSync(configPath)) { - const moduleConfig: ModuleConfig = require(configPath).default({ - app: this.app, - env: this.app.getEnv(), - }); - modules.push({ - order: moduleConfig.order || 0, - module: module, - }); - await this.moduleConfig(module, moduleConfig); - // 处理全局中间件 - if (!_.isEmpty(moduleConfig.globalMiddlewares)) { - globalMiddlewareArr.push({ - order: moduleConfig.order || 0, - data: moduleConfig.globalMiddlewares, - }); - } - } else { - throw new CoolCoreException(`模块【${module}】缺少config.ts配置文件`); - } - } - } - this.modules = _.orderBy(modules, ['order'], ['desc']).map(e => { - return e.module; - }); - await this.globalMiddlewareArr(globalMiddlewareArr); - } - - /** - * 模块配置 - * @param module 模块 - * @param config 配置 - */ - async moduleConfig(module, config) { - // 追加配置 - this.allConfig['module'][module] = config; - } - - /** - * 全局中间件 - * @param middleware 中间件 - */ - async globalMiddlewareArr(middlewares: any[]) { - middlewares = _.orderBy(middlewares, ['order'], ['desc']); - for (const middleware of middlewares) { - for (const item of middleware.data) { - this.app.getMiddleware().insertLast(item); - } - } - } -} diff --git a/packages/core/src/module/import.ts b/packages/core/src/module/import.ts deleted file mode 100644 index 0981589..0000000 --- a/packages/core/src/module/import.ts +++ /dev/null @@ -1,150 +0,0 @@ -import { ILogger, IMidwayApplication } from "@midwayjs/core"; -import { - App, - Config, - Init, - Inject, - Logger, - Provide, - Scope, - ScopeEnum, -} from "@midwayjs/decorator"; -import { CoolCoreException } from "../exception/core"; -import * as Importer from "mysql2-import"; -import * as fs from "fs"; -import { CoolModuleConfig } from "./config"; -import * as path from "path"; -import { InjectDataSource, TypeORMDataSourceManager } from "@midwayjs/typeorm"; -import { DataSource } from "typeorm"; -import { CoolEventManager } from "../event"; - -/** - * 模块sql - */ -@Provide() -@Scope(ScopeEnum.Singleton) -export class CoolModuleImport { - @Config("typeorm.dataSource") - ormConfig; - - @InjectDataSource("default") - defaultDataSource: DataSource; - - @Inject() - typeORMDataSourceManager: TypeORMDataSourceManager; - - @Config("cool") - coolConfig; - - @Logger() - coreLogger: ILogger; - - @Inject() - coolModuleConfig: CoolModuleConfig; - - @Inject() - coolEventManager: CoolEventManager; - - @App() - app: IMidwayApplication; - - @Init() - async init() { - // 是否需要导入 - if (this.coolConfig.initDB) { - await this.checkDbVersion(); - const modules = this.coolModuleConfig.modules; - const importLockPath = path.join( - `${this.app.getBaseDir()}`, - "..", - "lock" - ); - if (!fs.existsSync(importLockPath)) { - fs.mkdirSync(importLockPath); - } - setTimeout(async () => { - for (const module of modules) { - const lockPath = path.join(importLockPath, module + ".sql.lock"); - if (!fs.existsSync(lockPath)) { - await this.initDataBase(module, lockPath); - } - } - this.coolEventManager.emit("onDBInit", {}); - }, 2000); - } - } - - /** - * 导入数据库 - * @param module - * @param lockPath 锁定导入 - */ - async initDataBase(module: string, lockPath: string) { - // 模块路径 - const modulePath = `${this.app.getBaseDir()}/modules/${module}`; - // sql 路径 - const sqlPath = `${modulePath}/init.sql`; - // 延迟2秒再导入数据库 - if (fs.existsSync(sqlPath)) { - let second = 0; - const t = setInterval(() => { - this.coreLogger.info( - "\x1B[36m [cool:core] midwayjs cool core init " + - module + - " database... \x1B[0m" - ); - second++; - }, 1000); - const { host, username, password, database, charset, port } = this - .ormConfig?.default - ? this.ormConfig.default - : this.ormConfig; - const importer = new Importer({ - host, - password, - database, - charset, - port, - user: username, - }); - await importer - .import(sqlPath) - .then(async () => { - clearInterval(t); - this.coreLogger.info( - "\x1B[36m [cool:core] midwayjs cool core init " + - module + - " database complete \x1B[0m" - ); - fs.writeFileSync(lockPath, `time consuming:${second}s`); - }) - .catch((err) => { - clearTimeout(t); - this.coreLogger.error( - "\x1B[36m [cool:core] midwayjs cool core init " + - module + - " database err please manual import \x1B[0m" - ); - fs.writeFileSync(lockPath, `time consuming:${second}s`); - this.coreLogger.error(err); - this.coreLogger.error( - `自动初始化模块[${module}]数据库失败,尝试手动导入数据库` - ); - }); - } - } - - /** - * 检查数据库版本 - */ - async checkDbVersion() { - const versions = ( - await this.defaultDataSource.query("SELECT VERSION() AS version") - )[0].version.split("."); - if ((versions[0] == 5 && versions[1] < 7) || versions[0] < 5) { - throw new CoolCoreException( - "数据库不满足要求:mysql>=5.7,请升级数据库版本" - ); - } - } -} diff --git a/packages/core/src/package.json b/packages/core/src/package.json deleted file mode 100644 index 55f5026..0000000 --- a/packages/core/src/package.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "name": "@cool-midway/core", - "version": "6.0.7", - "description": "", - "main": "index.js", - "typings": "index.d.ts", - "scripts": { - "build": "cross-env midway-bin build -c", - "test": "cross-env midway-bin test --ts", - "cov": "cross-env midway-bin cov --ts", - "lint": "mwts check", - "lint:fix": "mwts fix" - }, - "keywords": [ - "cool", - "cool-admin", - "cooljs" - ], - "readme": "README.md", - "author": "COOL", - "files": [ - "**/*.js", - "**/*.d.ts", - "index.d.ts" - ], - "license": "MIT", - "repository": { - "type": "git", - "url": "https://cool-js.com" - }, - "devDependencies": { - "@midwayjs/cli": "1.3.21", - "@midwayjs/core": "^3.9.0", - "@midwayjs/decorator": "^3.9.0", - "@midwayjs/koa": "^3.9.0", - "@midwayjs/mock": "^3.9.0", - "@midwayjs/typeorm": "^3.9.0", - "@types/jest": "^29.2.4", - "@types/node": "^18.11.15", - "cross-env": "^7.0.3", - "jest": "^29.3.1", - "mwts": "^1.3.0", - "ts-jest": "^29.0.3", - "typeorm": "^0.3.11", - "typescript": "~4.9.4" - }, - "dependencies": { - "@midwayjs/cache": "^3.9.0", - "lodash": "^4.17.21", - "md5": "^2.3.0", - "moment": "^2.29.4", - "mysql2-import": "^5.0.22", - "sqlstring": "^2.3.3" - } -} diff --git a/packages/core/src/rest/eps.ts b/packages/core/src/rest/eps.ts deleted file mode 100644 index 623b733..0000000 --- a/packages/core/src/rest/eps.ts +++ /dev/null @@ -1,124 +0,0 @@ -import { - CONTROLLER_KEY, - getClassMetadata, - listModule, - Provide, - Scope, - ScopeEnum, -} from "@midwayjs/decorator"; -import * as _ from "lodash"; -import { Inject, MidwayWebRouterService } from "@midwayjs/core"; -import { TypeORMDataSourceManager } from "@midwayjs/typeorm"; - -/** - * 实体路径 - */ -@Provide() -@Scope(ScopeEnum.Singleton) -export class CoolEps { - admin = {}; - - app = {}; - - @Inject() - midwayWebRouterService: MidwayWebRouterService; - - @Inject() - typeORMDataSourceManager: TypeORMDataSourceManager; - - // @Init() - async init() { - const entitys = await this.entity(); - const controllers = await this.controller(); - const routers = await this.router(); - const adminArr = []; - const appArr = []; - for (const controller of controllers) { - const { prefix, module, curdOption } = controller; - const name = curdOption?.entity?.name; - (_.startsWith(prefix, "/admin/") ? adminArr : appArr).push({ - module, - api: routers[prefix], - name, - columns: entitys[name] || [], - prefix, - }); - } - this.admin = _.groupBy(adminArr, "module"); - this.app = _.groupBy(appArr, "module"); - } - - /** - * 所有controller - * @returns - */ - async controller() { - const result = []; - const controllers = listModule(CONTROLLER_KEY); - for (const controller of controllers) { - result.push(getClassMetadata(CONTROLLER_KEY, controller)); - } - - return result; - } - - /** - * 所有路由 - * @returns - */ - async router() { - return _.groupBy( - (await await this.midwayWebRouterService.getFlattenRouterTable()).map( - (item) => { - return { - method: item.requestMethod, - path: item.url, - summary: item.summary, - dts: {}, - tag: "", - prefix: item.prefix, - }; - } - ), - "prefix" - ); - } - - /** - * 所有实体 - * @returns - */ - async entity() { - const result = {}; - const dataSourceNames = this.typeORMDataSourceManager.getDataSourceNames(); - for (const dataSourceName of dataSourceNames) { - const entityMetadatas = await this.typeORMDataSourceManager.getDataSource( - dataSourceName - ).entityMetadatas; - for (const entityMetadata of entityMetadatas) { - const commColums = []; - let columns = entityMetadata.columns; - columns = _.filter( - columns.map((e) => { - return { - propertyName: e.propertyName, - type: - typeof e.type == "string" ? e.type : e.type.name.toLowerCase(), - length: e.length, - comment: e.comment, - nullable: e.isNullable, - }; - }), - (o) => { - if (["createTime", "updateTime"].includes(o.propertyName)) { - commColums.push(o); - } - return o && !["createTime", "updateTime"].includes(o.propertyName); - } - ).concat(commColums); - result[entityMetadata.name] = columns; - } - } - return result; - } -} diff --git a/packages/core/src/service/base.ts b/packages/core/src/service/base.ts deleted file mode 100644 index d3cce2c..0000000 --- a/packages/core/src/service/base.ts +++ /dev/null @@ -1,526 +0,0 @@ -import { Init, Provide, Inject, App, Config } from "@midwayjs/decorator"; -import { CoolValidateException } from "../exception/validate"; -import { ERRINFO, EVENT } from "../constant/global"; -import { Application, Context } from "@midwayjs/koa"; -import * as SqlString from "sqlstring"; -import { CoolConfig } from "../interface"; -import { TypeORMDataSourceManager } from "@midwayjs/typeorm"; -import { Brackets, In, Repository, SelectQueryBuilder } from "typeorm"; -import { QueryOp } from "../decorator/controller"; -import * as _ from "lodash"; -import { CoolEventManager } from "../event"; - -/** - * 服务基类 - */ -@Provide() -export abstract class BaseService { - // 分页配置 - @Config("cool") - private _coolConfig: CoolConfig; - - // 模型 - protected entity: Repository; - - protected sqlParams; - - @Inject() - typeORMDataSourceManager: TypeORMDataSourceManager; - - @Inject() - coolEventManager: CoolEventManager; - - // 设置模型 - setEntity(entity: any) { - this.entity = entity; - } - - // 设置请求上下文 - setCtx(ctx: Context) { - this.baseCtx = ctx; - } - - @App() - baseApp: Application; - - // 设置应用对象 - setApp(app: Application) { - this.baseApp = app; - } - - @Inject("ctx") - baseCtx: Context; - - // 初始化 - @Init() - init() { - this.sqlParams = []; - } - - /** - * 设置sql - * @param condition 条件是否成立 - * @param sql sql语句 - * @param params 参数 - */ - setSql(condition, sql, params) { - let rSql = false; - if (condition || (condition === 0 && condition !== "")) { - rSql = true; - this.sqlParams = this.sqlParams.concat(params); - } - return rSql ? sql : ""; - } - - /** - * 获得查询个数的SQL - * @param sql - */ - getCountSql(sql) { - sql = sql - .replace(new RegExp("LIMIT", "gm"), "limit ") - .replace(new RegExp("\n", "gm"), " "); - if (sql.includes("limit")) { - const sqlArr = sql.split("limit "); - sqlArr.pop(); - sql = sqlArr.join("limit "); - } - return `select count(*) as count from (${sql}) a`; - } - - /** - * 参数安全性检查 - * @param params - */ - async paramSafetyCheck(params) { - const lp = params.toLowerCase(); - return !( - lp.indexOf("update ") > -1 || - lp.indexOf("select ") > -1 || - lp.indexOf("delete ") > -1 || - lp.indexOf("insert ") > -1 - ); - } - - /** - * 原生查询 - * @param sql - * @param params - * @param connectionName - */ - async nativeQuery(sql, params?, connectionName?) { - if (_.isEmpty(params)) { - params = this.sqlParams; - } - let newParams = []; - newParams = newParams.concat(params); - this.sqlParams = []; - for (const param of newParams) { - SqlString.escape(param); - } - return await this.getOrmManager(connectionName).query(sql, newParams || []); - } - - /** - * 获得ORM管理 - * @param connectionName 连接名称 - */ - getOrmManager(connectionName = "default") { - return this.typeORMDataSourceManager.getDataSource(connectionName); - } - - /** - * 操作entity获得分页数据,不用写sql - * @param find QueryBuilder - * @param query - * @param autoSort - * @param connectionName - */ - async entityRenderPage( - find: SelectQueryBuilder, - query, - autoSort = true - ) { - const { - size = this._coolConfig.crud.pageSize, - page = 1, - order = "createTime", - sort = "desc", - isExport = false, - maxExportLimit, - } = query; - const count = await find.getCount(); - let dataFind: SelectQueryBuilder; - if (isExport && maxExportLimit > 0) { - dataFind = find.limit(maxExportLimit); - } else { - dataFind = find.offset((page - 1) * size).limit(size); - } - if (autoSort) { - find.addOrderBy(order, sort.toUpperCase()); - } - return { - list: await dataFind.getMany(), - pagination: { - page: parseInt(page), - size: parseInt(size), - total: count, - }, - }; - } - - /** - * 执行SQL并获得分页数据 - * @param sql 执行的sql语句 - * @param query 分页查询条件 - * @param autoSort 是否自动排序 - * @param connectionName 连接名称 - */ - async sqlRenderPage(sql, query, autoSort = true, connectionName?) { - const { - size = this._coolConfig.crud.pageSize, - page = 1, - order = "createTime", - sort = "desc", - isExport = false, - maxExportLimit, - } = query; - if (order && sort && autoSort) { - if (!(await this.paramSafetyCheck(order + sort))) { - throw new CoolValidateException("非法传参~"); - } - sql += ` ORDER BY ${SqlString.escapeId(order)} ${this.checkSort(sort)}`; - } - if (isExport && maxExportLimit > 0) { - this.sqlParams.push(parseInt(maxExportLimit)); - sql += " LIMIT ? "; - } - if (!isExport) { - this.sqlParams.push((page - 1) * size); - this.sqlParams.push(parseInt(size)); - sql += " LIMIT ?,? "; - } - - let params = []; - params = params.concat(this.sqlParams); - const result = await this.nativeQuery(sql, params, connectionName); - const countResult = await this.nativeQuery( - this.getCountSql(sql), - params, - connectionName - ); - return { - list: result, - pagination: { - page: parseInt(page), - size: parseInt(size), - total: parseInt(countResult[0] ? countResult[0].count : 0), - }, - }; - } - - /** - * 检查排序 - * @param sort 排序 - * @returns - */ - private checkSort(sort) { - if (!["desc", "asc"].includes(sort.toLowerCase())) { - throw new CoolValidateException("sort 非法传参~"); - } - return sort; - } - - /** - * 获得单个ID - * @param id ID - * @param infoIgnoreProperty 忽略返回属性 - */ - async info(id: any, infoIgnoreProperty?: string[]) { - if (!this.entity) throw new CoolValidateException(ERRINFO.NOENTITY); - if (!id) { - throw new CoolValidateException(ERRINFO.NOID); - } - const info = await this.entity.findOneBy({ id }); - if (info && infoIgnoreProperty) { - for (const property of infoIgnoreProperty) { - delete info[property]; - } - } - return info; - } - - /** - * 删除 - * @param ids 删除的ID集合 如:[1,2,3] 或者 1,2,3 - */ - async delete(ids: any) { - if (!this.entity) throw new CoolValidateException(ERRINFO.NOENTITY); - await this.modifyBefore(ids, "delete"); - if (ids instanceof String) { - ids = ids.split(","); - } - // 启动软删除发送事件 - if (this._coolConfig.crud?.softDelete) { - this.softDelete(ids); - } - await this.entity.delete(ids); - await this.modifyAfter(ids, "delete"); - } - - /** - * 软删除 - * @param ids 删除的ID数组 - * @param entity 实体 - */ - async softDelete(ids: number[], entity?: Repository) { - const data = await this.entity.find({ - where: { - id: In(ids), - }, - }); - if (_.isEmpty(data)) return; - const _entity = entity ? entity : this.entity; - const params = { - data, - ctx: this.baseCtx, - entity: _entity, - }; - if (data.length > 0) { - this.coolEventManager.emit(EVENT.SOFT_DELETE, params); - } - } - - /** - * 修改 - * @param param 数据 - */ - async update(param: any) { - if (!this.entity) throw new CoolValidateException(ERRINFO.NOENTITY); - await this.modifyBefore(param, "update"); - if (!param.id && !(param instanceof Array)) - throw new CoolValidateException(ERRINFO.NOID); - await this.addOrUpdate(param); - await this.modifyAfter(param, "update"); - } - - /** - * 新增 - * @param param 数据 - */ - async add(param: any | any[]): Promise { - if (!this.entity) throw new CoolValidateException(ERRINFO.NOENTITY); - await this.modifyBefore(param, "add"); - await this.addOrUpdate(param); - await this.modifyAfter(param, "add"); - return { - id: - param instanceof Array - ? param.map((e) => { - return e.id ? e.id : e._id; - }) - : param.id - ? param.id - : param._id, - }; - } - - /** - * 新增|修改 - * @param param 数据 - */ - async addOrUpdate(param: any | any[]) { - if (!this.entity) throw new CoolValidateException(ERRINFO.NOENTITY); - delete param.createTime; - if (param.id) { - param.updateTime = new Date(); - await this.entity.update(param.id, param); - } else { - param.createTime = new Date(); - param.updateTime = new Date(); - await this.entity.insert(param); - } - } - - /** - * 非分页查询 - * @param query 查询条件 - * @param option 查询配置 - * @param connectionName 连接名 - */ - async list(query, option, connectionName?): Promise { - if (!this.entity) throw new CoolValidateException(ERRINFO.NOENTITY); - const sql = await this.getOptionFind(query, option); - return this.nativeQuery(sql, [], connectionName); - } - - /** - * 分页查询 - * @param query 查询条件 - * @param option 查询配置 - * @param connectionName 连接名 - */ - async page(query, option, connectionName?) { - if (!this.entity) throw new CoolValidateException(ERRINFO.NOENTITY); - const sql = await this.getOptionFind(query, option); - return this.sqlRenderPage(sql, query, false, connectionName); - } - - /** - * 构建查询配置 - * @param query 前端查询 - * @param option - */ - private async getOptionFind(query, option: QueryOp) { - let { order = "createTime", sort = "desc", keyWord = "" } = query; - const sqlArr = ["SELECT"]; - const selects = ["a.*"]; - const find = this.entity.createQueryBuilder("a"); - if (option) { - if (typeof option == "function") { - // @ts-ignore - option = await option(this.baseCtx, this.baseApp); - } - // 判断是否有关联查询,有的话取个别名 - if (!_.isEmpty(option.join)) { - for (const item of option.join) { - selects.push(`${item.alias}.*`); - find[item.type || "leftJoin"]( - item.entity, - item.alias, - item.condition - ); - } - } - // 默认条件 - if (option.where) { - const wheres = - typeof option.where == "function" - ? await option.where(this.baseCtx, this.baseApp) - : option.where; - if (!_.isEmpty(wheres)) { - for (const item of wheres) { - if ( - item.length == 2 || - (item.length == 3 && - (item[2] || (item[2] === 0 && item[2] != ""))) - ) { - for (const key in item[1]) { - this.sqlParams.push(item[1][key]); - } - find.andWhere(item[0], item[1]); - } - } - } - } - // 附加排序 - if (!_.isEmpty(option.addOrderBy)) { - for (const key in option.addOrderBy) { - if (order && order == key) { - sort = option.addOrderBy[key].toUpperCase(); - } - find.addOrderBy( - SqlString.escapeId(key), - this.checkSort(option.addOrderBy[key].toUpperCase()) - ); - } - } - // 关键字模糊搜索 - if (keyWord || (keyWord == 0 && keyWord != "")) { - keyWord = `%${keyWord}%`; - find.andWhere( - new Brackets((qb) => { - const keyWordLikeFields = option.keyWordLikeFields; - for (let i = 0; i < option.keyWordLikeFields?.length || 0; i++) { - qb.orWhere(`${keyWordLikeFields[i]} like :keyWord`, { - keyWord, - }); - this.sqlParams.push(keyWord); - } - }) - ); - } - // 筛选字段 - if (!_.isEmpty(option.select)) { - sqlArr.push(option.select.join(",")); - find.select(option.select); - } else { - sqlArr.push(selects.join(",")); - } - // 字段全匹配 - if (!_.isEmpty(option.fieldEq)) { - for (const key of option.fieldEq) { - const c = {}; - // 单表字段无别名的情况下操作 - if (typeof key === "string") { - if (query[key] || (query[key] == 0 && query[key] == "")) { - c[key] = query[key]; - const eq = query[key] instanceof Array ? "in" : "="; - if (eq === "in") { - find.andWhere(`${key} ${eq} (:${key})`, c); - } else { - find.andWhere(`${key} ${eq} :${key}`, c); - } - this.sqlParams.push(query[key]); - } - } else { - if ( - query[key.requestParam] || - (query[key.requestParam] == 0 && query[key.requestParam] !== "") - ) { - c[key.column] = query[key.requestParam]; - const eq = query[key.requestParam] instanceof Array ? "in" : "="; - if (eq === "in") { - find.andWhere(`${key.column} ${eq} (:${key.column})`, c); - } else { - find.andWhere(`${key.column} ${eq} :${key.column}`, c); - } - this.sqlParams.push(query[key.requestParam]); - } - } - } - } - } else { - sqlArr.push(selects.join(",")); - } - // 接口请求的排序 - if (sort && order) { - const sorts = sort.toUpperCase().split(","); - const orders = order.split(","); - if (sorts.length != orders.length) { - throw new CoolValidateException(ERRINFO.SORTFIELD); - } - for (const i in sorts) { - find.addOrderBy( - SqlString.escapeId(orders[i]), - this.checkSort(sorts[i]) - ); - } - } - if (option?.extend) { - await option?.extend(find, this.baseCtx, this.baseApp); - } - const sqls = find.getSql().split("FROM"); - sqlArr.push("FROM"); - sqlArr.push(sqls[1]); - return sqlArr.join(" "); - } - - /** - * 新增|修改|删除 之后的操作 - * @param data 对应数据 - */ - async modifyAfter( - data: any, - type: "delete" | "update" | "add" - ): Promise {} - - /** - * 新增|修改|删除 之前的操作 - * @param data 对应数据 - */ - async modifyBefore( - data: any, - type: "delete" | "update" | "add" - ): Promise {} -} diff --git a/packages/core/src/tag/data.ts b/packages/core/src/tag/data.ts deleted file mode 100644 index 217246b..0000000 --- a/packages/core/src/tag/data.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { CoolUrlTagConfig } from './../decorator/tag'; -import { - CONTROLLER_KEY, - getClassMetadata, - Init, - listModule, - Provide, - Scope, - ScopeEnum, -} from '@midwayjs/decorator'; -import { COOL_URL_TAG_KEY } from '../decorator/tag'; -import * as _ from 'lodash'; - -/** - * URL标签 - */ -@Provide() -@Scope(ScopeEnum.Singleton) -export class CoolUrlTagData { - data = {}; - @Init() - async init() { - const tags = listModule(COOL_URL_TAG_KEY); - for (const controller of tags) { - const controllerOption = getClassMetadata(CONTROLLER_KEY, controller); - const tagOption: CoolUrlTagConfig = getClassMetadata( - COOL_URL_TAG_KEY, - controller - ); - const data: string[] = this.data[tagOption.key] || []; - this.data[tagOption.key] = _.uniq(data.concat( - tagOption.value.map(e => { - return controllerOption.prefix + '/' + e; - })) - ); - } - } - - /** - * 根据键获得 - * @param key - * @returns - */ - byKey(key: string): string[] { - return this.data[key]; - } -} diff --git a/packages/core/src/util/func.ts b/packages/core/src/util/func.ts deleted file mode 100644 index f796bbc..0000000 --- a/packages/core/src/util/func.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { ILogger } from '@midwayjs/core'; -import { Init, Logger, Provide, Scope, ScopeEnum } from '@midwayjs/decorator'; -import * as moment from 'moment'; - -/** - * 常用函数处理 - */ -@Provide() -@Scope(ScopeEnum.Singleton) -export class FuncUtil { - @Logger() - coreLogger: ILogger; - - @Init() - async init() { - Date.prototype.toJSON = function () { - return moment(this).format('YYYY-MM-DD HH:mm:ss'); - }; - // 新增String支持replaceAll方法 - String.prototype['replaceAll'] = function (s1, s2) { - return this.replace(new RegExp(s1, 'gm'), s2); - }; - this.coreLogger.info( - '\x1B[36m [cool:core] midwayjs cool core func handler \x1B[0m' - ); - } -} diff --git a/packages/core/src/util/location.ts b/packages/core/src/util/location.ts deleted file mode 100644 index 5558180..0000000 --- a/packages/core/src/util/location.ts +++ /dev/null @@ -1,95 +0,0 @@ -import { Session } from 'inspector'; -import { v1 as uuid } from 'uuid'; -import * as util from 'util'; - -/** - * Location 工具类 - */ -class LocationUtil { - static instance = null; - - session: Session; - - PREFIX = '__functionLocation__'; - - scripts = {}; - - post$ = null; - - constructor() { - if (!LocationUtil.instance) { - this.init(); - LocationUtil.instance = this; - } - return LocationUtil.instance; - } - - init() { - if (!global[this.PREFIX]) { - global[this.PREFIX] = {}; - } - if (this.session) { - return; - } - this.session = new Session(); - this.session.connect(); - this.post$ = util.promisify(this.session.post).bind(this.session); - this.session.on('Debugger.scriptParsed', res => { - this.scripts[res.params.scriptId] = res.params; - LocationUtil.instance = this; - }); - this.post$('Debugger.enable'); - LocationUtil.instance = this; - } - - /** - * 获得脚本位置 - * @param target - */ - async scriptPath(target: any) { - const id = uuid(); - global[this.PREFIX][id] = target; - const evaluated = await this.post$('Runtime.evaluate', { - expression: `global['${this.PREFIX}']['${id}']`, - objectGroup: this.PREFIX, - }); - const properties = await this.post$('Runtime.getProperties', { - objectId: evaluated.result.objectId, - }); - const location = properties.internalProperties.find( - prop => prop.name === '[[FunctionLocation]]' - ); - const script = this.scripts[location.value.value.scriptId]; - delete global[this.PREFIX][id]; - let source = decodeURI(script.url); - if (!source.startsWith('file://')) { - source = `file://${source}`; - } - return { - column: location.value.value.columnNumber + 1, - line: location.value.value.lineNumber + 1, - path: source.substr(7), - source, - }; - } - - /** - * 清除 - */ - async clean() { - if (this.session) { - await this.post$('Runtime.releaseObjectGroup', { - objectGroup: this.PREFIX, - }); - this.session.disconnect(); - } - - this.session = null; - this.post$ = null; - this.scripts = null; - delete global[this.PREFIX]; - LocationUtil.instance = null; - } -} - -export default new LocationUtil(); diff --git a/packages/core/test/index.test.ts b/packages/core/test/index.test.ts deleted file mode 100644 index a6c75a1..0000000 --- a/packages/core/test/index.test.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { createLightApp } from '@midwayjs/mock'; -import * as custom from '../src'; - -describe('/test/index.test.ts', () => { - it('test component', async () => { - const app = await createLightApp('', { - imports: [ - custom - ] - }); - const bookService = await app.getApplicationContext().getAsync(custom.BookService); - expect(await bookService.getBookById()).toEqual('hello world'); - }); -}); diff --git a/packages/core/tsconfig.json b/packages/core/tsconfig.json deleted file mode 100644 index 9bb4ab7..0000000 --- a/packages/core/tsconfig.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "compileOnSave": true, - "compilerOptions": { - "target": "es2018", - "module": "commonjs", - "moduleResolution": "node", - "experimentalDecorators": true, - "emitDecoratorMetadata": true, - "inlineSourceMap":false, - "noImplicitThis": true, - "noUnusedLocals": true, - "stripInternal": true, - "skipLibCheck": true, - "noImplicitReturns": false, - "pretty": true, - "declaration": true, - "forceConsistentCasingInFileNames": true, - "outDir": "dist" - }, - "exclude": [ - "dist", - "node_modules", - "test" - ] -} diff --git a/packages/es/.editorconfig b/packages/es/.editorconfig deleted file mode 100644 index 4c7f8a8..0000000 --- a/packages/es/.editorconfig +++ /dev/null @@ -1,11 +0,0 @@ -# 🎨 editorconfig.org - -root = true - -[*] -charset = utf-8 -end_of_line = lf -indent_style = space -indent_size = 2 -trim_trailing_whitespace = true -insert_final_newline = true \ No newline at end of file diff --git a/packages/es/.eslintrc.json b/packages/es/.eslintrc.json deleted file mode 100644 index aad9755..0000000 --- a/packages/es/.eslintrc.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "extends": "./node_modules/mwts/", - "ignorePatterns": [ - "node_modules", - "dist", - "test", - "jest.config.js", - "typings", - "public/**/**", - "view/**/**" - ], - "env": { - "jest": true - }, - "rules": { - "@typescript-eslint/explicit-module-boundary-types": "off", - "@typescript-eslint/no-unused-vars": "off", - "@typescript-eslint/ban-ts-comment": "off", - "node/no-extraneous-import": "off", - "no-empty": "off", - "node/no-extraneous-require": "off", - "eqeqeq": "off", - "node/no-unsupported-features/node-builtins": "off", - "@typescript-eslint/ban-types": "off", - "no-control-regex": "off", - "prefer-const": "off" - } -} \ No newline at end of file diff --git a/packages/es/.gitignore b/packages/es/.gitignore deleted file mode 100644 index 13bc3a6..0000000 --- a/packages/es/.gitignore +++ /dev/null @@ -1,15 +0,0 @@ -logs/ -npm-debug.log -yarn-error.log -node_modules/ -package-lock.json -yarn.lock -coverage/ -dist/ -.idea/ -run/ -.DS_Store -*.sw* -*.un~ -.tsbuildinfo -.tsbuildinfo.* diff --git a/packages/es/.prettierrc.js b/packages/es/.prettierrc.js deleted file mode 100644 index b964930..0000000 --- a/packages/es/.prettierrc.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - ...require('mwts/.prettierrc.json') -} diff --git a/packages/es/README.md b/packages/es/README.md deleted file mode 100644 index 610c3db..0000000 --- a/packages/es/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# cool-admin - -https://cool-js.com diff --git a/packages/es/index.d.ts b/packages/es/index.d.ts deleted file mode 100644 index e0065de..0000000 --- a/packages/es/index.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -export * from './dist/index'; - -declare module '@midwayjs/core/dist/interface' { - interface MidwayConfig { - book?: PowerPartial<{ - a: number; - b: string; - }>; - } -} diff --git a/packages/es/jest.config.js b/packages/es/jest.config.js deleted file mode 100644 index 82a8b85..0000000 --- a/packages/es/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - preset: 'ts-jest', - testEnvironment: 'node', - testPathIgnorePatterns: ['/test/fixtures'], - coveragePathIgnorePatterns: ['/test/'], - setupFilesAfterEnv: ['./jest.setup.js'] -}; diff --git a/packages/es/jest.setup.js b/packages/es/jest.setup.js deleted file mode 100644 index 1399c91..0000000 --- a/packages/es/jest.setup.js +++ /dev/null @@ -1 +0,0 @@ -jest.setTimeout(30000); diff --git a/packages/es/package.json b/packages/es/package.json deleted file mode 100644 index 9a5dd36..0000000 --- a/packages/es/package.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "name": "@cool-midway/es", - "version": "6.0.0", - "description": "cool-js.com elasticsearch", - "main": "dist/index.js", - "typings": "index.d.ts", - "scripts": { - "build": "cross-env midway-bin build -c", - "test": "cross-env midway-bin test --ts", - "cov": "cross-env midway-bin cov --ts", - "lint": "mwts check", - "lint:fix": "mwts fix" - }, - "keywords": [ - "cool", - "cool-admin", - "cooljs" - ], - "author": "COOL", - "readme": "README.md", - "files": [ - "dist/**/*.js", - "dist/**/*.d.ts", - "index.d.ts" - ], - "license": "MIT", - "devDependencies": { - "@cool-midway/core": "^6.0.0", - "@midwayjs/cli": "^2.0.9", - "@midwayjs/core": "^3.9.0", - "@midwayjs/decorator": "^3.9.0", - "@midwayjs/mock": "^3.9.0", - "@types/jest": "^29.2.5", - "@types/node": "^18.11.18", - "cross-env": "^7.0.3", - "jest": "^29.3.1", - "mwts": "^1.3.0", - "ts-jest": "^29.0.3", - "typescript": "^4.9.4" - }, - "dependencies": { - "@elastic/elasticsearch": "^8.5.0" - } -} diff --git a/packages/es/src/base.ts b/packages/es/src/base.ts deleted file mode 100644 index b975ddb..0000000 --- a/packages/es/src/base.ts +++ /dev/null @@ -1,569 +0,0 @@ -import { CoolEventManager } from '@cool-midway/core'; -import { Client } from '@elastic/elasticsearch'; -import { WaitForActiveShards } from '@elastic/elasticsearch/lib/api/types'; -import { Inject, Logger } from '@midwayjs/decorator'; -import { ILogger } from '@midwayjs/logger'; -import { EsConfig } from '.'; - -/** - * Es索引基类 - */ -export class BaseEsIndex { - // 索引 - public index: string; - // es客户端 - public client: Client; - // 日志 - @Logger() - coreLogger: ILogger; - // 事件 - @Inject('cool:coolEventManager') - coolEventManager: CoolEventManager; - - /** - * 设置索引 - * @param index - */ - setIndex(index: string) { - this.index = index; - } - - /** - * 处理es数据变更事件,主要用于同步数据 - * @param method - * @param data - */ - async handleDataChange(index, method, data) { - this.index = index; - const { - id, - ids, - bodys, - body, - type, - refresh, - waitForActiveShards, - properties, - config, - } = data; - switch (method) { - case 'upsert': - await this.upsert(body, refresh, waitForActiveShards); - break; - case 'batchIndex': - await this.batchIndex(bodys, type, refresh, waitForActiveShards); - break; - case 'deleteById': - await this.deleteById(id, refresh, waitForActiveShards); - break; - case 'deleteByIds': - await this.deleteByIds(ids, refresh, waitForActiveShards); - break; - case 'deleteByQuery': - await this.deleteByQuery(body, refresh, waitForActiveShards); - break; - case 'updateById': - await this.updateById(body, refresh, waitForActiveShards); - break; - case 'updateByQuery': - await this.updateByQuery(body, refresh, waitForActiveShards); - break; - case 'createIndex': - await this.updateByQuery(properties, config); - break; - } - } - - /** - * 数据更新事件 - * @param method - * @param data - */ - async esDataChange(method, data) { - this.coolEventManager?.emit('esDataChange', this.index, method, data); - } - - /** - * - * @param client - */ - setClient(client: Client) { - this.client = client; - } - - /** - * 查询 - * @param body - */ - async find(body?: any, size?: number) { - if (!body) { - body = {}; - } - body.size = size ? size : 10000; - return this.client - .search({ - index: this.index, - body, - }) - .then(res => { - return ( - res.hits.hits.map(e => { - e._source['id'] = e._id; - const _source: any = e._source; - ['_id', '_index', '_score', '_source'].forEach(key => { - delete e[key]; - }); - return { - ..._source, - ...e, - }; - }) || [] - ); - }); - } - - /** - * 分页查询 - * @param body - * @param page - * @param size - */ - async findPage(body?: any, page?: number, size?: number) { - if (!page) { - page = 1; - } - if (!size) { - size = 20; - } - if (!body) { - body = {}; - } - const total = await this.findCount(body); - body.from = (page - 1) * size; - body.size = size; - return this.client.search({ index: this.index, body }).then(res => { - const result = - res.hits.hits.map(e => { - e._source['id'] = e._id; - const _source: any = e._source; - ['_id', '_index', '_score', '_source'].forEach(key => { - delete e[key]; - }); - return { - ..._source, - ...e, - }; - }) || []; - return { - list: result, - pagination: { - page, - size, - total, - }, - }; - }); - } - - /** - * 根据ID查询 - * @param id - * @returns - */ - async findById(id) { - return this.client - .get({ - index: this.index, - id, - }) - .then(res => { - res._source['id'] = res._id; - return res._source || undefined; - }) - .catch(e => { - return undefined; - }); - } - - /** - * 根据多个ID查询 - * @param ids - * @returns - */ - async findByIds(ids: string[]) { - return this.client - .mget({ index: this.index, body: { ids } }) - .then(res => { - const result = res.docs.map((e: any) => { - e._source.id = e._id; - return e._source || 'undefined'; - }); - return result.filter(e => { - return e !== 'undefined'; - }); - }) - .catch(e => { - return undefined; - }); - } - - /** - * 插入与更新 - * @param body - * @param refresh - * @param waitForActiveShards - * @returns - */ - async upsert( - body: any, - refresh?: boolean | 'wait_for', - waitForActiveShards?: WaitForActiveShards - ) { - if (refresh == undefined) { - refresh = true; - } - if (body.id) { - this.esDataChange('upsert', { - body, - refresh, - waitForActiveShards, - }); - const id = body.id; - delete body.id; - return this.client.index({ - id, - index: this.index, - wait_for_active_shards: waitForActiveShards, - refresh, - body, - }); - } else { - return this.client - .index({ - index: this.index, - wait_for_active_shards: waitForActiveShards, - refresh, - body, - }) - .then(res => { - this.esDataChange('upsert', { - body: { - ...body, - id: res._id, - }, - refresh, - waitForActiveShards, - }); - return res; - }); - } - } - - /** - * 批量插入更新 - * @param bodys - * @param type - * @param refresh - * @param waitForActiveShards - * @returns - */ - async batchIndex( - bodys: any[], - type: 'index' | 'create' | 'delete' | 'update', - refresh?: boolean | 'wait_for', - waitForActiveShards?: WaitForActiveShards - ) { - this.esDataChange('batchIndex', { - bodys, - type, - refresh, - waitForActiveShards, - }); - if (refresh == undefined) { - refresh = true; - } - const list = []; - for (const body of bodys) { - const typeO = {}; - typeO[type] = { _index: this.index, _id: body.id }; - if (body.id) { - delete body.id; - } - list.push(typeO); - if (type !== 'delete') { - if (type == 'update') { - list.push({ doc: body }); - } else { - list.push(body); - } - } - } - return this.client.bulk({ - wait_for_active_shards: waitForActiveShards, - index: this.index, - refresh, - body: list, - }); - } - - /** - * 删除索引 - * @param id - * @param refresh - * @param waitForActiveShards - * @returns - */ - async deleteById( - id, - refresh?: boolean | 'wait_for', - waitForActiveShards?: WaitForActiveShards - ) { - this.esDataChange('deleteById', { - id, - refresh, - waitForActiveShards, - }); - if (refresh == undefined) { - refresh = true; - } - try { - return this.client.delete({ - index: this.index, - refresh, - wait_for_active_shards: waitForActiveShards, - id, - }); - } catch {} - } - - /** - * 删除文档 - * @param ids - * @param refresh - * @param waitForActiveShards - * @returns - */ - async deleteByIds( - ids: string[], - refresh?: boolean, - waitForActiveShards?: WaitForActiveShards - ) { - this.esDataChange('deleteByIds', { - ids, - refresh, - waitForActiveShards, - }); - if (refresh == undefined) { - refresh = true; - } - const body = { - query: { - bool: { - must: [ - { - terms: { - _id: ids, - }, - }, - ], - }, - }, - }; - return this.client.deleteByQuery({ - index: this.index, - refresh, - wait_for_active_shards: waitForActiveShards, - body, - }); - } - - /** - * 根据条件批量删除 - * @param body - * @param refresh - * @param waitForActiveShards - * @returns - */ - async deleteByQuery( - body, - refresh?: boolean, - waitForActiveShards?: WaitForActiveShards - ) { - this.esDataChange('deleteByQuery', { - body, - refresh, - waitForActiveShards, - }); - if (refresh == undefined) { - refresh = true; - } - return this.client.deleteByQuery({ - index: this.index, - refresh, - wait_for_active_shards: waitForActiveShards, - body, - }); - } - - /** - * 更新索引 - * @param body - * @param refresh - * @param waitForActiveShards - * @returns - */ - async updateById( - body, - refresh?: boolean | 'wait_for', - waitForActiveShards?: WaitForActiveShards - ) { - this.esDataChange('updateById', { - body, - refresh, - waitForActiveShards, - }); - if (refresh == undefined) { - refresh = true; - } - const id = body.id; - delete body.id; - return this.client.update({ - wait_for_active_shards: waitForActiveShards, - index: this.index, - id: id, - refresh, - body: { - doc: body, - }, - }); - } - - /** - * 根据条件更新 - * @param body - * @param refresh - * @param waitForActiveShards - */ - async updateByQuery( - body, - refresh?: boolean, - waitForActiveShards?: WaitForActiveShards - ) { - this.esDataChange('updateByQuery', { - body, - refresh, - waitForActiveShards, - }); - if (refresh == undefined) { - refresh = true; - } - return this.client.updateByQuery({ - index: this.index, - refresh, - wait_for_active_shards: waitForActiveShards, - body, - }); - } - - /** - * 查询条数 - * @param body - */ - async findCount(body?: any) { - let _body = Object.assign({}, body || {}); - delete _body.from; - delete _body.size; - delete _body.sort; - return this.client - .count({ - index: this.index, - body: _body, - }) - .then(res => { - return res.count; - }) - .catch(e => { - return undefined; - }); - } - - /** - * 创建更新索引 - * @param config 配置 - */ - async createIndex( - properties: {}, - config: EsConfig = { - name: '', - replicas: 1, - shards: 8, - analyzers: [], - } - ) { - this.esDataChange('createIndex', { - properties, - config, - }); - const body = { - settings: { - number_of_shards: config.shards, - number_of_replicas: config.replicas, - analysis: { - analyzer: { - comma: { type: 'pattern', pattern: ',' }, - blank: { type: 'pattern', pattern: ' ' }, - }, - }, - mapping: { - nested_fields: { - limit: 100, - }, - }, - }, - mappings: { - properties: {}, - }, - }; - if (config.analyzers) { - for (const analyzer of config.analyzers) { - for (const key in analyzer) { - body.settings.analysis.analyzer[key] = analyzer[key]; - } - } - } - const param = { - index: this.index, - body, - }; - param.body = body; - param.body.mappings.properties = properties; - - this.client.indices.exists({ index: this.index }).then(async res => { - if (!res) { - await this.client.indices.create(param).then(res => { - if (res.acknowledged) { - console.info( - '\x1B[36m [cool:core] midwayjs cool elasticsearch ES索引创建成功: ' + - this.index + - ' \x1B[0m' - ); - } - }); - } else { - const updateParam = { - index: this.index, - body: param.body.mappings, - }; - await this.client.indices.putMapping(updateParam).then(res => { - if (res.acknowledged) { - console.info( - '\x1B[36m [cool:core] midwayjs cool elasticsearch ES索引更新成功: ' + - this.index + - ' \x1B[0m' - ); - } - }); - } - }); - } -} diff --git a/packages/es/src/config/config.default.ts b/packages/es/src/config/config.default.ts deleted file mode 100644 index d8324ca..0000000 --- a/packages/es/src/config/config.default.ts +++ /dev/null @@ -1,4 +0,0 @@ -export const customKey = { - a: 1, - b: 'hello', -}; diff --git a/packages/es/src/configuration.ts b/packages/es/src/configuration.ts deleted file mode 100644 index 93d6842..0000000 --- a/packages/es/src/configuration.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Configuration } from '@midwayjs/decorator'; -import * as DefaultConfig from './config/config.default'; -import { IMidwayContainer } from '@midwayjs/core'; -import { CoolElasticSearch } from './elasticsearch'; - -@Configuration({ - namespace: 'cool:es', - importConfigs: [ - { - default: DefaultConfig, - }, - ], -}) -export class CoolEsConfiguration { - async onReady(container: IMidwayContainer) { - await container.getAsync(CoolElasticSearch); - // TODO something - } -} diff --git a/packages/es/src/decorator/elasticsearch.ts b/packages/es/src/decorator/elasticsearch.ts deleted file mode 100644 index 7c89d0f..0000000 --- a/packages/es/src/decorator/elasticsearch.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { - Scope, - ScopeEnum, - saveClassMetadata, - saveModule, -} from '@midwayjs/decorator'; - -export const COOL_ES_KEY = 'decorator:cool:es'; - -export interface EsConfig { - shards?: number; - name: string; - replicas?: number; - analyzers?: any[]; -} - -/** - * 索引 - * @param config - * @returns - */ -export function CoolEsIndex( - config: EsConfig | string = { - name: '', - replicas: 1, - shards: 8, - analyzers: [], - } -): ClassDecorator { - if (typeof config == 'string') { - config = { name: config, replicas: 1, shards: 8, analyzers: [] }; - } - return (target: any) => { - // 将装饰的类,绑定到该装饰器,用于后续能获取到 class - saveModule(COOL_ES_KEY, target); - // 保存一些元数据信息,任意你希望存的东西 - saveClassMetadata(COOL_ES_KEY, config, target); - // 指定 IoC 容器创建实例的作用域,这里注册为请求作用域,这样能取到 ctx - Scope(ScopeEnum.Singleton)(target); - }; -} diff --git a/packages/es/src/elasticsearch.ts b/packages/es/src/elasticsearch.ts deleted file mode 100644 index 6bb32e6..0000000 --- a/packages/es/src/elasticsearch.ts +++ /dev/null @@ -1,154 +0,0 @@ -import { - Provide, - getClassMetadata, - App, - Logger, - Inject, - Init, - Scope, - ScopeEnum, - Config, -} from '@midwayjs/decorator'; -import { COOL_ES_KEY, EsConfig } from './decorator/elasticsearch'; -import { listModule } from '@midwayjs/decorator'; -import { IMidwayApplication } from '@midwayjs/core'; -import { CoolCoreException, CoolEventManager } from '@cool-midway/core'; -import { ILogger } from '@midwayjs/logger'; -import { Client } from '@elastic/elasticsearch'; -import * as _ from 'lodash'; -import { CoolEsConfig, ICoolEs } from '.'; - -/** - * 搜索引擎 - */ -@Provide() -@Scope(ScopeEnum.Singleton) -export class CoolElasticSearch { - @App() - app: IMidwayApplication; - - @Logger() - coreLogger: ILogger; - - @Config('cool.es') - esConfig: CoolEsConfig; - - client: Client; - - @Inject('cool:coolEventManager') - coolEventManager: CoolEventManager; - - @Init() - async init() { - if (!this.esConfig?.nodes) { - throw new CoolCoreException('es.nodes config is require'); - } - if (this.esConfig.nodes.length == 1) { - this.client = new Client({ node: this.esConfig.nodes[0] }); - } else { - this.client = new Client({ nodes: this.esConfig.nodes }); - } - this.client.ping({}, { requestTimeout: 30000 }).then(res => { - if (res) { - this.coolEventManager.emit('esReady', this.client); - this.scan(); - } - }); - } - - async scan() { - const modules = listModule(COOL_ES_KEY); - for (let module of modules) { - const cls: ICoolEs = await this.app - .getApplicationContext() - .getAsync(module); - const data = getClassMetadata(COOL_ES_KEY, module); - this.createIndex(cls, data); - } - } - - /** - * 数据更新事件 - * @param method - * @param data - */ - async esDataChange(method, data) { - //this.coolEventManager.emit('esDataChange', { method, data }); - } - - /** - * 创建索引 - * @param cls - * @param config - */ - async createIndex(cls, config: EsConfig) { - cls.index = config.name; - cls.client = this.client; - const body = { - settings: { - number_of_shards: config.shards, - number_of_replicas: config.replicas, - analysis: { - analyzer: { - comma: { type: 'pattern', pattern: ',' }, - blank: { type: 'pattern', pattern: ' ' }, - }, - }, - mapping: { - nested_fields: { - limit: 100, - }, - }, - }, - mappings: { - properties: {}, - }, - }; - if (config.analyzers) { - for (const analyzer of config.analyzers) { - for (const key in analyzer) { - body.settings.analysis.analyzer[key] = analyzer[key]; - } - } - } - const param = { - index: config.name, - body, - }; - param.body = body; - param.body.mappings.properties = cls.indexInfo(); - - this.esDataChange('createIndex', { - properties: param.body.mappings.properties, - config, - }); - - this.client.indices.exists({ index: config.name }).then(async res => { - if (!res) { - await this.client.indices.create(param).then(res => { - if (res.acknowledged) { - this.coreLogger.info( - '\x1B[36m [cool:core] midwayjs cool elasticsearch ES索引创建成功: ' + - config.name + - ' \x1B[0m' - ); - } - }); - } else { - const updateParam = { - index: config.name, - body: param.body.mappings, - }; - await this.client.indices.putMapping(updateParam).then(res => { - if (res.acknowledged) { - this.coreLogger.info( - '\x1B[36m [cool:core] midwayjs cool elasticsearch ES索引更新成功: ' + - config.name + - ' \x1B[0m' - ); - } - }); - } - }); - } -} diff --git a/packages/es/src/index.ts b/packages/es/src/index.ts deleted file mode 100644 index 438e1a9..0000000 --- a/packages/es/src/index.ts +++ /dev/null @@ -1,15 +0,0 @@ -export { CoolEsConfiguration as Configuration } from './configuration'; - -export * from './elasticsearch'; - -export * from './decorator/elasticsearch'; - -export * from './base'; - -export interface ICoolEs { - indexInfo(): Object; -} - -export interface CoolEsConfig { - nodes: string[]; -} diff --git a/packages/es/src/package.json b/packages/es/src/package.json deleted file mode 100644 index c599b18..0000000 --- a/packages/es/src/package.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "name": "@cool-midway/es", - "version": "6.0.0", - "description": "cool-js.com elasticsearch", - "main": "index.js", - "typings": "index.d.ts", - "scripts": { - "build": "cross-env midway-bin build -c", - "test": "cross-env midway-bin test --ts", - "cov": "cross-env midway-bin cov --ts", - "lint": "mwts check", - "lint:fix": "mwts fix" - }, - "keywords": [], - "author": "", - "files": [ - "**/*.js", - "**/*.d.ts" - ], - "repository": { - "type": "git", - "url": "https://cool-js.com" - }, - "license": "MIT", - "devDependencies": { - "@cool-midway/core": "^6.0.0", - "@midwayjs/cli": "^1.2.38", - "@midwayjs/core": "^3.0.0", - "@midwayjs/decorator": "^3.0.0", - "@midwayjs/mock": "^3.0.0", - "@types/jest": "^27.4.0", - "@types/node": "^16.11.22", - "cross-env": "^6.0.0", - "jest": "^27.5.1", - "mwts": "^1.0.5", - "ts-jest": "^27.1.3", - "typescript": "^4.0.0" - }, - "dependencies": { - "@elastic/elasticsearch": "^8.1.0" - } -} diff --git a/packages/es/test/index.test.ts b/packages/es/test/index.test.ts deleted file mode 100644 index a6c75a1..0000000 --- a/packages/es/test/index.test.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { createLightApp } from '@midwayjs/mock'; -import * as custom from '../src'; - -describe('/test/index.test.ts', () => { - it('test component', async () => { - const app = await createLightApp('', { - imports: [ - custom - ] - }); - const bookService = await app.getApplicationContext().getAsync(custom.BookService); - expect(await bookService.getBookById()).toEqual('hello world'); - }); -}); diff --git a/packages/es/tsconfig.json b/packages/es/tsconfig.json deleted file mode 100644 index f01e1d2..0000000 --- a/packages/es/tsconfig.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "compileOnSave": true, - "compilerOptions": { - "target": "es2018", - "module": "commonjs", - "moduleResolution": "node", - "experimentalDecorators": true, - "emitDecoratorMetadata": true, - "inlineSourceMap":false, - "noImplicitThis": true, - "noUnusedLocals": true, - "stripInternal": true, - "skipLibCheck": true, - "noImplicitReturns": false, - "pretty": true, - "declaration": true, - "outDir": "dist" - }, - "exclude": [ - "dist", - "node_modules", - "test" - ] -} diff --git a/packages/file/.editorconfig b/packages/file/.editorconfig deleted file mode 100644 index 4c7f8a8..0000000 --- a/packages/file/.editorconfig +++ /dev/null @@ -1,11 +0,0 @@ -# 🎨 editorconfig.org - -root = true - -[*] -charset = utf-8 -end_of_line = lf -indent_style = space -indent_size = 2 -trim_trailing_whitespace = true -insert_final_newline = true \ No newline at end of file diff --git a/packages/file/.eslintrc.json b/packages/file/.eslintrc.json deleted file mode 100644 index 93e32bd..0000000 --- a/packages/file/.eslintrc.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "extends": "./node_modules/mwts/", - "ignorePatterns": ["node_modules", "dist", "test", "jest.config.js", "typings"], - "env": { - "jest": true - }, - "rules": { - "@typescript-eslint/explicit-module-boundary-types": "off", - "@typescript-eslint/no-unused-vars": "off", - "@typescript-eslint/ban-ts-comment": "off", - "node/no-extraneous-import": "off", - "no-empty": "off", - "node/no-extraneous-require": "off", - "eqeqeq": "off", - "node/no-unsupported-features/node-builtins": "off", - "@typescript-eslint/ban-types": "off", - "no-control-regex": "off", - "prefer-const": "off" - } -} diff --git a/packages/file/.gitignore b/packages/file/.gitignore deleted file mode 100644 index 13bc3a6..0000000 --- a/packages/file/.gitignore +++ /dev/null @@ -1,15 +0,0 @@ -logs/ -npm-debug.log -yarn-error.log -node_modules/ -package-lock.json -yarn.lock -coverage/ -dist/ -.idea/ -run/ -.DS_Store -*.sw* -*.un~ -.tsbuildinfo -.tsbuildinfo.* diff --git a/packages/file/.prettierrc.js b/packages/file/.prettierrc.js deleted file mode 100644 index b964930..0000000 --- a/packages/file/.prettierrc.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - ...require('mwts/.prettierrc.json') -} diff --git a/packages/file/LICENSE b/packages/file/LICENSE deleted file mode 100644 index 5a739ee..0000000 --- a/packages/file/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2013 - Now midwayjs - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/packages/file/index.d.ts b/packages/file/index.d.ts deleted file mode 100644 index e0065de..0000000 --- a/packages/file/index.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -export * from './dist/index'; - -declare module '@midwayjs/core/dist/interface' { - interface MidwayConfig { - book?: PowerPartial<{ - a: number; - b: string; - }>; - } -} diff --git a/packages/file/jest.config.js b/packages/file/jest.config.js deleted file mode 100644 index 82a8b85..0000000 --- a/packages/file/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - preset: 'ts-jest', - testEnvironment: 'node', - testPathIgnorePatterns: ['/test/fixtures'], - coveragePathIgnorePatterns: ['/test/'], - setupFilesAfterEnv: ['./jest.setup.js'] -}; diff --git a/packages/file/jest.setup.js b/packages/file/jest.setup.js deleted file mode 100644 index 1399c91..0000000 --- a/packages/file/jest.setup.js +++ /dev/null @@ -1 +0,0 @@ -jest.setTimeout(30000); diff --git a/packages/file/package.json b/packages/file/package.json deleted file mode 100644 index 38f3e3e..0000000 --- a/packages/file/package.json +++ /dev/null @@ -1,53 +0,0 @@ -{ - "name": "@cool-midway/file", - "version": "6.0.3", - "description": "", - "main": "dist/index.js", - "typings": "index.d.ts", - "scripts": { - "build": "cross-env midway-bin build -c", - "test": "cross-env midway-bin test --ts", - "cov": "cross-env midway-bin cov --ts", - "lint": "mwts check", - "lint:fix": "mwts fix" - }, - "keywords": [ - "cool", - "cool-admin", - "cooljs" - ], - "author": "COOL", - "files": [ - "dist/**/*.js", - "dist/**/*.d.ts", - "index.d.ts" - ], - "license": "MIT", - "repository": { - "type": "git", - "url": "https://cool-js.com" - }, - "devDependencies": { - "@cool-midway/core": "^6.0.0", - "@midwayjs/cli": "^2.0.9", - "@midwayjs/core": "^3.9.0", - "@midwayjs/decorator": "^3.9.0", - "@midwayjs/mock": "^3.9.0", - "@types/jest": "^29.2.5", - "@types/node": "^18.11.18", - "cross-env": "^7.0.3", - "jest": "^29.3.1", - "lodash": "^4.17.21", - "mwts": "^1.3.0", - "ts-jest": "^29.0.3", - "typescript": "^4.9.4" - }, - "dependencies": { - "@midwayjs/upload": "^3.9.9", - "ali-oss": "^6.17.1", - "cos-nodejs-sdk-v5": "^2.11.19", - "download": "^8.0.0", - "qcloud-cos-sts": "^3.1.0", - "qiniu": "^7.8.0" - } -} diff --git a/packages/file/src/config/config.default.ts b/packages/file/src/config/config.default.ts deleted file mode 100644 index 9b0cf96..0000000 --- a/packages/file/src/config/config.default.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { CoolFileConfig } from './../interface'; -import { MODETYPE } from '../interface'; - -/** - * cool的配置 - */ -export default { - cool: { - file: { - // 上传模式 - mode: MODETYPE.LOCAL, - // 文件路径前缀 本地上传模式下 有效 - domain: 'http://127.0.0.1:8001', - } as CoolFileConfig, - }, -}; diff --git a/packages/file/src/configuration.ts b/packages/file/src/configuration.ts deleted file mode 100644 index e4ef4ba..0000000 --- a/packages/file/src/configuration.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Configuration } from '@midwayjs/decorator'; -import * as DefaultConfig from './config/config.default'; -import * as upload from '@midwayjs/upload'; -import { IMidwayContainer } from '@midwayjs/core'; -import { CoolFile } from './file'; - -@Configuration({ - namespace: 'cool:file', - importConfigs: [ - { - default: DefaultConfig, - }, - ], - imports: [upload], -}) -export class CoolFileConfiguration { - async onReady(container: IMidwayContainer) { - await container.getAsync(CoolFile); - // TODO something - } -} diff --git a/packages/file/src/file.ts b/packages/file/src/file.ts deleted file mode 100644 index 720654d..0000000 --- a/packages/file/src/file.ts +++ /dev/null @@ -1,476 +0,0 @@ -import { - App, - Config, - Init, - Logger, - Provide, - Scope, - ScopeEnum, -} from '@midwayjs/decorator'; -import { Mode, CoolFileConfig, MODETYPE, CLOUDTYPE } from './interface'; -import { CoolCommException } from '@cool-midway/core'; -import * as moment from 'moment'; -import { v1 as uuid } from 'uuid'; -import * as path from 'path'; -import * as fs from 'fs'; -import { ILogger, IMidwayApplication } from '@midwayjs/core'; -import * as _ from 'lodash'; -import * as OSS from 'ali-oss'; -import * as crypto from 'crypto'; -import * as STS from 'qcloud-cos-sts'; -import * as download from 'download'; -import * as COS from 'cos-nodejs-sdk-v5'; -import * as QINIU from 'qiniu'; - -/** - * 文件上传 - */ -@Provide() -@Scope(ScopeEnum.Singleton) -export class CoolFile { - @Config('cool.file') - config: CoolFileConfig; - - @Logger() - coreLogger: ILogger; - - client: OSS & COS & QINIU.auth.digest.Mac; - - @App() - app: IMidwayApplication; - - @Init() - async init(config: CoolFileConfig) { - const filePath = path.join(this.app.getBaseDir(), '..', 'public'); - const uploadsPath = path.join(filePath, 'uploads'); - const tempPath = path.join(filePath, 'temp'); - if (!fs.existsSync(uploadsPath)) { - fs.mkdirSync(uploadsPath); - } - if (!fs.existsSync(tempPath)) { - fs.mkdirSync(tempPath); - } - if (config) { - this.config = config; - } - const { mode, oss, cos, qiniu } = this.config; - if (mode == MODETYPE.CLOUD) { - if (oss) { - const { accessKeyId, accessKeySecret, bucket, endpoint } = oss; - this.client = new OSS({ - region: endpoint.split('.')[0], - accessKeyId, - accessKeySecret, - bucket, - }); - } - if (cos) { - const { accessKeyId, accessKeySecret } = cos; - this.client = new COS({ - SecretId: accessKeyId, - SecretKey: accessKeySecret, - }); - } - if (qiniu) { - const { accessKeyId, accessKeySecret } = qiniu; - this.client = new QINIU.auth.digest.Mac(accessKeyId, accessKeySecret); - } - } - } - - /** - * 上传模式 - * @returns 上传模式 - */ - async getMode(): Promise { - const { mode, oss, cos, qiniu } = this.config; - if (mode == MODETYPE.LOCAL) { - return { - mode: MODETYPE.LOCAL, - type: MODETYPE.LOCAL, - }; - } - if (oss) { - return { - mode: MODETYPE.CLOUD, - type: CLOUDTYPE.OSS, - }; - } - if (cos) { - return { - mode: MODETYPE.CLOUD, - type: CLOUDTYPE.COS, - }; - } - if (qiniu) { - return { - mode: MODETYPE.CLOUD, - type: CLOUDTYPE.QINIU, - }; - } - } - - /** - * 获得原始操作对象 - * @returns - */ - getMetaFileObj(): OSS & COS & QINIU.auth.digest.Mac { - return this.client; - } - - /** - * 下载并上传 - * @param url - * @param fileName 文件名 - */ - async downAndUpload(url: string, fileName?: string) { - const { mode, oss, cos, qiniu, domain } = this.config; - let extend = ''; - if (url.includes('.')) { - const urlArr = url.split('.'); - extend = '.' + urlArr[urlArr.length - 1].split('?')[0]; - } - - const data = url.includes('http') - ? await download(url) - : fs.readFileSync(url); - - const isCloud = mode == MODETYPE.CLOUD; - // 创建文件夹 - const dirPath = path.join( - this.app.getBaseDir(), - '..', - `public/${isCloud ? 'temp' : 'uploads'}/${moment().format('YYYYMMDD')}` - ); - if (!fs.existsSync(dirPath)) { - fs.mkdirSync(dirPath); - } - const uuidStr = uuid(); - const name = `uploads/${moment().format('YYYYMMDD')}/${ - fileName ? fileName : uuidStr + extend - }`; - if (isCloud) { - if (oss) { - const ossClient: OSS = this.getMetaFileObj(); - return (await ossClient.put(name, data)).url; - } - if (cos) { - const cosClient: COS = this.getMetaFileObj(); - await cosClient.putObject({ - Bucket: cos.bucket, - Region: cos.region, - Key: name, - Body: data, - }); - return cos.publicDomain + '/' + name; - } - if (qiniu) { - let uploadToken = (await this.qiniu())['token']; - const formUploader = new QINIU.form_up.FormUploader(); - const putExtra = new QINIU.form_up.PutExtra(); - return new Promise((resolve, reject) => { - formUploader.put( - uploadToken, - name, - data, - putExtra, - (respErr, respBody, respInfo) => { - if (respErr) { - throw respErr; - } - if (respInfo.statusCode == 200) { - resolve(qiniu.publicDomain + '/' + name); - } - } - ); - }); - } - } else { - fs.writeFileSync( - `${dirPath}/${fileName ? fileName : uuidStr + extend}`, - data - ); - return `${domain}/public/${name}`; - } - } - - /** - * 指定Key(路径)上传 - * @param file - * @param key 路径一致会覆盖源文件 - */ - async uploadWithKey(file, key) { - const { mode, oss, cos, qiniu } = this.config; - const data = fs.readFileSync(file.data); - if (mode == MODETYPE.LOCAL) { - fs.writeFileSync(path.join(this.app.getBaseDir(), '..', key), data); - return this.config.domain + key; - } - if (mode == MODETYPE.CLOUD) { - if (oss) { - const ossClient: OSS = this.getMetaFileObj(); - return (await ossClient.put(key, data)).url; - } - if (cos) { - const cosClient: COS = this.getMetaFileObj(); - await cosClient.putObject({ - Bucket: cos.bucket, - Region: cos.region, - Key: key, - Body: data, - }); - return cos.publicDomain + '/' + key; - } - if (qiniu) { - let uploadToken = (await this.qiniu())['token']; - const formUploader = new QINIU.form_up.FormUploader(); - const putExtra = new QINIU.form_up.PutExtra(); - return new Promise((resolve, reject) => { - formUploader.put( - uploadToken, - key, - data, - putExtra, - (respErr, respBody, respInfo) => { - if (respErr) { - throw respErr; - } - if (respInfo.statusCode == 200) { - resolve(qiniu.publicDomain + '/' + key); - } - } - ); - }); - } - } - } - - /** - * 上传文件 - * @param ctx - * @param key 文件路径 - */ - async upload(ctx) { - const { mode, oss, cos, qiniu } = this.config; - if (mode == MODETYPE.LOCAL) { - return await this.local(ctx); - } - if (mode == MODETYPE.CLOUD) { - if (oss) { - return await this.oss(ctx); - } - if (cos) { - return await this.cos(ctx); - } - if (qiniu) { - return await this.qiniu(ctx); - } - } - } - - /** - * 七牛上传 - * @param ctx - * @returns - */ - private async qiniu(ctx?) { - const { - bucket, - publicDomain, - region, - uploadUrl = `https://upload-${region}.qiniup.com/`, - fileKey = 'file', - } = this.config.qiniu; - let options = { - scope: bucket, - }; - const putPolicy = new QINIU.rs.PutPolicy(options); - const uploadToken = putPolicy.uploadToken(this.client); - return new Promise((resolve, reject) => { - resolve({ - uploadUrl, - publicDomain, - token: uploadToken, - fileKey, - }); - }); - } - - /** - * OSS 文件上传 - * @param ctx - */ - private async oss(ctx) { - const { - accessKeyId, - accessKeySecret, - bucket, - endpoint, - expAfter = 300000, - maxSize = 200 * 1024 * 1024, - host, - } = this.config.oss; - const oss = { - bucket, - region: endpoint.split('.')[0], // 我的是 hangzhou - accessKeyId, - accessKeySecret, - expAfter, // 签名失效时间,毫秒 - maxSize, // 文件最大的 size - }; - const newHost = host ? host : `https://${bucket}.${endpoint}`; - const expireTime = new Date().getTime() + oss.expAfter; - const expiration = new Date(expireTime).toISOString(); - const policyString = JSON.stringify({ - expiration, - conditions: [ - ['content-length-range', 0, oss.maxSize], // 设置上传文件的大小限制,200mb - ], - }); - const policy = Buffer.from(policyString).toString('base64'); - - const signature = crypto - .createHmac('sha1', oss.accessKeySecret) - .update(policy) - .digest('base64'); - - return { - signature, - policy, - host: newHost, - OSSAccessKeyId: accessKeyId, - success_action_status: 200, - }; - } - - /** - * COS 文件上传 - * @param ctx - */ - private async cos(ctx) { - const { - accessKeyId, - accessKeySecret, - bucket, - region, - publicDomain, - durationSeconds = 1800, - allowPrefix = '_ALLOW_DIR_/*', - allowActions = [ - // 所有 action 请看文档 https://cloud.tencent.com/document/product/436/31923 - // 简单上传 - 'name/cos:PutObject', - 'name/cos:PostObject', - // 分片上传 - 'name/cos:InitiateMultipartUpload', - 'name/cos:ListMultipartUploads', - 'name/cos:ListParts', - 'name/cos:UploadPart', - 'name/cos:CompleteMultipartUpload', - ], - } = this.config.cos; - // 配置参数 - let config = { - secretId: accessKeyId, - secretKey: accessKeySecret, - durationSeconds, - bucket: bucket, - region: region, - // 允许操作(上传)的对象前缀,可以根据自己网站的用户登录态判断允许上传的目录,例子: user1/* 或者 * 或者a.jpg - // 请注意当使用 * 时,可能存在安全风险,详情请参阅:https://cloud.tencent.com/document/product/436/40265 - allowPrefix, - // 密钥的权限列表 - allowActions, - }; - - // 获取临时密钥 - let LongBucketName = config.bucket; - let ShortBucketName = LongBucketName.substring( - 0, - LongBucketName.lastIndexOf('-') - ); - let AppId = LongBucketName.substring(LongBucketName.lastIndexOf('-') + 1); - - let policy = { - version: '2.0', - statement: [ - { - action: config.allowActions, - effect: 'allow', - resource: [ - 'qcs::cos:' + - config.region + - ':uid/' + - AppId + - ':prefix//' + - AppId + - '/' + - ShortBucketName + - '/' + - config.allowPrefix, - ], - }, - ], - }; - - return new Promise((resolve, reject) => { - STS.getCredential( - { - secretId: config.secretId, - secretKey: config.secretKey, - durationSeconds: config.durationSeconds, - policy: policy, - }, - (err, tempKeys) => { - if (err) { - reject(err); - } - if (tempKeys) { - tempKeys.startTime = Math.round(Date.now() / 1000); - } - resolve({ - ...tempKeys, - url: publicDomain, - }); - } - ); - }); - } - - /** - * 本地上传 - * @param ctx - * @returns - */ - private async local(ctx) { - try { - const { key } = ctx.fields; - if (_.isEmpty(ctx.files)) { - throw new CoolCommException('上传文件为空'); - } - const file = ctx.files[0]; - const extension = file.filename.split('.').pop(); - const name = - moment().format('YYYYMMDD') + '/' + (key || `${uuid()}.${extension}`); - const target = path.join( - this.app.getBaseDir(), - '..', - `public/uploads/${name}` - ); - const dirPath = path.join( - this.app.getBaseDir(), - '..', - `public/uploads/${moment().format('YYYYMMDD')}` - ); - if (!fs.existsSync(dirPath)) { - fs.mkdirSync(dirPath); - } - const data = fs.readFileSync(file.data); - fs.writeFileSync(target, data); - return this.config.domain + '/public/uploads/' + name; - } catch (err) { - this.coreLogger.error(err); - throw new CoolCommException('上传失败'); - } - } -} diff --git a/packages/file/src/index.ts b/packages/file/src/index.ts deleted file mode 100644 index 5a58056..0000000 --- a/packages/file/src/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export { CoolFileConfiguration as Configuration } from './configuration'; - -export * from './interface'; - -export * from './file'; diff --git a/packages/file/src/interface.ts b/packages/file/src/interface.ts deleted file mode 100644 index db332ae..0000000 --- a/packages/file/src/interface.ts +++ /dev/null @@ -1,105 +0,0 @@ -// 模式 -export enum MODETYPE { - // 本地 - LOCAL = 'local', - // 云存储 - CLOUD = 'cloud', - // 其他 - OTHER = 'other', -} - -export enum CLOUDTYPE { - // 阿里云存储 - OSS = 'oss', - // 腾讯云存储 - COS = 'cos', - // 七牛云存储 - QINIU = 'qiniu', -} - -/** - * 上传模式 - */ -export interface Mode { - // 模式 - mode: MODETYPE; - // 类型 - type: string; -} - -/** - * 模块配置 - */ -export interface CoolFileConfig { - // 上传模式 - mode: MODETYPE; - // 阿里云oss 配置 - oss: OSSConfig; - // 腾讯云 cos配置 - cos: COSConfig; - // 七牛云 配置 - qiniu: QINIUConfig; - // 文件前缀 - domain: string; -} - -/** - * OSS 配置 - */ -export interface OSSConfig { - // 阿里云accessKeyId - accessKeyId: string; - // 阿里云accessKeySecret - accessKeySecret: string; - // 阿里云oss的bucket - bucket: string; - // 阿里云oss的endpoint - endpoint: string; - // 阿里云oss的timeout - timeout: string; - // 签名失效时间,毫秒 - expAfter?: number; - // 文件最大的 size - maxSize?: number; - // host - host?: string; -} - -/** - * COS 配置 - */ -export interface COSConfig { - // 腾讯云accessKeyId - accessKeyId: string; - // 腾讯云accessKeySecret - accessKeySecret: string; - // 腾讯云cos的bucket - bucket: string; - // 腾讯云cos的区域 - region: string; - // 腾讯云cos的公网访问地址 - publicDomain: string; - // 上传持续时间 - durationSeconds?: number; - // 允许操作(上传)的对象前缀 - allowPrefix?: string; - // 密钥的权限列表 - allowActions?: string[]; -} - -export interface QINIUConfig { - // 七牛云accessKeyId - accessKeyId: string; - // 七牛云accessKeySecret - accessKeySecret: string; - // 七牛云cos的bucket - bucket: string; - // 七牛云cos的区域 - region: string; - // 七牛云cos的公网访问地址 - publicDomain: string; - // 上传地址 - uploadUrl?: string; - // 上传fileKey - fileKey?: string; -} diff --git a/packages/file/src/package.json b/packages/file/src/package.json deleted file mode 100644 index b1e69e6..0000000 --- a/packages/file/src/package.json +++ /dev/null @@ -1,53 +0,0 @@ -{ - "name": "@cool-midway/file", - "version": "6.0.3", - "description": "", - "main": "index.js", - "typings": "index.d.ts", - "scripts": { - "build": "cross-env midway-bin build -c", - "test": "cross-env midway-bin test --ts", - "cov": "cross-env midway-bin cov --ts", - "lint": "mwts check", - "lint:fix": "mwts fix" - }, - "keywords": [ - "cool", - "cool-admin", - "cooljs" - ], - "author": "COOL", - "files": [ - "**/*.js", - "**/*.d.ts", - "index.d.ts" - ], - "license": "MIT", - "repository": { - "type": "git", - "url": "https://cool-js.com" - }, - "devDependencies": { - "@cool-midway/core": "^6.0.0", - "@midwayjs/cli": "^2.0.9", - "@midwayjs/core": "^3.9.0", - "@midwayjs/decorator": "^3.9.0", - "@midwayjs/mock": "^3.9.0", - "@types/jest": "^29.2.5", - "@types/node": "^18.11.18", - "cross-env": "^7.0.3", - "jest": "^29.3.1", - "lodash": "^4.17.21", - "mwts": "^1.3.0", - "ts-jest": "^29.0.3", - "typescript": "^4.9.4" - }, - "dependencies": { - "@midwayjs/upload": "^3.9.1", - "ali-oss": "^6.17.1", - "cos-nodejs-sdk-v5": "^2.11.19", - "download": "^8.0.0", - "qcloud-cos-sts": "^3.1.0", - "qiniu": "^7.8.0" - } -} diff --git a/packages/file/test/index.test.ts b/packages/file/test/index.test.ts deleted file mode 100644 index a6c75a1..0000000 --- a/packages/file/test/index.test.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { createLightApp } from '@midwayjs/mock'; -import * as custom from '../src'; - -describe('/test/index.test.ts', () => { - it('test component', async () => { - const app = await createLightApp('', { - imports: [ - custom - ] - }); - const bookService = await app.getApplicationContext().getAsync(custom.BookService); - expect(await bookService.getBookById()).toEqual('hello world'); - }); -}); diff --git a/packages/file/tsconfig.json b/packages/file/tsconfig.json deleted file mode 100644 index 9bb4ab7..0000000 --- a/packages/file/tsconfig.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "compileOnSave": true, - "compilerOptions": { - "target": "es2018", - "module": "commonjs", - "moduleResolution": "node", - "experimentalDecorators": true, - "emitDecoratorMetadata": true, - "inlineSourceMap":false, - "noImplicitThis": true, - "noUnusedLocals": true, - "stripInternal": true, - "skipLibCheck": true, - "noImplicitReturns": false, - "pretty": true, - "declaration": true, - "forceConsistentCasingInFileNames": true, - "outDir": "dist" - }, - "exclude": [ - "dist", - "node_modules", - "test" - ] -} diff --git a/packages/iot/.editorconfig b/packages/iot/.editorconfig deleted file mode 100644 index 4c7f8a8..0000000 --- a/packages/iot/.editorconfig +++ /dev/null @@ -1,11 +0,0 @@ -# 🎨 editorconfig.org - -root = true - -[*] -charset = utf-8 -end_of_line = lf -indent_style = space -indent_size = 2 -trim_trailing_whitespace = true -insert_final_newline = true \ No newline at end of file diff --git a/packages/iot/.eslintrc.json b/packages/iot/.eslintrc.json deleted file mode 100644 index aad9755..0000000 --- a/packages/iot/.eslintrc.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "extends": "./node_modules/mwts/", - "ignorePatterns": [ - "node_modules", - "dist", - "test", - "jest.config.js", - "typings", - "public/**/**", - "view/**/**" - ], - "env": { - "jest": true - }, - "rules": { - "@typescript-eslint/explicit-module-boundary-types": "off", - "@typescript-eslint/no-unused-vars": "off", - "@typescript-eslint/ban-ts-comment": "off", - "node/no-extraneous-import": "off", - "no-empty": "off", - "node/no-extraneous-require": "off", - "eqeqeq": "off", - "node/no-unsupported-features/node-builtins": "off", - "@typescript-eslint/ban-types": "off", - "no-control-regex": "off", - "prefer-const": "off" - } -} \ No newline at end of file diff --git a/packages/iot/.gitignore b/packages/iot/.gitignore deleted file mode 100644 index 13bc3a6..0000000 --- a/packages/iot/.gitignore +++ /dev/null @@ -1,15 +0,0 @@ -logs/ -npm-debug.log -yarn-error.log -node_modules/ -package-lock.json -yarn.lock -coverage/ -dist/ -.idea/ -run/ -.DS_Store -*.sw* -*.un~ -.tsbuildinfo -.tsbuildinfo.* diff --git a/packages/iot/.prettierrc.js b/packages/iot/.prettierrc.js deleted file mode 100644 index b964930..0000000 --- a/packages/iot/.prettierrc.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - ...require('mwts/.prettierrc.json') -} diff --git a/packages/iot/README.md b/packages/iot/README.md deleted file mode 100644 index 610c3db..0000000 --- a/packages/iot/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# cool-admin - -https://cool-js.com diff --git a/packages/iot/index.d.ts b/packages/iot/index.d.ts deleted file mode 100644 index e0065de..0000000 --- a/packages/iot/index.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -export * from './dist/index'; - -declare module '@midwayjs/core/dist/interface' { - interface MidwayConfig { - book?: PowerPartial<{ - a: number; - b: string; - }>; - } -} diff --git a/packages/iot/jest.config.js b/packages/iot/jest.config.js deleted file mode 100644 index 82a8b85..0000000 --- a/packages/iot/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - preset: 'ts-jest', - testEnvironment: 'node', - testPathIgnorePatterns: ['/test/fixtures'], - coveragePathIgnorePatterns: ['/test/'], - setupFilesAfterEnv: ['./jest.setup.js'] -}; diff --git a/packages/iot/jest.setup.js b/packages/iot/jest.setup.js deleted file mode 100644 index 1399c91..0000000 --- a/packages/iot/jest.setup.js +++ /dev/null @@ -1 +0,0 @@ -jest.setTimeout(30000); diff --git a/packages/iot/package.json b/packages/iot/package.json deleted file mode 100644 index 299377c..0000000 --- a/packages/iot/package.json +++ /dev/null @@ -1,53 +0,0 @@ -{ - "name": "@cool-midway/iot", - "version": "6.0.0", - "description": "cool-js.com iot模块", - "main": "dist/index.js", - "typings": "index.d.ts", - "scripts": { - "build": "cross-env midway-bin build -c", - "test": "cross-env midway-bin test --ts", - "cov": "cross-env midway-bin cov --ts", - "lint": "mwts check", - "lint:fix": "mwts fix" - }, - "keywords": [ - "cool", - "cool-admin", - "cooljs", - "cool-iot", - "iot" - ], - "author": "COOL", - "readme": "README.md", - "license": "MIT", - "repository": { - "type": "git", - "url": "https://cool-js.com" - }, - "files": [ - "dist/**/*.js", - "dist/**/*.d.ts", - "index.d.ts" - ], - "devDependencies": { - "@cool-midway/core": "6.0.0", - "@midwayjs/cli": "^2.0.9", - "@midwayjs/core": "^3.9.0", - "@midwayjs/decorator": "^3.9.0", - "@midwayjs/mock": "^3.9.0", - "@types/jest": "^29.2.5", - "@types/node": "^18.11.18", - "cross-env": "^7.0.3", - "jest": "^29.3.1", - "mwts": "^1.3.0", - "ts-jest": "^29.0.3", - "typescript": "^4.9.4" - }, - "dependencies": { - "@cool-midway/mqemitter-redis": "^6.0.0", - "aedes": "^0.48.1", - "aedes-persistence-redis": "^9.0.2", - "aedes-server-factory": "^0.2.1" - } -} diff --git a/packages/iot/src/config/config.default.ts b/packages/iot/src/config/config.default.ts deleted file mode 100644 index ee625da..0000000 --- a/packages/iot/src/config/config.default.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { CoolIotConfig } from '../interface'; - -/** - * cool的配置 - */ -export default { - cool: { - iot: { - port: 1883, - wsPort: 8083, - } as CoolIotConfig, - }, -}; diff --git a/packages/iot/src/configuration.ts b/packages/iot/src/configuration.ts deleted file mode 100644 index ecb17aa..0000000 --- a/packages/iot/src/configuration.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { CoolMqttServe } from './mqtt'; -import { Configuration } from '@midwayjs/decorator'; -import * as DefaultConfig from './config/config.default'; -import { IMidwayContainer } from '@midwayjs/core'; - -@Configuration({ - namespace: 'cool:iot', - importConfigs: [ - { - default: DefaultConfig, - }, - ], -}) -export class CoolIotConfiguration { - async onReady(container: IMidwayContainer) { - (await container.getAsync(CoolMqttServe)).init(); - } -} diff --git a/packages/iot/src/decorator/mqtt.ts b/packages/iot/src/decorator/mqtt.ts deleted file mode 100644 index 8feb4f6..0000000 --- a/packages/iot/src/decorator/mqtt.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { - Scope, - ScopeEnum, - saveClassMetadata, - saveModule, - attachClassMetadata, -} from '@midwayjs/core'; - -export const COOL_MQTT_KEY = 'decorator:cool:cls:mqtt'; - -export function CoolMqtt(): ClassDecorator { - return (target: any) => { - // 将装饰的类,绑定到该装饰器,用于后续能获取到 class - saveModule(COOL_MQTT_KEY, target); - // 保存一些元数据信息,任意你希望存的东西 - saveClassMetadata(COOL_MQTT_KEY, {}, target); - // 指定 IoC 容器创建实例的作用域,这里注册为请求作用域,这样能取到 ctx - Scope(ScopeEnum.Singleton)(target); - }; -} - -export const COOL_MQTT_EVENT_KEY = 'decorator:cool:mqtt:event'; - -/** - * 事件 - * @param eventName - * @returns - */ -export function CoolMqttEvent(eventName?: string): MethodDecorator { - return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => { - // 将装饰的类,绑定到该装饰器,用于后续能获取到 class - attachClassMetadata( - COOL_MQTT_EVENT_KEY, - { - eventName, - propertyKey, - descriptor, - }, - target - ); - }; -} diff --git a/packages/iot/src/index.ts b/packages/iot/src/index.ts deleted file mode 100644 index e827cde..0000000 --- a/packages/iot/src/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -export { CoolIotConfiguration as Configuration } from './configuration'; - -export * from './decorator/mqtt'; - -export * from './mqtt'; - -export * from './interface'; diff --git a/packages/iot/src/interface.ts b/packages/iot/src/interface.ts deleted file mode 100644 index ca033f1..0000000 --- a/packages/iot/src/interface.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { AedesOptions } from 'aedes'; -import { PublishPacket } from 'packet'; - -/** - * MQTT配置 - */ -export interface CoolIotConfig { - /** MQTT服务端口 */ - port: number; - /** MQTT Websocket服务端口 */ - wsPort: number; - /** redis 配置 mqtt cluster下必须要配置 */ - redis?: { - /** host */ - host: string; - /** port */ - port: number; - /** password */ - password: string; - /** db */ - db: number; - }; - /** 发布消息配置 */ - publish?: PublishPacket; - /** 认证 */ - auth?: { - /** 用户 */ - username: string; - /** 密码 */ - password: string; - }; - /** 服务配置 */ - serve?: AedesOptions; -} diff --git a/packages/iot/src/mqtt.ts b/packages/iot/src/mqtt.ts deleted file mode 100644 index 7fade44..0000000 --- a/packages/iot/src/mqtt.ts +++ /dev/null @@ -1,163 +0,0 @@ -import { CoolIotConfig } from './interface'; -import { - App, - Config, - getClassMetadata, - ILogger, - IMidwayApplication, - listModule, - Logger, - Provide, - Scope, - ScopeEnum, -} from '@midwayjs/core'; -import { COOL_MQTT_EVENT_KEY, COOL_MQTT_KEY } from './decorator/mqtt'; -import Aedes, { AedesOptions } from 'aedes'; -import { randomUUID } from 'crypto'; - -/** - * MQTT服务 - */ -@Provide() -@Scope(ScopeEnum.Singleton) -export class CoolMqttServe { - @Config('cool.iot') - coolIotConfig: CoolIotConfig; - - @Logger() - coreLogger: ILogger; - - serve: Aedes; - - @App() - app: IMidwayApplication; - - async init() { - await this.initServe(); - await this.handlerCls(); - await this.startServe(); - } - - /** - * 开启服务 - */ - async startServe() { - const { port, wsPort } = this.coolIotConfig; - const { createServer } = require('aedes-server-factory'); - const server = createServer(this.serve); - - const serverWs = createServer(this.serve, { ws: true }); - - server.listen(port, () => { - this.coreLogger.info( - `\x1B[36m [cool:iot] MQTT serve started port: ${port} \x1B[0m` - ); - }); - - serverWs.listen(wsPort, () => { - this.coreLogger.info( - `\x1B[36m [cool:iot] MQTT websocket serve started port: ${wsPort} \x1B[0m` - ); - }); - } - - /** - * 初始化服务 - */ - async initServe() { - const { redis } = this.coolIotConfig; - let option = {} as AedesOptions; - // cluster模式下必须配置redis - if (redis) { - const mqredis = require('@cool-midway/mqemitter-redis'); - const mq = mqredis(redis); - option.id = randomUUID(); - // redis cluster模式 - if (redis instanceof Array) { - option.persistence = require('aedes-persistence-redis')({ - cluster: redis, - maxSessionDelivery: 1000, // maximum offline messages deliverable on client CONNECT, default is 1000 - }); - } else { - option.persistence = require('aedes-persistence-redis')({ - ...redis, - maxSessionDelivery: 1000, // maximum offline messages deliverable on client CONNECT, default is 1000 - }); - } - option = { - id: randomUUID(), - mq, - }; - } - this.serve = require('aedes')(option); - - // 认证 - if (this.coolIotConfig.auth) { - const auth = this.coolIotConfig.auth; - this.serve.authenticate = function ( - client, - username, - password, - callback - ) { - callback( - null, - username === auth.username && password.toString() === auth.password - ); - }; - } - } - - /** - * 处理类 - */ - async handlerCls() { - const eventModules = listModule(COOL_MQTT_KEY); - for (const module of eventModules) { - this.handlerEvent(module); - } - } - - /** - * 处理事件 - * @param module - */ - async handlerEvent(module) { - const events = getClassMetadata(COOL_MQTT_EVENT_KEY, module); - for (const event of events) { - const method = event.eventName ? event.eventName : event.propertyKey; - this.serve.on(method, async (...args) => { - const moduleInstance = await this.app - .getApplicationContext() - .getAsync(module); - moduleInstance[event.propertyKey](...args); - }); - } - } - - /** - * 发送消息 - * @param topic 话题 - * @param message 消息 - * @param other 其他配置 - */ - async publish(topic, message, other?) { - this.serve.publish( - { - cmd: 'publish', - qos: 2, - dup: false, - topic, - payload: Buffer.from(message), - retain: false, - ...this.coolIotConfig.publish, - ...other, - }, - error => { - if (error) { - this.coreLogger.error('publish fail', error); - } - } - ); - } -} diff --git a/packages/iot/src/package.json b/packages/iot/src/package.json deleted file mode 100644 index 5c9fb5b..0000000 --- a/packages/iot/src/package.json +++ /dev/null @@ -1,53 +0,0 @@ -{ - "name": "@cool-midway/iot", - "version": "6.0.0", - "description": "cool-js.com iot模块", - "main": "index.js", - "typings": "index.d.ts", - "scripts": { - "build": "cross-env midway-bin build -c", - "test": "cross-env midway-bin test --ts", - "cov": "cross-env midway-bin cov --ts", - "lint": "mwts check", - "lint:fix": "mwts fix" - }, - "keywords": [ - "cool", - "cool-admin", - "cooljs", - "cool-iot", - "iot" - ], - "author": "COOL", - "readme": "README.md", - "license": "MIT", - "repository": { - "type": "git", - "url": "https://cool-js.com" - }, - "files": [ - "**/*.js", - "**/*.d.ts", - "index.d.ts" - ], - "devDependencies": { - "@cool-midway/core": "^6.0.0", - "@midwayjs/cli": "^2.0.9", - "@midwayjs/core": "^3.9.0", - "@midwayjs/decorator": "^3.9.0", - "@midwayjs/mock": "^3.9.0", - "@types/jest": "^29.2.5", - "@types/node": "^18.11.18", - "cross-env": "^7.0.3", - "jest": "^29.3.1", - "mwts": "^1.3.0", - "ts-jest": "^29.0.3", - "typescript": "^4.9.4" - }, - "dependencies": { - "aedes": "^0.48.1", - "aedes-persistence-redis": "^9.0.2", - "@cool-midway/mqemitter-redis": "^6.0.0", - "aedes-server-factory": "^0.2.1" - } -} diff --git a/packages/iot/test/index.test.ts b/packages/iot/test/index.test.ts deleted file mode 100644 index a6c75a1..0000000 --- a/packages/iot/test/index.test.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { createLightApp } from '@midwayjs/mock'; -import * as custom from '../src'; - -describe('/test/index.test.ts', () => { - it('test component', async () => { - const app = await createLightApp('', { - imports: [ - custom - ] - }); - const bookService = await app.getApplicationContext().getAsync(custom.BookService); - expect(await bookService.getBookById()).toEqual('hello world'); - }); -}); diff --git a/packages/iot/tsconfig.json b/packages/iot/tsconfig.json deleted file mode 100644 index f01e1d2..0000000 --- a/packages/iot/tsconfig.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "compileOnSave": true, - "compilerOptions": { - "target": "es2018", - "module": "commonjs", - "moduleResolution": "node", - "experimentalDecorators": true, - "emitDecoratorMetadata": true, - "inlineSourceMap":false, - "noImplicitThis": true, - "noUnusedLocals": true, - "stripInternal": true, - "skipLibCheck": true, - "noImplicitReturns": false, - "pretty": true, - "declaration": true, - "outDir": "dist" - }, - "exclude": [ - "dist", - "node_modules", - "test" - ] -} diff --git a/packages/other/cache-manager-fs-hash/LICENSE b/packages/other/cache-manager-fs-hash/LICENSE deleted file mode 100644 index 924498c..0000000 --- a/packages/other/cache-manager-fs-hash/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 Roland Starke - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/packages/other/cache-manager-fs-hash/README.md b/packages/other/cache-manager-fs-hash/README.md deleted file mode 100644 index b77338d..0000000 --- a/packages/other/cache-manager-fs-hash/README.md +++ /dev/null @@ -1,81 +0,0 @@ -# Node Cache Manager store for Filesystem - -[![Build Status](https://travis-ci.org/rolandstarke/node-cache-manager-fs-hash.svg?branch=master)](https://travis-ci.org/rolandstarke/node-cache-manager-fs-hash) -[![dependencies Status](https://david-dm.org/rolandstarke/node-cache-manager-fs-hash/status.svg)](https://david-dm.org/rolandstarke/node-cache-manager-fs-hash) -[![npm package](https://img.shields.io/npm/v/cache-manager-fs-hash.svg)](https://www.npmjs.com/package/cache-manager-fs-hash) -[![node](https://img.shields.io/node/v/cache-manager-fs-hash.svg)](https://nodejs.org) - -A Filesystem store for the [node-cache-manager](https://github.com/BryanDonovan/node-cache-manager) module - -## Installation - -```sh -npm install cache-manager-fs-hash --save -``` - -## Features - -* Saves anything that is `JSON.stringify`-able to disk -* Buffers are saved as well (if they reach a certain size they will be stored to separate files) -* Works well with the cluster module - -## Usage example - -Here is an example that demonstrates how to implement the Filesystem cache store. - -```javascript -const cacheManager = require('cache-manager'); -const fsStore = require('cache-manager-fs-hash'); - -const diskCache = cacheManager.caching({ - store: fsStore, - options: { - path: 'diskcache', //path for cached files - ttl: 60 * 60, //time to life in seconds - subdirs: true, //create subdirectories to reduce the - //files in a single dir (default: false) - zip: true, //zip files to save diskspace (default: false) - } -}); - - -(async () => { - - await diskCache.set('key', 'value'); - console.log(await diskCache.get('key')); //"value" - console.log(await diskCache.ttl('key')); //3600 seconds - await diskCache.del('key'); - console.log(await diskCache.get('key')); //undefined - - - console.log(await getUserCached(5)); //{id: 5, name: '...'} - console.log(await getUserCached(5)); //{id: 5, name: '...'} - - await diskCache.reset(); - - function getUserCached(userId) { - return diskCache.wrap(userId /* cache key */, function () { - return getUser(userId); - }); - } - - async function getUser(userId) { - return {id: userId, name: '...'}; - } - -})(); -``` - -## How it works - -The filename is determined by the md5 hash of the `key`. (The `key` is also saved in the file to detect hash collisions. In this case it will just return a cache miss). Writing is performed with .lock files so that multiple instances of the library (e.g. using the cluster module) do not interfere with one another. - -## Tests - -```sh -npm test -``` - -## License - -cache-manager-fs-hash is licensed under the MIT license. diff --git a/packages/other/cache-manager-fs-hash/index.js b/packages/other/cache-manager-fs-hash/index.js deleted file mode 100644 index 211e452..0000000 --- a/packages/other/cache-manager-fs-hash/index.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./src'); \ No newline at end of file diff --git a/packages/other/cache-manager-fs-hash/package.json b/packages/other/cache-manager-fs-hash/package.json deleted file mode 100644 index 179e838..0000000 --- a/packages/other/cache-manager-fs-hash/package.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "name": "@cool-midway/cache-manager-fs-hash", - "version": "6.0.0", - "main": "index.js", - "engines": { - "node": ">=8.0.0" - }, - "description": "file system store for node cache manager", - "author": "Roland Starke", - "license": "MIT", - "files": [ - "index.js", - "src/*" - ], - "keywords": [ - "cache-manager", - "storage", - "filesystem" - ], - "repository": { - "type": "git", - "url": "git+https://github.com/rolandstarke/node-cache-manager-fs-hash.git" - }, - "bugs": { - "url": "https://github.com/rolandstarke/node-cache-manager-fs-hash/issues" - }, - "scripts": { - "test": "mocha ./test/**/*.js" - }, - "devDependencies": { - "cache-manager": "^3.2.1", - "mocha": "^7.1.1", - "rimraf": "^3.0.2" - }, - "dependencies": { - "lockfile": "^1.0.4" - } -} diff --git a/packages/other/cache-manager-fs-hash/src/index.js b/packages/other/cache-manager-fs-hash/src/index.js deleted file mode 100644 index e500294..0000000 --- a/packages/other/cache-manager-fs-hash/src/index.js +++ /dev/null @@ -1,261 +0,0 @@ -const fs = require('fs'); -const crypto = require('crypto'); -const path = require('path'); -const promisify = require('util').promisify; -const lockFile = require('lockfile'); -const jsonFileStore = require('./json-file-store'); -const wrapCallback = require('./wrap-callback'); - - -/** - * construction of the disk storage - * @param {object} [args] options of disk store - * @param {string} [args.path] path for cached files - * @param {number} [args.ttl] time to life in seconds - * @param {boolean} [args.zip] zip content to save diskspace - * @todo {number} [args.maxsize] max size in bytes on disk - * @param {boolean} [args.subdirs] create subdirectories - * @returns {DiskStore} - */ -exports.create = function (args) { - return new DiskStore(args && args.options ? args.options : args); -}; - -function DiskStore(options) { - options = options || {}; - - this.options = { - path: options.path || './cache', /* path for cached files */ - ttl: options.ttl, /* time before expiring in seconds */ - maxsize: options.maxsize || Infinity, /* max size in bytes on disk */ - subdirs: options.subdirs || false, - zip: options.zip || false, - lockFile: { //check lock at 0ms 50ms 100ms ... 400ms 1400ms 1450ms... up to 10 seconds, after that just asume the lock is staled - wait: 400, - pollPeriod: 50, - stale: 10 * 1000, - retries: 10, - retryWait: 600, - } - }; - - // check storage directory for existence (or create it) - if (!fs.existsSync(this.options.path)) { - fs.mkdirSync(this.options.path); - } -} - -/** - * save an entry in store - * @param {string} key - * @param {*} val - * @param {object} [options] - * @param {number} options.ttl time to life in seconds - * @param {function} [cb] - * @returns {Promise} - */ -DiskStore.prototype.set = wrapCallback(async function (key, val, options) { - key = key + ''; - const filePath = this._getFilePathByKey(key); - - const ttl = (options && (options.ttl >= 0)) ? +options.ttl : this.options.ttl; - const data = { - key: key, - val: val, - }; - if(ttl>0){ - data.expireTime = Date.now() + ttl * 1000; - } - - - if (this.options.subdirs) { - //check if subdir exists or create it - const dir = path.dirname(filePath); - await promisify(fs.access)(dir, fs.constants.W_OK).catch(function () { - return promisify(fs.mkdir)(dir).catch(err => { - if (err.code !== 'EEXIST') throw err; - }); - }); - } - - try { - await this._lock(filePath); - await jsonFileStore.write(filePath, data, this.options); - } catch (err) { - throw err; - } finally { - await this._unlock(filePath); - } -}); - - -DiskStore.prototype._readFile = async function (key) { - key = key + ''; - const filePath = this._getFilePathByKey(key); - - try { - const data = await jsonFileStore.read(filePath, this.options).catch(async (err) => { - if (err.code === 'ENOENT') { - throw err; - } - //maybe the file is currently written to, lets lock it and read again - try { - await this._lock(filePath); - return await jsonFileStore.read(filePath, this.options); - } catch (err2) { - throw err2; - } finally { - await this._unlock(filePath); - } - }); - if (data.expireTime <= Date.now()) { - //cache expired - this.del(key).catch(() => 0 /* ignore */); - return undefined; - } - if (data.key !== key) { - //hash collision - return undefined; - } - return data; - - } catch (err) { - //file does not exist lets return a cache miss - if (err.code === 'ENOENT') { - return undefined; - } else { - throw err; - } - } -}; - -/** - * get an entry from store - * @param {string} key - * @param {function} [cb] - * @returns {Promise} - */ -DiskStore.prototype.get = wrapCallback(async function (key) { - const data = await this._readFile(key); - if (data) { - return data.val; - } else { - return data; - } -}); - -/** - * get ttl in seconds for key in store - * @param {string} key - * @param {function} [cb] - * @returns {Promise} - */ -DiskStore.prototype.ttl = wrapCallback(async function (key) { - const data = await this._readFile(key); - if (data) { - return (data.expireTime - Date.now()) / 1000; - } else { - return 0; - } -}); - - -/** - * delete entry from cache - */ -DiskStore.prototype.del = wrapCallback(async function (key) { - const filePath = this._getFilePathByKey(key); - try { - if (this.options.subdirs) { - //check if the folder exists to fail faster - const dir = path.dirname(filePath); - await promisify(fs.access)(dir, fs.constants.W_OK); - } - - await this._lock(filePath); - await jsonFileStore.delete(filePath, this.options); - } catch (err) { - //ignore deleting non existing keys - if (err.code !== 'ENOENT') { - throw err; - } - } finally { - await this._unlock(filePath); - } -}); - - -/** - * cleanup cache on disk -> delete all files from the cache - */ -DiskStore.prototype.reset = wrapCallback(async function () { - const readdir = promisify(fs.readdir); - const stat = promisify(fs.stat); - const unlink = promisify(fs.unlink); - - return await deletePath(this.options.path, 2); - - async function deletePath(fileOrDir, maxDeep) { - if (maxDeep < 0) { - return; - } - const stats = await stat(fileOrDir); - if (stats.isDirectory()) { - const files = await readdir(fileOrDir); - for (let i = 0; i < files.length; i++) { - await deletePath(path.join(fileOrDir, files[i]), maxDeep - 1); - } - } else if (stats.isFile() && /[/\\]diskstore-[0-9a-fA-F/\\]+(\.json|-\d\.bin)/.test(fileOrDir)) { - //delete the file if it is a diskstore file - await unlink(fileOrDir); - } - } -}); - - -/** - * locks a file so other forks that want to use the same file have to wait - * @param {string} filePath - * @returns {Promise} - * @private - */ -DiskStore.prototype._lock = function (filePath) { - return promisify(lockFile.lock)( - filePath + '.lock', - JSON.parse(JSON.stringify(this.options.lockFile)) //the options are modified -> create a copy to prevent that - ); -}; - -/** - * unlocks a file path - * @type {Function} - * @param {string} filePath - * @returns {Promise} - * @private - */ -DiskStore.prototype._unlock = function (filePath) { - return promisify(lockFile.unlock)(filePath + '.lock'); -}; - -/** - * returns the location where the value should be stored - * @param {string} key - * @returns {string} - * @private - */ -DiskStore.prototype._getFilePathByKey = function (key) { - const hash = crypto.createHash('md5').update(key + '').digest('hex'); - if (this.options.subdirs) { - //create subdirs with the first 3 chars of the hash - return path.join( - this.options.path, - 'diskstore-' + hash.substr(0, 3), - hash.substr(3), - ); - } else { - return path.join( - this.options.path, - 'diskstore-' + hash - ); - } -}; \ No newline at end of file diff --git a/packages/other/cache-manager-fs-hash/src/json-file-store.js b/packages/other/cache-manager-fs-hash/src/json-file-store.js deleted file mode 100644 index f655fd8..0000000 --- a/packages/other/cache-manager-fs-hash/src/json-file-store.js +++ /dev/null @@ -1,118 +0,0 @@ -const promisify = require('util').promisify; -const fs = require('fs'); -const zlib = require('zlib'); - -exports.write = async function (path, data, options) { - const externalBuffers = []; - let dataString = JSON.stringify(data, function replacerFunction(k, value) { - //Buffers searilize to {data: [...], type: "Buffer"} - if (value && value.type === 'Buffer' && value.data && value.data.length >= 1024 /* only save bigger Buffers external, small ones can be inlined */) { - const buffer = Buffer.from(value.data); - externalBuffers.push({ - index: externalBuffers.length, - buffer: buffer, - }); - return { - type: 'ExternalBuffer', - index: externalBuffers.length - 1, - size: buffer.length, - }; - } else if (value === Infinity || value === -Infinity) { - return { type: 'Infinity', sign: Math.sign(value) }; - } else { - return value; - } - }); - - - let zipExtension = ''; - if (options.zip) { - zipExtension = '.gz'; - dataString = await promisify(zlib.deflate)(dataString); - } - //save main json file - await promisify(fs.writeFile)(path + '.json' + zipExtension, dataString, 'utf8'); - - //save external buffers - await Promise.all(externalBuffers.map(async function (externalBuffer) { - let buffer = externalBuffer.buffer; - if (options.zip) { - buffer = await promisify(zlib.deflate)(buffer); - } - await promisify(fs.writeFile)(path + '-' + externalBuffer.index + '.bin' + zipExtension, buffer, 'utf8'); - })); -}; - - -exports.read = async function (path, options) { - let zipExtension = ''; - if (options.zip) { - zipExtension = '.gz'; - } - - //read main json file - let dataString; - if (options.zip) { - const compressedData = await promisify(fs.readFile)(path + '.json' + zipExtension); - dataString = (await promisify(zlib.unzip)(compressedData)).toString(); - } else { - dataString = await promisify(fs.readFile)(path + '.json' + zipExtension, 'utf8'); - } - - - const externalBuffers = []; - const data = JSON.parse(dataString, function bufferReceiver(k, value) { - if (value && value.type === 'Buffer' && value.data) { - return Buffer.from(value.data); - } else if (value && value.type === 'ExternalBuffer' && typeof value.index === 'number' && typeof value.size === 'number') { - //JSON.parse is sync so we need to return a buffer sync, we will fill the buffer later - const buffer = Buffer.alloc(value.size); - externalBuffers.push({ - index: +value.index, - buffer: buffer, - }); - return buffer; - } else if (value && value.type === 'Infinity' && typeof value.sign === 'number') { - return Infinity * value.sign; - } else { - return value; - } - }); - - //read external buffers - await Promise.all(externalBuffers.map(async function (externalBuffer) { - - if (options.zip) { - const bufferCompressed = await promisify(fs.readFile)(path + '-' + +externalBuffer.index + '.bin' + zipExtension); - const buffer = await promisify(zlib.unzip)(bufferCompressed); - buffer.copy(externalBuffer.buffer); - } else { - const fd = await promisify(fs.open)(path + '-' + +externalBuffer.index + '.bin' + zipExtension, 'r'); - await promisify(fs.read)(fd, externalBuffer.buffer, 0, externalBuffer.buffer.length, 0); - await promisify(fs.close)(fd); - } - })); - return data; -}; - -exports.delete = async function (path, options) { - let zipExtension = ''; - if (options.zip) { - zipExtension = '.gz'; - } - - await promisify(fs.unlink)(path + '.json' + zipExtension); - - //delete binary files - try { - for (let i = 0; i < Infinity; i++) { - await promisify(fs.unlink)(path + '-' + i + '.bin' + zipExtension); - } - } catch (err) { - if (err.code === 'ENOENT') { - // every binary is deleted, we are done - } else { - throw err; - } - } -}; \ No newline at end of file diff --git a/packages/other/cache-manager-fs-hash/src/wrap-callback.js b/packages/other/cache-manager-fs-hash/src/wrap-callback.js deleted file mode 100644 index aafc3ba..0000000 --- a/packages/other/cache-manager-fs-hash/src/wrap-callback.js +++ /dev/null @@ -1,21 +0,0 @@ -/** - * adds an callback param to the original function - * @param {function} fn - * @returns {function} - */ -module.exports = function wrapCallback(fn) { - return function (...args) { - let cb; - if (typeof args[args.length - 1] === 'function') { - cb = args.pop(); - } - - const promise = fn.apply(this, args); - - if (typeof cb === 'function') { - promise.then(value => setImmediate(cb, null, value), err => setImmediate(cb, err)); - } - - return promise; - }; -}; \ No newline at end of file diff --git a/packages/other/mqemitter-redis/.github/dependabot.yml b/packages/other/mqemitter-redis/.github/dependabot.yml deleted file mode 100644 index 4872c5a..0000000 --- a/packages/other/mqemitter-redis/.github/dependabot.yml +++ /dev/null @@ -1,7 +0,0 @@ -version: 2 -updates: -- package-ecosystem: npm - directory: "/" - schedule: - interval: daily - open-pull-requests-limit: 10 diff --git a/packages/other/mqemitter-redis/.github/workflows/ci.yml b/packages/other/mqemitter-redis/.github/workflows/ci.yml deleted file mode 100644 index c9b1558..0000000 --- a/packages/other/mqemitter-redis/.github/workflows/ci.yml +++ /dev/null @@ -1,35 +0,0 @@ -name: ci - -on: [push, pull_request] - -jobs: - test: - runs-on: ubuntu-latest - - strategy: - matrix: - node-version: [14.x, 16.x, 18.x] - redis-tag: [5, 6] - - services: - redis: - image: redis:${{ matrix.redis-tag }} - ports: - - 6379:6379 - options: --entrypoint redis-server - - steps: - - uses: actions/checkout@v1 - - - name: Use Node.js - uses: actions/setup-node@v2 - with: - node-version: ${{ matrix.node-version }} - - - name: Install - run: | - npm install - - - name: Run tests - run: | - npm run test diff --git a/packages/other/mqemitter-redis/.gitignore b/packages/other/mqemitter-redis/.gitignore deleted file mode 100644 index 6c655ef..0000000 --- a/packages/other/mqemitter-redis/.gitignore +++ /dev/null @@ -1,33 +0,0 @@ -# Logs -logs -*.log - -# Runtime data -pids -*.pid -*.seed - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage - -# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# Compiled binary addons (http://nodejs.org/api/addons.html) -build/Release - -# Dependency directory -# Commenting this out is preferred by some people, see -# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git- -node_modules - -# Users Environment Variables -.lock-wscript - -# ignore redis dump -dump.rdb - -package-lock.json diff --git a/packages/other/mqemitter-redis/.travis.yml b/packages/other/mqemitter-redis/.travis.yml deleted file mode 100644 index 73469a0..0000000 --- a/packages/other/mqemitter-redis/.travis.yml +++ /dev/null @@ -1,9 +0,0 @@ -language: node_js -node_js: - - "10" - - "12" - - "13" - - "14" - - "15" -services: - - redis diff --git a/packages/other/mqemitter-redis/LICENSE b/packages/other/mqemitter-redis/LICENSE deleted file mode 100644 index feb2ed0..0000000 --- a/packages/other/mqemitter-redis/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2014-2020 Matteo Collina - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/packages/other/mqemitter-redis/README.md b/packages/other/mqemitter-redis/README.md deleted file mode 100644 index e4cd108..0000000 --- a/packages/other/mqemitter-redis/README.md +++ /dev/null @@ -1,76 +0,0 @@ -mqemitter-redis  ![ci](https://github.com/mcollina/mqemitter/workflows/ci/badge.svg) -=============== - -Redis-powered [MQEmitter](http://github.com/mcollina/mqemitter). - -See [MQEmitter](http://github.com/mcollina/mqemitter) for the actual -API. - -[![js-standard-style](https://raw.githubusercontent.com/feross/standard/master/badge.png)](https://github.com/feross/standard) - - -Install -------- - -```bash -$ npm install mqemitter-redis --save -``` - -Example -------- - -```js -var redis = require('mqemitter-redis') -var mq = redis({ - port: 12345, - host: '12.34.56.78', - password: 'my secret', - db: 4 -}) -var msg = { - topic: 'hello world', - payload: 'or any other fields' -} - -mq.on('hello world', function (message, cb) { - // call callback when you are done - // do not pass any errors, the emitter cannot handle it. - cb() -}) - -// topic is mandatory -mq.emit(msg, function () { - // emitter will never return an error -}) -``` - -Connection String Example -------------------------- - -```js -var redis = require('mqemitter-redis') -var mq = redis({ - connectionString: 'redis://:authpassword@127.0.0.1:6380/4' -}) -``` - -## API - - -### MQEmitterRedis([opts]) - -Creates a new instance of mqemitter-redis. -It takes all the same options of [ioredis](http://npm.im/ioredis), -which is used internally to connect to Redis. - -This constructor creates two connections to Redis. - -Acknowledgements ----------------- - -Code ported from [Ascoltatori](http://github.com/mcollina/ascoltatori). - -License -------- - -MIT diff --git a/packages/other/mqemitter-redis/mqemitter-redis.js b/packages/other/mqemitter-redis/mqemitter-redis.js deleted file mode 100644 index 62f2222..0000000 --- a/packages/other/mqemitter-redis/mqemitter-redis.js +++ /dev/null @@ -1,250 +0,0 @@ -"use strict"; - -const Redis = require("ioredis"); -const MQEmitter = require("mqemitter"); -const hyperid = require("hyperid")(); -const inherits = require("inherits"); -const LRU = require("lru-cache"); -const msgpack = require("msgpack-lite"); -const EE = require("events").EventEmitter; -const Pipeline = require("ioredis-auto-pipeline"); - -function MQEmitterRedis(opts) { - if (!(this instanceof MQEmitterRedis)) { - return new MQEmitterRedis(opts); - } - - opts = opts || {}; - - this._opts = opts; - - if (opts instanceof Array) { - this.subConn = new Redis.Cluster(opts); - this.pubConn = new Redis.Cluster(opts); - } else { - this.subConn = new Redis(opts.connectionString || opts); - this.pubConn = new Redis(opts.connectionString || opts); - } - - this._pipeline = Pipeline(this.pubConn); - - this._topics = {}; - - this._cache = new LRU({ - max: 10000, - ttl: 60 * 1000, // one minute - }); - - this.state = new EE(); - - const that = this; - - function onError(err) { - if (err && !that.closing) { - that.state.emit("error", err); - } - } - - this._onError = onError; - - function handler(sub, topic, payload) { - const packet = msgpack.decode(payload); - if (!that._cache.get(packet.id)) { - that._emit(packet.msg); - } - that._cache.set(packet.id, true); - } - - this.subConn.on("messageBuffer", function (topic, message) { - handler(topic, topic, message); - }); - - this.subConn.on("pmessageBuffer", function (sub, topic, message) { - handler(sub, topic, message); - }); - - this.subConn.on("connect", function () { - that.state.emit("subConnect"); - }); - - this.subConn.on("error", function (err) { - that._onError(err); - }); - - this.pubConn.on("connect", function () { - that.state.emit("pubConnect"); - }); - - this.pubConn.on("error", function (err) { - that._onError(err); - }); - - MQEmitter.call(this, opts); - - this._opts.regexWildcardOne = new RegExp( - this._opts.wildcardOne.replace(/([/,!\\^${}[\]().*+?|<>\-&])/g, "\\$&"), - "g" - ); - this._opts.regexWildcardSome = new RegExp( - (this._opts.matchEmptyLevels - ? this._opts.separator.replace(/([/,!\\^${}[\]().*+?|<>\-&])/g, "\\$&") + - "?" - : "") + - this._opts.wildcardSome.replace(/([/,!\\^${}[\]().*+?|<>\-&])/g, "\\$&"), - "g" - ); -} - -inherits(MQEmitterRedis, MQEmitter); -["emit", "on", "removeListener", "close"].forEach(function (name) { - MQEmitterRedis.prototype["_" + name] = MQEmitterRedis.prototype[name]; -}); - -MQEmitterRedis.prototype.close = function (cb) { - cb = cb || noop; - - if (this.closed || this.closing) { - return cb(); - } - - this.closing = true; - - let count = 2; - const that = this; - - function onEnd() { - if (--count === 0) { - that._close(cb); - } - } - - this.subConn.on("end", onEnd); - this.subConn.quit(); - - this.pubConn.on("end", onEnd); - this.pubConn.quit(); - - return this; -}; - -MQEmitterRedis.prototype._subTopic = function (topic) { - return topic - .replace(this._opts.regexWildcardOne, "*") - .replace(this._opts.regexWildcardSome, "*"); -}; - -MQEmitterRedis.prototype.on = function on(topic, cb, done) { - const subTopic = this._subTopic(topic); - const onFinish = function () { - if (done) { - setImmediate(done); - } - }; - - this._on(topic, cb); - - if (this._topics[subTopic]) { - this._topics[subTopic]++; - onFinish.call(this); - return this; - } - - this._topics[subTopic] = 1; - - if (this._containsWildcard(topic)) { - this.subConn.psubscribe(subTopic, onFinish.bind(this)); - } else { - this.subConn.subscribe(subTopic, onFinish.bind(this)); - } - - return this; -}; - -MQEmitterRedis.prototype.emit = function (msg, done) { - done = done || this._onError; - - if (this.closed) { - const err = new Error("mqemitter-redis is closed"); - return done(err); - } - - const packet = { - id: hyperid(), - msg, - }; - - this._pipeline - .publish(msg.topic, msgpack.encode(packet)) - .then(() => done()) - .catch(done); -}; - -MQEmitterRedis.prototype.removeListener = function (topic, cb, done) { - const subTopic = this._subTopic(topic); - const onFinish = function () { - if (done) { - setImmediate(done); - } - }; - - this._removeListener(topic, cb); - - if (--this._topics[subTopic] > 0) { - onFinish(); - return this; - } - - delete this._topics[subTopic]; - - if (this._containsWildcard(topic)) { - this.subConn.punsubscribe(subTopic, onFinish); - } else if (this._matcher.match(topic)) { - this.subConn.unsubscribe(subTopic, onFinish); - } - - return this; -}; - -MQEmitterRedis.prototype._containsWildcard = function (topic) { - return ( - topic.indexOf(this._opts.wildcardOne) >= 0 || - topic.indexOf(this._opts.wildcardSome) >= 0 - ); -}; - -function noop() {} - -module.exports = MQEmitterRedis; - -function MQEmitterRedisPrefix(pubSubPrefix, options) { - MQEmitterRedis.call(this, options); - this._pubSubPrefix = pubSubPrefix; - this._sym_proxiedCallback = Symbol("proxiedCallback"); -} -inherits(MQEmitterRedisPrefix, MQEmitterRedis); -MQEmitterRedisPrefix.prototype.on = function (topic, cb, done) { - const t = this._pubSubPrefix + topic; - cb[this._sym_proxiedCallback] = function (packet, cbcb) { - const t = packet.topic.slice(this._pubSubPrefix.length); - const p = { ...packet, topic: t }; - return cb.call(this, p, cbcb); - }.bind(this); - return MQEmitterRedis.prototype.on.call( - this, - t, - cb[this._sym_proxiedCallback], - done - ); -}; -MQEmitterRedisPrefix.prototype.removeListener = function (topic, func, done) { - const t = this._pubSubPrefix + topic; - const f = func[this._sym_proxiedCallback]; - return MQEmitterRedis.prototype.removeListener.call(this, t, f, done); -}; -MQEmitterRedisPrefix.prototype.emit = function (packet, done) { - const t = this._pubSubPrefix + packet.topic; - const p = { ...packet, topic: t }; - return MQEmitterRedis.prototype.emit.call(this, p, done); -}; - -module.exports.MQEmitterRedisPrefix = MQEmitterRedisPrefix; diff --git a/packages/other/mqemitter-redis/package.json b/packages/other/mqemitter-redis/package.json deleted file mode 100644 index f2495f6..0000000 --- a/packages/other/mqemitter-redis/package.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "name": "@cool-midway/mqemitter-redis", - "version": "6.0.0", - "description": "Redis-based MQEmitter", - "main": "mqemitter-redis.js", - "types": "types/index.d.ts", - "dependencies": { - "hyperid": "^3.0.1", - "inherits": "^2.0.1", - "ioredis": "^5.0.4", - "ioredis-auto-pipeline": "^1.0.1", - "lru-cache": "^7.9.0", - "mqemitter": "^4.1.3", - "msgpack-lite": "^0.1.14" - }, - "devDependencies": { - "@types/ioredis": "^4.19.4", - "faucet": "^0.0.1", - "pre-commit": "^1.0.7", - "safe-buffer": "^5.1.2", - "standard": "^17.0.0", - "tape": "^5.0.1", - "tsd": "^0.20.0" - }, - "scripts": { - "test:types": "tsd", - "test": "standard && tape test.js | faucet && tsd" - }, - "pre-commit": "test", - "repository": { - "type": "git", - "url": "https://github.com/mcollina/mqemitter-redis.git" - }, - "keywords": [ - "redis", - "mqemitter", - "emitter", - "pubsub", - "publish", - "subscribe", - "cool" - ], - "author": "COOL", - "license": "MIT", - "homepage": "https://cool-js.com" -} diff --git a/packages/other/mqemitter-redis/test.js b/packages/other/mqemitter-redis/test.js deleted file mode 100644 index 8305b3a..0000000 --- a/packages/other/mqemitter-redis/test.js +++ /dev/null @@ -1,116 +0,0 @@ -'use strict' - -const redis = require('./') -const test = require('tape').test -const abstractTests = require('mqemitter/abstractTest.js') - -abstractTests({ - builder: redis, - test -}) - -abstractTests({ - builder: function (opts) { return new redis.MQEmitterRedisPrefix('some_prefix/', opts) }, - test -}) - -function noop () {} - -test('actual unsubscribe from Redis', function (t) { - const e = redis() - - e.subConn.on('message', function (topic, message) { - t.fail('the message should not be emitted') - }) - - e.on('hello', noop) - e.removeListener('hello', noop) - e.emit({ topic: 'hello' }, function (err) { - t.notOk(err) - e.close(function () { - t.end() - }) - }) -}) - -test('ioredis connect event', function (t) { - const e = redis() - - let subConnectEventReceived = false - let pubConnectEventReceived = false - - e.state.on('pubConnect', function () { - pubConnectEventReceived = true - newConnectionEvent() - }) - - e.state.on('subConnect', function () { - subConnectEventReceived = true - newConnectionEvent() - }) - - function newConnectionEvent () { - if (subConnectEventReceived && pubConnectEventReceived) { - e.close(function () { - t.end() - }) - } - } -}) - -test('ioredis error event', function (t) { - const e = redis({ host: '127' }) - - t.plan(1) - - e.state.once('error', function (err) { - t.deepEqual(err.message.substr(0, 7), 'connect') - e.close(function () { - t.end() - }) - }) -}) - -test('topic pattern adapter', function (t) { - const e = redis() - - const mqttTopic = 'rooms/+/devices/+/status' - const expectedRedisPattern = 'rooms/*/devices/*/status' - - const subTopic = e._subTopic(mqttTopic) - - t.plan(1) - - t.deepEqual(subTopic, expectedRedisPattern) - - e.close(function () { - t.end() - }) -}) - -test('ioredis connection string', function (t) { - const e = redis({ - connectionString: 'redis://localhost:6379/0' - }) - - let subConnectEventReceived = false - let pubConnectEventReceived = false - - e.state.on('pubConnect', function () { - pubConnectEventReceived = true - newConnectionEvent() - }) - - e.state.on('subConnect', function () { - subConnectEventReceived = true - newConnectionEvent() - }) - - function newConnectionEvent () { - if (subConnectEventReceived && pubConnectEventReceived) { - e.close(function () { - t.end() - }) - } - } -}) diff --git a/packages/other/mqemitter-redis/types/index.d.ts b/packages/other/mqemitter-redis/types/index.d.ts deleted file mode 100644 index a6a5a6c..0000000 --- a/packages/other/mqemitter-redis/types/index.d.ts +++ /dev/null @@ -1,37 +0,0 @@ -import type { RedisOptions } from 'ioredis'; -import type { MQEmitter } from 'mqemitter'; - -export interface MQEmitterOptions { - concurrency?: number; - matchEmptyLevels?: boolean; - separator?: string; - wildcardOne?: string; - wildcardSome?: string; - connectionString?: string; -} - -export type Message = Record & { topic: string }; - -export interface MQEmitterRedis extends MQEmitter { - new (options?: MQEmitterOptions & RedisOptions): MQEmitterRedis; - current: number; - concurrent: number; - on( - topic: string, - listener: (message: Message, done: () => void) => void, - callback?: () => void - ): this; - emit(message: Message, callback?: (error?: Error) => void): void; - removeListener( - topic: string, - listener: (message: Message, done: () => void) => void, - callback?: () => void - ): void; - close(callback: () => void): void; -} - -declare function MQEmitterRedis( - options?: MQEmitterOptions & RedisOptions -): MQEmitterRedis; - -export default MQEmitterRedis; diff --git a/packages/other/mqemitter-redis/types/index.test-d.ts b/packages/other/mqemitter-redis/types/index.test-d.ts deleted file mode 100644 index f9d83d2..0000000 --- a/packages/other/mqemitter-redis/types/index.test-d.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { expectError, expectType } from 'tsd'; -import mqEmitterRedis, { Message, MQEmitterRedis } from '.'; - -expectType(mqEmitterRedis()); - -expectType( - mqEmitterRedis({ concurrency: 200, matchEmptyLevels: true }) -); - -expectType( - mqEmitterRedis({ - concurrency: 10, - matchEmptyLevels: true, - separator: '/', - wildcardOne: '+', - wildcardSome: '#', - connectionString: 'redis://:authpassword@127.0.0.1:6380/4', - }) -); - -expectType( - mqEmitterRedis({ - concurrency: 10, - matchEmptyLevels: true, - host: 'localhost', - port: 6379, - reconnectOnError: (error: Error) => true, - retryStrategy: (times: number) => times * 1.5, - }) -); - -function listener(message: Message, done: () => void) {} - -expectType(mqEmitterRedis().on('topic', listener)); - -expectType(mqEmitterRedis().removeListener('topic', listener)); - -expectError(mqEmitterRedis().emit(null)); - -expectType(mqEmitterRedis().emit({ topic: 'test', prop1: 'prop1' })); - -expectType(mqEmitterRedis().close(() => null)); diff --git a/packages/pay/.editorconfig b/packages/pay/.editorconfig deleted file mode 100644 index 4c7f8a8..0000000 --- a/packages/pay/.editorconfig +++ /dev/null @@ -1,11 +0,0 @@ -# 🎨 editorconfig.org - -root = true - -[*] -charset = utf-8 -end_of_line = lf -indent_style = space -indent_size = 2 -trim_trailing_whitespace = true -insert_final_newline = true \ No newline at end of file diff --git a/packages/pay/.eslintrc.json b/packages/pay/.eslintrc.json deleted file mode 100644 index aad9755..0000000 --- a/packages/pay/.eslintrc.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "extends": "./node_modules/mwts/", - "ignorePatterns": [ - "node_modules", - "dist", - "test", - "jest.config.js", - "typings", - "public/**/**", - "view/**/**" - ], - "env": { - "jest": true - }, - "rules": { - "@typescript-eslint/explicit-module-boundary-types": "off", - "@typescript-eslint/no-unused-vars": "off", - "@typescript-eslint/ban-ts-comment": "off", - "node/no-extraneous-import": "off", - "no-empty": "off", - "node/no-extraneous-require": "off", - "eqeqeq": "off", - "node/no-unsupported-features/node-builtins": "off", - "@typescript-eslint/ban-types": "off", - "no-control-regex": "off", - "prefer-const": "off" - } -} \ No newline at end of file diff --git a/packages/pay/.gitignore b/packages/pay/.gitignore deleted file mode 100644 index 13bc3a6..0000000 --- a/packages/pay/.gitignore +++ /dev/null @@ -1,15 +0,0 @@ -logs/ -npm-debug.log -yarn-error.log -node_modules/ -package-lock.json -yarn.lock -coverage/ -dist/ -.idea/ -run/ -.DS_Store -*.sw* -*.un~ -.tsbuildinfo -.tsbuildinfo.* diff --git a/packages/pay/.prettierrc.js b/packages/pay/.prettierrc.js deleted file mode 100644 index b964930..0000000 --- a/packages/pay/.prettierrc.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - ...require('mwts/.prettierrc.json') -} diff --git a/packages/pay/index.d.ts b/packages/pay/index.d.ts deleted file mode 100644 index e0065de..0000000 --- a/packages/pay/index.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -export * from './dist/index'; - -declare module '@midwayjs/core/dist/interface' { - interface MidwayConfig { - book?: PowerPartial<{ - a: number; - b: string; - }>; - } -} diff --git a/packages/pay/jest.config.js b/packages/pay/jest.config.js deleted file mode 100644 index 82a8b85..0000000 --- a/packages/pay/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - preset: 'ts-jest', - testEnvironment: 'node', - testPathIgnorePatterns: ['/test/fixtures'], - coveragePathIgnorePatterns: ['/test/'], - setupFilesAfterEnv: ['./jest.setup.js'] -}; diff --git a/packages/pay/jest.setup.js b/packages/pay/jest.setup.js deleted file mode 100644 index 1399c91..0000000 --- a/packages/pay/jest.setup.js +++ /dev/null @@ -1 +0,0 @@ -jest.setTimeout(30000); diff --git a/packages/pay/package.json b/packages/pay/package.json deleted file mode 100644 index f80982a..0000000 --- a/packages/pay/package.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "name": "@cool-midway/pay", - "version": "6.0.0", - "description": "cool-js.com 支付 微信 支付宝", - "main": "dist/index.js", - "typings": "index.d.ts", - "scripts": { - "build": "cross-env midway-bin build -c", - "test": "cross-env midway-bin test --ts", - "cov": "cross-env midway-bin cov --ts", - "lint": "mwts check", - "lint:fix": "mwts fix" - }, - "keywords": [ - "cool", - "cool-admin", - "cooljs" - ], - "author": "COOL", - "readme": "README.md", - "files": [ - "dist/**/*.js", - "dist/**/*.d.ts", - "index.d.ts" - ], - "license": "MIT", - "repository": { - "type": "git", - "url": "https://cool-js.com" - }, - "devDependencies": { - "@cool-midway/core": "^6.0.0", - "@midwayjs/cli": "^2.0.9", - "@midwayjs/core": "^3.9.0", - "@midwayjs/decorator": "^3.9.0", - "@midwayjs/mock": "^3.9.0", - "@types/jest": "^29.2.5", - "@types/node": "^18.11.18", - "cross-env": "^7.0.3", - "jest": "^29.3.1", - "mwts": "^1.3.0", - "ts-jest": "^29.0.3", - "typescript": "^4.9.4" - }, - "dependencies": { - "@4a/cid": "^0.1.0", - "alipay-sdk": "^3.2.0", - "wechatpay-node-v3": "^2.1.0" - } -} diff --git a/packages/pay/src/ali.ts b/packages/pay/src/ali.ts deleted file mode 100644 index b46e992..0000000 --- a/packages/pay/src/ali.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { Config, Init, Provide, Scope, ScopeEnum } from '@midwayjs/decorator'; -import * as cid from '@4a/cid'; -import { CoolAliPayConfig } from './interface'; -import AlipaySdk from 'alipay-sdk'; - -/** - * 支付宝支付 - */ -@Provide() -@Scope(ScopeEnum.Singleton) -export class CoolAliPay { - pay: AlipaySdk; - - @Config('cool.pay.ali') - coolAlipay: CoolAliPayConfig; - - @Init() - async init() { - if (this.coolAlipay) this.pay = new AlipaySdk(this.coolAlipay); - } - - /** - * 获得支付宝支付SDK实例 - * @returns - */ - getInstance(): AlipaySdk { - return this.pay; - } - - /** - * 通知验签 - * @param postData {JSON} 服务端的消息内容 - * @param raw {Boolean} 是否使用 raw 内容而非 decode 内容验签 - */ - signVerify(postData: any, raw?: boolean) { - return this.pay.checkNotifySign(postData, raw); - } - - /** - * 创建订单 - * @param length 订单长度 - * @returns - */ - createOrderNum(length = 26) { - return cid(length); - } - - /** - * 动态配置支付参数 - * @param config 微信配置 - * @returns - */ - initPay(config: CoolAliPayConfig) { - return new AlipaySdk(config); - } -} diff --git a/packages/pay/src/config/config.default.ts b/packages/pay/src/config/config.default.ts deleted file mode 100644 index d8324ca..0000000 --- a/packages/pay/src/config/config.default.ts +++ /dev/null @@ -1,4 +0,0 @@ -export const customKey = { - a: 1, - b: 'hello', -}; diff --git a/packages/pay/src/configuration.ts b/packages/pay/src/configuration.ts deleted file mode 100644 index a77d2e5..0000000 --- a/packages/pay/src/configuration.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Configuration } from '@midwayjs/decorator'; -import * as DefaultConfig from './config/config.default'; -import { IMidwayContainer } from '@midwayjs/core'; -import { CoolWxPay } from './wx'; -import { CoolAliPay } from './ali'; - -@Configuration({ - namespace: 'cool:pay', - importConfigs: [ - { - default: DefaultConfig, - }, - ], -}) -export class CoolPayConfiguration { - async onReady(container: IMidwayContainer) { - await container.getAsync(CoolWxPay); - await container.getAsync(CoolAliPay); - // TODO something - } -} diff --git a/packages/pay/src/index.ts b/packages/pay/src/index.ts deleted file mode 100644 index c040890..0000000 --- a/packages/pay/src/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -export { CoolPayConfiguration as Configuration } from './configuration'; - -export * from './interface'; - -export * from './wx'; - -export * from './ali'; diff --git a/packages/pay/src/interface.ts b/packages/pay/src/interface.ts deleted file mode 100644 index 43eba55..0000000 --- a/packages/pay/src/interface.ts +++ /dev/null @@ -1,77 +0,0 @@ -/** - * 微信支付配置 - */ -export interface CoolWxPayConfig { - // 直连商户申请的公众号或移动应用appid。 - appid: string; - // 商户号 - mchid: string; - // 可选参数 证书序列号 - serial_no?: string; - // 回调链接 - notify_url: string; - // 公钥 - publicKey: Buffer; - // 私钥 - privateKey: Buffer; - // 可选参数 认证类型,目前为WECHATPAY2-SHA256-RSA2048 - authType?: string; - // 可选参数 User-Agent - userAgent?: string; - // 可选参数 APIv3密钥 - key?: string; -} - -/** - * 支付宝支付配置 - */ -export interface CoolAliPayConfig { - // 支付回调地址 - notifyUrl: string; - /** 应用ID */ - appId: string; - /** - * 应用私钥字符串 - * RSA签名验签工具:https://docs.open.alipay.com/291/106097) - * 密钥格式一栏请选择 “PKCS1(非JAVA适用)” - */ - privateKey: string; - signType?: 'RSA2' | 'RSA'; - /** 支付宝公钥(需要对返回值做验签时候必填) */ - alipayPublicKey?: string; - /** 网关 */ - gateway?: string; - /** 网关超时时间(单位毫秒,默认 5s) */ - timeout?: number; - /** 是否把网关返回的下划线 key 转换为驼峰写法 */ - camelcase?: boolean; - /** 编码(只支持 utf-8) */ - charset?: 'utf-8'; - /** api版本 */ - version?: '1.0'; - urllib?: any; - /** 指定private key类型, 默认: PKCS1, PKCS8: PRIVATE KEY, PKCS1: RSA PRIVATE KEY */ - keyType?: 'PKCS1' | 'PKCS8'; - /** 应用公钥证书文件路径 */ - appCertPath?: string; - /** 应用公钥证书文件内容 */ - appCertContent?: string | Buffer; - /** 应用公钥证书sn */ - appCertSn?: string; - /** 支付宝根证书文件路径 */ - alipayRootCertPath?: string; - /** 支付宝根证书文件内容 */ - alipayRootCertContent?: string | Buffer; - /** 支付宝根证书sn */ - alipayRootCertSn?: string; - /** 支付宝公钥证书文件路径 */ - alipayPublicCertPath?: string; - /** 支付宝公钥证书文件内容 */ - alipayPublicCertContent?: string | Buffer; - /** 支付宝公钥证书sn */ - alipayCertSn?: string; - /** AES密钥,调用AES加解密相关接口时需要 */ - encryptKey?: string; - /** 服务器地址 */ - wsServiceUrl?: string; -} diff --git a/packages/pay/src/package.json b/packages/pay/src/package.json deleted file mode 100644 index f679a33..0000000 --- a/packages/pay/src/package.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "name": "@cool-midway/pay", - "version": "6.0.0", - "description": "cool-js.com 支付 微信 支付宝", - "main": "index.js", - "typings": "index.d.ts", - "scripts": { - "build": "cross-env midway-bin build -c", - "test": "cross-env midway-bin test --ts", - "cov": "cross-env midway-bin cov --ts", - "lint": "mwts check", - "lint:fix": "mwts fix" - }, - "keywords": [ - "cool", - "cool-admin", - "cooljs" - ], - "author": "COOL", - "readme": "README.md", - "files": [ - "**/*.js", - "**/*.d.ts", - "index.d.ts" - ], - "license": "MIT", - "repository": { - "type": "git", - "url": "https://cool-js.com" - }, - "devDependencies": { - "@cool-midway/core": "^6.0.0", - "@midwayjs/cli": "^2.0.9", - "@midwayjs/core": "^3.9.0", - "@midwayjs/decorator": "^3.9.0", - "@midwayjs/mock": "^3.9.0", - "@types/jest": "^29.2.5", - "@types/node": "^18.11.18", - "cross-env": "^7.0.3", - "jest": "^29.3.1", - "mwts": "^1.3.0", - "ts-jest": "^29.0.3", - "typescript": "^4.9.4" - }, - "dependencies": { - "@4a/cid": "^0.1.0", - "alipay-sdk": "^3.2.0", - "wechatpay-node-v3": "^2.1.0" - } -} diff --git a/packages/pay/src/wx.ts b/packages/pay/src/wx.ts deleted file mode 100644 index 09c67fc..0000000 --- a/packages/pay/src/wx.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { CoolCommException } from '@cool-midway/core'; -import { Config, Init, Provide, Scope, ScopeEnum } from '@midwayjs/decorator'; -import * as cid from '@4a/cid'; -import { CoolWxPayConfig } from './interface'; -import WxPay = require('wechatpay-node-v3'); - -/** - * 微信支付 - */ -@Provide() -@Scope(ScopeEnum.Singleton) -export class CoolWxPay { - pay: WxPay; - - @Config('cool.pay.wx') - coolWxPay: CoolWxPayConfig; - - @Init() - async init() { - if (this.coolWxPay) this.pay = new WxPay(this.coolWxPay); - } - - /** - * 获得微信支付SDK实例 - * @returns - */ - getInstance(): WxPay { - return this.pay; - } - - /** - * 签名 - * @param params - * @returns - */ - async signVerify(ctx) { - if (!this.coolWxPay.key) { - throw new CoolCommException('未配置key(v3 API密钥)'); - } - const params = { - apiSecret: this.coolWxPay.key, // 如果在构造中传入了 key, 这里可以不传该值,否则需要传入该值 - body: ctx.request.body, // 请求体 body - signature: ctx.headers['wechatpay-signature'], - serial: ctx.headers['wechatpay-serial'], - nonce: ctx.headers['wechatpay-nonce'], - timestamp: ctx.headers['wechatpay-timestamp'], - }; - return await this.pay.verifySign(params); - } - - /** - * 创建订单 - * @param length 订单长度 - * @returns - */ - createOrderNum(length = 26) { - return cid(length); - } - - /** - * 动态配置支付参数 - * @param config 微信配置 - * @returns - */ - initPay(config: CoolWxPayConfig) { - return new WxPay(config); - } -} diff --git a/packages/pay/test/index.test.ts b/packages/pay/test/index.test.ts deleted file mode 100644 index a6c75a1..0000000 --- a/packages/pay/test/index.test.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { createLightApp } from '@midwayjs/mock'; -import * as custom from '../src'; - -describe('/test/index.test.ts', () => { - it('test component', async () => { - const app = await createLightApp('', { - imports: [ - custom - ] - }); - const bookService = await app.getApplicationContext().getAsync(custom.BookService); - expect(await bookService.getBookById()).toEqual('hello world'); - }); -}); diff --git a/packages/pay/tsconfig.json b/packages/pay/tsconfig.json deleted file mode 100644 index f01e1d2..0000000 --- a/packages/pay/tsconfig.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "compileOnSave": true, - "compilerOptions": { - "target": "es2018", - "module": "commonjs", - "moduleResolution": "node", - "experimentalDecorators": true, - "emitDecoratorMetadata": true, - "inlineSourceMap":false, - "noImplicitThis": true, - "noUnusedLocals": true, - "stripInternal": true, - "skipLibCheck": true, - "noImplicitReturns": false, - "pretty": true, - "declaration": true, - "outDir": "dist" - }, - "exclude": [ - "dist", - "node_modules", - "test" - ] -} diff --git a/packages/rpc/.editorconfig b/packages/rpc/.editorconfig deleted file mode 100644 index 4c7f8a8..0000000 --- a/packages/rpc/.editorconfig +++ /dev/null @@ -1,11 +0,0 @@ -# 🎨 editorconfig.org - -root = true - -[*] -charset = utf-8 -end_of_line = lf -indent_style = space -indent_size = 2 -trim_trailing_whitespace = true -insert_final_newline = true \ No newline at end of file diff --git a/packages/rpc/.eslintrc.json b/packages/rpc/.eslintrc.json deleted file mode 100644 index 0abd65a..0000000 --- a/packages/rpc/.eslintrc.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "extends": "./node_modules/mwts/", - "ignorePatterns": [ - "node_modules", - "dist", - "test", - "jest.config.js", - "typings", - "public/**/**", - "view/**/**" - ], - "env": { - "jest": true - }, - "rules": { - "@typescript-eslint/explicit-module-boundary-types": "off", - "@typescript-eslint/no-unused-vars": "off", - "@typescript-eslint/ban-ts-comment": "off", - "node/no-extraneous-import": "off", - "@typescript-eslint/no-this-alias": "off", - "no-empty": "off", - "node/no-extraneous-require": "off", - "eqeqeq": "off", - "node/no-unsupported-features/node-builtins": "off", - "@typescript-eslint/ban-types": "off", - "no-control-regex": "off", - "prefer-const": "off" - } -} \ No newline at end of file diff --git a/packages/rpc/.gitignore b/packages/rpc/.gitignore deleted file mode 100644 index 13bc3a6..0000000 --- a/packages/rpc/.gitignore +++ /dev/null @@ -1,15 +0,0 @@ -logs/ -npm-debug.log -yarn-error.log -node_modules/ -package-lock.json -yarn.lock -coverage/ -dist/ -.idea/ -run/ -.DS_Store -*.sw* -*.un~ -.tsbuildinfo -.tsbuildinfo.* diff --git a/packages/rpc/.prettierrc.js b/packages/rpc/.prettierrc.js deleted file mode 100644 index b964930..0000000 --- a/packages/rpc/.prettierrc.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - ...require('mwts/.prettierrc.json') -} diff --git a/packages/rpc/index.d.ts b/packages/rpc/index.d.ts deleted file mode 100644 index e0065de..0000000 --- a/packages/rpc/index.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -export * from './dist/index'; - -declare module '@midwayjs/core/dist/interface' { - interface MidwayConfig { - book?: PowerPartial<{ - a: number; - b: string; - }>; - } -} diff --git a/packages/rpc/jest.config.js b/packages/rpc/jest.config.js deleted file mode 100644 index 82a8b85..0000000 --- a/packages/rpc/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - preset: 'ts-jest', - testEnvironment: 'node', - testPathIgnorePatterns: ['/test/fixtures'], - coveragePathIgnorePatterns: ['/test/'], - setupFilesAfterEnv: ['./jest.setup.js'] -}; diff --git a/packages/rpc/jest.setup.js b/packages/rpc/jest.setup.js deleted file mode 100644 index 1399c91..0000000 --- a/packages/rpc/jest.setup.js +++ /dev/null @@ -1 +0,0 @@ -jest.setTimeout(30000); diff --git a/packages/rpc/package.json b/packages/rpc/package.json deleted file mode 100644 index 0b42cac..0000000 --- a/packages/rpc/package.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "name": "@cool-midway/rpc", - "version": "6.0.1", - "description": "cool-js.com rpc 微服务", - "main": "dist/index.js", - "typings": "index.d.ts", - "scripts": { - "build": "cross-env midway-bin build -c", - "test": "cross-env midway-bin test --ts", - "cov": "cross-env midway-bin cov --ts", - "lint": "mwts check", - "lint:fix": "mwts fix" - }, - "keywords": [], - "author": "", - "files": [ - "dist/**/*.js", - "dist/**/*.d.ts", - "index.d.ts" - ], - "repository": { - "type": "git", - "url": "https://cool-js.com" - }, - "license": "MIT", - "devDependencies": { - "@cool-midway/core": "^6.0.0", - "@midwayjs/cli": "^2.0.9", - "@midwayjs/core": "^3.9.0", - "@midwayjs/decorator": "^3.9.0", - "@midwayjs/mock": "^3.9.0", - "@midwayjs/redis": "^3.9.0", - "@midwayjs/typeorm": "^3.9.5", - "@types/jest": "^29.2.5", - "@types/node": "^18.11.18", - "cross-env": "^7.0.3", - "jest": "^29.3.1", - "lodash": "^4.17.21", - "mwts": "^1.3.0", - "ts-jest": "^29.0.3", - "typeorm": "^0.3.11", - "typescript": "^4.9.4" - }, - "dependencies": { - "ioredis": "4.28.5", - "moleculer": "^0.14.28" - } -} diff --git a/packages/rpc/src/config/config.default.ts b/packages/rpc/src/config/config.default.ts deleted file mode 100644 index a30c406..0000000 --- a/packages/rpc/src/config/config.default.ts +++ /dev/null @@ -1,6 +0,0 @@ -/** - * cool的配置 - */ -export default { - cool: {}, -}; diff --git a/packages/rpc/src/configuration.ts b/packages/rpc/src/configuration.ts deleted file mode 100644 index 16ae071..0000000 --- a/packages/rpc/src/configuration.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Configuration } from '@midwayjs/decorator'; -import * as DefaultConfig from './config/config.default'; -import { IMidwayContainer } from '@midwayjs/core'; -import { CoolRpc } from './rpc'; -import { CoolRpcDecorator } from './decorator'; - -@Configuration({ - namespace: 'cool:rpc', - importConfigs: [ - { - default: DefaultConfig, - }, - ], -}) -export class CoolRpcConfiguration { - async onReady(container: IMidwayContainer) { - global['moleculer.transactions'] = {}; - (await container.getAsync(CoolRpc)).init(); - // 装饰器 - await container.getAsync(CoolRpcDecorator); - } - - async onStop(container: IMidwayContainer): Promise { - (await container.getAsync(CoolRpc)).stop(); - } -} diff --git a/packages/rpc/src/decorator/event/event.ts b/packages/rpc/src/decorator/event/event.ts deleted file mode 100644 index 526e11e..0000000 --- a/packages/rpc/src/decorator/event/event.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { - Scope, - ScopeEnum, - saveClassMetadata, - saveModule, -} from '@midwayjs/decorator'; - -export const COOL_RPC_EVENT_KEY = 'decorator:cool:rpc:event'; - -export function CoolRpcEvent(): ClassDecorator { - return (target: any) => { - // 将装饰的类,绑定到该装饰器,用于后续能获取到 class - saveModule(COOL_RPC_EVENT_KEY, target); - // 保存一些元数据信息,任意你希望存的东西 - saveClassMetadata(COOL_RPC_EVENT_KEY, {}, target); - // 指定 IoC 容器创建实例的作用域 - Scope(ScopeEnum.Singleton)(target); - }; -} diff --git a/packages/rpc/src/decorator/event/handler.ts b/packages/rpc/src/decorator/event/handler.ts deleted file mode 100644 index e5a8328..0000000 --- a/packages/rpc/src/decorator/event/handler.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { attachClassMetadata } from '@midwayjs/decorator'; - -export const COOL_RPC_EVENT_HANDLER_KEY = 'decorator:cool:rpc:event:handler'; - -/** - * 事件 - * @param eventName 事件名称 - * @returns - */ -export function CoolRpcEventHandler(eventName?: string): MethodDecorator { - return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => { - // 将装饰的类,绑定到该装饰器,用于后续能获取到 class - attachClassMetadata( - COOL_RPC_EVENT_HANDLER_KEY, - { - propertyKey, - descriptor, - eventName, - }, - target - ); - }; -} diff --git a/packages/rpc/src/decorator/index.ts b/packages/rpc/src/decorator/index.ts deleted file mode 100644 index 3299815..0000000 --- a/packages/rpc/src/decorator/index.ts +++ /dev/null @@ -1,101 +0,0 @@ -import { CoolCommException } from '@cool-midway/core'; -import { - Provide, - Scope, - ScopeEnum, - JoinPoint, - Init, - MidwayDecoratorService, - Inject, -} from '@midwayjs/core'; -import { TypeORMDataSourceManager } from '@midwayjs/typeorm'; -import { COOL_RPC_TRANSACTION, TransactionOptions } from './transaction'; -import { v1 as uuid } from 'uuid'; - -/** - * 装饰器 - */ -@Provide() -@Scope(ScopeEnum.Singleton) -export class CoolRpcDecorator { - @Inject() - decoratorService: MidwayDecoratorService; - - @Inject() - typeORMDataSourceManager: TypeORMDataSourceManager; - - @Init() - async init() { - // 事务 - await this.transaction(); - } - - /** - * 事务 - */ - async transaction() { - this.decoratorService.registerMethodHandler( - COOL_RPC_TRANSACTION, - options => { - return { - around: async (joinPoint: JoinPoint) => { - const option: TransactionOptions = options.metadata; - let isCaller = false; - let rpcTransactionId; - if (joinPoint.args[0]) { - isCaller = false; - rpcTransactionId = joinPoint.args[0].rpcTransactionId; - } - // 如果没有事务ID,手动创建 - if (!rpcTransactionId) { - isCaller = true; - rpcTransactionId = uuid(); - } - - let data; - const dataSource = this.typeORMDataSourceManager.getDataSource( - option?.connectionName || 'default' - ); - const queryRunner = dataSource.createQueryRunner(); - // 使用我们的新queryRunner建立真正的数据库连 - await queryRunner.connect(); - if (option && option.isolation) { - await queryRunner.startTransaction(option.isolation); - } else { - await queryRunner.startTransaction(); - } - - try { - global['moleculer.transactions'][rpcTransactionId] = queryRunner; - // 半小时后清除 - setTimeout(() => { - global['moleculer.transactions'][rpcTransactionId].release(); - delete global['moleculer.transactions'][rpcTransactionId]; - }, 1800 * 1000); - joinPoint.args.push(rpcTransactionId); - joinPoint.args.push(queryRunner); - data = await joinPoint.proceed(...joinPoint.args); - if (isCaller) { - global['moleculer:broker'].broadcast('moleculer.transaction', { - rpcTransactionId, - commit: true, - }); - } - //await queryRunner.commitTransaction(); - } catch (error) { - //await queryRunner.rollbackTransaction(); - if (isCaller) { - global['moleculer:broker'].broadcast('moleculer.transaction', { - rpcTransactionId, - commit: false, - }); - } - throw new CoolCommException(error.message); - } - return data; - }, - }; - } - ); - } -} diff --git a/packages/rpc/src/decorator/rpc.ts b/packages/rpc/src/decorator/rpc.ts deleted file mode 100644 index 8e91b4b..0000000 --- a/packages/rpc/src/decorator/rpc.ts +++ /dev/null @@ -1,84 +0,0 @@ -import { - Scope, - ScopeEnum, - saveClassMetadata, - saveModule, -} from '@midwayjs/decorator'; - -export const MOLECYLER_KEY = 'decorator:cool:rpc'; - -export type MethodTypes = - | 'add' - | 'delete' - | 'update' - | 'page' - | 'info' - | 'list'; - -// 字段匹配 -export interface FieldEq { - // 字段 - column: string; - // 请求参数 - requestParam: string; -} - -// 关联查询 -export interface LeftJoinOp { - // 实体 - entity: any; - // 别名 - alias: string; - // 关联条件 - condition: string; -} - -// Crud配置 -export interface CurdOption { - // 路由前缀,不配置默认是按Controller下的文件夹路径 - prefix?: string; - // curd api接口 - method: MethodTypes[]; - // 分页查询配置 - pageQueryOp?: QueryOp; - // 非分页查询配置 - listQueryOp?: QueryOp; - // 插入参数 - insertParam?: Function; - // info 忽略返回属性 - infoIgnoreProperty?: string[]; - // 实体 - entity: { entityKey?: any; connectionName?: string } | any; -} - -// 查询配置 -export interface QueryOp { - // 需要模糊查询的字段 - keyWordLikeFields?: string[]; - // 查询条件 - where?: Function; - // 查询字段 - select?: string[]; - // 字段相等 - fieldEq?: string[] | FieldEq[]; - // 添加排序条件 - addOrderBy?: {}; - // 关联配置 - leftJoin?: LeftJoinOp[]; -} - -/** - * moleculer 微服务配置 - * @param option - * @returns - */ -export function CoolRpcService(option?: CurdOption): ClassDecorator { - return (target: any) => { - // 将装饰的类,绑定到该装饰器,用于后续能获取到 class - saveModule(MOLECYLER_KEY, target); - // 保存一些元数据信息,任意你希望存的东西 - saveClassMetadata(MOLECYLER_KEY, option, target); - // 指定 IoC 容器创建实例的作用域,这里注册为请求作用域,这样能取到 ctx - Scope(ScopeEnum.Request)(target); - }; -} diff --git a/packages/rpc/src/decorator/transaction.ts b/packages/rpc/src/decorator/transaction.ts deleted file mode 100644 index 93cc5ca..0000000 --- a/packages/rpc/src/decorator/transaction.ts +++ /dev/null @@ -1,22 +0,0 @@ -import * as _ from 'lodash'; -import { createCustomMethodDecorator } from '@midwayjs/core'; - -type IsolationLevel = - | 'READ UNCOMMITTED' - | 'READ COMMITTED' - | 'REPEATABLE READ' - | 'SERIALIZABLE'; - -export interface TransactionOptions { - connectionName?: string; - isolation?: IsolationLevel; -} - -// 装饰器内部的唯一 id -export const COOL_RPC_TRANSACTION = 'decorator:cool_rpc_transaction'; - -export function CoolRpcTransaction( - option?: TransactionOptions -): MethodDecorator { - return createCustomMethodDecorator(COOL_RPC_TRANSACTION, option); -} diff --git a/packages/rpc/src/index.ts b/packages/rpc/src/index.ts deleted file mode 100644 index 4d68d39..0000000 --- a/packages/rpc/src/index.ts +++ /dev/null @@ -1,25 +0,0 @@ -export { CoolRpcConfiguration as Configuration } from './configuration'; - -export * from './test'; -export * from './rpc'; -export * from './decorator/rpc'; -export * from './decorator/event/event'; -export * from './decorator/event/handler'; -export * from './service/base'; -export * from './decorator/transaction'; -export * from './transaction/event'; -export * from './decorator/index'; - -export interface CoolRpcConfig { - // 服务名称 - name: string; - // redis - redis: RedisConfig & RedisConfig[] & unknown; -} - -export interface RedisConfig { - host: string; - password: string; - port: number; - db: number; -} diff --git a/packages/rpc/src/package.json b/packages/rpc/src/package.json deleted file mode 100644 index 0d762c0..0000000 --- a/packages/rpc/src/package.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "name": "@cool-midway/rpc", - "version": "6.0.1", - "description": "cool-js.com rpc 微服务", - "main": "index.js", - "typings": "index.d.ts", - "scripts": { - "build": "cross-env midway-bin build -c", - "test": "cross-env midway-bin test --ts", - "cov": "cross-env midway-bin cov --ts", - "lint": "mwts check", - "lint:fix": "mwts fix" - }, - "keywords": [], - "author": "", - "files": [ - "**/*.js", - "**/*.d.ts", - "index.d.ts" - ], - "repository": { - "type": "git", - "url": "https://cool-js.com" - }, - "license": "MIT", - "devDependencies": { - "@cool-midway/core": "^6.0.0", - "@midwayjs/cli": "^2.0.9", - "@midwayjs/core": "^3.9.0", - "@midwayjs/decorator": "^3.9.0", - "@midwayjs/mock": "^3.9.0", - "@midwayjs/redis": "^3.9.0", - "@midwayjs/typeorm": "^3.9.5", - "@types/jest": "^29.2.5", - "@types/node": "^18.11.18", - "cross-env": "^7.0.3", - "jest": "^29.3.1", - "lodash": "^4.17.21", - "mwts": "^1.3.0", - "ts-jest": "^29.0.3", - "typeorm": "^0.3.11", - "typescript": "^4.9.4" - }, - "dependencies": { - "ioredis": "4.28.5", - "moleculer": "^0.14.28" - } -} diff --git a/packages/rpc/src/rpc.ts b/packages/rpc/src/rpc.ts deleted file mode 100644 index 597e88b..0000000 --- a/packages/rpc/src/rpc.ts +++ /dev/null @@ -1,275 +0,0 @@ -import { ILogger, IMidwayApplication, Inject } from '@midwayjs/core'; -import { - App, - Config, - getClassMetadata, - listModule, - Logger, - Provide, - Scope, - ScopeEnum, -} from '@midwayjs/decorator'; -import { ServiceBroker } from 'moleculer'; -import { CoolRpcConfig } from '.'; -import { CoolCoreException, CoolValidateException } from '@cool-midway/core'; -import { camelCase } from '@midwayjs/core/dist/util/camelCase'; -import { v1 as uuid } from 'uuid'; -import { BaseRpcService } from './service/base'; -import { CurdOption, MOLECYLER_KEY } from './decorator/rpc'; -import { COOL_RPC_EVENT_KEY } from './decorator/event/event'; -import { COOL_RPC_EVENT_HANDLER_KEY } from './decorator/event/handler'; -import * as _ from 'lodash'; -import { TypeORMDataSourceManager } from '@midwayjs/typeorm'; -// import { AgentService } from '@moleculer/lab'; - -/** - * 微服务 - */ -@Provide() -@Scope(ScopeEnum.Singleton) -export class CoolRpc { - broker: ServiceBroker; - - @Inject() - typeORMDataSourceManager: TypeORMDataSourceManager; - - @Logger() - coreLogger: ILogger; - - @Config('cool.rpc') - rpcConfig: CoolRpcConfig; - - @Config('cool') - coolConfig; - - @App() - app: IMidwayApplication; - - cruds; - - async init() { - if (!this.rpcConfig?.name) { - throw new CoolCoreException( - 'cool.rpc.name config is require and every service name must be unique' - ); - } - - let redisConfig; - - if (!this.rpcConfig?.redis && !this.coolConfig?.redis) { - throw new CoolCoreException('cool.rpc.redis or cool.redis is require'); - } - - redisConfig = this.rpcConfig?.redis - ? this.rpcConfig?.redis - : this.coolConfig?.redis; - - const transporter = { - type: 'Redis', - options: {}, - }; - if (redisConfig instanceof Array) { - transporter.options = { - cluster: { - nodes: redisConfig, - }, - }; - } else { - transporter.options = redisConfig; - } - - this.broker = new ServiceBroker({ - nodeID: `${this.rpcConfig.name}-${uuid()}`, - transporter, - // metrics: { - // enabled: true, - // reporter: 'Laboratory', - // }, - // tracing: { - // enabled: true, - // exporter: 'Laboratory', - // }, - ...this.rpcConfig, - }); - - // this.broker.createService({ - // name: this.rpcConfig.name, - // mixins: [], - // // settings: { - // // name: 'test', - // // port: 3210, - // // token: '123123', - // // apiKey: '92C18ZR-ERM45EG-HT8GQGQ-4MHCXAT', - // // }, - // }); - - global['moleculer:broker'] = this.broker; - - await this.initService(); - await this.createService(); - } - - /** - * 获得事件 - * @returns - */ - async getEvents() { - const allEvents = {}; - const modules = listModule(COOL_RPC_EVENT_KEY); - for (const module of modules) { - const moduleInstance = await this.app - .getApplicationContext() - .getAsync(module); - moduleInstance['broker'] = this.broker; - const events = getClassMetadata(COOL_RPC_EVENT_HANDLER_KEY, module); - for (const event of events) { - allEvents[event.eventName ? event.eventName : event.propertyKey] = { - handler(ctx) { - moduleInstance[event.propertyKey](ctx.params); - }, - }; - } - } - return allEvents; - } - - /** - * 创建服务 - */ - async createService() { - const _this = this; - this.broker.createService({ - name: this.rpcConfig.name, - events: await this.getEvents(), - actions: { - async call(ctx) { - const { service, method, params } = ctx.params; - const targetName = _.upperFirst(service); - const target = _.find(_this.cruds, { name: targetName }); - if (!target) { - throw new CoolValidateException('找不到服务'); - } - const curdOption: CurdOption = getClassMetadata( - MOLECYLER_KEY, - target - ); - - const cls = await _this.app - .getApplicationContext() - .getAsync(camelCase(service)); - const serviceInstance: BaseRpcService = new target(); - Object.assign(serviceInstance, cls); - serviceInstance.setModel(_this.getModel(curdOption)); - serviceInstance.setApp(_this.app); - serviceInstance.init(); - - // 如果是通用crud方法 注入参数 - if ( - ['add', 'delete', 'update', 'page', 'info', 'list'].includes(method) - ) { - if (!curdOption.method.includes(method)) { - throw new CoolValidateException('方法不存在'); - } - } - return serviceInstance[method](params); - }, - }, - }); - this.broker.start(); - } - - /** - * 初始化service,设置entity - */ - async initService() { - // 获得所有的service - this.cruds = listModule(MOLECYLER_KEY); - for (const crud of this.cruds) { - const curdOption: CurdOption = getClassMetadata(MOLECYLER_KEY, crud); - const serviceInstance: BaseRpcService = await this.app - .getApplicationContext() - .getAsync(crud); - serviceInstance.setModel(this.getModel(curdOption)); - serviceInstance.setCurdOption(curdOption); - } - } - - /** - * 获得Model - * @param curdOption - */ - getModel(curdOption) { - // 获得到model - let entityModel; - const { entity } = curdOption || {}; - if (entity) { - const dataSourceName = - this.typeORMDataSourceManager.getDataSourceNameByModel(entity); - entityModel = this.typeORMDataSourceManager - .getDataSource(dataSourceName) - .getRepository(entity); - } - return entityModel; - } - - /** - * 调用服务 - * @param name 服务名称 - * @param controller 接口服务 - * @param method 方法 - * @param params 参数 - * @returns - */ - async call(name: string, service: string, method: string, params?: {}) { - return this.broker.call(`${name}.call`, { service, method, params }); - } - - /** - * 发送事件 - * @param name 事件名称 - * @param params 事件参数 - * @param node 节点名称 - */ - async event(name: string, params: any, node?: string | string[]) { - this.broker.emit(name, params); - } - - /** - * 发送广播事件 - * @param name - * @param params - * @param node 节点名称 - */ - async broadcastEvent(name: string, params: any, node?: string | string[]) { - this.broker.broadcast(name, params); - } - - /** - * 发送本地广播事件 - * @param name - * @param params - * @param node 节点名称 - */ - async broadcastLocalEvent( - name: string, - params: any, - node?: string | string[] - ) { - this.broker.broadcastLocal(name, params); - } - - /** - * 获得原始的broker对象 - * @returns - */ - getBroker() { - return this.broker; - } - - /** - * 停止 - */ - stop() { - this.broker.stop(); - } -} diff --git a/packages/rpc/src/service/base.ts b/packages/rpc/src/service/base.ts deleted file mode 100644 index 8d0abf3..0000000 --- a/packages/rpc/src/service/base.ts +++ /dev/null @@ -1,406 +0,0 @@ -import { Config, Init, Provide, App } from '@midwayjs/decorator'; -import { Brackets } from 'typeorm'; -import * as _ from 'lodash'; -import { CoolValidateException, ERRINFO } from '@cool-midway/core'; -import { QueryOp } from '../decorator/rpc'; -import { IMidwayApplication, Inject } from '@midwayjs/core'; -import * as SqlString from 'sqlstring'; -import { TypeORMDataSourceManager } from '@midwayjs/typeorm'; - -/** - * 服务基类 - */ -@Provide() -export abstract class BaseRpcService { - // 分页配置 - @Config('cool.page') - private conf; - - // 模型 - protected entity; - - protected sqlParams; - - protected curdOption; - - @Inject() - typeORMDataSourceManager: TypeORMDataSourceManager; - - // 设置模型 - setModel(entity: any) { - this.entity = entity; - } - - setCurdOption(curdOption) { - this.curdOption = curdOption; - } - - @App() - app: IMidwayApplication; - - setApp(app) { - this.app = app; - } - - // 初始化 - @Init() - init() { - this.sqlParams = []; - } - - /** - * 检查排序 - * @param sort 排序 - * @returns - */ - private checkSort(sort) { - if (!['desc', 'asc'].includes(sort.toLowerCase())) { - throw new CoolValidateException('sort 非法传参~'); - } - return sort; - } - - /** - * 获得单个ID - * @param params 参数 - */ - async info(params: any): Promise { - const { id } = params; - if (!this.entity) throw new CoolValidateException(ERRINFO.NOENTITY); - if (!id) { - throw new CoolValidateException(ERRINFO.NOID); - } - const info = await this.entity.findOne({ id }); - if (info && this.curdOption.infoIgnoreProperty) { - for (const property of this.curdOption.infoIgnoreProperty) { - delete info[property]; - } - } - return info; - } - - /** - * 执行SQL并获得分页数据 - * @param sql 执行的sql语句 - * @param query 分页查询条件 - * @param autoSort 是否自动排序 - * @param connectionName 连接名称 - */ - async sqlRenderPage(sql, query, autoSort = false, connectionName?) { - const { - size = this.conf.size, - page = 1, - order = 'createTime', - sort = 'desc', - isExport = false, - maxExportLimit, - } = query; - if (order && sort && !autoSort) { - if (!(await this.paramSafetyCheck(order + sort))) { - throw new CoolValidateException('非法传参~'); - } - sql += ` ORDER BY ${SqlString.escapeId(order)} ${this.checkSort(sort)}`; - } - if (isExport && maxExportLimit > 0) { - this.sqlParams.push(parseInt(maxExportLimit)); - sql += ' LIMIT ? '; - } - if (!isExport) { - this.sqlParams.push((page - 1) * size); - this.sqlParams.push(parseInt(size)); - sql += ' LIMIT ?,? '; - } - - let params = []; - params = params.concat(this.sqlParams); - const result = await this.nativeQuery(sql, params, connectionName); - const countResult = await this.nativeQuery( - this.getCountSql(sql), - params, - connectionName - ); - return { - list: result, - pagination: { - page: parseInt(page), - size: parseInt(size), - total: parseInt(countResult[0] ? countResult[0].count : 0), - }, - }; - } - - /** - * 设置sql - * @param condition 条件是否成立 - * @param sql sql语句 - * @param params 参数 - */ - setSql(condition, sql, params) { - let rSql = false; - if (condition || (condition === 0 && condition !== '')) { - rSql = true; - this.sqlParams = this.sqlParams.concat(params); - } - return rSql ? sql : ''; - } - - /** - * 获得查询个数的SQL - * @param sql - */ - getCountSql(sql) { - sql = sql.replace('LIMIT ', 'limit '); - return `select count(*) as count from (${ - sql.replace(new RegExp('\n', 'gm'), ' ').split('limit ')[0] - }) a`; - } - - /** - * 参数安全性检查 - * @param params - */ - async paramSafetyCheck(params) { - const lp = params.toLowerCase(); - return !( - lp.indexOf('update ') > -1 || - lp.indexOf('select ') > -1 || - lp.indexOf('delete ') > -1 || - lp.indexOf('insert ') > -1 - ); - } - - /** - * 原生查询 - * @param sql - * @param params - * @param connectionName - */ - async nativeQuery(sql, params?, connectionName?) { - if (_.isEmpty(params)) { - params = this.sqlParams; - } - let newParams = []; - newParams = newParams.concat(params); - this.sqlParams = []; - return await this.getOrmManager(connectionName).query(sql, newParams || []); - } - - /** - * 获得ORM管理 - * @param connectionName 连接名称 - */ - getOrmManager(connectionName = 'default') { - return this.typeORMDataSourceManager.getDataSource(connectionName); - } - - /** - * 非分页查询 - * @param params 查询条件 - */ - async list(params?): Promise { - if (!this.entity) throw new CoolValidateException(ERRINFO.NOENTITY); - const sql = await this.getOptionFind(params, this.curdOption.listQueryOp); - return this.nativeQuery(sql, []); - } - - /** - * 删除 - * @param params 参数 - */ - async delete(params: any | string) { - const { ids } = params; - if (!this.entity) throw new CoolValidateException(ERRINFO.NOENTITY); - if (ids instanceof Array) { - await this.entity.delete(ids); - } else { - await this.entity.delete(ids.split(',')); - } - await this.modifyAfter(ids); - } - - /** - * 新增|修改 - * @param params 数据 - */ - async addOrUpdate(params: any) { - if (!this.entity) throw new CoolValidateException(ERRINFO.NOENTITY); - await this.entity.save(params); - } - - /** - * 新增 - * @param param 数据 - */ - async add(params: any): Promise { - if (!this.entity) throw new CoolValidateException(ERRINFO.NOENTITY); - await this.addOrUpdate(params); - await this.modifyAfter(params); - return { - id: params.id, - }; - } - - /** - * 修改 - * @param param 数据 - */ - async update(params: any) { - if (!this.entity) throw new CoolValidateException(ERRINFO.NOENTITY); - if (!params.id) throw new CoolValidateException(ERRINFO.NOID); - await this.addOrUpdate(params); - await this.modifyAfter(params); - } - - /** - * 新增|修改|删除 之后的操作 - * @param data 对应数据 - */ - async modifyAfter(data: any): Promise {} - - /** - * 分页查询 - * @param params 查询条件 - */ - async page(params?) { - if (!this.entity) throw new CoolValidateException(ERRINFO.NOENTITY); - const sql = await this.getOptionFind(params, this.curdOption.pageQueryOp); - return this.sqlRenderPage(sql, params, true); - } - - /** - * query - * @param data - * @param query - */ - renderPage(data, query) { - const { size = this.conf.size, page = 1 } = query; - return { - list: data[0], - pagination: { - page: parseInt(page), - size: parseInt(size), - total: data[1], - }, - }; - } - - /** - * 构建查询配置 - * @param query 前端查询 - * @param option - */ - private async getOptionFind(query, option: QueryOp) { - let { order = 'createTime', sort = 'desc', keyWord = '' } = query || {}; - let sqlArr = ['SELECT']; - let selects = ['a.*']; - let find = this.entity.createQueryBuilder('a'); - if (option) { - // 判断是否有关联查询,有的话取个别名 - if (!_.isEmpty(option.leftJoin)) { - for (const item of option.leftJoin) { - selects.push(`${item.alias}.*`); - find.leftJoin(item.entity, item.alias, item.condition); - } - } - // 默认条件 - if (option.where) { - const wheres = await option.where(query, this.app); - if (!_.isEmpty(wheres)) { - for (const item of wheres) { - if ( - item.length == 2 || - (item.length == 3 && - (item[2] || (item[2] === 0 && item[2] != ''))) - ) { - for (const key in item[1]) { - this.sqlParams.push(item[1][key]); - } - find.andWhere(item[0], item[1]); - } - } - } - } - // 附加排序 - if (!_.isEmpty(option.addOrderBy)) { - for (const key in option.addOrderBy) { - find.addOrderBy( - SqlString.escapeId(key), - this.checkSort(option.addOrderBy[key].toUpperCase()) - ); - } - } - // 关键字模糊搜索 - if (keyWord) { - keyWord = `%${keyWord}%`; - find.andWhere( - new Brackets(qb => { - const keyWordLikeFields = option.keyWordLikeFields; - for (let i = 0; i < option.keyWordLikeFields?.length || 0; i++) { - qb.orWhere(`${keyWordLikeFields[i]} like :keyWord`, { - keyWord, - }); - this.sqlParams.push(keyWord); - } - }) - ); - } - // 筛选字段 - if (!_.isEmpty(option.select)) { - sqlArr.push(option.select.join(',')); - find.select(option.select); - } else { - sqlArr.push(selects.join(',')); - } - // 字段全匹配 - if (!_.isEmpty(option.fieldEq)) { - for (const key of option.fieldEq) { - const c = {}; - // 单表字段无别名的情况下操作 - if (typeof key === 'string') { - if (query[key] || query[key] == 0) { - c[key] = query[key]; - const eq = query[key] instanceof Array ? 'in' : '='; - if (eq === 'in') { - find.andWhere(`${key} ${eq} (:${key})`, c); - } else { - find.andWhere(`${key} ${eq} :${key}`, c); - } - this.sqlParams.push(query[key]); - } - } else { - if (query[key.column] || query[key.column] == 0) { - c[key.column] = query[key.column]; - const eq = query[key.column] instanceof Array ? 'in' : '='; - if (eq === 'in') { - find.andWhere(`${key.column} ${eq} (:${key.column})`, c); - } else { - find.andWhere(`${key.column} ${eq} :${key.column}`, c); - } - this.sqlParams.push(query[key.column]); - } - } - } - } - } else { - sqlArr.push(selects.join(',')); - } - // 接口请求的排序 - if (sort && order) { - const sorts = sort.toUpperCase().split(','); - const orders = order.split(','); - if (sorts.length != orders.length) { - throw new CoolValidateException(ERRINFO.SORTFIELD); - } - for (const i in sorts) { - find.addOrderBy( - SqlString.escapeId(orders[i]), - this.checkSort(sorts[i]) - ); - } - } - const sqls = find.getSql().split('FROM'); - sqlArr.push('FROM'); - sqlArr.push(sqls[1]); - return sqlArr.join(' '); - } -} diff --git a/packages/rpc/src/test.ts b/packages/rpc/src/test.ts deleted file mode 100644 index d15b931..0000000 --- a/packages/rpc/src/test.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Controller, Inject, Post, Provide } from '@midwayjs/decorator'; -import { BaseController } from '@cool-midway/core'; -import { CoolRpc } from './rpc'; - -/** - * 本地开发调试 - */ -@Provide() -@Controller('/rpc') -export class RpcTestController extends BaseController { - @Inject() - rpc: CoolRpc; - - @Inject() - ctx; - - /** - * 测试 - */ - @Post('/test') - async test() { - const { name, service, method, params } = this.ctx.request.body; - return this.rpc.call(name, service, method, params); - } -} diff --git a/packages/rpc/src/transaction/event.ts b/packages/rpc/src/transaction/event.ts deleted file mode 100644 index c81cf6c..0000000 --- a/packages/rpc/src/transaction/event.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { Logger, Provide, Scope, ScopeEnum } from '@midwayjs/decorator'; -import { CoolRpcEvent, CoolRpcEventHandler } from '..'; -import { ILogger } from '@midwayjs/logger'; - -/** - * moleculer 事件处理 - */ -@Provide() -@Scope(ScopeEnum.Singleton) -@CoolRpcEvent() -export class MoleculerTransactionHandler { - @Logger() - coreLogger: ILogger; - - /** - * 注册事件 - * @param params - */ - @CoolRpcEventHandler('moleculer.transaction') // 唯一参数,eventName,事件名,可不填,默认为方法名 - async handler(params) { - const { rpcTransactionId, commit } = params; - this.coreLogger.info( - `\x1B[36m [cool:core] MoleculerTransaction event params: ${JSON.stringify( - params - )} \x1B[0m` - ); - if (global['moleculer.transactions'][rpcTransactionId]) { - this.coreLogger.info( - `\x1B[36m [cool:core] MoleculerTransaction event ${ - commit ? 'commitTransaction' : 'rollbackTransaction' - } ID: ${rpcTransactionId} \x1B[0m` - ); - await global['moleculer.transactions'][rpcTransactionId][ - commit ? 'commitTransaction' : 'rollbackTransaction' - ](); - await global['moleculer.transactions'][rpcTransactionId].release(); - delete global['moleculer.transactions'][rpcTransactionId]; - } - } -} diff --git a/packages/rpc/test/index.test.ts b/packages/rpc/test/index.test.ts deleted file mode 100644 index a6c75a1..0000000 --- a/packages/rpc/test/index.test.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { createLightApp } from '@midwayjs/mock'; -import * as custom from '../src'; - -describe('/test/index.test.ts', () => { - it('test component', async () => { - const app = await createLightApp('', { - imports: [ - custom - ] - }); - const bookService = await app.getApplicationContext().getAsync(custom.BookService); - expect(await bookService.getBookById()).toEqual('hello world'); - }); -}); diff --git a/packages/rpc/tsconfig.json b/packages/rpc/tsconfig.json deleted file mode 100644 index f01e1d2..0000000 --- a/packages/rpc/tsconfig.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "compileOnSave": true, - "compilerOptions": { - "target": "es2018", - "module": "commonjs", - "moduleResolution": "node", - "experimentalDecorators": true, - "emitDecoratorMetadata": true, - "inlineSourceMap":false, - "noImplicitThis": true, - "noUnusedLocals": true, - "stripInternal": true, - "skipLibCheck": true, - "noImplicitReturns": false, - "pretty": true, - "declaration": true, - "outDir": "dist" - }, - "exclude": [ - "dist", - "node_modules", - "test" - ] -} diff --git a/packages/sms/.editorconfig b/packages/sms/.editorconfig deleted file mode 100644 index 4c7f8a8..0000000 --- a/packages/sms/.editorconfig +++ /dev/null @@ -1,11 +0,0 @@ -# 🎨 editorconfig.org - -root = true - -[*] -charset = utf-8 -end_of_line = lf -indent_style = space -indent_size = 2 -trim_trailing_whitespace = true -insert_final_newline = true \ No newline at end of file diff --git a/packages/sms/.eslintrc.json b/packages/sms/.eslintrc.json deleted file mode 100644 index aad9755..0000000 --- a/packages/sms/.eslintrc.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "extends": "./node_modules/mwts/", - "ignorePatterns": [ - "node_modules", - "dist", - "test", - "jest.config.js", - "typings", - "public/**/**", - "view/**/**" - ], - "env": { - "jest": true - }, - "rules": { - "@typescript-eslint/explicit-module-boundary-types": "off", - "@typescript-eslint/no-unused-vars": "off", - "@typescript-eslint/ban-ts-comment": "off", - "node/no-extraneous-import": "off", - "no-empty": "off", - "node/no-extraneous-require": "off", - "eqeqeq": "off", - "node/no-unsupported-features/node-builtins": "off", - "@typescript-eslint/ban-types": "off", - "no-control-regex": "off", - "prefer-const": "off" - } -} \ No newline at end of file diff --git a/packages/sms/.gitignore b/packages/sms/.gitignore deleted file mode 100644 index 13bc3a6..0000000 --- a/packages/sms/.gitignore +++ /dev/null @@ -1,15 +0,0 @@ -logs/ -npm-debug.log -yarn-error.log -node_modules/ -package-lock.json -yarn.lock -coverage/ -dist/ -.idea/ -run/ -.DS_Store -*.sw* -*.un~ -.tsbuildinfo -.tsbuildinfo.* diff --git a/packages/sms/.prettierrc.js b/packages/sms/.prettierrc.js deleted file mode 100644 index b964930..0000000 --- a/packages/sms/.prettierrc.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - ...require('mwts/.prettierrc.json') -} diff --git a/packages/sms/index.d.ts b/packages/sms/index.d.ts deleted file mode 100644 index e0065de..0000000 --- a/packages/sms/index.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -export * from './dist/index'; - -declare module '@midwayjs/core/dist/interface' { - interface MidwayConfig { - book?: PowerPartial<{ - a: number; - b: string; - }>; - } -} diff --git a/packages/sms/jest.config.js b/packages/sms/jest.config.js deleted file mode 100644 index 82a8b85..0000000 --- a/packages/sms/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - preset: 'ts-jest', - testEnvironment: 'node', - testPathIgnorePatterns: ['/test/fixtures'], - coveragePathIgnorePatterns: ['/test/'], - setupFilesAfterEnv: ['./jest.setup.js'] -}; diff --git a/packages/sms/jest.setup.js b/packages/sms/jest.setup.js deleted file mode 100644 index 1399c91..0000000 --- a/packages/sms/jest.setup.js +++ /dev/null @@ -1 +0,0 @@ -jest.setTimeout(30000); diff --git a/packages/sms/package.json b/packages/sms/package.json deleted file mode 100644 index 7ea0c13..0000000 --- a/packages/sms/package.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "name": "@cool-midway/sms", - "version": "6.0.1", - "description": "cool-js.com 短信", - "main": "dist/index.js", - "typings": "index.d.ts", - "scripts": { - "build": "cross-env midway-bin build -c", - "test": "cross-env midway-bin test --ts", - "cov": "cross-env midway-bin cov --ts", - "lint": "mwts check", - "lint:fix": "mwts fix" - }, - "keywords": [ - "cool", - "cool-admin", - "cooljs" - ], - "author": "COOL", - "readme": "README.md", - "files": [ - "dist/**/*.js", - "dist/**/*.d.ts", - "index.d.ts" - ], - "license": "MIT", - "repository": { - "type": "git", - "url": "https://cool-js.com" - }, - "devDependencies": { - "@cool-midway/core": "^6.0.0", - "@midwayjs/cli": "^2.0.9", - "@midwayjs/core": "^3.9.0", - "@midwayjs/decorator": "^3.9.0", - "@midwayjs/mock": "^3.9.0", - "@types/jest": "^29.2.5", - "@types/node": "^18.11.18", - "cross-env": "^7.0.3", - "jest": "^29.3.1", - "mwts": "^1.3.0", - "ts-jest": "^29.0.3", - "typescript": "^4.9.4" - }, - "dependencies": { - "@alicloud/pop-core": "^1.7.13", - "tencentcloud-sdk-nodejs": "^4.0.607" - } -} diff --git a/packages/sms/src/ali.ts b/packages/sms/src/ali.ts deleted file mode 100644 index a2f4e6f..0000000 --- a/packages/sms/src/ali.ts +++ /dev/null @@ -1,64 +0,0 @@ -import * as Core from '@alicloud/pop-core'; -import { Config, Provide } from "@midwayjs/core"; -import { CoolSmsAliConfig } from './interface'; -import { CoolCommException } from '@cool-midway/core'; - -/** - * 阿里云短信 - */ -@Provide() -export class SmsAli { - @Config('cool.sms.ali') - config: CoolSmsAliConfig; - - /** - * 配置 - * @param config - */ - setConfig(config: CoolSmsAliConfig) { - this.config = config; - } - - /** - * 发送短信 - * @param phone 手机号 - * @param params 参数 - * @param config signName 签名 template 模板 - * @returns - */ - async send(phone, params: { - [key: string]: string; - }, config?: { - signName: string; - template: string; - }) { - const { accessKeyId, accessKeySecret } = this.config; - if (!accessKeyId || !accessKeyId) { - throw new CoolCommException('请配置阿里云短信'); - } - if (!config) { - config = { - signName: this.config.signName, - template: this.config.template, - }; - } - const client = new Core({ - accessKeyId, - accessKeySecret, - endpoint: 'https://dysmsapi.aliyuncs.com', - // endpoint: 'https://cs.cn-hangzhou.aliyuncs.com', - apiVersion: '2017-05-25', - // apiVersion: '2018-04-18', - }); - const data = { - RegionId: 'cn-shanghai', - PhoneNumbers: phone, - signName: config.signName, - templateCode: config.template, - TemplateParam: JSON.stringify(params), - }; - return await client.request('SendSms', data, { - method: 'POST', - }); - } -} \ No newline at end of file diff --git a/packages/sms/src/config/config.default.ts b/packages/sms/src/config/config.default.ts deleted file mode 100644 index 2a8c538..0000000 --- a/packages/sms/src/config/config.default.ts +++ /dev/null @@ -1,5 +0,0 @@ -export const customKey = { - a: 1, - b: 'hello', - }; - \ No newline at end of file diff --git a/packages/sms/src/configuration.ts b/packages/sms/src/configuration.ts deleted file mode 100644 index d968e7f..0000000 --- a/packages/sms/src/configuration.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { Configuration } from '@midwayjs/decorator'; -import * as DefaultConfig from './config/config.default'; -import { IMidwayContainer } from '@midwayjs/core'; - -@Configuration({ - namespace: 'cool:sms', - importConfigs: [ - { - default: DefaultConfig, - }, - ], -}) -export class CoolPayConfiguration { - async onReady(container: IMidwayContainer) { - // TODO something - } -} diff --git a/packages/sms/src/index.ts b/packages/sms/src/index.ts deleted file mode 100644 index 3856a5c..0000000 --- a/packages/sms/src/index.ts +++ /dev/null @@ -1,9 +0,0 @@ -export { CoolPayConfiguration as Configuration } from './configuration'; - -export * from './interface'; - -export * from './ali'; -export * from './yp'; -export * from './tx'; - -export * from './sms'; diff --git a/packages/sms/src/interface.ts b/packages/sms/src/interface.ts deleted file mode 100644 index cad710a..0000000 --- a/packages/sms/src/interface.ts +++ /dev/null @@ -1,80 +0,0 @@ -export interface CoolSmsConfig { - /** - * 阿里云短信配置 - */ - ali: CoolSmsAliConfig; - /** - * 腾讯云短信配置 - */ - tx: CoolTxConfig; - /** - * 云片短信配置 - */ - yp: CoolYpConfig; -} - -/** - * 阿里云配置 - */ -export interface CoolSmsAliConfig { - /** - * 阿里云accessKeyId - */ - accessKeyId: string; - /** - * 阿里云accessKeySecret - */ - accessKeySecret: string; - /** - * 签名,非必填,调用时可以传入 - */ - signName?: string; - /** - * 模板,非必填,调用时可以传入 - */ - template?: string; -} - -/** - * 腾讯云配置 - */ -export interface CoolTxConfig { - /** - * 应用ID - */ - appId: string; - /** - * 腾讯云secretId - */ - secretId: string; - /** - * 腾讯云secretKey - */ - secretKey: string; - /** - * 签名,非必填,调用时可以传入 - */ - signName?: string; - /** - * 模板,非必填,调用时可以传入 - */ - template?: string; -} - -/** - * 云片短信配置 - */ -export interface CoolYpConfig { - /** - * 云片apikey - */ - apikey: string; - /** - * 签名,非必填,调用时可以传入 - */ - signName?: string; - /** - * 模板,非必填,调用时可以传入 - */ - template?: string; -} diff --git a/packages/sms/src/package.json b/packages/sms/src/package.json deleted file mode 100644 index 45b3eb3..0000000 --- a/packages/sms/src/package.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "name": "@cool-midway/sms", - "version": "6.0.1", - "description": "cool-js.com 短信", - "main": "index.js", - "typings": "index.d.ts", - "scripts": { - "build": "cross-env midway-bin build -c", - "test": "cross-env midway-bin test --ts", - "cov": "cross-env midway-bin cov --ts", - "lint": "mwts check", - "lint:fix": "mwts fix" - }, - "keywords": [ - "cool", - "cool-admin", - "cooljs" - ], - "author": "COOL", - "readme": "README.md", - "files": [ - "**/*.js", - "**/*.d.ts", - "index.d.ts" - ], - "license": "MIT", - "repository": { - "type": "git", - "url": "https://cool-js.com" - }, - "devDependencies": { - "@cool-midway/core": "^6.0.0", - "@midwayjs/cli": "^2.0.9", - "@midwayjs/core": "^3.9.0", - "@midwayjs/decorator": "^3.9.0", - "@midwayjs/mock": "^3.9.0", - "@types/jest": "^29.2.5", - "@types/node": "^18.11.18", - "cross-env": "^7.0.3", - "jest": "^29.3.1", - "mwts": "^1.3.0", - "ts-jest": "^29.0.3", - "typescript": "^4.9.4" - }, - "dependencies": { - "@alicloud/pop-core": "^1.7.13", - "tencentcloud-sdk-nodejs": "^4.0.607" - } -} diff --git a/packages/sms/src/sms.ts b/packages/sms/src/sms.ts deleted file mode 100644 index 2ce7b3d..0000000 --- a/packages/sms/src/sms.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { Config, Inject, Provide } from "@midwayjs/core"; -import { SmsYp } from "./yp"; -import { SmsAli } from "./ali"; -import { SmsTx } from "./tx"; -import { CoolSmsConfig } from "./interface"; - -@Provide() -export class CoolSms { - @Inject() - smsYp: SmsYp - - @Inject() - smsAli: SmsAli - - @Inject() - smsTx: SmsTx - - @Config('cool.sms') - config: CoolSmsConfig; - - /** - * 配置 - * @param config - */ - setConfig(config: CoolSmsConfig) { - this.smsYp.setConfig(config.yp); - this.smsAli.setConfig(config.ali); - this.smsTx.setConfig(config.tx); - this.config = config; - } - - /** - * 发送验证码 模板字段名为:code - * @param phone - * @param config - */ - async sendCode(phone, config?: { - signName: string; - template: string; - }) { - const code = this.generateNumber(); - let params = { - code - } - await this.send(phone, this.config.tx ? [code] : params, config) - return code; - } - - /** - * 发送短信 - * @param phone - * @param params - * @param config - * @returns - */ - async send(phone: string, params: any, config?: { - signName: string; - template: string; - }) { - if (this.config.ali) { - return await this.smsAli.send(phone, params, config); - } - if (this.config.tx) { - return await this.smsTx.send(phone, params, config); - } - if (this.config.yp) { - return await this.smsYp.send(phone, params, config); - } - return true; - } - - /** - * 生成验证码 - */ - generateNumber(digits = 4) { - if (digits <= 0) { - return 0; - } - const min = Math.pow(10, digits - 1); - const max = Math.pow(10, digits) - 1; - return Math.floor(Math.random() * (max - min + 1)) + min; - } -} \ No newline at end of file diff --git a/packages/sms/src/tx.ts b/packages/sms/src/tx.ts deleted file mode 100644 index 1d3e9e1..0000000 --- a/packages/sms/src/tx.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { Config, Provide } from "@midwayjs/core"; -import { CoolTxConfig } from './interface'; -import * as tencentcloud from "tencentcloud-sdk-nodejs"; -import { CoolCommException } from "@cool-midway/core"; - -/** - * 腾讯云短信 - */ -@Provide() -export class SmsTx { - @Config('cool.sms.tx') - config: CoolTxConfig; - - /** - * 配置 - * @param config - */ - setConfig(config: CoolTxConfig) { - this.config = config; - } - - /** - * 发送短信 - * @param phone 手机号 - * @param params 参数 - * @param config signName 签名 template 模板 - * @returns - */ - async send(phone: string, params: string[], config?: { - signName: string; - template: string; - }) { - const { appId, secretId, secretKey } = this.config; - if(!config) { - config = { - signName: this.config.signName, - template: this.config.template, - }; - } - if(!appId || !secretId || !secretKey) { - throw new CoolCommException('请配置腾讯云短信'); - } - const smsClient = tencentcloud.sms.v20210111.Client; - - const client = new smsClient({ - credential: { - secretId, - secretKey, - }, - region: 'ap-guangzhou', - profile: { - signMethod: 'HmacSHA256', - httpProfile: { - reqMethod: 'POST', - reqTimeout: 30, - endpoint: 'sms.tencentcloudapi.com', - }, - }, - }); - - const data = { - SmsSdkAppId: appId, - SignName: config.signName, - TemplateId: config.template, - TemplateParamSet: params, - PhoneNumberSet: [`+86${phone}`], - }; - return client.SendSms(data); - } -} \ No newline at end of file diff --git a/packages/sms/src/yp.ts b/packages/sms/src/yp.ts deleted file mode 100644 index 01ffc66..0000000 --- a/packages/sms/src/yp.ts +++ /dev/null @@ -1,86 +0,0 @@ -import { Config, Provide } from "@midwayjs/core"; -import { CoolYpConfig } from "./interface"; -import { CoolCommException } from "@cool-midway/core"; -import axios from 'axios'; - -/** - * 云片短信 - */ -@Provide() -export class SmsYp { - @Config('cool.sms.yp') - config: CoolYpConfig; - - /** - * 配置 - * @param config - */ - setConfig(config: CoolYpConfig) { - this.config = config; - } - - /** - * 发送短信 - * @param phones 手机号 数组,需要加国家码如 ["+8612345678901"] - * @param params 参数 - * @param config signName 签名 template 模板 - * @returns - */ - async send(phones: string, params: { - [key: string]: string; - }, config?: { - signName: string; - template: string; - }) { - const { apikey } = this.config; - if (!config) { - config = { - signName: this.config.signName, - template: this.config.template, - }; - } - if (!apikey) { - throw new CoolCommException('请配置云片短信'); - } - - const headers = { - Accept: 'application/json;charset=utf-8', - 'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8', - }; - const data = { - apikey: apikey, - mobile: phones, - tpl_id: config.template, - tpl_value: this.smsTplValue(params), - }; - const result = await axios.post( - 'https://sms.yunpian.com/v2/sms/tpl_single_send.json', - data, - { headers } - ); - if (result.data.code === 0) { - return true; - } - return false; - } - - /** - * 获得短信模板值 - * @param obj - * @returns - */ - protected smsTplValue(obj) { - const urlParams = []; - - for (let key in obj) { - // eslint-disable-next-line no-prototype-builtins - if (obj.hasOwnProperty(key)) { - const encodedKey = encodeURIComponent(`#${key}#`); - const encodedValue = encodeURIComponent(obj[key]); - urlParams.push(`${encodedKey}=${encodedValue}`); - } - } - - return urlParams.join('&'); - } -} \ No newline at end of file diff --git a/packages/sms/test/index.test.ts b/packages/sms/test/index.test.ts deleted file mode 100644 index a6c75a1..0000000 --- a/packages/sms/test/index.test.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { createLightApp } from '@midwayjs/mock'; -import * as custom from '../src'; - -describe('/test/index.test.ts', () => { - it('test component', async () => { - const app = await createLightApp('', { - imports: [ - custom - ] - }); - const bookService = await app.getApplicationContext().getAsync(custom.BookService); - expect(await bookService.getBookById()).toEqual('hello world'); - }); -}); diff --git a/packages/sms/tsconfig.json b/packages/sms/tsconfig.json deleted file mode 100644 index f01e1d2..0000000 --- a/packages/sms/tsconfig.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "compileOnSave": true, - "compilerOptions": { - "target": "es2018", - "module": "commonjs", - "moduleResolution": "node", - "experimentalDecorators": true, - "emitDecoratorMetadata": true, - "inlineSourceMap":false, - "noImplicitThis": true, - "noUnusedLocals": true, - "stripInternal": true, - "skipLibCheck": true, - "noImplicitReturns": false, - "pretty": true, - "declaration": true, - "outDir": "dist" - }, - "exclude": [ - "dist", - "node_modules", - "test" - ] -} diff --git a/packages/task/.editorconfig b/packages/task/.editorconfig deleted file mode 100644 index 4c7f8a8..0000000 --- a/packages/task/.editorconfig +++ /dev/null @@ -1,11 +0,0 @@ -# 🎨 editorconfig.org - -root = true - -[*] -charset = utf-8 -end_of_line = lf -indent_style = space -indent_size = 2 -trim_trailing_whitespace = true -insert_final_newline = true \ No newline at end of file diff --git a/packages/task/.eslintrc.json b/packages/task/.eslintrc.json deleted file mode 100644 index fa5dee4..0000000 --- a/packages/task/.eslintrc.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "extends": "./node_modules/mwts/", - "ignorePatterns": [ - "node_modules", - "dist", - "test", - "jest.config.js", - "typings", - "public/**/**", - "view/**/**" - ], - "env": { - "jest": true - }, - "rules": { - "@typescript-eslint/explicit-module-boundary-types": "off", - "@typescript-eslint/no-unused-vars": "off", - "@typescript-eslint/ban-ts-comment": "off", - "node/no-extraneous-import": "off", - "no-empty": "off", - "node/no-extraneous-require": "off", - "eqeqeq": "off", - "node/no-unsupported-features/node-builtins": "off", - "@typescript-eslint/ban-types": "off", - "no-control-regex": "off", - "prefer-const": "off" - } -} \ No newline at end of file diff --git a/packages/task/.gitignore b/packages/task/.gitignore deleted file mode 100644 index 13bc3a6..0000000 --- a/packages/task/.gitignore +++ /dev/null @@ -1,15 +0,0 @@ -logs/ -npm-debug.log -yarn-error.log -node_modules/ -package-lock.json -yarn.lock -coverage/ -dist/ -.idea/ -run/ -.DS_Store -*.sw* -*.un~ -.tsbuildinfo -.tsbuildinfo.* diff --git a/packages/task/.prettierrc.js b/packages/task/.prettierrc.js deleted file mode 100644 index b964930..0000000 --- a/packages/task/.prettierrc.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - ...require('mwts/.prettierrc.json') -} diff --git a/packages/task/README.md b/packages/task/README.md deleted file mode 100644 index 610c3db..0000000 --- a/packages/task/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# cool-admin - -https://cool-js.com diff --git a/packages/task/index.d.ts b/packages/task/index.d.ts deleted file mode 100644 index e0065de..0000000 --- a/packages/task/index.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -export * from './dist/index'; - -declare module '@midwayjs/core/dist/interface' { - interface MidwayConfig { - book?: PowerPartial<{ - a: number; - b: string; - }>; - } -} diff --git a/packages/task/jest.config.js b/packages/task/jest.config.js deleted file mode 100644 index 82a8b85..0000000 --- a/packages/task/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - preset: 'ts-jest', - testEnvironment: 'node', - testPathIgnorePatterns: ['/test/fixtures'], - coveragePathIgnorePatterns: ['/test/'], - setupFilesAfterEnv: ['./jest.setup.js'] -}; diff --git a/packages/task/jest.setup.js b/packages/task/jest.setup.js deleted file mode 100644 index 1399c91..0000000 --- a/packages/task/jest.setup.js +++ /dev/null @@ -1 +0,0 @@ -jest.setTimeout(30000); diff --git a/packages/task/package.json b/packages/task/package.json deleted file mode 100644 index a98f696..0000000 --- a/packages/task/package.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "name": "@cool-midway/task", - "version": "6.0.0", - "description": "cool-js.com 任务与队列", - "main": "dist/index.js", - "typings": "index.d.ts", - "scripts": { - "build": "cross-env midway-bin build -c", - "test": "cross-env midway-bin test --ts", - "cov": "cross-env midway-bin cov --ts", - "lint": "mwts check", - "lint:fix": "mwts fix" - }, - "keywords": [ - "cool", - "cool-admin", - "cooljs" - ], - "author": "COOL", - "readme": "README.md", - "files": [ - "dist/**/*.js", - "dist/**/*.d.ts", - "index.d.ts" - ], - "license": "MIT", - "repository": { - "type": "git", - "url": "https://cool-js.com" - }, - "devDependencies": { - "@cool-midway/core": "^6.0.0", - "@midwayjs/cli": "^2.0.9", - "@midwayjs/core": "^3.9.0", - "@midwayjs/decorator": "^3.9.0", - "@midwayjs/mock": "^3.9.0", - "@midwayjs/redis": "^3.9.0", - "@types/jest": "^29.2.5", - "@types/node": "^18.11.18", - "cross-env": "^7.0.3", - "jest": "^29.3.1", - "lodash": "^4.17.21", - "mwts": "^1.3.0", - "ts-jest": "^29.0.3", - "typescript": "^4.9.4" - }, - "dependencies": { - "bullmq": "^3.5.2", - "ioredis": "^5.2.4" - } -} diff --git a/packages/task/src/base.ts b/packages/task/src/base.ts deleted file mode 100644 index 8d1e5b6..0000000 --- a/packages/task/src/base.ts +++ /dev/null @@ -1,118 +0,0 @@ -import { - Job, - JobsOptions, - Queue, - QueueGetters, - RepeatOptions, - Worker, -} from 'bullmq'; - -/** - * 队列基类 - */ -export abstract class BaseCoolQueue { - /** - * @deprecated 将在后续版本废弃 - */ - queue: BaseCoolQueue; - // 获得者 - getters: QueueGetters; - // 消费者 - worker: Worker; - // 队列名 - queueName: string; - // 原始队列 - metaQueue: Queue; - - constructor() { - this.queue = this; - } - - // 数据 - async data(job: Job, done: Function) {} - - /** - * 发送数据 - * @param data - * @param opts - */ - async add(data: any, opts?: JobsOptions): Promise> { - return this.metaQueue.add(this.queueName, data, opts); - } - - /** - * 批量新增 - * @param datas - * @param opts - */ - async addBulk( - datas: any[], - opts?: JobsOptions - ): Promise[]> { - return this.metaQueue.addBulk( - datas.map(data => { - return { - name: this.queueName, - data, - opts, - }; - }) - ); - } - - defaultJobOptions(): JobsOptions { - return this.metaQueue.defaultJobOptions; - } - - async repeat() { - return this.metaQueue.repeat; - } - - async pause() { - this.metaQueue.pause(); - } - - async resume() { - this.metaQueue.resume(); - } - - async isPaused() { - return this.metaQueue.isPaused(); - } - - async getRepeatableJobs(start?: number, end?: number, asc?: boolean) { - return this.metaQueue.getRepeatableJobs(start, end, asc); - } - - async removeRepeatable(repeatOpts: RepeatOptions, jobId?: string) { - this.metaQueue.removeRepeatable(this.queueName, repeatOpts, jobId); - } - - async removeRepeatableByKey(key: string) { - this.metaQueue.removeRepeatableByKey(key); - } - - async remove(jobId: string) { - return this.metaQueue.remove(jobId); - } - - async drain(delayed?: boolean) { - this.metaQueue.drain(delayed); - } - - async clean( - grace: number, - limit: number, - type?: 'completed' | 'wait' | 'active' | 'paused' | 'delayed' | 'failed' - ) { - return this.metaQueue.clean(grace, limit, type); - } - - async obliterate(opts?: { force?: boolean; count?: number }) { - this.metaQueue.obliterate(opts); - } - - async trimEvents(maxLength: number) { - return this.metaQueue.trimEvents(maxLength); - } -} diff --git a/packages/task/src/config/config.default.ts b/packages/task/src/config/config.default.ts deleted file mode 100644 index a30c406..0000000 --- a/packages/task/src/config/config.default.ts +++ /dev/null @@ -1,6 +0,0 @@ -/** - * cool的配置 - */ -export default { - cool: {}, -}; diff --git a/packages/task/src/configuration.ts b/packages/task/src/configuration.ts deleted file mode 100644 index 4baebdf..0000000 --- a/packages/task/src/configuration.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Configuration } from '@midwayjs/decorator'; -import * as DefaultConfig from './config/config.default'; -import { IMidwayContainer } from '@midwayjs/core'; -import { CoolQueueHandle } from './queue'; - -@Configuration({ - namespace: 'cool:task', - importConfigs: [ - { - default: DefaultConfig, - }, - ], -}) -export class CoolTaskConfiguration { - async onReady(container: IMidwayContainer) { - await container.getAsync(CoolQueueHandle); - // TODO something - } -} diff --git a/packages/task/src/decorator/queue.ts b/packages/task/src/decorator/queue.ts deleted file mode 100644 index 6303fb4..0000000 --- a/packages/task/src/decorator/queue.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { - Scope, - ScopeEnum, - saveClassMetadata, - saveModule, -} from '@midwayjs/decorator'; -import { JobsOptions } from 'bullmq'; - -export const COOL_TASK_KEY = 'decorator:cool:task'; - -export function CoolQueue( - config = { type: 'comm', queue: {}, worker: {} } as { - type?: 'comm' | 'getter' | 'noworker' | 'single'; - queue?: JobsOptions; - worker?: WorkerOptions; - } -): ClassDecorator { - return (target: any) => { - // 将装饰的类,绑定到该装饰器,用于后续能获取到 class - saveModule(COOL_TASK_KEY, target); - // 保存一些元数据信息,任意你希望存的东西 - saveClassMetadata(COOL_TASK_KEY, config, target); - // 指定 IoC 容器创建实例的作用域,这里注册为请求作用域,这样能取到 ctx - Scope(ScopeEnum.Singleton)(target); - }; -} diff --git a/packages/task/src/index.ts b/packages/task/src/index.ts deleted file mode 100644 index 37134d7..0000000 --- a/packages/task/src/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -export { CoolTaskConfiguration as Configuration } from './configuration'; - -export * from './base'; - -export * from './queue'; - -export * from './decorator/queue'; diff --git a/packages/task/src/package.json b/packages/task/src/package.json deleted file mode 100644 index 5888897..0000000 --- a/packages/task/src/package.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "name": "@cool-midway/task", - "version": "6.0.0", - "description": "cool-js.com 任务与队列", - "main": "index.js", - "typings": "index.d.ts", - "scripts": { - "build": "cross-env midway-bin build -c", - "test": "cross-env midway-bin test --ts", - "cov": "cross-env midway-bin cov --ts", - "lint": "mwts check", - "lint:fix": "mwts fix" - }, - "keywords": [ - "cool", - "cool-admin", - "cooljs" - ], - "author": "COOL", - "readme": "README.md", - "files": [ - "**/*.js", - "**/*.d.ts", - "index.d.ts" - ], - "license": "MIT", - "repository": { - "type": "git", - "url": "https://cool-js.com" - }, - "devDependencies": { - "@cool-midway/core": "^6.0.0", - "@midwayjs/cli": "^2.0.9", - "@midwayjs/core": "^3.9.0", - "@midwayjs/decorator": "^3.9.0", - "@midwayjs/mock": "^3.9.0", - "@midwayjs/redis": "^3.9.0", - "@types/jest": "^29.2.5", - "@types/node": "^18.11.18", - "cross-env": "^7.0.3", - "jest": "^29.3.1", - "lodash": "^4.17.21", - "mwts": "^1.3.0", - "ts-jest": "^29.0.3", - "typescript": "^4.9.4" - }, - "dependencies": { - "bullmq": "^3.5.2", - "ioredis": "^5.2.4" - } -} diff --git a/packages/task/src/queue.ts b/packages/task/src/queue.ts deleted file mode 100644 index 533a824..0000000 --- a/packages/task/src/queue.ts +++ /dev/null @@ -1,142 +0,0 @@ -import { ILogger, IMidwayApplication } from '@midwayjs/core'; -import { - App, - Config, - getClassMetadata, - Init, - listModule, - Logger, - Provide, - Scope, - ScopeEnum, -} from '@midwayjs/decorator'; -import { Job, QueueGetters, Queue, Worker } from 'bullmq'; -import { BaseCoolQueue } from './base'; -import { COOL_TASK_KEY } from './decorator/queue'; -import Redis from 'ioredis'; - -/** - * 任务队列 - */ -@Provide() -@Scope(ScopeEnum.Singleton) -export class CoolQueueHandle { - @Config('cool.redis') - redisConfig; - - @Logger() - coreLogger: ILogger; - - @App() - app: IMidwayApplication; - - redis; - - @Init() - async init() { - if (!this.redisConfig) { - this.coreLogger.error('@cool-midway/task组件 redis未配置'); - } - - await this.scan(); - } - - /** - * 扫描队列 - */ - async scan() { - const modules = listModule(COOL_TASK_KEY); - for (let mod of modules) { - const cls: BaseCoolQueue = await this.app - .getApplicationContext() - .getAsync(mod); - this.createQueue(cls, mod); - } - } - - /** - * 获得锁 - * @param key 键 - * @param expireTime 过期时间 - * @returns - */ - async getLock(key, expireTime) { - const lockSuccessful = await this.redis.setnx(key, 'locked'); - if (lockSuccessful) { - await this.redis.expire(key, expireTime); - return true; - } else { - return false; - } - } - - /** - * 队列名称 - * @param cls - * @param mod - */ - async createQueue(cls: BaseCoolQueue, mod: any) { - this.redis; - if (this.redisConfig instanceof Array) { - this.redis = new Redis.Cluster(this.redisConfig, { - enableReadyCheck: false, - }); - } else { - this.redis = new Redis({ - ...this.redisConfig, - enableReadyCheck: false, - maxRetriesPerRequest: null, - }); - } - const name = mod.name; - const config = getClassMetadata(COOL_TASK_KEY, mod); - const opts = { - connection: this.redis, - prefix: `{queue${name}}`, - defaultJobOptions: { - removeOnComplete: true, - removeOnFail: true, - attempts: 5, - backoff: { - type: 'fixed', - delay: 10000, - }, - ...(config.queue || {}), - }, - }; - const queue = new Queue(name, opts); - cls.metaQueue = queue; - cls.queueName = name; - let lock = false; - // 本地开发的情况下直接获得锁 - if (config.type == 'single') { - if (this.app.getEnv() == 'local') { - lock = true; - } else { - // cluster 需要配合redis 获得锁 - if (await this.getLock('COOL_QUEUE_SINGLE', 15)) { - lock = true; - } - } - } - - if (config.type == 'comm' || (config.type == 'single' && lock)) { - cls.worker = new Worker( - name, - async (job: Job) => { - await cls.data(job, async () => { - await job.isCompleted(); - }); - }, - { - connection: opts.connection, - prefix: opts.prefix, - ...(config.worker || {}), - } - ); - } else { - cls.getters = new QueueGetters(name, opts); - } - this.coreLogger.info(`\x1B[36m [cool:task] create ${name} queue \x1B[0m`); - } -} diff --git a/packages/task/test/index.test.ts b/packages/task/test/index.test.ts deleted file mode 100644 index a6c75a1..0000000 --- a/packages/task/test/index.test.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { createLightApp } from '@midwayjs/mock'; -import * as custom from '../src'; - -describe('/test/index.test.ts', () => { - it('test component', async () => { - const app = await createLightApp('', { - imports: [ - custom - ] - }); - const bookService = await app.getApplicationContext().getAsync(custom.BookService); - expect(await bookService.getBookById()).toEqual('hello world'); - }); -}); diff --git a/packages/task/tsconfig.json b/packages/task/tsconfig.json deleted file mode 100644 index f01e1d2..0000000 --- a/packages/task/tsconfig.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "compileOnSave": true, - "compilerOptions": { - "target": "es2018", - "module": "commonjs", - "moduleResolution": "node", - "experimentalDecorators": true, - "emitDecoratorMetadata": true, - "inlineSourceMap":false, - "noImplicitThis": true, - "noUnusedLocals": true, - "stripInternal": true, - "skipLibCheck": true, - "noImplicitReturns": false, - "pretty": true, - "declaration": true, - "outDir": "dist" - }, - "exclude": [ - "dist", - "node_modules", - "test" - ] -} diff --git a/public/css/welcome.css b/public/css/welcome.css index e85c269..c838986 100644 --- a/public/css/welcome.css +++ b/public/css/welcome.css @@ -7,6 +7,31 @@ body { background: #222; } +@keyframes fadeIn { + from { + opacity: 0; + } + to { + opacity: 1; + } +} + +.footer-bar { + position: fixed; + bottom: 0; + left: 0; + right: 0; + color: #6ee1f5; + padding: 10px 0 20px 0; + text-align: center; + opacity: 0; /* 开始时隐藏 */ + animation: fadeIn 5s forwards; /* 应用动画 */ +} + +.link { + color: #6ee1f5; +} + .reveal { position: relative; display: flex; diff --git a/src/config/config.local.ts b/src/config/config.local.ts index d4031e1..9c65399 100644 --- a/src/config/config.local.ts +++ b/src/config/config.local.ts @@ -28,8 +28,10 @@ export default { }, }, cool: { - // 是否自动导入数据库 + // 是否自动导入模块数据库 initDB: true, + // 是否自动导入模块菜单 + initMenu: true, // crud配置 crud: { // 软删除 diff --git a/src/configuration.ts b/src/configuration.ts index 010a5af..90b6028 100644 --- a/src/configuration.ts +++ b/src/configuration.ts @@ -67,24 +67,5 @@ export class ContainerLifeCycle { @Config('module') config; - async onReady() { - // 检查配置 - await this.checkConfig(); - } - - /** - * 检查配置 - */ - async checkConfig() { - if (this.config.base.jwt.secret === 'cool-admin-xxxxxx') { - this.logger.warn( - '安全起见,请修改[base]模块配置文件 config.ts 中的 jwt.secret 为随机字符串' - ); - } - if (this.config.user.jwt.secret == 'cool-app-xxxxxx') { - this.logger.warn( - '安全起见,请修改[user]模块配置文件 config.ts 中的 jwt.secret 为随机字符串' - ); - } - } + async onReady() {} } diff --git a/src/modules/base/config.ts b/src/modules/base/config.ts index c512e64..82cb3c9 100644 --- a/src/modules/base/config.ts +++ b/src/modules/base/config.ts @@ -20,7 +20,7 @@ export default () => { // 单点登录 sso: false, // 注意: 最好重新修改,防止破解 - secret: 'cool-admin-xxxxxx', + secret: 'a7f442005dc411eeb330bb388e9deb5b', // token token: { // 2小时过期,需要用刷新token diff --git a/src/modules/base/controller/admin/comm.ts b/src/modules/base/controller/admin/comm.ts index ab4be59..11ef46d 100644 --- a/src/modules/base/controller/admin/comm.ts +++ b/src/modules/base/controller/admin/comm.ts @@ -1,10 +1,5 @@ import { Provide, Inject, Get, Post, Body, ALL } from '@midwayjs/decorator'; -import { - CoolController, - BaseController, - CoolUrlTag, - TagTypes, -} from '@cool-midway/core'; +import { CoolController, BaseController } from '@cool-midway/core'; import { BaseSysUserEntity } from '../../entity/sys/user'; import { BaseSysLoginService } from '../../service/sys/login'; import { BaseSysPermsService } from '../../service/sys/perms'; @@ -15,10 +10,6 @@ import { CoolFile } from '@cool-midway/file'; /** * Base 通用接口 一般写不需要权限过滤的接口 */ -@CoolUrlTag({ - key: TagTypes.IGNORE_TOKEN, - value: ['eps'], -}) @Provide() @CoolController() export class BaseCommController extends BaseController { diff --git a/src/modules/base/controller/admin/open.ts b/src/modules/base/controller/admin/open.ts index 86aeabe..fdc471e 100644 --- a/src/modules/base/controller/admin/open.ts +++ b/src/modules/base/controller/admin/open.ts @@ -58,9 +58,12 @@ export class BaseOpenController extends BaseController { async captcha( @Query('type') type: string, @Query('width') width: number, - @Query('height') height: number + @Query('height') height: number, + @Query('color') color: string ) { - return this.ok(await this.baseSysLoginService.captcha(type, width, height)); + return this.ok( + await this.baseSysLoginService.captcha(type, width, height, color) + ); } /** diff --git a/src/modules/base/controller/admin/sys/menu.ts b/src/modules/base/controller/admin/sys/menu.ts index 8f5808f..fd3f3d4 100644 --- a/src/modules/base/controller/admin/sys/menu.ts +++ b/src/modules/base/controller/admin/sys/menu.ts @@ -32,4 +32,15 @@ export class BaseSysMenuController extends BaseController { await this.baseSysMenuService.create(body); return this.ok(); } + + @Post('/export', { summary: '导出' }) + async export(@Body('ids') ids: number[]) { + return this.ok(await this.baseSysMenuService.export(ids)); + } + + @Post('/import', { summary: '导入' }) + async import(@Body('menus') menus: any[]) { + await this.baseSysMenuService.import(menus); + return this.ok(); + } } diff --git a/src/modules/base/controller/app/comm.ts b/src/modules/base/controller/app/comm.ts index faa9167..1a38efb 100644 --- a/src/modules/base/controller/app/comm.ts +++ b/src/modules/base/controller/app/comm.ts @@ -1,21 +1,20 @@ -import { Provide, Inject, Get, Post } from '@midwayjs/decorator'; +import { Provide, Inject, Get, Post, Query } from '@midwayjs/decorator'; import { CoolController, BaseController, CoolEps, TagTypes, CoolUrlTag, + CoolTag, } from '@cool-midway/core'; import { Context } from '@midwayjs/koa'; import { CoolFile } from '@cool-midway/file'; +import { BaseSysParamService } from '../../service/sys/param'; /** * 不需要登录的后台接口 */ -@CoolUrlTag({ - key: TagTypes.IGNORE_TOKEN, - value: ['eps'], -}) +@CoolUrlTag() @Provide() @CoolController() export class BaseAppCommController extends BaseController { @@ -28,10 +27,19 @@ export class BaseAppCommController extends BaseController { @Inject() eps: CoolEps; + @Inject() + baseSysParamService: BaseSysParamService; + + @Get('/param', { summary: '参数配置' }) + async param(@Query('key') key: string) { + return this.ok(await this.baseSysParamService.dataByKey(key)); + } + /** * 实体信息与路径 * @returns */ + @CoolTag(TagTypes.IGNORE_TOKEN) @Get('/eps', { summary: '实体信息与路径' }) public async getEps() { return this.ok(this.eps.app); diff --git a/src/modules/base/event/app.ts b/src/modules/base/event/app.ts new file mode 100644 index 0000000..05eeb96 --- /dev/null +++ b/src/modules/base/event/app.ts @@ -0,0 +1,41 @@ +import { CoolEvent, Event } from '@cool-midway/core'; +import { App, Config, ILogger, Logger } from '@midwayjs/core'; +import { IMidwayKoaApplication } from '@midwayjs/koa'; +import * as fs from 'fs'; +import * as path from 'path'; +import { v1 as uuid } from 'uuid'; + +/** + * 修改jwt.secret + */ +@CoolEvent() +export class BaseAppEvent { + @Logger() + coreLogger: ILogger; + + @Config('module') + config; + + @App() + app: IMidwayKoaApplication; + + @Event('onServerReady') + async onServerReady() { + if (this.config.base.jwt.secret == 'cool-admin-xxxxxx') { + const filePath = path.join( + this.app.getBaseDir(), + 'modules', + 'base', + 'config.ts' + ); + // 替换文件内容 + let fileData = fs.readFileSync(filePath, 'utf8'); + const secret = uuid().replace(/-/g, ''); + this.config.base.jwt.secret = secret; + fs.writeFileSync(filePath, fileData.replace('cool-admin-xxxxxx', secret)); + this.coreLogger.info( + '\x1B[36m [cool:module:base] midwayjs cool module base auto modify jwt.secret\x1B[0m' + ); + } + } +} diff --git a/src/modules/base/event/menu.ts b/src/modules/base/event/menu.ts new file mode 100644 index 0000000..bb3a19e --- /dev/null +++ b/src/modules/base/event/menu.ts @@ -0,0 +1,25 @@ +import { CoolEvent, Event } from '@cool-midway/core'; +import { BaseSysMenuService } from '../service/sys/menu'; +import { ILogger, Inject, Logger } from '@midwayjs/core'; + +/** + * 导入菜单 + */ +@CoolEvent() +export class BaseMenuEvent { + @Inject() + baseSysMenuService: BaseSysMenuService; + + @Logger() + coreLogger: ILogger; + + @Event('onMenuImport') + async onMenuImport(module, data) { + await this.baseSysMenuService.import(data); + this.coreLogger.info( + '\x1B[36m [cool:module:base] midwayjs cool module base import [' + + module + + '] module menu success \x1B[0m' + ); + } +} diff --git a/src/modules/base/service/sys/menu.ts b/src/modules/base/service/sys/menu.ts index a51a50f..ba77046 100644 --- a/src/modules/base/service/sys/menu.ts +++ b/src/modules/base/service/sys/menu.ts @@ -1,8 +1,8 @@ -import { App, IMidwayApplication } from '@midwayjs/core'; +import { App, IMidwayApplication, Scope, ScopeEnum } from '@midwayjs/core'; import { ALL, Config, Inject, Provide } from '@midwayjs/decorator'; import { BaseService, CoolCommException } from '@cool-midway/core'; import { InjectEntityModel } from '@midwayjs/typeorm'; -import { Repository } from 'typeorm'; +import { In, Repository } from 'typeorm'; import { BaseSysMenuEntity } from '../../entity/sys/menu'; import * as _ from 'lodash'; import { BaseSysPermsService } from './perms'; @@ -16,6 +16,7 @@ import * as pathUtil from 'path'; /** * 菜单 */ +@Scope(ScopeEnum.Request, { allowDowngrade: true }) @Provide() export class BaseSysMenuService extends BaseService { @Inject() @@ -188,7 +189,7 @@ export class BaseSysMenuService extends BaseService { }); // 连接数据库 await tempDataSource.initialize(); - const { newCode, className } = this.parseCode(entityString); + const { newCode, className, oldTableName } = this.parseCode(entityString); const code = ts.transpile( `${newCode} tempDataSource.options.entities.push(${className}) @@ -198,13 +199,22 @@ export class BaseSysMenuService extends BaseService { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2018, removeComments: true, + experimentalDecorators: true, + noImplicitThis: true, + noUnusedLocals: true, + stripInternal: true, + skipLibCheck: true, + pretty: true, + declaration: true, + noImplicitAny: false, } ); eval(code); await tempDataSource.buildMetadatas(); - const columnArr = tempDataSource.getMetadata(className).columns; + const meta = tempDataSource.getMetadata(className); + const columnArr = meta.columns; await tempDataSource.destroy(); - const fileName = await this.fileName(controller); + const commColums = []; const columns = _.filter( columnArr.map(e => { @@ -223,6 +233,18 @@ export class BaseSysMenuService extends BaseService { return o && !['createTime', 'updateTime'].includes(o.propertyName); } ).concat(commColums); + if (!controller) { + const tableNames = oldTableName.split('_'); + const fileName = tableNames[tableNames.length - 1]; + return { + columns, + className: className.replace('TEMP', ''), + tableName: oldTableName, + fileName, + path: `/admin/${module}/${fileName}`, + }; + } + const fileName = await this.fileName(controller); return { columns, path: `/admin/${module}/${fileName}`, @@ -256,6 +278,7 @@ export class BaseSysMenuService extends BaseService { .replace(oldTableName, `func_${oldTableName}`), className, tableName: `func_${oldTableName}`, + oldTableName, }; } catch (err) { throw new CoolCommException('代码结构不正确,请检查'); @@ -267,9 +290,9 @@ export class BaseSysMenuService extends BaseService { * @param body body */ async create(body) { - const { module, entity, controller } = body; + const { module, entity, controller, fileName } = body; const basePath = this.app.getBaseDir(); - const fileName = await this.fileName(controller); + // const fileName = await this.fileName(controller); // 生成Entity const entityPath = pathUtil.join( basePath, @@ -357,4 +380,81 @@ export default () => { } fs.writeFileSync(filePath, content); } + + /** + * 导出菜单 + * @param ids + * @returns + */ + async export(ids: number[]) { + const result: any[] = []; + const menus = await this.baseSysMenuEntity.findBy({ id: In(ids) }); + + // 递归取出子菜单 + const getChildMenus = (parentId: number): any[] => { + const children = _.remove(menus, e => e.parentId == parentId); + children.forEach(child => { + child.childMenus = getChildMenus(child.id); + // 删除不需要的字段 + delete child.id; + delete child.createTime; + delete child.updateTime; + delete child.parentId; + }); + return children; + }; + + // lodash取出父级菜单(parentId为 null), 并从menus 删除 + const parentMenus = _.remove(menus, e => { + return e.parentId == null; + }); + + // 对于每个父级菜单,获取它的子菜单 + parentMenus.forEach(parent => { + parent.childMenus = getChildMenus(parent.id); + // 删除不需要的字段 + delete parent.id; + delete parent.createTime; + delete parent.updateTime; + delete parent.parentId; + + result.push(parent); + }); + + return result; + } + + /** + * 导入 + * @param menus + */ + async import(menus: any[]) { + // 递归保存子菜单 + const saveChildMenus = async (parentMenu: any, parentId: number | null) => { + const children = parentMenu.childMenus || []; + for (let child of children) { + const childData = { ...child, parentId: parentId }; // 保持与数据库的parentId字段的一致性 + delete childData.childMenus; // 删除childMenus属性,因为我们不想将它保存到数据库中 + + // 保存子菜单并获取其ID,以便为其子菜单设置parentId + const savedChild = await this.baseSysMenuEntity.save(childData); + + if (!_.isEmpty(child.childMenus)) { + await saveChildMenus(child, savedChild.id); + } + } + }; + + for (let menu of menus) { + const menuData = { ...menu }; + delete menuData.childMenus; // 删除childMenus属性,因为我们不想将它保存到数据库中 + + // 保存主菜单并获取其ID + const savedMenu = await this.baseSysMenuEntity.save(menuData); + + if (menu.childMenus && menu.childMenus.length > 0) { + await saveChildMenus(menu, savedMenu.id); + } + } + } } diff --git a/src/modules/base/service/sys/user.ts b/src/modules/base/service/sys/user.ts index 3fd4e14..4b07645 100644 --- a/src/modules/base/service/sys/user.ts +++ b/src/modules/base/service/sys/user.ts @@ -172,10 +172,14 @@ export class BaseSysUserService extends BaseService { param.id = this.ctx.admin.userId; if (!_.isEmpty(param.password)) { param.password = md5(param.password); + const oldPassword = md5(param.oldPassword); const userInfo = await this.baseSysUserEntity.findOneBy({ id: param.id }); if (!userInfo) { throw new CoolCommException('用户不存在'); } + if (oldPassword !== userInfo.password) { + throw new CoolCommException('原密码错误'); + } param.passwordV = userInfo.passwordV + 1; await this.cacheManager.set( `admin:passwordVersion:${param.id}`, diff --git a/src/modules/demo/controller/app/cache.ts b/src/modules/demo/controller/open/cache.ts similarity index 93% rename from src/modules/demo/controller/app/cache.ts rename to src/modules/demo/controller/open/cache.ts index ee6313f..b509243 100644 --- a/src/modules/demo/controller/app/cache.ts +++ b/src/modules/demo/controller/open/cache.ts @@ -1,4 +1,4 @@ -import { DemoCacheService } from './../../service/cache'; +import { DemoCacheService } from '../../service/cache'; import { Inject, Post, Provide, Get } from '@midwayjs/decorator'; import { CoolController, BaseController } from '@cool-midway/core'; import { CacheManager } from '@midwayjs/cache'; diff --git a/src/modules/demo/controller/app/event.ts b/src/modules/demo/controller/open/event.ts similarity index 100% rename from src/modules/demo/controller/app/event.ts rename to src/modules/demo/controller/open/event.ts diff --git a/src/modules/demo/controller/app/goods.ts b/src/modules/demo/controller/open/goods.ts similarity index 100% rename from src/modules/demo/controller/app/goods.ts rename to src/modules/demo/controller/open/goods.ts diff --git a/src/modules/demo/controller/app/pay.ts b/src/modules/demo/controller/open/pay.ts similarity index 100% rename from src/modules/demo/controller/app/pay.ts rename to src/modules/demo/controller/open/pay.ts diff --git a/src/modules/demo/controller/app/queue.ts b/src/modules/demo/controller/open/queue.ts similarity index 100% rename from src/modules/demo/controller/app/queue.ts rename to src/modules/demo/controller/open/queue.ts diff --git a/src/modules/demo/controller/app/rpc.ts b/src/modules/demo/controller/open/rpc.ts similarity index 100% rename from src/modules/demo/controller/app/rpc.ts rename to src/modules/demo/controller/open/rpc.ts diff --git a/src/modules/demo/controller/app/transaction.ts b/src/modules/demo/controller/open/transaction.ts similarity index 88% rename from src/modules/demo/controller/app/transaction.ts rename to src/modules/demo/controller/open/transaction.ts index 5b37a6d..aa1ccd5 100644 --- a/src/modules/demo/controller/app/transaction.ts +++ b/src/modules/demo/controller/open/transaction.ts @@ -1,4 +1,4 @@ -import { DemoGoodsEntity } from './../../entity/goods'; +import { DemoGoodsEntity } from '../../entity/goods'; import { Provide } from '@midwayjs/decorator'; import { CoolController, BaseController } from '@cool-midway/core'; import { DemoTransactionService } from '../../service/transaction'; diff --git a/src/modules/dict/controller/app/info.ts b/src/modules/dict/controller/app/info.ts index aa8b9e9..b83a849 100644 --- a/src/modules/dict/controller/app/info.ts +++ b/src/modules/dict/controller/app/info.ts @@ -4,6 +4,7 @@ import { BaseController, CoolUrlTag, TagTypes, + CoolTag, } from '@cool-midway/core'; import { DictInfoService } from '../../service/info'; @@ -12,14 +13,12 @@ import { DictInfoService } from '../../service/info'; */ @Provide() @CoolController() -@CoolUrlTag({ - key: TagTypes.IGNORE_TOKEN, - value: ['data'], -}) +@CoolUrlTag() export class AppDictInfoController extends BaseController { @Inject() dictInfoService: DictInfoService; + @CoolTag(TagTypes.IGNORE_TOKEN) @Post('/data', { summary: '获得字典数据' }) async data(@Body('types') types: string[] = []) { return this.ok(await this.dictInfoService.data(types)); diff --git a/src/modules/dict/entity/info.ts b/src/modules/dict/entity/info.ts index 7197a14..68d4701 100644 --- a/src/modules/dict/entity/info.ts +++ b/src/modules/dict/entity/info.ts @@ -12,6 +12,9 @@ export class DictInfoEntity extends BaseEntity { @Column({ comment: '名称' }) name: string; + @Column({ comment: '值', nullable: true }) + value: string; + @Column({ comment: '排序', default: 0 }) orderNum: number; diff --git a/src/modules/dict/service/info.ts b/src/modules/dict/service/info.ts index 1254e17..7b33dae 100644 --- a/src/modules/dict/service/info.ts +++ b/src/modules/dict/service/info.ts @@ -33,7 +33,14 @@ export class DictInfoService extends BaseService { } const data = await this.dictInfoEntity .createQueryBuilder('a') - .select(['a.id', 'a.name', 'a.typeId', 'a.parentId', 'a.orderNum']) + .select([ + 'a.id', + 'a.name', + 'a.typeId', + 'a.parentId', + 'a.orderNum', + 'a.value', + ]) .where('typeId in(:typeIds)', { typeIds: typeData.map(e => { return e.id; diff --git a/src/modules/task/event/app.ts b/src/modules/task/event/app.ts index 6866027..32f409a 100644 --- a/src/modules/task/event/app.ts +++ b/src/modules/task/event/app.ts @@ -12,6 +12,6 @@ export class AppEvent { @Event('onServerReady') async onServerReady() { - await this.taskInfoService.initTask(); + this.taskInfoService.initTask(); } } diff --git a/src/modules/task/service/info.ts b/src/modules/task/service/info.ts index 435a778..3adea85 100644 --- a/src/modules/task/service/info.ts +++ b/src/modules/task/service/info.ts @@ -246,7 +246,8 @@ export class TaskInfoService extends BaseService { * 初始化任务 */ async initTask() { - setTimeout(async () => { + try { + await this.utils.sleep(3000); this.logger.info('init task....'); const runningTasks = await this.taskInfoEntity.findBy({ status: 1 }); if (!_.isEmpty(runningTasks)) { @@ -258,7 +259,7 @@ export class TaskInfoService extends BaseService { } } } - }, 3000); + } catch (e) {} } /** diff --git a/src/modules/user/config.ts b/src/modules/user/config.ts index 6e0946b..c08b0eb 100644 --- a/src/modules/user/config.ts +++ b/src/modules/user/config.ts @@ -41,7 +41,7 @@ export default () => { // 刷新token 过期时间,单位秒 refreshExpire: 60 * 60 * 24 * 30, // jwt 秘钥 - secret: 'cool-app-xxxxxx', + secret: 'a7f469105dc411eeb330bb388e9deb5b', }, } as ModuleConfig; }; diff --git a/src/modules/user/controller/app/comm.ts b/src/modules/user/controller/app/comm.ts index 78af233..0de190f 100644 --- a/src/modules/user/controller/app/comm.ts +++ b/src/modules/user/controller/app/comm.ts @@ -3,6 +3,7 @@ import { BaseController, CoolUrlTag, TagTypes, + CoolTag, } from '@cool-midway/core'; import { Get, Inject, Query } from '@midwayjs/core'; import { UserWxService } from '../../service/wx'; @@ -10,15 +11,13 @@ import { UserWxService } from '../../service/wx'; /** * 通用 */ -@CoolUrlTag({ - key: TagTypes.IGNORE_TOKEN, - value: ['wxMpConfig'], -}) +@CoolUrlTag() @CoolController() export class UserCommController extends BaseController { @Inject() userWxService: UserWxService; + @CoolTag(TagTypes.IGNORE_TOKEN) @Get('/wxMpConfig', { summary: '获取微信公众号配置' }) public async getWxMpConfig(@Query() url: string) { const a = await this.userWxService.getWxMpConfig(url); diff --git a/src/modules/user/controller/app/login.ts b/src/modules/user/controller/app/login.ts index 34d549a..d830b48 100644 --- a/src/modules/user/controller/app/login.ts +++ b/src/modules/user/controller/app/login.ts @@ -3,6 +3,7 @@ import { BaseController, CoolUrlTag, TagTypes, + CoolTag, } from '@cool-midway/core'; import { Body, Get, Inject, Post, Query } from '@midwayjs/core'; import { UserLoginService } from '../../service/login'; @@ -11,10 +12,7 @@ import { BaseSysLoginService } from '../../../base/service/sys/login'; /** * 登录 */ -@CoolUrlTag({ - key: TagTypes.IGNORE_TOKEN, - value: ['mini', 'mp', 'phone', 'captcha', 'smsCode', 'refreshToken'], -}) +@CoolUrlTag() @CoolController() export class AppUserLoginController extends BaseController { @Inject() @@ -23,22 +21,26 @@ export class AppUserLoginController extends BaseController { @Inject() baseSysLoginService: BaseSysLoginService; + @CoolTag(TagTypes.IGNORE_TOKEN) @Post('/mini', { summary: '小程序登录' }) async mini(@Body() body) { const { code, encryptedData, iv } = body; return this.ok(await this.userLoginService.mini(code, encryptedData, iv)); } + @CoolTag(TagTypes.IGNORE_TOKEN) @Post('/mp', { summary: '公众号登录' }) async mp(@Body('code') code: string) { return this.ok(await this.userLoginService.mp(code)); } + @CoolTag(TagTypes.IGNORE_TOKEN) @Post('/phone', { summary: '手机号登录' }) async phone(@Body('phone') phone: string, @Body('smsCode') smsCode: string) { return this.ok(await this.userLoginService.phone(phone, smsCode)); } + @CoolTag(TagTypes.IGNORE_TOKEN) @Get('/captcha', { summary: '图片验证码' }) async captcha( @Query('type') type: string, @@ -51,6 +53,7 @@ export class AppUserLoginController extends BaseController { ); } + @CoolTag(TagTypes.IGNORE_TOKEN) @Post('/smsCode', { summary: '验证码' }) async smsCode( @Body('phone') phone: string, @@ -60,6 +63,7 @@ export class AppUserLoginController extends BaseController { return this.ok(await this.userLoginService.smsCode(phone, captchaId, code)); } + @CoolTag(TagTypes.IGNORE_TOKEN) @Post('/refreshToken', { summary: '刷新token' }) public async refreshToken(@Body('refreshToken') refreshToken) { return this.ok(await this.userLoginService.refreshToken(refreshToken)); diff --git a/src/modules/user/event/app.ts b/src/modules/user/event/app.ts new file mode 100644 index 0000000..f5fbffd --- /dev/null +++ b/src/modules/user/event/app.ts @@ -0,0 +1,41 @@ +import { CoolEvent, Event } from '@cool-midway/core'; +import { App, Config, ILogger, Logger } from '@midwayjs/core'; +import { IMidwayKoaApplication } from '@midwayjs/koa'; +import * as fs from 'fs'; +import * as path from 'path'; +import { v1 as uuid } from 'uuid'; + +/** + * 修改jwt.secret + */ +@CoolEvent() +export class UserAppEvent { + @Logger() + coreLogger: ILogger; + + @Config('module') + config; + + @App() + app: IMidwayKoaApplication; + + @Event('onServerReady') + async onServerReady() { + if (this.config.user.jwt.secret == 'cool-app-xxxxxx') { + const filePath = path.join( + this.app.getBaseDir(), + 'modules', + 'user', + 'config.ts' + ); + // 替换文件内容 + let fileData = fs.readFileSync(filePath, 'utf8'); + const secret = uuid().replace(/-/g, ''); + this.config.user.jwt.secret = secret; + fs.writeFileSync(filePath, fileData.replace('cool-app-xxxxxx', secret)); + this.coreLogger.info( + '\x1B[36m [cool:module:user] midwayjs cool module user auto modify jwt.secret\x1B[0m' + ); + } + } +} diff --git a/src/modules/user/service/login.ts b/src/modules/user/service/login.ts index 9cead6b..b8a4625 100644 --- a/src/modules/user/service/login.ts +++ b/src/modules/user/service/login.ts @@ -49,7 +49,7 @@ export class UserLoginService extends BaseService { if (!check) { throw new CoolCommException('图片验证码错误'); } - this.userSmsService.sendSms(phone); + await this.userSmsService.sendSms(phone); } /** diff --git a/src/welcome.ts b/src/welcome.ts index 7260af1..7a5c2d8 100644 --- a/src/welcome.ts +++ b/src/welcome.ts @@ -15,7 +15,7 @@ export class WelcomeController { @Get('/') public async welcome() { await this.ctx.render('welcome', { - text: 'HELLO COOL-ADMIN 6.x 一个项目用COOL就够了!!!', + text: 'HELLO COOL-ADMIN v7.0 一个项目用COOL就够了!!!', }); } } diff --git a/test/README.md b/test/README.md new file mode 100644 index 0000000..7effc7e --- /dev/null +++ b/test/README.md @@ -0,0 +1,12 @@ +# 测试方式 + +考虑到cool-admin采用了自动化路由技术,它与官方集成的jest测试工具并不兼容。为确保测试环境与实际的开发环境保持一致,我们并不推荐使用jest进行测试。 + +# 自动化测试API工具 + +我们为您推荐以下的自动化API测试工具: + +- [Apifox](https://apifox.com/) +- [ApiPost](https://www.apipost.cn/) + +同时这些工具也方便写API接口文档,更加灵活有用 \ No newline at end of file diff --git a/test/controller/api.test.ts b/test/controller/api.test.ts deleted file mode 100644 index da433b5..0000000 --- a/test/controller/api.test.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { createApp, close, createHttpRequest } from '@midwayjs/mock'; -import { Framework } from '@midwayjs/koa'; - -describe('test/controller/home.test.ts', () => { - - it('should POST /api/get_user', async () => { - // create app - const app = await createApp(); - - // make request - const result = await createHttpRequest(app).get('/api/get_user').query({ uid: 123 }); - - // use expect by jest - expect(result.status).toBe(200); - expect(result.body.message).toBe('OK'); - - // close app - await close(app); - }); -}); diff --git a/test/controller/home.test.ts b/test/controller/home.test.ts deleted file mode 100644 index 93dc66f..0000000 --- a/test/controller/home.test.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { createApp, close, createHttpRequest } from '@midwayjs/mock'; -import { Framework } from '@midwayjs/koa'; - -describe('test/controller/home.test.ts', () => { - - it('should GET /', async () => { - // create app - const app = await createApp(); - - // make request - const result = await createHttpRequest(app).get('/'); - - // use expect by jest - expect(result.status).toBe(200); - expect(result.text).toBe('Hello Midwayjs!'); - - // close app - await close(app); - }); - -}); diff --git a/typings/app/index.d.ts b/typings/app/index.d.ts deleted file mode 100644 index 8ed2d4b..0000000 --- a/typings/app/index.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -// This file is created by egg-ts-helper -// Do not modify this file!!!!!!!!! -import 'egg'; -import '@midwayjs/web'; -export * from 'egg'; -export as namespace Egg; \ No newline at end of file diff --git a/typings/config/index.d.ts b/typings/config/index.d.ts deleted file mode 100644 index d68bf9a..0000000 --- a/typings/config/index.d.ts +++ /dev/null @@ -1,35 +0,0 @@ -// This file is created by egg-ts-helper -// Do not modify this file!!!!!!!!! -import 'egg'; -import '@midwayjs/web'; -import 'egg-onerror'; -import 'egg-session'; -import 'egg-i18n'; -import 'egg-watcher'; -import 'egg-multipart'; -import 'egg-security'; -import 'egg-development'; -import 'egg-logrotator'; -import 'egg-schedule'; -import 'egg-static'; -import 'egg-jsonp'; -import 'egg-view'; -import 'midway-schedule'; -import { EggPluginItem } from 'egg'; -declare module 'egg' { - interface EggPlugin { - 'onerror'?: EggPluginItem; - 'session'?: EggPluginItem; - 'i18n'?: EggPluginItem; - 'watcher'?: EggPluginItem; - 'multipart'?: EggPluginItem; - 'security'?: EggPluginItem; - 'development'?: EggPluginItem; - 'logrotator'?: EggPluginItem; - 'schedule'?: EggPluginItem; - 'static'?: EggPluginItem; - 'jsonp'?: EggPluginItem; - 'view'?: EggPluginItem; - 'schedulePlus'?: EggPluginItem; - } -} \ No newline at end of file diff --git a/typings/config/plugin.d.ts b/typings/config/plugin.d.ts deleted file mode 100644 index d68bf9a..0000000 --- a/typings/config/plugin.d.ts +++ /dev/null @@ -1,35 +0,0 @@ -// This file is created by egg-ts-helper -// Do not modify this file!!!!!!!!! -import 'egg'; -import '@midwayjs/web'; -import 'egg-onerror'; -import 'egg-session'; -import 'egg-i18n'; -import 'egg-watcher'; -import 'egg-multipart'; -import 'egg-security'; -import 'egg-development'; -import 'egg-logrotator'; -import 'egg-schedule'; -import 'egg-static'; -import 'egg-jsonp'; -import 'egg-view'; -import 'midway-schedule'; -import { EggPluginItem } from 'egg'; -declare module 'egg' { - interface EggPlugin { - 'onerror'?: EggPluginItem; - 'session'?: EggPluginItem; - 'i18n'?: EggPluginItem; - 'watcher'?: EggPluginItem; - 'multipart'?: EggPluginItem; - 'security'?: EggPluginItem; - 'development'?: EggPluginItem; - 'logrotator'?: EggPluginItem; - 'schedule'?: EggPluginItem; - 'static'?: EggPluginItem; - 'jsonp'?: EggPluginItem; - 'view'?: EggPluginItem; - 'schedulePlus'?: EggPluginItem; - } -} \ No newline at end of file diff --git a/view/welcome.html b/view/welcome.html index fc70487..923ac48 100644 --- a/view/welcome.html +++ b/view/welcome.html @@ -13,6 +13,15 @@
<%= text %>
+ + + +