├── .eslintrc ├── .gitattributes ├── .gitignore ├── Dockerfile ├── README.md ├── docs └── onion-architecture.png ├── package-lock.json ├── package.json ├── src ├── api │ └── http │ │ ├── controller.ts │ │ ├── middlewares │ │ └── error-handler.ts │ │ ├── router.ts │ │ ├── server.ts │ │ └── validation │ │ ├── cart.ts │ │ └── item.ts ├── app │ ├── cart.ts │ └── item.ts ├── container.ts ├── domain │ ├── cart.ts │ ├── entity.ts │ ├── item.ts │ └── repository.ts ├── infra │ ├── database │ │ └── memory │ │ │ ├── mappers │ │ │ ├── cart.ts │ │ │ └── item.ts │ │ │ ├── memory-data.ts │ │ │ └── repositories │ │ │ ├── cart.ts │ │ │ └── item.ts │ └── logging │ │ └── pino.ts ├── libs │ └── errors.ts ├── main.ts └── types.ts └── tsconfig.json /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "@typescript-eslint/parser", 3 | "parserOptions": { 4 | "ecmaVersion": 2020, 5 | "sourceType": "module" 6 | }, 7 | "extends": ["plugin:@typescript-eslint/recommended", "plugin:prettier/recommended"], 8 | "plugins": ["@typescript-eslint", "prettier"], 9 | "env": { 10 | "es6": true, 11 | "node": true, 12 | "jest": true 13 | }, 14 | "rules": { 15 | "prettier/prettier": "error" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ### OS ### 2 | .DS_Store 3 | 4 | ### IDE ### 5 | .vscode/ 6 | 7 | ### Node ### 8 | # Logs 9 | logs 10 | *.log 11 | npm-debug.log* 12 | 13 | # Runtime data 14 | pids 15 | *.pid 16 | *.seed 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 | 24 | # nyc test coverage 25 | .nyc_output 26 | 27 | # node-waf configuration 28 | .lock-wscript 29 | 30 | # Compiled binary addons (http://nodejs.org/api/addons.html) 31 | build/Release 32 | 33 | # Dependency directories 34 | node_modules 35 | jspm_packages 36 | 37 | # Optional npm cache directory 38 | .npm 39 | 40 | # Optional REPL history 41 | .node_repl_history 42 | 43 | # Build 44 | build 45 | dist 46 | 47 | # dotenv 48 | .env -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:14-alpine 2 | WORKDIR /usr/app 3 | 4 | COPY src ./src 5 | COPY package.json package-lock.json tsconfig.json ./ 6 | 7 | RUN npm install && \ 8 | npm run build 9 | 10 | EXPOSE 3000 11 | 12 | CMD ["npm", "start"] -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # shopping-cart 2 | 3 | A DDD shopping cart application focused on separation of concerns and scalability. 4 | 5 | ## Philosofy 6 | 7 | Main concepts for this architecture are around codebase scalability. The goal is to provide a clean architecture while flexible for implementing and growing functionalities into the codebase. 8 | 9 | Everything is highly testable, given low coupling with clear dependency graphs provided by Inversion of Control. 10 | 11 | ## Architecture 12 | 13 | ![Onion Architecture](docs/onion-architecture.png) 14 | 15 | ## Folder structure 16 | 17 | . 18 | └── src 19 | ├── api # Layer that exposes application to external world (primary adapters) 20 | │   └── http # Exposes application over HTTP protocol 21 | ├── app # Layer that composes application use cases 22 | ├── domain # Business domain classes and everything that composes domain model 23 | ├── infra # Communication with what is external of application 24 | └── libs # Common functionalities 25 | 26 | ## API 27 | 28 | ### Create an item 29 | 30 | POST http://localhost:3000/item 31 | 32 | ```json 33 | { 34 | "sku": "AS-1234", 35 | "displayName": "My first item", 36 | "price": 100 37 | } 38 | ``` 39 | 40 | ### List items 41 | 42 | GET http://localhost:3000/item 43 | 44 | ### Add item to shopping cart 45 | 46 | - If shopping cart doesn't exist, it is going to be created. 47 | - If itemId already exists, quantity for existing item in the cart will be increased. 48 | 49 | POST http://localhost:3000/cart/1/item 50 | 51 | ```json 52 | { 53 | "itemId": "ck0r5ypdz0000ppo73m4o8hfa", 54 | "quantity": 1 55 | } 56 | ``` 57 | 58 | ### Delete item from cart 59 | 60 | DELETE http://localhost:3000/cart/1/item/ck0r46c9w0000y9o70hvh605j 61 | 62 | ### Empty all items for a cart 63 | 64 | POST http://localhost:3000/cart/1/clean 65 | -------------------------------------------------------------------------------- /docs/onion-architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bazaglia/shopping-cart/c34cc86e5e73b255b47fcef9d9aa3d3435685ff3/docs/onion-architecture.png -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "shopping-cart-api", 3 | "version": "0.1.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@babel/code-frame": { 8 | "version": "7.12.11", 9 | "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", 10 | "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", 11 | "dev": true, 12 | "requires": { 13 | "@babel/highlight": "^7.10.4" 14 | } 15 | }, 16 | "@babel/helper-validator-identifier": { 17 | "version": "7.14.8", 18 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.8.tgz", 19 | "integrity": "sha512-ZGy6/XQjllhYQrNw/3zfWRwZCTVSiBLZ9DHVZxn9n2gip/7ab8mv2TWlKPIBk26RwedCBoWdjLmn+t9na2Gcow==", 20 | "dev": true 21 | }, 22 | "@babel/highlight": { 23 | "version": "7.14.5", 24 | "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", 25 | "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", 26 | "dev": true, 27 | "requires": { 28 | "@babel/helper-validator-identifier": "^7.14.5", 29 | "chalk": "^2.0.0", 30 | "js-tokens": "^4.0.0" 31 | } 32 | }, 33 | "@eslint/eslintrc": { 34 | "version": "0.4.3", 35 | "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", 36 | "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", 37 | "dev": true, 38 | "requires": { 39 | "ajv": "^6.12.4", 40 | "debug": "^4.1.1", 41 | "espree": "^7.3.0", 42 | "globals": "^13.9.0", 43 | "ignore": "^4.0.6", 44 | "import-fresh": "^3.2.1", 45 | "js-yaml": "^3.13.1", 46 | "minimatch": "^3.0.4", 47 | "strip-json-comments": "^3.1.1" 48 | }, 49 | "dependencies": { 50 | "strip-json-comments": { 51 | "version": "3.1.1", 52 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", 53 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", 54 | "dev": true 55 | } 56 | } 57 | }, 58 | "@hapi/boom": { 59 | "version": "7.4.11", 60 | "resolved": "https://registry.npmjs.org/@hapi/boom/-/boom-7.4.11.tgz", 61 | "integrity": "sha512-VSU/Cnj1DXouukYxxkes4nNJonCnlogHvIff1v1RVoN4xzkKhMXX+GRmb3NyH1iar10I9WFPDv2JPwfH3GaV0A==", 62 | "requires": { 63 | "@hapi/hoek": "8.x.x" 64 | } 65 | }, 66 | "@hapi/bourne": { 67 | "version": "2.0.0", 68 | "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-2.0.0.tgz", 69 | "integrity": "sha512-WEezM1FWztfbzqIUbsDzFRVMxSoLy3HugVcux6KDDtTqzPsLE8NDRHfXvev66aH1i2oOKKar3/XDjbvh/OUBdg==", 70 | "dev": true 71 | }, 72 | "@hapi/hoek": { 73 | "version": "8.5.1", 74 | "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-8.5.1.tgz", 75 | "integrity": "sha512-yN7kbciD87WzLGc5539Tn0sApjyiGHAJgKvG9W8C7O+6c7qmoQMfVs0W4bX17eqz6C78QJqqFrtgdK5EWf6Qow==" 76 | }, 77 | "@hapi/topo": { 78 | "version": "5.1.0", 79 | "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", 80 | "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", 81 | "requires": { 82 | "@hapi/hoek": "^9.0.0" 83 | }, 84 | "dependencies": { 85 | "@hapi/hoek": { 86 | "version": "9.2.0", 87 | "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.2.0.tgz", 88 | "integrity": "sha512-sqKVVVOe5ivCaXDWivIJYVSaEgdQK9ul7a4Kity5Iw7u9+wBAPbX1RMSnLLmp7O4Vzj0WOWwMAJsTL00xwaNug==" 89 | } 90 | } 91 | }, 92 | "@humanwhocodes/config-array": { 93 | "version": "0.5.0", 94 | "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", 95 | "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", 96 | "dev": true, 97 | "requires": { 98 | "@humanwhocodes/object-schema": "^1.2.0", 99 | "debug": "^4.1.1", 100 | "minimatch": "^3.0.4" 101 | } 102 | }, 103 | "@humanwhocodes/object-schema": { 104 | "version": "1.2.0", 105 | "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", 106 | "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==", 107 | "dev": true 108 | }, 109 | "@koa/cors": { 110 | "version": "3.1.0", 111 | "resolved": "https://registry.npmjs.org/@koa/cors/-/cors-3.1.0.tgz", 112 | "integrity": "sha512-7ulRC1da/rBa6kj6P4g2aJfnET3z8Uf3SWu60cjbtxTA5g8lxRdX/Bd2P92EagGwwAhANeNw8T8if99rJliR6Q==", 113 | "requires": { 114 | "vary": "^1.1.2" 115 | } 116 | }, 117 | "@koa/router": { 118 | "version": "8.0.8", 119 | "resolved": "https://registry.npmjs.org/@koa/router/-/router-8.0.8.tgz", 120 | "integrity": "sha512-FnT93N4NUehnXr+juupDmG2yfi0JnWdCmNEuIXpCG4TtG+9xvtrLambBH3RclycopVUOEYAim2lydiNBI7IRVg==", 121 | "requires": { 122 | "debug": "^4.1.1", 123 | "http-errors": "^1.7.3", 124 | "koa-compose": "^4.1.0", 125 | "methods": "^1.1.2", 126 | "path-to-regexp": "1.x", 127 | "urijs": "^1.19.2" 128 | } 129 | }, 130 | "@nodelib/fs.scandir": { 131 | "version": "2.1.5", 132 | "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", 133 | "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", 134 | "dev": true, 135 | "requires": { 136 | "@nodelib/fs.stat": "2.0.5", 137 | "run-parallel": "^1.1.9" 138 | } 139 | }, 140 | "@nodelib/fs.stat": { 141 | "version": "2.0.5", 142 | "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", 143 | "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", 144 | "dev": true 145 | }, 146 | "@nodelib/fs.walk": { 147 | "version": "1.2.8", 148 | "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", 149 | "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", 150 | "dev": true, 151 | "requires": { 152 | "@nodelib/fs.scandir": "2.1.5", 153 | "fastq": "^1.6.0" 154 | } 155 | }, 156 | "@sideway/address": { 157 | "version": "4.1.2", 158 | "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.2.tgz", 159 | "integrity": "sha512-idTz8ibqWFrPU8kMirL0CoPH/A29XOzzAzpyN3zQ4kAWnzmNfFmRaoMNN6VI8ske5M73HZyhIaW4OuSFIdM4oA==", 160 | "requires": { 161 | "@hapi/hoek": "^9.0.0" 162 | }, 163 | "dependencies": { 164 | "@hapi/hoek": { 165 | "version": "9.2.0", 166 | "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.2.0.tgz", 167 | "integrity": "sha512-sqKVVVOe5ivCaXDWivIJYVSaEgdQK9ul7a4Kity5Iw7u9+wBAPbX1RMSnLLmp7O4Vzj0WOWwMAJsTL00xwaNug==" 168 | } 169 | } 170 | }, 171 | "@sideway/formula": { 172 | "version": "3.0.0", 173 | "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.0.tgz", 174 | "integrity": "sha512-vHe7wZ4NOXVfkoRb8T5otiENVlT7a3IAiw7H5M2+GO+9CDgcVUUsX1zalAztCmwyOr2RUTGJdgB+ZvSVqmdHmg==" 175 | }, 176 | "@sideway/pinpoint": { 177 | "version": "2.0.0", 178 | "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", 179 | "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==" 180 | }, 181 | "@tsconfig/node10": { 182 | "version": "1.0.8", 183 | "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", 184 | "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", 185 | "dev": true 186 | }, 187 | "@tsconfig/node12": { 188 | "version": "1.0.9", 189 | "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", 190 | "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", 191 | "dev": true 192 | }, 193 | "@tsconfig/node14": { 194 | "version": "1.0.1", 195 | "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", 196 | "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", 197 | "dev": true 198 | }, 199 | "@tsconfig/node16": { 200 | "version": "1.0.2", 201 | "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", 202 | "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", 203 | "dev": true 204 | }, 205 | "@types/accepts": { 206 | "version": "1.3.5", 207 | "resolved": "https://registry.npmjs.org/@types/accepts/-/accepts-1.3.5.tgz", 208 | "integrity": "sha512-jOdnI/3qTpHABjM5cx1Hc0sKsPoYCp+DP/GJRGtDlPd7fiV9oXGGIcjW/ZOxLIvjGz8MA+uMZI9metHlgqbgwQ==", 209 | "dev": true, 210 | "requires": { 211 | "@types/node": "*" 212 | } 213 | }, 214 | "@types/body-parser": { 215 | "version": "1.19.1", 216 | "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.1.tgz", 217 | "integrity": "sha512-a6bTJ21vFOGIkwM0kzh9Yr89ziVxq4vYH2fQ6N8AeipEzai/cFK6aGMArIkUeIdRIgpwQa+2bXiLuUJCpSf2Cg==", 218 | "dev": true, 219 | "requires": { 220 | "@types/connect": "*", 221 | "@types/node": "*" 222 | } 223 | }, 224 | "@types/connect": { 225 | "version": "3.4.35", 226 | "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", 227 | "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", 228 | "dev": true, 229 | "requires": { 230 | "@types/node": "*" 231 | } 232 | }, 233 | "@types/content-disposition": { 234 | "version": "0.5.4", 235 | "resolved": "https://registry.npmjs.org/@types/content-disposition/-/content-disposition-0.5.4.tgz", 236 | "integrity": "sha512-0mPF08jn9zYI0n0Q/Pnz7C4kThdSt+6LD4amsrYDDpgBfrVWa3TcCOxKX1zkGgYniGagRv8heN2cbh+CAn+uuQ==", 237 | "dev": true 238 | }, 239 | "@types/cookies": { 240 | "version": "0.7.7", 241 | "resolved": "https://registry.npmjs.org/@types/cookies/-/cookies-0.7.7.tgz", 242 | "integrity": "sha512-h7BcvPUogWbKCzBR2lY4oqaZbO3jXZksexYJVFvkrFeLgbZjQkU4x8pRq6eg2MHXQhY0McQdqmmsxRWlVAHooA==", 243 | "dev": true, 244 | "requires": { 245 | "@types/connect": "*", 246 | "@types/express": "*", 247 | "@types/keygrip": "*", 248 | "@types/node": "*" 249 | } 250 | }, 251 | "@types/express": { 252 | "version": "4.17.13", 253 | "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz", 254 | "integrity": "sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==", 255 | "dev": true, 256 | "requires": { 257 | "@types/body-parser": "*", 258 | "@types/express-serve-static-core": "^4.17.18", 259 | "@types/qs": "*", 260 | "@types/serve-static": "*" 261 | } 262 | }, 263 | "@types/express-serve-static-core": { 264 | "version": "4.17.24", 265 | "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.24.tgz", 266 | "integrity": "sha512-3UJuW+Qxhzwjq3xhwXm2onQcFHn76frIYVbTu+kn24LFxI+dEhdfISDFovPB8VpEgW8oQCTpRuCe+0zJxB7NEA==", 267 | "dev": true, 268 | "requires": { 269 | "@types/node": "*", 270 | "@types/qs": "*", 271 | "@types/range-parser": "*" 272 | } 273 | }, 274 | "@types/hapi__boom": { 275 | "version": "7.4.1", 276 | "resolved": "https://registry.npmjs.org/@types/hapi__boom/-/hapi__boom-7.4.1.tgz", 277 | "integrity": "sha512-x/ZK824GomII7Yoei/nMoB46NQcSfGe0iVpZK3uUivxIAfUUSzRvu8RQO7ZkKapIgzgshHZc+GR+z/BQ8l2VLg==", 278 | "dev": true 279 | }, 280 | "@types/http-assert": { 281 | "version": "1.5.1", 282 | "resolved": "https://registry.npmjs.org/@types/http-assert/-/http-assert-1.5.1.tgz", 283 | "integrity": "sha512-PGAK759pxyfXE78NbKxyfRcWYA/KwW17X290cNev/qAsn9eQIxkH4shoNBafH37wewhDG/0p1cHPbK6+SzZjWQ==", 284 | "dev": true 285 | }, 286 | "@types/http-errors": { 287 | "version": "1.8.1", 288 | "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-1.8.1.tgz", 289 | "integrity": "sha512-e+2rjEwK6KDaNOm5Aa9wNGgyS9oSZU/4pfSMMPYNOfjvFI0WVXm29+ITRFr6aKDvvKo7uU1jV68MW4ScsfDi7Q==", 290 | "dev": true 291 | }, 292 | "@types/joi": { 293 | "version": "17.2.3", 294 | "resolved": "https://registry.npmjs.org/@types/joi/-/joi-17.2.3.tgz", 295 | "integrity": "sha512-dGjs/lhrWOa+eO0HwgxCSnDm5eMGCsXuvLglMghJq32F6q5LyyNuXb41DHzrg501CKNOSSAHmfB7FDGeUnDmzw==", 296 | "dev": true, 297 | "requires": { 298 | "joi": "*" 299 | } 300 | }, 301 | "@types/json-schema": { 302 | "version": "7.0.8", 303 | "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.8.tgz", 304 | "integrity": "sha512-YSBPTLTVm2e2OoQIDYx8HaeWJ5tTToLH67kXR7zYNGupXMEHa2++G8k+DczX2cFVgalypqtyZIcU19AFcmOpmg==", 305 | "dev": true 306 | }, 307 | "@types/keygrip": { 308 | "version": "1.0.2", 309 | "resolved": "https://registry.npmjs.org/@types/keygrip/-/keygrip-1.0.2.tgz", 310 | "integrity": "sha512-GJhpTepz2udxGexqos8wgaBx4I/zWIDPh/KOGEwAqtuGDkOUJu5eFvwmdBX4AmB8Odsr+9pHCQqiAqDL/yKMKw==", 311 | "dev": true 312 | }, 313 | "@types/koa": { 314 | "version": "2.13.4", 315 | "resolved": "https://registry.npmjs.org/@types/koa/-/koa-2.13.4.tgz", 316 | "integrity": "sha512-dfHYMfU+z/vKtQB7NUrthdAEiSvnLebvBjwHtfFmpZmB7em2N3WVQdHgnFq+xvyVgxW5jKDmjWfLD3lw4g4uTw==", 317 | "dev": true, 318 | "requires": { 319 | "@types/accepts": "*", 320 | "@types/content-disposition": "*", 321 | "@types/cookies": "*", 322 | "@types/http-assert": "*", 323 | "@types/http-errors": "*", 324 | "@types/keygrip": "*", 325 | "@types/koa-compose": "*", 326 | "@types/node": "*" 327 | } 328 | }, 329 | "@types/koa-bodyparser": { 330 | "version": "4.3.2", 331 | "resolved": "https://registry.npmjs.org/@types/koa-bodyparser/-/koa-bodyparser-4.3.2.tgz", 332 | "integrity": "sha512-fjNPSs3qNs/sKVT6O6VdF+RTBd5HLlFtFmAZxWGiOPwCm7+/jhia462Ni30XmCM2ziUbfx2pa79NkHDBI0TgAQ==", 333 | "dev": true, 334 | "requires": { 335 | "@types/koa": "*" 336 | } 337 | }, 338 | "@types/koa-compose": { 339 | "version": "3.2.5", 340 | "resolved": "https://registry.npmjs.org/@types/koa-compose/-/koa-compose-3.2.5.tgz", 341 | "integrity": "sha512-B8nG/OoE1ORZqCkBVsup/AKcvjdgoHnfi4pZMn5UwAPCbhk/96xyv284eBYW8JlQbQ7zDmnpFr68I/40mFoIBQ==", 342 | "dev": true, 343 | "requires": { 344 | "@types/koa": "*" 345 | } 346 | }, 347 | "@types/koa-compress": { 348 | "version": "2.0.9", 349 | "resolved": "https://registry.npmjs.org/@types/koa-compress/-/koa-compress-2.0.9.tgz", 350 | "integrity": "sha512-1Sa9OsbHd2N2N7gLpdIRHe8W99EZbfIR31D7Iisx16XgwZCnWUtGXzXQejhu74Y1pE/wILqBP6VL49ch/MVpZw==", 351 | "dev": true, 352 | "requires": { 353 | "@types/koa": "*", 354 | "@types/node": "*" 355 | } 356 | }, 357 | "@types/koa__cors": { 358 | "version": "2.2.3", 359 | "resolved": "https://registry.npmjs.org/@types/koa__cors/-/koa__cors-2.2.3.tgz", 360 | "integrity": "sha512-RfG2EuSc+nv/E+xbDSLW8KCoeri/3AkqwVPuENfF/DctllRoXhooboO//Sw7yFtkLvj7nG7O1H3JcZmoTQz8nQ==", 361 | "dev": true, 362 | "requires": { 363 | "@types/koa": "*" 364 | } 365 | }, 366 | "@types/koa__router": { 367 | "version": "8.0.7", 368 | "resolved": "https://registry.npmjs.org/@types/koa__router/-/koa__router-8.0.7.tgz", 369 | "integrity": "sha512-OB3Ax75nmTP+WR9AgdzA42DI7YmBtiNKN2g1Wxl+d5Dyek9SWt740t+ukwXSmv/jMBCUPyV3YEI93vZHgdP7UQ==", 370 | "dev": true, 371 | "requires": { 372 | "@types/koa": "*" 373 | } 374 | }, 375 | "@types/mime": { 376 | "version": "1.3.2", 377 | "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", 378 | "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", 379 | "dev": true 380 | }, 381 | "@types/node": { 382 | "version": "12.20.16", 383 | "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.16.tgz", 384 | "integrity": "sha512-6CLxw83vQf6DKqXxMPwl8qpF8I7THFZuIwLt4TnNsumxkp1VsRZWT8txQxncT/Rl2UojTsFzWgDG4FRMwafrlA==", 385 | "dev": true 386 | }, 387 | "@types/pino": { 388 | "version": "6.3.9", 389 | "resolved": "https://registry.npmjs.org/@types/pino/-/pino-6.3.9.tgz", 390 | "integrity": "sha512-2/XV6adNNCLWnT2lJqcSn/OXrCxRFOY6yXYoofrLy5Ts5e8RHTJP1M4XEcCarQQMa6H6JISaa4GkrlGZwIP5aQ==", 391 | "dev": true, 392 | "requires": { 393 | "@types/node": "*", 394 | "@types/pino-pretty": "*", 395 | "@types/pino-std-serializers": "*", 396 | "@types/sonic-boom": "*" 397 | } 398 | }, 399 | "@types/pino-pretty": { 400 | "version": "4.7.1", 401 | "resolved": "https://registry.npmjs.org/@types/pino-pretty/-/pino-pretty-4.7.1.tgz", 402 | "integrity": "sha512-l1ntNXdpVWsnPYUk5HyO5Lxfr38zLCgxVfEn/9Zhhm+nGF04/BiIou/m8XPwvoVZLV+livUo79VdHXMJPfUYxA==", 403 | "dev": true, 404 | "requires": { 405 | "@types/pino": "*" 406 | } 407 | }, 408 | "@types/pino-std-serializers": { 409 | "version": "2.4.1", 410 | "resolved": "https://registry.npmjs.org/@types/pino-std-serializers/-/pino-std-serializers-2.4.1.tgz", 411 | "integrity": "sha512-17XcksO47M24IVTVKPeAByWUd3Oez7EbIjXpSbzMPhXVzgjGtrOa49gKBwxH9hb8dKv58OelsWQ+A1G1l9S3wQ==", 412 | "dev": true, 413 | "requires": { 414 | "@types/node": "*" 415 | } 416 | }, 417 | "@types/qs": { 418 | "version": "6.9.7", 419 | "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", 420 | "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", 421 | "dev": true 422 | }, 423 | "@types/range-parser": { 424 | "version": "1.2.4", 425 | "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", 426 | "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", 427 | "dev": true 428 | }, 429 | "@types/serve-static": { 430 | "version": "1.13.10", 431 | "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.10.tgz", 432 | "integrity": "sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==", 433 | "dev": true, 434 | "requires": { 435 | "@types/mime": "^1", 436 | "@types/node": "*" 437 | } 438 | }, 439 | "@types/sonic-boom": { 440 | "version": "0.7.0", 441 | "resolved": "https://registry.npmjs.org/@types/sonic-boom/-/sonic-boom-0.7.0.tgz", 442 | "integrity": "sha512-AfqR0fZMoUXUNwusgXKxcE9DPlHNDHQp6nKYUd4PSRpLobF5CCevSpyTEBcVZreqaWKCnGBr9KI1fHMTttoB7A==", 443 | "dev": true, 444 | "requires": { 445 | "@types/node": "*" 446 | } 447 | }, 448 | "@typescript-eslint/eslint-plugin": { 449 | "version": "4.28.4", 450 | "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.28.4.tgz", 451 | "integrity": "sha512-s1oY4RmYDlWMlcV0kKPBaADn46JirZzvvH7c2CtAqxCY96S538JRBAzt83RrfkDheV/+G/vWNK0zek+8TB3Gmw==", 452 | "dev": true, 453 | "requires": { 454 | "@typescript-eslint/experimental-utils": "4.28.4", 455 | "@typescript-eslint/scope-manager": "4.28.4", 456 | "debug": "^4.3.1", 457 | "functional-red-black-tree": "^1.0.1", 458 | "regexpp": "^3.1.0", 459 | "semver": "^7.3.5", 460 | "tsutils": "^3.21.0" 461 | }, 462 | "dependencies": { 463 | "semver": { 464 | "version": "7.3.5", 465 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", 466 | "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", 467 | "dev": true, 468 | "requires": { 469 | "lru-cache": "^6.0.0" 470 | } 471 | } 472 | } 473 | }, 474 | "@typescript-eslint/experimental-utils": { 475 | "version": "4.28.4", 476 | "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.28.4.tgz", 477 | "integrity": "sha512-OglKWOQRWTCoqMSy6pm/kpinEIgdcXYceIcH3EKWUl4S8xhFtN34GQRaAvTIZB9DD94rW7d/U7tUg3SYeDFNHA==", 478 | "dev": true, 479 | "requires": { 480 | "@types/json-schema": "^7.0.7", 481 | "@typescript-eslint/scope-manager": "4.28.4", 482 | "@typescript-eslint/types": "4.28.4", 483 | "@typescript-eslint/typescript-estree": "4.28.4", 484 | "eslint-scope": "^5.1.1", 485 | "eslint-utils": "^3.0.0" 486 | }, 487 | "dependencies": { 488 | "eslint-utils": { 489 | "version": "3.0.0", 490 | "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", 491 | "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", 492 | "dev": true, 493 | "requires": { 494 | "eslint-visitor-keys": "^2.0.0" 495 | } 496 | } 497 | } 498 | }, 499 | "@typescript-eslint/parser": { 500 | "version": "4.28.4", 501 | "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.28.4.tgz", 502 | "integrity": "sha512-4i0jq3C6n+og7/uCHiE6q5ssw87zVdpUj1k6VlVYMonE3ILdFApEzTWgppSRG4kVNB/5jxnH+gTeKLMNfUelQA==", 503 | "dev": true, 504 | "requires": { 505 | "@typescript-eslint/scope-manager": "4.28.4", 506 | "@typescript-eslint/types": "4.28.4", 507 | "@typescript-eslint/typescript-estree": "4.28.4", 508 | "debug": "^4.3.1" 509 | } 510 | }, 511 | "@typescript-eslint/scope-manager": { 512 | "version": "4.28.4", 513 | "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.28.4.tgz", 514 | "integrity": "sha512-ZJBNs4usViOmlyFMt9X9l+X0WAFcDH7EdSArGqpldXu7aeZxDAuAzHiMAeI+JpSefY2INHrXeqnha39FVqXb8w==", 515 | "dev": true, 516 | "requires": { 517 | "@typescript-eslint/types": "4.28.4", 518 | "@typescript-eslint/visitor-keys": "4.28.4" 519 | } 520 | }, 521 | "@typescript-eslint/types": { 522 | "version": "4.28.4", 523 | "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.28.4.tgz", 524 | "integrity": "sha512-3eap4QWxGqkYuEmVebUGULMskR6Cuoc/Wii0oSOddleP4EGx1tjLnZQ0ZP33YRoMDCs5O3j56RBV4g14T4jvww==", 525 | "dev": true 526 | }, 527 | "@typescript-eslint/typescript-estree": { 528 | "version": "4.28.4", 529 | "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.28.4.tgz", 530 | "integrity": "sha512-z7d8HK8XvCRyN2SNp+OXC2iZaF+O2BTquGhEYLKLx5k6p0r05ureUtgEfo5f6anLkhCxdHtCf6rPM1p4efHYDQ==", 531 | "dev": true, 532 | "requires": { 533 | "@typescript-eslint/types": "4.28.4", 534 | "@typescript-eslint/visitor-keys": "4.28.4", 535 | "debug": "^4.3.1", 536 | "globby": "^11.0.3", 537 | "is-glob": "^4.0.1", 538 | "semver": "^7.3.5", 539 | "tsutils": "^3.21.0" 540 | }, 541 | "dependencies": { 542 | "semver": { 543 | "version": "7.3.5", 544 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", 545 | "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", 546 | "dev": true, 547 | "requires": { 548 | "lru-cache": "^6.0.0" 549 | } 550 | } 551 | } 552 | }, 553 | "@typescript-eslint/visitor-keys": { 554 | "version": "4.28.4", 555 | "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.28.4.tgz", 556 | "integrity": "sha512-NIAXAdbz1XdOuzqkJHjNKXKj8QQ4cv5cxR/g0uQhCYf/6//XrmfpaYsM7PnBcNbfvTDLUkqQ5TPNm1sozDdTWg==", 557 | "dev": true, 558 | "requires": { 559 | "@typescript-eslint/types": "4.28.4", 560 | "eslint-visitor-keys": "^2.0.0" 561 | } 562 | }, 563 | "accepts": { 564 | "version": "1.3.7", 565 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", 566 | "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", 567 | "requires": { 568 | "mime-types": "~2.1.24", 569 | "negotiator": "0.6.2" 570 | } 571 | }, 572 | "acorn": { 573 | "version": "7.4.1", 574 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", 575 | "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", 576 | "dev": true 577 | }, 578 | "acorn-jsx": { 579 | "version": "5.3.2", 580 | "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", 581 | "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", 582 | "dev": true 583 | }, 584 | "ajv": { 585 | "version": "6.12.6", 586 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", 587 | "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", 588 | "dev": true, 589 | "requires": { 590 | "fast-deep-equal": "^3.1.1", 591 | "fast-json-stable-stringify": "^2.0.0", 592 | "json-schema-traverse": "^0.4.1", 593 | "uri-js": "^4.2.2" 594 | } 595 | }, 596 | "ansi-colors": { 597 | "version": "4.1.1", 598 | "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", 599 | "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", 600 | "dev": true 601 | }, 602 | "ansi-regex": { 603 | "version": "5.0.1", 604 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 605 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 606 | "dev": true 607 | }, 608 | "ansi-styles": { 609 | "version": "3.2.1", 610 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 611 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 612 | "dev": true, 613 | "requires": { 614 | "color-convert": "^1.9.0" 615 | } 616 | }, 617 | "any-promise": { 618 | "version": "1.3.0", 619 | "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", 620 | "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=" 621 | }, 622 | "arg": { 623 | "version": "4.1.3", 624 | "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", 625 | "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", 626 | "dev": true 627 | }, 628 | "argparse": { 629 | "version": "1.0.10", 630 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", 631 | "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", 632 | "dev": true, 633 | "requires": { 634 | "sprintf-js": "~1.0.2" 635 | } 636 | }, 637 | "args": { 638 | "version": "5.0.1", 639 | "resolved": "https://registry.npmjs.org/args/-/args-5.0.1.tgz", 640 | "integrity": "sha512-1kqmFCFsPffavQFGt8OxJdIcETti99kySRUPMpOhaGjL6mRJn8HFU1OxKY5bMqfZKUwTQc1mZkAjmGYaVOHFtQ==", 641 | "dev": true, 642 | "requires": { 643 | "camelcase": "5.0.0", 644 | "chalk": "2.4.2", 645 | "leven": "2.1.0", 646 | "mri": "1.1.4" 647 | }, 648 | "dependencies": { 649 | "camelcase": { 650 | "version": "5.0.0", 651 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.0.0.tgz", 652 | "integrity": "sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA==", 653 | "dev": true 654 | } 655 | } 656 | }, 657 | "array-union": { 658 | "version": "2.1.0", 659 | "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", 660 | "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", 661 | "dev": true 662 | }, 663 | "astral-regex": { 664 | "version": "2.0.0", 665 | "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", 666 | "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", 667 | "dev": true 668 | }, 669 | "atomic-sleep": { 670 | "version": "1.0.0", 671 | "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", 672 | "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==" 673 | }, 674 | "balanced-match": { 675 | "version": "1.0.2", 676 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 677 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 678 | "dev": true 679 | }, 680 | "brace-expansion": { 681 | "version": "1.1.11", 682 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 683 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 684 | "dev": true, 685 | "requires": { 686 | "balanced-match": "^1.0.0", 687 | "concat-map": "0.0.1" 688 | } 689 | }, 690 | "braces": { 691 | "version": "3.0.2", 692 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", 693 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", 694 | "dev": true, 695 | "requires": { 696 | "fill-range": "^7.0.1" 697 | } 698 | }, 699 | "buffer-from": { 700 | "version": "1.1.1", 701 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", 702 | "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", 703 | "dev": true 704 | }, 705 | "bytes": { 706 | "version": "3.1.0", 707 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", 708 | "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" 709 | }, 710 | "cache-content-type": { 711 | "version": "1.0.1", 712 | "resolved": "https://registry.npmjs.org/cache-content-type/-/cache-content-type-1.0.1.tgz", 713 | "integrity": "sha512-IKufZ1o4Ut42YUrZSo8+qnMTrFuKkvyoLXUywKz9GJ5BrhOFGhLdkx9sG4KAnVvbY6kEcSFjLQul+DVmBm2bgA==", 714 | "requires": { 715 | "mime-types": "^2.1.18", 716 | "ylru": "^1.2.0" 717 | } 718 | }, 719 | "call-bind": { 720 | "version": "1.0.2", 721 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", 722 | "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", 723 | "requires": { 724 | "function-bind": "^1.1.1", 725 | "get-intrinsic": "^1.0.2" 726 | } 727 | }, 728 | "callsites": { 729 | "version": "3.1.0", 730 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", 731 | "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", 732 | "dev": true 733 | }, 734 | "chalk": { 735 | "version": "2.4.2", 736 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", 737 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", 738 | "dev": true, 739 | "requires": { 740 | "ansi-styles": "^3.2.1", 741 | "escape-string-regexp": "^1.0.5", 742 | "supports-color": "^5.3.0" 743 | } 744 | }, 745 | "co": { 746 | "version": "4.6.0", 747 | "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", 748 | "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" 749 | }, 750 | "co-body": { 751 | "version": "6.1.0", 752 | "resolved": "https://registry.npmjs.org/co-body/-/co-body-6.1.0.tgz", 753 | "integrity": "sha512-m7pOT6CdLN7FuXUcpuz/8lfQ/L77x8SchHCF4G0RBTJO20Wzmhn5Sp4/5WsKy8OSpifBSUrmg83qEqaDHdyFuQ==", 754 | "requires": { 755 | "inflation": "^2.0.0", 756 | "qs": "^6.5.2", 757 | "raw-body": "^2.3.3", 758 | "type-is": "^1.6.16" 759 | } 760 | }, 761 | "color-convert": { 762 | "version": "1.9.3", 763 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", 764 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", 765 | "dev": true, 766 | "requires": { 767 | "color-name": "1.1.3" 768 | } 769 | }, 770 | "color-name": { 771 | "version": "1.1.3", 772 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 773 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", 774 | "dev": true 775 | }, 776 | "compressible": { 777 | "version": "2.0.18", 778 | "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", 779 | "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", 780 | "requires": { 781 | "mime-db": ">= 1.43.0 < 2" 782 | } 783 | }, 784 | "concat-map": { 785 | "version": "0.0.1", 786 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 787 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 788 | "dev": true 789 | }, 790 | "content-disposition": { 791 | "version": "0.5.3", 792 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", 793 | "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", 794 | "requires": { 795 | "safe-buffer": "5.1.2" 796 | } 797 | }, 798 | "content-type": { 799 | "version": "1.0.4", 800 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 801 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" 802 | }, 803 | "cookies": { 804 | "version": "0.8.0", 805 | "resolved": "https://registry.npmjs.org/cookies/-/cookies-0.8.0.tgz", 806 | "integrity": "sha512-8aPsApQfebXnuI+537McwYsDtjVxGm8gTIzQI3FDW6t5t/DAhERxtnbEPN/8RX+uZthoz4eCOgloXaE5cYyNow==", 807 | "requires": { 808 | "depd": "~2.0.0", 809 | "keygrip": "~1.1.0" 810 | }, 811 | "dependencies": { 812 | "depd": { 813 | "version": "2.0.0", 814 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", 815 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" 816 | } 817 | } 818 | }, 819 | "copy-to": { 820 | "version": "2.0.1", 821 | "resolved": "https://registry.npmjs.org/copy-to/-/copy-to-2.0.1.tgz", 822 | "integrity": "sha1-JoD7uAaKSNCGVrYJgJK9r8kG9KU=" 823 | }, 824 | "create-require": { 825 | "version": "1.1.1", 826 | "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", 827 | "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", 828 | "dev": true 829 | }, 830 | "cross-spawn": { 831 | "version": "7.0.3", 832 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", 833 | "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", 834 | "dev": true, 835 | "requires": { 836 | "path-key": "^3.1.0", 837 | "shebang-command": "^2.0.0", 838 | "which": "^2.0.1" 839 | }, 840 | "dependencies": { 841 | "path-key": { 842 | "version": "3.1.1", 843 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", 844 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", 845 | "dev": true 846 | }, 847 | "shebang-command": { 848 | "version": "2.0.0", 849 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", 850 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", 851 | "dev": true, 852 | "requires": { 853 | "shebang-regex": "^3.0.0" 854 | } 855 | }, 856 | "shebang-regex": { 857 | "version": "3.0.0", 858 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", 859 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", 860 | "dev": true 861 | }, 862 | "which": { 863 | "version": "2.0.2", 864 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", 865 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", 866 | "dev": true, 867 | "requires": { 868 | "isexe": "^2.0.0" 869 | } 870 | } 871 | } 872 | }, 873 | "cuid": { 874 | "version": "2.1.8", 875 | "resolved": "https://registry.npmjs.org/cuid/-/cuid-2.1.8.tgz", 876 | "integrity": "sha512-xiEMER6E7TlTPnDxrM4eRiC6TRgjNX9xzEZ5U/Se2YJKr7Mq4pJn/2XEHjl3STcSh96GmkHPcBXLES8M29wyyg==" 877 | }, 878 | "dateformat": { 879 | "version": "4.5.1", 880 | "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-4.5.1.tgz", 881 | "integrity": "sha512-OD0TZ+B7yP7ZgpJf5K2DIbj3FZvFvxgFUuaqA/V5zTjAtAAXZ1E8bktHxmAGs4x5b7PflqA9LeQ84Og7wYtF7Q==", 882 | "dev": true 883 | }, 884 | "debug": { 885 | "version": "4.3.2", 886 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", 887 | "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", 888 | "requires": { 889 | "ms": "2.1.2" 890 | } 891 | }, 892 | "deep-equal": { 893 | "version": "1.0.1", 894 | "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", 895 | "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=" 896 | }, 897 | "deep-is": { 898 | "version": "0.1.3", 899 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", 900 | "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", 901 | "dev": true 902 | }, 903 | "delegates": { 904 | "version": "1.0.0", 905 | "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", 906 | "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" 907 | }, 908 | "depd": { 909 | "version": "1.1.2", 910 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", 911 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" 912 | }, 913 | "destroy": { 914 | "version": "1.0.4", 915 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", 916 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" 917 | }, 918 | "diff": { 919 | "version": "4.0.2", 920 | "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", 921 | "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", 922 | "dev": true 923 | }, 924 | "dir-glob": { 925 | "version": "3.0.1", 926 | "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", 927 | "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", 928 | "dev": true, 929 | "requires": { 930 | "path-type": "^4.0.0" 931 | }, 932 | "dependencies": { 933 | "path-type": { 934 | "version": "4.0.0", 935 | "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", 936 | "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", 937 | "dev": true 938 | } 939 | } 940 | }, 941 | "doctrine": { 942 | "version": "3.0.0", 943 | "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", 944 | "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", 945 | "dev": true, 946 | "requires": { 947 | "esutils": "^2.0.2" 948 | } 949 | }, 950 | "duplexer": { 951 | "version": "0.1.2", 952 | "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", 953 | "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", 954 | "dev": true 955 | }, 956 | "ee-first": { 957 | "version": "1.1.1", 958 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 959 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" 960 | }, 961 | "emoji-regex": { 962 | "version": "8.0.0", 963 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 964 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", 965 | "dev": true 966 | }, 967 | "encodeurl": { 968 | "version": "1.0.2", 969 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 970 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" 971 | }, 972 | "end-of-stream": { 973 | "version": "1.4.4", 974 | "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", 975 | "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", 976 | "dev": true, 977 | "requires": { 978 | "once": "^1.4.0" 979 | } 980 | }, 981 | "enquirer": { 982 | "version": "2.3.6", 983 | "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", 984 | "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", 985 | "dev": true, 986 | "requires": { 987 | "ansi-colors": "^4.1.1" 988 | } 989 | }, 990 | "escape-html": { 991 | "version": "1.0.3", 992 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 993 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" 994 | }, 995 | "escape-string-regexp": { 996 | "version": "1.0.5", 997 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 998 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", 999 | "dev": true 1000 | }, 1001 | "eslint": { 1002 | "version": "7.31.0", 1003 | "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.31.0.tgz", 1004 | "integrity": "sha512-vafgJpSh2ia8tnTkNUkwxGmnumgckLh5aAbLa1xRmIn9+owi8qBNGKL+B881kNKNTy7FFqTEkpNkUvmw0n6PkA==", 1005 | "dev": true, 1006 | "requires": { 1007 | "@babel/code-frame": "7.12.11", 1008 | "@eslint/eslintrc": "^0.4.3", 1009 | "@humanwhocodes/config-array": "^0.5.0", 1010 | "ajv": "^6.10.0", 1011 | "chalk": "^4.0.0", 1012 | "cross-spawn": "^7.0.2", 1013 | "debug": "^4.0.1", 1014 | "doctrine": "^3.0.0", 1015 | "enquirer": "^2.3.5", 1016 | "escape-string-regexp": "^4.0.0", 1017 | "eslint-scope": "^5.1.1", 1018 | "eslint-utils": "^2.1.0", 1019 | "eslint-visitor-keys": "^2.0.0", 1020 | "espree": "^7.3.1", 1021 | "esquery": "^1.4.0", 1022 | "esutils": "^2.0.2", 1023 | "fast-deep-equal": "^3.1.3", 1024 | "file-entry-cache": "^6.0.1", 1025 | "functional-red-black-tree": "^1.0.1", 1026 | "glob-parent": "^5.1.2", 1027 | "globals": "^13.6.0", 1028 | "ignore": "^4.0.6", 1029 | "import-fresh": "^3.0.0", 1030 | "imurmurhash": "^0.1.4", 1031 | "is-glob": "^4.0.0", 1032 | "js-yaml": "^3.13.1", 1033 | "json-stable-stringify-without-jsonify": "^1.0.1", 1034 | "levn": "^0.4.1", 1035 | "lodash.merge": "^4.6.2", 1036 | "minimatch": "^3.0.4", 1037 | "natural-compare": "^1.4.0", 1038 | "optionator": "^0.9.1", 1039 | "progress": "^2.0.0", 1040 | "regexpp": "^3.1.0", 1041 | "semver": "^7.2.1", 1042 | "strip-ansi": "^6.0.0", 1043 | "strip-json-comments": "^3.1.0", 1044 | "table": "^6.0.9", 1045 | "text-table": "^0.2.0", 1046 | "v8-compile-cache": "^2.0.3" 1047 | }, 1048 | "dependencies": { 1049 | "ansi-styles": { 1050 | "version": "4.3.0", 1051 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 1052 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 1053 | "dev": true, 1054 | "requires": { 1055 | "color-convert": "^2.0.1" 1056 | } 1057 | }, 1058 | "chalk": { 1059 | "version": "4.1.1", 1060 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", 1061 | "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", 1062 | "dev": true, 1063 | "requires": { 1064 | "ansi-styles": "^4.1.0", 1065 | "supports-color": "^7.1.0" 1066 | } 1067 | }, 1068 | "color-convert": { 1069 | "version": "2.0.1", 1070 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 1071 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 1072 | "dev": true, 1073 | "requires": { 1074 | "color-name": "~1.1.4" 1075 | } 1076 | }, 1077 | "color-name": { 1078 | "version": "1.1.4", 1079 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 1080 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 1081 | "dev": true 1082 | }, 1083 | "escape-string-regexp": { 1084 | "version": "4.0.0", 1085 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", 1086 | "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", 1087 | "dev": true 1088 | }, 1089 | "glob-parent": { 1090 | "version": "5.1.2", 1091 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", 1092 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", 1093 | "dev": true, 1094 | "requires": { 1095 | "is-glob": "^4.0.1" 1096 | } 1097 | }, 1098 | "has-flag": { 1099 | "version": "4.0.0", 1100 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 1101 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 1102 | "dev": true 1103 | }, 1104 | "lru-cache": { 1105 | "version": "6.0.0", 1106 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", 1107 | "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", 1108 | "dev": true, 1109 | "requires": { 1110 | "yallist": "^4.0.0" 1111 | } 1112 | }, 1113 | "semver": { 1114 | "version": "7.3.5", 1115 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", 1116 | "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", 1117 | "dev": true, 1118 | "requires": { 1119 | "lru-cache": "^6.0.0" 1120 | } 1121 | }, 1122 | "strip-ansi": { 1123 | "version": "6.0.0", 1124 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", 1125 | "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", 1126 | "dev": true, 1127 | "requires": { 1128 | "ansi-regex": "^5.0.0" 1129 | } 1130 | }, 1131 | "strip-json-comments": { 1132 | "version": "3.1.1", 1133 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", 1134 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", 1135 | "dev": true 1136 | }, 1137 | "supports-color": { 1138 | "version": "7.2.0", 1139 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 1140 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 1141 | "dev": true, 1142 | "requires": { 1143 | "has-flag": "^4.0.0" 1144 | } 1145 | }, 1146 | "yallist": { 1147 | "version": "4.0.0", 1148 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", 1149 | "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", 1150 | "dev": true 1151 | } 1152 | } 1153 | }, 1154 | "eslint-config-prettier": { 1155 | "version": "8.3.0", 1156 | "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.3.0.tgz", 1157 | "integrity": "sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew==", 1158 | "dev": true 1159 | }, 1160 | "eslint-plugin-prettier": { 1161 | "version": "3.4.0", 1162 | "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.0.tgz", 1163 | "integrity": "sha512-UDK6rJT6INSfcOo545jiaOwB701uAIt2/dR7WnFQoGCVl1/EMqdANBmwUaqqQ45aXprsTGzSa39LI1PyuRBxxw==", 1164 | "dev": true, 1165 | "requires": { 1166 | "prettier-linter-helpers": "^1.0.0" 1167 | } 1168 | }, 1169 | "eslint-scope": { 1170 | "version": "5.1.1", 1171 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", 1172 | "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", 1173 | "dev": true, 1174 | "requires": { 1175 | "esrecurse": "^4.3.0", 1176 | "estraverse": "^4.1.1" 1177 | } 1178 | }, 1179 | "eslint-utils": { 1180 | "version": "2.1.0", 1181 | "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", 1182 | "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", 1183 | "dev": true, 1184 | "requires": { 1185 | "eslint-visitor-keys": "^1.1.0" 1186 | }, 1187 | "dependencies": { 1188 | "eslint-visitor-keys": { 1189 | "version": "1.3.0", 1190 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", 1191 | "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", 1192 | "dev": true 1193 | } 1194 | } 1195 | }, 1196 | "eslint-visitor-keys": { 1197 | "version": "2.1.0", 1198 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", 1199 | "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", 1200 | "dev": true 1201 | }, 1202 | "espree": { 1203 | "version": "7.3.1", 1204 | "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", 1205 | "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", 1206 | "dev": true, 1207 | "requires": { 1208 | "acorn": "^7.4.0", 1209 | "acorn-jsx": "^5.3.1", 1210 | "eslint-visitor-keys": "^1.3.0" 1211 | }, 1212 | "dependencies": { 1213 | "eslint-visitor-keys": { 1214 | "version": "1.3.0", 1215 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", 1216 | "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", 1217 | "dev": true 1218 | } 1219 | } 1220 | }, 1221 | "esprima": { 1222 | "version": "4.0.1", 1223 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", 1224 | "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", 1225 | "dev": true 1226 | }, 1227 | "esquery": { 1228 | "version": "1.4.0", 1229 | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", 1230 | "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", 1231 | "dev": true, 1232 | "requires": { 1233 | "estraverse": "^5.1.0" 1234 | }, 1235 | "dependencies": { 1236 | "estraverse": { 1237 | "version": "5.2.0", 1238 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", 1239 | "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", 1240 | "dev": true 1241 | } 1242 | } 1243 | }, 1244 | "esrecurse": { 1245 | "version": "4.3.0", 1246 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", 1247 | "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", 1248 | "dev": true, 1249 | "requires": { 1250 | "estraverse": "^5.2.0" 1251 | }, 1252 | "dependencies": { 1253 | "estraverse": { 1254 | "version": "5.2.0", 1255 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", 1256 | "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", 1257 | "dev": true 1258 | } 1259 | } 1260 | }, 1261 | "estraverse": { 1262 | "version": "4.3.0", 1263 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", 1264 | "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", 1265 | "dev": true 1266 | }, 1267 | "esutils": { 1268 | "version": "2.0.3", 1269 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", 1270 | "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", 1271 | "dev": true 1272 | }, 1273 | "event-stream": { 1274 | "version": "3.3.4", 1275 | "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", 1276 | "integrity": "sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=", 1277 | "dev": true, 1278 | "requires": { 1279 | "duplexer": "~0.1.1", 1280 | "from": "~0", 1281 | "map-stream": "~0.1.0", 1282 | "pause-stream": "0.0.11", 1283 | "split": "0.3", 1284 | "stream-combiner": "~0.0.4", 1285 | "through": "~2.3.1" 1286 | } 1287 | }, 1288 | "fast-deep-equal": { 1289 | "version": "3.1.3", 1290 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", 1291 | "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", 1292 | "dev": true 1293 | }, 1294 | "fast-diff": { 1295 | "version": "1.2.0", 1296 | "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", 1297 | "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", 1298 | "dev": true 1299 | }, 1300 | "fast-glob": { 1301 | "version": "3.2.7", 1302 | "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", 1303 | "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", 1304 | "dev": true, 1305 | "requires": { 1306 | "@nodelib/fs.stat": "^2.0.2", 1307 | "@nodelib/fs.walk": "^1.2.3", 1308 | "glob-parent": "^5.1.2", 1309 | "merge2": "^1.3.0", 1310 | "micromatch": "^4.0.4" 1311 | } 1312 | }, 1313 | "fast-json-stable-stringify": { 1314 | "version": "2.1.0", 1315 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", 1316 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", 1317 | "dev": true 1318 | }, 1319 | "fast-levenshtein": { 1320 | "version": "2.0.6", 1321 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 1322 | "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", 1323 | "dev": true 1324 | }, 1325 | "fast-redact": { 1326 | "version": "3.0.1", 1327 | "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.0.1.tgz", 1328 | "integrity": "sha512-kYpn4Y/valC9MdrISg47tZOpYBNoTXKgT9GYXFpHN/jYFs+lFkPoisY+LcBODdKVMY96ATzvzsWv+ES/4Kmufw==" 1329 | }, 1330 | "fast-safe-stringify": { 1331 | "version": "2.0.8", 1332 | "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.8.tgz", 1333 | "integrity": "sha512-lXatBjf3WPjmWD6DpIZxkeSsCOwqI0maYMpgDlx8g4U2qi4lbjA9oH/HD2a87G+KfsUmo5WbJFmqBZlPxtptag==" 1334 | }, 1335 | "fastq": { 1336 | "version": "1.11.1", 1337 | "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.1.tgz", 1338 | "integrity": "sha512-HOnr8Mc60eNYl1gzwp6r5RoUyAn5/glBolUzP/Ez6IFVPMPirxn/9phgL6zhOtaTy7ISwPvQ+wT+hfcRZh/bzw==", 1339 | "dev": true, 1340 | "requires": { 1341 | "reusify": "^1.0.4" 1342 | } 1343 | }, 1344 | "file-entry-cache": { 1345 | "version": "6.0.1", 1346 | "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", 1347 | "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", 1348 | "dev": true, 1349 | "requires": { 1350 | "flat-cache": "^3.0.4" 1351 | } 1352 | }, 1353 | "fill-range": { 1354 | "version": "7.0.1", 1355 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", 1356 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", 1357 | "dev": true, 1358 | "requires": { 1359 | "to-regex-range": "^5.0.1" 1360 | } 1361 | }, 1362 | "flat-cache": { 1363 | "version": "3.0.4", 1364 | "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", 1365 | "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", 1366 | "dev": true, 1367 | "requires": { 1368 | "flatted": "^3.1.0", 1369 | "rimraf": "^3.0.2" 1370 | } 1371 | }, 1372 | "flatstr": { 1373 | "version": "1.0.12", 1374 | "resolved": "https://registry.npmjs.org/flatstr/-/flatstr-1.0.12.tgz", 1375 | "integrity": "sha512-4zPxDyhCyiN2wIAtSLI6gc82/EjqZc1onI4Mz/l0pWrAlsSfYH/2ZIcU+e3oA2wDwbzIWNKwa23F8rh6+DRWkw==" 1376 | }, 1377 | "flatted": { 1378 | "version": "3.2.1", 1379 | "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.1.tgz", 1380 | "integrity": "sha512-OMQjaErSFHmHqZe+PSidH5n8j3O0F2DdnVh8JB4j4eUQ2k6KvB0qGfrKIhapvez5JerBbmWkaLYUYWISaESoXg==", 1381 | "dev": true 1382 | }, 1383 | "fresh": { 1384 | "version": "0.5.2", 1385 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 1386 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" 1387 | }, 1388 | "from": { 1389 | "version": "0.1.7", 1390 | "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", 1391 | "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=", 1392 | "dev": true 1393 | }, 1394 | "fs.realpath": { 1395 | "version": "1.0.0", 1396 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 1397 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", 1398 | "dev": true 1399 | }, 1400 | "function-bind": { 1401 | "version": "1.1.1", 1402 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 1403 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" 1404 | }, 1405 | "functional-red-black-tree": { 1406 | "version": "1.0.1", 1407 | "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", 1408 | "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", 1409 | "dev": true 1410 | }, 1411 | "get-intrinsic": { 1412 | "version": "1.1.1", 1413 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", 1414 | "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", 1415 | "requires": { 1416 | "function-bind": "^1.1.1", 1417 | "has": "^1.0.3", 1418 | "has-symbols": "^1.0.1" 1419 | } 1420 | }, 1421 | "glob": { 1422 | "version": "7.1.7", 1423 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", 1424 | "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", 1425 | "dev": true, 1426 | "requires": { 1427 | "fs.realpath": "^1.0.0", 1428 | "inflight": "^1.0.4", 1429 | "inherits": "2", 1430 | "minimatch": "^3.0.4", 1431 | "once": "^1.3.0", 1432 | "path-is-absolute": "^1.0.0" 1433 | } 1434 | }, 1435 | "glob-parent": { 1436 | "version": "5.1.2", 1437 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", 1438 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", 1439 | "dev": true, 1440 | "requires": { 1441 | "is-glob": "^4.0.1" 1442 | } 1443 | }, 1444 | "globals": { 1445 | "version": "13.10.0", 1446 | "resolved": "https://registry.npmjs.org/globals/-/globals-13.10.0.tgz", 1447 | "integrity": "sha512-piHC3blgLGFjvOuMmWZX60f+na1lXFDhQXBf1UYp2fXPXqvEUbOhNwi6BsQ0bQishwedgnjkwv1d9zKf+MWw3g==", 1448 | "dev": true, 1449 | "requires": { 1450 | "type-fest": "^0.20.2" 1451 | } 1452 | }, 1453 | "globby": { 1454 | "version": "11.0.4", 1455 | "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", 1456 | "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", 1457 | "dev": true, 1458 | "requires": { 1459 | "array-union": "^2.1.0", 1460 | "dir-glob": "^3.0.1", 1461 | "fast-glob": "^3.1.1", 1462 | "ignore": "^5.1.4", 1463 | "merge2": "^1.3.0", 1464 | "slash": "^3.0.0" 1465 | }, 1466 | "dependencies": { 1467 | "ignore": { 1468 | "version": "5.1.8", 1469 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", 1470 | "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", 1471 | "dev": true 1472 | } 1473 | } 1474 | }, 1475 | "has": { 1476 | "version": "1.0.3", 1477 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 1478 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 1479 | "requires": { 1480 | "function-bind": "^1.1.1" 1481 | } 1482 | }, 1483 | "has-flag": { 1484 | "version": "3.0.0", 1485 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 1486 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", 1487 | "dev": true 1488 | }, 1489 | "has-symbols": { 1490 | "version": "1.0.2", 1491 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", 1492 | "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" 1493 | }, 1494 | "http-assert": { 1495 | "version": "1.4.1", 1496 | "resolved": "https://registry.npmjs.org/http-assert/-/http-assert-1.4.1.tgz", 1497 | "integrity": "sha512-rdw7q6GTlibqVVbXr0CKelfV5iY8G2HqEUkhSk297BMbSpSL8crXC+9rjKoMcZZEsksX30le6f/4ul4E28gegw==", 1498 | "requires": { 1499 | "deep-equal": "~1.0.1", 1500 | "http-errors": "~1.7.2" 1501 | }, 1502 | "dependencies": { 1503 | "http-errors": { 1504 | "version": "1.7.3", 1505 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", 1506 | "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==", 1507 | "requires": { 1508 | "depd": "~1.1.2", 1509 | "inherits": "2.0.4", 1510 | "setprototypeof": "1.1.1", 1511 | "statuses": ">= 1.5.0 < 2", 1512 | "toidentifier": "1.0.0" 1513 | } 1514 | }, 1515 | "setprototypeof": { 1516 | "version": "1.1.1", 1517 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", 1518 | "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" 1519 | } 1520 | } 1521 | }, 1522 | "http-errors": { 1523 | "version": "1.8.0", 1524 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.0.tgz", 1525 | "integrity": "sha512-4I8r0C5JDhT5VkvI47QktDW75rNlGVsUf/8hzjCC/wkWI/jdTRmBb9aI7erSG82r1bjKY3F6k28WnsVxB1C73A==", 1526 | "requires": { 1527 | "depd": "~1.1.2", 1528 | "inherits": "2.0.4", 1529 | "setprototypeof": "1.2.0", 1530 | "statuses": ">= 1.5.0 < 2", 1531 | "toidentifier": "1.0.0" 1532 | } 1533 | }, 1534 | "iconv-lite": { 1535 | "version": "0.4.24", 1536 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 1537 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 1538 | "requires": { 1539 | "safer-buffer": ">= 2.1.2 < 3" 1540 | } 1541 | }, 1542 | "ignore": { 1543 | "version": "4.0.6", 1544 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", 1545 | "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", 1546 | "dev": true 1547 | }, 1548 | "import-fresh": { 1549 | "version": "3.3.0", 1550 | "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", 1551 | "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", 1552 | "dev": true, 1553 | "requires": { 1554 | "parent-module": "^1.0.0", 1555 | "resolve-from": "^4.0.0" 1556 | } 1557 | }, 1558 | "imurmurhash": { 1559 | "version": "0.1.4", 1560 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", 1561 | "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", 1562 | "dev": true 1563 | }, 1564 | "inflation": { 1565 | "version": "2.0.0", 1566 | "resolved": "https://registry.npmjs.org/inflation/-/inflation-2.0.0.tgz", 1567 | "integrity": "sha1-i0F+R8KPklpFEz2RTKH9OJEH8w8=" 1568 | }, 1569 | "inflight": { 1570 | "version": "1.0.6", 1571 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 1572 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 1573 | "dev": true, 1574 | "requires": { 1575 | "once": "^1.3.0", 1576 | "wrappy": "1" 1577 | } 1578 | }, 1579 | "inherits": { 1580 | "version": "2.0.4", 1581 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 1582 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 1583 | }, 1584 | "inversify": { 1585 | "version": "5.1.1", 1586 | "resolved": "https://registry.npmjs.org/inversify/-/inversify-5.1.1.tgz", 1587 | "integrity": "sha512-j8grHGDzv1v+8T1sAQ+3boTCntFPfvxLCkNcxB1J8qA0lUN+fAlSyYd+RXKvaPRL4AGyPxViutBEJHNXOyUdFQ==" 1588 | }, 1589 | "is-extglob": { 1590 | "version": "2.1.1", 1591 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 1592 | "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", 1593 | "dev": true 1594 | }, 1595 | "is-generator-function": { 1596 | "version": "1.0.9", 1597 | "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.9.tgz", 1598 | "integrity": "sha512-ZJ34p1uvIfptHCN7sFTjGibB9/oBg17sHqzDLfuwhvmN/qLVvIQXRQ8licZQ35WJ8KuEQt/etnnzQFI9C9Ue/A==" 1599 | }, 1600 | "is-glob": { 1601 | "version": "4.0.1", 1602 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", 1603 | "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", 1604 | "dev": true, 1605 | "requires": { 1606 | "is-extglob": "^2.1.1" 1607 | } 1608 | }, 1609 | "is-number": { 1610 | "version": "7.0.0", 1611 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 1612 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 1613 | "dev": true 1614 | }, 1615 | "isarray": { 1616 | "version": "0.0.1", 1617 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", 1618 | "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" 1619 | }, 1620 | "isexe": { 1621 | "version": "2.0.0", 1622 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 1623 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", 1624 | "dev": true 1625 | }, 1626 | "jmespath": { 1627 | "version": "0.15.0", 1628 | "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.15.0.tgz", 1629 | "integrity": "sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc=", 1630 | "dev": true 1631 | }, 1632 | "joi": { 1633 | "version": "17.4.1", 1634 | "resolved": "https://registry.npmjs.org/joi/-/joi-17.4.1.tgz", 1635 | "integrity": "sha512-gDPOwQ5sr+BUxXuPDGrC1pSNcVR/yGGcTI0aCnjYxZEa3za60K/iCQ+OFIkEHWZGVCUcUlXlFKvMmrlmxrG6UQ==", 1636 | "requires": { 1637 | "@hapi/hoek": "^9.0.0", 1638 | "@hapi/topo": "^5.0.0", 1639 | "@sideway/address": "^4.1.0", 1640 | "@sideway/formula": "^3.0.0", 1641 | "@sideway/pinpoint": "^2.0.0" 1642 | }, 1643 | "dependencies": { 1644 | "@hapi/hoek": { 1645 | "version": "9.2.0", 1646 | "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.2.0.tgz", 1647 | "integrity": "sha512-sqKVVVOe5ivCaXDWivIJYVSaEgdQK9ul7a4Kity5Iw7u9+wBAPbX1RMSnLLmp7O4Vzj0WOWwMAJsTL00xwaNug==" 1648 | } 1649 | } 1650 | }, 1651 | "joycon": { 1652 | "version": "3.0.1", 1653 | "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.0.1.tgz", 1654 | "integrity": "sha512-SJcJNBg32dGgxhPtM0wQqxqV0ax9k/9TaUskGDSJkSFSQOEWWvQ3zzWdGQRIUry2j1zA5+ReH13t0Mf3StuVZA==", 1655 | "dev": true 1656 | }, 1657 | "js-tokens": { 1658 | "version": "4.0.0", 1659 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", 1660 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", 1661 | "dev": true 1662 | }, 1663 | "js-yaml": { 1664 | "version": "3.14.1", 1665 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", 1666 | "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", 1667 | "dev": true, 1668 | "requires": { 1669 | "argparse": "^1.0.7", 1670 | "esprima": "^4.0.0" 1671 | } 1672 | }, 1673 | "json-schema-traverse": { 1674 | "version": "0.4.1", 1675 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 1676 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", 1677 | "dev": true 1678 | }, 1679 | "json-stable-stringify-without-jsonify": { 1680 | "version": "1.0.1", 1681 | "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", 1682 | "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", 1683 | "dev": true 1684 | }, 1685 | "keygrip": { 1686 | "version": "1.1.0", 1687 | "resolved": "https://registry.npmjs.org/keygrip/-/keygrip-1.1.0.tgz", 1688 | "integrity": "sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==", 1689 | "requires": { 1690 | "tsscmp": "1.0.6" 1691 | } 1692 | }, 1693 | "koa": { 1694 | "version": "2.13.1", 1695 | "resolved": "https://registry.npmjs.org/koa/-/koa-2.13.1.tgz", 1696 | "integrity": "sha512-Lb2Dloc72auj5vK4X4qqL7B5jyDPQaZucc9sR/71byg7ryoD1NCaCm63CShk9ID9quQvDEi1bGR/iGjCG7As3w==", 1697 | "requires": { 1698 | "accepts": "^1.3.5", 1699 | "cache-content-type": "^1.0.0", 1700 | "content-disposition": "~0.5.2", 1701 | "content-type": "^1.0.4", 1702 | "cookies": "~0.8.0", 1703 | "debug": "~3.1.0", 1704 | "delegates": "^1.0.0", 1705 | "depd": "^2.0.0", 1706 | "destroy": "^1.0.4", 1707 | "encodeurl": "^1.0.2", 1708 | "escape-html": "^1.0.3", 1709 | "fresh": "~0.5.2", 1710 | "http-assert": "^1.3.0", 1711 | "http-errors": "^1.6.3", 1712 | "is-generator-function": "^1.0.7", 1713 | "koa-compose": "^4.1.0", 1714 | "koa-convert": "^1.2.0", 1715 | "on-finished": "^2.3.0", 1716 | "only": "~0.0.2", 1717 | "parseurl": "^1.3.2", 1718 | "statuses": "^1.5.0", 1719 | "type-is": "^1.6.16", 1720 | "vary": "^1.1.2" 1721 | }, 1722 | "dependencies": { 1723 | "debug": { 1724 | "version": "3.1.0", 1725 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", 1726 | "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", 1727 | "requires": { 1728 | "ms": "2.0.0" 1729 | } 1730 | }, 1731 | "depd": { 1732 | "version": "2.0.0", 1733 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", 1734 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" 1735 | }, 1736 | "ms": { 1737 | "version": "2.0.0", 1738 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 1739 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 1740 | } 1741 | } 1742 | }, 1743 | "koa-bodyparser": { 1744 | "version": "4.3.0", 1745 | "resolved": "https://registry.npmjs.org/koa-bodyparser/-/koa-bodyparser-4.3.0.tgz", 1746 | "integrity": "sha512-uyV8G29KAGwZc4q/0WUAjH+Tsmuv9ImfBUF2oZVyZtaeo0husInagyn/JH85xMSxM0hEk/mbCII5ubLDuqW/Rw==", 1747 | "requires": { 1748 | "co-body": "^6.0.0", 1749 | "copy-to": "^2.0.1" 1750 | } 1751 | }, 1752 | "koa-compose": { 1753 | "version": "4.1.0", 1754 | "resolved": "https://registry.npmjs.org/koa-compose/-/koa-compose-4.1.0.tgz", 1755 | "integrity": "sha512-8ODW8TrDuMYvXRwra/Kh7/rJo9BtOfPc6qO8eAfC80CnCvSjSl0bkRM24X6/XBBEyj0v1nRUQ1LyOy3dbqOWXw==" 1756 | }, 1757 | "koa-compress": { 1758 | "version": "3.1.0", 1759 | "resolved": "https://registry.npmjs.org/koa-compress/-/koa-compress-3.1.0.tgz", 1760 | "integrity": "sha512-0m24/yS/GbhWI+g9FqtvStY+yJwTObwoxOvPok6itVjRen7PBWkjsJ8pre76m+99YybXLKhOJ62mJ268qyBFMQ==", 1761 | "requires": { 1762 | "bytes": "^3.0.0", 1763 | "compressible": "^2.0.0", 1764 | "koa-is-json": "^1.0.0", 1765 | "statuses": "^1.0.0" 1766 | } 1767 | }, 1768 | "koa-convert": { 1769 | "version": "1.2.0", 1770 | "resolved": "https://registry.npmjs.org/koa-convert/-/koa-convert-1.2.0.tgz", 1771 | "integrity": "sha1-2kCHXfSd4FOQmNFwC1CCDOvNIdA=", 1772 | "requires": { 1773 | "co": "^4.6.0", 1774 | "koa-compose": "^3.0.0" 1775 | }, 1776 | "dependencies": { 1777 | "koa-compose": { 1778 | "version": "3.2.1", 1779 | "resolved": "https://registry.npmjs.org/koa-compose/-/koa-compose-3.2.1.tgz", 1780 | "integrity": "sha1-qFzLQLfZhtjlo0Wzoazo6rz1Tec=", 1781 | "requires": { 1782 | "any-promise": "^1.1.0" 1783 | } 1784 | } 1785 | } 1786 | }, 1787 | "koa-is-json": { 1788 | "version": "1.0.0", 1789 | "resolved": "https://registry.npmjs.org/koa-is-json/-/koa-is-json-1.0.0.tgz", 1790 | "integrity": "sha1-JzwH7c3Ljfaiwat9We52SRRR7BQ=" 1791 | }, 1792 | "leven": { 1793 | "version": "2.1.0", 1794 | "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", 1795 | "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=", 1796 | "dev": true 1797 | }, 1798 | "levn": { 1799 | "version": "0.4.1", 1800 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", 1801 | "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", 1802 | "dev": true, 1803 | "requires": { 1804 | "prelude-ls": "^1.2.1", 1805 | "type-check": "~0.4.0" 1806 | } 1807 | }, 1808 | "lodash.clonedeep": { 1809 | "version": "4.5.0", 1810 | "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", 1811 | "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", 1812 | "dev": true 1813 | }, 1814 | "lodash.merge": { 1815 | "version": "4.6.2", 1816 | "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", 1817 | "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", 1818 | "dev": true 1819 | }, 1820 | "lodash.truncate": { 1821 | "version": "4.4.2", 1822 | "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", 1823 | "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", 1824 | "dev": true 1825 | }, 1826 | "lru-cache": { 1827 | "version": "6.0.0", 1828 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", 1829 | "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", 1830 | "dev": true, 1831 | "requires": { 1832 | "yallist": "^4.0.0" 1833 | } 1834 | }, 1835 | "make-error": { 1836 | "version": "1.3.6", 1837 | "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", 1838 | "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", 1839 | "dev": true 1840 | }, 1841 | "map-stream": { 1842 | "version": "0.1.0", 1843 | "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", 1844 | "integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=", 1845 | "dev": true 1846 | }, 1847 | "media-typer": { 1848 | "version": "0.3.0", 1849 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 1850 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" 1851 | }, 1852 | "merge2": { 1853 | "version": "1.4.1", 1854 | "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", 1855 | "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", 1856 | "dev": true 1857 | }, 1858 | "methods": { 1859 | "version": "1.1.2", 1860 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 1861 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" 1862 | }, 1863 | "micromatch": { 1864 | "version": "4.0.4", 1865 | "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", 1866 | "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", 1867 | "dev": true, 1868 | "requires": { 1869 | "braces": "^3.0.1", 1870 | "picomatch": "^2.2.3" 1871 | } 1872 | }, 1873 | "mime-db": { 1874 | "version": "1.48.0", 1875 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz", 1876 | "integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==" 1877 | }, 1878 | "mime-types": { 1879 | "version": "2.1.31", 1880 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz", 1881 | "integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==", 1882 | "requires": { 1883 | "mime-db": "1.48.0" 1884 | } 1885 | }, 1886 | "minimatch": { 1887 | "version": "3.0.4", 1888 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 1889 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 1890 | "dev": true, 1891 | "requires": { 1892 | "brace-expansion": "^1.1.7" 1893 | } 1894 | }, 1895 | "mri": { 1896 | "version": "1.1.4", 1897 | "resolved": "https://registry.npmjs.org/mri/-/mri-1.1.4.tgz", 1898 | "integrity": "sha512-6y7IjGPm8AzlvoUrwAaw1tLnUBudaS3752vcd8JtrpGGQn+rXIe63LFVHm/YMwtqAuh+LJPCFdlLYPWM1nYn6w==", 1899 | "dev": true 1900 | }, 1901 | "ms": { 1902 | "version": "2.1.2", 1903 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 1904 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 1905 | }, 1906 | "natural-compare": { 1907 | "version": "1.4.0", 1908 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", 1909 | "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", 1910 | "dev": true 1911 | }, 1912 | "negotiator": { 1913 | "version": "0.6.2", 1914 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", 1915 | "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" 1916 | }, 1917 | "node-cleanup": { 1918 | "version": "2.1.2", 1919 | "resolved": "https://registry.npmjs.org/node-cleanup/-/node-cleanup-2.1.2.tgz", 1920 | "integrity": "sha1-esGavSl+Caf3KnFUXZUbUX5N3iw=", 1921 | "dev": true 1922 | }, 1923 | "object-inspect": { 1924 | "version": "1.11.0", 1925 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", 1926 | "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==" 1927 | }, 1928 | "on-finished": { 1929 | "version": "2.3.0", 1930 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 1931 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", 1932 | "requires": { 1933 | "ee-first": "1.1.1" 1934 | } 1935 | }, 1936 | "once": { 1937 | "version": "1.4.0", 1938 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 1939 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 1940 | "dev": true, 1941 | "requires": { 1942 | "wrappy": "1" 1943 | } 1944 | }, 1945 | "only": { 1946 | "version": "0.0.2", 1947 | "resolved": "https://registry.npmjs.org/only/-/only-0.0.2.tgz", 1948 | "integrity": "sha1-Kv3oTQPlC5qO3EROMGEKcCle37Q=" 1949 | }, 1950 | "optionator": { 1951 | "version": "0.9.1", 1952 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", 1953 | "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", 1954 | "dev": true, 1955 | "requires": { 1956 | "deep-is": "^0.1.3", 1957 | "fast-levenshtein": "^2.0.6", 1958 | "levn": "^0.4.1", 1959 | "prelude-ls": "^1.2.1", 1960 | "type-check": "^0.4.0", 1961 | "word-wrap": "^1.2.3" 1962 | } 1963 | }, 1964 | "parent-module": { 1965 | "version": "1.0.1", 1966 | "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", 1967 | "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", 1968 | "dev": true, 1969 | "requires": { 1970 | "callsites": "^3.0.0" 1971 | } 1972 | }, 1973 | "parseurl": { 1974 | "version": "1.3.3", 1975 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 1976 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" 1977 | }, 1978 | "path-is-absolute": { 1979 | "version": "1.0.1", 1980 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 1981 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 1982 | "dev": true 1983 | }, 1984 | "path-to-regexp": { 1985 | "version": "1.8.0", 1986 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", 1987 | "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", 1988 | "requires": { 1989 | "isarray": "0.0.1" 1990 | } 1991 | }, 1992 | "pause-stream": { 1993 | "version": "0.0.11", 1994 | "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", 1995 | "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=", 1996 | "dev": true, 1997 | "requires": { 1998 | "through": "~2.3" 1999 | } 2000 | }, 2001 | "picomatch": { 2002 | "version": "2.3.0", 2003 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", 2004 | "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", 2005 | "dev": true 2006 | }, 2007 | "pino": { 2008 | "version": "6.13.0", 2009 | "resolved": "https://registry.npmjs.org/pino/-/pino-6.13.0.tgz", 2010 | "integrity": "sha512-mRXSTfa34tbfrWqCIp1sUpZLqBhcoaGapoyxfEwaWwJGMpLijlRdDKIQUyvq4M3DUfFH5vEglwSw8POZYwbThA==", 2011 | "requires": { 2012 | "fast-redact": "^3.0.0", 2013 | "fast-safe-stringify": "^2.0.8", 2014 | "flatstr": "^1.0.12", 2015 | "pino-std-serializers": "^3.1.0", 2016 | "quick-format-unescaped": "^4.0.3", 2017 | "sonic-boom": "^1.0.2" 2018 | } 2019 | }, 2020 | "pino-pretty": { 2021 | "version": "5.1.2", 2022 | "resolved": "https://registry.npmjs.org/pino-pretty/-/pino-pretty-5.1.2.tgz", 2023 | "integrity": "sha512-20HWKSHFvF/pF/C4spBVW0RQdnBYptCj4Bwgb6pFkWY5FOYiElCGHkkPU1173iK8fsoiBMHMEvS0wB2loQZJ+Q==", 2024 | "dev": true, 2025 | "requires": { 2026 | "@hapi/bourne": "^2.0.0", 2027 | "args": "^5.0.1", 2028 | "chalk": "^4.0.0", 2029 | "dateformat": "^4.5.1", 2030 | "fast-safe-stringify": "^2.0.7", 2031 | "jmespath": "^0.15.0", 2032 | "joycon": "^3.0.0", 2033 | "pump": "^3.0.0", 2034 | "readable-stream": "^3.6.0", 2035 | "rfdc": "^1.3.0", 2036 | "split2": "^3.1.1", 2037 | "strip-json-comments": "^3.1.1" 2038 | }, 2039 | "dependencies": { 2040 | "ansi-styles": { 2041 | "version": "4.3.0", 2042 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 2043 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 2044 | "dev": true, 2045 | "requires": { 2046 | "color-convert": "^2.0.1" 2047 | } 2048 | }, 2049 | "chalk": { 2050 | "version": "4.1.1", 2051 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", 2052 | "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", 2053 | "dev": true, 2054 | "requires": { 2055 | "ansi-styles": "^4.1.0", 2056 | "supports-color": "^7.1.0" 2057 | } 2058 | }, 2059 | "color-convert": { 2060 | "version": "2.0.1", 2061 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 2062 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 2063 | "dev": true, 2064 | "requires": { 2065 | "color-name": "~1.1.4" 2066 | } 2067 | }, 2068 | "color-name": { 2069 | "version": "1.1.4", 2070 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 2071 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 2072 | "dev": true 2073 | }, 2074 | "has-flag": { 2075 | "version": "4.0.0", 2076 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 2077 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 2078 | "dev": true 2079 | }, 2080 | "readable-stream": { 2081 | "version": "3.6.0", 2082 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", 2083 | "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", 2084 | "dev": true, 2085 | "requires": { 2086 | "inherits": "^2.0.3", 2087 | "string_decoder": "^1.1.1", 2088 | "util-deprecate": "^1.0.1" 2089 | } 2090 | }, 2091 | "strip-json-comments": { 2092 | "version": "3.1.1", 2093 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", 2094 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", 2095 | "dev": true 2096 | }, 2097 | "supports-color": { 2098 | "version": "7.2.0", 2099 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 2100 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 2101 | "dev": true, 2102 | "requires": { 2103 | "has-flag": "^4.0.0" 2104 | } 2105 | } 2106 | } 2107 | }, 2108 | "pino-std-serializers": { 2109 | "version": "3.2.0", 2110 | "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-3.2.0.tgz", 2111 | "integrity": "sha512-EqX4pwDPrt3MuOAAUBMU0Tk5kR/YcCM5fNPEzgCO2zJ5HfX0vbiH9HbJglnyeQsN96Kznae6MWD47pZB5avTrg==" 2112 | }, 2113 | "prelude-ls": { 2114 | "version": "1.2.1", 2115 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", 2116 | "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", 2117 | "dev": true 2118 | }, 2119 | "prettier": { 2120 | "version": "2.3.2", 2121 | "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.2.tgz", 2122 | "integrity": "sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ==", 2123 | "dev": true 2124 | }, 2125 | "prettier-linter-helpers": { 2126 | "version": "1.0.0", 2127 | "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", 2128 | "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", 2129 | "dev": true, 2130 | "requires": { 2131 | "fast-diff": "^1.1.2" 2132 | } 2133 | }, 2134 | "progress": { 2135 | "version": "2.0.3", 2136 | "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", 2137 | "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", 2138 | "dev": true 2139 | }, 2140 | "ps-tree": { 2141 | "version": "1.2.0", 2142 | "resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-1.2.0.tgz", 2143 | "integrity": "sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA==", 2144 | "dev": true, 2145 | "requires": { 2146 | "event-stream": "=3.3.4" 2147 | } 2148 | }, 2149 | "pump": { 2150 | "version": "3.0.0", 2151 | "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", 2152 | "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", 2153 | "dev": true, 2154 | "requires": { 2155 | "end-of-stream": "^1.1.0", 2156 | "once": "^1.3.1" 2157 | } 2158 | }, 2159 | "punycode": { 2160 | "version": "2.1.1", 2161 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", 2162 | "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", 2163 | "dev": true 2164 | }, 2165 | "qs": { 2166 | "version": "6.10.1", 2167 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz", 2168 | "integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==", 2169 | "requires": { 2170 | "side-channel": "^1.0.4" 2171 | } 2172 | }, 2173 | "queue-microtask": { 2174 | "version": "1.2.3", 2175 | "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", 2176 | "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", 2177 | "dev": true 2178 | }, 2179 | "quick-format-unescaped": { 2180 | "version": "4.0.3", 2181 | "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.3.tgz", 2182 | "integrity": "sha512-MaL/oqh02mhEo5m5J2rwsVL23Iw2PEaGVHgT2vFt8AAsr0lfvQA5dpXo9TPu0rz7tSBdUPgkbam0j/fj5ZM8yg==" 2183 | }, 2184 | "raw-body": { 2185 | "version": "2.4.1", 2186 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.1.tgz", 2187 | "integrity": "sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA==", 2188 | "requires": { 2189 | "bytes": "3.1.0", 2190 | "http-errors": "1.7.3", 2191 | "iconv-lite": "0.4.24", 2192 | "unpipe": "1.0.0" 2193 | }, 2194 | "dependencies": { 2195 | "http-errors": { 2196 | "version": "1.7.3", 2197 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", 2198 | "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==", 2199 | "requires": { 2200 | "depd": "~1.1.2", 2201 | "inherits": "2.0.4", 2202 | "setprototypeof": "1.1.1", 2203 | "statuses": ">= 1.5.0 < 2", 2204 | "toidentifier": "1.0.0" 2205 | } 2206 | }, 2207 | "setprototypeof": { 2208 | "version": "1.1.1", 2209 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", 2210 | "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" 2211 | } 2212 | } 2213 | }, 2214 | "reflect-metadata": { 2215 | "version": "0.1.13", 2216 | "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", 2217 | "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" 2218 | }, 2219 | "regexpp": { 2220 | "version": "3.2.0", 2221 | "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", 2222 | "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", 2223 | "dev": true 2224 | }, 2225 | "require-from-string": { 2226 | "version": "2.0.2", 2227 | "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", 2228 | "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", 2229 | "dev": true 2230 | }, 2231 | "resolve-from": { 2232 | "version": "4.0.0", 2233 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", 2234 | "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", 2235 | "dev": true 2236 | }, 2237 | "reusify": { 2238 | "version": "1.0.4", 2239 | "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", 2240 | "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", 2241 | "dev": true 2242 | }, 2243 | "rfdc": { 2244 | "version": "1.3.0", 2245 | "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", 2246 | "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", 2247 | "dev": true 2248 | }, 2249 | "rimraf": { 2250 | "version": "3.0.2", 2251 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", 2252 | "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", 2253 | "dev": true, 2254 | "requires": { 2255 | "glob": "^7.1.3" 2256 | } 2257 | }, 2258 | "run-parallel": { 2259 | "version": "1.2.0", 2260 | "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", 2261 | "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", 2262 | "dev": true, 2263 | "requires": { 2264 | "queue-microtask": "^1.2.2" 2265 | } 2266 | }, 2267 | "safe-buffer": { 2268 | "version": "5.1.2", 2269 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 2270 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 2271 | }, 2272 | "safer-buffer": { 2273 | "version": "2.1.2", 2274 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 2275 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 2276 | }, 2277 | "setprototypeof": { 2278 | "version": "1.2.0", 2279 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", 2280 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" 2281 | }, 2282 | "side-channel": { 2283 | "version": "1.0.4", 2284 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", 2285 | "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", 2286 | "requires": { 2287 | "call-bind": "^1.0.0", 2288 | "get-intrinsic": "^1.0.2", 2289 | "object-inspect": "^1.9.0" 2290 | } 2291 | }, 2292 | "slash": { 2293 | "version": "3.0.0", 2294 | "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", 2295 | "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", 2296 | "dev": true 2297 | }, 2298 | "slice-ansi": { 2299 | "version": "4.0.0", 2300 | "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", 2301 | "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", 2302 | "dev": true, 2303 | "requires": { 2304 | "ansi-styles": "^4.0.0", 2305 | "astral-regex": "^2.0.0", 2306 | "is-fullwidth-code-point": "^3.0.0" 2307 | }, 2308 | "dependencies": { 2309 | "ansi-styles": { 2310 | "version": "4.3.0", 2311 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 2312 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 2313 | "dev": true, 2314 | "requires": { 2315 | "color-convert": "^2.0.1" 2316 | } 2317 | }, 2318 | "color-convert": { 2319 | "version": "2.0.1", 2320 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 2321 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 2322 | "dev": true, 2323 | "requires": { 2324 | "color-name": "~1.1.4" 2325 | } 2326 | }, 2327 | "color-name": { 2328 | "version": "1.1.4", 2329 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 2330 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 2331 | "dev": true 2332 | }, 2333 | "is-fullwidth-code-point": { 2334 | "version": "3.0.0", 2335 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", 2336 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", 2337 | "dev": true 2338 | } 2339 | } 2340 | }, 2341 | "sonic-boom": { 2342 | "version": "1.4.1", 2343 | "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-1.4.1.tgz", 2344 | "integrity": "sha512-LRHh/A8tpW7ru89lrlkU4AszXt1dbwSjVWguGrmlxE7tawVmDBlI1PILMkXAxJTwqhgsEeTHzj36D5CmHgQmNg==", 2345 | "requires": { 2346 | "atomic-sleep": "^1.0.0", 2347 | "flatstr": "^1.0.12" 2348 | } 2349 | }, 2350 | "source-map-support": { 2351 | "version": "0.5.19", 2352 | "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", 2353 | "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", 2354 | "dev": true, 2355 | "requires": { 2356 | "buffer-from": "^1.0.0", 2357 | "source-map": "^0.6.0" 2358 | }, 2359 | "dependencies": { 2360 | "source-map": { 2361 | "version": "0.6.1", 2362 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 2363 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", 2364 | "dev": true 2365 | } 2366 | } 2367 | }, 2368 | "split": { 2369 | "version": "0.3.3", 2370 | "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz", 2371 | "integrity": "sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=", 2372 | "dev": true, 2373 | "requires": { 2374 | "through": "2" 2375 | } 2376 | }, 2377 | "split2": { 2378 | "version": "3.2.2", 2379 | "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", 2380 | "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", 2381 | "dev": true, 2382 | "requires": { 2383 | "readable-stream": "^3.0.0" 2384 | }, 2385 | "dependencies": { 2386 | "readable-stream": { 2387 | "version": "3.6.0", 2388 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", 2389 | "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", 2390 | "dev": true, 2391 | "requires": { 2392 | "inherits": "^2.0.3", 2393 | "string_decoder": "^1.1.1", 2394 | "util-deprecate": "^1.0.1" 2395 | } 2396 | } 2397 | } 2398 | }, 2399 | "sprintf-js": { 2400 | "version": "1.0.3", 2401 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", 2402 | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", 2403 | "dev": true 2404 | }, 2405 | "statuses": { 2406 | "version": "1.5.0", 2407 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", 2408 | "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" 2409 | }, 2410 | "stream-combiner": { 2411 | "version": "0.0.4", 2412 | "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", 2413 | "integrity": "sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=", 2414 | "dev": true, 2415 | "requires": { 2416 | "duplexer": "~0.1.1" 2417 | } 2418 | }, 2419 | "string-argv": { 2420 | "version": "0.1.2", 2421 | "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.1.2.tgz", 2422 | "integrity": "sha512-mBqPGEOMNJKXRo7z0keX0wlAhbBAjilUdPW13nN0PecVryZxdHIeM7TqbsSUA7VYuS00HGC6mojP7DlQzfa9ZA==", 2423 | "dev": true 2424 | }, 2425 | "string_decoder": { 2426 | "version": "1.1.1", 2427 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", 2428 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 2429 | "dev": true, 2430 | "requires": { 2431 | "safe-buffer": "~5.1.0" 2432 | } 2433 | }, 2434 | "supports-color": { 2435 | "version": "5.5.0", 2436 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 2437 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 2438 | "dev": true, 2439 | "requires": { 2440 | "has-flag": "^3.0.0" 2441 | } 2442 | }, 2443 | "table": { 2444 | "version": "6.7.1", 2445 | "resolved": "https://registry.npmjs.org/table/-/table-6.7.1.tgz", 2446 | "integrity": "sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg==", 2447 | "dev": true, 2448 | "requires": { 2449 | "ajv": "^8.0.1", 2450 | "lodash.clonedeep": "^4.5.0", 2451 | "lodash.truncate": "^4.4.2", 2452 | "slice-ansi": "^4.0.0", 2453 | "string-width": "^4.2.0", 2454 | "strip-ansi": "^6.0.0" 2455 | }, 2456 | "dependencies": { 2457 | "ajv": { 2458 | "version": "8.6.2", 2459 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.2.tgz", 2460 | "integrity": "sha512-9807RlWAgT564wT+DjeyU5OFMPjmzxVobvDFmNAhY+5zD6A2ly3jDp6sgnfyDtlIQ+7H97oc/DGCzzfu9rjw9w==", 2461 | "dev": true, 2462 | "requires": { 2463 | "fast-deep-equal": "^3.1.1", 2464 | "json-schema-traverse": "^1.0.0", 2465 | "require-from-string": "^2.0.2", 2466 | "uri-js": "^4.2.2" 2467 | } 2468 | }, 2469 | "is-fullwidth-code-point": { 2470 | "version": "3.0.0", 2471 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", 2472 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", 2473 | "dev": true 2474 | }, 2475 | "json-schema-traverse": { 2476 | "version": "1.0.0", 2477 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", 2478 | "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", 2479 | "dev": true 2480 | }, 2481 | "string-width": { 2482 | "version": "4.2.2", 2483 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", 2484 | "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", 2485 | "dev": true, 2486 | "requires": { 2487 | "emoji-regex": "^8.0.0", 2488 | "is-fullwidth-code-point": "^3.0.0", 2489 | "strip-ansi": "^6.0.0" 2490 | } 2491 | }, 2492 | "strip-ansi": { 2493 | "version": "6.0.0", 2494 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", 2495 | "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", 2496 | "dev": true, 2497 | "requires": { 2498 | "ansi-regex": "^5.0.0" 2499 | } 2500 | } 2501 | } 2502 | }, 2503 | "text-table": { 2504 | "version": "0.2.0", 2505 | "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", 2506 | "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", 2507 | "dev": true 2508 | }, 2509 | "through": { 2510 | "version": "2.3.8", 2511 | "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", 2512 | "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", 2513 | "dev": true 2514 | }, 2515 | "to-regex-range": { 2516 | "version": "5.0.1", 2517 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 2518 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 2519 | "dev": true, 2520 | "requires": { 2521 | "is-number": "^7.0.0" 2522 | } 2523 | }, 2524 | "toidentifier": { 2525 | "version": "1.0.0", 2526 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", 2527 | "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" 2528 | }, 2529 | "ts-node": { 2530 | "version": "10.1.0", 2531 | "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.1.0.tgz", 2532 | "integrity": "sha512-6szn3+J9WyG2hE+5W8e0ruZrzyk1uFLYye6IGMBadnOzDh8aP7t8CbFpsfCiEx2+wMixAhjFt7lOZC4+l+WbEA==", 2533 | "dev": true, 2534 | "requires": { 2535 | "@tsconfig/node10": "^1.0.7", 2536 | "@tsconfig/node12": "^1.0.7", 2537 | "@tsconfig/node14": "^1.0.0", 2538 | "@tsconfig/node16": "^1.0.1", 2539 | "arg": "^4.1.0", 2540 | "create-require": "^1.1.0", 2541 | "diff": "^4.0.1", 2542 | "make-error": "^1.1.1", 2543 | "source-map-support": "^0.5.17", 2544 | "yn": "3.1.1" 2545 | } 2546 | }, 2547 | "tsc-watch": { 2548 | "version": "4.4.0", 2549 | "resolved": "https://registry.npmjs.org/tsc-watch/-/tsc-watch-4.4.0.tgz", 2550 | "integrity": "sha512-+0Yey6ptOOXAnt44OKTk2/EnQnmA0auL7VWXm9d9abMS4tabt0Xdr9B4AK6OJbWAre9ZdLA81+Nk8sz9unptyA==", 2551 | "dev": true, 2552 | "requires": { 2553 | "cross-spawn": "^7.0.3", 2554 | "node-cleanup": "^2.1.2", 2555 | "ps-tree": "^1.2.0", 2556 | "string-argv": "^0.1.1", 2557 | "strip-ansi": "^6.0.0" 2558 | }, 2559 | "dependencies": { 2560 | "cross-spawn": { 2561 | "version": "7.0.3", 2562 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", 2563 | "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", 2564 | "dev": true, 2565 | "requires": { 2566 | "path-key": "^3.1.0", 2567 | "shebang-command": "^2.0.0", 2568 | "which": "^2.0.1" 2569 | } 2570 | }, 2571 | "path-key": { 2572 | "version": "3.1.1", 2573 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", 2574 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", 2575 | "dev": true 2576 | }, 2577 | "shebang-command": { 2578 | "version": "2.0.0", 2579 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", 2580 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", 2581 | "dev": true, 2582 | "requires": { 2583 | "shebang-regex": "^3.0.0" 2584 | } 2585 | }, 2586 | "shebang-regex": { 2587 | "version": "3.0.0", 2588 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", 2589 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", 2590 | "dev": true 2591 | }, 2592 | "strip-ansi": { 2593 | "version": "6.0.0", 2594 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", 2595 | "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", 2596 | "dev": true, 2597 | "requires": { 2598 | "ansi-regex": "^5.0.0" 2599 | } 2600 | }, 2601 | "which": { 2602 | "version": "2.0.2", 2603 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", 2604 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", 2605 | "dev": true, 2606 | "requires": { 2607 | "isexe": "^2.0.0" 2608 | } 2609 | } 2610 | } 2611 | }, 2612 | "tslib": { 2613 | "version": "1.14.1", 2614 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", 2615 | "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", 2616 | "dev": true 2617 | }, 2618 | "tsscmp": { 2619 | "version": "1.0.6", 2620 | "resolved": "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.6.tgz", 2621 | "integrity": "sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==" 2622 | }, 2623 | "tsutils": { 2624 | "version": "3.21.0", 2625 | "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", 2626 | "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", 2627 | "dev": true, 2628 | "requires": { 2629 | "tslib": "^1.8.1" 2630 | } 2631 | }, 2632 | "type-check": { 2633 | "version": "0.4.0", 2634 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", 2635 | "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", 2636 | "dev": true, 2637 | "requires": { 2638 | "prelude-ls": "^1.2.1" 2639 | } 2640 | }, 2641 | "type-fest": { 2642 | "version": "0.20.2", 2643 | "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", 2644 | "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", 2645 | "dev": true 2646 | }, 2647 | "type-is": { 2648 | "version": "1.6.18", 2649 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 2650 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 2651 | "requires": { 2652 | "media-typer": "0.3.0", 2653 | "mime-types": "~2.1.24" 2654 | } 2655 | }, 2656 | "typescript": { 2657 | "version": "4.3.5", 2658 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz", 2659 | "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==", 2660 | "dev": true 2661 | }, 2662 | "unpipe": { 2663 | "version": "1.0.0", 2664 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 2665 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" 2666 | }, 2667 | "uri-js": { 2668 | "version": "4.4.1", 2669 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", 2670 | "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", 2671 | "dev": true, 2672 | "requires": { 2673 | "punycode": "^2.1.0" 2674 | } 2675 | }, 2676 | "urijs": { 2677 | "version": "1.19.11", 2678 | "resolved": "https://registry.npmjs.org/urijs/-/urijs-1.19.11.tgz", 2679 | "integrity": "sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ==" 2680 | }, 2681 | "util-deprecate": { 2682 | "version": "1.0.2", 2683 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 2684 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", 2685 | "dev": true 2686 | }, 2687 | "v8-compile-cache": { 2688 | "version": "2.3.0", 2689 | "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", 2690 | "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", 2691 | "dev": true 2692 | }, 2693 | "vary": { 2694 | "version": "1.1.2", 2695 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 2696 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" 2697 | }, 2698 | "word-wrap": { 2699 | "version": "1.2.3", 2700 | "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", 2701 | "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", 2702 | "dev": true 2703 | }, 2704 | "wrappy": { 2705 | "version": "1.0.2", 2706 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 2707 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", 2708 | "dev": true 2709 | }, 2710 | "yallist": { 2711 | "version": "4.0.0", 2712 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", 2713 | "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", 2714 | "dev": true 2715 | }, 2716 | "ylru": { 2717 | "version": "1.2.1", 2718 | "resolved": "https://registry.npmjs.org/ylru/-/ylru-1.2.1.tgz", 2719 | "integrity": "sha512-faQrqNMzcPCHGVC2aaOINk13K+aaBDUPjGWl0teOXywElLjyVAB6Oe2jj62jHYtwsU49jXhScYbvPENK+6zAvQ==" 2720 | }, 2721 | "yn": { 2722 | "version": "3.1.1", 2723 | "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", 2724 | "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", 2725 | "dev": true 2726 | } 2727 | } 2728 | } 2729 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "shopping-cart-api", 3 | "version": "0.1.0", 4 | "description": "API for shopping cart", 5 | "main": "src/index.js", 6 | "repository": "git@github.com:bazaglia/shopping-cart.git", 7 | "author": "André Bazaglia", 8 | "license": "MIT", 9 | "scripts": { 10 | "start": "ts-node src/main.ts", 11 | "start:dev": "tsc-watch --onSuccess \"node dist/main.js\"", 12 | "lint": "eslint src --ext .js,.ts", 13 | "build": "tsc -b" 14 | }, 15 | "jest": { 16 | "testEnvironment": "node", 17 | "coverageDirectory": "./coverage/", 18 | "collectCoverage": true, 19 | "testMatch": [ 20 | "**/tests/**/*.test.js" 21 | ] 22 | }, 23 | "prettier": { 24 | "singleQuote": true, 25 | "trailingComma": "all", 26 | "semi": false 27 | }, 28 | "dependencies": { 29 | "@hapi/boom": "^7.4.3", 30 | "@koa/cors": "^3.0.0", 31 | "@koa/router": "^8.0.1", 32 | "cuid": "^2.1.4", 33 | "inversify": "^5.0.1", 34 | "joi": "^17.4.1", 35 | "koa": "^2.7.0", 36 | "koa-bodyparser": "^4.2.1", 37 | "koa-compress": "^3.0.0", 38 | "pino": "^6.13.0", 39 | "reflect-metadata": "^0.1.13" 40 | }, 41 | "devDependencies": { 42 | "@types/hapi__boom": "^7.4.0", 43 | "@types/joi": "^17.2.3", 44 | "@types/koa": "^2.0.49", 45 | "@types/koa-bodyparser": "^4.3.0", 46 | "@types/koa-compress": "^2.0.9", 47 | "@types/koa__cors": "^2.2.3", 48 | "@types/koa__router": "^8.0.0", 49 | "@types/node": "^12.6.2", 50 | "@types/pino": "^6.3.9", 51 | "@typescript-eslint/eslint-plugin": "^4.28.4", 52 | "@typescript-eslint/parser": "^4.28.4", 53 | "eslint": "^7.31.0", 54 | "eslint-config-prettier": "^8.3.0", 55 | "eslint-plugin-prettier": "^3.1.0", 56 | "pino-pretty": "^5.1.2", 57 | "prettier": "^2.3.2", 58 | "ts-node": "^10.1.0", 59 | "tsc-watch": "^4.0.0", 60 | "typescript": "^4.3.5" 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/api/http/controller.ts: -------------------------------------------------------------------------------- 1 | import { RouterContext } from '@koa/router' 2 | import { inject, injectable } from 'inversify' 3 | import { TYPES } from '../../types' 4 | import { Item } from '../../domain/item' 5 | import { ItemService } from '../../app/item' 6 | import { CartService } from '../../app/cart' 7 | import { validateCreateItem } from './validation/item' 8 | import { validateAddToCart } from './validation/cart' 9 | 10 | @injectable() 11 | export class HTTPController { 12 | @inject(TYPES.ItemService) private _itemService: ItemService 13 | @inject(TYPES.CartService) private _cartService: CartService 14 | 15 | public async listItems(ctx: RouterContext): Promise { 16 | const items = await this._itemService.findAll() 17 | ctx.body = items.map((item) => item.unmarshal()) 18 | } 19 | 20 | public async getItem(ctx: RouterContext): Promise { 21 | const item = await this._itemService.getById(ctx.params.id) 22 | ctx.body = item.unmarshal() 23 | } 24 | 25 | public async createItem(ctx: RouterContext): Promise { 26 | const input = validateCreateItem( 27 | ctx.request.body as Record, 28 | ) 29 | const item = Item.create(input) 30 | const created = await this._itemService.create(item) 31 | 32 | ctx.body = created.unmarshal() 33 | } 34 | 35 | public async getCart(ctx: RouterContext): Promise { 36 | const cart = await this._cartService.getById(ctx.params.id) 37 | ctx.body = cart.unmarshal() 38 | } 39 | 40 | public async addToCart(ctx: RouterContext): Promise { 41 | const { cartId } = ctx.params 42 | const { itemId, quantity } = validateAddToCart( 43 | ctx.request.body as Record, 44 | ) 45 | 46 | const item = await this._itemService.getById(itemId) 47 | const cart = await this._cartService.add(cartId, item, quantity) 48 | 49 | ctx.body = cart.unmarshal() 50 | } 51 | 52 | public async removeFromCart(ctx: RouterContext): Promise { 53 | const { cartId, itemId } = ctx.params 54 | const cart = await this._cartService.remove(cartId, itemId) 55 | ctx.body = cart.unmarshal() 56 | } 57 | 58 | public async emptyCart(ctx: RouterContext): Promise { 59 | const { cartId } = ctx.params 60 | await this._cartService.empty(cartId) 61 | ctx.body = null 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/api/http/middlewares/error-handler.ts: -------------------------------------------------------------------------------- 1 | import Joi from 'joi' 2 | import Boom from '@hapi/boom' 3 | import { RouterContext } from '@koa/router' 4 | import { ResourceNotFound, ValidationError } from '../../../libs/errors' 5 | 6 | const mapErrorToHttpResponse = (err: Error | Boom): Boom => { 7 | if (err instanceof Boom) { 8 | return err 9 | } 10 | 11 | if (err instanceof ResourceNotFound) { 12 | return Boom.notFound(err.message) 13 | } 14 | 15 | if (err instanceof ValidationError) { 16 | return Boom.badRequest(err.message) 17 | } 18 | 19 | if (err instanceof Joi.ValidationError) { 20 | return Boom.badRequest('Invalid input', err.details) 21 | } 22 | 23 | return Boom.badImplementation("Server couldn't handle your request") 24 | } 25 | 26 | export const errorHandler = async ( 27 | ctx: RouterContext, 28 | next: () => Promise, 29 | ): Promise => { 30 | try { 31 | await next() 32 | } catch (err) { 33 | const httpError = mapErrorToHttpResponse(err) 34 | 35 | ctx.status = httpError.output.statusCode 36 | ctx.body = { 37 | ...httpError.output.payload, 38 | ...(httpError.data ? { data: httpError.data } : {}), 39 | } 40 | 41 | ctx.app.emit('error', err, ctx) 42 | } 43 | } 44 | 45 | export const devErrorHandler = async ( 46 | ctx: RouterContext, 47 | next: () => Promise, 48 | ): Promise => { 49 | try { 50 | await next() 51 | } catch (err) { 52 | const httpError = mapErrorToHttpResponse(err) 53 | 54 | ctx.status = httpError.output.statusCode 55 | ctx.body = { 56 | ...httpError.output.payload, 57 | ...(httpError.data ? { data: httpError.data } : {}), 58 | stack: err.stack, 59 | } 60 | 61 | ctx.app.emit('error', err, ctx) 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/api/http/router.ts: -------------------------------------------------------------------------------- 1 | import Router, { RouterContext } from '@koa/router' 2 | import { inject, injectable } from 'inversify' 3 | import { TYPES } from '../../types' 4 | import { HTTPController } from './controller' 5 | 6 | @injectable() 7 | export class HTTPRouter { 8 | @inject(TYPES.HTTPController) private _controller: HTTPController 9 | 10 | get(): Router { 11 | return new Router() 12 | .get('/item', (ctx: RouterContext) => this._controller.listItems(ctx)) 13 | .get('/item/:id', (ctx: RouterContext) => this._controller.getItem(ctx)) 14 | .post('/item', (ctx: RouterContext) => this._controller.createItem(ctx)) 15 | .get('/cart/:id', (ctx: RouterContext) => this._controller.getCart(ctx)) 16 | .post('/cart/:cartId/item', (ctx: RouterContext) => 17 | this._controller.addToCart(ctx), 18 | ) 19 | .delete('/cart/:cartId/item/:itemId', (ctx: RouterContext) => 20 | this._controller.removeFromCart(ctx), 21 | ) 22 | .post('/cart/:cartId/clean', (ctx: RouterContext) => 23 | this._controller.emptyCart(ctx), 24 | ) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/api/http/server.ts: -------------------------------------------------------------------------------- 1 | import { injectable, inject } from 'inversify' 2 | import Koa from 'koa' 3 | import cors from '@koa/cors' 4 | import bodyParser from 'koa-bodyparser' 5 | import compress from 'koa-compress' 6 | 7 | import { TYPES } from '../../types' 8 | import { Logger } from '../../infra/logging/pino' 9 | import { errorHandler, devErrorHandler } from './middlewares/error-handler' 10 | import { HTTPRouter } from './router' 11 | 12 | export interface IServer { 13 | start(): void 14 | } 15 | 16 | @injectable() 17 | export class Server { 18 | @inject(TYPES.HTTPRouter) private _router: HTTPRouter 19 | @inject(TYPES.Logger) private _logger: Logger 20 | 21 | start(): void { 22 | const router = this._router.get() 23 | const logger = this._logger.get() 24 | const env = String(process.env) 25 | 26 | router.get('/robots.txt', (ctx) => { 27 | ctx.body = 'User-Agent: *\nDisallow: /' 28 | }) 29 | 30 | router.get('/health', (ctx) => { 31 | ctx.body = 'OK' 32 | }) 33 | 34 | const app = new Koa() 35 | 36 | app.use(cors()) 37 | app.use(bodyParser()) 38 | app.use(compress()) 39 | 40 | app.use(env === 'production' ? errorHandler : devErrorHandler) 41 | 42 | app.use(router.routes()) 43 | 44 | app.on('error', (err) => { 45 | if (process.env.NODE_ENV !== 'test') { 46 | logger.error(err) 47 | } 48 | }) 49 | 50 | app.listen(3000) 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/api/http/validation/cart.ts: -------------------------------------------------------------------------------- 1 | import Joi from 'joi' 2 | 3 | type AddToCartPayload = { 4 | itemId: string 5 | quantity: number 6 | } 7 | 8 | const schema = Joi.object({ 9 | itemId: Joi.string().alphanum().min(3).max(30).required(), 10 | quantity: Joi.number().positive().required(), 11 | }) 12 | 13 | export const validateAddToCart = ( 14 | body: Record, 15 | ): AddToCartPayload => { 16 | const validation = schema.validate(body) 17 | 18 | if (validation.error) { 19 | throw validation.error 20 | } 21 | 22 | return validation.value 23 | } 24 | -------------------------------------------------------------------------------- /src/api/http/validation/item.ts: -------------------------------------------------------------------------------- 1 | import Joi from 'joi' 2 | import { UnmarshalledItem } from '../../../domain/item' 3 | 4 | const schema = Joi.object({ 5 | id: Joi.string().alphanum().min(3).max(30), 6 | sku: Joi.string().required(), 7 | displayName: Joi.string().required(), 8 | price: Joi.number().positive().required(), 9 | }) 10 | 11 | export const validateCreateItem = ( 12 | body: Record, 13 | ): UnmarshalledItem => { 14 | const validation = schema.validate(body) 15 | 16 | if (validation.error) { 17 | throw validation.error 18 | } 19 | 20 | return validation.value as UnmarshalledItem 21 | } 22 | -------------------------------------------------------------------------------- /src/app/cart.ts: -------------------------------------------------------------------------------- 1 | import { inject, injectable } from 'inversify' 2 | import { TYPES } from '../types' 3 | import { Item } from '../domain/item' 4 | import { Cart } from '../domain/cart' 5 | import { CartRepository } from '../domain/repository' 6 | 7 | @injectable() 8 | export class CartService { 9 | @inject(TYPES.CartRepository) private repository: CartRepository 10 | 11 | private async _getCart(id: string): Promise { 12 | try { 13 | const cart = await this.repository.getById(id) 14 | return cart 15 | } catch (e) { 16 | const emptyCart = Cart.create({ id }) 17 | return this.repository.create(emptyCart) 18 | } 19 | } 20 | 21 | public getById(id: string): Promise { 22 | return this.repository.getById(id) 23 | } 24 | 25 | public async add(cartId: string, item: Item, sku: number): Promise { 26 | const cart = await this._getCart(cartId) 27 | cart.add(item, sku) 28 | 29 | return this.repository.update(cart) 30 | } 31 | 32 | public async remove(cartId: string, itemId: string): Promise { 33 | const cart = await this._getCart(cartId) 34 | cart.remove(itemId) 35 | 36 | return this.repository.update(cart) 37 | } 38 | 39 | public async empty(cartId: string): Promise { 40 | const cart = await this._getCart(cartId) 41 | cart.empty() 42 | 43 | return this.repository.update(cart) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/app/item.ts: -------------------------------------------------------------------------------- 1 | import { inject, injectable } from 'inversify' 2 | import { TYPES } from '../types' 3 | import { Item } from '../domain/item' 4 | import { ItemRepository } from '../domain/repository' 5 | 6 | @injectable() 7 | export class ItemService { 8 | @inject(TYPES.ItemRepository) private repository: ItemRepository 9 | 10 | public findAll(): Promise { 11 | return this.repository.findAll() 12 | } 13 | 14 | public getById(id: string): Promise { 15 | return this.repository.getById(id) 16 | } 17 | 18 | public create(item: Item): Promise { 19 | return this.repository.insert(item) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/container.ts: -------------------------------------------------------------------------------- 1 | import 'reflect-metadata' 2 | 3 | import { Container } from 'inversify' 4 | import { TYPES } from './types' 5 | 6 | import { CartRepository, ItemRepository } from './domain/repository' 7 | 8 | import { HTTPController } from './api/http/controller' 9 | import { HTTPRouter } from './api/http/router' 10 | import { Server, IServer } from './api/http/server' 11 | 12 | import { CartService } from './app/cart' 13 | import { ItemService } from './app/item' 14 | 15 | import { Logger } from './infra/logging/pino' 16 | import { MemoryData } from './infra/database/memory/memory-data' 17 | import { CartMemoryRepository } from './infra/database/memory/repositories/cart' 18 | import { ItemMemoryRepository } from './infra/database/memory/repositories/item' 19 | 20 | const container = new Container() 21 | 22 | container.bind(TYPES.HTTPController).to(HTTPController).inSingletonScope() 23 | container.bind(TYPES.HTTPRouter).to(HTTPRouter).inSingletonScope() 24 | container.bind(TYPES.Server).to(Server).inSingletonScope() 25 | 26 | container.bind(TYPES.CartService).to(CartService) 27 | container.bind(TYPES.ItemService).to(ItemService) 28 | 29 | container.bind(TYPES.Logger).to(Logger).inSingletonScope() 30 | container.bind(TYPES.Database).to(MemoryData).inSingletonScope() 31 | container.bind(TYPES.CartRepository).to(CartMemoryRepository) 32 | container.bind(TYPES.ItemRepository).to(ItemMemoryRepository) 33 | 34 | export { container } 35 | -------------------------------------------------------------------------------- /src/domain/cart.ts: -------------------------------------------------------------------------------- 1 | import { ValidationError } from '../libs/errors' 2 | import { Entity } from './entity' 3 | import { Item, UnmarshalledItem } from './item' 4 | 5 | export interface CartItem { 6 | item: Item 7 | quantity: number 8 | } 9 | 10 | export interface UnmarshalledCartItem { 11 | item: UnmarshalledItem 12 | quantity: number 13 | } 14 | 15 | export interface UnmarshalledCart { 16 | id: string 17 | products: UnmarshalledCartItem[] 18 | totalPrice: number 19 | } 20 | 21 | export interface CartProps { 22 | id?: string 23 | rawProducts?: UnmarshalledCartItem[] 24 | } 25 | 26 | export class Cart extends Entity { 27 | private _products: CartItem[] 28 | 29 | private constructor({ id, ...data }: CartProps) { 30 | super(data, id) 31 | } 32 | 33 | public static create(props: CartProps): Cart { 34 | const instance = new Cart(props) 35 | instance.products = instance.props.rawProducts || [] 36 | return instance 37 | } 38 | 39 | public unmarshal(): UnmarshalledCart { 40 | return { 41 | id: this.id, 42 | products: this.products.map((product) => ({ 43 | item: product.item.unmarshal(), 44 | quantity: product.quantity, 45 | })), 46 | totalPrice: this.totalPrice, 47 | } 48 | } 49 | 50 | private static validQuantity(quantity: number) { 51 | return quantity >= 1 && quantity <= 1000 52 | } 53 | 54 | get id(): string { 55 | return this._id 56 | } 57 | 58 | get totalPrice(): number { 59 | const sum = (acc: number, product: CartItem) => { 60 | return acc + product.item.price * product.quantity 61 | } 62 | 63 | return this.products.reduce(sum, 0) 64 | } 65 | 66 | get products(): CartItem[] { 67 | return this._products 68 | } 69 | 70 | set products(products: CartItem[] | UnmarshalledCartItem[]) { 71 | this._products = products.map((p) => ({ 72 | item: p.item instanceof Item ? p.item : Item.create(p.item), 73 | quantity: p.quantity, 74 | })) 75 | } 76 | 77 | public add(item: Item, quantity: number): void { 78 | if (!Cart.validQuantity(quantity)) { 79 | throw new ValidationError( 80 | 'SKU needs to have a quantity between 1 and 1000', 81 | ) 82 | } 83 | 84 | const index = this.products.findIndex((p) => p.item.sku === item.sku) 85 | 86 | if (index > -1) { 87 | const product = { 88 | ...this.products[index], 89 | quantity: this.products[index].quantity + quantity, 90 | } 91 | 92 | if (!Cart.validQuantity(product.quantity)) { 93 | throw new ValidationError('SKU exceeded allowed quantity') 94 | } 95 | 96 | const products = [ 97 | ...this.products.slice(0, index), 98 | product, 99 | ...this.products.slice(index + 1), 100 | ] 101 | 102 | this.products = products 103 | } else { 104 | this.products = [...this.products, { item, quantity }] 105 | } 106 | } 107 | 108 | public remove(itemId: string): void { 109 | const products = this.products.filter( 110 | (product) => product.item.id !== itemId, 111 | ) 112 | this.products = products 113 | } 114 | 115 | public empty(): void { 116 | this.products = [] 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /src/domain/entity.ts: -------------------------------------------------------------------------------- 1 | import UniqueEntityID from 'cuid' 2 | 3 | const isEntity = (v: Entity): v is Entity => { 4 | return v instanceof Entity 5 | } 6 | 7 | export abstract class Entity { 8 | protected readonly _id: string 9 | protected props: T 10 | 11 | constructor(props: T, id?: string) { 12 | this._id = id ? id : UniqueEntityID() 13 | this.props = props 14 | } 15 | 16 | public equals(object?: Entity): boolean { 17 | if (object == null || object == undefined) { 18 | return false 19 | } 20 | 21 | if (this === object) { 22 | return true 23 | } 24 | 25 | if (!isEntity(object)) { 26 | return false 27 | } 28 | 29 | return this._id == object._id 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/domain/item.ts: -------------------------------------------------------------------------------- 1 | import { Entity } from './entity' 2 | 3 | export interface UnmarshalledItem { 4 | id?: string 5 | sku: string 6 | displayName: string 7 | price: number 8 | } 9 | 10 | export class Item extends Entity { 11 | private constructor(props: UnmarshalledItem) { 12 | const { id, ...data } = props 13 | super(data, id) 14 | } 15 | 16 | public static create(props: UnmarshalledItem): Item { 17 | const instance = new Item(props) 18 | return instance 19 | } 20 | 21 | public unmarshal(): UnmarshalledItem { 22 | return { 23 | id: this.id, 24 | sku: this.sku, 25 | displayName: this.displayName, 26 | price: parseFloat(this.price.toString()), 27 | } 28 | } 29 | 30 | get id(): string { 31 | return this._id 32 | } 33 | 34 | get sku(): string { 35 | return this.props.sku 36 | } 37 | 38 | get displayName(): string { 39 | return this.props.displayName 40 | } 41 | 42 | get price(): number { 43 | return this.props.price 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/domain/repository.ts: -------------------------------------------------------------------------------- 1 | import { Cart } from './cart' 2 | import { Item } from './item' 3 | 4 | export interface CartRepository { 5 | getById(id: string): Promise 6 | create(cart: Cart): Promise 7 | update(cart: Cart): Promise 8 | } 9 | 10 | export interface ItemRepository { 11 | findAll(): Promise 12 | getById(id: string): Promise 13 | insert(item: Item): Promise 14 | } 15 | -------------------------------------------------------------------------------- /src/infra/database/memory/mappers/cart.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Cart, 3 | UnmarshalledCart, 4 | UnmarshalledCartItem, 5 | } from '../../../../domain/cart' 6 | 7 | const getProducts = (products: UnmarshalledCartItem[]) => { 8 | return products.map((product) => ({ 9 | item: product.item, 10 | quantity: product.quantity, 11 | })) 12 | } 13 | 14 | export class CartMapper { 15 | public static toDomain(raw: UnmarshalledCart): Cart { 16 | return Cart.create({ 17 | id: raw.id, 18 | rawProducts: getProducts(raw.products || []), 19 | }) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/infra/database/memory/mappers/item.ts: -------------------------------------------------------------------------------- 1 | import { Item, UnmarshalledItem } from '../../../../domain/item' 2 | 3 | export class ItemMapper { 4 | public static toDomain(raw: UnmarshalledItem): Item { 5 | return Item.create({ 6 | id: raw.id, 7 | displayName: raw.displayName, 8 | sku: raw.sku, 9 | price: raw.price, 10 | }) 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/infra/database/memory/memory-data.ts: -------------------------------------------------------------------------------- 1 | import { injectable } from 'inversify' 2 | import cuid from 'cuid' 3 | 4 | class Collection { 5 | private data: Record = {} 6 | 7 | async findAll(): Promise { 8 | return Object.entries(this.data).map(([key, value]) => ({ 9 | id: key, 10 | ...(value as Record), 11 | })) as T[] 12 | } 13 | 14 | async getById(id: string): Promise { 15 | return this.data[id] as T 16 | } 17 | 18 | async insert(value: T): Promise { 19 | this.data[value.id || cuid()] = value 20 | return value 21 | } 22 | 23 | async update(id: string, value: T): Promise { 24 | this.data[id] = value 25 | return this.data[id] as T 26 | } 27 | } 28 | 29 | @injectable() 30 | export class MemoryData { 31 | public items = new Collection() 32 | public cart = new Collection() 33 | } 34 | -------------------------------------------------------------------------------- /src/infra/database/memory/repositories/cart.ts: -------------------------------------------------------------------------------- 1 | import { injectable, inject } from 'inversify' 2 | import { TYPES } from '../../../../types' 3 | import { ResourceNotFound } from '../../../../libs/errors' 4 | import { Cart, UnmarshalledCart } from '../../../../domain/cart' 5 | import { CartRepository } from '../../../../domain/repository' 6 | import { MemoryData } from '../memory-data' 7 | import { CartMapper } from '../mappers/cart' 8 | 9 | @injectable() 10 | export class CartMemoryRepository implements CartRepository { 11 | @inject(TYPES.Database) private _database: MemoryData 12 | 13 | async getById(id: string): Promise { 14 | const cart = await this._database.cart.getById(id) 15 | if (!cart) { 16 | throw new ResourceNotFound('Cart', { id }) 17 | } 18 | return CartMapper.toDomain(cart) 19 | } 20 | 21 | async create(cart: Cart): Promise { 22 | const dtoCart = cart.unmarshal() 23 | const inserted = await this._database.cart.insert(dtoCart) 24 | return CartMapper.toDomain(inserted) 25 | } 26 | 27 | async update(cart: Cart): Promise { 28 | const dtoCart = cart.unmarshal() 29 | const updated = await this._database.cart.update( 30 | cart.id, 31 | dtoCart, 32 | ) 33 | 34 | return CartMapper.toDomain(updated) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/infra/database/memory/repositories/item.ts: -------------------------------------------------------------------------------- 1 | import { injectable, inject } from 'inversify' 2 | import { TYPES } from '../../../../types' 3 | import { ResourceNotFound } from '../../../../libs/errors' 4 | import { Item, UnmarshalledItem } from '../../../../domain/item' 5 | import { ItemRepository } from '../../../../domain/repository' 6 | import { MemoryData } from '../memory-data' 7 | import { ItemMapper } from '../mappers/item' 8 | 9 | @injectable() 10 | export class ItemMemoryRepository implements ItemRepository { 11 | @inject(TYPES.Database) private _database: MemoryData 12 | 13 | async findAll(): Promise { 14 | const items = await (>( 15 | this._database.items.findAll() 16 | )) 17 | return items.map((item) => ItemMapper.toDomain(item)) 18 | } 19 | 20 | async getById(id: string): Promise { 21 | const item = await this._database.items.getById(id) 22 | if (!item) { 23 | throw new ResourceNotFound('Item', { id }) 24 | } 25 | return ItemMapper.toDomain(item) 26 | } 27 | 28 | async insert(item: Item): Promise { 29 | const dtoItem = item.unmarshal() 30 | const inserted = await this._database.items.insert(dtoItem) 31 | return ItemMapper.toDomain(inserted) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/infra/logging/pino.ts: -------------------------------------------------------------------------------- 1 | import { injectable } from 'inversify' 2 | import pino from 'pino' 3 | 4 | @injectable() 5 | export class Logger { 6 | get(): pino.Logger { 7 | return pino({ prettyPrint: { colorize: true } }) 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/libs/errors.ts: -------------------------------------------------------------------------------- 1 | class ExtendableError extends Error { 2 | constructor(message: string) { 3 | super(message) 4 | this.name = this.constructor.name 5 | Error.captureStackTrace(this, this.constructor) 6 | } 7 | } 8 | 9 | export class InternalError extends ExtendableError { 10 | data: Record 11 | 12 | constructor(message: string, data: Record) { 13 | super(message) 14 | this.data = data 15 | } 16 | } 17 | 18 | export class ValidationError extends ExtendableError {} 19 | 20 | export class ResourceNotFound extends ExtendableError { 21 | data: Record 22 | 23 | constructor(resource: string, query: Record | string) { 24 | super(`Resource ${resource} was not found.`) 25 | this.data = { resource, query } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import 'reflect-metadata' 2 | 3 | import { container } from './container' 4 | import { TYPES } from './types' 5 | import { IServer } from './api/http/server' 6 | 7 | const start = async () => { 8 | const server = container.get(TYPES.Server) 9 | return server.start() 10 | } 11 | 12 | start() 13 | console.log('Listening on http://localhost:3000') 14 | -------------------------------------------------------------------------------- /src/types.ts: -------------------------------------------------------------------------------- 1 | const TYPES = { 2 | Logger: Symbol.for('Logger'), 3 | Database: Symbol.for('Database'), 4 | 5 | Server: Symbol.for('Server'), 6 | HTTPController: Symbol.for('HTTPController'), 7 | HTTPRouter: Symbol.for('HTTPRouter'), 8 | 9 | CartService: Symbol.for('CartService'), 10 | CartRepository: Symbol.for('CartRepository'), 11 | ItemService: Symbol.for('ItemService'), 12 | ItemRepository: Symbol.for('ItemRepository'), 13 | } 14 | 15 | export { TYPES } 16 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "moduleResolution": "node", 5 | "target": "es2020", 6 | "lib": ["es2020"], 7 | "types": ["reflect-metadata"], 8 | "outDir": "./dist", 9 | "removeComments": true, 10 | "emitDecoratorMetadata": true, 11 | "experimentalDecorators": true, 12 | "sourceMap": true, 13 | "incremental": true, 14 | "noImplicitAny": true, 15 | "esModuleInterop": true, 16 | }, 17 | "exclude": [ 18 | "node_modules", 19 | "dist" 20 | ] 21 | } --------------------------------------------------------------------------------