├── .editorconfig ├── .eslintrc.js ├── .gitignore ├── .prettierrc.js ├── .vscode └── settings.json ├── package-lock.json ├── package.json ├── src ├── dip │ ├── classes │ │ ├── customer.ts │ │ ├── discount.ts │ │ ├── interfaces │ │ │ ├── cart-item.ts │ │ │ ├── customer-protocol.ts │ │ │ ├── messaging-protocol.ts │ │ │ ├── order-status.ts │ │ │ ├── persistency-protocol.ts │ │ │ └── shopping-cart-protocol.ts │ │ ├── order.ts │ │ ├── product.ts │ │ └── shopping-cart.ts │ ├── main.ts │ └── services │ │ ├── messaging.ts │ │ └── persistency.ts ├── index.ts ├── isp │ ├── classes │ │ ├── customer.ts │ │ ├── discount.ts │ │ ├── interfaces │ │ │ ├── cart-item.ts │ │ │ ├── customer-protocol.ts │ │ │ └── order-status.ts │ │ ├── order.ts │ │ ├── product.ts │ │ └── shopping-cart.ts │ ├── main.ts │ └── services │ │ ├── messaging.ts │ │ └── persistency.ts ├── legacy │ └── shopping-cart-legacy.ts ├── lsp │ ├── classes │ │ ├── discount.ts │ │ ├── interfaces │ │ │ ├── cart-item.ts │ │ │ └── order-status.ts │ │ ├── order.ts │ │ ├── product.ts │ │ └── shopping-cart.ts │ ├── main.ts │ └── services │ │ ├── messaging.ts │ │ └── persistency.ts ├── ocp │ ├── classes │ │ ├── discount.ts │ │ ├── interfaces │ │ │ ├── cart-item.ts │ │ │ └── order-status.ts │ │ ├── order.ts │ │ ├── product.ts │ │ └── shopping-cart.ts │ ├── main.ts │ └── services │ │ ├── messaging.ts │ │ └── persistency.ts └── srp │ ├── classes │ ├── interfaces │ │ ├── cart-item.ts │ │ └── order-status.ts │ ├── order.ts │ ├── product.ts │ └── shopping-cart.ts │ ├── main.ts │ └── services │ ├── messaging.ts │ └── persistency.ts └── tsconfig.json /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | charset = utf-8 7 | trim_trailing_whitespace = true 8 | insert_final_newline = true 9 | end_of_line = lf -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | browser: true, 4 | es6: true, 5 | node: true, 6 | }, 7 | extends: [ 8 | 'eslint:recommended', 9 | 'plugin:@typescript-eslint/eslint-recommended', 10 | 'plugin:@typescript-eslint/recommended', 11 | 'plugin:prettier/recommended', 12 | ], 13 | globals: { 14 | Atomics: 'readonly', 15 | SharedArrayBuffer: 'readonly', 16 | }, 17 | parser: '@typescript-eslint/parser', 18 | parserOptions: { 19 | ecmaVersion: 11, 20 | sourceType: 'module', 21 | }, 22 | plugins: ['@typescript-eslint'], 23 | rules: {}, 24 | }; 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.toptal.com/developers/gitignore/api/node 3 | # Edit at https://www.toptal.com/developers/gitignore?templates=node 4 | 5 | ### Node ### 6 | # Logs 7 | logs 8 | *.log 9 | npm-debug.log* 10 | yarn-debug.log* 11 | yarn-error.log* 12 | lerna-debug.log* 13 | 14 | # Diagnostic reports (https://nodejs.org/api/report.html) 15 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 16 | 17 | # Runtime data 18 | pids 19 | *.pid 20 | *.seed 21 | *.pid.lock 22 | 23 | # Directory for instrumented libs generated by jscoverage/JSCover 24 | lib-cov 25 | 26 | # Coverage directory used by tools like istanbul 27 | coverage 28 | *.lcov 29 | 30 | # nyc test coverage 31 | .nyc_output 32 | 33 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 34 | .grunt 35 | 36 | # Bower dependency directory (https://bower.io/) 37 | bower_components 38 | 39 | # node-waf configuration 40 | .lock-wscript 41 | 42 | # Compiled binary addons (https://nodejs.org/api/addons.html) 43 | build/Release 44 | 45 | # Dependency directories 46 | node_modules/ 47 | jspm_packages/ 48 | 49 | # TypeScript v1 declaration files 50 | typings/ 51 | 52 | # TypeScript cache 53 | *.tsbuildinfo 54 | 55 | # Optional npm cache directory 56 | .npm 57 | 58 | # Optional eslint cache 59 | .eslintcache 60 | 61 | # Microbundle cache 62 | .rpt2_cache/ 63 | .rts2_cache_cjs/ 64 | .rts2_cache_es/ 65 | .rts2_cache_umd/ 66 | 67 | # Optional REPL history 68 | .node_repl_history 69 | 70 | # Output of 'npm pack' 71 | *.tgz 72 | 73 | # Yarn Integrity file 74 | .yarn-integrity 75 | 76 | # dotenv environment variables file 77 | .env 78 | .env.test 79 | 80 | # parcel-bundler cache (https://parceljs.org/) 81 | .cache 82 | 83 | # Next.js build output 84 | .next 85 | 86 | # Nuxt.js build / generate output 87 | .nuxt 88 | dist 89 | 90 | # Gatsby files 91 | .cache/ 92 | # Comment in the public line in if your project uses Gatsby and not Next.js 93 | # https://nextjs.org/blog/next-9-1#public-directory-support 94 | # public 95 | 96 | # vuepress build output 97 | .vuepress/dist 98 | 99 | # Serverless directories 100 | .serverless/ 101 | 102 | # FuseBox cache 103 | .fusebox/ 104 | 105 | # DynamoDB Local files 106 | .dynamodb/ 107 | 108 | # TernJS port file 109 | .tern-port 110 | 111 | # Stores VSCode versions used for testing VSCode extensions 112 | .vscode-test 113 | 114 | # End of https://www.toptal.com/developers/gitignore/api/node -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | semi: true, 3 | trailingComma: 'all', 4 | singleQuote: true, 5 | printWidth: 80, 6 | tabWidth: 2, 7 | } 8 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.fontSize": 20, 3 | "window.zoomLevel": 1, 4 | "code-runner.executorMap": { 5 | "typescript": "clear && npx ts-node --files --transpile-only", 6 | }, 7 | "liveServer.settings.port": 5501 8 | } 9 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescriptsolid", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@babel/code-frame": { 8 | "version": "7.10.4", 9 | "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", 10 | "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", 11 | "dev": true, 12 | "requires": { 13 | "@babel/highlight": "^7.10.4" 14 | } 15 | }, 16 | "@babel/helper-validator-identifier": { 17 | "version": "7.10.4", 18 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", 19 | "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", 20 | "dev": true 21 | }, 22 | "@babel/highlight": { 23 | "version": "7.10.4", 24 | "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", 25 | "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", 26 | "dev": true, 27 | "requires": { 28 | "@babel/helper-validator-identifier": "^7.10.4", 29 | "chalk": "^2.0.0", 30 | "js-tokens": "^4.0.0" 31 | }, 32 | "dependencies": { 33 | "chalk": { 34 | "version": "2.4.2", 35 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", 36 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", 37 | "dev": true, 38 | "requires": { 39 | "ansi-styles": "^3.2.1", 40 | "escape-string-regexp": "^1.0.5", 41 | "supports-color": "^5.3.0" 42 | } 43 | } 44 | } 45 | }, 46 | "@types/color-name": { 47 | "version": "1.1.1", 48 | "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", 49 | "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", 50 | "dev": true 51 | }, 52 | "@types/eslint-visitor-keys": { 53 | "version": "1.0.0", 54 | "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", 55 | "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==", 56 | "dev": true 57 | }, 58 | "@types/json-schema": { 59 | "version": "7.0.5", 60 | "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.5.tgz", 61 | "integrity": "sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ==", 62 | "dev": true 63 | }, 64 | "@types/node": { 65 | "version": "14.0.23", 66 | "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.23.tgz", 67 | "integrity": "sha512-Z4U8yDAl5TFkmYsZdFPdjeMa57NOvnaf1tljHzhouaPEp7LCj2JKkejpI1ODviIAQuW4CcQmxkQ77rnLsOOoKw==", 68 | "dev": true 69 | }, 70 | "@typescript-eslint/eslint-plugin": { 71 | "version": "3.6.1", 72 | "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.6.1.tgz", 73 | "integrity": "sha512-06lfjo76naNeOMDl+mWG9Fh/a0UHKLGhin+mGaIw72FUMbMGBkdi/FEJmgEDzh4eE73KIYzHWvOCYJ0ak7nrJQ==", 74 | "dev": true, 75 | "requires": { 76 | "@typescript-eslint/experimental-utils": "3.6.1", 77 | "debug": "^4.1.1", 78 | "functional-red-black-tree": "^1.0.1", 79 | "regexpp": "^3.0.0", 80 | "semver": "^7.3.2", 81 | "tsutils": "^3.17.1" 82 | } 83 | }, 84 | "@typescript-eslint/experimental-utils": { 85 | "version": "3.6.1", 86 | "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-3.6.1.tgz", 87 | "integrity": "sha512-oS+hihzQE5M84ewXrTlVx7eTgc52eu+sVmG7ayLfOhyZmJ8Unvf3osyFQNADHP26yoThFfbxcibbO0d2FjnYhg==", 88 | "dev": true, 89 | "requires": { 90 | "@types/json-schema": "^7.0.3", 91 | "@typescript-eslint/types": "3.6.1", 92 | "@typescript-eslint/typescript-estree": "3.6.1", 93 | "eslint-scope": "^5.0.0", 94 | "eslint-utils": "^2.0.0" 95 | } 96 | }, 97 | "@typescript-eslint/parser": { 98 | "version": "3.6.1", 99 | "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-3.6.1.tgz", 100 | "integrity": "sha512-SLihQU8RMe77YJ/jGTqOt0lMq7k3hlPVfp7v/cxMnXA9T0bQYoMDfTsNgHXpwSJM1Iq2aAJ8WqekxUwGv5F67Q==", 101 | "dev": true, 102 | "requires": { 103 | "@types/eslint-visitor-keys": "^1.0.0", 104 | "@typescript-eslint/experimental-utils": "3.6.1", 105 | "@typescript-eslint/types": "3.6.1", 106 | "@typescript-eslint/typescript-estree": "3.6.1", 107 | "eslint-visitor-keys": "^1.1.0" 108 | } 109 | }, 110 | "@typescript-eslint/types": { 111 | "version": "3.6.1", 112 | "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-3.6.1.tgz", 113 | "integrity": "sha512-NPxd5yXG63gx57WDTW1rp0cF3XlNuuFFB5G+Kc48zZ+51ZnQn9yjDEsjTPQ+aWM+V+Z0I4kuTFKjKvgcT1F7xQ==", 114 | "dev": true 115 | }, 116 | "@typescript-eslint/typescript-estree": { 117 | "version": "3.6.1", 118 | "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-3.6.1.tgz", 119 | "integrity": "sha512-G4XRe/ZbCZkL1fy09DPN3U0mR6SayIv1zSeBNquRFRk7CnVLgkC2ZPj8llEMJg5Y8dJ3T76SvTGtceytniaztQ==", 120 | "dev": true, 121 | "requires": { 122 | "@typescript-eslint/types": "3.6.1", 123 | "@typescript-eslint/visitor-keys": "3.6.1", 124 | "debug": "^4.1.1", 125 | "glob": "^7.1.6", 126 | "is-glob": "^4.0.1", 127 | "lodash": "^4.17.15", 128 | "semver": "^7.3.2", 129 | "tsutils": "^3.17.1" 130 | } 131 | }, 132 | "@typescript-eslint/visitor-keys": { 133 | "version": "3.6.1", 134 | "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-3.6.1.tgz", 135 | "integrity": "sha512-qC8Olwz5ZyMTZrh4Wl3K4U6tfms0R/mzU4/5W3XeUZptVraGVmbptJbn6h2Ey6Rb3hOs3zWoAUebZk8t47KGiQ==", 136 | "dev": true, 137 | "requires": { 138 | "eslint-visitor-keys": "^1.1.0" 139 | } 140 | }, 141 | "acorn": { 142 | "version": "7.3.1", 143 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.3.1.tgz", 144 | "integrity": "sha512-tLc0wSnatxAQHVHUapaHdz72pi9KUyHjq5KyHjGg9Y8Ifdc79pTh2XvI6I1/chZbnM7QtNKzh66ooDogPZSleA==", 145 | "dev": true 146 | }, 147 | "acorn-jsx": { 148 | "version": "5.2.0", 149 | "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz", 150 | "integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==", 151 | "dev": true 152 | }, 153 | "ajv": { 154 | "version": "6.12.3", 155 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.3.tgz", 156 | "integrity": "sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA==", 157 | "dev": true, 158 | "requires": { 159 | "fast-deep-equal": "^3.1.1", 160 | "fast-json-stable-stringify": "^2.0.0", 161 | "json-schema-traverse": "^0.4.1", 162 | "uri-js": "^4.2.2" 163 | } 164 | }, 165 | "ansi-colors": { 166 | "version": "4.1.1", 167 | "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", 168 | "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", 169 | "dev": true 170 | }, 171 | "ansi-regex": { 172 | "version": "5.0.0", 173 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", 174 | "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", 175 | "dev": true 176 | }, 177 | "ansi-styles": { 178 | "version": "3.2.1", 179 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 180 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 181 | "dev": true, 182 | "requires": { 183 | "color-convert": "^1.9.0" 184 | } 185 | }, 186 | "arg": { 187 | "version": "4.1.3", 188 | "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", 189 | "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", 190 | "dev": true 191 | }, 192 | "argparse": { 193 | "version": "1.0.10", 194 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", 195 | "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", 196 | "dev": true, 197 | "requires": { 198 | "sprintf-js": "~1.0.2" 199 | } 200 | }, 201 | "astral-regex": { 202 | "version": "1.0.0", 203 | "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", 204 | "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", 205 | "dev": true 206 | }, 207 | "balanced-match": { 208 | "version": "1.0.0", 209 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 210 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", 211 | "dev": true 212 | }, 213 | "big.js": { 214 | "version": "5.2.2", 215 | "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", 216 | "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", 217 | "dev": true 218 | }, 219 | "brace-expansion": { 220 | "version": "1.1.11", 221 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 222 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 223 | "dev": true, 224 | "requires": { 225 | "balanced-match": "^1.0.0", 226 | "concat-map": "0.0.1" 227 | } 228 | }, 229 | "braces": { 230 | "version": "3.0.2", 231 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", 232 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", 233 | "dev": true, 234 | "requires": { 235 | "fill-range": "^7.0.1" 236 | } 237 | }, 238 | "buffer-from": { 239 | "version": "1.1.1", 240 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", 241 | "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", 242 | "dev": true 243 | }, 244 | "callsites": { 245 | "version": "3.1.0", 246 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", 247 | "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", 248 | "dev": true 249 | }, 250 | "chalk": { 251 | "version": "4.1.0", 252 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", 253 | "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", 254 | "dev": true, 255 | "requires": { 256 | "ansi-styles": "^4.1.0", 257 | "supports-color": "^7.1.0" 258 | }, 259 | "dependencies": { 260 | "ansi-styles": { 261 | "version": "4.2.1", 262 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", 263 | "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", 264 | "dev": true, 265 | "requires": { 266 | "@types/color-name": "^1.1.1", 267 | "color-convert": "^2.0.1" 268 | } 269 | }, 270 | "color-convert": { 271 | "version": "2.0.1", 272 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 273 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 274 | "dev": true, 275 | "requires": { 276 | "color-name": "~1.1.4" 277 | } 278 | }, 279 | "color-name": { 280 | "version": "1.1.4", 281 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 282 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 283 | "dev": true 284 | }, 285 | "has-flag": { 286 | "version": "4.0.0", 287 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 288 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 289 | "dev": true 290 | }, 291 | "supports-color": { 292 | "version": "7.1.0", 293 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", 294 | "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", 295 | "dev": true, 296 | "requires": { 297 | "has-flag": "^4.0.0" 298 | } 299 | } 300 | } 301 | }, 302 | "color-convert": { 303 | "version": "1.9.3", 304 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", 305 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", 306 | "dev": true, 307 | "requires": { 308 | "color-name": "1.1.3" 309 | } 310 | }, 311 | "color-name": { 312 | "version": "1.1.3", 313 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 314 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", 315 | "dev": true 316 | }, 317 | "concat-map": { 318 | "version": "0.0.1", 319 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 320 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 321 | "dev": true 322 | }, 323 | "core-util-is": { 324 | "version": "1.0.2", 325 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 326 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", 327 | "dev": true 328 | }, 329 | "cross-spawn": { 330 | "version": "7.0.3", 331 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", 332 | "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", 333 | "dev": true, 334 | "requires": { 335 | "path-key": "^3.1.0", 336 | "shebang-command": "^2.0.0", 337 | "which": "^2.0.1" 338 | } 339 | }, 340 | "debug": { 341 | "version": "4.1.1", 342 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", 343 | "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", 344 | "dev": true, 345 | "requires": { 346 | "ms": "^2.1.1" 347 | } 348 | }, 349 | "deep-is": { 350 | "version": "0.1.3", 351 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", 352 | "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", 353 | "dev": true 354 | }, 355 | "diff": { 356 | "version": "4.0.2", 357 | "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", 358 | "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", 359 | "dev": true 360 | }, 361 | "doctrine": { 362 | "version": "3.0.0", 363 | "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", 364 | "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", 365 | "dev": true, 366 | "requires": { 367 | "esutils": "^2.0.2" 368 | } 369 | }, 370 | "emoji-regex": { 371 | "version": "7.0.3", 372 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", 373 | "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", 374 | "dev": true 375 | }, 376 | "emojis-list": { 377 | "version": "3.0.0", 378 | "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", 379 | "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", 380 | "dev": true 381 | }, 382 | "enhanced-resolve": { 383 | "version": "4.2.0", 384 | "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.2.0.tgz", 385 | "integrity": "sha512-S7eiFb/erugyd1rLb6mQ3Vuq+EXHv5cpCkNqqIkYkBgN2QdFnyCZzFBleqwGEx4lgNGYij81BWnCrFNK7vxvjQ==", 386 | "dev": true, 387 | "requires": { 388 | "graceful-fs": "^4.1.2", 389 | "memory-fs": "^0.5.0", 390 | "tapable": "^1.0.0" 391 | } 392 | }, 393 | "enquirer": { 394 | "version": "2.3.6", 395 | "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", 396 | "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", 397 | "dev": true, 398 | "requires": { 399 | "ansi-colors": "^4.1.1" 400 | } 401 | }, 402 | "errno": { 403 | "version": "0.1.7", 404 | "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", 405 | "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", 406 | "dev": true, 407 | "requires": { 408 | "prr": "~1.0.1" 409 | } 410 | }, 411 | "escape-string-regexp": { 412 | "version": "1.0.5", 413 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 414 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", 415 | "dev": true 416 | }, 417 | "eslint": { 418 | "version": "7.5.0", 419 | "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.5.0.tgz", 420 | "integrity": "sha512-vlUP10xse9sWt9SGRtcr1LAC67BENcQMFeV+w5EvLEoFe3xJ8cF1Skd0msziRx/VMC+72B4DxreCE+OR12OA6Q==", 421 | "dev": true, 422 | "requires": { 423 | "@babel/code-frame": "^7.0.0", 424 | "ajv": "^6.10.0", 425 | "chalk": "^4.0.0", 426 | "cross-spawn": "^7.0.2", 427 | "debug": "^4.0.1", 428 | "doctrine": "^3.0.0", 429 | "enquirer": "^2.3.5", 430 | "eslint-scope": "^5.1.0", 431 | "eslint-utils": "^2.1.0", 432 | "eslint-visitor-keys": "^1.3.0", 433 | "espree": "^7.2.0", 434 | "esquery": "^1.2.0", 435 | "esutils": "^2.0.2", 436 | "file-entry-cache": "^5.0.1", 437 | "functional-red-black-tree": "^1.0.1", 438 | "glob-parent": "^5.0.0", 439 | "globals": "^12.1.0", 440 | "ignore": "^4.0.6", 441 | "import-fresh": "^3.0.0", 442 | "imurmurhash": "^0.1.4", 443 | "is-glob": "^4.0.0", 444 | "js-yaml": "^3.13.1", 445 | "json-stable-stringify-without-jsonify": "^1.0.1", 446 | "levn": "^0.4.1", 447 | "lodash": "^4.17.19", 448 | "minimatch": "^3.0.4", 449 | "natural-compare": "^1.4.0", 450 | "optionator": "^0.9.1", 451 | "progress": "^2.0.0", 452 | "regexpp": "^3.1.0", 453 | "semver": "^7.2.1", 454 | "strip-ansi": "^6.0.0", 455 | "strip-json-comments": "^3.1.0", 456 | "table": "^5.2.3", 457 | "text-table": "^0.2.0", 458 | "v8-compile-cache": "^2.0.3" 459 | } 460 | }, 461 | "eslint-config-prettier": { 462 | "version": "6.11.0", 463 | "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.11.0.tgz", 464 | "integrity": "sha512-oB8cpLWSAjOVFEJhhyMZh6NOEOtBVziaqdDQ86+qhDHFbZXoRTM7pNSvFRfW/W/L/LrQ38C99J5CGuRBBzBsdA==", 465 | "dev": true, 466 | "requires": { 467 | "get-stdin": "^6.0.0" 468 | } 469 | }, 470 | "eslint-plugin-prettier": { 471 | "version": "3.1.4", 472 | "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.4.tgz", 473 | "integrity": "sha512-jZDa8z76klRqo+TdGDTFJSavwbnWK2ZpqGKNZ+VvweMW516pDUMmQ2koXvxEE4JhzNvTv+radye/bWGBmA6jmg==", 474 | "dev": true, 475 | "requires": { 476 | "prettier-linter-helpers": "^1.0.0" 477 | } 478 | }, 479 | "eslint-scope": { 480 | "version": "5.1.0", 481 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.0.tgz", 482 | "integrity": "sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w==", 483 | "dev": true, 484 | "requires": { 485 | "esrecurse": "^4.1.0", 486 | "estraverse": "^4.1.1" 487 | } 488 | }, 489 | "eslint-utils": { 490 | "version": "2.1.0", 491 | "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", 492 | "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", 493 | "dev": true, 494 | "requires": { 495 | "eslint-visitor-keys": "^1.1.0" 496 | } 497 | }, 498 | "eslint-visitor-keys": { 499 | "version": "1.3.0", 500 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", 501 | "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", 502 | "dev": true 503 | }, 504 | "espree": { 505 | "version": "7.2.0", 506 | "resolved": "https://registry.npmjs.org/espree/-/espree-7.2.0.tgz", 507 | "integrity": "sha512-H+cQ3+3JYRMEIOl87e7QdHX70ocly5iW4+dttuR8iYSPr/hXKFb+7dBsZ7+u1adC4VrnPlTkv0+OwuPnDop19g==", 508 | "dev": true, 509 | "requires": { 510 | "acorn": "^7.3.1", 511 | "acorn-jsx": "^5.2.0", 512 | "eslint-visitor-keys": "^1.3.0" 513 | } 514 | }, 515 | "esprima": { 516 | "version": "4.0.1", 517 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", 518 | "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", 519 | "dev": true 520 | }, 521 | "esquery": { 522 | "version": "1.3.1", 523 | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", 524 | "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", 525 | "dev": true, 526 | "requires": { 527 | "estraverse": "^5.1.0" 528 | }, 529 | "dependencies": { 530 | "estraverse": { 531 | "version": "5.1.0", 532 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.1.0.tgz", 533 | "integrity": "sha512-FyohXK+R0vE+y1nHLoBM7ZTyqRpqAlhdZHCWIWEviFLiGB8b04H6bQs8G+XTthacvT8VuwvteiP7RJSxMs8UEw==", 534 | "dev": true 535 | } 536 | } 537 | }, 538 | "esrecurse": { 539 | "version": "4.2.1", 540 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", 541 | "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", 542 | "dev": true, 543 | "requires": { 544 | "estraverse": "^4.1.0" 545 | } 546 | }, 547 | "estraverse": { 548 | "version": "4.3.0", 549 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", 550 | "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", 551 | "dev": true 552 | }, 553 | "esutils": { 554 | "version": "2.0.3", 555 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", 556 | "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", 557 | "dev": true 558 | }, 559 | "fast-deep-equal": { 560 | "version": "3.1.3", 561 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", 562 | "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", 563 | "dev": true 564 | }, 565 | "fast-diff": { 566 | "version": "1.2.0", 567 | "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", 568 | "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", 569 | "dev": true 570 | }, 571 | "fast-json-stable-stringify": { 572 | "version": "2.1.0", 573 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", 574 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", 575 | "dev": true 576 | }, 577 | "fast-levenshtein": { 578 | "version": "2.0.6", 579 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 580 | "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", 581 | "dev": true 582 | }, 583 | "file-entry-cache": { 584 | "version": "5.0.1", 585 | "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", 586 | "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", 587 | "dev": true, 588 | "requires": { 589 | "flat-cache": "^2.0.1" 590 | } 591 | }, 592 | "fill-range": { 593 | "version": "7.0.1", 594 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", 595 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", 596 | "dev": true, 597 | "requires": { 598 | "to-regex-range": "^5.0.1" 599 | } 600 | }, 601 | "flat-cache": { 602 | "version": "2.0.1", 603 | "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", 604 | "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", 605 | "dev": true, 606 | "requires": { 607 | "flatted": "^2.0.0", 608 | "rimraf": "2.6.3", 609 | "write": "1.0.3" 610 | } 611 | }, 612 | "flatted": { 613 | "version": "2.0.2", 614 | "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", 615 | "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", 616 | "dev": true 617 | }, 618 | "fs.realpath": { 619 | "version": "1.0.0", 620 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 621 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", 622 | "dev": true 623 | }, 624 | "functional-red-black-tree": { 625 | "version": "1.0.1", 626 | "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", 627 | "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", 628 | "dev": true 629 | }, 630 | "get-stdin": { 631 | "version": "6.0.0", 632 | "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", 633 | "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", 634 | "dev": true 635 | }, 636 | "glob": { 637 | "version": "7.1.6", 638 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", 639 | "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", 640 | "dev": true, 641 | "requires": { 642 | "fs.realpath": "^1.0.0", 643 | "inflight": "^1.0.4", 644 | "inherits": "2", 645 | "minimatch": "^3.0.4", 646 | "once": "^1.3.0", 647 | "path-is-absolute": "^1.0.0" 648 | } 649 | }, 650 | "glob-parent": { 651 | "version": "5.1.1", 652 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", 653 | "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", 654 | "dev": true, 655 | "requires": { 656 | "is-glob": "^4.0.1" 657 | } 658 | }, 659 | "globals": { 660 | "version": "12.4.0", 661 | "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", 662 | "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", 663 | "dev": true, 664 | "requires": { 665 | "type-fest": "^0.8.1" 666 | } 667 | }, 668 | "graceful-fs": { 669 | "version": "4.2.4", 670 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", 671 | "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", 672 | "dev": true 673 | }, 674 | "has-flag": { 675 | "version": "3.0.0", 676 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 677 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", 678 | "dev": true 679 | }, 680 | "ignore": { 681 | "version": "4.0.6", 682 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", 683 | "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", 684 | "dev": true 685 | }, 686 | "import-fresh": { 687 | "version": "3.2.1", 688 | "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", 689 | "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", 690 | "dev": true, 691 | "requires": { 692 | "parent-module": "^1.0.0", 693 | "resolve-from": "^4.0.0" 694 | } 695 | }, 696 | "imurmurhash": { 697 | "version": "0.1.4", 698 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", 699 | "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", 700 | "dev": true 701 | }, 702 | "inflight": { 703 | "version": "1.0.6", 704 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 705 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 706 | "dev": true, 707 | "requires": { 708 | "once": "^1.3.0", 709 | "wrappy": "1" 710 | } 711 | }, 712 | "inherits": { 713 | "version": "2.0.4", 714 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 715 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 716 | "dev": true 717 | }, 718 | "is-extglob": { 719 | "version": "2.1.1", 720 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 721 | "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", 722 | "dev": true 723 | }, 724 | "is-fullwidth-code-point": { 725 | "version": "2.0.0", 726 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 727 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", 728 | "dev": true 729 | }, 730 | "is-glob": { 731 | "version": "4.0.1", 732 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", 733 | "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", 734 | "dev": true, 735 | "requires": { 736 | "is-extglob": "^2.1.1" 737 | } 738 | }, 739 | "is-number": { 740 | "version": "7.0.0", 741 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 742 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 743 | "dev": true 744 | }, 745 | "isarray": { 746 | "version": "1.0.0", 747 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 748 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", 749 | "dev": true 750 | }, 751 | "isexe": { 752 | "version": "2.0.0", 753 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 754 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", 755 | "dev": true 756 | }, 757 | "js-tokens": { 758 | "version": "4.0.0", 759 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", 760 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", 761 | "dev": true 762 | }, 763 | "js-yaml": { 764 | "version": "3.14.0", 765 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", 766 | "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", 767 | "dev": true, 768 | "requires": { 769 | "argparse": "^1.0.7", 770 | "esprima": "^4.0.0" 771 | } 772 | }, 773 | "json-schema-traverse": { 774 | "version": "0.4.1", 775 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 776 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", 777 | "dev": true 778 | }, 779 | "json-stable-stringify-without-jsonify": { 780 | "version": "1.0.1", 781 | "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", 782 | "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", 783 | "dev": true 784 | }, 785 | "json5": { 786 | "version": "1.0.1", 787 | "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", 788 | "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", 789 | "dev": true, 790 | "requires": { 791 | "minimist": "^1.2.0" 792 | } 793 | }, 794 | "levn": { 795 | "version": "0.4.1", 796 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", 797 | "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", 798 | "dev": true, 799 | "requires": { 800 | "prelude-ls": "^1.2.1", 801 | "type-check": "~0.4.0" 802 | } 803 | }, 804 | "loader-utils": { 805 | "version": "1.4.0", 806 | "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", 807 | "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", 808 | "dev": true, 809 | "requires": { 810 | "big.js": "^5.2.2", 811 | "emojis-list": "^3.0.0", 812 | "json5": "^1.0.1" 813 | } 814 | }, 815 | "lodash": { 816 | "version": "4.17.19", 817 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", 818 | "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", 819 | "dev": true 820 | }, 821 | "make-error": { 822 | "version": "1.3.6", 823 | "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", 824 | "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", 825 | "dev": true 826 | }, 827 | "memory-fs": { 828 | "version": "0.5.0", 829 | "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", 830 | "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", 831 | "dev": true, 832 | "requires": { 833 | "errno": "^0.1.3", 834 | "readable-stream": "^2.0.1" 835 | } 836 | }, 837 | "micromatch": { 838 | "version": "4.0.2", 839 | "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", 840 | "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", 841 | "dev": true, 842 | "requires": { 843 | "braces": "^3.0.1", 844 | "picomatch": "^2.0.5" 845 | } 846 | }, 847 | "minimatch": { 848 | "version": "3.0.4", 849 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 850 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 851 | "dev": true, 852 | "requires": { 853 | "brace-expansion": "^1.1.7" 854 | } 855 | }, 856 | "minimist": { 857 | "version": "1.2.5", 858 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", 859 | "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", 860 | "dev": true 861 | }, 862 | "mkdirp": { 863 | "version": "0.5.5", 864 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", 865 | "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", 866 | "dev": true, 867 | "requires": { 868 | "minimist": "^1.2.5" 869 | } 870 | }, 871 | "ms": { 872 | "version": "2.1.2", 873 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 874 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 875 | "dev": true 876 | }, 877 | "natural-compare": { 878 | "version": "1.4.0", 879 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", 880 | "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", 881 | "dev": true 882 | }, 883 | "once": { 884 | "version": "1.4.0", 885 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 886 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 887 | "dev": true, 888 | "requires": { 889 | "wrappy": "1" 890 | } 891 | }, 892 | "optionator": { 893 | "version": "0.9.1", 894 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", 895 | "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", 896 | "dev": true, 897 | "requires": { 898 | "deep-is": "^0.1.3", 899 | "fast-levenshtein": "^2.0.6", 900 | "levn": "^0.4.1", 901 | "prelude-ls": "^1.2.1", 902 | "type-check": "^0.4.0", 903 | "word-wrap": "^1.2.3" 904 | } 905 | }, 906 | "parent-module": { 907 | "version": "1.0.1", 908 | "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", 909 | "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", 910 | "dev": true, 911 | "requires": { 912 | "callsites": "^3.0.0" 913 | } 914 | }, 915 | "path-is-absolute": { 916 | "version": "1.0.1", 917 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 918 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 919 | "dev": true 920 | }, 921 | "path-key": { 922 | "version": "3.1.1", 923 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", 924 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", 925 | "dev": true 926 | }, 927 | "picomatch": { 928 | "version": "2.2.2", 929 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", 930 | "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", 931 | "dev": true 932 | }, 933 | "prelude-ls": { 934 | "version": "1.2.1", 935 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", 936 | "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", 937 | "dev": true 938 | }, 939 | "prettier": { 940 | "version": "2.0.5", 941 | "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.0.5.tgz", 942 | "integrity": "sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg==", 943 | "dev": true 944 | }, 945 | "prettier-linter-helpers": { 946 | "version": "1.0.0", 947 | "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", 948 | "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", 949 | "dev": true, 950 | "requires": { 951 | "fast-diff": "^1.1.2" 952 | } 953 | }, 954 | "process-nextick-args": { 955 | "version": "2.0.1", 956 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", 957 | "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", 958 | "dev": true 959 | }, 960 | "progress": { 961 | "version": "2.0.3", 962 | "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", 963 | "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", 964 | "dev": true 965 | }, 966 | "prr": { 967 | "version": "1.0.1", 968 | "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", 969 | "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", 970 | "dev": true 971 | }, 972 | "punycode": { 973 | "version": "2.1.1", 974 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", 975 | "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", 976 | "dev": true 977 | }, 978 | "readable-stream": { 979 | "version": "2.3.7", 980 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", 981 | "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", 982 | "dev": true, 983 | "requires": { 984 | "core-util-is": "~1.0.0", 985 | "inherits": "~2.0.3", 986 | "isarray": "~1.0.0", 987 | "process-nextick-args": "~2.0.0", 988 | "safe-buffer": "~5.1.1", 989 | "string_decoder": "~1.1.1", 990 | "util-deprecate": "~1.0.1" 991 | } 992 | }, 993 | "regexpp": { 994 | "version": "3.1.0", 995 | "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", 996 | "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", 997 | "dev": true 998 | }, 999 | "resolve-from": { 1000 | "version": "4.0.0", 1001 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", 1002 | "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", 1003 | "dev": true 1004 | }, 1005 | "rimraf": { 1006 | "version": "2.6.3", 1007 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", 1008 | "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", 1009 | "dev": true, 1010 | "requires": { 1011 | "glob": "^7.1.3" 1012 | } 1013 | }, 1014 | "safe-buffer": { 1015 | "version": "5.1.2", 1016 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 1017 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", 1018 | "dev": true 1019 | }, 1020 | "semver": { 1021 | "version": "7.3.2", 1022 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", 1023 | "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", 1024 | "dev": true 1025 | }, 1026 | "shebang-command": { 1027 | "version": "2.0.0", 1028 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", 1029 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", 1030 | "dev": true, 1031 | "requires": { 1032 | "shebang-regex": "^3.0.0" 1033 | } 1034 | }, 1035 | "shebang-regex": { 1036 | "version": "3.0.0", 1037 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", 1038 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", 1039 | "dev": true 1040 | }, 1041 | "slice-ansi": { 1042 | "version": "2.1.0", 1043 | "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", 1044 | "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", 1045 | "dev": true, 1046 | "requires": { 1047 | "ansi-styles": "^3.2.0", 1048 | "astral-regex": "^1.0.0", 1049 | "is-fullwidth-code-point": "^2.0.0" 1050 | } 1051 | }, 1052 | "source-map": { 1053 | "version": "0.6.1", 1054 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 1055 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", 1056 | "dev": true 1057 | }, 1058 | "source-map-support": { 1059 | "version": "0.5.19", 1060 | "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", 1061 | "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", 1062 | "dev": true, 1063 | "requires": { 1064 | "buffer-from": "^1.0.0", 1065 | "source-map": "^0.6.0" 1066 | } 1067 | }, 1068 | "sprintf-js": { 1069 | "version": "1.0.3", 1070 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", 1071 | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", 1072 | "dev": true 1073 | }, 1074 | "string-width": { 1075 | "version": "3.1.0", 1076 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", 1077 | "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", 1078 | "dev": true, 1079 | "requires": { 1080 | "emoji-regex": "^7.0.1", 1081 | "is-fullwidth-code-point": "^2.0.0", 1082 | "strip-ansi": "^5.1.0" 1083 | }, 1084 | "dependencies": { 1085 | "ansi-regex": { 1086 | "version": "4.1.0", 1087 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", 1088 | "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", 1089 | "dev": true 1090 | }, 1091 | "strip-ansi": { 1092 | "version": "5.2.0", 1093 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", 1094 | "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", 1095 | "dev": true, 1096 | "requires": { 1097 | "ansi-regex": "^4.1.0" 1098 | } 1099 | } 1100 | } 1101 | }, 1102 | "string_decoder": { 1103 | "version": "1.1.1", 1104 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", 1105 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 1106 | "dev": true, 1107 | "requires": { 1108 | "safe-buffer": "~5.1.0" 1109 | } 1110 | }, 1111 | "strip-ansi": { 1112 | "version": "6.0.0", 1113 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", 1114 | "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", 1115 | "dev": true, 1116 | "requires": { 1117 | "ansi-regex": "^5.0.0" 1118 | } 1119 | }, 1120 | "strip-json-comments": { 1121 | "version": "3.1.1", 1122 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", 1123 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", 1124 | "dev": true 1125 | }, 1126 | "supports-color": { 1127 | "version": "5.5.0", 1128 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 1129 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 1130 | "dev": true, 1131 | "requires": { 1132 | "has-flag": "^3.0.0" 1133 | } 1134 | }, 1135 | "table": { 1136 | "version": "5.4.6", 1137 | "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", 1138 | "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", 1139 | "dev": true, 1140 | "requires": { 1141 | "ajv": "^6.10.2", 1142 | "lodash": "^4.17.14", 1143 | "slice-ansi": "^2.1.0", 1144 | "string-width": "^3.0.0" 1145 | } 1146 | }, 1147 | "tapable": { 1148 | "version": "1.1.3", 1149 | "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", 1150 | "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", 1151 | "dev": true 1152 | }, 1153 | "text-table": { 1154 | "version": "0.2.0", 1155 | "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", 1156 | "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", 1157 | "dev": true 1158 | }, 1159 | "to-regex-range": { 1160 | "version": "5.0.1", 1161 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 1162 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 1163 | "dev": true, 1164 | "requires": { 1165 | "is-number": "^7.0.0" 1166 | } 1167 | }, 1168 | "ts-loader": { 1169 | "version": "7.0.5", 1170 | "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-7.0.5.tgz", 1171 | "integrity": "sha512-zXypEIT6k3oTc+OZNx/cqElrsbBtYqDknf48OZos0NQ3RTt045fBIU8RRSu+suObBzYB355aIPGOe/3kj9h7Ig==", 1172 | "dev": true, 1173 | "requires": { 1174 | "chalk": "^2.3.0", 1175 | "enhanced-resolve": "^4.0.0", 1176 | "loader-utils": "^1.0.2", 1177 | "micromatch": "^4.0.0", 1178 | "semver": "^6.0.0" 1179 | }, 1180 | "dependencies": { 1181 | "chalk": { 1182 | "version": "2.4.2", 1183 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", 1184 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", 1185 | "dev": true, 1186 | "requires": { 1187 | "ansi-styles": "^3.2.1", 1188 | "escape-string-regexp": "^1.0.5", 1189 | "supports-color": "^5.3.0" 1190 | } 1191 | }, 1192 | "semver": { 1193 | "version": "6.3.0", 1194 | "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", 1195 | "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", 1196 | "dev": true 1197 | } 1198 | } 1199 | }, 1200 | "ts-node": { 1201 | "version": "8.10.2", 1202 | "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.10.2.tgz", 1203 | "integrity": "sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA==", 1204 | "dev": true, 1205 | "requires": { 1206 | "arg": "^4.1.0", 1207 | "diff": "^4.0.1", 1208 | "make-error": "^1.1.1", 1209 | "source-map-support": "^0.5.17", 1210 | "yn": "3.1.1" 1211 | } 1212 | }, 1213 | "tslib": { 1214 | "version": "1.13.0", 1215 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", 1216 | "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", 1217 | "dev": true 1218 | }, 1219 | "tsutils": { 1220 | "version": "3.17.1", 1221 | "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", 1222 | "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==", 1223 | "dev": true, 1224 | "requires": { 1225 | "tslib": "^1.8.1" 1226 | } 1227 | }, 1228 | "type-check": { 1229 | "version": "0.4.0", 1230 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", 1231 | "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", 1232 | "dev": true, 1233 | "requires": { 1234 | "prelude-ls": "^1.2.1" 1235 | } 1236 | }, 1237 | "type-fest": { 1238 | "version": "0.8.1", 1239 | "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", 1240 | "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", 1241 | "dev": true 1242 | }, 1243 | "typescript": { 1244 | "version": "3.9.7", 1245 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.7.tgz", 1246 | "integrity": "sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw==", 1247 | "dev": true 1248 | }, 1249 | "uri-js": { 1250 | "version": "4.2.2", 1251 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", 1252 | "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", 1253 | "dev": true, 1254 | "requires": { 1255 | "punycode": "^2.1.0" 1256 | } 1257 | }, 1258 | "util-deprecate": { 1259 | "version": "1.0.2", 1260 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 1261 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", 1262 | "dev": true 1263 | }, 1264 | "v8-compile-cache": { 1265 | "version": "2.1.1", 1266 | "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz", 1267 | "integrity": "sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ==", 1268 | "dev": true 1269 | }, 1270 | "which": { 1271 | "version": "2.0.2", 1272 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", 1273 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", 1274 | "dev": true, 1275 | "requires": { 1276 | "isexe": "^2.0.0" 1277 | } 1278 | }, 1279 | "word-wrap": { 1280 | "version": "1.2.3", 1281 | "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", 1282 | "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", 1283 | "dev": true 1284 | }, 1285 | "wrappy": { 1286 | "version": "1.0.2", 1287 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 1288 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", 1289 | "dev": true 1290 | }, 1291 | "write": { 1292 | "version": "1.0.3", 1293 | "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", 1294 | "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", 1295 | "dev": true, 1296 | "requires": { 1297 | "mkdirp": "^0.5.1" 1298 | } 1299 | }, 1300 | "yn": { 1301 | "version": "3.1.1", 1302 | "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", 1303 | "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", 1304 | "dev": true 1305 | } 1306 | } 1307 | } 1308 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescriptsolid", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "devDependencies": { 13 | "@types/node": "^14.0.23", 14 | "@typescript-eslint/eslint-plugin": "^3.6.1", 15 | "@typescript-eslint/parser": "^3.6.1", 16 | "eslint": "^7.5.0", 17 | "eslint-config-prettier": "^6.11.0", 18 | "eslint-plugin-prettier": "^3.1.4", 19 | "prettier": "^2.0.5", 20 | "ts-loader": "^7.0.5", 21 | "ts-node": "^8.10.2", 22 | "typescript": "^3.9.7" 23 | }, 24 | "dependencies": {} 25 | } 26 | -------------------------------------------------------------------------------- /src/dip/classes/customer.ts: -------------------------------------------------------------------------------- 1 | import { 2 | IndividualCustomerProtocol, 3 | EnterpriseCustomerProtocol, 4 | CustomerOrder, 5 | } from './interfaces/customer-protocol'; 6 | 7 | export class IndividualCustomer 8 | implements IndividualCustomerProtocol, CustomerOrder { 9 | firstName: string; 10 | lastName: string; 11 | cpf: string; 12 | cnpj: string; 13 | 14 | constructor(firstName: string, lastName: string, cpf: string) { 15 | this.firstName = firstName; 16 | this.lastName = lastName; 17 | this.cpf = cpf; 18 | this.cnpj = ''; 19 | } 20 | 21 | getName(): string { 22 | return this.firstName + ' ' + this.lastName; 23 | } 24 | 25 | getIDN(): string { 26 | return this.cpf; 27 | } 28 | } 29 | 30 | export class EnterpriseCustomer 31 | implements EnterpriseCustomerProtocol, CustomerOrder { 32 | name: string; 33 | cnpj: string; 34 | 35 | constructor(name: string, cnpj: string) { 36 | this.name = name; 37 | this.cnpj = cnpj; 38 | } 39 | 40 | getName(): string { 41 | return this.name; 42 | } 43 | 44 | getIDN(): string { 45 | return this.cnpj; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/dip/classes/discount.ts: -------------------------------------------------------------------------------- 1 | export abstract class Discount { 2 | protected discount = 0; 3 | 4 | calculate(price: number): number { 5 | return price - price * this.discount; 6 | } 7 | } 8 | 9 | export class FiftyPercentDiscount extends Discount { 10 | protected readonly discount = 0.5; 11 | } 12 | 13 | export class TenPercentDiscount extends Discount { 14 | protected readonly discount = 0.1; 15 | } 16 | 17 | export class NoDiscount extends Discount {} 18 | -------------------------------------------------------------------------------- /src/dip/classes/interfaces/cart-item.ts: -------------------------------------------------------------------------------- 1 | export interface CartItem { 2 | name: string; 3 | price: number; 4 | } 5 | -------------------------------------------------------------------------------- /src/dip/classes/interfaces/customer-protocol.ts: -------------------------------------------------------------------------------- 1 | export interface CustomerOrder { 2 | getName(): string; 3 | getIDN(): string; 4 | } 5 | 6 | export interface IndividualCustomerProtocol { 7 | firstName: string; 8 | lastName: string; 9 | cpf: string; 10 | } 11 | 12 | export interface EnterpriseCustomerProtocol { 13 | name: string; 14 | cnpj: string; 15 | } 16 | -------------------------------------------------------------------------------- /src/dip/classes/interfaces/messaging-protocol.ts: -------------------------------------------------------------------------------- 1 | export interface MessagingProtocol { 2 | sendMessage(msg: string): void; 3 | } 4 | -------------------------------------------------------------------------------- /src/dip/classes/interfaces/order-status.ts: -------------------------------------------------------------------------------- 1 | export type OrderStatus = 'open' | 'closed'; 2 | -------------------------------------------------------------------------------- /src/dip/classes/interfaces/persistency-protocol.ts: -------------------------------------------------------------------------------- 1 | export interface PersistencyProtocol { 2 | saveOrder(): void; 3 | } 4 | -------------------------------------------------------------------------------- /src/dip/classes/interfaces/shopping-cart-protocol.ts: -------------------------------------------------------------------------------- 1 | import { CartItem } from './cart-item'; 2 | 3 | export interface ShoppingCartProtocol { 4 | items: Readonly; 5 | addItem(item: CartItem): void; 6 | removeItem(index: number): void; 7 | total(): number; 8 | totalWithDicount(): number; 9 | isEmpty(): boolean; 10 | clear(): void; 11 | } 12 | -------------------------------------------------------------------------------- /src/dip/classes/order.ts: -------------------------------------------------------------------------------- 1 | import { OrderStatus } from './interfaces/order-status'; 2 | import { CustomerOrder } from './interfaces/customer-protocol'; 3 | import { ShoppingCartProtocol } from './interfaces/shopping-cart-protocol'; 4 | import { MessagingProtocol } from './interfaces/messaging-protocol'; 5 | import { PersistencyProtocol } from './interfaces/persistency-protocol'; 6 | 7 | export class Order { 8 | private _orderStatus: OrderStatus = 'open'; 9 | 10 | constructor( 11 | private readonly cart: ShoppingCartProtocol, 12 | private readonly messaging: MessagingProtocol, 13 | private readonly persistency: PersistencyProtocol, 14 | private readonly customer: CustomerOrder, 15 | ) {} 16 | 17 | get orderStatus(): OrderStatus { 18 | return this._orderStatus; 19 | } 20 | 21 | checkout(): void { 22 | if (this.cart.isEmpty()) { 23 | console.log('Seu carrinho está vazio'); 24 | return; 25 | } 26 | 27 | this._orderStatus = 'closed'; 28 | this.messaging.sendMessage( 29 | `Seu pedido com total de ${this.cart.totalWithDicount()} foi recebido.`, 30 | ); 31 | this.persistency.saveOrder(); 32 | this.cart.clear(); 33 | 34 | console.log( 35 | 'O cliente é:', 36 | this.customer.getName(), 37 | this.customer.getIDN(), 38 | ); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/dip/classes/product.ts: -------------------------------------------------------------------------------- 1 | import { CartItem } from './interfaces/cart-item'; 2 | 3 | export class Product implements CartItem { 4 | constructor(public name: string, public price: number) {} 5 | } 6 | -------------------------------------------------------------------------------- /src/dip/classes/shopping-cart.ts: -------------------------------------------------------------------------------- 1 | import { CartItem } from './interfaces/cart-item'; 2 | import { Discount } from './discount'; 3 | import { ShoppingCartProtocol } from './interfaces/shopping-cart-protocol'; 4 | 5 | export class ShoppingCart implements ShoppingCartProtocol { 6 | private readonly _items: CartItem[] = []; 7 | 8 | constructor(private readonly discount: Discount) {} 9 | 10 | addItem(item: CartItem): void { 11 | this._items.push(item); 12 | } 13 | 14 | removeItem(index: number): void { 15 | this._items.splice(index, 1); 16 | } 17 | 18 | get items(): Readonly { 19 | return this._items; 20 | } 21 | 22 | total(): number { 23 | return +this._items 24 | .reduce((total, next) => total + next.price, 0) 25 | .toFixed(2); 26 | } 27 | 28 | totalWithDicount(): number { 29 | return this.discount.calculate(this.total()); 30 | } 31 | 32 | isEmpty(): boolean { 33 | return this._items.length === 0; 34 | } 35 | 36 | clear(): void { 37 | console.log('Carrinho de compras foi limpo...'); 38 | this._items.length = 0; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/dip/main.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Módulos de alto nível não devem depender de módulos de baixo nível. Ambos devem 3 | depender de abstrações. 4 | Dependa de abstrações, não de implementações. 5 | Abstrações não devem depender de detalhes. Detalhes devem depender 6 | de abstrações. 7 | 8 | Classes de baixo nível são classes que executam tarefas (os detalhes) 9 | Classes de alto nível são classes que gerenciam as classes de baixo nível. 10 | */ 11 | import { ShoppingCart } from './classes/shopping-cart'; 12 | import { Order } from './classes/order'; 13 | import { Messaging } from './services/messaging'; 14 | import { Persistency } from './services/persistency'; 15 | import { Product } from './classes/product'; 16 | import { NoDiscount } from './classes/discount'; 17 | import { EnterpriseCustomer } from './classes/customer'; 18 | 19 | // const fiftyPercentDiscount = new FiftyPercentDiscount(); 20 | // const tenPercentDiscount = new TenPercentDiscount(); 21 | const noDiscount = new NoDiscount(); 22 | const shoppingCart = new ShoppingCart(noDiscount); 23 | const messaging = new Messaging(); 24 | const persistency = new Persistency(); 25 | // const individualCustomer = new IndividualCustomer( 26 | // 'Luiz', 27 | // 'Miranda', 28 | // '111.111.111-11', 29 | // ); 30 | const enterpriseCustomer = new EnterpriseCustomer( 31 | 'Empresa Gigante', 32 | '2222222222222222', 33 | ); 34 | 35 | const order = new Order( 36 | shoppingCart, 37 | messaging, 38 | persistency, 39 | enterpriseCustomer, 40 | ); 41 | 42 | shoppingCart.addItem(new Product('Camiseta', 49.91)); 43 | shoppingCart.addItem(new Product('Caderno', 9.9123)); 44 | shoppingCart.addItem(new Product('Lápis', 1.59)); 45 | 46 | console.log(shoppingCart.items); 47 | console.log(shoppingCart.total()); 48 | console.log(shoppingCart.totalWithDicount()); 49 | console.log(order.orderStatus); 50 | order.checkout(); 51 | console.log(order.orderStatus); 52 | -------------------------------------------------------------------------------- /src/dip/services/messaging.ts: -------------------------------------------------------------------------------- 1 | import { MessagingProtocol } from '../classes/interfaces/messaging-protocol'; 2 | 3 | export class Messaging implements MessagingProtocol { 4 | sendMessage(msg: string): void { 5 | console.log('Mensagem enviada:', msg); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/dip/services/persistency.ts: -------------------------------------------------------------------------------- 1 | import { PersistencyProtocol } from '../classes/interfaces/persistency-protocol'; 2 | 3 | export class Persistency implements PersistencyProtocol { 4 | saveOrder(): void { 5 | console.log('Pedido salvo com sucesso...'); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Vantagens e desvantagens do S.O.L.I.D. 3 | 4 | Vantagens: 5 | - Código modular 6 | - Código reutilizável (D.R.Y - Don't repeat yourself) 7 | - Código testável, baixo acoplamento 8 | - Baixo acoplamento e alta coesão 9 | - Código expansível 10 | - Separations of concerns (Separação de conceitos) 11 | - Fácil manutenção 12 | Desvantagens: 13 | - Complexidade 14 | - Quantidade de código digitado aumenta 15 | - Tempo de desenvolvimento aumenta bastante 16 | - Tenha cuidados com: YAGNI, KISS (You aren't gonna need it, Keep it simple, stupid!) 17 | */ 18 | -------------------------------------------------------------------------------- /src/isp/classes/customer.ts: -------------------------------------------------------------------------------- 1 | import { 2 | IndividualCustomerProtocol, 3 | EnterpriseCustomerProtocol, 4 | CustomerOrder, 5 | } from './interfaces/customer-protocol'; 6 | 7 | export class IndividualCustomer 8 | implements IndividualCustomerProtocol, CustomerOrder { 9 | firstName: string; 10 | lastName: string; 11 | cpf: string; 12 | cnpj: string; 13 | 14 | constructor(firstName: string, lastName: string, cpf: string) { 15 | this.firstName = firstName; 16 | this.lastName = lastName; 17 | this.cpf = cpf; 18 | this.cnpj = ''; 19 | } 20 | 21 | getName(): string { 22 | return this.firstName + ' ' + this.lastName; 23 | } 24 | 25 | getIDN(): string { 26 | return this.cpf; 27 | } 28 | } 29 | 30 | export class EnterpriseCustomer 31 | implements EnterpriseCustomerProtocol, CustomerOrder { 32 | name: string; 33 | cnpj: string; 34 | 35 | constructor(name: string, cnpj: string) { 36 | this.name = name; 37 | this.cnpj = cnpj; 38 | } 39 | 40 | getName(): string { 41 | return this.name; 42 | } 43 | 44 | getIDN(): string { 45 | return this.cnpj; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/isp/classes/discount.ts: -------------------------------------------------------------------------------- 1 | export abstract class Discount { 2 | protected discount = 0; 3 | 4 | calculate(price: number): number { 5 | return price - price * this.discount; 6 | } 7 | } 8 | 9 | export class FiftyPercentDiscount extends Discount { 10 | protected readonly discount = 0.5; 11 | } 12 | 13 | export class TenPercentDiscount extends Discount { 14 | protected readonly discount = 0.1; 15 | } 16 | 17 | export class NoDiscount extends Discount {} 18 | -------------------------------------------------------------------------------- /src/isp/classes/interfaces/cart-item.ts: -------------------------------------------------------------------------------- 1 | export interface CartItem { 2 | name: string; 3 | price: number; 4 | } 5 | -------------------------------------------------------------------------------- /src/isp/classes/interfaces/customer-protocol.ts: -------------------------------------------------------------------------------- 1 | export interface CustomerOrder { 2 | getName(): string; 3 | getIDN(): string; 4 | } 5 | 6 | export interface IndividualCustomerProtocol { 7 | firstName: string; 8 | lastName: string; 9 | cpf: string; 10 | } 11 | 12 | export interface EnterpriseCustomerProtocol { 13 | name: string; 14 | cnpj: string; 15 | } 16 | -------------------------------------------------------------------------------- /src/isp/classes/interfaces/order-status.ts: -------------------------------------------------------------------------------- 1 | export type OrderStatus = 'open' | 'closed'; 2 | -------------------------------------------------------------------------------- /src/isp/classes/order.ts: -------------------------------------------------------------------------------- 1 | import { OrderStatus } from './interfaces/order-status'; 2 | import { ShoppingCart } from './shopping-cart'; 3 | import { Messaging } from '../services/messaging'; 4 | import { Persistency } from '../services/persistency'; 5 | import { CustomerOrder } from './interfaces/customer-protocol'; 6 | 7 | export class Order { 8 | private _orderStatus: OrderStatus = 'open'; 9 | 10 | constructor( 11 | private readonly cart: ShoppingCart, 12 | private readonly messaging: Messaging, 13 | private readonly persistency: Persistency, 14 | private readonly customer: CustomerOrder, 15 | ) {} 16 | 17 | get orderStatus(): OrderStatus { 18 | return this._orderStatus; 19 | } 20 | 21 | checkout(): void { 22 | if (this.cart.isEmpty()) { 23 | console.log('Seu carrinho está vazio'); 24 | return; 25 | } 26 | 27 | this._orderStatus = 'closed'; 28 | this.messaging.sendMessage( 29 | `Seu pedido com total de ${this.cart.totalWithDicount()} foi recebido.`, 30 | ); 31 | this.persistency.saveOrder(); 32 | this.cart.clear(); 33 | 34 | console.log( 35 | 'O cliente é:', 36 | this.customer.getName(), 37 | this.customer.getIDN(), 38 | ); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/isp/classes/product.ts: -------------------------------------------------------------------------------- 1 | import { CartItem } from './interfaces/cart-item'; 2 | 3 | export class Product implements CartItem { 4 | constructor(public name: string, public price: number) {} 5 | } 6 | -------------------------------------------------------------------------------- /src/isp/classes/shopping-cart.ts: -------------------------------------------------------------------------------- 1 | import { CartItem } from './interfaces/cart-item'; 2 | import { Discount } from './discount'; 3 | 4 | export class ShoppingCart { 5 | private readonly _items: CartItem[] = []; 6 | 7 | constructor(private readonly discount: Discount) {} 8 | 9 | addItem(item: CartItem): void { 10 | this._items.push(item); 11 | } 12 | 13 | removeItem(index: number): void { 14 | this._items.splice(index, 1); 15 | } 16 | 17 | get items(): Readonly { 18 | return this._items; 19 | } 20 | 21 | total(): number { 22 | return +this._items 23 | .reduce((total, next) => total + next.price, 0) 24 | .toFixed(2); 25 | } 26 | 27 | totalWithDicount(): number { 28 | return this.discount.calculate(this.total()); 29 | } 30 | 31 | isEmpty(): boolean { 32 | return this._items.length === 0; 33 | } 34 | 35 | clear(): void { 36 | console.log('Carrinho de compras foi limpo...'); 37 | this._items.length = 0; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/isp/main.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Interface segregation principle (Princípio da segregação de Interface) - 3 | os clientes não devem ser forçados a depender de types, interfaces ou membros 4 | abstratos que não utilizam 5 | */ 6 | import { ShoppingCart } from './classes/shopping-cart'; 7 | import { Order } from './classes/order'; 8 | import { Messaging } from './services/messaging'; 9 | import { Persistency } from './services/persistency'; 10 | import { Product } from './classes/product'; 11 | import { NoDiscount } from './classes/discount'; 12 | import { EnterpriseCustomer } from './classes/customer'; 13 | 14 | // const fiftyPercentDiscount = new FiftyPercentDiscount(); 15 | // const tenPercentDiscount = new TenPercentDiscount(); 16 | const noDiscount = new NoDiscount(); 17 | const shoppingCart = new ShoppingCart(noDiscount); 18 | const messaging = new Messaging(); 19 | const persistency = new Persistency(); 20 | // const individualCustomer = new IndividualCustomer( 21 | // 'Luiz', 22 | // 'Miranda', 23 | // '111.111.111-11', 24 | // ); 25 | const enterpriseCustomer = new EnterpriseCustomer( 26 | 'Empresa Gigante', 27 | '2222222222222222', 28 | ); 29 | const order = new Order( 30 | shoppingCart, 31 | messaging, 32 | persistency, 33 | enterpriseCustomer, 34 | ); 35 | 36 | shoppingCart.addItem(new Product('Camiseta', 49.91)); 37 | shoppingCart.addItem(new Product('Caderno', 9.9123)); 38 | shoppingCart.addItem(new Product('Lápis', 1.59)); 39 | 40 | console.log(shoppingCart.items); 41 | console.log(shoppingCart.total()); 42 | console.log(shoppingCart.totalWithDicount()); 43 | console.log(order.orderStatus); 44 | order.checkout(); 45 | console.log(order.orderStatus); 46 | -------------------------------------------------------------------------------- /src/isp/services/messaging.ts: -------------------------------------------------------------------------------- 1 | export class Messaging { 2 | sendMessage(msg: string): void { 3 | console.log('Mensagem enviada:', msg); 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /src/isp/services/persistency.ts: -------------------------------------------------------------------------------- 1 | export class Persistency { 2 | saveOrder(): void { 3 | console.log('Pedido salvo com sucesso...'); 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /src/legacy/shopping-cart-legacy.ts: -------------------------------------------------------------------------------- 1 | type CartItem = { name: string; price: number }; 2 | type OrderStatus = 'open' | 'closed'; 3 | 4 | export class ShoppingCartLegacy { 5 | private readonly _items: CartItem[] = []; 6 | private _orderStatus: OrderStatus = 'open'; 7 | 8 | addItem(item: CartItem): void { 9 | this._items.push(item); 10 | } 11 | 12 | removeItem(index: number): void { 13 | this._items.splice(index, 1); 14 | } 15 | 16 | get items(): Readonly { 17 | return this._items; 18 | } 19 | 20 | get orderStatus(): OrderStatus { 21 | return this._orderStatus; 22 | } 23 | 24 | total(): number { 25 | return +this._items 26 | .reduce((total, next) => total + next.price, 0) 27 | .toFixed(2); 28 | } 29 | 30 | checkout(): void { 31 | if (this.isEmpty()) { 32 | console.log('Seu carrinho está vazio'); 33 | return; 34 | } 35 | 36 | this._orderStatus = 'closed'; 37 | this.sendMessage(`Seu pedido com total de ${this.total()} foi recebido.`); 38 | this.saveOrder(); 39 | this.clear(); 40 | } 41 | 42 | isEmpty(): boolean { 43 | return this._items.length === 0; 44 | } 45 | 46 | sendMessage(msg: string): void { 47 | console.log('Mensagem enviada:', msg); 48 | } 49 | 50 | saveOrder(): void { 51 | console.log('Pedido salvo com sucesso...'); 52 | } 53 | 54 | clear(): void { 55 | console.log('Carrinho de compras foi limpo...'); 56 | this._items.length = 0; 57 | } 58 | } 59 | 60 | const shoppingCart = new ShoppingCartLegacy(); 61 | shoppingCart.addItem({ name: 'Camiseta', price: 49.91 }); 62 | shoppingCart.addItem({ name: 'Caderno', price: 9.9123 }); 63 | shoppingCart.addItem({ name: 'Lápis', price: 1.59 }); 64 | 65 | console.log(shoppingCart.items); 66 | console.log(shoppingCart.total()); 67 | console.log(shoppingCart.orderStatus); 68 | shoppingCart.checkout(); 69 | console.log(shoppingCart.orderStatus); 70 | -------------------------------------------------------------------------------- /src/lsp/classes/discount.ts: -------------------------------------------------------------------------------- 1 | export abstract class Discount { 2 | protected discount = 0; 3 | 4 | calculate(price: number): number { 5 | return price - price * this.discount; 6 | } 7 | } 8 | 9 | export class FiftyPercentDiscount extends Discount { 10 | protected readonly discount = 0.5; 11 | } 12 | 13 | export class TenPercentDiscount extends Discount { 14 | protected readonly discount = 0.1; 15 | } 16 | 17 | export class NoDiscount extends Discount {} 18 | -------------------------------------------------------------------------------- /src/lsp/classes/interfaces/cart-item.ts: -------------------------------------------------------------------------------- 1 | export interface CartItem { 2 | name: string; 3 | price: number; 4 | } 5 | -------------------------------------------------------------------------------- /src/lsp/classes/interfaces/order-status.ts: -------------------------------------------------------------------------------- 1 | export type OrderStatus = 'open' | 'closed'; 2 | -------------------------------------------------------------------------------- /src/lsp/classes/order.ts: -------------------------------------------------------------------------------- 1 | import { OrderStatus } from './interfaces/order-status'; 2 | import { ShoppingCart } from './shopping-cart'; 3 | import { Messaging } from '../services/messaging'; 4 | import { Persistency } from '../services/persistency'; 5 | 6 | export class Order { 7 | private _orderStatus: OrderStatus = 'open'; 8 | 9 | constructor( 10 | private readonly cart: ShoppingCart, 11 | private readonly messaging: Messaging, 12 | private readonly persistency: Persistency, 13 | ) {} 14 | 15 | get orderStatus(): OrderStatus { 16 | return this._orderStatus; 17 | } 18 | 19 | checkout(): void { 20 | if (this.cart.isEmpty()) { 21 | console.log('Seu carrinho está vazio'); 22 | return; 23 | } 24 | 25 | this._orderStatus = 'closed'; 26 | this.messaging.sendMessage( 27 | `Seu pedido com total de ${this.cart.totalWithDicount()} foi recebido.`, 28 | ); 29 | this.persistency.saveOrder(); 30 | this.cart.clear(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/lsp/classes/product.ts: -------------------------------------------------------------------------------- 1 | import { CartItem } from './interfaces/cart-item'; 2 | 3 | export class Product implements CartItem { 4 | constructor(public name: string, public price: number) {} 5 | } 6 | -------------------------------------------------------------------------------- /src/lsp/classes/shopping-cart.ts: -------------------------------------------------------------------------------- 1 | import { CartItem } from './interfaces/cart-item'; 2 | import { Discount } from './discount'; 3 | 4 | export class ShoppingCart { 5 | private readonly _items: CartItem[] = []; 6 | 7 | constructor(private readonly discount: Discount) {} 8 | 9 | addItem(item: CartItem): void { 10 | this._items.push(item); 11 | } 12 | 13 | removeItem(index: number): void { 14 | this._items.splice(index, 1); 15 | } 16 | 17 | get items(): Readonly { 18 | return this._items; 19 | } 20 | 21 | total(): number { 22 | return +this._items 23 | .reduce((total, next) => total + next.price, 0) 24 | .toFixed(2); 25 | } 26 | 27 | totalWithDicount(): number { 28 | return this.discount.calculate(this.total()); 29 | } 30 | 31 | isEmpty(): boolean { 32 | return this._items.length === 0; 33 | } 34 | 35 | clear(): void { 36 | console.log('Carrinho de compras foi limpo...'); 37 | this._items.length = 0; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/lsp/main.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Liskov substitution principle (Princípio da substituição de Liskov) - 3 | Se ϕ(x) é uma propriedade demonstrável dos objetos x de tipo T. Então ϕ(y) 4 | deve ser verdadeiro para objetos y de tipo S onde S é um subtipo de T. 5 | 6 | Mais simples: Subtipos precisam ser substituíveis por seus tipos de base. 7 | Mais simples ainda: Se meu programa espera um Animal, algo do tipo 8 | Cachorro (que herda de Animal) deve servir como qualquer outro Animal. 9 | */ 10 | import { ShoppingCart } from './classes/shopping-cart'; 11 | import { Order } from './classes/order'; 12 | import { Messaging } from './services/messaging'; 13 | import { Persistency } from './services/persistency'; 14 | import { Product } from './classes/product'; 15 | import { NoDiscount } from './classes/discount'; 16 | 17 | // const fiftyPercentDiscount = new FiftyPercentDiscount(); 18 | // const tenPercentDiscount = new TenPercentDiscount(); 19 | const noDiscount = new NoDiscount(); 20 | const shoppingCart = new ShoppingCart(noDiscount); 21 | const messaging = new Messaging(); 22 | const persistency = new Persistency(); 23 | const order = new Order(shoppingCart, messaging, persistency); 24 | 25 | shoppingCart.addItem(new Product('Camiseta', 49.91)); 26 | shoppingCart.addItem(new Product('Caderno', 9.9123)); 27 | shoppingCart.addItem(new Product('Lápis', 1.59)); 28 | 29 | console.log(shoppingCart.items); 30 | console.log(shoppingCart.total()); 31 | console.log(shoppingCart.totalWithDicount()); 32 | console.log(order.orderStatus); 33 | order.checkout(); 34 | console.log(order.orderStatus); 35 | -------------------------------------------------------------------------------- /src/lsp/services/messaging.ts: -------------------------------------------------------------------------------- 1 | export class Messaging { 2 | sendMessage(msg: string): void { 3 | console.log('Mensagem enviada:', msg); 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /src/lsp/services/persistency.ts: -------------------------------------------------------------------------------- 1 | export class Persistency { 2 | saveOrder(): void { 3 | console.log('Pedido salvo com sucesso...'); 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /src/ocp/classes/discount.ts: -------------------------------------------------------------------------------- 1 | export abstract class Discount { 2 | protected discount = 0; 3 | 4 | calculate(price: number): number { 5 | return price - price * this.discount; 6 | } 7 | } 8 | 9 | export class FiftyPercentDiscount extends Discount { 10 | protected readonly discount = 0.5; 11 | } 12 | 13 | export class TenPercentDiscount extends Discount { 14 | protected readonly discount = 0.1; 15 | } 16 | 17 | export class NoDiscount extends Discount {} 18 | -------------------------------------------------------------------------------- /src/ocp/classes/interfaces/cart-item.ts: -------------------------------------------------------------------------------- 1 | export interface CartItem { 2 | name: string; 3 | price: number; 4 | } 5 | -------------------------------------------------------------------------------- /src/ocp/classes/interfaces/order-status.ts: -------------------------------------------------------------------------------- 1 | export type OrderStatus = 'open' | 'closed'; 2 | -------------------------------------------------------------------------------- /src/ocp/classes/order.ts: -------------------------------------------------------------------------------- 1 | import { OrderStatus } from './interfaces/order-status'; 2 | import { ShoppingCart } from './shopping-cart'; 3 | import { Messaging } from '../services/messaging'; 4 | import { Persistency } from '../services/persistency'; 5 | 6 | export class Order { 7 | private _orderStatus: OrderStatus = 'open'; 8 | 9 | constructor( 10 | private readonly cart: ShoppingCart, 11 | private readonly messaging: Messaging, 12 | private readonly persistency: Persistency, 13 | ) {} 14 | 15 | get orderStatus(): OrderStatus { 16 | return this._orderStatus; 17 | } 18 | 19 | checkout(): void { 20 | if (this.cart.isEmpty()) { 21 | console.log('Seu carrinho está vazio'); 22 | return; 23 | } 24 | 25 | this._orderStatus = 'closed'; 26 | this.messaging.sendMessage( 27 | `Seu pedido com total de ${this.cart.totalWithDicount()} foi recebido.`, 28 | ); 29 | this.persistency.saveOrder(); 30 | this.cart.clear(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/ocp/classes/product.ts: -------------------------------------------------------------------------------- 1 | import { CartItem } from './interfaces/cart-item'; 2 | 3 | export class Product implements CartItem { 4 | constructor(public name: string, public price: number) {} 5 | } 6 | -------------------------------------------------------------------------------- /src/ocp/classes/shopping-cart.ts: -------------------------------------------------------------------------------- 1 | import { CartItem } from './interfaces/cart-item'; 2 | import { Discount } from './discount'; 3 | 4 | export class ShoppingCart { 5 | private readonly _items: CartItem[] = []; 6 | 7 | constructor(private readonly discount: Discount) {} 8 | 9 | addItem(item: CartItem): void { 10 | this._items.push(item); 11 | } 12 | 13 | removeItem(index: number): void { 14 | this._items.splice(index, 1); 15 | } 16 | 17 | get items(): Readonly { 18 | return this._items; 19 | } 20 | 21 | total(): number { 22 | return +this._items 23 | .reduce((total, next) => total + next.price, 0) 24 | .toFixed(2); 25 | } 26 | 27 | totalWithDicount(): number { 28 | return this.discount.calculate(this.total()); 29 | } 30 | 31 | isEmpty(): boolean { 32 | return this._items.length === 0; 33 | } 34 | 35 | clear(): void { 36 | console.log('Carrinho de compras foi limpo...'); 37 | this._items.length = 0; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/ocp/main.ts: -------------------------------------------------------------------------------- 1 | /* 2 | Open/closed principle 3 | Entidades devem estar abertas para extensão, mas fechadas para modificação. 4 | */ 5 | import { ShoppingCart } from './classes/shopping-cart'; 6 | import { Order } from './classes/order'; 7 | import { Messaging } from './services/messaging'; 8 | import { Persistency } from './services/persistency'; 9 | import { Product } from './classes/product'; 10 | import { FiftyPercentDiscount } from './classes/discount'; 11 | 12 | const fiftyPercentDiscount = new FiftyPercentDiscount(); 13 | // const tenPercentDiscount = new TenPercentDiscount(); 14 | // const noDiscount = new NoDiscount(); 15 | const shoppingCart = new ShoppingCart(fiftyPercentDiscount); 16 | const messaging = new Messaging(); 17 | const persistency = new Persistency(); 18 | const order = new Order(shoppingCart, messaging, persistency); 19 | 20 | shoppingCart.addItem(new Product('Camiseta', 49.91)); 21 | shoppingCart.addItem(new Product('Caderno', 9.9123)); 22 | shoppingCart.addItem(new Product('Lápis', 1.59)); 23 | 24 | console.log(shoppingCart.items); 25 | console.log(shoppingCart.total()); 26 | console.log(shoppingCart.totalWithDicount()); 27 | console.log(order.orderStatus); 28 | order.checkout(); 29 | console.log(order.orderStatus); 30 | -------------------------------------------------------------------------------- /src/ocp/services/messaging.ts: -------------------------------------------------------------------------------- 1 | export class Messaging { 2 | sendMessage(msg: string): void { 3 | console.log('Mensagem enviada:', msg); 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /src/ocp/services/persistency.ts: -------------------------------------------------------------------------------- 1 | export class Persistency { 2 | saveOrder(): void { 3 | console.log('Pedido salvo com sucesso...'); 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /src/srp/classes/interfaces/cart-item.ts: -------------------------------------------------------------------------------- 1 | export interface CartItem { 2 | name: string; 3 | price: number; 4 | } 5 | -------------------------------------------------------------------------------- /src/srp/classes/interfaces/order-status.ts: -------------------------------------------------------------------------------- 1 | export type OrderStatus = 'open' | 'closed'; 2 | -------------------------------------------------------------------------------- /src/srp/classes/order.ts: -------------------------------------------------------------------------------- 1 | import { OrderStatus } from './interfaces/order-status'; 2 | import { ShoppingCart } from './shopping-cart'; 3 | import { Messaging } from '../services/messaging'; 4 | import { Persistency } from '../services/persistency'; 5 | 6 | export class Order { 7 | private _orderStatus: OrderStatus = 'open'; 8 | 9 | constructor( 10 | private readonly cart: ShoppingCart, 11 | private readonly messaging: Messaging, 12 | private readonly persistency: Persistency, 13 | ) {} 14 | 15 | get orderStatus(): OrderStatus { 16 | return this._orderStatus; 17 | } 18 | 19 | checkout(): void { 20 | if (this.cart.isEmpty()) { 21 | console.log('Seu carrinho está vazio'); 22 | return; 23 | } 24 | 25 | this._orderStatus = 'closed'; 26 | this.messaging.sendMessage( 27 | `Seu pedido com total de ${this.cart.total()} foi recebido.`, 28 | ); 29 | this.persistency.saveOrder(); 30 | this.cart.clear(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/srp/classes/product.ts: -------------------------------------------------------------------------------- 1 | import { CartItem } from './interfaces/cart-item'; 2 | 3 | export class Product implements CartItem { 4 | constructor(public name: string, public price: number) {} 5 | } 6 | -------------------------------------------------------------------------------- /src/srp/classes/shopping-cart.ts: -------------------------------------------------------------------------------- 1 | import { CartItem } from './interfaces/cart-item'; 2 | 3 | export class ShoppingCart { 4 | private readonly _items: CartItem[] = []; 5 | 6 | addItem(item: CartItem): void { 7 | this._items.push(item); 8 | } 9 | 10 | removeItem(index: number): void { 11 | this._items.splice(index, 1); 12 | } 13 | 14 | get items(): Readonly { 15 | return this._items; 16 | } 17 | 18 | total(): number { 19 | return +this._items 20 | .reduce((total, next) => total + next.price, 0) 21 | .toFixed(2); 22 | } 23 | 24 | isEmpty(): boolean { 25 | return this._items.length === 0; 26 | } 27 | 28 | clear(): void { 29 | console.log('Carrinho de compras foi limpo...'); 30 | this._items.length = 0; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/srp/main.ts: -------------------------------------------------------------------------------- 1 | import { ShoppingCart } from './classes/shopping-cart'; 2 | import { Order } from './classes/order'; 3 | import { Messaging } from './services/messaging'; 4 | import { Persistency } from './services/persistency'; 5 | import { Product } from './classes/product'; 6 | 7 | const shoppingCart = new ShoppingCart(); 8 | const messaging = new Messaging(); 9 | const persistency = new Persistency(); 10 | const order = new Order(shoppingCart, messaging, persistency); 11 | 12 | shoppingCart.addItem(new Product('Camiseta', 49.91)); 13 | shoppingCart.addItem(new Product('Caderno', 9.9123)); 14 | shoppingCart.addItem(new Product('Lápis', 1.59)); 15 | 16 | console.log(shoppingCart.items); 17 | console.log(shoppingCart.total()); 18 | console.log(order.orderStatus); 19 | order.checkout(); 20 | console.log(order.orderStatus); 21 | -------------------------------------------------------------------------------- /src/srp/services/messaging.ts: -------------------------------------------------------------------------------- 1 | export class Messaging { 2 | sendMessage(msg: string): void { 3 | console.log('Mensagem enviada:', msg); 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /src/srp/services/persistency.ts: -------------------------------------------------------------------------------- 1 | export class Persistency { 2 | saveOrder(): void { 3 | console.log('Pedido salvo com sucesso...'); 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Visit https://aka.ms/tsconfig.json to read more about this file */ 4 | 5 | /* Basic Options */ 6 | // "incremental": true, /* Enable incremental compilation */ 7 | "target": "ES2019", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */ 8 | "module": "CommonJS", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */ 9 | "lib": ["ESNext", "DOM"], /* Specify library files to be included in the compilation. */ 10 | "allowJs": true, /* Allow javascript files to be compiled. */ 11 | // "checkJs": true, /* Report errors in .js files. */ 12 | // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ 13 | // "declaration": true, /* Generates corresponding '.d.ts' file. */ 14 | // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ 15 | "sourceMap": true, /* Generates corresponding '.map' file. */ 16 | // "outFile": "./", /* Concatenate and emit output to single file. */ 17 | "outDir": "./dist", /* Redirect output structure to the directory. */ 18 | "rootDir": "./src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ 19 | // "composite": true, /* Enable project compilation */ 20 | // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ 21 | "removeComments": true, /* Do not emit comments to output. */ 22 | // "noEmit": true, /* Do not emit outputs. */ 23 | "noEmitOnError": true, 24 | // "importHelpers": true, /* Import emit helpers from 'tslib'. */ 25 | // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ 26 | // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ 27 | 28 | /* Strict Type-Checking Options */ 29 | "strict": true, /* Enable all strict type-checking options. */ 30 | // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ 31 | // "strictNullChecks": true, /* Enable strict null checks. */ 32 | // "strictFunctionTypes": true, /* Enable strict checking of function types. */ 33 | // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ 34 | // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ 35 | // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ 36 | // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ 37 | 38 | /* Additional Checks */ 39 | // "noUnusedLocals": true, /* Report errors on unused locals. */ 40 | // "noUnusedParameters": true, /* Report errors on unused parameters. */ 41 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ 42 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ 43 | 44 | /* Module Resolution Options */ 45 | // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ 46 | // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ 47 | // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ 48 | // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ 49 | // "typeRoots": [], /* List of folders to include type definitions from. */ 50 | // "types": [], /* Type declaration files to be included in compilation. */ 51 | // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ 52 | "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ 53 | // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ 54 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 55 | 56 | /* Source Map Options */ 57 | // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ 58 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 59 | // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ 60 | // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ 61 | 62 | /* Experimental Options */ 63 | "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ 64 | "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ 65 | 66 | /* Advanced Options */ 67 | "skipLibCheck": true, /* Skip type checking of declaration files. */ 68 | "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ 69 | }, 70 | "include": [ 71 | "./src" 72 | ] 73 | } 74 | --------------------------------------------------------------------------------