├── .github └── workflows │ ├── pr.yml │ └── release.yml ├── .gitignore ├── .husky ├── commit-msg └── pre-commit ├── CHANGELOG.md ├── LICENSE ├── README.MD ├── package-lock.json ├── package.json ├── renovate.json ├── src ├── common │ ├── index.ts │ └── interface │ │ ├── client.ts │ │ ├── config.ts │ │ ├── http.ts │ │ ├── index.ts │ │ ├── pagination.ts │ │ └── provider.ts ├── decorator │ ├── async-inject.ts │ └── index.ts ├── index.ts └── struct │ ├── index.ts │ ├── provider.ts │ └── store.ts ├── test ├── decorator.spec.ts └── tsconfig.json └── tsconfig.json /.github/workflows/pr.yml: -------------------------------------------------------------------------------- 1 | name: "pr" 2 | 3 | on: 4 | pull_request: 5 | branches: [master] 6 | 7 | jobs: 8 | check: 9 | uses: vodyani/workflows/.github/workflows/check.yml@master 10 | with: 11 | enable_test: true 12 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: "release" 2 | 3 | on: 4 | push: 5 | branches: [beta, alpha, master] 6 | 7 | jobs: 8 | check: 9 | uses: vodyani/workflows/.github/workflows/check.yml@master 10 | with: 11 | enable_test: true 12 | 13 | codecov: 14 | needs: [check] 15 | uses: vodyani/workflows/.github/workflows/codecov.yml@master 16 | secrets: 17 | CODE_COV_CI_TOKEN: ${{ secrets.CODECOV_CI_TOKEN_BY_CORE }} 18 | 19 | semantic_release: 20 | needs: [codecov] 21 | uses: vodyani/workflows/.github/workflows/semantic-release-npm.yml@master 22 | secrets: 23 | NPM_CI_TOKEN: ${{ secrets.NPM_CI_TOKEN }} 24 | GITHUB_CI_TOKEN: ${{ secrets.GITHUB_TOKEN }} 25 | with: 26 | enable_build: true 27 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Build 9 | dist 10 | temp 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | report.json 24 | eslint-report.* 25 | 26 | # nyc test coverage 27 | .nyc_output 28 | 29 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 30 | .grunt 31 | 32 | # Bower dependency directory (https://bower.io/) 33 | bower_components 34 | 35 | # node-waf configuration 36 | .lock-wscript 37 | 38 | # Compiled binary addons (https://nodejs.org/api/addons.html) 39 | build/Release 40 | 41 | # Dependency directories 42 | node_modules/ 43 | jspm_packages/ 44 | 45 | # TypeScript v1 declaration files 46 | typings/ 47 | 48 | # Optional npm cache directory 49 | .npm 50 | .npmrc 51 | 52 | # Optional eslint cache 53 | .eslintcache 54 | 55 | # Optional REPL history 56 | .node_repl_history 57 | 58 | # Output of 'npm pack' 59 | *.tgz 60 | 61 | # Yarn Integrity file 62 | .yarn-integrity 63 | 64 | # dotenv environment variables file 65 | .env 66 | 67 | # next.js build output 68 | .next -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | npx --no-install commitlint --edit $1 5 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | npm run lint & npm run test 5 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # [8.10.0](https://github.com/vodyani/core/compare/v8.9.8...v8.10.0) (2022-10-18) 2 | 3 | 4 | ### Features 5 | 6 | * add http & pagination interface ([50d0302](https://github.com/vodyani/core/commit/50d03027993abd2b81f10543c877fcd4747f9550)) 7 | 8 | ## [8.9.8](https://github.com/vodyani/core/compare/v8.9.7...v8.9.8) (2022-10-16) 9 | 10 | 11 | ### Bug Fixes 12 | 13 | * adjust the attributes associated with the config observer ([e945842](https://github.com/vodyani/core/commit/e9458422471e4810e3b1c50cece5be1ad599256b)) 14 | 15 | ## [8.9.7](https://github.com/vodyani/core/compare/v8.9.6...v8.9.7) (2022-10-15) 16 | 17 | 18 | ### Bug Fixes 19 | 20 | * reconstructing the data structure ([21667bb](https://github.com/vodyani/core/commit/21667bb19874ad73267a182356f9ddeb6797fb96)) 21 | 22 | ## [8.9.6](https://github.com/vodyani/core/compare/v8.9.5...v8.9.6) (2022-10-15) 23 | 24 | 25 | ### Bug Fixes 26 | 27 | * fix config loader scope of type compatibility ([1e5bc30](https://github.com/vodyani/core/commit/1e5bc307eb53e8204f7859d0adeb2fb5e8766d7e)) 28 | 29 | ## [8.9.5](https://github.com/vodyani/core/compare/v8.9.4...v8.9.5) (2022-10-14) 30 | 31 | 32 | ### Bug Fixes 33 | 34 | * client adapter ([a4af45b](https://github.com/vodyani/core/commit/a4af45bfa5346e5e9a5b13cb46a713d52686ace5)) 35 | 36 | ## [8.9.4](https://github.com/vodyani/core/compare/v8.9.3...v8.9.4) (2022-10-14) 37 | 38 | 39 | ### Bug Fixes 40 | 41 | * interface define ([f740279](https://github.com/vodyani/core/commit/f740279c32851b58716b46bdce52cd06c4a2fdeb)) 42 | 43 | ## [8.9.3](https://github.com/vodyani/core/compare/v8.9.2...v8.9.3) (2022-10-14) 44 | 45 | 46 | ### Bug Fixes 47 | 48 | * interface define ([2115181](https://github.com/vodyani/core/commit/21151819ee42a2c399f786f8e7ee18d3897e2f27)) 49 | 50 | ## [8.9.2](https://github.com/vodyani/core/compare/v8.9.1...v8.9.2) (2022-10-12) 51 | 52 | 53 | ### Bug Fixes 54 | 55 | * abstract create method 🐛 ([db6fb55](https://github.com/vodyani/core/commit/db6fb551489c7163a939955db3a71a652984517c)) 56 | 57 | ## [8.9.1](https://github.com/vodyani/core/compare/v8.9.0...v8.9.1) (2022-10-12) 58 | 59 | 60 | ### Bug Fixes 61 | 62 | * abstract create method 🐛 ([ca528e7](https://github.com/vodyani/core/commit/ca528e710b7430389a127752c503f4a51fdc9cc8)) 63 | 64 | # [8.9.0](https://github.com/vodyani/core/compare/v8.8.1...v8.9.0) (2022-10-12) 65 | 66 | 67 | ### Features 68 | 69 | * optimize the naming and interface structure ([fb2b64c](https://github.com/vodyani/core/commit/fb2b64c6ccaed3d500779bee144f9a65a74cfed8)) 70 | 71 | ## [8.8.1](https://github.com/vodyani/core/compare/v8.8.0...v8.8.1) (2022-09-25) 72 | 73 | 74 | ### Bug Fixes 75 | 76 | * remove post decorator ([db79757](https://github.com/vodyani/core/commit/db79757c703af3bb342ba36d280b4d0c3cd16e81)) 77 | 78 | # [8.8.0](https://github.com/vodyani/core/compare/v8.7.1...v8.8.0) (2022-09-24) 79 | 80 | 81 | ### Features 82 | 83 | * remove custom registration decorators and reduce base dependencies ([da331d5](https://github.com/vodyani/core/commit/da331d52663b894c1f0cab8500e22fd13fb6e90e)) 84 | 85 | # [8.8.0-beta.1](https://github.com/vodyani/core/compare/v8.7.1...v8.8.0-beta.1) (2022-09-24) 86 | 87 | 88 | ### Features 89 | 90 | * remove custom registration decorators and reduce base dependencies ([da331d5](https://github.com/vodyani/core/commit/da331d52663b894c1f0cab8500e22fd13fb6e90e)) 91 | 92 | ## [8.7.1](https://github.com/vodyani/core/compare/v8.7.0...v8.7.1) (2022-09-19) 93 | 94 | 95 | ### Bug Fixes 96 | 97 | * remote config client subscribe argument ([fb50ff8](https://github.com/vodyani/core/commit/fb50ff86ae5e3c9c218c5fb0bf3d1374c2b5bef1)) 98 | 99 | # [8.7.0](https://github.com/vodyani/core/compare/v8.6.9...v8.7.0) (2022-09-19) 100 | 101 | 102 | ### Features 103 | 104 | * change the interface convention for the remote configuration center ([6a5cb8f](https://github.com/vodyani/core/commit/6a5cb8fb68b91930d805ca851be4d71b514e7e3e)) 105 | 106 | ## [8.6.9](https://github.com/vodyani/core/compare/v8.6.8...v8.6.9) (2022-09-08) 107 | 108 | 109 | ### Bug Fixes 110 | 111 | * subscribe argument ([20428be](https://github.com/vodyani/core/commit/20428be184942464205f702b336cd2b98694275c)) 112 | 113 | ## [8.6.8](https://github.com/vodyani/core/compare/v8.6.7...v8.6.8) (2022-09-07) 114 | 115 | 116 | ### Bug Fixes 117 | 118 | * remote config client types ([325c1ad](https://github.com/vodyani/core/commit/325c1ad66d3449927a176d0fc439b520941f28e2)) 119 | 120 | ## [8.6.7](https://github.com/vodyani/core/compare/v8.6.6...v8.6.7) (2022-09-07) 121 | 122 | 123 | ### Bug Fixes 124 | 125 | * delete unnecessary types ([41c6747](https://github.com/vodyani/core/commit/41c67470c59795a22d2b99d5aa0b951c531219aa)) 126 | 127 | ## [8.6.6](https://github.com/vodyani/core/compare/v8.6.5...v8.6.6) (2022-09-02) 128 | 129 | 130 | ### Bug Fixes 131 | 132 | * centralize common top-level interfaces ([0b20742](https://github.com/vodyani/core/commit/0b207424e320aa7093ef2ee7afad8c6b92d4c530)) 133 | 134 | ## [8.6.6-beta.1](https://github.com/vodyani/core/compare/v8.6.5...v8.6.6-beta.1) (2022-09-02) 135 | 136 | 137 | ### Bug Fixes 138 | 139 | * centralize common top-level interfaces ([0b20742](https://github.com/vodyani/core/commit/0b207424e320aa7093ef2ee7afad8c6b92d4c530)) 140 | 141 | ## [8.6.5](https://github.com/vodyani/core/compare/v8.6.4...v8.6.5) (2022-09-01) 142 | 143 | 144 | ### Bug Fixes 145 | 146 | * unbind the express platform ([6bf6737](https://github.com/vodyani/core/commit/6bf6737eb06833afac165b32aff849e71ef58cb3)) 147 | 148 | ## [8.6.4](https://github.com/vodyani/core/compare/v8.6.3...v8.6.4) (2022-08-31) 149 | 150 | 151 | ### Bug Fixes 152 | 153 | * remove invalid dependency declarations ([9187fae](https://github.com/vodyani/core/commit/9187fae74b670721fc994d2e52a4920bd94d7601)) 154 | 155 | ## [8.6.3](https://github.com/vodyani/core/compare/v8.6.2...v8.6.3) (2022-08-31) 156 | 157 | 158 | ### Bug Fixes 159 | 160 | * express declare ([ece6dda](https://github.com/vodyani/core/commit/ece6ddaf54742ca4cecc09007838b72c24377119)) 161 | 162 | ## [8.6.2](https://github.com/vodyani/core/compare/v8.6.1...v8.6.2) (2022-08-31) 163 | 164 | 165 | ### Bug Fixes 166 | 167 | * add express dependencies ([f7b075a](https://github.com/vodyani/core/commit/f7b075a0b3ebd684b21a0b88359c71b9d4f229c7)) 168 | 169 | ## [8.6.1](https://github.com/vodyani/core/compare/v8.6.0...v8.6.1) (2022-08-31) 170 | 171 | 172 | ### Bug Fixes 173 | 174 | * composition methods and declarations ([7ab1b95](https://github.com/vodyani/core/commit/7ab1b95d38377b221650fd971faab87f2e9846a9)) 175 | 176 | # [8.6.0](https://github.com/vodyani/core/compare/v8.5.1...v8.6.0) (2022-08-30) 177 | 178 | 179 | ### Features 180 | 181 | * a small refactoring to aggregate scattered dependencies and modify logic of some decorators ([da32364](https://github.com/vodyani/core/commit/da323645ce1a5d6b524e5e4a4f1239cc741a4c91)) 182 | * change the way the asynchronous provider factory works and, in addition, add some decorators ([6ac9f2d](https://github.com/vodyani/core/commit/6ac9f2d9baceb88fc9ac364dde4d71472b710aaa)) 183 | 184 | ## [8.5.1](https://github.com/vodyani/core/compare/v8.5.0...v8.5.1) (2022-08-26) 185 | 186 | 187 | ### Bug Fixes 188 | 189 | * semantic-release workflow ([dbcfea4](https://github.com/vodyani/core/commit/dbcfea4f8c4a6d8ab206343fee8e651a49e6eb02)) 190 | 191 | # [8.5.0](https://github.com/vodyani/core/compare/v8.4.13...v8.5.0) (2022-08-12) 192 | 193 | 194 | ### Features 195 | 196 | * add decorator for asynchronous injection and optimize previous module registry ([abea2c6](https://github.com/vodyani/core/commit/abea2c6a6cac6f0019846df8460e495e293e5080)) 197 | 198 | # [8.5.0-beta.1](https://github.com/vodyani/core/compare/v8.4.13...v8.5.0-beta.1) (2022-08-12) 199 | 200 | 201 | ### Features 202 | 203 | * add decorator for asynchronous injection and optimize previous module registry ([abea2c6](https://github.com/vodyani/core/commit/abea2c6a6cac6f0019846df8460e495e293e5080)) 204 | 205 | ## [8.4.13](https://github.com/vodyani/core/compare/v8.4.12...v8.4.13) (2022-07-08) 206 | 207 | 208 | ### Bug Fixes 209 | 210 | * release publish ci ([fe263c6](https://github.com/vodyani/core/commit/fe263c6c184e5d4f1ea6bc0cfdd12e3a25c0446a)) 211 | 212 | ## [8.4.12](https://github.com/vodyani/core/compare/v8.4.11...v8.4.12) (2022-07-08) 213 | 214 | 215 | ### Bug Fixes 216 | 217 | * release publish ([2314c93](https://github.com/vodyani/core/commit/2314c939cae1166b377ba61d861262a38c58ad14)) 218 | 219 | ## [8.4.11](https://github.com/vodyani/core/compare/v8.4.10...v8.4.11) (2022-07-07) 220 | 221 | 222 | ### Bug Fixes 223 | 224 | * deps ([d70b4ae](https://github.com/vodyani/core/commit/d70b4ae017e5a4ca7a64fd15de2255c5b3e64703)) 225 | * github plugins ([ea4a740](https://github.com/vodyani/core/commit/ea4a740f749ecabe38c6eea1832f460ac73d07ca)) 226 | * github plugins ([90c7b82](https://github.com/vodyani/core/commit/90c7b82301828154c7118d9c772e3b683bf4645d)) 227 | 228 | ## [8.4.11-beta.3](https://github.com/vodyani/core/compare/v8.4.11-beta.2...v8.4.11-beta.3) (2022-07-07) 229 | 230 | 231 | ### Bug Fixes 232 | 233 | * github plugins ([ea4a740](https://github.com/vodyani/core/commit/ea4a740f749ecabe38c6eea1832f460ac73d07ca)) 234 | 235 | ## [8.4.11-beta.2](https://github.com/vodyani/core/compare/v8.4.11-beta.1...v8.4.11-beta.2) (2022-07-07) 236 | 237 | 238 | ### Bug Fixes 239 | 240 | * github plugins ([90c7b82](https://github.com/vodyani/core/commit/90c7b82301828154c7118d9c772e3b683bf4645d)) 241 | 242 | ## [8.4.11-beta.1](https://github.com/vodyani/core/compare/v8.4.10...v8.4.11-beta.1) (2022-07-07) 243 | 244 | 245 | ### Bug Fixes 246 | 247 | * deps ([d70b4ae](https://github.com/vodyani/core/commit/d70b4ae017e5a4ca7a64fd15de2255c5b3e64703)) 248 | 249 | ## [8.4.10](https://github.com/vodyani/core/compare/v8.4.9...v8.4.10) (2022-07-07) 250 | 251 | 252 | ### Bug Fixes 253 | 254 | * container register & domain service exports ([d02ef29](https://github.com/vodyani/core/commit/d02ef29fcba066e3c1d89c1d08ec4f036486c96b)) 255 | 256 | ## [8.4.10-beta.1](https://github.com/vodyani/core/compare/v8.4.9...v8.4.10-beta.1) (2022-07-07) 257 | 258 | 259 | ### Bug Fixes 260 | 261 | * container register & domain service exports ([d02ef29](https://github.com/vodyani/core/commit/d02ef29fcba066e3c1d89c1d08ec4f036486c96b)) 262 | 263 | ## [8.4.9](https://github.com/vodyani/core/compare/v8.4.8...v8.4.9) (2022-07-07) 264 | 265 | 266 | ### Bug Fixes 267 | 268 | * semantic-release plugins ([dbf5903](https://github.com/vodyani/core/commit/dbf5903d261c859a66ffc80717e2ce1d6977355c)) 269 | 270 | ## [8.4.8](https://github.com/vodyani/core/compare/v8.4.7...v8.4.8) (2022-07-07) 271 | 272 | 273 | ### Bug Fixes 274 | 275 | * semantic-release plugins ([f62186f](https://github.com/vodyani/core/commit/f62186fe4dbd71bed05ffe2f1fdd5b68801b7893)) 276 | 277 | ## [8.4.1](https://github.com/vodyani/core/compare/v8.4.0...v8.4.1) (2022-07-07) 278 | 279 | 280 | ### Bug Fixes 281 | 282 | * semantic-release ([7f9aead](https://github.com/vodyani/core/commit/7f9aeadf1c1a152bdcfcfc30bb4d5494d0088439)) 283 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022-present ChoGathK 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.MD: -------------------------------------------------------------------------------- 1 | # Vodyani core 2 | 3 | 👩🏻‍🚀 core 是 vodyani 的顶层设计集合。 4 | 5 | [![Npm](https://img.shields.io/npm/v/@vodyani/core/latest.svg)](https://www.npmjs.com/package/@vodyani/core) 6 | [![Npm](https://img.shields.io/npm/v/@vodyani/core/beta.svg)](https://www.npmjs.com/package/@vodyani/core) 7 | [![Npm](https://img.shields.io/npm/dm/@vodyani/core)](https://www.npmjs.com/package/@vodyani/core) 8 | [![License](https://img.shields.io/github/license/vodyani/core)](LICENSE) 9 |
10 | [![codecov](https://codecov.io/gh/vodyani/core/branch/main/graph/badge.svg?token=YHBHSZH5PB)](https://codecov.io/gh/vodyani/core) 11 | ![Workflow](https://github.com/vodyani/core/actions/workflows/release.yml/badge.svg) 12 | [![semantic-release: angular](https://img.shields.io/badge/semantic--release-angular-e10079?logo=semantic-release)](https://github.com/semantic-release/semantic-release) 13 | 14 | ## Installation 15 | 16 | ```sh 17 | npm install @vodyani/core 18 | ``` 19 | 20 | ## Getting started 21 | 22 | - [使用文档 📚](https://vodyani.netlify.app/docs/advanced/core) 23 | - [Documentation 📚](https://vodyani.netlify.app/en/docs/advanced/core) 24 | 25 | ## Questions 26 | 27 | - [Discussions 🧐](https://github.com/vodyani/core/discussions) 28 | 29 | ## Team 30 | 31 | |[![ChoGathK](https://github.com/chogathK.png?size=100)](https://github.com/chogathK)| 32 | |:-:| 33 | |[ChoGathK](https://github.com/chogathK)| 34 | 35 | ![Alt](https://repobeats.axiom.co/api/embed/cb8b521a295e8fa608771a42468fca99a125dfca.svg "Repobeats analytics image") 36 | 37 | ## License 38 | 39 | Vodyani core is [MIT licensed](LICENSE). 40 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@vodyani/core", 3 | "license": "MIT", 4 | "version": "8.10.0", 5 | "author": "ChoGathK", 6 | "description": "👩🏻‍🚀 core is the top-level design package for vodyani scaffolding, providing a single responsibility module registrar for the different tiers.", 7 | "homepage": "https://github.com/vodyani/core#readme", 8 | "repository": { 9 | "type": "git", 10 | "url": "git+https://github.com/vodyani/core.git" 11 | }, 12 | "bugs": { 13 | "url": "https://github.com/vodyani/core/issues" 14 | }, 15 | "keywords": [ 16 | "npm-package", 17 | "vodyani", 18 | "nestjs", 19 | "core" 20 | ], 21 | "files": [ 22 | "package.json", 23 | "README.MD", 24 | "LICENSE", 25 | "dist" 26 | ], 27 | "main": "dist/index.js", 28 | "scripts": { 29 | "local": "npm i && npm i @vodyani/eslint-config -D && npx husky install", 30 | "build": "rm -rf dist && tsc", 31 | "test": "jest", 32 | "test:coverage": "jest --coverage", 33 | "lint": "eslint ./src ./test && tsc", 34 | "lint:fix": "eslint --fix --ext .ts src/ test/", 35 | "lint:html-report": "eslint ./src ./test -f html -o eslint-report.html", 36 | "lint:json-report": "eslint ./src ./test -f json -o eslint-report.json" 37 | }, 38 | "publishConfig": { 39 | "access": "public" 40 | }, 41 | "eslintConfig": { 42 | "extends": "@vodyani" 43 | }, 44 | "commitlint": { 45 | "extends": "@commitlint/config-conventional" 46 | }, 47 | "jest": { 48 | "testEnvironment": "node", 49 | "testRegex": "(/test/.spec.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$", 50 | "moduleNameMapper": { 51 | "@/(.*)$": "/src/$1" 52 | }, 53 | "transform": { 54 | "^.+\\.js$": "babel-jest", 55 | "^.+\\.ts$": "ts-jest" 56 | }, 57 | "transformIgnorePatterns": [ 58 | "./node_modules/(?!(lodash-es|other-es-lib))" 59 | ] 60 | }, 61 | "dependencies": { 62 | "@nestjs/common": "8.4.7" 63 | }, 64 | "devDependencies": { 65 | "@commitlint/cli": "16.3.0", 66 | "@commitlint/config-conventional": "16.2.4", 67 | "@nestjs/testing": "8.4.7", 68 | "@types/jest": "27.5.2", 69 | "@types/node": "16.11.56", 70 | "@types/supertest": "2.0.12", 71 | "@vodyani/eslint-config": "^1.1.0", 72 | "husky": "7.0.4", 73 | "jest": "27.5.1", 74 | "supertest": "6.2.4", 75 | "ts-jest": "27.1.5", 76 | "typescript": "4.8.2" 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "config:base" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /src/common/index.ts: -------------------------------------------------------------------------------- 1 | export * from './interface'; 2 | -------------------------------------------------------------------------------- /src/common/interface/client.ts: -------------------------------------------------------------------------------- 1 | import { IConfigSubscriber } from './config'; 2 | 3 | export interface IClientAdapter { 4 | /** 5 | * Close the client. 6 | * 7 | * @publicApi 8 | */ 9 | close: () => void | Promise; 10 | /** 11 | * Get the client instance. 12 | * 13 | * @publicApi 14 | */ 15 | connect: () => T; 16 | /** 17 | * Create the client instance. 18 | * 19 | * @param config C The configuration of client instance 20 | * 21 | * @publicApi 22 | */ 23 | create: (config: C) => void | Promise; 24 | /** 25 | * Redeploy the client instance. 26 | * 27 | * @param config C The configuration of client instance 28 | * 29 | * @publicApi 30 | */ 31 | redeploy: (config: C) => void | Promise; 32 | } 33 | 34 | export interface IClientMediator extends IConfigSubscriber { 35 | /** 36 | * Destroy the client from mediator. 37 | * 38 | * @param key string The key of client. 39 | * 40 | * @publicApi 41 | */ 42 | destroy: (key: string) => void | Promise; 43 | /** 44 | * Deploy the client inside to mediator. 45 | * 46 | * @param key string The key of client. 47 | * @param client IClientAdapter The client. 48 | * 49 | * @publicApi 50 | */ 51 | deploy: (key: string, client: IClientAdapter) => void | Promise; 52 | /** 53 | * Redeploy the client inside to mediator. 54 | * 55 | * @param key string The key of client. 56 | * 57 | * @publicApi 58 | */ 59 | redeploy: (key: string, config: C) => void | Promise; 60 | /** 61 | * Get the client from mediator. 62 | * 63 | * @param key string The key of client. 64 | * 65 | * @publicApi 66 | */ 67 | getClient: (key: string) => IClientAdapter; 68 | } 69 | -------------------------------------------------------------------------------- /src/common/interface/config.ts: -------------------------------------------------------------------------------- 1 | export interface IObserver { 2 | /** 3 | * Register the subscriber inside client. 4 | * 5 | * @param ...args: any[] 6 | * 7 | * @publicApi 8 | */ 9 | subscribe: (...args: any[]) => void | Promise; 10 | /** 11 | * Remove the subscriber from client. 12 | * 13 | * @param ...args: any[] 14 | * 15 | * @publicApi 16 | */ 17 | unSubscribe: (...args: any[]) => void; 18 | /** 19 | * Notify subscribers of configuration updates. 20 | * 21 | * @param ...args: any[] 22 | * 23 | * @publicApi 24 | */ 25 | notify: (...args: any[]) => void; 26 | } 27 | 28 | export interface IConfig { 29 | /** 30 | * Deep search the configuration with property key. 31 | * 32 | * @param key string The property of configuration. 33 | * 34 | * @publicApi 35 | */ 36 | get: (key: string) => V; 37 | /** 38 | * Search the configuration with property key. 39 | * 40 | * @param key string The property of configuration. 41 | * 42 | * @publicApi 43 | */ 44 | search: (key: K) => T[K] 45 | /** 46 | * Replace the configuration with property key. 47 | * 48 | * @param key string The property of configuration. 49 | * @param value any The configuration value. 50 | * 51 | * @publicApi 52 | */ 53 | replace: (key: string, value: any) => void; 54 | /** 55 | * Merge the configuration. 56 | * 57 | * @param config any The configuration. 58 | * 59 | * @publicApi 60 | */ 61 | merge: (config: T) => void; 62 | } 63 | 64 | export interface IConfigSubscriber { 65 | /** 66 | * Updating Configuration. 67 | * 68 | * @param key string The property of configuration. 69 | * @param value any The configuration value. 70 | * 71 | * @publicApi 72 | */ 73 | update: (key: string, value: any) => void | Promise 74 | } 75 | 76 | export interface IConfigClientSubscriber { 77 | /** 78 | * Updating Configuration. 79 | * 80 | * @param value any The configuration value. 81 | * 82 | * @publicApi 83 | */ 84 | update: (value: any) => void | Promise 85 | } 86 | 87 | export interface IConfigLoader { 88 | /** 89 | * Load configuration. 90 | * 91 | * @publicApi 92 | */ 93 | execute: () => T | Promise; 94 | } 95 | 96 | export interface IConfigPoller { 97 | /** 98 | * Open the polling. 99 | * 100 | * @publicApi 101 | */ 102 | execute: () => void; 103 | /** 104 | * Close the polling. 105 | * 106 | * @publicApi 107 | */ 108 | close: () => void | Promise; 109 | } 110 | 111 | export interface IConfigObserver extends IObserver { 112 | /** 113 | * Register the subscriber inside client by the key of configuration. 114 | * 115 | * @param key string The key of configuration. 116 | * @param subscriber IConfigSubscriber The configuration subscriber. 117 | * 118 | * @publicApi 119 | */ 120 | subscribe: (key: string, subscriber: IConfigSubscriber) => void; 121 | /** 122 | * Remove the subscriber from client by the key of configuration.. 123 | * 124 | * @param key string The key of configuration. 125 | * 126 | * @publicApi 127 | */ 128 | unSubscribe: (key: string) => void; 129 | /** 130 | * Notify subscribers of configuration updates. 131 | * 132 | * @param key string The key of configuration. 133 | * @param value any The configuration value. 134 | * 135 | * @publicApi 136 | */ 137 | notify: (key: string, value: any) => void; 138 | /** 139 | * Open the polling. 140 | * 141 | * @publicApi 142 | */ 143 | polling: (...args: any[]) => void; 144 | /** 145 | * Close the polling. 146 | * 147 | * @publicApi 148 | */ 149 | unPolling: () => void; 150 | } 151 | 152 | export interface IConfigClient extends IObserver { 153 | /** 154 | * Load configuration. 155 | * 156 | * @param loader: IConfigLoader 157 | * 158 | * @publicApi 159 | */ 160 | init: (loader: IConfigLoader) => T | Promise; 161 | /** 162 | * Register the subscriber inside client. 163 | * 164 | * @param subscriber IConfigClientSubscriber The configuration client subscriber. 165 | * 166 | * @publicApi 167 | */ 168 | subscribe: (subscriber: IConfigClientSubscriber) => void; 169 | /** 170 | * Remove the subscriber from client. 171 | * 172 | * @publicApi 173 | */ 174 | unSubscribe: () => void; 175 | /** 176 | * Notify subscribers of configuration updates. 177 | * 178 | * @param value any The configuration value. 179 | * 180 | * @publicApi 181 | */ 182 | notify: (value: any) => void; 183 | /** 184 | * Open the polling. 185 | * 186 | * @publicApi 187 | */ 188 | polling: (...args: any[]) => void; 189 | /** 190 | * Close the polling. 191 | * 192 | * @publicApi 193 | */ 194 | unPolling: () => void; 195 | } 196 | -------------------------------------------------------------------------------- /src/common/interface/http.ts: -------------------------------------------------------------------------------- 1 | export interface IRequestPage { 2 | index?: number; 3 | size?: number; 4 | orderBy?: string; 5 | orderRule?: 'desc' | 'DESC' | 'asc' | 'ASC'; 6 | } 7 | 8 | export interface IResponseBody { 9 | data?: T; 10 | code?: number; 11 | message?: string; 12 | requestId?: string; 13 | requestTime?: number; 14 | responseTime?: number; 15 | } 16 | -------------------------------------------------------------------------------- /src/common/interface/index.ts: -------------------------------------------------------------------------------- 1 | export * from './client'; 2 | export * from './config'; 3 | export * from './http'; 4 | export * from './pagination'; 5 | export * from './provider'; 6 | -------------------------------------------------------------------------------- /src/common/interface/pagination.ts: -------------------------------------------------------------------------------- 1 | export interface IPage { 2 | index: number; 3 | size: number; 4 | count: number; 5 | pageCount: number; 6 | } 7 | 8 | export interface IPagination { 9 | rows: T; 10 | page: IPage; 11 | } 12 | -------------------------------------------------------------------------------- /src/common/interface/provider.ts: -------------------------------------------------------------------------------- 1 | import { FactoryProvider } from '@nestjs/common'; 2 | 3 | export interface IAsyncProviderFactory { 4 | /** 5 | * Create a factory provider by specifying the creation parameters externally. 6 | * 7 | * @see: [factory provider objects](https://docs.nestjs.com/fundamentals/custom-providers#factory-providers-usefactory) 8 | * 9 | * @returns FactoryProvider 10 | * 11 | * @publicApi 12 | */ 13 | create?: (...args: any[]) => FactoryProvider; 14 | } 15 | -------------------------------------------------------------------------------- /src/decorator/async-inject.ts: -------------------------------------------------------------------------------- 1 | import { Inject, Type } from '@nestjs/common'; 2 | 3 | import { AsyncProviderFactory, FactoryProviderStore } from '../struct'; 4 | 5 | /** 6 | * Use this decorator to handle dependency management for asynchronous provider factory classes. 7 | * 8 | * @param target The asynchronous provider factory class. 9 | * 10 | * @publicApi 11 | */ 12 | export function AsyncInjectable(target: Type) { 13 | FactoryProviderStore.set(target.name, Symbol(target.name)); 14 | } 15 | /** 16 | * Use this decorator to inject the asynchronous provider into the class instantiation process. 17 | * 18 | * @param target The asynchronous provider factory class. 19 | * 20 | * @publicApi 21 | */ 22 | export function AsyncInject(target: Type) { 23 | return Inject((target as any).getToken()); 24 | } 25 | -------------------------------------------------------------------------------- /src/decorator/index.ts: -------------------------------------------------------------------------------- 1 | export * from './async-inject'; 2 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export { AsyncProviderFactory } from './struct'; 2 | export * from './decorator'; 3 | export * from './common'; 4 | -------------------------------------------------------------------------------- /src/struct/index.ts: -------------------------------------------------------------------------------- 1 | export * from './provider'; 2 | export * from './store'; 3 | -------------------------------------------------------------------------------- /src/struct/provider.ts: -------------------------------------------------------------------------------- 1 | import { IAsyncProviderFactory } from '../common'; 2 | 3 | import { FactoryProviderStore } from './store'; 4 | 5 | export abstract class AsyncProviderFactory implements IAsyncProviderFactory { 6 | /** 7 | * Gets the static token for the async provider factory class. 8 | * 9 | * @returns symbol 10 | * 11 | * @publicStaticApi 12 | */ 13 | public static getToken() { 14 | return FactoryProviderStore.get(this.name); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/struct/store.ts: -------------------------------------------------------------------------------- 1 | export class FactoryProviderStore { 2 | private static readonly map = new Map(); 3 | 4 | public static get(key: string): symbol { 5 | return FactoryProviderStore.map.get(key); 6 | } 7 | 8 | public static set(key: string, token: symbol) { 9 | FactoryProviderStore.map.set(key, token); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /test/decorator.spec.ts: -------------------------------------------------------------------------------- 1 | import { beforeEach, describe, expect, it } from '@jest/globals'; 2 | import { Injectable, Module, Controller, Get } from '@nestjs/common'; 3 | import { Test } from '@nestjs/testing'; 4 | import * as request from 'supertest'; 5 | 6 | import { 7 | AsyncInject, 8 | AsyncInjectable, 9 | AsyncProviderFactory, 10 | } from '../src'; 11 | 12 | @AsyncInjectable 13 | class AsyncNameProvider extends AsyncProviderFactory { 14 | public create = () => ({ 15 | inject: [NameInfrastructureProvider], 16 | provide: AsyncNameProvider.getToken(), 17 | useFactory: (provider: NameInfrastructureProvider) => { 18 | return provider; 19 | }, 20 | }); 21 | } 22 | 23 | @Injectable() 24 | class NameInfrastructureProvider { 25 | public get() { 26 | return 'InfrastructureProvider'; 27 | } 28 | } 29 | 30 | @Module({ 31 | exports: [NameInfrastructureProvider], 32 | providers: [NameInfrastructureProvider], 33 | }) 34 | class NameInfrastructure {} 35 | 36 | @Injectable() 37 | class NameProvider { 38 | constructor( 39 | private readonly name: NameInfrastructureProvider, 40 | @AsyncInject(AsyncNameProvider) private readonly asyncName: any, 41 | ) {} 42 | 43 | public get() { 44 | return this.name.get(); 45 | } 46 | 47 | public getAsyncName() { 48 | return this.asyncName.get(); 49 | } 50 | } 51 | 52 | @Injectable() 53 | class NameService { 54 | constructor(private readonly name: NameProvider) {} 55 | 56 | public get() { 57 | return { 58 | name: this.name.get(), 59 | asyncName: this.name.getAsyncName(), 60 | }; 61 | } 62 | } 63 | 64 | @Module({ 65 | imports: [NameInfrastructure], 66 | exports: [NameService], 67 | providers: [NameService, NameProvider, new AsyncNameProvider().create()], 68 | }) 69 | class NameDomain {} 70 | 71 | 72 | @Controller('name') 73 | class NameController { 74 | constructor(private readonly name: NameService) {} 75 | 76 | @Get() 77 | result() { 78 | return { data: this.name.get() }; 79 | } 80 | } 81 | 82 | @Module({ 83 | imports: [NameDomain], 84 | controllers: [NameController], 85 | }) 86 | class NameApi {} 87 | 88 | @Module({ imports: [NameApi] }) 89 | class AppModule {} 90 | 91 | let app: any; 92 | 93 | beforeEach(async () => { 94 | const moduleRef = await Test.createTestingModule({ imports: [AppModule] }).compile(); 95 | app = moduleRef.createNestApplication(); 96 | await app.init(); 97 | }); 98 | 99 | describe('decorator', () => { 100 | it('test', async () => { 101 | const data = await request(app.getHttpServer()).get('/name'); 102 | 103 | expect(data.statusCode).toBe(200); 104 | expect(data.body.data.name).toBe('InfrastructureProvider'); 105 | expect(data.body.data.asyncName).toBe('InfrastructureProvider'); 106 | 107 | await app.close(); 108 | }); 109 | }); 110 | -------------------------------------------------------------------------------- /test/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "include": ["**/*.spec.ts"], 4 | "exclude": ["node_modules", "dist"], 5 | } -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": [ 3 | "src", 4 | ], 5 | "compilerOptions": { 6 | "baseUrl": ".", 7 | "lib": ["ESNext"], 8 | "target": "ES6", 9 | "outDir": "dist", 10 | "module": "CommonJS", 11 | "sourceMap": true, 12 | "declaration": true, 13 | "incremental": false, 14 | "skipLibCheck": true, 15 | "noImplicitAny": true, 16 | "noImplicitThis": true, 17 | "removeComments": false, 18 | "emitDecoratorMetadata": true, 19 | "experimentalDecorators": true 20 | } 21 | } --------------------------------------------------------------------------------